rspec-expectations 2.13.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- checksums.yaml.gz.sig +0 -0
- data/Changelog.md +413 -23
- data/License.txt +1 -0
- data/README.md +109 -80
- data/lib/rspec/{matchers → expectations}/configuration.rb +44 -14
- data/lib/rspec/expectations/expectation_target.rb +71 -38
- data/lib/rspec/expectations/fail_with.rb +12 -44
- data/lib/rspec/expectations/handler.rb +135 -35
- data/lib/rspec/expectations/minitest_integration.rb +16 -0
- data/lib/rspec/expectations/syntax.rb +60 -94
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/expectations.rb +46 -24
- data/lib/rspec/matchers/aliased_matcher.rb +41 -0
- data/lib/rspec/matchers/built_in/all.rb +78 -0
- data/lib/rspec/matchers/built_in/base_matcher.rb +63 -15
- data/lib/rspec/matchers/built_in/be.rb +170 -79
- data/lib/rspec/matchers/built_in/be_between.rb +77 -0
- data/lib/rspec/matchers/built_in/be_instance_of.rb +11 -3
- data/lib/rspec/matchers/built_in/be_kind_of.rb +5 -0
- data/lib/rspec/matchers/built_in/be_within.rb +40 -16
- data/lib/rspec/matchers/built_in/change.rb +275 -74
- data/lib/rspec/matchers/built_in/compound.rb +122 -0
- data/lib/rspec/matchers/built_in/contain_exactly.rb +256 -0
- data/lib/rspec/matchers/built_in/cover.rb +3 -0
- data/lib/rspec/matchers/built_in/eq.rb +60 -6
- data/lib/rspec/matchers/built_in/eql.rb +17 -5
- data/lib/rspec/matchers/built_in/equal.rb +55 -21
- data/lib/rspec/matchers/built_in/exist.rb +74 -10
- data/lib/rspec/matchers/built_in/has.rb +71 -15
- data/lib/rspec/matchers/built_in/include.rb +58 -29
- data/lib/rspec/matchers/built_in/match.rb +19 -1
- data/lib/rspec/matchers/built_in/operators.rb +119 -0
- data/lib/rspec/matchers/built_in/output.rb +150 -0
- data/lib/rspec/matchers/built_in/raise_error.rb +91 -33
- data/lib/rspec/matchers/built_in/respond_to.rb +42 -20
- data/lib/rspec/matchers/built_in/satisfy.rb +19 -3
- data/lib/rspec/matchers/built_in/start_and_end_with.rb +54 -18
- data/lib/rspec/matchers/built_in/throw_symbol.rb +38 -8
- data/lib/rspec/matchers/built_in/yield.rb +237 -55
- data/lib/rspec/matchers/built_in.rb +45 -33
- data/lib/rspec/matchers/composable.rb +179 -0
- data/lib/rspec/matchers/dsl.rb +362 -5
- data/lib/rspec/matchers/generated_descriptions.rb +13 -6
- data/lib/rspec/matchers/matcher_delegator.rb +37 -0
- data/lib/rspec/matchers/pretty.rb +33 -20
- data/lib/rspec/matchers.rb +450 -227
- data.tar.gz.sig +1 -0
- metadata +100 -215
- metadata.gz.sig +0 -0
- data/features/README.md +0 -49
- data/features/Upgrade.md +0 -53
- data/features/built_in_matchers/README.md +0 -90
- data/features/built_in_matchers/be.feature +0 -175
- data/features/built_in_matchers/be_within.feature +0 -48
- data/features/built_in_matchers/cover.feature +0 -47
- data/features/built_in_matchers/end_with.feature +0 -48
- data/features/built_in_matchers/equality.feature +0 -139
- data/features/built_in_matchers/exist.feature +0 -45
- data/features/built_in_matchers/expect_change.feature +0 -59
- data/features/built_in_matchers/expect_error.feature +0 -144
- data/features/built_in_matchers/have.feature +0 -109
- data/features/built_in_matchers/include.feature +0 -174
- data/features/built_in_matchers/match.feature +0 -52
- data/features/built_in_matchers/operators.feature +0 -227
- data/features/built_in_matchers/predicates.feature +0 -137
- data/features/built_in_matchers/respond_to.feature +0 -84
- data/features/built_in_matchers/satisfy.feature +0 -33
- data/features/built_in_matchers/start_with.feature +0 -48
- data/features/built_in_matchers/throw_symbol.feature +0 -91
- data/features/built_in_matchers/types.feature +0 -116
- data/features/built_in_matchers/yield.feature +0 -146
- data/features/custom_matchers/access_running_example.feature +0 -53
- data/features/custom_matchers/define_diffable_matcher.feature +0 -27
- data/features/custom_matchers/define_matcher.feature +0 -368
- data/features/custom_matchers/define_matcher_outside_rspec.feature +0 -38
- data/features/custom_matchers/define_matcher_with_fluent_interface.feature +0 -24
- data/features/customized_message.feature +0 -22
- data/features/diffing.feature +0 -85
- data/features/implicit_docstrings.feature +0 -52
- data/features/step_definitions/additional_cli_steps.rb +0 -22
- data/features/support/env.rb +0 -5
- data/features/syntax_configuration.feature +0 -68
- data/features/test_frameworks/test_unit.feature +0 -46
- data/lib/rspec/expectations/deprecation.rb +0 -38
- data/lib/rspec/expectations/differ.rb +0 -115
- data/lib/rspec/expectations/errors.rb +0 -9
- data/lib/rspec/expectations/extensions/array.rb +0 -9
- data/lib/rspec/expectations/extensions/object.rb +0 -39
- data/lib/rspec/expectations/extensions.rb +0 -2
- data/lib/rspec/matchers/be_close.rb +0 -9
- data/lib/rspec/matchers/built_in/have.rb +0 -108
- data/lib/rspec/matchers/built_in/match_array.rb +0 -51
- data/lib/rspec/matchers/compatibility.rb +0 -14
- data/lib/rspec/matchers/extensions/instance_eval_with_args.rb +0 -39
- data/lib/rspec/matchers/matcher.rb +0 -300
- data/lib/rspec/matchers/method_missing.rb +0 -12
- data/lib/rspec/matchers/operator_matcher.rb +0 -109
- data/lib/rspec-expectations.rb +0 -1
- data/spec/rspec/expectations/differ_spec.rb +0 -170
- data/spec/rspec/expectations/expectation_target_spec.rb +0 -75
- data/spec/rspec/expectations/extensions/kernel_spec.rb +0 -67
- data/spec/rspec/expectations/fail_with_spec.rb +0 -95
- data/spec/rspec/expectations/handler_spec.rb +0 -206
- data/spec/rspec/expectations/syntax_spec.rb +0 -97
- data/spec/rspec/matchers/base_matcher_spec.rb +0 -62
- data/spec/rspec/matchers/be_close_spec.rb +0 -22
- data/spec/rspec/matchers/be_instance_of_spec.rb +0 -63
- data/spec/rspec/matchers/be_kind_of_spec.rb +0 -41
- data/spec/rspec/matchers/be_spec.rb +0 -516
- data/spec/rspec/matchers/be_within_spec.rb +0 -129
- data/spec/rspec/matchers/change_spec.rb +0 -542
- data/spec/rspec/matchers/configuration_spec.rb +0 -238
- data/spec/rspec/matchers/cover_spec.rb +0 -69
- data/spec/rspec/matchers/description_generation_spec.rb +0 -176
- data/spec/rspec/matchers/dsl_spec.rb +0 -57
- data/spec/rspec/matchers/eq_spec.rb +0 -60
- data/spec/rspec/matchers/eql_spec.rb +0 -41
- data/spec/rspec/matchers/equal_spec.rb +0 -78
- data/spec/rspec/matchers/exist_spec.rb +0 -124
- data/spec/rspec/matchers/has_spec.rb +0 -122
- data/spec/rspec/matchers/have_spec.rb +0 -445
- data/spec/rspec/matchers/include_matcher_integration_spec.rb +0 -30
- data/spec/rspec/matchers/include_spec.rb +0 -531
- data/spec/rspec/matchers/match_array_spec.rb +0 -194
- data/spec/rspec/matchers/match_spec.rb +0 -61
- data/spec/rspec/matchers/matcher_spec.rb +0 -471
- data/spec/rspec/matchers/matchers_spec.rb +0 -37
- data/spec/rspec/matchers/method_missing_spec.rb +0 -28
- data/spec/rspec/matchers/operator_matcher_spec.rb +0 -223
- data/spec/rspec/matchers/raise_error_spec.rb +0 -395
- data/spec/rspec/matchers/respond_to_spec.rb +0 -292
- data/spec/rspec/matchers/satisfy_spec.rb +0 -44
- data/spec/rspec/matchers/start_with_end_with_spec.rb +0 -186
- data/spec/rspec/matchers/throw_symbol_spec.rb +0 -116
- data/spec/rspec/matchers/yield_spec.rb +0 -437
- data/spec/spec_helper.rb +0 -54
- data/spec/support/classes.rb +0 -56
- data/spec/support/in_sub_process.rb +0 -38
- data/spec/support/matchers.rb +0 -22
- data/spec/support/ruby_version.rb +0 -10
- data/spec/support/shared_examples.rb +0 -13
data/lib/rspec/matchers.rb
CHANGED
|
@@ -1,15 +1,31 @@
|
|
|
1
|
+
require 'rspec/support'
|
|
2
|
+
RSpec::Support.define_optimized_require_for_rspec(:matchers) { |f| require_relative(f) }
|
|
3
|
+
|
|
4
|
+
%w[
|
|
5
|
+
pretty
|
|
6
|
+
composable
|
|
7
|
+
built_in
|
|
8
|
+
generated_descriptions
|
|
9
|
+
dsl
|
|
10
|
+
matcher_delegator
|
|
11
|
+
aliased_matcher
|
|
12
|
+
].each { |file| RSpec::Support.require_rspec_matchers(file) }
|
|
13
|
+
|
|
14
|
+
# RSpec's top level namespace. All of rspec-expectations is contained
|
|
15
|
+
# in the `RSpec::Expectations` and `RSpec::Matchers` namespaces.
|
|
1
16
|
module RSpec
|
|
2
|
-
# RSpec::Matchers provides a number of useful matchers we use to
|
|
17
|
+
# RSpec::Matchers provides a number of useful matchers we use to define
|
|
3
18
|
# expectations. A matcher is any object that responds to the following:
|
|
4
19
|
#
|
|
5
20
|
# matches?(actual)
|
|
6
|
-
#
|
|
21
|
+
# failure_message
|
|
7
22
|
#
|
|
8
23
|
# These methods are also part of the matcher protocol, but are optional:
|
|
9
24
|
#
|
|
10
25
|
# does_not_match?(actual)
|
|
11
|
-
#
|
|
26
|
+
# failure_message_when_negated
|
|
12
27
|
# description
|
|
28
|
+
# supports_block_expectations?
|
|
13
29
|
#
|
|
14
30
|
# ## Predicates
|
|
15
31
|
#
|
|
@@ -20,32 +36,39 @@ module RSpec
|
|
|
20
36
|
# A Ruby predicate is a method that ends with a "?" and returns true or false.
|
|
21
37
|
# Common examples are `empty?`, `nil?`, and `instance_of?`.
|
|
22
38
|
#
|
|
23
|
-
# All you need to do is write `
|
|
24
|
-
# the question mark, and RSpec will figure it out from there.
|
|
39
|
+
# All you need to do is write `expect(..).to be_` followed by the predicate
|
|
40
|
+
# without the question mark, and RSpec will figure it out from there.
|
|
41
|
+
# For example:
|
|
25
42
|
#
|
|
26
|
-
# [].
|
|
27
|
-
# [].
|
|
43
|
+
# expect([]).to be_empty # => [].empty?() | passes
|
|
44
|
+
# expect([]).not_to be_empty # => [].empty?() | fails
|
|
28
45
|
#
|
|
29
46
|
# In addtion to prefixing the predicate matchers with "be_", you can also use "be_a_"
|
|
30
47
|
# and "be_an_", making your specs read much more naturally:
|
|
31
48
|
#
|
|
32
|
-
# "a string".
|
|
49
|
+
# expect("a string").to be_an_instance_of(String) # =>"a string".instance_of?(String) # passes
|
|
33
50
|
#
|
|
34
|
-
# 3.
|
|
35
|
-
# 3.
|
|
36
|
-
# 3.
|
|
37
|
-
# 3.
|
|
51
|
+
# expect(3).to be_a_kind_of(Fixnum) # => 3.kind_of?(Numeric) | passes
|
|
52
|
+
# expect(3).to be_a_kind_of(Numeric) # => 3.kind_of?(Numeric) | passes
|
|
53
|
+
# expect(3).to be_an_instance_of(Fixnum) # => 3.instance_of?(Fixnum) | passes
|
|
54
|
+
# expect(3).not_to be_an_instance_of(Numeric) # => 3.instance_of?(Numeric) | fails
|
|
38
55
|
#
|
|
39
56
|
# RSpec will also create custom matchers for predicates like `has_key?`. To
|
|
40
57
|
# use this feature, just state that the object should have_key(:key) and RSpec will
|
|
41
58
|
# call has_key?(:key) on the target. For example:
|
|
42
59
|
#
|
|
43
|
-
#
|
|
44
|
-
#
|
|
60
|
+
# expect(:a => "A").to have_key(:a)
|
|
61
|
+
# expect(:a => "A").to have_key(:b) # fails
|
|
45
62
|
#
|
|
46
63
|
# You can use this feature to invoke any predicate that begins with "has_", whether it is
|
|
47
64
|
# part of the Ruby libraries (like `Hash#has_key?`) or a method you wrote on your own class.
|
|
48
65
|
#
|
|
66
|
+
# Note that RSpec does not provide composable aliases for these dynamic predicate
|
|
67
|
+
# matchers. You can easily define your own aliases, though:
|
|
68
|
+
#
|
|
69
|
+
# RSpec::Matchers.alias_matcher :a_user_who_is_an_admin, :be_an_admin
|
|
70
|
+
# expect(user_list).to include(a_user_who_is_an_admin)
|
|
71
|
+
#
|
|
49
72
|
# ## Custom Matchers
|
|
50
73
|
#
|
|
51
74
|
# When you find that none of the stock matchers provide a natural feeling
|
|
@@ -58,15 +81,15 @@ module RSpec
|
|
|
58
81
|
# zones on a virtual board. To specify that bob should be in zone 4, you
|
|
59
82
|
# could say:
|
|
60
83
|
#
|
|
61
|
-
# bob.current_zone.
|
|
84
|
+
# expect(bob.current_zone).to eql(Zone.new("4"))
|
|
62
85
|
#
|
|
63
86
|
# But you might find it more expressive to say:
|
|
64
87
|
#
|
|
65
|
-
# bob.
|
|
88
|
+
# expect(bob).to be_in_zone("4")
|
|
66
89
|
#
|
|
67
90
|
# and/or
|
|
68
91
|
#
|
|
69
|
-
# bob.
|
|
92
|
+
# expect(bob).not_to be_in_zone("3")
|
|
70
93
|
#
|
|
71
94
|
# You can create such a matcher like so:
|
|
72
95
|
#
|
|
@@ -85,11 +108,11 @@ module RSpec
|
|
|
85
108
|
# player.in_zone?(zone)
|
|
86
109
|
# end
|
|
87
110
|
#
|
|
88
|
-
#
|
|
111
|
+
# failure_message do |player|
|
|
89
112
|
# # generate and return the appropriate string.
|
|
90
113
|
# end
|
|
91
114
|
#
|
|
92
|
-
#
|
|
115
|
+
# failure_message_when_negated do |player|
|
|
93
116
|
# # generate and return the appropriate string.
|
|
94
117
|
# end
|
|
95
118
|
#
|
|
@@ -100,9 +123,9 @@ module RSpec
|
|
|
100
123
|
#
|
|
101
124
|
# Each of the message-generation methods has access to the block arguments
|
|
102
125
|
# passed to the <tt>create</tt> method (in this case, <tt>zone</tt>). The
|
|
103
|
-
# failure message methods (<tt>
|
|
104
|
-
# <tt>
|
|
105
|
-
# receiver of <tt>
|
|
126
|
+
# failure message methods (<tt>failure_message</tt> and
|
|
127
|
+
# <tt>failure_message_when_negated</tt>) are passed the actual value (the
|
|
128
|
+
# receiver of <tt>expect(..)</tt> or <tt>expect(..).not_to</tt>).
|
|
106
129
|
#
|
|
107
130
|
# ### Custom Matcher from scratch
|
|
108
131
|
#
|
|
@@ -118,11 +141,11 @@ module RSpec
|
|
|
118
141
|
# @target.current_zone.eql?(Zone.new(@expected))
|
|
119
142
|
# end
|
|
120
143
|
#
|
|
121
|
-
# def
|
|
144
|
+
# def failure_message
|
|
122
145
|
# "expected #{@target.inspect} to be in Zone #{@expected}"
|
|
123
146
|
# end
|
|
124
147
|
#
|
|
125
|
-
# def
|
|
148
|
+
# def failure_message_when_negated
|
|
126
149
|
# "expected #{@target.inspect} not to be in Zone #{@expected}"
|
|
127
150
|
# end
|
|
128
151
|
# end
|
|
@@ -158,59 +181,112 @@ module RSpec
|
|
|
158
181
|
# RSpec::configure do |config|
|
|
159
182
|
# config.include(CustomGameMatchers)
|
|
160
183
|
# end
|
|
184
|
+
#
|
|
185
|
+
# ### Making custom matchers composable
|
|
186
|
+
#
|
|
187
|
+
# RSpec's built-in matchers are designed to be composed, in expressions like:
|
|
188
|
+
#
|
|
189
|
+
# expect(["barn", 2.45]).to contain_exactly(
|
|
190
|
+
# a_value_within(0.1).of(2.5),
|
|
191
|
+
# a_string_starting_with("bar")
|
|
192
|
+
# )
|
|
193
|
+
#
|
|
194
|
+
# Custom matchers can easily participate in composed matcher expressions like these.
|
|
195
|
+
# Include {RSpec::Matchers::Composable} in your custom matcher to make it support
|
|
196
|
+
# being composed (matchers defined using the DSL have this included automatically).
|
|
197
|
+
# Within your matcher's `matches?` method (or the `match` block, if using the DSL),
|
|
198
|
+
# use `values_match?(expected, actual)` rather than `expected == actual`.
|
|
199
|
+
# Under the covers, `values_match?` is able to match arbitrary
|
|
200
|
+
# nested data structures containing a mix of both matchers and non-matcher objects.
|
|
201
|
+
# It uses `===` and `==` to perform the matching, considering the values to
|
|
202
|
+
# match if either returns `true`. The `Composable` mixin also provides some helper
|
|
203
|
+
# methods for surfacing the matcher descriptions within your matcher's description
|
|
204
|
+
# or failure messages.
|
|
205
|
+
#
|
|
206
|
+
# RSpec's built-in matchers each have a number of aliases that rephrase the matcher
|
|
207
|
+
# from a verb phrase (such as `be_within`) to a noun phrase (such as `a_value_within`),
|
|
208
|
+
# which reads better when the matcher is passed as an argument in a composed matcher
|
|
209
|
+
# expressions, and also uses the noun-phrase wording in the matcher's `description`,
|
|
210
|
+
# for readable failure messages. You can alias your custom matchers in similar fashion
|
|
211
|
+
# using {RSpec::Matchers.alias_matcher}.
|
|
161
212
|
module Matchers
|
|
162
|
-
#
|
|
163
|
-
#
|
|
164
|
-
#
|
|
165
|
-
#
|
|
166
|
-
#
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
213
|
+
# @method expect
|
|
214
|
+
# Supports `expect(actual).to matcher` syntax by wrapping `actual` in an
|
|
215
|
+
# `ExpectationTarget`.
|
|
216
|
+
# @example
|
|
217
|
+
# expect(actual).to eq(expected)
|
|
218
|
+
# expect(actual).not_to eq(expected)
|
|
219
|
+
# @return [ExpectationTarget]
|
|
220
|
+
# @see ExpectationTarget#to
|
|
221
|
+
# @see ExpectationTarget#not_to
|
|
222
|
+
|
|
223
|
+
# Defines a matcher alias. The returned matcher's `description` will be overriden
|
|
224
|
+
# to reflect the phrasing of the new name, which will be used in failure messages
|
|
225
|
+
# when passed as an argument to another matcher in a composed matcher expression.
|
|
226
|
+
#
|
|
227
|
+
# @param new_name [Symbol] the new name for the matcher
|
|
228
|
+
# @param old_name [Symbol] the original name for the matcher
|
|
229
|
+
# @yield [String] optional block that, when given is used to define the overriden
|
|
230
|
+
# description. The yielded arg is the original description. If no block is
|
|
231
|
+
# provided, a default description override is used based on the old and
|
|
232
|
+
# new names.
|
|
233
|
+
#
|
|
234
|
+
# @example
|
|
235
|
+
#
|
|
236
|
+
# RSpec::Matchers.alias_matcher :a_list_that_sums_to, :sum_to
|
|
237
|
+
# sum_to(3).description # => "sum to 3"
|
|
238
|
+
# a_list_that_sums_to(3).description # => "a list that sums to 3"
|
|
239
|
+
#
|
|
240
|
+
# @example
|
|
241
|
+
#
|
|
242
|
+
# RSpec::Matchers.alias_matcher :a_list_sorted_by, :be_sorted_by do |description|
|
|
243
|
+
# description.sub("be sorted by", "a list sorted by")
|
|
244
|
+
# end
|
|
245
|
+
#
|
|
246
|
+
# be_sorted_by(:age).description # => "be sorted by age"
|
|
247
|
+
# a_list_sorted_by(:age).description # => "a list sorted by age"
|
|
248
|
+
#
|
|
249
|
+
# @!macro [attach] alias_matcher
|
|
250
|
+
# @!parse
|
|
251
|
+
# alias $1 $2
|
|
252
|
+
def self.alias_matcher(new_name, old_name, &description_override)
|
|
253
|
+
description_override ||= lambda do |old_desc|
|
|
254
|
+
old_desc.gsub(Pretty.split_words(old_name), Pretty.split_words(new_name))
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
define_method(new_name) do |*args, &block|
|
|
258
|
+
matcher = __send__(old_name, *args, &block)
|
|
259
|
+
AliasedMatcher.new(matcher, description_override)
|
|
260
|
+
end
|
|
172
261
|
end
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
require 'rspec/matchers/extensions/instance_eval_with_args'
|
|
177
|
-
require 'rspec/matchers/pretty'
|
|
178
|
-
|
|
179
|
-
require 'rspec/matchers/built_in'
|
|
180
|
-
require 'rspec/matchers/matcher'
|
|
181
|
-
require 'rspec/matchers/operator_matcher'
|
|
182
|
-
require 'rspec/matchers/be_close'
|
|
183
|
-
|
|
184
|
-
require 'rspec/matchers/generated_descriptions'
|
|
185
|
-
require 'rspec/matchers/method_missing'
|
|
186
|
-
require 'rspec/matchers/compatibility'
|
|
187
|
-
require 'rspec/matchers/dsl'
|
|
188
|
-
|
|
189
|
-
module RSpec
|
|
190
|
-
module Matchers
|
|
191
262
|
|
|
192
263
|
# Passes if actual is truthy (anything but false or nil)
|
|
193
|
-
def
|
|
194
|
-
BuiltIn::
|
|
264
|
+
def be_truthy
|
|
265
|
+
BuiltIn::BeTruthy.new
|
|
195
266
|
end
|
|
267
|
+
alias_matcher :a_truthy_value, :be_truthy
|
|
196
268
|
|
|
197
|
-
# Passes if actual is
|
|
198
|
-
def
|
|
199
|
-
BuiltIn::
|
|
269
|
+
# Passes if actual is falsey (false or nil)
|
|
270
|
+
def be_falsey
|
|
271
|
+
BuiltIn::BeFalsey.new
|
|
200
272
|
end
|
|
273
|
+
alias_matcher :be_falsy, :be_falsey
|
|
274
|
+
alias_matcher :a_falsey_value, :be_falsey
|
|
275
|
+
alias_matcher :a_falsy_value, :be_falsey
|
|
201
276
|
|
|
202
277
|
# Passes if actual is nil
|
|
203
278
|
def be_nil
|
|
204
279
|
BuiltIn::BeNil.new
|
|
205
280
|
end
|
|
281
|
+
alias_matcher :a_nil_value, :be_nil
|
|
206
282
|
|
|
207
283
|
# @example
|
|
208
|
-
# actual.
|
|
209
|
-
# actual.
|
|
210
|
-
# actual.
|
|
211
|
-
# actual.
|
|
212
|
-
# actual.
|
|
213
|
-
# actual.
|
|
284
|
+
# expect(actual).to be_truthy
|
|
285
|
+
# expect(actual).to be_falsey
|
|
286
|
+
# expect(actual).to be_nil
|
|
287
|
+
# expect(actual).to be_[arbitrary_predicate](*args)
|
|
288
|
+
# expect(actual).not_to be_nil
|
|
289
|
+
# expect(actual).not_to be_[arbitrary_predicate](*args)
|
|
214
290
|
#
|
|
215
291
|
# Given true, false, or nil, will pass if actual value is true, false or
|
|
216
292
|
# nil (respectively). Given no args means the caller should satisfy an if
|
|
@@ -228,49 +304,68 @@ module RSpec
|
|
|
228
304
|
args.empty? ?
|
|
229
305
|
Matchers::BuiltIn::Be.new : equal(*args)
|
|
230
306
|
end
|
|
307
|
+
alias_matcher :a_value, :be
|
|
231
308
|
|
|
232
309
|
# passes if target.kind_of?(klass)
|
|
233
310
|
def be_a(klass)
|
|
234
311
|
be_a_kind_of(klass)
|
|
235
312
|
end
|
|
236
|
-
|
|
237
313
|
alias_method :be_an, :be_a
|
|
238
314
|
|
|
239
315
|
# Passes if actual.instance_of?(expected)
|
|
240
316
|
#
|
|
241
317
|
# @example
|
|
242
318
|
#
|
|
243
|
-
# 5.
|
|
244
|
-
# 5.
|
|
245
|
-
# 5.
|
|
319
|
+
# expect(5).to be_an_instance_of(Fixnum)
|
|
320
|
+
# expect(5).not_to be_an_instance_of(Numeric)
|
|
321
|
+
# expect(5).not_to be_an_instance_of(Float)
|
|
246
322
|
def be_an_instance_of(expected)
|
|
247
323
|
BuiltIn::BeAnInstanceOf.new(expected)
|
|
248
324
|
end
|
|
249
|
-
|
|
250
|
-
|
|
325
|
+
alias_method :be_instance_of, :be_an_instance_of
|
|
326
|
+
alias_matcher :an_instance_of, :be_an_instance_of
|
|
251
327
|
|
|
252
328
|
# Passes if actual.kind_of?(expected)
|
|
253
329
|
#
|
|
254
330
|
# @example
|
|
255
331
|
#
|
|
256
|
-
# 5.
|
|
257
|
-
# 5.
|
|
258
|
-
# 5.
|
|
332
|
+
# expect(5).to be_a_kind_of(Fixnum)
|
|
333
|
+
# expect(5).to be_a_kind_of(Numeric)
|
|
334
|
+
# expect(5).not_to be_a_kind_of(Float)
|
|
259
335
|
def be_a_kind_of(expected)
|
|
260
336
|
BuiltIn::BeAKindOf.new(expected)
|
|
261
337
|
end
|
|
338
|
+
alias_method :be_kind_of, :be_a_kind_of
|
|
339
|
+
alias_matcher :a_kind_of, :be_a_kind_of
|
|
262
340
|
|
|
263
|
-
|
|
341
|
+
# Passes if actual.between?(min, max). Works with any Comparable object,
|
|
342
|
+
# including String, Symbol, Time, or Numeric (Fixnum, Bignum, Integer,
|
|
343
|
+
# Float, Complex, and Rational).
|
|
344
|
+
#
|
|
345
|
+
# By default, `be_between` is inclusive (i.e. passes when given either the max or min value),
|
|
346
|
+
# but you can make it `exclusive` by chaining that off the matcher.
|
|
347
|
+
#
|
|
348
|
+
# @example
|
|
349
|
+
#
|
|
350
|
+
# expect(5).to be_between(1, 10)
|
|
351
|
+
# expect(11).not_to be_between(1, 10)
|
|
352
|
+
# expect(10).not_to be_between(1, 10).exclusive
|
|
353
|
+
def be_between(min, max)
|
|
354
|
+
BuiltIn::BeBetween.new(min, max)
|
|
355
|
+
end
|
|
356
|
+
alias_matcher :a_value_between, :be_between
|
|
264
357
|
|
|
265
358
|
# Passes if actual == expected +/- delta
|
|
266
359
|
#
|
|
267
360
|
# @example
|
|
268
361
|
#
|
|
269
|
-
# result.
|
|
270
|
-
# result.
|
|
362
|
+
# expect(result).to be_within(0.5).of(3.0)
|
|
363
|
+
# expect(result).not_to be_within(0.5).of(3.0)
|
|
271
364
|
def be_within(delta)
|
|
272
365
|
BuiltIn::BeWithin.new(delta)
|
|
273
366
|
end
|
|
367
|
+
alias_matcher :a_value_within, :be_within
|
|
368
|
+
alias_matcher :within, :be_within
|
|
274
369
|
|
|
275
370
|
# Applied to a proc, specifies that its execution will cause some value to
|
|
276
371
|
# change.
|
|
@@ -281,78 +376,118 @@ module RSpec
|
|
|
281
376
|
# You can either pass <tt>receiver</tt> and <tt>message</tt>, or a block,
|
|
282
377
|
# but not both.
|
|
283
378
|
#
|
|
284
|
-
# When passing a block, it must use the
|
|
285
|
-
# do/end, as
|
|
286
|
-
# would errantly bind to the
|
|
379
|
+
# When passing a block, it must use the `{ ... }` format, not
|
|
380
|
+
# do/end, as `{ ... }` binds to the `change` method, whereas do/end
|
|
381
|
+
# would errantly bind to the `expect(..).to` or `expect(...).not_to` method.
|
|
382
|
+
#
|
|
383
|
+
# You can chain any of the following off of the end to specify details
|
|
384
|
+
# about the change:
|
|
385
|
+
#
|
|
386
|
+
# * `by`
|
|
387
|
+
# * `by_at_least`
|
|
388
|
+
# * `by_at_most`
|
|
389
|
+
# * `from`
|
|
390
|
+
# * `to`
|
|
287
391
|
#
|
|
288
392
|
# @example
|
|
289
393
|
#
|
|
290
|
-
#
|
|
394
|
+
# expect {
|
|
291
395
|
# team.add_player(player)
|
|
292
|
-
# }.
|
|
396
|
+
# }.to change(roster, :count)
|
|
293
397
|
#
|
|
294
|
-
#
|
|
398
|
+
# expect {
|
|
295
399
|
# team.add_player(player)
|
|
296
|
-
# }.
|
|
400
|
+
# }.to change(roster, :count).by(1)
|
|
297
401
|
#
|
|
298
|
-
#
|
|
402
|
+
# expect {
|
|
299
403
|
# team.add_player(player)
|
|
300
|
-
# }.
|
|
404
|
+
# }.to change(roster, :count).by_at_least(1)
|
|
301
405
|
#
|
|
302
|
-
#
|
|
406
|
+
# expect {
|
|
303
407
|
# team.add_player(player)
|
|
304
|
-
# }.
|
|
408
|
+
# }.to change(roster, :count).by_at_most(1)
|
|
305
409
|
#
|
|
306
410
|
# string = "string"
|
|
307
|
-
#
|
|
411
|
+
# expect {
|
|
308
412
|
# string.reverse!
|
|
309
|
-
# }.
|
|
413
|
+
# }.to change { string }.from("string").to("gnirts")
|
|
310
414
|
#
|
|
311
|
-
#
|
|
415
|
+
# string = "string"
|
|
416
|
+
# expect {
|
|
417
|
+
# string
|
|
418
|
+
# }.not_to change { string }.from("string")
|
|
419
|
+
#
|
|
420
|
+
# expect {
|
|
312
421
|
# person.happy_birthday
|
|
313
|
-
# }.
|
|
422
|
+
# }.to change(person, :birthday).from(32).to(33)
|
|
314
423
|
#
|
|
315
|
-
#
|
|
424
|
+
# expect {
|
|
316
425
|
# employee.develop_great_new_social_networking_app
|
|
317
|
-
# }.
|
|
426
|
+
# }.to change(employee, :title).from("Mail Clerk").to("CEO")
|
|
318
427
|
#
|
|
319
|
-
#
|
|
428
|
+
# expect {
|
|
320
429
|
# doctor.leave_office
|
|
321
|
-
# }.
|
|
430
|
+
# }.to change(doctor, :sign).from(/is in/).to(/is out/)
|
|
322
431
|
#
|
|
323
432
|
# user = User.new(:type => "admin")
|
|
324
|
-
#
|
|
433
|
+
# expect {
|
|
325
434
|
# user.symbolize_type
|
|
326
|
-
# }.
|
|
435
|
+
# }.to change(user, :type).from(String).to(Symbol)
|
|
327
436
|
#
|
|
328
437
|
# == Notes
|
|
329
438
|
#
|
|
330
|
-
# Evaluates
|
|
331
|
-
# evaluates the
|
|
332
|
-
# above).
|
|
439
|
+
# Evaluates `receiver.message` or `block` before and after it
|
|
440
|
+
# evaluates the block passed to `expect`.
|
|
333
441
|
#
|
|
334
|
-
#
|
|
335
|
-
#
|
|
336
|
-
#
|
|
442
|
+
# `expect( ... ).not_to change` supports the form that specifies `from`
|
|
443
|
+
# (which specifies what you expect the starting, unchanged value to be)
|
|
444
|
+
# but does not support forms with subsequent calls to `by`, `by_at_least`,
|
|
445
|
+
# `by_at_most` or `to`.
|
|
337
446
|
def change(receiver=nil, message=nil, &block)
|
|
338
447
|
BuiltIn::Change.new(receiver, message, &block)
|
|
339
448
|
end
|
|
449
|
+
alias_matcher :a_block_changing, :change
|
|
450
|
+
alias_matcher :changing, :change
|
|
451
|
+
|
|
452
|
+
# Passes if actual contains all of the expected regardless of order.
|
|
453
|
+
# This works for collections. Pass in multiple args and it will only
|
|
454
|
+
# pass if all args are found in collection.
|
|
455
|
+
#
|
|
456
|
+
# @note This is also available using the `=~` operator with `should`,
|
|
457
|
+
# but `=~` is not supported with `expect`.
|
|
458
|
+
#
|
|
459
|
+
# @note This matcher only supports positive expectations.
|
|
460
|
+
# `expect(...).not_to contain_exactly(other_array)` is not supported.
|
|
461
|
+
#
|
|
462
|
+
# @example
|
|
463
|
+
#
|
|
464
|
+
# expect([1, 2, 3]).to contain_exactly(1, 2, 3)
|
|
465
|
+
# expect([1, 2, 3]).to contain_exactly(1, 3, 2)
|
|
466
|
+
#
|
|
467
|
+
# @see #match_array
|
|
468
|
+
def contain_exactly(*items)
|
|
469
|
+
BuiltIn::ContainExactly.new(items)
|
|
470
|
+
end
|
|
471
|
+
alias_matcher :a_collection_containing_exactly, :contain_exactly
|
|
472
|
+
alias_matcher :containing_exactly, :contain_exactly
|
|
340
473
|
|
|
341
474
|
# Passes if actual covers expected. This works for
|
|
342
475
|
# Ranges. You can also pass in multiple args
|
|
343
476
|
# and it will only pass if all args are found in Range.
|
|
344
477
|
#
|
|
345
478
|
# @example
|
|
346
|
-
# (1..10).
|
|
347
|
-
# (1..10).
|
|
348
|
-
# (1..10).
|
|
349
|
-
# (1..10).
|
|
350
|
-
# (1..10).
|
|
479
|
+
# expect(1..10).to cover(5)
|
|
480
|
+
# expect(1..10).to cover(4, 6)
|
|
481
|
+
# expect(1..10).to cover(4, 6, 11) # fails
|
|
482
|
+
# expect(1..10).not_to cover(11)
|
|
483
|
+
# expect(1..10).not_to cover(5) # fails
|
|
351
484
|
#
|
|
352
485
|
# ### Warning:: Ruby >= 1.9 only
|
|
353
486
|
def cover(*values)
|
|
354
487
|
BuiltIn::Cover.new(*values)
|
|
355
|
-
end
|
|
488
|
+
end
|
|
489
|
+
alias_matcher :a_range_covering, :cover
|
|
490
|
+
alias_matcher :covering, :cover
|
|
356
491
|
|
|
357
492
|
# Matches if the actual value ends with the expected value(s). In the case
|
|
358
493
|
# of a string, matches against the last `expected.length` characters of the
|
|
@@ -361,149 +496,193 @@ module RSpec
|
|
|
361
496
|
#
|
|
362
497
|
# @example
|
|
363
498
|
#
|
|
364
|
-
# "this string".
|
|
365
|
-
# [0, 1, 2, 3, 4].
|
|
366
|
-
# [0, 2, 3, 4, 4].
|
|
499
|
+
# expect("this string").to end_with "string"
|
|
500
|
+
# expect([0, 1, 2, 3, 4]).to end_with 4
|
|
501
|
+
# expect([0, 2, 3, 4, 4]).to end_with 3, 4
|
|
367
502
|
def end_with(*expected)
|
|
368
503
|
BuiltIn::EndWith.new(*expected)
|
|
369
504
|
end
|
|
505
|
+
alias_matcher :a_collection_ending_with, :end_with
|
|
506
|
+
alias_matcher :a_string_ending_with, :end_with
|
|
507
|
+
alias_matcher :ending_with, :end_with
|
|
370
508
|
|
|
371
509
|
# Passes if <tt>actual == expected</tt>.
|
|
372
510
|
#
|
|
373
|
-
# See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more
|
|
511
|
+
# See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more
|
|
512
|
+
# information about equality in Ruby.
|
|
374
513
|
#
|
|
375
514
|
# @example
|
|
376
515
|
#
|
|
377
|
-
# 5.
|
|
378
|
-
# 5.
|
|
516
|
+
# expect(5).to eq(5)
|
|
517
|
+
# expect(5).not_to eq(3)
|
|
379
518
|
def eq(expected)
|
|
380
519
|
BuiltIn::Eq.new(expected)
|
|
381
520
|
end
|
|
521
|
+
alias_matcher :an_object_eq_to, :eq
|
|
522
|
+
alias_matcher :eq_to, :eq
|
|
382
523
|
|
|
383
|
-
# Passes if
|
|
524
|
+
# Passes if `actual.eql?(expected)`
|
|
384
525
|
#
|
|
385
|
-
# See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more
|
|
526
|
+
# See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more
|
|
527
|
+
# information about equality in Ruby.
|
|
386
528
|
#
|
|
387
529
|
# @example
|
|
388
530
|
#
|
|
389
|
-
# 5.
|
|
390
|
-
# 5.
|
|
531
|
+
# expect(5).to eql(5)
|
|
532
|
+
# expect(5).not_to eql(3)
|
|
391
533
|
def eql(expected)
|
|
392
534
|
BuiltIn::Eql.new(expected)
|
|
393
535
|
end
|
|
536
|
+
alias_matcher :an_object_eql_to, :eql
|
|
537
|
+
alias_matcher :eql_to, :eql
|
|
394
538
|
|
|
395
539
|
# Passes if <tt>actual.equal?(expected)</tt> (object identity).
|
|
396
540
|
#
|
|
397
|
-
# See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more
|
|
541
|
+
# See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more
|
|
542
|
+
# information about equality in Ruby.
|
|
398
543
|
#
|
|
399
544
|
# @example
|
|
400
545
|
#
|
|
401
|
-
# 5.
|
|
402
|
-
# "5".
|
|
546
|
+
# expect(5).to equal(5) # Fixnums are equal
|
|
547
|
+
# expect("5").not_to equal("5") # Strings that look the same are not the same object
|
|
403
548
|
def equal(expected)
|
|
404
549
|
BuiltIn::Equal.new(expected)
|
|
405
550
|
end
|
|
551
|
+
alias_matcher :an_object_equal_to, :equal
|
|
552
|
+
alias_matcher :equal_to, :equal
|
|
406
553
|
|
|
407
554
|
# Passes if `actual.exist?` or `actual.exists?`
|
|
408
555
|
#
|
|
409
556
|
# @example
|
|
410
|
-
# File.
|
|
557
|
+
# expect(File).to exist("path/to/file")
|
|
411
558
|
def exist(*args)
|
|
412
559
|
BuiltIn::Exist.new(*args)
|
|
413
560
|
end
|
|
561
|
+
alias_matcher :an_object_existing, :exist
|
|
562
|
+
alias_matcher :existing, :exist
|
|
414
563
|
|
|
415
|
-
# Passes if
|
|
416
|
-
#
|
|
417
|
-
#
|
|
418
|
-
# If the receiver OWNS the collection, you must use the name of the
|
|
419
|
-
# collection. So if a `Team` instance has a collection named `#players`,
|
|
420
|
-
# you must use that name to set the expectation.
|
|
564
|
+
# Passes if actual includes expected. This works for
|
|
565
|
+
# collections and Strings. You can also pass in multiple args
|
|
566
|
+
# and it will only pass if all args are found in collection.
|
|
421
567
|
#
|
|
422
|
-
#
|
|
423
|
-
# `named_collection`. We'd recommend using either "elements", "members", or
|
|
424
|
-
# "items" as these are all standard ways of describing the things IN a
|
|
425
|
-
# collection.
|
|
568
|
+
# @example
|
|
426
569
|
#
|
|
427
|
-
#
|
|
428
|
-
#
|
|
570
|
+
# expect([1,2,3]).to include(3)
|
|
571
|
+
# expect([1,2,3]).to include(2,3)
|
|
572
|
+
# expect([1,2,3]).to include(2,3,4) # fails
|
|
573
|
+
# expect([1,2,3]).not_to include(4)
|
|
574
|
+
# expect("spread").to include("read")
|
|
575
|
+
# expect("spread").not_to include("red")
|
|
576
|
+
def include(*expected)
|
|
577
|
+
BuiltIn::Include.new(*expected)
|
|
578
|
+
end
|
|
579
|
+
alias_matcher :a_collection_including, :include
|
|
580
|
+
alias_matcher :a_string_including, :include
|
|
581
|
+
alias_matcher :a_hash_including, :include
|
|
582
|
+
alias_matcher :including, :include
|
|
583
|
+
|
|
584
|
+
# Passes if actual all expected objects pass. This works for
|
|
585
|
+
# any enumerable object.
|
|
429
586
|
#
|
|
430
587
|
# @example
|
|
431
588
|
#
|
|
432
|
-
#
|
|
433
|
-
#
|
|
589
|
+
# expect([1, 3, 5]).to all be_odd
|
|
590
|
+
# expect([1, 3, 6]).to all be_odd # fails
|
|
434
591
|
#
|
|
435
|
-
#
|
|
436
|
-
#
|
|
592
|
+
# @note The negative form `not_to all` is not supported. Instead
|
|
593
|
+
# use `not_to include` or pass a negative form of a matcher
|
|
594
|
+
# as the argument (e.g. `all exclude(:foo)`).
|
|
437
595
|
#
|
|
438
|
-
#
|
|
439
|
-
# [1,2,3].should have(3).items #"items" is pure sugar
|
|
596
|
+
# @note You can also use this with compound matchers as well.
|
|
440
597
|
#
|
|
441
|
-
#
|
|
442
|
-
#
|
|
443
|
-
def
|
|
444
|
-
BuiltIn::
|
|
598
|
+
# @example
|
|
599
|
+
# expect([1, 3, 5]).to all( be_odd.and be_an(Integer) )
|
|
600
|
+
def all(expected)
|
|
601
|
+
BuiltIn::All.new(expected)
|
|
445
602
|
end
|
|
446
|
-
alias :have_exactly :have
|
|
447
603
|
|
|
448
|
-
#
|
|
604
|
+
# Given a `Regexp` or `String`, passes if `actual.match(pattern)`
|
|
605
|
+
# Given an arbitrary nested data structure (e.g. arrays and hashes),
|
|
606
|
+
# matches if `expected === actual` || `actual == expected` for each
|
|
607
|
+
# pair of elements.
|
|
449
608
|
#
|
|
450
609
|
# @example
|
|
451
|
-
# "this".should have_at_least(3).letters
|
|
452
|
-
#
|
|
453
|
-
# ### Warning:
|
|
454
610
|
#
|
|
455
|
-
#
|
|
456
|
-
|
|
457
|
-
BuiltIn::Have.new(n, :at_least)
|
|
458
|
-
end
|
|
459
|
-
|
|
460
|
-
# Exactly like have() with <=.
|
|
611
|
+
# expect(email).to match(/^([^\s]+)((?:[-a-z0-9]+\.)+[a-z]{2,})$/i)
|
|
612
|
+
# expect(email).to match("@example.com")
|
|
461
613
|
#
|
|
462
614
|
# @example
|
|
463
|
-
# should have_at_most(number).items
|
|
464
615
|
#
|
|
465
|
-
#
|
|
616
|
+
# hash = {
|
|
617
|
+
# :a => {
|
|
618
|
+
# :b => ["foo", 5],
|
|
619
|
+
# :c => { :d => 2.05 }
|
|
620
|
+
# }
|
|
621
|
+
# }
|
|
466
622
|
#
|
|
467
|
-
#
|
|
468
|
-
|
|
469
|
-
|
|
623
|
+
# expect(hash).to match(
|
|
624
|
+
# :a => {
|
|
625
|
+
# :b => a_collection_containing_exactly(
|
|
626
|
+
# a_string_starting_with("f"),
|
|
627
|
+
# an_instance_of(Fixnum)
|
|
628
|
+
# ),
|
|
629
|
+
# :c => { :d => (a_value < 3) }
|
|
630
|
+
# }
|
|
631
|
+
# )
|
|
632
|
+
#
|
|
633
|
+
# @note The `match_regex` alias is deprecated and is not recommended for use.
|
|
634
|
+
# It was added in 2.12.1 to facilitate its use from within custom
|
|
635
|
+
# matchers (due to how the custom matcher DSL was evaluated in 2.x,
|
|
636
|
+
# `match` could not be used there), but is no longer needed in 3.x.
|
|
637
|
+
def match(expected)
|
|
638
|
+
BuiltIn::Match.new(expected)
|
|
470
639
|
end
|
|
640
|
+
alias_matcher :match_regex, :match
|
|
641
|
+
alias_matcher :an_object_matching, :match
|
|
642
|
+
alias_matcher :a_string_matching, :match
|
|
643
|
+
alias_matcher :matching, :match
|
|
471
644
|
|
|
472
|
-
#
|
|
473
|
-
#
|
|
474
|
-
#
|
|
645
|
+
# An alternate form of `contain_exactly` that accepts
|
|
646
|
+
# the expected contents as a single array arg rather
|
|
647
|
+
# that splatted out as individual items.
|
|
475
648
|
#
|
|
476
649
|
# @example
|
|
477
650
|
#
|
|
478
|
-
#
|
|
479
|
-
#
|
|
480
|
-
# [1,2
|
|
481
|
-
#
|
|
482
|
-
#
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
BuiltIn::Include.new(*expected)
|
|
651
|
+
# expect(results).to contain_exactly(1, 2)
|
|
652
|
+
# # is identical to:
|
|
653
|
+
# expect(results).to match_array([1, 2])
|
|
654
|
+
#
|
|
655
|
+
# @see #contain_exactly
|
|
656
|
+
def match_array(items)
|
|
657
|
+
contain_exactly(*items)
|
|
486
658
|
end
|
|
487
659
|
|
|
488
|
-
#
|
|
660
|
+
# With no arg, passes if the block outputs `to_stdout` or `to_stderr`.
|
|
661
|
+
# With a string, passes if the blocks outputs that specific string `to_stdout` or `to_stderr`.
|
|
662
|
+
# With a regexp or matcher, passes if the blocks outputs a string `to_stdout` or `to_stderr` that matches.
|
|
489
663
|
#
|
|
490
664
|
# @example
|
|
491
665
|
#
|
|
492
|
-
#
|
|
493
|
-
#
|
|
494
|
-
#
|
|
495
|
-
# zipcode.should match_regex("90210")
|
|
666
|
+
# expect { print 'foo' }.to output.to_stdout
|
|
667
|
+
# expect { print 'foo' }.to output('foo').to_stdout
|
|
668
|
+
# expect { print 'foo' }.to output(/foo/).to_stdout
|
|
496
669
|
#
|
|
497
|
-
#
|
|
498
|
-
#
|
|
499
|
-
# (
|
|
500
|
-
#
|
|
501
|
-
#
|
|
502
|
-
|
|
503
|
-
|
|
670
|
+
# expect { do_something }.to_not output.to_stdout
|
|
671
|
+
#
|
|
672
|
+
# expect { warn('foo') }.to output.to_stderr
|
|
673
|
+
# expect { warn('foo') }.to output('foo').to_stderr
|
|
674
|
+
# expect { warn('foo') }.to output(/foo/).to_stderr
|
|
675
|
+
#
|
|
676
|
+
# expect { do_something }.to_not output.to_stderr
|
|
677
|
+
#
|
|
678
|
+
# @note This matcher works by temporarily replacing `$stdout` or `$stderr`,
|
|
679
|
+
# so it's not able to intercept stream output that explicitly uses `STDOUT`/`STDERR`
|
|
680
|
+
# or that uses a reference to `$stdout`/`$stderr` that was stored before the
|
|
681
|
+
# matcher is used.
|
|
682
|
+
def output(expected=nil)
|
|
683
|
+
BuiltIn::Output.new(expected)
|
|
504
684
|
end
|
|
505
|
-
|
|
506
|
-
alias_method :match_regex, :match
|
|
685
|
+
alias_matcher :a_block_outputting, :output
|
|
507
686
|
|
|
508
687
|
# With no args, matches if any error is raised.
|
|
509
688
|
# With a named error, matches only if that specific error is raised.
|
|
@@ -513,30 +692,38 @@ module RSpec
|
|
|
513
692
|
#
|
|
514
693
|
# @example
|
|
515
694
|
#
|
|
516
|
-
#
|
|
517
|
-
#
|
|
518
|
-
#
|
|
519
|
-
#
|
|
520
|
-
#
|
|
695
|
+
# expect { do_something_risky }.to raise_error
|
|
696
|
+
# expect { do_something_risky }.to raise_error(PoorRiskDecisionError)
|
|
697
|
+
# expect { do_something_risky }.to raise_error(PoorRiskDecisionError) { |error| expect(error.data).to eq 42 }
|
|
698
|
+
# expect { do_something_risky }.to raise_error(PoorRiskDecisionError, "that was too risky")
|
|
699
|
+
# expect { do_something_risky }.to raise_error(PoorRiskDecisionError, /oo ri/)
|
|
521
700
|
#
|
|
522
|
-
#
|
|
523
|
-
# lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError)
|
|
524
|
-
# lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError, "that was too risky")
|
|
525
|
-
# lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError, /oo ri/)
|
|
701
|
+
# expect { do_something_risky }.not_to raise_error
|
|
526
702
|
def raise_error(error=Exception, message=nil, &block)
|
|
527
703
|
BuiltIn::RaiseError.new(error, message, &block)
|
|
528
704
|
end
|
|
705
|
+
alias_method :raise_exception, :raise_error
|
|
706
|
+
|
|
707
|
+
alias_matcher :a_block_raising, :raise_error do |desc|
|
|
708
|
+
desc.sub("raise", "a block raising")
|
|
709
|
+
end
|
|
529
710
|
|
|
530
|
-
|
|
711
|
+
alias_matcher :raising, :raise_error do |desc|
|
|
712
|
+
desc.sub("raise", "raising")
|
|
713
|
+
end
|
|
531
714
|
|
|
532
715
|
# Matches if the target object responds to all of the names
|
|
533
716
|
# provided. Names can be Strings or Symbols.
|
|
534
717
|
#
|
|
535
718
|
# @example
|
|
536
719
|
#
|
|
720
|
+
# expect("string").to respond_to(:length)
|
|
721
|
+
#
|
|
537
722
|
def respond_to(*names)
|
|
538
723
|
BuiltIn::RespondTo.new(*names)
|
|
539
724
|
end
|
|
725
|
+
alias_matcher :an_object_responding_to, :respond_to
|
|
726
|
+
alias_matcher :responding_to, :respond_to
|
|
540
727
|
|
|
541
728
|
# Passes if the submitted block returns true. Yields target to the
|
|
542
729
|
# block.
|
|
@@ -550,12 +737,12 @@ module RSpec
|
|
|
550
737
|
#
|
|
551
738
|
# @example
|
|
552
739
|
#
|
|
553
|
-
# 5.
|
|
554
|
-
# n > 3
|
|
555
|
-
# }
|
|
740
|
+
# expect(5).to satisfy { |n| n > 3 }
|
|
556
741
|
def satisfy(&block)
|
|
557
742
|
BuiltIn::Satisfy.new(&block)
|
|
558
743
|
end
|
|
744
|
+
alias_matcher :an_object_satisfying, :satisfy
|
|
745
|
+
alias_matcher :satisfying, :satisfy
|
|
559
746
|
|
|
560
747
|
# Matches if the actual value starts with the expected value(s). In the
|
|
561
748
|
# case of a string, matches against the first `expected.length` characters
|
|
@@ -564,12 +751,15 @@ module RSpec
|
|
|
564
751
|
#
|
|
565
752
|
# @example
|
|
566
753
|
#
|
|
567
|
-
# "this string".
|
|
568
|
-
# [0, 1, 2, 3, 4].
|
|
569
|
-
# [0, 2, 3, 4, 4].
|
|
754
|
+
# expect("this string").to start_with "this s"
|
|
755
|
+
# expect([0, 1, 2, 3, 4]).to start_with 0
|
|
756
|
+
# expect([0, 2, 3, 4, 4]).to start_with 0, 1
|
|
570
757
|
def start_with(*expected)
|
|
571
758
|
BuiltIn::StartWith.new(*expected)
|
|
572
759
|
end
|
|
760
|
+
alias_matcher :a_collection_starting_with, :start_with
|
|
761
|
+
alias_matcher :a_string_starting_with, :start_with
|
|
762
|
+
alias_matcher :starting_with, :start_with
|
|
573
763
|
|
|
574
764
|
# Given no argument, matches if a proc throws any Symbol.
|
|
575
765
|
#
|
|
@@ -580,17 +770,25 @@ module RSpec
|
|
|
580
770
|
#
|
|
581
771
|
# @example
|
|
582
772
|
#
|
|
583
|
-
#
|
|
584
|
-
#
|
|
585
|
-
#
|
|
773
|
+
# expect { do_something_risky }.to throw_symbol
|
|
774
|
+
# expect { do_something_risky }.to throw_symbol(:that_was_risky)
|
|
775
|
+
# expect { do_something_risky }.to throw_symbol(:that_was_risky, 'culprit')
|
|
586
776
|
#
|
|
587
|
-
#
|
|
588
|
-
#
|
|
589
|
-
#
|
|
777
|
+
# expect { do_something_risky }.not_to throw_symbol
|
|
778
|
+
# expect { do_something_risky }.not_to throw_symbol(:that_was_risky)
|
|
779
|
+
# expect { do_something_risky }.not_to throw_symbol(:that_was_risky, 'culprit')
|
|
590
780
|
def throw_symbol(expected_symbol=nil, expected_arg=nil)
|
|
591
781
|
BuiltIn::ThrowSymbol.new(expected_symbol, expected_arg)
|
|
592
782
|
end
|
|
593
783
|
|
|
784
|
+
alias_matcher :a_block_throwing, :throw_symbol do |desc|
|
|
785
|
+
desc.sub("throw", "a block throwing")
|
|
786
|
+
end
|
|
787
|
+
|
|
788
|
+
alias_matcher :throwing, :throw_symbol do |desc|
|
|
789
|
+
desc.sub("throw", "throwing")
|
|
790
|
+
end
|
|
791
|
+
|
|
594
792
|
# Passes if the method called in the expect block yields, regardless
|
|
595
793
|
# of whether or not arguments are yielded.
|
|
596
794
|
#
|
|
@@ -606,6 +804,8 @@ module RSpec
|
|
|
606
804
|
def yield_control
|
|
607
805
|
BuiltIn::YieldControl.new
|
|
608
806
|
end
|
|
807
|
+
alias_matcher :a_block_yielding_control, :yield_control
|
|
808
|
+
alias_matcher :yielding_control, :yield_control
|
|
609
809
|
|
|
610
810
|
# Passes if the method called in the expect block yields with
|
|
611
811
|
# no arguments. Fails if it does not yield, or yields with arguments.
|
|
@@ -623,6 +823,8 @@ module RSpec
|
|
|
623
823
|
def yield_with_no_args
|
|
624
824
|
BuiltIn::YieldWithNoArgs.new
|
|
625
825
|
end
|
|
826
|
+
alias_matcher :a_block_yielding_with_no_args, :yield_with_no_args
|
|
827
|
+
alias_matcher :yielding_with_no_args, :yield_with_no_args
|
|
626
828
|
|
|
627
829
|
# Given no arguments, matches if the method called in the expect
|
|
628
830
|
# block yields with arguments (regardless of what they are or how
|
|
@@ -652,6 +854,8 @@ module RSpec
|
|
|
652
854
|
def yield_with_args(*args)
|
|
653
855
|
BuiltIn::YieldWithArgs.new(*args)
|
|
654
856
|
end
|
|
857
|
+
alias_matcher :a_block_yielding_with_args, :yield_with_args
|
|
858
|
+
alias_matcher :yielding_with_args, :yield_with_args
|
|
655
859
|
|
|
656
860
|
# Designed for use with methods that repeatedly yield (such as
|
|
657
861
|
# iterators). Passes if the method called in the expect block yields
|
|
@@ -672,28 +876,47 @@ module RSpec
|
|
|
672
876
|
def yield_successive_args(*args)
|
|
673
877
|
BuiltIn::YieldSuccessiveArgs.new(*args)
|
|
674
878
|
end
|
|
879
|
+
alias_matcher :a_block_yielding_successive_args, :yield_successive_args
|
|
880
|
+
alias_matcher :yielding_successive_args, :yield_successive_args
|
|
881
|
+
|
|
882
|
+
# Delegates to {RSpec::Expectations.configuration}.
|
|
883
|
+
# This is here because rspec-core's `expect_with` option
|
|
884
|
+
# looks for a `configuration` method on the mixin
|
|
885
|
+
# (`RSpec::Matchers`) to yield to a block.
|
|
886
|
+
# @return [RSpec::Expectations::Configuration] the configuration object
|
|
887
|
+
def self.configuration
|
|
888
|
+
Expectations.configuration
|
|
889
|
+
end
|
|
675
890
|
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
#
|
|
693
|
-
def
|
|
694
|
-
BuiltIn::
|
|
891
|
+
private
|
|
892
|
+
|
|
893
|
+
BE_PREDICATE_REGEX = /^(be_(?:an?_)?)(.*)/
|
|
894
|
+
HAS_REGEX = /^(?:have_)(.*)/
|
|
895
|
+
|
|
896
|
+
def method_missing(method, *args, &block)
|
|
897
|
+
case method.to_s
|
|
898
|
+
when BE_PREDICATE_REGEX
|
|
899
|
+
BuiltIn::BePredicate.new(method, *args, &block)
|
|
900
|
+
when HAS_REGEX
|
|
901
|
+
BuiltIn::Has.new(method, *args, &block)
|
|
902
|
+
else
|
|
903
|
+
super
|
|
904
|
+
end
|
|
905
|
+
end
|
|
906
|
+
|
|
907
|
+
# @api private
|
|
908
|
+
def self.is_a_matcher?(obj)
|
|
909
|
+
return true if ::RSpec::Matchers::BuiltIn::BaseMatcher === obj
|
|
910
|
+
return false if obj.respond_to?(:i_respond_to_everything_so_im_not_really_a_matcher)
|
|
911
|
+
return false unless obj.respond_to?(:matches?)
|
|
912
|
+
|
|
913
|
+
obj.respond_to?(:failure_message) ||
|
|
914
|
+
obj.respond_to?(:failure_message_for_should) # support legacy matchers
|
|
695
915
|
end
|
|
696
916
|
|
|
697
|
-
|
|
917
|
+
# @api private
|
|
918
|
+
def self.is_a_describable_matcher?(obj)
|
|
919
|
+
is_a_matcher?(obj) && obj.respond_to?(:description)
|
|
920
|
+
end
|
|
698
921
|
end
|
|
699
922
|
end
|