rspec-core 3.0.0.beta1 → 3.0.0.beta2

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 (145) hide show
  1. data.tar.gz.sig +0 -0
  2. data/Changelog.md +137 -0
  3. data/README.md +2 -2
  4. data/exe/rspec +2 -23
  5. data/features/README.md +1 -5
  6. data/features/command_line/README.md +7 -10
  7. data/features/command_line/exit_status.feature +1 -1
  8. data/features/command_line/format_option.feature +1 -1
  9. data/features/command_line/init.feature +40 -1
  10. data/features/command_line/line_number_option.feature +2 -2
  11. data/features/command_line/ruby.feature +5 -4
  12. data/features/configuration/enable_global_dsl.feature +54 -0
  13. data/features/example_groups/aliasing.feature +48 -0
  14. data/features/example_groups/basic_structure.feature +1 -1
  15. data/features/expectation_framework_integration/configure_expectation_framework.feature +1 -1
  16. data/features/filtering/if_and_unless.feature +0 -30
  17. data/features/formatters/custom_formatter.feature +32 -0
  18. data/features/formatters/regression_tests.feature +95 -0
  19. data/features/hooks/around_hooks.feature +1 -0
  20. data/features/hooks/before_and_after_hooks.feature +2 -2
  21. data/features/mock_framework_integration/use_flexmock.feature +11 -13
  22. data/features/mock_framework_integration/use_mocha.feature +11 -13
  23. data/features/mock_framework_integration/use_rr.feature +11 -13
  24. data/features/mock_framework_integration/use_rspec.feature +11 -13
  25. data/features/pending_and_skipped_examples/README.md +3 -0
  26. data/features/pending_and_skipped_examples/pending_examples.feature +118 -0
  27. data/features/pending_and_skipped_examples/skipped_examples.feature +106 -0
  28. data/features/step_definitions/additional_cli_steps.rb +34 -0
  29. data/features/subject/explicit_subject.feature +1 -1
  30. data/features/subject/one_liner_syntax.feature +71 -0
  31. data/lib/rspec/core.rb +6 -14
  32. data/lib/rspec/core/backtrace_formatter.rb +16 -4
  33. data/lib/rspec/core/command_line.rb +2 -3
  34. data/lib/rspec/core/configuration.rb +114 -125
  35. data/lib/rspec/core/configuration_options.rb +32 -18
  36. data/lib/rspec/core/dsl.rb +80 -18
  37. data/lib/rspec/core/example.rb +84 -33
  38. data/lib/rspec/core/example_group.rb +95 -43
  39. data/lib/rspec/core/filter_manager.rb +31 -40
  40. data/lib/rspec/core/formatters.rb +137 -0
  41. data/lib/rspec/core/formatters/base_formatter.rb +28 -41
  42. data/lib/rspec/core/formatters/base_text_formatter.rb +26 -37
  43. data/lib/rspec/core/formatters/deprecation_formatter.rb +48 -27
  44. data/lib/rspec/core/formatters/documentation_formatter.rb +27 -22
  45. data/lib/rspec/core/formatters/html_formatter.rb +48 -56
  46. data/lib/rspec/core/formatters/html_printer.rb +11 -18
  47. data/lib/rspec/core/formatters/json_formatter.rb +18 -22
  48. data/lib/rspec/core/formatters/legacy_formatter.rb +227 -0
  49. data/lib/rspec/core/formatters/progress_formatter.rb +7 -10
  50. data/lib/rspec/core/hooks.rb +250 -217
  51. data/lib/rspec/core/memoized_helpers.rb +43 -9
  52. data/lib/rspec/core/mocking_adapters/flexmock.rb +29 -0
  53. data/lib/rspec/core/{mocking/with_mocha.rb → mocking_adapters/mocha.rb} +19 -16
  54. data/lib/rspec/core/mocking_adapters/null.rb +12 -0
  55. data/lib/rspec/core/mocking_adapters/rr.rb +28 -0
  56. data/lib/rspec/core/mocking_adapters/rspec.rb +30 -0
  57. data/lib/rspec/core/notifications.rb +100 -0
  58. data/lib/rspec/core/option_parser.rb +11 -18
  59. data/lib/rspec/core/pending.rb +78 -47
  60. data/lib/rspec/core/project_initializer.rb +2 -49
  61. data/lib/rspec/core/project_initializer/dot_rspec +3 -0
  62. data/lib/rspec/core/project_initializer/spec_helper.rb +82 -0
  63. data/lib/rspec/core/rake_task.rb +5 -14
  64. data/lib/rspec/core/reporter.rb +24 -32
  65. data/lib/rspec/core/ruby_project.rb +1 -1
  66. data/lib/rspec/core/runner.rb +14 -4
  67. data/lib/rspec/core/shared_example_group.rb +40 -13
  68. data/lib/rspec/core/version.rb +1 -1
  69. data/spec/command_line/order_spec.rb +15 -15
  70. data/spec/rspec/core/backtrace_formatter_spec.rb +15 -1
  71. data/spec/rspec/core/command_line_spec.rb +18 -17
  72. data/spec/rspec/core/configuration_options_spec.rb +57 -34
  73. data/spec/rspec/core/configuration_spec.rb +162 -184
  74. data/spec/rspec/core/drb_command_line_spec.rb +5 -7
  75. data/spec/rspec/core/drb_options_spec.rb +2 -2
  76. data/spec/rspec/core/dsl_spec.rb +79 -15
  77. data/spec/rspec/core/example_group_spec.rb +253 -39
  78. data/spec/rspec/core/example_spec.rb +149 -33
  79. data/spec/rspec/core/filter_manager_spec.rb +9 -26
  80. data/spec/rspec/core/formatters/base_formatter_spec.rb +2 -5
  81. data/spec/rspec/core/formatters/base_text_formatter_spec.rb +42 -145
  82. data/spec/rspec/core/formatters/deprecation_formatter_spec.rb +64 -34
  83. data/spec/rspec/core/formatters/documentation_formatter_spec.rb +15 -28
  84. data/spec/rspec/core/formatters/helpers_spec.rb +2 -2
  85. data/spec/rspec/core/formatters/{html_formatted-1.8.7.html → html_formatted-2.1.0.html} +22 -44
  86. data/spec/rspec/core/formatters/{html_formatted-1.8.7-jruby.html → html_formatted.html} +30 -49
  87. data/spec/rspec/core/formatters/html_formatter_spec.rb +35 -19
  88. data/spec/rspec/core/formatters/json_formatter_spec.rb +42 -40
  89. data/spec/rspec/core/formatters/legacy_formatter_spec.rb +137 -0
  90. data/spec/rspec/core/formatters/progress_formatter_spec.rb +38 -25
  91. data/spec/rspec/core/formatters/snippet_extractor_spec.rb +1 -1
  92. data/spec/rspec/core/formatters_spec.rb +120 -0
  93. data/spec/rspec/core/hooks_filtering_spec.rb +1 -1
  94. data/spec/rspec/core/hooks_spec.rb +13 -2
  95. data/spec/rspec/core/memoized_helpers_spec.rb +17 -8
  96. data/spec/rspec/core/metadata_spec.rb +3 -3
  97. data/spec/rspec/core/option_parser_spec.rb +53 -46
  98. data/spec/rspec/core/ordering_spec.rb +4 -4
  99. data/spec/rspec/core/pending_example_spec.rb +23 -126
  100. data/spec/rspec/core/pending_spec.rb +8 -0
  101. data/spec/rspec/core/project_initializer_spec.rb +8 -41
  102. data/spec/rspec/core/rake_task_spec.rb +15 -4
  103. data/spec/rspec/core/random_spec.rb +1 -1
  104. data/spec/rspec/core/reporter_spec.rb +50 -37
  105. data/spec/rspec/core/resources/formatter_specs.rb +9 -11
  106. data/spec/rspec/core/rspec_matchers_spec.rb +1 -1
  107. data/spec/rspec/core/ruby_project_spec.rb +3 -3
  108. data/spec/rspec/core/runner_spec.rb +65 -23
  109. data/spec/rspec/core/shared_context_spec.rb +4 -4
  110. data/spec/rspec/core/shared_example_group/collection_spec.rb +1 -1
  111. data/spec/rspec/core/shared_example_group_spec.rb +20 -11
  112. data/spec/rspec/core/warnings_spec.rb +1 -1
  113. data/spec/rspec/core/world_spec.rb +10 -10
  114. data/spec/rspec/core_spec.rb +2 -2
  115. data/spec/spec_helper.rb +12 -24
  116. data/spec/support/config_options_helper.rb +1 -3
  117. data/spec/support/formatter_support.rb +83 -0
  118. data/spec/support/isolate_load_path_mutation.rb +1 -2
  119. data/spec/support/isolated_directory.rb +1 -1
  120. data/spec/support/isolated_home_directory.rb +1 -1
  121. data/spec/support/legacy_formatter_using_sub_classing_example.rb +87 -0
  122. data/spec/support/matchers.rb +20 -0
  123. data/spec/support/mathn_integration_support.rb +2 -2
  124. data/spec/support/old_style_formatter_example.rb +69 -0
  125. data/spec/support/shared_example_groups.rb +1 -1
  126. data/spec/support/spec_files.rb +3 -3
  127. metadata +192 -69
  128. metadata.gz.sig +3 -1
  129. checksums.yaml +0 -15
  130. checksums.yaml.gz.sig +0 -2
  131. data/features/configuration/show_failures_in_pending_blocks.feature +0 -61
  132. data/features/pending/pending_examples.feature +0 -229
  133. data/features/subject/implicit_receiver.feature +0 -29
  134. data/lib/rspec/core/mocking/with_absolutely_nothing.rb +0 -11
  135. data/lib/rspec/core/mocking/with_flexmock.rb +0 -27
  136. data/lib/rspec/core/mocking/with_rr.rb +0 -27
  137. data/lib/rspec/core/mocking/with_rspec.rb +0 -27
  138. data/spec/rspec/core/formatters/html_formatted-1.8.7-rbx.html +0 -477
  139. data/spec/rspec/core/formatters/html_formatted-1.9.2.html +0 -425
  140. data/spec/rspec/core/formatters/html_formatted-1.9.3-jruby.html +0 -416
  141. data/spec/rspec/core/formatters/html_formatted-1.9.3-rbx.html +0 -477
  142. data/spec/rspec/core/formatters/html_formatted-1.9.3.html +0 -419
  143. data/spec/rspec/core/formatters/html_formatted-2.0.0.html +0 -425
  144. data/spec/support/in_sub_process.rb +0 -37
  145. data/spec/support/sandboxed_mock_space.rb +0 -100
