Skip to content

Commit

Permalink
Explicit argc/argv passing
Browse files Browse the repository at this point in the history
This allows user to explicitly specify args
for the run.

```c++
int main(int argc, const char** argv) {
  // explicitly run registered test suites and manually pass argc/argv
  return ut::cfg<>.run({.argc = argc, .argv = argv});
}
```

To get it working yet another event has been added: `events::run_begin`,
which contains `argc`/`argv` passed by the user.
  • Loading branch information
R2RT authored and kris-jusiak committed Jul 7, 2024
1 parent f17a00a commit fb06064
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 10 deletions.
1 change: 1 addition & 0 deletions example/cfg/reporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class reporter {
auto on(ut::events::fatal_assertion) -> void {}
auto on(ut::events::exception) -> void {}
auto on(ut::events::summary) -> void {}
auto on(ut::events::run_begin) -> void {}
};
} // namespace cfg

Expand Down
5 changes: 3 additions & 2 deletions example/run.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ ut::suite _ = [] {
};
};

int main() {
return ut::cfg<>.run(); // explicitly run registered test suites
int main(int argc, const char** argv) {
// explicitly run registered test suites and manually pass argc/argv
return ut::cfg<>.run({.argc = argc, .argv = argv});
}
33 changes: 25 additions & 8 deletions include/boost/ut.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,10 @@ fixed_string(const CharT (&str)[N]) -> fixed_string<CharT, N - 1>;
struct none {};

namespace events {
struct run_begin {
int argc{};
const char** argv{};
};
struct test_begin {
std::string_view type{};
std::string_view name{};
Expand Down Expand Up @@ -802,11 +806,17 @@ struct cfg {
std::cout << "version: " << BOOST_UT_VERSION << std::endl;
}

static inline void parse_arg_with_fallback(int argc, const char* argv[]) {
if (argc > 0 && argv != nullptr) {
cfg::largc = argc;
cfg::largv = argv;
}
parse(cfg::largc, cfg::largv);
}

static inline void parse(int argc, const char* argv[]) {
const std::size_t n_args = argc > 0 ? static_cast<std::size_t>(argc) : 0U;
if (n_args > 0 && argv != nullptr) {
cfg::largc = argc;
cfg::largv = argv;
executable_name = argv[0];
}
query_pattern = "";
Expand All @@ -816,15 +826,15 @@ struct cfg {
auto cmd_option = find_arg(cmd);
if (!cmd_option.has_value()) {
if (found_first_option) {
std::cerr << "unknown option: '" << argv[i] << "' run:" << std::endl;
std::cerr << "'" << argv[0] << " --help'" << std::endl;
std::cerr << "unknown option: '" << cmd << "' run:" << std::endl;
std::cerr << "'" << executable_name << " --help'" << std::endl;
std::cerr << "for additional help" << std::endl;
std::exit(-1);
} else {
if (i > 1U) {
query_pattern.append(" ");
}
query_pattern.append(argv[i]);
query_pattern.append(cmd);
}
continue;
}
Expand Down Expand Up @@ -1489,6 +1499,8 @@ class reporter {
printer_ = static_cast<TPrinter&&>(printer);
}

auto on(events::run_begin) -> void {}

auto on(events::test_begin test_begin) -> void {
printer_ << "Running \"" << test_begin.name << "\"...";
fails_ = asserts_.fail;
Expand Down Expand Up @@ -1692,8 +1704,11 @@ class reporter_junit {
constexpr auto operator=(TPrinter printer) {
printer_ = static_cast<TPrinter&&>(printer);
}
reporter_junit() : lcout_(std::cout.rdbuf()) {
::boost::ut::detail::cfg::parse(detail::cfg::largc, detail::cfg::largv);
reporter_junit() : lcout_(std::cout.rdbuf()) {}
~reporter_junit() { std::cout.rdbuf(cout_save); }

auto on(events::run_begin run) {
::boost::ut::detail::cfg::parse_arg_with_fallback(run.argc, run.argv);

if (detail::cfg::show_reporters) {
std::cout << "available reporter:\n";
Expand All @@ -1713,7 +1728,6 @@ class reporter_junit {
std::cout.rdbuf(ss_out_.rdbuf());
}
}
~reporter_junit() { std::cout.rdbuf(cout_save); }

auto on(events::suite_begin suite) -> void {
while (active_test_.size() > 0) {
Expand Down Expand Up @@ -1998,6 +2012,8 @@ struct options {

struct run_cfg {
bool report_errors{false};
int argc{0};
const char** argv{nullptr};
};

template <class TReporter = reporter<printer>, auto MaxPathSize = 16>
Expand Down Expand Up @@ -2201,6 +2217,7 @@ class runner {

[[nodiscard]] auto run(run_cfg rc = {}) -> bool {
run_ = true;
reporter_.on(events::run_begin{.argc = rc.argc, .argv = rc.argv});
for (const auto& [suite, suite_name] : suites_) {
// add reporter in/out
if constexpr (requires { reporter_.on(events::suite_begin{}); }) {
Expand Down
19 changes: 19 additions & 0 deletions test/ut/ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,13 +287,22 @@ struct test_summary_reporter : ut::reporter<ut::printer> {
summary_counter_ = &counter;
}

auto count_runs(std::size_t& counter) -> void { runs_counter_ = &counter; }

auto on(ut::events::summary) -> void {
if (summary_counter_) {
++*summary_counter_;
}
}

auto on(ut::events::run_begin) -> void {
if (runs_counter_) {
++*runs_counter_;
}
}

std::size_t* summary_counter_{};
std::size_t* runs_counter_{};
};

struct test_summary_runner : ut::runner<test_summary_reporter> {
Expand Down Expand Up @@ -845,6 +854,16 @@ int main() {
test_assert(1 == summary_count);
}

{
std::size_t run_count = 0;
{
auto run = test_summary_runner{};
run.reporter_.count_runs(run_count);
test_assert(false == run.run({.report_errors = true}));
}
test_assert(1 == run_count);
}

auto& test_cfg = ut::cfg<ut::override>;

{
Expand Down

0 comments on commit fb06064

Please sign in to comment.