package bun import ( "go/ast" "go/parser" "go/token" "testing" "git.warky.dev/wdevs/relspecgo/pkg/readers" ) func newTestReader() *Reader { return NewReader(&readers.ReaderOptions{}) } func mustExpr(t *testing.T, src string) ast.Expr { t.Helper() e, err := parser.ParseExpr(src) if err != nil { t.Fatal(err) } return e } func TestGoTypeToSQL(t *testing.T) { r := newTestReader() tests := []struct{ src, want string }{ {"int", "integer"}, {"int32", "integer"}, {"int64", "bigint"}, {"string", "text"}, {"bool", "boolean"}, {"float32", "real"}, {"float64", "double precision"}, {"uint8", "text"}, {"time.Time", "timestamp"}, {"time.Duration", "text"}, {"sql_types.SqlString", "text"}, {"sql_types.SqlInt", "integer"}, {"sql_types.SqlInt64", "bigint"}, {"sql_types.SqlFloat", "double precision"}, {"sql_types.SqlBool", "boolean"}, {"sql_types.SqlTime", "timestamp"}, {"sql_types.Other", "text"}, {"other.Thing", "text"}, {"*int64", "bigint"}, {"*time.Time", "timestamp"}, {"[]byte", "text"}, } for _, tt := range tests { t.Run(tt.src, func(t *testing.T) { if got := r.goTypeToSQL(mustExpr(t, tt.src)); got != tt.want { t.Errorf("got %q want %q", got, tt.want) } }) } } func TestDeriveTableName(t *testing.T) { r := newTestReader() for in, want := range map[string]string{ "ModelUser": "user", "ModelUserRole": "user_role", "Account": "account", "OrderItem": "order_item", } { if got := r.deriveTableName(in); got != want { t.Errorf("%q: got %q want %q", in, got, want) } } } func TestGetReceiverType(t *testing.T) { r := newTestReader() for src, want := range map[string]string{"User": "User", "*User": "User", "*pkg.User": "", "[]User": ""} { if got := r.getReceiverType(mustExpr(t, src)); got != want { t.Errorf("%s: got %q want %q", src, got, want) } } } func TestGetRelationType(t *testing.T) { r := newTestReader() for tag, want := range map[string]string{ `bun:"rel:has-many,join:id=user_id"`: "has-many", `bun:"rel:belongs-to,join:user_id=id"`: "belongs-to", `bun:"rel:has-one,join:id=user_id"`: "has-one", `bun:"rel:many-to-many,join_table:x"`: "many-to-many", `bun:"rel:unknown"`: "", `bun:"id,pk"`: "", } { if got := r.getRelationType(tag); got != want { t.Errorf("%s: got %q want %q", tag, got, want) } } } func TestParseTableNameMethod(t *testing.T) { r := newTestReader() parse := func(src string) *ast.FuncDecl { f, err := parser.ParseFile(token.NewFileSet(), "x.go", "package p\n"+src, 0) if err != nil { t.Fatal(err) } return f.Decls[0].(*ast.FuncDecl) } if tbl, sch := r.parseTableNameMethod(parse(`func (User) TableName() string { return "public.users" }`)); tbl != "users" || sch != "public" { t.Errorf("qualified: %q %q", tbl, sch) } if tbl, sch := r.parseTableNameMethod(parse(`func (User) TableName() string { return "users" }`)); tbl != "users" || sch != "public" { t.Errorf("plain: %q %q", tbl, sch) } if tbl, _ := r.parseTableNameMethod(parse(`func (User) TableName() string`)); tbl != "" { t.Errorf("no body: %q", tbl) } if tbl, _ := r.parseTableNameMethod(parse(`func (User) TableName() string { x := 1; _ = x; return foo() }`)); tbl != "" { t.Errorf("non-literal: %q", tbl) } }