Added NULL decoding tests for return values
This commit is contained in:
@@ -97,3 +97,28 @@ export const mixedStaticAndDynamicReturnValues: MethodAbi = {
|
||||
stateMutability: 'nonpayable',
|
||||
type: 'function',
|
||||
};
|
||||
|
||||
export const structuredReturnValue: MethodAbi = {
|
||||
constant: false,
|
||||
inputs: [],
|
||||
name: 'fillOrder',
|
||||
outputs: [
|
||||
{
|
||||
components: [
|
||||
{
|
||||
name: 'makerAssetFilledAmount',
|
||||
type: 'uint256',
|
||||
},
|
||||
{
|
||||
name: 'takerAssetFilledAmount',
|
||||
type: 'uint256',
|
||||
},
|
||||
],
|
||||
name: 'fillResults',
|
||||
type: 'tuple',
|
||||
},
|
||||
],
|
||||
payable: false,
|
||||
stateMutability: 'nonpayable',
|
||||
type: 'function',
|
||||
};
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import * as chai from 'chai';
|
||||
import 'mocha';
|
||||
|
||||
import { AbiEncoder } from '../../src/';
|
||||
import { AbiEncoder, BigNumber } from '../../src/';
|
||||
import { chaiSetup } from '../utils/chai_setup';
|
||||
|
||||
import * as ReturnValueAbis from './abi_samples/return_value_abis';
|
||||
@@ -11,67 +11,194 @@ const expect = chai.expect;
|
||||
|
||||
describe('ABI Encoder: Return Value Encoding/Decoding', () => {
|
||||
const encodingRules: AbiEncoder.EncodingRules = { shouldOptimize: false }; // optimizer is tested separately.
|
||||
it('No Return Value', async () => {
|
||||
// Decode return value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.noReturnValues);
|
||||
const returnValue = '0x';
|
||||
const decodedReturnValue = method.decodeReturnValues(returnValue, { shouldConvertStructsToObjects: false });
|
||||
const expectedDecodedReturnValue: any[] = [];
|
||||
expect(decodedReturnValue).to.be.deep.equal(expectedDecodedReturnValue);
|
||||
});
|
||||
it('Single static return value', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.singleStaticReturnValue);
|
||||
const returnValue = ['0x01020304'];
|
||||
const encodedReturnValue = method.encodeReturnValues(returnValue, encodingRules);
|
||||
const decodedReturnValue = method.decodeReturnValues(encodedReturnValue, {
|
||||
shouldConvertStructsToObjects: false,
|
||||
const nullEncodedReturnValue = '0x';
|
||||
describe('Standard encoding/decoding', () => {
|
||||
it('No Return Value', async () => {
|
||||
// Decode return value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.noReturnValues);
|
||||
const returnValue = '0x';
|
||||
const decodedReturnValue = method.decodeReturnValues(returnValue, { shouldConvertStructsToObjects: false });
|
||||
const expectedDecodedReturnValue: any[] = [];
|
||||
expect(decodedReturnValue).to.be.deep.equal(expectedDecodedReturnValue);
|
||||
});
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue);
|
||||
});
|
||||
it('Multiple static return values', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.multipleStaticReturnValues);
|
||||
const returnValue = ['0x01020304', '0x05060708'];
|
||||
const encodedReturnValue = method.encodeReturnValues(returnValue, encodingRules);
|
||||
const decodedReturnValue = method.decodeReturnValues(encodedReturnValue, {
|
||||
shouldConvertStructsToObjects: false,
|
||||
it('Single static return value', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.singleStaticReturnValue);
|
||||
const returnValue = ['0x01020304'];
|
||||
const encodedReturnValue = method.encodeReturnValues(returnValue, encodingRules);
|
||||
const decodedReturnValue = method.decodeReturnValues(encodedReturnValue, {
|
||||
shouldConvertStructsToObjects: false,
|
||||
});
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue);
|
||||
});
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue);
|
||||
});
|
||||
it('Single dynamic return value', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.singleDynamicReturnValue);
|
||||
const returnValue = ['0x01020304'];
|
||||
const encodedReturnValue = method.encodeReturnValues(returnValue, encodingRules);
|
||||
const decodedReturnValue = method.decodeReturnValues(encodedReturnValue, {
|
||||
shouldConvertStructsToObjects: false,
|
||||
it('Multiple static return values', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.multipleStaticReturnValues);
|
||||
const returnValue = ['0x01020304', '0x05060708'];
|
||||
const encodedReturnValue = method.encodeReturnValues(returnValue, encodingRules);
|
||||
const decodedReturnValue = method.decodeReturnValues(encodedReturnValue, {
|
||||
shouldConvertStructsToObjects: false,
|
||||
});
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue);
|
||||
});
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue);
|
||||
});
|
||||
it('Multiple dynamic return values', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.multipleDynamicReturnValues);
|
||||
const returnValue = ['0x01020304', '0x05060708'];
|
||||
const encodedReturnValue = method.encodeReturnValues(returnValue, encodingRules);
|
||||
const decodedReturnValue = method.decodeReturnValues(encodedReturnValue, {
|
||||
shouldConvertStructsToObjects: false,
|
||||
it('Single dynamic return value', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.singleDynamicReturnValue);
|
||||
const returnValue = ['0x01020304'];
|
||||
const encodedReturnValue = method.encodeReturnValues(returnValue, encodingRules);
|
||||
const decodedReturnValue = method.decodeReturnValues(encodedReturnValue, {
|
||||
shouldConvertStructsToObjects: false,
|
||||
});
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue);
|
||||
});
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue);
|
||||
});
|
||||
it('Mixed static/dynamic return values', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.mixedStaticAndDynamicReturnValues);
|
||||
const returnValue = ['0x01020304', '0x05060708'];
|
||||
const encodedReturnValue = method.encodeReturnValues(returnValue, encodingRules);
|
||||
const decodedReturnValue = method.decodeReturnValues(encodedReturnValue, {
|
||||
shouldConvertStructsToObjects: false,
|
||||
it('Multiple dynamic return values', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.multipleDynamicReturnValues);
|
||||
const returnValue = ['0x01020304', '0x05060708'];
|
||||
const encodedReturnValue = method.encodeReturnValues(returnValue, encodingRules);
|
||||
const decodedReturnValue = method.decodeReturnValues(encodedReturnValue, {
|
||||
shouldConvertStructsToObjects: false,
|
||||
});
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue);
|
||||
});
|
||||
it('Mixed static/dynamic return values', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.mixedStaticAndDynamicReturnValues);
|
||||
const returnValue = ['0x01020304', '0x05060708'];
|
||||
const encodedReturnValue = method.encodeReturnValues(returnValue, encodingRules);
|
||||
const decodedReturnValue = method.decodeReturnValues(encodedReturnValue, {
|
||||
shouldConvertStructsToObjects: false,
|
||||
});
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue);
|
||||
});
|
||||
it('Should decode NULL as default value (single; static)', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.singleStaticReturnValue);
|
||||
const returnValue = ['0x00000000'];
|
||||
|
||||
const decodedReturnValue = method.decodeReturnValues(nullEncodedReturnValue, {
|
||||
shouldConvertStructsToObjects: false,
|
||||
});
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue);
|
||||
});
|
||||
it('Should decode NULL as default value (multiple; static)', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.multipleStaticReturnValues);
|
||||
const returnValue = ['0x00000000', '0x00000000'];
|
||||
const decodedReturnValue = method.decodeReturnValues(nullEncodedReturnValue, {
|
||||
shouldConvertStructsToObjects: false,
|
||||
});
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue);
|
||||
});
|
||||
it('Should decode NULL as default value (single; dynamic)', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.singleDynamicReturnValue);
|
||||
const returnValue = ['0x'];
|
||||
const decodedReturnValue = method.decodeReturnValues(nullEncodedReturnValue, {
|
||||
shouldConvertStructsToObjects: false,
|
||||
});
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Strict encoding/decoding', () => {
|
||||
it('No Return Value', async () => {
|
||||
// Decode return value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.noReturnValues);
|
||||
const returnValue = '0x';
|
||||
const decodedReturnValue = method.strictDecodeReturnValue<void>(returnValue);
|
||||
const expectedDecodedReturnValue = undefined;
|
||||
expect(decodedReturnValue).to.be.deep.equal(expectedDecodedReturnValue);
|
||||
});
|
||||
it('Single static return value', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.singleStaticReturnValue);
|
||||
const returnValue = ['0x01020304'];
|
||||
const encodedReturnValue = method.encodeReturnValues(returnValue, encodingRules);
|
||||
const decodedReturnValue = method.strictDecodeReturnValue<string>(encodedReturnValue);
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue[0]);
|
||||
});
|
||||
it('Multiple static return values', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.multipleStaticReturnValues);
|
||||
const returnValue = ['0x01020304', '0x05060708'];
|
||||
const encodedReturnValue = method.encodeReturnValues(returnValue, encodingRules);
|
||||
const decodedReturnValue = method.strictDecodeReturnValue<[string, string]>(encodedReturnValue);
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue);
|
||||
});
|
||||
it('Single dynamic return value', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.singleDynamicReturnValue);
|
||||
const returnValue = ['0x01020304'];
|
||||
const encodedReturnValue = method.encodeReturnValues(returnValue, encodingRules);
|
||||
const decodedReturnValue = method.strictDecodeReturnValue<string>(encodedReturnValue);
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue[0]);
|
||||
});
|
||||
it('Multiple dynamic return values', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.multipleDynamicReturnValues);
|
||||
const returnValue = ['0x01020304', '0x05060708'];
|
||||
const encodedReturnValue = method.encodeReturnValues(returnValue, encodingRules);
|
||||
const decodedReturnValue = method.strictDecodeReturnValue<[string, string]>(encodedReturnValue);
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue);
|
||||
});
|
||||
it('Struct should include fields', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.structuredReturnValue);
|
||||
const returnValue = {
|
||||
fillResults: {
|
||||
makerAssetFilledAmount: new BigNumber(50),
|
||||
takerAssetFilledAmount: new BigNumber(40),
|
||||
},
|
||||
};
|
||||
const encodedReturnValue = method.encodeReturnValues(returnValue, encodingRules);
|
||||
const decodedReturnValue = method.strictDecodeReturnValue<{
|
||||
makerAssetFilledAmount: BigNumber;
|
||||
takerAssetFilledAmount: BigNumber;
|
||||
}>(encodedReturnValue);
|
||||
// Validate decoded return value
|
||||
// Note that only the contents of `fillResults`, not the key itself, is decoded.
|
||||
// This is by design, as only a struct's contents are encoded and returned by a funciton call.
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue.fillResults);
|
||||
});
|
||||
it('Should decode NULL as default value (single; static)', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.singleStaticReturnValue);
|
||||
const returnValue = '0x00000000';
|
||||
const encodedReturnValue = '0x';
|
||||
const decodedReturnValue = method.strictDecodeReturnValue<string>(encodedReturnValue);
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue);
|
||||
});
|
||||
it('Should decode NULL as default value (multiple; static)', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.multipleStaticReturnValues);
|
||||
const returnValue = ['0x00000000', '0x00000000'];
|
||||
const encodedReturnValue = '0x';
|
||||
const decodedReturnValue = method.strictDecodeReturnValue<[string, string]>(encodedReturnValue);
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue);
|
||||
});
|
||||
it('Should decode NULL as default value (single; dynamic)', async () => {
|
||||
// Generate Return Value
|
||||
const method = new AbiEncoder.Method(ReturnValueAbis.singleDynamicReturnValue);
|
||||
const returnValue = '0x';
|
||||
const encodedReturnValue = '0x';
|
||||
const decodedReturnValue = method.strictDecodeReturnValue<string>(encodedReturnValue);
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue);
|
||||
});
|
||||
// Validate decoded return value
|
||||
expect(decodedReturnValue).to.be.deep.equal(returnValue);
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user