rspec-core 3.0.4 → 3.12.2

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 (85) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data/.document +1 -1
  4. data/.yardopts +2 -1
  5. data/Changelog.md +888 -2
  6. data/{License.txt → LICENSE.md} +6 -5
  7. data/README.md +165 -24
  8. data/lib/rspec/autorun.rb +1 -0
  9. data/lib/rspec/core/backtrace_formatter.rb +19 -20
  10. data/lib/rspec/core/bisect/coordinator.rb +62 -0
  11. data/lib/rspec/core/bisect/example_minimizer.rb +173 -0
  12. data/lib/rspec/core/bisect/fork_runner.rb +138 -0
  13. data/lib/rspec/core/bisect/server.rb +61 -0
  14. data/lib/rspec/core/bisect/shell_command.rb +126 -0
  15. data/lib/rspec/core/bisect/shell_runner.rb +73 -0
  16. data/lib/rspec/core/bisect/utilities.rb +69 -0
  17. data/lib/rspec/core/configuration.rb +1287 -246
  18. data/lib/rspec/core/configuration_options.rb +95 -35
  19. data/lib/rspec/core/did_you_mean.rb +46 -0
  20. data/lib/rspec/core/drb.rb +21 -12
  21. data/lib/rspec/core/dsl.rb +10 -6
  22. data/lib/rspec/core/example.rb +305 -113
  23. data/lib/rspec/core/example_group.rb +431 -223
  24. data/lib/rspec/core/example_status_persister.rb +235 -0
  25. data/lib/rspec/core/filter_manager.rb +86 -115
  26. data/lib/rspec/core/flat_map.rb +6 -4
  27. data/lib/rspec/core/formatters/base_bisect_formatter.rb +45 -0
  28. data/lib/rspec/core/formatters/base_formatter.rb +14 -116
  29. data/lib/rspec/core/formatters/base_text_formatter.rb +18 -21
  30. data/lib/rspec/core/formatters/bisect_drb_formatter.rb +29 -0
  31. data/lib/rspec/core/formatters/bisect_progress_formatter.rb +157 -0
  32. data/lib/rspec/core/formatters/console_codes.rb +29 -18
  33. data/lib/rspec/core/formatters/deprecation_formatter.rb +16 -16
  34. data/lib/rspec/core/formatters/documentation_formatter.rb +49 -16
  35. data/lib/rspec/core/formatters/exception_presenter.rb +525 -0
  36. data/lib/rspec/core/formatters/failure_list_formatter.rb +23 -0
  37. data/lib/rspec/core/formatters/fallback_message_formatter.rb +28 -0
  38. data/lib/rspec/core/formatters/helpers.rb +45 -15
  39. data/lib/rspec/core/formatters/html_formatter.rb +33 -28
  40. data/lib/rspec/core/formatters/html_printer.rb +30 -20
  41. data/lib/rspec/core/formatters/html_snippet_extractor.rb +120 -0
  42. data/lib/rspec/core/formatters/json_formatter.rb +18 -9
  43. data/lib/rspec/core/formatters/profile_formatter.rb +10 -9
  44. data/lib/rspec/core/formatters/progress_formatter.rb +5 -4
  45. data/lib/rspec/core/formatters/protocol.rb +182 -0
  46. data/lib/rspec/core/formatters/snippet_extractor.rb +113 -82
  47. data/lib/rspec/core/formatters/syntax_highlighter.rb +91 -0
  48. data/lib/rspec/core/formatters.rb +81 -41
  49. data/lib/rspec/core/hooks.rb +314 -244
  50. data/lib/rspec/core/invocations.rb +87 -0
  51. data/lib/rspec/core/memoized_helpers.rb +161 -51
  52. data/lib/rspec/core/metadata.rb +132 -61
  53. data/lib/rspec/core/metadata_filter.rb +224 -64
  54. data/lib/rspec/core/minitest_assertions_adapter.rb +6 -3
  55. data/lib/rspec/core/mocking_adapters/flexmock.rb +4 -2
  56. data/lib/rspec/core/mocking_adapters/mocha.rb +11 -9
  57. data/lib/rspec/core/mocking_adapters/null.rb +2 -0
  58. data/lib/rspec/core/mocking_adapters/rr.rb +3 -1
  59. data/lib/rspec/core/mocking_adapters/rspec.rb +3 -1
  60. data/lib/rspec/core/notifications.rb +192 -206
  61. data/lib/rspec/core/option_parser.rb +174 -69
  62. data/lib/rspec/core/ordering.rb +48 -35
  63. data/lib/rspec/core/output_wrapper.rb +29 -0
  64. data/lib/rspec/core/pending.rb +25 -33
  65. data/lib/rspec/core/profiler.rb +34 -0
  66. data/lib/rspec/core/project_initializer/.rspec +0 -2
  67. data/lib/rspec/core/project_initializer/spec/spec_helper.rb +59 -39
  68. data/lib/rspec/core/project_initializer.rb +5 -3
  69. data/lib/rspec/core/rake_task.rb +99 -55
  70. data/lib/rspec/core/reporter.rb +128 -15
  71. data/lib/rspec/core/ruby_project.rb +14 -6
  72. data/lib/rspec/core/runner.rb +96 -45
  73. data/lib/rspec/core/sandbox.rb +37 -0
  74. data/lib/rspec/core/set.rb +54 -0
  75. data/lib/rspec/core/shared_example_group.rb +133 -43
  76. data/lib/rspec/core/shell_escape.rb +49 -0
  77. data/lib/rspec/core/test_unit_assertions_adapter.rb +4 -4
  78. data/lib/rspec/core/version.rb +1 -1
  79. data/lib/rspec/core/warnings.rb +6 -6
  80. data/lib/rspec/core/world.rb +172 -68
  81. data/lib/rspec/core.rb +66 -21
  82. data.tar.gz.sig +0 -0
  83. metadata +93 -69
  84. metadata.gz.sig +0 -0
  85. data/lib/rspec/core/backport_random.rb +0 -336
