diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-04-12 23:29:59 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-04-12 23:33:49 -0700 |
commit | 43d2d20e55c052c5844a38d0d87526f68c7e2217 (patch) | |
tree | 9c85c2b09adbd9f40836649875310c5b23a3ceb6 /cpp | |
parent | d03028a3035fc514a694a89dcec9429625c9217c (diff) | |
download | mu-43d2d20e55c052c5844a38d0d87526f68c7e2217.tar.gz |
1058 - scenarios can now check trace
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/.traces/first_scenario_checking_trace | 11 | ||||
-rw-r--r-- | cpp/.traces/first_scenario_checking_trace_negative | 11 | ||||
-rw-r--r-- | cpp/.traces/trace_in_mu | 7 | ||||
-rw-r--r-- | cpp/031scenario | 3 | ||||
-rw-r--r-- | cpp/034scenario_trace | 101 | ||||
-rw-r--r-- | cpp/035scenario_trace_test.mu | 27 |
6 files changed, 160 insertions, 0 deletions
diff --git a/cpp/.traces/first_scenario_checking_trace b/cpp/.traces/first_scenario_checking_trace new file mode 100644 index 00000000..8ea5d60b --- /dev/null +++ b/cpp/.traces/first_scenario_checking_trace @@ -0,0 +1,11 @@ +parse/0: instruction: 2 +parse/0: ingredient: {name: "2", value: 0, type: 0, properties: ["2": "literal"]} +parse/0: ingredient: {name: "2", value: 0, type: 0, properties: ["2": "literal"]} +parse/0: product: {name: "1", value: 0, type: 1, properties: ["1": "integer"]} +after-brace/0: recipe test-first_scenario_checking_trace +after-brace/0: add ... +run/0: instruction test-first_scenario_checking_trace/0 +run/0: ingredient 0 is 2 +run/0: ingredient 1 is 2 +run/0: product 0 is 4 +mem/0: storing 4 in location 1 diff --git a/cpp/.traces/first_scenario_checking_trace_negative b/cpp/.traces/first_scenario_checking_trace_negative new file mode 100644 index 00000000..e80d680f --- /dev/null +++ b/cpp/.traces/first_scenario_checking_trace_negative @@ -0,0 +1,11 @@ +parse/0: instruction: 2 +parse/0: ingredient: {name: "2", value: 0, type: 0, properties: ["2": "literal"]} +parse/0: ingredient: {name: "2", value: 0, type: 0, properties: ["2": "literal"]} +parse/0: product: {name: "1", value: 0, type: 1, properties: ["1": "integer"]} +after-brace/0: recipe test-first_scenario_checking_trace_negative +after-brace/0: add ... +run/0: instruction test-first_scenario_checking_trace_negative/0 +run/0: ingredient 0 is 2 +run/0: ingredient 1 is 2 +run/0: product 0 is 4 +mem/0: storing 4 in location 1 diff --git a/cpp/.traces/trace_in_mu b/cpp/.traces/trace_in_mu new file mode 100644 index 00000000..dc7d8d8a --- /dev/null +++ b/cpp/.traces/trace_in_mu @@ -0,0 +1,7 @@ +parse/0: instruction: 32 +parse/0: ingredient: {name: "foo", value: 0, type: 0, properties: ["foo": "literal-string"]} +parse/0: ingredient: {name: "aaa", value: 0, type: 0, properties: ["aaa": "literal-string"]} +after-brace/0: recipe test-trace_in_mu +after-brace/0: trace ... +run/0: instruction test-trace_in_mu/0 +foo/0: aaa diff --git a/cpp/031scenario b/cpp/031scenario index f3bd582c..c595ce82 100644 --- a/cpp/031scenario +++ b/cpp/031scenario @@ -1,8 +1,10 @@ +//: Allow tests to be written in mu files. :(before "End Types") struct scenario { string name; string to_run; map<int, int> memory_expectations; + // End scenario Fields }; :(before "End Globals") @@ -28,6 +30,7 @@ for (size_t i = 0; i < Scenarios.size(); ++i) { Passed = false; } } + // End Scenario Checks if (Passed) cerr << "."; } diff --git a/cpp/034scenario_trace b/cpp/034scenario_trace new file mode 100644 index 00000000..90dab204 --- /dev/null +++ b/cpp/034scenario_trace @@ -0,0 +1,101 @@ +:(before "End scenario Fields") +vector<pair<string, string> > trace_checks; +vector<pair<string, string> > trace_negative_checks; + +:(before "End Scenario Command Handlers") +else if (scenario_command == "trace") { + handle_scenario_trace_directive(inner, x); +} + +:(before "End Scenario Checks") +check_trace_contents(Scenarios[i]); +check_trace_negative_contents(Scenarios[i]); + +:(code) +void handle_scenario_trace_directive(istream& in, scenario& out) { + if (next_word(in) != "should") { + raise << "'trace' directive inside scenario must continue 'trace should'\n"; + } + string s = next_word(in); + if (s == "not") { + handle_scenario_trace_negative_directive(in, out); + return; + } + if (s != "contain") { + raise << "'trace' directive inside scenario must continue 'trace should [not] contain'\n"; + } + skip_bracket(in, "'trace' directive inside scenario must begin with 'trace should contain ['\n"); + while (true) { + skip_whitespace_and_comments(in); + if (in.eof()) break; + if (in.peek() == ']') break; + string curr_line; + getline(in, curr_line); + istringstream tmp(curr_line); + tmp >> std::noskipws; + string label = slurp_until(tmp, ':'); + if (tmp.get() != ' ') { + raise << "'trace' directive inside scenario should contain lines of the form 'label: message', instead got " << curr_line; + continue; + } + string message = slurp_rest(tmp); + out.trace_checks.push_back(pair<string, string>(label, message)); + trace("scenario") << "trace: " << label << ": " << message << '\n'; + } + skip_whitespace(in); + assert(in.get() == ']'); +} + +void handle_scenario_trace_negative_directive(istream& in, scenario& out) { + // 'not' already slurped + if (next_word(in) != "contain") { + raise << "'trace' directive inside scenario must continue 'trace should not contain'\n"; + } + skip_bracket(in, "'trace' directive inside scenario must begin with 'trace should not contain ['\n"); + while (true) { + skip_whitespace_and_comments(in); + if (in.eof()) break; + if (in.peek() == ']') break; + string curr_line; + getline(in, curr_line); + istringstream tmp(curr_line); + tmp >> std::noskipws; + string label = slurp_until(tmp, ':'); + if (tmp.get() != ' ') { + raise << "'trace' directive inside scenario should contain lines of the form 'label: message', instead got " << curr_line; + continue; + } + string message = slurp_rest(tmp); + out.trace_negative_checks.push_back(pair<string, string>(label, message)); + trace("scenario") << "trace: " << label << ": " << message << '\n'; + } + skip_whitespace(in); + assert(in.get() == ']'); +} + +string slurp_rest(istream& in) { + ostringstream out; + char c; + while (in >> c) { + out << c; + } + return out.str(); +} + +void check_trace_contents(const scenario& s) { + if (s.trace_checks.empty()) return; + ostringstream contents; + for (size_t i = 0; i < s.trace_checks.size(); ++i) { + contents << s.trace_checks[i].first << ": " << s.trace_checks[i].second << ""; + } + CHECK_TRACE_CONTENTS(contents.str()); +} + +void check_trace_negative_contents(const scenario& s) { + for (size_t i = 0; i < s.trace_negative_checks.size(); ++i) { + if (trace_count(s.trace_negative_checks[i].first, s.trace_negative_checks[i].second) > 0) { + raise << "trace shouldn't contain " << s.trace_negative_checks[i].first << ": " << s.trace_negative_checks[i].second << '\n'; + Passed = false; + } + } +} diff --git a/cpp/035scenario_trace_test.mu b/cpp/035scenario_trace_test.mu new file mode 100644 index 00000000..abf0ef9a --- /dev/null +++ b/cpp/035scenario_trace_test.mu @@ -0,0 +1,27 @@ +# tests for trace-checking scenario in previous layer +scenario first_scenario_checking_trace [ + run [ + 1:integer <- add 2:literal, 2:literal + ] + trace should contain [ + mem: storing 4 in location 1 + ] +] + +scenario first_scenario_checking_trace_negative [ + run [ + 1:integer <- add 2:literal, 2:literal + ] + trace should not contain [ + mem: storing 5 in location 1 + ] +] + +scenario trace_in_mu [ + run [ + trace [foo], [aaa] + ] + trace should contain [ + foo: aaa + ] +] |