From ad9a82b113ff9cfae827c34b9cdd03fd1f7c66d0 Mon Sep 17 00:00:00 2001 From: Magnus Jacobsson Date: Thu, 21 Jul 2022 13:16:41 +0200 Subject: [PATCH] tests: add new test_svg_analyzer test skeleton Upcoming commits will add functionality to the SVG analyzer and extend this test. --- tests/CMakeLists.txt | 2 + tests/test_svg_analyzer.cpp | 106 ++++++++++++++++++++++++ tests/test_utilities.cpp | 155 ++++++++++++++++++++++++++++++++++++ tests/test_utilities.h | 22 +++++ 4 files changed, 285 insertions(+) create mode 100644 tests/test_svg_analyzer.cpp create mode 100644 tests/test_utilities.cpp create mode 100644 tests/test_utilities.h diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2ac89859c..0a1b956c7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -12,6 +12,7 @@ enable_testing() # separate test can be as small as possible add_library(test_common SHARED catch2_main.cpp + test_utilities.cpp svgpp_context.cpp svgpp_context.h svgpp_document_traverser.cpp @@ -77,3 +78,4 @@ CREATE_TEST(neatopack) CREATE_TEST(simple) CREATE_TEST(subgraph_layout) CREATE_TEST(subgraphs) +CREATE_TEST(svg_analyzer) diff --git a/tests/test_svg_analyzer.cpp b/tests/test_svg_analyzer.cpp new file mode 100644 index 000000000..33e5f7211 --- /dev/null +++ b/tests/test_svg_analyzer.cpp @@ -0,0 +1,106 @@ +#include +#include + +#include "svg_analyzer.h" +#include +#include +#include +#include + +#include "test_utilities.h" + +TEST_CASE( + "SvgAnalyzer", + "The SvgAnalyzer parses an SVG produced by Graphviz to an internal data " + "structure and supports retrieval of information about that graph") { + + const auto shape_char_ptr = GENERATE(from_range(all_node_shapes)); + const std::string shape{shape_char_ptr}; + INFO(fmt::format("Shape: {}", shape)); + + auto dot = fmt::format("digraph g1 {{node [shape={}]; a -> b}}", shape); + + auto g = CGraph::AGraph{dot}; + + const auto demand_loading = false; + auto gvc = GVC::GVContext(lt_preloaded_symbols, demand_loading); + + const auto layout = GVC::GVLayout(std::move(gvc), std::move(g), "dot"); + + const auto result = layout.render("svg"); + const std::string original_svg{result.string_view()}; + SVGAnalyzer svgAnalyzer{result.c_str()}; + + const std::size_t expected_num_graphs = 1; + const std::size_t expected_num_nodes = 2; + const std::size_t expected_num_edges = 1; + + { + const std::size_t expected_num_svgs = expected_num_graphs; + const std::size_t expected_num_groups = + expected_num_graphs + expected_num_nodes + expected_num_edges; + const std::size_t expected_num_circles = 0; + const std::size_t expected_num_ellipses = [&]() { + if (shape == "doublecircle") { + return expected_num_nodes * 2; + } else if (contains_ellipse_shape(shape)) { + return expected_num_nodes; + } else { + return 0UL; + } + }(); + const std::size_t expected_num_lines = 0; + const std::size_t expected_num_paths = + expected_num_edges + (shape == "cylinder" ? expected_num_nodes * 2 : 0); + const std::size_t expected_num_polygons = + expected_num_graphs + expected_num_edges + [&]() { + if (shape == "noverhang") { + return expected_num_nodes * 4; + } else if (shape == "tripleoctagon") { + return expected_num_nodes * 3; + } else if (shape == "doubleoctagon" || shape == "fivepoverhang" || + shape == "threepoverhang" || shape == "assembly") { + return expected_num_nodes * 2; + } else if (contains_polygon_shape(shape)) { + return expected_num_nodes; + } else { + return 0UL; + } + }(); + const std::size_t expected_num_polylines = [&]() { + if (shape == "Mdiamond" || shape == "Msquare") { + return expected_num_nodes * 4; + } else if (shape == "box3d" || shape == "signature" || + shape == "insulator" || shape == "ribosite" || + shape == "rnastab") { + return expected_num_nodes * 3; + } else if (shape == "Mcircle" || shape == "note" || + shape == "component" || shape == "restrictionsite" || + shape == "noverhang" || shape == "assembly" || + shape == "proteasesite" || shape == "proteinstab") { + return expected_num_nodes * 2; + } else if (shape == "underline" || shape == "tab" || + shape == "promoter" || shape == "terminator" || + shape == "utr" || shape == "primersite" || + shape == "fivepoverhang" || shape == "threepoverhang") { + return expected_num_nodes; + } else { + return 0UL; + } + }(); + const std::size_t expected_num_rects = 0; + const std::size_t expected_num_titles = + expected_num_graphs + expected_num_nodes + expected_num_edges; + + CHECK(svgAnalyzer.num_svgs() == expected_num_svgs); + CHECK(svgAnalyzer.num_groups() == expected_num_groups); + CHECK(svgAnalyzer.num_circles() == expected_num_circles); + CHECK(svgAnalyzer.num_ellipses() == expected_num_ellipses); + CHECK(svgAnalyzer.num_lines() == expected_num_lines); + CHECK(svgAnalyzer.num_paths() == expected_num_paths); + CHECK(svgAnalyzer.num_polygons() == expected_num_polygons); + CHECK(svgAnalyzer.num_polylines() == expected_num_polylines); + CHECK(svgAnalyzer.num_rects() == expected_num_rects); + CHECK(svgAnalyzer.num_titles() == expected_num_titles); + } +} diff --git a/tests/test_utilities.cpp b/tests/test_utilities.cpp new file mode 100644 index 000000000..a155f4648 --- /dev/null +++ b/tests/test_utilities.cpp @@ -0,0 +1,155 @@ +#include +#include + +#include "test_utilities.h" + +const std::unordered_set node_shapes_consisting_of_ellipse = { + "ellipse", // + "oval", // + "circle", // + "doublecircle", // + "point", // +}; + +const std::unordered_set + node_shapes_consisting_of_ellipse_and_polyline = { + "Mcircle", // +}; + +const std::unordered_set node_shapes_consisting_of_path = { + "cylinder", // +}; + +const std::unordered_set node_shapes_consisting_of_polygon = { + "box", // + "polygon", // + "egg", // + "triangle", // + "diamond", // + "trapezium", // + "parallelogram", // + "house", // + "pentagon", // + "hexagon", // + "septagon", // + "octagon", // + "doubleoctagon", // + "tripleoctagon", // + "invtriangle", // + "invtrapezium", // + "invhouse", // + "rect", // + "rectangle", // + "square", // + "star", // + "cds", // + "rpromoter", // + "rarrow", // + "larrow", // + "lpromoter", // + "folder", // +}; + +const std::unordered_set + node_shapes_consisting_of_polygon_and_polyline = { + "Mdiamond", // + "Msquare", // + "underline", // + "note", // + "tab", // + "box3d", // + "component", // + "promoter", // + "terminator", // + "utr", // + "primersite", // + "restrictionsite", // + "fivepoverhang", // + "threepoverhang", // + "noverhang", // + "assembly", // + "signature", // + "insulator", // + "ribosite", // + "rnastab", // + "proteasesite", // + "proteinstab", // +}; + +const std::unordered_set node_shapes_without_svg_shape = { + "plaintext", // + "plain", // + "none", // +}; + +const std::unordered_set all_node_shapes = { + "box", // + "polygon", // + "ellipse", // + "oval", // + "circle", // + "point", // + "egg", // + "triangle", // + "plaintext", // + "plain", // + "diamond", // + "trapezium", // + "parallelogram", // + "house", // + "pentagon", // + "hexagon", // + "septagon", // + "octagon", // + "doublecircle", // + "doubleoctagon", // + "tripleoctagon", // + "invtriangle", // + "invtrapezium", // + "invhouse", // + "Mdiamond", // + "Msquare", // + "Mcircle", // + "rect", // + "rectangle", // + "square", // + "star", // + "none", // + "underline", // + "cylinder", // + "note", // + "tab", // + "folder", // + "box3d", // + "component", // + "promoter", // + "cds", // + "terminator", // + "utr", // + "primersite", // + "restrictionsite", // + "fivepoverhang", // + "threepoverhang", // + "noverhang", // + "assembly", // + "signature", // + "insulator", // + "ribosite", // + "rnastab", // + "proteasesite", // + "proteinstab", // + "rpromoter", // + "rarrow", // + "larrow", // + "lpromoter" // +}; + +bool contains_polygon_shape(std::string_view shape) { + return node_shapes_consisting_of_polygon.contains(shape) || + node_shapes_consisting_of_polygon_and_polyline.contains(shape); +} + +bool contains_ellipse_shape(std::string_view shape) { + return node_shapes_consisting_of_ellipse.contains(shape) || + node_shapes_consisting_of_ellipse_and_polyline.contains(shape); +} diff --git a/tests/test_utilities.h b/tests/test_utilities.h new file mode 100644 index 000000000..7cbd0de2f --- /dev/null +++ b/tests/test_utilities.h @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +/// node shapes + +extern const std::unordered_set all_node_shapes; +extern const std::unordered_set + node_shapes_consisting_of_ellipse; +extern const std::unordered_set + node_shapes_consisting_of_ellipse_and_polyline; +extern const std::unordered_set + node_shapes_consisting_of_path; +extern const std::unordered_set + node_shapes_consisting_of_polygon; +extern const std::unordered_set + node_shapes_consisting_of_polygon_and_polyline; +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); -- 2.50.1