package hero_test import ( "fmt" "reflect" "testing" "github.com/kataras/iris/v12/context" . "github.com/kataras/iris/v12/hero" ) type testDependencyTest struct { Dependency interface{} Expected interface{} } func TestDependency(t *testing.T) { var tests = []testDependencyTest{ { Dependency: "myValue", Expected: "myValue", }, { Dependency: struct{ Name string }{"name"}, Expected: struct{ Name string }{"name"}, }, { Dependency: func(*context.Context, *Input) (reflect.Value, error) { return reflect.ValueOf(42), nil }, Expected: 42, }, { Dependency: DependencyHandler(func(*context.Context, *Input) (reflect.Value, error) { return reflect.ValueOf(255), nil }), Expected: 255, }, { Dependency: func(*context.Context) (reflect.Value, error) { return reflect.ValueOf("OK without Input"), nil }, Expected: "OK without Input", }, { Dependency: func(*context.Context, ...string) (reflect.Value, error) { return reflect.ValueOf("OK variadic ignored"), nil }, Expected: "OK variadic ignored", }, { Dependency: func(*context.Context) reflect.Value { return reflect.ValueOf("OK without Input and error") }, Expected: "OK without Input and error", }, { Dependency: func(*context.Context, ...int) reflect.Value { return reflect.ValueOf("OK without error and variadic ignored") }, Expected: "OK without error and variadic ignored", }, { Dependency: func(*context.Context) interface{} { return "1" }, Expected: "1", }, { Dependency: func(*context.Context) interface{} { return false }, Expected: false, }, } testDependencies(t, tests) } // Test dependencies that depend on previous one(s). func TestDependentDependency(t *testing.T) { msgBody := "prefix: it is a deep dependency" newMsgBody := msgBody + " new" var tests = []testDependencyTest{ // test three level depth and error. { // 0 Dependency: &testServiceImpl{prefix: "prefix:"}, Expected: &testServiceImpl{prefix: "prefix:"}, }, { // 1 Dependency: func(service testService) testMessage { return testMessage{Body: service.Say("it is a deep") + " dependency"} }, Expected: testMessage{Body: msgBody}, }, { // 2 Dependency: func(msg testMessage) string { return msg.Body }, Expected: msgBody, }, { // 3 Dependency: func(msg testMessage) error { return fmt.Errorf(msg.Body) }, Expected: fmt.Errorf(msgBody), }, // Test depend on more than one previous registered dependencies and require a before-previous one. { // 4 Dependency: func(body string, msg testMessage) string { if body != msg.Body { t.Fatalf("body[%s] != msg.Body[%s]", body, msg.Body) } return body + " new" }, Expected: newMsgBody, }, // Test dependency order by expecting the first returning value and not the later-on registered dependency(#4). // 5 { Dependency: func(body string) string { return body }, Expected: newMsgBody, }, } testDependencies(t, tests) } func testDependencies(t *testing.T, tests []testDependencyTest) { t.Helper() c := New() for i, tt := range tests { d := c.Register(tt.Dependency) if d == nil { t.Fatalf("[%d] expected %#+v to be converted to a valid dependency", i, tt) } val, err := d.Handle(context.NewContext(nil), &Input{}) if expectError := isError(reflect.TypeOf(tt.Expected)); expectError { val = reflect.ValueOf(err) err = nil } if err != nil { t.Fatalf("[%d] expected a nil error but got: %v", i, err) } if !val.CanInterface() { t.Fatalf("[%d] expected output value to be accessible: %T", i, val) } if expected, got := fmt.Sprintf("%#+v", tt.Expected), fmt.Sprintf("%#+v", val.Interface()); expected != got { t.Fatalf("[%d] expected return value to be:\n%s\nbut got:\n%s", i, expected, got) } // t.Logf("[%d] %s", i, d) // t.Logf("[%d] output: %#+v", i, val.Interface()) } } func TestDependentDependencyInheritanceStatic(t *testing.T) { // Tests the following case #1564: // Logger // func(Logger) S1 // ^ Should be static because Logger // is a structure, a static dependency. // // func(Logger) S2 // func(S1, S2) S3 // ^ Should be marked as static dependency // because everything that depends on are static too. type S1 struct { msg string } type S2 struct { msg2 string } serviceDep := NewDependency(&testServiceImpl{prefix: "1"}) d1 := NewDependency(func(t testService) S1 { return S1{t.Say("2")} }, serviceDep) if !d1.Static { t.Fatalf("d1 dependency should be static: %#+v", d1) } d2 := NewDependency(func(t testService, s S1) S2 { return S2{"3"} }, serviceDep, d1) if !d2.Static { t.Fatalf("d2 dependency should be static: %#+v", d2) } }