rspec-expectations 2.11.3 → 3.11.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.
Files changed (152) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/.document +1 -1
  4. data/.yardopts +1 -1
  5. data/Changelog.md +1026 -21
  6. data/{License.txt → LICENSE.md} +5 -3
  7. data/README.md +174 -78
  8. data/lib/rspec/expectations/block_snippet_extractor.rb +253 -0
  9. data/lib/rspec/expectations/configuration.rb +230 -0
  10. data/lib/rspec/expectations/expectation_target.rb +130 -55
  11. data/lib/rspec/expectations/fail_with.rb +17 -33
  12. data/lib/rspec/expectations/failure_aggregator.rb +212 -0
  13. data/lib/rspec/expectations/handler.rb +163 -29
  14. data/lib/rspec/expectations/minitest_integration.rb +58 -0
  15. data/lib/rspec/expectations/syntax.rb +68 -54
  16. data/lib/rspec/expectations/version.rb +1 -1
  17. data/lib/rspec/expectations.rb +59 -24
  18. data/lib/rspec/matchers/aliased_matcher.rb +116 -0
  19. data/lib/rspec/matchers/built_in/all.rb +86 -0
  20. data/lib/rspec/matchers/built_in/base_matcher.rb +150 -20
  21. data/lib/rspec/matchers/built_in/be.rb +115 -109
  22. data/lib/rspec/matchers/built_in/be_between.rb +77 -0
  23. data/lib/rspec/matchers/built_in/be_instance_of.rb +16 -1
  24. data/lib/rspec/matchers/built_in/be_kind_of.rb +10 -1
  25. data/lib/rspec/matchers/built_in/be_within.rb +43 -17
  26. data/lib/rspec/matchers/built_in/change.rb +392 -75
  27. data/lib/rspec/matchers/built_in/compound.rb +290 -0
  28. data/lib/rspec/matchers/built_in/contain_exactly.rb +302 -0
  29. data/lib/rspec/matchers/built_in/count_expectation.rb +169 -0
  30. data/lib/rspec/matchers/built_in/cover.rb +3 -0
  31. data/lib/rspec/matchers/built_in/eq.rb +26 -8
  32. data/lib/rspec/matchers/built_in/eql.rb +19 -8
  33. data/lib/rspec/matchers/built_in/equal.rb +56 -19
  34. data/lib/rspec/matchers/built_in/exist.rb +74 -10
  35. data/lib/rspec/matchers/built_in/has.rb +141 -22
  36. data/lib/rspec/matchers/built_in/have_attributes.rb +114 -0
  37. data/lib/rspec/matchers/built_in/include.rb +175 -20
  38. data/lib/rspec/matchers/built_in/match.rb +95 -1
  39. data/lib/rspec/matchers/built_in/operators.rb +128 -0
  40. data/lib/rspec/matchers/built_in/output.rb +207 -0
  41. data/lib/rspec/matchers/built_in/raise_error.rb +212 -38
  42. data/lib/rspec/matchers/built_in/respond_to.rb +155 -29
  43. data/lib/rspec/matchers/built_in/satisfy.rb +39 -9
  44. data/lib/rspec/matchers/built_in/start_or_end_with.rb +94 -0
  45. data/lib/rspec/matchers/built_in/throw_symbol.rb +58 -14
  46. data/lib/rspec/matchers/built_in/yield.rb +252 -98
  47. data/lib/rspec/matchers/built_in.rb +47 -33
  48. data/lib/rspec/matchers/composable.rb +171 -0
  49. data/lib/rspec/matchers/dsl.rb +530 -10
  50. data/lib/rspec/matchers/english_phrasing.rb +58 -0
  51. data/lib/rspec/matchers/expecteds_for_multiple_diffs.rb +82 -0
  52. data/lib/rspec/matchers/fail_matchers.rb +42 -0
  53. data/lib/rspec/matchers/generated_descriptions.rb +15 -10
  54. data/lib/rspec/matchers/matcher_delegator.rb +35 -0
  55. data/lib/rspec/matchers/matcher_protocol.rb +105 -0
  56. data/lib/rspec/matchers.rb +604 -252
  57. data.tar.gz.sig +0 -0
  58. metadata +178 -278
  59. metadata.gz.sig +0 -0
  60. data/features/README.md +0 -49
  61. data/features/Upgrade.md +0 -53
  62. data/features/built_in_matchers/README.md +0 -90
  63. data/features/built_in_matchers/be.feature +0 -173
  64. data/features/built_in_matchers/be_within.feature +0 -46
  65. data/features/built_in_matchers/cover.feature +0 -45
  66. data/features/built_in_matchers/end_with.feature +0 -46
  67. data/features/built_in_matchers/equality.feature +0 -145
  68. data/features/built_in_matchers/exist.feature +0 -43
  69. data/features/built_in_matchers/expect_change.feature +0 -59
  70. data/features/built_in_matchers/expect_error.feature +0 -138
  71. data/features/built_in_matchers/have.feature +0 -103
  72. data/features/built_in_matchers/include.feature +0 -121
  73. data/features/built_in_matchers/match.feature +0 -50
  74. data/features/built_in_matchers/operators.feature +0 -221
  75. data/features/built_in_matchers/predicates.feature +0 -128
  76. data/features/built_in_matchers/respond_to.feature +0 -78
  77. data/features/built_in_matchers/satisfy.feature +0 -31
  78. data/features/built_in_matchers/start_with.feature +0 -46
  79. data/features/built_in_matchers/throw_symbol.feature +0 -85
  80. data/features/built_in_matchers/types.feature +0 -114
  81. data/features/built_in_matchers/yield.feature +0 -146
  82. data/features/custom_matchers/access_running_example.feature +0 -53
  83. data/features/custom_matchers/define_diffable_matcher.feature +0 -27
  84. data/features/custom_matchers/define_matcher.feature +0 -340
  85. data/features/custom_matchers/define_matcher_outside_rspec.feature +0 -38
  86. data/features/custom_matchers/define_matcher_with_fluent_interface.feature +0 -24
  87. data/features/customized_message.feature +0 -22
  88. data/features/diffing.feature +0 -85
  89. data/features/implicit_docstrings.feature +0 -52
  90. data/features/step_definitions/additional_cli_steps.rb +0 -22
  91. data/features/support/env.rb +0 -5
  92. data/features/syntax_configuration.feature +0 -68
  93. data/features/test_frameworks/test_unit.feature +0 -46
  94. data/lib/rspec/expectations/deprecation.rb +0 -38
  95. data/lib/rspec/expectations/differ.rb +0 -81
  96. data/lib/rspec/expectations/errors.rb +0 -9
  97. data/lib/rspec/expectations/extensions/array.rb +0 -9
  98. data/lib/rspec/expectations/extensions/object.rb +0 -39
  99. data/lib/rspec/expectations/extensions.rb +0 -2
  100. data/lib/rspec/matchers/be_close.rb +0 -9
  101. data/lib/rspec/matchers/built_in/have.rb +0 -108
  102. data/lib/rspec/matchers/built_in/match_array.rb +0 -45
  103. data/lib/rspec/matchers/built_in/start_and_end_with.rb +0 -48
  104. data/lib/rspec/matchers/compatibility.rb +0 -14
  105. data/lib/rspec/matchers/configuration.rb +0 -66
  106. data/lib/rspec/matchers/extensions/instance_eval_with_args.rb +0 -39
  107. data/lib/rspec/matchers/matcher.rb +0 -299
  108. data/lib/rspec/matchers/method_missing.rb +0 -12
  109. data/lib/rspec/matchers/operator_matcher.rb +0 -84
  110. data/lib/rspec/matchers/pretty.rb +0 -60
  111. data/lib/rspec-expectations.rb +0 -1
  112. data/spec/rspec/expectations/differ_spec.rb +0 -153
  113. data/spec/rspec/expectations/expectation_target_spec.rb +0 -65
  114. data/spec/rspec/expectations/extensions/kernel_spec.rb +0 -67
  115. data/spec/rspec/expectations/fail_with_spec.rb +0 -70
  116. data/spec/rspec/expectations/handler_spec.rb +0 -206
  117. data/spec/rspec/matchers/base_matcher_spec.rb +0 -60
  118. data/spec/rspec/matchers/be_close_spec.rb +0 -22
  119. data/spec/rspec/matchers/be_instance_of_spec.rb +0 -40
  120. data/spec/rspec/matchers/be_kind_of_spec.rb +0 -37
  121. data/spec/rspec/matchers/be_spec.rb +0 -452
  122. data/spec/rspec/matchers/be_within_spec.rb +0 -80
  123. data/spec/rspec/matchers/change_spec.rb +0 -528
  124. data/spec/rspec/matchers/configuration_spec.rb +0 -202
  125. data/spec/rspec/matchers/cover_spec.rb +0 -69
  126. data/spec/rspec/matchers/description_generation_spec.rb +0 -176
  127. data/spec/rspec/matchers/dsl_spec.rb +0 -57
  128. data/spec/rspec/matchers/eq_spec.rb +0 -54
  129. data/spec/rspec/matchers/eql_spec.rb +0 -41
  130. data/spec/rspec/matchers/equal_spec.rb +0 -60
  131. data/spec/rspec/matchers/exist_spec.rb +0 -110
  132. data/spec/rspec/matchers/has_spec.rb +0 -118
  133. data/spec/rspec/matchers/have_spec.rb +0 -461
  134. data/spec/rspec/matchers/include_spec.rb +0 -367
  135. data/spec/rspec/matchers/match_array_spec.rb +0 -124
  136. data/spec/rspec/matchers/match_spec.rb +0 -61
  137. data/spec/rspec/matchers/matcher_spec.rb +0 -434
  138. data/spec/rspec/matchers/matchers_spec.rb +0 -31
  139. data/spec/rspec/matchers/method_missing_spec.rb +0 -24
  140. data/spec/rspec/matchers/operator_matcher_spec.rb +0 -221
  141. data/spec/rspec/matchers/raise_error_spec.rb +0 -344
  142. data/spec/rspec/matchers/respond_to_spec.rb +0 -295
  143. data/spec/rspec/matchers/satisfy_spec.rb +0 -44
  144. data/spec/rspec/matchers/start_with_end_with_spec.rb +0 -182
  145. data/spec/rspec/matchers/throw_symbol_spec.rb +0 -116
  146. data/spec/rspec/matchers/yield_spec.rb +0 -402
  147. data/spec/spec_helper.rb +0 -27
  148. data/spec/support/classes.rb +0 -56
  149. data/spec/support/in_sub_process.rb +0 -31
  150. data/spec/support/matchers.rb +0 -22
  151. data/spec/support/ruby_version.rb +0 -10
  152. data/spec/support/shared_examples.rb +0 -13
