diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/ctor.cc | 91 | ||||
-rw-r--r-- | test/paths.h | 15 | ||||
-rw-r--r-- | test/source_type_test.cc | 76 | ||||
-rw-r--r-- | test/suite/ctor_files/ctor.cc.bar | 62 | ||||
-rw-r--r-- | test/suite/ctor_files/ctor.cc.base | 62 | ||||
-rw-r--r-- | test/suite/ctor_files/ctor.cc.multi | 64 | ||||
-rw-r--r-- | test/suite/foobar.h | 3 | ||||
-rw-r--r-- | test/suite/hello.cc | 6 | ||||
-rwxr-xr-x | test/suite/test.sh | 104 | ||||
-rw-r--r-- | test/tasks_test.cc | 106 | ||||
-rw-r--r-- | test/testmain.cc | 36 | ||||
-rw-r--r-- | test/tools_test.cc | 212 | ||||
m--------- | test/uunit | 0 |
13 files changed, 775 insertions, 62 deletions
diff --git a/test/ctor.cc b/test/ctor.cc index 8080d61..9b690a2 100644 --- a/test/ctor.cc +++ b/test/ctor.cc @@ -5,7 +5,7 @@ namespace { -BuildConfigurations ctorTestConfigs() +BuildConfigurations ctorTestConfigs(const Settings& settings) { return { @@ -14,13 +14,16 @@ BuildConfigurations ctorTestConfigs() .target = "execute_test", .sources = { "execute_test.cc", - "uunit/uunit.cc", + "testmain.cc", "../src/execute.cc", }, - .cxxflags = { - "-std=c++17", "-O3", "-s", "-Wall", "-Werror", - "-I../src", "-Iuunit", - "-DOUTPUT=\"execute\"", + .flags = { + .cxxflags = { + "-std=c++20", "-O3", "-s", "-Wall", "-Werror", + "-I../src", "-Iuunit", + "-DOUTPUT=\"execute\"", + }, + .ldflags = { "-pthread" }, }, }, { @@ -28,13 +31,77 @@ BuildConfigurations ctorTestConfigs() .target = "tasks_test", .sources = { "tasks_test.cc", - "uunit/uunit.cc", + "testmain.cc", }, - .depends = {"libctor.a"}, - .cxxflags = { - "-std=c++17", "-O3", "-s", "-Wall", "-Werror", - "-I../src", "-Iuunit", - "-DOUTPUT=\"tasks\"", + .depends = { "libctor_nomain.a" }, + .flags = { + .cxxflags = { + "-std=c++20", "-O3", "-s", "-Wall", "-Werror", + "-I../src", "-Iuunit", + "-DOUTPUT=\"tasks\"", + }, + .ldflags = { "-pthread" }, + }, + }, + { + .type = TargetType::UnitTest, + .target = "source_type_test", + .sources = { + "source_type_test.cc", + "testmain.cc", + }, + .depends = { "libctor_nomain.a" }, + .flags = { + .cxxflags = { + "-std=c++20", "-O3", "-s", "-Wall", "-Werror", + "-I../src", "-Iuunit", + "-DOUTPUT=\"source_type\"", + }, + .ldflags = { "-pthread" }, + }, + }, + { + .type = TargetType::UnitTest, + .target = "tools_test", + .sources = { + "tools_test.cc", + "testmain.cc", + "../src/tools.cc", + }, + //.depends = { "libctor_nomain.a" }, + .flags = { + .cxxflags = { + "-std=c++20", "-O3", "-Wall", "-Werror", + "-I../src", "-Iuunit", + "-DOUTPUT=\"tools\"", + }, + }, + }, + { + .type = TargetType::UnitTestLib, + .target = "libctor_nomain.a", + .sources = { + "../src/build.cc", + "../src/configure.cc", + "../src/execute.cc", + "../src/rebuild.cc", + "../src/tasks.cc", + "../src/task.cc", + "../src/task_ar.cc", + "../src/task_cc.cc", + "../src/task_fn.cc", + "../src/task_ld.cc", + "../src/task_so.cc", + "../src/tools.cc", + "../src/util.cc", + "../src/externals_manual.cc", + }, + .flags = { + .cxxflags = { + "-std=c++20", "-O3", "-s", "-Wall", "-Werror", + "-I../src", + }, + .ldflags = { "-pthread" }, }, }, }; diff --git a/test/paths.h b/test/paths.h new file mode 100644 index 0000000..f149972 --- /dev/null +++ b/test/paths.h @@ -0,0 +1,15 @@ +// -*- c++ -*- +// Distributed under the BSD 2-Clause License. +// See accompanying file LICENSE for details. +#pragma once + +#include <string> +#include <filesystem> + +namespace paths +{ +extern std::string argv_0; +extern std::filesystem::path top_srcdir; +extern std::filesystem::path top_builddir; +extern std::filesystem::path testdir; +} diff --git a/test/source_type_test.cc b/test/source_type_test.cc new file mode 100644 index 0000000..ed7e783 --- /dev/null +++ b/test/source_type_test.cc @@ -0,0 +1,76 @@ +#include <uunit.h> + +#include <libctor.h> +#include <task_cc.h> + +std::ostream& operator<<(std::ostream& stream, const Language& lang) +{ + switch(lang) + { + case Language::Auto: + stream << "Language::Auto"; + break; + case Language::C: + stream << "Language::C"; + break; + case Language::Cpp: + stream << "Language::Cpp"; + break; + case Language::Asm: + stream << "Language::Asm"; + break; + } + + return stream; +} +class TestableTaskCC + : public TaskCC +{ +public: + TestableTaskCC(const Source& source) + : TaskCC({}, {}, "build", source) + {} + + Language language() const + { + return source_language; + } +}; + +class SourceTypeTest + : public uUnit +{ +public: + SourceTypeTest() + { + uTEST(SourceTypeTest::test); + } + + void test() + { + { // c++ + TestableTaskCC task("hello.cc"); + uASSERT_EQUAL(Language::Cpp, task.language()); + } + + { // c + TestableTaskCC task("hello.c"); + uASSERT_EQUAL(Language::C, task.language()); + } + + { // asm + TestableTaskCC task("hello.s"); + uASSERT_EQUAL(Language::Asm, task.language()); + } + + { // custom/explicit language + TestableTaskCC task( {"hello.foo", Language::Asm} ); + uASSERT_EQUAL(Language::Asm, task.language()); + } + + // Note: Failure state will result in exit(1) so cannot be tested + } +}; + +// Registers the fixture into the 'registry' +static SourceTypeTest test; diff --git a/test/suite/ctor_files/ctor.cc.bar b/test/suite/ctor_files/ctor.cc.bar new file mode 100644 index 0000000..92456cb --- /dev/null +++ b/test/suite/ctor_files/ctor.cc.bar @@ -0,0 +1,62 @@ +// -*- c++ -*- +// Distributed under the BSD 2-Clause License. +// See accompanying file LICENSE for details. +#include <libctor.h> +//#include "config.h" + +namespace +{ +BuildConfigurations ctorConfigs() +{ + return + { + { + .name = "hello", + .target = "hello", + .sources = { + "hello.cc", + }, + .flags = { + .cxxflags = { + "-std=c++20", + "-O3", + "-g", + "-Wall", + "-Werror", + }, + }, + .externals = {"bar"}, + } + }; +} + +ExternalConfigurations ctorExtConfigs() +{ + return + { + { + .name = "bar", + .flags = { + .cxxflags = { "-D_A_", "-DBAR"}, + .cflags = { "-D_B_" }, + .ldflags = { "-D_C_" }, + .asmflags = { "-D_D_" }, + }, + // Creates --with-foo-prefix arg to configure which will be used for + // -L and -I flags. + // If not specified configure will try to find them in the system paths. + }, +// { +// .name = "bar", +// .type = TargetType::ExternalPkgConfig, +// .min_version = "0.1", +// .max_version = "0.9", +// // cflags, cxxflags and ldflags deduced by pkg-config tool (or parsed +// // directly from .pc if faster) +// }, + }; +} +} + +REG(ctorConfigs); +REG(ctorExtConfigs); diff --git a/test/suite/ctor_files/ctor.cc.base b/test/suite/ctor_files/ctor.cc.base new file mode 100644 index 0000000..6c60513 --- /dev/null +++ b/test/suite/ctor_files/ctor.cc.base @@ -0,0 +1,62 @@ +// -*- c++ -*- +// Distributed under the BSD 2-Clause License. +// See accompanying file LICENSE for details. +#include <libctor.h> +//#include "config.h" + +namespace +{ +BuildConfigurations ctorConfigs() +{ + return + { + { + .name = "hello", + .target = "hello", + .sources = { + "hello.cc", + }, + .flags = { + .cxxflags = { + "-std=c++20", + "-O3", + "-g", + "-Wall", + "-Werror", + }, + }, + .externals = {"bar"}, + } + }; +} + +ExternalConfigurations ctorExtConfigs() +{ + return + { + { + .name = "bar", + .flags = { + .cxxflags = { "-D_A_", "-DFOO"}, + .cflags = { "-D_B_" }, + .ldflags = { "-D_C_" }, + .asmflags = { "-D_D_" }, + }, + // Creates --with-foo-prefix arg to configure which will be used for + // -L and -I flags. + // If not specified configure will try to find them in the system paths. + }, +// { +// .name = "bar", +// .type = TargetType::ExternalPkgConfig, +// .min_version = "0.1", +// .max_version = "0.9", +// // cflags, cxxflags and ldflags deduced by pkg-config tool (or parsed +// // directly from .pc if faster) +// }, + }; +} +} + +REG(ctorConfigs); +REG(ctorExtConfigs); diff --git a/test/suite/ctor_files/ctor.cc.multi b/test/suite/ctor_files/ctor.cc.multi new file mode 100644 index 0000000..9db2517 --- /dev/null +++ b/test/suite/ctor_files/ctor.cc.multi @@ -0,0 +1,64 @@ +// -*- c++ -*- +// Distributed under the BSD 2-Clause License. +// See accompanying file LICENSE for details. +#include <libctor.h> +//#include "config.h" + +#include "foobar.h" + +namespace +{ +BuildConfigurations ctorConfigs() +{ + return + { + { + .name = "hello", + .target = "hello", + .sources = { + "hello.cc", + }, + .flags = { + .cxxflags = { + "-std=c++20", + "-O3", + "-g", + "-Wall", + "-Werror", + }, + }, + .externals = {"bar"}, + } + }; +} + +ExternalConfigurations ctorExtConfigs() +{ + return + { + { + .name = "bar", + .flags = { + .cxxflags = { "-D_A_", "-DFOO"}, + .cflags = { "-D_B_" }, + .ldflags = { "-D_C_" }, + .asmflags = { "-D_D_" }, + }, + // Creates --with-foo-prefix arg to configure which will be used for + // -L and -I flags. + // If not specified configure will try to find them in the system paths. + }, +// { +// .name = "bar", +// .type = TargetType::ExternalPkgConfig, +// .min_version = "0.1", +// .max_version = "0.9", +// // cflags, cxxflags and ldflags deduced by pkg-config tool (or parsed +// // directly from .pc if faster) +// }, + }; +} +} + +REG(ctorConfigs); +REG(ctorExtConfigs); diff --git a/test/suite/foobar.h b/test/suite/foobar.h new file mode 100644 index 0000000..e6e274e --- /dev/null +++ b/test/suite/foobar.h @@ -0,0 +1,3 @@ +#pragma once + +// Nothing to see here diff --git a/test/suite/hello.cc b/test/suite/hello.cc new file mode 100644 index 0000000..06e3deb --- /dev/null +++ b/test/suite/hello.cc @@ -0,0 +1,6 @@ +#include <iostream> + +int main() +{ + std::cout << "Hello\n"; +} diff --git a/test/suite/test.sh b/test/suite/test.sh new file mode 100755 index 0000000..c980154 --- /dev/null +++ b/test/suite/test.sh @@ -0,0 +1,104 @@ +#!/bin/bash + +function fail +{ + echo "*** Failure at line $1" + exit 1 +} + +function ctor +{ + echo "*** Running: ./ctor $*" + ./ctor $* +} + +# Wipe the board +rm -Rf build +rm -f configuration.cc +rm -f ctor + +cp ctor_files/ctor.cc.base ctor.cc + +# Compile bootstrap binary +g++ -pthread -std=c++20 -L../../build -lctor -I../../src ctor.cc -o ctor || fail ${LINENO} + +# No build files should have been created yet +[ -d build ] && fail ${LINENO} + +# capture md5 sum of ctor binary before configure is called +MD5=`md5sum ctor` +ctor configure --ctor-includedir ../../src --ctor-libdir ../../build + +# ctor should be rebuilt at this point, so md5 sum should have changed +(echo $MD5 | md5sum --status -c) && fail ${LINENO} + +# configuration.cc should have been generated now +[ ! -f configuration.cc ] && fail ${LINENO} + +# Shouldn't compile anything yet - only configure +[ -f build/hello-hello_cc.o ] && fail ${LINENO} + +MD5=`md5sum ctor` + +# Run normally to build project +ctor -v + +# Compiled object should now exist +[ ! -f build/hello-hello_cc.o ] && fail ${LINENO} + +# ctor should not have been rebuilt, so md5 sum should be the same +(echo $MD5 | md5sum --status -c) || fail ${LINENO} + +MOD1=`stat -c %Y build/hello-hello_cc.o` +touch hello.cc +sleep 1.1 + +# Run normally to rebuild hello.cc +ctor -v + +# Object file should have been recompiled +MOD2=`stat -c %Y build/hello-hello_cc.o` +[[ $MOD1 == $MOD2 ]] && fail ${LINENO} + +# Replacve -DFOO with -DBAR in foo external.cxxflags +cp ctor_files/ctor.cc.bar ctor.cc + +MD5C=`md5sum configuration.cc` +MD5=`md5sum ctor` +MOD1=`stat -c %Y build/hello-hello_cc.o` +sleep 1.1 + +# Run normally to reconfigure, rebuild ctor and rebuild hello.cc +ctor -v + +MOD2=`stat -c %Y build/hello-hello_cc.o` +[[ $MOD1 == $MOD2 ]] && fail ${LINENO} +(echo $MD5C | md5sum --status -c) && fail ${LINENO} +(echo $MD5 | md5sum --status -c) && fail ${LINENO} + +cp ctor_files/ctor.cc.multi ctor.cc + +MD5C=`md5sum configuration.cc` +MD5=`md5sum ctor` +MOD1=`stat -c %Y build/hello-hello_cc.o` +sleep 1.1 + +# Run normally to reconfigure, rebuild ctor and rebuild hello.cc +ctor -v + +MOD2=`stat -c %Y build/hello-hello_cc.o` +[[ $MOD1 == $MOD2 ]] && fail ${LINENO} +(echo $MD5C | md5sum --status -c) && fail ${LINENO} +(echo $MD5 | md5sum --status -c) && fail ${LINENO} + +# now touching foobar.h, should retrigger re-configuration +touch foobar.h + +MOD1=`stat -c %Y ctor` +sleep 1.1 + +# Run normally to reconfigure, rebuild ctor and rebuild hello.cc +ctor -v + +MOD2=`stat -c %Y ctor` +[[ $MOD1 == $MOD2 ]] && fail ${LINENO} diff --git a/test/tasks_test.cc b/test/tasks_test.cc index d6515b8..2e0ffc7 100644 --- a/test/tasks_test.cc +++ b/test/tasks_test.cc @@ -2,11 +2,10 @@ #include <libctor.h> #include <tasks.h> -#include <settings.h> namespace { -BuildConfigurations ctorTestConfigs1() +BuildConfigurations ctorTestConfigs1(const Settings&) { return { @@ -20,7 +19,7 @@ BuildConfigurations ctorTestConfigs1() }; } -BuildConfigurations ctorTestConfigs2() +BuildConfigurations ctorTestConfigs2(const Settings&) { return { @@ -37,6 +36,19 @@ BuildConfigurations ctorTestConfigs2() REG(ctorTestConfigs1); REG(ctorTestConfigs2); +std::size_t count(const std::set<std::shared_ptr<Task>>& tasks, + const std::string& name) +{ + auto cnt{0u}; + for(const auto& task : tasks) + { + if(task->target() == name) + { + cnt++; + } + } + return cnt; +} class TestTask : public Task @@ -44,7 +56,7 @@ class TestTask public: TestTask(const std::string& name, bool dirty, const std::vector<std::string>& deps = {}) - : Task({}) + : Task({}, {}, {}) , task_name(name) , task_dirty(dirty) , task_deps(deps) @@ -55,6 +67,8 @@ public: int clean() override { return 0; } std::vector<std::string> 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: @@ -95,34 +109,26 @@ public: void getTasks_test() { using namespace std::string_literals; - Settings settings{}; + Settings settings{ .builddir = "foo" }; { auto tasks = getTasks(settings); uASSERT_EQUAL(6u, tasks.size()); - auto task = tasks.begin(); - uASSERT_EQUAL("target1-foo_cc.o"s, (*task)->target()); - task++; - uASSERT_EQUAL("target1-bar_c.o"s, (*task)->target()); - task++; - uASSERT_EQUAL("target1"s, (*task)->target()); - task++; - uASSERT_EQUAL("target2"s, (*task)->target()); - task++; - uASSERT_EQUAL("target3"s, (*task)->target()); - task++; - uASSERT_EQUAL("target4"s, (*task)->target()); + // Note: count() is used here because the order of + // std::set<std::shared_ptr<T>> 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()); - auto task = tasks.begin(); - uASSERT_EQUAL("target1-foo_cc.o"s, (*task)->target()); - task++; - uASSERT_EQUAL("target1-bar_c.o"s, (*task)->target()); - task++; - uASSERT_EQUAL("target1"s, (*task)->target()); - task++; - uASSERT_EQUAL("target3"s, (*task)->target()); + 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"}); @@ -136,8 +142,8 @@ public: Settings settings{}; { // Zero (Empty) - std::list<std::shared_ptr<Task>> allTasks; - std::list<std::shared_ptr<Task>> dirtyTasks; + std::set<std::shared_ptr<Task>> allTasks; + std::set<std::shared_ptr<Task>> dirtyTasks; for(auto& task : dirtyTasks) { @@ -150,10 +156,10 @@ public: { // Zero (One task, no dirty) auto task1 = std::make_shared<TestTask>("task1", false); - std::list<std::shared_ptr<Task>> allTasks; - allTasks.push_back(task1); + std::set<std::shared_ptr<Task>> allTasks; + allTasks.insert(task1); - std::list<std::shared_ptr<Task>> dirtyTasks; + std::set<std::shared_ptr<Task>> dirtyTasks; for(auto& task : dirtyTasks) { @@ -166,11 +172,11 @@ public: { // One (One task, one dirty) auto task1 = std::make_shared<TestTask>("task1", true); - std::list<std::shared_ptr<Task>> allTasks; - allTasks.push_back(task1); + std::set<std::shared_ptr<Task>> allTasks; + allTasks.insert(task1); - std::list<std::shared_ptr<Task>> dirtyTasks; - dirtyTasks.push_back(task1); + std::set<std::shared_ptr<Task>> dirtyTasks; + dirtyTasks.insert(task1); for(auto& task : dirtyTasks) { @@ -185,12 +191,12 @@ public: auto task1 = std::make_shared<TestTask>("task1", false); auto task2 = std::make_shared<TestTask>("task2", true); - std::list<std::shared_ptr<Task>> allTasks; - allTasks.push_back(task1); - allTasks.push_back(task2); + std::set<std::shared_ptr<Task>> allTasks; + allTasks.insert(task1); + allTasks.insert(task2); - std::list<std::shared_ptr<Task>> dirtyTasks; - dirtyTasks.push_back(task2); + std::set<std::shared_ptr<Task>> dirtyTasks; + dirtyTasks.insert(task2); for(auto& task : dirtyTasks) { @@ -207,12 +213,12 @@ public: std::vector<std::string> deps = {"task1"}; auto task2 = std::make_shared<TestTask>("task2", true, deps); - std::list<std::shared_ptr<Task>> allTasks; - allTasks.push_back(task1); - allTasks.push_back(task2); + std::set<std::shared_ptr<Task>> allTasks; + allTasks.insert(task1); + allTasks.insert(task2); - std::list<std::shared_ptr<Task>> dirtyTasks; - dirtyTasks.push_back(task2); + std::set<std::shared_ptr<Task>> dirtyTasks; + dirtyTasks.insert(task2); for(auto& task : dirtyTasks) { @@ -229,13 +235,13 @@ public: std::vector<std::string> deps = {"task1"}; auto task2 = std::make_shared<TestTask>("task2", true, deps); - std::list<std::shared_ptr<Task>> allTasks; - allTasks.push_back(task2); - allTasks.push_back(task1); + std::set<std::shared_ptr<Task>> allTasks; + allTasks.insert(task2); + allTasks.insert(task1); - std::list<std::shared_ptr<Task>> dirtyTasks; - dirtyTasks.push_back(task2); - dirtyTasks.push_back(task1); + std::set<std::shared_ptr<Task>> dirtyTasks; + dirtyTasks.insert(task2); + dirtyTasks.insert(task1); for(auto& task : dirtyTasks) { diff --git a/test/testmain.cc b/test/testmain.cc new file mode 100644 index 0000000..db8e22c --- /dev/null +++ b/test/testmain.cc @@ -0,0 +1,36 @@ +// -*- c++ -*- +// Distributed under the BSD 2-Clause License. +// See accompanying file LICENSE for details. +#define uUNIT_MAIN +#include "uunit.h" + +#include <fstream> +#include <string> +#include <filesystem> + +namespace paths +{ +std::string argv_0; +std::filesystem::path top_srcdir; +std::filesystem::path top_builddir; +std::filesystem::path testdir; +} + +int main(int argc, char* argv[]) +{ + (void)argc; + + paths::argv_0 = argv[0]; + + auto cur = std::filesystem::current_path(); + paths::testdir = std::filesystem::path(paths::argv_0).parent_path(); + // assuming <builddir>/test + paths::top_builddir = paths::testdir.parent_path(); + paths::top_srcdir = std::filesystem::relative(cur, paths::testdir); + + std::filesystem::current_path(paths::testdir); + + std::ofstream xmlfile; + xmlfile.open("result_" OUTPUT ".xml"); + return uUnit::runTests(xmlfile); +} diff --git a/test/tools_test.cc b/test/tools_test.cc new file mode 100644 index 0000000..3e9de1b --- /dev/null +++ b/test/tools_test.cc @@ -0,0 +1,212 @@ +#include <uunit.h> + +#include <initializer_list> +#include <cassert> + +#include <tools.h> + +using namespace std::string_literals; + +namespace +{ +std::ostream& operator<<(std::ostream& stream, const ToolChain& tool_chain) +{ + switch(tool_chain) + { + case ToolChain::gcc: + stream << "ToolChain::gcc"; + break; + case ToolChain::clang: + stream << "ToolChain::clang"; + break; + } + return stream; +} + +std::ostream& operator<<(std::ostream& stream, const std::vector<std::string>& vs) +{ + bool first{true}; + stream << "{ "; + for(const auto& v : vs) + { + if(!first) + { + stream << ", "; + } + stream << "'" << v << "'"; + first = false; + } + stream << " }"; + + return stream; +} + +std::ostream& operator<<(std::ostream& stream, opt o) +{ + // Adding to this enum should also imply adding to the unit-tests below + switch(o) + { + case opt::output: stream << "opt::output"; break; + case opt::debug: stream << "opt::debug"; break; + case opt::strip: stream << "opt::strip"; break; + case opt::warn_all: stream << "opt::warn_all"; break; + case opt::warnings_as_errors: stream << "opt::warnings_as_errors"; break; + case opt::generate_dep_tree: stream << "opt::generate_dep_tree"; break; + case opt::no_link: stream << "opt::no_link"; break; + case opt::include_path: stream << "opt::include_path"; break; + case opt::library_path: stream << "opt::library_path"; break; + case opt::link: stream << "opt::link"; break; + case opt::cpp_std: stream << "opt::cpp_std"; break; + case opt::build_shared: stream << "opt::build_shared"; break; + case opt::threads: stream << "opt::threads"; break; + case opt::optimization: stream << "opt::optimization"; break; + case opt::position_independent_code: stream << "opt::position_independent_code"; break; + case opt::position_independent_executable: stream << "opt::position_independent_executable"; break; + case opt::custom: stream << "opt::custom"; break; + } + + return stream; +} + +std::ostream& operator<<(std::ostream& stream, const std::pair<opt, std::string>& vs) +{ + stream << "{ " << vs.first << ", " << vs.second << " }"; + + return stream; +} +} + +// Controllable getConfiguration stub: +namespace +{ +std::string conf_host_cxx{}; +std::string conf_build_cxx{}; +} +const std::string& getConfiguration(const std::string& key, + const std::string& defval) +{ + if(key == cfg::host_cxx) + { + return conf_host_cxx; + } + + if(key == cfg::build_cxx) + { + return conf_build_cxx; + } + + assert(false); // bad key + + static std::string res{}; + return res; +} + +class ToolsTest + : public uUnit +{ +public: + ToolsTest() + { + uTEST(ToolsTest::getToolChain_test); + uTEST(ToolsTest::getOption_toolchain_test); + uTEST(ToolsTest::getOption_str_test); + } + + void getToolChain_test() + { + // host + conf_host_cxx = "/usr/bin/g++"; + uASSERT_EQUAL(ToolChain::gcc, getToolChain(OutputSystem::Host)); + + conf_host_cxx = "/usr/bin/g++-10"; + uASSERT_EQUAL(ToolChain::gcc, getToolChain(OutputSystem::Host)); + + conf_host_cxx = "/usr/bin/x86_64-pc-linux-gnu-g++-9.3.0"; + uASSERT_EQUAL(ToolChain::gcc, getToolChain(OutputSystem::Host)); + + conf_host_cxx = "/usr/bin/clang++"; + uASSERT_EQUAL(ToolChain::clang, getToolChain(OutputSystem::Host)); + + conf_host_cxx = "/usr/bin/clang++-10"; + uASSERT_EQUAL(ToolChain::clang, getToolChain(OutputSystem::Host)); + + conf_host_cxx = "/usr/lib/llvm/12/bin/i686-pc-linux-gnu-clang++-12"; + uASSERT_EQUAL(ToolChain::clang, getToolChain(OutputSystem::Host)); + + // build + conf_build_cxx = "/usr/bin/g++"; + uASSERT_EQUAL(ToolChain::gcc, getToolChain(OutputSystem::Build)); + + conf_build_cxx = "/usr/bin/g++-10"; + uASSERT_EQUAL(ToolChain::gcc, getToolChain(OutputSystem::Build)); + + conf_build_cxx = "/usr/bin/x86_64-pc-linux-gnu-g++-9.3.0"; + uASSERT_EQUAL(ToolChain::gcc, getToolChain(OutputSystem::Build)); + + conf_build_cxx = "/usr/bin/clang++"; + uASSERT_EQUAL(ToolChain::clang, getToolChain(OutputSystem::Build)); + + conf_build_cxx = "/usr/bin/clang++-10"; + uASSERT_EQUAL(ToolChain::clang, getToolChain(OutputSystem::Build)); + + conf_build_cxx = "/usr/lib/llvm/12/bin/i686-pc-linux-gnu-clang++-12"; + uASSERT_EQUAL(ToolChain::clang, getToolChain(OutputSystem::Build)); + } + + void getOption_toolchain_test() + { + using sv = std::vector<std::string>; + + uUnit::assert_equal(sv{ "-o", "foo" }, getOption(ToolChain::clang, opt::output, "foo"), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-g" }, getOption(ToolChain::clang, opt::debug), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-s" }, getOption(ToolChain::clang, opt::strip), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-Wall" }, getOption(ToolChain::clang, opt::warn_all), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-Werror" }, getOption(ToolChain::clang, opt::warnings_as_errors), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-MMD" }, getOption(ToolChain::clang, opt::generate_dep_tree), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-c" }, getOption(ToolChain::clang, opt::no_link), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-Ifoo" }, getOption(ToolChain::clang, opt::include_path, "foo"), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-Lfoo" }, getOption(ToolChain::clang, opt::library_path, "foo"), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-lfoo" }, getOption(ToolChain::clang, opt::link, "foo"), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-std=foo" }, getOption(ToolChain::clang, opt::cpp_std, "foo"), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-shared" }, getOption(ToolChain::clang, opt::build_shared), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-pthread" }, getOption(ToolChain::clang, opt::threads), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-Ofoo" }, getOption(ToolChain::clang, opt::optimization, "foo"), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-fPIC" }, getOption(ToolChain::clang, opt::position_independent_code), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-fPIE" }, getOption(ToolChain::clang, opt::position_independent_executable), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-foo" }, getOption(ToolChain::clang, opt::custom, "-foo"), __FILE__, __LINE__); + + uUnit::assert_equal(sv{ "-o", "foo" }, getOption(ToolChain::gcc, opt::output, "foo"), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-g" }, getOption(ToolChain::gcc, opt::debug), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-s" }, getOption(ToolChain::gcc, opt::strip), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-Wall" }, getOption(ToolChain::gcc, opt::warn_all), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-Werror" }, getOption(ToolChain::gcc, opt::warnings_as_errors), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-MMD" }, getOption(ToolChain::gcc, opt::generate_dep_tree), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-c" }, getOption(ToolChain::gcc, opt::no_link), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-Ifoo" }, getOption(ToolChain::gcc, opt::include_path, "foo"), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-Lfoo" }, getOption(ToolChain::gcc, opt::library_path, "foo"), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-lfoo" }, getOption(ToolChain::gcc, opt::link, "foo"), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-std=foo" }, getOption(ToolChain::gcc, opt::cpp_std, "foo"), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-shared" }, getOption(ToolChain::gcc, opt::build_shared), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-pthread" }, getOption(ToolChain::gcc, opt::threads), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-Ofoo" }, getOption(ToolChain::gcc, opt::optimization, "foo"), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-fPIC" }, getOption(ToolChain::gcc, opt::position_independent_code), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-fPIE" }, getOption(ToolChain::gcc, opt::position_independent_executable), __FILE__, __LINE__); + uUnit::assert_equal(sv{ "-foo" }, getOption(ToolChain::gcc, opt::custom, "-foo"), __FILE__, __LINE__); + } + + void getOption_str_test() + { + using p = std::pair<opt, std::string>; + uUnit::assert_equal(p{ opt::include_path, "foo" }, getOption("-Ifoo", ToolChain::gcc), __FILE__, __LINE__); + uUnit::assert_equal(p{ opt::library_path, "foo" }, getOption("-Lfoo", ToolChain::gcc), __FILE__, __LINE__); + + uUnit::assert_equal(p{ opt::include_path, "foo" }, getOption("-Ifoo", ToolChain::clang), __FILE__, __LINE__); + uUnit::assert_equal(p{ opt::library_path, "foo" }, getOption("-Lfoo", ToolChain::clang), __FILE__, __LINE__); + } + + + +}; + +// Registers the fixture into the 'registry' +static ToolsTest test; diff --git a/test/uunit b/test/uunit -Subproject fd83de802d05a227cc00489f66ea70fccb4dda0 +Subproject bc078da645412c6b36ef59e635d6c35d11088c9 |