@@ -102,34 +102,16 @@ module RSpec
102
102
 
103
103
  private
104
104
 
105
- def without_conditional_filters
106
- reject {|k,v| CONDITIONAL_FILTERS[k] == v}
107
- end
108
- end
109
-
110
- module BackwardCompatibility
111
- def merge(orig, opposite, *updates)
112
- _warn_deprecated_keys(updates.last)
113
- super
114
- end
115
-
116
- def reverse_merge(orig, opposite, *updates)
117
- _warn_deprecated_keys(updates.last)
118
- super
119
- end
120
-
121
- # Supports a use case that probably doesn't exist: overriding the
122
- # if/unless procs.
123
- def _warn_deprecated_keys(updates)
124
- _warn_deprecated_key(:unless, updates) if updates.has_key?(:unless)
125
- _warn_deprecated_key(:if, updates) if updates.has_key?(:if)
126
- end
127
-
128
- # Emits a deprecation warning for keys that will not be supported in
129
- # the future.
130
- def _warn_deprecated_key(key, updates)
131
- RSpec.deprecate("FilterManager#exclude(#{key.inspect} => #{updates[key].inspect})")
132
- @exclusions[key] = updates.delete(key)
105
+ if RUBY_VERSION.to_f < 2.1
106
+ def without_conditional_filters
107
+ # On 1.8.7, Hash#reject returns a hash but Hash#select returns an array.
108
+ reject {|k,v| CONDITIONAL_FILTERS[k] == v}
109
+ end
110
+ else
111
+ def without_conditional_filters
112
+ # On ruby 2.1 #reject on a subclass of Hash emits warnings, but #select does not.
113
+ select {|k,v| CONDITIONAL_FILTERS[k] != v}
114
+ end
133
115
  end
