cucumber 4.0.0.rc.1 → 4.0.0.rc.6

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 (66) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +97 -4
  3. data/CONTRIBUTING.md +1 -18
  4. data/README.md +4 -5
  5. data/lib/autotest/cucumber_mixin.rb +2 -10
  6. data/lib/cucumber.rb +1 -1
  7. data/lib/cucumber/cli/configuration.rb +1 -1
  8. data/lib/cucumber/cli/main.rb +1 -0
  9. data/lib/cucumber/cli/options.rb +18 -13
  10. data/lib/cucumber/cli/profile_loader.rb +23 -12
  11. data/lib/cucumber/configuration.rb +11 -2
  12. data/lib/cucumber/deprecate.rb +29 -5
  13. data/lib/cucumber/errors.rb +5 -2
  14. data/lib/cucumber/events.rb +12 -7
  15. data/lib/cucumber/events/envelope.rb +9 -0
  16. data/lib/cucumber/events/hook_test_step_created.rb +13 -0
  17. data/lib/cucumber/events/test_case_created.rb +13 -0
  18. data/lib/cucumber/events/test_case_ready.rb +12 -0
  19. data/lib/cucumber/events/test_step_created.rb +13 -0
  20. data/lib/cucumber/filters.rb +1 -0
  21. data/lib/cucumber/filters/broadcast_test_case_ready_event.rb +12 -0
  22. data/lib/cucumber/formatter/ast_lookup.rb +43 -38
  23. data/lib/cucumber/formatter/backtrace_filter.rb +4 -1
  24. data/lib/cucumber/formatter/console.rb +4 -9
  25. data/lib/cucumber/formatter/console_issues.rb +1 -1
  26. data/lib/cucumber/formatter/duration.rb +1 -1
  27. data/lib/cucumber/formatter/duration_extractor.rb +2 -0
  28. data/lib/cucumber/formatter/errors.rb +6 -0
  29. data/lib/cucumber/formatter/html.rb +24 -0
  30. data/lib/cucumber/formatter/http_io.rb +146 -0
  31. data/lib/cucumber/formatter/interceptor.rb +3 -21
  32. data/lib/cucumber/formatter/io.rb +14 -8
  33. data/lib/cucumber/formatter/json.rb +46 -36
  34. data/lib/cucumber/formatter/junit.rb +13 -11
  35. data/lib/cucumber/formatter/message.rb +22 -0
  36. data/lib/cucumber/formatter/message_builder.rb +243 -0
  37. data/lib/cucumber/formatter/pretty.rb +65 -60
  38. data/lib/cucumber/formatter/query/hook_by_test_step.rb +31 -0
  39. data/lib/cucumber/formatter/query/pickle_by_test.rb +26 -0
  40. data/lib/cucumber/formatter/query/pickle_step_by_test_step.rb +26 -0
  41. data/lib/cucumber/formatter/query/step_definitions_by_test_step.rb +40 -0
  42. data/lib/cucumber/formatter/query/test_case_started_by_test_case.rb +40 -0
  43. data/lib/cucumber/formatter/summary.rb +1 -1
  44. data/lib/cucumber/formatter/usage.rb +3 -3
  45. data/lib/cucumber/gherkin/data_table_parser.rb +12 -3
  46. data/lib/cucumber/gherkin/steps_parser.rb +13 -3
  47. data/lib/cucumber/glue/hook.rb +18 -2
  48. data/lib/cucumber/glue/proto_world.rb +30 -18
  49. data/lib/cucumber/glue/registry_and_more.rb +40 -3
  50. data/lib/cucumber/glue/snippet.rb +2 -2
  51. data/lib/cucumber/glue/step_definition.rb +28 -4
  52. data/lib/cucumber/hooks.rb +8 -8
  53. data/lib/cucumber/multiline_argument.rb +1 -1
  54. data/lib/cucumber/multiline_argument/data_table.rb +17 -13
  55. data/lib/cucumber/platform.rb +1 -1
  56. data/lib/cucumber/rake/task.rb +3 -0
  57. data/lib/cucumber/runtime.rb +29 -3
  58. data/lib/cucumber/runtime/after_hooks.rb +6 -2
  59. data/lib/cucumber/runtime/before_hooks.rb +6 -2
  60. data/lib/cucumber/runtime/for_programming_languages.rb +1 -0
  61. data/lib/cucumber/runtime/step_hooks.rb +3 -2
  62. data/lib/cucumber/runtime/support_code.rb +3 -3
  63. data/lib/cucumber/runtime/user_interface.rb +2 -10
  64. data/lib/cucumber/step_definitions.rb +2 -2
  65. data/lib/cucumber/version +1 -1
  66. metadata +227 -73
