diff --git a/store.go b/store.go index 97578ac..dfb36aa 100644 --- a/store.go +++ b/store.go @@ -121,6 +121,9 @@ func lookupNextToken(in string, offset int, parent *node, res *[]Token, numParam // -- -- {END} if offset+child.Token.Len <= len(in) { + if child.nextEnd() && offset+child.Token.Len != len(in) { + continue + } if in[offset:offset+child.Token.Len] == child.Token.Raw { *res = append(*res, child.Token) @@ -289,6 +292,13 @@ func (n *node) lengthConstOrZero() int { return len(n.Token.Raw) } +func (n *node) nextEnd() bool { + if len(n.Childs) != 1 { + return false + } + return n.Childs[0].Token.Mode == END +} + // Less returns true if // - left token type is CONST // - more length of value of token (type is CONST) on the left than right diff --git a/store_test.go b/store_test.go index c246f0d..e692194 100644 --- a/store_test.go +++ b/store_test.go @@ -176,6 +176,36 @@ func Test_StoreMultiple(t *testing.T) { {"pathParams", "/path/{param}"}, {"path", "/path/"}, }, "/path/foo", true, Tokens{StartToken, ConstToken("/path/"), ParsedParameterToken("param", "foo"), NamedEndToken("pathParams")}}, + + // https://github.com/gebv/strparam/issues/7 + {[][]string{ + {"a", "/{foobar}"}, + {"b", "/b"}, + {"c", "/ba"}, + {"d", "/baz"}, + {"e", "/ba{foobar}"}, + }, "/baz", true, Tokens{StartToken, ConstToken("/baz"), NamedEndToken("d")}}, + {[][]string{ + {"a", "/{foobar}"}, + {"b", "/b"}, + {"c", "/ba"}, + // {"d", "/baz"}, + {"e", "/ba{foobar}"}, + }, "/baz", true, Tokens{StartToken, ConstToken("/ba"), ParsedParameterToken("foobar", "z"), NamedEndToken("e")}}, + {[][]string{ + {"a", "/{foobar}"}, + {"b", "/b"}, + {"c", "/ba"}, + // {"d", "/baz"}, + // {"e", "/ba{foobar}"}, + }, "/baz", true, Tokens{StartToken, ConstToken("/"), ParsedParameterToken("foobar", "baz"), NamedEndToken("a")}}, + {[][]string{ + // {"a", "/{foobar}"}, + {"b", "/b"}, + {"c", "/ba"}, + // {"d", "/baz"}, + // {"e", "/ba{foobar}"}, + }, "/baz", false, nil}, } for _, tt := range tests { t.Run(fmt.Sprintf("%q->%q", tt.namedPatterns, tt.in), func(t *testing.T) { @@ -271,3 +301,16 @@ func Test_PatternWithSeparator(t *testing.T) { t.Log(params) }) } + +func Test_nextEnd(t *testing.T) { + n := &node{} + assert.False(t, n.nextEnd()) + n = &node{Childs: []*node{{Token: ConstToken("!")}}} + assert.False(t, n.nextEnd()) + n = &node{Childs: []*node{{Token: SeparatorToken("a")}}} + assert.False(t, n.nextEnd()) + n = &node{Childs: []*node{{Token: EndToken}}} + assert.True(t, n.nextEnd()) + n = &node{Childs: []*node{{Token: NamedEndToken("abc")}}} + assert.True(t, n.nextEnd()) +}