Files
lualibs-lrexlib/rex_pcre_sets_test.lua
T
2022-12-21 16:36:15 +10:00

196 lines
7.5 KiB
Lua

-- See Copyright Notice in the file LICENSE
local luatest = require "rex_lua_test"
local N = luatest.NT
local unpack = unpack or table.unpack
local function norm(a) return a==nil and N or a end
local function fill (n, m)
local t = {}
for i = n, m, -1 do table.insert (t, i) end
return t
end
local function set_named_subpatterns (lib, flg)
return {
Name = "Named Subpatterns",
Func = function (subj, methodname, patt, name1, name2)
local r = lib.new (patt)
local _,_,caps = r[methodname] (r, subj)
return norm(caps[name1]), norm(caps[name2])
end,
--{} N.B. subject is always first element
{ {"abcd", "tfind", "(?P<dog>.)b.(?P<cat>d)", "dog", "cat"}, {"a","d"} },
{ {"abcd", "exec", "(?P<dog>.)b.(?P<cat>d)", "dog", "cat"}, {"a","d"} },
}
end
local function set_f_find (lib, flg)
local cp1251 =
"ÀÁÂÃÄŨÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãä叿çèéêëìíîïðñòóôõö÷øùúûüýþÿ"
local loc = "Russian_Russia.1251"
return {
Name = "Function find",
Func = lib.find,
--{subj, patt, st,cf,ef,lo}, { results }
{ {"abcd", ".+", 5}, { N } }, -- failing st
{ {"abcd", ".*?"}, { 1,0 } }, -- non-greedy
{ {"abc", "aBC", N,flg.CASELESS}, { 1,3 } }, -- cf
{ {"abc", "aBC", N,"i" }, { 1,3 } }, -- cf
{ {"abc", "bc", N,flg.ANCHORED}, { N } }, -- cf
{ {"abc", "bc", N,N,flg.ANCHORED}, { N } }, -- ef
--{ {cp1251, "[[:upper:]]+", N,N,N, loc}, { 1,33} }, -- locale
--{ {cp1251, "[[:lower:]]+", N,N,N, loc}, {34,66} }, -- locale
}
end
local function set_f_match (lib, flg)
return {
Name = "Function match",
Func = lib.match,
--{subj, patt, st,cf,ef,lo}, { results }
{ {"abcd", ".+", 5}, { N }}, -- failing st
{ {"abcd", ".*?"}, { "" }}, -- non-greedy
{ {"abc", "aBC", N,flg.CASELESS}, {"abc" }}, -- cf
{ {"abc", "aBC", N,"i" }, {"abc" }}, -- cf
{ {"abc", "bc", N,flg.ANCHORED}, { N }}, -- cf
{ {"abc", "bc", N,N,flg.ANCHORED}, { N }}, -- ef
}
end
local function set_f_gmatch (lib, flg)
-- gmatch (s, p, [cf], [ef])
local pCSV = "[^,]*"
local F = false
local function test_gmatch (subj, patt)
local out, guard = {}, 10
for a, b in lib.gmatch (subj, patt) do
table.insert (out, { norm(a), norm(b) })
guard = guard - 1
if guard == 0 then break end
end
return unpack (out)
end
return {
Name = "Function gmatch",
Func = test_gmatch,
--{ subj patt results }
{ {"a\0c", "." }, {{"a",N},{"\0",N},{"c",N}} },--nuls in subj
{ {"", pCSV}, {{"",N}} },
{ {"12", pCSV}, {{"12",N}} },
{ {",", pCSV}, {{"", N},{"", N}} },
{ {"12,,45", pCSV}, {{"12",N},{"",N},{"45",N}} },
{ {",,12,45,,ab,", pCSV}, {{"",N},{"",N},{"12",N},{"45",N},{"",N},{"ab",N},{"",N}} },
{ {"12345", "(.)(.)"}, {{"1","2"},{"3","4"}} },
{ {"12345", "(.)(.?)"}, {{"1","2"},{"3","4"},{"5",""}} },
}
end
local function set_f_split (lib, flg)
-- split (s, p, [cf], [ef])
local function test_split (subj, patt)
local out, guard = {}, 10
for a, b, c in lib.split (subj, patt) do
table.insert (out, { norm(a), norm(b), norm(c) })
guard = guard - 1
if guard == 0 then break end
end
return unpack (out)
end
return {
Name = "Function split",
Func = test_split,
--{ subj patt results }
{ {"a,\0,c", ","}, {{"a",",",N},{"\0",",",N},{"c",N,N}, } },--nuls in subj
{ {"ab", "$"}, {{"ab","",N}, {"",N,N} } },
{ {"ab", "^|$"}, {{"", "", N}, {"ab","",N}, {"",N,N} } },
{ {"ab45ab","(?<=ab).*?"}, {{"ab","",N}, {"45ab","",N}, {"",N,N} } },
{ {"ab", "\\b"}, {{"", "", N}, {"ab","",N}, {"",N,N} } },
{ {"ab", ".*" }, {{"","ab",N}, {"",N,N} } },
{ {"ab", ".*?" }, {{"","",N}, {"a","",N}, {"b","",N}, {"",N,N} } },
{ {"ab;de", ";*" }, {{"","",N},{"a","",N},{"b",";",N},{"d","",N},{"e","",N},{"",N,N} }},
}
end
local function set_m_exec (lib, flg)
return {
Name = "Method exec",
Method = "exec",
--{patt,cf,lo}, {subj,st,ef} { results }
{ {".+"}, {"abcd",5}, { N } }, -- failing st
{ {".*?"}, {"abcd"}, {1,0,{}} }, -- non-greedy
{ {"aBC",flg.CASELESS}, {"abc"}, {1,3,{}} }, -- cf
{ {"aBC","i" }, {"abc"}, {1,3,{}} }, -- cf
{ {"bc",flg.ANCHORED}, {"abc"}, { N } }, -- cf
{ {"bc"}, {"abc",N, flg.ANCHORED}, { N } }, -- ef
}
end
local function set_m_tfind (lib, flg)
return {
Name = "Method tfind",
Method = "tfind",
--{patt,cf,lo}, {subj,st,ef} { results }
{ {".+"}, {"abcd",5}, { N } }, -- failing st
{ {".*?"}, {"abcd"}, {1,0,{}} }, -- non-greedy
{ {"aBC",flg.CASELESS}, {"abc"}, {1,3,{}} }, -- cf
{ {"aBC","i" }, {"abc"}, {1,3,{}} }, -- cf
{ {"bc",flg.ANCHORED}, {"abc"}, { N } }, -- cf
{ {"bc"}, {"abc",N, flg.ANCHORED}, { N } }, -- ef
}
end
local function set_m_dfa_exec (lib, flg)
local ver = tonumber(lib.version():match("%d+%.%d+"))
local NAP = ver < 8.34 and "" or "(*NO_AUTO_POSSESS)"
local flag_partial = ver < 10.0 and flg.PARTIAL or flg.PARTIAL_SOFT
return {
Name = "Method dfa_exec",
Method = "dfa_exec",
--{patt,cf,lo}, {subj,st,ef,os,ws} { results }
{ {NAP..".+"}, {"abcd"}, {1,{4,3,2,1},4} }, -- [none]
{ {NAP..".+"}, {"abcd",2}, {2,{4,3,2}, 3} }, -- positive st
{ {NAP..".+"}, {"abcd",-2}, {3,{4,3}, 2} }, -- negative st
{ {".+"}, {"abcd",5}, {N } }, -- failing st
{ {NAP..".*"}, {"abcd"}, {1,{4,3,2,1,0},5}}, -- [none]
{ {".*?"}, {"abcd"}, {1,{4,3,2,1,0},5}}, -- non-greedy
{ {"aBC",flg.CASELESS}, {"abc"}, {1,{3},1} }, -- cf
{ {"aBC","i" }, {"abc"}, {1,{3},1} }, -- cf
{ {"bc"}, {"abc"}, {2,{3},1} }, -- [none]
{ {"bc",flg.ANCHORED}, {"abc"}, {N } }, -- cf
{ {"bc"}, {"abc",N, flg.ANCHORED}, {N } }, -- ef
{ { "(.)b.(d)"}, {"abcd"}, {1,{4},1} }, --[captures]
{ {"abc"}, {"ab"}, {N } },
{ {"abc"}, {"ab",N,flag_partial}, {1,{2},flg.ERROR_PARTIAL} },
{ {NAP..".+"}, {string.rep("a",50),N,N,50,50}, {1, fill(50,26), 0}},-- small ovecsize
}
end
local function set_m_fullinfo (lib, flg)
local r = lib.new("(foo)(bar)")
local info = r:fullinfo()
assert(info.CAPTURECOUNT == 2)
end
return function (libname)
local lib = require (libname)
local flags = lib.flags ()
local sets = {
set_f_match (lib, flags),
set_f_find (lib, flags),
set_f_gmatch (lib, flags),
set_f_split (lib, flags),
set_m_exec (lib, flags),
set_m_tfind (lib, flags),
set_m_fullinfo (lib, flags),
}
if flags.MAJOR >= 4 then
table.insert (sets, set_named_subpatterns (lib, flags))
end
if flags.MAJOR >= 6 then
table.insert (sets, set_m_dfa_exec (lib, flags))
end
return sets
end