@@ -19,7 +19,7 @@ module Cucumber
19
19
  #
20
20
  # If the output is STDOUT (and not a file), there are bright colours to watch too.
21
21
  #
22
- class Pretty
22
+ class Pretty # rubocop:disable Metrics/ClassLength
23
23
  include FileUtils
24
24
  include Console
25
25
  include Io
@@ -101,13 +101,11 @@ module Cucumber
101
101
  print_step_header(current_test_case) if first_step_after_printing_background_steps?(event.test_step)
102
102
  end
103
103
 
104
- def on_test_step_finished(event) # rubocop:disable Metrics/PerceivedComplexity
104
+ def on_test_step_finished(event)
105
105
  collect_snippet_data(event.test_step, @ast_lookup) if event.result.undefined?
106
106
  return if in_scenario_outline && !options[:expand]
107
107
  exception_to_be_printed = find_exception_to_be_printed(event.result)
108
- # rubocop:disable Metrics/LineLength
109
- print_step_data(event.test_step, event.result) if !event.test_step.hook? && (print_background_steps || event.test_step.location.lines.max >= current_test_case.location.lines.max || exception_to_be_printed)
110
- # rubocop:enable Metrics/LineLength
108
+ print_step_data(event.test_step, event.result) if print_step_data?(event, exception_to_be_printed)
111
109
  print_step_output
112
110
  return unless exception_to_be_printed
113
111
  print_exception(exception_to_be_printed, event.result.to_sym, 6)
@@ -133,10 +131,9 @@ module Cucumber
133
131
  print_summary
134
132
  end
135
133
 
136
- def puts(*messages)
137
- messages.each do |message|
138
- @test_step_output.push message
139
- end
134
+ def attach(src, media_type)
135
+ return unless media_type == 'text/x.cucumber.log+plain'
136
+ @test_step_output.push src
140
137
  end
141
138
 
142
139
  private
@@ -155,10 +152,10 @@ module Cucumber
155
152
  end
156
153
 
157
154
  def calculate_source_indent_for_ast_node(ast_node)
158
- indent = 4 + ast_node[:keyword].length
159
- indent += 1 + ast_node[:name].length
160
- ast_node[:steps].each do |step|
161
- step_indent = 5 + step[:keyword].length + step[:text].length
155
+ indent = 4 + ast_node.keyword.length
156
+ indent += 1 + ast_node.name.length
157
+ ast_node.steps.each do |step|
158
+ step_indent = 5 + step.keyword.length + step.text.length
162
159
  indent = step_indent if step_indent > indent
163
160
  end
164
161
  indent
@@ -190,9 +187,9 @@ module Cucumber
190
187
  end
191
188
 
192
189
  def feature_has_background?
193
- feature_children = gherkin_document[:feature][:children]
190
+ feature_children = gherkin_document.feature.children
194
191
  return false if feature_children.empty?
195
- !feature_children.first[:background].nil?
192
+ !feature_children.first.background.nil?
196
193
  end
197
194
 
198
195
  def print_step_header(test_case)
@@ -240,12 +237,12 @@ module Cucumber
240
237
  end
241
238
 
242
239
  def print_feature_data
243
- feature = gherkin_document[:feature]
244
- print_language_comment(feature[:location][:line])
245
- print_comments(feature[:location][:line], 0)
246
- print_tags(feature[:tags], 0)
240
+ feature = gherkin_document.feature
241
+ print_language_comment(feature.location.line)
242
+ print_comments(feature.location.line, 0)
243
+ print_tags(feature.tags, 0)
247
244
  print_feature_line(feature)
248
- print_description(feature[:description])
245
+ print_description(feature.description)
249
246
  @io.flush
250
247
  end
251
248
 
@@ -256,11 +253,11 @@ module Cucumber
256
253
  end
257
254
 
258
255
  def print_comments(up_to_line, indent)
259
- comments = gherkin_document[:comments]
256
+ comments = gherkin_document.comments
260
257
  return if comments.empty? || comments.length <= @next_comment_to_be_printed
