tinyyarn

scenario testing of Unix command line tools
Log | Files | Refs | README | LICENSE

commit e2f5e318e279d24d6730262221354da8e0a54976
parent d056f24f7b07910ac35c7d832bff517deaf66d9f
Author: Richard Ipsum <richardipsum@vx21.xyz>
Date:   Fri, 23 Oct 2020 23:53:36 +0200

err if last scenario line is not THEN

also err if last scenario has no THEN before FINALLY

Diffstat:
Mtyarn.lua.in | 79+++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------
1 file changed, 55 insertions(+), 24 deletions(-)

diff --git a/tyarn.lua.in b/tyarn.lua.in @@ -94,67 +94,102 @@ function parse_implementations(filepath, implementations) end function validate_scenario(steps_seen, scenario_name, scenario_line_no) - if not steps_seen["WHEN"] then + local seen_when = false + local seen_then = false + local i + + for n, step_type in ipairs(steps_seen) do + if step_type == "WHEN" then + seen_when = true + elseif step_type == "THEN" then + seen_then = true + end + end + + if not seen_when then io.stderr:write(string.format('Scenario "%s" (line %d) has no WHEN step\n', scenario_name, scenario_line_no)) os.exit(1) end - if not steps_seen["THEN"] then + if not seen_then then io.stderr:write(string.format('Scenario "%s" (line %d) has no THEN step\n', scenario_name, scenario_line_no)) os.exit(1) end + + if steps_seen[#steps_seen] == "FINALLY" then + i = #steps_seen - 1 + while steps_seen[i] == "FINALLY" do + i = i - 1 + end + + if steps_seen[i] ~= "THEN" then + errmsg = 'Scenario "%s" (line %d) does not have a THEN step before FINALLY step\n' + io.stderr:write(string.format(errmsg, scenario_name, scenario_line_no)) + os.exit(1) + end + elseif steps_seen[#steps_seen] ~= "THEN" then + io.stderr:write(string.format('Scenario "%s" (line %d) does not end with THEN or FINALLY step\n', + scenario_name, scenario_line_no)) + os.exit(1) + else + i = #steps_seen + end + + while steps_seen[i] == "THEN" do + i = i - 1 + end + + if steps_seen[i] ~= "WHEN" then + errmsg = 'Scenario "%s" (line %d) does not have a WHEN step before THEN step\n' + io.stderr:write(string.format(errmsg, scenario_name, scenario_line_no)) + os.exit(1) + end end -function parse_scenario_line(scenario, scenario_name, steps_seen, - line, line_no, last_step_type) +function parse_scenario_line(scenario, scenario_name, steps_seen, line, line_no) stripped_line = lstrip(line) if tyarn.re_match(line, "^( )[ \t]*GIVEN") then table.insert(scenario, normalise_scenario_line(stripped_line, "GIVEN")) - last_step_type = "GIVEN" - steps_seen["GIVEN"] = true + table.insert(steps_seen, "GIVEN") elseif tyarn.re_match(line, "^( )[ \t]*WHEN") then table.insert(scenario, normalise_scenario_line(stripped_line, "WHEN")) - last_step_type = "WHEN" - steps_seen["WHEN"] = true + table.insert(steps_seen, "WHEN") elseif tyarn.re_match(line, "^( )[ \t]*THEN") then table.insert(scenario, normalise_scenario_line(stripped_line, "THEN")) - last_step_type = "THEN" - steps_seen["THEN"] = true + table.insert(steps_seen, "THEN") elseif tyarn.re_match(line, "^( )[ \t]*ASSUMING") then table.insert(scenario, normalise_scenario_line(stripped_line, "ASSUMING")) - last_step_type = "ASSUMING" - steps_seen["ASSUMING"] = true + table.insert(steps_seen, "ASSUMING") elseif tyarn.re_match(line, "^( )[ \t]*AND") then - if last_step_type == nil then + if #steps_seen == 0 then io.stderr:write(string.format( 'Scenario "%s" (line %d) has AND as first step: %s\n', scenario_name, line_no, stripped_line)) os.exit(1) end - processed_line = string.gsub(stripped_line, "AND", last_step_type) + processed_line = string.gsub(stripped_line, "AND", steps_seen[#steps_seen]) + table.insert(steps_seen, steps_seen[#steps_seen]) - if last_step_type == "FINALLY" then + if steps_seen[#steps_seen - 1] == "FINALLY" then table.insert(scenario["FINALLY"], processed_line) else table.insert(scenario, processed_line) end elseif tyarn.re_match(line, "^( )[ \t]*FINALLY") then - last_step_type = "FINALLY" - steps_seen["FINALLY"] = true + table.insert(steps_seen, "FINALLY") table.insert(scenario["FINALLY"], normalise_scenario_line(stripped_line, "FINALLY")) elseif tyarn.re_match(line, "^( )[ \t]*\\.\\.\\.") then - if last_step_type == nil then + if #steps_seen == 0 then io.stderr:write(string.format( 'Scenario "%s" (line %d) has ... as first step: %s\n', scenario_name, line_no, stripped_line)) os.exit(1) end - -- continuation of previous scenario line scenario[#scenario] = scenario[#scenario] .. ' ' .. lstrip(string.gsub(stripped_line, '^...', '', 1)) elseif tyarn.re_match(line, "^( )[ \t]*.+") then @@ -163,14 +198,11 @@ function parse_scenario_line(scenario, scenario_name, steps_seen, scenario_name, line_no, stripped_line)) os.exit(1) end - - return last_step_type end function _parse_scenarios(scenario_list, scenarios, filepath, file, scenario_name, scenario_line_no) debug('Parsing scenario', scenario_name) - last_step_type = nil scenario = {} scenario["FINALLY"] = {} line_no = scenario_line_no @@ -193,8 +225,7 @@ function _parse_scenarios(scenario_list, scenarios, filepath, end if in_scenario then - last_step_type = parse_scenario_line(scenario, scenario_name, steps_seen, - line, line_no, last_step_type) + parse_scenario_line(scenario, scenario_name, steps_seen, line, line_no) end -- ignore lines that aren't indented by one level