diff --git a/packages/app-tests/aiPrompt.test.ts b/packages/app-tests/aiPrompt.test.ts index 3cfc11b1e..1d5e2324b 100644 --- a/packages/app-tests/aiPrompt.test.ts +++ b/packages/app-tests/aiPrompt.test.ts @@ -61,8 +61,8 @@ test("agent mode prompt makes the first SQL block the executable recommendation" const prompt = buildSystemPrompt("generate", context(), "agent"); assert.match(prompt, /Agent 模式/); - assert.match(prompt, /第一个 ```sql 代码块只能包含最终推荐执行的 SQL/); - assert.match(prompt, /不要把解释性 SQL、备选 SQL、危险 SQL 放在第一个代码块/); + assert.match(prompt, /第一个 ```sql 代码块只放最终推荐 SQL/); + assert.match(prompt, /execute_query/); }); test("ask mode prompt forbids auto-execution assumptions", () => { diff --git a/packages/app-tests/dataGridColumnWidth.test.ts b/packages/app-tests/dataGridColumnWidth.test.ts deleted file mode 100644 index b4c9fc0ff..000000000 --- a/packages/app-tests/dataGridColumnWidth.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { strict as assert } from "node:assert"; -import { test } from "vitest"; -import { calculateDataGridColumnWidth, DATA_GRID_HEADER_CONTROL_WIDTH } from "../../apps/desktop/src/lib/dataGridColumnWidth.ts"; - -test("reserves header control space when auto-sizing a column from the header", () => { - const width = calculateDataGridColumnWidth({ - columnName: "created_at", - sampleValues: [], - }); - - assert.equal(width, "created_at".length * 8 + DATA_GRID_HEADER_CONTROL_WIDTH); -}); - -test("keeps cell content as the sizing driver when it is wider than header controls", () => { - const width = calculateDataGridColumnWidth({ - columnName: "id", - sampleValues: ["a long enough value to dominate"], - }); - - assert.equal(width, "a long enough value to dominate".length * 8 + 28); -}); diff --git a/packages/app-tests/dataGridPaintTheme.test.ts b/packages/app-tests/dataGridPaintTheme.test.ts deleted file mode 100644 index 748af350d..000000000 --- a/packages/app-tests/dataGridPaintTheme.test.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { strict as assert } from "node:assert"; -import { test } from "vitest"; -import { resolveDataGridPaintTheme } from "../../apps/desktop/src/lib/dataGridPaintTheme.ts"; - -test("canvas grid paint theme falls back from advanced CSS colors", () => { - const vars = new Map([ - ["--background", "oklch(1 0 0)"], - ["--foreground", "oklch(0.145 0 0)"], - ["--primary", "oklch(0.205 0 0)"], - ["--border", "oklch(0.922 0 0)"], - ["--data-grid-cell-selected-bg", "color-mix(in oklab, var(--primary) 25%, transparent)"], - ["--data-grid-row-number-selected-bg", "color-mix(in oklab, var(--primary) 25%, var(--background))"], - ]); - - const theme = resolveDataGridPaintTheme({ - getVar: (name) => vars.get(name) ?? "", - isDark: false, - }); - - assert.equal(theme.background, "rgb(255, 255, 255)"); - assert.equal(theme.foreground, "rgb(10, 10, 10)"); - assert.equal(theme.border, "rgb(229, 231, 235)"); - assert.equal(theme.primary, "rgb(23, 23, 23)"); - assert.equal(theme.cellSelected, "rgb(226, 226, 226)"); - assert.equal(theme.rowNumberSelected, "rgb(226, 226, 226)"); -}); - -test("canvas grid paint theme converts rgb color-mix tokens to rgba", () => { - const vars = new Map([ - ["--primary", "rgb(23 23 23)"], - ["--background", "rgb(255 255 255)"], - ["--data-grid-cell-selected-bg", "color-mix(in oklab, var(--primary) 25%, transparent)"], - ["--data-grid-row-number-selected-bg", "color-mix(in oklab, var(--primary) 25%, var(--background))"], - ]); - - const theme = resolveDataGridPaintTheme({ - getVar: (name) => vars.get(name) ?? "", - isDark: false, - }); - - assert.equal(theme.cellSelected, "rgba(23, 23, 23, 0.25)"); - assert.equal(theme.rowNumberSelected, "rgb(197, 197, 197)"); -}); diff --git a/packages/app-tests/dataGridScrollGutter.test.ts b/packages/app-tests/dataGridScrollGutter.test.ts deleted file mode 100644 index fdc40a126..000000000 --- a/packages/app-tests/dataGridScrollGutter.test.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { strict as assert } from "node:assert"; -import { test } from "vitest"; -import { dataGridHeaderContentWidth, scrollbarGutterWidth } from "../../apps/desktop/src/lib/dataGridScrollGutter.ts"; - -test("calculates scrollbar gutter from element dimensions", () => { - assert.equal(scrollbarGutterWidth({ offsetWidth: 1000, clientWidth: 985 }), 15); - assert.equal(scrollbarGutterWidth({ offsetWidth: 1000, clientWidth: 1000 }), 0); -}); - -test("extends header content width by the body scrollbar gutter", () => { - assert.equal(dataGridHeaderContentWidth("var(--total-w)", 15), "calc(var(--total-w) + 15px)"); - assert.equal(dataGridHeaderContentWidth("var(--total-w)", 0), "var(--total-w)"); -}); diff --git a/packages/app-tests/diagramZoom.test.ts b/packages/app-tests/diagramZoom.test.ts deleted file mode 100644 index 416b99865..000000000 --- a/packages/app-tests/diagramZoom.test.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { strict as assert } from "node:assert"; -import { test } from "vitest"; -import { clampDiagramZoom, zoomFromGestureScale, zoomFromWheelDelta } from "../../apps/desktop/src/lib/diagramZoom.ts"; - -test("clamps diagram zoom to supported bounds", () => { - assert.equal(clampDiagramZoom(0.2), 0.6); - assert.equal(clampDiagramZoom(2), 1.5); - assert.equal(clampDiagramZoom(1.234), 1.23); -}); - -test("maps trackpad pinch wheel delta to smooth zoom changes", () => { - assert.ok(zoomFromWheelDelta(1, -120) > 1); - assert.ok(zoomFromWheelDelta(1, 120) < 1); -}); - -test("maps WebKit gesture scale from the gesture start zoom", () => { - assert.equal(zoomFromGestureScale(1, 1.25), 1.25); - assert.equal(zoomFromGestureScale(1, 4), 1.5); -}); diff --git a/packages/app-tests/editorZoom.test.ts b/packages/app-tests/editorZoom.test.ts deleted file mode 100644 index c1871c992..000000000 --- a/packages/app-tests/editorZoom.test.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { strict as assert } from "node:assert"; -import { test } from "vitest"; -import { clampEditorFontSize, createEditorZoomCommitScheduler, fontSizeFromGestureScale, fontSizeFromWheelDelta } from "../../apps/desktop/src/lib/editorZoom.ts"; - -test("clamps editor font size to supported bounds", () => { - assert.equal(clampEditorFontSize(8), 10); - assert.equal(clampEditorFontSize(30), 24); - assert.equal(clampEditorFontSize(13.257), 13.26); -}); - -test("maps trackpad pinch wheel delta to smooth font size changes", () => { - assert.ok(fontSizeFromWheelDelta(13, -120) > 13); - assert.ok(fontSizeFromWheelDelta(13, 120) < 13); -}); - -test("maps WebKit gesture scale from the gesture start font size", () => { - assert.equal(fontSizeFromGestureScale(13, 1.25), 16.25); - assert.equal(fontSizeFromGestureScale(13, 4), 24); -}); - -test("debounces editor zoom commits and keeps only the latest font size", async () => { - const committed: number[] = []; - const scheduler = createEditorZoomCommitScheduler((fontSize) => committed.push(fontSize), 10); - - scheduler.schedule(13.5); - scheduler.schedule(14.25); - - await new Promise((resolve) => setTimeout(resolve, 25)); - - assert.deepEqual(committed, [14.25]); -}); - -test("flushes a pending editor zoom commit immediately", () => { - const committed: number[] = []; - const scheduler = createEditorZoomCommitScheduler((fontSize) => committed.push(fontSize), 50); - - scheduler.schedule(15.75); - scheduler.flush(); - - assert.deepEqual(committed, [15.75]); - assert.equal(scheduler.hasPendingCommit(), false); -}); diff --git a/packages/app-tests/historyVirtualList.test.ts b/packages/app-tests/historyVirtualList.test.ts deleted file mode 100644 index d2c200ffd..000000000 --- a/packages/app-tests/historyVirtualList.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { strict as assert } from "node:assert"; -import { test } from "vitest"; -import { HISTORY_ROW_HEIGHT, HISTORY_SCROLL_BUFFER, shouldVirtualizeHistory } from "../../apps/desktop/src/lib/historyVirtualList.ts"; - -test("history list virtualizes every non-empty result set", () => { - assert.equal(shouldVirtualizeHistory(0), false); - assert.equal(shouldVirtualizeHistory(1), true); - assert.equal(shouldVirtualizeHistory(1000), true); -}); - -test("history virtual list keeps enough buffer for smooth scrolling", () => { - assert.equal(HISTORY_ROW_HEIGHT, 72); - assert.ok(HISTORY_SCROLL_BUFFER >= HISTORY_ROW_HEIGHT * 6); -}); diff --git a/packages/app-tests/imagePreviewViewer.test.ts b/packages/app-tests/imagePreviewViewer.test.ts deleted file mode 100644 index e2ac92ddb..000000000 --- a/packages/app-tests/imagePreviewViewer.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { strict as assert } from "node:assert"; -import { test } from "vitest"; -import { imagePreviewFitScale, clampImagePreviewScale, imagePreviewTransform, nextImagePreviewScale } from "../../apps/desktop/src/lib/imagePreviewViewer.ts"; - -test("clamps image preview zoom to usable bounds", () => { - assert.equal(clampImagePreviewScale(0.1), 0.2); - assert.equal(clampImagePreviewScale(1.25), 1.25); - assert.equal(clampImagePreviewScale(12), 8); -}); - -test("zooms in fixed steps from wheel direction", () => { - assert.equal(nextImagePreviewScale(1, "in"), 1.2); - assert.equal(nextImagePreviewScale(1, "out"), 0.8); - assert.equal(nextImagePreviewScale(7.95, "in"), 8); -}); - -test("builds a stable CSS transform for image previews", () => { - assert.equal(imagePreviewTransform({ scale: 1.5, offsetX: 12, offsetY: -8 }), "translate(12px, -8px) scale(1.5)"); -}); - -test("calculates fit scale from image and viewport dimensions", () => { - assert.equal( - imagePreviewFitScale({ - imageWidth: 2000, - imageHeight: 1000, - viewportWidth: 1000, - viewportHeight: 800, - }), - 0.45, - ); - assert.equal( - imagePreviewFitScale({ - imageWidth: 200, - imageHeight: 100, - viewportWidth: 1000, - viewportHeight: 800, - }), - 1, - ); -}); diff --git a/packages/app-tests/sidebarTableNameDisplay.test.ts b/packages/app-tests/sidebarTableNameDisplay.test.ts deleted file mode 100644 index 8475f29ee..000000000 --- a/packages/app-tests/sidebarTableNameDisplay.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { test } from "vitest"; -import assert from "node:assert/strict"; -import { normalizeSidebarHiddenTablePrefixes, sidebarDisplayTableName } from "../../apps/desktop/src/lib/sidebarTableNameDisplay.ts"; - -test("normalizes sidebar hidden table prefixes", () => { - assert.deepEqual(normalizeSidebarHiddenTablePrefixes([" app_", "app_", "", "ods."]), ["app_", "ods."]); - assert.deepEqual(normalizeSidebarHiddenTablePrefixes("app_\nods.\n app_ "), ["app_", "ods."]); - assert.deepEqual(normalizeSidebarHiddenTablePrefixes(null), []); -}); - -test("hides a configured table prefix from the sidebar label", () => { - assert.equal(sidebarDisplayTableName("t8y2_long_customer_order", ["t8y2_long_"]), "...customer_order"); -}); - -test("uses the longest matching sidebar table prefix", () => { - assert.equal(sidebarDisplayTableName("app_sales_orders", ["app_", "app_sales_"]), "...orders"); -}); - -test("keeps the full name when hiding would leave an empty label", () => { - assert.equal(sidebarDisplayTableName("app_", ["app_"]), "app_"); -}); diff --git a/packages/app-tests/sidebarTreeItemLayout.test.ts b/packages/app-tests/sidebarTreeItemLayout.test.ts deleted file mode 100644 index bb7fd024c..000000000 --- a/packages/app-tests/sidebarTreeItemLayout.test.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { strict as assert } from "node:assert"; -import { test } from "vitest"; -import { canTreeNodeExpand, canTreeNodeShowExpander, treeItemPaddingLeft, usesFullWidthTreeLabel } from "../../apps/desktop/src/lib/sidebarTreeItemLayout.ts"; - -test("treeItemPaddingLeft converts tree depth to sidebar indentation", () => { - assert.equal(treeItemPaddingLeft(0), "8px"); - assert.equal(treeItemPaddingLeft(1), "24px"); - assert.equal(treeItemPaddingLeft(2), "40px"); -}); - -test("canTreeNodeExpand only returns true for expandable sidebar node types", () => { - assert.equal(canTreeNodeExpand("connection"), true); - assert.equal(canTreeNodeExpand("database"), true); - assert.equal(canTreeNodeExpand("schema"), true); - assert.equal(canTreeNodeExpand("table"), true); - assert.equal(canTreeNodeExpand("view"), true); - assert.equal(canTreeNodeExpand("saved-sql-root"), true); - assert.equal(canTreeNodeExpand("saved-sql-folder"), true); - - assert.equal(canTreeNodeExpand("saved-sql-file"), false); - assert.equal(canTreeNodeExpand("object-browser"), false); - assert.equal(canTreeNodeExpand("column"), false); - assert.equal(canTreeNodeExpand("index"), false); - assert.equal(canTreeNodeExpand("redis-db"), false); - assert.equal(canTreeNodeExpand("mongo-collection"), false); - assert.equal(canTreeNodeExpand("user-admin"), false); -}); - -test("canTreeNodeShowExpander hides empty saved SQL containers", () => { - assert.equal(canTreeNodeShowExpander({ type: "saved-sql-root", childCount: 0 }), false); - assert.equal(canTreeNodeShowExpander({ type: "saved-sql-folder", childCount: 0 }), false); - assert.equal(canTreeNodeShowExpander({ type: "saved-sql-root", childCount: 1 }), true); - assert.equal(canTreeNodeShowExpander({ type: "saved-sql-folder", childCount: 1 }), true); -}); - -test("usesFullWidthTreeLabel only expands object names when horizontal scroll is enabled", () => { - assert.equal(usesFullWidthTreeLabel("table", true), true); - assert.equal(usesFullWidthTreeLabel("view", true), true); - assert.equal(usesFullWidthTreeLabel("mongo-collection", true), true); - - assert.equal(usesFullWidthTreeLabel("table", false), false); - assert.equal(usesFullWidthTreeLabel("connection", true), false); - assert.equal(usesFullWidthTreeLabel("schema", true), false); - assert.equal(usesFullWidthTreeLabel("column", true), false); -}); diff --git a/packages/app-tests/windowControlsFullscreenInset.test.ts b/packages/app-tests/windowControlsFullscreenInset.test.ts deleted file mode 100644 index e65530b43..000000000 --- a/packages/app-tests/windowControlsFullscreenInset.test.ts +++ /dev/null @@ -1,10 +0,0 @@ -import assert from "node:assert/strict"; -import { test } from "vitest"; -import * as windowControlsModule from "../../apps/desktop/src/composables/useWindowControls.ts"; - -test("mac traffic-light inset is removed in fullscreen", () => { - assert.equal(typeof windowControlsModule.shouldReserveMacTrafficLightInset, "function"); - assert.equal(windowControlsModule.shouldReserveMacTrafficLightInset(true, false), true); - assert.equal(windowControlsModule.shouldReserveMacTrafficLightInset(true, true), false); - assert.equal(windowControlsModule.shouldReserveMacTrafficLightInset(false, false), false); -});