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  }