@@ -1,15 +1,24 @@
1
+ require 'rspec/support'
2
+ RSpec::Support.require_rspec_support 'matcher_definition'
3
+ RSpec::Support.define_optimized_require_for_rspec(:matchers) { |f| require_relative(f) }
4
+
5
+ %w[
6
+ english_phrasing
7
+ composable
8
+ built_in
9
+ generated_descriptions
10
+ dsl
11
+ matcher_delegator
12
+ aliased_matcher
13
+ expecteds_for_multiple_diffs
14
+ ].each { |file| RSpec::Support.require_rspec_matchers(file) }
15
+
16
+ # RSpec's top level namespace. All of rspec-expectations is contained
17
+ # in the `RSpec::Expectations` and `RSpec::Matchers` namespaces.
1
18
  module RSpec
2
- # RSpec::Matchers provides a number of useful matchers we use to compose
3
- # expectations. A matcher is any object that responds to the following:
4
- #
5
- # matches?(actual)
6
- # failure_message_for_should
7
- #
8
- # These methods are also part of the matcher protocol, but are optional:
9
- #
10
- # does_not_match?(actual)
11
- # failure_message_for_should_not
12
- # description
19
+ # RSpec::Matchers provides a number of useful matchers we use to define
20
+ # expectations. Any object that implements the [matcher protocol](Matchers/MatcherProtocol)
21
+ # can be used as a matcher.
13
22
  #
14
23
  # ## Predicates
15
24
  #
@@ -20,32 +29,59 @@ module RSpec
20
29
  # A Ruby predicate is a method that ends with a "?" and returns true or false.
21
30
  # Common examples are `empty?`, `nil?`, and `instance_of?`.
22
31
  #
23
- # All you need to do is write `should be_` followed by the predicate without
24
- # the question mark, and RSpec will figure it out from there. For example:
32
+ # All you need to do is write `expect(..).to be_` followed by the predicate
33
+ # without the question mark, and RSpec will figure it out from there.
34
+ # For example:
25
35
  #
26
- # [].should be_empty # => [].empty?() | passes
27
- # [].should_not be_empty # => [].empty?() | fails
36
+ # expect([]).to be_empty # => [].empty?() | passes
37
+ # expect([]).not_to be_empty # => [].empty?() | fails
28
38
  #
29
39
  # In addtion to prefixing the predicate matchers with "be_", you can also use "be_a_"
30
40
  # and "be_an_", making your specs read much more naturally:
31
41
  #
32
- # "a string".should be_an_instance_of(String) =>"a string".instance_of?(String) #passes
42
+ # expect("a string").to be_an_instance_of(String) # =>"a string".instance_of?(String) # passes
33
43
  #
34
- # 3.should be_a_kind_of(Fixnum) # => 3.kind_of?(Numeric) | passes
35
- # 3.should be_a_kind_of(Numeric) # => 3.kind_of?(Numeric) | passes
36
- # 3.should be_an_instance_of(Fixnum) # => 3.instance_of?(Fixnum) | passes
37
- # 3.should_not be_instance_of(Numeric) # => 3.instance_of?(Numeric) | fails
44
+ # expect(3).to be_a_kind_of(Integer) # => 3.kind_of?(Numeric) | passes
45
+ # expect(3).to be_a_kind_of(Numeric) # => 3.kind_of?(Numeric) | passes
46
+ # expect(3).to be_an_instance_of(Integer) # => 3.instance_of?(Integer) | passes
47
+ # expect(3).not_to be_an_instance_of(Numeric) # => 3.instance_of?(Numeric) | fails
38
48
  #
39
49
  # RSpec will also create custom matchers for predicates like `has_key?`. To
40
50
  # use this feature, just state that the object should have_key(:key) and RSpec will
41
51
  # call has_key?(:key) on the target. For example:
42
52
  #
43
- # {:a => "A"}.should have_key(:a) # => {:a => "A"}.has_key?(:a) | passes
44
- # {:a => "A"}.should have_key(:b) # => {:a => "A"}.has_key?(:b) | fails
53
+ # expect(:a => "A").to have_key(:a)
54
+ # expect(:a => "A").to have_key(:b) # fails
45
55
  #
46
56
  # You can use this feature to invoke any predicate that begins with "has_", whether it is
47
57
  # part of the Ruby libraries (like `Hash#has_key?`) or a method you wrote on your own class.
48
58
  #
59
+ # Note that RSpec does not provide composable aliases for these dynamic predicate
60
+ # matchers. You can easily define your own aliases, though:
61
+ #
62
+ # RSpec::Matchers.alias_matcher :a_user_who_is_an_admin, :be_an_admin
63
+ # expect(user_list).to include(a_user_who_is_an_admin)
64
+ #
65
+ # ## Alias Matchers
66
+ #
67
+ # With {RSpec::Matchers.alias_matcher}, you can easily create an
68
+ # alternate name for a given matcher.
69
+ #
70
+ # The description will also change according to the new name:
71
+ #
72
+ # RSpec::Matchers.alias_matcher :a_list_that_sums_to, :sum_to
73
+ # sum_to(3).description # => "sum to 3"
74
+ # a_list_that_sums_to(3).description # => "a list that sums to 3"
75
+ #
76
+ # or you can specify a custom description like this:
77
+ #
78
+ # RSpec::Matchers.alias_matcher :a_list_sorted_by, :be_sorted_by do |description|
79
+ # description.sub("be sorted by", "a list sorted by")
80
+ # end
81
+ #
82
+ # be_sorted_by(:age).description # => "be sorted by age"
83
+ # a_list_sorted_by(:age).description # => "a list sorted by age"
84
+ #
49
85
  # ## Custom Matchers
50
86
  #
51
87
  # When you find that none of the stock matchers provide a natural feeling
@@ -58,15 +94,15 @@ module RSpec
58
94
  # zones on a virtual board. To specify that bob should be in zone 4, you
59
95
  # could say:
60
96
  #
