@systemfsoftware/vitest 1.0.0 → 4.1.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 CHANGED
@@ -1,53 +1,9 @@
1
1
  # @systemfsoftware/vitest
2
2
 
3
- ## 1.0.0
3
+ # @systemfsoftware/vitest@4.1.1
4
4
 
5
- ### Major Changes
5
+ Published declaration files no longer carry the rolldown-plugin-dts patch; they come from rolldown-plugin-dts 0.28.8, which includes the same fix upstream.
6
6
 
7
- - Require `effect` `^4` (stable 4.0.0). Release candidates are no longer supported: imports follow 4.0.0's module layout (`effect/http`, `effect/rpc`, `effect/http-api`, `effect/cluster`, `effect/process`, `effect/socket`, `effect/persistence`, `effect/reactivity`, `effect/encoding`, `effect/Arbitrary`), which does not exist in any 4.0.0 RC.
7
+ The property-check defaults no longer read `process.env` when a browser runner exposes a `process` with no `env`; there the record is empty, as it already was when `process` is absent.
8
8
 
9
- ## 0.3.0
10
-
11
- ### Minor Changes
12
-
13
- - `@systemfsoftware/vitest/failure` exports `Replay`, the `ReplayFromText` codec for `CONFORMANCE_REPLAY` text (`seed=<n>;path=<steps>`), and `replayOfText`, which reads that text or throws. `ReplayValue.path` is now `ReadonlyArray<number>`, and `providedWorkspaceRoot()` returns a branded `WorkspaceRoot`.
14
-
15
- ## 0.2.0
16
-
17
- ### Minor Changes
18
-
19
- - Tests take `expect` from the test callback and yield each check: `it(name, function* ({ expect }) { yield* expect(actual).toEqual(expected) })`. The package stops exporting `expect`, `assert` and the `utils` helpers. With its `guard` entry listed in `setupFiles`, an `expect` imported from Vitest, or a test registered through Vitest's own `it`, is refused. Also refused, each with its rewrite as the message: a second check on one observed state, an unyielded check, a body with no check, a non-generator body, `it.effect`/`it.scoped`/`it.scopedLive`, `beforeEach`/`afterEach`, and weak matchers such as `toHaveLength`, `toBeDefined`, snapshots, `expect.anything`, `expect.soft`/`expect.poll` and argument-less `toThrow`. Libraries that judge inside a test import `step`, `captureRunBinding` and the `Check`/`Expect`/`Asserted` types from the `integration` entry.
20
-
21
- - `@systemfsoftware/differential-spec` depends on and imports `@systemfsoftware/vitest` by its own name instead of through an `@effect/vitest` alias. `@systemfsoftware/oxlint-config-recommended` enables the test-discipline rule under its new id `vitest-from-systemfsoftware-vitest`. `@systemfsoftware/vitest` documentation examples import from `@systemfsoftware/vitest`.
22
-
23
- The lawful runner is published under its own name, `@systemfsoftware/vitest`, starting at `0.1.0`, so peers declared as `^0.1.0` accept its patch releases.
24
-
25
- - A failing test now reports one failure record instead of a raw cause: the error with its message, the first source line outside the spec libraries, the steps that ran and the cell decisions each caused, and a rerun command for that one scenario. Every cause in the chain keeps all lines of its message. A replay value is printed only for a run a seed or a property chose. Each failure prints once; other errors in the same cause are logged. A failed `expect` points at the line that called it and a property failure at the line that declared it. A new `@systemfsoftware/vitest/failure` entry exports the renderer, the recorder, the cause summary (`summaryOf`) and the author call-site capture (`callSite`, `callFrameOutside`, `withRaisingFrame`) for libraries that raise their own failures.
26
-
27
- - Kernel runs are serialized. A run started while another is live now waits behind it, in arrival order, instead of failing: two runs never interleave, so a scenario never sees another run's decisions, and a suite whose cases drive the kernel can run its tests concurrently.
28
-
29
- `@systemfsoftware/vitest` adds `captureRunBinding`, the running test's run binding. `bind(effect)` re-provides it to an effect a library runs on a runtime of its own — its own scheduler, a worker, a simulation kernel — so the checks inside it count as that test's assertions, report softly, and see the same `owned` regions.
30
-
31
- `@systemfsoftware/effect-spec-runtime` runs a case that declares no live reason through that runner, and a case's annotations now reach the test's report.
32
-
33
- ## 0.1.0
34
-
35
- ### Minor Changes
36
-
37
- - Tests take `expect` from the test callback and yield each check: `it(name, function* ({ expect }) { yield* expect(actual).toEqual(expected) })`. The package stops exporting `expect`, `assert` and the `utils` helpers. With its `guard` entry listed in `setupFiles`, an `expect` imported from Vitest, or a test registered through Vitest's own `it`, is refused. Also refused, each with its rewrite as the message: a second check on one observed state, an unyielded check, a body with no check, a non-generator body, `it.effect`/`it.scoped`/`it.scopedLive`, `beforeEach`/`afterEach`, and weak matchers such as `toHaveLength`, `toBeDefined`, snapshots, `expect.anything`, `expect.soft`/`expect.poll` and argument-less `toThrow`. Libraries that judge inside a test import `step`, `captureRunBinding` and the `Check`/`Expect`/`Asserted` types from the `integration` entry.
38
-
39
- ## 0.0.0
40
-
41
- ### Minor Changes
42
-
43
- - New `captureRunBinding`: an Effect that captures the running test's binding, so a testing library can run an effect elsewhere (e.g. inside a simulation kernel) and still have its `expect` calls counted as that test's assertions.
44
-
45
- - `@systemfsoftware/differential-spec` depends on and imports `@systemfsoftware/vitest` by its own name instead of through an `@effect/vitest` alias. `@systemfsoftware/oxlint-config-recommended` enables the test-discipline rule under its new id `vitest-from-systemfsoftware-vitest`. `@systemfsoftware/vitest` documentation examples import from `@systemfsoftware/vitest`.
46
-
47
- The lawful runner is published under its own name, `@systemfsoftware/vitest`, starting at `0.1.0`, so peers declared as `^0.1.0` accept its patch releases.
48
-
49
- - Kernel runs are serialized. A run started while another is live now waits behind it, in arrival order, instead of failing: two runs never interleave, so a scenario never sees another run's decisions, and a suite whose cases drive the kernel can run its tests concurrently.
50
-
51
- `@systemfsoftware/vitest` adds `captureRunBinding`, the running test's run binding. `bind(effect)` re-provides it to an effect a library runs on a runtime of its own — its own scheduler, a worker, a simulation kernel — so the checks inside it count as that test's assertions, report softly, and see the same `owned` regions.
52
-
53
- `@systemfsoftware/effect-spec-runtime` runs a case that declares no live reason through that runner, and a case's annotations now reach the test's report.
9
+ `@systemfsoftware/effect-schema-discovery` is rebuilt against the updated `@systemfsoftware/vitest`; its own behavior is unchanged.
package/README.md CHANGED
@@ -97,6 +97,18 @@ A passing test outside a declared-shared block runs a second time on a fresh bui
97
97
 
