cucumber 3.2.0 → 4.1.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.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +192 -19
  3. data/CONTRIBUTING.md +2 -18
  4. data/README.md +4 -5
  5. data/bin/cucumber +1 -1
  6. data/lib/autotest/cucumber_mixin.rb +34 -39
  7. data/lib/cucumber/cli/configuration.rb +5 -5
  8. data/lib/cucumber/cli/main.rb +12 -12
  9. data/lib/cucumber/cli/options.rb +62 -71
  10. data/lib/cucumber/cli/profile_loader.rb +49 -26
  11. data/lib/cucumber/configuration.rb +31 -23
  12. data/lib/cucumber/constantize.rb +2 -5
  13. data/lib/cucumber/deprecate.rb +31 -7
  14. data/lib/cucumber/errors.rb +5 -7
  15. data/lib/cucumber/events/envelope.rb +9 -0
  16. data/lib/cucumber/events/gherkin_source_parsed.rb +11 -0
  17. data/lib/cucumber/events/hook_test_step_created.rb +13 -0
  18. data/lib/cucumber/events/step_activated.rb +2 -1
  19. data/lib/cucumber/events/test_case_created.rb +13 -0
  20. data/lib/cucumber/events/test_case_ready.rb +12 -0
  21. data/lib/cucumber/events/test_step_created.rb +13 -0
  22. data/lib/cucumber/events/undefined_parameter_type.rb +10 -0
  23. data/lib/cucumber/events.rb +13 -6
  24. data/lib/cucumber/file_specs.rb +6 -6
  25. data/lib/cucumber/filters/activate_steps.rb +5 -3
  26. data/lib/cucumber/filters/broadcast_test_case_ready_event.rb +12 -0
  27. data/lib/cucumber/filters/prepare_world.rb +5 -9
  28. data/lib/cucumber/filters/quit.rb +1 -3
  29. data/lib/cucumber/filters/tag_limits/verifier.rb +2 -4
  30. data/lib/cucumber/filters.rb +1 -0
  31. data/lib/cucumber/formatter/ansicolor.rb +40 -45
  32. data/lib/cucumber/formatter/ast_lookup.rb +165 -0
  33. data/lib/cucumber/formatter/backtrace_filter.rb +9 -8
  34. data/lib/cucumber/formatter/console.rb +58 -66
  35. data/lib/cucumber/formatter/console_counts.rb +4 -9
  36. data/lib/cucumber/formatter/console_issues.rb +6 -3
  37. data/lib/cucumber/formatter/duration.rb +1 -1
  38. data/lib/cucumber/formatter/duration_extractor.rb +3 -1
  39. data/lib/cucumber/formatter/errors.rb +6 -0
  40. data/lib/cucumber/formatter/fanout.rb +2 -0
  41. data/lib/cucumber/formatter/html.rb +11 -598
  42. data/lib/cucumber/formatter/http_io.rb +1 -1
  43. data/lib/cucumber/formatter/ignore_missing_messages.rb +1 -1
  44. data/lib/cucumber/formatter/interceptor.rb +8 -28
  45. data/lib/cucumber/formatter/io.rb +1 -1
  46. data/lib/cucumber/formatter/json.rb +101 -115
  47. data/lib/cucumber/formatter/junit.rb +56 -56
  48. data/lib/cucumber/formatter/message.rb +22 -0
  49. data/lib/cucumber/formatter/message_builder.rb +255 -0
  50. data/lib/cucumber/formatter/pretty.rb +359 -153
  51. data/lib/cucumber/formatter/progress.rb +30 -32
  52. data/lib/cucumber/formatter/query/hook_by_test_step.rb +31 -0
  53. data/lib/cucumber/formatter/query/pickle_by_test.rb +26 -0
  54. data/lib/cucumber/formatter/query/pickle_step_by_test_step.rb +26 -0
  55. data/lib/cucumber/formatter/query/step_definitions_by_test_step.rb +40 -0
  56. data/lib/cucumber/formatter/query/test_case_started_by_test_case.rb +40 -0
  57. data/lib/cucumber/formatter/rerun.rb +22 -4
  58. data/lib/cucumber/formatter/stepdefs.rb +1 -2
  59. data/lib/cucumber/formatter/steps.rb +2 -3
  60. data/lib/cucumber/formatter/summary.rb +16 -8
  61. data/lib/cucumber/formatter/unicode.rb +15 -17
  62. data/lib/cucumber/formatter/usage.rb +11 -10
  63. data/lib/cucumber/gherkin/data_table_parser.rb +17 -6
  64. data/lib/cucumber/gherkin/formatter/ansi_escapes.rb +13 -17
  65. data/lib/cucumber/gherkin/formatter/escaping.rb +2 -2
  66. data/lib/cucumber/gherkin/steps_parser.rb +17 -8
  67. data/lib/cucumber/glue/dsl.rb +1 -1
  68. data/lib/cucumber/glue/hook.rb +34 -11
  69. data/lib/cucumber/glue/invoke_in_world.rb +13 -18
  70. data/lib/cucumber/glue/proto_world.rb +42 -33
  71. data/lib/cucumber/glue/registry_and_more.rb +42 -12
  72. data/lib/cucumber/glue/snippet.rb +23 -22
  73. data/lib/cucumber/glue/step_definition.rb +42 -19
  74. data/lib/cucumber/glue/world_factory.rb +1 -1
  75. data/lib/cucumber/hooks.rb +11 -11
  76. data/lib/cucumber/multiline_argument/data_table/diff_matrices.rb +1 -1
  77. data/lib/cucumber/multiline_argument/data_table.rb +97 -64
  78. data/lib/cucumber/multiline_argument/doc_string.rb +1 -1
  79. data/lib/cucumber/multiline_argument.rb +4 -6
  80. data/lib/cucumber/platform.rb +3 -3
  81. data/lib/cucumber/rake/task.rb +16 -16
  82. data/lib/cucumber/rspec/disable_option_parser.rb +9 -8
  83. data/lib/cucumber/running_test_case.rb +2 -53
  84. data/lib/cucumber/runtime/after_hooks.rb +8 -4
  85. data/lib/cucumber/runtime/before_hooks.rb +8 -4
  86. data/lib/cucumber/runtime/for_programming_languages.rb +4 -2
  87. data/lib/cucumber/runtime/step_hooks.rb +6 -2
  88. data/lib/cucumber/runtime/support_code.rb +13 -15
  89. data/lib/cucumber/runtime/user_interface.rb +6 -16
  90. data/lib/cucumber/runtime.rb +34 -58
  91. data/lib/cucumber/step_definition_light.rb +4 -3
  92. data/lib/cucumber/step_definitions.rb +2 -2
  93. data/lib/cucumber/step_match.rb +12 -11
  94. data/lib/cucumber/step_match_search.rb +2 -1
  95. data/lib/cucumber/term/ansicolor.rb +9 -9
  96. data/lib/cucumber/version +1 -1
  97. data/lib/cucumber.rb +1 -1
  98. metadata +251 -81
  99. data/lib/cucumber/formatter/cucumber.css +0 -286
  100. data/lib/cucumber/formatter/cucumber.sass +0 -247
  101. data/lib/cucumber/formatter/hook_query_visitor.rb +0 -42
  102. data/lib/cucumber/formatter/html_builder.rb +0 -121
  103. data/lib/cucumber/formatter/inline-js.js +0 -30
  104. data/lib/cucumber/formatter/jquery-min.js +0 -154
  105. data/lib/cucumber/formatter/json_pretty.rb +0 -11
  106. data/lib/cucumber/formatter/legacy_api/adapter.rb +0 -1028
  107. data/lib/cucumber/formatter/legacy_api/ast.rb +0 -394
  108. data/lib/cucumber/formatter/legacy_api/results.rb +0 -50
  109. data/lib/cucumber/formatter/legacy_api/runtime_facade.rb +0 -32
  110. data/lib/cucumber/step_argument.rb +0 -25
