#include "nix/util/closure.hh" #include namespace nix { using namespace std; map> testGraph = { {"A", {"B", "C", "G"}}, {"B", {"A"}}, // Loops back to A {"C", {"F"}}, // Indirect reference {"D", {"A"}}, // Not reachable, but has backreferences {"E", {}}, // Just not reachable {"F", {}}, {"G", {"G"}}, // Self reference }; TEST(closure, correctClosure) { set aClosure; set expectedClosure = {"A", "B", "C", "F", "G"}; computeClosure( {"A"}, aClosure, [&](const string currentNode, function> &)> processEdges) { promise> promisedNodes; promisedNodes.set_value(testGraph[currentNode]); processEdges(promisedNodes); }); ASSERT_EQ(aClosure, expectedClosure); } TEST(closure, properlyHandlesDirectExceptions) { struct TestExn {}; set aClosure; EXPECT_THROW( computeClosure( {"A"}, aClosure, [&](const string currentNode, function> &)> processEdges) { throw TestExn(); }), TestExn); } TEST(closure, properlyHandlesExceptionsInPromise) { struct TestExn {}; set aClosure; EXPECT_THROW( computeClosure( {"A"}, aClosure, [&](const string currentNode, function> &)> processEdges) { promise> promise; try { throw TestExn(); } catch (...) { promise.set_exception(std::current_exception()); } processEdges(promise); }), TestExn); } } // namespace nix