-
Notifications
You must be signed in to change notification settings - Fork 1.7k
assert.EqualExportedValues: fix handling of arrays #1473
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
assert.EqualExportedValues: fix handling of arrays #1473
Conversation
@HaraldNordgren Looks like this was introduce in #1379, I saw this along with the issue you are addressing in #1384. |
Awesome! |
I think this needs some more tests. And would it make sense to combine the array and slice paths more since the logic is so similar after instantiating? Something like this: // copyExportedFields iterates downward through list data structures and creates a copy
// that only contains the exported struct fields.
func copyExportedFieldsList(expectedValue, result reflect.Value) reflect.Value {
for i := 0; i < expectedValue.Len(); i++ {
index := expectedValue.Index(i)
if isNil(index) {
continue
}
unexportedRemoved := copyExportedFields(index.Interface())
result.Index(i).Set(reflect.ValueOf(unexportedRemoved))
}
return result
} and then case reflect.Array:
result := reflect.New(reflect.ArrayOf(expectedValue.Len(), expectedType.Elem())).Elem()
result = copyExportedFieldsList(expectedValue, result)
return result.Interface()
case reflect.Slice:
result := reflect.MakeSlice(expectedType, expectedValue.Len(), expectedValue.Len())
result = copyExportedFieldsList(expectedValue, result)
return result.Interface() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(See my comment above)
@dolmen @boyan-soubachov Can you take a look at this? It's a good change that should be merged to unbreak the code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only difference between the reflect.Array and reflect.Slice blocks are how result
is allocated.
Please refactor to keep a single switch block and just branch with an if for the construction of result
.
@dolmen I moved the two cases into a single switch statement to reduce code duplication as requested. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
Summary
In EqualExportedValues, testify treats an Array as a Slice, however, the reflect library throws an error if the type passed to
reflect.MakeSlice
is not a Slice kind. This issue was identified in #1404The result is a very simple test such as
results in a panic
This PR adjusts the offending switch statement in
copyExportedFields
to handle arrays separately, and construct the array usingreflect.New(reflect.ArrayOf(len, type)).Elem()
instead ofreflect.MakeSlice
.Changes
copyExportedFields
(used byEqualExportedValues
) to handle Array type separately from Slices as they must be constructed differently.TestEqualExportedValues
to verify an array object can be set on object passed toEqualExportedValues
.Motivation
A user was unable to use
EqualExportedValues
if they had an exported array type nested somewhere in their struct.A test like this will now pass
Related issues
Closes #1404