61
- # bob.current_zone.should eql(Zone.new("4"))
97
+ # expect(bob.current_zone).to eql(Zone.new("4"))
62
98
  #
63
99
  # But you might find it more expressive to say:
64
100
  #
65
- # bob.should be_in_zone("4")
101
+ # expect(bob).to be_in_zone("4")
66
102
  #
67
103
  # and/or
68
104
  #
69
- # bob.should_not be_in_zone("3")
105
+ # expect(bob).not_to be_in_zone("3")
70
106
  #
71
107
  # You can create such a matcher like so:
72
108
  #
@@ -85,11 +121,11 @@ module RSpec
85
121
  # player.in_zone?(zone)
86
122
  # end
87
123
  #
88
- # failure_message_for_should do |player|
124
+ # failure_message do |player|
89
125
  # # generate and return the appropriate string.
90
126
  # end
91
127
  #
92
- # failure_message_for_should_not do |player|
128
+ # failure_message_when_negated do |player|
93
129
  # # generate and return the appropriate string.
94
130
  # end
95
131
  #
@@ -100,9 +136,9 @@ module RSpec
100
136
  #
101
137
  # Each of the message-generation methods has access to the block arguments
102
138
  # passed to the <tt>create</tt> method (in this case, <tt>zone</tt>). The
103
- # failure message methods (<tt>failure_message_for_should</tt> and
104
- # <tt>failure_message_for_should_not</tt>) are passed the actual value (the
105
- # receiver of <tt>should</tt> or <tt>should_not</tt>).
139
+ # failure message methods (<tt>failure_message</tt> and
140
+ # <tt>failure_message_when_negated</tt>) are passed the actual value (the
141
+ # receiver of <tt>expect(..)</tt> or <tt>expect(..).not_to</tt>).
106
142
  #
107
143
  # ### Custom Matcher from scratch
108
144
  #
@@ -118,11 +154,11 @@ module RSpec
118
154
  # @target.current_zone.eql?(Zone.new(@expected))
119
155
  # end
120
156
  #
121
- # def failure_message_for_should
157
+ # def failure_message
122
158
  # "expected #{@target.inspect} to be in Zone #{@expected}"
123
159
  # end
124
160
  #
125
- # def failure_message_for_should_not
161
+ # def failure_message_when_negated
126
162
  # "expected #{@target.inspect} not to be in Zone #{@expected}"
127
163
  # end
128
164
  # end
@@ -158,63 +194,149 @@ module RSpec
158
194
  # RSpec::configure do |config|
159
195
  # config.include(CustomGameMatchers)
160
196
  # end
161
- module Matchers
162
- # Include Matchers for other test frameworks. Note that MiniTest _must_
163
- # come before TU because on ruby 1.9, T::U::TC is a subclass of MT::U::TC
164
- # and a 1.9 bug can lead to infinite recursion from the `super` call in our
165
- # method_missing hook. See this gist for more info:
166
- # https://gist.github.com/845896
167
- if defined?(MiniTest::Unit::TestCase)
168
- MiniTest::Unit::TestCase.send(:include, self)
169
- end
170
- if defined?(Test::Unit::TestCase)
171
- Test::Unit::TestCase.send(:include, self)
197
+ #
198
+ # ### Making custom matchers composable
199
+ #
200
+ # RSpec's built-in matchers are designed to be composed, in expressions like:
201
+ #
202
+ # expect(["barn", 2.45]).to contain_exactly(
203
+ # a_value_within(0.1).of(2.5),
204
+ # a_string_starting_with("bar")
205
+ # )
206
+ #
207
+ # Custom matchers can easily participate in composed matcher expressions like these.
208
+ # Include {RSpec::Matchers::Composable} in your custom matcher to make it support
209
+ # being composed (matchers defined using the DSL have this included automatically).
210
+ # Within your matcher's `matches?` method (or the `match` block, if using the DSL),
211
+ # use `values_match?(expected, actual)` rather than `expected == actual`.
212
+ # Under the covers, `values_match?` is able to match arbitrary
213
+ # nested data structures containing a mix of both matchers and non-matcher objects.
214
+ # It uses `===` and `==` to perform the matching, considering the values to
215
+ # match if either returns `true`. The `Composable` mixin also provides some helper
216
+ # methods for surfacing the matcher descriptions within your matcher's description
217
+ # or failure messages.
218
+ #
219
+ # RSpec's built-in matchers each have a number of aliases that rephrase the matcher
220
+ # from a verb phrase (such as `be_within`) to a noun phrase (such as `a_value_within`),
221
+ # which reads better when the matcher is passed as an argument in a composed matcher
222
+ # expressions, and also uses the noun-phrase wording in the matcher's `description`,
223
+ # for readable failure messages. You can alias your custom matchers in similar fashion
224
+ # using {RSpec::Matchers.alias_matcher}.
225
+ #
226
+ # ## Negated Matchers
227
+ #
228
+ # Sometimes if you want to test for the opposite using a more descriptive name
229
+ # instead of using `not_to`, you can use {RSpec::Matchers.define_negated_matcher}:
230
+ #
231
+ # RSpec::Matchers.define_negated_matcher :exclude, :include
232
+ # include(1, 2).description # => "include 1 and 2"
233
+ # exclude(1, 2).description # => "exclude 1 and 2"
234
+ #
235
+ # While the most obvious negated form may be to add a `not_` prefix,
236
+ # the failure messages you get with that form can be confusing (e.g.
237
+ # "expected [actual] to not [verb], but did not"). We've found it works
238
+ # best to find a more positive name for the negated form, such as
239
+ # `avoid_changing` rather than `not_change`.
240
+ #
241
+ module Matchers # rubocop:disable Metrics/ModuleLength
242
+ extend ::RSpec::Matchers::DSL
243
+
244
+ # @!macro [attach] alias_matcher
245
+ # @!parse
246
+ # alias $1 $2
247
+ # @!visibility private
248
+ # We define this override here so we can attach a YARD macro to it.
249
+ # It ensures that our docs list all the matcher aliases.
250
+ def self.alias_matcher(*args, &block)
251
+ super(*args, &block)
172
252
  end
173
- end
174
- end
175
253
 
176
- require 'rspec/matchers/extensions/instance_eval_with_args'
177
- require 'rspec/matchers/pretty'
254
+ # @!method self.alias_matcher(new_name, old_name, options={}, &description_override)
255
+ # Extended from {RSpec::Matchers::DSL#alias_matcher}.
178
256
 
179
- require 'rspec/matchers/built_in'
180
- require 'rspec/matchers/matcher'
181
- require 'rspec/matchers/operator_matcher'
182
- require 'rspec/matchers/be_close'
257
+ # @!method self.define(name, &declarations)
258
+ # Extended from {RSpec::Matchers::DSL#define}.
183
259
 
184
- require 'rspec/matchers/generated_descriptions'
185
- require 'rspec/matchers/method_missing'
186
- require 'rspec/matchers/compatibility'
187
- require 'rspec/matchers/dsl'
260
+ # @!method self.define_negated_matcher(negated_name, base_name, &description_override)
261
+ # Extended from {RSpec::Matchers::DSL#define_negated_matcher}.
188
262
 
189
- module RSpec
190
- module Matchers
263
+ # @method expect
264
+ # Supports `expect(actual).to matcher` syntax by wrapping `actual` in an
265
+ # `ExpectationTarget`.
266
+ # @example
267
+ # expect(actual).to eq(expected)
268
+ # expect(actual).not_to eq(expected)
269
+ # @return [Expectations::ExpectationTarget]
270
+ # @see Expectations::ExpectationTarget#to
271
+ # @see Expectations::ExpectationTarget#not_to
272
+
273
+ # Allows multiple expectations in the provided block to fail, and then
274
+ # aggregates them into a single exception, rather than aborting on the
275
+ # first expectation failure like normal. This allows you to see all
276
+ # failures from an entire set of expectations without splitting each
277
+ # off into its own example (which may slow things down if the example
278
+ # setup is expensive).
279
+ #
280
+ # @param label [String] label for this aggregation block, which will be
281
+ # included in the aggregated exception message.
282
+ # @param metadata [Hash] additional metadata about this failure aggregation
283
+ # block. If multiple expectations fail, it will be exposed from the
284
+ # {Expectations::MultipleExpectationsNotMetError} exception. Mostly
285
+ # intended for internal RSpec use but you can use it as well.
286
+ # @yield Block containing as many expectation as you want. The block is
287
+ # simply yielded to, so you can trust that anything that works outside
288
+ # the block should work within it.
289
+ # @raise [Expectations::MultipleExpectationsNotMetError] raised when
290
+ # multiple expectations fail.
291
+ # @raise [Expectations::ExpectationNotMetError] raised when a single
292
+ # expectation fails.
293
+ # @raise [Exception] other sorts of exceptions will be raised as normal.
294
+ #
295
+ # @example
296
+ # aggregate_failures("verifying response") do
297
+ # expect(response.status).to eq(200)
298
+ # expect(response.headers).to include("Content-Type" => "text/plain")
299
+ # expect(response.body).to include("Success")
300
+ # end
301
+ #
302
+ # @note The implementation of this feature uses a thread-local variable,
303
+ # which means that if you have an expectation failure in another thread,
304
+ # it'll abort like normal.
305
+ def aggregate_failures(label=nil, metadata={}, &block)
306
+ Expectations::FailureAggregator.new(label, metadata).aggregate(&block)
307
+ end
191
308
 
