@systemfsoftware/vitest 0.0.0 → 0.2.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.
@@ -0,0 +1,37 @@
1
+
2
+ import { a as Expect, n as AssertedShape, r as Check, t as Asserted } from "./checks-Cq9of-Lx.js";
3
+ import * as Effect from "effect/Effect";
4
+ //#region src/integration.d.ts
5
+ /**
6
+ * A flow that asserts more than once marks each assertion point with this, so the check after it is that
7
+ * state's one check (KTD5).
8
+ *
9
+ * @since 4.0.0
10
+ */
11
+ export declare const step: <A, E, R>(self: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R | Asserted>;
12
+ /**
13
+ * The test's run, as a library hands it to a runtime of its own: `bind` provides what a check reads off the
14
+ * test's own fiber — the ledger — so the checks the other runtime runs count as this test's assertions, and the
15
+ * bound effect no longer requires `Asserted`, which is what lets it cross into a runtime that cannot know it.
16
+ *
17
+ * A runtime of its own re-runs the bound effect — a kernel explores a baseline and then its seeded replays — and
18
+ * executing the bound effect opens a new observed state before it runs, so each execution is a run. `bind`
19
+ * resets nothing on its own: the step runs when the bound effect is executed. A runtime that re-runs a check
20
+ * without executing the bound effect has opened no state, so its second check is refused, as any two checks on
21
+ * one state are. One check per execution, and two checks inside one execution are still refused.
22
+ *
23
+ * @since 4.0.0
24
+ */
25
+ export interface RunBinding {
26
+ readonly bind: <A, E, R>(self: Effect.Effect<A, E, R | Asserted>) => Effect.Effect<A, E, R>;
27
+ }
28
+ /**
29
+ * The run binding of the test the caller is executing in: the ledger its checks count on, and the running task
30
+ * context. Capture it from inside a test — the capture requires `Asserted`, so a library cannot mistake a run
31
+ * binding for something the outside has — and bind the effect before handing it to a runtime of its own.
32
+ *
33
+ * @since 4.0.0
34
+ */
35
+ export declare const captureRunBinding: Effect.Effect<RunBinding, never, Asserted>;
36
+ //#endregion
37
+ export type { Asserted, AssertedShape, Check, Expect };
@@ -0,0 +1,38 @@
1
+
2
+ import { r as Asserted, t as VitestTestContext } from "./test-context-ChvjVyCo.mjs";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Option from "effect/Option";
5
+ //#region src/integration.ts
6
+ /**
7
+ * The integration entry (KTD5): the types a library writes its verdicts with, the marker it calls between the
8
+ * observations of one flow, and the binding it carries onto a runtime of its own.
9
+ *
10
+ * @since 4.0.0
11
+ */
12
+ /**
13
+ * A flow that asserts more than once marks each assertion point with this, so the check after it is that
14
+ * state's one check (KTD5).
15
+ *
16
+ * @since 4.0.0
17
+ */
18
+ const step = (self) => Effect.flatMap(Asserted, (asserted) => Effect.andThen(Effect.sync(() => asserted.step()), self));
19
+ const boundContext = (self, ctx) => Option.match(Option.fromNullishOr(ctx), {
20
+ onNone: () => self,
21
+ onSome: (value) => Effect.provideService(self, VitestTestContext, value)
22
+ });
23
+ const openedRun = (self, asserted) => Effect.andThen(Effect.sync(() => asserted.step()), self);
24
+ const bindingOf = (asserted, ctx) => ({ bind: (self) => boundContext(Effect.provideService(openedRun(self, asserted), Asserted, asserted), ctx) });
25
+ /**
26
+ * The run binding of the test the caller is executing in: the ledger its checks count on, and the running task
27
+ * context. Capture it from inside a test — the capture requires `Asserted`, so a library cannot mistake a run
28
+ * binding for something the outside has — and bind the effect before handing it to a runtime of its own.
29
+ *
30
+ * @since 4.0.0
31
+ */
32
+ const captureRunBinding = Effect.gen(function* () {
33
+ const asserted = yield* Asserted;
34
+ const ctx = Option.getOrUndefined(yield* Effect.serviceOption(VitestTestContext));
35
+ return bindingOf(asserted, ctx);
36
+ });
37
+ //#endregion
38
+ export { captureRunBinding, step };
@@ -0,0 +1,328 @@
1
+
2
+ import { a as booleanRefusal, c as negatedText, m as refusePiecewise, s as neededText, t as authorize, u as refusalOf, x as refusedText } from "./guard-p_8ARgPm.mjs";
3
+ import * as V from "vitest";
4
+ import * as Effect from "effect/Effect";
5
+ import * as Function from "effect/Function";
6
+ import * as Schema from "effect/Schema";
7
+ import * as Option from "effect/Option";
8
+ import * as Context from "effect/Context";
9
+ //#region src/internal/call-site.ts
10
+ /**
11
+ * The one rule that reads a frame out of a stack: which frame a failure is raised from, and which frame an author
12
+ * wrote the thing that raised it on (R2, KTD6).
13
+ *
14
+ * A deferred check and a declared property both fail inside the fork, where the stack holds only the fork's frames
15
+ * and the author's line is long gone. Each captures its call site while the author's frame is still on the stack
16
+ * and hands it to the failure as its first frame, so the renderer's R2 walk leads with the author's line.
17
+ *
18
+ * The rule is the same everywhere it applies: the first frame outside the vendored install, node internals, and
19
+ * every spec library's own `src` and `dist` — {@link LIBRARY_DIRS}. A caller may name its own extra frames with a
20
+ * {@link RegExp}, and a value that captured a raw stack records it whole, resolved here rather than by a second
21
+ * copy of the rule. `effect-spec-runtime`, `effect-cell-types`, `effect-gherkin-spec` and `trace-spec` read it from
22
+ * here.
23
+ *
24
+ * @since 4.0.0
25
+ */
26
+ const FRAME = /\(?((?:file:\/\/)?[^()\s]+):(\d+):(\d+)\)?\s*$/u;
27
+ const FILE_PROTOCOL = "file://";
28
+ const FRAME_AT = "at ";
29
+ const FRAME_PAREN = " (";
30
+ const and = (left, right) => left && right;
31
+ const not = (value) => !value;
32
+ const LIBRARY_DIRS = [
33
+ "runner/vitest",
34
+ "effect-spec-runtime",
35
+ "effect-cell-types",
36
+ "effect-gherkin-spec",
37
+ "storybook-gherkin",
38
+ "conformance-spec",
39
+ "differential-spec",
40
+ "trace-spec",
41
+ "effect-daemon-spec"
42
+ ];
43
+ const isVendoredPath = (path) => path.includes("node_modules") || path.startsWith("node:");
44
+ const inOwnDir = (path) => (dir) => path.includes(`/${dir}/src/`) || path.includes(`/${dir}/dist/`);
45
+ const isLibraryPath = (path) => LIBRARY_DIRS.some(inOwnDir(path));
46
+ /** @internal */
47
+ const isUserPath = (path) => and(not(isVendoredPath(path)), not(isLibraryPath(path)));
48
+ const stripProtocol = (path) => path.startsWith(FILE_PROTOCOL) ? path.slice(7) : path;
49
+ const isFrame = (frame) => frame !== void 0;
50
+ const partsOf = (match) => Option.flatMap(Option.fromNullishOr(match), (found) => Option.map(Option.all([
51
+ Option.fromNullishOr(found[1]),
52
+ Option.fromNullishOr(found[2]),
53
+ Option.fromNullishOr(found[3])
54
+ ]), ([path, line, column]) => ({
55
+ path: stripProtocol(path),
56
+ line,
57
+ column
58
+ })));
59
+ const beforeParen = (rest) => Option.flatMap(Option.fromNullishOr(rest.indexOf(FRAME_PAREN)), (paren) => Option.some(rest.slice(0, paren)));
60
+ const afterAt = (line) => line.startsWith(FRAME_AT) ? Option.some(line.slice(3)) : Option.none();
61
+ const nonEmpty = (text) => text.length > 0;
62
+ const fnIn = (line) => Option.getOrUndefined(Option.flatMap(afterAt(line), (rest) => Option.filter(beforeParen(rest), nonEmpty)));
63
+ const frameOfLine = (line) => {
64
+ const raw = line.trim();
65
+ return Option.match(partsOf(FRAME.exec(raw)), {
66
+ onNone: () => void 0,
67
+ onSome: (parts) => ({
68
+ ...parts,
69
+ fn: fnIn(raw),
70
+ raw
71
+ })
72
+ });
73
+ };
74
+ /** @internal */
75
+ const framesOf = (stack) => stack.split("\n").map(frameOfLine).filter(isFrame);
76
+ const frameSiteOf = (frame) => `${frame.path}:${frame.line}:${frame.column}`;
77
+ const isUserFrame = (frame) => isUserPath(frame.path);
78
+ const firstUserFrameOf = (stack) => framesOf(stack).find(isUserFrame);
79
+ /** @internal */
80
+ const firstUserSiteOf = (stack) => {
81
+ const frame = firstUserFrameOf(stack);
82
+ return frame === void 0 ? void 0 : frameSiteOf(frame);
83
+ };
84
+ const NO_LIBRARY = /$^/u;
85
+ const currentStack = () => (/* @__PURE__ */ new Error()).stack ?? "";
86
+ const isSiteOf = (library) => (frame) => and(isUserPath(frame.path), not(library.test(frame.raw)));
87
+ const firstFrameOf = (stack, library) => framesOf(stack).find(isSiteOf(library));
88
+ /** @internal */
89
+ const callFrameOutside = (library) => {
90
+ const frame = firstFrameOf(currentStack(), library);
91
+ return frame === void 0 ? void 0 : frame.raw;
92
+ };
93
+ /** @internal */
94
+ const callFrame = () => callFrameOutside(NO_LIBRARY);
95
+ const callSiteOutside = (library) => {
96
+ const frame = firstFrameOf(currentStack(), library);
97
+ return frame === void 0 ? void 0 : frameSiteOf(frame);
98
+ };
99
+ /** @internal */
100
+ const callSite = () => callSiteOutside(NO_LIBRARY);
101
+ const firstLineOf = (lines) => lines[0] ?? "";
102
+ const stackOf = (error) => error.stack ?? "";
103
+ const withRaisingFrameImpl = (error, frame) => {
104
+ if (frame === void 0) return error;
105
+ const lines = stackOf(error).split("\n");
106
+ error.stack = [
107
+ firstLineOf(lines),
108
+ frame,
109
+ ...lines.slice(1)
110
+ ].join("\n");
111
+ return error;
112
+ };
113
+ /** @internal */
114
+ const withRaisingFrame = Function.dual(2, withRaisingFrameImpl);
115
+ //#endregion
116
+ //#region src/internal/checks.ts
117
+ /**
118
+ * The checks a test receives as its callback parameter. There is no importable `expect`: the only one in reach is
119
+ * the one the runner hands this test, so it is bound to this test by construction, not by a lookup.
120
+ *
121
+ * Every matcher returns a `Check`: an Effect that needs `Asserted`, a service only the runner provides.
122
+ * - A check that is not yielded is a floating Effect: `@effect/language-service` `floatingEffect` fails the build.
123
+ * - A body that yields no check has no `Asserted` in its requirements: the test signature refuses it.
124
+ * - A check run outside a test has nothing providing `Asserted`: a type error.
125
+ *
126
+ * @since 4.0.0
127
+ */
128
+ /** @internal */
129
+ var Asserted = class extends Context.Service()("@systemfsoftware/vitest/Asserted") {};
130
+ const branded = /* @__PURE__ */ new WeakSet();
131
+ const isObject = (value) => typeof value === "object" && value !== null;
132
+ /** @internal */
133
+ const isCheck = (value) => isObject(value) && branded.has(value);
134
+ const makeCheck = (judgement, written) => {
135
+ written(judgement);
136
+ const check = Effect.gen(function* () {
137
+ (yield* Asserted).judge(judgement);
138
+ });
139
+ branded.add(check);
140
+ return check;
141
+ };
142
+ const has = (table, key) => Object.hasOwn(table, key);
143
+ const isPlainObject = (value) => isObject(value) && Object.getPrototypeOf(value) === Object.prototype;
144
+ const isEmptyShape = (value) => isPlainObject(value) && Object.keys(value).length === 0;
145
+ /** A thunk that refuses with `text`: thrown when a matcher is called, or when a static is read. */
146
+ const refusing = (text) => () => {
147
+ throw refusalOf(text);
148
+ };
149
+ const forView = (view, negated) => ({
150
+ ...view,
151
+ negated
152
+ });
153
+ const notView = (view) => forView(view, !view.negated);
154
+ const viewFor = (written, actual, message, site) => ({
155
+ actual,
156
+ message,
157
+ negated: false,
158
+ written,
159
+ site
160
+ });
161
+ const messageOf = (argument) => typeof argument === "string" ? argument : void 0;
162
+ const refuseBooleanActual = (actual) => typeof actual === "boolean";
163
+ const refusedTextOf = (property) => has(refusedText, property) ? refusedText[property] : void 0;
164
+ const negatedTextOf = (property) => has(negatedText, property) ? negatedText[property] : void 0;
165
+ const textRefusalOf = (view, property) => view.negated ? negatedTextOf(property) : refusedTextOf(property);
166
+ const readRefusals = {
167
+ resolves: refusedText.resolves,
168
+ rejects: refusedText.rejects
169
+ };
170
+ const readRefusal = (property) => readRefusals[property];
171
+ const neededArity = {
172
+ toThrow: 1,
173
+ toThrowError: 1,
174
+ toSatisfy: 2,
175
+ toMatchObject: 1
176
+ };
177
+ const tooFewArguments = (property, args) => args.length < neededArity[property];
178
+ const vacuousMatchObject = (property, args) => property === "toMatchObject" && isEmptyShape(args[0]);
179
+ const missingArgument = (property, args) => tooFewArguments(property, args) || vacuousMatchObject(property, args);
180
+ const memberAt = (target, property) => Reflect.get(target, property, target);
181
+ const isCallable = (value) => typeof value === "function";
182
+ const invokeMember = (target, property, args) => {
183
+ const member = memberAt(target, property);
184
+ if (isCallable(member)) Reflect.apply(member, target, args);
185
+ };
186
+ const judgedBy = (view, property, args, make) => {
187
+ const assertion = make(view.actual, view.message);
188
+ const target = view.negated ? assertion.not : assertion;
189
+ invokeMember(target, property, args);
190
+ };
191
+ const raisedFailure = (thrown, site) => thrown instanceof Error ? withRaisingFrame(thrown, site) : thrown;
192
+ /**
193
+ * A failed judgement is a failure the fork raised: by now the stack holds only the fork's frames, so the site the
194
+ * body called `expect` from is prepended to the error's stack (R2, KTD6).
195
+ */
196
+ const judgementOf = (view, property, args) => (make) => {
197
+ try {
198
+ judgedBy(view, property, args, make);
199
+ } catch (thrown) {
200
+ throw raisedFailure(thrown, view.site);
201
+ }
202
+ };
203
+ const judgedCheck = (view, property, args) => makeCheck(judgementOf(view, property, args), view.written);
204
+ const genericMember = (view, property) => (...args) => judgedCheck(view, property, args);
205
+ const neededMember = (view, property) => (...args) => {
206
+ if (missingArgument(property, args)) throw refusalOf(neededText[property]);
207
+ return judgedCheck(view, property, args);
208
+ };
209
+ const absent = { found: false };
210
+ const present = (value) => ({
211
+ found: true,
212
+ value
213
+ });
214
+ const valueOf = (member) => member.found ? member.value : void 0;
215
+ const fallbackMember = (view, property) => has(neededText, property) ? present(neededMember(view, property)) : present(genericMember(view, property));
216
+ const refusedMember = (view, property) => {
217
+ const text = textRefusalOf(view, property);
218
+ if (text === void 0) return absent;
219
+ return present(refusing(text));
220
+ };
221
+ const afterRefusal = (view, property) => {
222
+ const refused = refusedMember(view, property);
223
+ if (refused.found) return refused;
224
+ return fallbackMember(view, property);
225
+ };
226
+ const negationMember = (view, property) => property === "not" ? present(matcherView(notView(view))) : absent;
227
+ const viewMember = (view, property) => {
228
+ const negation = negationMember(view, property);
229
+ if (negation.found) return negation;
230
+ return afterRefusal(view, property);
231
+ };
232
+ const memberOf = (view, property) => {
233
+ const read = readRefusal(property);
234
+ if (read !== void 0) throw refusalOf(read);
235
+ return valueOf(viewMember(view, property));
236
+ };
237
+ const memberFor = (view, property) => typeof property === "string" ? memberOf(view, property) : void 0;
238
+ const viewHandler = (view) => ({ get: (_target, property) => memberFor(view, property) });
239
+ const matcherView = (view) => new Proxy({}, viewHandler(view));
240
+ const assertionView = (written, args) => {
241
+ if (refuseBooleanActual(args[0])) throw refusalOf(booleanRefusal);
242
+ return matcherView(viewFor(written, args[0], messageOf(args[1]), callFrame()));
243
+ };
244
+ const isDecodingSchema = (value) => Schema.isSchema(value);
245
+ const asMatcher = (value) => {
246
+ if (isObject(value) === false) throw new Error("vitest returned no asymmetric matcher");
247
+ return value;
248
+ };
249
+ const toStandardSchema = (schema) => isDecodingSchema(schema) ? Schema.toStandardSchemaV1(schema) : schema;
250
+ const standardSchemaOf = (schema) => asMatcher(V.expect.schemaMatching(toStandardSchema(schema)));
251
+ const notShapes = {
252
+ stringContaining: V.expect.not.stringContaining,
253
+ objectContaining: V.expect.not.objectContaining,
254
+ arrayContaining: V.expect.not.arrayContaining,
255
+ stringMatching: V.expect.not.stringMatching
256
+ };
257
+ const shapes = {
258
+ objectContaining: V.expect.objectContaining,
259
+ arrayContaining: V.expect.arrayContaining,
260
+ stringContaining: V.expect.stringContaining,
261
+ stringMatching: V.expect.stringMatching,
262
+ closeTo: V.expect.closeTo,
263
+ any: V.expect.any,
264
+ schemaMatching: standardSchemaOf,
265
+ not: notShapes,
266
+ anything: refusing(refusedText.anything),
267
+ poll: refusing(refusedText.poll),
268
+ soft: refusing(refusedText.soft)
269
+ };
270
+ const refusalGetters = [
271
+ ["anything", refusedText.anything],
272
+ ["poll", refusedText.poll],
273
+ ["soft", refusedText.soft]
274
+ ];
275
+ const defineRefusalGetters = (target) => {
276
+ for (const [name, text] of refusalGetters) Object.defineProperty(target, name, { get: refusing(text) });
277
+ };
278
+ const unreachableTarget = () => () => {
279
+ throw new Error("the expect proxy answers every call");
280
+ };
281
+ const expectHandler = (written) => ({ apply: (_target, _thisArgument, argumentList) => assertionView(written, argumentList) });
282
+ const expectFor = (written) => {
283
+ const base = Object.assign(unreachableTarget(), shapes);
284
+ defineRefusalGetters(base);
285
+ return new Proxy(base, expectHandler(written));
286
+ };
287
+ /** @internal */
288
+ const makeLedger = (ctx) => {
289
+ const pending = /* @__PURE__ */ new Set();
290
+ const counter = {
291
+ judged: 0,
292
+ since: 0
293
+ };
294
+ const hard = (actual, message) => ctx.expect(actual, message);
295
+ return {
296
+ asserted: {
297
+ judge: (judgement) => {
298
+ pending.delete(judgement);
299
+ counter.judged += 1;
300
+ counter.since += 1;
301
+ if (counter.since > 1) throw refusalOf(refusePiecewise);
302
+ authorize(() => judgement(hard));
303
+ },
304
+ step: () => {
305
+ counter.since = 0;
306
+ }
307
+ },
308
+ written: (judgement) => {
309
+ pending.add(judgement);
310
+ },
311
+ unyielded: () => pending.size,
312
+ judged: () => counter.judged
313
+ };
314
+ };
315
+ /** @internal */
316
+ const checksFor = (ledger) => ({ expect: expectFor(ledger.written) });
317
+ //#endregion
318
+ //#region src/internal/test-context.ts
319
+ /** @internal */
320
+ const vitestTestContextKey = "@systemfsoftware/vitest/TestContext";
321
+ /**
322
+ * The running Vitest test, or `null` outside a run; provided on every test the fork runs.
323
+ *
324
+ * @internal
325
+ */
326
+ const VitestTestContext = Context.Reference(vitestTestContextKey, { defaultValue: () => null });
327
+ //#endregion
328
+ export { isCheck as a, callFrameOutside as c, framesOf as d, isUserPath as f, checksFor as i, callSite as l, vitestTestContextKey as n, makeLedger as o, withRaisingFrame as p, Asserted as r, callFrame as s, VitestTestContext as t, firstUserSiteOf as u };
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@systemfsoftware/vitest",
3
3
  "license": "MIT",
4
- "version": "0.0.0",
4
+ "version": "0.2.0",
5
5
  "author": "Ryan Lee <drdgvhbh@gmail.com>",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "git+https://github.com/systemfsoftware/systemfsoftware.git",
9
- "directory": "packages/vitest"
9
+ "directory": "packages/runner/vitest"
10
10
  },
