@logixjs/test 0.0.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.
Files changed (52) hide show
  1. package/dist/Assertions-OpNAhiI_.d.ts +16 -0
  2. package/dist/Assertions-uDVCBadW.d.cts +16 -0
  3. package/dist/Assertions.cjs +85 -0
  4. package/dist/Assertions.d.cts +4 -0
  5. package/dist/Assertions.d.ts +4 -0
  6. package/dist/Assertions.js +12 -0
  7. package/dist/Execution-Cu-n-UYb.d.ts +18 -0
  8. package/dist/Execution-FfEGGSS7.d.cts +18 -0
  9. package/dist/Execution.cjs +98 -0
  10. package/dist/Execution.d.cts +2 -0
  11. package/dist/Execution.d.ts +2 -0
  12. package/dist/Execution.js +24 -0
  13. package/dist/ExecutionResult-BRC-Jzsv.d.cts +35 -0
  14. package/dist/ExecutionResult-BRC-Jzsv.d.ts +35 -0
  15. package/dist/TestProgram-BLXiWhJQ.d.cts +31 -0
  16. package/dist/TestProgram-CPvVAbfI.d.cts +10 -0
  17. package/dist/TestProgram-DJAm0dIS.d.ts +10 -0
  18. package/dist/TestProgram-X35n_2Js.d.ts +31 -0
  19. package/dist/TestProgram.cjs +220 -0
  20. package/dist/TestProgram.d.cts +6 -0
  21. package/dist/TestProgram.d.ts +6 -0
  22. package/dist/TestProgram.js +10 -0
  23. package/dist/TestRuntime-CyYCUXdT.d.cts +10 -0
  24. package/dist/TestRuntime-CyYCUXdT.d.ts +10 -0
  25. package/dist/TestRuntime.cjs +36 -0
  26. package/dist/TestRuntime.d.cts +2 -0
  27. package/dist/TestRuntime.d.ts +2 -0
  28. package/dist/TestRuntime.js +8 -0
  29. package/dist/Vitest-BXBtxem-.d.ts +28 -0
  30. package/dist/Vitest-BiBMIx3C.d.cts +28 -0
  31. package/dist/Vitest.cjs +3338 -0
  32. package/dist/Vitest.d.cts +7 -0
  33. package/dist/Vitest.d.ts +7 -0
  34. package/dist/Vitest.js +13 -0
  35. package/dist/chunk-42QGM623.js +16 -0
  36. package/dist/chunk-5XFEOVH5.js +16 -0
  37. package/dist/chunk-CZJ37XWT.js +132 -0
  38. package/dist/chunk-DKT5EFOF.js +10 -0
  39. package/dist/chunk-DU6VSL4D.js +57 -0
  40. package/dist/chunk-FOYMJMJR.js +38 -0
  41. package/dist/chunk-J5AZHNSA.js +32 -0
  42. package/dist/chunk-RG24KSEB.js +64 -0
  43. package/dist/chunk-TDYES47J.js +3125 -0
  44. package/dist/chunk-WVD5DTP4.js +20 -0
  45. package/dist/index.cjs +3424 -0
  46. package/dist/index.d.cts +11 -0
  47. package/dist/index.d.ts +11 -0
  48. package/dist/index.js +27 -0
  49. package/dist/magic-string.es-6HF3TVF6.js +1308 -0
  50. package/dist/waitUntil-CjpwZxCu.d.cts +13 -0
  51. package/dist/waitUntil-CjpwZxCu.d.ts +13 -0
  52. package/package.json +71 -0
