summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAntonio Zugaldia <antonio@silicalabs.com>2015-09-14 17:24:59 -0400
committerAntonio Zugaldia <antonio@silicalabs.com>2015-09-14 17:24:59 -0400
commit7756f7727c0418a27ca987559a007bbc9a93bf51 (patch)
tree362dd1786a22d4ddf199a7aada081d37e4d7ab82 /test
parent5c74d202d3e0b603ce842c9e60eecc617a9cdbdd (diff)
parent5ef7011089e761dda0a26782c04dad9f61e65d34 (diff)
downloadqtlocation-mapboxgl-7756f7727c0418a27ca987559a007bbc9a93bf51.tar.gz
Merge remote-tracking branch 'mapbox/master' into 2317-espresso
Conflicts: android/java/MapboxGLAndroidSDKTestApp/build.gradle
Diffstat (limited to 'test')
-rw-r--r--test/annotations/sprite_atlas.cpp173
-rw-r--r--test/annotations/sprite_image.cpp64
-rw-r--r--test/annotations/sprite_parser.cpp310
-rw-r--r--test/annotations/sprite_store.cpp143
-rw-r--r--test/api/annotations.cpp36
-rw-r--r--test/api/api_misuse.cpp8
-rw-r--r--test/api/repeated_render.cpp12
-rw-r--r--test/api/set_style.cpp4
-rw-r--r--test/fixtures/annotations/emerald.json1
-rw-r--r--test/fixtures/annotations/emerald.pngbin0 -> 39041 bytes
-rw-r--r--test/fixtures/annotations/emerald@2x.json1
-rw-r--r--test/fixtures/annotations/emerald@2x.pngbin0 -> 80896 bytes
-rw-r--r--test/fixtures/api/water.json2
-rw-r--r--test/fixtures/fixture_log_observer.cpp80
-rw-r--r--test/fixtures/fixture_log_observer.hpp64
-rw-r--r--test/fixtures/headless/pois.json26
-rw-r--r--test/fixtures/mock_file_source.cpp (renamed from test/style/mock_file_source.cpp)20
-rw-r--r--test/fixtures/mock_file_source.hpp (renamed from test/style/mock_file_source.hpp)0
-rw-r--r--test/fixtures/mock_view.hpp9
-rw-r--r--test/fixtures/resources/raster.pngbin0 -> 12146 bytes
-rw-r--r--test/fixtures/resources/source_raster.json1
-rw-r--r--test/fixtures/resources/source_vector.json (renamed from test/fixtures/resources/source.json)0
-rw-r--r--test/fixtures/resources/style.json19
-rw-r--r--test/fixtures/style_parser/circle-blur.info.json7
-rw-r--r--test/fixtures/style_parser/circle-blur.style.json18
-rw-r--r--test/fixtures/style_parser/circle-color.info.json7
-rw-r--r--test/fixtures/style_parser/circle-color.style.json18
-rw-r--r--test/fixtures/style_parser/circle-opacity.info.json7
-rw-r--r--test/fixtures/style_parser/circle-opacity.style.json18
-rw-r--r--test/fixtures/style_parser/circle-radius.info.json7
-rw-r--r--test/fixtures/style_parser/circle-radius.style.json18
-rw-r--r--test/fixtures/style_parser/colors.style.json2
-rw-r--r--test/fixtures/style_parser/function-numeric.style.json2
-rw-r--r--test/fixtures/style_parser/function-string-bool-enum.style.json4
-rw-r--r--test/fixtures/style_parser/function-type.style.json2
-rw-r--r--test/fixtures/style_parser/line-opacity.style.json2
-rw-r--r--test/fixtures/style_parser/line-translate.style.json2
-rw-r--r--test/fixtures/style_parser/line-width.style.json2
-rw-r--r--test/fixtures/style_parser/stop-zoom-value.style.json2
-rw-r--r--test/fixtures/style_parser/stops-array.style.json2
-rw-r--r--test/fixtures/style_parser/text-size.style.json2
-rw-r--r--test/fixtures/tiles/streets/15-17605-10749.vector.pbfbin0 -> 143637 bytes
-rw-r--r--test/fixtures/tiles/streets/15-17605-10750.vector.pbfbin0 -> 123586 bytes
-rw-r--r--test/fixtures/util.cpp16
-rw-r--r--test/fixtures/util.hpp3
-rw-r--r--test/headless/headless.cpp181
-rwxr-xr-xtest/headless/server.js19
-rw-r--r--test/ios/KIFTestActor+MapboxGL.m2
-rw-r--r--test/ios/MGLTAppDelegate.m2
-rw-r--r--test/ios/MGLTViewController.m2
-rw-r--r--test/ios/MapViewTests.m6
-rw-r--r--test/ios/MetricsTests.m20
-rw-r--r--test/ios/ios-tests.xcodeproj/project.pbxproj16
-rw-r--r--test/ios/ios-tests.xcodeproj/xcshareddata/xcschemes/Mapbox GL Tests.xcscheme14
-rw-r--r--test/miscellaneous/custom_sprites.cpp61
-rw-r--r--test/miscellaneous/map.cpp8
-rw-r--r--test/miscellaneous/map_context.cpp4
-rw-r--r--test/miscellaneous/mapbox.cpp17
-rw-r--r--test/miscellaneous/style_parser.cpp9
-rw-r--r--test/miscellaneous/thread.cpp144
-rw-r--r--test/miscellaneous/transform.cpp32
-rw-r--r--test/miscellaneous/work_queue.cpp63
-rw-r--r--test/miscellaneous/worker.cpp104
-rw-r--r--test/storage/database.cpp77
-rw-r--r--test/style/glyph_store.cpp231
-rw-r--r--test/style/pending_resources.cpp23
-rw-r--r--test/style/resource_loading.cpp58
-rw-r--r--test/style/sprite.cpp173
-rw-r--r--test/test.gypi33
69 files changed, 1877 insertions, 536 deletions
diff --git a/test/annotations/sprite_atlas.cpp b/test/annotations/sprite_atlas.cpp
new file mode 100644
index 0000000000..0eece6c47c
--- /dev/null
+++ b/test/annotations/sprite_atlas.cpp
@@ -0,0 +1,173 @@
+#include "../fixtures/util.hpp"
+#include "../fixtures/fixture_log_observer.hpp"
+
+#include <mbgl/geometry/sprite_atlas.hpp>
+#include <mbgl/annotation/sprite_store.hpp>
+#include <mbgl/annotation/sprite_parser.hpp>
+#include <mbgl/util/io.hpp>
+#include <mbgl/util/image.hpp>
+
+using namespace mbgl;
+
+TEST(Annotations, SpriteAtlas) {
+ FixtureLog log;
+
+ auto spriteParseResult = parseSprite(util::read_file("test/fixtures/annotations/emerald.png"),
+ util::read_file("test/fixtures/annotations/emerald.json"));
+
+ SpriteStore store;
+ store.setSprites(spriteParseResult.get<Sprites>());
+
+ SpriteAtlas atlas(63, 112, 1, store);
+
+ EXPECT_EQ(1.0f, atlas.getPixelRatio());
+ EXPECT_EQ(63, atlas.getWidth());
+ EXPECT_EQ(112, atlas.getHeight());
+ EXPECT_EQ(63, atlas.getTextureWidth());
+ EXPECT_EQ(112, atlas.getTextureHeight());
+
+ // Image hasn't been created yet.
+ EXPECT_TRUE(atlas.getData());
+
+ auto metro = atlas.getImage("metro", false);
+ EXPECT_EQ(0, metro.pos.x);
+ EXPECT_EQ(0, metro.pos.y);
+ EXPECT_EQ(20, metro.pos.w);
+ EXPECT_EQ(20, metro.pos.h);
+ EXPECT_EQ(18, metro.pos.originalW);
+ EXPECT_EQ(18, metro.pos.originalH);
+ EXPECT_EQ(18, metro.texture->width);
+ EXPECT_EQ(18, metro.texture->height);
+ EXPECT_EQ(18, metro.texture->pixelWidth);
+ EXPECT_EQ(18, metro.texture->pixelHeight);
+ EXPECT_EQ(1.0f, metro.texture->pixelRatio);
+
+ auto pos = atlas.getPosition("metro", false);
+ EXPECT_DOUBLE_EQ(20, pos.size[0]);
+ EXPECT_DOUBLE_EQ(20, pos.size[1]);
+ EXPECT_DOUBLE_EQ(1.0f / 63, pos.tl[0]);
+ EXPECT_DOUBLE_EQ(1.0f / 112, pos.tl[1]);
+ EXPECT_DOUBLE_EQ(21.0f / 63, pos.br[0]);
+ EXPECT_DOUBLE_EQ(21.0f / 112, pos.br[1]);
+
+
+ auto missing = atlas.getImage("doesnotexist", false);
+ EXPECT_FALSE(missing.pos.hasArea());
+ EXPECT_EQ(0, missing.pos.x);
+ EXPECT_EQ(0, missing.pos.y);
+ EXPECT_EQ(0, missing.pos.w);
+ EXPECT_EQ(0, missing.pos.h);
+ EXPECT_EQ(0, missing.pos.originalW);
+ EXPECT_EQ(0, missing.pos.originalH);
+ EXPECT_FALSE(missing.texture);
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Info,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't find sprite named 'doesnotexist'",
+ }));
+
+ // Different wrapping mode produces different image.
+ auto metro2 = atlas.getImage("metro", true);
+ EXPECT_EQ(20, metro2.pos.x);
+ EXPECT_EQ(0, metro2.pos.y);
+ EXPECT_EQ(20, metro2.pos.w);
+ EXPECT_EQ(20, metro2.pos.h);
+ EXPECT_EQ(18, metro2.pos.originalW);
+ EXPECT_EQ(18, metro2.pos.originalH);
+
+ const size_t bytes = atlas.getTextureWidth() * atlas.getTextureHeight() * 4;
+ const auto hash = test::crc64(reinterpret_cast<const char*>(atlas.getData()), bytes);
+ EXPECT_EQ(0x9875FC0595489A9Fu, hash) << std::hex << hash;
+
+ // util::write_file(
+ // "test/fixtures/annotations/atlas1.png",
+ // util::compress_png(atlas.getTextureWidth(), atlas.getTextureHeight(), atlas.getData()));
+}
+
+TEST(Annotations, SpriteAtlasSize) {
+ auto spriteParseResult = parseSprite(util::read_file("test/fixtures/annotations/emerald.png"),
+ util::read_file("test/fixtures/annotations/emerald.json"));
+
+ SpriteStore store;
+ store.setSprites(spriteParseResult.get<Sprites>());
+
+ SpriteAtlas atlas(63, 112, 1.4, store);
+
+ EXPECT_DOUBLE_EQ(1.4f, atlas.getPixelRatio());
+ EXPECT_EQ(63, atlas.getWidth());
+ EXPECT_EQ(112, atlas.getHeight());
+ EXPECT_EQ(89, atlas.getTextureWidth());
+ EXPECT_EQ(157, atlas.getTextureHeight());
+
+ auto metro = atlas.getImage("metro", false);
+ EXPECT_EQ(0, metro.pos.x);
+ EXPECT_EQ(0, metro.pos.y);
+ EXPECT_EQ(20, metro.pos.w);
+ EXPECT_EQ(20, metro.pos.h);
+ EXPECT_EQ(18, metro.pos.originalW);
+ EXPECT_EQ(18, metro.pos.originalH);
+ EXPECT_EQ(18, metro.texture->width);
+ EXPECT_EQ(18, metro.texture->height);
+ EXPECT_EQ(18, metro.texture->pixelWidth);
+ EXPECT_EQ(18, metro.texture->pixelHeight);
+ EXPECT_EQ(1.0f, metro.texture->pixelRatio);
+
+ const size_t bytes = atlas.getTextureWidth() * atlas.getTextureHeight() * 4;
+ const auto hash = test::crc64(reinterpret_cast<const char*>(atlas.getData()), bytes);
+ EXPECT_EQ(0x2CDDA7DBB04D116Du, hash) << std::hex << hash;
+
+ // util::write_file(
+ // "test/fixtures/annotations/atlas2.png",
+ // util::compress_png(atlas.getTextureWidth(), atlas.getTextureHeight(), atlas.getData()));
+}
+
+TEST(Annotations, SpriteAtlasUpdates) {
+ SpriteStore store;
+
+ SpriteAtlas atlas(32, 32, 1, store);
+
+ EXPECT_EQ(1.0f, atlas.getPixelRatio());
+ EXPECT_EQ(32, atlas.getWidth());
+ EXPECT_EQ(32, atlas.getHeight());
+ EXPECT_EQ(32, atlas.getTextureWidth());
+ EXPECT_EQ(32, atlas.getTextureHeight());
+
+ store.setSprite("one", std::make_shared<SpriteImage>(16, 12, 1, std::string(16 * 12 * 4, '\x00')));
+ auto one = atlas.getImage("one", false);
+ EXPECT_EQ(0, one.pos.x);
+ EXPECT_EQ(0, one.pos.y);
+ EXPECT_EQ(20, one.pos.w);
+ EXPECT_EQ(16, one.pos.h);
+ EXPECT_EQ(16, one.pos.originalW);
+ EXPECT_EQ(12, one.pos.originalH);
+ EXPECT_EQ(16, one.texture->width);
+ EXPECT_EQ(12, one.texture->height);
+ EXPECT_EQ(16, one.texture->pixelWidth);
+ EXPECT_EQ(12, one.texture->pixelHeight);
+ EXPECT_EQ(1.0f, one.texture->pixelRatio);
+
+ const size_t bytes = atlas.getTextureWidth() * atlas.getTextureHeight() * 4;
+ const auto hash = test::crc64(reinterpret_cast<const char*>(atlas.getData()), bytes);
+ EXPECT_EQ(0x0000000000000000u, hash) << std::hex << hash;
+
+ // Update sprite
+ auto newSprite = std::make_shared<SpriteImage>(16, 12, 1, std::string(16 * 12 * 4, '\xFF'));
+ store.setSprite("one", newSprite);
+ ASSERT_EQ(newSprite, store.getSprite("one"));
+
+ // Atlas texture hasn't changed yet.
+ const auto hash2 = test::crc64(reinterpret_cast<const char*>(atlas.getData()), bytes);
+ EXPECT_EQ(0x0000000000000000u, hash2) << std::hex << hash2;
+
+ atlas.updateDirty();
+
+ // Now the atlas texture has changed.
+ const auto hash3 = test::crc64(reinterpret_cast<const char*>(atlas.getData()), bytes);
+ EXPECT_EQ(0x4E6D4900CD2D9149u, hash3) << std::hex << hash3;
+
+ // util::write_file(
+ // "test/fixtures/annotations/atlas3.png",
+ // util::compress_png(atlas.getTextureWidth(), atlas.getTextureHeight(), atlas.getData()));
+}
diff --git a/test/annotations/sprite_image.cpp b/test/annotations/sprite_image.cpp
new file mode 100644
index 0000000000..9c5ca79ac9
--- /dev/null
+++ b/test/annotations/sprite_image.cpp
@@ -0,0 +1,64 @@
+#include "../fixtures/util.hpp"
+
+#include <mbgl/annotation/sprite_image.hpp>
+#include <mbgl/util/exception.hpp>
+
+using namespace mbgl;
+
+TEST(Annotations, SpriteImageZeroWidth) {
+ try {
+ SpriteImage(0, 16, 2, "");
+ FAIL() << "Expected exception";
+ } catch (util::SpriteImageException& ex) {
+ EXPECT_STREQ("Sprite image dimensions may not be zero", ex.what());
+ }
+}
+
+TEST(Annotations, SpriteImageZeroHeight) {
+ try {
+ SpriteImage(16, 0, 2, "");
+ FAIL() << "Expected exception";
+ } catch (util::SpriteImageException& ex) {
+ EXPECT_STREQ("Sprite image dimensions may not be zero", ex.what());
+ }
+}
+
+TEST(Annotations, SpriteImageZeroRatio) {
+ try {
+ SpriteImage(16, 16, 0, "");
+ FAIL() << "Expected exception";
+ } catch (util::SpriteImageException& ex) {
+ EXPECT_STREQ("Sprite image dimensions may not be zero", ex.what());
+ }
+}
+
+TEST(Annotations, SpriteImageMismatchedData) {
+ try {
+ SpriteImage(16, 16, 2, "");
+ FAIL() << "Expected exception";
+ } catch (util::SpriteImageException& ex) {
+ EXPECT_STREQ("Sprite image pixel count mismatch", ex.what());
+ }
+}
+
+TEST(Annotations, SpriteImage) {
+ std::string pixels(32 * 24 * 4, '\0');
+ SpriteImage sprite(16, 12, 2, std::move(pixels));
+ EXPECT_EQ(16, sprite.width);
+ EXPECT_EQ(32, sprite.pixelWidth);
+ EXPECT_EQ(12, sprite.height);
+ EXPECT_EQ(24, sprite.pixelHeight);
+ EXPECT_EQ(2, sprite.pixelRatio);
+ EXPECT_EQ(32u * 24 * 4, sprite.data.size());
+}
+
+TEST(Annotations, SpriteImageFractionalRatio) {
+ std::string pixels(20 * 12 * 4, '\0');
+ SpriteImage sprite(13, 8, 1.5, std::move(pixels));
+ EXPECT_EQ(13, sprite.width);
+ EXPECT_EQ(20, sprite.pixelWidth);
+ EXPECT_EQ(8, sprite.height);
+ EXPECT_EQ(12, sprite.pixelHeight);
+ EXPECT_EQ(1.5, sprite.pixelRatio);
+ EXPECT_EQ(20u * 12 * 4, sprite.data.size());
+}
diff --git a/test/annotations/sprite_parser.cpp b/test/annotations/sprite_parser.cpp
new file mode 100644
index 0000000000..7033152581
--- /dev/null
+++ b/test/annotations/sprite_parser.cpp
@@ -0,0 +1,310 @@
+#include "../fixtures/util.hpp"
+#include "../fixtures/fixture_log_observer.hpp"
+
+#include <mbgl/annotation/sprite_parser.hpp>
+#include <mbgl/annotation/sprite_image.hpp>
+#include <mbgl/util/image.hpp>
+#include <mbgl/util/io.hpp>
+
+#include <algorithm>
+
+using namespace mbgl;
+
+TEST(Annotations, SpriteImageCreationInvalid) {
+ FixtureLog log;
+
+ const util::Image image_1x(util::read_file("test/fixtures/annotations/emerald.png"));
+ ASSERT_TRUE(image_1x);
+ ASSERT_EQ(200u, image_1x.getWidth());
+ ASSERT_EQ(299u, image_1x.getHeight());
+
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 0, 16, 1, false)); // width == 0
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 16, 0, 1, false)); // height == 0
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 1, 1, 0, false)); // ratio == 0
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 1, 1, 23, false)); // ratio too large
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 2048, 16, 1, false)); // too wide
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 16, 1025, 1, false)); // too tall
+
+ EXPECT_EQ(6u, log.count({
+ EventSeverity::Warning,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics",
+ }));
+}
+
+TEST(Annotations, SpriteImageCreation1x) {
+ const util::Image image_1x(util::read_file("test/fixtures/annotations/emerald.png"));
+ ASSERT_TRUE(image_1x);
+ ASSERT_EQ(200u, image_1x.getWidth());
+ ASSERT_EQ(299u, image_1x.getHeight());
+
+ { // "museum_icon":{"x":177,"y":187,"width":18,"height":18,"pixelRatio":1,"sdf":false}
+ const auto sprite = createSpriteImage(image_1x, 177, 187, 18, 18, 1, false);
+ ASSERT_TRUE(sprite.get());
+ EXPECT_EQ(18, sprite->width);
+ EXPECT_EQ(18, sprite->height);
+ EXPECT_EQ(18, sprite->pixelWidth);
+ EXPECT_EQ(18, sprite->pixelHeight);
+ EXPECT_EQ(1, sprite->pixelRatio);
+ EXPECT_EQ(0x7FCC5F263D1FFE16u, test::crc64(sprite->data));
+ }
+
+ { // outside image == blank
+ const auto sprite = createSpriteImage(image_1x, 200, 0, 16, 16, 1, false);
+ ASSERT_TRUE(sprite.get());
+ EXPECT_EQ(16, sprite->width);
+ EXPECT_EQ(16, sprite->height);
+ EXPECT_EQ(16, sprite->pixelWidth);
+ EXPECT_EQ(16, sprite->pixelHeight);
+ EXPECT_EQ(1, sprite->pixelRatio);
+ EXPECT_EQ(0x0000000000000000u, test::crc64(sprite->data)) << std::hex << test::crc64(sprite->data);
+ }
+
+ { // outside image == blank
+ const auto sprite = createSpriteImage(image_1x, 0, 300, 16, 16, 1, false);
+ ASSERT_TRUE(sprite.get());
+ EXPECT_EQ(16, sprite->width);
+ EXPECT_EQ(16, sprite->height);
+ EXPECT_EQ(16, sprite->pixelWidth);
+ EXPECT_EQ(16, sprite->pixelHeight);
+ EXPECT_EQ(1, sprite->pixelRatio);
+ EXPECT_EQ(0x0000000000000000u, test::crc64(sprite->data)) << std::hex << test::crc64(sprite->data);
+ }
+}
+
+TEST(Annotations, SpriteImageCreation2x) {
+ const util::Image image_2x(util::read_file("test/fixtures/annotations/emerald@2x.png"));
+ ASSERT_TRUE(image_2x);
+
+ // "museum_icon":{"x":354,"y":374,"width":36,"height":36,"pixelRatio":2,"sdf":false}
+ const auto sprite = createSpriteImage(image_2x, 354, 374, 36, 36, 2, false);
+ ASSERT_TRUE(sprite.get());
+ EXPECT_EQ(18, sprite->width);
+ EXPECT_EQ(18, sprite->height);
+ EXPECT_EQ(36, sprite->pixelWidth);
+ EXPECT_EQ(36, sprite->pixelHeight);
+ EXPECT_EQ(2, sprite->pixelRatio);
+ EXPECT_EQ(0x85F345098DD4F9E3u, test::crc64(sprite->data));
+}
+
+TEST(Annotations, SpriteImageCreation1_5x) {
+ const util::Image image_2x(util::read_file("test/fixtures/annotations/emerald@2x.png"));
+ ASSERT_TRUE(image_2x);
+
+ // "museum_icon":{"x":354,"y":374,"width":36,"height":36,"pixelRatio":2,"sdf":false}
+ const auto sprite = createSpriteImage(image_2x, 354, 374, 36, 36, 1.5, false);
+ ASSERT_TRUE(sprite.get());
+ EXPECT_EQ(24, sprite->width);
+ EXPECT_EQ(24, sprite->height);
+ EXPECT_EQ(36, sprite->pixelWidth);
+ EXPECT_EQ(36, sprite->pixelHeight);
+ EXPECT_EQ(1.5, sprite->pixelRatio);
+ EXPECT_EQ(0x85F345098DD4F9E3u, test::crc64(sprite->data));
+
+ // "hospital_icon":{"x":314,"y":518,"width":36,"height":36,"pixelRatio":2,"sdf":false}
+ const auto sprite2 = createSpriteImage(image_2x, 314, 518, 35, 35, 1.5, false);
+ ASSERT_TRUE(sprite2.get());
+ EXPECT_EQ(24, sprite2->width);
+ EXPECT_EQ(24, sprite2->height);
+ EXPECT_EQ(36, sprite2->pixelWidth);
+ EXPECT_EQ(36, sprite2->pixelHeight);
+ EXPECT_EQ(1.5, sprite2->pixelRatio);
+ EXPECT_EQ(0x134A530C742DD141u, test::crc64(sprite2->data));
+}
+
+TEST(Annotations, SpriteParsing) {
+ const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
+ const auto json_1x = util::read_file("test/fixtures/annotations/emerald.json");
+
+ const auto images = parseSprite(image_1x, json_1x).get<Sprites>();
+
+ std::set<std::string> names;
+ std::transform(images.begin(), images.end(), std::inserter(names, names.begin()),
+ [](const auto& pair) { return pair.first; });
+
+ EXPECT_EQ(std::set<std::string>({ "airfield_icon",
+ "airport_icon",
+ "background",
+ "cemetery_icon",
+ "college_icon",
+ "default_1",
+ "default_2",
+ "default_3",
+ "default_4",
+ "default_5",
+ "default_6",
+ "default_marker",
+ "dlr",
+ "dlr.london-overground.london-underground.national-rail",
+ "dlr.london-underground",
+ "dlr.london-underground.national-rail",
+ "dlr.national-rail",
+ "dot",
+ "embassy_icon",
+ "fire-station_icon",
+ "generic-metro",
+ "generic-rail",
+ "generic_icon",
+ "golf_icon",
+ "government_icon",
+ "grass_pattern",
+ "harbor_icon",
+ "hospital_icon",
+ "hospital_striped",
+ "interstate_1",
+ "interstate_2",
+ "interstate_3",
+ "library_icon",
+ "london-overground",
+ "london-overground.london-underground",
+ "london-overground.london-underground.national-rail",
+ "london-overground.national-rail",
+ "london-underground",
+ "london-underground.national-rail",
+ "marker_icon",
+ "metro",
+ "metro.rer",
+ "monument_icon",
+ "moscow-metro",
+ "museum_icon",
+ "national-rail",
+ "oneway_motorway",
+ "oneway_road",
+ "park_icon",
+ "police_icon",
+ "post_icon",
+ "prison_icon",
+ "religious-christian_icon",
+ "religious-jewish_icon",
+ "religious-muslim_icon",
+ "rer",
+ "rer.transilien",
+ "s-bahn",
+ "s-bahn.u-bahn",
+ "sand_noise",
+ "school_icon",
+ "school_striped",
+ "secondary_marker",
+ "u-bahn",
+ "us_highway_1",
+ "us_highway_2",
+ "us_highway_3",
+ "us_state_1",
+ "us_state_2",
+ "us_state_3",
+ "washington-metro",
+ "wiener-linien",
+ "zoo_icon" }),
+ names);
+
+ {
+ auto sprite = images.find("generic-metro")->second;
+ EXPECT_EQ(18, sprite->width);
+ EXPECT_EQ(18, sprite->height);
+ EXPECT_EQ(18, sprite->pixelWidth);
+ EXPECT_EQ(18, sprite->pixelHeight);
+ EXPECT_EQ(1, sprite->pixelRatio);
+ EXPECT_EQ(0xFF56F5F48F707147u, test::crc64(sprite->data));
+ }
+}
+
+TEST(Annotations, SpriteParsingInvalidJSON) {
+ const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
+ const auto json_1x = R"JSON({ "image": " })JSON";
+
+ const auto error = parseSprite(image_1x, json_1x).get<std::string>();
+
+ EXPECT_EQ(error,
+ std::string("Failed to parse JSON: lacks ending quotation before the end of string at offset 10"));
+}
+
+TEST(Annotations, SpriteParsingEmptyImage) {
+ FixtureLog log;
+
+ const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
+ const auto json_1x = R"JSON({ "image": {} })JSON";
+
+ const auto images = parseSprite(image_1x, json_1x).get<Sprites>();
+ EXPECT_EQ(0u, images.size());
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Warning,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics",
+ }));
+}
+
+TEST(Annotations, SpriteParsingSimpleWidthHeight) {
+ FixtureLog log;
+
+ const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
+ const auto json_1x = R"JSON({ "image": { "width": 32, "height": 32 } })JSON";
+
+ const auto images = parseSprite(image_1x, json_1x).get<Sprites>();
+ EXPECT_EQ(1u, images.size());
+}
+
+TEST(Annotations, SpriteParsingWidthTooBig) {
+ FixtureLog log;
+
+ const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
+ const auto json_1x = R"JSON({ "image": { "width": 65536, "height": 32 } })JSON";
+
+ const auto images = parseSprite(image_1x, json_1x).get<Sprites>();
+ EXPECT_EQ(0u, images.size());
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Warning,
+ Event::Sprite,
+ int64_t(-1),
+ "Value of 'width' must be an integer between 0 and 65535",
+ }));
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Warning,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics",
+ }));
+}
+
+TEST(Annotations, SpriteParsingNegativeWidth) {
+ FixtureLog log;
+
+ const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
+ const auto json_1x = R"JSON({ "image": { "width": -1, "height": 32 } })JSON";
+
+ const auto images = parseSprite(image_1x, json_1x).get<Sprites>();
+ EXPECT_EQ(0u, images.size());
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Warning,
+ Event::Sprite,
+ int64_t(-1),
+ "Value of 'width' must be an integer between 0 and 65535",
+ }));
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Warning,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics",
+ }));
+}
+
+TEST(Annotations, SpriteParsingNullRatio) {
+ FixtureLog log;
+
+ const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
+ const auto json_1x = R"JSON({ "image": { "width": 32, "height": 32, "pixelRatio": 0 } })JSON";
+
+ const auto images = parseSprite(image_1x, json_1x).get<Sprites>();
+ EXPECT_EQ(0u, images.size());
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Warning,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics",
+ }));
+}
diff --git a/test/annotations/sprite_store.cpp b/test/annotations/sprite_store.cpp
new file mode 100644
index 0000000000..16eaad2499
--- /dev/null
+++ b/test/annotations/sprite_store.cpp
@@ -0,0 +1,143 @@
+#include "../fixtures/util.hpp"
+#include "../fixtures/fixture_log_observer.hpp"
+
+#include <mbgl/annotation/sprite_store.hpp>
+
+using namespace mbgl;
+
+TEST(Annotations, SpriteStore) {
+ FixtureLog log;
+
+ 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'));
+ const auto sprite3 = std::make_shared<SpriteImage>(8, 8, 2, std::string(16 * 16 * 4, '\0'));
+
+ using Sprites = std::map<std::string, std::shared_ptr<const SpriteImage>>;
+ SpriteStore store;
+
+ // Adding single
+ store.setSprite("one", sprite1);
+ EXPECT_EQ(Sprites({
+ { "one", sprite1 },
+ }),
+ store.getDirty());
+ EXPECT_EQ(Sprites(), store.getDirty());
+
+ // Adding multiple
+ store.setSprite("two", sprite2);
+ store.setSprite("three", sprite3);
+ EXPECT_EQ(Sprites({
+ { "two", sprite2 }, { "three", sprite3 },
+ }),
+ store.getDirty());
+ EXPECT_EQ(Sprites(), store.getDirty());
+
+ // Removing
+ store.removeSprite("one");
+ store.removeSprite("two");
+ EXPECT_EQ(Sprites({
+ { "one", nullptr }, { "two", nullptr },
+ }),
+ store.getDirty());
+ EXPECT_EQ(Sprites(), store.getDirty());
+
+ // Accessing
+ EXPECT_EQ(sprite3, store.getSprite("three"));
+
+ EXPECT_TRUE(log.empty());
+
+ EXPECT_EQ(nullptr, store.getSprite("two"));
+ EXPECT_EQ(nullptr, store.getSprite("four"));
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Info,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't find sprite named 'two'",
+ }));
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Info,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't find sprite named 'four'",
+ }));
+
+ // Overwriting
+ store.setSprite("three", sprite1);
+ EXPECT_EQ(Sprites({
+ { "three", sprite1 },
+ }),
+ store.getDirty());
+ EXPECT_EQ(Sprites(), store.getDirty());
+}
+
+TEST(Annotations, SpriteStoreOtherPixelRatio) {
+ FixtureLog log;
+
+ const auto sprite1 = std::make_shared<SpriteImage>(8, 8, 1, std::string(8 * 8 * 4, '\0'));
+
+ using Sprites = std::map<std::string, std::shared_ptr<const SpriteImage>>;
+ SpriteStore store;
+
+ // Adding mismatched sprite image
+ store.setSprite("one", sprite1);
+ EXPECT_EQ(Sprites({ { "one", sprite1 } }), store.getDirty());
+}
+
+TEST(Annotations, SpriteStoreMultiple) {
+ 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'));
+
+ using Sprites = std::map<std::string, std::shared_ptr<const SpriteImage>>;
+ SpriteStore store;
+
+ store.setSprites({
+ { "one", sprite1 }, { "two", sprite2 },
+ });
+ EXPECT_EQ(Sprites({
+ { "one", sprite1 }, { "two", sprite2 },
+ }),
+ store.getDirty());
+ EXPECT_EQ(Sprites(), store.getDirty());
+}
+
+TEST(Annotations, SpriteStoreReplace) {
+ FixtureLog log;
+
+ 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'));
+
+ using Sprites = std::map<std::string, std::shared_ptr<const SpriteImage>>;
+ SpriteStore store;
+
+ store.setSprite("sprite", sprite1);
+ EXPECT_EQ(sprite1, store.getSprite("sprite"));
+ store.setSprite("sprite", sprite2);
+ EXPECT_EQ(sprite2, store.getSprite("sprite"));
+
+ EXPECT_EQ(Sprites({ { "sprite", sprite2 } }), store.getDirty());
+}
+
+TEST(Annotations, SpriteStoreReplaceWithDifferentDimensions) {
+ FixtureLog log;
+
+ const auto sprite1 = std::make_shared<SpriteImage>(8, 8, 2, std::string(16 * 16 * 4, '\0'));
+ const auto sprite2 = std::make_shared<SpriteImage>(9, 9, 2, std::string(18 * 18 * 4, '\0'));
+
+ using Sprites = std::map<std::string, std::shared_ptr<const SpriteImage>>;
+ SpriteStore store;
+
+ store.setSprite("sprite", sprite1);
+ store.setSprite("sprite", sprite2);
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Warning,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't change sprite dimensions for 'sprite'",
+ }));
+
+ EXPECT_EQ(sprite1, store.getSprite("sprite"));
+
+ EXPECT_EQ(Sprites({ { "sprite", sprite1 } }), store.getDirty());
+}
diff --git a/test/api/annotations.cpp b/test/api/annotations.cpp
new file mode 100644
index 0000000000..33374d4386
--- /dev/null
+++ b/test/api/annotations.cpp
@@ -0,0 +1,36 @@
+#include "../fixtures/fixture_log_observer.hpp"
+#include "../fixtures/mock_file_source.hpp"
+#include "../fixtures/util.hpp"
+
+#include <mbgl/annotation/point_annotation.hpp>
+#include <mbgl/map/map.hpp>
+#include <mbgl/map/still_image.hpp>
+#include <mbgl/platform/default/headless_display.hpp>
+#include <mbgl/platform/default/headless_view.hpp>
+
+#include <future>
+#include <vector>
+
+TEST(API, PointAnnotation) {
+ using namespace mbgl;
+
+ auto display = std::make_shared<mbgl::HeadlessDisplay>();
+ HeadlessView view(display, 1);
+
+ MockFileSource fileSource(MockFileSource::Success, "");
+
+ Map map(view, fileSource, MapMode::Still);
+ map.setStyleURL("test/fixtures/resources/style.json");
+
+ std::vector<PointAnnotation> points;
+ points.emplace_back(PointAnnotation({ 50.0, 50.0 }, "default_marker"));
+
+ map.addPointAnnotations(points);
+
+ std::promise<bool> promise;
+ map.renderStill([&promise](std::exception_ptr, std::unique_ptr<const StillImage>) {
+ promise.set_value(true);
+ });
+
+ promise.get_future().get();
+}
diff --git a/test/api/api_misuse.cpp b/test/api/api_misuse.cpp
index a98cf04101..1f54855323 100644
--- a/test/api/api_misuse.cpp
+++ b/test/api/api_misuse.cpp
@@ -17,11 +17,11 @@ TEST(API, RenderWithoutCallback) {
Log::setObserver(std::unique_ptr<Log::Observer>(log));
auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display);
+ HeadlessView view(display, 1);
+ view.resize(128, 512);
DefaultFileSource fileSource(nullptr);
std::unique_ptr<Map> map = std::make_unique<Map>(view, fileSource, MapMode::Still);
- map->resize(128, 512, 1);
map->renderStill(nullptr);
// Force Map thread to join.
@@ -39,11 +39,11 @@ TEST(API, RenderWithoutCallback) {
TEST(API, RenderWithoutStyle) {
auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display);
+ HeadlessView view(display, 1);
+ view.resize(128, 512);
DefaultFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Still);
- map.resize(128, 512, 1);
std::promise<std::exception_ptr> promise;
map.renderStill([&promise](std::exception_ptr error, std::unique_ptr<const StillImage>) {
diff --git a/test/api/repeated_render.cpp b/test/api/repeated_render.cpp
index 7f55237744..3317b4e3a4 100644
--- a/test/api/repeated_render.cpp
+++ b/test/api/repeated_render.cpp
@@ -17,7 +17,7 @@ TEST(API, RepeatedRender) {
const auto style = util::read_file("test/fixtures/api/water.json");
auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display);
+ HeadlessView view(display, 1, 256, 512);
DefaultFileSource fileSource(nullptr);
Log::setObserver(std::make_unique<FixtureLogObserver>());
@@ -25,29 +25,27 @@ TEST(API, RepeatedRender) {
Map map(view, fileSource, MapMode::Still);
{
- map.resize(128, 512, 1);
- map.setStyleJSON(style, "test/suite");
+ map.setStyleJSON(style, "");
std::promise<std::unique_ptr<const StillImage>> promise;
map.renderStill([&promise](std::exception_ptr, std::unique_ptr<const StillImage> image) {
promise.set_value(std::move(image));
});
auto result = promise.get_future().get();
- ASSERT_EQ(128, result->width);
+ ASSERT_EQ(256, result->width);
ASSERT_EQ(512, result->height);
const std::string png = util::compress_png(result->width, result->height, result->pixels.get());
util::write_file("test/fixtures/api/1.png", png);
}
{
- map.resize(512, 512, 2);
map.setStyleJSON(style, "TEST_DATA/suite");
std::promise<std::unique_ptr<const StillImage>> promise;
map.renderStill([&promise](std::exception_ptr, std::unique_ptr<const StillImage> image) {
promise.set_value(std::move(image));
});
auto result = promise.get_future().get();
- ASSERT_EQ(1024, result->width);
- ASSERT_EQ(1024, result->height);
+ ASSERT_EQ(256, result->width);
+ ASSERT_EQ(512, result->height);
const std::string png = util::compress_png(result->width, result->height, result->pixels.get());
util::write_file("test/fixtures/api/2.png", png);
}
diff --git a/test/api/set_style.cpp b/test/api/set_style.cpp
index 72260e6343..c3e62def20 100644
--- a/test/api/set_style.cpp
+++ b/test/api/set_style.cpp
@@ -11,14 +11,14 @@ TEST(API, SetStyle) {
using namespace mbgl;
auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display);
+ HeadlessView view(display, 1);
DefaultFileSource fileSource(nullptr);
Log::setObserver(std::make_unique<FixtureLogObserver>());
{
Map map(view, fileSource, MapMode::Still);
- map.setStyleJSON("invalid", "test/suite");
+ map.setStyleJSON("invalid", "");
}
auto observer = Log::removeObserver();
diff --git a/test/fixtures/annotations/emerald.json b/test/fixtures/annotations/emerald.json
new file mode 100644
index 0000000000..dcc2b4808c
--- /dev/null
+++ b/test/fixtures/annotations/emerald.json
@@ -0,0 +1 @@
+{"background":{"x":0,"y":20,"width":50,"height":50,"pixelRatio":1,"sdf":false},"grass_pattern":{"x":100,"y":80,"width":50,"height":50,"pixelRatio":1,"sdf":false},"interstate_1":{"x":0,"y":100,"width":41,"height":40,"pixelRatio":1,"sdf":false},"interstate_2":{"x":0,"y":100,"width":41,"height":40,"pixelRatio":1,"sdf":false},"interstate_3":{"x":41,"y":100,"width":48,"height":39,"pixelRatio":1,"sdf":false},"us_state_1":{"x":0,"y":73,"width":29,"height":24,"pixelRatio":1,"sdf":false},"us_state_2":{"x":0,"y":73,"width":29,"height":24,"pixelRatio":1,"sdf":false},"us_state_3":{"x":30,"y":73,"width":32,"height":24,"pixelRatio":1,"sdf":false},"us_highway_1":{"x":0,"y":142,"width":29,"height":29,"pixelRatio":1,"sdf":false},"us_highway_2":{"x":30,"y":142,"width":33,"height":29,"pixelRatio":1,"sdf":false},"us_highway_3":{"x":64,"y":142,"width":36,"height":29,"pixelRatio":1,"sdf":false},"default_1":{"x":0,"y":0,"width":17,"height":16,"pixelRatio":1,"sdf":false},"default_2":{"x":17,"y":0,"width":22,"height":16,"pixelRatio":1,"sdf":false},"default_3":{"x":39,"y":0,"width":27,"height":16,"pixelRatio":1,"sdf":false},"default_4":{"x":66,"y":0,"width":32,"height":16,"pixelRatio":1,"sdf":false},"default_5":{"x":98,"y":0,"width":37,"height":16,"pixelRatio":1,"sdf":false},"default_6":{"x":135,"y":0,"width":42,"height":16,"pixelRatio":1,"sdf":false},"london-overground":{"x":70,"y":25,"width":18,"height":18,"pixelRatio":1,"sdf":false},"london-underground":{"x":88,"y":25,"width":18,"height":18,"pixelRatio":1,"sdf":false},"national-rail":{"x":106,"y":25,"width":18,"height":18,"pixelRatio":1,"sdf":false},"dlr":{"x":106,"y":25,"width":18,"height":18,"pixelRatio":1,"sdf":false},"dlr.london-overground.london-underground.national-rail":{"x":70,"y":25,"width":72,"height":18,"pixelRatio":1,"sdf":false},"dlr.london-underground":{"x":88,"y":25,"width":36,"height":18,"pixelRatio":1,"sdf":false},"dlr.london-underground.national-rail":{"x":88,"y":25,"width":54,"height":18,"pixelRatio":1,"sdf":false},"dlr.national-rail":{"x":106,"y":25,"width":36,"height":18,"pixelRatio":1,"sdf":false},"london-overground.london-underground":{"x":70,"y":25,"width":36,"height":18,"pixelRatio":1,"sdf":false},"london-overground.london-underground.national-rail":{"x":124,"y":25,"width":54,"height":18,"pixelRatio":1,"sdf":false},"london-overground.national-rail":{"x":124,"y":25,"width":36,"height":18,"pixelRatio":1,"sdf":false},"london-underground.national-rail":{"x":124,"y":43,"width":36,"height":18,"pixelRatio":1,"sdf":false},"metro":{"x":71,"y":43,"width":18,"height":18,"pixelRatio":1,"sdf":false},"rer":{"x":87,"y":43,"width":18,"height":18,"pixelRatio":1,"sdf":false},"metro.rer":{"x":71,"y":43,"width":34,"height":18,"pixelRatio":1,"sdf":false},"rer.transilien":{"x":87,"y":43,"width":36,"height":18,"pixelRatio":1,"sdf":false},"u-bahn":{"x":70,"y":62,"width":18,"height":18,"pixelRatio":1,"sdf":false},"s-bahn":{"x":88,"y":62,"width":18,"height":18,"pixelRatio":1,"sdf":false},"s-bahn.u-bahn":{"x":70,"y":62,"width":36,"height":18,"pixelRatio":1,"sdf":false},"washington-metro":{"x":106,"y":62,"width":18,"height":18,"pixelRatio":1,"sdf":false},"wiener-linien":{"x":124,"y":62,"width":18,"height":18,"pixelRatio":1,"sdf":false},"moscow-metro":{"x":142,"y":61,"width":21,"height":18,"pixelRatio":1,"sdf":false},"generic-metro":{"x":160,"y":43,"width":18,"height":18,"pixelRatio":1,"sdf":false},"generic-rail":{"x":178,"y":43,"width":18,"height":18,"pixelRatio":1,"sdf":false},"dot":{"x":166,"y":63,"width":13,"height":13,"pixelRatio":1,"sdf":false},"default_marker":{"x":0,"y":175,"width":33,"height":86,"pixelRatio":1,"sdf":false},"secondary_marker":{"x":33,"y":175,"width":33,"height":86,"pixelRatio":1,"sdf":false},"oneway_motorway":{"x":178,"y":24,"width":21,"height":19,"pixelRatio":1,"sdf":false},"oneway_road":{"x":178,"y":62,"width":21,"height":19,"pixelRatio":1,"sdf":false},"hospital_icon":{"x":157,"y":259,"width":18,"height":18,"pixelRatio":1,"sdf":false},"fire-station_icon":{"x":157,"y":241,"width":18,"height":18,"pixelRatio":1,"sdf":false},"cemetery_icon":{"x":157,"y":79,"width":18,"height":18,"pixelRatio":1,"sdf":false},"zoo_icon":{"x":177,"y":79,"width":18,"height":18,"pixelRatio":1,"sdf":false},"park_icon":{"x":177,"y":97,"width":18,"height":18,"pixelRatio":1,"sdf":false},"golf_icon":{"x":177,"y":115,"width":18,"height":18,"pixelRatio":1,"sdf":false},"school_icon":{"x":177,"y":133,"width":18,"height":18,"pixelRatio":1,"sdf":false},"monument_icon":{"x":177,"y":151,"width":18,"height":18,"pixelRatio":1,"sdf":false},"library_icon":{"x":177,"y":169,"width":18,"height":18,"pixelRatio":1,"sdf":false},"museum_icon":{"x":177,"y":187,"width":18,"height":18,"pixelRatio":1,"sdf":false},"college_icon":{"x":177,"y":205,"width":18,"height":18,"pixelRatio":1,"sdf":false},"religious-christian_icon":{"x":157,"y":115,"width":18,"height":18,"pixelRatio":1,"sdf":false},"religious-jewish_icon":{"x":157,"y":133,"width":18,"height":18,"pixelRatio":1,"sdf":false},"religious-muslim_icon":{"x":157,"y":151,"width":18,"height":18,"pixelRatio":1,"sdf":false},"government_icon":{"x":157,"y":169,"width":18,"height":18,"pixelRatio":1,"sdf":false},"post_icon":{"x":157,"y":205,"width":18,"height":18,"pixelRatio":1,"sdf":false},"embassy_icon":{"x":157,"y":223,"width":18,"height":18,"pixelRatio":1,"sdf":false},"police_icon":{"x":157,"y":169,"width":18,"height":18,"pixelRatio":1,"sdf":false},"marker_icon":{"x":157,"y":169,"width":18,"height":18,"pixelRatio":1,"sdf":false},"prison_icon":{"x":157,"y":169,"width":18,"height":18,"pixelRatio":1,"sdf":false},"airfield_icon":{"x":157,"y":187,"width":18,"height":18,"pixelRatio":1,"sdf":false},"airport_icon":{"x":157,"y":187,"width":18,"height":18,"pixelRatio":1,"sdf":false},"harbor_icon":{"x":139,"y":169,"width":18,"height":18,"pixelRatio":1,"sdf":false},"generic_icon":{"x":139,"y":187,"width":18,"height":18,"pixelRatio":1,"sdf":false},"hospital_striped":{"x":117,"y":135,"width":3,"height":3,"pixelRatio":1,"sdf":false},"school_striped":{"x":114,"y":135,"width":3,"height":3,"pixelRatio":1,"sdf":false},"sand_noise":{"x":75,"y":174,"width":50,"height":50,"pixelRatio":1,"sdf":false}} \ No newline at end of file
diff --git a/test/fixtures/annotations/emerald.png b/test/fixtures/annotations/emerald.png
new file mode 100644
index 0000000000..967f2e76a6
--- /dev/null
+++ b/test/fixtures/annotations/emerald.png
Binary files differ
diff --git a/test/fixtures/annotations/emerald@2x.json b/test/fixtures/annotations/emerald@2x.json
new file mode 100644
index 0000000000..250aa36194
--- /dev/null
+++ b/test/fixtures/annotations/emerald@2x.json
@@ -0,0 +1 @@
+{"background":{"x":0,"y":40,"width":100,"height":100,"pixelRatio":2,"sdf":false},"grass_pattern":{"x":200,"y":160,"width":100,"height":100,"pixelRatio":2,"sdf":false},"interstate_1":{"x":0,"y":200,"width":82,"height":80,"pixelRatio":2,"sdf":false},"interstate_2":{"x":0,"y":200,"width":82,"height":80,"pixelRatio":2,"sdf":false},"interstate_3":{"x":82,"y":200,"width":96,"height":78,"pixelRatio":2,"sdf":false},"us_state_1":{"x":0,"y":146,"width":58,"height":48,"pixelRatio":2,"sdf":false},"us_state_2":{"x":0,"y":146,"width":58,"height":48,"pixelRatio":2,"sdf":false},"us_state_3":{"x":60,"y":146,"width":64,"height":48,"pixelRatio":2,"sdf":false},"us_highway_1":{"x":0,"y":284,"width":58,"height":58,"pixelRatio":2,"sdf":false},"us_highway_2":{"x":60,"y":284,"width":66,"height":58,"pixelRatio":2,"sdf":false},"us_highway_3":{"x":128,"y":284,"width":72,"height":58,"pixelRatio":2,"sdf":false},"default_1":{"x":0,"y":0,"width":34,"height":32,"pixelRatio":2,"sdf":false},"default_2":{"x":34,"y":0,"width":44,"height":32,"pixelRatio":2,"sdf":false},"default_3":{"x":78,"y":0,"width":54,"height":32,"pixelRatio":2,"sdf":false},"default_4":{"x":132,"y":0,"width":64,"height":32,"pixelRatio":2,"sdf":false},"default_5":{"x":196,"y":0,"width":74,"height":32,"pixelRatio":2,"sdf":false},"default_6":{"x":270,"y":0,"width":84,"height":32,"pixelRatio":2,"sdf":false},"london-overground":{"x":140,"y":50,"width":36,"height":36,"pixelRatio":2,"sdf":false},"london-underground":{"x":176,"y":50,"width":36,"height":36,"pixelRatio":2,"sdf":false},"national-rail":{"x":212,"y":50,"width":36,"height":36,"pixelRatio":2,"sdf":false},"dlr":{"x":212,"y":50,"width":36,"height":36,"pixelRatio":2,"sdf":false},"dlr.london-overground.london-underground.national-rail":{"x":140,"y":50,"width":144,"height":36,"pixelRatio":2,"sdf":false},"dlr.london-underground":{"x":176,"y":50,"width":72,"height":36,"pixelRatio":2,"sdf":false},"dlr.london-underground.national-rail":{"x":176,"y":50,"width":108,"height":36,"pixelRatio":2,"sdf":false},"dlr.national-rail":{"x":212,"y":50,"width":72,"height":36,"pixelRatio":2,"sdf":false},"london-overground.london-underground":{"x":140,"y":50,"width":72,"height":36,"pixelRatio":2,"sdf":false},"london-overground.london-underground.national-rail":{"x":248,"y":50,"width":108,"height":36,"pixelRatio":2,"sdf":false},"london-overground.national-rail":{"x":248,"y":50,"width":72,"height":36,"pixelRatio":2,"sdf":false},"london-underground.national-rail":{"x":248,"y":86,"width":72,"height":36,"pixelRatio":2,"sdf":false},"metro":{"x":142,"y":86,"width":36,"height":36,"pixelRatio":2,"sdf":false},"rer":{"x":174,"y":86,"width":36,"height":36,"pixelRatio":2,"sdf":false},"metro.rer":{"x":142,"y":86,"width":68,"height":36,"pixelRatio":2,"sdf":false},"rer.transilien":{"x":174,"y":86,"width":72,"height":36,"pixelRatio":2,"sdf":false},"u-bahn":{"x":140,"y":124,"width":36,"height":36,"pixelRatio":2,"sdf":false},"s-bahn":{"x":176,"y":124,"width":36,"height":36,"pixelRatio":2,"sdf":false},"s-bahn.u-bahn":{"x":140,"y":124,"width":72,"height":36,"pixelRatio":2,"sdf":false},"washington-metro":{"x":212,"y":124,"width":36,"height":36,"pixelRatio":2,"sdf":false},"wiener-linien":{"x":248,"y":124,"width":36,"height":36,"pixelRatio":2,"sdf":false},"moscow-metro":{"x":284,"y":122,"width":42,"height":36,"pixelRatio":2,"sdf":false},"generic-metro":{"x":320,"y":86,"width":36,"height":36,"pixelRatio":2,"sdf":false},"generic-rail":{"x":356,"y":86,"width":36,"height":36,"pixelRatio":2,"sdf":false},"dot":{"x":332,"y":126,"width":26,"height":26,"pixelRatio":2,"sdf":false},"default_marker":{"x":0,"y":350,"width":66,"height":172,"pixelRatio":2,"sdf":false},"secondary_marker":{"x":66,"y":350,"width":66,"height":172,"pixelRatio":2,"sdf":false},"oneway_motorway":{"x":356,"y":48,"width":42,"height":38,"pixelRatio":2,"sdf":false},"oneway_road":{"x":356,"y":124,"width":42,"height":38,"pixelRatio":2,"sdf":false},"hospital_icon":{"x":314,"y":518,"width":36,"height":36,"pixelRatio":2,"sdf":false},"fire-station_icon":{"x":314,"y":482,"width":36,"height":36,"pixelRatio":2,"sdf":false},"cemetery_icon":{"x":314,"y":158,"width":36,"height":36,"pixelRatio":2,"sdf":false},"zoo_icon":{"x":354,"y":158,"width":36,"height":36,"pixelRatio":2,"sdf":false},"park_icon":{"x":354,"y":194,"width":36,"height":36,"pixelRatio":2,"sdf":false},"golf_icon":{"x":354,"y":230,"width":36,"height":36,"pixelRatio":2,"sdf":false},"school_icon":{"x":354,"y":266,"width":36,"height":36,"pixelRatio":2,"sdf":false},"monument_icon":{"x":354,"y":302,"width":36,"height":36,"pixelRatio":2,"sdf":false},"library_icon":{"x":354,"y":338,"width":36,"height":36,"pixelRatio":2,"sdf":false},"museum_icon":{"x":354,"y":374,"width":36,"height":36,"pixelRatio":2,"sdf":false},"college_icon":{"x":354,"y":410,"width":36,"height":36,"pixelRatio":2,"sdf":false},"religious-christian_icon":{"x":314,"y":230,"width":36,"height":36,"pixelRatio":2,"sdf":false},"religious-jewish_icon":{"x":314,"y":266,"width":36,"height":36,"pixelRatio":2,"sdf":false},"religious-muslim_icon":{"x":314,"y":302,"width":36,"height":36,"pixelRatio":2,"sdf":false},"government_icon":{"x":314,"y":338,"width":36,"height":36,"pixelRatio":2,"sdf":false},"post_icon":{"x":314,"y":410,"width":36,"height":36,"pixelRatio":2,"sdf":false},"embassy_icon":{"x":314,"y":446,"width":36,"height":36,"pixelRatio":2,"sdf":false},"police_icon":{"x":314,"y":338,"width":36,"height":36,"pixelRatio":2,"sdf":false},"marker_icon":{"x":314,"y":338,"width":36,"height":36,"pixelRatio":2,"sdf":false},"prison_icon":{"x":314,"y":338,"width":36,"height":36,"pixelRatio":2,"sdf":false},"airfield_icon":{"x":314,"y":374,"width":36,"height":36,"pixelRatio":2,"sdf":false},"airport_icon":{"x":314,"y":374,"width":36,"height":36,"pixelRatio":2,"sdf":false},"harbor_icon":{"x":278,"y":338,"width":36,"height":36,"pixelRatio":2,"sdf":false},"generic_icon":{"x":278,"y":374,"width":36,"height":36,"pixelRatio":2,"sdf":false},"hospital_striped":{"x":234,"y":270,"width":6,"height":6,"pixelRatio":2,"sdf":false},"school_striped":{"x":228,"y":270,"width":6,"height":6,"pixelRatio":2,"sdf":false},"sand_noise":{"x":150,"y":348,"width":100,"height":100,"pixelRatio":2,"sdf":false}} \ No newline at end of file
diff --git a/test/fixtures/annotations/emerald@2x.png b/test/fixtures/annotations/emerald@2x.png
new file mode 100644
index 0000000000..a1ffbd95ea
--- /dev/null
+++ b/test/fixtures/annotations/emerald@2x.png
Binary files differ
diff --git a/test/fixtures/api/water.json b/test/fixtures/api/water.json
index 2bcce11992..c969b345ae 100644
--- a/test/fixtures/api/water.json
+++ b/test/fixtures/api/water.json
@@ -1,5 +1,5 @@
{
- "version": 7,
+ "version": 8,
"name": "Water",
"sources": {
"mapbox": {
diff --git a/test/fixtures/fixture_log_observer.cpp b/test/fixtures/fixture_log_observer.cpp
index b3b8e56fdb..a6e89e2e79 100644
--- a/test/fixtures/fixture_log_observer.cpp
+++ b/test/fixtures/fixture_log_observer.cpp
@@ -3,33 +3,50 @@
namespace mbgl {
-FixtureLogObserver::LogMessage::LogMessage(EventSeverity severity_, Event event_, int64_t code_,
- const std::string &msg_)
+FixtureLog::Message::Message(EventSeverity severity_,
+ Event event_,
+ int64_t code_,
+ const std::string& msg_)
: severity(severity_), event(event_), code(code_), msg(msg_) {
}
-FixtureLogObserver::LogMessage::LogMessage() : severity(), event(), code(), msg() {
+bool FixtureLog::Message::operator==(const Message& rhs) const {
+ return severity == rhs.severity && event == rhs.event && code == rhs.code && msg == rhs.msg;
}
-bool FixtureLogObserver::LogMessage::operator==(const LogMessage &rhs) const {
- return (!severity || !rhs.severity || severity.get() == rhs.severity.get()) &&
- (!event || !rhs.event || event.get() == rhs.event.get()) &&
- (!code || !rhs.code || code.get() == rhs.code.get()) &&
- (!msg || !rhs.msg || msg.get() == rhs.msg.get());
+FixtureLog::Message::Message() : severity(), event(), code(), msg() {
}
-FixtureLogObserver::~FixtureLogObserver() {
+FixtureLog::Observer::Observer(FixtureLog* log_) : log(log_) {
+}
+
+FixtureLog::Observer::~Observer() {
+ if (log) {
+ log->observer = nullptr;
+ }
std::cerr << unchecked();
}
-bool FixtureLogObserver::onRecord(EventSeverity severity, Event event, int64_t code,
- const std::string &msg) {
+bool FixtureLog::Observer::onRecord(EventSeverity severity,
+ Event event,
+ int64_t code,
+ const std::string& msg) {
+ std::lock_guard<std::mutex> lock(messagesMutex);
+
messages.emplace_back(severity, event, code, msg);
return true;
}
-size_t FixtureLogObserver::count(const LogMessage &message) const {
+bool FixtureLog::Observer::empty() const {
+ std::lock_guard<std::mutex> lock(messagesMutex);
+
+ return messages.empty();
+}
+
+size_t FixtureLog::Observer::count(const Message& message) const {
+ std::lock_guard<std::mutex> lock(messagesMutex);
+
size_t message_count = 0;
for (const auto& msg : messages) {
if (msg == message) {
@@ -40,8 +57,28 @@ size_t FixtureLogObserver::count(const LogMessage &message) const {
return message_count;
}
-std::vector<FixtureLogObserver::LogMessage> FixtureLogObserver::unchecked() const {
- std::vector<LogMessage> unchecked_messages;
+FixtureLog::FixtureLog() : observer(new FixtureLogObserver(this)) {
+ Log::setObserver(std::unique_ptr<Log::Observer>(observer));
+}
+
+bool FixtureLog::empty() const {
+ return observer ? observer->empty() : true;
+}
+
+size_t FixtureLog::count(const FixtureLog::Message& message) const {
+ return observer ? observer->count(message) : 0;
+}
+
+FixtureLog::~FixtureLog() {
+ if (observer) {
+ Log::removeObserver();
+ }
+}
+
+std::vector<FixtureLog::Message> FixtureLogObserver::unchecked() const {
+ std::lock_guard<std::mutex> lock(messagesMutex);
+
+ std::vector<Message> unchecked_messages;
for (const auto& msg : messages) {
if (!msg.checked) {
unchecked_messages.push_back(msg);
@@ -51,21 +88,18 @@ std::vector<FixtureLogObserver::LogMessage> FixtureLogObserver::unchecked() cons
return unchecked_messages;
}
-::std::ostream &operator<<(::std::ostream &os,
- const std::vector<FixtureLogObserver::LogMessage> &messages) {
+::std::ostream& operator<<(::std::ostream& os, const std::vector<FixtureLog::Message>& messages) {
for (const auto& message : messages) {
os << "- " << message;
}
return os;
}
-::std::ostream &operator<<(::std::ostream &os, const FixtureLogObserver::LogMessage &message) {
- os << "[\"" << message.severity.get() << "\", \"" << message.event.get() << "\"";
- if (message.code)
- os << ", " << message.code.get();
- if (message.msg)
- os << ", \"" << message.msg.get() << "\"";
+::std::ostream& operator<<(::std::ostream& os, const FixtureLog::Message& message) {
+ os << "[\"" << message.severity << "\", \"" << message.event << "\"";
+ os << ", " << message.code;
+ os << ", \"" << message.msg << "\"";
return os << "]" << std::endl;
}
-}
+} // namespace mbgl
diff --git a/test/fixtures/fixture_log_observer.hpp b/test/fixtures/fixture_log_observer.hpp
index 7e419a617f..f2ccb5cb58 100644
--- a/test/fixtures/fixture_log_observer.hpp
+++ b/test/fixtures/fixture_log_observer.hpp
@@ -2,46 +2,70 @@
#define MBGL_TEST_FIXTURE_LOG_OBSERVER
#include <mbgl/platform/log.hpp>
-#include <mbgl/util/optional.hpp>
#include <vector>
#include <cstdarg>
+#include <mutex>
#include <iostream>
namespace mbgl {
-class FixtureLogObserver : public Log::Observer {
+class FixtureLog {
public:
- struct LogMessage {
- LogMessage(EventSeverity severity_, Event event_, int64_t code_, const std::string &msg_);
- LogMessage();
+ struct Message {
+ Message(EventSeverity severity_, Event event_, int64_t code_, const std::string &msg_);
+ Message();
- bool operator==(const LogMessage &rhs) const;
+ bool operator==(const Message& rhs) const;
- const mapbox::util::optional<EventSeverity> severity;
- const mapbox::util::optional<Event> event;
- const mapbox::util::optional<int64_t> code;
- const mapbox::util::optional<std::string> msg;
+ const EventSeverity severity;
+ const Event event;
+ const int64_t code;
+ const std::string msg;
mutable bool checked = false;
};
- ~FixtureLogObserver();
+ class Observer : public Log::Observer {
+ public:
+ using LogMessage = Message;
- // Log::Observer implementation
- virtual bool onRecord(EventSeverity severity, Event event, int64_t code, const std::string &msg) override;
+ Observer(FixtureLog* log = nullptr);
+ ~Observer();
- size_t count(const LogMessage &message) const;
- std::vector<LogMessage> unchecked() const;
+ // Log::Observer implementation
+ virtual bool onRecord(EventSeverity severity,
+ Event event,
+ int64_t code,
+ const std::string& msg) override;
-public:
- std::vector<LogMessage> messages;
+ bool empty() const;
+ size_t count(const Message& message) const;
+ std::vector<Message> unchecked() const;
+
+ private:
+ FixtureLog* log;
+ std::vector<Message> messages;
+ mutable std::mutex messagesMutex;
+ };
+
+ FixtureLog();
+
+ bool empty() const;
+ size_t count(const Message& message) const;
+
+ ~FixtureLog();
+
+private:
+ Observer* observer;
};
::std::ostream &operator<<(::std::ostream &os,
- const std::vector<FixtureLogObserver::LogMessage> &messages);
-::std::ostream &operator<<(::std::ostream &os, const FixtureLogObserver::LogMessage &message);
+ const std::vector<FixtureLog::Observer::LogMessage> &messages);
+::std::ostream &operator<<(::std::ostream &os, const FixtureLog::Observer::LogMessage &message);
+
+using FixtureLogObserver = FixtureLog::Observer;
-}
+} // namespace mbgl
#endif
diff --git a/test/fixtures/headless/pois.json b/test/fixtures/headless/pois.json
new file mode 100644
index 0000000000..a7fcfdb9dc
--- /dev/null
+++ b/test/fixtures/headless/pois.json
@@ -0,0 +1,26 @@
+{
+ "version": 8,
+ "name": "POIs",
+ "sources": {
+ "mapbox": {
+ "type": "vector",
+ "url": "asset://TEST_DATA/fixtures/tiles/streets.json"
+ }
+ },
+ "layers": [{
+ "id": "background",
+ "type": "background",
+ "paint": {
+ "background-color": "#CCCCCC"
+ }
+ }, {
+ "id": "pois",
+ "type": "symbol",
+ "source": "mapbox",
+ "source-layer": "poi_label",
+ "filter": ["in", "maki", "cafe", "bakery"],
+ "layout": {
+ "icon-image": "{maki}"
+ }
+ }]
+}
diff --git a/test/style/mock_file_source.cpp b/test/fixtures/mock_file_source.cpp
index 6aa735d0ea..b420ba7298 100644
--- a/test/style/mock_file_source.cpp
+++ b/test/fixtures/mock_file_source.cpp
@@ -17,8 +17,8 @@ namespace mbgl {
class MockFileSource::Impl {
public:
- Impl(uv_loop_t* loop, Type type, const std::string& match)
- : type_(type), match_(match), timer_(loop) {
+ Impl(Type type, const std::string& match)
+ : type_(type), match_(match), timer_(util::RunLoop::getLoop()) {
timer_.start(timeout, timeout, [this] { dispatchPendingRequests(); });
timer_.unref();
}
@@ -53,7 +53,13 @@ private:
void MockFileSource::Impl::replyWithSuccess(Request* req) const {
std::shared_ptr<Response> res = std::make_shared<Response>();
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);
}
@@ -117,11 +123,13 @@ void MockFileSource::Impl::handleRequest(Request* req) {
void MockFileSource::Impl::cancelRequest(Request* req) {
auto it = std::find(pendingRequests_.begin(), pendingRequests_.end(), req);
if (it != pendingRequests_.end()) {
- (*it)->destruct();
pendingRequests_.erase(it);
} else {
- EXPECT_TRUE(false) << "Should never be reached.";
+ // There is no request for this URL anymore. Likely, the request already completed
+ // before we got around to process the cancelation request.
}
+
+ req->destruct();
}
void MockFileSource::Impl::dispatchPendingRequests() {
@@ -142,7 +150,7 @@ void MockFileSource::setOnRequestDelayedCallback(std::function<void(void)> callb
Request* MockFileSource::request(const Resource& resource, uv_loop_t* loop, Callback callback) {
Request* req = new Request(resource, loop, std::move(callback));
- thread_->invokeSync(&Impl::handleRequest, req);
+ thread_->invoke(&Impl::handleRequest, req);
return req;
}
diff --git a/test/style/mock_file_source.hpp b/test/fixtures/mock_file_source.hpp
index 6bee95dcf8..6bee95dcf8 100644
--- a/test/style/mock_file_source.hpp
+++ b/test/fixtures/mock_file_source.hpp
diff --git a/test/fixtures/mock_view.hpp b/test/fixtures/mock_view.hpp
index dcbe3fef84..e608545da5 100644
--- a/test/fixtures/mock_view.hpp
+++ b/test/fixtures/mock_view.hpp
@@ -3,6 +3,8 @@
#include <mbgl/map/view.hpp>
+#include <array>
+
namespace mbgl {
class MockView : public View {
@@ -10,11 +12,16 @@ public:
MockView() = default;
// View implementation.
+ float getPixelRatio() const override { return 1; }
+ std::array<uint16_t, 2> getSize() const override { return {{ 0, 0 }}; }
+ std::array<uint16_t, 2> getFramebufferSize() const override { return {{ 0, 0 }}; }
+
void activate() override {};
void deactivate() override {};
void notify() override {};
void invalidate() override {}
- void swap() override {}
+ void beforeRender() override {}
+ void afterRender() override {}
};
}
diff --git a/test/fixtures/resources/raster.png b/test/fixtures/resources/raster.png
new file mode 100644
index 0000000000..78ad885baf
--- /dev/null
+++ b/test/fixtures/resources/raster.png
Binary files differ
diff --git a/test/fixtures/resources/source_raster.json b/test/fixtures/resources/source_raster.json
new file mode 100644
index 0000000000..b114988edb
--- /dev/null
+++ b/test/fixtures/resources/source_raster.json
@@ -0,0 +1 @@
+{"attribution":"<a href=\"https://www.mapbox.com/about/maps/\" target=\"_blank\">&copy; Mapbox</a> <a href=\"http://www.openstreetmap.org/about/\" target=\"_blank\">&copy; OpenStreetMap</a> <a class=\"mapbox-improve-map\" href=\"https://www.mapbox.com/map-feedback/\" target=\"_blank\">Improve this map</a> <a href=\"https://www.digitalglobe.com/\" target=\"_blank\">&copy; DigitalGlobe</a>","autoscale":true,"bounds":[-180,-85,180,85],"center":[0,0,3],"description":"","id":"mapbox.satellite","maxzoom":19,"minzoom":0,"name":"Mapbox Satellite","private":true,"scheme":"xyz","tilejson":"2.0.0","tiles":["test/fixtures/resources/raster.png"]}
diff --git a/test/fixtures/resources/source.json b/test/fixtures/resources/source_vector.json
index db516f9f95..db516f9f95 100644
--- a/test/fixtures/resources/source.json
+++ b/test/fixtures/resources/source_vector.json
diff --git a/test/fixtures/resources/style.json b/test/fixtures/resources/style.json
index 698f3fb1e8..fc5f9c973b 100644
--- a/test/fixtures/resources/style.json
+++ b/test/fixtures/resources/style.json
@@ -1,10 +1,15 @@
{
- "version": 1,
+ "version": 8,
"name": "Test",
"sources": {
- "compositedsource": {
- "url": "test/fixtures/resources/source.json",
+ "vectorsource": {
+ "url": "test/fixtures/resources/source_vector.json",
"type": "vector"
+ },
+ "rastersource": {
+ "url": "test/fixtures/resources/source_raster.json",
+ "type": "raster",
+ "tileSize": 256
}
},
"sprite": "test/fixtures/resources/sprite",
@@ -12,19 +17,19 @@
"layers": [{
"id": "road",
"type": "symbol",
- "source": "compositedsource",
+ "source": "vectorsource",
"source-layer": "road_label",
"layout": {
- "text-font": "Open Sans Regular, Arial Unicode MS Regular",
+ "text-font": ["Open Sans Regular", "Arial Unicode MS Regular"],
"text-field": "{name_en}"
}
}, {
"id": "poi",
"type": "symbol",
- "source": "compositedsource",
+ "source": "vectorsource",
"source-layer": "poi_label",
"layout": {
- "text-font": "Open Sans Regular, Arial Unicode MS Regular",
+ "text-font": ["Open Sans Regular", "Arial Unicode MS Regular"],
"icon-image": "{maki}_icon"
}
}]
diff --git a/test/fixtures/style_parser/circle-blur.info.json b/test/fixtures/style_parser/circle-blur.info.json
new file mode 100644
index 0000000000..397e4cd4d1
--- /dev/null
+++ b/test/fixtures/style_parser/circle-blur.info.json
@@ -0,0 +1,7 @@
+{
+ "default": {
+ "log": [
+ [1, "WARNING", "ParseStyle", "value of 'circle-blur' must be a number, or a number function"]
+ ]
+ }
+}
diff --git a/test/fixtures/style_parser/circle-blur.style.json b/test/fixtures/style_parser/circle-blur.style.json
new file mode 100644
index 0000000000..8140ad5e47
--- /dev/null
+++ b/test/fixtures/style_parser/circle-blur.style.json
@@ -0,0 +1,18 @@
+{
+ "version": 8,
+ "sources": {
+ "mapbox": {
+ "type": "vector",
+ "url": "mapbox://mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5",
+ "maxzoom": 14
+ }
+ },
+ "layers": [{
+ "id": "circle_blur_example",
+ "type": "circle",
+ "source": "mapbox",
+ "paint": {
+ "circle-blur": null
+ }
+ }]
+}
diff --git a/test/fixtures/style_parser/circle-color.info.json b/test/fixtures/style_parser/circle-color.info.json
new file mode 100644
index 0000000000..b1708c2f05
--- /dev/null
+++ b/test/fixtures/style_parser/circle-color.info.json
@@ -0,0 +1,7 @@
+{
+ "default": {
+ "log": [
+ [1, "WARNING", "ParseStyle", "color value must be a string"]
+ ]
+ }
+}
diff --git a/test/fixtures/style_parser/circle-color.style.json b/test/fixtures/style_parser/circle-color.style.json
new file mode 100644
index 0000000000..44c32f99ce
--- /dev/null
+++ b/test/fixtures/style_parser/circle-color.style.json
@@ -0,0 +1,18 @@
+{
+ "version": 8,
+ "sources": {
+ "mapbox": {
+ "type": "vector",
+ "url": "mapbox://mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5",
+ "maxzoom": 14
+ }
+ },
+ "layers": [{
+ "id": "circle_color_example",
+ "type": "circle",
+ "source": "mapbox",
+ "paint": {
+ "circle-color": null
+ }
+ }]
+}
diff --git a/test/fixtures/style_parser/circle-opacity.info.json b/test/fixtures/style_parser/circle-opacity.info.json
new file mode 100644
index 0000000000..3e8662bdbe
--- /dev/null
+++ b/test/fixtures/style_parser/circle-opacity.info.json
@@ -0,0 +1,7 @@
+{
+ "default": {
+ "log": [
+ [1, "WARNING", "ParseStyle", "value of 'circle-opacity' must be a number, or a number function"]
+ ]
+ }
+}
diff --git a/test/fixtures/style_parser/circle-opacity.style.json b/test/fixtures/style_parser/circle-opacity.style.json
new file mode 100644
index 0000000000..601e81a51b
--- /dev/null
+++ b/test/fixtures/style_parser/circle-opacity.style.json
@@ -0,0 +1,18 @@
+{
+ "version": 8,
+ "sources": {
+ "mapbox": {
+ "type": "vector",
+ "url": "mapbox://mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5",
+ "maxzoom": 14
+ }
+ },
+ "layers": [{
+ "id": "circle_opacity_example",
+ "type": "circle",
+ "source": "mapbox",
+ "paint": {
+ "circle-opacity": null
+ }
+ }]
+}
diff --git a/test/fixtures/style_parser/circle-radius.info.json b/test/fixtures/style_parser/circle-radius.info.json
new file mode 100644
index 0000000000..7e87aa4fdb
--- /dev/null
+++ b/test/fixtures/style_parser/circle-radius.info.json
@@ -0,0 +1,7 @@
+{
+ "default": {
+ "log": [
+ [1, "WARNING", "ParseStyle", "value of 'circle-radius' must be a number, or a number function"]
+ ]
+ }
+}
diff --git a/test/fixtures/style_parser/circle-radius.style.json b/test/fixtures/style_parser/circle-radius.style.json
new file mode 100644
index 0000000000..a7fb28b2d3
--- /dev/null
+++ b/test/fixtures/style_parser/circle-radius.style.json
@@ -0,0 +1,18 @@
+{
+ "version": 8,
+ "sources": {
+ "mapbox": {
+ "type": "vector",
+ "url": "mapbox://mapbox.mapbox-terrain-v1,mapbox.mapbox-streets-v5",
+ "maxzoom": 14
+ }
+ },
+ "layers": [{
+ "id": "circle_radius_example",
+ "type": "circle",
+ "source": "mapbox",
+ "paint": {
+ "circle-radius": null
+ }
+ }]
+}
diff --git a/test/fixtures/style_parser/colors.style.json b/test/fixtures/style_parser/colors.style.json
index 24aa2e5d1c..8996548885 100644
--- a/test/fixtures/style_parser/colors.style.json
+++ b/test/fixtures/style_parser/colors.style.json
@@ -1,5 +1,5 @@
{
- "version": 6,
+ "version": 8,
"constants": {
"@land": "r44,239,225)",
"@snow": "f4f8foNGbjf#",
diff --git a/test/fixtures/style_parser/function-numeric.style.json b/test/fixtures/style_parser/function-numeric.style.json
index 2db5624ac9..f3fca7e1d0 100644
--- a/test/fixtures/style_parser/function-numeric.style.json
+++ b/test/fixtures/style_parser/function-numeric.style.json
@@ -1,5 +1,5 @@
{
- "version": 6,
+ "version": 8,
"sources": {
"mapbox": {
"type": "vector",
diff --git a/test/fixtures/style_parser/function-string-bool-enum.style.json b/test/fixtures/style_parser/function-string-bool-enum.style.json
index c38f195259..0447990911 100644
--- a/test/fixtures/style_parser/function-string-bool-enum.style.json
+++ b/test/fixtures/style_parser/function-string-bool-enum.style.json
@@ -1,5 +1,5 @@
{
- "version": 6,
+ "version": 8,
"sources": {
"mapbox": {
"type": "vector",
@@ -31,7 +31,7 @@
"source-layer": "waterway",
"layout": {
"text-font": {
- "stops": [[0, "Open Sans Regular"]]
+ "stops": [[0, ["Open Sans Regular"]]]
},
"text-keep-upright": {
"stops": [[0, false], [10, true]]
diff --git a/test/fixtures/style_parser/function-type.style.json b/test/fixtures/style_parser/function-type.style.json
index c992e71f04..cde8dfc76b 100644
--- a/test/fixtures/style_parser/function-type.style.json
+++ b/test/fixtures/style_parser/function-type.style.json
@@ -1,5 +1,5 @@
{
- "version": 6,
+ "version": 8,
"sources": {
"mapbox": {
"type": "vector",
diff --git a/test/fixtures/style_parser/line-opacity.style.json b/test/fixtures/style_parser/line-opacity.style.json
index 8f5221b8ad..712b2b6f50 100644
--- a/test/fixtures/style_parser/line-opacity.style.json
+++ b/test/fixtures/style_parser/line-opacity.style.json
@@ -1,5 +1,5 @@
{
- "version": 6,
+ "version": 8,
"sources": {
"mapbox": {
"type": "vector",
diff --git a/test/fixtures/style_parser/line-translate.style.json b/test/fixtures/style_parser/line-translate.style.json
index 3c079f3520..a32b2d8ee4 100644
--- a/test/fixtures/style_parser/line-translate.style.json
+++ b/test/fixtures/style_parser/line-translate.style.json
@@ -1,5 +1,5 @@
{
- "version": 6,
+ "version": 8,
"sources": {
"mapbox": {
"type": "vector",
diff --git a/test/fixtures/style_parser/line-width.style.json b/test/fixtures/style_parser/line-width.style.json
index 18653074db..e5fe6fa8e1 100644
--- a/test/fixtures/style_parser/line-width.style.json
+++ b/test/fixtures/style_parser/line-width.style.json
@@ -1,5 +1,5 @@
{
- "version": 6,
+ "version": 8,
"sources": {
"mapbox": {
"type": "vector",
diff --git a/test/fixtures/style_parser/stop-zoom-value.style.json b/test/fixtures/style_parser/stop-zoom-value.style.json
index 5f907cd8e9..520db9a904 100644
--- a/test/fixtures/style_parser/stop-zoom-value.style.json
+++ b/test/fixtures/style_parser/stop-zoom-value.style.json
@@ -1,5 +1,5 @@
{
- "version": 6,
+ "version": 8,
"sources": {
"mapbox": {
"type": "vector",
diff --git a/test/fixtures/style_parser/stops-array.style.json b/test/fixtures/style_parser/stops-array.style.json
index 107c1c064c..daa48214d9 100644
--- a/test/fixtures/style_parser/stops-array.style.json
+++ b/test/fixtures/style_parser/stops-array.style.json
@@ -1,5 +1,5 @@
{
- "version": 6,
+ "version": 8,
"sources": {
"mapbox": {
"type": "vector",
diff --git a/test/fixtures/style_parser/text-size.style.json b/test/fixtures/style_parser/text-size.style.json
index 175ce456ad..46dd33e3c4 100644
--- a/test/fixtures/style_parser/text-size.style.json
+++ b/test/fixtures/style_parser/text-size.style.json
@@ -1,5 +1,5 @@
{
- "version": 6,
+ "version": 8,
"sources": {
"mapbox": {
"type": "vector",
diff --git a/test/fixtures/tiles/streets/15-17605-10749.vector.pbf b/test/fixtures/tiles/streets/15-17605-10749.vector.pbf
new file mode 100644
index 0000000000..1f43a6c487
--- /dev/null
+++ b/test/fixtures/tiles/streets/15-17605-10749.vector.pbf
Binary files differ
diff --git a/test/fixtures/tiles/streets/15-17605-10750.vector.pbf b/test/fixtures/tiles/streets/15-17605-10750.vector.pbf
new file mode 100644
index 0000000000..1ad616a56c
--- /dev/null
+++ b/test/fixtures/tiles/streets/15-17605-10750.vector.pbf
Binary files differ
diff --git a/test/fixtures/util.cpp b/test/fixtures/util.cpp
index 068a3d849f..7527f64f91 100644
--- a/test/fixtures/util.cpp
+++ b/test/fixtures/util.cpp
@@ -2,6 +2,11 @@
#include <mbgl/platform/log.hpp>
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wshadow"
+#include <boost/crc.hpp>
+#pragma GCC diagnostic pop
+
#include <csignal>
#include <unistd.h>
@@ -57,5 +62,16 @@ void stopServer(pid_t pid) {
kill(pid, SIGTERM);
}
+// from https://gist.github.com/ArtemGr/997887
+uint64_t crc64(const char* data, size_t size) {
+ boost::crc_optimal<64, 0x04C11DB7, 0, 0, false, false> crc;
+ crc.process_bytes(data, size);
+ return crc.checksum();
+}
+
+uint64_t crc64(const std::string& str) {
+ return crc64(str.data(), str.size());
+}
+
}
}
diff --git a/test/fixtures/util.hpp b/test/fixtures/util.hpp
index dd8539c846..fbee03c2d1 100644
--- a/test/fixtures/util.hpp
+++ b/test/fixtures/util.hpp
@@ -17,6 +17,9 @@ namespace test {
pid_t startServer(const char *executable);
void stopServer(pid_t pid);
+uint64_t crc64(const char*, size_t);
+uint64_t crc64(const std::string&);
+
}
}
diff --git a/test/headless/headless.cpp b/test/headless/headless.cpp
deleted file mode 100644
index c65e9855e7..0000000000
--- a/test/headless/headless.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-#include "../fixtures/util.hpp"
-#include "../fixtures/fixture_log_observer.hpp"
-
-#include <mbgl/map/map.hpp>
-#include <mbgl/map/still_image.hpp>
-#include <mbgl/util/image.hpp>
-
-#include <mbgl/util/io.hpp>
-#include <rapidjson/document.h>
-#include <rapidjson/writer.h>
-#include <rapidjson/stringbuffer.h>
-
-#include <mbgl/platform/platform.hpp>
-#include <mbgl/platform/default/headless_view.hpp>
-#include <mbgl/platform/default/headless_display.hpp>
-#include <mbgl/storage/default_file_source.hpp>
-
-#include <dirent.h>
-
-#include <future>
-
-void rewriteLocalScheme(rapidjson::Value &value, rapidjson::Document::AllocatorType &allocator) {
- ASSERT_TRUE(value.IsString());
- auto string = std::string { value.GetString(),value.GetStringLength() };
- if (string.compare(0, 8, "local://") == 0) {
- string.replace(0, 8, "http://127.0.0.1:2900/");
- value.SetString(string.data(), string.size(), allocator);
- }
-}
-
-
-class HeadlessTest : public ::testing::TestWithParam<std::string> {
-public:
- static void SetUpTestCase() {
- const auto server = mbgl::platform::applicationRoot() + "/TEST_DATA/headless/server.js";
- pid = mbgl::test::startServer(server.c_str());
- display = std::make_shared<mbgl::HeadlessDisplay>();
- }
-
- static void TearDownTestCase() {
- display.reset();
- mbgl::test::stopServer(pid);
- }
-
-protected:
- static pid_t pid;
- static std::shared_ptr<mbgl::HeadlessDisplay> display;
-};
-
-pid_t HeadlessTest::pid = 0;
-std::shared_ptr<mbgl::HeadlessDisplay> HeadlessTest::display;
-
-TEST_P(HeadlessTest, render) {
- using namespace mbgl;
-
- const std::string& base = GetParam();
-
- std::string style = util::read_file("test/suite/tests/" + base + "/style.json");
- std::string info = util::read_file("test/suite/tests/" + base + "/info.json");
-
- // Parse style.
- rapidjson::Document styleDoc;
- styleDoc.Parse<0>((const char *const)style.c_str());
- ASSERT_FALSE(styleDoc.HasParseError());
- ASSERT_TRUE(styleDoc.IsObject());
-
- // Rewrite "local://" to "http://127.0.0.1:2900/".
- if (styleDoc.HasMember("sprite")) {
- rewriteLocalScheme(styleDoc["sprite"], styleDoc.GetAllocator());
- }
-
- if (styleDoc.HasMember("glyphs")) {
- rewriteLocalScheme(styleDoc["glyphs"], styleDoc.GetAllocator());
- }
-
- if (styleDoc.HasMember("sources")) {
- auto &sources = styleDoc["sources"];
- ASSERT_TRUE(sources.IsObject());
- for (auto source = sources.MemberBegin(), end = sources.MemberEnd(); source != end; source++) {
- if (source->value.HasMember("tiles")) {
- auto &tiles = source->value["tiles"];
- ASSERT_TRUE(tiles.IsArray());
- for (rapidjson::SizeType i = 0; i < tiles.Size(); i++) {
- rewriteLocalScheme(tiles[i], styleDoc.GetAllocator());
- }
- }
-
- if (source->value.HasMember("url") && source->value["url"].IsString()) {
- rewriteLocalScheme(source->value["url"], styleDoc.GetAllocator());
- }
- }
- }
-
- // Convert the JSON object back into a stringified version.
- rapidjson::StringBuffer buffer;
- rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
- styleDoc.Accept(writer);
- style = buffer.GetString();
-
- // Parse settings.
- rapidjson::Document infoDoc;
- infoDoc.Parse<0>((const char *const)info.c_str());
- ASSERT_FALSE(infoDoc.HasParseError());
- ASSERT_TRUE(infoDoc.IsObject());
-
- for (auto it = infoDoc.MemberBegin(), end = infoDoc.MemberEnd(); it != end; it++) {
- const std::string name {
- it->name.GetString(), it->name.GetStringLength()
- };
-
- Log::Info(Event::General, "%s %s", base.c_str(), name.c_str());
-
- const rapidjson::Value& value = it->value;
- ASSERT_TRUE(value.IsObject());
-
- if (value.HasMember("native") && !value["native"].GetBool())
- continue;
-
- if (value.HasMember("center")) ASSERT_TRUE(value["center"].IsArray());
-
- const std::string actual_image = "test/suite/tests/" + base + "/" + name + "/actual.png";
-
- const double zoom = value.HasMember("zoom") ? value["zoom"].GetDouble() : 0;
- const double bearing = value.HasMember("bearing") ? value["bearing"].GetDouble() : 0;
- const double latitude = value.HasMember("center") ? value["center"][rapidjson::SizeType(0)].GetDouble() : 0;
- const double longitude = value.HasMember("center") ? value["center"][rapidjson::SizeType(1)].GetDouble() : 0;
- const unsigned int width = value.HasMember("width") ? value["width"].GetUint() : 512;
- const unsigned int height = value.HasMember("height") ? value["height"].GetUint() : 512;
- const unsigned int pixelRatio = value.HasMember("pixelRatio") ? value["pixelRatio"].GetUint() : 1;
-
- std::vector<std::string> classes;
- if (value.HasMember("classes")) {
- const rapidjson::Value& js_classes = value["classes"];
- ASSERT_TRUE(js_classes.IsArray());
- for (rapidjson::SizeType i = 0; i < js_classes.Size(); i++) {
- const rapidjson::Value& js_class = js_classes[i];
- ASSERT_TRUE(js_class.IsString());
- classes.push_back({ js_class.GetString(), js_class.GetStringLength() });
- }
- }
-
- std::promise<void> promise;
-
- HeadlessView view(display, width, height, pixelRatio);
- DefaultFileSource fileSource(nullptr);
- Map map(view, fileSource, MapMode::Still);
-
- map.resize(width, height, pixelRatio);
- map.setClasses(classes);
- map.setStyleJSON(style, "test/suite");
- map.setLatLngZoom(mbgl::LatLng(latitude, longitude), zoom);
- map.setBearing(bearing);
-
- map.renderStill([&](std::exception_ptr, std::unique_ptr<const StillImage> image) {
- const std::string png = util::compress_png(image->width, image->height, image->pixels.get());
- util::write_file("test/suite/tests/" + base + "/" + name + "/actual.png", png);
- promise.set_value();
- });
-
- promise.get_future().get();
- }
-}
-
-INSTANTIATE_TEST_CASE_P(Headless, HeadlessTest, ::testing::ValuesIn([] {
- std::vector<std::string> names;
-
- const auto tests = mbgl::platform::applicationRoot() + "/TEST_DATA/suite/tests";
- DIR *dir = opendir(tests.c_str());
- if (dir != nullptr) {
- for (dirent *dp = nullptr; (dp = readdir(dir)) != nullptr;) {
- const std::string name = dp->d_name;
- if (name != "index.html" && !(name.size() >= 1 && name[0] == '.')) {
- names.push_back(name);
- }
- }
- closedir(dir);
- }
-
- EXPECT_GT(names.size(), 0ul);
- return names;
-}()));
diff --git a/test/headless/server.js b/test/headless/server.js
deleted file mode 100755
index ff349b050e..0000000000
--- a/test/headless/server.js
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env node
-/* jshint node: true */
-'use strict';
-
-var express = require('express');
-var app = express();
-
-app.use(express.static('test/suite'));
-
-var server = app.listen(2900, function () {
- var host = server.address().address;
- var port = server.address().port;
- console.log('Test server listening at http://%s:%s', host, port);
-
- if (process.argv[2]) {
- // Allow the test to continue running.
- process.stdin.write("Go!\n");
- }
-});
diff --git a/test/ios/KIFTestActor+MapboxGL.m b/test/ios/KIFTestActor+MapboxGL.m
index 330adfdc28..6ebd248448 100644
--- a/test/ios/KIFTestActor+MapboxGL.m
+++ b/test/ios/KIFTestActor+MapboxGL.m
@@ -1,6 +1,6 @@
#import "KIFTestActor+MapboxGL.h"
-#import "MapboxGL.h"
+#import "Mapbox.h"
#import <KIF/UIApplication-KIFAdditions.h>
diff --git a/test/ios/MGLTAppDelegate.m b/test/ios/MGLTAppDelegate.m
index 3fa68b6da1..ba49f96d22 100644
--- a/test/ios/MGLTAppDelegate.m
+++ b/test/ios/MGLTAppDelegate.m
@@ -1,6 +1,6 @@
#import "MGLTAppDelegate.h"
#import "MGLTViewController.h"
-#import "MapboxGL.h"
+#import "Mapbox.h"
@implementation MGLTAppDelegate
diff --git a/test/ios/MGLTViewController.m b/test/ios/MGLTViewController.m
index e3357616f8..01a053f50d 100644
--- a/test/ios/MGLTViewController.m
+++ b/test/ios/MGLTViewController.m
@@ -1,5 +1,5 @@
#import "MGLTViewController.h"
-#import "MapboxGL.h"
+#import "Mapbox.h"
@implementation MGLTViewController
{
diff --git a/test/ios/MapViewTests.m b/test/ios/MapViewTests.m
index 82360db231..f4ae501d7e 100644
--- a/test/ios/MapViewTests.m
+++ b/test/ios/MapViewTests.m
@@ -3,7 +3,7 @@
#import "KIFTestActor+MapboxGL.h"
-#import "MapboxGL.h"
+#import "Mapbox.h"
#import "MGLTViewController.h"
#import "LocationMocker/LocationMocker.h"
@@ -544,7 +544,7 @@
- (void)testUserTrackingModeFollow {
tester.mapView.userTrackingMode = MGLUserTrackingModeFollow;
- [tester waitForTimeInterval:1];
+ [tester acknowledgeSystemAlert];
XCTAssertEqual(tester.mapView.userLocationVisible,
YES,
@@ -570,7 +570,7 @@
- (void)testUserTrackingModeFollowWithHeading {
tester.mapView.userTrackingMode = MGLUserTrackingModeFollowWithHeading;
- [tester waitForTimeInterval:1];
+ [tester acknowledgeSystemAlert];
XCTAssertEqual(tester.mapView.userLocationVisible,
YES,
diff --git a/test/ios/MetricsTests.m b/test/ios/MetricsTests.m
index 7c71ee6739..d3b99dc63b 100644
--- a/test/ios/MetricsTests.m
+++ b/test/ios/MetricsTests.m
@@ -5,7 +5,7 @@
#import <KIF/KIF.h>
#import <OCMock/OCMock.h>
-#import "MapboxGL.h"
+#import "Mapbox.h"
#import "OHHTTPStubs.h"
const NSUInteger MGLMaximumEventsPerFlush = 20;
@@ -102,7 +102,7 @@ const NSTimeInterval MGLFlushInterval = 60;
[self pushFakeEvent];
- [self waitForExpectationsWithTimeout:1.0 handler:nil];
+ [self waitForExpectationsWithTimeout:2.0 handler:nil];
}
- (void)testTimerDestroyedAfterFlush {
@@ -119,7 +119,7 @@ const NSTimeInterval MGLFlushInterval = 60;
[[MGLMapboxEvents sharedManager] flush];
- [self waitForExpectationsWithTimeout:1.0 handler:nil];
+ [self waitForExpectationsWithTimeout:2.0 handler:nil];
XCTAssertNil([[MGLMapboxEvents sharedManager] timer]);
}
@@ -138,12 +138,12 @@ const NSTimeInterval MGLFlushInterval = 60;
[[MGLMapboxEvents sharedManager] flush];
- [self waitForExpectationsWithTimeout:1.0 handler:nil];
+ [self waitForExpectationsWithTimeout:2.0 handler:nil];
id eventsMock = [OCMockObject partialMockForObject:[MGLMapboxEvents sharedManager]];
[[[eventsMock expect] andForwardToRealObject] startTimer];
[self pushFakeEvent];
- [eventsMock verifyWithDelay:0.1];
+ [eventsMock verifyWithDelay:2.0];
XCTAssertEqual([[[MGLMapboxEvents sharedManager] eventQueue] count], 1);
XCTAssertNotNil([[MGLMapboxEvents sharedManager] timer]);
@@ -164,7 +164,7 @@ const NSTimeInterval MGLFlushInterval = 60;
[[MGLMapboxEvents sharedManager] flush];
- [self waitForExpectationsWithTimeout:1.0 handler:nil];
+ [self waitForExpectationsWithTimeout:2.0 handler:nil];
[self pushFakeEvent];
id eventsMock = [OCMockObject partialMockForObject:[MGLMapboxEvents sharedManager]];
@@ -178,7 +178,7 @@ const NSTimeInterval MGLFlushInterval = 60;
id eventsMock = [OCMockObject partialMockForObject:[MGLMapboxEvents sharedManager]];
[[eventsMock expect] postEvents:events];
[[MGLMapboxEvents sharedManager] flush];
- [eventsMock verifyWithDelay:1.0];
+ [eventsMock verifyWithDelay:2.0];
XCTAssertTrue([[[MGLMapboxEvents sharedManager] eventQueue] count] == 0);
}
@@ -209,7 +209,7 @@ const NSTimeInterval MGLFlushInterval = 60;
[self pushFakeEvent];
[MGLMapboxEvents flush];
- [self waitForExpectationsWithTimeout:1.0 handler:nil];
+ [self waitForExpectationsWithTimeout:2.0 handler:nil];
}
- (void)testPushEventAddsToEventQueue {
@@ -228,7 +228,7 @@ const NSTimeInterval MGLFlushInterval = 60;
[self pushFakeEvent];
- [self waitForExpectationsWithTimeout:1.0 handler:nil];
+ [self waitForExpectationsWithTimeout:2.0 handler:nil];
}
- (void)testOptOutUpfrontDisablesMetrics {
@@ -266,7 +266,7 @@ const NSTimeInterval MGLFlushInterval = 60;
[[MGLMapboxEvents sharedManager] flush];
- [tester waitForTimeInterval:1.0];
+ [tester waitForTimeInterval:2.0];
}
@end
diff --git a/test/ios/ios-tests.xcodeproj/project.pbxproj b/test/ios/ios-tests.xcodeproj/project.pbxproj
index 30494412e7..6408372430 100644
--- a/test/ios/ios-tests.xcodeproj/project.pbxproj
+++ b/test/ios/ios-tests.xcodeproj/project.pbxproj
@@ -17,8 +17,6 @@
DD043366196DBBE000E6F39D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = DD043365196DBBE000E6F39D /* main.m */; };
DD0580E81ACB628200B112C9 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD0580E71ACB628200B112C9 /* IOKit.framework */; };
DD0581041ACB661200B112C9 /* Headers in Resources */ = {isa = PBXBuildFile; fileRef = DD0581031ACB661200B112C9 /* Headers */; };
- DD0581061ACB661C00B112C9 /* MapboxGL.bundle in Resources */ = {isa = PBXBuildFile; fileRef = DD0581051ACB661C00B112C9 /* MapboxGL.bundle */; };
- DD0581081ACB663200B112C9 /* libMapboxGL.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD0581071ACB663200B112C9 /* libMapboxGL.a */; };
DD0E6F671B01806600DC035A /* MetricsTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DD0E6F661B01806600DC035A /* MetricsTests.m */; };
DD0E6F841B0190E200DC035A /* libOCMock.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DD0E6F701B0190E200DC035A /* libOCMock.a */; };
DD0E6F981B01B68E00DC035A /* OHHTTPStubs.m in Sources */ = {isa = PBXBuildFile; fileRef = DD0E6F8E1B01B68E00DC035A /* OHHTTPStubs.m */; };
@@ -38,6 +36,8 @@
DDBD016C196DC4740033959E /* MapViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DDBD0168196DC4740033959E /* MapViewTests.m */; };
DDBD016D196DC4740033959E /* KIFTestActor+MapboxGL.m in Sources */ = {isa = PBXBuildFile; fileRef = DDBD016A196DC4740033959E /* KIFTestActor+MapboxGL.m */; };
DDBD016E196DC4A10033959E /* libKIF.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DDBD0144196DC3AE0033959E /* libKIF.a */; };
+ DDC5C7BC1B84D62B00E1EA6B /* libMapbox.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DDC5C7BA1B84D62B00E1EA6B /* libMapbox.a */; };
+ DDC5C7BD1B84D62B00E1EA6B /* Mapbox.bundle in Resources */ = {isa = PBXBuildFile; fileRef = DDC5C7BB1B84D62B00E1EA6B /* Mapbox.bundle */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -105,8 +105,6 @@
DD0580E71ACB628200B112C9 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/Frameworks/IOKit.framework; sourceTree = DEVELOPER_DIR; };
DD0580EF1ACB62BE00B112C9 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
DD0581031ACB661200B112C9 /* Headers */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Headers; path = ../../build/ios/pkg/static/Headers; sourceTree = SOURCE_ROOT; };
- DD0581051ACB661C00B112C9 /* MapboxGL.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = MapboxGL.bundle; path = ../../build/ios/pkg/static/MapboxGL.bundle; sourceTree = SOURCE_ROOT; };
- DD0581071ACB663200B112C9 /* libMapboxGL.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libMapboxGL.a; path = ../../build/ios/pkg/static/libMapboxGL.a; sourceTree = SOURCE_ROOT; };
DD0E6F661B01806600DC035A /* MetricsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MetricsTests.m; sourceTree = SOURCE_ROOT; };
DD0E6F701B0190E200DC035A /* libOCMock.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libOCMock.a; path = OCMock/libOCMock.a; sourceTree = SOURCE_ROOT; };
DD0E6F721B0190E200DC035A /* NSNotificationCenter+OCMAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSNotificationCenter+OCMAdditions.h"; sourceTree = "<group>"; };
@@ -144,6 +142,8 @@
DDBD0168196DC4740033959E /* MapViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MapViewTests.m; sourceTree = SOURCE_ROOT; };
DDBD016A196DC4740033959E /* KIFTestActor+MapboxGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "KIFTestActor+MapboxGL.m"; sourceTree = SOURCE_ROOT; };
DDBD016B196DC4740033959E /* KIFTestActor+MapboxGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "KIFTestActor+MapboxGL.h"; sourceTree = SOURCE_ROOT; };
+ DDC5C7BA1B84D62B00E1EA6B /* libMapbox.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libMapbox.a; path = ../../../build/ios/pkg/static/libMapbox.a; sourceTree = "<group>"; };
+ DDC5C7BB1B84D62B00E1EA6B /* Mapbox.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; name = Mapbox.bundle; path = ../../../build/ios/pkg/static/Mapbox.bundle; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -155,8 +155,8 @@
DD41CE171ACB5DE700FA7979 /* GLKit.framework in Frameworks */,
DD41CE151ACB5DE000FA7979 /* ImageIO.framework in Frameworks */,
DD41CE131ACB5DDA00FA7979 /* MobileCoreServices.framework in Frameworks */,
+ DDC5C7BC1B84D62B00E1EA6B /* libMapbox.a in Frameworks */,
DD41CE0B1ACB5DC400FA7979 /* SystemConfiguration.framework in Frameworks */,
- DD0581081ACB663200B112C9 /* libMapboxGL.a in Frameworks */,
DD41CE0D1ACB5DCB00FA7979 /* libc++.dylib in Frameworks */,
DD41CE0F1ACB5DD000FA7979 /* libsqlite3.dylib in Frameworks */,
DD41CE111ACB5DD500FA7979 /* libz.dylib in Frameworks */,
@@ -300,8 +300,8 @@
children = (
DD0581031ACB661200B112C9 /* Headers */,
DACAD7111B08719F009119DC /* MGLMapboxEvents.h */,
- DD0581071ACB663200B112C9 /* libMapboxGL.a */,
- DD0581051ACB661C00B112C9 /* MapboxGL.bundle */,
+ DDC5C7BA1B84D62B00E1EA6B /* libMapbox.a */,
+ DDC5C7BB1B84D62B00E1EA6B /* Mapbox.bundle */,
);
name = "GL Library";
sourceTree = "<group>";
@@ -474,7 +474,7 @@
files = (
96567A311B0E8BB900D78776 /* Images.xcassets in Resources */,
DD0581041ACB661200B112C9 /* Headers in Resources */,
- DD0581061ACB661C00B112C9 /* MapboxGL.bundle in Resources */,
+ DDC5C7BD1B84D62B00E1EA6B /* Mapbox.bundle in Resources */,
96567A231B0E84CD00D78776 /* LaunchScreen.xib in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
diff --git a/test/ios/ios-tests.xcodeproj/xcshareddata/xcschemes/Mapbox GL Tests.xcscheme b/test/ios/ios-tests.xcodeproj/xcshareddata/xcschemes/Mapbox GL Tests.xcscheme
index f7173ee644..2737f5185f 100644
--- a/test/ios/ios-tests.xcodeproj/xcshareddata/xcschemes/Mapbox GL Tests.xcscheme
+++ b/test/ios/ios-tests.xcodeproj/xcshareddata/xcschemes/Mapbox GL Tests.xcscheme
@@ -37,10 +37,10 @@
</BuildActionEntries>
</BuildAction>
<TestAction
+ buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
- shouldUseLaunchSchemeArgsEnv = "YES"
- buildConfiguration = "Release">
+ shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
@@ -59,6 +59,9 @@
Identifier = "MapViewTests/testUserTrackingModeFollowWithHeading">
</Test>
<Test
+ Identifier = "MetricsTests">
+ </Test>
+ <Test
Identifier = "MetricsTests/testFlushPostsEvents">
</Test>
<Test
@@ -79,15 +82,18 @@
ReferencedContainer = "container:ios-tests.xcodeproj">
</BuildableReference>
</MacroExpansion>
+ <AdditionalOptions>
+ </AdditionalOptions>
</TestAction>
<LaunchAction
+ buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
- buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
+ debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
@@ -103,10 +109,10 @@
</AdditionalOptions>
</LaunchAction>
<ProfileAction
+ buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
- buildConfiguration = "Release"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
diff --git a/test/miscellaneous/custom_sprites.cpp b/test/miscellaneous/custom_sprites.cpp
new file mode 100644
index 0000000000..a72119ea61
--- /dev/null
+++ b/test/miscellaneous/custom_sprites.cpp
@@ -0,0 +1,61 @@
+#include "../fixtures/util.hpp"
+#include "../fixtures/fixture_log_observer.hpp"
+
+#include <mbgl/map/map.hpp>
+#include <mbgl/map/still_image.hpp>
+#include <mbgl/util/image.hpp>
+#include <mbgl/annotation/sprite_image.hpp>
+
+#include <mbgl/util/io.hpp>
+
+#include <mbgl/platform/default/headless_view.hpp>
+#include <mbgl/platform/default/headless_display.hpp>
+#include <mbgl/storage/default_file_source.hpp>
+
+#include <future>
+
+using namespace mbgl;
+
+TEST(Headless, CustomSpriteImages) {
+ FixtureLog log;
+
+ auto display = std::make_shared<mbgl::HeadlessDisplay>();
+ HeadlessView view(display, 1);
+ view.resize(256, 256);
+ DefaultFileSource fileSource(nullptr);
+
+ const auto style = util::read_file("test/fixtures/headless/pois.json");
+
+ Map map(view, fileSource, MapMode::Still);
+
+ map.setLatLngZoom(LatLng{ 52.499167, 13.418056 }, 15);
+
+ map.setStyleJSON(style, "");
+ map.setSprite("cafe",
+ std::make_shared<SpriteImage>(12, 12, 1, std::string(12 * 12 * 4, '\xFF')));
+ std::promise<std::unique_ptr<const StillImage>> promise;
+ map.renderStill([&promise](std::exception_ptr error, std::unique_ptr<const StillImage> image) {
+ if (error) {
+ promise.set_exception(error);
+ } else {
+ promise.set_value(std::move(image));
+ }
+ });
+ auto result = promise.get_future().get();
+ ASSERT_EQ(256, result->width);
+ ASSERT_EQ(256, result->height);
+
+ EXPECT_EQ(
+ 21u,
+ log.count({
+ EventSeverity::Info, Event::Sprite, int64_t(-1), "Can't find sprite named 'bakery'",
+ }));
+
+ // const size_t bytes = result->width * result->height * 4;
+ // const auto hash = test::crc64(reinterpret_cast<const char*>(result->pixels.get()), bytes);
+ // EXPECT_EQ(0xC40A4BCD76AEC564u, hash) << std::hex << hash;
+
+ // const std::string png = util::compress_png(result->width, result->height,
+ // result->pixels.get());
+ // util::write_file("test/fixtures/headless/1.actual.png", png);
+}
diff --git a/test/miscellaneous/map.cpp b/test/miscellaneous/map.cpp
index b8707f3902..fdd33c1466 100644
--- a/test/miscellaneous/map.cpp
+++ b/test/miscellaneous/map.cpp
@@ -11,7 +11,7 @@ TEST(Map, PauseResume) {
using namespace mbgl;
auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display);
+ HeadlessView view(display, 1);
DefaultFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Continuous);
@@ -24,7 +24,7 @@ TEST(Map, DoublePause) {
using namespace mbgl;
auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display);
+ HeadlessView view(display, 1);
DefaultFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Continuous);
@@ -38,7 +38,7 @@ TEST(Map, ResumeWithoutPause) {
using namespace mbgl;
auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display);
+ HeadlessView view(display, 1);
DefaultFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Continuous);
@@ -50,7 +50,7 @@ TEST(Map, DestroyPaused) {
using namespace mbgl;
auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display);
+ HeadlessView view(display, 1);
DefaultFileSource fileSource(nullptr);
Map map(view, fileSource, MapMode::Continuous);
diff --git a/test/miscellaneous/map_context.cpp b/test/miscellaneous/map_context.cpp
index f1f26a9c47..ec88862f05 100644
--- a/test/miscellaneous/map_context.cpp
+++ b/test/miscellaneous/map_context.cpp
@@ -11,9 +11,9 @@ using namespace mbgl;
TEST(MapContext, DoubleStyleLoad) {
std::shared_ptr<HeadlessDisplay> display = std::make_shared<HeadlessDisplay>();
- HeadlessView view(display, 512, 512, 1);
+ HeadlessView view(display, 1, 512, 512);
DefaultFileSource fileSource(nullptr);
- MapData data(MapMode::Continuous);
+ MapData data(MapMode::Continuous, view.getPixelRatio());
util::Thread<MapContext> context({"Map", util::ThreadType::Map, util::ThreadPriority::Regular}, view, fileSource, data);
diff --git a/test/miscellaneous/mapbox.cpp b/test/miscellaneous/mapbox.cpp
index 1aff2494a4..a0f9208298 100644
--- a/test/miscellaneous/mapbox.cpp
+++ b/test/miscellaneous/mapbox.cpp
@@ -8,21 +8,30 @@
using namespace mbgl;
TEST(Mapbox, SourceURL) {
- EXPECT_EQ(mbgl::util::mapbox::normalizeSourceURL("mapbox://user.map", "key"), "https://api.tiles.mapbox.com/v4/user.map.json?access_token=key&secure");
- EXPECT_EQ(mbgl::util::mapbox::normalizeSourceURL("mapbox://user.map", "token"), "https://api.tiles.mapbox.com/v4/user.map.json?access_token=token&secure");
+ EXPECT_EQ(mbgl::util::mapbox::normalizeSourceURL("mapbox://user.map", "key"), "https://api.mapbox.com/v4/user.map.json?access_token=key&secure");
+ EXPECT_EQ(mbgl::util::mapbox::normalizeSourceURL("mapbox://user.map", "token"), "https://api.mapbox.com/v4/user.map.json?access_token=token&secure");
EXPECT_THROW(mbgl::util::mapbox::normalizeSourceURL("mapbox://user.map", ""), std::runtime_error);
}
TEST(Mapbox, GlyphsURL) {
- EXPECT_EQ(mbgl::util::mapbox::normalizeGlyphsURL("mapbox://fontstack/{fontstack}/{range}.pbf", "key"), "https://api.tiles.mapbox.com/v4/fontstack/{fontstack}/{range}.pbf?access_token=key");
+ EXPECT_EQ(mbgl::util::mapbox::normalizeGlyphsURL("mapbox://fonts/boxmap/Comic%20Sans/0-255.pbf", "key"), "https://api.mapbox.com/fonts/v1/boxmap/Comic%20Sans/0-255.pbf?access_token=key");
+ EXPECT_EQ(mbgl::util::mapbox::normalizeGlyphsURL("mapbox://fonts/boxmap/{fontstack}/{range}.pbf", "key"), "https://api.mapbox.com/fonts/v1/boxmap/{fontstack}/{range}.pbf?access_token=key");
EXPECT_EQ(mbgl::util::mapbox::normalizeGlyphsURL("http://path", "key"), "http://path");
}
TEST(Mapbox, StyleURL) {
- EXPECT_EQ(mbgl::util::mapbox::normalizeStyleURL("mapbox://user.style", "key"), "https://api.tiles.mapbox.com/styles/v1/user/user.style?access_token=key");
+ EXPECT_EQ(mbgl::util::mapbox::normalizeStyleURL("mapbox://styles/user/style", "key"), "https://api.mapbox.com/styles/v1/user/style?access_token=key");
+ EXPECT_EQ(mbgl::util::mapbox::normalizeStyleURL("mapbox://styles/user/style/draft", "key"), "https://api.mapbox.com/styles/v1/user/style/draft?access_token=key");
EXPECT_EQ(mbgl::util::mapbox::normalizeStyleURL("http://path", "key"), "http://path");
}
+TEST(Mapbox, SpriteURL) {
+ EXPECT_EQ(mbgl::util::mapbox::normalizeSpriteURL("map/box/sprites@2x.json", "key"), "map/box/sprites@2x.json");
+ EXPECT_EQ(mbgl::util::mapbox::normalizeSpriteURL("mapbox://sprites/mapbox/streets-v8.json", "key"), "https://api.mapbox.com/styles/v1/mapbox/streets-v8/sprite.json?access_token=key");
+ EXPECT_EQ(mbgl::util::mapbox::normalizeSpriteURL("mapbox://sprites/mapbox/streets-v8@2x.png", "key"), "https://api.mapbox.com/styles/v1/mapbox/streets-v8/sprite@2x.png?access_token=key");
+ EXPECT_EQ(mbgl::util::mapbox::normalizeSpriteURL("mapbox://sprites/mapbox/streets-v8/draft@2x.png", "key"), "https://api.mapbox.com/styles/v1/mapbox/streets-v8/draft/sprite@2x.png?access_token=key");
+}
+
TEST(Mapbox, TileURL) {
try {
EXPECT_EQ(mbgl::util::mapbox::normalizeTileURL("http://path.png/tile.png", "mapbox://user.map", SourceType::Raster), "http://path.png/tile{ratio}.png");
diff --git a/test/miscellaneous/style_parser.cpp b/test/miscellaneous/style_parser.cpp
index 7a38ba054d..e88d798411 100644
--- a/test/miscellaneous/style_parser.cpp
+++ b/test/miscellaneous/style_parser.cpp
@@ -3,6 +3,9 @@
#include <mbgl/style/style_parser.hpp>
#include <mbgl/util/io.hpp>
+#include <mbgl/map/mode.hpp>
+#include <mbgl/map/map_data.hpp>
+
#include <rapidjson/document.h>
#include "../fixtures/fixture_log_observer.hpp"
@@ -35,7 +38,11 @@ TEST_P(StyleParserTest, ParseStyle) {
FixtureLogObserver* observer = new FixtureLogObserver();
Log::setObserver(std::unique_ptr<Log::Observer>(observer));
- StyleParser parser;
+ MapMode mapMode = MapMode::Continuous;
+ const float pixelRatio = 1.0f;
+
+ MapData data(mapMode, pixelRatio);
+ StyleParser parser(data);
parser.parse(styleDoc);
for (auto it = infoDoc.MemberBegin(), end = infoDoc.MemberEnd(); it != end; it++) {
diff --git a/test/miscellaneous/thread.cpp b/test/miscellaneous/thread.cpp
index f8d91bf97f..9d8f6b6327 100644
--- a/test/miscellaneous/thread.cpp
+++ b/test/miscellaneous/thread.cpp
@@ -7,7 +7,7 @@ using namespace mbgl::util;
class TestObject {
public:
- TestObject(uv_loop_t*, std::thread::id otherTid)
+ TestObject(std::thread::id otherTid)
: tid(std::this_thread::get_id()) {
EXPECT_NE(tid, otherTid);
}
@@ -17,9 +17,9 @@ public:
EXPECT_EQ(val, 1);
}
- int fn2() {
+ void fn2(std::function<void (int)> cb) {
EXPECT_EQ(tid, std::this_thread::get_id());
- return 1;
+ cb(1);
}
void transferIn(std::unique_ptr<int> val) {
@@ -27,15 +27,15 @@ public:
EXPECT_EQ(*val, 1);
}
- std::unique_ptr<int> transferOut() {
+ void transferOut(std::function<void (std::unique_ptr<int>)> cb) {
EXPECT_EQ(tid, std::this_thread::get_id());
- return std::make_unique<int>(1);
+ cb(std::make_unique<int>(1));
}
- std::unique_ptr<int> transferInOut(std::unique_ptr<int> val) {
+ void transferInOut(std::unique_ptr<int> val, std::function<void (std::unique_ptr<int>)> cb) {
EXPECT_EQ(tid, std::this_thread::get_id());
EXPECT_EQ(*val, 1);
- return std::move(val);
+ cb(std::move(val));
}
void transferInShared(std::shared_ptr<int> val) {
@@ -43,21 +43,21 @@ public:
EXPECT_EQ(*val, 1);
}
- std::shared_ptr<int> transferOutShared() {
+ void transferOutShared(std::function<void (std::shared_ptr<int>)> cb) {
EXPECT_EQ(tid, std::this_thread::get_id());
- return std::make_shared<int>(1);
+ cb(std::make_shared<int>(1));
}
- std::string transferString(const std::string& string) {
+ void transferString(const std::string& string, std::function<void (std::string)> cb) {
EXPECT_EQ(tid, std::this_thread::get_id());
EXPECT_EQ(string, "test");
- return string;
+ cb(string);
}
- bool checkContext() const {
- return ThreadContext::currentlyOn(ThreadType::Worker)
+ void checkContext(std::function<void (bool)> cb) const {
+ cb(ThreadContext::currentlyOn(ThreadType::Worker)
&& ThreadContext::getName() == "Test"
- && ThreadContext::getPriority() == ThreadPriority::Low;
+ && ThreadContext::getPriority() == ThreadPriority::Low);
}
const std::thread::id tid;
@@ -67,40 +67,46 @@ TEST(Thread, invoke) {
const std::thread::id tid = std::this_thread::get_id();
RunLoop loop(uv_default_loop());
+ std::vector<std::unique_ptr<mbgl::WorkRequest>> requests;
loop.invoke([&] {
EXPECT_EQ(tid, std::this_thread::get_id());
Thread<TestObject> thread({"Test", ThreadType::Map, ThreadPriority::Regular}, tid);
thread.invoke(&TestObject::fn1, 1);
- thread.invokeWithResult<int>(&TestObject::fn2, [&] (int result) {
+ requests.push_back(thread.invokeWithCallback(&TestObject::fn2, [&] (int result) {
EXPECT_EQ(tid, std::this_thread::get_id());
EXPECT_EQ(result, 1);
- });
+ }));
thread.invoke(&TestObject::transferIn, std::make_unique<int>(1));
- thread.invokeWithResult<std::unique_ptr<int>>(&TestObject::transferOut, [&] (std::unique_ptr<int> result) {
+ requests.push_back(thread.invokeWithCallback(&TestObject::transferOut, [&] (std::unique_ptr<int> result) {
EXPECT_EQ(tid, std::this_thread::get_id());
EXPECT_EQ(*result, 1);
- });
+ }));
- thread.invokeWithResult<std::unique_ptr<int>>(&TestObject::transferInOut, [&] (std::unique_ptr<int> result) {
+ requests.push_back(thread.invokeWithCallback(&TestObject::transferInOut, [&] (std::unique_ptr<int> result) {
EXPECT_EQ(tid, std::this_thread::get_id());
EXPECT_EQ(*result, 1);
- }, std::make_unique<int>(1));
+ }, std::make_unique<int>(1)));
thread.invoke(&TestObject::transferInShared, std::make_shared<int>(1));
- thread.invokeWithResult<std::shared_ptr<int>>(&TestObject::transferOutShared, [&] (std::shared_ptr<int> result) {
+ requests.push_back(thread.invokeWithCallback(&TestObject::transferOutShared, [&] (std::shared_ptr<int> result) {
EXPECT_EQ(tid, std::this_thread::get_id());
EXPECT_EQ(*result, 1);
+ }));
+
+ // Cancelled request
+ thread.invokeWithCallback(&TestObject::fn2, [&] (int) {
+ ADD_FAILURE();
});
std::string test("test");
- thread.invokeWithResult<std::string>(&TestObject::transferString, [&] (std::string result){
+ requests.push_back(thread.invokeWithCallback(&TestObject::transferString, [&] (std::string result){
EXPECT_EQ(tid, std::this_thread::get_id());
EXPECT_EQ(result, "test");
loop.stop();
- }, test);
+ }, test));
test.clear();
});
@@ -117,15 +123,103 @@ TEST(Thread, context) {
const std::thread::id tid = std::this_thread::get_id();
RunLoop loop(uv_default_loop());
+ std::vector<std::unique_ptr<mbgl::WorkRequest>> requests;
loop.invoke([&] {
Thread<TestObject> thread({"Test", ThreadType::Worker, ThreadPriority::Low}, tid);
- thread.invokeWithResult<bool>(&TestObject::checkContext, [&] (bool inTestThreadContext) {
+ requests.push_back(thread.invokeWithCallback(&TestObject::checkContext, [&] (bool inTestThreadContext) {
EXPECT_EQ(inTestThreadContext, true);
loop.stop();
- });
+ }));
});
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
}
+
+class TestWorker {
+public:
+ TestWorker() = default;
+
+ void send(std::function<void ()> fn, std::function<void ()> cb) {
+ fn();
+ cb();
+ }
+};
+
+TEST(Thread, ExecutesAfter) {
+ RunLoop loop(uv_default_loop());
+ Thread<TestWorker> thread({"Test", ThreadType::Map, ThreadPriority::Regular});
+
+ bool didWork = false;
+ bool didAfter = false;
+
+ auto request = thread.invokeWithCallback(&TestWorker::send, [&] {
+ didAfter = true;
+ loop.stop();
+ }, [&] {
+ didWork = true;
+ });
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+
+ EXPECT_TRUE(didWork);
+ EXPECT_TRUE(didAfter);
+}
+
+TEST(Thread, WorkRequestDeletionWaitsForWorkToComplete) {
+ RunLoop loop(uv_default_loop());
+ Thread<TestWorker> thread({"Test", ThreadType::Map, ThreadPriority::Regular});
+
+ std::promise<void> started;
+ bool didWork = false;
+
+ auto request = thread.invokeWithCallback(&TestWorker::send, [&] {}, [&] {
+ started.set_value();
+ usleep(10000);
+ didWork = true;
+ });
+
+ started.get_future().get();
+ request.reset();
+ EXPECT_TRUE(didWork);
+}
+
+TEST(Thread, WorkRequestDeletionCancelsAfter) {
+ RunLoop loop(uv_default_loop());
+ Thread<TestWorker> thread({"Test", ThreadType::Map, ThreadPriority::Regular});
+
+ std::promise<void> started;
+ bool didAfter = false;
+
+ auto request = thread.invokeWithCallback(&TestWorker::send, [&] {
+ didAfter = true;
+ }, [&] {
+ started.set_value();
+ });
+
+ started.get_future().get();
+ request.reset();
+ uv_run(uv_default_loop(), UV_RUN_ONCE);
+ EXPECT_FALSE(didAfter);
+}
+
+TEST(Thread, WorkRequestDeletionCancelsImmediately) {
+ RunLoop loop(uv_default_loop());
+ Thread<TestWorker> thread({"Test", ThreadType::Map, ThreadPriority::Regular});
+
+ std::promise<void> started;
+
+ auto request1 = thread.invokeWithCallback(&TestWorker::send, [&] {}, [&] {
+ usleep(10000);
+ started.set_value();
+ });
+
+ auto request2 = thread.invokeWithCallback(&TestWorker::send, [&] {}, [&] {
+ ADD_FAILURE() << "Second work item should not be invoked";
+ });
+ request2.reset();
+
+ started.get_future().get();
+ request1.reset();
+}
diff --git a/test/miscellaneous/transform.cpp b/test/miscellaneous/transform.cpp
index 5d00bfd20b..426e9e534d 100644
--- a/test/miscellaneous/transform.cpp
+++ b/test/miscellaneous/transform.cpp
@@ -105,3 +105,35 @@ TEST(Transform, InvalidBearing) {
ASSERT_DOUBLE_EQ(2, transform.getScale());
ASSERT_DOUBLE_EQ(2, transform.getAngle());
}
+
+TEST(Transform, PerspectiveProjection) {
+ MockView view;
+ Transform transform(view);
+
+ transform.resize({{ 1000, 1000 }});
+ transform.setScale(1024);
+ transform.setPitch(0.9);
+ transform.setLatLng(LatLng(38, -77));
+
+ // expected values are from mapbox-gl-js
+
+ LatLng loc = transform.getState().pointToLatLng({ 500, 500 });
+ ASSERT_NEAR(-77, loc.longitude, 0.0001);
+ ASSERT_NEAR(38, loc.latitude, 0.0001);
+
+ loc = transform.getState().pointToLatLng({ 0, 1000 });
+ ASSERT_NEAR(-77.59198961199148, loc.longitude, 0.0002);
+ ASSERT_NEAR(38.74661326302018, loc.latitude, 0.0001);
+
+ loc = transform.getState().pointToLatLng({ 1000, 0 });
+ ASSERT_NEAR(-76.75823239205641, loc.longitude, 0.0001);
+ ASSERT_NEAR(37.692872969426375, loc.latitude, 0.0001);
+
+ vec2<double> point = transform.getState().latLngToPoint({38.74661326302018, -77.59198961199148});
+ ASSERT_NEAR(point.x, 0, 0.01);
+ ASSERT_NEAR(point.y, 1000, 0.01);
+
+ point = transform.getState().latLngToPoint({37.692872969426375, -76.75823239205641});
+ ASSERT_NEAR(point.x, 1000, 0.02);
+ ASSERT_NEAR(point.y, 0, 0.02);
+}
diff --git a/test/miscellaneous/work_queue.cpp b/test/miscellaneous/work_queue.cpp
new file mode 100644
index 0000000000..a5f616fe5b
--- /dev/null
+++ b/test/miscellaneous/work_queue.cpp
@@ -0,0 +1,63 @@
+#include "../fixtures/util.hpp"
+
+#include <mbgl/util/run_loop.hpp>
+#include <mbgl/util/thread.hpp>
+#include <mbgl/util/work_queue.hpp>
+
+#include <thread>
+
+using namespace mbgl::util;
+
+class TestThread {
+public:
+ TestThread(WorkQueue* queue_) : queue(queue_) {}
+
+ void send(std::function<void()>&& fn) {
+ EXPECT_TRUE(ThreadContext::currentlyOn(ThreadType::Map));
+
+ queue->push(std::move(fn));
+ }
+
+private:
+ WorkQueue* queue;
+};
+
+TEST(WorkQueue, push) {
+ RunLoop loop(uv_default_loop());
+
+ WorkQueue queue;
+ Thread<TestThread> thread({"Test", ThreadType::Map, ThreadPriority::Regular}, &queue);
+
+ uint8_t count = 0;
+
+ auto endTest = [&]() {
+ EXPECT_TRUE(ThreadContext::currentlyOn(ThreadType::Main));
+
+ if (++count == 4) {
+ loop.stop();
+ }
+ };
+
+ thread.invoke(&TestThread::send, endTest);
+ thread.invoke(&TestThread::send, endTest);
+ thread.invoke(&TestThread::send, endTest);
+ thread.invoke(&TestThread::send, endTest);
+
+ uv_run(uv_default_loop(), UV_RUN_DEFAULT);
+}
+
+TEST(WorkQueue, cancel) {
+ RunLoop loop(uv_default_loop());
+
+ WorkQueue queue;
+
+ auto work = [&]() {
+ FAIL() << "Should never be called";
+ };
+
+ queue.push(work);
+ queue.push(work);
+ queue.push(work);
+ queue.push(work);
+ queue.push(work);
+}
diff --git a/test/miscellaneous/worker.cpp b/test/miscellaneous/worker.cpp
deleted file mode 100644
index 3d3c781b8c..0000000000
--- a/test/miscellaneous/worker.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-#include "../fixtures/util.hpp"
-
-#include <mbgl/util/worker.hpp>
-#include <mbgl/util/work_request.hpp>
-#include <mbgl/util/run_loop.hpp>
-
-using namespace mbgl;
-using namespace mbgl::util;
-
-TEST(Worker, ExecutesWorkAndAfter) {
- RunLoop loop(uv_default_loop());
-
- Worker worker(1);
- std::unique_ptr<WorkRequest> request;
-
- bool didWork = false;
- bool didAfter = false;
-
- loop.invoke([&] {
- request = worker.send([&] {
- didWork = true;
- }, [&] {
- didAfter = true;
- loop.stop();
- });
- });
-
- uv_run(uv_default_loop(), UV_RUN_DEFAULT);
- EXPECT_TRUE(didWork);
- EXPECT_TRUE(didAfter);
-}
-
-TEST(Worker, WorkRequestDeletionWaitsForWorkToComplete) {
- RunLoop loop(uv_default_loop());
-
- Worker worker(1);
- std::promise<void> started;
- bool didWork = false;
-
- loop.invoke([&] {
- auto request = worker.send([&] {
- started.set_value();
- usleep(10000);
- didWork = true;
- }, [&] {});
- started.get_future().get();
-
- request.reset();
- EXPECT_TRUE(didWork);
- loop.stop();
- });
-
- uv_run(uv_default_loop(), UV_RUN_DEFAULT);
-}
-
-TEST(Worker, WorkRequestJoinCancelsAfter) {
- RunLoop loop(uv_default_loop());
-
- Worker worker(1);
- std::promise<void> started;
- bool didAfter = false;
-
- loop.invoke([&] {
- auto request = worker.send([&] {
- started.set_value();
- }, [&] {
- didAfter = true;
- });
- started.get_future().get();
-
- request.reset();
- loop.stop();
- });
-
- uv_run(uv_default_loop(), UV_RUN_DEFAULT);
- EXPECT_FALSE(didAfter);
-}
-
-TEST(Worker, WorkRequestCancelsImmediately) {
- RunLoop loop(uv_default_loop());
-
- Worker worker(1);
-
- loop.invoke([&] {
- std::promise<void> started;
- // First worker item.
- auto request1 = worker.send([&] {
- usleep(10000);
- started.set_value();
- }, [&] {});
-
- auto request2 = worker.send([&] {
- ADD_FAILURE() << "Second work item should not be invoked";
- }, [&] {});
- request2.reset();
-
- started.get_future().get();
- request1.reset();
-
- loop.stop();
- });
-
- uv_run(uv_default_loop(), UV_RUN_DEFAULT);
-}
diff --git a/test/storage/database.cpp b/test/storage/database.cpp
index b54b69a133..b40474c004 100644
--- a/test/storage/database.cpp
+++ b/test/storage/database.cpp
@@ -13,10 +13,11 @@ TEST_F(Storage, DatabaseDoesNotExist) {
Log::setObserver(std::make_unique<FixtureLogObserver>());
- SQLiteCache::Impl cache(nullptr, "test/fixtures/404/cache.db");
+ SQLiteCache::Impl cache("test/fixtures/404/cache.db");
- std::unique_ptr<Response> res = cache.get({ Resource::Unknown, "mapbox://test" });
- EXPECT_EQ(nullptr, res.get());
+ cache.get({ Resource::Unknown, "mapbox://test" }, [] (std::unique_ptr<Response> res) {
+ EXPECT_EQ(nullptr, res.get());
+ });
auto observer = Log::removeObserver();
EXPECT_EQ(1ul, dynamic_cast<FixtureLogObserver*>(observer.get())->count({ EventSeverity::Error, Event::Database, 14, "unable to open database file" }));
@@ -54,10 +55,11 @@ TEST_F(Storage, DatabaseCreate) {
Log::setObserver(std::make_unique<FixtureLogObserver>());
- SQLiteCache::Impl cache(nullptr, "test/fixtures/database/cache.db");
+ SQLiteCache::Impl cache("test/fixtures/database/cache.db");
- std::unique_ptr<Response> res = cache.get({ Resource::Unknown, "mapbox://test" });
- EXPECT_EQ(nullptr, res.get());
+ cache.get({ Resource::Unknown, "mapbox://test" }, [] (std::unique_ptr<Response> res) {
+ EXPECT_EQ(nullptr, res.get());
+ });
Log::removeObserver();
}
@@ -109,14 +111,15 @@ TEST_F(Storage, DatabaseLockedRead) {
deleteFile("test/fixtures/database/locked.db");
FileLock guard("test/fixtures/database/locked.db");
- SQLiteCache::Impl cache(nullptr, "test/fixtures/database/locked.db");
+ SQLiteCache::Impl cache("test/fixtures/database/locked.db");
{
// First request should fail.
Log::setObserver(std::make_unique<FixtureLogObserver>());
- std::unique_ptr<Response> res = cache.get({ Resource::Unknown, "mapbox://test" });
- EXPECT_EQ(nullptr, res.get());
+ cache.get({ Resource::Unknown, "mapbox://test" }, [] (std::unique_ptr<Response> res) {
+ EXPECT_EQ(nullptr, res.get());
+ });
// Make sure that we got a few "database locked" errors
auto observer = Log::removeObserver();
@@ -131,8 +134,9 @@ TEST_F(Storage, DatabaseLockedRead) {
// First, try getting a file (the cache value should not exist).
Log::setObserver(std::make_unique<FixtureLogObserver>());
- std::unique_ptr<Response> res = cache.get({ Resource::Unknown, "mapbox://test" });
- EXPECT_EQ(nullptr, res.get());
+ cache.get({ Resource::Unknown, "mapbox://test" }, [] (std::unique_ptr<Response> res) {
+ EXPECT_EQ(nullptr, res.get());
+ });
// Make sure that we got a no errors
Log::removeObserver();
@@ -149,7 +153,7 @@ TEST_F(Storage, DatabaseLockedWrite) {
deleteFile("test/fixtures/database/locked.db");
FileLock guard("test/fixtures/database/locked.db");
- SQLiteCache::Impl cache(nullptr, "test/fixtures/database/locked.db");
+ SQLiteCache::Impl cache("test/fixtures/database/locked.db");
{
// Adds a file (which should fail).
@@ -157,8 +161,9 @@ TEST_F(Storage, DatabaseLockedWrite) {
auto response = std::make_shared<Response>();
cache.put({ Resource::Unknown, "mapbox://test" }, response);
- std::unique_ptr<Response> res = cache.get({ Resource::Unknown, "mapbox://test" });
- EXPECT_EQ(nullptr, res.get());
+ cache.get({ Resource::Unknown, "mapbox://test" }, [] (std::unique_ptr<Response> res) {
+ EXPECT_EQ(nullptr, res.get());
+ });
auto observer = Log::removeObserver();
auto flo = dynamic_cast<FixtureLogObserver*>(observer.get());
@@ -175,9 +180,10 @@ TEST_F(Storage, DatabaseLockedWrite) {
auto response = std::make_shared<Response>();
response->data = "Demo";
cache.put({ Resource::Unknown, "mapbox://test" }, response);
- std::unique_ptr<Response> res = cache.get({ Resource::Unknown, "mapbox://test" });
- EXPECT_NE(nullptr, res.get());
- EXPECT_EQ("Demo", res->data);
+ cache.get({ Resource::Unknown, "mapbox://test" }, [] (std::unique_ptr<Response> res) {
+ EXPECT_NE(nullptr, res.get());
+ EXPECT_EQ("Demo", res->data);
+ });
// Make sure that we got a no errors
Log::removeObserver();
@@ -194,7 +200,7 @@ TEST_F(Storage, DatabaseLockedRefresh) {
createDir("test/fixtures/database");
deleteFile("test/fixtures/database/locked.db");
- SQLiteCache::Impl cache(nullptr, "test/fixtures/database/locked.db");
+ SQLiteCache::Impl cache("test/fixtures/database/locked.db");
// Then, lock the file and try again.
FileLock guard("test/fixtures/database/locked.db");
@@ -206,8 +212,9 @@ TEST_F(Storage, DatabaseLockedRefresh) {
auto response = std::make_shared<Response>();
response->data = "Demo";
cache.put({ Resource::Unknown, "mapbox://test" }, response);
- std::unique_ptr<Response> res = cache.get({ Resource::Unknown, "mapbox://test" });
- EXPECT_EQ(nullptr, res.get());
+ cache.get({ Resource::Unknown, "mapbox://test" }, [] (std::unique_ptr<Response> res) {
+ EXPECT_EQ(nullptr, res.get());
+ });
auto observer = Log::removeObserver();
auto flo = dynamic_cast<FixtureLogObserver*>(observer.get());
@@ -221,8 +228,9 @@ TEST_F(Storage, DatabaseLockedRefresh) {
auto response = std::make_shared<Response>();
response->data = "Demo";
cache.refresh({ Resource::Unknown, "mapbox://test" }, response->expires);
- std::unique_ptr<Response> res = cache.get({ Resource::Unknown, "mapbox://test" });
- EXPECT_EQ(nullptr, res.get());
+ cache.get({ Resource::Unknown, "mapbox://test" }, [] (std::unique_ptr<Response> res) {
+ EXPECT_EQ(nullptr, res.get());
+ });
// Make sure that we got the right errors.
auto observer = Log::removeObserver();
@@ -240,7 +248,7 @@ TEST_F(Storage, DatabaseDeleted) {
createDir("test/fixtures/database");
deleteFile("test/fixtures/database/locked.db");
- SQLiteCache::Impl cache(nullptr, "test/fixtures/database/locked.db");
+ SQLiteCache::Impl cache("test/fixtures/database/locked.db");
{
// Adds a file.
@@ -249,9 +257,10 @@ TEST_F(Storage, DatabaseDeleted) {
auto response = std::make_shared<Response>();
response->data = "Demo";
cache.put({ Resource::Unknown, "mapbox://test" }, response);
- std::unique_ptr<Response> res = cache.get({ Resource::Unknown, "mapbox://test" });
- EXPECT_NE(nullptr, res.get());
- EXPECT_EQ("Demo", res->data);
+ cache.get({ Resource::Unknown, "mapbox://test" }, [] (std::unique_ptr<Response> res) {
+ EXPECT_NE(nullptr, res.get());
+ EXPECT_EQ("Demo", res->data);
+ });
Log::removeObserver();
}
@@ -265,9 +274,10 @@ TEST_F(Storage, DatabaseDeleted) {
auto response = std::make_shared<Response>();
response->data = "Demo";
cache.put({ Resource::Unknown, "mapbox://test" }, response);
- std::unique_ptr<Response> res = cache.get({ Resource::Unknown, "mapbox://test" });
- EXPECT_NE(nullptr, res.get());
- EXPECT_EQ("Demo", res->data);
+ cache.get({ Resource::Unknown, "mapbox://test" }, [] (std::unique_ptr<Response> res) {
+ EXPECT_NE(nullptr, res.get());
+ EXPECT_EQ("Demo", res->data);
+ });
auto observer = Log::removeObserver();
auto flo = dynamic_cast<FixtureLogObserver*>(observer.get());
@@ -285,7 +295,7 @@ TEST_F(Storage, DatabaseInvalid) {
deleteFile("test/fixtures/database/invalid.db");
writeFile("test/fixtures/database/invalid.db", "this is an invalid file");
- SQLiteCache::Impl cache(nullptr, "test/fixtures/database/invalid.db");
+ SQLiteCache::Impl cache("test/fixtures/database/invalid.db");
{
// Adds a file.
@@ -294,9 +304,10 @@ TEST_F(Storage, DatabaseInvalid) {
auto response = std::make_shared<Response>();
response->data = "Demo";
cache.put({ Resource::Unknown, "mapbox://test" }, response);
- std::unique_ptr<Response> res = cache.get({ Resource::Unknown, "mapbox://test" });
- EXPECT_NE(nullptr, res.get());
- EXPECT_EQ("Demo", res->data);
+ cache.get({ Resource::Unknown, "mapbox://test" }, [] (std::unique_ptr<Response> res) {
+ EXPECT_NE(nullptr, res.get());
+ EXPECT_EQ("Demo", res->data);
+ });
auto observer = Log::removeObserver();
auto flo = dynamic_cast<FixtureLogObserver*>(observer.get());
diff --git a/test/style/glyph_store.cpp b/test/style/glyph_store.cpp
new file mode 100644
index 0000000000..fe614e8c60
--- /dev/null
+++ b/test/style/glyph_store.cpp
@@ -0,0 +1,231 @@
+#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_TRUE(fontStack->getMetrics().empty());
+ ASSERT_TRUE(fontStack->getSDFs().empty());
+
+ 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);
+
+ auto fontStack = store->getFontStack(params.stack);
+ ASSERT_TRUE(fontStack->getMetrics().empty());
+ ASSERT_TRUE(fontStack->getSDFs().empty());
+
+ 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_TRUE(fontStack->getMetrics().empty());
+ ASSERT_TRUE(fontStack->getSDFs().empty());
+
+ stopTest();
+ };
+
+ MockFileSource fileSource(MockFileSource::Success, "");
+ runTest(params, &fileSource, callback);
+}
diff --git a/test/style/pending_resources.cpp b/test/style/pending_resources.cpp
index 5d13d49a7c..3ba59657de 100644
--- a/test/style/pending_resources.cpp
+++ b/test/style/pending_resources.cpp
@@ -1,6 +1,6 @@
#include "../fixtures/fixture_log_observer.hpp"
+#include "../fixtures/mock_file_source.hpp"
#include "../fixtures/util.hpp"
-#include "mock_file_source.hpp"
#include <mbgl/map/map.hpp>
#include <mbgl/map/still_image.hpp>
@@ -21,15 +21,10 @@ class PendingResources : public ::testing::TestWithParam<std::string> {
// the Map object after that. The idea here is to test if these pending requests
// are getting canceled correctly if on shutdown.
TEST_P(PendingResources, DeleteMapObjectWithPendingRequest) {
- // TODO: The glyphs test is blocked by the issue #1664.
- if (GetParam() == "glyphs.pbf") {
- return;
- }
-
util::RunLoop loop(uv_default_loop());
auto display = std::make_shared<mbgl::HeadlessDisplay>();
- HeadlessView view(display);
+ HeadlessView view(display, 1, 1000, 1000);
MockFileSource fileSource(MockFileSource::SuccessWithDelay, GetParam());
std::unique_ptr<Map> map = std::make_unique<Map>(view, fileSource, MapMode::Still);
@@ -43,7 +38,6 @@ TEST_P(PendingResources, DeleteMapObjectWithPendingRequest) {
fileSource.setOnRequestDelayedCallback([&endTest] { endTest.send(); });
const std::string style = util::read_file("test/fixtures/resources/style.json");
- map->resize(1000, 1000, 1.0);
map->setStyleJSON(style, ".");
map->renderStill([&endTest](std::exception_ptr, std::unique_ptr<const StillImage>) {
@@ -55,7 +49,16 @@ TEST_P(PendingResources, DeleteMapObjectWithPendingRequest) {
// In the test data below, "sprite" will match both "sprite.json" and "sprite.png" and cause two
// requests to be canceled. "resources" will match everything but in practice will only test the
-// cancellation of the sprites and "source.json" because we only load the rest after "source.json"
+// cancellation of the sprites and "source_*.json" because we only load the rest after "source_*.json"
// gets parsed.
INSTANTIATE_TEST_CASE_P(Style, PendingResources,
- ::testing::Values("source.json", "sprite.json", "sprite.png", "sprite", "vector.pbf", "glyphs.pbf", "resources"));
+ ::testing::Values(
+ "source_raster.json",
+ "source_vector.json",
+ "sprite.json",
+ "sprite.png",
+ "sprite",
+ "raster.png",
+ "vector.pbf",
+ "glyphs.pbf",
+ "resources"));
diff --git a/test/style/resource_loading.cpp b/test/style/resource_loading.cpp
index 92d479b512..5ed09065a1 100644
--- a/test/style/resource_loading.cpp
+++ b/test/style/resource_loading.cpp
@@ -1,7 +1,7 @@
#include "../fixtures/fixture_log_observer.hpp"
#include "../fixtures/util.hpp"
+#include "../fixtures/mock_file_source.hpp"
#include "../fixtures/mock_view.hpp"
-#include "mock_file_source.hpp"
#include <mbgl/map/map_data.hpp>
#include <mbgl/map/transform.hpp>
@@ -20,20 +20,20 @@ namespace {
class MockMapContext : public Style::Observer {
public:
- MockMapContext(uv_loop_t* loop,
- View& view,
+ MockMapContext(View& view,
FileSource& fileSource,
const std::function<void(std::exception_ptr error)>& callback)
- : data_(MapMode::Still),
+ : data_(MapMode::Still, view.getPixelRatio()),
transform_(view),
callback_(callback) {
util::ThreadContext::setFileSource(&fileSource);
- transform_.resize(1000, 1000, 1.0, 1000, 1000);
+ 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>(style, "", loop),
+ style_ = std::make_unique<Style>(data_);
+ style_->setJSON(style, "");
style_->setObserver(this);
}
@@ -47,7 +47,7 @@ public:
data_.setAnimationTime(now);
transform_.updateTransitions(now);
- style_->update(data_, transform_.getState(), texturePool_);
+ style_->update(transform_.getState(), texturePool_);
}
// Style::Observer implementation.
@@ -63,6 +63,10 @@ public:
callback_(error);
}
+ void onSpriteStoreLoaded() override {
+ // no-op
+ }
+
private:
MapData data_;
Transform transform_;
@@ -98,11 +102,11 @@ void runTestCase(MockFileSource::Type type,
} catch (const util::GlyphRangeLoadingException&) {
EXPECT_EQ(param, "glyphs.pbf");
} catch (const util::SourceLoadingException&) {
- EXPECT_EQ(param, "source.json");
+ 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_EQ(param, "vector.pbf");
+ EXPECT_TRUE(param == "raster.png" || param == "vector.pbf");
} catch (const std::exception&) {
EXPECT_TRUE(false) << "Unhandled exception.";
}
@@ -124,7 +128,7 @@ void runTestCase(MockFileSource::Type type,
std::vector<FixtureLogObserver::LogMessage> logMessages = log->unchecked();
for (auto& logMessage : logMessages) {
- if (std::regex_match(*logMessage.msg, std::regex(message))) {
+ if (std::regex_match(logMessage.msg, std::regex(message))) {
match++;
}
}
@@ -138,38 +142,30 @@ void runTestCase(MockFileSource::Type type,
}
-class ResourceLoading : public ::testing::TestWithParam<std::string> {
+class ResourceLoading : public ::testing::TestWithParam<std::pair<std::string, std::string>> {
};
TEST_P(ResourceLoading, Success) {
- runTestCase(MockFileSource::Success, GetParam(), std::string());
+ runTestCase(MockFileSource::Success, GetParam().first, std::string());
}
TEST_P(ResourceLoading, RequestFail) {
std::stringstream message;
- message << "Failed to load \\[test\\/fixtures\\/resources\\/" << GetParam() << "\\]\\: Failed by the test case";
+ message << "Failed to load \\[test\\/fixtures\\/resources\\/" << GetParam().first << "\\]\\: Failed by the test case";
- runTestCase(MockFileSource::RequestFail, GetParam(), message.str());
+ runTestCase(MockFileSource::RequestFail, GetParam().first, message.str());
}
TEST_P(ResourceLoading, RequestWithCorruptedData) {
- const std::string param(GetParam());
-
- std::stringstream message;
- message << "Failed to parse ";
-
- if (param == "vector.pbf") {
- message << "\\[15\\/1638(3|4)\\/1638(3|4)\\]\\: 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());
+ runTestCase(MockFileSource::RequestWithCorruptedData, GetParam().first, GetParam().second);
}
INSTANTIATE_TEST_CASE_P(Style, ResourceLoading,
- ::testing::Values("source.json", "sprite.json", "sprite.png", "vector.pbf", "glyphs.pbf"));
+ ::testing::Values(
+ std::make_pair("source_raster.json", "Failed to parse \\[test\\/fixtures\\/resources\\/source_raster.json\\]: 0 - Expect either an object or array at root"),
+ std::make_pair("source_vector.json", "Failed to parse \\[test\\/fixtures\\/resources\\/source_vector.json\\]: 0 - Expect either an object or array at root"),
+ std::make_pair("sprite.json", "Failed to parse JSON: Expect either an object or array at root 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")));
diff --git a/test/style/sprite.cpp b/test/style/sprite.cpp
new file mode 100644
index 0000000000..1c3f9b2271
--- /dev/null
+++ b/test/style/sprite.cpp
@@ -0,0 +1,173 @@
+#include "../fixtures/fixture_log_observer.hpp"
+#include "../fixtures/mock_file_source.hpp"
+#include "../fixtures/util.hpp"
+
+#include <mbgl/map/sprite.hpp>
+#include <mbgl/util/run_loop.hpp>
+#include <mbgl/util/thread.hpp>
+
+using namespace mbgl;
+
+using SpriteTestCallback = std::function<void(Sprite*, const Sprites&, std::exception_ptr)>;
+
+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> 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<uv::async>(loop.get(), [&] { 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);
+
+ uv_run(loop.get(), UV_RUN_DEFAULT);
+
+ tester.invoke(&SpriteThread::unloadSprite);
+ }
+
+ void stopTest() {
+ async_->send();
+ }
+
+private:
+ std::unique_ptr<uv::async> async_;
+};
+
+TEST_F(SpriteTest, LoadingSuccess) {
+ SpriteParams params = {
+ "test/fixtures/resources/sprite",
+ 1.0,
+ };
+
+ auto callback = [this, &params](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, &params](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 f3d6976dd2..a35b00133b 100644
--- a/test/test.gypi
+++ b/test/test.gypi
@@ -30,22 +30,32 @@
],
'sources': [
'fixtures/main.cpp',
+ 'fixtures/mock_file_source.cpp',
+ 'fixtures/mock_file_source.hpp',
+ 'fixtures/mock_view.hpp',
'fixtures/util.hpp',
'fixtures/util.cpp',
'fixtures/fixture_log_observer.hpp',
'fixtures/fixture_log_observer.cpp',
+ 'miscellaneous/assert.cpp',
+
+ 'annotations/sprite_atlas.cpp',
+ 'annotations/sprite_image.cpp',
+ 'annotations/sprite_store.cpp',
+ 'annotations/sprite_parser.cpp',
+
+ 'api/annotations.cpp',
'api/api_misuse.cpp',
'api/repeated_render.cpp',
'api/set_style.cpp',
- 'headless/headless.cpp',
- 'miscellaneous/assert.cpp',
'miscellaneous/clip_ids.cpp',
'miscellaneous/binpack.cpp',
'miscellaneous/bilinear.cpp',
'miscellaneous/comparisons.cpp',
+ 'miscellaneous/custom_sprites.cpp',
'miscellaneous/enums.cpp',
'miscellaneous/functions.cpp',
'miscellaneous/geo.cpp',
@@ -58,8 +68,8 @@
'miscellaneous/thread.cpp',
'miscellaneous/tile.cpp',
'miscellaneous/transform.cpp',
+ 'miscellaneous/work_queue.cpp',
'miscellaneous/variant.cpp',
- 'miscellaneous/worker.cpp',
'storage/storage.hpp',
'storage/storage.cpp',
@@ -77,26 +87,25 @@
'storage/http_other_loop.cpp',
'storage/http_reading.cpp',
- 'style/mock_file_source.cpp',
- 'style/mock_file_source.hpp',
- 'style/mock_view.hpp',
+ 'style/glyph_store.cpp',
'style/pending_resources.cpp',
'style/resource_loading.cpp',
+ 'style/sprite.cpp',
],
'libraries': [
- '<@(uv_static_libs)',
- '<@(sqlite3_static_libs)',
+ '<@(libuv_static_libs)',
+ '<@(sqlite_static_libs)',
],
'variables': {
'cflags_cc': [
- '<@(uv_cflags)',
+ '<@(libuv_cflags)',
'<@(opengl_cflags)',
'<@(boost_cflags)',
- '<@(sqlite3_cflags)',
+ '<@(sqlite_cflags)',
],
'ldflags': [
- '<@(uv_ldflags)',
- '<@(sqlite3_ldflags)',
+ '<@(libuv_ldflags)',
+ '<@(sqlite_ldflags)',
],
},
'conditions': [