rspec-core 2.99.2 → 3.0.0.beta1

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 (165) hide show
  1. checksums.yaml +14 -6
  2. checksums.yaml.gz.sig +2 -0
  3. data.tar.gz.sig +0 -0
  4. data/Changelog.md +103 -191
  5. data/License.txt +1 -0
  6. data/README.md +4 -25
  7. data/features/Upgrade.md +2 -14
  8. data/features/command_line/dry_run.feature +29 -0
  9. data/features/command_line/example_name_option.feature +1 -1
  10. data/features/command_line/fail_fast.feature +26 -0
  11. data/features/command_line/format_option.feature +3 -3
  12. data/features/command_line/line_number_option.feature +16 -11
  13. data/features/command_line/order.feature +2 -3
  14. data/features/command_line/pattern_option.feature +3 -3
  15. data/features/command_line/randomization.feature +63 -0
  16. data/features/command_line/require_option.feature +2 -2
  17. data/features/command_line/ruby.feature +1 -1
  18. data/features/configuration/alias_example_to.feature +13 -22
  19. data/features/configuration/{backtrace_clean_patterns.feature → backtrace_exclusion_patterns.feature} +17 -14
  20. data/features/configuration/custom_settings.feature +11 -11
  21. data/features/configuration/overriding_global_ordering.feature +93 -0
  22. data/features/configuration/profile.feature +13 -13
  23. data/features/configuration/read_options_from_file.feature +7 -7
  24. data/features/example_groups/basic_structure.feature +1 -1
  25. data/features/example_groups/shared_context.feature +8 -8
  26. data/features/example_groups/shared_examples.feature +6 -14
  27. data/features/expectation_framework_integration/configure_expectation_framework.feature +27 -122
  28. data/features/filtering/exclusion_filters.feature +2 -5
  29. data/features/filtering/inclusion_filters.feature +1 -5
  30. data/features/formatters/json_formatter.feature +2 -2
  31. data/features/formatters/text_formatter.feature +4 -4
  32. data/features/helper_methods/arbitrary_methods.feature +2 -2
  33. data/features/helper_methods/let.feature +5 -5
  34. data/features/helper_methods/modules.feature +5 -8
  35. data/features/hooks/around_hooks.feature +2 -2
  36. data/features/hooks/before_and_after_hooks.feature +14 -14
  37. data/features/hooks/filtering.feature +12 -14
  38. data/features/metadata/described_class.feature +1 -1
  39. data/features/metadata/user_defined.feature +16 -29
  40. data/features/mock_framework_integration/use_flexmock.feature +1 -1
  41. data/features/mock_framework_integration/use_mocha.feature +1 -1
  42. data/features/mock_framework_integration/use_rr.feature +1 -1
  43. data/features/mock_framework_integration/use_rspec.feature +5 -5
  44. data/features/pending/pending_examples.feature +5 -5
  45. data/features/spec_files/arbitrary_file_suffix.feature +1 -1
  46. data/features/step_definitions/additional_cli_steps.rb +3 -3
  47. data/features/subject/explicit_subject.feature +8 -8
  48. data/features/subject/implicit_receiver.feature +29 -0
  49. data/features/subject/implicit_subject.feature +4 -4
  50. data/features/support/env.rb +10 -3
  51. data/features/support/require_expect_syntax_in_aruba_specs.rb +16 -0
  52. data/lib/rspec/core.rb +11 -48
  53. data/lib/rspec/core/backport_random.rb +302 -0
  54. data/lib/rspec/core/backtrace_formatter.rb +65 -0
  55. data/lib/rspec/core/command_line.rb +7 -18
  56. data/lib/rspec/core/configuration.rb +202 -507
  57. data/lib/rspec/core/configuration_options.rb +17 -30
  58. data/lib/rspec/core/example.rb +29 -39
  59. data/lib/rspec/core/example_group.rb +166 -259
  60. data/lib/rspec/core/filter_manager.rb +30 -47
  61. data/lib/rspec/core/flat_map.rb +17 -0
  62. data/lib/rspec/core/formatters.rb +0 -138
  63. data/lib/rspec/core/formatters/base_formatter.rb +46 -1
  64. data/lib/rspec/core/formatters/base_text_formatter.rb +38 -61
  65. data/lib/rspec/core/formatters/deprecation_formatter.rb +21 -52
  66. data/lib/rspec/core/formatters/helpers.rb +0 -28
  67. data/lib/rspec/core/formatters/html_formatter.rb +1 -1
  68. data/lib/rspec/core/formatters/json_formatter.rb +38 -9
  69. data/lib/rspec/core/formatters/snippet_extractor.rb +14 -5
  70. data/lib/rspec/core/hooks.rb +55 -39
  71. data/lib/rspec/core/memoized_helpers.rb +17 -167
  72. data/lib/rspec/core/metadata.rb +16 -64
  73. data/lib/rspec/core/option_parser.rb +30 -39
  74. data/lib/rspec/core/ordering.rb +154 -0
  75. data/lib/rspec/core/pending.rb +12 -69
  76. data/lib/rspec/core/project_initializer.rb +12 -10
  77. data/lib/rspec/core/rake_task.rb +5 -108
  78. data/lib/rspec/core/reporter.rb +15 -18
  79. data/lib/rspec/core/runner.rb +16 -30
  80. data/lib/rspec/core/shared_context.rb +3 -5
  81. data/lib/rspec/core/shared_example_group.rb +3 -51
  82. data/lib/rspec/core/shared_example_group/collection.rb +1 -19
  83. data/lib/rspec/core/version.rb +1 -1
  84. data/lib/rspec/core/warnings.rb +22 -0
  85. data/lib/rspec/core/world.rb +12 -8
  86. data/spec/command_line/order_spec.rb +20 -23
  87. data/spec/rspec/core/backtrace_formatter_spec.rb +216 -0
  88. data/spec/rspec/core/command_line_spec.rb +32 -48
  89. data/spec/rspec/core/configuration_options_spec.rb +19 -50
  90. data/spec/rspec/core/configuration_spec.rb +142 -713
  91. data/spec/rspec/core/drb_command_line_spec.rb +2 -0
  92. data/spec/rspec/core/dsl_spec.rb +0 -1
  93. data/spec/rspec/core/example_group_spec.rb +192 -223
  94. data/spec/rspec/core/example_spec.rb +40 -16
  95. data/spec/rspec/core/filter_manager_spec.rb +2 -2
  96. data/spec/rspec/core/formatters/base_formatter_spec.rb +0 -41
  97. data/spec/rspec/core/formatters/base_text_formatter_spec.rb +5 -123
  98. data/spec/rspec/core/formatters/deprecation_formatter_spec.rb +2 -87
  99. data/spec/rspec/core/formatters/documentation_formatter_spec.rb +2 -3
  100. data/spec/rspec/core/formatters/{text_mate_formatted.html → html_formatted-1.8.7-jruby.html} +44 -25
  101. data/spec/rspec/core/formatters/html_formatted-1.8.7-rbx.html +477 -0
  102. data/spec/rspec/core/formatters/{html_formatted.html → html_formatted-1.8.7.html} +42 -25
  103. data/spec/rspec/core/formatters/html_formatted-1.9.2.html +425 -0
  104. data/spec/rspec/core/formatters/html_formatted-1.9.3-jruby.html +416 -0
  105. data/spec/rspec/core/formatters/html_formatted-1.9.3-rbx.html +477 -0
  106. data/spec/rspec/core/formatters/html_formatted-1.9.3.html +419 -0
  107. data/spec/rspec/core/formatters/html_formatted-2.0.0.html +425 -0
  108. data/spec/rspec/core/formatters/html_formatter_spec.rb +21 -46
  109. data/spec/rspec/core/formatters/json_formatter_spec.rb +97 -8
  110. data/spec/rspec/core/hooks_filtering_spec.rb +5 -5
  111. data/spec/rspec/core/hooks_spec.rb +61 -47
  112. data/spec/rspec/core/memoized_helpers_spec.rb +20 -322
  113. data/spec/rspec/core/metadata_spec.rb +1 -24
  114. data/spec/rspec/core/option_parser_spec.rb +20 -62
  115. data/spec/rspec/core/ordering_spec.rb +102 -0
  116. data/spec/rspec/core/pending_example_spec.rb +0 -40
  117. data/spec/rspec/core/project_initializer_spec.rb +1 -25
  118. data/spec/rspec/core/rake_task_spec.rb +5 -72
  119. data/spec/rspec/core/random_spec.rb +47 -0
  120. data/spec/rspec/core/reporter_spec.rb +23 -48
  121. data/spec/rspec/core/runner_spec.rb +31 -39
  122. data/spec/rspec/core/shared_context_spec.rb +3 -15
  123. data/spec/rspec/core/shared_example_group/collection_spec.rb +4 -17
  124. data/spec/rspec/core/shared_example_group_spec.rb +12 -45
  125. data/spec/rspec/core/{deprecation_spec.rb → warnings_spec.rb} +3 -1
  126. data/spec/rspec/core_spec.rb +4 -21
  127. data/spec/spec_helper.rb +41 -5
  128. data/spec/support/helper_methods.rb +0 -29
  129. data/spec/support/sandboxed_mock_space.rb +0 -16
  130. data/spec/support/shared_example_groups.rb +7 -36
  131. data/spec/support/stderr_splitter.rb +36 -0
  132. metadata +163 -157
  133. metadata.gz.sig +1 -0
  134. data/exe/autospec +0 -13
  135. data/features/Autotest.md +0 -38
  136. data/features/configuration/treat_symbols_as_metadata_keys_with_true_values.feature +0 -52
  137. data/features/subject/attribute_of_subject.feature +0 -124
  138. data/features/subject/one_liner_syntax.feature +0 -71
  139. data/lib/autotest/discover.rb +0 -10
  140. data/lib/autotest/rspec2.rb +0 -77
  141. data/lib/rspec/core/backtrace_cleaner.rb +0 -46
  142. data/lib/rspec/core/backward_compatibility.rb +0 -55
  143. data/lib/rspec/core/caller_filter.rb +0 -60
  144. data/lib/rspec/core/deprecated_mutable_array_proxy.rb +0 -32
  145. data/lib/rspec/core/deprecation.rb +0 -26
  146. data/lib/rspec/core/extensions/instance_eval_with_args.rb +0 -44
  147. data/lib/rspec/core/extensions/kernel.rb +0 -9
  148. data/lib/rspec/core/extensions/module_eval_with_args.rb +0 -38
  149. data/lib/rspec/core/extensions/ordered.rb +0 -27
  150. data/lib/rspec/core/formatters/console_codes.rb +0 -42
  151. data/lib/rspec/core/formatters/text_mate_formatter.rb +0 -34
  152. data/lib/rspec/core/metadata_hash_builder.rb +0 -97
  153. data/lib/rspec/core/minitest_assertions_adapter.rb +0 -28
  154. data/lib/rspec/core/test_unit_assertions_adapter.rb +0 -30
  155. data/spec/autotest/discover_spec.rb +0 -49
  156. data/spec/autotest/failed_results_re_spec.rb +0 -45
  157. data/spec/autotest/rspec_spec.rb +0 -133
  158. data/spec/rspec/core/backtrace_cleaner_spec.rb +0 -68
  159. data/spec/rspec/core/caller_filter_spec.rb +0 -58
  160. data/spec/rspec/core/deprecations_spec.rb +0 -59
  161. data/spec/rspec/core/formatters/console_codes_spec.rb +0 -50
  162. data/spec/rspec/core/formatters/text_mate_formatter_spec.rb +0 -107
  163. data/spec/rspec/core/kernel_extensions_spec.rb +0 -9
  164. data/spec/rspec/core/pending_spec.rb +0 -27
  165. data/spec/support/silence_dsl_deprecations.rb +0 -32