261
258
  comments[@next_comment_to_be_printed..-1].each do |comment|
262
- if comment[:location][:line] <= up_to_line
263
- @io.puts(format_string(comment[:text].strip, :comment).indent(indent))
259
+ if comment.location.line <= up_to_line
260
+ @io.puts(format_string(comment.text.strip, :comment).indent(indent))
264
261
  @next_comment_to_be_printed += 1
265
262
  end
266
263
  break if @next_comment_to_be_printed >= comments.length
@@ -269,11 +266,11 @@ module Cucumber
269
266
 
270
267
  def print_tags(tags, indent)
271
268
  return if !tags || tags.empty?
272
- @io.puts(tags.map { |tag| format_string(tag[:name], :tag) }.join(' ').indent(indent))
269
+ @io.puts(tags.map { |tag| format_string(tag.name, :tag) }.join(' ').indent(indent))
273
270
  end
274
271
 
275
272
  def print_feature_line(feature)
276
- print_keyword_name(feature[:keyword], feature[:name], 0)
273
+ print_keyword_name(feature.keyword, feature.name, 0)
277
274
  end
278
275
 
279
276
  def print_keyword_name(keyword, name, indent, location = nil)
@@ -296,29 +293,37 @@ module Cucumber
296
293
 
297
294
  def print_background_data
298
295
  @io.puts
299
- background = gherkin_document[:feature][:children].first[:background]
296
+ background = gherkin_document.feature.children.first.background
300
297
  @source_indent = calculate_source_indent_for_ast_node(background) if options[:source]
301
- print_comments(background[:location][:line], 2)
298
+ print_comments(background.location.line, 2)
302
299
  print_background_line(background)
303
- print_description(background[:description])
300
+ print_description(background.description)
304
301
  @io.flush
305
302
  end
306
303
 
307
304
  def print_background_line(background)
308
- print_keyword_name(background[:keyword], background[:name], 2, "#{current_feature_uri}:#{background[:location][:line]}")
305
+ print_keyword_name(background.keyword, background.name, 2, "#{current_feature_uri}:#{background.location.line}")
309
306
  end
310
307
 
311
308
  def print_scenario_data(test_case)
312
309
  scenario = scenario_source(test_case).scenario
313
- print_comments(scenario[:location][:line], 2)
314
- print_tags(scenario[:tags], 2)
310
+ print_comments(scenario.location.line, 2)
311
+ print_tags(scenario.tags, 2)
315
312
  print_scenario_line(scenario, test_case.location)
316
- print_description(scenario[:description])
313
+ print_description(scenario.description)
317
314
  @io.flush
318
315
  end
319
316
 
320
317
  def print_scenario_line(scenario, location = nil)
321
- print_keyword_name(scenario[:keyword], scenario[:name], 2, location)
318
+ print_keyword_name(scenario.keyword, scenario.name, 2, location)
319
+ end
320
+
321
+ def print_step_data?(event, exception_to_be_printed)
322
+ !event.test_step.hook? && (
323
+ print_background_steps ||
324
+ event.test_step.location.lines.max >= current_test_case.location.lines.max ||
325
+ exception_to_be_printed
326
+ )
322
327
  end
323
328
 
324
329
  def print_step_data(test_step, result)
@@ -334,7 +339,7 @@ module Cucumber
334
339
 
335
340
  def test_step_keyword(test_step)
336
341
  step = step_source(test_step).step
337
- step[:keyword]
342
+ step.keyword
338
343
  end
339
344
 
340
345
  def step_source(test_step)
@@ -355,38 +360,38 @@ module Cucumber
355
360
 
356
361
  def print_multiline_argument(test_step, result, indent)
357
362
  step = step_source(test_step).step
358
- if !step[:doc_string].nil?
359
- print_doc_string(step[:doc_string][:content], result.to_sym, indent)
360
- elsif !step[:data_table].nil?
361
- print_data_table(step[:data_table], result.to_sym, indent)
363
+ if !step.doc_string.nil?
364
+ print_doc_string(step.doc_string.content, result.to_sym, indent)
365
+ elsif !step.data_table.nil?
366
+ print_data_table(step.data_table, result.to_sym, indent)
362
367
  end
363
368
  end
364
369
 
365
370
  def print_data_table(data_table, status, indent)
