Files
t8y2--dbx/packages/app-tests/dataGridTranspose.test.ts
2026-07-13 13:09:14 +08:00

312 lines
7.7 KiB
TypeScript
Vendored

import { strict as assert } from "node:assert";
import { test } from "vitest";
import {
buildTransposeRows,
buildVisibleTransposeRows,
transposeRecordIndexesForMode,
nextContextTransposeState,
nextAppendedTransposeState,
nextKeyboardTransposeState,
nextTransposeState,
nextTransposeStateForRecordCount,
transposeAnchorRowIndex,
transposeFieldWidth,
transposeScrollLeftForRecord,
visibleTransposeRecordWindow,
} from "../../apps/desktop/src/lib/dataGrid/dataGridTranspose.ts";
test("row number double click opens transpose for a row", () => {
assert.deepEqual(nextTransposeState(false, null, 2), {
showTranspose: true,
transposeRowIndex: 2,
});
});
test("row number double click switches transpose to another row", () => {
assert.deepEqual(nextTransposeState(true, 2, 4), {
showTranspose: true,
transposeRowIndex: 4,
});
});
test("row number double click closes transpose for the same row", () => {
assert.deepEqual(nextTransposeState(true, 2, 2), {
showTranspose: false,
transposeRowIndex: null,
});
});
test("context menu transpose closes when invoked for the current anchor row", () => {
assert.deepEqual(
nextContextTransposeState({
showTranspose: true,
transposeRowIndex: 2,
requestedRowIndex: 3,
rowIds: [10, 11, 12, 13, 14],
selectedRowIds: new Set([12, 13]),
selectedRange: null,
}),
{
showTranspose: false,
transposeRowIndex: null,
},
);
});
test("builds one virtualizable transpose row per field with all record values", () => {
const rows = buildTransposeRows({
columns: ["id", "name", "notes"],
records: [
[1, "Ada", null],
[2, "Grace", "compiler"],
],
typeByColumn: new Map([
["id", "int"],
["name", "varchar"],
]),
displayValue: (value) => (value === null ? "NULL" : String(value)),
});
assert.deepEqual(rows, [
{
id: "0:id",
column: "id",
type: "int",
values: [
{ value: 1, display: "1", isNull: false },
{ value: 2, display: "2", isNull: false },
],
},
{
id: "1:name",
column: "name",
type: "varchar",
values: [
{ value: "Ada", display: "Ada", isNull: false },
{ value: "Grace", display: "Grace", isNull: false },
],
},
{
id: "2:notes",
column: "notes",
type: "",
values: [
{ value: null, display: "NULL", isNull: true },
{ value: "compiler", display: "compiler", isNull: false },
],
},
]);
});
test("builds transpose rows for only the visible record window", () => {
const formatted: string[] = [];
const rows = buildVisibleTransposeRows({
columns: ["id", "name"],
records: [
[1, "Ada"],
[2, "Grace"],
[3, "Linus"],
],
recordIndexes: [1, 2],
displayValue: (value, column, _columnIndex, recordIndex) => {
formatted.push(`${recordIndex}:${column}`);
return String(value);
},
});
assert.deepEqual(
rows.map((row) => ({
column: row.column,
values: row.values.map((cell) => ({ recordIndex: cell.recordIndex, display: cell.display })),
})),
[
{
column: "id",
values: [
{ recordIndex: 1, display: "2" },
{ recordIndex: 2, display: "3" },
],
},
{
column: "name",
values: [
{ recordIndex: 1, display: "Grace" },
{ recordIndex: 2, display: "Linus" },
],
},
],
);
assert.deepEqual(formatted, ["1:id", "2:id", "1:name", "2:name"]);
});
test("builds visible transpose rows from mapped source column indexes", () => {
const rows = buildVisibleTransposeRows({
columns: ["name"],
records: [
[1, "Ada"],
[2, "Grace"],
],
recordIndexes: [0],
valueIndexes: [1],
displayValue: (value) => String(value),
});
assert.equal(rows[0].values[0].display, "Ada");
assert.equal(rows[0].values[0].valueIndex, 1);
});
test("single-row transpose only includes the active record", () => {
assert.deepEqual(
transposeRecordIndexesForMode({
multiRow: false,
activeRecordIndex: 3,
totalRecords: 10,
visibleRecordIndexes: [1, 2, 3, 4],
}),
[3],
);
});
test("single-row transpose clamps the active record into range", () => {
assert.deepEqual(
transposeRecordIndexesForMode({
multiRow: false,
activeRecordIndex: 12,
totalRecords: 10,
visibleRecordIndexes: [7, 8, 9],
}),
[9],
);
});
test("multi-row transpose keeps the visible record window", () => {
assert.deepEqual(
transposeRecordIndexesForMode({
multiRow: true,
activeRecordIndex: 3,
totalRecords: 10,
visibleRecordIndexes: [1, 2, 3, 4],
}),
[1, 2, 3, 4],
);
});
test("keyboard transpose opens from the selected cell row and closes when active", () => {
assert.deepEqual(
nextKeyboardTransposeState({
showTranspose: false,
transposeRowIndex: null,
requestedRowIndex: 3,
rowIds: [10, 11, 12, 13, 14],
selectedRowIds: new Set(),
selectedRange: null,
}),
{
showTranspose: true,
transposeRowIndex: 3,
},
);
assert.deepEqual(
nextKeyboardTransposeState({
showTranspose: true,
transposeRowIndex: 3,
requestedRowIndex: 3,
rowIds: [10, 11, 12, 13, 14],
selectedRowIds: new Set(),
selectedRange: null,
}),
{
showTranspose: false,
transposeRowIndex: null,
},
);
});
test("transpose follows appended rows when already open", () => {
assert.deepEqual(nextAppendedTransposeState(true, 4), {
showTranspose: true,
transposeRowIndex: 3,
});
assert.deepEqual(nextAppendedTransposeState(false, 4), {
showTranspose: false,
transposeRowIndex: null,
});
});
test("transpose state is preserved and clamped after record refresh", () => {
assert.deepEqual(nextTransposeStateForRecordCount(true, 4, 3), {
showTranspose: true,
transposeRowIndex: 2,
});
assert.deepEqual(nextTransposeStateForRecordCount(true, 1, 0), {
showTranspose: false,
transposeRowIndex: null,
});
});
test("calculates a horizontal record window with spacer widths", () => {
assert.deepEqual(
visibleTransposeRecordWindow({
totalRecords: 100,
scrollLeft: 680,
viewportWidth: 720,
pinnedWidth: 320,
recordWidth: 160,
overscan: 1,
}),
{
start: 1,
end: 7,
beforeWidth: 160,
afterWidth: 14880,
},
);
});
test("uses the first selected row as the transpose anchor when context row is inside row selection", () => {
assert.equal(
transposeAnchorRowIndex({
requestedRowIndex: 3,
rowIds: [10, 11, 12, 13, 14, 15],
selectedRowIds: new Set([12, 13, 14]),
selectedRange: null,
}),
2,
);
});
test("uses the first selected cell range row as the transpose anchor when context row is inside range", () => {
assert.equal(
transposeAnchorRowIndex({
requestedRowIndex: 5,
rowIds: [10, 11, 12, 13, 14, 15],
selectedRowIds: new Set(),
selectedRange: { startRow: 2, endRow: 5, startCol: 0, endCol: 2 },
}),
2,
);
});
test("sizes the transpose field column from visible field names", () => {
assert.equal(transposeFieldWidth(["id", "iso3", "year"]), 104);
assert.equal(transposeFieldWidth(["country_name"]), 128);
});
test("caps the transpose field column width for long field names", () => {
assert.equal(transposeFieldWidth(["a_very_long_metric_column_name"]), 220);
});
test("aligns the selected transpose record at the start of the scrollable records", () => {
assert.equal(
transposeScrollLeftForRecord({
recordIndex: 55,
totalRecords: 100,
viewportWidth: 1200,
pinnedWidth: 104,
recordWidth: 168,
}),
9240,
);
});