134
116
  end
135
117
 
@@ -138,7 +120,6 @@ module RSpec
138
120
  def initialize
139
121
  @exclusions = ExclusionFilterHash.new
140
122
  @inclusions = InclusionFilterHash.new
141
- extend(BackwardCompatibility)
142
123
  end
143
124
 
144
125
  def add_location(file_path, line_numbers)
@@ -147,8 +128,8 @@ module RSpec
147
128
  # { "path/to/file.rb" => [37, 42] }
148
129
  locations = @inclusions.delete(:locations) || Hash.new {|h,k| h[k] = []}
149
130
  locations[File.expand_path(file_path)].push(*line_numbers)
150
- @inclusions.replace(:locations => locations)
151
- @exclusions.clear
131
+
132
+ replace_filters :locations => locations
152
133
  end
153
134
 
154
135
  def empty?
@@ -175,26 +156,36 @@ module RSpec
175
156
  @exclusions.empty? ? false : example.any_apply?(@exclusions)
176
157
  end
177
158
 
178
- def include(*args)
179
- unless_standalone(*args) { merge(@inclusions, @exclusions, *args) }
159
+ def include(*filters)
160
+ set_standalone_filter(*filters) || merge(@inclusions, @exclusions, *filters)
180
161
  end
181
162
 
