Загрузка данных
import { BehaviorSubject } from 'rxjs';
import type { BaseDrawingParams } from '@core/Drawings/SeriesDrawingBase';
import type { CanvasRenderingTarget2D } from 'fancy-canvas';
import type { Coordinate, Logical, Time } from 'lightweight-charts';
interface EnvironmentOptions {
selected?: boolean;
locked?: boolean;
seriesData?: readonly unknown[];
width?: number;
height?: number;
}
export function createDrawingTestEnvironment({
selected = false,
locked = false,
seriesData = [],
width = 400,
height = 300,
}: EnvironmentOptions = {}) {
let selectedValue = selected;
let lockedValue = locked;
const selected$ = new BehaviorSubject(selected);
const locked$ = new BehaviorSubject(locked);
const interaction = {
selected$,
locked$,
isSelected: jest.fn(() => selectedValue),
isLocked: jest.fn(() => lockedValue),
select: jest.fn(() => {
selectedValue = true;
selected$.next(true);
}),
deselect: jest.fn(() => {
selectedValue = false;
selected$.next(false);
}),
} as unknown as BaseDrawingParams['interaction'];
const container = document.createElement('div');
jest.spyOn(container, 'getBoundingClientRect').mockReturnValue({
x: 0,
y: 0,
left: 0,
top: 0,
right: width,
bottom: height,
width,
height,
toJSON: jest.fn(),
});
const coordinateToTime = jest.fn((coordinate: Coordinate): Time | null => Number(coordinate) as Time);
const timeToCoordinate = jest.fn((time: Time): Coordinate | null => Number(time) as Coordinate);
const coordinateToLogical = jest.fn((coordinate: Coordinate): Logical | null => Number(coordinate) as Logical);
const logicalToCoordinate = jest.fn((logical: Logical): Coordinate | null => Number(logical) as Coordinate);
const timeScale = {
coordinateToTime,
timeToCoordinate,
coordinateToLogical,
logicalToCoordinate,
getVisibleLogicalRange: jest.fn(() => ({
from: 0 as Logical,
to: Math.max(seriesData.length - 1, 0) as Logical,
})),
subscribeVisibleLogicalRangeChange: jest.fn(),
unsubscribeVisibleLogicalRangeChange: jest.fn(),
};
const pane = {
paneIndex: jest.fn(() => 0),
getHeight: jest.fn(() => height),
};
const chart = {
timeScale: jest.fn(() => timeScale),
applyOptions: jest.fn(),
panes: jest.fn(() => [pane]),
subscribeClick: jest.fn(),
unsubscribeClick: jest.fn(),
subscribeCrosshairMove: jest.fn(),
unsubscribeCrosshairMove: jest.fn(),
} as unknown as BaseDrawingParams['chart'];
const coordinateToPrice = jest.fn((coordinate: Coordinate): number | null => Number(coordinate));
const priceToCoordinate = jest.fn((price: number): Coordinate | null => price as Coordinate);
const series = {
coordinateToPrice,
priceToCoordinate,
data: jest.fn(() => seriesData),
attachPrimitive: jest.fn(),
detachPrimitive: jest.fn(),
getPane: jest.fn(() => pane),
} as unknown as BaseDrawingParams['series'];
return {
chart,
series,
container,
interaction,
timeScale,
pane,
coordinateToPrice,
priceToCoordinate,
setSelected(value: boolean) {
selectedValue = value;
selected$.next(value);
},
setLocked(value: boolean) {
lockedValue = value;
locked$.next(value);
},
};
}
export function createPointerEvent(
target: Node,
x: number,
y: number,
pointerId = 1,
button = 0,
): PointerEvent {
return {
target,
clientX: x,
clientY: y,
pointerId,
button,
preventDefault: jest.fn(),
stopPropagation: jest.fn(),
} as unknown as PointerEvent;
}
export function createMouseEvent(target: Node, x: number, y: number, detail = 1): MouseEvent {
return {
target,
clientX: x,
clientY: y,
detail,
preventDefault: jest.fn(),
stopPropagation: jest.fn(),
} as unknown as MouseEvent;
}
export function createCanvasTarget() {
const context = {
canvas: {
width: 800,
height: 600,
},
save: jest.fn(),
restore: jest.fn(),
beginPath: jest.fn(),
closePath: jest.fn(),
moveTo: jest.fn(),
lineTo: jest.fn(),
quadraticCurveTo: jest.fn(),
arc: jest.fn(),
arcTo: jest.fn(),
rect: jest.fn(),
clip: jest.fn(),
fill: jest.fn(),
stroke: jest.fn(),
fillRect: jest.fn(),
strokeRect: jest.fn(),
fillText: jest.fn(),
setLineDash: jest.fn(),
translate: jest.fn(),
rotate: jest.fn(),
measureText: jest.fn((text: string) => ({
width: text.length * 8,
})),
fillStyle: '',
strokeStyle: '',
lineWidth: 0,
globalAlpha: 1,
font: '',
textAlign: 'start',
textBaseline: 'alphabetic',
};
const useBitmapCoordinateSpace = jest.fn(
(
callback: (scope: {
context: CanvasRenderingContext2D;
horizontalPixelRatio: number;
verticalPixelRatio: number;
bitmapSize: {
width: number;
height: number;
};
}) => void,
) => {
callback({
context: context as unknown as CanvasRenderingContext2D,
horizontalPixelRatio: 2,
verticalPixelRatio: 2,
bitmapSize: {
width: 800,
height: 600,
},
});
},
);
return {
context,
useBitmapCoordinateSpace,
target: {
useBitmapCoordinateSpace,
} as unknown as CanvasRenderingTarget2D,
};
}