From 199c9ac77abc7aa6cd16acbafd83fc4c1e7969da Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Sat, 2 Aug 2025 18:34:06 -0700 Subject: [PATCH] Remove ExpectInvalid() All use cases are converted. Co-Authored-by: Yongrui Lin --- .../output_tests/tags/immutable/doc_test.go | 24 +++--- .../item/immutable_transitions/doc_test.go | 16 ++-- .../tags/item/subfield/doc_test.go | 12 +-- .../tags/item/typedef/doc_test.go | 6 +- .../tags/listmap/multiple_keys/doc_test.go | 38 ++++---- .../tags/listmap/single_key/doc_test.go | 38 ++++---- .../output_tests/tags/listset/doc_test.go | 30 +++---- .../output_tests/tags/minimum/doc.go | 4 +- .../output_tests/tags/minimum/doc_test.go | 29 +++---- .../tags/minimum/zz_generated.validations.go | 4 - .../issubresource/doc_test.go | 12 +-- .../tags/supported_resources/root/doc_test.go | 12 +-- .../subresource/doc_test.go | 24 +++--- .../discriminated/custom_members/doc_test.go | 12 +-- .../union/discriminated/multiple/doc_test.go | 24 +++--- .../union/discriminated/simple/doc_test.go | 12 +-- .../union/discriminated/sparse/doc_test.go | 12 +-- .../custom_members/doc_test.go | 12 +-- .../undiscriminated/multiple/doc_test.go | 32 +++---- .../union/undiscriminated/simple/doc_test.go | 24 +++--- .../zerooroneof/custom_members/doc_test.go | 6 +- .../zerooroneof/multiple/doc_test.go | 19 ++-- .../zerooroneof/simple/doc_test.go | 18 ++-- .../primitive_pointers/doc_test.go | 12 +-- .../update_validations/primitives/doc_test.go | 12 +-- .../validation-gen/testscheme/testscheme.go | 86 ------------------- 26 files changed, 218 insertions(+), 312 deletions(-) diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/immutable/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/immutable/doc_test.go index 8b27cc4edf8..100e349add7 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/immutable/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/immutable/doc_test.go @@ -64,16 +64,16 @@ func Test(t *testing.T) { st.Value(&structA).OldValue(&structA2).ExpectValid() st.Value(&structA2).OldValue(&structA).ExpectValid() - st.Value(&structA).OldValue(&structB).ExpectInvalid( - field.Forbidden(field.NewPath("stringField"), "field is immutable"), - field.Forbidden(field.NewPath("stringPtrField"), "field is immutable"), - field.Forbidden(field.NewPath("structField"), "field is immutable"), - field.Forbidden(field.NewPath("structPtrField"), "field is immutable"), - field.Forbidden(field.NewPath("noncomparableStructField"), "field is immutable"), - field.Forbidden(field.NewPath("noncomparableStructPtrField"), "field is immutable"), - field.Forbidden(field.NewPath("sliceField"), "field is immutable"), - field.Forbidden(field.NewPath("mapField"), "field is immutable"), - field.Forbidden(field.NewPath("immutableField"), "field is immutable"), - field.Forbidden(field.NewPath("immutablePtrField"), "field is immutable"), - ) + st.Value(&structA).OldValue(&structB).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Forbidden(field.NewPath("stringField"), "immutable"), + field.Forbidden(field.NewPath("stringPtrField"), "immutable"), + field.Forbidden(field.NewPath("structField"), "immutable"), + field.Forbidden(field.NewPath("structPtrField"), "immutable"), + field.Forbidden(field.NewPath("noncomparableStructField"), "immutable"), + field.Forbidden(field.NewPath("noncomparableStructPtrField"), "immutable"), + field.Forbidden(field.NewPath("sliceField"), "immutable"), + field.Forbidden(field.NewPath("mapField"), "immutable"), + field.Forbidden(field.NewPath("immutableField"), "immutable"), + field.Forbidden(field.NewPath("immutablePtrField"), "immutable"), + }) } diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/item/immutable_transitions/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/item/immutable_transitions/doc_test.go index d20d9db9d47..467392461e2 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/item/immutable_transitions/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/item/immutable_transitions/doc_test.go @@ -41,15 +41,15 @@ func Test(t *testing.T) { }, } - st.Value(new).OldValue(old).ExpectInvalid( - field.Forbidden(field.NewPath("listField").Index(0), "field is immutable"), - field.Forbidden(field.NewPath("listField").Index(1).Child("stringField"), "field is immutable"), - ) + st.Value(new).OldValue(old).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Forbidden(field.NewPath("listField").Index(0), "immutable"), + field.Forbidden(field.NewPath("listField").Index(1).Child("stringField"), "immutable"), + }) - st.Value(new).OldValue(&Struct{ListField: []Item{}}).ExpectInvalid( - field.Forbidden(field.NewPath("listField").Index(0), "field is immutable"), - field.Forbidden(field.NewPath("listField").Index(1).Child("stringField"), "field is immutable"), - ) + st.Value(new).OldValue(&Struct{ListField: []Item{}}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Forbidden(field.NewPath("listField").Index(0), "immutable"), + field.Forbidden(field.NewPath("listField").Index(1).Child("stringField"), "immutable"), + }) // Test that "c" can change independently st.Value(&Struct{ diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/item/subfield/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/item/subfield/doc_test.go index d53c343e007..7ecbbca0c55 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/item/subfield/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/item/subfield/doc_test.go @@ -44,9 +44,9 @@ func Test(t *testing.T) { RatchetItems: []RatchetItem{ {Key: "ratchet", Status: "forbidden", Version: 1}, }, - }).ExpectInvalid( - field.Invalid(field.NewPath("ratchetItems").Index(0).Child("status"), "forbidden", "must not be equal to \"forbidden\""), - ) + }).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring(), field.ErrorList{ + field.Invalid(field.NewPath("ratchetItems").Index(0).Child("status"), nil, ""), + }) st.Value(&Struct{ RatchetItems: []RatchetItem{ @@ -74,7 +74,7 @@ func Test(t *testing.T) { RatchetItems: []RatchetItem{ {Key: "ratchet", Status: "allowed", Version: 1}, }, - }).ExpectInvalid( - field.Invalid(field.NewPath("ratchetItems").Index(0).Child("status"), "forbidden", "must not be equal to \"forbidden\""), - ) + }).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring(), field.ErrorList{ + field.Invalid(field.NewPath("ratchetItems").Index(0).Child("status"), nil, ""), + }) } diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/item/typedef/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/item/typedef/doc_test.go index 0fb31bc28e6..43dc94afe9a 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/item/typedef/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/item/typedef/doc_test.go @@ -52,9 +52,9 @@ func Test(t *testing.T) { {Key: "immutable", Data: "changed"}, }, } - st.Value(newStruct).OldValue(oldStruct).ExpectInvalid( - field.Forbidden(field.NewPath("typedefItems").Index(0), "field is immutable"), - ) + st.Value(newStruct).OldValue(oldStruct).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Forbidden(field.NewPath("typedefItems").Index(0), "immutable"), + }) // Test nested typedef (typedef of typedef). st.Value(&Struct{ diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/listmap/multiple_keys/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/listmap/multiple_keys/doc_test.go index f96ad2b0bae..2787b0118a8 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/listmap/multiple_keys/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/listmap/multiple_keys/doc_test.go @@ -105,26 +105,26 @@ func TestUpdateCorrelation(t *testing.T) { st.Value(&structA2).OldValue(&structA1).ExpectValid() - st.Value(&structA1).OldValue(&structB).ExpectInvalid( - field.Forbidden(field.NewPath("listField").Index(0), "field is immutable"), - field.Forbidden(field.NewPath("listField").Index(1), "field is immutable"), - field.Forbidden(field.NewPath("listTypedefField").Index(0), "field is immutable"), - field.Forbidden(field.NewPath("listTypedefField").Index(1), "field is immutable"), - field.Forbidden(field.NewPath("typedefField").Index(0), "field is immutable"), - field.Forbidden(field.NewPath("typedefField").Index(1), "field is immutable"), - ) + st.Value(&structA1).OldValue(&structB).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Forbidden(field.NewPath("listField").Index(0), "immutable"), + field.Forbidden(field.NewPath("listField").Index(1), "immutable"), + field.Forbidden(field.NewPath("listTypedefField").Index(0), "immutable"), + field.Forbidden(field.NewPath("listTypedefField").Index(1), "immutable"), + field.Forbidden(field.NewPath("typedefField").Index(0), "immutable"), + field.Forbidden(field.NewPath("typedefField").Index(1), "immutable"), + }) - st.Value(&structB).OldValue(&structA1).ExpectInvalid( - field.Forbidden(field.NewPath("listField").Index(0), "field is immutable"), - field.Forbidden(field.NewPath("listField").Index(1), "field is immutable"), - field.Forbidden(field.NewPath("listField").Index(2), "field is immutable"), - field.Forbidden(field.NewPath("listTypedefField").Index(0), "field is immutable"), - field.Forbidden(field.NewPath("listTypedefField").Index(1), "field is immutable"), - field.Forbidden(field.NewPath("listTypedefField").Index(2), "field is immutable"), - field.Forbidden(field.NewPath("typedefField").Index(0), "field is immutable"), - field.Forbidden(field.NewPath("typedefField").Index(1), "field is immutable"), - field.Forbidden(field.NewPath("typedefField").Index(2), "field is immutable"), - ) + st.Value(&structB).OldValue(&structA1).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Forbidden(field.NewPath("listField").Index(0), "immutable"), + field.Forbidden(field.NewPath("listField").Index(1), "immutable"), + field.Forbidden(field.NewPath("listField").Index(2), "immutable"), + field.Forbidden(field.NewPath("listTypedefField").Index(0), "immutable"), + field.Forbidden(field.NewPath("listTypedefField").Index(1), "immutable"), + field.Forbidden(field.NewPath("listTypedefField").Index(2), "immutable"), + field.Forbidden(field.NewPath("typedefField").Index(0), "immutable"), + field.Forbidden(field.NewPath("typedefField").Index(1), "immutable"), + field.Forbidden(field.NewPath("typedefField").Index(2), "immutable"), + }) } func TestRatcheting(t *testing.T) { diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/listmap/single_key/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/listmap/single_key/doc_test.go index e331f5d5274..a2130348018 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/listmap/single_key/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/listmap/single_key/doc_test.go @@ -106,26 +106,26 @@ func TestUpdateCorrelation(t *testing.T) { st.Value(&structA2).OldValue(&structA1).ExpectValid() - st.Value(&structA1).OldValue(&structB).ExpectInvalid( - field.Forbidden(field.NewPath("listField").Index(0), "field is immutable"), - field.Forbidden(field.NewPath("listField").Index(1), "field is immutable"), - field.Forbidden(field.NewPath("listTypedefField").Index(0), "field is immutable"), - field.Forbidden(field.NewPath("listTypedefField").Index(1), "field is immutable"), - field.Forbidden(field.NewPath("typedefField").Index(0), "field is immutable"), - field.Forbidden(field.NewPath("typedefField").Index(1), "field is immutable"), - ) + st.Value(&structA1).OldValue(&structB).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Forbidden(field.NewPath("listField").Index(0), "immutable"), + field.Forbidden(field.NewPath("listField").Index(1), "immutable"), + field.Forbidden(field.NewPath("listTypedefField").Index(0), "immutable"), + field.Forbidden(field.NewPath("listTypedefField").Index(1), "immutable"), + field.Forbidden(field.NewPath("typedefField").Index(0), "immutable"), + field.Forbidden(field.NewPath("typedefField").Index(1), "immutable"), + }) - st.Value(&structB).OldValue(&structA1).ExpectInvalid( - field.Forbidden(field.NewPath("listField").Index(0), "field is immutable"), - field.Forbidden(field.NewPath("listField").Index(1), "field is immutable"), - field.Forbidden(field.NewPath("listField").Index(2), "field is immutable"), - field.Forbidden(field.NewPath("listTypedefField").Index(0), "field is immutable"), - field.Forbidden(field.NewPath("listTypedefField").Index(1), "field is immutable"), - field.Forbidden(field.NewPath("listTypedefField").Index(2), "field is immutable"), - field.Forbidden(field.NewPath("typedefField").Index(0), "field is immutable"), - field.Forbidden(field.NewPath("typedefField").Index(1), "field is immutable"), - field.Forbidden(field.NewPath("typedefField").Index(2), "field is immutable"), - ) + st.Value(&structB).OldValue(&structA1).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Forbidden(field.NewPath("listField").Index(0), "immutable"), + field.Forbidden(field.NewPath("listField").Index(1), "immutable"), + field.Forbidden(field.NewPath("listField").Index(2), "immutable"), + field.Forbidden(field.NewPath("listTypedefField").Index(0), "immutable"), + field.Forbidden(field.NewPath("listTypedefField").Index(1), "immutable"), + field.Forbidden(field.NewPath("listTypedefField").Index(2), "immutable"), + field.Forbidden(field.NewPath("typedefField").Index(0), "immutable"), + field.Forbidden(field.NewPath("typedefField").Index(1), "immutable"), + field.Forbidden(field.NewPath("typedefField").Index(2), "immutable"), + }) } func TestRatcheting(t *testing.T) { diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/listset/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/listset/doc_test.go index 3acf78740e7..a04c007b0ed 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/listset/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/listset/doc_test.go @@ -56,21 +56,21 @@ func Test(t *testing.T) { {StringPtrField: ptrS1}, {StringPtrField: ptrS2}, }, - }).ExpectInvalid( - field.Duplicate(field.NewPath("sliceStringField").Index(3), "ccc"), - field.Duplicate(field.NewPath("sliceStringField").Index(4), "bbb"), - field.Duplicate(field.NewPath("sliceStringField").Index(5), "aaa"), - field.Duplicate(field.NewPath("sliceIntField").Index(3), 3), - field.Duplicate(field.NewPath("sliceIntField").Index(4), 2), - field.Duplicate(field.NewPath("sliceIntField").Index(5), 1), - field.Duplicate(field.NewPath("sliceComparableField").Index(3), ComparableStruct{"ccc"}), - field.Duplicate(field.NewPath("sliceComparableField").Index(4), ComparableStruct{"bbb"}), - field.Duplicate(field.NewPath("sliceComparableField").Index(5), ComparableStruct{"aaa"}), - field.Duplicate(field.NewPath("sliceNonComparableField").Index(3), NonComparableStruct{[]string{"ccc", "333"}}), - field.Duplicate(field.NewPath("sliceNonComparableField").Index(4), NonComparableStruct{[]string{"bbb", "222"}}), - field.Duplicate(field.NewPath("sliceNonComparableField").Index(5), NonComparableStruct{[]string{"aaa", "111"}}), - field.Duplicate(field.NewPath("sliceFalselyComparableField").Index(1), FalselyComparableStruct{StringPtrField: ptrS2}), - ) + }).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Duplicate(field.NewPath("sliceStringField").Index(3), nil), + field.Duplicate(field.NewPath("sliceStringField").Index(4), nil), + field.Duplicate(field.NewPath("sliceStringField").Index(5), nil), + field.Duplicate(field.NewPath("sliceIntField").Index(3), nil), + field.Duplicate(field.NewPath("sliceIntField").Index(4), nil), + field.Duplicate(field.NewPath("sliceIntField").Index(5), nil), + field.Duplicate(field.NewPath("sliceComparableField").Index(3), nil), + field.Duplicate(field.NewPath("sliceComparableField").Index(4), nil), + field.Duplicate(field.NewPath("sliceComparableField").Index(5), nil), + field.Duplicate(field.NewPath("sliceNonComparableField").Index(3), nil), + field.Duplicate(field.NewPath("sliceNonComparableField").Index(4), nil), + field.Duplicate(field.NewPath("sliceNonComparableField").Index(5), nil), + field.Duplicate(field.NewPath("sliceFalselyComparableField").Index(1), nil), + }) } func TestSetCorrelation(t *testing.T) { diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/minimum/doc.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/minimum/doc.go index b9bd2b9276d..082320aef4e 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/minimum/doc.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/minimum/doc.go @@ -53,9 +53,7 @@ type Struct struct { // +k8s:minimum=1 Uint64Field uint64 `json:"uint64Field"` - // +k8s:minimum=1 - TypedefField IntType `json:"typedefField"` - // +k8s:minimum=1 + TypedefField IntType `json:"typedefField"` TypedefPtrField *IntType `json:"typedefPtrField"` } diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/minimum/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/minimum/doc_test.go index 46d416e2f28..971228d6aaf 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/minimum/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/minimum/doc_test.go @@ -19,7 +19,6 @@ package minimum import ( "testing" - "k8s.io/apimachinery/pkg/api/validate/content" "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/utils/ptr" ) @@ -32,20 +31,20 @@ func Test(t *testing.T) { IntPtrField: ptr.To(0), UintPtrField: ptr.To(uint(0)), TypedefPtrField: ptr.To(IntType(0)), - }).ExpectInvalid( - field.Invalid(field.NewPath("intField"), 0, content.MinError(1)), - field.Invalid(field.NewPath("intPtrField"), 0, content.MinError(1)), - field.Invalid(field.NewPath("int16Field"), 0, content.MinError(1)), - field.Invalid(field.NewPath("int32Field"), 0, content.MinError(1)), - field.Invalid(field.NewPath("int64Field"), 0, content.MinError(1)), - field.Invalid(field.NewPath("uintField"), uint(0), content.MinError(1)), - field.Invalid(field.NewPath("uintPtrField"), uint(0), content.MinError(1)), - field.Invalid(field.NewPath("uint16Field"), uint(0), content.MinError(1)), - field.Invalid(field.NewPath("uint32Field"), uint(0), content.MinError(1)), - field.Invalid(field.NewPath("uint64Field"), uint(0), content.MinError(1)), - field.Invalid(field.NewPath("typedefField"), 0, content.MinError(1)), - field.Invalid(field.NewPath("typedefPtrField"), 0, content.MinError(1)), - ) + }).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring(), field.ErrorList{ + field.Invalid(field.NewPath("intField"), nil, ""), + field.Invalid(field.NewPath("intPtrField"), nil, ""), + field.Invalid(field.NewPath("int16Field"), nil, ""), + field.Invalid(field.NewPath("int32Field"), nil, ""), + field.Invalid(field.NewPath("int64Field"), nil, ""), + field.Invalid(field.NewPath("uintField"), nil, ""), + field.Invalid(field.NewPath("uintPtrField"), nil, ""), + field.Invalid(field.NewPath("uint16Field"), nil, ""), + field.Invalid(field.NewPath("uint32Field"), nil, ""), + field.Invalid(field.NewPath("uint64Field"), nil, ""), + field.Invalid(field.NewPath("typedefField"), nil, ""), + field.Invalid(field.NewPath("typedefPtrField"), nil, ""), + }) // Test validation ratcheting st.Value(&Struct{ IntPtrField: ptr.To(0), diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/minimum/zz_generated.validations.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/minimum/zz_generated.validations.go index b55cc16908f..a8fc2df748a 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/minimum/zz_generated.validations.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/minimum/zz_generated.validations.go @@ -188,8 +188,6 @@ func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) { return nil } - // call field-attached validations - errs = append(errs, validate.Minimum(ctx, op, fldPath, obj, oldObj, 1)...) // call the type's validation function errs = append(errs, Validate_IntType(ctx, op, fldPath, obj, oldObj)...) return @@ -202,8 +200,6 @@ func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field if op.Type == operation.Update && (obj == oldObj || (obj != nil && oldObj != nil && *obj == *oldObj)) { return nil } - // call field-attached validations - errs = append(errs, validate.Minimum(ctx, op, fldPath, obj, oldObj, 1)...) // call the type's validation function errs = append(errs, Validate_IntType(ctx, op, fldPath, obj, oldObj)...) return diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/supported_resources/issubresource/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/supported_resources/issubresource/doc_test.go index f69a3c284d5..0dbe831864a 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/supported_resources/issubresource/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/supported_resources/issubresource/doc_test.go @@ -27,13 +27,13 @@ func TestRegisterValidations(t *testing.T) { st := localSchemeBuilder.Test(t) t1 := &T1{} - st.Value(t1).ExpectInvalid( - field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", t1, "/")), - ) + st.Value(t1).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.InternalError(nil, fmt.Errorf("")), + }) st.Value(t1).Subresources([]string{"scale"}).ExpectValid() - st.Value(t1).Subresources([]string{"unknown"}).ExpectInvalid( - field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", t1, "/unknown")), - ) + st.Value(t1).Subresources([]string{"unknown"}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.InternalError(nil, fmt.Errorf("")), + }) } diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/supported_resources/root/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/supported_resources/root/doc_test.go index 44d1d484783..cceeda6dca6 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/supported_resources/root/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/supported_resources/root/doc_test.go @@ -30,11 +30,11 @@ func TestRegisterValidations(t *testing.T) { st.Value(t1).ExpectValid() - st.Value(t1).Subresources([]string{"scale"}).ExpectInvalid( - field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", t1, "/scale")), - ) + st.Value(t1).Subresources([]string{"scale"}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.InternalError(nil, fmt.Errorf("")), + }) - st.Value(t1).Subresources([]string{"x", "y"}).ExpectInvalid( - field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", t1, "/x/y")), - ) + st.Value(t1).Subresources([]string{"x", "y"}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.InternalError(nil, fmt.Errorf("")), + }) } diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/supported_resources/subresource/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/supported_resources/subresource/doc_test.go index 17ddb42ee9a..8bf631a70ea 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/supported_resources/subresource/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/supported_resources/subresource/doc_test.go @@ -34,17 +34,17 @@ func TestRegisterValidations(t *testing.T) { st.Value(t1).Subresources([]string{"scale"}).ExpectValid() st.Value(t1).Subresources([]string{"x", "y"}).ExpectValid() - st.Value(t1).Subresources([]string{"status", "unknown"}).ExpectInvalid( - field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", t1, "/status/unknown")), - ) + st.Value(t1).Subresources([]string{"status", "unknown"}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.InternalError(nil, fmt.Errorf("")), + }) - st.Value(t1).Subresources([]string{"unknown"}).ExpectInvalid( - field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", t1, "/unknown")), - ) - st.Value(t1).Subresources([]string{"x", "unknown"}).ExpectInvalid( - field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", t1, "/x/unknown")), - ) - st.Value(t1).Subresources([]string{"x", "y", "unknown"}).ExpectInvalid( - field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", t1, "/x/y/unknown")), - ) + st.Value(t1).Subresources([]string{"unknown"}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.InternalError(nil, fmt.Errorf("")), + }) + st.Value(t1).Subresources([]string{"x", "unknown"}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.InternalError(nil, fmt.Errorf("")), + }) + st.Value(t1).Subresources([]string{"x", "y", "unknown"}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.InternalError(nil, fmt.Errorf("")), + }) } diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/discriminated/custom_members/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/discriminated/custom_members/doc_test.go index 116d101f8c1..bd5487edc9e 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/discriminated/custom_members/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/discriminated/custom_members/doc_test.go @@ -28,13 +28,13 @@ func Test(t *testing.T) { st.Value(&Struct{D: DM1, M1: &M1{}}).ExpectValid() st.Value(&Struct{D: DM2, M2: &M2{}}).ExpectValid() - st.Value(&Struct{D: DM2, M1: &M1{}, M2: &M2{}}).ExpectInvalid( - field.Invalid(field.NewPath("m1"), "", "may only be specified when `d` is \"CustomM1\""), - ) + st.Value(&Struct{D: DM2, M1: &M1{}, M2: &M2{}}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(field.NewPath("m1"), nil, "may only be specified when"), + }) - st.Value(&Struct{D: DM1}).ExpectInvalid( - field.Invalid(field.NewPath("m1"), "", "must be specified when `d` is \"CustomM1\""), - ) + st.Value(&Struct{D: DM1}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(field.NewPath("m1"), nil, "must be specified when"), + }) // Test validation ratcheting st.Value(&Struct{D: DM2, M1: &M1{}, M2: &M2{}}).OldValue(&Struct{D: DM2, M1: &M1{}, M2: &M2{}}).ExpectValid() diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/discriminated/multiple/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/discriminated/multiple/doc_test.go index eed30841e42..4d1ad466f80 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/discriminated/multiple/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/discriminated/multiple/doc_test.go @@ -40,26 +40,26 @@ func Test(t *testing.T) { st.Value(&Struct{ D1: U1M2, U1M1: &M1{}, U1M2: &M2{}, D2: U2M2, // no value - }).ExpectInvalid( - field.Invalid(field.NewPath("u1m1"), "", "may only be specified when `d1` is \"U1M1\""), - field.Invalid(field.NewPath("u2m2"), "", "must be specified when `d2` is \"U2M2\""), - ) + }).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(field.NewPath("u1m1"), nil, "may only be specified when"), + field.Invalid(field.NewPath("u2m2"), nil, "must be specified when"), + }) st.Value(&Struct{ D1: U1M2, // no value D2: U2M2, U2M1: &M1{}, U2M2: &M2{}, - }).ExpectInvalid( - field.Invalid(field.NewPath("u1m2"), "", "must be specified when `d1` is \"U1M2\""), - field.Invalid(field.NewPath("u2m1"), "", "may only be specified when `d2` is \"U2M1\""), - ) + }).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(field.NewPath("u1m2"), nil, "must be specified when"), + field.Invalid(field.NewPath("u2m1"), nil, "may only be specified when"), + }) st.Value(&Struct{ D1: U1M2, // no value D2: U2M2, // no value - }).ExpectInvalid( - field.Invalid(field.NewPath("u1m2"), "", "must be specified when `d1` is \"U1M2\""), - field.Invalid(field.NewPath("u2m2"), "", "must be specified when `d2` is \"U2M2\""), - ) + }).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(field.NewPath("u1m2"), nil, "must be specified when"), + field.Invalid(field.NewPath("u2m2"), nil, "must be specified when"), + }) // Test validation ratcheting st.Value(&Struct{ diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/discriminated/simple/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/discriminated/simple/doc_test.go index d606dc9d180..bd2885ffb04 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/discriminated/simple/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/discriminated/simple/doc_test.go @@ -30,13 +30,13 @@ func Test(t *testing.T) { st.Value(&Struct{D: DM1, M1: &M1{}}).ExpectValid() st.Value(&Struct{D: DM2, M2: &M2{}}).ExpectValid() - st.Value(&Struct{D: DM2, M1: &M1{}, M2: &M2{}}).ExpectInvalid( - field.Invalid(field.NewPath("m1"), "", "may only be specified when `d` is \"M1\""), - ) + st.Value(&Struct{D: DM2, M1: &M1{}, M2: &M2{}}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(field.NewPath("m1"), nil, "may only be specified when"), + }) - st.Value(&Struct{D: DM1}).ExpectInvalid( - field.Invalid(field.NewPath("m1"), "", "must be specified when `d` is \"M1\""), - ) + st.Value(&Struct{D: DM1}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(field.NewPath("m1"), nil, "must be specified when"), + }) // Test validation ratcheting st.Value(&Struct{D: DM2, M1: &M1{}, M2: &M2{}}).OldValue(&Struct{D: DM2, M1: &M1{}, M2: &M2{}}).ExpectValid() diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/discriminated/sparse/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/discriminated/sparse/doc_test.go index 1c786417371..66068b71467 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/discriminated/sparse/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/discriminated/sparse/doc_test.go @@ -30,13 +30,13 @@ func Test(t *testing.T) { st.Value(&Struct{D: DM1, M1: &M1{}}).ExpectValid() st.Value(&Struct{D: DM2}).ExpectValid() - st.Value(&Struct{D: DM2, M1: &M1{}}).ExpectInvalid( - field.Invalid(field.NewPath("m1"), "", "may only be specified when `d` is \"M1\""), - ) + st.Value(&Struct{D: DM2, M1: &M1{}}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(field.NewPath("m1"), nil, "may only be specified when"), + }) - st.Value(&Struct{D: DM1}).ExpectInvalid( - field.Invalid(field.NewPath("m1"), "", "must be specified when `d` is \"M1\""), - ) + st.Value(&Struct{D: DM1}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(field.NewPath("m1"), nil, "must be specified when"), + }) // Test validation ratcheting st.Value(&Struct{D: DM2, M1: &M1{}}).OldValue(&Struct{D: DM2, M1: &M1{}}).ExpectValid() diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/undiscriminated/custom_members/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/undiscriminated/custom_members/doc_test.go index 8a52021c607..7aef1de0ce4 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/undiscriminated/custom_members/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/undiscriminated/custom_members/doc_test.go @@ -28,12 +28,12 @@ func Test(t *testing.T) { st.Value(&Struct{M1: &M1{}}).ExpectValid() st.Value(&Struct{M2: &M2{}}).ExpectValid() - st.Value(&Struct{M1: &M1{}, M2: &M2{}}).ExpectInvalid( - field.Invalid(nil, "{m1, m2}", "must specify exactly one of: `m1`, `m2`"), - ) - st.Value(&Struct{}).ExpectInvalid( - field.Invalid(nil, "", "must specify one of: `m1`, `m2`"), - ) + st.Value(&Struct{M1: &M1{}, M2: &M2{}}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(nil, nil, "must specify exactly one of"), + }) + st.Value(&Struct{}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(nil, nil, "must specify one of"), + }) // Test validation ratcheting st.Value(&Struct{M1: &M1{}, M2: &M2{}}).OldValue(&Struct{M1: &M1{}, M2: &M2{}}).ExpectValid() diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/undiscriminated/multiple/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/undiscriminated/multiple/doc_test.go index 4539c2cc3f9..cac9528c158 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/undiscriminated/multiple/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/undiscriminated/multiple/doc_test.go @@ -25,31 +25,31 @@ import ( func Test(t *testing.T) { st := localSchemeBuilder.Test(t) - st.Value(&Struct{}).ExpectInvalid( - field.Invalid(nil, "", "must specify one of: `u1m1`, `u1m2`"), - field.Invalid(nil, "", "must specify one of: `u2m1`, `u2m2`"), - ) + st.Value(&Struct{}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(nil, nil, "must specify one of"), + field.Invalid(nil, nil, "must specify one of"), + }) st.Value(&Struct{U1M1: &M1{}, U2M1: &M1{}}).ExpectValid() st.Value(&Struct{U1M2: &M2{}, U2M2: &M2{}}).ExpectValid() - st.Value(&Struct{U1M1: &M1{}, U1M2: &M2{}}).ExpectInvalid( - field.Invalid(nil, "{u1m1, u1m2}", "must specify exactly one of: `u1m1`, `u1m2`"), - field.Invalid(nil, "", "must specify one of: `u2m1`, `u2m2`"), - ) + st.Value(&Struct{U1M1: &M1{}, U1M2: &M2{}}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(nil, nil, "must specify exactly one of"), + field.Invalid(nil, nil, "must specify one of"), + }) - st.Value(&Struct{U2M1: &M1{}, U2M2: &M2{}}).ExpectInvalid( - field.Invalid(nil, "", "must specify one of: `u1m1`, `u1m2`"), - field.Invalid(nil, "{u2m1, u2m2}", "must specify exactly one of: `u2m1`, `u2m2`"), - ) + st.Value(&Struct{U2M1: &M1{}, U2M2: &M2{}}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(nil, nil, "must specify one of"), + field.Invalid(nil, nil, "must specify exactly one of"), + }) st.Value(&Struct{ U1M1: &M1{}, U1M2: &M2{}, U2M1: &M1{}, U2M2: &M2{}, - }).ExpectInvalid( - field.Invalid(nil, "{u1m1, u1m2}", "must specify exactly one of: `u1m1`, `u1m2`"), - field.Invalid(nil, "{u2m1, u2m2}", "must specify exactly one of: `u2m1`, `u2m2`"), - ) + }).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(nil, nil, "must specify exactly one of"), + field.Invalid(nil, nil, "must specify exactly one of"), + }) // Test validation ratcheting st.Value(&Struct{}).OldValue(&Struct{}).ExpectValid() diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/undiscriminated/simple/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/undiscriminated/simple/doc_test.go index be0d9320eac..f00b41b546f 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/undiscriminated/simple/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/union/union/undiscriminated/simple/doc_test.go @@ -26,24 +26,24 @@ import ( func Test(t *testing.T) { st := localSchemeBuilder.Test(t) - st.Value(&Struct{}).ExpectInvalid( - field.Invalid(nil, "", "must specify one of: `m1`, `m2`, `m3`, `m4`"), - ) + st.Value(&Struct{}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(nil, nil, "must specify one of"), + }) st.Value(&Struct{M1: &M1{}}).ExpectValid() st.Value(&Struct{M2: &M2{}}).ExpectValid() st.Value(&Struct{M3: "a string"}).ExpectValid() st.Value(&Struct{M4: ptr.To("a string")}).ExpectValid() - st.Value(&Struct{M1: &M1{}, M2: &M2{}}).ExpectInvalid( - field.Invalid(nil, "{m1, m2}", "must specify exactly one of: `m1`, `m2`, `m3`, `m4`"), - ) - st.Value(&Struct{M1: &M1{}, M3: "a string"}).ExpectInvalid( - field.Invalid(nil, "{m1, m3}", "must specify exactly one of: `m1`, `m2`, `m3`, `m4`"), - ) - st.Value(&Struct{M1: &M1{}, M4: ptr.To("a string")}).ExpectInvalid( - field.Invalid(nil, "{m1, m4}", "must specify exactly one of: `m1`, `m2`, `m3`, `m4`"), - ) + st.Value(&Struct{M1: &M1{}, M2: &M2{}}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(nil, nil, "must specify exactly one of"), + }) + st.Value(&Struct{M1: &M1{}, M3: "a string"}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(nil, nil, "must specify exactly one of"), + }) + st.Value(&Struct{M1: &M1{}, M4: ptr.To("a string")}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(nil, nil, "must specify exactly one of"), + }) // Update only considers whether a field was set, not the value. st.Value(&Struct{M3: "a string"}).OldValue(&Struct{M3: "different string"}).ExpectValid() diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/zerooroneof/zerooroneof/custom_members/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/zerooroneof/zerooroneof/custom_members/doc_test.go index 9707ab935c4..a8d559372e9 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/zerooroneof/zerooroneof/custom_members/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/zerooroneof/zerooroneof/custom_members/doc_test.go @@ -31,9 +31,9 @@ func Test(t *testing.T) { st.Value(&Struct{M1: &M1{}}).ExpectValid() st.Value(&Struct{M2: &M2{}}).ExpectValid() - st.Value(&Struct{M1: &M1{}, M2: &M2{}}).ExpectInvalid( - field.Invalid(nil, "{m1, m2}", "must specify at most one of: `m1`, `m2`"), - ) + st.Value(&Struct{M1: &M1{}, M2: &M2{}}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring(), field.ErrorList{ + field.Invalid(nil, nil, "must specify at most one of"), + }) // Test validation ratcheting st.Value(&Struct{M1: &M1{}, M2: &M2{}}).OldValue(&Struct{M1: &M1{}, M2: &M2{}}).ExpectValid() diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/zerooroneof/zerooroneof/multiple/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/zerooroneof/zerooroneof/multiple/doc_test.go index d1f1155149f..2be31c9563a 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/zerooroneof/zerooroneof/multiple/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/zerooroneof/zerooroneof/multiple/doc_test.go @@ -37,21 +37,20 @@ func Test(t *testing.T) { st.Value(&Struct{U2M2: &M2{}}).ExpectValid() // Multiple members in one union - st.Value(&Struct{U1M1: &M1{}, U1M2: &M2{}}).ExpectInvalid( - field.Invalid(nil, "{u1m1, u1m2}", "must specify at most one of: `u1m1`, `u1m2`"), - ) + st.Value(&Struct{U1M1: &M1{}, U1M2: &M2{}}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(nil, nil, "must specify at most one of").WithOrigin("zeroOrOneOf"), + }) - st.Value(&Struct{U2M1: &M1{}, U2M2: &M2{}}).ExpectInvalid( - field.Invalid(nil, "{u2m1, u2m2}", "must specify at most one of: `u2m1`, `u2m2`"), - ) + st.Value(&Struct{U2M1: &M1{}, U2M2: &M2{}}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(nil, nil, "must specify at most one of").WithOrigin("zeroOrOneOf"), + }) st.Value(&Struct{ U1M1: &M1{}, U1M2: &M2{}, U2M1: &M1{}, U2M2: &M2{}, - }).ExpectInvalid( - field.Invalid(nil, "{u1m1, u1m2}", "must specify at most one of: `u1m1`, `u1m2`"), - field.Invalid(nil, "{u2m1, u2m2}", "must specify at most one of: `u2m1`, `u2m2`"), - ) + }).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(nil, nil, "must specify at most one of").WithOrigin("zeroOrOneOf"), + }) // Test validation ratcheting st.Value(&Struct{}).OldValue(&Struct{}).ExpectValid() diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/zerooroneof/zerooroneof/simple/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/zerooroneof/zerooroneof/simple/doc_test.go index f2024c936c1..01a92457af9 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/zerooroneof/zerooroneof/simple/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/tags/zerooroneof/zerooroneof/simple/doc_test.go @@ -34,15 +34,15 @@ func Test(t *testing.T) { st.Value(&Struct{M3: "a string"}).ExpectValid() st.Value(&Struct{M4: ptr.To("a string")}).ExpectValid() - st.Value(&Struct{M1: &M1{}, M2: &M2{}}).ExpectInvalid( - field.Invalid(nil, "{m1, m2}", "must specify at most one of: `m1`, `m2`, `m3`, `m4`"), - ) - st.Value(&Struct{M1: &M1{}, M3: "a string"}).ExpectInvalid( - field.Invalid(nil, "{m1, m3}", "must specify at most one of: `m1`, `m2`, `m3`, `m4`"), - ) - st.Value(&Struct{M1: &M1{}, M4: ptr.To("a string")}).ExpectInvalid( - field.Invalid(nil, "{m1, m4}", "must specify at most one of: `m1`, `m2`, `m3`, `m4`"), - ) + st.Value(&Struct{M1: &M1{}, M2: &M2{}}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(nil, nil, "must specify at most one of").WithOrigin("zeroOrOneOf"), + }) + st.Value(&Struct{M1: &M1{}, M3: "a string"}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(nil, nil, "must specify at most one of").WithOrigin("zeroOrOneOf"), + }) + st.Value(&Struct{M1: &M1{}, M4: ptr.To("a string")}).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Invalid(nil, nil, "must specify at most one of").WithOrigin("zeroOrOneOf"), + }) // Update only considers whether a field was set, not the value. st.Value(&Struct{M3: "a string"}).OldValue(&Struct{M3: "different string"}).ExpectValid() diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/update_validations/primitive_pointers/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/update_validations/primitive_pointers/doc_test.go index f6022bbe1f1..7ad410ae888 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/update_validations/primitive_pointers/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/update_validations/primitive_pointers/doc_test.go @@ -52,10 +52,10 @@ func Test(t *testing.T) { st.Value(&structA1).OldValue(&structA2).ExpectValid() - st.Value(&structA1).OldValue(&structB).ExpectInvalid( - field.Forbidden(field.NewPath("sp"), "field is immutable"), - field.Forbidden(field.NewPath("ip"), "field is immutable"), - field.Forbidden(field.NewPath("bp"), "field is immutable"), - field.Forbidden(field.NewPath("fp"), "field is immutable"), - ) + st.Value(&structA1).OldValue(&structB).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Forbidden(field.NewPath("sp"), ""), + field.Forbidden(field.NewPath("ip"), ""), + field.Forbidden(field.NewPath("bp"), ""), + field.Forbidden(field.NewPath("fp"), ""), + }) } diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/update_validations/primitives/doc_test.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/update_validations/primitives/doc_test.go index 93ccc70ff57..429c8812868 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/update_validations/primitives/doc_test.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/output_tests/update_validations/primitives/doc_test.go @@ -42,10 +42,10 @@ func Test(t *testing.T) { st.Value(&structA).OldValue(&structA).ExpectValid() - st.Value(&structA).OldValue(&structB).ExpectInvalid( - field.Forbidden(field.NewPath("s"), "field is immutable"), - field.Forbidden(field.NewPath("i"), "field is immutable"), - field.Forbidden(field.NewPath("b"), "field is immutable"), - field.Forbidden(field.NewPath("f"), "field is immutable"), - ) + st.Value(&structA).OldValue(&structB).ExpectMatches(field.ErrorMatcher{}.ByType().ByField().ByDetailSubstring().ByOrigin(), field.ErrorList{ + field.Forbidden(field.NewPath("s"), ""), + field.Forbidden(field.NewPath("i"), ""), + field.Forbidden(field.NewPath("b"), ""), + field.Forbidden(field.NewPath("f"), ""), + }) } diff --git a/staging/src/k8s.io/code-generator/cmd/validation-gen/testscheme/testscheme.go b/staging/src/k8s.io/code-generator/cmd/validation-gen/testscheme/testscheme.go index 2461a15dcdf..b98b5708762 100644 --- a/staging/src/k8s.io/code-generator/cmd/validation-gen/testscheme/testscheme.go +++ b/staging/src/k8s.io/code-generator/cmd/validation-gen/testscheme/testscheme.go @@ -310,14 +310,6 @@ func (v *ValidationTester) ExpectValid() *ValidationTester { return v } -// ExpectInvalid validates the value and calls t.Errorf if want does not match the actual errors. -// Returns ValidationTester to support call chaining. -func (v *ValidationTester) ExpectInvalid(want ...*field.Error) *ValidationTester { - v.T.Helper() - - return v.expectInvalid(byFullError, want...) -} - func (v *ValidationTester) ExpectValidateFalseByPath(expectedByPath map[string][]string) *ValidationTester { v.T.Helper() @@ -368,84 +360,6 @@ func (v *ValidationTester) ExpectMatches(matcher field.ErrorMatcher, expected fi return v } -func (v *ValidationTester) getErrorsByPath() map[string][]string { - byPath := map[string][]string{} - errs := v.validate() - for _, e := range errs { - f := e.Field - if f == "" { - f = "" - } - byPath[f] = append(byPath[f], e.ErrorBody()) - } - // ensure args are sorted - for _, args := range byPath { - sort.Strings(args) - } - return byPath -} - -func renderByPath(byPath map[string][]string) string { - keys := []string{} - for key := range byPath { - keys = append(keys, key) - } - sort.Strings(keys) - - for _, vals := range byPath { - sort.Strings(vals) - } - - buf := strings.Builder{} - for _, key := range keys { - vals := byPath[key] - for _, val := range vals { - buf.WriteString(fmt.Sprintf("\t%s: %q\n", key, val)) - } - } - return buf.String() -} - -func renderList(list []string) string { - buf := strings.Builder{} - for _, item := range list { - buf.WriteString(fmt.Sprintf("\t%q\n", item)) - } - return buf.String() -} - -func (v *ValidationTester) expectInvalid(matcher matcher, errs ...*field.Error) *ValidationTester { - v.T.Helper() - - v.T.Run(fmt.Sprintf("%T", v.value), func(t *testing.T) { - t.Helper() - - want := sets.New[string]() - for _, e := range errs { - want.Insert(matcher(e)) - } - - got := sets.New[string]() - for _, e := range v.validate() { - got.Insert(matcher(e)) - } - if !got.Equal(want) { - t.Errorf("validation errors differed from expected:\n%v\n", cmp.Diff(want, got, cmpopts.SortMaps(stdcmp.Less[string]))) - - for x := range got.Difference(want) { - fmt.Printf("%q,\n", strings.TrimPrefix(x, "forced failure: ")) - } - } - }) - return v -} - -type matcher func(err *field.Error) string - -func byFullError(err *field.Error) string { - return err.Error() -} - func (v *ValidationTester) validate() field.ErrorList { var errs field.ErrorList if v.oldValue == nil {