@shivaedev/test-story 0.0.0 → 0.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.
Files changed (90) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/LICENSE +21 -0
  3. package/README.md +284 -1
  4. package/dist/genreTags.d.ts +6 -0
  5. package/dist/genreTags.d.ts.map +1 -0
  6. package/dist/genreTags.js +5 -0
  7. package/dist/genreTags.js.map +1 -0
  8. package/dist/internal/callSite.d.ts +3 -0
  9. package/dist/internal/callSite.d.ts.map +1 -0
  10. package/dist/internal/callSite.js +17 -0
  11. package/dist/internal/callSite.js.map +1 -0
  12. package/dist/internal/engineSnapshot.d.ts +4 -0
  13. package/dist/internal/engineSnapshot.d.ts.map +1 -0
  14. package/dist/internal/engineSnapshot.js +36 -0
  15. package/dist/internal/engineSnapshot.js.map +1 -0
  16. package/dist/internal/errors.d.ts +5 -0
  17. package/dist/internal/errors.d.ts.map +1 -0
  18. package/dist/internal/errors.js +15 -0
  19. package/dist/internal/errors.js.map +1 -0
  20. package/dist/internal/failureReport.d.ts +8 -0
  21. package/dist/internal/failureReport.d.ts.map +1 -0
  22. package/dist/internal/failureReport.js +41 -0
  23. package/dist/internal/failureReport.js.map +1 -0
  24. package/dist/internal/genre.d.ts +7 -0
  25. package/dist/internal/genre.d.ts.map +1 -0
  26. package/dist/internal/genre.js +8 -0
  27. package/dist/internal/genre.js.map +1 -0
  28. package/dist/internal/hooked.d.ts +7 -0
  29. package/dist/internal/hooked.d.ts.map +1 -0
  30. package/dist/internal/hooked.js +11 -0
  31. package/dist/internal/hooked.js.map +1 -0
  32. package/dist/internal/narration.d.ts +25 -0
  33. package/dist/internal/narration.d.ts.map +1 -0
  34. package/dist/internal/narration.js +34 -0
  35. package/dist/internal/narration.js.map +1 -0
  36. package/dist/internal/render.d.ts +8 -0
  37. package/dist/internal/render.d.ts.map +1 -0
  38. package/dist/internal/render.js +56 -0
  39. package/dist/internal/render.js.map +1 -0
  40. package/dist/internal/runUntil.d.ts +17 -0
  41. package/dist/internal/runUntil.d.ts.map +1 -0
  42. package/dist/internal/runUntil.js +24 -0
  43. package/dist/internal/runUntil.js.map +1 -0
  44. package/dist/internal/seed.d.ts +29 -0
  45. package/dist/internal/seed.d.ts.map +1 -0
  46. package/dist/internal/seed.js +27 -0
  47. package/dist/internal/seed.js.map +1 -0
  48. package/dist/internal/start.d.ts +7 -0
  49. package/dist/internal/start.d.ts.map +1 -0
  50. package/dist/internal/start.js +23 -0
  51. package/dist/internal/start.js.map +1 -0
  52. package/dist/internal/storyIt.d.ts +16 -0
  53. package/dist/internal/storyIt.d.ts.map +1 -0
  54. package/dist/internal/storyIt.js +51 -0
  55. package/dist/internal/storyIt.js.map +1 -0
  56. package/dist/internal/traits.d.ts +12 -0
  57. package/dist/internal/traits.d.ts.map +1 -0
  58. package/dist/internal/traits.js +8 -0
  59. package/dist/internal/traits.js.map +1 -0
  60. package/dist/internal/wrap.d.ts +8 -0
  61. package/dist/internal/wrap.d.ts.map +1 -0
  62. package/dist/internal/wrap.js +49 -0
  63. package/dist/internal/wrap.js.map +1 -0
  64. package/dist/storyKit.d.ts +67 -0
  65. package/dist/storyKit.d.ts.map +1 -0
  66. package/dist/storyKit.js +11 -0
  67. package/dist/storyKit.js.map +1 -0
  68. package/docs/north-star.md +35 -0
  69. package/docs/roadmap.md +23 -0
  70. package/package.json +67 -3
  71. package/src/genreTags.ts +10 -0
  72. package/src/internal/callSite.ts +19 -0
  73. package/src/internal/engineSnapshot.ts +48 -0
  74. package/src/internal/errors.ts +39 -0
  75. package/src/internal/failureReport.ts +55 -0
  76. package/src/internal/genre.ts +14 -0
  77. package/src/internal/hooked.ts +22 -0
  78. package/src/internal/narration.ts +57 -0
  79. package/src/internal/render.ts +69 -0
  80. package/src/internal/runUntil.ts +43 -0
  81. package/src/internal/seed.ts +56 -0
  82. package/src/internal/start.ts +24 -0
  83. package/src/internal/storyIt.ts +68 -0
  84. package/src/internal/traits.ts +20 -0
  85. package/src/internal/wrap.ts +50 -0
  86. package/src/storyKit.ts +130 -0
  87. package/login.log +0 -26
  88. package/publish.log +0 -0
  89. package/run.out +0 -26
  90. package/run.sh +0 -10