@@ -66,51 +66,44 @@ module RSpec
66
66
  # @see Configuration#filter_run_including
67
67
  # @see Configuration#filter_run_excluding
68
68
  class FilterManager
69
- class << self
70
- def const_missing(name)
71
- case name
72
- when :DEFAULT_EXCLUSIONS
73
- RSpec.deprecate("RSpec::Core::FilterManager::DEFAULT_EXCLUSIONS is deprecated")
74
- default_exclusions
75
- when :STANDALONE_FILTERS
76
- RSpec.deprecate("RSpec::Core::FilterManager::STANDALONE_FILTERS is deprecated")
77
- standalone_filters
78
- else
79
- super
80
- end
81
- end
69
+ STANDALONE_FILTERS = [:locations, :line_numbers, :full_description]
82
70
 
83
- # @private
84
- def default_exclusions
85
- @default_exclusions ||= {
86
- :if => lambda { |value| !value },
87
- :unless => lambda { |value| value }
88
- }
89
- end
71
+ PROC_HEX_NUMBER = /0x[0-9a-f]+@/
72
+ PROJECT_DIR = File.expand_path('.')
73
+
74
+ def self.inspect_filter_hash(hash)
75
+ hash.inspect.gsub(PROC_HEX_NUMBER, '').gsub(PROJECT_DIR, '.').gsub(' (lambda)','')
76
+ end
90
77
 
