summaryrefslogtreecommitdiff
path: root/test/sprite/sprite_parser.test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/sprite/sprite_parser.test.cpp')
-rw-r--r--test/sprite/sprite_parser.test.cpp306
1 files changed, 306 insertions, 0 deletions
diff --git a/test/sprite/sprite_parser.test.cpp b/test/sprite/sprite_parser.test.cpp
new file mode 100644
index 0000000000..8d32d081bf
--- /dev/null
+++ b/test/sprite/sprite_parser.test.cpp
@@ -0,0 +1,306 @@
+#include <mbgl/test/util.hpp>
+#include <mbgl/test/fixture_log_observer.hpp>
+
+#include <mbgl/sprite/sprite_parser.hpp>
+#include <mbgl/sprite/sprite_image.hpp>
+#include <mbgl/util/image.hpp>
+#include <mbgl/util/io.hpp>
+#include <mbgl/util/string.hpp>
+
+#include <algorithm>
+
+using namespace mbgl;
+
+namespace {
+
+auto readImage(const std::string& name) {
+ return decodeImage(util::read_file(name));
+}
+
+} // namespace
+
+TEST(Sprite, SpriteImageCreationInvalid) {
+ FixtureLog log;
+
+ const PremultipliedImage image_1x = decodeImage(util::read_file("test/fixtures/annotations/emerald.png"));
+
+ ASSERT_EQ(200u, image_1x.width);
+ ASSERT_EQ(299u, image_1x.height);
+
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 0, 16, 1, false)); // width == 0
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 16, 0, 1, false)); // height == 0
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, -1, 16, 1, false)); // width < 0
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 16, -1, 1, false)); // height < 0
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 1, 1, 0, false)); // ratio == 0
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 1, 1, -1, false)); // ratio < 0
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 1, 1, 23, false)); // ratio too large
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 2048, 16, 1, false)); // too wide
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 16, 1025, 1, false)); // too tall
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, -1, 0, 16, 16, 1, false)); // srcX < 0
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, -1, 16, 16, 1, false)); // srcY < 0
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, image_1x.width + 1, 16, 1, false)); // right edge out of bounds
+ ASSERT_EQ(nullptr, createSpriteImage(image_1x, 0, 0, 16, image_1x.height + 1, 1, false)); // bottom edge out of bounds
+
+ EXPECT_EQ(13u, log.count({
+ EventSeverity::Error,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics",
+ }));
+}
+
+TEST(Sprite, SpriteImageCreation1x) {
+ const PremultipliedImage image_1x = decodeImage(util::read_file("test/fixtures/annotations/emerald.png"));
+
+ ASSERT_EQ(200u, image_1x.width);
+ ASSERT_EQ(299u, image_1x.height);
+
+ { // "museum_icon":{"x":177,"y":187,"width":18,"height":18,"pixelRatio":1,"sdf":false}
+ const auto sprite = createSpriteImage(image_1x, 177, 187, 18, 18, 1, false);
+ ASSERT_TRUE(sprite.get());
+ EXPECT_EQ(18, sprite->getWidth());
+ EXPECT_EQ(18, sprite->getHeight());
+ EXPECT_EQ(18u, sprite->image.width);
+ EXPECT_EQ(18u, sprite->image.height);
+ EXPECT_EQ(1, sprite->pixelRatio);
+ EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteimagecreation1x-museum.png"),
+ sprite->image);
+ }
+}
+
+TEST(Sprite, SpriteImageCreation2x) {
+ const PremultipliedImage image_2x = decodeImage(util::read_file("test/fixtures/annotations/emerald@2x.png"));
+
+ // "museum_icon":{"x":354,"y":374,"width":36,"height":36,"pixelRatio":2,"sdf":false}
+ const auto sprite = createSpriteImage(image_2x, 354, 374, 36, 36, 2, false);
+ ASSERT_TRUE(sprite.get());
+ EXPECT_EQ(18, sprite->getWidth());
+ EXPECT_EQ(18, sprite->getHeight());
+ EXPECT_EQ(36u, sprite->image.width);
+ EXPECT_EQ(36u, sprite->image.height);
+ EXPECT_EQ(2, sprite->pixelRatio);
+ EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteimagecreation2x.png"),
+ sprite->image);
+}
+
+TEST(Sprite, SpriteImageCreation1_5x) {
+ const PremultipliedImage image_2x = decodeImage(util::read_file("test/fixtures/annotations/emerald@2x.png"));
+
+ // "museum_icon":{"x":354,"y":374,"width":36,"height":36,"pixelRatio":2,"sdf":false}
+ const auto sprite = createSpriteImage(image_2x, 354, 374, 36, 36, 1.5, false);
+ ASSERT_TRUE(sprite.get());
+ EXPECT_EQ(24, sprite->getWidth());
+ EXPECT_EQ(24, sprite->getHeight());
+ EXPECT_EQ(36u, sprite->image.width);
+ EXPECT_EQ(36u, sprite->image.height);
+ EXPECT_EQ(1.5, sprite->pixelRatio);
+ EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteimagecreation1_5x-museum.png"),
+ sprite->image);
+
+ // "hospital_icon":{"x":314,"y":518,"width":36,"height":36,"pixelRatio":2,"sdf":false}
+ const auto sprite2 = createSpriteImage(image_2x, 314, 518, 35, 35, 1.5, false);
+ ASSERT_TRUE(sprite2.get());
+ EXPECT_EQ(float(35 / 1.5), sprite2->getWidth());
+ EXPECT_EQ(float(35 / 1.5), sprite2->getHeight());
+ EXPECT_EQ(35u, sprite2->image.width);
+ EXPECT_EQ(35u, sprite2->image.height);
+ EXPECT_EQ(1.5, sprite2->pixelRatio);
+ EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteimagecreation1_5x-hospital.png"),
+ sprite2->image);
+}
+
+TEST(Sprite, SpriteParsing) {
+ const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
+ const auto json_1x = util::read_file("test/fixtures/annotations/emerald.json");
+
+ const auto images = parseSprite(image_1x, json_1x).get<Sprites>();
+
+ std::set<std::string> names;
+ std::transform(images.begin(), images.end(), std::inserter(names, names.begin()),
+ [](const auto& pair) { return pair.first; });
+
+ EXPECT_EQ(std::set<std::string>({ "airfield_icon",
+ "airport_icon",
+ "background",
+ "cemetery_icon",
+ "college_icon",
+ "default_1",
+ "default_2",
+ "default_3",
+ "default_4",
+ "default_5",
+ "default_6",
+ "default_marker",
+ "dlr",
+ "dlr.london-overground.london-underground.national-rail",
+ "dlr.london-underground",
+ "dlr.london-underground.national-rail",
+ "dlr.national-rail",
+ "dot",
+ "embassy_icon",
+ "fire-station_icon",
+ "generic-metro",
+ "generic-rail",
+ "generic_icon",
+ "golf_icon",
+ "government_icon",
+ "grass_pattern",
+ "harbor_icon",
+ "hospital_icon",
+ "hospital_striped",
+ "interstate_1",
+ "interstate_2",
+ "interstate_3",
+ "library_icon",
+ "london-overground",
+ "london-overground.london-underground",
+ "london-overground.london-underground.national-rail",
+ "london-overground.national-rail",
+ "london-underground",
+ "london-underground.national-rail",
+ "marker_icon",
+ "metro",
+ "metro.rer",
+ "monument_icon",
+ "moscow-metro",
+ "museum_icon",
+ "national-rail",
+ "oneway_motorway",
+ "oneway_road",
+ "park_icon",
+ "police_icon",
+ "post_icon",
+ "prison_icon",
+ "religious-christian_icon",
+ "religious-jewish_icon",
+ "religious-muslim_icon",
+ "rer",
+ "rer.transilien",
+ "s-bahn",
+ "s-bahn.u-bahn",
+ "sand_noise",
+ "school_icon",
+ "school_striped",
+ "secondary_marker",
+ "u-bahn",
+ "us_highway_1",
+ "us_highway_2",
+ "us_highway_3",
+ "us_state_1",
+ "us_state_2",
+ "us_state_3",
+ "washington-metro",
+ "wiener-linien",
+ "zoo_icon" }),
+ names);
+
+ {
+ auto sprite = images.find("generic-metro")->second;
+ EXPECT_EQ(18, sprite->getWidth());
+ EXPECT_EQ(18, sprite->getHeight());
+ EXPECT_EQ(18u, sprite->image.width);
+ EXPECT_EQ(18u, sprite->image.height);
+ EXPECT_EQ(1, sprite->pixelRatio);
+ EXPECT_EQ(readImage("test/fixtures/annotations/result-spriteparsing.png"), sprite->image);
+ }
+}
+
+TEST(Sprite, SpriteParsingInvalidJSON) {
+ const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
+ const auto json_1x = R"JSON({ "image": " })JSON";
+
+ const auto error = parseSprite(image_1x, json_1x).get<std::exception_ptr>();
+
+ EXPECT_EQ(util::toString(error),
+ std::string("Failed to parse JSON: Missing a closing quotation mark in string. at offset 14"));
+}
+
+TEST(Sprite, SpriteParsingEmptyImage) {
+ FixtureLog log;
+
+ const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
+ const auto json_1x = R"JSON({ "image": {} })JSON";
+
+ const auto images = parseSprite(image_1x, json_1x).get<Sprites>();
+ EXPECT_EQ(0u, images.size());
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Error,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics",
+ }));
+}
+
+TEST(Sprite, SpriteParsingSimpleWidthHeight) {
+ FixtureLog log;
+
+ const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
+ const auto json_1x = R"JSON({ "image": { "width": 32, "height": 32 } })JSON";
+
+ const auto images = parseSprite(image_1x, json_1x).get<Sprites>();
+ EXPECT_EQ(1u, images.size());
+}
+
+TEST(Sprite, SpriteParsingWidthTooBig) {
+ FixtureLog log;
+
+ const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
+ const auto json_1x = R"JSON({ "image": { "width": 65536, "height": 32 } })JSON";
+
+ const auto images = parseSprite(image_1x, json_1x).get<Sprites>();
+ EXPECT_EQ(0u, images.size());
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Warning,
+ Event::Sprite,
+ int64_t(-1),
+ "Value of 'width' must be an integer between 0 and 65535",
+ }));
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Error,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics",
+ }));
+}
+
+TEST(Sprite, SpriteParsingNegativeWidth) {
+ FixtureLog log;
+
+ const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
+ const auto json_1x = R"JSON({ "image": { "width": -1, "height": 32 } })JSON";
+
+ const auto images = parseSprite(image_1x, json_1x).get<Sprites>();
+ EXPECT_EQ(0u, images.size());
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Warning,
+ Event::Sprite,
+ int64_t(-1),
+ "Value of 'width' must be an integer between 0 and 65535",
+ }));
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Error,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics",
+ }));
+}
+
+TEST(Sprite, SpriteParsingNullRatio) {
+ FixtureLog log;
+
+ const auto image_1x = util::read_file("test/fixtures/annotations/emerald.png");
+ const auto json_1x = R"JSON({ "image": { "width": 32, "height": 32, "pixelRatio": 0 } })JSON";
+
+ const auto images = parseSprite(image_1x, json_1x).get<Sprites>();
+ EXPECT_EQ(0u, images.size());
+
+ EXPECT_EQ(1u, log.count({
+ EventSeverity::Error,
+ Event::Sprite,
+ int64_t(-1),
+ "Can't create sprite with invalid metrics",
+ }));
+}