pi-lens 3.6.2 → 3.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -2
- package/package.json +4 -4
- package/tsconfig.json +1 -1
- package/clients/__tests__/file-time.test.js +0 -216
- package/clients/__tests__/file-time.test.ts +0 -276
- package/clients/__tests__/format-service.test.js +0 -245
- package/clients/__tests__/format-service.test.ts +0 -339
- package/clients/__tests__/formatters.test.js +0 -271
- package/clients/__tests__/formatters.test.ts +0 -401
- package/clients/agent-behavior-client.js +0 -110
- package/clients/agent-behavior-client.test.js +0 -94
- package/clients/agent-behavior-client.test.ts +0 -116
- package/clients/amain-types.js +0 -164
- package/clients/architect-client.js +0 -291
- package/clients/ast-grep-client.js +0 -253
- package/clients/ast-grep-parser.js +0 -84
- package/clients/ast-grep-rule-manager.js +0 -89
- package/clients/ast-grep-types.js +0 -9
- package/clients/auto-loop.js +0 -131
- package/clients/biome-client.js +0 -420
- package/clients/biome-client.test.js +0 -144
- package/clients/biome-client.test.ts +0 -163
- package/clients/cache/rule-cache.js +0 -72
- package/clients/cache-manager.js +0 -245
- package/clients/cache-manager.test.js +0 -197
- package/clients/cache-manager.test.ts +0 -299
- package/clients/complexity-client.js +0 -675
- package/clients/complexity-client.test.js +0 -234
- package/clients/complexity-client.test.ts +0 -255
- package/clients/config-validator.js +0 -465
- package/clients/dependency-checker.js +0 -325
- package/clients/dependency-checker.test.js +0 -60
- package/clients/dependency-checker.test.ts +0 -71
- package/clients/dispatch/__tests__/autofix-integration.test.js +0 -245
- package/clients/dispatch/__tests__/autofix-integration.test.ts +0 -300
- package/clients/dispatch/__tests__/runner-registration.test.js +0 -234
- package/clients/dispatch/__tests__/runner-registration.test.ts +0 -286
- package/clients/dispatch/debug.log +0 -1
- package/clients/dispatch/dispatcher.edge.test.js +0 -82
- package/clients/dispatch/dispatcher.edge.test.ts +0 -100
- package/clients/dispatch/dispatcher.format.test.js +0 -46
- package/clients/dispatch/dispatcher.format.test.ts +0 -58
- package/clients/dispatch/dispatcher.inline.test.js +0 -74
- package/clients/dispatch/dispatcher.inline.test.ts +0 -93
- package/clients/dispatch/dispatcher.js +0 -381
- package/clients/dispatch/dispatcher.test.js +0 -116
- package/clients/dispatch/dispatcher.test.ts +0 -149
- package/clients/dispatch/integration.js +0 -108
- package/clients/dispatch/plan.js +0 -183
- package/clients/dispatch/runners/architect.js +0 -83
- package/clients/dispatch/runners/architect.test.js +0 -138
- package/clients/dispatch/runners/architect.test.ts +0 -162
- package/clients/dispatch/runners/ast-grep-napi.js +0 -405
- package/clients/dispatch/runners/ast-grep-napi.test.js +0 -107
- package/clients/dispatch/runners/ast-grep-napi.test.ts +0 -129
- package/clients/dispatch/runners/ast-grep.js +0 -157
- package/clients/dispatch/runners/biome.js +0 -55
- package/clients/dispatch/runners/config-validation.js +0 -67
- package/clients/dispatch/runners/go-vet.js +0 -48
- package/clients/dispatch/runners/index.js +0 -47
- package/clients/dispatch/runners/lsp.js +0 -102
- package/clients/dispatch/runners/oxlint.js +0 -67
- package/clients/dispatch/runners/oxlint.test.js +0 -230
- package/clients/dispatch/runners/oxlint.test.ts +0 -303
- package/clients/dispatch/runners/pyright.js +0 -100
- package/clients/dispatch/runners/pyright.test.js +0 -98
- package/clients/dispatch/runners/pyright.test.ts +0 -121
- package/clients/dispatch/runners/python-slop.js +0 -97
- package/clients/dispatch/runners/python-slop.test.js +0 -203
- package/clients/dispatch/runners/python-slop.test.ts +0 -298
- package/clients/dispatch/runners/ruff.js +0 -48
- package/clients/dispatch/runners/rust-clippy.js +0 -102
- package/clients/dispatch/runners/scan_codebase.test.js +0 -89
- package/clients/dispatch/runners/scan_codebase.test.ts +0 -105
- package/clients/dispatch/runners/shellcheck.js +0 -147
- package/clients/dispatch/runners/shellcheck.test.js +0 -98
- package/clients/dispatch/runners/shellcheck.test.ts +0 -129
- package/clients/dispatch/runners/similarity.js +0 -230
- package/clients/dispatch/runners/spellcheck.js +0 -106
- package/clients/dispatch/runners/spellcheck.test.js +0 -158
- package/clients/dispatch/runners/spellcheck.test.ts +0 -214
- package/clients/dispatch/runners/tree-sitter.js +0 -246
- package/clients/dispatch/runners/ts-lsp.js +0 -125
- package/clients/dispatch/runners/ts-slop.js +0 -113
- package/clients/dispatch/runners/type-safety.js +0 -142
- package/clients/dispatch/runners/utils/diagnostic-parsers.js +0 -134
- package/clients/dispatch/runners/utils/runner-helpers.js +0 -115
- package/clients/dispatch/runners/utils.js +0 -51
- package/clients/dispatch/runners/yaml-rule-parser.js +0 -360
- package/clients/dispatch/types.js +0 -16
- package/clients/dispatch/utils/format-utils.js +0 -44
- package/clients/dogfood.test.js +0 -201
- package/clients/dogfood.test.ts +0 -269
- package/clients/file-kinds.js +0 -177
- package/clients/file-kinds.test.js +0 -169
- package/clients/file-kinds.test.ts +0 -210
- package/clients/file-time.js +0 -152
- package/clients/file-utils.js +0 -40
- package/clients/fix-scanners.js +0 -204
- package/clients/format-service.js +0 -184
- package/clients/formatters.js +0 -488
- package/clients/go-client.js +0 -203
- package/clients/go-client.test.js +0 -127
- package/clients/go-client.test.ts +0 -143
- package/clients/installer/index.js +0 -403
- package/clients/interviewer-templates.js +0 -75
- package/clients/interviewer.js +0 -173
- package/clients/jscpd-client.js +0 -196
- package/clients/jscpd-client.test.js +0 -127
- package/clients/jscpd-client.test.ts +0 -145
- package/clients/knip-client.js +0 -239
- package/clients/knip-client.test.js +0 -112
- package/clients/knip-client.test.ts +0 -128
- package/clients/latency-logger.js +0 -40
- package/clients/lsp/__tests__/client.test.js +0 -310
- package/clients/lsp/__tests__/client.test.ts +0 -412
- package/clients/lsp/__tests__/config.test.js +0 -167
- package/clients/lsp/__tests__/config.test.ts +0 -217
- package/clients/lsp/__tests__/error-recovery.test.js +0 -213
- package/clients/lsp/__tests__/error-recovery.test.ts +0 -279
- package/clients/lsp/__tests__/integration.test.js +0 -127
- package/clients/lsp/__tests__/integration.test.ts +0 -160
- package/clients/lsp/__tests__/launch.test.js +0 -313
- package/clients/lsp/__tests__/launch.test.ts +0 -394
- package/clients/lsp/__tests__/server.test.js +0 -259
- package/clients/lsp/__tests__/server.test.ts +0 -332
- package/clients/lsp/__tests__/service.test.js +0 -438
- package/clients/lsp/__tests__/service.test.ts +0 -530
- package/clients/lsp/client.js +0 -350
- package/clients/lsp/config.js +0 -112
- package/clients/lsp/index.js +0 -318
- package/clients/lsp/installer/index.js +0 -391
- package/clients/lsp/interactive-install.js +0 -221
- package/clients/lsp/language.js +0 -170
- package/clients/lsp/launch.js +0 -329
- package/clients/lsp/lsp/launch.js +0 -116
- package/clients/lsp/lsp/server.js +0 -532
- package/clients/lsp/lsp-index.js +0 -10
- package/clients/lsp/path-utils.js +0 -5
- package/clients/lsp/server.js +0 -725
- package/clients/lsp/test-py-spawn/requirements.txt +0 -1
- package/clients/lsp/test-py-spawn/test.py +0 -3
- package/clients/lsp/test-py-svc/requirements.txt +0 -1
- package/clients/lsp/test-py-svc/test.py +0 -3
- package/clients/lsp/test-python-project/requirements.txt +0 -1
- package/clients/lsp/test-python-project/test.py +0 -5
- package/clients/metrics-client.js +0 -107
- package/clients/metrics-client.test.js +0 -128
- package/clients/metrics-client.test.ts +0 -163
- package/clients/metrics-history.js +0 -367
- package/clients/path-utils.js +0 -142
- package/clients/pipeline.js +0 -272
- package/clients/production-readiness.js +0 -522
- package/clients/project-index.js +0 -255
- package/clients/project-metadata.js +0 -531
- package/clients/ruff-client.js +0 -325
- package/clients/ruff-client.test.js +0 -132
- package/clients/ruff-client.test.ts +0 -153
- package/clients/rules-scanner.js +0 -97
- package/clients/runner-tracker.js +0 -152
- package/clients/rust-client.js +0 -205
- package/clients/rust-client.test.js +0 -108
- package/clients/rust-client.test.ts +0 -130
- package/clients/safe-spawn-async.js +0 -163
- package/clients/safe-spawn.js +0 -241
- package/clients/sanitize.js +0 -291
- package/clients/sanitize.test.js +0 -177
- package/clients/sanitize.test.ts +0 -223
- package/clients/scan-architectural-debt.js +0 -167
- package/clients/scan-utils.js +0 -83
- package/clients/secrets-scanner.js +0 -119
- package/clients/secrets-scanner.test.js +0 -100
- package/clients/secrets-scanner.test.ts +0 -113
- package/clients/sg-runner.js +0 -292
- package/clients/state-matrix.js +0 -160
- package/clients/subprocess-client.js +0 -65
- package/clients/symbol-types.js +0 -5
- package/clients/test-runner-client.js +0 -523
- package/clients/test-runner-client.test.js +0 -192
- package/clients/test-runner-client.test.ts +0 -253
- package/clients/test-utils.js +0 -27
- package/clients/test-utils.ts +0 -36
- package/clients/todo-scanner.js +0 -200
- package/clients/todo-scanner.test.js +0 -301
- package/clients/todo-scanner.test.ts +0 -352
- package/clients/tool-availability.js +0 -207
- package/clients/tree-sitter-client.js +0 -601
- package/clients/tree-sitter-query-loader.js +0 -355
- package/clients/tree-sitter-symbol-extractor.js +0 -289
- package/clients/ts-service.js +0 -129
- package/clients/type-coverage-client.js +0 -127
- package/clients/type-coverage-client.test.js +0 -105
- package/clients/type-coverage-client.test.ts +0 -125
- package/clients/type-safety-client.js +0 -138
- package/clients/types.js +0 -11
- package/clients/typescript-client.codefix.test.js +0 -157
- package/clients/typescript-client.codefix.test.ts +0 -186
- package/clients/typescript-client.js +0 -509
- package/clients/typescript-client.test.js +0 -105
- package/clients/typescript-client.test.ts +0 -126
- package/commands/booboo.js +0 -1007
- package/commands/fix-from-booboo.js +0 -398
- package/commands/fix-simplified.js +0 -618
- package/commands/rate.js +0 -281
- package/commands/rate.test.js +0 -119
- package/commands/rate.test.ts +0 -131
- package/commands/refactor.js +0 -130
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Spellcheck runner for dispatch system
|
|
3
|
-
*
|
|
4
|
-
* Uses typos-cli (Rust-based, fast, zero-config) to check spelling in:
|
|
5
|
-
* - Markdown files (.md, .mdx)
|
|
6
|
-
* - Code comments (optional, if typos is configured)
|
|
7
|
-
*
|
|
8
|
-
* Key features:
|
|
9
|
-
* - Fast (Rust-based, ~10x faster than cspell)
|
|
10
|
-
* - Low false positives (only checks known typos)
|
|
11
|
-
* - Zero-config by default
|
|
12
|
-
* - JSON output for easy parsing
|
|
13
|
-
*
|
|
14
|
-
* Alternative considered: cspell
|
|
15
|
-
* - cspell: More comprehensive, but higher false positives, needs config
|
|
16
|
-
* - typos-cli: Faster, less noise, works out of the box
|
|
17
|
-
*
|
|
18
|
-
* Install: cargo install typos-cli
|
|
19
|
-
* Or: npm install -g typos-cli (if wrapped)
|
|
20
|
-
*/
|
|
21
|
-
import { safeSpawn } from "../../safe-spawn.js";
|
|
22
|
-
import { createAvailabilityChecker } from "./utils/runner-helpers.js";
|
|
23
|
-
const typos = createAvailabilityChecker("typos", ".exe");
|
|
24
|
-
/**
|
|
25
|
-
* Parse typos-cli JSON output (JSON Lines format)
|
|
26
|
-
*
|
|
27
|
-
* Each line is a JSON object:
|
|
28
|
-
* {
|
|
29
|
-
* "path": "file.md",
|
|
30
|
-
* "line_num": 42,
|
|
31
|
-
* "byte_offset": 1234,
|
|
32
|
-
* "typo": "recieve",
|
|
33
|
-
* "corrections": ["receive"]
|
|
34
|
-
* }
|
|
35
|
-
*/
|
|
36
|
-
function parseTyposOutput(raw, filePath) {
|
|
37
|
-
const diagnostics = [];
|
|
38
|
-
if (!raw.trim()) {
|
|
39
|
-
return diagnostics;
|
|
40
|
-
}
|
|
41
|
-
const lines = raw.trim().split("\n").filter((l) => l.trim());
|
|
42
|
-
for (const line of lines) {
|
|
43
|
-
try {
|
|
44
|
-
const parsed = JSON.parse(line);
|
|
45
|
-
if (!parsed.typo || !parsed.line_num)
|
|
46
|
-
continue;
|
|
47
|
-
const corrections = parsed.corrections?.join(", ") || "no suggestions";
|
|
48
|
-
const message = `Typo: "${parsed.typo}" → ${corrections}`;
|
|
49
|
-
diagnostics.push({
|
|
50
|
-
id: `typos-${parsed.line_num}-${parsed.typo}`,
|
|
51
|
-
message,
|
|
52
|
-
filePath,
|
|
53
|
-
line: parsed.line_num,
|
|
54
|
-
column: 1, // typos-cli doesn't provide column, just byte offset
|
|
55
|
-
severity: "warning",
|
|
56
|
-
semantic: "warning",
|
|
57
|
-
tool: "typos",
|
|
58
|
-
rule: "typo",
|
|
59
|
-
fixable: !!parsed.corrections?.length,
|
|
60
|
-
fixSuggestion: parsed.corrections?.[0],
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
catch {
|
|
64
|
-
// Skip invalid JSON lines
|
|
65
|
-
continue;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return diagnostics;
|
|
69
|
-
}
|
|
70
|
-
const spellcheckRunner = {
|
|
71
|
-
id: "spellcheck",
|
|
72
|
-
appliesTo: ["markdown"],
|
|
73
|
-
priority: 30, // Run after code quality checks (biome=10, slop=25)
|
|
74
|
-
enabledByDefault: true,
|
|
75
|
-
skipTestFiles: false, // Check docs in test files too
|
|
76
|
-
async run(ctx) {
|
|
77
|
-
// Skip if typos-cli is not installed
|
|
78
|
-
if (!typos.isAvailable(ctx.cwd || process.cwd())) {
|
|
79
|
-
return { status: "skipped", diagnostics: [], semantic: "none" };
|
|
80
|
-
}
|
|
81
|
-
// Run typos-cli with JSON output
|
|
82
|
-
// --format json: Output JSON Lines
|
|
83
|
-
// --exclude <pattern>: Could be used to exclude code blocks if needed
|
|
84
|
-
const args = ["--format", "json", ctx.filePath];
|
|
85
|
-
const result = safeSpawn(typos.getCommand(), args, {
|
|
86
|
-
timeout: 15000,
|
|
87
|
-
});
|
|
88
|
-
// typos-cli exits with code 2 if typos found, 0 if clean
|
|
89
|
-
const hasTypos = result.status === 2 || result.stdout?.trim();
|
|
90
|
-
if (!hasTypos) {
|
|
91
|
-
return { status: "succeeded", diagnostics: [], semantic: "none" };
|
|
92
|
-
}
|
|
93
|
-
// Parse diagnostics
|
|
94
|
-
const raw = result.stdout + result.stderr;
|
|
95
|
-
const diagnostics = parseTyposOutput(raw, ctx.filePath);
|
|
96
|
-
if (diagnostics.length === 0) {
|
|
97
|
-
return { status: "succeeded", diagnostics: [], semantic: "none" };
|
|
98
|
-
}
|
|
99
|
-
return {
|
|
100
|
-
status: "failed",
|
|
101
|
-
diagnostics,
|
|
102
|
-
semantic: "warning",
|
|
103
|
-
};
|
|
104
|
-
},
|
|
105
|
-
};
|
|
106
|
-
export default spellcheckRunner;
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for spellcheck runner (typos-cli)
|
|
3
|
-
*/
|
|
4
|
-
import * as fs from "node:fs";
|
|
5
|
-
import { createRequire } from "node:module";
|
|
6
|
-
import * as path from "node:path";
|
|
7
|
-
import { describe, expect, it } from "vitest";
|
|
8
|
-
function createMockContext(filePath) {
|
|
9
|
-
return {
|
|
10
|
-
filePath,
|
|
11
|
-
cwd: process.cwd(),
|
|
12
|
-
kind: "markdown",
|
|
13
|
-
autofix: false,
|
|
14
|
-
deltaMode: false,
|
|
15
|
-
baselines: { get: () => [], add: () => { }, save: () => { } },
|
|
16
|
-
pi: {},
|
|
17
|
-
hasTool: async () => false,
|
|
18
|
-
log: () => { },
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
describe("spellcheck runner", () => {
|
|
22
|
-
const require = createRequire(import.meta.url);
|
|
23
|
-
it("should have correct runner definition", async () => {
|
|
24
|
-
const spellcheckModule = await import("./spellcheck.js");
|
|
25
|
-
const runner = spellcheckModule.default;
|
|
26
|
-
expect(runner.id).toBe("spellcheck");
|
|
27
|
-
expect(runner.appliesTo).toEqual(["markdown"]);
|
|
28
|
-
expect(runner.priority).toBe(30);
|
|
29
|
-
expect(runner.enabledByDefault).toBe(true);
|
|
30
|
-
expect(runner.skipTestFiles).toBe(false); // Check docs in test files too
|
|
31
|
-
});
|
|
32
|
-
it("should detect typos-cli availability", () => {
|
|
33
|
-
const { spawnSync } = require("node:child_process");
|
|
34
|
-
const result = spawnSync("typos", ["--version"], {
|
|
35
|
-
encoding: "utf-8",
|
|
36
|
-
timeout: 10000,
|
|
37
|
-
shell: true,
|
|
38
|
-
});
|
|
39
|
-
expect(result.error || result.status !== 0 ? "not available" : "available").toBeTruthy(); // May or may not be installed
|
|
40
|
-
});
|
|
41
|
-
it("should detect typos in markdown content", async () => {
|
|
42
|
-
const tmpFile = path.join(process.env.TEMP || "/tmp", `spellcheck_test_${Date.now()}.md`);
|
|
43
|
-
fs.writeFileSync(tmpFile, `# README
|
|
44
|
-
|
|
45
|
-
This is a documnet about recieving data.
|
|
46
|
-
The seperation of concerns is important.
|
|
47
|
-
`);
|
|
48
|
-
try {
|
|
49
|
-
const spellcheckModule = await import("./spellcheck.js");
|
|
50
|
-
const runner = spellcheckModule.default;
|
|
51
|
-
const result = await runner.run(createMockContext(tmpFile));
|
|
52
|
-
// If typos-cli is installed, should detect typos
|
|
53
|
-
// If not installed, will be skipped
|
|
54
|
-
if (result.status !== "skipped") {
|
|
55
|
-
// Should detect at least "documnet" and "recieving"
|
|
56
|
-
expect(result.diagnostics.length).toBeGreaterThanOrEqual(1);
|
|
57
|
-
expect(result.diagnostics.some((d) => d.tool === "typos" &&
|
|
58
|
-
(d.message.includes("documnet") ||
|
|
59
|
-
d.message.includes("recieving") ||
|
|
60
|
-
d.message.includes("seperation")))).toBe(true);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
finally {
|
|
64
|
-
if (fs.existsSync(tmpFile)) {
|
|
65
|
-
fs.unlinkSync(tmpFile);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
});
|
|
69
|
-
it("should suggest corrections for typos", async () => {
|
|
70
|
-
const tmpFile = path.join(process.env.TEMP || "/tmp", `spellcheck_fix_${Date.now()}.md`);
|
|
71
|
-
fs.writeFileSync(tmpFile, `# Test
|
|
72
|
-
|
|
73
|
-
This is a recieving test.
|
|
74
|
-
`);
|
|
75
|
-
try {
|
|
76
|
-
const spellcheckModule = await import("./spellcheck.js");
|
|
77
|
-
const runner = spellcheckModule.default;
|
|
78
|
-
const result = await runner.run(createMockContext(tmpFile));
|
|
79
|
-
if (result.status !== "skipped" && result.diagnostics.length > 0) {
|
|
80
|
-
// Should have fix suggestions
|
|
81
|
-
const fixableDiags = result.diagnostics.filter((d) => d.fixable);
|
|
82
|
-
expect(fixableDiags.length).toBeGreaterThanOrEqual(1);
|
|
83
|
-
expect(fixableDiags.some((d) => d.fixSuggestion?.toLowerCase().includes("receive"))).toBe(true);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
finally {
|
|
87
|
-
if (fs.existsSync(tmpFile)) {
|
|
88
|
-
fs.unlinkSync(tmpFile);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
it("should pass clean markdown files", async () => {
|
|
93
|
-
const tmpFile = path.join(process.env.TEMP || "/tmp", `spellcheck_ok_${Date.now()}.md`);
|
|
94
|
-
fs.writeFileSync(tmpFile, `# Clean README
|
|
95
|
-
|
|
96
|
-
This is a correct document about receiving data.
|
|
97
|
-
The separation of concerns is important.
|
|
98
|
-
All spelling is proper in this file.
|
|
99
|
-
`);
|
|
100
|
-
try {
|
|
101
|
-
const spellcheckModule = await import("./spellcheck.js");
|
|
102
|
-
const runner = spellcheckModule.default;
|
|
103
|
-
const result = await runner.run(createMockContext(tmpFile));
|
|
104
|
-
if (result.status !== "skipped") {
|
|
105
|
-
// Should have no typos
|
|
106
|
-
expect(result.diagnostics.length).toBe(0);
|
|
107
|
-
expect(result.status).toBe("succeeded");
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
finally {
|
|
111
|
-
if (fs.existsSync(tmpFile)) {
|
|
112
|
-
fs.unlinkSync(tmpFile);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
it("should handle JSON parse errors gracefully", async () => {
|
|
117
|
-
const tmpFile = path.join(process.env.TEMP || "/tmp", `spellcheck_json_${Date.now()}.md`);
|
|
118
|
-
fs.writeFileSync(tmpFile, `# Test\n\nSimple file.`);
|
|
119
|
-
try {
|
|
120
|
-
const spellcheckModule = await import("./spellcheck.js");
|
|
121
|
-
const runner = spellcheckModule.default;
|
|
122
|
-
const result = await runner.run(createMockContext(tmpFile));
|
|
123
|
-
// Should not crash on JSON parse issues
|
|
124
|
-
expect(["succeeded", "failed", "skipped"]).toContain(result.status);
|
|
125
|
-
}
|
|
126
|
-
finally {
|
|
127
|
-
if (fs.existsSync(tmpFile)) {
|
|
128
|
-
fs.unlinkSync(tmpFile);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
});
|
|
132
|
-
it("should skip when typos-cli is not available", async () => {
|
|
133
|
-
const tmpFile = path.join(process.env.TEMP || "/tmp", `spellcheck_skip_${Date.now()}.md`);
|
|
134
|
-
fs.writeFileSync(tmpFile, `# Test\n\nContent with typo: recieve.`);
|
|
135
|
-
try {
|
|
136
|
-
const spellcheckModule = await import("./spellcheck.js");
|
|
137
|
-
const runner = spellcheckModule.default;
|
|
138
|
-
// Check if typos is available
|
|
139
|
-
const { spawnSync } = require("node:child_process");
|
|
140
|
-
const checkResult = spawnSync("typos", ["--version"], {
|
|
141
|
-
encoding: "utf-8",
|
|
142
|
-
timeout: 5000,
|
|
143
|
-
shell: true,
|
|
144
|
-
});
|
|
145
|
-
const isAvailable = !checkResult.error && checkResult.status === 0;
|
|
146
|
-
const result = await runner.run(createMockContext(tmpFile));
|
|
147
|
-
if (!isAvailable) {
|
|
148
|
-
expect(result.status).toBe("skipped");
|
|
149
|
-
expect(result.diagnostics).toHaveLength(0);
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
finally {
|
|
153
|
-
if (fs.existsSync(tmpFile)) {
|
|
154
|
-
fs.unlinkSync(tmpFile);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
});
|
|
158
|
-
});
|
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for spellcheck runner (typos-cli)
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import * as fs from "node:fs";
|
|
6
|
-
import { createRequire } from "node:module";
|
|
7
|
-
import * as path from "node:path";
|
|
8
|
-
import { describe, expect, it } from "vitest";
|
|
9
|
-
import type { DispatchContext } from "../types.js";
|
|
10
|
-
|
|
11
|
-
function createMockContext(filePath: string): DispatchContext {
|
|
12
|
-
return {
|
|
13
|
-
filePath,
|
|
14
|
-
cwd: process.cwd(),
|
|
15
|
-
kind: "markdown" as any,
|
|
16
|
-
autofix: false,
|
|
17
|
-
deltaMode: false,
|
|
18
|
-
baselines: { get: () => [], add: () => {}, save: () => {} } as any,
|
|
19
|
-
pi: {} as any,
|
|
20
|
-
hasTool: async () => false,
|
|
21
|
-
log: () => {},
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
describe("spellcheck runner", () => {
|
|
26
|
-
const require = createRequire(import.meta.url);
|
|
27
|
-
|
|
28
|
-
it("should have correct runner definition", async () => {
|
|
29
|
-
const spellcheckModule = await import("./spellcheck.js");
|
|
30
|
-
const runner = spellcheckModule.default;
|
|
31
|
-
|
|
32
|
-
expect(runner.id).toBe("spellcheck");
|
|
33
|
-
expect(runner.appliesTo).toEqual(["markdown"]);
|
|
34
|
-
expect(runner.priority).toBe(30);
|
|
35
|
-
expect(runner.enabledByDefault).toBe(true);
|
|
36
|
-
expect(runner.skipTestFiles).toBe(false); // Check docs in test files too
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it("should detect typos-cli availability", () => {
|
|
40
|
-
const { spawnSync } =
|
|
41
|
-
require("node:child_process") as typeof import("node:child_process");
|
|
42
|
-
const result = spawnSync("typos", ["--version"], {
|
|
43
|
-
encoding: "utf-8",
|
|
44
|
-
timeout: 10000,
|
|
45
|
-
shell: true,
|
|
46
|
-
});
|
|
47
|
-
expect(
|
|
48
|
-
result.error || result.status !== 0 ? "not available" : "available",
|
|
49
|
-
).toBeTruthy(); // May or may not be installed
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it("should detect typos in markdown content", async () => {
|
|
53
|
-
const tmpFile = path.join(
|
|
54
|
-
process.env.TEMP || "/tmp",
|
|
55
|
-
`spellcheck_test_${Date.now()}.md`,
|
|
56
|
-
);
|
|
57
|
-
fs.writeFileSync(
|
|
58
|
-
tmpFile,
|
|
59
|
-
`# README
|
|
60
|
-
|
|
61
|
-
This is a documnet about recieving data.
|
|
62
|
-
The seperation of concerns is important.
|
|
63
|
-
`,
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
try {
|
|
67
|
-
const spellcheckModule = await import("./spellcheck.js");
|
|
68
|
-
const runner = spellcheckModule.default;
|
|
69
|
-
const result = await runner.run(createMockContext(tmpFile));
|
|
70
|
-
|
|
71
|
-
// If typos-cli is installed, should detect typos
|
|
72
|
-
// If not installed, will be skipped
|
|
73
|
-
if (result.status !== "skipped") {
|
|
74
|
-
// Should detect at least "documnet" and "recieving"
|
|
75
|
-
expect(result.diagnostics.length).toBeGreaterThanOrEqual(1);
|
|
76
|
-
expect(
|
|
77
|
-
result.diagnostics.some(
|
|
78
|
-
(d) =>
|
|
79
|
-
d.tool === "typos" &&
|
|
80
|
-
(d.message.includes("documnet") ||
|
|
81
|
-
d.message.includes("recieving") ||
|
|
82
|
-
d.message.includes("seperation")),
|
|
83
|
-
),
|
|
84
|
-
).toBe(true);
|
|
85
|
-
}
|
|
86
|
-
} finally {
|
|
87
|
-
if (fs.existsSync(tmpFile)) {
|
|
88
|
-
fs.unlinkSync(tmpFile);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it("should suggest corrections for typos", async () => {
|
|
94
|
-
const tmpFile = path.join(
|
|
95
|
-
process.env.TEMP || "/tmp",
|
|
96
|
-
`spellcheck_fix_${Date.now()}.md`,
|
|
97
|
-
);
|
|
98
|
-
fs.writeFileSync(
|
|
99
|
-
tmpFile,
|
|
100
|
-
`# Test
|
|
101
|
-
|
|
102
|
-
This is a recieving test.
|
|
103
|
-
`,
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
try {
|
|
107
|
-
const spellcheckModule = await import("./spellcheck.js");
|
|
108
|
-
const runner = spellcheckModule.default;
|
|
109
|
-
const result = await runner.run(createMockContext(tmpFile));
|
|
110
|
-
|
|
111
|
-
if (result.status !== "skipped" && result.diagnostics.length > 0) {
|
|
112
|
-
// Should have fix suggestions
|
|
113
|
-
const fixableDiags = result.diagnostics.filter((d) => d.fixable);
|
|
114
|
-
expect(fixableDiags.length).toBeGreaterThanOrEqual(1);
|
|
115
|
-
expect(
|
|
116
|
-
fixableDiags.some((d) =>
|
|
117
|
-
d.fixSuggestion?.toLowerCase().includes("receive"),
|
|
118
|
-
),
|
|
119
|
-
).toBe(true);
|
|
120
|
-
}
|
|
121
|
-
} finally {
|
|
122
|
-
if (fs.existsSync(tmpFile)) {
|
|
123
|
-
fs.unlinkSync(tmpFile);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
it("should pass clean markdown files", async () => {
|
|
129
|
-
const tmpFile = path.join(
|
|
130
|
-
process.env.TEMP || "/tmp",
|
|
131
|
-
`spellcheck_ok_${Date.now()}.md`,
|
|
132
|
-
);
|
|
133
|
-
fs.writeFileSync(
|
|
134
|
-
tmpFile,
|
|
135
|
-
`# Clean README
|
|
136
|
-
|
|
137
|
-
This is a correct document about receiving data.
|
|
138
|
-
The separation of concerns is important.
|
|
139
|
-
All spelling is proper in this file.
|
|
140
|
-
`,
|
|
141
|
-
);
|
|
142
|
-
|
|
143
|
-
try {
|
|
144
|
-
const spellcheckModule = await import("./spellcheck.js");
|
|
145
|
-
const runner = spellcheckModule.default;
|
|
146
|
-
const result = await runner.run(createMockContext(tmpFile));
|
|
147
|
-
|
|
148
|
-
if (result.status !== "skipped") {
|
|
149
|
-
// Should have no typos
|
|
150
|
-
expect(result.diagnostics.length).toBe(0);
|
|
151
|
-
expect(result.status).toBe("succeeded");
|
|
152
|
-
}
|
|
153
|
-
} finally {
|
|
154
|
-
if (fs.existsSync(tmpFile)) {
|
|
155
|
-
fs.unlinkSync(tmpFile);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
it("should handle JSON parse errors gracefully", async () => {
|
|
161
|
-
const tmpFile = path.join(
|
|
162
|
-
process.env.TEMP || "/tmp",
|
|
163
|
-
`spellcheck_json_${Date.now()}.md`,
|
|
164
|
-
);
|
|
165
|
-
fs.writeFileSync(tmpFile, `# Test\n\nSimple file.`);
|
|
166
|
-
|
|
167
|
-
try {
|
|
168
|
-
const spellcheckModule = await import("./spellcheck.js");
|
|
169
|
-
const runner = spellcheckModule.default;
|
|
170
|
-
const result = await runner.run(createMockContext(tmpFile));
|
|
171
|
-
|
|
172
|
-
// Should not crash on JSON parse issues
|
|
173
|
-
expect(["succeeded", "failed", "skipped"]).toContain(result.status);
|
|
174
|
-
} finally {
|
|
175
|
-
if (fs.existsSync(tmpFile)) {
|
|
176
|
-
fs.unlinkSync(tmpFile);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
it("should skip when typos-cli is not available", async () => {
|
|
182
|
-
const tmpFile = path.join(
|
|
183
|
-
process.env.TEMP || "/tmp",
|
|
184
|
-
`spellcheck_skip_${Date.now()}.md`,
|
|
185
|
-
);
|
|
186
|
-
fs.writeFileSync(tmpFile, `# Test\n\nContent with typo: recieve.`);
|
|
187
|
-
|
|
188
|
-
try {
|
|
189
|
-
const spellcheckModule = await import("./spellcheck.js");
|
|
190
|
-
const runner = spellcheckModule.default;
|
|
191
|
-
|
|
192
|
-
// Check if typos is available
|
|
193
|
-
const { spawnSync } =
|
|
194
|
-
require("node:child_process") as typeof import("node:child_process");
|
|
195
|
-
const checkResult = spawnSync("typos", ["--version"], {
|
|
196
|
-
encoding: "utf-8",
|
|
197
|
-
timeout: 5000,
|
|
198
|
-
shell: true,
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
const isAvailable = !checkResult.error && checkResult.status === 0;
|
|
202
|
-
const result = await runner.run(createMockContext(tmpFile));
|
|
203
|
-
|
|
204
|
-
if (!isAvailable) {
|
|
205
|
-
expect(result.status).toBe("skipped");
|
|
206
|
-
expect(result.diagnostics).toHaveLength(0);
|
|
207
|
-
}
|
|
208
|
-
} finally {
|
|
209
|
-
if (fs.existsSync(tmpFile)) {
|
|
210
|
-
fs.unlinkSync(tmpFile);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
});
|