#include #include #include "daggy/DAG.hpp" TEST_CASE("dag_construction", "[dag]") { daggy::DAG dag; REQUIRE(dag.size() == 0); REQUIRE(dag.empty()); REQUIRE_NOTHROW(dag.addVertex(0, 0)); for (size_t i = 1; i < 10; ++i) { dag.addVertex(i, i); REQUIRE(dag.hasVertex(i)); REQUIRE(dag.getVertex(i).data == i); dag.addEdge(i - 1, i); } REQUIRE(dag.size() == 10); REQUIRE(!dag.empty()); // Cannot add an edge that would result in a cycle dag.addEdge(9, 5); REQUIRE(!dag.isValid()); // Bounds checking SECTION("addEdge Bounds Checking") { REQUIRE_THROWS(dag.addEdge(20, 0)); REQUIRE_THROWS(dag.addEdge(0, 20)); } } TEST_CASE("dag_traversal", "[dag]") { daggy::DAG dag; const int N_VERTICES = 10; for (int i = 0; i < N_VERTICES; ++i) { dag.addVertex(i, i); } /* 0 ---------------------\ 1 ---------- \ \ /-----> 8 2 ---- 3 ---- > 5 -------> 6 -----> 7 4 -------------------------------/ \-----> 9 */ std::vector> edges{{0, 6}, {1, 5}, {5, 6}, {6, 7}, {2, 3}, {3, 5}, {4, 7}, {7, 8}, {7, 9}}; for (auto const [from, to] : edges) { dag.addEdge(from, to); } SECTION("Basic Traversal") { dag.reset(); std::vector visitOrder(N_VERTICES); size_t i = 0; while (!dag.allVisited()) { const auto v = dag.visitNext().value(); dag.completeVisit(v.first); visitOrder[v.first] = i; ++i; } // Ensure visit order is preserved for (auto const [from, to] : edges) { REQUIRE(visitOrder[from] <= visitOrder[to]); } } SECTION("Iteration") { size_t nVisited = 0; dag.forEach([&](auto &k) { (void)k; ++nVisited; }); REQUIRE(nVisited == dag.size()); } }