Skip to content

Commit

Permalink
Add support for new messages fields (#131)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidjgoss authored Nov 8, 2024
1 parent e498991 commit 1b7fe26
Show file tree
Hide file tree
Showing 15 changed files with 352 additions and 124 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## [Unreleased]
### Added
- Populate `TestRunStarted.id`, `TestCase.testRunStartedId` and `TestRunFinished.testRunStartedId` on messages
- Populate `Hook.type` on messages

### Changed
- Changed signatures of `makeTestCase` and `makeTestPlan`

## [17.0.0] - 2024-08-29
### Removed
Expand Down
244 changes: 175 additions & 69 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"@cucumber/gherkin-streams": "^5.0.1",
"@cucumber/gherkin-utils": "^9.0.0",
"@cucumber/message-streams": "^4.0.1",
"@cucumber/messages": "^24.0.0",
"@cucumber/messages": "^27.0.0",
"@types/glob": "8.1.0",
"@types/mocha": "10.0.9",
"@types/node": "20.17.6",
Expand All @@ -56,20 +56,20 @@
"typescript": "5.6.3"
},
"dependencies": {
"@cucumber/ci-environment": "^10.0.0",
"@cucumber/ci-environment": "^10.0.1",
"@cucumber/cucumber-expressions": "^18.0.0",
"@cucumber/tag-expressions": "^6.0.0",
"@cucumber/tag-expressions": "^6.1.0",
"@types/stack-utils": "2.0.3",
"commander": "12.1.0",
"glob": "11.0.0",
"stack-utils": "2.0.6"
},
"peerDependencies": {
"@cucumber/gherkin": ">=24.0",
"@cucumber/gherkin": ">=30.0",
"@cucumber/gherkin-streams": ">=5.0.1",
"@cucumber/gherkin-utils": ">=8.0.0",
"@cucumber/message-streams": ">=4.0.1",
"@cucumber/messages": ">=19.0"
"@cucumber/messages": ">=27.0"
},
"directories": {
"test": "test"
Expand Down
3 changes: 3 additions & 0 deletions src/Hook.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as messages from '@cucumber/messages'
import { HookType } from '@cucumber/messages'
import parseTagExpression from '@cucumber/tag-expressions'

import SupportCodeExecutor from './SupportCodeExecutor'
Expand All @@ -7,6 +8,7 @@ import { AnyBody, IHook, ISupportCodeExecutor } from './types'
export default class Hook implements IHook {
constructor(
public readonly id: string,
private readonly type: HookType,
private readonly tagExpression: string | null,
private readonly sourceReference: messages.SourceReference,
private readonly body: AnyBody,
Expand All @@ -24,6 +26,7 @@ export default class Hook implements IHook {
public toMessage(): messages.Envelope {
const hook: messages.Hook = {
id: this.id,
type: this.type,
sourceReference: this.sourceReference,
}

Expand Down
25 changes: 22 additions & 3 deletions src/SupportCode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
ParameterTypeRegistry,
} from '@cucumber/cucumber-expressions'
import * as messages from '@cucumber/messages'
import { HookType } from '@cucumber/messages'

import DateClock from './DateClock'
import { MakeErrorMessage, withFullStackTrace } from './ErrorMessageGenerator'
Expand Down Expand Up @@ -106,7 +107,12 @@ export default class SupportCode {
body?: AnyBody
) {
this.registerBeforeHook(
this.makeHook(sourceReference, tagExpressionOptionsOrBody, body)
this.makeHook(
HookType.BEFORE_TEST_CASE,
sourceReference,
tagExpressionOptionsOrBody,
body
)
)
}

Expand All @@ -120,7 +126,12 @@ export default class SupportCode {
body?: AnyBody
) {
this.registerAfterHook(
this.makeHook(sourceReference, tagExpressionOptionsOrBody, body)
this.makeHook(
HookType.AFTER_TEST_CASE,
sourceReference,
tagExpressionOptionsOrBody,
body
)
)
}

Expand All @@ -129,6 +140,7 @@ export default class SupportCode {
}

private makeHook(
type: HookType,
sourceReference: messages.SourceReference,
tagExpressionOptionsOrBody: string | HookOptions | AnyBody,
body?: AnyBody
Expand All @@ -147,6 +159,13 @@ export default class SupportCode {
typeof tagExpressionOptionsOrBody === 'function'
? tagExpressionOptionsOrBody
: body
return new Hook(this.newId(), tagExpression, sourceReference, body, name)
return new Hook(
this.newId(),
type,
tagExpression,
sourceReference,
body,
name
)
}
}
2 changes: 2 additions & 0 deletions src/TestCase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const { millisecondsSinceEpochToTimestamp } = messages.TimeConversion
export default class TestCase implements ITestCase {
constructor(
public readonly id: string,
private readonly runId: string,
private readonly testSteps: ITestStep[],
private readonly pickleId: string,
private readonly clock: IClock
Expand All @@ -18,6 +19,7 @@ export default class TestCase implements ITestCase {
return {
testCase: {
id: this.id,
testRunStartedId: this.runId,
pickleId: this.pickleId,
testSteps: this.testSteps.map((step) => step.toMessage()),
},
Expand Down
3 changes: 3 additions & 0 deletions src/TestPlan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { EnvelopeListener, ITestCase, ITestPlan, RunOptions } from './types'

export default class TestPlan implements ITestPlan {
constructor(
private readonly runId: string,
private readonly testCases: ITestCase[],
private readonly supportCode: SupportCode,
private readonly runOptions: RunOptions
Expand All @@ -30,6 +31,7 @@ export default class TestPlan implements ITestPlan {

listener({
testRunStarted: {
id: this.runId,
timestamp: messages.TimeConversion.millisecondsSinceEpochToTimestamp(
this.supportCode.clock.clockNow()
),
Expand Down Expand Up @@ -60,6 +62,7 @@ export default class TestPlan implements ITestPlan {
}
listener({
testRunFinished: {
testRunStartedId: this.runId,
timestamp: messages.TimeConversion.millisecondsSinceEpochToTimestamp(
this.supportCode.clock.clockNow()
),
Expand Down
3 changes: 2 additions & 1 deletion src/makeTestCase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from './types'

export default function makeTestCase(
runId: string,
pickle: messages.Pickle,
stepDefinitions: readonly IStepDefinition[],
beforeHooks: readonly IHook[],
Expand Down Expand Up @@ -67,7 +68,7 @@ export default function makeTestCase(
.concat(pickleTestSteps)
.concat(afterHookSteps)

return new TestCase(newId(), testSteps, pickle.id, clock)
return new TestCase(newId(), runId, testSteps, pickle.id, clock)
}

function makeHookSteps(
Expand Down
4 changes: 3 additions & 1 deletion src/makeTestPlan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ export default function makeTestPlan(
runOptions: RunOptions,
makeTestCase: MakeTestCase
): ITestPlan {
const runId = supportCode.newId()
const pickles = gherkinQuery.getPickles()
const testCases = pickles.map((pickle) =>
makeTestCase(
runId,
pickle,
supportCode.stepDefinitions,
supportCode.beforeHooks,
Expand All @@ -29,5 +31,5 @@ export default function makeTestPlan(
)
)

return new TestPlan(testCases, supportCode, runOptions)
return new TestPlan(runId, testCases, supportCode, runOptions)
}
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ export type MakeHookTestStep = (
) => ITestStep

export type MakeTestCase = (
runId: string,
pickle: messages.Pickle,
stepDefinitions: readonly IStepDefinition[],
beforeHooks: readonly IHook[],
Expand Down
59 changes: 50 additions & 9 deletions test/HookTest.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as messages from '@cucumber/messages'
import { Envelope, HookType } from '@cucumber/messages'
import assert from 'assert'

import Hook from '../src/Hook'
Expand All @@ -7,9 +8,15 @@ import TestWorld from './TestWorld'
describe('Hook', () => {
describe('#match', () => {
it("does not return a SupportCodeExecutor if the hook's tag expression does not match", () => {
const hook = new Hook('hook-id', 'not @foo', null, () => {
throw new Error('unexpected')
})
const hook = new Hook(
'hook-id',
HookType.BEFORE_TEST_CASE,
'not @foo',
null,
() => {
throw new Error('unexpected')
}
)
const pickle: messages.Pickle = {
tags: [{ name: '@foo', astNodeId: '1' }],
astNodeIds: [],
Expand All @@ -25,9 +32,15 @@ describe('Hook', () => {
})

it("returns a SupportCodeExecutor if the hook's tag expression matches", () => {
const hook = new Hook('hook-id', 'not @foo', null, () => {
return 'something'
})
const hook = new Hook(
'hook-id',
HookType.BEFORE_TEST_CASE,
'not @foo',
null,
() => {
return 'something'
}
)
const pickle: messages.Pickle = {
tags: [{ name: '@bar', astNodeId: '1' }],
astNodeIds: [],
Expand All @@ -43,9 +56,15 @@ describe('Hook', () => {
})

it('returns a SupportCodeExecutor if the hook has no tag expression', () => {
const hook = new Hook('hook-id', null, null, () => {
return 'something'
})
const hook = new Hook(
'hook-id',
HookType.BEFORE_TEST_CASE,
null,
null,
() => {
return 'something'
}
)
const pickle: messages.Pickle = {
tags: [{ name: '@bar', astNodeId: '1' }],
astNodeIds: [],
Expand All @@ -60,4 +79,26 @@ describe('Hook', () => {
assert.strictEqual(executor.execute(new TestWorld()), 'something')
})
})

describe('#toMessage', () => {
it('converts to hook message', () => {
const hook = new Hook(
'hook-id',
HookType.BEFORE_TEST_CASE,
null,
{ uri: '/some/file.ts' },
() => {
return 'something'
}
)

assert.deepStrictEqual<Envelope>(hook.toMessage(), {
hook: {
id: 'hook-id',
type: HookType.BEFORE_TEST_CASE,
sourceReference: { uri: '/some/file.ts' },
},
})
})
})
})
Loading

0 comments on commit 1b7fe26

Please sign in to comment.