Skip to content

Commit

Permalink
merge feature from branch
Browse files Browse the repository at this point in the history
  • Loading branch information
sumory committed Apr 16, 2017
2 parents e79b7c5 + d47632e commit 3a30937
Show file tree
Hide file tree
Showing 6 changed files with 502 additions and 13 deletions.
2 changes: 1 addition & 1 deletion lib/lor/lib/application.lua
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ function App:handle(req, res, callback)
local done = callback or function(err)
if err then
if ngx then ngx.log(ngx.ERR, err) end
res:status(500):send("unknown error.")
res:status(500):send("internal error! please check log.")
end
end

Expand Down
73 changes: 66 additions & 7 deletions lib/lor/lib/router/group.lua
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
local setmetatable = setmetatable
local pairs = pairs
local type = type
local error = error
local next = next
local string_format = string.format
local string_lower = string.lower
local table_insert = table.insert
local unpack = table.unpack or unpack

local supported_http_methods = require("lor.lib.methods")
local debug = require("lor.lib.debug")
local utils = require("lor.lib.utils.utils")
local random = utils.random
local clone = utils.clone
local handler_error_tip = "handler must be `function` that matches `function(req, res, next) ... end`"

local Group = {}

Expand Down Expand Up @@ -45,29 +50,83 @@ function Group:get_apis()
return self.apis
end

function Group:set_api(path, method, func)
if not path or not method or not func then
return error("params should not be nil.")
function Group:set_api(path, method, ...)
if not path or not method then
return error("`path` & `method` should not be nil.")
end

if type(path) ~= "string" or type(method) ~= "string" or type(func) ~= "function" then
local handlers = {...}
if not next(handlers) then
return error("handler should not be nil or empty")
end

if type(path) ~= "string" or type(method) ~= "string" or type(handlers) ~= "table" then
return error("params type error.")
end

local extended_handlers = {}
for _, h in ipairs(handlers) do
if type(h) == "function" then
table_insert(extended_handlers, h)
elseif type(h) == "table" then
for _, hh in ipairs(h) do
if type(hh) == "function" then
table_insert(extended_handlers, hh)
else
error(handler_error_tip)
end
end
else
error(handler_error_tip)
end
end

method = string_lower(method)
if not supported_http_methods[method] then
return error(string_format("[%s] method is not supported yet.", method))
end

self.apis[path] = self.apis[path] or {}
self.apis[path][method] = func
self.apis[path][method] = extended_handlers
end

function Group:build_method()
for m, _ in pairs(supported_http_methods) do
m = string_lower(m)
Group[m] = function(myself, path, func)
Group.set_api(myself, path, m, func)

-- 1. group_router:get(func1)
-- 2. group_router:get(func1, func2)
-- 3. group_router:get({func1, func2})
-- 4. group_router:get(path, func1)
-- 5. group_router:get(path, func1, func2)
-- 6. group_router:get(path, {func1, func2})
Group[m] = function(myself, ...)
local params = {...}
if not next(params) then return error("params should not be nil or empty") end

-- case 1 or 3
if #params == 1 then
if type(params[1]) ~= "function" and type(params[1]) ~= "table" then
return error("it must be an function if there's only one param")
end

if type(params[1]) == "table" and #(params[1]) == 0 then
return error("params should not be nil or empty")
end

return Group.set_api(myself, "", m, ...)
end

-- case 2,4,5,6
if #params > 1 then
if type(params[1]) == "string" then -- case 4,5,6
return Group.set_api(myself, params[1], m, unpack(params, 2))
else -- case 2
return Group.set_api(myself, "", m, ...)
end
end

error("error params for group route define")
end
end
end
Expand Down
17 changes: 12 additions & 5 deletions lib/lor/lib/router/router.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ local ipairs = ipairs
local pcall = pcall
local xpcall = xpcall
local type = type
local error = error
local setmetatable = setmetatable
local traceback = debug.traceback
local tinsert = table.insert
Expand Down Expand Up @@ -287,21 +288,27 @@ function Router:merge_group(prefix, group)
if apis then
for uri, api_methods in pairs(apis) do
if type(api_methods) == "table" then
local path = utils.clear_slash(prefix .. "/" .. uri)
local path
if uri == "" then -- for group index route
path = utils.clear_slash(prefix)
else
path = utils.clear_slash(prefix .. "/" .. uri)
end