91
- # @private
92
- def standalone_filters
93
- @standalone_filters ||= [:locations, :line_numbers, :full_description]
78
+ class InclusionFilterHash < Hash
79
+ def description
80
+ FilterManager.inspect_filter_hash self
94
81
  end
95
82
  end
96
83
 
97
- module Describable
98
- PROC_HEX_NUMBER = /0x[0-9a-f]+\s?@/
99
- PROJECT_DIR = File.expand_path('.')
84
+ class ExclusionFilterHash < Hash
85
+ CONDITIONAL_FILTERS = {
86
+ :if => lambda { |value| !value },
87
+ :unless => lambda { |value| value }
88
+ }
89
+
90
+ def initialize(*)
91
+ super
92
+ CONDITIONAL_FILTERS.each {|k,v| store(k, v)}
93
+ end
100
94
 
101
95
  def description
102
- reject { |k, v| RSpec::Core::FilterManager.default_exclusions[k] == v }.inspect.
103
- gsub(PROC_HEX_NUMBER, '').gsub(PROJECT_DIR, '.').gsub(' (lambda)','').gsub('__is_lambda__=true','')
96
+ FilterManager.inspect_filter_hash without_conditional_filters
104
97
  end
105
98
 
106
99
  def empty_without_conditional_filters?