@@ -9,30 +9,18 @@ module Cucumber
9
9
  @pipe = pipe
10
10
  @buffer = StringIO.new
11
11
  @wrapped = true
12
+ @lock = Mutex.new
12
13
  end
13
14
 
14
15
  def write(str)
15
- lock.synchronize do
16
+ @lock.synchronize do
16
17
  @buffer << str if @wrapped
17
18
  return @pipe.write(str)
18
19
  end
19
20
  end
20
21
 
21
- # @deprecated use #buffer_string
22
- def buffer
23
- require 'cucumber/deprecate.rb'
24
- Cucumber.deprecate(
25
- 'Use Cucumber::Formatter::Interceptor::Pipe#buffer_string instead',
26
- 'Cucumber::Formatter::Interceptor::Pipe#buffer',
27
- '3.99'
28
- )
29
- lock.synchronize do
30
- return @buffer.string.lines
31
- end
32
- end
33
-
34
22
  def buffer_string
35
- lock.synchronize do
23
+ @lock.synchronize do
36
24
  return @buffer.string.dup
37
25
  end
38
26
  end
@@ -43,17 +31,15 @@ module Cucumber
43
31
  end
44
32
 
45
33
  def method_missing(method, *args, &blk)
46
- @pipe.send(method, *args, &blk)
34
+ @pipe.send(method, *args, &blk) || super
47
35
  end
