aboutsummaryrefslogtreecommitdiff
path: root/src/testing/match_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/testing/match_test.go')
-rw-r--r--src/testing/match_test.go97
1 files changed, 66 insertions, 31 deletions
diff --git a/src/testing/match_test.go b/src/testing/match_test.go
index 9ceadbb31d..206ac0b651 100644
--- a/src/testing/match_test.go
+++ b/src/testing/match_test.go
@@ -149,49 +149,84 @@ func TestMatcher(t *T) {
}
}
-func TestNaming(t *T) {
- m := newMatcher(regexp.MatchString, "", "")
-
- parent := &common{name: "x", level: 1} // top-level test.
+var namingTestCases = []struct{ name, want string }{
+ // Uniqueness
+ {"", "x/#00"},
+ {"", "x/#01"},
+ {"#0", "x/#0"}, // Doesn't conflict with #00 because the number of digits differs.
+ {"#00", "x/#00#01"}, // Conflicts with implicit #00 (used above), so add a suffix.
+ {"#", "x/#"},
+ {"#", "x/##01"},
- // Rig the matcher with some preloaded values.
- m.subNames["x/b"] = 1000
+ {"t", "x/t"},
+ {"t", "x/t#01"},
+ {"t", "x/t#02"},
+ {"t#00", "x/t#00"}, // Explicit "#00" doesn't conflict with the unsuffixed first subtest.
- testCases := []struct {
- name, want string
- }{
- // Uniqueness
- {"", "x/#00"},
- {"", "x/#01"},
+ {"a#01", "x/a#01"}, // user has subtest with this name.
+ {"a", "x/a"}, // doesn't conflict with this name.
+ {"a", "x/a#02"}, // This string is claimed now, so resume
+ {"a", "x/a#03"}, // with counting.
+ {"a#02", "x/a#02#01"}, // We already used a#02 once, so add a suffix.
- {"t", "x/t"},
- {"t", "x/t#01"},
- {"t", "x/t#02"},
+ {"b#00", "x/b#00"},
+ {"b", "x/b"}, // Implicit 0 doesn't conflict with explicit "#00".
+ {"b", "x/b#01"},
+ {"b#9223372036854775807", "x/b#9223372036854775807"}, // MaxInt64
+ {"b", "x/b#02"},
+ {"b", "x/b#03"},
- {"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`},
+}
- // // Sanitizing
- {"A:1 B:2", "x/A:1_B:2"},
- {"s\t\r\u00a0", "x/s___"},
- {"\x01", `x/\x01`},
- {"\U0010ffff", `x/\U0010ffff`},
- }
+func TestNaming(t *T) {
+ m := newMatcher(regexp.MatchString, "", "")
+ parent := &common{name: "x", level: 1} // top-level test.
- for i, tc := range testCases {
+ for i, tc := range namingTestCases {
if got, _, _ := m.fullName(parent, tc.name); got != tc.want {
t.Errorf("%d:%s: got %q; want %q", i, tc.name, got, tc.want)
}
}
}
+func FuzzNaming(f *F) {
+ for _, tc := range namingTestCases {
+ f.Add(tc.name)
+ }
+ parent := &common{name: "x", level: 1}
+ var m *matcher
+ var seen map[string]string
+ reset := func() {
+ m = newMatcher(regexp.MatchString, "", "")
+ seen = make(map[string]string)
+ }
+ reset()
+
+ f.Fuzz(func(t *T, subname string) {
+ if len(subname) > 10 {
+ // Long names attract the OOM killer.
+ t.Skip()
+ }
+ name := m.unique(parent.name, subname)
+ if !strings.Contains(name, "/"+subname) {
+ t.Errorf("name %q does not contain subname %q", name, subname)
+ }
+ if prev, ok := seen[name]; ok {
+ t.Errorf("name %q generated by both %q and %q", name, prev, subname)
+ }
+ if len(seen) > 1e6 {
+ // Free up memory.
+ reset()
+ }
+ seen[name] = subname
+ })
+}
+
// GoString returns a string that is more readable than the default, which makes
// it easier to read test errors.
func (m alternationMatch) GoString() string {