Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add name property to hook schema #1914

Merged
merged 11 commits into from
Mar 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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