package commands import ( "fmt" "os" "path/filepath" "testing" "github.com/spf13/cobra" "github.com/spf13/pflag" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestLoadXEnvCLIStringSliceValue(t *testing.T) { testCases := []struct { name string envKey, envValue, flagValue string flagDefault []string flag *pflag.Flag expected []string expectedResult XEnvCLIResult expectedErr string }{ { "ShouldParseFromEnv", "EXAMPLE_ONE", "abc", "example-one", []string{"flagdef"}, &pflag.Flag{Name: "example-one", Changed: false}, []string{"abc"}, XEnvCLIResultEnvironment, "", }, { "ShouldParseMultipleFromEnv", "EXAMPLE_ONE", "abc,123", "example-one", []string{"flagdef"}, &pflag.Flag{Name: "example-one", Changed: false}, []string{"abc", "123"}, XEnvCLIResultEnvironment, "", }, { "ShouldParseCLIExplicit", "EXAMPLE_ONE", "abc,123", "example-from-flag,123", []string{"flagdef"}, &pflag.Flag{Name: "example-one", Changed: true}, []string{"example-from-flag", "123"}, XEnvCLIResultCLIExplicit, "", }, { "ShouldParseCLIImplicit", "EXAMPLE_ONE", "", "example-one", []string{"example-from-flag-default", "123"}, &pflag.Flag{Name: "example-one", Changed: false}, []string{"example-from-flag-default", "123"}, XEnvCLIResultCLIImplicit, "", }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { cmd := &cobra.Command{} if tc.flag != nil { cmd.Flags().StringSlice(tc.flag.Name, tc.flagDefault, "") if tc.flag.Changed { require.NoError(t, cmd.Flags().Set(tc.flag.Name, tc.flagValue)) } } if tc.envValue != "" { require.NoError(t, os.Setenv(tc.envKey, tc.envValue)) } actual, actualResult, actualErr := loadXEnvCLIStringSliceValue(cmd, tc.envKey, tc.flag.Name) assert.Equal(t, tc.expected, actual) assert.Equal(t, tc.expectedResult, actualResult) if tc.expectedErr == "" { assert.NoError(t, actualErr) } else { assert.EqualError(t, actualErr, tc.expectedErr) } if tc.envValue != "" { require.NoError(t, os.Unsetenv(tc.envKey)) } }) } } func TestLoadXNormalizedPaths(t *testing.T) { root := t.TempDir() configdir := filepath.Join(root, "config") otherdir := filepath.Join(root, "other") require.NoError(t, os.Mkdir(configdir, 0700)) require.NoError(t, os.Mkdir(otherdir, 0700)) var ( info os.FileInfo file *os.File err error ) ayml := filepath.Join(configdir, "a.yml") byml := filepath.Join(configdir, "b.yml") cyml := filepath.Join(otherdir, "c.yml") file, err = os.Create(ayml) require.NoError(t, err) require.NoError(t, file.Close()) file, err = os.Create(byml) require.NoError(t, err) require.NoError(t, file.Close()) file, err = os.Create(cyml) require.NoError(t, err) require.NoError(t, file.Close()) info, err = os.Stat(configdir) require.NoError(t, err) require.True(t, info.IsDir()) info, err = os.Stat(otherdir) require.NoError(t, err) require.True(t, info.IsDir()) info, err = os.Stat(ayml) require.NoError(t, err) require.False(t, info.IsDir()) info, err = os.Stat(byml) require.NoError(t, err) require.False(t, info.IsDir()) info, err = os.Stat(cyml) require.NoError(t, err) require.False(t, info.IsDir()) testCases := []struct { name string have, expected []string expectedErr string }{ {"ShouldAllowFiles", []string{ayml}, []string{ayml}, "", }, {"ShouldAllowDirectories", []string{configdir}, []string{configdir}, "", }, {"ShouldAllowFilesDirectories", []string{ayml, otherdir}, []string{ayml, otherdir}, "", }, {"ShouldRaiseErrOnOverlappingFilesDirectories", []string{ayml, configdir}, nil, fmt.Sprintf("failed to load config directory '%s': the config file '%s' is in that directory which is not supported", configdir, ayml), }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { actual, actualErr := loadXNormalizedPaths(tc.have) assert.Equal(t, tc.expected, actual) if tc.expectedErr == "" { assert.NoError(t, actualErr) } else { assert.EqualError(t, actualErr, tc.expectedErr) } }) } }