|
|
@@ -0,0 +1,104 @@
|
|
|
+package config
|
|
|
+
|
|
|
+import (
|
|
|
+ "os"
|
|
|
+ "strings"
|
|
|
+ "testing"
|
|
|
+
|
|
|
+ "github.com/spf13/viper"
|
|
|
+ "github.com/stretchr/testify/assert"
|
|
|
+)
|
|
|
+
|
|
|
+var stringEnvConfigYaml = `
|
|
|
+pageTitle: ${{ INPUT }}
|
|
|
+`
|
|
|
+
|
|
|
+var stringEnvInterpolationConfigYaml = `
|
|
|
+pageTitle: Olivetin - ${{ INPUT }}
|
|
|
+`
|
|
|
+
|
|
|
+var boolEnvConfigYaml = `
|
|
|
+checkForUpdates: ${{ INPUT }}
|
|
|
+`
|
|
|
+
|
|
|
+var numericEnvConfigYaml = `
|
|
|
+logHistoryPageSize: ${{ INPUT }}
|
|
|
+`
|
|
|
+
|
|
|
+var argsSyntaxConfigYaml = `
|
|
|
+actions:
|
|
|
+ - title: Ping host
|
|
|
+ id: ping_host
|
|
|
+ shell: ping {{ host }} -c ${{ INPUT }}
|
|
|
+ icon: ping
|
|
|
+ timeout: 100
|
|
|
+ popupOnStart: execution-dialog-stdout-only
|
|
|
+ arguments:
|
|
|
+ - name: host
|
|
|
+ title: Host
|
|
|
+ type: ascii_identifier
|
|
|
+ default: example.com
|
|
|
+ description: The host that you want to ping
|
|
|
+`
|
|
|
+
|
|
|
+func pageTitleSelector(cfg *Config) any {
|
|
|
+ return cfg.PageTitle
|
|
|
+}
|
|
|
+
|
|
|
+func checkForUpdatesSelector(cfg *Config) any {
|
|
|
+ return cfg.CheckForUpdates
|
|
|
+}
|
|
|
+
|
|
|
+func logHistoryPageSizeSelector(cfg *Config) any {
|
|
|
+ return cfg.LogHistoryPageSize
|
|
|
+}
|
|
|
+
|
|
|
+var envConfigTests = []struct {
|
|
|
+ yaml string
|
|
|
+ input string
|
|
|
+ output any
|
|
|
+ selector func(*Config) any
|
|
|
+}{
|
|
|
+ // Test that it works for string type config fields, both standalone and as part of a larger string value.
|
|
|
+ {stringEnvConfigYaml, "A Nice Title", "A Nice Title", pageTitleSelector},
|
|
|
+ {stringEnvInterpolationConfigYaml, "A Nice Title", "Olivetin - A Nice Title", pageTitleSelector},
|
|
|
+ // Test that unset variables turn into empty strings.
|
|
|
+ {stringEnvConfigYaml, "", "", pageTitleSelector},
|
|
|
+ // Test that it works for bool type config fields for intuitive bool->string conversions.
|
|
|
+ {boolEnvConfigYaml, "FALSE", false, checkForUpdatesSelector},
|
|
|
+ {boolEnvConfigYaml, "false", false, checkForUpdatesSelector},
|
|
|
+ {boolEnvConfigYaml, "False", false, checkForUpdatesSelector},
|
|
|
+ {boolEnvConfigYaml, "TRUE", true, checkForUpdatesSelector},
|
|
|
+ {boolEnvConfigYaml, "true", true, checkForUpdatesSelector},
|
|
|
+ {boolEnvConfigYaml, "True", true, checkForUpdatesSelector},
|
|
|
+ {boolEnvConfigYaml, "0", false, checkForUpdatesSelector},
|
|
|
+ {boolEnvConfigYaml, "1", true, checkForUpdatesSelector},
|
|
|
+ // Test that unset variables turn into false bools.
|
|
|
+ {boolEnvConfigYaml, "", false, checkForUpdatesSelector},
|
|
|
+ // Test that it works for numeric type config fields.
|
|
|
+ {numericEnvConfigYaml, "2048", int64(2048), logHistoryPageSizeSelector},
|
|
|
+ // Test that unset variables turn into zero numbers.
|
|
|
+ {numericEnvConfigYaml, "", int64(0), logHistoryPageSizeSelector},
|
|
|
+ // Test that it doesn't interfere with similar arguments
|
|
|
+ {argsSyntaxConfigYaml, "5", "ping {{ host }} -c 5", func(cfg *Config) any { return cfg.Actions[0].Shell }},
|
|
|
+}
|
|
|
+
|
|
|
+func TestEnvInConfig(t *testing.T) {
|
|
|
+ viper.SetConfigType("yaml")
|
|
|
+
|
|
|
+ for _, tt := range envConfigTests {
|
|
|
+ err := viper.ReadConfig(strings.NewReader(tt.yaml))
|
|
|
+ assert.Nil(t, err, "Viper read config file with environment variable syntax")
|
|
|
+
|
|
|
+ if tt.input != "" {
|
|
|
+ os.Setenv("INPUT", tt.input)
|
|
|
+ }
|
|
|
+
|
|
|
+ cfg := DefaultConfig()
|
|
|
+ Reload(cfg)
|
|
|
+ field := tt.selector(cfg)
|
|
|
+ assert.Equal(t, tt.output, field, "Unmarshaled config field doesn't match expected value: env=\"%s\"", tt.input)
|
|
|
+
|
|
|
+ os.Unsetenv("INPUT")
|
|
|
+ }
|
|
|
+}
|