mirror of
https://github.com/louisrubet/rpn
synced 2025-01-07 17:24:19 +01:00
250 lines
7.8 KiB
C
250 lines
7.8 KiB
C
void test_get_stack(string& stack_is, stack& stk)
|
|
{
|
|
// write stack in a string, each entry separated between commas
|
|
for (int i = 0; i < (int)stk.size(); i++)
|
|
{
|
|
FILE* tmp_file = tmpfile();
|
|
char* line = NULL;
|
|
size_t len;
|
|
|
|
if (i > 0)
|
|
stack_is += ", ";
|
|
|
|
if (tmp_file != NULL)
|
|
{
|
|
((object*)stk.seq_obj(i))->show(tmp_file);
|
|
|
|
// write stack in a tmp file
|
|
(void)rewind(tmp_file);
|
|
if (getline(&line, &len, tmp_file) >=0)
|
|
{
|
|
stack_is += line;
|
|
free(line);
|
|
}
|
|
(void)fclose(tmp_file);
|
|
}
|
|
else
|
|
ERR_CONTEXT(ret_runtime_error);
|
|
}
|
|
}
|
|
|
|
void test_show_result(string title, int tests, int tests_failed, int steps, int steps_failed)
|
|
{
|
|
printf("%s: run %d tests: %d passed, ", title.c_str(), tests, tests-tests_failed);
|
|
if(tests_failed>0)
|
|
printf(FG_RED);
|
|
printf("%d failed", tests_failed);
|
|
if(tests_failed>0)
|
|
printf(COLOR_OFF);
|
|
|
|
printf(" (%d steps: %d passed, ", steps, steps-steps_failed);
|
|
if(steps_failed>0)
|
|
printf(FG_RED);
|
|
printf("%d failed", steps_failed);
|
|
if(steps_failed>0)
|
|
printf(COLOR_OFF);
|
|
printf(")\n");
|
|
}
|
|
|
|
void test()
|
|
{
|
|
MIN_ARGUMENTS(1);
|
|
ARG_MUST_BE_OF_TYPE(0, cmd_string);
|
|
|
|
int total_tests=0;
|
|
int total_tests_failed=0;
|
|
int total_steps=0;
|
|
int total_steps_failed=0;
|
|
|
|
string test_filename = ((ostring*)_stack->pop_back())->_value;
|
|
test(test_filename, total_tests, total_tests_failed, total_steps, total_steps_failed);
|
|
test_show_result("Total", total_tests, total_tests_failed, total_steps, total_steps_failed);
|
|
}
|
|
|
|
void test(string test_filename, int& total_tests, int& total_tests_failed, int& total_steps, int& total_steps_failed)
|
|
{
|
|
const string stack_size("-> stack size should be ");
|
|
const string stack_value("-> stack should be ");
|
|
const string cmd_error("-> error should be ");
|
|
const string cmd_exit("exit test");
|
|
|
|
ifstream test_file(test_filename.c_str());
|
|
int tests = 0;
|
|
int tests_failed = 0;
|
|
int steps = 0;
|
|
int steps_failed = 0;
|
|
|
|
if (test_file.is_open())
|
|
{
|
|
string test_title;
|
|
string entry;
|
|
ret_value ret;
|
|
stack stk;
|
|
heap hp;
|
|
bool failed = false;
|
|
bool is_first_step;
|
|
bool is_test_error_shown;
|
|
int last_err;
|
|
stringstream cerr_buffer;
|
|
streambuf* cerr_old_buffer;
|
|
|
|
// redirect cerr
|
|
cerr_old_buffer = cerr.rdbuf(cerr_buffer.rdbuf());
|
|
|
|
while (!test_file.eof())
|
|
{
|
|
getline(test_file, entry);
|
|
|
|
if (entry.substr(0,8)=="#include")
|
|
test(entry.substr(9), total_tests, total_tests_failed, total_steps, total_steps_failed);
|
|
else if (entry.substr(0,2)=="##")
|
|
printf("\n%s: %s\n", test_filename.c_str(), entry.substr(3).c_str());
|
|
else if (entry.substr(0,2)=="# ")
|
|
{
|
|
// indicates the status of previous test
|
|
if (failed == false && tests > 0)
|
|
printf(FG_GREEN " PASSED" COLOR_OFF "\n");
|
|
failed = false;
|
|
|
|
// read a test title
|
|
test_title = entry;
|
|
is_first_step = true;
|
|
is_test_error_shown = false;
|
|
printf("%s", test_title.c_str());
|
|
}
|
|
// treat "-> stack size should be "
|
|
else if (entry.find(stack_size, 0) == 0)
|
|
{
|
|
// count test and step
|
|
if (is_first_step)
|
|
tests++;
|
|
steps++;
|
|
|
|
// check current stack size
|
|
istringstream isub;
|
|
int size;
|
|
|
|
isub.str(entry.substr(stack_size.size()));
|
|
isub>>size;
|
|
if (size != (int)stk.size())
|
|
{
|
|
// count fail test and step
|
|
if (!is_test_error_shown)
|
|
{
|
|
printf(FG_RED " FAIL" COLOR_OFF "\n");
|
|
tests_failed++;
|
|
is_test_error_shown = true;
|
|
}
|
|
steps_failed++;
|
|
|
|
// show failure
|
|
printf("\t%s\n", entry.c_str());
|
|
printf("\tbut real stack size is " FG_RED "%d" COLOR_OFF "\n", stk.size());
|
|
failed = true;
|
|
}
|
|
is_first_step = false;
|
|
}
|
|
// treat "-> stack should be "
|
|
else if (entry.find(stack_value, 0) == 0)
|
|
{
|
|
// count test
|
|
if (is_first_step)
|
|
tests++;
|
|
steps++;
|
|
|
|
// check current stack value
|
|
string stack_should_be = entry.substr(stack_value.size());
|
|
string stack_is;
|
|
|
|
test_get_stack(stack_is, stk);
|
|
|
|
if (stack_is != stack_should_be)
|
|
{
|
|
// count fail test and step
|
|
if (!is_test_error_shown)
|
|
{
|
|
printf(FG_RED " FAIL" COLOR_OFF "\n");
|
|
tests_failed++;
|
|
is_test_error_shown = true;
|
|
}
|
|
steps_failed++;
|
|
|
|
// show failure
|
|
printf("\t%s\n", entry.c_str());
|
|
printf("\tbut real stack size is " FG_RED "%s" COLOR_OFF "\n", stack_is.c_str());
|
|
failed = true;
|
|
}
|
|
is_first_step = false;
|
|
}
|
|
// treat "-> error should be "
|
|
else if (entry.find(cmd_error, 0) == 0)
|
|
{
|
|
// count test
|
|
if (is_first_step)
|
|
tests++;
|
|
steps++;
|
|
|
|
// check current error
|
|
istringstream isub;
|
|
int err_should_be;
|
|
isub.str(entry.substr(cmd_error.size()));
|
|
isub>>err_should_be;
|
|
if (err_should_be != last_err)
|
|
{
|
|
// count fail test and step
|
|
if (!is_test_error_shown)
|
|
{
|
|
printf(FG_RED " FAIL" COLOR_OFF "\n");
|
|
tests_failed++;
|
|
is_test_error_shown = true;
|
|
}
|
|
steps_failed++;
|
|
|
|
// show failure
|
|
printf("\t%s\n", entry.c_str());
|
|
printf("\tbut last error is " FG_RED "%d" COLOR_OFF "\n", last_err);
|
|
failed = true;
|
|
}
|
|
is_first_step = false;
|
|
}
|
|
else if (entry.find(cmd_exit, 0) == 0)
|
|
{
|
|
// forced test end
|
|
break;
|
|
}
|
|
else if (entry.size() > 0)
|
|
{
|
|
// parse entry and run line
|
|
program prog;
|
|
ret = program::parse(entry.c_str(), prog);
|
|
if (ret == ret_ok)
|
|
{
|
|
// run it
|
|
(void)prog.run(stk, hp);
|
|
last_err = (int)prog.get_err();
|
|
}
|
|
}
|
|
}
|
|
|
|
// last test
|
|
// indicates the status of previous test
|
|
if (failed == false && tests > 0)
|
|
printf(FG_GREEN " PASSED" COLOR_OFF "\n");
|
|
|
|
// cerr back
|
|
cerr.rdbuf(cerr_old_buffer);
|
|
|
|
// conclusion: show and keep for total
|
|
if (tests != 0)
|
|
{
|
|
test_show_result(test_filename, tests, tests_failed, steps, steps_failed);
|
|
|
|
total_tests += tests;
|
|
total_tests_failed += tests_failed;
|
|
total_steps += steps;
|
|
total_steps_failed += steps_failed;
|
|
}
|
|
}
|
|
else
|
|
fprintf(stderr, "test file '%s' not found\n", test_filename.c_str());
|
|
}
|