Skip to content

Instantly share code, notes, and snippets.

Created May 22, 2015 17:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/d8fd0bc11db45bed8c86 to your computer and use it in GitHub Desktop.
Save anonymous/d8fd0bc11db45bed8c86 to your computer and use it in GitHub Desktop.
package main
import (
"bytes"
"fmt"
"regexp"
"testing"
"unicode/utf8"
)
func generateString(lower, upper int) []byte {
buf := &bytes.Buffer{}
for i := lower; i <= upper; i++ {
fmt.Fprint(buf, i)
}
return buf.Bytes()
}
func generateRegexp(str []byte) string {
buf := &bytes.Buffer{}
fmt.Fprint(buf, "^")
build(buf, str)
return buf.String()
}
func build(buf *bytes.Buffer, str []byte) {
if len(str) == 0 {
fmt.Fprint(buf, ".+")
return
}
r, n := utf8.DecodeRune(str)
fmt.Fprintf(buf, "(?:(?:%c", r)
build(buf, str[n:])
fmt.Fprintf(buf, ")|[^%c]|$)", r)
}
type Test struct {
Pattern []byte
Match bool
}
func generateTests(lower, upper int) (tests []Test) {
str := generateString(lower, upper)
for i := lower; i <= upper; i++ {
for j := i + 1; j <= upper; j++ {
tests = append(tests, Test{
Pattern: str[i:j],
Match: !bytes.Equal(str[i:j], str),
})
}
}
return
}
var simpleTests = []Test{
{[]byte("ab"), true},
{[]byte(""), true},
{[]byte("4"), true},
{[]byte("0"), true},
{[]byte("02"), true},
{[]byte("11"), true},
{[]byte("0123"), true},
{[]byte("01234"), false},
{[]byte("012a4"), true},
{[]byte("012345"), true},
}
func TestRegexpNot(t *testing.T) {
str := generateString(0, 4)
t.Log("Regexp:", generateRegexp(str))
re, err := regexp.Compile(generateRegexp(str))
if err != nil {
t.Fatal("regexp.Compile:", err)
}
for _, test := range simpleTests {
if m := re.Match(test.Pattern); m != test.Match {
t.Errorf("Test %q: expected %v, got %v.", test.Pattern, test.Match, m)
}
}
}
func BenchmarkRegexpNot(b *testing.B) {
b.StopTimer()
lower, upper := 1, 500
regex := generateRegexp(generateString(lower, upper))
tests := generateTests(lower, upper)
re, err := regexp.Compile(regex)
if err != nil {
b.Fatal("regexp.Compile:", err)
}
b.StartTimer()
for i := 0; i < b.N; i++ {
for _, t := range tests {
if m := re.Match(t.Pattern); m != t.Match {
b.Errorf("Test %q: expected %v, got %v", t.Pattern, t.Match, m)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment