rspec-core 3.0.0.beta1 → 3.0.0.beta2

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