Skip to content

Commit

Permalink
messages: add name property to hook schema (#1914)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidjgoss authored Mar 3, 2022
1 parent 4687684 commit 2197a4c
Show file tree
Hide file tree
Showing 22 changed files with 166 additions and 79 deletions.
2 changes: 2 additions & 0 deletions compatibility-kit/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Added

* Add a named hooked case to the Hooks suite ([#1914](https://github.com/cucumber/common/pull/1914))

### Changed

### Deprecated
Expand Down
137 changes: 74 additions & 63 deletions compatibility-kit/javascript/features/hooks/hooks.feature.ndjson

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions compatibility-kit/javascript/features/hooks/hooks.feature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ Before(function () {
// no-op
})

Before({name: 'A named hook'}, function () {
// no-op
})

When('a step passes', function () {
// no-op
})
Expand Down
5 changes: 5 additions & 0 deletions compatibility-kit/ruby/features/hooks/hooks.feature.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ def attach_or_embed(world, data, media_type)
# no-op
end

Before do
# This is the equivalent of the new named hook in typescript
# no-op
end

When('a step passes') do
# no-op
end
Expand Down
2 changes: 1 addition & 1 deletion compatibility-kit/ruby/scripts/neutralize-json
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ set -euf -o pipefail
jq "del(.[].elements[]?.before[]?.result.duration)" | \
jq "del(.[].elements[]?.steps[]?.result.duration)" | \
jq "del(.[].elements[]?.after[]?.result.duration)" | \
jq
jq "."
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ jq "del(.[].elements[]?.after[]?.result.duration)" | \
jq ".[].elements[]?.after[]?.result.error_message = \"some after hook error\"" | \
jq ".[].elements[]?.after[]?.match.location = \"some_after_hook.xyz\"" | \

jq
jq "."
2 changes: 2 additions & 0 deletions fake-cucumber/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Added

* Ability to provide a name for `Before` and `After` hooks ([#1914](https://github.com/cucumber/common/pull/1914))

### Changed

### Deprecated
Expand Down
7 changes: 6 additions & 1 deletion fake-cucumber/javascript/src/Hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ export default class Hook implements IHook {
public readonly id: string,
private readonly tagExpression: string | null,
private readonly sourceReference: messages.SourceReference,
private readonly body: AnyBody
private readonly body: AnyBody,
private readonly name?: string
) {}

public match(pickle: messages.Pickle): ISupportCodeExecutor | null {
Expand All @@ -23,6 +24,10 @@ export default class Hook implements IHook {
sourceReference: this.sourceReference,
}

if (this.name) {
hook.name = this.name
}

if (this.tagExpression) {
hook.tagExpression = this.tagExpression
}
Expand Down
25 changes: 16 additions & 9 deletions fake-cucumber/javascript/src/SupportCode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {
ParameterTypeRegistry,
} from '@cucumber/cucumber-expressions'
import * as messages from '@cucumber/messages'
import { IHook, AnyBody, IStepDefinition } from './types'
import { IHook, AnyBody, IStepDefinition, HookOptions } from './types'
import ExpressionStepDefinition from './ExpressionStepDefinition'
import Hook from './Hook'
import IClock from './IClock'
Expand Down Expand Up @@ -90,10 +90,10 @@ export default class SupportCode {

public defineBeforeHook(
sourceReference: messages.SourceReference,
tagExpressionOrBody: string | AnyBody,
tagExpressionOptionsOrBody: string | HookOptions | AnyBody,
body?: AnyBody
) {
this.registerBeforeHook(this.makeHook(sourceReference, tagExpressionOrBody, body))
this.registerBeforeHook(this.makeHook(sourceReference, tagExpressionOptionsOrBody, body))
}

public registerBeforeHook(hook: IHook) {
Expand All @@ -102,10 +102,10 @@ export default class SupportCode {

public defineAfterHook(
sourceReference: messages.SourceReference,
tagExpressionOrBody: string | AnyBody,
tagExpressionOptionsOrBody: string | HookOptions | AnyBody,
body?: AnyBody
) {
this.registerAfterHook(this.makeHook(sourceReference, tagExpressionOrBody, body))
this.registerAfterHook(this.makeHook(sourceReference, tagExpressionOptionsOrBody, body))
}

public registerAfterHook(hook: IHook) {
Expand All @@ -114,11 +114,18 @@ export default class SupportCode {

private makeHook(
sourceReference: messages.SourceReference,
tagExpressionOrBody: string | AnyBody,
tagExpressionOptionsOrBody: string | HookOptions | AnyBody,
body?: AnyBody
) {
const tagExpression = typeof tagExpressionOrBody === 'string' ? tagExpressionOrBody : null
body = typeof tagExpressionOrBody !== 'string' ? tagExpressionOrBody : body
return new Hook(this.newId(), tagExpression, sourceReference, body)
const name =
typeof tagExpressionOptionsOrBody === 'object' ? tagExpressionOptionsOrBody.name : undefined
let tagExpression = null
if (typeof tagExpressionOptionsOrBody === 'string') {
tagExpression = tagExpressionOptionsOrBody
} else if (typeof tagExpressionOptionsOrBody === 'object') {
tagExpression = tagExpressionOptionsOrBody.tagExpression ?? null
}
body = typeof tagExpressionOptionsOrBody === 'function' ? tagExpressionOptionsOrBody : body
return new Hook(this.newId(), tagExpression, sourceReference, body, name)
}
}
6 changes: 3 additions & 3 deletions fake-cucumber/javascript/src/dsl.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import SupportCode from './SupportCode'
import { AnyBody } from './types'
import { AnyBody, HookOptions } from './types'
import * as messages from '@cucumber/messages'
import StackUtils from 'stack-utils'
import IParameterTypeDefinition from './IParameterTypeDefinition'
Expand All @@ -15,7 +15,7 @@ function defineStepDefinition(expression: string | RegExp, body: AnyBody) {
global.supportCode.defineStepDefinition(getSourceReference(new Error().stack), expression, body)
}

function defineBeforeHook(tagExpressionOrBody: string | AnyBody, body?: AnyBody) {
function defineBeforeHook(tagExpressionOrBody: string | HookOptions | AnyBody, body?: AnyBody) {
//@ts-ignore
global.supportCode.defineBeforeHook(
getSourceReference(new Error().stack),
Expand All @@ -24,7 +24,7 @@ function defineBeforeHook(tagExpressionOrBody: string | AnyBody, body?: AnyBody)
)
}

function defineAfterHook(tagExpressionOrBody: string | AnyBody, body?: AnyBody) {
function defineAfterHook(tagExpressionOrBody: string | HookOptions | AnyBody, body?: AnyBody) {
//@ts-ignore
global.supportCode.defineAfterHook(
getSourceReference(new Error().stack),
Expand Down
4 changes: 4 additions & 0 deletions fake-cucumber/javascript/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ export interface ITestCase {
}

export type EnvelopeListener = (envelope: messages.Envelope) => void
export interface HookOptions {
name?: string
tagExpression?: string
}
export type AnyBody = (...args: readonly unknown[]) => unknown
export type Attach = (data: string | Buffer | Readable, mediaType: string) => void | Promise<void>
export type Log = (text: string) => void | Promise<void>
Expand Down
2 changes: 1 addition & 1 deletion json-formatter/ruby-testdata/neutralize-json
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ jq ".[].elements[]?.after[]?.result.duration = 99" | \
jq ".[].elements[]?.after[]?.result.error_message = \"some after hook error\"" | \
jq ".[].elements[]?.after[]?.match.location = \"some_after_hook.xyz\"" | \

jq
jq "."
1 change: 1 addition & 0 deletions messages/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

* Support for EcmaScript modules (aka ESM)
([#1756](https://github.com/cucumber/common/pull/1756))
* New optional `name` property on the Hook schema ([#1914](https://github.com/cucumber/common/pull/1914))

### Changed

Expand Down
1 change: 1 addition & 0 deletions messages/go/messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ type Tag struct {

type Hook struct {
Id string `json:"id"`
Name string `json:"name,omitempty"`
SourceReference *SourceReference `json:"sourceReference"`
TagExpression string `json:"tagExpression,omitempty"`
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,18 @@
@SuppressWarnings("unused")
public final class Hook {
private final String id;
private final String name;
private final SourceReference sourceReference;
private final String tagExpression;

public Hook(
String id,
String name,
SourceReference sourceReference,
String tagExpression
) {
this.id = requireNonNull(id, "Hook.id cannot be null");
this.name = name;
this.sourceReference = requireNonNull(sourceReference, "Hook.sourceReference cannot be null");
this.tagExpression = tagExpression;
}
Expand All @@ -28,6 +31,10 @@ public String getId() {
return id;
}

public Optional<String> getName() {
return Optional.ofNullable(name);
}

public SourceReference getSourceReference() {
return sourceReference;
}
Expand All @@ -43,6 +50,7 @@ public boolean equals(Object o) {
Hook that = (Hook) o;
return
id.equals(that.id) &&
Objects.equals(name, that.name) &&
sourceReference.equals(that.sourceReference) &&
Objects.equals(tagExpression, that.tagExpression);
}
Expand All @@ -51,6 +59,7 @@ public boolean equals(Object o) {
public int hashCode() {
return Objects.hash(
id,
name,
sourceReference,
tagExpression
);
Expand All @@ -60,6 +69,7 @@ public int hashCode() {
public String toString() {
return "Hook{" +
"id=" + id +
", name=" + name +
", sourceReference=" + sourceReference +
", tagExpression=" + tagExpression +
'}';
Expand Down
2 changes: 2 additions & 0 deletions messages/javascript/src/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,8 @@ export class Hook {

id: string = ''

name?: string

@Type(() => SourceReference)
sourceReference: SourceReference = new SourceReference()

Expand Down
3 changes: 3 additions & 0 deletions messages/jsonschema/Hook.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"sourceReference": {
"$ref": "./SourceReference.json"
},
Expand Down
1 change: 1 addition & 0 deletions messages/messages.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ will only have one of its fields set, which indicates the payload of the message
| Field | Type | Required | Description |
| ----- | ---- | ----------- | ----------- |
| `id` | string | yes | |
| `name` | string | no | |
| `sourceReference` | [SourceReference](#sourcereference) | yes | |
| `tagExpression` | string | no | |

Expand Down
11 changes: 11 additions & 0 deletions messages/perl/lib/Cucumber/Messages.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1913,6 +1913,7 @@ use Scalar::Util qw( blessed );

my %types = (
id => 'string',
name => 'string',
source_reference => 'Cucumber::Messages::SourceReference',
tag_expression => 'string',
);
Expand All @@ -1937,6 +1938,16 @@ has id =>
);


=head4 name
=cut

has name =>
(is => 'ro',
);


=head4 source_reference
Expand Down
13 changes: 13 additions & 0 deletions messages/php/src-generated/Hook.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ final class Hook implements JsonSerializable
*/
public function __construct(
public readonly string $id = '',
public readonly ?string $name = null,
public readonly SourceReference $sourceReference = new SourceReference(),
public readonly ?string $tagExpression = null,
) {
Expand All @@ -39,11 +40,13 @@ public function __construct(
public static function fromArray(array $arr): self
{
self::ensureId($arr);
self::ensureName($arr);
self::ensureSourceReference($arr);
self::ensureTagExpression($arr);

return new self(
(string) $arr['id'],
isset($arr['name']) ? (string) $arr['name'] : null,
SourceReference::fromArray($arr['sourceReference']),
isset($arr['tagExpression']) ? (string) $arr['tagExpression'] : null,
);
Expand All @@ -62,6 +65,16 @@ private static function ensureId(array $arr): void
}
}

/**
* @psalm-assert array{name?: string|int|bool} $arr
*/
private static function ensureName(array $arr): void
{
if (array_key_exists('name', $arr) && is_array($arr['name'])) {
throw new SchemaViolationException('Property \'name\' was array');
}
}

/**
* @psalm-assert array{sourceReference: array} $arr
*/
Expand Down
1 change: 1 addition & 0 deletions messages/ruby/lib/cucumber/messages.deserializers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ def self.from_h(hash)

self.new(
id: hash[:id],
name: hash[:name],
source_reference: SourceReference.from_h(hash[:sourceReference]),
tag_expression: hash[:tagExpression],
)
Expand Down
4 changes: 4 additions & 0 deletions messages/ruby/lib/cucumber/messages.dtos.rb
Original file line number Diff line number Diff line change
Expand Up @@ -794,16 +794,20 @@ class Hook < ::Cucumber::Messages::Message

attr_reader :id

attr_reader :name

attr_reader :source_reference

attr_reader :tag_expression

def initialize(
id: '',
name: nil,
source_reference: SourceReference.new,
tag_expression: nil
)
@id = id
@name = name
@source_reference = source_reference
@tag_expression = tag_expression
end
Expand Down

0 comments on commit 2197a4c

Please sign in to comment.