From a666c0827436ad57bfdf1f94edb8e38897ce78f9 Mon Sep 17 00:00:00 2001 From: "Thiago Marcos P. Santos" Date: Mon, 15 Jun 2015 17:59:38 +0300 Subject: Add unit tests for the Sprite class --- test/style/mock_file_source.cpp | 8 +- test/style/sprite.cpp | 173 ++++++++++++++++++++++++++++++++++++++++ test/test.gypi | 1 + 3 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 test/style/sprite.cpp diff --git a/test/style/mock_file_source.cpp b/test/style/mock_file_source.cpp index 0637645233..b420ba7298 100644 --- a/test/style/mock_file_source.cpp +++ b/test/style/mock_file_source.cpp @@ -53,7 +53,13 @@ private: void MockFileSource::Impl::replyWithSuccess(Request* req) const { std::shared_ptr res = std::make_shared(); res->status = Response::Status::Successful; - res->data = util::read_file(req->resource.url); + + try { + res->data = util::read_file(req->resource.url); + } catch (const std::exception& err) { + res->status = Response::Status::Error; + res->message = err.what(); + } req->notify(res); } diff --git a/test/style/sprite.cpp b/test/style/sprite.cpp new file mode 100644 index 0000000000..41ded0afe2 --- /dev/null +++ b/test/style/sprite.cpp @@ -0,0 +1,173 @@ +#include "../fixtures/fixture_log_observer.hpp" +#include "../fixtures/util.hpp" +#include "mock_file_source.hpp" + +#include +#include +#include + +using namespace mbgl; + +using SpriteTestCallback = std::function; + +struct SpriteParams { + const std::string baseUrl; + const float pixelRatio; +}; + +class SpriteThread : public Sprite::Observer { +public: + SpriteThread(FileSource* fileSource, SpriteTestCallback callback) : callback_(callback) { + util::ThreadContext::setFileSource(fileSource); + } + + void loadSprite(const SpriteParams& params) { + sprite_.reset(new Sprite(params.baseUrl, params.pixelRatio)); + sprite_->setObserver(this); + } + + void unloadSprite() { + sprite_->setObserver(nullptr); + sprite_.reset(); + } + + void onSpriteLoaded(const Sprites& sprites) override { + callback_(sprite_.get(), sprites, nullptr); + } + + void onSpriteLoadingFailed(std::exception_ptr error) override { + callback_(sprite_.get(), Sprites(), error); + } + +private: + std::unique_ptr sprite_; + SpriteTestCallback callback_; +}; + +class SpriteTest : public testing::Test { +protected: + void runTest(const SpriteParams& params, FileSource* fileSource, SpriteTestCallback callback) { + util::RunLoop loop(uv_default_loop()); + + async_ = std::make_unique(loop.get(), [&] { loop.stop(); }); + async_->unref(); + + const util::ThreadContext context = {"Map", util::ThreadType::Map, util::ThreadPriority::Regular}; + + util::Thread tester(context, fileSource, callback); + tester.invoke(&SpriteThread::loadSprite, params); + + uv_run(loop.get(), UV_RUN_DEFAULT); + + tester.invoke(&SpriteThread::unloadSprite); + } + + void stopTest() { + async_->send(); + } + +private: + std::unique_ptr async_; +}; + +TEST_F(SpriteTest, LoadingSuccess) { + SpriteParams params = { + "test/fixtures/resources/sprite", + 1.0, + }; + + auto callback = [this, ¶ms](Sprite* sprite, const Sprites& sprites, std::exception_ptr error) { + ASSERT_TRUE(util::ThreadContext::currentlyOn(util::ThreadType::Map)); + + ASSERT_TRUE(error == nullptr); + + ASSERT_TRUE(!sprites.empty()); + + ASSERT_EQ(sprite->pixelRatio, params.pixelRatio); + ASSERT_NE(sprite->pixelRatio, 1.5); + ASSERT_NE(sprite->pixelRatio, 2.0); + + ASSERT_TRUE(sprite->isLoaded()); + + stopTest(); + }; + + MockFileSource fileSource(MockFileSource::Success, ""); + runTest(params, &fileSource, callback); +} + +TEST_F(SpriteTest, LoadingFail) { + SpriteParams params = { + "test/fixtures/resources/sprite", + 1.0, + }; + + auto callback = [this, ¶ms](Sprite* sprite, const Sprites&, std::exception_ptr error) { + ASSERT_TRUE(util::ThreadContext::currentlyOn(util::ThreadType::Map)); + + ASSERT_TRUE(error != nullptr); + + ASSERT_EQ(sprite->pixelRatio, params.pixelRatio); + ASSERT_NE(sprite->pixelRatio, 1.5); + ASSERT_NE(sprite->pixelRatio, 2.0); + + ASSERT_FALSE(sprite->isLoaded()); + + stopTest(); + }; + + 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_F(SpriteTest, LoadingCancel) { + SpriteParams params = { + "test/fixtures/resources/sprite", + 1.0, + }; + + auto callback = [this](Sprite*, const Sprites&, std::exception_ptr) { + FAIL() << "Should never be called"; + }; + + MockFileSource fileSourceDelaySpriteJSON(MockFileSource::SuccessWithDelay, "sprite.json"); + fileSourceDelaySpriteJSON.setOnRequestDelayedCallback([this]{ + stopTest(); + }); + runTest(params, &fileSourceDelaySpriteJSON, callback); + + MockFileSource fileSourceDelaySpriteImage(MockFileSource::SuccessWithDelay, "sprite.png"); + fileSourceDelaySpriteImage.setOnRequestDelayedCallback([this]{ + stopTest(); + }); + runTest(params, &fileSourceDelaySpriteImage, callback); +} + +TEST_F(SpriteTest, InvalidURL) { + SpriteParams params = { + "foo bar", + 1.0, + }; + + auto callback = [this](Sprite* sprite, const Sprites&, std::exception_ptr error) { + ASSERT_TRUE(util::ThreadContext::currentlyOn(util::ThreadType::Map)); + + ASSERT_TRUE(error != nullptr); + + ASSERT_EQ(sprite->isLoaded(), false); + + stopTest(); + }; + + MockFileSource fileSource(MockFileSource::Success, ""); + runTest(params, &fileSource, callback); +} diff --git a/test/test.gypi b/test/test.gypi index 8cf7b1b063..c32b02746a 100644 --- a/test/test.gypi +++ b/test/test.gypi @@ -88,6 +88,7 @@ 'style/mock_view.hpp', 'style/pending_resources.cpp', 'style/resource_loading.cpp', + 'style/sprite.cpp', ], 'libraries': [ '<@(uv_static_libs)', -- cgit v1.2.1