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, 0–100 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 0–100', () => { 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); }); });