diff options
Diffstat (limited to 'Data/Libraries/Penlight/tests/test-utils.lua')
-rw-r--r-- | Data/Libraries/Penlight/tests/test-utils.lua | 320 |
1 files changed, 320 insertions, 0 deletions
diff --git a/Data/Libraries/Penlight/tests/test-utils.lua b/Data/Libraries/Penlight/tests/test-utils.lua new file mode 100644 index 0000000..cff400a --- /dev/null +++ b/Data/Libraries/Penlight/tests/test-utils.lua @@ -0,0 +1,320 @@ +local utils = require 'pl.utils' +local path = require 'pl.path' +local test = require 'pl.test' +local asserteq, T = test.asserteq, test.tuple + + +local function quote(s) + if utils.is_windows then + return '"'..s..'"' + else + return "'"..s.."'" + end +end + +-- construct command to run external lua, we need to to be able to run some +-- tests on the same lua engine, but also need to pass on the LuaCov flag +-- if it was used, to make sure we report the proper coverage. +local cmd = "-e " +do + local i = 0 + while arg[i-1] do + local a = arg[i-1] + if a:find("package%.path") and a:sub(1,1) ~= "'" then + a = quote(a) + end + cmd = a .. " " .. cmd + i = i - 1 + end +end + + +--- quitting +do + local luacode = quote("require([[pl.utils]]).quit([[hello world]])") + local success, code, stdout, stderr = utils.executeex(cmd..luacode) + asserteq(success, false) + if utils.is_windows then + asserteq(code, -1) + else + asserteq(code, 255) + end + asserteq(stdout, "") + asserteq(stderr, "hello world\n") + + local luacode = quote("require([[pl.utils]]).quit(2, [[hello world]])") + local success, code, stdout, stderr = utils.executeex(cmd..luacode) + asserteq(success, false) + asserteq(code, 2) + asserteq(stdout, "") + asserteq(stderr, "hello world\n") + + local luacode = quote("require([[pl.utils]]).quit(2, [[hello %s]], 42)") + local success, code, stdout, stderr = utils.executeex(cmd..luacode) + asserteq(success, false) + asserteq(code, 2) + asserteq(stdout, "") + asserteq(stderr, "hello 42\n") + + local luacode = quote("require([[pl.utils]]).quit(2)") + local success, code, stdout, stderr = utils.executeex(cmd..luacode) + asserteq(success, false) + asserteq(code, 2) + asserteq(stdout, "") + asserteq(stderr, "") +end + +----- importing module tables wholesale --- +utils.import(math) +asserteq(type(sin),"function") +asserteq(type(abs),"function") + +--- useful patterns +local P = utils.patterns +asserteq(("+0.1e10"):match(P.FLOAT) ~= nil, true) +asserteq(("-23430"):match(P.INTEGER) ~= nil, true) +asserteq(("my_little_pony99"):match(P.IDEN) ~= nil, true) + +--- escaping magic chars +local escape = utils.escape +asserteq(escape '[a]','%[a%]') +asserteq(escape '$(bonzo)','%$%(bonzo%)') + +--- choose +asserteq(utils.choose(true, 1, 2), 1) +asserteq(utils.choose(false, 1, 2), 2) + +--- splitting strings --- +local split = utils.split +asserteq(split("hello dolly"),{"hello","dolly"}) +asserteq(split("hello,dolly",","),{"hello","dolly"}) +asserteq(split("hello,dolly,",","),{"hello","dolly"}) + +local first,second = utils.splitv("hello:dolly",":") +asserteq(T(first,second),T("hello","dolly")) +local first,second = utils.splitv("hello:dolly:parton",":", false, 2) +asserteq(T(first,second),T("hello","dolly:parton")) +local first,second,third = utils.splitv("hello=dolly:parton","[:=]") +asserteq(T(first,second,third),T("hello","dolly","parton")) +local first,second = utils.splitv("hello=dolly:parton","[:=]", false, 2) +asserteq(T(first,second),T("hello","dolly:parton")) + +----- table of values to table of strings +asserteq(utils.array_tostring{1,2,3},{"1","2","3"}) +-- writing into existing table +local tmp = {} +utils.array_tostring({1,2,3},tmp) +asserteq(tmp,{"1","2","3"}) + +--- memoizing a function +local kount = 0 +local f = utils.memoize(function(x) + kount = kount + 1 + return x*x +end) +asserteq(f(2),4) +asserteq(f(10),100) +asserteq(f(2),4) +-- actual function only called twice +asserteq(kount,2) + +-- string lambdas +local L = utils.string_lambda +local g = L"|x| x:sub(1,1)" +asserteq(g("hello"),"h") + +local f = L"|x,y| x - y" +asserteq(f(10,2),8) + +-- alternative form for _one_ argument +asserteq(L("2 * _")(4), 8) + +local List = require 'pl.List' +local ls = List{10,20,30} + +-- string lambdas can be used throughout Penlight +asserteq(ls:map"_+1", {11,21,31}) + +-- because they use this common function +local function test_fn_arg(f) + f = utils.function_arg(1,f) + asserteq(f(10),11) +end + +test_fn_arg (function (x) return x + 1 end) +test_fn_arg '_ + 1' +test.assertraise(function() test_fn_arg {} end, 'not a callable object') +test.assertraise(function() test_fn_arg (0) end, 'must be callable') + +-- partial application + +local f1 = utils.bind1(f,10) +asserteq(f1(2), 8) + +local f2 = utils.bind2(f,2) +asserteq(f2(10), 8) + +--- extended type checking + +local is_type = utils.is_type +-- anything without a metatable works as regular type() function +asserteq(is_type("one","string"),true) +asserteq(is_type({},"table"),true) + +-- but otherwise the type of an object is considered to be its metatable +asserteq(is_type(ls,List),true) + +-- compatibility functions +local chunk = utils.load 'return 42' +asserteq(chunk(),42) + +chunk = utils.load 'a = 42' +chunk() +asserteq(a,42) + +local t = {} +chunk = utils.load ('b = 42','<str>','t',t) +chunk() +asserteq(t.b,42) + +chunk,err = utils.load ('a = ?','<str>') +assert(err,[[[string "<str>"]:1: unexpected symbol near '?']]) + +asserteq(utils.quote_arg("foo"), [[foo]]) +if path.is_windows then + asserteq(utils.quote_arg(""), '^"^"') + asserteq(utils.quote_arg('"'), '^"') + asserteq(utils.quote_arg([[ \]]), [[^" \\^"]]) + asserteq(utils.quote_arg([[foo\\ bar\\" baz\]]), [[^"foo\\ bar\\\\\^" baz\\^"]]) + asserteq(utils.quote_arg("%path% ^^!()"), [[^"^%path^% ^^^^^!()^"]]) +else + asserteq(utils.quote_arg(""), "''") + asserteq(utils.quote_arg("'"), [[''\''']]) + asserteq(utils.quote_arg([['a\'b]]), [[''\''a\'\''b']]) +end + +-- packing and unpacking arguments in a nil-safe way +local t = utils.pack(nil, nil, "hello", nil) +asserteq(t.n, 4) -- the last nil does count as an argument + +local arg1, arg2, arg3, arg4 = utils.unpack(t) +assert(arg1 == nil) +assert(arg2 == nil) +asserteq("hello", arg3) +assert(arg4 == nil) + + +-- Assert arguments assert_arg +local ok, err = pcall(function() + utils.assert_arg(4,'!@#$%^&*','string',require("pl.path").isdir,'not a directory') +end) +asserteq(ok, false) +asserteq(err:match("(argument .+)$"), "argument 4: '!@#$%^&*' not a directory") + +local ok, err = pcall(function() + utils.assert_arg(1, "hello", "table") +end) +asserteq(ok, false) +asserteq(err:match("(argument .+)$"), "argument 1 expected a 'table', got a 'string'") + +local ok, err = pcall(function() + return utils.assert_arg(1, "hello", "string") +end) +asserteq(ok, true) +asserteq(err, "hello") + +-- assert_string +local success, err = pcall(utils.assert_string, 2, 5) +asserteq(success, false) +asserteq(err:match("(argument .+)$"), "argument 2 expected a 'string', got a 'number'") + +local x = utils.assert_string(2, "5") +asserteq(x, "5") + + +do + -- printf -- without template + local luacode = quote("require([[pl.utils]]).printf([[hello world]])") + local success, code, stdout, stderr = utils.executeex(cmd..luacode) + asserteq(success, true) + asserteq(code, 0) + asserteq(stdout, "hello world") + asserteq(stderr, "") + + -- printf -- with template + local luacode = quote("require([[pl.utils]]).printf([[hello %s]], [[world]])") + local success, code, stdout, stderr = utils.executeex(cmd..luacode) + asserteq(success, true) + asserteq(code, 0) + asserteq(stdout, "hello world") + asserteq(stderr, "") + + -- printf -- with bad template + local luacode = quote("require([[pl.utils]]).printf(42)") + local success, code, stdout, stderr = utils.executeex(cmd..luacode) + asserteq(success, false) + asserteq(code, 1) + asserteq(stdout, "") + assert(stderr:find("argument 1 expected a 'string', got a 'number'")) +end + +do + -- on_error, raise -- default + utils.on_error("default") + local ok, err = utils.raise("some error") + asserteq(ok, nil) + asserteq(err, "some error") + local ok, err = pcall(utils.on_error, "bad one") + asserteq(ok, false) + asserteq(err, "Bad argument expected string; 'default', 'quit', or 'error'. Got 'bad one'") + + -- on_error, raise -- error + utils.on_error("error") + local ok, err = pcall(utils.raise, "some error") + asserteq(ok, false) + asserteq(err, "some error") + local ok, err = pcall(utils.on_error, "bad one") + asserteq(ok, false) + assert(err:find("Bad argument expected string; 'default', 'quit', or 'error'. Got 'bad one'")) + + -- on_error, raise -- quit + utils.on_error("quit") + local luacode = quote("local u=require([[pl.utils]]) u.on_error([[quit]]) u.raise([[some error]])") + local success, code, stdout, stderr = utils.executeex(cmd..luacode) + asserteq(success, false) + if utils.is_windows then + asserteq(code, -1) + else + asserteq(code, 255) + end + asserteq(stdout, "") + asserteq(stderr, "some error\n") + + local luacode = quote("local u=require([[pl.utils]]) u.on_error([[quit]]) u.on_error([[bad one]])") + local success, code, stdout, stderr = utils.executeex(cmd..luacode) + asserteq(success, false) + if utils.is_windows then + asserteq(code, -1) + else + asserteq(code, 255) + end + asserteq(stdout, "") + asserteq(stderr, "Bad argument expected string; 'default', 'quit', or 'error'. Got 'bad one'\n") + + utils.on_error("default") -- cleanup by restoring behaviour after on_error + raise tests +end + +do + -- readlines + local f = utils.readlines("tests/test-utils.lua") + asserteq(type(f), "table") + local v = "some extraordinary string this is only in this file for test purposes so we can go and find it" + local found = false + for i, line in ipairs(f) do + if line:find(v) then + found = true + break + end + end + asserteq(found, true) +end |