@@ -0,0 +1,25 @@
1
+ import type { TestContext } from "vitest";
2
+ export interface Refusal {
3
+ readonly cause: unknown;
4
+ readonly index: number;
5
+ }
6
+ export interface Narration {
7
+ at: Error | undefined;
8
+ given: number;
9
+ readonly lines: string[];
10
+ refused: Refusal | undefined;
11
+ readonly sites: Error[];
12
+ readonly tell: (line: string) => void;
13
+ readonly tellAt: (line: string, site: Error) => void;
14
+ }
15
+ export interface Subject<TEngine> {
16
+ readonly engine: TEngine;
17
+ readonly inspect: ((engine: TEngine) => unknown) | undefined;
18
+ readonly name: string;
19
+ }
20
+ export declare function narrate<TEngine>(subject: Subject<TEngine>, { onTestFailed }: Pick<TestContext, "onTestFailed">): Narration;
21
+ export declare function tellGiven(narration: Narration, given: readonly {
22
+ readonly line: string;
23
+ readonly site: Error;
24
+ }[]): void;
25
+ //# sourceMappingURL=narration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"narration.d.ts","sourceRoot":"","sources":["../../src/internal/narration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAK1C,MAAM,WAAW,OAAO;IACvB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,SAAS;IACzB,EAAE,EAAE,KAAK,GAAG,SAAS,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;IACzB,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,KAAK,IAAI,CAAC;CACrD;AAED,MAAM,WAAW,OAAO,CAAC,OAAO;IAC/B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,GAAG,SAAS,CAAC;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,YAAY,EAAE,EAAE,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,SAAS,CAuB1H;AAED,wBAAgB,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAA;CAAE,EAAE,GAAG,IAAI,CAKvH"}
@@ -0,0 +1,34 @@
1
+ import { callSite } from "#internal/callSite.ts";
2
+ import { failureReport } from "#internal/failureReport.ts";
3
+ import { describeFailure } from "#internal/render.ts";
4
+ export function narrate(subject, { onTestFailed }) {
5
+ const narration = {
6
+ at: undefined,
7
+ given: 0,
8
+ lines: [],
9
+ refused: undefined,
10
+ sites: [],
11
+ tell: (line) => {
12
+ narration.tellAt(line, callSite());
13
+ },
14
+ tellAt: (line, site) => {
15
+ narration.lines.push(line);
16
+ narration.sites.push(site);
17
+ narration.at = site;
18
+ },
19
+ };
20
+ onTestFailed(({ task }) => {
21
+ const failure = task.result?.errors?.[0];
22
+ if (failure !== undefined) {
23
+ failure.message = `${failure.message === "" ? describeFailure(failure) : failure.message}\n\n${failureReport(narration, subject, { file: task.file.filepath, name: task.name, stack: failure.stack })}`;
24
+ }
25
+ });
26
+ return narration;
27
+ }
28
+ export function tellGiven(narration, given) {
29
+ for (const part of given) {
30
+ narration.tellAt(part.line, part.site);
31
+ }
32
+ narration.given = given.length;
33
+ }
34
+ //# sourceMappingURL=narration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"narration.js","sourceRoot":"","sources":["../../src/internal/narration.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAuBtD,MAAM,UAAU,OAAO,CAAU,OAAyB,EAAE,EAAE,YAAY,EAAqC;IAC9G,MAAM,SAAS,GAAc;QAC5B,EAAE,EAAE,SAAS;QACb,KAAK,EAAE,CAAC;QACR,KAAK,EAAE,EAAE;QACT,OAAO,EAAE,SAAS;QAClB,KAAK,EAAE,EAAE;QACT,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;YACd,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QACpC,CAAC;QACD,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE;YACtB,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3B,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC3B,SAAS,CAAC,EAAE,GAAG,IAAI,CAAC;QACrB,CAAC;KACD,CAAC;IACF,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;QACzC,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,CAAC,OAAO,GAAG,GAAG,OAAO,CAAC,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,OAAO,aAAa,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC;QACzM,CAAC;IACF,CAAC,CAAC,CAAC;IACH,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,SAAoB,EAAE,KAAiE;IAChH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,CAAC;IACD,SAAS,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;AAChC,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare function describeValue(value: unknown): string;
2
+ export declare function describeFailure(failure: {
3
+ readonly _tag?: unknown;
4
+ readonly message: string;
5
+ readonly name?: string;
6
+ }): string;
7
+ export declare function toJson(value: unknown, indent?: number): string;
8
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/internal/render.ts"],"names":[],"mappings":"AAKA,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAQpD;AAOD,wBAAgB,eAAe,CAAC,OAAO,EAAE;IAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAO9H;AAYD,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CA6B9D"}
@@ -0,0 +1,56 @@
1
+ const OWN_ERROR_KEYS = new Set(["_tag", "cause", "message", "name", "stack"]);
2
+ // Vitest serializes a failure's class into these keys.
3
+ const SERIALIZED_KEYS = new Set(["constructor", "toString"]);
4
+ export function describeValue(value) {
5
+ if (typeof value === "string") {
6
+ return value;
7
+ }
8
+ if (value instanceof Error) {
9
+ return describeError(value);
10
+ }
11
+ return typeof value === "object" && value !== null ? toJson(value) : String(value);
12
+ }
13
+ function describeError(error) {
14
+ const tag = "_tag" in error && typeof error._tag === "string" ? error._tag : error.name;
15
+ return describeTagged(tag, error.message, Object.entries(error));
16
+ }
17
+ export function describeFailure(failure) {
18
+ const tag = typeof failure._tag === "string" ? failure._tag : (failure.name ?? "Error");
19
+ return describeTagged(tag, failure.message, Object.entries(failure).filter(([key]) => !SERIALIZED_KEYS.has(key)));
20
+ }
21
+ function describeTagged(tag, message, entries) {
22
+ const fields = Object.fromEntries(entries.filter(([key]) => !OWN_ERROR_KEYS.has(key)));
23
+ const label = tag === "Error" ? "" : tag;
24
+ const detail = Object.keys(fields).length === 0 ? "" : toJson(fields);
25
+ if (message === "") {
26
+ return [label, detail].filter((part) => part !== "").join(" ") || "Error";
27
+ }
28
+ return [label === "" ? message : `${label}: ${message}`, detail].filter((part) => part !== "").join(" ");
29
+ }
30
+ export function toJson(value, indent) {
31
+ const seen = new WeakSet();
32
+ const json = JSON.stringify(value, (_key, item) => {
33
+ if (typeof item === "bigint") {
34
+ return `${item}n`;
35
+ }
36
+ if (typeof item === "symbol") {
37
+ return item.toString();
38
+ }
39
+ if (item instanceof Error) {
40
+ return describeError(item);
41
+ }
42
+ if (typeof item !== "object" || item === null) {
43
+ return item;
44
+ }
45
+ if (seen.has(item)) {
46
+ return "[shown above]";
47
+ }
48
+ seen.add(item);
49
+ if (item instanceof Map) {
50
+ return Object.fromEntries([...item].map(([key, entry]) => [describeValue(key), entry]));
51
+ }
52
+ return item instanceof Set ? [...item] : item;
53
+ }, indent);
54
+ return json ?? String(value);
55
+ }
56
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../../src/internal/render.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { Effect } from "effect";
2
+ import { type AnyEffect, type Hook } from "#internal/hooked.ts";
3
+ import type { RunUntilOptions } from "#storyKit.ts";
4
+ export interface LooseRunHooks<TEngine> {
5
+ readonly diagnose?: Hook<[engine: TEngine], AnyEffect, string>;
6
+ readonly failed?: Hook<[engine: TEngine], AnyEffect, string | undefined>;
7
+ readonly maxSteps: number;
8
+ readonly step: Hook<[engine: TEngine, tell: (line: string) => void], AnyEffect, void>;
9
+ }
10
+ export interface Running<TEngine> {
11
+ readonly engine: TEngine;
12
+ readonly name: string;
13
+ readonly run: LooseRunHooks<TEngine> | undefined;
14
+ readonly tell: (line: string) => void;
15
+ }
16
+ export declare const runUntil: <TEngine>(args_0: Running<TEngine>, until: Hook<[engine: TEngine], AnyEffect, boolean>, options: RunUntilOptions | undefined) => Effect.Effect<undefined, unknown, unknown>;
17
+ //# sourceMappingURL=runUntil.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runUntil.d.ts","sourceRoot":"","sources":["../../src/internal/runUntil.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,IAAI,EAAU,MAAM,qBAAqB,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,WAAW,aAAa,CAAC,OAAO;IACrC,QAAQ,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IAC/D,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;CACtF;AAED,MAAM,WAAW,OAAO,CAAC,OAAO;IAC/B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC;IACjD,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,eAAO,MAAM,QAAQ,GAAgC,OAAO,mKAuB1D,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { Effect } from "effect";
2
+ import { broken, cannotRun, unfinished } from "#internal/errors.ts";
3
+ import { hooked } from "#internal/hooked.ts";
4
+ export const runUntil = Effect.fnUntraced(function* ({ engine, name, run, tell }, until, options) {
5
+ if (run === undefined) {
6
+ return yield* Effect.die(cannotRun(name));
7
+ }
8
+ const { diagnose, failed, step } = run;
9
+ const maxSteps = options?.maxSteps ?? run.maxSteps;
10
+ for (let steps = 0;; steps += 1) {
11
+ const reason = failed === undefined ? undefined : yield* hooked(() => failed(engine));
12
+ if (reason !== undefined) {
13
+ return yield* Effect.die(broken(name, steps, reason));
14
+ }
15
+ if (yield* hooked(() => until(engine))) {
16
+ return;
17
+ }
18
+ if (steps >= maxSteps) {
19
+ return yield* Effect.die(unfinished(name, steps, diagnose === undefined ? undefined : yield* hooked(() => diagnose(engine))));
20
+ }
21
+ yield* hooked(() => step(engine, tell));
22
+ }
23
+ });
24
+ //# sourceMappingURL=runUntil.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runUntil.js","sourceRoot":"","sources":["../../src/internal/runUntil.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAA6B,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAiBxE,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAClD,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAoB,EAC7C,KAAkD,EAClD,OAAoC;IAEpC,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3C,CAAC;IACD,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC;IACvC,MAAM,QAAQ,GAAG,OAAO,EAAE,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC;IACnD,KAAK,IAAI,KAAK,GAAG,CAAC,GAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QACtF,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;YACxC,OAAO;QACR,CAAC;QACD,IAAI,KAAK,IAAI,QAAQ,EAAE,CAAC;YACvB,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/H,CAAC;QACD,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IACzC,CAAC;AACF,CAAC,CAAC,CAAC"}
@@ -0,0 +1,29 @@
1
+ import { Effect, type Scope } from "effect";
2
+ import type { AnyTestLayer } from "@shivaedev/effect-test/any-test-layer.ts";
3
+ import type { EffectClock } from "@shivaedev/effect-test/types.ts";
4
+ import { type AnyEffect, type Hook } from "#internal/hooked.ts";
5
+ import { type Narration } from "#internal/narration.ts";
6
+ import type { LooseRunHooks } from "#internal/runUntil.ts";
7
+ import type { Parts } from "#internal/traits.ts";
8
+ import type { RunUntilOptions } from "#storyKit.ts";
9
+ export type LooseTrait = Parts<string, (engine: unknown) => Effect.Effect<void, unknown, unknown>>;
10
+ export interface LooseStory {
11
+ readonly engine: unknown;
12
+ readonly lines: readonly string[];
13
+ readonly runUntil: (until: Hook<[engine: unknown], AnyEffect, boolean>, options?: RunUntilOptions) => Effect.Effect<void, unknown, unknown>;
14
+ readonly tell: (line: string) => void;
15
+ }
16
+ export interface LooseDefinition {
17
+ readonly after?: Readonly<Partial<Record<string, Hook<[engine: unknown], AnyEffect, void>>>>;
18
+ readonly around?: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, unknown, R | Scope.Scope>;
19
+ readonly clock?: EffectClock;
20
+ readonly create: Hook<[], AnyEffect, unknown>;
21
+ readonly inspect?: (engine: unknown) => unknown;
22
+ readonly layer?: AnyTestLayer;
23
+ readonly name: string;
24
+ readonly run?: LooseRunHooks<unknown>;
25
+ readonly stages: readonly string[];
26
+ readonly verbs: (engine: unknown, story: LooseStory) => object;
27
+ }
28
+ export declare const seed: (definition: LooseDefinition, engine: unknown, narration: Narration, given: readonly LooseTrait[]) => Effect.Effect<void, unknown, unknown>;
29
+ //# sourceMappingURL=seed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../../src/internal/seed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,MAAM,EAAE,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAC7E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAC;AAEnE,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,IAAI,EAAU,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,KAAK,SAAS,EAAa,MAAM,wBAAwB,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,MAAM,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AAEnG,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,eAAe,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC5I,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7F,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAC1G,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAC9C,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC;IAChD,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,KAAK,MAAM,CAAC;CAC/D;AAED,eAAO,MAAM,IAAI,6IAuBf,CAAC"}
@@ -0,0 +1,27 @@
1
+ import { Cause, Effect } from "effect";
2
+ import { refusal } from "#internal/errors.ts";
3
+ import { hooked } from "#internal/hooked.ts";
4
+ import { tellGiven } from "#internal/narration.ts";
5
+ export const seed = Effect.fnUntraced(function* (definition, engine, narration, given) {
6
+ const parts = given.flatMap((each) => each.parts);
7
+ tellGiven(narration, parts);
8
+ for (const stage of definition.stages) {
9
+ for (const [index, part] of parts.entries()) {
10
+ if (part.stage === stage) {
11
+ yield* Effect.suspend(() => part.apply(engine)).pipe(Effect.catchCause((cause) => {
12
+ if (Cause.hasInterruptsOnly(cause)) {
13
+ return Effect.interrupt;
14
+ }
15
+ const thrown = Cause.squash(cause);
16
+ narration.refused = { cause: thrown, index };
17
+ return Effect.die(refusal(definition.name, part.line, thrown));
18
+ }));
19
+ }
20
+ }
21
+ const after = definition.after?.[stage];
22
+ if (after !== undefined) {
23
+ yield* hooked(() => after(engine));
24
+ }
25
+ }
26
+ });
27
+ //# sourceMappingURL=seed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed.js","sourceRoot":"","sources":["../../src/internal/seed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAc,MAAM,QAAQ,CAAC;AAGnD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAA6B,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAkB,SAAS,EAAE,MAAM,wBAAwB,CAAC;AA2BnE,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,UAA2B,EAAE,MAAe,EAAE,SAAoB,EAAE,KAA4B;IAChJ,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClD,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC5B,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC;QACvC,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;YAC7C,IAAI,IAAI,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;gBAC1B,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CACnD,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,EAAE;oBAC3B,IAAI,KAAK,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;wBACpC,OAAO,MAAM,CAAC,SAAS,CAAC;oBACzB,CAAC;oBACD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBACnC,SAAS,CAAC,OAAO,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;oBAC7C,OAAO,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;gBAChE,CAAC,CAAC,CACF,CAAC;YACH,CAAC;QACF,CAAC;QACD,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;QACxC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACzB,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QACpC,CAAC;IACF,CAAC;AACF,CAAC,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { Effect } from "effect";
2
+ import type { TestContext } from "vitest";
3
+ import { type LooseDefinition, type LooseStory, type LooseTrait } from "#internal/seed.ts";
4
+ export declare const start: (definition: LooseDefinition, given: readonly LooseTrait[], context: TestContext) => Effect.Effect<{
5
+ story: LooseStory;
6
+ }, unknown, unknown>;
7
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/internal/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAK1C,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,UAAU,EAAE,KAAK,UAAU,EAAQ,MAAM,mBAAmB,CAAC;AAEjG,eAAO,MAAM,KAAK;;oBAehB,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { Effect } from "effect";
2
+ import { callSite } from "#internal/callSite.ts";
3
+ import { hooked } from "#internal/hooked.ts";
4
+ import { narrate } from "#internal/narration.ts";
5
+ import { runUntil } from "#internal/runUntil.ts";
6
+ import { seed } from "#internal/seed.ts";
7
+ export const start = Effect.fnUntraced(function* (definition, given, context) {
8
+ const engine = yield* hooked(definition.create);
9
+ const narration = narrate({ engine, inspect: definition.inspect, name: definition.name }, context);
10
+ yield* seed(definition, engine, narration, given);
11
+ const story = {
12
+ engine,
13
+ lines: narration.lines,
14
+ runUntil: (until, options) => {
15
+ const site = callSite();
16
+ narration.at = site;
17
+ return runUntil({ engine, name: definition.name, run: definition.run, tell: (line) => narration.tellAt(line, site) }, until, options);
18
+ },
19
+ tell: narration.tell,
20
+ };
21
+ return { ...definition.verbs(engine, story), story };
22
+ });
23
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/internal/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAA0D,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEjG,MAAM,CAAC,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,UAA2B,EAAE,KAA4B,EAAE,OAAoB;IAChI,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,SAAS,GAAG,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,OAAO,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,EAAE,OAAO,CAAC,CAAC;IACnG,KAAK,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;IAClD,MAAM,KAAK,GAAe;QACzB,MAAM;QACN,KAAK,EAAE,SAAS,CAAC,KAAK;QACtB,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YAC5B,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;YACxB,SAAS,CAAC,EAAE,GAAG,IAAI,CAAC;YACpB,OAAO,QAAQ,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,UAAU,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QACvI,CAAC;QACD,IAAI,EAAE,SAAS,CAAC,IAAI;KACpB,CAAC;IACF,OAAO,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC;AACtD,CAAC,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { TestContext } from "@effect/vitest";
2
+ import type { EffectTestOptions } from "@shivaedev/effect-test/types.ts";
3
+ import { type AnyEffect } from "#internal/hooked.ts";
4
+ import type { LooseDefinition, LooseTrait } from "#internal/seed.ts";
5
+ type LooseBody = (told: object, context: TestContext) => Generator<AnyEffect, unknown, never> | undefined;
6
+ type LooseTest = (name: string, given: readonly LooseTrait[], body?: LooseBody, options?: number | EffectTestOptions) => void;
7
+ export interface LooseIt extends LooseTest {
8
+ readonly fails: LooseTest;
9
+ readonly only: LooseTest;
10
+ readonly runIf: (condition: unknown) => LooseTest;
11
+ readonly skip: LooseTest;
12
+ readonly skipIf: (condition: unknown) => LooseTest;
13
+ }
14
+ export declare function storyIt(definition: LooseDefinition): LooseIt;
15
+ export {};
16
+ //# sourceMappingURL=storyIt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storyIt.d.ts","sourceRoot":"","sources":["../../src/internal/storyIt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,KAAK,EAAc,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAGrF,OAAO,EAAE,KAAK,SAAS,EAAU,MAAM,qBAAqB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGrE,KAAK,SAAS,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,KAAK,SAAS,CAAC,SAAS,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,SAAS,CAAC;AAE1G,KAAK,SAAS,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,UAAU,EAAE,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,iBAAiB,KAAK,IAAI,CAAC;AAE9H,MAAM,WAAW,OAAQ,SAAQ,SAAS;IACzC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,SAAS,CAAC;IAClD,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,SAAS,CAAC;CACnD;AAiCD,wBAAgB,OAAO,CAAC,UAAU,EAAE,eAAe,GAAG,OAAO,CAe5D"}
@@ -0,0 +1,51 @@
1
+ import { Effect, Layer } from "effect";
2
+ import { makeEffectIt } from "@shivaedev/effect-test/vitest.ts";
3
+ import { genreOf } from "#internal/genre.ts";
4
+ import { hooked } from "#internal/hooked.ts";
5
+ import { start } from "#internal/start.ts";
6
+ function withTags(options, tags) {
7
+ if (typeof options === "number") {
8
+ return { tags: [...tags], timeout: options };
9
+ }
10
+ const own = options?.tags ?? [];
11
+ return { ...options, tags: [...tags, ...(typeof own === "string" ? [own] : own)] };
12
+ }
13
+ function storyOf(definition, given, body) {
14
+ return function* story(_harness, context) {
15
+ const told = yield* start(definition, given, context);
16
+ return yield* hooked(() => body?.(told, context));
17
+ };
18
+ }
19
+ // Vitest refuses a tag its config does not declare, so a genre the config leaves out names the test without tagging it.
20
+ function declaring(definition, genre, declare) {
21
+ return (name, given, body, options) => {
22
+ const title = `${genre.title}: ${name}`;
23
+ const story = storyOf(definition, given, body);
24
+ try {
25
+ declare(title, story, withTags(options, [genre.tag.name]));
26
+ }
27
+ catch (error) {
28
+ if (!(error instanceof Error && error.message.includes(`"${genre.tag.name}"`))) {
29
+ throw error;
30
+ }
31
+ declare(title, story, withTags(options, []));
32
+ }
33
+ };
34
+ }
35
+ export function storyIt(definition) {
36
+ const genre = genreOf(definition.name);
37
+ const { effectApp } = makeEffectIt({
38
+ around: definition.around,
39
+ clock: definition.clock,
40
+ layer: definition.layer ?? Layer.empty,
41
+ makeHarness: () => Effect.void,
42
+ });
43
+ return Object.assign(declaring(definition, genre, effectApp), {
44
+ fails: declaring(definition, genre, effectApp.fails),
45
+ only: declaring(definition, genre, effectApp.only),
46
+ runIf: (condition) => declaring(definition, genre, effectApp.runIf(condition)),
47
+ skip: declaring(definition, genre, effectApp.skip),
48
+ skipIf: (condition) => declaring(definition, genre, effectApp.skipIf(condition)),
49
+ });
50
+ }
51
+ //# sourceMappingURL=storyIt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storyIt.js","sourceRoot":"","sources":["../../src/internal/storyIt.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAEvC,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAc,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAkB,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAc3C,SAAS,QAAQ,CAAC,OAA+C,EAAE,IAAuB;IACzF,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;IAC9C,CAAC;IACD,MAAM,GAAG,GAAG,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;IAChC,OAAO,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;AACpF,CAAC;AAED,SAAS,OAAO,CAAC,UAA2B,EAAE,KAA4B,EAAE,IAA2B;IACtG,OAAO,QAAQ,CAAC,CAAC,KAAK,CAAC,QAAiB,EAAE,OAAoB;QAC7D,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QACtD,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,CAAC,CAAC;AACH,CAAC;AAED,wHAAwH;AACxH,SAAS,SAAS,CAAC,UAA2B,EAAE,KAAY,EAAE,OAAqC;IAClG,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,GAAG,KAAK,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC;YACJ,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC;gBAChF,MAAM,KAAK,CAAC;YACb,CAAC;YACD,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;QAC9C,CAAC;IACF,CAAC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,UAA2B;IAClD,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC;QAClC,MAAM,EAAE,UAAU,CAAC,MAAM;QACzB,KAAK,EAAE,UAAU,CAAC,KAAK;QACvB,KAAK,EAAE,UAAU,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK;QACtC,WAAW,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI;KAC9B,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,KAAK,EAAE,SAAS,CAAC,EAAE;QAC7D,KAAK,EAAE,SAAS,CAAC,UAAU,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC;QACpD,IAAI,EAAE,SAAS,CAAC,UAAU,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC;QAClD,KAAK,EAAE,CAAC,SAAkB,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,KAAK,EAAE,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACvF,IAAI,EAAE,SAAS,CAAC,UAAU,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC;QAClD,MAAM,EAAE,CAAC,SAAkB,EAAE,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;KACzF,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ export interface TraitPart<TStage extends string, TApply> {
2
+ readonly apply: TApply;
3
+ readonly line: string;
4
+ readonly site: Error;
5
+ readonly stage: TStage;
6
+ }
7
+ export interface Parts<TStage extends string, TApply> {
8
+ readonly parts: readonly TraitPart<TStage, TApply>[];
9
+ }
10
+ export declare function trait<TStage extends string, TApply>(stage: TStage, line: string, apply: TApply): Parts<TStage, TApply>;
11
+ export declare function traits<TStage extends string, TApply>(...given: readonly Parts<TStage, TApply>[]): Parts<TStage, TApply>;
12
+ //# sourceMappingURL=traits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traits.d.ts","sourceRoot":"","sources":["../../src/internal/traits.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS,CAAC,MAAM,SAAS,MAAM,EAAE,MAAM;IACvD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,KAAK,CAAC,MAAM,SAAS,MAAM,EAAE,MAAM;IACnD,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;CACrD;AAED,wBAAgB,KAAK,CAAC,MAAM,SAAS,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAEtH;AAED,wBAAgB,MAAM,CAAC,MAAM,SAAS,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,SAAS,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAEvH"}
@@ -0,0 +1,8 @@
1
+ import { callSite } from "#internal/callSite.ts";
2
+ export function trait(stage, line, apply) {
3
+ return { parts: [{ apply, line, site: callSite(), stage }] };
4
+ }
5
+ export function traits(...given) {
6
+ return { parts: given.flatMap((each) => each.parts) };
7
+ }
8
+ //# sourceMappingURL=traits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traits.js","sourceRoot":"","sources":["../../src/internal/traits.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAajD,MAAM,UAAU,KAAK,CAAgC,KAAa,EAAE,IAAY,EAAE,KAAa;IAC9F,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,MAAM,CAAgC,GAAG,KAAuC;IAC/F,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;AACvD,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare const WIDTH = 120;
2
+ export declare function wrap(text: string, { first, rest }?: {
3
+ readonly first?: string;
4
+ readonly rest?: string;
5
+ }): string[];
6
+ export declare function explained(what: string, help: string): string;
7
+ export declare function wrapJson(json: string): string[];
8
+ //# sourceMappingURL=wrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrap.d.ts","sourceRoot":"","sources":["../../src/internal/wrap.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,KAAK,MAAM,CAAC;AAEzB,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAU,EAAE,IAAS,EAAE,GAAE;IAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,EAAE,CAahI;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5D;AAYD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAkB/C"}
@@ -0,0 +1,49 @@
1
+ export const WIDTH = 120;
2
+ export function wrap(text, { first = "", rest = "" } = {}) {
3
+ const lines = [];
4
+ let line = first;
5
+ for (const word of text.split(" ")) {
6
+ const prefix = lines.length === 0 ? first : rest;
7
+ if (line.length > prefix.length && line.length + 1 + word.length > WIDTH) {
8
+ lines.push(line);
9
+ line = `${rest}${word}`;
10
+ }
11
+ else {
12
+ line = line.length > prefix.length ? `${line} ${word}` : `${line}${word}`;
13
+ }
14
+ }
15
+ return [...lines, line];
16
+ }
17
+ export function explained(what, help) {
18
+ return [...wrap(what, { rest: " " }), ...wrap(help, { first: "help: ", rest: " " })].join("\n");
19
+ }
20
+ function members(json) {
21
+ const value = JSON.parse(json);
22
+ if (Array.isArray(value)) {
23
+ return value.map((item) => JSON.stringify(item));
24
+ }
25
+ return typeof value === "object" && value !== null
26
+ ? Object.entries(value).map(([key, item]) => `${JSON.stringify(key)}:${JSON.stringify(item)}`)
27
+ : [json];
28
+ }
29
+ export function wrapJson(json) {
30
+ const [open, close] = json.startsWith("[") ? ["[", "]"] : ["{", "}"];
31
+ const pieces = members(json);
32
+ if (pieces.length < 2) {
33
+ return [json];
34
+ }
35
+ const lines = [];
36
+ let line = open;
37
+ for (const [index, piece] of pieces.entries()) {
38
+ const next = `${piece}${index === pieces.length - 1 ? close : ","}`;
39
+ if (line.length > 1 && line.length + next.length > WIDTH) {
40
+ lines.push(line);
41
+ line = next;
42
+ }
43
+ else {
44
+ line += next;
45
+ }
46
+ }
47
+ return [...lines, line];
48
+ }
49
+ //# sourceMappingURL=wrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrap.js","sourceRoot":"","sources":["../../src/internal/wrap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import type { TestContext } from "@effect/vitest";
2
+ import type { Effect, Layer, Scope } from "effect";
3
+ import type { EffectClock, EffectTestOptions } from "@shivaedev/effect-test/types.ts";
4
+ import { type AnyEffect, type ErrorOf, type Hook, type ServicesOf } from "#internal/hooked.ts";
5
+ import { type Parts } from "#internal/traits.ts";
6
+ export type Trait<TEngine, TStage extends string, R = never> = Parts<TStage, (engine: TEngine) => Effect.Effect<void, unknown, R>>;
7
+ type TraitServices<TTrait> = TTrait extends Parts<string, (engine: never) => Effect.Effect<void, unknown, infer R>> ? R : never;
8
+ type Needs<TProvided> = Effect.Effect<unknown, unknown, TProvided>;
9
+ type AfterEffects<TAfter> = {
10
+ readonly [TKey in keyof TAfter]-?: AnyEffect extends TAfter[TKey] ? never : TAfter[TKey];
11
+ }[keyof TAfter];
12
+ type LayerFor<THooks, TProvided> = [Exclude<ServicesOf<THooks>, Scope.Scope>] extends [TProvided] ? unknown : {
13
+ readonly layer: Layer.Layer<Exclude<ServicesOf<THooks>, Scope.Scope>, unknown, never>;
14
+ };
15
+ export interface RunUntilOptions {
16
+ readonly maxSteps?: number | undefined;
17
+ }
18
+ export interface Story<TEngine, TRun extends AnyEffect = never> {
19
+ readonly engine: TEngine;
20
+ readonly lines: readonly string[];
21
+ readonly runUntil: <TUntil extends AnyEffect = never>(until: Hook<[engine: TEngine], TUntil, boolean>, options?: RunUntilOptions) => Effect.Effect<void, ErrorOf<TRun | TUntil>, ServicesOf<TRun | TUntil>>;
22
+ readonly tell: (line: string) => void;
23
+ }
24
+ export interface RunHooks<TEngine, TStep extends AnyEffect, TFailed extends AnyEffect, TDiagnose extends AnyEffect> {
25
+ readonly diagnose?: Hook<[engine: TEngine], TDiagnose, string>;
26
+ readonly failed?: Hook<[engine: TEngine], TFailed, string | undefined>;
27
+ readonly maxSteps: number;
28
+ readonly step: Hook<[engine: TEngine, tell: (line: string) => void], TStep, void>;
29
+ }
30
+ export interface StoryKitDefinition<TEngine, TStage extends string, TVerbs, TProvided, TCreate extends AnyEffect, TAfter extends {
31
+ readonly [TKey in TStage]?: AnyEffect;
32
+ }, TStep extends AnyEffect, TFailed extends AnyEffect, TDiagnose extends AnyEffect> {
33
+ readonly after?: {
34
+ readonly [TKey in keyof TAfter]: Hook<[engine: TEngine], TAfter[TKey] & AnyEffect, void>;
35
+ };
36
+ readonly around?: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, unknown, R | NoInfer<TProvided> | Scope.Scope>;
37
+ readonly clock?: EffectClock;
38
+ readonly create: Hook<[], TCreate, TEngine>;
39
+ readonly inspect?: (engine: TEngine) => unknown;
40
+ readonly layer?: Layer.Layer<TProvided, unknown, never>;
41
+ readonly name: string;
42
+ readonly run?: RunHooks<TEngine, TStep, TFailed, TDiagnose>;
43
+ readonly stages: readonly [TStage, ...TStage[]];
44
+ readonly verbs: (engine: TEngine, story: Story<TEngine, TStep | TFailed | TDiagnose>) => TVerbs;
45
+ }
46
+ export type Told<TEngine, TVerbs, TRun extends AnyEffect> = TVerbs & {
47
+ readonly story: Story<TEngine, TRun>;
48
+ };
49
+ export type StoryBody<TEngine, TVerbs, TRun extends AnyEffect, TEffect extends AnyEffect> = (told: Told<TEngine, TVerbs, TRun>, context: TestContext) => Generator<TEffect, unknown, never> | undefined;
50
+ export type StoryTest<TEngine, TStage extends string, TVerbs, TRun extends AnyEffect, TProvided> = <TEffect extends Needs<TProvided | Scope.Scope> = never>(name: string, given: readonly Trait<TEngine, TStage, TProvided | Scope.Scope>[], body?: StoryBody<TEngine, TVerbs, TRun, TEffect>, options?: number | EffectTestOptions) => void;
51
+ export interface StoryIt<TEngine, TStage extends string, TVerbs, TRun extends AnyEffect, TProvided> extends StoryTest<TEngine, TStage, TVerbs, TRun, TProvided> {
52
+ readonly fails: StoryTest<TEngine, TStage, TVerbs, TRun, TProvided>;
53
+ readonly only: StoryTest<TEngine, TStage, TVerbs, TRun, TProvided>;
54
+ readonly runIf: (condition: unknown) => StoryTest<TEngine, TStage, TVerbs, TRun, TProvided>;
55
+ readonly skip: StoryTest<TEngine, TStage, TVerbs, TRun, TProvided>;
56
+ readonly skipIf: (condition: unknown) => StoryTest<TEngine, TStage, TVerbs, TRun, TProvided>;
57
+ }
58
+ export interface StoryKit<TEngine, TStage extends string, TVerbs, TRun extends AnyEffect, TProvided> {
59
+ readonly it: StoryIt<TEngine, TStage, TVerbs, TRun, TProvided>;
60
+ readonly trait: <TEffect extends AnyEffect = never>(stage: TStage, line: string, apply: Hook<[engine: TEngine], TEffect, void>) => Trait<TEngine, TStage, ServicesOf<TEffect>>;
61
+ readonly traits: <const TGiven extends readonly Trait<TEngine, TStage, unknown>[]>(...given: TGiven) => Trait<TEngine, TStage, TraitServices<TGiven[number]>>;
62
+ }
63
+ export declare function storyKit<TEngine, const TStage extends string, TVerbs extends object, TProvided = never, TCreate extends AnyEffect = never, TAfter extends {
64
+ readonly [TKey in TStage]?: AnyEffect;
65
+ } = Record<never, never>, TStep extends AnyEffect = never, TFailed extends AnyEffect = never, TDiagnose extends AnyEffect = never>(definition: StoryKitDefinition<TEngine, TStage, TVerbs, TProvided, TCreate, TAfter, TStep, TFailed, TDiagnose> & LayerFor<TCreate | AfterEffects<TAfter> | TStep | TFailed | TDiagnose, TProvided>): StoryKit<TEngine, TStage, TVerbs, TStep | TFailed | TDiagnose, TProvided>;
66
+ export {};
67
+ //# sourceMappingURL=storyKit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storyKit.d.ts","sourceRoot":"","sources":["../src/storyKit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { hooked } from "#internal/hooked.ts";
2
+ import { storyIt } from "#internal/storyIt.ts";
3
+ import { trait, traits } from "#internal/traits.ts";
4
+ export function storyKit(definition) {
5
+ return {
6
+ it: storyIt(definition),
7
+ trait: (stage, line, apply) => trait(stage, line, (engine) => hooked(() => apply(engine))),
8
+ traits,
9
+ };
10
+ }
11
+ //# sourceMappingURL=storyKit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storyKit.js","sourceRoot":"","sources":["../src/storyKit.ts"],"names":[],"mappings":"AAGA,OAAO,EAA2C,MAAM,EAAmB,MAAM,qBAAqB,CAAC;AAEvG,OAAO,EAAgB,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAc,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAqHhE,MAAM,UAAU,QAAQ,CAAC,UAA2B;IACnD,OAAO;QACN,EAAE,EAAE,OAAO,CAAC,UAAU,CAAC;QACvB,KAAK,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1F,MAAM;KACN,CAAC;AACH,CAAC"}