cucumber-gherkin 17.0.1 → 19.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,10 +8,10 @@ module Gherkin
8
8
  def compile(gherkin_document, source)
9
9
  pickles = []
10
10
 
11
- return pickles unless gherkin_document.feature
12
- feature = gherkin_document.feature
13
- language = feature.language
14
- tags = feature.tags
11
+ return pickles unless gherkin_document[:feature]
12
+ feature = gherkin_document[:feature]
13
+ language = feature[:language]
14
+ tags = feature[:tags]
15
15
 
16
16
  compile_feature(pickles, language, tags, feature, source)
17
17
  pickles
@@ -21,14 +21,14 @@ module Gherkin
21
21
 
22
22
  def compile_feature(pickles, language, tags, feature, source)
23
23
  feature_background_steps = []
24
- feature.children.each do |child|
25
- if child.background
26
- feature_background_steps.concat(child.background.steps)
27
- elsif child.rule
28
- compile_rule(pickles, language, tags, feature_background_steps, child.rule, source)
24
+ feature[:children].each do |child|
25
+ if child[:background]
26
+ feature_background_steps.concat(child[:background][:steps])
27
+ elsif child[:rule]
28
+ compile_rule(pickles, language, tags, feature_background_steps, child[:rule], source)
29
29
  else
30
- scenario = child.scenario
31
- if scenario.examples.empty?
30
+ scenario = child[:scenario]
31
+ if scenario[:examples].empty?
32
32
  compile_scenario(tags, feature_background_steps, scenario, language, pickles, source)
33
33
  else
34
34
  compile_scenario_outline(tags, feature_background_steps, scenario, language, pickles, source)
@@ -37,14 +37,16 @@ module Gherkin
37
37
  end
38
38
  end
39
39
 
40
- def compile_rule(pickles, language, tags, feature_background_steps, rule, source)
40
+ def compile_rule(pickles, language, feature_tags, feature_background_steps, rule, source)
41
+ tags = [].concat(feature_tags).concat(rule[:tags])
42
+
41
43
  rule_background_steps = feature_background_steps.dup
42
- rule.children.each do |child|
43
- if child.background
44
- rule_background_steps.concat(child.background.steps)
44
+ rule[:children].each do |child|
45
+ if child[:background]
46
+ rule_background_steps.concat(child[:background][:steps])
45
47
  else
46
- scenario = child.scenario
47
- if scenario.examples.empty?
48
+ scenario = child[:scenario]
49
+ if scenario[:examples].empty?
48
50
  compile_scenario(tags, rule_background_steps, scenario, language, pickles, source)
49
51
  else
50
52
  compile_scenario_outline(tags, rule_background_steps, scenario, language, pickles, source)
@@ -53,52 +55,52 @@ module Gherkin
53
55
  end
54
56
  end
55
57
 
56
- def compile_scenario(feature_tags, background_steps, scenario, language, pickles, source)
57
- steps = scenario.steps.empty? ? [] : [].concat(pickle_steps(background_steps))
58
+ def compile_scenario(inherited_tags, background_steps, scenario, language, pickles, source)
59
+ steps = scenario[:steps].empty? ? [] : [].concat(pickle_steps(background_steps))
58
60
 
59
- tags = [].concat(feature_tags).concat(scenario.tags)
61
+ tags = [].concat(inherited_tags).concat(scenario[:tags])
60
62
 
61
- scenario.steps.each do |step|
63
+ scenario[:steps].each do |step|
62
64
  steps.push(pickle_step(step))
63
65
  end
64
66
 
65
- pickle = Cucumber::Messages::Pickle.new(
66
- uri: source.uri,
67
+ pickle = {
68
+ uri: source[:uri],
67
69
  id: @id_generator.new_id,
68
70
  tags: pickle_tags(tags),
69
- name: scenario.name,
71
+ name: scenario[:name],
70
72
  language: language,
71
- ast_node_ids: [scenario.id],
73
+ astNodeIds: [scenario[:id]],
72
74
  steps: steps
73
- )
75
+ }
74
76
  pickles.push(pickle)
75
77
  end
76
78
 
