rspec-core 2.13.1 → 2.14.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. data/Changelog.md +80 -0
  2. data/exe/autospec +1 -1
  3. data/features/README.md +2 -2
  4. data/features/command_line/format_option.feature +8 -14
  5. data/features/command_line/line_number_appended_to_path.feature +4 -4
  6. data/features/command_line/line_number_option.feature +1 -1
  7. data/features/command_line/rake_task.feature +2 -2
  8. data/features/command_line/require_option.feature +43 -0
  9. data/features/command_line/ruby.feature +2 -2
  10. data/features/command_line/warnings_option.feature +27 -0
  11. data/features/configuration/backtrace_clean_patterns.feature +2 -2
  12. data/features/configuration/deprecation_stream.feature +58 -0
  13. data/features/configuration/pattern.feature +8 -0
  14. data/features/configuration/profile.feature +59 -2
  15. data/features/configuration/read_options_from_file.feature +8 -5
  16. data/features/configuration/run_all_when_everything_filtered.feature +20 -4
  17. data/features/example_groups/basic_structure.feature +1 -1
  18. data/features/example_groups/shared_context.feature +1 -1
  19. data/features/example_groups/shared_examples.feature +72 -0
  20. data/features/filtering/exclusion_filters.feature +10 -10
  21. data/features/formatters/custom_formatter.feature +1 -1
  22. data/features/hooks/before_and_after_hooks.feature +19 -19
  23. data/features/mock_framework_integration/use_any_framework.feature +6 -6
  24. data/features/mock_framework_integration/use_flexmock.feature +3 -3
  25. data/features/mock_framework_integration/use_mocha.feature +3 -3
  26. data/features/mock_framework_integration/use_rr.feature +3 -3
  27. data/features/mock_framework_integration/use_rspec.feature +3 -3
  28. data/features/subject/implicit_subject.feature +1 -1
  29. data/lib/rspec/core.rb +20 -3
  30. data/lib/rspec/core/backtrace_cleaner.rb +46 -0
  31. data/lib/rspec/core/backward_compatibility.rb +3 -13
  32. data/lib/rspec/core/configuration.rb +136 -49
  33. data/lib/rspec/core/configuration_options.rb +19 -8
  34. data/lib/rspec/core/deprecation.rb +18 -30
  35. data/lib/rspec/core/example.rb +3 -3
  36. data/lib/rspec/core/example_group.rb +4 -3
  37. data/lib/rspec/core/extensions/kernel.rb +1 -1
  38. data/lib/rspec/core/filter_manager.rb +1 -1
  39. data/lib/rspec/core/formatters.rb +1 -1
  40. data/lib/rspec/core/formatters/base_formatter.rb +10 -1
  41. data/lib/rspec/core/formatters/base_text_formatter.rb +47 -10
  42. data/lib/rspec/core/formatters/deprecation_formatter.rb +35 -0
  43. data/lib/rspec/core/formatters/helpers.rb +12 -5
  44. data/lib/rspec/core/formatters/html_formatter.rb +7 -6
  45. data/lib/rspec/core/formatters/html_printer.rb +13 -12
  46. data/lib/rspec/core/formatters/json_formatter.rb +1 -2
  47. data/lib/rspec/core/formatters/text_mate_formatter.rb +1 -1
  48. data/lib/rspec/core/hooks.rb +9 -0
  49. data/lib/rspec/core/memoized_helpers.rb +19 -8
  50. data/lib/rspec/core/metadata.rb +3 -1
  51. data/lib/rspec/core/mocking/with_flexmock.rb +1 -1
  52. data/lib/rspec/core/mocking/with_rr.rb +1 -1
  53. data/lib/rspec/core/option_parser.rb +6 -2
  54. data/lib/rspec/core/pending.rb +1 -0
  55. data/lib/rspec/core/rake_task.rb +11 -19
  56. data/lib/rspec/core/reporter.rb +33 -4
  57. data/lib/rspec/core/shared_example_group.rb +56 -16
  58. data/lib/rspec/core/shared_example_group/collection.rb +42 -0
  59. data/lib/rspec/core/version.rb +1 -1
  60. data/lib/rspec/core/world.rb +2 -3
  61. data/spec/autotest/rspec_spec.rb +2 -2
  62. data/spec/rspec/core/backtrace_cleaner_spec.rb +68 -0
  63. data/spec/rspec/core/configuration_options_spec.rb +15 -4
  64. data/spec/rspec/core/configuration_spec.rb +202 -19
  65. data/spec/rspec/core/deprecation_spec.rb +41 -0
  66. data/spec/rspec/core/deprecations_spec.rb +10 -12
  67. data/spec/rspec/core/drb_command_line_spec.rb +1 -1
  68. data/spec/rspec/core/example_group_spec.rb +37 -36
  69. data/spec/rspec/core/example_spec.rb +25 -4
  70. data/spec/rspec/core/filter_manager_spec.rb +6 -6
  71. data/spec/rspec/core/formatters/base_text_formatter_spec.rb +101 -36
  72. data/spec/rspec/core/formatters/deprecation_formatter_spec.rb +78 -0
  73. data/spec/rspec/core/formatters/documentation_formatter_spec.rb +2 -2
  74. data/spec/rspec/core/formatters/helpers_spec.rb +23 -7
  75. data/spec/rspec/core/formatters/html_formatted-1.8.7-jruby.html +20 -14
  76. data/spec/rspec/core/formatters/html_formatted-1.8.7-rbx.html +69 -169
  77. data/spec/rspec/core/formatters/html_formatted-1.8.7.html +28 -23
  78. data/spec/rspec/core/formatters/html_formatted-1.9.2.html +42 -33
  79. data/spec/rspec/core/formatters/html_formatted-1.9.3-jruby.html +17 -23
  80. data/spec/rspec/core/formatters/html_formatted-1.9.3-rbx.html +57 -157
  81. data/spec/rspec/core/formatters/html_formatted-1.9.3.html +42 -33
  82. data/spec/rspec/core/formatters/html_formatted-2.0.0.html +42 -33
  83. data/spec/rspec/core/formatters/html_formatter_spec.rb +1 -0
  84. data/spec/rspec/core/formatters/progress_formatter_spec.rb +3 -3
  85. data/spec/rspec/core/formatters/text_mate_formatted-1.8.7-jruby.html +11 -14
  86. data/spec/rspec/core/formatters/text_mate_formatted-1.8.7-rbx.html +103 -203
  87. data/spec/rspec/core/formatters/text_mate_formatted-1.8.7.html +30 -25
  88. data/spec/rspec/core/formatters/text_mate_formatted-1.9.2.html +42 -33
  89. data/spec/rspec/core/formatters/text_mate_formatted-1.9.3-jruby.html +20 -14
  90. data/spec/rspec/core/formatters/text_mate_formatted-1.9.3-rbx.html +103 -203
  91. data/spec/rspec/core/formatters/text_mate_formatted-1.9.3.html +42 -33
  92. data/spec/rspec/core/formatters/text_mate_formatted-2.0.0.html +42 -33
  93. data/spec/rspec/core/formatters/text_mate_formatter_spec.rb +1 -0
  94. data/spec/rspec/core/memoized_helpers_spec.rb +28 -0
  95. data/spec/rspec/core/metadata_spec.rb +8 -3
  96. data/spec/rspec/core/option_parser_spec.rb +8 -0
  97. data/spec/rspec/core/project_initializer_spec.rb +2 -2
  98. data/spec/rspec/core/rake_task_spec.rb +8 -8
  99. data/spec/rspec/core/reporter_spec.rb +26 -6
  100. data/spec/rspec/core/resources/formatter_specs.rb +3 -3
  101. data/spec/rspec/core/shared_context_spec.rb +20 -0
  102. data/spec/rspec/core/shared_example_group/collection_spec.rb +70 -0
  103. data/spec/rspec/core/shared_example_group_spec.rb +4 -4
  104. data/spec/rspec/core/world_spec.rb +1 -3
  105. data/spec/rspec/core_spec.rb +20 -0
  106. data/spec/spec_helper.rb +29 -29
  107. data/spec/support/helper_methods.rb +9 -1
  108. data/spec/support/isolate_load_path_mutation.rb +6 -0
  109. data/spec/support/sandboxed_mock_space.rb +100 -0
  110. metadata +28 -13
  111. data/features/filtering/run_all_when_everything_filtered.feature +0 -46
  112. data/lib/rspec/core/load_path.rb +0 -3
