@am_shork/attest 0.1.6 → 0.2.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/CHANGELOG.md +293 -83
- package/README.md +73 -5
- package/dist/cli/index.js +38 -13
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/json.d.ts +4 -2
- package/dist/cli/json.d.ts.map +1 -1
- package/dist/cli/json.js +2 -2
- package/dist/cli/json.js.map +1 -1
- package/dist/cli/report.d.ts +10 -2
- package/dist/cli/report.d.ts.map +1 -1
- package/dist/cli/report.js +18 -2
- package/dist/cli/report.js.map +1 -1
- package/dist/core/apply.d.ts.map +1 -1
- package/dist/core/apply.js +7 -1
- package/dist/core/apply.js.map +1 -1
- package/dist/core/gate.d.ts +9 -0
- package/dist/core/gate.d.ts.map +1 -1
- package/dist/core/gate.js +25 -12
- package/dist/core/gate.js.map +1 -1
- package/dist/core/loader.d.ts.map +1 -1
- package/dist/core/loader.js +16 -1
- package/dist/core/loader.js.map +1 -1
- package/dist/core/locate.d.ts +61 -5
- package/dist/core/locate.d.ts.map +1 -1
- package/dist/core/locate.js +130 -48
- package/dist/core/locate.js.map +1 -1
- package/dist/core/order.d.ts +3 -0
- package/dist/core/order.d.ts.map +1 -0
- package/dist/core/order.js +13 -0
- package/dist/core/order.js.map +1 -0
- package/dist/core/pipeline.d.ts +38 -6
- package/dist/core/pipeline.d.ts.map +1 -1
- package/dist/core/pipeline.js +156 -69
- package/dist/core/pipeline.js.map +1 -1
- package/dist/core/render.d.ts.map +1 -1
- package/dist/core/render.js +8 -4
- package/dist/core/render.js.map +1 -1
- package/dist/core/runner.d.ts.map +1 -1
- package/dist/core/runner.js +6 -0
- package/dist/core/runner.js.map +1 -1
- package/dist/core/static-registry.d.ts +14 -0
- package/dist/core/static-registry.d.ts.map +1 -0
- package/dist/core/static-registry.js +255 -0
- package/dist/core/static-registry.js.map +1 -0
- package/dist/core/validator.d.ts.map +1 -1
- package/dist/core/validator.js +16 -4
- package/dist/core/validator.js.map +1 -1
- package/package.json +1 -1
package/dist/core/pipeline.js
CHANGED
|
@@ -1,88 +1,128 @@
|
|
|
1
1
|
// High-level operations composing the core layers (design §9). These are
|
|
2
2
|
// tool-agnostic; the CLI is a thin shell that calls them and renders the result.
|
|
3
3
|
import { createLoader } from './loader.js';
|
|
4
|
-
import { loadRegistry,
|
|
4
|
+
import { evalReader, loadRegistry, parseSpecs, parseChangeSpecs, listChangeNames, scanProject, staticReader, } from './locate.js';
|
|
5
5
|
import { validateStructure, detectPotentialDrift } from './validator.js';
|
|
6
|
+
import { byCodeUnit } from './order.js';
|
|
6
7
|
import { runAndCollect } from './runner.js';
|
|
7
8
|
import { applyDelta } from './apply.js';
|
|
8
|
-
import { evaluateGate } from './gate.js';
|
|
9
|
+
import { evaluateGate, declaredNotRunIssues } from './gate.js';
|
|
9
10
|
import { renderMarkdown, staleIssue } from './render.js';
|
|
10
11
|
import { readFile } from 'node:fs/promises';
|
|
11
12
|
import { join, relative } from 'node:path';
|
|
12
13
|
import { configDefaults } from 'vitest/config';
|
|
13
14
|
import { hasError } from './types.js';
|
|
14
|
-
/**
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Read every registry under root with the reader `options` asks for, and close
|
|
17
|
+
* whatever that reader needed. Static reading starts no Vite server at all.
|
|
18
|
+
*/
|
|
19
|
+
async function readRegistry(root, options, files) {
|
|
20
|
+
if (!options.evaluate)
|
|
21
|
+
return loadRegistry(root, staticReader(), files);
|
|
16
22
|
const loader = await createLoader();
|
|
17
23
|
try {
|
|
18
|
-
|
|
19
|
-
const plan = await parseAllSpecFiles(root);
|
|
20
|
-
return [
|
|
21
|
-
...issues,
|
|
22
|
-
...validateStructure(registry, plan),
|
|
23
|
-
...detectPotentialDrift(registry, plan, plan.paramRefs),
|
|
24
|
-
];
|
|
24
|
+
return await loadRegistry(root, evalReader(loader), files);
|
|
25
25
|
}
|
|
26
26
|
finally {
|
|
27
27
|
await loader.close();
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
+
/** Static structural check (design §9: `attest check`). */
|
|
31
|
+
export async function runCheck(root, options = {}) {
|
|
32
|
+
const scan = await scanProject(root);
|
|
33
|
+
const { registry, issues } = await readRegistry(root, options, scan.reqsFiles);
|
|
34
|
+
const plan = await parseSpecs(scan.specFiles, root);
|
|
35
|
+
return [
|
|
36
|
+
...issues,
|
|
37
|
+
...validateStructure(registry, plan),
|
|
38
|
+
...detectPotentialDrift(registry, plan, plan.paramRefs),
|
|
39
|
+
];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The spec files a run should execute: the ones that declare a `requirement()`.
|
|
43
|
+
*
|
|
44
|
+
* Sweeping every `*.spec.ts` under the root meant `verify` in a repo that
|
|
45
|
+
* already had a suite pulled that suite into a run with no aliases and no DOM —
|
|
46
|
+
* a guaranteed red about code Attest was never asked to attest, and the first
|
|
47
|
+
* thing a brownfield adopter saw. The plan already knows which files declare
|
|
48
|
+
* intent, so the run scope is derived from it rather than from a glob.
|
|
49
|
+
*/
|
|
50
|
+
function attestingFiles(plan) {
|
|
51
|
+
return [...new Set(plan.scenarios.map((s) => s.file))].sort(byCodeUnit);
|
|
52
|
+
}
|
|
30
53
|
/** Executable verification (design §9: `attest verify`). */
|
|
31
54
|
export async function runVerify(root, options = {}) {
|
|
55
|
+
const scan = await scanProject(root);
|
|
32
56
|
const loader = await createLoader();
|
|
33
57
|
let registry;
|
|
34
58
|
let plan;
|
|
35
59
|
const issues = [];
|
|
36
60
|
try {
|
|
37
|
-
const loaded = await loadRegistry(root, loader);
|
|
61
|
+
const loaded = await loadRegistry(root, evalReader(loader), scan.reqsFiles);
|
|
38
62
|
registry = loaded.registry;
|
|
39
63
|
issues.push(...loaded.issues);
|
|
40
|
-
plan = await
|
|
64
|
+
plan = await parseSpecs(scan.specFiles, root);
|
|
41
65
|
}
|
|
42
66
|
finally {
|
|
43
67
|
await loader.close();
|
|
44
68
|
}
|
|
45
69
|
issues.push(...validateStructure(registry, plan));
|
|
46
70
|
issues.push(...detectPotentialDrift(registry, plan, plan.paramRefs));
|
|
47
|
-
const
|
|
71
|
+
const attesting = attestingFiles(plan);
|
|
72
|
+
const counts = {
|
|
73
|
+
requirements: Object.keys(registry).length,
|
|
74
|
+
scenarios: plan.scenarios.length,
|
|
75
|
+
specFiles: scan.specFiles.length,
|
|
76
|
+
attesting: attesting.length,
|
|
77
|
+
};
|
|
78
|
+
// A run with nothing to attest used to print "✓ No issues." and exit 0,
|
|
79
|
+
// because "no failing tests" was read as passed. An empty registry is the
|
|
80
|
+
// only shape of that which no other check already catches: with at least one
|
|
81
|
+
// requirement, an absent scenario is `uncovered-requirement` and a declared
|
|
82
|
+
// scenario that never executed is `declared-not-run`, both ERRORs. So this is
|
|
83
|
+
// narrower than "zero scenarios ran" — and firing on that too would only
|
|
84
|
+
// double-report a run that is already red.
|
|
85
|
+
if (counts.requirements === 0) {
|
|
86
|
+
issues.push({
|
|
87
|
+
level: 'ERROR',
|
|
88
|
+
code: 'empty-spec',
|
|
89
|
+
message: `No requirements found under this root, so this run attested nothing. ` +
|
|
90
|
+
`Point attest at the directory holding your *.reqs.ts files, or add one.`,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// Nothing declares intent, so there is nothing for Attest to run. Skipping
|
|
94
|
+
// the child run keeps an incumbent suite untouched; the verdict comes from
|
|
95
|
+
// empty-spec or uncovered-requirement, both already ERRORs above.
|
|
96
|
+
const run = attesting.length === 0
|
|
97
|
+
? { passed: true, runtimeCoverage: new Map() }
|
|
98
|
+
: await runAndCollect({
|
|
99
|
+
root,
|
|
100
|
+
quiet: true,
|
|
101
|
+
include: attesting.map(escapeGlob),
|
|
102
|
+
vitestConfig: options.vitestConfig,
|
|
103
|
+
});
|
|
48
104
|
if (!run.passed) {
|
|
49
105
|
issues.push({ level: 'ERROR', code: 'tests-red', message: 'Some tests are failing.' });
|
|
50
106
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
issues.push({
|
|
54
|
-
level: 'ERROR',
|
|
55
|
-
code: 'declared-not-run',
|
|
56
|
-
reqId: s.reqId,
|
|
57
|
-
file: s.file,
|
|
58
|
-
line: s.line,
|
|
59
|
-
message: `scenario "${s.name}" statically declares it attests ${s.reqId}, but never executed (skipped, or excluded by an .only?).`,
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return { issues, passed: run.passed, ok: run.passed && !hasError(issues) };
|
|
107
|
+
issues.push(...declaredNotRunIssues(plan, run));
|
|
108
|
+
return { issues, passed: run.passed, ok: run.passed && !hasError(issues), counts };
|
|
64
109
|
}
|
|
65
110
|
/** Coverage-only report (design §9: `attest cover`). */
|
|
66
|
-
export async function runCover(root) {
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
counts.set(s.reqId, (counts.get(s.reqId) ?? 0) + 1);
|
|
74
|
-
}
|
|
75
|
-
return Object.keys(registry)
|
|
76
|
-
.sort()
|
|
77
|
-
.map((reqId) => ({
|
|
78
|
-
reqId,
|
|
79
|
-
covered: (counts.get(reqId) ?? 0) > 0,
|
|
80
|
-
scenarioCount: counts.get(reqId) ?? 0,
|
|
81
|
-
}));
|
|
82
|
-
}
|
|
83
|
-
finally {
|
|
84
|
-
await loader.close();
|
|
111
|
+
export async function runCover(root, options = {}) {
|
|
112
|
+
const scan = await scanProject(root);
|
|
113
|
+
const { registry } = await readRegistry(root, options, scan.reqsFiles);
|
|
114
|
+
const plan = await parseSpecs(scan.specFiles, root);
|
|
115
|
+
const counts = new Map();
|
|
116
|
+
for (const s of plan.scenarios) {
|
|
117
|
+
counts.set(s.reqId, (counts.get(s.reqId) ?? 0) + 1);
|
|
85
118
|
}
|
|
119
|
+
return Object.keys(registry)
|
|
120
|
+
.sort()
|
|
121
|
+
.map((reqId) => ({
|
|
122
|
+
reqId,
|
|
123
|
+
covered: (counts.get(reqId) ?? 0) > 0,
|
|
124
|
+
scenarioCount: counts.get(reqId) ?? 0,
|
|
125
|
+
}));
|
|
86
126
|
}
|
|
87
127
|
/**
|
|
88
128
|
* Markdown projection of the intent layer (design §9: `attest render`).
|
|
@@ -92,19 +132,13 @@ export async function runCover(root) {
|
|
|
92
132
|
* `*.reqs.ts` files, so a committed rendering can be gated without going stale
|
|
93
133
|
* every time a line moves in a test file.
|
|
94
134
|
*/
|
|
95
|
-
export async function runRender(root) {
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return { markdown: '', issues };
|
|
103
|
-
return { markdown: renderMarkdown(registry), issues };
|
|
104
|
-
}
|
|
105
|
-
finally {
|
|
106
|
-
await loader.close();
|
|
107
|
-
}
|
|
135
|
+
export async function runRender(root, options = {}) {
|
|
136
|
+
const { registry, issues } = await readRegistry(root, options);
|
|
137
|
+
// A registry that failed to load yields a document that silently omits
|
|
138
|
+
// requirements. An incomplete spec doc is worse than none, so refuse.
|
|
139
|
+
if (hasError(issues))
|
|
140
|
+
return { markdown: '', issues };
|
|
141
|
+
return { markdown: renderMarkdown(registry), issues };
|
|
108
142
|
}
|
|
109
143
|
/**
|
|
110
144
|
* Freshness gate for a committed rendering (`attest render --check`).
|
|
@@ -113,19 +147,67 @@ export async function runRender(root) {
|
|
|
113
147
|
* failure mode Attest exists to remove — so the projection only earns its place
|
|
114
148
|
* alongside a gate that fails when the file no longer matches its source.
|
|
115
149
|
*/
|
|
116
|
-
export async function runRenderCheck(root, outFile, target) {
|
|
117
|
-
const { markdown, issues } = await runRender(root);
|
|
150
|
+
export async function runRenderCheck(root, outFile, target, options = {}) {
|
|
151
|
+
const { markdown, issues } = await runRender(root, options);
|
|
118
152
|
if (hasError(issues))
|
|
119
153
|
return issues;
|
|
120
154
|
const current = await readFile(outFile, 'utf8').catch(() => undefined);
|
|
121
155
|
const stale = staleIssue(target, current, markdown);
|
|
122
156
|
return stale ? [...issues, stale] : issues;
|
|
123
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* A change name must name one directory inside `changes/`, and nothing else.
|
|
160
|
+
*
|
|
161
|
+
* The name is interpolated into a path whose module is then *executed*, and
|
|
162
|
+
* `join` normalises `..` — so an unvalidated name loads code from anywhere on
|
|
163
|
+
* disk. That is reachable from CI the moment the name comes from a branch or
|
|
164
|
+
* MR title.
|
|
165
|
+
*
|
|
166
|
+
* The test is path safety, not a character whitelist: the name never reaches a
|
|
167
|
+
* glob (only *sibling* names do, and changeExcludeGlobs escapes those), so
|
|
168
|
+
* `feat(auth)` or a name with a space is a perfectly good directory and there
|
|
169
|
+
* is no reason for the gate to refuse it. Rejecting only what can escape the
|
|
170
|
+
* directory keeps the guard exactly as wide as the danger.
|
|
171
|
+
*/
|
|
172
|
+
function isSafeChangeName(name) {
|
|
173
|
+
return (name !== '' &&
|
|
174
|
+
name !== '.' &&
|
|
175
|
+
name !== '..' &&
|
|
176
|
+
!name.includes('/') &&
|
|
177
|
+
!name.includes('\\') &&
|
|
178
|
+
!name.includes('\0'));
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* The globs that keep *other* proposals out of a change's gate run.
|
|
182
|
+
*
|
|
183
|
+
* Sibling names come from `readdir`, not from the guard above, so they are
|
|
184
|
+
* escaped: a directory called `feat(auth)` pasted in raw is a *pattern*, it
|
|
185
|
+
* matches nothing, and that sibling's specs silently join the run — quietly
|
|
186
|
+
* widening the scope of the one check that decides "done".
|
|
187
|
+
*/
|
|
188
|
+
export function changeExcludeGlobs(others) {
|
|
189
|
+
return others.map((n) => `**/changes/${escapeGlob(n)}/**`);
|
|
190
|
+
}
|
|
191
|
+
function escapeGlob(name) {
|
|
192
|
+
return name.replace(/[*?[\]{}()!+@|^$]/g, '\\$&');
|
|
193
|
+
}
|
|
124
194
|
/** Archive gate for a change (design §8, §9: `attest archive <change>`). */
|
|
125
195
|
export async function runArchive(root, changeName, options = {}) {
|
|
196
|
+
// Checked before any loader starts: nothing should be resolved, let alone
|
|
197
|
+
// evaluated, on behalf of a name we have already rejected.
|
|
198
|
+
if (!isSafeChangeName(changeName)) {
|
|
199
|
+
return [
|
|
200
|
+
{
|
|
201
|
+
level: 'ERROR',
|
|
202
|
+
code: 'invalid-change-name',
|
|
203
|
+
message: `Invalid change name ${JSON.stringify(changeName)}. A change name must be one directory inside changes/: it cannot be empty, "." or "..", or contain a path separator.`,
|
|
204
|
+
},
|
|
205
|
+
];
|
|
206
|
+
}
|
|
207
|
+
const scan = await scanProject(root);
|
|
126
208
|
const loader = await createLoader();
|
|
127
209
|
try {
|
|
128
|
-
const { registry: base, issues } = await loadRegistry(root, loader);
|
|
210
|
+
const { registry: base, issues } = await loadRegistry(root, evalReader(loader), scan.reqsFiles);
|
|
129
211
|
if (issues.some((i) => i.level === 'ERROR'))
|
|
130
212
|
return issues;
|
|
131
213
|
const deltaPath = join(root, 'changes', changeName, 'requirements.delta.ts');
|
|
@@ -148,7 +230,7 @@ export async function runArchive(root, changeName, options = {}) {
|
|
|
148
230
|
if (applied.issues.length > 0)
|
|
149
231
|
return applied.issues;
|
|
150
232
|
// Static plan = merged base suite + this change's specs (design §8).
|
|
151
|
-
const basePlan = await
|
|
233
|
+
const basePlan = await parseSpecs(scan.specFiles, root);
|
|
152
234
|
const changePlan = await parseChangeSpecs(root, changeName);
|
|
153
235
|
const plan = {
|
|
154
236
|
scenarios: [...basePlan.scenarios, ...changePlan.scenarios],
|
|
@@ -159,17 +241,22 @@ export async function runArchive(root, changeName, options = {}) {
|
|
|
159
241
|
const exclude = [
|
|
160
242
|
...configDefaults.exclude,
|
|
161
243
|
'**/archive/**',
|
|
162
|
-
...others
|
|
244
|
+
...changeExcludeGlobs(others),
|
|
163
245
|
];
|
|
164
|
-
|
|
246
|
+
// Same run scope as `verify`: only the files that declare a requirement().
|
|
247
|
+
// The gate must not go red because a repo's incumbent suite happens to sit
|
|
248
|
+
// under the same root as the change being archived.
|
|
249
|
+
const run = await runAndCollect({
|
|
250
|
+
root,
|
|
251
|
+
quiet: true,
|
|
252
|
+
include: attestingFiles(plan).map(escapeGlob),
|
|
253
|
+
exclude,
|
|
254
|
+
vitestConfig: options.vitestConfig,
|
|
255
|
+
});
|
|
165
256
|
return evaluateGate({ registry: applied.registry, plan, run });
|
|
166
257
|
}
|
|
167
258
|
finally {
|
|
168
259
|
await loader.close();
|
|
169
260
|
}
|
|
170
261
|
}
|
|
171
|
-
/** True when a spec suite exists at all (used by the CLI to warn on empty roots). */
|
|
172
|
-
export async function hasSpecs(root) {
|
|
173
|
-
return (await findFiles(root, (n) => n.endsWith('.spec.ts'))).length > 0;
|
|
174
|
-
}
|
|
175
262
|
//# sourceMappingURL=pipeline.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/core/pipeline.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,iFAAiF;AAEjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACL,YAAY,EACZ,
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/core/pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/core/render.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/core/render.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAe,MAAM,YAAY,CAAC;AAQ/D;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAezD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,YAAY,EACpB,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,KAAK,EAAE,MAAM,GACZ,KAAK,GAAG,SAAS,CAYnB"}
|
package/dist/core/render.js
CHANGED
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
// - **Params interpolated into the statement.** The source says
|
|
21
21
|
// "{idleTimeoutMin} minutes"; a human reader wants "30 minutes". This is the
|
|
22
22
|
// one thing the projection gives that reading the source does not.
|
|
23
|
+
import { byCodeUnit } from './order.js';
|
|
23
24
|
const BANNER = '<!-- Generated by `attest render` — do not edit. Edit the `*.reqs.ts` registry and regenerate. -->';
|
|
24
25
|
/**
|
|
25
26
|
* Render the registry as a standalone Markdown document.
|
|
@@ -82,10 +83,10 @@ function compareIds(a, b) {
|
|
|
82
83
|
};
|
|
83
84
|
const [prefixA, numA] = split(a);
|
|
84
85
|
const [prefixB, numB] = split(b);
|
|
85
|
-
//
|
|
86
|
-
//
|
|
86
|
+
// byCodeUnit, not localeCompare: the ordering has to be identical on every
|
|
87
|
+
// machine, or `--check` would flap with the runner's locale.
|
|
87
88
|
if (prefixA !== prefixB)
|
|
88
|
-
return prefixA
|
|
89
|
+
return byCodeUnit(prefixA, prefixB);
|
|
89
90
|
return numA - numB;
|
|
90
91
|
}
|
|
91
92
|
/**
|
|
@@ -124,7 +125,10 @@ function section(id, req) {
|
|
|
124
125
|
* `unbound-param` error, and silently swallowing it here would hide that.
|
|
125
126
|
*/
|
|
126
127
|
function interpolate(statement, params) {
|
|
127
|
-
|
|
128
|
+
// `Object.hasOwn`, never `in`: `'toString' in {}` is true, and an `in` probe
|
|
129
|
+
// would splice `function toString() { [native code] }` into a document that
|
|
130
|
+
// reviewers and audit read as the system's promise.
|
|
131
|
+
return statement.replace(/\{(\w+)\}/g, (whole, name) => Object.hasOwn(params, name) ? `**${plain(params[name])}**` : whole);
|
|
128
132
|
}
|
|
129
133
|
/**
|
|
130
134
|
* A param value as prose, for inline use inside a statement. Escaped, unlike
|
package/dist/core/render.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/core/render.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,6BAA6B;AAC7B,EAAE;AACF,8EAA8E;AAC9E,+EAA+E;AAC/E,0EAA0E;AAC1E,mEAAmE;AACnE,EAAE;AACF,wCAAwC;AACxC,gFAAgF;AAChF,gFAAgF;AAChF,gFAAgF;AAChF,4EAA4E;AAC5E,+EAA+E;AAC/E,8EAA8E;AAC9E,yCAAyC;AACzC,4EAA4E;AAC5E,gFAAgF;AAChF,uDAAuD;AACvD,iEAAiE;AACjE,gFAAgF;AAChF,sEAAsE;
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/core/render.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/core/runner.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAQ5C,MAAM,WAAW,oBAAoB;IACnC,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,kFAAkF;IAClF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;gFACgF;AAChF,KAAK,aAAa,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEpE;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/core/runner.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAQ5C,MAAM,WAAW,oBAAoB;IACnC,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,kFAAkF;IAClF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;gFACgF;AAChF,KAAK,aAAa,GAAG,WAAW,CAAC,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEpE;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAe/E;AAED,wBAAsB,aAAa,CACjC,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,SAAS,CAAC,CAkCpB"}
|
package/dist/core/runner.js
CHANGED
|
@@ -22,6 +22,12 @@ export function buildVitestOptions(options) {
|
|
|
22
22
|
include: options.include ?? ['**/*.spec.ts'],
|
|
23
23
|
exclude: options.exclude ?? DEFAULT_EXCLUDE,
|
|
24
24
|
config: options.vitestConfig ?? false,
|
|
25
|
+
// Attest decides what an empty run means, not Vitest: without this, a run
|
|
26
|
+
// that matched no file printed its own include/exclude banner and
|
|
27
|
+
// "No test files found, exiting with code 1" into the middle of Attest's
|
|
28
|
+
// report — while `passed` still came back true, because zero tests means
|
|
29
|
+
// zero failures. The verdict for that case is `empty-spec` (pipeline.ts).
|
|
30
|
+
passWithNoTests: true,
|
|
25
31
|
...(options.quiet ? { silent: true, reporters: [{}] } : {}),
|
|
26
32
|
};
|
|
27
33
|
}
|
package/dist/core/runner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/core/runner.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/core/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Registry } from './types.js';
|
|
2
|
+
/** Codes this reader can produce; each is also produced by the evaluating path. */
|
|
3
|
+
export type StaticReadCode = 'registry-invalid' | 'registry-no-default' | 'registry-not-static';
|
|
4
|
+
export type StaticReadResult = {
|
|
5
|
+
ok: true;
|
|
6
|
+
registry: Registry;
|
|
7
|
+
} | {
|
|
8
|
+
ok: false;
|
|
9
|
+
code: StaticReadCode;
|
|
10
|
+
message: string;
|
|
11
|
+
line?: number;
|
|
12
|
+
};
|
|
13
|
+
export declare function readRegistrySource(file: string, source: string): StaticReadResult;
|
|
14
|
+
//# sourceMappingURL=static-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-registry.d.ts","sourceRoot":"","sources":["../../src/core/static-registry.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C,mFAAmF;AACnF,MAAM,MAAM,cAAc,GAAG,kBAAkB,GAAG,qBAAqB,GAAG,qBAAqB,CAAC;AAEhG,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,GAChC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAexE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAuDjF"}
|