14namespace sequoia::testing
16 namespace directed_graph{
20 nodew = graph_description::end,
96 node_0uuu_1uuu_0vvv_1vvv_0www_1www_0xxx_1xxx_0yyy_1yyy_0zzz_1zzz_node,
102 node_0zzz_1zzz_0yyy_1yyy_0xxx_1xxx_0www_1www_0vvv_1vvv_0uuu_1uuu_node
110 class EdgeStorageConfig,
111 class NodeWeightStorage
117 using edge_t =
typename graph_t::edge_init_type;
118 using node_weight_type =
typename graph_t::node_weight_type;
119 using edges_equivalent_t = std::initializer_list<std::initializer_list<edge_t>>;
124 auto trg{make_weighted_transition_graph(t)};
127 [&t](std::string_view description,
const graph_t& obtained,
const graph_t& prediction,
const graph_t& parent, std::size_t host, std::size_t target) {
128 t.check(equality, {description, no_source_location}, obtained, prediction);
129 if(host != target) t.check_semantics({description, no_source_location}, prediction, parent);
136 static void check_initialization_exceptions(
regular_test& t)
138 using nodes = std::initializer_list<node_weight_type>;
140 t.check_exception_thrown<std::out_of_range>(
"Zeroth partial index of edge out of range", [](){
return graph_t{{edge_t{1, 1.0}}}; });
141 t.check_exception_thrown<std::out_of_range>(
"First partial index of edge out of range", [](){
return graph_t{{edge_t{0, 1.0}, edge_t{1, 1.0}}}; });
142 t.check_exception_thrown<std::out_of_range>(
"First partial index of edge out of range", [](){
return graph_t{{edge_t{0, 1.0}, edge_t{2, 1.0}}, {}}; });
143 t.check_exception_thrown<std::out_of_range>(
"Zeroth partial index of node 1's edge out of range", [](){
return graph_t{{edge_t{0, 1.0}, edge_t{1, 1.0}}, {edge_t{2, 1.0}}}; });
145 t.check_exception_thrown<std::logic_error>(
"Mismatched edge/node initialization", [](){
return graph_t{{}, nodes{1.0}}; });
146 t.check_exception_thrown<std::logic_error>(
"Mismatched edge/node initialization", [](){
return graph_t{{{}}, nodes{1.0, 2.0}}; });
147 t.check_exception_thrown<std::logic_error>(
"Mismatched edge/node initialization", [](){
return graph_t{{{edge_t{0, 1.0}}}, nodes{1.0, 2.0}}; });
148 t.check_exception_thrown<std::logic_error>(
"Mismatched edge/node initialization", [](){
return graph_t{{{}, {}}, nodes{1.0}}; });
149 t.check_exception_thrown<std::logic_error>(
"Mismatched edge/node initialization", [](){
return graph_t{{{edge_t{1}}, {edge_t{0}}}, nodes{1.0}}; });
154 static graph_t make_and_check(
regular_test& t, std::string_view description, edges_equivalent_t edgeInit, std::initializer_list<node_weight_type> nodeInit)
160 static transition_graph make_weighted_transition_graph(
regular_test& t)
165 auto trg{base_ops::make_transition_graph(t)};
167 check_initialization_exceptions(t);
170 trg.add_node(make_and_check(t, t.report(
""), {{}}, {1.0}));
173 trg.add_node(make_and_check(t, t.report(
""), {{{0, 0.0}}}, {1.0}));
176 trg.add_node(make_and_check(t, t.report(
""), {{{0, 1.0}}}, {0.0}));
179 trg.add_node(make_and_check(t, t.report(
""), {{{0, 1.0}, {0, 1.0}}}, {0.0}));
182 trg.add_node(make_and_check(t, t.report(
""), {{{0, 0.0}, {0, 1.0}}}, {0.0}));
185 trg.add_node(make_and_check(t, t.report(
""), {{{0, 1.0}, {0, 0.0}}}, {0.0}));
188 trg.add_node(make_and_check(t, t.report(
""), {{}, {}}, {0.0, 1.0}));
191 trg.add_node(make_and_check(t, t.report(
""), {{}, {}}, {1.0, 0.0}));
194 trg.add_node(make_and_check(t, t.report(
""), {{{1, 0.0}}, {}}, {0.0, 1.0}));
197 trg.add_node(make_and_check(t, t.report(
""), {{}, {{0, 0.0}}}, {1.0, 0.0}));
200 trg.add_node(make_and_check(t, t.report(
""), {{{1, 0.0}, {1, 1.0}}, {}}, {0.0, 0.0}));
203 trg.add_node(make_and_check(t, t.report(
""), {{{1, 1.0}, {1, 0.0}}, {}}, {0.0, 0.0}));
206 trg.add_node(make_and_check(t, t.report(
""), {{{1, 1.0}, {1, 1.0}}, {}}, {0.0, 0.0}));
209 trg.add_node(make_and_check(t, t.report(
""), {{{1, 0.0}, {1, 1.0}, {1, 2.0}}, {}}, {0.0, 0.0}));
212 trg.add_node(make_and_check(t, t.report(
""), {{{1, 1.0}, {1, 2.0}, {1, 0.0}}, {}}, {0.0, 0.0}));
215 trg.add_node(make_and_check(t, t.report(
""), {{{1, 2.0}, {1, 1.0}, {1, 0.0}}, {}}, {0.0, 0.0}));
218 trg.add_node(make_and_check(t, t.report(
""), {{{1, 0.0}, {1, 1.0}, {1, 2.0}, {0, 3.0}}, {}}, {0.0, 0.0}));
221 trg.add_node(make_and_check(t, t.report(
""), {{{0, 3.0}, {1, 2.0}, {1, 1.0}, {1, 0.0}}, {}}, {0.0, 0.0}));
224 trg.add_node(make_and_check(t, t.report(
""), {{
225 {0, -2.0}, {0, -2.0}, {0, -2.0}, {1, -2.0}, {1, -2.0}, {1, -2.0},
226 {0, -1.0}, {0, -1.0}, {0, -1.0}, {1, -1.0}, {1, -1.0}, {1, -1.0},
227 {0, 0.0}, {0, 0.0}, {0, 0.0}, {1, 0.0}, {1, 0.0}, {1, 0.0},
228 {0, 1.0}, {0, 1.0}, {0, 1.0}, {1, 1.0}, {1, 1.0}, {1, 1.0},
229 {0, 2.0}, {0, 2.0}, {0, 2.0}, {1, 2.0}, {1, 2.0}, {1, 2.0},
230 {0, 3.0}, {0, 3.0}, {0, 3.0}, {1, 3.0}, {1, 3.0}, {1, 3.0}
235 trg.add_node(make_and_check(t, t.report(
""), {{
236 {0, 3.0}, {0, 3.0}, {0, 3.0}, {1, 3.0}, {1, 3.0}, {1, 3.0},
237 {0, 2.0}, {0, 2.0}, {0, 2.0}, {1, 2.0}, {1, 2.0}, {1, 2.0},
238 {0, 1.0}, {0, 1.0}, {0, 1.0}, {1, 1.0}, {1, 1.0}, {1, 1.0},
239 {0, 0.0}, {0, 0.0}, {0, 0.0}, {1, 0.0}, {1, 0.0}, {1, 0.0},
240 {0, -1.0}, {0, -1.0}, {0, -1.0}, {1, -1.0}, {1, -1.0}, {1, -1.0},
241 {0, -2.0}, {0, -2.0}, {0, -2.0}, {1, -2.0}, {1, -2.0}, {1, -2.0}
248 graph_description::empty,
249 graph_description::empty,
251 [&t](graph_t g) -> graph_t {
252 t.check_exception_thrown<std::out_of_range>(
"Attempt to set a node weight which does not exist", [&g](){ g.set_node_weight(g.cbegin_node_weights(), 1.0); });
258 graph_description::empty,
259 graph_description::empty,
260 t.report(
"Attempt to mutate a node weight which does not exist"),
261 [&t](graph_t g) -> graph_t {
262 t.check_exception_thrown<std::out_of_range>(
"Attempt to mutate a node weight which does not exist", [&g](){ g.mutate_node_weight(g.cbegin_node_weights(), [](
double&){}); });
268 graph_description::empty,
269 weighted_graph_description::nodew,
270 t.report(
"Add weighted node"),
271 [](graph_t g) -> graph_t {
278 graph_description::empty,
279 weighted_graph_description::nodew,
280 t.report(
"Insert weighted node"),
281 [](graph_t g) -> graph_t {
282 g.insert_node(0, 1.0);
292 graph_description::node,
293 graph_description::node,
295 [&t](graph_t g) -> graph_t {
296 t.check_exception_thrown<std::out_of_range>(
"Attempt to set a node weight which does not exist", [&g](){ g.set_node_weight(g.cend_node_weights(), 1.0); });
302 graph_description::node,
303 graph_description::node,
304 t.report(
"Attempt to mutate a node weight which does not exist"),
305 [&t](graph_t g) -> graph_t {
306 t.check_exception_thrown<std::out_of_range>(
"Attempt to mutate a node weight which does not exist", [&g](){ g.mutate_node_weight(g.cend_node_weights(), [](
double&){}); });
312 graph_description::node,
313 weighted_graph_description::nodew,
314 t.report(
"Change node weight"),
315 [](graph_t g) -> graph_t {
316 g.set_node_weight(g.cbegin_node_weights(), 1.0);
322 graph_description::node,
323 weighted_graph_description::nodew,
324 t.report(
"Mutate node weight"),
325 [](graph_t g) -> graph_t {
326 g.mutate_node_weight(g.cbegin_node_weights(), [](
double& x) { x += 1.0; });
333 graph_description::node,
334 weighted_graph_description::nodew,
335 t.report(
"Change node weight via iterator"),
336 [](graph_t g) -> graph_t {
337 *g.begin_node_weights() = 1.0;
343 graph_description::node,
344 weighted_graph_description::nodew_node,
345 t.report(
"Insert weighted node"),
346 [](graph_t g) -> graph_t {
347 g.insert_node(0, 1.0);
357 graph_description::node_0,
358 weighted_graph_description::node_0w,
359 t.report(
"Set edge weight"),
360 [](graph_t g) -> graph_t {
361 g.set_edge_weight(g.cbegin_edges(0), 1.0);
367 graph_description::node_0,
368 weighted_graph_description::node_0w,
369 t.report(
"Mutate edge weight"),
370 [](graph_t g) -> graph_t {
371 g.mutate_edge_weight(g.cbegin_edges(0), [](
double& x){ x += 1.0; });
377 graph_description::node_0,
378 weighted_graph_description::node_0w,
379 t.report(
"Mutate edge weight"),
380 [](graph_t g) -> graph_t {
381 *g.begin_edge_weights(0) += 1.0;;
387 graph_description::node_0,
388 weighted_graph_description::node_0w,
389 t.report(
"Mutate edge weight"),
390 [](graph_t g) -> graph_t {
391 *g.rbegin_edge_weights(0) += 1.0;;
397 graph_description::node_0,
398 weighted_graph_description::node_0w,
399 t.report(
"Mutate edge weight"),
400 [](graph_t g) -> graph_t {
401 *g.edge_weights(0).begin() += 1.0;;
407 graph_description::node_0,
408 weighted_graph_description::node_0_0w,
409 t.report(
"Join {0,0}"),
410 [](graph_t g) -> graph_t {
421 graph_description::node_0_0,
422 weighted_graph_description::node_0w_0,
423 t.report(
"Set zeroth edge weight"),
424 [](graph_t g) -> graph_t {
425 g.set_edge_weight(g.cbegin_edges(0), 1.0);
431 graph_description::node_0_0,
432 weighted_graph_description::node_0_0w,
433 t.report(
"Set first edge weight"),
434 [](graph_t g) -> graph_t {
435 g.set_edge_weight(++g.cbegin_edges(0), 1.0);
445 graph_description::node_1_1_node,
446 weighted_graph_description::node_1_1w_node,
447 t.report(
"Set edge weight"),
448 [](graph_t g) -> graph_t {
449 g.set_edge_weight(++g.cbegin_edges(0), 1.0);
455 graph_description::node_1_1_node,
456 weighted_graph_description::node_1_1w_node,
457 t.report(
"Mutate edge weight"),
458 [](graph_t g) -> graph_t {
459 g.mutate_edge_weight(++g.cbegin_edges(0), [](
double& x) { x += 1.0; });
465 graph_description::node_1_1_node,
466 weighted_graph_description::node_1w_1_node,
467 t.report(
"Set edge weight"),
468 [](graph_t g) -> graph_t {
469 g.set_edge_weight(g.cbegin_edges(0), 1.0);
475 graph_description::node_1_1_node,
476 weighted_graph_description::node_1w_1_node,
477 t.report(
"Mutate edge weight"),
478 [](graph_t g) -> graph_t {
479 g.mutate_edge_weight(g.cbegin_edges(0), [](
double& x) { x += 1.0; });
491 weighted_graph_description::node_0_0w,
492 weighted_graph_description::node_0w_0,
493 t.report(
"Swap edges"),
494 [](graph_t g) -> graph_t {
495 g.swap_edges(0, 0, 1);
501 weighted_graph_description::node_0_0w,
502 weighted_graph_description::node_0w_0,
503 t.report(
"Swap edges"),
504 [](graph_t g) -> graph_t {
505 g.swap_edges(0, 1, 0);
511 weighted_graph_description::node_0_0w,
512 weighted_graph_description::node_0w_0,
513 t.report(
"Sort edges"),
514 [](graph_t g) -> graph_t {
515 g.sort_edges(g.cbegin_edges(0), g.cend_edges(0), [](
const auto& lhs,
const auto& rhs) {
return lhs.weight() > rhs.weight(); });
525 weighted_graph_description::node_0w_0,
526 weighted_graph_description::node_0_0w,
527 t.report(
"Swap edges"),
528 [](graph_t g) -> graph_t {
529 g.swap_edges(0, 0, 1);
535 weighted_graph_description::node_0w_0,
536 weighted_graph_description::node_0_0w,
537 t.report(
"Swap edges"),
538 [](graph_t g) -> graph_t {
539 g.swap_edges(0, 1, 0);
545 weighted_graph_description::node_0w_0,
546 weighted_graph_description::node_0_0w,
547 t.report(
"Sort edges"),
548 [](graph_t g) -> graph_t {
549 g.sort_edges(g.cbegin_edges(0), g.cend_edges(0), [](
const auto& lhs,
const auto& rhs) {
return lhs.weight() < rhs.weight(); });
559 weighted_graph_description::node_nodew,
560 weighted_graph_description::nodew_node,
561 t.report(
"Swap nodes"),
562 [](graph_t g) -> graph_t {
573 weighted_graph_description::nodew_node,
574 weighted_graph_description::node_nodew,
575 t.report(
"Swap nodes"),
576 [](graph_t g) -> graph_t {
587 weighted_graph_description::node_1_nodew,
588 weighted_graph_description::nodew_node_0,
589 t.report(
"Swap nodes"),
590 [](graph_t g) -> graph_t {
601 weighted_graph_description::nodew_node_0,
602 weighted_graph_description::node_1_nodew,
603 t.report(
"Swap nodes"),
604 [](graph_t g) -> graph_t {
615 weighted_graph_description::node_1_1w_node,
616 weighted_graph_description::node_1w_1w_node,
617 t.report(
"Set edge weight"),
618 [](graph_t g) -> graph_t {
619 g.set_edge_weight(g.cbegin_edges(0), 1.0);
625 weighted_graph_description::node_1_1w_node,
626 weighted_graph_description::node_1w_1_node,
627 t.report(
"Swap edges"),
628 [](graph_t g) -> graph_t {
629 g.swap_edges(0, 0, 1);
635 weighted_graph_description::node_1_1w_node,
636 weighted_graph_description::node_1w_1_node,
637 t.report(
"Sort edges"),
638 [](graph_t g) -> graph_t {
639 g.sort_edges(g.cbegin_edges(0), g.cend_edges(0), [](
const auto& lhs,
const auto& rhs) {
return lhs.weight() > rhs.weight(); });
649 weighted_graph_description::node_1w_1_node,
650 weighted_graph_description::node_1w_1w_node,
651 t.report(
"Set edge weight"),
652 [](graph_t g) -> graph_t {
653 g.set_edge_weight(++g.cbegin_edges(0), 1.0);
659 weighted_graph_description::node_1w_1_node,
660 weighted_graph_description::node_1_1w_node,
661 t.report(
"Swap edges"),
662 [](graph_t g) -> graph_t {
663 g.swap_edges(0, 0, 1);
669 weighted_graph_description::node_1w_1_node,
670 weighted_graph_description::node_1_1w_node,
671 t.report(
"Sort edges"),
672 [](graph_t g) -> graph_t {
673 g.sort_edges(g.cbegin_edges(0), g.cend_edges(0), [](
const auto& lhs,
const auto& rhs) {
return lhs.weight() < rhs.weight(); });
683 weighted_graph_description::node_1w_1w_node,
684 weighted_graph_description::node_1_1w_node,
685 t.report(
"Set edge weight"),
686 [](graph_t g) -> graph_t {
687 g.set_edge_weight(g.cbegin_edges(0), 0.0);
693 weighted_graph_description::node_1w_1w_node,
694 weighted_graph_description::node_1_1w_node,
695 t.report(
"Mutate edge weight"),
696 [](graph_t g) -> graph_t {
697 g.mutate_edge_weight(g.cbegin_edges(0), [](
double& x){ x -= 1.0; });
703 weighted_graph_description::node_1w_1w_node,
704 weighted_graph_description::node_1w_1_node,
705 t.report(
"Set edge weight"),
706 [](graph_t g) -> graph_t {
707 g.set_edge_weight(++g.cbegin_edges(0), 0.0);
713 weighted_graph_description::node_1w_1w_node,
714 weighted_graph_description::node_1w_1_node,
715 t.report(
"Mutate edge weight"),
716 [](graph_t g) -> graph_t {
717 g.mutate_edge_weight(++g.cbegin_edges(0), [](
double& x){ x -= 1.0; });
727 weighted_graph_description::node_1_1w_1x_node,
728 weighted_graph_description::node_1_1w_1x_0y_node,
729 t.report(
"Join {0,0}"),
730 [](graph_t g) -> graph_t {
737 weighted_graph_description::node_1_1w_1x_node,
738 weighted_graph_description::node_1w_1x_1_node,
739 t.report(
"Set multiple edge weights"),
740 [](graph_t g) -> graph_t {
741 g.set_edge_weight(g.cbegin_edges(0), 1.0);
742 g.set_edge_weight(g.cbegin_edges(0) + 1, 2.0);
743 g.set_edge_weight(g.cbegin_edges(0) + 2 , 0.0);
749 weighted_graph_description::node_1_1w_1x_node,
750 weighted_graph_description::node_1w_1x_1_node,
751 t.report(
"Mutate mutliple edge weights"),
752 [](graph_t g) -> graph_t {
753 g.mutate_edge_weight(g.cbegin_edges(0), [](
double& x){ x += 1.0; });
754 g.mutate_edge_weight(g.cbegin_edges(0) + 1, [](
double& x){ x += 1.0; });
755 g.mutate_edge_weight(g.cbegin_edges(0) + 2, [](
double& x){ x -= 2.0; });
765 weighted_graph_description::node_1w_1x_1_node,
766 weighted_graph_description::node_1w_1_node,
767 t.report(
"Remove {0,1}"),
768 [](graph_t g) -> graph_t {
769 g.erase_edge(++g.cbegin_edges(0));
775 weighted_graph_description::node_1w_1x_1_node,
776 weighted_graph_description::node_1_1w_1x_node,
777 t.report(
"Sort edges"),
778 [](graph_t g) -> graph_t {
779 g.sort_edges(g.cbegin_edges(0), g.cend_edges(0), [](
const auto& lhs,
const auto& rhs) {
return lhs.weight() < rhs.weight(); });
789 weighted_graph_description::node_1x_1w_1_node,
790 weighted_graph_description::node_1w_1x_1_node,
791 t.report(
"Swap edges"),
792 [](graph_t g) -> graph_t {
793 g.swap_edges(0, 1, 0);
799 weighted_graph_description::node_1x_1w_1_node,
800 weighted_graph_description::node_1_1w_1x_node,
801 t.report(
"Sort edges"),
802 [](graph_t g) -> graph_t {
803 g.sort_edges(g.cbegin_edges(0), g.cend_edges(0), [](
const auto& lhs,
const auto& rhs) {
return lhs.weight() < rhs.weight(); });
813 weighted_graph_description::node_1_1w_1x_0y_node,
814 weighted_graph_description::node_0y_1x_1w_1_node,
815 t.report(
"Sort edges"),
816 [](graph_t g) -> graph_t {
817 g.sort_edges(g.cbegin_edges(0), g.cend_edges(0), [](
const auto& lhs,
const auto& rhs) {
return lhs.weight() > rhs.weight(); });
827 weighted_graph_description::node_0y_1x_1w_1_node,
828 weighted_graph_description::node_1x_1w_1_node,
829 t.report(
"Remove {0,0}"),
830 [](graph_t g) -> graph_t {
831 g.erase_edge(g.cbegin_edges(0));
837 weighted_graph_description::node_0y_1x_1w_1_node,
838 weighted_graph_description::node_1_1w_1x_0y_node,
839 t.report(
"Sort edges"),
840 [](graph_t g) -> graph_t {
841 g.sort_edges(g.cbegin_edges(0), g.cend_edges(0), [](
const auto& lhs,
const auto& rhs) {
return lhs.weight() < rhs.weight(); });
851 weighted_graph_description::node_0uuu_1uuu_0vvv_1vvv_0www_1www_0xxx_1xxx_0yyy_1yyy_0zzz_1zzz_node,
852 weighted_graph_description::node_0zzz_1zzz_0yyy_1yyy_0xxx_1xxx_0www_1www_0vvv_1vvv_0uuu_1uuu_node,
853 t.report(
"Sort edges"),
854 [](graph_t g) -> graph_t {
855 g.stable_sort_edges(g.cedges(0), std::ranges::greater{}, [](
const auto& e) {
return e.weight(); });
865 weighted_graph_description::node_0zzz_1zzz_0yyy_1yyy_0xxx_1xxx_0www_1www_0vvv_1vvv_0uuu_1uuu_node,
866 weighted_graph_description::node_0uuu_1uuu_0vvv_1vvv_0www_1www_0xxx_1xxx_0yyy_1yyy_0zzz_1zzz_node,
867 t.report(
"Sort edges"),
868 [](graph_t g) -> graph_t {
869 g.stable_sort_edges(g.cbegin_edges(0), g.cend_edges(0), [](
const auto& lhs,
const auto& rhs) {
return lhs.weight() < rhs.weight(); });
weighted_graph_description
Convention: the indices following 'node' - separated by underscores - give the target node of the ass...
Definition: DynamicDirectedGraphWeightedTestingUtilities.hpp:18
Definition: DynamicGraph.hpp:303
class template from which all concrete tests should derive.
Definition: FreeTestCore.hpp:144
Exposes elementary check methods, with the option to plug in arbitrary Extenders to compose functiona...
Definition: FreeCheckers.hpp:708
Definition: DynamicDirectedGraphTestingUtilities.hpp:172
Definition: DynamicDirectedGraphWeightedTestingUtilities.hpp:114
Definition: DynamicGraphTestingUtilities.hpp:173
Definition: StateTransitionUtilities.hpp:77