package confext import ( "gogs.mikescher.com/BlackForestBytes/goext/timeext" "gogs.mikescher.com/BlackForestBytes/goext/tst" "testing" "time" ) func TestApplyEnvOverridesNoop(t *testing.T) { type aliasint int type aliasstring string type testdata struct { V1 int `env:"TEST_V1"` VX string `` V2 string `env:"TEST_V2"` V3 int8 `env:"TEST_V3"` V4 int32 `env:"TEST_V4"` V5 int64 `env:"TEST_V5"` V6 aliasint `env:"TEST_V6"` VY aliasint `` V7 aliasstring `env:"TEST_V7"` V8 time.Duration `env:"TEST_V8"` V9 time.Time `env:"TEST_V9"` } input := testdata{ V1: 1, VX: "X", V2: "2", V3: 3, V4: 4, V5: 5, V6: 6, VY: 99, V7: "7", V8: 9, V9: time.Unix(1671102873, 0), } output := input err := ApplyEnvOverrides("", &output, ".") if err != nil { t.Errorf("%v", err) t.FailNow() } tst.AssertEqual(t, input, output) } func TestApplyEnvOverridesSimple(t *testing.T) { type aliasint int type aliasstring string type testdata struct { V1 int `env:"TEST_V1"` VX string `` V2 string `env:"TEST_V2"` V3 int8 `env:"TEST_V3"` V4 int32 `env:"TEST_V4"` V5 int64 `env:"TEST_V5"` V6 aliasint `env:"TEST_V6"` VY aliasint `` V7 aliasstring `env:"TEST_V7"` V8 time.Duration `env:"TEST_V8"` V9 time.Time `env:"TEST_V9"` VA bool `env:"TEST_VA"` } data := testdata{ V1: 1, VX: "X", V2: "2", V3: 3, V4: 4, V5: 5, V6: 6, VY: 99, V7: "7", V8: 9, V9: time.Unix(1671102873, 0), VA: false, } t.Setenv("TEST_V1", "846") t.Setenv("TEST_V2", "hello_world") t.Setenv("TEST_V3", "6") t.Setenv("TEST_V4", "333") t.Setenv("TEST_V5", "-937") t.Setenv("TEST_V6", "070") t.Setenv("TEST_V7", "AAAAAA") t.Setenv("TEST_V8", "1min4s") t.Setenv("TEST_V9", "2009-11-10T23:00:00Z") t.Setenv("TEST_VA", "true") err := ApplyEnvOverrides("", &data, ".") if err != nil { t.Errorf("%v", err) t.FailNow() } tst.AssertEqual(t, data.V1, 846) tst.AssertEqual(t, data.V2, "hello_world") tst.AssertEqual(t, data.V3, 6) tst.AssertEqual(t, data.V4, 333) tst.AssertEqual(t, data.V5, -937) tst.AssertEqual(t, data.V6, 70) tst.AssertEqual(t, data.V7, "AAAAAA") tst.AssertEqual(t, data.V8, time.Second*64) tst.AssertEqual(t, data.V9, time.Unix(1257894000, 0).UTC()) tst.AssertEqual(t, data.VA, true) } func TestApplyEnvOverridesRecursive(t *testing.T) { type subdata struct { V1 int `env:"SUB_V1"` VX string `` V2 string `env:"SUB_V2"` V8 time.Duration `env:"SUB_V3"` V9 time.Time `env:"SUB_V4"` } type testdata struct { V1 int `env:"TEST_V1"` VX string `` Sub1 subdata `` Sub2 subdata `env:"TEST_V2"` Sub3 subdata `env:"TEST_V3"` Sub4 subdata `env:""` V5 string `env:"-"` } data := testdata{ V1: 1, VX: "2", V5: "no", Sub1: subdata{ V1: 3, VX: "4", V2: "5", V8: 6 * time.Second, V9: time.Date(2000, 1, 7, 1, 1, 1, 0, time.UTC), }, Sub2: subdata{ V1: 8, VX: "9", V2: "10", V8: 11 * time.Second, V9: time.Date(2000, 1, 12, 1, 1, 1, 0, timeext.TimezoneBerlin), }, Sub3: subdata{ V1: 13, VX: "14", V2: "15", V8: 16 * time.Second, V9: time.Date(2000, 1, 17, 1, 1, 1, 0, timeext.TimezoneBerlin), }, Sub4: subdata{ V1: 18, VX: "19", V2: "20", V8: 21 * time.Second, V9: time.Date(2000, 1, 22, 1, 1, 1, 0, timeext.TimezoneBerlin), }, } t.Setenv("TEST_V1", "999") t.Setenv("-", "yes") t.Setenv("TEST_V2_SUB_V1", "846") t.Setenv("TEST_V2_SUB_V2", "222_hello_world") t.Setenv("TEST_V2_SUB_V3", "1min4s") t.Setenv("TEST_V2_SUB_V4", "2009-11-10T23:00:00Z") t.Setenv("TEST_V3_SUB_V1", "33846") t.Setenv("TEST_V3_SUB_V2", "33_hello_world") t.Setenv("TEST_V3_SUB_V3", "33min4s") t.Setenv("TEST_V3_SUB_V4", "2033-11-10T23:00:00Z") t.Setenv("SUB_V1", "11") t.Setenv("SUB_V2", "22") t.Setenv("SUB_V3", "33min") t.Setenv("SUB_V4", "2044-01-01T00:00:00Z") err := ApplyEnvOverrides("", &data, "_") if err != nil { t.Errorf("%v", err) t.FailNow() } tst.AssertEqual(t, data.V1, 999) tst.AssertEqual(t, data.VX, "2") tst.AssertEqual(t, data.V5, "no") tst.AssertEqual(t, data.Sub1.V1, 3) tst.AssertEqual(t, data.Sub1.VX, "4") tst.AssertEqual(t, data.Sub1.V2, "5") tst.AssertEqual(t, data.Sub1.V8, time.Second*6) tst.AssertEqual(t, data.Sub1.V9, time.Unix(947206861, 0).UTC()) tst.AssertEqual(t, data.Sub2.V1, 846) tst.AssertEqual(t, data.Sub2.VX, "9") tst.AssertEqual(t, data.Sub2.V2, "222_hello_world") tst.AssertEqual(t, data.Sub2.V8, time.Second*64) tst.AssertEqual(t, data.Sub2.V9, time.Unix(1257894000, 0).UTC()) tst.AssertEqual(t, data.Sub3.V1, 33846) tst.AssertEqual(t, data.Sub3.VX, "14") tst.AssertEqual(t, data.Sub3.V2, "33_hello_world") tst.AssertEqual(t, data.Sub3.V8, time.Second*1984) tst.AssertEqual(t, data.Sub3.V9, time.Unix(2015276400, 0).UTC()) tst.AssertEqual(t, data.Sub4.V1, 11) tst.AssertEqual(t, data.Sub4.VX, "19") tst.AssertEqual(t, data.Sub4.V2, "22") tst.AssertEqual(t, data.Sub4.V8, time.Second*1980) tst.AssertEqual(t, data.Sub4.V9, time.Unix(2335219200, 0).UTC()) } func TestApplyEnvOverridesPointer(t *testing.T) { type aliasint int type aliasstring string type testdata struct { V1 *int `env:"TEST_V1"` VX *string `` V2 *string `env:"TEST_V2"` V3 *int8 `env:"TEST_V3"` V4 *int32 `env:"TEST_V4"` V5 *int64 `env:"TEST_V5"` V6 *aliasint `env:"TEST_V6"` VY *aliasint `` V7 *aliasstring `env:"TEST_V7"` V8 *time.Duration `env:"TEST_V8"` V9 *time.Time `env:"TEST_V9"` } data := testdata{} t.Setenv("TEST_V1", "846") t.Setenv("TEST_V2", "hello_world") t.Setenv("TEST_V3", "6") t.Setenv("TEST_V4", "333") t.Setenv("TEST_V5", "-937") t.Setenv("TEST_V6", "070") t.Setenv("TEST_V7", "AAAAAA") t.Setenv("TEST_V8", "1min4s") t.Setenv("TEST_V9", "2009-11-10T23:00:00Z") err := ApplyEnvOverrides("", &data, ".") if err != nil { t.Errorf("%v", err) t.FailNow() } tst.AssertDeRefEqual(t, data.V1, 846) tst.AssertDeRefEqual(t, data.V2, "hello_world") tst.AssertDeRefEqual(t, data.V3, 6) tst.AssertDeRefEqual(t, data.V4, 333) tst.AssertDeRefEqual(t, data.V5, -937) tst.AssertDeRefEqual(t, data.V6, 70) tst.AssertDeRefEqual(t, data.V7, "AAAAAA") tst.AssertDeRefEqual(t, data.V8, time.Second*64) tst.AssertDeRefEqual(t, data.V9, time.Unix(1257894000, 0).UTC()) } func assertEqual[T comparable](t *testing.T, actual T, expected T) { if actual != expected { t.Errorf("values differ: Actual: '%v', Expected: '%v'", actual, expected) } } func assertPtrEqual[T comparable](t *testing.T, actual *T, expected T) { if actual == nil { t.Errorf("values differ: Actual: NIL, Expected: '%v'", expected) } if *actual != expected { t.Errorf("values differ: Actual: '%v', Expected: '%v'", actual, expected) } }