@blueprintjs/table
Version:
Scalable interactive table component
583 lines (510 loc) • 25.6 kB
text/typescript
/*
* Copyright 2017 Palantir Technologies, Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* eslint-disable sort-keys */
import { describe, expect, it } from "@blueprintjs/test-commons/vitest";
import { type Region, Regions } from "../../regions";
import { type CellCoordinates, type FocusedCell, type FocusedCellCoordinates, FocusMode } from "../cellTypes";
import * as FocusedCellUtils from "./focusedCellUtils";
describe("FocusedCellUtils", () => {
describe("expandFocusedRegion", () => {
const FOCUSED_ROW = 3;
const FOCUSED_COL = 3;
const PREV_ROW = FOCUSED_ROW - 2;
const NEXT_ROW = FOCUSED_ROW + 2;
const PREV_COL = FOCUSED_COL - 2;
const NEXT_COL = FOCUSED_COL + 2;
const focusedCell: FocusedCell = { type: FocusMode.CELL, ...toCellCoords(FOCUSED_ROW, FOCUSED_COL) };
// shorthand
const fn = FocusedCellUtils.expandFocusedRegion;
describe("Expands to a FULL_ROWS selection", () => {
it("upward", () => {
const newRegion = Regions.row(PREV_ROW);
const result = fn(focusedCell, newRegion);
checkEqual(result, Regions.row(PREV_ROW, FOCUSED_COL));
});
it("downward", () => {
const newRegion = Regions.row(NEXT_ROW);
const result = fn(focusedCell, newRegion);
checkEqual(result, Regions.row(FOCUSED_ROW, NEXT_ROW));
});
it("same row", () => {
const newRegion = Regions.row(FOCUSED_ROW);
const result = fn(focusedCell, newRegion);
checkEqual(result, Regions.row(FOCUSED_ROW, FOCUSED_COL));
});
});
describe("Expands to a FULL_COLUMNS selection", () => {
it("leftward", () => {
const newRegion = Regions.column(PREV_COL);
const result = fn(focusedCell, newRegion);
checkEqual(result, Regions.column(PREV_COL, FOCUSED_COL));
});
it("rightward", () => {
const newRegion = Regions.column(NEXT_COL);
const result = fn(focusedCell, newRegion);
checkEqual(result, Regions.column(FOCUSED_COL, NEXT_COL));
});
it("same column", () => {
const newRegion = Regions.column(FOCUSED_COL);
const result = fn(focusedCell, newRegion);
checkEqual(result, Regions.column(FOCUSED_COL, FOCUSED_COL));
});
});
describe("Expands to a CELLS selection", () => {
it("toward top-left", () => {
const newRegion = Regions.cell(PREV_ROW, PREV_COL);
const result = fn(focusedCell, newRegion);
checkEqual(result, Regions.cell(PREV_ROW, PREV_COL, FOCUSED_ROW, FOCUSED_COL));
});
it("toward top", () => {
const newRegion = Regions.cell(FOCUSED_ROW, PREV_COL);
const result = fn(focusedCell, newRegion);
checkEqual(result, Regions.cell(FOCUSED_ROW, PREV_COL, FOCUSED_ROW, FOCUSED_COL));
});
it("toward top-right", () => {
const newRegion = Regions.cell(PREV_ROW, NEXT_COL);
const result = fn(focusedCell, newRegion);
checkEqual(result, Regions.cell(PREV_ROW, FOCUSED_COL, FOCUSED_ROW, NEXT_COL));
});
it("toward right", () => {
const newRegion = Regions.cell(FOCUSED_ROW, NEXT_COL);
const result = fn(focusedCell, newRegion);
checkEqual(result, Regions.cell(FOCUSED_ROW, FOCUSED_COL, FOCUSED_ROW, NEXT_COL));
});
it("toward bottom-right", () => {
const newRegion = Regions.cell(NEXT_ROW, NEXT_COL);
const result = fn(focusedCell, newRegion);
checkEqual(result, Regions.cell(FOCUSED_ROW, FOCUSED_COL, NEXT_ROW, NEXT_COL));
});
it("toward bottom", () => {
const newRegion = Regions.cell(NEXT_ROW, FOCUSED_COL);
const result = fn(focusedCell, newRegion);
checkEqual(result, Regions.cell(FOCUSED_ROW, FOCUSED_COL, NEXT_ROW, FOCUSED_COL));
});
it("toward bottom-left", () => {
const newRegion = Regions.cell(NEXT_ROW, PREV_COL);
const result = fn(focusedCell, newRegion);
checkEqual(result, Regions.cell(FOCUSED_ROW, PREV_COL, NEXT_ROW, FOCUSED_COL));
});
it("toward left", () => {
const newRegion = Regions.cell(FOCUSED_ROW, PREV_COL);
const result = fn(focusedCell, newRegion);
checkEqual(result, Regions.cell(FOCUSED_ROW, PREV_COL, FOCUSED_ROW, FOCUSED_COL));
});
});
it("Expands to a FULL_TABLE selection", () => {
const newRegion = Regions.table();
const result = fn(focusedCell, newRegion);
checkEqual(result, Regions.table());
});
function checkEqual(result: Region, expected: Region) {
expect(result).to.deep.equal(expected);
}
function toCellCoords(row: number, col: number): FocusedCellCoordinates {
return { row, col, focusSelectionIndex: 0 };
}
});
describe("getFocusedOrLastSelectedIndex", () => {
const fn = FocusedCellUtils.getFocusedOrLastSelectedIndex;
it("always returns `undefined` if selectedRegions is empty", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, { row: 0, col: 0 });
expect(fn([], undefined)).to.be.undefined;
expect(fn([], focusedCell)).to.be.undefined;
});
it("returns selectedRegions's last index if focused cell not defined", () => {
const selectedRegions = [Regions.row(0), Regions.row(1), Regions.row(3)];
const lastIndex = selectedRegions.length - 1;
expect(fn(selectedRegions, undefined)).to.deep.equal(lastIndex);
});
it("returns focusSelectionIndex if focused cell is defined", () => {
const INDEX = 1;
const selectedRegions = [Regions.row(0), Regions.row(1), Regions.row(3)];
const focusedCell: FocusedCell = { type: FocusMode.CELL, row: 0, col: 0, focusSelectionIndex: INDEX };
expect(fn(selectedRegions, focusedCell)).to.deep.equal(INDEX);
});
});
describe("getInitialFocusedRegion", () => {
const FOCUSED_CELL_FROM_PROPS = getFocusedCell(1, 2);
const FOCUSED_CELL_FROM_STATE = getFocusedCell(3, 4);
const SELECTED_REGIONS = [Regions.cell(1, 1, 4, 5), Regions.cell(5, 1, 6, 2)];
it("returns undefined if enableFocusedCell=false", () => {
const focusedCell = FocusedCellUtils.getInitialFocusedRegion(
undefined,
FOCUSED_CELL_FROM_PROPS,
FOCUSED_CELL_FROM_STATE,
SELECTED_REGIONS,
);
expect(focusedCell).to.be.undefined;
});
it("returns the focusedCellFromProps if defined", () => {
const focusedCell = FocusedCellUtils.getInitialFocusedRegion(
FocusMode.CELL,
FOCUSED_CELL_FROM_PROPS,
FOCUSED_CELL_FROM_STATE,
SELECTED_REGIONS,
);
expect(focusedCell).to.deep.equal(FOCUSED_CELL_FROM_PROPS);
});
it("returns the focusedCellFromState if focusedCellFromProps not defined", () => {
const focusedCell = FocusedCellUtils.getInitialFocusedRegion(
FocusMode.CELL,
undefined,
FOCUSED_CELL_FROM_STATE,
SELECTED_REGIONS,
);
expect(focusedCell).to.deep.equal(FOCUSED_CELL_FROM_STATE);
});
it("returns the focused cell for the last selected region if focusedCell not provided", () => {
const focusedCell = FocusedCellUtils.getInitialFocusedRegion(
FocusMode.CELL,
undefined,
undefined,
SELECTED_REGIONS,
);
const lastIndex = SELECTED_REGIONS.length - 1;
const expectedFocusedCell: FocusedCell = {
...Regions.getFocusCellCoordinatesFromRegion(SELECTED_REGIONS[lastIndex]),
focusSelectionIndex: lastIndex,
type: FocusMode.CELL,
};
expect(focusedCell).to.deep.equal(expectedFocusedCell);
});
it("returns cell (0, 0) if nothing else is defined", () => {
const focusedCell = FocusedCellUtils.getInitialFocusedRegion(FocusMode.CELL, undefined, undefined, []);
const expectedFocusedCell: FocusedCell = {
col: 0,
focusSelectionIndex: 0,
row: 0,
type: FocusMode.CELL,
};
expect(focusedCell).to.deep.equal(expectedFocusedCell);
});
function getFocusedCell(row: number, col: number, focusSelectionIndex: number = 0): FocusedCell {
return { type: FocusMode.CELL, row, col, focusSelectionIndex };
}
});
describe("isFocusAtRegion__", () => {
const ROW_START = 3;
const ROW_END = 5;
const COL_START = 4;
const COL_END = 6;
const cellRegion = Regions.cell(ROW_START, COL_START, ROW_END, COL_END);
const columnRegion = Regions.column(COL_START, COL_END);
const rowRegion = Regions.row(ROW_START, ROW_END);
const tableRegion = Regions.table();
describe("isFocusAtRegionTop", () => {
const fn = FocusedCellUtils.isFocusAtRegionTop;
describe("CELLS region", () => {
it("returns true if focused cell at region top and inside region", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_START,
});
expect(fn(cellRegion, focusedCell)).to.be.true;
});
it("returns true if focused cell at region top and not inside region", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_END + 1,
});
expect(fn(cellRegion, focusedCell)).to.be.true;
});
it("returns false if focused cell not at region top", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START + 1,
col: COL_START,
});
expect(fn(cellRegion, focusedCell)).to.be.false;
});
});
describe("FULL_COLUMNS region", () => {
it("always returns false", () => {
const focusedCell1 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_START,
});
const focusedCell2 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_END + 1,
});
const focusedCell3 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START + 1,
col: COL_START,
});
expect(fn(columnRegion, focusedCell1)).to.be.false;
expect(fn(columnRegion, focusedCell2)).to.be.false;
expect(fn(columnRegion, focusedCell3)).to.be.false;
});
});
describe("FULL_ROWS region", () => {
it("returns true if focused cell at region top and inside region", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_START,
});
expect(fn(rowRegion, focusedCell)).to.be.true;
});
it("returns false if focused cell not at region top", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START + 1,
col: COL_START,
});
expect(fn(rowRegion, focusedCell)).to.be.false;
});
});
describe("FULL_TABLE region", () => {
it("always returns false", () => {
const focusedCell1 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, { row: 0, col: 0 })!;
const focusedCell2 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_START,
});
expect(fn(tableRegion, focusedCell1)).to.be.false;
expect(fn(tableRegion, focusedCell2)).to.be.false;
});
});
});
describe("isFocusAtRegionBottom", () => {
const fn = FocusedCellUtils.isFocusAtRegionBottom;
describe("CELLS region", () => {
it("returns true if focused cell at region bottom and inside region", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_END,
col: COL_START,
});
expect(fn(cellRegion, focusedCell)).to.be.true;
});
it("returns true if focused cell at region bottom and not inside region", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_END,
col: COL_END + 1,
});
expect(fn(cellRegion, focusedCell)).to.be.true;
});
it("returns false if focused cell not at region bottom", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_END - 1,
col: COL_START,
});
expect(fn(cellRegion, focusedCell)).to.be.false;
});
});
describe("FULL_COLUMNS region", () => {
it("always returns false", () => {
const focusedCell1 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_END,
col: COL_START,
});
const focusedCell2 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_END,
col: COL_END + 1,
});
const focusedCell3 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_END - 1,
col: COL_START,
});
expect(fn(columnRegion, focusedCell1)).to.be.false;
expect(fn(columnRegion, focusedCell2)).to.be.false;
expect(fn(columnRegion, focusedCell3)).to.be.false;
});
});
describe("FULL_ROWS region", () => {
it("returns true if focused cell at region bottom and inside region", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_END,
col: COL_START,
});
expect(fn(rowRegion, focusedCell)).to.be.true;
});
it("returns false if focused cell not at region bottom", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_END + 1,
col: COL_START,
});
expect(fn(rowRegion, focusedCell)).to.be.false;
});
});
describe("FULL_TABLE region", () => {
it("always returns false", () => {
const focusedCell1 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, { row: 0, col: 0 });
const focusedCell2 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_END,
col: COL_START,
});
expect(fn(tableRegion, focusedCell1)).to.be.false;
expect(fn(tableRegion, focusedCell2)).to.be.false;
});
});
});
describe("isFocusAtRegionLeft", () => {
const fn = FocusedCellUtils.isFocusAtRegionLeft;
describe("CELLS region", () => {
it("returns true if focused cell at region left and inside region", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_START,
});
expect(fn(cellRegion, focusedCell)).to.be.true;
});
it("returns true if focused cell at region left and not inside region", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_END + 1,
col: COL_START,
});
expect(fn(cellRegion, focusedCell)).to.be.true;
});
it("returns false if focused cell not at region left", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_START + 1,
});
expect(fn(cellRegion, focusedCell)).to.be.false;
});
});
describe("FULL_COLUMNS region", () => {
it("returns true if focused cell at region left and inside region", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_START,
});
expect(fn(columnRegion, focusedCell)).to.be.true;
});
it("returns false if focused cell not at region left", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_START + 1,
});
expect(fn(columnRegion, focusedCell)).to.be.false;
});
});
describe("FULL_ROWS region", () => {
it("always returns false", () => {
const focusedCell1 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_START,
});
const focusedCell2 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_END + 1,
col: COL_START,
});
const focusedCell3 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_START + 1,
});
expect(fn(rowRegion, focusedCell1)).to.be.false;
expect(fn(rowRegion, focusedCell2)).to.be.false;
expect(fn(rowRegion, focusedCell3)).to.be.false;
});
});
describe("FULL_TABLE region", () => {
it("always returns false", () => {
const focusedCell1 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, { row: 0, col: 0 });
const focusedCell2 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_START,
});
expect(fn(tableRegion, focusedCell1)).to.be.false;
expect(fn(tableRegion, focusedCell2)).to.be.false;
});
});
});
describe("isFocusAtRegionRight", () => {
const fn = FocusedCellUtils.isFocusAtRegionRight;
describe("CELLS region", () => {
it("returns true if focused cell at region right and inside region", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_END,
});
expect(fn(cellRegion, focusedCell)).to.be.true;
});
it("returns true if focused cell at region right and not inside region", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_END + 1,
col: COL_END,
});
expect(fn(cellRegion, focusedCell)).to.be.true;
});
it("returns false if focused cell not at region right", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_END - 1,
});
expect(fn(cellRegion, focusedCell)).to.be.false;
});
});
describe("FULL_COLUMNS region", () => {
it("returns true if focused cell at region right and inside region", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_END,
});
expect(fn(columnRegion, focusedCell)).to.be.true;
});
it("returns false if focused cell not at region right", () => {
const focusedCell = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_END - 1,
});
expect(fn(columnRegion, focusedCell)).to.be.false;
});
});
describe("FULL_ROWS region", () => {
it("always returns false", () => {
const focusedCell1 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_END,
});
const focusedCell2 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_END + 1,
col: COL_END,
});
const focusedCell3 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_END - 1,
});
expect(fn(rowRegion, focusedCell1)).to.be.false;
expect(fn(rowRegion, focusedCell2)).to.be.false;
expect(fn(rowRegion, focusedCell3)).to.be.false;
});
});
describe("FULL_TABLE region", () => {
it("always returns false", () => {
const focusedCell1 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, { row: 0, col: 0 });
const focusedCell2 = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, {
row: ROW_START,
col: COL_END,
});
expect(fn(tableRegion, focusedCell1)).to.be.false;
expect(fn(tableRegion, focusedCell2)).to.be.false;
});
});
});
});
describe("toFocusedRegion", () => {
it("applies focusSelectionIndex=0 by default", () => {
const cellCoords: CellCoordinates = { row: 2, col: 3 };
const result = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, cellCoords);
expect(result).to.deep.equal({ ...result, focusSelectionIndex: 0 });
});
it("applies a custom focusSelectionIndex if provided", () => {
const cellCoords: CellCoordinates = { row: 2, col: 3 };
const INDEX = 1;
const result = FocusedCellUtils.toFocusedRegion(FocusMode.CELL, cellCoords, INDEX);
expect(result).to.deep.equal({ ...result, focusSelectionIndex: INDEX });
});
});
});