Files
astrolabe/src/app/stores/PanesStore.test.ts
T

96 lines
3.5 KiB
TypeScript
Raw 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 { beforeEach, describe, expect, test } from 'vitest';
import {
clampSideWidth,
HANDLES_TOTAL,
maxSideWidth,
PANE_DEFAULT,
PANE_MIN,
sideWidthValue,
usePanesStore,
} from './PanesStore';
const store = () => usePanesStore.getState();
describe('clampSideWidth', () => {
// A roomy container where nothing is constrained.
const W = 1400;
test('passes a comfortable width through unchanged', () => {
expect(clampSideWidth('library', 300, W, PANE_DEFAULT.preview)).toBe(300);
expect(clampSideWidth('preview', 400, W, PANE_DEFAULT.library)).toBe(400);
});
test('never goes below the pane minimum', () => {
expect(clampSideWidth('library', 50, W, PANE_DEFAULT.preview)).toBe(PANE_MIN.library);
expect(clampSideWidth('preview', 10, W, PANE_DEFAULT.library)).toBe(PANE_MIN.preview);
});
test('caps the width so the editor keeps at least its minimum', () => {
const other = PANE_DEFAULT.preview;
const max = W - other - HANDLES_TOTAL - PANE_MIN.editor;
// Asking for far more than the editor can spare clamps to that maximum.
expect(clampSideWidth('library', W, W, other)).toBe(max);
// The editor sits exactly at its minimum at that point.
expect(W - max - other - HANDLES_TOTAL).toBe(PANE_MIN.editor);
});
test('a container too narrow for all minimums still never drops below the min', () => {
// 500px total can't fit library(180)+preview(240)+editor(320)+handles.
expect(clampSideWidth('library', 300, 500, PANE_MIN.preview)).toBe(PANE_MIN.library);
});
});
describe('sideWidthValue (aria-valuenow, 0100 per WAI-ARIA APG window splitter)', () => {
const W = 1400;
test('reports 0 at the pane minimum and 100 at the pane maximum', () => {
const other = PANE_DEFAULT.preview;
const max = maxSideWidth('library', W, other);
expect(sideWidthValue('library', PANE_MIN.library, W, other)).toBe(0);
expect(sideWidthValue('library', max, W, other)).toBe(100);
});
test('reports the midpoint as ~50', () => {
const other = PANE_DEFAULT.preview;
const mid = (PANE_MIN.library + maxSideWidth('library', W, other)) / 2;
expect(sideWidthValue('library', mid, W, other)).toBe(50);
});
test('clamps out-of-range widths into 0100', () => {
const other = PANE_DEFAULT.preview;
expect(sideWidthValue('library', 0, W, other)).toBe(0);
expect(sideWidthValue('library', 99999, W, other)).toBe(100);
});
test('returns null before layout is known (container width 0)', () => {
expect(sideWidthValue('library', 280, 0, PANE_DEFAULT.preview)).toBeNull();
});
test('returns null when the range has collapsed (container too narrow)', () => {
// 500px can't fit all the minimums, so min == max and there is no range.
expect(sideWidthValue('library', 200, 500, PANE_MIN.preview)).toBeNull();
});
});
describe('usePanesStore', () => {
beforeEach(() =>
store().hydrate({ libraryWidth: PANE_DEFAULT.library, previewWidth: PANE_DEFAULT.preview }),
);
test('setWidth updates the targeted side only', () => {
store().setWidth('library', 320);
expect(store().libraryWidth).toBe(320);
expect(store().previewWidth).toBe(PANE_DEFAULT.preview);
store().setWidth('preview', 420);
expect(store().previewWidth).toBe(420);
expect(store().libraryWidth).toBe(320);
});
test('hydrate fills missing values from defaults', () => {
store().hydrate({ libraryWidth: 250 });
expect(store().libraryWidth).toBe(250);
expect(store().previewWidth).toBe(PANE_DEFAULT.preview);
});
});