@@ -422,6 +422,122 @@ func TestMaybeConvertValue(t *testing.T) {
422422 }
423423}
424424
425+ func TestNativveToPyFuncBridge (t * testing.T ) {
426+ tests := []struct {
427+ name string
428+ fn func (* testing.T , * Frame , Args , KWArgs ) (* Object , * BaseException )
429+ typ reflect.Type
430+ args []interface {}
431+ ret []interface {}
432+ panc * BaseException
433+ }{
434+ {
435+ name : "no args" ,
436+ fn : func (t * testing.T , f * Frame , a Args , k KWArgs ) (* Object , * BaseException ) {
437+ if f == nil || len (a ) != 0 || len (k ) != 0 {
438+ t .Errorf ("fn called with (%v, %v, %v), want (non-nil, %v, %v)" , f , a , k , Args {}, KWArgs {})
439+ }
440+ return nil , nil
441+ },
442+ typ : reflect .TypeOf (func () {}),
443+ ret : []interface {}{},
444+ },
445+ {
446+ name : "return wrong size" ,
447+ fn : func (* testing.T , * Frame , Args , KWArgs ) (* Object , * BaseException ) {
448+ return NewInt (1 ).ToObject (), nil
449+ },
450+ typ : reflect .TypeOf (func () {}),
451+ panc : mustCreateException (TypeErrorType , "unexpected return of 1 when None expected" ),
452+ },
453+ {
454+ name : "single return value" ,
455+ fn : func (* testing.T , * Frame , Args , KWArgs ) (* Object , * BaseException ) {
456+ return NewInt (1 ).ToObject (), nil
457+ },
458+ typ : reflect .TypeOf ((* func () int )(nil )).Elem (),
459+ ret : []interface {}{1 },
460+ },
461+ {
462+ name : "wrong size multiple return value" ,
463+ fn : func (* testing.T , * Frame , Args , KWArgs ) (* Object , * BaseException ) {
464+ return NewTuple (NewInt (1 ).ToObject (), NewInt (2 ).ToObject (), NewInt (3 ).ToObject ()).ToObject (), nil
465+ },
466+ typ : reflect .TypeOf ((* func () (int , int ))(nil )).Elem (),
467+ panc : mustCreateException (TypeErrorType , "return value too long, want 2 items" ),
468+ },
469+ {
470+ name : "multiple return value" ,
471+ fn : func (* testing.T , * Frame , Args , KWArgs ) (* Object , * BaseException ) {
472+ return NewTuple (NewInt (1 ).ToObject (), NewInt (2 ).ToObject (), NewInt (3 ).ToObject ()).ToObject (), nil
473+ },
474+ typ : reflect .TypeOf ((* func () (int , int , int ))(nil )).Elem (),
475+ ret : []interface {}{1 , 2 , 3 },
476+ },
477+
478+ {
479+ name : "func takes args" ,
480+ fn : func (t * testing.T , f * Frame , a Args , k KWArgs ) (* Object , * BaseException ) {
481+ want := Args {
482+ NewInt (1 ).ToObject (),
483+ NewInt (2 ).ToObject (),
484+ }
485+ if f == nil || ! reflect .DeepEqual (a , want ) || len (k ) != 0 {
486+ t .Errorf ("fn called with (%v, %v, %v), want (non-nil, %v, %v)" , f , a , k , want , KWArgs {})
487+ }
488+ return nil , nil
489+ },
490+ typ : reflect .TypeOf (func (int , int ) {}),
491+ args : []interface {}{1 , 2 },
492+ ret : []interface {}{},
493+ },
494+ }
495+
496+ for _ , test := range tests {
497+ t .Run (test .name , func (t * testing.T ) {
498+ called := false
499+ fn := func (f * Frame , a Args , k KWArgs ) (* Object , * BaseException ) {
500+ called = true
501+ return test .fn (t , f , a , k )
502+ }
503+
504+ args := make ([]reflect.Value , len (test .args ))
505+ for i , a := range test .args {
506+ args [i ] = reflect .ValueOf (a )
507+ }
508+
509+ nativeFn := nativeToPyFuncBridge (fn , test .typ )
510+ ret := func () []reflect.Value {
511+ if test .panc != nil {
512+ defer func () {
513+ r := recover ()
514+ raised , ok := r .(* BaseException )
515+ if r == nil || ! ok || ! exceptionsAreEquivalent (raised , test .panc ) {
516+ t .Errorf ("recover()=%v (type %T), want %v" , r , r , test .panc )
517+ }
518+ }()
519+ }
520+ return nativeFn .Call (args )
521+ }()
522+
523+ if test .panc == nil {
524+ got := make ([]interface {}, 0 , len (test .ret ))
525+ for _ , v := range ret {
526+ got = append (got , v .Interface ())
527+ }
528+
529+ if ! reflect .DeepEqual (got , test .ret ) {
530+ t .Errorf ("fn returned %v, want %v" , got , test .ret )
531+ }
532+ }
533+
534+ if ! called {
535+ t .Errorf ("fn not called, want to be called" )
536+ }
537+ })
538+ }
539+ }
540+
425541func TestNativeTypedefNative (t * testing.T ) {
426542 fun := wrapFuncForTest (func (f * Frame , o * Object , wantType reflect.Type ) (bool , * BaseException ) {
427543 val , raised := ToNative (f , o )
0 commit comments