forked from arc/libarc-validate
156 lines
4.0 KiB
C++
156 lines
4.0 KiB
C++
|
#include <arc/validate/command-line.hxx>
|
||
|
#include <arc/validate/except.hxx>
|
||
|
#include <arc/validate/main.hxx>
|
||
|
#include <arc/validate/test.hxx>
|
||
|
#include <arc/validate/version.hxx>
|
||
|
|
||
|
#include <iostream>
|
||
|
|
||
|
namespace arc::validate
|
||
|
{
|
||
|
|
||
|
static
|
||
|
void
|
||
|
print_version()
|
||
|
{
|
||
|
std::cout << "libarc-validate test runner (" << LIBARC_VALIDATE_VERSION_ID << ")\n";
|
||
|
}
|
||
|
|
||
|
static
|
||
|
void
|
||
|
print_usage(std::string const& execname)
|
||
|
{
|
||
|
std::cout << "Usage: " << execname << " [<option>...] [<file>...]\n"
|
||
|
<< '\n'
|
||
|
<< "Mandatory arguments to long options are mandatory for short options too.\n"
|
||
|
<< '\n'
|
||
|
<< " -- Treat all remaining arguments as files.\n"
|
||
|
<< " --version Print version information and exit.\n"
|
||
|
<< " --help Display this help and exit.\n"
|
||
|
<< " --print-information Print test information.\n"
|
||
|
<< " --print-warnings Print warnings.\n"
|
||
|
<< " --print-success Print successful test information.\n"
|
||
|
<< " --print-failure Print failed test information.\n"
|
||
|
<< " --verbose Print everything.\n"
|
||
|
<< " -i, --include <name> Include execution of test <name>.\n"
|
||
|
<< " -e, --exclude <name> Exclude execution of test <name>.\n"
|
||
|
<< " -l, --list List available tests and exit.\n"
|
||
|
<< '\n'
|
||
|
<< "If any filenames are specified on the command line the program will terminate.\n"
|
||
|
<< '\n'
|
||
|
<< "Unknown tests passed as arguments to --include or --exclude are ignored.\n"
|
||
|
<< '\n'
|
||
|
;
|
||
|
}
|
||
|
|
||
|
static
|
||
|
bool
|
||
|
execute_test(test_t const& test,
|
||
|
bool print_information,
|
||
|
bool print_warnings,
|
||
|
bool print_success,
|
||
|
bool print_failure)
|
||
|
{
|
||
|
if (print_information) {
|
||
|
std::cout << "Executing test: " << test.name() << '\n';
|
||
|
}
|
||
|
|
||
|
try {
|
||
|
test.function()();
|
||
|
|
||
|
if (print_success) {
|
||
|
std::cout << "Test passed: " << test.name() << '\n';
|
||
|
}
|
||
|
}
|
||
|
catch (skipped_t const&) {
|
||
|
if (print_information) {
|
||
|
std::cout << "Test skipped: " << test.name() << '\n';
|
||
|
}
|
||
|
}
|
||
|
catch (not_implemented_t const&) {
|
||
|
if (print_warnings) {
|
||
|
std::cout << "Test not implemented: " << test.name() << '\n';
|
||
|
}
|
||
|
}
|
||
|
catch (failure_t const& failure) {
|
||
|
if (print_failure) {
|
||
|
std::cout << "Test failed: " << test.name() << '\n';
|
||
|
std::cout << failure.extras() << '\n';
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
int
|
||
|
main(int argc, char* argv[])
|
||
|
{
|
||
|
return main(argv[0], {argv + 1, argv + argc});
|
||
|
}
|
||
|
|
||
|
int
|
||
|
main(std::string const& execname, std::vector<std::string> const& args)
|
||
|
try
|
||
|
{
|
||
|
auto command_line = parse_command_line(args);
|
||
|
|
||
|
if (command_line.print_version) {
|
||
|
print_version();
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (command_line.print_usage) {
|
||
|
print_usage(execname);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (command_line.list) {
|
||
|
std::cout << "Available tests:\n\n";
|
||
|
|
||
|
for (auto const& j : test_t::get_tests()) {
|
||
|
std::cout << " - \"" << j->name() << "\"\n";
|
||
|
}
|
||
|
|
||
|
std::cout << '\n';
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// Let's execute some tests!
|
||
|
//
|
||
|
|
||
|
bool failed{false};
|
||
|
auto tests = test_t::get_tests(command_line.include, command_line.exclude);
|
||
|
|
||
|
for (auto const& j : tests) {
|
||
|
bool success = execute_test(
|
||
|
*j,
|
||
|
command_line.print_information,
|
||
|
command_line.print_warnings,
|
||
|
command_line.print_success,
|
||
|
command_line.print_failure
|
||
|
);
|
||
|
|
||
|
if (!success) {
|
||
|
failed = true;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (failed) {
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
catch (std::exception const& ex) {
|
||
|
std::cerr << execname << ": error: " << ex.what() << ".\n";
|
||
|
return 1;
|
||
|
}
|
||
|
catch (...) {
|
||
|
std::cerr << execname << ": unknown error.\n";
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
} // namespace arc::validate
|