fix(sql): preserve file associations and list selection

This commit is contained in:
zipg authored and GitHub committed 2026-08-13 11:44:55 +08:00
1 parent 2e27f7a66a
commit e5a3917f7d
25 files changed
+558 -186

No files matched your search

@@ -5,6 +5,7 @@ const savedTarget = {
connectionId: "saved-connection",
database: "saved_database",
schema: "saved_schema",
catalog: "saved_catalog",
};
describe("saved SQL execution targets", () => {
@@ -46,11 +47,13 @@ describe("saved SQL execution targets", () => {
connectionId: "runtime-connection",
database: "runtime_database",
schema: "runtime_schema",
catalog: "runtime_catalog",
}),
).toEqual({
connectionId: "runtime-connection",
database: "runtime_database",
schema: "runtime_schema",
catalog: "runtime_catalog",
});
});
});
@@ -0,0 +1,40 @@
import { describe, expect, it } from "vitest";
import { savedSqlImportTarget } from "@/lib/savedSql/savedSqlImportTarget";
describe("savedSqlImportTarget", () => {
it("inherits an explicitly associated local file target at the library root", () => {
expect(savedSqlImportTarget({ connectionId: "conn-1", database: "sales", catalog: "hive" })).toEqual({
connectionId: "conn-1",
database: "sales",
catalog: "hive",
});
});
it("keeps an unassociated local file unassociated at the library root", () => {
expect(savedSqlImportTarget({ connectionId: "", database: "" })).toEqual({ connectionId: "", database: "" });
});
it("keeps the destination folder connection and inherits a matching database", () => {
expect(savedSqlImportTarget({ connectionId: "conn-1", database: "sales", catalog: "iceberg" }, { connectionId: "conn-1" })).toEqual({
connectionId: "conn-1",
database: "sales",
catalog: "iceberg",
});
});
it("does not apply a database from a different connection to the destination folder", () => {
expect(savedSqlImportTarget({ connectionId: "conn-2", database: "analytics" }, { connectionId: "conn-1" })).toEqual({
connectionId: "conn-1",
database: "",
catalog: undefined,
});
});
it("uses the destination folder for an unassociated source", () => {
expect(savedSqlImportTarget({ connectionId: "", database: "" }, { connectionId: "conn-1" })).toEqual({
connectionId: "conn-1",
database: "",
catalog: undefined,
});
});
});
@@ -0,0 +1,40 @@
import { describe, expect, it } from "vitest";
import { orderedListRangeAnchorIndex, orderedListSelectionIntent } from "@/lib/selection/orderedListSelection";
describe("orderedListSelectionIntent", () => {
it("uses Shift for range selection even when another modifier is also reported", () => {
expect(orderedListSelectionIntent({ shiftKey: true, metaKey: false, ctrlKey: false })).toBe("range");
expect(orderedListSelectionIntent({ shiftKey: true, metaKey: true, ctrlKey: false })).toBe("range");
expect(orderedListSelectionIntent({ shiftKey: true, metaKey: false, ctrlKey: true })).toBe("range");
});
it("uses Cmd or Ctrl for toggle selection", () => {
expect(orderedListSelectionIntent({ shiftKey: false, metaKey: true, ctrlKey: false })).toBe("toggle");
expect(orderedListSelectionIntent({ shiftKey: false, metaKey: false, ctrlKey: true })).toBe("toggle");
});
it("uses an unmodified click for single selection", () => {
expect(orderedListSelectionIntent({ shiftKey: false, metaKey: false, ctrlKey: false })).toBe("single");
});
});
describe("orderedListRangeAnchorIndex", () => {
const items = [
{ type: "file", id: "first" },
{ type: "folder", id: "folder" },
{ type: "file", id: "last" },
];
it("keeps the explicit selection anchor", () => {
expect(orderedListRangeAnchorIndex(items, 2, { type: "file", id: "first" })).toBe(2);
});
it("uses the active item when no explicit anchor exists", () => {
expect(orderedListRangeAnchorIndex(items, null, { type: "folder", id: "folder" })).toBe(1);
});
it("does not fall back to the first item without an anchor", () => {
expect(orderedListRangeAnchorIndex(items, null, null)).toBeNull();
expect(orderedListRangeAnchorIndex(items, null, { type: "file", id: "missing" })).toBeNull();
});
});
@@ -1,7 +1,7 @@
// @vitest-environment happy-dom
import { beforeEach, describe, expect, it } from "vitest";
import { EXTERNAL_SQL_FILE_TARGETS_STORAGE_KEY, MAX_EXTERNAL_SQL_FILE_TARGETS, rememberExternalSqlFileTarget, resolveExternalSqlFileTarget } from "@/lib/sql/externalSqlFileTarget";
import { EXTERNAL_SQL_FILE_TARGETS_STORAGE_KEY, MAX_EXTERNAL_SQL_FILE_TARGETS, rememberExternalSqlFileTarget, resolveExternalSqlFileTarget, unassociatedExternalSqlFileTarget } from "@/lib/sql/externalSqlFileTarget";
describe("external SQL file targets", () => {
beforeEach(() => {
@@ -9,20 +9,48 @@ describe("external SQL file targets", () => {
});
it("restores the saved data source across normalized file paths", () => {
rememberExternalSqlFileTarget(" C:\\work\\report.sql ", { connectionId: "saved-connection", database: "analytics" });
rememberExternalSqlFileTarget(" C:\\work\\report.sql ", { connectionId: "saved-connection", database: "sales", catalog: "hive" });
expect(resolveExternalSqlFileTarget("C:/work/report.sql", () => true, { connectionId: "fallback", database: "default" })).toEqual({
connectionId: "saved-connection",
database: "analytics",
database: "sales",
catalog: "hive",
});
});
it("keeps same-named databases in different catalogs distinct", () => {
rememberExternalSqlFileTarget("/work/hive.sql", { connectionId: "saved-connection", database: "sales", catalog: "hive" });
rememberExternalSqlFileTarget("/work/iceberg.sql", { connectionId: "saved-connection", database: "sales", catalog: "iceberg" });
expect(resolveExternalSqlFileTarget("/work/hive.sql", () => true, unassociatedExternalSqlFileTarget()).catalog).toBe("hive");
expect(resolveExternalSqlFileTarget("/work/iceberg.sql", () => true, unassociatedExternalSqlFileTarget()).catalog).toBe("iceberg");
});
it("treats historical records without catalog as the default catalog", () => {
localStorage.setItem(EXTERNAL_SQL_FILE_TARGETS_STORAGE_KEY, JSON.stringify([{ path: "/work/legacy.sql", connectionId: "saved-connection", database: "sales", updatedAt: 1 }]));
expect(resolveExternalSqlFileTarget("/work/legacy.sql", () => true, unassociatedExternalSqlFileTarget())).toEqual({
connectionId: "saved-connection",
database: "sales",
catalog: undefined,
});
});
it("keeps a new file path unassociated", () => {
expect(resolveExternalSqlFileTarget("/work/new.sql", () => true, unassociatedExternalSqlFileTarget())).toEqual({
connectionId: "",
database: "",
catalog: undefined,
});
});
it("falls back when the saved connection no longer exists", () => {
rememberExternalSqlFileTarget("/work/report.sql", { connectionId: "deleted-connection", database: "analytics" });
expect(resolveExternalSqlFileTarget("/work/report.sql", () => false, { connectionId: "fallback", database: "default" })).toEqual({
connectionId: "fallback",
database: "default",
expect(resolveExternalSqlFileTarget("/work/report.sql", () => false, unassociatedExternalSqlFileTarget())).toEqual({
connectionId: "",
database: "",
catalog: undefined,
});
});
@@ -47,6 +75,7 @@ describe("external SQL file targets", () => {
expect(resolveExternalSqlFileTarget(`/work/report-${MAX_EXTERNAL_SQL_FILE_TARGETS}.sql`, () => true, { connectionId: "fallback", database: "default" })).toEqual({
connectionId: `connection-${MAX_EXTERNAL_SQL_FILE_TARGETS}`,
database: `database-${MAX_EXTERNAL_SQL_FILE_TARGETS}`,
catalog: undefined,
});
});
});