From 5a8eb77ff0a6b00e4df5d933426e451c8ef09f7b Mon Sep 17 00:00:00 2001 From: Leonid Logvinov <logvinov.leon@gmail.com> Date: Mon, 3 Jul 2017 11:39:26 -0700 Subject: Add initial implementation and tests for zeroEx.token.subscribeAsync --- test/token_wrapper_test.ts | 113 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/token_wrapper_test.ts b/test/token_wrapper_test.ts index a1c035672..4a20141db 100644 --- a/test/token_wrapper_test.ts +++ b/test/token_wrapper_test.ts @@ -5,8 +5,17 @@ import * as Web3 from 'web3'; import * as BigNumber from 'bignumber.js'; import promisify = require('es6-promisify'); import {web3Factory} from './utils/web3_factory'; -import {ZeroEx, ZeroExError, Token} from '../src'; +import { + ZeroEx, + ZeroExError, + Token, + SubscriptionOpts, + TokenEvents, + ContractEvent, + TransferContractEventArgs, +} from '../src'; import {BlockchainLifecycle} from './utils/blockchain_lifecycle'; +import {DoneCallback} from '../src/types'; chaiSetup.configure(); const expect = chai.expect; @@ -231,4 +240,106 @@ describe('TokenWrapper', () => { return expect(allowanceAfterSet).to.be.bignumber.equal(expectedAllowanceAfterAllowanceSet); }); }); + describe('#subscribeAsync', () => { + const indexFilterValues = {}; + const shouldCheckTransfer = false; + let tokenAddress: string; + const subscriptionOpts: SubscriptionOpts = { + fromBlock: 0, + toBlock: 'latest', + }; + const transferAmount = new BigNumber(42); + const allowanceAmount = new BigNumber(42); + before(() => { + const token = tokens[0]; + tokenAddress = token.address; + }); + afterEach(async () => { + await zeroEx.token.stopWatchingAllEventsAsync(); + }); + // Hack: Mocha does not allow a test to be both async and have a `done` callback + // Since we need to await the receipt of the event in the `subscribeAsync` callback, + // we do need both. A hack is to make the top-level a sync fn w/ a done callback and then + // wrap the rest of the test in an async block + // Source: https://github.com/mochajs/mocha/issues/2407 + it('Should receive the Transfer event when an order is filled', (done: DoneCallback) => { + (async () => { + const zeroExEvent = await zeroEx.token.subscribeAsync( + tokenAddress, TokenEvents.Transfer, subscriptionOpts, indexFilterValues); + zeroExEvent.watch((err: Error, event: ContractEvent) => { + expect(err).to.be.null(); + expect(event).to.not.be.undefined(); + expect(event.args as TransferContractEventArgs).to.be.deep.equal({ + _from: coinbase, + _to: addressWithoutFunds, + _value: transferAmount, + }); + done(); + }); + await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount); + })(); + }); + it('Should receive the Approval event when an order is cancelled', (done: DoneCallback) => { + (async () => { + const zeroExEvent = await zeroEx.token.subscribeAsync( + tokenAddress, TokenEvents.Approval, subscriptionOpts, indexFilterValues); + zeroExEvent.watch((err: Error, event: ContractEvent) => { + expect(err).to.be.null(); + expect(event).to.not.be.undefined(); + expect(event.args as TransferContractEventArgs).to.be.deep.equal({ + _owner: coinbase, + _spender: addressWithoutFunds, + _value: allowanceAmount, + }); + done(); + }); + await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount); + })(); + }); + it('Outstanding subscriptions are cancelled when zeroEx.setProviderAsync called', (done: DoneCallback) => { + (async () => { + const eventSubscriptionToBeCancelled = await zeroEx.token.subscribeAsync( + tokenAddress, TokenEvents.Transfer, subscriptionOpts, indexFilterValues); + eventSubscriptionToBeCancelled.watch((err: Error, event: ContractEvent) => { + done(new Error('Expected this subscription to have been cancelled')); + }); + + const newProvider = web3Factory.getRpcProvider(); + await zeroEx.setProviderAsync(newProvider); + + const eventSubscriptionToStay = await zeroEx.token.subscribeAsync( + tokenAddress, TokenEvents.Transfer, subscriptionOpts, indexFilterValues); + eventSubscriptionToStay.watch((err: Error, event: ContractEvent) => { + expect(err).to.be.null(); + expect(event).to.not.be.undefined(); + done(); + }); + await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount); + })(); + }); + it('Should stop watch for events when stopWatchingAsync called on the eventEmitter', (done: DoneCallback) => { + (async () => { + const eventSubscriptionToBeStopped = await zeroEx.token.subscribeAsync( + tokenAddress, TokenEvents.Transfer, subscriptionOpts, indexFilterValues); + eventSubscriptionToBeStopped.watch((err: Error, event: ContractEvent) => { + done(new Error('Expected this subscription to have been stopped')); + }); + await eventSubscriptionToBeStopped.stopWatchingAsync(); + await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount); + done(); + })(); + }); + it('Should wrap all event args BigNumber instances in a newer version of BigNumber', (done: DoneCallback) => { + (async () => { + const zeroExEvent = await zeroEx.token.subscribeAsync( + tokenAddress, TokenEvents.Transfer, subscriptionOpts, indexFilterValues); + zeroExEvent.watch((err: Error, event: ContractEvent) => { + const args = event.args as TransferContractEventArgs; + expect(args._value.isBigNumber).to.be.true(); + done(); + }); + await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount); + })(); + }); + }); }); -- cgit v1.2.3 From 7d7bef2b1a83a570be58c8c0c90c9e338c3b93f3 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov <logvinov.leon@gmail.com> Date: Mon, 3 Jul 2017 18:26:31 -0700 Subject: Handle errors from pseudo-async subscription tests --- test/exchange_wrapper_test.ts | 10 +++++----- test/token_wrapper_test.ts | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'test') diff --git a/test/exchange_wrapper_test.ts b/test/exchange_wrapper_test.ts index 3a88db5c9..0321eb569 100644 --- a/test/exchange_wrapper_test.ts +++ b/test/exchange_wrapper_test.ts @@ -721,7 +721,7 @@ describe('ExchangeWrapper', () => { await zeroEx.exchange.fillOrderAsync( signedOrder, fillTakerAmountInBaseUnits, shouldCheckTransfer, takerAddress, ); - })(); + })().catch(done); }); it('Should receive the LogCancel event when an order is cancelled', (done: DoneCallback) => { (async () => { @@ -735,7 +735,7 @@ describe('ExchangeWrapper', () => { done(); }); await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelTakerAmountInBaseUnits); - })(); + })().catch(done); }); it('Outstanding subscriptions are cancelled when zeroEx.setProviderAsync called', (done: DoneCallback) => { (async () => { @@ -761,7 +761,7 @@ describe('ExchangeWrapper', () => { await zeroEx.exchange.fillOrderAsync( signedOrder, fillTakerAmountInBaseUnits, shouldCheckTransfer, takerAddress, ); - })(); + })().catch(done); }); it('Should stop watch for events when stopWatchingAsync called on the eventEmitter', (done: DoneCallback) => { (async () => { @@ -776,7 +776,7 @@ describe('ExchangeWrapper', () => { signedOrder, fillTakerAmountInBaseUnits, shouldCheckTransfer, takerAddress, ); done(); - })(); + })().catch(done); }); it('Should wrap all event args BigNumber instances in a newer version of BigNumber', (done: DoneCallback) => { (async () => { @@ -794,7 +794,7 @@ describe('ExchangeWrapper', () => { await zeroEx.exchange.fillOrderAsync( signedOrder, fillTakerAmountInBaseUnits, shouldCheckTransfer, takerAddress, ); - })(); + })().catch(done); }); }); describe('#getOrderHashHexUsingContractCallAsync', () => { diff --git a/test/token_wrapper_test.ts b/test/token_wrapper_test.ts index 4a20141db..c5a08dc43 100644 --- a/test/token_wrapper_test.ts +++ b/test/token_wrapper_test.ts @@ -277,7 +277,7 @@ describe('TokenWrapper', () => { done(); }); await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount); - })(); + })().catch(done); }); it('Should receive the Approval event when an order is cancelled', (done: DoneCallback) => { (async () => { @@ -294,7 +294,7 @@ describe('TokenWrapper', () => { done(); }); await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount); - })(); + })().catch(done); }); it('Outstanding subscriptions are cancelled when zeroEx.setProviderAsync called', (done: DoneCallback) => { (async () => { @@ -315,7 +315,7 @@ describe('TokenWrapper', () => { done(); }); await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount); - })(); + })().catch(done); }); it('Should stop watch for events when stopWatchingAsync called on the eventEmitter', (done: DoneCallback) => { (async () => { @@ -327,7 +327,7 @@ describe('TokenWrapper', () => { await eventSubscriptionToBeStopped.stopWatchingAsync(); await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount); done(); - })(); + })().catch(done); }); it('Should wrap all event args BigNumber instances in a newer version of BigNumber', (done: DoneCallback) => { (async () => { @@ -339,7 +339,7 @@ describe('TokenWrapper', () => { done(); }); await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount); - })(); + })().catch(done); }); }); }); -- cgit v1.2.3 From 64cf47f297827a869120b85e734406db87b87db8 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov <logvinov.leon@gmail.com> Date: Mon, 3 Jul 2017 21:59:42 -0700 Subject: Add tests for subscriptionOptsSchema and blockParamSchema --- test/schema_test.ts | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'test') diff --git a/test/schema_test.ts b/test/schema_test.ts index b251a68f9..7f9a66ae3 100644 --- a/test/schema_test.ts +++ b/test/schema_test.ts @@ -12,6 +12,7 @@ import {orderFillOrKillRequestsSchema} from '../src/schemas/order_fill_or_kill_r import {ecSignatureParameterSchema, ecSignatureSchema} from '../src/schemas/ec_signature_schema'; import {orderCancellationRequestsSchema} from '../src/schemas/order_cancel_schema'; import {orderFillRequestsSchema} from '../src/schemas/order_fill_requests_schema'; +import {blockParamSchema, subscriptionOptsSchema} from '../src/schemas/subscription_opts_schema'; chai.config.includeStack = true; const expect = chai.expect; @@ -96,6 +97,43 @@ describe('Schema', () => { validateAgainstSchema(testCases, ecSignatureSchema, shouldFail); }); }); + describe('#blockParamSchema', () => { + it('should validate valid block param', () => { + const testCases = [ + 42, + 'latest', + 'pending', + 'earliest', + ]; + validateAgainstSchema(testCases, blockParamSchema); + }); + it('should fail for invalid block param', () => { + const testCases = [ + {}, + '42', + 'pemding', + ]; + const shouldFail = true; + validateAgainstSchema(testCases, blockParamSchema, shouldFail); + }); + }); + describe('#subscriptionOptsSchema', () => { + it('should validate valid subscription opts', () => { + const testCases = [ + {fromBlock: 42, toBlock: 'latest'}, + ]; + validateAgainstSchema(testCases, subscriptionOptsSchema); + }); + it('should fail for invalid subscription opts', () => { + const testCases = [ + {}, + {fromBlock: 42}, + {fromBlock: 42, to: 43}, + ]; + const shouldFail = true; + validateAgainstSchema(testCases, subscriptionOptsSchema, shouldFail); + }); + }); describe('#tokenSchema', () => { const token = { name: 'Zero Ex', -- cgit v1.2.3 From f39a2134b946ab2c7f24b9fcc49f95156e7682d5 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov <logvinov.leon@gmail.com> Date: Mon, 3 Jul 2017 22:32:24 -0700 Subject: Add tests for order hash Schema --- test/schema_test.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/schema_test.ts b/test/schema_test.ts index 7f9a66ae3..4746c7949 100644 --- a/test/schema_test.ts +++ b/test/schema_test.ts @@ -6,7 +6,7 @@ import promisify = require('es6-promisify'); import {constants} from './utils/constants'; import {SchemaValidator} from '../src/utils/schema_validator'; import {tokenSchema} from '../src/schemas/token_schema'; -import {orderSchema, signedOrderSchema} from '../src/schemas/order_schemas'; +import {orderSchema, signedOrderSchema, orderHashSchema} from '../src/schemas/order_schemas'; import {addressSchema, numberSchema} from '../src/schemas/basic_type_schemas'; import {orderFillOrKillRequestsSchema} from '../src/schemas/order_fill_or_kill_requests_schema'; import {ecSignatureParameterSchema, ecSignatureSchema} from '../src/schemas/ec_signature_schema'; @@ -97,6 +97,25 @@ describe('Schema', () => { validateAgainstSchema(testCases, ecSignatureSchema, shouldFail); }); }); + describe('#orderHashSchema', () => { + it('should validate valid order hash', () => { + const testCases = [ + '0x61a3ed31B43c8780e905a260a35faefEc527be7516aa11c0256729b5b351bc33', + '0x40349190569279751135161d22529dc25add4f6069af05be04cacbda2ace2254', + ]; + validateAgainstSchema(testCases, orderHashSchema); + }); + it('should fail for invalid order hash', () => { + const testCases = [ + {}, + '0x', + '0x8b0292B11a196601eD2ce54B665CaFEca0347D42', + '61a3ed31B43c8780e905a260a35faefEc527be7516aa11c0256729b5b351bc33', + ]; + const shouldFail = true; + validateAgainstSchema(testCases, orderHashSchema, shouldFail); + }); + }); describe('#blockParamSchema', () => { it('should validate valid block param', () => { const testCases = [ -- cgit v1.2.3 From 5611df82f9f276fb161fa268f7ab468a6c1d7784 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov <logvinov.leon@gmail.com> Date: Tue, 4 Jul 2017 10:19:03 -0700 Subject: Refactor event tests --- test/token_wrapper_test.ts | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'test') diff --git a/test/token_wrapper_test.ts b/test/token_wrapper_test.ts index c5a08dc43..6ac1beb43 100644 --- a/test/token_wrapper_test.ts +++ b/test/token_wrapper_test.ts @@ -13,6 +13,7 @@ import { TokenEvents, ContractEvent, TransferContractEventArgs, + ApprovalContractEventArgs, } from '../src'; import {BlockchainLifecycle} from './utils/blockchain_lifecycle'; import {DoneCallback} from '../src/types'; @@ -269,11 +270,10 @@ describe('TokenWrapper', () => { zeroExEvent.watch((err: Error, event: ContractEvent) => { expect(err).to.be.null(); expect(event).to.not.be.undefined(); - expect(event.args as TransferContractEventArgs).to.be.deep.equal({ - _from: coinbase, - _to: addressWithoutFunds, - _value: transferAmount, - }); + const args = event.args as TransferContractEventArgs; + expect(args._from).to.be.equal(coinbase); + expect(args._to).to.be.equal(addressWithoutFunds); + expect(args._value).to.be.equal(transferAmount); done(); }); await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount); @@ -284,14 +284,13 @@ describe('TokenWrapper', () => { const zeroExEvent = await zeroEx.token.subscribeAsync( tokenAddress, TokenEvents.Approval, subscriptionOpts, indexFilterValues); zeroExEvent.watch((err: Error, event: ContractEvent) => { - expect(err).to.be.null(); - expect(event).to.not.be.undefined(); - expect(event.args as TransferContractEventArgs).to.be.deep.equal({ - _owner: coinbase, - _spender: addressWithoutFunds, - _value: allowanceAmount, - }); - done(); + expect(err).to.be.null(); + expect(event).to.not.be.undefined(); + const args = event.args as ApprovalContractEventArgs; + expect(args._owner).to.be.equal(coinbase); + expect(args._spender).to.be.equal(addressWithoutFunds); + expect(args._value).to.be.equal(allowanceAmount); + done(); }); await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount); })().catch(done); -- cgit v1.2.3 From c5dca95f893cbc66d7e6d2de234f1411f28e1d19 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov <logvinov.leon@gmail.com> Date: Tue, 4 Jul 2017 10:31:07 -0700 Subject: Use .bignumber for BigNumber comparation --- test/token_wrapper_test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/token_wrapper_test.ts b/test/token_wrapper_test.ts index 6ac1beb43..06e373bfa 100644 --- a/test/token_wrapper_test.ts +++ b/test/token_wrapper_test.ts @@ -273,7 +273,7 @@ describe('TokenWrapper', () => { const args = event.args as TransferContractEventArgs; expect(args._from).to.be.equal(coinbase); expect(args._to).to.be.equal(addressWithoutFunds); - expect(args._value).to.be.equal(transferAmount); + expect(args._value).to.be.bignumber.equal(transferAmount); done(); }); await zeroEx.token.transferAsync(tokenAddress, coinbase, addressWithoutFunds, transferAmount); @@ -289,7 +289,7 @@ describe('TokenWrapper', () => { const args = event.args as ApprovalContractEventArgs; expect(args._owner).to.be.equal(coinbase); expect(args._spender).to.be.equal(addressWithoutFunds); - expect(args._value).to.be.equal(allowanceAmount); + expect(args._value).to.be.bignumber.equal(allowanceAmount); done(); }); await zeroEx.token.setAllowanceAsync(tokenAddress, coinbase, addressWithoutFunds, allowanceAmount); -- cgit v1.2.3 From 82c1d7ca7c206fcb7f436ddd31c97609257d0d2e Mon Sep 17 00:00:00 2001 From: Leonid Logvinov <logvinov.leon@gmail.com> Date: Tue, 4 Jul 2017 12:29:14 -0700 Subject: Add exchangeContractAddress to an order in schema tests --- test/schema_test.ts | 1 + 1 file changed, 1 insertion(+) (limited to 'test') diff --git a/test/schema_test.ts b/test/schema_test.ts index 4746c7949..da7e97ce3 100644 --- a/test/schema_test.ts +++ b/test/schema_test.ts @@ -200,6 +200,7 @@ describe('Schema', () => { takerTokenAddress: constants.NULL_ADDRESS, salt: '256', feeRecipient: constants.NULL_ADDRESS, + exchangeContractAddress: constants.NULL_ADDRESS, expirationUnixTimestampSec: '42', }; describe('#orderSchema', () => { -- cgit v1.2.3 From 464c16be73bddce1ed675f642937b164f7add9d8 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov <logvinov.leon@gmail.com> Date: Tue, 4 Jul 2017 17:33:35 -0700 Subject: move order hash schema to a separate file --- test/schema_test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/schema_test.ts b/test/schema_test.ts index da7e97ce3..3d1d32d9c 100644 --- a/test/schema_test.ts +++ b/test/schema_test.ts @@ -6,7 +6,8 @@ import promisify = require('es6-promisify'); import {constants} from './utils/constants'; import {SchemaValidator} from '../src/utils/schema_validator'; import {tokenSchema} from '../src/schemas/token_schema'; -import {orderSchema, signedOrderSchema, orderHashSchema} from '../src/schemas/order_schemas'; +import {orderHashSchema} from '../src/schemas/order_hash_schema'; +import {orderSchema, signedOrderSchema} from '../src/schemas/order_schemas'; import {addressSchema, numberSchema} from '../src/schemas/basic_type_schemas'; import {orderFillOrKillRequestsSchema} from '../src/schemas/order_fill_or_kill_requests_schema'; import {ecSignatureParameterSchema, ecSignatureSchema} from '../src/schemas/ec_signature_schema'; -- cgit v1.2.3 From ea6583d47e786c846c18fb4893847d3271dedbc3 Mon Sep 17 00:00:00 2001 From: Leonid Logvinov <logvinov.leon@gmail.com> Date: Tue, 4 Jul 2017 17:35:02 -0700 Subject: Make all fields of subscriptionOpts schema optional --- test/schema_test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/schema_test.ts b/test/schema_test.ts index 3d1d32d9c..c170bebb1 100644 --- a/test/schema_test.ts +++ b/test/schema_test.ts @@ -141,14 +141,14 @@ describe('Schema', () => { it('should validate valid subscription opts', () => { const testCases = [ {fromBlock: 42, toBlock: 'latest'}, + {fromBlock: 42}, + {}, ]; validateAgainstSchema(testCases, subscriptionOptsSchema); }); it('should fail for invalid subscription opts', () => { const testCases = [ - {}, - {fromBlock: 42}, - {fromBlock: 42, to: 43}, + {fromBlock: '42'}, ]; const shouldFail = true; validateAgainstSchema(testCases, subscriptionOptsSchema, shouldFail); -- cgit v1.2.3