1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
13 // For each pattern/text pair, what is the expected output of each function?
14 // We can derive the textual results from the indexed results, the non-submatch
15 // results from the submatched results, the single results from the 'all' results,
16 // and the byte results from the string results. Therefore the table includes
17 // only the FindAllStringSubmatchIndex result.
18 type FindTest struct {
24 func (t FindTest) String() string {
25 return fmt.Sprintf("pat: %#q text: %#q", t.pat, t.text)
28 var findTests = []FindTest{
29 {``, ``, build(1, 0, 0)},
30 {`^abcdefg`, "abcdefg", build(1, 0, 7)},
31 {`a+`, "baaab", build(1, 1, 4)},
32 {"abcd..", "abcdef", build(1, 0, 6)},
33 {`a`, "a", build(1, 0, 1)},
35 {`b`, "abc", build(1, 1, 2)},
36 {`.`, "a", build(1, 0, 1)},
37 {`.*`, "abcdef", build(1, 0, 6)},
38 {`^`, "abcde", build(1, 0, 0)},
39 {`$`, "abcde", build(1, 5, 5)},
40 {`^abcd$`, "abcd", build(1, 0, 4)},
41 {`^bcd'`, "abcdef", nil},
42 {`^abcd$`, "abcde", nil},
43 {`a+`, "baaab", build(1, 1, 4)},
44 {`a*`, "baaab", build(3, 0, 0, 1, 4, 5, 5)},
45 {`[a-z]+`, "abcd", build(1, 0, 4)},
46 {`[^a-z]+`, "ab1234cd", build(1, 2, 6)},
47 {`[a\-\]z]+`, "az]-bcz", build(2, 0, 4, 6, 7)},
48 {`[^\n]+`, "abcd\n", build(1, 0, 4)},
49 {`[日本語]+`, "日本語日本語", build(1, 0, 18)},
50 {`日本語+`, "日本語", build(1, 0, 9)},
51 {`日本語+`, "日本語語語語", build(1, 0, 18)},
52 {`()`, "", build(1, 0, 0, 0, 0)},
53 {`(a)`, "a", build(1, 0, 1, 0, 1)},
54 {`(.)(.)`, "日a", build(1, 0, 4, 0, 3, 3, 4)},
55 {`(.*)`, "", build(1, 0, 0, 0, 0)},
56 {`(.*)`, "abcd", build(1, 0, 4, 0, 4)},
57 {`(..)(..)`, "abcd", build(1, 0, 4, 0, 2, 2, 4)},
58 {`(([^xyz]*)(d))`, "abcd", build(1, 0, 4, 0, 4, 0, 3, 3, 4)},
59 {`((a|b|c)*(d))`, "abcd", build(1, 0, 4, 0, 4, 2, 3, 3, 4)},
60 {`(((a|b|c)*)(d))`, "abcd", build(1, 0, 4, 0, 4, 0, 3, 2, 3, 3, 4)},
61 {`\a\f\n\r\t\v`, "\a\f\n\r\t\v", build(1, 0, 6)},
62 {`[\a\f\n\r\t\v]+`, "\a\f\n\r\t\v", build(1, 0, 6)},
64 {`a*(|(b))c*`, "aacc", build(1, 0, 4, 2, 2, -1, -1)},
65 {`(.*).*`, "ab", build(1, 0, 2, 0, 2)},
66 {`[.]`, ".", build(1, 0, 1)},
67 {`/$`, "/abc/", build(1, 4, 5)},
71 {`.`, "abc", build(3, 0, 1, 1, 2, 2, 3)},
72 {`(.)`, "abc", build(3, 0, 1, 0, 1, 1, 2, 1, 2, 2, 3, 2, 3)},
73 {`.(.)`, "abcd", build(2, 0, 2, 1, 2, 2, 4, 3, 4)},
74 {`ab*`, "abbaab", build(3, 0, 3, 3, 4, 4, 6)},
75 {`a(b*)`, "abbaab", build(3, 0, 3, 1, 3, 3, 4, 4, 4, 4, 6, 5, 6)},
78 {`ab$`, "cab", build(1, 1, 3)},
79 {`axxb$`, "axxcb", nil},
80 {`data`, "daXY data", build(1, 5, 9)},
81 {`da(.)a$`, "daXY data", build(1, 5, 9, 7, 8)},
82 {`zx+`, "zzx", build(1, 1, 3)},
84 // can backslash-escape any punctuation
85 {`\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\{\|\}\~`,
86 `!"#$%&'()*+,-./:;<=>?@[\]^_{|}~`, build(1, 0, 31)},
87 {`[\!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\:\;\<\=\>\?\@\[\\\]\^\_\{\|\}\~]+`,
88 `!"#$%&'()*+,-./:;<=>?@[\]^_{|}~`, build(1, 0, 31)},
89 {"\\`", "`", build(1, 0, 1)},
90 {"[\\`]+", "`", build(1, 0, 1)},
92 // long set of matches (longer than startSize)
95 "qwertyuiopasdfghjklzxcvbnm1234567890",
96 build(36, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
97 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20,
98 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30,
99 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36),
103 // build is a helper to construct a [][]int by extracting n sequences from x.
104 // This represents n matches with len(x)/n submatches each.
105 func build(n int, x ...int) [][]int {
106 ret := make([][]int, n)
107 runLength := len(x) / n
110 ret[i] = make([]int, runLength)
114 panic("invalid build entry")
120 // First the simple cases.
122 func TestFind(t *testing.T) {
123 for _, test := range findTests {
124 re := MustCompile(test.pat)
125 if re.String() != test.pat {
126 t.Errorf("String() = `%s`; should be `%s`", re.String(), test.pat)
128 result := re.Find([]byte(test.text))
130 case len(test.matches) == 0 && len(result) == 0:
132 case test.matches == nil && result != nil:
133 t.Errorf("expected no match; got one: %s", test)
134 case test.matches != nil && result == nil:
135 t.Errorf("expected match; got none: %s", test)
136 case test.matches != nil && result != nil:
137 expect := test.text[test.matches[0][0]:test.matches[0][1]]
138 if expect != string(result) {
139 t.Errorf("expected %q got %q: %s", expect, result, test)
145 func TestFindString(t *testing.T) {
146 for _, test := range findTests {
147 result := MustCompile(test.pat).FindString(test.text)
149 case len(test.matches) == 0 && len(result) == 0:
151 case test.matches == nil && result != "":
152 t.Errorf("expected no match; got one: %s", test)
153 case test.matches != nil && result == "":
154 // Tricky because an empty result has two meanings: no match or empty match.
155 if test.matches[0][0] != test.matches[0][1] {
156 t.Errorf("expected match; got none: %s", test)
158 case test.matches != nil && result != "":
159 expect := test.text[test.matches[0][0]:test.matches[0][1]]
160 if expect != result {
161 t.Errorf("expected %q got %q: %s", expect, result, test)
167 func testFindIndex(test *FindTest, result []int, t *testing.T) {
169 case len(test.matches) == 0 && len(result) == 0:
171 case test.matches == nil && result != nil:
172 t.Errorf("expected no match; got one: %s", test)
173 case test.matches != nil && result == nil:
174 t.Errorf("expected match; got none: %s", test)
175 case test.matches != nil && result != nil:
176 expect := test.matches[0]
177 if expect[0] != result[0] || expect[1] != result[1] {
178 t.Errorf("expected %v got %v: %s", expect, result, test)
183 func TestFindIndex(t *testing.T) {
184 for _, test := range findTests {
185 testFindIndex(&test, MustCompile(test.pat).FindIndex([]byte(test.text)), t)
189 func TestFindStringIndex(t *testing.T) {
190 for _, test := range findTests {
191 testFindIndex(&test, MustCompile(test.pat).FindStringIndex(test.text), t)
195 func TestFindReaderIndex(t *testing.T) {
196 for _, test := range findTests {
197 testFindIndex(&test, MustCompile(test.pat).FindReaderIndex(strings.NewReader(test.text)), t)
201 // Now come the simple All cases.
203 func TestFindAll(t *testing.T) {
204 for _, test := range findTests {
205 result := MustCompile(test.pat).FindAll([]byte(test.text), -1)
207 case test.matches == nil && result == nil:
209 case test.matches == nil && result != nil:
210 t.Errorf("expected no match; got one: %s", test)
211 case test.matches != nil && result == nil:
212 t.Fatalf("expected match; got none: %s", test)
213 case test.matches != nil && result != nil:
214 if len(test.matches) != len(result) {
215 t.Errorf("expected %d matches; got %d: %s", len(test.matches), len(result), test)
218 for k, e := range test.matches {
219 expect := test.text[e[0]:e[1]]
220 if expect != string(result[k]) {
221 t.Errorf("match %d: expected %q got %q: %s", k, expect, result[k], test)
228 func TestFindAllString(t *testing.T) {
229 for _, test := range findTests {
230 result := MustCompile(test.pat).FindAllString(test.text, -1)
232 case test.matches == nil && result == nil:
234 case test.matches == nil && result != nil:
235 t.Errorf("expected no match; got one: %s", test)
236 case test.matches != nil && result == nil:
237 t.Errorf("expected match; got none: %s", test)
238 case test.matches != nil && result != nil:
239 if len(test.matches) != len(result) {
240 t.Errorf("expected %d matches; got %d: %s", len(test.matches), len(result), test)
243 for k, e := range test.matches {
244 expect := test.text[e[0]:e[1]]
245 if expect != result[k] {
246 t.Errorf("expected %q got %q: %s", expect, result, test)
253 func testFindAllIndex(test *FindTest, result [][]int, t *testing.T) {
255 case test.matches == nil && result == nil:
257 case test.matches == nil && result != nil:
258 t.Errorf("expected no match; got one: %s", test)
259 case test.matches != nil && result == nil:
260 t.Errorf("expected match; got none: %s", test)
261 case test.matches != nil && result != nil:
262 if len(test.matches) != len(result) {
263 t.Errorf("expected %d matches; got %d: %s", len(test.matches), len(result), test)
266 for k, e := range test.matches {
267 if e[0] != result[k][0] || e[1] != result[k][1] {
268 t.Errorf("match %d: expected %v got %v: %s", k, e, result[k], test)
274 func TestFindAllIndex(t *testing.T) {
275 for _, test := range findTests {
276 testFindAllIndex(&test, MustCompile(test.pat).FindAllIndex([]byte(test.text), -1), t)
280 func TestFindAllStringIndex(t *testing.T) {
281 for _, test := range findTests {
282 testFindAllIndex(&test, MustCompile(test.pat).FindAllStringIndex(test.text, -1), t)
286 // Now come the Submatch cases.
288 func testSubmatchBytes(test *FindTest, n int, submatches []int, result [][]byte, t *testing.T) {
289 if len(submatches) != len(result)*2 {
290 t.Errorf("match %d: expected %d submatches; got %d: %s", n, len(submatches)/2, len(result), test)
293 for k := 0; k < len(submatches); k += 2 {
294 if submatches[k] == -1 {
295 if result[k/2] != nil {
296 t.Errorf("match %d: expected nil got %q: %s", n, result, test)
300 expect := test.text[submatches[k]:submatches[k+1]]
301 if expect != string(result[k/2]) {
302 t.Errorf("match %d: expected %q got %q: %s", n, expect, result, test)
308 func TestFindSubmatch(t *testing.T) {
309 for _, test := range findTests {
310 result := MustCompile(test.pat).FindSubmatch([]byte(test.text))
312 case test.matches == nil && result == nil:
314 case test.matches == nil && result != nil:
315 t.Errorf("expected no match; got one: %s", test)
316 case test.matches != nil && result == nil:
317 t.Errorf("expected match; got none: %s", test)
318 case test.matches != nil && result != nil:
319 testSubmatchBytes(&test, 0, test.matches[0], result, t)
324 func testSubmatchString(test *FindTest, n int, submatches []int, result []string, t *testing.T) {
325 if len(submatches) != len(result)*2 {
326 t.Errorf("match %d: expected %d submatches; got %d: %s", n, len(submatches)/2, len(result), test)
329 for k := 0; k < len(submatches); k += 2 {
330 if submatches[k] == -1 {
331 if result[k/2] != "" {
332 t.Errorf("match %d: expected nil got %q: %s", n, result, test)
336 expect := test.text[submatches[k]:submatches[k+1]]
337 if expect != result[k/2] {
338 t.Errorf("match %d: expected %q got %q: %s", n, expect, result, test)
344 func TestFindStringSubmatch(t *testing.T) {
345 for _, test := range findTests {
346 result := MustCompile(test.pat).FindStringSubmatch(test.text)
348 case test.matches == nil && result == nil:
350 case test.matches == nil && result != nil:
351 t.Errorf("expected no match; got one: %s", test)
352 case test.matches != nil && result == nil:
353 t.Errorf("expected match; got none: %s", test)
354 case test.matches != nil && result != nil:
355 testSubmatchString(&test, 0, test.matches[0], result, t)
360 func testSubmatchIndices(test *FindTest, n int, expect, result []int, t *testing.T) {
361 if len(expect) != len(result) {
362 t.Errorf("match %d: expected %d matches; got %d: %s", n, len(expect)/2, len(result)/2, test)
365 for k, e := range expect {
367 t.Errorf("match %d: submatch error: expected %v got %v: %s", n, expect, result, test)
372 func testFindSubmatchIndex(test *FindTest, result []int, t *testing.T) {
374 case test.matches == nil && result == nil:
376 case test.matches == nil && result != nil:
377 t.Errorf("expected no match; got one: %s", test)
378 case test.matches != nil && result == nil:
379 t.Errorf("expected match; got none: %s", test)
380 case test.matches != nil && result != nil:
381 testSubmatchIndices(test, 0, test.matches[0], result, t)
385 func TestFindSubmatchIndex(t *testing.T) {
386 for _, test := range findTests {
387 testFindSubmatchIndex(&test, MustCompile(test.pat).FindSubmatchIndex([]byte(test.text)), t)
391 func TestFindStringSubmatchIndex(t *testing.T) {
392 for _, test := range findTests {
393 testFindSubmatchIndex(&test, MustCompile(test.pat).FindStringSubmatchIndex(test.text), t)
397 func TestFindReaderSubmatchIndex(t *testing.T) {
398 for _, test := range findTests {
399 testFindSubmatchIndex(&test, MustCompile(test.pat).FindReaderSubmatchIndex(strings.NewReader(test.text)), t)
403 // Now come the monster AllSubmatch cases.
405 func TestFindAllSubmatch(t *testing.T) {
406 for _, test := range findTests {
407 result := MustCompile(test.pat).FindAllSubmatch([]byte(test.text), -1)
409 case test.matches == nil && result == nil:
411 case test.matches == nil && result != nil:
412 t.Errorf("expected no match; got one: %s", test)
413 case test.matches != nil && result == nil:
414 t.Errorf("expected match; got none: %s", test)
415 case len(test.matches) != len(result):
416 t.Errorf("expected %d matches; got %d: %s", len(test.matches), len(result), test)
417 case test.matches != nil && result != nil:
418 for k, match := range test.matches {
419 testSubmatchBytes(&test, k, match, result[k], t)
425 func TestFindAllStringSubmatch(t *testing.T) {
426 for _, test := range findTests {
427 result := MustCompile(test.pat).FindAllStringSubmatch(test.text, -1)
429 case test.matches == nil && result == nil:
431 case test.matches == nil && result != nil:
432 t.Errorf("expected no match; got one: %s", test)
433 case test.matches != nil && result == nil:
434 t.Errorf("expected match; got none: %s", test)
435 case len(test.matches) != len(result):
436 t.Errorf("expected %d matches; got %d: %s", len(test.matches), len(result), test)
437 case test.matches != nil && result != nil:
438 for k, match := range test.matches {
439 testSubmatchString(&test, k, match, result[k], t)
445 func testFindAllSubmatchIndex(test *FindTest, result [][]int, t *testing.T) {
447 case test.matches == nil && result == nil:
449 case test.matches == nil && result != nil:
450 t.Errorf("expected no match; got one: %s", test)
451 case test.matches != nil && result == nil:
452 t.Errorf("expected match; got none: %s", test)
453 case len(test.matches) != len(result):
454 t.Errorf("expected %d matches; got %d: %s", len(test.matches), len(result), test)
455 case test.matches != nil && result != nil:
456 for k, match := range test.matches {
457 testSubmatchIndices(test, k, match, result[k], t)
462 func TestFindAllSubmatchIndex(t *testing.T) {
463 for _, test := range findTests {
464 testFindAllSubmatchIndex(&test, MustCompile(test.pat).FindAllSubmatchIndex([]byte(test.text), -1), t)
468 func TestFindAllStringSubmatchIndex(t *testing.T) {
469 for _, test := range findTests {
470 testFindAllSubmatchIndex(&test, MustCompile(test.pat).FindAllStringSubmatchIndex(test.text, -1), t)