@@ -1,9 +1,13 @@
1
+ RSpec::Support.require_rspec_support "directory_maker"
2
+
1
3
  # ## Built-in Formatters
2
4
  #
3
- # * progress (default) - prints dots for passing examples, `F` for failures, `*` for pending
4
- # * documentation - prints the docstrings passed to `describe` and `it` methods (and their aliases)
5
+ # * progress (default) - Prints dots for passing examples, `F` for failures, `*`
6
+ # for pending.
7
+ # * documentation - Prints the docstrings passed to `describe` and `it` methods
8
+ # (and their aliases).
5
9
  # * html
6
- # * json - useful for archiving data for subsequent analysis
10
+ # * json - Useful for archiving data for subsequent analysis.
7
11
  #
8
12
  # The progress formatter is the default, but you can choose any one or more of
9
13
  # the other formatters by passing with the `--format` (or `-f` for short)
@@ -21,7 +25,7 @@
21
25
  # ## Custom Formatters
22
26
  #
23
27
  # You can tell RSpec to use a custom formatter by passing its path and name to
24
- # the `rspec` commmand. For example, if you define MyCustomFormatter in
28
+ # the `rspec` command. For example, if you define MyCustomFormatter in
25
29
  # path/to/my_custom_formatter.rb, you would type this command:
26
30
  #
27
31
  # rspec --require path/to/my_custom_formatter.rb --format MyCustomFormatter
@@ -63,15 +67,20 @@
63
67
  # @see RSpec::Core::Formatters::BaseTextFormatter
64
68
  # @see RSpec::Core::Reporter
65
69
  module RSpec::Core::Formatters
66
- autoload :DocumentationFormatter, 'rspec/core/formatters/documentation_formatter'
67
- autoload :HtmlFormatter, 'rspec/core/formatters/html_formatter'
68
- autoload :ProgressFormatter, 'rspec/core/formatters/progress_formatter'
69
- autoload :ProfileFormatter, 'rspec/core/formatters/profile_formatter'
70
- autoload :JsonFormatter, 'rspec/core/formatters/json_formatter'
70
+ autoload :DocumentationFormatter, 'rspec/core/formatters/documentation_formatter'
71
+ autoload :HtmlFormatter, 'rspec/core/formatters/html_formatter'
72
+ autoload :FallbackMessageFormatter, 'rspec/core/formatters/fallback_message_formatter'
73
+ autoload :ProgressFormatter, 'rspec/core/formatters/progress_formatter'
74
+ autoload :ProfileFormatter, 'rspec/core/formatters/profile_formatter'
75
+ autoload :JsonFormatter, 'rspec/core/formatters/json_formatter'
76
+ autoload :BisectDRbFormatter, 'rspec/core/formatters/bisect_drb_formatter'
77
+ autoload :ExceptionPresenter, 'rspec/core/formatters/exception_presenter'
78
+ autoload :FailureListFormatter, 'rspec/core/formatters/failure_list_formatter'
71
79
 
