86 lines
3.6 KiB
TypeScript
86 lines
3.6 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { readFileSync } from "node:fs";
|
|
import { test } from "vitest";
|
|
import { createOpenTabsRestorationBarrier, initializeDesktopOpenTabs } from "../../apps/desktop/src/lib/app/openTabsStartup.ts";
|
|
|
|
const appSource = readFileSync("apps/desktop/src/App.vue", "utf8");
|
|
|
|
test("desktop SQL file opening survives unrelated initialization failure and follows restored tabs", async () => {
|
|
const events: string[] = [];
|
|
const barrier = createOpenTabsRestorationBarrier();
|
|
const fileOpen = (async () => {
|
|
await barrier.settled;
|
|
events.push("read-file");
|
|
events.push("open-tab");
|
|
})();
|
|
|
|
await initializeDesktopOpenTabs({
|
|
barrier,
|
|
initializeOptionalState: async () => {
|
|
events.push("initialize-ai-configs");
|
|
throw new Error("AI config storage unavailable");
|
|
},
|
|
restoreOpenTabs: async () => {
|
|
events.push("initialize-editor-settings");
|
|
events.push("initialize-connections");
|
|
events.push("restore-tabs");
|
|
},
|
|
onOptionalStateError: () => events.push("ignore-ai-config-error"),
|
|
});
|
|
await fileOpen;
|
|
|
|
assert.deepEqual(events, ["initialize-ai-configs", "ignore-ai-config-error", "initialize-editor-settings", "initialize-connections", "restore-tabs", "read-file", "open-tab"]);
|
|
});
|
|
|
|
test("desktop SQL file opening is released when persisted tab restoration rejects", async () => {
|
|
const events: string[] = [];
|
|
const barrier = createOpenTabsRestorationBarrier();
|
|
const fileOpen = barrier.settled.then(() => events.push("open-file"));
|
|
|
|
await assert.rejects(
|
|
initializeDesktopOpenTabs({
|
|
barrier,
|
|
initializeOptionalState: async () => {},
|
|
restoreOpenTabs: async () => {
|
|
events.push("restore-tabs");
|
|
throw new Error("corrupt persisted tabs");
|
|
},
|
|
onOptionalStateError: () => {},
|
|
}),
|
|
/corrupt persisted tabs/,
|
|
);
|
|
await fileOpen;
|
|
|
|
assert.deepEqual(events, ["restore-tabs", "open-file"]);
|
|
});
|
|
|
|
test("cold-start SQL files wait for restored tabs before opening", () => {
|
|
const openPathStart = appSource.indexOf("async function openSqlFilePath");
|
|
const openPathEnd = appSource.indexOf("async function openPendingSqlFiles", openPathStart);
|
|
assert.ok(openPathStart >= 0 && openPathEnd > openPathStart);
|
|
|
|
const openPathSource = appSource.slice(openPathStart, openPathEnd);
|
|
const initializationWait = openPathSource.indexOf("await desktopOpenTabsRestorationBarrier?.settled");
|
|
const fileRead = openPathSource.indexOf("api.readExternalSqlFileSnapshot(path)");
|
|
const tabOpen = openPathSource.indexOf("queryStore.openExternalSqlFile");
|
|
assert.ok(initializationWait >= 0);
|
|
assert.ok(initializationWait < fileRead);
|
|
assert.ok(fileRead < tabOpen);
|
|
|
|
const mountedStart = appSource.indexOf("onMounted(async () =>");
|
|
const mountedEnd = appSource.indexOf("onUnmounted(", mountedStart);
|
|
assert.ok(mountedStart >= 0 && mountedEnd > mountedStart);
|
|
|
|
const mountedSource = appSource.slice(mountedStart, mountedEnd);
|
|
const barrierCreation = mountedSource.indexOf("desktopOpenTabsRestorationBarrier = createOpenTabsRestorationBarrier()");
|
|
const initializationStart = mountedSource.indexOf("void initApp()", barrierCreation);
|
|
const listenerSetup = mountedSource.indexOf("setupTauriListeners()", initializationStart);
|
|
const pendingFileOpen = mountedSource.indexOf("openPendingSqlFiles()");
|
|
assert.ok(barrierCreation >= 0);
|
|
assert.ok(initializationStart >= 0);
|
|
assert.ok(barrierCreation < initializationStart);
|
|
assert.ok(initializationStart < listenerSetup);
|
|
assert.ok(listenerSetup < pendingFileOpen);
|
|
assert.ok(initializationStart < pendingFileOpen);
|
|
});
|