Skip to content

Commit 111716d

Browse files
Merge pull request #1729 from siliconbrain/fix-subset-notsubset-mixed-type
fix Subset/NotSubset when calling with mixed input types
2 parents d338e95 + 121ddb9 commit 111716d

File tree

6 files changed

+114
-42
lines changed

6 files changed

+114
-42
lines changed

assert/assertion_format.go

Lines changed: 12 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

assert/assertion_forward.go

Lines changed: 24 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

assert/assertions.go

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -982,11 +982,15 @@ func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{})
982982

983983
}
984984

985-
// Subset asserts that the specified list(array, slice...) or map contains all
986-
// elements given in the specified subset list(array, slice...) or map.
985+
// Subset asserts that the list (array, slice, or map) contains all elements
986+
// given in the subset (array, slice, or map).
987+
// Map elements are key-value pairs unless compared with an array or slice where
988+
// only the map key is evaluated.
987989
//
988990
// assert.Subset(t, [1, 2, 3], [1, 2])
989991
// assert.Subset(t, {"x": 1, "y": 2}, {"x": 1})
992+
// assert.Subset(t, [1, 2, 3], {1: "one", 2: "two"})
993+
// assert.Subset(t, {"x": 1, "y": 2}, ["x"])
990994
func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
991995
if h, ok := t.(tHelper); ok {
992996
h.Helper()
@@ -1001,7 +1005,7 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
10011005
}
10021006

10031007
subsetKind := reflect.TypeOf(subset).Kind()
1004-
if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map {
1008+
if subsetKind != reflect.Array && subsetKind != reflect.Slice && subsetKind != reflect.Map {
10051009
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...)
10061010
}
10071011

@@ -1025,6 +1029,13 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
10251029
}
10261030

10271031
subsetList := reflect.ValueOf(subset)
1032+
if subsetKind == reflect.Map {
1033+
keys := make([]interface{}, subsetList.Len())
1034+
for idx, key := range subsetList.MapKeys() {
1035+
keys[idx] = key.Interface()
1036+
}
1037+
subsetList = reflect.ValueOf(keys)
1038+
}
10281039
for i := 0; i < subsetList.Len(); i++ {
10291040
element := subsetList.Index(i).Interface()
10301041
ok, found := containsElement(list, element)
@@ -1039,12 +1050,15 @@ func Subset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok
10391050
return true
10401051
}
10411052

1042-
// NotSubset asserts that the specified list(array, slice...) or map does NOT
1043-
// contain all elements given in the specified subset list(array, slice...) or
1044-
// map.
1053+
// NotSubset asserts that the list (array, slice, or map) does NOT contain all
1054+
// elements given in the subset (array, slice, or map).
1055+
// Map elements are key-value pairs unless compared with an array or slice where
1056+
// only the map key is evaluated.
10451057
//
10461058
// assert.NotSubset(t, [1, 3, 4], [1, 2])
10471059
// assert.NotSubset(t, {"x": 1, "y": 2}, {"z": 3})
1060+
// assert.NotSubset(t, [1, 3, 4], {1: "one", 2: "two"})
1061+
// assert.NotSubset(t, {"x": 1, "y": 2}, ["z"])
10481062
func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{}) (ok bool) {
10491063
if h, ok := t.(tHelper); ok {
10501064
h.Helper()
@@ -1059,7 +1073,7 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{})
10591073
}
10601074

10611075
subsetKind := reflect.TypeOf(subset).Kind()
1062-
if subsetKind != reflect.Array && subsetKind != reflect.Slice && listKind != reflect.Map {
1076+
if subsetKind != reflect.Array && subsetKind != reflect.Slice && subsetKind != reflect.Map {
10631077
return Fail(t, fmt.Sprintf("%q has an unsupported type %s", subset, subsetKind), msgAndArgs...)
10641078
}
10651079

@@ -1083,6 +1097,13 @@ func NotSubset(t TestingT, list, subset interface{}, msgAndArgs ...interface{})
10831097
}
10841098

10851099
subsetList := reflect.ValueOf(subset)
1100+
if subsetKind == reflect.Map {
1101+
keys := make([]interface{}, subsetList.Len())
1102+
for idx, key := range subsetList.MapKeys() {
1103+
keys[idx] = key.Interface()
1104+
}
1105+
subsetList = reflect.ValueOf(keys)
1106+
}
10861107
for i := 0; i < subsetList.Len(); i++ {
10871108
element := subsetList.Index(i).Interface()
10881109
ok, found := containsElement(list, element)

assert/assertions_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,6 +1142,7 @@ func TestSubsetNotSubset(t *testing.T) {
11421142
"a": "x",
11431143
"b": "y",
11441144
}, true, `map["a":"x" "b":"y"] is a subset of map["a":"x" "b":"y" "c":"z"]`},
1145+
{[]string{"a", "b", "c"}, map[string]int{"a": 1, "c": 3}, true, `map["a":'\x01' "c":'\x03'] is a subset of ["a" "b" "c"]`},
11451146

11461147
// cases that are expected not to contain
11471148
{[]string{"hello", "world"}, []string{"hello", "testify"}, false, `[]string{"hello", "world"} does not contain "testify"`},
@@ -1163,6 +1164,7 @@ func TestSubsetNotSubset(t *testing.T) {
11631164
"b": "y",
11641165
"c": "z",
11651166
}, false, `map[string]string{"a":"x", "b":"y"} does not contain map[string]string{"a":"x", "b":"y", "c":"z"}`},
1167+
{[]string{"a", "b", "c"}, map[string]int{"c": 3, "d": 4}, false, `[]string{"a", "b", "c"} does not contain "d"`},
11661168
}
11671169

11681170
for _, c := range cases {

require/require.go

Lines changed: 24 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

require/require_forward.go

Lines changed: 24 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)