Merge from mainline (167278:168000).
[official-gcc/graphite-test-results.git] / libgo / go / regexp / all_test.go
blobd5a0e7da6ad705872e13542a690e30b6bc274e77
1 // Copyright 2009 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.
5 package regexp
7 import (
8 "os"
9 "strings"
10 "testing"
13 var good_re = []string{
14 ``,
15 `.`,
16 `^.$`,
17 `a`,
18 `a*`,
19 `a+`,
20 `a?`,
21 `a|b`,
22 `a*|b*`,
23 `(a*|b)(c*|d)`,
24 `[a-z]`,
25 `[a-abc-c\-\]\[]`,
26 `[a-z]+`,
27 `[]`,
28 `[abc]`,
29 `[^1234]`,
30 `[^\n]`,
31 `\!\\`,
34 type stringError struct {
35 re string
36 err os.Error
39 var bad_re = []stringError{
40 {`*`, ErrBareClosure},
41 {`(abc`, ErrUnmatchedLpar},
42 {`abc)`, ErrUnmatchedRpar},
43 {`x[a-z`, ErrUnmatchedLbkt},
44 {`abc]`, ErrUnmatchedRbkt},
45 {`[z-a]`, ErrBadRange},
46 {`abc\`, ErrExtraneousBackslash},
47 {`a**`, ErrBadClosure},
48 {`a*+`, ErrBadClosure},
49 {`a??`, ErrBadClosure},
50 {`*`, ErrBareClosure},
51 {`\x`, ErrBadBackslash},
54 func compileTest(t *testing.T, expr string, error os.Error) *Regexp {
55 re, err := Compile(expr)
56 if err != error {
57 t.Error("compiling `", expr, "`; unexpected error: ", err.String())
59 return re
62 func TestGoodCompile(t *testing.T) {
63 for i := 0; i < len(good_re); i++ {
64 compileTest(t, good_re[i], nil)
68 func TestBadCompile(t *testing.T) {
69 for i := 0; i < len(bad_re); i++ {
70 compileTest(t, bad_re[i].re, bad_re[i].err)
74 func matchTest(t *testing.T, test *FindTest) {
75 re := compileTest(t, test.pat, nil)
76 if re == nil {
77 return
79 m := re.MatchString(test.text)
80 if m != (len(test.matches) > 0) {
81 t.Errorf("MatchString failure on %s: %t should be %t", test, m, len(test.matches) > 0)
83 // now try bytes
84 m = re.Match([]byte(test.text))
85 if m != (len(test.matches) > 0) {
86 t.Errorf("Match failure on %s: %t should be %t", test, m, len(test.matches) > 0)
90 func TestMatch(t *testing.T) {
91 for _, test := range findTests {
92 matchTest(t, &test)
96 func matchFunctionTest(t *testing.T, test *FindTest) {
97 m, err := MatchString(test.pat, test.text)
98 if err == nil {
99 return
101 if m != (len(test.matches) > 0) {
102 t.Errorf("Match failure on %s: %t should be %t", test, m, len(test.matches) > 0)
106 func TestMatchFunction(t *testing.T) {
107 for _, test := range findTests {
108 matchFunctionTest(t, &test)
112 type ReplaceTest struct {
113 pattern, replacement, input, output string
116 var replaceTests = []ReplaceTest{
117 // Test empty input and/or replacement, with pattern that matches the empty string.
118 {"", "", "", ""},
119 {"", "x", "", "x"},
120 {"", "", "abc", "abc"},
121 {"", "x", "abc", "xaxbxcx"},
123 // Test empty input and/or replacement, with pattern that does not match the empty string.
124 {"b", "", "", ""},
125 {"b", "x", "", ""},
126 {"b", "", "abc", "ac"},
127 {"b", "x", "abc", "axc"},
128 {"y", "", "", ""},
129 {"y", "x", "", ""},
130 {"y", "", "abc", "abc"},
131 {"y", "x", "abc", "abc"},
133 // Multibyte characters -- verify that we don't try to match in the middle
134 // of a character.
135 {"[a-c]*", "x", "\u65e5", "x\u65e5x"},
136 {"[^\u65e5]", "x", "abc\u65e5def", "xxx\u65e5xxx"},
138 // Start and end of a string.
139 {"^[a-c]*", "x", "abcdabc", "xdabc"},
140 {"[a-c]*$", "x", "abcdabc", "abcdx"},
141 {"^[a-c]*$", "x", "abcdabc", "abcdabc"},
142 {"^[a-c]*", "x", "abc", "x"},
143 {"[a-c]*$", "x", "abc", "x"},
144 {"^[a-c]*$", "x", "abc", "x"},
145 {"^[a-c]*", "x", "dabce", "xdabce"},
146 {"[a-c]*$", "x", "dabce", "dabcex"},
147 {"^[a-c]*$", "x", "dabce", "dabce"},
148 {"^[a-c]*", "x", "", "x"},
149 {"[a-c]*$", "x", "", "x"},
150 {"^[a-c]*$", "x", "", "x"},
152 {"^[a-c]+", "x", "abcdabc", "xdabc"},
153 {"[a-c]+$", "x", "abcdabc", "abcdx"},
154 {"^[a-c]+$", "x", "abcdabc", "abcdabc"},
155 {"^[a-c]+", "x", "abc", "x"},
156 {"[a-c]+$", "x", "abc", "x"},
157 {"^[a-c]+$", "x", "abc", "x"},
158 {"^[a-c]+", "x", "dabce", "dabce"},
159 {"[a-c]+$", "x", "dabce", "dabce"},
160 {"^[a-c]+$", "x", "dabce", "dabce"},
161 {"^[a-c]+", "x", "", ""},
162 {"[a-c]+$", "x", "", ""},
163 {"^[a-c]+$", "x", "", ""},
165 // Other cases.
166 {"abc", "def", "abcdefg", "defdefg"},
167 {"bc", "BC", "abcbcdcdedef", "aBCBCdcdedef"},
168 {"abc", "", "abcdabc", "d"},
169 {"x", "xXx", "xxxXxxx", "xXxxXxxXxXxXxxXxxXx"},
170 {"abc", "d", "", ""},
171 {"abc", "d", "abc", "d"},
172 {".+", "x", "abc", "x"},
173 {"[a-c]*", "x", "def", "xdxexfx"},
174 {"[a-c]+", "x", "abcbcdcdedef", "xdxdedef"},
175 {"[a-c]*", "x", "abcbcdcdedef", "xdxdxexdxexfx"},
178 type ReplaceFuncTest struct {
179 pattern string
180 replacement func(string) string
181 input, output string
184 var replaceFuncTests = []ReplaceFuncTest{
185 {"[a-c]", func(s string) string { return "x" + s + "y" }, "defabcdef", "defxayxbyxcydef"},
186 {"[a-c]+", func(s string) string { return "x" + s + "y" }, "defabcdef", "defxabcydef"},
187 {"[a-c]*", func(s string) string { return "x" + s + "y" }, "defabcdef", "xydxyexyfxabcydxyexyfxy"},
190 func TestReplaceAll(t *testing.T) {
191 for _, tc := range replaceTests {
192 re, err := Compile(tc.pattern)
193 if err != nil {
194 t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
195 continue
197 actual := re.ReplaceAllString(tc.input, tc.replacement)
198 if actual != tc.output {
199 t.Errorf("%q.Replace(%q,%q) = %q; want %q",
200 tc.pattern, tc.input, tc.replacement, actual, tc.output)
202 // now try bytes
203 actual = string(re.ReplaceAll([]byte(tc.input), []byte(tc.replacement)))
204 if actual != tc.output {
205 t.Errorf("%q.Replace(%q,%q) = %q; want %q",
206 tc.pattern, tc.input, tc.replacement, actual, tc.output)
211 func TestReplaceAllFunc(t *testing.T) {
212 for _, tc := range replaceFuncTests {
213 re, err := Compile(tc.pattern)
214 if err != nil {
215 t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
216 continue
218 actual := re.ReplaceAllStringFunc(tc.input, tc.replacement)
219 if actual != tc.output {
220 t.Errorf("%q.ReplaceFunc(%q,%q) = %q; want %q",
221 tc.pattern, tc.input, tc.replacement, actual, tc.output)
223 // now try bytes
224 actual = string(re.ReplaceAllFunc([]byte(tc.input), func(s []byte) []byte { return []byte(tc.replacement(string(s))) }))
225 if actual != tc.output {
226 t.Errorf("%q.ReplaceFunc(%q,%q) = %q; want %q",
227 tc.pattern, tc.input, tc.replacement, actual, tc.output)
232 type QuoteMetaTest struct {
233 pattern, output string
236 var quoteMetaTests = []QuoteMetaTest{
237 {``, ``},
238 {`foo`, `foo`},
239 {`!@#$%^&*()_+-=[{]}\|,<.>/?~`, `!@#\$%\^&\*\(\)_\+-=\[{\]}\\\|,<\.>/\?~`},
242 func TestQuoteMeta(t *testing.T) {
243 for _, tc := range quoteMetaTests {
244 // Verify that QuoteMeta returns the expected string.
245 quoted := QuoteMeta(tc.pattern)
246 if quoted != tc.output {
247 t.Errorf("QuoteMeta(`%s`) = `%s`; want `%s`",
248 tc.pattern, quoted, tc.output)
249 continue
252 // Verify that the quoted string is in fact treated as expected
253 // by Compile -- i.e. that it matches the original, unquoted string.
254 if tc.pattern != "" {
255 re, err := Compile(quoted)
256 if err != nil {
257 t.Errorf("Unexpected error compiling QuoteMeta(`%s`): %v", tc.pattern, err)
258 continue
260 src := "abc" + tc.pattern + "def"
261 repl := "xyz"
262 replaced := re.ReplaceAllString(src, repl)
263 expected := "abcxyzdef"
264 if replaced != expected {
265 t.Errorf("QuoteMeta(`%s`).Replace(`%s`,`%s`) = `%s`; want `%s`",
266 tc.pattern, src, repl, replaced, expected)
272 type numSubexpCase struct {
273 input string
274 expected int
277 var numSubexpCases = []numSubexpCase{
278 {``, 0},
279 {`.*`, 0},
280 {`abba`, 0},
281 {`ab(b)a`, 1},
282 {`ab(.*)a`, 1},
283 {`(.*)ab(.*)a`, 2},
284 {`(.*)(ab)(.*)a`, 3},
285 {`(.*)((a)b)(.*)a`, 4},
286 {`(.*)(\(ab)(.*)a`, 3},
287 {`(.*)(\(a\)b)(.*)a`, 3},
290 func TestNumSubexp(t *testing.T) {
291 for _, c := range numSubexpCases {
292 re := MustCompile(c.input)
293 n := re.NumSubexp()
294 if n != c.expected {
295 t.Errorf("NumSubexp for %q returned %d, expected %d", c.input, n, c.expected)
300 func BenchmarkLiteral(b *testing.B) {
301 x := strings.Repeat("x", 50)
302 b.StopTimer()
303 re := MustCompile(x)
304 b.StartTimer()
305 for i := 0; i < b.N; i++ {
306 if !re.MatchString(x) {
307 println("no match!")
308 break
313 func BenchmarkNotLiteral(b *testing.B) {
314 x := strings.Repeat("x", 49)
315 b.StopTimer()
316 re := MustCompile("^" + x)
317 b.StartTimer()
318 for i := 0; i < b.N; i++ {
319 if !re.MatchString(x) {
320 println("no match!")
321 break
326 func BenchmarkMatchClass(b *testing.B) {
327 b.StopTimer()
328 x := strings.Repeat("xxxx", 20) + "w"
329 re := MustCompile("[abcdw]")
330 b.StartTimer()
331 for i := 0; i < b.N; i++ {
332 if !re.MatchString(x) {
333 println("no match!")
334 break
339 func BenchmarkMatchClass_InRange(b *testing.B) {
340 b.StopTimer()
341 // 'b' is betwen 'a' and 'c', so the charclass
342 // range checking is no help here.
343 x := strings.Repeat("bbbb", 20) + "c"
344 re := MustCompile("[ac]")
345 b.StartTimer()
346 for i := 0; i < b.N; i++ {
347 if !re.MatchString(x) {
348 println("no match!")
349 break
354 func BenchmarkReplaceAll(b *testing.B) {
355 x := "abcdefghijklmnopqrstuvwxyz"
356 b.StopTimer()
357 re := MustCompile("[cjrw]")
358 b.StartTimer()
359 for i := 0; i < b.N; i++ {
360 re.ReplaceAllString(x, "")