Skip to content

Commit 556259d

Browse files
authored
[Ruby] Split messages files per message type (#225)
* Set minimum ruby to 2.7 and minimum rubygems to 3.2.3 * Remove ruby 2.6 and 2.7 from workflows - Add in ruby 3.3 * Update target rubocop version * Update misc files * Update to use latest CCK in testing * Remove some gitignore files * Spike of non-working code * Spike of using both private and public methods * Compare / contrast the two ways of performing the new cck path reference * Working example for iterative checks on each item * Use file exist to simplify code - Remove wildcards * Update minimum deps for rake / rspec * Fix up all gemspec cops * Move towards a spec support structure to remove any oddities flagged by rubocop * Remove duplicate dummy messages * Split up composiite dummy message class into individual items * Remove top level leaked fake class for utils testing * Fix up some minor simple offenses for utils spec * Slight update to check rubocop works and then regenerate autogenconfig * Bump rubocop performance and rubocop rake to latest. Slight bump to rubocop / rubocop-rspec * Fix up issue whereby error was being rescued incorrectly and was being stored without requirement * Tidy up serialization formatting * Ignore line length cop as it's un-enforceable * Attempt to distinguish what are the actual objects in the acceptance tests * Re-gen the autogen config using bundler to ensure correct version (For now) * Set minimum ruby to 3.0 * Reduce line count of spec for acceptance as we just want a wrap/unwrap call * Fix up typos and named subject issue in serialization spec * Fix up a couple of spec support Lint/MissingSuper calls * Simplify deserialization protocol into just a single class method which is extended * underscore as a method isn't used in the utils implementation * Remove underscore tests * Simplify Utils to just be extended as class methods * Utils aren't used in the deserialization protocol * Move all serialization into the message proper as it's just a single module with 1 method used in 1 location * Move the deserialization spec tests into message proper Fix describe block as they're class methods not instance methods * Remove utils class and place camelize inside the message proper * Don't create an extra object * Split id generator into individual class files * AF: Style/SpecialGlobalVars * Simplify serialization spec by not creating 10 different subjects * AF: Gemspec/OrderedDependencies * AF: Layout/EmptyLineAfterMagicComment * Partial fix for the Layout/FirstArrayElementIndentation cop offenses * AF: Layout/LeadingEmptyLines * Re-generate todo file with May's marker - 50 offenses cleared with the gem upgrade and rubocop bump * Fix rubocop error * Alter UUID test to just check for a securerandom uuid and simplify the code * Alter incrementing spec to only have 1 assertion line * Move serialization into message model proper * Fix up Layout cops after copying over serialization messages * AF: Lint/ToJSON should allow optional discarded args * In ruby 2.6+ #to_h permits a block assign so we can refine this code better * Refine the compacting of the resultant hash in the message adhering to the Style/CollectionCompact rule * AF: Style/SlicingWithRange * Update tests to remove redundant failing ones and fix up some legacy named subject offenses * Re-order and tidy up messages class * Add super() call to each message generation - Should remedy Lint/MissingSuper cop offense * Re-generate config * Fix up args to JSONSchema generation to use Ruby 3.0+ idioms * Fix up the Trailing Whitespace cop by fixing a generation bug * AF: Lint/AmbiguousOperatorPrecedence * Fix up RSpec/DescribedClass issue with ndjson spec * Partial fix of RSpec/ExampleLength * Alter the Enum generator enabling us to autofix Style/ClassAndModuleChildren * AF: FrozenStringLiteral * Remove redundant spec * Configure and permit AllowedNames to also include as a name and Exclusion lists to be merged * Disable Style/AccessorGrouping * Fix up namespacing issues when migrating tests * Move some logic out into let/subject blocks * Fix up auto-fix offenses in rubocop * Remove frozen string literal pragma's whilst we haven't fixed up autogen * Add new requirements pending migration to one class per file logic like in java/cpp * Fix up line spacing in generic ruby file and begin to split file into constituent ones * Move all helpers to helpers namespace * Fix up tests and require path * Rename confusingly named make targets * Generate files in new way * Leave leakage item on dtos file for now as it will serve well when we come to fix filename * Add new generation logic to .generate-messages * add new clean command * Add new filename checking for template Fix clean process not to remove helpers * Alter generation to use snake cased names * Re-generate files * Remove extra line that's not needed * Make inheritance from message simpler * Alter enum generation to also make new unique files * Add .from_h method to ruby.rb.erb template to begin process of removing redundant template * Add enum generation to the generator script Clean up all redundant strings * Remove all trace to referencing the .dtos.rb file including using the now un-needed jsonschema template for the deserializers * Remove all trace to referencing the .deserializers.rb file * Fix up namespace for UUID * Require all new messages when requiring one message * Only add comma after properties that aren't final * Remove un-required requirement now we are recursively loading items in * Re-generate messages using new templates * Remove duplicate comma on the if/elsif/else statement * Add comma into correct spot in template * Fixed mismatched comment style from template * Fix frozen string literal pragmas in templates * Enum template was assigning an un-needed index during iteration * Re-generated messages * Re-generate TODO file after minor fixes in templates * AF: Style/StringConcatenation * Manual fix for RSpec/ExampleLength * AF: RSpec/DescribedClass£ * AF: Layout/SpaceInsideBlockBraces * Remove duplicate files missed by bad merge conflict * Re-generate TODO file owing to conflict clash * Fix up RSpec/MultipleExpectations * Disable ParameterLists cop as most messages will have 5+ properties * Fix up RSpec/NestedGroups * Ignore method length for same reason as parameter lists * AF: Layout/EmptyLineAfterGuardClause * Remove TODO file as we have < 10 offenses to fix now * Ignore all generated files * Switch from metric blanket overrides to generated code overrides * Only ignore Metrics and Layout/LineLength for generated messages * Fix up line length offenses in message class proper * Fix up all remaining line length issues in the specs * Fix up LineLength offenses by moving extraction of message out to a private sub method * Update changelogs * Slight update to some rubocop gems that don't affect signoff of rubocop conformance * Accessor grouping should only be unenforceable in generated messages * Update docs
1 parent 4a2c5fe commit 556259d

File tree

91 files changed

+3501
-3413
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

91 files changed

+3501
-3413
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
77

88
## [Unreleased]
99
### Changed
10+
- [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))
1011
- [Ruby] Updated minimum Ruby version to 3.0 ([#216](https://github.com/cucumber/messages/pull/216) [luke-hill](https://github.com/luke-hill))
1112
- [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))
12-
- [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))
13+
- [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))
1314
- [Php] Permit both PHPUnit 10 and PHPUnit 11 ([#200](https://github.com/cucumber/messages/pull/200) [ciaranmcnulty](https://github.com/ciaranmcnulty))
1415

1516
### Fixed

CONTRIBUTING.md

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Some guidelines for making schema changes:
77
- Use the most appropriate data type
88
- Follow existing naming conventions (camelCase)
99
- Add new fields last to minimise impact on consuming code
10-
- Probably don't add a new field as `required` - this will make the new code unable to read existing messages
10+
- Don't add a new field as `required` - this will make the new code unable to read existing messages
1111
- Ideally add a description to any new fields
1212

1313
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
2020
make clean-all generate-all
2121
```
2222

23-
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:
23+
Or you can alternative clean and generate code for just one language by cd'ing into that languages directory
24+
and then running the following commands
2425

2526
```shell
26-
docker run --volume $PWD:/app --user 1000 -it cucumber/cucumber-build:latest bash
27+
cd ruby # Or another alternative
28+
make clean generate
2729
```
2830

29-
For Windows (Powershell):
30-
31-
```shell
32-
docker run --volume ${PWD}:/app --user 1000 -it cucumber/cucumber-build:latest bash
33-
```
34-
35-
You can then run the same command as noted previously.
31+
This requires various tooling to be installed on your computer, including Ruby and Node.js.
3632

3733
### New files
3834

39-
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.
35+
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`
36+
at the root in order for it to be included in the code generation.
4037

4138
## Tests
4239

43-
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.
40+
Some of the language-specific directories contain some smoke tests to ensure (de)serialization, validation etc
41+
are working right. If you happen to change one of the messages that's constructed by these tests, you may
42+
need to update them. If you're not sure, raise a draft PR and see what happens in CI.

README.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ Cucumber needs to produce results in a machine-readable format so that other too
5656

5757
![messages-stream.svg](messages-stream.svg)
5858

59-
Historically, Cucumber has done this with the `json` and `junit` formatters.
60-
These formats have several shortcomings that are addressed by Cucumber Messages.
59+
Historically, Cucumber did this with the `json` and `junit` formatters.
60+
These formats however, have several shortcomings that are now addressed by using Cucumber Messages.
6161

6262
The `json` formatter is now in maintenance mode for these implementations, and Messages is the preferred standard.
6363
See [utilities](#utilities) for a list of tools that may help with backward and forward compatibility
@@ -78,15 +78,14 @@ of results.
7878

7979
### Lack of a schema
8080

81-
The JSON report does not have a formal schema. This has led to slightly inconsistent implementations
81+
The JSON reporter does not have a formal schema. This has led to slightly inconsistent implementations
8282
of the JSON formatter in various Cucumber implementations. Consumers of the JSON format have
8383
to anticipate and detect these inconsistencies and try to cope with them.
8484

8585
### Limited information
8686

8787
The `junit` XML format can only contain very limited information such as test case name and status.
88-
While there isn't an official schema for JUnit XML, there are a few defacto ones around, and they
89-
are very limited.
88+
While there isn't an official schema for JUnit XML, there are a few defacto ones around which are very limited.
9089

9190
The `json` format represents the following information:
9291

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1+
<%- @enums.each do |enum| -%>
2+
<%= underscore(enum[:name]) %>.rb
3+
# frozen_string_literal: true
14

2-
<% @enums.each do |enum| -%>
5+
# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb]
36
module Cucumber
47
module Messages
58
class <%= enum[:name] %>
6-
<%- enum[:values].each_with_index do |value, index| -%>
9+
<%- enum[:values].each do |value| -%>
710
<%= enum_constant(value) %> = '<%= value %>'
811
<%- end -%>
912
end
1013
end
1114
end
12-
<%= "\n" unless enum == @enums.last -%>
13-
<%- end -%>
15+
<% end -%>

jsonschema/scripts/templates/ruby.rb.erb

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
require 'cucumber/messages/message'
1+
<%- @schemas.each do |key, schema| -%>
2+
<%= underscore(class_name(key)) %>.rb
3+
# frozen_string_literal: true
24

35
# The code was auto-generated by {this script}[https://github.com/cucumber/messages/blob/main/jsonschema/scripts/codegen.rb]
4-
#
5-
66
module Cucumber
77
module Messages
8-
<%- @schemas.each do |key, schema| %>
98
##
109
# Represents the <%= class_name(key) %> message in Cucumber's {message protocol}[https://github.com/cucumber/messages].
10+
##
1111
<%= "#\n " if schema['description'] %><%= format_description(schema['description']) %>
12-
class <%= class_name(key) %> < ::Cucumber::Messages::Message
12+
class <%= class_name(key) %> < Message
1313
<%- schema['properties'].each do |property_name, property| -%>
1414
<%- if property['description'] -%>
1515
##
@@ -30,7 +30,34 @@ module Cucumber
3030
<%- end -%>
3131
super()
3232
end
33+
34+
##
35+
# Returns a new <%= class_name(key) %> from the given hash.
36+
# If the hash keys are camelCased, they are properly assigned to the
37+
# corresponding snake_cased attributes.
38+
#
39+
# Cucumber::Messages::<%= class_name(key) %>.from_h(some_hash) # => #<Cucumber::Messages::<%= class_name(key) %>:0x... ...>
40+
##
41+
def self.from_h(hash)
42+
return nil if hash.nil?
43+
44+
new(
45+
<%-
46+
schema['properties'].each do |property_name, property|
47+
ref = property['$ref']
48+
items_ref = property.dig('items', '$ref')
49+
-%>
50+
<%- final_key = property_name == schema['properties'].keys.last -%>
51+
<%- comma = final_key ? '' : ',' -%>
52+
<%= "#{underscore(property_name)}: " -%>
53+
<%- if items_ref -%>hash[:<%= property_name -%>]&.map { |item| <%= class_name(items_ref) %>.from_h(item) }<%= comma %>
54+
<%- elsif ref -%><%= class_name(ref) %>.from_h(hash[:<%= property_name %>])<%= comma %>
55+
<%- else -%>hash[:<%= property_name %>]<%= comma %>
56+
<%- end -%>
57+
<%- end -%>
58+
)
59+
end
3360
end
34-
<%- end -%>
3561
end
3662
end
63+
<% end -%>

jsonschema/scripts/templates/ruby_deserializers.rb.erb

Lines changed: 0 additions & 40 deletions
This file was deleted.

ruby/.rubocop.yml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
inherit_from: .rubocop_todo.yml
2-
31
inherit_mode:
42
merge:
53
- Exclude
@@ -17,9 +15,16 @@ AllCops:
1715
Gemspec/RequireMFA:
1816
Enabled: false
1917

20-
# Some long comments in the JSON Schema cause this to be un-enforceable
18+
# Generated messages (including the Envelope) aren't tested by the Metrics department because they have many
19+
# input properties for #initialize and .from_h which are generated 1-per-line. This renders most Metrics redundant
20+
Metrics:
21+
Exclude:
22+
- lib/cucumber/messages/*.rb
23+
24+
# Long comments in the generated messages from the JSON Schemas cause this to be un-enforceable
2125
Layout/LineLength:
22-
Max: 1000
26+
Exclude:
27+
- lib/cucumber/messages/*.rb
2328

2429
Naming/MethodParameterName:
2530
AllowedNames:
@@ -31,7 +36,8 @@ RSpec/MessageSpies:
3136
# Because of the nature of large amounts of Accessors, we disable this cop
3237
# This is because many of them will have custom documentation which are auto-generated from the jsonschema
3338
Style/AccessorGrouping:
34-
Enabled: false
39+
Exclude:
40+
- lib/cucumber/messages/*.rb
3541

3642
Style/Documentation:
3743
Enabled: false

ruby/.rubocop_todo.yml

Lines changed: 0 additions & 145 deletions
This file was deleted.

0 commit comments

Comments
 (0)