72
80
  # Register the formatter class
73
81
  # @param formatter_class [Class] formatter class to register
74
- # @param notifications [Symbol, ...] one or more notifications to be registered to the specified formatter
82
+ # @param notifications [Array<Symbol>] one or more notifications to be
83
+ # registered to the specified formatter
75
84
  #
76
85
  # @see RSpec::Core::Formatters::BaseFormatter
77
86
  def self.register(formatter_class, *notifications)
@@ -87,7 +96,7 @@ module RSpec::Core::Formatters
87
96
  class Loader
88
97
  # @api private
89
98
  #
90
- # Internal formatters are stored here when loaded
99
+ # Internal formatters are stored here when loaded.
91
100
  def self.formatters
92
101
  @formatters ||= {}
93
102
  end
@@ -108,41 +117,52 @@ module RSpec::Core::Formatters
108
117
  # @return [String] the default formatter to setup, defaults to `progress`
109
118
  attr_accessor :default_formatter
110
119
 
120
+ # @private
121
+ def prepare_default(output_stream, deprecation_stream)
122
+ reporter.prepare_default(self, output_stream, deprecation_stream)
123
+ end
124
+
111
125
  # @private
112
126
  def setup_default(output_stream, deprecation_stream)
113
- if @formatters.empty?
114
- add default_formatter, output_stream
115
- end
127
+ add default_formatter, output_stream if @formatters.empty?
128
+
116
129
  unless @formatters.any? { |formatter| DeprecationFormatter === formatter }
117
130
  add DeprecationFormatter, deprecation_stream, output_stream
118
131
  end
119
- if RSpec.configuration.profile_examples? && !existing_formatter_implements?(:dump_profile)
120
- add RSpec::Core::Formatters::ProfileFormatter, output_stream
132
+
133
+ unless existing_formatter_implements?(:message)
134
+ add FallbackMessageFormatter, output_stream
121
135
  end
136
+
137
+ return unless RSpec.configuration.profile_examples?
138
+ return if existing_formatter_implements?(:dump_profile)
139
+
140
+ add RSpec::Core::Formatters::ProfileFormatter, output_stream
122
141
  end
123
142
 
124
143
  # @private
125
144
  def add(formatter_to_use, *paths)
145
+ # If a formatter instance was passed, we can register it directly,
146
+ # with no need for any of the further processing that happens below.
147
+ if Loader.formatters.key?(formatter_to_use.class)
148
+ register formatter_to_use, notifications_for(formatter_to_use.class)
149
+ return
150
+ end
151
+
126
152
  formatter_class = find_formatter(formatter_to_use)
127
153
 
128
- args = paths.map { |p| p.respond_to?(:puts) ? p : file_at(p) }
154
+ args = paths.map { |p| p.respond_to?(:puts) ? p : open_stream(p) }
129
155
 
130
156
  if !Loader.formatters[formatter_class].nil?
131
157
  formatter = formatter_class.new(*args)
132
- @reporter.register_listener formatter, *notifications_for(formatter_class)
158
+ register formatter, notifications_for(formatter_class)
133
159
  elsif defined?(RSpec::LegacyFormatters)
134
160
  formatter = RSpec::LegacyFormatters.load_formatter formatter_class, *args
135
- @reporter.register_listener formatter, *formatter.notifications
161
+ register formatter, formatter.notifications
136
162
  else
137
- line = ::RSpec::CallerFilter.first_non_rspec_line
138
- if line
139
- call_site = "Formatter added at: #{line}"
140
- else
141
- call_site = "The formatter was added via command line flag or your "+
142
- "`.rspec` file."
143
- end
163
+ call_site = "Formatter added at: #{::RSpec::CallerFilter.first_non_rspec_line}"
144
164
 
145
- RSpec.warn_deprecation <<-WARNING.gsub(/\s*\|/,' ')
165
+ RSpec.warn_deprecation <<-WARNING.gsub(/\s*\|/, ' ')
146
166
  |The #{formatter_class} formatter uses the deprecated formatter
147
167
  |interface not supported directly by RSpec 3.
