mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-07-23 10:26:22 +00:00
add item + union and item + zeroroneof output tests
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright 2025 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:validation-gen=TypeMeta
|
||||
// +k8s:validation-gen-scheme-registry=k8s.io/code-generator/cmd/validation-gen/testscheme.Scheme
|
||||
|
||||
// This is a test package.
|
||||
package unionsimple
|
||||
|
||||
import "k8s.io/code-generator/cmd/validation-gen/testscheme"
|
||||
|
||||
var localSchemeBuilder = testscheme.New()
|
||||
|
||||
type Struct struct {
|
||||
TypeMeta int `json:"typeMeta"`
|
||||
|
||||
// +k8s:listType=map
|
||||
// +k8s:listMapKey=name
|
||||
// +k8s:item(name: "succeeded")=+k8s:unionMember
|
||||
// +k8s:item(name: "failed")=+k8s:unionMember
|
||||
Tasks []Task `json:"tasks"`
|
||||
}
|
||||
|
||||
type Task struct {
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
Copyright 2025 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package unionsimple
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
st := localSchemeBuilder.Test(t)
|
||||
|
||||
st.Value(&Struct{
|
||||
Tasks: []Task{
|
||||
{Name: "succeeded", State: "Succeeded"},
|
||||
{Name: "other", State: "Other"},
|
||||
},
|
||||
}).ExpectValid()
|
||||
|
||||
invalidBothSet := &Struct{
|
||||
Tasks: []Task{
|
||||
{Name: "succeeded", State: "Succeeded"},
|
||||
{Name: "failed", State: "Failed"},
|
||||
},
|
||||
}
|
||||
|
||||
st.Value(invalidBothSet).ExpectMatches(
|
||||
field.ErrorMatcher{},
|
||||
field.ErrorList{
|
||||
field.Invalid(field.NewPath("tasks"), "{Tasks[{\"name\": \"failed\"}], Tasks[{\"name\": \"succeeded\"}]}",
|
||||
"must specify exactly one of: `Tasks[{\"name\": \"succeeded\"}]`, `Tasks[{\"name\": \"failed\"}]`"),
|
||||
},
|
||||
)
|
||||
|
||||
invalidEmpty := &Struct{
|
||||
Tasks: []Task{},
|
||||
}
|
||||
st.Value(invalidEmpty).ExpectMatches(
|
||||
field.ErrorMatcher{},
|
||||
field.ErrorList{
|
||||
field.Invalid(field.NewPath("tasks"), "",
|
||||
"must specify one of: `Tasks[{\"name\": \"succeeded\"}]`, `Tasks[{\"name\": \"failed\"}]`"),
|
||||
},
|
||||
)
|
||||
|
||||
// Test ratcheting.
|
||||
st.Value(invalidEmpty).OldValue(invalidEmpty).ExpectValid()
|
||||
st.Value(invalidBothSet).OldValue(invalidBothSet).ExpectValid()
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by validation-gen. DO NOT EDIT.
|
||||
|
||||
package unionsimple
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
|
||||
equality "k8s.io/apimachinery/pkg/api/equality"
|
||||
operation "k8s.io/apimachinery/pkg/api/operation"
|
||||
safe "k8s.io/apimachinery/pkg/api/safe"
|
||||
validate "k8s.io/apimachinery/pkg/api/validate"
|
||||
field "k8s.io/apimachinery/pkg/util/validation/field"
|
||||
testscheme "k8s.io/code-generator/cmd/validation-gen/testscheme"
|
||||
)
|
||||
|
||||
func init() { localSchemeBuilder.Register(RegisterValidations) }
|
||||
|
||||
// RegisterValidations adds validation functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterValidations(scheme *testscheme.Scheme) error {
|
||||
scheme.AddValidationFunc((*Struct)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/":
|
||||
return Validate_Struct(ctx, op, nil /* fldPath */, obj.(*Struct), safe.Cast[*Struct](oldObj))
|
||||
}
|
||||
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
var unionMembershipFor_k8s_io_code_generator_cmd_validation_gen_output_tests_tags_item_union_simple_Struct_Tasks_ = validate.NewUnionMembership([2]string{"Tasks[{\"name\": \"succeeded\"}]", ""}, [2]string{"Tasks[{\"name\": \"failed\"}]", ""})
|
||||
|
||||
func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *Struct) (errs field.ErrorList) {
|
||||
// field Struct.TypeMeta has no validation
|
||||
|
||||
// field Struct.Tasks
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj []Task) (errs field.ErrorList) {
|
||||
if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil // no changes
|
||||
}
|
||||
errs = append(errs, validate.Unique(ctx, op, fldPath, obj, oldObj, func(a Task, b Task) bool { return a.Name == b.Name })...)
|
||||
errs = append(errs, validate.Union(ctx, op, fldPath, obj, oldObj, unionMembershipFor_k8s_io_code_generator_cmd_validation_gen_output_tests_tags_item_union_simple_Struct_Tasks_, func(list []Task) bool {
|
||||
for i := range list {
|
||||
if list[i].Name == "failed" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}, func(list []Task) bool {
|
||||
for i := range list {
|
||||
if list[i].Name == "succeeded" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
})...)
|
||||
return
|
||||
}(fldPath.Child("tasks"), obj.Tasks, safe.Field(oldObj, func(oldObj *Struct) []Task { return oldObj.Tasks }))...)
|
||||
|
||||
return errs
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright 2025 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:validation-gen=TypeMeta
|
||||
// +k8s:validation-gen-scheme-registry=k8s.io/code-generator/cmd/validation-gen/testscheme.Scheme
|
||||
|
||||
// This is a test package.
|
||||
package uniontypedef
|
||||
|
||||
import "k8s.io/code-generator/cmd/validation-gen/testscheme"
|
||||
|
||||
var localSchemeBuilder = testscheme.New()
|
||||
|
||||
type Struct struct {
|
||||
TypeMeta int `json:"typeMeta"`
|
||||
|
||||
Tasks TaskList `json:"tasks"`
|
||||
}
|
||||
|
||||
// +k8s:listType=map
|
||||
// +k8s:listMapKey=name
|
||||
// +k8s:item(name: "succeeded")=+k8s:unionMember
|
||||
// +k8s:item(name: "failed")=+k8s:unionMember
|
||||
type TaskList []Task
|
||||
|
||||
type Task struct {
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
Copyright 2025 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package uniontypedef
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
st := localSchemeBuilder.Test(t)
|
||||
|
||||
st.Value(&Struct{
|
||||
Tasks: TaskList{
|
||||
{Name: "succeeded", State: "Succeeded"},
|
||||
{Name: "other", State: "Other"},
|
||||
},
|
||||
}).ExpectValid()
|
||||
|
||||
invalidBothSet := &Struct{
|
||||
Tasks: []Task{
|
||||
{Name: "succeeded", State: "Succeeded"},
|
||||
{Name: "failed", State: "Failed"},
|
||||
},
|
||||
}
|
||||
|
||||
st.Value(invalidBothSet).ExpectMatches(
|
||||
field.ErrorMatcher{},
|
||||
field.ErrorList{
|
||||
field.Invalid(field.NewPath("tasks"), "{TaskList[{\"name\": \"failed\"}], TaskList[{\"name\": \"succeeded\"}]}",
|
||||
"must specify exactly one of: `TaskList[{\"name\": \"succeeded\"}]`, `TaskList[{\"name\": \"failed\"}]`"),
|
||||
},
|
||||
)
|
||||
|
||||
invalidEmpty := &Struct{
|
||||
Tasks: TaskList{},
|
||||
}
|
||||
st.Value(invalidEmpty).ExpectMatches(
|
||||
field.ErrorMatcher{},
|
||||
field.ErrorList{
|
||||
field.Invalid(field.NewPath("tasks"), "",
|
||||
"must specify one of: `TaskList[{\"name\": \"succeeded\"}]`, `TaskList[{\"name\": \"failed\"}]`"),
|
||||
},
|
||||
)
|
||||
|
||||
// Test ratcheting.
|
||||
st.Value(invalidEmpty).OldValue(invalidEmpty).ExpectValid()
|
||||
|
||||
st.Value(invalidBothSet).OldValue(invalidBothSet).ExpectValid()
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by validation-gen. DO NOT EDIT.
|
||||
|
||||
package uniontypedef
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
|
||||
equality "k8s.io/apimachinery/pkg/api/equality"
|
||||
operation "k8s.io/apimachinery/pkg/api/operation"
|
||||
safe "k8s.io/apimachinery/pkg/api/safe"
|
||||
validate "k8s.io/apimachinery/pkg/api/validate"
|
||||
field "k8s.io/apimachinery/pkg/util/validation/field"
|
||||
testscheme "k8s.io/code-generator/cmd/validation-gen/testscheme"
|
||||
)
|
||||
|
||||
func init() { localSchemeBuilder.Register(RegisterValidations) }
|
||||
|
||||
// RegisterValidations adds validation functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterValidations(scheme *testscheme.Scheme) error {
|
||||
scheme.AddValidationFunc((*Struct)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/":
|
||||
return Validate_Struct(ctx, op, nil /* fldPath */, obj.(*Struct), safe.Cast[*Struct](oldObj))
|
||||
}
|
||||
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *Struct) (errs field.ErrorList) {
|
||||
// field Struct.TypeMeta has no validation
|
||||
|
||||
// field Struct.Tasks
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj TaskList) (errs field.ErrorList) {
|
||||
if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil // no changes
|
||||
}
|
||||
errs = append(errs, validate.Unique(ctx, op, fldPath, obj, oldObj, func(a Task, b Task) bool { return a.Name == b.Name })...)
|
||||
errs = append(errs, Validate_TaskList(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}(fldPath.Child("tasks"), obj.Tasks, safe.Field(oldObj, func(oldObj *Struct) TaskList { return oldObj.Tasks }))...)
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
var unionMembershipFor_k8s_io_code_generator_cmd_validation_gen_output_tests_tags_item_union_typedef_TaskList_ = validate.NewUnionMembership([2]string{"TaskList[{\"name\": \"succeeded\"}]", ""}, [2]string{"TaskList[{\"name\": \"failed\"}]", ""})
|
||||
|
||||
func Validate_TaskList(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj TaskList) (errs field.ErrorList) {
|
||||
// type TaskList
|
||||
if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil // no changes
|
||||
}
|
||||
errs = append(errs, validate.Unique(ctx, op, fldPath, obj, oldObj, func(a Task, b Task) bool { return a.Name == b.Name })...)
|
||||
errs = append(errs, validate.Union(ctx, op, fldPath, obj, oldObj, unionMembershipFor_k8s_io_code_generator_cmd_validation_gen_output_tests_tags_item_union_typedef_TaskList_, func(list TaskList) bool {
|
||||
for i := range list {
|
||||
if list[i].Name == "failed" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}, func(list TaskList) bool {
|
||||
for i := range list {
|
||||
if list[i].Name == "succeeded" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
})...)
|
||||
|
||||
return errs
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright 2025 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:validation-gen=TypeMeta
|
||||
// +k8s:validation-gen-scheme-registry=k8s.io/code-generator/cmd/validation-gen/testscheme.Scheme
|
||||
|
||||
// This is a test package.
|
||||
package zeroroneofsimple
|
||||
|
||||
import "k8s.io/code-generator/cmd/validation-gen/testscheme"
|
||||
|
||||
var localSchemeBuilder = testscheme.New()
|
||||
|
||||
type Struct struct {
|
||||
TypeMeta int `json:"typeMeta"`
|
||||
|
||||
// +k8s:listType=map
|
||||
// +k8s:listMapKey=name
|
||||
// +k8s:item(name: "succeeded")=+k8s:zeroOrOneOfMember
|
||||
// +k8s:item(name: "failed")=+k8s:zeroOrOneOfMember
|
||||
Tasks []Task `json:"tasks"`
|
||||
}
|
||||
|
||||
type Task struct {
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
Copyright 2025 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package zeroroneofsimple
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
st := localSchemeBuilder.Test(t)
|
||||
|
||||
st.Value(&Struct{
|
||||
Tasks: []Task{
|
||||
{Name: "other", State: "Other"},
|
||||
},
|
||||
}).ExpectValid()
|
||||
|
||||
st.Value(&Struct{
|
||||
Tasks: []Task{
|
||||
{Name: "succeeded", State: "Succeeded"},
|
||||
},
|
||||
}).ExpectValid()
|
||||
|
||||
st.Value(&Struct{
|
||||
Tasks: []Task{},
|
||||
}).ExpectValid()
|
||||
|
||||
invalidBothSet := &Struct{
|
||||
Tasks: []Task{
|
||||
{Name: "succeeded", State: "Succeeded"},
|
||||
{Name: "failed", State: "Failed"},
|
||||
},
|
||||
}
|
||||
st.Value(invalidBothSet).ExpectMatches(
|
||||
field.ErrorMatcher{}.ByType().ByField().ByOrigin(),
|
||||
field.ErrorList{
|
||||
field.Invalid(field.NewPath("tasks"), nil, "").WithOrigin("zeroOrOneOf"),
|
||||
},
|
||||
)
|
||||
|
||||
// Test ratcheting.
|
||||
st.Value(invalidBothSet).OldValue(invalidBothSet).ExpectValid()
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by validation-gen. DO NOT EDIT.
|
||||
|
||||
package zeroroneofsimple
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
|
||||
equality "k8s.io/apimachinery/pkg/api/equality"
|
||||
operation "k8s.io/apimachinery/pkg/api/operation"
|
||||
safe "k8s.io/apimachinery/pkg/api/safe"
|
||||
validate "k8s.io/apimachinery/pkg/api/validate"
|
||||
field "k8s.io/apimachinery/pkg/util/validation/field"
|
||||
testscheme "k8s.io/code-generator/cmd/validation-gen/testscheme"
|
||||
)
|
||||
|
||||
func init() { localSchemeBuilder.Register(RegisterValidations) }
|
||||
|
||||
// RegisterValidations adds validation functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterValidations(scheme *testscheme.Scheme) error {
|
||||
scheme.AddValidationFunc((*Struct)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/":
|
||||
return Validate_Struct(ctx, op, nil /* fldPath */, obj.(*Struct), safe.Cast[*Struct](oldObj))
|
||||
}
|
||||
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
var zeroOrOneOfMembershipFor_k8s_io_code_generator_cmd_validation_gen_output_tests_tags_item_zerorooneof_simple_Struct_Tasks_ = validate.NewUnionMembership([2]string{"Tasks[{\"name\": \"succeeded\"}]", ""}, [2]string{"Tasks[{\"name\": \"failed\"}]", ""})
|
||||
|
||||
func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *Struct) (errs field.ErrorList) {
|
||||
// field Struct.TypeMeta has no validation
|
||||
|
||||
// field Struct.Tasks
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj []Task) (errs field.ErrorList) {
|
||||
if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil // no changes
|
||||
}
|
||||
errs = append(errs, validate.Unique(ctx, op, fldPath, obj, oldObj, func(a Task, b Task) bool { return a.Name == b.Name })...)
|
||||
errs = append(errs, validate.ZeroOrOneOfUnion(ctx, op, fldPath, obj, oldObj, zeroOrOneOfMembershipFor_k8s_io_code_generator_cmd_validation_gen_output_tests_tags_item_zerorooneof_simple_Struct_Tasks_, func(list []Task) bool {
|
||||
for i := range list {
|
||||
if list[i].Name == "failed" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}, func(list []Task) bool {
|
||||
for i := range list {
|
||||
if list[i].Name == "succeeded" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
})...)
|
||||
return
|
||||
}(fldPath.Child("tasks"), obj.Tasks, safe.Field(oldObj, func(oldObj *Struct) []Task { return oldObj.Tasks }))...)
|
||||
|
||||
return errs
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
Copyright 2025 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:validation-gen=TypeMeta
|
||||
// +k8s:validation-gen-scheme-registry=k8s.io/code-generator/cmd/validation-gen/testscheme.Scheme
|
||||
|
||||
// This is a test package.
|
||||
package zeroroneooftypedef
|
||||
|
||||
import "k8s.io/code-generator/cmd/validation-gen/testscheme"
|
||||
|
||||
var localSchemeBuilder = testscheme.New()
|
||||
|
||||
type Struct struct {
|
||||
TypeMeta int `json:"typeMeta"`
|
||||
|
||||
Tasks TaskList `json:"tasks"`
|
||||
}
|
||||
|
||||
// +k8s:listType=map
|
||||
// +k8s:listMapKey=name
|
||||
// +k8s:item(name: "succeeded")=+k8s:zeroOrOneOfMember
|
||||
// +k8s:item(name: "failed")=+k8s:zeroOrOneOfMember
|
||||
type TaskList []Task
|
||||
|
||||
type Task struct {
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright 2025 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package zeroroneooftypedef
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
func Test(t *testing.T) {
|
||||
st := localSchemeBuilder.Test(t)
|
||||
|
||||
st.Value(&Struct{
|
||||
Tasks: TaskList{
|
||||
{Name: "other", State: "Other"},
|
||||
},
|
||||
}).ExpectValid()
|
||||
|
||||
st.Value(&Struct{
|
||||
Tasks: TaskList{
|
||||
{Name: "succeeded", State: "Succeeded"},
|
||||
{Name: "other", State: "Other"},
|
||||
},
|
||||
}).ExpectValid()
|
||||
|
||||
st.Value(&Struct{
|
||||
Tasks: TaskList{},
|
||||
}).ExpectValid()
|
||||
|
||||
invalidBothSet := &Struct{
|
||||
Tasks: TaskList{
|
||||
{Name: "succeeded", State: "Succeeded"},
|
||||
{Name: "failed", State: "Failed"},
|
||||
},
|
||||
}
|
||||
|
||||
st.Value(invalidBothSet).ExpectMatches(
|
||||
field.ErrorMatcher{}.ByType().ByField().ByOrigin(),
|
||||
field.ErrorList{
|
||||
field.Invalid(field.NewPath("tasks"), nil, "").WithOrigin("zeroOrOneOf"),
|
||||
},
|
||||
)
|
||||
|
||||
// Test ratcheting.
|
||||
st.Value(invalidBothSet).OldValue(invalidBothSet).ExpectValid()
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by validation-gen. DO NOT EDIT.
|
||||
|
||||
package zeroroneooftypedef
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
|
||||
equality "k8s.io/apimachinery/pkg/api/equality"
|
||||
operation "k8s.io/apimachinery/pkg/api/operation"
|
||||
safe "k8s.io/apimachinery/pkg/api/safe"
|
||||
validate "k8s.io/apimachinery/pkg/api/validate"
|
||||
field "k8s.io/apimachinery/pkg/util/validation/field"
|
||||
testscheme "k8s.io/code-generator/cmd/validation-gen/testscheme"
|
||||
)
|
||||
|
||||
func init() { localSchemeBuilder.Register(RegisterValidations) }
|
||||
|
||||
// RegisterValidations adds validation functions to the given scheme.
|
||||
// Public to allow building arbitrary schemes.
|
||||
func RegisterValidations(scheme *testscheme.Scheme) error {
|
||||
scheme.AddValidationFunc((*Struct)(nil), func(ctx context.Context, op operation.Operation, obj, oldObj interface{}) field.ErrorList {
|
||||
switch op.Request.SubresourcePath() {
|
||||
case "/":
|
||||
return Validate_Struct(ctx, op, nil /* fldPath */, obj.(*Struct), safe.Cast[*Struct](oldObj))
|
||||
}
|
||||
return field.ErrorList{field.InternalError(nil, fmt.Errorf("no validation found for %T, subresource: %v", obj, op.Request.SubresourcePath()))}
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
func Validate_Struct(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj *Struct) (errs field.ErrorList) {
|
||||
// field Struct.TypeMeta has no validation
|
||||
|
||||
// field Struct.Tasks
|
||||
errs = append(errs,
|
||||
func(fldPath *field.Path, obj, oldObj TaskList) (errs field.ErrorList) {
|
||||
if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil // no changes
|
||||
}
|
||||
errs = append(errs, validate.Unique(ctx, op, fldPath, obj, oldObj, func(a Task, b Task) bool { return a.Name == b.Name })...)
|
||||
errs = append(errs, Validate_TaskList(ctx, op, fldPath, obj, oldObj)...)
|
||||
return
|
||||
}(fldPath.Child("tasks"), obj.Tasks, safe.Field(oldObj, func(oldObj *Struct) TaskList { return oldObj.Tasks }))...)
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
var zeroOrOneOfMembershipFor_k8s_io_code_generator_cmd_validation_gen_output_tests_tags_item_zerorooneof_typedef_TaskList_ = validate.NewUnionMembership([2]string{"TaskList[{\"name\": \"succeeded\"}]", ""}, [2]string{"TaskList[{\"name\": \"failed\"}]", ""})
|
||||
|
||||
func Validate_TaskList(ctx context.Context, op operation.Operation, fldPath *field.Path, obj, oldObj TaskList) (errs field.ErrorList) {
|
||||
// type TaskList
|
||||
if op.Type == operation.Update && equality.Semantic.DeepEqual(obj, oldObj) {
|
||||
return nil // no changes
|
||||
}
|
||||
errs = append(errs, validate.Unique(ctx, op, fldPath, obj, oldObj, func(a Task, b Task) bool { return a.Name == b.Name })...)
|
||||
errs = append(errs, validate.ZeroOrOneOfUnion(ctx, op, fldPath, obj, oldObj, zeroOrOneOfMembershipFor_k8s_io_code_generator_cmd_validation_gen_output_tests_tags_item_zerorooneof_typedef_TaskList_, func(list TaskList) bool {
|
||||
for i := range list {
|
||||
if list[i].Name == "failed" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}, func(list TaskList) bool {
|
||||
for i := range list {
|
||||
if list[i].Name == "succeeded" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
})...)
|
||||
|
||||
return errs
|
||||
}
|
||||
Reference in New Issue
Block a user