Skip to content

Commit

Permalink
Update Gherkin to use Messages DTOs instead of plain ruby hashes (#1603)
Browse files Browse the repository at this point in the history
* Update Gherkin to use Messages DTOs instead of plain ruby hashes

* Make messages#to_h compatible with ruby < 2.6

* Configure html-formatter to use local messages

* Update html-formatter to use new ruby message DTOs

Co-authored-by: Aslak Hellesøy <1000+aslakhellesoy@users.noreply.github.com>
  • Loading branch information
aurelien-reeves and aslakhellesoy committed Jul 7, 2021
1 parent 3b01430 commit 57b3926
Show file tree
Hide file tree
Showing 13 changed files with 213 additions and 207 deletions.
2 changes: 2 additions & 0 deletions gherkin/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ This document is formatted according to the principles of [Keep A CHANGELOG](htt
([#1625](https://github.com/cucumber/common/pull/1625) [willmac321])
* [Go] Move module paths to point to monorepo
([#1550](https://github.com/cucumber/common/issues/1550))
* [Ruby] Usage of Message DTOs instead of plain ruby hashes
([#1603](https://github.com/cucumber/common/pull/1603))

### Deprecated

Expand Down
2 changes: 1 addition & 1 deletion gherkin/ruby/bin/gherkin
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ end.parse!

def process_messages(messages, options)
messages.each do |message|
STDOUT.write(JSON.fast_generate(message))
STDOUT.write(message.to_json)
STDOUT.write("\n")
end
end
Expand Down
6 changes: 3 additions & 3 deletions gherkin/ruby/lib/gherkin.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ def self.from_source(uri, data, options={})
private

def self.encode_source_message(uri, data)
{
Cucumber::Messages::Source.new(
uri: uri,
data: data,
mediaType: 'text/x.cucumber.gherkin+plain'
}
media_type: 'text/x.cucumber.gherkin+plain'
)
end
end
86 changes: 43 additions & 43 deletions gherkin/ruby/lib/gherkin/ast_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ def end_rule(rule_type)

def build(token)
if token.matched_type == :Comment
@comments.push({
@comments.push(Cucumber::Messages::Comment.new(
location: get_location(token, 0),
text: token.matched_text
})
))
else
current_node.add(token.matched_type, token)
end
Expand All @@ -43,10 +43,10 @@ def current_node

def get_location(token, column)
column = column == 0 ? token.location[:column] : column
{
Cucumber::Messages::Location.new(
line: token.location[:line],
column: column
}.delete_if {|k,v| v.nil?}
)
end

def get_tags(node)
Expand All @@ -56,11 +56,11 @@ def get_tags(node)

tags_node.get_tokens(:TagLine).each do |token|
token.matched_items.each do |tag_item|
tags.push({
tags.push(Cucumber::Messages::Tag.new(
location: get_location(token, tag_item.column),
name: tag_item.text,
id: @id_generator.new_id
})
))
end
end

Expand All @@ -69,32 +69,32 @@ def get_tags(node)

def get_table_rows(node)
rows = node.get_tokens(:TableRow).map do |token|
{
Cucumber::Messages::TableRow.new(
id: @id_generator.new_id,
location: get_location(token, 0),
cells: get_cells(token)
}
)
end
ensure_cell_count(rows)
rows
end

def ensure_cell_count(rows)
return if rows.empty?
cell_count = rows[0][:cells].length
cell_count = rows[0].cells.length
rows.each do |row|
if row[:cells].length != cell_count
raise AstBuilderException.new("inconsistent cell count within the table", row[:location])
if row.cells.length != cell_count
raise AstBuilderException.new("inconsistent cell count within the table", row.location.to_h)
end
end
end

def get_cells(table_row_token)
table_row_token.matched_items.map do |cell_item|
{
Cucumber::Messages::TableCell.new(
location: get_location(table_row_token, cell_item.column),
value: cell_item.text
}
)
end
end

Expand All @@ -113,53 +113,53 @@ def transform_node(node)
data_table = node.get_single(:DataTable)
doc_string = node.get_single(:DocString)

step = {
step = Cucumber::Messages::Step.new(
location: get_location(step_line, 0),
keyword: step_line.matched_keyword,
text: step_line.matched_text,
dataTable: data_table,
docString: doc_string,
data_table: data_table,
doc_string: doc_string,
id: @id_generator.new_id
}.delete_if {|k,v| v.nil?}
)
when :DocString
separator_token = node.get_tokens(:DocStringSeparator)[0]
media_type = separator_token.matched_text == '' ? nil : separator_token.matched_text
line_tokens = node.get_tokens(:Other)
content = line_tokens.map { |t| t.matched_text }.join("\n")

{
Cucumber::Messages::DocString.new(
location: get_location(separator_token, 0),
content: content,
delimiter: separator_token.matched_keyword,
mediaType: media_type,
}.delete_if {|k,v| v.nil?}
media_type: media_type
)
when :DataTable
rows = get_table_rows(node)
{
location: rows[0][:location],
rows: rows,
}.delete_if {|k,v| v.nil?}
Cucumber::Messages::DataTable.new(
location: rows[0].location,
rows: rows
)
when :Background
background_line = node.get_token(:BackgroundLine)
description = get_description(node)
steps = get_steps(node)

{
Cucumber::Messages::Background.new(
id: @id_generator.new_id,
location: get_location(background_line, 0),
keyword: background_line.matched_keyword,
name: background_line.matched_text,
description: description,
steps: steps
}.delete_if {|k,v| v.nil?}
)
when :ScenarioDefinition
tags = get_tags(node)
scenario_node = node.get_single(:Scenario)
scenario_line = scenario_node.get_token(:ScenarioLine)
description = get_description(scenario_node)
steps = get_steps(scenario_node)
examples = scenario_node.get_items(:ExamplesDefinition)
{
Cucumber::Messages::Scenario.new(
id: @id_generator.new_id,
tags: tags,
location: get_location(scenario_line, 0),
Expand All @@ -168,7 +168,7 @@ def transform_node(node)
description: description,
steps: steps,
examples: examples
}.delete_if {|k,v| v.nil?}
)
when :ExamplesDefinition
tags = get_tags(node)
examples_node = node.get_single(:Examples)
Expand All @@ -179,16 +179,16 @@ def transform_node(node)
table_header = rows.nil? ? nil : rows.first
table_body = rows.nil? ? [] : rows[1..-1]

{
Cucumber::Messages::Examples.new(
id: @id_generator.new_id,
tags: tags,
location: get_location(examples_line, 0),
keyword: examples_line.matched_keyword,
name: examples_line.matched_text,
description: description,
tableHeader: table_header,
tableBody: table_body,
}.delete_if {|k,v| v.nil?}
table_header: table_header,
table_body: table_body
)
when :ExamplesTable
get_table_rows(node)
when :Description
Expand All @@ -205,25 +205,25 @@ def transform_node(node)
return unless feature_line
children = []
background = node.get_single(:Background)
children.push({background: background}) if background
children.push(Cucumber::Messages::FeatureChild.new(background: background)) if background
node.get_items(:ScenarioDefinition).each do |scenario|
children.push({scenario: scenario})
children.push(Cucumber::Messages::FeatureChild.new(scenario: scenario))
end
node.get_items(:Rule).each do |rule|
children.push({rule: rule})
children.push(Cucumber::Messages::FeatureChild.new(rule: rule))
end
description = get_description(header)
language = feature_line.matched_gherkin_dialect

{
Cucumber::Messages::Feature.new(
tags: tags,
location: get_location(feature_line, 0),
language: language,
keyword: feature_line.matched_keyword,
name: feature_line.matched_text,
description: description,
children: children,
}.delete_if {|k,v| v.nil?}
)
when :Rule
header = node.get_single(:RuleHeader)
return unless header
Expand All @@ -232,27 +232,27 @@ def transform_node(node)
tags = get_tags(header)
children = []
background = node.get_single(:Background)
children.push({background: background}) if background
children.push(Cucumber::Messages::RuleChild.new(background: background)) if background
node.get_items(:ScenarioDefinition).each do |scenario|
children.push({scenario: scenario})
children.push(Cucumber::Messages::RuleChild.new(scenario: scenario))
end
description = get_description(header)

{
Cucumber::Messages::Rule.new(
id: @id_generator.new_id,
tags: tags,
location: get_location(rule_line, 0),
keyword: rule_line.matched_keyword,
name: rule_line.matched_text,
description: description,
children: children,
}.delete_if {|k,v| v.nil?}
)
when :GherkinDocument
feature = node.get_single(:Feature)
{
Cucumber::Messages::GherkinDocument.new(
comments: @comments,
feature: feature
}.delete_if {|k,v| v.nil?}
)
else
return node
end
Expand Down
Loading

0 comments on commit 57b3926

Please sign in to comment.