@systemfsoftware/storybook-gherkin 4.0.1 → 4.0.3

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @systemfsoftware/storybook-gherkin
2
2
 
3
+ ## 4.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Every tagged error class now has a one-line message built from its fields, so a failure shows what went wrong instead of an empty message.
8
+
9
+ - A step whose story is left mid-step (Storybook aborts the play, for example when the visit moves to another story) now always settles the promise handed to Storybook's `step`. Before, an abort that landed just as a step started could leave that promise pending, so Storybook waited on it forever.
10
+
11
+ - Update peer and runtime dependency on `effect` and companion packages to `4.0.0-rc.117`.
12
+
13
+ ## 4.0.2
14
+
15
+ ### Patch Changes
16
+
17
+ - A step whose story is left mid-step (Storybook aborts the play, for example when the visit moves to another story) now always settles the promise handed to Storybook's `step`. Before, an abort that landed just as a step started could leave that promise pending, so Storybook waited on it forever.
18
+
3
19
  ## 4.0.1
4
20
 
5
21
  ### Patch Changes
package/README.md CHANGED
@@ -20,4 +20,4 @@ The public surface is generated from the source and versioned with the package:
20
20
 
21
21
  ## License
22
22
 
23
- Apache-2.0. Part of [systemfsoftware](https://github.com/systemfsoftware/systemfsoftware/tree/main/packages/storybook-gherkin#readme).
23
+ Apache-2.0. Part of [systemfsoftware](https://github.com/systemfsoftware/systemfsoftware/tree/main/packages/gherkin/storybook-gherkin#readme).
package/dist/index.d.ts CHANGED
@@ -15,7 +15,9 @@ declare type AnyConstraintDecoder<A = unknown> = Schema.ConstraintDecoder<A>;
15
15
 
16
16
  declare type AnyValue<V = unknown> = V;
17
17
 
18
- export declare class BackgroundNotGiven extends BackgroundNotGiven_base {}
18
+ export declare class BackgroundNotGiven extends BackgroundNotGiven_base {
19
+ get message(): string;
20
+ }
19
21
 
20
22
  declare const BackgroundNotGiven_base: Schema.Class<BackgroundNotGiven, Schema.TaggedStruct<"BackgroundNotGiven", {
21
23
  readonly step: Schema.String;
@@ -51,7 +53,9 @@ export declare const capture: {
51
53
  }): Capture<Name, string>;
52
54
  };
53
55
 
54
- export declare class CaptureDecodeFailed extends CaptureDecodeFailed_base {}
56
+ export declare class CaptureDecodeFailed extends CaptureDecodeFailed_base {
57
+ get message(): string;
58
+ }
55
59
 
56
60
  declare const CaptureDecodeFailed_base: Schema.Class<CaptureDecodeFailed, Schema.TaggedStruct<"CaptureDecodeFailed", {
57
61
  readonly step: Schema.String;
@@ -75,7 +79,9 @@ declare type CaptureTag = typeof CaptureTag;
75
79
 
76
80
  export declare type ConcreteKeyword = 'Given' | 'When' | 'Then';
77
81
 
78
- export declare class DuplicateCapture extends DuplicateCapture_base {}
82
+ export declare class DuplicateCapture extends DuplicateCapture_base {
83
+ get message(): string;
84
+ }
79
85
 
80
86
  declare const DuplicateCapture_base: Schema.Class<DuplicateCapture, Schema.TaggedStruct<"DuplicateCapture", {
81
87
  readonly step: Schema.String;
@@ -90,7 +96,9 @@ declare const DuplicateCapture_base: Schema.Class<DuplicateCapture, Schema.Tagge
90
96
  * - Run time: `CaptureDecodeFailed` travels the typed error channel of
91
97
  * `Step.run` and surfaces when the play edge interprets the scenario.
92
98
  */
93
- export declare class EmptyScenario extends EmptyScenario_base {}
99
+ export declare class EmptyScenario extends EmptyScenario_base {
100
+ get message(): string;
101
+ }
94
102
 
95
103
  declare const EmptyScenario_base: Schema.Class<EmptyScenario, Schema.TaggedStruct<"EmptyScenario", {
96
104
  readonly scenario: Schema.String;
@@ -138,7 +146,9 @@ export declare type Hole = Capture | string | number;
138
146
  export declare type Keyword = 'Given' | 'When' | 'Then' | 'And' | 'But' | 'Star';
139
147
 
140
148
  /** Without a Then-phase step nothing is asserted — the scenario is not a spec. */
141
- export declare class MissingThen extends MissingThen_base {}
149
+ export declare class MissingThen extends MissingThen_base {
150
+ get message(): string;
151
+ }
142
152
 
143
153
  declare const MissingThen_base: Schema.Class<MissingThen, Schema.TaggedStruct<"MissingThen", {
144
154
  readonly scenario: Schema.String;
@@ -149,14 +159,18 @@ export declare interface OutlineBuilder<TArgs> {
149
159
  }
150
160
 
151
161
  /** Row names become the exported story names, so duplicates would collide. */
152
- export declare class OutlineDuplicateRowName extends OutlineDuplicateRowName_base {}
162
+ export declare class OutlineDuplicateRowName extends OutlineDuplicateRowName_base {
163
+ get message(): string;
164
+ }
153
165
 
154
166
  declare const OutlineDuplicateRowName_base: Schema.Class<OutlineDuplicateRowName, Schema.TaggedStruct<"OutlineDuplicateRowName", {
155
167
  readonly outline: Schema.String;
156
168
  readonly name: Schema.String;
157
169
  }>, YieldableError>;
158
170
 
159
- export declare class OutlineEmpty extends OutlineEmpty_base {}
171
+ export declare class OutlineEmpty extends OutlineEmpty_base {
172
+ get message(): string;
173
+ }
160
174
 
161
175
  declare const OutlineEmpty_base: Schema.Class<OutlineEmpty, Schema.TaggedStruct<"OutlineEmpty", {
162
176
  readonly outline: Schema.String;
@@ -167,7 +181,9 @@ export declare interface OutlineFn<TArgs> {
167
181
  <TName extends string>(name: ScenarioTitle<TName>, options: ScenarioOptions, ...steps: readonly StepArg<TArgs>[]): OutlineBuilder<TArgs>;
168
182
  }
169
183
 
170
- export declare class OutlineInconsistentKeys extends OutlineInconsistentKeys_base {}
184
+ export declare class OutlineInconsistentKeys extends OutlineInconsistentKeys_base {
185
+ get message(): string;
186
+ }
171
187
 
172
188
  declare const OutlineInconsistentKeys_base: Schema.Class<OutlineInconsistentKeys, Schema.TaggedStruct<"OutlineInconsistentKeys", {
173
189
  readonly outline: Schema.String;
@@ -176,7 +192,9 @@ declare const OutlineInconsistentKeys_base: Schema.Class<OutlineInconsistentKeys
176
192
  readonly actual: Schema.$Array<Schema.String>;
177
193
  }>, YieldableError>;
178
194
 
179
- export declare class OutlineMissingCapture extends OutlineMissingCapture_base {}
195
+ export declare class OutlineMissingCapture extends OutlineMissingCapture_base {
196
+ get message(): string;
197
+ }
180
198
 
181
199
  declare const OutlineMissingCapture_base: Schema.Class<OutlineMissingCapture, Schema.TaggedStruct<"OutlineMissingCapture", {
182
200
  readonly outline: Schema.String;
@@ -316,7 +334,9 @@ declare interface StoryWithPlay<TArgs> {
316
334
  export declare const Then: StepCtor;
317
335
 
318
336
  /** Capture values come from a literal hole, `with`, or an outline row — none matched. */
319
- export declare class UnresolvedCapture extends UnresolvedCapture_base {}
337
+ export declare class UnresolvedCapture extends UnresolvedCapture_base {
338
+ get message(): string;
339
+ }
320
340
 
321
341
  declare const UnresolvedCapture_base: Schema.Class<UnresolvedCapture, Schema.TaggedStruct<"UnresolvedCapture", {
322
342
  readonly scenario: Schema.String;
package/dist/index.mjs CHANGED
@@ -28,46 +28,86 @@ const ConcreteKeywordSchema = Schema.Literals([
28
28
  * - Run time: `CaptureDecodeFailed` travels the typed error channel of
29
29
  * `Step.run` and surfaces when the play edge interprets the scenario.
30
30
  */
31
- var EmptyScenario = class extends Schema.TaggedError()("EmptyScenario", { scenario: Schema.String }) {};
31
+ var EmptyScenario = class extends Schema.TaggedError()("EmptyScenario", { scenario: Schema.String }) {
32
+ get message() {
33
+ return `Scenario "${this.scenario}" has no steps`;
34
+ }
35
+ };
32
36
  /** Without a Then-phase step nothing is asserted — the scenario is not a spec. */
33
- var MissingThen = class extends Schema.TaggedError()("MissingThen", { scenario: Schema.String }) {};
37
+ var MissingThen = class extends Schema.TaggedError()("MissingThen", { scenario: Schema.String }) {
38
+ get message() {
39
+ return `Scenario "${this.scenario}" has no Then step`;
40
+ }
41
+ };
34
42
  var BackgroundNotGiven = class extends Schema.TaggedError()("BackgroundNotGiven", {
35
43
  step: Schema.String,
36
44
  resolved: ConcreteKeywordSchema
37
- }) {};
45
+ }) {
46
+ get message() {
47
+ return `The background step "${this.step}" is written as ${this.resolved}; a background must be Given`;
48
+ }
49
+ };
38
50
  var DuplicateCapture = class extends Schema.TaggedError()("DuplicateCapture", {
39
51
  step: Schema.String,
40
52
  name: Schema.String
41
- }) {};
53
+ }) {
54
+ get message() {
55
+ return `Step "${this.step}" binds capture "${this.name}" more than once`;
56
+ }
57
+ };
42
58
  /** Capture values come from a literal hole, `with`, or an outline row — none matched. */
43
59
  var UnresolvedCapture = class extends Schema.TaggedError()("UnresolvedCapture", {
44
60
  scenario: Schema.String,
45
61
  step: Schema.String,
46
62
  capture: Schema.String
47
- }) {};
48
- var OutlineEmpty = class extends Schema.TaggedError()("OutlineEmpty", { outline: Schema.String }) {};
63
+ }) {
64
+ get message() {
65
+ return `Capture "${this.capture}" in step "${this.step}" of scenario "${this.scenario}" resolved to no value`;
66
+ }
67
+ };
68
+ var OutlineEmpty = class extends Schema.TaggedError()("OutlineEmpty", { outline: Schema.String }) {
69
+ get message() {
70
+ return `Outline "${this.outline}" has no rows`;
71
+ }
72
+ };
49
73
  var OutlineInconsistentKeys = class extends Schema.TaggedError()("OutlineInconsistentKeys", {
50
74
  outline: Schema.String,
51
75
  row: Schema.String,
52
76
  expected: Schema.Array(Schema.String),
53
77
  actual: Schema.Array(Schema.String)
54
- }) {};
78
+ }) {
79
+ get message() {
80
+ return `Outline "${this.outline}" row "${this.row}" provides [${this.actual.join(", ")}] where the outline declares [${this.expected.join(", ")}]`;
81
+ }
82
+ };
55
83
  /** Row names become the exported story names, so duplicates would collide. */
56
84
  var OutlineDuplicateRowName = class extends Schema.TaggedError()("OutlineDuplicateRowName", {
57
85
  outline: Schema.String,
58
86
  name: Schema.String
59
- }) {};
87
+ }) {
88
+ get message() {
89
+ return `Outline "${this.outline}" has more than one row named "${this.name}"`;
90
+ }
91
+ };
60
92
  var OutlineMissingCapture = class extends Schema.TaggedError()("OutlineMissingCapture", {
61
93
  outline: Schema.String,
62
94
  row: Schema.String,
63
95
  capture: Schema.String
64
- }) {};
96
+ }) {
97
+ get message() {
98
+ return `Outline "${this.outline}" row "${this.row}" has no value for capture "${this.capture}"`;
99
+ }
100
+ };
65
101
  var CaptureDecodeFailed = class extends Schema.TaggedError()("CaptureDecodeFailed", {
66
102
  step: Schema.String,
67
103
  capture: Schema.String,
68
104
  value: Schema.String,
69
105
  cause: Schema.Unknown
70
- }) {};
106
+ }) {
107
+ get message() {
108
+ return `Capture "${this.capture}" of step "${this.step}" did not decode: ${this.value}`;
109
+ }
110
+ };
71
111
  //#endregion
