2024-01-12 22:32:45 +01:00
# 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 " ;
2024-01-17 12:25:06 +01:00
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 ( ) ;
}
2024-01-12 22:32:45 +01:00
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 ( ) {
2024-01-17 12:25:06 +01:00
if ( shown ( ) )
std : : cout < < prefix ( ) < < " === " < < ANSI_YELLOW < < " start " < < ANSI_RESET < < std : : endl ;
2024-01-12 22:32:45 +01:00
}
2024-01-17 12:25:06 +01:00
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 ;
2024-01-12 22:32:45 +01:00
}
2024-01-17 12:25:06 +01:00
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 ;
2024-01-12 22:32:45 +01:00
}
void Tester : : assert_eq_str ( std : : string test_name , bool correct , std : : string got_s , std : : string expected_s ) {
if ( correct ) {
2024-01-17 12:25:06 +01:00
if ( shown ( ) ) {
std : : cout < < prefix ( ) < < ANSI_GREEN < < " ✓ " < < ANSI_RESET < < test_name < < ANSI_RESET < < std : : endl ;
}
2024-01-12 22:32:45 +01:00
for ( std : : optional < Tester * > at = this ; at . has_value ( ) ; at = ( * at ) - > parent ) {
( * at ) - > succeeded + + ;
}
} else {
2024-01-17 12:25:06 +01:00
std : : cout < < prefix ( ) < < ANSI_RED < < " ✗ " < < ANSI_RESET < < test_name < < " - " < < ANSI_RED < < " got " < < got_s < < " , expected " < < expected_s < < ANSI_RESET < < std : : endl ;
2024-01-12 22:32:45 +01:00
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);
2024-01-17 12:25:06 +01:00
if ( shown ( ) )
std : : cout < < prefix ( ) < < " === " < < ANSI_GREEN < < " all succeeded " < < ANSI_RESET < < " , out of " < < n_cases_s < < " total " < < std : : endl ;
2024-01-12 22:32:45 +01:00
} 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);
}
}