aboutsummaryrefslogtreecommitdiffstats
path: root/packages/0x.js/test
diff options
context:
space:
mode:
Diffstat (limited to 'packages/0x.js/test')
-rw-r--r--packages/0x.js/test/expiration_watcher_test.ts138
-rw-r--r--packages/0x.js/test/order_state_watcher_test.ts46
-rw-r--r--packages/0x.js/test/token_wrapper_test.ts3
-rw-r--r--packages/0x.js/test/utils/report_callback_errors.ts6
4 files changed, 175 insertions, 18 deletions
diff --git a/packages/0x.js/test/expiration_watcher_test.ts b/packages/0x.js/test/expiration_watcher_test.ts
new file mode 100644
index 000000000..0f2470070
--- /dev/null
+++ b/packages/0x.js/test/expiration_watcher_test.ts
@@ -0,0 +1,138 @@
+import 'mocha';
+import * as chai from 'chai';
+import * as _ from 'lodash';
+import * as Sinon from 'sinon';
+import * as Web3 from 'web3';
+import BigNumber from 'bignumber.js';
+import {chaiSetup} from './utils/chai_setup';
+import {web3Factory} from './utils/web3_factory';
+import {utils} from '../src/utils/utils';
+import {Web3Wrapper} from '../src/web3_wrapper';
+import {TokenUtils} from './utils/token_utils';
+import {ExpirationWatcher} from '../src/order_watcher/expiration_watcher';
+import {Token, DoneCallback} from '../src/types';
+import {ZeroEx} from '../src/0x';
+import {BlockchainLifecycle} from './utils/blockchain_lifecycle';
+import {FillScenarios} from './utils/fill_scenarios';
+import {reportCallbackErrors} from './utils/report_callback_errors';
+
+chaiSetup.configure();
+const expect = chai.expect;
+const blockchainLifecycle = new BlockchainLifecycle();
+
+describe('ExpirationWatcher', () => {
+ let web3: Web3;
+ let zeroEx: ZeroEx;
+ let tokenUtils: TokenUtils;
+ let tokens: Token[];
+ let userAddresses: string[];
+ let zrxTokenAddress: string;
+ let fillScenarios: FillScenarios;
+ let exchangeContractAddress: string;
+ let makerTokenAddress: string;
+ let takerTokenAddress: string;
+ let coinbase: string;
+ let makerAddress: string;
+ let takerAddress: string;
+ let feeRecipient: string;
+ const fillableAmount = new BigNumber(5);
+ let currentUnixTimestampSec: BigNumber;
+ let timer: Sinon.SinonFakeTimers;
+ let expirationWatcher: ExpirationWatcher;
+ before(async () => {
+ web3 = web3Factory.create();
+ zeroEx = new ZeroEx(web3.currentProvider);
+ exchangeContractAddress = await zeroEx.exchange.getContractAddressAsync();
+ userAddresses = await zeroEx.getAvailableAddressesAsync();
+ tokens = await zeroEx.tokenRegistry.getTokensAsync();
+ tokenUtils = new TokenUtils(tokens);
+ zrxTokenAddress = tokenUtils.getProtocolTokenOrThrow().address;
+ fillScenarios = new FillScenarios(zeroEx, userAddresses, tokens, zrxTokenAddress, exchangeContractAddress);
+ [coinbase, makerAddress, takerAddress, feeRecipient] = userAddresses;
+ tokens = await zeroEx.tokenRegistry.getTokensAsync();
+ const [makerToken, takerToken] = tokenUtils.getNonProtocolTokens();
+ makerTokenAddress = makerToken.address;
+ takerTokenAddress = takerToken.address;
+ });
+ beforeEach(async () => {
+ await blockchainLifecycle.startAsync();
+ const sinonTimerConfig = {shouldAdvanceTime: true} as any;
+ // This constructor has incorrect types
+ timer = Sinon.useFakeTimers(sinonTimerConfig);
+ currentUnixTimestampSec = utils.getCurrentUnixTimestampSec();
+ expirationWatcher = new ExpirationWatcher();
+ });
+ afterEach(async () => {
+ await blockchainLifecycle.revertAsync();
+ timer.restore();
+ expirationWatcher.unsubscribe();
+ });
+ it('correctly emits events when order expires', (done: DoneCallback) => {
+ (async () => {
+ const orderLifetimeSec = 60;
+ const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
+ const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+ makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
+ expirationUnixTimestampSec,
+ );
+ const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+ expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000));
+ const callbackAsync = reportCallbackErrors(done)(async (hash: string) => {
+ expect(hash).to.be.equal(orderHash);
+ expect(utils.getCurrentUnixTimestampSec()).to.be.bignumber.gte(expirationUnixTimestampSec);
+ done();
+ });
+ expirationWatcher.subscribe(callbackAsync);
+ timer.tick(orderLifetimeSec * 1000);
+ })().catch(done);
+ });
+ it('doesn\'t emit events before order expires', (done: DoneCallback) => {
+ (async () => {
+ const orderLifetimeSec = 60;
+ const expirationUnixTimestampSec = currentUnixTimestampSec.plus(orderLifetimeSec);
+ const signedOrder = await fillScenarios.createFillableSignedOrderAsync(
+ makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
+ expirationUnixTimestampSec,
+ );
+ const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+ expirationWatcher.addOrder(orderHash, signedOrder.expirationUnixTimestampSec.times(1000));
+ const callbackAsync = reportCallbackErrors(done)(async (hash: string) => {
+ done(new Error('Emitted expiration went before the order actually expired'));
+ });
+ expirationWatcher.subscribe(callbackAsync);
+ const notEnoughTime = orderLifetimeSec - 1;
+ timer.tick(notEnoughTime * 1000);
+ done();
+ })().catch(done);
+ });
+ it('emits events in correct order', (done: DoneCallback) => {
+ (async () => {
+ const order1Lifetime = 60;
+ const order2Lifetime = 120;
+ const order1ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order1Lifetime);
+ const order2ExpirationUnixTimestampSec = currentUnixTimestampSec.plus(order2Lifetime);
+ const signedOrder1 = await fillScenarios.createFillableSignedOrderAsync(
+ makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
+ order1ExpirationUnixTimestampSec,
+ );
+ const signedOrder2 = await fillScenarios.createFillableSignedOrderAsync(
+ makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
+ order2ExpirationUnixTimestampSec,
+ );
+ const orderHash1 = ZeroEx.getOrderHashHex(signedOrder1);
+ const orderHash2 = ZeroEx.getOrderHashHex(signedOrder2);
+ 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 orderHash = expirationOrder.shift();
+ expect(hash).to.be.equal(orderHash);
+ if (_.isEmpty(expirationOrder)) {
+ done();
+ }
+ });
+ expirationWatcher.subscribe(callbackAsync);
+ timer.tick(order2Lifetime * 1000);
+ })().catch(done);
+ });
+});
diff --git a/packages/0x.js/test/order_state_watcher_test.ts b/packages/0x.js/test/order_state_watcher_test.ts
index e64a69890..ab6174f71 100644
--- a/packages/0x.js/test/order_state_watcher_test.ts
+++ b/packages/0x.js/test/order_state_watcher_test.ts
@@ -75,13 +75,13 @@ describe('OrderStateWatcher', () => {
makerToken.address, takerToken.address, maker, taker, fillableAmount,
);
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
- zeroEx.orderStateWatcher.addOrder(signedOrder);
+ await zeroEx.orderStateWatcher.addOrderAsync(signedOrder);
expect((zeroEx.orderStateWatcher as any)._orderByOrderHash).to.include({
[orderHash]: signedOrder,
});
let dependentOrderHashes = (zeroEx.orderStateWatcher as any)._dependentOrderHashes;
expect(dependentOrderHashes[signedOrder.maker][signedOrder.makerTokenAddress]).to.have.keys(orderHash);
- zeroEx.orderStateWatcher.removeOrder(orderHash);
+ await zeroEx.orderStateWatcher.removeOrderAsync(orderHash);
expect((zeroEx.orderStateWatcher as any)._orderByOrderHash).to.not.include({
[orderHash]: signedOrder,
});
@@ -94,7 +94,7 @@ describe('OrderStateWatcher', () => {
);
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
const nonExistentOrderHash = `0x${orderHash.substr(2).split('').reverse().join('')}`;
- zeroEx.orderStateWatcher.removeOrder(nonExistentOrderHash);
+ await zeroEx.orderStateWatcher.removeOrderAsync(nonExistentOrderHash);
});
});
describe('#subscribe', async () => {
@@ -111,7 +111,7 @@ describe('OrderStateWatcher', () => {
afterEach(async () => {
zeroEx.orderStateWatcher.unsubscribe();
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
- zeroEx.orderStateWatcher.removeOrder(orderHash);
+ await zeroEx.orderStateWatcher.removeOrderAsync(orderHash);
});
it('should emit orderStateInvalid when maker allowance set to 0 for watched order', (done: DoneCallback) => {
(async () => {
@@ -119,7 +119,7 @@ describe('OrderStateWatcher', () => {
makerToken.address, takerToken.address, maker, taker, fillableAmount,
);
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
- zeroEx.orderStateWatcher.addOrder(signedOrder);
+ await zeroEx.orderStateWatcher.addOrderAsync(signedOrder);
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
expect(orderState.isValid).to.be.false();
const invalidOrderState = orderState as OrderStateInvalid;
@@ -137,7 +137,7 @@ describe('OrderStateWatcher', () => {
makerToken.address, takerToken.address, maker, taker, fillableAmount,
);
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
- zeroEx.orderStateWatcher.addOrder(signedOrder);
+ await zeroEx.orderStateWatcher.addOrderAsync(signedOrder);
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
throw new Error('OrderState callback fired for irrelevant order');
});
@@ -158,7 +158,7 @@ describe('OrderStateWatcher', () => {
makerToken.address, takerToken.address, maker, taker, fillableAmount,
);
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
- zeroEx.orderStateWatcher.addOrder(signedOrder);
+ await zeroEx.orderStateWatcher.addOrderAsync(signedOrder);
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
expect(orderState.isValid).to.be.false();
const invalidOrderState = orderState as OrderStateInvalid;
@@ -178,7 +178,7 @@ describe('OrderStateWatcher', () => {
makerToken.address, takerToken.address, maker, taker, fillableAmount,
);
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
- zeroEx.orderStateWatcher.addOrder(signedOrder);
+ await zeroEx.orderStateWatcher.addOrderAsync(signedOrder);
let eventCount = 0;
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
@@ -210,7 +210,7 @@ describe('OrderStateWatcher', () => {
const fillAmountInBaseUnits = new BigNumber(2);
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
- zeroEx.orderStateWatcher.addOrder(signedOrder);
+ await zeroEx.orderStateWatcher.addOrderAsync(signedOrder);
let eventCount = 0;
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
@@ -237,6 +237,22 @@ describe('OrderStateWatcher', () => {
);
})().catch(done);
});
+ it('should trigger the callback when orders backing ZRX allowance changes', (done: DoneCallback) => {
+ (async () => {
+ const makerFee = ZeroEx.toBaseUnitAmount(new BigNumber(2), 18);
+ const takerFee = ZeroEx.toBaseUnitAmount(new BigNumber(0), 18);
+ signedOrder = await fillScenarios.createFillableSignedOrderWithFeesAsync(
+ makerToken.address, takerToken.address, makerFee, takerFee, maker, taker, fillableAmount,
+ taker);
+ const orderHash = ZeroEx.getOrderHashHex(signedOrder);
+ await zeroEx.orderStateWatcher.addOrderAsync(signedOrder);
+ const callback = reportCallbackErrors(done)((orderState: OrderState) => {
+ done();
+ });
+ zeroEx.orderStateWatcher.subscribe(callback);
+ await zeroEx.token.setProxyAllowanceAsync(zrxTokenAddress, maker, new BigNumber(0));
+ })().catch(done);
+ });
describe('remainingFillable(M|T)akerTokenAmount', () => {
it('should calculate correct remaining fillable', (done: DoneCallback) => {
(async () => {
@@ -250,7 +266,7 @@ describe('OrderStateWatcher', () => {
const takerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, taker);
const fillAmountInBaseUnits = ZeroEx.toBaseUnitAmount(new BigNumber(2), decimals);
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
- zeroEx.orderStateWatcher.addOrder(signedOrder);
+ await zeroEx.orderStateWatcher.addOrderAsync(signedOrder);
let eventCount = 0;
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
eventCount++;
@@ -282,7 +298,7 @@ describe('OrderStateWatcher', () => {
const makerBalance = await zeroEx.token.getBalanceAsync(makerToken.address, maker);
const changedMakerApprovalAmount = ZeroEx.toBaseUnitAmount(new BigNumber(3), decimals);
- zeroEx.orderStateWatcher.addOrder(signedOrder);
+ await zeroEx.orderStateWatcher.addOrderAsync(signedOrder);
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
const validOrderState = orderState as OrderStateValid;
@@ -307,7 +323,7 @@ describe('OrderStateWatcher', () => {
const remainingAmount = ZeroEx.toBaseUnitAmount(new BigNumber(1), decimals);
const transferAmount = makerBalance.sub(remainingAmount);
- zeroEx.orderStateWatcher.addOrder(signedOrder);
+ await zeroEx.orderStateWatcher.addOrderAsync(signedOrder);
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
const validOrderState = orderState as OrderStateValid;
@@ -412,7 +428,7 @@ describe('OrderStateWatcher', () => {
makerToken.address, takerToken.address, maker, taker, fillableAmount,
);
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
- zeroEx.orderStateWatcher.addOrder(signedOrder);
+ await zeroEx.orderStateWatcher.addOrderAsync(signedOrder);
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
expect(orderState.isValid).to.be.false();
@@ -434,7 +450,7 @@ describe('OrderStateWatcher', () => {
makerToken.address, takerToken.address, maker, taker, fillableAmount,
);
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
- zeroEx.orderStateWatcher.addOrder(signedOrder);
+ await zeroEx.orderStateWatcher.addOrderAsync(signedOrder);
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
expect(orderState.isValid).to.be.false();
@@ -460,7 +476,7 @@ describe('OrderStateWatcher', () => {
const cancelAmountInBaseUnits = new BigNumber(2);
const orderHash = ZeroEx.getOrderHashHex(signedOrder);
- zeroEx.orderStateWatcher.addOrder(signedOrder);
+ await zeroEx.orderStateWatcher.addOrderAsync(signedOrder);
const callback = reportCallbackErrors(done)((orderState: OrderState) => {
expect(orderState.isValid).to.be.true();
diff --git a/packages/0x.js/test/token_wrapper_test.ts b/packages/0x.js/test/token_wrapper_test.ts
index b30762e8c..1a7cb9e40 100644
--- a/packages/0x.js/test/token_wrapper_test.ts
+++ b/packages/0x.js/test/token_wrapper_test.ts
@@ -361,6 +361,9 @@ describe('TokenWrapper', () => {
(async () => {
const callback = (err: Error, logEvent: DecodedLogEvent<TransferContractEventArgs>) => {
expect(logEvent).to.not.be.undefined();
+ expect(logEvent.logIndex).to.be.equal(0);
+ expect(logEvent.transactionIndex).to.be.equal(0);
+ expect(logEvent.blockNumber).to.be.a('number');
const args = logEvent.args;
expect(args._from).to.be.equal(coinbase);
expect(args._to).to.be.equal(addressWithoutFunds);
diff --git a/packages/0x.js/test/utils/report_callback_errors.ts b/packages/0x.js/test/utils/report_callback_errors.ts
index d471b2af2..4f9517704 100644
--- a/packages/0x.js/test/utils/report_callback_errors.ts
+++ b/packages/0x.js/test/utils/report_callback_errors.ts
@@ -1,10 +1,10 @@
import { DoneCallback } from '../../src/types';
export const reportCallbackErrors = (done: DoneCallback) => {
- return (f: (...args: any[]) => void) => {
- const wrapped = (...args: any[]) => {
+ return (fAsync: (...args: any[]) => void|Promise<void>) => {
+ const wrapped = async (...args: any[]) => {
try {
- f(...args);
+ await fAsync(...args);
} catch (err) {
done(err);
}