summaryrefslogtreecommitdiff
path: root/test/fixtures
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-02-01 14:07:26 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-02-01 15:29:42 -0800
commit716997b99eed50ecf35fd1ec3124a85760a05753 (patch)
treed2314e6ba16273b4ab232d2c38995d1ce59210eb /test/fixtures
parent0e66d4dcc53fad046673346f3db83346ad54e3e8 (diff)
downloadqtlocation-mapboxgl-716997b99eed50ecf35fd1ec3124a85760a05753.tar.gz
[tests] Refactor and make MockFileSource more general
Now it works more like StubStyleObserver: you can assign std::functions to specific slots based on resource type. Rewrite resource loading tests in that style, making them less like integration tests of Style and more like unit tests of Source, GlyphStore, and SpriteStore.
Diffstat (limited to 'test/fixtures')
-rw-r--r--test/fixtures/mock_file_source.cpp69
-rw-r--r--test/fixtures/mock_file_source.hpp55
-rw-r--r--test/fixtures/resources/style-unused-sources.json6
-rw-r--r--test/fixtures/stub_file_source.cpp66
-rw-r--r--test/fixtures/stub_file_source.hpp43
5 files changed, 111 insertions, 128 deletions
diff --git a/test/fixtures/mock_file_source.cpp b/test/fixtures/mock_file_source.cpp
deleted file mode 100644
index 078271a422..0000000000
--- a/test/fixtures/mock_file_source.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-#include "mock_file_source.hpp"
-#include <mbgl/util/io.hpp>
-#include <mbgl/util/chrono.hpp>
-
-namespace mbgl {
-
-class MockFileRequest : public FileRequest {
-public:
- MockFileRequest(MockFileSource& fileSource_)
- : fileSource(fileSource_) {
- }
-
- ~MockFileRequest() {
- fileSource.pending.erase(this);
- }
-
- MockFileSource& fileSource;
-};
-
-MockFileSource::MockFileSource(Type type_, const std::string& match_)
- : type(type_), match(match_) {
- timer.start(Milliseconds(10), Milliseconds(10), [this] {
- // Explicit move to avoid iterator invalidation if ~MockFileRequest gets called within the loop.
- auto pending_ = std::move(pending);
- for (auto& pair : pending_) {
- respond(pair.second.first, pair.second.second);
- }
- });
-}
-
-MockFileSource::~MockFileSource() {
- timer.stop();
-}
-
-void MockFileSource::respond(Resource resource, Callback callback) const {
- if (type == Type::Success || resource.url.find(match) == std::string::npos) {
- Response res;
- try {
- res.data = std::make_shared<const std::string>(util::read_file(resource.url));
- } catch (const std::exception& err) {
- res.error = std::make_unique<Response::Error>(Response::Error::Reason::Other, err.what());
- }
- callback(res);
- } else if (type == Type::RequestFail) {
- Response res;
- res.error = std::make_unique<Response::Error>(Response::Error::Reason::Other, "Failed by the test case");
- callback(res);
- } else if (type == Type::RequestWithCorruptedData) {
- Response res;
- auto data = std::make_shared<std::string>(util::read_file(resource.url));
- data->insert(0, "CORRUPTED");
- res.data = std::move(data);
- callback(res);
- }
-}
-
-std::unique_ptr<FileRequest> MockFileSource::request(const Resource& resource, Callback callback) {
- auto req = std::make_unique<MockFileRequest>(*this);
-
- pending.emplace(req.get(), std::make_pair(resource, callback));
-
- if (requestEnqueuedCallback && resource.url.find(match) != std::string::npos) {
- requestEnqueuedCallback();
- }
-
- return std::move(req);
-}
-
-} // namespace mbgl
diff --git a/test/fixtures/mock_file_source.hpp b/test/fixtures/mock_file_source.hpp
deleted file mode 100644
index 245e0da0eb..0000000000
--- a/test/fixtures/mock_file_source.hpp
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef TEST_RESOURCES_MOCK_FILE_SOURCE
-#define TEST_RESOURCES_MOCK_FILE_SOURCE
-
-#include <mbgl/storage/file_source.hpp>
-#include <mbgl/util/timer.hpp>
-
-#include <string>
-#include <unordered_map>
-
-namespace mbgl {
-
-// The MockFileSource is a FileSource that can simulate different
-// types of failures and it will work completely offline.
-class MockFileSource : public FileSource {
-public:
- // Success:
- // Will reply to every request correctly with valid data.
- //
- // RequestFail:
- // Will reply with an error to requests that contains
- // the "match" string on the URL.
- //
- // RequestWithCorruptedData:
- // Will answer every request successfully but will return
- // corrupt data on the requests that contains the "match"
- // string on the URL.
- enum Type {
- Success,
- RequestFail,
- RequestWithCorruptedData
- };
-
- MockFileSource(Type, const std::string& match);
- ~MockFileSource() override;
-
- // Function that gets called when a matching resource is enqueued.
- std::function<void (void)> requestEnqueuedCallback;
-
- // FileSource implementation.
- std::unique_ptr<FileRequest> request(const Resource&, Callback) override;
-
-private:
- void respond(Resource, Callback) const;
-
- friend class MockFileRequest;
-
- Type type;
- std::string match;
- std::unordered_map<FileRequest*, std::pair<Resource, Callback>> pending;
- util::Timer timer;
-};
-
-}
-
-#endif
diff --git a/test/fixtures/resources/style-unused-sources.json b/test/fixtures/resources/style-unused-sources.json
index 3878f85dd8..ede1c9adfd 100644
--- a/test/fixtures/resources/style-unused-sources.json
+++ b/test/fixtures/resources/style-unused-sources.json
@@ -3,16 +3,14 @@
"name": "Test",
"sources": {
"usedsource": {
- "url": "test/fixtures/resources/source_vector.json",
+ "tiles": [],
"type": "vector"
},
"unusedsource": {
- "url": "test/fixtures/resources/source_vector.json",
+ "tiles": [],
"type": "vector"
}
},
- "sprite": "test/fixtures/resources/sprite",
- "glyphs": "test/fixtures/resources/glyphs.pbf",
"layers": [{
"id": "usedlayer",
"type": "symbol",
diff --git a/test/fixtures/stub_file_source.cpp b/test/fixtures/stub_file_source.cpp
new file mode 100644
index 0000000000..57bc178ac1
--- /dev/null
+++ b/test/fixtures/stub_file_source.cpp
@@ -0,0 +1,66 @@
+#include "stub_file_source.hpp"
+
+namespace mbgl {
+
+using namespace std::chrono_literals;
+
+class StubFileRequest : public FileRequest {
+public:
+ StubFileRequest(StubFileSource& fileSource_)
+ : fileSource(fileSource_) {
+ }
+
+ ~StubFileRequest() {
+ fileSource.pending.erase(this);
+ }
+
+ StubFileSource& fileSource;
+};
+
+StubFileSource::StubFileSource() {
+ timer.start(10ms, 10ms, [this] {
+ // Explicit move to avoid iterator invalidation if ~StubFileRequest gets called within the loop.
+ auto pending_ = std::move(pending);
+ for (auto& pair : pending_) {
+ pair.second.second(pair.second.first);
+ }
+ });
+}
+
+StubFileSource::~StubFileSource() = default;
+
+std::unique_ptr<FileRequest> StubFileSource::request(const Resource& resource, Callback callback) {
+ auto req = std::make_unique<StubFileRequest>(*this);
+ pending.emplace(req.get(), std::make_pair(response(resource), callback));
+ return std::move(req);
+}
+
+Response StubFileSource::defaultResponse(const Resource& resource) {
+ switch (resource.kind) {
+ case Resource::Kind::Style:
+ if (!styleResponse) throw std::runtime_error("unexpected style request");
+ return styleResponse(resource);
+ case Resource::Kind::Source:
+ if (!sourceResponse) throw std::runtime_error("unexpected source request");
+ return sourceResponse(resource);
+ case Resource::Kind::Tile:
+ if (!tileResponse) throw std::runtime_error("unexpected tile request");
+ return tileResponse(resource);
+ case Resource::Kind::Glyphs:
+ if (!glyphsResponse) throw std::runtime_error("unexpected glyphs request");
+ return glyphsResponse(resource);
+ case Resource::Kind::SpriteJSON:
+ if (!spriteJSONResponse) throw std::runtime_error("unexpected sprite JSON request");
+ return spriteJSONResponse(resource);
+ case Resource::Kind::SpriteImage:
+ if (!spriteImageResponse) throw std::runtime_error("unexpected sprite image request");
+ return spriteImageResponse(resource);
+ case Resource::Kind::Unknown:
+ throw std::runtime_error("unknown resource type");
+ }
+
+ // The above switch is exhaustive, but placate GCC nonetheless:
+ return Response();
+}
+
+} // namespace mbgl
diff --git a/test/fixtures/stub_file_source.hpp b/test/fixtures/stub_file_source.hpp
new file mode 100644
index 0000000000..7cb9c89320
--- /dev/null
+++ b/test/fixtures/stub_file_source.hpp
@@ -0,0 +1,43 @@
+#ifndef TEST_RESOURCES_STUB_FILE_SOURCE
+#define TEST_RESOURCES_STUB_FILE_SOURCE
+
+#include <mbgl/storage/file_source.hpp>
+#include <mbgl/util/timer.hpp>
+
+#include <unordered_map>
+
+namespace mbgl {
+
+class StubFileSource : public FileSource {
+public:
+ StubFileSource();
+ ~StubFileSource() override;
+
+ std::unique_ptr<FileRequest> request(const Resource&, Callback) override;
+
+ // You can set the response callback on a global level by assigning this callback:
+ std::function<Response (const Resource&)> response = [this] (const Resource& resource) {
+ return defaultResponse(resource);
+ };
+
+ // Or set per-kind responses by setting these callbacks:
+ std::function<Response (const Resource&)> styleResponse;
+ std::function<Response (const Resource&)> sourceResponse;
+ std::function<Response (const Resource&)> tileResponse;
+ std::function<Response (const Resource&)> glyphsResponse;
+ std::function<Response (const Resource&)> spriteJSONResponse;
+ std::function<Response (const Resource&)> spriteImageResponse;
+
+private:
+ friend class StubFileRequest;
+
+ // The default behavior is to throw if no per-kind callback has been set.
+ Response defaultResponse(const Resource&);
+
+ std::unordered_map<FileRequest*, std::pair<Response, Callback>> pending;
+ util::Timer timer;
+};
+
+}
+
+#endif