@@ -0,0 +1,7 @@
1
+ export { i as itProgram, a as itProgramResult } from './Vitest-BiBMIx3C.cjs';
2
+ import 'effect';
3
+ import '@logixjs/core';
4
+ import './ExecutionResult-BRC-Jzsv.cjs';
5
+ import './TestProgram-BLXiWhJQ.cjs';
6
+ import '@logixjs/core/Runtime';
7
+ import './waitUntil-CjpwZxCu.cjs';
@@ -0,0 +1,7 @@
1
+ export { i as itProgram, a as itProgramResult } from './Vitest-BXBtxem-.js';
2
+ import 'effect';
3
+ import '@logixjs/core';
4
+ import './ExecutionResult-BRC-Jzsv.js';
5
+ import './TestProgram-X35n_2Js.js';
6
+ import '@logixjs/core/Runtime';
7
+ import './waitUntil-CjpwZxCu.js';
package/dist/Vitest.js ADDED
@@ -0,0 +1,13 @@
1
+ import {
2
+ itProgram,
3
+ itProgramResult
4
+ } from "./chunk-TDYES47J.js";
5
+ import "./chunk-CZJ37XWT.js";
6
+ import "./chunk-DU6VSL4D.js";
7
+ import "./chunk-RG24KSEB.js";
8
+ import "./chunk-DKT5EFOF.js";
9
+ import "./chunk-FOYMJMJR.js";
10
+ export {
11
+ itProgram,
12
+ itProgramResult
13
+ };
@@ -0,0 +1,16 @@
1
+ import {
2
+ runTest
3
+ } from "./chunk-DKT5EFOF.js";
4
+ import {
5
+ __export
6
+ } from "./chunk-FOYMJMJR.js";
7
+
8
+ // src/TestRuntime.ts
9
+ var TestRuntime_exports = {};
10
+ __export(TestRuntime_exports, {
11
+ runTest: () => runTest
12
+ });
13
+
14
+ export {
15
+ TestRuntime_exports
16
+ };
@@ -0,0 +1,16 @@
1
+ import {
2
+ runProgram
3
+ } from "./chunk-CZJ37XWT.js";
4
+ import {
5
+ __export
6
+ } from "./chunk-FOYMJMJR.js";
7
+
8
+ // src/TestProgram.ts
9
+ var TestProgram_exports = {};
10
+ __export(TestProgram_exports, {
11
+ runProgram: () => runProgram
12
+ });
13
+
14
+ export {
15
+ TestProgram_exports
16
+ };
@@ -0,0 +1,132 @@
1
+ import {
2
+ assertSignal,
3
+ assertState,
4
+ waitUntil
5
+ } from "./chunk-DU6VSL4D.js";
6
+ import {
7
+ make
8
+ } from "./chunk-RG24KSEB.js";
9
+
10
+ // src/internal/api/TestProgram.ts
11
+ import { Chunk, Clock, Effect, Layer, Ref, Scope, Stream, TestClock, TestContext } from "effect";
12
+ import * as Logix from "@logixjs/core";
13
+ var defaultOptions = (options) => {
14
+ const base = options ?? {};
15
+ const userLayer = base.layer ?? Layer.empty;
16
+ const layer = Layer.mergeAll(TestContext.TestContext, userLayer);
17
+ return {
18
+ ...base,
19
+ layer,
20
+ handleSignals: base.handleSignals ?? false
21
+ };
22
+ };
23
+ var makeTestApi = (ctx, actionsRef) => {
24
+ const assertStateEffect = (predicate, options) => Effect.gen(function* () {
25
+ const check = Effect.flatMap(ctx.module.getState, (s) => assertState(s, predicate));
26
+ yield* waitUntil(check, options);
27
+ });
28
+ const assertSignalEffect = (expectedType, expectedPayload, options) => Effect.gen(function* () {
29
+ const check = Effect.flatMap(
30
+ Ref.get(actionsRef),
31
+ (actions) => Effect.sync(() => {
32
+ for (const actual of Chunk.toReadonlyArray(actions)) {
33
+ const exit = Effect.runSyncExit(assertSignal(actual, expectedType, expectedPayload));
34
+ if (exit._tag === "Success") {
35
+ return;
36
+ }
37
+ }
38
+ throw new Error(
39
+ `Signal assertion failed: expected type=${expectedType}, payload=${JSON.stringify(expectedPayload)}`
40
+ );
41
+ })
42
+ );
43
+ yield* waitUntil(check, options);
44
+ });
45
+ return {
46
+ ctx,
47
+ dispatch: ctx.module.dispatch,
48
+ advance: (duration) => TestClock.adjust(duration).pipe(Effect.asVoid),
49
+ assert: {
50
+ state: assertStateEffect,
51
+ signal: assertSignalEffect
52
+ }
53
+ };
54
+ };
55
+ var startTraceCollectors = (ctx, traceRef, actionsRef) => Effect.gen(function* () {
56
+ yield* Stream.runForEach(
57
+ ctx.module.actions$,
58
+ (action) => Effect.gen(function* () {
59
+ const timestamp = yield* Clock.currentTimeMillis;
60
+ const event = { _tag: "Action", action, timestamp };
61
+ yield* Ref.update(traceRef, Chunk.append(event));
62
+ yield* Ref.update(actionsRef, Chunk.append(action));
63
+ })
64
+ ).pipe(Effect.forkScoped, Scope.extend(ctx.scope));
65
+ yield* Stream.runForEach(
66
+ ctx.module.changes((s) => s),
67
+ (state) => Effect.gen(function* () {
68
+ const timestamp = yield* Clock.currentTimeMillis;
69
+ const event = { _tag: "State", state, timestamp };
70
+ yield* Ref.update(traceRef, Chunk.append(event));
71
+ })
72
+ ).pipe(Effect.forkScoped, Scope.extend(ctx.scope));
73
+ yield* TestClock.adjust(1);
74
+ yield* Effect.yieldNow();
75
+ });
76
+ var runProgram = (program, body, options) => Effect.gen(function* () {
77
+ const traceRef = yield* Ref.make(Chunk.empty());
78
+ const actionsRef = yield* Ref.make(Chunk.empty());
79
+ const debugSink = {
80
+ record: (event) => {
81
+ if (event.type !== "lifecycle:error") {
82
+ return Effect.void;
83
+ }
84
+ return Effect.gen(function* () {
85
+ const timestamp = yield* Clock.currentTimeMillis;
86
+ const traceEvent = {
87
+ _tag: "Error",
88
+ cause: event.cause,
89
+ timestamp
90
+ };
91
+ yield* Ref.update(traceRef, Chunk.append(traceEvent));
92
+ }).pipe(Effect.asVoid);
93
+ }
94
+ };
95
+ const resolved = defaultOptions(options);
96
+ const ctx = yield* Effect.locally(Logix.Debug.internal.currentDebugSinks, [debugSink])(
97
+ Logix.Runtime.openProgram(program, resolved)
98
+ );
99
+ yield* Effect.tryPromise({
100
+ try: () => ctx.runtime.runPromise(startTraceCollectors(ctx, traceRef, actionsRef)),
101
+ catch: (e) => e
102
+ }).pipe(Effect.orDie);
103
+ const api = makeTestApi(ctx, actionsRef);
104
+ yield* Effect.tryPromise({
105
+ try: () => ctx.runtime.runPromise(body(api).pipe(Scope.extend(ctx.scope))),
106
+ catch: (e) => e
107
+ }).pipe(Effect.orDie);
108
+ yield* Effect.tryPromise({
109
+ try: () => ctx.runtime.runPromise(
110
+ Effect.gen(function* () {
111
+ yield* TestClock.adjust(1);
112
+ yield* Effect.yieldNow();
113
+ })
114
+ ),
115
+ catch: (e) => e
116
+ }).pipe(Effect.orDie);
117
+ const finalState = yield* Effect.tryPromise({
118
+ try: () => ctx.runtime.runPromise(ctx.module.getState),
119
+ catch: (e) => e
120
+ }).pipe(Effect.orDie);
121
+ const actionsChunk = yield* Ref.get(actionsRef);
122
+ const traceChunk = yield* Ref.get(traceRef);
123
+ return make(
124
+ finalState,
125
+ Chunk.toReadonlyArray(actionsChunk),
126
+ Chunk.toReadonlyArray(traceChunk)
127
+ );
128
+ });
129
+
130
+ export {
131
+ runProgram
132
+ };
@@ -0,0 +1,10 @@
1
+ // src/internal/runtime/runTest.ts
2
+ import { Effect, TestContext } from "effect";
3
+ var runTest = (effect) => {
4
+ const program = Effect.scoped(effect).pipe(Effect.provide(TestContext.TestContext));
5
+ return Effect.runPromise(program);
6
+ };
7
+
8
+ export {
9
+ runTest
10
+ };
@@ -0,0 +1,57 @@
1
+ // src/internal/utils/assertions.ts
2
+ import { Effect, Equal } from "effect";
3
+ var assertState = (actual, predicate, message) => {
4
+ return Effect.suspend(() => {
5
+ if (predicate(actual)) {
6
+ return Effect.void;
7
+ }
8
+ return Effect.fail(new Error(message || `State assertion failed. Actual: ${JSON.stringify(actual)}`));
9
+ });
10
+ };
11
+ var assertSignal = (actual, expectedType, expectedPayload) => {
12
+ return Effect.suspend(() => {
13
+ const candidate = actual;
14
+ if (candidate && typeof candidate === "object" && typeof candidate._tag === "string" && candidate._tag === expectedType) {
15
+ if (expectedPayload !== void 0) {
16
+ if (Equal.equals(candidate.payload, expectedPayload)) {
17
+ return Effect.void;
18
+ }
19
+ return Effect.fail(
20
+ new Error(
21
+ `Signal payload mismatch. Expected: ${JSON.stringify(expectedPayload)}, Actual: ${JSON.stringify(
22
+ candidate.payload
23
+ )}`
24
+ )
25
+ );
26
+ }
27
+ return Effect.void;
28
+ }
29
+ return Effect.fail(
30
+ new Error(`Signal assertion failed. Expected type: ${expectedType}, Actual: ${JSON.stringify(actual)}`)
31
+ );
32
+ });
33
+ };
34
+
35
+ // src/internal/utils/waitUntil.ts
36
+ import { Effect as Effect2, TestClock } from "effect";
37
+ var waitUntil = (check, options = {}) => Effect2.gen(function* () {
38
+ const maxAttempts = options.maxAttempts ?? 20;
39
+ const step = options.step ?? "10 millis";
40
+ let lastError;
41
+ for (let i = 0; i < maxAttempts; i++) {
42
+ const result = yield* check.pipe(Effect2.exit);
43
+ if (result._tag === "Success") {
44
+ return result.value;
45
+ }
46
+ lastError = result.cause;
47
+ yield* TestClock.adjust(step);
48
+ yield* Effect2.yieldNow();
49
+ }
50
+ return yield* Effect2.fail(lastError);
51
+ });
52
+
53
+ export {
54
+ assertState,
55
+ assertSignal,
56
+ waitUntil
57
+ };
@@ -0,0 +1,38 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __commonJS = (cb, mod) => function __require() {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
+ };
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
+ // If the importer is in node compatibility mode or this is not an ESM
25
+ // file that has been converted to a CommonJS file using a Babel-
26
+ // compatible transform (i.e. "__esModule" has not been set), then set
27
+ // "default" to the CommonJS "module.exports" for node compatibility.
28
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
+ mod
30
+ ));
31
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
32
+
33
+ export {
34
+ __commonJS,
35
+ __export,
36
+ __toESM,
37
+ __publicField
38
+ };
@@ -0,0 +1,32 @@
1
+ import {
2
+ expectActionSequence,
3
+ expectActionTag,
4
+ expectNoActionTag,
5
+ expectNoError,
6
+ getActionsByTag,
7
+ getErrors,
8
+ hasAction,
9
+ hasError,
10
+ make
11
+ } from "./chunk-RG24KSEB.js";
12
+ import {
13
+ __export
14
+ } from "./chunk-FOYMJMJR.js";
15
+
16
+ // src/Execution.ts
17
+ var Execution_exports = {};
18
+ __export(Execution_exports, {
19
+ expectActionSequence: () => expectActionSequence,
20
+ expectActionTag: () => expectActionTag,
21
+ expectNoActionTag: () => expectNoActionTag,
22
+ expectNoError: () => expectNoError,
23
+ getActionsByTag: () => getActionsByTag,
24
+ getErrors: () => getErrors,
25
+ hasAction: () => hasAction,
26
+ hasError: () => hasError,
27
+ make: () => make
28
+ });
29
+
30
+ export {
31
+ Execution_exports
32
+ };
@@ -0,0 +1,64 @@
1
+ // src/internal/api/ExecutionResult.ts
2
+ var make = (state, actions, trace) => ({
3
+ state,
4
+ actions,
5
+ trace
6
+ });
7
+ var hasAction = (result, predicate) => result.actions.some(predicate);
8
+ var getActionsByTag = (result, tag) => result.actions.filter((action) => typeof action._tag === "string" && action._tag === tag);
9
+ var hasError = (result) => result.trace.some((event) => event._tag === "Error");
10
+ var getErrors = (result) => result.trace.filter((event) => event._tag === "Error");
11
+ var actionTagOf = (action) => {
12
+ const value = action;
13
+ if (typeof value?._tag === "string") {
14
+ return value._tag;
15
+ }
16
+ if (typeof value?.type === "string") {
17
+ return value.type;
18
+ }
19
+ return void 0;
20
+ };
21
+ var expectActionTag = (result, tag, options = {}) => {
22
+ const actions = getActionsByTag(result, tag);
23
+ if (actions.length === 0) {
24
+ throw new Error(`Expected at least one action with tag "${tag}", but found none.`);
25
+ }
26
+ if (options.times !== void 0 && actions.length !== options.times) {
27
+ throw new Error(`Expected ${options.times} actions with tag "${tag}", but found ${actions.length}.`);
28
+ }
29
+ };
30
+ var expectNoActionTag = (result, tag) => {
31
+ const actions = getActionsByTag(result, tag);
32
+ if (actions.length > 0) {
33
+ throw new Error(`Expected no actions with tag "${tag}", but found ${actions.length}.`);
34
+ }
35
+ };
36
+ var expectActionSequence = (result, tags) => {
37
+ const actualTags = result.actions.map((action) => actionTagOf(action)).filter((tag) => typeof tag === "string");
38
+ if (actualTags.length !== tags.length) {
39
+ throw new Error(`Expected action tag sequence [${tags.join(", ")}], but got [${actualTags.join(", ")}].`);
40
+ }
41
+ for (let i = 0; i < tags.length; i++) {
42
+ if (actualTags[i] !== tags[i]) {
43
+ throw new Error(`Expected action tag sequence [${tags.join(", ")}], but got [${actualTags.join(", ")}].`);
44
+ }
45
+ }
46
+ };
47
+ var expectNoError = (result) => {
48
+ const errors = getErrors(result);
49
+ if (errors.length > 0) {
50
+ throw new Error(`Expected no errors, but found ${errors.length}. First error cause: ${String(errors[0]?.cause)}`);
51
+ }
52
+ };
53
+
54
+ export {
55
+ make,
56
+ hasAction,
57
+ getActionsByTag,
58
+ hasError,
59
+ getErrors,
60
+ expectActionTag,
61
+ expectNoActionTag,
62
+ expectActionSequence,
63
+ expectNoError
64
+ };