Unit tests

This commit is contained in:
Michael Zhu 2019-11-18 14:13:42 -08:00
parent 49e898b189
commit d51bbb0008
6 changed files with 245 additions and 3 deletions

View File

@ -0,0 +1,63 @@
/*
Copyright 2019 ZeroEx Intl.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;
import "../src/MixinExchangeWrapper.sol";
import "../src/libs/LibConstants.sol";
contract TestForwarder is
LibConstants,
MixinExchangeWrapper
{
// solhint-disable no-empty-blocks
constructor ()
public
LibConstants(
address(0),
address(0)
)
{}
function isPercentageFee(
bytes memory takerFeeAssetData,
bytes memory makerAssetData
)
public
returns (bool)
{
return _isPercentageFee(
takerFeeAssetData,
makerAssetData
);
}
function transferAssetToSender(
bytes memory assetData,
uint256 amount
)
public
{
_transferAssetToSender(
assetData,
amount
);
}
}

View File

@ -14,11 +14,12 @@
"build:ts": "tsc -b",
"build:ci": "yarn build",
"pre_build": "run-s compile contracts:gen generate_contract_wrappers contracts:copy",
"test": "echo !!! Tests have been relocated to @0x/contracts-integrations !!!",
"test": "yarn run_mocha",
"rebuild_and_test": "run-s build test",
"test:coverage": "SOLIDITY_COVERAGE=true run-s build run_mocha coverage:report:text coverage:report:lcov",
"test:profiler": "SOLIDITY_PROFILER=true run-s build run_mocha profiler:report:html",
"test:trace": "SOLIDITY_REVERT_TRACE=true run-s build run_mocha",
"run_mocha": "mocha --require source-map-support/register --require make-promises-safe 'lib/test/**/*.js' --timeout 100000 --bail --exit",
"compile": "sol-compiler",
"watch": "sol-compiler -w",
"clean": "shx rm -rf lib test/generated-artifacts test/generated-wrappers generated-artifacts generated-wrappers",
@ -38,7 +39,7 @@
},
"config": {
"publicInterfaceContracts": "Forwarder",
"abis": "./test/generated-artifacts/@(Forwarder|IAssets|IForwarder|IForwarderCore|LibConstants|LibForwarderRichErrors|MixinAssets|MixinExchangeWrapper|MixinForwarderCore|MixinWeth).json",
"abis": "./test/generated-artifacts/@(Forwarder|IAssets|IForwarder|IForwarderCore|LibConstants|LibForwarderRichErrors|MixinAssets|MixinExchangeWrapper|MixinForwarderCore|MixinWeth|TestForwarder).json",
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
},
"repository": {

View File

@ -15,6 +15,7 @@ import * as MixinAssets from '../test/generated-artifacts/MixinAssets.json';
import * as MixinExchangeWrapper from '../test/generated-artifacts/MixinExchangeWrapper.json';
import * as MixinForwarderCore from '../test/generated-artifacts/MixinForwarderCore.json';
import * as MixinWeth from '../test/generated-artifacts/MixinWeth.json';
import * as TestForwarder from '../test/generated-artifacts/TestForwarder.json';
export const artifacts = {
Forwarder: Forwarder as ContractArtifact,
MixinAssets: MixinAssets as ContractArtifact,
@ -26,4 +27,5 @@ export const artifacts = {
IForwarderCore: IForwarderCore as ContractArtifact,
LibConstants: LibConstants as ContractArtifact,
LibForwarderRichErrors: LibForwarderRichErrors as ContractArtifact,
TestForwarder: TestForwarder as ContractArtifact,
};

View File

@ -0,0 +1,174 @@
import { IAssetDataContract } from '@0x/contracts-asset-proxy';
import {
artifacts as ERC20Artifacts,
DummyERC20TokenContract,
ERC20TokenEvents,
ERC20TokenTransferEventArgs,
} from '@0x/contracts-erc20';
import {
artifacts as ERC721Artifacts,
DummyERC721TokenContract,
ERC721TokenEvents,
ERC721TokenTransferEventArgs,
} from '@0x/contracts-erc721';
import {
blockchainTests,
constants,
expect,
getRandomInteger,
hexRandom,
hexSlice,
randomAddress,
verifyEventsFromLogs,
} from '@0x/contracts-test-utils';
import { BigNumber } from '@0x/utils';
import { ForwarderRevertErrors } from '../src';
import { artifacts } from './artifacts';
import { TestForwarderContract } from './wrappers';
blockchainTests('Supported asset type unit tests', env => {
let forwarder: TestForwarderContract;
let assetDataEncoder: IAssetDataContract;
let bridgeAddress: string;
let bridgeData: string;
let receiver: string;
let erc20Token: DummyERC20TokenContract;
let erc721Token: DummyERC721TokenContract;
let nftId: BigNumber;
let erc20AssetData: string;
let erc721AssetData: string;
let erc20BridgeAssetData: string;
before(async () => {
[receiver] = await env.getAccountAddressesAsync();
assetDataEncoder = new IAssetDataContract(constants.NULL_ADDRESS, env.provider);
forwarder = await TestForwarderContract.deployFrom0xArtifactAsync(
artifacts.TestForwarder,
env.provider,
env.txDefaults,
{ ...artifacts, ...ERC20Artifacts, ...ERC721Artifacts },
);
erc20Token = await DummyERC20TokenContract.deployFrom0xArtifactAsync(
ERC20Artifacts.DummyERC20Token,
env.provider,
env.txDefaults,
ERC20Artifacts,
constants.DUMMY_TOKEN_NAME,
constants.DUMMY_TOKEN_SYMBOL,
constants.DUMMY_TOKEN_DECIMALS,
constants.DUMMY_TOKEN_TOTAL_SUPPLY,
);
erc20AssetData = assetDataEncoder.ERC20Token(erc20Token.address).getABIEncodedTransactionData();
erc721Token = await DummyERC721TokenContract.deployFrom0xArtifactAsync(
ERC721Artifacts.DummyERC721Token,
env.provider,
env.txDefaults,
ERC721Artifacts,
constants.DUMMY_TOKEN_NAME,
constants.DUMMY_TOKEN_SYMBOL,
);
nftId = getRandomInteger(constants.ZERO_AMOUNT, constants.MAX_UINT256);
erc721AssetData = assetDataEncoder.ERC721Token(erc721Token.address, nftId).getABIEncodedTransactionData();
bridgeAddress = randomAddress();
bridgeData = hexRandom();
erc20BridgeAssetData = assetDataEncoder
.ERC20Bridge(erc20Token.address, bridgeAddress, bridgeData)
.getABIEncodedTransactionData();
});
describe('_isPercentageFee', () => {
it('returns true if takerFeeAssetData == makerAssetData are ERC20', async () => {
const result = await forwarder.isPercentageFee(erc20AssetData, erc20AssetData).callAsync();
expect(result).to.be.true();
});
it('returns true if makerAssetData is the ERC20Bridge equivalent of takerFeeAssetData', async () => {
const result = await forwarder.isPercentageFee(erc20AssetData, erc20BridgeAssetData).callAsync();
expect(result).to.be.true();
});
it('returns false if takerFeeAssetData != makerAssetData are ERC20', async () => {
const differentERC20AssetData = assetDataEncoder.ERC20Token(randomAddress()).getABIEncodedTransactionData();
const result = await forwarder.isPercentageFee(erc20AssetData, differentERC20AssetData).callAsync();
expect(result).to.be.false();
});
it('returns false if takerFeeAssetData is ERC20 and makerAssetData is ERC721', async () => {
const result = await forwarder.isPercentageFee(erc20AssetData, erc721AssetData).callAsync();
expect(result).to.be.false();
});
it('returns false if makerAssetData us ERC20Bridge, but for a different token than takerFeeAssetData', async () => {
const mismatchedErc20BridgeAssetData = assetDataEncoder
.ERC20Bridge(randomAddress(), bridgeAddress, bridgeData)
.getABIEncodedTransactionData();
const result = await forwarder.isPercentageFee(erc20AssetData, mismatchedErc20BridgeAssetData).callAsync();
expect(result).to.be.false();
});
it('returns false if takerFeeAssetData is not ERC20', async () => {
const result = await forwarder.isPercentageFee(erc721AssetData, erc721AssetData).callAsync();
expect(result).to.be.false();
});
});
describe('_transferAssetToSender', () => {
const TRANSFER_AMOUNT = new BigNumber(1);
before(async () => {
await erc20Token
.setBalance(forwarder.address, constants.INITIAL_ERC20_BALANCE)
.awaitTransactionSuccessAsync();
await erc721Token.mint(forwarder.address, nftId).awaitTransactionSuccessAsync();
});
it('transfers an ERC20 token given ERC20 assetData', async () => {
const txReceipt = await forwarder
.transferAssetToSender(erc20AssetData, TRANSFER_AMOUNT)
.awaitTransactionSuccessAsync({ from: receiver });
verifyEventsFromLogs<ERC20TokenTransferEventArgs>(
txReceipt.logs,
[{ _from: forwarder.address, _to: receiver, _value: TRANSFER_AMOUNT }],
ERC20TokenEvents.Transfer,
);
});
it('transfers an ERC721 token given ERC721 assetData and amount == 1', async () => {
const txReceipt = await forwarder
.transferAssetToSender(erc721AssetData, TRANSFER_AMOUNT)
.awaitTransactionSuccessAsync({ from: receiver });
verifyEventsFromLogs<ERC721TokenTransferEventArgs>(
txReceipt.logs,
[{ _from: forwarder.address, _to: receiver, _tokenId: nftId }],
ERC721TokenEvents.Transfer,
);
});
it('reverts if attempting to transfer an ERC721 token with amount != 1', async () => {
const invalidAmount = new BigNumber(2);
const tx = forwarder
.transferAssetToSender(erc721AssetData, invalidAmount)
.awaitTransactionSuccessAsync({ from: receiver });
const expectedError = new ForwarderRevertErrors.Erc721AmountMustEqualOneError(invalidAmount);
expect(tx).to.revertWith(expectedError);
});
it('transfers an ERC20 token given ERC20Bridge assetData', async () => {
const txReceipt = await forwarder
.transferAssetToSender(erc20BridgeAssetData, TRANSFER_AMOUNT)
.awaitTransactionSuccessAsync({ from: receiver });
verifyEventsFromLogs<ERC20TokenTransferEventArgs>(
txReceipt.logs,
[{ _from: forwarder.address, _to: receiver, _value: TRANSFER_AMOUNT }],
ERC20TokenEvents.Transfer,
);
});
it('reverts if assetData is unsupported', async () => {
const randomBytes = hexRandom();
const tx = forwarder
.transferAssetToSender(randomBytes, TRANSFER_AMOUNT)
.awaitTransactionSuccessAsync({ from: receiver });
const expectedError = new ForwarderRevertErrors.UnsupportedAssetProxyError(hexSlice(randomBytes, 0, 4));
expect(tx).to.revertWith(expectedError);
});
});
});

View File

@ -13,3 +13,4 @@ export * from '../test/generated-wrappers/mixin_assets';
export * from '../test/generated-wrappers/mixin_exchange_wrapper';
export * from '../test/generated-wrappers/mixin_forwarder_core';
export * from '../test/generated-wrappers/mixin_weth';
export * from '../test/generated-wrappers/test_forwarder';

View File

@ -13,7 +13,8 @@
"test/generated-artifacts/MixinAssets.json",
"test/generated-artifacts/MixinExchangeWrapper.json",
"test/generated-artifacts/MixinForwarderCore.json",
"test/generated-artifacts/MixinWeth.json"
"test/generated-artifacts/MixinWeth.json",
"test/generated-artifacts/TestForwarder.json"
],
"exclude": ["./deploy/solc/solc_bin"]
}