-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmodules_test.go
More file actions
96 lines (86 loc) · 2.76 KB
/
Copy pathmodules_test.go
File metadata and controls
96 lines (86 loc) · 2.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package di_test
import (
"strings"
"testing"
"github.com/floatdrop/di"
)
// A small application in four modules, registered in order, plus one
// registration made outside any module.
type (
mCfg struct{}
mDB struct{}
mStore interface{ Kind() string }
mPGStore struct{}
mCache struct{}
mReq struct{}
mUser struct{}
mMailer struct{}
mServer struct{}
)
func (*mPGStore) Kind() string { return "pg" }
func mConfig(s *di.Scope) { s.Value(mCfg{}) }
func mStorage(s *di.Scope) {
s.Wire[*mDB](func(mCfg) *mDB { return &mDB{} })
s.Wire[mStore](func(*mDB) *mPGStore { return &mPGStore{} })
}
func mCaching(s *di.Scope) {
s.Wire[*mCache](func() *mCache { return &mCache{} })
s.Wrap[mStore](func(next mStore, _ *mCache) mStore { return next })
}
func mAPI(s *di.Scope) {
s.Wire[*mUser](func(*mReq) *mUser { return &mUser{} }).Scoped()
s.Provide(func(s *di.Scope) *mServer { _ = s.Get[mStore](); return &mServer{} })
s.Wire[*mMailer](func(*mUser, *mCfg) *mMailer { return &mMailer{} }) // *mCfg is not provided; mCfg is
}
func TestModulesReport(t *testing.T) {
app := di.New()
app.Use(mConfig, mStorage, mCaching, mAPI)
app.Value(&mReq{}) // outside any module
want := `di_test.mConfig
provides di_test.mCfg
di_test.mStorage
provides *di_test.mDB, di_test.mStore
needs di_test.mCfg ← di_test.mConfig
di_test.mCaching
provides *di_test.mCache
wraps di_test.mStore ← di_test.mStorage
di_test.mAPI
provides *di_test.mUser, *di_test.mServer, *di_test.mMailer
needs *di_test.mReq ← registered directly
*di_test.mCfg ← not provided
unchecked *di_test.mServer (closures: needs known when they run)
registered directly
provides *di_test.mReq
`
if got := app.Modules(); got != want {
t.Fatalf("got:\n%s\nwant:\n%s", got, want)
}
}
// A Scoped binding's dependency that only a resolving scope provides is
// owed, not missing, and a module's dependency on itself is not listed.
func TestModulesReportOwedAndInternal(t *testing.T) {
app := di.New()
app.Use(mAPI)
out := app.Modules()
if !strings.Contains(out, "*di_test.mReq ← owed to a resolving scope") {
t.Fatalf("the request should be owed:\n%s", out)
}
if strings.Contains(out, "*di_test.mUser ←") {
t.Fatalf("a module's own service is not a module dependency:\n%s", out)
}
// From a child that provides the request, nothing is owed.
req := app.Child("request")
req.Value(&mReq{})
if out := req.Modules(); strings.Contains(out, "owed") {
t.Fatalf("the child provides the request:\n%s", out)
}
}
func TestModulesReportBuildsNothing(t *testing.T) {
built := false
app := di.New()
app.Use(func(s *di.Scope) { s.Wire[*mDB](func() *mDB { built = true; return &mDB{} }) })
_ = app.Modules()
if built {
t.Fatal("Modules ran a constructor")
}
}