Home | History | Annotate | Download | only in testing
      1 // Copyright 2015 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 testing
      6 
      7 import (
      8 	"reflect"
      9 	"regexp"
     10 	"unicode"
     11 )
     12 
     13 // Verify that our IsSpace agrees with unicode.IsSpace.
     14 func TestIsSpace(t *T) {
     15 	n := 0
     16 	for r := rune(0); r <= unicode.MaxRune; r++ {
     17 		if isSpace(r) != unicode.IsSpace(r) {
     18 			t.Errorf("IsSpace(%U)=%t incorrect", r, isSpace(r))
     19 			n++
     20 			if n > 10 {
     21 				return
     22 			}
     23 		}
     24 	}
     25 }
     26 
     27 func TestSplitRegexp(t *T) {
     28 	res := func(s ...string) []string { return s }
     29 	testCases := []struct {
     30 		pattern string
     31 		result  []string
     32 	}{
     33 		// Correct patterns
     34 		// If a regexp pattern is correct, all split regexps need to be correct
     35 		// as well.
     36 		{"", res("")},
     37 		{"/", res("", "")},
     38 		{"//", res("", "", "")},
     39 		{"A", res("A")},
     40 		{"A/B", res("A", "B")},
     41 		{"A/B/", res("A", "B", "")},
     42 		{"/A/B/", res("", "A", "B", "")},
     43 		{"[A]/(B)", res("[A]", "(B)")},
     44 		{"[/]/[/]", res("[/]", "[/]")},
     45 		{"[/]/[:/]", res("[/]", "[:/]")},
     46 		{"/]", res("", "]")},
     47 		{"]/", res("]", "")},
     48 		{"]/[/]", res("]", "[/]")},
     49 		{`([)/][(])`, res(`([)/][(])`)},
     50 		{"[(]/[)]", res("[(]", "[)]")},
     51 
     52 		// Faulty patterns
     53 		// Errors in original should produce at least one faulty regexp in results.
     54 		{")/", res(")/")},
     55 		{")/(/)", res(")/(", ")")},
     56 		{"a[/)b", res("a[/)b")},
     57 		{"(/]", res("(/]")},
     58 		{"(/", res("(/")},
     59 		{"[/]/[/", res("[/]", "[/")},
     60 		{`\p{/}`, res(`\p{`, "}")},
     61 		{`\p/`, res(`\p`, "")},
     62 		{`[[:/:]]`, res(`[[:/:]]`)},
     63 	}
     64 	for _, tc := range testCases {
     65 		a := splitRegexp(tc.pattern)
     66 		if !reflect.DeepEqual(a, tc.result) {
     67 			t.Errorf("splitRegexp(%q) = %#v; want %#v", tc.pattern, a, tc.result)
     68 		}
     69 
     70 		// If there is any error in the pattern, one of the returned subpatterns
     71 		// needs to have an error as well.
     72 		if _, err := regexp.Compile(tc.pattern); err != nil {
     73 			ok := true
     74 			for _, re := range a {
     75 				if _, err := regexp.Compile(re); err != nil {
     76 					ok = false
     77 				}
     78 			}
     79 			if ok {
     80 				t.Errorf("%s: expected error in any of %q", tc.pattern, a)
     81 			}
     82 		}
     83 	}
     84 }
     85 
     86 func TestMatcher(t *T) {
     87 	testCases := []struct {
     88 		pattern     string
     89 		parent, sub string
     90 		ok          bool
     91 	}{
     92 		// Behavior without subtests.
     93 		{"", "", "TestFoo", true},
     94 		{"TestFoo", "", "TestFoo", true},
     95 		{"TestFoo/", "", "TestFoo", true},
     96 		{"TestFoo/bar/baz", "", "TestFoo", true},
     97 		{"TestFoo", "", "TestBar", false},
     98 		{"TestFoo/", "", "TestBar", false},
     99 		{"TestFoo/bar/baz", "", "TestBar/bar/baz", false},
    100 
    101 		// with subtests
    102 		{"", "TestFoo", "x", true},
    103 		{"TestFoo", "TestFoo", "x", true},
    104 		{"TestFoo/", "TestFoo", "x", true},
    105 		{"TestFoo/bar/baz", "TestFoo", "bar", true},
    106 		// Subtest with a '/' in its name still allows for copy and pasted names
    107 		// to match.
    108 		{"TestFoo/bar/baz", "TestFoo", "bar/baz", true},
    109 		{"TestFoo/bar/baz", "TestFoo/bar", "baz", true},
    110 		{"TestFoo/bar/baz", "TestFoo", "x", false},
    111 		{"TestFoo", "TestBar", "x", false},
    112 		{"TestFoo/", "TestBar", "x", false},
    113 		{"TestFoo/bar/baz", "TestBar", "x/bar/baz", false},
    114 
    115 		// subtests only
    116 		{"", "TestFoo", "x", true},
    117 		{"/", "TestFoo", "x", true},
    118 		{"./", "TestFoo", "x", true},
    119 		{"./.", "TestFoo", "x", true},
    120 		{"/bar/baz", "TestFoo", "bar", true},
    121 		{"/bar/baz", "TestFoo", "bar/baz", true},
    122 		{"//baz", "TestFoo", "bar/baz", true},
    123 		{"//", "TestFoo", "bar/baz", true},
    124 		{"/bar/baz", "TestFoo/bar", "baz", true},
    125 		{"//foo", "TestFoo", "bar/baz", false},
    126 		{"/bar/baz", "TestFoo", "x", false},
    127 		{"/bar/baz", "TestBar", "x/bar/baz", false},
    128 	}
    129 
    130 	for _, tc := range testCases {
    131 		m := newMatcher(regexp.MatchString, tc.pattern, "-test.run")
    132 
    133 		parent := &common{name: tc.parent}
    134 		if tc.parent != "" {
    135 			parent.level = 1
    136 		}
    137 		if n, ok := m.fullName(parent, tc.sub); ok != tc.ok {
    138 			t.Errorf("for pattern %q, fullName(parent=%q, sub=%q) = %q, ok %v; want ok %v",
    139 				tc.pattern, tc.parent, tc.sub, n, ok, tc.ok)
    140 		}
    141 	}
    142 }
    143 
    144 func TestNaming(t *T) {
    145 	m := newMatcher(regexp.MatchString, "", "")
    146 
    147 	parent := &common{name: "x", level: 1} // top-level test.
    148 
    149 	// Rig the matcher with some preloaded values.
    150 	m.subNames["x/b"] = 1000
    151 
    152 	testCases := []struct {
    153 		name, want string
    154 	}{
    155 		// Uniqueness
    156 		{"", "x/#00"},
    157 		{"", "x/#01"},
    158 
    159 		{"t", "x/t"},
    160 		{"t", "x/t#01"},
    161 		{"t", "x/t#02"},
    162 
    163 		{"a#01", "x/a#01"}, // user has subtest with this name.
    164 		{"a", "x/a"},       // doesn't conflict with this name.
    165 		{"a", "x/a#01#01"}, // conflict, add disambiguating string.
    166 		{"a", "x/a#02"},    // This string is claimed now, so resume
    167 		{"a", "x/a#03"},    // with counting.
    168 		{"a#02", "x/a#02#01"},
    169 
    170 		{"b", "x/b#1000"}, // rigged, see above
    171 		{"b", "x/b#1001"},
    172 
    173 		// // Sanitizing
    174 		{"A:1 B:2", "x/A:1_B:2"},
    175 		{"s\t\r\u00a0", "x/s___"},
    176 		{"\x01", `x/\x01`},
    177 		{"\U0010ffff", `x/\U0010ffff`},
    178 	}
    179 
    180 	for i, tc := range testCases {
    181 		if got, _ := m.fullName(parent, tc.name); got != tc.want {
    182 			t.Errorf("%d:%s: got %q; want %q", i, tc.name, got, tc.want)
    183 		}
    184 	}
    185 }
    186