diff options
Diffstat (limited to 'cpp/050scenario.cc')
-rw-r--r-- | cpp/050scenario.cc | 242 |
1 files changed, 76 insertions, 166 deletions
diff --git a/cpp/050scenario.cc b/cpp/050scenario.cc index 5dbc940a..dc839a10 100644 --- a/cpp/050scenario.cc +++ b/cpp/050scenario.cc @@ -4,10 +4,7 @@ :(before "End Types") struct scenario { string name; - string dump_layer; string to_run; - map<int, int> memory_expectations; - // End scenario Fields }; :(before "End Globals") @@ -15,178 +12,111 @@ vector<scenario> Scenarios; //:: How we check Scenarios. -:(before "End Tests") -time_t mu_time; time(&mu_time); -cerr << "\nMu tests: " << ctime(&mu_time); -for (size_t i = 0; i < Scenarios.size(); ++i) { - run_mu_test(i); -} - -:(code) -void run_mu_test(size_t i) { - setup(); - Trace_file = Scenarios[i].name; - START_TRACING_UNTIL_END_OF_SCOPE - if (!Scenarios[i].dump_layer.empty()) - Trace_stream->dump_layer = Scenarios[i].dump_layer; -//? cerr << "AAA " << Scenarios[i].name << '\n'; //? 1 -//? cout << Scenarios[i].to_run; //? 2 - run(Scenarios[i].to_run); -//? cout << "after: " << Memory[1] << '\n'; //? 1 -//? cout << "after:\n"; dump_memory(); //? 1 - for (map<int, int>::iterator p = Scenarios[i].memory_expectations.begin(); - p != Scenarios[i].memory_expectations.end(); - ++p) { - if (Memory[p->first] != p->second) { - // todo: unit tests for the test parsing infrastructure; use raise? - cerr << Scenarios[i].name << ": Expected location " << p->first << " to contain " << p->second << " but saw " << Memory[p->first] << '\n'; - Passed = false; - } - } - // End Scenario Checks - teardown(); - if (Passed) cerr << "."; -} - -//:: How we create Scenarios. +:(scenarios run_mu_scenario) +:(scenario scenario_block) +scenario foo [ + run [ + 1:integer <- copy 13:literal + ] + memory-should-contain [ + 1 <- 13 + ] +] +# checks are inside scenario -:(scenarios "parse_scenario") -:(scenario parse_scenario_memory_expectation) +:(scenario scenario_multiple_blocks) scenario foo [ run [ - a <- b + 1:integer <- copy 13:literal + ] + memory-should-contain [ + 1 <- 13 + ] + run [ + 2:integer <- copy 13:literal ] - memory should contain [ - 1 <- 0 + memory-should-contain [ + 1 <- 13 + 2 <- 13 ] ] -+parse: scenario will run: a <- b -:(scenario parse_scenario_memory_expectation_duplicate) -% Hide_warnings = true; +:(scenario scenario_check_memory_and_trace) scenario foo [ run [ - a <- b + 1:integer <- copy 13:literal + trace [a], [a b c] ] - memory should contain [ - 1 <- 0 - 1 <- 1 + memory-should-contain [ + 1 <- 13 + ] + trace-should-contain [ + a: a b c + ] + trace-should-not-contain [ + a: x y z ] ] -+warn: duplicate expectation for location 1: 0 -> 1 -:(before "End Command Handlers") -else if (command == "scenario") { -//? cout << "AAA scenario\n"; //? 1 - Scenarios.push_back(parse_scenario(in)); +:(code) +// just for tests +void run_mu_scenario(const string& form) { + istringstream in(form); + in >> std::noskipws; + assert(next_word(in) == "scenario"); + scenario s = parse_scenario(in); + run_mu_scenario(s); } -:(code) scenario parse_scenario(istream& in) { - scenario x; - x.name = next_word(in); - trace("parse") << "reading scenario " << x.name; + scenario result; + result.name = next_word(in); skip_bracket(in, "'scenario' must begin with '['"); ostringstream buffer; slurp_until_matching_bracket(in, buffer); -//? cout << "inner buffer: ^" << buffer.str() << "$\n"; //? 1 - istringstream inner(buffer.str()); - inner >> std::noskipws; - while (!inner.eof()) { - skip_whitespace_and_comments(inner); - string scenario_command = next_word(inner); - if (scenario_command.empty() && inner.eof()) break; - // Scenario Command Handlers - if (scenario_command == "run") { - handle_scenario_run_directive(inner, x); - } - else if (scenario_command == "memory") { - handle_scenario_memory_directive(inner, x); - } - else if (scenario_command == "dump") { - skip_whitespace_and_comments(inner); - x.dump_layer = next_word(inner); - } - // End Scenario Command Handlers - else { - raise << "unknown command in scenario: ^" << scenario_command << "$\n"; - } - } - return x; + result.to_run = buffer.str(); + return result; } -void handle_scenario_run_directive(istream& in, scenario& result) { - skip_bracket(in, "'run' inside scenario must begin with '['"); - ostringstream buffer; - slurp_until_matching_bracket(in, buffer); - string trace_result = buffer.str(); // temporary copy - trace("parse") << "scenario will run: " << trim(trace_result); -//? cout << buffer.str() << '\n'; //? 1 - result.to_run = "recipe test-"+result.name+" [" + buffer.str() + "]"; +void run_mu_scenario(const scenario& s) { + setup(); + // In this layer we're writing tangle scenarios about mu scenarios. + // Don't need to set Trace_file and Trace_stream in that situation. + // Hackily simulate a conditional START_TRACING_UNTIL_END_OF_SCOPE. + bool temporary_trace_file = Trace_file.empty(); + if (temporary_trace_file) Trace_file = s.name; + cerr << Trace_file << '\n'; + bool delete_trace_stream = !Trace_stream; + if (delete_trace_stream) Trace_stream = new trace_stream; +//? START_TRACING_UNTIL_END_OF_SCOPE; + run("recipe "+s.name+" [ " + s.to_run + " ]"); + teardown(); + if (delete_trace_stream) { + ofstream fout((Trace_dir+Trace_file).c_str()); + fout << Trace_stream->readable_contents(""); + fout.close(); + delete Trace_stream; + Trace_stream = NULL; + } + if (temporary_trace_file) Trace_file = ""; } -void handle_scenario_memory_directive(istream& in, scenario& out) { - if (next_word(in) != "should") { - raise << "'memory' directive inside scenario must continue 'memory should'\n"; - } - if (next_word(in) != "contain") { - raise << "'memory' directive inside scenario must continue 'memory should contain'\n"; - } - skip_bracket(in, "'memory' directive inside scenario must begin with 'memory should contain ['\n"); - while (true) { - skip_whitespace_and_comments(in); - if (in.eof()) break; -//? cout << "a: " << in.peek() << '\n'; //? 1 - if (in.peek() == ']') break; - string lhs = next_word(in); - if (!is_number(lhs)) { - handle_type(lhs, in, out); - continue; - } - int address = to_int(lhs); -//? cout << "address: " << address << '\n'; //? 2 -//? cout << "b: " << in.peek() << '\n'; //? 1 - skip_whitespace_and_comments(in); -//? cout << "c: " << in.peek() << '\n'; //? 1 - string _assign; in >> _assign; assert(_assign == "<-"); - skip_whitespace_and_comments(in); - int value = 0; in >> value; - if (out.memory_expectations.find(address) != out.memory_expectations.end()) - raise << "duplicate expectation for location " << address << ": " << out.memory_expectations[address] << " -> " << value << '\n'; - out.memory_expectations[address] = value; - trace("parse") << "memory expectation: *" << address << " == " << value; - } - skip_whitespace(in); - assert(in.get() == ']'); +:(before "End Command Handlers") +else if (command == "scenario") { + Scenarios.push_back(parse_scenario(in)); } -void handle_type(const string& lhs, istream& in, scenario& out) { - reagent x(lhs); - if (x.properties[0].second[0] == "string") { - x.set_value(to_int(x.name)); -//? cerr << x.name << ' ' << x.value << '\n'; //? 1 - skip_whitespace_and_comments(in); - string _assign = next_word(in); -//? cerr << _assign << '\n'; //? 1 - assert(_assign == "<-"); - skip_whitespace_and_comments(in); - string literal = next_word(in); -//? cerr << literal << '\n'; //? 1 - size_t address = x.value; - out.memory_expectations[address] = literal.size()-2; // exclude quoting brackets - ++address; - for (size_t i = 1; i < literal.size()-1; ++i) { -//? cerr << "checking " << address << ": " << literal[i] << '\n'; //? 1 - out.memory_expectations[address] = literal[i]; - ++address; - } - return; - } - raise << "scenario doesn't know how to parse memory expectation on " << lhs << '\n'; +:(before "End Tests") +time_t mu_time; time(&mu_time); +cerr << "\nMu tests: " << ctime(&mu_time); +for (size_t i = 0; i < Scenarios.size(); ++i) { + run_mu_scenario(Scenarios[i]); + if (Passed) cerr << "."; } //:: Helpers +:(code) void slurp_until_matching_bracket(istream& in, ostream& out) { int brace_depth = 1; // just scanned '[' char c; @@ -197,23 +127,3 @@ void slurp_until_matching_bracket(istream& in, ostream& out) { out << c; } } - -:(code) -// for tests -void parse_scenario(const string& s) { - istringstream in(s); - in >> std::noskipws; - skip_whitespace_and_comments(in); - string _scenario = next_word(in); -//? cout << _scenario << '\n'; //? 1 - assert(_scenario == "scenario"); - parse_scenario(in); -} - -:(before "End Includes") -#include <sys/stat.h> -:(code) -bool file_exists(const string& filename) { - struct stat buffer; - return stat(filename.c_str(), &buffer) == 0; -} |