chore: add market-depth-provider unit tests (#1839)
This commit is contained in:
parent
ee3b9a56c9
commit
786b85fde2
@ -7,7 +7,7 @@ import {
|
||||
ThemeContext,
|
||||
getNumberFormat,
|
||||
} from '@vegaprotocol/react-helpers';
|
||||
import dataProvider from './market-depth-provider';
|
||||
import { marketDepthProvider } from './market-depth-provider';
|
||||
import {
|
||||
useCallback,
|
||||
useEffect,
|
||||
@ -115,7 +115,7 @@ export const DepthChartContainer = ({ marketId }: DepthChartManagerProps) => {
|
||||
);
|
||||
|
||||
const { data, error, loading } = useDataProvider({
|
||||
dataProvider,
|
||||
dataProvider: marketDepthProvider,
|
||||
update,
|
||||
variables,
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
export * from './__generated___/MarketDepth';
|
||||
export * from './depth-chart';
|
||||
export * from './market-depth-provider';
|
||||
export { marketDepthProvider } from './market-depth-provider';
|
||||
export * from './orderbook-container';
|
||||
export * from './orderbook-data';
|
||||
export * from './orderbook-manager';
|
||||
|
76
libs/market-depth/src/lib/market-depth-provider.spec.ts
Normal file
76
libs/market-depth/src/lib/market-depth-provider.spec.ts
Normal file
@ -0,0 +1,76 @@
|
||||
import { update } from './market-depth-provider';
|
||||
import { captureException } from '@sentry/react';
|
||||
|
||||
const reload = jest.fn();
|
||||
jest.mock('@sentry/react', () => {
|
||||
const original = jest.requireActual('@sentry/react'); // Step 2.
|
||||
return {
|
||||
...original,
|
||||
captureException: jest.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('./orderbook-data', () => ({
|
||||
updateLevels: jest.fn((arg) => arg),
|
||||
}));
|
||||
|
||||
describe('market depth provider update', () => {
|
||||
it('omits overlapping updates', () => {
|
||||
const data = {
|
||||
id: '1',
|
||||
depth: {
|
||||
sequenceNumber: '1',
|
||||
},
|
||||
};
|
||||
const delta = {
|
||||
marketId: '2',
|
||||
sequenceNumber: '',
|
||||
previousSequenceNumber: '',
|
||||
};
|
||||
const updatedData = update(data, [delta], reload);
|
||||
expect(updatedData).toBe(data);
|
||||
});
|
||||
|
||||
it('omits not matching market', () => {
|
||||
const data = {
|
||||
id: '1',
|
||||
depth: {
|
||||
sequenceNumber: '10',
|
||||
},
|
||||
};
|
||||
const delta = [
|
||||
{
|
||||
marketId: '1',
|
||||
sequenceNumber: '5',
|
||||
previousSequenceNumber: '',
|
||||
},
|
||||
{
|
||||
marketId: '1',
|
||||
sequenceNumber: '10',
|
||||
previousSequenceNumber: '',
|
||||
},
|
||||
];
|
||||
expect(update(data, delta.slice(0, 1), reload)).toBe(data);
|
||||
expect(update(data, delta.slice(1, 2), reload)).toBe(data);
|
||||
});
|
||||
|
||||
it('restarts and captureException when there is gap in updates', () => {
|
||||
const data = {
|
||||
id: '1',
|
||||
depth: {
|
||||
sequenceNumber: '10',
|
||||
},
|
||||
};
|
||||
const delta = [
|
||||
{
|
||||
marketId: '1',
|
||||
sequenceNumber: '16',
|
||||
previousSequenceNumber: '12',
|
||||
},
|
||||
];
|
||||
const updatedData = update(data, delta, reload);
|
||||
expect(updatedData).toBe(data);
|
||||
expect(reload).toBeCalled();
|
||||
expect(captureException).toBeCalled();
|
||||
});
|
||||
});
|
@ -12,40 +12,34 @@ import type {
|
||||
MarketDepthUpdateSubscription,
|
||||
} from './__generated___/MarketDepth';
|
||||
|
||||
const sequenceNumbers: Record<string, number> = {};
|
||||
|
||||
const update: Update<
|
||||
export const update: Update<
|
||||
ReturnType<typeof getData>,
|
||||
ReturnType<typeof getDelta>
|
||||
> = (data, deltas, reload) => {
|
||||
if (!data) {
|
||||
return;
|
||||
return data;
|
||||
}
|
||||
for (const delta of deltas) {
|
||||
if (delta.marketId !== data.id) {
|
||||
continue;
|
||||
}
|
||||
const currentSequenceNumber = Number(delta.sequenceNumber);
|
||||
if (currentSequenceNumber <= sequenceNumbers[delta.marketId]) {
|
||||
if (Number(delta.sequenceNumber) <= Number(data.depth.sequenceNumber)) {
|
||||
return data;
|
||||
}
|
||||
if (
|
||||
delta.previousSequenceNumber !==
|
||||
sequenceNumbers[delta.marketId].toString()
|
||||
) {
|
||||
if (delta.previousSequenceNumber !== data.depth.sequenceNumber) {
|
||||
captureException(
|
||||
new Error(
|
||||
`Sequence number gap in marketsDepthUpdate for {data.id}, {sequenceNumbers[delta.marketId]} - {delta.previousSequenceNumber}`
|
||||
)
|
||||
);
|
||||
delete sequenceNumbers[delta.marketId];
|
||||
reload();
|
||||
return;
|
||||
return data;
|
||||
}
|
||||
sequenceNumbers[delta.marketId] = Number(currentSequenceNumber);
|
||||
const updatedData = {
|
||||
...data,
|
||||
depth: { ...data.depth },
|
||||
depth: {
|
||||
...data.depth,
|
||||
},
|
||||
};
|
||||
if (delta.buy) {
|
||||
updatedData.depth.buy = updateLevels(data.depth.buy ?? [], delta.buy);
|
||||
@ -53,19 +47,14 @@ const update: Update<
|
||||
if (delta.sell) {
|
||||
updatedData.depth.sell = updateLevels(data.depth.sell ?? [], delta.sell);
|
||||
}
|
||||
updatedData.depth.sequenceNumber = delta.sequenceNumber;
|
||||
return updatedData;
|
||||
}
|
||||
return data;
|
||||
};
|
||||
|
||||
const getData = (responseData: MarketDepthQuery) => {
|
||||
if (responseData.market?.id) {
|
||||
sequenceNumbers[responseData.market.id] = Number(
|
||||
responseData.market.depth.sequenceNumber
|
||||
);
|
||||
}
|
||||
return responseData.market;
|
||||
};
|
||||
const getData = (responseData: MarketDepthQuery) => responseData.market;
|
||||
|
||||
const getDelta = (subscriptionData: MarketDepthUpdateSubscription) =>
|
||||
subscriptionData.marketsDepthUpdate;
|
||||
|
||||
@ -76,5 +65,3 @@ export const marketDepthProvider = makeDataProvider({
|
||||
getData,
|
||||
getDelta,
|
||||
});
|
||||
|
||||
export default marketDepthProvider;
|
||||
|
@ -2,7 +2,7 @@ import throttle from 'lodash/throttle';
|
||||
import { AsyncRenderer } from '@vegaprotocol/ui-toolkit';
|
||||
import { Orderbook } from './orderbook';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import marketDepthProvider from './market-depth-provider';
|
||||
import { marketDepthProvider } from './market-depth-provider';
|
||||
import { marketDataProvider, marketProvider } from '@vegaprotocol/market-list';
|
||||
import type { MarketData } from '@vegaprotocol/market-list';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import throttle from 'lodash/throttle';
|
||||
import { useDataProvider } from '@vegaprotocol/react-helpers';
|
||||
import dataProvider from './market-depth-provider';
|
||||
import { marketDepthProvider } from './market-depth-provider';
|
||||
import type { MarketDepthQuery } from './__generated___/MarketDepth';
|
||||
|
||||
interface Props {
|
||||
@ -39,7 +39,7 @@ export const useOrderBookData = ({
|
||||
);
|
||||
|
||||
const { data, error, loading } = useDataProvider({
|
||||
dataProvider,
|
||||
dataProvider: marketDepthProvider,
|
||||
update,
|
||||
variables,
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user