@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.
@@ -1,11 +1,12 @@
1
1
 
2
- import { a as booleanRefusal, b as refusedText, c as negatedText, m as refusePiecewise, s as neededText, t as authorize, u as refusalOf } from "./guard-BocOhXt2.mjs";
2
+ import { a as booleanRefusal, b as refusedText, c as negatedText, m as refusePiecewise, s as neededText, t as authorize, u as refusalOf } from "./guard-Ci0TyBYv.mjs";
3
3
  import * as V from "vitest";
4
4
  import * as Effect from "effect/Effect";
5
5
  import * as Function from "effect/Function";
6
6
  import * as Schema from "effect/Schema";
7
7
  import * as Option from "effect/Option";
8
8
  import * as Context from "effect/Context";
9
+ import * as Predicate from "effect/Predicate";
9
10
  //#region src/internal/call-site.ts
10
11
  /**
11
12
  * The one rule that reads a frame out of a stack: which frame a failure is raised from, and which frame an author
@@ -126,10 +127,12 @@ const branded = /* @__PURE__ */ new WeakSet();
126
127
  const isObject = (value) => typeof value === "object" && value !== null;
127
128
  /** @internal */
128
129
  const isCheck = (value) => isObject(value) && branded.has(value);
130
+ const settled = (outcome) => Predicate.isPromiseLike(outcome) ? Effect.asVoid(Effect.promise(() => outcome)) : Effect.void;
129
131
  const makeCheck = (judgement, written) => {
130
132
  written(judgement);
131
133
  const check = Effect.gen(function* () {
132
- (yield* Asserted).judge(judgement);
134
+ const asserted = yield* Asserted;
135
+ yield* settled(asserted.judge(judgement));
133
136
  });
134
137
  branded.add(check);
135
138
  return check;
@@ -176,21 +179,22 @@ const memberAt = (target, property) => Reflect.get(target, property, target);
176
179
  const isCallable = (value) => typeof value === "function";
177
180
  const invokeMember = (target, property, args) => {
178
181
  const member = memberAt(target, property);
179
- if (isCallable(member)) Reflect.apply(member, target, args);
182
+ return isCallable(member) ? Reflect.apply(member, target, args) : void 0;
180
183
  };
181
184
  const judgedBy = (view, property, args, make) => {
182
185
  const assertion = make(view.actual, view.message);
183
186
  const target = view.negated ? assertion.not : assertion;
184
- invokeMember(target, property, args);
187
+ return invokeMember(target, property, args);
185
188
  };
186
189
  const raisedFailure = (thrown, site) => thrown instanceof Error ? withRaisingFrame(thrown, site) : thrown;
190
+ const framedOutcome = (outcome, site) => Predicate.isPromiseLike(outcome) ? outcome.then(void 0, (thrown) => Promise.reject(raisedFailure(thrown, site))) : outcome;
187
191
  /**
188
192
  * A failed judgement is a failure the fork raised: by now the stack holds only the fork's frames, so the site the
189
193
  * body called `expect` from is prepended to the error's stack (R2, KTD6).
190
194
  */
191
195
  const judgementOf = (view, property, args) => (make) => {
192
196
  try {
193
- judgedBy(view, property, args, make);
197
+ return framedOutcome(judgedBy(view, property, args, make), view.site);
194
198
  } catch (thrown) {
195
199
  throw raisedFailure(thrown, view.site);
196
200
  }
@@ -294,7 +298,7 @@ const makeLedger = (ctx) => {
294
298
  counter.judged += 1;
295
299
  counter.since += 1;
296
300
  if (counter.since > 1) throw refusalOf(refusePiecewise);
297
- authorize(() => judgement(hard));
301
+ return authorize(() => judgement(hard));
298
302
  },
299
303
  step: () => {
300
304
  counter.since = 0;
@@ -0,0 +1,36 @@
1
+
2
+ //#region src/internal/property/tiers.ts
3
+ const RUNS = {
4
+ mutation: 30,
5
+ ci: 1e3,
6
+ local: 100
7
+ };
8
+ const CI_OFF_VALUES = [
9
+ void 0,
10
+ "",
11
+ "false",
12
+ "0"
13
+ ];
14
+ const isCi = (env) => env["AGENT"] === void 0 && !CI_OFF_VALUES.includes(env["CI"]);
15
+ const isMutationWorker = (env) => env["STRYKER_MUTATOR_WORKER"] !== void 0;
16
+ const ciOrLocal = (env) => isCi(env) ? "ci" : "local";
17
+ /** @internal A Stryker worker wants fast mutant runs; CI wants the thorough tier; everything else is local. */
18
+ const tierOf = (env) => isMutationWorker(env) ? "mutation" : ciOrLocal(env);
19
+ /**
20
+ * @internal The check options direct `Arbitrary` checks use by default: `{ check: { runs } }` for the tier. A property
21
+ * test that passes its own `runs` still wins over this default.
22
+ */
23
+ const propertyTestDefaults = (env) => ({ check: { runs: RUNS[tierOf(env)] } });
24
+ /**
25
+ * @internal The property budget a run uses when it provides none: the tier's runs, and no seed-store writes in CI or a
26
+ * Stryker worker, where a checkout is discarded or a mutant run fails on purpose.
27
+ */
28
+ const providedBudgetOf = (env) => {
29
+ const tier = tierOf(env);
30
+ return tier === "local" ? { runs: RUNS.local } : {
31
+ runs: RUNS[tier],
32
+ record: false
33
+ };
34
+ };
35
+ //#endregion
36
+ export { providedBudgetOf as n, propertyTestDefaults as t };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@systemfsoftware/vitest",
3
3
  "license": "MIT",
4
- "version": "1.0.0",
4
+ "version": "4.1.1",
5
5
  "author": "Ryan Lee <drdgvhbh@gmail.com>",
6
6
  "repository": {
7
7
  "type": "git",
@@ -37,6 +37,10 @@
37
37
  "types": "./dist/integration.d.ts",
38
38
  "default": "./dist/integration.mjs"
39
39
  },
40
+ "./property-defaults": {
41
+ "types": "./dist/property-defaults.d.ts",
42
+ "default": "./dist/property-defaults.mjs"
43
+ },
40
44
  "./TestClock": {
41
45
  "types": "./dist/TestClock.d.ts",
42
46
  "default": "./dist/TestClock.mjs"
@@ -46,30 +50,26 @@
46
50
  "files": [
47
51
  "dist"
48
52
  ],
53
+ "dependencies": {
54
+ "@effect/platform-node": "^4.1.2"
55
+ },
49
56
  "devDependencies": {
50
57
  "@systemfsoftware/arethetypeswrong-cli": "^4.2.0",
51
- "@systemfsoftware/oxlint-config-recommended": "^4.0.0",
52
- "@systemfsoftware/stryker-config": "^0.1.0",
53
- "@systemfsoftware/stryker-ignorer-effect-schema-declarations": "latest",
54
- "@systemfsoftware/stryker-ignorer-in-source-vitest-block": "latest",
55
- "@systemfsoftware/stryker-js": "latest",
56
- "@systemfsoftware/stryker-js-typescript-checker": "latest",
57
- "@systemfsoftware/stryker-js-vitest-runner": "latest",
58
- "@systemfsoftware/stryker-test-contribution": "latest",
59
- "@systemfsoftware/tsconfig": "^2.0.1",
60
- "@systemfsoftware/tsdown-config": "^0.1.0",
61
- "@systemfsoftware/vitest-config": "^0.1.0",
62
- "@types/node": "^26",
63
- "effect": "^4",
64
- "oxlint": "~1.82.0",
58
+ "@systemfsoftware/oxlint-config-recommended": "^6.0.1",
59
+ "@systemfsoftware/tsconfig": "^2.1.0",
60
+ "@systemfsoftware/tsdown-config": "^0.1.2",
61
+ "@systemfsoftware/vitest-config": "^0.1.3",
62
+ "@types/node": "^26.6.5",
63
+ "effect": "^4.1.2",
64
+ "oxlint": "~1.89.0",
65
65
  "rimraf": "^6.1.3",
66
66
  "tsdown": "^0.23.0",
67
67
  "tstyche": "^7.2.5",
68
- "vitest": "^5"
68
+ "vitest": "^5.1.0"
69
69
  },
70
70
  "peerDependencies": {
71
- "effect": "^4",
72
- "vitest": "^5"
71
+ "effect": "^4.1.2",
72
+ "vitest": "^5.1.0"
73
73
  },
74
74
  "publishConfig": {
75
75
  "access": "public",
@@ -80,7 +80,6 @@
80
80
  "build": "tsdown -l warn",
81
81
  "typecheck": "tsc -b",
82
82
  "test": "vitest run",
83
- "mutation": "stryker run",
84
83
  "test:types": "TSTYCHE_TYPESCRIPT_MODULE=tstyche-typescript tstyche",
85
84
  "lint": "f=${OXLINT_FORMAT:-${AGENT:+agent}}; oxlint . --format=${f:-default}",
86
85
  "attw": "attw --pack ."
@@ -1,166 +0,0 @@
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/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 };