Sequoia
Loading...
Searching...
No Matches
DynamicUndirectedGraphMetaDataTestingUtilities.hpp
Go to the documentation of this file.
1
2// Copyright Oliver J. Rosten 2023. //
3// Distributed under the GNU GENERAL PUBLIC LICENSE, Version 3.0. //
4// (See accompanying file LICENSE.md or copy at //
5// https://www.gnu.org/licenses/gpl-3.0.en.html) //
7
8#pragma once
9
13
16
17namespace sequoia::testing
18{
19 namespace undirected_graph{
20 // Convention: the indices following 'node' - separated by underscores - give the target node of the associated edges
21 // Letters near the start of the alphabet distinguish meta-data values
22 enum meta_data_graph_description : std::size_t {
23
24 empty = 0,
25
26 // x
27 node,
28
29 // /\
30 // \/
31 // x
32 node_0a_0a,
33
34 // /\
35 // \/
36 // x
37 node_0a_0b,
38
39 // /\
40 // \/
41 // x
42 node_0b_0a,
43 };
44 }
45
46 template
47 <
48 class EdgeWeight,
49 class NodeWeight,
50 class EdgeMetaData,
51 class EdgeStorageConfig,
52 class NodeWeightStorage
53 >
55 {
56 public:
58 using edge_t = typename graph_t::edge_init_type;
59 using node_weight_type = typename graph_t::node_weight_type;
60 using edges_equivalent_t = std::initializer_list<std::initializer_list<edge_t>>;
61 using transition_graph = typename transition_checker<graph_t>::transition_graph;
62
63 static void execute_operations(regular_test& t)
64 {
65 auto trg{make_meta_data_transition_graph(t)};
66
67 auto checker{
68 [&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) {
69 t.check(equality, {description, no_source_location}, obtained, prediction);
70 if(host != target) t.check_semantics({description, no_source_location}, prediction, parent);
71 }
72 };
73
75 }
76
77 [[nodiscard]]
78 static graph_t make_and_check(regular_test& t, std::string_view description, edges_equivalent_t init)
79 {
81 }
82
83 static void check_initialization_exceptions(regular_test& t)
84 {
85 using namespace maths;
86
87 // One node
88 t.check_exception_thrown<std::out_of_range>("Target index of edge out of range", [](){ return graph_t{{edge_t{1, 0.5f}}}; });
89 t.check_exception_thrown<std::logic_error>("Mismatched loop", [](){ return graph_t{{edge_t{0, 0.5f}}}; });
90
91 // Two nodes
92 t.check_exception_thrown<std::logic_error>("Mismatched partial edges", [](){ return graph_t{{edge_t{1, 0.5f}}, {edge_t{1, -0.5f}}}; });
93 t.check_exception_thrown<std::logic_error>("Mismatched loop", [](){ return graph_t{{edge_t{1, 0.5f}}, {edge_t{0, 0.6f}, edge_t{1, -0.5f}}}; });
94 }
95
96 [[nodiscard]]
97 static transition_graph make_meta_data_transition_graph(regular_test& t)
98 {
99 using meta_data_t = EdgeMetaData;
100 using namespace undirected_graph;
101
102 check_initialization_exceptions(t);
103
104 return transition_graph{
105 {
106 { // begin 'meta_data_graph_description::empty'
107 }, // end 'meta_data_graph_description::empty'
108 { // begin 'meta_data_graph_description::node'
109 {
110 meta_data_graph_description::node_0a_0b,
111 t.report("Add loop"),
112 [](graph_t g) -> graph_t {
113 g.join(0, 0, 0.0f, 0.5f);
114 return g;
115 }
116 },
117 {
118 meta_data_graph_description::node_0b_0a,
119 t.report("Add loop"),
120 [](graph_t g) -> graph_t {
121 g.join(0, 0, 0.5f, 0.0f);
122 return g;
123 }
124 }
125 }, // end 'meta_data_graph_description::node'
126 { // begin 'meta_data_graph_description::node_0a_0a'
127 {
128 meta_data_graph_description::node_0b_0a,
129 t.report("Set edge meta data"),
130 [](graph_t g) -> graph_t {
131 g.set_edge_meta_data(g.cbegin_edges(0), 0.5f);
132 return g;
133 }
134 },
135 {
136 meta_data_graph_description::node_0b_0a,
137 t.report("Set edge meta data"),
138 [](graph_t g) -> graph_t {
139 g.set_edge_meta_data(g.cbegin_edges(0), meta_data_t{0.5f});
140 return g;
141 }
142 },
143 {
144 meta_data_graph_description::node_0b_0a,
145 t.report("Mutate edge meta data"),
146 [&t](graph_t g) -> graph_t {
147 t.check(equality, "Mutate return value", g.mutate_edge_meta_data(g.cbegin_edges(0), [](meta_data_t& m) { m += 0.5f; return 42; }), 42);
148 return g;
149 }
150 },
151 {
152 meta_data_graph_description::node_0a_0b,
153 t.report("Set meta data via reverse iterator"),
154 [](graph_t g) -> graph_t {
155 g.set_edge_meta_data(g.crbegin_edges(0), 0.5f);
156 return g;
157 }
158 },
159 {
160 meta_data_graph_description::node_0a_0b,
161 t.report("Mutate edge meta data via reverse iterator"),
162 [&t](graph_t g) -> graph_t {
163 t.check(equality, "Mutate return value", g.mutate_edge_meta_data(g.crbegin_edges(0), [](meta_data_t& m) { m += 0.5f; return 42; }), 42);
164 return g;
165 }
166 }
167 }, // end 'meta_data_graph_description::node_0a_0a'
168 { // begin 'meta_data_graph_description::node_0a_0b'
169 }, // end 'meta_data_graph_description::node_0a_0b'
170 { // begin 'meta_data_graph_description::node_0b_0a'
171 }, // end 'meta_data_graph_description::node_0b_0a'
172 },
173 {
174 // 'empty'
175 make_and_check(t, t.report(""), {}),
176
177 // 'node'
178 make_and_check(t, t.report(""), {{}}),
179
180 // 'node_0a_0a
181 make_and_check(t, t.report(""), {{{0, 0.0f}, {0, 0.0f}}}),
182
183 // 'node_0a_0b
184 make_and_check(t, t.report(""), {{{0, 0.0f}, {0, 0.5f}}}),
185
186 // 'node_0b_0a
187 make_and_check(t, t.report(""), {{{0, 0.5f}, {0, 0.0f}}}),
188 }
189 };
190 }
191 };
192}
Utilities for checking regular semantics.
Facility to define tests via a graph comprising states of an object and transitions between them.
Definition: DynamicGraph.hpp:303
Definition: DynamicGraph.hpp:360
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: DynamicUndirectedGraphMetaDataTestingUtilities.hpp:55
Definition: DynamicGraphTestingUtilities.hpp:173
Definition: StateTransitionUtilities.hpp:77