effect-bdd 0.1.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.
Files changed (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +465 -0
  3. package/dist/Bdd.d.ts +285 -0
  4. package/dist/Bdd.d.ts.map +1 -0
  5. package/dist/Bdd.js +304 -0
  6. package/dist/Bdd.js.map +1 -0
  7. package/dist/Errors.d.ts +65 -0
  8. package/dist/Errors.d.ts.map +1 -0
  9. package/dist/Errors.js +58 -0
  10. package/dist/Errors.js.map +1 -0
  11. package/dist/bin.d.ts +3 -0
  12. package/dist/bin.d.ts.map +1 -0
  13. package/dist/bin.js +7 -0
  14. package/dist/bin.js.map +1 -0
  15. package/dist/index.d.ts +147 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +31 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/internal/cli/errors.d.ts +30 -0
  20. package/dist/internal/cli/errors.d.ts.map +1 -0
  21. package/dist/internal/cli/errors.js +8 -0
  22. package/dist/internal/cli/errors.js.map +1 -0
  23. package/dist/internal/cli/glob.d.ts +13 -0
  24. package/dist/internal/cli/glob.d.ts.map +1 -0
  25. package/dist/internal/cli/glob.js +29 -0
  26. package/dist/internal/cli/glob.js.map +1 -0
  27. package/dist/internal/cli/loaders.d.ts +13 -0
  28. package/dist/internal/cli/loaders.d.ts.map +1 -0
  29. package/dist/internal/cli/loaders.js +44 -0
  30. package/dist/internal/cli/loaders.js.map +1 -0
  31. package/dist/internal/cli/models.d.ts +102 -0
  32. package/dist/internal/cli/models.d.ts.map +1 -0
  33. package/dist/internal/cli/models.js +2 -0
  34. package/dist/internal/cli/models.js.map +1 -0
  35. package/dist/internal/cli/moduleLoader.d.ts +14 -0
  36. package/dist/internal/cli/moduleLoader.d.ts.map +1 -0
  37. package/dist/internal/cli/moduleLoader.js +39 -0
  38. package/dist/internal/cli/moduleLoader.js.map +1 -0
  39. package/dist/internal/cli/reporter.d.ts +22 -0
  40. package/dist/internal/cli/reporter.d.ts.map +1 -0
  41. package/dist/internal/cli/reporter.js +227 -0
  42. package/dist/internal/cli/reporter.js.map +1 -0
  43. package/dist/internal/cli/runner.d.ts +14 -0
  44. package/dist/internal/cli/runner.d.ts.map +1 -0
  45. package/dist/internal/cli/runner.js +178 -0
  46. package/dist/internal/cli/runner.js.map +1 -0
  47. package/dist/internal/cli/tagExpression.d.ts +7 -0
  48. package/dist/internal/cli/tagExpression.d.ts.map +1 -0
  49. package/dist/internal/cli/tagExpression.js +127 -0
  50. package/dist/internal/cli/tagExpression.js.map +1 -0
  51. package/dist/internal/cucumberCompiler.d.ts +5 -0
  52. package/dist/internal/cucumberCompiler.d.ts.map +1 -0
  53. package/dist/internal/cucumberCompiler.js +49 -0
  54. package/dist/internal/cucumberCompiler.js.map +1 -0
  55. package/dist/internal/expression.d.ts +18 -0
  56. package/dist/internal/expression.d.ts.map +1 -0
  57. package/dist/internal/expression.js +59 -0
  58. package/dist/internal/expression.js.map +1 -0
  59. package/dist/internal/matching.d.ts +30 -0
  60. package/dist/internal/matching.d.ts.map +1 -0
  61. package/dist/internal/matching.js +37 -0
  62. package/dist/internal/matching.js.map +1 -0
  63. package/dist/internal/parser.d.ts +54 -0
  64. package/dist/internal/parser.d.ts.map +1 -0
  65. package/dist/internal/parser.js +93 -0
  66. package/dist/internal/parser.js.map +1 -0
  67. package/dist/internal/runner.d.ts +77 -0
  68. package/dist/internal/runner.d.ts.map +1 -0
  69. package/dist/internal/runner.js +117 -0
  70. package/dist/internal/runner.js.map +1 -0
  71. package/dist/main.d.ts +23 -0
  72. package/dist/main.d.ts.map +1 -0
  73. package/dist/main.js +104 -0
  74. package/dist/main.js.map +1 -0
  75. package/package.json +102 -0
  76. package/src/Bdd.ts +575 -0
  77. package/src/Errors.ts +60 -0
  78. package/src/bin.ts +10 -0
  79. package/src/index.ts +155 -0
  80. package/src/internal/cli/errors.ts +20 -0
  81. package/src/internal/cli/glob.ts +37 -0
  82. package/src/internal/cli/loaders.ts +100 -0
  83. package/src/internal/cli/models.ts +118 -0
  84. package/src/internal/cli/moduleLoader.ts +41 -0
  85. package/src/internal/cli/reporter.ts +367 -0
  86. package/src/internal/cli/runner.ts +336 -0
  87. package/src/internal/cli/tagExpression.ts +173 -0
  88. package/src/internal/cucumberCompiler.ts +58 -0
  89. package/src/internal/expression.ts +103 -0
  90. package/src/internal/matching.ts +81 -0
  91. package/src/internal/parser.ts +155 -0
  92. package/src/internal/runner.ts +373 -0
  93. package/src/main.ts +169 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tagExpression.js","names":["Arr","Effect","pipe","Str","DiscoveryError","compileAll","expressions","forEach","compile","map","predicates","tags","every","predicate","expression","tokens","tokenize","undefined","length","fail","result","parseOr","index","succeed","evaluate","left","parseAnd","parseOrRest","right","_tag","parseUnary","parseAndRest","parseNot","parsePrimary","token","startsWith","tag","contains","matches","match","normalized","replace","matched","join","message"],"sources":["../../../src/internal/cli/tagExpression.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,5 @@
1
+ import * as Layer from "effect/Layer";
2
+ import { GherkinCompiler } from "./parser.ts";
3
+ /** @internal */
4
+ export declare const Cucumber: Layer.Layer<GherkinCompiler, never, never>;
5
+ //# sourceMappingURL=cucumberCompiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cucumberCompiler.d.ts","sourceRoot":"","sources":["../../src/internal/cucumberCompiler.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,cAAc,CAAA;AAErC,OAAO,EAAE,eAAe,EAAqB,MAAM,aAAa,CAAA;AAEhE,gBAAgB;AAChB,eAAO,MAAM,QAAQ,4CAMnB,CAAA"}
@@ -0,0 +1,49 @@
1
+ import { AstBuilder, compile, GherkinClassicTokenMatcher, Parser } from "@cucumber/gherkin";
2
+ import { IdGenerator } from "@cucumber/messages";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Layer from "effect/Layer";
5
+ import { ParseError } from "../Errors.js";
6
+ import { GherkinCompiler } from "./parser.js";
7
+ /** @internal */
8
+ export const Cucumber = /*#__PURE__*/Layer.succeed(GherkinCompiler, {
9
+ compile: (source, uri) => Effect.try({
10
+ try: () => compileWithCucumber(source, uri),
11
+ catch: parseErrorFromCause
12
+ })
13
+ });
14
+ const compileWithCucumber = (source, uri) => {
15
+ const newId = IdGenerator.incrementing();
16
+ const parser = new Parser(new AstBuilder(newId), new GherkinClassicTokenMatcher());
17
+ const document = parser.parse(source);
18
+ return {
19
+ document,
20
+ pickles: compile(document, uri, newId)
21
+ };
22
+ };
23
+ const parseErrorFromCause = cause => {
24
+ const location = causeLocation(cause);
25
+ return new ParseError({
26
+ message: causeMessage(cause),
27
+ line: location?.line ?? 1,
28
+ column: location?.column ?? 1
29
+ });
30
+ };
31
+ const causeLocation = cause => {
32
+ if (typeof cause === "object" && cause !== null && "errors" in cause && Array.isArray(cause.errors) && cause.errors.length > 0) {
33
+ return causeLocation(cause.errors[0]);
34
+ }
35
+ if (typeof cause === "object" && cause !== null && "location" in cause) {
36
+ const location = cause.location;
37
+ if (typeof location === "object" && location !== null && "line" in location && typeof location.line === "number") {
38
+ return {
39
+ line: location.line,
40
+ ...("column" in location && typeof location.column === "number" ? {
41
+ column: location.column
42
+ } : {})
43
+ };
44
+ }
45
+ }
46
+ return undefined;
47
+ };
48
+ const causeMessage = cause => typeof cause === "object" && cause !== null && "message" in cause && typeof cause.message === "string" ? cause.message : String(cause);
49
+ //# sourceMappingURL=cucumberCompiler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cucumberCompiler.js","names":["AstBuilder","compile","GherkinClassicTokenMatcher","Parser","IdGenerator","Effect","Layer","ParseError","GherkinCompiler","Cucumber","succeed","source","uri","try","compileWithCucumber","catch","parseErrorFromCause","newId","incrementing","parser","document","parse","pickles","cause","location","causeLocation","message","causeMessage","line","column","Array","isArray","errors","length","undefined","String"],"sources":["../../src/internal/cucumberCompiler.ts"],"sourcesContent":[null],"mappings":"AAAA,SAASA,UAAU,EAAEC,OAAO,EAAEC,0BAA0B,EAAEC,MAAM,QAAQ,mBAAmB;AAC3F,SAASC,WAAW,QAAQ,oBAAoB;AAChD,OAAO,KAAKC,MAAM,MAAM,eAAe;AACvC,OAAO,KAAKC,KAAK,MAAM,cAAc;AACrC,SAASC,UAAU,QAAQ,cAAc;AACzC,SAASC,eAAe,QAA2B,aAAa;AAEhE;AACA,OAAO,MAAMC,QAAQ,gBAAGH,KAAK,CAACI,OAAO,CAACF,eAAe,EAAE;EACrDP,OAAO,EAAEA,CAACU,MAAM,EAAEC,GAAG,KACnBP,MAAM,CAACQ,GAAG,CAAC;IACTA,GAAG,EAAEA,CAAA,KAAMC,mBAAmB,CAACH,MAAM,EAAEC,GAAG,CAAC;IAC3CG,KAAK,EAAEC;GACR;CACJ,CAAC;AAEF,MAAMF,mBAAmB,GAAGA,CAACH,MAAc,EAAEC,GAAW,KAAkB;EACxE,MAAMK,KAAK,GAAGb,WAAW,CAACc,YAAY,EAAE;EACxC,MAAMC,MAAM,GAAG,IAAIhB,MAAM,CAAC,IAAIH,UAAU,CAACiB,KAAK,CAAC,EAAE,IAAIf,0BAA0B,EAAE,CAAC;EAClF,MAAMkB,QAAQ,GAAGD,MAAM,CAACE,KAAK,CAACV,MAAM,CAAC;EACrC,OAAO;IACLS,QAAQ;IACRE,OAAO,EAAErB,OAAO,CAACmB,QAAQ,EAAER,GAAG,EAAEK,KAAK;GACtC;AACH,CAAC;AAED,MAAMD,mBAAmB,GAAIO,KAAc,IAAgB;EACzD,MAAMC,QAAQ,GAAGC,aAAa,CAACF,KAAK,CAAC;EACrC,OAAO,IAAIhB,UAAU,CAAC;IACpBmB,OAAO,EAAEC,YAAY,CAACJ,KAAK,CAAC;IAC5BK,IAAI,EAAEJ,QAAQ,EAAEI,IAAI,IAAI,CAAC;IACzBC,MAAM,EAAEL,QAAQ,EAAEK,MAAM,IAAI;GAC7B,CAAC;AACJ,CAAC;AAED,MAAMJ,aAAa,GAAIF,KAAc,IAAqE;EACxG,IACE,OAAOA,KAAK,KAAK,QAAQ,IAAIA,KAAK,KAAK,IAAI,IAAI,QAAQ,IAAIA,KAAK,IAAIO,KAAK,CAACC,OAAO,CAACR,KAAK,CAACS,MAAM,CAAC,IAC/FT,KAAK,CAACS,MAAM,CAACC,MAAM,GAAG,CAAC,EACvB;IACA,OAAOR,aAAa,CAACF,KAAK,CAACS,MAAM,CAAC,CAAC,CAAC,CAAC;EACvC;EACA,IAAI,OAAOT,KAAK,KAAK,QAAQ,IAAIA,KAAK,KAAK,IAAI,IAAI,UAAU,IAAIA,KAAK,EAAE;IACtE,MAAMC,QAAQ,GAAGD,KAAK,CAACC,QAAQ;IAC/B,IAAI,OAAOA,QAAQ,KAAK,QAAQ,IAAIA,QAAQ,KAAK,IAAI,IAAI,MAAM,IAAIA,QAAQ,IAAI,OAAOA,QAAQ,CAACI,IAAI,KAAK,QAAQ,EAAE;MAChH,OAAO;QACLA,IAAI,EAAEJ,QAAQ,CAACI,IAAI;QACnB,IAAI,QAAQ,IAAIJ,QAAQ,IAAI,OAAOA,QAAQ,CAACK,MAAM,KAAK,QAAQ,GAAG;UAAEA,MAAM,EAAEL,QAAQ,CAACK;QAAM,CAAE,GAAG,EAAE;OACnG;IACH;EACF;EACA,OAAOK,SAAS;AAClB,CAAC;AAED,MAAMP,YAAY,GAAIJ,KAAc,IAClC,OAAOA,KAAK,KAAK,QAAQ,IAAIA,KAAK,KAAK,IAAI,IAAI,SAAS,IAAIA,KAAK,IAAI,OAAOA,KAAK,CAACG,OAAO,KAAK,QAAQ,GAClGH,KAAK,CAACG,OAAO,GACbS,MAAM,CAACZ,KAAK,CAAC","ignoreList":[]}
@@ -0,0 +1,18 @@
1
+ import * as Option from "effect/Option";
2
+ import * as Schema from "effect/Schema";
3
+ /** @internal */
4
+ export interface Capture<Name extends string, A> {
5
+ readonly _tag: "Capture";
6
+ readonly name: Name;
7
+ readonly schema: Schema.Codec<A, string>;
8
+ }
9
+ /** @internal */
10
+ export interface Matcher<A> {
11
+ readonly source: string;
12
+ readonly match: (text: string) => Option.Option<A>;
13
+ }
14
+ /** @internal */
15
+ export declare const makeCapture: <const Name extends string, A>(name: Name, schema: Schema.Codec<A, string>) => Capture<Name, A>;
16
+ /** @internal */
17
+ export declare const makeMatcher: <A>(strings: TemplateStringsArray, captures: ReadonlyArray<Capture<string, unknown>>) => Matcher<A>;
18
+ //# sourceMappingURL=expression.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expression.d.ts","sourceRoot":"","sources":["../../src/internal/expression.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAGvC,gBAAgB;AAChB,MAAM,WAAW,OAAO,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC;IAC7C,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAA;CACzC;AAED,gBAAgB;AAChB,MAAM,WAAW,OAAO,CAAC,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;CACnD;AASD,gBAAgB;AAChB,eAAO,MAAM,WAAW,GAAI,KAAK,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC,EACtD,MAAM,IAAI,EACV,QAAQ,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,KAC9B,OAAO,CAAC,IAAI,EAAE,CAAC,CAIhB,CAAA;AAEF,gBAAgB;AAChB,eAAO,MAAM,WAAW,GAAI,CAAC,EAC3B,SAAS,oBAAoB,EAC7B,UAAU,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAChD,OAAO,CAAC,CAAC,CAkBX,CAAA"}
@@ -0,0 +1,59 @@
1
+ import * as Arr from "effect/Array";
2
+ import { pipe } from "effect/Function";
3
+ import * as Option from "effect/Option";
4
+ import * as Record from "effect/Record";
5
+ import * as Schema from "effect/Schema";
6
+ import * as Str from "effect/String";
7
+ /** @internal */
8
+ export const makeCapture = (name, schema) => ({
9
+ _tag: "Capture",
10
+ name,
11
+ schema
12
+ });
13
+ /** @internal */
14
+ export const makeMatcher = (strings, captures) => {
15
+ const state = pipe(strings, Arr.reduce(initialMatcherState, (state, literal, index) => appendTemplatePart(state, literal, captures[index])));
16
+ const regex = new globalThis.RegExp(`${state.pattern}$`);
17
+ const decoders = Arr.map(state.captures, capture => Schema.decodeUnknownOption(capture.schema));
18
+ return {
19
+ source: state.source,
20
+ match(text) {
21
+ const match = regex.exec(text);
22
+ if (match === null) {
23
+ return Option.none();
24
+ }
25
+ return Option.map(decodeCaptures(state.names, decoders, match), out => out);
26
+ }
27
+ };
28
+ };
29
+ const initialMatcherState = {
30
+ names: [],
31
+ captures: [],
32
+ source: "",
33
+ pattern: "^"
34
+ };
35
+ const appendTemplatePart = (state, literal, capture) => {
36
+ const pattern = `${state.pattern}${escapeRegExp(literal)}`;
37
+ const source = `${state.source}${literal}`;
38
+ if (capture === undefined) {
39
+ return {
40
+ ...state,
41
+ pattern,
42
+ source
43
+ };
44
+ }
45
+ return {
46
+ names: Arr.append(state.names, capture.name),
47
+ captures: Arr.append(state.captures, capture),
48
+ pattern: `${pattern}(.+?)`,
49
+ source: `${source}{${capture.name}}`
50
+ };
51
+ };
52
+ const decodeCaptures = (names, decoders, match, index = 0, out = Record.empty()) => {
53
+ if (index >= names.length) {
54
+ return Option.some(out);
55
+ }
56
+ return pipe(decoders[index](match[index + 1]), Option.flatMap(value => decodeCaptures(names, decoders, match, index + 1, Record.set(out, names[index], value))));
57
+ };
58
+ const escapeRegExp = /*#__PURE__*/Str.replace(/[/\\^$*+?.()|[\]{}]/g, "\\$&");
59
+ //# sourceMappingURL=expression.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expression.js","names":["Arr","pipe","Option","Record","Schema","Str","makeCapture","name","schema","_tag","makeMatcher","strings","captures","state","reduce","initialMatcherState","literal","index","appendTemplatePart","regex","globalThis","RegExp","pattern","decoders","map","capture","decodeUnknownOption","source","match","text","exec","none","decodeCaptures","names","out","escapeRegExp","undefined","append","empty","length","some","flatMap","value","set","replace"],"sources":["../../src/internal/expression.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,30 @@
1
+ import { type PickleStep } from "@cucumber/messages";
2
+ import * as Option from "effect/Option";
3
+ /** @internal */
4
+ export type StepKind = "Step" | "Given" | "When" | "Then";
5
+ /** @internal */
6
+ export type ConcreteStepKind = "Given" | "When" | "Then";
7
+ /** @internal */
8
+ export interface MatchableTransition {
9
+ readonly kind: StepKind;
10
+ readonly expression: {
11
+ readonly source: string;
12
+ readonly match: (text: string) => Option.Option<unknown>;
13
+ };
14
+ }
15
+ /** @internal */
16
+ export interface MatchedTransition<Transition extends MatchableTransition> {
17
+ readonly transition: Transition;
18
+ readonly captures: unknown;
19
+ }
20
+ /** @internal */
21
+ export declare const matchingTextTransitions: <Transition extends MatchableTransition>(transitions: ReadonlyArray<Transition>, text: string) => ReadonlyArray<MatchedTransition<Transition>>;
22
+ /** @internal */
23
+ export declare const matchingKeywordTransitions: <Transition extends MatchableTransition>(transitions: ReadonlyArray<MatchedTransition<Transition>>, kind: ConcreteStepKind) => ReadonlyArray<MatchedTransition<Transition>>;
24
+ /** @internal */
25
+ export declare const keywordMatches: (transition: StepKind, keyword: ConcreteStepKind) => boolean;
26
+ /** @internal */
27
+ export declare const concreteStepKind: (step: PickleStep) => Option.Option<ConcreteStepKind>;
28
+ /** @internal */
29
+ export declare const renderTransitionKinds: <Transition extends MatchableTransition>(transitions: ReadonlyArray<Transition>) => string;
30
+ //# sourceMappingURL=matching.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matching.d.ts","sourceRoot":"","sources":["../../src/internal/matching.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAAkB,MAAM,oBAAoB,CAAA;AAGpE,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,gBAAgB;AAChB,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;AAEzD,gBAAgB;AAChB,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;AAExD,gBAAgB;AAChB,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;IACvB,QAAQ,CAAC,UAAU,EAAE;QACnB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;QACvB,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;KACzD,CAAA;CACF;AAED,gBAAgB;AAChB,MAAM,WAAW,iBAAiB,CAAC,UAAU,SAAS,mBAAmB;IACvE,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAA;IAC/B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAA;CAC3B;AAED,gBAAgB;AAChB,eAAO,MAAM,uBAAuB,GAAI,UAAU,SAAS,mBAAmB,EAC5E,aAAa,aAAa,CAAC,UAAU,CAAC,EACtC,MAAM,MAAM,KACX,aAAa,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAU3C,CAAA;AAEH,gBAAgB;AAChB,eAAO,MAAM,0BAA0B,GAAI,UAAU,SAAS,mBAAmB,EAC/E,aAAa,aAAa,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC,EACzD,MAAM,gBAAgB,KACrB,aAAa,CAAC,iBAAiB,CAAC,UAAU,CAAC,CACmC,CAAA;AAEjF,gBAAgB;AAChB,eAAO,MAAM,cAAc,GAAI,YAAY,QAAQ,EAAE,SAAS,gBAAgB,KAAG,OAChC,CAAA;AAEjD,gBAAgB;AAChB,eAAO,MAAM,gBAAgB,GAAI,MAAM,UAAU,KAAG,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAejF,CAAA;AAED,gBAAgB;AAChB,eAAO,MAAM,qBAAqB,GAAI,UAAU,SAAS,mBAAmB,EAC1E,aAAa,aAAa,CAAC,UAAU,CAAC,KACrC,MAMA,CAAA"}
@@ -0,0 +1,37 @@
1
+ import { PickleStepType } from "@cucumber/messages";
2
+ import * as Arr from "effect/Array";
3
+ import { pipe } from "effect/Function";
4
+ import * as Option from "effect/Option";
5
+ /** @internal */
6
+ export const matchingTextTransitions = (transitions, text) => pipe(transitions, Arr.map(transition => pipe(transition.expression.match(text), Option.map(captures => ({
7
+ transition,
8
+ captures
9
+ })))), Arr.getSomes);
10
+ /** @internal */
11
+ export const matchingKeywordTransitions = (transitions, kind) => Arr.filter(transitions, match => keywordMatches(match.transition.kind, kind));
12
+ /** @internal */
13
+ export const keywordMatches = (transition, keyword) => transition === "Step" || transition === keyword;
14
+ /** @internal */
15
+ export const concreteStepKind = step => {
16
+ switch (step.type) {
17
+ case PickleStepType.CONTEXT:
18
+ {
19
+ return Option.some("Given");
20
+ }
21
+ case PickleStepType.ACTION:
22
+ {
23
+ return Option.some("When");
24
+ }
25
+ case PickleStepType.OUTCOME:
26
+ {
27
+ return Option.some("Then");
28
+ }
29
+ default:
30
+ {
31
+ return Option.none();
32
+ }
33
+ }
34
+ };
35
+ /** @internal */
36
+ export const renderTransitionKinds = transitions => pipe(transitions, Arr.map(transition => transition.kind), Arr.dedupe, Arr.join(", "));
37
+ //# sourceMappingURL=matching.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"matching.js","names":["PickleStepType","Arr","pipe","Option","matchingTextTransitions","transitions","text","map","transition","expression","match","captures","getSomes","matchingKeywordTransitions","kind","filter","keywordMatches","keyword","concreteStepKind","step","type","CONTEXT","some","ACTION","OUTCOME","none","renderTransitionKinds","dedupe","join"],"sources":["../../src/internal/matching.ts"],"sourcesContent":[null],"mappings":"AAAA,SAA0BA,cAAc,QAAQ,oBAAoB;AACpE,OAAO,KAAKC,GAAG,MAAM,cAAc;AACnC,SAASC,IAAI,QAAQ,iBAAiB;AACtC,OAAO,KAAKC,MAAM,MAAM,eAAe;AAuBvC;AACA,OAAO,MAAMC,uBAAuB,GAAGA,CACrCC,WAAsC,EACtCC,IAAY,KAEZJ,IAAI,CACFG,WAAW,EACXJ,GAAG,CAACM,GAAG,CAAEC,UAAU,IACjBN,IAAI,CACFM,UAAU,CAACC,UAAU,CAACC,KAAK,CAACJ,IAAI,CAAC,EACjCH,MAAM,CAACI,GAAG,CAAEI,QAAQ,KAAM;EAAEH,UAAU;EAAEG;AAAQ,CAAE,CAAC,CAAC,CACrD,CACF,EACDV,GAAG,CAACW,QAAQ,CACb;AAEH;AACA,OAAO,MAAMC,0BAA0B,GAAGA,CACxCR,WAAyD,EACzDS,IAAsB,KAEtBb,GAAG,CAACc,MAAM,CAACV,WAAW,EAAGK,KAAK,IAAKM,cAAc,CAACN,KAAK,CAACF,UAAU,CAACM,IAAI,EAAEA,IAAI,CAAC,CAAC;AAEjF;AACA,OAAO,MAAME,cAAc,GAAGA,CAACR,UAAoB,EAAES,OAAyB,KAC5ET,UAAU,KAAK,MAAM,IAAIA,UAAU,KAAKS,OAAO;AAEjD;AACA,OAAO,MAAMC,gBAAgB,GAAIC,IAAgB,IAAqC;EACpF,QAAQA,IAAI,CAACC,IAAI;IACf,KAAKpB,cAAc,CAACqB,OAAO;MAAE;QAC3B,OAAOlB,MAAM,CAACmB,IAAI,CAAC,OAAO,CAAC;MAC7B;IACA,KAAKtB,cAAc,CAACuB,MAAM;MAAE;QAC1B,OAAOpB,MAAM,CAACmB,IAAI,CAAC,MAAM,CAAC;MAC5B;IACA,KAAKtB,cAAc,CAACwB,OAAO;MAAE;QAC3B,OAAOrB,MAAM,CAACmB,IAAI,CAAC,MAAM,CAAC;MAC5B;IACA;MAAS;QACP,OAAOnB,MAAM,CAACsB,IAAI,EAAE;MACtB;EACF;AACF,CAAC;AAED;AACA,OAAO,MAAMC,qBAAqB,GAChCrB,WAAsC,IAEtCH,IAAI,CACFG,WAAW,EACXJ,GAAG,CAACM,GAAG,CAAEC,UAAU,IAAKA,UAAU,CAACM,IAAI,CAAC,EACxCb,GAAG,CAAC0B,MAAM,EACV1B,GAAG,CAAC2B,IAAI,CAAC,IAAI,CAAC,CACf","ignoreList":[]}
@@ -0,0 +1,54 @@
1
+ import type { GherkinDocument, Pickle, Rule as CucumberRule, Scenario as CucumberScenario, Step as CucumberStep } from "@cucumber/messages";
2
+ import * as Context from "effect/Context";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Option from "effect/Option";
5
+ import { ParseError } from "../Errors.ts";
6
+ /** @internal */
7
+ export type Keyword = "Given" | "When" | "Then" | "And" | "But" | "*";
8
+ /** @internal */
9
+ export interface CompiledFeature {
10
+ readonly name: string;
11
+ readonly line: number;
12
+ readonly pickles: ReadonlyArray<Pickle>;
13
+ readonly source: SourceIndex;
14
+ }
15
+ /** @internal */
16
+ export interface ParsedSource {
17
+ readonly document: GherkinDocument;
18
+ readonly pickles: ReadonlyArray<Pickle>;
19
+ }
20
+ declare const GherkinCompiler_base: Context.ServiceClass<GherkinCompiler, "effect-bdd/GherkinCompiler", {
21
+ readonly compile: (source: string, uri: string) => Effect.Effect<ParsedSource, ParseError>;
22
+ }>;
23
+ /** @internal */
24
+ export declare class GherkinCompiler extends GherkinCompiler_base {
25
+ }
26
+ /** @internal */
27
+ export interface SourceIndex {
28
+ readonly steps: ReadonlyMap<string, CucumberStep>;
29
+ readonly scenarios: ReadonlyMap<string, {
30
+ readonly scenario: CucumberScenario;
31
+ readonly rule: CucumberRule | undefined;
32
+ }>;
33
+ }
34
+ /** @internal */
35
+ export declare const parse: (source: string, uri?: string) => Effect.Effect<CompiledFeature, ParseError, GherkinCompiler>;
36
+ /** @internal */
37
+ export declare const findScenario: (pickle: Pickle, index: SourceIndex) => Option.Option<{
38
+ readonly scenario: CucumberScenario;
39
+ readonly rule: CucumberRule | undefined;
40
+ }>;
41
+ /** @internal */
42
+ export declare const findStep: (pickleStep: {
43
+ readonly astNodeIds: ReadonlyArray<string>;
44
+ }, index: SourceIndex) => CucumberStep | undefined;
45
+ /** @internal */
46
+ export declare const stepLine: (step: {
47
+ readonly astNodeIds: ReadonlyArray<string>;
48
+ }, index: SourceIndex) => number;
49
+ /** @internal */
50
+ export declare const stepKeyword: (step: {
51
+ readonly astNodeIds: ReadonlyArray<string>;
52
+ }, index: SourceIndex) => Keyword;
53
+ export {};
54
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/internal/parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,eAAe,EACf,MAAM,EACN,IAAI,IAAI,YAAY,EACpB,QAAQ,IAAI,gBAAgB,EAC5B,IAAI,IAAI,YAAY,EACrB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAA;AACzC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AAEvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAEzC,gBAAgB;AAChB,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,GAAG,CAAA;AAErE,gBAAgB;AAChB,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACvC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;CAC7B;AAED,gBAAgB;AAChB,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAA;IAClC,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CACxC;;sBAImB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,UAAU,CAAC;;AAF5F,gBAAgB;AAChB,qBAAa,eAAgB,SAAQ,oBAEH;CAAG;AAErC,gBAAgB;AAChB,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IACjD,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,MAAM,EAAE;QACtC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAA;QACnC,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,SAAS,CAAA;KACxC,CAAC,CAAA;CACH;AAED,gBAAgB;AAChB,eAAO,MAAM,KAAK,GAAI,QAAQ,MAAM,EAAE,YAAgB,KAAG,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,UAAU,EAAE,eAAe,CACJ,CAAA;AAoE/G,gBAAgB;AAChB,eAAO,MAAM,YAAY,GAAI,QAAQ,MAAM,EAAE,OAAO,WAAW;uBA5ExC,gBAAgB;mBACpB,YAAY,GAAG,SAAS;EAiFxC,CAAA;AAEH,gBAAgB;AAChB,eAAO,MAAM,QAAQ,GACnB,YAAY;IAAE,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAAE,EAC1D,OAAO,WAAW,KACjB,YAAY,GAAG,SAGqB,CAAA;AAEvC,gBAAgB;AAChB,eAAO,MAAM,QAAQ,GACnB,MAAM;IAAE,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAAE,EACpD,OAAO,WAAW,KACjB,MAAmD,CAAA;AAEtD,gBAAgB;AAChB,eAAO,MAAM,WAAW,GACtB,MAAM;IAAE,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CAAE,EACpD,OAAO,WAAW,KACjB,OAGF,CAAA"}
@@ -0,0 +1,93 @@
1
+ import * as Context from "effect/Context";
2
+ import * as Effect from "effect/Effect";
3
+ import { pipe } from "effect/Function";
4
+ import * as Option from "effect/Option";
5
+ import { ParseError } from "../Errors.js";
6
+ /** @internal */
7
+ export class GherkinCompiler extends /*#__PURE__*/Context.Service()("effect-bdd/GherkinCompiler") {}
8
+ /** @internal */
9
+ export const parse = (source, uri = "<inline>") => Effect.flatMap(GherkinCompiler, compiler => pipe(compiler.compile(source, uri), Effect.flatMap(toFeature)));
10
+ const toFeature = /*#__PURE__*/Effect.fnUntraced(function* (parsed) {
11
+ const feature = parsed.document.feature;
12
+ if (feature === undefined) {
13
+ return yield* parseError("Expected a Feature declaration", 1, 1);
14
+ }
15
+ if (parsed.pickles.length === 0) {
16
+ return yield* parseError("Expected at least one Scenario", feature.location.line, feature.location.column ?? 1);
17
+ }
18
+ const source = indexDocument(parsed.document);
19
+ return {
20
+ name: feature.name,
21
+ line: feature.location.line,
22
+ pickles: parsed.pickles,
23
+ source
24
+ };
25
+ });
26
+ const indexDocument = document => {
27
+ const steps = new Map();
28
+ const scenarios = new Map();
29
+ const feature = document.feature;
30
+ if (feature === undefined) {
31
+ return {
32
+ steps,
33
+ scenarios
34
+ };
35
+ }
36
+ for (const child of feature.children) {
37
+ if (child.background !== undefined) {
38
+ indexBackground(steps, child.background);
39
+ }
40
+ if (child.scenario !== undefined) {
41
+ indexScenario(steps, scenarios, child.scenario, undefined);
42
+ }
43
+ if (child.rule !== undefined) {
44
+ for (const ruleChild of child.rule.children) {
45
+ if (ruleChild.background !== undefined) {
46
+ indexBackground(steps, ruleChild.background);
47
+ }
48
+ if (ruleChild.scenario !== undefined) {
49
+ indexScenario(steps, scenarios, ruleChild.scenario, child.rule);
50
+ }
51
+ }
52
+ }
53
+ }
54
+ return {
55
+ steps,
56
+ scenarios
57
+ };
58
+ };
59
+ const indexBackground = (steps, background) => {
60
+ for (const step of background.steps) {
61
+ steps.set(step.id, step);
62
+ }
63
+ };
64
+ const indexScenario = (steps, scenarios, scenario, rule) => {
65
+ scenarios.set(scenario.id, {
66
+ scenario,
67
+ rule
68
+ });
69
+ for (const step of scenario.steps) {
70
+ steps.set(step.id, step);
71
+ }
72
+ };
73
+ /** @internal */
74
+ export const findScenario = (pickle, index) => pipe(pickle.astNodeIds, Option.liftPredicate(ids => ids.length > 0), Option.flatMap(() => Option.fromNullishOr(pickle.astNodeIds.find(id => index.scenarios.has(id)))), Option.flatMap(id => Option.fromNullishOr(index.scenarios.get(id))));
75
+ /** @internal */
76
+ export const findStep = (pickleStep, index) => pickleStep.astNodeIds.map(id => index.steps.get(id)).find(step => step !== undefined);
77
+ /** @internal */
78
+ export const stepLine = (step, index) => findStep(step, index)?.location.line ?? 1;
79
+ /** @internal */
80
+ export const stepKeyword = (step, index) => {
81
+ const source = findStep(step, index);
82
+ return source === undefined ? "Given" : normalizeKeyword(source.keyword);
83
+ };
84
+ const normalizeKeyword = keyword => {
85
+ const trimmed = keyword.trim();
86
+ return trimmed === "*" ? "*" : trimmed;
87
+ };
88
+ const parseError = (message, line, column) => Effect.fail(new ParseError({
89
+ message,
90
+ line,
91
+ column
92
+ }));
93
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","names":["Context","Effect","pipe","Option","ParseError","GherkinCompiler","Service","parse","source","uri","flatMap","compiler","compile","toFeature","fnUntraced","parsed","feature","document","undefined","parseError","pickles","length","location","line","column","indexDocument","name","steps","Map","scenarios","child","children","background","indexBackground","scenario","indexScenario","rule","ruleChild","step","set","id","findScenario","pickle","index","astNodeIds","liftPredicate","ids","fromNullishOr","find","has","get","findStep","pickleStep","map","stepLine","stepKeyword","normalizeKeyword","keyword","trimmed","trim","message","fail"],"sources":["../../src/internal/parser.ts"],"sourcesContent":[null],"mappings":"AAQA,OAAO,KAAKA,OAAO,MAAM,gBAAgB;AACzC,OAAO,KAAKC,MAAM,MAAM,eAAe;AACvC,SAASC,IAAI,QAAQ,iBAAiB;AACtC,OAAO,KAAKC,MAAM,MAAM,eAAe;AACvC,SAASC,UAAU,QAAQ,cAAc;AAmBzC;AACA,OAAM,MAAOC,eAAgB,sBAAQL,OAAO,CAACM,OAAO,EAEhD,CAAC,4BAA4B,CAAC;AAWlC;AACA,OAAO,MAAMC,KAAK,GAAGA,CAACC,MAAc,EAAEC,GAAG,GAAG,UAAU,KACpDR,MAAM,CAACS,OAAO,CAACL,eAAe,EAAGM,QAAQ,IAAKT,IAAI,CAACS,QAAQ,CAACC,OAAO,CAACJ,MAAM,EAAEC,GAAG,CAAC,EAAER,MAAM,CAACS,OAAO,CAACG,SAAS,CAAC,CAAC,CAAC;AAE/G,MAAMA,SAAS,gBAAyEZ,MAAM,CAACa,UAAU,CAAC,WACxGC,MAAM;EAEN,MAAMC,OAAO,GAAGD,MAAM,CAACE,QAAQ,CAACD,OAAO;EACvC,IAAIA,OAAO,KAAKE,SAAS,EAAE;IACzB,OAAO,OAAOC,UAAU,CAAC,gCAAgC,EAAE,CAAC,EAAE,CAAC,CAAC;EAClE;EACA,IAAIJ,MAAM,CAACK,OAAO,CAACC,MAAM,KAAK,CAAC,EAAE;IAC/B,OAAO,OAAOF,UAAU,CAAC,gCAAgC,EAAEH,OAAO,CAACM,QAAQ,CAACC,IAAI,EAAEP,OAAO,CAACM,QAAQ,CAACE,MAAM,IAAI,CAAC,CAAC;EACjH;EAEA,MAAMhB,MAAM,GAAGiB,aAAa,CAACV,MAAM,CAACE,QAAQ,CAAC;EAC7C,OAAO;IACLS,IAAI,EAAEV,OAAO,CAACU,IAAI;IAClBH,IAAI,EAAEP,OAAO,CAACM,QAAQ,CAACC,IAAI;IAC3BH,OAAO,EAAEL,MAAM,CAACK,OAAO;IACvBZ;GACD;AACH,CAAC,CAAC;AAEF,MAAMiB,aAAa,GAAIR,QAAyB,IAAiB;EAC/D,MAAMU,KAAK,GAAG,IAAIC,GAAG,EAAwB;EAC7C,MAAMC,SAAS,GAAG,IAAID,GAAG,EAA4F;EACrH,MAAMZ,OAAO,GAAGC,QAAQ,CAACD,OAAO;EAChC,IAAIA,OAAO,KAAKE,SAAS,EAAE;IACzB,OAAO;MAAES,KAAK;MAAEE;IAAS,CAAE;EAC7B;EACA,KAAK,MAAMC,KAAK,IAAId,OAAO,CAACe,QAAQ,EAAE;IACpC,IAAID,KAAK,CAACE,UAAU,KAAKd,SAAS,EAAE;MAClCe,eAAe,CAACN,KAAK,EAAEG,KAAK,CAACE,UAAU,CAAC;IAC1C;IACA,IAAIF,KAAK,CAACI,QAAQ,KAAKhB,SAAS,EAAE;MAChCiB,aAAa,CAACR,KAAK,EAAEE,SAAS,EAAEC,KAAK,CAACI,QAAQ,EAAEhB,SAAS,CAAC;IAC5D;IACA,IAAIY,KAAK,CAACM,IAAI,KAAKlB,SAAS,EAAE;MAC5B,KAAK,MAAMmB,SAAS,IAAIP,KAAK,CAACM,IAAI,CAACL,QAAQ,EAAE;QAC3C,IAAIM,SAAS,CAACL,UAAU,KAAKd,SAAS,EAAE;UACtCe,eAAe,CAACN,KAAK,EAAEU,SAAS,CAACL,UAAU,CAAC;QAC9C;QACA,IAAIK,SAAS,CAACH,QAAQ,KAAKhB,SAAS,EAAE;UACpCiB,aAAa,CAACR,KAAK,EAAEE,SAAS,EAAEQ,SAAS,CAACH,QAAQ,EAAEJ,KAAK,CAACM,IAAI,CAAC;QACjE;MACF;IACF;EACF;EACA,OAAO;IAAET,KAAK;IAAEE;EAAS,CAAE;AAC7B,CAAC;AAED,MAAMI,eAAe,GAAGA,CAACN,KAAgC,EAAEK,UAA8B,KAAU;EACjG,KAAK,MAAMM,IAAI,IAAIN,UAAU,CAACL,KAAK,EAAE;IACnCA,KAAK,CAACY,GAAG,CAACD,IAAI,CAACE,EAAE,EAAEF,IAAI,CAAC;EAC1B;AACF,CAAC;AAED,MAAMH,aAAa,GAAGA,CACpBR,KAAgC,EAChCE,SAAwG,EACxGK,QAA0B,EAC1BE,IAA8B,KACtB;EACRP,SAAS,CAACU,GAAG,CAACL,QAAQ,CAACM,EAAE,EAAE;IAAEN,QAAQ;IAAEE;EAAI,CAAE,CAAC;EAC9C,KAAK,MAAME,IAAI,IAAIJ,QAAQ,CAACP,KAAK,EAAE;IACjCA,KAAK,CAACY,GAAG,CAACD,IAAI,CAACE,EAAE,EAAEF,IAAI,CAAC;EAC1B;AACF,CAAC;AAED;AACA,OAAO,MAAMG,YAAY,GAAGA,CAACC,MAAc,EAAEC,KAAkB,KAC7DzC,IAAI,CACFwC,MAAM,CAACE,UAAU,EACjBzC,MAAM,CAAC0C,aAAa,CAAEC,GAAG,IAAmCA,GAAG,CAACzB,MAAM,GAAG,CAAC,CAAC,EAC3ElB,MAAM,CAACO,OAAO,CAAC,MAAMP,MAAM,CAAC4C,aAAa,CAACL,MAAM,CAACE,UAAU,CAACI,IAAI,CAAER,EAAE,IAAKG,KAAK,CAACd,SAAS,CAACoB,GAAG,CAACT,EAAE,CAAC,CAAC,CAAC,CAAC,EACnGrC,MAAM,CAACO,OAAO,CAAE8B,EAAE,IAAKrC,MAAM,CAAC4C,aAAa,CAACJ,KAAK,CAACd,SAAS,CAACqB,GAAG,CAACV,EAAE,CAAC,CAAC,CAAC,CACtE;AAEH;AACA,OAAO,MAAMW,QAAQ,GAAGA,CACtBC,UAA0D,EAC1DT,KAAkB,KAElBS,UAAU,CAACR,UAAU,CAClBS,GAAG,CAAEb,EAAE,IAAKG,KAAK,CAAChB,KAAK,CAACuB,GAAG,CAACV,EAAE,CAAC,CAAC,CAChCQ,IAAI,CAAEV,IAAI,IAAKA,IAAI,KAAKpB,SAAS,CAAC;AAEvC;AACA,OAAO,MAAMoC,QAAQ,GAAGA,CACtBhB,IAAoD,EACpDK,KAAkB,KACPQ,QAAQ,CAACb,IAAI,EAAEK,KAAK,CAAC,EAAErB,QAAQ,CAACC,IAAI,IAAI,CAAC;AAEtD;AACA,OAAO,MAAMgC,WAAW,GAAGA,CACzBjB,IAAoD,EACpDK,KAAkB,KACP;EACX,MAAMnC,MAAM,GAAG2C,QAAQ,CAACb,IAAI,EAAEK,KAAK,CAAC;EACpC,OAAOnC,MAAM,KAAKU,SAAS,GAAG,OAAO,GAAGsC,gBAAgB,CAAChD,MAAM,CAACiD,OAAO,CAAC;AAC1E,CAAC;AAED,MAAMD,gBAAgB,GAAIC,OAAe,IAAa;EACpD,MAAMC,OAAO,GAAGD,OAAO,CAACE,IAAI,EAAE;EAC9B,OAAOD,OAAO,KAAK,GAAG,GAAG,GAAG,GAAGA,OAAkB;AACnD,CAAC;AAED,MAAMvC,UAAU,GAAGA,CAACyC,OAAe,EAAErC,IAAY,EAAEC,MAAc,KAC/DvB,MAAM,CAAC4D,IAAI,CAAC,IAAIzD,UAAU,CAAC;EAAEwD,OAAO;EAAErC,IAAI;EAAEC;AAAM,CAAE,CAAC,CAAC","ignoreList":[]}
@@ -0,0 +1,77 @@
1
+ import type { Pickle, PickleDocString, PickleTable } from "@cucumber/messages";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Option from "effect/Option";
4
+ import * as Schema from "effect/Schema";
5
+ import { MatchError, ParseError, StepError } from "../Errors.ts";
6
+ import * as Parser from "./parser.ts";
7
+ /** @internal */
8
+ export type DataTableInput = PickleTable;
9
+ /** @internal */
10
+ export type DocStringInput = PickleDocString;
11
+ /** @internal */
12
+ export type StepKind = "Step" | "Given" | "When" | "Then";
13
+ /** @internal */
14
+ export interface Matcher<A> {
15
+ readonly source: string;
16
+ readonly match: (text: string) => Option.Option<A>;
17
+ }
18
+ /** @internal */
19
+ export type StepArgument = {
20
+ readonly _tag: "TableArg";
21
+ readonly decode: (argument: DataTableInput) => Effect.Effect<unknown, unknown>;
22
+ } | {
23
+ readonly _tag: "DocStringArg";
24
+ readonly decode: (argument: DocStringInput) => Effect.Effect<unknown, unknown>;
25
+ };
26
+ /** @internal */
27
+ export interface Transition<State, E, R> {
28
+ readonly kind: StepKind;
29
+ readonly expression: Matcher<unknown>;
30
+ readonly argument?: StepArgument;
31
+ readonly run: (captures: unknown, argument: unknown, state: State) => Effect.Effect<State, E, R>;
32
+ }
33
+ /** @internal */
34
+ export interface Feature<State, E, R> {
35
+ readonly name: string;
36
+ readonly initial: State;
37
+ readonly transitions: ReadonlyArray<Transition<State, E, R>>;
38
+ }
39
+ /** @internal */
40
+ export interface Report {
41
+ readonly feature: string;
42
+ readonly scenarios: ReadonlyArray<{
43
+ readonly name: string;
44
+ readonly steps: number;
45
+ readonly tags: ReadonlyArray<string>;
46
+ }>;
47
+ }
48
+ /** @internal */
49
+ export type RunError = ParseError | MatchError | StepError;
50
+ /** @internal */
51
+ export type GherkinCompiler = Parser.GherkinCompiler;
52
+ /** @internal */
53
+ export interface ScenarioTask<State, E, R> {
54
+ readonly featureDefinition: Feature<State, E, R>;
55
+ readonly featureName: string;
56
+ readonly scenarioName: string;
57
+ readonly scenarioIndex: number;
58
+ readonly scenarioLine: number;
59
+ readonly ruleName?: string;
60
+ readonly ruleLine?: number;
61
+ readonly tags: ReadonlyArray<string>;
62
+ readonly pickle: Pickle;
63
+ readonly source: Parser.SourceIndex;
64
+ }
65
+ /** @internal */
66
+ export type ScenarioReport = Report["scenarios"][number];
67
+ /** @internal */
68
+ export declare const decodeTable: <S extends Schema.Decoder<unknown, never>>(row: S) => (table: PickleTable) => Effect.Effect<ReadonlyArray<S["Type"]>, unknown>;
69
+ /** @internal */
70
+ export declare const decodeDocString: <S extends Schema.Decoder<unknown, never>>(schema: S) => (docString: PickleDocString) => Effect.Effect<S["Type"], unknown>;
71
+ /** @internal */
72
+ export declare const run: <State, E, R>(featureDefinition: Feature<State, E, R>, source: string) => Effect.Effect<Report, RunError, R | Parser.GherkinCompiler>;
73
+ /** @internal */
74
+ export declare const buildScenarioTasks: <State, E, R>(featureDefinition: Feature<State, E, R>, feature: Parser.CompiledFeature) => ReadonlyArray<ScenarioTask<State, E, R>>;
75
+ /** @internal */
76
+ export declare const runScenarioTask: <State, E, R>(task: ScenarioTask<State, E, R>) => Effect.Effect<ScenarioReport, RunError, R>;
77
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/internal/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,117 @@
1
+ import * as Arr from "effect/Array";
2
+ import * as Effect from "effect/Effect";
3
+ import { pipe } from "effect/Function";
4
+ import * as Option from "effect/Option";
5
+ import * as Record from "effect/Record";
6
+ import * as Schema from "effect/Schema";
7
+ import { MatchError, ParseError, StepError } from "../Errors.js";
8
+ import * as Matching from "./matching.js";
9
+ import * as Parser from "./parser.js";
10
+ /** @internal */
11
+ export const decodeTable = row => {
12
+ const decode = Schema.decodeUnknownEffect(row);
13
+ return table => {
14
+ const [headers, ...rows] = table.rows.map(row => row.cells.map(cell => cell.value));
15
+ if (headers === undefined) {
16
+ return Effect.succeed([]);
17
+ }
18
+ return Effect.forEach(rows, cells => decode(rowObject(headers, cells)));
19
+ };
20
+ };
21
+ /** @internal */
22
+ export const decodeDocString = schema => {
23
+ const decode = Schema.decodeUnknownEffect(schema);
24
+ return docString => decode(docString.content);
25
+ };
26
+ /** @internal */
27
+ export const run = (featureDefinition, source) => pipe(Parser.parse(source), Effect.flatMap(feature => pipe(validateFeatureDefinition(featureDefinition, feature), Effect.flatMap(() => Effect.forEach(buildScenarioTasks(featureDefinition, feature), runScenarioTask)), Effect.map(scenarios => ({
28
+ feature: feature.name,
29
+ scenarios
30
+ })))));
31
+ const validateFeatureDefinition = (featureDefinition, feature) => featureDefinition.name === feature.name ? Effect.void : Effect.fail(new MatchError({
32
+ message: `Feature definition "${featureDefinition.name}" does not match Gherkin feature "${feature.name}"`,
33
+ scenario: "",
34
+ step: feature.name,
35
+ line: feature.line,
36
+ candidates: [featureDefinition.name]
37
+ }));
38
+ /** @internal */
39
+ export const buildScenarioTasks = (featureDefinition, feature) => Arr.map(feature.pickles, (pickle, scenarioIndex) => {
40
+ const source = Parser.findScenario(pickle, feature.source);
41
+ const rule = pipe(source, Option.map(({
42
+ rule
43
+ }) => rule), Option.getOrUndefined);
44
+ return {
45
+ featureDefinition,
46
+ featureName: feature.name,
47
+ scenarioName: pickle.name,
48
+ scenarioIndex,
49
+ scenarioLine: pickle.location?.line ?? pipe(source, Option.map(({
50
+ scenario
51
+ }) => scenario.location.line), Option.getOrElse(() => feature.line)),
52
+ ...(rule === undefined ? {} : {
53
+ ruleName: rule.name,
54
+ ruleLine: rule.location.line
55
+ }),
56
+ tags: pickle.tags.map(tag => tag.name),
57
+ pickle,
58
+ source: feature.source
59
+ };
60
+ });
61
+ /** @internal */
62
+ export const runScenarioTask = task => pipe(runSteps(task.featureDefinition, task.scenarioName, task.pickle.steps, task.source, task.featureDefinition.initial), Effect.as({
63
+ name: task.scenarioName,
64
+ steps: task.pickle.steps.length,
65
+ tags: task.tags
66
+ }));
67
+ const runSteps = (featureDefinition, scenario, steps, source, state, index = 0) => index >= steps.length ? Effect.succeed(state) : pipe(runStep(featureDefinition, scenario, steps[index], source, state), Effect.flatMap(state => runSteps(featureDefinition, scenario, steps, source, state, index + 1)));
68
+ const runStep = (featureDefinition, scenario, step, source, state) => pipe(stepKind(step, source), Effect.flatMap(kind => pipe(resolve(featureDefinition, scenario, step, kind, source), Effect.flatMap(({
69
+ transition,
70
+ captures
71
+ }) => pipe(decodeArgument(transition, scenario, step, source), Effect.flatMap(argument => pipe(transition.run(captures, argument, state), Effect.mapError(cause => new StepError({
72
+ message: `Step failed: ${step.text}`,
73
+ scenario,
74
+ step: step.text,
75
+ line: Parser.stepLine(step, source),
76
+ cause
77
+ })))))))));
78
+ const decodeArgument = (transition, scenario, step, source) => {
79
+ const candidates = [transition.expression.source];
80
+ if (transition.argument === undefined) {
81
+ return hasStepArgument(step) ? failMatch(`Step "${step.text}" has an unexpected argument`, scenario, step, source, candidates) : Effect.succeed(undefined);
82
+ }
83
+ if (transition.argument._tag === "TableArg") {
84
+ return step.argument?.dataTable === undefined ? failMatch(`Step "${step.text}" requires a DataTable`, scenario, step, source, candidates) : pipe(transition.argument.decode(step.argument.dataTable), Effect.mapError(cause => matchError(`Could not decode DataTable for step "${step.text}"`, scenario, step, source, candidates, cause)));
85
+ }
86
+ return step.argument?.docString === undefined ? failMatch(`Step "${step.text}" requires a DocString`, scenario, step, source, candidates) : pipe(transition.argument.decode(step.argument.docString), Effect.mapError(cause => matchError(`Could not decode DocString for step "${step.text}"`, scenario, step, source, candidates, cause)));
87
+ };
88
+ const resolve = (featureDefinition, scenario, step, kind, source) => {
89
+ const textMatches = Matching.matchingTextTransitions(featureDefinition.transitions, step.text);
90
+ const matches = Matching.matchingKeywordTransitions(textMatches, kind);
91
+ return pipe(matches, Arr.match({
92
+ onEmpty: () => textMatches.length === 0 ? failMatch(`No transition matched step "${step.text}"`, scenario, step, source, Arr.map(featureDefinition.transitions, transition => transition.expression.source)) : failMatch(`No ${kind} transition matched step "${step.text}"; matching text exists for ${Matching.renderTransitionKinds(Arr.map(textMatches, match => match.transition))}`, scenario, step, source, Arr.map(textMatches, match => match.transition.expression.source)),
93
+ onNonEmpty: matches => matches.length === 1 ? Effect.succeed(Arr.headNonEmpty(matches)) : failMatch(`Multiple transitions matched step "${step.text}"`, scenario, step, source, Arr.map(matches, match => match.transition.expression.source))
94
+ }));
95
+ };
96
+ const rowObject = (headers, cells) => pipe(headers, Arr.map((header, index) => [header, cells[index] ?? ""]), Record.fromEntries);
97
+ const hasStepArgument = step => step.argument !== undefined;
98
+ const stepKind = (step, source) => pipe(Matching.concreteStepKind(step), Option.match({
99
+ onNone: () => Effect.fail(new ParseError({
100
+ message: `${Parser.stepKeyword(step, source)} found before a Given, When, or Then step`,
101
+ line: Parser.stepLine(step, source),
102
+ column: 1
103
+ })),
104
+ onSome: Effect.succeed
105
+ }));
106
+ const failMatch = (message, scenario, step, source, candidates, cause) => Effect.fail(matchError(message, scenario, step, source, candidates, cause));
107
+ const matchError = (message, scenario, step, source, candidates, cause) => new MatchError({
108
+ message,
109
+ scenario,
110
+ step: step.text,
111
+ line: Parser.stepLine(step, source),
112
+ candidates,
113
+ ...(cause === undefined ? {} : {
114
+ cause
115
+ })
116
+ });
117
+ //# sourceMappingURL=runner.js.map