3.10 路由树-参数路径之校验
Last updated
// childOrCreate 本方法用于在节点上获取给定的子节点,如果给定的子节点不存在则创建
func (n *node) childOrCreate(segment string) *node {
// 如果路径为参数 则查找当前节点的参数子节点 或创建一个当前节点的参数子节点 并返回
if strings.HasPrefix(segment, ":") {
// 若当前节点存在通配符子节点 则不允许注册参数子节点
if n.wildcardChild != nil {
panic("web: 非法路由,已有通配符路由.不允许同时注册通配符路由和参数路由")
}
if n.paramChild == nil {
n.paramChild = &node{
path: segment,
}
}
return n.paramChild
}
// 若路径为通配符 则查找当前节点的通配符子节点 或创建一个当前节点的通配符子节点 并返回
if segment == "*" {
// 若当前节点存在参数子节点 则不允许注册通配符子节点
if n.paramChild != nil {
panic("web: 非法路由,已有参数路由.不允许同时注册通配符路由和参数路由")
}
if n.wildcardChild == nil {
n.wildcardChild = &node{
path: segment,
}
}
return n.wildcardChild
}
// 如果当前节点的子节点映射为空 则创建一个子节点映射
if n.children == nil {
n.children = map[string]*node{}
}
res, ok := n.children[segment]
// 如果没有找到子节点,则创建一个子节点;否则返回找到的子节点
if !ok {
res = &node{
path: segment,
}
n.children[segment] = res
}
return res
}// TestRouter_findRoute_param_and_wildcard_coexist 测试针对注册参数路由时,已有通配符路由的情况
func TestRouter_findRoute_param_and_wildcard_coexist(t *testing.T) {
// step1. 注册有冲突的路由
r := newRouter()
mockHandleFunc := func(ctx *Context) {}
r.addRoute(http.MethodGet, "/order/detail/*", mockHandleFunc)
// step2. 断言非法用例
assert.Panicsf(t, func() {
r.addRoute(http.MethodGet, "/order/detail/:id", mockHandleFunc)
}, "web: 非法路由,已有通配符路由.不允许同时注册通配符路由和参数路由")
}
// TestRouter_findRoute_wildcard_and_param_coexist 测试针对注册通配符路由时,已有参数路由的情况
func TestRouter_findRoute_wildcard_and_param_coexist(t *testing.T) {
// step1. 注册有冲突的路由
r := newRouter()
mockHandleFunc := func(ctx *Context) {}
r.addRoute(http.MethodGet, "/order/detail/:id", mockHandleFunc)
// step2. 断言非法用例
assert.Panicsf(t, func() {
r.addRoute(http.MethodGet, "/order/detail/*", mockHandleFunc)
}, "web: 非法路由,已有参数路由.不允许同时注册通配符路由和参数路由")
}