192
309
  # Passes if actual is truthy (anything but false or nil)
193
- def be_true
194
- BuiltIn::BeTrue.new
310
+ def be_truthy
311
+ BuiltIn::BeTruthy.new
195
312
  end
313
+ alias_matcher :a_truthy_value, :be_truthy
196
314
 
197
- # Passes if actual is falsy (false or nil)
198
- def be_false
199
- BuiltIn::BeFalse.new
315
+ # Passes if actual is falsey (false or nil)
316
+ def be_falsey
317
+ BuiltIn::BeFalsey.new
200
318
  end
319
+ alias_matcher :be_falsy, :be_falsey
320
+ alias_matcher :a_falsey_value, :be_falsey
321
+ alias_matcher :a_falsy_value, :be_falsey
201
322
 
202
323
  # Passes if actual is nil
203
324
  def be_nil
204
325
  BuiltIn::BeNil.new
205
326
  end
327
+ alias_matcher :a_nil_value, :be_nil
206
328
 
207
329
  # @example
208
- # actual.should be_true
209
- # actual.should be_false
210
- # actual.should be_nil
211
- # actual.should be_[arbitrary_predicate](*args)
212
- # actual.should_not be_nil
213
- # actual.should_not be_[arbitrary_predicate](*args)
330
+ # expect(actual).to be_truthy
331
+ # expect(actual).to be_falsey
332
+ # expect(actual).to be_nil
333
+ # expect(actual).to be_[arbitrary_predicate](*args)
334
+ # expect(actual).not_to be_nil
335
+ # expect(actual).not_to be_[arbitrary_predicate](*args)
214
336
  #
215
337
  # Given true, false, or nil, will pass if actual value is true, false or
216
338
  # nil (respectively). Given no args means the caller should satisfy an if
217
- # condition (to be or not to be).
339
+ # condition (to be or not to be).
218
340
  #
219
341
  # Predicates are any Ruby method that ends in a "?" and returns true or
220
342
  # false. Given be_ followed by arbitrary_predicate (without the "?"),
@@ -225,52 +347,66 @@ module RSpec
225
347
  # (e.g. be_empty), letting you choose the prefix that best suits the
226
348
  # predicate.
227
349
  def be(*args)
228
- args.empty? ?
229
- Matchers::BuiltIn::Be.new : equal(*args)
350
+ args.empty? ? Matchers::BuiltIn::Be.new : equal(*args)
230
351
  end
352
+ alias_matcher :a_value, :be, :klass => AliasedMatcherWithOperatorSupport
231
353
 
232
354
  # passes if target.kind_of?(klass)
233
355
  def be_a(klass)
234
356
  be_a_kind_of(klass)
235
357
  end
236
-
237
358
  alias_method :be_an, :be_a
238
359
 
239
360
  # Passes if actual.instance_of?(expected)
240
361
  #
241
362
  # @example
242
- #
243
- # 5.should be_instance_of(Fixnum)
244
- # 5.should_not be_instance_of(Numeric)
245
- # 5.should_not be_instance_of(Float)
363
+ # expect(5).to be_an_instance_of(Integer)
364
+ # expect(5).not_to be_an_instance_of(Numeric)
365
+ # expect(5).not_to be_an_instance_of(Float)
246
366
  def be_an_instance_of(expected)
247
367
  BuiltIn::BeAnInstanceOf.new(expected)
248
368
  end
249
-
250
369
  alias_method :be_instance_of, :be_an_instance_of
370
+ alias_matcher :an_instance_of, :be_an_instance_of
251
371
 
252
372
  # Passes if actual.kind_of?(expected)
253
373
  #
254
374
  # @example
255
- #
256
- # 5.should be_kind_of(Fixnum)
257
- # 5.should be_kind_of(Numeric)
258
- # 5.should_not be_kind_of(Float)
375
+ # expect(5).to be_a_kind_of(Integer)
376
+ # expect(5).to be_a_kind_of(Numeric)
377
+ # expect(5).not_to be_a_kind_of(Float)
259
378
  def be_a_kind_of(expected)
260
379
  BuiltIn::BeAKindOf.new(expected)
261
380
  end
262
-
263
381
  alias_method :be_kind_of, :be_a_kind_of
382
+ alias_matcher :a_kind_of, :be_a_kind_of
264
383
 
265
- # Passes if actual == expected +/- delta
384
+ # Passes if actual.between?(min, max). Works with any Comparable object,
385
+ # including String, Symbol, Time, or Numeric (Fixnum, Bignum, Integer,
386
+ # Float, Complex, and Rational).
387
+ #
388
+ # By default, `be_between` is inclusive (i.e. passes when given either the max or min value),
389
+ # but you can make it `exclusive` by chaining that off the matcher.
266
390
  #
267
391
  # @example
392
+ # expect(5).to be_between(1, 10)
393
+ # expect(11).not_to be_between(1, 10)
394
+ # expect(10).not_to be_between(1, 10).exclusive
395
+ def be_between(min, max)
396
+ BuiltIn::BeBetween.new(min, max)
397
+ end
398
+ alias_matcher :a_value_between, :be_between
399
+
400
+ # Passes if actual == expected +/- delta
268
401
  #
269
- # result.should be_within(0.5).of(3.0)
270
- # result.should_not be_within(0.5).of(3.0)
402
+ # @example
403
+ # expect(result).to be_within(0.5).of(3.0)
404
+ # expect(result).not_to be_within(0.5).of(3.0)
271
405
  def be_within(delta)
272
406
  BuiltIn::BeWithin.new(delta)
273
407
  end
408
+ alias_matcher :a_value_within, :be_within
409
+ alias_matcher :within, :be_within
274
410
 
275
411
  # Applied to a proc, specifies that its execution will cause some value to
276
412
  # change.
@@ -281,78 +417,119 @@ module RSpec
281
417
  # You can either pass <tt>receiver</tt> and <tt>message</tt>, or a block,
282
418
  # but not both.
283
419
  #
284
- # When passing a block, it must use the <tt>{ ... }</tt> format, not
285
- # do/end, as <tt>{ ... }</tt> binds to the +change+ method, whereas do/end
286
- # would errantly bind to the +should+ or +should_not+ method.
420
+ # When passing a block, it must use the `{ ... }` format, not
421
+ # do/end, as `{ ... }` binds to the `change` method, whereas do/end
422
+ # would errantly bind to the `expect(..).to` or `expect(...).not_to` method.
287
423
  #
288
- # @example
424
+ # You can chain any of the following off of the end to specify details
425
+ # about the change:
426
+ #
427
+ # * `from`
428
+ # * `to`
289
429
  #
290
- # lambda {
291
- # team.add_player(player)
292
- # }.should change(roster, :count)
430
+ # or any one of:
293
431
  #
294
- # lambda {
295
- # team.add_player(player)
296
- # }.should change(roster, :count).by(1)
432
+ # * `by`
433
+ # * `by_at_least`
434
+ # * `by_at_most`
297
435
  #
298
- # lambda {
299
- # team.add_player(player)
300
- # }.should change(roster, :count).by_at_least(1)
436
+ # @example
437
+ # expect {
438
+ # team.add_player(player)
439
+ # }.to change(roster, :count)
301
440
  #
302
- # lambda {
441
+ # expect {
303
442
  # team.add_player(player)