107
- RSpec.deprecate("(inclusion_filter | exclusion_filter)#empty_without_conditional_filters? is deprecated")
108
- rules_empty?
100
+ without_conditional_filters.empty?
109
101
  end
110
102
 
111
- # @private
112
- def rules_empty?
113
- reject { |k, v| RSpec::Core::FilterManager.default_exclusions[k] == v }.empty?
103
+ private
104
+
105
+ def without_conditional_filters
106
+ reject {|k,v| CONDITIONAL_FILTERS[k] == v}
114
107
  end
115
108
  end
116
109
 
@@ -143,8 +136,8 @@ module RSpec
143
136
  attr_reader :exclusions, :inclusions
144
137
 
145
138
  def initialize
146
- @exclusions = self.class.default_exclusions.dup.extend(Describable)
147
- @inclusions = {}.extend(Describable)
139
+ @exclusions = ExclusionFilterHash.new
140
+ @inclusions = InclusionFilterHash.new
148
141
  extend(BackwardCompatibility)
149
142
  end
150
143
 
@@ -159,7 +152,7 @@ module RSpec
159
152
  end
160
153
 
161
154
  def empty?
162
- inclusions.empty? && exclusions.rules_empty?
155
+ inclusions.empty? && exclusions.empty_without_conditional_filters?
163
156
  end
164
157
 
165
158
  def prune(examples)
@@ -171,11 +164,6 @@ module RSpec
171
164
  end
172
165
 
173
166
  def exclude!(*args)
174
- RSpec.deprecate("FilterManager#exclude! is deprecated. Use FilterManager#exclude_only")
175
- exclude_only(*args)
176
- end
177
-
178
- def exclude_only(*args)
179
167
  replace(@exclusions, @inclusions, *args)
180
168
  end
181
169
 
@@ -192,11 +180,6 @@ module RSpec
192
180
  end
193
181
 
194
182
  def include!(*args)