182
- def include!(*args)
183
- unless_standalone(*args) { replace(@inclusions, @exclusions, *args) }
163
+ def include!(*filters)
164
+ set_standalone_filter(*filters) || replace(@inclusions, @exclusions, *filters)
184
165
  end
185
166
 
186
- def include_with_low_priority(*args)
187
- unless_standalone(*args) { reverse_merge(@inclusions, @exclusions, *args) }
167
+ def include_with_low_priority(*filters)
168
+ set_standalone_filter(*filters) || reverse_merge(@inclusions, @exclusions, *filters)
188
169
  end
189
170
 
190
171
  def include?(example)
191
172
  @inclusions.empty? ? true : example.any_apply?(@inclusions)
192
173
  end
193
174
 
194
- private
175
+ private
195
176
 
196
- def unless_standalone(*args)
197
- is_standalone_filter?(args.last) ? @inclusions.replace(args.last) : yield unless already_set_standalone_filter?
177
+ def set_standalone_filter(*args)
178
+ if already_set_standalone_filter?
179
+ true
180
+ elsif is_standalone_filter?(args.last)
181
+ replace_filters(args.last)
182
+ true
183
+ end
184
+ end
185
+
186
+ def replace_filters(rule)
187
+ @inclusions.replace(rule)
188
+ @exclusions.clear
198
189
  end
199
190
 
200
191
  def merge(orig, opposite, *updates)
@@ -1,3 +1,5 @@
1
+ require 'rspec/core/formatters/legacy_formatter'
2
+
1
3
  # ## Built-in Formatters
2
4
  #
3
5
  # * progress (default) - prints dots for passing examples, `F` for failures, `*` for pending
@@ -51,4 +53,139 @@
51
53
  # @see RSpec::Core::Formatters::BaseTextFormatter
52
54
  # @see RSpec::Core::Reporter
53
55
  module RSpec::Core::Formatters
