1 package httprule
2
3 import (
4 "flag"
5 "fmt"
6 "reflect"
7 "testing"
8
9 "github.com/golang/glog"
10 )
11
12 func TestTokenize(t *testing.T) {
13 for _, spec := range []struct {
14 src string
15 tokens []string
16 }{
17 {
18 src: "",
19 tokens: []string{eof},
20 },
21 {
22 src: "v1",
23 tokens: []string{"v1", eof},
24 },
25 {
26 src: "v1/b",
27 tokens: []string{"v1", "/", "b", eof},
28 },
29 {
30 src: "v1/endpoint/*",
31 tokens: []string{"v1", "/", "endpoint", "/", "*", eof},
32 },
33 {
34 src: "v1/endpoint/**",
35 tokens: []string{"v1", "/", "endpoint", "/", "**", eof},
36 },
37 {
38 src: "v1/b/{bucket_name=*}",
39 tokens: []string{
40 "v1", "/",
41 "b", "/",
42 "{", "bucket_name", "=", "*", "}",
43 eof,
44 },
45 },
46 {
47 src: "v1/b/{bucket_name=buckets/*}",
48 tokens: []string{
49 "v1", "/",
50 "b", "/",
51 "{", "bucket_name", "=", "buckets", "/", "*", "}",
52 eof,
53 },
54 },
55 {
56 src: "v1/b/{bucket_name=buckets/*}/o",
57 tokens: []string{
58 "v1", "/",
59 "b", "/",
60 "{", "bucket_name", "=", "buckets", "/", "*", "}", "/",
61 "o",
62 eof,
63 },
64 },
65 {
66 src: "v1/b/{bucket_name=buckets/*}/o/{name}",
67 tokens: []string{
68 "v1", "/",
69 "b", "/",
70 "{", "bucket_name", "=", "buckets", "/", "*", "}", "/",
71 "o", "/", "{", "name", "}",
72 eof,
73 },
74 },
75 {
76 src: "v1/a=b&c=d;e=f:g/endpoint.rdf",
77 tokens: []string{
78 "v1", "/",
79 "a=b&c=d;e=f:g", "/",
80 "endpoint.rdf",
81 eof,
82 },
83 },
84 } {
85 tokens, verb := tokenize(spec.src)
86 if got, want := tokens, spec.tokens; !reflect.DeepEqual(got, want) {
87 t.Errorf("tokenize(%q) = %q, _; want %q, _", spec.src, got, want)
88 }
89 if got, want := verb, ""; got != want {
90 t.Errorf("tokenize(%q) = _, %q; want _, %q", spec.src, got, want)
91 }
92
93 src := fmt.Sprintf("%s:%s", spec.src, "LOCK")
94 tokens, verb = tokenize(src)
95 if got, want := tokens, spec.tokens; !reflect.DeepEqual(got, want) {
96 t.Errorf("tokenize(%q) = %q, _; want %q, _", src, got, want)
97 }
98 if got, want := verb, "LOCK"; got != want {
99 t.Errorf("tokenize(%q) = _, %q; want _, %q", src, got, want)
100 }
101 }
102 }
103
104 func TestParseSegments(t *testing.T) {
105 flag.Set("v", "3")
106 for _, spec := range []struct {
107 tokens []string
108 want []segment
109 }{
110 {
111 tokens: []string{"v1", eof},
112 want: []segment{
113 literal("v1"),
114 },
115 },
116 {
117 tokens: []string{"/", eof},
118 want: []segment{
119 wildcard{},
120 },
121 },
122 {
123 tokens: []string{"-._~!$&'()*+,;=:@", eof},
124 want: []segment{
125 literal("-._~!$&'()*+,;=:@"),
126 },
127 },
128 {
129 tokens: []string{"%e7%ac%ac%e4%b8%80%e7%89%88", eof},
130 want: []segment{
131 literal("%e7%ac%ac%e4%b8%80%e7%89%88"),
132 },
133 },
134 {
135 tokens: []string{"v1", "/", "*", eof},
136 want: []segment{
137 literal("v1"),
138 wildcard{},
139 },
140 },
141 {
142 tokens: []string{"v1", "/", "**", eof},
143 want: []segment{
144 literal("v1"),
145 deepWildcard{},
146 },
147 },
148 {
149 tokens: []string{"{", "name", "}", eof},
150 want: []segment{
151 variable{
152 path: "name",
153 segments: []segment{
154 wildcard{},
155 },
156 },
157 },
158 },
159 {
160 tokens: []string{"{", "name", "=", "*", "}", eof},
161 want: []segment{
162 variable{
163 path: "name",
164 segments: []segment{
165 wildcard{},
166 },
167 },
168 },
169 },
170 {
171 tokens: []string{"{", "field", ".", "nested", ".", "nested2", "=", "*", "}", eof},
172 want: []segment{
173 variable{
174 path: "field.nested.nested2",
175 segments: []segment{
176 wildcard{},
177 },
178 },
179 },
180 },
181 {
182 tokens: []string{"{", "name", "=", "a", "/", "b", "/", "*", "}", eof},
183 want: []segment{
184 variable{
185 path: "name",
186 segments: []segment{
187 literal("a"),
188 literal("b"),
189 wildcard{},
190 },
191 },
192 },
193 },
194 {
195 tokens: []string{
196 "v1", "/",
197 "{",
198 "name", ".", "nested", ".", "nested2",
199 "=",
200 "a", "/", "b", "/", "*",
201 "}", "/",
202 "o", "/",
203 "{",
204 "another_name",
205 "=",
206 "a", "/", "b", "/", "*", "/", "c",
207 "}", "/",
208 "**",
209 eof},
210 want: []segment{
211 literal("v1"),
212 variable{
213 path: "name.nested.nested2",
214 segments: []segment{
215 literal("a"),
216 literal("b"),
217 wildcard{},
218 },
219 },
220 literal("o"),
221 variable{
222 path: "another_name",
223 segments: []segment{
224 literal("a"),
225 literal("b"),
226 wildcard{},
227 literal("c"),
228 },
229 },
230 deepWildcard{},
231 },
232 },
233 } {
234 p := parser{tokens: spec.tokens}
235 segs, err := p.topLevelSegments()
236 if err != nil {
237 t.Errorf("parser{%q}.segments() failed with %v; want success", spec.tokens, err)
238 continue
239 }
240 if got, want := segs, spec.want; !reflect.DeepEqual(got, want) {
241 t.Errorf("parser{%q}.segments() = %#v; want %#v", spec.tokens, got, want)
242 }
243 if got := p.tokens; len(got) > 0 {
244 t.Errorf("p.tokens = %q; want []; spec.tokens=%q", got, spec.tokens)
245 }
246 }
247 }
248
249 func TestParseSegmentsWithErrors(t *testing.T) {
250 flag.Set("v", "3")
251 for _, spec := range []struct {
252 tokens []string
253 }{
254 {
255
256 tokens: []string{"//", eof},
257 },
258 {
259
260 tokens: []string{"a?b", eof},
261 },
262 {
263
264 tokens: []string{"%", eof},
265 },
266 {
267
268 tokens: []string{"%2", eof},
269 },
270 {
271
272 tokens: []string{"a%2z", eof},
273 },
274 {
275
276 tokens: []string{eof},
277 },
278 {
279
280 tokens: []string{"{", "name", eof},
281 },
282 {
283
284 tokens: []string{"{", "name", "=", eof},
285 },
286 {
287
288 tokens: []string{"{", "name", "=", "*", eof},
289 },
290 {
291
292 tokens: []string{"{", "name", ".", "}", eof},
293 },
294 {
295
296 tokens: []string{"{", "name", ".", ".", "nested", "}", eof},
297 },
298 {
299
300 tokens: []string{"{", "field-name", "}", eof},
301 },
302 {
303
304 tokens: []string{"v1", "endpoint", eof},
305 },
306 {
307
308 tokens: []string{"v1", "{", "name", "}", eof},
309 },
310 } {
311 p := parser{tokens: spec.tokens}
312 segs, err := p.topLevelSegments()
313 if err == nil {
314 t.Errorf("parser{%q}.segments() succeeded; want InvalidTemplateError; accepted %#v", spec.tokens, segs)
315 continue
316 }
317 glog.V(1).Info(err)
318 }
319 }
320
View as plain text