Skip to content

Commit 2192fa8

Browse files
committed
introducing no field is empty assertion
1 parent 1b4fca7 commit 2192fa8

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
@@ -2148,3 +2148,38 @@ func buildErrorChainString(err error) string {
21482148
}
21492149
return chain
21502150
}
2151+
2152+
// NoFieldIsEmpty asserts that object, which must be a struct or eventually reference to one, has no empty exported fields.
2153+
func NoFieldIsEmpty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool {
2154+
if reflect.TypeOf(object).Kind() == reflect.Ptr {
2155+
return NoFieldIsEmpty(t, reflect.ValueOf(object).Elem().Interface(), msgAndArgs)
2156+
}
2157+
2158+
if h, ok := t.(tHelper); ok {
2159+
h.Helper()
2160+
}
2161+
2162+
objectType := reflect.TypeOf(object)
2163+
if objectType.Kind() != reflect.Struct {
2164+
return Fail(t, "Input must be a struct or eventually reference one", msgAndArgs...)
2165+
}
2166+
2167+
var emptyFields []string
2168+
objectValue := reflect.ValueOf(object)
2169+
for i := 0; i < objectType.NumField(); i++ {
2170+
field := objectType.Field(i)
2171+
if !field.IsExported() {
2172+
continue
2173+
}
2174+
2175+
if isEmpty(objectValue.Field(i).Interface()) {
2176+
emptyFields = append(emptyFields, field.Name)
2177+
}
2178+
}
2179+
2180+
if len(emptyFields) > 0 {
2181+
return Fail(t, fmt.Sprintf("Object contained empty fields: %s", strings.Join(emptyFields, ", ")), msgAndArgs...)
2182+
}
2183+
2184+
return true
2185+
}

assert/assertions_test.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3279,3 +3279,88 @@ func TestErrorAs(t *testing.T) {
32793279
})
32803280
}
32813281
}
3282+
3283+
func TestNoFieldIsEmpty(t *testing.T) {
3284+
str := "a string"
3285+
tests := []struct {
3286+
name string
3287+
input interface{}
3288+
result bool
3289+
resultErrMsg string
3290+
}{
3291+
{
3292+
name: "success",
3293+
input: struct {
3294+
Float64 float64
3295+
Func func()
3296+
Int int
3297+
Interface interface{}
3298+
Pointer *string
3299+
Slice []string
3300+
String string
3301+
Struct struct{ String string }
3302+
}{
3303+
Float64: 1.5,
3304+
Func: func() {},
3305+
Int: 1,
3306+
Interface: "interface",
3307+
Pointer: &str,
3308+
Slice: []string{"a", "b"},
3309+
String: "a string",
3310+
Struct: struct{ String string }{String: "a nested string"},
3311+
},
3312+
result: true,
3313+
},
3314+
{
3315+
name: "success_pointer",
3316+
input: &struct {
3317+
String string
3318+
}{
3319+
String: "a string",
3320+
},
3321+
result: true,
3322+
},
3323+
{
3324+
name: "success_unexported",
3325+
input: struct{ unexported string }{},
3326+
result: true,
3327+
},
3328+
{
3329+
name: "failure",
3330+
input: struct {
3331+
Float64 float64
3332+
Func func()
3333+
Int int
3334+
Interface interface{}
3335+
Pointer *string
3336+
Slice []string
3337+
String string
3338+
Struct struct{ String string }
3339+
}{},
3340+
result: false,
3341+
resultErrMsg: "Object contained empty fields: Float64, Func, Int, Interface, Pointer, Slice, String, Struct\n",
3342+
},
3343+
{
3344+
name: "failure_partial",
3345+
input: struct {
3346+
StringA string
3347+
StringB string
3348+
}{StringA: "not_empty"},
3349+
result: false,
3350+
resultErrMsg: "Object contained empty fields: StringB\n",
3351+
},
3352+
{
3353+
name: "failure_wrong_type",
3354+
input: "a string is not a struct",
3355+
result: false,
3356+
resultErrMsg: "Input must be a struct or eventually reference one\n",
3357+
},
3358+
}
3359+
for _, tt := range tests {
3360+
t.Run(tt.name, func(t *testing.T) {
3361+
mockT := new(captureTestingT)
3362+
result := NoFieldIsEmpty(mockT, tt.input)
3363+
mockT.checkResultAndErrMsg(t, tt.result, result, tt.resultErrMsg)
3364+
})
3365+
}
3366+
}

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)