:(scenarios run_mu_scenario)
:(scenario screen_in_scenario)
scenario screen-in-scenario [
assume-screen 5:literal/width, 3:literal/height
run [
screen:address <- print-character screen:address, 97:literal
]
screen-should-contain [
.a .
. .
. .
]
]
:(scenario screen_in_scenario_error)
% Hide_warnings = true;
scenario screen-in-scenario-error [
assume-screen 5:literal/width, 3:literal/height
run [
screen:address <- print-character screen:address, 97:literal
]
screen-should-contain [
.b .
. .
. .
]
]
+warn: expected screen location (0, 0) to contain 'b' instead of 'a'
:(before "End Globals")
const size_t Max_variables_in_scenarios = Reserved_for_tests-100;
size_t Next_predefined_global_for_scenarios = Max_variables_in_scenarios;
:(before "End Setup")
assert(Next_predefined_global_for_scenarios < Reserved_for_tests);
:(after "transform_all()" following "case RUN:")
assert(Name[tmp_recipe.at(0)][""] < Max_variables_in_scenarios);
:(before "End Globals")
const size_t SCREEN = Next_predefined_global_for_scenarios++;
:(before "End Predefined Scenario Locals In Run")
Name[tmp_recipe.at(0)]["screen"] = SCREEN;
:(before "End Rewrite Instruction(curr)")
if (curr.name == "assume-screen") {
curr.operation = Recipe_number["init-fake-screen"];
assert(curr.products.empty());
curr.products.push_back(reagent("screen:address"));
curr.products.at(0).set_value(SCREEN);
}
:(before "End Primitive Recipe Declarations")
SCREEN_SHOULD_CONTAIN,
:(before "End Primitive Recipe Numbers")
Recipe_number["screen-should-contain"] = SCREEN_SHOULD_CONTAIN;
:(before "End Primitive Recipe Implementations")
case SCREEN_SHOULD_CONTAIN: {
check_screen(current_instruction().ingredients.at(0).name);
break;
}
:(code)
void check_screen(const string& contents) {
assert(!Current_routine->calls.front().default_space);
index_t screen_location = Memory[SCREEN];
int data_offset = find_element_name(Type_number["screen"], "data");
assert(data_offset >= 0);
index_t screen_data_location = screen_location+data_offset;
index_t screen_data_start = Memory[screen_data_location];
int width_offset = find_element_name(Type_number["screen"], "num-columns");
size_t screen_width = Memory[screen_location+width_offset];
int height_offset = find_element_name(Type_number["screen"], "num-rows");
size_t screen_height = Memory[screen_location+height_offset];
string expected_contents;
istringstream in(contents);
in >> std::noskipws;
for (index_t row = 0; row < screen_height; ++row) {
skip_whitespace_and_comments(in);
assert(!in.eof());
assert(in.get() == '.');
for (index_t column = 0; column < screen_width; ++column) {
assert(!in.eof());
expected_contents += in.get();
}
assert(in.get() == '.');
}
skip_whitespace_and_comments(in);
trace("run") << "checking screen size at " << screen_data_start;
if (Memory[screen_data_start] > static_cast<signed>(expected_contents.size()))
raise << "expected contents are larger than screen size " << Memory[screen_data_start] << '\n';
++screen_data_start;
for (index_t i = 0; i < expected_contents.size(); ++i) {
trace("run") << "checking location " << screen_data_start+i;
if ((!Memory[screen_data_start+i] && !isspace(expected_contents.at(i)))
|| (Memory[screen_data_start+i] && Memory[screen_data_start+i] != expected_contents.at(i))) {
if (Current_scenario && !Hide_warnings) {
raise << "\nF - " << Current_scenario->name << ": expected screen location (" << i/screen_width << ", " << i%screen_width << ") to contain '" << expected_contents.at(i) << "' instead of '" << static_cast<char>(Memory[screen_data_start+i]) << "'\n";
dump_screen();
}
else {
raise << "expected screen location (" << i/screen_width << ", " << i%screen_width << ") to contain '" << expected_contents.at(i) << "' instead of '" << static_cast<char>(Memory[screen_data_start+i]) << "'\n";
}
if (!Hide_warnings) {
Passed = false;
++Num_failures;
}
return;
}
}
}
:(before "End Primitive Recipe Declarations")
_DUMP_SCREEN,
:(before "End Primitive Recipe Numbers")
Recipe_number["$dump-screen"] = _DUMP_SCREEN;
:(before "End Primitive Recipe Implementations")
case _DUMP_SCREEN: {
dump_screen();
break;
}
:(code)
void dump_screen() {
assert(!Current_routine->calls.front().default_space);
index_t screen_location = Memory[SCREEN];
int width_offset = find_element_name(Type_number["screen"], "num-columns");
size_t screen_width = Memory[screen_location+width_offset];
int height_offset = find_element_name(Type_number["screen"], "num-rows");
size_t screen_height = Memory[screen_location+height_offset];
int data_offset = find_element_name(Type_number["screen"], "data");
assert(data_offset >= 0);
index_t screen_data_location = screen_location+data_offset;
index_t screen_data_start = Memory[screen_data_location];
assert(Memory[screen_data_start] == screen_width*screen_height);
index_t curr = screen_data_start+1;
for (index_t row = 0; row < screen_height; ++row) {
for (index_t col = 0; col < screen_width; ++col) {
cerr << static_cast<char>(Memory[curr]);
++curr;
}
cerr << '\n';
}
}