195
- RSpec.deprecate("FilterManager#include! is deprecated. Use FilterManager#include_only")
196
- include_only(*args)
197
- end
198
-
199
- def include_only(*args)
200
183
  unless_standalone(*args) { replace(@inclusions, @exclusions, *args) }
201
184
  end
202
185
 
@@ -234,7 +217,7 @@ module RSpec
234
217
  end
235
218
 
236
219
  def is_standalone_filter?(filter)
237
- self.class.standalone_filters.any? {|key| filter.has_key?(key)}
220
+ STANDALONE_FILTERS.any? {|key| filter.has_key?(key)}
238
221
  end
239
222
  end
240
223
  end
@@ -0,0 +1,17 @@
1
+ module RSpec
2
+ module Core
3
+ module FlatMap
4
+ if [].respond_to?(:flat_map)
5
+ def flat_map(array)
6
+ array.flat_map { |item| yield item }
7
+ end
8
+ else # for 1.8.7
9
+ def flat_map(array)
10
+ array.map { |item| yield item }.flatten
11
+ end
12
+ end
13
+
14
+ module_function :flat_map
15
+ end
16
+ end
17
+ end
@@ -3,7 +3,6 @@
3
3
  # * progress (default) - prints dots for passing examples, `F` for failures, `*` for pending
4
4
  # * documentation - prints the docstrings passed to `describe` and `it` methods (and their aliases)
5
5
  # * html
6
- # * textmate - html plus links to editor
7
6
  # * json - useful for archiving data for subsequent analysis
8
7
  #
9
8
  # The progress formatter is the default, but you can choose any one or more of
@@ -52,141 +51,4 @@
52
51
  # @see RSpec::Core::Formatters::BaseTextFormatter
53
52
  # @see RSpec::Core::Reporter
54
53
  module RSpec::Core::Formatters
