@@ -18,6 +18,7 @@ package bind_test
1818
1919import (
2020 "context"
21+ "errors"
2122 "math/big"
2223 "reflect"
2324 "strings"
@@ -75,34 +76,51 @@ func (mt *mockTransactor) SendTransaction(ctx context.Context, tx *types.Transac
7576}
7677
7778type mockCaller struct {
78- codeAtBlockNumber * big.Int
79- callContractBlockNumber * big.Int
80- pendingCodeAtCalled bool
81- pendingCallContractCalled bool
79+ codeAtBlockNumber * big.Int
80+ callContractBlockNumber * big.Int
81+ callContractBytes []byte
82+ callContractErr error
83+ codeAtBytes []byte
84+ codeAtErr error
8285}
8386
8487func (mc * mockCaller ) CodeAt (ctx context.Context , contract common.Address , blockNumber * big.Int ) ([]byte , error ) {
8588 mc .codeAtBlockNumber = blockNumber
86- return [] byte { 1 , 2 , 3 }, nil
89+ return mc . codeAtBytes , mc . codeAtErr
8790}
8891
8992func (mc * mockCaller ) CallContract (ctx context.Context , call ethereum.CallMsg , blockNumber * big.Int ) ([]byte , error ) {
9093 mc .callContractBlockNumber = blockNumber
91- return nil , nil
94+ return mc . callContractBytes , mc . callContractErr
9295}
9396
94- func (mc * mockCaller ) PendingCodeAt (ctx context.Context , contract common.Address ) ([]byte , error ) {
97+ type mockPendingCaller struct {
98+ * mockCaller
99+ pendingCodeAtBytes []byte
100+ pendingCodeAtErr error
101+ pendingCodeAtCalled bool
102+ pendingCallContractCalled bool
103+ pendingCallContractBytes []byte
104+ pendingCallContractErr error
105+ }
106+
107+ func (mc * mockPendingCaller ) PendingCodeAt (ctx context.Context , contract common.Address ) ([]byte , error ) {
95108 mc .pendingCodeAtCalled = true
96- return nil , nil
109+ return mc . pendingCodeAtBytes , mc . pendingCodeAtErr
97110}
98111
99- func (mc * mockCaller ) PendingCallContract (ctx context.Context , call ethereum.CallMsg ) ([]byte , error ) {
112+ func (mc * mockPendingCaller ) PendingCallContract (ctx context.Context , call ethereum.CallMsg ) ([]byte , error ) {
100113 mc .pendingCallContractCalled = true
101- return nil , nil
114+ return mc . pendingCallContractBytes , mc . pendingCallContractErr
102115}
116+
103117func TestPassingBlockNumber (t * testing.T ) {
104118
105- mc := & mockCaller {}
119+ mc := & mockPendingCaller {
120+ mockCaller : & mockCaller {
121+ codeAtBytes : []byte {1 , 2 , 3 },
122+ },
123+ }
106124
107125 bc := bind .NewBoundContract (common .HexToAddress ("0x0" ), abi.ABI {
108126 Methods : map [string ]abi.Method {
@@ -341,3 +359,132 @@ func newMockLog(topics []common.Hash, txHash common.Hash) types.Log {
341359 Removed : false ,
342360 }
343361}
362+
363+ func TestCall (t * testing.T ) {
364+ var method , methodWithArg = "something" , "somethingArrrrg"
365+ tests := []struct {
366+ name , method string
367+ opts * bind.CallOpts
368+ mc bind.ContractCaller
369+ results * []interface {}
370+ wantErr bool
371+ wantErrExact error
372+ }{{
373+ name : "ok not pending" ,
374+ mc : & mockCaller {
375+ codeAtBytes : []byte {0 },
376+ },
377+ method : method ,
378+ }, {
379+ name : "ok pending" ,
380+ mc : & mockPendingCaller {
381+ pendingCodeAtBytes : []byte {0 },
382+ },
383+ opts : & bind.CallOpts {
384+ Pending : true ,
385+ },
386+ method : method ,
387+ }, {
388+ name : "pack error, no method" ,
389+ mc : new (mockCaller ),
390+ method : "else" ,
391+ wantErr : true ,
392+ }, {
393+ name : "interface error, pending but not a PendingContractCaller" ,
394+ mc : new (mockCaller ),
395+ opts : & bind.CallOpts {
396+ Pending : true ,
397+ },
398+ method : method ,
399+ wantErrExact : bind .ErrNoPendingState ,
400+ }, {
401+ name : "pending call canceled" ,
402+ mc : & mockPendingCaller {
403+ pendingCallContractErr : context .DeadlineExceeded ,
404+ },
405+ opts : & bind.CallOpts {
406+ Pending : true ,
407+ },
408+ method : method ,
409+ wantErrExact : context .DeadlineExceeded ,
410+ }, {
411+ name : "pending code at error" ,
412+ mc : & mockPendingCaller {
413+ pendingCodeAtErr : errors .New ("" ),
414+ },
415+ opts : & bind.CallOpts {
416+ Pending : true ,
417+ },
418+ method : method ,
419+ wantErr : true ,
420+ }, {
421+ name : "no pending code at" ,
422+ mc : new (mockPendingCaller ),
423+ opts : & bind.CallOpts {
424+ Pending : true ,
425+ },
426+ method : method ,
427+ wantErrExact : bind .ErrNoCode ,
428+ }, {
429+ name : "call contract error" ,
430+ mc : & mockCaller {
431+ callContractErr : context .DeadlineExceeded ,
432+ },
433+ method : method ,
434+ wantErrExact : context .DeadlineExceeded ,
435+ }, {
436+ name : "code at error" ,
437+ mc : & mockCaller {
438+ codeAtErr : errors .New ("" ),
439+ },
440+ method : method ,
441+ wantErr : true ,
442+ }, {
443+ name : "no code at" ,
444+ mc : new (mockCaller ),
445+ method : method ,
446+ wantErrExact : bind .ErrNoCode ,
447+ }, {
448+ name : "unpack error missing arg" ,
449+ mc : & mockCaller {
450+ codeAtBytes : []byte {0 },
451+ },
452+ method : methodWithArg ,
453+ wantErr : true ,
454+ }, {
455+ name : "interface unpack error" ,
456+ mc : & mockCaller {
457+ codeAtBytes : []byte {0 },
458+ },
459+ method : method ,
460+ results : & []interface {}{0 },
461+ wantErr : true ,
462+ }}
463+ for _ , test := range tests {
464+ bc := bind .NewBoundContract (common .HexToAddress ("0x0" ), abi.ABI {
465+ Methods : map [string ]abi.Method {
466+ method : {
467+ Name : method ,
468+ Outputs : abi.Arguments {},
469+ },
470+ methodWithArg : {
471+ Name : methodWithArg ,
472+ Outputs : abi.Arguments {abi.Argument {}},
473+ },
474+ },
475+ }, test .mc , nil , nil )
476+ err := bc .Call (test .opts , test .results , test .method )
477+ if test .wantErr || test .wantErrExact != nil {
478+ if err == nil {
479+ t .Fatalf ("%q expected error" , test .name )
480+ }
481+ if test .wantErrExact != nil && ! errors .Is (err , test .wantErrExact ) {
482+ t .Fatalf ("%q expected error %q but got %q" , test .name , test .wantErrExact , err )
483+ }
484+ continue
485+ }
486+ if err != nil {
487+ t .Fatalf ("%q unexpected error: %v" , test .name , err )
488+ }
489+ }
490+ }
0 commit comments