Skip to content

Commit

Permalink
feat: add more test case
Browse files Browse the repository at this point in the history
  • Loading branch information
dapeng committed Dec 22, 2024
1 parent a117167 commit c39c87c
Show file tree
Hide file tree
Showing 8 changed files with 555 additions and 40 deletions.
140 changes: 140 additions & 0 deletions config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,3 +273,143 @@ func TestEnvConfigure_Get(t *testing.T) {
})
}
}

func TestConfigProvider_Init(t *testing.T) {
provider := &ConfigProvider{}
// Init() should not panic
provider.Init()
}

func TestConfigProvider_ProvideWithDefaultTag(t *testing.T) {
mockConfigure := &MockConfigure{
values: map[string]string{},
}

provider := &ConfigProvider{
configure: mockConfigure,
}

tests := []struct {
name string
tagConf string
valueType reflect.Type
want any
wantErr bool
}{
{
name: "Use default tag",
tagConf: "missing-key,default=default-value",
valueType: reflect.TypeOf(""),
want: "default-value",
wantErr: false,
},
{
name: "Multiple keys with default",
tagConf: "key1,key2,default=fallback",
valueType: reflect.TypeOf(""),
want: "fallback",
wantErr: false,
},
{
name: "Empty default value",
tagConf: "missing-key,default=",
valueType: reflect.TypeOf(""),
want: "",
wantErr: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := provider.Provide(tt.tagConf, tt.valueType)
if (err != nil) != tt.wantErr {
t.Errorf("ConfigProvider.Provide() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !tt.wantErr && !reflect.DeepEqual(got, tt.want) {
t.Errorf("ConfigProvider.Provide() = %v, want %v", got, tt.want)
}
})
}
}

