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  }