diff options
author | Artem Pavlenko <artem@mapnik.org> | 2020-02-13 11:29:04 +0000 |
---|---|---|
committer | Artem Pavlenko <artem@mapnik.org> | 2020-02-13 11:29:04 +0000 |
commit | e4b90f316f3879508736f3b4c988a68909171125 (patch) | |
tree | 120d86c4768c0a89d6367504f2f7e5e9b28a5b0d /test | |
parent | 4b0eef6104bf8c33bf105b7173dbc5f0f65e1efb (diff) | |
parent | d3535f1ca9f7c12b3c2290da3f347e4f95210425 (diff) | |
download | qtlocation-mapboxgl-e4b90f316f3879508736f3b4c988a68909171125.tar.gz |
Merge branch 'master' into galinelle_setStyle++
Diffstat (limited to 'test')
30 files changed, 880 insertions, 460 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000000..dcde7cd21a --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,188 @@ +add_library( + mbgl-test STATIC EXCLUDE_FROM_ALL + ${PROJECT_SOURCE_DIR}/test/actor/actor.test.cpp + ${PROJECT_SOURCE_DIR}/test/actor/actor_ref.test.cpp + ${PROJECT_SOURCE_DIR}/test/algorithm/update_renderables.test.cpp + ${PROJECT_SOURCE_DIR}/test/algorithm/update_tile_masks.test.cpp + ${PROJECT_SOURCE_DIR}/test/api/annotations.test.cpp + ${PROJECT_SOURCE_DIR}/test/api/api_misuse.test.cpp + ${PROJECT_SOURCE_DIR}/test/api/custom_geometry_source.test.cpp + ${PROJECT_SOURCE_DIR}/test/api/custom_layer.test.cpp + ${PROJECT_SOURCE_DIR}/test/api/query.test.cpp + ${PROJECT_SOURCE_DIR}/test/api/recycle_map.cpp + ${PROJECT_SOURCE_DIR}/test/geometry/dem_data.test.cpp + ${PROJECT_SOURCE_DIR}/test/geometry/line_atlas.test.cpp + ${PROJECT_SOURCE_DIR}/test/gl/bucket.test.cpp + ${PROJECT_SOURCE_DIR}/test/gl/context.test.cpp + ${PROJECT_SOURCE_DIR}/test/gl/gl_functions.test.cpp + ${PROJECT_SOURCE_DIR}/test/gl/object.test.cpp + ${PROJECT_SOURCE_DIR}/test/map/map.test.cpp + ${PROJECT_SOURCE_DIR}/test/map/prefetch.test.cpp + ${PROJECT_SOURCE_DIR}/test/map/transform.test.cpp + ${PROJECT_SOURCE_DIR}/test/math/clamp.test.cpp + ${PROJECT_SOURCE_DIR}/test/math/minmax.test.cpp + ${PROJECT_SOURCE_DIR}/test/math/wrap.test.cpp + ${PROJECT_SOURCE_DIR}/test/platform/settings.test.cpp + ${PROJECT_SOURCE_DIR}/test/programs/symbol_program.test.cpp + ${PROJECT_SOURCE_DIR}/test/renderer/backend_scope.test.cpp + ${PROJECT_SOURCE_DIR}/test/renderer/image_manager.test.cpp + ${PROJECT_SOURCE_DIR}/test/renderer/pattern_atlas.test.cpp + ${PROJECT_SOURCE_DIR}/test/sprite/sprite_loader.test.cpp + ${PROJECT_SOURCE_DIR}/test/sprite/sprite_parser.test.cpp + ${PROJECT_SOURCE_DIR}/test/src/mbgl/test/fixture_log_observer.cpp + ${PROJECT_SOURCE_DIR}/test/src/mbgl/test/getrss.cpp + ${PROJECT_SOURCE_DIR}/test/src/mbgl/test/sqlite3_test_fs.cpp + ${PROJECT_SOURCE_DIR}/test/src/mbgl/test/stub_file_source.cpp + ${PROJECT_SOURCE_DIR}/test/src/mbgl/test/test.cpp + ${PROJECT_SOURCE_DIR}/test/src/mbgl/test/util.cpp + ${PROJECT_SOURCE_DIR}/test/storage/asset_file_source.test.cpp + ${PROJECT_SOURCE_DIR}/test/storage/database_file_source.test.cpp + ${PROJECT_SOURCE_DIR}/test/storage/headers.test.cpp + ${PROJECT_SOURCE_DIR}/test/storage/http_file_source.test.cpp + ${PROJECT_SOURCE_DIR}/test/storage/local_file_source.test.cpp + ${PROJECT_SOURCE_DIR}/test/storage/main_resource_loader.test.cpp + ${PROJECT_SOURCE_DIR}/test/storage/offline.test.cpp + ${PROJECT_SOURCE_DIR}/test/storage/offline_database.test.cpp + ${PROJECT_SOURCE_DIR}/test/storage/offline_download.test.cpp + ${PROJECT_SOURCE_DIR}/test/storage/online_file_source.test.cpp + ${PROJECT_SOURCE_DIR}/test/storage/resource.test.cpp + ${PROJECT_SOURCE_DIR}/test/storage/sqlite.test.cpp + ${PROJECT_SOURCE_DIR}/test/style/conversion/conversion_impl.test.cpp + ${PROJECT_SOURCE_DIR}/test/style/conversion/function.test.cpp + ${PROJECT_SOURCE_DIR}/test/style/conversion/geojson_options.test.cpp + ${PROJECT_SOURCE_DIR}/test/style/conversion/layer.test.cpp + ${PROJECT_SOURCE_DIR}/test/style/conversion/light.test.cpp + ${PROJECT_SOURCE_DIR}/test/style/conversion/property_value.test.cpp + ${PROJECT_SOURCE_DIR}/test/style/conversion/stringify.test.cpp + ${PROJECT_SOURCE_DIR}/test/style/conversion/tileset.test.cpp + ${PROJECT_SOURCE_DIR}/test/style/expression/expression.test.cpp + ${PROJECT_SOURCE_DIR}/test/style/expression/util.test.cpp + ${PROJECT_SOURCE_DIR}/test/style/filter.test.cpp + ${PROJECT_SOURCE_DIR}/test/style/properties.test.cpp + ${PROJECT_SOURCE_DIR}/test/style/property_expression.test.cpp + ${PROJECT_SOURCE_DIR}/test/style/source.test.cpp + ${PROJECT_SOURCE_DIR}/test/style/style.test.cpp + ${PROJECT_SOURCE_DIR}/test/style/style_image.test.cpp + ${PROJECT_SOURCE_DIR}/test/style/style_layer.test.cpp + ${PROJECT_SOURCE_DIR}/test/style/style_parser.test.cpp + ${PROJECT_SOURCE_DIR}/test/text/bidi.test.cpp + ${PROJECT_SOURCE_DIR}/test/text/calculate_tile_distances.test.cpp + ${PROJECT_SOURCE_DIR}/test/text/cross_tile_symbol_index.test.cpp + ${PROJECT_SOURCE_DIR}/test/text/formatted.test.cpp + ${PROJECT_SOURCE_DIR}/test/text/get_anchors.test.cpp + ${PROJECT_SOURCE_DIR}/test/text/glyph_manager.test.cpp + ${PROJECT_SOURCE_DIR}/test/text/glyph_pbf.test.cpp + ${PROJECT_SOURCE_DIR}/test/text/language_tag.test.cpp + ${PROJECT_SOURCE_DIR}/test/text/local_glyph_rasterizer.test.cpp + ${PROJECT_SOURCE_DIR}/test/text/quads.test.cpp + ${PROJECT_SOURCE_DIR}/test/text/shaping.test.cpp + ${PROJECT_SOURCE_DIR}/test/text/tagged_string.test.cpp + ${PROJECT_SOURCE_DIR}/test/tile/custom_geometry_tile.test.cpp + ${PROJECT_SOURCE_DIR}/test/tile/geojson_tile.test.cpp + ${PROJECT_SOURCE_DIR}/test/tile/geometry_tile_data.test.cpp + ${PROJECT_SOURCE_DIR}/test/tile/raster_dem_tile.test.cpp + ${PROJECT_SOURCE_DIR}/test/tile/raster_tile.test.cpp + ${PROJECT_SOURCE_DIR}/test/tile/tile_cache.test.cpp + ${PROJECT_SOURCE_DIR}/test/tile/tile_coordinate.test.cpp + ${PROJECT_SOURCE_DIR}/test/tile/tile_id.test.cpp + ${PROJECT_SOURCE_DIR}/test/tile/vector_tile.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/async_task.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/dtoa.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/geo.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/grid_index.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/http_timeout.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/image.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/mapbox.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/memory.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/merge_lines.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/number_conversions.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/offscreen_texture.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/position.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/projection.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/run_loop.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/string.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/text_conversions.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/thread.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/thread_local.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/tile_cover.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/tile_range.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/timer.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/token.test.cpp + ${PROJECT_SOURCE_DIR}/test/util/url.test.cpp +) + +if(MBGL_WITH_OPENGL) + target_compile_definitions( + mbgl-test + PRIVATE MBGL_RENDER_BACKEND_OPENGL=1 + ) +endif() + +if(WIN32 OR CMAKE_SYSTEM_NAME STREQUAL Android AND ANDROID_NATIVE_API_LEVEL VERSION_LESS 24) + message("Target platform does not support HTTP tests or dependencies not found.") + + set(MBGL_TEST_HAS_TEST_SERVER 0) +else() + set(MBGL_TEST_HAS_TEST_SERVER 1) + target_sources( + mbgl-test + PRIVATE ${PROJECT_SOURCE_DIR}/test/src/mbgl/test/http_server.cpp + ) + set_source_files_properties( + ${PROJECT_SOURCE_DIR}/test/src/mbgl/test/http_server.cpp + PROPERTIES + COMPILE_FLAGS + -Wno-shadow + ) + target_include_directories( + mbgl-test + PRIVATE ${PROJECT_SOURCE_DIR}/vendor/cpp-httplib + ) +endif() + +if(NOT DEFINED ENV{CI}) + set(MBGL_TEST_BUILD_ON_CI 0) +else() + set(MBGL_TEST_BUILD_ON_CI 1) +endif() + +target_compile_definitions( + mbgl-test + PRIVATE TEST_HAS_SERVER=${MBGL_TEST_HAS_TEST_SERVER} CI_BUILD=${MBGL_TEST_BUILD_ON_CI} +) + +target_include_directories( + mbgl-test + PRIVATE + ${PROJECT_SOURCE_DIR}/platform/default/include + ${PROJECT_SOURCE_DIR}/platform/gfx/gl/src + ${PROJECT_SOURCE_DIR}/src + ${PROJECT_SOURCE_DIR}/test/src +) + +target_include_directories( + mbgl-test + PUBLIC ${PROJECT_SOURCE_DIR}/include ${PROJECT_SOURCE_DIR}/test/include +) + +include(${PROJECT_SOURCE_DIR}/vendor/googletest.cmake) + +# Needed for testing private classes +get_target_property(MBGL_CORE_PRIVATE_LIBRARIES mbgl-core LINK_LIBRARIES) + +target_link_libraries( + mbgl-test + PRIVATE + ${MBGL_CORE_PRIVATE_LIBRARIES} + Mapbox::Base::Extras::args + Mapbox::Base::pixelmatch-cpp + mbgl-compiler-options + PUBLIC mbgl-core +) + +target_link_libraries( + mbgl-test + PUBLIC mbgl-vendor-googletest +) + +set_property(TARGET mbgl-test PROPERTY FOLDER Core) diff --git a/test/android/app/build.gradle b/test/android/app/build.gradle index 9f915bbbd0..5c118d4853 100644 --- a/test/android/app/build.gradle +++ b/test/android/app/build.gradle @@ -5,7 +5,7 @@ android { defaultConfig { applicationId = 'com.mapbox.mapboxsdk.maps.test_runner' - minSdkVersion 14 + minSdkVersion 24 targetSdkVersion 28 def abi = 'all' if (project.hasProperty('mapbox.abis')) { @@ -33,7 +33,7 @@ android { externalNativeBuild { cmake { version '3.10.2' - path '../../../next/CMakeLists.txt' + path '../../../CMakeLists.txt' } } buildTypes { diff --git a/test/android/app/src/main/AndroidManifest.xml b/test/android/app/src/main/AndroidManifest.xml index 40767881d1..5311bf0507 100644 --- a/test/android/app/src/main/AndroidManifest.xml +++ b/test/android/app/src/main/AndroidManifest.xml @@ -5,6 +5,8 @@ android:versionName="1.0"> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <application android:allowBackup="false" android:fullBackupContent="false" diff --git a/test/api/custom_layer.test.cpp b/test/api/custom_layer.test.cpp index 2222645147..2cfa7bf400 100644 --- a/test/api/custom_layer.test.cpp +++ b/test/api/custom_layer.test.cpp @@ -1,14 +1,14 @@ #include <mbgl/test/util.hpp> -#include <mbgl/platform/gl_functions.hpp> +#include <mbgl/gfx/headless_frontend.hpp> +#include <mbgl/gl/custom_layer.hpp> +#include <mbgl/gl/defines.hpp> #include <mbgl/map/map.hpp> #include <mbgl/map/map_options.hpp> -#include <mbgl/gl/defines.hpp> -#include <mbgl/gfx/headless_frontend.hpp> +#include <mbgl/platform/gl_functions.hpp> #include <mbgl/storage/resource_options.hpp> -#include <mbgl/style/style.hpp> -#include <mbgl/style/layers/custom_layer.hpp> #include <mbgl/style/layers/fill_layer.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/util/io.hpp> #include <mbgl/util/mat4.hpp> #include <mbgl/util/run_loop.hpp> diff --git a/test/fixtures/expression_equality/within.a.json b/test/fixtures/expression_equality/within.a.json new file mode 100644 index 0000000000..c982681537 --- /dev/null +++ b/test/fixtures/expression_equality/within.a.json @@ -0,0 +1,4 @@ +["within", { + "type": "Polygon", + "coordinates": [[[0, 0], [0, 5], [5, 5], [5, 0], [0, 0]]] + }]
\ No newline at end of file diff --git a/test/fixtures/expression_equality/within.b.json b/test/fixtures/expression_equality/within.b.json new file mode 100644 index 0000000000..e5805c93a1 --- /dev/null +++ b/test/fixtures/expression_equality/within.b.json @@ -0,0 +1,4 @@ +["within", { + "type": "Polygon", + "coordinates": [[[0, 0], [0, 6], [5, 5], [5, 0], [0, 0]]] + }]
\ No newline at end of file diff --git a/test/fixtures/local_glyphs/ping_fang_qt/expected.png b/test/fixtures/local_glyphs/ping_fang_qt/expected.png Binary files differindex 0ede615967..94d086f63f 100644 --- a/test/fixtures/local_glyphs/ping_fang_qt/expected.png +++ b/test/fixtures/local_glyphs/ping_fang_qt/expected.png diff --git a/test/gl/bucket.test.cpp b/test/gl/bucket.test.cpp index 2a7455e17c..9f780fcffa 100644 --- a/test/gl/bucket.test.cpp +++ b/test/gl/bucket.test.cpp @@ -52,8 +52,12 @@ TEST(Buckets, CircleBucket) { ASSERT_FALSE(bucket.needsUpload()); GeometryCollection point { { { 0, 0 } } }; - bucket.addFeature(StubGeometryTileFeature{{}, FeatureType::Point, point, properties}, point, {}, PatternLayerMap(), - 0); + bucket.addFeature(StubGeometryTileFeature{{}, FeatureType::Point, point, properties}, + point, + {}, + PatternLayerMap(), + 0, + CanonicalTileID(0, 0, 0)); ASSERT_TRUE(bucket.hasData()); ASSERT_TRUE(bucket.needsUpload()); @@ -75,8 +79,12 @@ TEST(Buckets, FillBucket) { ASSERT_FALSE(bucket.needsUpload()); GeometryCollection polygon { { { 0, 0 }, { 0, 1 }, { 1, 1 } } }; - bucket.addFeature(StubGeometryTileFeature{{}, FeatureType::Polygon, polygon, properties}, polygon, {}, - PatternLayerMap(), 0); + bucket.addFeature(StubGeometryTileFeature{{}, FeatureType::Polygon, polygon, properties}, + polygon, + {}, + PatternLayerMap(), + 0, + CanonicalTileID(0, 0, 0)); ASSERT_TRUE(bucket.hasData()); ASSERT_TRUE(bucket.needsUpload()); @@ -98,13 +106,21 @@ TEST(Buckets, LineBucket) { // Ignore invalid feature type. GeometryCollection point { { { 0, 0 } } }; - bucket.addFeature(StubGeometryTileFeature{{}, FeatureType::Point, point, properties}, point, {}, PatternLayerMap(), - 0); + bucket.addFeature(StubGeometryTileFeature{{}, FeatureType::Point, point, properties}, + point, + {}, + PatternLayerMap(), + 0, + CanonicalTileID(0, 0, 0)); ASSERT_FALSE(bucket.hasData()); GeometryCollection line { { { 0, 0 }, { 1, 1 } } }; - bucket.addFeature(StubGeometryTileFeature{{}, FeatureType::LineString, line, properties}, line, {}, - PatternLayerMap(), 1); + bucket.addFeature(StubGeometryTileFeature{{}, FeatureType::LineString, line, properties}, + line, + {}, + PatternLayerMap(), + 1, + CanonicalTileID(0, 0, 0)); ASSERT_TRUE(bucket.hasData()); ASSERT_TRUE(bucket.needsUpload()); @@ -123,6 +139,7 @@ TEST(Buckets, SymbolBucket) { bool sortFeaturesByY = false; std::string bucketLeaderID = "test"; std::vector<SymbolInstance> symbolInstances; + std::vector<SortKeyRange> symbolRanges; gl::Context context{ backend }; SymbolBucket bucket{std::move(layout), @@ -134,6 +151,7 @@ TEST(Buckets, SymbolBucket) { sortFeaturesByY, bucketLeaderID, std::move(symbolInstances), + std::move(symbolRanges), 1.0f, false, {}, @@ -150,8 +168,12 @@ TEST(Buckets, SymbolBucket) { // SymbolBucket::addFeature() is a no-op. GeometryCollection point { { { 0, 0 } } }; - bucket.addFeature(StubGeometryTileFeature{{}, FeatureType::Point, std::move(point), properties}, point, {}, - PatternLayerMap(), 0); + bucket.addFeature(StubGeometryTileFeature{{}, FeatureType::Point, std::move(point), properties}, + point, + {}, + PatternLayerMap(), + 0, + CanonicalTileID(0, 0, 0)); ASSERT_FALSE(bucket.hasData()); ASSERT_FALSE(bucket.needsUpload()); diff --git a/test/gl/context.test.cpp b/test/gl/context.test.cpp index 9c709b7597..2135ed9862 100644 --- a/test/gl/context.test.cpp +++ b/test/gl/context.test.cpp @@ -1,18 +1,18 @@ #include <mbgl/test/util.hpp> -#include <mbgl/platform/gl_functions.hpp> -#include <mbgl/gl/context.hpp> -#include <mbgl/map/map.hpp> -#include <mbgl/map/map_options.hpp> #include <mbgl/gfx/backend_scope.hpp> -#include <mbgl/gl/defines.hpp> #include <mbgl/gfx/headless_frontend.hpp> +#include <mbgl/gl/context.hpp> +#include <mbgl/gl/custom_layer.hpp> +#include <mbgl/gl/defines.hpp> #include <mbgl/gl/renderable_resource.hpp> +#include <mbgl/map/map.hpp> +#include <mbgl/map/map_options.hpp> +#include <mbgl/platform/gl_functions.hpp> #include <mbgl/storage/resource_options.hpp> -#include <mbgl/style/style.hpp> -#include <mbgl/style/layers/custom_layer.hpp> -#include <mbgl/style/layers/fill_layer.hpp> #include <mbgl/style/layers/background_layer.hpp> +#include <mbgl/style/layers/fill_layer.hpp> +#include <mbgl/style/style.hpp> #include <mbgl/util/io.hpp> #include <mbgl/util/mat4.hpp> #include <mbgl/util/run_loop.hpp> diff --git a/test/include/mbgl/test/util.hpp b/test/include/mbgl/test/util.hpp index 9f56841dcc..959b3e646f 100644 --- a/test/include/mbgl/test/util.hpp +++ b/test/include/mbgl/test/util.hpp @@ -6,8 +6,6 @@ #if ANDROID #define TEST_READ_ONLY 0 - #undef TEST_HAS_SERVER - #define TEST_HAS_SERVER 0 #elif TARGET_OS_IOS #define TEST_READ_ONLY 1 #undef TEST_HAS_SERVER @@ -54,19 +52,25 @@ #include <cstdint> #include <memory> +#include <thread> #include <gtest/gtest.h> +namespace httplib { +class Server; +} + namespace mbgl { namespace test { -class Server { +class HttpServer { public: - Server(const char* script); - ~Server(); + HttpServer(); + ~HttpServer(); private: - int fd = -1; + std::unique_ptr<httplib::Server> server; + std::thread serverThread; }; void checkImage(const std::string& base, diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp index 89be4ad73e..e00f84eff0 100644 --- a/test/map/map.test.cpp +++ b/test/map/map.test.cpp @@ -19,8 +19,10 @@ #include <mbgl/style/layers/background_layer.hpp> #include <mbgl/style/layers/raster_layer.hpp> #include <mbgl/style/layers/symbol_layer.hpp> +#include <mbgl/style/sources/custom_geometry_source.hpp> #include <mbgl/style/sources/geojson_source.hpp> #include <mbgl/style/sources/image_source.hpp> +#include <mbgl/style/sources/vector_source.hpp> #include <mbgl/style/style.hpp> #include <mbgl/util/async_task.hpp> #include <mbgl/util/color.hpp> @@ -28,6 +30,8 @@ #include <mbgl/util/io.hpp> #include <mbgl/util/run_loop.hpp> +#include <atomic> + using namespace mbgl; using namespace mbgl::style; using namespace std::literals::string_literals; @@ -1119,3 +1123,133 @@ TEST(Map, NoHangOnMissingImage) { // The test passes if the following call does not hang. test.frontend.render(test.map); } + +TEST(Map, PrefetchDeltaOverride) { + MapTest<> test{1, MapMode::Continuous}; + + test.map.getStyle().loadJSON( + R"STYLE({ + "layers": [{ + "id": "vector", + "type": "fill", + "source": "vector", + "minzoom": 0, + "maxzoom": 24 + }, + { + "id": "custom", + "type": "fill", + "source": "custom", + "minzoom": 0, + "maxzoom": 24 + }] + })STYLE"); + + // Vector source + auto vectorSource = std::make_unique<VectorSource>("vector", Tileset{{"a/{z}/{x}/{y}"}}); + vectorSource->setPrefetchZoomDelta(0); + test.map.getStyle().addSource(std::move(vectorSource)); + + std::atomic_int requestedTiles(0); + test.fileSource->tileResponse = [&](const Resource&) { + ++requestedTiles; + Response res; + res.noContent = true; + return res; + }; + + // Custom source + CustomGeometrySource::Options options; + options.cancelTileFunction = [](const CanonicalTileID&) {}; + options.fetchTileFunction = [&requestedTiles, &test](const CanonicalTileID& tileID) { + ++requestedTiles; + auto* customSrc = static_cast<CustomGeometrySource*>(test.map.getStyle().getSource("custom")); + if (customSrc) { + customSrc->setTileData(tileID, {}); + } + }; + auto customSource = std::make_unique<CustomGeometrySource>("custom", std::move(options)); + customSource->setPrefetchZoomDelta(0); + test.map.getStyle().addSource(std::move(customSource)); + + test.map.jumpTo(CameraOptions().withZoom(double(16))); + test.observer.didFinishLoadingMapCallback = [&] { test.runLoop.stop(); }; + test.runLoop.run(); + // 2 sources x 4 tiles + EXPECT_EQ(8, requestedTiles); + + requestedTiles = 0; + + // Should request z12 tiles when delta is set back to default, that is 4. + test.observer.didFinishRenderingFrameCallback = [&](MapObserver::RenderFrameStatus status) { + if (status.mode == MapObserver::RenderMode::Full) { + test.runLoop.stop(); + } + }; + + test.map.getStyle().getSource("vector")->setPrefetchZoomDelta(nullopt); + test.map.getStyle().getSource("custom")->setPrefetchZoomDelta(nullopt); + test.runLoop.run(); + + // Each source requests 4 additional parent tiles. + EXPECT_EQ(8, requestedTiles); +} + +// Test that custom source's tile pyramid is reset +// if there is a significant change. +TEST(Map, PrefetchDeltaOverrideCustomSource) { + MapTest<> test{1, MapMode::Continuous}; + + test.map.getStyle().loadJSON( + R"STYLE({ + "layers": [{ + "id": "custom", + "type": "fill", + "source": "custom", + "source-layer": "a", + "minzoom": 0, + "maxzoom": 24 + }] + })STYLE"); + + std::atomic_int requestedTiles(0); + + auto makeCustomSource = [&requestedTiles, &test] { + CustomGeometrySource::Options options; + options.cancelTileFunction = [](const CanonicalTileID&) {}; + options.fetchTileFunction = [&requestedTiles, &test](const CanonicalTileID& tileID) { + ++requestedTiles; + auto* source = static_cast<CustomGeometrySource*>(test.map.getStyle().getSource("custom")); + if (source) { + source->setTileData(tileID, {}); + } + }; + return std::make_unique<CustomGeometrySource>("custom", std::move(options)); + }; + + auto customSource = makeCustomSource(); + customSource->setPrefetchZoomDelta(0); + test.map.getStyle().addSource(std::move(customSource)); + + test.map.jumpTo(CameraOptions().withZoom(double(16))); + test.observer.didFinishLoadingMapCallback = [&] { test.runLoop.stop(); }; + test.runLoop.run(); + EXPECT_EQ(4, requestedTiles); + requestedTiles = 0; + + test.observer.didFinishRenderingFrameCallback = [&](MapObserver::RenderFrameStatus status) { + if (status.mode == MapObserver::RenderMode::Full) { + test.runLoop.stop(); + } + }; + + auto layer = test.map.getStyle().removeLayer("custom"); + std::move(test.map.getStyle().removeSource("custom")); + test.map.getStyle().addLayer(std::move(layer)); + test.map.getStyle().addSource(makeCustomSource()); + test.runLoop.run(); + + // Source was significantly mutated, therefore, tile pyramid would be cleared + // and current zoom level + parent tiles would be re-requested. + EXPECT_EQ(8, requestedTiles); +} diff --git a/test/platform/settings.test.cpp b/test/platform/settings.test.cpp new file mode 100644 index 0000000000..46a8fc7ef9 --- /dev/null +++ b/test/platform/settings.test.cpp @@ -0,0 +1,48 @@ +#include <gtest/gtest.h> +#include <mbgl/platform/settings.hpp> + +using namespace mbgl; +using namespace mbgl::platform; + +TEST(Settings, SetAndGet) { + using Value = mapbox::base::Value; + using Object = mapbox::base::ValueObject; + + auto& settings = Settings::getInstance(); + auto value = settings.get(EXPERIMENTAL_THREAD_PRIORITY_WORKER); + EXPECT_TRUE(value.is<mapbox::base::NullValue>()); + + Value lowPrioValue{19.0}; + settings.set(EXPERIMENTAL_THREAD_PRIORITY_WORKER, lowPrioValue); + auto threadPriority = settings.get(EXPERIMENTAL_THREAD_PRIORITY_WORKER); + EXPECT_EQ(lowPrioValue, threadPriority); + EXPECT_EQ(lowPrioValue, settings.get("mapbox_thread_priority_worker")); + + Value networkPrioValue{-20.0}; + Value databasePrioValue{-10.0}; + Object multipleValues{{EXPERIMENTAL_THREAD_PRIORITY_DATABASE, databasePrioValue}, + {EXPERIMENTAL_THREAD_PRIORITY_NETWORK, networkPrioValue}}; + settings.set(std::move(multipleValues)); + + std::vector<std::string> keys{EXPERIMENTAL_THREAD_PRIORITY_WORKER, + EXPERIMENTAL_THREAD_PRIORITY_DATABASE, + EXPERIMENTAL_THREAD_PRIORITY_NETWORK, + EXPERIMENTAL_THREAD_PRIORITY_FILE}; + + auto object = settings.get(keys); + + Object values{{EXPERIMENTAL_THREAD_PRIORITY_WORKER, lowPrioValue}, + {EXPERIMENTAL_THREAD_PRIORITY_DATABASE, databasePrioValue}, + {EXPERIMENTAL_THREAD_PRIORITY_NETWORK, networkPrioValue}, + {EXPERIMENTAL_THREAD_PRIORITY_FILE, Value{}}}; + + EXPECT_EQ(values, object); + + values = Object{{EXPERIMENTAL_THREAD_PRIORITY_WORKER, Value{}}, + {EXPERIMENTAL_THREAD_PRIORITY_DATABASE, Value{}}, + {EXPERIMENTAL_THREAD_PRIORITY_NETWORK, Value{}}, + {EXPERIMENTAL_THREAD_PRIORITY_FILE, Value{}}}; + + settings.set(values); + EXPECT_EQ(values, settings.get(keys)); +} diff --git a/test/renderer/image_manager.test.cpp b/test/renderer/image_manager.test.cpp index a891f48b48..c3ab0d8227 100644 --- a/test/renderer/image_manager.test.cpp +++ b/test/renderer/image_manager.test.cpp @@ -27,10 +27,10 @@ TEST(ImageManager, Basic) { auto images = parseSprite(util::read_file("test/fixtures/annotations/emerald.png"), util::read_file("test/fixtures/annotations/emerald.json")); for (auto& image : images) { - imageManager.addImage(image->baseImpl); - auto* stored = imageManager.getImage(image->getID()); + imageManager.addImage(image); + auto* stored = imageManager.getImage(image->id); ASSERT_TRUE(stored); - EXPECT_EQ(image->getImage().size, stored->image.size); + EXPECT_EQ(image->image.size, stored->image.size); } } diff --git a/test/renderer/pattern_atlas.test.cpp b/test/renderer/pattern_atlas.test.cpp index 350a64adb4..143ee928b5 100644 --- a/test/renderer/pattern_atlas.test.cpp +++ b/test/renderer/pattern_atlas.test.cpp @@ -21,8 +21,8 @@ TEST(PatternAtlas, Basic) { auto images = parseSprite(util::read_file("test/fixtures/annotations/emerald.png"), util::read_file("test/fixtures/annotations/emerald.json")); for (auto& image : images) { - if (image->getID() == "metro") { - ASSERT_TRUE(patternAtlas.addPattern(*image->baseImpl)); + if (image->id == "metro") { + ASSERT_TRUE(patternAtlas.addPattern(*image)); } } auto found = patternAtlas.getPattern("metro"); diff --git a/test/sprite/sprite_loader.test.cpp b/test/sprite/sprite_loader.test.cpp index 122e711f51..4e68bff505 100644 --- a/test/sprite/sprite_loader.test.cpp +++ b/test/sprite/sprite_loader.test.cpp @@ -17,7 +17,7 @@ using namespace mbgl::style; class StubSpriteLoaderObserver : public SpriteLoaderObserver { public: - void onSpriteLoaded(std::vector<std::unique_ptr<style::Image>>&& images) override { + void onSpriteLoaded(std::vector<Immutable<style::Image::Impl>> images) override { if (spriteLoaded) spriteLoaded(std::move(images)); } @@ -25,7 +25,7 @@ public: if (spriteError) spriteError(error); } - std::function<void (std::vector<std::unique_ptr<style::Image>>&&)> spriteLoaded; + std::function<void(std::vector<Immutable<style::Image::Impl>>)> spriteLoaded; std::function<void (std::exception_ptr)> spriteError; }; @@ -92,7 +92,7 @@ TEST(SpriteLoader, LoadingSuccess) { test.end(); }; - test.observer.spriteLoaded = [&] (std::vector<std::unique_ptr<style::Image>>&& images) { + test.observer.spriteLoaded = [&](std::vector<Immutable<style::Image::Impl>> images) { EXPECT_EQ(images.size(), 367u); test.end(); }; @@ -169,7 +169,7 @@ TEST(SpriteLoader, LoadingCancel) { return optional<Response>(); }; - test.observer.spriteLoaded = [&] (const std::vector<std::unique_ptr<style::Image>>&) { + test.observer.spriteLoaded = [&](std::vector<Immutable<style::Image::Impl>>) { FAIL() << "Should never be called"; }; diff --git a/test/sprite/sprite_parser.test.cpp b/test/sprite/sprite_parser.test.cpp index c37fee02b9..58979a0e61 100644 --- a/test/sprite/sprite_parser.test.cpp +++ b/test/sprite/sprite_parser.test.cpp @@ -3,6 +3,7 @@ #include <mbgl/sprite/sprite_parser.hpp> #include <mbgl/style/image.hpp> +#include <mbgl/style/image_impl.hpp> #include <mbgl/util/image.hpp> #include <mbgl/util/io.hpp> #include <mbgl/util/string.hpp> @@ -242,8 +243,8 @@ TEST(Sprite, SpriteParsing) { const auto images = parseSprite(image_1x, json_1x); std::set<std::string> names; - std::transform(images.begin(), images.end(), std::inserter(names, names.begin()), - [](const auto& image) { return image->getID(); }); + std::transform( + images.begin(), images.end(), std::inserter(names, names.begin()), [](const auto& image) { return image->id; }); EXPECT_EQ(std::set<std::string>({ "airfield_icon", "airport_icon", @@ -321,11 +322,12 @@ TEST(Sprite, SpriteParsing) { names); { - auto& sprite = *std::find_if(images.begin(), images.end(), [] (const auto& image) { return image->getID() == "generic-metro"; }); - EXPECT_EQ(18u, sprite->getImage().size.width); - EXPECT_EQ(18u, sprite->getImage().size.height); - EXPECT_EQ(1, sprite->getPixelRatio()); - EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteparsing.png"), sprite->getImage()); + auto& sprite = + *std::find_if(images.begin(), images.end(), [](const auto& image) { return image->id == "generic-metro"; }); + EXPECT_EQ(18u, sprite->image.size.width); + EXPECT_EQ(18u, sprite->image.size.height); + EXPECT_EQ(1, sprite->pixelRatio); + EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteparsing.png"), sprite->image); } } @@ -460,10 +462,10 @@ TEST(Sprite, SpriteParsingStretchAndContent) { } })JSON"); EXPECT_EQ(1u, images.size()); - EXPECT_EQ("image", images[0]->getID()); - EXPECT_EQ((style::ImageStretches{{2, 14}}), images[0]->getStretchX()); - EXPECT_EQ((style::ImageStretches{{0, 4}, {12, 16}}), images[0]->getStretchY()); - EXPECT_EQ((style::ImageContent{2, 2, 14, 14}), images[0]->getContent()); + EXPECT_EQ("image", images[0]->id); + EXPECT_EQ((style::ImageStretches{{2, 14}}), images[0]->stretchX); + EXPECT_EQ((style::ImageStretches{{0, 4}, {12, 16}}), images[0]->stretchY); + EXPECT_EQ((style::ImageContent{2, 2, 14, 14}), images[0]->content); } TEST(Sprite, SpriteParsingEmptyImage) { diff --git a/test/src/mbgl/test/http_server.cpp b/test/src/mbgl/test/http_server.cpp new file mode 100644 index 0000000000..2b72bb2c94 --- /dev/null +++ b/test/src/mbgl/test/http_server.cpp @@ -0,0 +1,199 @@ +#include <mbgl/test/util.hpp> + +#include <mbgl/util/chrono.hpp> +#include <mbgl/util/logging.hpp> + +// Limit to 4 threads (default is the nbr of CPU cores) +#define CPPHTTPLIB_THREAD_POOL_COUNT 4 +#include <httplib.h> + +#include <atomic> + +namespace mbgl { +namespace test { + +void runServer(std::unique_ptr<httplib::Server>& server) { + using namespace httplib; + + server->Get("/test", [](const Request& req, Response& res) { + if (req.has_param("modified")) { + std::string str = util::rfc1123(util::parseTimestamp(std::stoi(req.get_param_value("modified")))); + res.set_header("Last-Modified", str); + } + if (req.has_param("expires")) { + std::string str = util::rfc1123(util::parseTimestamp(std::stoi(req.get_param_value("expires")))); + res.set_header("Expires", str); + } + if (req.has_param("etag")) { + res.set_header("ETag", req.get_param_value("etag")); + } + if (req.has_param("cachecontrol")) { + res.set_header("Cache-Control", "max-age=" + req.get_param_value("cachecontrol")); + } + res.set_content("Hello World!", "text/plain"); + }); + + server->Get("/stale", [](const Request&, Response&) { + // Never respond. + }); + + std::atomic_int cacheCounter(0); + server->Get("/cache", [&](const Request&, Response& res) { + res.set_header("Cache-Control", "max-age=30"); // Allow caching for 30 seconds + res.set_content("Response " + std::to_string(++cacheCounter), "text/plain"); + }); + + server->Get("/revalidate-same", [](const Request& req, Response& res) { + if (req.get_header_value("if-none-match") == "snowfall") { + // Second request can be cached for 1 second. + res.set_header("Cache-Control", "max-age=1, must-revalidate"); + res.status = 304; + } else { + // First request must always be revalidated. + res.set_header("ETag", "snowfall"); + res.set_header("Cache-Control", "must-revalidate"); + res.status = 200; + res.set_content("Response", "text/plain"); + } + }); + + std::atomic_bool expiredOnce(true); + server->Get("/clockskew", [&](const Request&, Response& res) { + std::string dateStr; + if (expiredOnce) { + dateStr = "jan 1 10:00:00 2010 utc"; + expiredOnce = false; + } else { + dateStr = "jan 1 10:01:00 2010 utc"; + } + res.set_header("Expires", util::rfc1123(util::parseTimestamp(dateStr.c_str()))); + res.status = 200; + res.set_content("Response", "text/plain"); + }); + + server->Get("/revalidate-modified", [&](const Request& req, Response& res) { + auto jan1 = util::parseTimestamp("jan 1 2015 utc"); + + if (req.has_header("if-modified-since")) { + auto modified_since = util::parseTimestamp(req.get_header_value("if-modified-since").c_str()); + if (modified_since >= jan1) { + res.set_header("Cache-Control", "max-age=1, must-revalidate"); + res.status = 304; + return; + } + } + + // First request must always be revalidated. + res.set_header("Last-Modified", util::rfc1123(jan1)); + res.set_header("Cache-Control", "must-revalidate"); + res.status = 200; + res.set_content("Response", "text/plain"); + }); + + std::atomic_int revalidateEtagCounter(1); + server->Get("/revalidate-etag", [&](const Request&, Response& res) { + res.set_header("ETag", "response-" + std::to_string(revalidateEtagCounter)); + res.set_header("Cache-Control", "must-revalidate"); + + res.status = 200; + res.set_content("Response " + std::to_string(revalidateEtagCounter), "text/plain"); + revalidateEtagCounter++; + }); + + server->Get("/empty-data", [](const Request&, Response& res) { res.status = 200; }); + + server->Get("/no-content", [](const Request&, Response& res) { res.status = 204; }); + + server->Get("/not-found", [](const Request&, Response& res) { + res.status = 404; + res.set_content("Not Found!", "text/plain"); + }); + + server->Get("/permanent-error", [](const Request&, Response& res) { + res.status = 500; + res.set_content("Server Error!", "text/plain"); + }); + + std::atomic_int temporaryErrorCounter(0); + server->Get("/temporary-error", [&](const Request&, Response& res) { + if (temporaryErrorCounter == 0) { + res.status = 500; + } else { + res.status = 200; + res.set_content("Hello World!", "text/plain"); + } + temporaryErrorCounter++; + }); + + server->Get("/rate-limit", [](const Request& req, Response& res) { + if (req.has_param("std")) { + res.set_header("Retry-After", "1"); + } else if (req.has_param("mbx")) { + res.set_header("x-rate-limit-reset", std::to_string(util::now().time_since_epoch().count() + 1)); + } + res.status = 429; + }); + + std::atomic_bool styleFailOnce500(true); + server->Get("/style-fail-once-500", [&](const Request&, Response& res) { + if (styleFailOnce500) { + res.status = 500; + res.set_content("Not found!", "text/plain"); + styleFailOnce500 = false; + } else { + res.status = 200; + res.set_content(R"({ "version": 8, "name": "Test Style" })", "text/plain"); + } + }); + + std::atomic_bool styleFailOnce404(true); + server->Get("/style-fail-once-404", [&](const Request&, Response& res) { + if (styleFailOnce404) { + res.status = 404; + res.set_content("Not found!", "text/plain"); + styleFailOnce404 = false; + } else { + res.status = 200; + res.set_content(R"({ "version": 8, "name": "Test Style" })", "text/plain"); + } + }); + + std::atomic_bool styleFailOnce404Cache(true); + server->Get("/style-fail-once-404-cache", [&](const Request&, Response& res) { + if (styleFailOnce404Cache) { + res.set_header("Cache-Control", "max-age=30"); + res.status = 404; + res.set_content("Not found!", "text/plain"); + styleFailOnce404Cache = false; + } else { + res.status = 200; + res.set_content(R"({ "version": 8, "name": "Teste Style" })", "text/plain"); + } + }); + + server->Get("/delayed", [](const Request&, Response& res) { + usleep(200000); + res.status = 200; + res.set_content("Response", "text/plain"); + }); + + server->Get(R"(/load/(\d+))", [](const Request req, Response& res) { + auto numbers = req.matches[1]; + res.set_content("Request " + std::string(numbers), "text/plain"); + }); + + server->listen("127.0.0.1", 3000); +} + +HttpServer::HttpServer() { + server = std::make_unique<httplib::Server>(); + serverThread = std::thread(runServer, std::ref(server)); +} + +HttpServer::~HttpServer() { + server->stop(); + serverThread.join(); +} + +} // namespace test +} // namespace mbgl diff --git a/test/src/mbgl/test/stub_geometry_tile_feature.hpp b/test/src/mbgl/test/stub_geometry_tile_feature.hpp index e74988df2e..024e3c6c40 100644 --- a/test/src/mbgl/test/stub_geometry_tile_feature.hpp +++ b/test/src/mbgl/test/stub_geometry_tile_feature.hpp @@ -16,6 +16,9 @@ public: geometry(std::move(geometry_)) { } + StubGeometryTileFeature(FeatureType type_, GeometryCollection geometry_) + : type(type_), geometry(std::move(geometry_)) {} + PropertyMap properties; FeatureIdentifier id; FeatureType type = FeatureType::Point; diff --git a/test/src/mbgl/test/test.cpp b/test/src/mbgl/test/test.cpp index 12a3dff720..fbc67f680c 100644 --- a/test/src/mbgl/test/test.cpp +++ b/test/src/mbgl/test/test.cpp @@ -8,7 +8,7 @@ namespace mbgl { int runTests(int argc, char *argv[]) { #if TEST_HAS_SERVER - auto server = std::make_unique<test::Server>("test/storage/server.js"); + auto server = std::make_unique<test::HttpServer>(); #endif testing::InitGoogleTest(&argc, argv); diff --git a/test/src/mbgl/test/util.cpp b/test/src/mbgl/test/util.cpp index 30eea19bdf..cde3d6e9de 100644 --- a/test/src/mbgl/test/util.cpp +++ b/test/src/mbgl/test/util.cpp @@ -6,88 +6,9 @@ #include <mapbox/pixelmatch.hpp> -#include <csignal> -#include <future> - -#include <unistd.h> - -#define xstr(s) str(s) -#define str(s) #s - namespace mbgl { namespace test { -Server::Server(const char* script) { - int input[2]; - int output[2]; - - if (pipe(input)) { - throw std::runtime_error("Cannot create server input pipe"); - } - if (pipe(output)) { - throw std::runtime_error("Cannot create server output pipe"); - } - - // Store the parent => child pipe so that we can close it in the destructor. - fd = input[1]; - - pid_t pid = fork(); - if (pid < 0) { - Log::Error(Event::Setup, "Cannot create server process"); - exit(1); - } else if (pid == 0) { - // This is the child process. - - // Connect the parent => child pipe to stdin. - while ((dup2(input[0], STDIN_FILENO) == -1) && (errno == EINTR)) {} - close(input[0]); - close(input[1]); - - // Move the child => parent side of the pipe to stdout. - while ((dup2(output[1], STDOUT_FILENO) == -1) && (errno == EINTR)) {} - close(output[1]); - close(output[0]); - - const char* executable = xstr(NODE_EXECUTABLE); - - // Launch the actual server process. - int ret = execl(executable, executable, script, nullptr); - - // This call should not return. In case execl failed, we exit anyway. - if (ret < 0) { - Log::Error(Event::Setup, "Failed to start server: %s", strerror(errno)); - } - abort(); - } else { - // This is the parent process. - - // Close the unneeded sides of the pipes. - close(output[1]); - close(input[0]); - - // Wait until the server process sends at least 2 bytes or closes the handle. - char buffer[2]; - ssize_t bytes, total = 0; - while (total < 2 && (bytes = read(output[0], buffer + total, 2 - total)) != 0) { - total += bytes; - } - - // Close child => parent pipe. - close(output[0]); - - // Check signature - if (total != 2 || strncmp(buffer, "OK", 2) != 0) { - throw std::runtime_error("Failed to start server: Invalid signature"); - } - } -} - -Server::~Server() { - if (fd > 0) { - close(fd); - } -} - void checkImage(const std::string& base, const PremultipliedImage& actual, double imageThreshold, diff --git a/test/storage/main_resource_loader.test.cpp b/test/storage/main_resource_loader.test.cpp index c5f1a9c707..ee9211b064 100644 --- a/test/storage/main_resource_loader.test.cpp +++ b/test/storage/main_resource_loader.test.cpp @@ -687,16 +687,23 @@ TEST(MainResourceLoader, TEST_REQUIRES_SERVER(CachedResourceLowPriority)) { response.data = std::make_shared<std::string>("Cached Request 4"); dbfs->forward(resource2, response); - onlineFs->setProperty("max-concurrent-requests", 1u); + onlineFs->setProperty(MAX_CONCURRENT_REQUESTS_KEY, 1u); fs.pause(); NetworkStatus::Set(NetworkStatus::Status::Offline); // Ensure that the online requests for new resources are processed first. + Resource nonCached0{Resource::Unknown, "http://127.0.0.1:3000/load/0", {}, Resource::LoadingMethod::All}; + std::unique_ptr<AsyncRequest> req0 = fs.request(nonCached0, [&](Response res) { + req0.reset(); + EXPECT_EQ(online_response_counter, 0); // make sure this is responded first + EXPECT_EQ("Request 0", *res.data); + }); + Resource nonCached1{Resource::Unknown, "http://127.0.0.1:3000/load/1", {}, Resource::LoadingMethod::All}; std::unique_ptr<AsyncRequest> req1 = fs.request(nonCached1, [&](Response res) { online_response_counter++; req1.reset(); - EXPECT_EQ(online_response_counter, 1); // make sure this is responded first + EXPECT_EQ(online_response_counter, 1); // make sure this is responded second EXPECT_EQ("Request 1", *res.data); }); @@ -733,7 +740,7 @@ TEST(MainResourceLoader, TEST_REQUIRES_SERVER(CachedResourceLowPriority)) { std::unique_ptr<AsyncRequest> req2 = fs.request(nonCached2, [&](Response res) { online_response_counter++; req2.reset(); - EXPECT_EQ(online_response_counter, 2); // make sure this is responded second + EXPECT_EQ(online_response_counter, 2); // make sure this is responded third EXPECT_EQ("Request 2", *res.data); }); diff --git a/test/storage/offline_database.test.cpp b/test/storage/offline_database.test.cpp index ef7ad257d7..f988457dac 100644 --- a/test/storage/offline_database.test.cpp +++ b/test/storage/offline_database.test.cpp @@ -1875,3 +1875,46 @@ TEST(OfflineDatabase, ResetDatabase) { EXPECT_EQ(1u, log.count({ EventSeverity::Warning, Event::Database, -1, "Removing existing incompatible offline database" })); EXPECT_EQ(0u, log.uncheckedCount()); } + +TEST(OfflineDatabase, PutResourceReadOnlyMode) { + FixtureLog log; + OfflineDatabase db(":memory:"); + + Resource resource{Resource::Style, "http://example.com/"}; + Response response; + response.data = std::make_shared<std::string>("success"); + + // In read-only mode put() is a no-op + db.reopenDatabaseReadOnly(true /*readOnly*/); + auto failedPutResult = db.put(resource, response); + EXPECT_FALSE(failedPutResult.first); + EXPECT_EQ(0u, failedPutResult.second); + + // put() works, if read-only mode is disabled + db.reopenDatabaseReadOnly(false /*readOnly*/); + auto succeededPutResult = db.put(resource, response); + EXPECT_TRUE(succeededPutResult.first); + EXPECT_EQ(7u, succeededPutResult.second); + + auto getResult = db.get(resource); + EXPECT_EQ(nullptr, getResult->error); + EXPECT_EQ("success", *getResult->data); + + EXPECT_EQ(0u, log.uncheckedCount()); +} + +TEST(OfflineDatabase, TEST_REQUIRES_WRITE(UpdateDatabaseReadOnlyMode)) { + FixtureLog log; + deleteDatabaseFiles(); + + OfflineDatabase db(filename); + db.reopenDatabaseReadOnly(true /*readOnly*/); + db.clearAmbientCache(); + EXPECT_EQ(1u, + log.count({EventSeverity::Error, + Event::Database, + -1, + "Can't clear ambient cache: Cannot modify database in read-only mode"})); + + EXPECT_EQ(0u, log.uncheckedCount()); +} diff --git a/test/storage/server.js b/test/storage/server.js deleted file mode 100755 index d6429e4635..0000000000 --- a/test/storage/server.js +++ /dev/null @@ -1,175 +0,0 @@ -#!/usr/bin/env node -/* jshint node: true */ -'use strict'; - -// This needs to be here to make sure the pipe stays open. -// We're waiting until the stdin pipe gets closed (e.g. because the parent -// process dies) -process.stdin.on('readable', function() {}); -process.stdin.on('end', function() { process.exit(0); }); - - -var fs = require('fs'); -var express = require('express'); -var app = express(); - -// We're manually setting Etag headers. -app.disable('etag'); - -app.get('/test', function (req, res) { - if (req.query.modified) { - res.setHeader('Last-Modified', (new Date(req.query.modified * 1000)).toUTCString()); - } - if (req.query.expires) { - res.setHeader('Expires', (new Date(req.query.expires * 1000)).toUTCString()); - } - if (req.query.etag) { - res.setHeader('ETag', req.query.etag); - } - if (req.query.cachecontrol) { - res.setHeader('Cache-Control', req.query.cachecontrol); - } - res.send('Hello World!'); -}); - -app.get('/stale/*', function() { - // Never respond. -}); - -var cacheCounter = 0; -app.get('/cache', function(req, res) { - res.setHeader('Cache-Control', 'max-age=30'); // Allow caching for 30 seconds - res.send('Response ' + (++cacheCounter)); -}); - -app.get('/revalidate-same', function(req, res) { - if (req.headers['if-none-match'] == 'snowfall') { - // Second request can be cached for 1 second. - res.setHeader('Cache-Control', 'max-age=1, must-revalidate'); - res.status(304).end(); - } else { - // First request must always be revalidated. - res.setHeader('ETag', 'snowfall'); - res.setHeader('Cache-Control', 'must-revalidate'); - res.status(200).send('Response'); - } -}); - -var expiresCounter = 0; -app.get('/clockskew', function (req, res) { - res.setHeader('Expires', (new Date(2010, 1, 1, 10, ++expiresCounter, 0)).toUTCString()); - res.status(200).send('Response'); -}); - -app.get('/revalidate-modified', function(req, res) { - var jan1 = new Date('jan 1 2015 utc'); - - if (req.headers['if-modified-since']) { - var modified_since = new Date(req.headers['if-modified-since']); - if (modified_since >= jan1) { - res.setHeader('Cache-Control', 'max-age=1, must-revalidate'); - res.status(304).end(); - return; - } - } - - // First request must always be revalidated. - res.setHeader('Last-Modified', jan1.toUTCString()); - res.setHeader('Cache-Control', 'must-revalidate'); - res.status(200).send('Response'); -}); - - -var revalidateEtagCounter = 1; -app.get('/revalidate-etag', function(req, res) { - res.setHeader('ETag', 'response-' + revalidateEtagCounter); - res.setHeader('Cache-Control', 'must-revalidate'); - - res.status(200).send('Response ' + revalidateEtagCounter); - revalidateEtagCounter++; -}); - -app.get('/empty-data', function(req, res) { - res.status(200).send(); -}); - -app.get('/no-content', function(req, res) { - res.status(204).send(); -}); - -app.get('/not-found', function(req, res) { - res.status(404).send('Not Found!'); -}); - -app.get('/permanent-error', function(req, res) { - res.status(500).send('Server Error!'); -}); - -var temporaryErrorCounter = 0; -app.get('/temporary-error', function(req, res) { - if (temporaryErrorCounter === 0) { - res.status(500).end(); - } else { - res.status(200).send('Hello World!'); - } - - temporaryErrorCounter++; -}); - -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'); - }, 200); -}); - - -app.get('/load/:number(\\d+)', function(req, res) { - res.send('Request ' + req.params.number); -}); - -var server = app.listen(3000, function () { - // Tell parent that we're now listening. - process.stdout.write("OK"); -}); diff --git a/test/style/property_expression.test.cpp b/test/style/property_expression.test.cpp index 6334fcbe39..0624cff385 100644 --- a/test/style/property_expression.test.cpp +++ b/test/style/property_expression.test.cpp @@ -7,6 +7,8 @@ #include <mbgl/style/expression/dsl.hpp> #include <mbgl/style/expression/format_section_override.hpp> +#include <sstream> + using namespace mbgl; using namespace mbgl::style; using namespace mbgl::style::expression; @@ -218,3 +220,99 @@ TEST(PropertyExpression, ImageExpression) { EXPECT_EQ(evaluatedImage.id(), "bicycle-15"s); } } + +TEST(PropertyExpression, WithinExpression) { + CanonicalTileID canonicalTileID(3, 3, 3); + + // geoJSON source must be Polygon.(Currently only supports Polygon) + static const std::string invalidGeoSource = R"({ + "type": "LineString", + "coordinates": [[0, 0], [0, 5], [5, 5], [5, 0]] + })"; + static const std::string validGeoSource = R"data( + { + "type": "Polygon", + "coordinates": [ + [ + [-11.689453125, -9.79567758282973], + [2.021484375, -10.012129557908128], + [-15.99609375, -17.392579271057766], + [-5.9765625, -5.659718554577273], + [-16.259765625, -3.7327083213358336], + [-17.75390625, -12.897489183755892], + [-17.138671875, -21.002471054356715], + [4.482421875, -16.8886597873816], + [3.076171875, -7.01366792756663], + [ -5.9326171875, 0.6591651462894632], + [-16.1279296875, 1.4939713066293239], + [-11.689453125, -9.79567758282973] + ] + ] + })data"; + + // evaluation test with invalid geojson source + { + std::stringstream ss; + ss << std::string(R"(["within", )") << invalidGeoSource << std::string(R"( ])"); + auto expression = createExpression(ss.str().c_str()); + ASSERT_FALSE(expression); + } + + // evaluation test with valid geojson source + std::stringstream ss; + ss << std::string(R"(["within", )") << validGeoSource << std::string(R"( ])"); + auto expression = createExpression(ss.str().c_str()); + ASSERT_TRUE(expression); + PropertyExpression<bool> propExpr(std::move(expression)); + + // evaluation test with valid geojson source but FeatureType is not Point (currently only support + // FeatureType::Point) + { + // testLine is inside polygon, but will return false + LineString<double> testLine{{-9.228515625, -17.560246503294888}, {-2.4609375, -16.04581345375217}}; + auto geoLine = convertGeometry(testLine, canonicalTileID); + StubGeometryTileFeature lineFeature(FeatureType::LineString, geoLine); + + auto evaluatedResult = propExpr.evaluate(EvaluationContext(&lineFeature).withCanonicalTileID(&canonicalTileID)); + EXPECT_FALSE(evaluatedResult); + } + + // evaluation test with valid geojson source and valid point features + { + auto getPointFeature = [&canonicalTileID](const Point<double>& testPoint) -> StubGeometryTileFeature { + auto geoPoint = convertGeometry(testPoint, canonicalTileID); + StubGeometryTileFeature pointFeature(FeatureType::Point, geoPoint); + return pointFeature; + }; + + // check `within` algorithm + auto pointFeature = getPointFeature(Point<double>(-10.72265625, -7.27529233637217)); + auto evaluatedResult = + propExpr.evaluate(EvaluationContext(&pointFeature).withCanonicalTileID(&canonicalTileID)); + EXPECT_FALSE(evaluatedResult); + + pointFeature = getPointFeature(Point<double>(-7.646484374999999, -12.382928338487396)); + evaluatedResult = propExpr.evaluate(EvaluationContext(&pointFeature).withCanonicalTileID(&canonicalTileID)); + EXPECT_FALSE(evaluatedResult); + + pointFeature = getPointFeature(Point<double>(-15.2490234375, -2.986927393334863)); + evaluatedResult = propExpr.evaluate(EvaluationContext(&pointFeature).withCanonicalTileID(&canonicalTileID)); + EXPECT_FALSE(evaluatedResult); + + pointFeature = getPointFeature(Point<double>(-10.590820312499998, 2.4601811810210052)); + evaluatedResult = propExpr.evaluate(EvaluationContext(&pointFeature).withCanonicalTileID(&canonicalTileID)); + EXPECT_FALSE(evaluatedResult); + + pointFeature = getPointFeature(Point<double>(-3.9990234375, -4.915832801313164)); + evaluatedResult = propExpr.evaluate(EvaluationContext(&pointFeature).withCanonicalTileID(&canonicalTileID)); + EXPECT_TRUE(evaluatedResult); + + pointFeature = getPointFeature(Point<double>(-1.1865234375, -16.63619187839765)); + evaluatedResult = propExpr.evaluate(EvaluationContext(&pointFeature).withCanonicalTileID(&canonicalTileID)); + EXPECT_TRUE(evaluatedResult); + + pointFeature = getPointFeature(Point<double>(-15.5126953125, -11.73830237143684)); + evaluatedResult = propExpr.evaluate(EvaluationContext(&pointFeature).withCanonicalTileID(&canonicalTileID)); + EXPECT_TRUE(evaluatedResult); + } +} diff --git a/test/style/source.test.cpp b/test/style/source.test.cpp index 1825cd08ae..15772902bf 100644 --- a/test/style/source.test.cpp +++ b/test/style/source.test.cpp @@ -765,15 +765,17 @@ public: const bool needsRendering, const bool needsRelayout, const TileParameters& parameters) override { - tilePyramid.update(layers, - needsRendering, - needsRelayout, - parameters, - SourceType::Vector, - util::tileSize, - tileset.zoomRange, - tileset.bounds, - [&](const OverscaledTileID& tileID) { return std::make_unique<FakeTile>(*this, tileID); }); + tilePyramid.update( + layers, + needsRendering, + needsRelayout, + parameters, + SourceType::Vector, + util::tileSize, + tileset.zoomRange, + tileset.bounds, + [&](const OverscaledTileID& tileID) { return std::make_unique<FakeTile>(*this, tileID); }, + baseImpl->getPrefetchZoomDelta()); } const optional<Tileset>& getTileset() const override { diff --git a/test/style/style.test.cpp b/test/style/style.test.cpp index c9fbd903a5..01ecaf8578 100644 --- a/test/style/style.test.cpp +++ b/test/style/style.test.cpp @@ -125,3 +125,19 @@ TEST(Style, SourceImplsOrder) { EXPECT_EQ("b", sourceImpls[1]->id); EXPECT_EQ("c", sourceImpls[2]->id); } + +TEST(Style, AddRemoveImage) { + util::RunLoop loop; + auto fileSource = std::make_shared<StubFileSource>(); + Style::Impl style{fileSource, 1.0}; + style.addImage(std::make_unique<style::Image>("one", PremultipliedImage({16, 16}), 2)); + style.addImage(std::make_unique<style::Image>("two", PremultipliedImage({16, 16}), 2)); + style.addImage(std::make_unique<style::Image>("three", PremultipliedImage({16, 16}), 2)); + + style.removeImage("one"); + style.removeImage("two"); + + EXPECT_TRUE(!!style.getImage("three")); + EXPECT_FALSE(!!style.getImage("two")); + EXPECT_FALSE(!!style.getImage("four")); +}
\ No newline at end of file diff --git a/test/style/style_layer.test.cpp b/test/style/style_layer.test.cpp index f9ab804cf9..73179250fa 100644 --- a/test/style/style_layer.test.cpp +++ b/test/style/style_layer.test.cpp @@ -1,3 +1,5 @@ +#include <mbgl/gl/custom_layer.hpp> +#include <mbgl/gl/custom_layer_impl.hpp> #include <mbgl/style/expression/dsl.hpp> #include <mbgl/style/expression/format_expression.hpp> #include <mbgl/style/expression/image.hpp> @@ -6,8 +8,6 @@ #include <mbgl/style/layers/background_layer_impl.hpp> #include <mbgl/style/layers/circle_layer.hpp> #include <mbgl/style/layers/circle_layer_impl.hpp> -#include <mbgl/style/layers/custom_layer.hpp> -#include <mbgl/style/layers/custom_layer_impl.hpp> #include <mbgl/style/layers/fill_layer.hpp> #include <mbgl/style/layers/fill_layer_impl.hpp> #include <mbgl/style/layers/line_layer.hpp> diff --git a/test/test-files.json b/test/test-files.json deleted file mode 100644 index 3a4ad95722..0000000000 --- a/test/test-files.json +++ /dev/null @@ -1,133 +0,0 @@ -{ - "//": "This file is generated. Do not edit. Regenerate it with scripts/generate-file-lists.js", - "sources": [ - "test/actor/actor.test.cpp", - "test/actor/actor_ref.test.cpp", - "test/algorithm/update_renderables.test.cpp", - "test/algorithm/update_tile_masks.test.cpp", - "test/api/annotations.test.cpp", - "test/api/api_misuse.test.cpp", - "test/api/custom_geometry_source.test.cpp", - "test/api/custom_layer.test.cpp", - "test/api/query.test.cpp", - "test/api/recycle_map.cpp", - "test/geometry/dem_data.test.cpp", - "test/geometry/line_atlas.test.cpp", - "test/gl/bucket.test.cpp", - "test/gl/context.test.cpp", - "test/gl/gl_functions.test.cpp", - "test/gl/object.test.cpp", - "test/map/map.test.cpp", - "test/map/prefetch.test.cpp", - "test/map/transform.test.cpp", - "test/math/clamp.test.cpp", - "test/math/minmax.test.cpp", - "test/math/wrap.test.cpp", - "test/programs/symbol_program.test.cpp", - "test/renderer/backend_scope.test.cpp", - "test/renderer/image_manager.test.cpp", - "test/renderer/pattern_atlas.test.cpp", - "test/sprite/sprite_loader.test.cpp", - "test/sprite/sprite_parser.test.cpp", - "test/src/mbgl/test/fixture_log_observer.cpp", - "test/src/mbgl/test/getrss.cpp", - "test/src/mbgl/test/sqlite3_test_fs.cpp", - "test/src/mbgl/test/stub_file_source.cpp", - "test/src/mbgl/test/test.cpp", - "test/src/mbgl/test/util.cpp", - "test/storage/asset_file_source.test.cpp", - "test/storage/database_file_source.test.cpp", - "test/storage/headers.test.cpp", - "test/storage/http_file_source.test.cpp", - "test/storage/local_file_source.test.cpp", - "test/storage/main_resource_loader.test.cpp", - "test/storage/offline.test.cpp", - "test/storage/offline_database.test.cpp", - "test/storage/offline_download.test.cpp", - "test/storage/online_file_source.test.cpp", - "test/storage/resource.test.cpp", - "test/storage/sqlite.test.cpp", - "test/storage/sync_file_source.test.cpp", - "test/style/conversion/conversion_impl.test.cpp", - "test/style/conversion/function.test.cpp", - "test/style/conversion/geojson_options.test.cpp", - "test/style/conversion/layer.test.cpp", - "test/style/conversion/light.test.cpp", - "test/style/conversion/property_value.test.cpp", - "test/style/conversion/stringify.test.cpp", - "test/style/conversion/tileset.test.cpp", - "test/style/expression/expression.test.cpp", - "test/style/expression/util.test.cpp", - "test/style/filter.test.cpp", - "test/style/properties.test.cpp", - "test/style/property_expression.test.cpp", - "test/style/source.test.cpp", - "test/style/style.test.cpp", - "test/style/style_image.test.cpp", - "test/style/style_layer.test.cpp", - "test/style/style_parser.test.cpp", - "test/text/bidi.test.cpp", - "test/text/calculate_tile_distances.test.cpp", - "test/text/cross_tile_symbol_index.test.cpp", - "test/text/formatted.test.cpp", - "test/text/get_anchors.test.cpp", - "test/text/glyph_manager.test.cpp", - "test/text/glyph_pbf.test.cpp", - "test/text/language_tag.test.cpp", - "test/text/local_glyph_rasterizer.test.cpp", - "test/text/quads.test.cpp", - "test/text/shaping.test.cpp", - "test/text/tagged_string.test.cpp", - "test/tile/custom_geometry_tile.test.cpp", - "test/tile/geojson_tile.test.cpp", - "test/tile/geometry_tile_data.test.cpp", - "test/tile/raster_dem_tile.test.cpp", - "test/tile/raster_tile.test.cpp", - "test/tile/tile_cache.test.cpp", - "test/tile/tile_coordinate.test.cpp", - "test/tile/tile_id.test.cpp", - "test/tile/vector_tile.test.cpp", - "test/util/async_task.test.cpp", - "test/util/dtoa.test.cpp", - "test/util/geo.test.cpp", - "test/util/grid_index.test.cpp", - "test/util/http_timeout.test.cpp", - "test/util/image.test.cpp", - "test/util/mapbox.test.cpp", - "test/util/memory.test.cpp", - "test/util/merge_lines.test.cpp", - "test/util/number_conversions.test.cpp", - "test/util/offscreen_texture.test.cpp", - "test/util/position.test.cpp", - "test/util/projection.test.cpp", - "test/util/run_loop.test.cpp", - "test/util/string.test.cpp", - "test/util/text_conversions.test.cpp", - "test/util/thread.test.cpp", - "test/util/thread_local.test.cpp", - "test/util/tile_cover.test.cpp", - "test/util/tile_range.test.cpp", - "test/util/timer.test.cpp", - "test/util/token.test.cpp", - "test/util/url.test.cpp" - ], - "public_headers": { - "mbgl/test.hpp": "test/include/mbgl/test.hpp", - "mbgl/test/util.hpp": "test/include/mbgl/test/util.hpp" - }, - "private_headers": { - "mbgl/test/fake_file_source.hpp": "test/src/mbgl/test/fake_file_source.hpp", - "mbgl/test/fixture_log_observer.hpp": "test/src/mbgl/test/fixture_log_observer.hpp", - "mbgl/test/getrss.hpp": "test/src/mbgl/test/getrss.hpp", - "mbgl/test/map_adapter.hpp": "test/src/mbgl/test/map_adapter.hpp", - "mbgl/test/mock.hpp": "test/src/mbgl/test/mock.hpp", - "mbgl/test/sqlite3_test_fs.hpp": "test/src/mbgl/test/sqlite3_test_fs.hpp", - "mbgl/test/stub_file_source.hpp": "test/src/mbgl/test/stub_file_source.hpp", - "mbgl/test/stub_geometry_tile_feature.hpp": "test/src/mbgl/test/stub_geometry_tile_feature.hpp", - "mbgl/test/stub_layer_observer.hpp": "test/src/mbgl/test/stub_layer_observer.hpp", - "mbgl/test/stub_map_observer.hpp": "test/src/mbgl/test/stub_map_observer.hpp", - "mbgl/test/stub_render_source_observer.hpp": "test/src/mbgl/test/stub_render_source_observer.hpp", - "mbgl/test/stub_style_observer.hpp": "test/src/mbgl/test/stub_style_observer.hpp", - "mbgl/test/stub_tile_observer.hpp": "test/src/mbgl/test/stub_tile_observer.hpp" - } -} diff --git a/test/text/cross_tile_symbol_index.test.cpp b/test/text/cross_tile_symbol_index.test.cpp index 6119392fd2..bedf96b430 100644 --- a/test/text/cross_tile_symbol_index.test.cpp +++ b/test/text/cross_tile_symbol_index.test.cpp @@ -47,6 +47,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { OverscaledTileID mainID(6, 0, 6, 8, 8); std::vector<SymbolInstance> mainInstances; + std::vector<SortKeyRange> mainRanges; mainInstances.push_back(makeSymbolInstance(1000, 1000, u"Detroit")); mainInstances.push_back(makeSymbolInstance(2000, 2000, u"Toronto")); SymbolBucket mainBucket{layout, @@ -58,6 +59,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { sortFeaturesByY, bucketLeaderID, std::move(mainInstances), + std::move(mainRanges), 1.0f, false, {}, @@ -72,6 +74,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { OverscaledTileID childID(7, 0, 7, 16, 16); std::vector<SymbolInstance> childInstances; + std::vector<SortKeyRange> childRanges; childInstances.push_back(makeSymbolInstance(2000, 2000, u"Detroit")); childInstances.push_back(makeSymbolInstance(2000, 2000, u"Windsor")); childInstances.push_back(makeSymbolInstance(3000, 3000, u"Toronto")); @@ -85,6 +88,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { sortFeaturesByY, bucketLeaderID, std::move(childInstances), + std::move(childRanges), 1.0f, false, {}, @@ -103,6 +107,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { OverscaledTileID parentID(5, 0, 5, 4, 4); std::vector<SymbolInstance> parentInstances; + std::vector<SortKeyRange> parentRanges; parentInstances.push_back(makeSymbolInstance(500, 500, u"Detroit")); SymbolBucket parentBucket{layout, {}, @@ -113,6 +118,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { sortFeaturesByY, bucketLeaderID, std::move(parentInstances), + std::move(parentRanges), 1.0f, false, {}, @@ -130,6 +136,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { // grandchild OverscaledTileID grandchildID(8, 0, 8, 32, 32); std::vector<SymbolInstance> grandchildInstances; + std::vector<SortKeyRange> grandchildRanges; grandchildInstances.push_back(makeSymbolInstance(4000, 4000, u"Detroit")); grandchildInstances.push_back(makeSymbolInstance(4000, 4000, u"Windsor")); SymbolBucket grandchildBucket{layout, @@ -141,6 +148,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { sortFeaturesByY, bucketLeaderID, std::move(grandchildInstances), + std::move(grandchildRanges), 1.0f, false, {}, @@ -169,6 +177,7 @@ TEST(CrossTileSymbolLayerIndex, resetIDs) { OverscaledTileID mainID(6, 0, 6, 8, 8); std::vector<SymbolInstance> mainInstances; + std::vector<SortKeyRange> mainRanges; mainInstances.push_back(makeSymbolInstance(1000, 1000, u"Detroit")); SymbolBucket mainBucket{layout, {}, @@ -179,6 +188,7 @@ TEST(CrossTileSymbolLayerIndex, resetIDs) { sortFeaturesByY, bucketLeaderID, std::move(mainInstances), + std::move(mainRanges), 1.0f, false, {}, @@ -187,6 +197,7 @@ TEST(CrossTileSymbolLayerIndex, resetIDs) { OverscaledTileID childID(7, 0, 7, 16, 16); std::vector<SymbolInstance> childInstances; + std::vector<SortKeyRange> childRanges; childInstances.push_back(makeSymbolInstance(2000, 2000, u"Detroit")); SymbolBucket childBucket{layout, {}, @@ -197,6 +208,7 @@ TEST(CrossTileSymbolLayerIndex, resetIDs) { sortFeaturesByY, bucketLeaderID, std::move(childInstances), + std::move(childRanges), 1.0f, false, {}, @@ -233,6 +245,7 @@ TEST(CrossTileSymbolLayerIndex, noDuplicatesWithinZoomLevel) { OverscaledTileID mainID(6, 0, 6, 8, 8); std::vector<SymbolInstance> mainInstances; + std::vector<SortKeyRange> mainRanges; mainInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // A mainInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // B SymbolBucket mainBucket{layout, @@ -244,6 +257,7 @@ TEST(CrossTileSymbolLayerIndex, noDuplicatesWithinZoomLevel) { sortFeaturesByY, bucketLeaderID, std::move(mainInstances), + std::move(mainRanges), 1.0f, false, {}, @@ -252,6 +266,7 @@ TEST(CrossTileSymbolLayerIndex, noDuplicatesWithinZoomLevel) { OverscaledTileID childID(7, 0, 7, 16, 16); std::vector<SymbolInstance> childInstances; + std::vector<SortKeyRange> childRanges; childInstances.push_back(makeSymbolInstance(2000, 2000, u"")); // A' childInstances.push_back(makeSymbolInstance(2000, 2000, u"")); // B' childInstances.push_back(makeSymbolInstance(2000, 2000, u"")); // C' @@ -264,6 +279,7 @@ TEST(CrossTileSymbolLayerIndex, noDuplicatesWithinZoomLevel) { sortFeaturesByY, bucketLeaderID, std::move(childInstances), + std::move(childRanges), 1.0f, false, {}, @@ -295,6 +311,7 @@ TEST(CrossTileSymbolLayerIndex, bucketReplacement) { OverscaledTileID tileID(6, 0, 6, 8, 8); std::vector<SymbolInstance> firstInstances; + std::vector<SortKeyRange> firstRanges; firstInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // A firstInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // B SymbolBucket firstBucket{layout, @@ -306,6 +323,7 @@ TEST(CrossTileSymbolLayerIndex, bucketReplacement) { sortFeaturesByY, bucketLeaderID, std::move(firstInstances), + std::move(firstRanges), 1.0f, false, {}, @@ -313,6 +331,7 @@ TEST(CrossTileSymbolLayerIndex, bucketReplacement) { firstBucket.bucketInstanceId = ++maxBucketInstanceId; std::vector<SymbolInstance> secondInstances; + std::vector<SortKeyRange> secondRanges; secondInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // A' secondInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // B' secondInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // C' @@ -325,6 +344,7 @@ TEST(CrossTileSymbolLayerIndex, bucketReplacement) { sortFeaturesByY, bucketLeaderID, std::move(secondInstances), + std::move(secondRanges), 1.0f, false, {}, @@ -369,6 +389,7 @@ TEST(CrossTileSymbolLayerIndex, offscreenSymbols) { std::vector<SymbolInstance> mainInstances; mainInstances.push_back(makeSymbolInstance(1000, 1000, u"Washington")); mainInstances.push_back(makeSymbolInstance(2000, 2000, u"Richmond")); + std::vector<SortKeyRange> mainRanges; SymbolBucket symbolBucket{layout, {}, 16.0f, @@ -378,6 +399,7 @@ TEST(CrossTileSymbolLayerIndex, offscreenSymbols) { sortFeaturesByY, bucketLeaderID, std::move(mainInstances), + std::move(mainRanges), 1.0f, false, {}, @@ -394,4 +416,4 @@ TEST(CrossTileSymbolLayerIndex, offscreenSymbols) { EXPECT_EQ(symbolBucket.symbolInstances.at(0).crossTileID, 1u); EXPECT_EQ(symbolBucket.symbolInstances.at(1).crossTileID, 2u); -}
\ No newline at end of file +} diff --git a/test/tile/custom_geometry_tile.test.cpp b/test/tile/custom_geometry_tile.test.cpp index bbe0c738e1..783dbfcddf 100644 --- a/test/tile/custom_geometry_tile.test.cpp +++ b/test/tile/custom_geometry_tile.test.cpp @@ -61,8 +61,11 @@ TEST(CustomGeometryTile, InvokeFetchTile) { auto mb =std::make_shared<Mailbox>(*Scheduler::GetCurrent()); ActorRef<CustomTileLoader> loaderActor(loader, mb); - CustomGeometryTile tile(OverscaledTileID(0, 0, 0), "source", test.tileParameters, CustomGeometrySource::TileOptions(), - loaderActor); + CustomGeometryTile tile(OverscaledTileID(0, 0, 0), + "source", + test.tileParameters, + makeMutable<CustomGeometrySource::TileOptions>(), + loaderActor); tile.setNecessity(TileNecessity::Required); @@ -86,8 +89,11 @@ TEST(CustomGeometryTile, InvokeCancelTile) { auto mb =std::make_shared<Mailbox>(*Scheduler::GetCurrent()); ActorRef<CustomTileLoader> loaderActor(loader, mb); - CustomGeometryTile tile(OverscaledTileID(0, 0, 0), "source", test.tileParameters, CustomGeometrySource::TileOptions(), - loaderActor); + CustomGeometryTile tile(OverscaledTileID(0, 0, 0), + "source", + test.tileParameters, + makeMutable<CustomGeometrySource::TileOptions>(), + loaderActor); tile.setNecessity(TileNecessity::Required); tile.setNecessity(TileNecessity::Optional); @@ -108,8 +114,11 @@ TEST(CustomGeometryTile, InvokeTileChanged) { auto mb =std::make_shared<Mailbox>(*Scheduler::GetCurrent()); ActorRef<CustomTileLoader> loaderActor(loader, mb); - CustomGeometryTile tile(OverscaledTileID(0, 0, 0), "source", test.tileParameters, CustomGeometrySource::TileOptions(), - loaderActor); + CustomGeometryTile tile(OverscaledTileID(0, 0, 0), + "source", + test.tileParameters, + makeMutable<CustomGeometrySource::TileOptions>(), + loaderActor); Immutable<LayerProperties> layerProperties = makeMutable<CircleLayerProperties>(staticImmutableCast<CircleLayer::Impl>(layer.baseImpl)); StubTileObserver observer; |