Skip to content

Commit 621db53

Browse files
committed
introducing no field is empty assertion
1 parent 8d4dcbb commit 621db53

File tree

6 files changed

+182
-0
lines changed

6 files changed

+182
-0
lines changed

assert/assertion_format.go

Lines changed: 8 additions & 0 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: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

assert/assertions.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2107,3 +2107,38 @@ func buildErrorChainString(err error) string {
21072107
}
21082108
return chain
21092109
}
2110+
2111+
// NoFieldIsEmpty asserts that object, which must be a struct or eventually reference to one, has no empty exported fields.
2112+
func NoFieldIsEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
2113+
if reflect.TypeOf(object).Kind() == reflect.Ptr {
2114+
return NoFieldIsEmpty(t, reflect.ValueOf(object).Elem().Interface(), msgAndArgs)
2115+
}
2116+
2117+
if h, ok := t.(tHelper); ok {
2118+
h.Helper()
2119+
}
2120+
2121+
objectType := reflect.TypeOf(object)
2122+
if objectType.Kind() != reflect.Struct {
2123+
return Fail(t, "Input must be a struct or eventually reference one", msgAndArgs...)
2124+
}
2125+
2126+
var emptyFields []string
2127+
objectValue := reflect.ValueOf(object)
2128+
for i := 0; i < objectType.NumField(); i++ {
2129+
field := objectType.Field(i)
2130+
if !field.IsExported() {
2131+
continue
2132+
}
2133+
2134+
if isEmpty(objectValue.Field(i).Interface()) {
2135+
emptyFields = append(emptyFields, field.Name)
2136+
}
2137+
}
2138+
2139+
if len(emptyFields) > 0 {
2140+
return Fail(t, fmt.Sprintf("Object contained empty fields: %s", strings.Join(emptyFields, ", ")), msgAndArgs...)
2141+
}
2142+
2143+
return true
2144+
}

assert/assertions_test.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3228,3 +3228,88 @@ func TestErrorAs(t *testing.T) {
32283228
})
32293229
}
32303230
}
3231+
3232+
func TestNoFieldIsEmpty(t *testing.T) {
3233+
str := "a string"
3234+
tests := []struct {
3235+
name string
3236+
input interface{}
3237+
result bool
3238+
resultErrMsg string
3239+
}{
3240+
{
3241+
name: "success",
3242+
input: struct {
3243+
Float64 float64
3244+
Func func()
3245+
Int int
3246+
Interface interface{}
3247+
Pointer *string
3248+
Slice []string
3249+
String string
3250+
Struct struct{ String string }
3251+
}{
3252+
Float64: 1.5,
3253+
Func: func() {},
3254+
Int: 1,
3255+
Interface: "interface",
3256+
Pointer: &str,
3257+
Slice: []string{"a", "b"},
3258+
String: "a string",
3259+
Struct: struct{ String string }{String: "a nested string"},
3260+
},
3261+
result: true,
3262+
},
3263+
{
3264+
name: "success_pointer",
3265+
input: &struct {
3266+
String string
3267+
}{
3268+
String: "a string",
3269+
},
3270+
result: true,
3271+
},
3272+
{
3273+
name: "success_unexported",
3274+
input: struct{ unexported string }{},
3275+
result: true,
3276+
},
3277+
{
3278+
name: "failure",
3279+
input: struct {
3280+
Float64 float64
3281+
Func func()
3282+
Int int
3283+
Interface interface{}
3284+
Pointer *string
3285+
Slice []string
3286+
String string
3287+
Struct struct{ String string }
3288+
}{},
3289+
result: false,
3290+
resultErrMsg: "Object contained empty fields: Float64, Func, Int, Interface, Pointer, Slice, String, Struct\n",
3291+
},
3292+
{
3293+
name: "failure_partial",
3294+
input: struct {
3295+
StringA string
3296+
StringB string
3297+
}{StringA: "not_empty"},
3298+
result: false,
3299+
resultErrMsg: "Object contained empty fields: StringB\n",
3300+
},
3301+
{
3302+
name: "failure_wrong_type",
3303+
input: "a string is not a struct",
3304+
result: false,
3305+
resultErrMsg: "Input must be a struct or eventually reference one\n",
3306+
},
3307+
}
3308+
for _, tt := range tests {
3309+
t.Run(tt.name, func(t *testing.T) {
3310+
mockT := new(captureTestingT)
3311+
result := NoFieldIsEmpty(mockT, tt.input)
3312+
mockT.checkResultAndErrMsg(t, tt.result, result, tt.resultErrMsg)
3313+
})
3314+
}
3315+
}

require/require.go

Lines changed: 22 additions & 0 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: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)