| // Copyright 2015 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. | 
 |  | 
 | package testing | 
 |  | 
 | import ( | 
 | 	"reflect" | 
 | 	"regexp" | 
 | 	"unicode" | 
 | ) | 
 |  | 
 | // Verify that our IsSpace agrees with unicode.IsSpace. | 
 | func TestIsSpace(t *T) { | 
 | 	n := 0 | 
 | 	for r := rune(0); r <= unicode.MaxRune; r++ { | 
 | 		if isSpace(r) != unicode.IsSpace(r) { | 
 | 			t.Errorf("IsSpace(%U)=%t incorrect", r, isSpace(r)) | 
 | 			n++ | 
 | 			if n > 10 { | 
 | 				return | 
 | 			} | 
 | 		} | 
 | 	} | 
 | } | 
 |  | 
 | func TestSplitRegexp(t *T) { | 
 | 	res := func(s ...string) []string { return s } | 
 | 	testCases := []struct { | 
 | 		pattern string | 
 | 		result  []string | 
 | 	}{ | 
 | 		// Correct patterns | 
 | 		// If a regexp pattern is correct, all split regexps need to be correct | 
 | 		// as well. | 
 | 		{"", res("")}, | 
 | 		{"/", res("", "")}, | 
 | 		{"//", res("", "", "")}, | 
 | 		{"A", res("A")}, | 
 | 		{"A/B", res("A", "B")}, | 
 | 		{"A/B/", res("A", "B", "")}, | 
 | 		{"/A/B/", res("", "A", "B", "")}, | 
 | 		{"[A]/(B)", res("[A]", "(B)")}, | 
 | 		{"[/]/[/]", res("[/]", "[/]")}, | 
 | 		{"[/]/[:/]", res("[/]", "[:/]")}, | 
 | 		{"/]", res("", "]")}, | 
 | 		{"]/", res("]", "")}, | 
 | 		{"]/[/]", res("]", "[/]")}, | 
 | 		{`([)/][(])`, res(`([)/][(])`)}, | 
 | 		{"[(]/[)]", res("[(]", "[)]")}, | 
 |  | 
 | 		// Faulty patterns | 
 | 		// Errors in original should produce at least one faulty regexp in results. | 
 | 		{")/", res(")/")}, | 
 | 		{")/(/)", res(")/(", ")")}, | 
 | 		{"a[/)b", res("a[/)b")}, | 
 | 		{"(/]", res("(/]")}, | 
 | 		{"(/", res("(/")}, | 
 | 		{"[/]/[/", res("[/]", "[/")}, | 
 | 		{`\p{/}`, res(`\p{`, "}")}, | 
 | 		{`\p/`, res(`\p`, "")}, | 
 | 		{`[[:/:]]`, res(`[[:/:]]`)}, | 
 | 	} | 
 | 	for _, tc := range testCases { | 
 | 		a := splitRegexp(tc.pattern) | 
 | 		if !reflect.DeepEqual(a, tc.result) { | 
 | 			t.Errorf("splitRegexp(%q) = %#v; want %#v", tc.pattern, a, tc.result) | 
 | 		} | 
 |  | 
 | 		// If there is any error in the pattern, one of the returned subpatterns | 
 | 		// needs to have an error as well. | 
 | 		if _, err := regexp.Compile(tc.pattern); err != nil { | 
 | 			ok := true | 
 | 			for _, re := range a { | 
 | 				if _, err := regexp.Compile(re); err != nil { | 
 | 					ok = false | 
 | 				} | 
 | 			} | 
 | 			if ok { | 
 | 				t.Errorf("%s: expected error in any of %q", tc.pattern, a) | 
 | 			} | 
 | 		} | 
 | 	} | 
 | } | 
 |  | 
 | func TestMatcher(t *T) { | 
 | 	testCases := []struct { | 
 | 		pattern     string | 
 | 		parent, sub string | 
 | 		ok          bool | 
 | 		partial     bool | 
 | 	}{ | 
 | 		// Behavior without subtests. | 
 | 		{"", "", "TestFoo", true, false}, | 
 | 		{"TestFoo", "", "TestFoo", true, false}, | 
 | 		{"TestFoo/", "", "TestFoo", true, true}, | 
 | 		{"TestFoo/bar/baz", "", "TestFoo", true, true}, | 
 | 		{"TestFoo", "", "TestBar", false, false}, | 
 | 		{"TestFoo/", "", "TestBar", false, false}, | 
 | 		{"TestFoo/bar/baz", "", "TestBar/bar/baz", false, false}, | 
 |  | 
 | 		// with subtests | 
 | 		{"", "TestFoo", "x", true, false}, | 
 | 		{"TestFoo", "TestFoo", "x", true, false}, | 
 | 		{"TestFoo/", "TestFoo", "x", true, false}, | 
 | 		{"TestFoo/bar/baz", "TestFoo", "bar", true, true}, | 
 | 		// Subtest with a '/' in its name still allows for copy and pasted names | 
 | 		// to match. | 
 | 		{"TestFoo/bar/baz", "TestFoo", "bar/baz", true, false}, | 
 | 		{"TestFoo/bar/baz", "TestFoo/bar", "baz", true, false}, | 
 | 		{"TestFoo/bar/baz", "TestFoo", "x", false, false}, | 
 | 		{"TestFoo", "TestBar", "x", false, false}, | 
 | 		{"TestFoo/", "TestBar", "x", false, false}, | 
 | 		{"TestFoo/bar/baz", "TestBar", "x/bar/baz", false, false}, | 
 |  | 
 | 		// subtests only | 
 | 		{"", "TestFoo", "x", true, false}, | 
 | 		{"/", "TestFoo", "x", true, false}, | 
 | 		{"./", "TestFoo", "x", true, false}, | 
 | 		{"./.", "TestFoo", "x", true, false}, | 
 | 		{"/bar/baz", "TestFoo", "bar", true, true}, | 
 | 		{"/bar/baz", "TestFoo", "bar/baz", true, false}, | 
 | 		{"//baz", "TestFoo", "bar/baz", true, false}, | 
 | 		{"//", "TestFoo", "bar/baz", true, false}, | 
 | 		{"/bar/baz", "TestFoo/bar", "baz", true, false}, | 
 | 		{"//foo", "TestFoo", "bar/baz", false, false}, | 
 | 		{"/bar/baz", "TestFoo", "x", false, false}, | 
 | 		{"/bar/baz", "TestBar", "x/bar/baz", false, false}, | 
 | 	} | 
 |  | 
 | 	for _, tc := range testCases { | 
 | 		m := newMatcher(regexp.MatchString, tc.pattern, "-test.run") | 
 |  | 
 | 		parent := &common{name: tc.parent} | 
 | 		if tc.parent != "" { | 
 | 			parent.level = 1 | 
 | 		} | 
 | 		if n, ok, partial := m.fullName(parent, tc.sub); ok != tc.ok || partial != tc.partial { | 
 | 			t.Errorf("for pattern %q, fullName(parent=%q, sub=%q) = %q, ok %v partial %v; want ok %v partial %v", | 
 | 				tc.pattern, tc.parent, tc.sub, n, ok, partial, tc.ok, tc.partial) | 
 | 		} | 
 | 	} | 
 | } | 
 |  | 
 | func TestNaming(t *T) { | 
 | 	m := newMatcher(regexp.MatchString, "", "") | 
 |  | 
 | 	parent := &common{name: "x", level: 1} // top-level test. | 
 |  | 
 | 	// Rig the matcher with some preloaded values. | 
 | 	m.subNames["x/b"] = 1000 | 
 |  | 
 | 	testCases := []struct { | 
 | 		name, want string | 
 | 	}{ | 
 | 		// Uniqueness | 
 | 		{"", "x/#00"}, | 
 | 		{"", "x/#01"}, | 
 |  | 
 | 		{"t", "x/t"}, | 
 | 		{"t", "x/t#01"}, | 
 | 		{"t", "x/t#02"}, | 
 |  | 
 | 		{"a#01", "x/a#01"}, // user has subtest with this name. | 
 | 		{"a", "x/a"},       // doesn't conflict with this name. | 
 | 		{"a", "x/a#01#01"}, // conflict, add disambiguating string. | 
 | 		{"a", "x/a#02"},    // This string is claimed now, so resume | 
 | 		{"a", "x/a#03"},    // with counting. | 
 | 		{"a#02", "x/a#02#01"}, | 
 |  | 
 | 		{"b", "x/b#1000"}, // rigged, see above | 
 | 		{"b", "x/b#1001"}, | 
 |  | 
 | 		// // Sanitizing | 
 | 		{"A:1 B:2", "x/A:1_B:2"}, | 
 | 		{"s\t\r\u00a0", "x/s___"}, | 
 | 		{"\x01", `x/\x01`}, | 
 | 		{"\U0010ffff", `x/\U0010ffff`}, | 
 | 	} | 
 |  | 
 | 	for i, tc := range testCases { | 
 | 		if got, _, _ := m.fullName(parent, tc.name); got != tc.want { | 
 | 			t.Errorf("%d:%s: got %q; want %q", i, tc.name, got, tc.want) | 
 | 		} | 
 | 	} | 
 | } |