Add Validate() to all collections#481
Add Validate() to all collections#481bflad merged 13 commits intohashicorp:mainfrom Doridian:feat/validation-collections
Conversation
bflad
left a comment
There was a problem hiding this comment.
Hi @Doridian 👋 Thank you for submitting this. Overall this is looking pretty good, it could just use some additional unit testing and small adjustments. If you have any questions about adding that testing, please reach out.
Also, if you could, it would be great to include a changelog entry which can be done by adding a .changelog/481.txt file with contents such as:
```release-note:bug
types: Ensured `List`, `Map`, and `Set` types with `xattr.TypeWithValidate` elements run validation on those elements
```| return diags | ||
| } | ||
|
|
||
| validatableType, isValidatable := st.ElemType.(xattr.TypeWithValidate) |
There was a problem hiding this comment.
We should ensure there is a covering unit test for this change. 👍
| return diags | ||
| } | ||
|
|
||
| if !in.Type().Is(tftypes.Map{}) { |
There was a problem hiding this comment.
We should ensure there is a covering unit test for this new conditional. 👍
Co-authored-by: Brian Flad <bflad417@gmail.com>
Co-authored-by: Brian Flad <bflad417@gmail.com>
Co-authored-by: Brian Flad <bflad417@gmail.com>
|
Addresses all suggestions but unit tests. I was looking at the unit tests and could not really find any that seem to test the current validation framework, so I was unsure how or where to add those. I also saw tests for collections spread over the local list_test/map_test and then the big struct_test file. I will gladly take any suggestion for where to best add those tests and if I maybe just missed validation tests I could base off of. |
|
It seems that |
|
@Doridian since we are adding a method onto the type, we can unit test the method itself, e.g. func TestListTypeValidate(t *testing.T) {
t.Parallel()
testCases := map[string]struct {
listType ListType
tfValue tftypes.Value
path path.Path
expectedDiags diag.Diagnostics
}{
"wrong-value-type": {
listType: ListType{
ElemType: StringType,
},
tfValue: tftypes.NewValue(tftypes.Set{
ElementType: tftypes.String,
}, []tftypes.Value{
tftypes.NewValue(tftypes.String, "testvalue"),
}),
path: path.Root("test"),
expectedDiags: diag.Diagnostics{
diag.NewAttributeErrorDiagnostic(
path.Root("test"),
"List Type Validation Error",
"An unexpected error was encountered trying to validate an attribute value. This is always an error in the provider. Please report the following to the provider developer:\n\n"+
"expected List value, received tftypes.Value with value: tftypes.Set[tftypes.String]<tftypes.String<\"testvalue\">>",
),
},
},
"no-validation": {
listType: ListType{
ElemType: StringType,
},
tfValue: tftypes.NewValue(tftypes.List{
ElementType: tftypes.String,
}, []tftypes.Value{
tftypes.NewValue(tftypes.String, "testvalue"),
}),
path: path.Root("test"),
},
}
for name, testCase := range testCases {
name, testCase := name, testCase
t.Run(name, func(t *testing.T) {
t.Parallel()
diags := testCase.listType.Validate(context.Background(), testCase.tfValue, testCase.path)
if diff := cmp.Diff(diags, testCase.expectedDiags); diff != "" {
t.Errorf("unexpected diagnostics difference: %s", diff)
}
})
}
}Rinse and repeat for This is okay for now as it would unfortunately take a lot more effort to import the existing |
|
(We could also create an unexported type with validation errors in the test files too, but it is totally fine.) |
|
I have added tests for list and map exactly as you described. |
Maybe in another PR if I find the time 😉 |
|
I'm going to lock this pull request because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active contributions. |
This also fixes a bug in
internal/reflect/map.gowhere it used the map's own type to Validate elements, which does not seem correct at all.Fixes #467