diff --git a/CHANGELOG.md b/CHANGELOG.md index c14922e7..ff663feb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Added +- Add `Attachment.testRunHookStartedId` for traceability of attachments to test run hooks ([#301](https://github.com/cucumber/messages/pull/301)) ### Fixed - [python] Add a LICENSE file for Python ([#278](https://github.com/cucumber/messages/pull/278)) diff --git a/cpp/include/messages/cucumber/messages/attachment.hpp b/cpp/include/messages/cucumber/messages/attachment.hpp index 3e0cd97a..7c984c08 100644 --- a/cpp/include/messages/cucumber/messages/attachment.hpp +++ b/cpp/include/messages/cucumber/messages/attachment.hpp @@ -42,6 +42,7 @@ struct attachment std::optional test_step_id; std::optional url; std::optional test_run_started_id; + std::optional test_run_hook_started_id; std::string to_string() const; diff --git a/cpp/src/lib/messages/cucumber/messages/attachment.cpp b/cpp/src/lib/messages/cucumber/messages/attachment.cpp index ba133cdb..fb84b07c 100644 --- a/cpp/src/lib/messages/cucumber/messages/attachment.cpp +++ b/cpp/src/lib/messages/cucumber/messages/attachment.cpp @@ -19,6 +19,7 @@ attachment::to_string() const cucumber::messages::to_string(oss, ", test_step_id=", test_step_id); cucumber::messages::to_string(oss, ", url=", url); cucumber::messages::to_string(oss, ", test_run_started_id=", test_run_started_id); + cucumber::messages::to_string(oss, ", test_run_hook_started_id=", test_run_hook_started_id); return oss.str(); } @@ -35,6 +36,7 @@ attachment::to_json(json& j) const cucumber::messages::to_json(j, camelize("test_step_id"), test_step_id); cucumber::messages::to_json(j, camelize("url"), url); cucumber::messages::to_json(j, camelize("test_run_started_id"), test_run_started_id); + cucumber::messages::to_json(j, camelize("test_run_hook_started_id"), test_run_hook_started_id); } std::string diff --git a/dotnet/Cucumber.Messages/generated/Attachment.cs b/dotnet/Cucumber.Messages/generated/Attachment.cs index 0177ba31..8a51b318 100644 --- a/dotnet/Cucumber.Messages/generated/Attachment.cs +++ b/dotnet/Cucumber.Messages/generated/Attachment.cs @@ -57,7 +57,13 @@ public sealed class Attachment */ public string MediaType { get; private set; } public Source Source { get; private set; } + /** + * The identifier of the test case attempt if the attachment was created during the execution of a test step + */ public string TestCaseStartedId { get; private set; } + /** + * The identifier of the test step if the attachment was created during the execution of a test step + */ public string TestStepId { get; private set; } /** * A URL where the attachment can be retrieved. This field should not be set by Cucumber. @@ -73,7 +79,14 @@ public sealed class Attachment * separately from reports. */ public string Url { get; private set; } + /** + * Not used; implementers should instead populate `testRunHookStartedId` if an attachment was created during the execution of a test run hook + */ public string TestRunStartedId { get; private set; } + /** + * The identifier of the test run hook execution if the attachment was created during the execution of a test run hook + */ + public string TestRunHookStartedId { get; private set; } public Attachment( @@ -85,7 +98,8 @@ public Attachment( string testCaseStartedId, string testStepId, string url, - string testRunStartedId + string testRunStartedId, + string testRunHookStartedId ) { RequireNonNull(body, "Body", "Attachment.Body cannot be null"); @@ -100,6 +114,7 @@ string testRunStartedId this.TestStepId = testStepId; this.Url = url; this.TestRunStartedId = testRunStartedId; + this.TestRunHookStartedId = testRunHookStartedId; } public override bool Equals(Object o) @@ -116,7 +131,8 @@ public override bool Equals(Object o) Object.Equals(TestCaseStartedId, that.TestCaseStartedId) && Object.Equals(TestStepId, that.TestStepId) && Object.Equals(Url, that.Url) && - Object.Equals(TestRunStartedId, that.TestRunStartedId); + Object.Equals(TestRunStartedId, that.TestRunStartedId) && + Object.Equals(TestRunHookStartedId, that.TestRunHookStartedId); } public override int GetHashCode() @@ -139,6 +155,8 @@ public override int GetHashCode() hash = hash * 31 + Url.GetHashCode(); if (TestRunStartedId != null) hash = hash * 31 + TestRunStartedId.GetHashCode(); + if (TestRunHookStartedId != null) + hash = hash * 31 + TestRunHookStartedId.GetHashCode(); return hash; } @@ -154,6 +172,7 @@ public override string ToString() ", testStepId=" + TestStepId + ", url=" + Url + ", testRunStartedId=" + TestRunStartedId + + ", testRunHookStartedId=" + TestRunHookStartedId + '}'; } diff --git a/go/messages.go b/go/messages.go index eaba8e4b..f244ff5e 100644 --- a/go/messages.go +++ b/go/messages.go @@ -1,15 +1,16 @@ package messages type Attachment struct { - Body string `json:"body"` - ContentEncoding AttachmentContentEncoding `json:"contentEncoding"` - FileName string `json:"fileName,omitempty"` - MediaType string `json:"mediaType"` - Source *Source `json:"source,omitempty"` - TestCaseStartedId string `json:"testCaseStartedId,omitempty"` - TestStepId string `json:"testStepId,omitempty"` - Url string `json:"url,omitempty"` - TestRunStartedId string `json:"testRunStartedId,omitempty"` + Body string `json:"body"` + ContentEncoding AttachmentContentEncoding `json:"contentEncoding"` + FileName string `json:"fileName,omitempty"` + MediaType string `json:"mediaType"` + Source *Source `json:"source,omitempty"` + TestCaseStartedId string `json:"testCaseStartedId,omitempty"` + TestStepId string `json:"testStepId,omitempty"` + Url string `json:"url,omitempty"` + TestRunStartedId string `json:"testRunStartedId,omitempty"` + TestRunHookStartedId string `json:"testRunHookStartedId,omitempty"` } type Duration struct { diff --git a/java/src/generated/java/io/cucumber/messages/types/Attachment.java b/java/src/generated/java/io/cucumber/messages/types/Attachment.java index 3bf3401e..a1ec6529 100644 --- a/java/src/generated/java/io/cucumber/messages/types/Attachment.java +++ b/java/src/generated/java/io/cucumber/messages/types/Attachment.java @@ -35,6 +35,7 @@ public final class Attachment { private final String testStepId; private final String url; private final String testRunStartedId; + private final String testRunHookStartedId; public Attachment( String body, @@ -45,7 +46,8 @@ public Attachment( String testCaseStartedId, String testStepId, String url, - String testRunStartedId + String testRunStartedId, + String testRunHookStartedId ) { this.body = requireNonNull(body, "Attachment.body cannot be null"); this.contentEncoding = requireNonNull(contentEncoding, "Attachment.contentEncoding cannot be null"); @@ -56,6 +58,7 @@ public Attachment( this.testStepId = testStepId; this.url = url; this.testRunStartedId = testRunStartedId; + this.testRunHookStartedId = testRunHookStartedId; } /** @@ -102,10 +105,16 @@ public Optional getSource() { return Optional.ofNullable(source); } + /** + * The identifier of the test case attempt if the attachment was created during the execution of a test step + */ public Optional getTestCaseStartedId() { return Optional.ofNullable(testCaseStartedId); } + /** + * The identifier of the test step if the attachment was created during the execution of a test step + */ public Optional getTestStepId() { return Optional.ofNullable(testStepId); } @@ -127,10 +136,20 @@ public Optional getUrl() { return Optional.ofNullable(url); } + /** + * Not used; implementers should instead populate `testRunHookStartedId` if an attachment was created during the execution of a test run hook + */ public Optional getTestRunStartedId() { return Optional.ofNullable(testRunStartedId); } + /** + * The identifier of the test run hook execution if the attachment was created during the execution of a test run hook + */ + public Optional getTestRunHookStartedId() { + return Optional.ofNullable(testRunHookStartedId); + } + @Override public boolean equals(Object o) { if (this == o) return true; @@ -145,7 +164,8 @@ public boolean equals(Object o) { Objects.equals(testCaseStartedId, that.testCaseStartedId) && Objects.equals(testStepId, that.testStepId) && Objects.equals(url, that.url) && - Objects.equals(testRunStartedId, that.testRunStartedId); + Objects.equals(testRunStartedId, that.testRunStartedId) && + Objects.equals(testRunHookStartedId, that.testRunHookStartedId); } @Override @@ -159,7 +179,8 @@ public int hashCode() { testCaseStartedId, testStepId, url, - testRunStartedId + testRunStartedId, + testRunHookStartedId ); } @@ -175,6 +196,7 @@ public String toString() { ", testStepId=" + testStepId + ", url=" + url + ", testRunStartedId=" + testRunStartedId + + ", testRunHookStartedId=" + testRunHookStartedId + '}'; } } diff --git a/java/src/test/java/io/cucumber/messages/MessagesTest.java b/java/src/test/java/io/cucumber/messages/MessagesTest.java index 4d7e3556..1be32c32 100644 --- a/java/src/test/java/io/cucumber/messages/MessagesTest.java +++ b/java/src/test/java/io/cucumber/messages/MessagesTest.java @@ -10,7 +10,7 @@ public class MessagesTest { @Test void is_invalid_when_required_fields_are_missing() { assertThrows(NullPointerException.class, () -> { - new Attachment(null, null, null, null, null, null, null, null, null); + new Attachment(null, null, null, null, null, null, null, null, null, null); }, "Attachment.body cannot be null"); } diff --git a/javascript/src/messages.ts b/javascript/src/messages.ts index 86e8abe0..8e6ff7d8 100644 --- a/javascript/src/messages.ts +++ b/javascript/src/messages.ts @@ -21,6 +21,8 @@ export class Attachment { url?: string testRunStartedId?: string + + testRunHookStartedId?: string } export class Duration { diff --git a/jsonschema/Attachment.json b/jsonschema/Attachment.json index 5a88ac84..abbbc572 100644 --- a/jsonschema/Attachment.json +++ b/jsonschema/Attachment.json @@ -33,9 +33,11 @@ "$ref": "./Source.json" }, "testCaseStartedId": { + "description": "The identifier of the test case attempt if the attachment was created during the execution of a test step", "type": "string" }, "testStepId": { + "description": "The identifier of the test step if the attachment was created during the execution of a test step", "type": "string" }, "url": { @@ -43,6 +45,12 @@ "type": "string" }, "testRunStartedId": { + "description": "Not used; implementers should instead populate `testRunHookStartedId` if an attachment was created during the execution of a test run hook", + "type": "string", + "deprecated": true + }, + "testRunHookStartedId": { + "description": "The identifier of the test run hook execution if the attachment was created during the execution of a test run hook", "type": "string" } }, diff --git a/messages.md b/messages.md index a878324c..d90dbe6b 100644 --- a/messages.md +++ b/messages.md @@ -16,6 +16,7 @@ will only have one of its fields set, which indicates the payload of the message | `testStepId` | string | no | | | `url` | string | no | | | `testRunStartedId` | string | no | | +| `testRunHookStartedId` | string | no | | ## Duration diff --git a/perl/lib/Cucumber/Messages.pm b/perl/lib/Cucumber/Messages.pm index 9f76facf..6ed52b58 100644 --- a/perl/lib/Cucumber/Messages.pm +++ b/perl/lib/Cucumber/Messages.pm @@ -87,6 +87,7 @@ my %types = ( test_step_id => 'string', url => 'string', test_run_started_id => 'string', + test_run_hook_started_id => 'string', ); # This is a work-around for the fact that Moo doesn't have introspection @@ -188,7 +189,7 @@ has source => =head4 test_case_started_id - +The identifier of the test case attempt if the attachment was created during the execution of a test step =cut has test_case_started_id => @@ -198,7 +199,7 @@ has test_case_started_id => =head4 test_step_id - +The identifier of the test step if the attachment was created during the execution of a test step =cut has test_step_id => @@ -229,7 +230,7 @@ has url => =head4 test_run_started_id - +Not used; implementers should instead populate `testRunHookStartedId` if an attachment was created during the execution of a test run hook =cut has test_run_started_id => @@ -237,6 +238,16 @@ has test_run_started_id => ); +=head4 test_run_hook_started_id + +The identifier of the test run hook execution if the attachment was created during the execution of a test run hook +=cut + +has test_run_hook_started_id => + (is => 'ro', + ); + + } package Cucumber::Messages::Duration { diff --git a/php/src-generated/Attachment.php b/php/src-generated/Attachment.php index 7008644d..bf34254e 100644 --- a/php/src-generated/Attachment.php +++ b/php/src-generated/Attachment.php @@ -68,7 +68,15 @@ public function __construct( */ public readonly string $mediaType = '', public readonly ?Source $source = null, + + /** + * The identifier of the test case attempt if the attachment was created during the execution of a test step + */ public readonly ?string $testCaseStartedId = null, + + /** + * The identifier of the test step if the attachment was created during the execution of a test step + */ public readonly ?string $testStepId = null, /** @@ -85,7 +93,16 @@ public function __construct( * separately from reports. */ public readonly ?string $url = null, + + /** + * Not used; implementers should instead populate `testRunHookStartedId` if an attachment was created during the execution of a test run hook + */ public readonly ?string $testRunStartedId = null, + + /** + * The identifier of the test run hook execution if the attachment was created during the execution of a test run hook + */ + public readonly ?string $testRunHookStartedId = null, ) { } @@ -105,6 +122,7 @@ public static function fromArray(array $arr): self self::ensureTestStepId($arr); self::ensureUrl($arr); self::ensureTestRunStartedId($arr); + self::ensureTestRunHookStartedId($arr); return new self( (string) $arr['body'], @@ -116,6 +134,7 @@ public static function fromArray(array $arr): self isset($arr['testStepId']) ? (string) $arr['testStepId'] : null, isset($arr['url']) ? (string) $arr['url'] : null, isset($arr['testRunStartedId']) ? (string) $arr['testRunStartedId'] : null, + isset($arr['testRunHookStartedId']) ? (string) $arr['testRunHookStartedId'] : null, ); } @@ -217,4 +236,14 @@ private static function ensureTestRunStartedId(array $arr): void throw new SchemaViolationException('Property \'testRunStartedId\' was array'); } } + + /** + * @psalm-assert array{testRunHookStartedId?: string|int|bool} $arr + */ + private static function ensureTestRunHookStartedId(array $arr): void + { + if (array_key_exists('testRunHookStartedId', $arr) && is_array($arr['testRunHookStartedId'])) { + throw new SchemaViolationException('Property \'testRunHookStartedId\' was array'); + } + } } diff --git a/python/src/cucumber_messages/_messages.py b/python/src/cucumber_messages/_messages.py index 1de36576..4439dd27 100644 --- a/python/src/cucumber_messages/_messages.py +++ b/python/src/cucumber_messages/_messages.py @@ -61,9 +61,10 @@ class Attachment: """ source: Optional[Source] = None - test_case_started_id: Optional[str] = None - test_run_started_id: Optional[str] = None - test_step_id: Optional[str] = None + test_case_started_id: Optional[str] = None # The identifier of the test case attempt if the attachment was created during the execution of a test step + test_run_hook_started_id: Optional[str] = None # The identifier of the test run hook execution if the attachment was created during the execution of a test run hook + test_run_started_id: Optional[str] = None # Not used; implementers should instead populate `testRunHookStartedId` if an attachment was created during the execution of a test run hook + test_step_id: Optional[str] = None # The identifier of the test step if the attachment was created during the execution of a test step url: Optional[str] = None """ * diff --git a/ruby/lib/cucumber/messages/attachment.rb b/ruby/lib/cucumber/messages/attachment.rb index 5028cb59..c56bf2ab 100644 --- a/ruby/lib/cucumber/messages/attachment.rb +++ b/ruby/lib/cucumber/messages/attachment.rb @@ -59,8 +59,14 @@ class Attachment < Message attr_reader :source + ## + # The identifier of the test case attempt if the attachment was created during the execution of a test step + ## attr_reader :test_case_started_id + ## + # The identifier of the test step if the attachment was created during the execution of a test step + ## attr_reader :test_step_id ## @@ -79,8 +85,16 @@ class Attachment < Message ## attr_reader :url + ## + # Not used; implementers should instead populate `testRunHookStartedId` if an attachment was created during the execution of a test run hook + ## attr_reader :test_run_started_id + ## + # The identifier of the test run hook execution if the attachment was created during the execution of a test run hook + ## + attr_reader :test_run_hook_started_id + def initialize( body: '', content_encoding: AttachmentContentEncoding::IDENTITY, @@ -90,7 +104,8 @@ def initialize( test_case_started_id: nil, test_step_id: nil, url: nil, - test_run_started_id: nil + test_run_started_id: nil, + test_run_hook_started_id: nil ) @body = body @content_encoding = content_encoding @@ -101,6 +116,7 @@ def initialize( @test_step_id = test_step_id @url = url @test_run_started_id = test_run_started_id + @test_run_hook_started_id = test_run_hook_started_id super() end @@ -123,7 +139,8 @@ def self.from_h(hash) test_case_started_id: hash[:testCaseStartedId], test_step_id: hash[:testStepId], url: hash[:url], - test_run_started_id: hash[:testRunStartedId] + test_run_started_id: hash[:testRunStartedId], + test_run_hook_started_id: hash[:testRunHookStartedId] ) end end