Test ParseSchema
This commit is contained in:
parent
af5536108a
commit
83b307642d
@ -24,7 +24,7 @@ func buildToOneRel(field *Field, sourceSchema *Schema) {
|
|||||||
// user belongs to profile, associationType is Profile, user use ProfileID as foreign key
|
// user belongs to profile, associationType is Profile, user use ProfileID as foreign key
|
||||||
relationship = &Relationship{}
|
relationship = &Relationship{}
|
||||||
associationType = sourceSchema.ModelType.Name()
|
associationType = sourceSchema.ModelType.Name()
|
||||||
destSchema = ParseSchema(reflect.New(field.StructField.Type).Interface())
|
destSchema = Parse(reflect.New(field.StructField.Type).Interface())
|
||||||
tagForeignKeys, tagAssociationForeignKeys []string
|
tagForeignKeys, tagAssociationForeignKeys []string
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -184,7 +184,7 @@ func buildToManyRel(field *Field, sourceSchema *Schema) {
|
|||||||
var (
|
var (
|
||||||
relationship = &Relationship{}
|
relationship = &Relationship{}
|
||||||
elemType = field.StructField.Type
|
elemType = field.StructField.Type
|
||||||
destSchema = ParseSchema(reflect.New(elemType).Interface())
|
destSchema = Parse(reflect.New(elemType).Interface())
|
||||||
foreignKeys, associationForeignKeys []string
|
foreignKeys, associationForeignKeys []string
|
||||||
)
|
)
|
||||||
|
|
||||||
|
65
schema/relationship_test.go
Normal file
65
schema/relationship_test.go
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package schema
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
type BelongsTo struct {
|
||||||
|
ID int
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
type HasOne struct {
|
||||||
|
ID int
|
||||||
|
MyStructID uint
|
||||||
|
}
|
||||||
|
|
||||||
|
type HasMany struct {
|
||||||
|
ID int
|
||||||
|
MyStructID uint
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
type Many2Many struct {
|
||||||
|
ID int
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBelongsToRel(t *testing.T) {
|
||||||
|
type MyStruct struct {
|
||||||
|
ID int
|
||||||
|
Name string
|
||||||
|
BelongsTo BelongsTo
|
||||||
|
}
|
||||||
|
|
||||||
|
Parse(&MyStruct{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHasOneRel(t *testing.T) {
|
||||||
|
type MyStruct struct {
|
||||||
|
ID int
|
||||||
|
Name string
|
||||||
|
HasOne HasOne
|
||||||
|
}
|
||||||
|
|
||||||
|
Parse(&MyStruct{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHasManyRel(t *testing.T) {
|
||||||
|
type MyStruct struct {
|
||||||
|
ID int
|
||||||
|
Name string
|
||||||
|
HasMany []HasMany
|
||||||
|
}
|
||||||
|
|
||||||
|
Parse(&MyStruct{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestManyToManyRel(t *testing.T) {
|
||||||
|
type MyStruct struct {
|
||||||
|
ID int
|
||||||
|
Name string
|
||||||
|
HasMany []HasMany
|
||||||
|
}
|
||||||
|
|
||||||
|
Parse(&MyStruct{})
|
||||||
|
}
|
||||||
|
|
@ -33,8 +33,8 @@ type Field struct {
|
|||||||
Relationship *Relationship
|
Relationship *Relationship
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseSchema parse struct and generate schema based on struct and tag definition
|
// Parse parse struct and generate schema based on struct and tag definition
|
||||||
func ParseSchema(dest interface{}) *Schema {
|
func Parse(dest interface{}) *Schema {
|
||||||
schema := Schema{}
|
schema := Schema{}
|
||||||
|
|
||||||
// Get dest type
|
// Get dest type
|
||||||
@ -104,7 +104,7 @@ func ParseSchema(dest interface{}) *Schema {
|
|||||||
field.IsNormal = true
|
field.IsNormal = true
|
||||||
} else if _, ok := field.TagSettings["EMBEDDED"]; ok || fieldStruct.Anonymous {
|
} else if _, ok := field.TagSettings["EMBEDDED"]; ok || fieldStruct.Anonymous {
|
||||||
// embedded struct
|
// embedded struct
|
||||||
if subSchema := ParseSchema(fieldValue); subSchema != nil {
|
if subSchema := Parse(fieldValue); subSchema != nil {
|
||||||
for _, subField := range subSchema.Fields {
|
for _, subField := range subSchema.Fields {
|
||||||
subField = subField.clone()
|
subField = subField.clone()
|
||||||
subField.BindNames = append([]string{fieldStruct.Name}, subField.BindNames...)
|
subField.BindNames = append([]string{fieldStruct.Name}, subField.BindNames...)
|
||||||
|
@ -2,89 +2,102 @@ package schema
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type MyStruct struct {
|
func fieldEqual(got, expected *Field) error {
|
||||||
|
if expected.DBName != got.DBName {
|
||||||
|
return fmt.Errorf("field DBName should be %v, got %v", expected.DBName, got.DBName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if expected.Name != got.Name {
|
||||||
|
return fmt.Errorf("field Name should be %v, got %v", expected.Name, got.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(expected.BindNames, got.BindNames) {
|
||||||
|
return fmt.Errorf("field BindNames should be %#v, got %#v", expected.BindNames, got.BindNames)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (expected.TagSettings == nil && len(got.TagSettings) != 0) && !reflect.DeepEqual(expected.TagSettings, got.TagSettings) {
|
||||||
|
return fmt.Errorf("field TagSettings should be %#v, got %#v", expected.TagSettings, got.TagSettings)
|
||||||
|
}
|
||||||
|
|
||||||
|
if expected.IsNormal != got.IsNormal {
|
||||||
|
return fmt.Errorf("field IsNormal should be %v, got %v", expected.IsNormal, got.IsNormal)
|
||||||
|
}
|
||||||
|
|
||||||
|
if expected.IsPrimaryKey != got.IsPrimaryKey {
|
||||||
|
return fmt.Errorf("field IsPrimaryKey should be %v, got %v", expected.IsPrimaryKey, got.IsPrimaryKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
if expected.IsIgnored != got.IsIgnored {
|
||||||
|
return fmt.Errorf("field IsIgnored should be %v, got %v", expected.IsIgnored, got.IsIgnored)
|
||||||
|
}
|
||||||
|
|
||||||
|
if expected.IsForeignKey != got.IsForeignKey {
|
||||||
|
return fmt.Errorf("field IsForeignKey should be %v, got %v", expected.IsForeignKey, got.IsForeignKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
if expected.DefaultValue != got.DefaultValue {
|
||||||
|
return fmt.Errorf("field DefaultValue should be %v, got %v", expected.DefaultValue, got.DefaultValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
if expected.HasDefaultValue != got.HasDefaultValue {
|
||||||
|
return fmt.Errorf("field HasDefaultValue should be %v, got %v", expected.HasDefaultValue, got.HasDefaultValue)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func compareFields(fields []*Field, expectedFields []*Field, t *testing.T) {
|
||||||
|
if len(fields) != len(expectedFields) {
|
||||||
|
t.Errorf("expected has %v fields, but got %v", len(expectedFields), len(fields))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, expectedField := range expectedFields {
|
||||||
|
field := getSchemaField(expectedField.DBName, fields)
|
||||||
|
if field == nil {
|
||||||
|
t.Errorf("Field %#v is not found", expectedField.Name)
|
||||||
|
} else if err := fieldEqual(field, expectedField); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParse(t *testing.T) {
|
||||||
|
type MyStruct struct {
|
||||||
ID int
|
ID int
|
||||||
Int uint
|
Int uint
|
||||||
IntPointer *uint
|
IntPointer *uint `gorm:"default:10"`
|
||||||
String string
|
String string
|
||||||
StringPointer *string
|
StringPointer *string `gorm:"column:strp"`
|
||||||
Time time.Time
|
Time time.Time
|
||||||
TimePointer *time.Time
|
TimePointer *time.Time
|
||||||
NullInt64 sql.NullInt64
|
NullInt64 sql.NullInt64
|
||||||
}
|
|
||||||
|
|
||||||
type BelongsTo struct {
|
|
||||||
ID int
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
|
|
||||||
type HasOne struct {
|
|
||||||
ID int
|
|
||||||
MyStructID uint
|
|
||||||
}
|
|
||||||
|
|
||||||
type HasMany struct {
|
|
||||||
ID int
|
|
||||||
MyStructID uint
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
|
|
||||||
type Many2Many struct {
|
|
||||||
ID int
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseSchema(t *testing.T) {
|
|
||||||
ParseSchema(&MyStruct{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseBelongsToRel(t *testing.T) {
|
|
||||||
type MyStruct struct {
|
|
||||||
ID int
|
|
||||||
Name string
|
|
||||||
BelongsTo BelongsTo
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseSchema(&MyStruct{})
|
schema := Parse(&MyStruct{})
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseHasOneRel(t *testing.T) {
|
compareFields(schema.Fields, []*Field{
|
||||||
type MyStruct struct {
|
{DBName: "id", Name: "ID", BindNames: []string{"ID"}, IsNormal: true, IsPrimaryKey: true},
|
||||||
ID int
|
{DBName: "int", Name: "Int", BindNames: []string{"Int"}, IsNormal: true},
|
||||||
Name string
|
{DBName: "int_pointer", Name: "IntPointer", BindNames: []string{"IntPointer"}, TagSettings: map[string]string{"DEFAULT": "10"}, IsNormal: true, HasDefaultValue: true, DefaultValue: "10"},
|
||||||
HasOne HasOne
|
{DBName: "string", Name: "String", BindNames: []string{"String"}, IsNormal: true},
|
||||||
}
|
{DBName: "strp", Name: "StringPointer", BindNames: []string{"StringPointer"}, TagSettings: map[string]string{"COLUMN": "strp"}, IsNormal: true},
|
||||||
|
{DBName: "time", Name: "Time", BindNames: []string{"Time"}, IsNormal: true},
|
||||||
ParseSchema(&MyStruct{})
|
{DBName: "time_pointer", Name: "TimePointer", BindNames: []string{"TimePointer"}, IsNormal: true},
|
||||||
}
|
{DBName: "null_int64", Name: "NullInt64", BindNames: []string{"NullInt64"}, IsNormal: true},
|
||||||
|
}, t)
|
||||||
func TestParseHasManyRel(t *testing.T) {
|
|
||||||
type MyStruct struct {
|
|
||||||
ID int
|
|
||||||
Name string
|
|
||||||
HasMany []HasMany
|
|
||||||
}
|
|
||||||
|
|
||||||
ParseSchema(&MyStruct{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseManyToManyRel(t *testing.T) {
|
|
||||||
type MyStruct struct {
|
|
||||||
ID int
|
|
||||||
Name string
|
|
||||||
HasMany []HasMany
|
|
||||||
}
|
|
||||||
|
|
||||||
ParseSchema(&MyStruct{})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEmbeddedStruct(t *testing.T) {
|
func TestEmbeddedStruct(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOverwriteEmbeddedStructFields(t *testing.T) {
|
||||||
|
}
|
||||||
|
|
||||||
func TestCustomizePrimaryKey(t *testing.T) {
|
func TestCustomizePrimaryKey(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +86,7 @@ func getPrimaryPrimaryField(fields []*Field) *Field {
|
|||||||
func parseTagSetting(tags reflect.StructTag) map[string]string {
|
func parseTagSetting(tags reflect.StructTag) map[string]string {
|
||||||
setting := map[string]string{}
|
setting := map[string]string{}
|
||||||
for _, str := range []string{tags.Get("sql"), tags.Get("gorm")} {
|
for _, str := range []string{tags.Get("sql"), tags.Get("gorm")} {
|
||||||
|
if str != "" {
|
||||||
tags := strings.Split(str, ";")
|
tags := strings.Split(str, ";")
|
||||||
for _, value := range tags {
|
for _, value := range tags {
|
||||||
v := strings.Split(value, ":")
|
v := strings.Split(value, ":")
|
||||||
@ -97,5 +98,6 @@ func parseTagSetting(tags reflect.StructTag) map[string]string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return setting
|
return setting
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user