#include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef WIN32 #include #endif using namespace mln; using namespace mln::style; TEST(Style, Properties) { util::RunLoop loop; auto fileSource = std::make_shared(); Style::Impl style{fileSource, 1.0, {Scheduler::GetBackground(), {}}}; style.loadJSON(R"STYLE({"name": "Test"})STYLE"); ASSERT_EQ("Test", style.getName()); style.loadJSON(R"STYLE({"center": [10, 20]})STYLE"); ASSERT_EQ("", style.getName()); ASSERT_EQ((LatLng{20, 10}), *style.getDefaultCamera().center); style.loadJSON(R"STYLE({"centerAltitude": 999})STYLE"); ASSERT_EQ("", style.getName()); ASSERT_EQ(999, *style.getDefaultCamera().centerAltitude); style.loadJSON(R"STYLE({"bearing": 24})STYLE"); ASSERT_EQ("", style.getName()); ASSERT_EQ(LatLng{}, *style.getDefaultCamera().center); ASSERT_EQ(24, *style.getDefaultCamera().bearing); style.loadJSON(R"STYLE({"zoom": 13.3})STYLE"); ASSERT_EQ("", style.getName()); ASSERT_EQ(13.3, *style.getDefaultCamera().zoom); style.loadJSON(R"STYLE({"pitch": 60})STYLE"); ASSERT_EQ("", style.getName()); ASSERT_EQ(60, *style.getDefaultCamera().pitch); style.loadJSON(R"STYLE({"roll": 99})STYLE"); ASSERT_EQ("", style.getName()); ASSERT_EQ(99, *style.getDefaultCamera().roll); style.loadJSON(R"STYLE({})STYLE"); ASSERT_EQ(Milliseconds(300), *style.getTransitionOptions().duration); ASSERT_EQ(std::optional{}, style.getTransitionOptions().delay); style.loadJSON(R"STYLE({"transition": { "duration": 500, "delay": 50 }})STYLE"); ASSERT_EQ(Milliseconds(500), *style.getTransitionOptions().duration); ASSERT_EQ(Milliseconds(50), *style.getTransitionOptions().delay); style.loadJSON(R"STYLE({"name": 23, "center": {}, "bearing": "north", "zoom": null, "pitch": "wide"})STYLE"); ASSERT_EQ("", style.getName()); ASSERT_EQ(LatLng{}, *style.getDefaultCamera().center); ASSERT_EQ(0, *style.getDefaultCamera().zoom); ASSERT_EQ(0, *style.getDefaultCamera().bearing); ASSERT_EQ(0, *style.getDefaultCamera().pitch); } TEST(Style, DuplicateSource) { util::RunLoop loop; auto fileSource = std::make_shared(); Style::Impl style{fileSource, 1.0, {Scheduler::GetBackground(), {}}}; style.loadJSON(util::read_file("test/fixtures/resources/style-unused-sources.json")); style.addSource(std::make_unique("sourceId", "mptiler://tiles/contours")); try { style.addSource(std::make_unique("sourceId", "mptiler://tiles/contours")); FAIL() << "Should not have been allowed to add a duplicate source id"; } catch (const std::runtime_error&) { // Expected } } TEST(Style, RemoveSourceInUse) { util::RunLoop loop; FixtureLog log; auto fileSource = std::make_shared(); Style::Impl style{fileSource, 1.0, {Scheduler::GetBackground(), {}}}; style.loadJSON(util::read_file("test/fixtures/resources/style-unused-sources.json")); style.addSource(std::make_unique("sourceId", "mptiler://tiles/contours")); style.addLayer(std::make_unique("layerId", "sourceId")); // Should not remove the source auto removed = style.removeSource("sourceId"); ASSERT_EQ(nullptr, removed); ASSERT_NE(nullptr, style.getSource("sourceId")); const FixtureLogObserver::LogMessage logMessage{ EventSeverity::Warning, Event::General, int64_t(-1), "Source 'sourceId' is in use, cannot remove", }; #if defined(WIN32) Sleep(1000); #endif EXPECT_EQ(log.count(logMessage), 1u); } TEST(Style, LoadJSONCancelsPendingLoadURL) { util::RunLoop loop; auto fileSource = std::make_shared<::StubFileSource>( ResourceOptions::Default(), ClientOptions(), StubFileSource::ResponseType::Manual); Style::Impl style{fileSource, 1.0, {Scheduler::GetBackground(), {}}}; // Start loading a URL (this will be pending) auto url = "http://some-url"; fileSource->styleResponse = [](const Resource&) { Response result; result.data = std::make_shared(util::read_file("test/fixtures/resources/style_vector.json")); return result; }; style.loadURL(url); // Before the URL request completes, load JSON directly const std::string json = R"STYLE({ "version": 8, "name": "Test Style", "sources": {}, "layers": [] })STYLE"; style.loadJSON(json); // The style should now be loaded with our JSON content ASSERT_EQ("Test Style", style.getName()); ASSERT_EQ("", style.getURL()); ASSERT_TRUE(style.getJSON().find("Test Style") != std::string::npos); fileSource->respondToAll(); // The style should still show our JSON content, not the URL content ASSERT_EQ("Test Style", style.getName()); ASSERT_NE("Streets", style.getName()); } TEST(Style, SourceImplsOrder) { util::RunLoop loop; auto fileSource = std::make_shared(); Style::Impl style{fileSource, 1.0, {Scheduler::GetBackground(), {}}}; style.addSource(std::make_unique("c", "mptiler://tiles/contours")); style.addSource(std::make_unique("b", "mptiler://tiles/contours")); style.addSource(std::make_unique("a", "mptiler://tiles/contours")); auto sources = style.getSources(); ASSERT_EQ(3u, sources.size()); EXPECT_EQ("c", sources[0]->getID()); EXPECT_EQ("b", sources[1]->getID()); EXPECT_EQ("a", sources[2]->getID()); const auto& sourceImpls = *style.getSourceImpls(); ASSERT_EQ(3u, sourceImpls.size()); EXPECT_EQ("a", sourceImpls[0]->id); EXPECT_EQ("b", sourceImpls[1]->id); EXPECT_EQ("c", sourceImpls[2]->id); } TEST(Style, AddRemoveImage) { util::RunLoop loop; auto fileSource = std::make_shared(); Style::Impl style{fileSource, 1.0, {Scheduler::GetBackground(), {}}}; style.addImage(std::make_unique("one", PremultipliedImage({16, 16}), 2.0f)); style.addImage(std::make_unique("two", PremultipliedImage({16, 16}), 2.0f)); style.addImage(std::make_unique("three", PremultipliedImage({16, 16}), 2.0f)); style.removeImage("one"); style.removeImage("two"); EXPECT_TRUE(!!style.getImage("three")); EXPECT_FALSE(!!style.getImage("two")); EXPECT_FALSE(!!style.getImage("four")); } TEST(Style, AddRemoveRemoveImage) { // regression test for https://github.com/mapbox/mapbox-gl-native/pull/16391 util::RunLoop loop; auto fileSource = std::make_shared(); Style::Impl style{fileSource, 1.0, {Scheduler::GetBackground(), {}}}; style.addImage(std::make_unique("one", PremultipliedImage({16, 16}), 2.0f)); style.addImage(std::make_unique("two", PremultipliedImage({16, 16}), 2.0f)); style.addImage(std::make_unique("three", PremultipliedImage({16, 16}), 2.0f)); style.removeImage("one"); style.removeImage("two"); style.removeImage("two"); EXPECT_TRUE(!!style.getImage("three")); EXPECT_FALSE(!!style.getImage("two")); EXPECT_FALSE(!!style.getImage("four")); }