1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-10-22 09:27:39 +00:00

Cherry pick several changes back from 1.19.3

The main purpose of this is to backport the improved parse/runtime
errors to older versions. I think they're sufficiently useful that we
should try to make it as widely available as possible.

We've been running them for a week now on SC3 and the released version
and not seen any issues, so I think it's probably stable enough.

This is a pretty lazy commit: I ended up copying the whole ROM over and
then picking up a few other related changes along the way.

 - Trim spaces from file paths (b8fce1eecc)

 - Correctly format 12AM/PM with
   %I (9f48395596)

 - Fix http.request and htpt.websocketAsync not handling a few failure
   edge-cases correctly (3b42f22a4f).

 - Move the internal modules into the main package path, hidden under
   cc.internal (34a31abd9c).

 - Gather code coverage in Java instead of
   Lua (28a55349a9).

 - Make error messages in edit more
   obvious (8cfbfe7ceb).

 - Make mcfly's test methods global. This means we don't need to pass
   stub everywhere (7335a892b5).

 - Improve runtime and parse errors. This comes from numerous commits,
   but chiefly a12b405acf, and
   5502412181.

 - Hide the internal redirect methods in
   multishell (33b6f38339).

Note this does /not/ include the shebang changes (sorry Emma!). I've
tried to avoid adding any user-controllable features, mostly because I
don't know how to handle the versioning otherwise :).
This commit is contained in:
Jonathan Coates
2023-02-14 09:45:02 +00:00
parent 68f6fa9343
commit 9b3cadf57c
95 changed files with 5447 additions and 942 deletions

View File

@@ -182,8 +182,12 @@ end
-- @treturn string The formatted value
local function format(value)
-- TODO: Look into something like mbs's pretty printer.
local ok, res = pcall(textutils.serialise, value)
if ok then return res else return tostring(value) end
if type(value) == "string" and value:find("\n") then
return "<<<\n" .. value .. "\n>>>"
else
local ok, res = pcall(textutils.serialise, value)
if ok then return res else return tostring(value) end
end
end
local expect_mt = {}
@@ -417,6 +421,9 @@ end
--- The stack of "describe"s.
local test_stack = { n = 0 }
--- The stack of setup functions.
local before_each_fns = { n = 0 }
--- Whether we're now running tests, and so cannot run any more.
local tests_locked = false
@@ -455,8 +462,14 @@ local function describe(name, body)
local n = test_stack.n + 1
test_stack[n], test_stack.n = name, n
local old_before, new_before = before_each_fns, { n = before_each_fns.n }
for i = 1, old_before.n do new_before[i] = old_before[i] end
before_each_fns = new_before
local ok, err = try(body)
before_each_fns = old_before
-- We count errors as a (failing) test.
if not ok then do_test { error = err, definition = format_loc(debug.getinfo(2, "Sl")) } end
@@ -477,7 +490,11 @@ local function it(name, body)
local n = test_stack.n + 1
test_stack[n], test_stack.n, tests_locked = name, n, true
do_test { action = body, definition = format_loc(debug.getinfo(2, "Sl")) }
do_test {
action = body,
before = before_each_fns,
definition = format_loc(debug.getinfo(2, "Sl")),
}
-- Pop the test from the stack
test_stack.n, tests_locked = n - 1, false
@@ -498,26 +515,17 @@ local function pending(name)
test_stack.n = n - 1
end
local native_co_create, native_loadfile = coroutine.create, loadfile
local function before_each(body)
check('it', 1, 'function', body)
if tests_locked then error("Cannot define before_each while running tests", 2) end
local n = before_each_fns.n + 1
before_each_fns[n], before_each_fns.n = body, n
end
local native_loadfile = loadfile
local line_counts = {}
if cct_test then
local string_sub, debug_getinfo = string.sub, debug.getinfo
local function debug_hook(_, line_nr)
local name = debug_getinfo(2, "S").source
if string_sub(name, 1, 1) ~= "@" then return end
name = string_sub(name, 2)
local file = line_counts[name]
if not file then file = {} line_counts[name] = file end
file[line_nr] = (file[line_nr] or 0) + 1
end
coroutine.create = function(...)
local co = native_co_create(...)
debug.sethook(co, debug_hook, "l")
return co
end
local expect = require "cc.expect".expect
_G.native_loadfile = native_loadfile
_G.loadfile = function(filename, mode, env)
@@ -537,8 +545,6 @@ if cct_test then
file.close()
return func, err
end
debug.sethook(debug_hook, "l")
end
local arg = ...
@@ -559,16 +565,11 @@ end
package.path = ("/%s/?.lua;/%s/?/init.lua;%s"):format(root_dir, root_dir, package.path)
do
-- Load in the tests from all our files
local env = setmetatable({}, { __index = _ENV })
local function set_env(tbl)
for k in pairs(env) do env[k] = nil end
for k, v in pairs(tbl) do env[k] = v end
end
-- When declaring tests, you shouldn't be able to use test methods
set_env { describe = describe, it = it, pending = pending }
-- Add our new functions to the current environment.
for k, v in pairs {
describe = describe, it = it, pending = pending, before_each = before_each,
expect = expect, fail = fail,
} do _ENV[k] = v end
local suffix = "_spec.lua"
local function run_in(sub_dir)
@@ -577,7 +578,7 @@ do
if fs.isDir(file) then
run_in(file)
elseif file:sub(-#suffix) == suffix then
local fun, err = loadfile(file, nil, env)
local fun, err = loadfile(file, nil, _ENV)
if not fun then
do_test { name = file:sub(#root_dir + 2), error = { message = err } }
else
@@ -590,8 +591,8 @@ do
run_in(root_dir)
-- When running tests, you shouldn't be able to declare new ones.
set_env { expect = expect, fail = fail, stub = stub }
-- Add stub later on, so its not available when running tests
_ENV.stub = stub
end
-- Error if we've found no tests
@@ -630,8 +631,13 @@ local function do_run(test)
-- Flush the event queue and ensure we're running with 0 timeout.
os.queueEvent("start_test") os.pullEvent("start_test")
local ok
ok, err = try(test.action)
local ok = true
for i = 1, test.before.n do
if not ok then break end
ok, err = try(test.before[i])
end
if ok then ok, err = try(test.action) end
status = ok and "pass" or (err.fail and "fail" or "error")
pop_state(state)
@@ -711,8 +717,6 @@ end
term.setTextColour(colours.white) io.write(info .. "\n")
-- Restore hook stubs
debug.sethook(nil, "l")
coroutine.create = native_co_create
_G.loadfile = native_loadfile
if cct_test then cct_test.finish(line_counts) end