diff options
Diffstat (limited to 'test')
29 files changed, 461 insertions, 328 deletions
diff --git a/test/fixtures/local_glyphs/mixed.json b/test/fixtures/local_glyphs/mixed.json index b982fd9641..3d943084e4 100644 --- a/test/fixtures/local_glyphs/mixed.json +++ b/test/fixtures/local_glyphs/mixed.json @@ -68,7 +68,7 @@ { "type": "Feature", "properties": { - "name": "身什戰アあ" + "name": "안녕 세상 KR" }, "geometry": { "type": "LineString", @@ -144,7 +144,7 @@ { "type": "Feature", "properties": { - "name": "8身什戰アあ" + "name": "안녕 세상8" }, "geometry": { "type": "LineString", diff --git a/test/fixtures/local_glyphs/no_local/expected.png b/test/fixtures/local_glyphs/no_local/expected.png Binary files differindex 77552c32fa..7e2049518b 100644 --- a/test/fixtures/local_glyphs/no_local/expected.png +++ b/test/fixtures/local_glyphs/no_local/expected.png diff --git a/test/fixtures/local_glyphs/no_local_with_content_insets/expected.png b/test/fixtures/local_glyphs/no_local_with_content_insets/expected.png Binary files differindex 52ef264590..da5e6957dd 100644 --- a/test/fixtures/local_glyphs/no_local_with_content_insets/expected.png +++ b/test/fixtures/local_glyphs/no_local_with_content_insets/expected.png diff --git a/test/fixtures/local_glyphs/no_local_with_content_insets_and_pitch/expected.png b/test/fixtures/local_glyphs/no_local_with_content_insets_and_pitch/expected.png Binary files differindex a1aa5fcb52..2501471562 100644 --- a/test/fixtures/local_glyphs/no_local_with_content_insets_and_pitch/expected.png +++ b/test/fixtures/local_glyphs/no_local_with_content_insets_and_pitch/expected.png diff --git a/test/fixtures/local_glyphs/noto_sans_cjk_kr_regular_qt/expected.png b/test/fixtures/local_glyphs/noto_sans_cjk_kr_regular_qt/expected.png Binary files differnew file mode 100644 index 0000000000..0d69075172 --- /dev/null +++ b/test/fixtures/local_glyphs/noto_sans_cjk_kr_regular_qt/expected.png diff --git a/test/fixtures/local_glyphs/ping_fang/expected.png b/test/fixtures/local_glyphs/ping_fang/expected.png Binary files differindex 44c24c276a..2ec62e1bc6 100644 --- a/test/fixtures/local_glyphs/ping_fang/expected.png +++ b/test/fixtures/local_glyphs/ping_fang/expected.png 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 465bce5b77..0ede615967 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/fixtures/resources/glyphs-12244-12543.pbf b/test/fixtures/resources/glyphs-12244-12543.pbf Binary files differnew file mode 100644 index 0000000000..cbc4a52056 --- /dev/null +++ b/test/fixtures/resources/glyphs-12244-12543.pbf diff --git a/test/geometry/dem_data.test.cpp b/test/geometry/dem_data.test.cpp index bf362820a0..24893d16ed 100644 --- a/test/geometry/dem_data.test.cpp +++ b/test/geometry/dem_data.test.cpp @@ -33,14 +33,6 @@ TEST(DEMData, ConstructorTerrarium) { EXPECT_EQ(demdata.getImage()->bytes(), size_t(18*18*4)); }; -TEST(DEMData, RoundTrip) { - PremultipliedImage image = fakeImage({16, 16}); - DEMData demdata(image, Tileset::DEMEncoding::Mapbox); - - demdata.set(4, 6, 255); - EXPECT_EQ(demdata.get(4, 6), 255); -} - TEST(DEMData, InitialBackfill) { PremultipliedImage image1 = fakeImage({4, 4}); diff --git a/test/gl/bucket.test.cpp b/test/gl/bucket.test.cpp index cd21a027a2..a3dbdb8f99 100644 --- a/test/gl/bucket.test.cpp +++ b/test/gl/bucket.test.cpp @@ -115,17 +115,20 @@ TEST(Buckets, SymbolBucket) { gfx::BackendScope scope { backend }; auto layout = makeMutable<style::SymbolLayoutProperties::PossiblyEvaluated>(); - bool sdfIcons = false; bool iconsNeedLinear = false; bool sortFeaturesByY = false; std::string bucketLeaderID = "test"; std::vector<SymbolInstance> symbolInstances; gl::Context context{ backend }; - SymbolBucket bucket { std::move(layout), {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(symbolInstances), 1.0f, false, {}}; + SymbolBucket bucket { std::move(layout), {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(symbolInstances), 1.0f, false, {}}; ASSERT_FALSE(bucket.hasIconData()); + ASSERT_FALSE(bucket.hasSdfIconData()); ASSERT_FALSE(bucket.hasTextData()); - ASSERT_FALSE(bucket.hasCollisionBoxData()); + ASSERT_FALSE(bucket.hasIconCollisionBoxData()); + ASSERT_FALSE(bucket.hasTextCollisionBoxData()); + ASSERT_FALSE(bucket.hasIconCollisionCircleData()); + ASSERT_FALSE(bucket.hasTextCollisionCircleData()); ASSERT_FALSE(bucket.hasData()); ASSERT_FALSE(bucket.needsUpload()); diff --git a/test/gl/context.test.cpp b/test/gl/context.test.cpp index 4b6bad6f65..770434c5be 100644 --- a/test/gl/context.test.cpp +++ b/test/gl/context.test.cpp @@ -91,7 +91,7 @@ TEST(GLContextMode, Shared) { util::RunLoop loop; - HeadlessFrontend frontend { 1, {}, gfx::ContextMode::Shared }; + HeadlessFrontend frontend { 1, gfx::ContextMode::Shared }; Map map(frontend, MapObserver::nullObserver(), MapOptions().withMapMode(MapMode::Static).withSize(frontend.getSize()), diff --git a/test/map/map.test.cpp b/test/map/map.test.cpp index 8cb781c6df..09e1b92336 100644 --- a/test/map/map.test.cpp +++ b/test/map/map.test.cpp @@ -762,7 +762,7 @@ TEST(Map, TEST_DISABLED_ON_CI(ContinuousRendering)) { HeadlessFrontend frontend(1); StubMapObserver observer; - observer.didFinishRenderingFrameCallback = [&] (MapObserver::RenderMode) { + observer.didFinishRenderingFrameCallback = [&] (MapObserver::RenderFrameStatus) { // Start a timer that ends the test one second from now. If we are continuing to render // indefinitely, the timer will be constantly restarted and never trigger. Instead, the // emergency shutoff above will trigger, failing the test. @@ -877,4 +877,53 @@ TEST(Map, Issue15216) { test.map.getStyle().addLayer(std::make_unique<RasterLayer>("RasterLayer", "ImageSource")); // Passes, if there is no assertion hit. test.runLoop.runOnce(); +} + +// https://github.com/mapbox/mapbox-gl-native/issues/15342 +// Tests the fix for constant repaint caused by `RenderSource::hasFadingTiles()` returning `true` all the time. +TEST(Map, Issue15342) { + MapTest<> test { 1, MapMode::Continuous }; + + test.fileSource->tileResponse = [&](const Resource&) { + Response result; + result.data = std::make_shared<std::string>(util::read_file("test/fixtures/map/issue12432/0-0-0.mvt")); + return result; + }; + test.map.jumpTo(CameraOptions().withZoom(3.0)); + test.map.getStyle().loadJSON(R"STYLE({ + "version": 8, + "sources": { + "mapbox": { + "type": "vector", + "tiles": ["http://example.com/{z}-{x}-{y}.vector.pbf"] + } + }, + "layers": [{ + "id": "water", + "type": "fill", + "source": "mapbox", + "source-layer": "water" + }] + })STYLE"); + + test.observer.didFinishLoadingMapCallback = [&]() { + test.map.getStyle().loadJSON(R"STYLE({ + "version": 8, + "sources": { + "mapbox": { + "type": "vector", + "tiles": ["http://example.com/{z}-{x}-{y}.vector.pbf"] + } + }, + "layers": [] + })STYLE"); + test.map.jumpTo(CameraOptions().withZoom(20.0)); + test.observer.didFinishRenderingFrameCallback = [&] (MapObserver::RenderFrameStatus status) { + if (!status.needsRepaint) { + test.runLoop.stop(); + } + }; + }; + + test.runLoop.run(); }
\ No newline at end of file diff --git a/test/renderer/image_manager.test.cpp b/test/renderer/image_manager.test.cpp index 0b72578c35..16700d713f 100644 --- a/test/renderer/image_manager.test.cpp +++ b/test/renderer/image_manager.test.cpp @@ -50,6 +50,18 @@ TEST(ImageManager, AddRemove) { EXPECT_EQ(nullptr, imageManager.getImage("four")); } +TEST(ImageManager, Update) { + FixtureLog log; + ImageManager imageManager; + + imageManager.addImage(makeMutable<style::Image::Impl>("one", PremultipliedImage({ 16, 16 }), 2)); + EXPECT_EQ(0, imageManager.updatedImageVersions.size()); + imageManager.updateImage(makeMutable<style::Image::Impl>("one", PremultipliedImage({ 16, 16 }), 2)); + EXPECT_EQ(1, imageManager.updatedImageVersions.size()); + imageManager.removeImage("one"); + EXPECT_EQ(0, imageManager.updatedImageVersions.size()); +} + TEST(ImageManager, RemoveReleasesBinPackRect) { FixtureLog log; ImageManager imageManager; diff --git a/test/src/mbgl/test/sqlite3_test_fs.cpp b/test/src/mbgl/test/sqlite3_test_fs.cpp index e4f958c900..068ae9e1cf 100644 --- a/test/src/mbgl/test/sqlite3_test_fs.cpp +++ b/test/src/mbgl/test/sqlite3_test_fs.cpp @@ -278,6 +278,7 @@ SQLite3TestFS::~SQLite3TestFS() { sqlite3_vfs* test_fs = sqlite3_vfs_find("test_fs"); if (test_fs) { sqlite3_vfs_unregister(test_fs); + sqlite3_free((void*)test_fs); } } diff --git a/test/src/mbgl/test/stub_map_observer.hpp b/test/src/mbgl/test/stub_map_observer.hpp index 00a039e732..89ee4e7953 100644 --- a/test/src/mbgl/test/stub_map_observer.hpp +++ b/test/src/mbgl/test/stub_map_observer.hpp @@ -32,9 +32,9 @@ public: } } - void onDidFinishRenderingFrame(RenderMode mode) final { + void onDidFinishRenderingFrame(RenderFrameStatus status) final { if (didFinishRenderingFrameCallback) { - didFinishRenderingFrameCallback(mode); + didFinishRenderingFrameCallback(status); } } @@ -42,7 +42,7 @@ public: std::function<void()> didFinishLoadingMapCallback; std::function<void()> didFailLoadingMapCallback; std::function<void()> didFinishLoadingStyleCallback; - std::function<void(RenderMode)> didFinishRenderingFrameCallback; + std::function<void(RenderFrameStatus)> didFinishRenderingFrameCallback; }; diff --git a/test/storage/offline_database.test.cpp b/test/storage/offline_database.test.cpp index 3f6db527d4..24234b0624 100644 --- a/test/storage/offline_database.test.cpp +++ b/test/storage/offline_database.test.cpp @@ -1093,8 +1093,8 @@ TEST(OfflineDatabase, HasRegionResource) { auto region = db.createRegion(definition, OfflineRegionMetadata()); ASSERT_TRUE(region); - EXPECT_FALSE(bool(db.hasRegionResource(region->getID(), Resource::style("http://example.com/1")))); - EXPECT_FALSE(bool(db.hasRegionResource(region->getID(), Resource::style("http://example.com/20")))); + EXPECT_FALSE(bool(db.hasRegionResource(Resource::style("http://example.com/1")))); + EXPECT_FALSE(bool(db.hasRegionResource(Resource::style("http://example.com/20")))); Response response; response.data = randomString(1024); @@ -1103,9 +1103,9 @@ TEST(OfflineDatabase, HasRegionResource) { db.putRegionResource(region->getID(), Resource::style("http://example.com/"s + util::toString(i)), response); } - EXPECT_TRUE(bool(db.hasRegionResource(region->getID(), Resource::style("http://example.com/1")))); - EXPECT_TRUE(bool(db.hasRegionResource(region->getID(), Resource::style("http://example.com/20")))); - EXPECT_EQ(1024, *(db.hasRegionResource(region->getID(), Resource::style("http://example.com/20")))); + EXPECT_TRUE(bool(db.hasRegionResource(Resource::style("http://example.com/1")))); + EXPECT_TRUE(bool(db.hasRegionResource(Resource::style("http://example.com/20")))); + EXPECT_EQ(1024, *(db.hasRegionResource(Resource::style("http://example.com/20")))); EXPECT_EQ(0u, log.uncheckedCount()); } @@ -1131,16 +1131,16 @@ TEST(OfflineDatabase, HasRegionResourceTile) { response.data = std::make_shared<std::string>("first"); - EXPECT_FALSE(bool(db.hasRegionResource(region->getID(), resource))); + EXPECT_FALSE(bool(db.hasRegionResource(resource))); db.putRegionResource(region->getID(), resource, response); - EXPECT_TRUE(bool(db.hasRegionResource(region->getID(), resource))); - EXPECT_EQ(5, *(db.hasRegionResource(region->getID(), resource))); + EXPECT_TRUE(bool(db.hasRegionResource(resource))); + EXPECT_EQ(5, *(db.hasRegionResource(resource))); auto anotherRegion = db.createRegion(definition, OfflineRegionMetadata()); ASSERT_TRUE(anotherRegion); EXPECT_LT(region->getID(), anotherRegion->getID()); - EXPECT_TRUE(bool(db.hasRegionResource(anotherRegion->getID(), resource))); - EXPECT_EQ(5, *(db.hasRegionResource(anotherRegion->getID(), resource))); + EXPECT_TRUE(bool(db.hasRegionResource(resource))); + EXPECT_EQ(5, *(db.hasRegionResource(resource))); EXPECT_EQ(0u, log.uncheckedCount()); @@ -1488,12 +1488,12 @@ TEST(OfflineDatabase, TEST_REQUIRES_WRITE(DisallowedIO)) { EXPECT_EQ(1u, log.count(warning(ResultCode::Auth, "Can't update region metadata: authorization denied"))); EXPECT_EQ(0u, log.uncheckedCount()); - EXPECT_EQ(nullopt, db.getRegionResource(region->getID(), fixture::resource)); + EXPECT_EQ(nullopt, db.getRegionResource(fixture::resource)); EXPECT_EQ(1u, log.count(warning(ResultCode::Auth, "Can't update timestamp: authorization denied"))); EXPECT_EQ(1u, log.count(warning(ResultCode::Auth, "Can't read region resource: authorization denied"))); EXPECT_EQ(0u, log.uncheckedCount()); - EXPECT_EQ(nullopt, db.hasRegionResource(region->getID(), fixture::resource)); + EXPECT_EQ(nullopt, db.hasRegionResource(fixture::resource)); EXPECT_EQ(1u, log.count(warning(ResultCode::Auth, "Can't query region resource: authorization denied"))); EXPECT_EQ(0u, log.uncheckedCount()); @@ -1566,7 +1566,7 @@ TEST(OfflineDatabase, TEST_REQUIRES_WRITE(MergeDatabaseWithSingleRegion_Update)) EXPECT_EQ(1u, status->completedTileCount); //Verify the modified timestamp matches the tile in the sideloaded db. - auto updatedTile = db.getRegionResource(regionId, + auto updatedTile = db.getRegionResource( Resource::tile("mapbox://tiles/mapbox.satellite/{z}/{x}/{y}{ratio}.webp", 1, 0, 0, 1, Tileset::Scheme::XYZ)); EXPECT_EQ(Timestamp{ Seconds(1520409600) }, *(updatedTile->first.modified)); @@ -1586,8 +1586,7 @@ TEST(OfflineDatabase, MergeDatabaseWithSingleRegion_NoUpdate) { EXPECT_EQ(1u, result->size()); EXPECT_EQ(1u, db.listRegions()->size()); - auto regionId = result->front().getID(); - auto updatedTile = db.getRegionResource(regionId, + auto updatedTile = db.getRegionResource( Resource::tile("mapbox://tiles/mapbox.satellite/{z}/{x}/{y}{ratio}.webp", 1, 0, 0, 1, Tileset::Scheme::XYZ)); @@ -1601,14 +1600,13 @@ TEST(OfflineDatabase, MergeDatabaseWithSingleRegion_AmbientTiles) { OfflineDatabase db(":memory:"); auto result = db.mergeDatabase(filename_sideload); - auto regionId = result->front().getID(); - EXPECT_TRUE(bool(db.hasRegionResource(regionId, Resource::tile("mapbox://tiles/mapbox.satellite/{z}/{x}/{y}{ratio}.png", 1, 0, 0, 1, Tileset::Scheme::XYZ)))); + EXPECT_TRUE(bool(db.hasRegionResource(Resource::tile("mapbox://tiles/mapbox.satellite/{z}/{x}/{y}{ratio}.png", 1, 0, 0, 1, Tileset::Scheme::XYZ)))); //Ambient resources should not be copied - EXPECT_FALSE(bool(db.hasRegionResource(regionId, Resource::style("mapbox://styles/mapbox/streets-v9")))); - EXPECT_FALSE(bool(db.hasRegionResource(regionId, Resource::tile("mapbox://tiles/mapbox.satellite/{z}/{x}/{y}{ratio}.png", 1, 0, 1, 2, Tileset::Scheme::XYZ)))); - EXPECT_FALSE(bool(db.hasRegionResource(regionId, Resource::tile("mapbox://tiles/mapbox.satellite/{z}/{x}/{y}{ratio}.png", 1, 1, 1, 2, Tileset::Scheme::XYZ)))); + EXPECT_FALSE(bool(db.hasRegionResource(Resource::style("mapbox://styles/mapbox/streets-v9")))); + EXPECT_FALSE(bool(db.hasRegionResource(Resource::tile("mapbox://tiles/mapbox.satellite/{z}/{x}/{y}{ratio}.png", 1, 0, 1, 2, Tileset::Scheme::XYZ)))); + EXPECT_FALSE(bool(db.hasRegionResource(Resource::tile("mapbox://tiles/mapbox.satellite/{z}/{x}/{y}{ratio}.png", 1, 1, 1, 2, Tileset::Scheme::XYZ)))); } TEST(OfflineDatabase, MergeDatabaseWithMultipleRegions_New) { diff --git a/test/storage/offline_download.test.cpp b/test/storage/offline_download.test.cpp index 9cdafaaf1e..ebe3f82ee9 100644 --- a/test/storage/offline_download.test.cpp +++ b/test/storage/offline_download.test.cpp @@ -1,8 +1,12 @@ +#include <mbgl/test/map_adapter.hpp> #include <mbgl/test/stub_file_source.hpp> #include <mbgl/test/fake_file_source.hpp> +#include <mbgl/test/stub_map_observer.hpp> #include <mbgl/test/fixture_log_observer.hpp> #include <mbgl/test/sqlite3_test_fs.hpp> +#include <mbgl/gfx/headless_frontend.hpp> +#include <mbgl/storage/default_file_source.hpp> #include <mbgl/storage/offline.hpp> #include <mbgl/storage/offline_database.hpp> #include <mbgl/storage/offline_download.hpp> @@ -14,7 +18,6 @@ #include <mbgl/storage/sqlite3.hpp> #include <gtest/gtest.h> -#include <iostream> using namespace mbgl; using namespace std::literals::string_literals; @@ -71,6 +74,10 @@ public: return db.createRegion(definition, metadata); } + auto invalidateRegion(int64_t region) { + return db.invalidateRegion(region); + } + Response response(const std::string& path) { Response result; result.data = std::make_shared<std::string>(util::read_file("test/fixtures/offline_download/"s + path)); @@ -150,6 +157,7 @@ TEST(OfflineDownload, InlineSource) { observer->statusChangedFn = [&] (OfflineRegionStatus status) { if (status.complete()) { + EXPECT_EQ(1u, status.completedTileCount); EXPECT_EQ(2u, status.completedResourceCount); EXPECT_EQ(test.size, status.completedResourceSize); EXPECT_TRUE(status.requiredResourceCountIsPrecise); @@ -253,6 +261,7 @@ TEST(OfflineDownload, Activate) { observer->statusChangedFn = [&] (OfflineRegionStatus status) { if (status.complete()) { + EXPECT_EQ(status.completedTileCount, status.requiredTileCount); EXPECT_EQ(264u, status.completedResourceCount); // 256 glyphs, 2 sprite images, 2 sprite jsons, 1 tile, 1 style, source, image EXPECT_EQ(test.size, status.completedResourceSize); @@ -260,6 +269,7 @@ TEST(OfflineDownload, Activate) { OfflineRegionStatus computedStatus = download.getStatus(); EXPECT_EQ(OfflineRegionDownloadState::Inactive, computedStatus.downloadState); EXPECT_EQ(status.requiredResourceCount, computedStatus.requiredResourceCount); + EXPECT_EQ(status.requiredTileCount, computedStatus.requiredTileCount); EXPECT_EQ(status.completedResourceCount, computedStatus.completedResourceCount); EXPECT_EQ(status.completedResourceSize, computedStatus.completedResourceSize); EXPECT_EQ(status.completedTileCount, computedStatus.completedTileCount); @@ -330,6 +340,7 @@ TEST(OfflineDownload, ExcludeIdeographs) { observer->statusChangedFn = [&] (OfflineRegionStatus status) { if (status.complete()) { + EXPECT_EQ(status.completedTileCount, status.requiredTileCount); EXPECT_EQ(138u, status.completedResourceCount); // 130 glyphs, 2 sprite images, 2 sprite jsons, 1 tile, 1 style, source, image EXPECT_EQ(test.size, status.completedResourceSize); @@ -337,6 +348,7 @@ TEST(OfflineDownload, ExcludeIdeographs) { OfflineRegionStatus computedStatus = download.getStatus(); EXPECT_EQ(OfflineRegionDownloadState::Inactive, computedStatus.downloadState); EXPECT_EQ(status.requiredResourceCount, computedStatus.requiredResourceCount); + EXPECT_EQ(status.requiredTileCount, computedStatus.requiredTileCount); EXPECT_EQ(status.completedResourceCount, computedStatus.completedResourceCount); EXPECT_EQ(status.completedResourceSize, computedStatus.completedResourceSize); EXPECT_EQ(status.completedTileCount, computedStatus.completedTileCount); @@ -391,6 +403,8 @@ TEST(OfflineDownload, GetStatusNoResources) { EXPECT_EQ(0u, status.completedResourceCount); EXPECT_EQ(0u, status.completedResourceSize); EXPECT_EQ(1u, status.requiredResourceCount); + EXPECT_EQ(0u, status.completedTileCount); + EXPECT_EQ(0u, status.requiredTileCount); EXPECT_FALSE(status.requiredResourceCountIsPrecise); EXPECT_FALSE(status.complete()); } @@ -414,6 +428,8 @@ TEST(OfflineDownload, GetStatusStyleComplete) { EXPECT_EQ(1u, status.completedResourceCount); EXPECT_EQ(test.size, status.completedResourceSize); EXPECT_EQ(263u, status.requiredResourceCount); + EXPECT_EQ(0u, status.completedTileCount); + EXPECT_EQ(0u, status.requiredTileCount); EXPECT_FALSE(status.requiredResourceCountIsPrecise); EXPECT_FALSE(status.complete()); } @@ -441,6 +457,8 @@ TEST(OfflineDownload, GetStatusStyleAndSourceComplete) { EXPECT_EQ(2u, status.completedResourceCount); EXPECT_EQ(test.size, status.completedResourceSize); EXPECT_EQ(264u, status.requiredResourceCount); + EXPECT_EQ(0u, status.completedTileCount); + EXPECT_EQ(1u, status.requiredTileCount); EXPECT_TRUE(status.requiredResourceCountIsPrecise); EXPECT_FALSE(status.complete()); } @@ -857,4 +875,75 @@ TEST(OfflineDownload, DiskFull) { test.loop.run(); EXPECT_EQ(0u, log.uncheckedCount()); } + +// Test verifies that resource requests for invalidated region don't +// have Resource::Usage::Offline tag set. +TEST(OfflineDownload, ResourceOfflineUsageUnset) { + deleteDatabaseFiles(); + test::SQLite3TestFS fs; + + OfflineTest test{ filename_test_fs }; + auto region = test.createRegion(); + ASSERT_TRUE(region); + + OfflineDownload download( + region->getID(), + OfflineTilePyramidRegionDefinition("http://127.0.0.1:3000/inline_source.style.json", + LatLngBounds::world(), 0.0, 0.0, 1.0, false), + test.db, test.fileSource); + + test.fileSource.styleResponse = [&] (const Resource& resource) { + EXPECT_TRUE(resource.priority == Resource::Priority::Low); + EXPECT_TRUE(resource.usage == Resource::Usage::Offline); + return test.response("inline_source.style.json"); + }; + + test.fileSource.tileResponse = [&] (const Resource& resource) { + EXPECT_TRUE(resource.priority == Resource::Priority::Low); + EXPECT_TRUE(resource.usage == Resource::Usage::Offline); + return test.response("0-0-0.vector.pbf"); + }; + + auto observer = std::make_unique<MockObserver>(); + observer->statusChangedFn = [&] (OfflineRegionStatus status) { + if (status.complete()) { + // Once download completes, invalidate region and try rendering map. + // Resource requests must not have Offline usage tag. + ASSERT_FALSE(test.invalidateRegion(region->getID())); + test.loop.stop(); + } + }; + + download.setObserver(std::move(observer)); + download.setState(OfflineRegionDownloadState::Active); + test.loop.run(); + + std::shared_ptr<StubFileSource> stubfileSource = std::make_shared<StubFileSource>(); + stubfileSource->styleResponse = [&] (const Resource& resource) { + EXPECT_TRUE(resource.usage != Resource::Usage::Offline); + return test.response("inline_source.style.json"); + }; + + stubfileSource->tileResponse = [&] (const Resource& resource) { + EXPECT_TRUE(resource.usage != Resource::Usage::Offline); + return test.response("0-0-0.vector.pbf"); + }; + + StubMapObserver mapObserver; + mapObserver.didFinishRenderingFrameCallback = [&] (MapObserver::RenderFrameStatus status) { + if (status.mode == MapObserver::RenderMode::Full) { + test.loop.stop(); + } + }; + + HeadlessFrontend frontend { 1 }; + MapAdapter map { frontend, mapObserver, stubfileSource, + MapOptions() + .withMapMode(MapMode::Continuous) + .withSize(frontend.getSize())}; + + map.getStyle().loadURL("http://127.0.0.1:3000/inline_source.style.json"); + map.jumpTo(CameraOptions().withCenter(LatLng{0.0, 0.0}).withZoom(0)); + test.loop.run(); +} #endif // __QT__ diff --git a/test/storage/sync_file_source.test.cpp b/test/storage/sync_file_source.test.cpp new file mode 100644 index 0000000000..4bd964199d --- /dev/null +++ b/test/storage/sync_file_source.test.cpp @@ -0,0 +1,50 @@ +#include <mbgl/util/run_loop.hpp> +#include <mbgl/util/io.hpp> +#include <mbgl/storage/file_source.hpp> +#include <mbgl/gfx/headless_frontend.hpp> +#include <mbgl/map/map.hpp> +#include <mbgl/map/map_impl.hpp> +#include <mbgl/style/style.hpp> +#include <mbgl/test/map_adapter.hpp> +#include <unordered_map> + +#include <gtest/gtest.h> + +using namespace mbgl; + +class SyncFileSource : public FileSource { +public: + std::unique_ptr<AsyncRequest> request(const Resource& resource, FileSource::Callback callback) { + Response response; + auto it = assets.find(resource.url); + if (it == assets.end()) { + response.error = std::make_unique<Response::Error>( + Response::Error::Reason::NotFound, std::string{ "Not Found: " } + resource.url); + } else { + response.data = it->second; + } + callback(response); + return nullptr; + } + + void add(std::string const& key, std::string const& data) { + assets.emplace(key, std::make_shared<std::string>(data)); + }; + +private: + std::unordered_map<std::string, std::shared_ptr<std::string>> assets; +}; + +TEST(SyncFileSource, LoadSyncRender) { + util::RunLoop loop; + auto fs = std::make_shared<SyncFileSource>(); + fs->add("mapbox://mapbox.mapbox-terrain-v2,mapbox.mapbox-streets-v7", + util::read_file("test/fixtures/resources/source_vector.json")); + fs->add("mapbox://sprites/mapbox/streets-v9.png", + util::read_file("test/fixtures/resources/sprite.png")); + fs->add("mapbox://sprites/mapbox/streets-v9.json", + util::read_file("test/fixtures/resources/sprite.json")); + HeadlessFrontend frontend{ { 512, 512 }, 1.0 }; + MapAdapter map{ frontend, MapObserver::nullObserver(), fs, MapOptions() }; + map.getStyle().loadJSON(util::read_file("test/fixtures/resources/style_vector.json")); +} diff --git a/test/style/conversion/geojson_options.test.cpp b/test/style/conversion/geojson_options.test.cpp index 181189775b..aa84686dce 100644 --- a/test/style/conversion/geojson_options.test.cpp +++ b/test/style/conversion/geojson_options.test.cpp @@ -38,6 +38,7 @@ TEST(GeoJSONOptions, RetainsDefaults) { ASSERT_EQ(converted.cluster, defaults.cluster); ASSERT_EQ(converted.clusterRadius, defaults.clusterRadius); ASSERT_EQ(converted.clusterMaxZoom, defaults.clusterMaxZoom); + ASSERT_TRUE(converted.clusterProperties.empty()); } TEST(GeoJSONOptions, FullConversion) { @@ -49,7 +50,12 @@ TEST(GeoJSONOptions, FullConversion) { "cluster": true, "clusterRadius": 4, "clusterMaxZoom": 5, - "lineMetrics": true + "lineMetrics": true, + "clusterProperties": { + "max": ["max", ["get", "scalerank"]], + "sum": [["+", ["accumulated"], ["get", "sum"]], ["get", "scalerank"]], + "has_island": ["any", ["==", ["get", "featureclass"], "island"]] + } })JSON", error); // GeoJSON-VT @@ -63,4 +69,8 @@ TEST(GeoJSONOptions, FullConversion) { ASSERT_EQ(converted.cluster, true); ASSERT_EQ(converted.clusterRadius, 4); ASSERT_EQ(converted.clusterMaxZoom, 5); + ASSERT_EQ(converted.clusterProperties.size(), 3); + ASSERT_EQ(converted.clusterProperties.count("max"), 1); + ASSERT_EQ(converted.clusterProperties.count("sum"), 1); + ASSERT_EQ(converted.clusterProperties.count("has_island"), 1); } diff --git a/test/style/conversion/light.test.cpp b/test/style/conversion/light.test.cpp index 092c476277..e49667f319 100644 --- a/test/style/conversion/light.test.cpp +++ b/test/style/conversion/light.test.cpp @@ -5,8 +5,10 @@ #include <mbgl/style/conversion/light.hpp> #include <mbgl/style/conversion_impl.hpp> #include <mbgl/style/position.hpp> +#include <mbgl/style/rapidjson_conversion.hpp> #include <mbgl/util/color.hpp> #include <mbgl/util/chrono.hpp> +#include <mbgl/util/rapidjson.hpp> #include <array> @@ -24,6 +26,27 @@ TEST(StyleConversion, Light) { { auto light = parseLight("{}"); ASSERT_TRUE((bool) light); + + const mbgl::JSValue colorValue("blue"); + light->setProperty("color", &colorValue); + + ASSERT_FALSE(light->getColor().isUndefined()); + ASSERT_TRUE(light->getColor().isConstant()); + ASSERT_EQ(light->getColor().asConstant(), mbgl::Color::blue()); + + const mbgl::JSValue intensityValue(0.5); + light->setProperty("intensity", &intensityValue); + ASSERT_FALSE(light->getIntensity().isUndefined()); + ASSERT_TRUE(light->getIntensity().isConstant()); + ASSERT_EQ(light->getIntensity().asConstant(), 0.5); + + mbgl::JSValue::AllocatorType allocator; + const mbgl::JSValue positionValue(std::move(mbgl::JSValue(rapidjson::kArrayType).PushBack(1.f, allocator).PushBack(2.f, allocator).PushBack(3.f, allocator).Move())); + light->setProperty("position", &positionValue); + ASSERT_FALSE(light->getPosition().isUndefined()); + ASSERT_TRUE(light->getPosition().isConstant()); + std::array<float, 3> expected{{ 1.f, 2.f, 3.f }}; + ASSERT_EQ(light->getPosition().asConstant(), mbgl::style::Position({ expected })); } { diff --git a/test/style/expression/expression.test.cpp b/test/style/expression/expression.test.cpp index 8e2acfcd32..dd986c98f5 100644 --- a/test/style/expression/expression.test.cpp +++ b/test/style/expression/expression.test.cpp @@ -36,8 +36,7 @@ TEST(Expression, IsExpression) { // TODO: "feature-state": https://github.com/mapbox/mapbox-gl-native/issues/12613 // TODO: "interpolate-hcl": https://github.com/mapbox/mapbox-gl-native/issues/8720 // TODO: "interpolate-lab": https://github.com/mapbox/mapbox-gl-native/issues/8720 - // TODO: "accumulated": https://github.com/mapbox/mapbox-gl-native/issues/14043 - if (name == "feature-state" || name == "interpolate-hcl" || name == "interpolate-lab" || name == "accumulated") { + if (name == "feature-state" || name == "interpolate-hcl" || name == "interpolate-lab") { if (expression::isExpression(conversion::Convertible(expression))) { ASSERT_TRUE(false) << "Expression name" << name << "is implemented - please update Expression.IsExpression test."; } diff --git a/test/test-files.json b/test/test-files.json index e46f833269..b239ac5ad8 100644 --- a/test/test-files.json +++ b/test/test-files.json @@ -46,6 +46,7 @@ "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", @@ -92,7 +93,6 @@ "test/util/merge_lines.test.cpp", "test/util/number_conversions.test.cpp", "test/util/offscreen_texture.test.cpp", - "test/util/peer.test.cpp", "test/util/position.test.cpp", "test/util/projection.test.cpp", "test/util/run_loop.test.cpp", diff --git a/test/text/cross_tile_symbol_index.test.cpp b/test/text/cross_tile_symbol_index.test.cpp index ccf83e81c8..4ff84063f9 100644 --- a/test/text/cross_tile_symbol_index.test.cpp +++ b/test/text/cross_tile_symbol_index.test.cpp @@ -13,12 +13,13 @@ SymbolInstance makeSymbolInstance(float x, float y, std::u16string key) { Anchor anchor(x, y, 0, 0); std::array<float, 2> textOffset{{0.0f, 0.0f}}; std::array<float, 2> iconOffset{{0.0f, 0.0f}}; + std::array<float, 2> variableTextOffset{{0.0f, 0.0f}}; style::SymbolPlacementType placementType = style::SymbolPlacementType::Point; auto sharedData = std::make_shared<SymbolInstanceSharedData>(std::move(line), - shaping, nullopt, layout_, 0.0f, placementType, + shaping, nullopt, nullopt, layout_, placementType, textOffset, positions, false); - return SymbolInstance(anchor, std::move(sharedData), shaping, nullopt, 0, 0, placementType, textOffset, 0, 0, iconOffset, subfeature, 0, 0, key, 0.0f, 0.0f, 0.0f, 0.0f, false); + return SymbolInstance(anchor, std::move(sharedData), shaping, nullopt, nullopt, 0, 0, placementType, textOffset, 0, 0, iconOffset, subfeature, 0, 0, key, 0.0f, 0.0f, 0.0f, variableTextOffset, false); } @@ -30,7 +31,6 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { Immutable<style::SymbolLayoutProperties::PossiblyEvaluated> layout = makeMutable<style::SymbolLayoutProperties::PossiblyEvaluated>(); - bool sdfIcons = false; bool iconsNeedLinear = false; bool sortFeaturesByY = false; std::string bucketLeaderID = "test"; @@ -39,7 +39,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { std::vector<SymbolInstance> mainInstances; mainInstances.push_back(makeSymbolInstance(1000, 1000, u"Detroit")); mainInstances.push_back(makeSymbolInstance(2000, 2000, u"Toronto")); - SymbolBucket mainBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(mainInstances), 1.0f, false, {} }; + SymbolBucket mainBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(mainInstances), 1.0f, false, {} }; mainBucket.bucketInstanceId = ++maxBucketInstanceId; index.addBucket(mainID, mainBucket, maxCrossTileID); @@ -54,7 +54,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { childInstances.push_back(makeSymbolInstance(2000, 2000, u"Windsor")); childInstances.push_back(makeSymbolInstance(3000, 3000, u"Toronto")); childInstances.push_back(makeSymbolInstance(4001, 4001, u"Toronto")); - SymbolBucket childBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(childInstances), 1.0f, false, {} }; + SymbolBucket childBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(childInstances), 1.0f, false, {} }; childBucket.bucketInstanceId = ++maxBucketInstanceId; index.addBucket(childID, childBucket, maxCrossTileID); @@ -70,7 +70,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { OverscaledTileID parentID(5, 0, 5, 4, 4); std::vector<SymbolInstance> parentInstances; parentInstances.push_back(makeSymbolInstance(500, 500, u"Detroit")); - SymbolBucket parentBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(parentInstances), 1.0f, false, {} }; + SymbolBucket parentBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(parentInstances), 1.0f, false, {} }; parentBucket.bucketInstanceId = ++maxBucketInstanceId; index.addBucket(parentID, parentBucket, maxCrossTileID); @@ -86,7 +86,7 @@ TEST(CrossTileSymbolLayerIndex, addBucket) { std::vector<SymbolInstance> grandchildInstances; grandchildInstances.push_back(makeSymbolInstance(4000, 4000, u"Detroit")); grandchildInstances.push_back(makeSymbolInstance(4000, 4000, u"Windsor")); - SymbolBucket grandchildBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(grandchildInstances), 1.0f, false, {} }; + SymbolBucket grandchildBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(grandchildInstances), 1.0f, false, {} }; grandchildBucket.bucketInstanceId = ++maxBucketInstanceId; index.addBucket(grandchildID, grandchildBucket, maxCrossTileID); @@ -105,7 +105,6 @@ TEST(CrossTileSymbolLayerIndex, resetIDs) { Immutable<style::SymbolLayoutProperties::PossiblyEvaluated> layout = makeMutable<style::SymbolLayoutProperties::PossiblyEvaluated>(); - bool sdfIcons = false; bool iconsNeedLinear = false; bool sortFeaturesByY = false; std::string bucketLeaderID = "test"; @@ -113,13 +112,13 @@ TEST(CrossTileSymbolLayerIndex, resetIDs) { OverscaledTileID mainID(6, 0, 6, 8, 8); std::vector<SymbolInstance> mainInstances; mainInstances.push_back(makeSymbolInstance(1000, 1000, u"Detroit")); - SymbolBucket mainBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(mainInstances), 1.0f, false, {} }; + SymbolBucket mainBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(mainInstances), 1.0f, false, {} }; mainBucket.bucketInstanceId = ++maxBucketInstanceId; OverscaledTileID childID(7, 0, 7, 16, 16); std::vector<SymbolInstance> childInstances; childInstances.push_back(makeSymbolInstance(2000, 2000, u"Detroit")); - SymbolBucket childBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(childInstances), 1.0f, false, {} }; + SymbolBucket childBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(childInstances), 1.0f, false, {} }; childBucket.bucketInstanceId = ++maxBucketInstanceId; // assigns a new id @@ -146,7 +145,6 @@ TEST(CrossTileSymbolLayerIndex, noDuplicatesWithinZoomLevel) { Immutable<style::SymbolLayoutProperties::PossiblyEvaluated> layout = makeMutable<style::SymbolLayoutProperties::PossiblyEvaluated>(); - bool sdfIcons = false; bool iconsNeedLinear = false; bool sortFeaturesByY = false; std::string bucketLeaderID = "test"; @@ -155,7 +153,7 @@ TEST(CrossTileSymbolLayerIndex, noDuplicatesWithinZoomLevel) { std::vector<SymbolInstance> mainInstances; mainInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // A mainInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // B - SymbolBucket mainBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(mainInstances), 1.0f, false, {} }; + SymbolBucket mainBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(mainInstances), 1.0f, false, {} }; mainBucket.bucketInstanceId = ++maxBucketInstanceId; OverscaledTileID childID(7, 0, 7, 16, 16); @@ -163,7 +161,7 @@ TEST(CrossTileSymbolLayerIndex, noDuplicatesWithinZoomLevel) { childInstances.push_back(makeSymbolInstance(2000, 2000, u"")); // A' childInstances.push_back(makeSymbolInstance(2000, 2000, u"")); // B' childInstances.push_back(makeSymbolInstance(2000, 2000, u"")); // C' - SymbolBucket childBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(childInstances), 1.0f, false, {} }; + SymbolBucket childBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(childInstances), 1.0f, false, {} }; childBucket.bucketInstanceId = ++maxBucketInstanceId; // assigns new ids @@ -185,7 +183,6 @@ TEST(CrossTileSymbolLayerIndex, bucketReplacement) { Immutable<style::SymbolLayoutProperties::PossiblyEvaluated> layout = makeMutable<style::SymbolLayoutProperties::PossiblyEvaluated>(); - bool sdfIcons = false; bool iconsNeedLinear = false; bool sortFeaturesByY = false; std::string bucketLeaderID = "test"; @@ -194,14 +191,14 @@ TEST(CrossTileSymbolLayerIndex, bucketReplacement) { std::vector<SymbolInstance> firstInstances; firstInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // A firstInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // B - SymbolBucket firstBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(firstInstances), 1.0f, false, {} }; + SymbolBucket firstBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(firstInstances), 1.0f, false, {} }; firstBucket.bucketInstanceId = ++maxBucketInstanceId; std::vector<SymbolInstance> secondInstances; secondInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // A' secondInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // B' secondInstances.push_back(makeSymbolInstance(1000, 1000, u"")); // C' - SymbolBucket secondBucket { layout, {}, 16.0f, 1.0f, 0, sdfIcons, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(secondInstances), 1.0f, false, {} }; + SymbolBucket secondBucket { layout, {}, 16.0f, 1.0f, 0, iconsNeedLinear, sortFeaturesByY, bucketLeaderID, std::move(secondInstances), 1.0f, false, {} }; secondBucket.bucketInstanceId = ++maxBucketInstanceId; // assigns new ids diff --git a/test/text/glyph_manager.test.cpp b/test/text/glyph_manager.test.cpp index 1193780631..1e9aef38ed 100644 --- a/test/text/glyph_manager.test.cpp +++ b/test/text/glyph_manager.test.cpp @@ -20,7 +20,7 @@ static constexpr const size_t stubBitmapLength = 900; class StubLocalGlyphRasterizer : public LocalGlyphRasterizer { public: bool canRasterizeGlyph(const FontStack&, GlyphID glyphID) override { - return util::i18n::allowsIdeographicBreaking(glyphID); + return util::i18n::allowsFixedWidthGlyphGeneration(glyphID); } Glyph rasterizeGlyph(const FontStack&, GlyphID glyphID) override { @@ -253,6 +253,57 @@ TEST(GlyphManager, LoadLocalCJKGlyph) { }); } +TEST(GlyphManager, LoadLocalCJKGlyphAfterLoadingRangeFromURL) { + GlyphManagerTest test; + int firstGlyphResponse = false; + + test.fileSource.glyphsResponse = [&] (const Resource&) { + firstGlyphResponse = true; + Response response; + response.data = std::make_shared<std::string>(util::read_file("test/fixtures/resources/glyphs-12244-12543.pbf")); + return response; + + }; + + test.requestor.glyphsAvailable = [&] (GlyphMap glyphs) { + const auto& testPositions = glyphs.at(FontStackHasher()({{"Test Stack"}})); + + if (firstGlyphResponse == true) { + firstGlyphResponse = false; + ASSERT_EQ(testPositions.size(), 1u); + ASSERT_EQ(testPositions.count(u'々'), 1u); + + //Katakana letter te, should be locally rasterized + // instead of using the glyph recieved from the range + // for the ideagraphic mark + test.glyphManager.getGlyphs(test.requestor, + GlyphDependencies { + {{{"Test Stack"}}, {u'テ'}} // 0x30c6 + }, + test.fileSource); + } else { + ASSERT_EQ(testPositions.size(), 1u); + ASSERT_EQ(testPositions.count(u'テ'), 1u); + + Immutable<Glyph> glyph = *testPositions.at(u'テ'); + EXPECT_EQ(glyph->id, u'テ'); + EXPECT_EQ(glyph->metrics.width, 24ul); + EXPECT_EQ(glyph->metrics.height, 24ul); + EXPECT_EQ(glyph->metrics.left, 0); + EXPECT_EQ(glyph->metrics.top, -8); + EXPECT_EQ(glyph->metrics.advance, 24ul); + EXPECT_EQ(glyph->bitmap.size, Size(30, 30)); + + test.end(); + } + }; + + test.run( + "test/fixtures/resources/glyphs-12244-12543.pbf", + GlyphDependencies { + {{{"Test Stack"}}, {u'々'}} //0x3005 + }); +} TEST(GlyphManager, LoadingInvalid) { GlyphManagerTest test; diff --git a/test/text/local_glyph_rasterizer.test.cpp b/test/text/local_glyph_rasterizer.test.cpp index 86dc87b6c7..2722ee5849 100644 --- a/test/text/local_glyph_rasterizer.test.cpp +++ b/test/text/local_glyph_rasterizer.test.cpp @@ -33,7 +33,7 @@ namespace { class LocalGlyphRasterizerTest { public: LocalGlyphRasterizerTest(const optional<std::string> fontFamily) - : frontend(1, optional<std::string>(), gfx::ContextMode::Unique, fontFamily) + : frontend(1, gfx::ContextMode::Unique, fontFamily) { } @@ -43,7 +43,7 @@ public: MapAdapter map { frontend, MapObserver::nullObserver(), fileSource, MapOptions().withMapMode(MapMode::Static).withSize(frontend.getSize())}; - void checkRendering(const char * name, double imageMatchPixelsThreshold = 0.05, double pixelMatchThreshold = 0.1) { + void checkRendering(const char * name, double imageMatchPixelsThreshold = 0.015, double pixelMatchThreshold = 0.1) { test::checkImage(std::string("test/fixtures/local_glyphs/") + name, frontend.render(map), imageMatchPixelsThreshold, pixelMatchThreshold); } @@ -64,7 +64,7 @@ TEST(LocalGlyphRasterizer, PingFang) { return response; }; test.map.getStyle().loadJSON(util::read_file("test/fixtures/local_glyphs/mixed.json")); -#if defined(__APPLE__) +#if defined(__APPLE__) && !defined(__QT__) test.checkRendering("ping_fang"); #elif defined(__QT__) test.checkRendering("ping_fang_qt"); @@ -73,6 +73,22 @@ TEST(LocalGlyphRasterizer, PingFang) { #endif // defined(__APPLE__) +#if defined(__linux__) && defined(__QT__) +TEST(LocalGlyphRasterizer, NotoSansCJK) { + LocalGlyphRasterizerTest test(std::string("Noto Sans CJK KR Regular")); + + test.fileSource->glyphsResponse = [&] (const Resource& resource) { + EXPECT_EQ(Resource::Kind::Glyphs, resource.kind); + Response response; + response.data = std::make_shared<std::string>(util::read_file("test/fixtures/resources/glyphs.pbf")); + return response; + }; + + test.map.getStyle().loadJSON(util::read_file("test/fixtures/local_glyphs/mixed.json")); + test.checkRendering("noto_sans_cjk_kr_regular_qt"); +} +#endif // defined(__linux__) && defined(__QT__) + TEST(LocalGlyphRasterizer, NoLocal) { // Expectation: without any local fonts set, and without any CJK glyphs provided, // the output should just contain basic latin characters. diff --git a/test/text/quads.test.cpp b/test/text/quads.test.cpp index c032d58b88..7aaeb4870d 100644 --- a/test/text/quads.test.cpp +++ b/test/text/quads.test.cpp @@ -20,10 +20,9 @@ TEST(getIconQuads, normal) { auto shapedIcon = PositionedIcon::shapeIcon(image, {{ -6.5f, -4.5f }}, SymbolAnchorType::Center, 0); GeometryCoordinates line; - Shaping shapedText; SymbolQuad quad = - getIconQuad(shapedIcon, layout, 16.0f, shapedText); + getIconQuad(shapedIcon, WritingModeType::Horizontal); EXPECT_EQ(quad.tl.x, -14); EXPECT_EQ(quad.tl.y, -10); @@ -42,8 +41,6 @@ TEST(getIconQuads, style) { style::Image::Impl("test", PremultipliedImage({1,1}), 1.0) }; - auto shapedIcon = PositionedIcon::shapeIcon(image, {{ -9.5f, -9.5f }}, SymbolAnchorType::Center, 0); - GeometryCoordinates line; Shaping shapedText; shapedText.top = -10.0f; @@ -54,9 +51,10 @@ TEST(getIconQuads, style) { // none { + auto shapedIcon = PositionedIcon::shapeIcon(image, {{ -9.5f, -9.5f }}, SymbolAnchorType::Center, 0); SymbolLayoutProperties::Evaluated layout; SymbolQuad quad = - getIconQuad(shapedIcon, layout, 12.0f, shapedText); + getIconQuad(shapedIcon, WritingModeType::Horizontal); EXPECT_EQ(quad.tl.x, -19.5); EXPECT_EQ(quad.tl.y, -19.5); @@ -73,16 +71,18 @@ TEST(getIconQuads, style) { SymbolLayoutProperties::Evaluated layout; layout.get<TextSize>() = 24.0f; layout.get<IconTextFit>() = IconTextFitType::Width; + auto shapedIcon = PositionedIcon::shapeIcon(image, {{ -9.5f, -9.5f }}, SymbolAnchorType::Center, 0); + shapedIcon.fitIconToText(layout, shapedText, 24.0f); SymbolQuad quad = - getIconQuad(shapedIcon, layout, 24.0f, shapedText); + getIconQuad(shapedIcon, WritingModeType::Horizontal); - EXPECT_EQ(quad.tl.x, -60); + EXPECT_EQ(quad.tl.x, -61); EXPECT_EQ(quad.tl.y, 0); - EXPECT_EQ(quad.tr.x, 20); + EXPECT_EQ(quad.tr.x, 21); EXPECT_EQ(quad.tr.y, 0); - EXPECT_EQ(quad.bl.x, -60); + EXPECT_EQ(quad.bl.x, -61); EXPECT_EQ(quad.bl.y, 20); - EXPECT_EQ(quad.br.x, 20); + EXPECT_EQ(quad.br.x, 21); EXPECT_EQ(quad.br.y, 20); } @@ -91,16 +91,18 @@ TEST(getIconQuads, style) { SymbolLayoutProperties::Evaluated layout; layout.get<TextSize>() = 12.0f; layout.get<IconTextFit>() = IconTextFitType::Width; + auto shapedIcon = PositionedIcon::shapeIcon(image, {{ -9.5f, -9.5f }}, SymbolAnchorType::Center, 0); + shapedIcon.fitIconToText(layout, shapedText, 12.0f); SymbolQuad quad = - getIconQuad(shapedIcon, layout, 12.0f, shapedText); + getIconQuad(shapedIcon, WritingModeType::Horizontal); - EXPECT_EQ(quad.tl.x, -30); + EXPECT_EQ(quad.tl.x, -31); EXPECT_EQ(quad.tl.y, -5); - EXPECT_EQ(quad.tr.x, 10); + EXPECT_EQ(quad.tr.x, 11); EXPECT_EQ(quad.tr.y, -5); - EXPECT_EQ(quad.bl.x, -30); + EXPECT_EQ(quad.bl.x, -31); EXPECT_EQ(quad.bl.y, 15); - EXPECT_EQ(quad.br.x, 10); + EXPECT_EQ(quad.br.x, 11); EXPECT_EQ(quad.br.y, 15); } @@ -113,16 +115,18 @@ TEST(getIconQuads, style) { layout.get<IconTextFitPadding>()[1] = 10.0f; layout.get<IconTextFitPadding>()[2] = 5.0f; layout.get<IconTextFitPadding>()[3] = 10.0f; + auto shapedIcon = PositionedIcon::shapeIcon(image, {{ -9.5f, -9.5f }}, SymbolAnchorType::Center, 0); + shapedIcon.fitIconToText(layout, shapedText, 12.0f); SymbolQuad quad = - getIconQuad(shapedIcon, layout, 12.0f, shapedText); + getIconQuad(shapedIcon, WritingModeType::Horizontal); - EXPECT_EQ(quad.tl.x, -40); + EXPECT_EQ(quad.tl.x, -41); EXPECT_EQ(quad.tl.y, -10); - EXPECT_EQ(quad.tr.x, 20); + EXPECT_EQ(quad.tr.x, 21); EXPECT_EQ(quad.tr.y, -10); - EXPECT_EQ(quad.bl.x, -40); + EXPECT_EQ(quad.bl.x, -41); EXPECT_EQ(quad.bl.y, 20); - EXPECT_EQ(quad.br.x, 20); + EXPECT_EQ(quad.br.x, 21); EXPECT_EQ(quad.br.y, 20); } @@ -131,17 +135,19 @@ TEST(getIconQuads, style) { SymbolLayoutProperties::Evaluated layout; layout.get<TextSize>() = 24.0f; layout.get<IconTextFit>() = IconTextFitType::Height; + auto shapedIcon = PositionedIcon::shapeIcon(image, {{ -9.5f, -9.5f }}, SymbolAnchorType::Center, 0); + shapedIcon.fitIconToText(layout, shapedText, 24.0f); SymbolQuad quad = - getIconQuad(shapedIcon, layout, 24.0f, shapedText); + getIconQuad(shapedIcon, WritingModeType::Horizontal); EXPECT_EQ(quad.tl.x, -30); - EXPECT_EQ(quad.tl.y, -10); + EXPECT_EQ(quad.tl.y, -11); EXPECT_EQ(quad.tr.x, -10); - EXPECT_EQ(quad.tr.y, -10); + EXPECT_EQ(quad.tr.y, -11); EXPECT_EQ(quad.bl.x, -30); - EXPECT_EQ(quad.bl.y, 30); + EXPECT_EQ(quad.bl.y, 31); EXPECT_EQ(quad.br.x, -10); - EXPECT_EQ(quad.br.y, 30); + EXPECT_EQ(quad.br.y, 31); } // height x textSize @@ -149,17 +155,19 @@ TEST(getIconQuads, style) { SymbolLayoutProperties::Evaluated layout; layout.get<TextSize>() = 12.0f; layout.get<IconTextFit>() = IconTextFitType::Height; + auto shapedIcon = PositionedIcon::shapeIcon(image, {{ -9.5f, -9.5f }}, SymbolAnchorType::Center, 0); + shapedIcon.fitIconToText(layout, shapedText, 12.0f); SymbolQuad quad = - getIconQuad(shapedIcon, layout, 12.0f, shapedText); + getIconQuad(shapedIcon, WritingModeType::Horizontal); EXPECT_EQ(quad.tl.x, -20); - EXPECT_EQ(quad.tl.y, -5); + EXPECT_EQ(quad.tl.y, -6); EXPECT_EQ(quad.tr.x, 0); - EXPECT_EQ(quad.tr.y, -5); + EXPECT_EQ(quad.tr.y, -6); EXPECT_EQ(quad.bl.x, -20); - EXPECT_EQ(quad.bl.y, 15); + EXPECT_EQ(quad.bl.y, 16); EXPECT_EQ(quad.br.x, 0); - EXPECT_EQ(quad.br.y, 15); + EXPECT_EQ(quad.br.y, 16); } // height x textSize + padding @@ -171,17 +179,19 @@ TEST(getIconQuads, style) { layout.get<IconTextFitPadding>()[1] = 10.0f; layout.get<IconTextFitPadding>()[2] = 5.0f; layout.get<IconTextFitPadding>()[3] = 10.0f; + auto shapedIcon = PositionedIcon::shapeIcon(image, {{ -9.5f, -9.5f }}, SymbolAnchorType::Center, 0); + shapedIcon.fitIconToText(layout, shapedText, 12.0f); SymbolQuad quad = - getIconQuad(shapedIcon, layout, 12.0f, shapedText); + getIconQuad(shapedIcon, WritingModeType::Horizontal); EXPECT_EQ(quad.tl.x, -30); - EXPECT_EQ(quad.tl.y, -10); + EXPECT_EQ(quad.tl.y, -11); EXPECT_EQ(quad.tr.x, 10); - EXPECT_EQ(quad.tr.y, -10); + EXPECT_EQ(quad.tr.y, -11); EXPECT_EQ(quad.bl.x, -30); - EXPECT_EQ(quad.bl.y, 20); + EXPECT_EQ(quad.bl.y, 21); EXPECT_EQ(quad.br.x, 10); - EXPECT_EQ(quad.br.y, 20); + EXPECT_EQ(quad.br.y, 21); } // both @@ -189,17 +199,19 @@ TEST(getIconQuads, style) { SymbolLayoutProperties::Evaluated layout; layout.get<TextSize>() = 24.0f; layout.get<IconTextFit>() = IconTextFitType::Both; + auto shapedIcon = PositionedIcon::shapeIcon(image, {{ -9.5f, -9.5f }}, SymbolAnchorType::Center, 0); + shapedIcon.fitIconToText(layout, shapedText, 24.0f); SymbolQuad quad = - getIconQuad(shapedIcon, layout, 24.0f, shapedText); - - EXPECT_EQ(quad.tl.x, -60); - EXPECT_EQ(quad.tl.y, -10); - EXPECT_EQ(quad.tr.x, 20); - EXPECT_EQ(quad.tr.y, -10); - EXPECT_EQ(quad.bl.x, -60); - EXPECT_EQ(quad.bl.y, 30); - EXPECT_EQ(quad.br.x, 20); - EXPECT_EQ(quad.br.y, 30); + getIconQuad(shapedIcon, WritingModeType::Horizontal); + + EXPECT_EQ(quad.tl.x, -61); + EXPECT_EQ(quad.tl.y, -11); + EXPECT_EQ(quad.tr.x, 21); + EXPECT_EQ(quad.tr.y, -11); + EXPECT_EQ(quad.bl.x, -61); + EXPECT_EQ(quad.bl.y, 31); + EXPECT_EQ(quad.br.x, 21); + EXPECT_EQ(quad.br.y, 31); } // both x textSize @@ -207,17 +219,19 @@ TEST(getIconQuads, style) { SymbolLayoutProperties::Evaluated layout; layout.get<TextSize>() = 12.0f; layout.get<IconTextFit>() = IconTextFitType::Both; + auto shapedIcon = PositionedIcon::shapeIcon(image, {{ -9.5f, -9.5f }}, SymbolAnchorType::Center, 0); + shapedIcon.fitIconToText(layout, shapedText, 12.0f); SymbolQuad quad = - getIconQuad(shapedIcon, layout, 12.0f, shapedText); - - EXPECT_EQ(quad.tl.x, -30); - EXPECT_EQ(quad.tl.y, -5); - EXPECT_EQ(quad.tr.x, 10); - EXPECT_EQ(quad.tr.y, -5); - EXPECT_EQ(quad.bl.x, -30); - EXPECT_EQ(quad.bl.y, 15); - EXPECT_EQ(quad.br.x, 10); - EXPECT_EQ(quad.br.y, 15); + getIconQuad(shapedIcon, WritingModeType::Horizontal); + + EXPECT_EQ(quad.tl.x, -31); + EXPECT_EQ(quad.tl.y, -6); + EXPECT_EQ(quad.tr.x, 11); + EXPECT_EQ(quad.tr.y, -6); + EXPECT_EQ(quad.bl.x, -31); + EXPECT_EQ(quad.bl.y, 16); + EXPECT_EQ(quad.br.x, 11); + EXPECT_EQ(quad.br.y, 16); } // both x textSize + padding @@ -229,17 +243,19 @@ TEST(getIconQuads, style) { layout.get<IconTextFitPadding>()[1] = 10.0f; layout.get<IconTextFitPadding>()[2] = 5.0f; layout.get<IconTextFitPadding>()[3] = 10.0f; + auto shapedIcon = PositionedIcon::shapeIcon(image, {{ -9.5f, -9.5f }}, SymbolAnchorType::Center, 0); + shapedIcon.fitIconToText(layout, shapedText, 12.0f); SymbolQuad quad = - getIconQuad(shapedIcon, layout, 12.0f, shapedText); - - EXPECT_EQ(quad.tl.x, -40); - EXPECT_EQ(quad.tl.y, -10); - EXPECT_EQ(quad.tr.x, 20); - EXPECT_EQ(quad.tr.y, -10); - EXPECT_EQ(quad.bl.x, -40); - EXPECT_EQ(quad.bl.y, 20); - EXPECT_EQ(quad.br.x, 20); - EXPECT_EQ(quad.br.y, 20); + getIconQuad(shapedIcon, WritingModeType::Horizontal); + + EXPECT_EQ(quad.tl.x, -41); + EXPECT_EQ(quad.tl.y, -11); + EXPECT_EQ(quad.tr.x, 21); + EXPECT_EQ(quad.tr.y, -11); + EXPECT_EQ(quad.bl.x, -41); + EXPECT_EQ(quad.bl.y, 21); + EXPECT_EQ(quad.br.x, 21); + EXPECT_EQ(quad.br.y, 21); } // both x textSize + padding t/r/b/l @@ -251,17 +267,19 @@ TEST(getIconQuads, style) { layout.get<IconTextFitPadding>()[1] = 5.0f; layout.get<IconTextFitPadding>()[2] = 10.0f; layout.get<IconTextFitPadding>()[3] = 15.0f; + auto shapedIcon = PositionedIcon::shapeIcon(image, {{ -9.5f, -9.5f }}, SymbolAnchorType::Center, 0); + shapedIcon.fitIconToText(layout, shapedText, 12.0f); SymbolQuad quad = - getIconQuad(shapedIcon, layout, 12.0f, shapedText); - - EXPECT_EQ(quad.tl.x, -45); - EXPECT_EQ(quad.tl.y, -5); - EXPECT_EQ(quad.tr.x, 15); - EXPECT_EQ(quad.tr.y, -5); - EXPECT_EQ(quad.bl.x, -45); - EXPECT_EQ(quad.bl.y, 25); - EXPECT_EQ(quad.br.x, 15); - EXPECT_EQ(quad.br.y, 25); + getIconQuad(shapedIcon, WritingModeType::Horizontal); + + EXPECT_EQ(quad.tl.x, -46); + EXPECT_EQ(quad.tl.y, -6); + EXPECT_EQ(quad.tr.x, 16); + EXPECT_EQ(quad.tr.y, -6); + EXPECT_EQ(quad.bl.x, -46); + EXPECT_EQ(quad.bl.y, 26); + EXPECT_EQ(quad.br.x, 16); + EXPECT_EQ(quad.br.y, 26); } } diff --git a/test/text/shaping.test.cpp b/test/text/shaping.test.cpp index 17c2fc96af..b22cd7da36 100644 --- a/test/text/shaping.test.cpp +++ b/test/text/shaping.test.cpp @@ -33,7 +33,7 @@ TEST(Shaping, ZWSP) { style::SymbolAnchorType::Center, style::TextJustifyType::Center, 0, // spacing - {0.0f, 0.0f}, // translate + {{0.0f, 0.0f}}, // translate WritingModeType::Horizontal, bidi, glyphs, diff --git a/test/util/peer.test.cpp b/test/util/peer.test.cpp deleted file mode 100644 index a808dd27d1..0000000000 --- a/test/util/peer.test.cpp +++ /dev/null @@ -1,189 +0,0 @@ -#include <mbgl/test/util.hpp> - -#include <mbgl/util/peer.hpp> - -using namespace mbgl::util; - -class TestType { -public: - TestType() { - str[0] = 'a'; - } - - //Detect moves - TestType(TestType&& t): i1(t.i1+1), i2(t.i2+2) { - str[0] = t.str[0]+1; - } - - TestType(const TestType&) = delete; - TestType& operator=(const TestType&) = delete; - - int i1 = 0; - int i2 = 1; - char str[256]; -}; - -bool IsStackAllocated (const peer& a, const void* obj1) { - auto a_ptr = (uintptr_t)(&a); - auto obj = (uintptr_t)(obj1); - return (obj >= a_ptr && obj < a_ptr + sizeof(peer)); -}; - -TEST(Peer, Empty) { - EXPECT_FALSE(peer().has_value()); -} - -TEST(Peer, BasicTypes) { - peer i = 3; - EXPECT_TRUE(i.has_value()); - EXPECT_TRUE(i.get<decltype(3)>() == 3); - - auto iValue = i.get<decltype(3)>(); - EXPECT_TRUE(iValue == 3); - - EXPECT_TRUE(peer(4).has_value()); - EXPECT_TRUE(peer(4).get<decltype(4)>() == 4); - - peer f = 6.2f; - EXPECT_TRUE(f.has_value()); - EXPECT_TRUE(f.get<decltype(6.2f)>() == 6.2f); - - const float fValue = f.get<decltype(6.2f)>(); - EXPECT_TRUE(fValue == 6.2f); - - EXPECT_TRUE(peer(1.0f).has_value()); - EXPECT_TRUE(peer(1.0f).get<decltype(1.0f)>() == 1.0f); - - peer c = 'z'; - EXPECT_TRUE(c.has_value()); - EXPECT_TRUE(c.get<decltype('z')>() == 'z'); - - EXPECT_TRUE(peer('z').has_value()); - EXPECT_TRUE(peer('z').get<decltype('z')>() == 'z'); -} - -TEST(Peer, BasicTypes_Move) { - peer i = 3; - EXPECT_TRUE(i.has_value()); - - peer f = 6.2f; - EXPECT_TRUE(f.has_value()); - - f = std::move(i); - EXPECT_FALSE(i.has_value()); - - EXPECT_TRUE(f.has_value()); - EXPECT_TRUE(f.get<decltype(3)>() == 3); -} - -TEST(Peer, SmallType) { - struct T { - T(int32_t* p_) : p(p_) { - (*p)++; - } - - T(T&& t) noexcept : p(t.p) { - (*p)++; - } - - ~T() { - (*p)--; - } - - T(const T&) = delete; - T& operator=(const T&) = delete; - - int32_t* p; - }; - - int32_t p = 0; - - { - peer u1 = peer(T(&p)); - EXPECT_EQ(p, 1); - - auto u2(std::move(u1)); - EXPECT_EQ(p, 1); - } - - EXPECT_EQ(p, 0); -} - -TEST(Peer, LargeType) { - TestType t1; - peer u1 = peer(std::move(t1)); - EXPECT_TRUE(u1.has_value()); - - //TestType should be moved into owning peer - EXPECT_EQ(u1.get<TestType>().i1, 1); - - auto u2(std::move(u1)); - EXPECT_FALSE(u1.has_value()); - - //TestType should not be moved when owning peer is moved; - EXPECT_EQ(u2.get<TestType>().i1, 1); - - // TestType should not be moved out of owning peer - auto& t2 = u2.get<TestType>(); - EXPECT_TRUE(u2.has_value()); - EXPECT_EQ(t2.i1, 1); -} - -TEST(Peer, Pointer) { - auto t1 = new TestType(); - - auto u1 = peer(std::move(t1)); - EXPECT_TRUE(u1.has_value()); - - //Only the pointer should be moved - TestType * t2 = u1.get<TestType *>(); - EXPECT_EQ(t2->i1, 0); - - peer u2(4); - std::swap(u2, u1); - - EXPECT_TRUE(u1.has_value()); - - EXPECT_TRUE(u2.has_value()); - - t2 = u2.get<TestType *>(); - EXPECT_EQ(t2->i1, 0); - delete t2; -} - - -TEST(Peer, UniquePtr) { - auto t1 = std::make_unique<TestType>(); - auto u1 = peer(std::move(t1)); - - EXPECT_EQ(t1.get(), nullptr); - EXPECT_TRUE(u1.has_value()); - - u1 = peer(); - EXPECT_FALSE(u1.has_value()); - - peer u2; - auto* t3 = new TestType(); - u2 = std::unique_ptr<TestType>(t3); - EXPECT_TRUE(u2.has_value()); -} - -TEST(Peer, SharedPtr) { - - std::shared_ptr<int> shared(new int(3)); - std::weak_ptr<int> weak = shared; - peer u1 = 0; - - EXPECT_EQ(weak.use_count(), 1); - peer u2 = shared; - EXPECT_EQ(weak.use_count(), 2); - - u1 = std::move(u2); - EXPECT_EQ(weak.use_count(), 2); - std::swap(u2, u1); - EXPECT_EQ(weak.use_count(), 2); - u2 = 0; - EXPECT_EQ(weak.use_count(), 1); - shared = nullptr; - EXPECT_EQ(weak.use_count(), 0); -} diff --git a/test/util/tile_cover.test.cpp b/test/util/tile_cover.test.cpp index e35e6e2e99..af9f0c4884 100644 --- a/test/util/tile_cover.test.cpp +++ b/test/util/tile_cover.test.cpp @@ -43,6 +43,20 @@ TEST(TileCover, Pitch) { util::tileCover(transform.getState(), 2)); } +TEST(TileCover, PitchIssue15442) { + Transform transform; + transform.resize({ 412, 691 }); + + transform.jumpTo(CameraOptions().withCenter(LatLng { 59.116898740996106, 91.565660781803615, }) + .withZoom(2.0551126748417214).withBearing(0.74963938256567264 * util::RAD2DEG) + .withPitch(1.0471975511965976 * util::RAD2DEG)); + + EXPECT_EQ((std::vector<UnwrappedTileID>{ + { 2, 3, 1 }, { 2, 2, 1 }, { 2, 3, 0 }, { 2, 2, 0 }, { 1, { 2, 0, 0 } }, { 1, { 2, 1, 0 } } + }), + util::tileCover(transform.getState(), 2)); +} + TEST(TileCover, PitchOverAllowedByContentInsets) { Transform transform; transform.resize({ 512, 512 }); |