package ui import ( "reflect" "testing" "git.warky.dev/wdevs/relspecgo/pkg/models" ) func TestColumnDataOps(t *testing.T) { se := newTestEditor() if se.CreateColumn(5, 0, "x", "int", false, false) != nil || se.CreateColumn(0, 5, "x", "int", false, false) != nil { t.Error("create with bad index must return nil") } col := se.CreateColumn(0, 0, "age", "integer", true, true) if col == nil || col.Type != "integer" || !col.IsPrimaryKey || !col.NotNull { t.Fatalf("create: %+v", col) } if se.GetColumn(0, 0, "age") != col || se.GetColumn(0, 0, "nope") != nil || se.GetColumn(9, 0, "age") != nil { t.Error("get mismatch") } if se.CreateColumn(0, 0, "a", "text", false, false) == nil { t.Error("create second column") } tests := []struct { name string si, ti int old, new string want bool }{ {"bad table", 0, 9, "age", "age", false}, {"missing column", 0, 0, "zzz", "zzz", false}, {"in place", 0, 0, "age", "age", true}, {"rename", 0, 0, "age", "years", true}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := se.UpdateColumn(tt.si, tt.ti, tt.old, tt.new, "bigint", false, true, "0", "desc"); got != tt.want { t.Errorf("got %v", got) } }) } got := se.GetColumn(0, 0, "years") if got == nil || got.Name != "years" || got.Type != "bigint" || got.IsPrimaryKey || got.Default != "0" || got.Description != "desc" { t.Errorf("after update: %+v", got) } if se.GetColumn(0, 0, "age") != nil { t.Error("old name must be gone") } if len(se.GetAllColumns(0, 0)) != 4 || se.GetAllColumns(0, 9) != nil { t.Error("GetAllColumns") } if se.DeleteColumn(0, 9, "a") || se.DeleteColumn(0, 0, "zzz") { t.Error("delete bad target must fail") } if !se.DeleteColumn(0, 0, "a") || se.DeleteColumn(0, 0, "a") { t.Error("delete should succeed once") } } func TestCreateColumn_NilMap(t *testing.T) { se := newTestEditor() se.db.Schemas[0].Tables[0].Columns = nil if se.CreateColumn(0, 0, "a", "text", false, false) == nil { t.Error("create with nil map") } } func TestRelationshipDataOps(t *testing.T) { se := newTestEditor() rel := &models.Relationship{Name: "fk_a", FromTable: "users", ToTable: "orders"} if se.CreateRelationship(9, 0, rel) != nil || se.CreateRelationship(0, 9, rel) != nil || se.CreateRelationship(0, -1, rel) != nil { t.Error("create bad index") } // Before any relationship exists, update/delete/get/names report nothing. se.db.Schemas[0].Tables[0].Relationships = nil if se.UpdateRelationship(0, 0, "fk_a", rel) || se.DeleteRelationship(0, 0, "fk_a") || se.GetRelationship(0, 0, "fk_a") != nil || se.GetRelationshipNames(0, 0) != nil { t.Error("nil map handling") } if se.CreateRelationship(0, 0, rel) != rel { t.Fatal("create") } se.CreateRelationship(0, 0, &models.Relationship{Name: "fk_0"}) if got := se.GetRelationshipNames(0, 0); !reflect.DeepEqual(got, []string{"fk_0", "fk_a"}) { t.Errorf("names must be sorted: %v", got) } if se.GetRelationship(0, 0, "fk_a") != rel || se.GetRelationship(0, 0, "none") != nil { t.Error("get") } renamed := &models.Relationship{Name: "fk_b"} if !se.UpdateRelationship(0, 0, "fk_a", renamed) { t.Fatal("update") } if se.GetRelationship(0, 0, "fk_a") != nil || se.GetRelationship(0, 0, "fk_b") != renamed { t.Error("rename") } if se.UpdateRelationship(9, 0, "x", renamed) || se.UpdateRelationship(0, 9, "x", renamed) { t.Error("update bad index") } if se.DeleteRelationship(9, 0, "x") || se.DeleteRelationship(0, 9, "x") { t.Error("delete bad index") } if !se.DeleteRelationship(0, 0, "fk_b") || se.GetRelationship(0, 0, "fk_b") != nil { t.Error("delete") } if se.GetRelationship(9, 0, "x") != nil || se.GetRelationship(0, 9, "x") != nil || se.GetRelationshipNames(9, 0) != nil || se.GetRelationshipNames(0, 9) != nil { t.Error("bad index reads") } } func TestSchemaDataOps(t *testing.T) { se := newTestEditor() s := se.CreateSchema("sales", "desc") if s == nil || s.Name != "sales" || s.Description != "desc" || s.Tables == nil || s.Sequences == nil || s.Enums == nil { t.Fatalf("create: %+v", s) } if len(se.GetAllSchemas()) != 2 || se.GetSchema(1) != s || se.GetSchema(2) != nil || se.GetSchema(-1) != nil { t.Error("get") } se.UpdateSchema(1, "billing", "owner", "d2") if s.Name != "billing" || s.Owner != "owner" || s.Description != "d2" { t.Errorf("update: %+v", s) } se.UpdateSchema(9, "x", "x", "x") // no panic if se.DeleteSchema(9) || se.DeleteSchema(-1) { t.Error("delete bad index") } if !se.DeleteSchema(1) || len(se.db.Schemas) != 1 { t.Error("delete") } } func TestTableDataOps(t *testing.T) { se := newTestEditor() if se.CreateTable(9, "x", "") != nil { t.Error("create bad schema") } tbl := se.CreateTable(0, "orders", "d") if tbl == nil || tbl.Schema != "public" || tbl.Columns == nil || tbl.Constraints == nil || tbl.Indexes == nil { t.Fatalf("create: %+v", tbl) } if se.GetTable(0, 1) != tbl || se.GetTable(0, 2) != nil || se.GetTable(9, 0) != nil || se.GetTable(0, -1) != nil { t.Error("get") } if len(se.GetAllTables()) != 2 || len(se.GetTablesInSchema(0)) != 2 || se.GetTablesInSchema(9) != nil { t.Error("get all") } se.UpdateTable(0, 1, "orders2", "d2") if tbl.Name != "orders2" || tbl.Description != "d2" { t.Errorf("update: %+v", tbl) } se.UpdateTable(9, 0, "x", "x") se.UpdateTable(0, 9, "x", "x") if se.DeleteTable(9, 0) || se.DeleteTable(0, 9) { t.Error("delete bad index") } if !se.DeleteTable(0, 1) || len(se.db.Schemas[0].Tables) != 1 { t.Error("delete") } } func TestUpdateDatabase(t *testing.T) { se := newTestEditor() se.updateDatabase("n", "d", "c", "pgsql", "16") db := se.db if db.Name != "n" || db.Description != "d" || db.Comment != "c" || db.DatabaseType != models.PostgresqlDatabaseType || db.DatabaseVersion != "16" { t.Errorf("%+v", db) } } func TestDomainDataOps(t *testing.T) { se := NewSchemaEditor(models.InitDatabase("d")) se.createDomain("a", "da") se.createDomain("b", "db") if len(se.db.Domains) != 2 || se.db.Domains[1].Sequence != 1 { t.Fatalf("create: %+v", se.db.Domains) } se.updateDomain(0, "a2", "da2") se.updateDomain(9, "x", "x") if se.db.Domains[0].Name != "a2" || se.db.Domains[0].Description != "da2" { t.Error("update") } se.deleteDomain(9) se.deleteDomain(-1) se.deleteDomain(0) if len(se.db.Domains) != 1 || se.db.Domains[0].Name != "b" { t.Errorf("delete: %+v", se.db.Domains) } }