vitest-bats 0.0.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/LICENSE +21 -0
- package/README.md +415 -0
- package/bats-executor.js +103 -0
- package/bats-generator.js +114 -0
- package/coverage-reporter.js +319 -0
- package/index.d.ts +655 -0
- package/index.js +9 -0
- package/matchers.js +310 -0
- package/package.json +68 -0
- package/plugin.js +208 -0
- package/runtime.d.ts +82 -0
- package/runtime.js +172 -0
- package/schema.js +75 -0
- package/setup.d.ts +1 -0
- package/setup.js +12 -0
- package/tsdoc-metadata.json +11 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,655 @@
|
|
|
1
|
+
import { Plugin } from "vitest/config";
|
|
2
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
3
|
+
//#region src/vitest-kcov-types.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* TypeScript module augmentation for Vitest coverage options.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* Extends Vitest's `CoverageOptions` interface to include custom `kcov` configuration.
|
|
9
|
+
* This allows `defineConfig()` to properly type-check kcov options without `@ts-expect-error`.
|
|
10
|
+
*
|
|
11
|
+
* **Usage:**
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { defineConfig } from "vitest/config";
|
|
14
|
+
* import "./lib/vitest-kcov-plugin/vitest-kcov-types.js";
|
|
15
|
+
*
|
|
16
|
+
* export default defineConfig({
|
|
17
|
+
* test: {
|
|
18
|
+
* coverage: {
|
|
19
|
+
* kcov: {
|
|
20
|
+
* enabled: true,
|
|
21
|
+
* // ... other kcov options are now type-checked
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
24
|
+
* }
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @packageDocumentation
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Log verbosity level for the kcov coverage provider.
|
|
32
|
+
*
|
|
33
|
+
* @remarks
|
|
34
|
+
* Controls the amount of output displayed during coverage collection:
|
|
35
|
+
* - `verbose`: Show all messages including debug and informational
|
|
36
|
+
* - `debug`: Show debug messages and errors
|
|
37
|
+
* - `errors-only`: Only show errors and warnings
|
|
38
|
+
* @public
|
|
39
|
+
*/
|
|
40
|
+
type LogLevel = "verbose" | "debug" | "errors-only";
|
|
41
|
+
/**
|
|
42
|
+
* Hyperlink format for terminal output.
|
|
43
|
+
*
|
|
44
|
+
* @remarks
|
|
45
|
+
* Controls how file paths are formatted in terminal output:
|
|
46
|
+
* - `auto`: Auto-detect terminal support for HTE links (VSCode, iTerm 3.1+, WezTerm)
|
|
47
|
+
* - `default`: Plain text paths (e.g., "coverage/vitest/index.html")
|
|
48
|
+
* - `hte`: Hypertext Escape sequences (OSC 8) for clickable links in compatible terminals
|
|
49
|
+
* @public
|
|
50
|
+
*/
|
|
51
|
+
type LinkFormat = "auto" | "default" | "hte";
|
|
52
|
+
/**
|
|
53
|
+
* Coverage thresholds for kcov shell script coverage.
|
|
54
|
+
*
|
|
55
|
+
* @remarks
|
|
56
|
+
* Defines minimum coverage percentages required for tests to pass.
|
|
57
|
+
*
|
|
58
|
+
* **Important Limitation:**
|
|
59
|
+
* Kcov does NOT actually track branch coverage for bash scripts. The `branches` field is
|
|
60
|
+
* included for format compatibility with standard coverage reports, but kcov always reports
|
|
61
|
+
* `branch-rate="1.0"` (100%) in cobertura.xml for all shell scripts, regardless of actual
|
|
62
|
+
* branch execution.
|
|
63
|
+
*
|
|
64
|
+
* **What this means:**
|
|
65
|
+
* - Line coverage: Fully supported and accurate
|
|
66
|
+
* - Branch coverage: Always shows 100% (not meaningful for bash scripts with kcov)
|
|
67
|
+
* - Branch thresholds: Will always pass since kcov reports 100%
|
|
68
|
+
*
|
|
69
|
+
* **Recommendation:**
|
|
70
|
+
* Set branch threshold to 100% to maintain format compatibility, but rely on line coverage
|
|
71
|
+
* for actual quality metrics.
|
|
72
|
+
* @public
|
|
73
|
+
*/
|
|
74
|
+
interface KcovThresholds {
|
|
75
|
+
/**
|
|
76
|
+
* Enforce thresholds per file instead of globally
|
|
77
|
+
*
|
|
78
|
+
* @remarks
|
|
79
|
+
* When `true` or `undefined` (default), thresholds are checked for each individual file.
|
|
80
|
+
* When `false`, thresholds are checked against overall coverage across all files.
|
|
81
|
+
*
|
|
82
|
+
* @defaultValue `true`
|
|
83
|
+
*/
|
|
84
|
+
perFile?: boolean;
|
|
85
|
+
/** Minimum line coverage percentage (0-100) */
|
|
86
|
+
lines?: number;
|
|
87
|
+
/**
|
|
88
|
+
* Minimum branch coverage percentage (0-100)
|
|
89
|
+
*
|
|
90
|
+
* @remarks
|
|
91
|
+
* **Note:** Kcov always reports 100% branch coverage for bash scripts.
|
|
92
|
+
* This field exists for format compatibility but is not meaningful for shell script coverage.
|
|
93
|
+
*/
|
|
94
|
+
branches?: number;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Configuration options for kcov coverage collection.
|
|
98
|
+
*
|
|
99
|
+
* @remarks
|
|
100
|
+
* These options control how kcov collects and reports coverage for shell scripts.
|
|
101
|
+
* All options are optional and have sensible defaults.
|
|
102
|
+
*
|
|
103
|
+
* @see {@link KcovOptions.incremental} for timestamped report directories useful for debugging
|
|
104
|
+
* @public
|
|
105
|
+
*/
|
|
106
|
+
interface KcovOptions {
|
|
107
|
+
/**
|
|
108
|
+
* Subdirectory within reportsDirectory for kcov output.
|
|
109
|
+
*
|
|
110
|
+
* @remarks
|
|
111
|
+
* Reports are output to a subdirectory to keep them organized and separated from other files.
|
|
112
|
+
*
|
|
113
|
+
* **Path resolution:**
|
|
114
|
+
* - The subdir is resolved relative to reportsDirectory
|
|
115
|
+
* - Can be multiple levels deep (e.g., "foo/bar")
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```typescript
|
|
119
|
+
* // Default: subdir: "kcov"
|
|
120
|
+
* // Reports output to: coverage/kcov
|
|
121
|
+
*
|
|
122
|
+
* // Custom: subdir: "foo/bar"
|
|
123
|
+
* // Reports output to: coverage/foo/bar
|
|
124
|
+
* ```
|
|
125
|
+
*
|
|
126
|
+
* @defaultValue "kcov"
|
|
127
|
+
*/
|
|
128
|
+
subdir?: string;
|
|
129
|
+
/**
|
|
130
|
+
* Directory for BATS cache files.
|
|
131
|
+
*
|
|
132
|
+
* @remarks
|
|
133
|
+
* The cache directory stores generated .bats files and kcov output directories.
|
|
134
|
+
*
|
|
135
|
+
* **Path resolution:**
|
|
136
|
+
* - Relative paths are resolved from the reports directory
|
|
137
|
+
* - Use `../` to place cache as a sibling to the reports directory
|
|
138
|
+
* - Absolute paths can be used for system-wide cache locations
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```typescript
|
|
142
|
+
* // Default: cacheDir: "../bats-cache"
|
|
143
|
+
* // With subdir: "kcov" -> cache at: coverage/bats-cache
|
|
144
|
+
*
|
|
145
|
+
* // Custom relative path
|
|
146
|
+
* subdir: "foo/bar"
|
|
147
|
+
* cacheDir: "../bats-cache" // Resolves to: coverage/foo/bats-cache
|
|
148
|
+
*
|
|
149
|
+
* // Absolute path
|
|
150
|
+
* cacheDir: "/tmp/bats-cache"
|
|
151
|
+
* ```
|
|
152
|
+
*
|
|
153
|
+
* @defaultValue "../bats-cache"
|
|
154
|
+
*/
|
|
155
|
+
cacheDir?: string;
|
|
156
|
+
/**
|
|
157
|
+
* Whether to clean the resolved reports output directory before running tests.
|
|
158
|
+
*
|
|
159
|
+
* @remarks
|
|
160
|
+
* When true, removes the entire reports directory (reportsDirectory + subdir) before
|
|
161
|
+
* running tests to ensure a fresh start.
|
|
162
|
+
*
|
|
163
|
+
* @defaultValue true
|
|
164
|
+
*/
|
|
165
|
+
clean?: boolean;
|
|
166
|
+
/**
|
|
167
|
+
* Whether to clean the resolved cache directory before running tests.
|
|
168
|
+
*
|
|
169
|
+
* @remarks
|
|
170
|
+
* When true, removes the cache directory before running tests to ensure fresh
|
|
171
|
+
* .bats files are generated and no stale kcov data exists.
|
|
172
|
+
*
|
|
173
|
+
* @defaultValue true
|
|
174
|
+
*/
|
|
175
|
+
cleanCache?: boolean;
|
|
176
|
+
/**
|
|
177
|
+
* Whether to use incremental (timestamped) report directories.
|
|
178
|
+
*
|
|
179
|
+
* @remarks
|
|
180
|
+
* When true, a timestamp folder is inserted into the path one level above the final segment,
|
|
181
|
+
* allowing multiple test runs to be preserved for debugging purposes.
|
|
182
|
+
*
|
|
183
|
+
* **Path Resolution with Incremental:**
|
|
184
|
+
* - The timestamp format is `YYYY-MM-DD_HH-MM-SS` (e.g., "2025-11-12_14-30-45")
|
|
185
|
+
* - The timestamp is inserted before the last segment of the subdir path
|
|
186
|
+
* - Assumes tests won't run more than once per second
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* ```typescript
|
|
190
|
+
* // Without incremental (default)
|
|
191
|
+
* subdir: "foo/bar"
|
|
192
|
+
* // Reports: coverage/foo/bar
|
|
193
|
+
*
|
|
194
|
+
* // With incremental: true (custom subdir)
|
|
195
|
+
* subdir: "foo/bar"
|
|
196
|
+
* cacheDir: "../bats-cache"
|
|
197
|
+
* incremental: true
|
|
198
|
+
* // Reports: coverage/foo/2025-11-12_14-30-45/bar
|
|
199
|
+
* // Cache: coverage/foo/2025-11-12_14-30-45/bats-cache
|
|
200
|
+
*
|
|
201
|
+
* // With incremental: true (no subdir - uses defaults)
|
|
202
|
+
* incremental: true
|
|
203
|
+
* // Reports: coverage/2025-11-12_14-30-45/kcov
|
|
204
|
+
* // Cache: coverage/2025-11-12_14-30-45/kcov-cache
|
|
205
|
+
* ```
|
|
206
|
+
*
|
|
207
|
+
* @defaultValue false
|
|
208
|
+
*/
|
|
209
|
+
incremental?: boolean;
|
|
210
|
+
/**
|
|
211
|
+
* Log verbosity level: `verbose` | `debug` | `errors-only`
|
|
212
|
+
* @defaultValue `errors-only`
|
|
213
|
+
* */
|
|
214
|
+
logLevel?: LogLevel;
|
|
215
|
+
/**
|
|
216
|
+
* Hyperlink format for terminal output
|
|
217
|
+
*
|
|
218
|
+
* @remarks
|
|
219
|
+
* - `auto`: Auto-detect terminal support for HTE links (VSCode, iTerm 3.1+, WezTerm)
|
|
220
|
+
* - `default`: Plain text paths (e.g., "coverage/vitest/index.html")
|
|
221
|
+
* - `hte`: Hypertext Escape sequences (OSC 8) for clickable links in compatible terminals
|
|
222
|
+
* @defaultValue `auto`
|
|
223
|
+
* */
|
|
224
|
+
links?: LinkFormat;
|
|
225
|
+
/**
|
|
226
|
+
* Coverage thresholds for shell scripts.
|
|
227
|
+
*
|
|
228
|
+
* @remarks
|
|
229
|
+
* Unlike v8/Istanbul, kcov only tracks line coverage for shell scripts.
|
|
230
|
+
* Functions and statements thresholds are not applicable.
|
|
231
|
+
*
|
|
232
|
+
* **Important:** Kcov does NOT track branch coverage for bash scripts - it always reports
|
|
233
|
+
* 100% branch coverage. The branch threshold exists for format compatibility but will
|
|
234
|
+
* always pass. Use line coverage thresholds for actual quality enforcement.
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* ```typescript
|
|
238
|
+
* kcov: {
|
|
239
|
+
* thresholds: {
|
|
240
|
+
* perFile: true,
|
|
241
|
+
* lines: 90, // Enforced - tracks actual line execution
|
|
242
|
+
* branches: 100 // Not enforced - kcov always reports 100%
|
|
243
|
+
* }
|
|
244
|
+
* }
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
thresholds?: KcovThresholds;
|
|
248
|
+
/**
|
|
249
|
+
* Optional path to custom reporter module for coverage display.
|
|
250
|
+
*
|
|
251
|
+
* @remarks
|
|
252
|
+
* Defaults to the built-in KcovReporter located alongside the provider.
|
|
253
|
+
* Only specify this if you want to use a custom reporter implementation.
|
|
254
|
+
*/
|
|
255
|
+
customReporter?: string;
|
|
256
|
+
}
|
|
257
|
+
declare module "vitest/node" {
|
|
258
|
+
interface CustomProviderOptions {
|
|
259
|
+
/**
|
|
260
|
+
* Kcov-specific coverage options for shell script testing.
|
|
261
|
+
*
|
|
262
|
+
* @remarks
|
|
263
|
+
* Only applies when using the custom kcov coverage provider:
|
|
264
|
+
* ```typescript
|
|
265
|
+
* coverage: {
|
|
266
|
+
* provider: "custom",
|
|
267
|
+
* customProviderModule: "./lib/vitest-kcov-plugin/vitest-kcov-provider.ts",
|
|
268
|
+
* kcov: {
|
|
269
|
+
* // ... kcov options
|
|
270
|
+
* }
|
|
271
|
+
* }
|
|
272
|
+
* ```
|
|
273
|
+
*/
|
|
274
|
+
kcov?: KcovOptions;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
//#endregion
|
|
278
|
+
//#region src/runtime.d.ts
|
|
279
|
+
/**
|
|
280
|
+
* A single recorded invocation of a mocked command, captured back to the test as
|
|
281
|
+
* part of {@link BatsResult.calls}.
|
|
282
|
+
* @public
|
|
283
|
+
*/
|
|
284
|
+
interface MockCall {
|
|
285
|
+
args: string[];
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* The raw fields decoded from a BATS run, wrapped by the {@link BatsResult} class.
|
|
289
|
+
* @public
|
|
290
|
+
*/
|
|
291
|
+
interface BatsResultData {
|
|
292
|
+
status: number;
|
|
293
|
+
output: string;
|
|
294
|
+
stderr: string;
|
|
295
|
+
calls: Record<string, MockCall[]>;
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Symbol brand identifying a BatsResult instance. Used by matchers to
|
|
299
|
+
* detect BatsResult inputs in a way that survives:
|
|
300
|
+
* - Module-graph duplication (per-entry self-contained bundles produced as
|
|
301
|
+
* the workaround for savvy-web/rslib-builder#158, where each entry has
|
|
302
|
+
* its own copy of the BatsResult class — `instanceof` would fail).
|
|
303
|
+
* - Property name minification (a `constructor.name === "BatsResult"`
|
|
304
|
+
* check would break under any minifier that renames classes).
|
|
305
|
+
*
|
|
306
|
+
* Registered with `Symbol.for(...)` so the symbol is shared across module
|
|
307
|
+
* graphs (the global symbol registry is process-wide).
|
|
308
|
+
* @internal
|
|
309
|
+
*/
|
|
310
|
+
declare const BATS_RESULT_BRAND: unique symbol;
|
|
311
|
+
/**
|
|
312
|
+
* The value returned by `ScriptBuilder.run()`/`.exec()`. Wraps the raw exit status,
|
|
313
|
+
* stdout/stderr (whole and split into lines), and recorded mock calls; assert
|
|
314
|
+
* against it with the `expect.extend` matchers from `vitest-bats/setup`.
|
|
315
|
+
* @public
|
|
316
|
+
*/
|
|
317
|
+
declare class BatsResult {
|
|
318
|
+
/** @internal */
|
|
319
|
+
readonly [BATS_RESULT_BRAND] = true;
|
|
320
|
+
readonly status: number;
|
|
321
|
+
readonly output: string;
|
|
322
|
+
readonly stderr: string;
|
|
323
|
+
readonly lines: string[];
|
|
324
|
+
readonly stderr_lines: string[];
|
|
325
|
+
readonly calls: Record<string, MockCall[]>;
|
|
326
|
+
private _jsonCache;
|
|
327
|
+
constructor(data: BatsResultData);
|
|
328
|
+
json<T = unknown>(): T;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* Resets every live `ScriptBuilder`'s `env()`/`flags()`/`mock()` configuration.
|
|
332
|
+
* Called automatically between tests by `vitest-bats/setup`'s `beforeEach` hook.
|
|
333
|
+
* @public
|
|
334
|
+
*/
|
|
335
|
+
declare function resetAllBuilders(): void;
|
|
336
|
+
/**
|
|
337
|
+
* Test-writing API returned by a `.sh` import. Configure with `env()`/`flags()`/
|
|
338
|
+
* `mock()`, then terminate with `run(...args)` or `exec(shellExpr)` to get a
|
|
339
|
+
* {@link BatsResult}.
|
|
340
|
+
* @public
|
|
341
|
+
*/
|
|
342
|
+
declare class ScriptBuilder {
|
|
343
|
+
readonly path: string;
|
|
344
|
+
readonly name: string;
|
|
345
|
+
private _env;
|
|
346
|
+
private _flags;
|
|
347
|
+
private _stubs;
|
|
348
|
+
constructor(path: string, name: string);
|
|
349
|
+
env(vars: Record<string, string>): this;
|
|
350
|
+
flags(value: string): this;
|
|
351
|
+
mock(cmd: string, responses?: Record<string, string>): this;
|
|
352
|
+
run(...args: string[]): BatsResult;
|
|
353
|
+
exec(shellExpr: string): BatsResult;
|
|
354
|
+
reset(): void;
|
|
355
|
+
private execute;
|
|
356
|
+
}
|
|
357
|
+
//#endregion
|
|
358
|
+
//#region src/bats-executor.d.ts
|
|
359
|
+
/**
|
|
360
|
+
* Options for {@link executeBats}.
|
|
361
|
+
* @internal
|
|
362
|
+
*/
|
|
363
|
+
interface ExecuteOptions {
|
|
364
|
+
batsPath: string;
|
|
365
|
+
batsContent: string;
|
|
366
|
+
recorderDir: string;
|
|
367
|
+
timeoutMs?: number;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Parses the base64-encoded result payload written by the generated BATS test file.
|
|
371
|
+
* @internal
|
|
372
|
+
*/
|
|
373
|
+
declare function parseExecutionResult(recorderDir: string): BatsResultData;
|
|
374
|
+
/**
|
|
375
|
+
* Spawns `bats` against a generated `.bats` file and parses the recorded result.
|
|
376
|
+
* @internal
|
|
377
|
+
*/
|
|
378
|
+
declare function executeBats(opts: ExecuteOptions): BatsResultData;
|
|
379
|
+
//#endregion
|
|
380
|
+
//#region src/bats-generator.d.ts
|
|
381
|
+
/**
|
|
382
|
+
* Resolved paths to the `bats` binary and the `bats-support` library, detected by
|
|
383
|
+
* `BatsPlugin` and threaded through to {@link generateBatsFile}.
|
|
384
|
+
* @internal
|
|
385
|
+
*/
|
|
386
|
+
interface BatsDeps {
|
|
387
|
+
batsPath: string;
|
|
388
|
+
batsSupportPath: string;
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Resolved kcov binary path and output directory for a single script run.
|
|
392
|
+
* @internal
|
|
393
|
+
*/
|
|
394
|
+
interface KcovConfig {
|
|
395
|
+
kcovPath: string;
|
|
396
|
+
outputDir: string;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* A single `mock()` call's command name and pattern-to-response map, as recorded
|
|
400
|
+
* by `ScriptBuilder`.
|
|
401
|
+
* @internal
|
|
402
|
+
*/
|
|
403
|
+
interface StubSpec {
|
|
404
|
+
cmd: string;
|
|
405
|
+
responses: Record<string, string>;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Whether the generated `.bats` file invokes the script with argv (`run()`) or as a
|
|
409
|
+
* raw shell expression (`exec()`).
|
|
410
|
+
* @internal
|
|
411
|
+
*/
|
|
412
|
+
type RunMode = {
|
|
413
|
+
kind: "args";
|
|
414
|
+
} | {
|
|
415
|
+
kind: "shell";
|
|
416
|
+
expression: string;
|
|
417
|
+
};
|
|
418
|
+
/**
|
|
419
|
+
* Input to {@link generateBatsFile}.
|
|
420
|
+
* @internal
|
|
421
|
+
*/
|
|
422
|
+
interface GenerateInput {
|
|
423
|
+
scriptPath: string;
|
|
424
|
+
args: string[];
|
|
425
|
+
env: Record<string, string>;
|
|
426
|
+
flags: string;
|
|
427
|
+
stubs: StubSpec[];
|
|
428
|
+
recorderDir: string;
|
|
429
|
+
deps: BatsDeps;
|
|
430
|
+
mode: RunMode;
|
|
431
|
+
kcov?: KcovConfig;
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
434
|
+
* Renders a `.bats` file body for a single `ScriptBuilder` invocation: setup (deps,
|
|
435
|
+
* env, recorder, mock shims, kcov), the `run` command, and the base64 result capture.
|
|
436
|
+
* @internal
|
|
437
|
+
*/
|
|
438
|
+
declare function generateBatsFile(input: GenerateInput): string;
|
|
439
|
+
//#endregion
|
|
440
|
+
//#region src/coverage-reporter.d.ts
|
|
441
|
+
/**
|
|
442
|
+
* Coverage thresholds applied to the merged v8/kcov CoverageMap.
|
|
443
|
+
* @public
|
|
444
|
+
*/
|
|
445
|
+
interface CoverageThresholds {
|
|
446
|
+
statements: number;
|
|
447
|
+
branches: number;
|
|
448
|
+
functions: number;
|
|
449
|
+
lines: number;
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Vitest coverage reporter that merges kcov's shell-script coverage into the v8
|
|
453
|
+
* Istanbul CoverageMap, with synthetic branch/function entries so threshold checks
|
|
454
|
+
* pass (kcov only tracks statements/lines). Always injected by {@link BatsPlugin}
|
|
455
|
+
* when coverage is enabled.
|
|
456
|
+
* @public
|
|
457
|
+
*/
|
|
458
|
+
declare class BatsCoverageReporter {
|
|
459
|
+
private cacheDir;
|
|
460
|
+
private thresholds;
|
|
461
|
+
private statementPassThrough;
|
|
462
|
+
private readonly xmlParser;
|
|
463
|
+
constructor(cacheDir: string, options?: {
|
|
464
|
+
thresholds?: CoverageThresholds;
|
|
465
|
+
statementPassThrough?: boolean;
|
|
466
|
+
});
|
|
467
|
+
onInit(): void;
|
|
468
|
+
onCoverage(coverage: unknown): void;
|
|
469
|
+
private buildSyntheticCoverageEntry;
|
|
470
|
+
private gcd;
|
|
471
|
+
/** Returns the smallest total/covered pair that gives exactly threshold%. */
|
|
472
|
+
private thresholdFraction;
|
|
473
|
+
/** Pad statements to an exact multiple and mark the right fraction as covered. */
|
|
474
|
+
private applySyntheticStatements;
|
|
475
|
+
/** Create synthetic branch entries for exact threshold coverage. */
|
|
476
|
+
private applySyntheticBranches;
|
|
477
|
+
/** Create synthetic function entries for exact threshold coverage. */
|
|
478
|
+
private applySyntheticFunctions;
|
|
479
|
+
private buildZeroCoverageEntry;
|
|
480
|
+
private isExecutableLine;
|
|
481
|
+
/**
|
|
482
|
+
* Collect real coverage data from kcov cobertura.xml files.
|
|
483
|
+
* Returns a map of absolute script path to Istanbul file coverage.
|
|
484
|
+
*/
|
|
485
|
+
private collectKcovCoverage;
|
|
486
|
+
private findCoberturaFiles;
|
|
487
|
+
private parseCoberturaToIstanbul;
|
|
488
|
+
}
|
|
489
|
+
//#endregion
|
|
490
|
+
//#region src/matchers.d.ts
|
|
491
|
+
/**
|
|
492
|
+
* The `{ pass, message }` shape expected by Vitest's `expect.extend`.
|
|
493
|
+
* @public
|
|
494
|
+
*/
|
|
495
|
+
interface MatcherResult {
|
|
496
|
+
pass: boolean;
|
|
497
|
+
message: () => string;
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* The 23 `expect.extend` matchers registered by `vitest-bats/setup` (auto-injected
|
|
501
|
+
* by {@link BatsPlugin}). Cover status, stdout/stderr, lines, mock calls, JSON
|
|
502
|
+
* values, and schema validation against a `BatsResult`.
|
|
503
|
+
* @public
|
|
504
|
+
*/
|
|
505
|
+
declare const batsMatchers: {
|
|
506
|
+
toSucceed(received: unknown): MatcherResult;
|
|
507
|
+
toFail(received: unknown, code?: number): MatcherResult;
|
|
508
|
+
toHaveOutput(received: unknown, text: string): MatcherResult;
|
|
509
|
+
toContainOutput(received: unknown, text: string): MatcherResult;
|
|
510
|
+
toMatchOutput(received: unknown, pattern: RegExp | string): MatcherResult;
|
|
511
|
+
toHaveEmptyOutput(received: unknown): MatcherResult;
|
|
512
|
+
toHaveStderr(received: unknown, text: string): MatcherResult;
|
|
513
|
+
toContainStderr(received: unknown, text: string): MatcherResult;
|
|
514
|
+
toMatchStderr(received: unknown, pattern: RegExp | string): MatcherResult;
|
|
515
|
+
toHaveLine(received: unknown, index: number, text: string): MatcherResult;
|
|
516
|
+
toHaveLineContaining(received: unknown, text: string, index?: number): MatcherResult;
|
|
517
|
+
toHaveLineMatching(received: unknown, pattern: RegExp | string, index?: number): MatcherResult;
|
|
518
|
+
toHaveLineCount(received: unknown, n: number): MatcherResult;
|
|
519
|
+
toOutputJson(received: unknown): MatcherResult;
|
|
520
|
+
toEqualJson(received: unknown, expected: unknown): MatcherResult;
|
|
521
|
+
toMatchJson(received: unknown, partial: object): MatcherResult;
|
|
522
|
+
toHaveJsonValue(received: unknown, path: string, expected: unknown): MatcherResult;
|
|
523
|
+
toHaveJsonPath(received: unknown, path: string): MatcherResult;
|
|
524
|
+
toMatchSchema(received: unknown, schema: unknown): MatcherResult;
|
|
525
|
+
toMatchJsonSchema(received: unknown, schema: object): MatcherResult;
|
|
526
|
+
toHaveInvoked(received: unknown, cmd: string, opts?: {
|
|
527
|
+
args?: string[];
|
|
528
|
+
}): MatcherResult;
|
|
529
|
+
toHaveInvokedTimes(received: unknown, cmd: string, n: number): MatcherResult;
|
|
530
|
+
toHaveInvokedExactly(received: unknown, cmd: string, calls: {
|
|
531
|
+
args: string[];
|
|
532
|
+
}[]): MatcherResult;
|
|
533
|
+
};
|
|
534
|
+
declare module "vitest" {
|
|
535
|
+
interface Assertion {
|
|
536
|
+
toSucceed(): void;
|
|
537
|
+
toFail(code?: number): void;
|
|
538
|
+
toHaveOutput(text: string): void;
|
|
539
|
+
toContainOutput(text: string): void;
|
|
540
|
+
toMatchOutput(pattern: RegExp | string): void;
|
|
541
|
+
toHaveEmptyOutput(): void;
|
|
542
|
+
toHaveStderr(text: string): void;
|
|
543
|
+
toContainStderr(text: string): void;
|
|
544
|
+
toMatchStderr(pattern: RegExp | string): void;
|
|
545
|
+
toHaveLine(index: number, text: string): void;
|
|
546
|
+
toHaveLineContaining(text: string, index?: number): void;
|
|
547
|
+
toHaveLineMatching(pattern: RegExp | string, index?: number): void;
|
|
548
|
+
toHaveLineCount(n: number): void;
|
|
549
|
+
toOutputJson(): void;
|
|
550
|
+
toEqualJson(expected: unknown): void;
|
|
551
|
+
toMatchJson(partial: object): void;
|
|
552
|
+
toHaveJsonValue(path: string, expected: unknown): void;
|
|
553
|
+
toHaveJsonPath(path: string): void;
|
|
554
|
+
toMatchSchema(schema: unknown): void;
|
|
555
|
+
toMatchJsonSchema(schema: object): void;
|
|
556
|
+
toHaveInvoked(cmd: string, opts?: {
|
|
557
|
+
args?: string[];
|
|
558
|
+
}): void;
|
|
559
|
+
toHaveInvokedTimes(cmd: string, n: number): void;
|
|
560
|
+
toHaveInvokedExactly(cmd: string, calls: {
|
|
561
|
+
args: string[];
|
|
562
|
+
}[]): void;
|
|
563
|
+
}
|
|
564
|
+
interface AsymmetricMatchersContaining {
|
|
565
|
+
toSucceed(): void;
|
|
566
|
+
toFail(code?: number): void;
|
|
567
|
+
toHaveOutput(text: string): void;
|
|
568
|
+
toContainOutput(text: string): void;
|
|
569
|
+
toMatchOutput(pattern: RegExp | string): void;
|
|
570
|
+
toHaveEmptyOutput(): void;
|
|
571
|
+
toHaveStderr(text: string): void;
|
|
572
|
+
toContainStderr(text: string): void;
|
|
573
|
+
toMatchStderr(pattern: RegExp | string): void;
|
|
574
|
+
toHaveLine(index: number, text: string): void;
|
|
575
|
+
toHaveLineContaining(text: string, index?: number): void;
|
|
576
|
+
toHaveLineMatching(pattern: RegExp | string, index?: number): void;
|
|
577
|
+
toHaveLineCount(n: number): void;
|
|
578
|
+
toOutputJson(): void;
|
|
579
|
+
toEqualJson(expected: unknown): void;
|
|
580
|
+
toMatchJson(partial: object): void;
|
|
581
|
+
toHaveJsonValue(path: string, expected: unknown): void;
|
|
582
|
+
toHaveJsonPath(path: string): void;
|
|
583
|
+
toMatchSchema(schema: unknown): void;
|
|
584
|
+
toMatchJsonSchema(schema: object): void;
|
|
585
|
+
toHaveInvoked(cmd: string, opts?: {
|
|
586
|
+
args?: string[];
|
|
587
|
+
}): void;
|
|
588
|
+
toHaveInvokedTimes(cmd: string, n: number): void;
|
|
589
|
+
toHaveInvokedExactly(cmd: string, calls: {
|
|
590
|
+
args: string[];
|
|
591
|
+
}[]): void;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
//#endregion
|
|
595
|
+
//#region src/plugin.d.ts
|
|
596
|
+
/**
|
|
597
|
+
* Options for {@link BatsPlugin}.
|
|
598
|
+
* @public
|
|
599
|
+
*/
|
|
600
|
+
interface BatsPluginOptions {
|
|
601
|
+
/**
|
|
602
|
+
* Shell script coverage mode. Default: "auto"
|
|
603
|
+
* - "auto": include .sh in coverage when kcov is available, exclude when not
|
|
604
|
+
* - true: require kcov, throw if unavailable, include .sh in coverage
|
|
605
|
+
* - false: always exclude .sh from coverage
|
|
606
|
+
*/
|
|
607
|
+
coverage?: "auto" | boolean;
|
|
608
|
+
/**
|
|
609
|
+
* How to handle missing system dependencies (bats, kcov, jq, etc.).
|
|
610
|
+
* Default: "error"
|
|
611
|
+
* - "error": throw on missing required deps, blocking all tests
|
|
612
|
+
* - "warn": log warnings but continue; BATS integration tests will
|
|
613
|
+
* fail individually at runtime, pure TS unit tests run normally
|
|
614
|
+
*/
|
|
615
|
+
deps?: "error" | "warn";
|
|
616
|
+
/** Log level for detection output. Default: "errors-only" */
|
|
617
|
+
logLevel?: LogLevel;
|
|
618
|
+
/** Hyperlink format for reporter. Default: "auto" */
|
|
619
|
+
links?: LinkFormat;
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* Vitest plugin that wires up `.sh` imports, dependency detection, coverage
|
|
623
|
+
* option handling, matcher setup-file injection, and coverage reporter injection.
|
|
624
|
+
* @public
|
|
625
|
+
*/
|
|
626
|
+
declare function BatsPlugin(options?: BatsPluginOptions): Plugin;
|
|
627
|
+
//#endregion
|
|
628
|
+
//#region src/schema.d.ts
|
|
629
|
+
/**
|
|
630
|
+
* Result of {@link validate}: either success, or failure with human-readable issue
|
|
631
|
+
* strings, used internally by the `toMatchSchema`/`toMatchJsonSchema` matchers.
|
|
632
|
+
* @internal
|
|
633
|
+
*/
|
|
634
|
+
type ValidationResult = {
|
|
635
|
+
ok: true;
|
|
636
|
+
} | {
|
|
637
|
+
ok: false;
|
|
638
|
+
issues: string[];
|
|
639
|
+
};
|
|
640
|
+
/**
|
|
641
|
+
* Detects whether `schema` implements the Standard Schema (`~standard`) interface,
|
|
642
|
+
* used by the `toMatchSchema` matcher to route to Standard Schema vs. JSON Schema
|
|
643
|
+
* validation.
|
|
644
|
+
* @internal
|
|
645
|
+
*/
|
|
646
|
+
declare function isStandardSchema(schema: unknown): schema is StandardSchemaV1;
|
|
647
|
+
/**
|
|
648
|
+
* Validates `value` against a Standard Schema validator or a raw JSON Schema
|
|
649
|
+
* object, backing the `toMatchSchema`/`toMatchJsonSchema` matchers.
|
|
650
|
+
* @internal
|
|
651
|
+
*/
|
|
652
|
+
declare function validate(schema: unknown, value: unknown): ValidationResult;
|
|
653
|
+
//#endregion
|
|
654
|
+
export { BatsCoverageReporter, type BatsDeps, BatsPlugin, type BatsPluginOptions, BatsResult, type BatsResultData, type CoverageThresholds, type ExecuteOptions, type GenerateInput, type KcovConfig, type KcovOptions, type KcovThresholds, type LinkFormat, type LogLevel, type MatcherResult, type MockCall, type RunMode, ScriptBuilder, type StubSpec, type ValidationResult, batsMatchers, executeBats, generateBatsFile, isStandardSchema, parseExecutionResult, resetAllBuilders, validate };
|
|
655
|
+
//# sourceMappingURL=index.d.ts.map
|
package/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { executeBats, parseExecutionResult } from "./bats-executor.js";
|
|
2
|
+
import { generateBatsFile } from "./bats-generator.js";
|
|
3
|
+
import { BatsCoverageReporter } from "./coverage-reporter.js";
|
|
4
|
+
import { BatsResult, ScriptBuilder, resetAllBuilders } from "./runtime.js";
|
|
5
|
+
import { isStandardSchema, validate } from "./schema.js";
|
|
6
|
+
import { batsMatchers } from "./matchers.js";
|
|
7
|
+
import { BatsPlugin } from "./plugin.js";
|
|
8
|
+
|
|
9
|
+
export { BatsCoverageReporter, BatsPlugin, BatsResult, ScriptBuilder, batsMatchers, executeBats, generateBatsFile, isStandardSchema, parseExecutionResult, resetAllBuilders, validate };
|