package migrate import ( "strings" "testing" "testing/fstest" ) func TestMigrationsRunInNumericOrderNotAlphabetical(t *testing.T) { // The bug this prevents: at ten migrations, "10_x.sql" sorts before // "9_x.sql" as text, so the tenth would run before the ninth and the // failure would be a column that does not exist yet - on the day the // project happens to reach double figures. src := fstest.MapFS{ "002_b.sql": {Data: []byte("select 2")}, "010_j.sql": {Data: []byte("select 10")}, "009_i.sql": {Data: []byte("select 9")}, "001_a.sql": {Data: []byte("select 1")}, } files, err := Load(src) if err != nil { t.Fatalf("load: %v", err) } got := make([]int, len(files)) for i, f := range files { got[i] = f.Version } want := []int{1, 2, 9, 10} for i := range want { if got[i] != want[i] { t.Fatalf("order was %v, want %v", got, want) } } } func TestTwoFilesCannotShareAVersion(t *testing.T) { // Two people adding "008" on separate branches is the ordinary way this // happens. Whichever runs first is then decided by the filesystem, which is // not an order, and one of them silently never runs at all. _, err := Load(fstest.MapFS{ "008_one.sql": {Data: []byte("select 1")}, "008_two.sql": {Data: []byte("select 2")}, }) if err == nil { t.Fatal("duplicate versions were accepted") } if !strings.Contains(err.Error(), "share version 8") { t.Fatalf("error does not name the collision: %v", err) } } func TestAFileThatIsNotNumberedIsRejected(t *testing.T) { for _, name := range []string{"schema.sql", "abc_x.sql", "0_zero.sql"} { if _, err := Load(fstest.MapFS{name: {Data: []byte("select 1")}}); err == nil { t.Fatalf("%s was accepted as a migration", name) } } } func TestTheChecksumChangesWithTheContent(t *testing.T) { // What makes an edited-after-applying migration detectable at all. a, err := Load(fstest.MapFS{"001_a.sql": {Data: []byte("select 1")}}) if err != nil { t.Fatal(err) } b, err := Load(fstest.MapFS{"001_a.sql": {Data: []byte("select 2")}}) if err != nil { t.Fatal(err) } if a[0].Checksum == b[0].Checksum { t.Fatal("two different migrations hashed the same") } }