rspec-core 3.8.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.document +5 -0
  5. data/.yardopts +8 -0
  6. data/Changelog.md +2243 -0
  7. data/LICENSE.md +26 -0
  8. data/README.md +384 -0
  9. data/exe/rspec +4 -0
  10. data/lib/rspec/autorun.rb +3 -0
  11. data/lib/rspec/core.rb +185 -0
  12. data/lib/rspec/core/backtrace_formatter.rb +65 -0
  13. data/lib/rspec/core/bisect/coordinator.rb +62 -0
  14. data/lib/rspec/core/bisect/example_minimizer.rb +173 -0
  15. data/lib/rspec/core/bisect/fork_runner.rb +134 -0
  16. data/lib/rspec/core/bisect/server.rb +61 -0
  17. data/lib/rspec/core/bisect/shell_command.rb +126 -0
  18. data/lib/rspec/core/bisect/shell_runner.rb +73 -0
  19. data/lib/rspec/core/bisect/utilities.rb +58 -0
  20. data/lib/rspec/core/configuration.rb +2308 -0
  21. data/lib/rspec/core/configuration_options.rb +233 -0
  22. data/lib/rspec/core/drb.rb +113 -0
  23. data/lib/rspec/core/dsl.rb +98 -0
  24. data/lib/rspec/core/example.rb +656 -0
  25. data/lib/rspec/core/example_group.rb +889 -0
  26. data/lib/rspec/core/example_status_persister.rb +235 -0
  27. data/lib/rspec/core/filter_manager.rb +231 -0
  28. data/lib/rspec/core/flat_map.rb +20 -0
  29. data/lib/rspec/core/formatters.rb +269 -0
  30. data/lib/rspec/core/formatters/base_bisect_formatter.rb +45 -0
  31. data/lib/rspec/core/formatters/base_formatter.rb +70 -0
  32. data/lib/rspec/core/formatters/base_text_formatter.rb +75 -0
  33. data/lib/rspec/core/formatters/bisect_drb_formatter.rb +29 -0
  34. data/lib/rspec/core/formatters/bisect_progress_formatter.rb +157 -0
  35. data/lib/rspec/core/formatters/console_codes.rb +68 -0
  36. data/lib/rspec/core/formatters/deprecation_formatter.rb +223 -0
  37. data/lib/rspec/core/formatters/documentation_formatter.rb +70 -0
  38. data/lib/rspec/core/formatters/exception_presenter.rb +508 -0
  39. data/lib/rspec/core/formatters/fallback_message_formatter.rb +28 -0
  40. data/lib/rspec/core/formatters/helpers.rb +110 -0
  41. data/lib/rspec/core/formatters/html_formatter.rb +153 -0
  42. data/lib/rspec/core/formatters/html_printer.rb +414 -0
  43. data/lib/rspec/core/formatters/html_snippet_extractor.rb +120 -0
  44. data/lib/rspec/core/formatters/json_formatter.rb +102 -0
  45. data/lib/rspec/core/formatters/profile_formatter.rb +68 -0
  46. data/lib/rspec/core/formatters/progress_formatter.rb +29 -0
  47. data/lib/rspec/core/formatters/protocol.rb +182 -0
  48. data/lib/rspec/core/formatters/snippet_extractor.rb +134 -0
  49. data/lib/rspec/core/formatters/syntax_highlighter.rb +91 -0
  50. data/lib/rspec/core/hooks.rb +624 -0
  51. data/lib/rspec/core/invocations.rb +87 -0
  52. data/lib/rspec/core/memoized_helpers.rb +554 -0
  53. data/lib/rspec/core/metadata.rb +498 -0
  54. data/lib/rspec/core/metadata_filter.rb +255 -0
  55. data/lib/rspec/core/minitest_assertions_adapter.rb +31 -0
  56. data/lib/rspec/core/mocking_adapters/flexmock.rb +31 -0
  57. data/lib/rspec/core/mocking_adapters/mocha.rb +57 -0
  58. data/lib/rspec/core/mocking_adapters/null.rb +14 -0
  59. data/lib/rspec/core/mocking_adapters/rr.rb +31 -0
  60. data/lib/rspec/core/mocking_adapters/rspec.rb +32 -0
  61. data/lib/rspec/core/notifications.rb +521 -0
  62. data/lib/rspec/core/option_parser.rb +309 -0
  63. data/lib/rspec/core/ordering.rb +158 -0
  64. data/lib/rspec/core/output_wrapper.rb +29 -0
  65. data/lib/rspec/core/pending.rb +165 -0
  66. data/lib/rspec/core/profiler.rb +34 -0
  67. data/lib/rspec/core/project_initializer.rb +48 -0
  68. data/lib/rspec/core/project_initializer/.rspec +1 -0
  69. data/lib/rspec/core/project_initializer/spec/spec_helper.rb +100 -0
  70. data/lib/rspec/core/rake_task.rb +168 -0
  71. data/lib/rspec/core/reporter.rb +257 -0
  72. data/lib/rspec/core/ruby_project.rb +53 -0
  73. data/lib/rspec/core/runner.rb +199 -0
  74. data/lib/rspec/core/sandbox.rb +37 -0
  75. data/lib/rspec/core/set.rb +54 -0
  76. data/lib/rspec/core/shared_context.rb +55 -0
  77. data/lib/rspec/core/shared_example_group.rb +269 -0
  78. data/lib/rspec/core/shell_escape.rb +49 -0
  79. data/lib/rspec/core/test_unit_assertions_adapter.rb +30 -0
  80. data/lib/rspec/core/version.rb +9 -0
  81. data/lib/rspec/core/warnings.rb +40 -0
  82. data/lib/rspec/core/world.rb +275 -0
  83. metadata +292 -0
  84. metadata.gz.sig +0 -0
