rpn/src/rpn-test-core.h

220 lines
7.2 KiB
C
Raw Normal View History

void program::test()
{
2017-04-22 22:49:44 +02:00
MIN_ARGUMENTS(1);
ARG_MUST_BE_OF_TYPE(0, cmd_string);
2015-05-19 17:51:03 +02:00
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");
2017-04-22 22:49:44 +02:00
string test_filename = ((ostring*)_stack->pop_back())->_value;
2015-05-19 17:51:03 +02:00
ifstream test_file(test_filename.c_str());
2017-04-22 22:49:44 +02:00
int tests = 0;
int tests_failed = 0;
int steps = 0;
int steps_failed = 0;
2015-05-19 17:51:03 +02:00
if (test_file.is_open())
{
string test_title;
string entry;
ret_value ret;
stack stk;
heap hp;
bool failed = false;
2017-04-22 22:49:44 +02:00
bool is_first_step;
bool is_test_error_shown;
2015-05-19 17:51:03 +02:00
int last_err;
stringstream cerr_buffer;
streambuf* cerr_old_buffer;
2015-05-19 17:51:03 +02:00
// redirect cerr
cerr_old_buffer = cerr.rdbuf(cerr_buffer.rdbuf());
2017-04-22 22:49:44 +02:00
while (!test_file.eof())
2015-05-19 17:51:03 +02:00
{
getline(test_file, entry);
if (entry.substr(0,2)=="##")
2017-05-24 14:09:52 +02:00
printf("%s\n", entry.c_str());
else if (entry.substr(0,2)=="# ")
2015-05-19 17:51:03 +02:00
{
2017-04-22 22:49:44 +02:00
// indicates the status of previous test
if (failed == false && tests > 0)
2017-05-24 14:09:52 +02:00
printf(FG_GREEN " PASSED" COLOR_OFF "\n");
2017-04-22 22:49:44 +02:00
failed = false;
2015-05-19 17:51:03 +02:00
// read a test title
test_title = entry;
2017-04-22 22:49:44 +02:00
is_first_step = true;
is_test_error_shown = false;
2017-05-24 14:09:52 +02:00
printf("%s", test_title.c_str());
2015-05-19 17:51:03 +02:00
}
// treat "-> stack size should be "
2015-05-19 17:51:03 +02:00
else if (entry.find(stack_size, 0) == 0)
{
2017-04-22 22:49:44 +02:00
// count test and step
if (is_first_step)
tests++;
steps++;
2015-05-19 17:51:03 +02:00
// check current stack size
istringstream isub;
int size;
2015-05-19 17:51:03 +02:00
isub.str(entry.substr(stack_size.size()));
isub>>size;
if (size != (int)stk.size())
{
2017-04-22 22:49:44 +02:00
// count fail test and step
if (!is_test_error_shown)
{
2017-05-24 14:09:52 +02:00
printf(FG_RED " FAIL" COLOR_OFF "\n");
2017-04-22 22:49:44 +02:00
tests_failed++;
is_test_error_shown = true;
}
steps_failed++;
// show failure
2017-05-24 14:09:52 +02:00
printf("\t%s\n", entry.c_str());
printf("\tbut real stack size is " FG_RED "%d" COLOR_OFF "\n", stk.size());
2015-05-19 17:51:03 +02:00
failed = true;
}
2017-04-22 22:49:44 +02:00
is_first_step = false;
2015-05-19 17:51:03 +02:00
}
// treat "-> stack should be "
2015-05-19 17:51:03 +02:00
else if (entry.find(stack_value, 0) == 0)
{
2017-04-22 22:49:44 +02:00
// count test
if (is_first_step)
tests++;
steps++;
2015-05-19 17:51:03 +02:00
// check current stack value
string stack_should_be = entry.substr(stack_value.size());
string stack_is;
string tmp;
2017-05-24 14:09:52 +02:00
FILE* tmp_file = tmpfile();
if (tmp_file != NULL)
2015-05-19 17:51:03 +02:00
{
2017-05-24 14:09:52 +02:00
char* line;
for (int i = 0; i < (int)stk.size(); i++)
2017-04-22 22:49:44 +02:00
{
2017-05-24 14:09:52 +02:00
if (i > 0)
stack_is += ", ";
rewind(tmp_file);
((object*)stk.seq_obj(i))->show(tmp_file);
line = NULL;
if (getline(&line, NULL, tmp_file) >=0)
{
stack_is += line;
free(line);
}
else
{
ERR_CONTEXT(ret_runtime_error);
break;
}
2017-04-22 22:49:44 +02:00
}
2017-05-24 14:09:52 +02:00
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++;
2017-04-22 22:49:44 +02:00
2017-05-24 14:09:52 +02:00
// 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;
fclose(tmp_file);
2015-05-19 17:51:03 +02:00
}
2017-05-24 14:09:52 +02:00
else
ERR_CONTEXT(ret_runtime_error);
2015-05-19 17:51:03 +02:00
}
// treat "-> error should be "
2015-05-19 17:51:03 +02:00
else if (entry.find(cmd_error, 0) == 0)
{
2017-04-22 22:49:44 +02:00
// count test
if (is_first_step)
tests++;
steps++;
2015-05-19 17:51:03 +02:00
// 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)
{
2017-04-22 22:49:44 +02:00
// count fail test and step
if (!is_test_error_shown)
{
2017-05-24 14:09:52 +02:00
printf(FG_RED " FAIL" COLOR_OFF "\n");
2017-04-22 22:49:44 +02:00
tests_failed++;
is_test_error_shown = true;
}
steps_failed++;
// show failure
2017-05-24 14:09:52 +02:00
printf("\t%s\n", entry.c_str());
printf("\tbut last error is " FG_RED "%d" COLOR_OFF "\n", last_err);
2015-05-19 17:51:03 +02:00
failed = true;
}
2017-04-22 22:49:44 +02:00
is_first_step = false;
2015-05-19 17:51:03 +02:00
}
else if (entry.find(cmd_exit, 0) == 0)
{
// forced test end
break;
}
else if (entry.size() > 0)
{
// parse entry and run line
program prog;
2015-02-26 22:33:28 +01:00
ret = program::parse(entry.c_str(), prog);
2015-05-19 17:51:03 +02:00
if (ret == ret_ok)
{
// run it
(void)prog.run(stk, hp);
last_err = (int)prog.get_err();
}
}
}
2017-04-22 22:49:44 +02:00
// last test
// indicates the status of previous test
if (failed == false && tests > 0)
2017-05-24 14:09:52 +02:00
printf(FG_GREEN " PASSED" COLOR_OFF "\n");
2015-05-19 17:51:03 +02:00
// cerr back
cerr.rdbuf(cerr_old_buffer);
2017-04-22 22:49:44 +02:00
// conclusion
2017-05-24 14:09:52 +02:00
printf("\nRun %d tests: %d passed, ", tests, tests-tests_failed);
2017-04-22 22:49:44 +02:00
if(tests_failed>0)
2017-05-24 14:09:52 +02:00
printf(FG_RED);
printf("%d failed", tests_failed);
2017-04-22 22:49:44 +02:00
if(tests_failed>0)
2017-05-24 14:09:52 +02:00
printf(COLOR_OFF);
2017-04-22 22:49:44 +02:00
2017-05-24 14:09:52 +02:00
printf(" (%d steps: %d passed, ", steps, steps-steps_failed);
2017-04-22 22:49:44 +02:00
if(steps_failed>0)
2017-05-24 14:09:52 +02:00
printf(FG_RED);
printf("%d failed", steps_failed);
2017-04-22 22:49:44 +02:00
if(steps_failed>0)
2017-05-24 14:09:52 +02:00
printf(COLOR_OFF);
printf(")\n");
2015-05-19 17:51:03 +02:00
}
else
2017-05-24 14:09:52 +02:00
fprintf(stderr, "test file '%s' not found\n", test_filename.c_str());
}