55
- autoload :DocumentationFormatter, 'rspec/core/formatters/documentation_formatter'
56
- autoload :HtmlFormatter, 'rspec/core/formatters/html_formatter'
57
- autoload :ProgressFormatter, 'rspec/core/formatters/progress_formatter'
58
- autoload :JsonFormatter, 'rspec/core/formatters/json_formatter'
59
- autoload :TextMateFormatter, 'rspec/core/formatters/text_mate_formatter'
60
-
61
- # @api private
62
- #
63
- # `RSpec::Core::Formatters::Loader` is an internal class for
64
- # managing formatters used by a particular configuration. It is
65
- # not expected to be used directly, but only through the configuration
66
- # interface.
67
- class Loader
68
-
69
- # @api private
70
- def initialize(reporter)
71
- @formatters = []
72
- @reporter = reporter
73
- @setup = false
74
- @default_formatter = 'progress'
75
- end
76
-
77
- # @return [Array] the loaded formatters
78
- attr_reader :formatters
79
-
80
- # @return [Reporter] the reporter
81
- attr_reader :reporter
82
-
83
- # @private
84
- def setup_default(output_stream, deprecation_stream)
85
- if @formatters.empty?
86
- add @default_formatter, output_stream
87
- end
88
- unless @formatters.any? { |formatter| DeprecationFormatter === formatter }
89
- add DeprecationFormatter, deprecation_stream, output_stream
90
- end
91
- @formatters.each do |formatter|
92
- @reporter.register_listener formatter, *RSpec::Core::Reporter::NOTIFICATIONS
93
- end
94
- @setup = true
95
- end
96
-
97
- # @private
98
- def add(formatter_to_use, *paths)
99
- formatter_class = find_formatter(formatter_to_use)
100
-
101
- args = paths.map { |p| p.respond_to?(:puts) ? p : file_at(p) }
102
-
103
- formatter = formatter_class.new(*args)
104
- if @setup
105
- @reporter.register_listener formatter, *RSpec::Core::Reporter::NOTIFICATIONS
106
- end
107
- @formatters << formatter unless duplicate_formatter_exists?(formatter)
108
-
109
- formatter
110
- end
111
-
112
- private
113
-
114
- def find_formatter(formatter_to_use)
115
- built_in_formatter(formatter_to_use) ||
116
- custom_formatter(formatter_to_use) ||
117
- (raise ArgumentError, "Formatter '#{formatter_to_use}' unknown - maybe you meant 'documentation' or 'progress'?.")
118
- end
119
-
120
- def duplicate_formatter_exists?(new_formatter)
121
- @formatters.any? do |formatter|
122
- formatter.class === new_formatter && formatter.output == new_formatter.output
123
- end
124
- end
125
-
126
- def built_in_formatter(key)
127
- case key.to_s
128
- when 'd', 'doc', 'documentation'
129
- DocumentationFormatter
130
- when 's', 'n', 'spec', 'nested'
131
- RSpec.deprecate "Using `#{key.to_s}` as a shortcut for the DocumentationFormatter",
132
- :replacement => "`d`, `doc`, or `documentation`"
133
- DocumentationFormatter
134
- when 'h', 'html'
135
- HtmlFormatter
136
- when 'p', 'progress'
137
- ProgressFormatter
138
- when 'j', 'json'
139
- JsonFormatter
140
- when 't', 'textmate'
141
- if defined?(::RSpec::Mate::Formatters::TextMateFormatter)
142
- RSpec.deprecate "Using the text`#{key.to_s}` as a shortcut for the TextMateFormatter",
143
- :replacement => "`::RSpec::Mate::Formatters::TextMateFormatter`"
144
- else
145
- RSpec.deprecate "Using rspec-core's `::RSpec::Core::TextMateFormatter`",
146
- :replacement => "the `rspec-tmbundle` gem and it's `::RSpec::Mate::Formatters::TextMateFormatter`"
147
- end
148
- TextMateFormatter
149
- end
150
- end
151
-
152
- def custom_formatter(formatter_ref)
153
- if Class === formatter_ref
154
- formatter_ref
155
- elsif string_const?(formatter_ref)
156
- begin
157
- formatter_ref.gsub(/^::/,'').split('::').inject(Object) { |const,string| const.const_get string }
158
- rescue NameError
159
- require( path_for(formatter_ref) ) ? retry : raise
160
- end
161
- end
162
- end
163
-
164
- def string_const?(str)
165
- str.is_a?(String) && /\A[A-Z][a-zA-Z0-9_:]*\z/ =~ str
166
- end
167
-
168
- def path_for(const_ref)
169
- underscore_with_fix_for_non_standard_rspec_naming(const_ref)
170
- end
171
-
172
- def underscore_with_fix_for_non_standard_rspec_naming(string)
173
- underscore(string).sub(%r{(^|/)r_spec($|/)}, '\\1rspec\\2')
174
- end
175
-
176
- # activesupport/lib/active_support/inflector/methods.rb, line 48
177
- def underscore(camel_cased_word)
178
- word = camel_cased_word.to_s.dup
179
- word.gsub!(/::/, '/')
180
- word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
181
- word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
182
- word.tr!("-", "_")
183
- word.downcase!
184
- word
185
- end
186
-
187
- def file_at(path)
188
- FileUtils.mkdir_p(File.dirname(path))
189
- File.new(path, 'w')
190
- end
191
- end
192
54
  end
@@ -161,6 +161,15 @@ module RSpec
161
161
  def dump_pending
162
162
  end
163
163
 
164
+ # @api public
165
+ #
166
+ # This methods is invoked form formatters to show slowest examples and example groups
167
+ # when using `--profile COUNT` (default 10).
168
+ #
169
+ # @return [nil]
170
+ def dump_profile
171
+ end
172
+
164
173
  # @private not intended for use outside RSpec.
165
174
  def seed(number)
166
175
  end
@@ -178,7 +187,7 @@ module RSpec
178
187
  # Formats the given backtrace based on configuration and
179
188
  # the metadata of the given example.
180
189
  def format_backtrace(backtrace, example)
181
- super(backtrace, example.metadata)
190
+ configuration.backtrace_formatter.format_backtrace(backtrace, example.metadata)
182
191
  end
183
192
 
184
193
  protected
@@ -240,6 +249,42 @@ module RSpec
240
249
  # Don't print out profiled info if there are failures and `--fail-fast` is used, it just clutters the output
241
250
  !profile_examples? || (fail_fast? && failure_count != 0)
242
251
  end
