github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gofrontend/libgo/go/old/regexp/all_test.go (about) 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. 4 5 package regexp 6 7 import ( 8 "strings" 9 "testing" 10 ) 11 12 var good_re = []string{ 13 ``, 14 `.`, 15 `^.$`, 16 `a`, 17 `a*`, 18 `a+`, 19 `a?`, 20 `a|b`, 21 `a*|b*`, 22 `(a*|b)(c*|d)`, 23 `[a-z]`, 24 `[a-abc-c\-\]\[]`, 25 `[a-z]+`, 26 `[]`, 27 `[abc]`, 28 `[^1234]`, 29 `[^\n]`, 30 `\!\\`, 31 } 32 33 type stringError struct { 34 re string 35 err error 36 } 37 38 var bad_re = []stringError{ 39 {`*`, ErrBareClosure}, 40 {`+`, ErrBareClosure}, 41 {`?`, ErrBareClosure}, 42 {`(abc`, ErrUnmatchedLpar}, 43 {`abc)`, ErrUnmatchedRpar}, 44 {`x[a-z`, ErrUnmatchedLbkt}, 45 {`abc]`, ErrUnmatchedRbkt}, 46 {`[z-a]`, ErrBadRange}, 47 {`abc\`, ErrExtraneousBackslash}, 48 {`a**`, ErrBadClosure}, 49 {`a*+`, ErrBadClosure}, 50 {`a??`, ErrBadClosure}, 51 {`\x`, ErrBadBackslash}, 52 } 53 54 func compileTest(t *testing.T, expr string, error error) *Regexp { 55 re, err := Compile(expr) 56 if err != error { 57 t.Error("compiling `", expr, "`; unexpected error: ", err.Error()) 58 } 59 return re 60 } 61 62 func TestGoodCompile(t *testing.T) { 63 for i := 0; i < len(good_re); i++ { 64 compileTest(t, good_re[i], nil) 65 } 66 } 67 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) 71 } 72 } 73 74 func matchTest(t *testing.T, test *FindTest) { 75 re := compileTest(t, test.pat, nil) 76 if re == nil { 77 return 78 } 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) 82 } 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) 87 } 88 } 89 90 func TestMatch(t *testing.T) { 91 for _, test := range findTests { 92 matchTest(t, &test) 93 } 94 } 95 96 func matchFunctionTest(t *testing.T, test *FindTest) { 97 m, err := MatchString(test.pat, test.text) 98 if err == nil { 99 return 100 } 101 if m != (len(test.matches) > 0) { 102 t.Errorf("Match failure on %s: %t should be %t", test, m, len(test.matches) > 0) 103 } 104 } 105 106 func TestMatchFunction(t *testing.T) { 107 for _, test := range findTests { 108 matchFunctionTest(t, &test) 109 } 110 } 111 112 type ReplaceTest struct { 113 pattern, replacement, input, output string 114 } 115 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"}, 122 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"}, 132 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"}, 137 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"}, 151 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", "", ""}, 164 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"}, 176 } 177 178 type ReplaceFuncTest struct { 179 pattern string 180 replacement func(string) string 181 input, output string 182 } 183 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"}, 188 } 189 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 196 } 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) 201 } 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) 207 } 208 } 209 } 210 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 217 } 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) 222 } 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) 228 } 229 } 230 } 231 232 type MetaTest struct { 233 pattern, output, literal string 234 isLiteral bool 235 } 236 237 var metaTests = []MetaTest{ 238 {``, ``, ``, true}, 239 {`foo`, `foo`, `foo`, true}, 240 {`foo\.\$`, `foo\\\.\\\$`, `foo.$`, true}, // has meta but no operator 241 {`foo.\$`, `foo\.\\\$`, `foo`, false}, // has escaped operators and real operators 242 {`!@#$%^&*()_+-=[{]}\|,<.>/?~`, `!@#\$%\^&\*\(\)_\+-=\[{\]}\\\|,<\.>/\?~`, `!@#`, false}, 243 } 244 245 func TestQuoteMeta(t *testing.T) { 246 for _, tc := range metaTests { 247 // Verify that QuoteMeta returns the expected string. 248 quoted := QuoteMeta(tc.pattern) 249 if quoted != tc.output { 250 t.Errorf("QuoteMeta(`%s`) = `%s`; want `%s`", 251 tc.pattern, quoted, tc.output) 252 continue 253 } 254 255 // Verify that the quoted string is in fact treated as expected 256 // by Compile -- i.e. that it matches the original, unquoted string. 257 if tc.pattern != "" { 258 re, err := Compile(quoted) 259 if err != nil { 260 t.Errorf("Unexpected error compiling QuoteMeta(`%s`): %v", tc.pattern, err) 261 continue 262 } 263 src := "abc" + tc.pattern + "def" 264 repl := "xyz" 265 replaced := re.ReplaceAllString(src, repl) 266 expected := "abcxyzdef" 267 if replaced != expected { 268 t.Errorf("QuoteMeta(`%s`).Replace(`%s`,`%s`) = `%s`; want `%s`", 269 tc.pattern, src, repl, replaced, expected) 270 } 271 } 272 } 273 } 274 275 func TestLiteralPrefix(t *testing.T) { 276 for _, tc := range metaTests { 277 // Literal method needs to scan the pattern. 278 re := MustCompile(tc.pattern) 279 str, complete := re.LiteralPrefix() 280 if complete != tc.isLiteral { 281 t.Errorf("LiteralPrefix(`%s`) = %t; want %t", tc.pattern, complete, tc.isLiteral) 282 } 283 if str != tc.literal { 284 t.Errorf("LiteralPrefix(`%s`) = `%s`; want `%s`", tc.pattern, str, tc.literal) 285 } 286 } 287 } 288 289 type numSubexpCase struct { 290 input string 291 expected int 292 } 293 294 var numSubexpCases = []numSubexpCase{ 295 {``, 0}, 296 {`.*`, 0}, 297 {`abba`, 0}, 298 {`ab(b)a`, 1}, 299 {`ab(.*)a`, 1}, 300 {`(.*)ab(.*)a`, 2}, 301 {`(.*)(ab)(.*)a`, 3}, 302 {`(.*)((a)b)(.*)a`, 4}, 303 {`(.*)(\(ab)(.*)a`, 3}, 304 {`(.*)(\(a\)b)(.*)a`, 3}, 305 } 306 307 func TestNumSubexp(t *testing.T) { 308 for _, c := range numSubexpCases { 309 re := MustCompile(c.input) 310 n := re.NumSubexp() 311 if n != c.expected { 312 t.Errorf("NumSubexp for %q returned %d, expected %d", c.input, n, c.expected) 313 } 314 } 315 } 316 317 func BenchmarkLiteral(b *testing.B) { 318 x := strings.Repeat("x", 50) + "y" 319 b.StopTimer() 320 re := MustCompile("y") 321 b.StartTimer() 322 for i := 0; i < b.N; i++ { 323 if !re.MatchString(x) { 324 b.Fatal("no match!") 325 } 326 } 327 } 328 329 func BenchmarkNotLiteral(b *testing.B) { 330 x := strings.Repeat("x", 50) + "y" 331 b.StopTimer() 332 re := MustCompile(".y") 333 b.StartTimer() 334 for i := 0; i < b.N; i++ { 335 if !re.MatchString(x) { 336 b.Fatal("no match!") 337 } 338 } 339 } 340 341 func BenchmarkMatchClass(b *testing.B) { 342 b.StopTimer() 343 x := strings.Repeat("xxxx", 20) + "w" 344 re := MustCompile("[abcdw]") 345 b.StartTimer() 346 for i := 0; i < b.N; i++ { 347 if !re.MatchString(x) { 348 b.Fatal("no match!") 349 } 350 } 351 } 352 353 func BenchmarkMatchClass_InRange(b *testing.B) { 354 b.StopTimer() 355 // 'b' is between 'a' and 'c', so the charclass 356 // range checking is no help here. 357 x := strings.Repeat("bbbb", 20) + "c" 358 re := MustCompile("[ac]") 359 b.StartTimer() 360 for i := 0; i < b.N; i++ { 361 if !re.MatchString(x) { 362 b.Fatal("no match!") 363 } 364 } 365 } 366 367 func BenchmarkReplaceAll(b *testing.B) { 368 x := "abcdefghijklmnopqrstuvwxyz" 369 b.StopTimer() 370 re := MustCompile("[cjrw]") 371 b.StartTimer() 372 for i := 0; i < b.N; i++ { 373 re.ReplaceAllString(x, "") 374 } 375 } 376 377 func BenchmarkAnchoredLiteralShortNonMatch(b *testing.B) { 378 b.StopTimer() 379 x := []byte("abcdefghijklmnopqrstuvwxyz") 380 re := MustCompile("^zbc(d|e)") 381 b.StartTimer() 382 for i := 0; i < b.N; i++ { 383 re.Match(x) 384 } 385 } 386 387 func BenchmarkAnchoredLiteralLongNonMatch(b *testing.B) { 388 b.StopTimer() 389 x := []byte("abcdefghijklmnopqrstuvwxyz") 390 for i := 0; i < 15; i++ { 391 x = append(x, x...) 392 } 393 re := MustCompile("^zbc(d|e)") 394 b.StartTimer() 395 for i := 0; i < b.N; i++ { 396 re.Match(x) 397 } 398 } 399 400 func BenchmarkAnchoredShortMatch(b *testing.B) { 401 b.StopTimer() 402 x := []byte("abcdefghijklmnopqrstuvwxyz") 403 re := MustCompile("^.bc(d|e)") 404 b.StartTimer() 405 for i := 0; i < b.N; i++ { 406 re.Match(x) 407 } 408 } 409 410 func BenchmarkAnchoredLongMatch(b *testing.B) { 411 b.StopTimer() 412 x := []byte("abcdefghijklmnopqrstuvwxyz") 413 for i := 0; i < 15; i++ { 414 x = append(x, x...) 415 } 416 re := MustCompile("^.bc(d|e)") 417 b.StartTimer() 418 for i := 0; i < b.N; i++ { 419 re.Match(x) 420 } 421 }