aboutsummaryrefslogtreecommitdiffstats
path: root/packages/order-utils/test
diff options
context:
space:
mode:
Diffstat (limited to 'packages/order-utils/test')
-rw-r--r--packages/order-utils/test/market_utils_test.ts146
-rw-r--r--packages/order-utils/test/utils/test_order_factory.ts63
2 files changed, 209 insertions, 0 deletions
diff --git a/packages/order-utils/test/market_utils_test.ts b/packages/order-utils/test/market_utils_test.ts
new file mode 100644
index 000000000..93779d035
--- /dev/null
+++ b/packages/order-utils/test/market_utils_test.ts
@@ -0,0 +1,146 @@
+import { OrderRelevantState, SignedOrder } from '@0xproject/types';
+import { BigNumber } from '@0xproject/utils';
+import * as chai from 'chai';
+import * as _ from 'lodash';
+import 'mocha';
+
+import { constants, marketUtils, orderFactory } from '../src';
+
+import { chaiSetup } from './utils/chai_setup';
+import { testOrderFactory } from './utils/test_order_factory';
+
+chaiSetup.configure();
+const expect = chai.expect;
+
+// tslint:disable: no-unused-expression
+describe('marketUtils', () => {
+ describe.only('#findOrdersThatCoverMakerAssetFillAmount', () => {
+ describe('no orders', () => {
+ it('returns empty and unchanged remainingFillAmount', async () => {
+ const fillAmount = new BigNumber(10);
+ const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount(
+ [],
+ [],
+ fillAmount,
+ );
+ expect(resultOrders).to.be.empty;
+ expect(remainingFillAmount).to.be.bignumber.equal(fillAmount);
+ });
+ });
+ describe('orders are all completely fillable', () => {
+ // generate three signed orders each with 10 units of makerAsset, 30 total
+ const testOrderCount = 3;
+ const makerAssetAmount = new BigNumber(10);
+ const inputOrders = testOrderFactory.generateTestSignedOrders(
+ {
+ makerAssetAmount,
+ },
+ testOrderCount,
+ );
+ // generate order states that cover the required fill amount
+ const inputOrderStates = testOrderFactory.generateTestOrderRelevantStates(
+ {
+ remainingFillableMakerAssetAmount: makerAssetAmount,
+ },
+ testOrderCount,
+ );
+ it('returns input orders and zero remainingFillAmount when input exactly matches requested fill amount', async () => {
+ // try to fill 30 units of makerAsset
+ const fillAmount = new BigNumber(30);
+ const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount(
+ inputOrders,
+ inputOrderStates,
+ fillAmount,
+ );
+ expect(resultOrders).to.be.deep.equal(inputOrders);
+ expect(remainingFillAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
+ });
+ it('returns input orders and zero remainingFillAmount when input has more than requested fill amount', async () => {
+ // try to fill 25 units of makerAsset
+ const fillAmount = new BigNumber(25);
+ const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount(
+ inputOrders,
+ inputOrderStates,
+ fillAmount,
+ );
+ expect(resultOrders).to.be.deep.equal(inputOrders);
+ expect(remainingFillAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
+ });
+ it('returns input orders and non-zero remainingFillAmount when input has less than requested fill amount', async () => {
+ // try to fill 35 units of makerAsset
+ const fillAmount = new BigNumber(35);
+ const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount(
+ inputOrders,
+ inputOrderStates,
+ fillAmount,
+ );
+ expect(resultOrders).to.be.deep.equal(inputOrders);
+ expect(remainingFillAmount).to.be.bignumber.equal(new BigNumber(5));
+ });
+ it('returns first order and zero remainingFillAmount when requested fill amount is exactly covered by the first order', async () => {
+ // try to fill 10 units of makerAsset
+ const fillAmount = new BigNumber(10);
+ const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount(
+ inputOrders,
+ inputOrderStates,
+ fillAmount,
+ );
+ expect(resultOrders).to.be.deep.equal([inputOrders[0]]);
+ expect(remainingFillAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
+ });
+ it('returns first two orders and zero remainingFillAmount when requested fill amount is over covered by the first two order', async () => {
+ // try to fill 15 units of makerAsset
+ const fillAmount = new BigNumber(15);
+ const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount(
+ inputOrders,
+ inputOrderStates,
+ fillAmount,
+ );
+ expect(resultOrders).to.be.deep.equal([inputOrders[0], inputOrders[1]]);
+ expect(remainingFillAmount).to.be.bignumber.equal(constants.ZERO_AMOUNT);
+ });
+ });
+ describe('orders are partially fillable', () => {
+ // generate three signed orders each with 10 units of makerAsset, 30 total
+ const testOrderCount = 3;
+ const makerAssetAmount = new BigNumber(10);
+ const inputOrders = testOrderFactory.generateTestSignedOrders(
+ {
+ makerAssetAmount,
+ },
+ testOrderCount,
+ );
+ // generate order states that cover different scenarios
+ // 1. order is completely filled already
+ // 2. order is partially fillable
+ // 3. order is completely fillable
+ const partialOrderStates: Array<Partial<OrderRelevantState>> = [
+ {
+ remainingFillableMakerAssetAmount: constants.ZERO_AMOUNT,
+ },
+ {
+ remainingFillableMakerAssetAmount: new BigNumber(5),
+ },
+ {
+ remainingFillableMakerAssetAmount: makerAssetAmount,
+ },
+ ];
+ const inputOrderStates: OrderRelevantState[] = _.map(
+ partialOrderStates,
+ testOrderFactory.generateTestOrderRelevantState,
+ );
+ it('returns last 2 orders and non-zero remainingFillAmount when trying to fill original makerAssetAmounts', async () => {
+ // try to fill 30 units of makerAsset
+ const fillAmount = new BigNumber(30);
+ const { resultOrders, remainingFillAmount } = marketUtils.findOrdersThatCoverMakerAssetFillAmount(
+ inputOrders,
+ inputOrderStates,
+ fillAmount,
+ );
+ expect(resultOrders).to.be.deep.equal([inputOrders[1], inputOrders[2]]);
+ expect(remainingFillAmount).to.be.bignumber.equal(new BigNumber(15));
+ });
+ });
+ });
+ describe('#findFeeOrdersThatCoverFeesForTargetOrders', () => {});
+});
diff --git a/packages/order-utils/test/utils/test_order_factory.ts b/packages/order-utils/test/utils/test_order_factory.ts
new file mode 100644
index 000000000..2c5d8cf61
--- /dev/null
+++ b/packages/order-utils/test/utils/test_order_factory.ts
@@ -0,0 +1,63 @@
+import { Order, OrderRelevantState, SignedOrder } from '@0xproject/types';
+import { BigNumber } from '@0xproject/utils';
+import * as _ from 'lodash';
+
+import { constants, orderFactory } from '../../src';
+
+const BASE_TEST_ORDER: Order = orderFactory.createOrder(
+ constants.NULL_ADDRESS,
+ constants.NULL_ADDRESS,
+ constants.NULL_ADDRESS,
+ constants.ZERO_AMOUNT,
+ constants.ZERO_AMOUNT,
+ constants.ZERO_AMOUNT,
+ constants.NULL_BYTES,
+ constants.ZERO_AMOUNT,
+ constants.NULL_BYTES,
+ constants.NULL_ADDRESS,
+ constants.NULL_ADDRESS,
+);
+const BASE_TEST_SIGNED_ORDER: SignedOrder = {
+ ...BASE_TEST_ORDER,
+ signature: constants.NULL_BYTES,
+};
+const BASE_TEST_ORDER_RELEVANT_STATE: OrderRelevantState = {
+ makerBalance: constants.ZERO_AMOUNT,
+ makerProxyAllowance: constants.ZERO_AMOUNT,
+ makerFeeBalance: constants.ZERO_AMOUNT,
+ makerFeeProxyAllowance: constants.ZERO_AMOUNT,
+ filledTakerAssetAmount: constants.ZERO_AMOUNT,
+ remainingFillableMakerAssetAmount: constants.ZERO_AMOUNT,
+ remainingFillableTakerAssetAmount: constants.ZERO_AMOUNT,
+};
+
+export const testOrderFactory = {
+ generateTestSignedOrder(partialOrder: Partial<SignedOrder>): SignedOrder {
+ return transformObject(BASE_TEST_SIGNED_ORDER, partialOrder);
+ },
+ generateTestSignedOrders(partialOrder: Partial<SignedOrder>, numOrders: number): SignedOrder[] {
+ const baseTestOrders = generateArrayOfInput(BASE_TEST_SIGNED_ORDER, numOrders);
+ return transformObjects(baseTestOrders, partialOrder);
+ },
+ generateTestOrderRelevantState(partialOrderRelevantState: Partial<OrderRelevantState>): OrderRelevantState {
+ return transformObject(BASE_TEST_ORDER_RELEVANT_STATE, partialOrderRelevantState);
+ },
+ generateTestOrderRelevantStates(
+ partialOrderRelevantState: Partial<OrderRelevantState>,
+ numOrderStates: number,
+ ): OrderRelevantState[] {
+ const baseTestOrderStates = generateArrayOfInput(BASE_TEST_ORDER_RELEVANT_STATE, numOrderStates);
+ return transformObjects(baseTestOrderStates, partialOrderRelevantState);
+ },
+};
+
+function generateArrayOfInput<T>(input: T, rangeLength: number): T[] {
+ return _.map(_.range(rangeLength), () => input);
+}
+function transformObject<T>(input: T, transformation: Partial<T>): T {
+ const copy = _.cloneDeep(input);
+ return _.assign(copy, transformation);
+}
+function transformObjects<T>(inputs: T[], transformation: Partial<T>): T[] {
+ return _.map(inputs, input => transformObject(input, transformation));
+}