@0x:contracts-integrations
Simplified the tests
This commit is contained in:
parent
03e35846fb
commit
e603a81a46
@ -1,64 +1,45 @@
|
|||||||
pragma solidity ^0.5.9;
|
pragma solidity ^0.5.9;
|
||||||
|
|
||||||
|
import "@0x/contracts-utils/contracts/src/LibRichErrors.sol";
|
||||||
|
|
||||||
|
|
||||||
|
// This contract is intended to be used in the unit tests that test the typescript
|
||||||
|
// test framework found in `test/utils/`
|
||||||
contract TestFramework {
|
contract TestFramework {
|
||||||
|
|
||||||
event SomeEvent(uint256 someNumber);
|
event Event(string input);
|
||||||
|
|
||||||
uint256 public counter;
|
// bytes4(keccak256("RichRevertErrorSelector(string)"))
|
||||||
|
bytes4 internal constant RICH_REVERT_ERROR_SELECTOR = 0x49a7e246;
|
||||||
|
|
||||||
function setCounter(uint256 newCounter)
|
function emitEvent(string calldata input)
|
||||||
external
|
external
|
||||||
{
|
{
|
||||||
counter = newCounter;
|
emit Event(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
function revertSideEffect(uint256 returnValue)
|
function emptyRevert()
|
||||||
external
|
external
|
||||||
returns (uint256)
|
|
||||||
{
|
{
|
||||||
if (counter != 0) {
|
revert();
|
||||||
revert("Revert");
|
|
||||||
}
|
|
||||||
|
|
||||||
emit SomeEvent(returnValue);
|
|
||||||
return returnValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function equalsSideEffect(uint256 possiblyZero)
|
function stringRevert(string calldata message)
|
||||||
external
|
external
|
||||||
view
|
|
||||||
returns (bool)
|
|
||||||
{
|
{
|
||||||
if (counter == 0) {
|
revert(message);
|
||||||
return possiblyZero == 0;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function noEffect(uint256)
|
function doNothing()
|
||||||
external
|
external
|
||||||
pure
|
pure
|
||||||
{} // solhint-disable-line no-empty-blocks
|
{} // solhint-disable-line no-empty-blocks
|
||||||
|
|
||||||
function numberSideEffect()
|
function returnInteger(uint256 integer)
|
||||||
external
|
external
|
||||||
view
|
pure
|
||||||
returns (uint256)
|
returns (uint256)
|
||||||
{
|
{
|
||||||
return counter;
|
return integer;
|
||||||
}
|
|
||||||
|
|
||||||
function hashSideEffect(uint256 arg1, bytes32 arg2)
|
|
||||||
external
|
|
||||||
view
|
|
||||||
returns (bytes32)
|
|
||||||
{
|
|
||||||
if (counter == 0) {
|
|
||||||
return keccak256(abi.encode(arg1, arg2));
|
|
||||||
} else {
|
|
||||||
return keccak256(hex"");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,75 +0,0 @@
|
|||||||
import { blockchainTests, expect } from '@0x/contracts-test-utils';
|
|
||||||
import { BigNumber } from '@0x/utils';
|
|
||||||
|
|
||||||
import { artifacts, TestFrameworkContract } from '../../src';
|
|
||||||
import { FunctionAssertion, Result } from '../utils/function_assertions';
|
|
||||||
|
|
||||||
// These tests provide examples for how to use the "FunctionAssertion" class to write
|
|
||||||
// tests for "payable" and "nonpayable" Solidity functions as well as "pure" and "view" functions.
|
|
||||||
blockchainTests('TestFramework', env => {
|
|
||||||
let exampleContract: TestFrameworkContract;
|
|
||||||
|
|
||||||
before(async () => {
|
|
||||||
exampleContract = await TestFrameworkContract.deployFrom0xArtifactAsync(
|
|
||||||
artifacts.TestFramework,
|
|
||||||
env.provider,
|
|
||||||
env.txDefaults,
|
|
||||||
artifacts,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('numberSideEffect', () => {
|
|
||||||
let assertion: FunctionAssertion;
|
|
||||||
|
|
||||||
before(async () => {
|
|
||||||
const condition = {
|
|
||||||
before: async () => {},
|
|
||||||
after: async (beforeInfo: any, result: Result) => {
|
|
||||||
// Ensure that the call was successful.
|
|
||||||
expect(result.success).to.be.true();
|
|
||||||
|
|
||||||
// Ensure that the correct counter was returned.
|
|
||||||
const counter = await exampleContract.counter.callAsync();
|
|
||||||
expect(result.data).bignumber.to.be.eq(counter);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
assertion = new FunctionAssertion(exampleContract.numberSideEffect, condition);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return the correct counter', async () => {
|
|
||||||
await assertion.runAsync();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return the correct counter', async () => {
|
|
||||||
await exampleContract.setCounter.awaitTransactionSuccessAsync(new BigNumber(2));
|
|
||||||
await assertion.runAsync();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('setCounter', () => {
|
|
||||||
let assertion: FunctionAssertion;
|
|
||||||
|
|
||||||
before(async () => {
|
|
||||||
const condition = {
|
|
||||||
before: async (expectedCounter: BigNumber) => {},
|
|
||||||
after: async (beforeInfo: any, result: Result, expectedCounter: BigNumber) => {
|
|
||||||
// Ensure that the call was successful.
|
|
||||||
expect(result.success).to.be.true();
|
|
||||||
|
|
||||||
// Ensure that the counter was updated correctly.
|
|
||||||
const counter = await exampleContract.counter.callAsync();
|
|
||||||
expect(counter).bignumber.to.be.eq(expectedCounter);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
assertion = new FunctionAssertion(exampleContract.setCounter, condition);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should correctly set counter to 1', async () => {
|
|
||||||
await assertion.runAsync(new BigNumber(1));
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should correctly set counter to 1500', async () => {
|
|
||||||
await assertion.runAsync(new BigNumber(1500));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -6,10 +6,10 @@ import {
|
|||||||
getRandomInteger,
|
getRandomInteger,
|
||||||
hexRandom,
|
hexRandom,
|
||||||
} from '@0x/contracts-test-utils';
|
} from '@0x/contracts-test-utils';
|
||||||
import { BigNumber } from '@0x/utils';
|
import { BigNumber, StringRevertError } from '@0x/utils';
|
||||||
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
||||||
|
|
||||||
import { artifacts, TestFrameworkContract, TestFrameworkSomeEventEventArgs, TestFrameworkEvents } from '../../src';
|
import { artifacts, TestFrameworkContract, TestFrameworkEventEventArgs, TestFrameworkEvents } from '../../src';
|
||||||
import { FunctionAssertion, Result } from '../utils/function_assertions';
|
import { FunctionAssertion, Result } from '../utils/function_assertions';
|
||||||
|
|
||||||
const ZERO = constants.ZERO_AMOUNT;
|
const ZERO = constants.ZERO_AMOUNT;
|
||||||
@ -30,13 +30,12 @@ blockchainTests.resets('FunctionAssertion Unit Tests', env => {
|
|||||||
describe('runAsync', () => {
|
describe('runAsync', () => {
|
||||||
it('should call the before function with the provided arguments', async () => {
|
it('should call the before function with the provided arguments', async () => {
|
||||||
let sideEffectTarget = ZERO;
|
let sideEffectTarget = ZERO;
|
||||||
const assertion = new FunctionAssertion(exampleContract.noEffect, {
|
const assertion = new FunctionAssertion(exampleContract.returnInteger, {
|
||||||
before: async (inputValue: BigNumber) => {
|
before: async (input: BigNumber) => {
|
||||||
sideEffectTarget = inputValue;
|
sideEffectTarget = randomInput;
|
||||||
},
|
},
|
||||||
after: async (beforeInfo: any, result: Result, returnValue: BigNumber) => {},
|
after: async (beforeInfo: any, result: Result, input: BigNumber) => {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const randomInput = getRandomInteger(ZERO, MAX_UINT256);
|
const randomInput = getRandomInteger(ZERO, MAX_UINT256);
|
||||||
await assertion.runAsync(randomInput);
|
await assertion.runAsync(randomInput);
|
||||||
expect(sideEffectTarget).bignumber.to.be.eq(randomInput);
|
expect(sideEffectTarget).bignumber.to.be.eq(randomInput);
|
||||||
@ -44,36 +43,33 @@ blockchainTests.resets('FunctionAssertion Unit Tests', env => {
|
|||||||
|
|
||||||
it('should call the after function with the provided arguments', async () => {
|
it('should call the after function with the provided arguments', async () => {
|
||||||
let sideEffectTarget = ZERO;
|
let sideEffectTarget = ZERO;
|
||||||
const assertion = new FunctionAssertion(exampleContract.noEffect, {
|
const assertion = new FunctionAssertion(exampleContract.returnInteger, {
|
||||||
before: async (inputValue: BigNumber) => {},
|
before: async (input: BigNumber) => {},
|
||||||
after: async (beforeInfo: any, result: Result, returnValue: BigNumber) => {
|
after: async (beforeInfo: any, result: Result, input: BigNumber) => {
|
||||||
sideEffectTarget = returnValue;
|
sideEffectTarget = input;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const randomInput = getRandomInteger(ZERO, MAX_UINT256);
|
const randomInput = getRandomInteger(ZERO, MAX_UINT256);
|
||||||
await assertion.runAsync(randomInput);
|
await assertion.runAsync(randomInput);
|
||||||
expect(sideEffectTarget).bignumber.to.be.eq(randomInput);
|
expect(sideEffectTarget).bignumber.to.be.eq(randomInput);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not fail immediately if the wrapped function fails', async () => {
|
it('should not fail immediately if the wrapped function fails', async () => {
|
||||||
await exampleContract.setCounter.awaitTransactionSuccessAsync(new BigNumber(1));
|
const assertion = new FunctionAssertion(exampleContract.emptyRevert, {
|
||||||
const assertion = new FunctionAssertion(exampleContract.revertSideEffect, {
|
before: async () => {},
|
||||||
before: async (inputValue: BigNumber) => {},
|
after: async (beforeInfo: any, result: Result) => {},
|
||||||
after: async (beforeInfo: any, result: Result, returnValue: BigNumber) => {},
|
|
||||||
});
|
});
|
||||||
const randomInput = getRandomInteger(ZERO, MAX_UINT256);
|
await assertion.runAsync();
|
||||||
await assertion.runAsync(randomInput);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should pass the return value from "before" to "after"', async () => {
|
it('should pass the return value of "before" to "after"', async () => {
|
||||||
const randomInput = getRandomInteger(ZERO, MAX_UINT256);
|
const randomInput = getRandomInteger(ZERO, MAX_UINT256);
|
||||||
let sideEffectTarget = constants.ZERO_AMOUNT;
|
let sideEffectTarget = constants.ZERO_AMOUNT;
|
||||||
const assertion = new FunctionAssertion(exampleContract.noEffect, {
|
const assertion = new FunctionAssertion(exampleContract.returnInteger, {
|
||||||
before: async (inputValue: BigNumber) => {
|
before: async (input: BigNumber) => {
|
||||||
return randomInput;
|
return randomInput;
|
||||||
},
|
},
|
||||||
after: async (beforeInfo: any, result: Result, returnValue: BigNumber) => {
|
after: async (beforeInfo: any, result: Result, input: BigNumber) => {
|
||||||
sideEffectTarget = beforeInfo;
|
sideEffectTarget = beforeInfo;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -83,9 +79,9 @@ blockchainTests.resets('FunctionAssertion Unit Tests', env => {
|
|||||||
|
|
||||||
it('should pass the result from the function call to "after"', async () => {
|
it('should pass the result from the function call to "after"', async () => {
|
||||||
let sideEffectTarget = constants.ZERO_AMOUNT;
|
let sideEffectTarget = constants.ZERO_AMOUNT;
|
||||||
const assertion = new FunctionAssertion(exampleContract.revertSideEffect, {
|
const assertion = new FunctionAssertion(exampleContract.returnInteger, {
|
||||||
before: async (inputValue: BigNumber) => {},
|
before: async (input: BigNumber) => {},
|
||||||
after: async (beforeInfo: any, result: Result, returnValue: BigNumber) => {
|
after: async (beforeInfo: any, result: Result, input: BigNumber) => {
|
||||||
sideEffectTarget = result.data;
|
sideEffectTarget = result.data;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -96,40 +92,43 @@ blockchainTests.resets('FunctionAssertion Unit Tests', env => {
|
|||||||
|
|
||||||
it('should pass the receipt from the function call to "after"', async () => {
|
it('should pass the receipt from the function call to "after"', async () => {
|
||||||
let sideEffectTarget = {} as TransactionReceiptWithDecodedLogs;
|
let sideEffectTarget = {} as TransactionReceiptWithDecodedLogs;
|
||||||
const assertion = new FunctionAssertion(exampleContract.revertSideEffect, {
|
const assertion = new FunctionAssertion(exampleContract.emitEvent, {
|
||||||
before: async (inputValue: BigNumber) => {},
|
before: async (input: string) => {},
|
||||||
after: async (beforeInfo: any, result: Result, returnValue: BigNumber) => {
|
after: async (beforeInfo: any, result: Result, input: string) => {
|
||||||
if (result.receipt) {
|
if (result.receipt) {
|
||||||
sideEffectTarget = result.receipt;
|
sideEffectTarget = result.receipt;
|
||||||
} else {
|
|
||||||
throw new Error('No receipt received.');
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const randomInput = getRandomInteger(ZERO, MAX_UINT256);
|
|
||||||
await assertion.runAsync(randomInput);
|
const input = 'emitted data';
|
||||||
|
await assertion.runAsync(input);
|
||||||
|
|
||||||
// Ensure that the correct events were emitted.
|
// Ensure that the correct events were emitted.
|
||||||
const [event] = filterLogsToArguments<TestFrameworkSomeEventEventArgs>(
|
const [event] = filterLogsToArguments<TestFrameworkEventEventArgs>(
|
||||||
sideEffectTarget.logs,
|
sideEffectTarget.logs,
|
||||||
TestFrameworkEvents.SomeEvent,
|
TestFrameworkEvents.Event,
|
||||||
);
|
);
|
||||||
expect(event).to.be.deep.eq({ someNumber: randomInput });
|
expect(event).to.be.deep.eq({ input });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should pass the error to "after" if the function call fails', async () => {
|
it('should pass the error to "after" if the function call fails', async () => {
|
||||||
let sideEffectTarget: Error = new Error('');
|
let sideEffectTarget: Error;
|
||||||
await exampleContract.setCounter.awaitTransactionSuccessAsync(new BigNumber(1));
|
const assertion = new FunctionAssertion(exampleContract.stringRevert, {
|
||||||
const assertion = new FunctionAssertion(exampleContract.revertSideEffect, {
|
before: async string => {},
|
||||||
before: async (inputValue: BigNumber) => {},
|
after: async (any, result: Result, string) => {
|
||||||
after: async (beforeInfo: any, result: Result, returnValue: BigNumber) => {
|
|
||||||
sideEffectTarget = result.data;
|
sideEffectTarget = result.data;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const randomInput = getRandomInteger(ZERO, MAX_UINT256);
|
const message = 'error message';
|
||||||
await assertion.runAsync(randomInput);
|
await assertion.runAsync(message);
|
||||||
const errorMessage = 'VM Exception while processing transaction: revert Revert';
|
|
||||||
expect(sideEffectTarget.message).to.be.eq(errorMessage);
|
const expectedError = new StringRevertError(message);
|
||||||
|
return expect(
|
||||||
|
new Promise((resolve, reject) => {
|
||||||
|
reject(sideEffectTarget);
|
||||||
|
}),
|
||||||
|
).to.revertWith(expectedError);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -3,7 +3,6 @@ import { TransactionReceiptWithDecodedLogs } from 'ethereum-types';
|
|||||||
|
|
||||||
export interface ContractGetterFunction {
|
export interface ContractGetterFunction {
|
||||||
callAsync: (...args: any[]) => Promise<any>;
|
callAsync: (...args: any[]) => Promise<any>;
|
||||||
getABIEncodedTransactionData: (...args: any[]) => string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ContractWrapperFunction extends ContractGetterFunction {
|
export interface ContractWrapperFunction extends ContractGetterFunction {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user