@@ -0,0 +1,20 @@
1
+ module RSpec
2
+ module Core
3
+ # @private
4
+ module FlatMap
5
+ if [].respond_to?(:flat_map)
6
+ def flat_map(array, &block)
7
+ array.flat_map(&block)
8
+ end
9
+ else # for 1.8.7
10
+ # :nocov:
11
+ def flat_map(array, &block)
12
+ array.map(&block).flatten(1)
13
+ end
14
+ # :nocov:
15
+ end
16
+
17
+ module_function :flat_map
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,269 @@
1
+ RSpec::Support.require_rspec_support "directory_maker"
2
+ # ## Built-in Formatters
3
+ #
4
+ # * progress (default) - Prints dots for passing examples, `F` for failures, `*`
5
+ # for pending.
6
+ # * documentation - Prints the docstrings passed to `describe` and `it` methods
7
+ # (and their aliases).
8
+ # * html
9
+ # * json - Useful for archiving data for subsequent analysis.
10
+ #
11
+ # The progress formatter is the default, but you can choose any one or more of
12
+ # the other formatters by passing with the `--format` (or `-f` for short)
13
+ # command-line option, e.g.
14
+ #
15
+ # rspec --format documentation
16
+ #
17
+ # You can also send the output of multiple formatters to different streams, e.g.
18
+ #
19
+ # rspec --format documentation --format html --out results.html
20
+ #
21
+ # This example sends the output of the documentation formatter to `$stdout`, and
22
+ # the output of the html formatter to results.html.
23
+ #
24
+ # ## Custom Formatters
25
+ #
26
+ # You can tell RSpec to use a custom formatter by passing its path and name to
27
+ # the `rspec` command. For example, if you define MyCustomFormatter in
28
+ # path/to/my_custom_formatter.rb, you would type this command:
29
+ #
30
+ # rspec --require path/to/my_custom_formatter.rb --format MyCustomFormatter
31
+ #
32
+ # The reporter calls every formatter with this protocol:
33
+ #
34
+ # * To start
35
+ # * `start(StartNotification)`
36
+ # * Once per example group
37
+ # * `example_group_started(GroupNotification)`
38
+ # * Once per example
39
+ # * `example_started(ExampleNotification)`
40
+ # * One of these per example, depending on outcome
41
+ # * `example_passed(ExampleNotification)`
42
+ # * `example_failed(FailedExampleNotification)`
43
+ # * `example_pending(ExampleNotification)`
44
+ # * Optionally at any time
45
+ # * `message(MessageNotification)`
46
+ # * At the end of the suite
47
+ # * `stop(ExamplesNotification)`
48
+ # * `start_dump(NullNotification)`
49
+ # * `dump_pending(ExamplesNotification)`
50
+ # * `dump_failures(ExamplesNotification)`
51
+ # * `dump_summary(SummaryNotification)`
52
+ # * `seed(SeedNotification)`
53
+ # * `close(NullNotification)`
54
+ #
55
+ # Only the notifications to which you subscribe your formatter will be called
56
+ # on your formatter. To subscribe your formatter use:
57
+ # `RSpec::Core::Formatters#register` e.g.
58
+ #
59
+ # `RSpec::Core::Formatters.register FormatterClassName, :example_passed, :example_failed`
60
+ #
61
+ # We recommend you implement the methods yourself; for simplicity we provide the
62
+ # default formatter output via our notification objects but if you prefer you
63
+ # can subclass `RSpec::Core::Formatters::BaseTextFormatter` and override the
64
+ # methods you wish to enhance.
65
+ #
66
+ # @see RSpec::Core::Formatters::BaseTextFormatter
67
+ # @see RSpec::Core::Reporter
68
+ module RSpec::Core::Formatters
69
+ autoload :DocumentationFormatter, 'rspec/core/formatters/documentation_formatter'
70
+ autoload :HtmlFormatter, 'rspec/core/formatters/html_formatter'
71
+ autoload :FallbackMessageFormatter, 'rspec/core/formatters/fallback_message_formatter'
72
+ autoload :ProgressFormatter, 'rspec/core/formatters/progress_formatter'
73
+ autoload :ProfileFormatter, 'rspec/core/formatters/profile_formatter'
74
+ autoload :JsonFormatter, 'rspec/core/formatters/json_formatter'
75
+ autoload :BisectDRbFormatter, 'rspec/core/formatters/bisect_drb_formatter'
76
+ autoload :ExceptionPresenter, 'rspec/core/formatters/exception_presenter'
77
+
78
+ # Register the formatter class
79
+ # @param formatter_class [Class] formatter class to register
80
+ # @param notifications [Symbol, ...] one or more notifications to be
81
+ # registered to the specified formatter
82
+ #
83
+ # @see RSpec::Core::Formatters::BaseFormatter
84
+ def self.register(formatter_class, *notifications)
85
+ Loader.formatters[formatter_class] = notifications
86
+ end
87
+
88
+ # @api private
89
+ #
90
+ # `RSpec::Core::Formatters::Loader` is an internal class for
91
+ # managing formatters used by a particular configuration. It is
92
+ # not expected to be used directly, but only through the configuration
93
+ # interface.
94
+ class Loader
95
+ # @api private
96
+ #
97
+ # Internal formatters are stored here when loaded.
98
+ def self.formatters
99
+ @formatters ||= {}
100
+ end
101
+
102
+ # @api private
103
+ def initialize(reporter)
104
+ @formatters = []
105
+ @reporter = reporter
106
+ self.default_formatter = 'progress'
107
+ end
108
+
109
+ # @return [Array] the loaded formatters
110
+ attr_reader :formatters
111
+
112
+ # @return [Reporter] the reporter
113
+ attr_reader :reporter
114
+
115
+ # @return [String] the default formatter to setup, defaults to `progress`
116
+ attr_accessor :default_formatter
117
+
118
+ # @private
119
+ def prepare_default(output_stream, deprecation_stream)
120
+ reporter.prepare_default(self, output_stream, deprecation_stream)
121
+ end
122
+
123
+ # @private
124
+ def setup_default(output_stream, deprecation_stream)
125
+ add default_formatter, output_stream if @formatters.empty?
126
+
127
+ unless @formatters.any? { |formatter| DeprecationFormatter === formatter }
128
+ add DeprecationFormatter, deprecation_stream, output_stream
129
+ end
130
+
131
+ unless existing_formatter_implements?(:message)
132
+ add FallbackMessageFormatter, output_stream
133
+ end
134
+
135
+ return unless RSpec.configuration.profile_examples?
136
+ return if existing_formatter_implements?(:dump_profile)
137
+
138
+ add RSpec::Core::Formatters::ProfileFormatter, output_stream
139
+ end
140
+
141
+ # @private
142
+ def add(formatter_to_use, *paths)
143
+ # If a formatter instance was passed, we can register it directly,
144
+ # with no need for any of the further processing that happens below.
145
+ if Loader.formatters.key?(formatter_to_use.class)
146
+ register formatter_to_use, notifications_for(formatter_to_use.class)
147
+ return
148
+ end
149
+
150
+ formatter_class = find_formatter(formatter_to_use)
151
+
152
+ args = paths.map { |p| p.respond_to?(:puts) ? p : open_stream(p) }
153
+
154
+ if !Loader.formatters[formatter_class].nil?
155
+ formatter = formatter_class.new(*args)
156
+ register formatter, notifications_for(formatter_class)
157
+ elsif defined?(RSpec::LegacyFormatters)
158
+ formatter = RSpec::LegacyFormatters.load_formatter formatter_class, *args
159
+ register formatter, formatter.notifications
160
+ else
161
+ call_site = "Formatter added at: #{::RSpec::CallerFilter.first_non_rspec_line}"
162
+
163
+ RSpec.warn_deprecation <<-WARNING.gsub(/\s*\|/, ' ')
164
+ |The #{formatter_class} formatter uses the deprecated formatter
165
+ |interface not supported directly by RSpec 3.
166
+ |
167
+ |To continue to use this formatter you must install the
168
+ |`rspec-legacy_formatters` gem, which provides support
169
+ |for legacy formatters or upgrade the formatter to a
170
+ |compatible version.
171
+ |
172
+ |#{call_site}
173
+ WARNING
174
+ end
175
+ end
176
+
177
+ private
178
+
179
+ def find_formatter(formatter_to_use)
180
+ built_in_formatter(formatter_to_use) ||
181
+ custom_formatter(formatter_to_use) ||
182
+ (raise ArgumentError, "Formatter '#{formatter_to_use}' unknown - " \
183
+ "maybe you meant 'documentation' or 'progress'?.")
184
+ end
185
+
186
+ def register(formatter, notifications)
187
+ return if duplicate_formatter_exists?(formatter)
188
+ @reporter.register_listener formatter, *notifications
189
+ @formatters << formatter
190
+ formatter
191
+ end
192
+
193
+ def duplicate_formatter_exists?(new_formatter)
194
+ @formatters.any? do |formatter|
195
+ formatter.class == new_formatter.class && formatter.output == new_formatter.output
196
+ end
197
+ end
198
+
199
+ def existing_formatter_implements?(notification)
200
+ @reporter.registered_listeners(notification).any?
201
+ end
202
+
203
+ def built_in_formatter(key)
204
+ case key.to_s
205
+ when 'd', 'doc', 'documentation'
206
+ DocumentationFormatter
207
+ when 'h', 'html'
208
+ HtmlFormatter
209
+ when 'p', 'progress'
210
+ ProgressFormatter
211
+ when 'j', 'json'
212
+ JsonFormatter
213
+ when 'bisect-drb'
214
+ BisectDRbFormatter
215
+ end
216
+ end
217
+
218
+ def notifications_for(formatter_class)
219
+ formatter_class.ancestors.inject(::RSpec::Core::Set.new) do |notifications, klass|
220
+ notifications.merge Loader.formatters.fetch(klass) { ::RSpec::Core::Set.new }
221
+ end
222
+ end
223
+
224
+ def custom_formatter(formatter_ref)
225
+ if Class === formatter_ref
226
+ formatter_ref
227
+ elsif string_const?(formatter_ref)
228
+ begin
229
+ formatter_ref.gsub(/^::/, '').split('::').inject(Object) { |a, e| a.const_get e }
230
+ rescue NameError
231
+ require(path_for(formatter_ref)) ? retry : raise
232
+ end
233
+ end
234
+ end
235
+
236
+ def string_const?(str)
237
+ str.is_a?(String) && /\A[A-Z][a-zA-Z0-9_:]*\z/ =~ str
238
+ end
239
+
240
+ def path_for(const_ref)
241
+ underscore_with_fix_for_non_standard_rspec_naming(const_ref)
242
+ end
243
+
244
+ def underscore_with_fix_for_non_standard_rspec_naming(string)
245
+ underscore(string).sub(%r{(^|/)r_spec($|/)}, '\\1rspec\\2')
246
+ end
247
+
248
+ # activesupport/lib/active_support/inflector/methods.rb, line 48
249
+ def underscore(camel_cased_word)
250
+ word = camel_cased_word.to_s.dup
251
+ word.gsub!(/::/, '/')
252
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
253
+ word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
254
+ word.tr!("-", "_")
255
+ word.downcase!
256
+ word
257
+ end
258
+
259
+ def open_stream(path_or_wrapper)
260
+ if RSpec::Core::OutputWrapper === path_or_wrapper
261
+ path_or_wrapper.output = open_stream(path_or_wrapper.output)
262
+ path_or_wrapper
263
+ else
264
+ RSpec::Support::DirectoryMaker.mkdir_p(File.dirname(path_or_wrapper))
265
+ File.new(path_or_wrapper, 'w')
266
+ end
267
+ end
268
+ end
269
+ end
@@ -0,0 +1,45 @@
1
+ RSpec::Support.require_rspec_core "bisect/utilities"
2
+
3
+ module RSpec
4
+ module Core
5
+ module Formatters
6
+ # Contains common logic for formatters used by `--bisect` to communicate results
7
+ # back to the bisect runner.
8
+ #
9
+ # Subclasses must define a `notify_results(all_example_ids, failed_example_ids)`
10
+ # method.
11
+ # @private
12
+ class BaseBisectFormatter
13
+ def self.inherited(formatter)
14
+ Formatters.register formatter, :start_dump, :example_failed, :example_finished
15
+ end
16
+
17
+ def initialize(expected_failures)
18
+ @all_example_ids = []
19
+ @failed_example_ids = []
20
+ @remaining_failures = expected_failures
21
+ end
22
+
23
+ def example_failed(notification)
24
+ @failed_example_ids << notification.example.id
25
+ end
26
+
27
+ def example_finished(notification)
28
+ @all_example_ids << notification.example.id
29
+ return unless @remaining_failures.include?(notification.example.id)
30
+ @remaining_failures.delete(notification.example.id)
31
+
32
+ status = notification.example.execution_result.status
33
+ return if status == :failed && !@remaining_failures.empty?
34
+ RSpec.world.wants_to_quit = true
35
+ end
36
+
37
+ def start_dump(_notification)
38
+ # `notify_results` is defined in the subclass
39
+ notify_results(Bisect::ExampleSetDescriptor.new(
40
+ @all_example_ids, @failed_example_ids))
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,70 @@
1
+ RSpec::Support.require_rspec_core "formatters/helpers"
2
+ require 'stringio'
3
+
4
+ module RSpec
5
+ module Core
6
+ module Formatters
7
+ # RSpec's built-in formatters are all subclasses of
8
+ # RSpec::Core::Formatters::BaseFormatter.
9
+ #
10
+ # @see RSpec::Core::Formatters::BaseTextFormatter
11
+ # @see RSpec::Core::Reporter
12
+ # @see RSpec::Core::Formatters::Protocol
13
+ class BaseFormatter
14
+ # All formatters inheriting from this formatter will receive these
15
+ # notifications.
16
+ Formatters.register self, :start, :example_group_started, :close
17
+ attr_accessor :example_group
18
+ attr_reader :output
19
+
20
+ # @api public
21
+ # @param output [IO] the formatter output
22
+ # @see RSpec::Core::Formatters::Protocol#initialize
23
+ def initialize(output)
24
+ @output = output || StringIO.new
25
+ @example_group = nil
26
+ end
27
+
28
+ # @api public
29
+ #
30
+ # @param notification [StartNotification]
31
+ # @see RSpec::Core::Formatters::Protocol#start
32
+ def start(notification)
33
+ start_sync_output
34
+ @example_count = notification.count
35
+ end
36
+
37
+ # @api public
38
+ #
39
+ # @param notification [GroupNotification] containing example_group
40
+ # subclass of `RSpec::Core::ExampleGroup`
41
+ # @see RSpec::Core::Formatters::Protocol#example_group_started
42
+ def example_group_started(notification)
43
+ @example_group = notification.group
44
+ end
45
+
46
+ # @api public
47
+ #
48
+ # @param _notification [NullNotification] (Ignored)
49
+ # @see RSpec::Core::Formatters::Protocol#close
50
+ def close(_notification)
51
+ restore_sync_output
52
+ end
53
+
54
+ private
55
+
56
+ def start_sync_output
57
+ @old_sync, output.sync = output.sync, true if output_supports_sync
58
+ end
59
+
60
+ def restore_sync_output
61
+ output.sync = @old_sync if output_supports_sync && !output.closed?
62
+ end
63
+
64
+ def output_supports_sync
65
+ output.respond_to?(:sync=)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,75 @@
1
+ RSpec::Support.require_rspec_core "formatters/base_formatter"
2
+
3
+ module RSpec
4
+ module Core
5
+ module Formatters
6
+ # Base for all of RSpec's built-in formatters. See
7
+ # RSpec::Core::Formatters::BaseFormatter to learn more about all of the
8
+ # methods called by the reporter.
9
+ #
10
+ # @see RSpec::Core::Formatters::BaseFormatter
11
+ # @see RSpec::Core::Reporter
12
+ class BaseTextFormatter < BaseFormatter
13
+ Formatters.register self,
14
+ :message, :dump_summary, :dump_failures, :dump_pending, :seed
15
+
16
+ # @api public
17
+ #
18
+ # Used by the reporter to send messages to the output stream.
19
+ #
20
+ # @param notification [MessageNotification] containing message
21
+ def message(notification)
22
+ output.puts notification.message
23
+ end
24
+
25
+ # @api public
26
+ #
27
+ # Dumps detailed information about each example failure.
28
+ #
29
+ # @param notification [NullNotification]
30
+ def dump_failures(notification)
31
+ return if notification.failure_notifications.empty?
32
+ output.puts notification.fully_formatted_failed_examples
33
+ end
34
+
35
+ # @api public
36
+ #
37
+ # This method is invoked after the dumping of examples and failures.
38
+ # Each parameter is assigned to a corresponding attribute.
39
+ #
40
+ # @param summary [SummaryNotification] containing duration,
41
+ # example_count, failure_count and pending_count
42
+ def dump_summary(summary)
43
+ output.puts summary.fully_formatted
44
+ end
45
+
46
+ # @private
47
+ def dump_pending(notification)
48
+ return if notification.pending_examples.empty?
49
+ output.puts notification.fully_formatted_pending_examples
50
+ end
51
+
52
+ # @private
53
+ def seed(notification)
54
+ return unless notification.seed_used?
55
+ output.puts notification.fully_formatted
56
+ end
57
+
58
+ # @api public
59
+ #
60
+ # Invoked at the end of a suite run. Allows the formatter to do any
61
+ # tidying up, but be aware that formatter output streams may be used
62
+ # elsewhere so don't actually close them.
63
+ #
64
+ # @param _notification [NullNotification] (Ignored)
65
+ def close(_notification)
66
+ return if output.closed?
67
+
68
+ output.puts
69
+
70
+ output.flush
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end