Skip to content

Commit

Permalink
100% coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
lsegal committed Mar 17, 2018
1 parent 51dfe05 commit 2f55619
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 30 deletions.
33 changes: 28 additions & 5 deletions dinit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ func TestInit_InvalidArgs(t *testing.T) {
assert.EqualError(t, dinit.Init(1), "unsupported provider type: 1")
assert.EqualError(t, dinit.Init("x"), "unsupported provider type: x")
assert.EqualError(t, dinit.Init(nil), "unsupported provider type: <nil>")

var f func()
assert.EqualError(t, dinit.Init(f), "nil function func()")
}

func TestInit_IgnoreArgs(t *testing.T) {
Expand All @@ -91,19 +94,39 @@ func TestInit_IgnoreArgs(t *testing.T) {
Unimplemented()
}
type val struct{}
prod := func() (val, int, unimplementer, error) {
out = append(out, "prod")
provide := func() (val, int, unimplementer, error) {
out = append(out, "provide")
return val{}, 0, nil, nil
}
assert.NoError(t, dinit.Init(prod, val{}))
assert.Equal(t, []string{"prod"}, out)
assert.NoError(t, dinit.Init(provide, val{}))
assert.Equal(t, []string{"provide"}, out)
}

func TestInit_InvalidInputs(t *testing.T) {
type unimplementer interface {
Unimplemented()
}
provide := func(u unimplementer) {}
assert.EqualError(t, dinit.Init(provide), "no injectable value for type dinit_test.unimplementer")

type x struct{}
type y struct{}
newX := func(y y) x { return x{} }
newY := func() {}
assert.EqualError(t, dinit.Init(newX, newY), "missing provider object for github.com/lsegal/dinit_test.y")
}

func TestInit_Error(t *testing.T) {
func TestInit_ProviderFnError(t *testing.T) {
out = []string{}
err := dinit.Init(newB, c{""}, d{"test"})
assert.EqualError(t, err, "invalid argument")
assert.Equal(t, []string{}, out)

type x struct{}
type y struct{}
newX := func(y y) x { return x{} }
newY := func() (y, error) { return y{}, errors.New("nope") }
assert.EqualError(t, dinit.Init(newX, newY), "nope")
}

func TestInit_Cycle(t *testing.T) {
Expand Down
15 changes: 5 additions & 10 deletions invoke.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,11 @@ func (r *resolver) callfn(fn reflect.Value, callmap map[reflect.Value]bool) erro
var val reflect.Value
var ok bool
var name string
var err error
for {
// check to see if we already have a value for this input type and use it
// if we do
val, ok, name, err = r.provide(t.In(i))
if err != nil {
return err
}
// if we do. ignore err here because after validate() this can no longer
// return an error.
val, ok, name, _ = r.provide(t.In(i))
if ok && val.IsValid() && val.Kind() != reflect.Func {
break
}
Expand Down Expand Up @@ -84,11 +81,9 @@ func (r *resolver) callfn(fn reflect.Value, callmap map[reflect.Value]bool) erro
if c == nil {
continue
}
name := nameof(c)
if name == "" {
continue
if name := nameof(c); name != "" {
r.valmap[name] = out
}
r.valmap[name] = out
}
return nil
}
25 changes: 10 additions & 15 deletions resolve.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,12 @@ func (r *resolver) fillValMap() {
if c == nil {
continue
}
name := nameof(c)
if name == "" {
continue
}
if _, ok := r.valmap[name]; ok {
continue // skip if we already have a value
if name := nameof(c); name != "" {
if _, ok := r.valmap[name]; ok {
continue // skip if we already have a value
}
r.valmap[name] = fn
}
r.valmap[name] = fn
}
}
}
Expand Down Expand Up @@ -125,22 +123,19 @@ func (r *resolver) provide(t reflect.Type) (v reflect.Value, ok bool, name strin
err = fmt.Errorf("no injectable value for type %v", t)
return
}
name = nameof(c)
if name == "" {
err = fmt.Errorf("unknown type %v", t)
return
if name = nameof(c); name != "" {
v, ok = r.valmap[name]
}
v, ok = r.valmap[name]
return
}

// validate checks to see if any provider functions will create a call cycle
// when trying to initialize objects or if any arguments are unknown.
func (r *resolver) validate(fn reflect.Value, m map[reflect.Value]int) error {
if !fn.IsValid() {
return nil
}
fnt := fn.Type()
if fn.IsNil() {
return fmt.Errorf("nil function %+v", fnt)
}

if m == nil {
m = map[reflect.Value]int{}
Expand Down

0 comments on commit 2f55619

Please sign in to comment.