48
36
 
49
- def respond_to?(method, include_private = false)
37
+ def respond_to_missing?(method, include_private = false)
50
38
  super || @pipe.respond_to?(method, include_private)
51
39
  end
52
40
 
53
41
  def self.validate_pipe(pipe)
54
- unless [:stdout, :stderr].include? pipe
55
- raise ArgumentError, '#wrap only accepts :stderr or :stdout'
56
- end
42
+ raise ArgumentError, '#wrap only accepts :stderr or :stdout' unless %i[stdout stderr].include? pipe
57
43
  end
58
44
 
59
45
  def self.unwrap!(pipe)
@@ -75,19 +61,13 @@ module Cucumber
75
61
 
76
62
  case pipe
77
63
  when :stderr
78
- $stderr = self.new($stderr)
64
+ $stderr = new($stderr)
79
65
  return $stderr
80
66
  when :stdout
81
- $stdout = self.new($stdout)
67
+ $stdout = new($stdout)
82
68
  return $stdout
83
69
  end
84
70
  end
85
-
86
- private
87
-
88
- def lock
89
- @lock ||= Mutex.new
90
- end
91
71
  end
92
72
  end
93
73
  end
@@ -10,7 +10,7 @@ module Cucumber
10
10
  def ensure_io(path_or_url_or_io)
11
11
  return nil if path_or_url_or_io.nil?
12
12
  return path_or_url_or_io if path_or_url_or_io.respond_to?(:write)
