1--- Test runner for async tests. 2-- 3-- @script async.run_test 4-- @copyright 2017 Aidan Holm <aidanholm@gmail.com> 5 6-- Adjust paths to work when running with DEVELOPMENT_PATHS=0 7dofile("tests/async/wrangle_paths.lua") 8require_web_module("tests/async/wrangle_paths") 9 10local shared_lib = {} 11local priv = require "tests.priv" 12local test = require("tests.lib") 13test.init(shared_lib) 14 15--- Launched as the init script of a luakit instance 16-- 17-- Loads test_file and runs all tests in it in order 18local function do_test_file(test_file) 19 local wait_timer = timer() 20 21 -- Load test table, or abort 22 print("__load__ ") 23 local T, err = priv.load_test_file(test_file) 24 if not T then 25 print("__fail__ " .. test_file) 26 print(err) 27 luakit.quit(0) 28 end 29 30 -- Convert functions to coroutines 31 for test_name, func in pairs(T) do 32 if type(func) == "function" then 33 T[test_name] = coroutine.create(func) 34 end 35 end 36 37 local current_test 38 local waiting_signal 39 40 --- Runs a test untit it passes, fails, or waits for a signal 41 -- Additional arguments: parameters to signal handler 42 -- @treturn string Status of the test; one of "pass", "wait", "fail" 43 local function begin_or_continue_test(func, ...) 44 assert(type(func) == "thread") 45 46 shared_lib.current_coroutine = func 47 48 -- Run test until it finishes, pauses, or fails 49 local ok, ret = coroutine.resume(func, ...) 50 local state = coroutine.status(func) 51 52 if not ok then 53 print("__fail__ " .. current_test) 54 print(tostring(ret)) 55 print(debug.traceback(func)) 56 return "fail" 57 elseif state == "suspended" then 58 print("__wait__ " .. current_test) 59 60 -- Start timer 61 wait_timer.interval = ret.timeout 62 wait_timer:start() 63 64 -- wait_for_signal 65 if #ret == 2 then 66 -- Add signal handlers to resume running test 67 local obj, sig = ret[1], ret[2] 68 local function wrapper(...) 69 obj:remove_signal(sig, wrapper) 70 shared_lib.resume_suspended_test(...) 71 end 72 obj:add_signal(sig, wrapper) 73 waiting_signal = sig 74 end 75 76 -- Return to luakit 77 return "wait" 78 else 79 print("__pass__ " .. current_test) 80 return "pass" 81 end 82 end 83 84 --- Finds the next test to run and starts it, or quits 85 local function do_next_test() 86 repeat 87 local test_name, func = next(T, current_test) 88 if not test_name then 89 -- Quit if all tests have been run 90 luakit.quit() 91 return 92 end 93 current_test = test_name 94 print("__run__ " .. current_test) 95 local test_status = begin_or_continue_test(func) 96 until test_status == "wait" 97 end 98 99 --- Resumes a waiting test when a signal occurs 100 shared_lib.resume_suspended_test = function (...) 101 local func = shared_lib.current_coroutine 102 assert(type(func) == "thread") 103 -- Stop the timeout timer 104 wait_timer:stop() 105 waiting_signal = nil 106 -- Continue the test 107 print("__cont__ " .. current_test) 108 local test_status = begin_or_continue_test(func, ...) 109 -- If the test finished, do the next one 110 if test_status ~= "wait" then 111 luakit.idle_add(do_next_test) 112 end 113 end 114 115 wait_timer:add_signal("timeout", function () 116 wait_timer:stop() 117 print("__fail__ " .. current_test) 118 if waiting_signal then 119 print("Timed out while waiting for signal '" .. waiting_signal .. "'") 120 else 121 print("Timed out while waiting") 122 end 123 print(" interval was " .. tostring(wait_timer.interval) .. "msec") 124 print(" " .. shared_lib.traceback) 125 do_next_test() 126 end) 127 128 do_next_test() 129 130 -- If the test hasn't opened any windows, open one to keep luakit happy 131 if #luakit.windows == 0 then 132 local win = widget{type="window"} 133 win:show() 134 end 135end 136 137io.stdout:setvbuf("line") 138 139local test_file = uris[1] 140assert(type(test_file) == "string") 141 142-- Setup luakit-test:// URI scheme 143luakit.register_scheme("luakit-test") 144widget.add_signal("create", function (w) 145 if w.type == "webview" then 146 w:add_signal("scheme-request::luakit-test", function (_, uri, request) 147 local path = uri:gsub("^luakit%-test://", "tests/html/") 148 local f = assert(io.open(path, "rb")) 149 local contents = f:read("*a") or "" 150 f:close() 151 152 local mime = "text/plain" 153 if path:match("%.html$") then mime = "text/html" end 154 if path:match("%.png$") then mime = "image/png" end 155 if path:match("%.jpg$") then mime = "image/jpeg" end 156 157 request:finish(contents, mime) 158 end) 159 end 160end) 161 162require('unique_instance') 163local lousy = require('lousy') 164-- Some lib files assume that a theme has been loaded 165lousy.theme.init(lousy.util.find_config("theme.lua")) 166 167do_test_file(test_file) 168 169-- vim: et:sw=4:ts=8:sts=4:tw=80 170