366
- data_table[:rows].each do |row|
367
- print_comments(row[:location][:line], indent)
368
- @io.puts format_string(gherkin_source.split("\n")[row[:location][:line] - 1].strip, status).indent(indent)
371
+ data_table.rows.each do |row|
372
+ print_comments(row.location.line, indent)
373
+ @io.puts format_string(gherkin_source.split("\n")[row.location.line - 1].strip, status).indent(indent)
369
374
  end
370
375
  end
371
376
 
372
377
  def print_outline_data(scenario_outline) # rubocop:disable Metrics/AbcSize
373
- print_comments(scenario_outline[:location][:line], 2)
374
- print_tags(scenario_outline[:tags], 2)
378
+ print_comments(scenario_outline.location.line, 2)
379
+ print_tags(scenario_outline.tags, 2)
375
380
  @source_indent = calculate_source_indent_for_ast_node(scenario_outline) if options[:source]
376
- print_scenario_line(scenario_outline, "#{current_feature_uri}:#{scenario_outline[:location][:line]}")
377
- print_description(scenario_outline[:description])
378
- scenario_outline[:steps].each do |step|
379
- print_comments(step[:location][:line], 4)
380
- step_line = " #{step[:keyword]}#{step[:text]}"
381
+ print_scenario_line(scenario_outline, "#{current_feature_uri}:#{scenario_outline.location.line}")
382
+ print_description(scenario_outline.description)
383
+ scenario_outline.steps.each do |step|
384
+ print_comments(step.location.line, 4)
385
+ step_line = " #{step.keyword}#{step.text}"
381
386
  @io.print(format_string(step_line, :skipped))
382
387
  if options[:source]
383
- comment_line = format_string("# #{current_feature_uri}:#{step[:location][:line]}", :comment)
388
+ comment_line = format_string("# #{current_feature_uri}:#{step.location.line}", :comment)
384
389
  @io.print(comment_line.indent(@source_indent - step_line.length))
385
390
  end
386
391
  @io.puts
387
392
  next if options[:no_multiline]
388
- print_doc_string(step[:doc_string][:content], :skipped, 6) unless step[:doc_string].nil?
389
- print_data_table(step[:data_table], :skipped, 6) unless step[:data_table].nil?
393
+ print_doc_string(step.doc_string.content, :skipped, 6) unless step.doc_string.nil?
394
+ print_data_table(step.data_table, :skipped, 6) unless step.data_table.nil?
390
395
  end
391
396
  @io.flush
392
397
  end
@@ -398,13 +403,13 @@ module Cucumber
398
403
  end
399
404
 
400
405
  def print_examples_data(examples)
401
- print_comments(examples[:location][:line], 4)
402
- print_tags(examples[:tags], 4)
403
- print_keyword_name(examples[:keyword], examples[:name], 4)
404
- print_description(examples[:description])
406
+ print_comments(examples.location.line, 4)
407
+ print_tags(examples.tags, 4)
408
+ print_keyword_name(examples.keyword, examples.name, 4)
409
+ print_description(examples.description)
405
410
  unless options[:expand]
406
- print_comments(examples[:table_header][:location][:line], 6)
407
- @io.puts(gherkin_source.split("\n")[examples[:table_header][:location][:line] - 1].strip.indent(6))
411
+ print_comments(examples.table_header.location.line, 6)
412
+ @io.puts(gherkin_source.split("\n")[examples.table_header.location.line - 1].strip.indent(6))
408
413
  end
409
414
  @io.flush
410
415
  end
@@ -427,12 +432,12 @@ module Cucumber
427
432
  end
428
433
 
429
434
  def print_expanded_row_data(test_case)
430
- feature = gherkin_document[:feature]
431
- language_code = feature[:language] || 'en'
435
+ feature = gherkin_document.feature
436
+ language_code = feature.language || 'en'
432
437
  language = ::Gherkin::Dialect.for(language_code)
433
438
  scenario_keyword = language.scenario_keywords[0]
434
439
  row = scenario_source(test_case).row
435
- expanded_name = '| ' + row[:cells].map { |cell| cell[:value] }.join(' | ') + ' |'
440
+ expanded_name = '| ' + row.cells.map(&:value).join(' | ') + ' |'
436
441
  @source_indent = calculate_source_indent_for_expanded_test_case(test_case, scenario_keyword, expanded_name)
437
442
  @io.puts
438
443
  print_keyword_name(scenario_keyword, expanded_name, 6, test_case.location)
@@ -0,0 +1,31 @@
1
+ require 'cucumber/formatter/errors'
2
+
3
+ module Cucumber
4
+ module Formatter
5
+ module Query
6
+ class HookByTestStep
7
+ def initialize(config)
8
+ @hook_id_by_test_step_id = {}
9
+
10
+ config.on_event :test_step_created, &method(:on_test_step_created)
11
+ config.on_event :hook_test_step_created, &method(:on_hook_test_step_created)
12
+ end
13
+
14
+ def hook_id(test_step)
15
+ return @hook_id_by_test_step_id[test_step.id] if @hook_id_by_test_step_id.key?(test_step.id)
16
+ raise TestStepUnknownError, "No hook found for #{test_step.id} }. Known: #{@hook_id_by_test_step_id.keys}"
17
+ end
18
+
19
+ private
20
+
21
+ def on_test_step_created(event)
22
+ @hook_id_by_test_step_id[event.test_step.id] = nil
23
+ end
24
+
25
+ def on_hook_test_step_created(event)
26
+ @hook_id_by_test_step_id[event.test_step.id] = event.hook.id
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,26 @@
1
+ require 'cucumber/formatter/errors'
2
+
3
+ module Cucumber
4
+ module Formatter
5
+ module Query
6
+ class PickleByTest
7
+ def initialize(config)
8
+ @pickle_id_by_test_case_id = {}
9
+ config.on_event :test_case_created, &method(:on_test_case_created)
10
+ end
11
+
12
+ def pickle_id(test_case)
13
+ return @pickle_id_by_test_case_id[test_case.id] if @pickle_id_by_test_case_id.key?(test_case.id)
14
+
15
+ raise TestCaseUnknownError, "No pickle found for #{test_case.id} }. Known: #{@pickle_id_by_test_case_id.keys}"
16
+ end
17
+
18
+ private
19
+
20
+ def on_test_case_created(event)
21
+ @pickle_id_by_test_case_id[event.test_case.id] = event.pickle.id
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ require 'cucumber/formatter/errors'
2
+
3
+ module Cucumber
4
+ module Formatter
5
+ module Query
6
+ class PickleStepByTestStep
7
+ def initialize(config)
8
+ @pickle_id_step_by_test_step_id = {}
9
+ config.on_event :test_step_created, &method(:on_test_step_created)
10
+ end
11
+
12
+ def pickle_step_id(test_step)
13
+ return @pickle_id_step_by_test_step_id[test_step.id] if @pickle_id_step_by_test_step_id.key?(test_step.id)
14
+
15
+ raise TestStepUnknownError, "No pickle step found for #{test_step.id} }. Known: #{@pickle_id_step_by_test_step_id.keys}"
16
+ end
17
+
18
+ private
19
+
20
+ def on_test_step_created(event)
21
+ @pickle_id_step_by_test_step_id[event.test_step.id] = event.pickle_step.id
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,40 @@
1
+ require 'cucumber/formatter/errors'
2
+
3
+ module Cucumber
4
+ module Formatter
5
+ module Query
6
+ class StepDefinitionsByTestStep
7
+ def initialize(config)
8
+ @step_definition_ids_by_test_step_id = {}
9
+ @step_match_arguments_by_test_step_id = {}
10
+
11
+ config.on_event :test_step_created, &method(:on_test_step_created)
12
+ config.on_event :step_activated, &method(:on_step_activated)
13
+ end
14
+
15
+ def step_definition_ids(test_step)
16
+ return @step_definition_ids_by_test_step_id[test_step.id] if @step_definition_ids_by_test_step_id.key?(test_step.id)
17
+
18
+ raise TestStepUnknownError, "No step definition found for #{test_step.id} }. Known: #{@step_definition_ids_by_test_step_id.keys}"
19
+ end
20
+
21
+ def step_match_arguments(test_step)
22
+ return @step_match_arguments_by_test_step_id[test_step.id] if @step_match_arguments_by_test_step_id.key?(test_step.id)
23
+
24
+ raise TestStepUnknownError, "No step match arguments found for #{test_step.id} }. Known: #{@step_match_arguments_by_test_step_id.keys}"
25
+ end
26
+
27
+ private
28
+
29
+ def on_test_step_created(event)
30
+ @step_definition_ids_by_test_step_id[event.test_step.id] = []
31
+ end
32
+
33
+ def on_step_activated(event)
34
+ @step_definition_ids_by_test_step_id[event.test_step.id] << event.step_match.step_definition.id
35
+ @step_match_arguments_by_test_step_id[event.test_step.id] = event.step_match.step_arguments
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,40 @@
1
+ require 'cucumber/formatter/errors'
2
+
3
+ module Cucumber
4
+ module Formatter
5
+ module Query
6
+ class TestCaseStartedByTestCase
7
+ def initialize(config)
8
+ @config = config
9
+ config.on_event :test_case_created, &method(:on_test_case_created)
10
+ config.on_event :test_case_started, &method(:on_test_case_started)
11
+
12
+ @attempts_by_test_case_id = {}
13
+ @test_case_started_id_by_test_case_id = {}
14
+ end
15
+
16
+ def attempt_by_test_case(test_case)
17
+ raise TestCaseUnknownError, "No test case found for #{test_case.id} }. Known: #{@attempts_by_test_case_id.keys}" unless @attempts_by_test_case_id.key?(test_case.id)
18
+ @attempts_by_test_case_id[test_case.id]
19
+ end
20
+
21
+ def test_case_started_id_by_test_case(test_case)
22
+ raise TestCaseUnknownError, "No test case found for #{test_case.id} }. Known: #{@test_case_started_id_by_test_case_id.keys}" unless @test_case_started_id_by_test_case_id.key?(test_case.id)
23
+ @test_case_started_id_by_test_case_id[test_case.id]
24
+ end
25
+
26
+ private
27
+
28
+ def on_test_case_created(event)
29
+ @attempts_by_test_case_id[event.test_case.id] = 0
30
+ @test_case_started_id_by_test_case_id[event.test_case.id] = nil
31
+ end
32
+
33
+ def on_test_case_started(event)
34
+ @attempts_by_test_case_id[event.test_case.id] += 1
35
+ @test_case_started_id_by_test_case_id[event.test_case.id] = @config.id_generator.new_id
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -47,7 +47,7 @@ module Cucumber
47
47
  def print_feature(test_case)
