github.com/adharshmk96/stk@v1.2.3/pkg/sqlMigrator/core_test.go (about) 1 package sqlmigrator_test 2 3 import ( 4 "os" 5 "path" 6 "strings" 7 "testing" 8 9 sqlmigrator "github.com/adharshmk96/stk/pkg/sqlMigrator" 10 "github.com/adharshmk96/stk/testutils" 11 "github.com/stretchr/testify/assert" 12 ) 13 14 var LOG_FILE_CONTENT = `1_create_users_table_up 15 2_create_posts_table_up 16 3_create_comments_table_up 17 4_create_likes_table_down 18 5_create_followers_table_down 19 6_create_messages_table_down 20 ` 21 22 func TestParseRawMigration(t *testing.T) { 23 t.Run("parses a correct raw migration", func(t *testing.T) { 24 tc := []struct { 25 rawMigrationString string 26 expectedNumber int 27 expectedName string 28 commitStatus bool 29 }{ 30 { 31 rawMigrationString: "1_create_users_table_up", 32 expectedNumber: 1, 33 expectedName: "create_users_table", 34 commitStatus: true, 35 }, 36 { 37 rawMigrationString: "2_up", 38 expectedNumber: 2, 39 expectedName: "", 40 commitStatus: true, 41 }, 42 { 43 rawMigrationString: "3_create_posts_table_down", 44 expectedNumber: 3, 45 expectedName: "create_posts_table", 46 commitStatus: false, 47 }, 48 { 49 rawMigrationString: "4_down", 50 expectedNumber: 4, 51 expectedName: "", 52 commitStatus: false, 53 }, 54 } 55 56 for _, c := range tc { 57 rawMigration, err := sqlmigrator.ParseMigrationEntry(c.rawMigrationString) 58 assert.NoError(t, err) 59 assert.Equal(t, c.expectedNumber, rawMigration.Number) 60 assert.Equal(t, c.expectedName, rawMigration.Name) 61 assert.Equal(t, c.commitStatus, rawMigration.Committed) 62 } 63 }) 64 65 t.Run("returns an error if raw migration is invalid", func(t *testing.T) { 66 tc := []struct { 67 rawMigrationString string 68 }{ 69 { 70 rawMigrationString: "create_users_table_up", 71 }, 72 { 73 rawMigrationString: "1_create_users_table", 74 }, 75 { 76 rawMigrationString: "1", 77 }, 78 { 79 rawMigrationString: "1create_users_table", 80 }, 81 { 82 rawMigrationString: "create_users_table", 83 }, 84 { 85 rawMigrationString: "create_users_table1", 86 }, 87 { 88 rawMigrationString: "", 89 }, 90 { 91 rawMigrationString: "nameonly", 92 }, 93 } 94 95 for _, c := range tc { 96 _, err := sqlmigrator.ParseMigrationEntry(c.rawMigrationString) 97 assert.Error(t, err) 98 } 99 }) 100 } 101 102 func TestRawMigrationString(t *testing.T) { 103 t.Run("outputs correct migration string", func(t *testing.T) { 104 tc := []struct { 105 rawMigration sqlmigrator.MigrationFileEntry 106 expected string 107 }{ 108 { 109 rawMigration: sqlmigrator.MigrationFileEntry{ 110 Number: 1, 111 Name: "create_users_table", 112 Committed: true, 113 }, 114 expected: "1_create_users_table_up", 115 }, 116 { 117 rawMigration: sqlmigrator.MigrationFileEntry{ 118 Number: 2, 119 Name: "", 120 Committed: false, 121 }, 122 expected: "2_down", 123 }, 124 { 125 rawMigration: sqlmigrator.MigrationFileEntry{ 126 Number: 3, 127 Name: "create_posts_table", 128 Committed: true, 129 }, 130 expected: "3_create_posts_table_up", 131 }, 132 { 133 rawMigration: sqlmigrator.MigrationFileEntry{ 134 Number: 4, 135 Name: "", 136 Committed: true, 137 }, 138 expected: "4_up", 139 }, 140 } 141 142 for _, c := range tc { 143 assert.Equal(t, c.expected, c.rawMigration.EntryString()) 144 } 145 }) 146 } 147 148 func TestContextLoding(t *testing.T) { 149 t.Run("loads migration entries from log file", func(t *testing.T) { 150 tempDir, removeDir := testutils.CreateTempDirectory(t) 151 defer removeDir() 152 153 ctx := sqlmigrator.NewContext(tempDir, sqlmigrator.SQLiteDB, "migrator.log", false) 154 logFilePath := path.Join(ctx.WorkDir, ctx.LogFile) 155 156 err := os.WriteFile(logFilePath, []byte(LOG_FILE_CONTENT), 0644) 157 assert.NoError(t, err) 158 159 err = ctx.LoadMigrationEntries() 160 assert.NoError(t, err) 161 162 assert.Equal(t, 6, len(ctx.Migrations)) 163 164 expected := func() []*sqlmigrator.MigrationFileEntry { 165 migrationEntry := []*sqlmigrator.MigrationFileEntry{} 166 167 lines := strings.Split(LOG_FILE_CONTENT, "\n")[0:6] 168 for _, line := range lines { 169 entry, err := sqlmigrator.ParseMigrationEntry(line) 170 assert.NoError(t, err) 171 migrationEntry = append(migrationEntry, entry) 172 } 173 174 return migrationEntry 175 }() 176 177 for i, migration := range ctx.Migrations { 178 assert.Equal(t, expected[i].EntryString(), migration.EntryString()) 179 assert.Equal(t, expected[i].Number, migration.Number) 180 assert.Equal(t, expected[i].Name, migration.Name) 181 assert.Equal(t, expected[i].Committed, migration.Committed) 182 } 183 }) 184 185 t.Run("empty migration entries if log file is empty", func(t *testing.T) { 186 tempDir, removeDir := testutils.CreateTempDirectory(t) 187 defer removeDir() 188 189 ctx := sqlmigrator.NewContext(tempDir, sqlmigrator.SQLiteDB, "migrator.log", false) 190 err := ctx.LoadMigrationEntries() 191 assert.NoError(t, err) 192 assert.Equal(t, 0, len(ctx.Migrations)) 193 }) 194 195 t.Run("writes migration entries to logfile", func(t *testing.T) { 196 tempDir, removeDir := testutils.CreateTempDirectory(t) 197 defer removeDir() 198 199 ctx := sqlmigrator.NewContext(tempDir, sqlmigrator.SQLiteDB, "migrator.log", false) 200 logFilePath := path.Join(ctx.WorkDir, ctx.LogFile) 201 202 err := ctx.LoadMigrationEntries() 203 assert.NoError(t, err) 204 assert.Equal(t, 0, len(ctx.Migrations)) 205 206 migrationEntry := []*sqlmigrator.MigrationFileEntry{} 207 208 lines := strings.Split(LOG_FILE_CONTENT, "\n")[0:6] 209 for _, line := range lines { 210 entry, err := sqlmigrator.ParseMigrationEntry(line) 211 assert.NoError(t, err) 212 migrationEntry = append(migrationEntry, entry) 213 } 214 215 ctx.Migrations = migrationEntry 216 217 err = ctx.WriteMigrationEntries() 218 assert.NoError(t, err) 219 220 assert.FileExists(t, logFilePath) 221 assert.Equal(t, LOG_FILE_CONTENT, testutils.GetFileContent(t, logFilePath)) 222 223 err = ctx.WriteMigrationEntries() 224 assert.NoError(t, err) 225 226 assert.FileExists(t, logFilePath) 227 assert.Equal(t, LOG_FILE_CONTENT, testutils.GetFileContent(t, logFilePath)) 228 229 // updates the migration entries 230 ctx.Migrations = ctx.Migrations[:3] 231 err = ctx.WriteMigrationEntries() 232 assert.NoError(t, err) 233 234 assert.FileExists(t, logFilePath) 235 assert.Equal(t, "1_create_users_table_up\n2_create_posts_table_up\n3_create_comments_table_up\n", testutils.GetFileContent(t, logFilePath)) 236 237 }) 238 239 t.Run("loads migration content from files", func(t *testing.T) { 240 tempDir, removeDir := testutils.CreateTempDirectory(t) 241 defer removeDir() 242 243 ctx := sqlmigrator.NewContext(tempDir, sqlmigrator.SQLiteDB, "migrator.log", false) 244 err := ctx.LoadMigrationEntries() 245 assert.NoError(t, err) 246 247 assert.Equal(t, 0, len(ctx.Migrations)) 248 249 generator := sqlmigrator.NewGenerator("user_table", 3, true) 250 generatedFiles, err := generator.Generate(ctx) 251 assert.NoError(t, err) 252 253 assert.Equal(t, 6, len(generatedFiles)) 254 assert.Equal(t, 3, len(ctx.Migrations)) 255 256 for _, migration := range ctx.Migrations { 257 assert.FileExists(t, migration.UpFilePath) 258 assert.FileExists(t, migration.DownFilePath) 259 260 upFileContent, downFileContent := migration.LoadFileContent() 261 assert.Equal(t, testutils.GetFileContent(t, migration.UpFilePath), upFileContent) 262 assert.Equal(t, testutils.GetFileContent(t, migration.DownFilePath), downFileContent) 263 264 } 265 }) 266 }