mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-11-12 23:31:02 +00:00
4c0583845a
Selecting a place no longer spiderfies a city-sized cluster: the reveal only fans open bubbles of up to 12 stops, or stacks whose stops all share one coordinate, so a zoomed-out trip with hundreds of places stays usable (#2990). The selected pin now carries a white border inside a pulsing blue ring on both renderers (static under reduced motion), and the map measures the place card instead of assuming a fixed 320px, so the selection pans the pin above even a tall card on portrait tablets and eases it back out when the card grows over it later (#2991). Closes #2990 Closes #2991
69 lines
2.5 KiB
TypeScript
69 lines
2.5 KiB
TypeScript
import { render } from '@testing-library/react';
|
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
import { useMeasuredHeight, useReportedHeight } from './useReportedHeight';
|
|
|
|
function Card({ onHeight, open = true }: { onHeight?: (height: number) => void; open?: boolean }) {
|
|
const ref = useReportedHeight(onHeight);
|
|
return open ? <div ref={ref}>card</div> : null;
|
|
}
|
|
|
|
const original = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'offsetHeight');
|
|
afterEach(() => {
|
|
if (original) Object.defineProperty(HTMLElement.prototype, 'offsetHeight', original);
|
|
vi.unstubAllGlobals();
|
|
});
|
|
|
|
describe('useReportedHeight', () => {
|
|
it('REPORTED-HEIGHT-001: reports the height on mount and 0 once the element is gone', () => {
|
|
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', { configurable: true, get: () => 412 });
|
|
const onHeight = vi.fn();
|
|
const { rerender } = render(<Card onHeight={onHeight} />);
|
|
expect(onHeight).toHaveBeenLastCalledWith(412);
|
|
|
|
rerender(<Card onHeight={onHeight} open={false} />);
|
|
expect(onHeight).toHaveBeenLastCalledWith(0);
|
|
});
|
|
|
|
it('REPORTED-HEIGHT-002: reports again whenever the element resizes', () => {
|
|
let height = 300;
|
|
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', { configurable: true, get: () => height });
|
|
const observed: { resize?: () => void } = {};
|
|
const disconnect = vi.fn();
|
|
vi.stubGlobal(
|
|
'ResizeObserver',
|
|
class {
|
|
constructor(cb: () => void) {
|
|
observed.resize = cb;
|
|
}
|
|
observe() {}
|
|
disconnect = disconnect;
|
|
}
|
|
);
|
|
const onHeight = vi.fn();
|
|
const { unmount } = render(<Card onHeight={onHeight} />);
|
|
height = 820;
|
|
expect(observed.resize).toBeTypeOf('function');
|
|
observed.resize?.();
|
|
expect(onHeight).toHaveBeenLastCalledWith(820);
|
|
|
|
unmount();
|
|
expect(disconnect).toHaveBeenCalled();
|
|
});
|
|
|
|
it('REPORTED-HEIGHT-003: does nothing without a listener', () => {
|
|
expect(() => render(<Card />)).not.toThrow();
|
|
});
|
|
});
|
|
|
|
describe('useMeasuredHeight', () => {
|
|
it('REPORTED-HEIGHT-004: holds the measured height as state', () => {
|
|
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', { configurable: true, get: () => 512 });
|
|
function Probe() {
|
|
const { height, measure } = useMeasuredHeight();
|
|
return <div ref={measure} data-height={height} />;
|
|
}
|
|
const { container } = render(<Probe />);
|
|
expect(container.firstElementChild?.getAttribute('data-height')).toBe('512');
|
|
});
|
|
});
|