312 lines
7.7 KiB
TypeScript
Vendored
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,
|
|
);
|
|
});
|