2014-09-05 14:39:24 +02:00
|
|
|
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;
|
2014-09-05 14:39:24 +02:00
|
|
|
|
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;
|
2014-09-05 14:39:24 +02:00
|
|
|
|
2015-05-19 17:51:03 +02:00
|
|
|
// redirect cerr
|
|
|
|
cerr_old_buffer = cerr.rdbuf(cerr_buffer.rdbuf());
|
2014-09-05 14:39:24 +02:00
|
|
|
|
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());
|
2017-04-23 15:37:42 +02:00
|
|
|
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
|
|
|
}
|
2017-04-23 15:37:42 +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;
|
2014-09-05 14:39:24 +02:00
|
|
|
|
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
|
|
|
}
|
2017-04-23 15:37:42 +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
|
|
|
}
|
2017-04-23 15:37:42 +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");
|
2014-09-05 14:39:24 +02:00
|
|
|
|
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());
|
2014-09-05 14:39:24 +02:00
|
|
|
}
|