wireshark/test/lua/luatest.lua
Hadriel Kaplan ea46cdc474 Add GLib's regex library into Lua
While Lua's built-in pattern support is ok for simple things, many people end
up wanting a real regex engine. Since Wireshark already includes the GLib
Regex library (a wrapper for PCRE), it makes sense to expose that library to
Lua scripts. This has been done using Lrexlib, one of the most popular regex
bindings for Lua. Lrexlib didn't support binding GLib's Regex in particular -
it does for PCRE but GLib is a different API - so I've done that. A fairly
thorough testsuite came along with that, which has been incorporated into the
wireshark wslua testuites as well in this commit.

Change-Id: I05811d1edf7af8d7c9f4f081de6850f31c0717c7
Reviewed-on: https://code.wireshark.org/review/332
Reviewed-by: Anders Broman <a.broman58@gmail.com>
2014-03-10 07:11:12 +00:00

175 lines
4.4 KiB
Lua
Executable file

-- See Copyright Notice in the file LICENSE
-- arrays: deep comparison
local function eq (t1, t2, lut)
if t1 == t2 then return true end
if type(t1) ~= "table" or type(t2) ~= "table" or #t1 ~= #t2 then
return false
end
lut = lut or {} -- look-up table: are these 2 arrays already compared?
lut[t1] = lut[t1] or {}
if lut[t1][t2] then return true end
lut[t2] = lut[t2] or {}
lut[t1][t2], lut[t2][t1] = true, true
for k,v in ipairs (t1) do
if not eq (t2[k], v, lut) then return false end -- recursion
end
return true
end
-- a "nil GUID", to be used instead of nils in datasets
local NT = "b5f74fe5-46f4-483a-8321-e58ba2fa0e17"
-- pack vararg in table, replacing nils with "NT" items
local function packNT (...)
local t = {}
for i=1, select ("#", ...) do
local v = select (i, ...)
t[i] = (v == nil) and NT or v
end
return t
end
-- unpack table into vararg, replacing "NT" items with nils
local function unpackNT (t)
local len = #t
local function unpack_from (i)
local v = t[i]
if v == NT then v = nil end
if i == len then return v end
return v, unpack_from (i+1)
end
if len > 0 then return unpack_from (1) end
end
-- print results (deep into arrays)
local function print_results (val, indent, lut)
indent = indent or ""
lut = lut or {} -- look-up table
local str = tostring (val)
if type (val) == "table" then
if lut[val] then
io.write (indent, str, "\n")
else
lut[val] = true
io.write (indent, str, "\n")
for i,v in ipairs (val) do
print_results (v, " " .. indent, lut) -- recursion
end
end
else
io.write (indent, val == NT and "nil" or str, "\n")
end
end
-- returns:
-- 1) true, if success; false, if failure
-- 2) test results table or error_message
local function test_function (test, func)
local res
local t = packNT (pcall (func, unpackNT (test[1])))
if t[1] then
table.remove (t, 1)
res = t
if alien then
local subject = test[1][1]
local buf = alien.buffer (#subject)
if #subject > 0 then
alien.memmove (buf:topointer (), subject, #subject)
end
test[1][1] = buf
local t = packNT (pcall (func, unpackNT (test[1])))
if t[1] then
table.remove (t, 1)
res = t
else
print "alien test failed"
res = t[2] --> error_message
end
end
else
res = t[2] --> error_message
end
local how = (type (res) == type (test[2])) and
(type (res) == "string" or eq (res, test[2])) -- allow error messages to differ
return how, res
end
-- returns:
-- 1) true, if success; false, if failure
-- 2) test results table or error_message
-- 3) test results table or error_message
local function test_method (test, constructor, name)
local res1, res2
local subject = test[2][1]
local ok, r = pcall (constructor, unpackNT (test[1]))
if ok then
local t = packNT (pcall (r[name], r, unpackNT (test[2])))
if t[1] then
table.remove (t, 1)
res1, res2 = t
else
res1, res2 = 2, t[2] --> 2, error_message
end
else
res1, res2 = 1, r --> 1, error_message
end
return eq (res1, test[3]), res1, res2
end
-- returns: a list of failed tests
local function test_set (set, lib, verbose)
local list = {}
if type (set.Func) == "function" then
local func = set.Func
for i,test in ipairs (set) do
if verbose then
io.write (" running function test "..i.."...")
io.flush ()
end
local ok, res = test_function (test, func)
if not ok then
if verbose then io.stdout:write("failed!\n") end
table.insert (list, {i=i, test[2], res})
elseif verbose then
io.write ("passed\n")
io.flush ()
end
end
elseif type (set.Method) == "string" then
for i,test in ipairs (set) do
if verbose then
io.write (" running method test "..i.."...")
io.flush ()
end
local ok, res1, res2 = test_method (test, lib.new, set.Method)
if not ok then
if verbose then io.stdout:write("failed!\n") end
table.insert (list, {i=i, test[3], res1, res2})
elseif verbose then
io.write ("passed\n")
io.flush ()
end
end
else
error ("neither set.Func nor set.Method is valid")
end
return list
end
return {
eq = eq,
NT = NT,
print_results = print_results,
test_function = test_function,
test_method = test_method,
test_set = test_set,
}