diff --git a/contracts/integrations/test/examples/simple.ts b/contracts/integrations/test/examples/simple.ts index 043e7c54aa..23f68f08b4 100644 --- a/contracts/integrations/test/examples/simple.ts +++ b/contracts/integrations/test/examples/simple.ts @@ -1,4 +1,4 @@ -/*import { blockchainTests, expect } from '@0x/contracts-test-utils'; +import { blockchainTests, expect } from '@0x/contracts-test-utils'; import { BigNumber } from '@0x/utils'; import { artifacts, TestFrameworkContract } from '../../src'; @@ -73,4 +73,3 @@ blockchainTests('TestFramework', env => { }); }); }); -*/ diff --git a/contracts/integrations/test/framework-unit-tests/function_assertion_test.ts b/contracts/integrations/test/framework-unit-tests/function_assertion_test.ts index d7b81ec758..07cc7d32c5 100644 --- a/contracts/integrations/test/framework-unit-tests/function_assertion_test.ts +++ b/contracts/integrations/test/framework-unit-tests/function_assertion_test.ts @@ -1,10 +1,20 @@ -/*import { blockchainTests, constants, expect, filterLogsToArguments, hexRandom } from '@0x/contracts-test-utils'; -import { BigNumber, generatePseudoRandom256BitNumber } from '@0x/utils'; +import { + blockchainTests, + constants, + expect, + filterLogsToArguments, + getRandomInteger, + hexRandom, +} from '@0x/contracts-test-utils'; +import { BigNumber } from '@0x/utils'; import { TransactionReceiptWithDecodedLogs } from 'ethereum-types'; import { artifacts, TestFrameworkContract, TestFrameworkSomeEventEventArgs, TestFrameworkEvents } from '../../src'; import { FunctionAssertion, Result } from '../utils/function_assertions'; +const ZERO = constants.ZERO_AMOUNT; +const MAX_UINT256 = constants.MAX_UINT256; + blockchainTests.resets('FunctionAssertion Unit Tests', env => { let exampleContract: TestFrameworkContract; @@ -19,7 +29,7 @@ blockchainTests.resets('FunctionAssertion Unit Tests', env => { describe('runAsync', () => { it('should call the before function with the provided arguments', async () => { - let sideEffectTarget = constants.ZERO_AMOUNT; + let sideEffectTarget = ZERO; const assertion = new FunctionAssertion(exampleContract.noEffect, { before: async (inputValue: BigNumber) => { sideEffectTarget = inputValue; @@ -27,13 +37,13 @@ blockchainTests.resets('FunctionAssertion Unit Tests', env => { after: async (beforeInfo: any, result: Result, returnValue: BigNumber) => {}, }); - const randomInput = generatePseudoRandom256BitNumber(); + const randomInput = getRandomInteger(ZERO, MAX_UINT256); await assertion.runAsync(randomInput); expect(sideEffectTarget).bignumber.to.be.eq(randomInput); }); it('should call the after function with the provided arguments', async () => { - let sideEffectTarget = constants.ZERO_AMOUNT; + let sideEffectTarget = ZERO; const assertion = new FunctionAssertion(exampleContract.noEffect, { before: async (inputValue: BigNumber) => {}, after: async (beforeInfo: any, result: Result, returnValue: BigNumber) => { @@ -41,7 +51,7 @@ blockchainTests.resets('FunctionAssertion Unit Tests', env => { }, }); - const randomInput = generatePseudoRandom256BitNumber(); + const randomInput = getRandomInteger(ZERO, MAX_UINT256); await assertion.runAsync(randomInput); expect(sideEffectTarget).bignumber.to.be.eq(randomInput); }); @@ -52,12 +62,12 @@ blockchainTests.resets('FunctionAssertion Unit Tests', env => { before: async (inputValue: BigNumber) => {}, after: async (beforeInfo: any, result: Result, returnValue: BigNumber) => {}, }); - const randomInput = generatePseudoRandom256BitNumber(); + const randomInput = getRandomInteger(ZERO, MAX_UINT256); await assertion.runAsync(randomInput); }); it('should pass the return value from "before" to "after"', async () => { - const randomInput = generatePseudoRandom256BitNumber(); + const randomInput = getRandomInteger(ZERO, MAX_UINT256); let sideEffectTarget = constants.ZERO_AMOUNT; const assertion = new FunctionAssertion(exampleContract.noEffect, { before: async (inputValue: BigNumber) => { @@ -79,13 +89,13 @@ blockchainTests.resets('FunctionAssertion Unit Tests', env => { sideEffectTarget = result.data; }, }); - const randomInput = generatePseudoRandom256BitNumber(); + const randomInput = getRandomInteger(ZERO, MAX_UINT256); await assertion.runAsync(randomInput); expect(sideEffectTarget).bignumber.to.be.eq(randomInput); }); it('should pass the receipt from the function call to "after"', async () => { - let sideEffectTarget: TransactionReceiptWithDecodedLogs = {} as TransactionReceiptWithDecodedLogs; + let sideEffectTarget = {} as TransactionReceiptWithDecodedLogs; const assertion = new FunctionAssertion(exampleContract.revertSideEffect, { before: async (inputValue: BigNumber) => {}, after: async (beforeInfo: any, result: Result, returnValue: BigNumber) => { @@ -96,7 +106,7 @@ blockchainTests.resets('FunctionAssertion Unit Tests', env => { } }, }); - const randomInput = generatePseudoRandom256BitNumber(); + const randomInput = getRandomInteger(ZERO, MAX_UINT256); await assertion.runAsync(randomInput); // Ensure that the correct events were emitted. @@ -116,11 +126,10 @@ blockchainTests.resets('FunctionAssertion Unit Tests', env => { sideEffectTarget = result.data; }, }); - const randomInput = generatePseudoRandom256BitNumber(); + const randomInput = getRandomInteger(ZERO, MAX_UINT256); await assertion.runAsync(randomInput); const errorMessage = 'VM Exception while processing transaction: revert Revert'; expect(sideEffectTarget.message).to.be.eq(errorMessage); }); }); }); -*/ diff --git a/contracts/integrations/test/framework-unit-tests/getter_cache_test.ts b/contracts/integrations/test/framework-unit-tests/getter_cache_test.ts deleted file mode 100644 index a8c97a8333..0000000000 --- a/contracts/integrations/test/framework-unit-tests/getter_cache_test.ts +++ /dev/null @@ -1,155 +0,0 @@ -import { blockchainTests, constants, expect, hexSlice } from '@0x/contracts-test-utils'; -import { BigNumber } from '@0x/utils'; -import { BlockParam, CallData } from 'ethereum-types'; -import * as ethUtil from 'ethereumjs-util'; - -import { artifacts, TestFrameworkContract } from '../../src'; -import { GetterCache } from '../utils/cache'; - -blockchainTests.resets('Cache Tests', env => { - let exampleContract: TestFrameworkContract; - - before(async () => { - exampleContract = await TestFrameworkContract.deployFrom0xArtifactAsync( - artifacts.TestFramework, - env.provider, - env.txDefaults, - artifacts, - ); - }); - - describe('callAsync', () => { - describe('() => uint', () => { - let cache: GetterCache; - - beforeEach(async () => { - cache = new GetterCache(exampleContract.numberSideEffect); - }); - - it('should return 0 when "counter" == 0', async () => { - expect(await cache.callAsync()).bignumber.to.be.eq(constants.ZERO_AMOUNT); - }); - - it('should return 1 when "counter" == 1', async () => { - // Update the counter to 1. - await exampleContract.setCounter.awaitTransactionSuccessAsync(new BigNumber(1)); - - // Ensure that the returned value is the updated counter. - expect(await cache.callAsync()).bignumber.to.be.eq(new BigNumber(1)); - }); - - it('should return the cached counter', async () => { - // Cache a value. - expect(await cache.callAsync()).bignumber.to.be.eq(constants.ZERO_AMOUNT); - - // Update the counter to 1. - await exampleContract.setCounter.awaitTransactionSuccessAsync(new BigNumber(1)); - - // This should return "0" because a value was cached by the first call to "callAsync" - expect(await cache.callAsync()).bignumber.to.be.eq(constants.ZERO_AMOUNT); - }); - }); - - describe('uint => boolean', () => { - let cache: GetterCache; - - beforeEach(async () => { - cache = new GetterCache(exampleContract.equalsSideEffect); - }); - - it('should return true when "possiblyZero" == 0 && "counter" == 0', async () => { - expect(await cache.callAsync(constants.ZERO_AMOUNT)).to.be.true(); - }); - - it('should return false when "possiblyZero" == 0 && "counter" != 0', async () => { - // Update "counter" to "1", which will cause all calls to return false. - await exampleContract.setCounter.awaitTransactionSuccessAsync(new BigNumber(1)); - expect(await cache.callAsync(constants.ZERO_AMOUNT)).to.be.false(); - }); - - it('should return the cached value', async () => { - // Cache a "true" value when "possiblyZero" == 0 && "counter" == 0 - expect(await cache.callAsync(constants.ZERO_AMOUNT)).to.be.true(); - - // Update "counter" to "1", which will cause all calls of "isZeroOrFalse" to return "false". - await exampleContract.setCounter.awaitTransactionSuccessAsync(new BigNumber(1)); - - // This should return "true" because a value was by the first call to "callAsync" - expect(await cache.callAsync(constants.ZERO_AMOUNT)).to.be.true(); - }); - }); - - describe('(uint, bytes32) => bytes32', () => { - let cache: GetterCache; - - beforeEach(async () => { - cache = new GetterCache(exampleContract.hashSideEffect); - }); - - it('should return correct hash when counter == 0', async () => { - // Get the calldata for the function call, which includes the abi-encoded data to hash. - const hashData = exampleContract.hashSideEffect.getABIEncodedTransactionData( - new BigNumber(1), - ethUtil.bufferToHex(ethUtil.sha3(0)), - ); - - // Ensure that the correct hash was returned from the cache. - expect(await cache.callAsync(new BigNumber(1), ethUtil.bufferToHex(ethUtil.sha3(0)))).to.be.eq( - ethUtil.bufferToHex(ethUtil.sha3(hexSlice(hashData, 4))), - ); - }); - - it('should return the null hash when counter != 0', async () => { - // Update "counter" to "1", which will cause all calls to return the null hash. - await exampleContract.setCounter.awaitTransactionSuccessAsync(new BigNumber(1)); - - // Ensure that the cache returns the correct value. - expect(await cache.callAsync(new BigNumber(1), ethUtil.bufferToHex(ethUtil.sha3(0)))).to.be.eq( - ethUtil.bufferToHex(ethUtil.sha3('0x')), - ); - }); - - it('should return the cached hash', async () => { - // Get the calldata for the function call, which includes the abi-encoded data to hash. - const hashData = exampleContract.hashSideEffect.getABIEncodedTransactionData( - new BigNumber(1), - ethUtil.bufferToHex(ethUtil.sha3(0)), - ); - const hash = ethUtil.bufferToHex(ethUtil.sha3(hexSlice(hashData, 4))); - - // Ensure that the cache returns the correct value. - expect(await cache.callAsync(new BigNumber(1), ethUtil.bufferToHex(ethUtil.sha3(0)))).to.be.eq(hash); - - // Update "counter" to "1", which will cause all calls to return the null hash. - await exampleContract.setCounter.awaitTransactionSuccessAsync(new BigNumber(1)); - - // The cache should return the same value as the first call to `callAsync` since a value was cached. - expect(await cache.callAsync(new BigNumber(1), ethUtil.bufferToHex(ethUtil.sha3(0)))).to.be.eq(hash); - }); - }); - }); - - describe('flush', () => { - describe('uint => boolean', () => { - let cache: GetterCache; - - beforeEach(async () => { - cache = new GetterCache(exampleContract.equalsSideEffect); - }); - - it('should return false when the cache was flushed && "possiblyZero" == 0 && "counter" != 0', async () => { - // Cache a "true" value when "possiblyZero" == 0 && "counter" == 0 - expect(await cache.callAsync(constants.ZERO_AMOUNT)).to.be.true(); - - // Update "counter" to "1", which will cause all calls of "isZeroOrFalse" to return "false". - await exampleContract.setCounter.awaitTransactionSuccessAsync(new BigNumber(1)); - - // Flush the entire cache. - cache.flush(); - - // This should return "false" because the value was flushed. - expect(await cache.callAsync(constants.ZERO_AMOUNT)).to.be.false(); - }); - }); - }); -}); diff --git a/contracts/integrations/test/utils/cache.ts b/contracts/integrations/test/utils/cache.ts deleted file mode 100644 index 2fcefff9ca..0000000000 --- a/contracts/integrations/test/utils/cache.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { ContractGetterFunction } from './function_assertions'; -import * as _ from 'lodash'; - -export class GetterCache { - // The getter function whose values will be cached. - public getter: ContractGetterFunction; - - // The cache that will be used to store values. This has to use a "string" for indexing - // because the "Map" datastructure uses reference equality when the keys are objects, - // which was unsuitable for our purposes. - private cache: { - [key: string]: any; - }; - - constructor(getter: ContractGetterFunction) { - this.getter = getter; - this.cache = {}; - } - - /** - * Calls the contract getter and caches the result if there is not a cached value. Otherwise, - * this returns the cached value. - * @param ...args A variadic list of args to use when calling "callAsync". Due - * to the fact that we need to serialize the arguments to "callAsync" these - * arguments must be valid arguments to "getABIEncodedTransactionData". - * @return Either a cached value or the queried value. - */ - public async callAsync(...args: TCallArgs): Promise { - const key = this.getter.getABIEncodedTransactionData(...args); - const cachedResult = this.cache[key]; - - if (cachedResult !== undefined) { - return cachedResult; - } else { - const result = await this.getter.callAsync(...args); - this.cache[key] = result; - return result; - } - } - - /** - * Flushes the entire cache so that future calls to "callAsync" call the contract getter. - */ - public flush(): void { - this.cache = {}; - } -} - -export interface GetterCacheSet { - [getter: string]: GetterCache; -} - -export class GetterCacheCollection { - // A dictionary of getter cache's that allow the user of the collection to reference - // the getter functions by name. - public getters: GetterCacheSet; - - /** - * Constructs a getter collection with pre-seeded getter names and getters. - * @param getterNames The names of the getter functions to register. - * @param getters The getter functions to register. - */ - constructor(getters: GetterCacheSet) { - this.getters = getters; - } - - /** - * Registers a new getter in the collection. - * @param getterName The name of the contract getter function. - * @param getter The actual contract getter function. - */ - public registerGetter(getterName: string, getter: ContractGetterFunction): void { - this.getters[getterName] = new GetterCache(getter); - } - - /** - * Flushes all of the registered caches. - */ - public flushAll(): void { - for (const getter of Object.keys(this.getters)) { - this.getters[getter].flush(); - } - } -} diff --git a/contracts/integrations/test/utils/function_assertions.ts b/contracts/integrations/test/utils/function_assertions.ts index 98b6142fa6..85652dcf81 100644 --- a/contracts/integrations/test/utils/function_assertions.ts +++ b/contracts/integrations/test/utils/function_assertions.ts @@ -1,16 +1,13 @@ import { PromiseWithTransactionHash } from '@0x/base-contract'; import { TransactionReceiptWithDecodedLogs } from 'ethereum-types'; -export interface ContractGetterFunction { - callAsync: (...args: TCallArgs) => Promise; - getABIEncodedTransactionData: (...args: TCallArgs) => string; +export interface ContractGetterFunction { + callAsync: (...args: any[]) => Promise; + getABIEncodedTransactionData: (...args: any[]) => string; } -export interface ContractWrapperFunction - extends ContractGetterFunction { - awaitTransactionSuccessAsync?: ( - ...args: TAwaitArgs - ) => PromiseWithTransactionHash; +export interface ContractWrapperFunction extends ContractGetterFunction { + awaitTransactionSuccessAsync?: (...args: any[]) => PromiseWithTransactionHash; } export interface Condition { @@ -18,14 +15,14 @@ export interface Condition { after: (beforeInfo: any, result: Result, ...args: any[]) => Promise; } -export class FunctionAssertion { +export class FunctionAssertion { // A before and an after assertion that will be called around the wrapper function. public condition: Condition; // The wrapper function that will be wrapped in assertions. - public wrapperFunction: ContractWrapperFunction; + public wrapperFunction: ContractWrapperFunction; - constructor(wrapperFunction: ContractWrapperFunction, condition: Condition) { + constructor(wrapperFunction: ContractWrapperFunction, condition: Condition) { this.condition = condition; this.wrapperFunction = wrapperFunction; } @@ -34,7 +31,7 @@ export class FunctionAssertion { + public async runAsync(...args: any[]): Promise<{ beforeInfo: any; afterInfo: any }> { // Call the before condition. const beforeInfo = await this.condition.before(...args);