feat: null_safety test

This commit is contained in:
2024-12-29 21:39:29 +07:00
parent b32eafb43d
commit 9a66f2f2a7
9 changed files with 107 additions and 36 deletions

View File

@@ -2,9 +2,9 @@ package common
import (
"errors"
"fmt"
"github.com/fatih/structtag"
"go/ast"
"golang.org/x/tools/go/analysis"
)
func isPointerType(typeExpr ast.Expr) bool {
@@ -30,7 +30,7 @@ func isGormValueNullable(tags *structtag.Tags) (*bool, error) {
nullTagExist := gormTag.HasOption("null")
notNullTagExist := gormTag.HasOption("not null")
if nullTagExist == notNullTagExist && nullTagExist == true {
if nullTagExist == notNullTagExist && nullTagExist {
return nil, errors.New(`tags "null" and "not null" are specified at one field`)
}
@@ -43,26 +43,28 @@ func isGormValueNullable(tags *structtag.Tags) (*bool, error) {
}
}
func CheckFieldNullConsistency(pass analysis.Pass, field ast.Field, structName string, structTags string) {
func CheckFieldNullConsistency(field ast.Field, structName string, structTags string) error {
tags, err := structtag.Parse(structTags)
if err != nil {
pass.Reportf(field.Pos(), "Invalid structure tag: %s", err)
return errors.New(fmt.Sprintf("Invalid structure tag: %s", err))
}
if tags == nil {
return
return nil
}
isFieldNullable := isPointerType(field.Type)
isColumnNullable, err := isGormValueNullable(tags)
if err != nil {
pass.Reportf(field.Pos(), "Null safety error: %s", err)
return errors.New(fmt.Sprintf("Null safety error: %s", err))
}
if isColumnNullable == nil {
return
return nil
}
if isFieldNullable != *isColumnNullable {
pass.Reportf(field.Pos(), "Null safety error in \"%s\" model, field \"%s\": column nullable policy doesn't match to tag nullable policy", structName, field.Names[0].Name)
return errors.New(fmt.Sprintf("Null safety error in \"%s\" model, field \"%s\": column nullable policy doesn't match to tag nullable policy", structName, field.Names[0].Name))
}
return nil
}

View File

@@ -1,18 +1,21 @@
package common
import (
"errors"
"fmt"
"go/ast"
"golang.org/x/tools/go/analysis"
)
func CheckUnnamedModel(pass analysis.Pass, typeSpec ast.TypeSpec) {
func CheckUnnamedModel(typeSpec ast.TypeSpec) error {
if typeSpec.Name == nil {
pass.Reportf(typeSpec.Pos(), "Unnamed model\n")
return errors.New(fmt.Sprintf("Unnamed model\n"))
}
return nil
}
func CheckUnnamedField(pass analysis.Pass, structName string, field ast.Field) {
func CheckUnnamedField(structName string, field ast.Field) error {
if len(field.Names) == 0 {
pass.Reportf(field.Pos(), "Struct \"%s\" has unnamed field", structName)
return errors.New(fmt.Sprintf("Struct \"%s\" has unnamed field", structName))
}
return nil
}