148
168
  |
@@ -153,10 +173,7 @@ module RSpec::Core::Formatters
153
173
  |
154
174
  |#{call_site}
155
175
  WARNING
156
- return
157
176
  end
158
- @formatters << formatter unless duplicate_formatter_exists?(formatter)
159
- formatter
160
177
  end
161
178
 
162
179
  private
@@ -164,15 +181,29 @@ module RSpec::Core::Formatters
164
181
  def find_formatter(formatter_to_use)
165
182
  built_in_formatter(formatter_to_use) ||
166
183
  custom_formatter(formatter_to_use) ||
167
- (raise ArgumentError, "Formatter '#{formatter_to_use}' unknown - maybe you meant 'documentation' or 'progress'?.")
184
+ (raise ArgumentError, "Formatter '#{formatter_to_use}' unknown - " \
185
+ "maybe you meant 'documentation' or 'progress'?.")
186
+ end
187
+
188
+ def register(formatter, notifications)
189
+ return if duplicate_formatter_exists?(formatter)
190
+ @reporter.register_listener formatter, *notifications
191
+ @formatters << formatter
192
+ formatter
168
193
  end
169
194
 
170
195
  def duplicate_formatter_exists?(new_formatter)
171
196
  @formatters.any? do |formatter|
172
- formatter.class === new_formatter && formatter.output == new_formatter.output
197
+ formatter.class == new_formatter.class &&
198
+ has_matching_output?(formatter, new_formatter)
173
199
  end
174
200
  end
175
201
 
202
+ def has_matching_output?(formatter, new_formatter)
203
+ return true unless formatter.respond_to?(:output) && new_formatter.respond_to?(:output)
204
+ formatter.output == new_formatter.output
205
+ end
206
+
176
207
  def existing_formatter_implements?(notification)
177
208
  @reporter.registered_listeners(notification).any?
178
209
  end
@@ -187,12 +218,16 @@ module RSpec::Core::Formatters
187
218
  ProgressFormatter
188
219
  when 'j', 'json'
189
220
  JsonFormatter
221
+ when 'bisect-drb'
222
+ BisectDRbFormatter
223
+ when 'f', 'failures'
224
+ FailureListFormatter
190
225
  end
191
226
  end
192
227
 
193
228
  def notifications_for(formatter_class)
194
- formatter_class.ancestors.inject(Set.new) do |notifications, klass|
195
- notifications + Loader.formatters.fetch(klass) { Set.new }
229
+ formatter_class.ancestors.inject(::RSpec::Core::Set.new) do |notifications, klass|
230
+ notifications.merge Loader.formatters.fetch(klass) { ::RSpec::Core::Set.new }
196
231
  end
197
232
  end
198
233
 
@@ -201,9 +236,9 @@ module RSpec::Core::Formatters
201
236
  formatter_ref
202
237
  elsif string_const?(formatter_ref)
203
238
  begin
204
- formatter_ref.gsub(/^::/,'').split('::').inject(Object) { |const,string| const.const_get string }
239
+ formatter_ref.gsub(/^::/, '').split('::').inject(Object) { |a, e| a.const_get e }
205
240
  rescue NameError
206
- require( path_for(formatter_ref) ) ? retry : raise
241
+ require(path_for(formatter_ref)) ? retry : raise
207
242
  end
208
243
  end
209
244
  end
@@ -224,16 +259,21 @@ module RSpec::Core::Formatters
224
259
  def underscore(camel_cased_word)
225
260
  word = camel_cased_word.to_s.dup
226
261
  word.gsub!(/::/, '/')
227
- word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
228
- word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
262
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
263
+ word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
229
264
  word.tr!("-", "_")
230
265
  word.downcase!
231
266
  word
232
267
  end
233
268
 
234
- def file_at(path)
235
- FileUtils.mkdir_p(File.dirname(path))
236
- File.new(path, 'w')
269
+ def open_stream(path_or_wrapper)
270
+ if RSpec::Core::OutputWrapper === path_or_wrapper
271
+ path_or_wrapper.output = open_stream(path_or_wrapper.output)
272
+ path_or_wrapper
273
+ else
274
+ RSpec::Support::DirectoryMaker.mkdir_p(File.dirname(path_or_wrapper))
275
+ File.new(path_or_wrapper, 'w')
276
+ end
237
277
  end
238
278
  end
239
279
  end