@auto-engineer/narrative 0.13.0 → 0.13.2
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/CHANGELOG.md +22 -0
- package/dist/src/commands/export-schema-runner.js +1 -1
- package/dist/src/commands/export-schema-runner.js.map +1 -1
- package/dist/src/fluent-builder.js +3 -3
- package/dist/src/fluent-builder.js.map +1 -1
- package/dist/src/getNarratives.specs.js +149 -153
- package/dist/src/getNarratives.specs.js.map +1 -1
- package/dist/src/id/addAutoIds.d.ts.map +1 -1
- package/dist/src/id/addAutoIds.js +50 -12
- package/dist/src/id/addAutoIds.js.map +1 -1
- package/dist/src/id/addAutoIds.specs.js +396 -45
- package/dist/src/id/addAutoIds.specs.js.map +1 -1
- package/dist/src/id/hasAllIds.d.ts.map +1 -1
- package/dist/src/id/hasAllIds.js +28 -5
- package/dist/src/id/hasAllIds.js.map +1 -1
- package/dist/src/id/hasAllIds.specs.js +407 -214
- package/dist/src/id/hasAllIds.specs.js.map +1 -1
- package/dist/src/index.d.ts +6 -8
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/loader/graph.d.ts.map +1 -1
- package/dist/src/loader/graph.js +13 -6
- package/dist/src/loader/graph.js.map +1 -1
- package/dist/src/loader/ts-utils.d.ts +1 -0
- package/dist/src/loader/ts-utils.d.ts.map +1 -1
- package/dist/src/loader/ts-utils.js +95 -16
- package/dist/src/loader/ts-utils.js.map +1 -1
- package/dist/src/model-to-narrative.specs.js +531 -449
- package/dist/src/model-to-narrative.specs.js.map +1 -1
- package/dist/src/narrative-context.d.ts +8 -8
- package/dist/src/narrative-context.d.ts.map +1 -1
- package/dist/src/narrative-context.js +111 -301
- package/dist/src/narrative-context.js.map +1 -1
- package/dist/src/narrative-context.specs.js +15 -55
- package/dist/src/narrative-context.specs.js.map +1 -1
- package/dist/src/narrative.d.ts +19 -22
- package/dist/src/narrative.d.ts.map +1 -1
- package/dist/src/narrative.js +42 -71
- package/dist/src/narrative.js.map +1 -1
- package/dist/src/samples/test-with-ids.narrative.js +13 -29
- package/dist/src/samples/test-with-ids.narrative.js.map +1 -1
- package/dist/src/schema.d.ts +3205 -8287
- package/dist/src/schema.d.ts.map +1 -1
- package/dist/src/schema.js +29 -47
- package/dist/src/schema.js.map +1 -1
- package/dist/src/slice-builder.js +3 -3
- package/dist/src/slice-builder.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/flow.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/flow.js +118 -74
- package/dist/src/transformers/model-to-narrative/generators/flow.js.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/gwt.d.ts +9 -1
- package/dist/src/transformers/model-to-narrative/generators/gwt.d.ts.map +1 -1
- package/dist/src/transformers/model-to-narrative/generators/gwt.js +112 -112
- package/dist/src/transformers/model-to-narrative/generators/gwt.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 +13 -9
- package/dist/src/transformers/model-to-narrative/generators/imports.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/index.d.ts.map +1 -1
- package/dist/src/transformers/narrative-to-model/index.js +50 -23
- package/dist/src/transformers/narrative-to-model/index.js.map +1 -1
- package/dist/src/transformers/narrative-to-model/type-inference.specs.js +100 -90
- package/dist/src/transformers/narrative-to-model/type-inference.specs.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/commands/export-schema-runner.ts +3 -1
- package/src/fluent-builder.ts +3 -3
- package/src/getNarratives.specs.ts +168 -176
- package/src/id/addAutoIds.specs.ts +424 -47
- package/src/id/addAutoIds.ts +57 -13
- package/src/id/hasAllIds.specs.ts +400 -223
- package/src/id/hasAllIds.ts +32 -6
- package/src/index.ts +9 -12
- package/src/loader/graph.ts +23 -6
- package/src/loader/ts-utils.ts +169 -26
- package/src/model-to-narrative.specs.ts +531 -449
- package/src/narrative-context.specs.ts +73 -116
- package/src/narrative-context.ts +127 -374
- package/src/narrative.ts +70 -120
- package/src/samples/test-with-ids.narrative.ts +23 -31
- package/src/schema.ts +36 -52
- package/src/slice-builder.ts +3 -3
- package/src/transformers/model-to-narrative/generators/flow.ts +191 -85
- package/src/transformers/model-to-narrative/generators/gwt.ts +195 -178
- package/src/transformers/model-to-narrative/generators/imports.ts +13 -9
- package/src/transformers/narrative-to-model/index.ts +87 -26
- package/src/transformers/narrative-to-model/type-inference.specs.ts +100 -90
|
@@ -406,85 +406,150 @@ function addRequestToChain(
|
|
|
406
406
|
return chain;
|
|
407
407
|
}
|
|
408
408
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
then: [],
|
|
415
|
-
};
|
|
409
|
+
interface StepWithDocString {
|
|
410
|
+
keyword: 'Given' | 'When' | 'Then' | 'And';
|
|
411
|
+
text: string;
|
|
412
|
+
docString?: Record<string, unknown>;
|
|
413
|
+
}
|
|
416
414
|
|
|
417
|
-
|
|
418
|
-
|
|
415
|
+
interface StepWithError {
|
|
416
|
+
keyword: 'Then';
|
|
417
|
+
error: { type: string; message?: string };
|
|
418
|
+
}
|
|
419
419
|
|
|
420
|
-
|
|
421
|
-
if (example.given) {
|
|
422
|
-
gwtBlock.given = example.given.map((given) => {
|
|
423
|
-
if ('stateRef' in given) {
|
|
424
|
-
return { eventRef: given.stateRef, exampleData: given.exampleData };
|
|
425
|
-
} else if ('eventRef' in given) {
|
|
426
|
-
return { eventRef: given.eventRef, exampleData: given.exampleData };
|
|
427
|
-
}
|
|
428
|
-
return given;
|
|
429
|
-
});
|
|
430
|
-
}
|
|
420
|
+
type Step = StepWithDocString | StepWithError;
|
|
431
421
|
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
422
|
+
function isStepWithError(step: Step): step is StepWithError {
|
|
423
|
+
return 'error' in step;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
interface OldFormatThenItem {
|
|
427
|
+
eventRef?: string;
|
|
428
|
+
stateRef?: string;
|
|
429
|
+
commandRef?: string;
|
|
430
|
+
exampleData: Record<string, unknown>;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
interface OldFormatExample {
|
|
434
|
+
description?: string;
|
|
435
|
+
name?: string;
|
|
436
|
+
given?: Array<{ eventRef?: string; stateRef?: string; exampleData: Record<string, unknown> }>;
|
|
437
|
+
when?:
|
|
438
|
+
| { commandRef?: string; eventRef?: string; exampleData: Record<string, unknown> }
|
|
439
|
+
| Array<{ eventRef: string; exampleData: Record<string, unknown> }>;
|
|
440
|
+
then?: OldFormatThenItem[];
|
|
441
|
+
steps?: Step[];
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
function processErrorStep(step: StepWithError, gwtBlock: GWTBlock): void {
|
|
445
|
+
gwtBlock.then.push({
|
|
446
|
+
errorType: step.error.type as 'IllegalStateError' | 'ValidationError' | 'NotFoundError',
|
|
447
|
+
message: step.error.message,
|
|
448
|
+
});
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
function processGivenStep(step: StepWithDocString, gwtBlock: GWTBlock): void {
|
|
452
|
+
if (!gwtBlock.given) gwtBlock.given = [];
|
|
453
|
+
gwtBlock.given.push({ eventRef: step.text, exampleData: step.docString ?? {} });
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
function processWhenStep(
|
|
457
|
+
step: StepWithDocString,
|
|
458
|
+
sliceType: 'command' | 'query' | 'react' | 'experience',
|
|
459
|
+
gwtBlock: GWTBlock,
|
|
460
|
+
): void {
|
|
461
|
+
if (sliceType === 'command') {
|
|
462
|
+
gwtBlock.when = { commandRef: step.text, exampleData: step.docString ?? {} };
|
|
463
|
+
} else if (sliceType === 'react' || sliceType === 'query') {
|
|
464
|
+
const eventData = { eventRef: step.text, exampleData: step.docString ?? {} };
|
|
465
|
+
if (!gwtBlock.when) {
|
|
466
|
+
gwtBlock.when = [eventData];
|
|
467
|
+
} else if (Array.isArray(gwtBlock.when)) {
|
|
468
|
+
gwtBlock.when.push(eventData);
|
|
459
469
|
}
|
|
460
470
|
}
|
|
471
|
+
}
|
|
461
472
|
|
|
462
|
-
|
|
463
|
-
gwtBlock.then
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
+
function processThenStep(step: StepWithDocString, gwtBlock: GWTBlock): void {
|
|
474
|
+
gwtBlock.then.push({ eventRef: step.text, exampleData: step.docString ?? {} });
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
function processStepsFormat(
|
|
478
|
+
steps: Step[],
|
|
479
|
+
sliceType: 'command' | 'query' | 'react' | 'experience',
|
|
480
|
+
gwtBlock: GWTBlock,
|
|
481
|
+
): void {
|
|
482
|
+
let effectiveKeyword: 'Given' | 'When' | 'Then' = 'Given';
|
|
483
|
+
|
|
484
|
+
for (const step of steps) {
|
|
485
|
+
if (isStepWithError(step)) {
|
|
486
|
+
processErrorStep(step, gwtBlock);
|
|
487
|
+
continue;
|
|
473
488
|
}
|
|
474
|
-
|
|
489
|
+
|
|
490
|
+
if (step.keyword !== 'And') {
|
|
491
|
+
effectiveKeyword = step.keyword;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
if (effectiveKeyword === 'Given') {
|
|
495
|
+
processGivenStep(step, gwtBlock);
|
|
496
|
+
} else if (effectiveKeyword === 'When') {
|
|
497
|
+
processWhenStep(step, sliceType, gwtBlock);
|
|
498
|
+
} else if (effectiveKeyword === 'Then') {
|
|
499
|
+
processThenStep(step, gwtBlock);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
function mapThenItem(t: OldFormatThenItem): GWTBlock['then'][0] {
|
|
505
|
+
if (t.eventRef !== undefined && t.eventRef !== '') return { eventRef: t.eventRef, exampleData: t.exampleData };
|
|
506
|
+
if (t.commandRef !== undefined && t.commandRef !== '')
|
|
507
|
+
return { commandRef: t.commandRef, exampleData: t.exampleData };
|
|
508
|
+
if (t.stateRef !== undefined && t.stateRef !== '') return { stateRef: t.stateRef, exampleData: t.exampleData };
|
|
509
|
+
return { eventRef: '', exampleData: t.exampleData };
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
function processOldFormat(oldExample: OldFormatExample, gwtBlock: GWTBlock): void {
|
|
513
|
+
if (oldExample.given !== undefined && oldExample.given.length > 0) {
|
|
514
|
+
gwtBlock.given = oldExample.given.map((g) => ({
|
|
515
|
+
eventRef: g.eventRef ?? g.stateRef ?? '',
|
|
516
|
+
exampleData: g.exampleData,
|
|
517
|
+
}));
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
if (oldExample.when !== undefined) {
|
|
521
|
+
gwtBlock.when = oldExample.when as GWTBlock['when'];
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
if (oldExample.then !== undefined && oldExample.then.length > 0) {
|
|
525
|
+
gwtBlock.then = oldExample.then.map(mapThenItem);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
function convertExampleToGWT(example: Example, sliceType: 'command' | 'query' | 'react' | 'experience'): GWTBlock {
|
|
530
|
+
const gwtBlock: GWTBlock = { then: [] };
|
|
531
|
+
const oldExample = example as OldFormatExample;
|
|
532
|
+
(gwtBlock as { name?: string }).name = oldExample.name ?? oldExample.description;
|
|
533
|
+
|
|
534
|
+
if (oldExample.steps !== undefined && oldExample.steps.length > 0) {
|
|
535
|
+
processStepsFormat(oldExample.steps, sliceType, gwtBlock);
|
|
536
|
+
} else {
|
|
537
|
+
processOldFormat(oldExample, gwtBlock);
|
|
538
|
+
}
|
|
475
539
|
|
|
476
540
|
return gwtBlock;
|
|
477
541
|
}
|
|
478
542
|
|
|
479
|
-
type RuleType = { id?: string;
|
|
543
|
+
type RuleType = { id?: string; name: string; examples: Example[] };
|
|
480
544
|
type RuleGroup = { rule: RuleType; examples: Example[] };
|
|
545
|
+
type SpecType = { type: 'gherkin'; feature: string; rules: RuleType[] };
|
|
481
546
|
|
|
482
547
|
function buildRuleGroups(rules: RuleType[]): Map<string, RuleGroup> {
|
|
483
548
|
const ruleGroups = new Map<string, RuleGroup>();
|
|
484
549
|
|
|
485
550
|
for (const rule of rules) {
|
|
486
551
|
const ruleId = rule.id ?? 'no-id';
|
|
487
|
-
const ruleKey = `${ruleId}:${rule.
|
|
552
|
+
const ruleKey = `${ruleId}:${rule.name}`;
|
|
488
553
|
|
|
489
554
|
if (ruleGroups.has(ruleKey)) {
|
|
490
555
|
const existingGroup = ruleGroups.get(ruleKey)!;
|
|
@@ -513,21 +578,74 @@ function buildConsolidatedRules(
|
|
|
513
578
|
ruleDescription?: string;
|
|
514
579
|
exampleDescription?: string;
|
|
515
580
|
ruleId?: string;
|
|
581
|
+
exampleId?: string;
|
|
516
582
|
};
|
|
517
583
|
|
|
518
|
-
extendedGwtBlock.ruleDescription = rule.
|
|
519
|
-
|
|
584
|
+
extendedGwtBlock.ruleDescription = rule.name;
|
|
585
|
+
const oldFormatExample = example as { name?: string; description?: string };
|
|
586
|
+
extendedGwtBlock.exampleDescription = oldFormatExample.name ?? oldFormatExample.description;
|
|
520
587
|
extendedGwtBlock.ruleId = rule.id;
|
|
588
|
+
extendedGwtBlock.exampleId = example.id;
|
|
521
589
|
|
|
522
590
|
return extendedGwtBlock;
|
|
523
591
|
});
|
|
524
592
|
|
|
525
|
-
allRuleStatements.push(
|
|
593
|
+
allRuleStatements.push(
|
|
594
|
+
buildConsolidatedGwtSpecBlock(ts, f, { id: rule.id, description: rule.name }, gwtBlocks, sliceType, messages),
|
|
595
|
+
);
|
|
526
596
|
}
|
|
527
597
|
|
|
528
598
|
return allRuleStatements;
|
|
529
599
|
}
|
|
530
600
|
|
|
601
|
+
function buildSingleSpecStatements(
|
|
602
|
+
ts: typeof import('typescript'),
|
|
603
|
+
f: tsNS.NodeFactory,
|
|
604
|
+
spec: SpecType,
|
|
605
|
+
sliceType: 'command' | 'query' | 'react' | 'experience',
|
|
606
|
+
messages?: Array<{ type: string; name: string; fields: Array<{ name: string; type: string; required: boolean }> }>,
|
|
607
|
+
): tsNS.Statement {
|
|
608
|
+
const ruleGroups = buildRuleGroups(spec.rules);
|
|
609
|
+
const allRuleStatements = buildConsolidatedRules(ts, f, ruleGroups, sliceType, messages);
|
|
610
|
+
|
|
611
|
+
const arrowFunction = f.createArrowFunction(
|
|
612
|
+
undefined,
|
|
613
|
+
undefined,
|
|
614
|
+
[],
|
|
615
|
+
undefined,
|
|
616
|
+
f.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
617
|
+
f.createBlock(allRuleStatements, true),
|
|
618
|
+
);
|
|
619
|
+
|
|
620
|
+
const args: tsNS.Expression[] = [];
|
|
621
|
+
if (spec.feature && spec.feature.trim() !== '') {
|
|
622
|
+
args.push(f.createStringLiteral(spec.feature));
|
|
623
|
+
}
|
|
624
|
+
args.push(arrowFunction);
|
|
625
|
+
|
|
626
|
+
return f.createExpressionStatement(f.createCallExpression(f.createIdentifier('specs'), undefined, args));
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
interface OldSpecFormat {
|
|
630
|
+
name?: string;
|
|
631
|
+
rules?: Array<{ description?: string; id?: string; examples?: Example[] }>;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
function convertOldSpecToNewFormat(oldSpec: OldSpecFormat): SpecType | null {
|
|
635
|
+
if (oldSpec.rules === undefined || oldSpec.rules.length === 0) {
|
|
636
|
+
return null;
|
|
637
|
+
}
|
|
638
|
+
return {
|
|
639
|
+
type: 'gherkin',
|
|
640
|
+
feature: oldSpec.name ?? '',
|
|
641
|
+
rules: oldSpec.rules.map((r) => ({
|
|
642
|
+
id: r.id,
|
|
643
|
+
name: r.description ?? '',
|
|
644
|
+
examples: r.examples ?? [],
|
|
645
|
+
})),
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
|
|
531
649
|
function buildServerStatements(
|
|
532
650
|
ts: typeof import('typescript'),
|
|
533
651
|
f: tsNS.NodeFactory,
|
|
@@ -542,28 +660,16 @@ function buildServerStatements(
|
|
|
542
660
|
}
|
|
543
661
|
|
|
544
662
|
if (server.specs !== null && server.specs !== undefined) {
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
f.createBlock(allRuleStatements, true),
|
|
555
|
-
);
|
|
556
|
-
|
|
557
|
-
const args: tsNS.Expression[] = [];
|
|
558
|
-
if (server.specs.name && server.specs.name.trim() !== '') {
|
|
559
|
-
args.push(f.createStringLiteral(server.specs.name));
|
|
663
|
+
if (Array.isArray(server.specs)) {
|
|
664
|
+
for (const spec of server.specs as SpecType[]) {
|
|
665
|
+
statements.push(buildSingleSpecStatements(ts, f, spec, sliceType, messages));
|
|
666
|
+
}
|
|
667
|
+
} else {
|
|
668
|
+
const convertedSpec = convertOldSpecToNewFormat(server.specs as OldSpecFormat);
|
|
669
|
+
if (convertedSpec !== null) {
|
|
670
|
+
statements.push(buildSingleSpecStatements(ts, f, convertedSpec, sliceType, messages));
|
|
671
|
+
}
|
|
560
672
|
}
|
|
561
|
-
args.push(arrowFunction);
|
|
562
|
-
|
|
563
|
-
const specsStatement = f.createExpressionStatement(
|
|
564
|
-
f.createCallExpression(f.createIdentifier('specs'), undefined, args),
|
|
565
|
-
);
|
|
566
|
-
statements.push(specsStatement);
|
|
567
673
|
}
|
|
568
674
|
|
|
569
675
|
return statements;
|