15namespace sequoia::testing
17 namespace partitioned_data
19 enum data_description : std::size_t {
75 template<
class PartitionedData>
79 using data_t = PartitionedData;
80 using value_type =
typename PartitionedData::value_type;
81 using equiv_t = std::initializer_list<std::initializer_list<value_type>>;
86 auto trg{make_transition_graph(t)};
89 [&t](std::string_view description,
const data_t& obtained,
const data_t& prediction,
const data_t& parent, std::size_t host, std::size_t target) {
90 t.check(equality, {description, no_source_location}, obtained, prediction);
91 if(host != target) t.check_semantics({description, no_source_location}, prediction, parent);
99 static data_t make_and_check(
regular_test& t, std::string_view description, equiv_t init)
102 t.check(equivalence, description, d, init);
107 static transition_graph make_transition_graph(
regular_test& t)
109 using namespace partitioned_data;
110 return transition_graph{
114 data_description::empty,
116 [&t](data_t d) -> data_t {
117 t.check_exception_thrown<std::out_of_range>(
"Pushing back to non-existent partition throws", [&d]() {
return d.push_back_to_partition(0, 8); });
122 data_description::empty,
124 [&t](data_t d) -> data_t {
125 t.check_exception_thrown<std::out_of_range>(
"Inserting to non-existent partition throws", [&d]() {
return d.insert_to_partition(d.cbegin_partition(0), 8); });
130 data_description::empty,
132 [&t](data_t d) -> data_t {
133 t.check_exception_thrown<std::out_of_range>(
"Inserting to non-existent partition throws", [&d]() {
return d.insert_to_partition(0, 0, 8); });
138 data_description::empty,
139 t.report(
"Swapping non-existent partition"),
140 [&t](data_t d) -> data_t {
141 d.swap_partitions(0, 0);
146 data_description::empty,
147 t.report(
"Clear empty container"),
148 [&t](data_t d) -> data_t {
154 data_description::empty_partition,
155 t.report(
"Add slot to empty container"),
156 [&t](data_t d) -> data_t {
162 data_description::empty_partition,
163 t.report(
"Insert slot to empty container"),
164 [&t](data_t d) -> data_t {
172 data_description::empty_partition,
174 [&t](data_t d) -> data_t {
175 t.check_exception_thrown<std::out_of_range>(
"Pushing back to non-existent partition throws", [&d]() {
return d.push_back_to_partition(1, 8); });
180 data_description::empty_partition,
182 [&t](data_t d) -> data_t {
183 t.check_exception_thrown<std::out_of_range>(
"Inserting to non-existent partition throws", [&d]() {
return d.insert_to_partition(d.cbegin_partition(1), 8); });
188 data_description::empty_partition,
190 [&t](data_t d) -> data_t {
191 t.check_exception_thrown<std::out_of_range>(
"Inserting to non-existent partition throws", [&d]() {
return d.insert_to_partition(1, 0, 8); });
196 data_description::empty_partition,
197 t.report(
"Swapping non-existent partition"),
198 [&t](data_t d) -> data_t {
199 d.swap_partitions(0, 1);
204 data_description::empty_partition,
205 t.report(
"Swapping non-existent partition"),
206 [&t](data_t d) -> data_t {
207 d.swap_partitions(1, 0);
212 data_description::empty_partition,
214 [&t](data_t d) -> data_t {
215 auto i{d.erase_from_partition(d.cbegin_partition(0))};
216 t.check(equality,
"Erase from partition with nothing in it", i, d.begin_partition(0));
221 data_description::empty_partition,
223 [&t](data_t d) -> data_t {
224 auto i{d.erase_from_partition(0, 0)};
225 t.check(equality,
"Erase from partition with nothing in it", i, d.begin_partition(0));
230 data_description::empty_partition,
232 [&t](data_t d) -> data_t {
233 auto i{d.erase_from_partition(0, 1)};
234 t.check(equality,
"Erase from partition with nothing in it", i, d.begin_partition(0));
239 data_description::empty_partition,
241 [&t](data_t d) -> data_t {
242 auto i{d.erase_from_partition(d.cbegin_partition(0), d.cend_partition(0))};
243 t.check(equality,
"Erase empty range", i, d.begin_partition(0));
248 data_description::empty_partition,
250 [&t](data_t d) -> data_t {
251 t.check_exception_thrown<std::domain_error>(
"", [&d](){ d.erase_from_partition(d.cbegin_partition(0), d.cend_partition(1)); });
256 data_description::empty_partition,
258 [&t](data_t d) -> data_t {
259 t.check_exception_thrown<std::domain_error>(
"", [&d](){ d.erase_from_partition(d.cbegin_partition(1), d.cend_partition(0)); });
264 data_description::empty_partition,
266 [&t](data_t d) -> data_t {
267 auto i{d.erase_from_partition(d.cbegin_partition(1), d.cend_partition(1))};
268 t.check(equality,
"Erase fictional range", i, d.end_partition(1));
273 data_description::empty_partition,
274 t.report(
"Swapping non-existent partition"),
275 [&t](data_t d) -> data_t {
276 d.swap_partitions(0, 0);
281 data_description::empty_partition,
282 t.report(
"Swapping non-existent partition"),
283 [&t](data_t d) -> data_t {
284 d.swap_partitions(1, 0);
289 data_description::empty_partition,
291 [&t](data_t d) -> data_t {
292 d.swap_partitions(0, 1);
297 data_description::empty,
298 t.report(
"Clear empty container"),
299 [&t](data_t d) -> data_t {
305 data_description::empty,
307 [&t](data_t d) -> data_t {
313 data_description::one_2,
315 [&t](data_t d) -> data_t {
316 d.push_back_to_partition(0, 2);
321 data_description::one_2,
323 [&t](data_t d) -> data_t {
324 d.insert_to_partition(d.cbegin_partition(0), 2);
329 data_description::two_empty_partitions,
331 [&t](data_t d) -> data_t {
337 data_description::two_empty_partitions,
339 [&t](data_t d) -> data_t {
345 data_description::two_empty_partitions,
347 [&t](data_t d) -> data_t {
355 data_description::empty_partition,
357 [&t](data_t d) -> data_t {
358 d.erase_from_partition(d.cbegin_partition(0));
363 data_description::empty_partition,
365 [&t](data_t d) -> data_t {
366 d.erase_from_partition(d.cbegin_partition(0), d.cend_partition(0));
371 data_description::empty,
373 [&t](data_t d) -> data_t {
379 data_description::empty,
381 [&t](data_t d) -> data_t {
387 data_description::one_2,
389 [&t](data_t d) -> data_t {
390 d.swap_partitions(0, 0);
395 data_description::one_3,
397 [&t](data_t d) -> data_t {
398 *d.begin_partition(0) = 3;
403 data_description::one_3,
405 [&t](data_t d) -> data_t {
406 *d.rbegin_partition(0) = 3;
411 data_description::one_2_3,
413 [&t](data_t d) -> data_t {
414 d.push_back_to_partition(0, 3);
419 data_description::one_2_3,
421 [&t](data_t d) -> data_t {
422 d.insert_to_partition(d.cbegin_partition(0)+1, 3);
427 data_description::two_2__,
429 [&t](data_t d) -> data_t {
435 data_description::two__2,
437 [&t](data_t d) -> data_t {
445 data_description::one_2,
447 [&t](data_t d) -> data_t {
448 *d.begin_partition(0) = 2;
453 data_description::one_3_2,
455 [&t](data_t d) -> data_t {
456 d.push_back_to_partition(0, 2);
461 data_description::one_2_3,
463 [&t](data_t d) -> data_t {
464 d.insert_to_partition(d.cbegin_partition(0), 2);
471 data_description::one_3,
473 [&t](data_t d) -> data_t {
474 d.erase_from_partition(d.cbegin_partition(0));
479 data_description::one_3,
481 [&t](data_t d) -> data_t {
482 d.erase_from_partition(d.cbegin_partition(0), d.cbegin_partition(0) + 1);
487 data_description::one_2,
489 [&t](data_t d) -> data_t {
490 d.erase_from_partition(d.cbegin_partition(0)+1);
495 data_description::one_2,
497 [&t](data_t d) -> data_t {
498 d.erase_from_partition(d.cbegin_partition(0) + 1, d.cend_partition(0));
503 data_description::empty_partition,
505 [&t](data_t d) -> data_t {
506 d.erase_from_partition(d.cbegin_partition(0), d.cend_partition(0));
511 data_description::empty,
513 [&t](data_t d) -> data_t {
519 data_description::empty,
521 [&t](data_t d) -> data_t {
527 data_description::one_3_2,
529 [&t](data_t d) -> data_t {
530 std::ranges::sort(d.begin_partition(0), d.end_partition(0), std::greater{});
535 data_description::two__2_3,
537 [&t](data_t d) -> data_t {
545 data_description::one_2,
547 [&t](data_t d) -> data_t {
548 d.erase_from_partition(d.cbegin_partition(0));
553 data_description::one_3,
555 [&t](data_t d) -> data_t {
556 d.erase_from_partition(d.cbegin_partition(0) + 1);
561 data_description::one_2_3,
563 [&t](data_t d) -> data_t {
564 std::ranges::sort(d.begin_partition(0), d.end_partition(0));
569 data_description::one_3_4_2,
571 [&t](data_t d) -> data_t {
572 d.insert_to_partition(d.cbegin_partition(0) + 1, 4);
579 data_description::one_3_2,
581 [&t](data_t d) -> data_t {
582 d.erase_from_partition(d.cbegin_partition(0) + 1);
587 data_description::one_3_2,
589 [&t](data_t d) -> data_t {
590 d.erase_from_partition(d.cbegin_partition(0) + 1, d.cbegin_partition(0) + 2);
595 data_description::one_3,
597 [&t](data_t d) -> data_t {
598 d.erase_from_partition(d.cbegin_partition(0) + 1, d.cend_partition(0));
603 data_description::one_2,
605 [&t](data_t d) -> data_t {
606 d.erase_from_partition(d.cbegin_partition(0), d.cbegin_partition(0)+2);
613 data_description::two_empty_partitions,
615 [&t](data_t d) -> data_t {
616 t.check_exception_thrown<std::domain_error>(
"", [&d](){ d.erase_from_partition(d.cbegin_partition(0), d.cend_partition(1)); });
621 data_description::two_empty_partitions,
623 [&t](data_t d) -> data_t {
624 d.swap_partitions(0, 0);
629 data_description::empty_partition,
631 [&t](data_t d) -> data_t {
637 data_description::empty_partition,
639 [&t](data_t d) -> data_t {
645 data_description::empty,
647 [&t](data_t d) -> data_t {
653 data_description::two_2__,
655 [&t](data_t d) -> data_t {
656 d.push_back_to_partition(0, 2);
661 data_description::two_2__,
663 [&t](data_t d) -> data_t {
664 d.insert_to_partition(d.cbegin_partition(0), 2);
669 data_description::two__2,
671 [&t](data_t d) -> data_t {
672 d.insert_to_partition(d.cbegin_partition(1), 2);
679 data_description::empty_partition,
681 [&t](data_t d) -> data_t {
687 data_description::one_2,
689 [&t](data_t d) -> data_t {
695 data_description::two__2,
697 [&t](data_t d) -> data_t {
698 d.swap_partitions(0, 1);
703 data_description::two__2,
705 [&t](data_t d) -> data_t {
706 d.swap_partitions(1, 0);
713 data_description::two_2_3__,
715 [&t](data_t d) -> data_t {
716 d.insert_to_partition(d.cbegin_partition(0), 2);
723 data_description::two__2_3,
725 [&t](data_t d) -> data_t {
726 d.swap_partitions(0, 1);
731 data_description::two_3__,
733 [&t](data_t d) -> data_t {
734 d.erase_from_partition(d.cbegin_partition(0));
741 data_description::two_2__,
743 [&t](data_t d) -> data_t {
744 d.swap_partitions(1, 0);
751 data_description::two__2,
753 [&t](data_t d) -> data_t {
754 d.erase_from_partition(d.cbegin_partition(1) + 1);
759 data_description::two_2_3__,
761 [&t](data_t d) -> data_t {
762 d.swap_partitions(0, 1);
769 data_description::two_3__2,
771 [&t](data_t d) -> data_t {
772 d.swap_partitions(0, 1);
777 data_description::two_2__,
779 [&t](data_t d) -> data_t {
780 d.erase_from_partition(d.cbegin_partition(1), d.cend_partition(1));
785 data_description::one_2,
787 [&t](data_t d) -> data_t {
793 data_description::one_3,
795 [&t](data_t d) -> data_t {
801 data_description::three_2____3,
803 [&t](data_t d) -> data_t {
809 data_description::three_2__3__,
811 [&t](data_t d) -> data_t {
819 data_description::two_2__3,
821 [&t](data_t d) -> data_t {
822 d.swap_partitions(1, 0);
827 data_description::three_3____2,
829 [&t](data_t d) -> data_t {
837 data_description::three_3____2,
839 [&t](data_t d) -> data_t {
840 d.swap_partitions(0,2);
845 data_description::three_2__3__,
847 [&t](data_t d) -> data_t {
848 d.swap_partitions(1,2);
853 data_description::two_2__3,
855 [&t](data_t d) -> data_t {
863 data_description::three_2____3,
865 [&t](data_t d) -> data_t {
866 d.swap_partitions(2,0);
871 data_description::two__2,
873 [&t](data_t d) -> data_t {
881 data_description::three_2____3,
883 [&t](data_t d) -> data_t {
884 d.swap_partitions(2,1);
892 make_and_check(t, t.report(
""), {}),
895 make_and_check(t, t.report(
""), {{}}),
898 make_and_check(t, t.report(
""), {{2}}),
901 make_and_check(t, t.report(
""), {{3}}),
904 make_and_check(t, t.report(
""), {{2, 3}}),
907 make_and_check(t, t.report(
""), {{3, 2}}),
910 make_and_check(t, t.report(
""), {{3, 4, 2}}),
913 make_and_check(t, t.report(
""), {{}, {}}),
916 make_and_check(t, t.report(
""), {{2}, {}}),
919 make_and_check(t, t.report(
""), {{3}, {}}),
922 make_and_check(t, t.report(
""), {{2,3}, {}}),
925 make_and_check(t, t.report(
""), {{}, {2}}),
928 make_and_check(t, t.report(
""), {{}, {2, 3}}),
931 make_and_check(t, t.report(
""), {{2}, {3}}),
934 make_and_check(t, t.report(
""), {{3}, {2}}),
937 make_and_check(t, t.report(
""), {{2}, {}, {3}}),
940 make_and_check(t, t.report(
""), {{3}, {}, {2}}),
943 make_and_check(t, t.report(
""), {{2}, {3}, {}}),
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
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: PartitionedDataGenericTests.hpp:77
Definition: StateTransitionUtilities.hpp:77