252
+
253
+ # @api private
254
+ def slowest_examples
255
+ number_of_examples = RSpec.configuration.profile_examples
256
+ sorted_examples = examples.sort_by {|example|
257
+ example.execution_result[:run_time] }.reverse.first(number_of_examples)
258
+
259
+ total, slows = [examples, sorted_examples].map do |exs|
260
+ exs.inject(0.0) {|i, e| i + e.execution_result[:run_time] }
261
+ end
262
+ {:examples => sorted_examples, :total => total, :slows => slows}
263
+ end
264
+
265
+ # @api private
266
+ def slowest_groups
267
+ number_of_examples = RSpec.configuration.profile_examples
268
+ example_groups = {}
269
+
270
+ examples.each do |example|
271
+ location = example.example_group.parent_groups.last.metadata[:example_group][:location]
272
+
273
+ example_groups[location] ||= Hash.new(0)
274
+ example_groups[location][:total_time] += example.execution_result[:run_time]
275
+ example_groups[location][:count] += 1
276
+ example_groups[location][:description] = example.example_group.top_level_description unless example_groups[location].has_key?(:description)
277
+ end
278
+
279
+ # stop if we've only one example group
280
+ return {} if example_groups.keys.length <= 1
281
+
282
+ example_groups.each_value do |hash|
283
+ hash[:average] = hash[:total_time].to_f / hash[:count]
284
+ end
285
+
286
+ example_groups.sort_by {|_, hash| -hash[:average]}.first(number_of_examples)
287
+ end
243
288
  end
244
289
  end
245
290
  end
@@ -1,5 +1,5 @@
1
1
  require 'rspec/core/formatters/base_formatter'
2
- require 'rspec/core/formatters/console_codes'
2
+ require 'set'
3
3
 
4
4
  module RSpec
5
5
  module Core
@@ -75,53 +75,31 @@ module RSpec
75
75
  end
76
76
 
77
77
  def dump_profile_slowest_examples
78
- number_of_examples = RSpec.configuration.profile_examples
79
- sorted_examples = examples.sort_by {|example|
80
- example.execution_result[:run_time] }.reverse.first(number_of_examples)
78
+ sorted_examples = slowest_examples
81
79
 
82
- total, slows = [examples, sorted_examples].map {|exs|
83
- exs.inject(0.0) {|i, e| i + e.execution_result[:run_time] }}
84
-
85
- time_taken = slows / total
80
+ time_taken = sorted_examples[:slows] / sorted_examples[:total]
86
81
  percentage = '%.1f' % ((time_taken.nan? ? 0.0 : time_taken) * 100)
87
82
 
88
- output.puts "\nTop #{sorted_examples.size} slowest examples (#{format_seconds(slows)} seconds, #{percentage}% of total time):\n"
83
+ output.puts "\nTop #{sorted_examples[:examples].size} slowest examples (#{format_seconds(sorted_examples[:slows])} seconds, #{percentage}% of total time):\n"
89
84
 
90
- sorted_examples.each do |example|
85
+ sorted_examples[:examples].each do |example|
91
86
  output.puts " #{example.full_description}"
92
- output.puts detail_color(" #{failure_color(format_seconds(example.execution_result[:run_time]))} #{failure_color("seconds")} #{format_caller(example.location)}")
87
+ output.puts " #{bold(format_seconds(example.execution_result[:run_time]))} #{bold("seconds")} #{format_caller(example.location)}"
93
88
  end
94
89
  end
95
90
 
96
91
  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
92
 
116
- sorted_groups = example_groups.sort_by {|_, hash| -hash[:average]}.first(number_of_examples)
93
+ sorted_groups = slowest_groups
94
+ return if sorted_groups.empty?
117
95
 
118
96
  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"
97
+ slowest_groups.each do |loc, hash|
98
+ average = "#{bold(format_seconds(hash[:average]))} #{bold("seconds")} average"
121
99
  total = "#{format_seconds(hash[:total_time])} seconds"
122
100
  count = pluralize(hash[:count], "example")
123
101
  output.puts " #{hash[:description]}"
124
- output.puts detail_color(" #{average} (#{total} / #{count}) #{loc}")
102
+ output.puts " #{average} (#{total} / #{count}) #{loc}"
125
103
  end
