satelito

Static [web] site (or page) generator (ssg) made with Lua script.
git clone git://soucy.cc/satelito.git
Log | Files | Refs | README

tester.lua (3741B)


      1 
      2 
      3 local tester = { 
      4   test = {}, 
      5   linecache = {},
      6   globals = {},
      7   passcount = 0,
      8   failcount = 0
      9 }
     10 
     11 
     12 local function isequal(a, b)
     13   if type(a) ~= type(b) then return nil end
     14   local t = {}
     15   function t.table(a, b)
     16     for k, v in pairs(a) do if not isequal(b[k], v) then return nil end end
     17     for k, v in pairs(b) do if not isequal(a[k], v) then return nil end end
     18     return true
     19   end
     20   function t.number(a, b) return math.abs(a - b) < 10e-9 end
     21   return t[type(a)] and t[type(a)](a, b) or (a == b)
     22 end
     23 
     24 
     25 local function stringify(x)
     26   if type(x) == "number" then return string.format("%.2f", x) end
     27   return string.format("%q", tostring(x))
     28 end
     29 
     30 
     31 local function getline(file, line)
     32   if not tester.linecache[file] then
     33     local t = {}
     34     for line in io.lines(file) do
     35       t[#t + 1] = line
     36     end
     37     tester.linecache[file] = t
     38   end
     39   return tester.linecache[file][line]  
     40 end
     41 
     42 
     43 local function truncate(str, max)
     44   max = max or 72
     45   if #str > max then
     46     return str:sub(1, max - 3) .. "..."
     47   end
     48   return str
     49 end
     50 
     51 
     52 local function has(t, value)
     53   for k, v in pairs(t) do
     54     if v == value then return true end
     55   end
     56   return false
     57 end
     58 
     59 
     60 local function makelogstr(passed, file, line)
     61   local t = {}
     62   t[#t + 1] = passed and "[\27[32mPASS\27[0m]" or "[\27[31mFAIL\27[0m]"
     63   t[#t + 1] = file .. ":" .. line .. ":"
     64   t[#t + 1] = getline(file, line) :gsub(" %s+", " ") :gsub("^ *", "")
     65   return truncate(table.concat(t, " "))
     66 end
     67 
     68 
     69 local function dopass(file, line)
     70   print(makelogstr(true, file, line))
     71   tester.passcount = tester.passcount + 1
     72 end
     73 
     74 
     75 local function dofail(file, line)
     76   print(makelogstr(false, file, line))
     77   tester.failcount = tester.failcount + 1
     78 end
     79 
     80 
     81 local function printfailmsg(str)
     82     print(string.rep(" ", 7) .. str)
     83 end
     84 
     85 
     86 
     87 
     88 function tester.init()
     89   for k, v in pairs(_G) do
     90     tester.globals[k] = v
     91   end
     92   return tester
     93 end
     94 
     95 
     96 function tester.test.global(expectedglobals)
     97   expectedglobals = expectedglobals or {}
     98   local info = debug.getinfo(2)
     99   local unexpected = {}
    100   for k in pairs(_G) do
    101     if not tester.globals[k] and not has(expectedglobals, k) then
    102       table.insert(unexpected, "Unexpected global '" .. k .. "'")
    103     end
    104   end
    105   if #unexpected == 0 then
    106     dopass(info.short_src, info.currentline)
    107   else
    108     dofail(info.short_src, info.currentline)
    109     for _, v in pairs(unexpected) do printfailmsg(v) end
    110   end
    111 end
    112 
    113 
    114 function tester.test.equal(result, expected)
    115   local passed = isequal(result, expected)
    116   local info = debug.getinfo(2)
    117   if passed then
    118     dopass(info.short_src, info.currentline)
    119   else
    120     dofail(info.short_src, info.currentline)
    121     if type(expected) == "table" and type(result) == "table" then
    122       printfailmsg("Tables do not match")
    123     else
    124       printfailmsg(string.format("Expected %s got %s",
    125                                  stringify(expected), stringify(result) ))
    126     end
    127   end
    128 end
    129 
    130 
    131 function tester.test.error(fn, ...)
    132   local passed = not pcall(fn, ...)
    133   local info = debug.getinfo(2)
    134   if passed then
    135     dopass(info.short_src, info.currentline)
    136   else
    137     dofail(info.short_src, info.currentline)
    138     printfailmsg("Expected an error to be raised")
    139   end
    140 end
    141 
    142 
    143 function tester.dotests(t)
    144   local keys = {}
    145   for k in pairs(t) do table.insert(keys, k) end
    146   table.sort(keys)
    147   for _, k in pairs(keys) do
    148     print("\27[33m-- " .. k .. "\27[0m")
    149     t[k]()
    150   end
    151 end
    152 
    153 
    154 function tester.printresults()
    155   local str = table.concat{
    156     "-- ", 
    157     string.format("Results:   %d Total", tester.passcount + tester.failcount),
    158     "   ", string.format("%d Passed", tester.passcount),
    159     "   ", string.format("%d Failed", tester.failcount), 
    160     " --", }
    161   local b = string.rep("-", #str)
    162   print(table.concat{b, "\n", str, "\n", b})
    163 end
    164 
    165 
    166 return tester.init()