2023-02-11 16:25:24 +01:00
# include "test.h"
# include <stdio.h>
# include <stdlib.h>
2023-02-12 18:39:50 +01:00
# include "common.h"
2023-02-11 16:25:24 +01:00
# include "log.h"
# define TEST_GROUP_ENTRIES_ALLOC 16
2023-02-12 17:27:48 +01:00
/**
* create a new test suite .
*
* @ return test suite struct instance , with space allocated for adding test
* group functions .
*/
test_suite_t
test_suite_new ( void )
2023-02-11 16:25:24 +01:00
{
2023-02-12 17:27:48 +01:00
test_suite_t suite ;
2023-02-11 16:25:24 +01:00
2023-02-12 17:27:48 +01:00
suite = ( test_suite_t ) { 0 } ;
2023-02-12 18:39:50 +01:00
suite . entries = smalloc ( ( sizeof * ( suite . entries ) ) * TEST_GROUP_ENTRIES_ALLOC ) ;
2023-02-12 17:27:48 +01:00
suite . entries [ 0 ] = NULL ;
suite . entries_cap = TEST_GROUP_ENTRIES_ALLOC ;
2023-02-11 16:25:24 +01:00
2023-02-12 17:27:48 +01:00
return suite ;
2023-02-11 16:25:24 +01:00
}
2023-02-12 17:27:48 +01:00
/**
* free dynamically allocated memory occupied by a test suite
*
* @ param suite : a pointer to the suite to free up
*/
2023-02-11 16:25:24 +01:00
void
2023-02-12 17:27:48 +01:00
test_suite_free ( test_suite_t * suite )
2023-02-11 16:25:24 +01:00
{
2023-02-12 17:27:48 +01:00
free ( suite - > entries ) ;
2023-02-11 16:25:24 +01:00
}
2023-02-12 17:27:48 +01:00
/**
* add a test group function to a test suite .
*
* @ param suite : the suite to add the test group function to
* @ param func : the test group function
*/
2023-02-11 16:25:24 +01:00
void
2023-02-12 17:27:48 +01:00
test_suite_add ( test_suite_t * suite , test_entry_func_t func )
2023-02-11 16:25:24 +01:00
{
2023-02-12 17:27:48 +01:00
if ( suite - > entries_len = = suite - > entries_cap - 1 )
2023-02-11 16:25:24 +01:00
{
2023-02-12 17:27:48 +01:00
suite - > entries_cap + = TEST_GROUP_ENTRIES_ALLOC ;
2023-02-12 18:39:50 +01:00
suite - > entries = realloc ( suite - > entries , ( sizeof * ( suite - > entries ) ) * suite - > entries_cap ) ;
2023-02-11 16:25:24 +01:00
}
2023-02-12 17:27:48 +01:00
suite - > entries [ suite - > entries_len ] = func ;
suite - > entries_len + = 1 ;
suite - > entries [ suite - > entries_len ] = NULL ;
2023-02-11 16:25:24 +01:00
}
2023-02-12 17:27:48 +01:00
/**
* run the entries within a test suite and print a message informing the user
* about the number of passed or failed tests .
*
* @ param suite : the suite to run
*
* @ return test results ( number of successful and failed tests )
*/
2023-02-11 16:25:24 +01:00
test_results_t
2023-02-12 17:27:48 +01:00
test_suite_run ( test_suite_t * suite )
2023-02-11 16:25:24 +01:00
{
test_results_t total_result , result ;
size_t i ;
total_result = ( test_results_t ) { 0 } ;
2023-02-12 17:27:48 +01:00
for ( i = 0 ; i < suite - > entries_len ; i + + )
2023-02-11 16:25:24 +01:00
{
2023-02-12 17:27:48 +01:00
result = suite - > entries [ i ] ( ) ;
2023-02-11 16:25:24 +01:00
total_result . success + = result . success ;
total_result . failure + = result . failure ;
}
if ( total_result . failure = = 0 )
2023-02-12 17:27:48 +01:00
log_ok ( " all tests successful (%zu tests in %zu groups) \n " , total_result . success , suite - > entries_len ) ;
2023-02-11 16:25:24 +01:00
else
2023-02-12 17:27:48 +01:00
log_error ( " tests unsuccessful (%zu tests in %zu groups, out of which %zu successful and %zu failures) \n " , total_result . success + total_result . failure , suite - > entries_len , total_result . success , total_result . failure ) ;
2023-02-11 16:25:24 +01:00
return total_result ;
}
2023-02-12 17:27:48 +01:00
/**
* create a new test group .
*
* @ return a test group struct instance
*/
test_group_t
test_group_new ( void )
2023-02-11 16:25:24 +01:00
{
2023-02-12 17:27:48 +01:00
return ( test_group_t ) { 0 } ;
2023-02-11 16:25:24 +01:00
}
2023-02-12 17:27:48 +01:00
/**
* add a test to a test group , update its status and print an error message if
* the test failed .
*
* @ param group : the test group to add the test to
* @ param success : wheter the assertion was successful
* @ param assertion : a string containing the assertion expression
* @ param file : the file in which the test was added
* @ param line : the source code line where the test was added
*
* @ usage the header file ` test . h ` defines various macros for using this
* function . file name and line will be inserted automatically , and
* assertion macros may be used to fill in the ` success ` and
* ` assertion ` parameters .
*/
2023-02-11 16:25:24 +01:00
void
2023-02-12 17:27:48 +01:00
test_group_add ( test_group_t * group , bool success , const char * assertion , const char * name , const char * file , size_t line )
2023-02-11 16:25:24 +01:00
{
if ( success )
2023-02-12 17:27:48 +01:00
group - > results . success + = 1 ;
2023-02-11 16:25:24 +01:00
else
{
2023-02-12 17:27:48 +01:00
group - > results . failure + = 1 ;
2023-02-11 16:25:24 +01:00
log_print_fl ( LOG_LEVEL_ERROR , file , line , " test '%s' (assertion '%s') failed \n " , name , assertion ) ;
}
}
2023-02-12 17:27:48 +01:00
/**
* get results of a test group . used for returning the status from a test group
* function .
*
* @ param group : the group to query
*/
2023-02-11 16:25:24 +01:00
test_results_t
2023-02-12 17:27:48 +01:00
test_group_get_results ( test_group_t * group )
2023-02-11 16:25:24 +01:00
{
2023-02-12 17:27:48 +01:00
return group - > results ;
2023-02-11 16:25:24 +01:00
}