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 		partial     bool
     92 	}{
     93 		// Behavior without subtests.
     94 		{"", "", "TestFoo", true, false},
     95 		{"TestFoo", "", "TestFoo", true, false},
     96 		{"TestFoo/", "", "TestFoo", true, true},
     97 		{"TestFoo/bar/baz", "", "TestFoo", true, true},
     98 		{"TestFoo", "", "TestBar", false, false},
     99 		{"TestFoo/", "", "TestBar", false, false},
    100 		{"TestFoo/bar/baz", "", "TestBar/bar/baz", false, false},
    101 
    102 		// with subtests
    103 		{"", "TestFoo", "x", true, false},
    104 		{"TestFoo", "TestFoo", "x", true, false},
    105 		{"TestFoo/", "TestFoo", "x", true, false},
    106 		{"TestFoo/bar/baz", "TestFoo", "bar", true, true},
    107 		// Subtest with a '/' in its name still allows for copy and pasted names
    108 		// to match.
    109 		{"TestFoo/bar/baz", "TestFoo", "bar/baz", true, false},
    110 		{"TestFoo/bar/baz", "TestFoo/bar", "baz", true, false},
    111 		{"TestFoo/bar/baz", "TestFoo", "x", false, false},
    112 		{"TestFoo", "TestBar", "x", false, false},
    113 		{"TestFoo/", "TestBar", "x", false, false},
    114 		{"TestFoo/bar/baz", "TestBar", "x/bar/baz", false, false},
    115 
    116 		// subtests only
    117 		{"", "TestFoo", "x", true, false},
    118 		{"/", "TestFoo", "x", true, false},
    119 		{"./", "TestFoo", "x", true, false},
    120 		{"./.", "TestFoo", "x", true, false},
    121 		{"/bar/baz", "TestFoo", "bar", true, true},
    122 		{"/bar/baz", "TestFoo", "bar/baz", true, false},
    123 		{"//baz", "TestFoo", "bar/baz", true, false},
    124 		{"//", "TestFoo", "bar/baz", true, false},
    125 		{"/bar/baz", "TestFoo/bar", "baz", true, false},
    126 		{"//foo", "TestFoo", "bar/baz", false, false},
    127 		{"/bar/baz", "TestFoo", "x", false, false},
    128 		{"/bar/baz", "TestBar", "x/bar/baz", false, false},
    129 	}
    130 
    131 	for _, tc := range testCases {
    132 		m := newMatcher(regexp.MatchString, tc.pattern, "-test.run")
    133 
    134 		parent := &common{name: tc.parent}
    135 		if tc.parent != "" {
    136 			parent.level = 1
    137 		}
    138 		if n, ok, partial := m.fullName(parent, tc.sub); ok != tc.ok || partial != tc.partial {
    139 			t.Errorf("for pattern %q, fullName(parent=%q, sub=%q) = %q, ok %v partial %v; want ok %v partial %v",
    140 				tc.pattern, tc.parent, tc.sub, n, ok, partial, tc.ok, tc.partial)
    141 		}
    142 	}
    143 }
    144 
    145 func TestNaming(t *T) {
    146 	m := newMatcher(regexp.MatchString, "", "")
    147 
    148 	parent := &common{name: "x", level: 1} // top-level test.
    149 
    150 	// Rig the matcher with some preloaded values.
    151 	m.subNames["x/b"] = 1000
    152 
    153 	testCases := []struct {
    154 		name, want string
    155 	}{
    156 		// Uniqueness
    157 		{"", "x/#00"},
    158 		{"", "x/#01"},
    159 
    160 		{"t", "x/t"},
    161 		{"t", "x/t#01"},
    162 		{"t", "x/t#02"},
    163 
    164 		{"a#01", "x/a#01"}, // user has subtest with this name.
    165 		{"a", "x/a"},       // doesn't conflict with this name.
    166 		{"a", "x/a#01#01"}, // conflict, add disambiguating string.
    167 		{"a", "x/a#02"},    // This string is claimed now, so resume
    168 		{"a", "x/a#03"},    // with counting.
    169 		{"a#02", "x/a#02#01"},
    170 
    171 		{"b", "x/b#1000"}, // rigged, see above
    172 		{"b", "x/b#1001"},
    173 
    174 		// // Sanitizing
    175 		{"A:1 B:2", "x/A:1_B:2"},
    176 		{"s\t\r\u00a0", "x/s___"},
    177 		{"\x01", `x/\x01`},
    178 		{"\U0010ffff", `x/\U0010ffff`},
    179 	}
    180 
    181 	for i, tc := range testCases {
    182 		if got, _, _ := m.fullName(parent, tc.name); got != tc.want {
    183 			t.Errorf("%d:%s: got %q; want %q", i, tc.name, got, tc.want)
    184 		}
    185 	}
    186 }
    187