Skip to content

Commit 5d133ff

Browse files
committed
Add custom Catch2 matchers
1 parent 7d0bd7a commit 5d133ff

File tree

11 files changed

+459
-198
lines changed

11 files changed

+459
-198
lines changed

test/common/test_version.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
namespace {
1010

11+
namespace CM = Catch::Matchers;
12+
1113
CATCH_TEST_CASE("WHIRLWIND_VERSION_EPOCH", "[version]")
1214
{
1315
using T = decltype(WHIRLWIND_VERSION_EPOCH);
@@ -24,8 +26,7 @@ CATCH_TEST_CASE("WHIRLWIND_VERSION_PATCH", "[version]")
2426

2527
CATCH_TEST_CASE("WHIRLWIND_VERSION_STRING", "[version]")
2628
{
27-
using Catch::Matchers::Matches;
28-
CATCH_CHECK_THAT(WHIRLWIND_VERSION_STRING, Matches(R"(^\d{8}\.\d+$)"));
29+
CATCH_CHECK_THAT(WHIRLWIND_VERSION_STRING, CM::Matches(R"(^\d{8}\.\d+$)"));
2930
}
3031

3132
} // namespace

test/graph/test_csr_graph.cpp

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
#include <whirlwind/graph/csr_graph.hpp>
1010
#include <whirlwind/graph/edge_list.hpp>
1111

12+
#include "../testing/matchers/graph_matchers.hpp"
1213
#include "../testing/string_conversions.hpp" // IWYU pragma: keep
1314

1415
namespace {
1516

17+
namespace CM = Catch::Matchers;
1618
namespace ww = whirlwind;
1719

1820
CATCH_TEST_CASE("CSRGraph (empty)", "[graph]")
@@ -27,8 +29,8 @@ CATCH_TEST_CASE("CSRGraph (empty)", "[graph]")
2729

2830
CATCH_SECTION("contains_{vertex,edge}")
2931
{
30-
CATCH_CHECK_FALSE(graph.contains_vertex(0U));
31-
CATCH_CHECK_FALSE(graph.contains_edge(0U));
32+
CATCH_CHECK_THAT(graph, !ww::testing::ContainsVertex(0U));
33+
CATCH_CHECK_THAT(graph, !ww::testing::ContainsEdge(0U));
3234
}
3335
}
3436

@@ -75,22 +77,23 @@ CATCH_TEST_CASE("CSRGraph", "[graph]")
7577

7678
CATCH_SECTION("{vertices,edges}")
7779
{
78-
using Catch::Matchers::RangeEquals;
79-
CATCH_CHECK_THAT(graph.vertices(), RangeEquals(vertices));
80-
CATCH_CHECK_THAT(graph.edges(), RangeEquals(edges));
80+
CATCH_CHECK_THAT(graph.vertices(), CM::RangeEquals(vertices));
81+
CATCH_CHECK_THAT(graph.edges(), CM::RangeEquals(edges));
8182
}
8283

8384
CATCH_SECTION("contains_{vertex,edge}")
8485
{
85-
CATCH_CHECK(graph.contains_vertex(0U));
86-
CATCH_CHECK(graph.contains_vertex(3U));
87-
CATCH_CHECK_FALSE(graph.contains_vertex(999U));
88-
CATCH_CHECK_FALSE(graph.contains_vertex(4U));
89-
90-
CATCH_CHECK(graph.contains_edge(0U));
91-
CATCH_CHECK(graph.contains_edge(4U));
92-
CATCH_CHECK_FALSE(graph.contains_edge(999U));
93-
CATCH_CHECK_FALSE(graph.contains_edge(5U));
86+
using ww::testing::ContainsVertex;
87+
CATCH_CHECK_THAT(graph, ContainsVertex(0U));
88+
CATCH_CHECK_THAT(graph, ContainsVertex(3U));
89+
CATCH_CHECK_THAT(graph, !ContainsVertex(999U));
90+
CATCH_CHECK_THAT(graph, !ContainsVertex(4U));
91+
92+
using ww::testing::ContainsEdge;
93+
CATCH_CHECK_THAT(graph, ContainsEdge(0U));
94+
CATCH_CHECK_THAT(graph, ContainsEdge(4U));
95+
CATCH_CHECK_THAT(graph, !ContainsEdge(999U));
96+
CATCH_CHECK_THAT(graph, !ContainsEdge(5U));
9497
}
9598

9699
CATCH_SECTION("outdegree")
@@ -105,8 +108,7 @@ CATCH_TEST_CASE("CSRGraph", "[graph]")
105108
{
106109
using Pair = std::pair<Edge, Vertex>;
107110
const auto outgoing_edges = {Pair(0U, 1U), Pair(1U, 2U), Pair(2U, 3U)};
108-
using Catch::Matchers::RangeEquals;
109-
CATCH_CHECK_THAT(graph.outgoing_edges(0U), RangeEquals(outgoing_edges));
111+
CATCH_CHECK_THAT(graph.outgoing_edges(0U), CM::RangeEquals(outgoing_edges));
110112
}
111113
}
112114

