Skip to content

Commit 56c99de

Browse files
committed
test skipping, CLI extension support
1 parent 4b2dc92 commit 56c99de

11 files changed

Lines changed: 123 additions & 34 deletions

File tree

example/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ target_sources(example_test PRIVATE
33
tparams.cpp
44
params.cpp
55
fixtures.cpp
6+
conditional.cpp
67
)
78

89
add_executable(params_debug params_debug.cpp)

example/conditional.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include <rsl/test>
2+
#include <rsl/config>
3+
4+
namespace demo::conditional {
5+
6+
[[=rsl::test, =rsl::skip]]
7+
void never_run() {
8+
ASSERT(false);
9+
}
10+
11+
static constexpr bool skip = true;
12+
[[=rsl::test, =rsl::skip_if(skip)]]
13+
void skip_constant() {
14+
ASSERT(false);
15+
}
16+
17+
bool should_skip() {
18+
// determine at runtime whether to skip or not
19+
return true;
20+
}
21+
22+
[[=rsl::test, =rsl::skip_if(should_skip)]]
23+
void skip_runtime() {
24+
ASSERT(false);
25+
}
26+
27+
struct CLI : rsl::cli_extension<CLI> {
28+
[[=option, =flag]] bool skip_cli = false;
29+
};
30+
31+
[[=rsl::test, =rsl::skip_if([] { return CLI::value.skip_cli; })]]
32+
void skip_cli() {
33+
ASSERT(false, "Pass --skip-cli to disable this test.");
34+
}
35+
36+
[[=rsl::test, =rsl::skip_if(&CLI::skip_cli)]]
37+
void skip_cli2() {
38+
ASSERT(false, "Pass --skip-cli to disable this test.");
39+
}
40+
} // namespace

example/tparams.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ consteval std::vector<rsl::testing::ParamSet> make_tparams() {
1212
[[=rsl::tparams({{^^int, 10}, {^^float, 21}})]]
1313
[[=rsl::params({{42, 'c'}, {12, 'b'}})]]
1414
constexpr inline auto tparam_gt_5 = []<typename T, unsigned I>(int a, char b) static {
15-
ASSERT(I < 5);
15+
ASSERT(I > 5);
1616
};
1717

1818
struct TestAggregate{ unsigned value; };

include/rsl/testing/all.hpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,19 @@
1010
#include <rsl/testing/_testing_impl/discovery.hpp>
1111

1212
namespace rsl {
13-
using testing::expect_failure;
1413
using testing::fixture;
15-
using testing::params;
14+
using testing::fuzz;
15+
using testing::property_test;
1616
using testing::test;
17+
18+
using testing::params;
1719
using testing::tparams;
1820

21+
using testing::expect_failure;
22+
using testing::rename;
23+
using testing::skip;
24+
using testing::skip_if;
25+
1926
} // namespace rsl
2027

2128
#ifndef RSLTEST_IMPL_USED

include/rsl/testing/annotations.hpp

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#pragma once
2+
#include <type_traits>
23
#include <vector>
34
#include <initializer_list>
45
#include <meta>
@@ -29,15 +30,32 @@ struct Skip {
2930
bool (*value)() = &_testing_impl::constant_predicate<true>;
3031
};
3132

32-
struct SkipIf {
33-
static consteval Skip operator()(auto condition) {
34-
// TODO wrap arbitrary conditions
35-
return Skip();
36-
}
37-
};
3833

39-
struct Rename {
40-
rsl::string_view value;
34+
namespace _impl {
35+
template <typename T, bool T::*condition>
36+
bool wrap_cli_nsdm() {
37+
return T::get().*condition;
38+
}
39+
}
40+
41+
struct SkipIf {
42+
static consteval Skip operator()(bool condition) {
43+
return {extract<bool (*)()>(
44+
substitute(^^_testing_impl::constant_predicate, {std::meta::reflect_constant(condition)}))};
45+
}
46+
47+
static consteval Skip operator()(bool (*condition)()) { return {condition}; }
48+
49+
template <typename T>
50+
requires requires { T::get(); }
51+
static consteval Skip operator()(bool T::* condition) {
52+
return {extract<bool (*)()>(
53+
substitute(^^_impl::wrap_cli_nsdm, {^^T, std::meta::reflect_constant(condition)}))};
54+
}
55+
};
56+
57+
struct Rename {
58+
rsl::string_view value;
4159

4260
static consteval Rename operator()(std::string_view new_name) {
4361
return Rename(define_static_string(new_name));

include/rsl/testing/test_case.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,17 @@
55

66
namespace rsl::testing {
77

8+
enum class TestOutcome: uint8_t {
9+
FAIL,
10+
PASS,
11+
SKIP
12+
};
13+
814
struct TestResult {
915
class Test const* test;
1016
std::string name;
11-
bool passed;
17+
18+
TestOutcome outcome;
1219
double duration_ms;
1320

1421
std::string failure;

src/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
target_sources(rsltest PRIVATE
1+
target_sources(rsltest PUBLIC
22
capture.cpp
33
test.cpp
44
)

src/main/reporters/catch2xml.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,11 +198,17 @@ class[[= rename("xml")]] Catch2XmlReporter : public Reporter::Registrar<Catch2Xm
198198
section->stderr = {.value = result.stderr};
199199
}
200200

201-
if (result.passed) {
202-
++section->results.successes;
203-
} else {
204-
section->failure = {.value = result.failure};
205-
++section->results.failures;
201+
switch (result.outcome) {
202+
using enum TestOutcome;
203+
case PASS: ++section->results.successes; break;
204+
case FAIL:
205+
section->failure = {.value = result.failure};
206+
++section->results.failures;
207+
break;
208+
case SKIP:
209+
section->results.skipped = true;
210+
++tc.result.skips;
211+
break;
206212
}
207213
section->results.durationInSeconds += result.duration_ms / 1000.;
208214

src/main/reporters/terminal.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class [[=rename("plain")]] ConsoleReporter : public Reporter::Registrar<ConsoleR
1414
auto const color = std::array{must_colorize ? "\033[32m" : "", must_colorize ? "\033[31m" : ""};
1515
const char* const reset = must_colorize ? "\033[0m" : "";
1616

17-
if (result.passed) {
17+
if (result.outcome == TestOutcome::PASS) {
1818
std::print("[{} OK {}] {} ({:.3f} ms)\n",
1919
color[0],
2020
reset,
@@ -32,7 +32,7 @@ class [[=rename("plain")]] ConsoleReporter : public Reporter::Registrar<ConsoleR
3232
}
3333
}
3434
void after_run(std::span<TestResult> results) override {
35-
auto passed = std::ranges::count_if(results, [](auto& r) { return r.passed; });
35+
auto passed = std::ranges::count_if(results, [](auto& r) { return r.outcome == TestOutcome::PASS; });
3636
std::print("=== Summary ===\n{} / {} tests passed.\n", passed, results.size());
3737
}
3838

src/main/reporters/xml.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class [[=rename("junit")]] JUnitXmlReporter : public Reporter::Registrar<JUnitXm
2222
void before_test(TestCase const& test) override {}
2323
void after_test(TestResult const& result) override {
2424
auto node = testcase{.name=std::string(result.name), .time=result.duration_ms / 1000.};
25-
if (!result.passed) {
25+
if (result.outcome == TestOutcome::FAIL) {
2626
node.failure = result.failure + "\n";
2727
}
2828
suite.tests.push_back(node);

0 commit comments

Comments
 (0)