Merge branch 'development' into feature/bignumber-8.0
This commit is contained in:
@@ -8,6 +8,24 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "4.1.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Adds new public method getLiquidityForAssetDataAsync, and exposes getOrdersAndFillableAmountsAsync as public method",
|
||||
"pr": 1512
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1547747677,
|
||||
"version": "4.0.2",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Dependencies updated"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1547561734,
|
||||
"version": "4.0.1",
|
||||
|
||||
@@ -5,6 +5,10 @@ Edit the package's CHANGELOG.json file only.
|
||||
|
||||
CHANGELOG
|
||||
|
||||
## v4.0.2 - _January 17, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
## v4.0.1 - _January 15, 2019_
|
||||
|
||||
* Dependencies updated
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@0x/asset-buyer",
|
||||
"version": "4.0.1",
|
||||
"version": "4.0.2",
|
||||
"engines": {
|
||||
"node": ">=6.12"
|
||||
},
|
||||
@@ -38,7 +38,7 @@
|
||||
"dependencies": {
|
||||
"@0x/assert": "^1.0.23",
|
||||
"@0x/connect": "^3.0.13",
|
||||
"@0x/contract-wrappers": "^5.0.0",
|
||||
"@0x/contract-wrappers": "^5.0.1",
|
||||
"@0x/json-schemas": "^2.1.7",
|
||||
"@0x/order-utils": "^3.1.2",
|
||||
"@0x/subproviders": "^2.1.11",
|
||||
@@ -65,6 +65,7 @@
|
||||
"shx": "^0.2.2",
|
||||
"tslint": "5.11.0",
|
||||
"typedoc": "0.13.0",
|
||||
"typemoq": "^2.1.0",
|
||||
"typescript": "3.0.1"
|
||||
},
|
||||
"publishConfig": {
|
||||
|
||||
@@ -16,14 +16,16 @@ import {
|
||||
BuyQuote,
|
||||
BuyQuoteExecutionOpts,
|
||||
BuyQuoteRequestOpts,
|
||||
LiquidityForAssetData,
|
||||
LiquidityRequestOpts,
|
||||
OrderProvider,
|
||||
OrderProviderResponse,
|
||||
OrdersAndFillableAmounts,
|
||||
} from './types';
|
||||
|
||||
import { assert } from './utils/assert';
|
||||
import { assetDataUtils } from './utils/asset_data_utils';
|
||||
import { buyQuoteCalculator } from './utils/buy_quote_calculator';
|
||||
import { calculateLiquidity } from './utils/calculate_liquidity';
|
||||
import { orderProviderResponseProcessor } from './utils/order_provider_response_processor';
|
||||
|
||||
interface OrdersEntry {
|
||||
@@ -138,10 +140,10 @@ export class AssetBuyer {
|
||||
// get the relevant orders for the makerAsset and fees
|
||||
// if the requested assetData is ZRX, don't get the fee info
|
||||
const [ordersAndFillableAmounts, feeOrdersAndFillableAmounts] = await Promise.all([
|
||||
this._getOrdersAndFillableAmountsAsync(assetData, shouldForceOrderRefresh),
|
||||
this.getOrdersAndFillableAmountsAsync(assetData, shouldForceOrderRefresh),
|
||||
isMakerAssetZrxToken
|
||||
? Promise.resolve(constants.EMPTY_ORDERS_AND_FILLABLE_AMOUNTS)
|
||||
: this._getOrdersAndFillableAmountsAsync(zrxTokenAssetData, shouldForceOrderRefresh),
|
||||
: this.getOrdersAndFillableAmountsAsync(zrxTokenAssetData, shouldForceOrderRefresh),
|
||||
shouldForceOrderRefresh,
|
||||
]);
|
||||
if (ordersAndFillableAmounts.orders.length === 0) {
|
||||
@@ -177,6 +179,40 @@ export class AssetBuyer {
|
||||
const buyQuote = this.getBuyQuoteAsync(assetData, assetBuyAmount, options);
|
||||
return buyQuote;
|
||||
}
|
||||
/**
|
||||
* Returns information about available liquidity for an asset
|
||||
* Does not factor in slippage or fees
|
||||
* @param assetData The assetData of the desired asset to buy (for more info: https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md).
|
||||
* @param options Options for the request. See type definition for more information.
|
||||
*
|
||||
* @return An object that conforms to LiquidityForAssetData that satisfies the request. See type definition for more information.
|
||||
*/
|
||||
public async getLiquidityForAssetDataAsync(
|
||||
assetData: string,
|
||||
options: Partial<LiquidityRequestOpts> = {},
|
||||
): Promise<LiquidityForAssetData> {
|
||||
const shouldForceOrderRefresh =
|
||||
options.shouldForceOrderRefresh !== undefined ? options.shouldForceOrderRefresh : false;
|
||||
assetDataUtils.decodeAssetDataOrThrow(assetData);
|
||||
assert.isBoolean('options.shouldForceOrderRefresh', shouldForceOrderRefresh);
|
||||
|
||||
const assetPairs = await this.orderProvider.getAvailableMakerAssetDatasAsync(assetData);
|
||||
const etherTokenAssetData = this._getEtherTokenAssetDataOrThrow();
|
||||
if (!assetPairs.includes(etherTokenAssetData)) {
|
||||
return {
|
||||
tokensAvailableInBaseUnits: new BigNumber(0),
|
||||
ethValueAvailableInWei: new BigNumber(0),
|
||||
};
|
||||
}
|
||||
|
||||
const ordersAndFillableAmounts = await this.getOrdersAndFillableAmountsAsync(
|
||||
assetData,
|
||||
shouldForceOrderRefresh,
|
||||
);
|
||||
|
||||
return calculateLiquidity(ordersAndFillableAmounts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a BuyQuote and desired rate, attempt to execute the buy.
|
||||
* @param buyQuote An object that conforms to BuyQuote. See type definition for more information.
|
||||
@@ -260,8 +296,10 @@ export class AssetBuyer {
|
||||
}
|
||||
/**
|
||||
* Grab orders from the map, if there is a miss or it is time to refresh, fetch and process the orders
|
||||
* @param assetData The assetData of the desired asset to buy (for more info: https://github.com/0xProject/0x-protocol-specification/blob/master/v2/v2-specification.md).
|
||||
* @param shouldForceOrderRefresh If set to true, new orders and state will be fetched instead of waiting for the next orderRefreshIntervalMs.
|
||||
*/
|
||||
private async _getOrdersAndFillableAmountsAsync(
|
||||
public async getOrdersAndFillableAmountsAsync(
|
||||
assetData: string,
|
||||
shouldForceOrderRefresh: boolean,
|
||||
): Promise<OrdersAndFillableAmounts> {
|
||||
|
||||
@@ -19,6 +19,9 @@ export {
|
||||
BuyQuoteExecutionOpts,
|
||||
BuyQuoteInfo,
|
||||
BuyQuoteRequestOpts,
|
||||
LiquidityForAssetData,
|
||||
LiquidityRequestOpts,
|
||||
OrdersAndFillableAmounts,
|
||||
OrderProvider,
|
||||
OrderProviderRequest,
|
||||
OrderProviderResponse,
|
||||
|
||||
@@ -75,6 +75,13 @@ export interface BuyQuoteRequestOpts {
|
||||
slippagePercentage: number;
|
||||
}
|
||||
|
||||
/*
|
||||
* Options for checking liquidity
|
||||
*
|
||||
* shouldForceOrderRefresh: If set to true, new orders and state will be fetched instead of waiting for the next orderRefreshIntervalMs. Defaults to false.
|
||||
*/
|
||||
export type LiquidityRequestOpts = Pick<BuyQuoteRequestOpts, 'shouldForceOrderRefresh'>;
|
||||
|
||||
/**
|
||||
* ethAmount: The desired amount of eth to spend. Defaults to buyQuote.worstCaseQuoteInfo.totalEthAmount.
|
||||
* takerAddress: The address to perform the buy. Defaults to the first available address from the provider.
|
||||
@@ -117,7 +124,19 @@ export enum AssetBuyerError {
|
||||
TransactionValueTooLow = 'TRANSACTION_VALUE_TOO_LOW',
|
||||
}
|
||||
|
||||
/**
|
||||
* orders: An array of signed orders
|
||||
* remainingFillableMakerAssetAmounts: A list of fillable amounts for the signed orders. The index of an item in the array associates the amount with the corresponding order.
|
||||
*/
|
||||
export interface OrdersAndFillableAmounts {
|
||||
orders: SignedOrder[];
|
||||
remainingFillableMakerAssetAmounts: BigNumber[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents available liquidity for a given assetData
|
||||
*/
|
||||
export interface LiquidityForAssetData {
|
||||
tokensAvailableInBaseUnits: BigNumber;
|
||||
ethValueAvailableInWei: BigNumber;
|
||||
}
|
||||
|
||||
34
packages/asset-buyer/src/utils/calculate_liquidity.ts
Normal file
34
packages/asset-buyer/src/utils/calculate_liquidity.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { BigNumber } from '@0x/utils';
|
||||
|
||||
import { LiquidityForAssetData, OrdersAndFillableAmounts } from '../types';
|
||||
|
||||
import { orderUtils } from './order_utils';
|
||||
|
||||
export const calculateLiquidity = (ordersAndFillableAmounts: OrdersAndFillableAmounts): LiquidityForAssetData => {
|
||||
const { orders, remainingFillableMakerAssetAmounts } = ordersAndFillableAmounts;
|
||||
const liquidityInBigNumbers = orders.reduce(
|
||||
(acc, order, curIndex) => {
|
||||
const availableMakerAssetAmount = remainingFillableMakerAssetAmounts[curIndex];
|
||||
if (availableMakerAssetAmount === undefined) {
|
||||
throw new Error(`No corresponding fillableMakerAssetAmounts at index ${curIndex}`);
|
||||
}
|
||||
|
||||
const tokensAvailableForCurrentOrder = availableMakerAssetAmount;
|
||||
const ethValueAvailableForCurrentOrder = orderUtils.getTakerFillAmount(order, availableMakerAssetAmount);
|
||||
return {
|
||||
tokensAvailableInBaseUnits: acc.tokensAvailableInBaseUnits.plus(tokensAvailableForCurrentOrder),
|
||||
ethValueAvailableInWei: acc.ethValueAvailableInWei.plus(ethValueAvailableForCurrentOrder),
|
||||
};
|
||||
},
|
||||
{
|
||||
tokensAvailableInBaseUnits: new BigNumber(0),
|
||||
ethValueAvailableInWei: new BigNumber(0),
|
||||
},
|
||||
);
|
||||
|
||||
// Turn into regular numbers
|
||||
return {
|
||||
tokensAvailableInBaseUnits: liquidityInBigNumbers.tokensAvailableInBaseUnits,
|
||||
ethValueAvailableInWei: liquidityInBigNumbers.ethValueAvailableInWei,
|
||||
};
|
||||
};
|
||||
212
packages/asset-buyer/test/asset_buyer_test.ts
Normal file
212
packages/asset-buyer/test/asset_buyer_test.ts
Normal file
@@ -0,0 +1,212 @@
|
||||
import { orderFactory } from '@0x/order-utils/lib/src/order_factory';
|
||||
import { Web3ProviderEngine } from '@0x/subproviders';
|
||||
import { SignedOrder } from '@0x/types';
|
||||
import { BigNumber } from '@0x/utils';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import * as chai from 'chai';
|
||||
import 'mocha';
|
||||
import * as TypeMoq from 'typemoq';
|
||||
|
||||
import { AssetBuyer } from '../src';
|
||||
import { constants } from '../src/constants';
|
||||
import { LiquidityForAssetData, OrderProvider, OrdersAndFillableAmounts } from '../src/types';
|
||||
|
||||
import { chaiSetup } from './utils/chai_setup';
|
||||
import {
|
||||
mockAvailableAssetDatas,
|
||||
mockedAssetBuyerWithOrdersAndFillableAmounts,
|
||||
orderProviderMock,
|
||||
} from './utils/mocks';
|
||||
|
||||
chaiSetup.configure();
|
||||
const expect = chai.expect;
|
||||
|
||||
const FAKE_SRA_URL = 'https://fakeurl.com';
|
||||
const FAKE_ASSET_DATA = '0xf47261b00000000000000000000000001dc4c1cefef38a777b15aa20260a54e584b16c48';
|
||||
const TOKEN_DECIMALS = 18;
|
||||
const DAI_ASSET_DATA = '0xf47261b000000000000000000000000089d24a6b4ccb1b6faa2625fe562bdd9a23260359"';
|
||||
const WETH_ASSET_DATA = '0xf47261b0000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2';
|
||||
const WETH_DECIMALS = constants.ETHER_TOKEN_DECIMALS;
|
||||
|
||||
const baseUnitAmount = (unitAmount: number, decimals = TOKEN_DECIMALS): BigNumber => {
|
||||
return Web3Wrapper.toBaseUnitAmount(new BigNumber(unitAmount), decimals);
|
||||
};
|
||||
|
||||
const expectLiquidityResult = async (
|
||||
web3Provider: Web3ProviderEngine,
|
||||
orderProvider: OrderProvider,
|
||||
ordersAndFillableAmounts: OrdersAndFillableAmounts,
|
||||
expectedLiquidityResult: LiquidityForAssetData,
|
||||
) => {
|
||||
const mockedAssetBuyer = mockedAssetBuyerWithOrdersAndFillableAmounts(
|
||||
web3Provider,
|
||||
orderProvider,
|
||||
FAKE_ASSET_DATA,
|
||||
ordersAndFillableAmounts,
|
||||
);
|
||||
const liquidityResult = await mockedAssetBuyer.object.getLiquidityForAssetDataAsync(FAKE_ASSET_DATA);
|
||||
expect(liquidityResult).to.deep.equal(expectedLiquidityResult);
|
||||
};
|
||||
|
||||
// tslint:disable:custom-no-magic-numbers
|
||||
describe('AssetBuyer', () => {
|
||||
describe('getLiquidityForAssetDataAsync', () => {
|
||||
const mockWeb3Provider = TypeMoq.Mock.ofType(Web3ProviderEngine);
|
||||
const mockOrderProvider = orderProviderMock();
|
||||
|
||||
beforeEach(() => {
|
||||
mockWeb3Provider.reset();
|
||||
mockOrderProvider.reset();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mockWeb3Provider.verifyAll();
|
||||
mockOrderProvider.verifyAll();
|
||||
});
|
||||
|
||||
describe('validation', () => {
|
||||
it('should ensure assetData is a string', async () => {
|
||||
const assetBuyer = AssetBuyer.getAssetBuyerForStandardRelayerAPIUrl(
|
||||
mockWeb3Provider.object,
|
||||
FAKE_SRA_URL,
|
||||
);
|
||||
|
||||
expect(assetBuyer.getLiquidityForAssetDataAsync(false as any)).to.be.rejectedWith(
|
||||
'Expected assetData to be of type string, encountered: false',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('asset pair not supported', () => {
|
||||
it('should return 0s when no asset pair not supported', async () => {
|
||||
mockAvailableAssetDatas(mockOrderProvider, FAKE_ASSET_DATA, []);
|
||||
|
||||
const assetBuyer = new AssetBuyer(mockWeb3Provider.object, mockOrderProvider.object);
|
||||
const liquidityResult = await assetBuyer.getLiquidityForAssetDataAsync(FAKE_ASSET_DATA);
|
||||
expect(liquidityResult).to.deep.equal({
|
||||
tokensAvailableInBaseUnits: new BigNumber(0),
|
||||
ethValueAvailableInWei: new BigNumber(0),
|
||||
});
|
||||
});
|
||||
it('should return 0s when only other asset pair supported', async () => {
|
||||
mockAvailableAssetDatas(mockOrderProvider, FAKE_ASSET_DATA, [DAI_ASSET_DATA]);
|
||||
|
||||
const assetBuyer = new AssetBuyer(mockWeb3Provider.object, mockOrderProvider.object);
|
||||
const liquidityResult = await assetBuyer.getLiquidityForAssetDataAsync(FAKE_ASSET_DATA);
|
||||
expect(liquidityResult).to.deep.equal({
|
||||
tokensAvailableInBaseUnits: new BigNumber(0),
|
||||
ethValueAvailableInWei: new BigNumber(0),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('assetData is supported', () => {
|
||||
// orders
|
||||
const sellTwoTokensFor1Weth: SignedOrder = orderFactory.createSignedOrderFromPartial({
|
||||
makerAssetAmount: baseUnitAmount(2),
|
||||
takerAssetAmount: baseUnitAmount(1, WETH_DECIMALS),
|
||||
});
|
||||
const sellTenTokensFor10Weth: SignedOrder = orderFactory.createSignedOrderFromPartial({
|
||||
makerAssetAmount: baseUnitAmount(10),
|
||||
takerAssetAmount: baseUnitAmount(10, WETH_DECIMALS),
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
mockAvailableAssetDatas(mockOrderProvider, FAKE_ASSET_DATA, [WETH_ASSET_DATA]);
|
||||
});
|
||||
|
||||
it('should return 0s when no orders available', async () => {
|
||||
const ordersAndFillableAmounts: OrdersAndFillableAmounts = {
|
||||
orders: [],
|
||||
remainingFillableMakerAssetAmounts: [],
|
||||
};
|
||||
const expectedResult = {
|
||||
tokensAvailableInBaseUnits: new BigNumber(0),
|
||||
ethValueAvailableInWei: new BigNumber(0),
|
||||
};
|
||||
await expectLiquidityResult(
|
||||
mockWeb3Provider.object,
|
||||
mockOrderProvider.object,
|
||||
ordersAndFillableAmounts,
|
||||
expectedResult,
|
||||
);
|
||||
});
|
||||
|
||||
it('should return correct computed value when orders provided with full fillableAmounts', async () => {
|
||||
const orders: SignedOrder[] = [sellTwoTokensFor1Weth, sellTenTokensFor10Weth];
|
||||
const ordersAndFillableAmounts = {
|
||||
orders: [sellTwoTokensFor1Weth, sellTenTokensFor10Weth],
|
||||
remainingFillableMakerAssetAmounts: orders.map(o => o.makerAssetAmount),
|
||||
};
|
||||
|
||||
const expectedTokensAvailable = orders[0].makerAssetAmount.plus(orders[1].makerAssetAmount);
|
||||
const expectedEthValueAvailable = orders[0].takerAssetAmount.plus(orders[1].takerAssetAmount);
|
||||
const expectedResult = {
|
||||
tokensAvailableInBaseUnits: expectedTokensAvailable,
|
||||
ethValueAvailableInWei: expectedEthValueAvailable,
|
||||
};
|
||||
|
||||
await expectLiquidityResult(
|
||||
mockWeb3Provider.object,
|
||||
mockOrderProvider.object,
|
||||
ordersAndFillableAmounts,
|
||||
expectedResult,
|
||||
);
|
||||
});
|
||||
|
||||
it('should return correct computed value with one partial fillableAmounts', async () => {
|
||||
const ordersAndFillableAmounts = {
|
||||
orders: [sellTwoTokensFor1Weth],
|
||||
remainingFillableMakerAssetAmounts: [baseUnitAmount(1)],
|
||||
};
|
||||
const expectedResult = {
|
||||
tokensAvailableInBaseUnits: baseUnitAmount(1),
|
||||
ethValueAvailableInWei: baseUnitAmount(0.5, WETH_DECIMALS),
|
||||
};
|
||||
|
||||
await expectLiquidityResult(
|
||||
mockWeb3Provider.object,
|
||||
mockOrderProvider.object,
|
||||
ordersAndFillableAmounts,
|
||||
expectedResult,
|
||||
);
|
||||
});
|
||||
|
||||
it('should return correct computed value with multiple orders and fillable amounts', async () => {
|
||||
const ordersAndFillableAmounts = {
|
||||
orders: [sellTwoTokensFor1Weth, sellTenTokensFor10Weth],
|
||||
remainingFillableMakerAssetAmounts: [baseUnitAmount(1), baseUnitAmount(3)],
|
||||
};
|
||||
const expectedResult = {
|
||||
tokensAvailableInBaseUnits: baseUnitAmount(4),
|
||||
ethValueAvailableInWei: baseUnitAmount(3.5, WETH_DECIMALS),
|
||||
};
|
||||
|
||||
await expectLiquidityResult(
|
||||
mockWeb3Provider.object,
|
||||
mockOrderProvider.object,
|
||||
ordersAndFillableAmounts,
|
||||
expectedResult,
|
||||
);
|
||||
});
|
||||
|
||||
it('should return 0s when no amounts fillable', async () => {
|
||||
const ordersAndFillableAmounts = {
|
||||
orders: [sellTwoTokensFor1Weth, sellTenTokensFor10Weth],
|
||||
remainingFillableMakerAssetAmounts: [baseUnitAmount(0), baseUnitAmount(0)],
|
||||
};
|
||||
const expectedResult = {
|
||||
tokensAvailableInBaseUnits: baseUnitAmount(0),
|
||||
ethValueAvailableInWei: baseUnitAmount(0, WETH_DECIMALS),
|
||||
};
|
||||
|
||||
await expectLiquidityResult(
|
||||
mockWeb3Provider.object,
|
||||
mockOrderProvider.object,
|
||||
ordersAndFillableAmounts,
|
||||
expectedResult,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -168,7 +168,7 @@ describe('buyQuoteCalculator', () => {
|
||||
};
|
||||
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(1));
|
||||
});
|
||||
it('should throw without amount available to fill if amount rounds to 0', () => {
|
||||
it('should throw with 0 available to fill if amount rounds to 0', () => {
|
||||
const smallOrder = orderFactory.createSignedOrderFromPartial({
|
||||
makerAssetAmount: new BigNumber(1),
|
||||
takerAssetAmount: new BigNumber(1),
|
||||
@@ -184,7 +184,7 @@ describe('buyQuoteCalculator', () => {
|
||||
false,
|
||||
);
|
||||
};
|
||||
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, undefined);
|
||||
testHelpers.expectInsufficientLiquidityError(expect, errorFunction, new BigNumber(0));
|
||||
});
|
||||
});
|
||||
it('should not throw if order is fillable', () => {
|
||||
|
||||
68
packages/asset-buyer/test/utils/mocks.ts
Normal file
68
packages/asset-buyer/test/utils/mocks.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { Web3ProviderEngine } from '@0x/subproviders';
|
||||
import * as TypeMoq from 'typemoq';
|
||||
|
||||
import { AssetBuyer } from '../../src/asset_buyer';
|
||||
import { OrderProvider, OrderProviderResponse, OrdersAndFillableAmounts } from '../../src/types';
|
||||
|
||||
// tslint:disable:promise-function-async
|
||||
|
||||
// Implementing dummy class for using in mocks, see https://github.com/florinn/typemoq/issues/3
|
||||
class OrderProviderClass implements OrderProvider {
|
||||
// tslint:disable-next-line:prefer-function-over-method
|
||||
public async getOrdersAsync(): Promise<OrderProviderResponse> {
|
||||
return Promise.resolve({ orders: [] });
|
||||
}
|
||||
// tslint:disable-next-line:prefer-function-over-method
|
||||
public async getAvailableMakerAssetDatasAsync(takerAssetData: string): Promise<string[]> {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
}
|
||||
|
||||
export const orderProviderMock = () => {
|
||||
return TypeMoq.Mock.ofType(OrderProviderClass, TypeMoq.MockBehavior.Strict);
|
||||
};
|
||||
|
||||
export const mockAvailableAssetDatas = (
|
||||
mockOrderProvider: TypeMoq.IMock<OrderProviderClass>,
|
||||
assetData: string,
|
||||
availableAssetDatas: string[],
|
||||
) => {
|
||||
mockOrderProvider
|
||||
.setup(op => op.getAvailableMakerAssetDatasAsync(TypeMoq.It.isValue(assetData)))
|
||||
.returns(() => {
|
||||
return Promise.resolve(availableAssetDatas);
|
||||
})
|
||||
.verifiable(TypeMoq.Times.once());
|
||||
};
|
||||
|
||||
const partiallyMockedAssetBuyer = (
|
||||
provider: Web3ProviderEngine,
|
||||
orderProvider: OrderProvider,
|
||||
): TypeMoq.IMock<AssetBuyer> => {
|
||||
const rawAssetBuyer = new AssetBuyer(provider, orderProvider);
|
||||
const mockedAssetBuyer = TypeMoq.Mock.ofInstance(rawAssetBuyer, TypeMoq.MockBehavior.Loose, false);
|
||||
mockedAssetBuyer.callBase = true;
|
||||
return mockedAssetBuyer;
|
||||
};
|
||||
|
||||
const mockGetOrdersAndAvailableAmounts = (
|
||||
mockedAssetBuyer: TypeMoq.IMock<AssetBuyer>,
|
||||
assetData: string,
|
||||
ordersAndFillableAmounts: OrdersAndFillableAmounts,
|
||||
): void => {
|
||||
mockedAssetBuyer
|
||||
.setup(a => a.getOrdersAndFillableAmountsAsync(assetData, false))
|
||||
.returns(() => Promise.resolve(ordersAndFillableAmounts))
|
||||
.verifiable(TypeMoq.Times.once());
|
||||
};
|
||||
|
||||
export const mockedAssetBuyerWithOrdersAndFillableAmounts = (
|
||||
provider: Web3ProviderEngine,
|
||||
orderProvider: OrderProvider,
|
||||
assetData: string,
|
||||
ordersAndFillableAmounts: OrdersAndFillableAmounts,
|
||||
): TypeMoq.IMock<AssetBuyer> => {
|
||||
const mockedAssetBuyer = partiallyMockedAssetBuyer(provider, orderProvider);
|
||||
mockGetOrdersAndAvailableAmounts(mockedAssetBuyer, assetData, ordersAndFillableAmounts);
|
||||
return mockedAssetBuyer;
|
||||
};
|
||||
@@ -6,7 +6,7 @@ export const testHelpers = {
|
||||
expectInsufficientLiquidityError: (
|
||||
expect: Chai.ExpectStatic,
|
||||
functionWhichTriggersError: () => void,
|
||||
expectedAmountAvailableToFill?: BigNumber,
|
||||
expectedAmountAvailableToFill: BigNumber,
|
||||
): void => {
|
||||
let wasErrorThrown = false;
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user