From 8f984328637f7cd381e113422fee56d7823d9596 Mon Sep 17 00:00:00 2001 From: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> Date: Wed, 19 Mar 2025 19:07:47 +0530 Subject: [PATCH 01/19] pkg simpleschema: adds SimpleSchema enum support Signed-off-by: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> --- pkg/simpleschema/markers.go | 5 ++- pkg/simpleschema/transform.go | 40 +++++++++++++++++++++ pkg/simpleschema/transform_test.go | 58 ++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/pkg/simpleschema/markers.go b/pkg/simpleschema/markers.go index d422b48d1..b1045d409 100644 --- a/pkg/simpleschema/markers.go +++ b/pkg/simpleschema/markers.go @@ -50,12 +50,15 @@ const ( MarkerTypeMinimum MarkerType = "minimum" // MarkerTypeMaximum represents the `maximum` marker. MarkerTypeMaximum MarkerType = "maximum" + + // MarkerTypeEnum represents the `enum` marker. + MarkerTypeEnum MarkerType = "enum" ) func markerTypeFromString(s string) (MarkerType, error) { switch MarkerType(s) { case MarkerTypeRequired, MarkerTypeDefault, MarkerTypeDescription, - MarkerTypeMinimum, MarkerTypeMaximum: + MarkerTypeMinimum, MarkerTypeMaximum, MarkerTypeEnum: return MarkerType(s), nil default: return "", fmt.Errorf("unknown marker type: %s", s) diff --git a/pkg/simpleschema/transform.go b/pkg/simpleschema/transform.go index 7218e76ce..49c9feb81 100644 --- a/pkg/simpleschema/transform.go +++ b/pkg/simpleschema/transform.go @@ -16,6 +16,7 @@ package simpleschema import ( "fmt" "strconv" + "strings" extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" ) @@ -212,6 +213,45 @@ func (tf *transformer) applyMarkers(schema *extv1.JSONSchemaProps, markers []*Ma if val, err := strconv.ParseFloat(marker.Value, 64); err == nil { schema.Maximum = &val } + case MarkerTypeEnum: + enumValues := strings.Split(marker.Value, ",") + + var enumJsonValues []extv1.JSON + + for _, val := range enumValues { + val = strings.TrimSpace(val) + var rawValue []byte + + switch schema.Type { + case "string": + rawValue = []byte(fmt.Sprintf("\"%s\"", val)) + case "integer": + if _, err := strconv.ParseInt(val, 10, 64); err == nil { + rawValue = []byte(val) + enumJsonValues = append(enumJsonValues, extv1.JSON{Raw: rawValue}) + continue + } + case "number": + if _, err := strconv.ParseInt(val, 10, 64); err == nil { + rawValue = []byte(val) + enumJsonValues = append(enumJsonValues, extv1.JSON{Raw: rawValue}) + continue + } + case "boolean": + if val == "true" || val == "false" { + rawValue = []byte(val) + enumJsonValues = append(enumJsonValues, extv1.JSON{Raw: rawValue}) + continue + } + default: + rawValue = []byte(val) + enumJsonValues = append(enumJsonValues, extv1.JSON{Raw: rawValue}) + } + enumJsonValues = append(enumJsonValues, extv1.JSON{Raw: rawValue}) + } + if len(enumJsonValues) > 0 { + schema.Enum = enumJsonValues + } } } } diff --git a/pkg/simpleschema/transform_test.go b/pkg/simpleschema/transform_test.go index 425866a55..08bd58fc2 100644 --- a/pkg/simpleschema/transform_test.go +++ b/pkg/simpleschema/transform_test.go @@ -279,6 +279,64 @@ func TestBuildOpenAPISchema(t *testing.T) { }, wantErr: false, }, + { + name: "Schema with multiple enum types", + obj: map[string]interface{}{ + "logLevel": "string | enum=\"debug,info,warn,error\" default=\"info\"", + "features": map[string]interface{}{ + "debugMode": "boolean | enum=\"true,false\" default=false", + "logFormat": "string | enum=\"json,text,csv\" default=\"json\"", + "errorCode": "integer | enum=\"400,404,500\" default=500", + }, + }, + want: &extv1.JSONSchemaProps{ + Type: "object", + Properties: map[string]extv1.JSONSchemaProps{ + "logLevel": { + Type: "string", + Default: &extv1.JSON{Raw: []byte("\"info\"")}, + Enum: []extv1.JSON{ + {Raw: []byte("\"debug\"")}, + {Raw: []byte("\"info\"")}, + {Raw: []byte("\"warn\"")}, + {Raw: []byte("\"error\"")}, + }, + }, + "features": { + Type: "object", + Properties: map[string]extv1.JSONSchemaProps{ + "debugMode": { + Type: "boolean", + Default: &extv1.JSON{Raw: []byte("false")}, + Enum: []extv1.JSON{ + {Raw: []byte("true")}, + {Raw: []byte("false")}, + }, + }, + "logFormat": { + Type: "string", + Default: &extv1.JSON{Raw: []byte("\"json\"")}, + Enum: []extv1.JSON{ + {Raw: []byte("\"json\"")}, + {Raw: []byte("\"text\"")}, + {Raw: []byte("\"csv\"")}, + }, + }, + "errorCode": { + Type: "integer", + Default: &extv1.JSON{Raw: []byte("500")}, + Enum: []extv1.JSON{ + {Raw: []byte("400")}, + {Raw: []byte("404")}, + {Raw: []byte("500")}, + }, + }, + }, + }, + }, + }, + wantErr: false, + }, } for _, tt := range tests { From c9b401942d23d6cc158e366c5f5a36cb7336a80a Mon Sep 17 00:00:00 2001 From: Dhairya Majmudar <124715224+DhairyaMajmudar@users.noreply.github.com> Date: Thu, 20 Mar 2025 10:50:15 +0530 Subject: [PATCH 02/19] Update pkg/simpleschema/markers.go Co-authored-by: Amine --- pkg/simpleschema/markers.go | 1 - 1 file changed, 1 deletion(-) diff --git a/pkg/simpleschema/markers.go b/pkg/simpleschema/markers.go index b1045d409..3072352b4 100644 --- a/pkg/simpleschema/markers.go +++ b/pkg/simpleschema/markers.go @@ -50,7 +50,6 @@ const ( MarkerTypeMinimum MarkerType = "minimum" // MarkerTypeMaximum represents the `maximum` marker. MarkerTypeMaximum MarkerType = "maximum" - // MarkerTypeEnum represents the `enum` marker. MarkerTypeEnum MarkerType = "enum" ) From cf40d1db43acca43638bf94767864657bb4d1cf6 Mon Sep 17 00:00:00 2001 From: Dhairya Majmudar <124715224+DhairyaMajmudar@users.noreply.github.com> Date: Thu, 20 Mar 2025 10:50:50 +0530 Subject: [PATCH 03/19] Update pkg/simpleschema/transform.go Co-authored-by: Matthew Christopher --- pkg/simpleschema/transform.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/simpleschema/transform.go b/pkg/simpleschema/transform.go index 49c9feb81..5c7dbee1d 100644 --- a/pkg/simpleschema/transform.go +++ b/pkg/simpleschema/transform.go @@ -216,7 +216,7 @@ func (tf *transformer) applyMarkers(schema *extv1.JSONSchemaProps, markers []*Ma case MarkerTypeEnum: enumValues := strings.Split(marker.Value, ",") - var enumJsonValues []extv1.JSON + var enumJSONValues []extv1.JSON for _, val := range enumValues { val = strings.TrimSpace(val) From f4dff31f18e30389388a64748ed46a1fa149859e Mon Sep 17 00:00:00 2001 From: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> Date: Thu, 20 Mar 2025 10:52:52 +0530 Subject: [PATCH 04/19] enumJsonValues -> enumJSONValues --- pkg/simpleschema/transform.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/simpleschema/transform.go b/pkg/simpleschema/transform.go index 5c7dbee1d..c52f10861 100644 --- a/pkg/simpleschema/transform.go +++ b/pkg/simpleschema/transform.go @@ -228,29 +228,29 @@ func (tf *transformer) applyMarkers(schema *extv1.JSONSchemaProps, markers []*Ma case "integer": if _, err := strconv.ParseInt(val, 10, 64); err == nil { rawValue = []byte(val) - enumJsonValues = append(enumJsonValues, extv1.JSON{Raw: rawValue}) + enumJSONValues = append(enumJSONValues, extv1.JSON{Raw: rawValue}) continue } case "number": if _, err := strconv.ParseInt(val, 10, 64); err == nil { rawValue = []byte(val) - enumJsonValues = append(enumJsonValues, extv1.JSON{Raw: rawValue}) + enumJSONValues = append(enumJSONValues, extv1.JSON{Raw: rawValue}) continue } case "boolean": if val == "true" || val == "false" { rawValue = []byte(val) - enumJsonValues = append(enumJsonValues, extv1.JSON{Raw: rawValue}) + enumJSONValues = append(enumJSONValues, extv1.JSON{Raw: rawValue}) continue } default: rawValue = []byte(val) - enumJsonValues = append(enumJsonValues, extv1.JSON{Raw: rawValue}) + enumJSONValues = append(enumJSONValues, extv1.JSON{Raw: rawValue}) } - enumJsonValues = append(enumJsonValues, extv1.JSON{Raw: rawValue}) + enumJSONValues = append(enumJSONValues, extv1.JSON{Raw: rawValue}) } - if len(enumJsonValues) > 0 { - schema.Enum = enumJsonValues + if len(enumJSONValues) > 0 { + schema.Enum = enumJSONValues } } } From ee57ea0783a0c90936fb49bd69adde1bd98df7f1 Mon Sep 17 00:00:00 2001 From: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> Date: Thu, 20 Mar 2025 11:20:30 +0530 Subject: [PATCH 05/19] fix: removed boolean enum Signed-off-by: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> --- pkg/simpleschema/transform.go | 6 ------ pkg/simpleschema/transform_test.go | 9 --------- 2 files changed, 15 deletions(-) diff --git a/pkg/simpleschema/transform.go b/pkg/simpleschema/transform.go index c52f10861..21cb7f696 100644 --- a/pkg/simpleschema/transform.go +++ b/pkg/simpleschema/transform.go @@ -237,12 +237,6 @@ func (tf *transformer) applyMarkers(schema *extv1.JSONSchemaProps, markers []*Ma enumJSONValues = append(enumJSONValues, extv1.JSON{Raw: rawValue}) continue } - case "boolean": - if val == "true" || val == "false" { - rawValue = []byte(val) - enumJSONValues = append(enumJSONValues, extv1.JSON{Raw: rawValue}) - continue - } default: rawValue = []byte(val) enumJSONValues = append(enumJSONValues, extv1.JSON{Raw: rawValue}) diff --git a/pkg/simpleschema/transform_test.go b/pkg/simpleschema/transform_test.go index 08bd58fc2..bf9765a7e 100644 --- a/pkg/simpleschema/transform_test.go +++ b/pkg/simpleschema/transform_test.go @@ -284,7 +284,6 @@ func TestBuildOpenAPISchema(t *testing.T) { obj: map[string]interface{}{ "logLevel": "string | enum=\"debug,info,warn,error\" default=\"info\"", "features": map[string]interface{}{ - "debugMode": "boolean | enum=\"true,false\" default=false", "logFormat": "string | enum=\"json,text,csv\" default=\"json\"", "errorCode": "integer | enum=\"400,404,500\" default=500", }, @@ -305,14 +304,6 @@ func TestBuildOpenAPISchema(t *testing.T) { "features": { Type: "object", Properties: map[string]extv1.JSONSchemaProps{ - "debugMode": { - Type: "boolean", - Default: &extv1.JSON{Raw: []byte("false")}, - Enum: []extv1.JSON{ - {Raw: []byte("true")}, - {Raw: []byte("false")}, - }, - }, "logFormat": { Type: "string", Default: &extv1.JSON{Raw: []byte("\"json\"")}, From 5db9e88ba900b9682fe647184dafc4fb7ea012ae Mon Sep 17 00:00:00 2001 From: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> Date: Thu, 20 Mar 2025 12:11:53 +0530 Subject: [PATCH 06/19] fea: adding better error handling Signed-off-by: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> --- pkg/simpleschema/transform.go | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/pkg/simpleschema/transform.go b/pkg/simpleschema/transform.go index 21cb7f696..750ae2360 100644 --- a/pkg/simpleschema/transform.go +++ b/pkg/simpleschema/transform.go @@ -117,7 +117,9 @@ func (tf *transformer) parseFieldSchema(key, fieldValue string, parentSchema *ex fieldJSONSchemaProps = &preDefinedType } - tf.applyMarkers(fieldJSONSchemaProps, markers, key, parentSchema) + if err := tf.applyMarkers(fieldJSONSchemaProps, markers, key, parentSchema); err != nil { + return nil, fmt.Errorf("failed to apply markers: %w", err) + } return fieldJSONSchemaProps, nil } @@ -185,7 +187,7 @@ func (tf *transformer) handleSliceType(key, fieldType string) (*extv1.JSONSchema return fieldJSONSchemaProps, nil } -func (tf *transformer) applyMarkers(schema *extv1.JSONSchemaProps, markers []*Marker, key string, parentSchema *extv1.JSONSchemaProps) { +func (tf *transformer) applyMarkers(schema *extv1.JSONSchemaProps, markers []*Marker, key string, parentSchema *extv1.JSONSchemaProps) error { for _, marker := range markers { switch marker.MarkerType { case MarkerTypeRequired: @@ -206,11 +208,15 @@ func (tf *transformer) applyMarkers(schema *extv1.JSONSchemaProps, markers []*Ma case MarkerTypeDescription: schema.Description = marker.Value case MarkerTypeMinimum: - if val, err := strconv.ParseFloat(marker.Value, 64); err == nil { + if val, err := strconv.ParseFloat(marker.Value, 64); err != nil { + return fmt.Errorf("failed to parse minimum enum value: %w", err) + } else { schema.Minimum = &val } case MarkerTypeMaximum: - if val, err := strconv.ParseFloat(marker.Value, 64); err == nil { + if val, err := strconv.ParseFloat(marker.Value, 64); err != nil { + return fmt.Errorf("failed to parse maximum enum value: %w", err) + } else { schema.Maximum = &val } case MarkerTypeEnum: @@ -226,20 +232,20 @@ func (tf *transformer) applyMarkers(schema *extv1.JSONSchemaProps, markers []*Ma case "string": rawValue = []byte(fmt.Sprintf("\"%s\"", val)) case "integer": - if _, err := strconv.ParseInt(val, 10, 64); err == nil { + if _, err := strconv.ParseInt(val, 10, 64); err != nil { + return fmt.Errorf("failed to parse integer enum value: %w", err) + } else { rawValue = []byte(val) - enumJSONValues = append(enumJSONValues, extv1.JSON{Raw: rawValue}) - continue } + case "number": - if _, err := strconv.ParseInt(val, 10, 64); err == nil { + if _, err := strconv.ParseInt(val, 10, 64); err != nil { + return fmt.Errorf("failed to parse number enum value: %w", err) + } else { rawValue = []byte(val) - enumJSONValues = append(enumJSONValues, extv1.JSON{Raw: rawValue}) - continue } default: rawValue = []byte(val) - enumJSONValues = append(enumJSONValues, extv1.JSON{Raw: rawValue}) } enumJSONValues = append(enumJSONValues, extv1.JSON{Raw: rawValue}) } @@ -248,6 +254,7 @@ func (tf *transformer) applyMarkers(schema *extv1.JSONSchemaProps, markers []*Ma } } } + return nil } // Other functions (LoadPreDefinedTypes, transformMap) remain unchanged From 74fd90c0c87f18cdc0272db0bf758b71b517d3e3 Mon Sep 17 00:00:00 2001 From: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> Date: Thu, 20 Mar 2025 14:58:35 +0530 Subject: [PATCH 07/19] tests: adding tests cases for number type Signed-off-by: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> --- pkg/simpleschema/atomic.go | 4 +++- pkg/simpleschema/transform.go | 3 +-- pkg/simpleschema/transform_test.go | 10 ++++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/pkg/simpleschema/atomic.go b/pkg/simpleschema/atomic.go index 2238c3036..3ae3ad96e 100644 --- a/pkg/simpleschema/atomic.go +++ b/pkg/simpleschema/atomic.go @@ -34,11 +34,13 @@ const ( AtomicTypeFloat AtomicType = "float" // AtomicTypeString represents a string value. AtomicTypeString AtomicType = "string" + // AtomicTypeNumber represents a number value. + AtomicTypeNumber AtomicType = "number" ) func isAtomicType(s string) bool { switch AtomicType(s) { - case AtomicTypeBool, AtomicTypeInteger, AtomicTypeFloat, AtomicTypeString: + case AtomicTypeBool, AtomicTypeInteger, AtomicTypeFloat, AtomicTypeString, AtomicTypeNumber: return true default: return false diff --git a/pkg/simpleschema/transform.go b/pkg/simpleschema/transform.go index 750ae2360..3f566ac48 100644 --- a/pkg/simpleschema/transform.go +++ b/pkg/simpleschema/transform.go @@ -237,9 +237,8 @@ func (tf *transformer) applyMarkers(schema *extv1.JSONSchemaProps, markers []*Ma } else { rawValue = []byte(val) } - case "number": - if _, err := strconv.ParseInt(val, 10, 64); err != nil { + if _, err := strconv.ParseFloat(val, 64); err != nil { return fmt.Errorf("failed to parse number enum value: %w", err) } else { rawValue = []byte(val) diff --git a/pkg/simpleschema/transform_test.go b/pkg/simpleschema/transform_test.go index bf9765a7e..667068c1a 100644 --- a/pkg/simpleschema/transform_test.go +++ b/pkg/simpleschema/transform_test.go @@ -286,6 +286,7 @@ func TestBuildOpenAPISchema(t *testing.T) { "features": map[string]interface{}{ "logFormat": "string | enum=\"json,text,csv\" default=\"json\"", "errorCode": "integer | enum=\"400,404,500\" default=500", + "threshold": "number | enum=\"1.2,2.0,0.1\" default=0.1", }, }, want: &extv1.JSONSchemaProps{ @@ -322,6 +323,15 @@ func TestBuildOpenAPISchema(t *testing.T) { {Raw: []byte("500")}, }, }, + "threshold": { + Type: "number", + Default: &extv1.JSON{Raw: []byte("0.1")}, + Enum: []extv1.JSON{ + {Raw: []byte("1.2")}, + {Raw: []byte("2.0")}, + {Raw: []byte("0.1")}, + }, + }, }, }, }, From 763c707d013ee6b4b35bef01041131c8baf1980e Mon Sep 17 00:00:00 2001 From: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> Date: Thu, 20 Mar 2025 15:02:28 +0530 Subject: [PATCH 08/19] tests: added negative test cases to check invalid enum Signed-off-by: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> --- pkg/simpleschema/transform_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkg/simpleschema/transform_test.go b/pkg/simpleschema/transform_test.go index 667068c1a..87a5c8a8b 100644 --- a/pkg/simpleschema/transform_test.go +++ b/pkg/simpleschema/transform_test.go @@ -338,6 +338,14 @@ func TestBuildOpenAPISchema(t *testing.T) { }, wantErr: false, }, + { + name: "invalid enum type", + obj: map[string]interface{}{ + "threshold": "number | enum=\"1.0,1.5,three\"", + }, + want: nil, + wantErr: true, + }, } for _, tt := range tests { From 821e34365ac78a7fa143243a260189b98a2e5603 Mon Sep 17 00:00:00 2001 From: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> Date: Thu, 20 Mar 2025 22:18:29 +0530 Subject: [PATCH 09/19] test: added test to check empty enum Signed-off-by: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> --- pkg/simpleschema/transform_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/simpleschema/transform_test.go b/pkg/simpleschema/transform_test.go index 87a5c8a8b..f77e48a2e 100644 --- a/pkg/simpleschema/transform_test.go +++ b/pkg/simpleschema/transform_test.go @@ -341,6 +341,7 @@ func TestBuildOpenAPISchema(t *testing.T) { { name: "invalid enum type", obj: map[string]interface{}{ + "errorCode": "int | enum=\"1,,3\"", "threshold": "number | enum=\"1.0,1.5,three\"", }, want: nil, From 987c78f3fa564269dad3eb191c779979eddb556c Mon Sep 17 00:00:00 2001 From: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> Date: Thu, 20 Mar 2025 22:34:54 +0530 Subject: [PATCH 10/19] test: seperating empty test case Signed-off-by: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> --- pkg/simpleschema/transform_test.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pkg/simpleschema/transform_test.go b/pkg/simpleschema/transform_test.go index f77e48a2e..85321c0b2 100644 --- a/pkg/simpleschema/transform_test.go +++ b/pkg/simpleschema/transform_test.go @@ -341,12 +341,19 @@ func TestBuildOpenAPISchema(t *testing.T) { { name: "invalid enum type", obj: map[string]interface{}{ - "errorCode": "int | enum=\"1,,3\"", "threshold": "number | enum=\"1.0,1.5,three\"", }, want: nil, wantErr: true, }, + { + name: "empty enum type", + obj: map[string]interface{}{ + "errorCode": "int | enum=\"1,,3\"", + }, + want: nil, + wantErr: true, + }, } for _, tt := range tests { From 58d2f70b72f43e722f83ac7bc15eff6cac6e9a3a Mon Sep 17 00:00:00 2001 From: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> Date: Sat, 22 Mar 2025 11:55:59 +0530 Subject: [PATCH 11/19] fixes: removed number case Signed-off-by: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> --- pkg/simpleschema/atomic.go | 4 +--- pkg/simpleschema/transform.go | 8 +------- pkg/simpleschema/transform_test.go | 14 ++------------ 3 files changed, 4 insertions(+), 22 deletions(-) diff --git a/pkg/simpleschema/atomic.go b/pkg/simpleschema/atomic.go index 3ae3ad96e..2238c3036 100644 --- a/pkg/simpleschema/atomic.go +++ b/pkg/simpleschema/atomic.go @@ -34,13 +34,11 @@ const ( AtomicTypeFloat AtomicType = "float" // AtomicTypeString represents a string value. AtomicTypeString AtomicType = "string" - // AtomicTypeNumber represents a number value. - AtomicTypeNumber AtomicType = "number" ) func isAtomicType(s string) bool { switch AtomicType(s) { - case AtomicTypeBool, AtomicTypeInteger, AtomicTypeFloat, AtomicTypeString, AtomicTypeNumber: + case AtomicTypeBool, AtomicTypeInteger, AtomicTypeFloat, AtomicTypeString: return true default: return false diff --git a/pkg/simpleschema/transform.go b/pkg/simpleschema/transform.go index 3f566ac48..4e34e6e75 100644 --- a/pkg/simpleschema/transform.go +++ b/pkg/simpleschema/transform.go @@ -237,14 +237,8 @@ func (tf *transformer) applyMarkers(schema *extv1.JSONSchemaProps, markers []*Ma } else { rawValue = []byte(val) } - case "number": - if _, err := strconv.ParseFloat(val, 64); err != nil { - return fmt.Errorf("failed to parse number enum value: %w", err) - } else { - rawValue = []byte(val) - } default: - rawValue = []byte(val) + return fmt.Errorf("enum values only supported for string and integer types, got type: %s", schema.Type) } enumJSONValues = append(enumJSONValues, extv1.JSON{Raw: rawValue}) } diff --git a/pkg/simpleschema/transform_test.go b/pkg/simpleschema/transform_test.go index 85321c0b2..37e48554c 100644 --- a/pkg/simpleschema/transform_test.go +++ b/pkg/simpleschema/transform_test.go @@ -286,7 +286,6 @@ func TestBuildOpenAPISchema(t *testing.T) { "features": map[string]interface{}{ "logFormat": "string | enum=\"json,text,csv\" default=\"json\"", "errorCode": "integer | enum=\"400,404,500\" default=500", - "threshold": "number | enum=\"1.2,2.0,0.1\" default=0.1", }, }, want: &extv1.JSONSchemaProps{ @@ -323,15 +322,6 @@ func TestBuildOpenAPISchema(t *testing.T) { {Raw: []byte("500")}, }, }, - "threshold": { - Type: "number", - Default: &extv1.JSON{Raw: []byte("0.1")}, - Enum: []extv1.JSON{ - {Raw: []byte("1.2")}, - {Raw: []byte("2.0")}, - {Raw: []byte("0.1")}, - }, - }, }, }, }, @@ -341,7 +331,7 @@ func TestBuildOpenAPISchema(t *testing.T) { { name: "invalid enum type", obj: map[string]interface{}{ - "threshold": "number | enum=\"1.0,1.5,three\"", + "threshold": "integer | enum=\"1,2,three\"", }, want: nil, wantErr: true, @@ -349,7 +339,7 @@ func TestBuildOpenAPISchema(t *testing.T) { { name: "empty enum type", obj: map[string]interface{}{ - "errorCode": "int | enum=\"1,,3\"", + "errorCode": "integer | enum=\"1,,3\"", }, want: nil, wantErr: true, From 0202c60fbf8a1c74b7aef239e82abd03b02a2153 Mon Sep 17 00:00:00 2001 From: Dhairya Majmudar <124715224+DhairyaMajmudar@users.noreply.github.com> Date: Sat, 22 Mar 2025 12:08:34 +0530 Subject: [PATCH 12/19] Update pkg/simpleschema/transform.go Co-authored-by: Amine --- pkg/simpleschema/transform.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/simpleschema/transform.go b/pkg/simpleschema/transform.go index 4e34e6e75..c409d9d87 100644 --- a/pkg/simpleschema/transform.go +++ b/pkg/simpleschema/transform.go @@ -234,9 +234,8 @@ func (tf *transformer) applyMarkers(schema *extv1.JSONSchemaProps, markers []*Ma case "integer": if _, err := strconv.ParseInt(val, 10, 64); err != nil { return fmt.Errorf("failed to parse integer enum value: %w", err) - } else { - rawValue = []byte(val) } + rawValue = []byte(val) default: return fmt.Errorf("enum values only supported for string and integer types, got type: %s", schema.Type) } From e0bedbe64e9ab3823d321d7222a1f0ba40fc07be Mon Sep 17 00:00:00 2001 From: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> Date: Sat, 22 Mar 2025 12:30:04 +0530 Subject: [PATCH 13/19] fix: skiping empty strings and added a test case Signed-off-by: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> --- pkg/simpleschema/transform.go | 5 +++++ pkg/simpleschema/transform_test.go | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/pkg/simpleschema/transform.go b/pkg/simpleschema/transform.go index c409d9d87..3706a03a8 100644 --- a/pkg/simpleschema/transform.go +++ b/pkg/simpleschema/transform.go @@ -226,6 +226,11 @@ func (tf *transformer) applyMarkers(schema *extv1.JSONSchemaProps, markers []*Ma for _, val := range enumValues { val = strings.TrimSpace(val) + + if val == "" { + return fmt.Errorf("empty enum values are not allowed") + } + var rawValue []byte switch schema.Type { diff --git a/pkg/simpleschema/transform_test.go b/pkg/simpleschema/transform_test.go index 37e48554c..22c8c3494 100644 --- a/pkg/simpleschema/transform_test.go +++ b/pkg/simpleschema/transform_test.go @@ -337,13 +337,21 @@ func TestBuildOpenAPISchema(t *testing.T) { wantErr: true, }, { - name: "empty enum type", + name: "empty enum integer type", obj: map[string]interface{}{ "errorCode": "integer | enum=\"1,,3\"", }, want: nil, wantErr: true, }, + { + name: "string enum with empty values", + obj: map[string]interface{}{ + "status": "string | enum=\"a,b,,c\"", + }, + want: nil, + wantErr: true, + }, } for _, tt := range tests { From affdf659ddd31b1e2eaf36810245120fad03f745 Mon Sep 17 00:00:00 2001 From: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> Date: Sat, 22 Mar 2025 12:33:56 +0530 Subject: [PATCH 14/19] fix: removing extra changes Signed-off-by: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> --- pkg/simpleschema/transform.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/pkg/simpleschema/transform.go b/pkg/simpleschema/transform.go index 3706a03a8..43134eebe 100644 --- a/pkg/simpleschema/transform.go +++ b/pkg/simpleschema/transform.go @@ -208,15 +208,11 @@ func (tf *transformer) applyMarkers(schema *extv1.JSONSchemaProps, markers []*Ma case MarkerTypeDescription: schema.Description = marker.Value case MarkerTypeMinimum: - if val, err := strconv.ParseFloat(marker.Value, 64); err != nil { - return fmt.Errorf("failed to parse minimum enum value: %w", err) - } else { + if val, err := strconv.ParseFloat(marker.Value, 64); err == nil { schema.Minimum = &val } case MarkerTypeMaximum: - if val, err := strconv.ParseFloat(marker.Value, 64); err != nil { - return fmt.Errorf("failed to parse maximum enum value: %w", err) - } else { + if val, err := strconv.ParseFloat(marker.Value, 64); err == nil { schema.Maximum = &val } case MarkerTypeEnum: From 4e9f8b49b847deca0ae1885f54f411e458378822 Mon Sep 17 00:00:00 2001 From: Dhairya Majmudar <124715224+DhairyaMajmudar@users.noreply.github.com> Date: Sat, 22 Mar 2025 13:28:45 +0530 Subject: [PATCH 15/19] Update pkg/simpleschema/transform.go Co-authored-by: Amine --- pkg/simpleschema/transform.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/simpleschema/transform.go b/pkg/simpleschema/transform.go index 43134eebe..e6b2470f9 100644 --- a/pkg/simpleschema/transform.go +++ b/pkg/simpleschema/transform.go @@ -231,7 +231,7 @@ func (tf *transformer) applyMarkers(schema *extv1.JSONSchemaProps, markers []*Ma switch schema.Type { case "string": - rawValue = []byte(fmt.Sprintf("\"%s\"", val)) + rawValue = []byte(fmt.Sprintf("%q", val)) case "integer": if _, err := strconv.ParseInt(val, 10, 64); err != nil { return fmt.Errorf("failed to parse integer enum value: %w", err) From 088fad1cc71daae760b54f10ebff4df0d5274906 Mon Sep 17 00:00:00 2001 From: Dhairya Majmudar <124715224+DhairyaMajmudar@users.noreply.github.com> Date: Sat, 22 Mar 2025 13:28:59 +0530 Subject: [PATCH 16/19] Update pkg/simpleschema/transform_test.go Co-authored-by: Amine --- pkg/simpleschema/transform_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/simpleschema/transform_test.go b/pkg/simpleschema/transform_test.go index 22c8c3494..4afd3cfb2 100644 --- a/pkg/simpleschema/transform_test.go +++ b/pkg/simpleschema/transform_test.go @@ -337,7 +337,7 @@ func TestBuildOpenAPISchema(t *testing.T) { wantErr: true, }, { - name: "empty enum integer type", + name: "Invalid integer enum marker", obj: map[string]interface{}{ "errorCode": "integer | enum=\"1,,3\"", }, From 66846b9920bbed1e7bf550a123e252cf36a114cf Mon Sep 17 00:00:00 2001 From: Dhairya Majmudar <124715224+DhairyaMajmudar@users.noreply.github.com> Date: Sat, 22 Mar 2025 13:29:11 +0530 Subject: [PATCH 17/19] Update pkg/simpleschema/transform_test.go Co-authored-by: Amine --- pkg/simpleschema/transform_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/simpleschema/transform_test.go b/pkg/simpleschema/transform_test.go index 4afd3cfb2..62843135e 100644 --- a/pkg/simpleschema/transform_test.go +++ b/pkg/simpleschema/transform_test.go @@ -345,7 +345,7 @@ func TestBuildOpenAPISchema(t *testing.T) { wantErr: true, }, { - name: "string enum with empty values", + name: "invalid string enum marker", obj: map[string]interface{}{ "status": "string | enum=\"a,b,,c\"", }, From f0c4621056c288b199602fed1e144db206199ff8 Mon Sep 17 00:00:00 2001 From: Dhairya Majmudar <124715224+DhairyaMajmudar@users.noreply.github.com> Date: Sat, 22 Mar 2025 13:29:31 +0530 Subject: [PATCH 18/19] Update pkg/simpleschema/transform.go Co-authored-by: Amine --- pkg/simpleschema/transform.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/pkg/simpleschema/transform.go b/pkg/simpleschema/transform.go index e6b2470f9..e66d86114 100644 --- a/pkg/simpleschema/transform.go +++ b/pkg/simpleschema/transform.go @@ -216,19 +216,16 @@ func (tf *transformer) applyMarkers(schema *extv1.JSONSchemaProps, markers []*Ma schema.Maximum = &val } case MarkerTypeEnum: - enumValues := strings.Split(marker.Value, ",") - var enumJSONValues []extv1.JSON + enumValues := strings.Split(marker.Value, ",") for _, val := range enumValues { val = strings.TrimSpace(val) - if val == "" { return fmt.Errorf("empty enum values are not allowed") } - + var rawValue []byte - switch schema.Type { case "string": rawValue = []byte(fmt.Sprintf("%q", val)) From 8ee044d7bfabc125e930874027310c1e211a8779 Mon Sep 17 00:00:00 2001 From: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> Date: Sat, 22 Mar 2025 13:46:09 +0530 Subject: [PATCH 19/19] tests: adds test cases for invalid enum Signed-off-by: Dhairya Majmudar <2022kuec2045@iiitkota.ac.in> --- pkg/simpleschema/transform.go | 2 +- pkg/simpleschema/transform_test.go | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/pkg/simpleschema/transform.go b/pkg/simpleschema/transform.go index e66d86114..8bddbcd93 100644 --- a/pkg/simpleschema/transform.go +++ b/pkg/simpleschema/transform.go @@ -224,7 +224,7 @@ func (tf *transformer) applyMarkers(schema *extv1.JSONSchemaProps, markers []*Ma if val == "" { return fmt.Errorf("empty enum values are not allowed") } - + var rawValue []byte switch schema.Type { case "string": diff --git a/pkg/simpleschema/transform_test.go b/pkg/simpleschema/transform_test.go index 62843135e..1cca3f689 100644 --- a/pkg/simpleschema/transform_test.go +++ b/pkg/simpleschema/transform_test.go @@ -337,13 +337,21 @@ func TestBuildOpenAPISchema(t *testing.T) { wantErr: true, }, { - name: "Invalid integer enum marker", + name: "Invalid integer enum - empty values", obj: map[string]interface{}{ "errorCode": "integer | enum=\"1,,3\"", }, want: nil, wantErr: true, }, + { + name: "Invalid integer enum - parsing failure", + obj: map[string]interface{}{ + "errorCode": "integer | enum=\"1,2,3,abc\"", + }, + want: nil, + wantErr: true, + }, { name: "invalid string enum marker", obj: map[string]interface{}{