src/lib/grid/__tests__/selection.test.ts

48 lines
import { describe, expect, it } from "vitest";
import {
  activeCell,
  addRange,
  contains,
  extendBy,
  extendTo,
  moveActive,
  selectedCells,
  single,
  stats,
} from "../selection";

const b = { rows: 5, cols: 6 };

describe("selection", () => {
  it("shift+arrow extends from the anchor, keeping the active cell", () => {
    let s = single({ r: 1, c: 1 });
    s = extendBy(s, 2, 1, b);
    expect(activeCell(s)).toEqual({ r: 1, c: 1 });
    expect(selectedCells(s)).toHaveLength(6);
    expect(contains(s, { r: 3, c: 2 })).toBe(true);
  });

  it("clamps to the grid", () => {
    const s = extendBy(single({ r: 4, c: 5 }), 3, 3, b);
    expect(selectedCells(s)).toEqual([{ r: 4, c: 5 }]);
  });

  it("plain arrow collapses the selection", () => {
    const s = moveActive(extendTo(single({ r: 0, c: 0 }), { r: 3, c: 3 }, b), 1, 0, b);
    expect(selectedCells(s)).toEqual([{ r: 1, c: 0 }]);
  });

  it("ctrl ranges are unioned without double counting", () => {
    let s = extendTo(single({ r: 0, c: 1 }), { r: 1, c: 1 }, b);
    s = addRange(s, { r: 1, c: 1 });
    s = extendTo(s, { r: 2, c: 1 }, b);
    expect(selectedCells(s)).toHaveLength(3);
    expect(activeCell(s)).toEqual({ r: 1, c: 1 });
  });

  it("stats", () => {
    expect(stats([1, 2, 3])).toEqual({ count: 3, sum: 6, average: 2, min: 1, max: 3 });
    expect(stats([])).toBeNull();
  });
});