support running tests multiple times

We now collect multiple test failures, but that's just the first step.
This commit is contained in:
Kartik K. Agaram 2023-01-20 20:07:45 -08:00
parent 4c7ea0e776
commit 46889593da
1 changed files with 67 additions and 55 deletions

122
app.lua
View File

@ -12,11 +12,68 @@
-- Scroll below this function for more details.
function love.run()
App.snapshot_love()
-- have LÖVE delegate all handlers to App if they exist
for name in pairs(love.handlers) do
if App[name] then
love.handlers[name] = App[name]
end
end
-- Stash current state of App for tests
App_for_tests = {}
for k,v in pairs(App) do
App_for_tests[k] = v
end
-- there's one nested table
App_for_tests.screen = {}
for k,v in pairs(App.screen) do
App_for_tests.screen[k] = v
end
-- Mutate App for the real app
-- disable test methods
App.screen.init = nil
App.filesystem = nil
App.time = nil
App.run_after_textinput = nil
App.run_after_keychord = nil
App.keypress = nil
App.keyrelease = nil
App.run_after_mouse_click = nil
App.run_after_mouse_press = nil
App.run_after_mouse_release = nil
App.fake_keys_pressed = nil
App.fake_key_press = nil
App.fake_key_release = nil
App.fake_mouse_state = nil
App.fake_mouse_press = nil
App.fake_mouse_release = nil
-- dispatch some methods to real hardware
App.screen.resize = love.window.setMode
App.screen.size = love.window.getMode
App.screen.move = love.window.setPosition
App.screen.position = love.window.getPosition
App.screen.print = love.graphics.print
App.newText = love.graphics.newText
App.screen.draw = love.graphics.draw
App.width = function(text) return text:getWidth() end
App.open_for_reading = function(filename) return io.open(filename, 'r') end
App.open_for_writing = function(filename) return io.open(filename, 'w') end
App.getTime = love.timer.getTime
App.getClipboardText = love.system.getClipboardText
App.setClipboardText = love.system.setClipboardText
App.modifier_down = love.keyboard.isDown
App.mouse_move = love.mouse.setPosition
App.mouse_down = love.mouse.isDown
App.mouse_x = love.mouse.getX
App.mouse_y = love.mouse.getY
-- Tests always run at the start.
App.run_tests()
-- example handler
if #Test_errors > 0 then
error('\n\n'..table.concat(Test_errors, '\n'))
end
--? print('==')
App.disable_tests()
App.initialize_globals()
App.initialize(love.arg.parseGameArguments(arg), arg)
@ -369,63 +426,18 @@ function App.run_tests()
end
end
table.sort(sorted_names)
local saved_app = App
App = App_for_tests
Test_errors = {}
for _,name in ipairs(sorted_names) do
App.initialize_for_test()
_G[name]()
local status, err = xpcall(_G[name], handle_error_in_test)
end
print()
-- clean up all test methods
for _,name in ipairs(sorted_names) do
_G[name] = nil
end
App = saved_app
end
-- call this once all tests are run
-- can't run any tests after this
function App.disable_tests()
-- have LÖVE delegate all handlers to App if they exist
for name in pairs(love.handlers) do
if App[name] then
love.handlers[name] = App[name]
end
end
-- test methods are disallowed outside tests
App.run_tests = nil
App.disable_tests = nil
App.screen.init = nil
App.filesystem = nil
App.time = nil
App.run_after_textinput = nil
App.run_after_keychord = nil
App.keypress = nil
App.keyrelease = nil
App.run_after_mouse_click = nil
App.run_after_mouse_press = nil
App.run_after_mouse_release = nil
App.fake_keys_pressed = nil
App.fake_key_press = nil
App.fake_key_release = nil
App.fake_mouse_state = nil
App.fake_mouse_press = nil
App.fake_mouse_release = nil
-- other methods dispatch to real hardware
App.screen.resize = love.window.setMode
App.screen.size = love.window.getMode
App.screen.move = love.window.setPosition
App.screen.position = love.window.getPosition
App.screen.print = love.graphics.print
App.newText = love.graphics.newText
App.screen.draw = love.graphics.draw
App.width = function(text) return text:getWidth() end
App.open_for_reading = function(filename) return io.open(filename, 'r') end
App.open_for_writing = function(filename) return io.open(filename, 'w') end
App.getTime = love.timer.getTime
App.getClipboardText = love.system.getClipboardText
App.setClipboardText = love.system.setClipboardText
App.modifier_down = love.keyboard.isDown
App.mouse_move = love.mouse.setPosition
App.mouse_down = love.mouse.isDown
App.mouse_x = love.mouse.getX
App.mouse_y = love.mouse.getY
function handle_error_in_test(err)
local full_error = debug.traceback('Error: '..err, --[[stack frame]]3):gsub('\n[^\n]+$', '')
table.insert(Test_errors, full_error..'\n')
end