diff options
Diffstat (limited to 'test/api')
-rw-r--r-- | test/api/annotations.test.cpp | 172 | ||||
-rw-r--r-- | test/api/api_misuse.test.cpp | 44 | ||||
-rw-r--r-- | test/api/custom_layer.test.cpp | 22 | ||||
-rw-r--r-- | test/api/query.test.cpp | 52 | ||||
-rw-r--r-- | test/api/recycle_map.cpp | 58 | ||||
-rw-r--r-- | test/api/render_missing.test.cpp | 64 | ||||
-rw-r--r-- | test/api/repeated_render.test.cpp | 75 | ||||
-rw-r--r-- | test/api/zoom_history.cpp | 71 |
8 files changed, 264 insertions, 294 deletions
diff --git a/test/api/annotations.test.cpp b/test/api/annotations.test.cpp index 97ccaae684..9e622f780a 100644 --- a/test/api/annotations.test.cpp +++ b/test/api/annotations.test.cpp @@ -3,37 +3,40 @@ #include <mbgl/util/default_thread_pool.hpp> #include <mbgl/annotation/annotation.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/style/image.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/util/io.hpp> #include <mbgl/util/run_loop.hpp> #include <mbgl/util/color.hpp> +#include <mbgl/renderer/renderer.hpp> +#include <mbgl/gl/headless_frontend.hpp> using namespace mbgl; namespace { +PremultipliedImage namedImage(const std::string& name) { + return decodeImage(util::read_file("test/fixtures/sprites/" + name + ".png")); +} + std::unique_ptr<style::Image> namedMarker(const std::string& name) { - PremultipliedImage image = decodeImage(util::read_file("test/fixtures/sprites/" + name)); - return std::make_unique<style::Image>(std::move(image), 1.0); + return std::make_unique<style::Image>(name, namedImage(name), 1.0); } class AnnotationTest { public: util::RunLoop loop; - HeadlessBackend backend { test::sharedDisplay() }; - BackendScope scope { backend }; - OffscreenView view { backend.getContext() }; StubFileSource fileSource; ThreadPool threadPool { 4 }; - Map map { backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still }; + float pixelRatio { 1 }; + HeadlessFrontend frontend { pixelRatio, fileSource, threadPool }; + Map map { frontend, MapObserver::nullObserver(), frontend.getSize(), pixelRatio, fileSource, + threadPool, MapMode::Still }; void checkRendering(const char * name) { test::checkImage(std::string("test/fixtures/annotations/") + name, - test::render(map, view), 0.0002, 0.1); + frontend.render(map), 0.0002, 0.1); } }; @@ -42,12 +45,12 @@ public: TEST(Annotations, SymbolAnnotation) { AnnotationTest test; - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); - test.map.addAnnotationImage("default_marker", namedMarker("default_marker.png")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.addAnnotationImage(namedMarker("default_marker")); test.map.addAnnotation(SymbolAnnotation { Point<double>(0, 0), "default_marker" }); test.checkRendering("point_annotation"); -// auto size = test.view.getSize(); +// auto size = test.frontend.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); @@ -64,7 +67,7 @@ TEST(Annotations, LineAnnotation) { annotation.color = Color::red(); annotation.width = { 5 }; - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); test.map.addAnnotation(annotation); test.checkRendering("line_annotation"); @@ -79,7 +82,7 @@ TEST(Annotations, FillAnnotation) { FillAnnotation annotation { polygon }; annotation.color = Color::red(); - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); test.map.addAnnotation(annotation); test.checkRendering("fill_annotation"); @@ -92,7 +95,7 @@ TEST(Annotations, AntimeridianAnnotationSmall) { double antimeridian = 180; test.map.setLatLngZoom(mbgl::LatLng(0, antimeridian), 0); - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); LineString<double> line = {{ { antimeridian, 20 }, { antimeridian, -20 } }}; LineAnnotation lineAnnotation { line }; @@ -113,7 +116,7 @@ TEST(Annotations, AntimeridianAnnotationLarge) { double antimeridian = 180; test.map.setLatLngZoom(mbgl::LatLng(0, antimeridian), 0); - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); LineString<double> line = {{ { antimeridian, 20 }, { antimeridian, -20 } }}; LineAnnotation lineAnnotation { line }; @@ -138,30 +141,20 @@ TEST(Annotations, OverlappingFillAnnotation) { FillAnnotation overlaidAnnotation { polygon }; overlaidAnnotation.color = Color::red(); - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); test.map.addAnnotation(underlaidAnnotation); test.map.addAnnotation(overlaidAnnotation); test.checkRendering("overlapping_fill_annotation"); } -TEST(Annotations, StyleSourcedShapeAnnotation) { - AnnotationTest test; - - Polygon<double> polygon = { {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }; - - test.map.setStyleJSON(util::read_file("test/fixtures/api/annotation.json")); - test.map.addAnnotation(StyleSourcedAnnotation { polygon, "annotation" }); - test.checkRendering("style_sourced_shape_annotation"); -} - TEST(Annotations, AddMultiple) { AnnotationTest test; - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); - test.map.addAnnotationImage("default_marker", namedMarker("default_marker.png")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.addAnnotationImage(namedMarker("default_marker")); test.map.addAnnotation(SymbolAnnotation { Point<double> { -10, 0 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); test.map.addAnnotation(SymbolAnnotation { Point<double> { 10, 0 }, "default_marker" }); test.checkRendering("add_multiple"); @@ -170,8 +163,8 @@ TEST(Annotations, AddMultiple) { TEST(Annotations, NonImmediateAdd) { AnnotationTest test; - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); - test::render(test.map, test.view); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); + test.frontend.render(test.map); Polygon<double> polygon = { {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} }; FillAnnotation annotation { polygon }; @@ -184,12 +177,12 @@ TEST(Annotations, NonImmediateAdd) { TEST(Annotations, UpdateSymbolAnnotationGeometry) { AnnotationTest test; - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); - test.map.addAnnotationImage("default_marker", namedMarker("default_marker.png")); - test.map.addAnnotationImage("flipped_marker", namedMarker("flipped_marker.png")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.addAnnotationImage(namedMarker("default_marker")); + test.map.addAnnotationImage(namedMarker("flipped_marker")); AnnotationID point = test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); test.map.updateAnnotation(point, SymbolAnnotation { Point<double> { -10, 0 }, "default_marker" }); test.checkRendering("update_point"); @@ -198,12 +191,12 @@ TEST(Annotations, UpdateSymbolAnnotationGeometry) { TEST(Annotations, UpdateSymbolAnnotationIcon) { AnnotationTest test; - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); - test.map.addAnnotationImage("default_marker", namedMarker("default_marker.png")); - test.map.addAnnotationImage("flipped_marker", namedMarker("flipped_marker.png")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.addAnnotationImage(namedMarker("default_marker")); + test.map.addAnnotationImage(namedMarker("flipped_marker")); AnnotationID point = test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); test.map.updateAnnotation(point, SymbolAnnotation { Point<double> { 0, 0 }, "flipped_marker" }); test.checkRendering("update_icon"); @@ -216,10 +209,10 @@ TEST(Annotations, UpdateLineAnnotationGeometry) { annotation.color = Color::red(); annotation.width = { 5 }; - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); AnnotationID line = test.map.addAnnotation(annotation); - test::render(test.map, test.view); + test.frontend.render(test.map); annotation.geometry = LineString<double> {{ { 0, 0 }, { -45, -45 } }}; test.map.updateAnnotation(line, annotation); @@ -233,10 +226,10 @@ TEST(Annotations, UpdateLineAnnotationStyle) { annotation.color = Color::red(); annotation.width = { 5 }; - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); AnnotationID line = test.map.addAnnotation(annotation); - test::render(test.map, test.view); + test.frontend.render(test.map); annotation.color = Color::green(); annotation.width = { 2 }; @@ -250,10 +243,10 @@ TEST(Annotations, UpdateFillAnnotationGeometry) { FillAnnotation annotation { Polygon<double> { {{ { 0, 0 }, { 0, 45 }, { 45, 45 }, { 45, 0 } }} } }; annotation.color = Color::red(); - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); AnnotationID fill = test.map.addAnnotation(annotation); - test::render(test.map, test.view); + test.frontend.render(test.map); annotation.geometry = Polygon<double> { {{ { 0, 0 }, { 0, 45 }, { 45, 0 } }} }; test.map.updateAnnotation(fill, annotation); @@ -267,10 +260,10 @@ TEST(Annotations, UpdateFillAnnotationStyle) { FillAnnotation annotation { polygon }; annotation.color = Color::red(); - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); AnnotationID fill = test.map.addAnnotation(annotation); - test::render(test.map, test.view); + test.frontend.render(test.map); annotation.color = Color::green(); test.map.updateAnnotation(fill, annotation); @@ -280,11 +273,11 @@ TEST(Annotations, UpdateFillAnnotationStyle) { TEST(Annotations, RemovePoint) { AnnotationTest test; - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); - test.map.addAnnotationImage("default_marker", namedMarker("default_marker.png")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.addAnnotationImage(namedMarker("default_marker")); AnnotationID point = test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); test.map.removeAnnotation(point); test.checkRendering("remove_point"); @@ -298,10 +291,10 @@ TEST(Annotations, RemoveShape) { annotation.color = Color::red(); annotation.width = { 5 }; - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); AnnotationID shape = test.map.addAnnotation(annotation); - test::render(test.map, test.view); + test.frontend.render(test.map); test.map.removeAnnotation(shape); test.checkRendering("remove_shape"); @@ -311,40 +304,53 @@ TEST(Annotations, ImmediateRemoveShape) { AnnotationTest test; test.map.removeAnnotation(test.map.addAnnotation(LineAnnotation { LineString<double>() })); - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); - test::render(test.map, test.view); + test.frontend.render(test.map); } TEST(Annotations, SwitchStyle) { AnnotationTest test; - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); - test.map.addAnnotationImage("default_marker", namedMarker("default_marker.png")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.addAnnotationImage(namedMarker("default_marker")); test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); test.checkRendering("switch_style"); } +TEST(Annotations, ReaddImage) { + AnnotationTest test; + + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.addAnnotationImage(namedMarker("default_marker")); + test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" }); + + test.frontend.render(test.map); + + test.map.addAnnotationImage(std::make_unique<style::Image>("default_marker", namedImage("flipped_marker"), 1.0)); + test.checkRendering("readd_image"); +} + TEST(Annotations, QueryRenderedFeatures) { AnnotationTest test; - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); - test.map.addAnnotationImage("default_marker", namedMarker("default_marker.png")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.addAnnotationImage(namedMarker("default_marker")); test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 0 }, "default_marker" }); test.map.addAnnotation(SymbolAnnotation { Point<double> { 0, 50 }, "default_marker" }); - test::render(test.map, test.view); + test.frontend.render(test.map); - auto features = test.map.queryRenderedFeatures(test.map.pixelForLatLng({ 0, 0 })); + auto features = test.frontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 0, 0 })); EXPECT_EQ(features.size(), 1u); EXPECT_TRUE(!!features[0].id); EXPECT_EQ(*features[0].id, uint64_t(0)); - auto features2 = test.map.queryRenderedFeatures(test.map.pixelForLatLng({ 50, 0 })); + auto features2 = test.frontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 50, 0 })); EXPECT_EQ(features2.size(), 1u); EXPECT_TRUE(!!features2[0].id); EXPECT_EQ(*features2[0].id, uint64_t(1)); @@ -353,11 +359,11 @@ TEST(Annotations, QueryRenderedFeatures) { TEST(Annotations, QueryFractionalZoomLevels) { AnnotationTest test; - auto viewSize = test.view.getSize(); + auto viewSize = test.frontend.getSize(); auto box = ScreenBox { {}, { double(viewSize.width), double(viewSize.height) } }; - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); - test.map.addAnnotationImage("default_marker", namedMarker("default_marker.png")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.addAnnotationImage(namedMarker("default_marker")); std::vector<mbgl::AnnotationID> ids; for (int longitude = 0; longitude < 10; ++longitude) { @@ -369,8 +375,8 @@ TEST(Annotations, QueryFractionalZoomLevels) { test.map.setLatLngZoom({ 5, 5 }, 0); for (uint16_t zoomSteps = 10; zoomSteps <= 20; ++zoomSteps) { test.map.setZoom(zoomSteps / 10.0); - test::render(test.map, test.view); - auto features = test.map.queryRenderedFeatures(box); + test.frontend.render(test.map); + auto features = test.frontend.getRenderer()->queryRenderedFeatures(box); // Filter out repeated features. // See 'edge-cases/null-island' query-test for reference. @@ -385,11 +391,11 @@ TEST(Annotations, QueryFractionalZoomLevels) { TEST(Annotations, VisibleFeatures) { AnnotationTest test; - auto viewSize = test.view.getSize(); + auto viewSize = test.frontend.getSize(); auto box = ScreenBox { {}, { double(viewSize.width), double(viewSize.height) } }; - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); - test.map.addAnnotationImage("default_marker", namedMarker("default_marker.png")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.addAnnotationImage(namedMarker("default_marker")); test.map.setLatLngZoom({ 5, 5 }, 3); std::vector<mbgl::AnnotationID> ids; @@ -401,9 +407,9 @@ TEST(Annotations, VisibleFeatures) { // Change bearing *after* adding annotations causes them to be reordered. test.map.setBearing(45); - test::render(test.map, test.view); + test.frontend.render(test.map); - auto features = test.map.queryRenderedFeatures(box, {}); + auto features = test.frontend.getRenderer()->queryRenderedFeatures(box, {}); auto sortID = [](const Feature& lhs, const Feature& rhs) { return lhs.id < rhs.id; }; auto sameID = [](const Feature& lhs, const Feature& rhs) { return lhs.id == rhs.id; }; std::sort(features.begin(), features.end(), sortID); @@ -412,13 +418,19 @@ TEST(Annotations, VisibleFeatures) { test.map.setBearing(0); test.map.setZoom(4); - test::render(test.map, test.view); - features = test.map.queryRenderedFeatures(box); + test.frontend.render(test.map); + features = test.frontend.getRenderer()->queryRenderedFeatures(box); std::sort(features.begin(), features.end(), sortID); features.erase(std::unique(features.begin(), features.end(), sameID), features.end()); EXPECT_EQ(features.size(), ids.size()); } +TEST(Annotations, TopOffsetPixels) { + AnnotationTest test; + + test.map.addAnnotationImage(namedMarker("default_marker")); + EXPECT_EQ(test.map.getTopOffsetPixelsForAnnotationImage("default_marker"), -28); +} TEST(Annotations, DebugEmpty) { // This test should render nothing, not even the tile borders. Tile borders are only rendered @@ -426,7 +438,7 @@ TEST(Annotations, DebugEmpty) { // should not render them. AnnotationTest test; - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); test.map.setDebug(MapDebugOptions::TileBorders); test.map.setZoom(1); @@ -439,10 +451,10 @@ TEST(Annotations, DebugSparse) { // tiles because they're all empty. AnnotationTest test; - test.map.setStyleJSON(util::read_file("test/fixtures/api/empty.json")); + test.map.getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); test.map.setDebug(MapDebugOptions::TileBorders); test.map.setZoom(1); - test.map.addAnnotationImage("default_marker", namedMarker("default_marker.png")); + test.map.addAnnotationImage(namedMarker("default_marker")); test.map.addAnnotation(SymbolAnnotation { Point<double>(10, 10), "default_marker" }); test.checkRendering("debug_sparse"); diff --git a/test/api/api_misuse.test.cpp b/test/api/api_misuse.test.cpp index af703fddfb..690c1548e5 100644 --- a/test/api/api_misuse.test.cpp +++ b/test/api/api_misuse.test.cpp @@ -3,9 +3,8 @@ #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/renderer/backend_scope.hpp> +#include <mbgl/gl/headless_frontend.hpp> #include <mbgl/storage/online_file_source.hpp> #include <mbgl/util/default_thread_pool.hpp> #include <mbgl/util/exception.hpp> @@ -22,15 +21,14 @@ TEST(API, RenderWithoutCallback) { util::RunLoop loop; - HeadlessBackend backend { test::sharedDisplay() }; - BackendScope scope { backend }; - OffscreenView view { backend.getContext(), { 128, 512 } }; StubFileSource fileSource; ThreadPool threadPool(4); + float pixelRatio { 1 }; + HeadlessFrontend frontend { pixelRatio, fileSource, threadPool }; - std::unique_ptr<Map> map = - std::make_unique<Map>(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still); - map->renderStill(view, nullptr); + auto map = std::make_unique<Map>(frontend, MapObserver::nullObserver(), frontend.getSize(), + pixelRatio, fileSource, threadPool, MapMode::Still); + map->renderStill(nullptr); // Force Map thread to join. map.reset(); @@ -44,31 +42,3 @@ TEST(API, RenderWithoutCallback) { EXPECT_EQ(log->count(logMessage), 1u); } - -TEST(API, RenderWithoutStyle) { - util::RunLoop loop; - - HeadlessBackend backend { test::sharedDisplay() }; - BackendScope scope { backend }; - OffscreenView view { backend.getContext(), { 128, 512 } }; - StubFileSource fileSource; - ThreadPool threadPool(4); - - Map map(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still); - - std::exception_ptr error; - map.renderStill(view, [&](std::exception_ptr error_) { - error = error_; - loop.stop(); - }); - - loop.run(); - - try { - std::rethrow_exception(error); - } catch (const util::MisuseException& ex) { - EXPECT_EQ(std::string(ex.what()), "Map doesn't have a style"); - } catch (const std::exception&) { - EXPECT_TRUE(false) << "Unhandled exception."; - } -} diff --git a/test/api/custom_layer.test.cpp b/test/api/custom_layer.test.cpp index 5a30220cd7..1c514aeca2 100644 --- a/test/api/custom_layer.test.cpp +++ b/test/api/custom_layer.test.cpp @@ -2,11 +2,10 @@ #include <mbgl/gl/gl.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/util/default_thread_pool.hpp> #include <mbgl/storage/default_file_source.hpp> +#include <mbgl/gl/headless_frontend.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/style/layers/custom_layer.hpp> #include <mbgl/style/layers/fill_layer.hpp> #include <mbgl/util/io.hpp> @@ -86,16 +85,15 @@ public: TEST(CustomLayer, Basic) { util::RunLoop loop; - HeadlessBackend backend { test::sharedDisplay() }; - BackendScope scope { backend }; - OffscreenView view { backend.getContext() }; DefaultFileSource fileSource(":memory:", "test/fixtures/api/assets"); ThreadPool threadPool(4); - - Map map(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still); - map.setStyleJSON(util::read_file("test/fixtures/api/water.json")); + float pixelRatio { 1 }; + HeadlessFrontend frontend { pixelRatio, fileSource, threadPool }; + Map map(frontend, MapObserver::nullObserver(), frontend.getSize(), pixelRatio, fileSource, + threadPool, MapMode::Still); + map.getStyle().loadJSON(util::read_file("test/fixtures/api/water.json")); map.setLatLngZoom({ 37.8, -122.5 }, 10); - map.addLayer(std::make_unique<CustomLayer>( + map.getStyle().addLayer(std::make_unique<CustomLayer>( "custom", [] (void* context) { reinterpret_cast<TestLayer*>(context)->initialize(); @@ -110,7 +108,7 @@ TEST(CustomLayer, Basic) { auto layer = std::make_unique<FillLayer>("landcover", "mapbox"); layer->setSourceLayer("landcover"); layer->setFillColor(Color{ 1.0, 1.0, 0.0, 1.0 }); - map.addLayer(std::move(layer)); + map.getStyle().addLayer(std::move(layer)); - test::checkImage("test/fixtures/custom_layer/basic", test::render(map, view), 0.0006, 0.1); + test::checkImage("test/fixtures/custom_layer/basic", frontend.render(map), 0.0006, 0.1); } diff --git a/test/api/query.test.cpp b/test/api/query.test.cpp index c509753d2d..3f3825eb72 100644 --- a/test/api/query.test.cpp +++ b/test/api/query.test.cpp @@ -1,15 +1,15 @@ #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/util/default_thread_pool.hpp> #include <mbgl/test/stub_file_source.hpp> #include <mbgl/test/util.hpp> #include <mbgl/util/image.hpp> #include <mbgl/util/io.hpp> #include <mbgl/util/run_loop.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/style/image.hpp> #include <mbgl/style/source.hpp> +#include <mbgl/renderer/renderer.hpp> +#include <mbgl/gl/headless_frontend.hpp> using namespace mbgl; using namespace mbgl::style; @@ -19,20 +19,20 @@ namespace { class QueryTest { public: QueryTest() { - map.setStyleJSON(util::read_file("test/fixtures/api/query_style.json")); - map.addImage("test-icon", std::make_unique<style::Image>( + map.getStyle().loadJSON(util::read_file("test/fixtures/api/query_style.json")); + map.getStyle().addImage(std::make_unique<style::Image>("test-icon", decodeImage(util::read_file("test/fixtures/sprites/default_marker.png")), 1.0)); - test::render(map, view); + frontend.render(map); } util::RunLoop loop; - HeadlessBackend backend { test::sharedDisplay() }; - BackendScope scope { backend }; - OffscreenView view { backend.getContext() }; StubFileSource fileSource; ThreadPool threadPool { 4 }; - Map map { backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still }; + float pixelRatio { 1 }; + HeadlessFrontend frontend { pixelRatio, fileSource, threadPool }; + Map map { frontend, MapObserver::nullObserver(), frontend.getSize(), pixelRatio, fileSource, + threadPool, MapMode::Still }; }; } // end namespace @@ -40,10 +40,10 @@ public: TEST(Query, QueryRenderedFeatures) { QueryTest test; - auto features1 = test.map.queryRenderedFeatures(test.map.pixelForLatLng({ 0, 0 })); + auto features1 = test.frontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 0, 0 })); EXPECT_EQ(features1.size(), 4u); - auto features2 = test.map.queryRenderedFeatures(test.map.pixelForLatLng({ 9, 9 })); + auto features2 = test.frontend.getRenderer()->queryRenderedFeatures(test.map.pixelForLatLng({ 9, 9 })); EXPECT_EQ(features2.size(), 0u); } @@ -52,16 +52,16 @@ TEST(Query, QueryRenderedFeaturesFilterLayer) { auto zz = test.map.pixelForLatLng({ 0, 0 }); - auto features1 = test.map.queryRenderedFeatures(zz, {{{ "layer1"}}, {}}); + auto features1 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{{ "layer1"}}, {}}); EXPECT_EQ(features1.size(), 1u); - auto features2 = test.map.queryRenderedFeatures(zz, {{{ "layer1", "layer2" }}, {}}); + auto features2 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{{ "layer1", "layer2" }}, {}}); EXPECT_EQ(features2.size(), 2u); - auto features3 = test.map.queryRenderedFeatures(zz, {{{ "foobar" }}, {}}); + auto features3 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{{ "foobar" }}, {}}); EXPECT_EQ(features3.size(), 0u); - auto features4 = test.map.queryRenderedFeatures(zz, {{{ "foobar", "layer3" }}, {}}); + auto features4 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{{ "foobar", "layer3" }}, {}}); EXPECT_EQ(features4.size(), 1u); } @@ -71,22 +71,22 @@ TEST(Query, QueryRenderedFeaturesFilter) { auto zz = test.map.pixelForLatLng({ 0, 0 }); const EqualsFilter eqFilter = { "key1", std::string("value1") }; - auto features1 = test.map.queryRenderedFeatures(zz, {{}, { eqFilter }}); + auto features1 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{}, { eqFilter }}); EXPECT_EQ(features1.size(), 1u); const IdentifierNotEqualsFilter idNotEqFilter = { std::string("feature1") }; - auto features2 = test.map.queryRenderedFeatures(zz, {{{ "layer4" }}, { idNotEqFilter }}); + auto features2 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{{ "layer4" }}, { idNotEqFilter }}); EXPECT_EQ(features2.size(), 0u); const GreaterThanFilter gtFilter = { "key2", 1.0 }; - auto features3 = test.map.queryRenderedFeatures(zz, {{ }, { gtFilter }}); + auto features3 = test.frontend.getRenderer()->queryRenderedFeatures(zz, {{ }, { gtFilter }}); EXPECT_EQ(features3.size(), 1u); } TEST(Query, QuerySourceFeatures) { QueryTest test; - auto features1 = test.map.querySourceFeatures("source3"); + auto features1 = test.frontend.getRenderer()->querySourceFeatures("source3"); EXPECT_EQ(features1.size(), 1u); } @@ -94,15 +94,15 @@ TEST(Query, QuerySourceFeaturesOptionValidation) { QueryTest test; // GeoJSONSource, doesn't require a layer id - auto features = test.map.querySourceFeatures("source3"); + auto features = test.frontend.getRenderer()->querySourceFeatures("source3"); ASSERT_EQ(features.size(), 1u); // VectorSource, requires a layer id - features = test.map.querySourceFeatures("source5"); + features = test.frontend.getRenderer()->querySourceFeatures("source5"); ASSERT_EQ(features.size(), 0u); // RasterSource, not supported - features = test.map.querySourceFeatures("source6"); + features = test.frontend.getRenderer()->querySourceFeatures("source6"); ASSERT_EQ(features.size(), 0u); } @@ -110,15 +110,15 @@ TEST(Query, QuerySourceFeaturesFilter) { QueryTest test; const EqualsFilter eqFilter = { "key1", std::string("value1") }; - auto features1 = test.map.querySourceFeatures("source4", {{}, { eqFilter }}); + auto features1 = test.frontend.getRenderer()->querySourceFeatures("source4", {{}, { eqFilter }}); EXPECT_EQ(features1.size(), 1u); const IdentifierNotEqualsFilter idNotEqFilter = { std::string("feature1") }; - auto features2 = test.map.querySourceFeatures("source4", {{}, { idNotEqFilter }}); + auto features2 = test.frontend.getRenderer()->querySourceFeatures("source4", {{}, { idNotEqFilter }}); EXPECT_EQ(features2.size(), 0u); const GreaterThanFilter gtFilter = { "key2", 1.0 }; - auto features3 = test.map.querySourceFeatures("source4", {{}, { gtFilter }}); + auto features3 = test.frontend.getRenderer()->querySourceFeatures("source4", {{}, { gtFilter }}); EXPECT_EQ(features3.size(), 1u); } diff --git a/test/api/recycle_map.cpp b/test/api/recycle_map.cpp new file mode 100644 index 0000000000..8cd622fe79 --- /dev/null +++ b/test/api/recycle_map.cpp @@ -0,0 +1,58 @@ +#include <mbgl/test/util.hpp> +#include <mbgl/test/stub_file_source.hpp> + +#include <mbgl/gl/headless_frontend.hpp> +#include <mbgl/map/map.hpp> +#include <mbgl/renderer/backend_scope.hpp> +#include <mbgl/storage/online_file_source.hpp> +#include <mbgl/style/layers/symbol_layer.hpp> +#include <mbgl/style/sources/geojson_source.hpp> +#include <mbgl/style/image.hpp> +#include <mbgl/style/style.hpp> +#include <mbgl/util/default_thread_pool.hpp> +#include <mbgl/util/exception.hpp> +#include <mbgl/util/geometry.hpp> +#include <mbgl/util/geojson.hpp> +#include <mbgl/util/io.hpp> +#include <mbgl/util/run_loop.hpp> + +using namespace mbgl; +using namespace mbgl::style; + + +TEST(API, RecycleMapUpdateImages) { + util::RunLoop loop; + + StubFileSource fileSource; + ThreadPool threadPool(4); + float pixelRatio { 1 }; + + HeadlessFrontend frontend { pixelRatio, fileSource, threadPool }; + auto map = std::make_unique<Map>(frontend, MapObserver::nullObserver(), frontend.getSize(), + pixelRatio, fileSource, threadPool, MapMode::Still); + + EXPECT_TRUE(map); + + auto loadStyle = [&](auto markerName, auto markerPath) { + auto source = std::make_unique<GeoJSONSource>("geometry"); + source->setGeoJSON({ Point<double> { 0, 0 } }); + + auto layer = std::make_unique<SymbolLayer>("geometry", "geometry"); + layer->setIconImage({ markerName }); + + map->getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); + map->getStyle().addSource(std::move(source)); + map->getStyle().addLayer(std::move(layer)); + map->getStyle().addImage(std::make_unique<style::Image>(markerName, decodeImage(util::read_file(markerPath)), 1.0)); + }; + + // default marker + + loadStyle("default_marker", "test/fixtures/sprites/default_marker.png"); + test::checkImage("test/fixtures/recycle_map/default_marker", frontend.render(*map), 0.0006, 0.1); + + // flipped marker + + loadStyle("flipped_marker", "test/fixtures/sprites/flipped_marker.png"); + test::checkImage("test/fixtures/recycle_map/flipped_marker", frontend.render(*map), 0.0006, 0.1); +} diff --git a/test/api/render_missing.test.cpp b/test/api/render_missing.test.cpp deleted file mode 100644 index 6e99501708..0000000000 --- a/test/api/render_missing.test.cpp +++ /dev/null @@ -1,64 +0,0 @@ -#include <mbgl/test/util.hpp> -#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/util/default_thread_pool.hpp> -#include <mbgl/storage/default_file_source.hpp> -#include <mbgl/util/image.hpp> -#include <mbgl/util/io.hpp> -#include <mbgl/util/run_loop.hpp> - -#include <future> - -#if TEST_HAS_SERVER -#define TEST_REQUIRES_SERVER(name) name -#else -#define TEST_REQUIRES_SERVER(name) DISABLED_ ## name -#endif - -TEST(API, TEST_REQUIRES_SERVER(RenderMissingTile)) { - using namespace mbgl; - - util::RunLoop loop; - - const auto style = util::read_file("test/fixtures/api/water_missing_tiles.json"); - - HeadlessBackend backend { test::sharedDisplay() }; - BackendScope scope { backend }; - OffscreenView view { backend.getContext(), { 256, 512 } }; - DefaultFileSource fileSource(":memory:", "test/fixtures/api/assets"); - ThreadPool threadPool(4); - - Log::setObserver(std::make_unique<FixtureLogObserver>()); - - Map map(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still); - - std::string message; - - // This host does not respond (== connection error). - // Are you seeing this test fail? Make sure you don't have a server running on port 3001! - map.setStyleJSON(style); - map.renderStill(view, [&](std::exception_ptr err) { - ASSERT_TRUE(err.operator bool()); - try { - std::rethrow_exception(err); - } catch (const std::exception& ex) { - message = ex.what(); - EXPECT_TRUE(message.find("onnect") != std::string::npos); // [C|c]onnect - } - loop.stop(); - }); - - loop.run(); - - auto observer = Log::removeObserver(); - auto flo = dynamic_cast<FixtureLogObserver*>(observer.get()); - EXPECT_EQ(1u, flo->count(FixtureLog::Message( - EventSeverity::Error, Event::Style, -1, - std::string("Failed to load tile 0/0/0=>0 for source mapbox: " + message)))); - auto unchecked = flo->unchecked(); - EXPECT_TRUE(unchecked.empty()) << unchecked; -} diff --git a/test/api/repeated_render.test.cpp b/test/api/repeated_render.test.cpp deleted file mode 100644 index 0b9726d3fa..0000000000 --- a/test/api/repeated_render.test.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include <mbgl/test/util.hpp> -#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/util/default_thread_pool.hpp> -#include <mbgl/storage/default_file_source.hpp> -#include <mbgl/util/image.hpp> -#include <mbgl/util/io.hpp> -#include <mbgl/util/run_loop.hpp> - -#include <future> - -using namespace mbgl; - - -TEST(API, RepeatedRender) { - - util::RunLoop loop; - - const auto style = util::read_file("test/fixtures/api/water.json"); - - HeadlessBackend backend { test::sharedDisplay() }; - BackendScope scope { backend }; - OffscreenView view { backend.getContext(), { 256, 512 } }; - DefaultFileSource fileSource(":memory:", "test/fixtures/api/assets"); - ThreadPool threadPool(4); - - Log::setObserver(std::make_unique<FixtureLogObserver>()); - - Map map(backend, view.getSize(), 1, fileSource, threadPool, MapMode::Still); - - { - map.setStyleJSON(style); - PremultipliedImage result; - map.renderStill(view, [&](std::exception_ptr) { - result = view.readStillImage(); - }); - - while (!result.valid()) { - loop.runOnce(); - } - - ASSERT_EQ(256u, result.size.width); - ASSERT_EQ(512u, result.size.height); -#if !TEST_READ_ONLY - util::write_file("test/fixtures/api/1.png", encodePNG(result)); -#endif - } - - { - map.setStyleJSON(style); - PremultipliedImage result; - map.renderStill(view, [&](std::exception_ptr) { - result = view.readStillImage(); - }); - - while (!result.valid()) { - loop.runOnce(); - } - - ASSERT_EQ(256u, result.size.width); - ASSERT_EQ(512u, result.size.height); -#if !TEST_READ_ONLY - util::write_file("test/fixtures/api/2.png", encodePNG(result)); -#endif - } - - auto observer = Log::removeObserver(); - auto flo = dynamic_cast<FixtureLogObserver*>(observer.get()); - auto unchecked = flo->unchecked(); - EXPECT_TRUE(unchecked.empty()) << unchecked; -} diff --git a/test/api/zoom_history.cpp b/test/api/zoom_history.cpp new file mode 100644 index 0000000000..1b1159bf52 --- /dev/null +++ b/test/api/zoom_history.cpp @@ -0,0 +1,71 @@ +#include <mbgl/test/util.hpp> +#include <mbgl/test/stub_file_source.hpp> + +#include <mbgl/gl/headless_frontend.hpp> +#include <mbgl/map/map.hpp> +#include <mbgl/renderer/backend_scope.hpp> +#include <mbgl/storage/online_file_source.hpp> +#include <mbgl/style/function/camera_function.hpp> +#include <mbgl/style/function/exponential_stops.hpp> +#include <mbgl/style/image.hpp> +#include <mbgl/style/layers/line_layer.hpp> +#include <mbgl/style/sources/geojson_source.hpp> +#include <mbgl/style/style.hpp> +#include <mbgl/util/default_thread_pool.hpp> +#include <mbgl/util/exception.hpp> +#include <mbgl/util/geometry.hpp> +#include <mbgl/util/geojson.hpp> +#include <mbgl/util/io.hpp> +#include <mbgl/util/run_loop.hpp> + +using namespace mbgl; +using namespace mbgl::style; + +TEST(API, ZoomHistory) { + util::RunLoop loop; + + StubFileSource fileSource; + ThreadPool threadPool(4); + float pixelRatio { 1 }; + + HeadlessFrontend frontend { pixelRatio, fileSource, threadPool }; + auto map = std::make_unique<Map>(frontend, MapObserver::nullObserver(), frontend.getSize(), + pixelRatio, fileSource, threadPool, MapMode::Still); + + EXPECT_TRUE(map); + + map->getStyle().loadJSON(util::read_file("test/fixtures/api/empty.json")); + + auto source = std::make_unique<GeoJSONSource>("source"); + source->setGeoJSON({ LineString<double> { { 45, -45 }, { -45, 45 } } }); + map->getStyle().addSource(std::move(source)); + + auto layer = std::make_unique<LineLayer>("layer-1", "source"); + layer->setLineWidth(CameraFunction<float> { ExponentialStops<float> {{ { 0, 8 }, { 1, 16 } }} }); + layer->setLineDasharray({ std::vector<float> { 1, 1 } }); + layer->setLineColor( { Color::black() } ); + map->getStyle().addLayer(std::move(layer)); + + layer = std::make_unique<LineLayer>("layer-2", "source"); + layer->setLineWidth(CameraFunction<float> { ExponentialStops<float> {{ { 0, 4 }, { 1, 8 } }} }); + layer->setLineDasharray({ std::vector<float> { 2, 2 } }); + layer->setLineColor( { Color::red() } ); + map->getStyle().addLayer(std::move(layer)); + + // ZoomHistory.lastIntegerZoom is 1. + map->setZoom(1.0); + frontend.render(*map); + + map->setZoom(0.0); + frontend.render(*map); + + // ZoomHistory.lastIntegerZoom should be 0. + map->setZoom(0.5); + test::checkImage("test/fixtures/zoom_history", frontend.render(*map), 0.0002); + + map->setZoom(1.0); + frontend.render(*map); + + map->setZoom(0.5); + test::checkImage("test/fixtures/zoom_history", frontend.render(*map), 0.0002); +} |