--- @section Autotest module --- The module contains functions to write automated gameplay tests. Do not use it in production code! --- --- To use this module, you need to use require to bring it to scope: --- ```lua --- local autotest = require "autotest" --- ``` local autotest = {} local timeout_event = nil --- Logs the test success and quits the game. function autotest.pass() nl_info("Test passed") if timeout_event then nl_remove_timed_event(timeout_event) timeout_event = nil end if nl_game_testing_mode() then nl_game_quit() end end --- Logs the test failure with the optional message and quits the game. function autotest.fail(message) if message then assert(false, "Test failed: " .. message) else assert(false, "Test failed") end end --- Sets the timeout in seconds after which the test fails with a reason "Timeout". function autotest.set_timeout(delay) timeout_event = nl_add_timed_event(delay, function() autotest.fail("Timeout") end) end --- If the condition is false, then logs the test failure with the provided message and quits the game. function autotest.assert(condition, message) assert(condition, "Test failed: Assertion error: " .. message) end --- Compares two values. If not equal, then logs the test failure with the provided message and quits the game. function autotest.assert_equals(value1, value2, message) autotest.assert(value1 == value2, string.format("%s != %s (%s)", tostring(value1), tostring(value2), message)) end --- Sets PC input mode enabled. This mode is required to receive input from real or simulated devices. function autotest.enable_pc_input_mode() nl_input_pc_mode(true) end --- Presses the target input. The named_input can be either a key/button ("KEY_W", "KEY_SPACEBAR", "MOUSE_LEFT") or an input action ("SHOOT_MOUSE", "JUMP_KEYBOARD"). --- Optional float axis argument is used for analog inputs (e.g. "MOUSE_DELTA_X") to define direction (sign) and amount (abs value). --- For keys, buttons and input actions the input must be released before it can be used again. For analog inputs it can be used repeatedly without releasing. function autotest.input_press(named_input, axis) nl_input_simulate_press(named_input, axis) end --- Releases the target input. The named_input can be either a key/button ("KEY_W", "KEY_SPACEBAR", "MOUSE_LEFT") or an input action ("SHOOT_MOUSE", "JUMP_KEYBOARD"). --- Does nothing for analog inputs (e.g. "MOUSE_DELTA_X"). function autotest.input_release(named_input) nl_input_simulate_release(named_input) end --- Presses the target input and then releases it after the provided delay. The named_input can be either a key/button ("KEY_W", "KEY_SPACEBAR", "MOUSE_LEFT") or an input action ("SHOOT_MOUSE", "JUMP_KEYBOARD"). --- The delay is either in seconds or in frames. Use time_units to specify the delay type: "seconds" or "frames". If time_units is omitted, then "seconds" is used. --- The "frames" delay is not precise and can differ by one frame from the given argument value. function autotest.input_press_and_release(named_input, delay, time_units) time_units = time_units or "seconds" autotest.input_press(named_input) if time_units == "seconds" then nl_add_timed_event(delay, function() autotest.input_release(named_input) end) elseif time_units == "frames" then nl_add_timed_event((delay + 1) * nl_delta_time(), function() autotest.input_release(named_input) end) end end return autotest