cucumber-gherkin 19.0.1 → 20.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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)
@@ -38,15 +38,15 @@ module Gherkin
38
38
  end
39
39
 
40
40
  def compile_rule(pickles, language, feature_tags, feature_background_steps, rule, source)
41
- tags = [].concat(feature_tags).concat(rule[:tags])
41
+ tags = [].concat(feature_tags).concat(rule.tags)
42
42
 
43
43
  rule_background_steps = feature_background_steps.dup
44
- rule[:children].each do |child|
45
- if child[:background]
46
- 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)
47
47
  else
48
- scenario = child[:scenario]
49
- if scenario[:examples].empty?
48
+ scenario = child.scenario
49
+ if scenario.examples.empty?
50
50
  compile_scenario(tags, rule_background_steps, scenario, language, pickles, source)
51
51
  else
52
52
  compile_scenario_outline(tags, rule_background_steps, scenario, language, pickles, source)
@@ -56,51 +56,51 @@ module Gherkin
56
56
  end
57
57
 
58
58
  def compile_scenario(inherited_tags, background_steps, scenario, language, pickles, source)
59
- steps = scenario[:steps].empty? ? [] : [].concat(pickle_steps(background_steps))
59
+ steps = scenario.steps.empty? ? [] : [].concat(pickle_steps(background_steps))
60
60
 
61
- tags = [].concat(inherited_tags).concat(scenario[:tags])
61
+ tags = [].concat(inherited_tags).concat(scenario.tags)
62
62
 
63
- scenario[:steps].each do |step|
63
+ scenario.steps.each do |step|
64
64
  steps.push(pickle_step(step))
65
65
  end
66
66
 
67
- pickle = {
68
- uri: source[:uri],
67
+ pickle = Cucumber::Messages::Pickle.new(
68
+ uri: source.uri,
69
69
  id: @id_generator.new_id,
70
70
  tags: pickle_tags(tags),
71
- name: scenario[:name],
71
+ name: scenario.name,
72
72
  language: language,
73
- astNodeIds: [scenario[:id]],
73
+ ast_node_ids: [scenario.id],
74
74
  steps: steps
75
- }
75
+ )
76
76
  pickles.push(pickle)
77
77
  end
78
78
 
79
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)
80
+ scenario.examples.reject { |examples| examples.table_header.nil? }.each do |examples|
81
+ variable_cells = examples.table_header.cells
82
+ examples.table_body.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_props = pickle_step_props(scenario_step, variable_cells, values_row)
89
+ steps.push(Cucumber::Messages::PickleStep.new(**step_props))
90
90
  end
91
91
 
92
- pickle = {
93
- uri: source[:uri],
92
+ pickle = Cucumber::Messages::Pickle.new(
93
+ uri: source.uri,
94
94
  id: @id_generator.new_id,
95
- name: interpolate(scenario[:name], variable_cells, value_cells),
95
+ name: interpolate(scenario.name, variable_cells, value_cells),
96
96
  language: language,
97
97
  steps: steps,
98
98
  tags: pickle_tags(tags),
99
- astNodeIds: [
100
- scenario[:id],
101
- values_row[:id]
102
- ],
103
- }
99
+ ast_node_ids: [
100
+ scenario.id,
101
+ values_row.id
102
+ ]
103
+ )
104
104
  pickles.push(pickle)
105
105
 
106
106
  end
@@ -110,7 +110,7 @@ module Gherkin
110
110
  def interpolate(name, variable_cells, value_cells)
111
111
  variable_cells.each_with_index do |variable_cell, n|
112
112
  value_cell = value_cells[n]
113
- name = name.gsub('<' + variable_cell[:value] + '>', value_cell[:value])
113
+ name = name.gsub('<' + variable_cell.value + '>', value_cell.value)
114
114
  end
115
115
  name
116
116
  end
@@ -122,57 +122,57 @@ module Gherkin
122
122
  end
123
123
 
124
124
  def pickle_step(step)
125
- pickle_step_props(step, [], nil)
125
+ Cucumber::Messages::PickleStep.new(**pickle_step_props(step, [], nil))
126
126
  end
127
127
 
128
128
  def pickle_step_props(step, variable_cells, values_row)
129
- value_cells = values_row ? values_row[:cells] : []
129
+ value_cells = values_row ? values_row.cells : []
130
130
  props = {
131
131
  id: @id_generator.new_id,
132
- astNodeIds: [step[:id]],
133
- text: interpolate(step[:text], variable_cells, value_cells),
132
+ ast_node_ids: [step.id],
133
+ text: interpolate(step.text, variable_cells, value_cells),
134
134
  }
