mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-19 16:16:45 +00:00
78 lines
3.1 KiB
TypeScript
Vendored
78 lines
3.1 KiB
TypeScript
Vendored
// Regression tests for upstream issue t8y2/dbx#11956:
|
|
// 「对查询表数据进行搜索时,数据存在但搜索不到」
|
|
// The result-grid Ctrl+F search runs over the FORMATTED DISPLAY text of each
|
|
// cell, which DataGrid.vue truncates with limitDataGridCellDisplay at
|
|
// DATA_GRID_CELL_DISPLAY_MAX_LENGTH (256) characters. A search term past that
|
|
// cut was invisible to Ctrl+F while a server-side WHERE found it.
|
|
//
|
|
// Fix: the match scan re-checks the full raw value of cells whose display text
|
|
// is truncated (ends with "..."), so matches past the display cut are found.
|
|
//
|
|
// The wiring below mirrors DataGrid.vue's useDataGridSearch call for a plain
|
|
// text column (DataGrid.vue:1146-1170): search text = lowercase of the
|
|
// 256-char-truncated display value.
|
|
import { nextTick } from "vue";
|
|
import { test, vi } from "vitest";
|
|
import { strict as assert } from "node:assert";
|
|
import { useDataGridSearch } from "../../apps/desktop/src/composables/useDataGridSearch.ts";
|
|
import { limitDataGridCellDisplay } from "../../apps/desktop/src/lib/dataGrid/cellValue.ts";
|
|
|
|
async function flushSearchDebounce() {
|
|
await nextTick();
|
|
vi.runOnlyPendingTimers();
|
|
await nextTick();
|
|
await nextTick();
|
|
}
|
|
|
|
// Same shape as DataGrid.vue's getCellSearchText for a plain text column.
|
|
const cellSearchText = (row: string[], column: number): string => limitDataGridCellDisplay(String(row[column] ?? "")).toLowerCase();
|
|
|
|
function longValue(prefix: string, needle: string, totalLength: number): string {
|
|
const head = `${prefix}${"x".repeat(totalLength)}`.slice(0, totalLength);
|
|
// Place the needle just past the 256-character display cut.
|
|
return head.slice(0, 260) + needle + head.slice(260 + needle.length);
|
|
}
|
|
|
|
test("finds values whose match sits past the 256-char display cut", async () => {
|
|
vi.useFakeTimers();
|
|
|
|
const rows = [
|
|
[longValue("row A: ", "needle_a", 400)],
|
|
[longValue("row B: ", "needle_b", 400)],
|
|
[longValue("row C: ", "needle_c", 400)],
|
|
// Control: same row shape but the keyword within the first 256 chars.
|
|
[longValue("row D: ", "needle_d", 100)],
|
|
];
|
|
const search = useDataGridSearch({
|
|
columns: ["content"],
|
|
rows,
|
|
getCellSearchText: cellSearchText,
|
|
getCellRawSearchText: (row, col) => String(row[col] ?? ""),
|
|
includeColumnMatches: false,
|
|
});
|
|
|
|
for (const needle of ["needle_a", "needle_b", "needle_c", "needle_d"]) {
|
|
search.searchText.value = needle;
|
|
await flushSearchDebounce();
|
|
assert.equal(search.matchCount.value, 1, `Ctrl+F "${needle}" should match its row; the data exists and WHERE finds it`);
|
|
}
|
|
});
|
|
|
|
test("does not report truncated cells whose raw value has no match", async () => {
|
|
vi.useFakeTimers();
|
|
|
|
// A raw value that legitimately ends with "..." but never contains the query
|
|
// must not become a false positive through the raw re-check.
|
|
const rows = [["x".repeat(300) + "..."]];
|
|
const search = useDataGridSearch({
|
|
columns: ["content"],
|
|
rows,
|
|
getCellSearchText: cellSearchText,
|
|
getCellRawSearchText: (row, col) => String(row[col] ?? ""),
|
|
includeColumnMatches: false,
|
|
});
|
|
search.searchText.value = "needle_none";
|
|
await flushSearchDebounce();
|
|
assert.equal(search.matchCount.value, 0);
|
|
});
|