Skip to content

Commit b53031f

Browse files
committed
chore: adds tests
1 parent 567c20e commit b53031f

2 files changed

Lines changed: 237 additions & 21 deletions

File tree

custom_lookup_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package envconfig
2+
3+
import (
4+
"os"
5+
"testing"
6+
)
7+
8+
func TestCustomLookup(t *testing.T) {
9+
t.Run("empty", func(t *testing.T) {
10+
const keyEmpty = "__CUSTOM_LOOKUP_EMPTY_KEY__"
11+
t.Setenv(keyEmpty, "")
12+
13+
_, ignoreExists := IgnoreEmptyEnvLookup(keyEmpty)
14+
_, osExists := os.LookupEnv(keyEmpty)
15+
16+
if ignoreExists == osExists {
17+
t.Fatalf("Expected %q to not exists got %v != %v", keyEmpty, ignoreExists, osExists)
18+
}
19+
})
20+
21+
t.Run("non_empty", func(t *testing.T) {
22+
const keyNotEmpty = "__CUSTOM_LOOKUP_KEY__"
23+
t.Setenv(keyNotEmpty, "__value__")
24+
25+
ignoreVal, ignoreExists := IgnoreEmptyEnvLookup(keyNotEmpty)
26+
osVal, osExists := os.LookupEnv(keyNotEmpty)
27+
28+
if ignoreExists != osExists {
29+
t.Fatalf("Expected %q to not exists got %v != %v", keyNotEmpty, ignoreExists, osExists)
30+
}
31+
32+
if ignoreVal != osVal {
33+
t.Fatalf("Expected %q to have the same values: %v != %v", keyNotEmpty, ignoreVal, osVal)
34+
}
35+
})
36+
}

envconfig_test.go

