Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
Expand All @@ -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 |
Expand Down
8 changes: 4 additions & 4 deletions internal/analyzer/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 fdType.IsGoType() && !operations[op].ValidTypes[fdType.ToString()] {
return types.NewValidationError("operation %s: invalid %s type", op, fdType.BaseType)
}
}
}
Expand All @@ -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
Expand Down Expand Up @@ -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]
Expand Down
35 changes: 18 additions & 17 deletions internal/analyzer/analyzer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"testing"

"github.com/opencodeco/validgen/internal/common"
"github.com/opencodeco/validgen/internal/parser"
"github.com/opencodeco/validgen/types"
)
Expand Down Expand Up @@ -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: ``,
},
},
Expand Down Expand Up @@ -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: ``,
},
},
Expand All @@ -157,7 +158,7 @@ func TestAnalyzeStructsWithValidNestedFieldOperations(t *testing.T) {
Fields: []parser.Field{
{
FieldName: "Field2",
Type: tt.fType,
Type: common.FieldType{BaseType: tt.fType},
Tag: ``,
},
},
Expand Down Expand Up @@ -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: ``,
},
},
Expand All @@ -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"`,
},
},
Expand All @@ -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: ``,
},
},
Expand Down Expand Up @@ -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: ``,
},
},
Expand All @@ -272,7 +273,7 @@ func TestAnalyzeStructsWithInvalidNestedFieldOperations(t *testing.T) {
Fields: []parser.Field{
{
FieldName: "Field2",
Type: "uint8",
Type: common.FieldType{BaseType: "uint8"},
Tag: ``,
},
},
Expand All @@ -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"`,
},
},
Expand All @@ -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: ``,
},
},
Expand All @@ -322,7 +323,7 @@ func TestAnalyzeStructsWithInvalidNestedFieldOperations(t *testing.T) {
Fields: []parser.Field{
{
FieldName: "Field2",
Type: "string",
Type: common.FieldType{BaseType: "string"},
Tag: ``,
},
},
Expand Down
3 changes: 2 additions & 1 deletion internal/analyzer/operations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"testing"

"github.com/opencodeco/validgen/internal/common"
"github.com/opencodeco/validgen/internal/parser"
)

Expand Down Expand Up @@ -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),
},
},
Expand Down
15 changes: 8 additions & 7 deletions internal/codegenerator/build_func_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand All @@ -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"`,
},
},
Expand Down Expand Up @@ -69,7 +70,7 @@ return errs
Fields: []parser.Field{
{
FieldName: "FirstName",
Type: "string",
Type: common.FieldType{BaseType: "string"},
Tag: `validate:"min=5"`,
},
},
Expand Down Expand Up @@ -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"`,
},
},
Expand Down Expand Up @@ -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: ``,
},
},
Expand Down
18 changes: 9 additions & 9 deletions internal/codegenerator/build_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type structTpl struct {

type fieldTpl struct {
FieldName string
Type string
Type common.FieldType
Validations []*analyzer.Validation
}

Expand All @@ -48,14 +48,14 @@ 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 {
var testCode = ""
var err error

if common.IsGoType(fieldType) {
if fieldType.IsGoType() {
testCode, err = gv.buildIfCode(fieldName, fieldType, fieldValidation)
if err != nil {
return "", err
Expand All @@ -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)
Expand All @@ -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
Expand Down
Loading
Loading