304
- # }.should change(roster, :count).by_at_most(1)
443
+ # }.to change(roster, :count).by(1)
444
+ #
445
+ # expect {
446
+ # team.add_player(player)
447
+ # }.to change(roster, :count).by_at_least(1)
448
+ #
449
+ # expect {
450
+ # team.add_player(player)
451
+ # }.to change(roster, :count).by_at_most(1)
305
452
  #
306
453
  # string = "string"
307
- # lambda {
454
+ # expect {
308
455
  # string.reverse!
309
- # }.should change { string }.from("string").to("gnirts")
456
+ # }.to change { string }.from("string").to("gnirts")
310
457
  #
311
- # lambda {
458
+ # string = "string"
459
+ # expect {
460
+ # string
461
+ # }.not_to change { string }.from("string")
462
+ #
463
+ # expect {
312
464
  # person.happy_birthday
313
- # }.should change(person, :birthday).from(32).to(33)
314
- #
315
- # lambda {
465
+ # }.to change(person, :birthday).from(32).to(33)
466
+ #
467
+ # expect {
316
468
  # employee.develop_great_new_social_networking_app
317
- # }.should change(employee, :title).from("Mail Clerk").to("CEO")
469
+ # }.to change(employee, :title).from("Mail Clerk").to("CEO")
318
470
  #
319
- # lambda {
471
+ # expect {
320
472
  # doctor.leave_office
321
- # }.should change(doctor, :sign).from(/is in/).to(/is out/)
473
+ # }.to change(doctor, :sign).from(/is in/).to(/is out/)
322
474
  #
323
475
  # user = User.new(:type => "admin")
324
- # lambda {
476
+ # expect {
325
477
  # user.symbolize_type
326
- # }.should change(user, :type).from(String).to(Symbol)
478
+ # }.to change(user, :type).from(String).to(Symbol)
327
479
  #
328
480
  # == Notes
329
481
  #
330
- # Evaluates <tt>receiver.message</tt> or <tt>block</tt> before and after it
331
- # evaluates the proc object (generated by the lambdas in the examples
332
- # above).
482
+ # Evaluates `receiver.message` or `block` before and after it
483
+ # evaluates the block passed to `expect`. If the value is the same
484
+ # object, its before/after `hash` value is used to see if it has changed.
485
+ # Therefore, your object needs to properly implement `hash` to work correctly
486
+ # with this matcher.
333
487
  #
334
- # <tt>should_not change</tt> only supports the form with no subsequent
335
- # calls to <tt>by</tt>, <tt>by_at_least</tt>, <tt>by_at_most</tt>,
336
- # <tt>to</tt> or <tt>from</tt>.
488
+ # `expect( ... ).not_to change` supports the form that specifies `from`
489
+ # (which specifies what you expect the starting, unchanged value to be)
490
+ # but does not support forms with subsequent calls to `by`, `by_at_least`,
491
+ # `by_at_most` or `to`.
337
492
  def change(receiver=nil, message=nil, &block)
338
493
  BuiltIn::Change.new(receiver, message, &block)
339
494
  end
495
+ alias_matcher :a_block_changing, :change
496
+ alias_matcher :changing, :change
497
+
498
+ # Passes if actual contains all of the expected regardless of order.
499
+ # This works for collections. Pass in multiple args and it will only
500
+ # pass if all args are found in collection.
501
+ #
502
+ # @note This is also available using the `=~` operator with `should`,
503
+ # but `=~` is not supported with `expect`.
504
+ #
505
+ # @example
506
+ # expect([1, 2, 3]).to contain_exactly(1, 2, 3)
507
+ # expect([1, 2, 3]).to contain_exactly(1, 3, 2)
508
+ #
509
+ # @see #match_array
510
+ def contain_exactly(*items)
511
+ BuiltIn::ContainExactly.new(items)
512
+ end
513
+ alias_matcher :a_collection_containing_exactly, :contain_exactly
514
+ alias_matcher :containing_exactly, :contain_exactly
340
515
 
341
516
  # Passes if actual covers expected. This works for
342
517
  # Ranges. You can also pass in multiple args
343
518
  # and it will only pass if all args are found in Range.
344
519
  #
345
520
  # @example
346
- # (1..10).should cover(5)
347
- # (1..10).should cover(4, 6)
348
- # (1..10).should cover(4, 6, 11) # will fail
349
- # (1..10).should_not cover(11)
350
- # (1..10).should_not cover(5) # will fail
521
+ # expect(1..10).to cover(5)
522
+ # expect(1..10).to cover(4, 6)
523
+ # expect(1..10).to cover(4, 6, 11) # fails
524
+ # expect(1..10).not_to cover(11)
525
+ # expect(1..10).not_to cover(5) # fails
351
526
  #
352
527
  # ### Warning:: Ruby >= 1.9 only
353
528
  def cover(*values)
354
529
  BuiltIn::Cover.new(*values)
355
- end if (1..2).respond_to?(:cover?)
530
+ end
531
+ alias_matcher :a_range_covering, :cover
532
+ alias_matcher :covering, :cover
356
533
 
357
534
  # Matches if the actual value ends with the expected value(s). In the case
358
535
  # of a string, matches against the last `expected.length` characters of the
@@ -360,140 +537,219 @@ module RSpec
360
537
  # `expected.length` elements of the actual array.
361
538
  #
362
539
  # @example
363
- #
364
- # "this string".should end_with "string"
365
- # [0, 1, 2, 3, 4].should end_with 4
366
- # [0, 2, 3, 4, 4].should end_with 3, 4
540
+ # expect("this string").to end_with "string"
541
+ # expect([0, 1, 2, 3, 4]).to end_with 4
542
+ # expect([0, 2, 3, 4, 4]).to end_with 3, 4
367
543
  def end_with(*expected)
368
544
  BuiltIn::EndWith.new(*expected)
369
545
  end
546
+ alias_matcher :a_collection_ending_with, :end_with
547
+ alias_matcher :a_string_ending_with, :end_with
548
+ alias_matcher :ending_with, :end_with
370
549
 
371
550
  # Passes if <tt>actual == expected</tt>.
372
551
  #
373
- # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more information about equality in Ruby.
552
+ # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more
553
+ # information about equality in Ruby.
374
554
  #
375
555
  # @example
376
- #
377
- # 5.should eq(5)
378
- # 5.should_not eq(3)
556
+ # expect(5).to eq(5)
557
+ # expect(5).not_to eq(3)
379
558
  def eq(expected)
380
559
  BuiltIn::Eq.new(expected)
381
560
  end
561
+ alias_matcher :an_object_eq_to, :eq
562
+ alias_matcher :eq_to, :eq
382
563
 
383
- # Passes if +actual.eql?(expected)+
564
+ # Passes if `actual.eql?(expected)`
384
565
  #
385
- # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more information about equality in Ruby.
566
+ # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more
567
+ # information about equality in Ruby.
386
568
  #
387
569
  # @example
388
- #
389
- # 5.should eql(5)
390
- # 5.should_not eql(3)
570
+ # expect(5).to eql(5)
571
+ # expect(5).not_to eql(3)
391
572
  def eql(expected)
392
573
  BuiltIn::Eql.new(expected)
393
574
  end
575
+ alias_matcher :an_object_eql_to, :eql
576
+ alias_matcher :eql_to, :eql
394
577
 
395
578
  # Passes if <tt>actual.equal?(expected)</tt> (object identity).
396
579
  #
397
- # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more information about equality in Ruby.
580
+ # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more
581
+ # information about equality in Ruby.
398
582
  #
399
583
  # @example
400
- #
401
- # 5.should equal(5) # Fixnums are equal
402
- # "5".should_not equal("5") # Strings that look the same are not the same object
584
+ # expect(5).to equal(5) # Integers are equal
585
+ # expect("5").not_to equal("5") # Strings that look the same are not the same object
403
586
  def equal(expected)
404
587
  BuiltIn::Equal.new(expected)
405
588
  end
589
+ alias_matcher :an_object_equal_to, :equal
590
+ alias_matcher :equal_to, :equal
406
591
 
407
592
  # Passes if `actual.exist?` or `actual.exists?`
408
593
  #
409
594
  # @example
410
- # File.should exist("path/to/file")
595
+ # expect(File).to exist("path/to/file")
411
596
  def exist(*args)
412
597
  BuiltIn::Exist.new(*args)
