From 8da0229a7e172a86c023edc6bb25ba803c68f5d3 Mon Sep 17 00:00:00 2001 From: "Claudius \"keldu\" Holeksa" Date: Mon, 4 Dec 2023 13:45:37 +0100 Subject: core, tests: Moving core tests to core module --- modules/core/.nix/derivation.nix | 6 +++ modules/core/SConstruct | 4 ++ modules/core/c++/SConscript | 8 +-- modules/core/c++/test/SConscript | 33 ++++++++++++ modules/core/c++/test/suite.cpp | 107 +++++++++++++++++++++++++++++++++++++++ modules/core/c++/test/suite.h | 43 ++++++++++++++++ modules/core/tests/SConscript | 29 +++++++++++ modules/core/tests/core.cpp | 67 ++++++++++++++++++++++++ modules/core/tests/tree.cpp | 24 +++++++++ modules/test/.nix/derivation.nix | 28 ---------- modules/test/SConscript | 33 ------------ modules/test/SConstruct | 66 ------------------------ modules/test/suite.cpp | 107 --------------------------------------- modules/test/suite.h | 43 ---------------- 14 files changed, 317 insertions(+), 281 deletions(-) create mode 100644 modules/core/c++/test/SConscript create mode 100644 modules/core/c++/test/suite.cpp create mode 100644 modules/core/c++/test/suite.h create mode 100644 modules/core/tests/SConscript create mode 100644 modules/core/tests/core.cpp create mode 100644 modules/core/tests/tree.cpp delete mode 100644 modules/test/.nix/derivation.nix delete mode 100644 modules/test/SConscript delete mode 100644 modules/test/SConstruct delete mode 100644 modules/test/suite.cpp delete mode 100644 modules/test/suite.h (limited to 'modules') diff --git a/modules/core/.nix/derivation.nix b/modules/core/.nix/derivation.nix index 1618651..372d3a6 100644 --- a/modules/core/.nix/derivation.nix +++ b/modules/core/.nix/derivation.nix @@ -17,5 +17,11 @@ stdenv.mkDerivation { clang-tools ]; + doCheck = true; + checkPhase = '' + scons test + ./bin/tests + ''; + outputs = ["out" "dev"]; } diff --git a/modules/core/SConstruct b/modules/core/SConstruct index 015645b..643550d 100644 --- a/modules/core/SConstruct +++ b/modules/core/SConstruct @@ -58,7 +58,11 @@ env.targets = []; Export('env') SConscript('c++/SConscript') +SConscript('c++/test/SConscript') +SConscript('tests/SConscript') + +# Aliasing env.Alias('cdb', env.cdb); env.Alias('all', [env.targets]); env.Default('all'); diff --git a/modules/core/c++/SConscript b/modules/core/c++/SConscript index 02bd050..cea6b76 100644 --- a/modules/core/c++/SConscript +++ b/modules/core/c++/SConscript @@ -21,20 +21,20 @@ env.headers += core_env.headers; ## Shared lib objects_shared = [] core_env.add_source_files(objects_shared, core_env.sources, shared=True); -core_env.library_shared = core_env.SharedLibrary('#build/forstio-core', [objects_shared]); +env.library_shared = core_env.SharedLibrary('#build/forstio-core', [objects_shared]); ## Static lib objects_static = [] core_env.add_source_files(objects_static, core_env.sources, shared=False); -core_env.library_static = core_env.StaticLibrary('#build/forstio-core', [objects_static]); +env.library_static = core_env.StaticLibrary('#build/forstio-core', [objects_static]); # Set Alias -env.Alias('library_core', [core_env.library_shared, core_env.library_static]); +env.Alias('library_core', [env.library_shared, env.library_static]); env.targets += ['library_core']; # Install -env.Install('$prefix/lib/', [core_env.library_shared, core_env.library_static]); +env.Install('$prefix/lib/', [env.library_shared, env.library_static]); env.Install('$prefix/include/forstio/core/', [core_env.headers]); # Test diff --git a/modules/core/c++/test/SConscript b/modules/core/c++/test/SConscript new file mode 100644 index 0000000..1c4de76 --- /dev/null +++ b/modules/core/c++/test/SConscript @@ -0,0 +1,33 @@ +#!/bin/false + +import os +import os.path +import glob + + +Import('env') + +dir_path = Dir('.').abspath + +# Environment for base library +test_env = env.Clone(); + +test_env.sources = sorted(glob.glob(dir_path + "/*.cpp")) +test_env.headers = sorted(glob.glob(dir_path + "/*.h")) + +env.sources += test_env.sources; +env.headers += test_env.headers; + +## Shared lib +objects = [] +test_env.add_source_files(objects, test_env.sources, shared=False); +env.test_library = test_env.StaticLibrary('#build/forstio-test', [objects]); + +# Set Alias +env.Alias('library_test', [env.test_library]); + +env.targets += ['library_test']; + +# Install +env.Install('$prefix/lib/', [env.test_library]); +env.Install('$prefix/include/forstio/test/', [test_env.headers]); diff --git a/modules/core/c++/test/suite.cpp b/modules/core/c++/test/suite.cpp new file mode 100644 index 0000000..0fca8f9 --- /dev/null +++ b/modules/core/c++/test/suite.cpp @@ -0,0 +1,107 @@ +#include "suite.h" + +#include +#include +#include +#include + +namespace saw { +namespace test { + test_case* testCaseHead = nullptr; + test_case** testCaseTail = &testCaseHead; + + test_case::test_case(const std::string& file_, uint line_, const std::string& description_): + file{file_}, + line{line_}, + description{description_}, + matched_filter{false}, + next{nullptr}, + prev{testCaseTail} + { + *prev = this; + testCaseTail = &next; + } + + test_case::~test_case(){ + *prev = next; + if( next == nullptr ){ + testCaseTail = prev; + }else{ + next->prev = prev; + } + } + + class test_runner { + private: + enum Colour { + RED, + GREEN, + BLUE, + WHITE + }; + + void write(Colour colour, const std::string& front, const std::string& message){ + std::string start_col, end_col; + switch(colour){ + case RED: start_col = "\033[0;1;31m"; break; + case GREEN: start_col = "\033[0;1;32m"; break; + case BLUE: start_col = "\033[0;1;34m"; break; + case WHITE: start_col = "\033[0m"; break; + } + end_col = "\033[0m"; + std::cout<next){ + testCase->matched_filter = true; + } + } + + int run() { + size_t passed_count = 0; + size_t failed_count = 0; + + for(test_case* testCase = testCaseHead; testCase != nullptr; testCase =testCase->next){ + if(testCase->matched_filter){ + std::string name = testCase->file + std::string(":") + std::to_string(testCase->line) + std::string(": ") + testCase->description; + write(BLUE, "[ TEST ] ", name); + bool failed = true; + std::string fail_message; + auto start_clock = std::chrono::steady_clock::now(); + try { + testCase->run(); + failed = false; + }catch(std::exception& e){ + fail_message = e.what(); + failed = true; + } + auto stop_clock = std::chrono::steady_clock::now(); + + auto runtime_duration_intern = stop_clock - start_clock; + auto runtime_duration = std::chrono::duration_cast(runtime_duration_intern); + std::string message = name + std::string(" (") + std::to_string(runtime_duration.count()) + std::string(" µs)"); + if(failed){ + write(RED, "[ FAIL ] ", message + " " + fail_message); + ++failed_count; + }else{ + write(GREEN, "[ PASS ] ", message); + ++passed_count; + } + } + } + + if(passed_count>0) write(GREEN, std::to_string(passed_count) + std::string(" test(s) passed"), ""); + if(failed_count>0) write(RED, std::to_string(failed_count) + std::string(" test(s) failed"), ""); + return -failed_count; + } + }; +} +} + +int main() { + saw::test::test_runner runner; + runner.allowAll(); + int rv = runner.run(); + return rv<0?-1:0; +} diff --git a/modules/core/c++/test/suite.h b/modules/core/c++/test/suite.h new file mode 100644 index 0000000..e28a94c --- /dev/null +++ b/modules/core/c++/test/suite.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include +#include +#include + +#include "../common.h" + +namespace saw { +namespace test { +class test_runner; +class test_case { +private: + std::string file; + uint line; + std::string description; + bool matched_filter; + test_case* next; + test_case** prev; + + friend class test_runner; +public: + test_case(const std::string& file_, uint line_, const std::string& description_); + ~test_case(); + + virtual void run() = 0; +}; +} +} +#define SAW_TEST(description) \ + class SAW_UNIQUE_NAME(test_case) : public ::saw::test::test_case { \ + public: \ + SAW_UNIQUE_NAME(test_case)(): ::saw::test::test_case(__FILE__,__LINE__,description) {} \ + void run() override; \ + }SAW_UNIQUE_NAME(test_case_); \ + void SAW_UNIQUE_NAME(test_case)::run() + +#define SAW_EXPECT(expr, msg_split) \ + if( ! (expr) ){ \ + auto msg = msg_split; \ + throw std::runtime_error{std::string{msg}};\ + } diff --git a/modules/core/tests/SConscript b/modules/core/tests/SConscript new file mode 100644 index 0000000..cec3132 --- /dev/null +++ b/modules/core/tests/SConscript @@ -0,0 +1,29 @@ +#!/bin/false + +import os +import os.path +import glob + + +Import('env') + +dir_path = Dir('.').abspath + +# Environment for base library +test_cases_env = env.Clone(); + +test_cases_env.sources = sorted(glob.glob(dir_path + "/*.cpp")) +test_cases_env.headers = sorted(glob.glob(dir_path + "/*.h")) + +env.sources += test_cases_env.sources; +env.headers += test_cases_env.headers; + +objects_static = [] +test_cases_env.add_source_files(objects_static, test_cases_env.sources, shared=False); +test_cases_env.program = test_cases_env.Program('#bin/tests', [objects_static, env.library_static, env.test_library]); + +# Set Alias +env.Alias('test', test_cases_env.program); +env.Alias('check', test_cases_env.program); + +env.targets += ['test','check']; diff --git a/modules/core/tests/core.cpp b/modules/core/tests/core.cpp new file mode 100644 index 0000000..2b63b94 --- /dev/null +++ b/modules/core/tests/core.cpp @@ -0,0 +1,67 @@ +#include "../c++/test/suite.h" +#include "../c++/id.h" +#include "../c++/id_map.h" +#include "../c++/string_literal.h" + +namespace { +SAW_TEST("ID functionality") { + using namespace saw; + struct foo {}; + + id a{1}; + id b{1}; + id c{2}; + + /** + * The following doesn't compile, so it's commented out as an example + */ + /** + * struct bar {}; + * + * id d{1}; + * + * SAW_EXPECT(a == d, "Shouldn't compile"); + */ + + SAW_EXPECT(a == b, "Should be equal"); + SAW_EXPECT(a != c, "Shouldn't be equal"); + SAW_EXPECT(b != c, "Shouldn't be equal"); + SAW_EXPECT(a.get_value() == 1, "Lost original value"); +} + +SAW_TEST("String Literal Append"){ + using namespace saw; + + constexpr string_literal a = "foo"; + constexpr string_literal b = "bar"; + constexpr string_literal c = a+b; + + SAW_EXPECT(c == "foobar", "CT String sum is not \"foobar\""); +} + +SAW_TEST("ID Map Insert"){ + using namespace saw; + + struct foo {}; + + id_map map; + { + auto eoid = map.insert(foo{}); + SAW_EXPECT(eoid.is_value(), "First insert failed"); + + auto& id = eoid.get_value(); + + auto eoid_2 = map.insert(foo{}); + SAW_EXPECT(eoid_2.is_value(), "Second Insert failed"); + auto& id_2 = eoid_2.get_value(); + + SAW_EXPECT(id != id_2, "Shouldn't be equal"); + + auto eov = map.erase(id); + SAW_EXPECT(eov.is_value(), "Erase failed"); + + auto eov_2 = map.erase(id); + SAW_EXPECT(eov_2.is_error(), "This is a double free"); + } +} +} diff --git a/modules/core/tests/tree.cpp b/modules/core/tests/tree.cpp new file mode 100644 index 0000000..78f72ef --- /dev/null +++ b/modules/core/tests/tree.cpp @@ -0,0 +1,24 @@ +#include "../c++/test/suite.h" +#include "../c++/tree.h" + +namespace { +SAW_TEST("Tree add child"){ + using namespace saw; + + tree tr; + { + auto eov = tr.add(10); + SAW_EXPECT(eov.is_value(), "Didn't manage to add value"); + } + { + auto eov = tr.add(); + SAW_EXPECT(eov.is_value(), "Didn't manage to add tree"); + std::size_t index = eov.get_value(); + + auto& inner_tr = tr.at(index); + + auto eov2 = inner_tr.get_tree().add(420); + SAW_EXPECT(eov2.is_value(), "Didn't manage to add to inner tree"); + } +} +} diff --git a/modules/test/.nix/derivation.nix b/modules/test/.nix/derivation.nix deleted file mode 100644 index c15421d..0000000 --- a/modules/test/.nix/derivation.nix +++ /dev/null @@ -1,28 +0,0 @@ -{ lib -, stdenv -, scons -, clang-tools -, version -, forstio -}: - -let - -in stdenv.mkDerivation { - pname = "forstio-test"; - inherit version; - src = ./..; - - enableParallelBuilding = true; - - nativeBuildInputs = [ - scons - clang-tools - ]; - - buildInputs = [ - forstio.core - ]; - - outputs = ["out" "dev"]; -} diff --git a/modules/test/SConscript b/modules/test/SConscript deleted file mode 100644 index 6379b24..0000000 --- a/modules/test/SConscript +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/false - -import os -import os.path -import glob - - -Import('env') - -dir_path = Dir('.').abspath - -# Environment for base library -test_env = env.Clone(); - -test_env.sources = sorted(glob.glob(dir_path + "/*.cpp")) -test_env.headers = sorted(glob.glob(dir_path + "/*.h")) - -env.sources += test_env.sources; -env.headers += test_env.headers; - -## Shared lib -objects = [] -test_env.add_source_files(objects, test_env.sources, shared=False); -test_env.library = test_env.StaticLibrary('#build/forstio-test', [objects]); - -# Set Alias -env.Alias('library_test', [test_env.library]); - -env.targets += ['library_test']; - -# Install -env.Install('$prefix/lib/', [test_env.library]); -env.Install('$prefix/include/forstio/test/', [test_env.headers]); diff --git a/modules/test/SConstruct b/modules/test/SConstruct deleted file mode 100644 index 0d7b7c6..0000000 --- a/modules/test/SConstruct +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python3 - -import sys -import os -import os.path -import glob -import re - - -if sys.version_info < (3,): - def isbasestring(s): - return isinstance(s,basestring) -else: - def isbasestring(s): - return isinstance(s, (str,bytes)) - -def add_kel_source_files(self, sources, filetype, lib_env=None, shared=False, target_post=""): - - if isbasestring(filetype): - dir_path = self.Dir('.').abspath - filetype = sorted(glob.glob(dir_path+"/"+filetype)) - - for path in filetype: - target_name = re.sub( r'(.*?)(\.cpp|\.c\+\+)', r'\1' + target_post, path ) - if shared: - target_name+='.os' - sources.append( self.SharedObject( target=target_name, source=path ) ) - else: - target_name+='.o' - sources.append( self.StaticObject( target=target_name, source=path ) ) - pass - -def isAbsolutePath(key, dirname, env): - assert os.path.isabs(dirname), "%r must have absolute path syntax" % (key,) - -env_vars = Variables( - args=ARGUMENTS -) - -env_vars.Add('prefix', - help='Installation target location of build results and headers', - default='/usr/local/', - validator=isAbsolutePath -) - -env=Environment(ENV=os.environ, variables=env_vars, CPPPATH=[], - CPPDEFINES=['SAW_UNIX'], - CXXFLAGS=['-std=c++20','-g','-Wall','-Wextra'], - LIBS=['forstio-core']) -env.__class__.add_source_files = add_kel_source_files -env.Tool('compilation_db'); -env.cdb = env.CompilationDatabase('compile_commands.json'); - -env.objects = []; -env.sources = []; -env.headers = []; -env.targets = []; - -Export('env') -SConscript('SConscript') - -env.Alias('cdb', env.cdb); -env.Alias('all', [env.targets]); -env.Default('all'); - -env.Alias('install', '$prefix') diff --git a/modules/test/suite.cpp b/modules/test/suite.cpp deleted file mode 100644 index 0fca8f9..0000000 --- a/modules/test/suite.cpp +++ /dev/null @@ -1,107 +0,0 @@ -#include "suite.h" - -#include -#include -#include -#include - -namespace saw { -namespace test { - test_case* testCaseHead = nullptr; - test_case** testCaseTail = &testCaseHead; - - test_case::test_case(const std::string& file_, uint line_, const std::string& description_): - file{file_}, - line{line_}, - description{description_}, - matched_filter{false}, - next{nullptr}, - prev{testCaseTail} - { - *prev = this; - testCaseTail = &next; - } - - test_case::~test_case(){ - *prev = next; - if( next == nullptr ){ - testCaseTail = prev; - }else{ - next->prev = prev; - } - } - - class test_runner { - private: - enum Colour { - RED, - GREEN, - BLUE, - WHITE - }; - - void write(Colour colour, const std::string& front, const std::string& message){ - std::string start_col, end_col; - switch(colour){ - case RED: start_col = "\033[0;1;31m"; break; - case GREEN: start_col = "\033[0;1;32m"; break; - case BLUE: start_col = "\033[0;1;34m"; break; - case WHITE: start_col = "\033[0m"; break; - } - end_col = "\033[0m"; - std::cout<next){ - testCase->matched_filter = true; - } - } - - int run() { - size_t passed_count = 0; - size_t failed_count = 0; - - for(test_case* testCase = testCaseHead; testCase != nullptr; testCase =testCase->next){ - if(testCase->matched_filter){ - std::string name = testCase->file + std::string(":") + std::to_string(testCase->line) + std::string(": ") + testCase->description; - write(BLUE, "[ TEST ] ", name); - bool failed = true; - std::string fail_message; - auto start_clock = std::chrono::steady_clock::now(); - try { - testCase->run(); - failed = false; - }catch(std::exception& e){ - fail_message = e.what(); - failed = true; - } - auto stop_clock = std::chrono::steady_clock::now(); - - auto runtime_duration_intern = stop_clock - start_clock; - auto runtime_duration = std::chrono::duration_cast(runtime_duration_intern); - std::string message = name + std::string(" (") + std::to_string(runtime_duration.count()) + std::string(" µs)"); - if(failed){ - write(RED, "[ FAIL ] ", message + " " + fail_message); - ++failed_count; - }else{ - write(GREEN, "[ PASS ] ", message); - ++passed_count; - } - } - } - - if(passed_count>0) write(GREEN, std::to_string(passed_count) + std::string(" test(s) passed"), ""); - if(failed_count>0) write(RED, std::to_string(failed_count) + std::string(" test(s) failed"), ""); - return -failed_count; - } - }; -} -} - -int main() { - saw::test::test_runner runner; - runner.allowAll(); - int rv = runner.run(); - return rv<0?-1:0; -} diff --git a/modules/test/suite.h b/modules/test/suite.h deleted file mode 100644 index 34f29bf..0000000 --- a/modules/test/suite.h +++ /dev/null @@ -1,43 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include - -namespace saw { -namespace test { -class test_runner; -class test_case { -private: - std::string file; - uint line; - std::string description; - bool matched_filter; - test_case* next; - test_case** prev; - - friend class test_runner; -public: - test_case(const std::string& file_, uint line_, const std::string& description_); - ~test_case(); - - virtual void run() = 0; -}; -} -} -#define SAW_TEST(description) \ - class SAW_UNIQUE_NAME(test_case) : public ::saw::test::test_case { \ - public: \ - SAW_UNIQUE_NAME(test_case)(): ::saw::test::test_case(__FILE__,__LINE__,description) {} \ - void run() override; \ - }SAW_UNIQUE_NAME(test_case_); \ - void SAW_UNIQUE_NAME(test_case)::run() - -#define SAW_EXPECT(expr, msg_split) \ - if( ! (expr) ){ \ - auto msg = msg_split; \ - throw std::runtime_error{std::string{msg}};\ - } -- cgit v1.2.3