@@ -19,15 +19,12 @@ module RSpec
19
19
  end
20
20
 
21
21
  def configure(config)
22
- formatters = options.delete(:formatters)
23
-
24
22
  config.filter_manager = filter_manager
23
+ process_options_into config
25
24
 
26
- order(options.keys, :libs, :requires, :default_path, :pattern).each do |key|
27
- force?(key) ? config.force(key => options[key]) : config.send("#{key}=", options[key])
28
- end
25
+ config.setup_load_path_and_require(options[:requires] || [])
29
26
 
30
- formatters.each {|pair| config.add_formatter(*pair) } if formatters
27
+ load_formatters_into config
31
28
  end
32
29
 
33
30
  def parse_options
@@ -55,6 +52,8 @@ module RSpec
55
52
 
56
53
  MERGED_OPTIONS = [:requires, :libs].to_set
57
54
 
55
+ UNPROCESSABLE_OPTIONS = [:formatters, :requires].to_set
56
+
58
57
  def force?(key)
59
58
  !NON_FORCED_OPTIONS.include?(key)
60
59
  end
@@ -66,6 +65,18 @@ module RSpec
66
65
  keys
67
66
  end
68
67
 
68
+ def process_options_into(config)
69
+ opts = options.reject { |k, _| UNPROCESSABLE_OPTIONS.include? k }
70
+
71
+ order(opts.keys, :libs, :default_path, :pattern).each do |key|
72
+ force?(key) ? config.force(key => opts[key]) : config.send("#{key}=", opts[key])
73
+ end
74
+ end
75
+
76
+ def load_formatters_into(config)
77
+ options[:formatters].each { |pair| config.add_formatter(*pair) } if options[:formatters]
78
+ end
79
+
69
80
  def extract_filters_from(*configs)
