From 8fece8387546610ae578e49ae5675620548fcecc Mon Sep 17 00:00:00 2001 From: David Goss Date: Thu, 22 Jun 2023 15:10:57 +0100 Subject: [PATCH] include source reference on parameter type message (#2287) --- CHANGELOG.md | 1 + package-lock.json | 57 ++++++++++--------- package.json | 12 ++-- src/cli/helpers.ts | 35 +++++------- src/cli/helpers_spec.ts | 24 +++++--- src/support_code_library_builder/index.ts | 23 ++------ .../sourced_parameter_type_registry.ts | 20 +++++++ src/support_code_library_builder/types.ts | 4 +- 8 files changed, 97 insertions(+), 79 deletions(-) create mode 100644 src/support_code_library_builder/sourced_parameter_type_registry.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 269bdc7fc..2c0d167cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Please see [CONTRIBUTING.md](./CONTRIBUTING.md) on how to contribute to Cucumber ## [Unreleased] ### Added - New option for JUnit test suite name to be passed in `formatOptions` ([#2265](https://github.com/cucumber/cucumber-js/issues/2265)) +- Include source reference in emitted messages for parameter types ([#2287](https://github.com/cucumber/cucumber-js/pull/2287)) ## [9.1.2] - 2023-05-07 ### Changed diff --git a/package-lock.json b/package-lock.json index b6e3e4617..92a13ddda 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,14 +9,14 @@ "version": "9.1.2", "license": "MIT", "dependencies": { - "@cucumber/ci-environment": "9.1.0", - "@cucumber/cucumber-expressions": "16.1.1", - "@cucumber/gherkin": "26.0.3", + "@cucumber/ci-environment": "9.2.0", + "@cucumber/cucumber-expressions": "16.1.2", + "@cucumber/gherkin": "26.2.0", "@cucumber/gherkin-streams": "5.0.1", "@cucumber/gherkin-utils": "8.0.2", - "@cucumber/html-formatter": "20.2.1", + "@cucumber/html-formatter": "20.3.0", "@cucumber/message-streams": "4.0.1", - "@cucumber/messages": "21.0.1", + "@cucumber/messages": "22.0.0", "@cucumber/tag-expressions": "5.0.1", "assertion-error-formatter": "^3.0.0", "capital-case": "^1.0.4", @@ -54,7 +54,7 @@ "cucumber-js": "bin/cucumber.js" }, "devDependencies": { - "@cucumber/compatibility-kit": "11.2.0", + "@cucumber/compatibility-kit": "11.3.0", "@cucumber/query": "12.0.1", "@microsoft/api-documenter": "7.19.27", "@microsoft/api-extractor": "7.33.7", @@ -559,30 +559,30 @@ } }, "node_modules/@cucumber/ci-environment": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@cucumber/ci-environment/-/ci-environment-9.1.0.tgz", - "integrity": "sha512-jdnF6APXP3GawMue8kdMxhu6TBhyRUO4KDRxTowf06NtclLjIw2Ybpo9IcIOMvE8kHukvJyM00uxWX+CfS7JgQ==" + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/@cucumber/ci-environment/-/ci-environment-9.2.0.tgz", + "integrity": "sha512-jLzRtVwdtNt+uAmTwvXwW9iGYLEOJFpDSmnx/dgoMGKXUWRx1UHT86Q696CLdgXO8kyTwsgJY0c6n5SW9VitAA==" }, "node_modules/@cucumber/compatibility-kit": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/@cucumber/compatibility-kit/-/compatibility-kit-11.2.0.tgz", - "integrity": "sha512-KGPQHQ9NJt092M2FIlidGLmQUekiUAzf9i/HaB9Ofqg6hjhh77aqB0N5Z3k7ByOaLeSmISFlbmM46EFahto6yQ==", + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/@cucumber/compatibility-kit/-/compatibility-kit-11.3.0.tgz", + "integrity": "sha512-hMpyQ1ZWlkwyUJ/Hzh37W3KJSopPdpJq8JWhQbJ2pE92LuzfiXm//JVGk1IXV31uTP4jPt3X4ouujDelQVELhQ==", "dev": true }, "node_modules/@cucumber/cucumber-expressions": { - "version": "16.1.1", - "resolved": "https://registry.npmjs.org/@cucumber/cucumber-expressions/-/cucumber-expressions-16.1.1.tgz", - "integrity": "sha512-Ugsb9qxfgrgfUKsGvbx0awVk+69NIFjWfxNT+dnm62YrF2gdTHYxAOzOLuPgvE0yqYTh+3otrFLDDfkHGThM1g==", + "version": "16.1.2", + "resolved": "https://registry.npmjs.org/@cucumber/cucumber-expressions/-/cucumber-expressions-16.1.2.tgz", + "integrity": "sha512-CfHEbxJ5FqBwF6mJyLLz4B353gyHkoi6cCL4J0lfDZ+GorpcWw4n2OUAdxJmP7ZlREANWoTFlp4FhmkLKrCfUA==", "dependencies": { "regexp-match-indices": "1.0.2" } }, "node_modules/@cucumber/gherkin": { - "version": "26.0.3", - "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-26.0.3.tgz", - "integrity": "sha512-xwJHi//bLFEU1drIyw2yswwUHnnVWO4XcyVBbCTDs6DkSh262GkogFI/IWwChZqJfOXnPglzLGxR1DibcZsILA==", + "version": "26.2.0", + "resolved": "https://registry.npmjs.org/@cucumber/gherkin/-/gherkin-26.2.0.tgz", + "integrity": "sha512-iRSiK8YAIHAmLrn/mUfpAx7OXZ7LyNlh1zT89RoziSVCbqSVDxJS6ckEzW8loxs+EEXl0dKPQOXiDmbHV+C/fA==", "dependencies": { - "@cucumber/messages": "19.1.4 - 21" + "@cucumber/messages": ">=19.1.4 <=22" } }, "node_modules/@cucumber/gherkin-streams": { @@ -653,9 +653,9 @@ } }, "node_modules/@cucumber/html-formatter": { - "version": "20.2.1", - "resolved": "https://registry.npmjs.org/@cucumber/html-formatter/-/html-formatter-20.2.1.tgz", - "integrity": "sha512-bwwyr1WjlOJ5dEFOLGbtYWbUprloB2eymqXBmmTC10s0xapZXkFn4VfHgMshaH91XiCIY/MoabWNAau3AeMHkQ==", + "version": "20.3.0", + "resolved": "https://registry.npmjs.org/@cucumber/html-formatter/-/html-formatter-20.3.0.tgz", + "integrity": "sha512-4DOuA2jmw2WqK63HxCWoXmyozGCrKeCddQ2wHWsQaAVP8YxWyzzY6azFJaByqvZW45WdaQ/5aMJWvEy+XAEXJg==", "peerDependencies": { "@cucumber/messages": ">=18" } @@ -669,16 +669,21 @@ } }, "node_modules/@cucumber/messages": { - "version": "21.0.1", - "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-21.0.1.tgz", - "integrity": "sha512-pGR7iURM4SF9Qp1IIpNiVQ77J9kfxMkPOEbyy+zRmGABnWWCsqMpJdfHeh9Mb3VskemVw85++e15JT0PYdcR3g==", + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/@cucumber/messages/-/messages-22.0.0.tgz", + "integrity": "sha512-EuaUtYte9ilkxcKmfqGF9pJsHRUU0jwie5ukuZ/1NPTuHS1LxHPsGEODK17RPRbZHOFhqybNzG2rHAwThxEymg==", "dependencies": { - "@types/uuid": "8.3.4", + "@types/uuid": "9.0.1", "class-transformer": "0.5.1", "reflect-metadata": "0.1.13", "uuid": "9.0.0" } }, + "node_modules/@cucumber/messages/node_modules/@types/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA==" + }, "node_modules/@cucumber/query": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/@cucumber/query/-/query-12.0.1.tgz", diff --git a/package.json b/package.json index 9a5b6a504..1155ae246 100644 --- a/package.json +++ b/package.json @@ -207,14 +207,14 @@ "node": "14 || 16 || 18 || 19" }, "dependencies": { - "@cucumber/ci-environment": "9.1.0", - "@cucumber/cucumber-expressions": "16.1.1", - "@cucumber/gherkin": "26.0.3", + "@cucumber/ci-environment": "9.2.0", + "@cucumber/cucumber-expressions": "16.1.2", + "@cucumber/gherkin": "26.2.0", "@cucumber/gherkin-streams": "5.0.1", "@cucumber/gherkin-utils": "8.0.2", - "@cucumber/html-formatter": "20.2.1", + "@cucumber/html-formatter": "20.3.0", "@cucumber/message-streams": "4.0.1", - "@cucumber/messages": "21.0.1", + "@cucumber/messages": "22.0.0", "@cucumber/tag-expressions": "5.0.1", "assertion-error-formatter": "^3.0.0", "capital-case": "^1.0.4", @@ -249,7 +249,7 @@ "yup": "^0.32.11" }, "devDependencies": { - "@cucumber/compatibility-kit": "11.2.0", + "@cucumber/compatibility-kit": "11.3.0", "@cucumber/query": "12.0.1", "@microsoft/api-documenter": "7.19.27", "@microsoft/api-extractor": "7.33.7", diff --git a/src/cli/helpers.ts b/src/cli/helpers.ts index a319fe5dd..0571d246c 100644 --- a/src/cli/helpers.ts +++ b/src/cli/helpers.ts @@ -13,9 +13,9 @@ import { ISupportCodeLibrary } from '../support_code_library_builder/types' import TestCaseHookDefinition from '../models/test_case_hook_definition' import TestRunHookDefinition from '../models/test_run_hook_definition' import { PickleOrder } from '../models/pickle_order' -import { builtinParameterTypes } from '../support_code_library_builder' import { version } from '../version' import { ILogger } from '../logger' +import { ILineAndUri } from '../types' interface IParseGherkinMessageStreamRequest { cwd?: string @@ -119,6 +119,13 @@ export async function emitMetaMessage( }) } +const makeSourceReference = (source: ILineAndUri) => ({ + uri: source.uri, + location: { + line: source.line, + }, +}) + function emitParameterTypes( supportCodeLibrary: ISupportCodeLibrary, eventBroadcaster: EventEmitter, @@ -126,9 +133,11 @@ function emitParameterTypes( ): void { for (const parameterType of supportCodeLibrary.parameterTypeRegistry .parameterTypes) { - if (builtinParameterTypes.includes(parameterType.name)) { + if (parameterType.builtin) { continue } + const source = + supportCodeLibrary.parameterTypeRegistry.lookupSource(parameterType) const envelope: messages.Envelope = { parameterType: { id: newId(), @@ -136,6 +145,7 @@ function emitParameterTypes( preferForRegularExpressionMatch: parameterType.preferForRegexpMatch, regularExpressions: parameterType.regexpStrings, useForSnippets: parameterType.useForSnippets, + sourceReference: makeSourceReference(source), }, } eventBroadcaster.emit('envelope', envelope) @@ -169,12 +179,7 @@ function emitStepDefinitions( ? messages.StepDefinitionPatternType.CUCUMBER_EXPRESSION : messages.StepDefinitionPatternType.REGULAR_EXPRESSION, }, - sourceReference: { - uri: stepDefinition.uri, - location: { - line: stepDefinition.line, - }, - }, + sourceReference: makeSourceReference(stepDefinition), }, } eventBroadcaster.emit('envelope', envelope) @@ -196,12 +201,7 @@ function emitTestCaseHooks( id: testCaseHookDefinition.id, name: testCaseHookDefinition.name, tagExpression: testCaseHookDefinition.tagExpression, - sourceReference: { - uri: testCaseHookDefinition.uri, - location: { - line: testCaseHookDefinition.line, - }, - }, + sourceReference: makeSourceReference(testCaseHookDefinition), }, } eventBroadcaster.emit('envelope', envelope) @@ -221,12 +221,7 @@ function emitTestRunHooks( const envelope: messages.Envelope = { hook: { id: testRunHookDefinition.id, - sourceReference: { - uri: testRunHookDefinition.uri, - location: { - line: testRunHookDefinition.line, - }, - }, + sourceReference: makeSourceReference(testRunHookDefinition), }, } eventBroadcaster.emit('envelope', envelope) diff --git a/src/cli/helpers_spec.ts b/src/cli/helpers_spec.ts index cff1a1ef2..0b40892ae 100644 --- a/src/cli/helpers_spec.ts +++ b/src/cli/helpers_spec.ts @@ -16,13 +16,13 @@ import StepDefinition from '../models/step_definition' import { CucumberExpression, ParameterType, - ParameterTypeRegistry, RegularExpression, } from '@cucumber/cucumber-expressions' import { ISupportCodeLibrary } from '../support_code_library_builder/types' import TestCaseHookDefinition from '../models/test_case_hook_definition' import TestRunHookDefinition from '../models/test_run_hook_definition' import { PickleOrder } from '../models/pickle_order' +import { SourcedParameterTypeRegistry } from '../support_code_library_builder/sourced_parameter_type_registry' const noopFunction = (): void => { // no code @@ -79,7 +79,7 @@ function testEmitSupportCodeMessages( afterTestCaseHookDefinitions: [], afterTestStepHookDefinitions: [], defaultTimeout: 0, - parameterTypeRegistry: new ParameterTypeRegistry(), + parameterTypeRegistry: new SourcedParameterTypeRegistry(), undefinedParameterTypes: [], World: null, parallelCanAssign: () => true, @@ -105,8 +105,8 @@ describe('helpers', () => { }) describe('emitSupportCodeMessages', () => { it('emits messages for parameter types', () => { - const parameterTypeRegistry = new ParameterTypeRegistry() - parameterTypeRegistry.defineParameterType( + const parameterTypeRegistry = new SourcedParameterTypeRegistry() + parameterTypeRegistry.defineSourcedParameterType( new ParameterType( 'flight', ['([A-Z]{3})-([A-Z]{3})'], @@ -114,7 +114,11 @@ describe('helpers', () => { () => 'argh', true, false - ) + ), + { + line: 4, + uri: 'features/support/parameter-types.js', + } ) const envelopes = testEmitSupportCodeMessages({ @@ -129,6 +133,12 @@ describe('helpers', () => { preferForRegularExpressionMatch: false, regularExpressions: ['([A-Z]{3})-([A-Z]{3})'], useForSnippets: true, + sourceReference: { + uri: 'features/support/parameter-types.js', + location: { + line: 4, + }, + }, }, }, ] @@ -149,7 +159,7 @@ describe('helpers', () => { pattern: 'I have {int} cukes in my belly', expression: new CucumberExpression( 'I have {int} cukes in my belly', - new ParameterTypeRegistry() + new SourcedParameterTypeRegistry() ), }), ], @@ -188,7 +198,7 @@ describe('helpers', () => { pattern: /I have (\d+) cukes in my belly/, expression: new RegularExpression( /I have (\d+) cukes in my belly/, - new ParameterTypeRegistry() + new SourcedParameterTypeRegistry() ), }), ], diff --git a/src/support_code_library_builder/index.ts b/src/support_code_library_builder/index.ts index b80183c52..001348dff 100644 --- a/src/support_code_library_builder/index.ts +++ b/src/support_code_library_builder/index.ts @@ -12,7 +12,6 @@ import arity from 'util-arity' import { CucumberExpression, - ParameterTypeRegistry, RegularExpression, } from '@cucumber/cucumber-expressions' import { doesHaveValue, doesNotHaveValue } from '../value_checker' @@ -34,6 +33,7 @@ import { import World from './world' import { ICanonicalSupportCodeIds } from '../runtime/parallel/command_types' import { GherkinStepKeyword } from '../models/gherkin_step_keyword' +import { SourcedParameterTypeRegistry } from './sourced_parameter_type_registry' interface IStepDefinitionConfig { code: any @@ -65,20 +65,6 @@ interface ITestRunHookDefinitionConfig { uri: string } -export const builtinParameterTypes = [ - 'bigdecimal', - 'biginteger', - 'byte', - 'double', - 'float', - 'int', - 'long', - 'short', - 'string', - 'word', - '', -] - export class SupportCodeLibraryBuilder { public readonly methods: IDefineSupportCodeMethods @@ -93,7 +79,7 @@ export class SupportCodeLibraryBuilder { private defaultTimeout: number private definitionFunctionWrapper: any private newId: IdGenerator.NewId - private parameterTypeRegistry: ParameterTypeRegistry + private parameterTypeRegistry: SourcedParameterTypeRegistry private stepDefinitionConfigs: IStepDefinitionConfig[] private World: any private parallelCanAssign: ParallelAssignmentValidator @@ -166,7 +152,8 @@ export class SupportCodeLibraryBuilder { defineParameterType(options: IParameterTypeDefinition): void { const parameterType = buildParameterType(options) - this.parameterTypeRegistry.defineParameterType(parameterType) + const source = getDefinitionLineAndUri(this.cwd) + this.parameterTypeRegistry.defineSourcedParameterType(parameterType, source) } defineStep( @@ -481,7 +468,7 @@ export class SupportCodeLibraryBuilder { this.beforeTestStepHookDefinitionConfigs = [] this.definitionFunctionWrapper = null this.defaultTimeout = 5000 - this.parameterTypeRegistry = new ParameterTypeRegistry() + this.parameterTypeRegistry = new SourcedParameterTypeRegistry() this.stepDefinitionConfigs = [] this.parallelCanAssign = () => true this.World = World diff --git a/src/support_code_library_builder/sourced_parameter_type_registry.ts b/src/support_code_library_builder/sourced_parameter_type_registry.ts new file mode 100644 index 000000000..c2d2f035a --- /dev/null +++ b/src/support_code_library_builder/sourced_parameter_type_registry.ts @@ -0,0 +1,20 @@ +import { ParameterTypeRegistry } from '@cucumber/cucumber-expressions' +import ParameterType from '@cucumber/cucumber-expressions/dist/cjs/src/ParameterType' +import { ILineAndUri } from '../types' + +export class SourcedParameterTypeRegistry extends ParameterTypeRegistry { + private parameterTypeToSource: WeakMap, ILineAndUri> = + new WeakMap() + + defineSourcedParameterType( + parameterType: ParameterType, + source: ILineAndUri + ) { + this.defineParameterType(parameterType) + this.parameterTypeToSource.set(parameterType, source) + } + + lookupSource(parameterType: ParameterType) { + return this.parameterTypeToSource.get(parameterType) + } +} diff --git a/src/support_code_library_builder/types.ts b/src/support_code_library_builder/types.ts index 0ab4e80b7..28cabf774 100644 --- a/src/support_code_library_builder/types.ts +++ b/src/support_code_library_builder/types.ts @@ -3,8 +3,8 @@ import TestCaseHookDefinition from '../models/test_case_hook_definition' import TestStepHookDefinition from '../models/test_step_hook_definition' import TestRunHookDefinition from '../models/test_run_hook_definition' import StepDefinition from '../models/step_definition' -import { ParameterTypeRegistry } from '@cucumber/cucumber-expressions' import { IWorld } from './world' +import { SourcedParameterTypeRegistry } from './sourced_parameter_type_registry' export type DefineStepPattern = string | RegExp export type ParallelAssignmentValidator = ( @@ -156,7 +156,7 @@ export interface ISupportCodeLibrary { readonly defaultTimeout: number readonly stepDefinitions: StepDefinition[] readonly undefinedParameterTypes: messages.UndefinedParameterType[] - readonly parameterTypeRegistry: ParameterTypeRegistry + readonly parameterTypeRegistry: SourcedParameterTypeRegistry readonly World: any readonly parallelCanAssign: ParallelAssignmentValidator }