1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-12-12 03:00:30 +00:00

Add a test utility for capturing program output

- Make mcfly's stubbing system a little more fault-tolerant.
 - Add a small utility function which redirects print, printError and
   write to capture their output, rather than printing to the terminal.
   This can then be matched against in order to determine a program's
   output.
   It's a little flakey - you can't use it multiple times in an it
   block, etc... but it's a nice feature.
 - Add a small couple of tests to delete as a proof-of-concept.
This commit is contained in:
SquidDev 2019-06-03 20:33:09 +01:00
parent 6f1b740c8f
commit ffa4cc241b
3 changed files with 67 additions and 4 deletions

View File

@ -34,10 +34,12 @@ local active_stubs = {}
-- @tparam string var The variable to stub -- @tparam string var The variable to stub
-- @param value The value to stub it with -- @param value The value to stub it with
local function stub(tbl, var, value) local function stub(tbl, var, value)
table.insert(active_stubs, { tbl = tbl, var = var, value = tbl[var] }) check('stub', 1, 'table', tbl)
_G[var] = value check('stub', 2, 'string', var)
end
table.insert(active_stubs, { tbl = tbl, var = var, value = tbl[var] })
rawset(tbl, var, value)
end
--- Capture the current global state of the computer --- Capture the current global state of the computer
local function push_state() local function push_state()
@ -55,7 +57,7 @@ end
local function pop_state(state) local function pop_state(state)
for i = #active_stubs, 1, -1 do for i = #active_stubs, 1, -1 do
local stub = active_stubs[i] local stub = active_stubs[i]
stub.tbl[stub.var] = stub.value rawset(stub.tbl, stub.var, stub.value)
end end
active_stubs = state.stubs active_stubs = state.stubs
@ -353,6 +355,9 @@ if not fs.isDir(root_dir) then
error() error()
end end
-- Ensure the test folder is also on the package path
package.path = ("/%s/?.lua;/%s/?/init.lua;%s"):format(root_dir, root_dir, package.path)
do do
-- Load in the tests from all our files -- Load in the tests from all our files
local env = setmetatable({}, { __index = _ENV }) local env = setmetatable({}, { __index = _ENV })

View File

@ -1,3 +1,5 @@
local capture = require "test_helpers".capture_program
describe("The rm program", function() describe("The rm program", function()
local function touch(file) local function touch(file)
io.open(file, "w"):close() io.open(file, "w"):close()
@ -32,4 +34,14 @@ describe("The rm program", function()
expect(fs.exists("/test-files/a.txt")):eq(false) expect(fs.exists("/test-files/a.txt")):eq(false)
expect(fs.exists("/test-files/b.txt")):eq(false) expect(fs.exists("/test-files/b.txt")):eq(false)
end) end)
it("displays the usage with no arguments", function()
expect(capture(stub, "rm"))
:matches { ok = true, output = "Usage: rm <paths>\n", error = "" }
end)
it("errors when a glob fails to match", function()
expect(capture(stub, "rm", "never-existed"))
:matches { ok = true, output = "", error = "never-existed: No matching files\n" }
end)
end) end)

View File

@ -0,0 +1,46 @@
--- Run a program and capture its output
--
-- @tparam function(tbl:table, var:string, value:string) stub The active stub function.
-- @tparam string program The program name.
-- @tparam string ... Arguments to this program.
-- @treturn { ok = boolean, output = string, error = string, combined = string }
-- Whether this program terminated successfully, and the various output streams.
local function capture_program(stub, program, ...)
local output, error, combined = {}, {}, {}
local function out(stream, msg)
table.insert(stream, msg)
table.insert(combined, msg)
end
stub(_G, "print", function(...)
for i = 1, select('#', ...) do
if i > 1 then out(output, " ") end
out(output, tostring(select(i, ...)))
end
out(output, "\n")
end)
stub(_G, "printError", function(...)
for i = 1, select('#', ...) do
if i > 1 then out(error, " ") end
out(error, tostring(select(i, ...)))
end
out(error, "\n")
end)
stub(_G, "write", function(msg) out(output, tostring(msg)) end)
local ok = shell.run(program, ...)
return {
output = table.concat(output),
error = table.concat(error),
combined = table.concat(combined),
ok = ok
}
end
return {
capture_program = capture_program,
}