98
98
  That is how a module-level counter, a shared cache, or a process-global histogram gets reported instead of staying green. `it.live` is re-run too, so a real-resource suite gets the same check. A declared-shared block is the one exception.
99
99
 
100
+ A registration can name what the second run runs with `rerun`, a generator body of the same shape. The second run still happens only after a clean first run, on a fresh build, and a failure there is still `LeakedState`. A harness whose first run already repeats the body many times uses it to run the body once more instead of repeating all of that work:
101
+
102
+ ```ts
103
+ it('reads the stored row', function*({ expect }) {
104
+ // the first run
105
+ }, {
106
+ rerun: function*({ expect }) {
107
+ // the second run, on a fresh build of the services
108
+ },
109
+ })
110
+ ```
111
+
100
112
  ## Concurrency and shuffle
101
113
 
102
114
  Tests inside a block run concurrently and in shuffled order, and each concurrent test keeps its own failure list and check counts. Concurrency is what makes a cross-test leak reproducible: two tests that interleave are two tests whose state must not be shared. Nothing else pins their order.
@@ -171,16 +183,82 @@ it.prop(
171
183
 
172
184
  ### The constant-impostor gate
173
185
 
174
- After a property holds, it runs again against a constant impostor of its subject — a fake that returns the first output forever, whatever the input. Each subject is judged across every property in its file, when the file ends. If nothing in the file refutes the impostor, the file fails `VacuousProperty`:
186
+ After a property holds, it runs again against a constant impostor of its subject — a fake that returns the first output forever, whatever the input. Each subject is judged across every property in its file, when the file ends. If nothing in the file refutes the impostor, the file fails with `VacuousProperty`:
187
+
188
+ ```ts
189
+ export interface VacuousProperty {
190
+ readonly _tag: 'VacuousProperty'
191
+ readonly subjects: ReadonlyArray<{
192
+ readonly label: string
193
+ readonly properties: ReadonlyArray<{
194
+ readonly property: { name: string; site: string | null; seed: number; runs: number }
195
+ readonly frozen:
196
+ | { _tag: 'Frozen'; outputs: ReadonlyArray<{ member: string; output: { rendered: string; value: unknown } }> }
197
+ | { _tag: 'NeverCalled' }
198
+ }>
199
+ }>
200
+ readonly exempt: ReadonlyArray<{ name: string; kind: string }>
201
+ readonly replay: string
202
+ }
203
+ ```
204
+
205
+ The `frozen` union distinguishes a subject whose impostor was called (`Frozen`, with rendered outputs for each member) from one never called during the vacuity check (`NeverCalled`). Replay the same verdict with:
206
+
207
+ ```bash
208
+ CONFORMANCE_REPLAY="property=<hash>;seed=<n>;runs=<n>|..." pnpm test
209
+ ```
210
+
211
+ Other property failures are exported from the package root as tagged errors — each carries its own fields:
175
212
 
176
- > sort: no property in this file refuted the constant impostor of \`sort\`, so nothing here pins it down. … Laws that only relate outputs to each other (additivity, idempotence, commutativity, round trips through the subject) hold for such constants. Pin the output to the input: compare against an independent model (\`subject(x)\` equals a straightforward reimplementation), or conjoin a base case (\`subject([one])\` equals its known value). Also check that the body calls the \`subject\` it was given, not the imported implementation.
213
+ - **`PropertyRefuted`**: `property` (name, site, seed, runs), `counterexample` (rendered, value), `shrinks`, `replay`
214
+ - **`PropertyExhausted`**: `property`, `discards`, `budget` (`{ runs, maxDiscards }`, `maxDiscards` null when uncapped), `replay` — the generator discarded too many draws, so the property was never evaluated; it is not a refutation and records nothing to the seed store
215
+ - **`NonBooleanVerdict`**: `property`, `drawn` (rendered, value), `returned` (array of kinds), `replay`
216
+ - **`CoverageBelowMinimum`**: `property`, `classes` (array of {label, hits, runs, minimum}), `replay`
217
+ - **`SelfModelLaw`**: `law`, `site` — the law compared the subject to itself
218
+ - **`SeedStoreUnreadable`**: `file`, `line`, `detail` — a seed store file's line could not be decoded
219
+ - **`ReplayUnreadable`**: `text` — `CONFORMANCE_REPLAY` names neither the kernel's `seed=…;path=…` nor a property entry
220
+ - **`ReplayNoLongerReproduces`**: `property`, `replay` — a `CONFORMANCE_REPLAY` replay no longer reproduces its recorded failure
177
221
 
178
- `sorting is ordered` alone is vacuous, because a constant empty array is also ordered. A law that pins the output to an input refutes the impostor for that subject:
222
+ A reporter receives every field on the raw error, so a script or agent narrows by `_tag` and reads the fields directly without parsing messages:
179
223
 
180
224
  ```ts
181
- it.law.model('agree with insertion sort', { of: [S.Array(S.Int)], subject: sort }, insertionSort)
225
+ if (error._tag === 'VacuousProperty') {
226
+ for (const subject of error.subjects) {
227
+ for (const run of subject.properties) {
228
+ console.log(run.property.name, run.frozen._tag, run.property.seed)
229
+ }
230
+ }
231
+ }
232
+ ```
233
+
234
+ ### Seeds and the seed store
235
+
236
+ A provided budget asks for derandomized runs by carrying a `seed`. Each property then gets its own stable seed derived from that seed and its identity, so different properties draw different inputs and the same property draws the same inputs in every process and on every machine:
237
+
238
+ ```ts
239
+ // vitest.config.ts
240
+ export default defineConfig({
241
+ test: { provide: { '@systemfsoftware/vitest:property-check': { runs: 30, seed: 1 } } },
242
+ })
182
243
  ```
183
244
 
245
+ **Seed precedence**: a property's own `arbitrary: { seed: 7 }` wins over a provided seed. With a provided `seed`, the engine hashes it (FNV-1a) with the property's identity — its package, its file relative to the Vitest project root, and its full test name. With neither, each property draws from a fresh random seed. Every failure reports the seed it ran with.
246
+
247
+ **Migration**: code that relied on a provided seed making every property share one stream must set `arbitrary: { seed: <literal> }` on each property that needs a literal seed.
248
+
249
+ **The seed store and recording**: failing seeds are automatically saved to a checked-in JSON Lines file `__property_seeds__/<test file>.jsonl` beside the test file. Each line holds either:
250
+
251
+ - Refuted: `{ "_tag": "Refuted", "property": "full test name", "seed": 42, "attempt": 5, "size": 3, "path": [0,1], "failure": "ReturnedFalse" }`
252
+ - NonBoolean: `{ "_tag": "NonBoolean", "property": "full test name", "seed": 42, "runs": 100 }`
253
+
254
+ Recorded seeds replay before novel draws on every run, whatever the budget. Only a refuted or non-boolean failure writes, and only in a run that is not derandomized and does not set `record: false`; the shared config sets `record: false` in CI and in Stryker workers. Commit seed store updates like snapshot files.
255
+
256
+ **Stale seeds**: a recorded seed-store refutation whose draw now passes no longer fails the property; the property's novel draws decide it, and the stale line can be deleted. A recorded draw that still fails but whose recorded shrink steps no longer replay (the generator's shrinking or the failure's kind changed) refutes the property with that draw, unshrunk, as its counterexample. An explicit `CONFORMANCE_REPLAY` replay that no longer reproduces its failure fails with `ReplayNoLongerReproduces` — the stored seed-store path is the one that passes.
257
+
258
+ **Generator changes**: if a property's generator changes, its recorded seeds may no longer produce their old counterexamples, so the failure stops reproducing. Cases that must always run belong in the test source itself, not in the seed store.
259
+
260
+ **The `record` option**: `{ runs: 30, record: false }` opts out of writing seeds for a run; the engine still reads and replays existing seeds.
261
+
184
262
  ### Law kinds
185
263
 
186
264
  `it.law.model` (an independent oracle), `it.law.metamorphic` (the input transform), `it.law.roundTrip` (the encode/decode pair) and `it.law.invariant` (a predicate on the output) are sugar over the same gate.
@@ -128,7 +128,7 @@ type Assertion<A> = V.Assertion<void, A>;
128
128
  /** @internal */
129
129
  type MakeAssertion = <A>(actual: A, message?: string) => Assertion<A>;
130
130
  /** @internal */
131
- type Judgement = (make: MakeAssertion) => void;
131
+ type Judgement = (make: MakeAssertion) => Opaque;
132
132
  /**
133
133
  * The service a check needs. `judge` counts the check and throws {@link refusePiecewise} when a check already ran
134
134
  * since the last {@link AssertedShape.step}; `step` opens a new observed state.
@@ -136,7 +136,7 @@ type Judgement = (make: MakeAssertion) => void;
136
136
  * @internal
137
137
  */
138
138
  interface AssertedShape {
139
- readonly judge: (judgement: Judgement) => void;
139
+ readonly judge: (judgement: Judgement) => Opaque;
140
140
  readonly step: () => void;
141
141
  }
142
142
  declare const Asserted_base: Context.ServiceClass<Asserted, "@systemfsoftware/vitest/Asserted", AssertedShape>;
@@ -0,0 +1,464 @@
1
+
2
+ import * as Cause from "effect/Cause";
3
+ import * as Effect$1 from "effect/Effect";
4
+ import * as Schema$1 from "effect/Schema";
5
+ import * as Tracer from "effect/Tracer";
6
+ import { Schema } from "effect";
7
+ import * as Arbitrary from "effect/Arbitrary";
8
+ //#region src/internal/errors.schema.d.ts
9
+ /**
10
+ * The contract rules a rendered failure record can break (R10, KTD7).
11
+ *
12
+ * @internal
13
+ */
14
+ declare const Breach: Schema.Literals<readonly ["R1", "R2", "R6"]>;
15
+ /** @internal */
16
+ type Breach = typeof Breach.Type;
17
+ //#endregion
18
+ //#region src/internal/property/error.schema.d.ts
19
+ /**
20
+ * One witness: the text the renderer prints for a value, and a JSON-safe projection of the same traversal (R3, KD7).
21
+ *
22
+ * @internal
23
+ */
24
+ declare const Witness: Schema.Struct<{
25
+ readonly rendered: Schema.String;
26
+ readonly value: Schema.Codec<Schema.Json, Schema.Json, never, never>;
27
+ }>;
28
+ /** @internal */
29
+ type Witness = typeof Witness.Type;
30
+ declare const PropertyRefuted_base: Schema.Class<PropertyRefuted, Schema.TaggedStruct<"PropertyRefuted", {
31
+ readonly property: Schema.Struct<{
32
+ readonly name: Schema.String;
33
+ readonly site: Schema.NullOr<Schema.String>;
34
+ readonly seed: Schema.brand<Schema.Int, "PropertySeed">;
35
+ readonly runs: Schema.brand<Schema.Int, "PropertyRunCount">;
36
+ }>;
37
+ readonly counterexample: Schema.Struct<{
38
+ readonly rendered: Schema.String;
39
+ readonly value: Schema.Codec<Schema.Json, Schema.Json, never, never>;
40
+ }>;
41
+ readonly shrinks: Schema.brand<Schema.Int, "PropertyShrinkCount">;
42
+ readonly replay: Schema.String;
43
+ }>, import("effect/Cause").YieldableError & {
44
+ readonly brand: unique symbol;
45
+ }>;
46
+ /**
47
+ * A falsified property: the property that ran, the shrunk counterexample the generator settled on, and how many
48
+ * shrink steps it took to reach it (R2-R4).
49
+ *
50
+ * @internal
51
+ */
52
+ declare class PropertyRefuted extends PropertyRefuted_base {
53
+ get message(): string;
54
+ }
55
+ declare const PropertyExhausted_base: Schema.Class<PropertyExhausted, Schema.TaggedStruct<"PropertyExhausted", {
56
+ readonly property: Schema.Struct<{
57
+ readonly name: Schema.String;
58
+ readonly site: Schema.NullOr<Schema.String>;
59
+ readonly seed: Schema.brand<Schema.Int, "PropertySeed">;
60
+ readonly runs: Schema.brand<Schema.Int, "PropertyRunCount">;
61
+ }>;
62
+ readonly discards: Schema.brand<Schema.Int, "PropertyRunCount">;
63
+ readonly budget: Schema.Struct<{
64
+ readonly runs: Schema.brand<Schema.Int, "PropertyRunCount">;
65
+ readonly maxDiscards: Schema.NullOr<Schema.brand<Schema.Int, "PropertyRunCount">>;
66
+ }>;
67
+ readonly replay: Schema.String;
68
+ }>, import("effect/Cause").YieldableError & {
69
+ readonly brand: unique symbol;
70
+ }>;
71
+ /** @internal */
72
+ declare class PropertyExhausted extends PropertyExhausted_base {
73
+ get message(): string;
74
+ }
75
+ declare const NonBooleanVerdict_base: Schema.Class<NonBooleanVerdict, Schema.TaggedStruct<"NonBooleanVerdict", {
76
+ readonly property: Schema.Struct<{
77
+ readonly name: Schema.String;
78
+ readonly site: Schema.NullOr<Schema.String>;
79
+ readonly seed: Schema.brand<Schema.Int, "PropertySeed">;
80
+ readonly runs: Schema.brand<Schema.Int, "PropertyRunCount">;
81
+ }>;
82
+ readonly drawn: Schema.Struct<{
83
+ readonly rendered: Schema.String;
84
+ readonly value: Schema.Codec<Schema.Json, Schema.Json, never, never>;
85
+ }>;
86
+ readonly returned: Schema.$Array<Schema.Literals<readonly ["undefined", "object", "boolean", "number", "bigint", "string", "symbol", "function", "effect"]>>;
87
+ readonly replay: Schema.String;
88
+ }>, import("effect/Cause").YieldableError & {
89
+ readonly brand: unique symbol;
90
+ }>;
91
+ /**
92
+ * A verdict that was not a literal boolean: the property that ran, the first drawn values whose verdict was not a
93
+ * boolean, and every kind of value the property returned (R4).
94
+ *
95
+ * @internal
96
+ */
97
+ declare class NonBooleanVerdict extends NonBooleanVerdict_base {
98
+ get message(): string;
99
+ }
100
+ declare const CoverageBelowMinimum_base: Schema.Class<CoverageBelowMinimum, Schema.TaggedStruct<"CoverageBelowMinimum", {
101
+ readonly property: Schema.Struct<{
102
+ readonly name: Schema.String;
103
+ readonly site: Schema.NullOr<Schema.String>;
104
+ readonly seed: Schema.brand<Schema.Int, "PropertySeed">;
105
+ readonly runs: Schema.brand<Schema.Int, "PropertyRunCount">;
106
+ }>;
107
+ readonly classes: Schema.$Array<Schema.Struct<{
108
+ readonly label: Schema.String;
109
+ readonly hits: Schema.Int;
110
+ readonly runs: Schema.Int;
111
+ readonly minimum: Schema.Finite;
112
+ }>>;
113
+ readonly replay: Schema.String;
114
+ }>, import("effect/Cause").YieldableError & {
115
+ readonly brand: unique symbol;
116
+ }>;
117
+ /**
118
+ * A property whose declared coverage classes stayed under their minima: the property and the failed classes, in
119
+ * declaration order (R7).
120
+ *
121
+ * @internal
122
+ */
123
+ declare class CoverageBelowMinimum extends CoverageBelowMinimum_base {
124
+ get message(): string;
125
+ }
126
+ declare const SelfModelLaw_base: Schema.Class<SelfModelLaw, Schema.TaggedStruct<"SelfModelLaw", {
127
+ readonly law: Schema.String;
128
+ readonly site: Schema.NullOr<Schema.String>;
129
+ }>, import("effect/Cause").YieldableError & {
130
+ readonly brand: unique symbol;
131
+ }>;
132
+ /**
133
+ * A model law given the subject itself as its oracle, so it compares nothing (R13).
134
+ *
135
+ * @internal
136
+ */
137
+ declare class SelfModelLaw extends SelfModelLaw_base {
138
+ get message(): string;
139
+ }
140
+ declare const SeedStoreUnreadable_base: Schema.Class<SeedStoreUnreadable, Schema.TaggedStruct<"SeedStoreUnreadable", {
141
+ readonly file: Schema.String;
142
+ readonly line: Schema.Int;
143
+ readonly detail: Schema.String;
144
+ }>, import("effect/Cause").YieldableError & {
145
+ readonly brand: unique symbol;
146
+ }>;
147
+ /**
148
+ * A seed-store line that could not be decoded (R16, KTD6).
149
+ *
150
+ * @internal
151
+ */
152
+ declare class SeedStoreUnreadable extends SeedStoreUnreadable_base {
153
+ get message(): string;
154
+ }
155
+ declare const VacuousProperty_base: Schema.Class<VacuousProperty, Schema.TaggedStruct<"VacuousProperty", {
156
+ readonly subjects: Schema.$Array<Schema.Struct<{
157
+ readonly label: Schema.String;
158
+ readonly properties: Schema.$Array<Schema.Struct<{
159
+ readonly property: Schema.Struct<{
160
+ readonly name: Schema.String;
161
+ readonly site: Schema.NullOr<Schema.String>;
162
+ readonly seed: Schema.brand<Schema.Int, "PropertySeed">;
163
+ readonly runs: Schema.brand<Schema.Int, "PropertyRunCount">;
164
+ }>;
165
+ readonly frozen: Schema.Union<readonly [Schema.TaggedStruct<"Frozen", {
166
+ readonly outputs: Schema.$Array<Schema.Struct<{
167
+ readonly member: Schema.String;
168
+ readonly output: Schema.Struct<{
169
+ readonly rendered: Schema.String;
170
+ readonly value: Schema.Codec<Schema.Json, Schema.Json, never, never>;
171
+ }>;
172
+ }>>;
173
+ }>, Schema.TaggedStruct<"NeverCalled", {}>]>;
174
+ }>>;
175
+ }>>;
176
+ readonly exempt: Schema.$Array<Schema.Struct<{
177
+ readonly name: Schema.String;
178
+ readonly kind: Schema.String;
179
+ }>>;
180
+ readonly replay: Schema.String;
181
+ }>, import("effect/Cause").YieldableError & {
182
+ readonly brand: unique symbol;
183
+ }>;
184
+ /**
185
+ * Thrown at file end when no property in the file refuted a subject's constant impostor (R12, R5, R6).
186
+ *
187
+ * @internal
188
+ */
189
+ declare class VacuousProperty extends VacuousProperty_base {
190
+ get message(): string;
191
+ }
192
+ declare const ReplayUnreadable_base: Schema.Class<ReplayUnreadable, Schema.TaggedStruct<"ReplayUnreadable", {
193
+ readonly text: Schema.String;
194
+ }>, import("effect/Cause").YieldableError & {
195
+ readonly brand: unique symbol;
196
+ }>;
197
+ /** @internal */
198
+ declare class ReplayUnreadable extends ReplayUnreadable_base {
199
+ get message(): string;
200
+ }
201
+ declare const ReplayNoLongerReproduces_base: Schema.Class<ReplayNoLongerReproduces, Schema.TaggedStruct<"ReplayNoLongerReproduces", {
202
+ readonly property: Schema.Struct<{
203
+ readonly name: Schema.String;
204
+ readonly site: Schema.NullOr<Schema.String>;
205
+ readonly seed: Schema.brand<Schema.Int, "PropertySeed">;
206
+ readonly runs: Schema.brand<Schema.Int, "PropertyRunCount">;
207
+ }>;
208
+ readonly replay: Schema.String;
209
+ }>, import("effect/Cause").YieldableError & {
210
+ readonly brand: unique symbol;
211
+ }>;
212
+ /**
213
+ * An explicit `CONFORMANCE_REPLAY` replay whose recorded failure no longer reproduces: after the root re-check,
214
+ * the replay still mismatched, so no draw reproduces the failure the text names. The recorded seed-store path is
215
+ * not this — there the entry is one candidate among the novel draws, and only a draw that still fails refutes.
216
+ *
217
+ * @internal
218
+ */
219
+ declare class ReplayNoLongerReproduces extends ReplayNoLongerReproduces_base {
220
+ get message(): string;
221
+ }
222
+ //#endregion
223
+ //#region src/internal/failure-record.d.ts
224
+ /** A value the renderer narrows rather than assumes. */
225
+ type Opaque$1<A = unknown> = A;
226
+ /**
227
+ * A value a recorded span attribute or a replay path carries. Structured values stay structured on the span
228
+ * (KTD2); the renderer decides the text.
229
+ *
230
+ * @internal
231
+ */
232
+ type AttributeValue = string | number | boolean | null | ReadonlyArray<AttributeValue> | {
233
+ readonly [key: string]: AttributeValue;
234
+ };
235
+ /**
236
+ * The test a failure happened in, as Vitest knows it. `file` is the path the rerun command names, so a caller
237
+ * that holds an absolute path derives the repo-relative one before handing it over.
238
+ *
239
+ * @internal
240
+ */
241
+ interface TestIdentity {
242
+ /**
243
+ * The npm package the test file belongs to, e.g. `@systemfsoftware/effect-readiness`. Empty when the run
244
+ * provided no name: the rerun command then drops its `pnpm --filter` prefix and runs from the package
245
+ * directory, which is not a breach (R6).
246
+ */
247
+ readonly package: string;
248
+ /** The test file, as the rerun command writes it. */
249
+ readonly file: string;
250
+ /** The scenario name the rerun command filters on with `-t`. */
251
+ readonly name: string;
252
+ }
253
+ /**
254
+ * The value a generator chose a run by: the kernel's seed and decision path, or a property counterexample's
255
+ * seed and path. A path without a seed is a replay value offered for a baseline run, which R6 refuses (KTD5).
256
+ *
257
+ * @internal
258
+ */
259
+ interface ReplayValue {
260
+ /** The generator's seed, or `undefined` when only a path was recorded. */
261
+ readonly seed: number | undefined;
262
+ /** The decisions the generator chose, in order; a decision is the index the scheduler picked (KTD5). */
263
+ readonly path: ReadonlyArray<number>;
264
+ }
265
+ /**
266
+ * A contract rule a rendered record breaks; the runner refuses such a record (R10, KTD7).
267
+ *
268
+ * @internal
269
+ */
270
+ /**
271
+ * What a rendered failure gives Vitest: the tag the error carries, the record text, and the rules it breaks.
272
+ *
273
+ * @internal
274
+ */
275
+ interface FailureRecord {
276
+ /** The headline's failure tag, e.g. `StepError`; the runner sets it as the thrown error's `name`. */
277
+ readonly name: string;
278
+ /** The text Vitest prints as the failure's message. */
279
+ readonly record: string;
280
+ /** The contract rules the record breaks: `R1` empty headline, `R2` no location, `R6` replay or rerun. */
281
+ readonly breaches: ReadonlyArray<Breach>;
282
+ /**
283
+ * The raised failure itself when it is one of the property-channel variants, so an in-process corpus run reads
284
+ * its fields without parsing the record text (R1, R2). Absent for every other failure.
285
+ */
286
+ readonly failure?: Opaque$1;
287
+ }
288
+ /**
289
+ * Everything one failure is rendered from: the failure, its run's spans, the test and the replay value.
290
+ *
291
+ * @internal
292
+ */
293
+ interface FailureRecordInput<E = never> {
294
+ /** The failure itself: a `Cause`, or the value a program threw or failed with. */
295
+ readonly failure: Cause.Cause<E> | E;
296
+ /** Every span the failing run recorded, in creation order. */
297
+ readonly spans: ReadonlyArray<Tracer.NativeSpan>;
298
+ /** The test the run belonged to. */
299
+ readonly identity: TestIdentity;
300
+ /** The generator that chose this run, or `undefined` on a run no generator chose. */
301
+ readonly replay: ReplayValue | undefined;
302
+ /**
303
+ * The seed the kernel's scheduler chose. The kernel knows its own scheduler, so it hands the note over rather
304
+ * than the renderer guessing it; a run no scheduler chose renders no note (KTD5).
305
+ */
306
+ readonly schedule?: {
307
+ readonly seed: number;
308
+ } | undefined;
309
+ /**
310
+ * The workspace root the rendered paths are relativized against, provided by the shared config the same way the
311
+ * package name is. Omitted, paths print absolute.
312
+ */
313
+ readonly root?: string | undefined;
314
+ }
315
+ /**
316
+ * A value `JSON.stringify` carries: the projection a witness travels to a consumer as (R3, KD7).
317
+ *
318
+ * @internal
319
+ */
320
+ type JsonValue = Schema$1.Json;
321
+ /**
322
+ * The one traversal a value's rendered text and its JSON projection come from (R3, KD7): `rendered` is exactly
323
+ * `renderValue`'s text, `value` is the same walk with every value JSON cannot carry marked by kind, and a cycle
324
+ * marks `circular` rather than recursing forever.
325
+ *
326
+ * @internal
327
+ */
328
+ declare const witnessOf: (value: Opaque$1) => Witness;
329
+ /** @internal */
330
+ declare const summaryOf: (value: Opaque$1) => string;
331
+ /**
332
+ * Renders the record Vitest prints for one spec failure, and the contract rules it breaks.
333
+ *
334
+ * Never throws: a `Cause` renders layer by layer, a thrown `Error` renders as one layer, and any other value
335
+ * renders as itself. The first location the record names is the raising frame — the first stack frame outside
336
+ * `node_modules` and outside the spec libraries' own `src/` and `dist/` — and when no layer has one, the
337
+ * innermost failed span's site stands in, or the innermost unfinished cell's decide site for a deadlock (KTD6).
338
+ *
339
+ * @internal
340
+ */
341
+ declare const renderFailureRecord: <E>(input: FailureRecordInput<E>) => FailureRecord;
342
+ /** @internal */
343
+ declare const throwFailureRecord: <E>(input: FailureRecordInput<E>) => never;
344
+ interface TaskLike {
345
+ readonly name?: string | undefined;
346
+ readonly fullName?: string | undefined;
347
+ readonly fullTestName?: string | undefined;
348
+ }
349
+ /** @internal */
350
+ declare const testIdentityOf: (task?: TaskLike | null) => TestIdentity;
351
+ //#endregion
352
+ //#region src/internal/property/defaults.d.ts
353
+ /** @internal The `test.provide` key the shared config fills with this run's tier's check options. */
354
+ declare const checkDefaultsKey = "@systemfsoftware/vitest:property-check";
355
+ /**
356
+ * The check options a run supplies as its property default, minus `replay`. `record` asks the engine to write a
357
+ * failing seed to the checked-in seed store, which it does unless a run opts out.
358
+ *
359
+ * @internal
360
+ */
361
+ interface PropertyBudget extends Omit<Arbitrary.CheckOptions, 'replay'> {
362
+ /** Write failing seeds to the seed store; default true. A derandomized run never writes regardless. */
363
+ readonly record?: boolean | undefined;
364
+ }
365
+ /** @internal The check options a run supplies as its property default (KTD4). */
366
+ type ProvidedCheckDefaults = PropertyBudget;
367
+ //#endregion
368
+ //#region src/internal/property/impostor.d.ts
369
+ /**
370
+ * A value the fork hands over without inspecting: an argument to the subject, or one of its outputs.
371
+ *
372
+ * @internal
373
+ */
374
+ type Opaque<A = unknown> = A;
375
+ /**
376
+ * A function under test: any argument, any output.
377
+ *
378
+ * @internal
379
+ */
380
+ type SubjectFunction = (...values: ReadonlyArray<never>) => Opaque;
381
+ /**
382
+ * A record of functions under test; every member is replaced by a constant.
383
+ *
384
+ * @internal
385
+ */
386
+ type MemberRecord = {
387
+ readonly [key: string]: SubjectFunction;
388
+ };
389
+ /**
390
+ * The function under test, or a record of them.
391
+ *
392
+ * @internal
393
+ */
394
+ type Subject = SubjectFunction | MemberRecord;
395
+ //#endregion
396
+ //#region src/internal/property/kinds.d.ts
397
+ /**
398
+ * A subject of a law kind: a function of the generated values.
399
+ *
400
+ * @internal
401
+ */
402
+ type LawSubject<G extends Gens, A> = (...values: ReadonlyArray<ElementValues<G>>) => A;
403
+ /**
404
+ * A metamorphic relation: the input transform, and how the two outputs relate (structural equality by default).
405
+ *
406
+ * @internal
407
+ */
408
+ interface MetamorphicRelation<G extends Gens, A> {
409
+ readonly transform: (...values: ReadonlyArray<ElementValues<G>>) => Values<G>;
410
+ readonly relate?: (original: A, transformed: A) => boolean;
411
+ }
412
+ /**
413
+ * The R13 law surface: four gated kinds and two declared exemptions.
414
+ *
415
+ * @internal
416
+ */
417
+ interface LawApi {
418
+ readonly model: <const G extends Gens, A, N extends number, S extends LawSubject<G, A>>(name: string, spec: PropertySpec<G, S, N>, oracle: LawSubject<G, A>) => void;
419
+ readonly metamorphic: <const G extends Gens, A, N extends number, S extends LawSubject<G, A>>(name: string, spec: PropertySpec<G, S, N>, relation: MetamorphicRelation<G, A>) => void;
420
+ readonly roundTrip: <const G extends Gens, E, N extends number, S extends LawSubject<G, E>>(name: string, spec: PropertySpec<G, S, N>, decode: (encoded: E) => Values<G>) => void;
421
+ readonly invariant: <const G extends Gens, A, N extends number, S extends LawSubject<G, A>>(name: string, spec: PropertySpec<G, S, N>, holds: (output: A, ...values: ReadonlyArray<ElementValues<G>>) => boolean) => void;
422
+ readonly idempotent: <const G extends Gens, N extends number, S extends (value: ElementValues<G>) => ElementValues<G>>(name: string, spec: PropertySpec<G, S, N>) => void;
423
+ readonly deterministic: <const G extends Gens, A, N extends number, S extends LawSubject<G, A>>(name: string, spec: PropertySpec<G, S, N>) => void;
424
+ }
425
+ //#endregion
426
+ //#region src/internal/property/engine.d.ts
427
+ /** @internal */
428
+ type ArbitraryInput = Schema$1.Top | Arbitrary.Arbitrary<Schema$1.Top['Type']>;
429
+ /** @internal */
430
+ type Gens = ReadonlyArray<ArbitraryInput> | {
431
+ readonly [key: string]: ArbitraryInput;
432
+ };
433
+ type Generated<I> = I extends Schema$1.Schema<infer T> ? T : I extends Arbitrary.Arbitrary<infer A> ? A : never;
434
+ /** @internal */
435
+ type Values<G extends Gens> = { readonly [K in keyof G]: Generated<G[K]>; };
436
+ /** @internal */
437
+ type ElementValues<G extends Gens> = G extends ReadonlyArray<ArbitraryInput> ? Generated<G[number]> : never;
438
+ /** @internal */
439
+ type PropertySubject = Subject;
440
+ /** @internal */
441
+ type CoveragePredicate<G extends Gens> = (...values: ReadonlyArray<ElementValues<G>>) => boolean;
442
+ type PropertyRuns<N extends number> = number extends N ? number : `${N}` extends `-${bigint}` ? never : `${N}` extends `${bigint}` ? (N extends 0 ? never : N) : never;
443
+ /** @internal */
444
+ interface PropertySpec<G extends Gens, S extends PropertySubject, N extends number> {
445
+ readonly of: G;
446
+ readonly subject: S;
447
+ /**
448
+ * The property's own run count. Omitted, the configured default applies; when the run provides none,
449
+ * the built-in default of 100 does.
450
+ */
451
+ readonly runs?: N & PropertyRuns<N>;
452
+ /** Labelled input predicates, each with the minimum share of runs it must see (R14). */
453
+ readonly cover?: Readonly<Record<string, readonly [CoveragePredicate<G>, number]>>;
454
+ /** The property's own check options, merged field by field over the provided and built-in defaults. */
455
+ readonly arbitrary?: Arbitrary.CheckOptions;
456
+ }
457
+ /** @internal */
458
+ interface PropApi<R> {
459
+ readonly prop: <const G extends Gens, S extends PropertySubject, N extends number>(name: string, spec: PropertySpec<G, S, N>, holds: (subject: S, values: Values<G>) => boolean) => void;
460
+ readonly effectProp: <const G extends Gens, S extends PropertySubject, N extends number, E>(name: string, spec: PropertySpec<G, S, N>, holds: (subject: S, values: Values<G>) => Effect$1.Effect<boolean, E, R>) => void;
461
+ readonly law: LawApi;
462
+ }
463
+ //#endregion
464
+ export { VacuousProperty as A, NonBooleanVerdict as C, ReplayUnreadable as D, ReplayNoLongerReproduces as E, Breach as M, SeedStoreUnreadable as O, CoverageBelowMinimum as S, PropertyRefuted as T, renderFailureRecord as _, PropertySubject as a, throwFailureRecord as b, PropertyBudget as c, AttributeValue as d, FailureRecord as f, TestIdentity as g, ReplayValue as h, PropertySpec as i, Witness as j, SelfModelLaw as k, ProvidedCheckDefaults as l, JsonValue as m, Gens as n, Values as o, FailureRecordInput as p, PropApi as r, LawApi as s, ArbitraryInput as t, checkDefaultsKey as u, summaryOf as v, PropertyExhausted as w, witnessOf as x, testIdentityOf as y };