56
+ autoload :DocumentationFormatter, 'rspec/core/formatters/documentation_formatter'
57
+ autoload :HtmlFormatter, 'rspec/core/formatters/html_formatter'
58
+ autoload :ProgressFormatter, 'rspec/core/formatters/progress_formatter'
59
+ autoload :JsonFormatter, 'rspec/core/formatters/json_formatter'
60
+
61
+ def self.register(formatter_class, *notifications)
62
+ Loader.formatters[formatter_class] = notifications
63
+ end
64
+
65
+ # @api private
66
+ #
67
+ # `RSpec::Core::Formatters::Loader` is an internal class for
68
+ # managing formatters used by a particular configuration. It is
69
+ # not expected to be used directly, but only through the configuration
70
+ # interface.
71
+ class Loader
72
+ # @api private
73
+ #
74
+ # Internal formatters are stored here when loaded
75
+ def self.formatters
76
+ @formatters ||= {}
77
+ end
78
+
79
+ # @api private
80
+ def initialize(reporter)
81
+ @formatters = []
82
+ @reporter = reporter
83
+ end
84
+ attr_reader :formatters, :reporter
85
+
86
+ # @api private
87
+ def setup_default(output_stream, deprecation_stream)
88
+ if @formatters.empty?
89
+ add 'progress', output_stream
90
+ end
91
+ unless @formatters.any? { |formatter| DeprecationFormatter === formatter }
92
+ add DeprecationFormatter, deprecation_stream, output_stream
93
+ end
94
+ end
95
+
96
+ # @api private
97
+ def add(formatter_to_use, *paths)
98
+ formatter_class = find_formatter(formatter_to_use)
99
+
100
+ args = paths.map { |p| String === p ? file_at(p) : p }
101
+
102
+ if !Loader.formatters[formatter_class].nil?
103
+ formatter = formatter_class.new(*args)
104
+ @reporter.register_listener formatter, *notifications_for(formatter_class)
105
+ else
106
+ formatter = LegacyFormatter.new(formatter_class, *args)
107
+ @reporter.register_listener formatter, *formatter.notifications
108
+ end
109
+
110
+ @formatters << formatter unless duplicate_formatter_exists?(formatter)
111
+ if formatter.is_a?(LegacyFormatter)
112
+ RSpec.warn_deprecation "The #{formatter_class} formatter uses the deprecated formatter interface.\n Formatter added at: #{::RSpec::CallerFilter.first_non_rspec_line}"
113
+ end
114
+
115
+ formatter
116
+ end
117
+
118
+ private
119
+
120
+ def find_formatter(formatter_to_use)
121
+ built_in_formatter(formatter_to_use) ||
122
+ custom_formatter(formatter_to_use) ||
123
+ (raise ArgumentError, "Formatter '#{formatter_to_use}' unknown - maybe you meant 'documentation' or 'progress'?.")
124
+ end
125
+
126
+ def duplicate_formatter_exists?(new_formatter)
127
+ @formatters.any? do |formatter|
128
+ formatter.class === new_formatter && formatter.output == new_formatter.output
129
+ end
130
+ end
131
+
132
+ def built_in_formatter(key)
133
+ case key.to_s
134
+ when 'd', 'doc', 'documentation'
135
+ DocumentationFormatter
136
+ when 'h', 'html'
137
+ HtmlFormatter
138
+ when 'p', 'progress'
139
+ ProgressFormatter
140
+ when 'j', 'json'
141
+ JsonFormatter
142
+ end
143
+ end
144
+
145
+ def notifications_for(formatter_class)
146
+ formatter_class.ancestors.inject(Set.new) do |notifications, klass|
147
+ notifications + Loader.formatters.fetch(klass) { Set.new }
148
+ end
149
+ end
150
+
151
+ def custom_formatter(formatter_ref)
152
+ if Class === formatter_ref
153
+ formatter_ref
154
+ elsif string_const?(formatter_ref)
155
+ begin
156
+ formatter_ref.gsub(/^::/,'').split('::').inject(Object) { |const,string| const.const_get string }
157
+ rescue NameError
158
+ require( path_for(formatter_ref) ) ? retry : raise
159
+ end
160
+ end
161
+ end
162
+
163
+ def string_const?(str)
164
+ str.is_a?(String) && /\A[A-Z][a-zA-Z0-9_:]*\z/ =~ str
165
+ end
166
+
167
+ def path_for(const_ref)
168
+ underscore_with_fix_for_non_standard_rspec_naming(const_ref)
169
+ end
170
+
171
+ def underscore_with_fix_for_non_standard_rspec_naming(string)
172
+ underscore(string).sub(%r{(^|/)r_spec($|/)}, '\\1rspec\\2')
173
+ end
174
+
175
+ # activesupport/lib/active_support/inflector/methods.rb, line 48
176
+ def underscore(camel_cased_word)
177
+ word = camel_cased_word.to_s.dup
178
+ word.gsub!(/::/, '/')
179
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
180
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
181
+ word.tr!("-", "_")
182
+ word.downcase!
183
+ word
184
+ end
185
+
186
+ def file_at(path)
187
+ FileUtils.mkdir_p(File.dirname(path))
188
+ File.new(path, 'w')
189
+ end
190
+ end
54
191
  end