Lines changed: 201 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ func TestReadValues(t *testing.T) {
120120
CustomJSONUnmarshaler2: CustomJSONUnmarshaler{
121121
Value: "***custom3***",
122122
},
123-
Duration: time.Hour,
123+
CustomString: "***custom_text***",
124+
Duration: time.Hour,
124125
SliceDuration: []time.Duration{
125126
time.Hour,
126127
2 * time.Hour,
@@ -318,26 +319,27 @@ type Config struct {
318319
NotPopulated string `env:"-"`
319320
unexported string
320321

321-
String string `env:"A"`
322-
Int int `env:"B"`
323-
Int8 int8 `env:"C"`
324-
Int16 int16 `env:"D"`
325-
Int32 int32 `env:"E"`
326-
Int64 int64 `env:"F"`
327-
Uint uint `env:"G"`
328-
Uint8 uint8 `env:"H"`
329-
Uint16 uint16 `env:"I"`
330-
Uint32 uint32 `env:"J"`
331-
Uint64 uint64 `env:"K"`
332-
Float32 float32 `env:"L"`
333-
Float64 float64 `env:"M"`
334-
Bool bool `env:"N"`
335-
ArrString [2]string `env:"O"`
336-
SliceString []string `env:"P"`
337-
Map map[string]string `env:"Q"`
338-
PtrBool *bool `env:"R"`
339-
NilPtr *string `env:"MISSING"`
340-
NilPtrStruct *struct {
322+
String string `env:"A"`
323+
Int int `env:"B"`
324+
Int8 int8 `env:"C"`
325+
Int16 int16 `env:"D"`
326+
Int32 int32 `env:"E"`
327+
Int64 int64 `env:"F"`
328+
Uint uint `env:"G"`
329+
Uint8 uint8 `env:"H"`
330+
Uint16 uint16 `env:"I"`
331+
Uint32 uint32 `env:"J"`
332+
Uint64 uint64 `env:"K"`
333+
Float32 float32 `env:"L"`
334+
Float64 float64 `env:"M"`
335+
Bool bool `env:"N"`
336+
ArrString [2]string `env:"O"`
337+
SliceString []string `env:"P"`
338+
Map map[string]string `env:"Q"`
339+
PtrBool *bool `env:"R"`
340+
NilPtrIgnored *int `env:"-"`
341+
NilPtr *string `env:"MISSING"`
342+
NilPtrStruct *struct {
341343
A string `env:"A"`
342344
B *string `env:"MISSING"`
343345
}
@@ -351,6 +353,8 @@ type Config struct {
351353
CustomBinaryUnmarshaler CustomBinaryUnmarshaler `env:"CUSTOM_BINARY"`
352354
CustomJSONUnmarshaler CustomJSONUnmarshaler `env:"CUSTOM_JSON"`
353355

356+
CustomString CustomString `env:"CUSTOM_TEXT"`
357+
354358
CustomTextUnmarshaler2 CustomTextUnmarshaler `env:"CUSTOM"`
355359
CustomBinaryUnmarshaler2 CustomBinaryUnmarshaler `env:"CUSTOM"`
356360
CustomJSONUnmarshaler2 CustomJSONUnmarshaler `env:"CUSTOM"`
@@ -398,6 +402,13 @@ func (c *CustomJSONUnmarshaler) UnmarshalJSON(text []byte) error {
398402
return nil
399403
}
400404

405+
type CustomString string
406+
407+
func (c *CustomString) UnmarshalJSON(text []byte) error {
408+
*c = CustomString("***" + string(text) + "***")
409+
return nil
410+
}
411+
401412
func ptr[T any](t T) *T {
402413
return &t
403414
}
@@ -823,6 +834,175 @@ func TestNilPointer(t *testing.T) {
823834
assertErr(t, err, "envconfig: nil holder")
824835
}
825836

837+
func TestPointerStructDeallocation(t *testing.T) {
838+
type Sub struct {
839+
Host string `env:"HOST"`
840+
Port int `env:"PORT"`
841+
}
842+
843+
t.Run("nil_when_no_env_vars_set", func(t *testing.T) {
844+
type Config struct {
845+
DB *Sub `envPrefix:"DB"`
846+
}
847+
848+
le := func(key string) (string, bool) {
849+
return "", false
850+
}
851+
852+
var cfg Config
853+
if err := envconfig.Read(&cfg, le); err != nil {
854+
t.Fatal(err)
855+
}
856+
857+
if cfg.DB != nil {
858+
t.Errorf("expected DB to be nil, got %+v", cfg.DB)
859+
}
860+
})
861+
862+
t.Run("allocated_when_any_env_var_set", func(t *testing.T) {
863+
type Config struct {
864+
DB *Sub `envPrefix:"DB"`
865+
}
866+
867+
le := func(key string) (string, bool) {
868+
if key == "DB_HOST" {
869+
return "localhost", true
870+
}
871+
return "", false
872+
}
873+
874+
var cfg Config
875+
if err := envconfig.Read(&cfg, le); err != nil {
876+
t.Fatal(err)
877+
}
878+
879+
if cfg.DB == nil {
880+
t.Fatal("expected DB to be allocated")
881+
}
882+
if cfg.DB.Host != "localhost" {
883+
t.Errorf("expected Host=localhost, got %q", cfg.DB.Host)
884+
}
885+
if cfg.DB.Port != 0 {
886+
t.Errorf("expected Port=0, got %d", cfg.DB.Port)
887+
}
888+
})
889+
890+
t.Run("nested_pointer_struct_nil", func(t *testing.T) {
891+
type Inner struct {
892+
Cert string `env:"CERT"`
893+
}
894+
type Outer struct {
895+
Host string `env:"HOST"`
896+
TLS *Inner `envPrefix:"TLS"`
897+
}
898+
type Config struct {
899+
DB *Outer `envPrefix:"DB"`
900+
}
901+
902+
le := func(key string) (string, bool) {
903+
if key == "DB_HOST" {
904+
return "localhost", true
905+
}
906+
return "", false
907+
}
908+
909+
var cfg Config
910+
if err := envconfig.Read(&cfg, le); err != nil {
911+
t.Fatal(err)
912+
}
913+
914+
if cfg.DB == nil {
915+
t.Fatal("expected DB to be allocated")
916+
}
917+
if cfg.DB.TLS != nil {
918+
t.Errorf("expected TLS to be nil, got %+v", cfg.DB.TLS)
919+
}
920+
})
921+
}
922+
923+
func TestUnmarshalerInCompositeTypes(t *testing.T) {
924+
t.Run("slice_of_text_unmarshaler", func(t *testing.T) {
925+
type Config struct {
926+
Values []CustomString `env:"VALUES"`
927+
}
928+
929+
le := func(key string) (string, bool) {
930+
if key == "VALUES" {
931+
return "hello,world", true
932+
}
933+
return "", false
934+
}
935+
936+
var cfg Config
937+
if err := envconfig.Read(&cfg, le); err != nil {
938+
t.Fatal(err)
939+
}
940+
941+
if len(cfg.Values) != 2 {
942+
t.Fatalf("expected 2 elements, got %d", len(cfg.Values))
943+
}
944+
if cfg.Values[0] != "***hello***" {
945+
t.Errorf("expected ***hello***, got %q", cfg.Values[0])
946+
}
947+
if cfg.Values[1] != "***world***" {
948+
t.Errorf("expected ***world***, got %q", cfg.Values[1])
949+
}
950+
})
951+
952+
t.Run("map_value_text_unmarshaler", func(t *testing.T) {
953+
type Config struct {
954+
Values map[string]CustomString `env:"VALUES"`
955+
}
956+
957+
le := func(key string) (string, bool) {
958+
if key == "VALUES" {
959+
return "a=hello,b=world", true
960+
}
961+
return "", false
962+
}
963+
964+
var cfg Config
965+
if err := envconfig.Read(&cfg, le); err != nil {
966+
t.Fatal(err)
967+
}
968+
969+
if len(cfg.Values) != 2 {
970+
t.Fatalf("expected 2 entries, got %d", len(cfg.Values))
971+
}
972+
if cfg.Values["a"] != "***hello***" {
973+
t.Errorf("expected ***hello***, got %q", cfg.Values["a"])
974+
}
975+
if cfg.Values["b"] != "***world***" {
976+
t.Errorf("expected ***world***, got %q", cfg.Values["b"])
977+
}
978+
})
979+
980+
t.Run("array_of_text_unmarshaler", func(t *testing.T) {
981+
type Config struct {
982+
Values [2]CustomString `env:"VALUES"`
983+
}
984+
985+
le := func(key string) (string, bool) {
986+
if key == "VALUES" {
987+
return "hello,world", true
988+
}
989+
return "", false
990+
}
991+
992+
var cfg Config
993+
if err := envconfig.Read(&cfg, le); err != nil {
994+
t.Fatal(err)
995+
}
996+
997+
if cfg.Values[0] != "***hello***" {
998+
t.Errorf("expected ***hello***, got %q", cfg.Values[0])
999+
}
1000+
if cfg.Values[1] != "***world***" {
1001+
t.Errorf("expected ***world***, got %q", cfg.Values[1])
1002+
}
1003+
})
1004+
}
1005+
8261006
func assertErr(t *testing.T, err error, exp string) {
8271007
t.Helper()
8281008
if err == nil {

0 commit comments

Comments
 (0)