Skip to content

Commit

Permalink
Add custom Catch2 matchers
Browse files Browse the repository at this point in the history
  • Loading branch information
gmgunter committed Aug 13, 2024
1 parent 7d0bd7a commit 5d133ff
Show file tree
Hide file tree
Showing 11 changed files with 459 additions and 198 deletions.
5 changes: 3 additions & 2 deletions test/common/test_version.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

namespace {

namespace CM = Catch::Matchers;

CATCH_TEST_CASE("WHIRLWIND_VERSION_EPOCH", "[version]")
{
using T = decltype(WHIRLWIND_VERSION_EPOCH);
Expand All @@ -24,8 +26,7 @@ CATCH_TEST_CASE("WHIRLWIND_VERSION_PATCH", "[version]")

CATCH_TEST_CASE("WHIRLWIND_VERSION_STRING", "[version]")
{
using Catch::Matchers::Matches;
CATCH_CHECK_THAT(WHIRLWIND_VERSION_STRING, Matches(R"(^\d{8}\.\d+$)"));
CATCH_CHECK_THAT(WHIRLWIND_VERSION_STRING, CM::Matches(R"(^\d{8}\.\d+$)"));
}

} // namespace
66 changes: 32 additions & 34 deletions test/graph/test_csr_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
#include <whirlwind/graph/csr_graph.hpp>
#include <whirlwind/graph/edge_list.hpp>

#include "../testing/matchers/graph_matchers.hpp"
#include "../testing/string_conversions.hpp" // IWYU pragma: keep

namespace {

namespace CM = Catch::Matchers;
namespace ww = whirlwind;

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

CATCH_SECTION("contains_{vertex,edge}")
{
CATCH_CHECK_FALSE(graph.contains_vertex(0U));
CATCH_CHECK_FALSE(graph.contains_edge(0U));
CATCH_CHECK_THAT(graph, !ww::testing::ContainsVertex(0U));
CATCH_CHECK_THAT(graph, !ww::testing::ContainsEdge(0U));
}
}

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

CATCH_SECTION("{vertices,edges}")
{
using Catch::Matchers::RangeEquals;
CATCH_CHECK_THAT(graph.vertices(), RangeEquals(vertices));
CATCH_CHECK_THAT(graph.edges(), RangeEquals(edges));
CATCH_CHECK_THAT(graph.vertices(), CM::RangeEquals(vertices));
CATCH_CHECK_THAT(graph.edges(), CM::RangeEquals(edges));
}

CATCH_SECTION("contains_{vertex,edge}")
{
CATCH_CHECK(graph.contains_vertex(0U));
CATCH_CHECK(graph.contains_vertex(3U));
CATCH_CHECK_FALSE(graph.contains_vertex(999U));
CATCH_CHECK_FALSE(graph.contains_vertex(4U));

CATCH_CHECK(graph.contains_edge(0U));
CATCH_CHECK(graph.contains_edge(4U));
CATCH_CHECK_FALSE(graph.contains_edge(999U));
CATCH_CHECK_FALSE(graph.contains_edge(5U));
using ww::testing::ContainsVertex;
CATCH_CHECK_THAT(graph, ContainsVertex(0U));
CATCH_CHECK_THAT(graph, ContainsVertex(3U));
CATCH_CHECK_THAT(graph, !ContainsVertex(999U));
CATCH_CHECK_THAT(graph, !ContainsVertex(4U));

using ww::testing::ContainsEdge;
CATCH_CHECK_THAT(graph, ContainsEdge(0U));
CATCH_CHECK_THAT(graph, ContainsEdge(4U));
CATCH_CHECK_THAT(graph, !ContainsEdge(999U));
CATCH_CHECK_THAT(graph, !ContainsEdge(5U));
}

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

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

CATCH_SECTION("{vertices,edges}")
{
using Catch::Matchers::RangeEquals;

const auto vertices = {0U, 1U, 2U, 3U, 4U, 5U};
CATCH_CHECK_THAT(graph.vertices(), RangeEquals(vertices));

const auto edges = {0U, 1U, 2U};
CATCH_CHECK_THAT(graph.edges(), RangeEquals(edges));

CATCH_CHECK_THAT(graph.vertices(), CM::RangeEquals(vertices));
CATCH_CHECK_THAT(graph.edges(), CM::RangeEquals(edges));
}

CATCH_SECTION("contains_vertex")
{
CATCH_CHECK(graph.contains_vertex(3U));
CATCH_CHECK_FALSE(graph.contains_vertex(6U));
using ww::testing::ContainsVertex;
CATCH_CHECK_THAT(graph, ContainsVertex(3U));
CATCH_CHECK_THAT(graph, !ContainsVertex(6U));
}

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

CATCH_SECTION("{vertices,edges}")
{
using Catch::Matchers::RangeEquals;

const auto vertices = {0U, 1U, 2U, 3U};
CATCH_CHECK_THAT(graph.vertices(), RangeEquals(vertices));

const auto edges = {0U, 1U, 2U, 3U, 4U};
CATCH_CHECK_THAT(graph.edges(), RangeEquals(edges));

CATCH_CHECK_THAT(graph.vertices(), CM::RangeEquals(vertices));
CATCH_CHECK_THAT(graph.edges(), CM::RangeEquals(edges));
}

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

using Catch::Matchers::RangeEquals;
CATCH_CHECK_THAT(graph.outgoing_edges(0U), RangeEquals(outgoing_edges));
CATCH_CHECK_THAT(graph.outgoing_edges(0U), CM::RangeEquals(outgoing_edges));
}
}

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