135
135
  if values_row
136
- props[:astNodeIds].push(values_row[:id])
136
+ props[:ast_node_ids].push(values_row.id)
137
137
  end
138
138
 
139
- if step[:dataTable]
140
- data_table = {
141
- dataTable: pickle_data_table(step[:dataTable], variable_cells, value_cells)
142
- }
139
+ if step.data_table
140
+ data_table = Cucumber::Messages::PickleStepArgument.new(
141
+ data_table: pickle_data_table(step.data_table, variable_cells, value_cells)
142
+ )
143
143
  props[:argument] = data_table
144
144
  end
145
- if step[:docString]
146
- doc_string = {
147
- docString: pickle_doc_string(step[:docString], variable_cells, value_cells)
148
- }
145
+ if step.doc_string
146
+ doc_string = Cucumber::Messages::PickleStepArgument.new(
147
+ doc_string: pickle_doc_string(step.doc_string, variable_cells, value_cells)
148
+ )
149
149
  props[:argument] = doc_string
150
150
  end
151
151
  props
152
152
  end
153
153
 
154
154
  def pickle_data_table(data_table, variable_cells, value_cells)
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
- }
155
+ Cucumber::Messages::PickleTable.new(
156
+ rows: data_table.rows.map do |row|
157
+ Cucumber::Messages::PickleTableRow.new(
158
+ cells: row.cells.map do |cell|
159
+ Cucumber::Messages::PickleTableCell.new(
160
+ value: interpolate(cell.value, variable_cells, value_cells)
161
+ )
162
162
  end
163
- }
163
+ )
164
164
  end
165
- }
165
+ )
166
166
  end
167
167
 
168
168
  def pickle_doc_string(doc_string, variable_cells, value_cells)
169
169
  props = {
170
- content: interpolate(doc_string[:content], variable_cells, value_cells)
170
+ content: interpolate(doc_string.content, variable_cells, value_cells)
171
171
  }
172
- if doc_string[:mediaType]
173
- props[:mediaType] = interpolate(doc_string[:mediaType], variable_cells, value_cells)
172
+ if doc_string.media_type
173
+ props[:media_type] = interpolate(doc_string.media_type, variable_cells, value_cells)
174
174
  end
175
- props
175
+ Cucumber::Messages::PickleDocString.new(**props)
176
176
  end
177
177
 
178
178
  def pickle_tags(tags)
@@ -180,10 +180,10 @@ module Gherkin
180
180
  end
181
181
 
182
182
  def pickle_tag(tag)
183
- {
184
- name: tag[:name],
185
- astNodeId: tag[:id]
186
- }
183
+ Cucumber::Messages::PickleTag.new(
184
+ name: tag.name,
185
+ ast_node_id: tag.id
186
+ )
187
187
  end
188
188
  end
189
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[:gherkinDocument][:feature]) if message[:gherkinDocument]
8
+ update_feature(message.gherkin_document.feature) if message.gherkin_document
9
9
  end
10
10
 
11
11
  def location(ast_node_id)
@@ -17,33 +17,36 @@ 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
+ return if rule.nil?
31
+ store_nodes_location(rule.tags)
32
+
33
+ rule.children.each do |child|
34
+ update_background(child.background) if child.background
35
+ update_scenario(child.scenario) if child.scenario
33
36
  end
34
37
  end
35
38
 
36
39
  def update_background(background)
37
- update_steps(background[:steps])
40
+ update_steps(background.steps)
38
41
  end
39
42
 
40
43
  def update_scenario(scenario)
41
44
  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[:tableBody] || [])
45
+ store_nodes_location(scenario.tags)
46
+ update_steps(scenario.steps)
47
+ scenario.examples.each do |examples|
48
+ store_nodes_location(examples.tags || [])
49
+ store_nodes_location(examples.table_body || [])
47
50
  end
48
51
  end
49
52
 
@@ -56,7 +59,7 @@ module Gherkin
56
59
  end
57
60
 
58
61
  def store_node_location(node)
59
- @ast_node_locations[node[:id]] = node[:location]
62
+ @ast_node_locations[node.id] = node.location
60
63
  end
61
64
  end
62
65
  end
@@ -23,25 +23,25 @@ module Gherkin
23
23
  enumerated = true
24
24
 
25
25
  sources.each do |source|
