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/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 };