Skip to content

Commit

Permalink
run: handle parse errors better (#1951)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidjgoss authored Mar 8, 2022
1 parent 36ccc1b commit 8f365aa
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Please see [CONTRIBUTING.md](https://github.com/cucumber/cucumber/blob/master/CO

### Fixed
- Warn users who are on an unsupported node version ([#1922](https://github.com/cucumber/cucumber-js/pull/1922))
- Allow formatters to finish when a Gherkin parse error is encountered ([#1404](https://github.com/cucumber/cucumber-js/issues/1404) [#1951](https://github.com/cucumber/cucumber-js/pull/1951))

### Changed
- Switch from `colors` to `chalk` for terminal coloring ([#1895](https://github.com/cucumber/cucumber-js/pull/1895))
Expand Down
29 changes: 27 additions & 2 deletions features/gherkin_parse_failure.feature
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Feature: Gherkin parse failure
I want an error message that points me to the file
So that I can quickly fix the issue and move on

Scenario:
Scenario: URI, line and column are called out in output
Given a file named "features/a.feature" with:
"""
Feature: a feature name
Expand All @@ -16,5 +16,30 @@ Feature: Gherkin parse failure
Then it fails
And the error output contains the text:
"""
Parse error in 'features/a.feature'
Parse error in "features/a.feature" (4:5)
"""

Scenario: All parseable sources and all parse errors are emitted
Given a file named "features/a.feature" with:
"""
Parse Error
"""
Given a file named "features/b.feature" with:
"""
Feature: a feature name
Scenario: a scenario name
Given a step
"""
Given a file named "features/c.feature" with:
"""
Parse Error
"""
When I run cucumber-js with `--format message`
Then it fails
And the output contains these types and quantities of message:
| TYPE | COUNT |
| source | 3 |
| gherkinDocument | 1 |
| pickle | 1 |
| parseError | 2 |

16 changes: 16 additions & 0 deletions features/step_definitions/cli_steps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,22 @@ Then('the output contains the text:', function (this: World, text: string) {
expect(actualOutput).to.include(expectedOutput)
})

Then(
'the output contains these types and quantities of message:',
function (this: World, expectedMessages: DataTable) {
const envelopes = this.lastRun.output
.split('\n')
.filter((line) => !!line)
.map((line) => JSON.parse(line))
expectedMessages.rows().forEach(([type, count]) => {
expect(envelopes.filter((envelope) => !!envelope[type])).to.have.length(
Number(count),
`Didn't find expected number of ${type} messages`
)
})
}
)

Then(
'the output does not contain the text:',
function (this: World, text: string) {
Expand Down
24 changes: 23 additions & 1 deletion src/api/runCucumber.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Envelope, IdGenerator } from '@cucumber/messages'
import { Envelope, IdGenerator, ParseError } from '@cucumber/messages'
import { EventEmitter } from 'events'
import { EventDataCollector } from '../formatter/helpers'
import {
Expand All @@ -15,6 +15,8 @@ import { makeRuntime } from './runtime'
import { initializeFormatters } from './formatters'
import { getSupportCodeLibrary } from './support'
import { Console } from 'console'
import * as messages from '@cucumber/messages'
import { doesHaveValue } from '../value_checker'

export async function runCucumber(
configuration: IRunConfiguration,
Expand Down Expand Up @@ -73,6 +75,12 @@ export async function runCucumber(
relativeTo: cwd,
})
let pickleIds: string[] = []
const parseErrors: ParseError[] = []
gherkinMessageStream.on('data', (envelope: messages.Envelope) => {
if (doesHaveValue(envelope.parseError)) {
parseErrors.push(envelope.parseError)
}
})

if (featurePaths.length > 0) {
pickleIds = await parseGherkinMessageStream({
Expand All @@ -89,6 +97,20 @@ export async function runCucumber(
}),
})
}

if (parseErrors.length) {
parseErrors.forEach((parseError) => {
logger.error(
`Parse error in "${parseError.source.uri}" ${parseError.message}`
)
})
await cleanup()
return {
success: false,
support: supportCodeLibrary,
}
}

emitSupportCodeMessages({
eventBroadcaster,
supportCodeLibrary,
Expand Down
7 changes: 0 additions & 7 deletions src/cli/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,6 @@ export async function parseGherkinMessageStream({
result.push(pickleId)
}
}
if (doesHaveValue(envelope.parseError)) {
reject(
new Error(
`Parse error in '${envelope.parseError.source.uri}': ${envelope.parseError.message}`
)
)
}
})
gherkinMessageStream.on('end', () => {
orderPickleIds(result, order, logger)
Expand Down

0 comments on commit 8f365aa

Please sign in to comment.