summaryrefslogtreecommitdiff
path: root/Data/DefaultContent/Libraries/luafun/tests/runtest
blob: f6774f64966d49e5a0467e2ee0cb9a23a4b6ce8b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/env lua

package.path = "../?.lua;"..package.path
require "fun" ()
function dump(gen, init, state) each(print, gen, init, state) end

local unpack = rawget(table, "unpack") or unpack
local loadstring = rawget(_G, "loadstring") or load

function file_print(file, ...)
    local n, i = select("#",...)
    for i=1,n do
        local x = select(i, ...)
        if type(x) == "number" and math.floor(x) == math.ceil(x) then
            -- A special hack for Lua 5.3: remove .0 for integer
            x = string.match(select(i,...), '^-?%d+')
        end
        file:write(tostring(x))
        if i~=n then
            file:write(' ')
        end
    end
    file:write('\n')
end

local globals = {}
setmetatable(_G, {
    __newindex = function(t,k,v)
        local info = debug.getinfo(2, "S")
        if info.short_src:sub(1,7) ~= '[string' then
            local file = info.short_src
            local func = debug.getinfo(2, "n").name or ""
            local line = info.linedefined
            globals[file..':'..line..':'..k] = {file, line, func, k}
        end
        rawset(t, k, v)
    end
})

local function process(test_name)
    io.write("Testing ", test_name, "\n")
    local new_name = test_name..".new"
    local test_file = io.open(test_name, 'r')
    local content = test_file:read("*a");
    test_file:close()

    local new_file = io.open(new_name, 'w')

    local prev_print = print
    print = function(...) file_print(new_file, ...) end

    io.flush()
    local expr
    for expr in content:gmatch("(.-)%s*--%[%[test.-test%]%]") do
        new_file:write(expr)
        new_file:write("\n--[[test\n")
        local res, err = loadstring(expr)
        if res then
            res, err = pcall(res, expr)
        end
        if not res then
            new_file:write('error: ', err:match(".-:%d+:%s*(.*)"), "\n")
        end
        new_file:write("--test]]")
    end
    new_file:write("\n")
    new_file:close()

    print = prev_print

    local r = os.execute(string.format('diff -U4 "%s" "%s" 2>&1',
        test_name, new_name))
    if r then
        os.remove(new_name)
        return true
    else
        return false
    end
end

if #arg <= 0 then
    io.write("Usage: runtest *.lua", "\n")
    os.exit(1)
end

local failed, i = {}
for i=1,#arg,1 do
    local test_name = arg[i]
    if not process(test_name) then
        table.insert(failed, test_name)
    end
end

if #failed > 0 then
    io.write("\n")
    io.write("Failed tests:", "\n")
    for _k,test_name in ipairs(failed) do
        io.write("   ", test_name, "\n")
    end
    io.write("\n", "Please review *.new files and update tests", "\n")
end

if next(globals) then
    io.write("\n")
    io.write("Some global variables have been declared by mistake:", "\n")
    for k, pollution in pairs(globals) do
        local file, line, func, var = unpack(pollution)
        io.write(file..":"..line.." function "..func.."() = var '"..var.."'", "\n")
    end
    io.write("\n", "Please declare them with the local statement", "\n")
elseif #failed == 0 then
    io.write("All tests have passed!", "\n")
    os.exit(0)
end