@systemfsoftware/vitest 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/engine-ZbxyPNiN.d.ts +166 -0
- package/dist/failure-DC_SJoxW.mjs +1293 -0
- package/dist/failure.d.ts +204 -0
- package/dist/failure.mjs +4 -0
- package/dist/index.d.ts +3 -154
- package/dist/index.mjs +56 -529
- package/dist/integration.mjs +1 -1
- package/dist/{test-context-hvSoKLtw.mjs → test-context-D_-acRSc.mjs} +122 -5
- package/package.json +17 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @systemfsoftware/vitest
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- `@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`.
|
|
8
|
+
|
|
9
|
+
## 0.2.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 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.
|
|
14
|
+
|
|
15
|
+
- `@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`.
|
|
16
|
+
|
|
17
|
+
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.
|
|
18
|
+
|
|
19
|
+
- 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.
|
|
20
|
+
|
|
21
|
+
- 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.
|
|
22
|
+
|
|
23
|
+
`@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.
|
|
24
|
+
|
|
25
|
+
`@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.
|
|
26
|
+
|
|
3
27
|
## 0.1.0
|
|
4
28
|
|
|
5
29
|
### Minor Changes
|
|
@@ -0,0 +1,166 @@
|
|
|
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 { Schema } from "effect";
|
|
6
|
+
import * as Arbitrary from "effect/unstable/arbitrary/Arbitrary";
|
|
7
|
+
//#endregion
|
|
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
|
+
declare const NonBooleanVerdict_base: Schema.Class<NonBooleanVerdict, Schema.TaggedStruct<"NonBooleanVerdict", {
|
|
18
|
+
readonly detail: Schema.String;
|
|
19
|
+
}>, import("effect/Cause").YieldableError>;
|
|
20
|
+
/** @internal */
|
|
21
|
+
declare class NonBooleanVerdict extends NonBooleanVerdict_base {
|
|
22
|
+
get message(): string;
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
//#region src/internal/property/impostor.d.ts
|
|
26
|
+
/**
|
|
27
|
+
* @internal The constant impostor of R12: a fake of the subject under test that
|
|
28
|
+
* returns the first output it ever produced, for every later call, whatever the
|
|
29
|
+
* input it was given.
|
|
30
|
+
*
|
|
31
|
+
* A property that still holds for the impostor does not constrain the subject.
|
|
32
|
+
* Whether that is fatal is a per-file question — a subject's impostor must be
|
|
33
|
+
* refuted by some property in its file — so this module builds the fake and
|
|
34
|
+
* collects the verdicts; the engine decides them once, when the file finishes
|
|
35
|
+
* (KTD10).
|
|
36
|
+
*/
|
|
37
|
+
/**
|
|
38
|
+
* A value the fork hands over without inspecting: an argument to the subject, or one of its outputs.
|
|
39
|
+
*
|
|
40
|
+
* @internal
|
|
41
|
+
*/
|
|
42
|
+
type Opaque<A = unknown> = A;
|
|
43
|
+
/**
|
|
44
|
+
* A function under test: any argument, any output.
|
|
45
|
+
*
|
|
46
|
+
* @internal
|
|
47
|
+
*/
|
|
48
|
+
type SubjectFunction = (...values: ReadonlyArray<never>) => Opaque;
|
|
49
|
+
/**
|
|
50
|
+
* A record of functions under test; every member is replaced by a constant.
|
|
51
|
+
*
|
|
52
|
+
* @internal
|
|
53
|
+
*/
|
|
54
|
+
type MemberRecord = {
|
|
55
|
+
readonly [key: string]: SubjectFunction;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* The function under test, or a record of them.
|
|
59
|
+
*
|
|
60
|
+
* @internal
|
|
61
|
+
*/
|
|
62
|
+
type Subject = SubjectFunction | MemberRecord;
|
|
63
|
+
declare namespace kinds_d_exports {
|
|
64
|
+
export { LawApi, LawKind, LawSubject, MetamorphicRelation, deterministicHolds, idempotentHolds, invariantHolds, metamorphicHolds, modelHolds, roundTripHolds, spreadValues };
|
|
65
|
+
}
|
|
66
|
+
/** @internal */
|
|
67
|
+
type LawKind = 'model' | 'metamorphic' | 'roundTrip' | 'invariant' | 'idempotent' | 'deterministic';
|
|
68
|
+
/**
|
|
69
|
+
* A subject of a law kind: a function of the generated values.
|
|
70
|
+
*
|
|
71
|
+
* @internal
|
|
72
|
+
*/
|
|
73
|
+
type LawSubject<G extends Gens, A> = (...values: ReadonlyArray<ElementValues<G>>) => A;
|
|
74
|
+
/**
|
|
75
|
+
* A metamorphic relation: the input transform, and how the two outputs relate (structural equality by default).
|
|
76
|
+
*
|
|
77
|
+
* @internal
|
|
78
|
+
*/
|
|
79
|
+
interface MetamorphicRelation<G extends Gens, A> {
|
|
80
|
+
readonly transform: (...values: ReadonlyArray<ElementValues<G>>) => Values<G>;
|
|
81
|
+
readonly relate?: (original: A, transformed: A) => boolean;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* The R13 law surface: four gated kinds and two declared exemptions.
|
|
85
|
+
*
|
|
86
|
+
* @internal
|
|
87
|
+
*/
|
|
88
|
+
interface LawApi {
|
|
89
|
+
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;
|
|
90
|
+
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;
|
|
91
|
+
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;
|
|
92
|
+
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;
|
|
93
|
+
readonly idempotent: <const G extends Gens, N extends number, S extends (value: ElementValues<G>) => ElementValues<G>>(name: string, spec: PropertySpec<G, S, N>) => void;
|
|
94
|
+
readonly deterministic: <const G extends Gens, A, N extends number, S extends LawSubject<G, A>>(name: string, spec: PropertySpec<G, S, N>) => void;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The generated values as the argument list a law subject is called with.
|
|
98
|
+
*
|
|
99
|
+
* @internal
|
|
100
|
+
*/
|
|
101
|
+
declare const spreadValues: <G extends Gens>(values: Values<G>) => ReadonlyArray<ElementValues<G>>;
|
|
102
|
+
/** @internal */
|
|
103
|
+
declare const modelHolds: <G extends Gens, A>(oracle: LawSubject<G, A>) => (subject: LawSubject<G, A>, values: Values<G>) => boolean;
|
|
104
|
+
/** @internal */
|
|
105
|
+
declare const metamorphicHolds: <G extends Gens, A>(relation: MetamorphicRelation<G, A>) => (subject: LawSubject<G, A>, values: Values<G>) => boolean;
|
|
106
|
+
/** @internal */
|
|
107
|
+
declare const roundTripHolds: <G extends Gens, E>(decode: (encoded: E) => Values<G>) => (subject: LawSubject<G, E>, values: Values<G>) => boolean;
|
|
108
|
+
/** @internal */
|
|
109
|
+
declare const invariantHolds: <G extends Gens, A>(holds: (output: A, ...values: ReadonlyArray<ElementValues<G>>) => boolean) => (subject: LawSubject<G, A>, values: Values<G>) => boolean;
|
|
110
|
+
/** @internal */
|
|
111
|
+
declare const idempotentHolds: <G extends Gens>() => (subject: (value: ElementValues<G>) => ElementValues<G>, values: Values<G>) => boolean;
|
|
112
|
+
/** @internal */
|
|
113
|
+
declare const deterministicHolds: <G extends Gens, A>() => (subject: LawSubject<G, A>, values: Values<G>) => boolean;
|
|
114
|
+
declare namespace engine_d_exports {
|
|
115
|
+
export { ArbitraryInput, CoveragePredicate, ElementValues, Gens, PropApi, PropertyRuntime, PropertySpec, PropertySubject, Values, makeProperty };
|
|
116
|
+
}
|
|
117
|
+
/** @internal */
|
|
118
|
+
type ArbitraryInput = Schema$1.Top | Arbitrary.Arbitrary<Schema$1.Top['Type']>;
|
|
119
|
+
/** @internal */
|
|
120
|
+
type Gens = ReadonlyArray<ArbitraryInput> | {
|
|
121
|
+
readonly [key: string]: ArbitraryInput;
|
|
122
|
+
};
|
|
123
|
+
type Generated<I> = I extends Schema$1.Schema<infer T> ? T : I extends Arbitrary.Arbitrary<infer A> ? A : never;
|
|
124
|
+
/** @internal */
|
|
125
|
+
type Values<G extends Gens> = { readonly [K in keyof G]: Generated<G[K]>; };
|
|
126
|
+
/** @internal */
|
|
127
|
+
type ElementValues<G extends Gens> = G extends ReadonlyArray<ArbitraryInput> ? Generated<G[number]> : never;
|
|
128
|
+
/** @internal */
|
|
129
|
+
type PropertySubject = Subject;
|
|
130
|
+
/** @internal */
|
|
131
|
+
type CoveragePredicate<G extends Gens> = (...values: ReadonlyArray<ElementValues<G>>) => boolean;
|
|
132
|
+
type PropertyRuns<N extends number> = number extends N ? number : `${N}` extends `-${bigint}` ? never : `${N}` extends `${bigint}` ? (N extends 0 ? never : N) : never;
|
|
133
|
+
/** @internal */
|
|
134
|
+
interface PropertySpec<G extends Gens, S extends PropertySubject, N extends number> {
|
|
135
|
+
readonly of: G;
|
|
136
|
+
readonly subject: S;
|
|
137
|
+
/**
|
|
138
|
+
* The property's own run count. Omitted, the configured default applies; when the run provides none,
|
|
139
|
+
* the built-in default of 100 does.
|
|
140
|
+
*/
|
|
141
|
+
readonly runs?: N & PropertyRuns<N>;
|
|
142
|
+
/** Labelled input predicates, each with the minimum share of runs it must see (R14). */
|
|
143
|
+
readonly cover?: Readonly<Record<string, readonly [CoveragePredicate<G>, number]>>;
|
|
144
|
+
/** The property's own check options, merged field by field over the provided and built-in defaults. */
|
|
145
|
+
readonly arbitrary?: Arbitrary.CheckOptions;
|
|
146
|
+
}
|
|
147
|
+
/** @internal */
|
|
148
|
+
interface PropertyRuntime<R> {
|
|
149
|
+
/** Registers the property's program; the runtime runs it inside the test it registers, under that test's binding. */
|
|
150
|
+
readonly register: (name: string, program: () => Effect$1.Effect<void, Cause.Cause<NonBooleanVerdict>, never>) => void;
|
|
151
|
+
readonly provide: <A, E>(effect: Effect$1.Effect<A, E, R>) => Effect$1.Effect<A, E, never>;
|
|
152
|
+
}
|
|
153
|
+
/** @internal */
|
|
154
|
+
interface PropApi<R> {
|
|
155
|
+
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;
|
|
156
|
+
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;
|
|
157
|
+
readonly law: LawApi;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* The property surface over one runtime: `prop`, `effectProp`, and the R13 law kinds routed through the gate.
|
|
161
|
+
*
|
|
162
|
+
* @internal
|
|
163
|
+
*/
|
|
164
|
+
declare const makeProperty: <R>(runtime: PropertyRuntime<R>) => PropApi<R>;
|
|
165
|
+
//#endregion
|
|
166
|
+
export { Values as a, kinds_d_exports as c, PropertySubject as i, Breach as l, Gens as n, engine_d_exports as o, PropertySpec as r, LawApi as s, ArbitraryInput as t, __exportAll as u };
|