From b8150fac822db4681a9eb7928804216183cb81c8 Mon Sep 17 00:00:00 2001 From: sehe Date: Sat, 20 Apr 2024 23:46:31 +0200 Subject: [PATCH 1/3] Restore broken test_basic_csr_directed_graph Works around invalidation of bundle property maps (see #373). The `#if SEHE_UNSTABLE_PROPERTY_MAPS_FIXED` section is there to signal my intent to investigate a generalized fix under that issue. It doubles as literate documentation of the need for the workaround, so it's less likely to bite the unwary. --- test/graphviz_test.cpp | 45 +++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/test/graphviz_test.cpp b/test/graphviz_test.cpp index 7769256ba..b40f3fb2c 100644 --- a/test/graphviz_test.cpp +++ b/test/graphviz_test.cpp @@ -17,6 +17,11 @@ #include #include #include +#include +#include + +// SEHE: Apparently unused or indirectly included +#include #include #include #include @@ -376,19 +381,40 @@ void test_comments_embedded_in_strings() BOOST_TEST((test_graph< graph_t >(gs, 2, mass_map_t(), weight_map_t()))); } -#if 0 // Currently broken - void test_basic_csr_directed_graph() { +void test_basic_csr_directed_graph() +{ weight_map_t weights; - insert( weights )(make_pair("a","b"),0.0) - (make_pair("c","d"),7.7)(make_pair("e","f"),6.66) - (make_pair("d","e"),0.5)(make_pair("e","a"),0.5); + insert(weights)(make_pair("a", "b"), 0.0)(make_pair("c", "d"), 7.7)( + make_pair("e", "f"), 6.66)(make_pair("d", "e"), 0.5)( + make_pair("e", "a"), 0.5); gs_t gs("digraph { a -> b eDge [weight = 7.7] " - "c -> d e-> f [weight = 6.66] " + "c -> d e-> f [weight = 6.66] " "d ->e->a [weight=.5]}"); - typedef compressed_sparse_row_graph graph_t; - BOOST_TEST((test_graph(gs,6,mass_map_t(),weights,"node_id","",&vertex_p_bundled::name,&vertex_p_bundled::color,&edge_p_bundled::weight))); - } + typedef compressed_sparse_row_graph< directedS, vertex_p_bundled, + edge_p_bundled, graph_p > + graph_t; + graph_t g; +#ifdef SEHE_UNSTABLE_PROPERTY_MAPS_FIXED // https://github.com/boostorg/graph/issues/373 + BOOST_TEST((test_graph(gs, g, 6, mass_map_t(), weights, "node_id", "", + get(&vertex_p_bundled::name, g), // SEHE FIXME + get(&vertex_p_bundled::color, g), // SEHE FIXME + get(&edge_p_bundled::weight, g)) // SEHE FIXME + )); +#else + BOOST_TEST((test_graph(gs, g, 6, mass_map_t(), weights, "node_id", + "", // + boost::make_function_property_map< graph_t::vertex_descriptor >( + [&g](graph_t::vertex_descriptor v) -> std::string& + { return g[v].name; }), + boost::make_function_property_map< graph_t::vertex_descriptor >( + [&g](graph_t::vertex_descriptor v) -> float& + { return g[v].color; }), + boost::make_function_property_map< graph_t::edge_descriptor >( + [&g](graph_t::edge_descriptor e) -> double& + { return g[e].weight; }) // + ))); #endif +} void test_basic_csr_directed_graph_ext_props() { @@ -433,5 +459,6 @@ int main() test_graph_property_test_3(); test_comments_embedded_in_strings(); test_basic_csr_directed_graph_ext_props(); + test_basic_csr_directed_graph(); return boost::report_errors(); } From 215439890690edfe9c5e7bf228d64b5571d12c22 Mon Sep 17 00:00:00 2001 From: sehe Date: Wed, 8 May 2024 14:39:27 +0200 Subject: [PATCH 2/3] Review comments --- test/graphviz_test.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/test/graphviz_test.cpp b/test/graphviz_test.cpp index b40f3fb2c..b57b4c2cf 100644 --- a/test/graphviz_test.cpp +++ b/test/graphviz_test.cpp @@ -20,7 +20,6 @@ #include #include -// SEHE: Apparently unused or indirectly included #include #include #include @@ -394,11 +393,11 @@ void test_basic_csr_directed_graph() edge_p_bundled, graph_p > graph_t; graph_t g; -#ifdef SEHE_UNSTABLE_PROPERTY_MAPS_FIXED // https://github.com/boostorg/graph/issues/373 +#ifdef UNSTABLE_PROPERTY_MAPS_FIXED // https://github.com/boostorg/graph/issues/373 BOOST_TEST((test_graph(gs, g, 6, mass_map_t(), weights, "node_id", "", - get(&vertex_p_bundled::name, g), // SEHE FIXME - get(&vertex_p_bundled::color, g), // SEHE FIXME - get(&edge_p_bundled::weight, g)) // SEHE FIXME + get(&vertex_p_bundled::name, g), // Warning, currently broken + get(&vertex_p_bundled::color, g), // Warning, currently broken + get(&edge_p_bundled::weight, g)) // Warning, currently broken )); #else BOOST_TEST((test_graph(gs, g, 6, mass_map_t(), weights, "node_id", From 8126d9798998988faf5eb3eb6c16cb880d6c97cd Mon Sep 17 00:00:00 2001 From: sehe Date: Sun, 21 Apr 2024 17:02:22 +0200 Subject: [PATCH 3/3] refactoring graphviz_test for review The code was mostly fine (except for unhygienic `using namespace` in places), but it was hard to see what was covered. I've seperated fixtures (sample input + expected output) and this will simplify invoking the ComparisonDriver (test_graph). --- test/graphviz_test.cpp | 550 ++++++++++++++++++++--------------------- 1 file changed, 274 insertions(+), 276 deletions(-) diff --git a/test/graphviz_test.cpp b/test/graphviz_test.cpp index b57b4c2cf..400732176 100644 --- a/test/graphviz_test.cpp +++ b/test/graphviz_test.cpp @@ -1,155 +1,192 @@ // Copyright 2004-5 Trustees of Indiana University +// // Use, modification and distribution is subject to the Boost Software // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // -// graphviz_test.cpp - Test cases for the Boost.Spirit implementation of a -// Graphviz DOT Language reader. +// graphviz_test.cpp - Test cases for the Graphviz DOT Language reader // // Author: Ronald Garcia #define BOOST_GRAPHVIZ_USE_ISTREAM -#include #include #include +#include #include #include #include #include - -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include #include -template -class close_to { -public: - explicit close_to(T f) - : f_(f) { } +typedef std::string node_t; +typedef std::pair< node_t, node_t > edge_t; - bool operator()(T l, T r) const { - return std::abs(l - r) <= - (std::max)(f_ * (std::max)(std::abs(l), std::abs(r)), T()); - } +typedef float Mass; +typedef double Weight; +typedef std::map< node_t, Mass > expected_masses_t; +typedef std::map< edge_t, Weight > expected_weights_t; +#define MAP_MASSES boost::assign::list_of< std::pair< node_t, Mass > > +#define MAP_WEIGHTS boost::assign::list_of< std::pair< edge_t, Weight > > -private: - T f_; +struct Fixture +{ + std::string graphviz_text; + size_t correct_num_vertices; + expected_masses_t masses; + expected_weights_t weights; }; -using namespace std; -using namespace boost; +namespace Samples +{ +namespace Directed +{ + static Fixture const basic { + "digraph { a node [mass = 7.7] c e [mass = 6.66] }", + 3, + MAP_MASSES("a", 0.0f)("c", 7.7f)("e", 6.66f), + expected_weights_t(), + }; + + static Fixture const basic_aliased { + "digraph { a node [mass = 7.7] \"a\" e [mass = 6.66] }", + 2, + MAP_MASSES("a", 0.0f)("e", 6.66f), + expected_weights_t(), + }; + + static Fixture const full { + "digraph { a -> b eDge [weight = 7.7] " + "c -> d e-> f [weight = 6.66] " + "d ->e->a [weight=.5]}", + 6, + expected_masses_t(), + MAP_WEIGHTS(edge_t("a", "b"), 0.0)(edge_t("c", "d"), 7.7)( + edge_t("e", "f"), 6.66)(edge_t("d", "e"), 0.5)( + edge_t("e", "a"), 0.5), + }; +} -using namespace boost::assign; +namespace Undirected +{ + static Fixture const basic { + "graph { a nodE [mass = 7.7] c e [mass =\\\n6.66] }", + 3, + MAP_MASSES("a", 0.0f)("c", 7.7f)("e", 6.66f), + expected_weights_t(), + }; + + static Fixture const full { + "graph { a -- b eDge [weight = 7.7] " + "c -- d e -- f [weight = 6.66] }", + 6, + expected_masses_t(), + MAP_WEIGHTS(edge_t("a", "b"), 0.0)(edge_t("c", "d"), 7.7)( + edge_t("e", "f"), 6.66), + }; +} -typedef std::string node_t; -typedef std::pair< node_t, node_t > edge_t; +Fixture const all_directed[] { + Directed::basic, + Directed::basic_aliased, + Directed::full, +}; +Fixture const all_undirected[] { + Undirected::basic, + Undirected::full, +}; +} // Samples -typedef std::map< node_t, float > mass_map_t; -typedef std::map< edge_t, double > weight_map_t; +namespace ComparisonDriver +{ +template < class T > class close_to +{ +public: + explicit close_to(T f) : f_(f) { assert(f >= 0); } -template < typename graph_t, typename NameMap, typename MassMap, - typename WeightMap > -bool test_graph(std::istream& dotfile, graph_t& graph, - std::size_t correct_num_vertices, mass_map_t const& masses, - weight_map_t const& weights, std::string const& node_id, - std::string const& g_name, NameMap name, MassMap mass, WeightMap weight); + bool operator()(T l, T r) const + { + using std::abs; + return abs(l - r) <= f_ * (std::max)(abs(l), abs(r)); + } -template < typename graph_t > -bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices, - mass_map_t const& masses, weight_map_t const& weights, - std::string const& node_id = "node_id", - std::string const& g_name = std::string()) -{ - graph_t g; - return test_graph(dotfile, g, correct_num_vertices, masses, weights, - node_id, g_name, get(vertex_name, g), get(vertex_color, g), - get(edge_weight, g)); -} +private: + T f_; +}; template < typename graph_t, typename NameMap, typename MassMap, typename WeightMap > -bool test_graph(std::istream& dotfile, graph_t& graph, - std::size_t correct_num_vertices, mass_map_t const& masses, - weight_map_t const& weights, std::string const& node_id, - std::string const& g_name, NameMap name, MassMap mass, WeightMap weight) +bool test_graph(std::string const& text, graph_t& graph, + std::size_t correct_num_vertices, expected_masses_t const& expected_masses, + expected_weights_t const& expected_weights, std::string const& node_id, + std::string const& g_name, NameMap name_map, MassMap mass_map, + WeightMap weight_map) { - // Construct a graph and set up the dynamic_property_maps. - dynamic_properties dp(ignore_other_properties); - dp.property(node_id, name); - dp.property("mass", mass); - dp.property("weight", weight); + boost::dynamic_properties dp(boost::ignore_other_properties); + dp.property(node_id, name_map); + dp.property("mass", mass_map); + dp.property("weight", weight_map); boost::ref_property_map< graph_t*, std::string > gname( - get_property(graph, graph_name)); + get_property(graph, boost::graph_name)); dp.property("name", gname); bool result = true; #ifdef BOOST_GRAPHVIZ_USE_ISTREAM - if (read_graphviz(dotfile, graph, dp, node_id)) - { + std::istringstream is(text); + if (read_graphviz(is, graph, dp, node_id)) #else - std::string data; - dotfile >> std::noskipws; - std::copy(std::istream_iterator< char >(dotfile), - std::istream_iterator< char >(), std::back_inserter(data)); - if (read_graphviz(data.begin(), data.end(), graph, dp, node_id)) - { + if (read_graphviz(text.begin(), text.end(), graph, dp, node_id)) #endif + { // check correct vertex count BOOST_TEST_EQ(num_vertices(graph), correct_num_vertices); // check masses - if (!masses.empty()) + if (!expected_masses.empty()) { // assume that all the masses have been set // for each vertex: - typename graph_traits< graph_t >::vertex_iterator i, j; + typename boost::graph_traits< graph_t >::vertex_iterator i, j; for (boost::tie(i, j) = vertices(graph); i != j; ++i) { - // - get its name - std::string node_name = get(name, *i); - // - get its mass - float node_mass = get(mass, *i); - BOOST_TEST(masses.find(node_name) != masses.end()); - float ref_mass = masses.find(node_name)->second; + std::string node_name = get(name_map, *i); + Mass node_mass = get(mass_map, *i); + BOOST_TEST( + expected_masses.find(node_name) != expected_masses.end()); + Mass ref_mass = expected_masses.find(node_name)->second; // - compare the mass to the result in the table - BOOST_TEST_WITH(node_mass, ref_mass, close_to(0.01f)); + BOOST_TEST_WITH(node_mass, ref_mass, close_to< Mass >(0.0001f)); } } // check weights - if (!weights.empty()) + if (!expected_weights.empty()) { // assume that all weights have been set /// for each edge: - typename graph_traits< graph_t >::edge_iterator i, j; + typename boost::graph_traits< graph_t >::edge_iterator i, j; for (boost::tie(i, j) = edges(graph); i != j; ++i) { // - get its name - std::pair< std::string, std::string > edge_name = make_pair( - get(name, source(*i, graph)), get(name, target(*i, graph))); + std::pair< std::string, std::string > edge_name + = make_pair(get(name_map, source(*i, graph)), + get(name_map, target(*i, graph))); // - get its weight - double edge_weight = get(weight, *i); - BOOST_TEST(weights.find(edge_name) != weights.end()); - double ref_weight = weights.find(edge_name)->second; - // - compare the weight to teh result in the table - BOOST_TEST_WITH(edge_weight, ref_weight, close_to(0.01)); + Weight edge_weight = get(weight_map, *i); + BOOST_TEST( + expected_weights.find(edge_name) != expected_weights.end()); + Weight ref_weight = expected_weights.find(edge_name)->second; + // - compare the weight to the result in the table + BOOST_TEST_WITH( + edge_weight, ref_weight, close_to< Weight >(0.000001)); } } if (!g_name.empty()) { - std::string parsed_name = get_property(graph, graph_name); + std::string parsed_name = get_property(graph, boost::graph_name); BOOST_TEST(parsed_name == g_name); } } @@ -162,236 +199,202 @@ bool test_graph(std::istream& dotfile, graph_t& graph, return result; } -// int test_main(int, char*[]) { +template < typename graph_t, typename NameMap, typename MassMap, + typename WeightMap > +bool test_graph(Fixture const& sample, graph_t& g, std::string const& node_id, + std::string const& g_name, NameMap name_map, MassMap mass_map, + WeightMap weight_map) +{ + return test_graph(sample.graphviz_text, g, sample.correct_num_vertices, + sample.masses, sample.weights, node_id, g_name, name_map, mass_map, + weight_map); +} -typedef istringstream gs_t; +template < typename graph_t > +bool test_graph(std::string const& dottext, std::size_t correct_num_vertices, + expected_masses_t const& masses, expected_weights_t const& weights, + std::string const& node_id = "node_id", std::string const& g_name = "") +{ + graph_t g; + return test_graph(dottext, g, correct_num_vertices, masses, weights, + node_id, g_name, get(boost::vertex_name, g), + get(boost::vertex_color, g), get(boost::edge_weight, g)); +} -typedef property< vertex_name_t, std::string, - property< vertex_color_t, float > > +template < typename graph_t > +bool test_graph(Fixture const& sample, std::string const& node_id = "node_id", + std::string const& g_name = "") +{ + graph_t g; + return test_graph(sample.graphviz_text, g, sample.correct_num_vertices, + sample.masses, sample.weights, node_id, g_name, // + get(boost::vertex_name, g), // + get(boost::vertex_color, g), // + get(boost::edge_weight, g) // + ); +} +} + +namespace Models +{ +typedef boost::property< boost::vertex_name_t, std::string, + boost::property< boost::vertex_color_t, Mass > > vertex_p; -typedef property< edge_weight_t, double > edge_p; -typedef property< graph_name_t, std::string > graph_p; +typedef boost::property< boost::edge_weight_t, Weight > edge_p; +typedef boost::property< boost::graph_name_t, std::string > graph_p; + +typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::undirectedS, + vertex_p, edge_p, graph_p > + Graph; +typedef boost::adjacency_list< boost::vecS, boost::vecS, boost::directedS, + vertex_p, edge_p, graph_p > + DiGraph; -struct vertex_p_bundled +typedef boost::adjacency_list< boost::setS, boost::vecS, boost::directedS, + vertex_p, edge_p, graph_p > + DiGraphNoParallel; + +struct VertexBundle { std::string name; - float color; + Mass mass; }; -struct edge_p_bundled +struct EdgeBundle { - double weight; + Weight weight; }; +typedef boost::compressed_sparse_row_graph< boost::directedS, VertexBundle, + EdgeBundle, graph_p > + CSRBundledGraph; +typedef boost::compressed_sparse_row_graph< boost::directedS, + boost::no_property, boost::no_property, graph_p > + CSRGraph; +} // Models + +// SEHE I intended for this to be able to pass __FUNCTION__ for reporting +// failures, but there seems to be no way to achieve this with lightweight_test +#define TEST_GRAPH(Model, ...) \ + BOOST_TEST((ComparisonDriver::test_graph< Model >(__VA_ARGS__))); + // Basic directed graph tests void test_basic_directed_graph_1() { - mass_map_t masses; - insert(masses)("a", 0.0f)("c", 7.7f)("e", 6.66f); - gs_t gs("digraph { a node [mass = 7.7] c e [mass = 6.66] }"); - typedef adjacency_list< vecS, vecS, directedS, vertex_p, edge_p, graph_p > - graph_t; - BOOST_TEST((test_graph< graph_t >(gs, 3, masses, weight_map_t()))); + TEST_GRAPH(Models::DiGraph, Samples::Directed::basic); } void test_basic_directed_graph_2() { - mass_map_t masses; - insert(masses)("a", 0.0f)("e", 6.66f); - gs_t gs("digraph { a node [mass = 7.7] \"a\" e [mass = 6.66] }"); - typedef adjacency_list< vecS, vecS, directedS, vertex_p, edge_p, graph_p > - graph_t; - BOOST_TEST((test_graph< graph_t >(gs, 2, masses, weight_map_t()))); + TEST_GRAPH(Models::DiGraph, Samples::Directed::basic_aliased); } void test_basic_directed_graph_3() { - weight_map_t weights; - insert(weights)(make_pair("a", "b"), 0.0)(make_pair("c", "d"), 7.7)( - make_pair("e", "f"), 6.66)(make_pair("d", "e"), 0.5)( - make_pair("e", "a"), 0.5); - gs_t gs("digraph { a -> b eDge [weight = 7.7] " - "c -> d e-> f [weight = 6.66] " - "d ->e->a [weight=.5]}"); - typedef adjacency_list< vecS, vecS, directedS, vertex_p, edge_p, graph_p > - graph_t; - BOOST_TEST((test_graph< graph_t >(gs, 6, mass_map_t(), weights))); + TEST_GRAPH(Models::DiGraph, Samples::Directed::full); } // undirected graph with alternate node_id property name void test_undirected_graph_alternate_node_id() { - mass_map_t masses; - insert(masses)("a", 0.0f)("c", 7.7f)("e", 6.66f); - gs_t gs("graph { a node [mass = 7.7] c e [mass = 6.66] }"); - typedef adjacency_list< vecS, vecS, undirectedS, vertex_p, edge_p, graph_p > - graph_t; - BOOST_TEST( - (test_graph< graph_t >(gs, 3, masses, weight_map_t(), "nodenames"))); + TEST_GRAPH(Models::Graph, Samples::Undirected::basic, "nodenames"); } // Basic undirected graph tests void test_basic_undirected_graph_1() { - mass_map_t masses; - insert(masses)("a", 0.0f)("c", 7.7f)("e", 6.66f); - gs_t gs("graph { a node [mass = 7.7] c e [mass =\\\n6.66] }"); - typedef adjacency_list< vecS, vecS, undirectedS, vertex_p, edge_p, graph_p > - graph_t; - BOOST_TEST((test_graph< graph_t >(gs, 3, masses, weight_map_t()))); + TEST_GRAPH(Models::Graph, Samples::Undirected::basic); } void test_basic_undirected_graph_2() { - weight_map_t weights; - insert(weights)(make_pair("a", "b"), 0.0)(make_pair("c", "d"), 7.7)( - make_pair("e", "f"), 6.66); - gs_t gs("graph { a -- b eDge [weight = 7.7] " - "c -- d e -- f [weight = 6.66] }"); - typedef adjacency_list< vecS, vecS, undirectedS, vertex_p, edge_p, graph_p > - graph_t; - BOOST_TEST((test_graph< graph_t >(gs, 6, mass_map_t(), weights))); + TEST_GRAPH(Models::Graph, Samples::Undirected::full); } // Mismatch directed graph test void test_mismatch_directed_graph() { - mass_map_t masses; - insert(masses)("a", 0.0f)("c", 7.7f)("e", 6.66f); - gs_t gs("graph { a nodE [mass = 7.7] c e [mass = 6.66] }"); - try - { - typedef adjacency_list< vecS, vecS, directedS, vertex_p, edge_p, - graph_p > - graph_t; - test_graph< graph_t >(gs, 3, masses, weight_map_t()); - BOOST_ERROR("Failed to throw boost::undirected_graph_error."); - } - catch (boost::undirected_graph_error&) - { - } - catch (boost::directed_graph_error&) - { - BOOST_ERROR("Threw boost::directed_graph_error, should have thrown " - "boost::undirected_graph_error."); - } + BOOST_TEST_THROWS(TEST_GRAPH(Models::DiGraph, Samples::Undirected::basic), + boost::undirected_graph_error); } // Mismatch undirected graph test void test_mismatch_undirected_graph() { - mass_map_t masses; - insert(masses)("a", 0.0f)("c", 7.7f)("e", 6.66f); - gs_t gs("digraph { a node [mass = 7.7] c e [mass = 6.66] }"); - try - { - typedef adjacency_list< vecS, vecS, undirectedS, vertex_p, edge_p, - graph_p > - graph_t; - test_graph< graph_t >(gs, 3, masses, weight_map_t()); - BOOST_ERROR("Failed to throw boost::directed_graph_error."); - } - catch (boost::directed_graph_error&) - { - } + BOOST_TEST_THROWS(TEST_GRAPH(Models::Graph, Samples::Directed::basic), + boost::directed_graph_error); } // Complain about parallel edges -void test_complain_about_parallel_edges() +void test_parallel_edges() { - weight_map_t weights; - insert(weights)(make_pair("a", "b"), 7.7); - gs_t gs("diGraph { a -> b [weight = 7.7] a -> b [weight = 7.7] }"); - try - { - typedef adjacency_list< setS, vecS, directedS, vertex_p, edge_p, - graph_p > - graph_t; - test_graph< graph_t >(gs, 2, mass_map_t(), weights); - BOOST_ERROR("Failed to throw boost::bad_parallel_edge."); - } - catch (boost::bad_parallel_edge&) - { - } -} - -// Handle parallel edges gracefully -void test_handle_parallel_edges_gracefully() -{ - weight_map_t weights; - insert(weights)(make_pair("a", "b"), 7.7); - gs_t gs("digraph { a -> b [weight = 7.7] a -> b [weight = 7.7] }"); - typedef adjacency_list< vecS, vecS, directedS, vertex_p, edge_p, graph_p > - graph_t; - BOOST_TEST((test_graph< graph_t >(gs, 2, mass_map_t(), weights))); + Fixture parallel { + "diGraph { a -> b [weight = 7.7] a -> b [weight = 7.7] }", + 2, + expected_masses_t(), + MAP_WEIGHTS(edge_t("a", "b"), 7.7), + }; + TEST_GRAPH(Models::DiGraph, parallel); + BOOST_TEST_THROWS(TEST_GRAPH(Models::DiGraphNoParallel, parallel), + boost::bad_parallel_edge); } // Graph Property Test 1 void test_graph_property_test_1() { - mass_map_t masses; - insert(masses)("a", 0.0f)("c", 0.0f)("e", 6.66f); - gs_t gs("digraph { graph [name=\"foo \\\"escaped\\\"\"] a c e [mass = " - "6.66] }"); - std::string graph_name("foo \"escaped\""); - typedef adjacency_list< vecS, vecS, directedS, vertex_p, edge_p, graph_p > - graph_t; - BOOST_TEST( - (test_graph< graph_t >(gs, 3, masses, weight_map_t(), "", graph_name))); + Fixture named { + "digraph { graph [name=\"foo \\\"escaped\\\"\"] a c e [mass = 6.66] " + "}", + 3, + MAP_MASSES("a", 0.0f)("c", 0.0f)("e", 6.66f), + expected_weights_t(), + }; + TEST_GRAPH(Models::DiGraph, named, "", "foo \"escaped\""); } // Graph Property Test 2 void test_graph_property_test_2() { - mass_map_t masses; - insert(masses)("a", 0.0f)("c", 0.0f)("e", 6.66f); - gs_t gs("digraph { name=\"fo\"+ \"\\\no\" a c e [mass = 6.66] }"); - std::string graph_name("foo"); - typedef adjacency_list< vecS, vecS, directedS, vertex_p, edge_p, graph_p > - graph_t; - BOOST_TEST( - (test_graph< graph_t >(gs, 3, masses, weight_map_t(), "", graph_name))); + Fixture named { + "digraph { name=\"fo\"+ \"\\\no\" a c e [mass = 6.66] }", + 3, + MAP_MASSES("a", 0.0f)("c", 0.0f)("e", 6.66f), + expected_weights_t(), + }; + TEST_GRAPH(Models::DiGraph, named, "", "foo"); // SEHE why not "foo\no"? } // Graph Property Test 3 (HTML) void test_graph_property_test_3() { - mass_map_t masses; - insert(masses)("a", 0.0f)("c", 0.0f)("e", 6.66f); std::string graph_name = "foo]]>bar\n
\nbaz"; - gs_t gs("digraph { name=" + graph_name + " a c e [mass = 6.66] }"); - typedef adjacency_list< vecS, vecS, directedS, vertex_p, edge_p, graph_p > - graph_t; - BOOST_TEST( - (test_graph< graph_t >(gs, 3, masses, weight_map_t(), "", graph_name))); + Fixture html_named { + "digraph { name=" + graph_name + " a c e [mass = 6.66] }", + 3, + MAP_MASSES("a", 0.0f)("c", 0.0f)("e", 6.66f), + expected_weights_t(), + }; + TEST_GRAPH(Models::DiGraph, html_named, "", graph_name); } // Comments embedded in strings void test_comments_embedded_in_strings() { - gs_t gs("digraph { " - "a0 [ label = \"//depot/path/to/file_14#4\" ];" - "a1 [ label = \"//depot/path/to/file_29#9\" ];" - "a0 -> a1 [ color=gray ];" - "}"); - typedef adjacency_list< vecS, vecS, directedS, vertex_p, edge_p, graph_p > - graph_t; - BOOST_TEST((test_graph< graph_t >(gs, 2, mass_map_t(), weight_map_t()))); + std::string gv("digraph { " + "a0 [ label = \"//depot/path/to/file_14#4\" ];" + "a1 [ label = \"//depot/path/to/file_29#9\" ];" + "a0 -> a1 [ color=gray ];" + "}"); + TEST_GRAPH( + Models::DiGraph, gv, 2, expected_masses_t(), expected_weights_t()); } void test_basic_csr_directed_graph() { - weight_map_t weights; - insert(weights)(make_pair("a", "b"), 0.0)(make_pair("c", "d"), 7.7)( - make_pair("e", "f"), 6.66)(make_pair("d", "e"), 0.5)( - make_pair("e", "a"), 0.5); - gs_t gs("digraph { a -> b eDge [weight = 7.7] " - "c -> d e-> f [weight = 6.66] " - "d ->e->a [weight=.5]}"); - typedef compressed_sparse_row_graph< directedS, vertex_p_bundled, - edge_p_bundled, graph_p > - graph_t; + auto sample = Samples::Directed::full; + + typedef Models::CSRBundledGraph graph_t; graph_t g; #ifdef UNSTABLE_PROPERTY_MAPS_FIXED // https://github.com/boostorg/graph/issues/373 BOOST_TEST((test_graph(gs, g, 6, mass_map_t(), weights, "node_id", "", @@ -400,45 +403,41 @@ void test_basic_csr_directed_graph() get(&edge_p_bundled::weight, g)) // Warning, currently broken )); #else - BOOST_TEST((test_graph(gs, g, 6, mass_map_t(), weights, "node_id", - "", // - boost::make_function_property_map< graph_t::vertex_descriptor >( - [&g](graph_t::vertex_descriptor v) -> std::string& - { return g[v].name; }), - boost::make_function_property_map< graph_t::vertex_descriptor >( - [&g](graph_t::vertex_descriptor v) -> float& - { return g[v].color; }), - boost::make_function_property_map< graph_t::edge_descriptor >( - [&g](graph_t::edge_descriptor e) -> double& - { return g[e].weight; }) // - ))); + typedef graph_t::vertex_descriptor V; + typedef graph_t::edge_descriptor E; + TEST_GRAPH(graph_t, sample, g, "node_id", "", // + boost::make_function_property_map< V >( + [&g](V v) -> std::string& { return g[v].name; }), + boost::make_function_property_map< V >( + [&g](V v) -> Mass& { return g[v].mass; }), + boost::make_function_property_map< E >( + [&g](E e) -> Weight& { return g[e].weight; }) // + ); #endif } void test_basic_csr_directed_graph_ext_props() { - weight_map_t weights; - insert(weights)(make_pair("a", "b"), 0.0)(make_pair("c", "d"), 7.7)( - make_pair("e", "f"), 6.66)(make_pair("d", "e"), 0.5)( - make_pair("e", "a"), 0.5); - gs_t gs("digraph { a -> b eDge [weight = 7.7] " - "c -> d e-> f [weight = 6.66] " - "d ->e->a [weight=.5]}"); - typedef compressed_sparse_row_graph< directedS, no_property, no_property, - graph_p > - graph_t; - graph_t g; - vector_property_map< std::string, - property_map< graph_t, vertex_index_t >::const_type > - vertex_name(get(vertex_index, g)); - vector_property_map< float, - property_map< graph_t, vertex_index_t >::const_type > - vertex_color(get(vertex_index, g)); - vector_property_map< double, - property_map< graph_t, edge_index_t >::const_type > - edge_weight(get(edge_index, g)); - BOOST_TEST((test_graph(gs, g, 6, mass_map_t(), weights, "node_id", "", - vertex_name, vertex_color, edge_weight))); + auto sample = Samples::Directed::full; + using Models::CSRGraph; + CSRGraph g; + boost::property_map< CSRGraph, boost::vertex_index_t >::const_type vidx + = get(boost::vertex_index, g); + boost::property_map< CSRGraph, boost::edge_index_t >::const_type eidx + = get(boost::edge_index, g); + + boost::vector_property_map< std::string, + boost::property_map< CSRGraph, boost::vertex_index_t >::const_type > + vertex_name(vidx); + boost::vector_property_map< Mass, + boost::property_map< CSRGraph, boost::vertex_index_t >::const_type > + vertex_mass(vidx); + boost::vector_property_map< Weight, + boost::property_map< CSRGraph, boost::edge_index_t >::const_type > + edge_weight(eidx); + + TEST_GRAPH(CSRGraph, sample, g, "node_id", "", vertex_name, vertex_mass, + edge_weight); } int main() @@ -451,8 +450,7 @@ int main() test_basic_undirected_graph_2(); test_mismatch_directed_graph(); test_mismatch_undirected_graph(); - test_complain_about_parallel_edges(); - test_handle_parallel_edges_gracefully(); + test_parallel_edges(); test_graph_property_test_1(); test_graph_property_test_2(); test_graph_property_test_3();