129 lines
2.6 KiB
Go
129 lines
2.6 KiB
Go
package container_test
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/cosmos/cosmos-sdk/container"
|
|
)
|
|
|
|
type KVStoreKey struct {
|
|
name string
|
|
}
|
|
|
|
type ModuleKey string
|
|
|
|
type MsgClientA struct {
|
|
key ModuleKey
|
|
}
|
|
|
|
type KeeperA struct {
|
|
key KVStoreKey
|
|
}
|
|
|
|
type KeeperB struct {
|
|
key KVStoreKey
|
|
msgClientA MsgClientA
|
|
}
|
|
|
|
type Handler struct {
|
|
Handle func()
|
|
}
|
|
|
|
type Command struct {
|
|
Run func()
|
|
}
|
|
|
|
func ProvideKVStoreKey(scope container.Scope) KVStoreKey {
|
|
return KVStoreKey{name: scope.Name()}
|
|
}
|
|
|
|
func ProvideModuleKey(scope container.Scope) ModuleKey {
|
|
return ModuleKey(scope.Name())
|
|
}
|
|
|
|
func ProvideMsgClientA(_ container.Scope, key ModuleKey) MsgClientA {
|
|
return MsgClientA{key}
|
|
}
|
|
|
|
type ModuleA struct{}
|
|
|
|
func (ModuleA) Provide(key KVStoreKey) (KeeperA, Handler, Command) {
|
|
return KeeperA{key}, Handler{}, Command{}
|
|
}
|
|
|
|
type ModuleB struct{}
|
|
|
|
type BDependencies struct {
|
|
container.StructArgs
|
|
|
|
Key KVStoreKey
|
|
A MsgClientA
|
|
}
|
|
|
|
type BProvides struct {
|
|
KeeperB KeeperB
|
|
Handler Handler
|
|
Commands []Command
|
|
}
|
|
|
|
func (ModuleB) Provide(dependencies BDependencies) BProvides {
|
|
return BProvides{
|
|
KeeperB: KeeperB{
|
|
key: dependencies.Key,
|
|
msgClientA: dependencies.A,
|
|
},
|
|
Handler: Handler{},
|
|
Commands: []Command{{}, {}},
|
|
}
|
|
}
|
|
|
|
func TestRun(t *testing.T) {
|
|
t.Skip("Expecting this test to fail for now")
|
|
require.NoError(t,
|
|
container.Run(
|
|
func(handlers map[container.Scope]Handler, commands []Command, a KeeperA, b KeeperB) {
|
|
// TODO:
|
|
// require one Handler for module a and a scopes
|
|
// require 3 commands
|
|
// require KeeperA have store key a
|
|
// require KeeperB have store key b and MsgClientA
|
|
}),
|
|
container.AutoGroupTypes(reflect.TypeOf(Command{})),
|
|
container.OnePerScopeTypes(reflect.TypeOf(Handler{})),
|
|
container.Provide(
|
|
ProvideKVStoreKey,
|
|
ProvideModuleKey,
|
|
ProvideMsgClientA,
|
|
),
|
|
container.ProvideWithScope(container.NewScope("a"), wrapProvideMethod(ModuleA{})),
|
|
container.ProvideWithScope(container.NewScope("b"), wrapProvideMethod(ModuleB{})),
|
|
)
|
|
}
|
|
|
|
func wrapProvideMethod(module interface{}) container.ConstructorInfo {
|
|
method := reflect.TypeOf(module).Method(0)
|
|
methodTy := method.Type
|
|
var in []reflect.Type
|
|
var out []reflect.Type
|
|
|
|
for i := 1; i < methodTy.NumIn(); i++ {
|
|
in = append(in, methodTy.In(i))
|
|
}
|
|
for i := 0; i < methodTy.NumOut(); i++ {
|
|
out = append(out, methodTy.Out(i))
|
|
}
|
|
|
|
return container.ConstructorInfo{
|
|
In: in,
|
|
Out: out,
|
|
Fn: func(values []reflect.Value) []reflect.Value {
|
|
values = append([]reflect.Value{reflect.ValueOf(module)}, values...)
|
|
return method.Func.Call(values)
|
|
},
|
|
Location: container.LocationFromPC(method.Func.Pointer()),
|
|
}
|
|
}
|