diff options
Diffstat (limited to 'packages/0x.js')
-rw-r--r-- | packages/0x.js/src/contract_wrappers/contract_wrapper.ts | 2 | ||||
-rw-r--r-- | packages/0x.js/test/ether_token_wrapper_test.ts | 103 | ||||
-rw-r--r-- | packages/0x.js/test/exchange_wrapper_test.ts | 52 | ||||
-rw-r--r-- | packages/0x.js/test/expiration_watcher_test.ts | 10 | ||||
-rw-r--r-- | packages/0x.js/test/order_state_watcher_test.ts | 47 | ||||
-rw-r--r-- | packages/0x.js/test/subscription_test.ts | 20 | ||||
-rw-r--r-- | packages/0x.js/test/token_wrapper_test.ts | 64 | ||||
-rw-r--r-- | packages/0x.js/test/utils/report_callback_errors.ts | 60 | ||||
-rw-r--r-- | packages/0x.js/tsconfig.json | 2 |
9 files changed, 203 insertions, 157 deletions
diff --git a/packages/0x.js/src/contract_wrappers/contract_wrapper.ts b/packages/0x.js/src/contract_wrappers/contract_wrapper.ts index d308d207e..9c4e5dfd3 100644 --- a/packages/0x.js/src/contract_wrappers/contract_wrapper.ts +++ b/packages/0x.js/src/contract_wrappers/contract_wrapper.ts @@ -87,7 +87,7 @@ export class ContractWrapper { } const filterToken = filterUtils.generateUUID(); this._filters[filterToken] = filter; - this._filterCallbacks[filterToken] = callback; + this._filterCallbacks[filterToken] = callback as EventCallback<ContractEventArgs>; return filterToken; } protected async _getLogsAsync<ArgsType extends ContractEventArgs>( diff --git a/packages/0x.js/test/ether_token_wrapper_test.ts b/packages/0x.js/test/ether_token_wrapper_test.ts index db7acc8e5..b810fc9f1 100644 --- a/packages/0x.js/test/ether_token_wrapper_test.ts +++ b/packages/0x.js/test/ether_token_wrapper_test.ts @@ -22,6 +22,7 @@ import { DoneCallback } from '../src/types'; import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; +import { reportNodeCallbackErrors } from './utils/report_callback_errors'; import { TokenUtils } from './utils/token_utils'; import { web3Factory } from './utils/web3_factory'; @@ -153,19 +154,19 @@ describe('EtherTokenWrapper', () => { // Source: https://github.com/mochajs/mocha/issues/2407 it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => { (async () => { - const callback = (err: Error, logEvent: DecodedLogEvent<TransferContractEventArgs>) => { - expect(err).to.be.null(); - expect(logEvent).to.not.be.undefined(); - expect(logEvent.isRemoved).to.be.false(); - expect(logEvent.log.logIndex).to.be.equal(0); - expect(logEvent.log.transactionIndex).to.be.equal(0); - expect(logEvent.log.blockNumber).to.be.a('number'); - const args = logEvent.log.args; - expect(args._from).to.be.equal(addressWithETH); - expect(args._to).to.be.equal(addressWithoutFunds); - expect(args._value).to.be.bignumber.equal(transferAmount); - done(); - }; + const callback = reportNodeCallbackErrors(done)( + (logEvent: DecodedLogEvent<TransferContractEventArgs>) => { + expect(logEvent).to.not.be.undefined(); + expect(logEvent.isRemoved).to.be.false(); + expect(logEvent.log.logIndex).to.be.equal(0); + expect(logEvent.log.transactionIndex).to.be.equal(0); + expect(logEvent.log.blockNumber).to.be.a('number'); + const args = logEvent.log.args; + expect(args._from).to.be.equal(addressWithETH); + expect(args._to).to.be.equal(addressWithoutFunds); + expect(args._value).to.be.bignumber.equal(transferAmount); + }, + ); await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH); zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callback); await zeroEx.token.transferAsync( @@ -178,16 +179,16 @@ describe('EtherTokenWrapper', () => { }); it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => { (async () => { - const callback = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { - expect(err).to.be.null(); - expect(logEvent).to.not.be.undefined(); - expect(logEvent.isRemoved).to.be.false(); - const args = logEvent.log.args; - expect(args._owner).to.be.equal(addressWithETH); - expect(args._spender).to.be.equal(addressWithoutFunds); - expect(args._value).to.be.bignumber.equal(allowanceAmount); - done(); - }; + const callback = reportNodeCallbackErrors(done)( + (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { + expect(logEvent).to.not.be.undefined(); + expect(logEvent.isRemoved).to.be.false(); + const args = logEvent.log.args; + expect(args._owner).to.be.equal(addressWithETH); + expect(args._spender).to.be.equal(addressWithoutFunds); + expect(args._value).to.be.bignumber.equal(allowanceAmount); + }, + ); zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Approval, indexFilterValues, callback); await zeroEx.token.setAllowanceAsync( etherTokenAddress, @@ -199,30 +200,30 @@ describe('EtherTokenWrapper', () => { }); it('Should receive the Deposit event when ether is being deposited', (done: DoneCallback) => { (async () => { - const callback = (err: Error, logEvent: DecodedLogEvent<DepositContractEventArgs>) => { - expect(err).to.be.null(); - expect(logEvent).to.not.be.undefined(); - expect(logEvent.isRemoved).to.be.false(); - const args = logEvent.log.args; - expect(args._owner).to.be.equal(addressWithETH); - expect(args._value).to.be.bignumber.equal(depositAmount); - done(); - }; + const callback = reportNodeCallbackErrors(done)( + (logEvent: DecodedLogEvent<DepositContractEventArgs>) => { + expect(logEvent).to.not.be.undefined(); + expect(logEvent.isRemoved).to.be.false(); + const args = logEvent.log.args; + expect(args._owner).to.be.equal(addressWithETH); + expect(args._value).to.be.bignumber.equal(depositAmount); + }, + ); zeroEx.etherToken.subscribe(etherTokenAddress, EtherTokenEvents.Deposit, indexFilterValues, callback); await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH); })().catch(done); }); it('Should receive the Withdrawal event when ether is being withdrawn', (done: DoneCallback) => { (async () => { - const callback = (err: Error, logEvent: DecodedLogEvent<WithdrawalContractEventArgs>) => { - expect(err).to.be.null(); - expect(logEvent).to.not.be.undefined(); - expect(logEvent.isRemoved).to.be.false(); - const args = logEvent.log.args; - expect(args._owner).to.be.equal(addressWithETH); - expect(args._value).to.be.bignumber.equal(depositAmount); - done(); - }; + const callback = reportNodeCallbackErrors(done)( + (logEvent: DecodedLogEvent<WithdrawalContractEventArgs>) => { + expect(logEvent).to.not.be.undefined(); + expect(logEvent.isRemoved).to.be.false(); + const args = logEvent.log.args; + expect(args._owner).to.be.equal(addressWithETH); + expect(args._value).to.be.bignumber.equal(depositAmount); + }, + ); await zeroEx.etherToken.depositAsync(etherTokenAddress, depositAmount, addressWithETH); zeroEx.etherToken.subscribe( etherTokenAddress, @@ -235,18 +236,18 @@ describe('EtherTokenWrapper', () => { }); it('should cancel outstanding subscriptions when ZeroEx.setProvider is called', (done: DoneCallback) => { (async () => { - const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { - done(new Error('Expected this subscription to have been cancelled')); - }; + const callbackNeverToBeCalled = reportNodeCallbackErrors(done)( + (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { + done(new Error('Expected this subscription to have been cancelled')); + }, + ); zeroEx.etherToken.subscribe( etherTokenAddress, EtherTokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled, ); - const callbackToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { - done(); - }; + const callbackToBeCalled = reportNodeCallbackErrors(done)(); const newProvider = web3Factory.getRpcProvider(); zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID); await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH); @@ -266,9 +267,11 @@ describe('EtherTokenWrapper', () => { }); it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => { (async () => { - const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { - done(new Error('Expected this subscription to have been cancelled')); - }; + const callbackNeverToBeCalled = reportNodeCallbackErrors(done)( + (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { + done(new Error('Expected this subscription to have been cancelled')); + }, + ); await zeroEx.etherToken.depositAsync(etherTokenAddress, transferAmount, addressWithETH); const subscriptionToken = zeroEx.etherToken.subscribe( etherTokenAddress, diff --git a/packages/0x.js/test/exchange_wrapper_test.ts b/packages/0x.js/test/exchange_wrapper_test.ts index cb927ba8f..c501ce998 100644 --- a/packages/0x.js/test/exchange_wrapper_test.ts +++ b/packages/0x.js/test/exchange_wrapper_test.ts @@ -1,6 +1,7 @@ import { BlockchainLifecycle } from '@0xproject/dev-utils'; import { BigNumber } from '@0xproject/utils'; import * as chai from 'chai'; +import * as _ from 'lodash'; import 'mocha'; import * as Web3 from 'web3'; @@ -22,6 +23,7 @@ import { BlockParamLiteral, DoneCallback } from '../src/types'; import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; import { FillScenarios } from './utils/fill_scenarios'; +import { reportNodeCallbackErrors } from './utils/report_callback_errors'; import { TokenUtils } from './utils/token_utils'; import { web3Factory } from './utils/web3_factory'; @@ -31,6 +33,13 @@ const blockchainLifecycle = new BlockchainLifecycle(constants.RPC_URL); const NON_EXISTENT_ORDER_HASH = '0x79370342234e7acd6bbeac335bd3bb1d368383294b64b8160a00f4060e4d3777'; +function noError<T>(err: Error | null, value: T | undefined): value is T { + if (_.isNull(err)) { + throw err; + } + return _.isNull(err); +} + describe('ExchangeWrapper', () => { let web3: Web3; let zeroEx: ZeroEx; @@ -851,10 +860,11 @@ describe('ExchangeWrapper', () => { // Source: https://github.com/mochajs/mocha/issues/2407 it('Should receive the LogFill event when an order is filled', (done: DoneCallback) => { (async () => { - const callback = (err: Error, logEvent: DecodedLogEvent<LogFillContractEventArgs>) => { - expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill); - done(); - }; + const callback = reportNodeCallbackErrors(done)( + (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => { + expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill); + }, + ); zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback); await zeroEx.exchange.fillOrderAsync( signedOrder, @@ -866,28 +876,32 @@ describe('ExchangeWrapper', () => { }); it('Should receive the LogCancel event when an order is cancelled', (done: DoneCallback) => { (async () => { - const callback = (err: Error, logEvent: DecodedLogEvent<LogCancelContractEventArgs>) => { - expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogCancel); - done(); - }; + const callback = reportNodeCallbackErrors(done)( + (logEvent: DecodedLogEvent<LogCancelContractEventArgs>) => { + expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogCancel); + }, + ); zeroEx.exchange.subscribe(ExchangeEvents.LogCancel, indexFilterValues, callback); await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelTakerAmountInBaseUnits); })().catch(done); }); it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => { (async () => { - const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<LogFillContractEventArgs>) => { - done(new Error('Expected this subscription to have been cancelled')); - }; + const callbackNeverToBeCalled = reportNodeCallbackErrors(done)( + (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => { + done(new Error('Expected this subscription to have been cancelled')); + }, + ); zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callbackNeverToBeCalled); const newProvider = web3Factory.getRpcProvider(); zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID); - const callback = (err: Error, logEvent: DecodedLogEvent<LogFillContractEventArgs>) => { - expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill); - done(); - }; + const callback = reportNodeCallbackErrors(done)( + (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => { + expect(logEvent.log.event).to.be.equal(ExchangeEvents.LogFill); + }, + ); zeroEx.exchange.subscribe(ExchangeEvents.LogFill, indexFilterValues, callback); await zeroEx.exchange.fillOrderAsync( signedOrder, @@ -899,9 +913,11 @@ describe('ExchangeWrapper', () => { }); it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => { (async () => { - const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<LogFillContractEventArgs>) => { - done(new Error('Expected this subscription to have been cancelled')); - }; + const callbackNeverToBeCalled = reportNodeCallbackErrors(done)( + (logEvent: DecodedLogEvent<LogFillContractEventArgs>) => { + done(new Error('Expected this subscription to have been cancelled')); + }, + ); const subscriptionToken = zeroEx.exchange.subscribe( ExchangeEvents.LogFill, indexFilterValues, diff --git a/packages/0x.js/test/expiration_watcher_test.ts b/packages/0x.js/test/expiration_watcher_test.ts index e7ba3533a..770615f88 100644 --- a/packages/0x.js/test/expiration_watcher_test.ts +++ b/packages/0x.js/test/expiration_watcher_test.ts @@ -15,7 +15,7 @@ import { utils } from '../src/utils/utils'; import { chaiSetup } from './utils/chai_setup'; import { constants as testConstants } from './utils/constants'; import { FillScenarios } from './utils/fill_scenarios'; -import { reportCallbackErrors } from './utils/report_callback_errors'; +import { reportNoErrorCallbackErrors } from './utils/report_callback_errors'; import { TokenUtils } from './utils/token_utils'; import { web3Factory } from './utils/web3_factory'; @@ -87,10 +87,9 @@ describe('ExpirationWatcher', () => { ); const orderHash = ZeroEx.getOrderHashHex(signedOrder); expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000)); - const callbackAsync = reportCallbackErrors(done)(async (hash: string) => { + const callbackAsync = reportNoErrorCallbackErrors(done)((hash: string) => { expect(hash).to.be.equal(orderHash); expect(utils.getCurrentUnixTimestampSec()).to.be.bignumber.gte(expirationUnixTimestampSec); - done(); }); expirationWatcher.subscribe(callbackAsync); timer.tick(orderLifetimeSec * 1000); @@ -110,7 +109,7 @@ describe('ExpirationWatcher', () => { ); const orderHash = ZeroEx.getOrderHashHex(signedOrder); expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000)); - const callbackAsync = reportCallbackErrors(done)(async (hash: string) => { + const callbackAsync = reportNoErrorCallbackErrors(done)(async (hash: string) => { done(new Error('Emitted expiration went before the order actually expired')); }); expirationWatcher.subscribe(callbackAsync); @@ -146,7 +145,8 @@ describe('ExpirationWatcher', () => { expirationWatcher.addOrder(orderHash2, signedOrder2.expirationUnixTimestampSec.times(1000)); expirationWatcher.addOrder(orderHash1, signedOrder1.expirationUnixTimestampSec.times(1000)); const expirationOrder = [orderHash1, orderHash2]; - const callbackAsync = reportCallbackErrors(done)(async (hash: string) => { + const expectToBeCalledOnce = false; + const callbackAsync = reportNoErrorCallbackErrors(done, expectToBeCalledOnce)((hash: string) => { const orderHash = expirationOrder.shift(); expect(hash).to.be.equal(orderHash); if (_.isEmpty(expirationOrder)) { diff --git a/packages/0x.js/test/order_state_watcher_test.ts b/packages/0x.js/test/order_state_watcher_test.ts index 9f284cfd9..311752bd8 100644 --- a/packages/0x.js/test/order_state_watcher_test.ts +++ b/packages/0x.js/test/order_state_watcher_test.ts @@ -20,7 +20,7 @@ import { DoneCallback } from '../src/types'; import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; import { FillScenarios } from './utils/fill_scenarios'; -import { reportCallbackErrors } from './utils/report_callback_errors'; +import { reportNoErrorCallbackErrors } from './utils/report_callback_errors'; import { TokenUtils } from './utils/token_utils'; import { web3Factory } from './utils/web3_factory'; @@ -134,12 +134,11 @@ describe('OrderStateWatcher', () => { ); const orderHash = ZeroEx.getOrderHashHex(signedOrder); zeroEx.orderStateWatcher.addOrder(signedOrder); - const callback = reportCallbackErrors(done)((orderState: OrderState) => { + const callback = reportNoErrorCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.false(); const invalidOrderState = orderState as OrderStateInvalid; expect(invalidOrderState.orderHash).to.be.equal(orderHash); expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerAllowance); - done(); }); zeroEx.orderStateWatcher.subscribe(callback); await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, new BigNumber(0)); @@ -155,7 +154,7 @@ describe('OrderStateWatcher', () => { fillableAmount, ); zeroEx.orderStateWatcher.addOrder(signedOrder); - const callback = reportCallbackErrors(done)((orderState: OrderState) => { + const callback = reportNoErrorCallbackErrors(done)((orderState: OrderState) => { throw new Error('OrderState callback fired for irrelevant order'); }); zeroEx.orderStateWatcher.subscribe(callback); @@ -179,12 +178,11 @@ describe('OrderStateWatcher', () => { ); const orderHash = ZeroEx.getOrderHashHex(signedOrder); zeroEx.orderStateWatcher.addOrder(signedOrder); - const callback = reportCallbackErrors(done)((orderState: OrderState) => { + const callback = reportNoErrorCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.false(); const invalidOrderState = orderState as OrderStateInvalid; expect(invalidOrderState.orderHash).to.be.equal(orderHash); expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.InsufficientMakerBalance); - done(); }); zeroEx.orderStateWatcher.subscribe(callback); const anyRecipient = taker; @@ -204,12 +202,11 @@ describe('OrderStateWatcher', () => { const orderHash = ZeroEx.getOrderHashHex(signedOrder); zeroEx.orderStateWatcher.addOrder(signedOrder); - const callback = reportCallbackErrors(done)((orderState: OrderState) => { + const callback = reportNoErrorCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.false(); const invalidOrderState = orderState as OrderStateInvalid; expect(invalidOrderState.orderHash).to.be.equal(orderHash); expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderRemainingFillAmountZero); - done(); }); zeroEx.orderStateWatcher.subscribe(callback); @@ -237,7 +234,7 @@ describe('OrderStateWatcher', () => { const orderHash = ZeroEx.getOrderHashHex(signedOrder); zeroEx.orderStateWatcher.addOrder(signedOrder); - const callback = reportCallbackErrors(done)((orderState: OrderState) => { + const callback = reportNoErrorCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.true(); const validOrderState = orderState as OrderStateValid; expect(validOrderState.orderHash).to.be.equal(orderHash); @@ -251,7 +248,6 @@ describe('OrderStateWatcher', () => { remainingFillable, ); expect(orderRelevantState.makerBalance).to.be.bignumber.equal(remainingMakerBalance); - done(); }); zeroEx.orderStateWatcher.subscribe(callback); const shouldThrowOnInsufficientBalanceOrAllowance = true; @@ -277,9 +273,7 @@ describe('OrderStateWatcher', () => { fillableAmount, taker, ); - const callback = reportCallbackErrors(done)((orderState: OrderState) => { - done(); - }); + const callback = reportNoErrorCallbackErrors(done)(); zeroEx.orderStateWatcher.addOrder(signedOrder); zeroEx.orderStateWatcher.subscribe(callback); await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, new BigNumber(0)); @@ -301,7 +295,7 @@ describe('OrderStateWatcher', () => { const fillAmountInBaseUnits = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals); const orderHash = ZeroEx.getOrderHashHex(signedOrder); zeroEx.orderStateWatcher.addOrder(signedOrder); - const callback = reportCallbackErrors(done)((orderState: OrderState) => { + const callback = reportNoErrorCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.true(); const validOrderState = orderState as OrderStateValid; expect(validOrderState.orderHash).to.be.equal(orderHash); @@ -312,7 +306,6 @@ describe('OrderStateWatcher', () => { expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal( ZeroEx.toBaseUnitAmount(new BigNumber(8), decimals), ); - done(); }); zeroEx.orderStateWatcher.subscribe(callback); const shouldThrowOnInsufficientBalanceOrAllowance = true; @@ -337,7 +330,7 @@ describe('OrderStateWatcher', () => { const changedMakerApprovalAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals); zeroEx.orderStateWatcher.addOrder(signedOrder); - const callback = reportCallbackErrors(done)((orderState: OrderState) => { + const callback = reportNoErrorCallbackErrors(done)((orderState: OrderState) => { const validOrderState = orderState as OrderStateValid; const orderRelevantState = validOrderState.orderRelevantState; expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal( @@ -346,7 +339,6 @@ describe('OrderStateWatcher', () => { expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal( changedMakerApprovalAmount, ); - done(); }); zeroEx.orderStateWatcher.subscribe(callback); await zeroEx.token.setProxyAllowanceAsync(makerToken.address, maker, changedMakerApprovalAmount); @@ -368,7 +360,7 @@ describe('OrderStateWatcher', () => { const transferAmount = makerBalance.sub(remainingAmount); zeroEx.orderStateWatcher.addOrder(signedOrder); - const callback = reportCallbackErrors(done)((orderState: OrderState) => { + const callback = reportNoErrorCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.true(); const validOrderState = orderState as OrderStateValid; const orderRelevantState = validOrderState.orderRelevantState; @@ -378,7 +370,6 @@ describe('OrderStateWatcher', () => { expect(orderRelevantState.remainingFillableTakerTokenAmount).to.be.bignumber.equal( remainingAmount, ); - done(); }); zeroEx.orderStateWatcher.subscribe(callback); await zeroEx.token.transferAsync(makerToken.address, maker, ZeroEx.NULL_ADDRESS, transferAmount); @@ -404,14 +395,13 @@ describe('OrderStateWatcher', () => { const transferTokenAmount = makerFee.sub(remainingTokenAmount); zeroEx.orderStateWatcher.addOrder(signedOrder); - const callback = reportCallbackErrors(done)((orderState: OrderState) => { + const callback = reportNoErrorCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.true(); const validOrderState = orderState as OrderStateValid; const orderRelevantState = validOrderState.orderRelevantState; expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal( remainingTokenAmount, ); - done(); }); zeroEx.orderStateWatcher.subscribe(callback); await zeroEx.exchange.cancelOrderAsync(signedOrder, transferTokenAmount); @@ -439,13 +429,12 @@ describe('OrderStateWatcher', () => { const transferTokenAmount = makerFee.sub(remainingTokenAmount); zeroEx.orderStateWatcher.addOrder(signedOrder); - const callback = reportCallbackErrors(done)((orderState: OrderState) => { + const callback = reportNoErrorCallbackErrors(done)((orderState: OrderState) => { const validOrderState = orderState as OrderStateValid; const orderRelevantState = validOrderState.orderRelevantState; expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal( remainingFeeAmount, ); - done(); }); zeroEx.orderStateWatcher.subscribe(callback); await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, remainingFeeAmount); @@ -475,13 +464,12 @@ describe('OrderStateWatcher', () => { zeroEx.orderStateWatcher.addOrder(signedOrder); - const callback = reportCallbackErrors(done)((orderState: OrderState) => { + const callback = reportNoErrorCallbackErrors(done)((orderState: OrderState) => { const validOrderState = orderState as OrderStateValid; const orderRelevantState = validOrderState.orderRelevantState; expect(orderRelevantState.remainingFillableMakerTokenAmount).to.be.bignumber.equal( fillableAmount, ); - done(); }); zeroEx.orderStateWatcher.subscribe(callback); await zeroEx.token.setProxyAllowanceAsync( @@ -504,12 +492,11 @@ describe('OrderStateWatcher', () => { const orderHash = ZeroEx.getOrderHashHex(signedOrder); zeroEx.orderStateWatcher.addOrder(signedOrder); - const callback = reportCallbackErrors(done)((orderState: OrderState) => { + const callback = reportNoErrorCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.false(); const invalidOrderState = orderState as OrderStateInvalid; expect(invalidOrderState.orderHash).to.be.equal(orderHash); expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderRemainingFillAmountZero); - done(); }); zeroEx.orderStateWatcher.subscribe(callback); @@ -529,12 +516,11 @@ describe('OrderStateWatcher', () => { const orderHash = ZeroEx.getOrderHashHex(signedOrder); zeroEx.orderStateWatcher.addOrder(signedOrder); - const callback = reportCallbackErrors(done)((orderState: OrderState) => { + const callback = reportNoErrorCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.false(); const invalidOrderState = orderState as OrderStateInvalid; expect(invalidOrderState.orderHash).to.be.equal(orderHash); expect(invalidOrderState.error).to.be.equal(ExchangeContractErrs.OrderFillRoundingError); - done(); }); zeroEx.orderStateWatcher.subscribe(callback); await zeroEx.exchange.cancelOrderAsync( @@ -557,13 +543,12 @@ describe('OrderStateWatcher', () => { const orderHash = ZeroEx.getOrderHashHex(signedOrder); zeroEx.orderStateWatcher.addOrder(signedOrder); - const callback = reportCallbackErrors(done)((orderState: OrderState) => { + const callback = reportNoErrorCallbackErrors(done)((orderState: OrderState) => { expect(orderState.isValid).to.be.true(); const validOrderState = orderState as OrderStateValid; expect(validOrderState.orderHash).to.be.equal(orderHash); const orderRelevantState = validOrderState.orderRelevantState; expect(orderRelevantState.cancelledTakerTokenAmount).to.be.bignumber.equal(cancelAmountInBaseUnits); - done(); }); zeroEx.orderStateWatcher.subscribe(callback); await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmountInBaseUnits); diff --git a/packages/0x.js/test/subscription_test.ts b/packages/0x.js/test/subscription_test.ts index d6269f15f..f44bfecf6 100644 --- a/packages/0x.js/test/subscription_test.ts +++ b/packages/0x.js/test/subscription_test.ts @@ -11,7 +11,7 @@ import { DoneCallback } from '../src/types'; import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; -import { reportCallbackErrors } from './utils/report_callback_errors'; +import { assertNodeCallbackError } from './utils/report_callback_errors'; import { web3Factory } from './utils/web3_factory'; chaiSetup.configure(); @@ -59,13 +59,7 @@ describe('SubscriptionTest', () => { it('Should receive the Error when an error occurs while fetching the block', (done: DoneCallback) => { (async () => { const errMsg = 'Error fetching block'; - const callback = reportCallbackErrors(done)( - (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { - expect(err.message).to.be.equal(errMsg); - expect(logEvent).to.be.undefined(); - done(); - }, - ); + const callback = assertNodeCallbackError(done, errMsg); stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error(errMsg))]; zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback); await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount); @@ -74,13 +68,7 @@ describe('SubscriptionTest', () => { it('Should receive the Error when an error occurs while reconciling the new block', (done: DoneCallback) => { (async () => { const errMsg = 'Error fetching logs'; - const callback = reportCallbackErrors(done)( - (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { - expect(err.message).to.be.equal(errMsg); - expect(logEvent).to.be.undefined(); - done(); - }, - ); + const callback = assertNodeCallbackError(done, errMsg); stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getLogsAsync').throws(new Error(errMsg))]; zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback); await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount); @@ -88,7 +76,7 @@ describe('SubscriptionTest', () => { }); it('Should allow unsubscribeAll to be called successfully after an error', (done: DoneCallback) => { (async () => { - const callback = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop; + const callback = (err: Error | null, logEvent?: DecodedLogEvent<ApprovalContractEventArgs>) => _.noop; zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback); stubs = [Sinon.stub((zeroEx as any)._web3Wrapper, 'getBlockAsync').throws(new Error('JSON RPC error'))]; zeroEx.token.unsubscribeAll(); diff --git a/packages/0x.js/test/token_wrapper_test.ts b/packages/0x.js/test/token_wrapper_test.ts index 296a704dd..4ba1f07c5 100644 --- a/packages/0x.js/test/token_wrapper_test.ts +++ b/packages/0x.js/test/token_wrapper_test.ts @@ -20,6 +20,7 @@ import { DoneCallback } from '../src/types'; import { chaiSetup } from './utils/chai_setup'; import { constants } from './utils/constants'; +import { reportNodeCallbackErrors } from './utils/report_callback_errors'; import { TokenUtils } from './utils/token_utils'; import { web3Factory } from './utils/web3_factory'; @@ -386,46 +387,47 @@ describe('TokenWrapper', () => { // Source: https://github.com/mochajs/mocha/issues/2407 it('Should receive the Transfer event when tokens are transfered', (done: DoneCallback) => { (async () => { - const callback = (err: Error, logEvent: DecodedLogEvent<TransferContractEventArgs>) => { - expect(logEvent).to.not.be.undefined(); - expect(logEvent.isRemoved).to.be.false(); - expect(logEvent.log.logIndex).to.be.equal(0); - expect(logEvent.log.transactionIndex).to.be.equal(0); - expect(logEvent.log.blockNumber).to.be.a('number'); - const args = logEvent.log.args; - expect(args._from).to.be.equal(coinbase); - expect(args._to).to.be.equal(addressWithoutFunds); - expect(args._value).to.be.bignumber.equal(transferAmount); - done(); - }; + const callback = reportNodeCallbackErrors(done)( + (logEvent: DecodedLogEvent<TransferContractEventArgs>) => { + expect(logEvent.isRemoved).to.be.false(); + expect(logEvent.log.logIndex).to.be.equal(0); + expect(logEvent.log.transactionIndex).to.be.equal(0); + expect(logEvent.log.blockNumber).to.be.a('number'); + const args = logEvent.log.args; + expect(args._from).to.be.equal(coinbase); + expect(args._to).to.be.equal(addressWithoutFunds); + expect(args._value).to.be.bignumber.equal(transferAmount); + }, + ); zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callback); await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount); })().catch(done); }); it('Should receive the Approval event when allowance is being set', (done: DoneCallback) => { (async () => { - const callback = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { - expect(logEvent).to.not.be.undefined(); - expect(logEvent.isRemoved).to.be.false(); - const args = logEvent.log.args; - expect(args._owner).to.be.equal(coinbase); - expect(args._spender).to.be.equal(addressWithoutFunds); - expect(args._value).to.be.bignumber.equal(allowanceAmount); - done(); - }; + const callback = reportNodeCallbackErrors(done)( + (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { + expect(logEvent).to.not.be.undefined(); + expect(logEvent.isRemoved).to.be.false(); + const args = logEvent.log.args; + expect(args._owner).to.be.equal(coinbase); + expect(args._spender).to.be.equal(addressWithoutFunds); + expect(args._value).to.be.bignumber.equal(allowanceAmount); + }, + ); zeroEx.token.subscribe(tokenAddress, TokenEvents.Approval, indexFilterValues, callback); await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount); })().catch(done); }); it('Outstanding subscriptions are cancelled when zeroEx.setProvider called', (done: DoneCallback) => { (async () => { - const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { - done(new Error('Expected this subscription to have been cancelled')); - }; + const callbackNeverToBeCalled = reportNodeCallbackErrors(done)( + (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { + done(new Error('Expected this subscription to have been cancelled')); + }, + ); zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackNeverToBeCalled); - const callbackToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { - done(); - }; + const callbackToBeCalled = reportNodeCallbackErrors(done)(); const newProvider = web3Factory.getRpcProvider(); zeroEx.setProvider(newProvider, constants.TESTRPC_NETWORK_ID); zeroEx.token.subscribe(tokenAddress, TokenEvents.Transfer, indexFilterValues, callbackToBeCalled); @@ -434,9 +436,11 @@ describe('TokenWrapper', () => { }); it('Should cancel subscription when unsubscribe called', (done: DoneCallback) => { (async () => { - const callbackNeverToBeCalled = (err: Error, logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { - done(new Error('Expected this subscription to have been cancelled')); - }; + const callbackNeverToBeCalled = reportNodeCallbackErrors(done)( + (logEvent: DecodedLogEvent<ApprovalContractEventArgs>) => { + done(new Error('Expected this subscription to have been cancelled')); + }, + ); const subscriptionToken = zeroEx.token.subscribe( tokenAddress, TokenEvents.Transfer, diff --git a/packages/0x.js/test/utils/report_callback_errors.ts b/packages/0x.js/test/utils/report_callback_errors.ts index 8a8f4d966..7890e7cd3 100644 --- a/packages/0x.js/test/utils/report_callback_errors.ts +++ b/packages/0x.js/test/utils/report_callback_errors.ts @@ -1,10 +1,22 @@ -import { DoneCallback } from '../../src/types'; +import * as chai from 'chai'; +import * as _ from 'lodash'; -export const reportCallbackErrors = (done: DoneCallback) => { - return (f: (...args: any[]) => void) => { - const wrapped = async (...args: any[]) => { +import { DoneCallback, OrderState } from '../../src/types'; + +const expect = chai.expect; + +export const reportNoErrorCallbackErrors = (done: DoneCallback, expectToBeCalledOnce = true) => { + return <T>(f?: (value: T) => void) => { + const wrapped = (value: T) => { + if (_.isUndefined(f)) { + done(); + return; + } try { - f(...args); + f(value); + if (expectToBeCalledOnce) { + done(); + } } catch (err) { done(err); } @@ -12,3 +24,41 @@ export const reportCallbackErrors = (done: DoneCallback) => { return wrapped; }; }; + +export const reportNodeCallbackErrors = (done: DoneCallback) => { + return <T>(f?: (value: T) => void) => { + const wrapped = (error: Error | null, value: T | undefined) => { + if (!_.isNull(error)) { + done(error); + } else { + if (_.isUndefined(f)) { + done(); + return; + } + try { + f(value as T); + done(); + } catch (err) { + done(err); + } + } + }; + return wrapped; + }; +}; + +export const assertNodeCallbackError = (done: DoneCallback, errMsg: string) => { + const wrapped = <T>(error: Error | null, value: T | undefined) => { + if (_.isNull(error)) { + done(new Error('Expected callback to receive an error')); + } else { + try { + expect(error.message).to.be.equal(errMsg); + done(); + } catch (err) { + done(err); + } + } + }; + return wrapped; +}; diff --git a/packages/0x.js/tsconfig.json b/packages/0x.js/tsconfig.json index 1defcc4a4..117f51e83 100644 --- a/packages/0x.js/tsconfig.json +++ b/packages/0x.js/tsconfig.json @@ -2,7 +2,7 @@ "extends": "../../tsconfig", "compilerOptions": { "outDir": "lib", - "strict": false + "noImplicitThis": false }, "include": [ "./src/**/*", |