func wrap(fn Agent) formatAgent { r := reflect.ValueOf(fn) t := r.Type() in := make([]reflect.Value, t.NumIn()) return func(ctx context.Context) (context.Context, string, error) { for i := 0; i < t.NumIn(); i++ { switch { case t.In(i).Implements(reflect.TypeOf(iContext).Elem()): in[i] = reflect.ValueOf(ctx) case t.In(i).Implements(reflect.TypeOf(iLogger).Elem()): logger, ok := ctx.Value("logger").(logex.Logger) if !ok { logger = logex.New() } in[i] = reflect.ValueOf(logger) case t.In(i).AssignableTo(reflect.TypeOf(iRequest).Elem()): v, ok := ctx.Value("req").(*http.Request) if !ok { panic("*http.Request not found") } in[i] = reflect.ValueOf(v) case t.In(i).Implements(reflect.TypeOf(iResponse).Elem()): v, ok := ctx.Value("res").(http.ResponseWriter) if !ok { panic("http.ResponseWriter not found") } in[i] = reflect.ValueOf(v) } } /* if t.NumIn() == 1 && reflect.TypeOf(ctx).AssignableTo(t.In(0)) { in[0] = reflect.ValueOf(ctx) } */ out := r.Call(in) var ( nextStep string = "default" err error ) for _, v := range out { switch { case v.Type().Implements(reflect.TypeOf(iContext).Elem()): // log.Println("got context.Context") ctx = v.Interface().(context.Context) case v.Type().Implements(reflect.TypeOf(iError).Elem()) && !v.IsNil(): // log.Println("got error") err = v.Interface().(error) case v.Type().AssignableTo(reflect.TypeOf(nextStep)): // log.Println("got step") nextStep = v.String() default: // log.Println(v.Type()) } } return ctx, nextStep, err } }
func TestLogger(t *testing.T) { log := logex.New() log.SetLogLevel(logex.DEBUG) bf := bytes.Buffer{} log.SetOutput(&bf) ctx := context.WithValue(context.Background(), "logger", log) fn := wrap(func(logger logex.Logger, ctx context.Context) context.Context { logger.Debug("123") t.Log("print log") t.Log(bf.String()) return ctx }) var ( tc context.Context ts string te error ) tc, ts, te = fn(ctx) t.Log(tc, ts, te) if strings.Index(bf.String(), "123") == -1 { t.Error(bf.String()) } }