[tests] Rewrite {Sprite,Glyph}Store tests in the style of ResourceLoading

This commit is contained in:
John Firebaugh
2015-12-23 16:54:34 -08:00
parent aca584e124
commit 338f94e7ed
4 changed files with 224 additions and 368 deletions

67
test/fixtures/stub_style_observer.hpp vendored Normal file
View File

@@ -0,0 +1,67 @@
#ifndef MBGL_TEST_STUB_STYLE_OBSERVER
#define MBGL_TEST_STUB_STYLE_OBSERVER
#include <mbgl/style/style.hpp>
namespace mbgl {
/**
* An implementation of Style::Observer that forwards all methods to dynamically-settable lambas.
*/
class StubStyleObserver : public Style::Observer {
public:
void onGlyphsLoaded(const std::string& fontStack, const GlyphRange& glyphRange) override {
if (glyphsLoaded) glyphsLoaded(fontStack, glyphRange);
}
void onGlyphsError(const std::string& fontStack, const GlyphRange& glyphRange, std::exception_ptr error) override {
if (glyphsError) glyphsError(fontStack, glyphRange, error);
}
void onSpriteLoaded() override {
if (spriteLoaded) spriteLoaded();
}
void onSpriteError(std::exception_ptr error) override {
if (spriteError) spriteError(error);
}
void onSourceLoaded(Source& source) override {
if (sourceLoaded) sourceLoaded(source);
}
void onSourceError(Source& source, std::exception_ptr error) override {
if (sourceError) sourceError(source, error);
}
void onTileLoaded(Source& source, const TileID& tileID, bool isNewTile) override {
if (tileLoaded) tileLoaded(source, tileID, isNewTile);
}
void onTileError(Source& source, const TileID& tileID, std::exception_ptr error) override {
if (tileError) tileError(source, tileID, error);
}
void onResourceLoaded() override {
if (resourceLoaded) resourceLoaded();
};
void onResourceError(std::exception_ptr error) override {
if (resourceError) resourceError(error);
};
std::function<void (const std::string& fontStack, const GlyphRange&)> glyphsLoaded;
std::function<void (const std::string& fontStack, const GlyphRange&, std::exception_ptr)> glyphsError;
std::function<void ()> spriteLoaded;
std::function<void (std::exception_ptr)> spriteError;
std::function<void (Source&)> sourceLoaded;
std::function<void (Source&, std::exception_ptr)> sourceError;
std::function<void (Source&, const TileID&, bool isNewTile)> tileLoaded;
std::function<void (Source&, const TileID&, std::exception_ptr)> tileError;
std::function<void ()> resourceLoaded;
std::function<void (std::exception_ptr)> resourceError;
};
} // namespace mbgl
#endif

View File

