123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- package search
- import (
- "testing"
- "github.com/stretchr/testify/assert"
- )
- type mockedRoute struct {
- route string
- value int
- }
- func TestSearch(t *testing.T) {
- routes := []mockedRoute{
- {"/", 1},
- {"/api", 2},
- {"/img", 3},
- {"/:layer1", 4},
- {"/api/users", 5},
- {"/img/jpgs", 6},
- {"/img/jpgs", 7},
- {"/api/:layer2", 8},
- {"/:layer1/:layer2", 9},
- {"/:layer1/:layer2/users", 10},
- }
- tests := []struct {
- query string
- expect int
- params map[string]string
- contains bool
- }{
- {
- query: "",
- contains: false,
- },
- {
- query: "/",
- expect: 1,
- contains: true,
- },
- {
- query: "/wildcard",
- expect: 4,
- params: map[string]string{
- "layer1": "wildcard",
- },
- contains: true,
- },
- {
- query: "/wildcard/",
- expect: 4,
- params: map[string]string{
- "layer1": "wildcard",
- },
- contains: true,
- },
- {
- query: "/a/b/c",
- contains: false,
- },
- {
- query: "/a/b",
- expect: 9,
- params: map[string]string{
- "layer1": "a",
- "layer2": "b",
- },
- contains: true,
- },
- {
- query: "/a/b/",
- expect: 9,
- params: map[string]string{
- "layer1": "a",
- "layer2": "b",
- },
- contains: true,
- },
- {
- query: "/a/b/users",
- expect: 10,
- params: map[string]string{
- "layer1": "a",
- "layer2": "b",
- },
- contains: true,
- },
- }
- for _, test := range tests {
- t.Run(test.query, func(t *testing.T) {
- tree := NewTree()
- for _, r := range routes {
- tree.Add(r.route, r.value)
- }
- result, ok := tree.Search(test.query)
- assert.Equal(t, test.contains, ok)
- if ok {
- actual := result.Item.(int)
- assert.EqualValues(t, test.params, result.Params)
- assert.Equal(t, test.expect, actual)
- }
- })
- }
- }
- func TestStrictSearch(t *testing.T) {
- routes := []mockedRoute{
- {"/api/users", 1},
- {"/api/:layer", 2},
- }
- query := "/api/users"
- tree := NewTree()
- for _, r := range routes {
- tree.Add(r.route, r.value)
- }
- for i := 0; i < 1000; i++ {
- result, ok := tree.Search(query)
- assert.True(t, ok)
- assert.Equal(t, 1, result.Item.(int))
- }
- }
- func TestStrictSearchSibling(t *testing.T) {
- routes := []mockedRoute{
- {"/api/:user/profile/name", 1},
- {"/api/:user/profile", 2},
- {"/api/:user/name", 3},
- {"/api/:layer", 4},
- }
- query := "/api/123/name"
- tree := NewTree()
- for _, r := range routes {
- tree.Add(r.route, r.value)
- }
- for i := 0; i < 1000; i++ {
- result, ok := tree.Search(query)
- assert.True(t, ok)
- assert.Equal(t, 3, result.Item.(int))
- }
- }
- func TestAddDuplicate(t *testing.T) {
- tree := NewTree()
- err := tree.Add("/a/b", 1)
- assert.Nil(t, err)
- err = tree.Add("/a/b", 2)
- assert.Error(t, errDupItem, err)
- err = tree.Add("/a/b/", 2)
- assert.Error(t, errDupItem, err)
- }
- func TestPlain(t *testing.T) {
- tree := NewTree()
- err := tree.Add("/a/b", 1)
- assert.Nil(t, err)
- err = tree.Add("/a/c", 2)
- assert.Nil(t, err)
- _, ok := tree.Search("/a/d")
- assert.False(t, ok)
- }
- func TestSearchWithDoubleSlashes(t *testing.T) {
- tree := NewTree()
- err := tree.Add("//a", 1)
- assert.Error(t, errDupSlash, err)
- }
- func TestSearchInvalidRoute(t *testing.T) {
- tree := NewTree()
- err := tree.Add("", 1)
- assert.Equal(t, errNotFromRoot, err)
- err = tree.Add("bad", 1)
- assert.Equal(t, errNotFromRoot, err)
- }
- func TestSearchInvalidItem(t *testing.T) {
- tree := NewTree()
- err := tree.Add("/", nil)
- assert.Equal(t, errEmptyItem, err)
- }
|