13
- io = if path_or_url_or_io =~ %r{^https?://}
13
+ io = if path_or_url_or_io.match(%r{^https?://})
14
14
  HTTPIO.open(path_or_url_or_io)
15
15
  else
16
16
  File.open(path_or_url_or_io, Cucumber.file_mode('w'))
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'multi_json'
3
+ require 'json'
4
4
  require 'base64'
5
5
  require 'cucumber/formatter/backtrace_filter'
6
6
  require 'cucumber/formatter/io'
7
- require 'cucumber/formatter/hook_query_visitor'
7
+ require 'cucumber/formatter/ast_lookup'
8
+ require 'cucumber/deprecate'
8
9
 
9
10
  module Cucumber
10
11
  module Formatter
@@ -13,7 +14,16 @@ module Cucumber
13
14
  include Io
14
15
 
15
16
  def initialize(config)
17
+ Cucumber::Deprecate::CliOption.deprecate(
18
+ config.error_stream,
19
+ '--format=json',
20
+ "Please use --format=message and stand-alone json-formatter.\n" \
21
+ 'json-formatter homepage: https://github.com/cucumber/cucumber/tree/master/json-formatter#cucumber-json-formatter',
22
+ '5.0.0'
23
+ )
24
+
16
25
  @io = ensure_io(config.out_stream)
26
+ @ast_lookup = AstLookup.new(config)
17
27
  @feature_hashes = []
18
28
  @step_or_hook_hash = {}
19
29
  config.on_event :test_case_started, &method(:on_test_case_started)
@@ -25,16 +35,18 @@ module Cucumber
25
35
 
26
36
  def on_test_case_started(event)
27
37
  test_case = event.test_case
28
- builder = Builder.new(test_case)
29
- unless same_feature_as_previous_test_case?(test_case.feature)
38
+ builder = Builder.new(test_case, @ast_lookup)
39
+ unless same_feature_as_previous_test_case?(test_case)
30
40
  @feature_hash = builder.feature_hash
31
41
  @feature_hashes << @feature_hash
32
42
  end
33
43
  @test_case_hash = builder.test_case_hash
34
44
  if builder.background?
45
+ @in_background = true
35
46
  feature_elements << builder.background_hash
36
47
  @element_hash = builder.background_hash
37
48
  else
49
+ @in_background = false
38
50
  feature_elements << @test_case_hash
39
51
  @element_hash = @test_case_hash
40
52
  end
@@ -44,17 +56,17 @@ module Cucumber
44
56
  def on_test_step_started(event)
45
57
  test_step = event.test_step
46
58
  return if internal_hook?(test_step)
47
- hook_query = HookQueryVisitor.new(test_step)
48
- if hook_query.hook?
59
+ if test_step.hook?
49
60
  @step_or_hook_hash = {}
50
- hooks_of_type(hook_query) << @step_or_hook_hash
61
+ hooks_of_type(test_step) << @step_or_hook_hash
51
62
  return
52
63
  end
53
64
  if first_step_after_background?(test_step)
65
+ @in_background = false
54
66
  feature_elements << @test_case_hash
55
67
  @element_hash = @test_case_hash
56
68
  end
57
- @step_or_hook_hash = create_step_hash(test_step.source.last)
69
+ @step_or_hook_hash = create_step_hash(test_step)
58
70
  steps << @step_or_hook_hash
59
71
  @step_hash = @step_or_hook_hash
60
72
  end
@@ -74,50 +86,42 @@ module Cucumber
74
86
  end
75
87
 
76
88
  def on_test_run_finished(_event)
77
- @io.write(MultiJson.dump(@feature_hashes, pretty: true))
78
- end
79
-
80
- def puts(message)
81
- test_step_output << message
89
+ @io.write(JSON.generate(@feature_hashes, pretty: true))
82
90
  end
83
91
 
84
- def embed(src, mime_type, _label)
85
- begin
86
- is_file = File.file?(src)
87
- rescue ArgumentError
88
- is_file = false
92
+ def attach(src, mime_type)
93
+ if mime_type == 'text/x.cucumber.log+plain'
94
+ test_step_output << src
95
+ return
89
96
  end
90
-
91
- if is_file
97
+ if File.file?(src)
92
98
  content = File.open(src, 'rb', &:read)
93
99
  data = encode64(content)
100
+ elsif mime_type =~ /;base64$/
101
+ mime_type = mime_type[0..-8]
102
+ data = src
94
103
  else
95
- if mime_type =~ /;base64$/
96
- mime_type = mime_type[0..-8]
97
- data = src
98
- else
99
- data = encode64(src)
100
- end
104
+ data = encode64(src)
101
105
  end
102
106
  test_step_embeddings << { mime_type: mime_type, data: data }
103
107
  end
104
108
 
105
109
  private
106
110
 
107
- def same_feature_as_previous_test_case?(feature)
108
- current_feature[:uri] == feature.file && current_feature[:line] == feature.location.line
111
+ def same_feature_as_previous_test_case?(test_case)
112
+ current_feature[:uri] == test_case.location.file
109
113
  end
110
114
 
111
115
  def first_step_after_background?(test_step)
112
- test_step.source[1].to_s != @element_hash[:name]
116
+ @in_background && test_step.location.lines.max >= @test_case_hash[:line]
113
117
  end
114
118
 
115
119
  def internal_hook?(test_step)
116
- test_step.source.last.location.file.include?('lib/cucumber/')
120
+ test_step.location.file.include?('lib/cucumber/')
117
121
  end
118
122
 
119
123
  def current_feature
120
- @feature_hash ||= {}
124
+ @feature_hash ||= {} # rubocop:disable Naming/MemoizedInstanceVariableName
121
125
  end
122
126
 
123
127
  def feature_elements
@@ -128,16 +132,16 @@ module Cucumber
128
132
  @element_hash[:steps] ||= []
129
133
  end
130
134
 
131
- def hooks_of_type(hook_query)
132
- case hook_query.type
133
- when :before
134
- return before_hooks
135
- when :after
136
- return after_hooks
137
- when :after_step
138
- return after_step_hooks
135
+ def hooks_of_type(hook_step)
136
+ case hook_step.text
137
+ when 'Before hook'
138
+ before_hooks
139
+ when 'After hook'
140
+ after_hooks
141
+ when 'AfterStep hook'
142
+ after_step_hooks
139
143
  else
140
- fail 'Unknown hook type ' + hook_query.type.to_s
144
+ raise 'Unknown hook type ' + hook_step.to_s
141
145
  end
142
146
  end
143
147
 
@@ -165,20 +169,20 @@ module Cucumber
165
169
  @step_or_hook_hash[:embeddings] ||= []
166
170
  end
167
171
 
168
- def create_step_hash(step_source)
172
+ def create_step_hash(test_step)
173
+ step_source = @ast_lookup.step_source(test_step).step
169
174
  step_hash = {
170
175
  keyword: step_source.keyword,
171
- name: step_source.to_s,
172
- line: step_source.original_location.line
176
+ name: test_step.text,
177
+ line: test_step.location.lines.min
173
178
  }
174
- step_hash[:comments] = Formatter.create_comments_array(step_source.comments) unless step_source.comments.empty?
175
- step_hash[:doc_string] = create_doc_string_hash(step_source.multiline_arg) if step_source.multiline_arg.doc_string?
176
- step_hash[:rows] = create_data_table_value(step_source.multiline_arg) if step_source.multiline_arg.data_table?
179
+ step_hash[:doc_string] = create_doc_string_hash(step_source.doc_string) unless step_source.doc_string.nil?
180
+ step_hash[:rows] = create_data_table_value(step_source.data_table) unless step_source.data_table.nil?
177
181
  step_hash
178
182
  end
179
183
 
180
184
  def create_doc_string_hash(doc_string)
181
- content_type = doc_string.content_type ? doc_string.content_type : ''
185
+ content_type = doc_string.media_type || ''
182
186
  {
183
187
  value: doc_string.content,
184
188
  content_type: content_type,
@@ -187,14 +191,15 @@ module Cucumber
187
191
  end
188
192
 
189
193
  def create_data_table_value(data_table)
190
- data_table.raw.map do |row|
191
- { cells: row }
194
+ data_table.rows.map do |row|
195
+ { cells: row.cells.map(&:value) }
192
196
  end
193
197
  end
194
198
 
195
199
  def add_match_and_result(test_step, result)
196
200
  @step_or_hook_hash[:match] = create_match_hash(test_step, result)
197
201
  @step_or_hook_hash[:result] = create_result_hash(result)
202
+ result.embeddings.each { |e| embed(e['src'], e['mime_type'], e['label']) } if result.respond_to?(:embeddings)
198
203
  end
199
204
 
200
205
  def add_failed_around_hook(result)
@@ -232,113 +237,94 @@ module Cucumber
232
237
  class Builder
233
238
  attr_reader :feature_hash, :background_hash, :test_case_hash
234
239
 
235
- def initialize(test_case)
240
+ def initialize(test_case, ast_lookup)
236
241
  @background_hash = nil
237
- test_case.describe_source_to(self)
238
- test_case.feature.background.describe_to(self)
242
+ uri = test_case.location.file
243
+ feature = ast_lookup.gherkin_document(uri).feature
244
+ feature(feature, uri)
245
+ background(feature.children.first.background) unless feature.children.first.background.nil?
246
+ scenario(ast_lookup.scenario_source(test_case), test_case)
239
247
  end
240
248
 
241
249
  def background?
242
250
  @background_hash != nil
243
251
  end
244
252
 
245
- def feature(feature)
253
+ def feature(feature, uri)
246
254
  @feature_hash = {
247
- uri: feature.file,
248
- id: create_id(feature),
255
+ id: create_id(feature.name),
256
+ uri: uri,
249
257
  keyword: feature.keyword,
250
- name: feature.to_s,
251
- description: feature.description,
258
+ name: feature.name,
259
+ description: value_or_empty_string(feature.description),
252
260
  line: feature.location.line
253
261
  }
254
- unless feature.tags.empty?
255
- @feature_hash[:tags] = create_tags_array(feature.tags)
256
- @test_case_hash[:tags] = if @test_case_hash[:tags]
257
- @feature_hash[:tags] + @test_case_hash[:tags]
258
- else
259
- @feature_hash[:tags]
260
- end
261
- end
262
- @feature_hash[:comments] = Formatter.create_comments_array(feature.comments) unless feature.comments.empty?
263
- @test_case_hash[:id].insert(0, @feature_hash[:id] + ';')
262
+ return if feature.tags.empty?
263
+ @feature_hash[:tags] = create_tags_array_from_hash_array(feature.tags)
264
264
  end
265
265
 
266
266
  def background(background)
267
267
  @background_hash = {
268
268
  keyword: background.keyword,
269
- name: background.to_s,
270
- description: background.description,
269
+ name: background.name,
270
+ description: value_or_empty_string(background.description),
271
271
  line: background.location.line,
272
272
  type: 'background'
273
273
  }
274
- @background_hash[:comments] = Formatter.create_comments_array(background.comments) unless background.comments.empty?
275
274
  end
276
275
 
277
- def scenario(scenario)
276
+ def scenario(scenario_source, test_case)
277
+ scenario = scenario_source.type == :Scenario ? scenario_source.scenario : scenario_source.scenario_outline
278
278
  @test_case_hash = {
279
- id: create_id(scenario),
279
+ id: "#{@feature_hash[:id]};#{create_id_from_scenario_source(scenario_source)}",
280
280
  keyword: scenario.keyword,
281
- name: scenario.to_s,
282
- description: scenario.description,
283
- line: scenario.location.line,
281
+ name: test_case.name,
282
+ description: value_or_empty_string(scenario.description),
283
+ line: test_case.location.lines.max,
284
284
  type: 'scenario'
285
285
  }
286
- @test_case_hash[:tags] = create_tags_array(scenario.tags) unless scenario.tags.empty?
287
- @test_case_hash[:comments] = Formatter.create_comments_array(scenario.comments) unless scenario.comments.empty?
286
+ @test_case_hash[:tags] = create_tags_array_from_tags_array(test_case.tags) unless test_case.tags.empty?
288
287
  end
289
288
 
290
- def scenario_outline(scenario)
291
- @test_case_hash = {
292
- id: create_id(scenario) + ';' + @example_id,
293
- keyword: scenario.keyword,
294
- name: scenario.to_s,
295
- description: scenario.description,
296
- line: @row.location.line,
297
- type: 'scenario'
298
- }
299
- tags = []
300
- tags += create_tags_array(scenario.tags) unless scenario.tags.empty?
301
- tags += @examples_table_tags if @examples_table_tags
302
- @test_case_hash[:tags] = tags unless tags.empty?
303
- comments = []
304
- comments += Formatter.create_comments_array(scenario.comments) unless scenario.comments.empty?
305
- comments += @examples_table_comments if @examples_table_comments
306
- comments += @row_comments if @row_comments
307
- @test_case_hash[:comments] = comments unless comments.empty?
308
- end
289
+ private
309
290
 
310
- def examples_table(examples_table)
311
- # the json file have traditionally used the header row as row 1,
312
- # wheras cucumber-ruby-core used the first example row as row 1.
313
- @example_id = create_id(examples_table) + ";#{@row.number + 1}"
291
+ def value_or_empty_string(value)
292
+ value.nil? ? '' : value
293
+ end
314
294
 
315
- @examples_table_tags = create_tags_array(examples_table.tags) unless examples_table.tags.empty?
316
- @examples_table_comments = Formatter.create_comments_array(examples_table.comments) unless examples_table.comments.empty?
295
+ def create_id(name)
296
+ name.downcase.tr(' ', '-')
317
297
  end
318
298
 
319
- def examples_table_row(row)
320
- @row = row
321
- @row_comments = Formatter.create_comments_array(row.comments) unless row.comments.empty?
299
+ def create_id_from_scenario_source(scenario_source)
300
+ if scenario_source.type == :Scenario
301
+ create_id(scenario_source.scenario.name)
302
+ else
303
+ scenario_outline_name = scenario_source.scenario_outline.name
304
+ examples_name = scenario_source.examples.name
305
+ row_number = calculate_row_number(scenario_source)
306
+ "#{create_id(scenario_outline_name)};#{create_id(examples_name)};#{row_number}"
307
+ end
322
308
  end
323
309
 
324
- private
310
+ def calculate_row_number(scenario_source)
311
+ scenario_source.examples.table_body.each_with_index do |row, index|
312
+ return index + 2 if row == scenario_source.row
313
+ end
314
+ end
325
315
 
326
- def create_id(element)
327
- element.to_s.downcase.tr(' ', '-')
316
+ def create_tags_array_from_hash_array(tags)
317
+ tags_array = []
318
+ tags.each { |tag| tags_array << { name: tag.name, line: tag.location.line } }
319
+ tags_array
328
320
  end
329
321
 
330
- def create_tags_array(tags)
322
+ def create_tags_array_from_tags_array(tags)
331
323
  tags_array = []
332
324
  tags.each { |tag| tags_array << { name: tag.name, line: tag.location.line } }
333
325
  tags_array
334
326
  end
335
327
  end
336
328
  end
337
-
338
- def self.create_comments_array(comments)
339
- comments_array = []
340
- comments.each { |comment| comments_array << { value: comment.to_s.strip, line: comment.location.line } }
341
- comments_array
342
- end
343
329
  end
344
330
  end