rpn/src/rpn-test-core.h

201 lines
6.3 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)=="##")
{
cout << entry;
2017-04-22 22:49:44 +02:00
cout << endl;
2015-05-19 17:51:03 +02:00
}
else if (entry.substr(0,1)=="#")
{
2017-04-22 22:49:44 +02:00
// indicates the status of previous test
if (failed == false && tests > 0)
cout<<FG_GREEN<<" PASSED"<<COLOR_OFF<<endl;
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;
cout << test_title;
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)
{
cout<<FG_RED<<" FAIL"<<COLOR_OFF<<endl;
tests_failed++;
is_test_error_shown = true;
}
steps_failed++;
// show failure
cout<<"\t"<<entry<<endl;
cout<<"\tbut real stack size is "<<FG_RED<<stk.size()<<COLOR_OFF<<endl;
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(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;
for (int i = (int)stk.size() - 1; i >= 0; i--)
{
stringstream os;
if (i < (int)(stk.size() - 1))
stack_is += ", ";
((object*)stk.seq_obj(i))->show(os);
getline(os, tmp);
stack_is += tmp;
}
if (stack_is != stack_should_be)
{
2017-04-22 22:49:44 +02:00
// count fail test and step
if (!is_test_error_shown)
{
cout<<FG_RED<<" FAIL"<<COLOR_OFF<<endl;
tests_failed++;
is_test_error_shown = true;
}
steps_failed++;
// show failure
cout<<"\t"<<entry<<endl;
cout<<"\tbut real stack is "<<FG_RED<<stack_is<<COLOR_OFF<<endl;
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_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)
{
cout<<FG_RED<<" FAIL"<<COLOR_OFF<<endl;
tests_failed++;
is_test_error_shown = true;
}
steps_failed++;
// show failure
cout<<"\t"<<entry<<endl;
cout<<"\tbut last error is "<<FG_RED<<last_err<<COLOR_OFF<<endl;
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)
cout << FG_GREEN << " PASSED" << COLOR_OFF << endl;
2015-05-19 17:51:03 +02:00
// cerr back
cerr.rdbuf(cerr_old_buffer);
2017-04-22 22:49:44 +02:00
// conclusion
cout<<endl<<"Run "<<tests<<" tests: "<<tests-tests_failed<<" passed, ";
if(tests_failed>0)
cout<<FG_RED;
cout<<tests_failed<<" failed";
if(tests_failed>0)
cout<<COLOR_OFF;
cout<<" ("<<steps<<" steps: "<<steps-steps_failed<<" passed, ";
if(steps_failed>0)
cout<<FG_RED;
cout<<steps_failed<<" failed";
if(steps_failed>0)
cout<<COLOR_OFF;
cout<<")"<<endl;
2015-05-19 17:51:03 +02:00
}
else
cerr << "test file '"<<test_filename<<"' not found" << endl;
}