CATCH_SECTION("contains_vertex")
{
CATCH_CHECK(graph.contains_vertex(0U));
CATCH_CHECK(graph.contains_vertex(2U));
using ww::testing::ContainsVertex;
CATCH_CHECK_THAT(graph, ContainsVertex(0U));
CATCH_CHECK_THAT(graph, ContainsVertex(2U));
}

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

using Catch::Matchers::RangeEquals;
CATCH_CHECK_THAT(graph.outgoing_edges(1U), RangeEquals(outgoing_edges));
CATCH_CHECK_THAT(graph.outgoing_edges(1U), CM::RangeEquals(outgoing_edges));
}
}

Expand Down
89 changes: 53 additions & 36 deletions test/graph/test_dial.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <cstddef>
#include <limits>
#include <memory>
#include <type_traits>
#include <vector>
Expand All @@ -16,27 +17,33 @@
#include <whirlwind/graph/edge_list.hpp>
#include <whirlwind/graph/rectangular_grid_graph.hpp>

#include "../testing/matchers/forest_matchers.hpp"
#include "../testing/matchers/range_matchers.hpp"

namespace {

namespace CM = Catch::Matchers;
namespace ww = whirlwind;

CATCH_TEST_CASE("Dial", "[graph]")
{
using D = int;
using G = ww::CSRGraph<>;
using Distance = int;
using Graph = ww::CSRGraph<>;

constexpr auto max_distance = std::numeric_limits<Distance>::max();

auto edgelist = ww::EdgeList();
edgelist.add_edge(0U, 1U);
edgelist.add_edge(1U, 2U);
edgelist.add_edge(2U, 3U);

const auto graph = G(edgelist);
const auto graph = Graph(edgelist);
const auto num_buckets = 101U;

auto dial = ww::Dial<D, G>(graph, num_buckets);
auto dial = ww::Dial<Distance, Graph>(graph, num_buckets);

using Distance = decltype(dial)::distance_type;
using Graph = decltype(dial)::graph_type;
using Distance_ = decltype(dial)::distance_type;
using Graph_ = decltype(dial)::graph_type;
using Vertex = decltype(dial)::vertex_type;
using Edge = decltype(dial)::edge_type;
using Size = decltype(dial)::size_type;
Expand All @@ -45,20 +52,29 @@ CATCH_TEST_CASE("Dial", "[graph]")
{
CATCH_CHECK(std::addressof(dial.graph()) == std::addressof(graph));
CATCH_CHECK(dial.num_buckets() == num_buckets);

CATCH_CHECK(std::size(dial.buckets()) == num_buckets);
using Catch::Matchers::AllMatch;
using Catch::Matchers::IsEmpty;
CATCH_CHECK_THAT(dial.buckets(), AllMatch(IsEmpty()));
CATCH_CHECK_THAT(dial.buckets(), CM::AllMatch(CM::IsEmpty()));
CATCH_CHECK(dial.current_bucket_id() == 0U);

CATCH_CHECK(dial.done());

using ww::testing::WasReachedBy;
CATCH_CHECK_THAT(graph.vertices(), CM::NoneMatch(WasReachedBy(dial)));

const auto distances =
graph.vertices() | ranges::views::transform([&](const auto& vertex) {
return dial.distance_to_vertex(vertex);
});
CATCH_CHECK_THAT(distances, ww::testing::AllEqualTo(max_distance));
}

CATCH_SECTION("{distance,graph,vertex,edge}_type")
{
CATCH_STATIC_REQUIRE((std::is_same_v<Distance, D>));
CATCH_STATIC_REQUIRE((std::is_same_v<Graph, G>));
CATCH_STATIC_REQUIRE((std::is_same_v<Vertex, G::vertex_type>));
CATCH_STATIC_REQUIRE((std::is_same_v<Edge, G::edge_type>));
CATCH_STATIC_REQUIRE((std::is_same_v<Distance_, Distance>));
CATCH_STATIC_REQUIRE((std::is_same_v<Graph_, Graph>));
CATCH_STATIC_REQUIRE((std::is_same_v<Vertex, Graph::vertex_type>));
CATCH_STATIC_REQUIRE((std::is_same_v<Edge, Graph::edge_type>));
CATCH_STATIC_REQUIRE((std::is_same_v<Size, std::size_t>));
}

Expand Down Expand Up @@ -90,9 +106,7 @@ CATCH_TEST_CASE("Dial", "[graph]")
bucket.pop();
}

using Catch::Matchers::AllMatch;
using Catch::Matchers::IsEmpty;
CATCH_CHECK_THAT(dial.buckets(), AllMatch(IsEmpty()));
CATCH_CHECK_THAT(dial.buckets(), CM::AllMatch(CM::IsEmpty()));
}

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

