effect-bun-testing 4.0.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,152 @@
1
+ import { Cause, Duration, Effect, Exit, Layer, pipe, Schedule, Scope } from "effect";
2
+ import { TestClock, TestConsole } from "effect/testing";
3
+ import { describe, beforeAll, afterAll, test as bunTest, expect } from "bun:test";
4
+ import * as fc from "fast-check";
5
+ import * as Equal from "effect/Equal";
6
+ // ---------------------------------------------------------------------------
7
+ // Test Environment
8
+ // ---------------------------------------------------------------------------
9
+ const TestEnv = Layer.mergeAll(TestConsole.layer, TestClock.layer());
10
+ // ---------------------------------------------------------------------------
11
+ // runPromise — Bun-adapted Effect runner (no signal, no onTestFinished)
12
+ // ---------------------------------------------------------------------------
13
+ const runPromise = (effect) => Effect.gen(function* () {
14
+ const exit = yield* Effect.exit(effect);
15
+ if (Exit.isSuccess(exit)) {
16
+ return exit.value;
17
+ }
18
+ if (Cause.hasInterruptsOnly(exit.cause)) {
19
+ throw new Error("All fibers interrupted without errors.");
20
+ }
21
+ const errors = Cause.prettyErrors(exit.cause);
22
+ for (let i = 1; i < errors.length; i++) {
23
+ yield* Effect.logError(errors[i]);
24
+ }
25
+ throw errors[0];
26
+ }).pipe(Effect.runPromise);
27
+ // ---------------------------------------------------------------------------
28
+ // makeTester — creates a Tester<R> that maps each test body through mapEffect
29
+ // ---------------------------------------------------------------------------
30
+ export const makeTester = (mapEffect, testFn = bunTest) => {
31
+ const run = (self) => runPromise(pipe(Effect.suspend(self), mapEffect, Effect.asVoid));
32
+ const f = (name, self, timeout) => testFn(name, () => run(self), timeout);
33
+ const skip = (name, self, timeout) => testFn.skip(name, () => run(self), timeout);
34
+ const only = (name, self, timeout) => testFn.only(name, () => run(self), timeout);
35
+ const skipIf = (condition) => (name, self, timeout) => testFn.skipIf(condition)(name, () => run(self), timeout);
36
+ const ifCond = (condition) => (name, self, timeout) => testFn.if(condition)(name, () => run(self), timeout);
37
+ const each = (cases) => (name, self, timeout) => testFn.each(cases)(name, (args) => runPromise(pipe(Effect.suspend(() => self(args)), mapEffect, Effect.asVoid)), timeout);
38
+ const failing = (name, self, timeout) => testFn.failing(name, () => run(self), timeout);
39
+ const propFn = (name, arbitraries, self, timeout) => {
40
+ const fcOptions = typeof timeout === "object" ? timeout?.fastCheck : undefined;
41
+ const timeoutMs = typeof timeout === "number" ? timeout : undefined;
42
+ testFn(name, async () => {
43
+ await fc.assert(fc.asyncProperty(...arbitraries, (...args) => runPromise(pipe(Effect.suspend(() => self(...args)), mapEffect, Effect.asVoid))), fcOptions);
44
+ }, timeoutMs);
45
+ };
46
+ return Object.assign(f, {
47
+ skip,
48
+ only,
49
+ skipIf,
50
+ if: ifCond,
51
+ runIf: ifCond,
52
+ each,
53
+ failing,
54
+ fails: failing,
55
+ prop: propFn
56
+ });
57
+ };
58
+ // ---------------------------------------------------------------------------
59
+ // Preconfigured testers
60
+ // ---------------------------------------------------------------------------
61
+ /** Run effects with TestClock + TestConsole, auto-scoped. */
62
+ export const effect = makeTester((e) => e.pipe(Effect.scoped, Effect.provide(TestEnv)));
63
+ /** Run effects live (no test services), auto-scoped. */
64
+ export const live = makeTester((e) => Effect.scoped(e));
65
+ // ---------------------------------------------------------------------------
66
+ // flakyTest — retry an effect up to 10 times within a timeout
67
+ // ---------------------------------------------------------------------------
68
+ export const flakyTest = (self, timeout = Duration.seconds(30)) => pipe(Effect.catchDefect(self, (defect) => Effect.fail(defect)), Effect.retry(Schedule.both(Schedule.recurs(10), Schedule.during(timeout))), Effect.orDie);
69
+ // ---------------------------------------------------------------------------
70
+ // prop — non-Effect property-based test
71
+ // ---------------------------------------------------------------------------
72
+ export const prop = (name, arbitraries, self, timeout) => {
73
+ const fcOptions = typeof timeout === "object" ? timeout?.fastCheck : undefined;
74
+ const timeoutMs = typeof timeout === "number" ? timeout : undefined;
75
+ bunTest(name, async () => {
76
+ await fc.assert(fc.asyncProperty(...arbitraries, (...args) => self(...args)), fcOptions);
77
+ }, timeoutMs);
78
+ };
79
+ // ---------------------------------------------------------------------------
80
+ // layer — shared Layer across tests with beforeAll/afterAll lifecycle
81
+ // ---------------------------------------------------------------------------
82
+ export const layer = (layer_, options) => {
83
+ return ((...args) => {
84
+ const excludeTestServices = options?.excludeTestServices ?? false;
85
+ const withTestEnv = excludeTestServices
86
+ ? layer_
87
+ : Layer.provideMerge(layer_, TestEnv);
88
+ const memoMap = options?.memoMap ?? Layer.makeMemoMapUnsafe();
89
+ const scope = Scope.makeUnsafe();
90
+ const timeout = options?.timeout
91
+ ? Duration.toMillis(options.timeout)
92
+ : undefined;
93
+ const serviceMapEffect = pipe(Layer.buildWithMemoMap(withTestEnv, memoMap, scope), Effect.orDie, Effect.cached, Effect.runSync);
94
+ const effectTester = makeTester((e) => Effect.flatMap(serviceMapEffect, (serviceMap) => e.pipe(Effect.scoped, Effect.provide(serviceMap))));
95
+ const makeIt = () => ({
96
+ effect: effectTester,
97
+ flakyTest,
98
+ prop,
99
+ layer: (nestedLayer, nestedOptions) => layer(Layer.provideMerge(nestedLayer, withTestEnv), {
100
+ ...nestedOptions,
101
+ memoMap,
102
+ excludeTestServices: true
103
+ })
104
+ });
105
+ if (args.length === 1) {
106
+ beforeAll(() => runPromise(Effect.asVoid(serviceMapEffect)), timeout);
107
+ afterAll(() => runPromise(Scope.close(scope, Exit.void)), timeout);
108
+ return args[0](makeIt());
109
+ }
110
+ return describe(args[0], () => {
111
+ beforeAll(() => runPromise(Effect.asVoid(serviceMapEffect)), timeout);
112
+ afterAll(() => runPromise(Scope.close(scope, Exit.void)), timeout);
113
+ return args[1](makeIt());
114
+ });
115
+ });
116
+ };
117
+ // ---------------------------------------------------------------------------
118
+ // makeMethods — compose the full `Methods` object
119
+ // ---------------------------------------------------------------------------
120
+ export const makeMethods = () => ({
121
+ effect,
122
+ live,
123
+ flakyTest,
124
+ layer,
125
+ prop
126
+ });
127
+ // ---------------------------------------------------------------------------
128
+ // addEqualityTesters — register Effect Equal-aware matchers via expect.extend
129
+ // ---------------------------------------------------------------------------
130
+ export const addEqualityTesters = () => {
131
+ expect.extend({
132
+ toEqualEffect(received, expected) {
133
+ if (!Equal.isEqual(received) || !Equal.isEqual(expected)) {
134
+ const pass = Object.is(received, expected);
135
+ return {
136
+ pass,
137
+ message: () => pass
138
+ ? `Expected values to not be equal`
139
+ : `Expected values to be equal`
140
+ };
141
+ }
142
+ const pass = Equal.equals(received, expected);
143
+ return {
144
+ pass,
145
+ message: () => pass
146
+ ? `Expected Effect values to not be equal (via Equal.equals)`
147
+ : `Expected Effect values to be equal (via Equal.equals), but they differ`
148
+ };
149
+ }
150
+ });
151
+ };
152
+ //# sourceMappingURL=internal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal.js","sourceRoot":"","sources":["../../src/internal/internal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { Option, Result, Exit, Cause } from "effect";
2
+ export declare function fail(message: string): never;
3
+ export declare function deepStrictEqual<A>(actual: A, expected: A, message?: string): void;
4
+ export declare function strictEqual<A>(actual: A, expected: A, message?: string): void;
5
+ export declare function notDeepStrictEqual<A>(actual: A, expected: A, message?: string): void;
6
+ /** Compare using Effect's `Equal.equals` for structural equality. */
7
+ export declare function assertEquals<A>(actual: A, expected: A, message?: string): void;
8
+ export declare function doesNotThrow(thunk: () => void, message?: string): void;
9
+ export declare function assertTrue(self: unknown, message?: string): asserts self;
10
+ export declare function assertFalse(self: boolean, message?: string): void;
11
+ export declare function assertInstanceOf<C extends abstract new (...args: any[]) => any>(value: unknown, constructor: C, message?: string): asserts value is InstanceType<C>;
12
+ export declare function assertInclude(actual: string | undefined, expected: string): void;
13
+ export declare function assertMatch(actual: string, regexp: RegExp): void;
14
+ export declare function throws(thunk: () => void, error?: Error | ((u: unknown) => void)): void;
15
+ export declare function throwsAsync(thunk: () => Promise<void>, error?: Error | ((u: unknown) => void)): Promise<void>;
16
+ export declare function assertNone<A>(option: Option.Option<A>): asserts option is Option.None<never>;
17
+ export declare function assertSome<A>(option: Option.Option<A>, expected: A): asserts option is Option.Some<A>;
18
+ export declare function assertSuccess_<A, E>(result: Result.Result<A, E>, expected: A): asserts result is Result.Success<A, E>;
19
+ export declare function assertFailure_<A, E>(result: Result.Result<A, E>, expected: E): asserts result is Result.Failure<A, E>;
20
+ /** Alias for assertSuccess_ (vitest compat: assertRight). */
21
+ export declare function assertRight<A, E>(result: Result.Result<A, E>, expected: A): asserts result is Result.Success<A, E>;
22
+ /** Alias for assertFailure_ (vitest compat: assertLeft). */
23
+ export declare function assertLeft<A, E>(result: Result.Result<A, E>, expected: E): asserts result is Result.Failure<A, E>;
24
+ export declare function assertExitSuccess<A, E>(exit: Exit.Exit<A, E>, expected: A): asserts exit is Exit.Success<A, never>;
25
+ export declare function assertExitFailure<A, E>(exit: Exit.Exit<A, E>, expected: Cause.Cause<E>): asserts exit is Exit.Failure<never, E>;
26
+ /** @deprecated Use assertExitSuccess. Alias. */
27
+ export declare const assertSuccess: typeof assertExitSuccess;
28
+ /** @deprecated Use assertExitFailure. Alias. */
29
+ export declare const assertFailure: typeof assertExitFailure;
30
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
package/dist/utils.js ADDED
@@ -0,0 +1,158 @@
1
+ import { expect } from "bun:test";
2
+ import * as Equal from "effect/Equal";
3
+ import { Option, Result, Exit } from "effect";
4
+ // ---------------------------------------------------------------------------
5
+ // Primitive assertions
6
+ // ---------------------------------------------------------------------------
7
+ export function fail(message) {
8
+ throw new Error(message);
9
+ }
10
+ export function deepStrictEqual(actual, expected, message) {
11
+ expect(actual).toStrictEqual(expected);
12
+ if (message) {
13
+ // Message is informational — the assertion above throws on failure
14
+ }
15
+ }
16
+ export function strictEqual(actual, expected, message) {
17
+ expect(actual).toBe(expected);
18
+ }
19
+ export function notDeepStrictEqual(actual, expected, message) {
20
+ expect(actual).not.toStrictEqual(expected);
21
+ }
22
+ /** Compare using Effect's `Equal.equals` for structural equality. */
23
+ export function assertEquals(actual, expected, message) {
24
+ if (!Equal.equals(actual, expected)) {
25
+ const msg = message ?? `Expected values to be equal (via Equal.equals)`;
26
+ throw new Error(`${msg}\n actual: ${JSON.stringify(actual)}\n expected: ${JSON.stringify(expected)}`);
27
+ }
28
+ }
29
+ export function doesNotThrow(thunk, message) {
30
+ try {
31
+ thunk();
32
+ }
33
+ catch (e) {
34
+ throw new Error(message ?? `Expected function not to throw, but it threw: ${e}`);
35
+ }
36
+ }
37
+ // ---------------------------------------------------------------------------
38
+ // Boolean assertions
39
+ // ---------------------------------------------------------------------------
40
+ export function assertTrue(self, message) {
41
+ expect(self).toBeTruthy();
42
+ }
43
+ export function assertFalse(self, message) {
44
+ expect(self).toBeFalsy();
45
+ }
46
+ // ---------------------------------------------------------------------------
47
+ // Type assertions
48
+ // ---------------------------------------------------------------------------
49
+ export function assertInstanceOf(value, constructor, message) {
50
+ expect(value).toBeInstanceOf(constructor);
51
+ }
52
+ // ---------------------------------------------------------------------------
53
+ // String assertions
54
+ // ---------------------------------------------------------------------------
55
+ export function assertInclude(actual, expected) {
56
+ expect(actual).toBeDefined();
57
+ expect(actual).toInclude(expected);
58
+ }
59
+ export function assertMatch(actual, regexp) {
60
+ expect(actual).toMatch(regexp);
61
+ }
62
+ // ---------------------------------------------------------------------------
63
+ // Throw assertions
64
+ // ---------------------------------------------------------------------------
65
+ export function throws(thunk, error) {
66
+ if (typeof error === "function") {
67
+ try {
68
+ thunk();
69
+ throw new Error("Expected function to throw");
70
+ }
71
+ catch (e) {
72
+ error(e);
73
+ }
74
+ }
75
+ else if (error) {
76
+ expect(thunk).toThrow(error.message);
77
+ }
78
+ else {
79
+ expect(thunk).toThrow();
80
+ }
81
+ }
82
+ export async function throwsAsync(thunk, error) {
83
+ if (typeof error === "function") {
84
+ try {
85
+ await thunk();
86
+ throw new Error("Expected async function to throw");
87
+ }
88
+ catch (e) {
89
+ error(e);
90
+ }
91
+ }
92
+ else {
93
+ try {
94
+ await thunk();
95
+ throw new Error("Expected async function to throw");
96
+ }
97
+ catch (e) {
98
+ if (error && e instanceof Error) {
99
+ expect(e.message).toInclude(error.message);
100
+ }
101
+ }
102
+ }
103
+ }
104
+ // ---------------------------------------------------------------------------
105
+ // Option assertions
106
+ // ---------------------------------------------------------------------------
107
+ export function assertNone(option) {
108
+ expect(Option.isNone(option)).toBe(true);
109
+ }
110
+ export function assertSome(option, expected) {
111
+ expect(Option.isSome(option)).toBe(true);
112
+ if (Option.isSome(option)) {
113
+ assertEquals(option.value, expected);
114
+ }
115
+ }
116
+ // ---------------------------------------------------------------------------
117
+ // Result assertions (v4: Either → Result)
118
+ // ---------------------------------------------------------------------------
119
+ export function assertSuccess_(result, expected) {
120
+ expect(Result.isSuccess(result)).toBe(true);
121
+ if (Result.isSuccess(result)) {
122
+ assertEquals(result.success, expected);
123
+ }
124
+ }
125
+ export function assertFailure_(result, expected) {
126
+ expect(Result.isFailure(result)).toBe(true);
127
+ if (Result.isFailure(result)) {
128
+ assertEquals(result.failure, expected);
129
+ }
130
+ }
131
+ /** Alias for assertSuccess_ (vitest compat: assertRight). */
132
+ export function assertRight(result, expected) {
133
+ assertSuccess_(result, expected);
134
+ }
135
+ /** Alias for assertFailure_ (vitest compat: assertLeft). */
136
+ export function assertLeft(result, expected) {
137
+ assertFailure_(result, expected);
138
+ }
139
+ // ---------------------------------------------------------------------------
140
+ // Exit assertions
141
+ // ---------------------------------------------------------------------------
142
+ export function assertExitSuccess(exit, expected) {
143
+ expect(Exit.isSuccess(exit)).toBe(true);
144
+ if (Exit.isSuccess(exit)) {
145
+ assertEquals(exit.value, expected);
146
+ }
147
+ }
148
+ export function assertExitFailure(exit, expected) {
149
+ expect(Exit.isFailure(exit)).toBe(true);
150
+ if (Exit.isFailure(exit)) {
151
+ assertEquals(exit.cause, expected);
152
+ }
153
+ }
154
+ /** @deprecated Use assertExitSuccess. Alias. */
155
+ export const assertSuccess = assertExitSuccess;
156
+ /** @deprecated Use assertExitFailure. Alias. */
157
+ export const assertFailure = assertExitFailure;
158
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "effect-bun-testing",
3
+ "version": "4.0.0",
4
+ "description": "Effect test helpers for Bun's built-in test runner",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "bun": "./src/index.ts",
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ }
15
+ },
16
+ "./utils": {
17
+ "bun": "./src/utils.ts",
18
+ "import": {
19
+ "types": "./dist/utils.d.ts",
20
+ "default": "./dist/utils.js"
21
+ }
22
+ }
23
+ },
24
+ "files": [
25
+ "dist",
26
+ "src",
27
+ "README.md"
28
+ ],
29
+ "peerDependencies": {
30
+ "effect": "^4.0.0-beta.10"
31
+ },
32
+ "devDependencies": {
33
+ "@changesets/changelog-github": "^0.5.2",
34
+ "@changesets/cli": "^2.29.8",
35
+ "@types/bun": "^1.2.0",
36
+ "effect": "4.0.0-beta.10",
37
+ "fast-check": "^3.23.0"
38
+ },
39
+ "scripts": {
40
+ "test": "bun test",
41
+ "typecheck": "bun x tsc --noEmit",
42
+ "build": "rm -rf dist && tsc -p tsconfig.build.json",
43
+ "prepublishOnly": "bun run build",
44
+ "changeset": "changeset",
45
+ "version": "changeset version",
46
+ "release": "bun run build && changeset publish"
47
+ },
48
+ "keywords": [
49
+ "effect",
50
+ "bun",
51
+ "test",
52
+ "testing"
53
+ ],
54
+ "license": "MIT"
55
+ }
package/src/index.ts ADDED
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Effect test helpers for Bun's built-in test runner.
3
+ *
4
+ * Ports the `@effect/vitest` API to `bun:test`, including `it.effect`,
5
+ * `it.live`, `layer()`, `flakyTest`, property-based testing, and assertion
6
+ * utilities.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { it } from "effect-bun-test"
11
+ * import { Effect } from "effect"
12
+ *
13
+ * it.effect("adds numbers", () =>
14
+ * Effect.gen(function*() {
15
+ * const result = 1 + 1
16
+ * expect(result).toBe(2)
17
+ * })
18
+ * )
19
+ * ```
20
+ *
21
+ * @module
22
+ */
23
+
24
+ // Re-export bun:test for convenience (parallel to @effect/vitest re-exporting vitest)
25
+ export {
26
+ describe,
27
+ expect,
28
+ beforeAll,
29
+ afterAll,
30
+ beforeEach,
31
+ afterEach,
32
+ test,
33
+ mock,
34
+ spyOn,
35
+ jest,
36
+ vi,
37
+ setSystemTime
38
+ } from "bun:test"
39
+
40
+ // ---------------------------------------------------------------------------
41
+ // Core exports from internal
42
+ // ---------------------------------------------------------------------------
43
+ export {
44
+ effect,
45
+ live,
46
+ makeTester,
47
+ flakyTest,
48
+ prop,
49
+ layer,
50
+ makeMethods,
51
+ addEqualityTesters
52
+ } from "./internal/internal.js"
53
+
54
+ // ---------------------------------------------------------------------------
55
+ // Type exports
56
+ // ---------------------------------------------------------------------------
57
+ export type {
58
+ TestFunction,
59
+ Test,
60
+ Tester,
61
+ PropEffect,
62
+ Prop,
63
+ TestServices,
64
+ Methods,
65
+ MethodsNonLive,
66
+ LayerOptions,
67
+ LayerFn
68
+ } from "./internal/internal.js"
69
+
70
+ // ---------------------------------------------------------------------------
71
+ // Composed `it` — the primary import for most users
72
+ // ---------------------------------------------------------------------------
73
+ import { test as bunTest } from "bun:test"
74
+ import {
75
+ effect,
76
+ live,
77
+ flakyTest,
78
+ layer,
79
+ prop
80
+ } from "./internal/internal.js"
81
+ import type { Methods } from "./internal/internal.js"
82
+
83
+ /**
84
+ * Drop-in replacement for bun:test's `it` / `test`, augmented with Effect
85
+ * methods.
86
+ *
87
+ * @example
88
+ * ```ts
89
+ * import { it } from "effect-bun-test"
90
+ *
91
+ * it.effect("runs an Effect test", () =>
92
+ * Effect.succeed(42).pipe(Effect.map((n) => expect(n).toBe(42)))
93
+ * )
94
+ *
95
+ * it.live("runs without test services", () =>
96
+ * Effect.sync(() => expect(Date.now()).toBeGreaterThan(0))
97
+ * )
98
+ * ```
99
+ */
100
+ export const it: typeof bunTest & Methods = Object.assign(bunTest, {
101
+ effect,
102
+ live,
103
+ flakyTest,
104
+ layer,
105
+ prop
106
+ } satisfies Methods)