Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/model/FunctionMap.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ local FunctionMap = {
["keyMatch4"] = BuiltInFunctions.keyMatch4Func,
["regexMatch"] = BuiltInFunctions.regexMatchFunc,
["IPMatch"] = BuiltInFunctions.IPMatchFunc,
["globMatch"] = BuiltInFunctions.globMatch
["globMatch"] = BuiltInFunctions.globMatch,
["keyMatch5"] = BuiltInFunctions.keyMatch4Func,
}

-- FunctionMap provides a set of built in functions
Expand Down
26 changes: 25 additions & 1 deletion src/util/BuiltInFunctions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ local BuiltInFunctions = {}

function BuiltInFunctions.validateVariadicArgs(expectedLen, args)
if #args ~= expectedLen then
return error("Expected"..expectedLen.." arguments, but got "..#args)
return error("Expected "..expectedLen.." arguments, but got "..#args)
end
for i=1,expectedLen do
if type(args[i])~="string" then
Expand Down Expand Up @@ -247,6 +247,30 @@ function BuiltInFunctions.globMatch(key1, key2)
end
end

-- Wrapper for keyMatch5
function BuiltInFunctions.keyMatch5Func(args)
BuiltInFunctions.validateVariadicArgs(2, args)
return BuiltInFunctions.keyMatch5(args[1], args[2])
end

-- KeyMatch5 determines whether key1 matches the pattern of key2 (similar to RESTful path), key2 can contain a *
-- For example,
-- - "/foo/bar?status=1&type=2" matches "/foo/bar"
-- - "/parent/child1" and "/parent/child1" matches "/parent/*"
-- - "/parent/child1?status=1" matches "/parent/*"
function BuiltInFunctions.keyMatch5(key1, key2)
local i = string.find(key1, "?", 1, true)

if i then
key1 = string.sub(key1, 1, i - 1)
end

key2 = string.gsub(key2, "/%*", "/.*")
key2 = string.gsub(key2, "%{[^/]+%}", "[^/]+")

return string.match(key1, "^" .. key2 .. "$") ~= nil
end

-- GenerateGFunction is the factory method of the g(_, _) function.
function BuiltInFunctions.generateGFunction(rm)
local function f(args)
Expand Down
42 changes: 42 additions & 0 deletions tests/util/built_in_functions_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -200,4 +200,46 @@ describe("BuiltInFunctions tests", function ()
assert.is.False(BuiltInFunctions.IPMatch("192.168.2.124", "192.168.2.123"))
assert.is.False(BuiltInFunctions.IPMatch("192.166.2.123", "192.168.2.123"))
end)

it("keyMatch5 tests", function ()
assert.has_error(function () BuiltInFunctions.keyMatch5Func({"/foo"}) end, "Expected 2 arguments, but got 1")
assert.has_error(function () BuiltInFunctions.keyMatch5Func({"/foo/create/123", "/foo/*", "/foo/update/123"}) end, "Expected 2 arguments, but got 3")
assert.has_error(function () BuiltInFunctions.keyMatch5Func({"/parent/123", true}) end, "Argument must be a string")

assert.is.True(BuiltInFunctions.keyMatch5("/parent/child?status=1&type=2", "/parent/child"))
assert.is.False(BuiltInFunctions.keyMatch5("/parent?status=1&type=2", "/parent/child"))

assert.is.True(BuiltInFunctions.keyMatch5("/parent/child/?status=1&type=2", "/parent/child/"))
assert.is.False(BuiltInFunctions.keyMatch5("/parent/child/?status=1&type=2", "/parent/child"))
assert.is.False(BuiltInFunctions.keyMatch5("/parent/child?status=1&type=2", "/parent/child/"))

assert.is.True(BuiltInFunctions.keyMatch5("/foo", "/foo"))
assert.is.True(BuiltInFunctions.keyMatch5("/foo", "/foo*"))
assert.is.False(BuiltInFunctions.keyMatch5("/foo", "/foo/*"))
assert.is.False(BuiltInFunctions.keyMatch5("/foo/bar", "/foo"))
assert.is.False(BuiltInFunctions.keyMatch5("/foo/bar", "/foo*"))
assert.is.True(BuiltInFunctions.keyMatch5("/foo/bar", "/foo/*"))
assert.is.False(BuiltInFunctions.keyMatch5("/foobar", "/foo"))
assert.is.False(BuiltInFunctions.keyMatch5("/foobar", "/foo*"))
assert.is.False(BuiltInFunctions.keyMatch5("/foobar", "/foo/*"))

assert.is.False(BuiltInFunctions.keyMatch5("/", "/{resource}"))
assert.is.True(BuiltInFunctions.keyMatch5("/resource1", "/{resource}"))
assert.is.False(BuiltInFunctions.keyMatch5("/myid", "/{id}/using/{resId}"))
assert.is.True(BuiltInFunctions.keyMatch5("/myid/using/myresid", "/{id}/using/{resId}"))

assert.is.False(BuiltInFunctions.keyMatch5("/proxy/myid", "/proxy/{id}/*"))
assert.is.True(BuiltInFunctions.keyMatch5("/proxy/myid/", "/proxy/{id}/*"))
assert.is.True(BuiltInFunctions.keyMatch5("/proxy/myid/res", "/proxy/{id}/*"))
assert.is.True(BuiltInFunctions.keyMatch5("/proxy/myid/res/res2", "/proxy/{id}/*"))
assert.is.True(BuiltInFunctions.keyMatch5("/proxy/myid/res/res2/res3", "/proxy/{id}/*"))
assert.is.False(BuiltInFunctions.keyMatch5("/proxy/", "/proxy/{id}/*"))

assert.is.False(BuiltInFunctions.keyMatch5("/proxy/myid?status=1&type=2", "/proxy/{id}/*"))
assert.is.True(BuiltInFunctions.keyMatch5("/proxy/myid/", "/proxy/{id}/*"))
assert.is.True(BuiltInFunctions.keyMatch5("/proxy/myid/res?status=1&type=2", "/proxy/{id}/*"))
assert.is.True(BuiltInFunctions.keyMatch5("/proxy/myid/res/res2?status=1&type=2", "/proxy/{id}/*"))
assert.is.True(BuiltInFunctions.keyMatch5("/proxy/myid/res/res2/res3?status=1&type=2", "/proxy/{id}/*"))
assert.is.False(BuiltInFunctions.keyMatch5("/proxy/", "/proxy/{id}/*"))
end)
end)
Loading