70
81
  configs.compact.each do |config|
71
82
  filter_manager.include config.delete(:inclusion_filter) if config.has_key?(:inclusion_filter)
@@ -112,11 +123,11 @@ module RSpec
112
123
  def args_from_options_file(path)
113
124
  return [] unless path && File.exist?(path)
114
125
  config_string = options_file_as_erb_string(path)
115
- config_string.split(/\n+/).map {|l| l.shellsplit}.flatten
126
+ config_string.split(/\n+/).map {|l| Shellwords.shellwords(l) }.flatten
116
127
  end
117
128
 
118
129
  def options_file_as_erb_string(path)
119
- ERB.new(File.read(path)).result(binding)
130
+ ERB.new(File.read(path), nil, '-').result(binding)
120
131
  end
121
132
 
122
133
  def custom_options_file
@@ -1,36 +1,24 @@
1
1
  module RSpec
2
- class << self
3
- # @private
4
- #
5
- # Used internally to print deprecation warnings
6
- def deprecate(method, alternate_method=nil, version=nil)
7
- version_string = version ? "rspec-#{version}" : "a future version of RSpec"
8
-
9
- message = <<-NOTICE
10
-
11
- *****************************************************************
12
- DEPRECATION WARNING: you are using deprecated behaviour that will
13
- be removed from #{version_string}.
14
-
15
- #{caller(0)[2]}
16
-
17
- * #{method} is deprecated.
18
- NOTICE
19
- if alternate_method
20
- message << <<-ADDITIONAL
21
- * please use #{alternate_method} instead.
22
- ADDITIONAL
2
+ module Core
3
+ module Deprecation
4
+ # @private
5
+ #
6
+ # Used internally to print deprecation warnings
7
+ def deprecate(deprecated, replacement_or_hash={}, ignore_version=nil)
8
+ # Temporarily support old and new APIs while we transition the other
9
+ # rspec libs to use a hash for the 2nd arg and no version arg
10
+ data = Hash === replacement_or_hash ? replacement_or_hash : { :replacement => replacement_or_hash }
11
+ RSpec.configuration.reporter.deprecation data.merge(:deprecated => deprecated, :call_site => caller(0)[2])
23
12
  end
