summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/api/annotations.test.cpp20
-rw-r--r--test/api/api_misuse.test.cpp4
-rw-r--r--test/api/custom_layer.test.cpp2
-rw-r--r--test/api/query.test.cpp2
-rw-r--r--test/api/render_missing.test.cpp2
-rw-r--r--test/api/repeated_render.test.cpp2
-rw-r--r--test/fixtures/annotations/result-spriteatlas.pngbin1124 -> 0 bytes
-rw-r--r--test/fixtures/map/no_vao/expected.pngbin0 -> 9832 bytes
-rw-r--r--test/fixtures/sprite_atlas/basic/expected.pngbin0 -> 694 bytes
-rw-r--r--test/fixtures/sprite_atlas/size/expected.png (renamed from test/fixtures/annotations/result-spriteatlassize.png)bin1118 -> 1118 bytes
-rw-r--r--test/fixtures/sprite_atlas/updates_after/expected.png (renamed from test/fixtures/annotations/result-spriteatlas-updated.png)bin135 -> 135 bytes
-rw-r--r--test/fixtures/sprite_atlas/updates_before/expected.png (renamed from test/fixtures/annotations/result-spriteatlas-empty.png)bin110 -> 110 bytes
-rw-r--r--test/gl/bucket.test.cpp19
-rw-r--r--test/gl/object.test.cpp4
-rw-r--r--test/map/map.test.cpp109
-rw-r--r--test/map/transform.test.cpp6
-rw-r--r--test/math/wrap.test.cpp2
-rw-r--r--test/sprite/sprite_atlas.test.cpp57
-rw-r--r--test/src/mbgl/test/conversion_stubs.hpp2
-rw-r--r--test/src/mbgl/test/getrss.cpp102
-rw-r--r--test/src/mbgl/test/getrss.hpp45
-rw-r--r--test/src/mbgl/test/stub_geometry_tile_feature.hpp34
-rw-r--r--test/src/mbgl/test/stub_layer_observer.hpp5
-rw-r--r--test/src/mbgl/test/util.hpp2
-rw-r--r--test/storage/default_file_source.test.cpp46
-rw-r--r--test/storage/local_file_source.test.cpp8
-rw-r--r--test/storage/offline_database.test.cpp4
-rw-r--r--test/storage/online_file_source.test.cpp14
-rwxr-xr-xtest/storage/server.js35
-rw-r--r--test/storage/sqlite.test.cpp27
-rw-r--r--test/style/conversion/function.test.cpp2
-rw-r--r--test/style/conversion/geojson_options.test.cpp22
-rw-r--r--test/style/conversion/layer.test.cpp46
-rw-r--r--test/style/conversion/stringify.test.cpp38
-rw-r--r--test/style/function/camera_function.test.cpp (renamed from test/style/functions.test.cpp)14
-rw-r--r--test/style/function/source_function.test.cpp94
-rw-r--r--test/style/paint_property.test.cpp76
-rw-r--r--test/style/source.test.cpp8
-rw-r--r--test/style/style.test.cpp2
-rw-r--r--test/style/style_layer.test.cpp124
-rw-r--r--test/text/glyph_atlas.test.cpp37
-rw-r--r--test/text/glyph_pbf.test.cpp8
-rw-r--r--test/text/quads.test.cpp274
-rw-r--r--test/tile/geometry_tile_data.test.cpp46
-rw-r--r--test/tile/raster_tile.test.cpp15
-rw-r--r--test/tile/vector_tile.test.cpp8
-rw-r--r--test/util/http_timeout.test.cpp15
-rw-r--r--test/util/image.test.cpp29
-rw-r--r--test/util/mapbox.test.cpp3
-rw-r--r--test/util/memory.test.cpp54
-rw-r--r--test/util/merge_lines.test.cpp136
-rw-r--r--test/util/offscreen_texture.test.cpp88
-rw-r--r--test/util/thread.test.cpp78
-rw-r--r--test/util/url.test.cpp20
54 files changed, 1266 insertions, 524 deletions
diff --git a/test/api/annotations.test.cpp b/test/api/annotations.test.cpp
index 72a2d62bde..6644e9c92c 100644
--- a/test/api/annotations.test.cpp
+++ b/test/api/annotations.test.cpp
@@ -27,7 +27,7 @@ public:
OffscreenView view { backend.getContext() };
StubFileSource fileSource;
ThreadPool threadPool { 4 };
- Map map { backend, view.size, 1, fileSource, threadPool, MapMode::Still };
+ Map map { backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still };
void checkRendering(const char * name) {
test::checkImage(std::string("test/fixtures/annotations/") + name,
@@ -45,13 +45,13 @@ TEST(Annotations, SymbolAnnotation) {
test.map.addAnnotation(SymbolAnnotation { Point<double>(0, 0), "default_marker" });
test.checkRendering("point_annotation");
- auto size = test.view.size;
- auto screenBox = ScreenBox { {}, { double(size.width), double(size.height) } };
- for (uint8_t zoom = test.map.getMinZoom(); zoom <= test.map.getMaxZoom(); ++zoom) {
- test.map.setZoom(zoom);
- test.checkRendering("point_annotation");
- EXPECT_EQ(test.map.queryPointAnnotations(screenBox).size(), 1u);
- }
+// auto size = test.view.getSize();
+// auto screenBox = ScreenBox { {}, { double(size.width), double(size.height) } };
+// for (uint8_t zoom = test.map.getMinZoom(); zoom <= test.map.getMaxZoom(); ++zoom) {
+// test.map.setZoom(zoom);
+// test.checkRendering("point_annotation");
+// EXPECT_EQ(test.map.queryPointAnnotations(screenBox).size(), 1u);
+// }
}
TEST(Annotations, LineAnnotation) {
@@ -351,7 +351,7 @@ TEST(Annotations, QueryRenderedFeatures) {
TEST(Annotations, QueryFractionalZoomLevels) {
AnnotationTest test;
- auto viewSize = test.view.size;
+ auto viewSize = test.view.getSize();
auto box = ScreenBox { {}, { double(viewSize.width), double(viewSize.height) } };
test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
@@ -383,7 +383,7 @@ TEST(Annotations, QueryFractionalZoomLevels) {
TEST(Annotations, VisibleFeatures) {
AnnotationTest test;
- auto viewSize = test.view.size;
+ auto viewSize = test.view.getSize();
auto box = ScreenBox { {}, { double(viewSize.width), double(viewSize.height) } };
test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
diff --git a/test/api/api_misuse.test.cpp b/test/api/api_misuse.test.cpp
index 34272f5366..1a61872f79 100644
--- a/test/api/api_misuse.test.cpp
+++ b/test/api/api_misuse.test.cpp
@@ -27,7 +27,7 @@ TEST(API, RenderWithoutCallback) {
ThreadPool threadPool(4);
std::unique_ptr<Map> map =
- std::make_unique<Map>(backend, view.size, 1, fileSource, threadPool, MapMode::Still);
+ std::make_unique<Map>(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still);
map->renderStill(view, nullptr);
// Force Map thread to join.
@@ -51,7 +51,7 @@ TEST(API, RenderWithoutStyle) {
StubFileSource fileSource;
ThreadPool threadPool(4);
- Map map(backend, view.size, 1, fileSource, threadPool, MapMode::Still);
+ Map map(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still);
std::exception_ptr error;
map.renderStill(view, [&](std::exception_ptr error_) {
diff --git a/test/api/custom_layer.test.cpp b/test/api/custom_layer.test.cpp
index 73b4e94af5..dd56197463 100644
--- a/test/api/custom_layer.test.cpp
+++ b/test/api/custom_layer.test.cpp
@@ -97,7 +97,7 @@ TEST(CustomLayer, Basic) {
ThreadPool threadPool(4);
- Map map(backend, view.size, 1, fileSource, threadPool, MapMode::Still);
+ Map map(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/water.json"));
map.setLatLngZoom({ 37.8, -122.5 }, 10);
map.addLayer(std::make_unique<CustomLayer>(
diff --git a/test/api/query.test.cpp b/test/api/query.test.cpp
index 86687fc818..4d2bf00f67 100644
--- a/test/api/query.test.cpp
+++ b/test/api/query.test.cpp
@@ -30,7 +30,7 @@ public:
OffscreenView view { backend.getContext() };
StubFileSource fileSource;
ThreadPool threadPool { 4 };
- Map map { backend, view.size, 1, fileSource, threadPool, MapMode::Still };
+ Map map { backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still };
};
} // end namespace
diff --git a/test/api/render_missing.test.cpp b/test/api/render_missing.test.cpp
index a5c59913bc..c1bf7e5702 100644
--- a/test/api/render_missing.test.cpp
+++ b/test/api/render_missing.test.cpp
@@ -38,7 +38,7 @@ TEST(API, TEST_REQUIRES_SERVER(RenderMissingTile)) {
Log::setObserver(std::make_unique<FixtureLogObserver>());
- Map map(backend, view.size, 1, fileSource, threadPool, MapMode::Still);
+ Map map(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still);
std::string message;
diff --git a/test/api/repeated_render.test.cpp b/test/api/repeated_render.test.cpp
index 49b9a31b0b..800813075f 100644
--- a/test/api/repeated_render.test.cpp
+++ b/test/api/repeated_render.test.cpp
@@ -34,7 +34,7 @@ TEST(API, RepeatedRender) {
Log::setObserver(std::make_unique<FixtureLogObserver>());
- Map map(backend, view.size, 1, fileSource, threadPool, MapMode::Still);
+ Map map(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still);
{
map.setStyleJSON(style);
diff --git a/test/fixtures/annotations/result-spriteatlas.png b/test/fixtures/annotations/result-spriteatlas.png
deleted file mode 100644
index e886e060fe..0000000000
--- a/test/fixtures/annotations/result-spriteatlas.png
+++ /dev/null
Binary files differ
diff --git a/test/fixtures/map/no_vao/expected.png b/test/fixtures/map/no_vao/expected.png
new file mode 100644
index 0000000000..d5b7c42762
--- /dev/null
+++ b/test/fixtures/map/no_vao/expected.png
Binary files differ
diff --git a/test/fixtures/sprite_atlas/basic/expected.png b/test/fixtures/sprite_atlas/basic/expected.png
new file mode 100644
index 0000000000..cd13d16df6
--- /dev/null
+++ b/test/fixtures/sprite_atlas/basic/expected.png
Binary files differ
diff --git a/test/fixtures/annotations/result-spriteatlassize.png b/test/fixtures/sprite_atlas/size/expected.png
index d9ae7dab47..d9ae7dab47 100644
--- a/test/fixtures/annotations/result-spriteatlassize.png
+++ b/test/fixtures/sprite_atlas/size/expected.png
Binary files differ
diff --git a/test/fixtures/annotations/result-spriteatlas-updated.png b/test/fixtures/sprite_atlas/updates_after/expected.png
index 3c850c0a25..3c850c0a25 100644
--- a/test/fixtures/annotations/result-spriteatlas-updated.png
+++ b/test/fixtures/sprite_atlas/updates_after/expected.png
Binary files differ
diff --git a/test/fixtures/annotations/result-spriteatlas-empty.png b/test/fixtures/sprite_atlas/updates_before/expected.png
index effcd38f1e..effcd38f1e 100644
--- a/test/fixtures/annotations/result-spriteatlas-empty.png
+++ b/test/fixtures/sprite_atlas/updates_before/expected.png
Binary files differ
diff --git a/test/gl/bucket.test.cpp b/test/gl/bucket.test.cpp
index 03cdc63a91..feda234af2 100644
--- a/test/gl/bucket.test.cpp
+++ b/test/gl/bucket.test.cpp
@@ -4,37 +4,34 @@
#include <mbgl/renderer/fill_bucket.hpp>
#include <mbgl/renderer/line_bucket.hpp>
#include <mbgl/renderer/symbol_bucket.hpp>
-
+#include <mbgl/style/bucket_parameters.hpp>
#include <mbgl/style/layers/symbol_layer_properties.hpp>
#include <mbgl/map/mode.hpp>
-TEST(Buckets, CircleBucket) {
- mbgl::MapMode mapMode = mbgl::MapMode::Still;
+using namespace mbgl;
- mbgl::CircleBucket bucket { mapMode };
+TEST(Buckets, CircleBucket) {
+ CircleBucket bucket { { {0, 0, 0}, MapMode::Still }, {} };
ASSERT_FALSE(bucket.hasData());
}
TEST(Buckets, FillBucket) {
- mbgl::FillBucket bucket;
+ FillBucket bucket { { {0, 0, 0}, MapMode::Still }, {} };
ASSERT_FALSE(bucket.hasData());
}
TEST(Buckets, LineBucket) {
- uint32_t overscaling = 0;
-
- mbgl::LineBucket bucket { overscaling };
+ LineBucket bucket { { {0, 0, 0}, MapMode::Still }, {}, {} };
ASSERT_FALSE(bucket.hasData());
}
TEST(Buckets, SymbolBucket) {
- mbgl::MapMode mapMode = mbgl::MapMode::Still;
- mbgl::style::SymbolLayoutProperties::Evaluated properties;
+ style::SymbolLayoutProperties::Evaluated layout;
bool sdfIcons = false;
bool iconsNeedLinear = false;
- mbgl::SymbolBucket bucket { mapMode, properties, sdfIcons, iconsNeedLinear };
+ SymbolBucket bucket { layout, {}, 0, sdfIcons, iconsNeedLinear };
ASSERT_FALSE(bucket.hasIconData());
ASSERT_FALSE(bucket.hasTextData());
ASSERT_FALSE(bucket.hasCollisionBoxData());
diff --git a/test/gl/object.test.cpp b/test/gl/object.test.cpp
index f1da93f1da..85ae457081 100644
--- a/test/gl/object.test.cpp
+++ b/test/gl/object.test.cpp
@@ -1,5 +1,6 @@
#include <mbgl/test/util.hpp>
+#include <mbgl/map/backend_scope.hpp>
#include <mbgl/gl/headless_backend.hpp>
#include <mbgl/gl/offscreen_view.hpp>
@@ -62,6 +63,7 @@ TEST(GLObject, Value) {
TEST(GLObject, Store) {
HeadlessBackend backend { test::sharedDisplay() };
OffscreenView view(backend.getContext());
+ BackendScope scope { backend };
gl::Context context;
EXPECT_TRUE(context.empty());
@@ -77,6 +79,4 @@ TEST(GLObject, Store) {
context.reset();
EXPECT_TRUE(context.empty());
-
- backend.deactivate();
}
diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp
index 8eedeb3c01..618c2e6a74 100644
--- a/test/map/map.test.cpp
+++ b/test/map/map.test.cpp
@@ -4,12 +4,15 @@
#include <mbgl/test/fixture_log_observer.hpp>
#include <mbgl/map/map.hpp>
+#include <mbgl/map/backend_scope.hpp>
#include <mbgl/gl/headless_backend.hpp>
#include <mbgl/gl/offscreen_view.hpp>
+#include <mbgl/gl/context.hpp>
#include <mbgl/util/default_thread_pool.hpp>
#include <mbgl/sprite/sprite_image.hpp>
#include <mbgl/storage/network_status.hpp>
#include <mbgl/storage/default_file_source.hpp>
+#include <mbgl/storage/online_file_source.hpp>
#include <mbgl/util/image.hpp>
#include <mbgl/util/io.hpp>
#include <mbgl/util/run_loop.hpp>
@@ -31,7 +34,7 @@ struct MapTest {
TEST(Map, LatLngBehavior) {
MapTest test;
- Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
@@ -65,7 +68,7 @@ TEST(Map, Offline) {
fileSource.put(Resource::glyphs(prefix + "{fontstack}/{range}.pbf", {{"Helvetica"}}, {0, 255}), expiredItem("glyph.pbf"));
NetworkStatus::Set(NetworkStatus::Status::Offline);
- Map map(test.backend, test.view.size, 1, fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.getSize(), 1, fileSource, test.threadPool, MapMode::Still);
map.setStyleURL(prefix + "style.json");
test::checkImage("test/fixtures/map/offline",
@@ -89,7 +92,7 @@ TEST(Map, SetStyleInvalidJSON) {
});
{
- Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool,
+ Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool,
MapMode::Still);
map.setStyleJSON("invalid");
}
@@ -121,7 +124,7 @@ TEST(Map, SetStyleInvalidURL) {
}
});
- Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
map.setStyleURL("mapbox://bar");
test.runLoop.run();
@@ -130,7 +133,7 @@ TEST(Map, SetStyleInvalidURL) {
TEST(Map, DoubleStyleLoad) {
MapTest test;
- Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
map.setStyleJSON("");
map.setStyleJSON("");
}
@@ -141,7 +144,7 @@ TEST(Map, StyleFresh) {
MapTest test;
FakeFileSource fileSource;
- Map map(test.backend, test.view.size, 1, fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.getSize(), 1, fileSource, test.threadPool, MapMode::Still);
map.setStyleURL("mapbox://styles/test");
EXPECT_EQ(1u, fileSource.requests.size());
@@ -161,7 +164,7 @@ TEST(Map, StyleExpired) {
MapTest test;
FakeFileSource fileSource;
- Map map(test.backend, test.view.size, 1, fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.getSize(), 1, fileSource, test.threadPool, MapMode::Still);
map.setStyleURL("mapbox://styles/test");
EXPECT_EQ(1u, fileSource.requests.size());
@@ -188,7 +191,7 @@ TEST(Map, StyleExpiredWithAnnotations) {
MapTest test;
FakeFileSource fileSource;
- Map map(test.backend, test.view.size, 1, fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.getSize(), 1, fileSource, test.threadPool, MapMode::Still);
map.setStyleURL("mapbox://styles/test");
EXPECT_EQ(1u, fileSource.requests.size());
@@ -212,7 +215,7 @@ TEST(Map, StyleEarlyMutation) {
MapTest test;
FakeFileSource fileSource;
- Map map(test.backend, test.view.size, 1, fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.getSize(), 1, fileSource, test.threadPool, MapMode::Still);
map.setStyleURL("mapbox://styles/test");
map.addLayer(std::make_unique<style::BackgroundLayer>("bg"));
@@ -226,7 +229,7 @@ TEST(Map, StyleEarlyMutation) {
TEST(Map, StyleLoadedSignal) {
MapTest test;
- Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
// The map should emit a signal on style loaded
bool emitted = false;
@@ -237,17 +240,64 @@ TEST(Map, StyleLoadedSignal) {
});
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
EXPECT_TRUE(emitted);
-
+
// But not when the style couldn't be parsed
emitted = false;
map.setStyleJSON("invalid");
EXPECT_FALSE(emitted);
}
+// Test for https://github.com/mapbox/mapbox-gl-native/issues/7902
+TEST(Map, TEST_REQUIRES_SERVER(StyleNetworkErrorRetry)) {
+ MapTest test;
+ OnlineFileSource fileSource;
+
+ Map map(test.backend, test.view.getSize(), 1, fileSource, test.threadPool, MapMode::Still);
+ map.setStyleURL("http://127.0.0.1:3000/style-fail-once-500");
+
+ test.backend.setMapChangeCallback([&](MapChange change) {
+ if (change == mbgl::MapChangeDidFinishLoadingStyle) {
+ test.runLoop.stop();
+ }
+ });
+
+ test.runLoop.run();
+}
+
+TEST(Map, TEST_REQUIRES_SERVER(StyleNotFound)) {
+ MapTest test;
+ OnlineFileSource fileSource;
+
+ Map map(test.backend, test.view.getSize(), 1, fileSource, test.threadPool, MapMode::Still);
+ map.setStyleURL("http://127.0.0.1:3000/style-fail-once-404");
+
+ using namespace std::chrono_literals;
+ util::Timer timer;
+
+ // Not found errors should not trigger a retry like other errors.
+ test.backend.setMapChangeCallback([&](MapChange change) {
+ if (change == mbgl::MapChangeDidFinishLoadingStyle) {
+ FAIL() << "Should not retry on not found!";
+ }
+
+ if (change == mbgl::MapChangeDidFailLoadingMap) {
+ timer.start(Milliseconds(1100), 0s, [&] {
+ test.runLoop.stop();
+ });
+ }
+ });
+
+ test.runLoop.run();
+
+ // Should also not retry if the response has cache headers.
+ map.setStyleURL("http://127.0.0.1:3000/style-fail-once-404-cache");
+ test.runLoop.run();
+}
+
TEST(Map, AddLayer) {
MapTest test;
- Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
auto layer = std::make_unique<BackgroundLayer>("background");
@@ -257,10 +307,28 @@ TEST(Map, AddLayer) {
test::checkImage("test/fixtures/map/add_layer", test::render(map, test.view));
}
+TEST(Map, WithoutVAOExtension) {
+ MapTest test;
+
+ test.backend.getContext().disableVAOExtension = true;
+
+#ifdef MBGL_ASSET_ZIP
+ // Regenerate with `cd test/fixtures/api/ && zip -r assets.zip assets/`
+ DefaultFileSource fileSource(":memory:", "test/fixtures/api/assets.zip");
+#else
+ DefaultFileSource fileSource(":memory:", "test/fixtures/api/assets");
+#endif
+
+ Map map(test.backend, test.view.getSize(), 1, fileSource, test.threadPool, MapMode::Still);
+ map.setStyleJSON(util::read_file("test/fixtures/api/water.json"));
+
+ test::checkImage("test/fixtures/map/no_vao", test::render(map, test.view), 0.002);
+}
+
TEST(Map, RemoveLayer) {
MapTest test;
- Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
auto layer = std::make_unique<BackgroundLayer>("background");
@@ -285,7 +353,7 @@ TEST(Map, DisabledSources) {
return {};
};
- Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
map.setZoom(1);
// This stylesheet has two raster layers, one that starts at zoom 1, the other at zoom 0.
@@ -335,7 +403,7 @@ TEST(Map, DisabledSources) {
TEST(Map, Classes) {
MapTest test;
- Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
map.setStyleJSON(util::read_file("test/fixtures/api/empty.json"));
EXPECT_FALSE(map.getTransitionOptions().duration);
@@ -369,7 +437,7 @@ TEST(Map, Classes) {
TEST(Map, AddImage) {
MapTest test;
- Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
auto decoded1 = decodeImage(util::read_file("test/fixtures/sprites/default_marker.png"));
auto decoded2 = decodeImage(util::read_file("test/fixtures/sprites/default_marker.png"));
auto image1 = std::make_unique<SpriteImage>(std::move(decoded1), 1.0);
@@ -386,7 +454,7 @@ TEST(Map, AddImage) {
TEST(Map, RemoveImage) {
MapTest test;
- Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
auto decoded = decodeImage(util::read_file("test/fixtures/sprites/default_marker.png"));
auto image = std::make_unique<SpriteImage>(std::move(decoded), 1.0);
@@ -399,7 +467,7 @@ TEST(Map, RemoveImage) {
TEST(Map, GetImage) {
MapTest test;
- Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
auto decoded = decodeImage(util::read_file("test/fixtures/sprites/default_marker.png"));
auto image = std::make_unique<SpriteImage>(std::move(decoded), 1.0);
@@ -411,7 +479,7 @@ TEST(Map, GetImage) {
TEST(Map, DontLoadUnneededTiles) {
MapTest test;
- Map map(test.backend, test.view.size, 1, test.fileSource, test.threadPool, MapMode::Still);
+ Map map(test.backend, test.view.getSize(), 1, test.fileSource, test.threadPool, MapMode::Still);
map.setStyleJSON(R"STYLE({
"sources": {
"a": { "type": "vector", "tiles": [ "a/{z}/{x}/{y}" ] }
@@ -484,7 +552,7 @@ TEST(Map, TEST_DISABLED_ON_CI(ContinuousRendering)) {
DefaultFileSource fileSource(":memory:", "test/fixtures/api/assets");
#endif
- Map map(backend, view.size, 1, fileSource, threadPool, MapMode::Continuous);
+ Map map(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Continuous);
using namespace std::chrono_literals;
@@ -507,6 +575,7 @@ TEST(Map, TEST_DISABLED_ON_CI(ContinuousRendering)) {
});
}
+ BackendScope scope(backend);
map.render(view);
}};
diff --git a/test/map/transform.test.cpp b/test/map/transform.test.cpp
index d5b98ac109..9125b6ef1d 100644
--- a/test/map/transform.test.cpp
+++ b/test/map/transform.test.cpp
@@ -343,12 +343,12 @@ TEST(Transform, Padding) {
ASSERT_DOUBLE_EQ(10, trueCenter.latitude);
ASSERT_DOUBLE_EQ(-100, trueCenter.longitude);
ASSERT_DOUBLE_EQ(10, transform.getZoom());
-
+
const LatLng manualShiftedCenter = transform.getState().screenCoordinateToLatLng({
1000.0 / 2.0,
1000.0 / 4.0,
});
-
+
EdgeInsets padding;
padding.top = 0;
@@ -359,7 +359,7 @@ TEST(Transform, Padding) {
padding.top = 1000.0 / 2.0;
ASSERT_TRUE(bool(padding));
-
+
const LatLng shiftedCenter = transform.getLatLng(padding);
ASSERT_NE(trueCenter.latitude, shiftedCenter.latitude);
ASSERT_NEAR(trueCenter.longitude, shiftedCenter.longitude, 1e-9);
diff --git a/test/math/wrap.test.cpp b/test/math/wrap.test.cpp
index 9ec1c6ef0c..5610257a5c 100644
--- a/test/math/wrap.test.cpp
+++ b/test/math/wrap.test.cpp
@@ -23,4 +23,4 @@ TEST(Math, WrapMaxValue) {
TEST(Math, WrapMinValue) {
ASSERT_DOUBLE_EQ(0.0, util::wrap(0.0, 0.0, 12.0));
-} \ No newline at end of file
+}
diff --git a/test/sprite/sprite_atlas.test.cpp b/test/sprite/sprite_atlas.test.cpp
index c9576013d4..2c425a95d2 100644
--- a/test/sprite/sprite_atlas.test.cpp
+++ b/test/sprite/sprite_atlas.test.cpp
@@ -15,14 +15,6 @@
using namespace mbgl;
-namespace {
-
-auto readImage(const std::string& name) {
- return decodeImage(util::read_file(name));
-}
-
-} // namespace
-
TEST(SpriteAtlas, Basic) {
FixtureLog log;
@@ -36,7 +28,7 @@ TEST(SpriteAtlas, Basic) {
EXPECT_EQ(63u, atlas.getSize().width);
EXPECT_EQ(112u, atlas.getSize().height);
- auto metro = *atlas.getImage("metro", SpritePatternMode::Single);
+ auto metro = *atlas.getIcon("metro");
EXPECT_EQ(0, metro.pos.x);
EXPECT_EQ(0, metro.pos.y);
EXPECT_EQ(20, metro.pos.w);
@@ -50,7 +42,7 @@ TEST(SpriteAtlas, Basic) {
EXPECT_EQ(63u, atlas.getAtlasImage().size.width);
EXPECT_EQ(112u, atlas.getAtlasImage().size.height);
- auto pos = *atlas.getPosition("metro", SpritePatternMode::Single);
+ auto pos = *atlas.getIcon("metro");
EXPECT_DOUBLE_EQ(18, pos.size[0]);
EXPECT_DOUBLE_EQ(18, pos.size[1]);
EXPECT_DOUBLE_EQ(1.0f / 63, pos.tl[0]);
@@ -58,7 +50,7 @@ TEST(SpriteAtlas, Basic) {
EXPECT_DOUBLE_EQ(19.0f / 63, pos.br[0]);
EXPECT_DOUBLE_EQ(19.0f / 112, pos.br[1]);
- auto missing = atlas.getImage("doesnotexist", SpritePatternMode::Single);
+ auto missing = atlas.getIcon("doesnotexist");
EXPECT_FALSE(missing);
EXPECT_EQ(1u, log.count({
@@ -69,13 +61,13 @@ TEST(SpriteAtlas, Basic) {
}));
// Different wrapping mode produces different image.
- auto metro2 = *atlas.getImage("metro", SpritePatternMode::Repeating);
+ auto metro2 = *atlas.getPattern("metro");
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(readImage("test/fixtures/annotations/result-spriteatlas.png"), atlas.getAtlasImage());
+ test::checkImage("test/fixtures/sprite_atlas/basic", atlas.getAtlasImage());
}
TEST(SpriteAtlas, Size) {
@@ -89,7 +81,7 @@ TEST(SpriteAtlas, Size) {
EXPECT_EQ(63u, atlas.getSize().width);
EXPECT_EQ(112u, atlas.getSize().height);
- auto metro = *atlas.getImage("metro", SpritePatternMode::Single);
+ auto metro = *atlas.getIcon("metro");
EXPECT_EQ(0, metro.pos.x);
EXPECT_EQ(0, metro.pos.y);
EXPECT_EQ(16, metro.pos.w);
@@ -104,8 +96,7 @@ TEST(SpriteAtlas, Size) {
EXPECT_EQ(89u, atlas.getAtlasImage().size.width);
EXPECT_EQ(157u, atlas.getAtlasImage().size.height);
- EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteatlassize.png"),
- atlas.getAtlasImage());
+ test::checkImage("test/fixtures/sprite_atlas/size", atlas.getAtlasImage());
}
TEST(SpriteAtlas, Updates) {
@@ -116,7 +107,7 @@ TEST(SpriteAtlas, Updates) {
EXPECT_EQ(32u, atlas.getSize().height);
atlas.setSprite("one", std::make_shared<SpriteImage>(PremultipliedImage({ 16, 12 }), 1));
- auto one = *atlas.getImage("one", SpritePatternMode::Single);
+ auto one = *atlas.getIcon("one");
EXPECT_EQ(0, one.pos.x);
EXPECT_EQ(0, one.pos.y);
EXPECT_EQ(20, one.pos.w);
@@ -131,8 +122,7 @@ TEST(SpriteAtlas, Updates) {
EXPECT_EQ(32u, atlas.getAtlasImage().size.width);
EXPECT_EQ(32u, atlas.getAtlasImage().size.height);
- EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteatlas-empty.png"),
- atlas.getAtlasImage());
+ test::checkImage("test/fixtures/sprite_atlas/updates_before", atlas.getAtlasImage());
// Update sprite
PremultipliedImage image2({ 16, 12 });
@@ -143,15 +133,7 @@ TEST(SpriteAtlas, Updates) {
atlas.setSprite("one", newSprite);
ASSERT_EQ(newSprite, atlas.getSprite("one"));
- // Atlas texture hasn't changed yet.
- EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteatlas-empty.png"),
- atlas.getAtlasImage());
-
- atlas.updateDirty();
-
- // Now the atlas texture has changed.
- EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteatlas-updated.png"),
- atlas.getAtlasImage());
+ test::checkImage("test/fixtures/sprite_atlas/updates_after", atlas.getAtlasImage());
}
TEST(SpriteAtlas, AddRemove) {
@@ -199,6 +181,25 @@ TEST(SpriteAtlas, AddRemove) {
atlas.setSprite("three", sprite1);
}
+TEST(SpriteAtlas, RemoveReleasesBinPackRect) {
+ FixtureLog log;
+
+ SpriteAtlas atlas({ 36, 36 }, 1);
+
+ const auto big = std::make_shared<SpriteImage>(PremultipliedImage({ 32, 32 }), 1);
+
+ atlas.setSprite("big", big);
+ EXPECT_TRUE(atlas.getIcon("big"));
+
+ atlas.removeSprite("big");
+
+ atlas.setSprite("big", big);
+ EXPECT_TRUE(atlas.getIcon("big"));
+
+ EXPECT_EQ(big, atlas.getSprite("big"));
+ EXPECT_TRUE(log.empty());
+}
+
TEST(SpriteAtlas, OtherPixelRatio) {
FixtureLog log;
diff --git a/test/src/mbgl/test/conversion_stubs.hpp b/test/src/mbgl/test/conversion_stubs.hpp
index ddffb1e3b2..e6581c5e53 100644
--- a/test/src/mbgl/test/conversion_stubs.hpp
+++ b/test/src/mbgl/test/conversion_stubs.hpp
@@ -24,7 +24,7 @@ class Value : public mbgl::variant<std::string,
};
inline bool isUndefined(const Value&) {
- //Variant is always intialized
+ // Variant is always intialized
return false;
}
diff --git a/test/src/mbgl/test/getrss.cpp b/test/src/mbgl/test/getrss.cpp
new file mode 100644
index 0000000000..9f57ad8e7b
--- /dev/null
+++ b/test/src/mbgl/test/getrss.cpp
@@ -0,0 +1,102 @@
+#include <mbgl/test/getrss.hpp>
+
+/*
+ * Adapted from
+ * http://nadeausoftware.com/articles/2012/07/c_c_tip_how_get_process_resident_set_size_physical_memory_use
+ *
+ * Author: David Robert Nadeau
+ * Site: http://NadeauSoftware.com/
+ * License: Creative Commons Attribution 3.0 Unported License
+ * http://creativecommons.org/licenses/by/3.0/deed.en_US
+ */
+
+namespace mbgl {
+namespace test {
+
+/**
+ * Returns the peak (maximum so far) resident set size (physical
+ * memory use) measured in bytes, or zero if the value cannot be
+ * determined on this OS.
+ */
+size_t getPeakRSS( )
+{
+#if defined(_WIN32)
+ /* Windows -------------------------------------------------- */
+ PROCESS_MEMORY_COUNTERS info;
+ GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
+ return (size_t)info.PeakWorkingSetSize;
+
+#elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
+ /* AIX and Solaris ------------------------------------------ */
+ struct psinfo psinfo;
+ int fd = -1;
+ if ( (fd = open( "/proc/self/psinfo", O_RDONLY )) == -1 )
+ return (size_t)0L; /* Can't open? */
+ if ( read( fd, &psinfo, sizeof(psinfo) ) != sizeof(psinfo) )
+ {
+ close( fd );
+ return (size_t)0L; /* Can't read? */
+ }
+ close( fd );
+ return (size_t)(psinfo.pr_rssize * 1024L);
+
+#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
+ /* BSD, Linux, and OSX -------------------------------------- */
+ struct rusage rusage;
+ getrusage( RUSAGE_SELF, &rusage );
+#if defined(__APPLE__) && defined(__MACH__)
+ return (size_t)rusage.ru_maxrss;
+#else
+ return (size_t)(rusage.ru_maxrss * 1024L);
+#endif
+
+#else
+ /* Unknown OS ----------------------------------------------- */
+ return (size_t)0L; /* Unsupported. */
+#endif
+}
+
+/**
+ * Returns the current resident set size (physical memory use) measured
+ * in bytes, or zero if the value cannot be determined on this OS.
+ */
+size_t getCurrentRSS( )
+{
+#if defined(_WIN32)
+ /* Windows -------------------------------------------------- */
+ PROCESS_MEMORY_COUNTERS info;
+ GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
+ return (size_t)info.WorkingSetSize;
+
+#elif defined(__APPLE__) && defined(__MACH__)
+ /* OSX ------------------------------------------------------ */
+ struct mach_task_basic_info info;
+ mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
+ if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO,
+ (task_info_t)&info, &infoCount ) != KERN_SUCCESS )
+ return (size_t)0L; /* Can't access? */
+ return (size_t)info.resident_size;
+
+#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
+ /* Linux ---------------------------------------------------- */
+ long rss = 0L;
+ FILE* fp = NULL;
+ if ( (fp = fopen( "/proc/self/statm", "r" )) == NULL )
+ return (size_t)0L; /* Can't open? */
+ if ( fscanf( fp, "%*s%ld", &rss ) != 1 )
+ {
+ fclose( fp );
+ return (size_t)0L; /* Can't read? */
+ }
+ fclose( fp );
+ return (size_t)rss * (size_t)sysconf( _SC_PAGESIZE);
+
+#else
+ /* AIX, BSD, Solaris, and Unknown OS ------------------------ */
+ return (size_t)0L; /* Unsupported. */
+#endif
+}
+
+} // namespace test
+} // namespace mbgl
+
diff --git a/test/src/mbgl/test/getrss.hpp b/test/src/mbgl/test/getrss.hpp
new file mode 100644
index 0000000000..a4420c4b5f
--- /dev/null
+++ b/test/src/mbgl/test/getrss.hpp
@@ -0,0 +1,45 @@
+#if defined(_WIN32)
+#include <windows.h>
+#include <psapi.h>
+
+#elif defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
+#include <unistd.h>
+#include <sys/resource.h>
+
+#if defined(__APPLE__) && defined(__MACH__)
+#include <mach/mach.h>
+#include <mach/message.h> // for mach_port_t
+#include <mach/task_info.h>
+
+#elif (defined(_AIX) || defined(__TOS__AIX__)) || (defined(__sun__) || defined(__sun) || defined(sun) && (defined(__SVR4) || defined(__svr4__)))
+#include <fcntl.h>
+#include <procfs.h>
+
+#elif defined(__linux__) || defined(__linux) || defined(linux) || defined(__gnu_linux__)
+#include <stdio.h>
+
+#endif
+
+#else
+#error "Cannot define getPeakRSS( ) or getCurrentRSS( ) for an unknown OS."
+#endif
+
+namespace mbgl {
+namespace test {
+
+
+/**
+ * Returns the peak (maximum so far) resident set size (physical
+ * memory use) measured in bytes, or zero if the value cannot be
+ * determined on this OS.
+ */
+size_t getPeakRSS();
+
+/**
+ * Returns the current resident set size (physical memory use) measured
+ * in bytes, or zero if the value cannot be determined on this OS.
+ */
+size_t getCurrentRSS();
+
+}
+}
diff --git a/test/src/mbgl/test/stub_geometry_tile_feature.hpp b/test/src/mbgl/test/stub_geometry_tile_feature.hpp
new file mode 100644
index 0000000000..21d198a96b
--- /dev/null
+++ b/test/src/mbgl/test/stub_geometry_tile_feature.hpp
@@ -0,0 +1,34 @@
+#include <mbgl/tile/geometry_tile_data.hpp>
+#include <mbgl/util/feature.hpp>
+
+namespace mbgl {
+
+class StubGeometryTileFeature : public GeometryTileFeature {
+public:
+ StubGeometryTileFeature(PropertyMap properties_)
+ : properties(std::move(properties_)) {
+ }
+
+ PropertyMap properties;
+ optional<FeatureIdentifier> id = {};
+ FeatureType type = FeatureType::Point;
+ GeometryCollection geometry = {};
+
+ FeatureType getType() const override {
+ return type;
+ }
+
+ optional<FeatureIdentifier> getID() const override {
+ return id;
+ }
+
+ optional<Value> getValue(const std::string& key) const override {
+ return properties.count(key) ? properties.at(key) : optional<Value>();
+ }
+
+ GeometryCollection getGeometries() const override {
+ return geometry;
+ }
+};
+
+} // namespace mbgl
diff --git a/test/src/mbgl/test/stub_layer_observer.hpp b/test/src/mbgl/test/stub_layer_observer.hpp
index 07797ce921..9acd4b077a 100644
--- a/test/src/mbgl/test/stub_layer_observer.hpp
+++ b/test/src/mbgl/test/stub_layer_observer.hpp
@@ -22,6 +22,10 @@ public:
if (layerPaintPropertyChanged) layerPaintPropertyChanged(layer);
}
+ void onLayerDataDrivenPaintPropertyChanged(Layer& layer) override {
+ if (layerDataDrivenPaintPropertyChanged) layerDataDrivenPaintPropertyChanged(layer);
+ }
+
void onLayerLayoutPropertyChanged(Layer& layer, const char * property) override {
if (layerLayoutPropertyChanged) layerLayoutPropertyChanged(layer, property);
}
@@ -29,5 +33,6 @@ public:
std::function<void (Layer&)> layerFilterChanged;
std::function<void (Layer&)> layerVisibilityChanged;
std::function<void (Layer&)> layerPaintPropertyChanged;
+ std::function<void (Layer&)> layerDataDrivenPaintPropertyChanged;
std::function<void (Layer&, const char *)> layerLayoutPropertyChanged;
};
diff --git a/test/src/mbgl/test/util.hpp b/test/src/mbgl/test/util.hpp
index 34d8969d3c..82d5c520f8 100644
--- a/test/src/mbgl/test/util.hpp
+++ b/test/src/mbgl/test/util.hpp
@@ -21,7 +21,7 @@
#define TEST_IS_SIMULATOR 0
#endif
-#if !TEST_IS_SIMULATOR
+#if !TEST_IS_SIMULATOR && !CI_BUILD
#define TEST_REQUIRES_ACCURATE_TIMING(name) name
#else
#define TEST_REQUIRES_ACCURATE_TIMING(name) DISABLED_ ## name
diff --git a/test/storage/default_file_source.test.cpp b/test/storage/default_file_source.test.cpp
index f4c23c4c7a..03f1076559 100644
--- a/test/storage/default_file_source.test.cpp
+++ b/test/storage/default_file_source.test.cpp
@@ -267,6 +267,22 @@ TEST(DefaultFileSource, OptionalExpired) {
loop.run();
}
+TEST(DefaultFileSource, GetBaseURLAndAccessTokenWhilePaused) {
+ util::RunLoop loop;
+ DefaultFileSource fs(":memory:", ".");
+
+ fs.pause();
+
+ auto baseURL = "http://url";
+ auto accessToken = "access_token";
+
+ fs.setAPIBaseURL(baseURL);
+ fs.setAccessToken(accessToken);
+
+ EXPECT_EQ(fs.getAPIBaseURL(), baseURL);
+ EXPECT_EQ(fs.getAccessToken(), accessToken);
+}
+
TEST(DefaultFileSource, OptionalNotFound) {
util::RunLoop loop;
DefaultFileSource fs(":memory:", ".");
@@ -460,3 +476,33 @@ TEST(DefaultFileSource, TEST_REQUIRES_SERVER(NoCacheRefreshModifiedModified)) {
loop.run();
}
+
+TEST(DefaultFileSource, TEST_REQUIRES_SERVER(SetResourceTransform)) {
+ util::RunLoop loop;
+ DefaultFileSource fs(":memory:", ".");
+
+ // Translates the URL "localhost://test to http://127.0.0.1:3000/test
+ fs.setResourceTransform([](Resource::Kind, std::string&& url) -> std::string {
+ if (url == "localhost://test") {
+ return "http://127.0.0.1:3000/test";
+ } else {
+ return std::move(url);
+ }
+ });
+
+ const Resource resource { Resource::Unknown, "localhost://test" };
+
+ std::unique_ptr<AsyncRequest> req;
+ req = fs.request(resource, [&](Response res) {
+ req.reset();
+ EXPECT_EQ(nullptr, res.error);
+ ASSERT_TRUE(res.data.get());
+ EXPECT_EQ("Hello World!", *res.data);
+ EXPECT_FALSE(bool(res.expires));
+ EXPECT_FALSE(bool(res.modified));
+ EXPECT_FALSE(bool(res.etag));
+ loop.stop();
+ });
+
+ loop.run();
+}
diff --git a/test/storage/local_file_source.test.cpp b/test/storage/local_file_source.test.cpp
index c2f04d7543..1b90e5bb1e 100644
--- a/test/storage/local_file_source.test.cpp
+++ b/test/storage/local_file_source.test.cpp
@@ -104,14 +104,14 @@ TEST(LocalFileSource, URLEncoding) {
TEST(LocalFileSource, URLLimit) {
util::RunLoop loop;
-
+
size_t length = PATH_MAX - toAbsoluteURL("").size();
LocalFileSource fs;
char filename[length];
memset(filename, 'x', length);
-
+
std::string url(filename, length);
-
+
std::unique_ptr<AsyncRequest> req = fs.request({ Resource::Unknown, toAbsoluteURL(url) }, [&](Response res) {
req.reset();
ASSERT_NE(nullptr, res.error);
@@ -119,6 +119,6 @@ TEST(LocalFileSource, URLLimit) {
ASSERT_FALSE(res.data.get());
loop.stop();
});
-
+
loop.run();
}
diff --git a/test/storage/offline_database.test.cpp b/test/storage/offline_database.test.cpp
index 2e25835d80..872310e46f 100644
--- a/test/storage/offline_database.test.cpp
+++ b/test/storage/offline_database.test.cpp
@@ -276,12 +276,12 @@ TEST(OfflineDatabase, CreateRegion) {
TEST(OfflineDatabase, UpdateMetadata) {
using namespace mbgl;
-
+
OfflineDatabase db(":memory:");
OfflineRegionDefinition definition { "http://example.com/style", LatLngBounds::hull({1, 2}, {3, 4}), 5, 6, 2.0 };
OfflineRegionMetadata metadata {{ 1, 2, 3 }};
OfflineRegion region = db.createRegion(definition, metadata);
-
+
OfflineRegionMetadata newmetadata {{ 4, 5, 6 }};
db.updateMetadata(region.getID(), newmetadata);
EXPECT_EQ(db.listRegions().at(0).getMetadata(), newmetadata);
diff --git a/test/storage/online_file_source.test.cpp b/test/storage/online_file_source.test.cpp
index 966ef6239a..1a1d2d42f8 100644
--- a/test/storage/online_file_source.test.cpp
+++ b/test/storage/online_file_source.test.cpp
@@ -364,7 +364,7 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(NetworkStatusOnlineOffline)) {
TEST(OnlineFileSource, TEST_REQUIRES_SERVER(RateLimitStandard)) {
util::RunLoop loop;
OnlineFileSource fs;
-
+
auto req = fs.request({ Resource::Unknown, "http://127.0.0.1:3000/rate-limit?std=true" }, [&](Response res) {
ASSERT_NE(nullptr, res.error);
EXPECT_EQ(Response::Error::Reason::RateLimit, res.error->reason);
@@ -372,14 +372,14 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(RateLimitStandard)) {
ASSERT_LT(util::now(), res.error->retryAfter);
loop.stop();
});
-
+
loop.run();
}
TEST(OnlineFileSource, TEST_REQUIRES_SERVER(RateLimitMBX)) {
util::RunLoop loop;
OnlineFileSource fs;
-
+
auto req = fs.request({ Resource::Unknown, "http://127.0.0.1:3000/rate-limit?mbx=true" }, [&](Response res) {
ASSERT_NE(nullptr, res.error);
EXPECT_EQ(Response::Error::Reason::RateLimit, res.error->reason);
@@ -387,28 +387,28 @@ TEST(OnlineFileSource, TEST_REQUIRES_SERVER(RateLimitMBX)) {
ASSERT_LT(util::now(), res.error->retryAfter);
loop.stop();
});
-
+
loop.run();
}
TEST(OnlineFileSource, TEST_REQUIRES_SERVER(RateLimitDefault)) {
util::RunLoop loop;
OnlineFileSource fs;
-
+
auto req = fs.request({ Resource::Unknown, "http://127.0.0.1:3000/rate-limit" }, [&](Response res) {
ASSERT_NE(nullptr, res.error);
EXPECT_EQ(Response::Error::Reason::RateLimit, res.error->reason);
ASSERT_FALSE(res.error->retryAfter);
loop.stop();
});
-
+
loop.run();
}
TEST(OnlineFileSource, ChangeAPIBaseURL){
util::RunLoop loop;
OnlineFileSource fs;
-
+
EXPECT_EQ(mbgl::util::API_BASE_URL, fs.getAPIBaseURL());
const std::string customURL = "test.domain";
fs.setAPIBaseURL(customURL);
diff --git a/test/storage/server.js b/test/storage/server.js
index a7538b55f1..b54ff835ec 100755
--- a/test/storage/server.js
+++ b/test/storage/server.js
@@ -117,16 +117,47 @@ app.get('/temporary-error', function(req, res) {
});
app.get('/rate-limit', function(req, res) {
-
+
if (req.query.std) {
res.setHeader('Retry-After', 1);
} else if (req.query.mbx) {
res.setHeader('x-rate-limit-reset', Math.round(Date.now() / 1000) + 1);
}
-
+
res.status(429).end();
});
+var styleFailOnce500 = true;
+app.get('/style-fail-once-500', function (req, res) {
+ if (styleFailOnce500) {
+ res.status(500).send('Server Error!');
+ styleFailOnce500 = false;
+ } else {
+ res.status(200).send('{ "version": 8, "name": "Teste Style" }');
+ }
+});
+
+var styleFailOnce404 = true;
+app.get('/style-fail-once-404', function (req, res) {
+ if (styleFailOnce404) {
+ res.status(404).send('Not found!');
+ styleFailOnce404 = false;
+ } else {
+ res.status(200).send('{ "version": 8, "name": "Teste Style" }');
+ }
+});
+
+var styleFailOnce404Cache = true;
+app.get('/style-fail-once-404-cache', function (req, res) {
+ if (styleFailOnce404Cache) {
+ res.setHeader('Cache-Control', 'max-age=30');
+ res.status(404).send('Not found!');
+ styleFailOnce404Cache = false;
+ } else {
+ res.status(200).send('{ "version": 8, "name": "Teste Style" }');
+ }
+});
+
app.get('/delayed', function(req, res) {
setTimeout(function() {
res.status(200).send('Response');
diff --git a/test/storage/sqlite.test.cpp b/test/storage/sqlite.test.cpp
new file mode 100644
index 0000000000..dbd7a09868
--- /dev/null
+++ b/test/storage/sqlite.test.cpp
@@ -0,0 +1,27 @@
+#include <mbgl/test/util.hpp>
+
+#include <gtest/gtest.h>
+#include <sqlite3.hpp>
+
+TEST(SQLite, Statement) {
+ using namespace mbgl;
+
+ mapbox::sqlite::Database db(":memory:", mapbox::sqlite::Create | mapbox::sqlite::ReadWrite);
+ db.exec("CREATE TABLE test (id INTEGER);");
+
+ mapbox::sqlite::Statement stmt1 = db.prepare("INSERT INTO test (id) VALUES (?1);");
+ ASSERT_EQ(stmt1.lastInsertRowId(), 0);
+ ASSERT_EQ(stmt1.changes(), 0u);
+ stmt1.bind(1, 10);
+ stmt1.run();
+ ASSERT_EQ(stmt1.lastInsertRowId(), 1);
+ ASSERT_EQ(stmt1.changes(), 1u);
+
+ mapbox::sqlite::Statement stmt2 = db.prepare("INSERT INTO test (id) VALUES (?1);");
+ ASSERT_EQ(stmt2.lastInsertRowId(), 0);
+ ASSERT_EQ(stmt2.changes(), 0u);
+ stmt2.bind(1, 20);
+ stmt2.run();
+ ASSERT_EQ(stmt2.lastInsertRowId(), 2);
+ ASSERT_EQ(stmt2.changes(), 1u);
+}
diff --git a/test/style/conversion/function.test.cpp b/test/style/conversion/function.test.cpp
index e93207ea13..5a3ec93917 100644
--- a/test/style/conversion/function.test.cpp
+++ b/test/style/conversion/function.test.cpp
@@ -13,7 +13,7 @@ using namespace mbgl::style::conversion;
auto parseFunction(const std::string& src) {
JSDocument doc;
doc.Parse<0>(src);
- return convert<Function<float>>(doc);
+ return convert<CameraFunction<float>>(doc);
}
TEST(StyleConversion, Function) {
diff --git a/test/style/conversion/geojson_options.test.cpp b/test/style/conversion/geojson_options.test.cpp
index 14a7adbba7..ddf261ea52 100644
--- a/test/style/conversion/geojson_options.test.cpp
+++ b/test/style/conversion/geojson_options.test.cpp
@@ -28,13 +28,13 @@ TEST(GeoJSONOptions, RetainsDefaults) {
Value raw(map);
GeoJSONOptions converted = *convert<GeoJSONOptions>(raw);
GeoJSONOptions defaults;
-
- //GeoJSON-VT
+
+ // GeoJSON-VT
ASSERT_EQ(converted.maxzoom, defaults.maxzoom);
ASSERT_EQ(converted.buffer, defaults.buffer);
ASSERT_EQ(converted.tolerance, defaults.tolerance);
-
- //Supercluster
+
+ // Supercluster
ASSERT_EQ(converted.cluster, defaults.cluster);
ASSERT_EQ(converted.clusterRadius, defaults.clusterRadius);
ASSERT_EQ(converted.clusterMaxZoom, defaults.clusterMaxZoom);
@@ -43,25 +43,25 @@ TEST(GeoJSONOptions, RetainsDefaults) {
TEST(GeoJSONOptions, FullConversion) {
ValueMap map {
- //GeoJSON-VT
+ // GeoJSON-VT
{"maxzoom", 1.0f},
{"buffer", 2.0f},
{"tolerance", 3.0f},
-
- //Supercluster
+
+ // Supercluster
{"cluster", true},
{"clusterRadius", 4.0f},
{"clusterMaxZoom", 5.0f}
};
Value raw(map);
GeoJSONOptions converted = *convert<GeoJSONOptions>(raw);
-
- //GeoJSON-VT
+
+ // GeoJSON-VT
ASSERT_EQ(converted.maxzoom, 1);
ASSERT_EQ(converted.buffer, 2);
ASSERT_EQ(converted.tolerance, 3);
-
- //Supercluster
+
+ // Supercluster
ASSERT_EQ(converted.cluster, true);
ASSERT_EQ(converted.clusterRadius, 4);
ASSERT_EQ(converted.clusterMaxZoom, 5);
diff --git a/test/style/conversion/layer.test.cpp b/test/style/conversion/layer.test.cpp
new file mode 100644
index 0000000000..b27c1841ee
--- /dev/null
+++ b/test/style/conversion/layer.test.cpp
@@ -0,0 +1,46 @@
+#include <mbgl/test/util.hpp>
+
+#include <mbgl/style/conversion.hpp>
+#include <mbgl/style/rapidjson_conversion.hpp>
+#include <mbgl/style/conversion/layer.hpp>
+#include <mbgl/style/layers/background_layer_impl.hpp>
+#include <mbgl/util/rapidjson.hpp>
+
+using namespace mbgl;
+using namespace mbgl::style;
+using namespace mbgl::style::conversion;
+using namespace std::literals::chrono_literals;
+
+auto parseLayer(const std::string& src) {
+ JSDocument doc;
+ doc.Parse<0>(src);
+ return convert<std::unique_ptr<Layer>, JSValue>(doc);
+}
+
+TEST(StyleConversion, LayerTransition) {
+ auto layer = parseLayer(R"JSON({
+ "type": "background",
+ "id": "background",
+ "paint": {
+ "background-color-transition": {
+ "duration": 400,
+ "delay": 500
+ }
+ },
+ "paint.class": {
+ "background-color-transition": {
+ "duration": 100
+ }
+ }
+ })JSON");
+
+ ASSERT_EQ(400ms, *(*layer)->as<BackgroundLayer>()->impl->paint.cascading
+ .get<BackgroundColor>().getTransition({}).duration);
+ ASSERT_EQ(500ms, *(*layer)->as<BackgroundLayer>()->impl->paint.cascading
+ .get<BackgroundColor>().getTransition({}).delay);
+
+ ASSERT_EQ(100ms, *(*layer)->as<BackgroundLayer>()->impl->paint.cascading
+ .get<BackgroundColor>().getTransition({"class"}).duration);
+ ASSERT_FALSE(bool((*layer)->as<BackgroundLayer>()->impl->paint.cascading
+ .get<BackgroundColor>().getTransition({"class"}).delay));
+}
diff --git a/test/style/conversion/stringify.test.cpp b/test/style/conversion/stringify.test.cpp
index be5d65d4ce..1dae20b26b 100644
--- a/test/style/conversion/stringify.test.cpp
+++ b/test/style/conversion/stringify.test.cpp
@@ -79,13 +79,45 @@ TEST(Stringify, Filter) {
ASSERT_EQ(stringify(EqualsFilter { "a", 1.0 }), "[\"==\",\"a\",1.0]");
}
-TEST(Stringify, Function) {
- ASSERT_EQ(stringify(Function<float>({{0, 1}}, 2)), "{\"base\":2.0,\"stops\":[[0.0,1.0]]}");
+TEST(Stringify, CameraFunction) {
+ ASSERT_EQ(stringify(CameraFunction<float>(ExponentialStops<float> { {{0, 1}}, 2 })),
+ "{\"type\":\"exponential\",\"base\":2.0,\"stops\":[[0.0,1.0]]}");
+ ASSERT_EQ(stringify(CameraFunction<float>(IntervalStops<float> { {{0, 1}} })),
+ "{\"type\":\"interval\",\"stops\":[[0.0,1.0]]}");
+}
+
+TEST(Stringify, SourceFunction) {
+ ASSERT_EQ(stringify(SourceFunction<float>("property", ExponentialStops<float> { {{0, 1}}, 2 })),
+ "{\"property\":\"property\",\"type\":\"exponential\",\"base\":2.0,\"stops\":[[0.0,1.0]]}");
+ ASSERT_EQ(stringify(SourceFunction<float>("property", IntervalStops<float> { {{0, 1}} })),
+ "{\"property\":\"property\",\"type\":\"interval\",\"stops\":[[0.0,1.0]]}");
+ ASSERT_EQ(stringify(SourceFunction<float>("property", CategoricalStops<float> { {{CategoricalValue(true), 1}} })),
+ "{\"property\":\"property\",\"type\":\"categorical\",\"stops\":[[true,1.0]]}");
+ ASSERT_EQ(stringify(SourceFunction<float>("property", IdentityStops<float> {})),
+ "{\"property\":\"property\",\"type\":\"identity\"}");
+ ASSERT_EQ(stringify(SourceFunction<float>("property", IdentityStops<float> {}, 0.0f)),
+ "{\"property\":\"property\",\"type\":\"identity\",\"default\":0.0}");
+}
+
+TEST(Stringify, CompositeFunction) {
+ ASSERT_EQ(stringify(CompositeFunction<float>("property",
+ CompositeExponentialStops<float> {
+ {
+ { 0, {{0, 1}} },
+ { 1, {{0, 1}} }
+ },
+ 2
+ }, 0.0f)),
+ "{\"property\":\"property\",\"type\":\"exponential\",\"base\":2.0,"
+ "\"stops\":["
+ "[{\"zoom\":0.0,\"value\":0.0},1.0],"
+ "[{\"zoom\":1.0,\"value\":0.0},1.0]],\"default\":0.0}");
}
TEST(Stringify, PropertyValue) {
ASSERT_EQ(stringify(PropertyValue<float>(1)), "1.0");
- ASSERT_EQ(stringify(PropertyValue<float>(Function<float>({{0, 1}}, 2))), "{\"base\":2.0,\"stops\":[[0.0,1.0]]}");
+ ASSERT_EQ(stringify(PropertyValue<float>(CameraFunction<float>(ExponentialStops<float> { {{0, 1}}, 2 }))),
+ "{\"type\":\"exponential\",\"base\":2.0,\"stops\":[[0.0,1.0]]}");
}
TEST(Stringify, Layout) {
diff --git a/test/style/functions.test.cpp b/test/style/function/camera_function.test.cpp
index 8553d13349..6cd53b0fa0 100644
--- a/test/style/functions.test.cpp
+++ b/test/style/function/camera_function.test.cpp
@@ -17,7 +17,7 @@ bool evaluate(PropertyValue<bool> value, float zoom) {
return value.evaluate(PropertyEvaluator<bool>(PropertyEvaluationParameters(zoom), false));
}
-TEST(Function, Constant) {
+TEST(CameraFunction, Constant) {
EXPECT_EQ(2.0f, evaluate(PropertyValue<float>(2.0), 0));
EXPECT_EQ(3.8f, evaluate(PropertyValue<float>(3.8), 0));
EXPECT_EQ(22.0f, evaluate(PropertyValue<float>(22.0), 0));
@@ -29,9 +29,9 @@ TEST(Function, Constant) {
EXPECT_EQ(22.0f, evaluate(PropertyValue<float>(22.0), 22));
}
-TEST(Function, Stops) {
+TEST(CameraFunction, Stops) {
// Explicit constant slope in fringe regions.
- Function<float> slope_1({ { 0, 1.5 }, { 6, 1.5 }, { 8, 3 }, { 22, 3 } }, 1.75);
+ CameraFunction<float> slope_1(ExponentialStops<float> { { { 0, 1.5 }, { 6, 1.5 }, { 8, 3 }, { 22, 3 } }, 1.75});
EXPECT_EQ(1.5, evaluate(slope_1, 0));
EXPECT_EQ(1.5, evaluate(slope_1, 4));
EXPECT_EQ(1.5, evaluate(slope_1, 6));
@@ -43,7 +43,7 @@ TEST(Function, Stops) {
// Test constant values in fringe regions.
- Function<float> slope_2({ { 6, 1.5 }, { 8, 3 } }, 1.75);
+ CameraFunction<float> slope_2(ExponentialStops<float> { { { 6, 1.5 }, { 8, 3 } }, 1.75 });
EXPECT_EQ(1.5, evaluate(slope_2, 0));
EXPECT_EQ(1.5, evaluate(slope_2, 4));
EXPECT_EQ(1.5, evaluate(slope_2, 6));
@@ -55,7 +55,7 @@ TEST(Function, Stops) {
// Explicit constant slope in fringe regions.
- Function<float> slope_4({ { 0, 2 }, { 8, 10 } }, 1);
+ CameraFunction<float> slope_4(ExponentialStops<float> { { { 0, 2 }, { 8, 10 } }, 1 });
EXPECT_EQ(2, evaluate(slope_4, 0));
EXPECT_EQ(3, evaluate(slope_4, 1));
EXPECT_EQ(4, evaluate(slope_4, 2));
@@ -63,14 +63,14 @@ TEST(Function, Stops) {
EXPECT_EQ(10, evaluate(slope_4, 8));
// discrete values
- Function<std::string> discrete_0({{3, "string0"}, {6, "string1"}, {9, "string2"}}, 1);
+ CameraFunction<std::string> discrete_0(IntervalStops<std::string> { {{3, "string0"}, {6, "string1"}, {9, "string2"}} });
EXPECT_EQ("string0", evaluate(discrete_0, 2));
EXPECT_EQ("string0", evaluate(discrete_0, 4));
EXPECT_EQ("string1", evaluate(discrete_0, 7));
EXPECT_EQ("string2", evaluate(discrete_0, 9));
EXPECT_EQ("string2", evaluate(discrete_0, 10));
- Function<bool> discreteBool({{1, false}, {3, true}}, 1);
+ CameraFunction<bool> discreteBool(IntervalStops<bool> { {{1, false}, {3, true}} });
EXPECT_FALSE(evaluate(discreteBool, 0));
EXPECT_FALSE(evaluate(discreteBool, 1));
EXPECT_FALSE(evaluate(discreteBool, 2));
diff --git a/test/style/function/source_function.test.cpp b/test/style/function/source_function.test.cpp
new file mode 100644
index 0000000000..260620c8d0
--- /dev/null
+++ b/test/style/function/source_function.test.cpp
@@ -0,0 +1,94 @@
+#include <mbgl/test/util.hpp>
+#include <mbgl/test/stub_geometry_tile_feature.hpp>
+
+#include <mbgl/style/function/source_function.hpp>
+
+using namespace mbgl;
+using namespace mbgl::style;
+
+using namespace std::string_literals;
+
+static StubGeometryTileFeature oneInteger {
+ PropertyMap {{ "property", uint64_t(1) }}
+};
+
+static StubGeometryTileFeature oneDouble {
+ PropertyMap {{ "property", 1.0 }}
+};
+
+static StubGeometryTileFeature oneString {
+ PropertyMap {{ "property", "1"s }}
+};
+
+static StubGeometryTileFeature red {
+ PropertyMap {{ "property", "red"s }}
+};
+
+static StubGeometryTileFeature oneTwoInteger {
+ PropertyMap {{ "property", std::vector<Value>({uint64_t(1), uint64_t(2)}) }}
+};
+
+static StubGeometryTileFeature oneTwoDouble {
+ PropertyMap {{ "property", std::vector<Value>({1.0, 2.0}) }}
+};
+
+static StubGeometryTileFeature oneTwoString {
+ PropertyMap {{ "property", std::vector<Value>({"1"s, "2"s}) }}
+};
+
+static StubGeometryTileFeature trueFeature {
+ PropertyMap {{ "property", true }}
+};
+
+static StubGeometryTileFeature falseFeature {
+ PropertyMap {{ "property", false }}
+};
+
+TEST(SourceFunction, Identity) {
+ EXPECT_EQ(1.0f, SourceFunction<float>("property", IdentityStops<float>(), 0.0f)
+ .evaluate(oneInteger, 2.0f));
+ EXPECT_EQ(1.0f, SourceFunction<float>("property", IdentityStops<float>(), 0.0f)
+ .evaluate(oneDouble, 2.0f));
+ EXPECT_EQ(0.0f, SourceFunction<float>("property", IdentityStops<float>(), 0.0f)
+ .evaluate(oneString, 2.0f));
+ EXPECT_EQ(2.0f, SourceFunction<float>("property", IdentityStops<float>())
+ .evaluate(oneString, 2.0f));
+
+ EXPECT_EQ(Color::red(), SourceFunction<Color>("property", IdentityStops<Color>(), Color::black())
+ .evaluate(red, Color::black()));
+ EXPECT_EQ(Color::black(), SourceFunction<Color>("property", IdentityStops<Color>(), Color::black())
+ .evaluate(oneInteger, Color::black()));
+
+ std::array<float, 2> zeroArray {{ 0, 0 }};
+ EXPECT_EQ((std::array<float, 2> {{ 1, 2 }}), (SourceFunction<std::array<float, 2>>("property", IdentityStops<std::array<float, 2>>(), zeroArray)
+ .evaluate(oneTwoInteger, zeroArray)));
+ EXPECT_EQ((std::array<float, 2> {{ 1, 2 }}), (SourceFunction<std::array<float, 2>>("property", IdentityStops<std::array<float, 2>>(), zeroArray)
+ .evaluate(oneTwoDouble, zeroArray)));
+ EXPECT_EQ((std::array<float, 2> {{ 0, 0 }}), (SourceFunction<std::array<float, 2>>("property", IdentityStops<std::array<float, 2>>(), zeroArray)
+ .evaluate(oneTwoString, zeroArray)));
+}
+
+TEST(SourceFunction, Categorical) {
+ EXPECT_EQ(1.0f, SourceFunction<float>("property", CategoricalStops<float>({{ int64_t(1), 1.0f }}))
+ .evaluate(oneInteger, 0.0f));
+ EXPECT_EQ(1.0f, SourceFunction<float>("property", CategoricalStops<float>({{ int64_t(1), 1.0f }}))
+ .evaluate(oneDouble, 0.0f));
+ EXPECT_EQ(0.0f, SourceFunction<float>("property", CategoricalStops<float>({{ int64_t(1), 1.0f }}))
+ .evaluate(oneString, 0.0f));
+
+ EXPECT_EQ(0.0f, SourceFunction<float>("property", CategoricalStops<float>({{ "1"s, 1.0f }}))
+ .evaluate(oneInteger, 0.0f));
+ EXPECT_EQ(0.0f, SourceFunction<float>("property", CategoricalStops<float>({{ "1"s, 1.0f }}))
+ .evaluate(oneDouble, 0.0f));
+ EXPECT_EQ(1.0f, SourceFunction<float>("property", CategoricalStops<float>({{ "1"s, 1.0f }}))
+ .evaluate(oneString, 0.0f));
+
+ EXPECT_EQ(1.0f, SourceFunction<float>("property", CategoricalStops<float>({{ true, 1.0f }}))
+ .evaluate(trueFeature, 0.0f));
+ EXPECT_EQ(0.0f, SourceFunction<float>("property", CategoricalStops<float>({{ true, 1.0f }}))
+ .evaluate(falseFeature, 0.0f));
+ EXPECT_EQ(0.0f, SourceFunction<float>("property", CategoricalStops<float>({{ false, 1.0f }}))
+ .evaluate(trueFeature, 0.0f));
+ EXPECT_EQ(1.0f, SourceFunction<float>("property", CategoricalStops<float>({{ false, 1.0f }}))
+ .evaluate(falseFeature, 0.0f));
+}
diff --git a/test/style/paint_property.test.cpp b/test/style/paint_property.test.cpp
index 487dbe9652..c70fa101ca 100644
--- a/test/style/paint_property.test.cpp
+++ b/test/style/paint_property.test.cpp
@@ -6,54 +6,59 @@ using namespace mbgl;
using namespace mbgl::style;
using namespace std::literals::chrono_literals;
+float evaluate(UnevaluatedPaintProperty<PropertyValue<float>>& property, Duration delta = Duration::zero()) {
+ PropertyEvaluationParameters parameters {
+ 0,
+ TimePoint::min() + delta,
+ ZoomHistory(),
+ Duration::zero()
+ };
+
+ PropertyEvaluator<float> evaluator {
+ parameters,
+ 0.0f
+ };
+
+ return property.evaluate(evaluator, parameters.now);
+}
+
TEST(UnevaluatedPaintProperty, EvaluateDefaultValue) {
- UnevaluatedPaintProperty<float, PropertyEvaluator<float>> property;
- ASSERT_EQ(0.0f, property.evaluate(PropertyEvaluationParameters(0), 0.0f));
+ UnevaluatedPaintProperty<PropertyValue<float>> property;
+ ASSERT_EQ(0.0f, evaluate(property));
}
TEST(UnevaluatedPaintProperty, EvaluateUntransitionedConstant) {
- UnevaluatedPaintProperty<float, PropertyEvaluator<float>> property {
+ UnevaluatedPaintProperty<PropertyValue<float>> property {
PropertyValue<float>(1.0f),
- UnevaluatedPaintProperty<float, PropertyEvaluator<float>>(),
+ UnevaluatedPaintProperty<PropertyValue<float>>(),
TransitionOptions(),
TimePoint::min()
};
- ASSERT_EQ(1.0f, property.evaluate(PropertyEvaluationParameters(0), 0.0f));
+ ASSERT_EQ(1.0f, evaluate(property));
}
TEST(UnevaluatedPaintProperty, EvaluateTransitionedConstantWithoutDelay) {
TransitionOptions transition;
transition.duration = { 1000ms };
- UnevaluatedPaintProperty<float, PropertyEvaluator<float>> t0 {
+ UnevaluatedPaintProperty<PropertyValue<float>> t0 {
PropertyValue<float>(0.0f),
- UnevaluatedPaintProperty<float, PropertyEvaluator<float>>(),
+ UnevaluatedPaintProperty<PropertyValue<float>>(),
TransitionOptions(),
TimePoint::min()
};
- UnevaluatedPaintProperty<float, PropertyEvaluator<float>> t1 {
+ UnevaluatedPaintProperty<PropertyValue<float>> t1 {
PropertyValue<float>(1.0f),
t0,
transition,
TimePoint::min()
};
- auto evaluate = [&] (Duration delta) {
- PropertyEvaluationParameters parameters {
- 0,
- TimePoint::min() + delta,
- ZoomHistory(),
- Duration::zero()
- };
-
- return t1.evaluate(parameters, 0.0f);
- };
-
- ASSERT_FLOAT_EQ(0.0f, evaluate(0ms));
- ASSERT_FLOAT_EQ(0.823099f, evaluate(500ms));
- ASSERT_FLOAT_EQ(1.0f, evaluate(1500ms));
+ ASSERT_FLOAT_EQ(0.0f, evaluate(t1, 0ms));
+ ASSERT_FLOAT_EQ(0.823099f, evaluate(t1, 500ms));
+ ASSERT_FLOAT_EQ(1.0f, evaluate(t1, 1500ms));
}
TEST(UnevaluatedPaintProperty, EvaluateTransitionedConstantWithDelay) {
@@ -61,34 +66,23 @@ TEST(UnevaluatedPaintProperty, EvaluateTransitionedConstantWithDelay) {
transition.delay = { 1000ms };
transition.duration = { 1000ms };
- UnevaluatedPaintProperty<float, PropertyEvaluator<float>> t0 {
+ UnevaluatedPaintProperty<PropertyValue<float>> t0 {
PropertyValue<float>(0.0f),
- UnevaluatedPaintProperty<float, PropertyEvaluator<float>>(),
+ UnevaluatedPaintProperty<PropertyValue<float>>(),
TransitionOptions(),
TimePoint::min()
};
- UnevaluatedPaintProperty<float, PropertyEvaluator<float>> t1 {
+ UnevaluatedPaintProperty<PropertyValue<float>> t1 {
PropertyValue<float>(1.0f),
t0,
transition,
TimePoint::min()
};
- auto evaluate = [&] (Duration delta) {
- PropertyEvaluationParameters parameters {
- 0,
- TimePoint::min() + delta,
- ZoomHistory(),
- Duration::zero()
- };
-
- return t1.evaluate(parameters, 0.0f);
- };
-
- ASSERT_FLOAT_EQ(0.0f, evaluate(0ms));
- ASSERT_FLOAT_EQ(0.0f, evaluate(500ms));
- ASSERT_FLOAT_EQ(0.0f, evaluate(612ms));
- ASSERT_FLOAT_EQ(0.823099f, evaluate(1500ms));
- ASSERT_FLOAT_EQ(1.0f, evaluate(2500ms));
+ ASSERT_FLOAT_EQ(0.0f, evaluate(t1, 0ms));
+ ASSERT_FLOAT_EQ(0.0f, evaluate(t1, 500ms));
+ ASSERT_FLOAT_EQ(0.0f, evaluate(t1, 612ms));
+ ASSERT_FLOAT_EQ(0.823099f, evaluate(t1, 1500ms));
+ ASSERT_FLOAT_EQ(1.0f, evaluate(t1, 2500ms));
}
diff --git a/test/style/source.test.cpp b/test/style/source.test.cpp
index 01f54d6b18..fb7737e417 100644
--- a/test/style/source.test.cpp
+++ b/test/style/source.test.cpp
@@ -393,7 +393,7 @@ TEST(Source, GeoJSonSourceUrlUpdate) {
};
test.observer.sourceDescriptionChanged = [&] (Source&) {
- //Should be called (test will hang if it doesn't)
+ // Should be called (test will hang if it doesn't)
test.end();
};
@@ -404,12 +404,12 @@ TEST(Source, GeoJSonSourceUrlUpdate) {
GeoJSONSource source("source");
source.baseImpl->setObserver(&test.observer);
- //Load initial, so the source state will be loaded=true
+ // Load initial, so the source state will be loaded=true
source.baseImpl->loadDescription(test.fileSource);
- //Schedule an update
+ // Schedule an update
test.loop.invoke([&] () {
- //Update the url
+ // Update the url
source.setURL(std::string("http://source-url.ext"));
});
diff --git a/test/style/style.test.cpp b/test/style/style.test.cpp
index 89c5c4ce6f..b49058420e 100644
--- a/test/style/style.test.cpp
+++ b/test/style/style.test.cpp
@@ -131,6 +131,6 @@ TEST(Style, DuplicateSource) {
style.addSource(std::make_unique<VectorSource>("sourceId", "mapbox://mapbox.mapbox-terrain-v2"));
FAIL() << "Should not have been allowed to add a duplicate source id";
} catch (std::runtime_error) {
- //Expected
+ // Expected
}
}
diff --git a/test/style/style_layer.test.cpp b/test/style/style_layer.test.cpp
index 8356f3accd..10b88c53d4 100644
--- a/test/style/style_layer.test.cpp
+++ b/test/style/style_layer.test.cpp
@@ -36,27 +36,27 @@ template <class T, class... Params> void testClone(Params... params) {
EXPECT_EQ("test", layer->baseImpl->clone()->getID());
}
-const auto color = PropertyValue<Color> {{ 1, 0, 0, 1 }};
-const auto opacity = PropertyValue<float> { 1.0f };
-const auto radius = PropertyValue<float> { 1.0f };
-const auto blur = PropertyValue<float> { 1.0f };
-const auto pattern = PropertyValue<std::string> { "foo" };
-const auto antialias = PropertyValue<bool> { false };
-const auto translate = PropertyValue<std::array<float, 2>> {{{ 0, 0 }}};
-const auto translateAnchor = PropertyValue<TranslateAnchorType> { TranslateAnchorType::Map };
-const auto lineCap = PropertyValue<LineCapType> { LineCapType::Round };
-const auto lineJoin = PropertyValue<LineJoinType> { LineJoinType::Miter };
-const auto miterLimit = PropertyValue<float> { 1.0f };
-const auto roundLimit = PropertyValue<float> { 1.0f };
-const auto width = PropertyValue<float> { 1.0f };
-const auto gapWidth = PropertyValue<float> { 1.0f };
-const auto offset = PropertyValue<float> { 1.0f };
-const auto dashArray = PropertyValue<std::vector<float>> {{}};
-const auto hueRotate = PropertyValue<float> { 1.0f };
-const auto brightness = PropertyValue<float> { 1.0f };
-const auto saturation = PropertyValue<float> { 1.0f };
-const auto contrast = PropertyValue<float> { 1.0f };
-const auto duration = PropertyValue<float> { 1.0f };
+const auto color = Color { 1, 0, 0, 1 };
+const auto opacity = 1.0f;
+const auto radius = 1.0f;
+const auto blur = 1.0f;
+const auto pattern = std::string { "foo" };
+const auto antialias = false;
+const auto translate = std::array<float, 2> {{ 0, 0 }};
+const auto translateAnchor = TranslateAnchorType::Map;
+const auto lineCap = LineCapType::Round;
+const auto lineJoin = LineJoinType::Miter;
+const auto miterLimit = 1.0f;
+const auto roundLimit = 1.0f;
+const auto width = 1.0f;
+const auto gapWidth = 1.0f;
+const auto offset = 1.0f;
+const auto dashArray = std::vector<float> {};
+const auto hueRotate = 1.0f;
+const auto brightness = 1.0f;
+const auto saturation = 1.0f;
+const auto contrast = 1.0f;
+const auto duration = 1.0f;
} // namespace
@@ -77,13 +77,13 @@ TEST(Layer, BackgroundProperties) {
// Paint properties
layer->setBackgroundColor(color);
- EXPECT_EQ(layer->getBackgroundColor().asConstant(), color.asConstant());
+ EXPECT_EQ(layer->getBackgroundColor(), color);
layer->setBackgroundOpacity(opacity);
- EXPECT_EQ(layer->getBackgroundOpacity().asConstant(), opacity.asConstant());
+ EXPECT_EQ(layer->getBackgroundOpacity(), opacity);
layer->setBackgroundPattern(pattern);
- EXPECT_EQ(layer->getBackgroundPattern().asConstant(), pattern.asConstant());
+ EXPECT_EQ(layer->getBackgroundPattern(), pattern);
}
TEST(Layer, CircleProperties) {
@@ -93,22 +93,22 @@ TEST(Layer, CircleProperties) {
// Paint properties
layer->setCircleColor(color);
- EXPECT_EQ(layer->getCircleColor().asConstant(), color.asConstant());
+ EXPECT_EQ(layer->getCircleColor(), color);
layer->setCircleOpacity(opacity);
- EXPECT_EQ(layer->getCircleOpacity().asConstant(), opacity.asConstant());
+ EXPECT_EQ(layer->getCircleOpacity(), opacity);
layer->setCircleRadius(radius);
- EXPECT_EQ(layer->getCircleRadius().asConstant(), radius.asConstant());
+ EXPECT_EQ(layer->getCircleRadius(), radius);
layer->setCircleBlur(blur);
- EXPECT_EQ(layer->getCircleBlur().asConstant(), blur.asConstant());
+ EXPECT_EQ(layer->getCircleBlur(), blur);
layer->setCircleTranslate(translate);
- EXPECT_EQ(layer->getCircleTranslate().asConstant(), translate.asConstant());
+ EXPECT_EQ(layer->getCircleTranslate(), translate);
layer->setCircleTranslateAnchor(translateAnchor);
- EXPECT_EQ(layer->getCircleTranslateAnchor().asConstant(), translateAnchor.asConstant());
+ EXPECT_EQ(layer->getCircleTranslateAnchor(), translateAnchor);
}
TEST(Layer, FillProperties) {
@@ -118,25 +118,25 @@ TEST(Layer, FillProperties) {
// Paint properties
layer->setFillColor(color);
- EXPECT_EQ(layer->getFillColor().asConstant(), color.asConstant());
+ EXPECT_EQ(layer->getFillColor(), color);
layer->setFillOutlineColor(color);
- EXPECT_EQ(layer->getFillOutlineColor().asConstant(), color.asConstant());
+ EXPECT_EQ(layer->getFillOutlineColor(), color);
layer->setFillOpacity(opacity);
- EXPECT_EQ(layer->getFillOpacity().asConstant(), opacity.asConstant());
+ EXPECT_EQ(layer->getFillOpacity(), opacity);
layer->setFillPattern(pattern);
- EXPECT_EQ(layer->getFillPattern().asConstant(), pattern.asConstant());
+ EXPECT_EQ(layer->getFillPattern(), pattern);
layer->setFillAntialias(antialias);
- EXPECT_EQ(layer->getFillAntialias().asConstant(), antialias.asConstant());
+ EXPECT_EQ(layer->getFillAntialias(), antialias);
layer->setFillTranslate(translate);
- EXPECT_EQ(layer->getFillTranslate().asConstant(), translate.asConstant());
+ EXPECT_EQ(layer->getFillTranslate(), translate);
layer->setFillTranslateAnchor(translateAnchor);
- EXPECT_EQ(layer->getFillTranslateAnchor().asConstant(), translateAnchor.asConstant());
+ EXPECT_EQ(layer->getFillTranslateAnchor(), translateAnchor);
}
TEST(Layer, LineProperties) {
@@ -146,48 +146,48 @@ TEST(Layer, LineProperties) {
// Layout properties
layer->setLineCap(lineCap);
- EXPECT_EQ(layer->getLineCap().asConstant(), lineCap.asConstant());
+ EXPECT_EQ(layer->getLineCap(), lineCap);
layer->setLineJoin(lineJoin);
- EXPECT_EQ(layer->getLineJoin().asConstant(), lineJoin.asConstant());
+ EXPECT_EQ(layer->getLineJoin(), lineJoin);
layer->setLineMiterLimit(miterLimit);
- EXPECT_EQ(layer->getLineMiterLimit().asConstant(), miterLimit.asConstant());
+ EXPECT_EQ(layer->getLineMiterLimit(), miterLimit);
layer->setLineRoundLimit(roundLimit);
- EXPECT_EQ(layer->getLineRoundLimit().asConstant(), roundLimit.asConstant());
+ EXPECT_EQ(layer->getLineRoundLimit(), roundLimit);
// Paint properties
layer->setLineColor(color);
- EXPECT_EQ(layer->getLineColor().asConstant(), color.asConstant());
+ EXPECT_EQ(layer->getLineColor(), color);
layer->setLineOpacity(opacity);
- EXPECT_EQ(layer->getLineOpacity().asConstant(), opacity.asConstant());
+ EXPECT_EQ(layer->getLineOpacity(), opacity);
layer->setLineTranslate(translate);
- EXPECT_EQ(layer->getLineTranslate().asConstant(), translate.asConstant());
+ EXPECT_EQ(layer->getLineTranslate(), translate);
layer->setLineTranslateAnchor(translateAnchor);
- EXPECT_EQ(layer->getLineTranslateAnchor().asConstant(), translateAnchor.asConstant());
+ EXPECT_EQ(layer->getLineTranslateAnchor(), translateAnchor);
layer->setLineWidth(width);
- EXPECT_EQ(layer->getLineWidth().asConstant(), width.asConstant());
+ EXPECT_EQ(layer->getLineWidth(), width);
layer->setLineGapWidth(gapWidth);
- EXPECT_EQ(layer->getLineGapWidth().asConstant(), gapWidth.asConstant());
+ EXPECT_EQ(layer->getLineGapWidth(), gapWidth);
layer->setLineOffset(offset);
- EXPECT_EQ(layer->getLineOffset().asConstant(), offset.asConstant());
+ EXPECT_EQ(layer->getLineOffset(), offset);
layer->setLineBlur(blur);
- EXPECT_EQ(layer->getLineBlur().asConstant(), blur.asConstant());
+ EXPECT_EQ(layer->getLineBlur(), blur);
layer->setLineDasharray(dashArray);
- EXPECT_EQ(layer->getLineDasharray().asConstant(), dashArray.asConstant());
+ EXPECT_EQ(layer->getLineDasharray(), dashArray);
layer->setLinePattern(pattern);
- EXPECT_EQ(layer->getLinePattern().asConstant(), pattern.asConstant());
+ EXPECT_EQ(layer->getLinePattern(), pattern);
}
TEST(Layer, RasterProperties) {
@@ -197,25 +197,25 @@ TEST(Layer, RasterProperties) {
// Paint properties
layer->setRasterOpacity(opacity);
- EXPECT_EQ(layer->getRasterOpacity().asConstant(), opacity.asConstant());
+ EXPECT_EQ(layer->getRasterOpacity(), opacity);
layer->setRasterHueRotate(hueRotate);
- EXPECT_EQ(layer->getRasterHueRotate().asConstant(), hueRotate.asConstant());
+ EXPECT_EQ(layer->getRasterHueRotate(), hueRotate);
layer->setRasterBrightnessMin(brightness);
- EXPECT_EQ(layer->getRasterBrightnessMin().asConstant(), brightness.asConstant());
+ EXPECT_EQ(layer->getRasterBrightnessMin(), brightness);
layer->setRasterBrightnessMax(brightness);
- EXPECT_EQ(layer->getRasterBrightnessMax().asConstant(), brightness.asConstant());
+ EXPECT_EQ(layer->getRasterBrightnessMax(), brightness);
layer->setRasterSaturation(saturation);
- EXPECT_EQ(layer->getRasterSaturation().asConstant(), saturation.asConstant());
+ EXPECT_EQ(layer->getRasterSaturation(), saturation);
layer->setRasterContrast(contrast);
- EXPECT_EQ(layer->getRasterContrast().asConstant(), contrast.asConstant());
+ EXPECT_EQ(layer->getRasterContrast(), contrast);
layer->setRasterFadeDuration(duration);
- EXPECT_EQ(layer->getRasterFadeDuration().asConstant(), duration.asConstant());
+ EXPECT_EQ(layer->getRasterFadeDuration(), duration);
}
TEST(Layer, Observer) {
@@ -278,20 +278,20 @@ TEST(Layer, Observer) {
TEST(Layer, DuplicateLayer) {
util::RunLoop loop;
- //Setup style
+ // Setup style
StubFileSource fileSource;
Style style { fileSource, 1.0 };
style.setJSON(util::read_file("test/fixtures/resources/style-unused-sources.json"));
- //Add initial layer
+ // Add initial layer
style.addLayer(std::make_unique<LineLayer>("line", "unusedsource"));
- //Try to add duplicate
+ // Try to add duplicate
try {
style.addLayer(std::make_unique<LineLayer>("line", "unusedsource"));
FAIL() << "Should not have been allowed to add a duplicate layer id";
} catch (const std::runtime_error e) {
- //Expected
+ // Expected
ASSERT_STREQ("Layer line already exists", e.what());
}
}
diff --git a/test/text/glyph_atlas.test.cpp b/test/text/glyph_atlas.test.cpp
index e229cd117b..3679cabc1b 100644
--- a/test/text/glyph_atlas.test.cpp
+++ b/test/text/glyph_atlas.test.cpp
@@ -83,8 +83,7 @@ TEST(GlyphAtlas, LoadingFail) {
EXPECT_TRUE(error != nullptr);
EXPECT_EQ(util::toString(error), "Failed by the test case");
- auto glyphSet = test.glyphAtlas.getGlyphSet({{"Test Stack"}});
- ASSERT_TRUE(glyphSet->getSDFs().empty());
+ ASSERT_TRUE(test.glyphAtlas.getGlyphSet({{"Test Stack"}})->getSDFs().empty());
ASSERT_FALSE(test.glyphAtlas.hasGlyphRanges({{"Test Stack"}}, {{0, 255}}));
test.end();
@@ -112,8 +111,7 @@ TEST(GlyphAtlas, LoadingCorrupted) {
EXPECT_TRUE(error != nullptr);
EXPECT_EQ(util::toString(error), "unknown pbf field type exception");
- auto glyphSet = test.glyphAtlas.getGlyphSet({{"Test Stack"}});
- ASSERT_TRUE(glyphSet->getSDFs().empty());
+ ASSERT_TRUE(test.glyphAtlas.getGlyphSet({{"Test Stack"}})->getSDFs().empty());
ASSERT_FALSE(test.glyphAtlas.hasGlyphRanges({{"Test Stack"}}, {{0, 255}}));
test.end();
@@ -144,32 +142,27 @@ TEST(GlyphAtlas, LoadingCancel) {
}
TEST(GlyphAtlas, InvalidSDFGlyph) {
- GlyphSet glyphSet;
- glyphSet.insert(65, SDFGlyph{ 65 /* ASCII 'A' */,
- "x" /* bitmap is too short */,
- { 1 /* width */, 1 /* height */, 0 /* left */, 0 /* top */,
- 0 /* advance */ } });
- glyphSet.insert(66, SDFGlyph{ 66 /* ASCII 'B' */,
- std::string(7 * 7, 'x'), /* correct */
+ const FontStack fontStack{ "Mock Font" };
+
+ GlyphAtlasTest test;
+ GlyphPositions positions;
+
+ auto glyphSet = test.glyphAtlas.getGlyphSet(fontStack);
+ glyphSet->insert(66, SDFGlyph{ 66 /* ASCII 'B' */,
+ AlphaImage({7, 7}), /* correct */
{ 1 /* width */, 1 /* height */, 0 /* left */, 0 /* top */,
0 /* advance */ } });
- glyphSet.insert(67, SDFGlyph{ 67 /* ASCII 'C' */,
- std::string(518 * 8, 'x'), /* correct */
+ glyphSet->insert(67, SDFGlyph{ 67 /* ASCII 'C' */,
+ AlphaImage({518, 8}), /* correct */
{ 512 /* width */, 2 /* height */, 0 /* left */, 0 /* top */,
0 /* advance */ } });
-
- const FontStack fontStack{ "Mock Font" };
-
- GlyphAtlasTest test;
- GlyphPositions positions;
test.glyphAtlas.addGlyphs(1, std::u16string{u"ABC"}, fontStack, glyphSet, positions);
- ASSERT_EQ(3u, positions.size());
+ ASSERT_EQ(2u, positions.size());
- // 'A' was not placed because the bitmap size is invalid.
- ASSERT_NE(positions.end(), positions.find(65));
- ASSERT_EQ((Rect<uint16_t>{ 0, 0, 0, 0 }), positions[65].rect);
+ // 'A' was not placed because not in the glyph set.
+ ASSERT_EQ(positions.end(), positions.find(65));
// 'B' was placed at the top left.
ASSERT_NE(positions.end(), positions.find(66));
diff --git a/test/text/glyph_pbf.test.cpp b/test/text/glyph_pbf.test.cpp
index 1e28dfbc31..be3ca3359b 100644
--- a/test/text/glyph_pbf.test.cpp
+++ b/test/text/glyph_pbf.test.cpp
@@ -44,15 +44,17 @@ TEST(GlyphPBF, Parsing) {
glyphAtlasObserver.glyphsLoaded = [&](const FontStack&, const GlyphRange&) {
loop.stop();
- auto sdfs = glyphAtlas.getGlyphSet(fontStack)->getSDFs();
+ const auto& sdfs = glyphAtlas.getGlyphSet(fontStack)->getSDFs();
// The fake glyphs don't contain a glyph that has the ID 0; it only contains glyphs with
// undefined IDs, but the parser should remove them.
EXPECT_TRUE(sdfs.size() == 1);
EXPECT_TRUE(sdfs.find(69) != sdfs.end());
- auto& sdf = sdfs[69];
- EXPECT_EQ("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"s, sdf.bitmap);
+ auto& sdf = sdfs.at(69);
+ AlphaImage expected({7, 7});
+ expected.fill('x');
+ EXPECT_EQ(expected, sdf.bitmap);
EXPECT_EQ(1u, sdf.metrics.width);
EXPECT_EQ(1u, sdf.metrics.height);
EXPECT_EQ(20, sdf.metrics.left);
diff --git a/test/text/quads.test.cpp b/test/text/quads.test.cpp
index c20218a82f..42bc0f2048 100644
--- a/test/text/quads.test.cpp
+++ b/test/text/quads.test.cpp
@@ -14,68 +14,68 @@ TEST(getIconQuads, normal) {
Anchor anchor(2.0, 3.0, 0.0, 0.5f, 0);
SpriteAtlasElement image = {
Rect<uint16_t>( 0, 0, 15, 11 ),
- std::shared_ptr<const SpriteImage>(),
+ std::make_shared<const SpriteImage>(PremultipliedImage({1,1}), 1.0),
+ { 0, 0 },
1.0f
};
- PositionedIcon shapedIcon(image, -5.0, 6.0, -7.0, 8.0);
+ PositionedIcon shapedIcon(image, -5.0, 6.0, -7.0, 8.0, 0);
GeometryCoordinates line;
Shaping shapedText;
- SymbolQuads quads =
- getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
+ SymbolQuad quad =
+ getIconQuad(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
- ASSERT_EQ(quads.size(), 1u);
- ASSERT_EQ(quads[0].anchorPoint.x, 2);
- ASSERT_EQ(quads[0].anchorPoint.y, 3);
- ASSERT_EQ(quads[0].tl.x, -8);
- ASSERT_EQ(quads[0].tl.y, -6);
- ASSERT_EQ(quads[0].tr.x, 7);
- ASSERT_EQ(quads[0].tr.y, -6);
- ASSERT_EQ(quads[0].bl.x, -8);
- ASSERT_EQ(quads[0].bl.y, 5);
- ASSERT_EQ(quads[0].br.x, 7);
- ASSERT_EQ(quads[0].br.y, 5);
- ASSERT_EQ(quads[0].anchorAngle, 0.0f);
- ASSERT_EQ(quads[0].glyphAngle, 0.0f);
- ASSERT_EQ(quads[0].minScale, 0.5f);
+ ASSERT_EQ(quad.anchorPoint.x, 2);
+ ASSERT_EQ(quad.anchorPoint.y, 3);
+ ASSERT_EQ(quad.tl.x, -8);
+ ASSERT_EQ(quad.tl.y, -6);
+ ASSERT_EQ(quad.tr.x, 7);
+ ASSERT_EQ(quad.tr.y, -6);
+ ASSERT_EQ(quad.bl.x, -8);
+ ASSERT_EQ(quad.bl.y, 5);
+ ASSERT_EQ(quad.br.x, 7);
+ ASSERT_EQ(quad.br.y, 5);
+ ASSERT_EQ(quad.anchorAngle, 0.0f);
+ ASSERT_EQ(quad.glyphAngle, 0.0f);
+ ASSERT_EQ(quad.minScale, 0.5f);
}
TEST(getIconQuads, style) {
Anchor anchor(0.0, 0.0, 0.0, 0.5f, 0);
SpriteAtlasElement image = {
Rect<uint16_t>( 0, 0, 20, 20 ),
- std::shared_ptr<const SpriteImage>(),
+ std::make_shared<const SpriteImage>(PremultipliedImage({1,1}), 1.0),
+ { 0, 0 },
1.0f
};
- PositionedIcon shapedIcon(image, -10.0, 10.0, -10.0, 10.0);
+ PositionedIcon shapedIcon(image, -10.0, 10.0, -10.0, 10.0, 0);
GeometryCoordinates line;
Shaping shapedText;
shapedText.top = -10.0f;
shapedText.bottom = 30.0f;
shapedText.left = -60.0f;
shapedText.right = 20.0f;
- shapedText.positionedGlyphs.emplace_back(PositionedGlyph(32, 0.0f, 0.0f));
+ shapedText.positionedGlyphs.emplace_back(PositionedGlyph(32, 0.0f, 0.0f, 0));
// none
{
SymbolLayoutProperties::Evaluated layout;
- SymbolQuads quads =
- getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
+ SymbolQuad quad =
+ getIconQuad(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
- ASSERT_EQ(quads.size(), 1u);
- ASSERT_EQ(quads[0].anchorPoint.x, 0);
- ASSERT_EQ(quads[0].anchorPoint.y, 0);
- ASSERT_EQ(quads[0].tl.x, -11);
- ASSERT_EQ(quads[0].tl.y, -11);
- ASSERT_EQ(quads[0].tr.x, 9);
- ASSERT_EQ(quads[0].tr.y, -11);
- ASSERT_EQ(quads[0].bl.x, -11);
- ASSERT_EQ(quads[0].bl.y, 9);
- ASSERT_EQ(quads[0].br.x, 9);
- ASSERT_EQ(quads[0].br.y, 9);
- ASSERT_EQ(quads[0].anchorAngle, 0.0f);
- ASSERT_EQ(quads[0].glyphAngle, 0.0f);
- ASSERT_EQ(quads[0].minScale, 0.5f);
+ ASSERT_EQ(quad.anchorPoint.x, 0);
+ ASSERT_EQ(quad.anchorPoint.y, 0);
+ ASSERT_EQ(quad.tl.x, -11);
+ ASSERT_EQ(quad.tl.y, -11);
+ ASSERT_EQ(quad.tr.x, 9);
+ ASSERT_EQ(quad.tr.y, -11);
+ ASSERT_EQ(quad.bl.x, -11);
+ ASSERT_EQ(quad.bl.y, 9);
+ ASSERT_EQ(quad.br.x, 9);
+ ASSERT_EQ(quad.br.y, 9);
+ ASSERT_EQ(quad.anchorAngle, 0.0f);
+ ASSERT_EQ(quad.glyphAngle, 0.0f);
+ ASSERT_EQ(quad.minScale, 0.5f);
}
// width
@@ -83,17 +83,17 @@ TEST(getIconQuads, style) {
SymbolLayoutProperties::Evaluated layout;
layout.get<TextSize>() = 24.0f;
layout.get<IconTextFit>() = IconTextFitType::Width;
- SymbolQuads quads =
- getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
+ SymbolQuad quad =
+ getIconQuad(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
- ASSERT_EQ(quads[0].tl.x, -60);
- ASSERT_EQ(quads[0].tl.y, 0);
- ASSERT_EQ(quads[0].tr.x, 20);
- ASSERT_EQ(quads[0].tr.y, 0);
- ASSERT_EQ(quads[0].bl.x, -60);
- ASSERT_EQ(quads[0].bl.y, 20);
- ASSERT_EQ(quads[0].br.x, 20);
- ASSERT_EQ(quads[0].br.y, 20);
+ ASSERT_EQ(quad.tl.x, -60);
+ ASSERT_EQ(quad.tl.y, 0);
+ ASSERT_EQ(quad.tr.x, 20);
+ ASSERT_EQ(quad.tr.y, 0);
+ ASSERT_EQ(quad.bl.x, -60);
+ ASSERT_EQ(quad.bl.y, 20);
+ ASSERT_EQ(quad.br.x, 20);
+ ASSERT_EQ(quad.br.y, 20);
}
// width x textSize
@@ -101,17 +101,17 @@ TEST(getIconQuads, style) {
SymbolLayoutProperties::Evaluated layout;
layout.get<TextSize>() = 12.0f;
layout.get<IconTextFit>() = IconTextFitType::Width;
- SymbolQuads quads =
- getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
+ SymbolQuad quad =
+ getIconQuad(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
- ASSERT_EQ(quads[0].tl.x, -30);
- ASSERT_EQ(quads[0].tl.y, -5);
- ASSERT_EQ(quads[0].tr.x, 10);
- ASSERT_EQ(quads[0].tr.y, -5);
- ASSERT_EQ(quads[0].bl.x, -30);
- ASSERT_EQ(quads[0].bl.y, 15);
- ASSERT_EQ(quads[0].br.x, 10);
- ASSERT_EQ(quads[0].br.y, 15);
+ ASSERT_EQ(quad.tl.x, -30);
+ ASSERT_EQ(quad.tl.y, -5);
+ ASSERT_EQ(quad.tr.x, 10);
+ ASSERT_EQ(quad.tr.y, -5);
+ ASSERT_EQ(quad.bl.x, -30);
+ ASSERT_EQ(quad.bl.y, 15);
+ ASSERT_EQ(quad.br.x, 10);
+ ASSERT_EQ(quad.br.y, 15);
}
// width x textSize + padding
@@ -123,17 +123,17 @@ TEST(getIconQuads, style) {
layout.get<IconTextFitPadding>()[1] = 10.0f;
layout.get<IconTextFitPadding>()[2] = 5.0f;
layout.get<IconTextFitPadding>()[3] = 10.0f;
- SymbolQuads quads =
- getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
+ SymbolQuad quad =
+ getIconQuad(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
- ASSERT_EQ(quads[0].tl.x, -40);
- ASSERT_EQ(quads[0].tl.y, -10);
- ASSERT_EQ(quads[0].tr.x, 20);
- ASSERT_EQ(quads[0].tr.y, -10);
- ASSERT_EQ(quads[0].bl.x, -40);
- ASSERT_EQ(quads[0].bl.y, 20);
- ASSERT_EQ(quads[0].br.x, 20);
- ASSERT_EQ(quads[0].br.y, 20);
+ ASSERT_EQ(quad.tl.x, -40);
+ ASSERT_EQ(quad.tl.y, -10);
+ ASSERT_EQ(quad.tr.x, 20);
+ ASSERT_EQ(quad.tr.y, -10);
+ ASSERT_EQ(quad.bl.x, -40);
+ ASSERT_EQ(quad.bl.y, 20);
+ ASSERT_EQ(quad.br.x, 20);
+ ASSERT_EQ(quad.br.y, 20);
}
// height
@@ -141,17 +141,17 @@ TEST(getIconQuads, style) {
SymbolLayoutProperties::Evaluated layout;
layout.get<TextSize>() = 24.0f;
layout.get<IconTextFit>() = IconTextFitType::Height;
- SymbolQuads quads =
- getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
+ SymbolQuad quad =
+ getIconQuad(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
- ASSERT_EQ(quads[0].tl.x, -30);
- ASSERT_EQ(quads[0].tl.y, -10);
- ASSERT_EQ(quads[0].tr.x, -10);
- ASSERT_EQ(quads[0].tr.y, -10);
- ASSERT_EQ(quads[0].bl.x, -30);
- ASSERT_EQ(quads[0].bl.y, 30);
- ASSERT_EQ(quads[0].br.x, -10);
- ASSERT_EQ(quads[0].br.y, 30);
+ ASSERT_EQ(quad.tl.x, -30);
+ ASSERT_EQ(quad.tl.y, -10);
+ ASSERT_EQ(quad.tr.x, -10);
+ ASSERT_EQ(quad.tr.y, -10);
+ ASSERT_EQ(quad.bl.x, -30);
+ ASSERT_EQ(quad.bl.y, 30);
+ ASSERT_EQ(quad.br.x, -10);
+ ASSERT_EQ(quad.br.y, 30);
}
// height x textSize
@@ -159,17 +159,17 @@ TEST(getIconQuads, style) {
SymbolLayoutProperties::Evaluated layout;
layout.get<TextSize>() = 12.0f;
layout.get<IconTextFit>() = IconTextFitType::Height;
- SymbolQuads quads =
- getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
+ SymbolQuad quad =
+ getIconQuad(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
- ASSERT_EQ(quads[0].tl.x, -20);
- ASSERT_EQ(quads[0].tl.y, -5);
- ASSERT_EQ(quads[0].tr.x, 0);
- ASSERT_EQ(quads[0].tr.y, -5);
- ASSERT_EQ(quads[0].bl.x, -20);
- ASSERT_EQ(quads[0].bl.y, 15);
- ASSERT_EQ(quads[0].br.x, 0);
- ASSERT_EQ(quads[0].br.y, 15);
+ ASSERT_EQ(quad.tl.x, -20);
+ ASSERT_EQ(quad.tl.y, -5);
+ ASSERT_EQ(quad.tr.x, 0);
+ ASSERT_EQ(quad.tr.y, -5);
+ ASSERT_EQ(quad.bl.x, -20);
+ ASSERT_EQ(quad.bl.y, 15);
+ ASSERT_EQ(quad.br.x, 0);
+ ASSERT_EQ(quad.br.y, 15);
}
// height x textSize + padding
@@ -181,17 +181,17 @@ TEST(getIconQuads, style) {
layout.get<IconTextFitPadding>()[1] = 10.0f;
layout.get<IconTextFitPadding>()[2] = 5.0f;
layout.get<IconTextFitPadding>()[3] = 10.0f;
- SymbolQuads quads =
- getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
+ SymbolQuad quad =
+ getIconQuad(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
- ASSERT_EQ(quads[0].tl.x, -30);
- ASSERT_EQ(quads[0].tl.y, -10);
- ASSERT_EQ(quads[0].tr.x, 10);
- ASSERT_EQ(quads[0].tr.y, -10);
- ASSERT_EQ(quads[0].bl.x, -30);
- ASSERT_EQ(quads[0].bl.y, 20);
- ASSERT_EQ(quads[0].br.x, 10);
- ASSERT_EQ(quads[0].br.y, 20);
+ ASSERT_EQ(quad.tl.x, -30);
+ ASSERT_EQ(quad.tl.y, -10);
+ ASSERT_EQ(quad.tr.x, 10);
+ ASSERT_EQ(quad.tr.y, -10);
+ ASSERT_EQ(quad.bl.x, -30);
+ ASSERT_EQ(quad.bl.y, 20);
+ ASSERT_EQ(quad.br.x, 10);
+ ASSERT_EQ(quad.br.y, 20);
}
// both
@@ -199,17 +199,17 @@ TEST(getIconQuads, style) {
SymbolLayoutProperties::Evaluated layout;
layout.get<TextSize>() = 24.0f;
layout.get<IconTextFit>() = IconTextFitType::Both;
- SymbolQuads quads =
- getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
+ SymbolQuad quad =
+ getIconQuad(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
- ASSERT_EQ(quads[0].tl.x, -60);
- ASSERT_EQ(quads[0].tl.y, -10);
- ASSERT_EQ(quads[0].tr.x, 20);
- ASSERT_EQ(quads[0].tr.y, -10);
- ASSERT_EQ(quads[0].bl.x, -60);
- ASSERT_EQ(quads[0].bl.y, 30);
- ASSERT_EQ(quads[0].br.x, 20);
- ASSERT_EQ(quads[0].br.y, 30);
+ ASSERT_EQ(quad.tl.x, -60);
+ ASSERT_EQ(quad.tl.y, -10);
+ ASSERT_EQ(quad.tr.x, 20);
+ ASSERT_EQ(quad.tr.y, -10);
+ ASSERT_EQ(quad.bl.x, -60);
+ ASSERT_EQ(quad.bl.y, 30);
+ ASSERT_EQ(quad.br.x, 20);
+ ASSERT_EQ(quad.br.y, 30);
}
// both x textSize
@@ -217,17 +217,17 @@ TEST(getIconQuads, style) {
SymbolLayoutProperties::Evaluated layout;
layout.get<TextSize>() = 12.0f;
layout.get<IconTextFit>() = IconTextFitType::Both;
- SymbolQuads quads =
- getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
+ SymbolQuad quad =
+ getIconQuad(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
- ASSERT_EQ(quads[0].tl.x, -30);
- ASSERT_EQ(quads[0].tl.y, -5);
- ASSERT_EQ(quads[0].tr.x, 10);
- ASSERT_EQ(quads[0].tr.y, -5);
- ASSERT_EQ(quads[0].bl.x, -30);
- ASSERT_EQ(quads[0].bl.y, 15);
- ASSERT_EQ(quads[0].br.x, 10);
- ASSERT_EQ(quads[0].br.y, 15);
+ ASSERT_EQ(quad.tl.x, -30);
+ ASSERT_EQ(quad.tl.y, -5);
+ ASSERT_EQ(quad.tr.x, 10);
+ ASSERT_EQ(quad.tr.y, -5);
+ ASSERT_EQ(quad.bl.x, -30);
+ ASSERT_EQ(quad.bl.y, 15);
+ ASSERT_EQ(quad.br.x, 10);
+ ASSERT_EQ(quad.br.y, 15);
}
// both x textSize + padding
@@ -239,17 +239,17 @@ TEST(getIconQuads, style) {
layout.get<IconTextFitPadding>()[1] = 10.0f;
layout.get<IconTextFitPadding>()[2] = 5.0f;
layout.get<IconTextFitPadding>()[3] = 10.0f;
- SymbolQuads quads =
- getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
+ SymbolQuad quad =
+ getIconQuad(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
- ASSERT_EQ(quads[0].tl.x, -40);
- ASSERT_EQ(quads[0].tl.y, -10);
- ASSERT_EQ(quads[0].tr.x, 20);
- ASSERT_EQ(quads[0].tr.y, -10);
- ASSERT_EQ(quads[0].bl.x, -40);
- ASSERT_EQ(quads[0].bl.y, 20);
- ASSERT_EQ(quads[0].br.x, 20);
- ASSERT_EQ(quads[0].br.y, 20);
+ ASSERT_EQ(quad.tl.x, -40);
+ ASSERT_EQ(quad.tl.y, -10);
+ ASSERT_EQ(quad.tr.x, 20);
+ ASSERT_EQ(quad.tr.y, -10);
+ ASSERT_EQ(quad.bl.x, -40);
+ ASSERT_EQ(quad.bl.y, 20);
+ ASSERT_EQ(quad.br.x, 20);
+ ASSERT_EQ(quad.br.y, 20);
}
// both x textSize + padding t/r/b/l
@@ -261,17 +261,17 @@ TEST(getIconQuads, style) {
layout.get<IconTextFitPadding>()[1] = 5.0f;
layout.get<IconTextFitPadding>()[2] = 10.0f;
layout.get<IconTextFitPadding>()[3] = 15.0f;
- SymbolQuads quads =
- getIconQuads(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
+ SymbolQuad quad =
+ getIconQuad(anchor, shapedIcon, line, layout, SymbolPlacementType::Point, shapedText);
- ASSERT_EQ(quads[0].tl.x, -45);
- ASSERT_EQ(quads[0].tl.y, -5);
- ASSERT_EQ(quads[0].tr.x, 15);
- ASSERT_EQ(quads[0].tr.y, -5);
- ASSERT_EQ(quads[0].bl.x, -45);
- ASSERT_EQ(quads[0].bl.y, 25);
- ASSERT_EQ(quads[0].br.x, 15);
- ASSERT_EQ(quads[0].br.y, 25);
+ ASSERT_EQ(quad.tl.x, -45);
+ ASSERT_EQ(quad.tl.y, -5);
+ ASSERT_EQ(quad.tr.x, 15);
+ ASSERT_EQ(quad.tr.y, -5);
+ ASSERT_EQ(quad.bl.x, -45);
+ ASSERT_EQ(quad.bl.y, 25);
+ ASSERT_EQ(quad.br.x, 15);
+ ASSERT_EQ(quad.br.y, 25);
}
}
diff --git a/test/tile/geometry_tile_data.test.cpp b/test/tile/geometry_tile_data.test.cpp
index 6e118d6fd5..f7fe5816ea 100644
--- a/test/tile/geometry_tile_data.test.cpp
+++ b/test/tile/geometry_tile_data.test.cpp
@@ -3,6 +3,18 @@
using namespace mbgl;
+static double _signedArea(const GeometryCoordinates& ring) {
+ double sum = 0;
+
+ for (std::size_t i = 0, len = ring.size(), j = len - 1; i < len; j = i++) {
+ const GeometryCoordinate& p1 = ring[i];
+ const GeometryCoordinate& p2 = ring[j];
+ sum += (p2.x - p1.x) * (p1.y + p2.y);
+ }
+
+ return sum;
+}
+
TEST(GeometryTileData, classifyRings1) {
std::vector<GeometryCollection> polygons = classifyRings({
{ {0, 0}, {0, 40}, {40, 40}, {40, 0}, {0, 0} }
@@ -59,3 +71,37 @@ TEST(GeometryTileData, limitHoles2) {
ASSERT_EQ(polygon[0][0].x, 0);
ASSERT_EQ(polygon[1][0].x, 10);
}
+
+TEST(GeometryTileData, limitHoles3) {
+ // real world polygon with interior rings with negative areas
+ // that need to be sorted in `limitHoles` by comparing absolute
+ // area not signed
+ GeometryCollection polygon = {
+ { {7336,-248},{7304,-248},{7272,-168},{7176,-200},{7080,-136},{7048,-56},{7128,-8},{7176,-56},{7288,-56},{7316,0},{6918,0},{6904,-40},{6984,-72},{6952,-88},{6952,-168},{6888,-88},{6856,-88},{6856,-8},{6872,0},{6170,0},{6184,-40},{6136,-72},{6104,-56},{6132,0},{6028,0},{6104,-152},{6184,-200},{6206,-256},{6272,-256},{6264,-248},{6248,-120},{6280,-136},{6280,-232},{6288,-256},{6790,-256},{6792,-248},{6800,-256},{7058,-256},{7064,-248},{7096,-256},{7338,-256},{7336,-248} },
+ { {6344,-104},{6264,-8},{6392,-72},{6360,-200},{6344,-104} },
+ { {6744,-24},{6760,-72},{6728,-104},{6744,-24} },
+ { {6616,-104},{6648,-88},{6632,-72},{6664,-56},{6664,-120},{6616,-104} }
+ };
+
+ // make a copy for later testing
+ GeometryCollection original(polygon);
+
+ ASSERT_EQ(polygon.size(), 4u);
+ ASSERT_EQ(_signedArea(polygon.at(0)), 515360); // exterior
+ ASSERT_EQ(_signedArea(polygon.at(1)), -12288); // biggest interior ring
+ ASSERT_EQ(_signedArea(polygon.at(2)), -2048); // smallest interior ring
+ ASSERT_EQ(_signedArea(polygon.at(3)), -3072); // second largest interior ring
+
+ limitHoles(polygon, 2);
+
+ // output: polygon 1 has 1 exterior, 2 interior
+ ASSERT_EQ(polygon.size(), 3u);
+
+ // ensure we've kept the exterior ring
+ ASSERT_EQ(original.at(0), polygon.at(0));
+
+ // ensure we've kept the two largest interior rings
+ ASSERT_EQ(original.at(1), polygon.at(1));
+ ASSERT_EQ(original.at(3), polygon.at(2));
+
+}
diff --git a/test/tile/raster_tile.test.cpp b/test/tile/raster_tile.test.cpp
index 0d599ceae0..5cfc274be0 100644
--- a/test/tile/raster_tile.test.cpp
+++ b/test/tile/raster_tile.test.cpp
@@ -9,6 +9,7 @@
#include <mbgl/style/style.hpp>
#include <mbgl/style/update_parameters.hpp>
#include <mbgl/annotation/annotation_manager.hpp>
+#include <mbgl/renderer/raster_bucket.hpp>
using namespace mbgl;
@@ -45,5 +46,19 @@ TEST(RasterTile, onError) {
RasterTileTest test;
RasterTile tile(OverscaledTileID(0, 0, 0), test.updateParameters, test.tileset);
tile.onError(std::make_exception_ptr(std::runtime_error("test")));
+ EXPECT_FALSE(tile.isRenderable());
+}
+
+TEST(RasterTile, onParsed) {
+ RasterTileTest test;
+ RasterTile tile(OverscaledTileID(0, 0, 0), test.updateParameters, test.tileset);
+ tile.onParsed(std::make_unique<RasterBucket>(UnassociatedImage{}));
EXPECT_TRUE(tile.isRenderable());
}
+
+TEST(RasterTile, onParsedEmpty) {
+ RasterTileTest test;
+ RasterTile tile(OverscaledTileID(0, 0, 0), test.updateParameters, test.tileset);
+ tile.onParsed(nullptr);
+ EXPECT_FALSE(tile.isRenderable());
+}
diff --git a/test/tile/vector_tile.test.cpp b/test/tile/vector_tile.test.cpp
index e34629bdba..49fdcbd9f8 100644
--- a/test/tile/vector_tile.test.cpp
+++ b/test/tile/vector_tile.test.cpp
@@ -60,8 +60,12 @@ TEST(VectorTile, Issue7615) {
style::SymbolLayer symbolLayer("symbol", "source");
auto symbolBucket = std::make_shared<SymbolBucket>(
- MapMode::Continuous, style::SymbolLayoutProperties::Evaluated(), false, false);
-
+ style::SymbolLayoutProperties::Evaluated(),
+ std::unordered_map<
+ std::string,
+ std::pair<style::IconPaintProperties::Evaluated, style::TextPaintProperties::Evaluated>>(),
+ 0.0f, false, false);
+
// Simulate placement of a symbol layer.
tile.onPlacement(GeometryTile::PlacementResult {
{{
diff --git a/test/util/http_timeout.test.cpp b/test/util/http_timeout.test.cpp
index e99c703159..c9373d955d 100644
--- a/test/util/http_timeout.test.cpp
+++ b/test/util/http_timeout.test.cpp
@@ -2,22 +2,25 @@
#include <mbgl/util/logging.hpp>
#include <mbgl/util/http_timeout.hpp>
-#include <regex>
-#include <iostream>
using namespace mbgl;
using namespace mbgl::http;
TEST(HttpRetry, OtherError) {
- //Non-retryable
+ // Non-retryable
ASSERT_EQ(Duration::max(), errorRetryTimeout(Response::Error::Reason::Other, 1));
}
+TEST(HttpRetry, NotFound) {
+ // Non-retryable
+ ASSERT_EQ(Duration::max(), errorRetryTimeout(Response::Error::Reason::NotFound, 1));
+}
+
TEST(HttpRetry, ServerError) {
// 1-3 failures -> 1 sec
ASSERT_EQ(Seconds(1), errorRetryTimeout(Response::Error::Reason::Server, 1));
ASSERT_EQ(Seconds(1), errorRetryTimeout(Response::Error::Reason::Server, 3));
-
+
// After 3, exponential backoff
ASSERT_EQ(Seconds(2), errorRetryTimeout(Response::Error::Reason::Server, 4));
ASSERT_EQ(Seconds(1u << 31), errorRetryTimeout(Response::Error::Reason::Server, 50));
@@ -32,8 +35,8 @@ TEST(HttpRetry, ConnectionError) {
TEST(HttpRetry, RateLimit) {
// Pre-set value from header
ASSERT_EQ(Seconds(1), errorRetryTimeout(Response::Error::Reason::Server, 1, { util::now() + Seconds(1) }));
-
- //Default
+
+ // Default
ASSERT_EQ(Seconds(5), errorRetryTimeout(Response::Error::Reason::RateLimit, 1, {}));
}
diff --git a/test/util/image.test.cpp b/test/util/image.test.cpp
index b15ddc1b3f..0cd4a7d8af 100644
--- a/test/util/image.test.cpp
+++ b/test/util/image.test.cpp
@@ -86,6 +86,35 @@ TEST(Image, WebPTile) {
}
#endif // !defined(__ANDROID__) && !defined(__APPLE__) && !defined(QT_IMAGE_DECODERS)
+TEST(Image, Copy) {
+ PremultipliedImage src5({5, 5});
+ PremultipliedImage dst5({5, 5});
+ PremultipliedImage src10({10, 10});
+ PremultipliedImage dst10({10, 10});
+
+ EXPECT_THROW(PremultipliedImage::copy(src5, dst10, {0, 0}, {0, 0}, {6, 0}), std::out_of_range);
+ EXPECT_THROW(PremultipliedImage::copy(src5, dst10, {0, 0}, {0, 0}, {0, 6}), std::out_of_range);
+ EXPECT_THROW(PremultipliedImage::copy(src5, dst10, {1, 1}, {0, 0}, {5, 0}), std::out_of_range);
+ EXPECT_THROW(PremultipliedImage::copy(src5, dst10, {1, 1}, {0, 0}, {0, 5}), std::out_of_range);
+
+ EXPECT_THROW(PremultipliedImage::copy(src10, dst5, {0, 0}, {0, 0}, {6, 0}), std::out_of_range);
+ EXPECT_THROW(PremultipliedImage::copy(src10, dst5, {0, 0}, {0, 0}, {0, 6}), std::out_of_range);
+ EXPECT_THROW(PremultipliedImage::copy(src10, dst5, {0, 0}, {1, 1}, {5, 0}), std::out_of_range);
+ EXPECT_THROW(PremultipliedImage::copy(src10, dst5, {0, 0}, {1, 1}, {0, 5}), std::out_of_range);
+
+ const uint32_t max = std::numeric_limits<uint32_t>::max();
+
+ EXPECT_THROW(PremultipliedImage::copy(src10, dst10, {max, 0}, {0, 0}, {1, 0}), std::out_of_range);
+ EXPECT_THROW(PremultipliedImage::copy(src10, dst10, {0, max}, {0, 0}, {0, 1}), std::out_of_range);
+ EXPECT_THROW(PremultipliedImage::copy(src10, dst10, {0, 0}, {max, 0}, {1, 0}), std::out_of_range);
+ EXPECT_THROW(PremultipliedImage::copy(src10, dst10, {0, 0}, {0, max}, {0, 1}), std::out_of_range);
+
+ EXPECT_THROW(PremultipliedImage::copy(src10, dst10, {1, 0}, {0, 0}, {max, 0}), std::out_of_range);
+ EXPECT_THROW(PremultipliedImage::copy(src10, dst10, {0, 1}, {0, 0}, {0, max}), std::out_of_range);
+ EXPECT_THROW(PremultipliedImage::copy(src10, dst10, {0, 0}, {1, 0}, {max, 0}), std::out_of_range);
+ EXPECT_THROW(PremultipliedImage::copy(src10, dst10, {0, 0}, {0, 1}, {0, max}), std::out_of_range);
+}
+
TEST(Image, Premultiply) {
UnassociatedImage rgba({ 1, 1 });
rgba.data[0] = 255;
diff --git a/test/util/mapbox.test.cpp b/test/util/mapbox.test.cpp
index 452106d6e6..299f0df833 100644
--- a/test/util/mapbox.test.cpp
+++ b/test/util/mapbox.test.cpp
@@ -3,8 +3,7 @@
#include <mbgl/util/logging.hpp>
#include <mbgl/util/mapbox.hpp>
#include <mbgl/util/constants.hpp>
-#include <regex>
-#include <iostream>
+#include <stdexcept>
using namespace mbgl;
diff --git a/test/util/memory.test.cpp b/test/util/memory.test.cpp
index 984e7a3e24..d49c49018f 100644
--- a/test/util/memory.test.cpp
+++ b/test/util/memory.test.cpp
@@ -1,4 +1,5 @@
#include <mbgl/test/stub_file_source.hpp>
+#include <mbgl/test/getrss.hpp>
#include <mbgl/test/util.hpp>
#include <mbgl/map/map.hpp>
@@ -21,29 +22,6 @@
using namespace mbgl;
using namespace std::literals::string_literals;
-long getRSS() {
- auto statm = util::read_file("/proc/self/statm");
-
- std::vector<std::string> stats;
- std::istringstream stream(statm);
-
- std::copy(std::istream_iterator<std::string>(stream),
- std::istream_iterator<std::string>(),
- std::back_inserter(stats));
-
- return std::stol(stats[1]) * getpagesize();
-}
-
-bool isUsingJemalloc() {
- const char* preload = getenv("LD_PRELOAD");
-
- if (preload) {
- return std::string(preload).find("libjemalloc.so") != std::string::npos;
- } else {
- return false;
- }
-}
-
class MemoryTest {
public:
MemoryTest() {
@@ -109,16 +87,31 @@ TEST(Memory, Raster) {
test::render(map, test.view);
}
+/**
+On CI, we only run the memory footprint test in the Qt build, because it uses
+jemalloc, which yields more consistent memory usage results. To force it to
+run locally, use `DO_MEMORY_FOOTPRINT=1 make run-test-Memory.Footprint.
+*/
+bool shouldRunFootprint() {
+ const char* preload = getenv("LD_PRELOAD");
+
+ if (preload) {
+ return std::string(preload).find("libjemalloc.so") != std::string::npos;
+ } else {
+ return getenv("DO_MEMORY_FOOTPRINT");
+ }
+}
+
// This test will measure the size of a Map object
// after rendering a raster and a vector style. The
// idea is to try to keep the memory footprint within
// reasonable limits, so this test acts more like a
// safeguard.
TEST(Memory, Footprint) {
- if (!isUsingJemalloc()) {
+ if (!shouldRunFootprint()) {
return;
}
-
+
MemoryTest test;
auto renderMap = [&](Map& map, const char* style){
@@ -141,7 +134,7 @@ TEST(Memory, Footprint) {
std::vector<std::unique_ptr<Map>> maps;
unsigned runs = 15;
- long vectorInitialRSS = getRSS();
+ long vectorInitialRSS = mbgl::test::getCurrentRSS();
for (unsigned i = 0; i < runs; ++i) {
auto vector = std::make_unique<Map>(test.backend, Size{ 256, 256 }, 2, test.fileSource,
test.threadPool, MapMode::Still);
@@ -149,9 +142,9 @@ TEST(Memory, Footprint) {
maps.push_back(std::move(vector));
};
- double vectorFootprint = (getRSS() - vectorInitialRSS) / double(runs);
+ double vectorFootprint = (mbgl::test::getCurrentRSS() - vectorInitialRSS) / double(runs);
- long rasterInitialRSS = getRSS();
+ long rasterInitialRSS = mbgl::test::getCurrentRSS();
for (unsigned i = 0; i < runs; ++i) {
auto raster = std::make_unique<Map>(test.backend, Size{ 256, 256 }, 2, test.fileSource,
test.threadPool, MapMode::Still);
@@ -159,7 +152,10 @@ TEST(Memory, Footprint) {
maps.push_back(std::move(raster));
};
- double rasterFootprint = (getRSS() - rasterInitialRSS) / double(runs);
+ double rasterFootprint = (mbgl::test::getCurrentRSS() - rasterInitialRSS) / double(runs);
+
+ RecordProperty("vectorFootprint", vectorFootprint);
+ RecordProperty("rasterFootprint", rasterFootprint);
ASSERT_LT(vectorFootprint, 65 * 1024 * 1024) << "\
mbgl::Map footprint over 65MB for vector styles.";
diff --git a/test/util/merge_lines.test.cpp b/test/util/merge_lines.test.cpp
index 9a8f01ef35..8a3a400887 100644
--- a/test/util/merge_lines.test.cpp
+++ b/test/util/merge_lines.test.cpp
@@ -8,95 +8,131 @@ const std::u16string bbb = u"b";
using namespace mbgl;
-TEST(MergeLines, SameText) {
- // merges lines with the same text
- std::vector<mbgl::SymbolFeature> input1 = {
- { FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}}}, aaa, {}, 0 },
- { FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, bbb, {}, 0 },
- { FeatureType::LineString, {{{8, 0}, {9, 0}}}, aaa, {}, 0 },
- { FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, aaa, {}, 0 },
- { FeatureType::LineString, {{{6, 0}, {7, 0}, {8, 0}}}, aaa, {}, 0 },
- { FeatureType::LineString, {{{5, 0}, {6, 0}}}, aaa, {}, 0 }
+class GeometryTileFeatureStub : public GeometryTileFeature {
+public:
+ GeometryTileFeatureStub(optional<FeatureIdentifier> id_, FeatureType type_, GeometryCollection geometry_,
+ std::unordered_map<std::string, Value> properties_) :
+ id(id_),
+ type(type_),
+ geometry(geometry_),
+ properties(properties_)
+ {}
+
+ FeatureType getType() const override { return type; }
+ optional<Value> getValue(const std::string& key) const override {
+ auto it = properties.find(key);
+ if (it != properties.end()) {
+ return it->second;
+ }
+ return {};
};
+ std::unordered_map<std::string,Value> getProperties() const override { return properties; };
+ optional<FeatureIdentifier> getID() const override { return id; };
+ GeometryCollection getGeometries() const override { return geometry; };
+
+ optional<FeatureIdentifier> id;
+ FeatureType type;
+ GeometryCollection geometry;
+ std::unordered_map<std::string,Value> properties;
+};
+
+class SymbolFeatureStub : public SymbolFeature {
+public:
+ SymbolFeatureStub(optional<FeatureIdentifier> id_, FeatureType type_, GeometryCollection geometry_,
+ std::unordered_map<std::string, Value> properties_, optional<std::u16string> text_,
+ optional<std::string> icon_, std::size_t index_) :
+ SymbolFeature(std::make_unique<GeometryTileFeatureStub>(id_, type_, geometry_, properties_))
+ {
+ text = text_;
+ icon = icon_;
+ index = index_;
+ }
+};
- const std::vector<mbgl::SymbolFeature> expected1 = {
- { FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}}}, aaa, {}, 0 },
- { FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, bbb, {}, 0 },
- { FeatureType::LineString, {{{5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}}}, aaa, {}, 0 },
- { FeatureType::LineString, {{}}, aaa, {}, 0 },
- { FeatureType::LineString, {{}}, aaa, {}, 0 },
- { FeatureType::LineString, {{}}, aaa, {}, 0 }
+TEST(MergeLines, SameText) {
+ // merges lines with the same text
+ std::vector<mbgl::SymbolFeature> input1;
+ input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}}}, {}, aaa, {}, 0));
+ input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, {}, bbb, {}, 0));
+ input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{8, 0}, {9, 0}}}, {}, aaa, {}, 0));
+ input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, {}, aaa, {}, 0));
+ input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{6, 0}, {7, 0}, {8, 0}}}, {}, aaa, {}, 0));
+ input1.push_back(SymbolFeatureStub({}, FeatureType::LineString, {{{5, 0}, {6, 0}}}, {}, aaa, {}, 0));
+
+ const std::vector<GeometryTileFeatureStub> expected1 = {
+ { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}}}, {} },
+ { {}, FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, {} },
+ { {}, FeatureType::LineString, {{{5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}}}, {} },
+ { {}, FeatureType::LineString, {{}}, {} },
+ { {}, FeatureType::LineString, {{}}, {} },
+ { {}, FeatureType::LineString, {{}}, {} }
};
-
+
mbgl::util::mergeLines(input1);
for (int i = 0; i < 6; i++) {
- EXPECT_TRUE(input1[i].geometry == expected1[i].geometry);
+ EXPECT_TRUE(input1[i].geometry == expected1[i].getGeometries());
}
}
TEST(MergeLines, BothEnds) {
// mergeLines handles merge from both ends
- std::vector<mbgl::SymbolFeature> input2 = {
- { FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}}}, aaa, {}, 0 },
- { FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, aaa, {}, 0 },
- { FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, aaa, {}, 0 }
- };
-
- const std::vector<mbgl::SymbolFeature> expected2 = {
- { FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}}}, aaa, {}, 0 },
- { FeatureType::LineString, {{}}, aaa, {}, 0 },
- { FeatureType::LineString, {{}}, aaa, {}, 0 }
+ std::vector<mbgl::SymbolFeature> input2;
+ input2.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}}}, {}, aaa, {}, 0 });
+ input2.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{4, 0}, {5, 0}, {6, 0}}}, {}, aaa, {}, 0 });
+ input2.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, {}, aaa, {}, 0 });
+
+ const std::vector<GeometryTileFeatureStub> expected2 = {
+ { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}}}, {} },
+ { {}, FeatureType::LineString, {{}}, {} },
+ { {}, FeatureType::LineString, {{}}, {} }
};
mbgl::util::mergeLines(input2);
for (int i = 0; i < 3; i++) {
- EXPECT_TRUE(input2[i].geometry == expected2[i].geometry);
+ EXPECT_TRUE(input2[i].geometry == expected2[i].getGeometries());
}
}
TEST(MergeLines, CircularLines) {
// mergeLines handles circular lines
- std::vector<mbgl::SymbolFeature> input3 = {
- { FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}}}, aaa, {}, 0 },
- { FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, aaa, {}, 0 },
- { FeatureType::LineString, {{{4, 0}, {0, 0}}}, aaa, {}, 0 }
- };
-
- const std::vector<mbgl::SymbolFeature> expected3 = {
- { FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {0, 0}}}, aaa, {}, 0 },
- { FeatureType::LineString, {{}}, aaa, {}, 0 },
- { FeatureType::LineString, {{}}, aaa, {}, 0 }
+ std::vector<mbgl::SymbolFeature> input3;
+ input3.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}}}, {}, aaa, {}, 0 });
+ input3.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{2, 0}, {3, 0}, {4, 0}}}, {}, aaa, {}, 0 });
+ input3.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{{4, 0}, {0, 0}}}, {}, aaa, {}, 0 });
+
+ const std::vector<GeometryTileFeatureStub> expected3 = {
+ { {}, FeatureType::LineString, {{{0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {0, 0}}}, {} },
+ { {}, FeatureType::LineString, {{}}, {} },
+ { {}, FeatureType::LineString, {{}}, {} }
};
mbgl::util::mergeLines(input3);
for (int i = 0; i < 3; i++) {
- EXPECT_TRUE(input3[i].geometry == expected3[i].geometry);
+ EXPECT_TRUE(input3[i].geometry == expected3[i].getGeometries());
}
}
TEST(MergeLines, EmptyOuterGeometry) {
- std::vector<mbgl::SymbolFeature> input = {
- { FeatureType::LineString, {}, aaa, {}, 0 },
- };
+ std::vector<mbgl::SymbolFeature> input;
+ input.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {}, {}, aaa, {}, 0 });
- const std::vector<mbgl::SymbolFeature> expected = input;
+ const std::vector<GeometryTileFeatureStub> expected = { { {}, FeatureType::LineString, {}, {} } };
mbgl::util::mergeLines(input);
- EXPECT_EQ(expected[0].geometry, input[0].geometry);
+ EXPECT_EQ(input[0].geometry, expected[0].getGeometries());
}
TEST(MergeLines, EmptyInnerGeometry) {
- std::vector<mbgl::SymbolFeature> input = {
- { FeatureType::LineString, {{}}, aaa, {}, 0 },
- };
+ std::vector<mbgl::SymbolFeature> input;
+ input.push_back(SymbolFeatureStub { {}, FeatureType::LineString, {{}}, {}, aaa, {}, 0 });
- const std::vector<mbgl::SymbolFeature> expected = input;
+ const std::vector<GeometryTileFeatureStub> expected = { { {}, FeatureType::LineString, {{}}, {} } };
mbgl::util::mergeLines(input);
- EXPECT_EQ(expected[0].geometry, input[0].geometry);
+ EXPECT_EQ(input[0].geometry, expected[0].getGeometries());
}
diff --git a/test/util/offscreen_texture.test.cpp b/test/util/offscreen_texture.test.cpp
index 31fb985394..feaabf2630 100644
--- a/test/util/offscreen_texture.test.cpp
+++ b/test/util/offscreen_texture.test.cpp
@@ -4,6 +4,7 @@
#include <mbgl/gl/context.hpp>
#include <mbgl/gl/headless_backend.hpp>
#include <mbgl/gl/offscreen_view.hpp>
+#include <mbgl/map/backend_scope.hpp>
#include <mbgl/util/offscreen_texture.hpp>
@@ -11,6 +12,7 @@ using namespace mbgl;
TEST(OffscreenTexture, EmptyRed) {
HeadlessBackend backend { test::sharedDisplay() };
+ BackendScope scope { backend };
OffscreenView view(backend.getContext(), { 512, 256 });
view.bind();
@@ -68,6 +70,7 @@ struct Buffer {
TEST(OffscreenTexture, RenderToTexture) {
HeadlessBackend backend { test::sharedDisplay() };
+ BackendScope scope { backend };
auto& context = backend.getContext();
MBGL_CHECK_ERROR(glEnable(GL_BLEND));
@@ -116,50 +119,45 @@ void main() {
Buffer triangleBuffer({ 0, 0.5, 0.5, -0.5, -0.5, -0.5 });
Buffer viewportBuffer({ -1, -1, 1, -1, -1, 1, 1, 1 });
- // Make sure the texture gets destructed before we call context.reset();
- {
- OffscreenView view(context, { 512, 256 });
- view.bind();
-
- // First, draw red to the bound FBO.
- context.clear(Color::red(), {}, {});
-
- // Then, create a texture, bind it, and render yellow to that texture. This should not
- // affect the originally bound FBO.
- OffscreenTexture texture(context, { 128, 128 });
- texture.bind();
-
- context.clear(Color(), {}, {});
-
- MBGL_CHECK_ERROR(glUseProgram(paintShader.program));
- MBGL_CHECK_ERROR(glBindBuffer(GL_ARRAY_BUFFER, triangleBuffer.buffer));
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(paintShader.a_pos));
- MBGL_CHECK_ERROR(
- glVertexAttribPointer(paintShader.a_pos, 2, GL_FLOAT, GL_FALSE, 0, nullptr));
- MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, 3));
-
- auto image = texture.readStillImage();
- test::checkImage("test/fixtures/offscreen_texture/render-to-texture", image, 0, 0);
-
- // Now reset the FBO back to normal and retrieve the original (restored) framebuffer.
- view.bind();
-
- image = view.readStillImage();
- test::checkImage("test/fixtures/offscreen_texture/render-to-fbo", image, 0, 0);
-
- // Now, composite the Framebuffer texture we've rendered to onto the main FBO.
- context.bindTexture(texture.getTexture(), 0, gl::TextureFilter::Linear);
- MBGL_CHECK_ERROR(glUseProgram(compositeShader.program));
- MBGL_CHECK_ERROR(glUniform1i(u_texture, 0));
- MBGL_CHECK_ERROR(glBindBuffer(GL_ARRAY_BUFFER, viewportBuffer.buffer));
- MBGL_CHECK_ERROR(glEnableVertexAttribArray(compositeShader.a_pos));
- MBGL_CHECK_ERROR(
- glVertexAttribPointer(compositeShader.a_pos, 2, GL_FLOAT, GL_FALSE, 0, nullptr));
- MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
-
- image = view.readStillImage();
- test::checkImage("test/fixtures/offscreen_texture/render-to-fbo-composited", image, 0, 0.1);
- }
+ OffscreenView view(context, { 512, 256 });
+ view.bind();
+
+ // First, draw red to the bound FBO.
+ context.clear(Color::red(), {}, {});
+
+ // Then, create a texture, bind it, and render yellow to that texture. This should not
+ // affect the originally bound FBO.
+ OffscreenTexture texture(context, { 128, 128 });
+ texture.bind();
+
+ context.clear(Color(), {}, {});
+
+ MBGL_CHECK_ERROR(glUseProgram(paintShader.program));
+ MBGL_CHECK_ERROR(glBindBuffer(GL_ARRAY_BUFFER, triangleBuffer.buffer));
+ MBGL_CHECK_ERROR(glEnableVertexAttribArray(paintShader.a_pos));
+ MBGL_CHECK_ERROR(
+ glVertexAttribPointer(paintShader.a_pos, 2, GL_FLOAT, GL_FALSE, 0, nullptr));
+ MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, 3));
+
+ auto image = texture.readStillImage();
+ test::checkImage("test/fixtures/offscreen_texture/render-to-texture", image, 0, 0);
+
+ // Now reset the FBO back to normal and retrieve the original (restored) framebuffer.
+ view.bind();
- context.reset();
+ image = view.readStillImage();
+ test::checkImage("test/fixtures/offscreen_texture/render-to-fbo", image, 0, 0);
+
+ // Now, composite the Framebuffer texture we've rendered to onto the main FBO.
+ context.bindTexture(texture.getTexture(), 0, gl::TextureFilter::Linear);
+ MBGL_CHECK_ERROR(glUseProgram(compositeShader.program));
+ MBGL_CHECK_ERROR(glUniform1i(u_texture, 0));
+ MBGL_CHECK_ERROR(glBindBuffer(GL_ARRAY_BUFFER, viewportBuffer.buffer));
+ MBGL_CHECK_ERROR(glEnableVertexAttribArray(compositeShader.a_pos));
+ MBGL_CHECK_ERROR(
+ glVertexAttribPointer(compositeShader.a_pos, 2, GL_FLOAT, GL_FALSE, 0, nullptr));
+ MBGL_CHECK_ERROR(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
+
+ image = view.readStillImage();
+ test::checkImage("test/fixtures/offscreen_texture/render-to-fbo-composited", image, 0, 0.1);
}
diff --git a/test/util/thread.test.cpp b/test/util/thread.test.cpp
index fc41fd4b78..972bddf383 100644
--- a/test/util/thread.test.cpp
+++ b/test/util/thread.test.cpp
@@ -3,6 +3,8 @@
#include <mbgl/test/util.hpp>
+#include <atomic>
+
using namespace mbgl::util;
class TestObject {
@@ -216,3 +218,79 @@ TEST(Thread, WorkRequestDeletionCancelsImmediately) {
started.get_future().get();
request1.reset();
}
+
+TEST(Thread, DeletePausedThread) {
+ RunLoop loop;
+
+ std::atomic_bool flag(false);
+
+ auto thread = std::make_unique<Thread<TestWorker>>(ThreadContext{"Test"});
+ thread->pause();
+ thread->invoke(&TestWorker::send, [&] { flag = true; }, [] {});
+
+ // Should not hang.
+ thread.reset();
+
+ // Should process the queue before destruction.
+ ASSERT_TRUE(flag);
+}
+
+TEST(Thread, Pause) {
+ RunLoop loop;
+
+ std::atomic_bool flag(false);
+
+ Thread<TestWorker> thread1({"Test1"});
+ thread1.pause();
+
+ Thread<TestWorker> thread2({"Test2"});
+
+ for (unsigned i = 0; i < 100; ++i) {
+ thread1.invoke(&TestWorker::send, [&] { flag = true; }, [] {});
+ thread2.invoke(&TestWorker::send, [&] { ASSERT_FALSE(flag); }, [] {});
+ }
+
+ // Queue a message at the end of thread2 queue.
+ thread2.invoke(&TestWorker::send, [&] { loop.stop(); }, [] {});
+ loop.run();
+}
+
+TEST(Thread, Resume) {
+ RunLoop loop;
+
+ std::atomic_bool flag(false);
+
+ Thread<TestWorker> thread({"Test"});
+ thread.pause();
+
+ for (unsigned i = 0; i < 100; ++i) {
+ thread.invoke(&TestWorker::send, [&] { flag = true; }, [] {});
+ }
+
+ // Thread messages are ondered, when we resume, this is going
+ // to me the last thing to run on the message queue.
+ thread.invoke(&TestWorker::send, [&] { loop.stop(); }, [] {});
+
+ // This test will be flaky if the thread doesn't get paused.
+ ASSERT_FALSE(flag);
+
+ thread.resume();
+ loop.run();
+
+ ASSERT_TRUE(flag);
+}
+
+TEST(Thread, PauseResume) {
+ RunLoop loop;
+
+ Thread<TestWorker> thread({"Test"});
+
+ // Test if multiple pause/resume work.
+ for (unsigned i = 0; i < 100; ++i) {
+ thread.pause();
+ thread.resume();
+ }
+
+ thread.invoke(&TestWorker::send, [&] { loop.stop(); }, [] {});
+ loop.run();
+}
diff --git a/test/util/url.test.cpp b/test/util/url.test.cpp
index 2acf3cb0db..ca24a5949a 100644
--- a/test/util/url.test.cpp
+++ b/test/util/url.test.cpp
@@ -26,6 +26,9 @@ TEST(URL, isURL) {
TEST(URL, Scheme) {
EXPECT_EQ(URL::Segment({ 0, 4 }), URL("http://example.com/test?query=foo").scheme);
+ EXPECT_EQ(URL::Segment({ 0, 4 }), URL("http://127.0.0.1:8080/test?query=foo").scheme);
+ EXPECT_EQ(URL::Segment({ 0, 4 }), URL("http://[2a01:4f8:c17:3680::386a:6f3d]:8080/test?query=foo").scheme);
+ EXPECT_EQ(URL::Segment({ 0, 4 }), URL("http://user:password@example.com.:80/test?query=foo").scheme);
EXPECT_EQ(URL::Segment({ 0, 0 }), URL("htt").scheme);
EXPECT_EQ(URL::Segment({ 0, 6 }), URL("mapbox://").scheme);
EXPECT_EQ(URL::Segment({ 0, 6 }), URL("mapbox:/#").scheme);
@@ -33,12 +36,17 @@ TEST(URL, Scheme) {
EXPECT_EQ(URL::Segment({ 0, 0 }), URL("").scheme);
EXPECT_EQ(URL::Segment({ 0, 0 }), URL("http?query://baz").scheme);
EXPECT_EQ(URL::Segment({ 0, 0 }), URL(":::").scheme);
+ EXPECT_EQ(URL::Segment({ 0, 0 }), URL("127.0.0.1:8080/test?query=foo").scheme);
+ EXPECT_EQ(URL::Segment({ 0, 0 }), URL("[2a01:4f8:c17:3680::386a:6f3d]:8080/test?query=foo").scheme);
EXPECT_EQ(URL::Segment({ 0, 4 }), URL("data:,Hello%2C%20World!").scheme);
EXPECT_EQ(URL::Segment({ 0, 4 }), URL("data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D").scheme);
}
TEST(URL, Query) {
EXPECT_EQ(URL::Segment({ 23, 10 }), URL("http://example.com/test?query=foo").query);
+ EXPECT_EQ(URL::Segment({ 26, 10 }), URL("http://127.0.0.1:8080/test?query=foo").query);
+ EXPECT_EQ(URL::Segment({ 47, 10 }), URL("http://[2a01:4f8:c17:3680::386a:6f3d]:8080/test?query=foo").query);
+ EXPECT_EQ(URL::Segment({ 41, 10 }), URL("http://user:password@example.com.:80/test?query=foo").query);
EXPECT_EQ(URL::Segment({ 23, 10 }), URL("http://example.com/test?query=foo#page-2").query);
EXPECT_EQ(URL::Segment({ 23, 0 }), URL("http://example.com/test#query=foo?page-2").query);
EXPECT_EQ(URL::Segment({ 0, 10 }), URL("?query=foo").query);
@@ -49,12 +57,17 @@ TEST(URL, Query) {
EXPECT_EQ(URL::Segment({ 12, 0 }), URL("mapbox://bar").query);
EXPECT_EQ(URL::Segment({ 0, 0 }), URL("").query);
EXPECT_EQ(URL::Segment({ 3, 0 }), URL(":::").query);
+ EXPECT_EQ(URL::Segment({ 19, 10 }), URL("127.0.0.1:8080/test?query=foo").query);
+ EXPECT_EQ(URL::Segment({ 40, 10 }), URL("[2a01:4f8:c17:3680::386a:6f3d]:8080/test?query=foo").query);
EXPECT_EQ(URL::Segment({ 23, 0 }), URL("data:,Hello%2C%20World!").query);
EXPECT_EQ(URL::Segment({ 47, 0 }), URL("data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D").query);
}
TEST(URL, Domain) {
EXPECT_EQ(URL::Segment({ 7, 11 }), URL("http://example.com/test?query=foo").domain);
+ EXPECT_EQ(URL::Segment({ 7, 14 }), URL("http://127.0.0.1:8080/test?query=foo").domain);
+ EXPECT_EQ(URL::Segment({ 7, 35 }), URL("http://[2a01:4f8:c17:3680::386a:6f3d]:8080/test?query=foo").domain);
+ EXPECT_EQ(URL::Segment({ 7, 29 }), URL("http://user:password@example.com.:80/test?query=foo").domain);
EXPECT_EQ(URL::Segment({ 5, 11 }), URL("http:example.com/test?query=foo").domain);
EXPECT_EQ(URL::Segment({ 0, 3 }), URL("htt").domain);
EXPECT_EQ(URL::Segment({ 0, 4 }), URL("http?query://baz").domain);
@@ -71,18 +84,25 @@ TEST(URL, Domain) {
EXPECT_EQ(URL::Segment({ 7, 6 }), URL("http://domain?").domain);
EXPECT_EQ(URL::Segment({ 7, 6 }), URL("http://domain?foo").domain);
EXPECT_EQ(URL::Segment({ 3, 0 }), URL(":::").domain);
+ EXPECT_EQ(URL::Segment({ 0, 14 }), URL("127.0.0.1:8080/test?query=foo").domain);
+ EXPECT_EQ(URL::Segment({ 0, 35 }), URL("[2a01:4f8:c17:3680::386a:6f3d]:8080/test?query=foo").domain);
EXPECT_EQ(URL::Segment({ 5, 0 }), URL("data:,Hello%2C%20World!").domain);
EXPECT_EQ(URL::Segment({ 5, 17 }), URL("data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D").domain);
}
TEST(URL, Path) {
EXPECT_EQ(URL::Segment({ 18, 5 }), URL("http://example.com/test?query=foo").path);
+ EXPECT_EQ(URL::Segment({ 21, 5 }), URL("http://127.0.0.1:8080/test?query=foo").path);
+ EXPECT_EQ(URL::Segment({ 42, 5 }), URL("http://[2a01:4f8:c17:3680::386a:6f3d]:8080/test?query=foo").path);
+ EXPECT_EQ(URL::Segment({ 36, 5 }), URL("http://user:password@example.com.:80/test?query=foo").path);
EXPECT_EQ(URL::Segment({ 18, 5 }), URL("http://example.com/test?query=foo#bar").path);
EXPECT_EQ(URL::Segment({ 18, 5 }), URL("http://example.com/test#bar").path);
EXPECT_EQ(URL::Segment({ 18, 0 }), URL("http://example.com?query=foo").path);
EXPECT_EQ(URL::Segment({ 18, 0 }), URL("http://example.com#?query=foo").path);
EXPECT_EQ(URL::Segment({ 18, 1 }), URL("http://example.com/?query=foo").path);
EXPECT_EQ(URL::Segment({ 3, 0 }), URL(":::").path);
+ EXPECT_EQ(URL::Segment({ 14, 5 }), URL("127.0.0.1:8080/test?query=foo").path);
+ EXPECT_EQ(URL::Segment({ 35, 5 }), URL("[2a01:4f8:c17:3680::386a:6f3d]:8080/test?query=foo").path);
EXPECT_EQ(URL::Segment({ 13, 0 }), URL("http://domain").path);
EXPECT_EQ(URL::Segment({ 6, 4 }), URL("domain/foo?bar").path);
EXPECT_EQ(URL::Segment({ 6, 17 }), URL("data:,Hello%2C%20World!").path);