summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2015-12-22 16:32:25 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2015-12-22 18:00:30 -0800
commit7c22792bdfa1f89990736bd8ef67cb4e5e64220f (patch)
tree855bf1ba6ef29c53ddb699863b07156407677c1b
parentd745ff09235cfb62404f56fb6403fa093fa9a92c (diff)
downloadqtlocation-mapboxgl-7c22792bdfa1f89990736bd8ef67cb4e5e64220f.tar.gz
[tests] Rewrite resource loading test
Make it more readable and easier to debug.
-rw-r--r--include/mbgl/platform/log.hpp6
-rw-r--r--include/mbgl/util/string.hpp9
-rw-r--r--test/fixtures/resources/style.json2
-rw-r--r--test/style/resource_loading.cpp219
4 files changed, 114 insertions, 122 deletions
diff --git a/include/mbgl/platform/log.hpp b/include/mbgl/platform/log.hpp
index a2a9119905..cd072c37da 100644
--- a/include/mbgl/platform/log.hpp
+++ b/include/mbgl/platform/log.hpp
@@ -21,6 +21,12 @@ public:
virtual bool onRecord(EventSeverity severity, Event event, int64_t code, const std::string &msg) = 0;
};
+ class NullObserver : public Observer {
+ bool onRecord(EventSeverity, Event, int64_t, const std::string&) override {
+ return true;
+ }
+ };
+
static void setObserver(std::unique_ptr<Observer> Observer);
static std::unique_ptr<Observer> removeObserver();
diff --git a/include/mbgl/util/string.hpp b/include/mbgl/util/string.hpp
index 9e2b2d8819..bc6b3b1eff 100644
--- a/include/mbgl/util/string.hpp
+++ b/include/mbgl/util/string.hpp
@@ -22,6 +22,15 @@ inline std::string toString(int8_t num) {
return boost::lexical_cast<std::string>(int(num));
}
+inline std::string toString(std::exception_ptr error) {
+ try {
+ std::rethrow_exception(error);
+ } catch (const std::exception& ex) {
+ return ex.what();
+ } catch (...) {
+ return "Unknown exception type";
+ }
+}
template<size_t max, typename... Args>
inline std::string sprintf(const char *msg, Args... args) {
diff --git a/test/fixtures/resources/style.json b/test/fixtures/resources/style.json
index f794d54fab..858e2de037 100644
--- a/test/fixtures/resources/style.json
+++ b/test/fixtures/resources/style.json
@@ -9,7 +9,7 @@
"rastersource": {
"url": "test/fixtures/resources/source_raster.json",
"type": "raster",
- "tileSize": 256
+ "tileSize": 512
}
},
"sprite": "test/fixtures/resources/sprite",
diff --git a/test/style/resource_loading.cpp b/test/style/resource_loading.cpp
index ba6a138b5d..8330879844 100644
--- a/test/style/resource_loading.cpp
+++ b/test/style/resource_loading.cpp
@@ -11,164 +11,141 @@
#include <mbgl/util/run_loop.hpp>
#include <mbgl/util/texture_pool.hpp>
#include <mbgl/util/thread.hpp>
-
-#include <regex>
+#include <mbgl/util/string.hpp>
using namespace mbgl;
-namespace {
-
-class MockMapContext : public Style::Observer {
+class StyleObserver : public Style::Observer {
public:
- MockMapContext(View& view,
- FileSource& fileSource,
- const std::function<void(std::exception_ptr error)>& callback)
- : data_(MapMode::Still, GLContextMode::Unique, view.getPixelRatio()),
- transform_(view, ConstrainMode::HeightOnly),
- callback_(callback) {
- util::ThreadContext::setFileSource(&fileSource);
-
- transform_.resize({{ 1000, 1000 }});
- transform_.setLatLngZoom({0, 0}, 16);
-
- const std::string style = util::read_file("test/fixtures/resources/style.json");
- style_ = std::make_unique<Style>(data_);
- style_->setJSON(style, "");
- style_->setObserver(this);
+ void onTileDataChanged() override {
+ tileDataChanged();
}
- ~MockMapContext() {
- cleanup();
+ void onResourceLoadingFailed(std::exception_ptr error) override {
+ resourceLoadingFailed(error);
}
- void cleanup() {
- style_.reset();
- }
+ std::function<void ()> tileDataChanged = [] {};
+ std::function<void (std::exception_ptr)> resourceLoadingFailed = [] (auto) {};
+};
- void update() {
- const auto now = Clock::now();
+std::string resourceErrorString(MockFileSource::Type type, const std::string& param) {
+ Log::setObserver(std::make_unique<Log::NullObserver>()); // Squelch logging.
- data_.setAnimationTime(now);
- transform_.updateTransitions(now);
+ util::RunLoop loop;
- style_->cascade();
- style_->recalculate(16);
- style_->update(transform_.getState(), texturePool_);
- }
+ util::ThreadContext context("Map", util::ThreadType::Map, util::ThreadPriority::Regular);
+ util::ThreadContext::Set(&context);
- // Style::Observer implementation.
- void onTileDataChanged() override {
- update();
+ MockFileSource fileSource(type, param);
+ util::ThreadContext::setFileSource(&fileSource);
- if (style_->isLoaded()) {
- callback_(nullptr);
- }
- };
+ MapData data(MapMode::Still, GLContextMode::Unique, 1.0);
+ MockView view;
+ Transform transform(view, ConstrainMode::HeightOnly);
+ TexturePool texturePool;
+ Style style(data);
- void onResourceLoadingFailed(std::exception_ptr error) override {
- callback_(error);
- }
+ StyleObserver observer;
+ std::string result;
-private:
- MapData data_;
- Transform transform_;
- TexturePool texturePool_;
+ observer.tileDataChanged = [&] () {
+ // Prompt tile loading after sources load.
+ style.update(transform.getState(), texturePool);
- std::unique_ptr<Style> style_;
+ if (style.isLoaded()) {
+ loop.stop();
+ }
+ };
- std::function<void(std::exception_ptr error)> callback_;
-};
+ observer.resourceLoadingFailed = [&] (std::exception_ptr error) {
+ result = util::toString(error);
+ loop.stop();
+ };
-void runTestCase(MockFileSource::Type type,
- const std::string& param,
- const std::string& message) {
- util::RunLoop loop;
+ transform.resize({{ 512, 512 }});
+ transform.setLatLngZoom({0, 0}, 0);
- MockView view;
- MockFileSource fileSource(type, param);
+ style.setObserver(&observer);
+ style.setJSON(util::read_file("test/fixtures/resources/style.json"), "");
+ style.cascade();
+ style.recalculate(16);
- FixtureLogObserver* log = new FixtureLogObserver();
- Log::setObserver(std::unique_ptr<Log::Observer>(log));
+ loop.run();
- auto callback = [type, &loop, &param](std::exception_ptr error) {
- if (type == MockFileSource::Success) {
- EXPECT_TRUE(error == nullptr);
- } else {
- EXPECT_TRUE(error != nullptr);
- }
+ return result;
+}
- try {
- if (error) {
- std::rethrow_exception(error);
- }
- } catch (const util::GlyphRangeLoadingException&) {
- EXPECT_EQ(param, "glyphs.pbf");
- } catch (const util::SourceLoadingException&) {
- EXPECT_TRUE(param == "source_raster.json" || param == "source_vector.json");
- } catch (const util::SpriteLoadingException&) {
- EXPECT_TRUE(param == "sprite.png" || param == "sprite.json");
- } catch (const util::TileLoadingException&) {
- EXPECT_TRUE(param == "raster.png" || param == "vector.pbf");
- } catch (const std::exception&) {
- EXPECT_TRUE(false) << "Unhandled exception.";
- }
+TEST(ResourceLoading, Success) {
+ EXPECT_EQ(resourceErrorString(MockFileSource::Success, ""), "");
+}
- loop.stop();
- };
+TEST(ResourceLoading, RasterSourceFail) {
+ EXPECT_EQ(resourceErrorString(MockFileSource::RequestFail, "source_raster.json"),
+ "Failed to load [test/fixtures/resources/source_raster.json]: Failed by the test case");
+}
- std::unique_ptr<util::Thread<MockMapContext>> context(
- std::make_unique<util::Thread<MockMapContext>>(
- util::ThreadContext{"Map", util::ThreadType::Map, util::ThreadPriority::Regular}, view, fileSource, callback));
+TEST(ResourceLoading, VectorSourceFail) {
+ EXPECT_EQ(resourceErrorString(MockFileSource::RequestFail, "source_vector.json"),
+ "Failed to load [test/fixtures/resources/source_vector.json]: Failed by the test case");
+}
- loop.run();
+TEST(ResourceLoading, SpriteJSONFail) {
+ EXPECT_EQ(resourceErrorString(MockFileSource::RequestFail, "sprite.json"),
+ "Failed to load [test/fixtures/resources/sprite.json]: Failed by the test case");
+}
- // Needed because it will make the Map thread
- // join and cease logging after this point.
- context->invoke(&MockMapContext::cleanup);
- context.reset();
+TEST(ResourceLoading, SpriteImageFail) {
+ EXPECT_EQ(resourceErrorString(MockFileSource::RequestFail, "sprite.png"),
+ "Failed to load [test/fixtures/resources/sprite.png]: Failed by the test case");
+}
- uint32_t match = 0;
- std::vector<FixtureLogObserver::LogMessage> logMessages = log->unchecked();
+TEST(ResourceLoading, RasterTileFail) {
+ EXPECT_EQ(resourceErrorString(MockFileSource::RequestFail, "raster.png"),
+ "Failed to load [test/fixtures/resources/raster.png]: Failed by the test case");
+}
- for (auto& logMessage : logMessages) {
- if (std::regex_match(logMessage.msg, std::regex(message))) {
- match++;
- }
- }
+TEST(ResourceLoading, VectorTileFail) {
+ EXPECT_EQ(resourceErrorString(MockFileSource::RequestFail, "vector.pbf"),
+ "Failed to load [test/fixtures/resources/vector.pbf]: Failed by the test case");
+}
- if (type == MockFileSource::Success) {
- EXPECT_EQ(match, 0u);
- } else {
- EXPECT_GT(match, 0u);
- }
+TEST(ResourceLoading, GlyphsFail) {
+ EXPECT_EQ(resourceErrorString(MockFileSource::RequestFail, "glyphs.pbf"),
+ "Failed to load [test/fixtures/resources/glyphs.pbf]: Failed by the test case");
}
-} // namespace
+TEST(ResourceLoading, RasterSourceCorrupt) {
+ EXPECT_EQ(resourceErrorString(MockFileSource::RequestWithCorruptedData, "source_raster.json"),
+ "Failed to parse [test/fixtures/resources/source_raster.json]: 0 - Invalid value.");
+}
-class ResourceLoading : public ::testing::TestWithParam<std::pair<std::string, std::string>> {
-};
+TEST(ResourceLoading, VectorSourceCorrupt) {
+ EXPECT_EQ(resourceErrorString(MockFileSource::RequestWithCorruptedData, "source_vector.json"),
+ "Failed to parse [test/fixtures/resources/source_vector.json]: 0 - Invalid value.");
+}
-TEST_P(ResourceLoading, Success) {
- runTestCase(MockFileSource::Success, GetParam().first, std::string());
+TEST(ResourceLoading, SpriteJSONCorrupt) {
+ EXPECT_EQ(resourceErrorString(MockFileSource::RequestWithCorruptedData, "sprite.json"),
+ "Failed to parse JSON: Invalid value. at offset 0");
}
-TEST_P(ResourceLoading, RequestFail) {
- std::stringstream message;
- message << "Failed to load \\[test\\/fixtures\\/resources\\/" << GetParam().first << "\\]\\: Failed by the test case";
+TEST(ResourceLoading, SpriteImageCorrupt) {
+ EXPECT_EQ(resourceErrorString(MockFileSource::RequestWithCorruptedData, "sprite.png"),
+ "Could not parse sprite image");
+}
- runTestCase(MockFileSource::RequestFail, GetParam().first, message.str());
+TEST(ResourceLoading, RasterTileCorrupt) {
+ EXPECT_EQ(resourceErrorString(MockFileSource::RequestWithCorruptedData, "raster.png"),
+ "Failed to parse [0/0/0]: error parsing raster image");
}
-TEST_P(ResourceLoading, RequestWithCorruptedData) {
- runTestCase(MockFileSource::RequestWithCorruptedData, GetParam().first, GetParam().second);
+TEST(ResourceLoading, VectorTileCorrupt) {
+ EXPECT_EQ(resourceErrorString(MockFileSource::RequestWithCorruptedData, "vector.pbf"),
+ "Failed to parse [0/0/0]: pbf unknown field type exception");
}
-INSTANTIATE_TEST_CASE_P(Style, ResourceLoading,
- ::testing::Values(
- std::make_pair("source_raster.json", "Failed to parse \\[test\\/fixtures\\/resources\\/source_raster.json\\]: 0 - Invalid value."),
- std::make_pair("source_vector.json", "Failed to parse \\[test\\/fixtures\\/resources\\/source_vector.json\\]: 0 - Invalid value."),
- std::make_pair("sprite.json", "Failed to parse JSON: Invalid value. at offset 0"),
- std::make_pair("sprite.png", "Could not parse sprite image"),
- std::make_pair("raster.png", "Failed to parse \\[17\\/6553(4|5|6|7)\\/6553(4|5|6|7)\\]\\: error parsing raster image"),
- std::make_pair("vector.pbf", "Failed to parse \\[1(5|6)\\/1638(3|4)\\/1638(3|4)\\]\\: pbf unknown field type exception"),
- std::make_pair("glyphs.pbf", "Failed to parse \\[test\\/fixtures\\/resources\\/glyphs.pbf\\]: pbf unknown field type exception")));
+TEST(ResourceLoading, GlyphsCorrupt) {
+ EXPECT_EQ(resourceErrorString(MockFileSource::RequestWithCorruptedData, "glyphs.pbf"),
+ "Failed to parse [test/fixtures/resources/glyphs.pbf]: pbf unknown field type exception");
+}