feat(cspell-junit-reporter): add JUnit XML reporter package - #8945
Conversation
Adds @cspell/cspell-junit-reporter, modeled on cspell-json-reporter, which emits a JUnit-compatible XML report of a cspell run for CI systems that consume the JUnit test result format. Mapping: one <testsuites> root for the run, one <testsuite> per file checked, one <testcase> per spelling issue (with a nested <failure>), a single passing <testcase> for clean files, and a dedicated cspell-errors testsuite using <error> for processing errors not tied to a specific issue. All file paths, words, and messages are XML escaped. Closes streetsidesoftware#4570. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ing, use IssueType enum Pre-submission review of streetsidesoftware#4570 found two issues: - package.json shipped at 0.1.0 while every other publishable package in the monorepo (lerna fixed/locked versioning, per lerna.json) is pinned at 10.0.1. Align it so lerna publish doesn't choke on a mismatched starting version. - buildJUnitXml.ts compared issue.issueType against the magic number 1 instead of the IssueType.directive enum already exported by @cspell/cspell-types. Re-ran build, vitest (32/32), eslint, and prettier for the package after both fixes; all clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces a new workspace package, @cspell/cspell-junit-reporter, which implements a CSpell reporter that emits JUnit-compatible XML for CI consumption. It follows the existing cspell-json-reporter package structure while adding in-repo XML escaping and XML string building utilities.
Changes:
- Added a new reporter package (
packages/cspell-junit-reporter) with JUnit XML output generation and settings validation. - Implemented XML escaping and JUnit XML document construction, plus unit tests and snapshots.
- Wired the new workspace package into the monorepo via
pnpm-lock.yaml.
Reviewed changes
Copilot reviewed 16 out of 17 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Adds the new workspace importer entry for packages/cspell-junit-reporter. |
| packages/cspell-junit-reporter/package.json | Defines the new package metadata, build/test scripts, and dependency on @cspell/cspell-types. |
| packages/cspell-junit-reporter/tsconfig.json | Adds TS project references for the new package. |
| packages/cspell-junit-reporter/tsconfig.esm.json | Configures ESM build output for the new reporter package. |
| packages/cspell-junit-reporter/README.md | Documents installation, usage, settings, and JUnit XML mapping. |
| packages/cspell-junit-reporter/cSpell.example.mjs | Provides a runnable example config for the package’s test:run smoke test. |
| packages/cspell-junit-reporter/src/index.ts | Implements the reporter entry point: collects issues/progress/errors and writes XML to stdout/stderr/file. |
| packages/cspell-junit-reporter/src/index.test.ts | Tests reporter output routing and basic grouping behavior (snapshotted). |
| packages/cspell-junit-reporter/src/snapshots/index.test.ts.snap | Stores snapshots for reporter output in tests. |
| packages/cspell-junit-reporter/src/CSpellJUnitReporterSettings.ts | Defines and documents the reporter’s settings shape. |
| packages/cspell-junit-reporter/src/utils/validateSettings.ts | Validates settings at runtime and throws typed assertion errors. |
| packages/cspell-junit-reporter/src/utils/validateSettings.test.ts | Unit tests for settings validation behavior. |
| packages/cspell-junit-reporter/src/utils/snapshots/validateSettings.test.ts.snap | Snapshots for settings validation error cases. |
| packages/cspell-junit-reporter/src/utils/escapeXml.ts | Adds XML escaping utilities for text and attribute contexts. |
| packages/cspell-junit-reporter/src/utils/escapeXml.test.ts | Unit tests covering escaping behavior and invalid character stripping. |
| packages/cspell-junit-reporter/src/utils/buildJUnitXml.ts | Builds the JUnit XML document and per-file/per-error testsuite elements. |
| packages/cspell-junit-reporter/src/utils/buildJUnitXml.test.ts | Unit tests covering empty output, clean files, issues, escaping, skipped files, and processing errors. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Addressed both review comments in 8c78d3d: expanded control-character filtering and unified skipped-file JUnit counts, with regression coverage. All 33 reporter tests pass, along with formatting and the TypeScript build. |
|
Thank you. |
Signed-off-by: Jason Dent <Jason3S@users.noreply.github.com>
Signed-off-by: Jason Dent <Jason3S@users.noreply.github.com>
Co-authored-by: Jason Dent <Jason3S@users.noreply.github.com> Signed-off-by: Jason Dent <Jason3S@users.noreply.github.com>
Performance ReportDaily Performancexychart-beta
title Files Per Second by Day
y-axis Files per Second
x-axis Date [Aug-9, Aug-10, Aug-19, Aug-20]
bar [191.27, 191.48, 199.45, 197.51]
line [19.76, 19.87, 23.15, 18.70]
line [94.45, 88.13, 97.66, 90.46]
line [106.66, 99.38, 103.80, 122.25]
line [80.61, 83.15, 92.81, 81.84]
line [239.79, 231.09, 223.10, 259.35]
line [269.81, 270.47, 289.77, 294.17]
line [39.52, 37.52, 44.46, 39.02]
line [268.54, 243.09, 257.77, 247.35]
line [6.78, 6.60, 7.51, 6.44]
line [240.17, 211.99, 227.00, 213.12]
line [125.68, 158.27, 127.25, 139.81]
line [225.24, 214.74, 210.02, 227.16]
line [225.91, 222.58, 246.74, 256.30]
line [145.75, 128.32, 148.05, 133.92]
line [24.65, 23.72, 23.68, 24.34]
line [139.45, 161.93, 128.87, 138.24]
line [25.95, 22.03, 24.86, 29.03]
line [154.75, 150.93, 149.02, 166.83]
line [15.80, 15.53, 17.25, 15.30]
line [196.97, 211.99, 246.59, 224.98]
line [180.75, 223.35, 172.94, 179.93]
line [96.93, 84.41, 106.12, 85.35]
line [77.16, 76.75, 77.91, 84.48]
line [400.74, 385.62, 371.65, 417.68]
line [145.79, 145.58, 147.10, 146.08]
line [249.96, 202.34, 263.67, 241.91]
line [186.27, 165.43, 184.07, 214.92]
line [224.37, 213.27, 217.89, 239.33]
line [47.00, 61.84, 45.89, 52.68]
line [127.47, 149.55, 129.16, 128.16]
line [181.18, 166.12, 186.93, 186.21]
line [57.90, 56.15, 56.35, 54.76]
line [101.07, 123.80, 99.87, 106.26]
line [98.84, 91.76, 103.43, 112.64]
line [162.48, 155.40, 204.32, 161.66]
line [360.76, 347.31, 389.41, 380.85]
line [198.91, 184.05, 187.41, 188.61]
line [242.10, 232.62, 273.32, 263.78]
line [73.60, 96.61, 68.89, 69.67]
line [415.14, 451.69, 458.22, 416.58]
line [283.77, 252.09, 262.36, 263.98]
line [22.84, 20.59, 20.47, 21.10]
line [205.56, 193.98, 216.67, 204.80]
line [126.64, 126.17, 128.45, 125.63]
line [105.46, 100.11, 102.43, 103.31]
line [47.26, 48.66, 46.00, 51.23]
line [268.09, 268.70, 290.78, 264.38]
line [234.76, 198.61, 243.75, 203.70]
line [39.98, 38.63, 38.64, 38.08]
line [192.03, 195.48, 194.87, 188.41]
Time to Process Files
Note:
Files per Second over Time
Data Throughput
|
Closes #4570.
Adds
@cspell/cspell-junit-reporter, a new workspace package modeled onpackages/cspell-json-reporter, that emits a JUnit-compatible XML report of a cspell run.The issue asked for a minimal mapping along the lines of:
This PR follows that shape but wraps it in a
<testsuites>root and groups by file (one<testsuite>per file, suite name = file path), since that is the convention used by other widely-consumed JUnit reporters (for example ESLint's JUnit formatter) and is what most CI JUnit parsers expect. The package README documents the full mapping.package.json,tsconfig.json, test framework, andfiles/exports/publishConfigshape are copied fromcspell-json-reporter. Version pinned to 10.0.1 to match the monorepo's locked versioning.src/utils/escapeXml.ts) and a pure XML-string builder (src/utils/buildJUnitXml.ts) were written in-repo, consistent with the monorepo's small-utility-file convention.erroremitter routed to a dedicatedcspell-errorstestsuite using<error>).Assumptions the issue thread left ambiguous, called out for review:
<testsuite>per file rather than one flat suite for the whole run. Matches common JUnit reporter convention and keeps per-file counts meaningful in CI UIs.<testcase name="no issues found">so a suite is never reported withtests="0", which some JUnit consumers treat as suspicious.cspell-json-reporter's (outFile,suiteNameonly). JUnit XML has no natural place for arbitrary debug/progress log dumps.<error>elements, distinct from spelling<failure>elements, per the JUnit failure-vs-error distinction.Verified locally:
tsc -bclean, vitest 32/32, eslint and prettier clean, and the full monorepobuild:prodsucceeds with the package in the workspace. One environment note: the package's CLI smoke-test script wasn't runnable locally (repo requires Node >=22.18.0, local was 22.17.0 — the sibling json-reporter fails identically there), so CI is the first place it will run.