From 56faf27e85a79468f28c8e120bb8cfdef46439f2 Mon Sep 17 00:00:00 2001 From: David Goss Date: Mon, 8 Sep 2025 14:35:50 +0100 Subject: [PATCH 1/6] Make PickleStep available on UndefinedError --- cucumber-core.api.md | 5 ++++- src/UndefinedError.ts | 6 ++++-- src/makeTestPlan.spec.ts | 7 ++++++- src/makeTestPlan.ts | 2 +- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/cucumber-core.api.md b/cucumber-core.api.md index 8fdfe50..686e2c3 100644 --- a/cucumber-core.api.md +++ b/cucumber-core.api.md @@ -13,6 +13,7 @@ import { IdGenerator } from '@cucumber/messages'; import { NamingStrategy } from '@cucumber/query'; import parse from '@cucumber/tag-expressions'; import { Pickle } from '@cucumber/messages'; +import { PickleStep } from '@cucumber/messages'; import { RegularExpression } from '@cucumber/cucumber-expressions'; import { SourceReference } from '@cucumber/messages'; import { StepDefinition } from '@cucumber/messages'; @@ -203,7 +204,9 @@ export interface TestPlanOptions { // @public export class UndefinedError extends Error { - constructor(text: string); + constructor(pickleStep: PickleStep); + // (undocumented) + readonly pickleStep: PickleStep; } // @public diff --git a/src/UndefinedError.ts b/src/UndefinedError.ts index 95b5464..7c4b47b 100644 --- a/src/UndefinedError.ts +++ b/src/UndefinedError.ts @@ -1,9 +1,11 @@ +import { PickleStep } from '@cucumber/messages' + /** * Represents an error that occurs when no step definitions are found matching the text of a step * @public */ export class UndefinedError extends Error { - constructor(text: string) { - super(`No matching step definitions found for text "${text}"`) + constructor(public readonly pickleStep: PickleStep) { + super(`No matching step definitions found for text "${pickleStep.text}"`) } } diff --git a/src/makeTestPlan.spec.ts b/src/makeTestPlan.spec.ts index c52751f..319124e 100644 --- a/src/makeTestPlan.spec.ts +++ b/src/makeTestPlan.spec.ts @@ -168,7 +168,12 @@ describe('makeTestPlan', () => { } ) - expect(() => result.testCases[0].testSteps[0].prepare(undefined)).to.throw(UndefinedError) + try { + result.testCases[0].testSteps[0].prepare(undefined) + } catch (err: any) { + expect(err).to.be.instanceOf(UndefinedError) + expect(err.pickleStep).to.eq(pickles[0].steps[0]) + } }) it('matches and prepares a step without parameters', () => { diff --git a/src/makeTestPlan.ts b/src/makeTestPlan.ts index afebab1..8846d29 100644 --- a/src/makeTestPlan.ts +++ b/src/makeTestPlan.ts @@ -178,7 +178,7 @@ function fromPickleSteps( always: false, prepare(thisArg) { if (matched.length < 1) { - throw new UndefinedError(pickleStep.text) + throw new UndefinedError(pickleStep) } else if (matched.length > 1) { throw new AmbiguousError( pickleStep.text, From f777dfb3b6a04e6a1a0cb55d61c8564b1535e395 Mon Sep 17 00:00:00 2001 From: David Goss Date: Mon, 8 Sep 2025 16:57:17 +0100 Subject: [PATCH 2/6] expose CucumberExpressionGenerator --- src/SupportCodeBuilderImpl.ts | 1 + src/SupportCodeLibraryImpl.ts | 6 ++++++ src/types.ts | 11 ++++++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/SupportCodeBuilderImpl.ts b/src/SupportCodeBuilderImpl.ts index 22d06db..e1e1c6e 100644 --- a/src/SupportCodeBuilderImpl.ts +++ b/src/SupportCodeBuilderImpl.ts @@ -275,6 +275,7 @@ export class SupportCodeBuilderImpl implements SupportCodeBuilder { build() { return new SupportCodeLibraryImpl( + this.parameterTypeRegistry, this.buildParameterTypes(), this.buildSteps(), this.buildUndefinedParameterTypes(), diff --git a/src/SupportCodeLibraryImpl.ts b/src/SupportCodeLibraryImpl.ts index 82a1464..62fcdb0 100644 --- a/src/SupportCodeLibraryImpl.ts +++ b/src/SupportCodeLibraryImpl.ts @@ -7,12 +7,14 @@ import { SupportCodeLibrary, UndefinedParameterType, } from './types' +import { CucumberExpressionGenerator, ParameterTypeRegistry } from '@cucumber/cucumber-expressions' /** * @internal */ export class SupportCodeLibraryImpl implements SupportCodeLibrary { constructor( + private readonly parameterTypeRegistry: ParameterTypeRegistry, private readonly parameterTypes: ReadonlyArray = [], private readonly steps: ReadonlyArray = [], private readonly undefinedParameterTypes: ReadonlyArray = [], @@ -36,6 +38,10 @@ export class SupportCodeLibraryImpl implements SupportCodeLibrary { return results } + getExpressionGenerator(): CucumberExpressionGenerator { + return new CucumberExpressionGenerator(() => this.parameterTypeRegistry.parameterTypes) + } + findAllBeforeHooksBy(tags: ReadonlyArray) { return this.beforeHooks.filter((def) => { if (def.tags) { diff --git a/src/types.ts b/src/types.ts index 4850abb..52c4a81 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,9 @@ -import { Argument, CucumberExpression, RegularExpression } from '@cucumber/cucumber-expressions' +import { + Argument, + CucumberExpression, + CucumberExpressionGenerator, + RegularExpression, +} from '@cucumber/cucumber-expressions' import { Envelope, GherkinDocument, @@ -329,6 +334,10 @@ export interface SupportCodeLibrary { * Find all step definitions whose expression is a match for the given text */ findAllStepsBy(text: string): ReadonlyArray + /** + * Get a generator for Cucumber Expressions based on the currently defined parameter types + */ + getExpressionGenerator(): CucumberExpressionGenerator /** * Get all BeforeAll hooks */ From 8478449c5b67ebf67ae3b963b017b5bb6727c419 Mon Sep 17 00:00:00 2001 From: David Goss Date: Mon, 8 Sep 2025 17:02:44 +0100 Subject: [PATCH 3/6] formatting --- src/SupportCodeLibraryImpl.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/SupportCodeLibraryImpl.ts b/src/SupportCodeLibraryImpl.ts index 62fcdb0..20d5c14 100644 --- a/src/SupportCodeLibraryImpl.ts +++ b/src/SupportCodeLibraryImpl.ts @@ -1,3 +1,5 @@ +import { CucumberExpressionGenerator, ParameterTypeRegistry } from '@cucumber/cucumber-expressions' + import { DefinedParameterType, DefinedStep, @@ -7,7 +9,6 @@ import { SupportCodeLibrary, UndefinedParameterType, } from './types' -import { CucumberExpressionGenerator, ParameterTypeRegistry } from '@cucumber/cucumber-expressions' /** * @internal From 6bb2d90ce93b1f1381be05f10d3f0859a187bb2d Mon Sep 17 00:00:00 2001 From: David Goss Date: Mon, 8 Sep 2025 17:06:04 +0100 Subject: [PATCH 4/6] update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1eef690..a8c3934 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- Add `pickleStep` to `UndefinedError` ([#13](https://github.com/cucumber/javascript-core/pull/13)) +- Add `getExpressionGenerator()` to `SupportCodeLibrary` ([#13](https://github.com/cucumber/javascript-core/pull/13)) ## [0.4.1] - 2025-09-05 ### Fixed From 0f99309f683f11aedca455da3ba08976559c3a53 Mon Sep 17 00:00:00 2001 From: David Goss Date: Mon, 8 Sep 2025 17:20:08 +0100 Subject: [PATCH 5/6] update api extractor --- cucumber-core.api.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cucumber-core.api.md b/cucumber-core.api.md index 686e2c3..a433a84 100644 --- a/cucumber-core.api.md +++ b/cucumber-core.api.md @@ -6,6 +6,7 @@ import { Argument } from '@cucumber/cucumber-expressions'; import { CucumberExpression } from '@cucumber/cucumber-expressions'; +import { CucumberExpressionGenerator } from '@cucumber/cucumber-expressions'; import { Envelope } from '@cucumber/messages'; import { GherkinDocument } from '@cucumber/messages'; import { Hook } from '@cucumber/messages'; @@ -180,6 +181,7 @@ export interface SupportCodeLibrary { findAllStepsBy(text: string): ReadonlyArray; getAllAfterAllHooks(): ReadonlyArray; getAllBeforeAllHooks(): ReadonlyArray; + getExpressionGenerator(): CucumberExpressionGenerator; toEnvelopes(): ReadonlyArray; } From d351db6f3bd70768752552a1eab2d43c33919502 Mon Sep 17 00:00:00 2001 From: David Goss Date: Mon, 8 Sep 2025 17:30:01 +0100 Subject: [PATCH 6/6] add missing test --- src/buildSupportCode.spec.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/buildSupportCode.spec.ts b/src/buildSupportCode.spec.ts index a1fbf79..9970c0a 100644 --- a/src/buildSupportCode.spec.ts +++ b/src/buildSupportCode.spec.ts @@ -336,6 +336,15 @@ describe('buildSupportCode', () => { }) }) + describe('expression generator', () => { + it('returns a cucumber expression generator primed with the parameter type registry', () => { + const library = buildSupportCode({ newId }).build() + const expressionGenerator = library.getExpressionGenerator() + const expressions = expressionGenerator.generateExpressions('I have 17 cukes in my belly') + expect(expressions.length).to.eq(2) + }) + }) + describe('test run hooks', () => { let library: SupportCodeLibrary beforeEach(() => {