libarc-validate/arc/validate/main.cxx

156 lines
4.0 KiB
C++
Raw Permalink Normal View History

#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