Skip to content
Snippets Groups Projects
all_test.go 3.46 KiB
Newer Older
  • Learn to ignore specific revisions
  • // Copyright 2009 The Go Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style
    // license that can be found in the LICENSE file.
    
    
    Rob Pike's avatar
    Rob Pike committed
    package regexp
    
    
    import (
    	"os";
    	"regexp";
    
    Rob Pike's avatar
    Rob Pike committed
    	"testing";
    
    Rob Pike's avatar
    Rob Pike committed
    var good_re = []string{
    
    Rob Pike's avatar
    Rob Pike committed
    	``,
    	`.`,
    	`^.$`,
    	`a`,
    	`a*`,
    	`a+`,
    	`a?`,
    	`a|b`,
    	`a*|b*`,
    	`(a*|b)(c*|d)`,
    	`[a-z]`,
    	`[a-abc-c\-\]\[]`,
    	`[a-z]+`,
    	`[]`,
    	`[abc]`,
    	`[^1234]`,
    
    Rob Pike's avatar
    Rob Pike committed
    }
    
    // TODO: nice to do this with a map but we don't have an iterator
    type StringError struct {
    	re	string;
    	err	*os.Error;
    }
    var bad_re = []StringError{
    
    	StringError{ `*`,	 	regexp.ErrBareClosure },
    
    Rob Pike's avatar
    Rob Pike committed
    	StringError{ `(abc`,	regexp.ErrUnmatchedLpar },	
    	StringError{ `abc)`,	regexp.ErrUnmatchedRpar },	
    	StringError{ `x[a-z`,	regexp.ErrUnmatchedLbkt },	
    	StringError{ `abc]`,	regexp.ErrUnmatchedRbkt },	
    	StringError{ `[z-a]`,	regexp.ErrBadRange },	
    	StringError{ `abc\`,	regexp.ErrExtraneousBackslash },	
    	StringError{ `a**`,	regexp.ErrBadClosure },	
    	StringError{ `a*+`,	regexp.ErrBadClosure },	
    	StringError{ `a??`,	regexp.ErrBadClosure },	
    	StringError{ `*`,	 	regexp.ErrBareClosure },	
    
    Rob Pike's avatar
    Rob Pike committed
    	StringError{ `\x`,	regexp.ErrBadBackslash },
    
    Rob Pike's avatar
    Rob Pike committed
    }
    
    
    Russ Cox's avatar
    Russ Cox committed
    type Vec []int;
    
    Rob Pike's avatar
    Rob Pike committed
    
    type Tester struct {
    	re	string;
    	text	string;
    	match	Vec;
    }
    
    var matches = []Tester {
    
    Russ Cox's avatar
    Russ Cox committed
    	Tester{ ``,	"",	Vec{0,0} },
    	Tester{ `a`,	"a",	Vec{0,1} },
    	Tester{ `b`,	"abc",	Vec{1,2} },
    	Tester{ `.`,	"a",	Vec{0,1} },
    	Tester{ `.*`,	"abcdef",	Vec{0,6} },
    	Tester{ `^abcd$`,	"abcd",	Vec{0,4} },
    	Tester{ `^bcd'`,	"abcdef",	Vec{} },
    	Tester{ `^abcd$`,	"abcde",	Vec{} },
    	Tester{ `a+`,	"baaab",	Vec{1,4} },
    	Tester{ `a*`,	"baaab",	Vec{0,0} },
    	Tester{ `[a-z]+`,	"abcd",	Vec{0,4} },
    	Tester{ `[^a-z]+`,	"ab1234cd",	Vec{2,6} },
    	Tester{ `[a\-\]z]+`,	"az]-bcz",	Vec{0,4} },
    	Tester{ `[日本語]+`,	"日本語日本語",	Vec{0,18} },
    	Tester{ `()`,	"",	Vec{0,0, 0,0} },
    	Tester{ `(a)`,	"a",	Vec{0,1, 0,1} },
    	Tester{ `(.)(.)`,	"日a",	Vec{0,4, 0,3, 3,4} },
    	Tester{ `(.*)`,	"",	Vec{0,0, 0,0} },
    	Tester{ `(.*)`,	"abcd",	Vec{0,4, 0,4} },
    	Tester{ `(..)(..)`,	"abcd",	Vec{0,4, 0,2, 2,4} },
    	Tester{ `(([^xyz]*)(d))`,	"abcd",	Vec{0,4, 0,4, 0,3, 3,4} },
    	Tester{ `((a|b|c)*(d))`,	"abcd",	Vec{0,4, 0,4, 2,3, 3,4} },
    	Tester{ `(((a|b|c)*)(d))`,	"abcd",	Vec{0,4, 0,4, 0,3, 2,3, 3,4} },
    	Tester{ `a*(|(b))c*`,	"aacc",	Vec{0,4, 2,2, -1,-1} },
    
    Rob Pike's avatar
    Rob Pike committed
    }
    
    
    Rob Pike's avatar
    Rob Pike committed
    func CompileTest(t *testing.T, expr string, error *os.Error) regexp.Regexp {
    
    Rob Pike's avatar
    Rob Pike committed
    	re, err := regexp.Compile(expr);
    	if err != error {
    
    Rob Pike's avatar
    Rob Pike committed
    		t.Error("compiling `", expr, "`; unexpected error: ", err.String());
    
    Rob Pike's avatar
    Rob Pike committed
    	}
    	return re
    }
    
    
    Russ Cox's avatar
    Russ Cox committed
    func PrintVec(t *testing.T, m [] int) {
    	l := len(m);
    
    Rob Pike's avatar
    Rob Pike committed
    	if l == 0 {
    
    Rob Pike's avatar
    Rob Pike committed
    		t.Log("\t<no match>");
    
    Rob Pike's avatar
    Rob Pike committed
    	} else {
    
    Russ Cox's avatar
    Russ Cox committed
    		for i := 0; i < l; i = i+2 {
    
    Rob Pike's avatar
    Rob Pike committed
    			t.Log("\t", m[i], ",", m[i+1])
    
    Rob Pike's avatar
    Rob Pike committed
    		}
    
    Russ Cox's avatar
    Russ Cox committed
    func Equal(m1, m2 []int) bool {
    	l := len(m1);
    	if l != len(m2) {
    
    Rob Pike's avatar
    Rob Pike committed
    		return false
    	}
    	for i := 0; i < l; i++ {
    		if m1[i] != m2[i] {
    			return false
    		}
    	}
    	return true
    }
    
    
    Russ Cox's avatar
    Russ Cox committed
    func MatchTest(t *testing.T, expr string, str string, match []int) {
    
    Rob Pike's avatar
    Rob Pike committed
    	re := CompileTest(t, expr, nil);
    	if re == nil {
    		return
    	}
    
    Rob Pike's avatar
    Rob Pike committed
    	m := re.Execute(str);
    	if !Equal(m, match) {
    
    Rob Pike's avatar
    Rob Pike committed
    		t.Error("failure on `", expr, "` matching `", str, "`:");
    		PrintVec(t, m);
    		t.Log("should be:");
    		PrintVec(t, match);
    
    Rob Pike's avatar
    Rob Pike committed
    export func TestGoodCompile(t *testing.T) {
    
    Rob Pike's avatar
    Rob Pike committed
    	for i := 0; i < len(good_re); i++ {
    
    Rob Pike's avatar
    Rob Pike committed
    		CompileTest(t, good_re[i], nil);
    
    Rob Pike's avatar
    Rob Pike committed
    	}
    
    Rob Pike's avatar
    Rob Pike committed
    }
    
    export func TestBadCompile(t *testing.T) {
    
    Rob Pike's avatar
    Rob Pike committed
    	for i := 0; i < len(bad_re); i++ {
    
    Rob Pike's avatar
    Rob Pike committed
    		CompileTest(t, bad_re[i].re, bad_re[i].err)
    
    Rob Pike's avatar
    Rob Pike committed
    	}
    
    Rob Pike's avatar
    Rob Pike committed
    }
    
    export func TestMatch(t *testing.T) {
    
    Rob Pike's avatar
    Rob Pike committed
    	for i := 0; i < len(matches); i++ {
    
    Rob Pike's avatar
    Rob Pike committed
    		test := &matches[i];
    
    Russ Cox's avatar
    Russ Cox committed
    		MatchTest(t, test.re, test.text, test.match)