@@ -127,19 +129,18 @@ CATCH_TEST_CASE("CSRGraph (nonconsecutive vertices)", "[graph]")
127129

128130
CATCH_SECTION("{vertices,edges}")
129131
{
130-
using Catch::Matchers::RangeEquals;
131-
132132
const auto vertices = {0U, 1U, 2U, 3U, 4U, 5U};
133-
CATCH_CHECK_THAT(graph.vertices(), RangeEquals(vertices));
134-
135133
const auto edges = {0U, 1U, 2U};
136-
CATCH_CHECK_THAT(graph.edges(), RangeEquals(edges));
134+
135+
CATCH_CHECK_THAT(graph.vertices(), CM::RangeEquals(vertices));
136+
CATCH_CHECK_THAT(graph.edges(), CM::RangeEquals(edges));
137137
}
138138

139139
CATCH_SECTION("contains_vertex")
140140
{
141-
CATCH_CHECK(graph.contains_vertex(3U));
142-
CATCH_CHECK_FALSE(graph.contains_vertex(6U));
141+
using ww::testing::ContainsVertex;
142+
CATCH_CHECK_THAT(graph, ContainsVertex(3U));
143+
CATCH_CHECK_THAT(graph, !ContainsVertex(6U));
143144
}
144145

145146
CATCH_SECTION("outdegree")
@@ -191,13 +192,11 @@ CATCH_TEST_CASE("CSRGraph (unsorted edges)", "[graph]")
191192

192193
CATCH_SECTION("{vertices,edges}")
193194
{
194-
using Catch::Matchers::RangeEquals;
195-
196195
const auto vertices = {0U, 1U, 2U, 3U};
197-
CATCH_CHECK_THAT(graph.vertices(), RangeEquals(vertices));
198-
199196
const auto edges = {0U, 1U, 2U, 3U, 4U};
200-
CATCH_CHECK_THAT(graph.edges(), RangeEquals(edges));
197+
198+
CATCH_CHECK_THAT(graph.vertices(), CM::RangeEquals(vertices));
199+
CATCH_CHECK_THAT(graph.edges(), CM::RangeEquals(edges));
201200
}
202201

203202
CATCH_SECTION("outgoing_edges")
@@ -207,8 +206,7 @@ CATCH_TEST_CASE("CSRGraph (unsorted edges)", "[graph]")
207206
using Pair = std::pair<Edge, Vertex>;
208207
const auto outgoing_edges = {Pair(0U, 1U), Pair(1U, 2U), Pair(2U, 3U)};
209208

210-
using Catch::Matchers::RangeEquals;
211-
CATCH_CHECK_THAT(graph.outgoing_edges(0U), RangeEquals(outgoing_edges));
209+
CATCH_CHECK_THAT(graph.outgoing_edges(0U), CM::RangeEquals(outgoing_edges));
212210
}
213211
}
214212

@@ -251,8 +249,9 @@ CATCH_TEST_CASE("CSRGraph (self loops)", "[graph]")
251249

252250
CATCH_SECTION("contains_vertex")
253251
{
254-
CATCH_CHECK(graph.contains_vertex(0U));
255-
CATCH_CHECK(graph.contains_vertex(2U));
252+
using ww::testing::ContainsVertex;
253+
CATCH_CHECK_THAT(graph, ContainsVertex(0U));
254+
CATCH_CHECK_THAT(graph, ContainsVertex(2U));
256255
}
257256

258257
CATCH_SECTION("outdegree") { CATCH_CHECK(graph.outdegree(1U) == 4U); }
@@ -265,8 +264,7 @@ CATCH_TEST_CASE("CSRGraph (self loops)", "[graph]")
265264
const auto outgoing_edges = {Pair(0U, 0U), Pair(1U, 1U), Pair(2U, 1U),
266265
Pair(3U, 2U)};
267266

268-
using Catch::Matchers::RangeEquals;
269-
CATCH_CHECK_THAT(graph.outgoing_edges(1U), RangeEquals(outgoing_edges));
267+
CATCH_CHECK_THAT(graph.outgoing_edges(1U), CM::RangeEquals(outgoing_edges));
270268
}
271269
}
272270

test/graph/test_dial.cpp

Lines changed: 53 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <cstddef>
2+
#include <limits>
23
#include <memory>
34
#include <type_traits>
45
#include <vector>
@@ -16,27 +17,33 @@
1617
#include <whirlwind/graph/edge_list.hpp>
1718
#include <whirlwind/graph/rectangular_grid_graph.hpp>
1819