@@ -1,17 +1,16 @@
#include "../fixtures/util.hpp"
#include "../fixtures/fixture_log_observer.hpp"
#include "../fixtures/mock_file_source.hpp"
#include "../fixtures/stub_style_observer.hpp"
#include <mbgl/sprite/sprite_store.hpp>
#include <mbgl/util/async_task.hpp>
#include <mbgl/util/run_loop.hpp>
#include <mbgl/util/thread.hpp>
#include <utility>
using namespace mbgl;
TEST(Sprite, SpriteStore) {
TEST(SpriteStore, SpriteStore) {
FixtureLog log;
const auto sprite1 = std::make_shared<SpriteImage>(8, 8, 2, std::string(16 * 16 * 4, '\0'));
@@ -77,7 +76,7 @@ TEST(Sprite, SpriteStore) {
EXPECT_EQ(Sprites(), store.getDirty());
}
TEST(Sprite, SpriteStoreOtherPixelRatio) {
TEST(SpriteStore, OtherPixelRatio) {
FixtureLog log;
const auto sprite1 = std::make_shared<SpriteImage>(8, 8, 1, std::string(8 * 8 * 4, '\0'));
@@ -90,7 +89,7 @@ TEST(Sprite, SpriteStoreOtherPixelRatio) {
EXPECT_EQ(Sprites({ { "one", sprite1 } }), store.getDirty());
}
TEST(Sprite, SpriteStoreMultiple) {
TEST(SpriteStore, Multiple) {
const auto sprite1 = std::make_shared<SpriteImage>(8, 8, 2, std::string(16 * 16 * 4, '\0'));
const auto sprite2 = std::make_shared<SpriteImage>(8, 8, 2, std::string(16 * 16 * 4, '\0'));
@@ -107,7 +106,7 @@ TEST(Sprite, SpriteStoreMultiple) {
EXPECT_EQ(Sprites(), store.getDirty());
}
TEST(Sprite, SpriteStoreReplace) {
TEST(SpriteStore, Replace) {
FixtureLog log;
const auto sprite1 = std::make_shared<SpriteImage>(8, 8, 2, std::string(16 * 16 * 4, '\0'));
@@ -124,7 +123,7 @@ TEST(Sprite, SpriteStoreReplace) {
EXPECT_EQ(Sprites({ { "sprite", sprite2 } }), store.getDirty());
}
TEST(Sprite, SpriteStoreReplaceWithDifferentDimensions) {
TEST(SpriteStore, ReplaceWithDifferentDimensions) {
FixtureLog log;
const auto sprite1 = std::make_shared<SpriteImage>(8, 8, 2, std::string(16 * 16 * 4, '\0'));
@@ -148,167 +147,100 @@ TEST(Sprite, SpriteStoreReplaceWithDifferentDimensions) {
EXPECT_EQ(Sprites({ { "sprite", sprite1 } }), store.getDirty());
}
using SpriteTestCallback = std::function<void(SpriteStore*, std::exception_ptr)>;
struct SpriteParams {
const std::string baseUrl;
const float pixelRatio;
};
class SpriteThread : public SpriteStore::Observer {
class SpriteStoreTest {
public:
SpriteThread(FileSource* fileSource, SpriteTestCallback callback) : callback_(std::move(callback)) {
util::ThreadContext::setFileSource(fileSource);
}
SpriteStoreTest(MockFileSource::Type type, const std::string& resource)
: fileSource(type, resource),
spriteStore(1.0) {}
void loadSprite(const SpriteParams& params) {
spriteStore_.reset(new SpriteStore(params.pixelRatio));
spriteStore_->setObserver(this);
spriteStore_->setURL(params.baseUrl);
}
util::ThreadContext context { "Map", util::ThreadType::Map, util::ThreadPriority::Regular };
util::RunLoop loop;
MockFileSource fileSource;
StubStyleObserver observer;
SpriteStore spriteStore;
void unloadSprite() {
spriteStore_->setObserver(nullptr);
spriteStore_.reset();
}
void run(const std::string& url) {
// Squelch logging.
Log::setObserver(std::make_unique<Log::NullObserver>());
void onSpriteLoaded() override {
callback_(spriteStore_.get(), nullptr);
}
util::ThreadContext::Set(&context);
util::ThreadContext::setFileSource(&fileSource);
void onSpriteError(std::exception_ptr error) override {
callback_(spriteStore_.get(), error);
}
private:
std::unique_ptr<SpriteStore> spriteStore_;
SpriteTestCallback callback_;
};
class SpriteTest : public testing::Test {
protected:
void runTest(const SpriteParams& params, FileSource* fileSource, SpriteTestCallback callback) {
util::RunLoop loop;
async_ = std::make_unique<util::AsyncTask>([&] { loop.stop(); });
async_->unref();
const util::ThreadContext context = {"Map", util::ThreadType::Map, util::ThreadPriority::Regular};
util::Thread<SpriteThread> tester(context, fileSource, callback);
tester.invoke(&SpriteThread::loadSprite, params);
spriteStore.setObserver(&observer);
spriteStore.setURL(url);
loop.run();
tester.invoke(&SpriteThread::unloadSprite);
}
void stopTest() {
async_->send();
void end() {
loop.stop();
}
private:
std::unique_ptr<util::AsyncTask> async_;
};
TEST_F(SpriteTest, LoadingSuccess) {
SpriteParams params = {
"test/fixtures/resources/sprite",
1.0,
TEST(SpriteStore, LoadingSuccess) {
SpriteStoreTest test(MockFileSource::Success, "");
test.observer.spriteError = [&] (std::exception_ptr) {
FAIL();
test.end();
};
auto callback = [this, &params](SpriteStore* spriteStore, std::exception_ptr error) {
ASSERT_TRUE(util::ThreadContext::currentlyOn(util::ThreadType::Map));
ASSERT_TRUE(error == nullptr);
ASSERT_TRUE(!spriteStore->getDirty().empty());
ASSERT_EQ(spriteStore->pixelRatio, params.pixelRatio);
ASSERT_NE(spriteStore->pixelRatio, 1.5);
ASSERT_NE(spriteStore->pixelRatio, 2.0);
ASSERT_TRUE(spriteStore->isLoaded());
stopTest();
test.observer.spriteLoaded = [&] () {
ASSERT_TRUE(!test.spriteStore.getDirty().empty());
ASSERT_EQ(test.spriteStore.pixelRatio, 1.0);
ASSERT_TRUE(test.spriteStore.isLoaded());
test.end();
};
MockFileSource fileSource(MockFileSource::Success, "");
runTest(params, &fileSource, callback);
test.run("test/fixtures/resources/sprite");
}
TEST_F(SpriteTest, LoadingFail) {
SpriteParams params = {
"test/fixtures/resources/sprite",
1.0,
};
auto callback = [this, &params](SpriteStore* spriteStore, std::exception_ptr error) {
ASSERT_TRUE(util::ThreadContext::currentlyOn(util::ThreadType::Map));
TEST(SpriteStore, LoadingFail) {
SpriteStoreTest test(MockFileSource::RequestFail, "sprite.json");
test.observer.spriteError = [&] (std::exception_ptr error) {
ASSERT_TRUE(error != nullptr);
ASSERT_EQ(spriteStore->pixelRatio, params.pixelRatio);
ASSERT_NE(spriteStore->pixelRatio, 1.5);
ASSERT_NE(spriteStore->pixelRatio, 2.0);
ASSERT_FALSE(spriteStore->isLoaded());
stopTest();
ASSERT_FALSE(test.spriteStore.isLoaded());
test.end();
};
MockFileSource fileSourceFailSpriteJSON(MockFileSource::RequestFail, "sprite.json");
runTest(params, &fileSourceFailSpriteJSON, callback);
MockFileSource fileSourceFailSpriteImage(MockFileSource::RequestFail, "sprite.png");
runTest(params, &fileSourceFailSpriteImage, callback);
MockFileSource fileSourceCorruptedSpriteJSON(MockFileSource::RequestWithCorruptedData, "sprite.json");
runTest(params, &fileSourceCorruptedSpriteJSON, callback);
MockFileSource fileSourceCorruptedSpriteImage(MockFileSource::RequestWithCorruptedData, "sprite.png");
runTest(params, &fileSourceCorruptedSpriteImage, callback);
test.run("test/fixtures/resources/sprite");
}
TEST_F(SpriteTest, LoadingCancel) {
SpriteParams params = {
"test/fixtures/resources/sprite",
1.0,
TEST(SpriteStore, LoadingCorrupted) {
SpriteStoreTest test(MockFileSource::RequestWithCorruptedData, "sprite.json");
test.observer.spriteError = [&] (std::exception_ptr error) {
ASSERT_TRUE(error != nullptr);
ASSERT_FALSE(test.spriteStore.isLoaded());
test.end();
};
auto callback = [this](SpriteStore*, std::exception_ptr) {
test.run("test/fixtures/resources/sprite");
}
TEST(SpriteStore, LoadingCancel) {
SpriteStoreTest test(MockFileSource::SuccessWithDelay, "sprite.json");
test.observer.spriteLoaded = [&] () {
FAIL() << "Should never be called";
};
MockFileSource fileSourceDelaySpriteJSON(MockFileSource::SuccessWithDelay, "sprite.json");
fileSourceDelaySpriteJSON.setOnRequestDelayedCallback([this]{
stopTest();
test.fileSource.setOnRequestDelayedCallback([&]{
test.end();
});
runTest(params, &fileSourceDelaySpriteJSON, callback);
MockFileSource fileSourceDelaySpriteImage(MockFileSource::SuccessWithDelay, "sprite.png");
fileSourceDelaySpriteImage.setOnRequestDelayedCallback([this]{
stopTest();
});
runTest(params, &fileSourceDelaySpriteImage, callback);
test.run("test/fixtures/resources/sprite");
}
TEST_F(SpriteTest, InvalidURL) {
SpriteParams params = {
"foo bar",
1.0,
};
auto callback = [this](SpriteStore* spriteStore, std::exception_ptr error) {
ASSERT_TRUE(util::ThreadContext::currentlyOn(util::ThreadType::Map));
TEST(SpriteStore, InvalidURL) {
SpriteStoreTest test(MockFileSource::Success, "");
test.observer.spriteError = [&] (std::exception_ptr error) {
ASSERT_TRUE(error != nullptr);
ASSERT_EQ(spriteStore->isLoaded(), false);
stopTest();
ASSERT_EQ(test.spriteStore.isLoaded(), false);
test.end();
};
MockFileSource fileSource(MockFileSource::Success, "");
runTest(params, &fileSource, callback);
test.run("foo bar");
}

View File

@@ -1,233 +1,145 @@
#include "../fixtures/fixture_log_observer.hpp"
#include "../fixtures/mock_file_source.hpp"
#include "../fixtures/util.hpp"
#include "../fixtures/mock_file_source.hpp"
#include "../fixtures/stub_style_observer.hpp"
#include <mbgl/text/font_stack.hpp>
#include <mbgl/text/glyph_store.hpp>
#include <mbgl/util/async_task.hpp>
#include <mbgl/util/run_loop.hpp>
#include <mbgl/util/thread.hpp>
#include <utility>
#include <mbgl/platform/log.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 {
class GlyphStoreTest {
public:
GlyphStoreThread(FileSource* fileSource, GlyphStoreTestCallback callback) : callback_(std::move(callback)) {
util::ThreadContext::setFileSource(fileSource);
}
GlyphStoreTest(MockFileSource::Type type, const std::string& resource)
: fileSource(type, resource) {}
void loadGlyphStore(const GlyphStoreParams& params) {
glyphStore_.reset(new GlyphStore());
util::ThreadContext context { "Map", util::ThreadType::Map, util::ThreadPriority::Regular };
util::RunLoop loop;
MockFileSource fileSource;
StubStyleObserver observer;
GlyphStore glyphStore;
glyphStore_->setObserver(this);
glyphStore_->setURL(params.url);
void run(const std::string& url, const std::string& fontStack, const std::set<GlyphRange>& glyphRanges) {
// Squelch logging.
Log::setObserver(std::make_unique<Log::NullObserver>());
ASSERT_FALSE(glyphStore_->hasGlyphRanges(params.stack, params.ranges));
}
util::ThreadContext::Set(&context);
util::ThreadContext::setFileSource(&fileSource);
void unloadGlyphStore() {
glyphStore_->setObserver(nullptr);
glyphStore_.reset();
}
void onGlyphsLoaded(const std::string&, const GlyphRange&) override {
callback_(glyphStore_.get(), nullptr);
}
void onGlyphsError(const std::string&, const GlyphRange&, 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;
async_ = std::make_unique<util::AsyncTask>([&]{ 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);
glyphStore.setObserver(&observer);
glyphStore.setURL(url);
glyphStore.hasGlyphRanges(fontStack, glyphRanges);
loop.run();
tester.invoke(&GlyphStoreThread::unloadGlyphStore);
}
void stopTest() {
testDone = true;
async_->send();
void end() {
loop.stop();
}
bool isDone() const {
return testDone;
}
private:
bool testDone = false;
std::unique_ptr<util::AsyncTask> async_;
};
TEST_F(GlyphStoreTest, LoadingSuccess) {
GlyphStoreParams params = {
"test/fixtures/resources/glyphs.pbf",
"Test Stack",
{{0, 255}, {256, 511}}
TEST(GlyphStore, LoadingSuccess) {
GlyphStoreTest test(MockFileSource::Success, "");
test.observer.glyphsError = [&] (const std::string&, const GlyphRange&, std::exception_ptr) {
FAIL();
test.end();
};
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()) {
test.observer.glyphsLoaded = [&] (const std::string&, const GlyphRange&) {
if (!test.glyphStore.hasGlyphRanges("Test Stack", {{0, 255}, {256, 511}}))
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);
auto fontStack = test.glyphStore.getFontStack("Test Stack");
ASSERT_FALSE(fontStack->getMetrics().empty());
ASSERT_FALSE(fontStack->getSDFs().empty());
stopTest();
test.end();
};
MockFileSource fileSource(MockFileSource::Success, "");
runTest(params, &fileSource, callback);
}
TEST_F(GlyphStoreTest, LoadingFail) {
GlyphStoreParams params = {
test.run(
"test/fixtures/resources/glyphs.pbf",
"Test Stack",
{{0, 255}, {256, 511}}
};
{{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;
}
TEST(GlyphStore, LoadingFail) {
GlyphStoreTest test(MockFileSource::RequestFail, "glyphs.pbf");
test.observer.glyphsError = [&] (const std::string& fontStack, const GlyphRange& glyphRange, std::exception_ptr error) {
ASSERT_TRUE(error != nullptr);
ASSERT_EQ(fontStack, "Test Stack");
ASSERT_EQ(glyphRange, GlyphRange(0, 255));
auto fontStack = store->getFontStack(params.stack);
ASSERT_TRUE(fontStack->getMetrics().empty());
ASSERT_TRUE(fontStack->getSDFs().empty());
auto stack = test.glyphStore.getFontStack("Test Stack");
ASSERT_TRUE(stack->getMetrics().empty());
ASSERT_TRUE(stack->getSDFs().empty());
ASSERT_FALSE(test.glyphStore.hasGlyphRanges("Test Stack", {{0, 255}}));
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();
test.end();
};
MockFileSource fileSource(MockFileSource::RequestFail, "glyphs.pbf");
runTest(params, &fileSource, callback);
}
TEST_F(GlyphStoreTest, LoadingCorrupted) {
GlyphStoreParams params = {
test.run(
"test/fixtures/resources/glyphs.pbf",
"Test Stack",
{{0, 255}, {256, 511}}
};
{{0, 255}});
}
auto callback = [this, &params](GlyphStore* store, std::exception_ptr error) {
ASSERT_TRUE(util::ThreadContext::currentlyOn(util::ThreadType::Map));
if (isDone()) {
return;
}
TEST(GlyphStore, LoadingCorrupted) {
GlyphStoreTest test(MockFileSource::RequestWithCorruptedData, "glyphs.pbf");
test.observer.glyphsError = [&] (const std::string& fontStack, const GlyphRange& glyphRange, std::exception_ptr error) {
ASSERT_TRUE(error != nullptr);
ASSERT_EQ(fontStack, "Test Stack");
ASSERT_EQ(glyphRange, GlyphRange(0, 255));
auto fontStack = store->getFontStack(params.stack);
ASSERT_TRUE(fontStack->getMetrics().empty());
ASSERT_TRUE(fontStack->getSDFs().empty());
auto stack = test.glyphStore.getFontStack("Test Stack");
ASSERT_TRUE(stack->getMetrics().empty());
ASSERT_TRUE(stack->getSDFs().empty());
ASSERT_FALSE(test.glyphStore.hasGlyphRanges("Test Stack", {{0, 255}}));
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();
test.end();
};
MockFileSource fileSource(MockFileSource::RequestWithCorruptedData, "glyphs.pbf");
runTest(params, &fileSource, callback);
}
TEST_F(GlyphStoreTest, LoadingCancel) {
GlyphStoreParams params = {
test.run(
"test/fixtures/resources/glyphs.pbf",
"Test Stack",
{{0, 255}, {256, 511}}
};
{{0, 255}});
}
auto callback = [this](GlyphStore*, std::exception_ptr) {
TEST(GlyphStore, LoadingCancel) {
GlyphStoreTest test(MockFileSource::SuccessWithDelay, "glyphs.pbf");
test.observer.glyphsLoaded = [&] (const std::string&, const GlyphRange&) {
FAIL() << "Should never be called";
};
MockFileSource fileSource(MockFileSource::SuccessWithDelay, "glyphs.pbf");
fileSource.setOnRequestDelayedCallback([this]{
stopTest();
test.fileSource.setOnRequestDelayedCallback([&]{
test.end();
});
runTest(params, &fileSource, callback);
test.run(
"test/fixtures/resources/glyphs.pbf",
"Test Stack",
{{0, 255}});
}
TEST_F(GlyphStoreTest, InvalidURL) {
GlyphStoreParams params = {
"foo bar",
"Test Stack",
{{0, 255}, {256, 511}}
};
TEST(GlyphStore, InvalidURL) {
GlyphStoreTest test(MockFileSource::Success, "");
auto callback = [this, &params](GlyphStore* store, std::exception_ptr error) {
test.observer.glyphsError = [&] (const std::string&, const GlyphRange&, std::exception_ptr error) {
ASSERT_TRUE(error != nullptr);
auto fontStack = store->getFontStack(params.stack);
ASSERT_TRUE(fontStack->getMetrics().empty());
ASSERT_TRUE(fontStack->getSDFs().empty());
auto stack = test.glyphStore.getFontStack("Test Stack");
ASSERT_TRUE(stack->getMetrics().empty());
ASSERT_TRUE(stack->getSDFs().empty());
stopTest();
test.end();
};
MockFileSource fileSource(MockFileSource::Success, "");
runTest(params, &fileSource, callback);
test.run(
"foo bar",
"Test Stack",
{{0, 255}});
}

View File

@@ -2,6 +2,7 @@
#include "../fixtures/util.hpp"
#include "../fixtures/mock_file_source.hpp"
#include "../fixtures/mock_view.hpp"
#include "../fixtures/stub_style_observer.hpp"
#include <mbgl/map/map_data.hpp>
#include <mbgl/map/transform.hpp>
@@ -15,72 +16,16 @@
using namespace mbgl;
class StyleObserver : public Style::Observer {
public:
void onGlyphsLoaded(const std::string& fontStack, const GlyphRange& glyphRange) override {
if (glyphsLoaded) glyphsLoaded(fontStack, glyphRange);
}
void onGlyphsError(const std::string& fontStack, const GlyphRange& glyphRange, std::exception_ptr error) override {
if (glyphsError) glyphsError(fontStack, glyphRange, error);
}
void onSpriteLoaded() override {
if (spriteLoaded) spriteLoaded();
}
void onSpriteError(std::exception_ptr error) override {
if (spriteError) spriteError(error);
}
void onSourceLoaded(Source& source) override {
if (sourceLoaded) sourceLoaded(source);
}
void onSourceError(Source& source, std::exception_ptr error) override {
if (sourceError) sourceError(source, error);
}
void onTileLoaded(Source& source, const TileID& tileID, bool isNewTile) override {
if (tileLoaded) tileLoaded(source, tileID, isNewTile);
}
void onTileError(Source& source, const TileID& tileID, std::exception_ptr error) override {
if (tileError) tileError(source, tileID, error);
}
void onResourceLoaded() override {
if (resourceLoaded) resourceLoaded();
};
void onResourceError(std::exception_ptr error) override {
if (resourceError) resourceError(error);
};
std::function<void (const std::string& fontStack, const GlyphRange&)> glyphsLoaded;
std::function<void (const std::string& fontStack, const GlyphRange&, std::exception_ptr)> glyphsError;
std::function<void ()> spriteLoaded;
std::function<void (std::exception_ptr)> spriteError;
std::function<void (Source&)> sourceLoaded;
std::function<void (Source&, std::exception_ptr)> sourceError;
std::function<void (Source&, const TileID&, bool isNewTile)> tileLoaded;
std::function<void (Source&, const TileID&, std::exception_ptr)> tileError;
std::function<void ()> resourceLoaded;
std::function<void (std::exception_ptr)> resourceError;
std::function<void ()> fullyLoaded;
};
class ResourceLoadingTest {
public:
ResourceLoadingTest(MockFileSource::Type type, const std::string& resource)
: fileSource(type, resource) {}
util::ThreadContext context { "Map", util::ThreadType::Map, util::ThreadPriority::Regular };
MockFileSource fileSource;
StyleObserver observer;
util::RunLoop loop;
MockFileSource fileSource;
StubStyleObserver observer;
std::function<void ()> onFullyLoaded;
MapData data { MapMode::Still, GLContextMode::Unique, 1.0 };
MockView view;
@@ -97,8 +42,8 @@ public:
observer.resourceLoaded = [&] () {
style.update(transform.getState(), texturePool);
if (style.isLoaded() && observer.fullyLoaded) {
observer.fullyLoaded();
if (style.isLoaded() && onFullyLoaded) {
onFullyLoaded();
}
};
@@ -125,7 +70,7 @@ TEST(ResourceLoading, Success) {
FAIL() << util::toString(error);
};
test.observer.fullyLoaded = [&] () {
test.onFullyLoaded = [&] () {
SUCCEED();
test.end();
};
@@ -306,7 +251,7 @@ TEST(ResourceLoading, GlyphsCorrupt) {
TEST(ResourceLoading, UnusedSource) {
ResourceLoadingTest test(MockFileSource::Success, "");
test.observer.fullyLoaded = [&] () {
test.onFullyLoaded = [&] () {
Source *usedSource = test.style.getSource("usedsource");
EXPECT_TRUE(usedSource);
EXPECT_TRUE(usedSource->isLoaded());
@@ -326,7 +271,7 @@ TEST(ResourceLoading, UnusedSourceActiveViaClassUpdate) {
test.data.addClass("visible");
test.observer.fullyLoaded = [&] () {
test.onFullyLoaded = [&] () {
Source *unusedSource = test.style.getSource("unusedsource");
EXPECT_TRUE(unusedSource);
EXPECT_TRUE(unusedSource->isLoaded());