diff --git a/.mockery.yml b/.mockery.yml new file mode 100644 index 0000000..eb85148 --- /dev/null +++ b/.mockery.yml @@ -0,0 +1,6 @@ +with-expecter: True + +packages: + pilgrim: + interfaces: + CliFlagRetriever: \ No newline at end of file diff --git a/go.mod b/go.mod index 5acff14..95d2b6e 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,12 @@ module mvvasilev.dev/pilgrim go 1.23.1 + +require github.com/stretchr/testify v1.10.0 + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..6fc3fcb --- /dev/null +++ b/go.sum @@ -0,0 +1,12 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pilgrim/context.go b/pilgrim/context.go index 3d88548..d26db8a 100644 --- a/pilgrim/context.go +++ b/pilgrim/context.go @@ -52,43 +52,43 @@ func NewPilgrimContext(cli CliFlagRetriever, env EnvVarRetriever) *pilgrimContex envUrlParts := ParseDatabaseUrl(envUrl) urlParts := UrlParts{ - Driver: pickFirstAvailable( + Driver: PickFirstAvailable( cli.Driver, func() (DbDriver, bool) { return DbDriver(cliUrlParts.Driver), cliUrlParts.Driver != EmptyString }, env.Driver, func() (DbDriver, bool) { return DbDriver(envUrlParts.Driver), envUrlParts.Driver != EmptyString }, ), - Username: pickFirstAvailable( + Username: PickFirstAvailable( cli.Username, func() (string, bool) { return cliUrlParts.Username, cliUrlParts.Username != EmptyString }, env.Username, func() (string, bool) { return envUrlParts.Username, envUrlParts.Username != EmptyString }, ), - Password: pickFirstAvailable( + Password: PickFirstAvailable( cli.Password, func() (string, bool) { return cliUrlParts.Password, cliUrlParts.Password != EmptyString }, env.Password, func() (string, bool) { return envUrlParts.Password, envUrlParts.Password != EmptyString }, ), - Host: pickFirstAvailable( + Host: PickFirstAvailable( cli.Host, func() (string, bool) { return cliUrlParts.Host, cliUrlParts.Host != EmptyString }, env.Host, func() (string, bool) { return envUrlParts.Host, envUrlParts.Host != EmptyString }, ), - Port: pickFirstAvailable( + Port: PickFirstAvailable( cli.Port, func() (string, bool) { return cliUrlParts.Port, cliUrlParts.Port != EmptyString }, env.Port, func() (string, bool) { return envUrlParts.Port, envUrlParts.Port != EmptyString }, ), - Segments: pickFirstAvailable( + Segments: PickFirstAvailable( cli.Segments, func() ([]string, bool) { return cliUrlParts.Segments, cliUrlParts.Segments != nil }, env.Segments, func() ([]string, bool) { return envUrlParts.Segments, envUrlParts.Segments != nil }, ), - Arguments: pickFirstAvailable( + Arguments: PickFirstAvailable( cli.Args, func() (map[string]string, bool) { return cliUrlParts.Arguments, cliUrlParts.Arguments != nil }, env.Args, @@ -104,9 +104,9 @@ func NewPilgrimContext(cli CliFlagRetriever, env EnvVarRetriever) *pilgrimContex migrationPhase, migrationScript, err := determineMigrationPhaseAndScript(cli) - migrationDirectory := pickFirstAvailable(cli.Directory, env.Directory, func() (string, bool) { return DefaultMigrationDirectory, true }) - migrationSchema := pickFirstAvailable(cli.MigrationTableSchema, env.MigrationTableSchema, pickFirstDefault(EmptyString)) // Default depends on driver, set empty for now - migrationTable := pickFirstAvailable(cli.MigrationTable, env.MigrationTable, pickFirstDefault(DefaultMigrationTable)) + migrationDirectory := PickFirstAvailable(cli.Directory, env.Directory, func() (string, bool) { return DefaultMigrationDirectory, true }) + migrationSchema := PickFirstAvailable(cli.MigrationTableSchema, env.MigrationTableSchema, pickFirstDefault(EmptyString)) // Default depends on driver, set empty for now + migrationTable := PickFirstAvailable(cli.MigrationTable, env.MigrationTable, pickFirstDefault(DefaultMigrationTable)) migrationStrictOrdering, _ := cli.IsStrictOrderingEnabled() migrationIsChecksumValidationEnabled, _ := cli.IsChecksumValidationEnabled() @@ -130,7 +130,13 @@ func NewPilgrimContext(cli CliFlagRetriever, env EnvVarRetriever) *pilgrimContex } } -func determineMigrationPhaseAndScript(cli CliFlagRetriever) (phase MigrationPhase, script string, err error) { +type MigrationPhaseRetriever interface { + Script() (script string, isScriptProvided bool) + IsUp() (isUp, isUpProvided bool) + IsDown() (isDown, isDownProvided bool) +} + +func determineMigrationPhaseAndScript(cli MigrationPhaseRetriever) (phase MigrationPhase, script string, err error) { script, _ = cli.Script() isUp, isUpProvided := cli.IsUp() @@ -155,7 +161,7 @@ func pickFirstDefault[T any](defaultVal T) func() (value T, provided bool) { } } -func pickFirstAvailable[T any](valueProviders ...func() (value T, provided bool)) (value T) { +func PickFirstAvailable[T any](valueProviders ...func() (value T, provided bool)) (value T) { for _, getValue := range valueProviders { val, provided := getValue() diff --git a/pilgrim/test/cli_test.go b/pilgrim/test/cli_test.go index a9bb7c7..cf3fde6 100644 --- a/pilgrim/test/cli_test.go +++ b/pilgrim/test/cli_test.go @@ -3,10 +3,9 @@ package pilgrim_test import ( "flag" "fmt" - "maps" - "slices" "testing" + "github.com/stretchr/testify/assert" "mvvasilev.dev/pilgrim/pilgrim" ) @@ -73,11 +72,7 @@ func Test_CliContext_Segments(t *testing.T) { value, _ := pilgrim.CliContext().Segments() - Assert( - t, - slices.Equal(value, expectedValue), - "Cli value '", pilgrim.Flag_Segments, "' differs from expected.", "Value:", value, "Expected:", expectedValue, - ) + assert.Equal(t, expectedValue, value) } func Test_CliContext_Args(t *testing.T) { @@ -91,11 +86,7 @@ func Test_CliContext_Args(t *testing.T) { value, _ := pilgrim.CliContext().Args() - Assert( - t, - maps.Equal(value, expectedValue), - "Cli value '", pilgrim.Flag_Args, "' differs from expected.", "Value:", value, "Expected:", expectedValue, - ) + assert.Equal(t, expectedValue, value) } func Test_CliContext_Directory(t *testing.T) { @@ -171,11 +162,7 @@ func Test_CliContext_DisableChecksumValidation(t *testing.T) { value, _ := pilgrim.CliContext().IsChecksumValidationEnabled() - Assert( - t, - value == expectedValue, - "Cli value '", pilgrim.Flag_DisableChecksumValidation, "' differs from expected.", "Value:", value, "Expected:", expectedValue, - ) + assert.Equal(t, expectedValue, value) } func Test_CliContext_ValidateChecksums(t *testing.T) { @@ -218,9 +205,5 @@ func test_cliValue[T string | pilgrim.DbDriver | bool](t *testing.T, cliVal func value, _ := cliVal(cli) - Assert( - t, - value == expectedVal, - "Cli value '", flagName, "' differs from expected.", "Value:", value, "Expected:", expectedVal, - ) + assert.Equal(t, expectedVal, value) } diff --git a/pilgrim/test/context_test.go b/pilgrim/test/context_test.go index 5b514ee..af2bfba 100644 --- a/pilgrim/test/context_test.go +++ b/pilgrim/test/context_test.go @@ -3,66 +3,36 @@ package pilgrim_test import ( "testing" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "mvvasilev.dev/pilgrim/pilgrim" - pilgrim_mock "mvvasilev.dev/pilgrim/pilgrim/test/mock" ) -const CliUrlValue = "postgres://cli_host:5432/cli_segment1/cli_segment2?cli_arg1=cli_val1&cli_arg2=cli_val2" -const CliDriverValue = "postgres" - -func createPilgrimContextWithDependencies( - cliFlags map[string]string, - envVars map[string]string, -) ( - pilgrimContext pilgrim.PilgrimConfigurationRetriever, - cliContext pilgrim.CliFlagRetriever, - envContext pilgrim.EnvVarRetriever, -) { - cliStringFlagFuncs := map[string]func() (value string, isProvided bool){} - - for k, v := range cliFlags { - cliStringFlagFuncs[k] = func() (value string, isProvided bool) { - return v, true - } - } - - cliContext = pilgrim_mock.MockCliContext( - cliStringFlagFuncs, - make(map[string]func() (value bool, isProvided bool)), - func() (value []string, isProvided bool) { return []string{}, false }, - func() (value map[string]string, isProvided bool) { return map[string]string{}, false }, - ) - - envVarStringFuncs := map[string]func() (value string, isProvided bool){} - - for k, v := range envVars { - envVarStringFuncs[k] = func() (value string, isProvided bool) { - return v, true - } - } - - envContext = pilgrim_mock.MockEnvVarContext( - envVarStringFuncs, - make(map[string]func() (value bool, isProvided bool)), - func() (value []string, isProvided bool) { return []string{}, false }, - func() (value map[string]string, isProvided bool) { return map[string]string{}, false }, - ) - - pilgrimContext = pilgrim.NewPilgrimContext(cliContext, envContext) - - return +type MockCliFlagRetriever struct { + mock.Mock } +type MockEnvVarRetriever struct { + mock.Mock +} + +const CliUrlValue = "postgres://cli_host:5432/cli_segment1/cli_segment2?cli_arg1=cli_val1&cli_arg2=cli_val2" +const CliDriverValue = pilgrim.DbDriver_Postgres + func Test_PilgrimContext_CliDriverOverridesCliUrlDriver(t *testing.T) { + env, cli := new(MockEnvVarRetriever), new(MockCliFlagRetriever) + + env.On("Driver") + context, _, _ := createPilgrimContextWithDependencies( map[string]string{ pilgrim.Flag_Url: CliUrlValue, - pilgrim.Flag_Driver: CliDriverValue, + pilgrim.Flag_Driver: string(CliDriverValue), }, map[string]string{}, ) - AssertEquals(t, context.UrlParts().Driver, CliDriverValue) + assert.Equal(t, CliDriverValue, context.UrlParts().Driver, CliDriverValue) } func Test_PilgrimContext_EnvDriverOverridesEnvUrlDriver(t *testing.T) { @@ -74,7 +44,7 @@ func Test_PilgrimContext_EnvDriverOverridesEnvUrlDriver(t *testing.T) { }, ) - AssertEquals(t, context.UrlParts().Driver, "postgres") + assert.Equal(t, pilgrim.DbDriver_Postgres, context.UrlParts().Driver) } func Test_PilgrimContext_CliUrlDriverOverridesEnvDriver(t *testing.T) { @@ -87,20 +57,20 @@ func Test_PilgrimContext_CliUrlDriverOverridesEnvDriver(t *testing.T) { }, ) - AssertEquals(t, context.UrlParts().Driver, CliDriverValue) + assert.Equal(t, CliDriverValue, context.UrlParts().Driver) } func Test_PilgrimContext_CliDriverOverridesEnvDriver(t *testing.T) { context, _, _ := createPilgrimContextWithDependencies( map[string]string{ - pilgrim.Flag_Driver: CliDriverValue, + pilgrim.Flag_Driver: string(CliDriverValue), }, map[string]string{ pilgrim.EnvVarKey_Driver: "mariadb", }, ) - AssertEquals(t, context.UrlParts().Driver, CliDriverValue) + assert.Equal(t, CliDriverValue, context.UrlParts().Driver) } func Test_PilgrimContext_EnvDriverIsUsedIfNoCliDriverProvided(t *testing.T) { @@ -111,7 +81,7 @@ func Test_PilgrimContext_EnvDriverIsUsedIfNoCliDriverProvided(t *testing.T) { }, ) - AssertEquals(t, context.UrlParts().Driver, "mariadb") + assert.Equal(t, pilgrim.DbDriver_MariaDB, context.UrlParts().Driver) } func Test_PilgrimContext_EnvUrlDriverIsUsedIfNoCliDriverProvided(t *testing.T) { @@ -122,7 +92,7 @@ func Test_PilgrimContext_EnvUrlDriverIsUsedIfNoCliDriverProvided(t *testing.T) { }, ) - AssertEquals(t, context.UrlParts().Driver, "mariadb") + assert.Equal(t, pilgrim.DbDriver_MariaDB, context.UrlParts().Driver) } func Test_PilgrimContext_EnvUrlDriverIsNotUsedIfNoCliDriverOverrideProvided(t *testing.T) { @@ -135,5 +105,5 @@ func Test_PilgrimContext_EnvUrlDriverIsNotUsedIfNoCliDriverOverrideProvided(t *t }, ) - AssertEquals(t, context.UrlParts().Driver, "postgres") + assert.Equal(t, pilgrim.DbDriver_Postgres, context.UrlParts().Driver) } diff --git a/pilgrim/test/env_test.go b/pilgrim/test/env_test.go index 255cedd..bb69bdc 100644 --- a/pilgrim/test/env_test.go +++ b/pilgrim/test/env_test.go @@ -1,11 +1,10 @@ package pilgrim_test import ( - "maps" "os" - "slices" "testing" + "github.com/stretchr/testify/assert" "mvvasilev.dev/pilgrim/pilgrim" ) @@ -19,12 +18,8 @@ func test_envVarContext_StringValue( val, isDefined := getEnvVar() - Assert(t, isDefined, "Env var '", envVarKey, "' was not defined when it should have been") - Assert( - t, - val == expectedVal, - "Env var value '", envVarKey, "' differs from expected.", "Value:", val, "Expected:", expectedVal, - ) + assert.True(t, isDefined) + assert.Equal(t, expectedVal, val) } func Test_envVarContext_Url(t *testing.T) { @@ -43,12 +38,8 @@ func Test_envVarContext_Driver(t *testing.T) { val, isDefined := pilgrim.NewEnvVarContext().Driver() - Assert(t, isDefined, "Env var '", pilgrim.EnvVarKey_Driver, "' was not defined when it should have been") - Assert( - t, - val == expectedVal, - "Env var value '", pilgrim.EnvVarKey_Driver, "' differs from expected.", "Value:", val, "Expected:", expectedVal, - ) + assert.True(t, isDefined) + assert.Equal(t, expectedVal, val) } func Test_envVarContext_Username(t *testing.T) { @@ -121,12 +112,8 @@ func Test_envVarContext_Segments(t *testing.T) { val, isDefined := pilgrim.NewEnvVarContext().Segments() - Assert(t, isDefined, "Env var '", pilgrim.EnvVarKey_Segments, "' was not defined when it should have been") - Assert( - t, - slices.Equal(expectedVal, val), - "Env var value '", pilgrim.EnvVarKey_Segments, "' differs from expected.", "Value:", val, "Expected:", expectedVal, - ) + assert.True(t, isDefined) + assert.Equal(t, expectedVal, val) } func Test_envVarContext_Args(t *testing.T) { @@ -140,10 +127,6 @@ func Test_envVarContext_Args(t *testing.T) { val, isDefined := pilgrim.NewEnvVarContext().Args() - Assert(t, isDefined, "Env var '", pilgrim.EnvVarKey_Arguments, "' was not defined when it should have been") - Assert( - t, - maps.Equal(expectedVal, val), - "Env var value '", pilgrim.EnvVarKey_Arguments, "' differs from expected.", "Value:", val, "Expected:", expectedVal, - ) + assert.True(t, isDefined) + assert.Equal(t, expectedVal, val) } diff --git a/pilgrim/test/url_parts_test.go b/pilgrim/test/url_parts_test.go index 8185b5e..997c834 100644 --- a/pilgrim/test/url_parts_test.go +++ b/pilgrim/test/url_parts_test.go @@ -1,9 +1,9 @@ package pilgrim_test import ( - "reflect" "testing" + "github.com/stretchr/testify/assert" "mvvasilev.dev/pilgrim/pilgrim" ) @@ -42,7 +42,7 @@ func Test_ParseDatabaseUrl(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := pilgrim.ParseDatabaseUrl(tt.args.cliUrl); !reflect.DeepEqual(got, tt.want) { + if got := pilgrim.ParseDatabaseUrl(tt.args.cliUrl); !assert.ObjectsAreEqual(got, tt.want) { t.Errorf("ParseDatabaseUrl() = %v, want %v", got, tt.want) } }) @@ -53,14 +53,14 @@ func Test_UrlParts_Validate_ValidUrl(t *testing.T) { urlParts := pilgrim.ParseDatabaseUrl("mssql://user:pass@localhost:9999/segment1/segment2?arg1=val1&arg2=val2") isValid, err := urlParts.Validate() - Assert(t, isValid, "Valid DatabaseUrl returned as invalid", err) - Assert(t, err == nil, "Valid DatabaseUrl returned validation errors", err) + assert.True(t, isValid, "Valid DatabaseUrl returned as invalid") + assert.True(t, err == nil, "Valid DatabaseUrl returned validation errors") } func Test_UrlParts_Validate_InvalidUrl(t *testing.T) { urlParts := pilgrim.ParseDatabaseUrl("invalid-driver://user:pass@localhost:9999/segment1/segment2?arg1=val1&arg2=val2") isValid, err := urlParts.Validate() - Assert(t, !isValid, "Invalid DatabaseUrl returned as valid", err) - Assert(t, err != nil, "Invalid DatabaseUrl did not return validation errors", err) + assert.True(t, !isValid, "Invalid DatabaseUrl returned as valid") + assert.True(t, err != nil, "Invalid DatabaseUrl did not return validation errors") } diff --git a/pilgrim/test/utils_test.go b/pilgrim/test/utils_test.go deleted file mode 100644 index db14d0a..0000000 --- a/pilgrim/test/utils_test.go +++ /dev/null @@ -1,24 +0,0 @@ -package pilgrim_test - -import "testing" - -func Assert(t *testing.T, condition bool, errItems ...any) { - if !condition { - t.Fail() - t.Log("Test failure reason:", errItems) - } -} - -func AssertEquals[T comparable](t *testing.T, value T, expected T) { - if value != expected { - t.Fail() - t.Logf("Got %v, expected %v", value, expected) - } -} - -func AssertEqualsFunc[T any](t *testing.T, value T, expected T, equalsFunc func(v, e T) bool) { - if !equalsFunc(value, expected) { - t.Fail() - t.Logf("Got %v, expected %v", value, expected) - } -}