413
598
  end
599
+ alias_matcher :an_object_existing, :exist
600
+ alias_matcher :existing, :exist
414
601
 
415
- # Passes if receiver is a collection with the submitted number of items OR
416
- # if the receiver OWNS a collection with the submitted number of items.
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.
421
- #
422
- # If the receiver IS the collection, you can use any name you like for
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.
426
- #
427
- # This also works for Strings, letting you set expectations about their
428
- # lengths.
602
+ # Passes if actual's attribute values match the expected attributes hash.
603
+ # This works no matter how you define your attribute readers.
429
604
  #
430
605
  # @example
606
+ # Person = Struct.new(:name, :age)
607
+ # person = Person.new("Bob", 32)
431
608
  #
432
- # # Passes if team.players.size == 11
433
- # team.should have(11).players
609
+ # expect(person).to have_attributes(:name => "Bob", :age => 32)
610
+ # expect(person).to have_attributes(:name => a_string_starting_with("B"), :age => (a_value > 30) )
434
611
  #
435
- # # Passes if [1,2,3].length == 3
436
- # [1,2,3].should have(3).items #"items" is pure sugar
612
+ # @note It will fail if actual doesn't respond to any of the expected attributes.
437
613
  #
438
- # # Passes if ['a', 'b', 'c'].count == 3
439
- # [1,2,3].should have(3).items #"items" is pure sugar
614
+ # @example
615
+ # expect(person).to have_attributes(:color => "red")
616
+ def have_attributes(expected)
617
+ BuiltIn::HaveAttributes.new(expected)
618
+ end
619
+ alias_matcher :an_object_having_attributes, :have_attributes
620
+ alias_matcher :having_attributes, :have_attributes
621
+
622
+ # Passes if actual includes expected. This works for
623
+ # collections and Strings. You can also pass in multiple args
624
+ # and it will only pass if all args are found in collection.
440
625
  #
441
- # # Passes if "this string".length == 11
442
- # "this string".should have(11).characters #"characters" is pure sugar
443
- def have(n)
444
- BuiltIn::Have.new(n)
626
+ # @example
627
+ # expect([1,2,3]).to include(3)
628
+ # expect([1,2,3]).to include(2,3)
629
+ # expect([1,2,3]).to include(2,3,4) # fails
630
+ # expect([1,2,3]).not_to include(4)
631
+ # expect("spread").to include("read")
632
+ # expect("spread").not_to include("red")
633
+ # expect(:a => 1, :b => 2).to include(:a)
634
+ # expect(:a => 1, :b => 2).to include(:a, :b)
635
+ # expect(:a => 1, :b => 2).to include(:a => 1)
636
+ # expect(:a => 1, :b => 2).to include(:b => 2, :a => 1)
637
+ # expect(:a => 1, :b => 2).to include(:c) # fails
638
+ # expect(:a => 1, :b => 2).not_to include(:a => 2)
639
+ def include(*expected)
640
+ BuiltIn::Include.new(*expected)
445
641
  end
446
- alias :have_exactly :have
642
+ alias_matcher :a_collection_including, :include
643
+ alias_matcher :a_string_including, :include
644
+ alias_matcher :a_hash_including, :include
645
+ alias_matcher :including, :include
447
646
 
448
- # Exactly like have() with >=.
647
+ # Passes if the provided matcher passes when checked against all
648
+ # elements of the collection.
449
649
  #
450
650
  # @example
451
- # "this".should have_at_least(3).letters
651
+ # expect([1, 3, 5]).to all be_odd
652
+ # expect([1, 3, 6]).to all be_odd # fails
653
+ #
654
+ # @note The negative form `not_to all` is not supported. Instead
655
+ # use `not_to include` or pass a negative form of a matcher
656
+ # as the argument (e.g. `all exclude(:foo)`).
452
657
  #
453
- # ### Warning:
658
+ # @note You can also use this with compound matchers as well.
454
659
  #
455
- # `should_not have_at_least` is not supported
456
- def have_at_least(n)
457
- BuiltIn::Have.new(n, :at_least)
660
+ # @example
661
+ # expect([1, 3, 5]).to all( be_odd.and be_an(Integer) )
662
+ def all(expected)
663
+ BuiltIn::All.new(expected)
458
664
  end
459
665
 
460
- # Exactly like have() with <=.
666
+ # Given a `Regexp` or `String`, passes if `actual.match(pattern)`
667
+ # Given an arbitrary nested data structure (e.g. arrays and hashes),
668
+ # matches if `expected === actual` || `actual == expected` for each
669
+ # pair of elements.
461
670
  #
462
671
  # @example
463
- # should have_at_most(number).items
672
+ # expect(email).to match(/^([^\s]+)((?:[-a-z0-9]+\.)+[a-z]{2,})$/i)
673
+ # expect(email).to match("@example.com")
464
674
  #
465
- # ### Warning:
675
+ # @example
676
+ # hash = {
677
+ # :a => {
678
+ # :b => ["foo", 5],
679
+ # :c => { :d => 2.05 }
680
+ # }
681
+ # }
466
682
  #
467
- # `should_not have_at_most` is not supported
468
- def have_at_most(n)
469
- BuiltIn::Have.new(n, :at_most)
683
+ # expect(hash).to match(
684
+ # :a => {
685
+ # :b => a_collection_containing_exactly(
686
+ # a_string_starting_with("f"),
687
+ # an_instance_of(Integer)
688
+ # ),
689
+ # :c => { :d => (a_value < 3) }
690
+ # }
691
+ # )
692
+ #
693
+ # @note The `match_regex` alias is deprecated and is not recommended for use.
694
+ # It was added in 2.12.1 to facilitate its use from within custom
695
+ # matchers (due to how the custom matcher DSL was evaluated in 2.x,
696
+ # `match` could not be used there), but is no longer needed in 3.x.
697
+ def match(expected)
698
+ BuiltIn::Match.new(expected)
470
699
  end
700
+ alias_matcher :match_regex, :match
701
+ alias_matcher :an_object_matching, :match
702
+ alias_matcher :a_string_matching, :match
703
+ alias_matcher :matching, :match
471
704
 
472
- # Passes if actual includes expected. This works for
473
- # collections and Strings. You can also pass in multiple args
474
- # and it will only pass if all args are found in collection.
705
+ # An alternate form of `contain_exactly` that accepts
706
+ # the expected contents as a single array arg rather
707
+ # that splatted out as individual items.
475
708
  #
476
709
  # @example
710
+ # expect(results).to contain_exactly(1, 2)
711
+ # # is identical to:
712
+ # expect(results).to match_array([1, 2])
477
713
  #
478
- # [1,2,3].should include(3)
479
- # [1,2,3].should include(2,3) #would pass
480
- # [1,2,3].should include(2,3,4) #would fail
481
- # [1,2,3].should_not include(4)
482
- # "spread".should include("read")
483
- # "spread".should_not include("red")
484
- def include(*expected)
485
- BuiltIn::Include.new(*expected)
714
+ # @see #contain_exactly
715
+ def match_array(items)
716
+ contain_exactly(*items)
486
717
  end
487
718
 
488
- # Given a Regexp or String, passes if actual.match(pattern)
719
+ # With no arg, passes if the block outputs `to_stdout` or `to_stderr`.
720
+ # With a string, passes if the block outputs that specific string `to_stdout` or `to_stderr`.
721
+ # With a regexp or matcher, passes if the block outputs a string `to_stdout` or `to_stderr` that matches.
722
+ #
723
+ # To capture output from any spawned subprocess as well, use `to_stdout_from_any_process` or
724
+ # `to_stderr_from_any_process`. Output from any process that inherits the main process's corresponding
725
+ # standard stream will be captured.
489
726
  #
490
727
  # @example
728
+ # expect { print 'foo' }.to output.to_stdout
729
+ # expect { print 'foo' }.to output('foo').to_stdout
730
+ # expect { print 'foo' }.to output(/foo/).to_stdout
491
731
  #
