Add unit tests and correct bugs detected by the tests
This commit is contained in:
@@ -5,7 +5,9 @@ function utils.is_array(table)
|
||||
local count = 0
|
||||
for k, v in pairs(table) do
|
||||
if type(k) == "number" then
|
||||
if k > max then max = k end
|
||||
if k > max then
|
||||
max = k
|
||||
end
|
||||
count = count + 1
|
||||
else
|
||||
return false
|
||||
@@ -19,143 +21,229 @@ function utils.is_array(table)
|
||||
end
|
||||
|
||||
function utils.escape(s)
|
||||
local replacements = {
|
||||
["\\"] = "\\\\" ,
|
||||
['"'] = '\\"',
|
||||
["\n"] = "\\n",
|
||||
["\t"] = "\\t",
|
||||
["\b"] = "\\b",
|
||||
["\f"] = "\\f",
|
||||
["\r"] = "\\r",
|
||||
["%"] = "%%"
|
||||
}
|
||||
return (s:gsub( "[\\'\"\n\t\b\f\r%%]", replacements ))
|
||||
local replacements = {
|
||||
["\\"] = "\\\\",
|
||||
['"'] = '\\"',
|
||||
["\n"] = "\\n",
|
||||
["\t"] = "\\t",
|
||||
["\b"] = "\\b",
|
||||
["\f"] = "\\f",
|
||||
["\r"] = "\\r",
|
||||
["%"] = "%%"
|
||||
}
|
||||
return (s:gsub("[\\'\"\n\t\b\f\r%%]", replacements))
|
||||
end
|
||||
|
||||
function utils.escape_pattern(s)
|
||||
return s:gsub("[%(%)%.%+%-%*%?%[%]%^%$%%]", "%%%1")
|
||||
return s:gsub("[%(%)%.%+%-%*%?%[%]%^%$%%]", "%%%1")
|
||||
end
|
||||
|
||||
function utils.unescape_pattern(s)
|
||||
return s:gsub( "[%%]", "%%%%")
|
||||
return s:gsub("[%%]", "%%%%")
|
||||
end
|
||||
|
||||
function utils.hex_to_char(x)
|
||||
return string.char(tonumber(x, 16))
|
||||
return string.char(tonumber(x, 16))
|
||||
end
|
||||
|
||||
|
||||
function utils.decodeURI(url)
|
||||
return url:gsub("%%(%x%x)", utils.hex_to_char)
|
||||
return url:gsub("%%(%x%x)", utils.hex_to_char):gsub('+', ' ')
|
||||
end
|
||||
|
||||
function utils.unescape(s)
|
||||
local str = ""
|
||||
local escape = false
|
||||
local esc_map = {b = '\b', f = '\f', n = '\n', r = '\r', t = '\t'}
|
||||
for c in s:gmatch"." do
|
||||
if c ~= '\\' then
|
||||
if escape then
|
||||
if esc_map[c] then
|
||||
str = str..esc_map[c]
|
||||
else
|
||||
str = str..c
|
||||
end
|
||||
else
|
||||
str = str..c
|
||||
end
|
||||
escape = false
|
||||
else
|
||||
if escape then
|
||||
str = str..c
|
||||
escape = false
|
||||
else
|
||||
escape = true
|
||||
end
|
||||
end
|
||||
end
|
||||
return str
|
||||
local str = ""
|
||||
local escape = false
|
||||
local esc_map = {
|
||||
b = '\b',
|
||||
f = '\f',
|
||||
n = '\n',
|
||||
r = '\r',
|
||||
t = '\t'
|
||||
}
|
||||
for c in s:gsub("%%%%", "%%"):gmatch "." do
|
||||
if c ~= '\\' then
|
||||
if escape then
|
||||
if esc_map[c] then
|
||||
str = str .. esc_map[c]
|
||||
else
|
||||
str = str .. c
|
||||
end
|
||||
else
|
||||
str = str .. c
|
||||
end
|
||||
escape = false
|
||||
else
|
||||
if escape then
|
||||
str = str .. c
|
||||
escape = false
|
||||
else
|
||||
escape = true
|
||||
end
|
||||
end
|
||||
end
|
||||
return str
|
||||
end
|
||||
|
||||
function utils.file_exists(name)
|
||||
local f=io.open(name,"r")
|
||||
if f~=nil then io.close(f) return true else return false end
|
||||
local f = io.open(name, "r")
|
||||
if f ~= nil then
|
||||
io.close(f)
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function utils.parse_query(str, sep)
|
||||
if not sep then
|
||||
sep = '&'
|
||||
end
|
||||
|
||||
local values = {}
|
||||
for key, val in str:gmatch(string.format('([^%q=]+)(=*[^%q=]*)', sep, sep)) do
|
||||
local key = utils.decodeURI(key)
|
||||
local keys = {}
|
||||
key = key:gsub('%[([^%]]*)%]', function(v)
|
||||
-- extract keys between balanced brackets
|
||||
if string.find(v, "^-?%d+$") then
|
||||
v = tonumber(v)
|
||||
else
|
||||
v = utils.decodeURI(v)
|
||||
end
|
||||
table.insert(keys, v)
|
||||
return "="
|
||||
end)
|
||||
key = key:gsub('=+.*$', "")
|
||||
key = key:gsub('%s', "_") -- remove spaces in parameter name
|
||||
val = val:gsub('^=+', "")
|
||||
|
||||
if not values[key] then
|
||||
values[key] = {}
|
||||
end
|
||||
if #keys > 0 and type(values[key]) ~= 'table' then
|
||||
values[key] = {}
|
||||
elseif #keys == 0 and type(values[key]) == 'table' then
|
||||
values[key] = utils.decodeURI(val)
|
||||
elseif type(values[key]) == 'string' then
|
||||
values[key] = {values[key]}
|
||||
table.insert(values[key], utils.decodeURI(val))
|
||||
end
|
||||
|
||||
local t = values[key]
|
||||
for i, k in ipairs(keys) do
|
||||
if type(t) ~= 'table' then
|
||||
t = {}
|
||||
end
|
||||
if k == "" then
|
||||
k = #t + 1
|
||||
end
|
||||
if not t[k] then
|
||||
t[k] = {}
|
||||
end
|
||||
if i == #keys then
|
||||
t[k] = val
|
||||
end
|
||||
t = t[k]
|
||||
end
|
||||
end
|
||||
return values
|
||||
end
|
||||
|
||||
function utils.url_parser(uri)
|
||||
local pattern = "^(https?)://([%.%w]+):?(%d*)(/?[^#]*)#?.*$"
|
||||
local obj = {}
|
||||
obj.protocol = uri:gsub(pattern, "%1")
|
||||
obj.hostname = uri:gsub(pattern, "%2")
|
||||
obj.port = uri:gsub(pattern, "%3")
|
||||
obj.query = uri:gsub(pattern, "%4")
|
||||
|
||||
if obj.port == "" then obj.port = 80 else obj.port = tonumber(obj.port) end
|
||||
if obj.query == "" then obj.query="/" end
|
||||
return obj
|
||||
local pattern = "^(https?)://([%.%w]+):?(%d*)(/?[^#]*)#?.*$"
|
||||
local obj = {}
|
||||
obj.protocol = uri:gsub(pattern, "%1")
|
||||
obj.hostname = uri:gsub(pattern, "%2")
|
||||
obj.port = uri:gsub(pattern, "%3")
|
||||
obj.query = uri:gsub(pattern, "%4")
|
||||
|
||||
if obj.port == "" then
|
||||
obj.port = 80
|
||||
else
|
||||
obj.port = tonumber(obj.port)
|
||||
end
|
||||
if obj.query == "" then
|
||||
obj.query = "/"
|
||||
end
|
||||
return obj
|
||||
end
|
||||
|
||||
JSON = require("json")
|
||||
|
||||
function JSON.encode(obj)
|
||||
local t = type(obj)
|
||||
if t == 'table' then
|
||||
-- encode object
|
||||
if utils.is_array(obj) == false then
|
||||
local lst = {}
|
||||
for k,v in pairs(obj) do
|
||||
table.insert(lst,'"'..k..'":'..JSON.encode(v))
|
||||
end
|
||||
return "{"..table.concat(lst,",").."}"
|
||||
else
|
||||
local lst = {}
|
||||
local a = {}
|
||||
for n in pairs(obj) do table.insert(a, n) end
|
||||
table.sort(a)
|
||||
for i,v in pairs(a) do
|
||||
table.insert(lst,JSON.encode(obj[v]))
|
||||
end
|
||||
return "["..table.concat(lst,",").."]"
|
||||
end
|
||||
elseif t == 'string' then
|
||||
--print('"'..utils.escape(obj)..'"')
|
||||
return '"'..utils.escape(obj)..'"'
|
||||
elseif t == 'boolean' or t == 'number' then
|
||||
return tostring(obj)
|
||||
elseif obj == nil then
|
||||
return "null"
|
||||
else
|
||||
return '"'..tostring(obj)..'"'
|
||||
end
|
||||
local t = type(obj)
|
||||
if t == 'table' then
|
||||
-- encode object
|
||||
if utils.is_array(obj) == false then
|
||||
local lst = {}
|
||||
for k, v in pairs(obj) do
|
||||
table.insert(lst, '"' .. k .. '":' .. JSON.encode(v))
|
||||
end
|
||||
return "{" .. table.concat(lst, ",") .. "}"
|
||||
else
|
||||
local lst = {}
|
||||
local a = {}
|
||||
for n in pairs(obj) do
|
||||
table.insert(a, n)
|
||||
end
|
||||
table.sort(a)
|
||||
for i, v in pairs(a) do
|
||||
table.insert(lst, JSON.encode(obj[v]))
|
||||
end
|
||||
return "[" .. table.concat(lst, ",") .. "]"
|
||||
end
|
||||
elseif t == 'string' then
|
||||
-- print('"'..utils.escape(obj)..'"')
|
||||
return '"' .. utils.escape(obj) .. '"'
|
||||
elseif t == 'boolean' or t == 'number' then
|
||||
return tostring(obj)
|
||||
elseif obj == nil then
|
||||
return "null"
|
||||
else
|
||||
return '"' .. tostring(obj) .. '"'
|
||||
end
|
||||
end
|
||||
|
||||
function explode(str, div) -- credit: http://richard.warburton.it
|
||||
if (div=='') then return false end
|
||||
local pos,arr = 0,{}
|
||||
-- for each divider found
|
||||
for st,sp in function() return string.find(str,div,pos,true) end do
|
||||
table.insert(arr,string.sub(str,pos,st-1)) -- Attach chars left of current divider
|
||||
pos = sp + 1 -- Jump past current divider
|
||||
end
|
||||
table.insert(arr,string.sub(str,pos)) -- Attach chars right of last divider
|
||||
return arr
|
||||
end
|
||||
if (div == '') then
|
||||
return false
|
||||
end
|
||||
local pos, arr = 0, {}
|
||||
-- for each divider found
|
||||
for st, sp in function()
|
||||
return string.find(str, div, pos, true)
|
||||
end do
|
||||
table.insert(arr, string.sub(str, pos, st - 1)) -- Attach chars left of current divider
|
||||
pos = sp + 1 -- Jump past current divider
|
||||
end
|
||||
table.insert(arr, string.sub(str, pos)) -- Attach chars right of last divider
|
||||
return arr
|
||||
end
|
||||
function implode(arr, div)
|
||||
return table.concat(arr,div)
|
||||
return table.concat(arr, div)
|
||||
end
|
||||
|
||||
function firstToUpper(str)
|
||||
return (str:gsub("^%l", string.upper))
|
||||
end
|
||||
|
||||
|
||||
local charset = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890"
|
||||
|
||||
function utils.generate_salt(length)
|
||||
local ret = {}
|
||||
local r
|
||||
for i = 1, length do
|
||||
r = math.random(1, #charset)
|
||||
table.insert(ret, charset:sub(r, r))
|
||||
end
|
||||
return table.concat(ret)
|
||||
local ret = {}
|
||||
local r
|
||||
for i = 1, length do
|
||||
r = math.random(1, #charset)
|
||||
table.insert(ret, charset:sub(r, r))
|
||||
end
|
||||
return table.concat(ret)
|
||||
end
|
||||
|
||||
function utils.ext(path)
|
||||
return path:match("%.([^%.]*)$")
|
||||
end
|
||||
|
||||
function utils.basename(str)
|
||||
local name = string.gsub(ulib.trim(str, "/"), "(.*/)(.*)", "%2")
|
||||
return name
|
||||
end
|
||||
Reference in New Issue
Block a user