24
13
 
25
- message << "*****************************************************************"
26
- warn_deprecation(message)
27
- end
28
-
29
- # @private
30
- #
31
- # Used internally to print deprecation warnings
32
- def warn_deprecation(message)
33
- warn message
14
+ # @private
15
+ #
16
+ # Used internally to print deprecation warnings
17
+ def warn_deprecation(message)
18
+ RSpec.configuration.reporter.deprecation :message => message
19
+ end
34
20
  end
35
21
  end
22
+
23
+ extend(Core::Deprecation)
36
24
  end
@@ -79,7 +79,7 @@ module RSpec
79
79
  def initialize(example_group_class, description, metadata, example_block=nil)
80
80
  @example_group_class, @options, @example_block = example_group_class, metadata, example_block
81
81
  @metadata = @example_group_class.metadata.for_example(description, metadata)
82
- @exception = nil
82
+ @example_group_instance = @exception = nil
83
83
  @pending_declared_in_example = false
84
84
  end
85
85
 
@@ -317,8 +317,8 @@ An error occurred #{context}
317
317
 
318
318
  def assign_generated_description
319
319
  return unless RSpec.configuration.expecting_with_rspec?
320
- if metadata[:description].empty? and !pending?
321
- metadata[:description] = RSpec::Matchers.generated_description
320
+ if metadata[:description_args].empty? and !pending?
321
+ metadata[:description_args] << RSpec::Matchers.generated_description
322
322
  end
323
323
  RSpec::Matchers.clear_generated_description
324
324
  end
@@ -162,7 +162,7 @@ module RSpec
162
162
  # @private
163
163
  def self.find_and_eval_shared(label, name, *args, &customization_block)
164
164
  raise ArgumentError, "Could not find shared #{label} #{name.inspect}" unless
165
- shared_block = world.shared_example_groups[name]
165
+ shared_block = shared_example_groups[name]
166
166
 
167
167
  module_eval_with_args(*args, &shared_block)
168
168
  module_eval(&customization_block) if customization_block
@@ -287,8 +287,8 @@ module RSpec
287
287
  args << build_metadata_hash_from(args)
288
288
  args.unshift(symbol_description) if symbol_description
289
289
  @metadata = RSpec::Core::Metadata.new(superclass_metadata).process(*args)
290
- world.configure_group(self)
291
290
  hooks.register_globals(self, RSpec.configuration.hooks)
291
+ world.configure_group(self)
292
292
  end
293
293
 
294
294
  # @private
@@ -444,7 +444,8 @@ An error occurred in an after(:all) hook.
444
444
 
445
445
  # @deprecated use {ExampleGroup#example}
446
446
  def running_example
447
- RSpec.deprecate("running_example", "example")
447
+ RSpec.deprecate("running_example",
448
+ :replacement => "example")
448
449
  example
449
450
  end
450
451
 
@@ -4,6 +4,6 @@ module Kernel
4
4
  # message to STDERR when ruby-debug is not loaded.
5
5
  def debugger(*args)
