summaryrefslogtreecommitdiff
path: root/test/style
diff options
context:
space:
mode:
authorThiago Marcos P. Santos <thiago@mapbox.com>2015-06-30 10:49:34 +0300
committerThiago Marcos P. Santos <thiago@mapbox.com>2015-07-16 19:38:39 +0300
commitcd2c1200c87afbe05bd2d63caa0959a0fff32d94 (patch)
treec4af0214210d8186d9c7e36c35f526fa15a8ea50 /test/style
parenta75cc8c06b8d931b3b85dd9ac6d852f84b06e5b2 (diff)
downloadqtlocation-mapboxgl-cd2c1200c87afbe05bd2d63caa0959a0fff32d94.tar.gz
Add GlyphStore unit tests
Diffstat (limited to 'test/style')
-rw-r--r--test/style/glyph_store.cpp225
1 files changed, 225 insertions, 0 deletions
diff --git a/test/style/glyph_store.cpp b/test/style/glyph_store.cpp
new file mode 100644
index 0000000000..fb4355b98b
--- /dev/null
+++ b/test/style/glyph_store.cpp
@@ -0,0 +1,225 @@
+#include "../fixtures/fixture_log_observer.hpp"
+#include "../fixtures/mock_file_source.hpp"
+#include "../fixtures/util.hpp"
+
+#include <mbgl/text/font_stack.hpp>
+#include <mbgl/text/glyph_store.hpp>
+#include <mbgl/util/run_loop.hpp>
+#include <mbgl/util/thread.hpp>
+
+using namespace mbgl;
+
+using GlyphStoreTestCallback = std::function<void(GlyphStore*, std::exception_ptr)>;
+
+struct GlyphStoreParams {
+ const std::string url;
+ const std::string stack;
+ const std::set<GlyphRange> ranges;
+};
+
+class GlyphStoreThread : public GlyphStore::Observer {
+public:
+ GlyphStoreThread(FileSource* fileSource, GlyphStoreTestCallback callback) : callback_(callback) {
+ util::ThreadContext::setFileSource(fileSource);
+ }
+
+ void loadGlyphStore(const GlyphStoreParams& params) {
+ glyphStore_.reset(new GlyphStore());
+
+ glyphStore_->setObserver(this);
+ glyphStore_->setURL(params.url);
+
+ ASSERT_FALSE(glyphStore_->hasGlyphRanges(params.stack, params.ranges));
+ }
+
+ void unloadGlyphStore() {
+ glyphStore_->setObserver(nullptr);
+ glyphStore_.reset();
+ }
+
+ void onGlyphRangeLoaded() override {
+ callback_(glyphStore_.get(), nullptr);
+ }
+
+ void onGlyphRangeLoadingFailed(std::exception_ptr error) override {
+ callback_(glyphStore_.get(), error);
+ }
+
+private:
+ std::unique_ptr<GlyphStore> glyphStore_;
+ GlyphStoreTestCallback callback_;
+};
+
+class GlyphStoreTest : public testing::Test {
+protected:
+ void runTest(const GlyphStoreParams& params, FileSource* fileSource, GlyphStoreTestCallback callback) {
+ util::RunLoop loop(uv_default_loop());
+
+ async_ = std::make_unique<uv::async>(loop.get(), [&]{ loop.stop(); });
+ async_->unref();
+
+ const util::ThreadContext context = {"Map", util::ThreadType::Map, util::ThreadPriority::Regular};
+
+ util::Thread<GlyphStoreThread> tester(context, fileSource, callback);
+ tester.invoke(&GlyphStoreThread::loadGlyphStore, params);
+
+ uv_run(loop.get(), UV_RUN_DEFAULT);
+
+ tester.invoke(&GlyphStoreThread::unloadGlyphStore);
+ }
+
+ void stopTest() {
+ testDone = true;
+ async_->send();
+ }
+
+ bool isDone() const {
+ return testDone;
+ }
+
+private:
+ bool testDone = false;
+
+ std::unique_ptr<uv::async> async_;
+};
+
+TEST_F(GlyphStoreTest, LoadingSuccess) {
+ GlyphStoreParams params = {
+ "test/fixtures/resources/glyphs.pbf",
+ "Test Stack",
+ {{0, 255}, {256, 511}}
+ };
+
+ auto callback = [this, &params](GlyphStore* store, std::exception_ptr error) {
+ ASSERT_TRUE(util::ThreadContext::currentlyOn(util::ThreadType::Map));
+
+ // We need to check if the test is over because checking
+ // if the GlyphStore has glyphs below will cause more requests
+ // to happen and we don't want this endless loop.
+ if (isDone()) {
+ return;
+ }
+
+ ASSERT_EQ(error, nullptr);
+
+ if (!store->hasGlyphRanges(params.stack, params.ranges)) {
+ return;
+ }
+
+ ASSERT_FALSE(store->hasGlyphRanges("Foobar", params.ranges));
+ ASSERT_FALSE(store->hasGlyphRanges("Foobar", {{512, 767}}));
+ ASSERT_FALSE(store->hasGlyphRanges("Test Stack", {{512, 767}}));
+
+ auto fontStack = store->getFontStack(params.stack);
+ ASSERT_FALSE(fontStack->getMetrics().empty());
+ ASSERT_FALSE(fontStack->getSDFs().empty());
+
+ stopTest();
+ };
+
+ MockFileSource fileSource(MockFileSource::Success, "");
+ runTest(params, &fileSource, callback);
+}
+
+TEST_F(GlyphStoreTest, LoadingFail) {
+ GlyphStoreParams params = {
+ "test/fixtures/resources/glyphs.pbf",
+ "Test Stack",
+ {{0, 255}, {256, 511}}
+ };
+
+ auto callback = [this, &params](GlyphStore* store, std::exception_ptr error) {
+ ASSERT_TRUE(util::ThreadContext::currentlyOn(util::ThreadType::Map));
+
+ if (isDone()) {
+ return;
+ }
+
+ ASSERT_TRUE(error != nullptr);
+
+ auto fontStack = store->getFontStack(params.stack);
+ ASSERT_EQ(*fontStack, nullptr);
+
+ for (const auto& range : params.ranges) {
+ ASSERT_FALSE(store->hasGlyphRanges(params.stack, {range}));
+ }
+
+ ASSERT_FALSE(store->hasGlyphRanges(params.stack, params.ranges));
+ ASSERT_FALSE(store->hasGlyphRanges("Foobar", params.ranges));
+ ASSERT_FALSE(store->hasGlyphRanges("Foobar", {{512, 767}}));
+
+ stopTest();
+ };
+
+ MockFileSource fileSource(MockFileSource::RequestFail, "glyphs.pbf");
+ runTest(params, &fileSource, callback);
+}
+
+TEST_F(GlyphStoreTest, LoadingCorrupted) {
+ GlyphStoreParams params = {
+ "test/fixtures/resources/glyphs.pbf",
+ "Test Stack",
+ {{0, 255}, {256, 511}}
+ };
+
+ auto callback = [this, &params](GlyphStore* store, std::exception_ptr error) {
+ ASSERT_TRUE(util::ThreadContext::currentlyOn(util::ThreadType::Map));
+
+ if (isDone()) {
+ return;
+ }
+
+ ASSERT_TRUE(error != nullptr);
+
+ for (const auto& range : params.ranges) {
+ ASSERT_FALSE(store->hasGlyphRanges(params.stack, {range}));
+ }
+
+ ASSERT_FALSE(store->hasGlyphRanges(params.stack, params.ranges));
+ ASSERT_FALSE(store->hasGlyphRanges("Foobar", params.ranges));
+ ASSERT_FALSE(store->hasGlyphRanges("Foobar", {{512, 767}}));
+
+ stopTest();
+ };
+
+ MockFileSource fileSource(MockFileSource::RequestWithCorruptedData, "glyphs.pbf");
+ runTest(params, &fileSource, callback);
+}
+
+TEST_F(GlyphStoreTest, LoadingCancel) {
+ GlyphStoreParams params = {
+ "test/fixtures/resources/glyphs.pbf",
+ "Test Stack",
+ {{0, 255}, {256, 511}}
+ };
+
+ auto callback = [this](GlyphStore*, std::exception_ptr) {
+ FAIL() << "Should never be called";
+ };
+
+ MockFileSource fileSource(MockFileSource::SuccessWithDelay, "glyphs.pbf");
+ fileSource.setOnRequestDelayedCallback([this]{
+ stopTest();
+ });
+ runTest(params, &fileSource, callback);
+}
+
+TEST_F(GlyphStoreTest, InvalidURL) {
+ GlyphStoreParams params = {
+ "foo bar",
+ "Test Stack",
+ {{0, 255}, {256, 511}}
+ };
+
+ auto callback = [this, &params](GlyphStore* store, std::exception_ptr error) {
+ ASSERT_TRUE(error != nullptr);
+
+ auto fontStack = store->getFontStack(params.stack);
+ ASSERT_EQ(*fontStack, nullptr);
+
+ stopTest();
+ };
+
+ MockFileSource fileSource(MockFileSource::Success, "");
+ runTest(params, &fileSource, callback);
+}