77
- def compile_scenario_outline(feature_tags, background_steps, scenario, language, pickles, source)
78
- scenario.examples.reject { |examples| examples.table_header.nil? }.each do |examples|
79
- variable_cells = examples.table_header.cells
80
- examples.table_body.each do |values_row|
81
- value_cells = values_row.cells
82
- steps = scenario.steps.empty? ? [] : [].concat(pickle_steps(background_steps))
83
- tags = [].concat(feature_tags).concat(scenario.tags).concat(examples.tags)
84
-
85
- scenario.steps.each do |scenario_outline_step|
86
- step_props = pickle_step_props(scenario_outline_step, variable_cells, values_row)
87
- steps.push(Cucumber::Messages::Pickle::PickleStep.new(step_props))
79
+ def compile_scenario_outline(inherited_tags, background_steps, scenario, language, pickles, source)
80
+ scenario[:examples].reject { |examples| examples[:tableHeader].nil? }.each do |examples|
81
+ variable_cells = examples[:tableHeader][:cells]
82
+ examples[:tableBody].each do |values_row|
83
+ value_cells = values_row[:cells]
84
+ steps = scenario[:steps].empty? ? [] : [].concat(pickle_steps(background_steps))
85
+ tags = [].concat(inherited_tags).concat(scenario[:tags]).concat(examples[:tags])
86
+
87
+ scenario[:steps].each do |scenario_step|
88
+ step = pickle_step_props(scenario_step, variable_cells, values_row)
89
+ steps.push(step)
88
90
  end
89
91
 