local node = self.trie:add_node(path)
if not node then
return error("cann't define node on router trie, path:" .. path)
end

for method, func in pairs(api_methods) do
for method, handlers in pairs(api_methods) do
local m = string_lower(method)
if supported_http_methods[m] == true then
node:handle(m, func)
end
node:handle(m, handlers)
end -- supported method
end
end
end
end
end -- ugly arrow style for missing `continue`

return self
end
Expand Down
165 changes: 165 additions & 0 deletions spec/cases/group_index_route_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
before_each(function()
lor = _G.lor
app = lor({
debug = true
})
Request = _G.request
Response = _G.response
req = Request:new()
res = Response:new()
end)

after_each(function()
lor = nil
app = nil
Request = nil
Response = nil
req = nil
res = nil
end)


describe("group index route: basic usages", function()
it("should be error when giving wrong params", function()
local flag = 0
local test_router = lor:Router()

assert.has_error(function() test_router:get() end, "params should not be nil or empty")
assert.has_error(function() test_router:get({}) end, "params should not be nil or empty")

assert.has_error(function() test_router:get("/test") end, "it must be an function if there's only one param")
assert.has_error(function() test_router:get("/test", "abc") end)
end)

it("uri should mathed", function()
local flag = 0

local test_router = lor:Router()
test_router:get(function(req, res, next)
flag = 1
end)

app:use("/test", test_router())

req.path = "/test"
req.method = "get"
app:handle(req, res)
assert.is.equals(1, flag)
end)

it("uri should not mathed", function()
local flag = 0

local test_router = lor:Router()
test_router:get(function(req, res, next)
flag = 1
end)

app:use("/test", test_router())
app:erroruse(function(err, req, res, next) -- 404 error
assert.is.truthy(err)
assert.is.equals(false, req:is_found())
flag = 999
end)

req.path = "/test/"
req.method = "get"
app:handle(req, res)
assert.is.equals(999, flag)
end)
end)


describe("group index route: multi funcs", function()
it("array params", function()
local flag = 0
local test_router = lor:Router()
local func1 = function(req, res, next)
flag = 1
next()
end
local func2 = function(req, res, next)
flag = 2
next()
end
local last_func = function(req, res, next)
flag = 3
end
test_router:post({func1, func2, last_func})
app:use("/test", test_router())

req.path = "/test"
req.method = "post"
app:handle(req, res)
assert.is.equals(3, flag)
end)

it("unpacked params", function()
local flag = 0
local test_router = lor:Router()
local func1 = function(req, res, next)
flag = 1
next()
end
local func2 = function(req, res, next)
flag = 2
next()
end
local last_func = function(req, res, next)
flag = 3
end
test_router:put(func1, func2, last_func)
app:use("/test", test_router())

req.path = "/test"
req.method = "put"
app:handle(req, res)
assert.is.equals(3, flag)
end)

it("mixed params, case1", function()
local flag = 0
local test_router = lor:Router()
local func1 = function(req, res, next)
flag = 1
next()
end
local func2 = function(req, res, next)
flag = 2
next()
end
local last_func = function(req, res, next)
flag = 3
end
test_router:get({func1, func2}, last_func)
app:use("/test", test_router())

req.path = "/test"
req.method = "get"
app:handle(req, res)
assert.is.equals(3, flag)
end)

it("mixed params, case2", function()
local flag = 0
local test_router = lor:Router()
local func1 = function(req, res, next)
flag = 1
next()
end
local func2 = function(req, res, next)
flag = 2
next()
end
local last_func = function(req, res, next)
flag = 3
end
test_router:put({func1}, func2, {last_func})
app:use("/test", test_router())

req.path = "/test"
req.method = "put"
app:handle(req, res)
assert.is.equals(3, flag)
end)
end)
Loading

0 comments on commit 3a30937

Please sign in to comment.