test: expand coverage across readers, writers, cmd, ui, diff and merge
Implements tests/_plans and previously deferred packages; updates plan README with new coverage numbers.
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type sortCase struct {
|
||||
name string
|
||||
seq uint
|
||||
}
|
||||
|
||||
var sortFixture = []sortCase{{"Banana", 3}, {"apple", 1}, {"Cherry", 2}}
|
||||
|
||||
var (
|
||||
wantNameAsc = []string{"apple", "Banana", "Cherry"}
|
||||
wantNameDesc = []string{"Cherry", "Banana", "apple"}
|
||||
wantSeqAsc = []string{"apple", "Cherry", "Banana"}
|
||||
wantSeqDesc = []string{"Banana", "Cherry", "apple"}
|
||||
)
|
||||
|
||||
func checkNames(t *testing.T, label string, got, want []string) {
|
||||
t.Helper()
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("%s: got %v, want %v", label, got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// runSortSuite exercises a by-name and by-sequence sorter pair over the shared fixture.
|
||||
func runSortSuite[T any](t *testing.T, build func(sortCase) T, name func(T) string,
|
||||
byName func([]T, bool) error, bySeq func([]T, bool) error) {
|
||||
t.Helper()
|
||||
mk := func() []T {
|
||||
out := make([]T, 0, len(sortFixture))
|
||||
for _, c := range sortFixture {
|
||||
out = append(out, build(c))
|
||||
}
|
||||
return out
|
||||
}
|
||||
names := func(items []T) []string {
|
||||
out := make([]string, 0, len(items))
|
||||
for _, it := range items {
|
||||
out = append(out, name(it))
|
||||
}
|
||||
return out
|
||||
}
|
||||
if byName != nil {
|
||||
items := mk()
|
||||
_ = byName(items, false)
|
||||
checkNames(t, "name asc", names(items), wantNameAsc)
|
||||
_ = byName(items, true)
|
||||
checkNames(t, "name desc", names(items), wantNameDesc)
|
||||
_ = byName(nil, false)
|
||||
_ = byName([]T{}, true)
|
||||
}
|
||||
if bySeq != nil {
|
||||
items := mk()
|
||||
_ = bySeq(items, false)
|
||||
checkNames(t, "seq asc", names(items), wantSeqAsc)
|
||||
_ = bySeq(items, true)
|
||||
checkNames(t, "seq desc", names(items), wantSeqDesc)
|
||||
_ = bySeq(nil, false)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSortSchemas(t *testing.T) {
|
||||
runSortSuite(t, func(c sortCase) *Schema { return &Schema{Name: c.name, Sequence: c.seq} },
|
||||
func(s *Schema) string { return s.Name }, SortSchemasByName, SortSchemasBySequence)
|
||||
}
|
||||
|
||||
func TestSortTables(t *testing.T) {
|
||||
runSortSuite(t, func(c sortCase) *Table { return &Table{Name: c.name, Sequence: c.seq} },
|
||||
func(s *Table) string { return s.Name }, SortTablesByName, SortTablesBySequence)
|
||||
}
|
||||
|
||||
func TestSortColumns(t *testing.T) {
|
||||
runSortSuite(t, func(c sortCase) *Column { return &Column{Name: c.name, Sequence: c.seq} },
|
||||
func(s *Column) string { return s.Name }, SortColumnsByName, SortColumnsBySequence)
|
||||
}
|
||||
|
||||
func TestSortViews(t *testing.T) {
|
||||
runSortSuite(t, func(c sortCase) *View { return &View{Name: c.name, Sequence: c.seq} },
|
||||
func(s *View) string { return s.Name }, SortViewsByName, SortViewsBySequence)
|
||||
}
|
||||
|
||||
func TestSortSequences(t *testing.T) {
|
||||
runSortSuite(t, func(c sortCase) *Sequence { return &Sequence{Name: c.name, Sequence: c.seq} },
|
||||
func(s *Sequence) string { return s.Name }, SortSequencesByName, SortSequencesBySequence)
|
||||
}
|
||||
|
||||
func TestSortIndexes(t *testing.T) {
|
||||
runSortSuite(t, func(c sortCase) *Index { return &Index{Name: c.name, Sequence: c.seq} },
|
||||
func(s *Index) string { return s.Name }, SortIndexesByName, SortIndexesBySequence)
|
||||
}
|
||||
|
||||
func TestSortNameOnly(t *testing.T) {
|
||||
runSortSuite(t, func(c sortCase) *Constraint { return &Constraint{Name: c.name} },
|
||||
func(s *Constraint) string { return s.Name }, SortConstraintsByName, nil)
|
||||
runSortSuite(t, func(c sortCase) *Relationship { return &Relationship{Name: c.name} },
|
||||
func(s *Relationship) string { return s.Name }, SortRelationshipsByName, nil)
|
||||
runSortSuite(t, func(c sortCase) *Script { return &Script{Name: c.name} },
|
||||
func(s *Script) string { return s.Name }, SortScriptsByName, nil)
|
||||
runSortSuite(t, func(c sortCase) *Enum { return &Enum{Name: c.name} },
|
||||
func(s *Enum) string { return s.Name }, SortEnumsByName, nil)
|
||||
}
|
||||
|
||||
func TestSortStableForTies(t *testing.T) {
|
||||
cols := []*Column{{Name: "x", Description: "first"}, {Name: "X", Description: "second"}, {Name: "x", Description: "third"}}
|
||||
_ = SortColumnsByName(cols, false)
|
||||
if cols[0].Description != "first" || cols[1].Description != "second" || cols[2].Description != "third" {
|
||||
t.Errorf("ties must keep input order: %v %v %v", cols[0].Description, cols[1].Description, cols[2].Description)
|
||||
}
|
||||
_ = SortColumnsBySequence(cols, true)
|
||||
if cols[0].Description != "first" || cols[2].Description != "third" {
|
||||
t.Errorf("sequence ties must keep input order")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSortMapVariants(t *testing.T) {
|
||||
cols := map[string]*Column{}
|
||||
idx := map[string]*Index{}
|
||||
cons := map[string]*Constraint{}
|
||||
rels := map[string]*Relationship{}
|
||||
for _, c := range sortFixture {
|
||||
cols[c.name] = &Column{Name: c.name, Sequence: c.seq}
|
||||
idx[c.name] = &Index{Name: c.name, Sequence: c.seq}
|
||||
cons[c.name] = &Constraint{Name: c.name}
|
||||
rels[c.name] = &Relationship{Name: c.name}
|
||||
}
|
||||
colNames := func(l []*Column) (o []string) {
|
||||
for _, x := range l {
|
||||
o = append(o, x.Name)
|
||||
}
|
||||
return
|
||||
}
|
||||
idxNames := func(l []*Index) (o []string) {
|
||||
for _, x := range l {
|
||||
o = append(o, x.Name)
|
||||
}
|
||||
return
|
||||
}
|
||||
conNames := func(l []*Constraint) (o []string) {
|
||||
for _, x := range l {
|
||||
o = append(o, x.Name)
|
||||
}
|
||||
return
|
||||
}
|
||||
relNames := func(l []*Relationship) (o []string) {
|
||||
for _, x := range l {
|
||||
o = append(o, x.Name)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
checkNames(t, "cols name", colNames(SortColumnsMapByName(cols, false)), wantNameAsc)
|
||||
checkNames(t, "cols name desc", colNames(SortColumnsMapByName(cols, true)), wantNameDesc)
|
||||
checkNames(t, "cols seq", colNames(SortColumnsMapBySequence(cols, false)), wantSeqAsc)
|
||||
checkNames(t, "cols seq desc", colNames(SortColumnsMapBySequence(cols, true)), wantSeqDesc)
|
||||
checkNames(t, "idx name", idxNames(SortIndexesMapByName(idx, false)), wantNameAsc)
|
||||
checkNames(t, "idx seq", idxNames(SortIndexesMapBySequence(idx, true)), wantSeqDesc)
|
||||
checkNames(t, "con name", conNames(SortConstraintsMapByName(cons, false)), wantNameAsc)
|
||||
checkNames(t, "rel name", relNames(SortRelationshipsMapByName(rels, true)), wantNameDesc)
|
||||
|
||||
if got := SortColumnsMapByName(nil, false); got == nil || len(got) != 0 {
|
||||
t.Errorf("nil map must give non-nil empty slice")
|
||||
}
|
||||
if len(cols) != 3 {
|
||||
t.Error("input map must not be modified")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user