90
- pickle = Cucumber::Messages::Pickle.new(
91
- uri: source.uri,
92
+ pickle = {
93
+ uri: source[:uri],
92
94
  id: @id_generator.new_id,
93
- name: interpolate(scenario.name, variable_cells, value_cells),
95
+ name: interpolate(scenario[:name], variable_cells, value_cells),
94
96
  language: language,
95
97
  steps: steps,
96
98
  tags: pickle_tags(tags),
97
- ast_node_ids: [
98
- scenario.id,
99
- values_row.id
99
+ astNodeIds: [
100
+ scenario[:id],
101
+ values_row[:id]
100
102
  ],
101
- )
103
+ }
102
104
  pickles.push(pickle)
103
105
 
104
106
  end
@@ -108,7 +110,7 @@ module Gherkin
108
110
  def interpolate(name, variable_cells, value_cells)
109
111
  variable_cells.each_with_index do |variable_cell, n|
110
112
  value_cell = value_cells[n]
111
- name = name.gsub('<' + variable_cell.value + '>', value_cell.value)
113
+ name = name.gsub('<' + variable_cell[:value] + '>', value_cell[:value])
112
114
  end
113
115
  name
114
116
  end
@@ -120,57 +122,57 @@ module Gherkin
120
122
  end
121
123
 
122
124
  def pickle_step(step)
123
- Cucumber::Messages::Pickle::PickleStep.new(pickle_step_props(step, [], nil))
125
+ pickle_step_props(step, [], nil)
124
126
  end
125
127
 
126
128
  def pickle_step_props(step, variable_cells, values_row)
127
- value_cells = values_row ? values_row.cells : []
129
+ value_cells = values_row ? values_row[:cells] : []
128
130
  props = {
129
131
  id: @id_generator.new_id,
130
- ast_node_ids: [step.id],
131
- text: interpolate(step.text, variable_cells, value_cells),
132
+ astNodeIds: [step[:id]],
133
+ text: interpolate(step[:text], variable_cells, value_cells),
132
134
  }
133
135
  if values_row
134
- props[:ast_node_ids].push(values_row.id)
136
+ props[:astNodeIds].push(values_row[:id])
135
137
  end
136
138
 
137
- if step.data_table
138
- data_table = Cucumber::Messages::PickleStepArgument.new(
139
- data_table: pickle_data_table(step.data_table, variable_cells, value_cells)
140
- )
139
+ if step[:dataTable]
140
+ data_table = {
141
+ dataTable: pickle_data_table(step[:dataTable], variable_cells, value_cells)
142
+ }
141
143
  props[:argument] = data_table
142
144
  end
143
- if step.doc_string
144
- doc_string = Cucumber::Messages::PickleStepArgument.new(
145
- doc_string: pickle_doc_string(step.doc_string, variable_cells, value_cells)
146
- )
145
+ if step[:docString]
146
+ doc_string = {
147
+ docString: pickle_doc_string(step[:docString], variable_cells, value_cells)
148
+ }
147
149
  props[:argument] = doc_string
148
150
  end
149
151
  props
150
152
  end
151
153
 
152
154
  def pickle_data_table(data_table, variable_cells, value_cells)
153
- Cucumber::Messages::PickleStepArgument::PickleTable.new(
154
- rows: data_table.rows.map do |row|
155
- Cucumber::Messages::PickleStepArgument::PickleTable::PickleTableRow.new(
156
- cells: row.cells.map do |cell|
157
- Cucumber::Messages::PickleStepArgument::PickleTable::PickleTableRow::PickleTableCell.new(
158
- value: interpolate(cell.value, variable_cells, value_cells)
159
- )
155
+ {
156
+ rows: data_table[:rows].map do |row|
157
+ {
158
+ cells: row[:cells].map do |cell|
159
+ {
160
+ value: interpolate(cell[:value], variable_cells, value_cells)
161
+ }
160
162
  end
161
- )
163
+ }
162
164
  end
163
- )
165
+ }
164
166
  end
165
167
 
166
168
  def pickle_doc_string(doc_string, variable_cells, value_cells)
167
169
  props = {
168
- content: interpolate(doc_string.content, variable_cells, value_cells)
170
+ content: interpolate(doc_string[:content], variable_cells, value_cells)
169
171
  }
170
- if doc_string.media_type
171
- props[:media_type] = interpolate(doc_string.media_type, variable_cells, value_cells)
172
+ if doc_string[:mediaType]
173
+ props[:mediaType] = interpolate(doc_string[:mediaType], variable_cells, value_cells)
172
174
  end
173
- Cucumber::Messages::PickleStepArgument::PickleDocString.new(props)
175
+ props
174
176
  end
175
177
 
176
178
  def pickle_tags(tags)
@@ -178,10 +180,10 @@ module Gherkin
178
180
  end
179
181
 
180
182
  def pickle_tag(tag)
181
- Cucumber::Messages::Pickle::PickleTag.new(
182
- name: tag.name,
183
- ast_node_id: tag.id
184
- )
183
+ {
184
+ name: tag[:name],
185
+ astNodeId: tag[:id]
186
+ }
185
187
  end
186
188
  end
187
189
  end
data/lib/gherkin/query.rb CHANGED
@@ -5,7 +5,7 @@ module Gherkin
5
5
  end
6
6
 
7
7
  def update(message)
8
- update_feature(message.gherkin_document.feature) if message.gherkin_document
8
+ update_feature(message[:gherkinDocument][:feature]) if message[:gherkinDocument]
9
9
  end
10
10
 
11
11
  def location(ast_node_id)
@@ -17,33 +17,33 @@ module Gherkin
17
17
 
18
18
  def update_feature(feature)
19
19
  return if feature.nil?
20
- store_nodes_location(feature.tags)
20
+ store_nodes_location(feature[:tags])
21
21
 
22
- feature.children.each do |child|
23
- update_rule(child.rule) if child.rule
24
- update_background(child.background) if child.background
25
- update_scenario(child.scenario) if child.scenario
22
+ feature[:children].each do |child|
23
+ update_rule(child[:rule]) if child[:rule]
24
+ update_background(child[:background]) if child[:background]
25
+ update_scenario(child[:scenario]) if child[:scenario]
26
26
  end
27
27
  end
28
28
 
29
29
  def update_rule(rule)
30
- rule.children.each do |child|
31
- update_background(child.background) if child.background
32
- update_scenario(child.scenario) if child.scenario
30
+ rule[:children].each do |child|
31
+ update_background(child[:background]) if child[:background]
32
+ update_scenario(child[:scenario]) if child[:scenario]
33
33
  end
34
34
  end
35
35
 
36
36
  def update_background(background)
37
- update_steps(background.steps)
37
+ update_steps(background[:steps])
38
38
  end
39
39
 
40
40
  def update_scenario(scenario)
41
41
  store_node_location(scenario)
42
- store_nodes_location(scenario.tags)
43
- update_steps(scenario.steps)
44
- scenario.examples.each do |examples|
45
- store_nodes_location(examples.tags)
46
- store_nodes_location(examples.table_body)
42
+ store_nodes_location(scenario[:tags])
43
+ update_steps(scenario[:steps])
44
+ scenario[:examples].each do |examples|
45
+ store_nodes_location(examples[:tags] || [])
46
+ store_nodes_location(examples[:tableBody] || [])
47
47
  end
48
48
  end
49
49
 
@@ -56,7 +56,7 @@ module Gherkin
56
56
  end
57
57
 
58
58
  def store_node_location(node)
59
- @ast_node_locations[node.id] = node.location
59
+ @ast_node_locations[node[:id]] = node[:location]
60
60
  end
61
61
  end
62
62
  end
@@ -23,25 +23,25 @@ module Gherkin
23
23
  enumerated = true
24
24
 
25
25
  sources.each do |source|
26
- y.yield(Cucumber::Messages::Envelope.new(source: source)) if @options[:include_source]
26
+ y.yield({source: source}) if @options[:include_source]
27
27
  begin
28
28
  gherkin_document = nil
29
29
 
30
30
  if @options[:include_gherkin_document]
31
31
  gherkin_document = build_gherkin_document(source)
32
- y.yield(Cucumber::Messages::Envelope.new(gherkin_document: gherkin_document))
32
+ y.yield({gherkinDocument: gherkin_document})
33
33
  end
34
34
  if @options[:include_pickles]
35
35
  gherkin_document ||= build_gherkin_document(source)
36
36
  pickles = @compiler.compile(gherkin_document, source)
37
37
  pickles.each do |pickle|
38
- y.yield(Cucumber::Messages::Envelope.new(pickle: pickle))
38
+ y.yield({pickle: pickle})
39
39
  end
40
40
  end
41
41
  rescue CompositeParserException => err
42
- yield_parse_errors(y, err.errors, source.uri)
42
+ yield_parse_errors(y, err.errors, source[:uri])
43
43
  rescue ParserException => err
44
- yield_parse_errors(y, [err], source.uri)
44
+ yield_parse_errors(y, [err], source[:uri])
45
45
  end
46
46
  end
47
47
  end
@@ -51,28 +51,28 @@ module Gherkin
51
51
 
52
52
  def yield_parse_errors(y, errors, uri)
53
53
  errors.each do |err|
54
- parse_error = Cucumber::Messages::ParseError.new(
55
- source: Cucumber::Messages::SourceReference.new(
54
+ parse_error = {
55
+ source: {
56
56
  uri: uri,
57
- location: Cucumber::Messages::Location.new(
57
+ location: {
58
58
  line: err.location[:line],
59
59
  column: err.location[:column]
60
- )
61
- ),
60
+ }.delete_if {|k,v| v.nil?}
61
+ },
62
62
  message: err.message
63
- )
64
- y.yield(Cucumber::Messages::Envelope.new(parse_error: parse_error))
63
+ }
64
+ y.yield({parseError: parse_error})
65
65
  end
66
66
  end
67
67
 
68
68
  def sources
69
69
  Enumerator.new do |y|
70
70
  @paths.each do |path|
71
- source = Cucumber::Messages::Source.new(
71
+ source = {
72
72
  uri: path,
73
73
  data: File.open(path, 'r:UTF-8', &:read),
74
- media_type: 'text/x.cucumber.gherkin+plain'
75
- )
74
+ mediaType: 'text/x.cucumber.gherkin+plain'
75
+ }
76
76
  y.yield(source)
77
77
  end
78
78
  @sources.each do |source|
@@ -84,12 +84,12 @@ module Gherkin
84
84
  def build_gherkin_document(source)
85
85
  if @options[:default_dialect]
86
86
  token_matcher = TokenMatcher.new(@options[:default_dialect])
87
- gd = @parser.parse(source.data, token_matcher)
87
+ gd = @parser.parse(source[:data], token_matcher)
88
88
  else
89
- gd = @parser.parse(source.data)
89
+ gd = @parser.parse(source[:data])
90
90
  end
91
- gd[:uri] = source.uri
92
- Cucumber::Messages::GherkinDocument.new(gd)
91
+ gd[:uri] = source[:uri]
92
+ gd
93
93
  end
94
94
  end
95
95
  end
@@ -25,7 +25,7 @@ module Gherkin
25
25
  end
26
26
 
27
27
  def read
28
- location = {line: @line_number += 1, column: 0}
28
+ location = {line: @line_number += 1}
29
29
  if @io.nil? || line = @io.gets
30
30
  gherkin_line = line ? GherkinLine.new(line, location[:line]) : nil
31
31
  Token.new(gherkin_line, location)
@@ -2,7 +2,17 @@ require 'rspec'
2
2
  require 'gherkin/gherkin_line'
3
3
 
4
4
  describe Gherkin::GherkinLine do
5
- context '#table_cell' do
5
+ context '#tags' do
6
+ def tags(line)
7
+ Gherkin::GherkinLine.new(line, 12).tags.map(&:text)
8
+ end
9
+
10
+ it 'allows any non-space characters in a tag' do
11
+ expect(tags(" @foo:bar @zap🥒yo")).to eq(['@foo:bar', '@zap🥒yo'])
12
+ end
13
+ end
14
+
15
+ context '#table_cells' do
6
16
  def cells_text(line)
7
17
  Gherkin::GherkinLine.new(line, 12).table_cells.map(&:text)
8
18
  end
@@ -3,20 +3,17 @@ require 'gherkin'
3
3
  require 'gherkin/query'
4
4
 
5
5
  describe Gherkin::Query do
6
- let(:subject) { Gherkin::Query.new() }
6
+ let(:subject) { Gherkin::Query.new }
7
7
 
8
8
  def filter_messages_by_attribute(messages, attribute)
9
- messages.map do |message|
10
- return unless message.respond_to?(attribute)
11
- message.send(attribute)
12
- end.compact
9
+ messages.select { |message| message.has_key?(attribute) }.map { |message| message[attribute] }
13
10
  end
14
11
 
15
12
  def find_message_by_attribute(messages, attribute)
16
13
  filter_messages_by_attribute(messages, attribute).first
17
14
  end
18
15
 
19
- let(:gherkin_document) { find_message_by_attribute(messages, :gherkin_document) }
16
+ let(:gherkin_document) { find_message_by_attribute(messages, :gherkinDocument) }
20
17
 
21
18
  let(:messages) {
22
19
  Gherkin.from_source(
@@ -80,8 +77,8 @@ describe Gherkin::Query do
80
77
  }
81
78
  end
82
79
 
83
- let(:background) { find_message_by_attribute(gherkin_document.feature.children, :background) }
84
- let(:scenarios) { filter_messages_by_attribute(gherkin_document.feature.children, :scenario) }
80
+ let(:background) { find_message_by_attribute(gherkin_document[:feature][:children], :background) }
81
+ let(:scenarios) { filter_messages_by_attribute(gherkin_document[:feature][:children], :scenario) }
85
82
  let(:scenario) { scenarios.first }
86
83
 
87
84
  it 'raises an exception when the AST node ID is unknown' do
@@ -89,68 +86,68 @@ describe Gherkin::Query do
89
86
  end
90
87
 
91
88
  it 'provides the location of a scenario' do
92
- expect(subject.location(scenario.id)).to eq(scenario.location)
89
+ expect(subject.location(scenario[:id])).to eq(scenario[:location])
93
90
  end
94
91
 
95
92
  it 'provides the location of an examples table row' do
96
- node = scenarios.last.examples.first.table_body.first
97
- expect(subject.location(node.id)).to eq(node.location)
93
+ node = scenarios.last[:examples].first[:tableBody].first
94
+ expect(subject.location(node[:id])).to eq(node[:location])
98
95
  end
99
96
 
100
97
  context 'when querying steps' do
101
- let(:background_step) { background.steps.first }
102
- let(:scenario_step) { scenario.steps.first }
98
+ let(:background_step) { background[:steps].first }
99
+ let(:scenario_step) { scenario[:steps].first }
103
100
 
104
101
  it 'provides the location of a background step' do
105
- expect(subject.location(background_step.id)).to eq(background_step.location)
102
+ expect(subject.location(background_step[:id])).to eq(background_step[:location])
106
103
  end
107
104
 
108
105
  it 'provides the location of a scenario step' do
109
- expect(subject.location(scenario_step.id)).to eq(scenario_step.location)
106
+ expect(subject.location(scenario_step[:id])).to eq(scenario_step[:location])
110
107
  end
111
108
  end
112
109
 
113
110
  context 'when querying tags' do
114
- let(:feature_tag) { gherkin_document.feature.tags.first }
115
- let(:scenario_tag) { scenario.tags.first }
116
- let(:example_tag) { scenarios.last.examples.first.tags.first }
111
+ let(:feature_tag) { gherkin_document[:feature][:tags].first }
112
+ let(:scenario_tag) { scenario[:tags].first }
113
+ let(:example_tag) { scenarios.last[:examples].first[:tags].first }
117
114
 
118
115
  it 'provides the location of a feature tags' do
119
- expect(subject.location(feature_tag.id)).to eq(feature_tag.location)
116
+ expect(subject.location(feature_tag[:id])).to eq(feature_tag[:location])
120
117
  end
121
118
 
122
119
  it 'provides the location of a scenario tags' do
123
- expect(subject.location(scenario_tag.id)).to eq(scenario_tag.location)
120
+ expect(subject.location(scenario_tag[:id])).to eq(scenario_tag[:location])
124
121
  end
125
122
 
126
123
  it 'provides the location of a scenario example tags' do
127
- expect(subject.location(example_tag.id)).to eq(example_tag.location)
124
+ expect(subject.location(example_tag[:id])).to eq(example_tag[:location])
128
125
  end
129
126
  end
130
127
 
131
128
  context 'when children are scoped in a Rule' do
132
- let(:rule) { find_message_by_attribute(gherkin_document.feature.children, :rule) }
133
- let(:rule_background) { find_message_by_attribute(rule.children, :background) }
134
- let(:rule_background_step) { rule_background.steps.first }
135
- let(:rule_scenario) { find_message_by_attribute(rule.children, :scenario) }
136
- let(:rule_scenario_step) { rule_scenario.steps.first }
137
- let(:rule_scenario_tag) { rule_scenario.tags.first }
129
+ let(:rule) { find_message_by_attribute(gherkin_document[:feature][:children], :rule) }
130
+ let(:rule_background) { find_message_by_attribute(rule[:children], :background) }
131
+ let(:rule_background_step) { rule_background[:steps].first }
132
+ let(:rule_scenario) { find_message_by_attribute(rule[:children], :scenario) }
133
+ let(:rule_scenario_step) { rule_scenario[:steps].first }
134
+ let(:rule_scenario_tag) { rule_scenario[:tags].first }
138
135
 
139
136
  it 'provides the location of a background step' do
140
- expect(subject.location(rule_background_step.id)).to eq(rule_background_step.location)
137
+ expect(subject.location(rule_background_step[:id])).to eq(rule_background_step[:location])
141
138
  end
142
139
 
143
140
  it 'provides the location of a scenario' do
144
- expect(subject.location(rule_scenario.id)).to eq(rule_scenario.location)
141
+ expect(subject.location(rule_scenario[:id])).to eq(rule_scenario[:location])
145
142
  end
146
143
 
147
144
  it 'provides the location of a scenario tag' do
148
- expect(subject.location(rule_scenario_tag.id)).to eq(rule_scenario_tag.location)
145
+ expect(subject.location(rule_scenario_tag[:id])).to eq(rule_scenario_tag[:location])
149
146
  end
150
147
 
151
148
  it 'provides the location of a scenario step' do
152
- expect(subject.location(rule_scenario_step.id)).to eq(rule_scenario_step.location)
149
+ expect(subject.location(rule_scenario_step[:id])).to eq(rule_scenario_step[:location])
153
150
  end
154
151
  end
155
152
  end
156
- end
153
+ end