72
112
  //#region src/Steps.ts
73
113
  const emptyIfMissing = (part) => {
@@ -229,7 +269,7 @@ const runStep = (step, values, stepCtx) => {
229
269
  const label = `${displayKeyword(step.model)} ${renderStepText(step.model, values)}`;
230
270
  return Deferred.make().pipe(Effect.flatMap((done) => {
231
271
  const bridge = () => Effect.runPromiseExit(Effect.flatten(Deferred.await(done))).then(squashExit);
232
- return Effect.forkChild(step.run(values, stepCtx).pipe(Effect.exit, Effect.flatMap((exit) => Deferred.succeed(done, exit)), Effect.ensuring(Deferred.interrupt(done).pipe(Effect.asVoid)))).pipe(Effect.flatMap((fiber) => Effect.promise(() => Promise.resolve(stepCtx.step(label, bridge))).pipe(Effect.flatMap(() => Fiber.join(fiber)), Effect.ensuring(Fiber.interrupt(fiber).pipe(Effect.asVoid)))));
272
+ return Effect.forkChild(step.run(values, stepCtx).pipe(Effect.exit, Effect.flatMap((exit) => Deferred.succeed(done, exit)), Effect.ensuring(Deferred.interrupt(done).pipe(Effect.asVoid)))).pipe(Effect.flatMap((fiber) => Effect.promise(() => Promise.resolve(stepCtx.step(label, bridge))).pipe(Effect.flatMap(() => Fiber.join(fiber)), Effect.ensuring(Fiber.interrupt(fiber).pipe(Effect.asVoid)))), Effect.ensuring(Deferred.interrupt(done).pipe(Effect.asVoid)));
233
273
  }));
234
274
  };
235
275
  const executeSteps = (ordered, values, ctx) => {
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@systemfsoftware/storybook-gherkin",
3
3
  "license": "Apache-2.0",
4
- "version": "4.0.1",
4
+ "version": "4.0.3",
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/storybook-gherkin"
9
+ "directory": "packages/gherkin/storybook-gherkin"
10
10
  },
11
- "homepage": "https://github.com/systemfsoftware/systemfsoftware/tree/main/packages/storybook-gherkin#readme",
11
+ "homepage": "https://github.com/systemfsoftware/systemfsoftware/tree/main/packages/gherkin/storybook-gherkin#readme",
12
12
  "bugs": "https://github.com/systemfsoftware/systemfsoftware/issues",
13
13
  "description": "Feature specs as Storybook stories — Gherkin Given/When/Then embedded in CSF with typed captures and scenario outlines, executing under Storybook's browser-mode play functions.",
14
14
  "keywords": [
@@ -47,15 +47,22 @@
47
47
  "@storybook/addon-vitest": "^10.6.0",
48
48
  "@storybook/react-vite": "^10.6.0",
49
49
  "@systemfsoftware/arethetypeswrong-cli": "^4.2.0",
50
- "@systemfsoftware/oxlint-config-recommended": "^2.0.2",
50
+ "@systemfsoftware/conformance-spec": "^0.2.0",
51
+ "@systemfsoftware/effect-gherkin-spec": "^6.0.0",
52
+ "@systemfsoftware/effect-sim-kernel": "^0.2.0",
53
+ "@systemfsoftware/effect-spec-runtime": "^0.3.1",
54
+ "@systemfsoftware/oxlint-config-recommended": "^3.2.0",
51
55
  "@systemfsoftware/tsconfig": "^2.0.1",
52
56
  "@systemfsoftware/tsdown-config": "^0.1.0",
57
+ "@systemfsoftware/vitest": "^0.2.0",
58
+ "@systemfsoftware/vitest-config": "^0.1.0",
53
59
  "@types/node": "^26",
54
60
  "@types/react": "^19.3.0",
55
61
  "@types/react-dom": "^19.3.0",
56
62
  "@vitest/browser": "^5",
57
63
  "@vitest/browser-playwright": "^5",
58
64
  "effect": "4.0.0-rc.117",
65
+ "jsdom": "29.1.1",
59
66
  "oxlint": "~1.82.0",
60
67
  "playwright": "^1",
61
68
  "react": "^19.3.0",
@@ -68,6 +75,7 @@
68
75
  "vitest": "^5"
69
76
  },
70
77
  "publishConfig": {
78
+ "access": "public",
71
79
  "provenance": true
72
80
  },
73
81
  "scripts": {
@@ -79,6 +87,7 @@
79
87
  "attw": "attw --pack .",
80
88
  "dts:check": "node scripts/check-dts.mjs",
81
89
  "storybook": "storybook dev -p 6006 --no-open",
90
+ "test": "vitest run --project conformance",
82
91
  "test:browser": "pnpm build && vitest run",
83
92
  "api:check": "tsdown -l warn && api-extractor-quiet run",
84
93
  "api:update": "api-extractor run --local"