11
- "homepage": "https://github.com/systemfsoftware/systemfsoftware/tree/main/packages/vitest#readme",
11
+ "homepage": "https://github.com/systemfsoftware/systemfsoftware/tree/main/packages/runner/vitest#readme",
12
12
  "bugs": "https://github.com/systemfsoftware/systemfsoftware/issues",
13
- "description": "A fork of @effect/vitest whose defaults make the lazy test a good test: fresh layers, a second run that catches leaked state, virtual time, soft checks that stop at the next step, and properties refuted against a constant impostor.",
13
+ "description": "A fork of @effect/vitest whose defaults make the lazy test a good test: expect bound to the test's own callback, one check per observed state, fresh layers, a second run that catches leaked state, virtual time, and properties refuted against a constant impostor.",
14
14
  "keywords": [
15
15
  "effect",
16
16
  "effect-ts",
@@ -25,18 +25,22 @@
25
25
  "types": "./dist/index.d.ts",
26
26
  "default": "./dist/index.mjs"
27
27
  },
28
- "./refusals": {
29
- "types": "./dist/refusals.d.ts",
30
- "default": "./dist/refusals.mjs"
28
+ "./failure": {
29
+ "types": "./dist/failure.d.ts",
30
+ "default": "./dist/failure.mjs"
31
+ },
32
+ "./guard": {
33
+ "types": "./dist/guard.d.ts",
34
+ "default": "./dist/guard.mjs"
35
+ },
36
+ "./integration": {
37
+ "types": "./dist/integration.d.ts",
38
+ "default": "./dist/integration.mjs"
31
39
  },
32
40
  "./TestClock": {
33
41
  "types": "./dist/TestClock.d.ts",
34
42
  "default": "./dist/TestClock.mjs"
35
43
  },
36
- "./utils": {
37
- "types": "./dist/utils.d.ts",
38
- "default": "./dist/utils.mjs"
39
- },
40
44
  "./package.json": "./package.json"
41
45
  },
