@paretools/test 0.2.0 → 0.5.0
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/README.md +82 -0
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/detect.d.ts +2 -2
- package/dist/lib/detect.d.ts.map +1 -1
- package/dist/lib/detect.js +11 -2
- package/dist/lib/detect.js.map +1 -1
- package/dist/lib/formatters.d.ts +2 -0
- package/dist/lib/formatters.d.ts.map +1 -1
- package/dist/lib/formatters.js +2 -0
- package/dist/lib/formatters.js.map +1 -1
- package/dist/lib/parsers/mocha.d.ts +18 -0
- package/dist/lib/parsers/mocha.d.ts.map +1 -0
- package/dist/lib/parsers/mocha.js +74 -0
- package/dist/lib/parsers/mocha.js.map +1 -0
- package/dist/schemas/index.d.ts +26 -152
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +6 -2
- package/dist/schemas/index.js.map +1 -1
- package/dist/tools/coverage.d.ts.map +1 -1
- package/dist/tools/coverage.js +8 -2
- package/dist/tools/coverage.js.map +1 -1
- package/dist/tools/run.d.ts +5 -0
- package/dist/tools/run.d.ts.map +1 -1
- package/dist/tools/run.js +66 -8
- package/dist/tools/run.js.map +1 -1
- package/package.json +30 -5
package/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# @paretools/test
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@paretools/test)
|
|
4
|
+
[](https://github.com/Dave-London/pare/blob/main/LICENSE)
|
|
5
|
+
|
|
6
|
+
**Structured, token-efficient test runner output for AI agents.** Up to 80% fewer tokens than raw test CLI output.
|
|
7
|
+
|
|
8
|
+
Part of the [Pare](https://github.com/Dave-London/pare) suite of MCP servers. Auto-detects pytest, jest, vitest, and mocha.
|
|
9
|
+
|
|
10
|
+
## Tools (2)
|
|
11
|
+
|
|
12
|
+
| Tool | Description |
|
|
13
|
+
| ---------- | ------------------------------------------------------- |
|
|
14
|
+
| `run` | Run tests, returns pass/fail counts and failure details |
|
|
15
|
+
| `coverage` | Run tests with coverage, returns per-file summary |
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx -y @paretools/test
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Add to your MCP client config:
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{
|
|
27
|
+
"mcpServers": {
|
|
28
|
+
"pare-test": {
|
|
29
|
+
"command": "npx",
|
|
30
|
+
"args": ["-y", "@paretools/test"]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Example
|
|
37
|
+
|
|
38
|
+
**`run` output:**
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"framework": "vitest",
|
|
43
|
+
"passed": 46,
|
|
44
|
+
"failed": 1,
|
|
45
|
+
"skipped": 0,
|
|
46
|
+
"total": 47,
|
|
47
|
+
"failures": [
|
|
48
|
+
{
|
|
49
|
+
"name": "parseOutput > handles empty input",
|
|
50
|
+
"file": "src/__tests__/parsers.test.ts",
|
|
51
|
+
"message": "expected true to be false"
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## All Pare Servers (62 tools)
|
|
58
|
+
|
|
59
|
+
| Package | Tools | Wraps |
|
|
60
|
+
| -------------------------------------------------------------------- | --------------------------------------------------------------------------- | ---------------------------------- |
|
|
61
|
+
| [@paretools/git](https://www.npmjs.com/package/@paretools/git) | status, log, diff, branch, show, add, commit, push, pull, checkout | git |
|
|
62
|
+
| **@paretools/test** | run, coverage | pytest, jest, vitest, mocha |
|
|
63
|
+
| [@paretools/npm](https://www.npmjs.com/package/@paretools/npm) | install, audit, outdated, list, run, test, init | npm |
|
|
64
|
+
| [@paretools/build](https://www.npmjs.com/package/@paretools/build) | tsc, build, esbuild, vite-build, webpack | tsc, esbuild, vite, webpack |
|
|
65
|
+
| [@paretools/lint](https://www.npmjs.com/package/@paretools/lint) | lint, format-check, prettier-format, biome-check, biome-format | eslint, prettier, biome |
|
|
66
|
+
| [@paretools/python](https://www.npmjs.com/package/@paretools/python) | pip-install, mypy, ruff-check, pip-audit, pytest, uv-install, uv-run, black | pip, mypy, ruff, pytest, uv, black |
|
|
67
|
+
| [@paretools/docker](https://www.npmjs.com/package/@paretools/docker) | ps, build, logs, images, run, exec, compose-up, compose-down, pull | docker, docker compose |
|
|
68
|
+
| [@paretools/cargo](https://www.npmjs.com/package/@paretools/cargo) | build, test, clippy, run, add, remove, fmt, doc, check | cargo |
|
|
69
|
+
| [@paretools/go](https://www.npmjs.com/package/@paretools/go) | build, test, vet, run, mod-tidy, fmt, generate | go, gofmt |
|
|
70
|
+
|
|
71
|
+
## Compatible Clients
|
|
72
|
+
|
|
73
|
+
Works with any MCP-compatible client: [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [Claude Desktop](https://claude.ai/download), [Cursor](https://cursor.com), [Windsurf](https://codeium.com/windsurf), [VS Code / GitHub Copilot](https://code.visualstudio.com), [Cline](https://github.com/cline/cline), [Roo Code](https://roocode.com), [Zed](https://zed.dev), [Continue.dev](https://continue.dev), [Gemini CLI](https://github.com/google-gemini/gemini-cli), [OpenAI Codex](https://openai.com/index/codex/)
|
|
74
|
+
|
|
75
|
+
## Links
|
|
76
|
+
|
|
77
|
+
- [Pare monorepo](https://github.com/Dave-London/pare)
|
|
78
|
+
- [MCP protocol](https://modelcontextprotocol.io)
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
[MIT](https://github.com/Dave-London/pare/blob/main/LICENSE)
|
package/dist/index.js
CHANGED
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
4
|
import { registerAllTools } from "./tools/index.js";
|
|
5
|
-
const server = new McpServer({
|
|
6
|
-
|
|
7
|
-
version: "0.1.0",
|
|
5
|
+
const server = new McpServer({ name: "@paretools/test", version: "0.2.0" }, {
|
|
6
|
+
instructions: "Structured test runner operations (run, coverage). Auto-detects pytest, jest, vitest, and mocha. Use instead of running test commands via bash. Returns typed JSON with structured pass/fail results and failure details.",
|
|
8
7
|
});
|
|
9
8
|
registerAllTools(server);
|
|
10
9
|
const transport = new StdioServerTransport();
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,MAAM,GAAG,IAAI,SAAS,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,OAAO,EAAE,EAC7C;IACE,YAAY,EACV,2NAA2N;CAC9N,CACF,CAAC;AAEF,gBAAgB,CAAC,MAAM,CAAC,CAAC;AAEzB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC"}
|
package/dist/lib/detect.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export type Framework = "pytest" | "jest" | "vitest";
|
|
1
|
+
export type Framework = "pytest" | "jest" | "vitest" | "mocha";
|
|
2
2
|
/**
|
|
3
3
|
* Auto-detects the test framework in use at the given directory.
|
|
4
|
-
* Priority: vitest > jest > pytest (check most specific first).
|
|
4
|
+
* Priority: vitest > jest > mocha > pytest (check most specific first).
|
|
5
5
|
*/
|
|
6
6
|
export declare function detectFramework(cwd: string): Promise<Framework>;
|
|
7
7
|
//# sourceMappingURL=detect.d.ts.map
|
package/dist/lib/detect.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/lib/detect.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/lib/detect.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AA0B/D;;;GAGG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAiDrE"}
|
package/dist/lib/detect.js
CHANGED
|
@@ -25,7 +25,7 @@ function hasDep(pkg, name) {
|
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
27
|
* Auto-detects the test framework in use at the given directory.
|
|
28
|
-
* Priority: vitest > jest > pytest (check most specific first).
|
|
28
|
+
* Priority: vitest > jest > mocha > pytest (check most specific first).
|
|
29
29
|
*/
|
|
30
30
|
export async function detectFramework(cwd) {
|
|
31
31
|
const pkg = await readPackageJson(cwd);
|
|
@@ -43,6 +43,15 @@ export async function detectFramework(cwd) {
|
|
|
43
43
|
(pkg && hasDep(pkg, "jest"))) {
|
|
44
44
|
return "jest";
|
|
45
45
|
}
|
|
46
|
+
// Mocha: config file or dependency
|
|
47
|
+
if ((await exists(join(cwd, ".mocharc.yml"))) ||
|
|
48
|
+
(await exists(join(cwd, ".mocharc.yaml"))) ||
|
|
49
|
+
(await exists(join(cwd, ".mocharc.json"))) ||
|
|
50
|
+
(await exists(join(cwd, ".mocharc.js"))) ||
|
|
51
|
+
(await exists(join(cwd, ".mocharc.cjs"))) ||
|
|
52
|
+
(pkg && hasDep(pkg, "mocha"))) {
|
|
53
|
+
return "mocha";
|
|
54
|
+
}
|
|
46
55
|
// Pytest: Python project markers
|
|
47
56
|
if ((await exists(join(cwd, "pytest.ini"))) ||
|
|
48
57
|
(await exists(join(cwd, "setup.cfg"))) ||
|
|
@@ -50,7 +59,7 @@ export async function detectFramework(cwd) {
|
|
|
50
59
|
(await exists(join(cwd, "conftest.py")))) {
|
|
51
60
|
return "pytest";
|
|
52
61
|
}
|
|
53
|
-
throw new Error("No supported test framework detected. Supported: vitest, jest, pytest. " +
|
|
62
|
+
throw new Error("No supported test framework detected. Supported: vitest, jest, mocha, pytest. " +
|
|
54
63
|
"Ensure the project has the framework installed or a config file present.");
|
|
55
64
|
}
|
|
56
65
|
//# sourceMappingURL=detect.js.map
|
package/dist/lib/detect.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/lib/detect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC,KAAK,UAAU,MAAM,CAAC,IAAY;IAChC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,GAAW;IACxC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC;QAC/D,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CAAC,GAA4B,EAAE,IAAY;IACxD,MAAM,IAAI,GAAG,GAAG,CAAC,eAAqD,CAAC;IACvE,MAAM,QAAQ,GAAG,GAAG,CAAC,YAAkD,CAAC;IACxE,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAW;IAC/C,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;IAEvC,oCAAoC;IACpC,IACE,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC,CAAC;QAC7C,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC,CAAC;QAC7C,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,mBAAmB,CAAC,CAAC,CAAC;QAC9C,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,EAC9B,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,kCAAkC;IAClC,IACE,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC,CAAC;QAC3C,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC,CAAC;QAC3C,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC,CAAC;QAC5C,CAAC,GAAG,IAAI,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,EAC5B,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,iCAAiC;IACjC,IACE,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC;QACvC,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC,CAAC;QACtC,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC,CAAC;QAC3C,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC,EACxC,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,KAAK,CACb,
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/lib/detect.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/formatters.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { TestRun, Coverage } from "../schemas/index.js";
|
|
2
|
+
/** Formats structured test run results into a human-readable summary with pass/fail counts and failure details. */
|
|
2
3
|
export declare function formatTestRun(r: TestRun): string;
|
|
4
|
+
/** Formats structured coverage data into a human-readable summary with per-file line coverage. */
|
|
3
5
|
export declare function formatCoverage(c: Coverage): string;
|
|
4
6
|
//# sourceMappingURL=formatters.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/lib/formatters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE7D,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAYhD;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM,CAWlD"}
|
|
1
|
+
{"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../src/lib/formatters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE7D,mHAAmH;AACnH,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAYhD;AAED,kGAAkG;AAClG,wBAAgB,cAAc,CAAC,CAAC,EAAE,QAAQ,GAAG,MAAM,CAWlD"}
|
package/dist/lib/formatters.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** Formats structured test run results into a human-readable summary with pass/fail counts and failure details. */
|
|
1
2
|
export function formatTestRun(r) {
|
|
2
3
|
const status = r.summary.failed > 0 ? "FAIL" : "PASS";
|
|
3
4
|
const parts = [
|
|
@@ -9,6 +10,7 @@ export function formatTestRun(r) {
|
|
|
9
10
|
}
|
|
10
11
|
return parts.join("\n");
|
|
11
12
|
}
|
|
13
|
+
/** Formats structured coverage data into a human-readable summary with per-file line coverage. */
|
|
12
14
|
export function formatCoverage(c) {
|
|
13
15
|
const parts = [`Coverage (${c.framework}): ${c.summary.lines}% lines`];
|
|
14
16
|
if (c.summary.branches !== undefined)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"formatters.js","sourceRoot":"","sources":["../../src/lib/formatters.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,aAAa,CAAC,CAAU;IACtC,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IACtD,MAAM,KAAK,GAAG;QACZ,GAAG,MAAM,KAAK,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,WAAW,CAAC,CAAC,OAAO,CAAC,MAAM,YAAY,CAAC,CAAC,OAAO,CAAC,MAAM,YAAY,CAAC,CAAC,OAAO,CAAC,OAAO,aAAa,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI;KACrK,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,CAAW;IACxC,MAAM,KAAK,GAAG,CAAC,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC;IAEvE,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS;QAAE,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,YAAY,CAAC;IACtF,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS;QAAE,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,CAAC,SAAS,aAAa,CAAC;IAEzF,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
1
|
+
{"version":3,"file":"formatters.js","sourceRoot":"","sources":["../../src/lib/formatters.ts"],"names":[],"mappings":"AAEA,mHAAmH;AACnH,MAAM,UAAU,aAAa,CAAC,CAAU;IACtC,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IACtD,MAAM,KAAK,GAAG;QACZ,GAAG,MAAM,KAAK,CAAC,CAAC,SAAS,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,WAAW,CAAC,CAAC,OAAO,CAAC,MAAM,YAAY,CAAC,CAAC,OAAO,CAAC,MAAM,YAAY,CAAC,CAAC,OAAO,CAAC,OAAO,aAAa,CAAC,CAAC,OAAO,CAAC,QAAQ,IAAI;KACrK,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAU,cAAc,CAAC,CAAW;IACxC,MAAM,KAAK,GAAG,CAAC,aAAa,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC,CAAC;IAEvE,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS;QAAE,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,CAAC,QAAQ,YAAY,CAAC;IACtF,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS;QAAE,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,CAAC,SAAS,aAAa,CAAC;IAEzF,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC;IAC/C,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { TestRun, Coverage } from "../../schemas/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Parses Mocha JSON reporter output (`mocha --reporter json`) into structured data.
|
|
4
|
+
*/
|
|
5
|
+
export declare function parseMochaJson(jsonStr: string): TestRun;
|
|
6
|
+
/**
|
|
7
|
+
* Parses nyc/Istanbul text coverage output for Mocha.
|
|
8
|
+
*
|
|
9
|
+
* Expected format (same as Jest/Vitest Istanbul output):
|
|
10
|
+
* ----------|---------|----------|---------|---------|
|
|
11
|
+
* File | % Stmts | % Branch | % Funcs | % Lines |
|
|
12
|
+
* ----------|---------|----------|---------|---------|
|
|
13
|
+
* All files | 85.71 | 66.67 | 100 | 85.71 |
|
|
14
|
+
* foo.js | 85.71 | 66.67 | 100 | 85.71 |
|
|
15
|
+
* ----------|---------|----------|---------|---------|
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseMochaCoverage(stdout: string): Coverage;
|
|
18
|
+
//# sourceMappingURL=mocha.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mocha.d.ts","sourceRoot":"","sources":["../../../src/lib/parsers/mocha.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAuChE;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAiCvD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAkC3D"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses Mocha JSON reporter output (`mocha --reporter json`) into structured data.
|
|
3
|
+
*/
|
|
4
|
+
export function parseMochaJson(jsonStr) {
|
|
5
|
+
const data = JSON.parse(jsonStr);
|
|
6
|
+
const failures = [];
|
|
7
|
+
for (const test of data.failures) {
|
|
8
|
+
const expected = test.err.expected !== undefined ? String(test.err.expected) : undefined;
|
|
9
|
+
const actual = test.err.actual !== undefined ? String(test.err.actual) : undefined;
|
|
10
|
+
failures.push({
|
|
11
|
+
name: test.fullTitle,
|
|
12
|
+
file: test.file,
|
|
13
|
+
message: test.err.message || "Test failed",
|
|
14
|
+
expected,
|
|
15
|
+
actual,
|
|
16
|
+
stack: test.err.stack,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
// Duration from mocha stats is in ms, convert to seconds
|
|
20
|
+
const durationSec = (data.stats.duration ?? 0) / 1000;
|
|
21
|
+
return {
|
|
22
|
+
framework: "mocha",
|
|
23
|
+
summary: {
|
|
24
|
+
total: data.stats.tests,
|
|
25
|
+
passed: data.stats.passes,
|
|
26
|
+
failed: data.stats.failures,
|
|
27
|
+
skipped: data.stats.pending,
|
|
28
|
+
duration: Math.round(durationSec * 100) / 100,
|
|
29
|
+
},
|
|
30
|
+
failures,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Parses nyc/Istanbul text coverage output for Mocha.
|
|
35
|
+
*
|
|
36
|
+
* Expected format (same as Jest/Vitest Istanbul output):
|
|
37
|
+
* ----------|---------|----------|---------|---------|
|
|
38
|
+
* File | % Stmts | % Branch | % Funcs | % Lines |
|
|
39
|
+
* ----------|---------|----------|---------|---------|
|
|
40
|
+
* All files | 85.71 | 66.67 | 100 | 85.71 |
|
|
41
|
+
* foo.js | 85.71 | 66.67 | 100 | 85.71 |
|
|
42
|
+
* ----------|---------|----------|---------|---------|
|
|
43
|
+
*/
|
|
44
|
+
export function parseMochaCoverage(stdout) {
|
|
45
|
+
const lines = stdout.split("\n");
|
|
46
|
+
const files = [];
|
|
47
|
+
let summary = { lines: 0, branches: 0, functions: 0 };
|
|
48
|
+
for (const line of lines) {
|
|
49
|
+
const match = line.match(/\s*(.+?)\s*\|\s*([\d.]+)\s*\|\s*([\d.]+)\s*\|\s*([\d.]+)\s*\|\s*([\d.]+)\s*\|/);
|
|
50
|
+
if (!match)
|
|
51
|
+
continue;
|
|
52
|
+
const [, name, , branch, funcs, linePct] = match;
|
|
53
|
+
const trimName = name.trim();
|
|
54
|
+
if (trimName === "File" || trimName.match(/^-+$/))
|
|
55
|
+
continue;
|
|
56
|
+
const entry = {
|
|
57
|
+
lines: parseFloat(linePct),
|
|
58
|
+
branches: parseFloat(branch),
|
|
59
|
+
functions: parseFloat(funcs),
|
|
60
|
+
};
|
|
61
|
+
if (trimName === "All files") {
|
|
62
|
+
summary = entry;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
files.push({ file: trimName, ...entry });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
framework: "mocha",
|
|
70
|
+
summary,
|
|
71
|
+
files,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=mocha.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mocha.js","sourceRoot":"","sources":["../../../src/lib/parsers/mocha.ts"],"names":[],"mappings":"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"}
|
package/dist/schemas/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
/** Zod schema for a single test failure with name, location, message, and optional expected/actual values. */
|
|
2
3
|
export declare const TestFailureSchema: z.ZodObject<{
|
|
3
4
|
name: z.ZodString;
|
|
4
5
|
file: z.ZodOptional<z.ZodString>;
|
|
@@ -7,45 +8,23 @@ export declare const TestFailureSchema: z.ZodObject<{
|
|
|
7
8
|
expected: z.ZodOptional<z.ZodString>;
|
|
8
9
|
actual: z.ZodOptional<z.ZodString>;
|
|
9
10
|
stack: z.ZodOptional<z.ZodString>;
|
|
10
|
-
},
|
|
11
|
-
name: string;
|
|
12
|
-
message: string;
|
|
13
|
-
file?: string | undefined;
|
|
14
|
-
line?: number | undefined;
|
|
15
|
-
expected?: string | undefined;
|
|
16
|
-
actual?: string | undefined;
|
|
17
|
-
stack?: string | undefined;
|
|
18
|
-
}, {
|
|
19
|
-
name: string;
|
|
20
|
-
message: string;
|
|
21
|
-
file?: string | undefined;
|
|
22
|
-
line?: number | undefined;
|
|
23
|
-
expected?: string | undefined;
|
|
24
|
-
actual?: string | undefined;
|
|
25
|
-
stack?: string | undefined;
|
|
26
|
-
}>;
|
|
11
|
+
}, z.core.$strip>;
|
|
27
12
|
export type TestFailure = z.infer<typeof TestFailureSchema>;
|
|
13
|
+
/** Zod schema for structured test run output including framework, summary counts, and failure details. */
|
|
28
14
|
export declare const TestRunSchema: z.ZodObject<{
|
|
29
|
-
framework: z.ZodEnum<
|
|
15
|
+
framework: z.ZodEnum<{
|
|
16
|
+
pytest: "pytest";
|
|
17
|
+
jest: "jest";
|
|
18
|
+
vitest: "vitest";
|
|
19
|
+
mocha: "mocha";
|
|
20
|
+
}>;
|
|
30
21
|
summary: z.ZodObject<{
|
|
31
22
|
total: z.ZodNumber;
|
|
32
23
|
passed: z.ZodNumber;
|
|
33
24
|
failed: z.ZodNumber;
|
|
34
25
|
skipped: z.ZodNumber;
|
|
35
26
|
duration: z.ZodNumber;
|
|
36
|
-
},
|
|
37
|
-
total: number;
|
|
38
|
-
passed: number;
|
|
39
|
-
failed: number;
|
|
40
|
-
skipped: number;
|
|
41
|
-
duration: number;
|
|
42
|
-
}, {
|
|
43
|
-
total: number;
|
|
44
|
-
passed: number;
|
|
45
|
-
failed: number;
|
|
46
|
-
skipped: number;
|
|
47
|
-
duration: number;
|
|
48
|
-
}>;
|
|
27
|
+
}, z.core.$strip>;
|
|
49
28
|
failures: z.ZodArray<z.ZodObject<{
|
|
50
29
|
name: z.ZodString;
|
|
51
30
|
file: z.ZodOptional<z.ZodString>;
|
|
@@ -54,142 +33,37 @@ export declare const TestRunSchema: z.ZodObject<{
|
|
|
54
33
|
expected: z.ZodOptional<z.ZodString>;
|
|
55
34
|
actual: z.ZodOptional<z.ZodString>;
|
|
56
35
|
stack: z.ZodOptional<z.ZodString>;
|
|
57
|
-
},
|
|
58
|
-
|
|
59
|
-
message: string;
|
|
60
|
-
file?: string | undefined;
|
|
61
|
-
line?: number | undefined;
|
|
62
|
-
expected?: string | undefined;
|
|
63
|
-
actual?: string | undefined;
|
|
64
|
-
stack?: string | undefined;
|
|
65
|
-
}, {
|
|
66
|
-
name: string;
|
|
67
|
-
message: string;
|
|
68
|
-
file?: string | undefined;
|
|
69
|
-
line?: number | undefined;
|
|
70
|
-
expected?: string | undefined;
|
|
71
|
-
actual?: string | undefined;
|
|
72
|
-
stack?: string | undefined;
|
|
73
|
-
}>, "many">;
|
|
74
|
-
}, "strip", z.ZodTypeAny, {
|
|
75
|
-
framework: "pytest" | "jest" | "vitest";
|
|
76
|
-
summary: {
|
|
77
|
-
total: number;
|
|
78
|
-
passed: number;
|
|
79
|
-
failed: number;
|
|
80
|
-
skipped: number;
|
|
81
|
-
duration: number;
|
|
82
|
-
};
|
|
83
|
-
failures: {
|
|
84
|
-
name: string;
|
|
85
|
-
message: string;
|
|
86
|
-
file?: string | undefined;
|
|
87
|
-
line?: number | undefined;
|
|
88
|
-
expected?: string | undefined;
|
|
89
|
-
actual?: string | undefined;
|
|
90
|
-
stack?: string | undefined;
|
|
91
|
-
}[];
|
|
92
|
-
}, {
|
|
93
|
-
framework: "pytest" | "jest" | "vitest";
|
|
94
|
-
summary: {
|
|
95
|
-
total: number;
|
|
96
|
-
passed: number;
|
|
97
|
-
failed: number;
|
|
98
|
-
skipped: number;
|
|
99
|
-
duration: number;
|
|
100
|
-
};
|
|
101
|
-
failures: {
|
|
102
|
-
name: string;
|
|
103
|
-
message: string;
|
|
104
|
-
file?: string | undefined;
|
|
105
|
-
line?: number | undefined;
|
|
106
|
-
expected?: string | undefined;
|
|
107
|
-
actual?: string | undefined;
|
|
108
|
-
stack?: string | undefined;
|
|
109
|
-
}[];
|
|
110
|
-
}>;
|
|
36
|
+
}, z.core.$strip>>;
|
|
37
|
+
}, z.core.$strip>;
|
|
111
38
|
export type TestRun = z.infer<typeof TestRunSchema>;
|
|
39
|
+
/** Zod schema for per-file coverage data including line, branch, and function coverage percentages. */
|
|
112
40
|
export declare const CoverageFileSchema: z.ZodObject<{
|
|
113
41
|
file: z.ZodString;
|
|
114
42
|
lines: z.ZodNumber;
|
|
115
43
|
branches: z.ZodOptional<z.ZodNumber>;
|
|
116
44
|
functions: z.ZodOptional<z.ZodNumber>;
|
|
117
|
-
uncoveredLines: z.ZodOptional<z.ZodArray<z.ZodNumber
|
|
118
|
-
},
|
|
119
|
-
|
|
120
|
-
lines: number;
|
|
121
|
-
branches?: number | undefined;
|
|
122
|
-
functions?: number | undefined;
|
|
123
|
-
uncoveredLines?: number[] | undefined;
|
|
124
|
-
}, {
|
|
125
|
-
file: string;
|
|
126
|
-
lines: number;
|
|
127
|
-
branches?: number | undefined;
|
|
128
|
-
functions?: number | undefined;
|
|
129
|
-
uncoveredLines?: number[] | undefined;
|
|
130
|
-
}>;
|
|
45
|
+
uncoveredLines: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
46
|
+
}, z.core.$strip>;
|
|
47
|
+
/** Zod schema for structured coverage output including framework, summary totals, and per-file details. */
|
|
131
48
|
export declare const CoverageSchema: z.ZodObject<{
|
|
132
|
-
framework: z.ZodEnum<
|
|
49
|
+
framework: z.ZodEnum<{
|
|
50
|
+
pytest: "pytest";
|
|
51
|
+
jest: "jest";
|
|
52
|
+
vitest: "vitest";
|
|
53
|
+
mocha: "mocha";
|
|
54
|
+
}>;
|
|
133
55
|
summary: z.ZodObject<{
|
|
134
56
|
lines: z.ZodNumber;
|
|
135
57
|
branches: z.ZodOptional<z.ZodNumber>;
|
|
136
58
|
functions: z.ZodOptional<z.ZodNumber>;
|
|
137
|
-
},
|
|
138
|
-
lines: number;
|
|
139
|
-
branches?: number | undefined;
|
|
140
|
-
functions?: number | undefined;
|
|
141
|
-
}, {
|
|
142
|
-
lines: number;
|
|
143
|
-
branches?: number | undefined;
|
|
144
|
-
functions?: number | undefined;
|
|
145
|
-
}>;
|
|
59
|
+
}, z.core.$strip>;
|
|
146
60
|
files: z.ZodArray<z.ZodObject<{
|
|
147
61
|
file: z.ZodString;
|
|
148
62
|
lines: z.ZodNumber;
|
|
149
63
|
branches: z.ZodOptional<z.ZodNumber>;
|
|
150
64
|
functions: z.ZodOptional<z.ZodNumber>;
|
|
151
|
-
uncoveredLines: z.ZodOptional<z.ZodArray<z.ZodNumber
|
|
152
|
-
},
|
|
153
|
-
|
|
154
|
-
lines: number;
|
|
155
|
-
branches?: number | undefined;
|
|
156
|
-
functions?: number | undefined;
|
|
157
|
-
uncoveredLines?: number[] | undefined;
|
|
158
|
-
}, {
|
|
159
|
-
file: string;
|
|
160
|
-
lines: number;
|
|
161
|
-
branches?: number | undefined;
|
|
162
|
-
functions?: number | undefined;
|
|
163
|
-
uncoveredLines?: number[] | undefined;
|
|
164
|
-
}>, "many">;
|
|
165
|
-
}, "strip", z.ZodTypeAny, {
|
|
166
|
-
framework: "pytest" | "jest" | "vitest";
|
|
167
|
-
summary: {
|
|
168
|
-
lines: number;
|
|
169
|
-
branches?: number | undefined;
|
|
170
|
-
functions?: number | undefined;
|
|
171
|
-
};
|
|
172
|
-
files: {
|
|
173
|
-
file: string;
|
|
174
|
-
lines: number;
|
|
175
|
-
branches?: number | undefined;
|
|
176
|
-
functions?: number | undefined;
|
|
177
|
-
uncoveredLines?: number[] | undefined;
|
|
178
|
-
}[];
|
|
179
|
-
}, {
|
|
180
|
-
framework: "pytest" | "jest" | "vitest";
|
|
181
|
-
summary: {
|
|
182
|
-
lines: number;
|
|
183
|
-
branches?: number | undefined;
|
|
184
|
-
functions?: number | undefined;
|
|
185
|
-
};
|
|
186
|
-
files: {
|
|
187
|
-
file: string;
|
|
188
|
-
lines: number;
|
|
189
|
-
branches?: number | undefined;
|
|
190
|
-
functions?: number | undefined;
|
|
191
|
-
uncoveredLines?: number[] | undefined;
|
|
192
|
-
}[];
|
|
193
|
-
}>;
|
|
65
|
+
uncoveredLines: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
|
|
66
|
+
}, z.core.$strip>>;
|
|
67
|
+
}, z.core.$strip>;
|
|
194
68
|
export type Coverage = z.infer<typeof CoverageSchema>;
|
|
195
69
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,iBAAiB
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,8GAA8G;AAC9G,eAAO,MAAM,iBAAiB;;;;;;;;iBAQ5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,0GAA0G;AAC1G,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;iBAUxB,CAAC;AAEH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEpD,uGAAuG;AACvG,eAAO,MAAM,kBAAkB;;;;;;iBAM7B,CAAC;AAEH,2GAA2G;AAC3G,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;iBAQzB,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC"}
|
package/dist/schemas/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
/** Zod schema for a single test failure with name, location, message, and optional expected/actual values. */
|
|
2
3
|
export const TestFailureSchema = z.object({
|
|
3
4
|
name: z.string(),
|
|
4
5
|
file: z.string().optional(),
|
|
@@ -8,8 +9,9 @@ export const TestFailureSchema = z.object({
|
|
|
8
9
|
actual: z.string().optional(),
|
|
9
10
|
stack: z.string().optional(),
|
|
10
11
|
});
|
|
12
|
+
/** Zod schema for structured test run output including framework, summary counts, and failure details. */
|
|
11
13
|
export const TestRunSchema = z.object({
|
|
12
|
-
framework: z.enum(["pytest", "jest", "vitest"]),
|
|
14
|
+
framework: z.enum(["pytest", "jest", "vitest", "mocha"]),
|
|
13
15
|
summary: z.object({
|
|
14
16
|
total: z.number(),
|
|
15
17
|
passed: z.number(),
|
|
@@ -19,6 +21,7 @@ export const TestRunSchema = z.object({
|
|
|
19
21
|
}),
|
|
20
22
|
failures: z.array(TestFailureSchema),
|
|
21
23
|
});
|
|
24
|
+
/** Zod schema for per-file coverage data including line, branch, and function coverage percentages. */
|
|
22
25
|
export const CoverageFileSchema = z.object({
|
|
23
26
|
file: z.string(),
|
|
24
27
|
lines: z.number(),
|
|
@@ -26,8 +29,9 @@ export const CoverageFileSchema = z.object({
|
|
|
26
29
|
functions: z.number().optional(),
|
|
27
30
|
uncoveredLines: z.array(z.number()).optional(),
|
|
28
31
|
});
|
|
32
|
+
/** Zod schema for structured coverage output including framework, summary totals, and per-file details. */
|
|
29
33
|
export const CoverageSchema = z.object({
|
|
30
|
-
framework: z.enum(["pytest", "jest", "vitest"]),
|
|
34
|
+
framework: z.enum(["pytest", "jest", "vitest", "mocha"]),
|
|
31
35
|
summary: z.object({
|
|
32
36
|
lines: z.number(),
|
|
33
37
|
branches: z.number().optional(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC7B,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,8GAA8G;AAC9G,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC7B,CAAC,CAAC;AAIH,0GAA0G;AAC1G,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACxD,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC;QAChB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;QACjB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;QAClB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;QAClB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;QACnB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;KACrB,CAAC;IACF,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC;CACrC,CAAC,CAAC;AAIH,uGAAuG;AACvG,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;IACjB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC/C,CAAC,CAAC;AAEH,2GAA2G;AAC3G,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IACxD,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC;QAChB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;QACjB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QAC/B,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KACjC,CAAC;IACF,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC;CACnC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../../src/tools/coverage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"coverage.d.ts","sourceRoot":"","sources":["../../src/tools/coverage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA0BzE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,QA2CrD"}
|
package/dist/tools/coverage.js
CHANGED
|
@@ -4,6 +4,7 @@ import { detectFramework } from "../lib/detect.js";
|
|
|
4
4
|
import { parsePytestCoverage } from "../lib/parsers/pytest.js";
|
|
5
5
|
import { parseJestCoverage } from "../lib/parsers/jest.js";
|
|
6
6
|
import { parseVitestCoverage } from "../lib/parsers/vitest.js";
|
|
7
|
+
import { parseMochaCoverage } from "../lib/parsers/mocha.js";
|
|
7
8
|
import { formatCoverage } from "../lib/formatters.js";
|
|
8
9
|
import { CoverageSchema } from "../schemas/index.js";
|
|
9
10
|
function getCoverageCommand(framework) {
|
|
@@ -17,16 +18,18 @@ function getCoverageCommand(framework) {
|
|
|
17
18
|
return { cmd: "npx", cmdArgs: ["jest", "--coverage", "--coverageReporters=text"] };
|
|
18
19
|
case "vitest":
|
|
19
20
|
return { cmd: "npx", cmdArgs: ["vitest", "run", "--coverage", "--reporter=default"] };
|
|
21
|
+
case "mocha":
|
|
22
|
+
return { cmd: "npx", cmdArgs: ["nyc", "--reporter=text", "mocha"] };
|
|
20
23
|
}
|
|
21
24
|
}
|
|
22
25
|
export function registerCoverageTool(server) {
|
|
23
26
|
server.registerTool("coverage", {
|
|
24
27
|
title: "Test Coverage",
|
|
25
|
-
description: "Runs tests with coverage and returns structured coverage summary per file",
|
|
28
|
+
description: "Runs tests with coverage and returns structured coverage summary per file. Use instead of running test coverage commands in the terminal.",
|
|
26
29
|
inputSchema: {
|
|
27
30
|
path: z.string().optional().describe("Project root path (default: cwd)"),
|
|
28
31
|
framework: z
|
|
29
|
-
.enum(["pytest", "jest", "vitest"])
|
|
32
|
+
.enum(["pytest", "jest", "vitest", "mocha"])
|
|
30
33
|
.optional()
|
|
31
34
|
.describe("Force a specific framework instead of auto-detecting"),
|
|
32
35
|
},
|
|
@@ -48,6 +51,9 @@ export function registerCoverageTool(server) {
|
|
|
48
51
|
case "vitest":
|
|
49
52
|
coverage = parseVitestCoverage(output);
|
|
50
53
|
break;
|
|
54
|
+
case "mocha":
|
|
55
|
+
coverage = parseMochaCoverage(output);
|
|
56
|
+
break;
|
|
51
57
|
}
|
|
52
58
|
return dualOutput(coverage, formatCoverage);
|
|
53
59
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coverage.js","sourceRoot":"","sources":["../../src/tools/coverage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAkB,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,SAAS,kBAAkB,CAAC,SAAoB;IAC9C,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,QAAQ;YACX,OAAO;gBACL,GAAG,EAAE,QAAQ;gBACb,OAAO,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,2BAA2B,EAAE,IAAI,CAAC;aACtE,CAAC;QACJ,KAAK,MAAM;YACT,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,0BAA0B,CAAC,EAAE,CAAC;QACrF,KAAK,QAAQ;YACX,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,oBAAoB,CAAC,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"coverage.js","sourceRoot":"","sources":["../../src/tools/coverage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAkB,MAAM,kBAAkB,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,SAAS,kBAAkB,CAAC,SAAoB;IAC9C,QAAQ,SAAS,EAAE,CAAC;QAClB,KAAK,QAAQ;YACX,OAAO;gBACL,GAAG,EAAE,QAAQ;gBACb,OAAO,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,2BAA2B,EAAE,IAAI,CAAC;aACtE,CAAC;QACJ,KAAK,MAAM;YACT,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,0BAA0B,CAAC,EAAE,CAAC;QACrF,KAAK,QAAQ;YACX,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,oBAAoB,CAAC,EAAE,CAAC;QACxF,KAAK,OAAO;YACV,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,OAAO,CAAC,EAAE,CAAC;IACxE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAiB;IACpD,MAAM,CAAC,YAAY,CACjB,UAAU,EACV;QACE,KAAK,EAAE,eAAe;QACtB,WAAW,EACT,2IAA2I;QAC7I,WAAW,EAAE;YACX,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kCAAkC,CAAC;YACxE,SAAS,EAAE,CAAC;iBACT,IAAI,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;iBAC3C,QAAQ,EAAE;iBACV,QAAQ,CAAC,sDAAsD,CAAC;SACpE;QACD,YAAY,EAAE,cAAc;KAC7B,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE;QAC5B,MAAM,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,SAAS,IAAI,CAAC,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3D,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAElE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC;QAEpD,IAAI,QAAQ,CAAC;QACb,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,QAAQ;gBACX,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;gBACvC,MAAM;YACR,KAAK,MAAM;gBACT,QAAQ,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;gBACrC,MAAM;YACR,KAAK,QAAQ;gBACX,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;gBACvC,MAAM;YACR,KAAK,OAAO;gBACV,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;gBACtC,MAAM;QACV,CAAC;QAED,OAAO,UAAU,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IAC9C,CAAC,CACF,CAAC;AACJ,CAAC"}
|
package/dist/tools/run.d.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
export declare function registerRunTool(server: McpServer): void;
|
|
3
|
+
/**
|
|
4
|
+
* Extracts the JSON object from mixed output that may include non-JSON text
|
|
5
|
+
* before or after the actual JSON data.
|
|
6
|
+
*/
|
|
7
|
+
export declare function extractJson(output: string): string;
|
|
3
8
|
//# sourceMappingURL=run.d.ts.map
|
package/dist/tools/run.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/tools/run.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/tools/run.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAuBzE,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,QAoGhD;AAqBD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAUlD"}
|
package/dist/tools/run.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { readFile, unlink } from "node:fs/promises";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { randomUUID } from "node:crypto";
|
|
2
6
|
import { dualOutput, run } from "@paretools/shared";
|
|
3
7
|
import { detectFramework } from "../lib/detect.js";
|
|
4
8
|
import { parsePytestOutput } from "../lib/parsers/pytest.js";
|
|
5
9
|
import { parseJestJson } from "../lib/parsers/jest.js";
|
|
6
10
|
import { parseVitestJson } from "../lib/parsers/vitest.js";
|
|
11
|
+
import { parseMochaJson } from "../lib/parsers/mocha.js";
|
|
7
12
|
import { formatTestRun } from "../lib/formatters.js";
|
|
8
13
|
import { TestRunSchema } from "../schemas/index.js";
|
|
9
14
|
function getRunCommand(framework, args) {
|
|
@@ -14,22 +19,29 @@ function getRunCommand(framework, args) {
|
|
|
14
19
|
return { cmd: "npx", cmdArgs: ["jest", "--json", ...args] };
|
|
15
20
|
case "vitest":
|
|
16
21
|
return { cmd: "npx", cmdArgs: ["vitest", "run", "--reporter=json", ...args] };
|
|
22
|
+
case "mocha":
|
|
23
|
+
return { cmd: "npx", cmdArgs: ["mocha", "--reporter", "json", ...args] };
|
|
17
24
|
}
|
|
18
25
|
}
|
|
19
26
|
export function registerRunTool(server) {
|
|
20
27
|
server.registerTool("run", {
|
|
21
28
|
title: "Run Tests",
|
|
22
|
-
description: "Auto-detects test framework (pytest/jest/vitest), runs tests, returns structured results with failures",
|
|
29
|
+
description: "Auto-detects test framework (pytest/jest/vitest/mocha), runs tests, returns structured results with failures. Use instead of running pytest/jest/vitest/mocha in the terminal.",
|
|
23
30
|
inputSchema: {
|
|
24
31
|
path: z.string().optional().describe("Project root path (default: cwd)"),
|
|
25
32
|
framework: z
|
|
26
|
-
.enum(["pytest", "jest", "vitest"])
|
|
33
|
+
.enum(["pytest", "jest", "vitest", "mocha"])
|
|
27
34
|
.optional()
|
|
28
35
|
.describe("Force a specific framework instead of auto-detecting"),
|
|
29
36
|
filter: z
|
|
30
37
|
.string()
|
|
31
38
|
.optional()
|
|
32
39
|
.describe("Test filter pattern (file path or test name pattern)"),
|
|
40
|
+
updateSnapshots: z
|
|
41
|
+
.boolean()
|
|
42
|
+
.optional()
|
|
43
|
+
.default(false)
|
|
44
|
+
.describe("Update snapshots (vitest/jest only, adds -u flag)"),
|
|
33
45
|
args: z
|
|
34
46
|
.array(z.string())
|
|
35
47
|
.optional()
|
|
@@ -37,7 +49,7 @@ export function registerRunTool(server) {
|
|
|
37
49
|
.describe("Additional arguments to pass to the test runner"),
|
|
38
50
|
},
|
|
39
51
|
outputSchema: TestRunSchema,
|
|
40
|
-
}, async ({ path, framework, filter, args }) => {
|
|
52
|
+
}, async ({ path, framework, filter, updateSnapshots, args }) => {
|
|
41
53
|
const cwd = path || process.cwd();
|
|
42
54
|
const detected = framework || (await detectFramework(cwd));
|
|
43
55
|
const extraArgs = [...(args || [])];
|
|
@@ -52,9 +64,25 @@ export function registerRunTool(server) {
|
|
|
52
64
|
case "vitest":
|
|
53
65
|
extraArgs.push(filter);
|
|
54
66
|
break;
|
|
67
|
+
case "mocha":
|
|
68
|
+
extraArgs.push("--grep", filter);
|
|
69
|
+
break;
|
|
55
70
|
}
|
|
56
71
|
}
|
|
72
|
+
// Snapshot update support (vitest/jest only)
|
|
73
|
+
if (updateSnapshots && (detected === "vitest" || detected === "jest")) {
|
|
74
|
+
extraArgs.push("-u");
|
|
75
|
+
}
|
|
76
|
+
// For vitest/jest, write JSON to a temp file instead of relying on
|
|
77
|
+
// stdout capture. On Windows, npx.cmd can swallow or mangle stdout,
|
|
78
|
+
// causing "No JSON output found" errors.
|
|
79
|
+
// Mocha outputs JSON to stdout, so we don't use --outputFile for it.
|
|
80
|
+
const useOutputFile = detected === "jest" || detected === "vitest";
|
|
81
|
+
const tempPath = useOutputFile ? join(tmpdir(), `pare-test-${randomUUID()}.json`) : "";
|
|
57
82
|
const { cmd, cmdArgs } = getRunCommand(detected, extraArgs);
|
|
83
|
+
if (useOutputFile) {
|
|
84
|
+
cmdArgs.push(`--outputFile=${tempPath}`);
|
|
85
|
+
}
|
|
58
86
|
const result = await run(cmd, cmdArgs, { cwd, timeout: 120_000 });
|
|
59
87
|
// Combine stdout and stderr for parsing (some frameworks write to stderr)
|
|
60
88
|
const output = result.stdout + "\n" + result.stderr;
|
|
@@ -63,21 +91,51 @@ export function registerRunTool(server) {
|
|
|
63
91
|
case "pytest":
|
|
64
92
|
testRun = parsePytestOutput(output);
|
|
65
93
|
break;
|
|
66
|
-
case "jest":
|
|
67
|
-
|
|
94
|
+
case "jest": {
|
|
95
|
+
const jsonStr = await readJsonOutput(tempPath, output);
|
|
96
|
+
testRun = parseJestJson(jsonStr);
|
|
68
97
|
break;
|
|
69
|
-
|
|
70
|
-
|
|
98
|
+
}
|
|
99
|
+
case "vitest": {
|
|
100
|
+
const jsonStr = await readJsonOutput(tempPath, output);
|
|
101
|
+
testRun = parseVitestJson(jsonStr);
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
case "mocha": {
|
|
105
|
+
const jsonStr = extractJson(output);
|
|
106
|
+
testRun = parseMochaJson(jsonStr);
|
|
71
107
|
break;
|
|
108
|
+
}
|
|
72
109
|
}
|
|
73
110
|
return dualOutput(testRun, formatTestRun);
|
|
74
111
|
});
|
|
75
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Reads JSON output from a temp file, falling back to extracting it from
|
|
115
|
+
* stdout if the file was not created. Always cleans up the temp file.
|
|
116
|
+
*/
|
|
117
|
+
async function readJsonOutput(tempPath, output) {
|
|
118
|
+
try {
|
|
119
|
+
return await readFile(tempPath, "utf-8");
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// Temp file wasn't created — fall back to stdout extraction
|
|
123
|
+
return extractJson(output);
|
|
124
|
+
}
|
|
125
|
+
finally {
|
|
126
|
+
try {
|
|
127
|
+
await unlink(tempPath);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
/* ignore cleanup errors */
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
76
134
|
/**
|
|
77
135
|
* Extracts the JSON object from mixed output that may include non-JSON text
|
|
78
136
|
* before or after the actual JSON data.
|
|
79
137
|
*/
|
|
80
|
-
function extractJson(output) {
|
|
138
|
+
export function extractJson(output) {
|
|
81
139
|
// Try to find JSON object boundaries
|
|
82
140
|
const start = output.indexOf("{");
|
|
83
141
|
const end = output.lastIndexOf("}");
|
package/dist/tools/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/tools/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/tools/run.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,33 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paretools/test",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"mcpName": "io.github.Dave-London/test",
|
|
4
5
|
"description": "MCP server for test runners with structured, token-efficient output",
|
|
5
6
|
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"mcp",
|
|
9
|
+
"mcp-server",
|
|
10
|
+
"model-context-protocol",
|
|
11
|
+
"structured-output",
|
|
12
|
+
"ai",
|
|
13
|
+
"ai-agent",
|
|
14
|
+
"claude",
|
|
15
|
+
"cursor",
|
|
16
|
+
"copilot",
|
|
17
|
+
"token-efficient",
|
|
18
|
+
"devtools",
|
|
19
|
+
"cli",
|
|
20
|
+
"testing",
|
|
21
|
+
"pytest",
|
|
22
|
+
"jest",
|
|
23
|
+
"vitest",
|
|
24
|
+
"mocha",
|
|
25
|
+
"test-runner"
|
|
26
|
+
],
|
|
27
|
+
"homepage": "https://github.com/Dave-London/pare/tree/main/packages/server-test",
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=20"
|
|
30
|
+
},
|
|
6
31
|
"type": "module",
|
|
7
32
|
"bin": {
|
|
8
33
|
"pare-test": "./dist/index.js"
|
|
@@ -26,13 +51,13 @@
|
|
|
26
51
|
],
|
|
27
52
|
"dependencies": {
|
|
28
53
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
29
|
-
"zod": "^3.
|
|
30
|
-
"@paretools/shared": "0.
|
|
54
|
+
"zod": "^4.3.6",
|
|
55
|
+
"@paretools/shared": "0.5.0"
|
|
31
56
|
},
|
|
32
57
|
"devDependencies": {
|
|
33
|
-
"@types/node": "^
|
|
58
|
+
"@types/node": "^25.2.3",
|
|
34
59
|
"typescript": "^5.7.0",
|
|
35
|
-
"vitest": "^
|
|
60
|
+
"vitest": "^4.0.18",
|
|
36
61
|
"@paretools/tsconfig": "0.0.0"
|
|
37
62
|
},
|
|
38
63
|
"scripts": {
|