func TestEnvConfigure_GetInvalidValues(t *testing.T) {
configure := &EnvConfigure{}

tests := []struct {
name string
key string
value any
envValue string
defaultVal string
wantErr bool
}{
{
name: "Invalid int format",
key: "TEST_INVALID_INT",
value: new(int),
envValue: "not-a-number",
defaultVal: "0",
wantErr: true,
},
{
name: "Invalid float format",
key: "TEST_INVALID_FLOAT",
value: new(float64),
envValue: "not-a-float",
defaultVal: "0.0",
wantErr: true,
},
{
name: "Invalid bool format",
key: "TEST_INVALID_BOOL",
value: new(bool),
envValue: "not-a-bool",
defaultVal: "false",
wantErr: true,
},
{
name: "Invalid duration format",
key: "TEST_INVALID_DURATION",
value: new(time.Duration),
envValue: "not-a-duration",
defaultVal: "1s",
wantErr: true,
},
{
name: "Invalid JSON for struct",
key: "TEST_INVALID_STRUCT",
value: &struct{ Name string }{},
envValue: "{invalid-json}",
defaultVal: "{}",
wantErr: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Set environment variable
os.Setenv(GONE+"_"+tt.key, tt.envValue)
defer os.Unsetenv(GONE + "_" + tt.key)

err := configure.Get(tt.key, tt.value, tt.defaultVal)
if (err != nil) != tt.wantErr {
t.Errorf("EnvConfigure.Get() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

func TestEnvConfigure_GetWithEmptyKey(t *testing.T) {
configure := &EnvConfigure{}
value := new(string)

// Test with empty key but valid default value
err := configure.Get("", value, "default")
if err != nil {
t.Errorf("EnvConfigure.Get() with empty key should use default value, got error: %v", err)
}
if *value != "default" {
t.Errorf("EnvConfigure.Get() with empty key = %v, want %v", *value, "default")
}
}
11 changes: 7 additions & 4 deletions core.go
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,11 @@ func (s *Core) GetGonerByName(name string) any {
}

func (s *Core) GetGonerByType(t reflect.Type) any {
return s.getDefaultCoffinByType(t)
T := s.getDefaultCoffinByType(t)
if T != nil {
return T.goner
}
return nil
}

func (s *Core) getCoffinsByType(t reflect.Type) (coffins []*coffin) {
Expand Down Expand Up @@ -421,8 +425,7 @@ func (s *Core) Provide(tagConf string, t reflect.Type) (any, error) {
}
return v.Interface(), nil
}

return nil, nil
return nil, NewInnerError("Cannot find matched Goner for type %s", NotSupport)
}

// FuncInjectHook is a function type used for customizing parameter injection in functions.
Expand Down Expand Up @@ -464,7 +467,7 @@ func (s *Core) InjectFuncParameters(fn any, injectBefore FuncInjectHook, injectA

if !injected {
v, err := s.Provide("", pt)
if err != nil {
if err != nil && !IsError(err, NotSupport) {
return nil, ToErrorWithMsg(err, fmt.Sprintf("Inject %dth parameter of %s error", i+1, GetFuncName(fn)))
}
if v != nil {
Expand Down
213 changes: 213 additions & 0 deletions core_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package gone

import (
"errors"
"fmt"
"reflect"
"testing"
)
Expand Down Expand Up @@ -382,3 +383,215 @@ func TestCore_InjectWrapFunc(t *testing.T) {
})
}
}

func TestCore_GetGonerByName(t *testing.T) {
tests := []struct {
name string
setup func(*Core)
findName string
want bool
}{
{
name: "Find existing named component",
setup: func(core *Core) {
_ = core.Load(&MockNamed{})
},
findName: "named-dep",
want: true,
},
{
name: "Component not found",
setup: func(core *Core) {
_ = core.Load(&MockComponent{})
},
findName: "non-existent",
want: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
core := NewCore()
tt.setup(core)

got := core.GetGonerByName(tt.findName)
if (got != nil) != tt.want {
t.Errorf("Core.GetGonerByName() = %v, want %v", got != nil, tt.want)
}
})
}
}

func TestCore_GetGonerByType(t *testing.T) {
tests := []struct {
name string
setup func(*Core)
typ reflect.Type
want bool
}{
{
name: "Find existing type",
setup: func(core *Core) {
_ = core.Load(&MockDependency{})
},
typ: reflect.TypeOf(&MockDependency{}),
want: true,
},
{
name: "Multiple implementations with default",
setup: func(core *Core) {
_ = core.Load(&MockDependency{}, IsDefault())
_ = core.Load(&MockDependency{})
},
typ: reflect.TypeOf(&MockDependency{}),
want: true,
},
{
name: "Type not found",
setup: func(core *Core) {},
typ: reflect.TypeOf(&MockComponent{}),
want: false,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
core := NewCore()
tt.setup(core)

got := core.GetGonerByType(tt.typ)
if (got != nil) != tt.want {
t.Errorf("Core.GetGonerByType() = %v, want %v", got != nil, tt.want)
}
})
}
}

func TestCore_InjectStruct(t *testing.T) {
type testStruct struct {
Flag
Dep *MockDependency `gone:"*"`
}

tests := []struct {
name string
setup func(*Core)
target any
wantErr bool
}{
{
name: "Valid struct injection",
setup: func(core *Core) {
_ = core.Load(&MockDependency{})
},
target: &testStruct{},
wantErr: false,
},
{
name: "Non-pointer target",
setup: func(core *Core) {},
target: testStruct{},
wantErr: true,
},
{
name: "Non-struct pointer",
setup: func(core *Core) {},
target: new(string),
wantErr: true,
},
{
name: "Missing dependency",
setup: func(core *Core) {},
target: &testStruct{},
wantErr: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
core := NewCore()
tt.setup(core)

err := core.InjectStruct(tt.target)
if (err != nil) != tt.wantErr {
t.Errorf("Core.InjectStruct() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

func TestCore_Loaded(t *testing.T) {
core := NewCore()
key := GenLoaderKey()

// First call should return false
if core.Loaded(key) {
t.Error("First call to Loaded() should return false")
}

// Second call should return true
if !core.Loaded(key) {
t.Error("Second call to Loaded() should return true")
}
}

func TestCore_Provide(t *testing.T) {
type testSlice []*MockDependency

tests := []struct {
name string
setup func(*Core)
typ reflect.Type
tagConf string
want bool
wantErr bool
}{
{
name: "Provide single component",
setup: func(core *Core) {
_ = core.Load(&MockDependency{})
},
typ: reflect.TypeOf(&MockDependency{}),
tagConf: "",
want: true,
wantErr: false,
},
{
name: "Provide slice of components",
setup: func(core *Core) {
_ = core.Load(&MockDependency{})
_ = core.Load(&MockDependency{})
},
typ: reflect.TypeOf(testSlice{}),
tagConf: "",
want: true,
wantErr: false,
},
{
name: "Provider returns error",
setup: func(core *Core) {
_ = core.Load(&MockProvider{returnErr: fmt.Errorf("provider error")})
},
typ: reflect.TypeOf(&MockDependency{}),
tagConf: "",
want: false,
wantErr: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
core := NewCore()
tt.setup(core)

got, err := core.Provide(tt.tagConf, tt.typ)
if (err != nil) != tt.wantErr {
t.Errorf("Core.Provide() error = %v, wantErr %v", err, tt.wantErr)
return
}
if (got != nil) != tt.want {
t.Errorf("Core.Provide() = %v, want %v", got != nil, tt.want)
}
})
}
}
Loading

0 comments on commit c39c87c

Please sign in to comment.