package internal_test import ( "strconv" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "tildegit.org/tjp/sliderule/internal" ) func TestPathTree(t *testing.T) { type pattern struct { string int } type matchresult struct { value int params map[string]string failed bool } tests := []struct { // path-matching pattern and the integers the tree stores for each patterns []pattern // paths to match against, and the int we get and captured params paths map[string]matchresult }{ { patterns: []pattern{ {"/a", 1}, {"/a/*rest", 2}, {"/a/b", 3}, {"/c", 4}, {"/x/:y/z/*rest", 5}, {"/f/prefix:y/z/*rest", 6}, }, paths: map[string]matchresult{ "/a": { value: 1, params: map[string]string{}, }, "/a/other": { value: 2, params: map[string]string{"rest": "other"}, }, "/a/b": { value: 3, params: map[string]string{}, }, "/a/b/c": { value: 2, params: map[string]string{"rest": "b/c"}, }, "/c": { value: 4, params: map[string]string{}, }, "/c/d": { failed: true, }, "/x/foo/z/bar/baz": { value: 5, params: map[string]string{"y": "foo", "rest": "bar/baz"}, }, "/": { failed: true, }, "/f/mismatch/z/more": { failed: true, }, "/f/prefixblargh/z/more": { value: 6, params: map[string]string{"y": "blargh", "rest": "more"}, }, }, }, { patterns: []pattern{ {"/", 10}, }, paths: map[string]matchresult{ "/": {value: 10, params: map[string]string{}}, "/foo": {failed: true}, }, }, } for i, test := range tests { t.Run(strconv.Itoa(i+1), func(t *testing.T) { tree := &internal.PathTree[int]{} for _, pattern := range test.patterns { tree.Add(pattern.string, pattern.int) } for path, result := range test.paths { t.Run(path, func(t *testing.T) { n, params := tree.Match(path) if result.failed { require.Nil(t, n) } else { require.NotNil(t, n) assert.Equal(t, result.value, *n) assert.Equal(t, result.params, params) } }) } }) } }