71 lines
1.8 KiB
C++
71 lines
1.8 KiB
C++
|
#include "closure.hh"
|
||
|
#include <gtest/gtest.h>
|
||
|
|
||
|
namespace nix {
|
||
|
|
||
|
using namespace std;
|
||
|
|
||
|
map<string, set<string>> 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<string> aClosure;
|
||
|
set<string> expectedClosure = {"A", "B", "C", "F", "G"};
|
||
|
computeClosure<string>(
|
||
|
{"A"},
|
||
|
aClosure,
|
||
|
[&](const string currentNode, function<void(promise<set<string>> &)> processEdges) {
|
||
|
promise<set<string>> promisedNodes;
|
||
|
promisedNodes.set_value(testGraph[currentNode]);
|
||
|
processEdges(promisedNodes);
|
||
|
}
|
||
|
);
|
||
|
|
||
|
ASSERT_EQ(aClosure, expectedClosure);
|
||
|
}
|
||
|
|
||
|
TEST(closure, properlyHandlesDirectExceptions) {
|
||
|
struct TestExn {};
|
||
|
set<string> aClosure;
|
||
|
EXPECT_THROW(
|
||
|
computeClosure<string>(
|
||
|
{"A"},
|
||
|
aClosure,
|
||
|
[&](const string currentNode, function<void(promise<set<string>> &)> processEdges) {
|
||
|
throw TestExn();
|
||
|
}
|
||
|
),
|
||
|
TestExn
|
||
|
);
|
||
|
}
|
||
|
|
||
|
TEST(closure, properlyHandlesExceptionsInPromise) {
|
||
|
struct TestExn {};
|
||
|
set<string> aClosure;
|
||
|
EXPECT_THROW(
|
||
|
computeClosure<string>(
|
||
|
{"A"},
|
||
|
aClosure,
|
||
|
[&](const string currentNode, function<void(promise<set<string>> &)> processEdges) {
|
||
|
promise<set<string>> promise;
|
||
|
try {
|
||
|
throw TestExn();
|
||
|
} catch (...) {
|
||
|
promise.set_exception(std::current_exception());
|
||
|
}
|
||
|
processEdges(promise);
|
||
|
}
|
||
|
),
|
||
|
TestExn
|
||
|
);
|
||
|
}
|
||
|
|
||
|
}
|