rspec-core 3.1.7 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.yardopts +1 -0
- data/Changelog.md +84 -0
- data/README.md +10 -1
- data/lib/rspec/core.rb +28 -8
- data/lib/rspec/core/backport_random.rb +12 -9
- data/lib/rspec/core/configuration.rb +350 -112
- data/lib/rspec/core/configuration_options.rb +14 -7
- data/lib/rspec/core/dsl.rb +7 -4
- data/lib/rspec/core/example.rb +86 -50
- data/lib/rspec/core/example_group.rb +247 -86
- data/lib/rspec/core/filter_manager.rb +38 -93
- data/lib/rspec/core/flat_map.rb +4 -4
- data/lib/rspec/core/formatters.rb +10 -6
- data/lib/rspec/core/formatters/base_formatter.rb +7 -4
- data/lib/rspec/core/formatters/base_text_formatter.rb +12 -12
- data/lib/rspec/core/formatters/console_codes.rb +8 -7
- data/lib/rspec/core/formatters/deprecation_formatter.rb +5 -3
- data/lib/rspec/core/formatters/documentation_formatter.rb +10 -4
- data/lib/rspec/core/formatters/helpers.rb +6 -4
- data/lib/rspec/core/formatters/html_formatter.rb +13 -8
- data/lib/rspec/core/formatters/html_printer.rb +26 -10
- data/lib/rspec/core/formatters/profile_formatter.rb +10 -7
- data/lib/rspec/core/formatters/protocol.rb +27 -18
- data/lib/rspec/core/formatters/snippet_extractor.rb +14 -7
- data/lib/rspec/core/hooks.rb +252 -211
- data/lib/rspec/core/memoized_helpers.rb +16 -16
- data/lib/rspec/core/metadata.rb +67 -28
- data/lib/rspec/core/metadata_filter.rb +151 -24
- data/lib/rspec/core/minitest_assertions_adapter.rb +5 -2
- data/lib/rspec/core/mocking_adapters/flexmock.rb +1 -1
- data/lib/rspec/core/mocking_adapters/mocha.rb +8 -8
- data/lib/rspec/core/notifications.rb +155 -94
- data/lib/rspec/core/option_parser.rb +16 -10
- data/lib/rspec/core/pending.rb +11 -9
- data/lib/rspec/core/project_initializer.rb +1 -1
- data/lib/rspec/core/project_initializer/spec/spec_helper.rb +10 -8
- data/lib/rspec/core/rake_task.rb +37 -52
- data/lib/rspec/core/reporter.rb +30 -7
- data/lib/rspec/core/ruby_project.rb +12 -4
- data/lib/rspec/core/runner.rb +5 -8
- data/lib/rspec/core/sandbox.rb +37 -0
- data/lib/rspec/core/shared_example_group.rb +41 -15
- data/lib/rspec/core/test_unit_assertions_adapter.rb +3 -3
- data/lib/rspec/core/version.rb +1 -1
- data/lib/rspec/core/warnings.rb +2 -2
- data/lib/rspec/core/world.rb +12 -28
- metadata +44 -31
- metadata.gz.sig +0 -0
@@ -1,71 +1,6 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Core
|
3
3
|
# @private
|
4
|
-
# Manages the filtering of examples and groups by matching tags declared on
|
5
|
-
# the command line or options files, or filters declared via
|
6
|
-
# `RSpec.configure`, with hash key/values submitted within example group
|
7
|
-
# and/or example declarations. For example, given this declaration:
|
8
|
-
#
|
9
|
-
# describe Thing, :awesome => true do
|
10
|
-
# it "does something" do
|
11
|
-
# # ...
|
12
|
-
# end
|
13
|
-
# end
|
14
|
-
#
|
15
|
-
# That group (or any other with `:awesome => true`) would be filtered in
|
16
|
-
# with any of the following commands:
|
17
|
-
#
|
18
|
-
# rspec --tag awesome:true
|
19
|
-
# rspec --tag awesome
|
20
|
-
# rspec -t awesome:true
|
21
|
-
# rspec -t awesome
|
22
|
-
#
|
23
|
-
# Prefixing the tag names with `~` negates the tags, thus excluding this group with
|
24
|
-
# any of:
|
25
|
-
#
|
26
|
-
# rspec --tag ~awesome:true
|
27
|
-
# rspec --tag ~awesome
|
28
|
-
# rspec -t ~awesome:true
|
29
|
-
# rspec -t ~awesome
|
30
|
-
#
|
31
|
-
# ## Options files and command line overrides
|
32
|
-
#
|
33
|
-
# Tag declarations can be stored in `.rspec`, `~/.rspec`, or a custom
|
34
|
-
# options file. This is useful for storing defaults. For example, let's
|
35
|
-
# say you've got some slow specs that you want to suppress most of the
|
36
|
-
# time. You can tag them like this:
|
37
|
-
#
|
38
|
-
# describe Something, :slow => true do
|
39
|
-
#
|
40
|
-
# And then store this in `.rspec`:
|
41
|
-
#
|
42
|
-
# --tag ~slow:true
|
43
|
-
#
|
44
|
-
# Now when you run `rspec`, that group will be excluded.
|
45
|
-
#
|
46
|
-
# ## Overriding
|
47
|
-
#
|
48
|
-
# Of course, you probably want to run them sometimes, so you can override
|
49
|
-
# this tag on the command line like this:
|
50
|
-
#
|
51
|
-
# rspec --tag slow:true
|
52
|
-
#
|
53
|
-
# ## RSpec.configure
|
54
|
-
#
|
55
|
-
# You can also store default tags with `RSpec.configure`. We use `tag` on
|
56
|
-
# the command line (and in options files like `.rspec`), but for historical
|
57
|
-
# reasons we use the term `filter` in `RSpec.configure:
|
58
|
-
#
|
59
|
-
# RSpec.configure do |c|
|
60
|
-
# c.filter_run_including :foo => :bar
|
61
|
-
# c.filter_run_excluding :foo => :bar
|
62
|
-
# end
|
63
|
-
#
|
64
|
-
# These declarations can also be overridden from the command line.
|
65
|
-
#
|
66
|
-
# @see RSpec.configure
|
67
|
-
# @see Configuration#filter_run_including
|
68
|
-
# @see Configuration#filter_run_excluding
|
69
4
|
class FilterManager
|
70
5
|
attr_reader :exclusions, :inclusions
|
71
6
|
|
@@ -83,7 +18,7 @@ module RSpec
|
|
83
18
|
# { "path/to/file.rb" => [37, 42] }
|
84
19
|
locations = inclusions.delete(:locations) || Hash.new { |h, k| h[k] = [] }
|
85
20
|
locations[File.expand_path(file_path)].push(*line_numbers)
|
86
|
-
inclusions.
|
21
|
+
inclusions.add(:locations => locations)
|
87
22
|
end
|
88
23
|
|
89
24
|
def empty?
|
@@ -91,11 +26,13 @@ module RSpec
|
|
91
26
|
end
|
92
27
|
|
93
28
|
def prune(examples)
|
29
|
+
examples = prune_conditionally_filtered_examples(examples)
|
30
|
+
|
94
31
|
if inclusions.standalone?
|
95
|
-
|
96
|
-
examples.select { |e| !base_exclusions.include_example?(e) && include?(e) }
|
32
|
+
examples.select { |e| include?(e) }
|
97
33
|
else
|
98
|
-
|
34
|
+
locations = inclusions.fetch(:locations) { Hash.new([]) }
|
35
|
+
examples.select { |e| priority_include?(e, locations) || (!exclude?(e) && include?(e)) }
|
99
36
|
end
|
100
37
|
end
|
101
38
|
|
@@ -111,10 +48,6 @@ module RSpec
|
|
111
48
|
exclusions.add_with_low_priority(args.last)
|
112
49
|
end
|
113
50
|
|
114
|
-
def exclude?(example)
|
115
|
-
exclusions.include_example?(example)
|
116
|
-
end
|
117
|
-
|
118
51
|
def include(*args)
|
119
52
|
inclusions.add(args.last)
|
120
53
|
end
|
@@ -127,9 +60,32 @@ module RSpec
|
|
127
60
|
inclusions.add_with_low_priority(args.last)
|
128
61
|
end
|
129
62
|
|
63
|
+
private
|
64
|
+
|
65
|
+
def exclude?(example)
|
66
|
+
exclusions.include_example?(example)
|
67
|
+
end
|
68
|
+
|
130
69
|
def include?(example)
|
131
70
|
inclusions.include_example?(example)
|
132
71
|
end
|
72
|
+
|
73
|
+
def prune_conditionally_filtered_examples(examples)
|
74
|
+
examples.reject do |ex|
|
75
|
+
meta = ex.metadata
|
76
|
+
!meta.fetch(:if, true) || meta[:unless]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# When a user specifies a particular spec location, that takes priority
|
81
|
+
# over any exclusion filters (such as if the spec is tagged with `:slow`
|
82
|
+
# and there is a `:slow => true` exclusion filter), but only for specs
|
83
|
+
# defined in the same file as the location filters. Excluded specs in
|
84
|
+
# other files should still be excluded.
|
85
|
+
def priority_include?(example, locations)
|
86
|
+
return false if locations[example.metadata[:absolute_file_path]].empty?
|
87
|
+
MetadataFilter.filter_applies?(:locations, locations, example.metadata)
|
88
|
+
end
|
133
89
|
end
|
134
90
|
|
135
91
|
# @private
|
@@ -194,16 +150,17 @@ module RSpec
|
|
194
150
|
def description
|
195
151
|
rules.inspect.gsub(PROC_HEX_NUMBER, '').gsub(PROJECT_DIR, '.').gsub(' (lambda)', '')
|
196
152
|
end
|
153
|
+
|
154
|
+
def include_example?(example)
|
155
|
+
MetadataFilter.apply?(:any?, @rules, example.metadata)
|
156
|
+
end
|
197
157
|
end
|
198
158
|
|
199
159
|
# @private
|
200
|
-
|
201
|
-
STANDALONE_FILTERS = [:locations, :full_description]
|
202
|
-
|
203
|
-
def add_location(locations)
|
204
|
-
replace_filters(:locations => locations)
|
205
|
-
end
|
160
|
+
ExclusionRules = FilterRules
|
206
161
|
|
162
|
+
# @private
|
163
|
+
class InclusionRules < FilterRules
|
207
164
|
def add(*args)
|
208
165
|
apply_standalone_filter(*args) || super
|
209
166
|
end
|
@@ -217,7 +174,7 @@ module RSpec
|
|
217
174
|
end
|
218
175
|
|
219
176
|
def include_example?(example)
|
220
|
-
@rules.empty?
|
177
|
+
@rules.empty? || super
|
221
178
|
end
|
222
179
|
|
223
180
|
def standalone?
|
@@ -240,19 +197,7 @@ module RSpec
|
|
240
197
|
end
|
241
198
|
|
242
199
|
def is_standalone_filter?(rules)
|
243
|
-
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
# @private
|
248
|
-
class ExclusionRules < FilterRules
|
249
|
-
CONDITIONAL_FILTERS = {
|
250
|
-
:if => lambda { |value| !value },
|
251
|
-
:unless => lambda { |value| value }
|
252
|
-
}.freeze
|
253
|
-
|
254
|
-
def include_example?(example)
|
255
|
-
example.any_apply?(@rules) || example.any_apply?(CONDITIONAL_FILTERS)
|
200
|
+
rules.key?(:full_description)
|
256
201
|
end
|
257
202
|
end
|
258
203
|
end
|
data/lib/rspec/core/flat_map.rb
CHANGED
@@ -3,12 +3,12 @@ module RSpec
|
|
3
3
|
# @private
|
4
4
|
module FlatMap
|
5
5
|
if [].respond_to?(:flat_map)
|
6
|
-
def flat_map(array)
|
7
|
-
array.flat_map
|
6
|
+
def flat_map(array, &block)
|
7
|
+
array.flat_map(&block)
|
8
8
|
end
|
9
9
|
else # for 1.8.7
|
10
|
-
def flat_map(array)
|
11
|
-
array.map
|
10
|
+
def flat_map(array, &block)
|
11
|
+
array.map(&block).flatten(1)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
@@ -1,10 +1,12 @@
|
|
1
1
|
RSpec::Support.require_rspec_support "directory_maker"
|
2
2
|
# ## Built-in Formatters
|
3
3
|
#
|
4
|
-
# * progress (default) -
|
5
|
-
#
|
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).
|
6
8
|
# * html
|
7
|
-
# * json -
|
9
|
+
# * json - Useful for archiving data for subsequent analysis.
|
8
10
|
#
|
9
11
|
# The progress formatter is the default, but you can choose any one or more of
|
10
12
|
# the other formatters by passing with the `--format` (or `-f` for short)
|
@@ -72,7 +74,8 @@ module RSpec::Core::Formatters
|
|
72
74
|
|
73
75
|
# Register the formatter class
|
74
76
|
# @param formatter_class [Class] formatter class to register
|
75
|
-
# @param notifications [Symbol, ...] one or more notifications to be
|
77
|
+
# @param notifications [Symbol, ...] one or more notifications to be
|
78
|
+
# registered to the specified formatter
|
76
79
|
#
|
77
80
|
# @see RSpec::Core::Formatters::BaseFormatter
|
78
81
|
def self.register(formatter_class, *notifications)
|
@@ -88,7 +91,7 @@ module RSpec::Core::Formatters
|
|
88
91
|
class Loader
|
89
92
|
# @api private
|
90
93
|
#
|
91
|
-
# Internal formatters are stored here when loaded
|
94
|
+
# Internal formatters are stored here when loaded.
|
92
95
|
def self.formatters
|
93
96
|
@formatters ||= {}
|
94
97
|
end
|
@@ -165,7 +168,8 @@ module RSpec::Core::Formatters
|
|
165
168
|
def find_formatter(formatter_to_use)
|
166
169
|
built_in_formatter(formatter_to_use) ||
|
167
170
|
custom_formatter(formatter_to_use) ||
|
168
|
-
(raise ArgumentError, "Formatter '#{formatter_to_use}' unknown -
|
171
|
+
(raise ArgumentError, "Formatter '#{formatter_to_use}' unknown - " \
|
172
|
+
"maybe you meant 'documentation' or 'progress'?.")
|
169
173
|
end
|
170
174
|
|
171
175
|
def duplicate_formatter_exists?(new_formatter)
|
@@ -4,13 +4,15 @@ require 'stringio'
|
|
4
4
|
module RSpec
|
5
5
|
module Core
|
6
6
|
module Formatters
|
7
|
-
# RSpec's built-in formatters are all subclasses of
|
7
|
+
# RSpec's built-in formatters are all subclasses of
|
8
|
+
# RSpec::Core::Formatters::BaseTextFormatter.
|
8
9
|
#
|
9
10
|
# @see RSpec::Core::Formatters::BaseTextFormatter
|
10
11
|
# @see RSpec::Core::Reporter
|
11
12
|
# @see RSpec::Core::Formatters::Protocol
|
12
13
|
class BaseFormatter
|
13
|
-
#
|
14
|
+
# All formatters inheriting from this formatter will receive these
|
15
|
+
# notifications.
|
14
16
|
Formatters.register self, :start, :example_group_started, :close
|
15
17
|
attr_accessor :example_group
|
16
18
|
attr_reader :output
|
@@ -34,7 +36,8 @@ module RSpec
|
|
34
36
|
|
35
37
|
# @api public
|
36
38
|
#
|
37
|
-
# @param notification [GroupNotification] containing example_group
|
39
|
+
# @param notification [GroupNotification] containing example_group
|
40
|
+
# subclass of `RSpec::Core::ExampleGroup`
|
38
41
|
# @see RSpec::Core::Formatters::Protocol#example_group_started
|
39
42
|
def example_group_started(notification)
|
40
43
|
@example_group = notification.group
|
@@ -42,7 +45,7 @@ module RSpec
|
|
42
45
|
|
43
46
|
# @api public
|
44
47
|
#
|
45
|
-
# @param
|
48
|
+
# @param _notification [NullNotification] (Ignored)
|
46
49
|
# @see RSpec::Core::Formatters::Protocol#close
|
47
50
|
def close(_notification)
|
48
51
|
restore_sync_output
|
@@ -4,8 +4,9 @@ RSpec::Support.require_rspec_core "formatters/console_codes"
|
|
4
4
|
module RSpec
|
5
5
|
module Core
|
6
6
|
module Formatters
|
7
|
-
# Base for all of RSpec's built-in formatters. See
|
8
|
-
# to learn more about all of the
|
7
|
+
# Base for all of RSpec's built-in formatters. See
|
8
|
+
# RSpec::Core::Formatters::BaseFormatter to learn more about all of the
|
9
|
+
# methods called by the reporter.
|
9
10
|
#
|
10
11
|
# @see RSpec::Core::Formatters::BaseFormatter
|
11
12
|
# @see RSpec::Core::Reporter
|
@@ -13,7 +14,6 @@ module RSpec
|
|
13
14
|
Formatters.register self,
|
14
15
|
:message, :dump_summary, :dump_failures, :dump_pending, :seed
|
15
16
|
|
16
|
-
# @method message
|
17
17
|
# @api public
|
18
18
|
#
|
19
19
|
# Used by the reporter to send messages to the output stream.
|
@@ -23,7 +23,6 @@ module RSpec
|
|
23
23
|
output.puts notification.message
|
24
24
|
end
|
25
25
|
|
26
|
-
# @method dump_failures
|
27
26
|
# @api public
|
28
27
|
#
|
29
28
|
# Dumps detailed information about each example failure.
|
@@ -34,14 +33,13 @@ module RSpec
|
|
34
33
|
output.puts notification.fully_formatted_failed_examples
|
35
34
|
end
|
36
35
|
|
37
|
-
# @method dump_summary
|
38
36
|
# @api public
|
39
37
|
#
|
40
|
-
# This method is invoked after the dumping of examples and failures.
|
41
|
-
# is assigned to a corresponding attribute.
|
38
|
+
# This method is invoked after the dumping of examples and failures.
|
39
|
+
# Each parameter is assigned to a corresponding attribute.
|
42
40
|
#
|
43
|
-
# @param summary [SummaryNotification] containing duration,
|
44
|
-
#
|
41
|
+
# @param summary [SummaryNotification] containing duration,
|
42
|
+
# example_count, failure_count and pending_count
|
45
43
|
def dump_summary(summary)
|
46
44
|
output.puts summary.fully_formatted
|
47
45
|
end
|
@@ -63,12 +61,14 @@ module RSpec
|
|
63
61
|
# Invoked at the very end, `close` allows the formatter to clean
|
64
62
|
# up resources, e.g. open streams, etc.
|
65
63
|
#
|
66
|
-
# @param
|
64
|
+
# @param _notification [NullNotification] (Ignored)
|
67
65
|
def close(_notification)
|
68
66
|
return unless IO === output
|
69
|
-
return if output.closed?
|
67
|
+
return if output.closed?
|
68
|
+
|
69
|
+
output.puts
|
70
70
|
|
71
|
-
output.close
|
71
|
+
output.close unless output == $stdout
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
@@ -22,14 +22,20 @@ module RSpec
|
|
22
22
|
|
23
23
|
module_function
|
24
24
|
|
25
|
+
# @private
|
26
|
+
CONFIG_COLORS_TO_METHODS = Configuration.instance_methods.grep(/_color\z/).inject({}) do |hash, method|
|
27
|
+
hash[method.to_s.sub(/_color\z/, '').to_sym] = method
|
28
|
+
hash
|
29
|
+
end
|
30
|
+
|
25
31
|
# Fetches the correct code for the supplied symbol, or checks
|
26
32
|
# that a code is valid. Defaults to white (37).
|
27
33
|
#
|
28
34
|
# @param code_or_symbol [Symbol, Fixnum] Symbol or code to check
|
29
35
|
# @return [Fixnum] a console code
|
30
36
|
def console_code_for(code_or_symbol)
|
31
|
-
if
|
32
|
-
console_code_for
|
37
|
+
if (config_method = CONFIG_COLORS_TO_METHODS[code_or_symbol])
|
38
|
+
console_code_for RSpec.configuration.__send__(config_method)
|
33
39
|
elsif VT100_CODE_VALUES.key?(code_or_symbol)
|
34
40
|
code_or_symbol
|
35
41
|
else
|
@@ -53,11 +59,6 @@ module RSpec
|
|
53
59
|
text
|
54
60
|
end
|
55
61
|
end
|
56
|
-
|
57
|
-
# @private
|
58
|
-
def configuration_color(code)
|
59
|
-
RSpec.configuration.__send__(:"#{code}_color")
|
60
|
-
end
|
61
62
|
end
|
62
63
|
end
|
63
64
|
end
|
@@ -21,7 +21,8 @@ module RSpec
|
|
21
21
|
def printer
|
22
22
|
@printer ||= case deprecation_stream
|
23
23
|
when File
|
24
|
-
ImmediatePrinter.new(FileStream.new(deprecation_stream),
|
24
|
+
ImmediatePrinter.new(FileStream.new(deprecation_stream),
|
25
|
+
summary_stream, self)
|
25
26
|
when RaiseErrorStream
|
26
27
|
ImmediatePrinter.new(deprecation_stream, summary_stream, self)
|
27
28
|
else
|
@@ -209,14 +210,15 @@ module RSpec
|
|
209
210
|
end
|
210
211
|
|
211
212
|
def summarize(summary_stream, deprecation_count)
|
212
|
-
|
213
|
+
path = @file.respond_to?(:path) ? @file.path : @file.inspect
|
214
|
+
summary_stream.puts "\n#{Helpers.pluralize(deprecation_count, 'deprecation')} logged to #{path}"
|
213
215
|
puts RAISE_ERROR_CONFIG_NOTICE
|
214
216
|
end
|
215
217
|
end
|
216
218
|
end
|
217
219
|
end
|
218
220
|
|
219
|
-
# Deprecation Error
|
221
|
+
# Deprecation Error.
|
220
222
|
DeprecationError = Class.new(StandardError)
|
221
223
|
end
|
222
224
|
end
|
@@ -29,11 +29,13 @@ module RSpec
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def example_pending(pending)
|
32
|
-
output.puts pending_output(pending.example,
|
32
|
+
output.puts pending_output(pending.example,
|
33
|
+
pending.example.execution_result.pending_message)
|
33
34
|
end
|
34
35
|
|
35
36
|
def example_failed(failure)
|
36
|
-
output.puts failure_output(failure.example,
|
37
|
+
output.puts failure_output(failure.example,
|
38
|
+
failure.example.execution_result.exception)
|
37
39
|
end
|
38
40
|
|
39
41
|
private
|
@@ -43,11 +45,15 @@ module RSpec
|
|
43
45
|
end
|
44
46
|
|
45
47
|
def pending_output(example, message)
|
46
|
-
ConsoleCodes.wrap("#{current_indentation}#{example.description.strip}
|
48
|
+
ConsoleCodes.wrap("#{current_indentation}#{example.description.strip} " \
|
49
|
+
"(PENDING: #{message})",
|
50
|
+
:pending)
|
47
51
|
end
|
48
52
|
|
49
53
|
def failure_output(example, _exception)
|
50
|
-
ConsoleCodes.wrap("#{current_indentation}#{example.description.strip}
|
54
|
+
ConsoleCodes.wrap("#{current_indentation}#{example.description.strip} " \
|
55
|
+
"(FAILED - #{next_failure_index})",
|
56
|
+
:failure)
|
51
57
|
end
|
52
58
|
|
53
59
|
def next_failure_index
|