Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions test/extension/e2e/caret-handoff-mention-range.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,16 @@

import * as assert from "node:assert";
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import * as vscode from "vscode";
import { cleanupBetweenTests, getHarness, isDocumentEvent, tick, VIEW_TYPE } from "./harness";
import {
cleanupBetweenTests,
getHarness,
isDocumentEvent,
makeTempDir,
tick,
VIEW_TYPE,
} from "./harness";

const PROTOCOL = 1;
const INSERT_AT_MENTIONED = "claude-code.insertAtMentioned";
Expand All @@ -45,7 +51,7 @@ describe("caret-handoff does not clobber the ⌘⌥K mention range", function ()
});

it("keeps the reveal's line-range selection through the insertAtMentioned read", async () => {
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "quoll-e2e-"));
const dir = await makeTempDir("mention-range");
tempFile = path.join(dir, "mention-range.md");
await fs.writeFile(tempFile, "line0\nline1\nline2\nline3\n");
const uri = vscode.Uri.file(tempFile);
Expand Down Expand Up @@ -136,7 +142,7 @@ describe("caret-handoff does not clobber the ⌘⌥K mention range", function ()
// (2,5) — so the assertion can only pass if the ordinary switch actually
// applied the re-reported caret (latch consumed, not stranded; a stranded
// latch would skip the apply and leave the fresh editor at its default).
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "quoll-e2e-"));
const dir = await makeTempDir("mention-range-recovery");
tempFile = path.join(dir, "mention-range-recovery.md");
await fs.writeFile(tempFile, "line0\nline1\nline2\nline3\n");
const uri = vscode.Uri.file(tempFile);
Expand Down
16 changes: 11 additions & 5 deletions test/extension/e2e/caret-handoff.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import * as assert from "node:assert";
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import * as vscode from "vscode";
import { cleanupBetweenTests, getHarness, isDocumentEvent, tick, VIEW_TYPE } from "./harness";
import {
cleanupBetweenTests,
getHarness,
isDocumentEvent,
makeTempDir,
tick,
VIEW_TYPE,
} from "./harness";

const PROTOCOL = 1;

Expand All @@ -25,7 +31,7 @@ describe("caret-handoff", function () {
});

it("caret-report inbound mutates no document and posts no Document event (reducer bypass)", async () => {
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "quoll-e2e-"));
const dir = await makeTempDir("caret-bypass");
tempFile = path.join(dir, "caret-bypass.md");
await fs.writeFile(tempFile, "line0\nline1\nline2\n");
const uri = vscode.Uri.file(tempFile);
Expand Down Expand Up @@ -76,7 +82,7 @@ describe("caret-handoff", function () {
});

it("applies the tracked caret to the live text editor on Quoll→text-editor switch", async () => {
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "quoll-e2e-"));
const dir = await makeTempDir("caret-apply");
tempFile = path.join(dir, "caret-apply.md");
await fs.writeFile(tempFile, "line0\nline1\nline2\nline3\n");
const uri = vscode.Uri.file(tempFile);
Expand Down Expand Up @@ -109,7 +115,7 @@ describe("caret-handoff", function () {
});

it("posts a caret-apply with the tracked caret on text-editor→Quoll switch (Codex #1)", async () => {
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "quoll-e2e-"));
const dir = await makeTempDir("caret-push");
tempFile = path.join(dir, "caret-push.md");
await fs.writeFile(tempFile, "line0\nline1\nline2\nline3\nline4\n");
const uri = vscode.Uri.file(tempFile);
Expand Down
4 changes: 2 additions & 2 deletions test/extension/e2e/crlf-roundtrip.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as assert from "node:assert";
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import * as vscode from "vscode";
import { PROTOCOL_VERSION } from "./constants";
Expand All @@ -9,6 +8,7 @@ import {
getHarness,
isDocumentAfter,
isDocumentEvent,
makeTempDir,
VIEW_TYPE,
} from "./harness";

