From eaa2abf3cf47cdc8e59e6f039bc0e08e16bb4c66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20S=2E=20Garz=C3=A3o?= Date: Sat, 27 Sep 2025 20:06:26 -0300 Subject: [PATCH 1/6] feat: type struct to deal with complex types (array, slice) --- internal/common/types.go | 21 +++++ internal/common/types_test.go | 66 ++++++++++++++ internal/common/utils.go | 11 +-- internal/common/utils_test.go | 161 ++++++++++++++++++++++++++++++++++ 4 files changed, 251 insertions(+), 8 deletions(-) create mode 100644 internal/common/types.go create mode 100644 internal/common/types_test.go create mode 100644 internal/common/utils_test.go diff --git a/internal/common/types.go b/internal/common/types.go new file mode 100644 index 0000000..c37f2d3 --- /dev/null +++ b/internal/common/types.go @@ -0,0 +1,21 @@ +package common + +type FieldType struct { + ComposedType string // array ([N]), map (map) or slice ([]) + BaseType string // base type (e.g. string, int, etc.) + Size string // for arrays + // IsGoType bool // true if is a Go built-in type +} + +func (ft FieldType) ToString() string { + switch ft.ComposedType { + case "[N]": + return "[N]" + ft.BaseType + case "[]": + return "[]" + ft.BaseType + case "map": + return "map[" + ft.BaseType + "]" + } + + return ft.BaseType +} diff --git a/internal/common/types_test.go b/internal/common/types_test.go new file mode 100644 index 0000000..50b4ca0 --- /dev/null +++ b/internal/common/types_test.go @@ -0,0 +1,66 @@ +package common + +import "testing" + +func TestFieldType_ToString(t *testing.T) { + type fields struct { + ComposedType string + BaseType string + Size string + } + tests := []struct { + name string + fields fields + want string + }{ + { + name: "base type", + fields: fields{ + ComposedType: "", + BaseType: "string", + Size: "", + }, + want: "string", + }, + { + name: "array type", + fields: fields{ + ComposedType: "[N]", + BaseType: "string", + Size: "5", + }, + want: "[N]string", + }, + { + name: "slice type", + fields: fields{ + ComposedType: "[]", + BaseType: "string", + Size: "", + }, + want: "[]string", + }, + { + name: "map type", + fields: fields{ + ComposedType: "map", + BaseType: "string", + Size: "", + }, + want: "map[string]", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ft := FieldType{ + ComposedType: tt.fields.ComposedType, + BaseType: tt.fields.BaseType, + Size: tt.fields.Size, + } + if got := ft.ToString(); got != tt.want { + t.Errorf("FieldType.ToString() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/internal/common/utils.go b/internal/common/utils.go index 18243ad..01a6ec7 100644 --- a/internal/common/utils.go +++ b/internal/common/utils.go @@ -2,15 +2,11 @@ package common import "strings" -func IsGoType(fieldType string) bool { - if strings.HasPrefix(fieldType, "map[") { - // REFACTOR! +func IsGoType(fieldType FieldType) bool { + if fieldType.ComposedType == "map" { return true } - fieldType = strings.TrimPrefix(fieldType, "[]") - fieldType = strings.TrimPrefix(fieldType, "[N]") - goTypes := map[string]struct{}{ "string": {}, "bool": {}, @@ -28,10 +24,9 @@ func IsGoType(fieldType string) bool { // "float64": {}, // "complex64": {}, // "complex128": {}, - "map": {}, } - _, ok := goTypes[fieldType] + _, ok := goTypes[fieldType.BaseType] return ok } diff --git a/internal/common/utils_test.go b/internal/common/utils_test.go new file mode 100644 index 0000000..fe3382f --- /dev/null +++ b/internal/common/utils_test.go @@ -0,0 +1,161 @@ +package common + +import ( + "testing" +) + +func TestExtractPackage(t *testing.T) { + type args struct { + fieldType string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "no package", + args: args{ + fieldType: "string", + }, + want: "", + }, + { + name: "with package", + args: args{ + fieldType: "mypkg.MyType", + }, + want: "mypkg", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := ExtractPackage(tt.args.fieldType); got != tt.want { + t.Errorf("ExtractPackage() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestKeyPath(t *testing.T) { + type args struct { + values []string + } + tests := []struct { + name string + args args + want string + }{ + { + name: "single value", + args: args{ + values: []string{"field"}, + }, + want: "field", + }, + { + name: "multiple values", + args: args{ + values: []string{"field1", "field2", "field3"}, + }, + want: "field1.field2.field3", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := KeyPath(tt.args.values...); got != tt.want { + t.Errorf("KeyPath() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestIsGoType(t *testing.T) { + type args struct { + fieldType FieldType + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "basic type", + args: args{ + fieldType: FieldType{BaseType: "string", ComposedType: "", Size: ""}, + }, + want: true, + }, + { + name: "array type", + args: args{ + fieldType: FieldType{BaseType: "string", ComposedType: "[N]", Size: "5"}, + }, + want: true, + }, + { + name: "slice type", + args: args{ + fieldType: FieldType{BaseType: "string", ComposedType: "[]", Size: ""}, + }, + want: true, + }, + { + name: "map type", + args: args{ + fieldType: FieldType{BaseType: "string", ComposedType: "map", Size: ""}, + }, + want: true, + }, + { + name: "custom type", + args: args{ + fieldType: FieldType{BaseType: "MyType", ComposedType: "", Size: ""}, + }, + want: false, + }, + { + name: "pointer type", + args: args{ + fieldType: FieldType{BaseType: "*MyType", ComposedType: "", Size: ""}, + }, + want: false, + }, + // { + // name: "pointer to basic type", + // args: args{ + // fieldType: FieldType{BaseType: "*string", ComposedType: "", Size: ""}, + // }, + // want: true, + // }, + { + name: "struct type", + args: args{ + fieldType: FieldType{BaseType: "MyStruct", ComposedType: "", Size: ""}, + }, + want: false, + }, + // { + // name: "interface type", + // args: args{ + // fieldType: FieldType{BaseType: "interface{}", ComposedType: "", Size: ""}, + // }, + // want: true, + // }, + // { + // name: "complex type", + // args: args{ + // fieldType: FieldType{BaseType: "map[string][]*MyType", ComposedType: "", Size: ""}, + // }, + // want: true, + // }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := IsGoType(tt.args.fieldType); got != tt.want { + t.Errorf("IsGoType() = %v, want %v", got, tt.want) + } + }) + } +} From c80a58467e066f599bb02d1ddab914c055a119b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20S=2E=20Garz=C3=A3o?= Date: Sat, 27 Sep 2025 20:18:48 -0300 Subject: [PATCH 2/6] chore: use FieldType instead of string --- internal/analyzer/analyzer.go | 8 +-- internal/analyzer/analyzer_test.go | 35 ++++++------ internal/analyzer/operations_test.go | 3 +- .../build_func_validator_test.go | 15 ++--- internal/codegenerator/build_validator.go | 16 +++--- .../codegenerator/build_validator_test.go | 49 +++++++++-------- .../get_test_elements_array_test.go | 12 ++-- .../get_test_elements_between_fields_test.go | 42 +++++++------- .../get_test_elements_bool_test.go | 4 +- .../get_test_elements_errors_test.go | 5 +- .../get_test_elements_map_test.go | 28 +++++----- .../get_test_elements_numeric_test.go | 10 ++-- .../get_test_elements_slice_test.go | 20 ++++--- .../get_test_elements_string_test.go | 4 +- internal/codegenerator/test_elements.go | 15 ++--- internal/parser/parser.go | 53 +++++++----------- internal/parser/parser_test.go | 55 ++++++++++--------- internal/parser/struct.go | 4 +- internal/pkgwriter/file_validator_test.go | 7 ++- 19 files changed, 194 insertions(+), 191 deletions(-) diff --git a/internal/analyzer/analyzer.go b/internal/analyzer/analyzer.go index ee7d3c5..9bf863d 100644 --- a/internal/analyzer/analyzer.go +++ b/internal/analyzer/analyzer.go @@ -89,8 +89,8 @@ func checkForInvalidOperations(structs []*Struct) error { // Check if is a valid operation for this type. fdType := fd.Type - if common.IsGoType(fdType) && !operations[op].ValidTypes[fdType] { - return types.NewValidationError("operation %s: invalid %s type", op, fdType) + if common.IsGoType(fdType) && !operations[op].ValidTypes[fdType.ToString()] { + return types.NewValidationError("operation %s: invalid %s type", op, fdType.BaseType) } } } @@ -102,7 +102,7 @@ func checkForInvalidOperations(structs []*Struct) error { func analyzeFieldOperations(structs []*Struct) error { // Map all fields and their types. - fieldsType := map[string]string{} + fieldsType := map[string]common.FieldType{} for _, st := range structs { for _, fd := range st.Fields { fieldsType[common.KeyPath(st.PackageName, st.StructName, fd.FieldName)] = fd.Type @@ -133,7 +133,7 @@ func analyzeFieldOperations(structs []*Struct) error { if !ok { return types.NewValidationError("operation %s: undefined nested field %s", op, qualifiedField) } - fd2NameToSearch = common.KeyPath(qFieldType, qualifiedNestedField) + fd2NameToSearch = common.KeyPath(qFieldType.BaseType, qualifiedNestedField) } f2Type, ok := fieldsType[fd2NameToSearch] diff --git a/internal/analyzer/analyzer_test.go b/internal/analyzer/analyzer_test.go index 3746033..e8b2bd1 100644 --- a/internal/analyzer/analyzer_test.go +++ b/internal/analyzer/analyzer_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + "github.com/opencodeco/validgen/internal/common" "github.com/opencodeco/validgen/internal/parser" "github.com/opencodeco/validgen/types" ) @@ -63,12 +64,12 @@ func TestAnalyzeStructsWithValidInnerFieldOperations(t *testing.T) { Fields: []parser.Field{ { FieldName: "Field1", - Type: tt.fType, + Type: common.FieldType{BaseType: tt.fType}, Tag: fmt.Sprintf(`valid:"%s=Field2"`, tt.op), }, { FieldName: "Field2", - Type: tt.fType, + Type: common.FieldType{BaseType: tt.fType}, Tag: ``, }, }, @@ -141,12 +142,12 @@ func TestAnalyzeStructsWithValidNestedFieldOperations(t *testing.T) { Fields: []parser.Field{ { FieldName: "Field1", - Type: tt.fType, + Type: common.FieldType{BaseType: tt.fType}, Tag: fmt.Sprintf(`valid:"%s=Nested.Field2"`, tt.op), }, { FieldName: "Nested", - Type: "main.NestedStruct", + Type: common.FieldType{BaseType: "main.NestedStruct"}, Tag: ``, }, }, @@ -157,7 +158,7 @@ func TestAnalyzeStructsWithValidNestedFieldOperations(t *testing.T) { Fields: []parser.Field{ { FieldName: "Field2", - Type: tt.fType, + Type: common.FieldType{BaseType: tt.fType}, Tag: ``, }, }, @@ -185,12 +186,12 @@ func TestAnalyzeStructsWithInvalidInnerFieldOperations(t *testing.T) { Fields: []parser.Field{ { FieldName: "Field1", - Type: "string", + Type: common.FieldType{BaseType: "string"}, Tag: `valid:"eqfield=Field2"`, }, { FieldName: "Field2", - Type: "uint8", + Type: common.FieldType{BaseType: "uint8"}, Tag: ``, }, }, @@ -203,7 +204,7 @@ func TestAnalyzeStructsWithInvalidInnerFieldOperations(t *testing.T) { Fields: []parser.Field{ { FieldName: "Field1", - Type: "string", + Type: common.FieldType{BaseType: "string"}, Tag: `valid:"eqfield=Field2"`, }, }, @@ -216,12 +217,12 @@ func TestAnalyzeStructsWithInvalidInnerFieldOperations(t *testing.T) { Fields: []parser.Field{ { FieldName: "Field1", - Type: "string", + Type: common.FieldType{BaseType: "string"}, Tag: `valid:"ltfield=Field2"`, }, { FieldName: "Field2", - Type: "string", + Type: common.FieldType{BaseType: "string"}, Tag: ``, }, }, @@ -256,12 +257,12 @@ func TestAnalyzeStructsWithInvalidNestedFieldOperations(t *testing.T) { Fields: []parser.Field{ { FieldName: "Field1", - Type: "string", + Type: common.FieldType{BaseType: "string"}, Tag: `valid:"eqfield=Nested.Field2"`, }, { FieldName: "Nested", - Type: "main.NestedStruct", + Type: common.FieldType{BaseType: "main.NestedStruct"}, Tag: ``, }, }, @@ -272,7 +273,7 @@ func TestAnalyzeStructsWithInvalidNestedFieldOperations(t *testing.T) { Fields: []parser.Field{ { FieldName: "Field2", - Type: "uint8", + Type: common.FieldType{BaseType: "uint8"}, Tag: ``, }, }, @@ -289,7 +290,7 @@ func TestAnalyzeStructsWithInvalidNestedFieldOperations(t *testing.T) { Fields: []parser.Field{ { FieldName: "Field1", - Type: "string", + Type: common.FieldType{BaseType: "string"}, Tag: `valid:"eqfield=Nested.Field2"`, }, }, @@ -306,12 +307,12 @@ func TestAnalyzeStructsWithInvalidNestedFieldOperations(t *testing.T) { Fields: []parser.Field{ { FieldName: "Field1", - Type: "string", + Type: common.FieldType{BaseType: "string"}, Tag: `valid:"ltfield=Nested.Field2"`, }, { FieldName: "Nested", - Type: "main.NestedStruct", + Type: common.FieldType{BaseType: "main.NestedStruct"}, Tag: ``, }, }, @@ -322,7 +323,7 @@ func TestAnalyzeStructsWithInvalidNestedFieldOperations(t *testing.T) { Fields: []parser.Field{ { FieldName: "Field2", - Type: "string", + Type: common.FieldType{BaseType: "string"}, Tag: ``, }, }, diff --git a/internal/analyzer/operations_test.go b/internal/analyzer/operations_test.go index aa96b34..e820edb 100644 --- a/internal/analyzer/operations_test.go +++ b/internal/analyzer/operations_test.go @@ -4,6 +4,7 @@ import ( "fmt" "testing" + "github.com/opencodeco/validgen/internal/common" "github.com/opencodeco/validgen/internal/parser" ) @@ -195,7 +196,7 @@ func TestValidFieldOperationsByType(t *testing.T) { Fields: []parser.Field{ { FieldName: "Field", - Type: tt.fieldType, + Type: common.FieldType{BaseType: tt.fieldType}, Tag: fmt.Sprintf(`valid:"%s"`, tt.op), }, }, diff --git a/internal/codegenerator/build_func_validator_test.go b/internal/codegenerator/build_func_validator_test.go index 9d66b6c..48741a2 100644 --- a/internal/codegenerator/build_func_validator_test.go +++ b/internal/codegenerator/build_func_validator_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/opencodeco/validgen/internal/analyzer" + "github.com/opencodeco/validgen/internal/common" "github.com/opencodeco/validgen/internal/parser" "github.com/sergi/go-diff/diffmatchpatch" ) @@ -27,12 +28,12 @@ func TestBuildFuncValidatorCode(t *testing.T) { Fields: []parser.Field{ { FieldName: "FirstName", - Type: "string", + Type: common.FieldType{BaseType: "string"}, Tag: `validate:"required"`, }, { FieldName: "MyAge", - Type: "uint8", + Type: common.FieldType{BaseType: "uint8"}, Tag: `validate:"required"`, }, }, @@ -69,7 +70,7 @@ return errs Fields: []parser.Field{ { FieldName: "FirstName", - Type: "string", + Type: common.FieldType{BaseType: "string"}, Tag: `validate:"min=5"`, }, }, @@ -100,12 +101,12 @@ return errs Fields: []parser.Field{ { FieldName: "Field1", - Type: "string", + Type: common.FieldType{BaseType: "string"}, Tag: ``, }, { FieldName: "Field2", - Type: "string", + Type: common.FieldType{BaseType: "string"}, Tag: `validate:"neqfield=Field1"`, }, }, @@ -139,12 +140,12 @@ return errs Fields: []parser.Field{ { FieldName: "Field1", - Type: "string", + Type: common.FieldType{BaseType: "string"}, Tag: `validate:"neqfield=Nested.Field2"`, }, { FieldName: "Nested", - Type: "NestedStruct", + Type: common.FieldType{BaseType: "NestedStruct"}, Tag: ``, }, }, diff --git a/internal/codegenerator/build_validator.go b/internal/codegenerator/build_validator.go index f1fb4a9..6a79610 100644 --- a/internal/codegenerator/build_validator.go +++ b/internal/codegenerator/build_validator.go @@ -23,7 +23,7 @@ type structTpl struct { type fieldTpl struct { FieldName string - Type string + Type common.FieldType Validations []*analyzer.Validation } @@ -48,7 +48,7 @@ func (gv *genValidations) BuildFuncValidatorCode() (string, error) { return code.String(), nil } -func (gv *genValidations) buildValidationCode(fieldName, fieldType string, fieldValidations []*analyzer.Validation) (string, error) { +func (gv *genValidations) buildValidationCode(fieldName string, fieldType common.FieldType, fieldValidations []*analyzer.Validation) (string, error) { tests := "" for _, fieldValidation := range fieldValidations { @@ -73,7 +73,7 @@ func (gv *genValidations) buildValidationCode(fieldName, fieldType string, field return tests, nil } -func (gv *genValidations) buildIfCode(fieldName, fieldType string, fieldValidation *analyzer.Validation) (string, error) { +func (gv *genValidations) buildIfCode(fieldName string, fieldType common.FieldType, fieldValidation *analyzer.Validation) (string, error) { testElements, err := DefineTestElements(fieldName, fieldType, fieldValidation) if err != nil { return "", fmt.Errorf("field %s: %w", fieldName, err) @@ -95,18 +95,18 @@ errs = append(errs, types.NewValidationError("%s")) `, booleanCondition, testElements.errorMessage), nil } -func (gv *genValidations) buildIfNestedCode(fieldName, fieldType string) (string, error) { - _, ok := gv.StructsWithValidation[fieldType] +func (gv *genValidations) buildIfNestedCode(fieldName string, fieldType common.FieldType) (string, error) { + _, ok := gv.StructsWithValidation[fieldType.BaseType] if !ok { return "", fmt.Errorf("no validator found for struct type %s", fieldType) } - pkg := common.ExtractPackage(fieldType) + pkg := common.ExtractPackage(fieldType.BaseType) if pkg == gv.Struct.PackageName { - fieldType = strings.TrimPrefix(fieldType, pkg+".") + fieldType.BaseType = strings.TrimPrefix(fieldType.BaseType, pkg+".") } - funcName := fieldType + "Validate" + funcName := fieldType.BaseType + "Validate" fieldParam := "&obj." + fieldName return fmt.Sprintf("errs = append(errs, %s(%s)...)\n", funcName, fieldParam), nil diff --git a/internal/codegenerator/build_validator_test.go b/internal/codegenerator/build_validator_test.go index 0755b7c..f5cde2a 100644 --- a/internal/codegenerator/build_validator_test.go +++ b/internal/codegenerator/build_validator_test.go @@ -4,13 +4,14 @@ import ( "testing" "github.com/opencodeco/validgen/internal/analyzer" + "github.com/opencodeco/validgen/internal/common" "github.com/opencodeco/validgen/internal/parser" ) func TestBuildValidationCode(t *testing.T) { type args struct { fieldName string - fieldType string + fieldType common.FieldType fieldValidation string } tests := []struct { @@ -22,7 +23,7 @@ func TestBuildValidationCode(t *testing.T) { name: "if code with string", args: args{ fieldName: "strField", - fieldType: "string", + fieldType: common.FieldType{BaseType: "string"}, fieldValidation: "eq=abc", }, want: `if !(obj.strField == "abc") { @@ -34,7 +35,7 @@ errs = append(errs, types.NewValidationError("strField must be equal to 'abc'")) name: "if code with uint8", args: args{ fieldName: "intField", - fieldType: "uint8", + fieldType: common.FieldType{BaseType: "uint8"}, fieldValidation: "gte=123", }, want: `if !(obj.intField >= 123) { @@ -46,7 +47,7 @@ errs = append(errs, types.NewValidationError("intField must be >= 123")) name: "if code with string and in", args: args{ fieldName: "strField", - fieldType: "string", + fieldType: common.FieldType{BaseType: "string"}, fieldValidation: "in=a b c", }, want: `if !(obj.strField == "a" || obj.strField == "b" || obj.strField == "c") { @@ -58,7 +59,7 @@ errs = append(errs, types.NewValidationError("strField must be one of 'a' 'b' 'c name: "if code with string and not in", args: args{ fieldName: "strField", - fieldType: "string", + fieldType: common.FieldType{BaseType: "string"}, fieldValidation: "nin=a b c", }, want: `if !(obj.strField != "a" && obj.strField != "b" && obj.strField != "c") { @@ -70,7 +71,7 @@ errs = append(errs, types.NewValidationError("strField must not be one of 'a' 'b name: "Required slice string", args: args{ fieldName: "strField", - fieldType: "[]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[]"}, fieldValidation: "required", }, want: `if !(len(obj.strField) != 0) { @@ -82,7 +83,7 @@ errs = append(errs, types.NewValidationError("strField must not be empty")) name: "Min slice string", args: args{ fieldName: "strField", - fieldType: "[]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[]"}, fieldValidation: "min=2", }, want: `if !(len(obj.strField) >= 2) { @@ -94,7 +95,7 @@ errs = append(errs, types.NewValidationError("strField must have at least 2 elem name: "Max slice string", args: args{ fieldName: "strField", - fieldType: "[]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[]"}, fieldValidation: "max=5", }, want: `if !(len(obj.strField) <= 5) { @@ -106,7 +107,7 @@ errs = append(errs, types.NewValidationError("strField must have at most 5 eleme name: "Len slice string", args: args{ fieldName: "strField", - fieldType: "[]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[]"}, fieldValidation: "len=3", }, want: `if !(len(obj.strField) == 3) { @@ -118,7 +119,7 @@ errs = append(errs, types.NewValidationError("strField must have exactly 3 eleme name: "In slice string", args: args{ fieldName: "strField", - fieldType: "[]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[]"}, fieldValidation: "in=a b c", }, want: `if !(types.SliceOnlyContains(obj.strField, []string{"a", "b", "c"})) { @@ -130,7 +131,7 @@ errs = append(errs, types.NewValidationError("strField elements must be one of ' name: "Not in slice string", args: args{ fieldName: "strField", - fieldType: "[]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[]"}, fieldValidation: "nin=a b c", }, want: `if !(types.SliceNotContains(obj.strField, []string{"a", "b", "c"})) { @@ -143,7 +144,7 @@ errs = append(errs, types.NewValidationError("strField elements must not be one name: "In array string", args: args{ fieldName: "strField", - fieldType: "[N]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[N]"}, fieldValidation: "in=a b c", }, want: `if !(types.SliceOnlyContains(obj.strField[:], []string{"a", "b", "c"})) { @@ -155,7 +156,7 @@ errs = append(errs, types.NewValidationError("strField elements must be one of ' name: "Not in array string", args: args{ fieldName: "strField", - fieldType: "[N]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[N]"}, fieldValidation: "nin=a b c", }, want: `if !(types.SliceNotContains(obj.strField[:], []string{"a", "b", "c"})) { @@ -168,7 +169,7 @@ errs = append(errs, types.NewValidationError("strField elements must not be one name: "inner field operation", args: args{ fieldName: "field1", - fieldType: "string", + fieldType: common.FieldType{BaseType: "string"}, fieldValidation: "eqfield=field2", }, want: `if !(obj.field1 == obj.field2) { @@ -180,7 +181,7 @@ errs = append(errs, types.NewValidationError("field1 must be equal to field2")) name: "nested field operation", args: args{ fieldName: "field1", - fieldType: "string", + fieldType: common.FieldType{BaseType: "string"}, fieldValidation: "eqfield=Nested.field2", }, want: `if !(obj.field1 == obj.Nested.field2) { @@ -193,7 +194,7 @@ errs = append(errs, types.NewValidationError("field1 must be equal to Nested.fie name: "if code with bool", args: args{ fieldName: "boolField", - fieldType: "bool", + fieldType: common.FieldType{BaseType: "bool"}, fieldValidation: "eq=true", }, want: `if !(obj.boolField == true) { @@ -207,7 +208,7 @@ errs = append(errs, types.NewValidationError("boolField must be equal to true")) name: "if code with string map", args: args{ fieldName: "mapField", - fieldType: "map[string]", + fieldType: common.FieldType{BaseType: "string", ComposedType: "map"}, fieldValidation: "len=3", }, want: `if !(len(obj.mapField) == 3) { @@ -219,7 +220,7 @@ errs = append(errs, types.NewValidationError("mapField must have exactly 3 eleme name: "if code with uint8 map", args: args{ fieldName: "mapField", - fieldType: "map[uint8]", + fieldType: common.FieldType{BaseType: "uint8", ComposedType: "map"}, fieldValidation: "len=3", }, want: `if !(len(obj.mapField) == 3) { @@ -248,7 +249,7 @@ errs = append(errs, types.NewValidationError("mapField must have exactly 3 eleme func TestBuildValidationCodeWithNestedStructsAndSlices(t *testing.T) { type args struct { fieldName string - fieldType string + fieldType common.FieldType fieldValidation string } tests := []struct { @@ -260,7 +261,7 @@ func TestBuildValidationCodeWithNestedStructsAndSlices(t *testing.T) { name: "test code with inner struct", args: args{ fieldName: "Field", - fieldType: "main.InnerStructType", + fieldType: common.FieldType{BaseType: "main.InnerStructType"}, fieldValidation: "required", }, want: "errs = append(errs, InnerStructTypeValidate(&obj.Field)...)\n", @@ -269,7 +270,7 @@ func TestBuildValidationCodeWithNestedStructsAndSlices(t *testing.T) { name: "test code with inner struct in another package", args: args{ fieldName: "Field", - fieldType: "mypkg.InnerStructType", + fieldType: common.FieldType{BaseType: "mypkg.InnerStructType"}, fieldValidation: "required", }, want: "errs = append(errs, mypkg.InnerStructTypeValidate(&obj.Field)...)\n", @@ -278,7 +279,7 @@ func TestBuildValidationCodeWithNestedStructsAndSlices(t *testing.T) { name: "test code with required slice of string", args: args{ fieldName: "Field", - fieldType: "[]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[]"}, fieldValidation: "required", }, want: `if !(len(obj.Field) != 0) { @@ -290,7 +291,7 @@ errs = append(errs, types.NewValidationError("Field must not be empty")) name: "test code with min slice of string", args: args{ fieldName: "Field", - fieldType: "[]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[]"}, fieldValidation: "min=2", }, want: `if !(len(obj.Field) >= 2) { @@ -310,7 +311,7 @@ errs = append(errs, types.NewValidationError("Field must have at least 2 element }, StructsWithValidation: map[string]struct{}{}, } - gv.StructsWithValidation[tt.args.fieldType] = struct{}{} + gv.StructsWithValidation[tt.args.fieldType.BaseType] = struct{}{} validation := AssertParserValidation(t, tt.args.fieldValidation) got, err := gv.buildValidationCode(tt.args.fieldName, tt.args.fieldType, []*analyzer.Validation{validation}) if err != nil { diff --git a/internal/codegenerator/get_test_elements_array_test.go b/internal/codegenerator/get_test_elements_array_test.go index 80a773f..f6a9c4e 100644 --- a/internal/codegenerator/get_test_elements_array_test.go +++ b/internal/codegenerator/get_test_elements_array_test.go @@ -3,12 +3,14 @@ package codegenerator import ( "reflect" "testing" + + "github.com/opencodeco/validgen/internal/common" ) func TestDefineTestElementsWithArrayFields(t *testing.T) { type args struct { fieldName string - fieldType string + fieldType common.FieldType fieldValidation string } tests := []struct { @@ -20,7 +22,7 @@ func TestDefineTestElementsWithArrayFields(t *testing.T) { name: "In array string with spaces", args: args{ fieldName: "myfield", - fieldType: "[N]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[N]"}, fieldValidation: "in=a b c", }, want: TestElements{ @@ -33,7 +35,7 @@ func TestDefineTestElementsWithArrayFields(t *testing.T) { name: "In array string with '", args: args{ fieldName: "myfield", - fieldType: "[N]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[N]"}, fieldValidation: "in=' a ' ' b ' ' c '", }, want: TestElements{ @@ -46,7 +48,7 @@ func TestDefineTestElementsWithArrayFields(t *testing.T) { name: "Not in array string with spaces", args: args{ fieldName: "myfield", - fieldType: "[N]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[N]"}, fieldValidation: "nin=a b c", }, want: TestElements{ @@ -59,7 +61,7 @@ func TestDefineTestElementsWithArrayFields(t *testing.T) { name: "Not in array string with '", args: args{ fieldName: "myfield", - fieldType: "[N]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[N]"}, fieldValidation: "nin=' a ' ' b ' ' c '", }, want: TestElements{ diff --git a/internal/codegenerator/get_test_elements_between_fields_test.go b/internal/codegenerator/get_test_elements_between_fields_test.go index 2d75bf6..1ec8225 100644 --- a/internal/codegenerator/get_test_elements_between_fields_test.go +++ b/internal/codegenerator/get_test_elements_between_fields_test.go @@ -3,12 +3,14 @@ package codegenerator import ( "reflect" "testing" + + "github.com/opencodeco/validgen/internal/common" ) func TestDefineTestElementsBetweenInnerFields(t *testing.T) { type args struct { fieldName string - fieldType string + fieldType common.FieldType fieldValidation string } tests := []struct { @@ -20,7 +22,7 @@ func TestDefineTestElementsBetweenInnerFields(t *testing.T) { name: "inner string fields must be equal", args: args{ fieldName: "myfield1", - fieldType: "string", + fieldType: common.FieldType{BaseType: "string"}, fieldValidation: "eqfield=myfield2", }, want: TestElements{ @@ -33,7 +35,7 @@ func TestDefineTestElementsBetweenInnerFields(t *testing.T) { name: "inner string fields must not be equal", args: args{ fieldName: "myfield1", - fieldType: "string", + fieldType: common.FieldType{BaseType: "string"}, fieldValidation: "neqfield=myfield2", }, want: TestElements{ @@ -46,7 +48,7 @@ func TestDefineTestElementsBetweenInnerFields(t *testing.T) { name: "inner uint8 fields must be equal", args: args{ fieldName: "myfield1", - fieldType: "uint8", + fieldType: common.FieldType{BaseType: "uint8"}, fieldValidation: "eqfield=myfield2", }, want: TestElements{ @@ -59,7 +61,7 @@ func TestDefineTestElementsBetweenInnerFields(t *testing.T) { name: "inner uint8 fields must not be equal", args: args{ fieldName: "myfield1", - fieldType: "uint8", + fieldType: common.FieldType{BaseType: "uint8"}, fieldValidation: "neqfield=myfield2", }, want: TestElements{ @@ -72,7 +74,7 @@ func TestDefineTestElementsBetweenInnerFields(t *testing.T) { name: "inner uint8 field must be greater than or equal", args: args{ fieldName: "myfield1", - fieldType: "uint8", + fieldType: common.FieldType{BaseType: "uint8"}, fieldValidation: "gtefield=myfield2", }, want: TestElements{ @@ -85,7 +87,7 @@ func TestDefineTestElementsBetweenInnerFields(t *testing.T) { name: "inner uint8 field must be greater than", args: args{ fieldName: "myfield1", - fieldType: "uint8", + fieldType: common.FieldType{BaseType: "uint8"}, fieldValidation: "gtfield=myfield2", }, want: TestElements{ @@ -98,7 +100,7 @@ func TestDefineTestElementsBetweenInnerFields(t *testing.T) { name: "inner uint8 fields must less than or equal", args: args{ fieldName: "myfield1", - fieldType: "uint8", + fieldType: common.FieldType{BaseType: "uint8"}, fieldValidation: "ltefield=myfield2", }, want: TestElements{ @@ -111,7 +113,7 @@ func TestDefineTestElementsBetweenInnerFields(t *testing.T) { name: "inner uint8 fields must less than", args: args{ fieldName: "myfield1", - fieldType: "uint8", + fieldType: common.FieldType{BaseType: "uint8"}, fieldValidation: "ltfield=myfield2", }, want: TestElements{ @@ -125,7 +127,7 @@ func TestDefineTestElementsBetweenInnerFields(t *testing.T) { name: "inner bool fields must be equal", args: args{ fieldName: "myfield1", - fieldType: "bool", + fieldType: common.FieldType{BaseType: "bool"}, fieldValidation: "eqfield=myfield2", }, want: TestElements{ @@ -138,7 +140,7 @@ func TestDefineTestElementsBetweenInnerFields(t *testing.T) { name: "inner bool fields must not be equal", args: args{ fieldName: "myfield1", - fieldType: "bool", + fieldType: common.FieldType{BaseType: "bool"}, fieldValidation: "neqfield=myfield2", }, want: TestElements{ @@ -168,7 +170,7 @@ func TestDefineTestElementsBetweenInnerFields(t *testing.T) { func TestDefineTestElementsBetweenNestedFields(t *testing.T) { type args struct { fieldName string - fieldType string + fieldType common.FieldType fieldValidation string } tests := []struct { @@ -180,7 +182,7 @@ func TestDefineTestElementsBetweenNestedFields(t *testing.T) { name: "nested string fields must be equal", args: args{ fieldName: "myfield1", - fieldType: "string", + fieldType: common.FieldType{BaseType: "string"}, fieldValidation: "eqfield=nested.myfield2", }, want: TestElements{ @@ -193,7 +195,7 @@ func TestDefineTestElementsBetweenNestedFields(t *testing.T) { name: "nested string fields must not be equal", args: args{ fieldName: "myfield1", - fieldType: "string", + fieldType: common.FieldType{BaseType: "string"}, fieldValidation: "neqfield=nested.myfield2", }, want: TestElements{ @@ -206,7 +208,7 @@ func TestDefineTestElementsBetweenNestedFields(t *testing.T) { name: "nested uint8 fields must be equal", args: args{ fieldName: "myfield1", - fieldType: "uint8", + fieldType: common.FieldType{BaseType: "uint8"}, fieldValidation: "eqfield=nested.myfield2", }, want: TestElements{ @@ -219,7 +221,7 @@ func TestDefineTestElementsBetweenNestedFields(t *testing.T) { name: "nested uint8 fields must not be equal", args: args{ fieldName: "myfield1", - fieldType: "uint8", + fieldType: common.FieldType{BaseType: "uint8"}, fieldValidation: "neqfield=nested.myfield2", }, want: TestElements{ @@ -232,7 +234,7 @@ func TestDefineTestElementsBetweenNestedFields(t *testing.T) { name: "nested uint8 field must be greater than or equal", args: args{ fieldName: "myfield1", - fieldType: "uint8", + fieldType: common.FieldType{BaseType: "uint8"}, fieldValidation: "gtefield=nested.myfield2", }, want: TestElements{ @@ -245,7 +247,7 @@ func TestDefineTestElementsBetweenNestedFields(t *testing.T) { name: "nested uint8 field must be greater than", args: args{ fieldName: "myfield1", - fieldType: "uint8", + fieldType: common.FieldType{BaseType: "uint8"}, fieldValidation: "gtfield=nested.myfield2", }, want: TestElements{ @@ -258,7 +260,7 @@ func TestDefineTestElementsBetweenNestedFields(t *testing.T) { name: "nested uint8 fields must less than or equal", args: args{ fieldName: "myfield1", - fieldType: "uint8", + fieldType: common.FieldType{BaseType: "uint8"}, fieldValidation: "ltefield=nested.myfield2", }, want: TestElements{ @@ -271,7 +273,7 @@ func TestDefineTestElementsBetweenNestedFields(t *testing.T) { name: "nested uint8 fields must less than", args: args{ fieldName: "myfield1", - fieldType: "uint8", + fieldType: common.FieldType{BaseType: "uint8"}, fieldValidation: "ltfield=nested.myfield2", }, want: TestElements{ diff --git a/internal/codegenerator/get_test_elements_bool_test.go b/internal/codegenerator/get_test_elements_bool_test.go index 138a84a..f5a5636 100644 --- a/internal/codegenerator/get_test_elements_bool_test.go +++ b/internal/codegenerator/get_test_elements_bool_test.go @@ -3,6 +3,8 @@ package codegenerator import ( "reflect" "testing" + + "github.com/opencodeco/validgen/internal/common" ) func TestDefineTestElementsWithBoolFields(t *testing.T) { @@ -41,7 +43,7 @@ func TestDefineTestElementsWithBoolFields(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - fieldType := "bool" + fieldType := common.FieldType{BaseType: "bool"} wantErr := false validation := AssertParserValidation(t, tt.args.fieldValidation) got, err := DefineTestElements(tt.args.fieldName, fieldType, validation) diff --git a/internal/codegenerator/get_test_elements_errors_test.go b/internal/codegenerator/get_test_elements_errors_test.go index 39716e0..86fe291 100644 --- a/internal/codegenerator/get_test_elements_errors_test.go +++ b/internal/codegenerator/get_test_elements_errors_test.go @@ -4,13 +4,14 @@ import ( "errors" "testing" + "github.com/opencodeco/validgen/internal/common" "github.com/opencodeco/validgen/types" ) func TestDefineTestElementsWithInvalidOperations(t *testing.T) { type args struct { fieldName string - fieldType string + fieldType common.FieldType fieldValidation string } tests := []struct { @@ -22,7 +23,7 @@ func TestDefineTestElementsWithInvalidOperations(t *testing.T) { name: "invalid uint8 operation", args: args{ fieldName: "xpto", - fieldType: "uint8", + fieldType: common.FieldType{BaseType: "uint8"}, fieldValidation: "in=1 2 3", }, expectedErr: types.NewValidationError("INTERNAL ERROR: unsupported operation in type uint8"), diff --git a/internal/codegenerator/get_test_elements_map_test.go b/internal/codegenerator/get_test_elements_map_test.go index b5a7912..a0cb3c5 100644 --- a/internal/codegenerator/get_test_elements_map_test.go +++ b/internal/codegenerator/get_test_elements_map_test.go @@ -3,12 +3,14 @@ package codegenerator import ( "reflect" "testing" + + "github.com/opencodeco/validgen/internal/common" ) func TestDefineTestElementsWithMapFields(t *testing.T) { type args struct { fieldName string - fieldType string + fieldType common.FieldType fieldValidation string } tests := []struct { @@ -21,7 +23,7 @@ func TestDefineTestElementsWithMapFields(t *testing.T) { name: "required string map", args: args{ fieldName: "myfield", - fieldType: "map[string]", + fieldType: common.FieldType{BaseType: "string", ComposedType: "map"}, fieldValidation: "required", }, want: TestElements{ @@ -33,7 +35,7 @@ func TestDefineTestElementsWithMapFields(t *testing.T) { name: "len string map", args: args{ fieldName: "myfield", - fieldType: "map[string]", + fieldType: common.FieldType{BaseType: "string", ComposedType: "map"}, fieldValidation: "len=3", }, want: TestElements{ @@ -45,7 +47,7 @@ func TestDefineTestElementsWithMapFields(t *testing.T) { name: "min string map", args: args{ fieldName: "myfield", - fieldType: "map[string]", + fieldType: common.FieldType{BaseType: "string", ComposedType: "map"}, fieldValidation: "min=2", }, want: TestElements{ @@ -57,7 +59,7 @@ func TestDefineTestElementsWithMapFields(t *testing.T) { name: "max string map", args: args{ fieldName: "myfield", - fieldType: "map[string]", + fieldType: common.FieldType{BaseType: "string", ComposedType: "map"}, fieldValidation: "max=5", }, want: TestElements{ @@ -69,7 +71,7 @@ func TestDefineTestElementsWithMapFields(t *testing.T) { name: "in string map", args: args{ fieldName: "myfield", - fieldType: "map[string]", + fieldType: common.FieldType{BaseType: "string", ComposedType: "map"}, fieldValidation: "in=1 2 3", }, want: TestElements{ @@ -81,7 +83,7 @@ func TestDefineTestElementsWithMapFields(t *testing.T) { name: "nin string map", args: args{ fieldName: "myfield", - fieldType: "map[string]", + fieldType: common.FieldType{BaseType: "string", ComposedType: "map"}, fieldValidation: "nin=1 2 3", }, want: TestElements{ @@ -95,7 +97,7 @@ func TestDefineTestElementsWithMapFields(t *testing.T) { name: "required uint8 map", args: args{ fieldName: "myfield", - fieldType: "map[uint8]", + fieldType: common.FieldType{BaseType: "uint8", ComposedType: "map"}, fieldValidation: "required", }, want: TestElements{ @@ -107,7 +109,7 @@ func TestDefineTestElementsWithMapFields(t *testing.T) { name: "len uint8 map", args: args{ fieldName: "myfield", - fieldType: "map[uint8]", + fieldType: common.FieldType{BaseType: "uint8", ComposedType: "map"}, fieldValidation: "len=3", }, want: TestElements{ @@ -119,7 +121,7 @@ func TestDefineTestElementsWithMapFields(t *testing.T) { name: "min uint8 map", args: args{ fieldName: "myfield", - fieldType: "map[uint8]", + fieldType: common.FieldType{BaseType: "uint8", ComposedType: "map"}, fieldValidation: "min=2", }, want: TestElements{ @@ -131,7 +133,7 @@ func TestDefineTestElementsWithMapFields(t *testing.T) { name: "max uint8 map", args: args{ fieldName: "myfield", - fieldType: "map[uint8]", + fieldType: common.FieldType{BaseType: "uint8", ComposedType: "map"}, fieldValidation: "max=5", }, want: TestElements{ @@ -143,7 +145,7 @@ func TestDefineTestElementsWithMapFields(t *testing.T) { name: "in uint8 map", args: args{ fieldName: "myfield", - fieldType: "map[uint8]", + fieldType: common.FieldType{BaseType: "uint8", ComposedType: "map"}, fieldValidation: "in=1 2 3", }, want: TestElements{ @@ -155,7 +157,7 @@ func TestDefineTestElementsWithMapFields(t *testing.T) { name: "nin uint8 map", args: args{ fieldName: "myfield", - fieldType: "map[uint8]", + fieldType: common.FieldType{BaseType: "uint8", ComposedType: "map"}, fieldValidation: "nin=1 2 3", }, want: TestElements{ diff --git a/internal/codegenerator/get_test_elements_numeric_test.go b/internal/codegenerator/get_test_elements_numeric_test.go index 0925707..f90a426 100644 --- a/internal/codegenerator/get_test_elements_numeric_test.go +++ b/internal/codegenerator/get_test_elements_numeric_test.go @@ -3,12 +3,14 @@ package codegenerator import ( "reflect" "testing" + + "github.com/opencodeco/validgen/internal/common" ) func TestDefineTestElementsWithNumericFields(t *testing.T) { type args struct { fieldName string - fieldType string + fieldType common.FieldType fieldValidation string } tests := []struct { @@ -21,7 +23,7 @@ func TestDefineTestElementsWithNumericFields(t *testing.T) { name: "Required uint8", args: args{ fieldName: "myfield2", - fieldType: "uint8", + fieldType: common.FieldType{BaseType: "uint8"}, fieldValidation: "required", }, want: TestElements{ @@ -34,7 +36,7 @@ func TestDefineTestElementsWithNumericFields(t *testing.T) { name: "uint8 >= 0", args: args{ fieldName: "myfield3", - fieldType: "uint8", + fieldType: common.FieldType{BaseType: "uint8"}, fieldValidation: "gte=0", }, want: TestElements{ @@ -47,7 +49,7 @@ func TestDefineTestElementsWithNumericFields(t *testing.T) { name: "uint8 <= 130", args: args{ fieldName: "myfield4", - fieldType: "uint8", + fieldType: common.FieldType{BaseType: "uint8"}, fieldValidation: "lte=130", }, want: TestElements{ diff --git a/internal/codegenerator/get_test_elements_slice_test.go b/internal/codegenerator/get_test_elements_slice_test.go index 5c99e7c..b69704a 100644 --- a/internal/codegenerator/get_test_elements_slice_test.go +++ b/internal/codegenerator/get_test_elements_slice_test.go @@ -3,12 +3,14 @@ package codegenerator import ( "reflect" "testing" + + "github.com/opencodeco/validgen/internal/common" ) func TestDefineTestElementsWithSliceFields(t *testing.T) { type args struct { fieldName string - fieldType string + fieldType common.FieldType fieldValidation string } tests := []struct { @@ -20,7 +22,7 @@ func TestDefineTestElementsWithSliceFields(t *testing.T) { name: "Required slice string", args: args{ fieldName: "myfield", - fieldType: "[]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[]"}, fieldValidation: "required", }, want: TestElements{ @@ -32,7 +34,7 @@ func TestDefineTestElementsWithSliceFields(t *testing.T) { name: "Min slice string", args: args{ fieldName: "myfield", - fieldType: "[]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[]"}, fieldValidation: "min=2", }, want: TestElements{ @@ -44,7 +46,7 @@ func TestDefineTestElementsWithSliceFields(t *testing.T) { name: "Max slice string", args: args{ fieldName: "myfield", - fieldType: "[]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[]"}, fieldValidation: "max=5", }, want: TestElements{ @@ -56,7 +58,7 @@ func TestDefineTestElementsWithSliceFields(t *testing.T) { name: "Len slice string", args: args{ fieldName: "myfield", - fieldType: "[]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[]"}, fieldValidation: "len=3", }, want: TestElements{ @@ -68,7 +70,7 @@ func TestDefineTestElementsWithSliceFields(t *testing.T) { name: "In slice string with spaces", args: args{ fieldName: "myfield", - fieldType: "[]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[]"}, fieldValidation: "in=a b c", }, want: TestElements{ @@ -81,7 +83,7 @@ func TestDefineTestElementsWithSliceFields(t *testing.T) { name: "In slice string with '", args: args{ fieldName: "myfield", - fieldType: "[]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[]"}, fieldValidation: "in=' a ' ' b ' ' c '", }, want: TestElements{ @@ -94,7 +96,7 @@ func TestDefineTestElementsWithSliceFields(t *testing.T) { name: "Not in slice string with spaces", args: args{ fieldName: "myfield", - fieldType: "[]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[]"}, fieldValidation: "nin=a b c", }, want: TestElements{ @@ -107,7 +109,7 @@ func TestDefineTestElementsWithSliceFields(t *testing.T) { name: "Not in slice string with '", args: args{ fieldName: "myfield", - fieldType: "[]string", + fieldType: common.FieldType{BaseType: "string", ComposedType: "[]"}, fieldValidation: "nin=' a ' ' b ' ' c '", }, want: TestElements{ diff --git a/internal/codegenerator/get_test_elements_string_test.go b/internal/codegenerator/get_test_elements_string_test.go index 21a2919..af81d6a 100644 --- a/internal/codegenerator/get_test_elements_string_test.go +++ b/internal/codegenerator/get_test_elements_string_test.go @@ -3,6 +3,8 @@ package codegenerator import ( "reflect" "testing" + + "github.com/opencodeco/validgen/internal/common" ) func TestDefineTestElementsWithStringFields(t *testing.T) { @@ -154,7 +156,7 @@ func TestDefineTestElementsWithStringFields(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - fieldType := "string" + fieldType := common.FieldType{BaseType: "string"} wantErr := false validation := AssertParserValidation(t, tt.args.fieldValidation) got, err := DefineTestElements(tt.args.fieldName, fieldType, validation) diff --git a/internal/codegenerator/test_elements.go b/internal/codegenerator/test_elements.go index 86a7c5f..7bc2daf 100644 --- a/internal/codegenerator/test_elements.go +++ b/internal/codegenerator/test_elements.go @@ -4,6 +4,7 @@ import ( "strings" "github.com/opencodeco/validgen/internal/analyzer" + "github.com/opencodeco/validgen/internal/common" "github.com/opencodeco/validgen/types" ) @@ -13,16 +14,16 @@ type TestElements struct { errorMessage string } -func DefineTestElements(fieldName, fieldType string, fieldValidation *analyzer.Validation) (TestElements, error) { +func DefineTestElements(fieldName string, fieldType common.FieldType, fieldValidation *analyzer.Validation) (TestElements, error) { op, ok := operationTable[fieldValidation.Operation] if !ok { return TestElements{}, types.NewValidationError("INTERNAL ERROR: unsupported operation %s", fieldValidation.Operation) } - condition, ok := op.ConditionByType[fieldType] + condition, ok := op.ConditionByType[fieldType.ToString()] if !ok { - return TestElements{}, types.NewValidationError("INTERNAL ERROR: unsupported operation %s type %s", fieldValidation.Operation, fieldType) + return TestElements{}, types.NewValidationError("INTERNAL ERROR: unsupported operation %s type %s", fieldValidation.Operation, fieldType.BaseType) } values := fieldValidation.Values @@ -36,13 +37,7 @@ func DefineTestElements(fieldName, fieldType string, fieldValidation *analyzer.V targetValue = condition.operation targetValues = "'" + condition.operation + "' " case analyzer.ONE_VALUE, analyzer.MANY_VALUES: - // TODO: refactor: When parsing, divide the type into Literal Type (array, map, etc.), Elemental Type (base type), and size (for arrays). - // Code below split basic type from slices and maps - basicType := strings.TrimPrefix(fieldType, "[N]") - basicType = strings.TrimPrefix(basicType, "[]") - basicType = strings.TrimPrefix(basicType, "map[") - basicType = strings.TrimSuffix(basicType, "]") - valuesAsNumericSlice, valuesAsStringSlice := normalizeSlicesAsCode(basicType, values) + valuesAsNumericSlice, valuesAsStringSlice := normalizeSlicesAsCode(fieldType.BaseType, values) for _, value := range values { operation := replaceNameAndTarget(condition.operation, fieldName, value) diff --git a/internal/parser/parser.go b/internal/parser/parser.go index c8701a1..6717c3e 100644 --- a/internal/parser/parser.go +++ b/internal/parser/parser.go @@ -147,7 +147,7 @@ func appendFields(structType *ast.StructType, packageName string, cstruct *Struc for _, field := range structType.Fields.List { appendFieldNames := false - fieldType := "" + fieldType := common.FieldType{} fieldTag := "" if field.Tag != nil { fieldTag = field.Tag.Value @@ -155,17 +155,19 @@ func appendFields(structType *ast.StructType, packageName string, cstruct *Struc switch v := field.Type.(type) { case *ast.Ident: - fieldType = v.Name + fieldType.BaseType = v.Name fieldType, fieldTag = extractFieldTypeAndTag(packageName, fieldType, fieldTag) appendFieldNames = true case *ast.ArrayType: - fieldType = v.Elt.(*ast.Ident).Name - arraySize := "" + fieldType.ComposedType = "[]" + fieldType.BaseType = v.Elt.(*ast.Ident).Name + fieldType.Size = "" if v.Len != nil { - arraySize = v.Len.(*ast.BasicLit).Value + fieldType.Size = v.Len.(*ast.BasicLit).Value + fieldType.ComposedType = "[N]" } - fieldType, fieldTag = extractSliceFieldTypeAndTag(packageName, fieldType, arraySize, fieldTag) + fieldType, fieldTag = extractFieldTypeAndTag(packageName, fieldType, fieldTag) appendFieldNames = true case *ast.SelectorExpr: @@ -174,7 +176,8 @@ func appendFields(structType *ast.StructType, packageName string, cstruct *Struc appendFieldNames = true case *ast.MapType: - fieldType = fmt.Sprintf("map[%s]", v.Key.(*ast.Ident).Name) + fieldType.ComposedType = "map" + fieldType.BaseType = v.Key.(*ast.Ident).Name _, fieldTag = extractFieldTypeAndTag(packageName, fieldType, fieldTag) appendFieldNames = true } @@ -191,11 +194,11 @@ func appendFields(structType *ast.StructType, packageName string, cstruct *Struc } } -func extractFieldTypeAndTag(packageName, fieldType, fieldTag string) (string, string) { +func extractFieldTypeAndTag(packageName string, fieldType common.FieldType, fieldTag string) (common.FieldType, string) { rFieldType := fieldType if !common.IsGoType(fieldType) { - rFieldType = common.KeyPath(packageName, fieldType) + rFieldType.BaseType = common.KeyPath(packageName, fieldType.BaseType) } rFieldTag := "" @@ -207,31 +210,13 @@ func extractFieldTypeAndTag(packageName, fieldType, fieldTag string) (string, st return rFieldType, rFieldTag } -func extractSliceFieldTypeAndTag(packageName, fieldType, fieldSize, fieldTag string) (string, string) { - rFieldType := fieldType - - if !common.IsGoType(fieldType) { - rFieldType = common.KeyPath(packageName, fieldType) - } - - if fieldSize != "" { - fieldSize = "N" - } - - rFieldType = "[" + fieldSize + "]" + rFieldType - - rFieldTag := "" - if fieldTag != "" { - rFieldTag = fieldTag - rFieldTag, _ = strconv.Unquote(rFieldTag) - } - - return rFieldType, rFieldTag -} - -func extractNestedFieldTypeAndTag(nestedPkgName, fieldType, fieldTag string) (string, string) { - rFieldType := common.KeyPath(nestedPkgName, fieldType) +func extractNestedFieldTypeAndTag(nestedPkgName, baseType, fieldTag string) (common.FieldType, string) { + rFieldType := common.KeyPath(nestedPkgName, baseType) rFieldTag, _ := strconv.Unquote(fieldTag) - return rFieldType, rFieldTag + return common.FieldType{ + BaseType: rFieldType, + ComposedType: "", + Size: "", + }, rFieldTag } diff --git a/internal/parser/parser_test.go b/internal/parser/parser_test.go index 19b113f..906f890 100644 --- a/internal/parser/parser_test.go +++ b/internal/parser/parser_test.go @@ -4,6 +4,7 @@ import ( "reflect" "testing" + "github.com/opencodeco/validgen/internal/common" "github.com/sergi/go-diff/diffmatchpatch" ) @@ -52,27 +53,27 @@ func TestParseStructsOk(t *testing.T) { Fields: []Field{ { FieldName: "FirstName", - Type: "string", + Type: common.FieldType{BaseType: "string", ComposedType: "", Size: ""}, Tag: "valid:\"required\"", }, { FieldName: "LastName", - Type: "string", + Type: common.FieldType{BaseType: "string", ComposedType: "", Size: ""}, Tag: "valid:\"required\"", }, { FieldName: "Age", - Type: "uint8", + Type: common.FieldType{BaseType: "uint8", ComposedType: "", Size: ""}, Tag: "valid:\"gte=18,lte=130\"", }, { FieldName: "UserName", - Type: "string", + Type: common.FieldType{BaseType: "string", ComposedType: "", Size: ""}, Tag: "valid:\"min=5,max=10\"", }, { FieldName: "Optional", - Type: "string", + Type: common.FieldType{BaseType: "string", ComposedType: "", Size: ""}, Tag: "", }, }, @@ -106,12 +107,12 @@ func TestParseStructsOk(t *testing.T) { Fields: []Field{ { FieldName: "FirstName", - Type: "string", + Type: common.FieldType{BaseType: "string", ComposedType: "", Size: ""}, Tag: "valid:\"required\"", }, { FieldName: "LastName", - Type: "string", + Type: common.FieldType{BaseType: "string", ComposedType: "", Size: ""}, Tag: "valid:\"required\"", }, }, @@ -124,12 +125,12 @@ func TestParseStructsOk(t *testing.T) { Fields: []Field{ { FieldName: "Field1", - Type: "string", + Type: common.FieldType{BaseType: "string", ComposedType: "", Size: ""}, Tag: "", }, { FieldName: "Field2", - Type: "uint8", + Type: common.FieldType{BaseType: "uint8", ComposedType: "", Size: ""}, Tag: "", }, }, @@ -161,17 +162,17 @@ func TestParseStructsOk(t *testing.T) { Fields: []Field{ { FieldName: "FirstName", - Type: "string", + Type: common.FieldType{BaseType: "string", ComposedType: "", Size: ""}, Tag: "valid:\"required\"", }, { FieldName: "LastName", - Type: "string", + Type: common.FieldType{BaseType: "string", ComposedType: "", Size: ""}, Tag: "valid:\"required\"", }, { FieldName: "Address", - Type: "inpkg.TypeAddress", + Type: common.FieldType{BaseType: "inpkg.TypeAddress", ComposedType: "", Size: ""}, Tag: "valid:\"required\"", }, }, @@ -211,17 +212,17 @@ func TestParseStructsOk(t *testing.T) { Fields: []Field{ { FieldName: "FirstName", - Type: "string", + Type: common.FieldType{BaseType: "string", ComposedType: "", Size: ""}, Tag: "valid:\"required\"", }, { FieldName: "LastName", - Type: "string", + Type: common.FieldType{BaseType: "string", ComposedType: "", Size: ""}, Tag: "valid:\"required\"", }, { FieldName: "Address", - Type: "main.TypeAddress", + Type: common.FieldType{BaseType: "main.TypeAddress", ComposedType: "", Size: ""}, Tag: "valid:\"required\"", }, }, @@ -234,12 +235,12 @@ func TestParseStructsOk(t *testing.T) { Fields: []Field{ { FieldName: "Street", - Type: "string", + Type: common.FieldType{BaseType: "string", ComposedType: "", Size: ""}, Tag: "valid:\"required\"", }, { FieldName: "City", - Type: "string", + Type: common.FieldType{BaseType: "string", ComposedType: "", Size: ""}, Tag: "valid:\"required\"", }, }, @@ -269,12 +270,12 @@ func TestParseStructsOk(t *testing.T) { Fields: []Field{ { FieldName: "FirstName", - Type: "string", + Type: common.FieldType{BaseType: "string", ComposedType: "", Size: ""}, Tag: "valid:\"required\"", }, { FieldName: "Types", - Type: "[]string", + Type: common.FieldType{BaseType: "string", ComposedType: "[]", Size: ""}, Tag: "valid:\"required\"", }, }, @@ -304,12 +305,12 @@ func TestParseStructsOk(t *testing.T) { Fields: []Field{ { FieldName: "FirstName", - Type: "string", + Type: common.FieldType{BaseType: "string", ComposedType: "", Size: ""}, Tag: "valid:\"required\"", }, { FieldName: "Types", - Type: "[N]string", + Type: common.FieldType{BaseType: "string", ComposedType: "[N]", Size: "5"}, Tag: "valid:\"in=a b c\"", }, }, @@ -339,12 +340,12 @@ func TestParseStructsOk(t *testing.T) { Fields: []Field{ { FieldName: "IsCorrect", - Type: "bool", + Type: common.FieldType{BaseType: "bool", ComposedType: "", Size: ""}, Tag: "valid:\"eq=true\"", }, { FieldName: "IsNotCorrect", - Type: "bool", + Type: common.FieldType{BaseType: "bool", ComposedType: "", Size: ""}, Tag: "valid:\"eq=false\"", }, }, @@ -375,17 +376,17 @@ func TestParseStructsOk(t *testing.T) { Fields: []Field{ { FieldName: "MapField1", - Type: "map[string]", + Type: common.FieldType{BaseType: "string", ComposedType: "map", Size: ""}, Tag: "valid:\"required\"", }, { FieldName: "MapField2", - Type: "map[string]", + Type: common.FieldType{BaseType: "string", ComposedType: "map", Size: ""}, Tag: "valid:\"len=3\"", }, { FieldName: "MapField3", - Type: "map[uint8]", + Type: common.FieldType{BaseType: "uint8", ComposedType: "map", Size: ""}, Tag: "valid:\"max=5\"", }, }, @@ -423,7 +424,7 @@ func structsToString(structs []*Struct) string { result += "Path: " + s.Path + "\n" result += "PackageName: " + s.PackageName + "\n" for _, f := range s.Fields { - result += " Field: " + f.FieldName + " Type: " + f.Type + " Tag: " + f.Tag + "\n" + result += " Field: " + f.FieldName + " Type: " + f.Type.ToString() + " Tag: " + f.Tag + "\n" } for _, v := range s.Imports { result += " Import: " + v.Name + " Path: " + v.Path + "\n" diff --git a/internal/parser/struct.go b/internal/parser/struct.go index 683cc41..06aa190 100644 --- a/internal/parser/struct.go +++ b/internal/parser/struct.go @@ -1,5 +1,7 @@ package parser +import "github.com/opencodeco/validgen/internal/common" + type Struct struct { StructName string Path string @@ -10,7 +12,7 @@ type Struct struct { type Field struct { FieldName string - Type string + Type common.FieldType Tag string } diff --git a/internal/pkgwriter/file_validator_test.go b/internal/pkgwriter/file_validator_test.go index 86d3311..0fc071e 100644 --- a/internal/pkgwriter/file_validator_test.go +++ b/internal/pkgwriter/file_validator_test.go @@ -5,6 +5,7 @@ import ( "github.com/opencodeco/validgen/internal/analyzer" "github.com/opencodeco/validgen/internal/codegenerator" + "github.com/opencodeco/validgen/internal/common" "github.com/opencodeco/validgen/internal/parser" "github.com/sergi/go-diff/diffmatchpatch" ) @@ -30,12 +31,12 @@ func TestBuildFileValidator(t *testing.T) { Fields: []parser.Field{ { FieldName: "FirstName", - Type: "string", + Type: common.FieldType{BaseType: "string"}, Tag: `validate:"required"`, }, { FieldName: "MyAge", - Type: "uint8", + Type: common.FieldType{BaseType: "uint8"}, Tag: `validate:"required"`, }, }, @@ -85,7 +86,7 @@ func UserValidate(obj *User) []error { Fields: []parser.Field{ { FieldName: "FirstName", - Type: "string", + Type: common.FieldType{BaseType: "string"}, Tag: `validate:"min=5"`, }, }, From 0d9b9b9f633397513b75103d52f0c80e3a6fbc35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20S=2E=20Garz=C3=A3o?= Date: Sat, 27 Sep 2025 20:26:55 -0300 Subject: [PATCH 3/6] refact: IsGoType is a FieldType method now --- internal/analyzer/analyzer.go | 2 +- internal/codegenerator/build_validator.go | 2 +- internal/common/types.go | 30 +++++++- internal/common/types_test.go | 89 +++++++++++++++++++++++ internal/common/utils.go | 29 -------- internal/common/utils_test.go | 89 ----------------------- internal/parser/parser.go | 2 +- 7 files changed, 121 insertions(+), 122 deletions(-) diff --git a/internal/analyzer/analyzer.go b/internal/analyzer/analyzer.go index 9bf863d..9674c91 100644 --- a/internal/analyzer/analyzer.go +++ b/internal/analyzer/analyzer.go @@ -89,7 +89,7 @@ func checkForInvalidOperations(structs []*Struct) error { // Check if is a valid operation for this type. fdType := fd.Type - if common.IsGoType(fdType) && !operations[op].ValidTypes[fdType.ToString()] { + if fdType.IsGoType() && !operations[op].ValidTypes[fdType.ToString()] { return types.NewValidationError("operation %s: invalid %s type", op, fdType.BaseType) } } diff --git a/internal/codegenerator/build_validator.go b/internal/codegenerator/build_validator.go index 6a79610..0ff1891 100644 --- a/internal/codegenerator/build_validator.go +++ b/internal/codegenerator/build_validator.go @@ -55,7 +55,7 @@ func (gv *genValidations) buildValidationCode(fieldName string, fieldType common var testCode = "" var err error - if common.IsGoType(fieldType) { + if fieldType.IsGoType() { testCode, err = gv.buildIfCode(fieldName, fieldType, fieldValidation) if err != nil { return "", err diff --git a/internal/common/types.go b/internal/common/types.go index c37f2d3..1a0bdf3 100644 --- a/internal/common/types.go +++ b/internal/common/types.go @@ -4,7 +4,35 @@ type FieldType struct { ComposedType string // array ([N]), map (map) or slice ([]) BaseType string // base type (e.g. string, int, etc.) Size string // for arrays - // IsGoType bool // true if is a Go built-in type +} + +func (ft FieldType) IsGoType() bool { + if ft.ComposedType == "map" { + return true + } + + goTypes := map[string]struct{}{ + "string": {}, + "bool": {}, + // "int": {}, + // "int8": {}, + // "int16": {}, + // "int32": {}, + // "int64": {}, + // "uint": {}, + "uint8": {}, + // "uint16": {}, + // "uint32": {}, + // "uint64": {}, + // "float32": {}, + // "float64": {}, + // "complex64": {}, + // "complex128": {}, + } + + _, ok := goTypes[ft.BaseType] + + return ok } func (ft FieldType) ToString() string { diff --git a/internal/common/types_test.go b/internal/common/types_test.go index 50b4ca0..f0e05fc 100644 --- a/internal/common/types_test.go +++ b/internal/common/types_test.go @@ -64,3 +64,92 @@ func TestFieldType_ToString(t *testing.T) { }) } } + +func TestFieldType_IsGoType(t *testing.T) { + type args struct { + fieldType FieldType + } + tests := []struct { + name string + args args + want bool + }{ + { + name: "basic type", + args: args{ + fieldType: FieldType{BaseType: "string", ComposedType: "", Size: ""}, + }, + want: true, + }, + { + name: "array type", + args: args{ + fieldType: FieldType{BaseType: "string", ComposedType: "[N]", Size: "5"}, + }, + want: true, + }, + { + name: "slice type", + args: args{ + fieldType: FieldType{BaseType: "string", ComposedType: "[]", Size: ""}, + }, + want: true, + }, + { + name: "map type", + args: args{ + fieldType: FieldType{BaseType: "string", ComposedType: "map", Size: ""}, + }, + want: true, + }, + { + name: "custom type", + args: args{ + fieldType: FieldType{BaseType: "MyType", ComposedType: "", Size: ""}, + }, + want: false, + }, + { + name: "pointer type", + args: args{ + fieldType: FieldType{BaseType: "*MyType", ComposedType: "", Size: ""}, + }, + want: false, + }, + // { + // name: "pointer to basic type", + // args: args{ + // fieldType: FieldType{BaseType: "*string", ComposedType: "", Size: ""}, + // }, + // want: true, + // }, + { + name: "struct type", + args: args{ + fieldType: FieldType{BaseType: "MyStruct", ComposedType: "", Size: ""}, + }, + want: false, + }, + // { + // name: "interface type", + // args: args{ + // fieldType: FieldType{BaseType: "interface{}", ComposedType: "", Size: ""}, + // }, + // want: true, + // }, + // { + // name: "complex type", + // args: args{ + // fieldType: FieldType{BaseType: "map[string][]*MyType", ComposedType: "", Size: ""}, + // }, + // want: true, + // }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.args.fieldType.IsGoType(); got != tt.want { + t.Errorf("IsGoType() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/internal/common/utils.go b/internal/common/utils.go index 01a6ec7..2339c3c 100644 --- a/internal/common/utils.go +++ b/internal/common/utils.go @@ -2,35 +2,6 @@ package common import "strings" -func IsGoType(fieldType FieldType) bool { - if fieldType.ComposedType == "map" { - return true - } - - goTypes := map[string]struct{}{ - "string": {}, - "bool": {}, - // "int": {}, - // "int8": {}, - // "int16": {}, - // "int32": {}, - // "int64": {}, - // "uint": {}, - "uint8": {}, - // "uint16": {}, - // "uint32": {}, - // "uint64": {}, - // "float32": {}, - // "float64": {}, - // "complex64": {}, - // "complex128": {}, - } - - _, ok := goTypes[fieldType.BaseType] - - return ok -} - func ExtractPackage(fieldType string) string { if pkg, _, ok := strings.Cut(fieldType, "."); ok { return pkg diff --git a/internal/common/utils_test.go b/internal/common/utils_test.go index fe3382f..4fd5afa 100644 --- a/internal/common/utils_test.go +++ b/internal/common/utils_test.go @@ -70,92 +70,3 @@ func TestKeyPath(t *testing.T) { }) } } - -func TestIsGoType(t *testing.T) { - type args struct { - fieldType FieldType - } - tests := []struct { - name string - args args - want bool - }{ - { - name: "basic type", - args: args{ - fieldType: FieldType{BaseType: "string", ComposedType: "", Size: ""}, - }, - want: true, - }, - { - name: "array type", - args: args{ - fieldType: FieldType{BaseType: "string", ComposedType: "[N]", Size: "5"}, - }, - want: true, - }, - { - name: "slice type", - args: args{ - fieldType: FieldType{BaseType: "string", ComposedType: "[]", Size: ""}, - }, - want: true, - }, - { - name: "map type", - args: args{ - fieldType: FieldType{BaseType: "string", ComposedType: "map", Size: ""}, - }, - want: true, - }, - { - name: "custom type", - args: args{ - fieldType: FieldType{BaseType: "MyType", ComposedType: "", Size: ""}, - }, - want: false, - }, - { - name: "pointer type", - args: args{ - fieldType: FieldType{BaseType: "*MyType", ComposedType: "", Size: ""}, - }, - want: false, - }, - // { - // name: "pointer to basic type", - // args: args{ - // fieldType: FieldType{BaseType: "*string", ComposedType: "", Size: ""}, - // }, - // want: true, - // }, - { - name: "struct type", - args: args{ - fieldType: FieldType{BaseType: "MyStruct", ComposedType: "", Size: ""}, - }, - want: false, - }, - // { - // name: "interface type", - // args: args{ - // fieldType: FieldType{BaseType: "interface{}", ComposedType: "", Size: ""}, - // }, - // want: true, - // }, - // { - // name: "complex type", - // args: args{ - // fieldType: FieldType{BaseType: "map[string][]*MyType", ComposedType: "", Size: ""}, - // }, - // want: true, - // }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := IsGoType(tt.args.fieldType); got != tt.want { - t.Errorf("IsGoType() = %v, want %v", got, tt.want) - } - }) - } -} diff --git a/internal/parser/parser.go b/internal/parser/parser.go index 6717c3e..4826a5f 100644 --- a/internal/parser/parser.go +++ b/internal/parser/parser.go @@ -197,7 +197,7 @@ func appendFields(structType *ast.StructType, packageName string, cstruct *Struc func extractFieldTypeAndTag(packageName string, fieldType common.FieldType, fieldTag string) (common.FieldType, string) { rFieldType := fieldType - if !common.IsGoType(fieldType) { + if !fieldType.IsGoType() { rFieldType.BaseType = common.KeyPath(packageName, fieldType.BaseType) } From 97671daaabafeb8f1cf3128fba56848195c890d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20S=2E=20Garz=C3=A3o?= Date: Sun, 28 Sep 2025 18:59:55 -0300 Subject: [PATCH 4/6] chore: register a possible refactor --- internal/codegenerator/test_elements.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/codegenerator/test_elements.go b/internal/codegenerator/test_elements.go index 7bc2daf..ed46a6a 100644 --- a/internal/codegenerator/test_elements.go +++ b/internal/codegenerator/test_elements.go @@ -32,7 +32,7 @@ func DefineTestElements(fieldName string, fieldType common.FieldType, fieldValid targetValues := "" switch fieldValidation.ExpectedValues { - case analyzer.ZERO_VALUE: + case analyzer.ZERO_VALUE: // REFACTOR: codegenerator should inform how many values are expected roperands = append(roperands, replaceNameAndTarget(condition.operation, fieldName, "")) targetValue = condition.operation targetValues = "'" + condition.operation + "' " From dc85a43f83a6d11aa42f42120d9bfe5a5c828a5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20S=2E=20Garz=C3=A3o?= Date: Mon, 29 Sep 2025 19:01:25 -0300 Subject: [PATCH 5/6] chore: removes unused tests --- internal/common/types_test.go | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/internal/common/types_test.go b/internal/common/types_test.go index f0e05fc..cbd6222 100644 --- a/internal/common/types_test.go +++ b/internal/common/types_test.go @@ -116,13 +116,6 @@ func TestFieldType_IsGoType(t *testing.T) { }, want: false, }, - // { - // name: "pointer to basic type", - // args: args{ - // fieldType: FieldType{BaseType: "*string", ComposedType: "", Size: ""}, - // }, - // want: true, - // }, { name: "struct type", args: args{ @@ -130,20 +123,6 @@ func TestFieldType_IsGoType(t *testing.T) { }, want: false, }, - // { - // name: "interface type", - // args: args{ - // fieldType: FieldType{BaseType: "interface{}", ComposedType: "", Size: ""}, - // }, - // want: true, - // }, - // { - // name: "complex type", - // args: args{ - // fieldType: FieldType{BaseType: "map[string][]*MyType", ComposedType: "", Size: ""}, - // }, - // want: true, - // }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From 1b54cad0fe1ce829141783705086826d1a3ca2f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20S=2E=20Garz=C3=A3o?= Date: Mon, 29 Sep 2025 19:15:51 -0300 Subject: [PATCH 6/6] chore: forgot to update docs and tests related to bool type --- README.md | 14 +++++++++----- tests/endtoend/bool.go | 20 ++++++++++++++------ tests/endtoend/validator__.go | 6 ++++++ 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index e35200b..74a8466 100644 --- a/README.md +++ b/README.md @@ -55,17 +55,21 @@ The following validations will be implemented: - ltefield (less than or equal field): field must be less than or equal to another field - ltfield (less than field): field must be less than another field -The following table shows the validations and possible types, where "I" means "Implemented", "W" means "Will be implemented" and "-" means "Will not be implemented": +The following table shows the validations and possible types, where: + +- "I" means "Implemented" +- "W" means "Will be implemented" +- "-" means "Will not be implemented" | Validation/Type | String | Numeric types (uint8 only) | Boolean | Slice | Array | Map | Time | Duration | | - | - | - | - | - | - | - | - | - | -| eq | I | W | W | - | - | - | W | W | +| eq | I | W | I | - | - | - | W | W | | eq_ignore_case | I | - | - | - | - | - | - | - | | gt | - | W | - | - | - | - | W | W | | gte | - | I | - | - | - | - | W | W | | lt | - | W | - | - | - | - | W | W | | lte | - | I | - | - | - | - | W | W | -| neq | I | W | W | - | - | - | W | W | +| neq | I | W | I | - | - | - | W | W | | neq_ignore_case | I | - | - | - | - | - | - | - | | len | I | - | - | I | - | W | - | - | | max | I | - | - | I | - | W | W | W | @@ -74,8 +78,8 @@ The following table shows the validations and possible types, where "I" means "I | nin | I | W | - | I | I | W | - | W | | required | I | W | - | I | - | W | W | W | | email | I | - | - | - | - | - | - | - | -| eqfield | I | I | W | - | - | - | W | W | -| neqfield | I | I | W | - | - | - | W | W | +| eqfield | I | I | I | - | - | - | W | W | +| neqfield | I | I | I | - | - | - | W | W | | gtefield | - | I | - | - | - | - | W | W | | gtfield | - | I | - | - | - | - | W | W | | ltefield | - | I | - | - | - | - | W | W | diff --git a/tests/endtoend/bool.go b/tests/endtoend/bool.go index 8bdf783..3c41612 100644 --- a/tests/endtoend/bool.go +++ b/tests/endtoend/bool.go @@ -3,8 +3,10 @@ package main import "log" type BoolType struct { - FieldEqTrue bool `valid:"eq=true"` - FieldNeqFalse bool `valid:"neq=false"` + FieldEqTrue bool `valid:"eq=true"` + FieldNeqFalse bool `valid:"neq=false"` + FieldEqFieldEqTrue bool `valid:"eqfield=FieldEqTrue"` + FieldNeqFieldEqTrue bool `valid:"neqfield=FieldEqTrue"` } func bool_tests() { @@ -15,12 +17,16 @@ func bool_tests() { // Test case 1: All failure scenarios v := &BoolType{ - FieldEqTrue: false, - FieldNeqFalse: false, + FieldEqTrue: false, + FieldNeqFalse: false, + FieldEqFieldEqTrue: true, + FieldNeqFieldEqTrue: false, } expectedMsgErrors = []string{ "FieldEqTrue must be equal to true", "FieldNeqFalse must not be equal to false", + "FieldEqFieldEqTrue must be equal to FieldEqTrue", + "FieldNeqFieldEqTrue must not be equal to FieldEqTrue", } errs = BoolTypeValidate(v) if !expectedMsgErrorsOk(errs, expectedMsgErrors) { @@ -29,8 +35,10 @@ func bool_tests() { // Test case 2: All valid input v = &BoolType{ - FieldEqTrue: true, - FieldNeqFalse: true, + FieldEqTrue: true, + FieldNeqFalse: true, + FieldEqFieldEqTrue: true, + FieldNeqFieldEqTrue: false, } expectedMsgErrors = nil errs = BoolTypeValidate(v) diff --git a/tests/endtoend/validator__.go b/tests/endtoend/validator__.go index 08c7dfb..00949f8 100755 --- a/tests/endtoend/validator__.go +++ b/tests/endtoend/validator__.go @@ -70,6 +70,12 @@ func BoolTypeValidate(obj *BoolType) []error { if !(obj.FieldNeqFalse != false) { errs = append(errs, types.NewValidationError("FieldNeqFalse must not be equal to false")) } + if !(obj.FieldEqFieldEqTrue == obj.FieldEqTrue) { + errs = append(errs, types.NewValidationError("FieldEqFieldEqTrue must be equal to FieldEqTrue")) + } + if !(obj.FieldNeqFieldEqTrue != obj.FieldEqTrue) { + errs = append(errs, types.NewValidationError("FieldNeqFieldEqTrue must not be equal to FieldEqTrue")) + } return errs } func CmpInnerBoolFieldsValidate(obj *CmpInnerBoolFields) []error {