6
6
  (RSpec.configuration.error_stream || $stderr).puts "\n***** debugger statement ignored, use -d or --debug option to enable debugging\n#{caller(0)[1]}"
7
- end
7
+ end
8
8
  end
9
9
  end
@@ -107,7 +107,7 @@ module RSpec
107
107
  # Emits a deprecation warning for keys that will not be supported in
108
108
  # the future.
109
109
  def _warn_deprecated_key(key, updates)
110
- RSpec.warn_deprecation("\nDEPRECATION NOTICE: FilterManager#exclude(#{key.inspect} => #{updates[key].inspect}) is deprecated with no replacement, and will be removed from rspec-3.0.")
110
+ RSpec.deprecate("FilterManager#exclude(#{key.inspect} => #{updates[key].inspect})")
111
111
  @exclusions[key] = updates.delete(key)
112
112
  end
113
113
  end
@@ -16,7 +16,7 @@
16
16
  #
17
17
  # rspec --format documentation --format html --out results.html
18
18
  #
19
- # This example sends the output of the documentation formatter to `STDOUT`, and
19
+ # This example sends the output of the documentation formatter to `$stdout`, and
20
20
  # the output of the html formatter to results.html.
21
21
  #
22
22
  # ## Custom Formatters
@@ -105,7 +105,7 @@ module RSpec
105
105
  # @api public
106
106
  #
107
107
  # Used by the reporter to send messages to the output stream.
108
- #
108
+ #
109
109
  # @param [String] message
110
110
  def message(message)
111
111
  end
@@ -228,9 +228,18 @@ module RSpec
228
228
  configuration.profile_examples
229
229
  end
230
230
 
231
+ def fail_fast?
232
+ configuration.fail_fast
233
+ end
234
+
231
235
  def color_enabled?
232
236
  configuration.color_enabled?(output)
233
237
  end
238
+
239
+ def mute_profile_output?(failure_count)
240
+ # Don't print out profiled info if there are failures and `--fail-fast` is used, it just clutters the output
241
+ !profile_examples? || (fail_fast? && failure_count != 0)
242
+ end
234
243
  end
235
244
  end
236
245
  end
@@ -44,7 +44,7 @@ module RSpec
44
44
 
45
45
  def dump_summary(duration, example_count, failure_count, pending_count)
46
46
  super(duration, example_count, failure_count, pending_count)
47
- dump_profile if profile_examples?
47
+ dump_profile unless mute_profile_output?(failure_count)
48
48
  output.puts "\nFinished in #{format_duration(duration)}\n"
49
49
  output.puts colorise_summary(summary_line(example_count, failure_count, pending_count))
50
50
  dump_commands_to_rerun_failed_examples
@@ -67,9 +67,14 @@ module RSpec
67
67
 
68
68
  # @api public
69
69
  #
70
- # Outputs the slowest examples in a report when using `--profile COUNT` (default 10).
71
- #
70
+ # Outputs the slowest examples and example groups in a report when using `--profile COUNT` (default 10).
71
+ #
72
72
  def dump_profile
73
+ dump_profile_slowest_examples
74
+ dump_profile_slowest_example_groups
75
+ end
76
+
77
+ def dump_profile_slowest_examples
73
78
  number_of_examples = RSpec.configuration.profile_examples
74
79
  sorted_examples = examples.sort_by {|example|
75
80
  example.execution_result[:run_time] }.reverse.first(number_of_examples)
@@ -88,6 +93,38 @@ module RSpec
88
93
  end
89
94
  end
90
95
 
