import { render, screen } from "@testing-library/react" import { afterEach, beforeEach, describe, expect, it, vi } from "vitest" import type { SelectionChart as SelectionChartData } from "../api/selection.types" const chartMocks = vi.hoisted(() => ({ disconnect: vi.fn(), dispose: vi.fn(), init: vi.fn(), observe: vi.fn(), resize: vi.fn(), setOption: vi.fn(), use: vi.fn(), })) vi.mock("echarts/charts", () => ({ BarChart: {}, CandlestickChart: {}, LineChart: {}, })) vi.mock("echarts/components", () => ({ AxisPointerComponent: {}, DataZoomComponent: {}, GridComponent: {}, LegendComponent: {}, TitleComponent: {}, TooltipComponent: {}, })) vi.mock("echarts/core", () => ({ init: chartMocks.init, use: chartMocks.use, })) vi.mock("echarts/renderers", () => ({ CanvasRenderer: {} })) import { SelectionChart } from "./selection-chart" const chart: SelectionChartData = { name: "药明康德", points: [ { close: 10.5, d: 48, high: 11, j: 60, k: 52, low: 9, open: 10, trade_date: "2026-08-08", trend_white: 10.2, trend_yellow: 10.4, volume: 1000, }, ], source_adj: "qfq", target_trade_date: "2026-08-08", ts_code: "603259.SH", } describe("SelectionChart", () => { beforeEach(() => { chartMocks.init.mockReturnValue({ dispose: chartMocks.dispose, resize: chartMocks.resize, setOption: chartMocks.setOption, }) vi.stubGlobal( "ResizeObserver", class { constructor(private readonly callback: ResizeObserverCallback) {} disconnect() { chartMocks.disconnect() } observe() { chartMocks.observe() this.callback([], this as unknown as ResizeObserver) } }, ) }) afterEach(() => { vi.unstubAllGlobals() vi.clearAllMocks() }) it("initializes, resizes, updates and disposes one chart instance", () => { const view = render() expect( screen.getByRole("img", { name: "药明康德 日线、知行黄白线、成交量和 J 线图表", }), ).toBeInTheDocument() expect(chartMocks.init).toHaveBeenCalledTimes(1) expect(chartMocks.observe).toHaveBeenCalledTimes(1) expect(chartMocks.resize).toHaveBeenCalledTimes(1) expect(chartMocks.setOption).toHaveBeenCalledTimes(1) view.rerender( , ) expect(chartMocks.setOption).toHaveBeenCalledTimes(2) view.unmount() expect(chartMocks.disconnect).toHaveBeenCalledTimes(1) expect(chartMocks.dispose).toHaveBeenCalledTimes(1) }) })