252 lines
7.4 KiB
Go
252 lines
7.4 KiB
Go
package modelgenerate
|
|
|
|
import (
|
|
"fmt"
|
|
"go/ast"
|
|
"go/token"
|
|
|
|
"git.offline-twitter.com/offline-labs/gas-stack/pkg/schema"
|
|
)
|
|
|
|
// GenerateModelTestAST produces an AST for a starter test file for a given model.
|
|
func GenerateModelTestAST(tbl schema.Table, gomodName string) *ast.File {
|
|
packageName := "db"
|
|
testpackageName := packageName + "_test"
|
|
|
|
testDBDecl := &ast.GenDecl{
|
|
Tok: token.VAR,
|
|
Specs: []ast.Spec{
|
|
&ast.ValueSpec{
|
|
Names: []*ast.Ident{ast.NewIdent("TestDB")},
|
|
Type: &ast.StarExpr{X: ast.NewIdent("DB")},
|
|
},
|
|
},
|
|
}
|
|
|
|
initFuncDecl := &ast.FuncDecl{
|
|
Name: ast.NewIdent("init"),
|
|
Type: &ast.FuncType{Params: &ast.FieldList{}},
|
|
Body: &ast.BlockStmt{
|
|
List: []ast.Stmt{
|
|
&ast.AssignStmt{
|
|
Lhs: []ast.Expr{ast.NewIdent("TestDB")},
|
|
Tok: token.ASSIGN,
|
|
Rhs: []ast.Expr{&ast.CallExpr{
|
|
Fun: ast.NewIdent("MakeDB"),
|
|
Args: []ast.Expr{&ast.BasicLit{Kind: token.STRING, Value: `"tmp"`}},
|
|
}},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
makeDBHelperDecl := &ast.FuncDecl{
|
|
Name: ast.NewIdent("MakeDB"),
|
|
Type: &ast.FuncType{
|
|
Params: &ast.FieldList{
|
|
List: []*ast.Field{{
|
|
Names: []*ast.Ident{ast.NewIdent("dbName")},
|
|
Type: ast.NewIdent("string"),
|
|
}},
|
|
},
|
|
Results: &ast.FieldList{
|
|
List: []*ast.Field{{Type: &ast.StarExpr{X: ast.NewIdent("DB")}}},
|
|
},
|
|
},
|
|
Body: &ast.BlockStmt{
|
|
List: []ast.Stmt{
|
|
// db := Must(Create(fmt.Sprintf("file:%s?mode=memory&cache=shared", dbName)))
|
|
&ast.AssignStmt{
|
|
Lhs: []ast.Expr{ast.NewIdent("db")},
|
|
Tok: token.DEFINE,
|
|
Rhs: []ast.Expr{&ast.CallExpr{
|
|
Fun: ast.NewIdent("Must"),
|
|
Args: []ast.Expr{&ast.CallExpr{
|
|
Fun: ast.NewIdent("Create"),
|
|
Args: []ast.Expr{&ast.CallExpr{
|
|
Fun: ast.NewIdent("fmt.Sprintf"),
|
|
Args: []ast.Expr{
|
|
&ast.BasicLit{Kind: token.STRING, Value: `"file:%s?mode=memory&cache=shared"`},
|
|
ast.NewIdent("dbName"),
|
|
},
|
|
}},
|
|
}},
|
|
}},
|
|
},
|
|
// return db
|
|
&ast.ReturnStmt{
|
|
Results: []ast.Expr{ast.NewIdent("db")},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
testObj := ast.NewIdent("item")
|
|
testObj2 := ast.NewIdent("item2")
|
|
fieldName := ast.NewIdent("Description")
|
|
description1 := `"an item"`
|
|
description2 := `"a big item"`
|
|
|
|
return &ast.File{
|
|
Name: ast.NewIdent(testpackageName),
|
|
Decls: []ast.Decl{
|
|
&ast.GenDecl{
|
|
Tok: token.IMPORT,
|
|
Specs: []ast.Spec{
|
|
&ast.ImportSpec{Path: &ast.BasicLit{Kind: token.STRING, Value: `"fmt"`}},
|
|
&ast.ImportSpec{Path: &ast.BasicLit{Kind: token.STRING, Value: `"testing"`}},
|
|
&ast.ImportSpec{
|
|
Path: &ast.BasicLit{Kind: token.STRING, Value: `"git.offline-twitter.com/offline-labs/gas-stack/pkg/db"`},
|
|
Name: ast.NewIdent("db"),
|
|
},
|
|
&ast.ImportSpec{
|
|
Path: &ast.BasicLit{Kind: token.STRING, Value: `"git.offline-twitter.com/offline-labs/gas-stack/pkg/flowutils"`},
|
|
Name: ast.NewIdent("."),
|
|
},
|
|
&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/stretchr/testify/assert"`}},
|
|
&ast.ImportSpec{Path: &ast.BasicLit{Kind: token.STRING, Value: `"github.com/stretchr/testify/require"`}},
|
|
},
|
|
},
|
|
// var TestDB *DB
|
|
testDBDecl,
|
|
|
|
// func init() { TestDB = MakeDB("tmp") }
|
|
initFuncDecl,
|
|
|
|
// func MakeDB(dbName string) *DB { db := Must(Create(fmt.Sprintf("file:%s?mode=memory&cache=shared", dbName))); return db }
|
|
makeDBHelperDecl,
|
|
|
|
&ast.FuncDecl{
|
|
Name: ast.NewIdent("TestCreateUpdateDelete" + tbl.TypeName),
|
|
Type: &ast.FuncType{
|
|
Params: &ast.FieldList{
|
|
List: []*ast.Field{{
|
|
Names: []*ast.Ident{ast.NewIdent("t")},
|
|
Type: ast.NewIdent("*testing.T"),
|
|
}},
|
|
},
|
|
},
|
|
Body: &ast.BlockStmt{
|
|
List: []ast.Stmt{
|
|
// item := Item{Description: "an item"}
|
|
&ast.AssignStmt{
|
|
Lhs: []ast.Expr{testObj},
|
|
Tok: token.DEFINE,
|
|
Rhs: []ast.Expr{&ast.CompositeLit{
|
|
Type: ast.NewIdent(tbl.TypeName),
|
|
Elts: []ast.Expr{
|
|
&ast.KeyValueExpr{
|
|
Key: fieldName,
|
|
Value: &ast.BasicLit{Kind: token.STRING, Value: description1},
|
|
},
|
|
},
|
|
}},
|
|
},
|
|
|
|
// TestDB.SaveItem(&item)
|
|
&ast.ExprStmt{X: &ast.CallExpr{
|
|
Fun: ast.NewIdent("TestDB.Save" + tbl.TypeName),
|
|
Args: []ast.Expr{&ast.UnaryExpr{Op: token.AND, X: testObj}},
|
|
}},
|
|
|
|
// require.NotZero(t, item.ID)
|
|
&ast.ExprStmt{X: &ast.CallExpr{
|
|
Fun: ast.NewIdent("require.NotZero"),
|
|
Args: []ast.Expr{ast.NewIdent("t"), &ast.SelectorExpr{X: testObj, Sel: ast.NewIdent("ID")}},
|
|
}},
|
|
|
|
// item2 := Must(TestDB.GetItemByID(item.ID))
|
|
&ast.AssignStmt{
|
|
Lhs: []ast.Expr{testObj2},
|
|
Tok: token.DEFINE,
|
|
Rhs: []ast.Expr{&ast.CallExpr{
|
|
Fun: ast.NewIdent("Must"),
|
|
Args: []ast.Expr{&ast.CallExpr{
|
|
Fun: ast.NewIdent("TestDB.Get" + tbl.TypeName + "ByID"),
|
|
Args: []ast.Expr{&ast.SelectorExpr{X: testObj, Sel: ast.NewIdent("ID")}},
|
|
}},
|
|
}},
|
|
},
|
|
|
|
// assert.Equal(t, "an item", item2.Description)
|
|
&ast.ExprStmt{X: &ast.CallExpr{
|
|
Fun: ast.NewIdent("assert.Equal"),
|
|
Args: []ast.Expr{
|
|
ast.NewIdent("t"),
|
|
&ast.BasicLit{Kind: token.STRING, Value: description1},
|
|
&ast.SelectorExpr{X: testObj2, Sel: fieldName},
|
|
},
|
|
}},
|
|
|
|
// item.Description = "a big item"
|
|
&ast.AssignStmt{
|
|
Lhs: []ast.Expr{&ast.SelectorExpr{X: testObj, Sel: fieldName}},
|
|
Tok: token.ASSIGN,
|
|
Rhs: []ast.Expr{&ast.BasicLit{Kind: token.STRING, Value: description2}},
|
|
},
|
|
|
|
// TestDB.SaveItem(&item)
|
|
&ast.ExprStmt{X: &ast.CallExpr{
|
|
Fun: ast.NewIdent("TestDB.Save" + tbl.TypeName),
|
|
Args: []ast.Expr{&ast.UnaryExpr{Op: token.AND, X: testObj}},
|
|
}},
|
|
|
|
// item2 = Must(TestDB.GetItemByID(item.ID))
|
|
&ast.AssignStmt{
|
|
Lhs: []ast.Expr{testObj2},
|
|
Tok: token.ASSIGN,
|
|
Rhs: []ast.Expr{&ast.CallExpr{
|
|
Fun: ast.NewIdent("Must"),
|
|
Args: []ast.Expr{&ast.CallExpr{
|
|
Fun: ast.NewIdent("TestDB.Get" + tbl.TypeName + "ByID"),
|
|
Args: []ast.Expr{&ast.SelectorExpr{X: testObj, Sel: ast.NewIdent("ID")}},
|
|
}},
|
|
}},
|
|
},
|
|
|
|
// assert.Equal(t, item.Description, item2.Description)
|
|
&ast.ExprStmt{X: &ast.CallExpr{
|
|
Fun: ast.NewIdent("assert.Equal"),
|
|
Args: []ast.Expr{
|
|
ast.NewIdent("t"),
|
|
&ast.SelectorExpr{X: testObj, Sel: fieldName},
|
|
&ast.SelectorExpr{X: testObj2, Sel: fieldName},
|
|
},
|
|
}},
|
|
|
|
// TestDB.DeleteItem(item)
|
|
&ast.ExprStmt{X: &ast.CallExpr{
|
|
Fun: ast.NewIdent("TestDB.Delete" + tbl.TypeName),
|
|
Args: []ast.Expr{testObj},
|
|
}},
|
|
|
|
// _, err := TestDB.GetItemByID(item.ID)
|
|
&ast.AssignStmt{
|
|
Lhs: []ast.Expr{ast.NewIdent("_"), ast.NewIdent("err")},
|
|
Tok: token.DEFINE,
|
|
Rhs: []ast.Expr{&ast.CallExpr{
|
|
Fun: ast.NewIdent("TestDB.Get" + tbl.TypeName + "ByID"),
|
|
Args: []ast.Expr{&ast.SelectorExpr{X: testObj, Sel: ast.NewIdent("ID")}},
|
|
}},
|
|
},
|
|
|
|
// assert.ErrorIs(t, err, db.ErrNotInDB)
|
|
&ast.ExprStmt{X: &ast.CallExpr{
|
|
Fun: ast.NewIdent("assert.ErrorIs"),
|
|
Args: []ast.Expr{
|
|
ast.NewIdent("t"),
|
|
ast.NewIdent("err"),
|
|
&ast.SelectorExpr{X: ast.NewIdent("db"), Sel: ast.NewIdent("ErrNotInDB")},
|
|
},
|
|
}},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|