1
0
mirror of https://github.com/Refactorio/RedMew.git synced 2025-03-17 21:08:08 +02:00

stop_on_first_error option

This commit is contained in:
James Gillham 2020-09-29 20:50:24 +01:00
parent 00fbe5853e
commit 965cebb005
3 changed files with 104 additions and 36 deletions

View File

@ -7,20 +7,15 @@ Command.add(
{
description = "Runs tests and opens the test runner, use flag 'open' to skip running tests first.",
arguments = {'open'},
default_values = {open = false}
default_values = {open = false},
allowed_by_server = false
},
function(args, player)
local open = args.open
if open == 'open' or open == 'o' then
if player == nil then
print('Can not open test runner from server console.')
return
end
Viewer.open(player)
return
else
Runner.run_module(nil, player)
end
Runner.run_module(nil, player)
end
)

View File

@ -14,9 +14,9 @@ Public.events = {
local run_runnables_token
local function print_summary(count, fail_count)
local pass_count = count - fail_count
game.print(table.concat {pass_count, ' of ', count, ' tests passed.'})
local function print_summary(data)
local pass_count = data.count - data.fail_count
data.player.print(table.concat {pass_count, ' of ', data.count, ' tests passed.'})
end
local function mark_module_for_passed(module)
@ -50,21 +50,21 @@ local function mark_modules_for_passed()
end
local function finish_test_run(data)
print_summary(data.count, data.fail_count)
print_summary(data)
mark_modules_for_passed()
script.raise_event(Public.events.tests_run_finished, {player = data.player})
end
local function print_error(test_name, error_message)
game.print(table.concat {"Failed - '", test_name, "': ", tostring(error_message)}, {r = 1})
local function print_error(player, test_name, error_message)
player.print(table.concat {"Failed - '", test_name, "': ", tostring(error_message)}, {r = 1})
end
local function print_success(test_name)
game.print(table.concat {"Passed - '", test_name, "'"}, {g = 1})
local function print_success(player, test_name)
player.print(table.concat {"Passed - '", test_name, "'"}, {g = 1})
end
local function print_hook_error(hook)
game.print(table.concat {'Failed ', hook.name, " hook -':", tostring(hook.error)}, {r = 1})
hook.context.player.print(table.concat {'Failed ', hook.name, " hook -':", tostring(hook.error)}, {r = 1})
end
local function record_hook_error_in_module(hook)
@ -75,16 +75,29 @@ local function record_hook_error_in_module(hook)
end
end
local function do_termination(data)
if not data.stop_on_first_error then
return false
end
data.player.print('Test run canceled due to stop on first error policy.')
finish_test_run(data)
data.index = -1
return true
end
local function run_hook(hook)
local context = hook.context
local steps = context._steps
local current_step = hook.current_step
local func
if current_step == 0 then
func = hook.func
else
func = steps[current_step].func
end
local success, return_value = pcall(func, context)
if not success then
@ -103,6 +116,11 @@ end
local function do_hook(hook, data)
local hook_success = run_hook(hook)
if hook_success == false and do_termination(data) then
return
end
if hook_success == nil then
local step_index = hook.current_step + 1
local step = hook.context._steps[step_index]
@ -120,23 +138,25 @@ local function run_test(test)
local context = test.context
local steps = context._steps
local current_step = test.current_step
local func
if current_step == 0 then
func = test.func
else
func = steps[current_step].func
end
local success, return_value = pcall(func, context)
if not success then
print_error(test.name, return_value)
print_error(context.player, test.name, return_value)
test.passed = false
test.error = return_value
return false
end
if current_step == #steps then
print_success(test.name)
print_success(context.player, test.name)
test.passed = true
return true
end
@ -150,6 +170,11 @@ local function do_test(test, data)
if success == false then
data.count = data.count + 1
data.fail_count = data.fail_count + 1
if do_termination(data) then
return
end
data.index = data.index + 1
Task.set_timeout_in_ticks(1, run_runnables_token, data)
return
@ -179,26 +204,41 @@ local function run_runnables(data)
if runnable.is_hook then
do_hook(runnable, data)
return
else
do_test(runnable, data)
end
do_test(runnable, data)
end
run_runnables_token = Token.register(run_runnables)
local function run(runnables, player)
run_runnables({runnables = runnables, player = player, index = 1, count = 0, fail_count = 0})
local function validate_options(options)
options = options or {}
options.stop_on_first_error = options.stop_on_first_error or false
return options
end
function Public.run_module(module, player)
local function run(runnables, player, options)
options = validate_options(options)
run_runnables(
{
runnables = runnables,
player = player,
index = 1,
count = 0,
fail_count = 0,
stop_on_first_error = options.stop_on_first_error
}
)
end
function Public.run_module(module, player, options)
local runnables = Builder.build_module_for_run(module or ModuleStore.root_module, player)
run(runnables, player)
run(runnables, player, options)
end
function Public.run_test(test, player)
function Public.run_test(test, player, options)
local runnables = Builder.build_test_for_run(test, player)
run(runnables, player)
run(runnables, player, options)
end
return Public

View File

@ -26,16 +26,20 @@ local module_label_name = Gui.uid_name()
local test_label_name = Gui.uid_name()
local run_all_button_name = Gui.uid_name()
local run_selected_button_name = Gui.uid_name()
local stop_on_error_checkbox_name = Gui.uid_name()
local error_test_box_name = Gui.uid_name()
local selected_test_info_by_player_index = {}
local stop_on_first_error_by_player_index = {}
Global.register(
{
selected_test_info_by_player_index = selected_test_info_by_player_index
selected_test_info_by_player_index = selected_test_info_by_player_index,
stop_on_first_error_by_player_index = stop_on_first_error_by_player_index
},
function(tbl)
selected_test_info_by_player_index = tbl.selected_test_info_by_player_index
stop_on_first_error_by_player_index = tbl.stop_on_first_error_by_player_index
end
)
@ -206,7 +210,7 @@ local function draw_tests(container)
end
local function draw_error_text_box(container)
local text = get_text_box_error()
local text = get_text_box_error(container.player_index)
local text_box = container.add {type = 'text-box', name = error_test_box_name, text = text}
local style = text_box.style
@ -229,6 +233,12 @@ local function create_main_frame(center)
name = run_selected_button_name,
caption = 'Run Selected'
}
top_flow.add {
type = 'checkbox',
name = stop_on_error_checkbox_name,
caption = 'Stop on first error',
state = stop_on_first_error_by_player_index[center.player_index] or false
}
draw_tests(frame)
@ -249,17 +259,21 @@ local function get_error_text_box(player)
return frame_data.error_text_box
end
local function make_options(player_index)
return {stop_on_first_error = stop_on_first_error_by_player_index[player_index]}
end
local run_module_token =
Token.register(
function(data)
Runner.run_module(data.module, data.player)
Runner.run_module(data.module, data.player, data.options)
end
)
local run_test_token =
Token.register(
function(data)
Runner.run_test(data.test, data.player)
Runner.run_test(data.test, data.player, data.options)
end
)
@ -344,7 +358,9 @@ Gui.on_click(
function(event)
local frame = event.player.gui.center[main_frame_name]
close_main_frame(frame)
Task.set_timeout_in_ticks(1, run_module_token, {module = nil, player = event.player})
local options = make_options(event.player_index)
Task.set_timeout_in_ticks(1, run_module_token, {module = nil, player = event.player, options = options})
end
)
@ -356,11 +372,21 @@ Gui.on_click(
return
end
local options = make_options(event.player_index)
local info_type = test_info.type
if info_type == info_type_module then
Task.set_timeout_in_ticks(1, run_module_token, {module = test_info.module, player = event.player})
Task.set_timeout_in_ticks(
1,
run_module_token,
{module = test_info.module, player = event.player, options = options}
)
elseif info_type == info_type_test then
Task.set_timeout_in_ticks(1, run_test_token, {test = test_info.test, player = event.player})
Task.set_timeout_in_ticks(
1,
run_test_token,
{test = test_info.test, player = event.player, options = options}
)
else
return
end
@ -370,6 +396,13 @@ Gui.on_click(
end
)
Gui.on_checked_state_changed(
stop_on_error_checkbox_name,
function(event)
stop_on_first_error_by_player_index[event.player_index] = event.element.state or nil
end
)
Event.add(
Runner.events.tests_run_finished,
function(event)