summaryrefslogtreecommitdiffhomepage
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rw-r--r--scripts/text-file-environment.ts19
-rw-r--r--scripts/text-file-live.test.ts20
2 files changed, 22 insertions, 17 deletions
diff --git a/scripts/text-file-environment.ts b/scripts/text-file-environment.ts
new file mode 100644
index 0000000..6507be2
--- /dev/null
+++ b/scripts/text-file-environment.ts
@@ -0,0 +1,19 @@
+import type { Environment } from "vitest/environments";
+import { builtinEnvironments } from "vitest/environments";
+
+/** Real runtime fetch and AbortSignal must belong to the same implementation.
+ * jsdom supplies DOM APIs but replaces these globals with an incompatible realm.
+ * Keep the runtime's pair for this opt-in real-network component probe only.
+ */
+export default {
+ name: "text-file-jsdom",
+ transformMode: "web",
+ async setup(global, options) {
+ const controller = global.AbortController;
+ const signal = global.AbortSignal;
+ const environment = await builtinEnvironments.jsdom.setup(global, options);
+ global.AbortController = controller;
+ global.AbortSignal = signal;
+ return environment;
+ },
+} satisfies Environment;
diff --git a/scripts/text-file-live.test.ts b/scripts/text-file-live.test.ts
index 18d1cb6..3305616 100644
--- a/scripts/text-file-live.test.ts
+++ b/scripts/text-file-live.test.ts
@@ -2,24 +2,10 @@ import { type ChildProcess, spawn } from "node:child_process";
import { rm, writeFile } from "node:fs/promises";
import { resolve as resolvePath } from "node:path";
import { createInterface } from "node:readline";
-import { transferableAbortController } from "node:util";
import { fireEvent, render, screen } from "@testing-library/svelte";
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { createTextFileClient, Markdown } from "../src/features/markdown";
-// Bridge only the outer fetch edge's jsdom signal to Node's native signal.
-const networkFetch: typeof fetch = async (input, init) => {
- const controller = transferableAbortController();
- const abort = () => controller.abort();
- init?.signal?.addEventListener("abort", abort, { once: true });
- if (init?.signal?.aborted) controller.abort();
- try {
- return await fetch(input, { ...init, signal: controller.signal });
- } finally {
- init?.signal?.removeEventListener("abort", abort);
- }
-};
-
interface Fixture {
url: string;
path: string;
@@ -30,7 +16,7 @@ interface Fixture {
// Opt-in real cross-repo UI/network probe. Owns an ephemeral loopback server and
// temporary files only; never connects to or restarts the deployed application.
-// TEXT_FILE_LIVE_PROBE=1 bunx vitest run scripts/text-file-live.test.ts
+// bun run test:text-file-live
// The backend must be installed and typechecked first (workspace public dists).
describe.skipIf(process.env.TEXT_FILE_LIVE_PROBE !== "1")("live saved-file chat display", () => {
let child: ChildProcess;
@@ -86,7 +72,7 @@ describe.skipIf(process.env.TEXT_FILE_LIVE_PROBE !== "1")("live saved-file chat
const saved = Array.from({ length: 20 }, (_, i) => `## Saved step ${i + 1}`).join("\n");
await writeFile(fixture.path, saved);
const reply = "I saved the implementation plan.\n\n[Plan](text-file:plan%20100%25.md)";
- const client = createTextFileClient(fixture.url, fixture.conversationId, networkFetch);
+ const client = createTextFileClient(fixture.url, fixture.conversationId, fetch);
let view = render(Markdown, { text: reply, textFiles: client });
try {
await screen.findByRole("heading", { name: "Saved step 1" });
@@ -115,7 +101,7 @@ describe.skipIf(process.env.TEXT_FILE_LIVE_PROBE !== "1")("live saved-file chat
});
it("does not read the same local path for an authoritative remote conversation", async () => {
- const client = createTextFileClient(fixture.url, fixture.remoteConversationId, networkFetch);
+ const client = createTextFileClient(fixture.url, fixture.remoteConversationId, fetch);
const view = render(Markdown, {
text: `[Remote](text-file:${encodeURI(fixture.path)})`,
textFiles: client,