Implements tests/_plans and previously deferred packages; updates plan README with new coverage numbers.
115 lines
2.9 KiB
Go
115 lines
2.9 KiB
Go
package drizzle
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"git.warky.dev/wdevs/relspecgo/pkg/models"
|
|
"git.warky.dev/wdevs/relspecgo/pkg/readers"
|
|
)
|
|
|
|
const fixture = "../../../tests/assets/drizzle/schema.ts"
|
|
|
|
func readFile(t *testing.T, path string) *models.Database {
|
|
t.Helper()
|
|
db, err := NewReader(&readers.ReaderOptions{FilePath: path}).ReadDatabase()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return db
|
|
}
|
|
|
|
func findTable(db *models.Database, name string) *models.Table {
|
|
for _, s := range db.Schemas {
|
|
for _, tb := range s.Tables {
|
|
if tb.Name == name {
|
|
return tb
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func TestReadFixture(t *testing.T) {
|
|
db := readFile(t, fixture)
|
|
if len(db.Schemas) == 0 || len(db.Schemas[0].Tables) == 0 {
|
|
t.Fatal("expected tables")
|
|
}
|
|
if len(db.Schemas[0].Enums) != 1 || db.Schemas[0].Enums[0].Name != "Role" {
|
|
t.Fatalf("enums = %+v", db.Schemas[0].Enums)
|
|
}
|
|
var found bool
|
|
for _, tb := range db.Schemas[0].Tables {
|
|
if c, ok := tb.Columns["role"]; ok {
|
|
found = true
|
|
if c.Type != "Role" {
|
|
t.Errorf("role type = %q", c.Type)
|
|
}
|
|
}
|
|
for n := range tb.Columns {
|
|
if n == "profile" {
|
|
t.Errorf("relation field leaked as column in %s", tb.Name)
|
|
}
|
|
}
|
|
}
|
|
if !found {
|
|
t.Error("no role column")
|
|
}
|
|
}
|
|
|
|
func TestEnumColumnSyntax(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
src string
|
|
}{
|
|
{"enum constant", "export const role = pgEnum('Role', ['A','B']);\nexport const users = pgTable('users', {\n role: role('role').notNull(),\n});\n"},
|
|
{"legacy", "export const role = pgEnum('Role', ['A','B']);\nexport const users = pgTable('users', {\n role: pgEnum('Role')('role').notNull(),\n});\n"},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
p := filepath.Join(t.TempDir(), "s.ts")
|
|
if err := os.WriteFile(p, []byte(tt.src), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
tb := findTable(readFile(t, p), "users")
|
|
if tb == nil {
|
|
t.Fatal("users missing")
|
|
}
|
|
c := tb.Columns["role"]
|
|
if c == nil || c.Type != "Role" || !c.NotNull {
|
|
t.Errorf("column = %+v", c)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReadDirectorySeparateEnums(t *testing.T) {
|
|
dir := t.TempDir()
|
|
files := map[string]string{
|
|
"enums.ts": "export const status = pgEnum('Status', ['on','off']);\n",
|
|
"tables.ts": "export const items = pgTable('items', {\n status: status('status'),\n});\n",
|
|
}
|
|
for n, c := range files {
|
|
if err := os.WriteFile(filepath.Join(dir, n), []byte(c), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
tb := findTable(readFile(t, dir), "items")
|
|
if tb == nil {
|
|
t.Fatal("items missing")
|
|
}
|
|
if c := tb.Columns["status"]; c == nil || c.Type != "Status" {
|
|
t.Errorf("column = %+v", c)
|
|
}
|
|
}
|
|
|
|
func TestReaderErrors(t *testing.T) {
|
|
if _, err := NewReader(&readers.ReaderOptions{}).ReadDatabase(); err == nil {
|
|
t.Error("expected error for empty path")
|
|
}
|
|
if _, err := NewReader(&readers.ReaderOptions{FilePath: "/nonexistent.ts"}).ReadDatabase(); err == nil {
|
|
t.Error("expected error for missing file")
|
|
}
|
|
}
|