Expand Down Expand Up @@ -47,7 +47,7 @@ describe("crlf-roundtrip", function () {
it("preserves \\r\\n bytes end-to-end through the host write path", async () => {
// Per-test temp file (mirrors external-edit-propagates) so a mid-test
// failure does not leave a shared fixture dirty for subsequent tests.
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "quoll-e2e-crlf-"));
const dir = await makeTempDir("crlf");
tempFile = path.join(dir, "crlf.md");
// Initial on-disk bytes: pure CRLF. The trailing CRLF after the last
// line gives the file two distinct CRLF separators so a single-
Expand Down
11 changes: 8 additions & 3 deletions test/extension/e2e/decoration-external-edit-boundary.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@

import * as assert from "node:assert";
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import * as vscode from "vscode";
import { cleanupBetweenTests, getHarness, isDocumentEvent, VIEW_TYPE } from "./harness";
import {
cleanupBetweenTests,
getHarness,
isDocumentEvent,
makeTempDir,
VIEW_TYPE,
} from "./harness";

describe("C4a external-edit byte-identity across a token boundary", function () {
this.timeout(20000);
Expand All @@ -36,7 +41,7 @@ describe("C4a external-edit byte-identity across a token boundary", function ()
// Per-test temp file so a mid-test failure does not leave any shared
// fixture dirty for subsequent tests. Mirrors the pattern used by
// external-edit-propagates.test.ts.
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "quoll-e2e-c4a-"));
const dir = await makeTempDir("c4a");
tempFile = path.join(dir, "boundary.md");
const initial = "**bold** rest";
await fs.writeFile(tempFile, initial);
Expand Down
4 changes: 2 additions & 2 deletions test/extension/e2e/dirty-doc-disk-conflict.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@

import * as assert from "node:assert";
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import * as vscode from "vscode";
import {
cleanupBetweenTests,
getHarness,
isDocumentAfter,
isDocumentEvent,
makeTempDir,
VIEW_TYPE,
} from "./harness";

Expand Down Expand Up @@ -51,7 +51,7 @@ describe("dirty-doc-disk-conflict", function () {
// Open the temp file in Quoll, seed, then dirty it via an in-session edit that
// does NOT match disk. Returns the seed docVersion.
async function openAndDirty(bodyEdit: string): Promise<number> {
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "quoll-e2e-dirty-conflict-"));
tempDir = await makeTempDir("dirty-conflict");
tempFile = path.join(tempDir, "dirty-conflict.md");
await fs.writeFile(tempFile, "# Initial\n\nbody\n");
const uri = vscode.Uri.file(tempFile);
Expand Down
8 changes: 4 additions & 4 deletions test/extension/e2e/external-edit-propagates.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as assert from "node:assert";
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import * as vscode from "vscode";
import { PROTOCOL_VERSION } from "./constants";
Expand All @@ -10,6 +9,7 @@ import {
getHarness,
isDocumentAfter,
isDocumentEvent,
makeTempDir,
tick,
VIEW_TYPE,
} from "./harness";
Expand All @@ -36,7 +36,7 @@ describe("external-edit-propagates", function () {
it("propagates an externally-applied WorkspaceEdit as a higher-docVersion Document", async () => {
// Per-test temp file so a mid-test failure does not leave the
// shared fixture dirty for subsequent tests.
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "quoll-e2e-"));
const dir = await makeTempDir("ext-edit");
tempFile = path.join(dir, "ext-edit.md");
await fs.writeFile(tempFile, "# Initial\n\nbody\n");
const uri = vscode.Uri.file(tempFile);
Expand Down Expand Up @@ -75,7 +75,7 @@ describe("external-edit-propagates", function () {
});

it("coalesces a burst of lock-free external edits into fewer Document posts (latest wins)", async () => {
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "quoll-e2e-"));
const dir = await makeTempDir("ext-edit-burst");
tempFile = path.join(dir, "ext-edit-burst.md");
await fs.writeFile(tempFile, "# Initial\n\nbody\n");
const uri = vscode.Uri.file(tempFile);
Expand Down Expand Up @@ -143,7 +143,7 @@ describe("external-edit-propagates", function () {
});

it("dispatches a lock-held racing external edit immediately (refused settlement posts the live version)", async () => {
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "quoll-e2e-"));
const dir = await makeTempDir("lock-race");
tempFile = path.join(dir, "lock-race.md");
await fs.writeFile(tempFile, "# Initial\n\nbody\n");
const uri = vscode.Uri.file(tempFile);
Expand Down
4 changes: 2 additions & 2 deletions test/extension/e2e/external-fs-write-propagates.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@

import * as assert from "node:assert";
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import * as vscode from "vscode";
import {
cleanupBetweenTests,
getHarness,
isDocumentAfter,
isDocumentEvent,
makeTempDir,
VIEW_TYPE,
} from "./harness";
import type { DocumentMessageShape, RecordedEventShape } from "./types";
Expand Down Expand Up @@ -70,7 +70,7 @@ describe("external-fs-write-propagates", function () {
it("propagates an out-of-process fs.writeFile as a higher-docVersion Document", async () => {
// Per-test temp dir so a mid-test failure does not leave the shared
// fixture dirty for subsequent tests (mirrors external-edit-propagates).
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "quoll-e2e-fswrite-"));
tempDir = await makeTempDir("fswrite");
tempFile = path.join(tempDir, "ext-fs-write.md");
await fs.writeFile(tempFile, "# Initial\n\nbody\n");
const uri = vscode.Uri.file(tempFile);
Expand Down
5 changes: 2 additions & 3 deletions test/extension/e2e/format-document-active-edge.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import * as assert from "node:assert";
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import * as vscode from "vscode";
import { PROTOCOL_VERSION } from "./constants";
import { cleanupBetweenTests, getHarness, tick, VIEW_TYPE } from "./harness";
import { cleanupBetweenTests, getHarness, makeTempDir, tick, VIEW_TYPE } from "./harness";
import type { PanelControlsShape, TestHarnessShape } from "./types";

// Pins the host-side routing of `quoll.formatDocument`: the command forwards a
Expand Down Expand Up @@ -43,7 +42,7 @@ async function openTempQuoll(
slug: string,
previous: PanelControlsShape | null
): Promise<{ uri: vscode.Uri; file: string; panel: PanelControlsShape }> {
const dir = await fs.mkdtemp(path.join(os.tmpdir(), `quoll-fmtdoc-${slug}-`));
const dir = await makeTempDir(`fmtdoc-${slug}`);
const file = path.join(dir, `${slug}.md`);
await fs.writeFile(file, content);
const uri = vscode.Uri.file(file);
Expand Down
4 changes: 2 additions & 2 deletions test/extension/e2e/handoff-edit-applied-barrier.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

import * as assert from "node:assert";
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import * as vscode from "vscode";
import { PROTOCOL_VERSION } from "./constants";
Expand All @@ -21,6 +20,7 @@ import {
deferred,
getHarness,
isDocumentEvent,
makeTempDir,
tick,
VIEW_TYPE,
} from "./harness";
Expand All @@ -41,7 +41,7 @@ describe("handoff edit-applied barrier", function () {
// its uri. The seed content is short (3 lines) so the applied 40-line clamp
// is non-vacuous.
const openTempDoc = async (): Promise<vscode.Uri> => {
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "quoll-e2e-barrier-"));
tempDir = await makeTempDir("barrier");
const tempFile = path.join(tempDir, "barrier.md");
await fs.writeFile(tempFile, "# seed\n\nbody\n");
const uri = vscode.Uri.file(tempFile);
Expand Down
12 changes: 10 additions & 2 deletions test/extension/e2e/harness.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import * as vscode from "vscode";
import { makeTempDir } from "../temp-root";
import type {
DocumentMessageShape,
EditorConfigMessageShape,
Expand All @@ -15,6 +15,14 @@ import type {
export const EXTENSION_ID = "mtskf.quoll";
export const VIEW_TYPE = "quoll.editMarkdown";

// Every temp dir an E2E suite creates lives under the run root that
// launch.ts made and disposes on exit — that single owner is why no suite
// needs dir teardown of its own, and why nothing here ever globs
// `quoll-e2e-*` (a parallel run owns its own root). Suites must NOT call
// fs.mkdtemp(os.tmpdir(), …); test/extension/temp-dir-choke-point.test.ts
// enforces that. Re-exported so suites keep importing from "./harness".
export { makeTempDir, makeTempDirSync } from "../temp-root";

// __dirname at runtime is `out/test-e2e/e2e/`. Resolve up to the
// repo root then back into the source-controlled fixtures directory.
// Avoids needing to copy *.md into out/ as a build step.
Expand Down Expand Up @@ -178,7 +186,7 @@ export async function openTempQuoll(
slug: string,
previous: PanelControlsShape | null
): Promise<{ uri: vscode.Uri; file: string; panel: PanelControlsShape }> {
const dir = await fs.mkdtemp(path.join(os.tmpdir(), `quoll-e2e-${slug}-`));
const dir = await makeTempDir(slug);
const file = path.join(dir, `${slug}.md`);
await fs.writeFile(file, content);
const uri = vscode.Uri.file(file);
Expand Down
12 changes: 9 additions & 3 deletions test/extension/e2e/hidden-webview-resync.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import * as assert from "node:assert";
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import * as vscode from "vscode";
import { cleanupBetweenTests, getHarness, isDocumentEvent, tick, VIEW_TYPE } from "./harness";
import {
cleanupBetweenTests,
getHarness,
isDocumentEvent,
makeTempDir,
tick,
VIEW_TYPE,
} from "./harness";

describe("hidden-webview-resync", function () {
this.timeout(25000);
Expand All @@ -24,7 +30,7 @@ describe("hidden-webview-resync", function () {
});

it("posts a fresh Document when a hidden panel becomes visible after an external edit", async () => {
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "quoll-e2e-"));
const dir = await makeTempDir("hidden");
tempFile = path.join(dir, "hidden.md");
await fs.writeFile(tempFile, "# Original\n");
const uri = vscode.Uri.file(tempFile);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import * as assert from "node:assert";
import * as fs from "node:fs";
import * as os from "node:os";
import * as path from "node:path";
import * as vscode from "vscode";
import { PROTOCOL_VERSION } from "./constants";
Expand All @@ -10,6 +9,7 @@ import {
getHarness,
hideQuollByOpeningOtherDoc,
isDocumentEvent,
makeTempDirSync,
openFixtureWithQuoll,
tick,
VIEW_TYPE,
Expand All @@ -22,7 +22,7 @@ const isEditRejectedEvent = (e: { message: { type: string } }) =>
// resumption case, and the revert-check of the deferred-race guard) writes to a
// throwaway file instead of mutating a committed fixture.
function tempMd(name: string): vscode.Uri {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "quoll-reject-"));
const dir = makeTempDirSync("reject");
const p = path.join(dir, name);
fs.writeFileSync(p, "# Title\n\nbody\n", "utf8");
return vscode.Uri.file(p);
Expand Down
9 changes: 4 additions & 5 deletions test/extension/e2e/lint-diagnostics-propagate.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import * as assert from "node:assert";
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import * as vscode from "vscode";
import { cleanupBetweenTests, getHarness, VIEW_TYPE } from "./harness";
import { cleanupBetweenTests, getHarness, makeTempDir, VIEW_TYPE } from "./harness";

// Poll vscode.languages.getDiagnostics(uri) until `predicate` holds or the
// deadline passes. Lint is debounced (250ms) in the webview, then posted across
Expand Down Expand Up @@ -52,7 +51,7 @@ describe("lint-diagnostics-propagate", function () {
});

it("mirrors lint into Problems with correct range, updates on fix, reopens, clears on close", async () => {
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "quoll-lint-e2e-"));
const dir = await makeTempDir("lint");
tempFile = path.join(dir, "heading-skip.md");
// h1 -> h3 skips h2: heading-increment (MD001-equivalent) warning on "### Skip".
await fs.writeFile(tempFile, "# Title\n\n### Skip\n");
Expand Down Expand Up @@ -113,7 +112,7 @@ describe("lint-diagnostics-propagate", function () {
});

it("maps ranges correctly for a CRLF document (line/character is EOL-invariant)", async () => {
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "quoll-lint-crlf-"));
const dir = await makeTempDir("lint-crlf");
tempFile = path.join(dir, "crlf.md");
// Same violation, CRLF line endings. An offset-based wire would mis-place
// the range (CM is LF-internal, the TextDocument is CRLF); line/character
Expand Down Expand Up @@ -147,7 +146,7 @@ describe("lint-diagnostics-propagate", function () {
// (Task 3) and toLintDiagnostics is host-document-independent (Task 2), so the
// host reproduces exactly the ranges the webview computed for its content.
it("surfaces a violation introduced by an external edit, at the correct line", async () => {
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "quoll-lint-dyn-"));
const dir = await makeTempDir("lint-dyn");
tempFile = path.join(dir, "baseline.md");
// Line 0 carries a single trailing space → a STABLE `no-trailing-spaces`
// finding (a single trailing space is flagged; only exactly two on a
Expand Down
Loading
Loading