@auto-engineer/narrative 1.139.0 → 1.140.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.
- package/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-test.log +5 -5
- package/.turbo/turbo-type-check.log +1 -1
- package/CHANGELOG.md +18 -0
- package/dist/scripts/convert-flow-exec.js +2 -2
- package/dist/scripts/convert-flow-exec.js.map +1 -1
- package/dist/scripts/print-schema.js +5 -5
- package/dist/scripts/print-schema.js.map +1 -1
- package/dist/src/fluent-builder.d.ts +29 -29
- package/dist/src/fluent-builder.d.ts.map +1 -1
- package/dist/src/fluent-builder.js +81 -81
- package/dist/src/fluent-builder.js.map +1 -1
- package/dist/src/{getNarratives.d.ts → getScenes.d.ts} +6 -6
- package/dist/src/getScenes.d.ts.map +1 -0
- package/dist/src/{getNarratives.js → getScenes.js} +16 -16
- package/dist/src/getScenes.js.map +1 -0
- package/dist/src/id/addAutoIds.d.ts.map +1 -1
- package/dist/src/id/addAutoIds.js +22 -22
- package/dist/src/id/addAutoIds.js.map +1 -1
- package/dist/src/id/hasAllIds.d.ts.map +1 -1
- package/dist/src/id/hasAllIds.js +2 -2
- package/dist/src/id/hasAllIds.js.map +1 -1
- package/dist/src/index.d.ts +8 -8
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -4
- package/dist/src/index.js.map +1 -1
- package/dist/src/loader/index.js +1 -1
- package/dist/src/loader/index.js.map +1 -1
- package/dist/src/loader/runtime-cjs.js +1 -1
- package/dist/src/loader/runtime-cjs.js.map +1 -1
- package/dist/src/narrative-context.d.ts +9 -9
- package/dist/src/narrative-context.d.ts.map +1 -1
- package/dist/src/narrative-context.js +47 -47
- package/dist/src/narrative-context.js.map +1 -1
- package/dist/src/narrative-registry.d.ts +6 -6
- package/dist/src/narrative-registry.d.ts.map +1 -1
- package/dist/src/narrative-registry.js +26 -26
- package/dist/src/narrative-registry.js.map +1 -1
- package/dist/src/narrative.d.ts +5 -5
- package/dist/src/narrative.d.ts.map +1 -1
- package/dist/src/narrative.js +26 -27
- package/dist/src/narrative.js.map +1 -1
- package/dist/src/parse-graphql-request.d.ts +1 -1
- package/dist/src/parse-graphql-request.d.ts.map +1 -1
- package/dist/src/parse-graphql-request.js +3 -3
- package/dist/src/parse-graphql-request.js.map +1 -1
- package/dist/src/samples/items.narrative.js +2 -2
- package/dist/src/samples/items.narrative.js.map +1 -1
- package/dist/src/samples/mixed-given-types.narrative.js +2 -2
- package/dist/src/samples/mixed-given-types.narrative.js.map +1 -1
- package/dist/src/samples/place-order.narrative.js +2 -2
- package/dist/src/samples/place-order.narrative.js.map +1 -1
- package/dist/src/samples/questionnaires.narrative.js +2 -2
- package/dist/src/samples/questionnaires.narrative.js.map +1 -1
- package/dist/src/samples/seasonal-assistant.schema.json +2 -2
- package/dist/src/samples/test-with-ids.narrative.js +2 -2
- package/dist/src/samples/test-with-ids.narrative.js.map +1 -1
- package/dist/src/schema.d.ts +136 -136
- package/dist/src/schema.d.ts.map +1 -1
- package/dist/src/schema.js +76 -76
- package/dist/src/schema.js.map +1 -1
- package/dist/src/slice-builder.d.ts +6 -6
- package/dist/src/slice-builder.d.ts.map +1 -1
- package/dist/src/slice-builder.js +21 -21
- package/dist/src/slice-builder.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/analysis/lint-helpers.js +1 -1
- package/dist/src/transformers/model-to-narrative/analysis/lint-helpers.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/cross-module-imports.js +4 -4
- package/dist/src/transformers/model-to-narrative/cross-module-imports.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/compose.js +3 -3
- package/dist/src/transformers/model-to-narrative/generators/compose.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/flow.d.ts +2 -2
- package/dist/src/transformers/model-to-narrative/generators/flow.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/flow.js +20 -20
- package/dist/src/transformers/model-to-narrative/generators/flow.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/imports.d.ts +1 -1
- package/dist/src/transformers/model-to-narrative/generators/imports.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/imports.js +1 -1
- package/dist/src/transformers/model-to-narrative/generators/imports.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/module-code.js +14 -14
- package/dist/src/transformers/model-to-narrative/generators/module-code.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/index.d.ts +4 -4
- package/dist/src/transformers/model-to-narrative/index.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/index.js +1 -1
- package/dist/src/transformers/model-to-narrative/spec-traversal.d.ts +2 -2
- package/dist/src/transformers/model-to-narrative/spec-traversal.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/spec-traversal.js +5 -5
- package/dist/src/transformers/model-to-narrative/spec-traversal.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/types.d.ts +1 -1
- package/dist/src/transformers/model-to-narrative/types.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/utils/integration-extractor.d.ts +1 -1
- package/dist/src/transformers/model-to-narrative/utils/integration-extractor.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/utils/integration-extractor.js +4 -4
- package/dist/src/transformers/model-to-narrative/utils/integration-extractor.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/validate-modules.d.ts +1 -1
- package/dist/src/transformers/model-to-narrative/validate-modules.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/validate-modules.js +19 -19
- package/dist/src/transformers/model-to-narrative/validate-modules.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/assemble.d.ts +2 -2
- package/dist/src/transformers/narrative-to-model/assemble.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/assemble.js +10 -3
- package/dist/src/transformers/narrative-to-model/assemble.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/debug.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/debug.js +1 -1
- package/dist/src/transformers/narrative-to-model/debug.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/derive-modules.d.ts +2 -2
- package/dist/src/transformers/narrative-to-model/derive-modules.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/derive-modules.js +9 -9
- package/dist/src/transformers/narrative-to-model/derive-modules.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/index.d.ts +2 -2
- package/dist/src/transformers/narrative-to-model/index.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/index.js +39 -39
- package/dist/src/transformers/narrative-to-model/index.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/spec-processors.js +1 -1
- package/dist/src/transformers/narrative-to-model/spec-processors.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/strings.d.ts +1 -1
- package/dist/src/transformers/narrative-to-model/strings.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/strings.js +6 -6
- package/dist/src/transformers/narrative-to-model/strings.js.map +1 -1
- package/dist/src/validate-slice-requests.d.ts +4 -4
- package/dist/src/validate-slice-requests.d.ts.map +1 -1
- package/dist/src/validate-slice-requests.js +34 -34
- package/dist/src/validate-slice-requests.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/scripts/convert-flow-exec.ts +2 -2
- package/scripts/print-schema.ts +8 -8
- package/src/fluent-builder.specs.ts +3 -3
- package/src/fluent-builder.ts +141 -141
- package/src/{getNarratives.cache.specs.ts → getScenes.cache.specs.ts} +45 -45
- package/src/{getNarratives.specs.ts → getScenes.specs.ts} +302 -300
- package/src/{getNarratives.ts → getScenes.ts} +20 -20
- package/src/id/addAutoIds.specs.ts +105 -105
- package/src/id/addAutoIds.ts +26 -26
- package/src/id/hasAllIds.specs.ts +59 -59
- package/src/id/hasAllIds.ts +6 -6
- package/src/index.ts +12 -13
- package/src/loader/index.ts +1 -1
- package/src/loader/runtime-cjs.ts +1 -1
- package/src/model-to-narrative.specs.ts +133 -135
- package/src/narrative-context.specs.ts +24 -24
- package/src/narrative-context.ts +61 -61
- package/src/narrative-registry.ts +31 -31
- package/src/narrative.ts +31 -33
- package/src/parse-graphql-request.specs.ts +5 -5
- package/src/parse-graphql-request.ts +3 -3
- package/src/samples/items.narrative.ts +2 -2
- package/src/samples/mixed-given-types.narrative.ts +2 -2
- package/src/samples/place-order.narrative.ts +2 -2
- package/src/samples/questionnaires.narrative.ts +2 -2
- package/src/samples/seasonal-assistant.schema.json +2 -2
- package/src/samples/test-with-ids.narrative.ts +2 -2
- package/src/schema.specs.ts +99 -91
- package/src/schema.ts +89 -89
- package/src/slice-builder.ts +30 -30
- package/src/transformers/model-to-narrative/analysis/lint-helpers.ts +1 -1
- package/src/transformers/model-to-narrative/cross-module-imports.specs.ts +43 -43
- package/src/transformers/model-to-narrative/cross-module-imports.ts +4 -4
- package/src/transformers/model-to-narrative/generators/compose.ts +4 -4
- package/src/transformers/model-to-narrative/generators/flow.ts +36 -36
- package/src/transformers/model-to-narrative/generators/imports.ts +1 -1
- package/src/transformers/model-to-narrative/generators/module-code.ts +15 -15
- package/src/transformers/model-to-narrative/index.ts +4 -4
- package/src/transformers/model-to-narrative/modules.specs.ts +58 -58
- package/src/transformers/model-to-narrative/spec-traversal.specs.ts +43 -43
- package/src/transformers/model-to-narrative/spec-traversal.ts +6 -6
- package/src/transformers/model-to-narrative/types.ts +1 -1
- package/src/transformers/model-to-narrative/utils/integration-extractor.ts +5 -5
- package/src/transformers/model-to-narrative/validate-modules.ts +22 -22
- package/src/transformers/narrative-to-model/assemble.ts +12 -4
- package/src/transformers/narrative-to-model/debug.ts +1 -1
- package/src/transformers/narrative-to-model/derive-modules.specs.ts +35 -35
- package/src/transformers/narrative-to-model/derive-modules.ts +11 -11
- package/src/transformers/narrative-to-model/index.ts +47 -47
- package/src/transformers/narrative-to-model/spec-processors.ts +1 -1
- package/src/transformers/narrative-to-model/strings.ts +6 -6
- package/src/transformers/narrative-to-model/type-inference.specs.ts +11 -11
- package/src/validate-slice-requests.specs.ts +113 -113
- package/src/validate-slice-requests.ts +49 -49
- package/dist/src/getNarratives.d.ts.map +0 -1
- package/dist/src/getNarratives.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
2
2
|
|
|
3
3
|
import { command } from './fluent-builder';
|
|
4
|
-
import type {
|
|
5
|
-
import { example,
|
|
4
|
+
import type { CommandMoment } from './index';
|
|
5
|
+
import { example, describe as narrativeDescribe, it as narrativeIt, rule, scene, should, specs } from './narrative';
|
|
6
6
|
import { registry } from './narrative-registry';
|
|
7
7
|
import type { Event, State } from './types';
|
|
8
8
|
|
|
@@ -45,7 +45,7 @@ describe('it and should with id parameter', () => {
|
|
|
45
45
|
});
|
|
46
46
|
|
|
47
47
|
it('should record it with title only', () => {
|
|
48
|
-
|
|
48
|
+
scene('test it title only', () => {
|
|
49
49
|
command('test command').client(() => {
|
|
50
50
|
narrativeDescribe('Test Section', () => {
|
|
51
51
|
narrativeIt('displays todo list');
|
|
@@ -53,8 +53,8 @@ describe('it and should with id parameter', () => {
|
|
|
53
53
|
});
|
|
54
54
|
});
|
|
55
55
|
|
|
56
|
-
const
|
|
57
|
-
const slice =
|
|
56
|
+
const scenes = registry.getAllScenes();
|
|
57
|
+
const slice = scenes[0].moments[0] as CommandMoment;
|
|
58
58
|
const describeNode = slice.client.specs[0];
|
|
59
59
|
|
|
60
60
|
expect(describeNode.type).toBe('describe');
|
|
@@ -68,7 +68,7 @@ describe('it and should with id parameter', () => {
|
|
|
68
68
|
});
|
|
69
69
|
|
|
70
70
|
it('should record it with title and id (id at end)', () => {
|
|
71
|
-
|
|
71
|
+
scene('test it with id', () => {
|
|
72
72
|
command('test command').client(() => {
|
|
73
73
|
narrativeDescribe('Test Section', () => {
|
|
74
74
|
narrativeIt('displays todo list', 'IT-001');
|
|
@@ -76,8 +76,8 @@ describe('it and should with id parameter', () => {
|
|
|
76
76
|
});
|
|
77
77
|
});
|
|
78
78
|
|
|
79
|
-
const
|
|
80
|
-
const slice =
|
|
79
|
+
const scenes = registry.getAllScenes();
|
|
80
|
+
const slice = scenes[0].moments[0] as CommandMoment;
|
|
81
81
|
const describeNode = slice.client.specs[0];
|
|
82
82
|
if (describeNode.type !== 'describe') throw new Error('Expected describe node');
|
|
83
83
|
const itNode = describeNode.children![0];
|
|
@@ -88,7 +88,7 @@ describe('it and should with id parameter', () => {
|
|
|
88
88
|
});
|
|
89
89
|
|
|
90
90
|
it('should record should with title only', () => {
|
|
91
|
-
|
|
91
|
+
scene('test should title only', () => {
|
|
92
92
|
command('test command').client(() => {
|
|
93
93
|
narrativeDescribe('Test Section', () => {
|
|
94
94
|
should('display todo list');
|
|
@@ -96,8 +96,8 @@ describe('it and should with id parameter', () => {
|
|
|
96
96
|
});
|
|
97
97
|
});
|
|
98
98
|
|
|
99
|
-
const
|
|
100
|
-
const slice =
|
|
99
|
+
const scenes = registry.getAllScenes();
|
|
100
|
+
const slice = scenes[0].moments[0] as CommandMoment;
|
|
101
101
|
const describeNode = slice.client.specs[0];
|
|
102
102
|
if (describeNode.type !== 'describe') throw new Error('Expected describe node');
|
|
103
103
|
const itNode = describeNode.children![0];
|
|
@@ -108,7 +108,7 @@ describe('it and should with id parameter', () => {
|
|
|
108
108
|
});
|
|
109
109
|
|
|
110
110
|
it('should record should with title and id (id at end)', () => {
|
|
111
|
-
|
|
111
|
+
scene('test should with id', () => {
|
|
112
112
|
command('test command').client(() => {
|
|
113
113
|
narrativeDescribe('Test Section', () => {
|
|
114
114
|
should('display todo list', 'SH-001');
|
|
@@ -116,8 +116,8 @@ describe('it and should with id parameter', () => {
|
|
|
116
116
|
});
|
|
117
117
|
});
|
|
118
118
|
|
|
119
|
-
const
|
|
120
|
-
const slice =
|
|
119
|
+
const scenes = registry.getAllScenes();
|
|
120
|
+
const slice = scenes[0].moments[0] as CommandMoment;
|
|
121
121
|
const describeNode = slice.client.specs[0];
|
|
122
122
|
if (describeNode.type !== 'describe') throw new Error('Expected describe node');
|
|
123
123
|
const itNode = describeNode.children![0];
|
|
@@ -134,7 +134,7 @@ describe('describe with id parameter', () => {
|
|
|
134
134
|
});
|
|
135
135
|
|
|
136
136
|
it('should record describe with title and callback', () => {
|
|
137
|
-
|
|
137
|
+
scene('test describe title', () => {
|
|
138
138
|
command('test command').client(() => {
|
|
139
139
|
narrativeDescribe('Todo List', () => {
|
|
140
140
|
narrativeIt('shows items');
|
|
@@ -142,8 +142,8 @@ describe('describe with id parameter', () => {
|
|
|
142
142
|
});
|
|
143
143
|
});
|
|
144
144
|
|
|
145
|
-
const
|
|
146
|
-
const slice =
|
|
145
|
+
const scenes = registry.getAllScenes();
|
|
146
|
+
const slice = scenes[0].moments[0] as CommandMoment;
|
|
147
147
|
const describeNode = slice.client.specs[0];
|
|
148
148
|
|
|
149
149
|
expect(describeNode.type).toBe('describe');
|
|
@@ -152,7 +152,7 @@ describe('describe with id parameter', () => {
|
|
|
152
152
|
});
|
|
153
153
|
|
|
154
154
|
it('should record describe with title, id, and callback (id at end)', () => {
|
|
155
|
-
|
|
155
|
+
scene('test describe with id', () => {
|
|
156
156
|
command('test command').client(() => {
|
|
157
157
|
narrativeDescribe('Todo List', 'DESC-001', () => {
|
|
158
158
|
narrativeIt('shows items');
|
|
@@ -160,8 +160,8 @@ describe('describe with id parameter', () => {
|
|
|
160
160
|
});
|
|
161
161
|
});
|
|
162
162
|
|
|
163
|
-
const
|
|
164
|
-
const slice =
|
|
163
|
+
const scenes = registry.getAllScenes();
|
|
164
|
+
const slice = scenes[0].moments[0] as CommandMoment;
|
|
165
165
|
const describeNode = slice.client.specs[0];
|
|
166
166
|
|
|
167
167
|
expect(describeNode.type).toBe('describe');
|
|
@@ -177,7 +177,7 @@ describe('Narrative DSL', () => {
|
|
|
177
177
|
|
|
178
178
|
it('should support given() method in builder', () => {
|
|
179
179
|
expect(() => {
|
|
180
|
-
|
|
180
|
+
scene('test flow with given', () => {
|
|
181
181
|
command('test command').server(() => {
|
|
182
182
|
specs(() => {
|
|
183
183
|
rule('test rule with given', () => {
|
|
@@ -212,7 +212,7 @@ describe('Narrative DSL', () => {
|
|
|
212
212
|
|
|
213
213
|
it('should support when() method in builder', () => {
|
|
214
214
|
expect(() => {
|
|
215
|
-
|
|
215
|
+
scene('test flow with when', () => {
|
|
216
216
|
command('test command').server(() => {
|
|
217
217
|
specs(() => {
|
|
218
218
|
rule('test rule', () => {
|
|
@@ -247,7 +247,7 @@ describe('Narrative DSL', () => {
|
|
|
247
247
|
|
|
248
248
|
it('should support then() method in builder', () => {
|
|
249
249
|
expect(() => {
|
|
250
|
-
|
|
250
|
+
scene('test flow with then', () => {
|
|
251
251
|
command('test command').server(() => {
|
|
252
252
|
specs(() => {
|
|
253
253
|
rule('test rule', () => {
|
|
@@ -282,7 +282,7 @@ describe('Narrative DSL', () => {
|
|
|
282
282
|
|
|
283
283
|
it('should support full narrative DSL flow', () => {
|
|
284
284
|
expect(() => {
|
|
285
|
-
|
|
285
|
+
scene('test full DSL flow', () => {
|
|
286
286
|
command('test preservation').server(() => {
|
|
287
287
|
specs(() => {
|
|
288
288
|
rule('full flow rule', () => {
|
package/src/narrative-context.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import createDebug from 'debug';
|
|
2
2
|
import type { z } from 'zod';
|
|
3
|
-
import type {
|
|
3
|
+
import type { CommandMoment, ExperienceMoment, Moment, QueryMoment, Scene } from './index';
|
|
4
4
|
import type { GivenTypeInfo } from './loader/ts-utils';
|
|
5
5
|
import type { ClientSpecNode, DataTarget, ExampleSchema, RuleSchema, SpecSchema, StepSchema } from './schema';
|
|
6
6
|
import type { Data, DataSink, DataSource } from './types';
|
|
@@ -14,9 +14,9 @@ const debug = createDebug('auto:narrative:context:given-types');
|
|
|
14
14
|
|
|
15
15
|
type MajorKeyword = 'Given' | 'When' | 'Then';
|
|
16
16
|
|
|
17
|
-
interface
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
interface SceneContext {
|
|
18
|
+
scene: Scene;
|
|
19
|
+
currentMomentIndex: number | null;
|
|
20
20
|
currentSpecTarget: 'client' | 'server' | null;
|
|
21
21
|
currentSpecIndex: number | null;
|
|
22
22
|
currentRuleIndex: number | null;
|
|
@@ -25,7 +25,7 @@ interface NarrativeContext {
|
|
|
25
25
|
lastMajorKeyword: MajorKeyword | null;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
let context:
|
|
28
|
+
let context: SceneContext | null = null;
|
|
29
29
|
let givenTypesByFile: Map<string, GivenTypeInfo[]> = new Map();
|
|
30
30
|
let whenTypesByFile: Map<string, GivenTypeInfo[]> = new Map();
|
|
31
31
|
let thenTypesByFile: Map<string, GivenTypeInfo[]> = new Map();
|
|
@@ -52,7 +52,7 @@ export function setGivenTypesByFile(types: Map<string, GivenTypeInfo[]>): void {
|
|
|
52
52
|
thenCallCounters.clear();
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
export function
|
|
55
|
+
export function startScene(name: string, id?: string): Scene {
|
|
56
56
|
const sourceFile = (globalThis as Record<string, unknown>).__aeCurrentModulePath as string | undefined;
|
|
57
57
|
if (sourceFile !== null && sourceFile !== undefined && sourceFile !== '') {
|
|
58
58
|
givenCallCounters.set(sourceFile, 0);
|
|
@@ -60,15 +60,15 @@ export function startNarrative(name: string, id?: string): Narrative {
|
|
|
60
60
|
thenCallCounters.set(sourceFile, 0);
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
-
const
|
|
63
|
+
const sceneObj: Scene = {
|
|
64
64
|
name,
|
|
65
65
|
id,
|
|
66
|
-
|
|
66
|
+
moments: [],
|
|
67
67
|
...(typeof sourceFile === 'string' ? { sourceFile } : {}),
|
|
68
68
|
};
|
|
69
69
|
context = {
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
scene: sceneObj,
|
|
71
|
+
currentMomentIndex: null,
|
|
72
72
|
currentSpecTarget: null,
|
|
73
73
|
currentSpecIndex: null,
|
|
74
74
|
currentRuleIndex: null,
|
|
@@ -76,43 +76,43 @@ export function startNarrative(name: string, id?: string): Narrative {
|
|
|
76
76
|
clientSpecStack: [],
|
|
77
77
|
lastMajorKeyword: null,
|
|
78
78
|
};
|
|
79
|
-
return
|
|
79
|
+
return sceneObj;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
export function
|
|
83
|
-
return context?.
|
|
82
|
+
export function getCurrentScene(): Scene | null {
|
|
83
|
+
return context?.scene ?? null;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
export function
|
|
86
|
+
export function clearCurrentScene(): void {
|
|
87
87
|
context = null;
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
export function
|
|
91
|
-
if (!context || context.
|
|
92
|
-
return context.
|
|
90
|
+
export function getCurrentMoment(): Moment | null {
|
|
91
|
+
if (!context || context.currentMomentIndex === null) return null;
|
|
92
|
+
return context.scene.moments[context.currentMomentIndex] ?? null;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
export function
|
|
96
|
-
if (!context) throw new Error('No active
|
|
97
|
-
context.
|
|
98
|
-
context.
|
|
95
|
+
export function addMoment(moment: Moment): void {
|
|
96
|
+
if (!context) throw new Error('No active scene');
|
|
97
|
+
context.scene.moments.push(moment);
|
|
98
|
+
context.currentMomentIndex = context.scene.moments.length - 1;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
function getServerSpecs(slice:
|
|
101
|
+
function getServerSpecs(slice: Moment): Spec[] | undefined {
|
|
102
102
|
if ('server' in slice) {
|
|
103
103
|
return slice.server?.specs;
|
|
104
104
|
}
|
|
105
105
|
return undefined;
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
function getCurrentSpec(slice:
|
|
108
|
+
function getCurrentSpec(slice: Moment): Spec | undefined {
|
|
109
109
|
if (!context || context.currentSpecIndex === null) return undefined;
|
|
110
110
|
const specs = getServerSpecs(slice);
|
|
111
111
|
if (!specs) return undefined;
|
|
112
112
|
return specs[context.currentSpecIndex];
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
function getCurrentExample(slice:
|
|
115
|
+
function getCurrentExample(slice: Moment): Example | undefined {
|
|
116
116
|
if (
|
|
117
117
|
!context ||
|
|
118
118
|
context.currentSpecIndex === null ||
|
|
@@ -128,8 +128,8 @@ function getCurrentExample(slice: Slice): Example | undefined {
|
|
|
128
128
|
return spec.rules[context.currentRuleIndex]?.examples[context.currentExampleIndex];
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
export function startClientBlock(slice:
|
|
132
|
-
if (!context) throw new Error('No active
|
|
131
|
+
export function startClientBlock(slice: Moment): void {
|
|
132
|
+
if (!context) throw new Error('No active scene context');
|
|
133
133
|
|
|
134
134
|
if (slice.type === 'command' || slice.type === 'query' || slice.type === 'experience') {
|
|
135
135
|
slice.client = {
|
|
@@ -158,8 +158,8 @@ export function endClientBlock(): void {
|
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
export function startServerBlock(slice:
|
|
162
|
-
if (!context) throw new Error('No active
|
|
161
|
+
export function startServerBlock(slice: Moment, description: string = ''): void {
|
|
162
|
+
if (!context) throw new Error('No active scene context');
|
|
163
163
|
|
|
164
164
|
if (slice.type === 'command') {
|
|
165
165
|
slice.server = {
|
|
@@ -190,7 +190,7 @@ export function endServerBlock(): void {
|
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
-
function addServerSpec(slice:
|
|
193
|
+
function addServerSpec(slice: Moment, feature: string): void {
|
|
194
194
|
if ('server' in slice && slice.server != null) {
|
|
195
195
|
const newSpec: Spec = {
|
|
196
196
|
type: 'gherkin',
|
|
@@ -204,8 +204,8 @@ function addServerSpec(slice: Slice, feature: string): void {
|
|
|
204
204
|
|
|
205
205
|
export function pushSpec(feature: string): void {
|
|
206
206
|
if (!context || !context.currentSpecTarget) throw new Error('No active spec target');
|
|
207
|
-
const slice =
|
|
208
|
-
if (!slice) throw new Error('No active
|
|
207
|
+
const slice = getCurrentMoment();
|
|
208
|
+
if (!slice) throw new Error('No active moment');
|
|
209
209
|
|
|
210
210
|
if (context.currentSpecTarget === 'server') {
|
|
211
211
|
addServerSpec(slice, feature);
|
|
@@ -213,7 +213,7 @@ export function pushSpec(feature: string): void {
|
|
|
213
213
|
}
|
|
214
214
|
|
|
215
215
|
export function pushDescribe(title?: string, id?: string): void {
|
|
216
|
-
if (!context) throw new Error('No active
|
|
216
|
+
if (!context) throw new Error('No active scene context');
|
|
217
217
|
|
|
218
218
|
const describeNode: ClientSpecNode = {
|
|
219
219
|
type: 'describe',
|
|
@@ -225,13 +225,13 @@ export function pushDescribe(title?: string, id?: string): void {
|
|
|
225
225
|
context.clientSpecStack.push(describeNode);
|
|
226
226
|
}
|
|
227
227
|
|
|
228
|
-
function
|
|
228
|
+
function validateMomentSupportsClientSpecs(slice: Moment): void {
|
|
229
229
|
if (slice.type !== 'command' && slice.type !== 'query' && slice.type !== 'experience') {
|
|
230
|
-
throw new Error('Client specs can only be added to command, query, or experience
|
|
230
|
+
throw new Error('Client specs can only be added to command, query, or experience moments');
|
|
231
231
|
}
|
|
232
232
|
}
|
|
233
233
|
|
|
234
|
-
function addNodeToParentOrRoot(node: ClientSpecNode, slice:
|
|
234
|
+
function addNodeToParentOrRoot(node: ClientSpecNode, slice: CommandMoment | QueryMoment | ExperienceMoment): void {
|
|
235
235
|
if (!context) return;
|
|
236
236
|
|
|
237
237
|
if (context.clientSpecStack.length === 0) {
|
|
@@ -246,21 +246,21 @@ function addNodeToParentOrRoot(node: ClientSpecNode, slice: CommandSlice | Query
|
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
export function popDescribe(): void {
|
|
249
|
-
if (!context) throw new Error('No active
|
|
249
|
+
if (!context) throw new Error('No active scene context');
|
|
250
250
|
if (context.clientSpecStack.length === 0) throw new Error('No active describe block');
|
|
251
251
|
|
|
252
252
|
const completedDescribe = context.clientSpecStack.pop();
|
|
253
253
|
if (!completedDescribe) return;
|
|
254
254
|
|
|
255
|
-
const slice =
|
|
256
|
-
if (!slice) throw new Error('No active
|
|
255
|
+
const slice = getCurrentMoment();
|
|
256
|
+
if (!slice) throw new Error('No active moment');
|
|
257
257
|
|
|
258
|
-
|
|
259
|
-
addNodeToParentOrRoot(completedDescribe, slice as
|
|
258
|
+
validateMomentSupportsClientSpecs(slice);
|
|
259
|
+
addNodeToParentOrRoot(completedDescribe, slice as CommandMoment | QueryMoment | ExperienceMoment);
|
|
260
260
|
}
|
|
261
261
|
|
|
262
262
|
export function recordIt(title: string, id?: string): void {
|
|
263
|
-
if (!context) throw new Error('No active
|
|
263
|
+
if (!context) throw new Error('No active scene context');
|
|
264
264
|
|
|
265
265
|
const itNode: ClientSpecNode = {
|
|
266
266
|
type: 'it',
|
|
@@ -268,23 +268,23 @@ export function recordIt(title: string, id?: string): void {
|
|
|
268
268
|
title,
|
|
269
269
|
};
|
|
270
270
|
|
|
271
|
-
const slice =
|
|
272
|
-
if (!slice) throw new Error('No active
|
|
271
|
+
const slice = getCurrentMoment();
|
|
272
|
+
if (!slice) throw new Error('No active moment');
|
|
273
273
|
|
|
274
|
-
|
|
275
|
-
addNodeToParentOrRoot(itNode, slice as
|
|
274
|
+
validateMomentSupportsClientSpecs(slice);
|
|
275
|
+
addNodeToParentOrRoot(itNode, slice as CommandMoment | QueryMoment | ExperienceMoment);
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
export function setQueryRequest(request: string): void {
|
|
279
|
-
const slice =
|
|
280
|
-
if (!slice || slice.type !== 'query') throw new Error('Request can only be set on query
|
|
279
|
+
const slice = getCurrentMoment();
|
|
280
|
+
if (!slice || slice.type !== 'query') throw new Error('Request can only be set on query moments');
|
|
281
281
|
slice.request = request;
|
|
282
282
|
}
|
|
283
283
|
|
|
284
|
-
export function
|
|
285
|
-
const slice =
|
|
286
|
-
if (!slice) throw new Error('No active
|
|
287
|
-
if (!('server' in slice)) throw new Error('Data can only be set on
|
|
284
|
+
export function setMomentData(data: Data): void {
|
|
285
|
+
const slice = getCurrentMoment();
|
|
286
|
+
if (!slice) throw new Error('No active moment');
|
|
287
|
+
if (!('server' in slice)) throw new Error('Data can only be set on moments with a server');
|
|
288
288
|
|
|
289
289
|
const items = data.items;
|
|
290
290
|
if (items.length === 0) {
|
|
@@ -313,11 +313,11 @@ function stripTypeDiscriminator(items: (DataSink | DataSource | DataTarget)[]):
|
|
|
313
313
|
|
|
314
314
|
export function recordRule(name: string, id?: string): void {
|
|
315
315
|
if (!context || context.currentSpecIndex === null) throw new Error('No active spec context');
|
|
316
|
-
const slice =
|
|
317
|
-
if (!slice) throw new Error('No active
|
|
316
|
+
const slice = getCurrentMoment();
|
|
317
|
+
if (!slice) throw new Error('No active moment');
|
|
318
318
|
|
|
319
319
|
const spec = getCurrentSpec(slice);
|
|
320
|
-
if (!spec) throw new Error('No active specs for current
|
|
320
|
+
if (!spec) throw new Error('No active specs for current moment');
|
|
321
321
|
|
|
322
322
|
const newRule: Rule = {
|
|
323
323
|
id,
|
|
@@ -332,11 +332,11 @@ export function recordExample(name: string, id?: string): void {
|
|
|
332
332
|
if (!context || context.currentSpecIndex === null || context.currentRuleIndex === null) {
|
|
333
333
|
throw new Error('No active rule context');
|
|
334
334
|
}
|
|
335
|
-
const slice =
|
|
336
|
-
if (!slice) throw new Error('No active
|
|
335
|
+
const slice = getCurrentMoment();
|
|
336
|
+
if (!slice) throw new Error('No active moment');
|
|
337
337
|
|
|
338
338
|
const spec = getCurrentSpec(slice);
|
|
339
|
-
if (!spec) throw new Error('No active specs for current
|
|
339
|
+
if (!spec) throw new Error('No active specs for current moment');
|
|
340
340
|
|
|
341
341
|
const rule = spec.rules[context.currentRuleIndex];
|
|
342
342
|
const newExample: Example = {
|
|
@@ -382,7 +382,7 @@ function getCountersForKeyword(keyword: MajorKeyword): Map<string, number> {
|
|
|
382
382
|
}
|
|
383
383
|
|
|
384
384
|
function getTypeNameFromAST(effectiveKeyword: MajorKeyword): string | null {
|
|
385
|
-
const sourceFile = context?.
|
|
385
|
+
const sourceFile = context?.scene.sourceFile;
|
|
386
386
|
if (!isValidSourceFile(sourceFile)) {
|
|
387
387
|
return null;
|
|
388
388
|
}
|
|
@@ -420,10 +420,10 @@ function getActiveExampleContext(): { example: Example } {
|
|
|
420
420
|
) {
|
|
421
421
|
throw new Error('No active example context');
|
|
422
422
|
}
|
|
423
|
-
const slice =
|
|
424
|
-
if (!slice) throw new Error('No active
|
|
423
|
+
const slice = getCurrentMoment();
|
|
424
|
+
if (!slice) throw new Error('No active moment');
|
|
425
425
|
const example = getCurrentExample(slice);
|
|
426
|
-
if (!example) throw new Error('No active example for current
|
|
426
|
+
if (!example) throw new Error('No active example for current moment');
|
|
427
427
|
return { example };
|
|
428
428
|
}
|
|
429
429
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import createDebug from 'debug';
|
|
2
|
-
import type {
|
|
3
|
-
import {
|
|
2
|
+
import type { Scene } from './index';
|
|
3
|
+
import { SceneSchema } from './schema';
|
|
4
4
|
|
|
5
5
|
const debug = createDebug('auto:narrative:registry');
|
|
6
6
|
// Set non-error-like colors for debug namespace
|
|
@@ -9,57 +9,57 @@ if ('color' in debug && typeof debug === 'object') {
|
|
|
9
9
|
(debug as { color: string }).color = '6'; // cyan
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
class
|
|
13
|
-
private
|
|
12
|
+
class SceneRegistry {
|
|
13
|
+
private scenes: Scene[] = [];
|
|
14
14
|
private instanceId = Math.random().toString(36).substring(7);
|
|
15
15
|
|
|
16
16
|
constructor() {
|
|
17
|
-
debug('Creating new
|
|
17
|
+
debug('Creating new SceneRegistry instance: %s', this.instanceId);
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
register(
|
|
21
|
-
debug('Registering
|
|
22
|
-
debug('
|
|
23
|
-
debug('
|
|
24
|
-
debug('Array object ID before: %s', this.
|
|
25
|
-
const validated =
|
|
26
|
-
this.
|
|
27
|
-
debug('
|
|
28
|
-
debug('Array object ID after: %s', this.
|
|
20
|
+
register(scene: Scene) {
|
|
21
|
+
debug('Registering scene: %s on instance %s', scene.name, this.instanceId);
|
|
22
|
+
debug('Scene moments: %d', scene.moments.length);
|
|
23
|
+
debug('Scenes array before push: %d', this.scenes.length);
|
|
24
|
+
debug('Array object ID before: %s', this.scenes);
|
|
25
|
+
const validated = SceneSchema.parse(scene);
|
|
26
|
+
this.scenes.push(validated);
|
|
27
|
+
debug('Scenes array after push: %d', this.scenes.length);
|
|
28
|
+
debug('Array object ID after: %s', this.scenes);
|
|
29
29
|
debug(
|
|
30
|
-
'Successfully registered
|
|
31
|
-
|
|
30
|
+
'Successfully registered scene: %s on instance %s, total scenes: %d',
|
|
31
|
+
scene.name,
|
|
32
32
|
this.instanceId,
|
|
33
|
-
this.
|
|
33
|
+
this.scenes.length,
|
|
34
34
|
);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
|
|
38
|
-
debug('Getting all
|
|
37
|
+
getAllScenes(): Scene[] {
|
|
38
|
+
debug('Getting all scenes, count: %d', this.scenes.length);
|
|
39
39
|
debug('Registry instance ID: %s', this.instanceId);
|
|
40
|
-
debug('Array object ID: %s', this.
|
|
40
|
+
debug('Array object ID: %s', this.scenes);
|
|
41
41
|
debug('this === registry? %s', this === registry);
|
|
42
|
-
if (this.
|
|
42
|
+
if (this.scenes.length > 0) {
|
|
43
43
|
debug(
|
|
44
|
-
'
|
|
45
|
-
this.
|
|
44
|
+
'Scenes: %o',
|
|
45
|
+
this.scenes.map((f) => f.name),
|
|
46
46
|
);
|
|
47
47
|
}
|
|
48
|
-
return [...this.
|
|
48
|
+
return [...this.scenes];
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
clearAll() {
|
|
52
|
-
debug('Clearing all
|
|
53
|
-
if (this.
|
|
52
|
+
debug('Clearing all scenes on instance %s, current count: %d', this.instanceId, this.scenes.length);
|
|
53
|
+
if (this.scenes.length > 0) {
|
|
54
54
|
debug(
|
|
55
|
-
'Clearing
|
|
55
|
+
'Clearing scenes on instance %s: %o',
|
|
56
56
|
this.instanceId,
|
|
57
|
-
this.
|
|
57
|
+
this.scenes.map((f) => f.name),
|
|
58
58
|
);
|
|
59
59
|
}
|
|
60
|
-
this.
|
|
61
|
-
debug('Cleared! Instance %s now has %d
|
|
60
|
+
this.scenes = [];
|
|
61
|
+
debug('Cleared! Instance %s now has %d scenes', this.instanceId, this.scenes.length);
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
export const registry = new
|
|
65
|
+
export const registry = new SceneRegistry();
|