#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::vector>& 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); assert_equal(4u, targets.size(), __FILE__, __LINE__); assert_equal("target1"s, targets[0].config.target, __FILE__, __LINE__); assert_equal("target2"s, targets[1].config.target, __FILE__, __LINE__); assert_equal("target3"s, targets[2].config.target, __FILE__, __LINE__); assert_equal("target4"s, targets[3].config.target, __FILE__, __LINE__); assert_equal("test"s, targets[0].path, __FILE__, __LINE__); assert_equal("test"s, targets[1].path, __FILE__, __LINE__); assert_equal("test"s, targets[2].path, __FILE__, __LINE__); assert_equal("test"s, targets[3].path, __FILE__, __LINE__); } void getTasks_test() { using namespace std::string_literals; ctor::settings settings{ .builddir = "foo" }; { auto tasks = getTasks(settings); assert_equal(6u, tasks.size(), __FILE__, __LINE__); // Note: count() is used here because the order doesn't matter assert_equal(1u, count(tasks, "target1"s), __FILE__, __LINE__); assert_equal(1u, count(tasks, "target2"s), __FILE__, __LINE__); assert_equal(1u, count(tasks, "target3"s), __FILE__, __LINE__); assert_equal(1u, count(tasks, "target4"s), __FILE__, __LINE__); assert_equal(1u, count(tasks, "test/target1-foo_cc.o"s), __FILE__, __LINE__); assert_equal(1u, count(tasks, "test/target1-bar_c.o"s), __FILE__, __LINE__); } { auto tasks = getTasks(settings, {"target1", "target3"}); assert_equal(4u, tasks.size(), __FILE__, __LINE__); assert_equal(1u, count(tasks, "target1"s), __FILE__, __LINE__); assert_equal(1u, count(tasks, "target3"s), __FILE__, __LINE__); assert_equal(1u, count(tasks, "test/target1-foo_cc.o"s), __FILE__, __LINE__); assert_equal(1u, count(tasks, "test/target1-bar_c.o"s), __FILE__, __LINE__); } { auto tasks = getTasks(settings, {"no-such-target"}); assert_equal(0u, tasks.size(), __FILE__, __LINE__); } } void getNextTask_test() { using namespace std::string_literals; ctor::settings settings{}; { // Zero (Empty) std::vector> allTasks; std::vector> dirtyTasks; for(auto& task : dirtyTasks) { assert_equal(0, task->registerDepTasks(allTasks), __FILE__, __LINE__); } assert_equal(nullptr, getNextTask(allTasks, dirtyTasks), __FILE__, __LINE__); } { // Zero (One task, no dirty) auto task1 = std::make_shared("task1", false); std::vector> allTasks; allTasks.push_back(task1); std::vector> dirtyTasks; for(auto& task : dirtyTasks) { assert_equal(0, task->registerDepTasks(allTasks), __FILE__, __LINE__); } assert_equal(nullptr, getNextTask(allTasks, dirtyTasks), __FILE__, __LINE__); } { // One (One task, one dirty) auto task1 = std::make_shared("task1", true); std::vector> allTasks; allTasks.push_back(task1); std::vector> dirtyTasks; dirtyTasks.push_back(task1); for(auto& task : dirtyTasks) { assert_equal(0, task->registerDepTasks(allTasks), __FILE__, __LINE__); } assert_equal(task1, getNextTask(allTasks, dirtyTasks), __FILE__, __LINE__); assert_equal(0u, dirtyTasks.size(), __FILE__, __LINE__); } { // One (Two tasks, one dirty) auto task1 = std::make_shared("task1", false); auto task2 = std::make_shared("task2", true); std::vector> allTasks; allTasks.push_back(task1); allTasks.push_back(task2); std::vector> dirtyTasks; dirtyTasks.push_back(task2); for(auto& task : dirtyTasks) { assert_equal(0, task->registerDepTasks(allTasks), __FILE__, __LINE__); } assert_equal(task2, getNextTask(allTasks, dirtyTasks), __FILE__, __LINE__); assert_equal(0u, dirtyTasks.size(), __FILE__, __LINE__); } { // 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::vector> allTasks; allTasks.push_back(task1); allTasks.push_back(task2); std::vector> dirtyTasks; dirtyTasks.push_back(task2); for(auto& task : dirtyTasks) { assert_equal(0, task->registerDepTasks(allTasks), __FILE__, __LINE__); } assert_equal(task2, getNextTask(allTasks, dirtyTasks), __FILE__, __LINE__); assert_equal(0u, dirtyTasks.size(), __FILE__, __LINE__); } { // 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::vector> allTasks; allTasks.push_back(task2); allTasks.push_back(task1); std::vector> dirtyTasks; dirtyTasks.push_back(task2); dirtyTasks.push_back(task1); for(auto& task : dirtyTasks) { assert_equal(0, task->registerDepTasks(allTasks), __FILE__, __LINE__); } assert_equal(task1, getNextTask(allTasks, dirtyTasks), __FILE__, __LINE__); assert_equal(1u, dirtyTasks.size(), __FILE__, __LINE__); } } }; // Registers the fixture into the 'registry' static TasksTest test;