100 lines
3.1 KiB
TypeScript
100 lines
3.1 KiB
TypeScript
import { describe, expect, it } from "vitest"
|
|
|
|
import type { SelectionChartPoint } from "../api/selection.types"
|
|
import { buildSelectionChartOption } from "./selection-chart-option"
|
|
|
|
function point(index: number): SelectionChartPoint {
|
|
return {
|
|
close: index + 10.5,
|
|
d: index + 20,
|
|
high: index + 11,
|
|
j: index + 30,
|
|
k: index + 10,
|
|
low: index + 9,
|
|
open: index + 10,
|
|
trade_date: `2026-${String(Math.floor(index / 28) + 1).padStart(2, "0")}-${String((index % 28) + 1).padStart(2, "0")}`,
|
|
trend_white: index + 10.2,
|
|
trend_yellow: index + 10.4,
|
|
volume: index + 1000,
|
|
}
|
|
}
|
|
|
|
describe("selection chart option", () => {
|
|
it("aligns all three grids and opens on exactly the last 120 points", () => {
|
|
const points = Array.from({ length: 250 }, (_, index) => point(index))
|
|
const option = buildSelectionChartOption(points)
|
|
const dataZoom = option.dataZoom as Array<{
|
|
endValue: string
|
|
startValue: string
|
|
xAxisIndex: number[]
|
|
}>
|
|
const series = option.series as Array<{
|
|
data: unknown[]
|
|
name: string
|
|
xAxisIndex: number
|
|
yAxisIndex: number
|
|
}>
|
|
const legends = option.legend as Array<{ data: string[] }>
|
|
|
|
expect(dataZoom).toHaveLength(2)
|
|
expect(dataZoom[0]).toMatchObject({
|
|
endValue: points[249].trade_date,
|
|
startValue: points[130].trade_date,
|
|
xAxisIndex: [0, 1, 2],
|
|
})
|
|
expect(dataZoom[1].xAxisIndex).toEqual([0, 1, 2])
|
|
expect(legends[0]?.data).toEqual(["知行白线", "知行黄线"])
|
|
expect(series.find((item) => item.name === "日线")).toMatchObject({
|
|
xAxisIndex: 0,
|
|
yAxisIndex: 0,
|
|
})
|
|
expect(series.find((item) => item.name === "知行白线")).toMatchObject({
|
|
data: points.map((item) => item.trend_white),
|
|
xAxisIndex: 0,
|
|
yAxisIndex: 0,
|
|
})
|
|
expect(series.find((item) => item.name === "知行黄线")).toMatchObject({
|
|
data: points.map((item) => item.trend_yellow),
|
|
xAxisIndex: 0,
|
|
yAxisIndex: 0,
|
|
})
|
|
expect(series.find((item) => item.name === "成交量")).toMatchObject({
|
|
xAxisIndex: 1,
|
|
yAxisIndex: 1,
|
|
})
|
|
expect(series.filter((item) => item.xAxisIndex === 2)).toHaveLength(3)
|
|
expect(series[0].data[0]).toEqual([10, 10.5, 9, 11])
|
|
})
|
|
|
|
it("keeps missing candles and indicator values empty", () => {
|
|
const incomplete = {
|
|
...point(0),
|
|
close: null,
|
|
d: null,
|
|
high: null,
|
|
j: null,
|
|
k: null,
|
|
trend_white: null,
|
|
trend_yellow: null,
|
|
volume: null,
|
|
}
|
|
const option = buildSelectionChartOption([incomplete])
|
|
const series = option.series as Array<{
|
|
connectNulls?: boolean
|
|
data: unknown[]
|
|
name: string
|
|
}>
|
|
const candle = series[0].data[0] as number[]
|
|
const volume = series.find((item) => item.name === "成交量")
|
|
const lines = series.filter((item) => item.connectNulls === false)
|
|
|
|
expect(candle).toHaveLength(4)
|
|
expect(candle.every(Number.isNaN)).toBe(true)
|
|
expect(volume?.data[0]).toMatchObject({ value: null })
|
|
expect(lines).toHaveLength(5)
|
|
for (const indicator of lines) {
|
|
expect(indicator.data).toEqual([null])
|
|
}
|
|
})
|
|
})
|