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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 64add3bc6c923a094fe43e64de951766afb3d546
|
4
|
+
data.tar.gz: a6edfdd40534051c51205124394016d6ee23b90c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee07178fc56ffde6a07f6f1488acc6a468eda931765714b06f995e073fe539a5468e1b4c31f878761f226fe9223252d078ef43bd2d7c114b03c2352c4baa0600
|
7
|
+
data.tar.gz: 370912d590a0243d8f2b532a49e513c87855cfe8ebf3d6d1e6bad896e5011c3fb9fcff932a09fdcefb1d7bef4ebfbf5153f023cac9ca2c2769747c2984d0168f
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/.yardopts
CHANGED
data/Changelog.md
CHANGED
@@ -1,3 +1,84 @@
|
|
1
|
+
### 3.2.0 / 2015-02-03
|
2
|
+
[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.7...v3.2.0)
|
3
|
+
|
4
|
+
Enhancements:
|
5
|
+
|
6
|
+
* Improve the `inspect` output of example groups. (Mike Dalton, #1687)
|
7
|
+
* When rake task fails, only output the command if `verbose` flag is
|
8
|
+
set. (Ben Snape, #1704)
|
9
|
+
* Add `RSpec.clear_examples` as a clear way to reset examples in between
|
10
|
+
spec runs, whilst retaining user configuration. (Alexey Fedorov, #1706)
|
11
|
+
* Reduce string allocations when defining and running examples by 70%
|
12
|
+
and 50% respectively. (Myron Marston, #1738)
|
13
|
+
* Removed dependency on pathname from stdlib. (Sam Phippen, #1703)
|
14
|
+
* Improve the message presented when a user hits Ctrl-C.
|
15
|
+
(Alex Chaffee #1717, #1742)
|
16
|
+
* Improve shared example group inclusion backtrace displayed
|
17
|
+
in failed example output so that it works for all methods
|
18
|
+
of including shared example groups and shows all inclusion
|
19
|
+
locations. (Myron Marston, #1763)
|
20
|
+
* Issue seed notification at start (as well as the end) of the reporter
|
21
|
+
run. (Arlandis Word, #1761)
|
22
|
+
* Improve the documentation of around hooks. (Jim Kingdon, #1772)
|
23
|
+
* Support prepending of modules into example groups from config and allow
|
24
|
+
filtering based on metadata. (Arlandis Word, #1806)
|
25
|
+
* Emit warnings when `:suite` hooks are registered on an example group
|
26
|
+
(where it has always been ignored) or are registered with metadata
|
27
|
+
(which has always been ignored). (Myron Marston, #1805)
|
28
|
+
* Provide a friendly error message when users call RSpec example group
|
29
|
+
APIs (e.g. `context`, `describe`, `it`, `let`, `before`, etc) from
|
30
|
+
within an example where those APIs are unavailable. (Myron Marston, #1819)
|
31
|
+
* Provide a friendly error message when users call RSpec example
|
32
|
+
APIs (e.g. `expect`, `double`, `stub_const`, etc) from
|
33
|
+
within an example group where those APIs are unavailable.
|
34
|
+
(Myron Marston, #1819)
|
35
|
+
* Add new `RSpec::Core::Sandbox.sandboxed { }` API that facilitates
|
36
|
+
testing RSpec with RSpec, allowing you to define example groups
|
37
|
+
and example from within an example without affecting the global
|
38
|
+
`RSpec.world` state. (Tyler Ball, 1808)
|
39
|
+
* Apply line-number filters only to the files they are scoped to,
|
40
|
+
allowing you to mix filtered and unfiltered files. (Myron Marston, #1839)
|
41
|
+
* When dumping pending examples, include the failure details so that you
|
42
|
+
don't have to un-pend the example to see it. (Myron Marston, #1844)
|
43
|
+
* Make `-I` option support multiple values when separated by
|
44
|
+
`File::PATH_SEPARATOR`, such as `rspec -I foo:bar`. This matches
|
45
|
+
the behavior of Ruby's `-I` option. (Fumiaki Matsushima, #1855).
|
46
|
+
|
47
|
+
Bug Fixes:
|
48
|
+
|
49
|
+
* When assigning generated example descriptions, surface errors
|
50
|
+
raised by `matcher.description` in the example description.
|
51
|
+
(Myron Marston, #1771)
|
52
|
+
* Don't consider expectations from `after` hooks when generating
|
53
|
+
example descriptions. (Myron Marston, #1771)
|
54
|
+
* Don't apply metadata-filtered config hooks to examples in groups
|
55
|
+
with matching metadata when those examples override the parent
|
56
|
+
metadata value to not match. (Myron Marston, #1796)
|
57
|
+
* Fix `config.expect_with :minitest` so that `skip` uses RSpec's
|
58
|
+
implementation rather than Minitest's. (Jonathan Rochkind, #1822)
|
59
|
+
* Fix `NameError` caused when duplicate example group aliases are defined and
|
60
|
+
the DSL is not globally exposed. (Aaron Kromer, #1825)
|
61
|
+
* When a shared example defined in an external file fails, use the host
|
62
|
+
example group (from a loaded spec file) for the re-run command to
|
63
|
+
ensure the command will actually work. (Myron Marston, #1835)
|
64
|
+
* Fix location filtering to work properly for examples defined in
|
65
|
+
a nested example group within a shared example group defined in
|
66
|
+
an external file. (Bradley Schaefer, Xavier Shay, Myron Marston, #1837)
|
67
|
+
* When a pending example fails (as expected) due to a mock expectation,
|
68
|
+
set `RSpec::Core::Example::ExecutionResult#pending_exception` --
|
69
|
+
previously it was not being set but should have been. (Myron Marston, #1844)
|
70
|
+
* Fix rake task to work when `rspec-core` is installed in a directory
|
71
|
+
containing a space. (Guido Günther, #1845)
|
72
|
+
* Fix regression in 3.1 that caused `describe Regexp` to raise errors.
|
73
|
+
(Durran Jordan, #1853)
|
74
|
+
* Fix regression in 3.x that caused the profile information to be printed
|
75
|
+
after the summary. (Max Lincoln, #1857)
|
76
|
+
* Apply `--seed` before loading `--require` files so that required files
|
77
|
+
can access the provided seed. (Myron Marston, #1745)
|
78
|
+
* Handle `RSpec::Core::Formatters::DeprecationFormatter::FileStream` being
|
79
|
+
reopened with an IO stream, which sometimes happens with spring.
|
80
|
+
(Kevin Mook, #1757)
|
81
|
+
|
1
82
|
### 3.1.7 / 2014-10-11
|
2
83
|
[Full Changelog](http://github.com/rspec/rspec-core/compare/v3.1.6...v3.1.7)
|
3
84
|
|
@@ -456,6 +537,9 @@ Bug Fixes:
|
|
456
537
|
directory (was broken in beta1). (Jon Rowe)
|
457
538
|
* Prevent RSpec mangling file names that have substrings containing `line_number`
|
458
539
|
or `default_path`. (Matijs van Zuijlen)
|
540
|
+
* Fix failure line detection so that it handles relative file paths
|
541
|
+
(which can happen when running specs through `ruby` using `rspec/autorun`).
|
542
|
+
(Myron Marston, #1829)
|
459
543
|
|
460
544
|
### 3.0.0.beta1 / 2013-11-07
|
461
545
|
[Full Changelog](http://github.com/rspec/rspec-core/compare/v2.99.1...v3.0.0.beta1)
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# rspec-core [![Build Status](https://secure.travis-ci.org/rspec/rspec-core.
|
1
|
+
# rspec-core [![Build Status](https://secure.travis-ci.org/rspec/rspec-core.svg?branch=master)](http://travis-ci.org/rspec/rspec-core) [![Code Climate](https://codeclimate.com/github/rspec/rspec-core.svg)](https://codeclimate.com/github/rspec/rspec-core)
|
2
2
|
|
3
3
|
rspec-core provides the structure for writing executable examples of how your
|
4
4
|
code should behave, and an `rspec` command with tools to constrain which
|
@@ -10,6 +10,15 @@ examples get run and tailor the output.
|
|
10
10
|
gem install rspec-core # for rspec-core only
|
11
11
|
rspec --help
|
12
12
|
|
13
|
+
Want to run against the `master` branch? You'll need to include the dependent
|
14
|
+
RSpec repos as well. Add the following to your `Gemfile`:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
%w[rspec-core rspec-expectations rspec-mocks rspec-support].each do |lib|
|
18
|
+
gem lib, :git => "git://github.com/rspec/#{lib}.git", :branch => 'master'
|
19
|
+
end
|
20
|
+
```
|
21
|
+
|
13
22
|
## basic structure
|
14
23
|
|
15
24
|
RSpec uses the words "describe" and "it" so we can express concepts like a conversation:
|
data/lib/rspec/core.rb
CHANGED
@@ -43,18 +43,38 @@ module RSpec
|
|
43
43
|
|
44
44
|
extend RSpec::Core::Warnings
|
45
45
|
|
46
|
-
|
47
|
-
|
46
|
+
class << self
|
47
|
+
# Setters for shared global objects
|
48
|
+
# @api private
|
49
|
+
attr_writer :configuration, :world
|
50
|
+
end
|
51
|
+
|
52
|
+
# Used to ensure examples get reloaded and user configuration gets reset to
|
53
|
+
# defaults between multiple runs in the same process.
|
48
54
|
#
|
49
55
|
# Users must invoke this if they want to have the configuration reset when
|
50
|
-
# they use runner multiple times within the same process.
|
56
|
+
# they use the runner multiple times within the same process. Users must deal
|
57
|
+
# themselves with re-configuration of RSpec before run.
|
51
58
|
def self.reset
|
52
59
|
@world = nil
|
53
60
|
@configuration = nil
|
54
61
|
end
|
55
62
|
|
56
|
-
#
|
57
|
-
#
|
63
|
+
# Used to ensure examples get reloaded between multiple runs in the same
|
64
|
+
# process and ensures user configuration is persisted.
|
65
|
+
#
|
66
|
+
# Users must invoke this if they want to clear all examples but preserve
|
67
|
+
# current configuration when they use the runner multiple times within the
|
68
|
+
# same process.
|
69
|
+
def self.clear_examples
|
70
|
+
world.reset
|
71
|
+
configuration.reporter.reset
|
72
|
+
configuration.start_time = ::RSpec::Core::Time.now
|
73
|
+
configuration.reset_filters
|
74
|
+
end
|
75
|
+
|
76
|
+
# Returns the global [Configuration](RSpec/Core/Configuration) object. While
|
77
|
+
# you _can_ use this method to access the configuration, the more common
|
58
78
|
# convention is to use [RSpec.configure](RSpec#configure-class_method).
|
59
79
|
#
|
60
80
|
# @example
|
@@ -116,11 +136,11 @@ module RSpec
|
|
116
136
|
# A single thread local variable so we don't excessively pollute that
|
117
137
|
# namespace.
|
118
138
|
def self.thread_local_metadata
|
119
|
-
Thread.current[:_rspec] ||= {}
|
139
|
+
Thread.current[:_rspec] ||= { :shared_example_group_inclusions => [] }
|
120
140
|
end
|
121
141
|
|
122
142
|
# @private
|
123
|
-
# Internal container for global non-configuration data
|
143
|
+
# Internal container for global non-configuration data.
|
124
144
|
def self.world
|
125
145
|
@world ||= RSpec::Core::World.new
|
126
146
|
end
|
@@ -137,7 +157,7 @@ module RSpec
|
|
137
157
|
end
|
138
158
|
end
|
139
159
|
|
140
|
-
# @private path to executable file
|
160
|
+
# @private path to executable file.
|
141
161
|
def self.path_to_executable
|
142
162
|
@path_to_executable ||= File.expand_path('../../../exe/rspec', __FILE__)
|
143
163
|
end
|
@@ -60,14 +60,14 @@ module RSpec
|
|
60
60
|
coerce_to(obj, Integer, :to_int)
|
61
61
|
end
|
62
62
|
|
63
|
-
# Used internally to make it easy to deal with optional arguments
|
63
|
+
# Used internally to make it easy to deal with optional arguments.
|
64
64
|
# (from Rubinius)
|
65
65
|
Undefined = Object.new
|
66
66
|
|
67
67
|
# @private
|
68
68
|
class Random
|
69
69
|
# @private
|
70
|
-
# An implementation of Mersenne Twister MT19937 in Ruby
|
70
|
+
# An implementation of Mersenne Twister MT19937 in Ruby.
|
71
71
|
class MT19937
|
72
72
|
STATE_SIZE = 624
|
73
73
|
LAST_STATE = STATE_SIZE - 1
|
@@ -92,9 +92,10 @@ module RSpec
|
|
92
92
|
end
|
93
93
|
|
94
94
|
# Seed must be either an Integer (only the first 32 bits will be used)
|
95
|
-
# or an Array of Integers (of which only the first 32 bits will be
|
95
|
+
# or an Array of Integers (of which only the first 32 bits will be
|
96
|
+
# used).
|
96
97
|
#
|
97
|
-
# No conversion or type checking is done at this level
|
98
|
+
# No conversion or type checking is done at this level.
|
98
99
|
def seed=(seed)
|
99
100
|
case seed
|
100
101
|
when Integer
|
@@ -129,7 +130,7 @@ module RSpec
|
|
129
130
|
end
|
130
131
|
end
|
131
132
|
|
132
|
-
# Returns a random Integer from the range 0 ... (1 << 32)
|
133
|
+
# Returns a random Integer from the range 0 ... (1 << 32).
|
133
134
|
def random_32_bits
|
134
135
|
next_state if @last_read >= LAST_STATE
|
135
136
|
@last_read += 1
|
@@ -146,12 +147,12 @@ module RSpec
|
|
146
147
|
# No argument checking is done here either.
|
147
148
|
|
148
149
|
FLOAT_FACTOR = 1.0/9007199254740992.0
|
149
|
-
#
|
150
|
+
# Generates a random number on [0, 1) with 53-bit resolution.
|
150
151
|
def random_float
|
151
152
|
((random_32_bits >> 5) * 67108864.0 + (random_32_bits >> 6)) * FLOAT_FACTOR;
|
152
153
|
end
|
153
154
|
|
154
|
-
# Returns an integer within 0...upto
|
155
|
+
# Returns an integer within 0...upto.
|
155
156
|
def random_integer(upto)
|
156
157
|
n = upto - 1
|
157
158
|
nb_full_32 = 0
|
@@ -202,7 +203,8 @@ module RSpec
|
|
202
203
|
end
|
203
204
|
end
|
204
205
|
|
205
|
-
# Convert an Integer seed of arbitrary size to either a single 32 bit
|
206
|
+
# Convert an Integer seed of arbitrary size to either a single 32 bit
|
207
|
+
# integer, or an Array of 32 bit integers.
|
206
208
|
def self.convert_seed(seed)
|
207
209
|
seed = seed.abs
|
208
210
|
long_values = []
|
@@ -211,7 +213,8 @@ module RSpec
|
|
211
213
|
seed >>= 32
|
212
214
|
end until seed == 0
|
213
215
|
|
214
|
-
|
216
|
+
# Done to allow any kind of sequence of integers.
|
217
|
+
long_values.pop if long_values[-1] == 1 && long_values.size > 1
|
215
218
|
|
216
219
|
long_values.size > 1 ? long_values : long_values.first
|
217
220
|
end
|
@@ -32,15 +32,23 @@ module RSpec
|
|
32
32
|
class Configuration
|
33
33
|
include RSpec::Core::Hooks
|
34
34
|
|
35
|
+
# Module that holds `attr_reader` declarations. It's in a separate
|
36
|
+
# module to allow us to override those methods and use `super`.
|
37
|
+
# @private
|
38
|
+
Readers = Module.new
|
39
|
+
include Readers
|
40
|
+
|
35
41
|
# @private
|
36
42
|
class MustBeConfiguredBeforeExampleGroupsError < StandardError; end
|
37
43
|
|
38
44
|
# @private
|
39
45
|
def self.define_reader(name)
|
40
|
-
|
41
|
-
|
42
|
-
|
46
|
+
Readers.class_eval do
|
47
|
+
remove_method name if method_defined?(name)
|
48
|
+
attr_reader name
|
43
49
|
end
|
50
|
+
|
51
|
+
define_method(name) { value_for(name) { super() } }
|
44
52
|
end
|
45
53
|
|
46
54
|
# @private
|
@@ -71,7 +79,7 @@ module RSpec
|
|
71
79
|
|
72
80
|
# @private
|
73
81
|
#
|
74
|
-
# As `add_setting` but only add the reader
|
82
|
+
# As `add_setting` but only add the reader.
|
75
83
|
def self.add_read_only_setting(name, opts={})
|
76
84
|
raise "Use the instance add_setting method if you want to set a default" if opts.key?(:default)
|
77
85
|
define_reader name
|
@@ -90,8 +98,8 @@ module RSpec
|
|
90
98
|
# `"spec"`). Allows you to just type `rspec` instead of `rspec spec` to
|
91
99
|
# run all the examples in the `spec` directory.
|
92
100
|
#
|
93
|
-
#
|
94
|
-
#
|
101
|
+
# @note Other scripts invoking `rspec` indirectly will ignore this
|
102
|
+
# setting.
|
95
103
|
add_setting :default_path
|
96
104
|
|
97
105
|
# @macro add_setting
|
@@ -160,11 +168,12 @@ module RSpec
|
|
160
168
|
add_setting :failure_exit_code
|
161
169
|
|
162
170
|
# @macro define_reader
|
163
|
-
# Indicates files configured to be required
|
171
|
+
# Indicates files configured to be required.
|
164
172
|
define_reader :requires
|
165
173
|
|
166
174
|
# @macro define_reader
|
167
|
-
# Returns dirs that have been prepended to the load path by the `-I`
|
175
|
+
# Returns dirs that have been prepended to the load path by the `-I`
|
176
|
+
# command line option.
|
168
177
|
define_reader :libs
|
169
178
|
|
170
179
|
# @macro add_setting
|
@@ -172,7 +181,7 @@ module RSpec
|
|
172
181
|
# Default: `$stdout`.
|
173
182
|
define_reader :output_stream
|
174
183
|
|
175
|
-
# Set the output stream for reporter
|
184
|
+
# Set the output stream for reporter.
|
176
185
|
# @attr value [IO] value for output, defaults to $stdout
|
177
186
|
def output_stream=(value)
|
178
187
|
if @reporter && !value.equal?(@output_stream)
|
@@ -186,20 +195,20 @@ module RSpec
|
|
186
195
|
end
|
187
196
|
|
188
197
|
# @macro define_reader
|
189
|
-
# Load files matching this pattern (default: `'**{,/*/**}/*_spec.rb'`)
|
198
|
+
# Load files matching this pattern (default: `'**{,/*/**}/*_spec.rb'`).
|
190
199
|
define_reader :pattern
|
191
200
|
|
192
|
-
# Set pattern to match files to load
|
201
|
+
# Set pattern to match files to load.
|
193
202
|
# @attr value [String] the filename pattern to filter spec files by
|
194
203
|
def pattern=(value)
|
195
204
|
update_pattern_attr :pattern, value
|
196
205
|
end
|
197
206
|
|
198
207
|
# @macro define_reader
|
199
|
-
# Exclude files matching this pattern
|
208
|
+
# Exclude files matching this pattern.
|
200
209
|
define_reader :exclude_pattern
|
201
210
|
|
202
|
-
# Set pattern to match files to exclude
|
211
|
+
# Set pattern to match files to exclude.
|
203
212
|
# @attr value [String] the filename pattern to exclude spec files by
|
204
213
|
def exclude_pattern=(value)
|
205
214
|
update_pattern_attr :exclude_pattern, value
|
@@ -211,84 +220,93 @@ module RSpec
|
|
211
220
|
add_setting :profile_examples
|
212
221
|
|
213
222
|
# @macro add_setting
|
214
|
-
# Run all examples if none match the configured filters
|
223
|
+
# Run all examples if none match the configured filters
|
224
|
+
# (default: `false`).
|
215
225
|
add_setting :run_all_when_everything_filtered
|
216
226
|
|
217
227
|
# @macro add_setting
|
218
228
|
# Color to use to indicate success.
|
219
229
|
# @param color [Symbol] defaults to `:green` but can be set to one of the
|
220
|
-
#
|
221
|
-
#
|
230
|
+
# following: `[:black, :white, :red, :green, :yellow, :blue, :magenta,
|
231
|
+
# :cyan]`
|
222
232
|
add_setting :success_color
|
223
233
|
|
224
234
|
# @macro add_setting
|
225
235
|
# Color to use to print pending examples.
|
226
236
|
# @param color [Symbol] defaults to `:yellow` but can be set to one of the
|
227
|
-
#
|
228
|
-
#
|
237
|
+
# following: `[:black, :white, :red, :green, :yellow, :blue, :magenta,
|
238
|
+
# :cyan]`
|
229
239
|
add_setting :pending_color
|
230
240
|
|
231
241
|
# @macro add_setting
|
232
242
|
# Color to use to indicate failure.
|
233
243
|
# @param color [Symbol] defaults to `:red` but can be set to one of the
|
234
|
-
#
|
235
|
-
#
|
244
|
+
# following: `[:black, :white, :red, :green, :yellow, :blue, :magenta,
|
245
|
+
# :cyan]`
|
236
246
|
add_setting :failure_color
|
237
247
|
|
238
248
|
# @macro add_setting
|
239
249
|
# The default output color.
|
240
250
|
# @param color [Symbol] defaults to `:white` but can be set to one of the
|
241
|
-
#
|
242
|
-
#
|
251
|
+
# following: `[:black, :white, :red, :green, :yellow, :blue, :magenta,
|
252
|
+
# :cyan]`
|
243
253
|
add_setting :default_color
|
244
254
|
|
245
255
|
# @macro add_setting
|
246
256
|
# Color used when a pending example is fixed.
|
247
257
|
# @param color [Symbol] defaults to `:blue` but can be set to one of the
|
248
|
-
#
|
249
|
-
#
|
258
|
+
# following: `[:black, :white, :red, :green, :yellow, :blue, :magenta,
|
259
|
+
# :cyan]`
|
250
260
|
add_setting :fixed_color
|
251
261
|
|
252
262
|
# @macro add_setting
|
253
263
|
# Color used to print details.
|
254
264
|
# @param color [Symbol] defaults to `:cyan` but can be set to one of the
|
255
|
-
#
|
256
|
-
#
|
265
|
+
# following: `[:black, :white, :red, :green, :yellow, :blue, :magenta,
|
266
|
+
# :cyan]`
|
257
267
|
add_setting :detail_color
|
258
268
|
|
259
269
|
# Deprecated. This config option was added in RSpec 2 to pave the way
|
260
270
|
# for this being the default behavior in RSpec 3. Now this option is
|
261
271
|
# a no-op.
|
262
272
|
def treat_symbols_as_metadata_keys_with_true_values=(_value)
|
263
|
-
RSpec.deprecate(
|
264
|
-
|
265
|
-
|
273
|
+
RSpec.deprecate(
|
274
|
+
"RSpec::Core::Configuration#treat_symbols_as_metadata_keys_with_true_values=",
|
275
|
+
:message => "RSpec::Core::Configuration#treat_symbols_as_metadata_keys_with_true_values= " \
|
276
|
+
"is deprecated, it is now set to true as default and " \
|
277
|
+
"setting it to false has no effect."
|
278
|
+
)
|
266
279
|
end
|
267
280
|
|
268
|
-
# Record the start time of the spec suite to measure load time
|
281
|
+
# Record the start time of the spec suite to measure load time.
|
269
282
|
add_setting :start_time
|
270
283
|
|
271
284
|
# @private
|
272
285
|
add_setting :tty
|
273
286
|
# @private
|
274
|
-
add_setting :include_or_extend_modules
|
275
|
-
# @private
|
276
287
|
attr_writer :files_to_run
|
277
288
|
# @private
|
278
|
-
add_setting :expecting_with_rspec
|
279
|
-
# @private
|
280
289
|
attr_accessor :filter_manager
|
281
290
|
# @private
|
282
|
-
|
291
|
+
attr_accessor :static_config_filter_manager
|
292
|
+
# @private
|
293
|
+
attr_reader :backtrace_formatter, :ordering_manager, :loaded_spec_files
|
283
294
|
|
284
295
|
def initialize
|
285
296
|
# rubocop:disable Style/GlobalVars
|
286
297
|
@start_time = $_rspec_core_load_started_at || ::RSpec::Core::Time.now
|
287
298
|
# rubocop:enable Style/GlobalVars
|
288
299
|
@expectation_frameworks = []
|
289
|
-
@
|
300
|
+
@include_modules = FilterableItemRepository::QueryOptimized.new(:any?)
|
301
|
+
@extend_modules = FilterableItemRepository::QueryOptimized.new(:any?)
|
302
|
+
@prepend_modules = FilterableItemRepository::QueryOptimized.new(:any?)
|
303
|
+
|
304
|
+
@before_suite_hooks = []
|
305
|
+
@after_suite_hooks = []
|
306
|
+
|
290
307
|
@mock_framework = nil
|
291
308
|
@files_or_directories_to_run = []
|
309
|
+
@loaded_spec_files = Set.new
|
292
310
|
@color = false
|
293
311
|
@pattern = '**{,/*/**}/*_spec.rb'
|
294
312
|
@exclude_pattern = ''
|
@@ -303,6 +321,7 @@ module RSpec
|
|
303
321
|
@reporter = nil
|
304
322
|
@reporter_buffer = nil
|
305
323
|
@filter_manager = FilterManager.new
|
324
|
+
@static_config_filter_manager = FilterManager.new
|
306
325
|
@ordering_manager = Ordering::ConfigurationManager.new
|
307
326
|
@preferred_options = {}
|
308
327
|
@failure_color = :red
|
@@ -314,7 +333,7 @@ module RSpec
|
|
314
333
|
@profile_examples = false
|
315
334
|
@requires = []
|
316
335
|
@libs = []
|
317
|
-
@derived_metadata_blocks =
|
336
|
+
@derived_metadata_blocks = FilterableItemRepository::QueryOptimized.new(:any?)
|
318
337
|
end
|
319
338
|
|
320
339
|
# @private
|
@@ -332,18 +351,29 @@ module RSpec
|
|
332
351
|
@formatter_loader = nil
|
333
352
|
end
|
334
353
|
|
354
|
+
# @private
|
355
|
+
def reset_filters
|
356
|
+
self.filter_manager = FilterManager.new
|
357
|
+
filter_manager.include_only(
|
358
|
+
Metadata.deep_hash_dup(static_config_filter_manager.inclusions.rules)
|
359
|
+
)
|
360
|
+
filter_manager.exclude_only(
|
361
|
+
Metadata.deep_hash_dup(static_config_filter_manager.exclusions.rules)
|
362
|
+
)
|
363
|
+
end
|
364
|
+
|
335
365
|
# @overload add_setting(name)
|
336
366
|
# @overload add_setting(name, opts)
|
337
367
|
# @option opts [Symbol] :default
|
338
368
|
#
|
339
|
-
#
|
369
|
+
# Set a default value for the generated getter and predicate methods:
|
340
370
|
#
|
341
371
|
# add_setting(:foo, :default => "default value")
|
342
372
|
#
|
343
373
|
# @option opts [Symbol] :alias_with
|
344
374
|
#
|
345
|
-
# Use `:alias_with` to alias the setter, getter, and predicate to
|
346
|
-
# name, or names:
|
375
|
+
# Use `:alias_with` to alias the setter, getter, and predicate to
|
376
|
+
# another name, or names:
|
347
377
|
#
|
348
378
|
# add_setting(:foo, :alias_with => :bar)
|
349
379
|
# add_setting(:foo, :alias_with => [:bar, :baz])
|
@@ -366,7 +396,7 @@ module RSpec
|
|
366
396
|
#
|
367
397
|
# RSpec.configuration.foo=(value)
|
368
398
|
# RSpec.configuration.foo
|
369
|
-
# RSpec.configuration.foo? #
|
399
|
+
# RSpec.configuration.foo? # Returns true if foo returns anything but nil or false.
|
370
400
|
def add_setting(name, opts={})
|
371
401
|
default = opts.delete(:default)
|
372
402
|
(class << self; self; end).class_exec do
|
@@ -375,7 +405,7 @@ module RSpec
|
|
375
405
|
__send__("#{name}=", default) if default
|
376
406
|
end
|
377
407
|
|
378
|
-
# Returns the configured mock framework adapter module
|
408
|
+
# Returns the configured mock framework adapter module.
|
379
409
|
def mock_framework
|
380
410
|
if @mock_framework.nil?
|
381
411
|
begin
|
@@ -387,7 +417,7 @@ module RSpec
|
|
387
417
|
@mock_framework
|
388
418
|
end
|
389
419
|
|
390
|
-
# Delegates to mock_framework=(framework)
|
420
|
+
# Delegates to mock_framework=(framework).
|
391
421
|
def mock_framework=(framework)
|
392
422
|
mock_with framework
|
393
423
|
end
|
@@ -395,19 +425,19 @@ module RSpec
|
|
395
425
|
# Regexps used to exclude lines from backtraces.
|
396
426
|
#
|
397
427
|
# Excludes lines from ruby (and jruby) source, installed gems, anything
|
398
|
-
# in any "bin" directory, and any of the
|
428
|
+
# in any "bin" directory, and any of the RSpec libs (outside gem
|
399
429
|
# installs) by default.
|
400
430
|
#
|
401
431
|
# You can modify the list via the getter, or replace it with the setter.
|
402
432
|
#
|
403
433
|
# To override this behaviour and display a full backtrace, use
|
404
|
-
# `--backtrace`on the command line, in a `.rspec` file, or in the
|
434
|
+
# `--backtrace` on the command line, in a `.rspec` file, or in the
|
405
435
|
# `rspec_options` attribute of RSpec's rake task.
|
406
436
|
def backtrace_exclusion_patterns
|
407
437
|
@backtrace_formatter.exclusion_patterns
|
408
438
|
end
|
409
439
|
|
410
|
-
# Set regular expressions used to exclude lines in backtrace
|
440
|
+
# Set regular expressions used to exclude lines in backtrace.
|
411
441
|
# @param patterns [Regexp] set the backtrace exlusion pattern
|
412
442
|
def backtrace_exclusion_patterns=(patterns)
|
413
443
|
@backtrace_formatter.exclusion_patterns = patterns
|
@@ -425,7 +455,7 @@ module RSpec
|
|
425
455
|
@backtrace_formatter.inclusion_patterns
|
426
456
|
end
|
427
457
|
|
428
|
-
# Set regular expressions used to include lines in backtrace
|
458
|
+
# Set regular expressions used to include lines in backtrace.
|
429
459
|
# @attr patterns [Regexp] set backtrace_formatter inclusion_patterns
|
430
460
|
def backtrace_inclusion_patterns=(patterns)
|
431
461
|
@backtrace_formatter.inclusion_patterns = patterns
|
@@ -485,8 +515,8 @@ module RSpec
|
|
485
515
|
# teardown_mocks_for_rspec
|
486
516
|
# - called after verify_mocks_for_rspec (even if there are errors)
|
487
517
|
#
|
488
|
-
# If the module responds to `configuration` and `mock_with` receives a
|
489
|
-
# it will yield the configuration object to the block e.g.
|
518
|
+
# If the module responds to `configuration` and `mock_with` receives a
|
519
|
+
# block, it will yield the configuration object to the block e.g.
|
490
520
|
#
|
491
521
|
# config.mock_with OtherMockFrameworkAdapter do |mod_config|
|
492
522
|
# mod_config.custom_setting = true
|
@@ -515,7 +545,8 @@ module RSpec
|
|
515
545
|
end
|
516
546
|
|
517
547
|
if block_given?
|
518
|
-
raise "#{framework_module} must respond to `configuration` so that
|
548
|
+
raise "#{framework_module} must respond to `configuration` so that " \
|
549
|
+
"mock_with can yield it." unless framework_module.respond_to?(:configuration)
|
519
550
|
yield framework_module.configuration
|
520
551
|
end
|
521
552
|
|
@@ -534,7 +565,7 @@ module RSpec
|
|
534
565
|
@expectation_frameworks
|
535
566
|
end
|
536
567
|
|
537
|
-
# Delegates to expect_with(framework)
|
568
|
+
# Delegates to expect_with(framework).
|
538
569
|
def expectation_framework=(framework)
|
539
570
|
expect_with(framework)
|
540
571
|
end
|
@@ -569,7 +600,6 @@ module RSpec
|
|
569
600
|
framework
|
570
601
|
when :rspec
|
571
602
|
require 'rspec/expectations'
|
572
|
-
self.expecting_with_rspec = true
|
573
603
|
::RSpec::Matchers
|
574
604
|
when :test_unit
|
575
605
|
require 'rspec/core/test_unit_assertions_adapter'
|
@@ -587,21 +617,24 @@ module RSpec
|
|
587
617
|
end
|
588
618
|
|
589
619
|
if block_given?
|
590
|
-
raise "expect_with only accepts a block with a single argument.
|
591
|
-
|
620
|
+
raise "expect_with only accepts a block with a single argument. " \
|
621
|
+
"Call expect_with #{modules.length} times, " \
|
622
|
+
"once with each argument, instead." if modules.length > 1
|
623
|
+
raise "#{modules.first} must respond to `configuration` so that " \
|
624
|
+
"expect_with can yield it." unless modules.first.respond_to?(:configuration)
|
592
625
|
yield modules.first.configuration
|
593
626
|
end
|
594
627
|
|
595
628
|
@expectation_frameworks.push(*modules)
|
596
629
|
end
|
597
630
|
|
598
|
-
# Check if full backtrace is enabled
|
631
|
+
# Check if full backtrace is enabled.
|
599
632
|
# @return [Boolean] is full backtrace enabled
|
600
633
|
def full_backtrace?
|
601
634
|
@backtrace_formatter.full_backtrace?
|
602
635
|
end
|
603
636
|
|
604
|
-
# Toggle full backtrace
|
637
|
+
# Toggle full backtrace.
|
605
638
|
# @attr true_or_false [Boolean] toggle full backtrace display
|
606
639
|
def full_backtrace=(true_or_false)
|
607
640
|
@backtrace_formatter.full_backtrace = true_or_false
|
@@ -613,10 +646,10 @@ module RSpec
|
|
613
646
|
# @see color_enabled?
|
614
647
|
# @return [Boolean]
|
615
648
|
def color
|
616
|
-
value_for(:color
|
649
|
+
value_for(:color) { @color }
|
617
650
|
end
|
618
651
|
|
619
|
-
# Check if color is enabled for a particular output
|
652
|
+
# Check if color is enabled for a particular output.
|
620
653
|
# @param output [IO] an output stream to use, defaults to the current
|
621
654
|
# `output_stream`
|
622
655
|
# @return [Boolean]
|
@@ -624,13 +657,15 @@ module RSpec
|
|
624
657
|
output_to_tty?(output) && color
|
625
658
|
end
|
626
659
|
|
627
|
-
# Toggle output color
|
660
|
+
# Toggle output color.
|
628
661
|
# @attr true_or_false [Boolean] toggle color enabled
|
629
662
|
def color=(true_or_false)
|
630
663
|
return unless true_or_false
|
631
664
|
|
632
|
-
if RSpec.
|
633
|
-
RSpec.warning "You must use ANSICON 1.31 or later
|
665
|
+
if RSpec::Support::OS.windows? && !ENV['ANSICON']
|
666
|
+
RSpec.warning "You must use ANSICON 1.31 or later " \
|
667
|
+
"(http://adoxa.3eeweb.com/ansicon/) to use colour " \
|
668
|
+
"on Windows"
|
634
669
|
@color = false
|
635
670
|
else
|
636
671
|
@color = true
|
@@ -743,10 +778,10 @@ module RSpec
|
|
743
778
|
|
744
779
|
# @api private
|
745
780
|
#
|
746
|
-
# Defaults `profile_examples` to 10 examples when `@profile_examples` is
|
747
|
-
#
|
781
|
+
# Defaults `profile_examples` to 10 examples when `@profile_examples` is
|
782
|
+
# `true`.
|
748
783
|
def profile_examples
|
749
|
-
profile = value_for(:profile_examples
|
784
|
+
profile = value_for(:profile_examples) { @profile_examples }
|
750
785
|
if profile && !profile.is_a?(Integer)
|
751
786
|
10
|
752
787
|
else
|
@@ -762,7 +797,7 @@ module RSpec
|
|
762
797
|
@files_to_run = nil
|
763
798
|
end
|
764
799
|
|
765
|
-
# The spec files RSpec will run
|
800
|
+
# The spec files RSpec will run.
|
766
801
|
# @return [Array] specified files about to run
|
767
802
|
def files_to_run
|
768
803
|
@files_to_run ||= get_files_to_run(@files_or_directories_to_run)
|
@@ -776,8 +811,8 @@ module RSpec
|
|
776
811
|
# @note The specific example alias below (`pending`) is already
|
777
812
|
# defined for you.
|
778
813
|
# @note Use with caution. This extends the language used in your
|
779
|
-
# specs, but does not add any additional documentation.
|
780
|
-
# in
|
814
|
+
# specs, but does not add any additional documentation. We use this
|
815
|
+
# in RSpec to define methods like `focus` and `xit`, but we also add
|
781
816
|
# docs for those methods.
|
782
817
|
#
|
783
818
|
# @example
|
@@ -860,8 +895,8 @@ module RSpec
|
|
860
895
|
# # ...sortability examples here
|
861
896
|
#
|
862
897
|
# @note Use with caution. This extends the language used in your
|
863
|
-
# specs, but does not add any additional documentation.
|
864
|
-
# in
|
898
|
+
# specs, but does not add any additional documentation. We use this
|
899
|
+
# in RSpec to define `it_should_behave_like` (for backward
|
865
900
|
# compatibility), but we also add docs for that method.
|
866
901
|
def alias_it_behaves_like_to(new_name, report_label='')
|
867
902
|
RSpec::Core::ExampleGroup.define_nested_shared_group_method(new_name, report_label)
|
@@ -878,28 +913,30 @@ module RSpec
|
|
878
913
|
# or config files (e.g. `.rspec`).
|
879
914
|
#
|
880
915
|
# @example
|
881
|
-
# #
|
916
|
+
# # Given this declaration.
|
882
917
|
# describe "something", :foo => 'bar' do
|
883
918
|
# # ...
|
884
919
|
# end
|
885
920
|
#
|
886
|
-
# #
|
921
|
+
# # Any of the following will include that group.
|
887
922
|
# config.filter_run_including :foo => 'bar'
|
888
923
|
# config.filter_run_including :foo => /^ba/
|
889
924
|
# config.filter_run_including :foo => lambda {|v| v == 'bar'}
|
890
925
|
# config.filter_run_including :foo => lambda {|v,m| m[:foo] == 'bar'}
|
891
926
|
#
|
892
|
-
# #
|
927
|
+
# # Given a proc with an arity of 1, the lambda is passed the value
|
928
|
+
# # related to the key, e.g.
|
893
929
|
# config.filter_run_including :foo => lambda {|v| v == 'bar'}
|
894
930
|
#
|
895
|
-
# #
|
896
|
-
# # and the metadata itself e.g.
|
931
|
+
# # Given a proc with an arity of 2, the lambda is passed the value
|
932
|
+
# # related to the key, and the metadata itself e.g.
|
897
933
|
# config.filter_run_including :foo => lambda {|v,m| m[:foo] == 'bar'}
|
898
934
|
#
|
899
935
|
# filter_run_including :foo # same as filter_run_including :foo => true
|
900
936
|
def filter_run_including(*args)
|
901
937
|
meta = Metadata.build_hash_from(args, :warn_about_example_group_filtering)
|
902
938
|
filter_manager.include_with_low_priority meta
|
939
|
+
static_config_filter_manager.include_with_low_priority Metadata.deep_hash_dup(meta)
|
903
940
|
end
|
904
941
|
|
905
942
|
alias_method :filter_run, :filter_run_including
|
@@ -936,28 +973,30 @@ module RSpec
|
|
936
973
|
# or config files (e.g. `.rspec`).
|
937
974
|
#
|
938
975
|
# @example
|
939
|
-
# #
|
976
|
+
# # Given this declaration.
|
940
977
|
# describe "something", :foo => 'bar' do
|
941
978
|
# # ...
|
942
979
|
# end
|
943
980
|
#
|
944
|
-
# #
|
981
|
+
# # Any of the following will exclude that group.
|
945
982
|
# config.filter_run_excluding :foo => 'bar'
|
946
983
|
# config.filter_run_excluding :foo => /^ba/
|
947
984
|
# config.filter_run_excluding :foo => lambda {|v| v == 'bar'}
|
948
985
|
# config.filter_run_excluding :foo => lambda {|v,m| m[:foo] == 'bar'}
|
949
986
|
#
|
950
|
-
# #
|
987
|
+
# # Given a proc with an arity of 1, the lambda is passed the value
|
988
|
+
# # related to the key, e.g.
|
951
989
|
# config.filter_run_excluding :foo => lambda {|v| v == 'bar'}
|
952
990
|
#
|
953
|
-
# #
|
954
|
-
# # and the metadata itself e.g.
|
991
|
+
# # Given a proc with an arity of 2, the lambda is passed the value
|
992
|
+
# # related to the key, and the metadata itself e.g.
|
955
993
|
# config.filter_run_excluding :foo => lambda {|v,m| m[:foo] == 'bar'}
|
956
994
|
#
|
957
995
|
# filter_run_excluding :foo # same as filter_run_excluding :foo => true
|
958
996
|
def filter_run_excluding(*args)
|
959
997
|
meta = Metadata.build_hash_from(args, :warn_about_example_group_filtering)
|
960
998
|
filter_manager.exclude_with_low_priority meta
|
999
|
+
static_config_filter_manager.exclude_with_low_priority Metadata.deep_hash_dup(meta)
|
961
1000
|
end
|
962
1001
|
|
963
1002
|
# Clears and reassigns the `exclusion_filter`. Set to `nil` if you don't
|
@@ -979,8 +1018,8 @@ module RSpec
|
|
979
1018
|
end
|
980
1019
|
|
981
1020
|
# Tells RSpec to include `mod` in example groups. Methods defined in
|
982
|
-
# `mod` are exposed to examples (not example groups).
|
983
|
-
# constrain the groups in which to include the module.
|
1021
|
+
# `mod` are exposed to examples (not example groups). Use `filters` to
|
1022
|
+
# constrain the groups or examples in which to include the module.
|
984
1023
|
#
|
985
1024
|
# @example
|
986
1025
|
#
|
@@ -1009,14 +1048,22 @@ module RSpec
|
|
1009
1048
|
# end
|
1010
1049
|
# end
|
1011
1050
|
#
|
1051
|
+
# @note Filtered module inclusions can also be applied to
|
1052
|
+
# individual examples that have matching metadata. Just like
|
1053
|
+
# Ruby's object model is that every object has a singleton class
|
1054
|
+
# which has only a single instance, RSpec's model is that every
|
1055
|
+
# example has a singleton example group containing just the one
|
1056
|
+
# example.
|
1057
|
+
#
|
1012
1058
|
# @see #extend
|
1059
|
+
# @see #prepend
|
1013
1060
|
def include(mod, *filters)
|
1014
1061
|
meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering)
|
1015
|
-
|
1062
|
+
@include_modules.append(mod, meta)
|
1016
1063
|
end
|
1017
1064
|
|
1018
|
-
# Tells RSpec to extend example groups with `mod`.
|
1019
|
-
# `mod` are exposed to example groups (not examples).
|
1065
|
+
# Tells RSpec to extend example groups with `mod`. Methods defined in
|
1066
|
+
# `mod` are exposed to example groups (not examples). Use `filters` to
|
1020
1067
|
# constrain the groups to extend.
|
1021
1068
|
#
|
1022
1069
|
# Similar to `include`, but behavior is added to example groups, which
|
@@ -1044,25 +1091,87 @@ module RSpec
|
|
1044
1091
|
# end
|
1045
1092
|
#
|
1046
1093
|
# @see #include
|
1094
|
+
# @see #prepend
|
1047
1095
|
def extend(mod, *filters)
|
1048
1096
|
meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering)
|
1049
|
-
|
1097
|
+
@extend_modules.append(mod, meta)
|
1098
|
+
end
|
1099
|
+
|
1100
|
+
if RSpec::Support::RubyFeatures.module_prepends_supported?
|
1101
|
+
# Tells RSpec to prepend example groups with `mod`. Methods defined in
|
1102
|
+
# `mod` are exposed to examples (not example groups). Use `filters` to
|
1103
|
+
# constrain the groups in which to prepend the module.
|
1104
|
+
#
|
1105
|
+
# Similar to `include`, but module is included before the example group's class
|
1106
|
+
# in the ancestor chain.
|
1107
|
+
#
|
1108
|
+
# @example
|
1109
|
+
#
|
1110
|
+
# module OverrideMod
|
1111
|
+
# def override_me
|
1112
|
+
# "overridden"
|
1113
|
+
# end
|
1114
|
+
# end
|
1115
|
+
#
|
1116
|
+
# RSpec.configure do |config|
|
1117
|
+
# config.prepend(OverrideMod, :method => :prepend)
|
1118
|
+
# end
|
1119
|
+
#
|
1120
|
+
# describe "overriding example's class", :method => :prepend do
|
1121
|
+
# it "finds the user" do
|
1122
|
+
# self.class.class_eval do
|
1123
|
+
# def override_me
|
1124
|
+
# end
|
1125
|
+
# end
|
1126
|
+
# override_me # => "overridden"
|
1127
|
+
# # ...
|
1128
|
+
# end
|
1129
|
+
# end
|
1130
|
+
#
|
1131
|
+
# @see #include
|
1132
|
+
# @see #extend
|
1133
|
+
def prepend(mod, *filters)
|
1134
|
+
meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering)
|
1135
|
+
@prepend_modules.append(mod, meta)
|
1136
|
+
end
|
1050
1137
|
end
|
1051
1138
|
|
1052
1139
|
# @private
|
1053
1140
|
#
|
1054
|
-
# Used internally to extend a group with modules using `include` and/or
|
1141
|
+
# Used internally to extend a group with modules using `include`, `prepend` and/or
|
1055
1142
|
# `extend`.
|
1056
1143
|
def configure_group(group)
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1144
|
+
configure_group_with group, @include_modules, :safe_include
|
1145
|
+
configure_group_with group, @extend_modules, :safe_extend
|
1146
|
+
configure_group_with group, @prepend_modules, :safe_prepend
|
1147
|
+
end
|
1148
|
+
|
1149
|
+
# @private
|
1150
|
+
def configure_group_with(group, module_list, application_method)
|
1151
|
+
module_list.items_for(group.metadata).each do |mod|
|
1152
|
+
__send__(application_method, mod, group)
|
1060
1153
|
end
|
1061
1154
|
end
|
1062
1155
|
|
1063
1156
|
# @private
|
1064
|
-
|
1065
|
-
|
1157
|
+
#
|
1158
|
+
# Used internally to extend the singleton class of a single example's
|
1159
|
+
# example group instance with modules using `include` and/or `extend`.
|
1160
|
+
def configure_example(example)
|
1161
|
+
# We replace the metadata so that SharedExampleGroupModule#included
|
1162
|
+
# has access to the example's metadata[:location].
|
1163
|
+
example.example_group_instance.singleton_class.with_replaced_metadata(example.metadata) do
|
1164
|
+
@include_modules.items_for(example.metadata).each do |mod|
|
1165
|
+
safe_include(mod, example.example_group_instance.singleton_class)
|
1166
|
+
end
|
1167
|
+
end
|
1168
|
+
end
|
1169
|
+
|
1170
|
+
if RSpec::Support::RubyFeatures.module_prepends_supported?
|
1171
|
+
# @private
|
1172
|
+
def safe_prepend(mod, host)
|
1173
|
+
host.__send__(:prepend, mod) unless host < mod
|
1174
|
+
end
|
1066
1175
|
end
|
1067
1176
|
|
1068
1177
|
# @private
|
@@ -1075,11 +1184,21 @@ module RSpec
|
|
1075
1184
|
|
1076
1185
|
# @private
|
1077
1186
|
if RUBY_VERSION.to_f >= 1.9
|
1187
|
+
# @private
|
1188
|
+
def safe_include(mod, host)
|
1189
|
+
host.__send__(:include, mod) unless host < mod
|
1190
|
+
end
|
1191
|
+
|
1078
1192
|
# @private
|
1079
1193
|
def safe_extend(mod, host)
|
1080
1194
|
host.extend(mod) unless host.singleton_class < mod
|
1081
1195
|
end
|
1082
1196
|
else
|
1197
|
+
# @private
|
1198
|
+
def safe_include(mod, host)
|
1199
|
+
host.__send__(:include, mod) unless host.included_modules.include?(mod)
|
1200
|
+
end
|
1201
|
+
|
1083
1202
|
# @private
|
1084
1203
|
def safe_extend(mod, host)
|
1085
1204
|
host.extend(mod) unless (class << host; self; end).included_modules.include?(mod)
|
@@ -1102,7 +1221,12 @@ module RSpec
|
|
1102
1221
|
|
1103
1222
|
# @private
|
1104
1223
|
def load_spec_files
|
1105
|
-
files_to_run.uniq.each
|
1224
|
+
files_to_run.uniq.each do |f|
|
1225
|
+
file = File.expand_path(f)
|
1226
|
+
load file
|
1227
|
+
loaded_spec_files << file
|
1228
|
+
end
|
1229
|
+
|
1106
1230
|
@spec_files_loaded = true
|
1107
1231
|
end
|
1108
1232
|
|
@@ -1112,7 +1236,8 @@ module RSpec
|
|
1112
1236
|
# Formats the docstring output using the block provided.
|
1113
1237
|
#
|
1114
1238
|
# @example
|
1115
|
-
# # This will strip the descriptions of both examples and example
|
1239
|
+
# # This will strip the descriptions of both examples and example
|
1240
|
+
# # groups.
|
1116
1241
|
# RSpec.configure do |config|
|
1117
1242
|
# config.format_docstrings { |s| s.strip }
|
1118
1243
|
# end
|
@@ -1157,7 +1282,8 @@ module RSpec
|
|
1157
1282
|
|
1158
1283
|
# @macro delegate_to_ordering_manager
|
1159
1284
|
#
|
1160
|
-
# Sets the default global order and, if order is `'rand:<seed>'`, also
|
1285
|
+
# Sets the default global order and, if order is `'rand:<seed>'`, also
|
1286
|
+
# sets the seed.
|
1161
1287
|
delegate_to_ordering_manager :order=
|
1162
1288
|
|
1163
1289
|
# @macro delegate_to_ordering_manager
|
@@ -1167,8 +1293,10 @@ module RSpec
|
|
1167
1293
|
#
|
1168
1294
|
# @param name [Symbol] The name of the ordering.
|
1169
1295
|
# @yield Block that will order the given examples or example groups
|
1170
|
-
# @yieldparam list [Array<RSpec::Core::Example>,
|
1171
|
-
#
|
1296
|
+
# @yieldparam list [Array<RSpec::Core::Example>,
|
1297
|
+
# Array<RSpec::Core::ExampleGroup>] The examples or groups to order
|
1298
|
+
# @yieldreturn [Array<RSpec::Core::Example>,
|
1299
|
+
# Array<RSpec::Core::ExampleGroup>] The re-ordered examples or groups
|
1172
1300
|
#
|
1173
1301
|
# @example
|
1174
1302
|
# RSpec.configure do |rspec|
|
@@ -1189,7 +1317,7 @@ module RSpec
|
|
1189
1317
|
# @private
|
1190
1318
|
delegate_to_ordering_manager :seed_used?, :ordering_registry
|
1191
1319
|
|
1192
|
-
# Set Ruby warnings on or off
|
1320
|
+
# Set Ruby warnings on or off.
|
1193
1321
|
def warnings=(value)
|
1194
1322
|
$VERBOSE = !!value
|
1195
1323
|
end
|
@@ -1252,7 +1380,7 @@ module RSpec
|
|
1252
1380
|
# `shared_examples_for`, etc) onto `main` and `Module`, instead
|
1253
1381
|
# requiring you to prefix these methods with `RSpec.`. It enables
|
1254
1382
|
# expect-only syntax for rspec-mocks and rspec-expectations. It
|
1255
|
-
# simply disables monkey patching on whatever pieces of
|
1383
|
+
# simply disables monkey patching on whatever pieces of RSpec
|
1256
1384
|
# the user is using.
|
1257
1385
|
#
|
1258
1386
|
# @note It configures rspec-mocks and rspec-expectations only
|
@@ -1265,7 +1393,7 @@ module RSpec
|
|
1265
1393
|
#
|
1266
1394
|
# @example
|
1267
1395
|
#
|
1268
|
-
# # It disables all monkey patching
|
1396
|
+
# # It disables all monkey patching.
|
1269
1397
|
# RSpec.configure do |config|
|
1270
1398
|
# config.disable_monkey_patching!
|
1271
1399
|
# end
|
@@ -1295,33 +1423,142 @@ module RSpec
|
|
1295
1423
|
|
1296
1424
|
# Defines a callback that can assign derived metadata values.
|
1297
1425
|
#
|
1298
|
-
# @param filters [Array<Symbol>, Hash] metadata filters that determine
|
1299
|
-
# or group metadata hashes the callback will be triggered
|
1300
|
-
# the callback will be run against the metadata
|
1301
|
-
#
|
1302
|
-
#
|
1426
|
+
# @param filters [Array<Symbol>, Hash] metadata filters that determine
|
1427
|
+
# which example or group metadata hashes the callback will be triggered
|
1428
|
+
# for. If none are given, the callback will be run against the metadata
|
1429
|
+
# hashes of all groups and examples.
|
1430
|
+
# @yieldparam metadata [Hash] original metadata hash from an example or
|
1431
|
+
# group. Mutate this in your block as needed.
|
1303
1432
|
#
|
1304
1433
|
# @example
|
1305
1434
|
# RSpec.configure do |config|
|
1306
|
-
# # Tag all groups and examples in the spec/unit directory with
|
1435
|
+
# # Tag all groups and examples in the spec/unit directory with
|
1436
|
+
# # :type => :unit
|
1307
1437
|
# config.define_derived_metadata(:file_path => %r{/spec/unit/}) do |metadata|
|
1308
1438
|
# metadata[:type] = :unit
|
1309
1439
|
# end
|
1310
1440
|
# end
|
1311
1441
|
def define_derived_metadata(*filters, &block)
|
1312
1442
|
meta = Metadata.build_hash_from(filters, :warn_about_example_group_filtering)
|
1313
|
-
@derived_metadata_blocks
|
1443
|
+
@derived_metadata_blocks.append(block, meta)
|
1314
1444
|
end
|
1315
1445
|
|
1316
1446
|
# @private
|
1317
1447
|
def apply_derived_metadata_to(metadata)
|
1318
|
-
@derived_metadata_blocks.each do |
|
1319
|
-
block.call(metadata)
|
1448
|
+
@derived_metadata_blocks.items_for(metadata).each do |block|
|
1449
|
+
block.call(metadata)
|
1320
1450
|
end
|
1321
1451
|
end
|
1322
1452
|
|
1453
|
+
# Defines a `before` hook. See {Hooks#before} for full docs.
|
1454
|
+
#
|
1455
|
+
# This method differs from {Hooks#before} in only one way: it supports
|
1456
|
+
# the `:suite` scope. Hooks with the `:suite` scope will be run once before
|
1457
|
+
# the first example of the entire suite is executed.
|
1458
|
+
#
|
1459
|
+
# @see #prepend_before
|
1460
|
+
# @see #after
|
1461
|
+
# @see #append_after
|
1462
|
+
def before(*args, &block)
|
1463
|
+
handle_suite_hook(args, @before_suite_hooks, :push,
|
1464
|
+
Hooks::BeforeHook, block) || super(*args, &block)
|
1465
|
+
end
|
1466
|
+
alias_method :append_before, :before
|
1467
|
+
|
1468
|
+
# Adds `block` to the start of the list of `before` blocks in the same
|
1469
|
+
# scope (`:example`, `:context`, or `:suite`), in contrast to {#before},
|
1470
|
+
# which adds the hook to the end of the list.
|
1471
|
+
#
|
1472
|
+
# See {Hooks#before} for full `before` hook docs.
|
1473
|
+
#
|
1474
|
+
# This method differs from {Hooks#prepend_before} in only one way: it supports
|
1475
|
+
# the `:suite` scope. Hooks with the `:suite` scope will be run once before
|
1476
|
+
# the first example of the entire suite is executed.
|
1477
|
+
#
|
1478
|
+
# @see #before
|
1479
|
+
# @see #after
|
1480
|
+
# @see #append_after
|
1481
|
+
def prepend_before(*args, &block)
|
1482
|
+
handle_suite_hook(args, @before_suite_hooks, :unshift,
|
1483
|
+
Hooks::BeforeHook, block) || super(*args, &block)
|
1484
|
+
end
|
1485
|
+
|
1486
|
+
# Defines a `after` hook. See {Hooks#after} for full docs.
|
1487
|
+
#
|
1488
|
+
# This method differs from {Hooks#after} in only one way: it supports
|
1489
|
+
# the `:suite` scope. Hooks with the `:suite` scope will be run once after
|
1490
|
+
# the last example of the entire suite is executed.
|
1491
|
+
#
|
1492
|
+
# @see #append_after
|
1493
|
+
# @see #before
|
1494
|
+
# @see #prepend_before
|
1495
|
+
def after(*args, &block)
|
1496
|
+
handle_suite_hook(args, @after_suite_hooks, :unshift,
|
1497
|
+
Hooks::AfterHook, block) || super(*args, &block)
|
1498
|
+
end
|
1499
|
+
alias_method :prepend_after, :after
|
1500
|
+
|
1501
|
+
# Adds `block` to the end of the list of `after` blocks in the same
|
1502
|
+
# scope (`:example`, `:context`, or `:suite`), in contrast to {#after},
|
1503
|
+
# which adds the hook to the start of the list.
|
1504
|
+
#
|
1505
|
+
# See {Hooks#after} for full `after` hook docs.
|
1506
|
+
#
|
1507
|
+
# This method differs from {Hooks#append_after} in only one way: it supports
|
1508
|
+
# the `:suite` scope. Hooks with the `:suite` scope will be run once after
|
1509
|
+
# the last example of the entire suite is executed.
|
1510
|
+
#
|
1511
|
+
# @see #append_after
|
1512
|
+
# @see #before
|
1513
|
+
# @see #prepend_before
|
1514
|
+
def append_after(*args, &block)
|
1515
|
+
handle_suite_hook(args, @after_suite_hooks, :push,
|
1516
|
+
Hooks::AfterHook, block) || super(*args, &block)
|
1517
|
+
end
|
1518
|
+
|
1519
|
+
# @private
|
1520
|
+
def with_suite_hooks
|
1521
|
+
return yield if dry_run?
|
1522
|
+
|
1523
|
+
hook_context = SuiteHookContext.new
|
1524
|
+
begin
|
1525
|
+
run_hooks_with(@before_suite_hooks, hook_context)
|
1526
|
+
yield
|
1527
|
+
ensure
|
1528
|
+
run_hooks_with(@after_suite_hooks, hook_context)
|
1529
|
+
end
|
1530
|
+
end
|
1531
|
+
|
1532
|
+
# @private
|
1533
|
+
# Holds the various registered hooks. Here we use a FilterableItemRepository
|
1534
|
+
# implementation that is specifically optimized for the read/write patterns
|
1535
|
+
# of the config object.
|
1536
|
+
def hooks
|
1537
|
+
@hooks ||= HookCollections.new(self, FilterableItemRepository::QueryOptimized)
|
1538
|
+
end
|
1539
|
+
|
1323
1540
|
private
|
1324
1541
|
|
1542
|
+
def handle_suite_hook(args, collection, append_or_prepend, hook_type, block)
|
1543
|
+
scope, meta = *args
|
1544
|
+
return nil unless scope == :suite
|
1545
|
+
|
1546
|
+
if meta
|
1547
|
+
# TODO: in RSpec 4, consider raising an error here.
|
1548
|
+
# We warn only for backwards compatibility.
|
1549
|
+
RSpec.warn_with "WARNING: `:suite` hooks do not support metadata since " \
|
1550
|
+
"they apply to the suite as a whole rather than " \
|
1551
|
+
"any individual example or example group that has metadata. " \
|
1552
|
+
"The metadata you have provided (#{meta.inspect}) will be ignored."
|
1553
|
+
end
|
1554
|
+
|
1555
|
+
collection.__send__(append_or_prepend, hook_type.new(block, {}))
|
1556
|
+
end
|
1557
|
+
|
1558
|
+
def run_hooks_with(hooks, hook_context)
|
1559
|
+
hooks.each { |h| h.run(hook_context) }
|
1560
|
+
end
|
1561
|
+
|
1325
1562
|
def get_files_to_run(paths)
|
1326
1563
|
FlatMap.flat_map(paths_to_check(paths)) do |path|
|
1327
1564
|
path = path.gsub(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR
|
@@ -1331,7 +1568,7 @@ module RSpec
|
|
1331
1568
|
|
1332
1569
|
def paths_to_check(paths)
|
1333
1570
|
return paths if pattern_might_load_specs_from_vendored_dirs?
|
1334
|
-
paths + [
|
1571
|
+
paths + [Dir.getwd]
|
1335
1572
|
end
|
1336
1573
|
|
1337
1574
|
def pattern_might_load_specs_from_vendored_dirs?
|
@@ -1386,8 +1623,8 @@ module RSpec
|
|
1386
1623
|
$0.split(File::SEPARATOR).last
|
1387
1624
|
end
|
1388
1625
|
|
1389
|
-
def value_for(key
|
1390
|
-
@preferred_options.
|
1626
|
+
def value_for(key)
|
1627
|
+
@preferred_options.fetch(key) { yield }
|
1391
1628
|
end
|
1392
1629
|
|
1393
1630
|
def assert_no_example_groups_defined(config_option)
|
@@ -1428,7 +1665,8 @@ module RSpec
|
|
1428
1665
|
|
1429
1666
|
def update_pattern_attr(name, value)
|
1430
1667
|
if @spec_files_loaded
|
1431
|
-
RSpec.warning "Configuring `#{name}` to #{value} has no effect since
|
1668
|
+
RSpec.warning "Configuring `#{name}` to #{value} has no effect since " \
|
1669
|
+
"RSpec has already loaded the spec files."
|
1432
1670
|
end
|
1433
1671
|
|
1434
1672
|
instance_variable_set(:"@#{name}", value)
|