126
104
  end
127
105
 
@@ -144,10 +122,8 @@ module RSpec
144
122
  output.puts pending_color(" #{pending_example.full_description}")
145
123
  output.puts detail_color(" # #{pending_example.execution_result[:pending_message]}")
146
124
  output.puts detail_color(" # #{format_caller(pending_example.location)}")
147
- # instance_variable_get is a hack to avoid a deprecation warning,
148
- # it's only for 2.99.
149
125
  if pending_example.execution_result[:exception] \
150
- && RSpec.configuration.instance_variable_get(:@show_failures_in_pending_blocks)
126
+ && RSpec.configuration.show_failures_in_pending_blocks?
151
127
  dump_failure_info(pending_example)
152
128
  dump_backtrace(pending_example)
153
129
  end
@@ -162,43 +138,44 @@ module RSpec
162
138
  end
163
139
 
164
140
  def close
165
- return unless IO === output
166
- return if output.closed? || output == $stdout
167
-
168
- output.close
169
- end
170
-
171
- def self.const_missing(name)
172
- base = "RSpec::Core::Formatters::"
173
- case name
174
- when :VT100_COLORS then
175
- RSpec.deprecate("#{base}#{name}", :replacement => "#{base}ConsoleCodes::VT100_CODES")
176
- RSpec::Core::Formatters::ConsoleCodes::VT100_CODES
177
- when :VT100_COLOR_CODES then
178
- RSpec.deprecate("#{base}#{name}", :replacement => "#{base}ConsoleCodes::VT100_CODE_VALUES")
179
- require 'set'
180
- RSpec::Core::Formatters::ConsoleCodes::VT100_CODES.to_set
181
- else
182
- super
183
- end
141
+ output.close if IO === output && output != $stdout
184
142
  end
185
143
 
144
+ VT100_COLORS = {
145
+ :black => 30,
146
+ :red => 31,
147
+ :green => 32,
148
+ :yellow => 33,
149
+ :blue => 34,
150
+ :magenta => 35,
151
+ :cyan => 36,
152
+ :white => 37
153
+ }
154
+
155
+ VT100_COLOR_CODES = VT100_COLORS.values.to_set
156
+
186
157
  def color_code_for(code_or_symbol)
187
- ConsoleCodes.console_code_for(code_or_symbol)
158
+ if VT100_COLOR_CODES.include?(code_or_symbol)
159
+ code_or_symbol
160
+ else
161
+ VT100_COLORS.fetch(code_or_symbol) do
162
+ color_code_for(:white)
163
+ end
164
+ end
188
165
  end
189
166
 
190
167
  def colorize(text, code_or_symbol)
191
- ConsoleCodes.wrap(text, code_or_symbol)
168
+ "\e[#{color_code_for(code_or_symbol)}m#{text}\e[0m"
192
169
  end
193
170
 
194
171
  protected
195
172
 
196
173
  def bold(text)
197
- ConsoleCodes.wrap(text, :bold)
174
+ color_enabled? ? "\e[1m#{text}\e[0m" : text
198
175
  end
199
176
 
200
177
  def color(text, color_code)
201
- ConsoleCodes.wrap(text, color_code)
178
+ color_enabled? ? colorize(text, color_code) : text
202
179
  end
203
180
 
204
181
  def failure_color(text)
@@ -271,7 +248,7 @@ module RSpec
271
248
  private
272
249
 
273
250
  def format_caller(caller_info)
274
- backtrace_line(caller_info.to_s.split(':in `block').first)
251
+ configuration.backtrace_formatter.backtrace_line(caller_info.to_s.split(':in `block').first)
275
252
  end
276
253
 
277
254
  def dump_backtrace(example)
@@ -314,7 +291,7 @@ module RSpec
314
291
 
315
292
  def dump_shared_failure_info(group)
316
293
  output.puts "#{long_padding}Shared Example Group: \"#{group.metadata[:shared_group_name]}\" called from " +
317
- "#{backtrace_line(group.metadata[:example_group][:location])}"
294
+ "#{configuration.backtrace_formatter.backtrace_line(group.metadata[:example_group][:location])}"
318
295
  end
319
296
 
320
297
  def find_shared_group(example)