const auto [vertex1, distance1] = dial.pop_next_unvisited_vertex();
CATCH_CHECK(dial.current_bucket_id() == 0U);
CATCH_CHECK_THAT(dial.current_bucket(), Catch::Matchers::IsEmpty());
CATCH_CHECK_THAT(dial.current_bucket(), CM::IsEmpty());
CATCH_CHECK(vertex1 == vertex0);
CATCH_CHECK(distance1 == distance0);
}
Expand All @@ -120,24 +134,18 @@ CATCH_TEST_CASE("Dial", "[graph]")

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

const auto has_reached_sources =
sources | ranges::views::transform([&](const auto& source) {
return dial.has_reached_vertex(source);
});
CATCH_CHECK_THAT(has_reached_sources, Catch::Matchers::AllTrue());

using Catch::Matchers::Contains;
const auto [vertex0, distance0] = dial.pop_next_unvisited_vertex();
CATCH_CHECK_THAT(sources, Contains(vertex0));
CATCH_CHECK_THAT(sources, CM::Contains(vertex0));
CATCH_CHECK(distance0 == 0);

const auto [vertex1, distance1] = dial.pop_next_unvisited_vertex();
CATCH_CHECK_THAT(sources, Contains(vertex1));
CATCH_CHECK_THAT(sources, CM::Contains(vertex1));
CATCH_CHECK(distance1 == 0);

CATCH_CHECK(dial.current_bucket_id() == 0U);
CATCH_CHECK_THAT(dial.current_bucket(), Catch::Matchers::IsEmpty());
CATCH_CHECK_THAT(dial.current_bucket(), CM::IsEmpty());
CATCH_CHECK(vertex0 != vertex1);
}

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

CATCH_CHECK_FALSE(dial.has_visited_vertex(vertex0));
using ww::testing::WasVisitedBy;
CATCH_CHECK_THAT(vertex0, !WasVisitedBy(dial));
dial.visit_vertex(vertex0, distance0);
CATCH_CHECK(dial.has_visited_vertex(vertex0));
CATCH_CHECK_THAT(vertex0, WasVisitedBy(dial));
CATCH_CHECK(dial.distance_to_vertex(vertex0) == distance0);

const auto edge = 0U;
const auto vertex1 = 1U;
const auto distance1 = 10;
dial.relax_edge(edge, vertex0, vertex1, distance1);
CATCH_CHECK_FALSE(dial.has_visited_vertex(vertex1));
CATCH_CHECK_THAT(vertex1, !WasVisitedBy(dial));

dial.visit_vertex(vertex1, distance1);
CATCH_CHECK(dial.has_visited_vertex(vertex1));
CATCH_CHECK_THAT(vertex1, WasVisitedBy(dial));
CATCH_CHECK(dial.distance_to_vertex(vertex1) == distance1);
}

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

CATCH_CHECK(dial.has_reached_vertex(head));
CATCH_CHECK_FALSE(dial.has_visited_vertex(head));
CATCH_CHECK_THAT(head, ww::testing::WasReachedBy(dial));
CATCH_CHECK_THAT(head, !ww::testing::WasVisitedBy(dial));
CATCH_CHECK(dial.distance_to_vertex(head) == distance + length);

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

dial.reset();
using Catch::Matchers::AllMatch;
using Catch::Matchers::IsEmpty;
CATCH_CHECK_THAT(dial.buckets(), AllMatch(IsEmpty()));

CATCH_CHECK_THAT(dial.buckets(), CM::AllMatch(CM::IsEmpty()));
CATCH_CHECK(dial.current_bucket_id() == 0U);
CATCH_CHECK(dial.done());

using ww::testing::WasReachedBy;
CATCH_CHECK_THAT(graph.vertices(), CM::NoneMatch(WasReachedBy(dial)));

const auto distances =
graph.vertices() | ranges::views::transform([&](const auto& vertex) {
return dial.distance_to_vertex(vertex);
});
CATCH_CHECK_THAT(distances, ww::testing::AllEqualTo(max_distance));
}
}

Expand Down
Loading

0 comments on commit 5d133ff

Please sign in to comment.