20+
#include "../testing/matchers/forest_matchers.hpp"
21+
#include "../testing/matchers/range_matchers.hpp"
22+
1923
namespace {
2024

25+
namespace CM = Catch::Matchers;
2126
namespace ww = whirlwind;
2227

2328
CATCH_TEST_CASE("Dial", "[graph]")
2429
{
25-
using D = int;
26-
using G = ww::CSRGraph<>;
30+
using Distance = int;
31+
using Graph = ww::CSRGraph<>;
32+
33+
constexpr auto max_distance = std::numeric_limits<Distance>::max();
2734

2835
auto edgelist = ww::EdgeList();
2936
edgelist.add_edge(0U, 1U);
3037
edgelist.add_edge(1U, 2U);
3138
edgelist.add_edge(2U, 3U);
3239

33-
const auto graph = G(edgelist);
40+
const auto graph = Graph(edgelist);
3441
const auto num_buckets = 101U;
3542

36-
auto dial = ww::Dial<D, G>(graph, num_buckets);
43+
auto dial = ww::Dial<Distance, Graph>(graph, num_buckets);
3744

38-
using Distance = decltype(dial)::distance_type;
39-
using Graph = decltype(dial)::graph_type;
45+
using Distance_ = decltype(dial)::distance_type;
46+
using Graph_ = decltype(dial)::graph_type;
4047
using Vertex = decltype(dial)::vertex_type;
4148
using Edge = decltype(dial)::edge_type;
4249
using Size = decltype(dial)::size_type;
@@ -45,20 +52,29 @@ CATCH_TEST_CASE("Dial", "[graph]")
4552
{
4653
CATCH_CHECK(std::addressof(dial.graph()) == std::addressof(graph));
4754
CATCH_CHECK(dial.num_buckets() == num_buckets);
55+
4856
CATCH_CHECK(std::size(dial.buckets()) == num_buckets);
49-
using Catch::Matchers::AllMatch;
50-
using Catch::Matchers::IsEmpty;
51-
CATCH_CHECK_THAT(dial.buckets(), AllMatch(IsEmpty()));
57+
CATCH_CHECK_THAT(dial.buckets(), CM::AllMatch(CM::IsEmpty()));
5258
CATCH_CHECK(dial.current_bucket_id() == 0U);
59+
5360
CATCH_CHECK(dial.done());
61+
62+
using ww::testing::WasReachedBy;
63+
CATCH_CHECK_THAT(graph.vertices(), CM::NoneMatch(WasReachedBy(dial)));
64+
65+
const auto distances =
66+
graph.vertices() | ranges::views::transform([&](const auto& vertex) {
67+
return dial.distance_to_vertex(vertex);
68+
});
69+
CATCH_CHECK_THAT(distances, ww::testing::AllEqualTo(max_distance));
5470
}
5571

5672
CATCH_SECTION("{distance,graph,vertex,edge}_type")
5773
{
58-
CATCH_STATIC_REQUIRE((std::is_same_v<Distance, D>));
59-
CATCH_STATIC_REQUIRE((std::is_same_v<Graph, G>));
60-
CATCH_STATIC_REQUIRE((std::is_same_v<Vertex, G::vertex_type>));
61-
CATCH_STATIC_REQUIRE((std::is_same_v<Edge, G::edge_type>));
74+
CATCH_STATIC_REQUIRE((std::is_same_v<Distance_, Distance>));
75+
CATCH_STATIC_REQUIRE((std::is_same_v<Graph_, Graph>));
76+
CATCH_STATIC_REQUIRE((std::is_same_v<Vertex, Graph::vertex_type>));
77+
CATCH_STATIC_REQUIRE((std::is_same_v<Edge, Graph::edge_type>));
6278
CATCH_STATIC_REQUIRE((std::is_same_v<Size, std::size_t>));
6379
}
6480

@@ -90,9 +106,7 @@ CATCH_TEST_CASE("Dial", "[graph]")
90106
bucket.pop();
91107
}
92108

93-
using Catch::Matchers::AllMatch;
94-
using Catch::Matchers::IsEmpty;
95-
CATCH_CHECK_THAT(dial.buckets(), AllMatch(IsEmpty()));
109+
CATCH_CHECK_THAT(dial.buckets(), CM::AllMatch(CM::IsEmpty()));
96110
}
97111

98112
CATCH_SECTION("pop_next_unvisited_vertex")
@@ -106,7 +120,7 @@ CATCH_TEST_CASE("Dial", "[graph]")
106120

107121
const auto [vertex1, distance1] = dial.pop_next_unvisited_vertex();
108122
CATCH_CHECK(dial.current_bucket_id() == 0U);
109-
CATCH_CHECK_THAT(dial.current_bucket(), Catch::Matchers::IsEmpty());
123+
CATCH_CHECK_THAT(dial.current_bucket(), CM::IsEmpty());
110124
CATCH_CHECK(vertex1 == vertex0);
111125
CATCH_CHECK(distance1 == distance0);
112126
}
@@ -120,24 +134,18 @@ CATCH_TEST_CASE("Dial", "[graph]")
120134

121135
CATCH_CHECK(dial.current_bucket_id() == 0U);
122136
CATCH_CHECK(std::size(dial.current_bucket()) == std::size(sources));
137+
CATCH_CHECK_THAT(sources, CM::AllMatch(ww::testing::WasReachedBy(dial)));
123138

124-
const auto has_reached_sources =
125-
sources | ranges::views::transform([&](const auto& source) {
126-
return dial.has_reached_vertex(source);
127-
});
128-
CATCH_CHECK_THAT(has_reached_sources, Catch::Matchers::AllTrue());
129-
130-
using Catch::Matchers::Contains;
131139
const auto [vertex0, distance0] = dial.pop_next_unvisited_vertex();
132-
CATCH_CHECK_THAT(sources, Contains(vertex0));
140+
CATCH_CHECK_THAT(sources, CM::Contains(vertex0));
133141
CATCH_CHECK(distance0 == 0);
134142