492
- # email.should match(/^([^\s]+)((?:[-a-z0-9]+\.)+[a-z]{2,})$/i)
493
- # email.should match("@example.com")
494
- def match(expected)
495
- BuiltIn::Match.new(expected)
732
+ # expect { do_something }.to_not output.to_stdout
733
+ #
734
+ # expect { warn('foo') }.to output.to_stderr
735
+ # expect { warn('foo') }.to output('foo').to_stderr
736
+ # expect { warn('foo') }.to output(/foo/).to_stderr
737
+ #
738
+ # expect { do_something }.to_not output.to_stderr
739
+ #
740
+ # expect { system('echo foo') }.to output("foo\n").to_stdout_from_any_process
741
+ # expect { system('echo foo', out: :err) }.to output("foo\n").to_stderr_from_any_process
742
+ #
743
+ # @note `to_stdout` and `to_stderr` work by temporarily replacing `$stdout` or `$stderr`,
744
+ # so they're not able to intercept stream output that explicitly uses `STDOUT`/`STDERR`
745
+ # or that uses a reference to `$stdout`/`$stderr` that was stored before the
746
+ # matcher was used.
747
+ # @note `to_stdout_from_any_process` and `to_stderr_from_any_process` use Tempfiles, and
748
+ # are thus significantly (~30x) slower than `to_stdout` and `to_stderr`.
749
+ def output(expected=nil)
750
+ BuiltIn::Output.new(expected)
496
751
  end
752
+ alias_matcher :a_block_outputting, :output
497
753
 
498
754
  # With no args, matches if any error is raised.
499
755
  # With a named error, matches only if that specific error is raised.
@@ -502,31 +758,39 @@ module RSpec
502
758
  # Pass an optional block to perform extra verifications on the exception matched
503
759
  #
504
760
  # @example
505
- #
506
- # lambda { do_something_risky }.should raise_error
507
- # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError)
508
- # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError) { |error| error.data.should == 42 }
509
- # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError, "that was too risky")
510
- # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError, /oo ri/)
511
- #
512
- # lambda { do_something_risky }.should_not raise_error
513
- # lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError)
514
- # lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError, "that was too risky")
515
- # lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError, /oo ri/)
516
- def raise_error(error=Exception, message=nil, &block)
761
+ # expect { do_something_risky }.to raise_error
762
+ # expect { do_something_risky }.to raise_error(PoorRiskDecisionError)
763
+ # expect { do_something_risky }.to raise_error(PoorRiskDecisionError) { |error| expect(error.data).to eq 42 }
764
+ # expect { do_something_risky }.to raise_error { |error| expect(error.data).to eq 42 }
765
+ # expect { do_something_risky }.to raise_error(PoorRiskDecisionError, "that was too risky")
766
+ # expect { do_something_risky }.to raise_error(PoorRiskDecisionError, /oo ri/)
767
+ # expect { do_something_risky }.to raise_error("that was too risky")
768
+ #
769
+ # expect { do_something_risky }.not_to raise_error
770
+ def raise_error(error=BuiltIn::RaiseError::UndefinedValue, message=nil, &block)
517
771
  BuiltIn::RaiseError.new(error, message, &block)
518
772
  end
519
-
520
773
  alias_method :raise_exception, :raise_error
521
774
 
775
+ alias_matcher :a_block_raising, :raise_error do |desc|
776
+ desc.sub("raise", "a block raising")
777
+ end
778
+
779
+ alias_matcher :raising, :raise_error do |desc|
780
+ desc.sub("raise", "raising")
781
+ end
782
+
522
783
  # Matches if the target object responds to all of the names
523
784
  # provided. Names can be Strings or Symbols.
524
785
  #
525
786
  # @example
526
- #
787
+ # expect("string").to respond_to(:length)
788
+ #
527
789
  def respond_to(*names)
528
790
  BuiltIn::RespondTo.new(*names)
529
791
  end
792
+ alias_matcher :an_object_responding_to, :respond_to
793
+ alias_matcher :responding_to, :respond_to
530
794
 
531
795
  # Passes if the submitted block returns true. Yields target to the
532
796
  # block.
@@ -538,14 +802,16 @@ module RSpec
538
802
  # If you do find yourself in such a situation, you could always write
539
803
  # a custom matcher, which would likely make your specs more expressive.
540
804
  #
541
- # @example
805
+ # @param description [String] optional description to be used for this matcher.
542
806
  #
543
- # 5.should satisfy { |n|
544
- # n > 3
545
- # }
546
- def satisfy(&block)
547
- BuiltIn::Satisfy.new(&block)
807
+ # @example
808
+ # expect(5).to satisfy { |n| n > 3 }
809
+ # expect(5).to satisfy("be greater than 3") { |n| n > 3 }
810
+ def satisfy(description=nil, &block)
811
+ BuiltIn::Satisfy.new(description, &block)
548
812
  end
813
+ alias_matcher :an_object_satisfying, :satisfy
814
+ alias_matcher :satisfying, :satisfy
549
815
 
550
816
  # Matches if the actual value starts with the expected value(s). In the
551
817
  # case of a string, matches against the first `expected.length` characters
@@ -553,13 +819,15 @@ module RSpec
553
819
  # `expected.length` elements of the actual array.
554
820
  #
555
821
  # @example
556
- #
557
- # "this string".should start_with "this s"
558
- # [0, 1, 2, 3, 4].should start_with 0
559
- # [0, 2, 3, 4, 4].should start_with 0, 1
822
+ # expect("this string").to start_with "this s"
823
+ # expect([0, 1, 2, 3, 4]).to start_with 0
824
+ # expect([0, 2, 3, 4, 4]).to start_with 0, 1
560
825
  def start_with(*expected)
561
826
  BuiltIn::StartWith.new(*expected)
562
827
  end
828
+ alias_matcher :a_collection_starting_with, :start_with
829
+ alias_matcher :a_string_starting_with, :start_with
830
+ alias_matcher :starting_with, :start_with
563
831
 
564
832
  # Given no argument, matches if a proc throws any Symbol.
565
833
  #
@@ -569,39 +837,44 @@ module RSpec
569
837
  # specified Symbol with the specified arg.
570
838
  #
571
839
  # @example
840
+ # expect { do_something_risky }.to throw_symbol
841
+ # expect { do_something_risky }.to throw_symbol(:that_was_risky)
842
+ # expect { do_something_risky }.to throw_symbol(:that_was_risky, 'culprit')
572
843
  #
573
- # lambda { do_something_risky }.should throw_symbol
574
- # lambda { do_something_risky }.should throw_symbol(:that_was_risky)
575
- # lambda { do_something_risky }.should throw_symbol(:that_was_risky, culprit)
576
- #
577
- # lambda { do_something_risky }.should_not throw_symbol
578
- # lambda { do_something_risky }.should_not throw_symbol(:that_was_risky)
579
- # lambda { do_something_risky }.should_not throw_symbol(:that_was_risky, culprit)
844
+ # expect { do_something_risky }.not_to throw_symbol
845
+ # expect { do_something_risky }.not_to throw_symbol(:that_was_risky)
846
+ # expect { do_something_risky }.not_to throw_symbol(:that_was_risky, 'culprit')
580
847
  def throw_symbol(expected_symbol=nil, expected_arg=nil)
581
848
  BuiltIn::ThrowSymbol.new(expected_symbol, expected_arg)
582
849
  end
583
850
 
851
+ alias_matcher :a_block_throwing, :throw_symbol do |desc|
852
+ desc.sub("throw", "a block throwing")
853
+ end
854
+
855
+ alias_matcher :throwing, :throw_symbol do |desc|
856
+ desc.sub("throw", "throwing")
857
+ end
858
+
584
859
  # Passes if the method called in the expect block yields, regardless
585
860
  # of whether or not arguments are yielded.
586
861
  #
587
862
  # @example
588
- #
589
863
  # expect { |b| 5.tap(&b) }.to yield_control
590
864
  # expect { |b| "a".to_sym(&b) }.not_to yield_control
591
865
  #
592
866
  # @note Your expect block must accept a parameter and pass it on to
593
867
  # the method-under-test as a block.
594
- # @note This matcher is not designed for use with methods that yield
595
- # multiple times.
596
868
  def yield_control
597
869
  BuiltIn::YieldControl.new
598
870
  end
871
+ alias_matcher :a_block_yielding_control, :yield_control
872
+ alias_matcher :yielding_control, :yield_control
599
873
 
600
874
  # Passes if the method called in the expect block yields with
601
875
  # no arguments. Fails if it does not yield, or yields with arguments.
602
876
  #
603
877
  # @example
604
- #
605
878
  # expect { |b| User.transaction(&b) }.to yield_with_no_args
