...
Run Format

Source file src/pkg/regexp/all_test.go

     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		"reflect"
     9		"strings"
    10		"testing"
    11	)
    12	
    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		`[abc]`,
    28		`[^1234]`,
    29		`[^\n]`,
    30		`\!\\`,
    31	}
    32	
    33	type stringError struct {
    34		re  string
    35		err string
    36	}
    37	
    38	var bad_re = []stringError{
    39		{`*`, "missing argument to repetition operator: `*`"},
    40		{`+`, "missing argument to repetition operator: `+`"},
    41		{`?`, "missing argument to repetition operator: `?`"},
    42		{`(abc`, "missing closing ): `(abc`"},
    43		{`abc)`, "unexpected ): `abc)`"},
    44		{`x[a-z`, "missing closing ]: `[a-z`"},
    45		{`[z-a]`, "invalid character class range: `z-a`"},
    46		{`abc\`, "trailing backslash at end of expression"},
    47		{`a**`, "invalid nested repetition operator: `**`"},
    48		{`a*+`, "invalid nested repetition operator: `*+`"},
    49		{`\x`, "invalid escape sequence: `\\x`"},
    50	}
    51	
    52	func compileTest(t *testing.T, expr string, error string) *Regexp {
    53		re, err := Compile(expr)
    54		if error == "" && err != nil {
    55			t.Error("compiling `", expr, "`; unexpected error: ", err.Error())
    56		}
    57		if error != "" && err == nil {
    58			t.Error("compiling `", expr, "`; missing error")
    59		} else if error != "" && !strings.Contains(err.Error(), error) {
    60			t.Error("compiling `", expr, "`; wrong error: ", err.Error(), "; want ", error)
    61		}
    62		return re
    63	}
    64	
    65	func TestGoodCompile(t *testing.T) {
    66		for i := 0; i < len(good_re); i++ {
    67			compileTest(t, good_re[i], "")
    68		}
    69	}
    70	
    71	func TestBadCompile(t *testing.T) {
    72		for i := 0; i < len(bad_re); i++ {
    73			compileTest(t, bad_re[i].re, bad_re[i].err)
    74		}
    75	}
    76	
    77	func matchTest(t *testing.T, test *FindTest) {
    78		re := compileTest(t, test.pat, "")
    79		if re == nil {
    80			return
    81		}
    82		m := re.MatchString(test.text)
    83		if m != (len(test.matches) > 0) {
    84			t.Errorf("MatchString failure on %s: %t should be %t", test, m, len(test.matches) > 0)
    85		}
    86		// now try bytes
    87		m = re.Match([]byte(test.text))
    88		if m != (len(test.matches) > 0) {
    89			t.Errorf("Match failure on %s: %t should be %t", test, m, len(test.matches) > 0)
    90		}
    91	}
    92	
    93	func TestMatch(t *testing.T) {
    94		for _, test := range findTests {
    95			matchTest(t, &test)
    96		}
    97	}
    98	
    99	func matchFunctionTest(t *testing.T, test *FindTest) {
   100		m, err := MatchString(test.pat, test.text)
   101		if err == nil {
   102			return
   103		}
   104		if m != (len(test.matches) > 0) {
   105			t.Errorf("Match failure on %s: %t should be %t", test, m, len(test.matches) > 0)
   106		}
   107	}
   108	
   109	func TestMatchFunction(t *testing.T) {
   110		for _, test := range findTests {
   111			matchFunctionTest(t, &test)
   112		}
   113	}
   114	
   115	type ReplaceTest struct {
   116		pattern, replacement, input, output string
   117	}
   118	
   119	var replaceTests = []ReplaceTest{
   120		// Test empty input and/or replacement, with pattern that matches the empty string.
   121		{"", "", "", ""},
   122		{"", "x", "", "x"},
   123		{"", "", "abc", "abc"},
   124		{"", "x", "abc", "xaxbxcx"},
   125	
   126		// Test empty input and/or replacement, with pattern that does not match the empty string.
   127		{"b", "", "", ""},
   128		{"b", "x", "", ""},
   129		{"b", "", "abc", "ac"},
   130		{"b", "x", "abc", "axc"},
   131		{"y", "", "", ""},
   132		{"y", "x", "", ""},
   133		{"y", "", "abc", "abc"},
   134		{"y", "x", "abc", "abc"},
   135	
   136		// Multibyte characters -- verify that we don't try to match in the middle
   137		// of a character.
   138		{"[a-c]*", "x", "\u65e5", "x\u65e5x"},
   139		{"[^\u65e5]", "x", "abc\u65e5def", "xxx\u65e5xxx"},
   140	
   141		// Start and end of a string.
   142		{"^[a-c]*", "x", "abcdabc", "xdabc"},
   143		{"[a-c]*$", "x", "abcdabc", "abcdx"},
   144		{"^[a-c]*$", "x", "abcdabc", "abcdabc"},
   145		{"^[a-c]*", "x", "abc", "x"},
   146		{"[a-c]*$", "x", "abc", "x"},
   147		{"^[a-c]*$", "x", "abc", "x"},
   148		{"^[a-c]*", "x", "dabce", "xdabce"},
   149		{"[a-c]*$", "x", "dabce", "dabcex"},
   150		{"^[a-c]*$", "x", "dabce", "dabce"},
   151		{"^[a-c]*", "x", "", "x"},
   152		{"[a-c]*$", "x", "", "x"},
   153		{"^[a-c]*$", "x", "", "x"},
   154	
   155		{"^[a-c]+", "x", "abcdabc", "xdabc"},
   156		{"[a-c]+$", "x", "abcdabc", "abcdx"},
   157		{"^[a-c]+$", "x", "abcdabc", "abcdabc"},
   158		{"^[a-c]+", "x", "abc", "x"},
   159		{"[a-c]+$", "x", "abc", "x"},
   160		{"^[a-c]+$", "x", "abc", "x"},
   161		{"^[a-c]+", "x", "dabce", "dabce"},
   162		{"[a-c]+$", "x", "dabce", "dabce"},
   163		{"^[a-c]+$", "x", "dabce", "dabce"},
   164		{"^[a-c]+", "x", "", ""},
   165		{"[a-c]+$", "x", "", ""},
   166		{"^[a-c]+$", "x", "", ""},
   167	
   168		// Other cases.
   169		{"abc", "def", "abcdefg", "defdefg"},
   170		{"bc", "BC", "abcbcdcdedef", "aBCBCdcdedef"},
   171		{"abc", "", "abcdabc", "d"},
   172		{"x", "xXx", "xxxXxxx", "xXxxXxxXxXxXxxXxxXx"},
   173		{"abc", "d", "", ""},
   174		{"abc", "d", "abc", "d"},
   175		{".+", "x", "abc", "x"},
   176		{"[a-c]*", "x", "def", "xdxexfx"},
   177		{"[a-c]+", "x", "abcbcdcdedef", "xdxdedef"},
   178		{"[a-c]*", "x", "abcbcdcdedef", "xdxdxexdxexfx"},
   179	
   180		// Substitutions
   181		{"a+", "($0)", "banana", "b(a)n(a)n(a)"},
   182		{"a+", "(${0})", "banana", "b(a)n(a)n(a)"},
   183		{"a+", "(${0})$0", "banana", "b(a)an(a)an(a)a"},
   184		{"a+", "(${0})$0", "banana", "b(a)an(a)an(a)a"},
   185		{"hello, (.+)", "goodbye, ${1}", "hello, world", "goodbye, world"},
   186		{"hello, (.+)", "goodbye, $1x", "hello, world", "goodbye, "},
   187		{"hello, (.+)", "goodbye, ${1}x", "hello, world", "goodbye, worldx"},
   188		{"hello, (.+)", "<$0><$1><$2><$3>", "hello, world", "<hello, world><world><><>"},
   189		{"hello, (?P<noun>.+)", "goodbye, $noun!", "hello, world", "goodbye, world!"},
   190		{"hello, (?P<noun>.+)", "goodbye, ${noun}", "hello, world", "goodbye, world"},
   191		{"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "hi", "hihihi"},
   192		{"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "bye", "byebyebye"},
   193		{"(?P<x>hi)|(?P<x>bye)", "$xyz", "hi", ""},
   194		{"(?P<x>hi)|(?P<x>bye)", "${x}yz", "hi", "hiyz"},
   195		{"(?P<x>hi)|(?P<x>bye)", "hello $$x", "hi", "hello $x"},
   196		{"a+", "${oops", "aaa", "${oops"},
   197		{"a+", "$$", "aaa", "$"},
   198		{"a+", "$", "aaa", "$"},
   199	
   200		// Substitution when subexpression isn't found
   201		{"(x)?", "$1", "123", "123"},
   202		{"abc", "$1", "123", "123"},
   203	}
   204	
   205	var replaceLiteralTests = []ReplaceTest{
   206		// Substitutions
   207		{"a+", "($0)", "banana", "b($0)n($0)n($0)"},
   208		{"a+", "(${0})", "banana", "b(${0})n(${0})n(${0})"},
   209		{"a+", "(${0})$0", "banana", "b(${0})$0n(${0})$0n(${0})$0"},
   210		{"a+", "(${0})$0", "banana", "b(${0})$0n(${0})$0n(${0})$0"},
   211		{"hello, (.+)", "goodbye, ${1}", "hello, world", "goodbye, ${1}"},
   212		{"hello, (?P<noun>.+)", "goodbye, $noun!", "hello, world", "goodbye, $noun!"},
   213		{"hello, (?P<noun>.+)", "goodbye, ${noun}", "hello, world", "goodbye, ${noun}"},
   214		{"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "hi", "$x$x$x"},
   215		{"(?P<x>hi)|(?P<x>bye)", "$x$x$x", "bye", "$x$x$x"},
   216		{"(?P<x>hi)|(?P<x>bye)", "$xyz", "hi", "$xyz"},
   217		{"(?P<x>hi)|(?P<x>bye)", "${x}yz", "hi", "${x}yz"},
   218		{"(?P<x>hi)|(?P<x>bye)", "hello $$x", "hi", "hello $$x"},
   219		{"a+", "${oops", "aaa", "${oops"},
   220		{"a+", "$$", "aaa", "$$"},
   221		{"a+", "$", "aaa", "$"},
   222	}
   223	
   224	type ReplaceFuncTest struct {
   225		pattern       string
   226		replacement   func(string) string
   227		input, output string
   228	}
   229	
   230	var replaceFuncTests = []ReplaceFuncTest{
   231		{"[a-c]", func(s string) string { return "x" + s + "y" }, "defabcdef", "defxayxbyxcydef"},
   232		{"[a-c]+", func(s string) string { return "x" + s + "y" }, "defabcdef", "defxabcydef"},
   233		{"[a-c]*", func(s string) string { return "x" + s + "y" }, "defabcdef", "xydxyexyfxabcydxyexyfxy"},
   234	}
   235	
   236	func TestReplaceAll(t *testing.T) {
   237		for _, tc := range replaceTests {
   238			re, err := Compile(tc.pattern)
   239			if err != nil {
   240				t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
   241				continue
   242			}
   243			actual := re.ReplaceAllString(tc.input, tc.replacement)
   244			if actual != tc.output {
   245				t.Errorf("%q.ReplaceAllString(%q,%q) = %q; want %q",
   246					tc.pattern, tc.input, tc.replacement, actual, tc.output)
   247			}
   248			// now try bytes
   249			actual = string(re.ReplaceAll([]byte(tc.input), []byte(tc.replacement)))
   250			if actual != tc.output {
   251				t.Errorf("%q.ReplaceAll(%q,%q) = %q; want %q",
   252					tc.pattern, tc.input, tc.replacement, actual, tc.output)
   253			}
   254		}
   255	}
   256	
   257	func TestReplaceAllLiteral(t *testing.T) {
   258		// Run ReplaceAll tests that do not have $ expansions.
   259		for _, tc := range replaceTests {
   260			if strings.Contains(tc.replacement, "$") {
   261				continue
   262			}
   263			re, err := Compile(tc.pattern)
   264			if err != nil {
   265				t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
   266				continue
   267			}
   268			actual := re.ReplaceAllLiteralString(tc.input, tc.replacement)
   269			if actual != tc.output {
   270				t.Errorf("%q.ReplaceAllLiteralString(%q,%q) = %q; want %q",
   271					tc.pattern, tc.input, tc.replacement, actual, tc.output)
   272			}
   273			// now try bytes
   274			actual = string(re.ReplaceAllLiteral([]byte(tc.input), []byte(tc.replacement)))
   275			if actual != tc.output {
   276				t.Errorf("%q.ReplaceAllLiteral(%q,%q) = %q; want %q",
   277					tc.pattern, tc.input, tc.replacement, actual, tc.output)
   278			}
   279		}
   280	
   281		// Run literal-specific tests.
   282		for _, tc := range replaceLiteralTests {
   283			re, err := Compile(tc.pattern)
   284			if err != nil {
   285				t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
   286				continue
   287			}
   288			actual := re.ReplaceAllLiteralString(tc.input, tc.replacement)
   289			if actual != tc.output {
   290				t.Errorf("%q.ReplaceAllLiteralString(%q,%q) = %q; want %q",
   291					tc.pattern, tc.input, tc.replacement, actual, tc.output)
   292			}
   293			// now try bytes
   294			actual = string(re.ReplaceAllLiteral([]byte(tc.input), []byte(tc.replacement)))
   295			if actual != tc.output {
   296				t.Errorf("%q.ReplaceAllLiteral(%q,%q) = %q; want %q",
   297					tc.pattern, tc.input, tc.replacement, actual, tc.output)
   298			}
   299		}
   300	}
   301	
   302	func TestReplaceAllFunc(t *testing.T) {
   303		for _, tc := range replaceFuncTests {
   304			re, err := Compile(tc.pattern)
   305			if err != nil {
   306				t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
   307				continue
   308			}
   309			actual := re.ReplaceAllStringFunc(tc.input, tc.replacement)
   310			if actual != tc.output {
   311				t.Errorf("%q.ReplaceFunc(%q,fn) = %q; want %q",
   312					tc.pattern, tc.input, actual, tc.output)
   313			}
   314			// now try bytes
   315			actual = string(re.ReplaceAllFunc([]byte(tc.input), func(s []byte) []byte { return []byte(tc.replacement(string(s))) }))
   316			if actual != tc.output {
   317				t.Errorf("%q.ReplaceFunc(%q,fn) = %q; want %q",
   318					tc.pattern, tc.input, actual, tc.output)
   319			}
   320		}
   321	}
   322	
   323	type MetaTest struct {
   324		pattern, output, literal string
   325		isLiteral                bool
   326	}
   327	
   328	var metaTests = []MetaTest{
   329		{``, ``, ``, true},
   330		{`foo`, `foo`, `foo`, true},
   331		{`foo\.\$`, `foo\\\.\\\$`, `foo.$`, true}, // has meta but no operator
   332		{`foo.\$`, `foo\.\\\$`, `foo`, false},     // has escaped operators and real operators
   333		{`!@#$%^&*()_+-=[{]}\|,<.>/?~`, `!@#\$%\^&\*\(\)_\+-=\[\{\]\}\\\|,<\.>/\?~`, `!@#`, false},
   334	}
   335	
   336	func TestQuoteMeta(t *testing.T) {
   337		for _, tc := range metaTests {
   338			// Verify that QuoteMeta returns the expected string.
   339			quoted := QuoteMeta(tc.pattern)
   340			if quoted != tc.output {
   341				t.Errorf("QuoteMeta(`%s`) = `%s`; want `%s`",
   342					tc.pattern, quoted, tc.output)
   343				continue
   344			}
   345	
   346			// Verify that the quoted string is in fact treated as expected
   347			// by Compile -- i.e. that it matches the original, unquoted string.
   348			if tc.pattern != "" {
   349				re, err := Compile(quoted)
   350				if err != nil {
   351					t.Errorf("Unexpected error compiling QuoteMeta(`%s`): %v", tc.pattern, err)
   352					continue
   353				}
   354				src := "abc" + tc.pattern + "def"
   355				repl := "xyz"
   356				replaced := re.ReplaceAllString(src, repl)
   357				expected := "abcxyzdef"
   358				if replaced != expected {
   359					t.Errorf("QuoteMeta(`%s`).Replace(`%s`,`%s`) = `%s`; want `%s`",
   360						tc.pattern, src, repl, replaced, expected)
   361				}
   362			}
   363		}
   364	}
   365	
   366	func TestLiteralPrefix(t *testing.T) {
   367		for _, tc := range metaTests {
   368			// Literal method needs to scan the pattern.
   369			re := MustCompile(tc.pattern)
   370			str, complete := re.LiteralPrefix()
   371			if complete != tc.isLiteral {
   372				t.Errorf("LiteralPrefix(`%s`) = %t; want %t", tc.pattern, complete, tc.isLiteral)
   373			}
   374			if str != tc.literal {
   375				t.Errorf("LiteralPrefix(`%s`) = `%s`; want `%s`", tc.pattern, str, tc.literal)
   376			}
   377		}
   378	}
   379	
   380	type subexpCase struct {
   381		input string
   382		num   int
   383		names []string
   384	}
   385	
   386	var subexpCases = []subexpCase{
   387		{``, 0, nil},
   388		{`.*`, 0, nil},
   389		{`abba`, 0, nil},
   390		{`ab(b)a`, 1, []string{"", ""}},
   391		{`ab(.*)a`, 1, []string{"", ""}},
   392		{`(.*)ab(.*)a`, 2, []string{"", "", ""}},
   393		{`(.*)(ab)(.*)a`, 3, []string{"", "", "", ""}},
   394		{`(.*)((a)b)(.*)a`, 4, []string{"", "", "", "", ""}},
   395		{`(.*)(\(ab)(.*)a`, 3, []string{"", "", "", ""}},
   396		{`(.*)(\(a\)b)(.*)a`, 3, []string{"", "", "", ""}},
   397		{`(?P<foo>.*)(?P<bar>(a)b)(?P<foo>.*)a`, 4, []string{"", "foo", "bar", "", "foo"}},
   398	}
   399	
   400	func TestSubexp(t *testing.T) {
   401		for _, c := range subexpCases {
   402			re := MustCompile(c.input)
   403			n := re.NumSubexp()
   404			if n != c.num {
   405				t.Errorf("%q: NumSubexp = %d, want %d", c.input, n, c.num)
   406				continue
   407			}
   408			names := re.SubexpNames()
   409			if len(names) != 1+n {
   410				t.Errorf("%q: len(SubexpNames) = %d, want %d", c.input, len(names), n)
   411				continue
   412			}
   413			if c.names != nil {
   414				for i := 0; i < 1+n; i++ {
   415					if names[i] != c.names[i] {
   416						t.Errorf("%q: SubexpNames[%d] = %q, want %q", c.input, i, names[i], c.names[i])
   417					}
   418				}
   419			}
   420		}
   421	}
   422	
   423	var splitTests = []struct {
   424		s   string
   425		r   string
   426		n   int
   427		out []string
   428	}{
   429		{"foo:and:bar", ":", -1, []string{"foo", "and", "bar"}},
   430		{"foo:and:bar", ":", 1, []string{"foo:and:bar"}},
   431		{"foo:and:bar", ":", 2, []string{"foo", "and:bar"}},
   432		{"foo:and:bar", "foo", -1, []string{"", ":and:bar"}},
   433		{"foo:and:bar", "bar", -1, []string{"foo:and:", ""}},
   434		{"foo:and:bar", "baz", -1, []string{"foo:and:bar"}},
   435		{"baabaab", "a", -1, []string{"b", "", "b", "", "b"}},
   436		{"baabaab", "a*", -1, []string{"b", "b", "b"}},
   437		{"baabaab", "ba*", -1, []string{"", "", "", ""}},
   438		{"foobar", "f*b*", -1, []string{"", "o", "o", "a", "r"}},
   439		{"foobar", "f+.*b+", -1, []string{"", "ar"}},
   440		{"foobooboar", "o{2}", -1, []string{"f", "b", "boar"}},
   441		{"a,b,c,d,e,f", ",", 3, []string{"a", "b", "c,d,e,f"}},
   442		{"a,b,c,d,e,f", ",", 0, nil},
   443		{",", ",", -1, []string{"", ""}},
   444		{",,,", ",", -1, []string{"", "", "", ""}},
   445		{"", ",", -1, []string{""}},
   446		{"", ".*", -1, []string{""}},
   447		{"", ".+", -1, []string{""}},
   448		{"", "", -1, []string{}},
   449		{"foobar", "", -1, []string{"f", "o", "o", "b", "a", "r"}},
   450		{"abaabaccadaaae", "a*", 5, []string{"", "b", "b", "c", "cadaaae"}},
   451		{":x:y:z:", ":", -1, []string{"", "x", "y", "z", ""}},
   452	}
   453	
   454	func TestSplit(t *testing.T) {
   455		for i, test := range splitTests {
   456			re, err := Compile(test.r)
   457			if err != nil {
   458				t.Errorf("#%d: %q: compile error: %s", i, test.r, err.Error())
   459				continue
   460			}
   461	
   462			split := re.Split(test.s, test.n)
   463			if !reflect.DeepEqual(split, test.out) {
   464				t.Errorf("#%d: %q: got %q; want %q", i, test.r, split, test.out)
   465			}
   466	
   467			if QuoteMeta(test.r) == test.r {
   468				strsplit := strings.SplitN(test.s, test.r, test.n)
   469				if !reflect.DeepEqual(split, strsplit) {
   470					t.Errorf("#%d: Split(%q, %q, %d): regexp vs strings mismatch\nregexp=%q\nstrings=%q", i, test.s, test.r, test.n, split, strsplit)
   471				}
   472			}
   473		}
   474	}
   475	
   476	// This ran out of stack before issue 7608 was fixed.
   477	func TestOnePassCutoff(t *testing.T) {
   478		MustCompile(`^(?:x{1,1000}){1,1000}$`)
   479	}
   480	
   481	func BenchmarkLiteral(b *testing.B) {
   482		x := strings.Repeat("x", 50) + "y"
   483		b.StopTimer()
   484		re := MustCompile("y")
   485		b.StartTimer()
   486		for i := 0; i < b.N; i++ {
   487			if !re.MatchString(x) {
   488				b.Fatalf("no match!")
   489			}
   490		}
   491	}
   492	
   493	func BenchmarkNotLiteral(b *testing.B) {
   494		x := strings.Repeat("x", 50) + "y"
   495		b.StopTimer()
   496		re := MustCompile(".y")
   497		b.StartTimer()
   498		for i := 0; i < b.N; i++ {
   499			if !re.MatchString(x) {
   500				b.Fatalf("no match!")
   501			}
   502		}
   503	}
   504	
   505	func BenchmarkMatchClass(b *testing.B) {
   506		b.StopTimer()
   507		x := strings.Repeat("xxxx", 20) + "w"
   508		re := MustCompile("[abcdw]")
   509		b.StartTimer()
   510		for i := 0; i < b.N; i++ {
   511			if !re.MatchString(x) {
   512				b.Fatalf("no match!")
   513			}
   514		}
   515	}
   516	
   517	func BenchmarkMatchClass_InRange(b *testing.B) {
   518		b.StopTimer()
   519		// 'b' is between 'a' and 'c', so the charclass
   520		// range checking is no help here.
   521		x := strings.Repeat("bbbb", 20) + "c"
   522		re := MustCompile("[ac]")
   523		b.StartTimer()
   524		for i := 0; i < b.N; i++ {
   525			if !re.MatchString(x) {
   526				b.Fatalf("no match!")
   527			}
   528		}
   529	}
   530	
   531	func BenchmarkReplaceAll(b *testing.B) {
   532		x := "abcdefghijklmnopqrstuvwxyz"
   533		b.StopTimer()
   534		re := MustCompile("[cjrw]")
   535		b.StartTimer()
   536		for i := 0; i < b.N; i++ {
   537			re.ReplaceAllString(x, "")
   538		}
   539	}
   540	
   541	func BenchmarkAnchoredLiteralShortNonMatch(b *testing.B) {
   542		b.StopTimer()
   543		x := []byte("abcdefghijklmnopqrstuvwxyz")
   544		re := MustCompile("^zbc(d|e)")
   545		b.StartTimer()
   546		for i := 0; i < b.N; i++ {
   547			re.Match(x)
   548		}
   549	}
   550	
   551	func BenchmarkAnchoredLiteralLongNonMatch(b *testing.B) {
   552		b.StopTimer()
   553		x := []byte("abcdefghijklmnopqrstuvwxyz")
   554		for i := 0; i < 15; i++ {
   555			x = append(x, x...)
   556		}
   557		re := MustCompile("^zbc(d|e)")
   558		b.StartTimer()
   559		for i := 0; i < b.N; i++ {
   560			re.Match(x)
   561		}
   562	}
   563	
   564	func BenchmarkAnchoredShortMatch(b *testing.B) {
   565		b.StopTimer()
   566		x := []byte("abcdefghijklmnopqrstuvwxyz")
   567		re := MustCompile("^.bc(d|e)")
   568		b.StartTimer()
   569		for i := 0; i < b.N; i++ {
   570			re.Match(x)
   571		}
   572	}
   573	
   574	func BenchmarkAnchoredLongMatch(b *testing.B) {
   575		b.StopTimer()
   576		x := []byte("abcdefghijklmnopqrstuvwxyz")
   577		for i := 0; i < 15; i++ {
   578			x = append(x, x...)
   579		}
   580		re := MustCompile("^.bc(d|e)")
   581		b.StartTimer()
   582		for i := 0; i < b.N; i++ {
   583			re.Match(x)
   584		}
   585	}
   586	
   587	func BenchmarkOnePassShortA(b *testing.B) {
   588		b.StopTimer()
   589		x := []byte("abcddddddeeeededd")
   590		re := MustCompile("^.bc(d|e)*$")
   591		b.StartTimer()
   592		for i := 0; i < b.N; i++ {
   593			re.Match(x)
   594		}
   595	}
   596	
   597	func BenchmarkNotOnePassShortA(b *testing.B) {
   598		b.StopTimer()
   599		x := []byte("abcddddddeeeededd")
   600		re := MustCompile(".bc(d|e)*$")
   601		b.StartTimer()
   602		for i := 0; i < b.N; i++ {
   603			re.Match(x)
   604		}
   605	}
   606	
   607	func BenchmarkOnePassShortB(b *testing.B) {
   608		b.StopTimer()
   609		x := []byte("abcddddddeeeededd")
   610		re := MustCompile("^.bc(?:d|e)*$")
   611		b.StartTimer()
   612		for i := 0; i < b.N; i++ {
   613			re.Match(x)
   614		}
   615	}
   616	
   617	func BenchmarkNotOnePassShortB(b *testing.B) {
   618		b.StopTimer()
   619		x := []byte("abcddddddeeeededd")
   620		re := MustCompile(".bc(?:d|e)*$")
   621		b.StartTimer()
   622		for i := 0; i < b.N; i++ {
   623			re.Match(x)
   624		}
   625	}
   626	
   627	func BenchmarkOnePassLongPrefix(b *testing.B) {
   628		b.StopTimer()
   629		x := []byte("abcdefghijklmnopqrstuvwxyz")
   630		re := MustCompile("^abcdefghijklmnopqrstuvwxyz.*$")
   631		b.StartTimer()
   632		for i := 0; i < b.N; i++ {
   633			re.Match(x)
   634		}
   635	}
   636	
   637	func BenchmarkOnePassLongNotPrefix(b *testing.B) {
   638		b.StopTimer()
   639		x := []byte("abcdefghijklmnopqrstuvwxyz")
   640		re := MustCompile("^.bcdefghijklmnopqrstuvwxyz.*$")
   641		b.StartTimer()
   642		for i := 0; i < b.N; i++ {
   643			re.Match(x)
   644		}
   645	}
   646	

View as plain text