Add tests for recursive MAP decoding

This commit is contained in:
Amir Bandeali 2019-01-03 11:18:33 -08:00
parent 70508f52a1
commit 5720589515
4 changed files with 68 additions and 10 deletions

View File

@ -128,16 +128,32 @@ export const assetDataUtils = {
*/
decodeMultiAssetDataRecursively(assetData: string): MultiAssetDataWithRecursiveDecoding {
const decodedAssetData = assetDataUtils.decodeMultiAssetData(assetData);
const decodedNestedAssetData = _.map(decodedAssetData.nestedAssetData as string[], nestedAssetDataElement => {
const decodedNestedAssetDataElement = assetDataUtils.decodeAssetDataOrThrow(nestedAssetDataElement);
return decodedNestedAssetDataElement.assetProxyId === AssetProxyId.MultiAsset
? assetDataUtils.decodeMultiAssetDataRecursively(nestedAssetDataElement).nestedAssetData
: (decodedNestedAssetDataElement as SingleAssetData);
});
const amounts: any[] = [];
const decodedNestedAssetData = _.map(
decodedAssetData.nestedAssetData as string[],
(nestedAssetDataElement, index) => {
const decodedNestedAssetDataElement = assetDataUtils.decodeAssetDataOrThrow(nestedAssetDataElement);
if (decodedNestedAssetDataElement.assetProxyId === AssetProxyId.MultiAsset) {
const recursivelyDecodedAssetData = assetDataUtils.decodeMultiAssetDataRecursively(
nestedAssetDataElement,
);
amounts.push(
_.map(recursivelyDecodedAssetData.amounts as BigNumber[], amountElement =>
amountElement.times(decodedAssetData.amounts[index]),
),
);
return recursivelyDecodedAssetData.nestedAssetData;
} else {
amounts.push(decodedAssetData.amounts[index]);
return decodedNestedAssetDataElement as SingleAssetData;
}
},
);
const flattenedAmounts = _.flattenDeep(amounts);
const flattenedDecodedNestedAssetData = _.flattenDeep(decodedNestedAssetData);
return {
assetProxyId: decodedAssetData.assetProxyId,
amounts: decodedAssetData.amounts,
amounts: flattenedAmounts,
nestedAssetData: flattenedDecodedNestedAssetData as SingleAssetData[],
};
},

View File

@ -3,6 +3,7 @@ import { BigNumber } from '@0x/utils';
export const constants = {
NULL_ADDRESS: '0x0000000000000000000000000000000000000000',
NULL_BYTES: '0x',
NULL_ERC20_ASSET_DATA: '0xf47261b00000000000000000000000000000000000000000000000000000000000000000',
// tslint:disable-next-line:custom-no-magic-numbers
UNLIMITED_ALLOWANCE_IN_BASE_UNITS: new BigNumber(2).pow(256).minus(1),
TESTRPC_NETWORK_ID: 50,

View File

@ -1,6 +1,6 @@
import * as chai from 'chai';
import { AssetProxyId } from '@0x/types';
import { AssetProxyId, ERC721AssetData } from '@0x/types';
import { BigNumber } from '@0x/utils';
import { assetDataUtils } from '../src/asset_data_utils';
@ -63,4 +63,45 @@ describe('assetDataUtils', () => {
expect(decodedAssetData.amounts).to.deep.equal(KNOWN_MULTI_ASSET_ENCODING.amounts);
expect(decodedAssetData.nestedAssetData).to.deep.equal(KNOWN_MULTI_ASSET_ENCODING.nestedAssetData);
});
it('should recursively decode ERC20 and ERC721 multiAssetData', () => {
const decodedAssetData = assetDataUtils.decodeMultiAssetDataRecursively(KNOWN_MULTI_ASSET_ENCODING.assetData);
expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.MultiAsset);
expect(decodedAssetData.amounts).to.deep.equal(KNOWN_MULTI_ASSET_ENCODING.amounts);
const decodedErc20AssetData = decodedAssetData.nestedAssetData[0];
const decodedErc721AssetData = decodedAssetData.nestedAssetData[1] as ERC721AssetData;
expect(decodedErc20AssetData.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address);
expect(decodedErc20AssetData.assetProxyId).to.equal(AssetProxyId.ERC20);
expect(decodedErc721AssetData.tokenAddress).to.equal(KNOWN_ERC721_ENCODING.address);
expect(decodedErc721AssetData.assetProxyId).to.equal(AssetProxyId.ERC721);
expect(decodedErc721AssetData.tokenId).to.be.bignumber.equal(KNOWN_ERC721_ENCODING.tokenId);
});
it('should recursively decode nested assetData within multiAssetData', () => {
const amounts = [new BigNumber(1), new BigNumber(1), new BigNumber(2)];
const nestedAssetData = [
KNOWN_ERC20_ENCODING.assetData,
KNOWN_ERC721_ENCODING.assetData,
KNOWN_MULTI_ASSET_ENCODING.assetData,
];
const assetData = assetDataUtils.encodeMultiAssetData(amounts, nestedAssetData);
const decodedAssetData = assetDataUtils.decodeMultiAssetDataRecursively(assetData);
expect(decodedAssetData.assetProxyId).to.equal(AssetProxyId.MultiAsset);
const expectedAmounts = [new BigNumber(1), new BigNumber(1), new BigNumber(2), new BigNumber(2)];
expect(decodedAssetData.amounts).to.deep.equal(expectedAmounts);
const expectedLength = 4;
expect(decodedAssetData.nestedAssetData.length).to.be.equal(expectedLength);
const decodedErc20AssetData1 = decodedAssetData.nestedAssetData[0];
const decodedErc721AssetData1 = decodedAssetData.nestedAssetData[1] as ERC721AssetData;
const decodedErc20AssetData2 = decodedAssetData.nestedAssetData[2];
const decodedErc721AssetData2 = decodedAssetData.nestedAssetData[3] as ERC721AssetData;
expect(decodedErc20AssetData1.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address);
expect(decodedErc20AssetData1.assetProxyId).to.equal(AssetProxyId.ERC20);
expect(decodedErc721AssetData1.tokenAddress).to.equal(KNOWN_ERC721_ENCODING.address);
expect(decodedErc721AssetData1.assetProxyId).to.equal(AssetProxyId.ERC721);
expect(decodedErc721AssetData1.tokenId).to.be.bignumber.equal(KNOWN_ERC721_ENCODING.tokenId);
expect(decodedErc20AssetData2.tokenAddress).to.equal(KNOWN_ERC20_ENCODING.address);
expect(decodedErc20AssetData2.assetProxyId).to.equal(AssetProxyId.ERC20);
expect(decodedErc721AssetData2.tokenAddress).to.equal(KNOWN_ERC721_ENCODING.address);
expect(decodedErc721AssetData2.assetProxyId).to.equal(AssetProxyId.ERC721);
expect(decodedErc721AssetData2.tokenId).to.be.bignumber.equal(KNOWN_ERC721_ENCODING.tokenId);
});
});

View File

@ -7,9 +7,9 @@ import { orderFactory } from '../../src/order_factory';
const BASE_TEST_ORDER: Order = orderFactory.createOrder(
constants.NULL_ADDRESS,
constants.ZERO_AMOUNT,
constants.NULL_ADDRESS,
constants.NULL_ERC20_ASSET_DATA,
constants.ZERO_AMOUNT,
constants.NULL_ADDRESS,
constants.NULL_ERC20_ASSET_DATA,
constants.NULL_ADDRESS,
);
const BASE_TEST_SIGNED_ORDER: SignedOrder = {