rspec-sleeping_king_studios 1.0.0.rc.2
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 +7 -0
- data/LICENSE +22 -0
- data/README.md +323 -0
- data/lib/rspec/sleeping_king_studios.rb +5 -0
- data/lib/rspec/sleeping_king_studios/matchers.rb +5 -0
- data/lib/rspec/sleeping_king_studios/matchers/active_model.rb +5 -0
- data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors.rb +219 -0
- data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors/error_expectation.rb +60 -0
- data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors/message_expectation.rb +17 -0
- data/lib/rspec/sleeping_king_studios/matchers/active_model/have_errors/require.rb +7 -0
- data/lib/rspec/sleeping_king_studios/matchers/active_model/require.rb +8 -0
- data/lib/rspec/sleeping_king_studios/matchers/base_matcher.rb +43 -0
- data/lib/rspec/sleeping_king_studios/matchers/built_in.rb +5 -0
- data/lib/rspec/sleeping_king_studios/matchers/built_in/be_kind_of.rb +68 -0
- data/lib/rspec/sleeping_king_studios/matchers/built_in/include.rb +92 -0
- data/lib/rspec/sleeping_king_studios/matchers/built_in/require.rb +7 -0
- data/lib/rspec/sleeping_king_studios/matchers/built_in/respond_to.rb +187 -0
- data/lib/rspec/sleeping_king_studios/matchers/core.rb +5 -0
- data/lib/rspec/sleeping_king_studios/matchers/core/be_boolean.rb +41 -0
- data/lib/rspec/sleeping_king_studios/matchers/core/construct.rb +138 -0
- data/lib/rspec/sleeping_king_studios/matchers/core/have_property.rb +84 -0
- data/lib/rspec/sleeping_king_studios/matchers/core/have_reader.rb +76 -0
- data/lib/rspec/sleeping_king_studios/matchers/core/have_writer.rb +101 -0
- data/lib/rspec/sleeping_king_studios/matchers/core/require.rb +7 -0
- data/lib/rspec/sleeping_king_studios/matchers/meta.rb +5 -0
- data/lib/rspec/sleeping_king_studios/matchers/meta/fail_with_actual.rb +142 -0
- data/lib/rspec/sleeping_king_studios/matchers/meta/pass_with_actual.rb +96 -0
- data/lib/rspec/sleeping_king_studios/matchers/meta/require.rb +7 -0
- data/lib/rspec/sleeping_king_studios/matchers/require.rb +12 -0
- data/lib/rspec/sleeping_king_studios/matchers/shared/match_parameters.rb +69 -0
- data/lib/rspec/sleeping_king_studios/matchers/shared/require.rb +7 -0
- data/lib/rspec/sleeping_king_studios/mocks/custom_double.rb +13 -0
- data/lib/rspec/sleeping_king_studios/require.rb +7 -0
- data/lib/rspec/sleeping_king_studios/version.rb +7 -0
- metadata +151 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a201081c88d39452f78afa3150316e817901a52d
|
4
|
+
data.tar.gz: 1ea674d3e88024e1d945b17e1ecd10d5c09d722a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ee4bdd1817d0d128b1e30304be501c63990545464bb7fa69dc272939073f487f26e5c32480aa7d00324c4d32d24a2cbc27738bb8ec374a671801ff09c03c1756
|
7
|
+
data.tar.gz: 8003b45634d319d7619a712dfece3d51df24e91394c294667e64e26e73770a2b99d6ae8986ded60be8902a055f5829a1fc25777d16f5a281d8ec2a404a47b523
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
(The MIT License)
|
2
|
+
|
3
|
+
Copyright (c) 2013 Rob Smith
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,323 @@
|
|
1
|
+
# RSpec::SleepingKingStudios
|
2
|
+
|
3
|
+
A collection of matchers and extensions to ease TDD/BDD using RSpec.
|
4
|
+
|
5
|
+
## The Extensions
|
6
|
+
|
7
|
+
To enable an extension, simply require the associated file.
|
8
|
+
|
9
|
+
### Mocks
|
10
|
+
|
11
|
+
These extensions support the creation and use of mock objects.
|
12
|
+
|
13
|
+
#### custom\_double
|
14
|
+
|
15
|
+
require 'rspec/sleeping_king_studios/mocks/custom_double'
|
16
|
+
|
17
|
+
As the built-in 'double' method, but accepts a block that is passed to
|
18
|
+
Class.new when the double is created, allowing you to create functional class
|
19
|
+
and instance methods on the double. Useful when you need to test a function or
|
20
|
+
sequence that repeatedly updates or checks the state of the injected object.
|
21
|
+
|
22
|
+
**How To Use:**
|
23
|
+
|
24
|
+
custom_double('My Double', :foo => "Foo") { attr_accessor :bar }
|
25
|
+
|
26
|
+
## The Matchers
|
27
|
+
|
28
|
+
To enable a custom matcher, simply require the associated file. Matchers can be
|
29
|
+
required individually or by category:
|
30
|
+
|
31
|
+
require 'rspec/sleeping_king_studios/matchers/core'
|
32
|
+
#=> requires all of the core matchers
|
33
|
+
|
34
|
+
require 'rspec/sleeping_king_studios/matchers/core/construct'
|
35
|
+
#=> requires only the :construct matcher
|
36
|
+
|
37
|
+
### ActiveModel
|
38
|
+
|
39
|
+
require 'rspec/sleeping_king_studios/matchers/active_model'
|
40
|
+
|
41
|
+
These matchers validate ActiveModel functionality, such as validations.
|
42
|
+
|
43
|
+
#### have\_errors Matcher
|
44
|
+
|
45
|
+
require 'rspec/sleeping_king_studios/matchers/active_model/have_errors'
|
46
|
+
|
47
|
+
Verifies that the actual object has validation errors. Optionally can specify
|
48
|
+
individual fields to validate, or even specific messages for each attribute.
|
49
|
+
|
50
|
+
**How To Use:**
|
51
|
+
|
52
|
+
expect(instance).to have_errors
|
53
|
+
|
54
|
+
expect(instance).to have_errors.on(:name)
|
55
|
+
|
56
|
+
expect(instance).to have_errors.on(:name).with_message('not to be nil')
|
57
|
+
|
58
|
+
**Chaining:**
|
59
|
+
|
60
|
+
* **on:** [String, Symbol] Adds a field to validate; the matcher only passes if
|
61
|
+
all validated fields have errors.
|
62
|
+
* **with\_message:** [String] Adds a message to the previously-defined field
|
63
|
+
validation. Raises ArgumentError if no field was previously set.
|
64
|
+
|
65
|
+
### BuiltIn
|
66
|
+
|
67
|
+
require 'rspec/sleeping_king_studios/matchers/built_in'
|
68
|
+
|
69
|
+
These extend the built-in RSpec matchers with additional functionality.
|
70
|
+
|
71
|
+
#### be\_kind\_of Matcher
|
72
|
+
|
73
|
+
require 'rspec/sleeping_king_studios/matchers/built_in/be_kind_of'
|
74
|
+
|
75
|
+
Now accepts an Array of types. The matcher passes if the actual object is
|
76
|
+
any of the parameter types.
|
77
|
+
|
78
|
+
Also allows nil parameter as a shortcut for NilClass.
|
79
|
+
|
80
|
+
**How To Use:**
|
81
|
+
|
82
|
+
expect(instance).to be_kind_of [String, Symbol, nil]
|
83
|
+
#=> passes iff instance is a String, a Symbol, or is nil
|
84
|
+
|
85
|
+
#### include Matcher
|
86
|
+
|
87
|
+
require 'rspec/sleeping_king_studios/matchers/built_in/include'
|
88
|
+
|
89
|
+
Now accepts Proc parameters; items in the actual object are passed into
|
90
|
+
proc#call, with a truthy response considered a match to the item. In addition,
|
91
|
+
now accepts an optional block as a shortcut for adding a proc expectation.
|
92
|
+
|
93
|
+
**How To Use:**
|
94
|
+
|
95
|
+
expect(instance).to include { |item| item =~ /pattern/ }
|
96
|
+
|
97
|
+
#### respond\_to Matcher
|
98
|
+
|
99
|
+
require 'rspec/sleeping_king_studios/matchers/built_in/respond_to'
|
100
|
+
|
101
|
+
Now has additional chaining functionality to validate the number of arguments
|
102
|
+
accepted by the method, and whether the method accepts a block argument.
|
103
|
+
|
104
|
+
**How To Use:**
|
105
|
+
|
106
|
+
expect(instance).to respond_to(:foo).with(2..3).arguments.and.a_block
|
107
|
+
|
108
|
+
**Chaining:**
|
109
|
+
|
110
|
+
* **a\_block:** No parameters. Verifies that the method requires a block
|
111
|
+
argument of the form &my_argument. _Important note:_ A negative result does
|
112
|
+
_not* mean the method cannot accept a block, merely that it does not require
|
113
|
+
one. Also, does _not_ check whether the block is called or yielded.
|
114
|
+
* **with:** Expects one Integer or Range argument. If an Integer, verifies that
|
115
|
+
the method accepts that number of arguments; if a Range, verifies that the
|
116
|
+
method accepts both the minimum and maximum number of arguments.
|
117
|
+
|
118
|
+
##### Ruby 2.0
|
119
|
+
|
120
|
+
Has additional functionality to support Ruby 2.0 keyword arguments.
|
121
|
+
|
122
|
+
**How To Use:**
|
123
|
+
expect(instance).to respond_to(:foo).with(0, :bar, :baz)
|
124
|
+
|
125
|
+
**Chaining:**
|
126
|
+
|
127
|
+
* **with:** Expects one Integer, Range, or nil argument, and zero or more
|
128
|
+
Symbol arguments corresponding to optional keywords. Verifies that the method
|
129
|
+
accepts that keyword, or has a variadic keyword of the form \*\*params.
|
130
|
+
|
131
|
+
_Important note:_ If you do not wish to validate the number of arguments,
|
132
|
+
make sure to use nil as the first argument to #with; otherwise, the matcher
|
133
|
+
will interpret your first keyword as the number of arguments to expect. And
|
134
|
+
then explode.
|
135
|
+
|
136
|
+
### Core
|
137
|
+
|
138
|
+
require 'rspec/sleeping_king_studios/matchers/core'
|
139
|
+
|
140
|
+
These matchers check core functionality, such as object boolean-ness, the
|
141
|
+
existence of properties, and so on.
|
142
|
+
|
143
|
+
#### be_boolean Matcher
|
144
|
+
|
145
|
+
require 'rspec/sleeping_king_studios/matchers/core/be_boolean'
|
146
|
+
|
147
|
+
Checks if the provided object is true or false.
|
148
|
+
|
149
|
+
**How To Use:**
|
150
|
+
|
151
|
+
expect(object).to be_boolean
|
152
|
+
|
153
|
+
**Parameters:** None.
|
154
|
+
|
155
|
+
#### construct Matcher
|
156
|
+
|
157
|
+
require 'rspec/sleeping_king_studios/matchers/core/construct'
|
158
|
+
|
159
|
+
Verifies that the actual object can be constructed using :new. Can take an
|
160
|
+
optional number of arguments.
|
161
|
+
|
162
|
+
**How To Use:**
|
163
|
+
|
164
|
+
expect(described_class).to construct.with(1).arguments
|
165
|
+
|
166
|
+
**Parameters:** None.
|
167
|
+
|
168
|
+
**Chaining:**
|
169
|
+
|
170
|
+
* **with:** Expects one Integer or Range argument. If an Integer, verifies that
|
171
|
+
the class's constructor accepts that number of arguments; if a Range,
|
172
|
+
verifies that the constructor accepts both the minimum and maximum number of
|
173
|
+
arguments.
|
174
|
+
|
175
|
+
##### Ruby 2.0
|
176
|
+
|
177
|
+
Has additional functionality to support Ruby 2.0 keyword arguments.
|
178
|
+
|
179
|
+
**How To Use:**
|
180
|
+
expect(instance).to construct.with(0, :bar, :baz)
|
181
|
+
|
182
|
+
**Chaining:**
|
183
|
+
|
184
|
+
* **with:** Expects one Integer, Range, or nil argument, and zero or more
|
185
|
+
Symbol arguments corresponding to optional keywords. Verifies that the
|
186
|
+
class's constructor accepts that keyword, or has a variadic keyword of the
|
187
|
+
form \*\*params.
|
188
|
+
|
189
|
+
_Important note:_ If you do not wish to validate the number of arguments,
|
190
|
+
make sure to use nil as the first argument to #with; otherwise, the matcher
|
191
|
+
will interpret your first keyword as the number of arguments to expect. And
|
192
|
+
then explode.
|
193
|
+
|
194
|
+
#### have\_property Matcher
|
195
|
+
|
196
|
+
require 'rspec/sleeping_king_studios/matchers/core/have_property'
|
197
|
+
|
198
|
+
Checks if the actual object responds to :property and :property=, and
|
199
|
+
optionally if a value written to actual.property= can then be read by
|
200
|
+
actual.property.
|
201
|
+
|
202
|
+
**How To Use:**
|
203
|
+
|
204
|
+
expect(instance).to have_property(:foo).with("foo")
|
205
|
+
|
206
|
+
**Parameters:** Property. Expects a string or symbol that is a valid
|
207
|
+
identifier.
|
208
|
+
|
209
|
+
**Chaining:**
|
210
|
+
|
211
|
+
* **with:** Expects one object, which is written to actual.property= and then
|
212
|
+
read from actual.property.
|
213
|
+
|
214
|
+
#### have\_reader Matcher
|
215
|
+
|
216
|
+
require 'rspec/sleeping_king_studios/matchers/core/have_reader'
|
217
|
+
|
218
|
+
Checks if the actual object responds to :property, and optionally if the
|
219
|
+
current value of actual.property is equal to a specified value.
|
220
|
+
|
221
|
+
**How To Use:**
|
222
|
+
|
223
|
+
expect(instance).to have_reader(:foo).with("foo")
|
224
|
+
|
225
|
+
**Parameters:** Property. Expects a string or symbol that is a valid
|
226
|
+
identifier.
|
227
|
+
|
228
|
+
**Chaining:**
|
229
|
+
|
230
|
+
* **with:** Expects one object, which is checked against the current value of
|
231
|
+
actual.property if actual responds to :property.
|
232
|
+
|
233
|
+
#### have\_writer Matcher
|
234
|
+
|
235
|
+
require 'rspec/sleeping_king_studios/matchers/core/have_writer'
|
236
|
+
|
237
|
+
Checks if the actual object responds to :property=, and optionally if setting
|
238
|
+
object.property = value sets object.property to value.
|
239
|
+
|
240
|
+
**How To Use:**
|
241
|
+
|
242
|
+
expect(instance).to have_writer(:foo=).with("foo")
|
243
|
+
|
244
|
+
**Parameters:** Property. Expects a string or symbol that is a valid
|
245
|
+
identifier. An equals sign '=' is automatically added if the identifier does
|
246
|
+
not already terminate in '='.
|
247
|
+
|
248
|
+
**Chaining:**
|
249
|
+
|
250
|
+
* **with:** Expects one object. The matcher attempts to set the actual's value
|
251
|
+
using actual.property=, then compare the value with actual.property.
|
252
|
+
|
253
|
+
_Note:_ Currently, write-only properties cannot be checked using with().
|
254
|
+
Attempting to do so will raise an exception.
|
255
|
+
|
256
|
+
#### include\_matching Matcher
|
257
|
+
|
258
|
+
require 'rspec/sleeping_king_studios/matchers/core/include_matching'
|
259
|
+
|
260
|
+
Loops through an enumerable actual object and checks if any of the items
|
261
|
+
matches the given pattern.
|
262
|
+
|
263
|
+
**How To Use:**
|
264
|
+
|
265
|
+
expect(instance).to include_matching(/[01]+/)
|
266
|
+
|
267
|
+
**Parameters:** Pattern. Expects a Regexp.
|
268
|
+
|
269
|
+
### Meta
|
270
|
+
|
271
|
+
require 'rspec/sleeping_king_studios/matchers/meta'
|
272
|
+
|
273
|
+
These meta-matchers are used to test other custom matchers.
|
274
|
+
|
275
|
+
#### fail\_with\_actual Matcher
|
276
|
+
|
277
|
+
require 'rspec/sleeping_king_studios/matchers/meta/fail_with_actual'
|
278
|
+
|
279
|
+
Checks if the given matcher will fail to match a specified actual object. Can
|
280
|
+
take an optional string to check the expected failure message when the matcher
|
281
|
+
is expected to pass, but does not.
|
282
|
+
|
283
|
+
_Note:_ Do not use the not\_to syntax for this matcher; instead, use the
|
284
|
+
pass\_with\_actual matcher, below.
|
285
|
+
|
286
|
+
**How To Use:**
|
287
|
+
|
288
|
+
expect(matcher).to fail_with_actual(actual).with_message(/expected to/)
|
289
|
+
|
290
|
+
**Parameters:** Matcher. Expects an object that, at minimum, responds to
|
291
|
+
:matches? and :failure\_message\_for\_should.
|
292
|
+
|
293
|
+
**Chaining:**
|
294
|
+
|
295
|
+
* **with\_message:** Expects one String or Regexp argument, which is matched
|
296
|
+
against the given matcher's failure\_message\_for\_should.
|
297
|
+
|
298
|
+
#### pass\_with\_actual Matcher
|
299
|
+
|
300
|
+
require 'rspec/sleeping_king_studios/matchers/meta/pass_with_actual'
|
301
|
+
|
302
|
+
Checks if the given matcher will match a specified actual object. Can take an
|
303
|
+
optional string to check the expected failure message when the matcher is
|
304
|
+
expected to fail, but does not.
|
305
|
+
|
306
|
+
_Note:_ Do not use the not\_to syntax for this matcher; instead, use the
|
307
|
+
fail\_with\_actual matcher, above.
|
308
|
+
|
309
|
+
**How To Use:**
|
310
|
+
|
311
|
+
expect(matcher).to pass_with_actual(actual)
|
312
|
+
|
313
|
+
**Parameters:** Matcher. Expects an object that, at minimum, responds to
|
314
|
+
:matches? and :failure\_message\_for\_should\_not.
|
315
|
+
|
316
|
+
**Chaining:**
|
317
|
+
|
318
|
+
* **with\_message:** Expects one String or Regexp argument, which is matched
|
319
|
+
against the given matcher's failure\_message\_for\_should\_not.
|
320
|
+
|
321
|
+
## License
|
322
|
+
|
323
|
+
RSpec::SleepingKingStudios is released under the [MIT License](http://www.opensource.org/licenses/MIT).
|
@@ -0,0 +1,219 @@
|
|
1
|
+
# lib/rspec/sleeping_king_studios/matchers/active_model/have_errors.rb
|
2
|
+
|
3
|
+
require 'rspec/sleeping_king_studios/matchers/base_matcher'
|
4
|
+
require 'rspec/sleeping_king_studios/matchers/active_model/require'
|
5
|
+
require 'rspec/sleeping_king_studios/matchers/active_model/have_errors/error_expectation'
|
6
|
+
|
7
|
+
module RSpec::SleepingKingStudios::Matchers::ActiveModel
|
8
|
+
# Matcher for testing ActiveModel object validations.
|
9
|
+
#
|
10
|
+
# @since 1.0.0
|
11
|
+
class HaveErrorsMatcher < RSpec::SleepingKingStudios::Matchers::BaseMatcher
|
12
|
+
include RSpec::SleepingKingStudios::Matchers::ActiveModel::HaveErrors
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
super
|
16
|
+
|
17
|
+
# The error and message expectations set up through #on and
|
18
|
+
# #with_message.
|
19
|
+
@error_expectations = []
|
20
|
+
end # constructor
|
21
|
+
|
22
|
+
# Checks if the object can be validated, whether the object is valid, and
|
23
|
+
# checks the errors on the object against the expected errors and messages
|
24
|
+
# from #on and #with_message, if any.
|
25
|
+
#
|
26
|
+
# @param [Object] actual the object to test against the matcher
|
27
|
+
#
|
28
|
+
# @return [Boolean] true if the object responds to :valid?, is not valid,
|
29
|
+
# and object.errors matches the specified errors and messages (if any);
|
30
|
+
# otherwise false
|
31
|
+
# @see RSpec::SleepingKingStudios::Matchers::BaseMatcher#matches?
|
32
|
+
def matches? actual
|
33
|
+
super
|
34
|
+
|
35
|
+
return false unless @validates = actual.respond_to?(:valid?)
|
36
|
+
|
37
|
+
@actual.invalid? && attributes_have_errors?
|
38
|
+
end # method matches?
|
39
|
+
|
40
|
+
# Adds an error expectation. If the actual object does not have an error on
|
41
|
+
# the specified attribute, #matches? will return false.
|
42
|
+
#
|
43
|
+
# @param [String, Symbol] attribute
|
44
|
+
#
|
45
|
+
# @return [HaveErrorsMatcher] self
|
46
|
+
#
|
47
|
+
# @example Setting an error expectation
|
48
|
+
# expect(actual).to have_errors.on(:foo)
|
49
|
+
def on attribute
|
50
|
+
@error_expectations << ErrorExpectation.new(attribute)
|
51
|
+
|
52
|
+
self
|
53
|
+
end # method on
|
54
|
+
|
55
|
+
# Adds a message expectation for the most recently added error attribute.
|
56
|
+
# If the actual object does not have an error on the that attribute with
|
57
|
+
# the specified message, #matches? will return false.
|
58
|
+
#
|
59
|
+
# @param [String, Regexp] message the expected error message. If a string,
|
60
|
+
# matcher will check for an exact match; if a regular expression, matcher
|
61
|
+
# will check if the message matches the regexp
|
62
|
+
#
|
63
|
+
# @raise [ArgumentError] if no error attribute has been added
|
64
|
+
#
|
65
|
+
# @return [HaveErrorsMatcher] self
|
66
|
+
#
|
67
|
+
# @example Setting an error and a message expectation
|
68
|
+
# expect(actual).to have_errors.on(:foo).with("can't be blank")
|
69
|
+
#
|
70
|
+
# @see #on
|
71
|
+
def with_message message
|
72
|
+
raise ArgumentError.new "no attribute specified for error message" if
|
73
|
+
@error_expectations.empty?
|
74
|
+
|
75
|
+
@error_expectations.last.messages << MessageExpectation.new(message)
|
76
|
+
|
77
|
+
self
|
78
|
+
end # method with_message
|
79
|
+
|
80
|
+
# Adds a set of message expectations for the most recently added error
|
81
|
+
# attribute.
|
82
|
+
#
|
83
|
+
# @param [Array<String, Regexp>] messages
|
84
|
+
#
|
85
|
+
# @see #with_message
|
86
|
+
def with_messages *messages
|
87
|
+
messages.each do |message| self.with_message(message); end
|
88
|
+
|
89
|
+
self
|
90
|
+
end # method with_message
|
91
|
+
|
92
|
+
# @see BaseMatcher#failure_message_for_should
|
93
|
+
def failure_message_for_should
|
94
|
+
# Failure cases:
|
95
|
+
# * object is not a model ("to respond to valid")
|
96
|
+
# * expected one or more errors, but received none ("to have errors")
|
97
|
+
# * expected one or more messages on :attribute, but received none or a
|
98
|
+
# subset ("to have errors on")
|
99
|
+
|
100
|
+
if !@validates
|
101
|
+
"expected #{@actual.inspect} to respond to :valid?"
|
102
|
+
elsif expected_errors.empty?
|
103
|
+
"expected #{@actual.inspect} to have errors"
|
104
|
+
else
|
105
|
+
"expected #{@actual.inspect} to have errors#{expected_errors_message}#{received_errors_message}"
|
106
|
+
end # if-elsif-else
|
107
|
+
end # method failure_message_for_should
|
108
|
+
|
109
|
+
# @see BaseMatcher#failure_message_for_should_not
|
110
|
+
def failure_message_for_should_not
|
111
|
+
# Failure cases:
|
112
|
+
# * expected one or more errors, received one or more ("not to have
|
113
|
+
# errors")
|
114
|
+
# * expected one or more messages on attribute, received one or more
|
115
|
+
# ("not to have errors on")
|
116
|
+
# * expected specific messages on attribute, received all ("not to have
|
117
|
+
# errors on")
|
118
|
+
|
119
|
+
if expected_errors.empty?
|
120
|
+
return "expected #{@actual.inspect} not to have errors#{received_errors_message}"
|
121
|
+
else
|
122
|
+
return "expected #{@actual.inspect} not to have errors#{expected_errors_message}#{received_errors_message}"
|
123
|
+
end # if-else
|
124
|
+
end # method failure_message_for_should_not
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
def attributes_have_errors?
|
129
|
+
# Iterate through the received errors and match them against the expected
|
130
|
+
# errors and messages.
|
131
|
+
@actual.errors.messages.each do |attribute, messages|
|
132
|
+
# Find the matching error expectation, if any.
|
133
|
+
error_expectation = @error_expectations.detect do |error_expectation|
|
134
|
+
error_expectation.attribute == attribute
|
135
|
+
end # detect
|
136
|
+
|
137
|
+
if error_expectation
|
138
|
+
error_expectation.received = true
|
139
|
+
|
140
|
+
# If the error includes message expectations, iterate through the
|
141
|
+
# received messages.
|
142
|
+
unless error_expectation.messages.empty?
|
143
|
+
messages.each do |message|
|
144
|
+
# Find the matching message expectation, if any.
|
145
|
+
message_expectation = error_expectation.messages.detect do |message_expectation|
|
146
|
+
if Regexp === message_expectation.message
|
147
|
+
message =~ message_expectation.message
|
148
|
+
else
|
149
|
+
message == message_expectation.message
|
150
|
+
end # if-else
|
151
|
+
end # detect
|
152
|
+
|
153
|
+
if message_expectation
|
154
|
+
message_expectation.received = true
|
155
|
+
else
|
156
|
+
error_expectation.messages << MessageExpectation.new(message, false, true)
|
157
|
+
end # if-else
|
158
|
+
end # each
|
159
|
+
end # unless
|
160
|
+
else
|
161
|
+
error_expectation = ErrorExpectation.new attribute, false, true
|
162
|
+
messages.each do |message|
|
163
|
+
error_expectation.messages << MessageExpectation.new(message, false, true)
|
164
|
+
end # each
|
165
|
+
|
166
|
+
@error_expectations << error_expectation
|
167
|
+
end # if-else
|
168
|
+
end # each
|
169
|
+
|
170
|
+
missing_errors.empty? && missing_messages.empty?
|
171
|
+
end # method attributes_have_errors
|
172
|
+
|
173
|
+
def expected_errors
|
174
|
+
@error_expectations.select do |error_expectation|
|
175
|
+
error_expectation.expected
|
176
|
+
end # select
|
177
|
+
end # method expected_errors
|
178
|
+
|
179
|
+
def missing_errors
|
180
|
+
@error_expectations.select do |error_expectation|
|
181
|
+
error_expectation.expected && !error_expectation.received
|
182
|
+
end # select
|
183
|
+
end # method missing_errors
|
184
|
+
|
185
|
+
def missing_messages
|
186
|
+
@error_expectations.select do |error_expectation|
|
187
|
+
!error_expectation.messages.missing.empty?
|
188
|
+
end # select
|
189
|
+
end # method missing_messages
|
190
|
+
|
191
|
+
def unexpected_errors
|
192
|
+
@error_expectations.select do |error_expectation|
|
193
|
+
!error_expectation.expected && error_expectation.received
|
194
|
+
end # select
|
195
|
+
end # method unexpected_errors
|
196
|
+
|
197
|
+
def expected_errors_message
|
198
|
+
"\n expected errors:" + expected_errors.map do |error_expectation|
|
199
|
+
"\n #{error_expectation.attribute}: " + (error_expectation.messages.empty? ?
|
200
|
+
"(any)" :
|
201
|
+
error_expectation.messages.expected.map(&:message).map(&:inspect).join(", "))
|
202
|
+
end.join # map
|
203
|
+
end # method expected_errors_message
|
204
|
+
|
205
|
+
def received_errors_message
|
206
|
+
return "" unless @validates
|
207
|
+
"\n received errors:" + @actual.errors.messages.map do |attr, ary|
|
208
|
+
"\n #{attr}: " + ary.map(&:inspect).join(", ")
|
209
|
+
end.join # map
|
210
|
+
end # method received_errors_message
|
211
|
+
end # class
|
212
|
+
|
213
|
+
module RSpec::SleepingKingStudios::Matchers
|
214
|
+
# @see RSpec::SleepingKingStudios::Matchers::ActiveModel::HaveErrorsMatcher#matches?
|
215
|
+
def have_errors
|
216
|
+
RSpec::SleepingKingStudios::Matchers::ActiveModel::HaveErrorsMatcher.new
|
217
|
+
end # method have_errors
|
218
|
+
end # module
|
219
|
+
end # module
|