96
+ def dump_profile_slowest_example_groups
97
+ number_of_examples = RSpec.configuration.profile_examples
98
+ example_groups = {}
99
+
100
+ examples.each do |example|
101
+ location = example.example_group.parent_groups.last.metadata[:example_group][:location]
102
+
103
+ example_groups[location] ||= Hash.new(0)
104
+ example_groups[location][:total_time] += example.execution_result[:run_time]
105
+ example_groups[location][:count] += 1
106
+ example_groups[location][:description] = example.example_group.top_level_description unless example_groups[location].has_key?(:description)
107
+ end
108
+
109
+ # stop if we've only one example group
110
+ return if example_groups.keys.length <= 1
111
+
112
+ example_groups.each do |loc, hash|
113
+ hash[:average] = hash[:total_time].to_f / hash[:count]
114
+ end
115
+
116
+ sorted_groups = example_groups.sort_by {|_, hash| -hash[:average]}.first(number_of_examples)
117
+
118
+ output.puts "\nTop #{sorted_groups.size} slowest example groups:"
119
+ sorted_groups.each do |loc, hash|
120
+ average = "#{failure_color(format_seconds(hash[:average]))} #{failure_color("seconds")} average"
121
+ total = "#{format_seconds(hash[:total_time])} seconds"
122
+ count = pluralize(hash[:count], "example")
123
+ output.puts " #{hash[:description]}"
124
+ output.puts detail_color(" #{average} (#{total} / #{count}) #{loc}")
125
+ end
126
+ end
127
+
91
128
  # @api public
92
129
  #
93
130
  # Outputs summary with number of examples, failures and pending.
@@ -188,37 +225,37 @@ module RSpec
188
225
  end
189
226
 
190
227
  def red(text)
191
- RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#red", "#failure_color", "3.0")
228
+ RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#red", :replacement => "#failure_color")
192
229
  color(text, :red)
193
230
  end
194
231
 
195
232
  def green(text)
196
- RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#green", "#success_color", "3.0")
233
+ RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#green", :replacement => "#success_color")
197
234
  color(text, :green)
198
235
  end
199
236
 
200
237
  def yellow(text)
201
- RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#yellow", "#pending_color", "3.0")
238
+ RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#yellow", :replacement => "#pending_color")
202
239
  color(text, :yellow)
203
240
  end
204
241
 
205
242
  def blue(text)
206
- RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#blue", "#fixed_color", "3.0")
243
+ RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#blue", :replacement => "#fixed_color")
207
244
  color(text, :blue)
208
245
  end
209
246
 
210
247
  def magenta(text)
211
- RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#magenta", nil, "3.0")
248
+ RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#magenta")
212
249
  color(text, :magenta)
213
250
  end
214
251
 
215
252
  def cyan(text)
216
- RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#cyan", "#detail_color", "3.0")
253
+ RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#cyan", :replacement => "#detail_color")
217
254
  color(text, :cyan)
218
255
  end
219
256
 
220
257
  def white(text)
221
- RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#white", "#default_color", "3.0")
258
+ RSpec.deprecate("RSpec::Core::Formatters::BaseTextFormatter#white", :replacement => "#default_color")
222
259
  color(text, :white)
223
260
  end
224
261
 
@@ -0,0 +1,35 @@
1
+ module RSpec
2
+ module Core
3
+ module Formatters
4
+ class DeprecationFormatter
5
+ def initialize(deprecation_stream=$stderr, summary_stream=$stdout)
6
+ @deprecation_stream = deprecation_stream
7
+ @summary_stream = summary_stream
8
+ @count = 0
9
+ end
10
+
11
+ def deprecation(data)
12
+ @count += 1
13
+ if data[:message]
14
+ @deprecation_stream.print data[:message]
15
+ else
16
+ @deprecation_stream.print "DEPRECATION: " unless File === @deprecation_stream
17
+ @deprecation_stream.print "#{data[:deprecated]} is deprecated."
18
+ @deprecation_stream.print " Use #{data[:replacement]} instead." if data[:replacement]
19
+ @deprecation_stream.print " Called from #{data[:call_site]}." if data[:call_site]
20
+ @deprecation_stream.puts
21
+ end
22
+ end
23
+
24
+ def deprecation_summary
25
+ if @count > 0 && File === @deprecation_stream
26
+ @summary_stream.print "\n#{@count} deprecation"
27
+ @summary_stream.print "s" if @count > 1
28
+ @summary_stream.print " logged to "
29
+ @summary_stream.puts @deprecation_stream.path
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -18,7 +18,7 @@ module RSpec
18
18
  protected
