Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ jobs:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- run: sudo apt-get install clang-19 -y
- run: sudo apt-get install g++-14 -y
- run: cmake -S . -B build && cmake --build build
env:
CXX: /usr/bin/g++-14
- run: ./build/willow_test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ iris.log
build/
.gdb_history
.cache
core
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
### main/HEAD
* Add `Willow::runSingleTest()` function to select a test on the command line

### v0.0.1 - 03/11/25
* Initial repo setup
Expand Down
2 changes: 0 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ project(willow-test LANGUAGES CXX)
add_subdirectory(src/willow)

if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
message("LOCAL BUILD ONLY")
set(CMAKE_CXX_COMPILER "/usr/bin/clang++")
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

Expand Down
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ A unit testing library for modern c++23

# How to use
Currently, willow only supports CMake for distribution, although if you know
what you're doing, feel free to clone the repo and do what you need yourself.
what you're doing, feel free to clone the repo and build it yourself

```cmake
set(CMAKE_CXX_STANDARD 23)
Expand Down Expand Up @@ -45,13 +45,16 @@ auto main() -> int {
// are available
Willow::DefaultReporter reporter = {};

// Your executable will exit with a return code displaying the number of
// failed tests
return Willow::runTests({
// Register each function to test
Willow::registerTests({
// Each test function is given a name to display as output. you can also
// mark tests for skipping
{"addition test", test_add},
{"skipped test", test_add, Willow::Status::Skip},
}, reporter);
});

// Your executable will exit with a return code displaying the number of
// failed tests
return Willow::runTests(reporter);
}
```
27 changes: 15 additions & 12 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,21 @@
#include "willow/reporters.h"
#include "willow/willow.h"

auto main() -> int {
auto main(int argc, char* argv[]) -> int {
Willow::PreCommitReporter reporter = {};

return Willow::runTests(
{
{"test_runTests", test_runTests},
{"test_toString", test_toString},
{"test_Test_alert", test_Test_alert},
{"test_Test_Operator()", test_Test_Operator},
{"PreCommitReporter::print", TestPreCommitReporter::test_print},
{"PreCommitReporter::cleanup", TestPreCommitReporter::test_cleanup},
{"PreCommitReporter::highlight", TestPreCommitReporter::test_highlight},
},
reporter);
Willow::registerTests({
{"test_runTests", test_runTests},
{"test_toString", test_toString},
{"test_Test_alert", test_Test_alert},
{"test_Test_Operator()", test_Test_Operator},
{"PreCommitReporter::print", TestPreCommitReporter::test_print},
{"PreCommitReporter::cleanup", TestPreCommitReporter::test_cleanup},
{"PreCommitReporter::highlight", TestPreCommitReporter::test_highlight},
});

if (argc > 1) {
return Willow::runSingleTest(std::string(argv[1]), reporter);
}
return Willow::runTests(reporter);
}
9 changes: 6 additions & 3 deletions src/tests/test_willow.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ namespace FixtureFuncs {

constexpr auto test_runTests([[maybe_unused]] Willow::Test* test) -> int {
SilentReporter r = {};
int ret = Willow::runTests(
std::vector<Willow::Test> storage = Willow::global_tests;

Willow::registerTests(
{{"pass", FixtureFuncs::pass},
{"fail", FixtureFuncs::fail},
{"skip", FixtureFuncs::fail, Willow::Status::Skip}},
r);
{"skip", FixtureFuncs::fail, Willow::Status::Skip}});

int ret = Willow::runTests(r);
Willow::global_tests = storage;
return !(ret == 1);
}
35 changes: 31 additions & 4 deletions src/willow/willow.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@
#include "test.h"

namespace Willow {
constexpr auto runTests(std::vector<Test> tests, Reporter& reporter) -> int {
for (auto&& test : tests) {
inline std::vector<Test> global_tests = {};

constexpr auto registerTests(std::vector<Test> tests) -> void {
global_tests = tests;
}

constexpr auto runTests(Reporter& reporter) -> int {
for (auto&& test : global_tests) {
if (test.status == Status::Skip) {
continue;
}
Expand All @@ -22,14 +28,35 @@ namespace Willow {
test.status = Status::Pass;
}

std::for_each(tests.begin(), tests.end(), [&reporter](Test& t) { reporter.print(t); });
std::for_each(
global_tests.begin(), global_tests.end(), [&reporter](Test& t) { reporter.print(t); });
reporter.cleanup();

return int32_t(std::count_if(tests.begin(), tests.end(), [](Test& t) {
return int32_t(std::count_if(global_tests.begin(), global_tests.end(), [](Test& t) {
return t.status == Status::Fail;
}));
}

constexpr auto runSingleTest(std::string_view test_name, Reporter& reporter) -> int {
auto it = std::find_if(global_tests.begin(), global_tests.end(), [&test_name](Test& t) {
return t.name.contains(test_name);
});
if (it == global_tests.end()) {
return 1;
}

Test& exec = *it;
if (exec.status == Status::Skip) {
return 2;
}

exec();
exec.status = (exec.retcode == 0 ? Status::Pass : Status::Fail);
reporter.print(exec);

return exec.retcode;
}

} // namespace Willow

#endif // WILLOW_H
Loading