@@ -5,16 +5,20 @@ module RSpec
5
5
  module Core
6
6
  module Formatters
7
7
  # RSpec's built-in formatters are all subclasses of RSpec::Core::Formatters::BaseTextFormatter,
8
- # but the BaseTextFormatter documents all of the methods needed to be implemented by a formatter,
9
- # as they are called from the reporter.
8
+ # but the BaseTextFormatter documents all of the notifications implemented as part of the standard
9
+ # interface. The reporter will issue these during a normal test suite run, but a formatter will
10
+ # only receive those notifications it has registered itself to receive.
10
11
  #
11
12
  # @see RSpec::Core::Formatters::BaseTextFormatter
12
13
  # @see RSpec::Core::Reporter
13
14
  class BaseFormatter
15
+
16
+ # all formatters inheriting from this formatter will receive these notifications
17
+ Formatters.register self, :start, :example_group_started, :example_started,
18
+ :example_pending, :example_failed, :close
14
19
  include Helpers
15
20
  attr_accessor :example_group
16
- attr_reader :duration, :examples, :output
17
- attr_reader :example_count, :pending_count, :failure_count
21
+ attr_reader :examples, :output
18
22
  attr_reader :failed_examples, :pending_examples
19
23
 
20
24
  # @api public
@@ -39,9 +43,9 @@ module RSpec
39
43
  # is {#example_group_started}.
40
44
  #
41
45
  # @param example_count
42
- def start(example_count)
46
+ def start(notification)
43
47
  start_sync_output
44
- @example_count = example_count
48
+ @example_count = notification.count
45
49
  end
46
50
 
47
51
  # @api public
@@ -54,17 +58,16 @@ module RSpec
54
58
  # {#example_pending}, or {#example_group_finished}.
55
59
  #
56
60
  # @param example_group
57
- def example_group_started(example_group)
58
- @example_group = example_group
61
+ def example_group_started(notification)
62
+ @example_group = notification.group
59
63
  end
60
64
 
65
+ # @method example_group_finished
61
66
  # @api public
62
67
  #
63
68
  # Invoked at the end of the execution of each example group.
64
69
  #
65
70
  # @param example_group subclass of `RSpec::Core::ExampleGroup`
66
- def example_group_finished(example_group)
67
- end
68
71
 
69
72
  # @api public
70
73
  #
@@ -72,24 +75,23 @@ module RSpec
72
75
  #
73
76
  # @param example instance of subclass of `RSpec::Core::ExampleGroup`
74
77
  # @return [Array]
75
- def example_started(example)
76
- examples << example
78
+ def example_started(notification)
79
+ examples << notification.example
77
80
  end
78
81
 
82
+ # @method example_passed
79
83
  # @api public
80
84
  #
81
85
  # Invoked when an example passes.
82
86
  #
83
87
  # @param example instance of subclass of `RSpec::Core::ExampleGroup`
84
- def example_passed(example)
85
- end
86
88
 
87
89
  # Invoked when an example is pending.
88
90
  #
89
91
  # @param example instance of subclass of `RSpec::Core::ExampleGroup`
90
92
  # @return [Array]
91
- def example_pending(example)
92
- @pending_examples << example
93
+ def example_pending(notification)
94
+ @pending_examples << notification.example
93
95
  end
94
96
 
95
97
  # @api public
@@ -98,26 +100,25 @@ module RSpec
98
100
  #
99
101
  # @param example instance of subclass of `RSpec::Core::ExampleGroup`
100
102
  # @return [Array]
101
- def example_failed(example)
102
- @failed_examples << example
103
+ def example_failed(notification)
104
+ @failed_examples << notification.example
103
105
  end
