From d29aeb2ddb4d8ce777f1e15c65121f15af21945e Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Sun, 11 Dec 2022 10:13:26 +0000 Subject: [PATCH] SVG parser unit test - add attribute comparison framework + test data --- test/data | 2 +- test/unit/svg/svg_parser_test.cpp | 164 ++++++++++++++++++------------ 2 files changed, 101 insertions(+), 65 deletions(-) diff --git a/test/data b/test/data index 5206bfd11..95789262d 160000 --- a/test/data +++ b/test/data @@ -1 +1 @@ -Subproject commit 5206bfd11f122bc8fe81519d39768b30108da03a +Subproject commit 95789262db507872c5976756777ee4cf64457ea5 diff --git a/test/unit/svg/svg_parser_test.cpp b/test/unit/svg/svg_parser_test.cpp index 6e05db806..c50d80380 100644 --- a/test/unit/svg/svg_parser_test.cpp +++ b/test/unit/svg/svg_parser_test.cpp @@ -30,59 +30,124 @@ #include #include #include +#include #include "util.hpp" #include #include +#include +#include +// boost +#include +#include +#include namespace // internal { -template + +std::ostream& operator<<(std::ostream& os, agg::rgba8 const& c) +{ + os << mapnik::color{c.r, c.g, c.b, c.a}; + return os; +} + +std::ostream& operator<<(std::ostream& os, mapnik::gradient const& gr) +{ + double cx, cy, fx, fy, r; + gr.get_control_points(fx, fy, cx, cy, r); + + os << "\n"; + for (auto const& stop : gr.get_stop_array()) + { + os << " (stop) << "\" color=\"" << std::get<1>(stop) << "\"/>\n"; + } + + os << "\n"; + + return os; +} + +std::ostream& operator<<(std::ostream& os, agg::trans_affine const& tr) +{ + os << "matrix(" << tr.sx << "," << tr.shy << "," + << tr.shx << "," << tr.sy << "," << tr.tx << "," + << tr.ty << ")"; + return os; +} + struct group_attribute_visitor { - group_attribute_visitor(int& index) - : index_(index) + group_attribute_visitor(std::stringstream& ss, unsigned padding) + : ss_(ss), padding_(padding) {} void operator()(mapnik::svg::group const& g) const { - std::cerr << " " << std::endl; + padding_ += 2; + //ss_ << "padding=>" << padding_ << std::endl; + std::string pad(padding_, ' '); + ss_ << pad << "" << std::endl; for (auto const& elem : g.elements) { - mapbox::util::apply_visitor(group_attribute_visitor(index_), elem); + mapbox::util::apply_visitor(group_attribute_visitor(ss_, padding_), elem); } - std::cerr << " " << std::endl; + ss_ << pad << "" << std::endl; + padding_ -= 2; } void operator()(mapnik::svg::path_attributes const& attr) const { - if (index_++ == MAX) - { - std::cerr << " " << std::endl; - std::cerr << " " << attr.opacity << "" << std::endl; - // std::cerr << " " << attr.fill_color << "" << std::endl; - std::cerr << " " << attr.fill_opacity << "" << std::endl; - // std::cerr << " " << attr.stroke_color << "" << std::endl; - std::cerr << " " << attr.stroke_width << "" << std::endl; - std::cerr << " " << attr.stroke_opacity << "" << std::endl; - std::cerr << " " << std::endl; - } - else - { - std::cerr << " " << std::endl; - } + padding_ += 2; + std::string pad(padding_, ' '); + ss_ << pad << "" << std::endl; + ss_ << pad << attr.transform << std::endl; + if (!attr.fill_gradient.get_stop_array().empty()) + ss_ << pad << attr.fill_gradient; + if (!attr.stroke_gradient.get_stop_array().empty()) + ss_ << pad << attr.stroke_gradient; + + ss_ << pad << " " << attr.opacity << "" << std::endl; + ss_ << pad << " " << attr.fill_color << "" << std::endl; + ss_ << pad << " " << attr.fill_opacity << "" << std::endl; + ss_ << pad << " " << attr.stroke_color << "" << std::endl; + ss_ << pad << " " << attr.stroke_width << "" << std::endl; + ss_ << pad << " " << attr.stroke_opacity << "" << std::endl; + ss_ << pad << "" << std::endl; + padding_ -=2; } - int& index_; + std::stringstream& ss_; + mutable unsigned padding_; }; -template -void group_attribute_printer(mapnik::svg::group const& g) +bool check_equal_attributes(std::string const& svg_file, mapnik::svg::group const& g) { - std::cerr << "" << std::endl; - int index = 0; + unsigned padding = 0; + std::stringstream ss; + ss << "" << std::endl; for (auto const& elem : g.elements) { - mapbox::util::apply_visitor(group_attribute_visitor(index), elem); + mapbox::util::apply_visitor(group_attribute_visitor(ss, padding), elem); + } + ss << "" << std::endl; + + std::string well_known_xml = svg_file + ".xml"; + if (!mapnik::util::exists(well_known_xml)) + { + std::cerr << "Well-known-xml-filename:" << well_known_xml << std::endl; + std::cerr << ss.str() << std::endl; + return false; + } + else + { + boost::property_tree::ptree t0, t1; + boost::property_tree::read_xml(well_known_xml, t0, boost::property_tree::xml_parser::trim_whitespace); + boost::property_tree::read_xml(ss, t1, boost::property_tree::xml_parser::trim_whitespace); + + if (t0 != t1) + { + std::cerr << ss.str() << std::endl; + } + return (t0 == t1); } - std::cerr << "" << std::endl; } struct test_parser @@ -312,11 +377,9 @@ TEST_CASE("SVG parser") auto const& group_attrs = storage->svg_group(); agg::line_cap_e expected_cap(agg::square_cap); - REQUIRE(group_attrs.elements.size() == 1); - // FIXME - // REQUIRE(attrs[0].line_cap == expected_cap); - group_attribute_printer<0>(group_attrs); + REQUIRE(check_equal_attributes(svg_name, group_attrs)); + double x, y; unsigned cmd; std::vector> vec; @@ -480,9 +543,7 @@ TEST_CASE("SVG parser") auto const& group_attrs = storage->svg_group(); agg::line_join_e expected_join(agg::bevel_join); - REQUIRE(group_attrs.elements.size() == 1); - // FIXME - // REQUIRE(attrs[0].line_join == expected_join); + REQUIRE(check_equal_attributes(svg_name, group_attrs)); } SECTION("SVG ") @@ -717,10 +778,7 @@ TEST_CASE("SVG parser") auto const& group_attrs = storage->svg_group(); - // REQUIRE(group_attrs.elements.size() == 3); - // FIXME - // REQUIRE(attrs[1].fill_gradient == attrs[2].fill_gradient); - + REQUIRE(check_equal_attributes(svg_name, group_attrs)); mapnik::svg::svg_path_adapter path(stl_storage); double x, y; unsigned cmd; @@ -768,13 +826,7 @@ TEST_CASE("SVG parser") REQUIRE(storage); auto const& group_attrs = storage->svg_group(); - // FIXME - // REQUIRE(attrs.size() == 3); - // REQUIRE(attrs[1].fill_gradient == attrs[2].fill_gradient); - // REQUIRE(attrs[1].fill_gradient.get_gradient_type() == mapnik::RADIAL); - agg::trans_affine transform; - transform *= agg::trans_affine_translation(240, 155); - // REQUIRE(attrs[1].fill_gradient.get_transform() == transform); + REQUIRE(check_equal_attributes(svg_name, group_attrs)); } SECTION("SVG with xlink:href") @@ -790,11 +842,7 @@ TEST_CASE("SVG parser") REQUIRE(storage); auto const& group_attrs = storage->svg_group(); - // FIXME - // REQUIRE(attrs.elements.size() == 2); - // REQUIRE(attrs[0].fill_gradient.get_gradient_type() == mapnik::LINEAR); - // REQUIRE(attrs[1].fill_gradient.get_gradient_type() == mapnik::LINEAR); - // REQUIRE(attrs[1].fill_gradient.has_stop()); + REQUIRE(check_equal_attributes(svg_name, group_attrs)); } SECTION("SVG with radial percents") @@ -808,19 +856,7 @@ TEST_CASE("SVG parser") REQUIRE(bbox == mapnik::box2d(0, 0, 200, 200)); auto storage = svg.get_data(); REQUIRE(storage); - - double x1, x2, y1, y2, r; - // FIXME - // auto const& attrs = storage->attributes(); - // REQUIRE(attrs.size() == 1); - // REQUIRE(attrs[0].fill_gradient.get_gradient_type() == mapnik::RADIAL); - // REQUIRE(attrs[0].fill_gradient.has_stop()); - // attrs[0].fill_gradient.get_control_points(x1, y1, x2, y2, r); - // REQUIRE(x1 == 0); - // REQUIRE(y1 == 0.25); - // REQUIRE(x2 == 0.10); - // REQUIRE(y2 == 0.10); - // REQUIRE(r == 0.75); + REQUIRE(check_equal_attributes(svg_name, storage->svg_group())); } SECTION("SVG ")