From 39ae91d4b95f32b23d4f4ae8f5fec02282a7d6a3 Mon Sep 17 00:00:00 2001 From: Magnus Jacobsson Date: Tue, 23 Aug 2022 10:26:24 +0200 Subject: [PATCH] tests: SVGAnalyzer: add support for retrieving the Graphviz edge penwidth --- tests/CMakeLists.txt | 1 + tests/graphviz_edge.cpp | 5 +++++ tests/graphviz_edge.h | 2 ++ tests/test_edge_penwidth.cpp | 30 ++++++++++++++++++++++++++++++ tests/test_utilities.cpp | 10 ++++++++++ tests/test_utilities.h | 7 +++++++ 6 files changed, 55 insertions(+) create mode 100644 tests/test_edge_penwidth.cpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index bf1341442..702ed9db3 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -78,6 +78,7 @@ endmacro() CREATE_TEST(AGraph_construction) CREATE_TEST(clusters) +CREATE_TEST(edge_penwidth) CREATE_TEST(engines) CREATE_TEST(GVContext_construction) CREATE_TEST(GVContext_render_svg) diff --git a/tests/graphviz_edge.cpp b/tests/graphviz_edge.cpp index 332b2504b..893580b9d 100644 --- a/tests/graphviz_edge.cpp +++ b/tests/graphviz_edge.cpp @@ -12,3 +12,8 @@ const SVG::SVGElement &GraphvizEdge::svg_g_element() const { SVG::SVGRect GraphvizEdge::bbox() const { return m_svg_g_element.bbox(); } SVG::SVGPoint GraphvizEdge::center() const { return bbox().center(); } + +double GraphvizEdge::penwidth() const { + return m_svg_g_element.attribute_from_subtree( + &SVG::SVGAttributes::stroke_width, &SVG::SVGElement::is_shape_element, 1); +} diff --git a/tests/graphviz_edge.h b/tests/graphviz_edge.h index eeeef8ba5..fdc0a0d9d 100644 --- a/tests/graphviz_edge.h +++ b/tests/graphviz_edge.h @@ -22,6 +22,8 @@ public: /// Return the 'edgeop' according to the DOT language specification. Note that /// this is not the same as the 'id' attribute of an edge. std::string_view edgeop() const; + /// Return the edge's `penwidth` attribute + double penwidth() const; /// Return a non-mutable reference to the SVG `g` element corresponding to the /// edge const SVG::SVGElement &svg_g_element() const; diff --git a/tests/test_edge_penwidth.cpp b/tests/test_edge_penwidth.cpp new file mode 100644 index 000000000..e37ce8c10 --- /dev/null +++ b/tests/test_edge_penwidth.cpp @@ -0,0 +1,30 @@ +#include +#include + +#include "svg_analyzer.h" +#include "test_utilities.h" + +TEST_CASE("Edge penwidth", + "Test that the Graphviz 'penwidth' attribute is used to set the " + "'stroke-width' attribute correctly for edges in the generated SVG") { + + const auto primitive_arrow_shape = + GENERATE(from_range(all_primitive_arrow_shapes)); + INFO(fmt::format("Primitive arrow shape: {}", primitive_arrow_shape)); + + const auto edge_penwidth = GENERATE(0.5, 1.0, 2.0); + INFO(fmt::format("Edge penwidth: {}", edge_penwidth)); + + auto dot = + fmt::format("digraph g1 {{edge [arrowhead={} penwidth={}]; a -> b}}", + primitive_arrow_shape, edge_penwidth); + + const auto engine = "dot"; + auto svg_analyzer = SVGAnalyzer::make_from_dot(dot, engine); + + for (const auto &graph : svg_analyzer.graphs()) { + for (const auto &edge : graph.edges()) { + CHECK(edge.penwidth() == edge_penwidth); + } + } +} diff --git a/tests/test_utilities.cpp b/tests/test_utilities.cpp index c9c9dbfc6..8f0c621f2 100644 --- a/tests/test_utilities.cpp +++ b/tests/test_utilities.cpp @@ -154,5 +154,15 @@ bool contains_ellipse_shape(std::string_view shape) { node_shapes_consisting_of_ellipse_and_polyline.contains(shape); } +const std::unordered_set primitive_polygon_arrow_shapes = { + "crow", "diamond", "inv", "normal", "vee"}; + +const std::unordered_set + primitive_polygon_and_polyline_arrow_shapes = {"box", "tee"}; + +const std::unordered_set all_primitive_arrow_shapes = { + "box", "crow", "curve", "diamond", "dot", "icurve", + "inv", "none", "normal", "tee", "vee"}; + const std::unordered_set all_rank_directions = {"TB", "BT", "LR", "RL"}; diff --git a/tests/test_utilities.h b/tests/test_utilities.h index bc78525e3..9bab6cac2 100644 --- a/tests/test_utilities.h +++ b/tests/test_utilities.h @@ -21,5 +21,12 @@ extern const std::unordered_set node_shapes_without_svg_shape; bool contains_ellipse_shape(std::string_view shape); bool contains_polygon_shape(std::string_view shape); +/// arrow shapes +extern const std::unordered_set + primitive_polygon_arrow_shapes; +extern const std::unordered_set + primitive_polygon_and_polyline_arrow_shapes; +extern const std::unordered_set all_primitive_arrow_shapes; + /// rank directions extern const std::unordered_set all_rank_directions; -- 2.40.0