135143
const auto [vertex1, distance1] = dial.pop_next_unvisited_vertex();
136-
CATCH_CHECK_THAT(sources, Contains(vertex1));
144+
CATCH_CHECK_THAT(sources, CM::Contains(vertex1));
137145
CATCH_CHECK(distance1 == 0);
138146

139147
CATCH_CHECK(dial.current_bucket_id() == 0U);
140-
CATCH_CHECK_THAT(dial.current_bucket(), Catch::Matchers::IsEmpty());
148+
CATCH_CHECK_THAT(dial.current_bucket(), CM::IsEmpty());
141149
CATCH_CHECK(vertex0 != vertex1);
142150
}
143151

@@ -147,19 +155,20 @@ CATCH_TEST_CASE("Dial", "[graph]")
147155
const auto distance0 = 0;
148156
dial.add_source(vertex0);
149157

150-
CATCH_CHECK_FALSE(dial.has_visited_vertex(vertex0));
158+
using ww::testing::WasVisitedBy;
159+
CATCH_CHECK_THAT(vertex0, !WasVisitedBy(dial));
151160
dial.visit_vertex(vertex0, distance0);
152-
CATCH_CHECK(dial.has_visited_vertex(vertex0));
161+
CATCH_CHECK_THAT(vertex0, WasVisitedBy(dial));
153162
CATCH_CHECK(dial.distance_to_vertex(vertex0) == distance0);
154163

155164
const auto edge = 0U;
156165
const auto vertex1 = 1U;
157166
const auto distance1 = 10;
158167
dial.relax_edge(edge, vertex0, vertex1, distance1);
159-
CATCH_CHECK_FALSE(dial.has_visited_vertex(vertex1));
168+
CATCH_CHECK_THAT(vertex1, !WasVisitedBy(dial));
160169

161170
dial.visit_vertex(vertex1, distance1);
162-
CATCH_CHECK(dial.has_visited_vertex(vertex1));
171+
CATCH_CHECK_THAT(vertex1, WasVisitedBy(dial));
163172
CATCH_CHECK(dial.distance_to_vertex(vertex1) == distance1);
164173
}
165174

@@ -178,8 +187,8 @@ CATCH_TEST_CASE("Dial", "[graph]")
178187
const auto length = 10;
179188
dial.relax_edge(edge, tail, head, distance + length);
180189

181-
CATCH_CHECK(dial.has_reached_vertex(head));
182-
CATCH_CHECK_FALSE(dial.has_visited_vertex(head));
190+
CATCH_CHECK_THAT(head, ww::testing::WasReachedBy(dial));
191+
CATCH_CHECK_THAT(head, !ww::testing::WasVisitedBy(dial));
183192
CATCH_CHECK(dial.distance_to_vertex(head) == distance + length);
184193

185194
const auto bucket_id = dial.get_bucket_id(distance + length);
@@ -216,11 +225,19 @@ CATCH_TEST_CASE("Dial", "[graph]")
216225
}
217226

218227
dial.reset();
219-
using Catch::Matchers::AllMatch;
220-
using Catch::Matchers::IsEmpty;
221-
CATCH_CHECK_THAT(dial.buckets(), AllMatch(IsEmpty()));
228+
229+
CATCH_CHECK_THAT(dial.buckets(), CM::AllMatch(CM::IsEmpty()));
222230
CATCH_CHECK(dial.current_bucket_id() == 0U);
223231
CATCH_CHECK(dial.done());
232+
233+
using ww::testing::WasReachedBy;
234+
CATCH_CHECK_THAT(graph.vertices(), CM::NoneMatch(WasReachedBy(dial)));
235+
236+
const auto distances =
237+
graph.vertices() | ranges::views::transform([&](const auto& vertex) {
238+
return dial.distance_to_vertex(vertex);
239+
});
240+
CATCH_CHECK_THAT(distances, ww::testing::AllEqualTo(max_distance));
224241
}
225242
}
226243

0 commit comments

Comments
 (0)