codegen: test fixture factories now use randomness to generate unique column values
This commit is contained in:
@@ -101,6 +101,22 @@ func GenerateModelTestAST(tbl pkgschema.Table, schema pkgschema.Schema, gomodNam
|
|||||||
|
|
||||||
hasCreatedAt, hasUpdatedAt := tbl.HasAutoTimestamps()
|
hasCreatedAt, hasUpdatedAt := tbl.HasAutoTimestamps()
|
||||||
updateTestFields := UpdateTestFields(tbl)
|
updateTestFields := UpdateTestFields(tbl)
|
||||||
|
uniqueColumns := map[string]bool{}
|
||||||
|
for _, index := range schema.Indexes {
|
||||||
|
if index.TableName != tbl.TableName || !index.IsUnique {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for _, columnName := range index.Columns {
|
||||||
|
uniqueColumns[columnName] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hasRandomUniqueField := false
|
||||||
|
for _, c := range updateTestFields {
|
||||||
|
if uniqueColumns[c.Name] {
|
||||||
|
hasRandomUniqueField = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
requiredForeignKeys := []pkgschema.Column{}
|
requiredForeignKeys := []pkgschema.Column{}
|
||||||
for _, c := range tbl.Columns {
|
for _, c := range tbl.Columns {
|
||||||
// Only ordinary object foreign keys use a distinct TargetObjectID Go type;
|
// Only ordinary object foreign keys use a distinct TargetObjectID Go type;
|
||||||
@@ -141,31 +157,71 @@ func GenerateModelTestAST(tbl pkgschema.Table, schema pkgschema.Schema, gomodNam
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Body: &ast.BlockStmt{
|
Body: &ast.BlockStmt{
|
||||||
List: []ast.Stmt{
|
List: append(
|
||||||
&ast.ReturnStmt{
|
func() []ast.Stmt {
|
||||||
Results: []ast.Expr{
|
if !hasRandomUniqueField {
|
||||||
&ast.CompositeLit{
|
return nil
|
||||||
Type: ast.NewIdent(tbl.GoTypeName),
|
}
|
||||||
Elts: func() (ret []ast.Expr) {
|
return []ast.Stmt{&ast.AssignStmt{
|
||||||
// `UpdateTestFields()` skips foreign keys, so this will not cause duplicates
|
Lhs: []ast.Expr{ast.NewIdent("id")},
|
||||||
for i, c := range requiredForeignKeys {
|
Tok: token.DEFINE,
|
||||||
ret = append(ret, &ast.KeyValueExpr{
|
Rhs: []ast.Expr{&ast.CallExpr{Fun: &ast.SelectorExpr{X: ast.NewIdent("rand"), Sel: ast.NewIdent("Int")}}},
|
||||||
Key: ast.NewIdent(c.GoFieldName()),
|
}}
|
||||||
Value: ast.NewIdent(requiredForeignKeyParamNames[i]),
|
}(),
|
||||||
})
|
[]ast.Stmt{
|
||||||
}
|
&ast.ReturnStmt{
|
||||||
for _, c := range updateTestFields {
|
Results: []ast.Expr{
|
||||||
ret = append(ret, &ast.KeyValueExpr{
|
&ast.CompositeLit{
|
||||||
Key: ast.NewIdent(c.GoFieldName()),
|
Type: ast.NewIdent(tbl.GoTypeName),
|
||||||
Value: SampleValue(c, 0),
|
Elts: func() (ret []ast.Expr) {
|
||||||
})
|
// `UpdateTestFields()` skips foreign keys, so this will not cause duplicates
|
||||||
}
|
for i, c := range requiredForeignKeys {
|
||||||
return
|
ret = append(ret, &ast.KeyValueExpr{
|
||||||
}(),
|
Key: ast.NewIdent(c.GoFieldName()),
|
||||||
|
Value: ast.NewIdent(requiredForeignKeyParamNames[i]),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
for _, c := range updateTestFields {
|
||||||
|
value := SampleValue(c, 0)
|
||||||
|
if uniqueColumns[c.Name] {
|
||||||
|
switch c.Type {
|
||||||
|
case "integer", "int":
|
||||||
|
value = ast.NewIdent("id")
|
||||||
|
case "text":
|
||||||
|
value = &ast.CallExpr{
|
||||||
|
Fun: &ast.SelectorExpr{X: ast.NewIdent("fmt"), Sel: ast.NewIdent("Sprintf")},
|
||||||
|
Args: []ast.Expr{
|
||||||
|
&ast.BasicLit{Kind: token.STRING, Value: `"%s-%d"`},
|
||||||
|
SampleValue(c, 0),
|
||||||
|
ast.NewIdent("id"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
case "blob":
|
||||||
|
value = &ast.CallExpr{
|
||||||
|
Fun: &ast.ArrayType{Elt: ast.NewIdent("byte")},
|
||||||
|
Args: []ast.Expr{&ast.CallExpr{
|
||||||
|
Fun: &ast.SelectorExpr{X: ast.NewIdent("fmt"), Sel: ast.NewIdent("Sprintf")},
|
||||||
|
Args: []ast.Expr{
|
||||||
|
&ast.BasicLit{Kind: token.STRING, Value: `"%s-%d"`},
|
||||||
|
&ast.CallExpr{Fun: ast.NewIdent("string"), Args: []ast.Expr{SampleValue(c, 0)}},
|
||||||
|
ast.NewIdent("id"),
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = append(ret, &ast.KeyValueExpr{
|
||||||
|
Key: ast.NewIdent(c.GoFieldName()),
|
||||||
|
Value: value,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}(),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}...,
|
||||||
},
|
),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -595,23 +651,33 @@ func GenerateModelTestAST(tbl pkgschema.Table, schema pkgschema.Schema, gomodNam
|
|||||||
Decls: append([]ast.Decl{
|
Decls: append([]ast.Decl{
|
||||||
&ast.GenDecl{
|
&ast.GenDecl{
|
||||||
Tok: token.IMPORT,
|
Tok: token.IMPORT,
|
||||||
Specs: []ast.Spec{
|
Specs: func() []ast.Spec {
|
||||||
&ast.ImportSpec{Path: &ast.BasicLit{Kind: token.STRING, Value: `"testing"`}},
|
specs := []ast.Spec{}
|
||||||
&ast.ImportSpec{
|
if hasRandomUniqueField {
|
||||||
Path: &ast.BasicLit{Kind: token.STRING, Value: `"git.offline-twitter.com/offline-labs/gas-stack/pkg/db"`},
|
specs = append(specs,
|
||||||
Name: ast.NewIdent("."),
|
&ast.ImportSpec{Path: &ast.BasicLit{Kind: token.STRING, Value: `"fmt"`}},
|
||||||
},
|
&ast.ImportSpec{Path: &ast.BasicLit{Kind: token.STRING, Value: `"math/rand"`}},
|
||||||
&ast.ImportSpec{
|
)
|
||||||
Path: &ast.BasicLit{Kind: token.STRING, Value: `"git.offline-twitter.com/offline-labs/gas-stack/pkg/must"`},
|
}
|
||||||
},
|
specs = append(specs, []ast.Spec{
|
||||||
&ast.ImportSpec{
|
&ast.ImportSpec{Path: &ast.BasicLit{Kind: token.STRING, Value: `"testing"`}},
|
||||||
Path: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf(`"%s/pkg/%s"`, gomodName, packageName)},
|
&ast.ImportSpec{
|
||||||
Name: ast.NewIdent("."),
|
Path: &ast.BasicLit{Kind: token.STRING, Value: `"git.offline-twitter.com/offline-labs/gas-stack/pkg/db"`},
|
||||||
},
|
Name: ast.NewIdent("."),
|
||||||
&ast.ImportSpec{Path: &ast.BasicLit{Kind: token.STRING, Value: `"github.com/go-test/deep"`}},
|
},
|
||||||
&ast.ImportSpec{Path: &ast.BasicLit{Kind: token.STRING, Value: `"github.com/stretchr/testify/assert"`}},
|
&ast.ImportSpec{
|
||||||
&ast.ImportSpec{Path: &ast.BasicLit{Kind: token.STRING, Value: `"github.com/stretchr/testify/require"`}},
|
Path: &ast.BasicLit{Kind: token.STRING, Value: `"git.offline-twitter.com/offline-labs/gas-stack/pkg/must"`},
|
||||||
},
|
},
|
||||||
|
&ast.ImportSpec{
|
||||||
|
Path: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf(`"%s/pkg/%s"`, gomodName, packageName)},
|
||||||
|
Name: ast.NewIdent("."),
|
||||||
|
},
|
||||||
|
&ast.ImportSpec{Path: &ast.BasicLit{Kind: token.STRING, Value: `"github.com/go-test/deep"`}},
|
||||||
|
&ast.ImportSpec{Path: &ast.BasicLit{Kind: token.STRING, Value: `"github.com/stretchr/testify/assert"`}},
|
||||||
|
&ast.ImportSpec{Path: &ast.BasicLit{Kind: token.STRING, Value: `"github.com/stretchr/testify/require"`}},
|
||||||
|
}...)
|
||||||
|
return specs
|
||||||
|
}(),
|
||||||
},
|
},
|
||||||
}, testList...),
|
}, testList...),
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user