#include #include #include namespace { ctor::build_configurations ctorTestConfigs1(const ctor::settings&) { return { { .target = "target1", .sources = {"foo.cc", "bar.c"}, }, { .target = "target2", }, }; } ctor::build_configurations ctorTestConfigs2(const ctor::settings&) { return { { .target = "target3", }, { .target = "target4", }, }; } } REG(ctorTestConfigs1); REG(ctorTestConfigs2); std::size_t count(const std::set>& tasks, const std::string& name) { auto cnt{0u}; for(const auto& task : tasks) { if(task->target() == name) { cnt++; } } return cnt; } class TestTask : public Task { public: TestTask(const std::string& name, bool dirty, const std::vector& deps = {}) : Task({}, {}, {}) , task_name(name) , task_dirty(dirty) , task_deps(deps) { } std::string name() const override { return task_name; } int clean() override { return 0; } std::vector depends() const override { return task_deps; } std::string target() const override { return task_name; } std::filesystem::path targetFile() const override { return {}; } bool derived() const override { return false; } bool dirtyInner() override { return task_dirty; } private: std::string task_name; bool task_dirty; std::vector task_deps; }; class TasksTest : public uUnit { public: TasksTest() { uTEST(TasksTest::getTargets_test); uTEST(TasksTest::getTasks_test); uTEST(TasksTest::getNextTask_test); } void getTargets_test() { using namespace std::string_literals; ctor::settings settings{}; const auto& targets = getTargets(settings); uASSERT_EQUAL(4u, targets.size()); uASSERT_EQUAL("target1"s, targets[0].config.target); uASSERT_EQUAL("target2"s, targets[1].config.target); uASSERT_EQUAL("target3"s, targets[2].config.target); uASSERT_EQUAL("target4"s, targets[3].config.target); uASSERT_EQUAL("test"s, targets[0].path); uASSERT_EQUAL("test"s, targets[1].path); uASSERT_EQUAL("test"s, targets[2].path); uASSERT_EQUAL("test"s, targets[3].path); } void getTasks_test() { using namespace std::string_literals; ctor::settings settings{ .builddir = "foo" }; { auto tasks = getTasks(settings); uASSERT_EQUAL(6u, tasks.size()); // Note: count() is used here because the order of // std::set> is not deterministic. uASSERT_EQUAL(1u, count(tasks, "target1"s)); uASSERT_EQUAL(1u, count(tasks, "target2"s)); uASSERT_EQUAL(1u, count(tasks, "target3"s)); uASSERT_EQUAL(1u, count(tasks, "target4"s)); uASSERT_EQUAL(1u, count(tasks, "test/target1-foo_cc.o"s)); uASSERT_EQUAL(1u, count(tasks, "test/target1-bar_c.o"s)); } { auto tasks = getTasks(settings, {"target1", "target3"}); uASSERT_EQUAL(4u, tasks.size()); uASSERT_EQUAL(1u, count(tasks, "target1"s)); uASSERT_EQUAL(1u, count(tasks, "target3"s)); uASSERT_EQUAL(1u, count(tasks, "test/target1-foo_cc.o"s)); uASSERT_EQUAL(1u, count(tasks, "test/target1-bar_c.o"s)); } { auto tasks = getTasks(settings, {"no-such-target"}); uASSERT_EQUAL(0u, tasks.size()); } } void getNextTask_test() { using namespace std::string_literals; ctor::settings settings{}; { // Zero (Empty) std::set> allTasks; std::set> dirtyTasks; for(auto& task : dirtyTasks) { uASSERT_EQUAL(0, task->registerDepTasks(allTasks)); } uASSERT_EQUAL(nullptr, getNextTask(allTasks, dirtyTasks)); } { // Zero (One task, no dirty) auto task1 = std::make_shared("task1", false); std::set> allTasks; allTasks.insert(task1); std::set> dirtyTasks; for(auto& task : dirtyTasks) { uASSERT_EQUAL(0, task->registerDepTasks(allTasks)); } uASSERT_EQUAL(nullptr, getNextTask(allTasks, dirtyTasks)); } { // One (One task, one dirty) auto task1 = std::make_shared("task1", true); std::set> allTasks; allTasks.insert(task1); std::set> dirtyTasks; dirtyTasks.insert(task1); for(auto& task : dirtyTasks) { uASSERT_EQUAL(0, task->registerDepTasks(allTasks)); } uASSERT_EQUAL(task1, getNextTask(allTasks, dirtyTasks)); uASSERT_EQUAL(0u, dirtyTasks.size()); } { // One (Two tasks, one dirty) auto task1 = std::make_shared("task1", false); auto task2 = std::make_shared("task2", true); std::set> allTasks; allTasks.insert(task1); allTasks.insert(task2); std::set> dirtyTasks; dirtyTasks.insert(task2); for(auto& task : dirtyTasks) { uASSERT_EQUAL(0, task->registerDepTasks(allTasks)); } uASSERT_EQUAL(task2, getNextTask(allTasks, dirtyTasks)); uASSERT_EQUAL(0u, dirtyTasks.size()); } { // One (Two tasks, one dirty which depends on the other) auto task1 = std::make_shared("task1", false); std::vector deps = {"task1"}; auto task2 = std::make_shared("task2", true, deps); std::set> allTasks; allTasks.insert(task1); allTasks.insert(task2); std::set> dirtyTasks; dirtyTasks.insert(task2); for(auto& task : dirtyTasks) { uASSERT_EQUAL(0, task->registerDepTasks(allTasks)); } uASSERT_EQUAL(task2, getNextTask(allTasks, dirtyTasks)); uASSERT_EQUAL(0u, dirtyTasks.size()); } { // One (Two tasks, Both dirty, one depends on the other) auto task1 = std::make_shared("task1", true); std::vector deps = {"task1"}; auto task2 = std::make_shared("task2", true, deps); std::set> allTasks; allTasks.insert(task2); allTasks.insert(task1); std::set> dirtyTasks; dirtyTasks.insert(task2); dirtyTasks.insert(task1); for(auto& task : dirtyTasks) { uASSERT_EQUAL(0, task->registerDepTasks(allTasks)); } uASSERT_EQUAL(task1, getNextTask(allTasks, dirtyTasks)); uASSERT_EQUAL(1u, dirtyTasks.size()); } } }; // Registers the fixture into the 'registry' static TasksTest test;