162 lines
4.7 KiB
C++
162 lines
4.7 KiB
C++
#include <iostream>
|
|
#include <optional>
|
|
#include "tester.hpp"
|
|
|
|
const std::string ANSI_RESET = "\033[0m";
|
|
const std::string ANSI_DARK = "\033[38;5;8m";
|
|
const std::string ANSI_BLUE = "\033[38;5;6m";
|
|
const std::string ANSI_GREEN = "\033[38;5;2m";
|
|
const std::string ANSI_RED = "\033[38;5;1m";
|
|
const std::string ANSI_YELLOW = "\033[38;5;11m";
|
|
|
|
Tester::Tester(std::string test_name) :
|
|
parent(),
|
|
name(test_name),
|
|
succeeded(0), failed(0),
|
|
detailed(true)
|
|
{
|
|
intro();
|
|
}
|
|
|
|
Tester::Tester(Tester* tester_parent, std::string test_name) :
|
|
parent(tester_parent),
|
|
name(test_name),
|
|
succeeded(0), failed(0),
|
|
detailed(false)
|
|
{
|
|
intro();
|
|
}
|
|
|
|
Tester::Tester(Tester* tester_parent, std::string test_name, bool show_details) :
|
|
parent(tester_parent),
|
|
name(test_name),
|
|
succeeded(0), failed(0),
|
|
detailed(show_details)
|
|
{
|
|
intro();
|
|
}
|
|
|
|
int Tester::depth() {
|
|
int depth = 0;
|
|
for (std::optional<Tester*> at = this; at.has_value(); at = (*at)->parent) {
|
|
depth++;
|
|
}
|
|
return depth;
|
|
}
|
|
|
|
std::string Tester::full_name() {
|
|
std::string full_name(name);
|
|
std::optional<Tester*> at = parent;
|
|
while (at.has_value()) {
|
|
full_name.insert(0, " ");
|
|
full_name.insert(0, (*at)->name);
|
|
at = (*at)->parent;
|
|
}
|
|
return full_name;
|
|
}
|
|
|
|
std::string Tester::prefix() {
|
|
std::string line = full_name();
|
|
line.insert(0, "[ ");
|
|
|
|
line.append(" ]");
|
|
|
|
int wanted_len = 10 * depth();
|
|
if (line.length() == wanted_len) {
|
|
line.insert(0, ANSI_BLUE);
|
|
line.append(ANSI_RESET);
|
|
line.append(" ");
|
|
return line;
|
|
} else if (line.length() > wanted_len) {
|
|
line.append("\n");
|
|
line.append(ANSI_DARK);
|
|
for (int i = 0; i < wanted_len; i++)
|
|
line.append("—");
|
|
|
|
line.insert(0, ANSI_BLUE);
|
|
line.append(ANSI_RESET);
|
|
line.append(" ");
|
|
return line;
|
|
} else {
|
|
int extra = wanted_len - line.length();
|
|
line.append(" ");
|
|
line.append(ANSI_DARK);
|
|
for (int i = 1; i < extra; i++)
|
|
line.append("—");
|
|
|
|
line.insert(0, ANSI_BLUE);
|
|
line.append(ANSI_RESET);
|
|
line.append(" ");
|
|
return line;
|
|
}
|
|
}
|
|
|
|
void Tester::intro() {
|
|
if (shown())
|
|
std::cout << prefix() << "=== " << ANSI_YELLOW << "start" << ANSI_RESET << std::endl;
|
|
}
|
|
|
|
bool name_show_overwritten(std::string name) {
|
|
char *shown_c = std::getenv("SHOW_CASE");
|
|
if (shown_c == NULL)
|
|
return false;
|
|
std::string shown(shown_c);
|
|
|
|
shown.push_back(' ');
|
|
shown.insert(0, " ");
|
|
|
|
name.push_back(' ');
|
|
name.insert(0, " ");
|
|
|
|
return shown.find(name) != std::string::npos;
|
|
}
|
|
|
|
bool Tester::shown() {
|
|
for (std::optional<Tester*> at = this; at.has_value(); at = (*at)->parent) {
|
|
if (name_show_overwritten((*at)->name))
|
|
return true;
|
|
}
|
|
|
|
for (std::optional<Tester*> at = this; at.has_value(); at = (*at)->parent) {
|
|
if (!(*at)->detailed)
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void Tester::assert_eq_str(std::string test_name, bool correct, std::string got_s, std::string expected_s) {
|
|
if (correct) {
|
|
if (shown()) {
|
|
std::cout << prefix() << ANSI_GREEN << "✓ " << ANSI_RESET << test_name << ANSI_RESET << std::endl;
|
|
}
|
|
for (std::optional<Tester*> at = this; at.has_value(); at = (*at)->parent) {
|
|
(*at)->succeeded++;
|
|
}
|
|
} else {
|
|
std::cout << prefix() << ANSI_RED << "✗ " << ANSI_RESET << test_name << " - " << ANSI_RED << "got " << got_s << ", expected " << expected_s << ANSI_RESET << std::endl;
|
|
for (std::optional<Tester*> at = this; at.has_value(); at = (*at)->parent) {
|
|
(*at)->failed++;
|
|
}
|
|
}
|
|
}
|
|
|
|
Tester::~Tester() {
|
|
finish();
|
|
}
|
|
|
|
void Tester::finish() {
|
|
char n_cases_s[10], n_succeeded_s[10], n_failed_s[10];
|
|
snprintf(n_cases_s, sizeof n_cases_s, "%d", succeeded + failed);
|
|
snprintf(n_succeeded_s, sizeof n_succeeded_s, "%d", succeeded);
|
|
snprintf(n_failed_s, sizeof n_failed_s, "%d", failed);
|
|
if (failed == 0) {
|
|
// printf("[ %s ] - %sall succeeded%s, out of %d total\n", name.c_str(), ANSI_GREEN.c_str(), ANSI_RESET.c_str(), succeeded + failed);
|
|
if (shown())
|
|
std::cout << prefix() << "=== " << ANSI_GREEN << "all succeeded" << ANSI_RESET << ", out of " << n_cases_s << " total" << std::endl;
|
|
} else {
|
|
std::cout << prefix() << "=== " << ANSI_RED << n_failed_s << " failed" << ANSI_RESET << ", " << ANSI_GREEN << n_succeeded_s << " succeeded" << ANSI_RESET << " out of " << n_cases_s << " total" << std::endl;
|
|
// printf("[ %s ] - %s%d failed, %d succeeded%s, out of %d total\n", name.c_str(), ANSI_RED.c_str(), failed, succeeded, ANSI_RESET.c_str(), succeeded + failed);
|
|
}
|
|
}
|
|
|