2011-05-20 16:14:50 +00:00
|
|
|
require "lfs"
|
2011-05-22 19:19:13 +00:00
|
|
|
require "alt_getopt"
|
|
|
|
|
2011-05-29 01:35:18 +00:00
|
|
|
local gettime = nil
|
|
|
|
|
|
|
|
pcall(function()
|
|
|
|
require "socket"
|
|
|
|
gettime = socket.gettime
|
|
|
|
end)
|
|
|
|
|
2011-05-22 19:19:13 +00:00
|
|
|
local opts, ind = alt_getopt.get_opts(arg, "d:", { })
|
|
|
|
|
|
|
|
local argv = {}
|
|
|
|
for i = ind, #arg do table.insert(argv, arg[i]) end
|
2011-05-20 16:14:50 +00:00
|
|
|
|
|
|
|
local action = table.remove(argv, 1) or "run"
|
|
|
|
|
2011-05-22 19:19:13 +00:00
|
|
|
local diff_tool = opts.d or "diff"
|
2011-05-20 16:14:50 +00:00
|
|
|
|
|
|
|
local opts = {
|
|
|
|
in_dir = "tests/inputs",
|
|
|
|
out_dir = "tests/outputs",
|
|
|
|
input_pattern = "(.*)%.moon$",
|
|
|
|
output_ext = ".lua"
|
|
|
|
}
|
|
|
|
|
|
|
|
local function diff(a_fname, b_fname)
|
|
|
|
return io.popen(diff_tool.." ".. a_fname.." "..b_fname, "r"):read("*a")
|
|
|
|
end
|
|
|
|
|
2011-05-21 22:26:46 +00:00
|
|
|
local function input_name(name) return opts.in_dir.."/".. name end
|
2011-05-20 16:14:50 +00:00
|
|
|
local function output_name(name)
|
|
|
|
return opts.out_dir.."/"..name:match(opts.input_pattern)..opts.output_ext
|
|
|
|
end
|
|
|
|
|
2011-05-29 01:35:18 +00:00
|
|
|
local function run_file(name, benchmark)
|
2011-05-20 16:14:50 +00:00
|
|
|
name = input_name(name)
|
|
|
|
file_str = io.open(name):read("*a")
|
|
|
|
|
|
|
|
local parse = require "moonscript.parse"
|
|
|
|
local compile = require "moonscript.compile"
|
|
|
|
|
2011-05-29 01:35:18 +00:00
|
|
|
|
|
|
|
local start_parse
|
|
|
|
if benchmark then start_parse = gettime() end
|
|
|
|
|
2011-05-21 22:26:46 +00:00
|
|
|
local tree, err = parse.string(file_str)
|
2011-05-29 01:35:18 +00:00
|
|
|
|
|
|
|
local parse_time = 0
|
|
|
|
if benchmark then parse_time = gettime() - start_parse end
|
|
|
|
|
2011-05-21 22:26:46 +00:00
|
|
|
if not tree then
|
2011-05-30 05:38:47 +00:00
|
|
|
error("Parse error in "..name.."\n"..err)
|
2011-05-21 22:26:46 +00:00
|
|
|
end
|
2011-05-29 01:35:18 +00:00
|
|
|
|
|
|
|
local start_compile
|
|
|
|
if benchmark then start_compile = gettime() end
|
|
|
|
|
2011-05-30 05:38:47 +00:00
|
|
|
local success, code = pcall(compile.tree, tree)
|
|
|
|
if not success then
|
|
|
|
error("Compile error in"..name..":\n"..code)
|
|
|
|
end
|
2011-05-29 01:35:18 +00:00
|
|
|
|
|
|
|
if benchmark then
|
|
|
|
local compile_time = gettime() - start_compile
|
|
|
|
return code, parse_time, compile_time
|
|
|
|
end
|
|
|
|
|
|
|
|
return code
|
2011-05-20 16:14:50 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
local function inputs(pattern)
|
|
|
|
return coroutine.wrap(function()
|
|
|
|
for file in lfs.dir(opts.in_dir) do
|
|
|
|
local body = file:match(opts.input_pattern)
|
|
|
|
if body then
|
|
|
|
if not pattern or body:match(pattern) then
|
|
|
|
coroutine.yield(file)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
end
|
|
|
|
|
|
|
|
local actions = {
|
|
|
|
build = function(pattern)
|
|
|
|
for file in inputs(pattern) do
|
|
|
|
local out_fname = output_name(file)
|
|
|
|
print("Building: ", file, out_fname)
|
2011-05-22 19:19:13 +00:00
|
|
|
local result = run_file(file)
|
|
|
|
if result then
|
2011-05-23 02:28:25 +00:00
|
|
|
io.open(out_fname, "w"):write(result)
|
2011-05-22 19:19:13 +00:00
|
|
|
end
|
2011-05-20 16:14:50 +00:00
|
|
|
end
|
|
|
|
end,
|
|
|
|
run = function(pattern)
|
2011-05-21 22:26:46 +00:00
|
|
|
local failed = false
|
2011-05-20 16:14:50 +00:00
|
|
|
local tests_run, result = 0
|
|
|
|
for file in inputs(pattern) do
|
|
|
|
tests_run = tests_run + 1
|
|
|
|
local correct_fname = output_name(file)
|
2011-05-29 01:35:18 +00:00
|
|
|
result, parse_time, compile_time = run_file(file, gettime)
|
2011-05-20 16:14:50 +00:00
|
|
|
local handle = io.open(correct_fname)
|
|
|
|
|
|
|
|
if not handle then
|
|
|
|
print("Test not built yet:", correct_fname)
|
|
|
|
else
|
|
|
|
local correct = handle:read("*a")
|
|
|
|
if result ~= correct then
|
|
|
|
print("Test", file, "failed")
|
|
|
|
local tmp_name = os.tmpname()
|
|
|
|
local tmp = io.open(tmp_name, "w")
|
|
|
|
tmp:write(result)
|
|
|
|
tmp:close()
|
|
|
|
print(diff(correct_fname, tmp_name))
|
|
|
|
os.remove(tmp_name)
|
|
|
|
-- break
|
|
|
|
else
|
2011-05-29 01:35:18 +00:00
|
|
|
if parse_time then
|
|
|
|
parse_time = ("%.3fms"):format(parse_time*1000)
|
|
|
|
compile_time = ("%.3fms"):format(compile_time*1000)
|
|
|
|
print("Test", file, "passed", "",
|
|
|
|
("p: %s, c: %s"):format(parse_time, compile_time))
|
|
|
|
else
|
|
|
|
print("Test", file, "passed")
|
|
|
|
end
|
2011-05-20 16:14:50 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if tests_run == 0 then
|
|
|
|
if not pattern then
|
|
|
|
print("No tests found")
|
|
|
|
else
|
|
|
|
print("No tests matching pattern:", pattern)
|
|
|
|
end
|
|
|
|
elseif tests_run == 1 then
|
2011-05-21 22:26:46 +00:00
|
|
|
-- print(result)
|
2011-05-20 16:14:50 +00:00
|
|
|
end
|
|
|
|
end,
|
|
|
|
list = function(pattern)
|
|
|
|
local count = 0
|
|
|
|
for file in inputs(pattern) do
|
|
|
|
count = count + 1
|
|
|
|
print(file)
|
|
|
|
end
|
|
|
|
if count > 0 then print("") end
|
|
|
|
print("Count:", count)
|
|
|
|
end
|
|
|
|
}
|
|
|
|
|
|
|
|
local fn = actions[action]
|
|
|
|
if fn then
|
|
|
|
fn(unpack(argv))
|
|
|
|
else
|
|
|
|
print("Unknown action:", action)
|
|
|
|
end
|
|
|
|
|
|
|
|
|