From 604df3a996f2bf7dcf5031b6d85d5f15af72ec79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Henrique=20Guard=C3=A3o=20Gandarez?= Date: Mon, 6 Jan 2025 16:35:15 -0300 Subject: [PATCH] Refactor FirstNonEmptyBool to accept false values --- cmd/logfile/logfile_test.go | 241 ++++++++++++++++-------------- cmd/params/params.go | 4 +- cmd/params/params_test.go | 163 ++++++++++---------- pkg/vipertools/vipertools.go | 30 +++- pkg/vipertools/vipertools_test.go | 38 +++-- 5 files changed, 273 insertions(+), 203 deletions(-) diff --git a/cmd/logfile/logfile_test.go b/cmd/logfile/logfile_test.go index 8a8b384b..3a0e1198 100644 --- a/cmd/logfile/logfile_test.go +++ b/cmd/logfile/logfile_test.go @@ -19,125 +19,142 @@ func TestLoadParams(t *testing.T) { defer tmpFile.Close() + ctx := context.Background() + + v := viper.New() + v.Set("log-file", tmpFile.Name()) + v.Set("log-to-stdout", true) + v.Set("metrics", true) + v.Set("verbose", true) + v.Set("send-diagnostics-on-errors", true) + + params, err := logfile.LoadParams(ctx, v) + require.NoError(t, err) + + assert.True(t, params.Verbose) + assert.True(t, params.Metrics) + assert.True(t, params.ToStdout) + assert.True(t, params.SendDiagsOnErrors) + assert.Equal(t, tmpFile.Name(), params.File) +} + +func TestLoadParams_LogFile_FlagDeprecated(t *testing.T) { + tmpFile, err := os.CreateTemp(t.TempDir(), "") + require.NoError(t, err) + + defer tmpFile.Close() + + ctx := context.Background() + + v := viper.New() + v.Set("logfile", tmpFile.Name()) + + params, err := logfile.LoadParams(ctx, v) + require.NoError(t, err) + + assert.Equal(t, tmpFile.Name(), params.File) +} + +func TestLoadParams_LogFile_FromConfig(t *testing.T) { + tmpFile, err := os.CreateTemp(t.TempDir(), "") + require.NoError(t, err) + + defer tmpFile.Close() + + ctx := context.Background() + + v := viper.New() + v.Set("settings.log_file", tmpFile.Name()) + + params, err := logfile.LoadParams(ctx, v) + require.NoError(t, err) + + assert.Equal(t, tmpFile.Name(), params.File) +} + +func TestLoadParams_LogFile_FromEnvVar(t *testing.T) { + tmpFile, err := os.CreateTemp(t.TempDir(), "") + require.NoError(t, err) + + defer tmpFile.Close() + dir, _ := filepath.Split(tmpFile.Name()) - logFile, err := os.Create(filepath.Join(dir, "wakatime.log")) + ctx := context.Background() + + v := viper.New() + t.Setenv("WAKATIME_HOME", dir) + + params, err := logfile.LoadParams(ctx, v) require.NoError(t, err) - defer logFile.Close() + assert.Equal(t, filepath.Join(dir, "wakatime.log"), params.File) +} - home, err := os.UserHomeDir() +func TestLoadParams_LogFile_FlagTakesPrecedence(t *testing.T) { + tmpFile, err := os.CreateTemp(t.TempDir(), "") require.NoError(t, err) + defer tmpFile.Close() + ctx := context.Background() - tests := map[string]struct { - EnvVar string - ViperDebug bool - ViperDebugConfig bool - ViperLogFile string - ViperLogFileConfig string - ViperLogFileOld string - ViperMetrics bool - ViperMetricsConfig bool - ViperToStdout bool - Expected logfile.Params - }{ - "verbose set": { - ViperDebug: true, - Expected: logfile.Params{ - File: filepath.Join(home, ".wakatime", "wakatime.log"), - Verbose: true, - }, - }, - "verbose from config": { - ViperDebugConfig: true, - Expected: logfile.Params{ - File: filepath.Join(home, ".wakatime", "wakatime.log"), - Verbose: true, - }, - }, - "log file flag takes precedence": { - ViperLogFile: tmpFile.Name(), - ViperLogFileConfig: "otherfolder/wakatime.config.log", - ViperLogFileOld: "otherfolder/wakatime.old.log", - Expected: logfile.Params{ - File: tmpFile.Name(), - }, - }, - "log file deprecated flag takes precedence": { - ViperLogFileConfig: "otherfolder/wakatime.config.log", - ViperLogFileOld: tmpFile.Name(), - Expected: logfile.Params{ - File: tmpFile.Name(), - }, - }, - "log file from config": { - ViperLogFileConfig: tmpFile.Name(), - Expected: logfile.Params{ - File: tmpFile.Name(), - }, - }, - "log file from WAKATIME_HOME": { - EnvVar: dir, - Expected: logfile.Params{ - File: filepath.Join(dir, "wakatime.log"), - }, - }, - "log file from home dir": { - Expected: logfile.Params{ - File: filepath.Join(home, ".wakatime", "wakatime.log"), - }, - }, - "metrics set": { - ViperMetrics: true, - Expected: logfile.Params{ - File: filepath.Join(home, ".wakatime", "wakatime.log"), - Metrics: true, - }, - }, - "metrics from config": { - ViperMetricsConfig: true, - Expected: logfile.Params{ - File: filepath.Join(home, ".wakatime", "wakatime.log"), - Metrics: true, - }, - }, - "metrics flag takes precedence": { - ViperMetrics: true, - ViperMetricsConfig: false, - Expected: logfile.Params{ - File: filepath.Join(home, ".wakatime", "wakatime.log"), - Metrics: true, - }, - }, - "log to stdout": { - ViperToStdout: true, - Expected: logfile.Params{ - File: filepath.Join(home, ".wakatime", "wakatime.log"), - ToStdout: true, - }, - }, - } - - for name, test := range tests { - t.Run(name, func(t *testing.T) { - v := viper.New() - v.Set("log-file", test.ViperLogFile) - v.Set("logfile", test.ViperLogFileOld) - v.Set("log-to-stdout", test.ViperToStdout) - v.Set("metrics", test.ViperMetrics) - v.Set("settings.metrics", test.ViperMetricsConfig) - v.Set("settings.log_file", test.ViperLogFileConfig) - v.Set("settings.debug", test.ViperDebug) - v.Set("verbose", test.ViperDebugConfig) - - t.Setenv("WAKATIME_HOME", test.EnvVar) - - params, err := logfile.LoadParams(ctx, v) - require.NoError(t, err) - - assert.Equal(t, test.Expected, params) - }) - } + v := viper.New() + v.Set("log-file", tmpFile.Name()) + v.Set("settings.log_file", "otherfolder/wakatime.config.log") + + params, err := logfile.LoadParams(ctx, v) + require.NoError(t, err) + + assert.Equal(t, tmpFile.Name(), params.File) +} + +func TestLoadParams_Metrics_FromConfig(t *testing.T) { + ctx := context.Background() + + v := viper.New() + v.Set("settings.metrics", true) + + params, err := logfile.LoadParams(ctx, v) + require.NoError(t, err) + + assert.True(t, params.Metrics) +} + +func TestLoadParams_Metrics_FlagTakesPrecedence(t *testing.T) { + ctx := context.Background() + + v := viper.New() + v.Set("metrics", false) + v.Set("settings.metrics", true) + + params, err := logfile.LoadParams(ctx, v) + require.NoError(t, err) + + assert.False(t, params.Metrics) +} + +func TestLoadParams_Verbose_FromConfig(t *testing.T) { + ctx := context.Background() + + v := viper.New() + v.Set("settings.debug", true) + + params, err := logfile.LoadParams(ctx, v) + require.NoError(t, err) + + assert.True(t, params.Verbose) +} + +func TestLoadParams_Verbose_FlagTakesPrecedence(t *testing.T) { + ctx := context.Background() + + v := viper.New() + v.Set("verbose", false) + v.Set("settings.debug", true) + + params, err := logfile.LoadParams(ctx, v) + require.NoError(t, err) + + assert.False(t, params.Verbose) } diff --git a/cmd/params/params.go b/cmd/params/params.go index 4c979af3..5799816a 100644 --- a/cmd/params/params.go +++ b/cmd/params/params.go @@ -388,7 +388,7 @@ func LoadHeartbeatParams(ctx context.Context, v *viper.Viper) (Heartbeat, error) return Heartbeat{}, errors.New("failed to retrieve entity") } - entityExpanded, err := homedir.Expand(entity) + entity, err := homedir.Expand(entity) if err != nil { return Heartbeat{}, fmt.Errorf("failed expanding entity: %s", err) } @@ -463,7 +463,7 @@ func LoadHeartbeatParams(ctx context.Context, v *viper.Viper) (Heartbeat, error) return Heartbeat{ Category: category, CursorPosition: cursorPosition, - Entity: entityExpanded, + Entity: entity, ExtraHeartbeats: extraHeartbeats, EntityType: entityType, GuessLanguage: vipertools.FirstNonEmptyBool(v, "guess-language", "settings.guess_language"), diff --git a/cmd/params/params_test.go b/cmd/params/params_test.go index 8edcd0b4..60991047 100644 --- a/cmd/params/params_test.go +++ b/cmd/params/params_test.go @@ -144,7 +144,7 @@ func TestLoadHeartbeatParams_CursorPosition_Unset(t *testing.T) { assert.Nil(t, params.CursorPosition) } -func TestLoadHeartbeatParams_Entity_EntityFlagTakesPrecedence(t *testing.T) { +func TestLoadHeartbeatParams_Entity_FlagTakesPrecedence(t *testing.T) { v := viper.New() v.Set("entity", "/path/to/file") v.Set("file", "ignored") @@ -501,13 +501,13 @@ func TestLoadHeartbeatParams_ExtraHeartbeats_NoData(t *testing.T) { func TestLoadHeartbeat_GuessLanguage_FlagTakesPrecedence(t *testing.T) { v := viper.New() v.Set("entity", "/path/to/file") - v.Set("guess-language", true) - v.Set("settings.guess_language", false) + v.Set("guess-language", false) + v.Set("settings.guess_language", true) params, err := cmdparams.LoadHeartbeatParams(context.Background(), v) require.NoError(t, err) - assert.True(t, params.GuessLanguage) + assert.False(t, params.GuessLanguage) } func TestLoadHeartbeat_GuessLanguage_FromConfig(t *testing.T) { @@ -916,7 +916,6 @@ func TestLoadHeartbeatParams_Filter_ExcludeUnknownProject(t *testing.T) { func TestLoadHeartbeatParams_Filter_ExcludeUnknownProject_FromConfig(t *testing.T) { v := viper.New() v.Set("entity", "/path/to/file") - v.Set("exclude-unknown-project", false) v.Set("settings.exclude_unknown_project", true) params, err := cmdparams.LoadHeartbeatParams(context.Background(), v) @@ -925,6 +924,18 @@ func TestLoadHeartbeatParams_Filter_ExcludeUnknownProject_FromConfig(t *testing. assert.True(t, params.Filter.ExcludeUnknownProject) } +func TestLoadHeartbeatParams_Filter_ExcludeUnknownProject_FlagTakesPrecedence(t *testing.T) { + v := viper.New() + v.Set("entity", "/path/to/file") + v.Set("exclude-unknown-project", false) + v.Set("settings.exclude_unknown_project", true) + + params, err := cmdparams.LoadHeartbeatParams(context.Background(), v) + require.NoError(t, err) + + assert.False(t, params.Filter.ExcludeUnknownProject) +} + func TestLoadHeartbeatParams_Filter_Include(t *testing.T) { v := viper.New() v.Set("entity", "/path/to/file") @@ -1002,7 +1013,6 @@ func TestLoadHeartbeatParams_Filter_IncludeOnlyWithProjectFile(t *testing.T) { func TestLoadHeartbeatParams_Filter_IncludeOnlyWithProjectFile_FromConfig(t *testing.T) { v := viper.New() v.Set("entity", "/path/to/file") - v.Set("include-only-with-project-file", false) v.Set("settings.include_only_with_project_file", true) params, err := cmdparams.LoadHeartbeatParams(context.Background(), v) @@ -1434,7 +1444,7 @@ func TestLoadHeartbeatParams_SanitizeParams_HideProjecthNames_List(t *testing.T) func TestLoadHeartbeatParams_SanitizeParams_HideProjectNames_FlagTakesPrecedence(t *testing.T) { v := viper.New() v.Set("entity", "/path/to/file") - v.Set("hide-project-names", "true") + v.Set("hide-project-names", true) v.Set("settings.hide_project_names", "ignored") v.Set("settings.hide_projectnames", "ignored") v.Set("settings.hideprojectnames", "ignored") @@ -1450,7 +1460,7 @@ func TestLoadHeartbeatParams_SanitizeParams_HideProjectNames_FlagTakesPrecedence func TestLoadHeartbeatParams_SanitizeParams_HideProjectNames_ConfigTakesPrecedence(t *testing.T) { v := viper.New() v.Set("entity", "/path/to/file") - v.Set("settings.hide_project_names", "true") + v.Set("settings.hide_project_names", true) v.Set("settings.hide_projectnames", "ignored") v.Set("settings.hideprojectnames", "ignored") @@ -1465,7 +1475,7 @@ func TestLoadHeartbeatParams_SanitizeParams_HideProjectNames_ConfigTakesPreceden func TestLoadHeartbeatParams_SanitizeParams_HideProjectNames_ConfigDeprecatedOneTakesPrecedence(t *testing.T) { v := viper.New() v.Set("entity", "/path/to/file") - v.Set("settings.hide_projectnames", "true") + v.Set("settings.hide_projectnames", true) v.Set("settings.hideprojectnames", "ignored") params, err := cmdparams.LoadHeartbeatParams(context.Background(), v) @@ -1609,7 +1619,7 @@ func TestLoadHeartbeatParams_SanitizeParams_HideFileNames_List(t *testing.T) { func TestLoadheartbeatParams_SanitizeParams_HideFileNames_FlagTakesPrecedence(t *testing.T) { v := viper.New() v.Set("entity", "/path/to/file") - v.Set("hide-file-names", "true") + v.Set("hide-file-names", true) v.Set("hide-filenames", "ignored") v.Set("hidefilenames", "ignored") v.Set("settings.hide_file_names", "ignored") @@ -1627,7 +1637,7 @@ func TestLoadheartbeatParams_SanitizeParams_HideFileNames_FlagTakesPrecedence(t func TestLoadHeartbeatParams_SanitizeParams_HideFileNames_FlagDeprecatedOneTakesPrecedence(t *testing.T) { v := viper.New() v.Set("entity", "/path/to/file") - v.Set("hide-filenames", "true") + v.Set("hide-filenames", true) v.Set("hidefilenames", "ignored") v.Set("settings.hide_file_names", "ignored") v.Set("settings.hide_filenames", "ignored") @@ -1644,7 +1654,7 @@ func TestLoadHeartbeatParams_SanitizeParams_HideFileNames_FlagDeprecatedOneTakes func TestLoadHeartbeatParams_SanitizeParams_HideFileNames_FlagDeprecatedTwoTakesPrecedence(t *testing.T) { v := viper.New() v.Set("entity", "/path/to/file") - v.Set("hidefilenames", "true") + v.Set("hidefilenames", true) v.Set("settings.hide_file_names", "ignored") v.Set("settings.hide_filenames", "ignored") v.Set("settings.hidefilenames", "ignored") @@ -1660,7 +1670,7 @@ func TestLoadHeartbeatParams_SanitizeParams_HideFileNames_FlagDeprecatedTwoTakes func TestLoadHeartbeatParams_SanitizeParams_HideFileNames_ConfigTakesPrecedence(t *testing.T) { v := viper.New() v.Set("entity", "/path/to/file") - v.Set("settings.hide_file_names", "true") + v.Set("settings.hide_file_names", true) v.Set("settings.hide_filenames", "ignored") v.Set("settings.hidefilenames", "ignored") @@ -1675,7 +1685,7 @@ func TestLoadHeartbeatParams_SanitizeParams_HideFileNames_ConfigTakesPrecedence( func TestLoadHeartbeatParams_SanitizeParams_HideFileNames_ConfigDeprecatedOneTakesPrecedence(t *testing.T) { v := viper.New() v.Set("entity", "/path/to/file") - v.Set("settings.hide_filenames", "true") + v.Set("settings.hide_filenames", true) v.Set("settings.hidefilenames", "ignored") params, err := cmdparams.LoadHeartbeatParams(context.Background(), v) @@ -1928,6 +1938,17 @@ func TestLoadAPIParams_Timeout_FlagTakesPrecedence(t *testing.T) { assert.Equal(t, 5*time.Second, params.Timeout) } +func TestLoadAPIParams_Timeout_ConfigTakesPrecedence(t *testing.T) { + v := viper.New() + v.Set("key", "00000000-0000-4000-8000-000000000000") + v.Set("settings.timeout", 10) + + params, err := cmdparams.LoadAPIParams(context.Background(), v) + require.NoError(t, err) + + assert.Equal(t, 10*time.Second, params.Timeout) +} + func TestLoadAPIParams_Timeout_FromConfig(t *testing.T) { v := viper.New() v.Set("key", "00000000-0000-4000-8000-000000000000") @@ -2001,7 +2022,7 @@ func TestLoadOfflineParams_Disabled_FlagDeprecatedTakesPrecedence(t *testing.T) params := cmdparams.LoadOfflineParams(context.Background(), v) - assert.True(t, params.Disabled) + assert.False(t, params.Disabled) } func TestLoadOfflineParams_Disabled_FromFlag(t *testing.T) { @@ -2147,56 +2168,50 @@ func TestLoadOfflineParams_SyncMax_NonIntegerValue(t *testing.T) { func TestLoadAPIParams_APIKey(t *testing.T) { ctx := context.Background() - tests := map[string]struct { - ViperAPIKey string - ViperAPIKeyConfig string - ViperAPIKeyConfigOld string - Expected cmdparams.API - }{ - "api key flag takes precedence": { - ViperAPIKey: "00000000-0000-4000-8000-000000000000", - ViperAPIKeyConfig: "10000000-0000-4000-8000-000000000000", - ViperAPIKeyConfigOld: "20000000-0000-4000-8000-000000000000", - Expected: cmdparams.API{ - Key: "00000000-0000-4000-8000-000000000000", - URL: "https://api.wakatime.com/api/v1", - Hostname: "my-computer", - }, - }, - "api from config takes precedence": { - ViperAPIKeyConfig: "00000000-0000-4000-8000-000000000000", - ViperAPIKeyConfigOld: "10000000-0000-4000-8000-000000000000", - Expected: cmdparams.API{ - Key: "00000000-0000-4000-8000-000000000000", - URL: "https://api.wakatime.com/api/v1", - Hostname: "my-computer", - }, - }, - "api key from config deprecated": { - ViperAPIKeyConfigOld: "00000000-0000-4000-8000-000000000000", - Expected: cmdparams.API{ - Key: "00000000-0000-4000-8000-000000000000", - URL: "https://api.wakatime.com/api/v1", - Hostname: "my-computer", - }, - }, - } + v := viper.New() + v.Set("key", "00000000-0000-4000-8000-000000000000") - for name, test := range tests { - t.Run(name, func(t *testing.T) { - v := viper.New() - v.Set("hostname", "my-computer") - v.Set("timeout", 0) - v.Set("key", test.ViperAPIKey) - v.Set("settings.api_key", test.ViperAPIKeyConfig) - v.Set("settings.apikey", test.ViperAPIKeyConfigOld) + params, err := cmdparams.LoadAPIParams(ctx, v) + require.NoError(t, err) - params, err := cmdparams.LoadAPIParams(ctx, v) - require.NoError(t, err) + assert.Equal(t, "00000000-0000-4000-8000-000000000000", params.Key) +} - assert.Equal(t, test.Expected, params) - }) - } +func TestLoadAPIParams_APIKey_FlagTakesPrecedence(t *testing.T) { + ctx := context.Background() + + v := viper.New() + v.Set("key", "00000000-0000-4000-8000-000000000000") + v.Set("settings.api_key", "10000000-0000-4000-8000-000000000000") + + params, err := cmdparams.LoadAPIParams(ctx, v) + require.NoError(t, err) + + assert.Equal(t, "00000000-0000-4000-8000-000000000000", params.Key) +} + +func TestLoadAPIParams_APIKey_FromConfig(t *testing.T) { + ctx := context.Background() + + v := viper.New() + v.Set("settings.api_key", "10000000-0000-4000-8000-000000000000") + + params, err := cmdparams.LoadAPIParams(ctx, v) + require.NoError(t, err) + + assert.Equal(t, "10000000-0000-4000-8000-000000000000", params.Key) +} + +func TestLoadAPIParams_APIKey_ConfigDeprecatedTakesPrecedence(t *testing.T) { + ctx := context.Background() + + v := viper.New() + v.Set("settings.apikey", "20000000-0000-4000-8000-000000000000") + + params, err := cmdparams.LoadAPIParams(ctx, v) + require.NoError(t, err) + + assert.Equal(t, "20000000-0000-4000-8000-000000000000", params.Key) } func TestLoadAPIParams_APIKeyUnset(t *testing.T) { @@ -2237,7 +2252,7 @@ func TestLoadAPIParams_APIKeyInvalid(t *testing.T) { } } -func TestLoadAPIParams_ApiKey_SettingTakePrecedence(t *testing.T) { +func TestLoadAPIParams_APIKey_ConfigFileTakesPrecedence(t *testing.T) { v := viper.New() v.Set("config", "testdata/.wakatime.cfg") v.Set("entity", "testdata/heartbeat_go.json") @@ -2254,7 +2269,7 @@ func TestLoadAPIParams_ApiKey_SettingTakePrecedence(t *testing.T) { assert.Equal(t, "00000000-0000-4000-8000-000000000000", params.Key) } -func TestLoadAPIParams_ApiKey_FromVault(t *testing.T) { +func TestLoadAPIParams_APIKey_FromVault(t *testing.T) { v := viper.New() v.Set("config", "testdata/.wakatime-vault.cfg") v.Set("entity", "testdata/heartbeat_go.json") @@ -2271,7 +2286,7 @@ func TestLoadAPIParams_ApiKey_FromVault(t *testing.T) { assert.Equal(t, "00000000-0000-4000-8000-000000000000", params.Key) } -func TestLoadParams_ApiKey_FromVault_Err_Darwin(t *testing.T) { +func TestLoadParams_APIKey_FromVault_Err_Darwin(t *testing.T) { if runtime.GOOS != "darwin" { t.Skip("Skipping because OS is not darwin.") } @@ -2304,7 +2319,7 @@ func TestLoadAPIParams_APIKeyFromEnv(t *testing.T) { assert.Equal(t, "00000000-0000-4000-8000-000000000000", params.Key) } -func TestLoadAPIParams_APIKeyFromEnvInvalid(t *testing.T) { +func TestLoadAPIParams_APIKeyFromEnv_Invalid(t *testing.T) { v := viper.New() t.Setenv("WAKATIME_API_KEY", "00000000-0000-4000-0000-000000000000") @@ -2490,13 +2505,13 @@ func TestLoadAPIParams_BackoffAtFuture(t *testing.T) { func TestLoadAPIParams_DisableSSLVerify_FlagTakesPrecedence(t *testing.T) { v := viper.New() v.Set("key", "00000000-0000-4000-8000-000000000000") - v.Set("no-ssl-verify", true) - v.Set("settings.no_ssl_verify", false) + v.Set("no-ssl-verify", false) + v.Set("settings.no_ssl_verify", true) params, err := cmdparams.LoadAPIParams(context.Background(), v) require.NoError(t, err) - assert.True(t, params.DisableSSLVerify) + assert.False(t, params.DisableSSLVerify) } func TestLoadAPIParams_DisableSSLVerify_FromConfig(t *testing.T) { @@ -2557,7 +2572,7 @@ func TestLoadAPIParams_ProxyURL_FlagTakesPrecedence(t *testing.T) { assert.Equal(t, "https://john:secret@example.org:8888", params.ProxyURL) } -func TestLoadAPIParams_ProxyURL_UserDefinedTakesPrecedenceOverEnvironment(t *testing.T) { +func TestLoadAPIParams_ProxyURL_FlagTakesPrecedenceOverEnvironment(t *testing.T) { v := viper.New() v.Set("key", "00000000-0000-4000-8000-000000000000") v.Set("proxy", "https://john:secret@example.org:8888") @@ -2653,8 +2668,6 @@ func TestLoadAPIParams_Hostname_FlagTakesPrecedence(t *testing.T) { v.Set("hostname", "my-machine") v.Set("settings.hostname", "ignored") - t.Setenv("GITPOD_WORKSPACE_ID", "gitpod") - params, err := cmdparams.LoadAPIParams(context.Background(), v) require.NoError(t, err) @@ -2712,13 +2725,13 @@ func TestLoadAPIParams_Hostname_DefaultFromSystem(t *testing.T) { func TestLoadStatusBarParams_HideCategories_FlagTakesPrecedence(t *testing.T) { v := viper.New() - v.Set("today-hide-categories", true) - v.Set("settings.status_bar_hide_categories", "ignored") + v.Set("today-hide-categories", false) + v.Set("settings.status_bar_hide_categories", true) params, err := cmdparams.LoadStatusBarParams(v) require.NoError(t, err) - assert.True(t, params.HideCategories) + assert.False(t, params.HideCategories) } func TestLoadStatusBarParams_HideCategories_ConfigTakesPrecedence(t *testing.T) { diff --git a/pkg/vipertools/vipertools.go b/pkg/vipertools/vipertools.go index 19a0e0f3..23374997 100644 --- a/pkg/vipertools/vipertools.go +++ b/pkg/vipertools/vipertools.go @@ -8,23 +8,32 @@ import ( ) // FirstNonEmptyBool accepts multiple keys and returns the first non-empty bool value -// from viper.Viper via these keys. Non-empty meaning false value will not be accepted. +// from viper.Viper via these keys. Non-empty meaning key not set will not be accepted. func FirstNonEmptyBool(v *viper.Viper, keys ...string) bool { if v == nil { return false } for _, key := range keys { - if value := v.GetBool(key); value { - return value + if !v.IsSet(key) { + continue + } + + value := v.Get(key) + + parsed, err := cast.ToBoolE(value) + if err != nil { + continue } + + return parsed } return false } // FirstNonEmptyInt accepts multiple keys and returns the first non-empty int value -// from viper.Viper via these keys. Non-empty meaning 0 value will not be accepted. +// from viper.Viper via these keys. Non-empty meaning key not set will not be accepted. // Will return false as second parameter, if non-empty int value could not be retrieved. func FirstNonEmptyInt(v *viper.Viper, keys ...string) (int, bool) { if v == nil { @@ -59,6 +68,19 @@ func FirstNonEmptyString(v *viper.Viper, keys ...string) string { } for _, key := range keys { + // if !v.IsSet(key) { + // continue + // } + + // value := v.Get(key) + + // parsed, err := cast.ToStringE(value) + // if err != nil { + // continue + // } + + // return parsed + if value := GetString(v, key); value != "" { return value } diff --git a/pkg/vipertools/vipertools_test.go b/pkg/vipertools/vipertools_test.go index 7b48b606..c36fa0ee 100644 --- a/pkg/vipertools/vipertools_test.go +++ b/pkg/vipertools/vipertools_test.go @@ -12,11 +12,19 @@ import ( func TestFirstNonEmptyBool(t *testing.T) { v := viper.New() - v.Set("second", true) - v.Set("third", false) + v.Set("second", false) + v.Set("third", true) value := vipertools.FirstNonEmptyBool(v, "first", "second", "third") - assert.True(t, value) + assert.False(t, value) +} + +func TestFirstNonEmptyBool_NonBool(t *testing.T) { + v := viper.New() + v.Set("first", "stringvalue") + + value := vipertools.FirstNonEmptyBool(v, "first") + assert.False(t, value) } func TestFirstNonEmptyBool_NilPointer(t *testing.T) { @@ -53,27 +61,37 @@ func TestFirstNonEmptyInt_NilPointer(t *testing.T) { func TestFirstNonEmptyInt_EmptyKeys(t *testing.T) { v := viper.New() - _, ok := vipertools.FirstNonEmptyInt(v) - assert.False(t, ok) + value, ok := vipertools.FirstNonEmptyInt(v) + require.False(t, ok) + + assert.Zero(t, value) } func TestFirstNonEmptyInt_NotFound(t *testing.T) { - _, ok := vipertools.FirstNonEmptyInt(viper.New(), "key") - assert.False(t, ok) + value, ok := vipertools.FirstNonEmptyInt(viper.New(), "key") + require.False(t, ok) + + assert.Zero(t, value) } func TestFirstNonEmptyInt_EmptyInt(t *testing.T) { v := viper.New() v.Set("first", 0) - _, ok := vipertools.FirstNonEmptyInt(v, "first") + + value, ok := vipertools.FirstNonEmptyInt(v, "first") assert.True(t, ok) + + assert.Zero(t, value) } func TestFirstNonEmptyInt_StringValue(t *testing.T) { v := viper.New() v.Set("first", "stringvalue") - _, ok := vipertools.FirstNonEmptyInt(v, "first") - assert.False(t, ok) + + value, ok := vipertools.FirstNonEmptyInt(v, "first") + require.False(t, ok) + + assert.Zero(t, value) } func TestFirstNonEmptyString(t *testing.T) {