26
- y.yield({source: source}) if @options[:include_source]
26
+ y.yield(Cucumber::Messages::Envelope.new(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({gherkinDocument: gherkin_document})
32
+ y.yield(Cucumber::Messages::Envelope.new(gherkin_document: 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({pickle: pickle})
38
+ y.yield(Cucumber::Messages::Envelope.new(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 = {
55
- source: {
54
+ parse_error = Cucumber::Messages::ParseError.new(
55
+ source: Cucumber::Messages::SourceReference.new(
56
56
  uri: uri,
57
- location: {
57
+ location: Cucumber::Messages::Location.new(
58
58
  line: err.location[:line],
59
59
  column: err.location[:column]
60
- }.delete_if {|k,v| v.nil?}
61
- },
60
+ )
61
+ ),
62
62
  message: err.message
63
- }
64
- y.yield({parseError: parse_error})
63
+ )
64
+ y.yield(Cucumber::Messages::Envelope.new(parse_error: 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 = {
71
+ source = Cucumber::Messages::Source.new(
72
72
  uri: path,
73
73
  data: File.open(path, 'r:UTF-8', &:read),
74
- mediaType: 'text/x.cucumber.gherkin+plain'
75
- }
74
+ media_type: 'text/x.cucumber.gherkin+plain'
75
+ )
76
76
  y.yield(source)
77
77
  end
78
78
  @sources.each do |source|
@@ -84,12 +84,15 @@ 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
- gd
91
+ Cucumber::Messages::GherkinDocument.new(
92
+ uri: source.uri,
93
+ feature: gd.feature,
94
+ comments: gd.comments
95
+ )
93
96
  end
94
97
  end
95
98
  end
@@ -6,16 +6,19 @@ describe Gherkin::Query do
6
6
  let(:subject) { Gherkin::Query.new }
7
7
 
8
8
  def filter_messages_by_attribute(messages, attribute)
9
- messages.select { |message| message.has_key?(attribute) }.map { |message| message[attribute] }
9
+ messages.map do |message|
10
+ return unless message.respond_to?(attribute)
11
+ message.send(attribute)
12
+ end.compact
10
13
  end
11
14
 
12
15
  def find_message_by_attribute(messages, attribute)
13
16
  filter_messages_by_attribute(messages, attribute).first
14
17
  end
15
18
 
16
- let(:gherkin_document) { find_message_by_attribute(messages, :gherkinDocument) }
19
+ let(:gherkin_document) { find_message_by_attribute(messages, :gherkin_document) }
17
20
 
18
- let(:messages) {
21
+ let(:messages) do
19
22
  Gherkin.from_source(
20
23
  "some/path",
21
24
  feature_content,
@@ -23,9 +26,9 @@ describe Gherkin::Query do
23
26
  include_gherkin_document: true
24
27
  }
25
28
  ).to_a
26
- }
29
+ end
27
30
 
28
- let(:feature_content) {
31
+ let(:feature_content) do
29
32
  """
30
33
  @feature-tag
31
34
  Feature: my feature
@@ -40,12 +43,12 @@ describe Gherkin::Query do
40
43
  Scenario Outline: with examples
41
44
  Given a <Status> step
42
45
 
43
- @example-tag
46
+ @examples-tag
44
47
  Examples:
45
48
  | Status |
46
49
  | passed |
47
50
 
48
-
51
+ @rule-tag
49
52
  Rule: this is a rule
50
53
  Background:
51
54
  Given the passed step in the rule background
@@ -53,32 +56,29 @@ describe Gherkin::Query do
53
56
  @ruled-scenario-tag
54
57
  Scenario: a ruled scenario
55
58
  Given a step in the ruled scenario
56
- """
57
- }
59
+ """
60
+ end
58
61
 
59
- context '#update' do
62
+ describe '#update' do
60
63
  context 'when the feature file is empty' do
61
64
  let(:feature_content) { '' }
62
65
 
63
66
  it 'does not fail' do
64
- expect {
65
- messages.each { |message|
66
- subject.update(message)
67
- }
68
- }.not_to raise_exception
67
+ expect do
68
+ messages.each { |message| subject.update(message) }
69
+ end.not_to raise_exception
69
70
  end
70
71
  end
71
72
  end
72
73
 
73
- context '#location' do
74
+ describe '#location' do
74
75
  before do
75
- messages.each { |message|
76
- subject.update(message)
77
- }
76
+ messages.each { |message| subject.update(message) }
78
77
  end
79
78
 
80
- let(:background) { find_message_by_attribute(gherkin_document[:feature][:children], :background) }
81
- let(:scenarios) { filter_messages_by_attribute(gherkin_document[:feature][:children], :scenario) }
79
+ let(:background) { find_message_by_attribute(gherkin_document.feature.children, :background) }
80
+ let(:rule) { find_message_by_attribute(gherkin_document.feature.children, :rule) }
81
+ let(:scenarios) { filter_messages_by_attribute(gherkin_document.feature.children, :scenario) }
82
82
  let(:scenario) { scenarios.first }
83
83
 
84
84
  it 'raises an exception when the AST node ID is unknown' do
@@ -86,67 +86,71 @@ describe Gherkin::Query do
86
86
  end
87
87
 
88
88
  it 'provides the location of a scenario' do
89
- expect(subject.location(scenario[:id])).to eq(scenario[:location])
89
+ expect(subject.location(scenario.id)).to eq(scenario.location)
90
90
  end
91
91
 
92
92
  it 'provides the location of an examples table row' do
93
- node = scenarios.last[:examples].first[:tableBody].first
94
- expect(subject.location(node[:id])).to eq(node[:location])
93
+ node = scenarios.last.examples.first.table_body.first
94
+ expect(subject.location(node.id)).to eq(node.location)
95
95
  end
96
96
 
97
97
  context 'when querying steps' do
98
- let(:background_step) { background[:steps].first }
99
- let(:scenario_step) { scenario[:steps].first }
98
+ let(:background_step) { background.steps.first }
99
+ let(:scenario_step) { scenario.steps.first }
100
100
 
101
101
  it 'provides the location of a background step' do
102
- expect(subject.location(background_step[:id])).to eq(background_step[:location])
102
+ expect(subject.location(background_step.id)).to eq(background_step.location)
103
103
  end
104
104
 
105
105
  it 'provides the location of a scenario step' do
106
- expect(subject.location(scenario_step[:id])).to eq(scenario_step[:location])
106
+ expect(subject.location(scenario_step.id)).to eq(scenario_step.location)
107
107
  end
108
108
  end
109
109
 
110
110
  context 'when querying tags' do
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 }
111
+ let(:feature_tag) { gherkin_document.feature.tags.first }
112
+ let(:rule_tag) { rule.tags.first }
113
+ let(:scenario_tag) { scenario.tags.first }
114
+ let(:examples_tag) { scenarios.last.examples.first.tags.first }
114
115
 
115
116
  it 'provides the location of a feature tags' do
116
- expect(subject.location(feature_tag[:id])).to eq(feature_tag[:location])
117
+ expect(subject.location(feature_tag.id)).to eq(feature_tag.location)
117
118
  end
118
119
 
119
120
  it 'provides the location of a scenario tags' do
120
- expect(subject.location(scenario_tag[:id])).to eq(scenario_tag[:location])
121
+ expect(subject.location(scenario_tag.id)).to eq(scenario_tag.location)
122
+ end
123
+
124
+ it 'provides the location of scenario examples tags' do
125
+ expect(subject.location(examples_tag.id)).to eq(examples_tag.location)
121
126
  end
122
127
 
123
- it 'provides the location of a scenario example tags' do
124
- expect(subject.location(example_tag[:id])).to eq(example_tag[:location])
128
+ it 'provides the location of a rule tag' do
129
+ expect(subject.location(rule_tag.id)).to eq(rule_tag.location)
125
130
  end
126
131
  end
127
132
 
128
133
  context 'when children are scoped in a Rule' do
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 }
134
+ let(:rule_background) { find_message_by_attribute(rule.children, :background) }
135
+ let(:rule_background_step) { rule_background.steps.first }
136
+ let(:rule_scenario) { find_message_by_attribute(rule.children, :scenario) }
137
+ let(:rule_scenario_step) { rule_scenario.steps.first }
138
+ let(:rule_scenario_tag) { rule_scenario.tags.first }
135
139
 
136
140
  it 'provides the location of a background step' do
137
- expect(subject.location(rule_background_step[:id])).to eq(rule_background_step[:location])
141
+ expect(subject.location(rule_background_step.id)).to eq(rule_background_step.location)
138
142
  end
139
143
 
140
144
  it 'provides the location of a scenario' do
141
- expect(subject.location(rule_scenario[:id])).to eq(rule_scenario[:location])
145
+ expect(subject.location(rule_scenario.id)).to eq(rule_scenario.location)
142
146
  end
143
147
 
144
148
  it 'provides the location of a scenario tag' do
145
- expect(subject.location(rule_scenario_tag[:id])).to eq(rule_scenario_tag[:location])
149
+ expect(subject.location(rule_scenario_tag.id)).to eq(rule_scenario_tag.location)
146
150
  end
147
151
 
148
152
  it 'provides the location of a scenario step' do
149
- expect(subject.location(rule_scenario_step[:id])).to eq(rule_scenario_step[:location])
153
+ expect(subject.location(rule_scenario_step.id)).to eq(rule_scenario_step.location)
150
154
  end
151
155
  end
152
156
  end