fix(tests): remove low-value source snapshots and define test standards

This commit is contained in:
t8y2 committed 2026-09-11 11:51:24 +08:00
1 parent ead906477f
commit 8186c697d5
80 files changed
+14 -2225

No files matched your search

@@ -1,18 +0,0 @@
import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
const source = readFileSync(new URL("../AiAssistant.vue", import.meta.url), "utf8");
describe("AI assistant explain_query canvas containment", () => {
it("bounds the embedded ExplainPlanViewer to a fixed, clipped height", () => {
const match = source.match(/<div v-if="step\.toolName === 'explain_query' && step\.explainData[^>]*class="([^"]*)"/);
expect(match, "explain_query wrapper div not found").not.toBeNull();
const wrapperClass = match![1];
expect(wrapperClass).toContain("h-64");
expect(wrapperClass).toContain("overflow-hidden");
});
it("does not rely on an unresolvable max-height alone to contain the canvas", () => {
expect(source).not.toContain('<ExplainPlanViewer :plan="parseExplainFromData(step.explainData, connection.db_type)" class="max-h-64" />');
});
});
@@ -1,17 +0,0 @@
import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
const source = readFileSync(new URL("../AiAssistant.vue", import.meta.url), "utf8");
describe("AI assistant maximize control", () => {
it("exposes a parent-controlled maximize toggle with accessible labels", () => {
expect(source).toContain("maximized?: boolean;");
expect(source).toContain("toggleMaximize: [];");
expect(source).toContain(":title=\"props.maximized ? t('ai.restore') : t('ai.maximize')\"");
expect(source).toContain(":aria-label=\"props.maximized ? t('ai.restore') : t('ai.maximize')\"");
expect(source).toContain(':aria-pressed="props.maximized"');
expect(source).toContain("@click=\"emit('toggleMaximize')\"");
expect(source).toContain('<Minimize2 v-if="props.maximized"');
expect(source).toContain("<Maximize2 v-else");
});
});
@@ -1,21 +0,0 @@
import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
const source = readFileSync(new URL("../AiAssistant.vue", import.meta.url), "utf8");
describe("AI assistant message copy actions", () => {
it("exposes copy actions below user and assistant messages", () => {
expect(source).toContain('data-ai-message-copy="user"');
expect(source).toContain('data-ai-message-copy="assistant"');
});
it("routes message copies through the body-only copy contract", () => {
expect(source).toContain("resolveAiMessageCopyText(msg, isStreamingMessage(msg))");
expect(source).toContain("copyAiContent(text, `message:${index}`)");
});
it("keeps code-block and message feedback keys separate", () => {
expect(source).toContain("copyAiContent(seg.content, `code:${i}:${j}`)");
expect(source).toContain("messageCopyKey(i)");
});
});
@@ -1,120 +0,0 @@
import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
const dialogSource = readFileSync(new URL("../EditorSettingsDialog.vue", import.meta.url), "utf8");
const templateSource = dialogSource.slice(dialogSource.indexOf("<template>"));
const styleSource = dialogSource.slice(dialogSource.indexOf("<style>"), dialogSource.indexOf("</style>"));
function sourceIndexForKey(key: string): number {
const index = templateSource.indexOf(`t("settings.${key}")`);
if (index < 0) throw new Error(`Missing settings key: ${key}`);
return index;
}
function tagEnd(source: string, start: number): number {
let quote: '"' | "'" | null = null;
for (let index = start; index < source.length; index += 1) {
const char = source[index];
if (quote) {
if (char === quote && source[index - 1] !== "\\") quote = null;
} else if (char === '"' || char === "'") {
quote = char;
} else if (char === ">") {
return index;
}
}
return -1;
}
function borderedSettingDivForKey(key: string): string {
const keyIndex = sourceIndexForKey(key);
let start = templateSource.lastIndexOf("<div", keyIndex);
while (start >= 0) {
const end = tagEnd(templateSource, start);
const tag = templateSource.slice(start, end + 1);
if (tag.includes("rounded") && tag.includes("border")) return tag;
start = templateSource.lastIndexOf("<div", start - 1);
}
throw new Error(`Missing bordered setting div for settings key: ${key}`);
}
function divTagForAttribute(attribute: string): string {
const index = templateSource.indexOf(attribute);
if (index < 0) throw new Error(`Missing template attribute: ${attribute}`);
let start = templateSource.lastIndexOf("<div", index);
while (start >= 0) {
const end = tagEnd(templateSource, start);
if (end >= index) return templateSource.slice(start, end + 1);
start = templateSource.lastIndexOf("<div", start - 1);
}
throw new Error(`Missing div for template attribute: ${attribute}`);
}
function settingItemDivForText(text: string): string {
const index = templateSource.indexOf(text);
if (index < 0) throw new Error(`Missing template text: ${text}`);
let start = templateSource.lastIndexOf("<div", index);
while (start >= 0) {
const end = tagEnd(templateSource, start);
const tag = templateSource.slice(start, end + 1);
if (tag.includes("settings-item")) return tag;
start = templateSource.lastIndexOf("<div", start - 1);
}
throw new Error(`Missing settings item for template text: ${text}`);
}
function borderedDivForText(text: string): string {
const index = templateSource.indexOf(text);
if (index < 0) throw new Error(`Missing template text: ${text}`);
let start = templateSource.lastIndexOf("<div", index);
while (start >= 0) {
const end = tagEnd(templateSource, start);
const tag = templateSource.slice(start, end + 1);
if (tag.includes("rounded") && tag.includes("border")) return tag;
start = templateSource.lastIndexOf("<div", start - 1);
}
throw new Error(`Missing bordered div for template text: ${text}`);
}
describe("EditorSettingsDialog standard item hover feedback", () => {
it("marks representative editor, navigation, data, toolbar, and update setting rows for the shared hover treatment", () => {
for (const key of ["showStatementRunButtons", "externalSqlEditorMaxMb", "dataGridTypeColorScheme", "exclusiveRightSidebarPanels", "updateDownloadSource"] as const) {
expect(borderedSettingDivForKey(key)).toContain("settings-item");
}
});
it("keeps hover feedback off rows while their controls are disabled", () => {
expect(settingItemDivForText('id="web-sql-file-upload-max-mb"')).toContain("'settings-item-disabled': !webSqlFileUploadMaxMbLoaded || webSqlFileUploadMaxMbLoading");
expect(settingItemDivForText('id="mcp-http-enabled"')).toContain("'settings-item-disabled': mcpHttpLoading || mcpHttpSaving");
expect(styleSource).toMatch(/\.settings-item:not\(\.settings-item-disabled\):not\(\.opacity-50\):hover/);
});
it("provides legacy color fallbacks before progressively enhancing hover colors", () => {
const fallbackStart = styleSource.indexOf(".settings-item:not(.settings-item-disabled):not(.opacity-50):hover");
const enhancementStart = styleSource.indexOf("@supports (background: color-mix(in oklab, black, white))");
expect(fallbackStart).toBeGreaterThan(-1);
expect(enhancementStart).toBeGreaterThan(fallbackStart);
expect(styleSource.slice(fallbackStart, enhancementStart)).toContain("background-color: var(--muted);");
expect(styleSource.slice(fallbackStart, enhancementStart)).toContain("border-color: var(--muted-foreground);");
expect(styleSource.slice(enhancementStart)).toContain("color-mix(in oklab");
});
it("limits shared hover feedback to independent rows instead of composite and informational containers", () => {
expect(divTagForAttribute('data-settings-search-id="data-grid-filter-view"')).not.toContain("settings-item");
expect(borderedSettingDivForKey("dataGridKeepFilterEditorExpanded")).toContain("settings-item");
for (const text of ['t("settings.mcpHttpWebServiceTitle")', 't("settings.mcpHttpUnsavedChangesHint")', "{{ mcpStatus.bin_path }}", 't("settings.mcpCursorConfigPath")', 't("settings.mcpQoderConfigPath")', 't("settings.supportInfoTitle")'] as const) {
expect(borderedDivForText(text)).not.toContain("settings-item");
}
});
it("uses direct selectors without styling nested descendants", () => {
expect(styleSource).not.toContain(".settings-item *");
expect(styleSource).not.toContain(".settings-item:hover *");
});
it("leaves choice cards and shortcut rows on their existing interaction styles", () => {
expect(borderedSettingDivForKey("showStatementRunButtons")).not.toContain("settings-choice-card");
expect(templateSource).toContain("settings-shortcut-row group");
});
});
@@ -1,23 +0,0 @@
import { readFileSync } from "node:fs";
import { resolve } from "node:path";
import { describe, expect, it } from "vitest";
// reka-ui's SelectItem throws on value="" (SelectItem.js: "A <SelectItem /> must
// have a value prop that is not an empty string"). The throw happens while the
// select's dismissable layer is up, and the leftover layer then blocks every
// click in the app — dialogs can no longer be closed. These dialogs use
// sentinel values instead; keep it that way.
const multiDbDialogSource = readFileSync(resolve(process.cwd(), "apps/desktop/src/components/editor/MultiDbExecuteDialog.vue"), "utf8");
const tagPanelSource = readFileSync(resolve(process.cwd(), "apps/desktop/src/components/config/TagManagementPanel.vue"), "utf8");
describe("Select empty-value regression guard", () => {
it("keeps the multi-db target-group select free of empty SelectItem values", () => {
expect(multiDbDialogSource).not.toMatch(/<SelectItem\s+value=""/);
expect(multiDbDialogSource).toContain("NO_GROUP_VALUE");
});
it("keeps the tag environment select free of empty SelectItem values", () => {
expect(tagPanelSource).not.toMatch(/<SelectItem\s+value=""/);
expect(tagPanelSource).toContain("ALL_ENVIRONMENTS");
});
});
@@ -1,10 +0,0 @@
import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
const dialogSource = readFileSync(new URL("../MultiDbExecuteDialog.vue", import.meta.url), "utf8");
describe("MultiDbExecuteDialog footer layout", () => {
it("keeps the target group manager close button aligned with the main dialog footer", () => {
expect(dialogSource).toContain('<DialogFooter class="mx-0 mb-0 shrink-0 border-t px-5 py-3">\n <Button variant="outline" @click="manageGroups = false">');
});
});
@@ -1,38 +0,0 @@
import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
const appSource = readFileSync(new URL("../../../App.vue", import.meta.url), "utf8");
const composableSource = readFileSync(new URL("../../../composables/useBackgroundImage.ts", import.meta.url), "utf8");
const globalsCss = readFileSync(new URL("../../../../src/styles/globals.css", import.meta.url), "utf8");
const queryEditorSource = readFileSync(new URL("../QueryEditor.vue", import.meta.url), "utf8");
const welcomeScreenSource = readFileSync(new URL("../../layout/WelcomeScreen.vue", import.meta.url), "utf8");
describe("global background image wiring", () => {
it("mounts a single app-level background layer behind all content", () => {
expect(appSource).toContain("data-app-background");
expect(appSource).toMatch(/pointer-events-none fixed inset-0 -z-10/);
expect(appSource).toContain("useBackgroundImage(settingsStore)");
});
it("toggles the wallpaper class on <html> and clears CodeMirror backgrounds app-wide", () => {
expect(composableSource).toContain('BACKGROUND_IMAGE_ACTIVE_CLASS = "dbx-bg-active"');
expect(globalsCss).toContain("html.dbx-bg-active .cm-editor");
expect(globalsCss).toContain("html.dbx-bg-active .cm-gutters");
});
it("keeps card and popover surfaces opaque (readability contract)", () => {
expect(composableSource).toContain("BACKGROUND_IMAGE_SURFACE_VARS");
const appBackground = readFileSync(new URL("../../../lib/app/appBackgroundImage.ts", import.meta.url), "utf8");
expect(appBackground).toContain('"--background"');
expect(appBackground).toContain('"--sidebar"');
expect(appBackground).not.toMatch(/"--card"|"--popover"/);
});
it("removed the scoped per-area mode (editor/welcome no longer render their own layers)", () => {
for (const source of [queryEditorSource, welcomeScreenSource]) {
expect(source).not.toContain("useBackgroundImage");
expect(source).not.toContain("data-query-editor-bg");
expect(source).not.toContain("data-welcome-bg");
}
});
});