48
48
  uri = test_case.location.file
49
49
  return if @current_feature_uri == uri
50
- feature_name = gherkin_document(uri)[:feature][:name]
50
+ feature_name = gherkin_document(uri).feature.name
51
51
  @io.puts unless @current_feature_uri.nil?
52
52
  @io.puts feature_name
53
53
  @current_feature_uri = uri
@@ -44,7 +44,7 @@ module Cucumber
44
44
  stepdef_key = StepDefKey.new(step_definition.expression.to_s, step_definition.location)
45
45
  unless @stepdef_to_match[stepdef_key].map { |key| key[:location] }.include? test_step.location
46
46
  duration = DurationExtractor.new(result).result_duration
47
- keyword = @ast_lookup.step_source(test_step).step[:keyword]
47
+ keyword = @ast_lookup.step_source(test_step).step.keyword
48
48
 
49
49
  @stepdef_to_match[stepdef_key] << {
50
50
  keyword: keyword,
@@ -84,7 +84,7 @@ module Cucumber
84
84
  end
85
85
 
86
86
  def print_step_definition(stepdef_key)
87
- @io.print format_string(format('%.7f', stepdef_key.mean_duration), :skipped) + ' ' unless config.dry_run?
87
+ @io.print format_string(format('%<duration>.7f', duration: stepdef_key.mean_duration), :skipped) + ' ' unless config.dry_run?
88
88
  @io.print format_string(stepdef_key.regexp_source, stepdef_key.status)
89
89
  if config.source?
90
90
  indent = max_length - stepdef_key.regexp_source.unpack('U*').length
@@ -97,7 +97,7 @@ module Cucumber
97
97
  def print_steps(stepdef_key)
98
98
  @stepdef_to_match[stepdef_key].each do |step|
99
99
  @io.print ' '
100
- @io.print format_string(format('%.7f', step[:duration]), :skipped) + ' ' unless config.dry_run?
100
+ @io.print format_string(format('%<duration>.7f', duration: step[:duration]), :skipped) + ' ' unless config.dry_run?
101
101
  @io.print format_step(step[:keyword], step[:step_match], step[:status], nil)
102
102
  if config.source?
103
103
  indent = max_length - (step[:keyword].unpack('U*').length + step[:step_match].format_args.unpack('U*').length)