From 491213afb8294c59da5955bf90ad0d81502de7de Mon Sep 17 00:00:00 2001 From: Kevin Wan Date: Sat, 15 May 2021 15:37:24 +0800 Subject: [PATCH] fix #683 (#690) * fix #683 * fix errors --- core/search/tree.go | 55 +++++++++++++++++++++++++++------------- core/search/tree_test.go | 12 ++++----- 2 files changed, 43 insertions(+), 24 deletions(-) diff --git a/core/search/tree.go b/core/search/tree.go index e6c4d796..c49754b9 100644 --- a/core/search/tree.go +++ b/core/search/tree.go @@ -1,6 +1,9 @@ package search -import "errors" +import ( + "errors" + "fmt" +) const ( colon = ':' @@ -8,16 +11,16 @@ const ( ) var ( - // ErrDupItem means adding duplicated item. - ErrDupItem = errors.New("duplicated item") - // ErrDupSlash means item is started with more than one slash. - ErrDupSlash = errors.New("duplicated slash") - // ErrEmptyItem means adding empty item. - ErrEmptyItem = errors.New("empty item") - // ErrInvalidState means search tree is in an invalid state. - ErrInvalidState = errors.New("search tree is in an invalid state") - // ErrNotFromRoot means path is not starting with slash. - ErrNotFromRoot = errors.New("path should start with /") + // errDupItem means adding duplicated item. + errDupItem = errors.New("duplicated item") + // errDupSlash means item is started with more than one slash. + errDupSlash = errors.New("duplicated slash") + // errEmptyItem means adding empty item. + errEmptyItem = errors.New("empty item") + // errInvalidState means search tree is in an invalid state. + errInvalidState = errors.New("search tree is in an invalid state") + // errNotFromRoot means path is not starting with slash. + errNotFromRoot = errors.New("path should start with /") // NotFound is used to hold the not found result. NotFound Result @@ -58,14 +61,22 @@ func NewTree() *Tree { // Add adds item to associate with route. func (t *Tree) Add(route string, item interface{}) error { if len(route) == 0 || route[0] != slash { - return ErrNotFromRoot + return errNotFromRoot } if item == nil { - return ErrEmptyItem + return errEmptyItem } - return add(t.root, route[1:], item) + err := add(t.root, route[1:], item) + switch err { + case errDupItem: + return duplicatedItem(route) + case errDupSlash: + return duplicatedSlash(route) + default: + return err + } } // Search searches item that associates with given route. @@ -141,7 +152,7 @@ func (nd *node) getChildren(route string) map[string]*node { func add(nd *node, route string, item interface{}) error { if len(route) == 0 { if nd.item != nil { - return ErrDupItem + return errDupItem } nd.item = item @@ -149,7 +160,7 @@ func add(nd *node, route string, item interface{}) error { } if route[0] == slash { - return ErrDupSlash + return errDupSlash } for i := range route { @@ -161,7 +172,7 @@ func add(nd *node, route string, item interface{}) error { return add(child, route[i+1:], item) } - return ErrInvalidState + return errInvalidState } child := newNode(nil) @@ -173,7 +184,7 @@ func add(nd *node, route string, item interface{}) error { children := nd.getChildren(route) if child, ok := children[route]; ok { if child.item != nil { - return ErrDupItem + return errDupItem } child.item = item @@ -192,6 +203,14 @@ func addParam(result *Result, k, v string) { result.Params[k] = v } +func duplicatedItem(item string) error { + return fmt.Errorf("duplicated item for %s", item) +} + +func duplicatedSlash(item string) error { + return fmt.Errorf("duplicated slash for %s", item) +} + func match(pat, token string) innerResult { if pat[0] == colon { return innerResult{ diff --git a/core/search/tree_test.go b/core/search/tree_test.go index 763d3abf..b7166e5a 100644 --- a/core/search/tree_test.go +++ b/core/search/tree_test.go @@ -151,9 +151,9 @@ func TestAddDuplicate(t *testing.T) { err := tree.Add("/a/b", 1) assert.Nil(t, err) err = tree.Add("/a/b", 2) - assert.Equal(t, ErrDupItem, err) + assert.Error(t, errDupItem, err) err = tree.Add("/a/b/", 2) - assert.Equal(t, ErrDupItem, err) + assert.Error(t, errDupItem, err) } func TestPlain(t *testing.T) { @@ -169,19 +169,19 @@ func TestPlain(t *testing.T) { func TestSearchWithDoubleSlashes(t *testing.T) { tree := NewTree() err := tree.Add("//a", 1) - assert.Error(t, ErrDupSlash, err) + assert.Error(t, errDupSlash, err) } func TestSearchInvalidRoute(t *testing.T) { tree := NewTree() err := tree.Add("", 1) - assert.Equal(t, ErrNotFromRoot, err) + assert.Equal(t, errNotFromRoot, err) err = tree.Add("bad", 1) - assert.Equal(t, ErrNotFromRoot, err) + assert.Equal(t, errNotFromRoot, err) } func TestSearchInvalidItem(t *testing.T) { tree := NewTree() err := tree.Add("/", nil) - assert.Equal(t, ErrEmptyItem, err) + assert.Equal(t, errEmptyItem, err) }