42
46
  "files": [
@@ -44,7 +48,7 @@
44
48
  ],
45
49
  "devDependencies": {
46
50
  "@systemfsoftware/arethetypeswrong-cli": "^4.2.0",
47
- "@systemfsoftware/oxlint-config-recommended": "^3.1.0",
51
+ "@systemfsoftware/oxlint-config-recommended": "^3.2.0",
48
52
  "@systemfsoftware/tsconfig": "^2.0.1",
49
53
  "@systemfsoftware/tsdown-config": "^0.1.0",
50
54
  "@systemfsoftware/vitest-config": "^0.1.0",
@@ -61,6 +65,7 @@
61
65
  "vitest": "^5"
62
66
  },
63
67
  "publishConfig": {
68
+ "access": "public",
64
69
  "provenance": true
65
70
  },
66
71
  "scripts": {
@@ -1,32 +0,0 @@
1
-
2
- //#region src/internal/refusals.ts
3
- /** @internal */
4
- const refuseHook = "✗ hooks share state between tests. Build what a test needs inside it; services come fresh per test from layer(Service.layer)((it) => { ... }).";
5
- /** @internal */
6
- const refuseNoAssertion = "✗ this test ran no assertion, so it cannot fail. Assert on what the code returned: expect(actual).toEqual(expected).";
7
- /** @internal */
8
- const refuseAsync = "✗ an async test runs Effects outside the test runtime: no virtual time, no fresh services, no leak check. Return the Effect instead: it.effect(name, () => Effect.gen(function* () { ... })).";
9
- /** @internal */
10
- const refuseBareEffect = "✗ a bare test body that returns an Effect never runs it, so nothing in the test was checked. Register it on the Effect lane: it.effect(name, () => Effect.gen(function* () { ... })).";
11
- /** @internal */
12
- const refuseUnprovided = "✗ the test needs a service that nothing provides. Pipe the body through Effect.provide(Service.layer), or write the tests inside layer(Service.layer)((it) => { ... }); every test gets its own fresh build.";
13
- /** @internal */
14
- const refuseBoolean = "✗ expect(<boolean>) can only report 'expected false to be true'. Pass the two values instead: expect(Equal.equals(a, b)).toBe(true) becomes expect(a).toEqual(b). A predicate: expect(value).toSatisfy(predicate).";
15
- /** @internal */
16
- const refusePositionalProp = "✗ it.prop(name, [arbitraries], predicate) is removed. Name the function under test and pass a budget: it.prop(name, { of, subject, runs }, holds).";
17
- /** @internal */
18
- const presenceMessage = (name) => `✗ ${name} passes for almost any value the code returns. Assert the value: toEqual(expected); for a key that must exist: toHaveProperty(key).`;
19
- /** @internal */
20
- const narrowVacuous = [
21
- "toBeDefined",
22
- "toBeTruthy",
23
- "toBeFalsy"
24
- ];
25
- /** @internal */
26
- const narrowNegated = [
27
- ...narrowVacuous,
28
- "toBeNull",
29
- "toBeUndefined"
30
- ];
31
- //#endregion
32
- export { refuseBareEffect as a, refuseNoAssertion as c, refuseAsync as i, refusePositionalProp as l, narrowVacuous as n, refuseBoolean as o, presenceMessage as r, refuseHook as s, narrowNegated as t, refuseUnprovided as u };
@@ -1,37 +0,0 @@
1
-
2
- //#region src/internal/refusals.d.ts
3
- /** @internal */
4
- declare const refuseHook = "✗ hooks share state between tests. Build what a test needs inside it; services come fresh per test from layer(Service.layer)((it) => { ... }).";
5
- /** @internal */
6
- declare const refuseNoAssertion = "✗ this test ran no assertion, so it cannot fail. Assert on what the code returned: expect(actual).toEqual(expected).";
7
- /** @internal */
8
- declare const refuseAsync = "✗ an async test runs Effects outside the test runtime: no virtual time, no fresh services, no leak check. Return the Effect instead: it.effect(name, () => Effect.gen(function* () { ... })).";
9
- /** @internal */
10
- declare const refuseBareEffect = "✗ a bare test body that returns an Effect never runs it, so nothing in the test was checked. Register it on the Effect lane: it.effect(name, () => Effect.gen(function* () { ... })).";
11
- /** @internal */
12
- declare const refuseUnprovided = "✗ the test needs a service that nothing provides. Pipe the body through Effect.provide(Service.layer), or write the tests inside layer(Service.layer)((it) => { ... }); every test gets its own fresh build.";
13
- /** @internal */
14
- declare const refuseBoolean = "✗ expect(<boolean>) can only report 'expected false to be true'. Pass the two values instead: expect(Equal.equals(a, b)).toBe(true) becomes expect(a).toEqual(b). A predicate: expect(value).toSatisfy(predicate).";
15
- /** @internal */
16
- declare const refusePositionalProp = "✗ it.prop(name, [arbitraries], predicate) is removed. Name the function under test and pass a budget: it.prop(name, { of, subject, runs }, holds).";
17
- /** @internal */
18
- type PresenceMessage<N extends string = string> = `✗ ${N} passes for almost any value the code returns. Assert the value: toEqual(expected); for a key that must exist: toHaveProperty(key).`;
19
- /**
20
- * The narrowed matcher as the type sees it: a call whose `this` is not the assertion cannot compile, and the
21
- * refused text is the compiler error (KTD9). The run time throws the same text.
22
- *
23
- * @internal
24
- */
25
- type PresenceRefusal<N extends string = string> = (this: PresenceMessage<N>, ...args: Array<never>) => void;
26
- /** @internal */
27
- declare const presenceMessage: <N extends string>(name: N) => PresenceMessage<N>;
28
- /** @internal */
29
- declare const narrowVacuous: readonly ['toBeDefined', 'toBeTruthy', 'toBeFalsy'];
30
- /** @internal */
31
- type NarrowVacuousName = (typeof narrowVacuous)[number];
32
- /** @internal */
33
- declare const narrowNegated: readonly ["toBeDefined", "toBeTruthy", "toBeFalsy", "toBeNull", "toBeUndefined"];
34
- /** @internal */
35
- type NarrowNegatedName = (typeof narrowNegated)[number];
36
- //#endregion
37
- export { narrowVacuous as a, refuseBareEffect as c, refuseNoAssertion as d, refusePositionalProp as f, narrowNegated as i, refuseBoolean as l, NarrowVacuousName as n, presenceMessage as o, refuseUnprovided as p, PresenceRefusal as r, refuseAsync as s, NarrowNegatedName as t, refuseHook as u };
@@ -1,3 +0,0 @@
1
-
2
- import { a as narrowVacuous, c as refuseBareEffect, d as refuseNoAssertion, f as refusePositionalProp, i as narrowNegated, l as refuseBoolean, o as presenceMessage, p as refuseUnprovided, s as refuseAsync, u as refuseHook } from "./refusals-_6e3GzVK.js";
3
- export { narrowNegated, narrowVacuous, presenceMessage, refuseAsync, refuseBareEffect, refuseBoolean, refuseHook, refuseNoAssertion, refusePositionalProp, refuseUnprovided };
package/dist/refusals.mjs DELETED
@@ -1,3 +0,0 @@
1
-
2
- import { a as refuseBareEffect, c as refuseNoAssertion, i as refuseAsync, l as refusePositionalProp, n as narrowVacuous, o as refuseBoolean, r as presenceMessage, s as refuseHook, t as narrowNegated, u as refuseUnprovided } from "./refusals-BQtDszyU.mjs";
3
- export { narrowNegated, narrowVacuous, presenceMessage, refuseAsync, refuseBareEffect, refuseBoolean, refuseHook, refuseNoAssertion, refusePositionalProp, refuseUnprovided };