104
106
 
107
+ # @method message
105
108
  # @api public
106
109
  #
107
110
  # Used by the reporter to send messages to the output stream.
108
111
  #
109
112
  # @param [String] message
110
- def message(message)
111
- end
112
113
 
114
+ # @method stop
113
115
  # @api public
114
116
  #
115
117
  # Invoked after all examples have executed, before dumping post-run reports.
116
118
  #
117
119
  # @return [nil]
118
- def stop
119
- end
120
120
 
121
+ # @method start_dump
121
122
  # @api public
122
123
  #
123
124
  # This method is invoked after all of the examples have executed. The next method
@@ -125,17 +126,15 @@ module RSpec
125
126
  # (BaseTextFormatter then calls {#dump_failure} once for each failed example.)
126
127
  #
127
128
  # @return [nil]
128
- def start_dump
129
- end
130
129
 
130
+ # @method dump_failures
131
131
  # @api public
132
132
  #
133
133
  # Dumps detailed information about each example failure.
134
134
  #
135
135
  # @return [nil]
136
- def dump_failures
137
- end
138
136
 
137
+ # @method dump_summary
139
138
  # @api public
140
139
  #
141
140
  # This method is invoked after the dumping of examples and failures. Each parameter
@@ -145,40 +144,28 @@ module RSpec
145
144
  # @param example_count
146
145
  # @param failure_count
147
146
  # @param pending_count
148
- def dump_summary(duration, example_count, failure_count, pending_count)
149
- @duration = duration
150
- @example_count = example_count
151
- @failure_count = failure_count
152
- @pending_count = pending_count
153
- end
154
147
 
148
+ # @method dump_pending
155
149
  # @api public
156
150
  #
157
151
  # Outputs a report of pending examples. This gets invoked
158
152
  # after the summary if option is set to do so.
159
153
  #
160
154
  # @return [nil]
161
- def dump_pending
162
- end
163
155
 
156
+ # @method dump_profile
164
157
  # @api public
165
158
  #
166
159
  # This methods is invoked form formatters to show slowest examples and example groups
167
160
  # when using `--profile COUNT` (default 10).
168
161
  #
169
162
  # @return [nil]
170
- def dump_profile
171
- end
172
-
173
- # @private not intended for use outside RSpec.
174
- def seed(number)
175
- end
176
163
 
177
164
  # @api public
178
165
  #
179
166
  # Invoked at the very end, `close` allows the formatter to clean
180
167
  # up resources, e.g. open streams, etc.
181
- def close
168
+ def close(notification)
182
169
  restore_sync_output
183
170
  end
184
171
 
@@ -11,11 +11,14 @@ module RSpec
11
11
  # @see RSpec::Core::Formatters::BaseFormatter
12
12
  # @see RSpec::Core::Reporter
13
13
  class BaseTextFormatter < BaseFormatter
14
- def message(message)
15
- output.puts message
14
+ Formatters.register self, :message, :dump_summary, :dump_failures,
15
+ :dump_profile, :dump_pending, :seed
16
+
17
+ def message(notification)
18
+ output.puts notification.message
16
19
  end
17
20
 
18
- def dump_failures
21
+ def dump_failures(notification)
19
22
  return if failed_examples.empty?
20
23
  output.puts
21
24
  output.puts "Failures:"
@@ -33,20 +36,19 @@ module RSpec
33
36
  #
34
37
  # @param [String] string
35
38
  def colorise_summary(summary)
36
- if failure_count > 0
37
- color(summary, RSpec.configuration.failure_color)
38
- elsif pending_count > 0
39
- color(summary, RSpec.configuration.pending_color)
39
+ if summary.failure_count > 0
40
+ color(summary.summary_line, RSpec.configuration.failure_color)
41
+ elsif summary.pending_count > 0
42
+ color(summary.summary_line, RSpec.configuration.pending_color)
40
43
  else
41
- color(summary, RSpec.configuration.success_color)
44
+ color(summary.summary_line, RSpec.configuration.success_color)
42
45
  end
43
46
  end
44
47
 
