summaryrefslogtreecommitdiff
path: root/test/resources
diff options
context:
space:
mode:
authorAnsis Brammanis <brammanis@gmail.com>2015-05-28 20:01:15 -0400
committerAnsis Brammanis <brammanis@gmail.com>2015-05-28 20:01:15 -0400
commitff6a5ce5bc674e17a24c3f18b305d5dd2f0e21b0 (patch)
tree405ec719109186590311262045ff1651b06e9506 /test/resources
parentfd19eb79056b8e62f037c0ae4532f4f7cc970580 (diff)
parent6c166b564ebb3acefb56bb4d39be4813851db4a7 (diff)
downloadqtlocation-mapboxgl-ff6a5ce5bc674e17a24c3f18b305d5dd2f0e21b0.tar.gz
Merge remote-tracking branch 'origin/master' into new-labelling
Conflicts: src/mbgl/map/source.cpp src/mbgl/map/source.hpp src/mbgl/map/tile_data.cpp src/mbgl/map/tile_parser.cpp src/mbgl/map/vector_tile_data.cpp src/mbgl/renderer/painter.cpp src/mbgl/renderer/symbol_bucket.cpp src/mbgl/text/glyph.hpp src/mbgl/text/glyph_store.cpp src/mbgl/text/placement.cpp test/suite
Diffstat (limited to 'test/resources')
-rw-r--r--test/resources/mock_file_source.cpp82
-rw-r--r--test/resources/mock_file_source.hpp40
-rw-r--r--test/resources/mock_view.hpp21
-rw-r--r--test/resources/resource_loader.cpp204
4 files changed, 347 insertions, 0 deletions
diff --git a/test/resources/mock_file_source.cpp b/test/resources/mock_file_source.cpp
new file mode 100644
index 0000000000..42067a2a73
--- /dev/null
+++ b/test/resources/mock_file_source.cpp
@@ -0,0 +1,82 @@
+#include "../fixtures/util.hpp"
+#include "mock_file_source.hpp"
+
+#include <mbgl/storage/request.hpp>
+#include <mbgl/util/io.hpp>
+#include <mbgl/util/thread.hpp>
+
+namespace mbgl {
+
+class MockFileSource::Impl {
+public:
+ Impl(uv_loop_t*, Type type, const std::string& match) : type_(type), match_(match) {}
+
+ void handleRequest(Request* req) const;
+
+private:
+ void replyWithFailure(Response* res) const;
+ void replyWithCorruptedData(Response* res, const std::string& url) const;
+ void replyWithSuccess(Response* res, const std::string& url) const;
+
+ Type type_;
+ std::string match_;
+};
+
+void MockFileSource::Impl::replyWithFailure(Response* res) const {
+ res->status = Response::Status::Error;
+ res->message = "Failed by the test case";
+}
+
+void MockFileSource::Impl::replyWithCorruptedData(Response* res, const std::string& url) const {
+ res->status = Response::Status::Successful;
+ res->data = util::read_file(url);
+ res->data.insert(0, "CORRUPTED");
+}
+
+void MockFileSource::Impl::replyWithSuccess(Response* res, const std::string& url) const {
+ res->status = Response::Status::Successful;
+ res->data = util::read_file(url);
+}
+
+void MockFileSource::Impl::handleRequest(Request* req) const {
+ const std::string& url = req->resource.url;
+ std::shared_ptr<Response> response = std::make_shared<Response>();
+
+ if (url.find(match_) == std::string::npos) {
+ replyWithSuccess(response.get(), url);
+ req->notify(response);
+ return;
+ }
+
+ switch (type_) {
+ case Type::Success:
+ replyWithSuccess(response.get(), url);
+ break;
+ case Type::RequestFail:
+ replyWithFailure(response.get());
+ break;
+ case Type::RequestWithCorruptedData:
+ replyWithCorruptedData(response.get(), url);
+ break;
+ default:
+ EXPECT_TRUE(false) << "Should never be reached.";
+ }
+
+ req->notify(response);
+}
+
+MockFileSource::MockFileSource(Type type, const std::string& match)
+ : thread_(std::make_unique<util::Thread<Impl>>("FileSource", util::ThreadPriority::Low, type, match)) {
+}
+
+Request* MockFileSource::request(const Resource& resource, uv_loop_t* loop, Callback callback) {
+ Request* req = new Request(resource, loop, std::move(callback));
+ thread_->invoke(&Impl::handleRequest, req);
+
+ return req;
+}
+
+void MockFileSource::cancel(Request*) {
+}
+
+}
diff --git a/test/resources/mock_file_source.hpp b/test/resources/mock_file_source.hpp
new file mode 100644
index 0000000000..bb9fb55a30
--- /dev/null
+++ b/test/resources/mock_file_source.hpp
@@ -0,0 +1,40 @@
+#ifndef TEST_RESOURCES_MOCK_FILE_SOURCE
+#define TEST_RESOURCES_MOCK_FILE_SOURCE
+
+#include <mbgl/storage/file_source.hpp>
+
+#include <string>
+#include <memory>
+
+namespace mbgl {
+
+namespace util {
+template <typename T> class Thread;
+}
+
+// This mock FileSource will read data from the disk and will fail
+// the request if the URL matches a string.
+class MockFileSource : public FileSource {
+public:
+ enum Type {
+ Success,
+ RequestFail,
+ RequestWithCorruptedData
+ };
+
+ class Impl;
+
+ MockFileSource(Type type, const std::string& match);
+ ~MockFileSource() override = default;
+
+ // FileSource implementation.
+ Request* request(const Resource&, uv_loop_t*, Callback) override;
+ void cancel(Request*) override;
+
+private:
+ const std::unique_ptr<util::Thread<Impl>> thread_;
+};
+
+}
+
+#endif
diff --git a/test/resources/mock_view.hpp b/test/resources/mock_view.hpp
new file mode 100644
index 0000000000..865cd2da55
--- /dev/null
+++ b/test/resources/mock_view.hpp
@@ -0,0 +1,21 @@
+#ifndef TEST_RESOURCES_MOCK_VIEW
+#define TEST_RESOURCES_MOCK_VIEW
+
+#include <mbgl/map/view.hpp>
+
+namespace mbgl {
+
+class MockView : public View {
+public:
+ MockView() = default;
+
+ // View implementation.
+ void activate() override {};
+ void deactivate() override {};
+ void notify() override {};
+ void invalidate(std::function<void()>) override {};
+};
+
+}
+
+#endif
diff --git a/test/resources/resource_loader.cpp b/test/resources/resource_loader.cpp
new file mode 100644
index 0000000000..7d57f47ee6
--- /dev/null
+++ b/test/resources/resource_loader.cpp
@@ -0,0 +1,204 @@
+#include "../fixtures/fixture_log_observer.hpp"
+#include "../fixtures/util.hpp"
+#include "mock_file_source.hpp"
+#include "mock_view.hpp"
+
+#include <mbgl/geometry/glyph_atlas.hpp>
+#include <mbgl/geometry/sprite_atlas.hpp>
+#include <mbgl/map/environment.hpp>
+#include <mbgl/map/map_data.hpp>
+#include <mbgl/map/resource_loader.hpp>
+#include <mbgl/map/transform_state.hpp>
+#include <mbgl/style/style.hpp>
+#include <mbgl/text/glyph_store.hpp>
+#include <mbgl/util/exception.hpp>
+#include <mbgl/util/io.hpp>
+#include <mbgl/util/run_loop.hpp>
+#include <mbgl/util/texture_pool.hpp>
+#include <mbgl/util/thread.hpp>
+
+using namespace mbgl;
+
+namespace {
+
+class MockMapContext : public ResourceLoader::Observer {
+public:
+ MockMapContext(uv_loop_t* loop,
+ View& view,
+ FileSource& fileSource,
+ const std::function<void(std::exception_ptr error)>& callback)
+ : env_(fileSource),
+ envScope_(env_, ThreadType::Map, "Map"),
+ data_(view, MapMode::Still),
+ glyphStore_(std::make_unique<GlyphStore>(loop, env_)),
+ glyphAtlas_(std::make_unique<GlyphAtlas>(1024, 1024)),
+ spriteAtlas_(std::make_unique<SpriteAtlas>(512, 512)),
+ texturePool_(std::make_unique<TexturePool>()),
+ style_(std::make_unique<Style>()),
+ resourceLoader_(std::make_unique<ResourceLoader>()),
+ asyncUpdate(std::make_unique<uv::async>(loop, [this] { update(); })),
+ callback_(callback) {
+ asyncUpdate->unref();
+
+ data_.transform.resize(1000, 1000, 1.0, 1000, 1000);
+ data_.transform.setLatLngZoom({0, 0}, 16);
+
+ const std::string style = util::read_file("test/fixtures/resources/style.json");
+ style_->loadJSON(reinterpret_cast<const uint8_t *>(style.c_str()));
+
+ glyphStore_->setURL(style_->glyph_url);
+
+ resourceLoader_->setGlyphStore(glyphStore_.get());
+ resourceLoader_->setObserver(this);
+ resourceLoader_->setStyle(style_.get());
+ }
+
+ ~MockMapContext() {
+ resourceLoader_.reset();
+ style_.reset();
+ texturePool_.reset();
+ spriteAtlas_.reset();
+ glyphAtlas_.reset();
+ glyphStore_.reset();
+ }
+
+ void update() {
+ const auto now = Clock::now();
+
+ data_.setAnimationTime(now);
+ data_.transform.updateTransitions(now);
+
+ transformState_ = data_.transform.currentState();
+
+ resourceLoader_->update(
+ data_, transformState_, *glyphAtlas_, *spriteAtlas_, *texturePool_);
+ }
+
+ // ResourceLoader::Observer implementation.
+ void onTileDataChanged() override {
+ util::ptr<Sprite> sprite = resourceLoader_->getSprite();
+ if (sprite && sprite->isLoaded() && style_->isLoaded()) {
+ callback_(nullptr);
+ }
+
+ asyncUpdate->send();
+ };
+
+ void onResourceLoadingFailed(std::exception_ptr error) override {
+ callback_(error);
+ }
+
+private:
+ Environment env_;
+ EnvironmentScope envScope_;
+
+ MapData data_;
+ TransformState transformState_;
+
+ std::unique_ptr<GlyphStore> glyphStore_;
+ std::unique_ptr<GlyphAtlas> glyphAtlas_;
+ std::unique_ptr<SpriteAtlas> spriteAtlas_;
+ std::unique_ptr<TexturePool> texturePool_;
+ std::unique_ptr<Style> style_;
+ std::unique_ptr<ResourceLoader> resourceLoader_;
+
+ std::unique_ptr<uv::async> asyncUpdate;
+
+ std::function<void(std::exception_ptr error)> callback_;
+};
+
+void runTestCase(MockFileSource::Type type,
+ const std::string& param,
+ const std::string& message) {
+ util::RunLoop loop(uv_default_loop());
+
+ MockView view;
+ MockFileSource fileSource(type, param);
+
+ FixtureLogObserver* log = new FixtureLogObserver();
+ Log::setObserver(std::unique_ptr<Log::Observer>(log));
+
+ auto callback = [&loop, &param](std::exception_ptr error) {
+ try {
+ if (error) {
+ std::rethrow_exception(error);
+ }
+ } catch (const util::GlyphRangeLoadingException&) {
+ EXPECT_EQ(param, "glyphs.pbf");
+ } catch (const util::SourceLoadingException&) {
+ EXPECT_EQ(param, "source.json");
+ } catch (const util::SpriteLoadingException&) {
+ EXPECT_TRUE(param == "sprite.png" || param == "sprite.json");
+ } catch (const util::TileLoadingException&) {
+ EXPECT_EQ(param, "vector.pbf");
+ } catch (const std::exception&) {
+ EXPECT_TRUE(false) << "Unhandled exception.";
+ }
+
+ loop.stop();
+ };
+
+ std::unique_ptr<util::Thread<MockMapContext>> context(
+ std::make_unique<util::Thread<MockMapContext>>(
+ "Map", util::ThreadPriority::Regular, view, fileSource, callback));
+
+ uv_run(loop.get(), UV_RUN_DEFAULT);
+
+ // Needed because it will make the Map thread
+ // join and cease logging after this point.
+ context.reset();
+
+ const FixtureLogObserver::LogMessage logMessage {
+ EventSeverity::Error,
+ Event::ResourceLoader,
+ int64_t(-1),
+ message,
+ };
+
+ if (type == MockFileSource::Success) {
+ EXPECT_EQ(log->count(logMessage), 0u);
+ } else {
+ EXPECT_GT(log->count(logMessage), 0u);
+ }
+
+ // Clear the remaining error messages
+ log->unchecked().size();
+}
+
+}
+
+class ResourceLoaderTest : public ::testing::TestWithParam<std::string> {
+};
+
+TEST_P(ResourceLoaderTest, Success) {
+ runTestCase(MockFileSource::Success, GetParam(), std::string());
+}
+
+TEST_P(ResourceLoaderTest, RequestFail) {
+ std::stringstream message;
+ message << "Failed to load [test/fixtures/resources/" << GetParam() << "]: Failed by the test case";
+
+ runTestCase(MockFileSource::RequestFail, GetParam(), message.str());
+}
+
+TEST_P(ResourceLoaderTest, RequestWithCorruptedData) {
+ const std::string param(GetParam());
+
+ std::stringstream message;
+ message << "Failed to parse ";
+
+ if (param == "vector.pbf") {
+ message << "[15/16384/16384]: pbf unknown field type exception";
+ } else {
+ message << "[test/fixtures/resources/" << param << "]";
+ }
+
+ if (param.find("json") != std::string::npos) {
+ message << ": 0 - Expect either an object or array at root";
+ }
+
+ runTestCase(MockFileSource::RequestWithCorruptedData, GetParam(), message.str());
+}
+
+INSTANTIATE_TEST_CASE_P(ResourceLoader, ResourceLoaderTest,
+ ::testing::Values("source.json", "sprite.json", "sprite.png", "vector.pbf", "glyphs.pbf"));