606
879
  # expect { |b| 5.tap(&b) }.not_to yield_with_no_args # because it yields with `5`
607
880
  # expect { |b| "a".to_sym(&b) }.not_to yield_with_no_args # because it does not yield
@@ -613,6 +886,8 @@ module RSpec
613
886
  def yield_with_no_args
614
887
  BuiltIn::YieldWithNoArgs.new
615
888
  end
889
+ alias_matcher :a_block_yielding_with_no_args, :yield_with_no_args
890
+ alias_matcher :yielding_with_no_args, :yield_with_no_args
616
891
 
617
892
  # Given no arguments, matches if the method called in the expect
618
893
  # block yields with arguments (regardless of what they are or how
@@ -626,10 +901,9 @@ module RSpec
626
901
  # operator, the matcher will pass.
627
902
  #
628
903
  # @example
629
- #
630
904
  # expect { |b| 5.tap(&b) }.to yield_with_args # because #tap yields an arg
631
905
  # expect { |b| 5.tap(&b) }.to yield_with_args(5) # because 5 == 5
632
- # expect { |b| 5.tap(&b) }.to yield_with_args(Fixnum) # because Fixnum === 5
906
+ # expect { |b| 5.tap(&b) }.to yield_with_args(Integer) # because Integer === 5
633
907
  # expect { |b| File.open("f.txt", &b) }.to yield_with_args(/txt/) # because /txt/ === "f.txt"
634
908
  #
635
909
  # expect { |b| User.transaction(&b) }.not_to yield_with_args # because it yields no args
@@ -642,6 +916,8 @@ module RSpec
642
916
  def yield_with_args(*args)
643
917
  BuiltIn::YieldWithArgs.new(*args)
644
918
  end
919
+ alias_matcher :a_block_yielding_with_args, :yield_with_args
920
+ alias_matcher :yielding_with_args, :yield_with_args
645
921
 
646
922
  # Designed for use with methods that repeatedly yield (such as
647
923
  # iterators). Passes if the method called in the expect block yields
@@ -652,7 +928,6 @@ module RSpec
652
928
  # operator, the matcher will pass.
653
929
  #
654
930
  # @example
655
- #
656
931
  # expect { |b| [1, 2, 3].each(&b) }.to yield_successive_args(1, 2, 3)
657
932
  # expect { |b| { :a => 1, :b => 2 }.each(&b) }.to yield_successive_args([:a, 1], [:b, 2])
658
933
  # expect { |b| [1, 2, 3].each(&b) }.not_to yield_successive_args(1, 2)
@@ -662,28 +937,105 @@ module RSpec
662
937
  def yield_successive_args(*args)
663
938
  BuiltIn::YieldSuccessiveArgs.new(*args)
664
939
  end
940
+ alias_matcher :a_block_yielding_successive_args, :yield_successive_args
941
+ alias_matcher :yielding_successive_args, :yield_successive_args
665
942
 
666
- # Passes if actual contains all of the expected regardless of order.
667
- # This works for collections. Pass in multiple args and it will only
668
- # pass if all args are found in collection.
669
- #
670
- # @note This is also available using the `=~` operator with `should`,
671
- # but `=~` is not supported with `expect`.
672
- # @note There is no should_not version of array.should =~ other_array
673
- #
674
- # @example
675
- #
676
- # expect([1,2,3]).to match_array([1,2,3])
677
- # expect([1,2,3]).to match_array([1,3,2])
678
- # [1,2,3].should =~ [1,2,3] # => would pass
679
- # [1,2,3].should =~ [2,3,1] # => would pass
680
- # [1,2,3,4].should =~ [1,2,3] # => would fail
681
- # [1,2,2,3].should =~ [1,2,3] # => would fail
682
- # [1,2,3].should =~ [1,2,3,4] # => would fail
683
- def match_array(array)
684
- BuiltIn::MatchArray.new(array)
943
+ # Delegates to {RSpec::Expectations.configuration}.
944
+ # This is here because rspec-core's `expect_with` option
945
+ # looks for a `configuration` method on the mixin
946
+ # (`RSpec::Matchers`) to yield to a block.
947
+ # @return [RSpec::Expectations::Configuration] the configuration object
948
+ def self.configuration
949
+ Expectations.configuration
685
950
  end
686
951
 
687
- OperatorMatcher.register(Array, '=~', BuiltIn::MatchArray)
952
+ private
953
+
954
+ BE_PREDICATE_REGEX = /^(?:be_(?:an?_)?)(.*)/
955
+ HAS_REGEX = /^(?:have_)(.*)/
956
+ DYNAMIC_MATCHER_REGEX = Regexp.union(BE_PREDICATE_REGEX, HAS_REGEX)
957
+
958
+ def method_missing(method, *args, &block)
959
+ case method.to_s
960
+ when BE_PREDICATE_REGEX
961
+ BuiltIn::BePredicate.new(method, *args, &block)
962
+ when HAS_REGEX
963
+ BuiltIn::Has.new(method, *args, &block)
964
+ else
965
+ super
966
+ end
967
+ end
968
+ ruby2_keywords :method_missing if respond_to?(:ruby2_keywords, true)
969
+
970
+ if RUBY_VERSION.to_f >= 1.9
971
+ def respond_to_missing?(method, *)
972
+ method =~ DYNAMIC_MATCHER_REGEX || super
973
+ end
974
+ else # for 1.8.7
975
+ # :nocov:
976
+ def respond_to?(method, *)
977
+ method = method.to_s
978
+ method =~ DYNAMIC_MATCHER_REGEX || super
979
+ end
980
+ public :respond_to?
981
+ # :nocov:
982
+ end
983
+
984
+ # @api private
985
+ def self.is_a_matcher?(obj)
986
+ return true if ::RSpec::Matchers::BuiltIn::BaseMatcher === obj
987
+ begin
988
+ return false if obj.respond_to?(:i_respond_to_everything_so_im_not_really_a_matcher)
989
+ rescue NoMethodError
990
+ # Some objects, like BasicObject, don't implemented standard
991
+ # reflection methods.
992
+ return false
993
+ end
994
+ return false unless obj.respond_to?(:matches?)
995
+
996
+ obj.respond_to?(:failure_message) ||
997
+ obj.respond_to?(:failure_message_for_should) # support legacy matchers
998
+ end
999
+
1000
+ ::RSpec::Support.register_matcher_definition do |obj|
1001
+ is_a_matcher?(obj)
1002
+ end
1003
+
1004
+ # @api private
1005
+ def self.is_a_describable_matcher?(obj)
1006
+ is_a_matcher?(obj) && obj.respond_to?(:description)
1007
+ end
1008
+
1009
+ class << self
1010
+ private
1011
+
1012
+ if RSpec::Support::Ruby.mri? && RUBY_VERSION[0, 3] == '1.9'
1013
+ # Note that `included` doesn't work for this because it is triggered
1014
+ # _after_ `RSpec::Matchers` is an ancestor of the inclusion host, rather
1015
+ # than _before_, like `append_features`. It's important we check this before
1016
+ # in order to find the cases where it was already previously included.
1017
+ # @api private
1018
+ def append_features(mod)
1019
+ return super if mod < self # `mod < self` indicates a re-inclusion.
1020
+
1021
+ subclasses = ObjectSpace.each_object(Class).select { |c| c < mod && c < self }
1022
+ return super unless subclasses.any?
1023
+
1024
+ subclasses.reject! { |s| subclasses.any? { |s2| s < s2 } } # Filter to the root ancestor.
1025
+ subclasses = subclasses.map { |s| "`#{s}`" }.join(", ")
1026
+
1027
+ RSpec.warning "`#{self}` has been included in a superclass (`#{mod}`) " \
1028
+ "after previously being included in subclasses (#{subclasses}), " \
1029
+ "which can trigger infinite recursion from `super` due to an MRI 1.9 bug " \
1030
+ "(https://redmine.ruby-lang.org/issues/3351). To work around this, " \
1031
+ "either upgrade to MRI 2.0+, include a dup of the module (e.g. " \
1032
+ "`include #{self}.dup`), or find a way to include `#{self}` in `#{mod}` " \
1033
+ "before it is included in subclasses (#{subclasses}). See " \
1034
+ "https://github.com/rspec/rspec-expectations/issues/814 for more info"
1035
+
1036
+ super
1037
+ end
1038
+ end
1039
+ end
688
1040
  end
689
1041
  end