78 lines
2.4 KiB
TypeScript
78 lines
2.4 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
|
|
import { computeTooltipPosition } from './chart-tooltip-position';
|
|
|
|
const viewport = { viewportW: 1000, viewportH: 800 };
|
|
|
|
describe('computeTooltipPosition', () => {
|
|
it('places the tooltip below-right of the cursor when it fits', () => {
|
|
const pos = computeTooltipPosition({
|
|
cx: 100,
|
|
cy: 100,
|
|
tipW: 120,
|
|
tipH: 60,
|
|
offset: 12,
|
|
...viewport,
|
|
});
|
|
|
|
expect(pos).toEqual({ x: 112, y: 112 });
|
|
});
|
|
|
|
it('flips to the left when it would overflow the right edge', () => {
|
|
const pos = computeTooltipPosition({
|
|
cx: 950,
|
|
cy: 100,
|
|
tipW: 120,
|
|
tipH: 60,
|
|
offset: 12,
|
|
...viewport,
|
|
});
|
|
|
|
// 950 + 12 + 120 = 1082 > 1000 - 8, so it flips: 950 - 120 - 12
|
|
expect(pos.x).toBe(818);
|
|
});
|
|
|
|
it('flips upward when it would overflow the bottom edge', () => {
|
|
const pos = computeTooltipPosition({
|
|
cx: 100,
|
|
cy: 780,
|
|
tipW: 120,
|
|
tipH: 60,
|
|
offset: 12,
|
|
...viewport,
|
|
});
|
|
|
|
// 780 + 12 + 60 = 852 > 800 - 8, so it flips: 780 - 60 - 12
|
|
expect(pos.y).toBe(708);
|
|
});
|
|
|
|
it('clamps to the 8px margin when even the flipped position is off-screen', () => {
|
|
// Tooltip larger than the space on both sides of the cursor: the flip
|
|
// pushes the coordinate negative, so it must clamp to 8 rather than
|
|
// render partially off-screen.
|
|
const pos = computeTooltipPosition({
|
|
cx: 950,
|
|
cy: 780,
|
|
tipW: 980,
|
|
tipH: 790,
|
|
offset: 12,
|
|
...viewport,
|
|
});
|
|
|
|
expect(pos).toEqual({ x: 8, y: 8 });
|
|
});
|
|
|
|
it('rounds to whole pixels so sub-pixel jitter collapses to one coordinate', () => {
|
|
const base = { tipW: 120, tipH: 60, offset: 12, ...viewport };
|
|
const a = computeTooltipPosition({ cx: 100.1, cy: 100.1, ...base });
|
|
const b = computeTooltipPosition({ cx: 100.4, cy: 100.4, ...base });
|
|
|
|
expect(Number.isInteger(a.x)).toBe(true);
|
|
expect(Number.isInteger(a.y)).toBe(true);
|
|
// 100.1 and 100.4 both land on the same pixel, so the equality guard
|
|
// sees an unchanged position instead of thrashing on the difference.
|
|
expect(a).toEqual(b);
|
|
expect(a).toEqual({ x: 112, y: 112 });
|
|
});
|
|
});
|