45
- def dump_summary(duration, example_count, failure_count, pending_count)
46
- super(duration, example_count, failure_count, pending_count)
47
- dump_profile unless mute_profile_output?(failure_count)
48
- output.puts "\nFinished in #{format_duration(duration)}\n"
49
- output.puts colorise_summary(summary_line(example_count, failure_count, pending_count))
48
+ def dump_summary(summary)
49
+ dump_profile unless mute_profile_output?(summary.failure_count)
50
+ output.puts "\nFinished in #{format_duration(summary.duration)}\n"
51
+ output.puts colorise_summary(summary)
50
52
  dump_commands_to_rerun_failed_examples
51
53
  end
52
54
 
@@ -74,6 +76,7 @@ module RSpec
74
76
  dump_profile_slowest_example_groups
75
77
  end
76
78
 
79
+ # @api private
77
80
  def dump_profile_slowest_examples
78
81
  sorted_examples = slowest_examples
79
82
 
@@ -88,6 +91,7 @@ module RSpec
88
91
  end
89
92
  end
90
93
 
94
+ # @api private
91
95
  def dump_profile_slowest_example_groups
92
96
 
93
97
  sorted_groups = slowest_groups
@@ -103,18 +107,7 @@ module RSpec
103
107
  end
104
108
  end
105
109
 
106
- # @api public
107
- #
108
- # Outputs summary with number of examples, failures and pending.
109
- #
110
- def summary_line(example_count, failure_count, pending_count)
111
- summary = pluralize(example_count, "example")
112
- summary << ", " << pluralize(failure_count, "failure")
113
- summary << ", #{pending_count} pending" if pending_count > 0
114
- summary
115
- end
116
-
117
- def dump_pending
110
+ def dump_pending(notification)
118
111
  unless pending_examples.empty?
119
112
  output.puts
120
113
  output.puts "Pending:"
@@ -122,22 +115,18 @@ module RSpec
122
115
  output.puts pending_color(" #{pending_example.full_description}")
123
116
  output.puts detail_color(" # #{pending_example.execution_result[:pending_message]}")
124
117
  output.puts detail_color(" # #{format_caller(pending_example.location)}")
125
- if pending_example.execution_result[:exception] \
126
- && RSpec.configuration.show_failures_in_pending_blocks?
127
- dump_failure_info(pending_example)
128
- dump_backtrace(pending_example)
129
- end
130
118
  end
131
119
  end
132
120
  end
133
121
 
134
- def seed(number)
122
+ def seed(notification)
123
+ return unless notification.seed_used?
135
124
  output.puts
136
- output.puts "Randomized with seed #{number}"
125
+ output.puts "Randomized with seed #{notification.seed}"
137
126
  output.puts
138
127
  end
139
128
 
140
- def close
129
+ def close(notification)
141
130
  output.close if IO === output && output != $stdout
142
131
  end
143
132
 
@@ -251,8 +240,8 @@ module RSpec
251
240
  configuration.backtrace_formatter.backtrace_line(caller_info.to_s.split(':in `block').first)
252
241
  end
253
242
 
254
- def dump_backtrace(example)
255
- format_backtrace(example.execution_result[:exception].backtrace, example).each do |backtrace_info|
243
+ def dump_backtrace(example, key = :exception)
244
+ format_backtrace(example.execution_result[key].backtrace, example).each do |backtrace_info|
256
245
  output.puts detail_color("#{long_padding}# #{backtrace_info}")
257
246
  end
258
247
  end
@@ -271,8 +260,8 @@ module RSpec
271
260
  dump_failure_info(example)
272
261
  end
273
262
 
274
- def dump_failure_info(example)
275
- exception = example.execution_result[:exception]
263
+ def dump_failure_info(example, key = :exception)
264
+ exception = example.execution_result[key]
276
265
  exception_class_name = exception_class_name_for(exception)
277
266
  output.puts "#{long_padding}#{failure_color("Failure/Error:")} #{failure_color(read_failed_line(exception, example).strip)}"
278
267
  output.puts "#{long_padding}#{failure_color(exception_class_name)}:" unless exception_class_name =~ /RSpec/