rspec-core 3.0.4 → 3.12.2

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