Files
u-ppt/tests/chart-domain.test.ts

110 lines
3.7 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { describe, it, expect } from 'vitest'
import { niceDomain, fmtTick } from '../src/components/editor/chart-domain'
describe('niceDomain', () => {
// 已确诊 bug 场景:数据全挤 97~98,旧实现映射到 [0,98] 导致折线贴顶
it('高基线小波动:line 值域收紧为数据带,折线不贴顶', () => {
const d = niceDomain([97, 98, 97.6, 97, 98])
// 波动 <10% → domain = [97 - 1.5, 98 + 1.5]step 0.5 → [95.5, 99.5]
expect(d.min).toBeLessThan(97)
expect(d.max).toBeGreaterThan(98)
expect(d.max - d.min).toBeLessThan(10)
})
it('高基线小波动:ticks 4~5 个且为整数步长', () => {
const d = niceDomain([97, 98, 97.6, 97, 98])
expect(d.ticks.length).toBeGreaterThanOrEqual(4)
expect(d.ticks.length).toBeLessThanOrEqual(6)
const step = d.ticks[1] - d.ticks[0]
expect(step).toBe(1)
// 首尾与 domain 对齐
expect(d.ticks[0]).toBe(d.min)
expect(d.ticks[d.ticks.length - 1]).toBe(d.max)
})
it('bar 类保持 0 基线(不因数据全大而从数据 min 起)', () => {
const d = niceDomain([97, 98, 97.6, 97, 98], { zeroBase: true })
expect(d.min).toBe(0)
expect(d.ticks[0]).toBe(0)
expect(d.max).toBeGreaterThanOrEqual(98)
})
it('常规整数数据 [1,2,3] → nice 步长(0.5 或 1),刻度覆盖 max', () => {
const d = niceDomain([1, 2, 3])
const step = d.ticks[1] - d.ticks[0]
expect([0.5, 1]).toContain(step)
expect(d.ticks).toContain(3)
})
it('小数值数据 [0.1, 0.2] → 步长 0.5,下限 0.5 生效', () => {
const d = niceDomain([0.1, 0.2])
expect(d.ticks[1] - d.ticks[0]).toBe(0.5)
expect(d.min).toBeLessThanOrEqual(0.1)
expect(d.max).toBeGreaterThanOrEqual(0.2)
})
it('单值数据不产生除零/NaN', () => {
const d = niceDomain([5])
expect(d.min).toBeLessThan(d.max)
expect(Number.isFinite(d.min)).toBe(true)
expect(Number.isFinite(d.max)).toBe(true)
expect(d.ticks.length).toBeGreaterThanOrEqual(3)
})
it('全等值数据 line 值域仍为区间而非单点', () => {
const d = niceDomain([42, 42, 42, 42])
expect(d.max).toBeGreaterThan(d.min)
expect(d.ticks.length).toBeGreaterThanOrEqual(3)
})
it('全等值数据 bar 类 → [0, ≥value]', () => {
const d = niceDomain([42, 42, 42], { zeroBase: true })
expect(d.min).toBe(0)
expect(d.max).toBeGreaterThanOrEqual(42)
})
it('maxCap 作为上限覆盖(仅当 > 数据 max', () => {
const d = niceDomain([1, 2, 3], { zeroBase: true, maxCap: 100 })
expect(d.max).toBeGreaterThanOrEqual(100)
})
it('maxCap 小于数据 max 时不收紧值域', () => {
const d = niceDomain([1, 2, 3], { zeroBase: true, maxCap: 1 })
expect(d.max).toBeGreaterThanOrEqual(3)
})
it('空数据返回安全默认值域', () => {
const d = niceDomain([])
expect(d.max).toBeGreaterThan(d.min)
expect(d.ticks.length).toBeGreaterThanOrEqual(2)
})
it('过滤 NaN/Infinity', () => {
const d = niceDomain([NaN, Infinity, -Infinity, 5, 10])
expect(d.min).toBeLessThanOrEqual(5)
expect(d.max).toBeGreaterThanOrEqual(10)
})
it('大整数数据步长取 5×10^k', () => {
const d = niceDomain([1000, 1200, 1500, 2000], { zeroBase: true })
const step = d.ticks[1] - d.ticks[0]
expect(step).toBeGreaterThan(0)
// 2000 跨度 → 步长 500 或 1000 之类 nice 数
expect([100, 200, 500, 1000].includes(step)).toBe(true)
})
})
describe('fmtTick', () => {
it('去尾零', () => {
expect(fmtTick(2.5)).toBe('2.5')
expect(fmtTick(20)).toBe('20')
expect(fmtTick(0)).toBe('0')
expect(fmtTick(97.6)).toBe('97.6')
})
it('消浮点误差', () => {
expect(fmtTick(0.1 + 0.2)).toBe('0.3')
expect(fmtTick(2.55)).toBe('2.55')
})
})