19
19
 
20
20
  def backtrace_line(line)
21
- return nil if RSpec.configuration.cleaned_from_backtrace?(line)
21
+ return nil if RSpec.configuration.backtrace_cleaner.exclude?(line)
22
22
  RSpec::Core::Metadata::relative_path(line)
23
23
  rescue SecurityError
24
24
  nil
@@ -43,20 +43,27 @@ module RSpec
43
43
  # format_duration(1) #=> "1 minute 1 second"
44
44
  # format_duration(135.14) #=> "2 minutes 15.14 seconds"
45
45
  def format_duration(duration)
46
+ precision = case
47
+ when duration < 1; SUB_SECOND_PRECISION
48
+ when duration < 120; DEFAULT_PRECISION
49
+ when duration < 300; 1
50
+ else 0
51
+ end
52
+
46
53
  if duration > 60
47
54
  minutes = duration.to_i / 60
48
55
  seconds = duration - minutes * 60
49
56
 
50
- "#{pluralize(minutes, 'minute')} #{pluralize(format_seconds(seconds), 'second')}"
57
+ "#{pluralize(minutes, 'minute')} #{pluralize(format_seconds(seconds, precision), 'second')}"
51
58
  else
52
- pluralize(format_seconds(duration), 'second')
59
+ pluralize(format_seconds(duration, precision), 'second')
53
60
  end
54
61
  end
55
62
 
56
63
  # @api private
57
64
  #
58
65
  # Formats seconds to have 5 digits of precision with trailing zeros removed if the number
59
- # if less than 1 or with 2 digits of precision if the number is greater than zero.
66
+ # is less than 1 or with 2 digits of precision if the number is greater than zero.
60
67
  #
61
68
  # @param [Float] float
62
69
  # @return [String] formatted float
@@ -69,7 +76,7 @@ module RSpec
69
76
  # The precision used is set in {Helpers::SUB_SECOND_PRECISION} and {Helpers::DEFAULT_PRECISION}.
70
77
  #
71
78
  # @see #strip_trailing_zeroes
72
- def format_seconds(float)
79
+ def format_seconds(float, precision = nil)
73
80
  precision ||= (float < 1) ? SUB_SECOND_PRECISION : DEFAULT_PRECISION
74
81
  formatted = sprintf("%.#{precision}f", float)
75
82
  strip_trailing_zeroes(formatted)
@@ -72,7 +72,7 @@ module RSpec
72
72
 
73
73
  unless @header_red
74
74
  @header_red = true
75
- @printer.make_header_red
75
+ @printer.make_header_red
76
76
  end
77
77
 
78
78
  unless @example_group_red
@@ -84,22 +84,23 @@ module RSpec
84
84
 
85
85
  exception = example.metadata[:execution_result][:exception]
86
86
  exception_details = if exception
87
- {
88
- :message => exception.message,
87
+ {
88
+ :message => exception.message,
89
89
  :backtrace => format_backtrace(exception.backtrace, example).join("\n")
90
90
  }
91
91
  else
92
- false
92
+ false
93
93
  end
94
94
  extra = extra_failure_content(exception)
95
95
 
96
- @printer.print_example_failed(
96
+ @printer.print_example_failed(
97
97
  exception.pending_fixed?,
98
98
  example.description,
99
99
  example.execution_result[:run_time],
100
100
  @failed_examples.size,
101
101
  exception_details,
102
- (extra == "") ? false : extra
102
+ (extra == "") ? false : extra,
103
+ true
103
104
  )
104
105
  @printer.flush
105
106
  end