rspec-core 2.99.2 → 3.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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)