testguard-cli 0.18.0 → 0.18.1
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 +21 -0
- package/README.md +4 -4
- package/package.json +1 -1
- package/src/probe/runners/discovery.mjs +10 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.18.1] - 2026-10-01
|
|
11
|
+
|
|
12
|
+
Automated weekly release — everything merged since `v0.18.0`.
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- test: consolidate native runtime acceptance checks
|
|
17
|
+
- perf: isolate native admission mutation defenders
|
|
18
|
+
- perf: size bounded report buffers to observed files
|
|
19
|
+
- chore(homebrew): sha256 for v0.18.0 (#194)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- Runner report and discovery-config reads reserve memory for the observed
|
|
25
|
+
file size instead of the maximum allowed size, retaining the hard byte
|
|
26
|
+
ceiling and checking file growth before parsing.
|
|
27
|
+
- Native-runner admission self-probes use focused defenders, preserving the
|
|
28
|
+
fault recipes and full runner acceptance coverage while avoiding unrelated
|
|
29
|
+
timeout and process-cleanup checks for each admission confirmation.
|
|
30
|
+
|
|
10
31
|
## [0.18.0] - 2026-10-01
|
|
11
32
|
|
|
12
33
|
Automated weekly release — everything merged since `v0.17.0`.
|
package/README.md
CHANGED
|
@@ -127,9 +127,9 @@ raises coverage. TestGuard admits it because it fails when the claim is false.
|
|
|
127
127
|
| npm | `npm i -D testguard-cli` then `npx testguard probe` |
|
|
128
128
|
| pip | `pip install testguard-cli` then `testguard probe` (needs Node ≥ 20) |
|
|
129
129
|
| Homebrew | `brew tap raccioly/tap && brew install testguard` |
|
|
130
|
-
| GitHub Action | `uses: raccioly/testguard@v0.18.
|
|
130
|
+
| GitHub Action | `uses: raccioly/testguard@v0.18.1` — see [`action.yml`](./action.yml) |
|
|
131
131
|
| pre-commit | `repo: https://github.com/raccioly/testguard`, hooks `testguard-claims`, `testguard-probe` |
|
|
132
|
-
| GitLab CI | `include: - remote: https://raw.githubusercontent.com/raccioly/testguard/v0.18.
|
|
132
|
+
| GitLab CI | `include: - remote: https://raw.githubusercontent.com/raccioly/testguard/v0.18.1/packaging/gitlab/testguard.gitlab-ci.yml` with `inputs:` — see [`packaging/gitlab/`](./packaging/gitlab/testguard.gitlab-ci.yml) |
|
|
133
133
|
|
|
134
134
|
Projects that set `min-release-age` in `.npmrc` cannot see a version published
|
|
135
135
|
less than that many days ago (`ENOVERSIONS`); install that one with
|
|
@@ -785,12 +785,12 @@ detected base that does not resolve is a warning for `status` and `brief`
|
|
|
785
785
|
# GitHub Actions
|
|
786
786
|
- uses: actions/checkout@v4
|
|
787
787
|
with: { fetch-depth: 0 }
|
|
788
|
-
- uses: raccioly/testguard@v0.18.
|
|
788
|
+
- uses: raccioly/testguard@v0.18.1
|
|
789
789
|
with: { command: gate }
|
|
790
790
|
|
|
791
791
|
# GitLab CI — the component-shaped template: gate + probe, brief as an artifact and, opted in, as a merge-request note
|
|
792
792
|
include:
|
|
793
|
-
- remote: 'https://raw.githubusercontent.com/raccioly/testguard/v0.18.
|
|
793
|
+
- remote: 'https://raw.githubusercontent.com/raccioly/testguard/v0.18.1/packaging/gitlab/testguard.gitlab-ci.yml'
|
|
794
794
|
inputs: { dir: backend, post_note: true } # post_note needs TESTGUARD_GITLAB_TOKEN (api scope); one note, updated in place
|
|
795
795
|
```
|
|
796
796
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "testguard-cli",
|
|
3
|
-
"version": "0.18.
|
|
3
|
+
"version": "0.18.1",
|
|
4
4
|
"description": "Breaks your code on purpose and reports every promise your tests did not notice breaking. Mutation testing bound to the claims a project makes — vitest, jest, Playwright, pytest and unittest.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -130,12 +130,21 @@ const readBoundedFile = (path, maxBytes, label, { optional = false } = {}) => {
|
|
|
130
130
|
const stat = fstatSync(descriptor);
|
|
131
131
|
if (!stat.isFile()) throw new DiscoveryError(`${label} is not a regular file`);
|
|
132
132
|
if (stat.size > maxBytes) throw new DiscoveryError(`${label} exceeded ${maxBytes} bytes`);
|
|
133
|
-
|
|
133
|
+
// Reserve the observed file size, not the allowance for the largest report.
|
|
134
|
+
// The extra byte detects growth; a full buffer grows within the same hard
|
|
135
|
+
// ceiling so a concurrently appended suffix can never be silently dropped.
|
|
136
|
+
let bytes = Buffer.alloc(stat.size + 1);
|
|
134
137
|
let length = 0;
|
|
135
138
|
while (length < bytes.length) {
|
|
136
139
|
const read = readSync(descriptor, bytes, length, bytes.length - length, null);
|
|
137
140
|
if (read === 0) break;
|
|
138
141
|
length += read;
|
|
142
|
+
if (length > maxBytes) throw new DiscoveryError(`${label} exceeded ${maxBytes} bytes`);
|
|
143
|
+
if (length === bytes.length) {
|
|
144
|
+
const grown = Buffer.alloc(Math.min(maxBytes + 1, Math.max(4096, bytes.length * 2)));
|
|
145
|
+
bytes.copy(grown, 0, 0, length);
|
|
146
|
+
bytes = grown;
|
|
147
|
+
}
|
|
139
148
|
}
|
|
140
149
|
if (length > maxBytes) throw new DiscoveryError(`${label} exceeded ${maxBytes} bytes`);
|
|
141
150
|
return bytes.subarray(0, length);
|