diff --git a/spec/action_migrate_dsl_statement_ordering_test.go b/spec/action_migrate_dsl_statement_ordering_test.go new file mode 100644 index 0000000..dd79259 --- /dev/null +++ b/spec/action_migrate_dsl_statement_ordering_test.go @@ -0,0 +1,58 @@ +package spec + +import ( + "testing" +) + +func TestActionMigrateDslStatementOrdering(t *testing.T) { + c := mockCli(mockConfig(` +migration "create_animals" { + version = "v1" + + up { + create_table "animals" { + column "id" "bigint" {} + } + + create_index "animals" "idx_id" { + columns = ["id"] + } + + sql = "ALTER INDEX idx_id RENAME TO idx_new" + + drop_index "idx_new" {} + + drop_table "animals" {} + } + + down {} +} + +migration_set "animals" { + migrations = [ + migration.create_animals + ] +} +`)) + defer c.Teardown() + if c.AssertSuccessfulRun(t, []string{"migrate", "up", "animals"}) { + c.AssertSchemaMigrationTable(t, "public", "v1") + c.AssertSQLContains(t, ` +CREATE TABLE "animals"( + "id" bigint +) + `) + c.AssertSQLContains(t, ` +CREATE INDEX "idx_id" ON "animals" + `) + c.AssertSQLContains(t, ` +ALTER INDEX idx_id RENAME TO idx_new + `) + c.AssertSQLContains(t, ` +DROP INDEX "idx_new" + `) + c.AssertSQLContains(t, ` +DROP TABLE "animals" + `) + } +} diff --git a/spec/helpers_test.go b/spec/helpers_test.go index f5451ae..fead0ac 100644 --- a/spec/helpers_test.go +++ b/spec/helpers_test.go @@ -32,7 +32,8 @@ type cliMock struct { func (m *cliMock) setup(args []string) { m.connection = &mockDBConnection{ - recorder: []string{}, + recorder: []string{}, + assertedSQLIndex: 0, } m.errorWriter = bytes.Buffer{} m.helpWriter = bytes.Buffer{} @@ -158,13 +159,37 @@ func (m *cliMock) AssertSchemaMigrationTable(t *testing.T, schema string, expect return false } +// AssertSQLContains compares expected query with all recoreded queries. +// Assertions must happen in order the queries are executed, otherwise assertion fails. func (m *cliMock) AssertSQLContains(t *testing.T, expected string) bool { - sql := strings.TrimSpace(strings.Join(m.connection.recorder, "\n")) expected = strings.TrimSpace(expected) - return assert.Contains(t, sql, expected, fmt.Sprintf("SQL mismatch:\n%s\nwith:\n%s", expected, sql)) + found := -1 + + // find matching query and remember last asserted query index + for i, sql := range m.connection.recorder { + if strings.Index(sql, expected) != -1 { + found = i + if i > m.connection.assertedSQLIndex { + m.connection.assertedSQLIndex = i + } + break + } + } + + sql := "" + if found != -1 { + sql = m.connection.recorder[found] + // make sure assertion happen in the correct order + if found < m.connection.assertedSQLIndex { + return assert.True(t, false, "Queries asserted in the wrong order") + } + } + + return assert.True(t, found != -1, fmt.Sprintf("SQL mismatch:\n%s\nwith:\n%s", expected, sql)) } func (m *cliMock) ResetSQLRecorder() { + m.connection.assertedSQLIndex = 0 m.connection.recorder = []string{} } diff --git a/spec/testdb_test.go b/spec/testdb_test.go index 9760c2d..81c7d4c 100644 --- a/spec/testdb_test.go +++ b/spec/testdb_test.go @@ -12,7 +12,8 @@ import ( ) type mockDBConnection struct { - recorder []string + recorder []string + assertedSQLIndex int } func (m *mockDBConnection) Get(f func(db krabdb.DB) error) error {