Add tests for batchCancelAsync

This commit is contained in:
Leonid Logvinov 2017-06-07 13:20:02 +02:00
parent 9325bd8cb4
commit 91101eb8ec
No known key found for this signature in database
GPG Key ID: 0DD294BFDE8C95D4
3 changed files with 69 additions and 27 deletions

View File

@ -212,7 +212,7 @@ export class ExchangeWrapper extends ContractWrapper {
orders: Array<Order|SignedOrder>, takerTokenCancelAmounts: BigNumber.BigNumber[]): Promise<void> { orders: Array<Order|SignedOrder>, takerTokenCancelAmounts: BigNumber.BigNumber[]): Promise<void> {
const makers = _.map(orders, order => order.maker); const makers = _.map(orders, order => order.maker);
assert.isSameLength('orders', orders, 'takerTokenCancelAmounts', takerTokenCancelAmounts); assert.isSameLength('orders', orders, 'takerTokenCancelAmounts', takerTokenCancelAmounts);
assert.assert(_.isEmpty(orders), 'Can not cancel an empty batch'); assert.assert(!_.isEmpty(orders), 'Can not cancel an empty batch');
assert.assert(_.uniq(makers).length === 1, 'Can not cancel orders from multiple makers in a single batch'); assert.assert(_.uniq(makers).length === 1, 'Can not cancel orders from multiple makers in a single batch');
const maker = makers[0]; const maker = makers[0];
// _.zip doesn't type check if values have different types :'( // _.zip doesn't type check if values have different types :'(

View File

@ -45,8 +45,8 @@ export const assert = {
isSameLength(variableName1: string, value1: any[], variableName2: string, value2: any[]) { isSameLength(variableName1: string, value1: any[], variableName2: string, value2: any[]) {
const length1 = value1.length; const length1 = value1.length;
const length2 = value2.length; const length2 = value2.length;
this.assert(length1 === length2, `${variableName1} and ${variableName2} length mismatch. this.assert(length1 === length2, `${variableName1} and ${variableName2} length mismatch. \
${length1} != ${length2}`); ${length1} != ${length2}`);
}, },
isNumber(variableName: string, value: number): void { isNumber(variableName: string, value: number): void {
this.assert(_.isFinite(value), this.typeAssertionMessage(variableName, 'number', value)); this.assert(_.isFinite(value), this.typeAssertionMessage(variableName, 'number', value));

View File

@ -323,7 +323,7 @@ describe('ExchangeWrapper', () => {
}); });
}); });
}); });
describe('#cancelOrderAsync', () => { describe('cancel order(s)', () => {
let makerTokenAddress: string; let makerTokenAddress: string;
let takerTokenAddress: string; let takerTokenAddress: string;
let coinbase: string; let coinbase: string;
@ -343,32 +343,74 @@ describe('ExchangeWrapper', () => {
); );
orderHashHex = await zeroEx.getOrderHashHexAsync(signedOrder); orderHashHex = await zeroEx.getOrderHashHexAsync(signedOrder);
}); });
describe('failed cancels', () => { describe('#cancelOrderAsync', () => {
it('should throw when cancel amount is zero', async () => { describe('failed cancels', () => {
const zeroCancelAmount = new BigNumber(0); it('should throw when cancel amount is zero', async () => {
return expect(zeroEx.exchange.cancelOrderAsync(signedOrder, zeroCancelAmount)) const zeroCancelAmount = new BigNumber(0);
.to.be.rejectedWith(ExchangeContractErrs.ORDER_CANCEL_AMOUNT_ZERO); return expect(zeroEx.exchange.cancelOrderAsync(signedOrder, zeroCancelAmount))
.to.be.rejectedWith(ExchangeContractErrs.ORDER_CANCEL_AMOUNT_ZERO);
});
it('should throw when order is expired', async () => {
const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017
const expiredSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress,
fillableAmount, expirationInPast,
);
orderHashHex = await zeroEx.getOrderHashHexAsync(expiredSignedOrder);
return expect(zeroEx.exchange.cancelOrderAsync(expiredSignedOrder, cancelAmount))
.to.be.rejectedWith(ExchangeContractErrs.ORDER_CANCEL_EXPIRED);
});
it('should throw when order is already cancelled or filled', async () => {
await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
return expect(zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount))
.to.be.rejectedWith(ExchangeContractErrs.ORDER_ALREADY_CANCELLED_OR_FILLED);
});
}); });
it('should throw when order is expired', async () => { describe('successful cancels', () => {
const expirationInPast = new BigNumber(1496826058); // 7th Jun 2017 it('should cancel an order', async () => {
const expiredSignedOrder = await fillScenarios.createFillableSignedOrderAsync( await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmount);
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount, expirationInPast, const cancelledAmount = await zeroEx.exchange.getCanceledTakerAmountAsync(orderHashHex);
); expect(cancelledAmount).to.be.bignumber.equal(cancelAmount);
orderHashHex = await zeroEx.getOrderHashHexAsync(expiredSignedOrder); });
return expect(zeroEx.exchange.cancelOrderAsync(expiredSignedOrder, cancelAmount))
.to.be.rejectedWith(ExchangeContractErrs.ORDER_CANCEL_EXPIRED);
});
it('should throw when order is already cancelled or filled', async () => {
await zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount);
return expect(zeroEx.exchange.cancelOrderAsync(signedOrder, fillableAmount))
.to.be.rejectedWith(ExchangeContractErrs.ORDER_ALREADY_CANCELLED_OR_FILLED);
}); });
}); });
describe('successful cancels', () => { describe('#batchCancelOrderAsync', () => {
it('should cancel an order', async () => { let anotherSignedOrder: SignedOrder;
await zeroEx.exchange.cancelOrderAsync(signedOrder, cancelAmount); let anotherOrderHashHex: string;
const cancelledAmount = await zeroEx.exchange.getCanceledTakerAmountAsync(orderHashHex); beforeEach(async () => {
expect(cancelledAmount).to.be.bignumber.equal(cancelAmount); anotherSignedOrder = await fillScenarios.createFillableSignedOrderAsync(
makerTokenAddress, takerTokenAddress, makerAddress, takerAddress, fillableAmount,
);
anotherOrderHashHex = await zeroEx.getOrderHashHexAsync(anotherSignedOrder);
});
describe('failed batch cancels', () => {
it('should throw when length of orders and cancelAmounts mismatch', async () => {
return expect(zeroEx.exchange.batchCancelOrderAsync([signedOrder], []))
.to.be.rejectedWith('orders and takerTokenCancelAmounts length mismatch. 1 != 0');
});
it('should throw when orders are empty', async () => {
return expect(zeroEx.exchange.batchCancelOrderAsync([], []))
.to.be.rejectedWith('Can not cancel an empty batch');
});
it.only('should throw when orders have different makers', async () => {
const signedOrderWithADifferentMaker = await fillScenarios.createFillableSignedOrderAsync(
makerTokenAddress, takerTokenAddress, takerAddress, takerAddress, fillableAmount,
);
return expect(zeroEx.exchange.batchCancelOrderAsync(
[signedOrder, signedOrderWithADifferentMaker], [cancelAmount, cancelAmount]))
.to.be.rejectedWith('Can not cancel orders from multiple makers in a single batch');
});
});
describe('successful batch cancels', () => {
it('should cancel a batch of orders', async () => {
await zeroEx.exchange.batchCancelOrderAsync(
[signedOrder, anotherSignedOrder], [cancelAmount, cancelAmount]);
const cancelledAmount = await zeroEx.exchange.getCanceledTakerAmountAsync(orderHashHex);
const anotherCancelledAmount = await zeroEx.exchange.getCanceledTakerAmountAsync(
anotherOrderHashHex);
expect(cancelledAmount).to.be.bignumber.equal(cancelAmount);
expect(anotherCancelledAmount).to.be.bignumber.equal(cancelAmount);
});
}); });
}); });
}); });