manifest: support NEP-24
Close #3451
wrapper generates:
// RoyaltyInfo invokes `royaltyInfo` method of contract.
func (c *ContractReader) RoyaltyInfo(tokenID []byte, royaltyToken util.Uint160, salePrice *big.Int) ([]stackitem.Item, error) {
return unwrap.Array(c.invoker.Call(c.hash, "royaltyInfo", tokenID, royaltyToken, salePrice))
}
but it should be different.
add tests with smartcontact/testdata/
Codecov Report
Attention: Patch coverage is 71.91011% with 50 lines in your changes missing coverage. Please review.
Project coverage is 82.97%. Comparing base (
57eec71) to head (b63c7aa). Report is 5 commits behind head on master.
Additional details and impacted files
@@ Coverage Diff @@
## master #3560 +/- ##
==========================================
- Coverage 83.02% 82.97% -0.06%
==========================================
Files 334 335 +1
Lines 46543 46708 +165
==========================================
+ Hits 38643 38755 +112
- Misses 6326 6363 +37
- Partials 1574 1590 +16
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
🚨 Try these New Features:
- Flaky Tests Detection - Detect and resolve failed and flaky tests
wrapper generates:
// RoyaltyInfo invokes
royaltyInfomethod of contract. func (c *ContractReader) RoyaltyInfo(tokenID []byte, royaltyToken util.Uint160, salePrice *big.Int) ([]stackitem.Item, error) { return unwrap.Array(c.invoker.Call(c.hash, "royaltyInfo", tokenID, royaltyToken, salePrice)) }but it should be different.
What is your expected result? To me, the auto-generated code looks good although it does not includes named return structures, but it depends on the original contract. As I said earlier, it's a matter of separate issue anyway.
i have:
// RoyaltyInfo invokes `royaltyInfo` method of contract.
func (c *RoyaltyReader) RoyaltyInfo(tokenID []byte, royaltyToken util.Uint160, salePrice *big.Int) ([]stackitem.Item, error) {
return unwrap.Array(c.Invoker.Call(c.Hash, "royaltyInfo", tokenID, royaltyToken, salePrice))
}
and:
func TestRoyaltyReaderRoyaltyInfo2(t *testing.T) {
ta := new(testAct)
rr := &RoyaltyReader{
Invoker: ta,
Hash: util.Uint160{1, 2, 3},
}
tokenID := []byte{1, 2, 3}
royaltyToken := util.Uint160{4, 5, 6}
salePrice := big.NewInt(1000)
tests := []struct {
name string
setupFunc func()
expectErr bool
expectedRI []RoyaltyRecipient
}{
{
name: "error case",
setupFunc: func() {
ta.err = errors.New("some error")
},
expectErr: true,
},
{
name: "valid response",
setupFunc: func() {
ta.err = nil
recipient := util.Uint160{7, 8, 9}
amount := big.NewInt(100)
ta.res = &result.Invoke{
State: "HALT",
Stack: []stackitem.Item{
stackitem.Make([]stackitem.Item{
stackitem.Make(recipient.BytesBE()),
stackitem.Make(amount),
}),
},
}
},
expectErr: false,
expectedRI: []RoyaltyRecipient{
{
Address: util.Uint160{7, 8, 9},
Amount: big.NewInt(100),
},
},
},
{
name: "invalid data response",
setupFunc: func() {
ta.res = &result.Invoke{
State: "HALT",
Stack: []stackitem.Item{
stackitem.Make([]stackitem.Item{
stackitem.Make(util.Uint160{7, 8, 9}.BytesBE()),
}),
},
}
},
expectErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.setupFunc()
riStackItems, err := rr.RoyaltyInfo(tokenID, royaltyToken, salePrice)
if tt.expectErr {
require.Error(t, err)
} else {
require.NoError(t, err)
require.Len(t, riStackItems, len(tt.expectedRI))
var actualRI []RoyaltyRecipient
for _, item := range riStackItems {
subItems, ok := item.Value().([]stackitem.Item)
require.True(t, ok)
require.Len(t, subItems, 2)
recipientBytes, err := subItems[0].TryBytes()
require.NoError(t, err)
recipient, err := util.Uint160DecodeBytesBE(recipientBytes)
require.NoError(t, err)
amount, err := subItems[1].TryInteger()
require.NoError(t, err)
actualRI = append(actualRI, RoyaltyRecipient{
Address: recipient,
Amount: amount,
})
}
require.Equal(t, tt.expectedRI, actualRI)
}
})
}
}
and:
=== RUN TestRoyaltyReaderRoyaltyInfo2/valid_response
royalty_test.go:183:
Error Trace: /Users/ekaterinapavlova/Workplace/neo-go/pkg/rpcclient/nep24/royalty_test.go:183
Error: "[ByteString BigInteger]" should have 1 item(s), but has 2
Test: TestRoyaltyReaderRoyaltyInfo2/valid_response
--- FAIL: TestRoyaltyReaderRoyaltyInfo2/valid_response (0.00s)
=== RUN TestRoyaltyReaderRoyaltyInfo2/invalid_data_response
royalty_test.go:180:
Error Trace: /Users/ekaterinapavlova/Workplace/neo-go/pkg/rpcclient/nep24/royalty_test.go:180
Error: An error is expected but got nil.
Test: TestRoyaltyReaderRoyaltyInfo2/invalid_data_response
--- FAIL: TestRoyaltyReaderRoyaltyInfo2/invalid_data_response (0.00s)
wrapper generates: // RoyaltyInfo invokes
royaltyInfomethod of contract. func (c *ContractReader) RoyaltyInfo(tokenID []byte, royaltyToken util.Uint160, salePrice *big.Int) ([]stackitem.Item, error) { return unwrap.Array(c.invoker.Call(c.hash, "royaltyInfo", tokenID, royaltyToken, salePrice)) } but it should be different.What is your expected result? To me, the auto-generated code looks good although it does not includes named return structures, but it depends on the original contract. As I said earlier, it's a matter of separate issue anyway.
I wrongly passed as a config file to generate-rpcbinding the same config file as used for contract compile which is why I expected a different result (something like: https://github.com/nspcc-dev/neo-go/blob/f27de7ce051d8bb5be96361cf8c6ec828b807338/cli/smartcontract/testdata/rpcbindings/nep_contract/rpcbindings.out#L75 ). Also tried to write the test for it https://github.com/nspcc-dev/neo-go/pull/3560#issuecomment-2438393776 and with that implementation, it didn't work.
I wrongly passed as a config file to generate-rpcbinding the same config file as used for contract compile
You're not first one to do this, btw. @smallhive and @tatiana-nspcc both know it happens easily. Long-term this will be solved by removing binding configuration file because of NEP-25.
@AliceInHunterland, ready for review?