Sequoia
Loading...
Searching...
No Matches
DynamicUndirectedEmbeddedGraphMetaDataTestingUtilities.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_embedded_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 // x x
45 node_node,
46
47 // x---x
48 node_1b_node_0a
49 };
50 }
51
52 template
53 <
54 class EdgeWeight,
55 class NodeWeight,
56 class EdgeMetaData,
57 class EdgeStorageConfig,
58 class NodeWeightStorage
59 >
61 {
62 public:
64 using edge_t = typename graph_t::edge_init_type;
65 using node_weight_type = typename graph_t::node_weight_type;
66 using edges_equivalent_t = std::initializer_list<std::initializer_list<edge_t>>;
67 using transition_graph = typename transition_checker<graph_t>::transition_graph;
68
69 static void execute_operations(regular_test& t)
70 {
71 auto trg{make_meta_data_transition_graph(t)};
72
73 auto checker{
74 [&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) {
75 t.check(equality, {description, no_source_location}, obtained, prediction);
76 if(host != target) t.check_semantics({description, no_source_location}, prediction, parent);
77 }
78 };
79
81 }
82
83 [[nodiscard]]
84 static graph_t make_and_check(regular_test& t, std::string_view description, edges_equivalent_t init)
85 {
87 }
88
89 static void check_initialization_exceptions(regular_test& t)
90 {
91 using namespace maths;
92
93 // One node
94 t.check_exception_thrown<std::out_of_range>("Target index of edge out of range", [](){ return graph_t{{{1, 0, 0.5f}}}; });
95 t.check_exception_thrown<std::out_of_range>("Complimentary index of edge out of range", [](){ return graph_t{{{0, 1, 0.5f}}}; });
96 t.check_exception_thrown<std::logic_error>("Self-referential complimentary index", [](){ return graph_t{{{0, 0, 0.5f}}}; });
97 t.check_exception_thrown<std::logic_error>("Mismatched complimentary indices", [](){ return graph_t{{{0, 1, 0.5f}, {0, 1, 0.5f}}}; });
98 t.check_exception_thrown<std::logic_error>("Mismatched complimentary indices", [](){ return graph_t{{{0, 1, 0.5f}, {0, 2, 0.5f}, {0, 0, 0.5f}}}; });
99
100 // Two nodes
101 t.check_exception_thrown<std::logic_error>("Mismatched complimentary indices", [](){ return graph_t{{{1, 0, 0.5f}, {0, 2, 0.5f}, {0, 1, 0.5f}}, {{0, 1, 0.5f}}}; });
102 }
103
104 [[nodiscard]]
105 static transition_graph make_meta_data_transition_graph(regular_test& t)
106 {
107 using meta_data_t = EdgeMetaData;
108 using namespace undirected_embedded_graph;
109
110 check_initialization_exceptions(t);
111
112 return transition_graph{
113 {
114 { // begin 'meta_data_graph_description::empty'
115 }, // end 'meta_data_graph_description::empty'
116 { // begin 'meta_data_graph_description::node'
117 {
118 meta_data_graph_description::node_0a_0b,
119 t.report("Add loop"),
120 [](graph_t g) -> graph_t {
121 g.join(0, 0, 0.0f, 0.5f);
122 return g;
123 }
124 },
125 {
126 meta_data_graph_description::node_0b_0a,
127 t.report("Add loop"),
128 [](graph_t g) -> graph_t {
129 g.join(0, 0, 0.5f, 0.0f);
130 return g;
131 }
132 },
133 {
134 meta_data_graph_description::node_0a_0b,
135 t.report("Insert loop"),
136 [](graph_t g) -> graph_t {
137 g.insert_join(g.cbegin_edges(0), 1, 0.0f, 0.5f);
138 return g;
139 }
140 },
141 {
142 meta_data_graph_description::node_0b_0a,
143 t.report("Insert loop"),
144 [](graph_t g) -> graph_t {
145 g.insert_join(g.cbegin_edges(0), g.cbegin_edges(0), 0.0f, 0.5f);
146 return g;
147 }
148 }
149 }, // end 'meta_data_graph_description::node'
150 { // begin 'meta_data_graph_description::node_0a_0a'
151 {
152 meta_data_graph_description::node_0b_0a,
153 t.report("Set edge meta data"),
154 [](graph_t g) -> graph_t {
155 g.set_edge_meta_data(g.cbegin_edges(0), 0.5f);
156 return g;
157 }
158 },
159 {
160 meta_data_graph_description::node_0b_0a,
161 t.report("Set edge meta data"),
162 [](graph_t g) -> graph_t {
163 g.set_edge_meta_data(g.cbegin_edges(0), meta_data_t{0.5f});
164 return g;
165 }
166 },
167 {
168 meta_data_graph_description::node_0b_0a,
169 t.report("Mutate edge meta data"),
170 [&t](graph_t g) -> graph_t {
171 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);
172 return g;
173 }
174 },
175 {
176 meta_data_graph_description::node_0a_0b,
177 t.report("Set meta data via reverse iterator"),
178 [](graph_t g) -> graph_t {
179 g.set_edge_meta_data(g.crbegin_edges(0), 0.5f);
180 return g;
181 }
182 },
183 {
184 meta_data_graph_description::node_0a_0b,
185 t.report("Mutate edge meta data via reverse iterator"),
186 [&t](graph_t g) -> graph_t {
187 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);
188 return g;
189 }
190 }
191 }, // end 'meta_data_graph_description::node_0a_0a'
192 { // begin 'meta_data_graph_description::node_0a_0b'
193 }, // end 'meta_data_graph_description::node_0a_0b'
194 { // begin 'meta_data_graph_description::node_0b_0a'
195 }, // end 'meta_data_graph_description::node_0b_0a'
196 { // begin 'meta_data_graph_description::node_node'
197 {
198 meta_data_graph_description::node_1b_node_0a,
199 t.report("Join {0,1}"),
200 [](graph_t g) -> graph_t {
201 g.join(0, 1, 0.5f, 0.0f);
202 return g;
203 }
204 },
205 {
206 meta_data_graph_description::node_1b_node_0a,
207 t.report("Join {0,1}"),
208 [](graph_t g) -> graph_t {
209 g.insert_join(g.cbegin_edges(0), g.cbegin_edges(1), 0.5f, 0.0f);
210 return g;
211 }
212 },
213 {
214 meta_data_graph_description::node_1b_node_0a,
215 t.report("Join {0,1}"),
216 [](graph_t g) -> graph_t {
217 g.insert_join(g.cbegin_edges(1), g.cbegin_edges(0), 0.0f, 0.5f);
218 return g;
219 }
220 }
221 }, // end 'meta_data_graph_description::node_node'
222 { // begin 'meta_data_graph_description::node_1b_node_0a'
223 } // end 'meta_data_graph_description::node_1b_node_0a'
224 },
225 {
226 // 'empty'
227 make_and_check(t, t.report(""), {}),
228
229 // 'node'
230 make_and_check(t, t.report(""), {{}}),
231
232 // 'node_0a_0a
233 make_and_check(t, t.report(""), {{{0, 1, 0.0f}, {0, 0, 0.0f}}}),
234
235 // 'node_0a_0b
236 make_and_check(t, t.report(""), {{{0, 1, 0.0f}, {0, 0, 0.5f}}}),
237
238 // 'node_0b_0a
239 make_and_check(t, t.report(""), {{{0, 1, 0.5f}, {0, 0, 0.0f}}}),
240
241 // 'node_node'
242 make_and_check(t, t.report(""), {{}, {}}),
243
244 // 'node_1b_node_0a'
245 make_and_check(t, t.report(""), {{{1, 0, 0.5f}}, {{0, 0, 0.0f}}})
246 }
247 };
248 }
249 };
250}
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:473
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: DynamicUndirectedEmbeddedGraphMetaDataTestingUtilities.hpp:61
Definition: DynamicGraphTestingUtilities.hpp:173
Definition: StateTransitionUtilities.hpp:77