Skip to content

Commit

Permalink
add specs for loadAndSetWithOriginal
Browse files Browse the repository at this point in the history
  • Loading branch information
ajatprabha committed Aug 22, 2023
1 parent 3bfc47d commit 281f67a
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 7 deletions.
2 changes: 1 addition & 1 deletion xload/async.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func setNilStructPtr(original reflect.Value, v reflect.Value, isNilStructPtr boo
if isNilStructPtr {
empty := reflect.New(original.Type().Elem()).Interface()

if !reflect.DeepEqual(empty, v.Interface()) {
if !reflect.DeepEqual(empty, v.Interface()) && original.CanSet() {
original.Set(v)
}
}
Expand Down
77 changes: 71 additions & 6 deletions xload/async_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package xload
import (
"context"
"errors"
"reflect"
"sync"
"testing"

Expand Down Expand Up @@ -45,19 +46,23 @@ func TestLoad_Async(t *testing.T) {

func TestLoad_Async_Error(t *testing.T) {
errMap := map[string]error{
"NAME": errors.New("error: NAME"),
"AGE": errors.New("error: AGE"),
"BIO": errors.New("error: BIO"),
"NAME": errors.New("error: NAME"),
"AGE": errors.New("error: AGE"),
"BIO": errors.New("error: BIO"),
"NESTED_VAL": errors.New("error: NESTED_VAL"),
}

loader := func(ctx context.Context, key string) (string, error) {
return "", errMap[key]
}

cfg := struct {
Name string `env:"NAME"`
Age int `env:"AGE"`
Bio string `env:"BIO"`
Name string `env:"NAME"`
Age int `env:"AGE"`
Bio string `env:"BIO"`
Nested struct {
Val string `env:"VAL"`
} `env:",prefix=NESTED_"`
}{}

err := Load(context.Background(), &cfg,
Expand All @@ -70,3 +75,63 @@ func TestLoad_Async_Error(t *testing.T) {
assert.True(t, errors.Is(err, want))
}
}

type CustomString string

func (cs *CustomString) Decode(s string) error {
*cs = CustomString(s)
return nil
}

func Test_loadAndSetWithOriginal(t *testing.T) {
type Args struct {
Nest *struct {
Val CustomString `env:"VAL,required"`
}
}

t.Run("successful load and set", func(t *testing.T) {
meta := &field{name: "testName", required: true}

obj := &Args{
Nest: &struct {
Val CustomString `env:"VAL,required"`
}{},
}

original := reflect.ValueOf(&obj.Nest.Val)
fVal := reflect.ValueOf(&obj.Nest.Val).Elem()

loader := LoaderFunc(func(ctx context.Context, key string) (string, error) {
return "loadedValue", nil
})

err := loadAndSetWithOriginal(loader, meta)(context.Background(), original, fVal, true)
assert.Nil(t, err)
assert.EqualValues(t, "loadedValue", string(obj.Nest.Val))
})

t.Run("loader returns error", func(t *testing.T) {
meta := &field{name: "testName", required: true}
original := reflect.ValueOf(new(string))
fVal := reflect.ValueOf(new(string))

err := loadAndSetWithOriginal(LoaderFunc(func(ctx context.Context, key string) (string, error) {
return "", errors.New("load error")
}), meta)(context.Background(), original, fVal, true)
assert.NotNil(t, err)
assert.Equal(t, "load error", err.Error())
})

t.Run("field is required but loader val is empty", func(t *testing.T) {
meta := &field{name: "testName", required: true}
original := reflect.ValueOf(new(string))
fVal := reflect.ValueOf(new(string))

err := loadAndSetWithOriginal(LoaderFunc(func(ctx context.Context, key string) (string, error) {
return "", nil
}), meta)(context.Background(), original, fVal, true)
assert.NotNil(t, err)
assert.Equal(t, ErrRequired, err)
})
}

0 comments on commit 281f67a

Please sign in to comment.