Files
openidea/src/features/run/workflow.test.ts
T
Jaw 55836e1b49 chore: Format the codebase with oxfmt and check formatting in CI (#135)
Run oxfmt once over the whole repository (formatting only, no logic changes) and add `pnpm format:check` to the frontend CI job so unformatted code no longer builds up. `.oxfmtrc.json` now skips the generated theme docs, test fixtures and code blocks inside Markdown.

Co-authored-by: jaw52 <[email protected]>
2026-10-28 19:35:16 +08:00

84 lines
3.1 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { ConsoleModel } from "./console";
import { foldRows } from "./ConsoleView";
import { expandMacros, toolRunConfig } from "./externalTools";
import { DEFAULT_EXTERNAL_TOOL } from "@/platform/workflowSettings";
const ctx = {
projectRoot: "/p",
projectName: "demo",
filePath: "/p/src/main.rs",
line: 3,
column: 5,
selectedText: "sel",
};
describe("console settings", () => {
it("keeps the cycle buffer under the character limit", () => {
const m = new ConsoleModel({ maxChars: 100 });
for (let i = 0; i < 50; i++) m.append({ kind: "stdout", text: `line ${i}\n` });
const chars = m.lines.reduce((n, l) => n + l.text.length + 1, 0);
expect(chars).toBeLessThanOrEqual(100);
expect(m.lines.at(-1)?.text).toBe("line 49");
expect(m.text()).toContain("line 49");
expect(m.dropped).toBeGreaterThan(0);
});
it("folds runs of matching lines onto the previous line, single lines too", () => {
const m = new ConsoleModel();
m.append({ kind: "stderr", text: "Error\n at org.junit.A\n at org.junit.B\n at app.Main\n at org.junit.C\n" });
const rows = foldRows(m.lines, ["at org.junit."], new Set());
const show = (rs: typeof rows) =>
rs.map((r) =>
r.kind === "fold" ? `fold${r.fold.count}` : m.lines[r.index]!.text.trim() + (r.fold ? ` +${r.fold.count}` : ""),
);
expect(show(rows)).toEqual(["Error +2", "at app.Main +1"]);
const first = rows[0]!.kind === "line" ? rows[0]!.fold! : null;
const open = foldRows(m.lines, ["at org.junit."], new Set([first!.id]));
expect(show(open)).toEqual(["Error +2", "at org.junit.A", "at org.junit.B", "at app.Main +1"]);
expect(open[0]!.kind === "line" && open[0]!.fold?.expanded).toBe(true);
});
it("keeps a fold with no line before it as a row of its own", () => {
const m = new ConsoleModel();
m.append({ kind: "stdout", text: " at org.junit.A\nok\n" });
const rows = foldRows(m.lines, ["at org.junit."], new Set());
expect(rows.map((r) => r.kind)).toEqual(["fold", "line"]);
});
it("exposes the open (prompt) line", () => {
const m = new ConsoleModel();
m.append({ kind: "stdout", text: "done\nName: " });
expect(m.openLine?.text).toBe("Name: ");
m.append({ kind: "stdout", text: "x\n" });
expect(m.openLine).toBeNull();
});
});
describe("external tools", () => {
it("expands IDEA macros", () => {
expect(expandMacros("$FileName$ $FileNameWithoutExtension$ $FileExt$ $FileRelativePath$", ctx)).toBe(
"main.rs main rs src/main.rs",
);
expect(expandMacros("$ProjectFileDir$:$LineNumber$:$ColumnNumber$ $Unknown$ $Prompt$", ctx, "x")).toBe(
"/p:3:5 $Unknown$ x",
);
});
it("builds a run configuration with per-argument expansion", () => {
const tool = {
...DEFAULT_EXTERNAL_TOOL,
id: "t",
name: "Fmt",
program: "rustfmt",
arguments: `--edition 2021 "$FilePath$"`,
};
expect(toolRunConfig(tool, { ...ctx, filePath: "/p/my dir/a.rs" })).toMatchObject({
id: "external:t",
command: "rustfmt",
args: ["--edition", "2021", "/p/my dir/a.rs"],
cwd: "/p",
});
});
});