diff --git a/CHANGELOG.md b/CHANGELOG.md index dc66ff6d..92c240fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,9 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Changed +- [Ruby] **Breaking change** Messages are now altered to be 1 message class per file ([#225](https://github.com/cucumber/messages/pull/225) [luke-hill](https://github.com/luke-hill)) - [Ruby] Updated minimum Ruby version to 3.0 ([#216](https://github.com/cucumber/messages/pull/216) [luke-hill](https://github.com/luke-hill)) - [Ruby] Use latest CCK conformance for signing off message releases ([#216](https://github.com/cucumber/messages/pull/216) [luke-hill](https://github.com/luke-hill)) -- [Ruby] Tidied up around 80% of all of the rubocop `Layout` offenses (This included 2 minor alterations to the generator code) ([#217](https://github.com/cucumber/messages/pull/217) [luke-hill](https://github.com/luke-hill)) +- [Ruby] Tidied up all remaining rubocop offenses (This included 2 minor alterations to the generator code) ([#217](https://github.com/cucumber/messages/pull/217) [#225](https://github.com/cucumber/messages/pull/225) [luke-hill](https://github.com/luke-hill)) - [Php] Permit both PHPUnit 10 and PHPUnit 11 ([#200](https://github.com/cucumber/messages/pull/200) [ciaranmcnulty](https://github.com/ciaranmcnulty)) ### Fixed diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8eb89af7..5aecee26 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,7 @@ Some guidelines for making schema changes: - Use the most appropriate data type - Follow existing naming conventions (camelCase) - Add new fields last to minimise impact on consuming code -- Probably don't add a new field as `required` - this will make the new code unable to read existing messages +- Don't add a new field as `required` - this will make the new code unable to read existing messages - Ideally add a description to any new fields If you need some advice, drop into the `#committers` channel on the [Cucumber Slack](https://cucumber.io/community#slack) and ask. @@ -20,24 +20,23 @@ The code for various languages is generated from the JSON files. You can clean a make clean-all generate-all ``` -This requires various tooling to be installed on your computer, including Ruby and Node.js. If you're missing some of it, you might find it easier to run a Docker container that has everything: +Or you can alternative clean and generate code for just one language by cd'ing into that languages directory +and then running the following commands ```shell -docker run --volume $PWD:/app --user 1000 -it cucumber/cucumber-build:latest bash +cd ruby # Or another alternative +make clean generate ``` -For Windows (Powershell): - -```shell -docker run --volume ${PWD}:/app --user 1000 -it cucumber/cucumber-build:latest bash -``` - -You can then run the same command as noted previously. +This requires various tooling to be installed on your computer, including Ruby and Node.js. ### New files -If you're adding a new file to the `jsonschema` directory, you'll need to add a reference to it near the top of the `Makefile` at the root in order for it to be included in the code generation. +If you're adding a new file to the `jsonschema` directory, you'll need to add a reference to it near the top of the `Makefile` +at the root in order for it to be included in the code generation. ## Tests -Some of the language-specific directories contain some smoke tests to ensure (de)serialization, validation etc are working right. If you happen to change one of the messages that's constructed by these tests, you may need to update them. If you're not sure, raise a draft PR and see what happens in CI. +Some of the language-specific directories contain some smoke tests to ensure (de)serialization, validation etc +are working right. If you happen to change one of the messages that's constructed by these tests, you may +need to update them. If you're not sure, raise a draft PR and see what happens in CI. diff --git a/README.md b/README.md index 2e0e2896..58f01172 100644 --- a/README.md +++ b/README.md @@ -56,8 +56,8 @@ Cucumber needs to produce results in a machine-readable format so that other too ![messages-stream.svg](messages-stream.svg) -Historically, Cucumber has done this with the `json` and `junit` formatters. -These formats have several shortcomings that are addressed by Cucumber Messages. +Historically, Cucumber did this with the `json` and `junit` formatters. +These formats however, have several shortcomings that are now addressed by using Cucumber Messages. The `json` formatter is now in maintenance mode for these implementations, and Messages is the preferred standard. See [utilities](#utilities) for a list of tools that may help with backward and forward compatibility @@ -78,15 +78,14 @@ of results. ### Lack of a schema -The JSON report does not have a formal schema. This has led to slightly inconsistent implementations +The JSON reporter does not have a formal schema. This has led to slightly inconsistent implementations of the JSON formatter in various Cucumber implementations. Consumers of the JSON format have to anticipate and detect these inconsistencies and try to cope with them. ### Limited information The `junit` XML format can only contain very limited information such as test case name and status. -While there isn't an official schema for JUnit XML, there are a few defacto ones around, and they -are very limited. +While there isn't an official schema for JUnit XML, there are a few defacto ones around which are very limited. The `json` format represents the following information: diff --git a/jsonschema/scripts/templates/ruby.enum.rb.erb b/jsonschema/scripts/templates/ruby.enum.rb.erb index 5f64e1ec..a75fb3c0 100644 --- a/jsonschema/scripts/templates/ruby.enum.rb.erb +++ b/jsonschema/scripts/templates/ruby.enum.rb.erb @@ -1,13 +1,15 @@ +<%- @enums.each do |enum| -%> +<%= underscore(enum[:name]) %>.rb +# frozen_string_literal: true -<% @enums.each do |enum| -%> +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] module Cucumber module Messages class <%= enum[:name] %> - <%- enum[:values].each_with_index do |value, index| -%> + <%- enum[:values].each do |value| -%> <%= enum_constant(value) %> = '<%= value %>' <%- end -%> end end end -<%= "\n" unless enum == @enums.last -%> -<%- end -%> +<% end -%> diff --git a/jsonschema/scripts/templates/ruby.rb.erb b/jsonschema/scripts/templates/ruby.rb.erb index c827d822..169a09e7 100644 --- a/jsonschema/scripts/templates/ruby.rb.erb +++ b/jsonschema/scripts/templates/ruby.rb.erb @@ -1,15 +1,15 @@ -require 'cucumber/messages/message' +<%- @schemas.each do |key, schema| -%> +<%= underscore(class_name(key)) %>.rb +# frozen_string_literal: true # The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] -# - module Cucumber module Messages - <%- @schemas.each do |key, schema| %> ## # Represents the <%= class_name(key) %> message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## <%= "#\n " if schema['description'] %><%= format_description(schema['description']) %> - class <%= class_name(key) %> < ::Cucumber::Messages::Message + class <%= class_name(key) %> < Message <%- schema['properties'].each do |property_name, property| -%> <%- if property['description'] -%> ## @@ -30,7 +30,34 @@ module Cucumber <%- end -%> super() end + + ## + # Returns a new <%= class_name(key) %> from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::<%= class_name(key) %>.from_h(some_hash) # => #:0x... ...> + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + <%- + schema['properties'].each do |property_name, property| + ref = property['$ref'] + items_ref = property.dig('items', '$ref') + -%> + <%- final_key = property_name == schema['properties'].keys.last -%> + <%- comma = final_key ? '' : ',' -%> + <%= "#{underscore(property_name)}: " -%> + <%- if items_ref -%>hash[:<%= property_name -%>]&.map { |item| <%= class_name(items_ref) %>.from_h(item) }<%= comma %> + <%- elsif ref -%><%= class_name(ref) %>.from_h(hash[:<%= property_name %>])<%= comma %> + <%- else -%>hash[:<%= property_name %>]<%= comma %> + <%- end -%> + <%- end -%> + ) + end end - <%- end -%> end end +<% end -%> diff --git a/jsonschema/scripts/templates/ruby_deserializers.rb.erb b/jsonschema/scripts/templates/ruby_deserializers.rb.erb deleted file mode 100644 index 0c1fecac..00000000 --- a/jsonschema/scripts/templates/ruby_deserializers.rb.erb +++ /dev/null @@ -1,40 +0,0 @@ -require 'cucumber/messages.dtos' -require 'json' - -# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] -# - -module Cucumber - module Messages - <%- @schemas.each do |key, schema| -%> - - class <%= class_name(key) %> - ## - # Returns a new <%= class_name(key) %> from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::<%= class_name(key) %>.from_h(some_hash) # => #:0x... ...> - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - <%- - schema['properties'].each do |property_name, property| - ref = property['$ref'] - items_ref = property.dig('items', '$ref') - -%> - <%= "#{underscore(property_name)}: " -%> - <%- if items_ref -%>hash[:<%= property_name -%>]&.map { |item| <%= class_name(items_ref) %>.from_h(item) }, - <%- elsif ref -%><%= class_name(ref) %>.from_h(hash[:<%= property_name %>]), - <%- else -%>hash[:<%= property_name %>], - <%- end -%> - <%- end -%> - ) - end - end - <%- end -%> - end -end diff --git a/ruby/.rubocop.yml b/ruby/.rubocop.yml index f9ba53fe..fdd1dfe8 100644 --- a/ruby/.rubocop.yml +++ b/ruby/.rubocop.yml @@ -1,5 +1,3 @@ -inherit_from: .rubocop_todo.yml - inherit_mode: merge: - Exclude @@ -17,9 +15,16 @@ AllCops: Gemspec/RequireMFA: Enabled: false -# Some long comments in the JSON Schema cause this to be un-enforceable +# Generated messages (including the Envelope) aren't tested by the Metrics department because they have many +# input properties for #initialize and .from_h which are generated 1-per-line. This renders most Metrics redundant +Metrics: + Exclude: + - lib/cucumber/messages/*.rb + +# Long comments in the generated messages from the JSON Schemas cause this to be un-enforceable Layout/LineLength: - Max: 1000 + Exclude: + - lib/cucumber/messages/*.rb Naming/MethodParameterName: AllowedNames: @@ -31,7 +36,8 @@ RSpec/MessageSpies: # Because of the nature of large amounts of Accessors, we disable this cop # This is because many of them will have custom documentation which are auto-generated from the jsonschema Style/AccessorGrouping: - Enabled: false + Exclude: + - lib/cucumber/messages/*.rb Style/Documentation: Enabled: false diff --git a/ruby/.rubocop_todo.yml b/ruby/.rubocop_todo.yml deleted file mode 100644 index 71944c7f..00000000 --- a/ruby/.rubocop_todo.yml +++ /dev/null @@ -1,145 +0,0 @@ -# This configuration was generated by -# `rubocop --auto-gen-config` -# on 2024-05-14 14:31:20 UTC using RuboCop version 1.49.0. -# The point is for the user to remove these configuration records -# one by one as the offenses are removed from the code base. -# Note that changes in the inspected code, or installation of new -# versions of RuboCop, may require this file to be generated again. - -# Initial iteration: 22 files inspected, 816 offenses detected, 678 offenses auto-correctable -# 2nd iteration (April): 22 files inspected, 395 offenses detected, 261 offenses auto-correctable -# 3rd iteration (May): 23 files inspected, 280 offenses detected, 246 offenses auto-correctable - -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -Layout/EmptyLineAfterGuardClause: - Exclude: - - 'lib/cucumber/messages/ndjson_to_message_enumerator.rb' - -# Offense count: 2 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: empty_lines, empty_lines_except_namespace, empty_lines_special, no_empty_lines -Layout/EmptyLinesAroundModuleBody: - Exclude: - - 'lib/cucumber/messages.deserializers.rb' - - 'lib/cucumber/messages.dtos.rb' - -# Offense count: 16 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: AllowInHeredoc. -Layout/TrailingWhitespace: - Exclude: - - 'lib/cucumber/messages.dtos.rb' - -# Offense count: 1 -# This cop supports safe autocorrection (--autocorrect). -Lint/AmbiguousOperatorPrecedence: - Exclude: - - 'lib/cucumber/messages/time_conversion.rb' - -# Offense count: 2 -# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes. -Metrics/AbcSize: - Max: 37 - -# Offense count: 1 -# Configuration parameters: AllowedMethods, AllowedPatterns. -Metrics/CyclomaticComplexity: - Max: 8 - -# Offense count: 6 -# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns. -Metrics/MethodLength: - Max: 20 - -# Offense count: 11 -# Configuration parameters: CountKeywordArgs, MaxOptionalParameters. -Metrics/ParameterLists: - Max: 17 - -# Offense count: 1 -# Configuration parameters: MinNameLength, AllowNamesEndingInNumbers, AllowedNames, ForbiddenNames. -# AllowedNames: as, at, by, cc, db, id, if, in, io, ip, of, on, os, pp, to -Naming/MethodParameterName: - Exclude: - - 'lib/cucumber/messages.dtos.rb' - -# Offense count: 1 -# Configuration parameters: IgnoredMetadata. -RSpec/DescribeClass: - Exclude: - - '**/spec/features/**/*' - - '**/spec/requests/**/*' - - '**/spec/routing/**/*' - - '**/spec/system/**/*' - - '**/spec/views/**/*' - - 'spec/cucumber/messages/ndjson_serialization_spec.rb' - -# Offense count: 3 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: SkipBlocks, EnforcedStyle. -# SupportedStyles: described_class, explicit -RSpec/DescribedClass: - Exclude: - - 'spec/cucumber/messages/message_spec.rb' - -# Offense count: 5 -# Configuration parameters: CountAsOne. -RSpec/ExampleLength: - Max: 7 - -# Offense count: 3 -RSpec/MultipleExpectations: - Max: 2 - -# Offense count: 1 -# Configuration parameters: IgnoreSharedExamples. -RSpec/NamedSubject: - Exclude: - - 'spec/cucumber/messages/version_spec.rb' - -# Offense count: 3 -# Configuration parameters: AllowedGroups. -RSpec/NestedGroups: - Max: 4 - -# Offense count: 117 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: separated, grouped -Style/AccessorGrouping: - Exclude: - - 'lib/cucumber/messages.dtos.rb' - -# Offense count: 6 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: nested, compact -Style/ClassAndModuleChildren: - Exclude: - - 'lib/cucumber/messages.dtos.rb' - -# Offense count: 22 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: always, always_true, never -Style/FrozenStringLiteralComment: - Enabled: false - -# Offense count: 23 -# This cop supports unsafe autocorrection (--autocorrect-all). -# Configuration parameters: EnforcedStyle. -# SupportedStyles: literals, strict -Style/MutableConstant: - Exclude: - - 'lib/cucumber/messages.dtos.rb' - - 'spec/support/enum_message.rb' - -# Offense count: 55 -# This cop supports safe autocorrection (--autocorrect). -# Configuration parameters: EnforcedStyleForMultiline. -# SupportedStylesForMultiline: comma, consistent_comma, no_comma -Style/TrailingCommaInArguments: - Exclude: - - 'lib/cucumber/messages.deserializers.rb' diff --git a/ruby/Makefile b/ruby/Makefile index eb20b5f5..dc86f64d 100644 --- a/ruby/Makefile +++ b/ruby/Makefile @@ -5,7 +5,7 @@ schemas = $(shell find ../jsonschema -name "*.json") help: ## Show this help @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \n\nWhere is one of:\n"} /^[$$()% a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) -generate: require lib/cucumber/messages.dtos.rb lib/cucumber/messages.deserializers.rb ## Generate ruby code based on the schemas found in ../jsonschema and using the scripts in ../jsonschema/scripts for the generation +generate: require .generate-messages ## Generate ruby code based on the schemas found in ../jsonschema and using the scripts in ../jsonschema/scripts for the generation require: ## Check requirements for the code generation (ruby, csplit and tail are required) @ruby --version >/dev/null 2>&1 || (echo "ERROR: ruby is required."; exit 1) @@ -13,12 +13,11 @@ require: ## Check requirements for the code generation (ruby, csplit and tail ar @tail --version >/dev/null 2>&1 || (echo "ERROR: tail is required."; exit 1) clean: ## Remove automatically generated files and related artifacts - rm -f lib/cucumber/messages.dtos.rb - rm -f lib/cucumber/messages.deserializers.rb + find ./lib/cucumber/messages/*.rb ! -name 'message.rb' -type f -exec rm -f {} + -lib/cucumber/messages.dtos.rb: $(schemas) ../jsonschema/scripts/codegen.rb ../jsonschema/scripts/templates/ruby.rb.erb ../jsonschema/scripts/templates/ruby.enum.rb.erb - ruby ../jsonschema/scripts/codegen.rb Ruby ../jsonschema ruby.rb.erb > $@ - ruby ../jsonschema/scripts/codegen.rb Ruby ../jsonschema ruby.enum.rb.erb >> $@ - -lib/cucumber/messages.deserializers.rb: $(schemas) ../jsonschema/scripts/codegen.rb ../jsonschema/scripts/templates/ruby_deserializers.rb.erb - ruby ../jsonschema/scripts/codegen.rb Ruby ../jsonschema ruby_deserializers.rb.erb > $@ +.generate-messages: $(schemas) ../jsonschema/scripts/codegen.rb ../jsonschema/scripts/templates/ruby.rb.erb ../jsonschema/scripts/templates/ruby.enum.rb.erb + ruby ../jsonschema/scripts/codegen.rb Ruby ../jsonschema ruby.rb.erb > Generated.rb.tmp + ruby ../jsonschema/scripts/codegen.rb Ruby ../jsonschema ruby.enum.rb.erb >> Generated.rb.tmp + csplit --quiet --prefix=Generated --suffix-format=%02d.rb.tmp --elide-empty-files Generated.rb.tmp /^[A-Za-z_.]*[.]rb/ {*} + rm Generated.rb.tmp + for file in Generated**; do tail -n +2 $$file > ./lib/cucumber/messages/$$(head -n 1 $$file | tr -d '\r\n'); rm $$file; done diff --git a/ruby/cucumber-messages.gemspec b/ruby/cucumber-messages.gemspec index 31e6378e..93aae7e9 100644 --- a/ruby/cucumber-messages.gemspec +++ b/ruby/cucumber-messages.gemspec @@ -26,10 +26,10 @@ Gem::Specification.new do |s| s.add_development_dependency 'cucumber-compatibility-kit', '~> 15.0' s.add_development_dependency 'rake', '~> 13.1' s.add_development_dependency 'rspec', '~> 3.13' - s.add_development_dependency 'rubocop', '~> 1.49.0' + s.add_development_dependency 'rubocop', '~> 1.50.2' s.add_development_dependency 'rubocop-performance', '~> 1.21.0' s.add_development_dependency 'rubocop-rake', '~> 0.6.0' - s.add_development_dependency 'rubocop-rspec', '~> 2.14.0' + s.add_development_dependency 'rubocop-rspec', '~> 2.25.0' s.files = Dir['README.md', 'VERSION', 'lib/**/*'] s.rdoc_options = ['--charset=UTF-8'] diff --git a/ruby/lib/cucumber/messages.deserializers.rb b/ruby/lib/cucumber/messages.deserializers.rb deleted file mode 100644 index 0f17c42d..00000000 --- a/ruby/lib/cucumber/messages.deserializers.rb +++ /dev/null @@ -1,1153 +0,0 @@ -require 'cucumber/messages.dtos' -require 'json' - -# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] -# - -module Cucumber - module Messages - - class Attachment - ## - # Returns a new Attachment from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Attachment.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - body: hash[:body], - content_encoding: hash[:contentEncoding], - file_name: hash[:fileName], - media_type: hash[:mediaType], - source: Source.from_h(hash[:source]), - test_case_started_id: hash[:testCaseStartedId], - test_step_id: hash[:testStepId], - url: hash[:url], - ) - end - end - - class Duration - ## - # Returns a new Duration from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Duration.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - seconds: hash[:seconds], - nanos: hash[:nanos], - ) - end - end - - class Envelope - ## - # Returns a new Envelope from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Envelope.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - attachment: Attachment.from_h(hash[:attachment]), - gherkin_document: GherkinDocument.from_h(hash[:gherkinDocument]), - hook: Hook.from_h(hash[:hook]), - meta: Meta.from_h(hash[:meta]), - parameter_type: ParameterType.from_h(hash[:parameterType]), - parse_error: ParseError.from_h(hash[:parseError]), - pickle: Pickle.from_h(hash[:pickle]), - source: Source.from_h(hash[:source]), - step_definition: StepDefinition.from_h(hash[:stepDefinition]), - test_case: TestCase.from_h(hash[:testCase]), - test_case_finished: TestCaseFinished.from_h(hash[:testCaseFinished]), - test_case_started: TestCaseStarted.from_h(hash[:testCaseStarted]), - test_run_finished: TestRunFinished.from_h(hash[:testRunFinished]), - test_run_started: TestRunStarted.from_h(hash[:testRunStarted]), - test_step_finished: TestStepFinished.from_h(hash[:testStepFinished]), - test_step_started: TestStepStarted.from_h(hash[:testStepStarted]), - undefined_parameter_type: UndefinedParameterType.from_h(hash[:undefinedParameterType]), - ) - end - end - - class Exception - ## - # Returns a new Exception from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Exception.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - type: hash[:type], - message: hash[:message], - stack_trace: hash[:stackTrace], - ) - end - end - - class GherkinDocument - ## - # Returns a new GherkinDocument from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::GherkinDocument.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - uri: hash[:uri], - feature: Feature.from_h(hash[:feature]), - comments: hash[:comments]&.map { |item| Comment.from_h(item) }, - ) - end - end - - class Background - ## - # Returns a new Background from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Background.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - location: Location.from_h(hash[:location]), - keyword: hash[:keyword], - name: hash[:name], - description: hash[:description], - steps: hash[:steps]&.map { |item| Step.from_h(item) }, - id: hash[:id], - ) - end - end - - class Comment - ## - # Returns a new Comment from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Comment.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - location: Location.from_h(hash[:location]), - text: hash[:text], - ) - end - end - - class DataTable - ## - # Returns a new DataTable from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::DataTable.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - location: Location.from_h(hash[:location]), - rows: hash[:rows]&.map { |item| TableRow.from_h(item) }, - ) - end - end - - class DocString - ## - # Returns a new DocString from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::DocString.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - location: Location.from_h(hash[:location]), - media_type: hash[:mediaType], - content: hash[:content], - delimiter: hash[:delimiter], - ) - end - end - - class Examples - ## - # Returns a new Examples from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Examples.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - location: Location.from_h(hash[:location]), - tags: hash[:tags]&.map { |item| Tag.from_h(item) }, - keyword: hash[:keyword], - name: hash[:name], - description: hash[:description], - table_header: TableRow.from_h(hash[:tableHeader]), - table_body: hash[:tableBody]&.map { |item| TableRow.from_h(item) }, - id: hash[:id], - ) - end - end - - class Feature - ## - # Returns a new Feature from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Feature.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - location: Location.from_h(hash[:location]), - tags: hash[:tags]&.map { |item| Tag.from_h(item) }, - language: hash[:language], - keyword: hash[:keyword], - name: hash[:name], - description: hash[:description], - children: hash[:children]&.map { |item| FeatureChild.from_h(item) }, - ) - end - end - - class FeatureChild - ## - # Returns a new FeatureChild from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::FeatureChild.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - rule: Rule.from_h(hash[:rule]), - background: Background.from_h(hash[:background]), - scenario: Scenario.from_h(hash[:scenario]), - ) - end - end - - class Rule - ## - # Returns a new Rule from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Rule.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - location: Location.from_h(hash[:location]), - tags: hash[:tags]&.map { |item| Tag.from_h(item) }, - keyword: hash[:keyword], - name: hash[:name], - description: hash[:description], - children: hash[:children]&.map { |item| RuleChild.from_h(item) }, - id: hash[:id], - ) - end - end - - class RuleChild - ## - # Returns a new RuleChild from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::RuleChild.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - background: Background.from_h(hash[:background]), - scenario: Scenario.from_h(hash[:scenario]), - ) - end - end - - class Scenario - ## - # Returns a new Scenario from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Scenario.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - location: Location.from_h(hash[:location]), - tags: hash[:tags]&.map { |item| Tag.from_h(item) }, - keyword: hash[:keyword], - name: hash[:name], - description: hash[:description], - steps: hash[:steps]&.map { |item| Step.from_h(item) }, - examples: hash[:examples]&.map { |item| Examples.from_h(item) }, - id: hash[:id], - ) - end - end - - class Step - ## - # Returns a new Step from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Step.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - location: Location.from_h(hash[:location]), - keyword: hash[:keyword], - keyword_type: hash[:keywordType], - text: hash[:text], - doc_string: DocString.from_h(hash[:docString]), - data_table: DataTable.from_h(hash[:dataTable]), - id: hash[:id], - ) - end - end - - class TableCell - ## - # Returns a new TableCell from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::TableCell.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - location: Location.from_h(hash[:location]), - value: hash[:value], - ) - end - end - - class TableRow - ## - # Returns a new TableRow from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::TableRow.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - location: Location.from_h(hash[:location]), - cells: hash[:cells]&.map { |item| TableCell.from_h(item) }, - id: hash[:id], - ) - end - end - - class Tag - ## - # Returns a new Tag from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Tag.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - location: Location.from_h(hash[:location]), - name: hash[:name], - id: hash[:id], - ) - end - end - - class Hook - ## - # Returns a new Hook from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Hook.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - id: hash[:id], - name: hash[:name], - source_reference: SourceReference.from_h(hash[:sourceReference]), - tag_expression: hash[:tagExpression], - ) - end - end - - class Location - ## - # Returns a new Location from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Location.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - line: hash[:line], - column: hash[:column], - ) - end - end - - class Meta - ## - # Returns a new Meta from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Meta.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - protocol_version: hash[:protocolVersion], - implementation: Product.from_h(hash[:implementation]), - runtime: Product.from_h(hash[:runtime]), - os: Product.from_h(hash[:os]), - cpu: Product.from_h(hash[:cpu]), - ci: Ci.from_h(hash[:ci]), - ) - end - end - - class Ci - ## - # Returns a new Ci from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Ci.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - name: hash[:name], - url: hash[:url], - build_number: hash[:buildNumber], - git: Git.from_h(hash[:git]), - ) - end - end - - class Git - ## - # Returns a new Git from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Git.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - remote: hash[:remote], - revision: hash[:revision], - branch: hash[:branch], - tag: hash[:tag], - ) - end - end - - class Product - ## - # Returns a new Product from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Product.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - name: hash[:name], - version: hash[:version], - ) - end - end - - class ParameterType - ## - # Returns a new ParameterType from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::ParameterType.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - name: hash[:name], - regular_expressions: hash[:regularExpressions], - prefer_for_regular_expression_match: hash[:preferForRegularExpressionMatch], - use_for_snippets: hash[:useForSnippets], - id: hash[:id], - source_reference: SourceReference.from_h(hash[:sourceReference]), - ) - end - end - - class ParseError - ## - # Returns a new ParseError from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::ParseError.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - source: SourceReference.from_h(hash[:source]), - message: hash[:message], - ) - end - end - - class Pickle - ## - # Returns a new Pickle from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Pickle.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - id: hash[:id], - uri: hash[:uri], - name: hash[:name], - language: hash[:language], - steps: hash[:steps]&.map { |item| PickleStep.from_h(item) }, - tags: hash[:tags]&.map { |item| PickleTag.from_h(item) }, - ast_node_ids: hash[:astNodeIds], - ) - end - end - - class PickleDocString - ## - # Returns a new PickleDocString from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::PickleDocString.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - media_type: hash[:mediaType], - content: hash[:content], - ) - end - end - - class PickleStep - ## - # Returns a new PickleStep from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::PickleStep.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - argument: PickleStepArgument.from_h(hash[:argument]), - ast_node_ids: hash[:astNodeIds], - id: hash[:id], - type: hash[:type], - text: hash[:text], - ) - end - end - - class PickleStepArgument - ## - # Returns a new PickleStepArgument from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::PickleStepArgument.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - doc_string: PickleDocString.from_h(hash[:docString]), - data_table: PickleTable.from_h(hash[:dataTable]), - ) - end - end - - class PickleTable - ## - # Returns a new PickleTable from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::PickleTable.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - rows: hash[:rows]&.map { |item| PickleTableRow.from_h(item) }, - ) - end - end - - class PickleTableCell - ## - # Returns a new PickleTableCell from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::PickleTableCell.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - value: hash[:value], - ) - end - end - - class PickleTableRow - ## - # Returns a new PickleTableRow from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::PickleTableRow.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - cells: hash[:cells]&.map { |item| PickleTableCell.from_h(item) }, - ) - end - end - - class PickleTag - ## - # Returns a new PickleTag from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::PickleTag.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - name: hash[:name], - ast_node_id: hash[:astNodeId], - ) - end - end - - class Source - ## - # Returns a new Source from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Source.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - uri: hash[:uri], - data: hash[:data], - media_type: hash[:mediaType], - ) - end - end - - class SourceReference - ## - # Returns a new SourceReference from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::SourceReference.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - uri: hash[:uri], - java_method: JavaMethod.from_h(hash[:javaMethod]), - java_stack_trace_element: JavaStackTraceElement.from_h(hash[:javaStackTraceElement]), - location: Location.from_h(hash[:location]), - ) - end - end - - class JavaMethod - ## - # Returns a new JavaMethod from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::JavaMethod.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - class_name: hash[:className], - method_name: hash[:methodName], - method_parameter_types: hash[:methodParameterTypes], - ) - end - end - - class JavaStackTraceElement - ## - # Returns a new JavaStackTraceElement from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::JavaStackTraceElement.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - class_name: hash[:className], - file_name: hash[:fileName], - method_name: hash[:methodName], - ) - end - end - - class StepDefinition - ## - # Returns a new StepDefinition from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::StepDefinition.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - id: hash[:id], - pattern: StepDefinitionPattern.from_h(hash[:pattern]), - source_reference: SourceReference.from_h(hash[:sourceReference]), - ) - end - end - - class StepDefinitionPattern - ## - # Returns a new StepDefinitionPattern from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::StepDefinitionPattern.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - source: hash[:source], - type: hash[:type], - ) - end - end - - class TestCase - ## - # Returns a new TestCase from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::TestCase.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - id: hash[:id], - pickle_id: hash[:pickleId], - test_steps: hash[:testSteps]&.map { |item| TestStep.from_h(item) }, - ) - end - end - - class Group - ## - # Returns a new Group from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Group.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - children: hash[:children]&.map { |item| Group.from_h(item) }, - start: hash[:start], - value: hash[:value], - ) - end - end - - class StepMatchArgument - ## - # Returns a new StepMatchArgument from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::StepMatchArgument.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - group: Group.from_h(hash[:group]), - parameter_type_name: hash[:parameterTypeName], - ) - end - end - - class StepMatchArgumentsList - ## - # Returns a new StepMatchArgumentsList from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::StepMatchArgumentsList.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - step_match_arguments: hash[:stepMatchArguments]&.map { |item| StepMatchArgument.from_h(item) }, - ) - end - end - - class TestStep - ## - # Returns a new TestStep from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::TestStep.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - hook_id: hash[:hookId], - id: hash[:id], - pickle_step_id: hash[:pickleStepId], - step_definition_ids: hash[:stepDefinitionIds], - step_match_arguments_lists: hash[:stepMatchArgumentsLists]&.map { |item| StepMatchArgumentsList.from_h(item) }, - ) - end - end - - class TestCaseFinished - ## - # Returns a new TestCaseFinished from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::TestCaseFinished.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - test_case_started_id: hash[:testCaseStartedId], - timestamp: Timestamp.from_h(hash[:timestamp]), - will_be_retried: hash[:willBeRetried], - ) - end - end - - class TestCaseStarted - ## - # Returns a new TestCaseStarted from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::TestCaseStarted.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - attempt: hash[:attempt], - id: hash[:id], - test_case_id: hash[:testCaseId], - worker_id: hash[:workerId], - timestamp: Timestamp.from_h(hash[:timestamp]), - ) - end - end - - class TestRunFinished - ## - # Returns a new TestRunFinished from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::TestRunFinished.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - message: hash[:message], - success: hash[:success], - timestamp: Timestamp.from_h(hash[:timestamp]), - exception: Exception.from_h(hash[:exception]), - ) - end - end - - class TestRunStarted - ## - # Returns a new TestRunStarted from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::TestRunStarted.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - timestamp: Timestamp.from_h(hash[:timestamp]), - ) - end - end - - class TestStepFinished - ## - # Returns a new TestStepFinished from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::TestStepFinished.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - test_case_started_id: hash[:testCaseStartedId], - test_step_id: hash[:testStepId], - test_step_result: TestStepResult.from_h(hash[:testStepResult]), - timestamp: Timestamp.from_h(hash[:timestamp]), - ) - end - end - - class TestStepResult - ## - # Returns a new TestStepResult from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::TestStepResult.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - duration: Duration.from_h(hash[:duration]), - message: hash[:message], - status: hash[:status], - exception: Exception.from_h(hash[:exception]), - ) - end - end - - class TestStepStarted - ## - # Returns a new TestStepStarted from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::TestStepStarted.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - test_case_started_id: hash[:testCaseStartedId], - test_step_id: hash[:testStepId], - timestamp: Timestamp.from_h(hash[:timestamp]), - ) - end - end - - class Timestamp - ## - # Returns a new Timestamp from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::Timestamp.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - seconds: hash[:seconds], - nanos: hash[:nanos], - ) - end - end - - class UndefinedParameterType - ## - # Returns a new UndefinedParameterType from the given hash. - # If the hash keys are camelCased, they are properly assigned to the - # corresponding snake_cased attributes. - # - # Cucumber::Messages::UndefinedParameterType.from_h(some_hash) # => # - # - - def self.from_h(hash) - return nil if hash.nil? - - new( - expression: hash[:expression], - name: hash[:name], - ) - end - end - end -end diff --git a/ruby/lib/cucumber/messages.dtos.rb b/ruby/lib/cucumber/messages.dtos.rb deleted file mode 100644 index dd099df0..00000000 --- a/ruby/lib/cucumber/messages.dtos.rb +++ /dev/null @@ -1,1861 +0,0 @@ -require 'cucumber/messages/message' - -# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] -# - -module Cucumber - module Messages - - ## - # Represents the Attachment message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # //// Attachments (parse errors, execution errors, screenshots, links...) - # - # * - # An attachment represents any kind of data associated with a line in a - # [Source](#io.cucumber.messages.Source) file. It can be used for: - # - # * Syntax errors during parse time - # * Screenshots captured and attached during execution - # * Logs captured and attached during execution - # - # It is not to be used for runtime errors raised/thrown during execution. This - # is captured in `TestResult`. - ## - class Attachment < ::Cucumber::Messages::Message - ## - # * - # The body of the attachment. If `contentEncoding` is `IDENTITY`, the attachment - # is simply the string. If it's `BASE64`, the string should be Base64 decoded to - # obtain the attachment. - ## - attr_reader :body - - ## - # * - # Whether to interpret `body` "as-is" (IDENTITY) or if it needs to be Base64-decoded (BASE64). - # - # Content encoding is *not* determined by the media type, but rather by the type - # of the object being attached: - # - # - string: IDENTITY - # - byte array: BASE64 - # - stream: BASE64 - ## - attr_reader :content_encoding - - ## - # * - # Suggested file name of the attachment. (Provided by the user as an argument to `attach`) - ## - attr_reader :file_name - - ## - # * - # The media type of the data. This can be any valid - # [IANA Media Type](https://www.iana.org/assignments/media-types/media-types.xhtml) - # as well as Cucumber-specific media types such as `text/x.cucumber.gherkin+plain` - # and `text/x.cucumber.stacktrace+plain` - ## - attr_reader :media_type - - attr_reader :source - - attr_reader :test_case_started_id - - attr_reader :test_step_id - - ## - # * - # A URL where the attachment can be retrieved. This field should not be set by Cucumber. - # It should be set by a program that reads a message stream and does the following for - # each Attachment message: - # - # - Writes the body (after base64 decoding if necessary) to a new file. - # - Sets `body` and `contentEncoding` to `null` - # - Writes out the new attachment message - # - # This will result in a smaller message stream, which can improve performance and - # reduce bandwidth of message consumers. It also makes it easier to process and download attachments - # separately from reports. - ## - attr_reader :url - - def initialize( - body: '', - content_encoding: AttachmentContentEncoding::IDENTITY, - file_name: nil, - media_type: '', - source: nil, - test_case_started_id: nil, - test_step_id: nil, - url: nil - ) - @body = body - @content_encoding = content_encoding - @file_name = file_name - @media_type = media_type - @source = source - @test_case_started_id = test_case_started_id - @test_step_id = test_step_id - @url = url - super() - end - end - - ## - # Represents the Duration message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # The structure is pretty close of the Timestamp one. For clarity, a second type - # of message is used. - ## - class Duration < ::Cucumber::Messages::Message - attr_reader :seconds - - ## - # Non-negative fractions of a second at nanosecond resolution. Negative - # second values with fractions must still have non-negative nanos values - # that count forward in time. Must be from 0 to 999,999,999 - # inclusive. - ## - attr_reader :nanos - - def initialize( - seconds: 0, - nanos: 0 - ) - @seconds = seconds - @nanos = nanos - super() - end - end - - ## - # Represents the Envelope message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # When removing a field, replace it with reserved, rather than deleting the line. - # When adding a field, add it to the end and increment the number by one. - # See https://developers.google.com/protocol-buffers/docs/proto#updating for details - # - # * - # All the messages that are passed between different components/processes are Envelope - # messages. - ## - class Envelope < ::Cucumber::Messages::Message - attr_reader :attachment - - attr_reader :gherkin_document - - attr_reader :hook - - attr_reader :meta - - attr_reader :parameter_type - - attr_reader :parse_error - - attr_reader :pickle - - attr_reader :source - - attr_reader :step_definition - - attr_reader :test_case - - attr_reader :test_case_finished - - attr_reader :test_case_started - - attr_reader :test_run_finished - - attr_reader :test_run_started - - attr_reader :test_step_finished - - attr_reader :test_step_started - - attr_reader :undefined_parameter_type - - def initialize( - attachment: nil, - gherkin_document: nil, - hook: nil, - meta: nil, - parameter_type: nil, - parse_error: nil, - pickle: nil, - source: nil, - step_definition: nil, - test_case: nil, - test_case_finished: nil, - test_case_started: nil, - test_run_finished: nil, - test_run_started: nil, - test_step_finished: nil, - test_step_started: nil, - undefined_parameter_type: nil - ) - @attachment = attachment - @gherkin_document = gherkin_document - @hook = hook - @meta = meta - @parameter_type = parameter_type - @parse_error = parse_error - @pickle = pickle - @source = source - @step_definition = step_definition - @test_case = test_case - @test_case_finished = test_case_finished - @test_case_started = test_case_started - @test_run_finished = test_run_finished - @test_run_started = test_run_started - @test_step_finished = test_step_finished - @test_step_started = test_step_started - @undefined_parameter_type = undefined_parameter_type - super() - end - end - - ## - # Represents the Exception message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # A simplified representation of an exception - ## - class Exception < ::Cucumber::Messages::Message - ## - # The type of the exception that caused this result. E.g. "Error" or "org.opentest4j.AssertionFailedError" - ## - attr_reader :type - - ## - # The message of exception that caused this result. E.g. expected: "a" but was: "b" - ## - attr_reader :message - - ## - # The stringified stack trace of the exception that caused this result - ## - attr_reader :stack_trace - - def initialize( - type: '', - message: nil, - stack_trace: nil - ) - @type = type - @message = message - @stack_trace = stack_trace - super() - end - end - - ## - # Represents the GherkinDocument message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # * - # The [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) of a Gherkin document. - # Cucumber implementations should *not* depend on `GherkinDocument` or any of its - # children for execution - use [Pickle](#io.cucumber.messages.Pickle) instead. - # - # The only consumers of `GherkinDocument` should only be formatters that produce - # "rich" output, resembling the original Gherkin document. - ## - class GherkinDocument < ::Cucumber::Messages::Message - ## - # * - # The [URI](https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) - # of the source, typically a file path relative to the root directory - ## - attr_reader :uri - - attr_reader :feature - - ## - # All the comments in the Gherkin document - ## - attr_reader :comments - - def initialize( - uri: nil, - feature: nil, - comments: [] - ) - @uri = uri - @feature = feature - @comments = comments - super() - end - end - - ## - # Represents the Background message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class Background < ::Cucumber::Messages::Message - ## - # The location of the `Background` keyword - ## - attr_reader :location - - attr_reader :keyword - - attr_reader :name - - attr_reader :description - - attr_reader :steps - - attr_reader :id - - def initialize( - location: Location.new, - keyword: '', - name: '', - description: '', - steps: [], - id: '' - ) - @location = location - @keyword = keyword - @name = name - @description = description - @steps = steps - @id = id - super() - end - end - - ## - # Represents the Comment message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # * - # A comment in a Gherkin document - ## - class Comment < ::Cucumber::Messages::Message - ## - # The location of the comment - ## - attr_reader :location - - ## - # The text of the comment - ## - attr_reader :text - - def initialize( - location: Location.new, - text: '' - ) - @location = location - @text = text - super() - end - end - - ## - # Represents the DataTable message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class DataTable < ::Cucumber::Messages::Message - attr_reader :location - - attr_reader :rows - - def initialize( - location: Location.new, - rows: [] - ) - @location = location - @rows = rows - super() - end - end - - ## - # Represents the DocString message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class DocString < ::Cucumber::Messages::Message - attr_reader :location - - attr_reader :media_type - - attr_reader :content - - attr_reader :delimiter - - def initialize( - location: Location.new, - media_type: nil, - content: '', - delimiter: '' - ) - @location = location - @media_type = media_type - @content = content - @delimiter = delimiter - super() - end - end - - ## - # Represents the Examples message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class Examples < ::Cucumber::Messages::Message - ## - # The location of the `Examples` keyword - ## - attr_reader :location - - attr_reader :tags - - attr_reader :keyword - - attr_reader :name - - attr_reader :description - - attr_reader :table_header - - attr_reader :table_body - - attr_reader :id - - def initialize( - location: Location.new, - tags: [], - keyword: '', - name: '', - description: '', - table_header: nil, - table_body: [], - id: '' - ) - @location = location - @tags = tags - @keyword = keyword - @name = name - @description = description - @table_header = table_header - @table_body = table_body - @id = id - super() - end - end - - ## - # Represents the Feature message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class Feature < ::Cucumber::Messages::Message - ## - # The location of the `Feature` keyword - ## - attr_reader :location - - ## - # All the tags placed above the `Feature` keyword - ## - attr_reader :tags - - ## - # The [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) language code of the Gherkin document - ## - attr_reader :language - - ## - # The text of the `Feature` keyword (in the language specified by `language`) - ## - attr_reader :keyword - - ## - # The name of the feature (the text following the `keyword`) - ## - attr_reader :name - - ## - # The line(s) underneath the line with the `keyword` that are used as description - ## - attr_reader :description - - ## - # Zero or more children - ## - attr_reader :children - - def initialize( - location: Location.new, - tags: [], - language: '', - keyword: '', - name: '', - description: '', - children: [] - ) - @location = location - @tags = tags - @language = language - @keyword = keyword - @name = name - @description = description - @children = children - super() - end - end - - ## - # Represents the FeatureChild message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # * - # A child node of a `Feature` node - ## - class FeatureChild < ::Cucumber::Messages::Message - attr_reader :rule - - attr_reader :background - - attr_reader :scenario - - def initialize( - rule: nil, - background: nil, - scenario: nil - ) - @rule = rule - @background = background - @scenario = scenario - super() - end - end - - ## - # Represents the Rule message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class Rule < ::Cucumber::Messages::Message - ## - # The location of the `Rule` keyword - ## - attr_reader :location - - ## - # All the tags placed above the `Rule` keyword - ## - attr_reader :tags - - attr_reader :keyword - - attr_reader :name - - attr_reader :description - - attr_reader :children - - attr_reader :id - - def initialize( - location: Location.new, - tags: [], - keyword: '', - name: '', - description: '', - children: [], - id: '' - ) - @location = location - @tags = tags - @keyword = keyword - @name = name - @description = description - @children = children - @id = id - super() - end - end - - ## - # Represents the RuleChild message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # * - # A child node of a `Rule` node - ## - class RuleChild < ::Cucumber::Messages::Message - attr_reader :background - - attr_reader :scenario - - def initialize( - background: nil, - scenario: nil - ) - @background = background - @scenario = scenario - super() - end - end - - ## - # Represents the Scenario message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class Scenario < ::Cucumber::Messages::Message - ## - # The location of the `Scenario` keyword - ## - attr_reader :location - - attr_reader :tags - - attr_reader :keyword - - attr_reader :name - - attr_reader :description - - attr_reader :steps - - attr_reader :examples - - attr_reader :id - - def initialize( - location: Location.new, - tags: [], - keyword: '', - name: '', - description: '', - steps: [], - examples: [], - id: '' - ) - @location = location - @tags = tags - @keyword = keyword - @name = name - @description = description - @steps = steps - @examples = examples - @id = id - super() - end - end - - ## - # Represents the Step message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # A step - ## - class Step < ::Cucumber::Messages::Message - ## - # The location of the steps' `keyword` - ## - attr_reader :location - - ## - # The actual keyword as it appeared in the source. - ## - attr_reader :keyword - - ## - # The test phase signalled by the keyword: Context definition (Given), Action performance (When), Outcome assertion (Then). Other keywords signal Continuation (And and But) from a prior keyword. Please note that all translations which a dialect maps to multiple keywords (`*` is in this category for all dialects), map to 'Unknown'. - ## - attr_reader :keyword_type - - attr_reader :text - - attr_reader :doc_string - - attr_reader :data_table - - ## - # Unique ID to be able to reference the Step from PickleStep - ## - attr_reader :id - - def initialize( - location: Location.new, - keyword: '', - keyword_type: nil, - text: '', - doc_string: nil, - data_table: nil, - id: '' - ) - @location = location - @keyword = keyword - @keyword_type = keyword_type - @text = text - @doc_string = doc_string - @data_table = data_table - @id = id - super() - end - end - - ## - # Represents the TableCell message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # A cell in a `TableRow` - ## - class TableCell < ::Cucumber::Messages::Message - ## - # The location of the cell - ## - attr_reader :location - - ## - # The value of the cell - ## - attr_reader :value - - def initialize( - location: Location.new, - value: '' - ) - @location = location - @value = value - super() - end - end - - ## - # Represents the TableRow message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # A row in a table - ## - class TableRow < ::Cucumber::Messages::Message - ## - # The location of the first cell in the row - ## - attr_reader :location - - ## - # Cells in the row - ## - attr_reader :cells - - attr_reader :id - - def initialize( - location: Location.new, - cells: [], - id: '' - ) - @location = location - @cells = cells - @id = id - super() - end - end - - ## - # Represents the Tag message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # * - # A tag - ## - class Tag < ::Cucumber::Messages::Message - ## - # Location of the tag - ## - attr_reader :location - - ## - # The name of the tag (including the leading `@`) - ## - attr_reader :name - - ## - # Unique ID to be able to reference the Tag from PickleTag - ## - attr_reader :id - - def initialize( - location: Location.new, - name: '', - id: '' - ) - @location = location - @name = name - @id = id - super() - end - end - - ## - # Represents the Hook message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - 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 - super() - end - end - - ## - # Represents the Location message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # * - # Points to a line and a column in a text file - ## - class Location < ::Cucumber::Messages::Message - attr_reader :line - - attr_reader :column - - def initialize( - line: 0, - column: nil - ) - @line = line - @column = column - super() - end - end - - ## - # Represents the Meta message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # * - # This message contains meta information about the environment. Consumers can use - # this for various purposes. - ## - class Meta < ::Cucumber::Messages::Message - ## - # * - # The [SEMVER](https://semver.org/) version number of the protocol - ## - attr_reader :protocol_version - - ## - # SpecFlow, Cucumber-JVM, Cucumber.js, Cucumber-Ruby, Behat etc. - ## - attr_reader :implementation - - ## - # Java, Ruby, Node.js etc - ## - attr_reader :runtime - - ## - # Windows, Linux, MacOS etc - ## - attr_reader :os - - ## - # 386, arm, amd64 etc - ## - attr_reader :cpu - - attr_reader :ci - - def initialize( - protocol_version: '', - implementation: Product.new, - runtime: Product.new, - os: Product.new, - cpu: Product.new, - ci: nil - ) - @protocol_version = protocol_version - @implementation = implementation - @runtime = runtime - @os = os - @cpu = cpu - @ci = ci - super() - end - end - - ## - # Represents the Ci message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # CI environment - ## - class Ci < ::Cucumber::Messages::Message - ## - # Name of the CI product, e.g. "Jenkins", "CircleCI" etc. - ## - attr_reader :name - - ## - # Link to the build - ## - attr_reader :url - - ## - # The build number. Some CI servers use non-numeric build numbers, which is why this is a string - ## - attr_reader :build_number - - attr_reader :git - - def initialize( - name: '', - url: nil, - build_number: nil, - git: nil - ) - @name = name - @url = url - @build_number = build_number - @git = git - super() - end - end - - ## - # Represents the Git message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # Information about Git, provided by the Build/CI server as environment - # variables. - ## - class Git < ::Cucumber::Messages::Message - attr_reader :remote - - attr_reader :revision - - attr_reader :branch - - attr_reader :tag - - def initialize( - remote: '', - revision: '', - branch: nil, - tag: nil - ) - @remote = remote - @revision = revision - @branch = branch - @tag = tag - super() - end - end - - ## - # Represents the Product message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # Used to describe various properties of Meta - ## - class Product < ::Cucumber::Messages::Message - ## - # The product name - ## - attr_reader :name - - ## - # The product version - ## - attr_reader :version - - def initialize( - name: '', - version: nil - ) - @name = name - @version = version - super() - end - end - - ## - # Represents the ParameterType message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class ParameterType < ::Cucumber::Messages::Message - ## - # The name is unique, so we don't need an id. - ## - attr_reader :name - - attr_reader :regular_expressions - - attr_reader :prefer_for_regular_expression_match - - attr_reader :use_for_snippets - - attr_reader :id - - attr_reader :source_reference - - def initialize( - name: '', - regular_expressions: [], - prefer_for_regular_expression_match: false, - use_for_snippets: false, - id: '', - source_reference: nil - ) - @name = name - @regular_expressions = regular_expressions - @prefer_for_regular_expression_match = prefer_for_regular_expression_match - @use_for_snippets = use_for_snippets - @id = id - @source_reference = source_reference - super() - end - end - - ## - # Represents the ParseError message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class ParseError < ::Cucumber::Messages::Message - attr_reader :source - - attr_reader :message - - def initialize( - source: SourceReference.new, - message: '' - ) - @source = source - @message = message - super() - end - end - - ## - # Represents the Pickle message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # //// Pickles - # - # * - # A `Pickle` represents a template for a `TestCase`. It is typically derived - # from another format, such as [GherkinDocument](#io.cucumber.messages.GherkinDocument). - # In the future a `Pickle` may be derived from other formats such as Markdown or - # Excel files. - # - # By making `Pickle` the main data structure Cucumber uses for execution, the - # implementation of Cucumber itself becomes simpler, as it doesn't have to deal - # with the complex structure of a [GherkinDocument](#io.cucumber.messages.GherkinDocument). - # - # Each `PickleStep` of a `Pickle` is matched with a `StepDefinition` to create a `TestCase` - ## - class Pickle < ::Cucumber::Messages::Message - ## - # * - # A unique id for the pickle - ## - attr_reader :id - - ## - # The uri of the source file - ## - attr_reader :uri - - ## - # The name of the pickle - ## - attr_reader :name - - ## - # The language of the pickle - ## - attr_reader :language - - ## - # One or more steps - ## - attr_reader :steps - - ## - # * - # One or more tags. If this pickle is constructed from a Gherkin document, - # It includes inherited tags from the `Feature` as well. - ## - attr_reader :tags - - ## - # * - # Points to the AST node locations of the pickle. The last one represents the unique - # id of the pickle. A pickle constructed from `Examples` will have the first - # id originating from the `Scenario` AST node, and the second from the `TableRow` AST node. - ## - attr_reader :ast_node_ids - - def initialize( - id: '', - uri: '', - name: '', - language: '', - steps: [], - tags: [], - ast_node_ids: [] - ) - @id = id - @uri = uri - @name = name - @language = language - @steps = steps - @tags = tags - @ast_node_ids = ast_node_ids - super() - end - end - - ## - # Represents the PickleDocString message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class PickleDocString < ::Cucumber::Messages::Message - attr_reader :media_type - - attr_reader :content - - def initialize( - media_type: nil, - content: '' - ) - @media_type = media_type - @content = content - super() - end - end - - ## - # Represents the PickleStep message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # * - # An executable step - ## - class PickleStep < ::Cucumber::Messages::Message - attr_reader :argument - - ## - # References the IDs of the source of the step. For Gherkin, this can be - # the ID of a Step, and possibly also the ID of a TableRow - ## - attr_reader :ast_node_ids - - ## - # A unique ID for the PickleStep - ## - attr_reader :id - - ## - # The context in which the step was specified: context (Given), action (When) or outcome (Then). - # - # Note that the keywords `But` and `And` inherit their meaning from prior steps and the `*` 'keyword' doesn't have specific meaning (hence Unknown) - ## - attr_reader :type - - attr_reader :text - - def initialize( - argument: nil, - ast_node_ids: [], - id: '', - type: nil, - text: '' - ) - @argument = argument - @ast_node_ids = ast_node_ids - @id = id - @type = type - @text = text - super() - end - end - - ## - # Represents the PickleStepArgument message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # An optional argument - ## - class PickleStepArgument < ::Cucumber::Messages::Message - attr_reader :doc_string - - attr_reader :data_table - - def initialize( - doc_string: nil, - data_table: nil - ) - @doc_string = doc_string - @data_table = data_table - super() - end - end - - ## - # Represents the PickleTable message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class PickleTable < ::Cucumber::Messages::Message - attr_reader :rows - - def initialize( - rows: [] - ) - @rows = rows - super() - end - end - - ## - # Represents the PickleTableCell message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class PickleTableCell < ::Cucumber::Messages::Message - attr_reader :value - - def initialize( - value: '' - ) - @value = value - super() - end - end - - ## - # Represents the PickleTableRow message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class PickleTableRow < ::Cucumber::Messages::Message - attr_reader :cells - - def initialize( - cells: [] - ) - @cells = cells - super() - end - end - - ## - # Represents the PickleTag message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # * - # A tag - ## - class PickleTag < ::Cucumber::Messages::Message - attr_reader :name - - ## - # Points to the AST node this was created from - ## - attr_reader :ast_node_id - - def initialize( - name: '', - ast_node_id: '' - ) - @name = name - @ast_node_id = ast_node_id - super() - end - end - - ## - # Represents the Source message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # //// Source - # - # * - # A source file, typically a Gherkin document or Java/Ruby/JavaScript source code - ## - class Source < ::Cucumber::Messages::Message - ## - # * - # The [URI](https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) - # of the source, typically a file path relative to the root directory - ## - attr_reader :uri - - ## - # The contents of the file - ## - attr_reader :data - - ## - # The media type of the file. Can be used to specify custom types, such as - # text/x.cucumber.gherkin+plain - ## - attr_reader :media_type - - def initialize( - uri: '', - data: '', - media_type: SourceMediaType::TEXT_X_CUCUMBER_GHERKIN_PLAIN - ) - @uri = uri - @data = data - @media_type = media_type - super() - end - end - - ## - # Represents the SourceReference message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # * - # Points to a [Source](#io.cucumber.messages.Source) identified by `uri` and a - # [Location](#io.cucumber.messages.Location) within that file. - ## - class SourceReference < ::Cucumber::Messages::Message - attr_reader :uri - - attr_reader :java_method - - attr_reader :java_stack_trace_element - - attr_reader :location - - def initialize( - uri: nil, - java_method: nil, - java_stack_trace_element: nil, - location: nil - ) - @uri = uri - @java_method = java_method - @java_stack_trace_element = java_stack_trace_element - @location = location - super() - end - end - - ## - # Represents the JavaMethod message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class JavaMethod < ::Cucumber::Messages::Message - attr_reader :class_name - - attr_reader :method_name - - attr_reader :method_parameter_types - - def initialize( - class_name: '', - method_name: '', - method_parameter_types: [] - ) - @class_name = class_name - @method_name = method_name - @method_parameter_types = method_parameter_types - super() - end - end - - ## - # Represents the JavaStackTraceElement message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class JavaStackTraceElement < ::Cucumber::Messages::Message - attr_reader :class_name - - attr_reader :file_name - - attr_reader :method_name - - def initialize( - class_name: '', - file_name: '', - method_name: '' - ) - @class_name = class_name - @file_name = file_name - @method_name = method_name - super() - end - end - - ## - # Represents the StepDefinition message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class StepDefinition < ::Cucumber::Messages::Message - attr_reader :id - - attr_reader :pattern - - attr_reader :source_reference - - def initialize( - id: '', - pattern: StepDefinitionPattern.new, - source_reference: SourceReference.new - ) - @id = id - @pattern = pattern - @source_reference = source_reference - super() - end - end - - ## - # Represents the StepDefinitionPattern message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class StepDefinitionPattern < ::Cucumber::Messages::Message - attr_reader :source - - attr_reader :type - - def initialize( - source: '', - type: StepDefinitionPatternType::CUCUMBER_EXPRESSION - ) - @source = source - @type = type - super() - end - end - - ## - # Represents the TestCase message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # //// TestCases - # - # * - # A `TestCase` contains a sequence of `TestStep`s. - ## - class TestCase < ::Cucumber::Messages::Message - attr_reader :id - - ## - # The ID of the `Pickle` this `TestCase` is derived from. - ## - attr_reader :pickle_id - - attr_reader :test_steps - - def initialize( - id: '', - pickle_id: '', - test_steps: [] - ) - @id = id - @pickle_id = pickle_id - @test_steps = test_steps - super() - end - end - - ## - # Represents the Group message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class Group < ::Cucumber::Messages::Message - attr_reader :children - - attr_reader :start - - attr_reader :value - - def initialize( - children: [], - start: nil, - value: nil - ) - @children = children - @start = start - @value = value - super() - end - end - - ## - # Represents the StepMatchArgument message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # * - # Represents a single argument extracted from a step match and passed to a step definition. - # This is used for the following purposes: - # - Construct an argument to pass to a step definition (possibly through a parameter type transform) - # - Highlight the matched parameter in rich formatters such as the HTML formatter - # - # This message closely matches the `Argument` class in the `cucumber-expressions` library. - ## - class StepMatchArgument < ::Cucumber::Messages::Message - ## - # * - # Represents the outermost capture group of an argument. This message closely matches the - # `Group` class in the `cucumber-expressions` library. - ## - attr_reader :group - - attr_reader :parameter_type_name - - def initialize( - group: Group.new, - parameter_type_name: nil - ) - @group = group - @parameter_type_name = parameter_type_name - super() - end - end - - ## - # Represents the StepMatchArgumentsList message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class StepMatchArgumentsList < ::Cucumber::Messages::Message - attr_reader :step_match_arguments - - def initialize( - step_match_arguments: [] - ) - @step_match_arguments = step_match_arguments - super() - end - end - - ## - # Represents the TestStep message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - # - # * - # A `TestStep` is derived from either a `PickleStep` - # combined with a `StepDefinition`, or from a `Hook`. - ## - class TestStep < ::Cucumber::Messages::Message - ## - # Pointer to the `Hook` (if derived from a Hook) - ## - attr_reader :hook_id - - attr_reader :id - - ## - # Pointer to the `PickleStep` (if derived from a `PickleStep`) - ## - attr_reader :pickle_step_id - - ## - # Pointer to all the matching `StepDefinition`s (if derived from a `PickleStep`) - ## - attr_reader :step_definition_ids - - ## - # A list of list of StepMatchArgument (if derived from a `PickleStep`). - # Each element represents a matching step definition. A size of 0 means `UNDEFINED`, - # and a size of 2+ means `AMBIGUOUS` - ## - attr_reader :step_match_arguments_lists - - def initialize( - hook_id: nil, - id: '', - pickle_step_id: nil, - step_definition_ids: nil, - step_match_arguments_lists: nil - ) - @hook_id = hook_id - @id = id - @pickle_step_id = pickle_step_id - @step_definition_ids = step_definition_ids - @step_match_arguments_lists = step_match_arguments_lists - super() - end - end - - ## - # Represents the TestCaseFinished message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class TestCaseFinished < ::Cucumber::Messages::Message - attr_reader :test_case_started_id - - attr_reader :timestamp - - attr_reader :will_be_retried - - def initialize( - test_case_started_id: '', - timestamp: Timestamp.new, - will_be_retried: false - ) - @test_case_started_id = test_case_started_id - @timestamp = timestamp - @will_be_retried = will_be_retried - super() - end - end - - ## - # Represents the TestCaseStarted message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class TestCaseStarted < ::Cucumber::Messages::Message - ## - # * - # The first attempt should have value 0, and for each retry the value - # should increase by 1. - ## - attr_reader :attempt - - ## - # * - # Because a `TestCase` can be run multiple times (in case of a retry), - # we use this field to group messages relating to the same attempt. - ## - attr_reader :id - - attr_reader :test_case_id - - ## - # An identifier for the worker process running this test case, if test cases are being run in parallel. The identifier will be unique per worker, but no particular format is defined - it could be an index, uuid, machine name etc - and as such should be assumed that it's not human readable. - ## - attr_reader :worker_id - - attr_reader :timestamp - - def initialize( - attempt: 0, - id: '', - test_case_id: '', - worker_id: nil, - timestamp: Timestamp.new - ) - @attempt = attempt - @id = id - @test_case_id = test_case_id - @worker_id = worker_id - @timestamp = timestamp - super() - end - end - - ## - # Represents the TestRunFinished message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class TestRunFinished < ::Cucumber::Messages::Message - ## - # An informative message about the test run. Typically additional information about failure, but not necessarily. - ## - attr_reader :message - - ## - # A test run is successful if all steps are either passed or skipped, all before/after hooks passed and no other exceptions where thrown. - ## - attr_reader :success - - ## - # Timestamp when the TestRun is finished - ## - attr_reader :timestamp - - ## - # Any exception thrown during the test run, if any. Does not include exceptions thrown while executing steps. - ## - attr_reader :exception - - def initialize( - message: nil, - success: false, - timestamp: Timestamp.new, - exception: nil - ) - @message = message - @success = success - @timestamp = timestamp - @exception = exception - super() - end - end - - ## - # Represents the TestRunStarted message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class TestRunStarted < ::Cucumber::Messages::Message - attr_reader :timestamp - - def initialize( - timestamp: Timestamp.new - ) - @timestamp = timestamp - super() - end - end - - ## - # Represents the TestStepFinished message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class TestStepFinished < ::Cucumber::Messages::Message - attr_reader :test_case_started_id - - attr_reader :test_step_id - - attr_reader :test_step_result - - attr_reader :timestamp - - def initialize( - test_case_started_id: '', - test_step_id: '', - test_step_result: TestStepResult.new, - timestamp: Timestamp.new - ) - @test_case_started_id = test_case_started_id - @test_step_id = test_step_id - @test_step_result = test_step_result - @timestamp = timestamp - super() - end - end - - ## - # Represents the TestStepResult message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class TestStepResult < ::Cucumber::Messages::Message - attr_reader :duration - - ## - # An arbitrary bit of information that explains this result. This can be a stack trace of anything else. - ## - attr_reader :message - - attr_reader :status - - ## - # Exception thrown while executing this step, if any. - ## - attr_reader :exception - - def initialize( - duration: Duration.new, - message: nil, - status: TestStepResultStatus::UNKNOWN, - exception: nil - ) - @duration = duration - @message = message - @status = status - @exception = exception - super() - end - end - - ## - # Represents the TestStepStarted message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class TestStepStarted < ::Cucumber::Messages::Message - attr_reader :test_case_started_id - - attr_reader :test_step_id - - attr_reader :timestamp - - def initialize( - test_case_started_id: '', - test_step_id: '', - timestamp: Timestamp.new - ) - @test_case_started_id = test_case_started_id - @test_step_id = test_step_id - @timestamp = timestamp - super() - end - end - - ## - # Represents the Timestamp message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class Timestamp < ::Cucumber::Messages::Message - ## - # Represents seconds of UTC time since Unix epoch - # 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to - # 9999-12-31T23:59:59Z inclusive. - ## - attr_reader :seconds - - ## - # Non-negative fractions of a second at nanosecond resolution. Negative - # second values with fractions must still have non-negative nanos values - # that count forward in time. Must be from 0 to 999,999,999 - # inclusive. - ## - attr_reader :nanos - - def initialize( - seconds: 0, - nanos: 0 - ) - @seconds = seconds - @nanos = nanos - super() - end - end - - ## - # Represents the UndefinedParameterType message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. - ## - class UndefinedParameterType < ::Cucumber::Messages::Message - attr_reader :expression - - attr_reader :name - - def initialize( - expression: '', - name: '' - ) - @expression = expression - @name = name - super() - end - end - end -end - -module Cucumber - module Messages - class AttachmentContentEncoding - IDENTITY = 'IDENTITY' - BASE64 = 'BASE64' - end - end -end - -module Cucumber - module Messages - class PickleStepType - UNKNOWN = 'Unknown' - CONTEXT = 'Context' - ACTION = 'Action' - OUTCOME = 'Outcome' - end - end -end - -module Cucumber - module Messages - class SourceMediaType - TEXT_X_CUCUMBER_GHERKIN_PLAIN = 'text/x.cucumber.gherkin+plain' - TEXT_X_CUCUMBER_GHERKIN_MARKDOWN = 'text/x.cucumber.gherkin+markdown' - end - end -end - -module Cucumber - module Messages - class StepDefinitionPatternType - CUCUMBER_EXPRESSION = 'CUCUMBER_EXPRESSION' - REGULAR_EXPRESSION = 'REGULAR_EXPRESSION' - end - end -end - -module Cucumber - module Messages - class StepKeywordType - UNKNOWN = 'Unknown' - CONTEXT = 'Context' - ACTION = 'Action' - OUTCOME = 'Outcome' - CONJUNCTION = 'Conjunction' - end - end -end - -module Cucumber - module Messages - class TestStepResultStatus - UNKNOWN = 'UNKNOWN' - PASSED = 'PASSED' - SKIPPED = 'SKIPPED' - PENDING = 'PENDING' - UNDEFINED = 'UNDEFINED' - AMBIGUOUS = 'AMBIGUOUS' - FAILED = 'FAILED' - end - end -end diff --git a/ruby/lib/cucumber/messages.rb b/ruby/lib/cucumber/messages.rb index a16aee8b..d7ece81d 100644 --- a/ruby/lib/cucumber/messages.rb +++ b/ruby/lib/cucumber/messages.rb @@ -1,9 +1,11 @@ # frozen_string_literal: true -require 'cucumber/messages/ndjson_to_message_enumerator' -require 'cucumber/messages/time_conversion' -require 'cucumber/messages/id_generator' -require 'cucumber/messages.deserializers' +require 'cucumber/messages/helpers/ndjson_to_message_enumerator' +require 'cucumber/messages/helpers/time_conversion' +require 'cucumber/messages/helpers/id_generator' +require 'cucumber/messages/message' + +Dir["#{File.dirname(__FILE__)}/messages/*.rb"].each { |file| require file } module Cucumber module Messages diff --git a/ruby/lib/cucumber/messages/attachment.rb b/ruby/lib/cucumber/messages/attachment.rb new file mode 100644 index 00000000..fae7a75c --- /dev/null +++ b/ruby/lib/cucumber/messages/attachment.rb @@ -0,0 +1,126 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Attachment message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # //// Attachments (parse errors, execution errors, screenshots, links...) + # + # * + # An attachment represents any kind of data associated with a line in a + # [Source](#io.cucumber.messages.Source) file. It can be used for: + # + # * Syntax errors during parse time + # * Screenshots captured and attached during execution + # * Logs captured and attached during execution + # + # It is not to be used for runtime errors raised/thrown during execution. This + # is captured in `TestResult`. + ## + class Attachment < Message + ## + # * + # The body of the attachment. If `contentEncoding` is `IDENTITY`, the attachment + # is simply the string. If it's `BASE64`, the string should be Base64 decoded to + # obtain the attachment. + ## + attr_reader :body + + ## + # * + # Whether to interpret `body` "as-is" (IDENTITY) or if it needs to be Base64-decoded (BASE64). + # + # Content encoding is *not* determined by the media type, but rather by the type + # of the object being attached: + # + # - string: IDENTITY + # - byte array: BASE64 + # - stream: BASE64 + ## + attr_reader :content_encoding + + ## + # * + # Suggested file name of the attachment. (Provided by the user as an argument to `attach`) + ## + attr_reader :file_name + + ## + # * + # The media type of the data. This can be any valid + # [IANA Media Type](https://www.iana.org/assignments/media-types/media-types.xhtml) + # as well as Cucumber-specific media types such as `text/x.cucumber.gherkin+plain` + # and `text/x.cucumber.stacktrace+plain` + ## + attr_reader :media_type + + attr_reader :source + + attr_reader :test_case_started_id + + attr_reader :test_step_id + + ## + # * + # A URL where the attachment can be retrieved. This field should not be set by Cucumber. + # It should be set by a program that reads a message stream and does the following for + # each Attachment message: + # + # - Writes the body (after base64 decoding if necessary) to a new file. + # - Sets `body` and `contentEncoding` to `null` + # - Writes out the new attachment message + # + # This will result in a smaller message stream, which can improve performance and + # reduce bandwidth of message consumers. It also makes it easier to process and download attachments + # separately from reports. + ## + attr_reader :url + + def initialize( + body: '', + content_encoding: AttachmentContentEncoding::IDENTITY, + file_name: nil, + media_type: '', + source: nil, + test_case_started_id: nil, + test_step_id: nil, + url: nil + ) + @body = body + @content_encoding = content_encoding + @file_name = file_name + @media_type = media_type + @source = source + @test_case_started_id = test_case_started_id + @test_step_id = test_step_id + @url = url + super() + end + + ## + # Returns a new Attachment from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Attachment.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + body: hash[:body], + content_encoding: hash[:contentEncoding], + file_name: hash[:fileName], + media_type: hash[:mediaType], + source: Source.from_h(hash[:source]), + test_case_started_id: hash[:testCaseStartedId], + test_step_id: hash[:testStepId], + url: hash[:url] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/attachment_content_encoding.rb b/ruby/lib/cucumber/messages/attachment_content_encoding.rb new file mode 100644 index 00000000..1a4a1d67 --- /dev/null +++ b/ruby/lib/cucumber/messages/attachment_content_encoding.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + class AttachmentContentEncoding + IDENTITY = 'IDENTITY' + BASE64 = 'BASE64' + end + end +end diff --git a/ruby/lib/cucumber/messages/background.rb b/ruby/lib/cucumber/messages/background.rb new file mode 100644 index 00000000..040e5e8b --- /dev/null +++ b/ruby/lib/cucumber/messages/background.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Background message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class Background < Message + ## + # The location of the `Background` keyword + ## + attr_reader :location + + attr_reader :keyword + + attr_reader :name + + attr_reader :description + + attr_reader :steps + + attr_reader :id + + def initialize( + location: Location.new, + keyword: '', + name: '', + description: '', + steps: [], + id: '' + ) + @location = location + @keyword = keyword + @name = name + @description = description + @steps = steps + @id = id + super() + end + + ## + # Returns a new Background from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Background.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + location: Location.from_h(hash[:location]), + keyword: hash[:keyword], + name: hash[:name], + description: hash[:description], + steps: hash[:steps]&.map { |item| Step.from_h(item) }, + id: hash[:id] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/ci.rb b/ruby/lib/cucumber/messages/ci.rb new file mode 100644 index 00000000..30280c76 --- /dev/null +++ b/ruby/lib/cucumber/messages/ci.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Ci message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # CI environment + ## + class Ci < Message + ## + # Name of the CI product, e.g. "Jenkins", "CircleCI" etc. + ## + attr_reader :name + + ## + # Link to the build + ## + attr_reader :url + + ## + # The build number. Some CI servers use non-numeric build numbers, which is why this is a string + ## + attr_reader :build_number + + attr_reader :git + + def initialize( + name: '', + url: nil, + build_number: nil, + git: nil + ) + @name = name + @url = url + @build_number = build_number + @git = git + super() + end + + ## + # Returns a new Ci from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Ci.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + name: hash[:name], + url: hash[:url], + build_number: hash[:buildNumber], + git: Git.from_h(hash[:git]) + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/comment.rb b/ruby/lib/cucumber/messages/comment.rb new file mode 100644 index 00000000..45e4258d --- /dev/null +++ b/ruby/lib/cucumber/messages/comment.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Comment message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # * + # A comment in a Gherkin document + ## + class Comment < Message + ## + # The location of the comment + ## + attr_reader :location + + ## + # The text of the comment + ## + attr_reader :text + + def initialize( + location: Location.new, + text: '' + ) + @location = location + @text = text + super() + end + + ## + # Returns a new Comment from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Comment.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + location: Location.from_h(hash[:location]), + text: hash[:text] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/data_table.rb b/ruby/lib/cucumber/messages/data_table.rb new file mode 100644 index 00000000..930c0c2b --- /dev/null +++ b/ruby/lib/cucumber/messages/data_table.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the DataTable message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class DataTable < Message + attr_reader :location + + attr_reader :rows + + def initialize( + location: Location.new, + rows: [] + ) + @location = location + @rows = rows + super() + end + + ## + # Returns a new DataTable from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::DataTable.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + location: Location.from_h(hash[:location]), + rows: hash[:rows]&.map { |item| TableRow.from_h(item) } + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/doc_string.rb b/ruby/lib/cucumber/messages/doc_string.rb new file mode 100644 index 00000000..2f4d7059 --- /dev/null +++ b/ruby/lib/cucumber/messages/doc_string.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the DocString message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class DocString < Message + attr_reader :location + + attr_reader :media_type + + attr_reader :content + + attr_reader :delimiter + + def initialize( + location: Location.new, + media_type: nil, + content: '', + delimiter: '' + ) + @location = location + @media_type = media_type + @content = content + @delimiter = delimiter + super() + end + + ## + # Returns a new DocString from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::DocString.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + location: Location.from_h(hash[:location]), + media_type: hash[:mediaType], + content: hash[:content], + delimiter: hash[:delimiter] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/duration.rb b/ruby/lib/cucumber/messages/duration.rb new file mode 100644 index 00000000..705836a3 --- /dev/null +++ b/ruby/lib/cucumber/messages/duration.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Duration message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # The structure is pretty close of the Timestamp one. For clarity, a second type + # of message is used. + ## + class Duration < Message + attr_reader :seconds + + ## + # Non-negative fractions of a second at nanosecond resolution. Negative + # second values with fractions must still have non-negative nanos values + # that count forward in time. Must be from 0 to 999,999,999 + # inclusive. + ## + attr_reader :nanos + + def initialize( + seconds: 0, + nanos: 0 + ) + @seconds = seconds + @nanos = nanos + super() + end + + ## + # Returns a new Duration from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Duration.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + seconds: hash[:seconds], + nanos: hash[:nanos] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/envelope.rb b/ruby/lib/cucumber/messages/envelope.rb new file mode 100644 index 00000000..1cc84706 --- /dev/null +++ b/ruby/lib/cucumber/messages/envelope.rb @@ -0,0 +1,124 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Envelope message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # When removing a field, replace it with reserved, rather than deleting the line. + # When adding a field, add it to the end and increment the number by one. + # See https://developers.google.com/protocol-buffers/docs/proto#updating for details + # + # * + # All the messages that are passed between different components/processes are Envelope + # messages. + ## + class Envelope < Message + attr_reader :attachment + + attr_reader :gherkin_document + + attr_reader :hook + + attr_reader :meta + + attr_reader :parameter_type + + attr_reader :parse_error + + attr_reader :pickle + + attr_reader :source + + attr_reader :step_definition + + attr_reader :test_case + + attr_reader :test_case_finished + + attr_reader :test_case_started + + attr_reader :test_run_finished + + attr_reader :test_run_started + + attr_reader :test_step_finished + + attr_reader :test_step_started + + attr_reader :undefined_parameter_type + + def initialize( + attachment: nil, + gherkin_document: nil, + hook: nil, + meta: nil, + parameter_type: nil, + parse_error: nil, + pickle: nil, + source: nil, + step_definition: nil, + test_case: nil, + test_case_finished: nil, + test_case_started: nil, + test_run_finished: nil, + test_run_started: nil, + test_step_finished: nil, + test_step_started: nil, + undefined_parameter_type: nil + ) + @attachment = attachment + @gherkin_document = gherkin_document + @hook = hook + @meta = meta + @parameter_type = parameter_type + @parse_error = parse_error + @pickle = pickle + @source = source + @step_definition = step_definition + @test_case = test_case + @test_case_finished = test_case_finished + @test_case_started = test_case_started + @test_run_finished = test_run_finished + @test_run_started = test_run_started + @test_step_finished = test_step_finished + @test_step_started = test_step_started + @undefined_parameter_type = undefined_parameter_type + super() + end + + ## + # Returns a new Envelope from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Envelope.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + attachment: Attachment.from_h(hash[:attachment]), + gherkin_document: GherkinDocument.from_h(hash[:gherkinDocument]), + hook: Hook.from_h(hash[:hook]), + meta: Meta.from_h(hash[:meta]), + parameter_type: ParameterType.from_h(hash[:parameterType]), + parse_error: ParseError.from_h(hash[:parseError]), + pickle: Pickle.from_h(hash[:pickle]), + source: Source.from_h(hash[:source]), + step_definition: StepDefinition.from_h(hash[:stepDefinition]), + test_case: TestCase.from_h(hash[:testCase]), + test_case_finished: TestCaseFinished.from_h(hash[:testCaseFinished]), + test_case_started: TestCaseStarted.from_h(hash[:testCaseStarted]), + test_run_finished: TestRunFinished.from_h(hash[:testRunFinished]), + test_run_started: TestRunStarted.from_h(hash[:testRunStarted]), + test_step_finished: TestStepFinished.from_h(hash[:testStepFinished]), + test_step_started: TestStepStarted.from_h(hash[:testStepStarted]), + undefined_parameter_type: UndefinedParameterType.from_h(hash[:undefinedParameterType]) + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/examples.rb b/ruby/lib/cucumber/messages/examples.rb new file mode 100644 index 00000000..c83d4d0d --- /dev/null +++ b/ruby/lib/cucumber/messages/examples.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Examples message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class Examples < Message + ## + # The location of the `Examples` keyword + ## + attr_reader :location + + attr_reader :tags + + attr_reader :keyword + + attr_reader :name + + attr_reader :description + + attr_reader :table_header + + attr_reader :table_body + + attr_reader :id + + def initialize( + location: Location.new, + tags: [], + keyword: '', + name: '', + description: '', + table_header: nil, + table_body: [], + id: '' + ) + @location = location + @tags = tags + @keyword = keyword + @name = name + @description = description + @table_header = table_header + @table_body = table_body + @id = id + super() + end + + ## + # Returns a new Examples from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Examples.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + location: Location.from_h(hash[:location]), + tags: hash[:tags]&.map { |item| Tag.from_h(item) }, + keyword: hash[:keyword], + name: hash[:name], + description: hash[:description], + table_header: TableRow.from_h(hash[:tableHeader]), + table_body: hash[:tableBody]&.map { |item| TableRow.from_h(item) }, + id: hash[:id] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/exception.rb b/ruby/lib/cucumber/messages/exception.rb new file mode 100644 index 00000000..f9292b1c --- /dev/null +++ b/ruby/lib/cucumber/messages/exception.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Exception message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # A simplified representation of an exception + ## + class Exception < Message + ## + # The type of the exception that caused this result. E.g. "Error" or "org.opentest4j.AssertionFailedError" + ## + attr_reader :type + + ## + # The message of exception that caused this result. E.g. expected: "a" but was: "b" + ## + attr_reader :message + + ## + # The stringified stack trace of the exception that caused this result + ## + attr_reader :stack_trace + + def initialize( + type: '', + message: nil, + stack_trace: nil + ) + @type = type + @message = message + @stack_trace = stack_trace + super() + end + + ## + # Returns a new Exception from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Exception.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + type: hash[:type], + message: hash[:message], + stack_trace: hash[:stackTrace] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/feature.rb b/ruby/lib/cucumber/messages/feature.rb new file mode 100644 index 00000000..457d241e --- /dev/null +++ b/ruby/lib/cucumber/messages/feature.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Feature message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class Feature < Message + ## + # The location of the `Feature` keyword + ## + attr_reader :location + + ## + # All the tags placed above the `Feature` keyword + ## + attr_reader :tags + + ## + # The [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) language code of the Gherkin document + ## + attr_reader :language + + ## + # The text of the `Feature` keyword (in the language specified by `language`) + ## + attr_reader :keyword + + ## + # The name of the feature (the text following the `keyword`) + ## + attr_reader :name + + ## + # The line(s) underneath the line with the `keyword` that are used as description + ## + attr_reader :description + + ## + # Zero or more children + ## + attr_reader :children + + def initialize( + location: Location.new, + tags: [], + language: '', + keyword: '', + name: '', + description: '', + children: [] + ) + @location = location + @tags = tags + @language = language + @keyword = keyword + @name = name + @description = description + @children = children + super() + end + + ## + # Returns a new Feature from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Feature.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + location: Location.from_h(hash[:location]), + tags: hash[:tags]&.map { |item| Tag.from_h(item) }, + language: hash[:language], + keyword: hash[:keyword], + name: hash[:name], + description: hash[:description], + children: hash[:children]&.map { |item| FeatureChild.from_h(item) } + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/feature_child.rb b/ruby/lib/cucumber/messages/feature_child.rb new file mode 100644 index 00000000..9e9652d8 --- /dev/null +++ b/ruby/lib/cucumber/messages/feature_child.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the FeatureChild message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # * + # A child node of a `Feature` node + ## + class FeatureChild < Message + attr_reader :rule + + attr_reader :background + + attr_reader :scenario + + def initialize( + rule: nil, + background: nil, + scenario: nil + ) + @rule = rule + @background = background + @scenario = scenario + super() + end + + ## + # Returns a new FeatureChild from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::FeatureChild.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + rule: Rule.from_h(hash[:rule]), + background: Background.from_h(hash[:background]), + scenario: Scenario.from_h(hash[:scenario]) + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/gherkin_document.rb b/ruby/lib/cucumber/messages/gherkin_document.rb new file mode 100644 index 00000000..3da7988f --- /dev/null +++ b/ruby/lib/cucumber/messages/gherkin_document.rb @@ -0,0 +1,62 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the GherkinDocument message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # * + # The [AST](https://en.wikipedia.org/wiki/Abstract_syntax_tree) of a Gherkin document. + # Cucumber implementations should *not* depend on `GherkinDocument` or any of its + # children for execution - use [Pickle](#io.cucumber.messages.Pickle) instead. + # + # The only consumers of `GherkinDocument` should only be formatters that produce + # "rich" output, resembling the original Gherkin document. + ## + class GherkinDocument < Message + ## + # * + # The [URI](https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) + # of the source, typically a file path relative to the root directory + ## + attr_reader :uri + + attr_reader :feature + + ## + # All the comments in the Gherkin document + ## + attr_reader :comments + + def initialize( + uri: nil, + feature: nil, + comments: [] + ) + @uri = uri + @feature = feature + @comments = comments + super() + end + + ## + # Returns a new GherkinDocument from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::GherkinDocument.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + uri: hash[:uri], + feature: Feature.from_h(hash[:feature]), + comments: hash[:comments]&.map { |item| Comment.from_h(item) } + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/git.rb b/ruby/lib/cucumber/messages/git.rb new file mode 100644 index 00000000..04fb24ec --- /dev/null +++ b/ruby/lib/cucumber/messages/git.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Git message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # Information about Git, provided by the Build/CI server as environment + # variables. + ## + class Git < Message + attr_reader :remote + + attr_reader :revision + + attr_reader :branch + + attr_reader :tag + + def initialize( + remote: '', + revision: '', + branch: nil, + tag: nil + ) + @remote = remote + @revision = revision + @branch = branch + @tag = tag + super() + end + + ## + # Returns a new Git from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Git.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + remote: hash[:remote], + revision: hash[:revision], + branch: hash[:branch], + tag: hash[:tag] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/group.rb b/ruby/lib/cucumber/messages/group.rb new file mode 100644 index 00000000..e5ce3fe2 --- /dev/null +++ b/ruby/lib/cucumber/messages/group.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Group message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class Group < Message + attr_reader :children + + attr_reader :start + + attr_reader :value + + def initialize( + children: [], + start: nil, + value: nil + ) + @children = children + @start = start + @value = value + super() + end + + ## + # Returns a new Group from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Group.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + children: hash[:children]&.map { |item| Group.from_h(item) }, + start: hash[:start], + value: hash[:value] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/id_generator.rb b/ruby/lib/cucumber/messages/helpers/id_generator.rb similarity index 100% rename from ruby/lib/cucumber/messages/id_generator.rb rename to ruby/lib/cucumber/messages/helpers/id_generator.rb diff --git a/ruby/lib/cucumber/messages/helpers/id_generator/incrementing.rb b/ruby/lib/cucumber/messages/helpers/id_generator/incrementing.rb new file mode 100644 index 00000000..70346822 --- /dev/null +++ b/ruby/lib/cucumber/messages/helpers/id_generator/incrementing.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Cucumber + module Messages + module Helpers + module IdGenerator + class Incrementing + def initialize + @index = -1 + end + + def new_id + @index += 1 + @index.to_s + end + end + end + end + end +end diff --git a/ruby/lib/cucumber/messages/id_generator/uuid.rb b/ruby/lib/cucumber/messages/helpers/id_generator/uuid.rb similarity index 50% rename from ruby/lib/cucumber/messages/id_generator/uuid.rb rename to ruby/lib/cucumber/messages/helpers/id_generator/uuid.rb index 5797b7bb..92fc5e64 100644 --- a/ruby/lib/cucumber/messages/id_generator/uuid.rb +++ b/ruby/lib/cucumber/messages/helpers/id_generator/uuid.rb @@ -4,10 +4,12 @@ module Cucumber module Messages - module IdGenerator - class UUID - def new_id - SecureRandom.uuid + module Helpers + module IdGenerator + class UUID + def new_id + SecureRandom.uuid + end end end end diff --git a/ruby/lib/cucumber/messages/helpers/ndjson_to_message_enumerator.rb b/ruby/lib/cucumber/messages/helpers/ndjson_to_message_enumerator.rb new file mode 100644 index 00000000..b46ff505 --- /dev/null +++ b/ruby/lib/cucumber/messages/helpers/ndjson_to_message_enumerator.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +require 'cucumber/messages' + +module Cucumber + module Messages + module Helpers + class NdjsonToMessageEnumerator < Enumerator + def initialize(io) + super() do |yielder| + io.each_line do |line| + next if line.strip.empty? + + message = extract_message(line) + yielder.yield(message) + end + end + end + + private + + def extract_message(json_line) + Envelope.from_json(json_line) + rescue StandardError + raise "Not JSON: #{json_line.strip}" + end + end + end + end +end diff --git a/ruby/lib/cucumber/messages/helpers/time_conversion.rb b/ruby/lib/cucumber/messages/helpers/time_conversion.rb new file mode 100644 index 00000000..ddc0ec4b --- /dev/null +++ b/ruby/lib/cucumber/messages/helpers/time_conversion.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module Cucumber + module Messages + module Helpers + module TimeConversion + NANOSECONDS_PER_SECOND = 1_000_000_000 + + def time_to_timestamp(time) + { 'seconds' => time.to_i, 'nanos' => time.nsec } + end + + def timestamp_to_time(timestamp) + Time.at(timestamp['seconds'] + (timestamp['nanos'].to_f / NANOSECONDS_PER_SECOND)) + end + + def seconds_to_duration(seconds_float) + seconds, second_modulus = seconds_float.divmod(1) + nanos = second_modulus * NANOSECONDS_PER_SECOND + { 'seconds' => seconds, 'nanos' => nanos.to_i } + end + + def duration_to_seconds(duration) + seconds_part = duration['seconds'] + nanos_part = duration['nanos'].to_f / NANOSECONDS_PER_SECOND + seconds_part + nanos_part + end + end + end + end +end diff --git a/ruby/lib/cucumber/messages/hook.rb b/ruby/lib/cucumber/messages/hook.rb new file mode 100644 index 00000000..20cff1b3 --- /dev/null +++ b/ruby/lib/cucumber/messages/hook.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Hook message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class Hook < 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 + super() + end + + ## + # Returns a new Hook from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Hook.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + id: hash[:id], + name: hash[:name], + source_reference: SourceReference.from_h(hash[:sourceReference]), + tag_expression: hash[:tagExpression] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/id_generator/incrementing.rb b/ruby/lib/cucumber/messages/id_generator/incrementing.rb deleted file mode 100644 index 208d59b0..00000000 --- a/ruby/lib/cucumber/messages/id_generator/incrementing.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true - -module Cucumber - module Messages - module IdGenerator - class Incrementing - def initialize - @index = -1 - end - - def new_id - @index += 1 - @index.to_s - end - end - end - end -end diff --git a/ruby/lib/cucumber/messages/java_method.rb b/ruby/lib/cucumber/messages/java_method.rb new file mode 100644 index 00000000..f639357c --- /dev/null +++ b/ruby/lib/cucumber/messages/java_method.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the JavaMethod message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class JavaMethod < Message + attr_reader :class_name + + attr_reader :method_name + + attr_reader :method_parameter_types + + def initialize( + class_name: '', + method_name: '', + method_parameter_types: [] + ) + @class_name = class_name + @method_name = method_name + @method_parameter_types = method_parameter_types + super() + end + + ## + # Returns a new JavaMethod from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::JavaMethod.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + class_name: hash[:className], + method_name: hash[:methodName], + method_parameter_types: hash[:methodParameterTypes] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/java_stack_trace_element.rb b/ruby/lib/cucumber/messages/java_stack_trace_element.rb new file mode 100644 index 00000000..c9777934 --- /dev/null +++ b/ruby/lib/cucumber/messages/java_stack_trace_element.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the JavaStackTraceElement message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class JavaStackTraceElement < Message + attr_reader :class_name + + attr_reader :file_name + + attr_reader :method_name + + def initialize( + class_name: '', + file_name: '', + method_name: '' + ) + @class_name = class_name + @file_name = file_name + @method_name = method_name + super() + end + + ## + # Returns a new JavaStackTraceElement from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::JavaStackTraceElement.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + class_name: hash[:className], + file_name: hash[:fileName], + method_name: hash[:methodName] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/location.rb b/ruby/lib/cucumber/messages/location.rb new file mode 100644 index 00000000..52691130 --- /dev/null +++ b/ruby/lib/cucumber/messages/location.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Location message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # * + # Points to a line and a column in a text file + ## + class Location < Message + attr_reader :line + + attr_reader :column + + def initialize( + line: 0, + column: nil + ) + @line = line + @column = column + super() + end + + ## + # Returns a new Location from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Location.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + line: hash[:line], + column: hash[:column] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/message.rb b/ruby/lib/cucumber/messages/message.rb index cdda96aa..d18b735d 100644 --- a/ruby/lib/cucumber/messages/message.rb +++ b/ruby/lib/cucumber/messages/message.rb @@ -14,16 +14,20 @@ def self.camelize(term) # Returns a new Message - or messages into an array - deserialized from the given json document. # CamelCased keys are properly converted to snake_cased attributes in the process # - # Cucumber::Messages::Duration.from_json('{"seconds":1,"nanos":42}') # => # - # Cucumber::Messages::PickleTag.from_json('{"name":"foo","astNodeId":"abc-def"}') # => # + # Cucumber::Messages::Duration.from_json('{"seconds":1,"nanos":42}') + # # => # + # Cucumber::Messages::PickleTag.from_json('{"name":"foo","astNodeId":"abc-def"}') + # # => # # # It is recursive so embedded messages are also processed. # # json_string = { location: { line: 2 }, text: "comment" }.to_json - # Cucumber::Messages::Comment.from_json(json_string) # => #, @text="comment"> + # Cucumber::Messages::Comment.from_json(json_string) + # # => #, @text="comment"> # # json_string = { uri: 'file:///...', comments: [{text: 'text comment'}, {text: 'another comment'}]}.to_json - # Cucumber::Messages::GherkinDocument.from_json(json_string) # => #]> + # Cucumber::Messages::GherkinDocument.from_json(json_string) + # # => # ## def self.from_json(json_string) from_h(JSON.parse(json_string, { symbolize_names: true })) @@ -34,14 +38,18 @@ def self.from_json(json_string) # If +camelize:+ keyword parameter is set to true, then keys will be camelized # If +reject_nil_values:+ keyword parameter is set to true, resulting hash won't include nil values # - # Cucumber::Messages::Duration.new(seconds: 1, nanos: 42).to_h # => { seconds: 1, nanos: 42 } - # Cucumber::Messages::PickleTag.new(name: 'foo', ast_node_id: 'abc-def').to_h(camelize: true) # => { name: 'foo', astNodeId: 'abc-def' } - # Cucumber::Messages::PickleTag.new(name: 'foo', ast_node_id: nil).to_h(reject_nil_values: true) # => { name: 'foo' } + # Cucumber::Messages::Duration.new(seconds: 1, nanos: 42).to_h + # # => { seconds: 1, nanos: 42 } + # Cucumber::Messages::PickleTag.new(name: 'foo', ast_node_id: 'abc-def').to_h(camelize: true) + # # => { name: 'foo', astNodeId: 'abc-def' } + # Cucumber::Messages::PickleTag.new(name: 'foo', ast_node_id: nil).to_h(reject_nil_values: true) + # # => { name: 'foo' } # # It is recursive so embedded messages are also processed # # location = Cucumber::Messages::Location.new(line: 2) - # Cucumber::Messages::Comment.new(location: location, text: 'comment').to_h # => { location: { line: 2, :column: nil }, text: "comment" } + # Cucumber::Messages::Comment.new(location: location, text: 'comment').to_h + # # => { location: { line: 2, :column: nil }, text: "comment" } ## def to_h(camelize: false, reject_nil_values: false) resulting_hash = instance_variables.to_h do |variable_name| @@ -58,14 +66,18 @@ def to_h(camelize: false, reject_nil_values: false) # Generates a JSON document from the message. # Keys are camelized during the process. Null values are not part of the json document. # - # Cucumber::Messages::Duration.new(seconds: 1, nanos: 42).to_json # => '{"seconds":1,"nanos":42}' - # Cucumber::Messages::PickleTag.new(name: 'foo', ast_node_id: 'abc-def').to_json # => '{"name":"foo","astNodeId":"abc-def"}' - # Cucumber::Messages::PickleTag.new(name: 'foo', ast_node_id: nil).to_json # => '{"name":"foo"}' + # Cucumber::Messages::Duration.new(seconds: 1, nanos: 42).to_json + # # => '{"seconds":1,"nanos":42}' + # Cucumber::Messages::PickleTag.new(name: 'foo', ast_node_id: 'abc-def').to_json + # # => '{"name":"foo","astNodeId":"abc-def"}' + # Cucumber::Messages::PickleTag.new(name: 'foo', ast_node_id: nil).to_json + # # => '{"name":"foo"}' # # As with #to_h, the method is recursive # # location = Cucumber::Messages::Location.new(line: 2) - # Cucumber::Messages::Comment.new(location: location, text: 'comment').to_json # => '{"location":{"line":2,"column":null},"text":"comment"}' + # Cucumber::Messages::Comment.new(location: location, text: 'comment').to_json + # # => '{"location":{"line":2,"column":null},"text":"comment"}' ## def to_json(*_args) to_h(camelize: true, reject_nil_values: true).to_json @@ -74,10 +86,13 @@ def to_json(*_args) private def prepare_value(value, camelize:, reject_nil_values:) - return value.to_h(camelize: camelize, reject_nil_values: reject_nil_values) if value.is_a?(Cucumber::Messages::Message) - return value.map { |element| prepare_value(element, camelize: camelize, reject_nil_values: reject_nil_values) } if value.is_a?(Array) - - value + if value.is_a?(Cucumber::Messages::Message) + value.to_h(camelize: camelize, reject_nil_values: reject_nil_values) + elsif value.is_a?(Array) + value.map { |element| prepare_value(element, camelize: camelize, reject_nil_values: reject_nil_values) } + else + value + end end end end diff --git a/ruby/lib/cucumber/messages/meta.rb b/ruby/lib/cucumber/messages/meta.rb new file mode 100644 index 00000000..16957e00 --- /dev/null +++ b/ruby/lib/cucumber/messages/meta.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Meta message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # * + # This message contains meta information about the environment. Consumers can use + # this for various purposes. + ## + class Meta < Message + ## + # * + # The [SEMVER](https://semver.org/) version number of the protocol + ## + attr_reader :protocol_version + + ## + # SpecFlow, Cucumber-JVM, Cucumber.js, Cucumber-Ruby, Behat etc. + ## + attr_reader :implementation + + ## + # Java, Ruby, Node.js etc + ## + attr_reader :runtime + + ## + # Windows, Linux, MacOS etc + ## + attr_reader :os + + ## + # 386, arm, amd64 etc + ## + attr_reader :cpu + + attr_reader :ci + + def initialize( + protocol_version: '', + implementation: Product.new, + runtime: Product.new, + os: Product.new, + cpu: Product.new, + ci: nil + ) + @protocol_version = protocol_version + @implementation = implementation + @runtime = runtime + @os = os + @cpu = cpu + @ci = ci + super() + end + + ## + # Returns a new Meta from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Meta.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + protocol_version: hash[:protocolVersion], + implementation: Product.from_h(hash[:implementation]), + runtime: Product.from_h(hash[:runtime]), + os: Product.from_h(hash[:os]), + cpu: Product.from_h(hash[:cpu]), + ci: Ci.from_h(hash[:ci]) + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/ndjson_to_message_enumerator.rb b/ruby/lib/cucumber/messages/ndjson_to_message_enumerator.rb deleted file mode 100644 index c5a6bc06..00000000 --- a/ruby/lib/cucumber/messages/ndjson_to_message_enumerator.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -require 'cucumber/messages.deserializers' - -module Cucumber - module Messages - class NdjsonToMessageEnumerator < Enumerator - def initialize(io) - super() do |yielder| - io.each_line do |line| - next if line.strip.empty? - begin - m = Envelope.from_json(line) - rescue StandardError - raise "Not JSON: #{line.strip}" - end - yielder.yield(m) - end - end - end - end - end -end diff --git a/ruby/lib/cucumber/messages/parameter_type.rb b/ruby/lib/cucumber/messages/parameter_type.rb new file mode 100644 index 00000000..59390f44 --- /dev/null +++ b/ruby/lib/cucumber/messages/parameter_type.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the ParameterType message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class ParameterType < Message + ## + # The name is unique, so we don't need an id. + ## + attr_reader :name + + attr_reader :regular_expressions + + attr_reader :prefer_for_regular_expression_match + + attr_reader :use_for_snippets + + attr_reader :id + + attr_reader :source_reference + + def initialize( + name: '', + regular_expressions: [], + prefer_for_regular_expression_match: false, + use_for_snippets: false, + id: '', + source_reference: nil + ) + @name = name + @regular_expressions = regular_expressions + @prefer_for_regular_expression_match = prefer_for_regular_expression_match + @use_for_snippets = use_for_snippets + @id = id + @source_reference = source_reference + super() + end + + ## + # Returns a new ParameterType from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::ParameterType.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + name: hash[:name], + regular_expressions: hash[:regularExpressions], + prefer_for_regular_expression_match: hash[:preferForRegularExpressionMatch], + use_for_snippets: hash[:useForSnippets], + id: hash[:id], + source_reference: SourceReference.from_h(hash[:sourceReference]) + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/parse_error.rb b/ruby/lib/cucumber/messages/parse_error.rb new file mode 100644 index 00000000..6796720f --- /dev/null +++ b/ruby/lib/cucumber/messages/parse_error.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the ParseError message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class ParseError < Message + attr_reader :source + + attr_reader :message + + def initialize( + source: SourceReference.new, + message: '' + ) + @source = source + @message = message + super() + end + + ## + # Returns a new ParseError from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::ParseError.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + source: SourceReference.from_h(hash[:source]), + message: hash[:message] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/pickle.rb b/ruby/lib/cucumber/messages/pickle.rb new file mode 100644 index 00000000..25362bf0 --- /dev/null +++ b/ruby/lib/cucumber/messages/pickle.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Pickle message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # //// Pickles + # + # * + # A `Pickle` represents a template for a `TestCase`. It is typically derived + # from another format, such as [GherkinDocument](#io.cucumber.messages.GherkinDocument). + # In the future a `Pickle` may be derived from other formats such as Markdown or + # Excel files. + # + # By making `Pickle` the main data structure Cucumber uses for execution, the + # implementation of Cucumber itself becomes simpler, as it doesn't have to deal + # with the complex structure of a [GherkinDocument](#io.cucumber.messages.GherkinDocument). + # + # Each `PickleStep` of a `Pickle` is matched with a `StepDefinition` to create a `TestCase` + ## + class Pickle < Message + ## + # * + # A unique id for the pickle + ## + attr_reader :id + + ## + # The uri of the source file + ## + attr_reader :uri + + ## + # The name of the pickle + ## + attr_reader :name + + ## + # The language of the pickle + ## + attr_reader :language + + ## + # One or more steps + ## + attr_reader :steps + + ## + # * + # One or more tags. If this pickle is constructed from a Gherkin document, + # It includes inherited tags from the `Feature` as well. + ## + attr_reader :tags + + ## + # * + # Points to the AST node locations of the pickle. The last one represents the unique + # id of the pickle. A pickle constructed from `Examples` will have the first + # id originating from the `Scenario` AST node, and the second from the `TableRow` AST node. + ## + attr_reader :ast_node_ids + + def initialize( + id: '', + uri: '', + name: '', + language: '', + steps: [], + tags: [], + ast_node_ids: [] + ) + @id = id + @uri = uri + @name = name + @language = language + @steps = steps + @tags = tags + @ast_node_ids = ast_node_ids + super() + end + + ## + # Returns a new Pickle from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Pickle.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + id: hash[:id], + uri: hash[:uri], + name: hash[:name], + language: hash[:language], + steps: hash[:steps]&.map { |item| PickleStep.from_h(item) }, + tags: hash[:tags]&.map { |item| PickleTag.from_h(item) }, + ast_node_ids: hash[:astNodeIds] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/pickle_doc_string.rb b/ruby/lib/cucumber/messages/pickle_doc_string.rb new file mode 100644 index 00000000..2bb38c9d --- /dev/null +++ b/ruby/lib/cucumber/messages/pickle_doc_string.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the PickleDocString message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class PickleDocString < Message + attr_reader :media_type + + attr_reader :content + + def initialize( + media_type: nil, + content: '' + ) + @media_type = media_type + @content = content + super() + end + + ## + # Returns a new PickleDocString from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::PickleDocString.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + media_type: hash[:mediaType], + content: hash[:content] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/pickle_step.rb b/ruby/lib/cucumber/messages/pickle_step.rb new file mode 100644 index 00000000..027f56e2 --- /dev/null +++ b/ruby/lib/cucumber/messages/pickle_step.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the PickleStep message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # * + # An executable step + ## + class PickleStep < Message + attr_reader :argument + + ## + # References the IDs of the source of the step. For Gherkin, this can be + # the ID of a Step, and possibly also the ID of a TableRow + ## + attr_reader :ast_node_ids + + ## + # A unique ID for the PickleStep + ## + attr_reader :id + + ## + # The context in which the step was specified: context (Given), action (When) or outcome (Then). + # + # Note that the keywords `But` and `And` inherit their meaning from prior steps and the `*` 'keyword' doesn't have specific meaning (hence Unknown) + ## + attr_reader :type + + attr_reader :text + + def initialize( + argument: nil, + ast_node_ids: [], + id: '', + type: nil, + text: '' + ) + @argument = argument + @ast_node_ids = ast_node_ids + @id = id + @type = type + @text = text + super() + end + + ## + # Returns a new PickleStep from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::PickleStep.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + argument: PickleStepArgument.from_h(hash[:argument]), + ast_node_ids: hash[:astNodeIds], + id: hash[:id], + type: hash[:type], + text: hash[:text] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/pickle_step_argument.rb b/ruby/lib/cucumber/messages/pickle_step_argument.rb new file mode 100644 index 00000000..e42b7d40 --- /dev/null +++ b/ruby/lib/cucumber/messages/pickle_step_argument.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the PickleStepArgument message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # An optional argument + ## + class PickleStepArgument < Message + attr_reader :doc_string + + attr_reader :data_table + + def initialize( + doc_string: nil, + data_table: nil + ) + @doc_string = doc_string + @data_table = data_table + super() + end + + ## + # Returns a new PickleStepArgument from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::PickleStepArgument.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + doc_string: PickleDocString.from_h(hash[:docString]), + data_table: PickleTable.from_h(hash[:dataTable]) + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/pickle_step_type.rb b/ruby/lib/cucumber/messages/pickle_step_type.rb new file mode 100644 index 00000000..2f784c7e --- /dev/null +++ b/ruby/lib/cucumber/messages/pickle_step_type.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + class PickleStepType + UNKNOWN = 'Unknown' + CONTEXT = 'Context' + ACTION = 'Action' + OUTCOME = 'Outcome' + end + end +end diff --git a/ruby/lib/cucumber/messages/pickle_table.rb b/ruby/lib/cucumber/messages/pickle_table.rb new file mode 100644 index 00000000..bcb190af --- /dev/null +++ b/ruby/lib/cucumber/messages/pickle_table.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the PickleTable message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class PickleTable < Message + attr_reader :rows + + def initialize( + rows: [] + ) + @rows = rows + super() + end + + ## + # Returns a new PickleTable from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::PickleTable.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + rows: hash[:rows]&.map { |item| PickleTableRow.from_h(item) } + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/pickle_table_cell.rb b/ruby/lib/cucumber/messages/pickle_table_cell.rb new file mode 100644 index 00000000..f6aae338 --- /dev/null +++ b/ruby/lib/cucumber/messages/pickle_table_cell.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the PickleTableCell message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class PickleTableCell < Message + attr_reader :value + + def initialize( + value: '' + ) + @value = value + super() + end + + ## + # Returns a new PickleTableCell from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::PickleTableCell.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + value: hash[:value] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/pickle_table_row.rb b/ruby/lib/cucumber/messages/pickle_table_row.rb new file mode 100644 index 00000000..6103b340 --- /dev/null +++ b/ruby/lib/cucumber/messages/pickle_table_row.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the PickleTableRow message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class PickleTableRow < Message + attr_reader :cells + + def initialize( + cells: [] + ) + @cells = cells + super() + end + + ## + # Returns a new PickleTableRow from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::PickleTableRow.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + cells: hash[:cells]&.map { |item| PickleTableCell.from_h(item) } + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/pickle_tag.rb b/ruby/lib/cucumber/messages/pickle_tag.rb new file mode 100644 index 00000000..1f962a5c --- /dev/null +++ b/ruby/lib/cucumber/messages/pickle_tag.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the PickleTag message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # * + # A tag + ## + class PickleTag < Message + attr_reader :name + + ## + # Points to the AST node this was created from + ## + attr_reader :ast_node_id + + def initialize( + name: '', + ast_node_id: '' + ) + @name = name + @ast_node_id = ast_node_id + super() + end + + ## + # Returns a new PickleTag from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::PickleTag.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + name: hash[:name], + ast_node_id: hash[:astNodeId] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/product.rb b/ruby/lib/cucumber/messages/product.rb new file mode 100644 index 00000000..5b5ade91 --- /dev/null +++ b/ruby/lib/cucumber/messages/product.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Product message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # Used to describe various properties of Meta + ## + class Product < Message + ## + # The product name + ## + attr_reader :name + + ## + # The product version + ## + attr_reader :version + + def initialize( + name: '', + version: nil + ) + @name = name + @version = version + super() + end + + ## + # Returns a new Product from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Product.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + name: hash[:name], + version: hash[:version] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/rule.rb b/ruby/lib/cucumber/messages/rule.rb new file mode 100644 index 00000000..e0a3a2df --- /dev/null +++ b/ruby/lib/cucumber/messages/rule.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Rule message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class Rule < Message + ## + # The location of the `Rule` keyword + ## + attr_reader :location + + ## + # All the tags placed above the `Rule` keyword + ## + attr_reader :tags + + attr_reader :keyword + + attr_reader :name + + attr_reader :description + + attr_reader :children + + attr_reader :id + + def initialize( + location: Location.new, + tags: [], + keyword: '', + name: '', + description: '', + children: [], + id: '' + ) + @location = location + @tags = tags + @keyword = keyword + @name = name + @description = description + @children = children + @id = id + super() + end + + ## + # Returns a new Rule from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Rule.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + location: Location.from_h(hash[:location]), + tags: hash[:tags]&.map { |item| Tag.from_h(item) }, + keyword: hash[:keyword], + name: hash[:name], + description: hash[:description], + children: hash[:children]&.map { |item| RuleChild.from_h(item) }, + id: hash[:id] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/rule_child.rb b/ruby/lib/cucumber/messages/rule_child.rb new file mode 100644 index 00000000..ecd50cf7 --- /dev/null +++ b/ruby/lib/cucumber/messages/rule_child.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the RuleChild message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # * + # A child node of a `Rule` node + ## + class RuleChild < Message + attr_reader :background + + attr_reader :scenario + + def initialize( + background: nil, + scenario: nil + ) + @background = background + @scenario = scenario + super() + end + + ## + # Returns a new RuleChild from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::RuleChild.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + background: Background.from_h(hash[:background]), + scenario: Scenario.from_h(hash[:scenario]) + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/scenario.rb b/ruby/lib/cucumber/messages/scenario.rb new file mode 100644 index 00000000..ca3a34c1 --- /dev/null +++ b/ruby/lib/cucumber/messages/scenario.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Scenario message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class Scenario < Message + ## + # The location of the `Scenario` keyword + ## + attr_reader :location + + attr_reader :tags + + attr_reader :keyword + + attr_reader :name + + attr_reader :description + + attr_reader :steps + + attr_reader :examples + + attr_reader :id + + def initialize( + location: Location.new, + tags: [], + keyword: '', + name: '', + description: '', + steps: [], + examples: [], + id: '' + ) + @location = location + @tags = tags + @keyword = keyword + @name = name + @description = description + @steps = steps + @examples = examples + @id = id + super() + end + + ## + # Returns a new Scenario from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Scenario.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + location: Location.from_h(hash[:location]), + tags: hash[:tags]&.map { |item| Tag.from_h(item) }, + keyword: hash[:keyword], + name: hash[:name], + description: hash[:description], + steps: hash[:steps]&.map { |item| Step.from_h(item) }, + examples: hash[:examples]&.map { |item| Examples.from_h(item) }, + id: hash[:id] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/source.rb b/ruby/lib/cucumber/messages/source.rb new file mode 100644 index 00000000..c6570cda --- /dev/null +++ b/ruby/lib/cucumber/messages/source.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Source message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # //// Source + # + # * + # A source file, typically a Gherkin document or Java/Ruby/JavaScript source code + ## + class Source < Message + ## + # * + # The [URI](https://en.wikipedia.org/wiki/Uniform_Resource_Identifier) + # of the source, typically a file path relative to the root directory + ## + attr_reader :uri + + ## + # The contents of the file + ## + attr_reader :data + + ## + # The media type of the file. Can be used to specify custom types, such as + # text/x.cucumber.gherkin+plain + ## + attr_reader :media_type + + def initialize( + uri: '', + data: '', + media_type: SourceMediaType::TEXT_X_CUCUMBER_GHERKIN_PLAIN + ) + @uri = uri + @data = data + @media_type = media_type + super() + end + + ## + # Returns a new Source from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Source.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + uri: hash[:uri], + data: hash[:data], + media_type: hash[:mediaType] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/source_media_type.rb b/ruby/lib/cucumber/messages/source_media_type.rb new file mode 100644 index 00000000..bd5c52f0 --- /dev/null +++ b/ruby/lib/cucumber/messages/source_media_type.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + class SourceMediaType + TEXT_X_CUCUMBER_GHERKIN_PLAIN = 'text/x.cucumber.gherkin+plain' + TEXT_X_CUCUMBER_GHERKIN_MARKDOWN = 'text/x.cucumber.gherkin+markdown' + end + end +end diff --git a/ruby/lib/cucumber/messages/source_reference.rb b/ruby/lib/cucumber/messages/source_reference.rb new file mode 100644 index 00000000..fd4282be --- /dev/null +++ b/ruby/lib/cucumber/messages/source_reference.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the SourceReference message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # * + # Points to a [Source](#io.cucumber.messages.Source) identified by `uri` and a + # [Location](#io.cucumber.messages.Location) within that file. + ## + class SourceReference < Message + attr_reader :uri + + attr_reader :java_method + + attr_reader :java_stack_trace_element + + attr_reader :location + + def initialize( + uri: nil, + java_method: nil, + java_stack_trace_element: nil, + location: nil + ) + @uri = uri + @java_method = java_method + @java_stack_trace_element = java_stack_trace_element + @location = location + super() + end + + ## + # Returns a new SourceReference from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::SourceReference.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + uri: hash[:uri], + java_method: JavaMethod.from_h(hash[:javaMethod]), + java_stack_trace_element: JavaStackTraceElement.from_h(hash[:javaStackTraceElement]), + location: Location.from_h(hash[:location]) + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/step.rb b/ruby/lib/cucumber/messages/step.rb new file mode 100644 index 00000000..b100d4be --- /dev/null +++ b/ruby/lib/cucumber/messages/step.rb @@ -0,0 +1,80 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Step message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # A step + ## + class Step < Message + ## + # The location of the steps' `keyword` + ## + attr_reader :location + + ## + # The actual keyword as it appeared in the source. + ## + attr_reader :keyword + + ## + # The test phase signalled by the keyword: Context definition (Given), Action performance (When), Outcome assertion (Then). Other keywords signal Continuation (And and But) from a prior keyword. Please note that all translations which a dialect maps to multiple keywords (`*` is in this category for all dialects), map to 'Unknown'. + ## + attr_reader :keyword_type + + attr_reader :text + + attr_reader :doc_string + + attr_reader :data_table + + ## + # Unique ID to be able to reference the Step from PickleStep + ## + attr_reader :id + + def initialize( + location: Location.new, + keyword: '', + keyword_type: nil, + text: '', + doc_string: nil, + data_table: nil, + id: '' + ) + @location = location + @keyword = keyword + @keyword_type = keyword_type + @text = text + @doc_string = doc_string + @data_table = data_table + @id = id + super() + end + + ## + # Returns a new Step from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Step.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + location: Location.from_h(hash[:location]), + keyword: hash[:keyword], + keyword_type: hash[:keywordType], + text: hash[:text], + doc_string: DocString.from_h(hash[:docString]), + data_table: DataTable.from_h(hash[:dataTable]), + id: hash[:id] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/step_definition.rb b/ruby/lib/cucumber/messages/step_definition.rb new file mode 100644 index 00000000..4986f4a2 --- /dev/null +++ b/ruby/lib/cucumber/messages/step_definition.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the StepDefinition message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class StepDefinition < Message + attr_reader :id + + attr_reader :pattern + + attr_reader :source_reference + + def initialize( + id: '', + pattern: StepDefinitionPattern.new, + source_reference: SourceReference.new + ) + @id = id + @pattern = pattern + @source_reference = source_reference + super() + end + + ## + # Returns a new StepDefinition from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::StepDefinition.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + id: hash[:id], + pattern: StepDefinitionPattern.from_h(hash[:pattern]), + source_reference: SourceReference.from_h(hash[:sourceReference]) + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/step_definition_pattern.rb b/ruby/lib/cucumber/messages/step_definition_pattern.rb new file mode 100644 index 00000000..aeb4b178 --- /dev/null +++ b/ruby/lib/cucumber/messages/step_definition_pattern.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the StepDefinitionPattern message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class StepDefinitionPattern < Message + attr_reader :source + + attr_reader :type + + def initialize( + source: '', + type: StepDefinitionPatternType::CUCUMBER_EXPRESSION + ) + @source = source + @type = type + super() + end + + ## + # Returns a new StepDefinitionPattern from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::StepDefinitionPattern.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + source: hash[:source], + type: hash[:type] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/step_definition_pattern_type.rb b/ruby/lib/cucumber/messages/step_definition_pattern_type.rb new file mode 100644 index 00000000..07c460cc --- /dev/null +++ b/ruby/lib/cucumber/messages/step_definition_pattern_type.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + class StepDefinitionPatternType + CUCUMBER_EXPRESSION = 'CUCUMBER_EXPRESSION' + REGULAR_EXPRESSION = 'REGULAR_EXPRESSION' + end + end +end diff --git a/ruby/lib/cucumber/messages/step_keyword_type.rb b/ruby/lib/cucumber/messages/step_keyword_type.rb new file mode 100644 index 00000000..55d935ea --- /dev/null +++ b/ruby/lib/cucumber/messages/step_keyword_type.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + class StepKeywordType + UNKNOWN = 'Unknown' + CONTEXT = 'Context' + ACTION = 'Action' + OUTCOME = 'Outcome' + CONJUNCTION = 'Conjunction' + end + end +end diff --git a/ruby/lib/cucumber/messages/step_match_argument.rb b/ruby/lib/cucumber/messages/step_match_argument.rb new file mode 100644 index 00000000..0785b62c --- /dev/null +++ b/ruby/lib/cucumber/messages/step_match_argument.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the StepMatchArgument message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # * + # Represents a single argument extracted from a step match and passed to a step definition. + # This is used for the following purposes: + # - Construct an argument to pass to a step definition (possibly through a parameter type transform) + # - Highlight the matched parameter in rich formatters such as the HTML formatter + # + # This message closely matches the `Argument` class in the `cucumber-expressions` library. + ## + class StepMatchArgument < Message + ## + # * + # Represents the outermost capture group of an argument. This message closely matches the + # `Group` class in the `cucumber-expressions` library. + ## + attr_reader :group + + attr_reader :parameter_type_name + + def initialize( + group: Group.new, + parameter_type_name: nil + ) + @group = group + @parameter_type_name = parameter_type_name + super() + end + + ## + # Returns a new StepMatchArgument from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::StepMatchArgument.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + group: Group.from_h(hash[:group]), + parameter_type_name: hash[:parameterTypeName] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/step_match_arguments_list.rb b/ruby/lib/cucumber/messages/step_match_arguments_list.rb new file mode 100644 index 00000000..70e1eaa7 --- /dev/null +++ b/ruby/lib/cucumber/messages/step_match_arguments_list.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the StepMatchArgumentsList message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class StepMatchArgumentsList < Message + attr_reader :step_match_arguments + + def initialize( + step_match_arguments: [] + ) + @step_match_arguments = step_match_arguments + super() + end + + ## + # Returns a new StepMatchArgumentsList from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::StepMatchArgumentsList.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + step_match_arguments: hash[:stepMatchArguments]&.map { |item| StepMatchArgument.from_h(item) } + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/table_cell.rb b/ruby/lib/cucumber/messages/table_cell.rb new file mode 100644 index 00000000..d60b6305 --- /dev/null +++ b/ruby/lib/cucumber/messages/table_cell.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the TableCell message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # A cell in a `TableRow` + ## + class TableCell < Message + ## + # The location of the cell + ## + attr_reader :location + + ## + # The value of the cell + ## + attr_reader :value + + def initialize( + location: Location.new, + value: '' + ) + @location = location + @value = value + super() + end + + ## + # Returns a new TableCell from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::TableCell.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + location: Location.from_h(hash[:location]), + value: hash[:value] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/table_row.rb b/ruby/lib/cucumber/messages/table_row.rb new file mode 100644 index 00000000..0daa1d76 --- /dev/null +++ b/ruby/lib/cucumber/messages/table_row.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the TableRow message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # A row in a table + ## + class TableRow < Message + ## + # The location of the first cell in the row + ## + attr_reader :location + + ## + # Cells in the row + ## + attr_reader :cells + + attr_reader :id + + def initialize( + location: Location.new, + cells: [], + id: '' + ) + @location = location + @cells = cells + @id = id + super() + end + + ## + # Returns a new TableRow from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::TableRow.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + location: Location.from_h(hash[:location]), + cells: hash[:cells]&.map { |item| TableCell.from_h(item) }, + id: hash[:id] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/tag.rb b/ruby/lib/cucumber/messages/tag.rb new file mode 100644 index 00000000..7262161b --- /dev/null +++ b/ruby/lib/cucumber/messages/tag.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Tag message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # * + # A tag + ## + class Tag < Message + ## + # Location of the tag + ## + attr_reader :location + + ## + # The name of the tag (including the leading `@`) + ## + attr_reader :name + + ## + # Unique ID to be able to reference the Tag from PickleTag + ## + attr_reader :id + + def initialize( + location: Location.new, + name: '', + id: '' + ) + @location = location + @name = name + @id = id + super() + end + + ## + # Returns a new Tag from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Tag.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + location: Location.from_h(hash[:location]), + name: hash[:name], + id: hash[:id] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/test_case.rb b/ruby/lib/cucumber/messages/test_case.rb new file mode 100644 index 00000000..d4204735 --- /dev/null +++ b/ruby/lib/cucumber/messages/test_case.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the TestCase message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # //// TestCases + # + # * + # A `TestCase` contains a sequence of `TestStep`s. + ## + class TestCase < Message + attr_reader :id + + ## + # The ID of the `Pickle` this `TestCase` is derived from. + ## + attr_reader :pickle_id + + attr_reader :test_steps + + def initialize( + id: '', + pickle_id: '', + test_steps: [] + ) + @id = id + @pickle_id = pickle_id + @test_steps = test_steps + super() + end + + ## + # Returns a new TestCase from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::TestCase.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + id: hash[:id], + pickle_id: hash[:pickleId], + test_steps: hash[:testSteps]&.map { |item| TestStep.from_h(item) } + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/test_case_finished.rb b/ruby/lib/cucumber/messages/test_case_finished.rb new file mode 100644 index 00000000..8a810d4c --- /dev/null +++ b/ruby/lib/cucumber/messages/test_case_finished.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the TestCaseFinished message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class TestCaseFinished < Message + attr_reader :test_case_started_id + + attr_reader :timestamp + + attr_reader :will_be_retried + + def initialize( + test_case_started_id: '', + timestamp: Timestamp.new, + will_be_retried: false + ) + @test_case_started_id = test_case_started_id + @timestamp = timestamp + @will_be_retried = will_be_retried + super() + end + + ## + # Returns a new TestCaseFinished from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::TestCaseFinished.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + test_case_started_id: hash[:testCaseStartedId], + timestamp: Timestamp.from_h(hash[:timestamp]), + will_be_retried: hash[:willBeRetried] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/test_case_started.rb b/ruby/lib/cucumber/messages/test_case_started.rb new file mode 100644 index 00000000..ed7b600d --- /dev/null +++ b/ruby/lib/cucumber/messages/test_case_started.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the TestCaseStarted message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class TestCaseStarted < Message + ## + # * + # The first attempt should have value 0, and for each retry the value + # should increase by 1. + ## + attr_reader :attempt + + ## + # * + # Because a `TestCase` can be run multiple times (in case of a retry), + # we use this field to group messages relating to the same attempt. + ## + attr_reader :id + + attr_reader :test_case_id + + ## + # An identifier for the worker process running this test case, if test cases are being run in parallel. The identifier will be unique per worker, but no particular format is defined - it could be an index, uuid, machine name etc - and as such should be assumed that it's not human readable. + ## + attr_reader :worker_id + + attr_reader :timestamp + + def initialize( + attempt: 0, + id: '', + test_case_id: '', + worker_id: nil, + timestamp: Timestamp.new + ) + @attempt = attempt + @id = id + @test_case_id = test_case_id + @worker_id = worker_id + @timestamp = timestamp + super() + end + + ## + # Returns a new TestCaseStarted from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::TestCaseStarted.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + attempt: hash[:attempt], + id: hash[:id], + test_case_id: hash[:testCaseId], + worker_id: hash[:workerId], + timestamp: Timestamp.from_h(hash[:timestamp]) + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/test_run_finished.rb b/ruby/lib/cucumber/messages/test_run_finished.rb new file mode 100644 index 00000000..6374d4fb --- /dev/null +++ b/ruby/lib/cucumber/messages/test_run_finished.rb @@ -0,0 +1,63 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the TestRunFinished message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class TestRunFinished < Message + ## + # An informative message about the test run. Typically additional information about failure, but not necessarily. + ## + attr_reader :message + + ## + # A test run is successful if all steps are either passed or skipped, all before/after hooks passed and no other exceptions where thrown. + ## + attr_reader :success + + ## + # Timestamp when the TestRun is finished + ## + attr_reader :timestamp + + ## + # Any exception thrown during the test run, if any. Does not include exceptions thrown while executing steps. + ## + attr_reader :exception + + def initialize( + message: nil, + success: false, + timestamp: Timestamp.new, + exception: nil + ) + @message = message + @success = success + @timestamp = timestamp + @exception = exception + super() + end + + ## + # Returns a new TestRunFinished from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::TestRunFinished.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + message: hash[:message], + success: hash[:success], + timestamp: Timestamp.from_h(hash[:timestamp]), + exception: Exception.from_h(hash[:exception]) + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/test_run_started.rb b/ruby/lib/cucumber/messages/test_run_started.rb new file mode 100644 index 00000000..dea6be01 --- /dev/null +++ b/ruby/lib/cucumber/messages/test_run_started.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the TestRunStarted message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class TestRunStarted < Message + attr_reader :timestamp + + def initialize( + timestamp: Timestamp.new + ) + @timestamp = timestamp + super() + end + + ## + # Returns a new TestRunStarted from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::TestRunStarted.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + timestamp: Timestamp.from_h(hash[:timestamp]) + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/test_step.rb b/ruby/lib/cucumber/messages/test_step.rb new file mode 100644 index 00000000..cbec1bd6 --- /dev/null +++ b/ruby/lib/cucumber/messages/test_step.rb @@ -0,0 +1,74 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the TestStep message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + # + # * + # A `TestStep` is derived from either a `PickleStep` + # combined with a `StepDefinition`, or from a `Hook`. + ## + class TestStep < Message + ## + # Pointer to the `Hook` (if derived from a Hook) + ## + attr_reader :hook_id + + attr_reader :id + + ## + # Pointer to the `PickleStep` (if derived from a `PickleStep`) + ## + attr_reader :pickle_step_id + + ## + # Pointer to all the matching `StepDefinition`s (if derived from a `PickleStep`) + ## + attr_reader :step_definition_ids + + ## + # A list of list of StepMatchArgument (if derived from a `PickleStep`). + # Each element represents a matching step definition. A size of 0 means `UNDEFINED`, + # and a size of 2+ means `AMBIGUOUS` + ## + attr_reader :step_match_arguments_lists + + def initialize( + hook_id: nil, + id: '', + pickle_step_id: nil, + step_definition_ids: nil, + step_match_arguments_lists: nil + ) + @hook_id = hook_id + @id = id + @pickle_step_id = pickle_step_id + @step_definition_ids = step_definition_ids + @step_match_arguments_lists = step_match_arguments_lists + super() + end + + ## + # Returns a new TestStep from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::TestStep.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + hook_id: hash[:hookId], + id: hash[:id], + pickle_step_id: hash[:pickleStepId], + step_definition_ids: hash[:stepDefinitionIds], + step_match_arguments_lists: hash[:stepMatchArgumentsLists]&.map { |item| StepMatchArgumentsList.from_h(item) } + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/test_step_finished.rb b/ruby/lib/cucumber/messages/test_step_finished.rb new file mode 100644 index 00000000..912cb1f1 --- /dev/null +++ b/ruby/lib/cucumber/messages/test_step_finished.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the TestStepFinished message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class TestStepFinished < Message + attr_reader :test_case_started_id + + attr_reader :test_step_id + + attr_reader :test_step_result + + attr_reader :timestamp + + def initialize( + test_case_started_id: '', + test_step_id: '', + test_step_result: TestStepResult.new, + timestamp: Timestamp.new + ) + @test_case_started_id = test_case_started_id + @test_step_id = test_step_id + @test_step_result = test_step_result + @timestamp = timestamp + super() + end + + ## + # Returns a new TestStepFinished from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::TestStepFinished.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + test_case_started_id: hash[:testCaseStartedId], + test_step_id: hash[:testStepId], + test_step_result: TestStepResult.from_h(hash[:testStepResult]), + timestamp: Timestamp.from_h(hash[:timestamp]) + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/test_step_result.rb b/ruby/lib/cucumber/messages/test_step_result.rb new file mode 100644 index 00000000..6e291f3e --- /dev/null +++ b/ruby/lib/cucumber/messages/test_step_result.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the TestStepResult message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class TestStepResult < Message + attr_reader :duration + + ## + # An arbitrary bit of information that explains this result. This can be a stack trace of anything else. + ## + attr_reader :message + + attr_reader :status + + ## + # Exception thrown while executing this step, if any. + ## + attr_reader :exception + + def initialize( + duration: Duration.new, + message: nil, + status: TestStepResultStatus::UNKNOWN, + exception: nil + ) + @duration = duration + @message = message + @status = status + @exception = exception + super() + end + + ## + # Returns a new TestStepResult from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::TestStepResult.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + duration: Duration.from_h(hash[:duration]), + message: hash[:message], + status: hash[:status], + exception: Exception.from_h(hash[:exception]) + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/test_step_result_status.rb b/ruby/lib/cucumber/messages/test_step_result_status.rb new file mode 100644 index 00000000..0f2472e3 --- /dev/null +++ b/ruby/lib/cucumber/messages/test_step_result_status.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + class TestStepResultStatus + UNKNOWN = 'UNKNOWN' + PASSED = 'PASSED' + SKIPPED = 'SKIPPED' + PENDING = 'PENDING' + UNDEFINED = 'UNDEFINED' + AMBIGUOUS = 'AMBIGUOUS' + FAILED = 'FAILED' + end + end +end diff --git a/ruby/lib/cucumber/messages/test_step_started.rb b/ruby/lib/cucumber/messages/test_step_started.rb new file mode 100644 index 00000000..c6e12d3f --- /dev/null +++ b/ruby/lib/cucumber/messages/test_step_started.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the TestStepStarted message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class TestStepStarted < Message + attr_reader :test_case_started_id + + attr_reader :test_step_id + + attr_reader :timestamp + + def initialize( + test_case_started_id: '', + test_step_id: '', + timestamp: Timestamp.new + ) + @test_case_started_id = test_case_started_id + @test_step_id = test_step_id + @timestamp = timestamp + super() + end + + ## + # Returns a new TestStepStarted from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::TestStepStarted.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + test_case_started_id: hash[:testCaseStartedId], + test_step_id: hash[:testStepId], + timestamp: Timestamp.from_h(hash[:timestamp]) + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/time_conversion.rb b/ruby/lib/cucumber/messages/time_conversion.rb deleted file mode 100644 index 8c6aeb1f..00000000 --- a/ruby/lib/cucumber/messages/time_conversion.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -module Cucumber - module Messages - module TimeConversion - NANOSECONDS_PER_SECOND = 1_000_000_000 - - def time_to_timestamp(time) - { 'seconds' => time.to_i, 'nanos' => time.nsec } - end - - def timestamp_to_time(timestamp) - Time.at(timestamp['seconds'] + (timestamp['nanos'].to_f / NANOSECONDS_PER_SECOND)) - end - - def seconds_to_duration(seconds_float) - seconds, second_modulus = seconds_float.divmod(1) - nanos = second_modulus * NANOSECONDS_PER_SECOND - { 'seconds' => seconds, 'nanos' => nanos.to_i } - end - - def duration_to_seconds(duration) - seconds_part = duration['seconds'] - nanos_part = duration['nanos'].to_f / NANOSECONDS_PER_SECOND - seconds_part + nanos_part - end - end - end -end diff --git a/ruby/lib/cucumber/messages/timestamp.rb b/ruby/lib/cucumber/messages/timestamp.rb new file mode 100644 index 00000000..715610db --- /dev/null +++ b/ruby/lib/cucumber/messages/timestamp.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the Timestamp message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class Timestamp < Message + ## + # Represents seconds of UTC time since Unix epoch + # 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + # 9999-12-31T23:59:59Z inclusive. + ## + attr_reader :seconds + + ## + # Non-negative fractions of a second at nanosecond resolution. Negative + # second values with fractions must still have non-negative nanos values + # that count forward in time. Must be from 0 to 999,999,999 + # inclusive. + ## + attr_reader :nanos + + def initialize( + seconds: 0, + nanos: 0 + ) + @seconds = seconds + @nanos = nanos + super() + end + + ## + # Returns a new Timestamp from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::Timestamp.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + seconds: hash[:seconds], + nanos: hash[:nanos] + ) + end + end + end +end diff --git a/ruby/lib/cucumber/messages/undefined_parameter_type.rb b/ruby/lib/cucumber/messages/undefined_parameter_type.rb new file mode 100644 index 00000000..3afe0b3b --- /dev/null +++ b/ruby/lib/cucumber/messages/undefined_parameter_type.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb] +module Cucumber + module Messages + ## + # Represents the UndefinedParameterType message in Cucumber's {message protocol}[https://github.com/cucumber/messages]. + ## + ## + class UndefinedParameterType < Message + attr_reader :expression + + attr_reader :name + + def initialize( + expression: '', + name: '' + ) + @expression = expression + @name = name + super() + end + + ## + # Returns a new UndefinedParameterType from the given hash. + # If the hash keys are camelCased, they are properly assigned to the + # corresponding snake_cased attributes. + # + # Cucumber::Messages::UndefinedParameterType.from_h(some_hash) # => # + ## + def self.from_h(hash) + return nil if hash.nil? + + new( + expression: hash[:expression], + name: hash[:name] + ) + end + end + end +end diff --git a/ruby/spec/cucumber/messages/acceptance_spec.rb b/ruby/spec/cucumber/messages/acceptance_spec.rb index 42d845a3..f0dc0631 100644 --- a/ruby/spec/cucumber/messages/acceptance_spec.rb +++ b/ruby/spec/cucumber/messages/acceptance_spec.rb @@ -17,10 +17,8 @@ module Messages it 'deserializes and serializes messages in the ndjson file' do File.open(ndjson_filepath, 'r:utf-8') do |file| file.each_line do |message| - parsed_actual_message = JSON.parse(message) - parsed_regenerated_message = JSON.parse(Envelope.from_json(message).to_json) - - expect(parsed_regenerated_message).to eq(parsed_actual_message) + # Check that the Envelope re-generated message equals the originally parsed message + expect(JSON.parse(Envelope.from_json(message).to_json)).to eq(JSON.parse(message)) end end end diff --git a/ruby/spec/cucumber/messages/id_generator/incrementing_spec.rb b/ruby/spec/cucumber/messages/helpers/id_generator/incrementing_spec.rb similarity index 83% rename from ruby/spec/cucumber/messages/id_generator/incrementing_spec.rb rename to ruby/spec/cucumber/messages/helpers/id_generator/incrementing_spec.rb index e23c635f..75534205 100644 --- a/ruby/spec/cucumber/messages/id_generator/incrementing_spec.rb +++ b/ruby/spec/cucumber/messages/helpers/id_generator/incrementing_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -describe Cucumber::Messages::IdGenerator::Incrementing do +describe Cucumber::Messages::Helpers::IdGenerator::Incrementing do subject(:generator) { described_class.new } describe '#new_id' do diff --git a/ruby/spec/cucumber/messages/id_generator/uuid_spec.rb b/ruby/spec/cucumber/messages/helpers/id_generator/uuid_spec.rb similarity index 79% rename from ruby/spec/cucumber/messages/id_generator/uuid_spec.rb rename to ruby/spec/cucumber/messages/helpers/id_generator/uuid_spec.rb index 35916070..2a044054 100644 --- a/ruby/spec/cucumber/messages/id_generator/uuid_spec.rb +++ b/ruby/spec/cucumber/messages/helpers/id_generator/uuid_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -describe Cucumber::Messages::IdGenerator::UUID do +describe Cucumber::Messages::Helpers::IdGenerator::UUID do subject(:generator) { described_class.new } describe '#new_id' do diff --git a/ruby/spec/cucumber/messages/ndjson_to_message_enumerator_spec.rb b/ruby/spec/cucumber/messages/helpers/ndjson_to_message_enumerator_spec.rb similarity index 85% rename from ruby/spec/cucumber/messages/ndjson_to_message_enumerator_spec.rb rename to ruby/spec/cucumber/messages/helpers/ndjson_to_message_enumerator_spec.rb index dd910baa..f801da18 100644 --- a/ruby/spec/cucumber/messages/ndjson_to_message_enumerator_spec.rb +++ b/ruby/spec/cucumber/messages/helpers/ndjson_to_message_enumerator_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -describe Cucumber::Messages::NdjsonToMessageEnumerator do +describe Cucumber::Messages::Helpers::NdjsonToMessageEnumerator do subject(:incoming_messages) { described_class.new(io) } let(:outgoing_messages) do @@ -9,7 +9,8 @@ Cucumber::Messages::Envelope.new(source: source) ] end - let(:attachment) { Cucumber::Messages::Attachment.new(body: 'Hello', content_encoding: Cucumber::Messages::AttachmentContentEncoding::IDENTITY) } + let(:attachment) { Cucumber::Messages::Attachment.new(body: 'Hello', content_encoding: content_encoding) } + let(:content_encoding) { Cucumber::Messages::AttachmentContentEncoding::IDENTITY } let(:source) { Cucumber::Messages::Source.new(data: 'Feature: Hello') } let(:io) { StringIO.new } diff --git a/ruby/spec/cucumber/messages/helpers/time_conversion_spec.rb b/ruby/spec/cucumber/messages/helpers/time_conversion_spec.rb new file mode 100644 index 00000000..1a77b0b4 --- /dev/null +++ b/ruby/spec/cucumber/messages/helpers/time_conversion_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +describe Cucumber::Messages::Helpers::TimeConversion do + include described_class + + it 'converts to and from milliseconds since epoch' do + time = Time.now + timestamp = time_to_timestamp(time) + time_again = timestamp_to_time(timestamp) + + expect(time).to be_within(0.000001).of(time_again) + end + + it 'converts to and from seconds duration' do + duration_in_seconds = 1234 + duration = seconds_to_duration(duration_in_seconds) + duration_in_seconds_again = duration_to_seconds(duration) + + expect(duration_in_seconds_again).to eq(duration_in_seconds) + end + + it 'converts to and from seconds duration (with decimal places)' do + duration_in_seconds = 3.000161 + duration = seconds_to_duration(duration_in_seconds) + duration_in_seconds_again = duration_to_seconds(duration) + + expect(duration_in_seconds_again).to be_within(0.000000001).of(duration_in_seconds) + end + + it 'converts to a hash where seconds and nanos are integers' do + duration_in_seconds = 3.000161 + + expect(seconds_to_duration(duration_in_seconds).values).to all be_integer + end +end diff --git a/ruby/spec/cucumber/messages/message_spec.rb b/ruby/spec/cucumber/messages/message_spec.rb index 6a239dbc..2e5e850e 100644 --- a/ruby/spec/cucumber/messages/message_spec.rb +++ b/ruby/spec/cucumber/messages/message_spec.rb @@ -11,15 +11,15 @@ end describe '.from_json' do - subject(:message) { Cucumber::Messages::Message.from_json(json_document) } + subject(:message) { described_class.from_json(json_document) } context 'with a valid JSON document' do let(:json_document) { '{"simpleMessage":{"isString":"answer"}}' } it 'deserialize the message using #from_h' do - allow(Cucumber::Messages::Message).to receive(:from_h) + allow(described_class).to receive(:from_h) - expect(Cucumber::Messages::Message).to receive(:from_h).with({ simpleMessage: { isString: 'answer' } }) + expect(described_class).to receive(:from_h).with({ simpleMessage: { isString: 'answer' } }) message end @@ -42,16 +42,12 @@ expect(message.to_h).to eq({ is_nil: nil, is_string: '', is_array: [], is_number: 0 }) end - context 'with camelize: true' do - it 'camelizes the keys of the resulting hash' do - expect(message.to_h(camelize: true)).to eq({ isNil: nil, isString: '', isArray: [], isNumber: 0 }) - end + it 'can be configured to camelize the keys of the resulting hash' do + expect(message.to_h(camelize: true)).to eq({ isNil: nil, isString: '', isArray: [], isNumber: 0 }) end - context 'with reject_nil_values: true' do - it 'rejects nil values from the resulting hash' do - expect(message.to_h(reject_nil_values: true)).to eq({ is_string: '', is_array: [], is_number: 0 }) - end + it 'can be configured to sanitize out any nil values from the resulting hash' do + expect(message.to_h(reject_nil_values: true)).to eq({ is_string: '', is_array: [], is_number: 0 }) end end @@ -66,39 +62,43 @@ subject(:message) { Cucumber::Messages::ComprehensiveMessage.new } let(:expected_snake_cased_hash) { { is_nil: nil, is_string: '', is_array: [], is_number: 0 } } - let(:expected_camel_cased_hash) { { isNil: nil, isString: '', isArray: [], isNumber: 0 } } + let(:expected_camelized_hash) { { isNil: nil, isString: '', isArray: [], isNumber: 0 } } describe '#to_h' do it 'includes a hash representation of embedded messages' do expect(message.to_h[:simple_message]).to eq(expected_snake_cased_hash) + end + + it 'stores enums' do expect(message.to_h[:is_enum]).to eq('an enum') end - it 'includes a hash representation of messages arrays' do + it 'includes a hash representation of more complex messages' do expect(message.to_h[:message_array]).to eq([expected_snake_cased_hash, expected_snake_cased_hash]) end - context 'with camelize: true' do - it 'camelizes the keys of the embedded messages resulting hashes' do - expect(message.to_h(camelize: true)[:simpleMessage]).to eq(expected_camel_cased_hash) - end + it 'can be configured to camelize the keys of an embedded messages and the resulting hash' do + expect(message.to_h(camelize: true)[:simpleMessage]).to eq(expected_camelized_hash) + end - it 'camelizes the keys of hashes for messages arrays' do - expect(message.to_h(camelize: true)[:messageArray]).to eq([expected_camel_cased_hash, expected_camel_cased_hash]) - end + it 'can be configured to camelize the keys of a more complex messages and the resulting hashes' do + expect(message.to_h(camelize: true)[:messageArray]).to eq([expected_camelized_hash, expected_camelized_hash]) end end describe '#to_json' do - let(:expected_camel_cased_hash) { { isString: '', isArray: [], isNumber: 0 } } + let(:expected_camelized_hash) { { isString: '', isArray: [], isNumber: 0 } } - it 'returns a JSON document with embedded messages' do - expect(message.to_json).to include(expected_camel_cased_hash.to_json) - expect(message.to_json).to include('"isEnum":"an enum"') + it 'returns a JSON document that includes simple embedded messages' do + expect(message.to_json).to include(expected_camelized_hash.to_json) end - it 'returns a JSON document with messages arrays' do - expect(message.to_json).to include([expected_camel_cased_hash, expected_camel_cased_hash].to_json) + it 'returns a JSON document that includes complex embedded messages' do + expect(message.to_json).to include([expected_camelized_hash, expected_camelized_hash].to_json) + end + + it 'returns a JSON document that includes enums' do + expect(message.to_json).to include('"isEnum":"an enum"') end end end diff --git a/ruby/spec/cucumber/messages/time_conversion_spec.rb b/ruby/spec/cucumber/messages/time_conversion_spec.rb deleted file mode 100644 index f938f8e5..00000000 --- a/ruby/spec/cucumber/messages/time_conversion_spec.rb +++ /dev/null @@ -1,41 +0,0 @@ -# frozen_string_literal: true - -module Cucumber - module Messages - describe TimeConversion do - include described_class - - it 'converts to and from milliseconds since epoch' do - time = Time.now - timestamp = time_to_timestamp(time) - time_again = timestamp_to_time(timestamp) - - expect(time).to be_within(0.000001).of(time_again) - end - - it 'converts to and from seconds duration' do - duration_in_seconds = 1234 - duration = seconds_to_duration(duration_in_seconds) - duration_in_seconds_again = duration_to_seconds(duration) - - expect(duration_in_seconds_again).to eq(duration_in_seconds) - end - - it 'converts to and from seconds duration (with decimal places)' do - duration_in_seconds = 3.000161 - duration = seconds_to_duration(duration_in_seconds) - duration_in_seconds_again = duration_to_seconds(duration) - - expect(duration_in_seconds_again).to be_within(0.000000001).of(duration_in_seconds) - end - - it 'converts to a hash where seconds and nanos are integers' do - duration_in_seconds = 3.000161 - duration = seconds_to_duration(duration_in_seconds) - - expect(duration['seconds']).to be_integer - expect(duration['nanos']).to be_integer - end - end - end -end diff --git a/ruby/spec/support/comprehensive_message.rb b/ruby/spec/support/comprehensive_message.rb index 5544b29b..a41f3be4 100644 --- a/ruby/spec/support/comprehensive_message.rb +++ b/ruby/spec/support/comprehensive_message.rb @@ -7,7 +7,11 @@ module Messages class ComprehensiveMessage < Message attr_reader :simple_message, :message_array, :is_enum - def initialize(simple_message: SimpleMessage.new, message_array: [SimpleMessage.new, SimpleMessage.new], is_enum: EnumMessage::ENUM) + def initialize( + simple_message: SimpleMessage.new, + message_array: [SimpleMessage.new, SimpleMessage.new], + is_enum: EnumMessage::ENUM + ) @simple_message = simple_message @message_array = message_array @is_enum = is_enum