rspec-expectations 2.12.0 → 2.12.1
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.
- data/Changelog.md +13 -1
- data/features/custom_matchers/define_matcher.feature +28 -0
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/matchers.rb +19 -9
- data/lib/rspec/matchers/operator_matcher.rb +27 -2
- data/spec/rspec/matchers/match_array_spec.rb +15 -0
- data/spec/rspec/matchers/operator_matcher_spec.rb +23 -0
- metadata +84 -74
data/Changelog.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
|
+
### 2.12.1 / 2012-12-15
|
2
|
+
[full changelog](http://github.com/rspec/rspec-expectations/compare/v2.12.0...v2.12.1)
|
3
|
+
|
4
|
+
Bug fixes
|
5
|
+
|
6
|
+
* Improve the failure message for an expression like
|
7
|
+
`{}.should =~ {}`. (Myron Marston and Andy Lindeman)
|
8
|
+
* Provide a `match_regex` alias so that custom matchers
|
9
|
+
built using the matcher DSL can use it (since `match`
|
10
|
+
is a different method in that context).
|
11
|
+
(Steven Harman)
|
12
|
+
|
1
13
|
### 2.12.0 / 2012-11-12
|
2
|
-
[full changelog](http://github.com/rspec/rspec-expectations/compare/v2.11.3...
|
14
|
+
[full changelog](http://github.com/rspec/rspec-expectations/compare/v2.11.3...v2.12.0)
|
3
15
|
|
4
16
|
Enhancements
|
5
17
|
|
@@ -338,3 +338,31 @@ Feature: define matcher
|
|
338
338
|
| 4 examples, 2 failures |
|
339
339
|
| expected 9 to be a multiple of 2 |
|
340
340
|
| expected 9 not to be a multiple of 3 |
|
341
|
+
|
342
|
+
Scenario: matching against a regular expression
|
343
|
+
Given a file named "regular_expression_matcher_spec.rb" with:
|
344
|
+
"""ruby
|
345
|
+
# Due to Ruby's method dispatch mechanism, use the `#match_regex` alias
|
346
|
+
# rather than the `#match` matcher when defining custom matchers via the
|
347
|
+
# DSL.
|
348
|
+
|
349
|
+
RSpec::Matchers.define :be_valid_us_zipcode do
|
350
|
+
match do |actual|
|
351
|
+
expect(actual).to match_regex(/\A\d{5}(-\d{4})?\z/)
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
describe "30316" do
|
356
|
+
it { should be_valid_us_zipcode }
|
357
|
+
end
|
358
|
+
|
359
|
+
describe "30316-0001" do
|
360
|
+
it { should be_valid_us_zipcode }
|
361
|
+
end
|
362
|
+
|
363
|
+
describe "1000-61303" do
|
364
|
+
it { should_not be_valid_us_zipcode }
|
365
|
+
end
|
366
|
+
"""
|
367
|
+
When I run `rspec regular_expression_matcher_spec.rb`
|
368
|
+
Then the stdout should contain "3 examples, 0 failures"
|
data/lib/rspec/matchers.rb
CHANGED
@@ -214,7 +214,7 @@ module RSpec
|
|
214
214
|
#
|
215
215
|
# Given true, false, or nil, will pass if actual value is true, false or
|
216
216
|
# nil (respectively). Given no args means the caller should satisfy an if
|
217
|
-
# condition (to be or not to be).
|
217
|
+
# condition (to be or not to be).
|
218
218
|
#
|
219
219
|
# Predicates are any Ruby method that ends in a "?" and returns true or
|
220
220
|
# false. Given be_ followed by arbitrary_predicate (without the "?"),
|
@@ -246,7 +246,7 @@ module RSpec
|
|
246
246
|
def be_an_instance_of(expected)
|
247
247
|
BuiltIn::BeAnInstanceOf.new(expected)
|
248
248
|
end
|
249
|
-
|
249
|
+
|
250
250
|
alias_method :be_instance_of, :be_an_instance_of
|
251
251
|
|
252
252
|
# Passes if actual.kind_of?(expected)
|
@@ -288,20 +288,20 @@ module RSpec
|
|
288
288
|
# @example
|
289
289
|
#
|
290
290
|
# lambda {
|
291
|
-
# team.add_player(player)
|
291
|
+
# team.add_player(player)
|
292
292
|
# }.should change(roster, :count)
|
293
293
|
#
|
294
294
|
# lambda {
|
295
|
-
# team.add_player(player)
|
295
|
+
# team.add_player(player)
|
296
296
|
# }.should change(roster, :count).by(1)
|
297
297
|
#
|
298
298
|
# lambda {
|
299
|
-
# team.add_player(player)
|
299
|
+
# team.add_player(player)
|
300
300
|
# }.should change(roster, :count).by_at_least(1)
|
301
301
|
#
|
302
302
|
# lambda {
|
303
303
|
# team.add_player(player)
|
304
|
-
# }.should change(roster, :count).by_at_most(1)
|
304
|
+
# }.should change(roster, :count).by_at_most(1)
|
305
305
|
#
|
306
306
|
# string = "string"
|
307
307
|
# lambda {
|
@@ -311,7 +311,7 @@ module RSpec
|
|
311
311
|
# lambda {
|
312
312
|
# person.happy_birthday
|
313
313
|
# }.should change(person, :birthday).from(32).to(33)
|
314
|
-
#
|
314
|
+
#
|
315
315
|
# lambda {
|
316
316
|
# employee.develop_great_new_social_networking_app
|
317
317
|
# }.should change(employee, :title).from("Mail Clerk").to("CEO")
|
@@ -491,10 +491,20 @@ module RSpec
|
|
491
491
|
#
|
492
492
|
# email.should match(/^([^\s]+)((?:[-a-z0-9]+\.)+[a-z]{2,})$/i)
|
493
493
|
# email.should match("@example.com")
|
494
|
+
# zipcode.should match_regex(/\A\d{5}(-\d{4})?\z/)
|
495
|
+
# zipcode.should match_regex("90210")
|
496
|
+
#
|
497
|
+
# @note Due to Ruby's method dispatch mechanism, using the `#match` matcher
|
498
|
+
# within a custom matcher defined via the matcher DSL
|
499
|
+
# (`RSpec::Matcher.define`) will result Ruby calling the wrong `#match`
|
500
|
+
# method and raising an `ArgumentError`. Instead, use the aliased
|
501
|
+
# `#match_regex` method.
|
494
502
|
def match(expected)
|
495
503
|
BuiltIn::Match.new(expected)
|
496
504
|
end
|
497
505
|
|
506
|
+
alias_method :match_regex, :match
|
507
|
+
|
498
508
|
# With no args, matches if any error is raised.
|
499
509
|
# With a named error, matches only if that specific error is raised.
|
500
510
|
# With a named error and messsage specified as a String, matches only if both match.
|
@@ -523,7 +533,7 @@ module RSpec
|
|
523
533
|
# provided. Names can be Strings or Symbols.
|
524
534
|
#
|
525
535
|
# @example
|
526
|
-
#
|
536
|
+
#
|
527
537
|
def respond_to(*names)
|
528
538
|
BuiltIn::RespondTo.new(*names)
|
529
539
|
end
|
@@ -684,6 +694,6 @@ module RSpec
|
|
684
694
|
BuiltIn::MatchArray.new(array)
|
685
695
|
end
|
686
696
|
|
687
|
-
OperatorMatcher.register(
|
697
|
+
OperatorMatcher.register(Enumerable, '=~', BuiltIn::MatchArray)
|
688
698
|
end
|
689
699
|
end
|
@@ -11,8 +11,17 @@ module RSpec
|
|
11
11
|
registry[klass][operator] = matcher
|
12
12
|
end
|
13
13
|
|
14
|
+
def unregister(klass, operator)
|
15
|
+
registry[klass] && registry[klass].delete(operator)
|
16
|
+
end
|
17
|
+
|
14
18
|
def get(klass, operator)
|
15
|
-
|
19
|
+
klass.ancestors.each { |ancestor|
|
20
|
+
matcher = registry[ancestor] && registry[ancestor][operator]
|
21
|
+
return matcher if matcher
|
22
|
+
}
|
23
|
+
|
24
|
+
nil
|
16
25
|
end
|
17
26
|
end
|
18
27
|
|
@@ -22,7 +31,7 @@ module RSpec
|
|
22
31
|
|
23
32
|
def self.use_custom_matcher_or_delegate(operator)
|
24
33
|
define_method(operator) do |expected|
|
25
|
-
if matcher = OperatorMatcher.get(@actual.class, operator)
|
34
|
+
if uses_generic_implementation_of?(operator) && matcher = OperatorMatcher.get(@actual.class, operator)
|
26
35
|
@actual.send(::RSpec::Matchers.last_should, matcher.new(expected))
|
27
36
|
else
|
28
37
|
eval_match(@actual, operator, expected)
|
@@ -53,6 +62,22 @@ module RSpec
|
|
53
62
|
|
54
63
|
private
|
55
64
|
|
65
|
+
if Method.method_defined?(:owner) # 1.8.6 lacks Method#owner :-(
|
66
|
+
def uses_generic_implementation_of?(op)
|
67
|
+
@actual.method(op).owner == ::Kernel
|
68
|
+
end
|
69
|
+
else
|
70
|
+
def uses_generic_implementation_of?(op)
|
71
|
+
# This is a bit of a hack, but:
|
72
|
+
#
|
73
|
+
# {}.method(:=~).to_s # => "#<Method: Hash(Kernel)#=~>"
|
74
|
+
#
|
75
|
+
# In the absence of Method#owner, this is the best we
|
76
|
+
# can do to see if the method comes from Kernel.
|
77
|
+
@actual.method(op).to_s.include?('(Kernel)')
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
56
81
|
def eval_match(actual, operator, expected)
|
57
82
|
::RSpec::Matchers.last_matcher = self
|
58
83
|
@operator, @expected = operator, expected
|
@@ -113,6 +113,17 @@ the missing elements were: [1]
|
|
113
113
|
MESSAGE
|
114
114
|
end
|
115
115
|
|
116
|
+
context "when the array defines a `=~` method" do
|
117
|
+
it 'delegates to that method rather than using the match_array matcher' do
|
118
|
+
array = []
|
119
|
+
def array.=~(other)
|
120
|
+
other == :foo
|
121
|
+
end
|
122
|
+
|
123
|
+
array.should =~ :foo
|
124
|
+
expect { array.should =~ :bar }.to fail_with(/expected: :bar/)
|
125
|
+
end
|
126
|
+
end
|
116
127
|
end
|
117
128
|
|
118
129
|
describe "should_not =~ [:with, :multiple, :args]" do
|
@@ -135,4 +146,8 @@ describe "matching against things that aren't arrays" do
|
|
135
146
|
it "fails with a string and the expected error message is given" do
|
136
147
|
expect { "I like turtles".should match_array([1,2,3]) }.to fail_with(/expected an array/)
|
137
148
|
end
|
149
|
+
|
150
|
+
it 'fails with a clear message when given a hash using the `should =~` syntax' do
|
151
|
+
expect { {}.should =~ {} }.to fail_with(/expected an array/)
|
152
|
+
end
|
138
153
|
end
|
@@ -196,6 +196,29 @@ describe "should <=" do
|
|
196
196
|
|
197
197
|
end
|
198
198
|
|
199
|
+
describe "OperatorMatcher registry" do
|
200
|
+
let(:custom_klass) { Class.new }
|
201
|
+
let(:custom_subklass) { Class.new(custom_klass) }
|
202
|
+
|
203
|
+
after {
|
204
|
+
RSpec::Matchers::OperatorMatcher.unregister(custom_klass, "=~")
|
205
|
+
}
|
206
|
+
|
207
|
+
it "allows operator matchers to be registered for types" do
|
208
|
+
RSpec::Matchers::OperatorMatcher.register(custom_klass, "=~", RSpec::Matchers::BuiltIn::Match)
|
209
|
+
expect(RSpec::Matchers::OperatorMatcher.get(custom_klass, "=~")).to eq(RSpec::Matchers::BuiltIn::Match)
|
210
|
+
end
|
211
|
+
|
212
|
+
it "considers ancestors when finding an operator matcher" do
|
213
|
+
RSpec::Matchers::OperatorMatcher.register(custom_klass, "=~", RSpec::Matchers::BuiltIn::Match)
|
214
|
+
expect(RSpec::Matchers::OperatorMatcher.get(custom_subklass, "=~")).to eq(RSpec::Matchers::BuiltIn::Match)
|
215
|
+
end
|
216
|
+
|
217
|
+
it "returns nil if there is no matcher registered for a type" do
|
218
|
+
expect(RSpec::Matchers::OperatorMatcher.get(custom_klass, "=~")).to be_nil
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
199
222
|
describe RSpec::Matchers::BuiltIn::PositiveOperatorMatcher do
|
200
223
|
|
201
224
|
it "works when the target has implemented #send" do
|
metadata
CHANGED
@@ -1,87 +1,96 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-expectations
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 61
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 2
|
8
|
+
- 12
|
9
|
+
- 1
|
10
|
+
version: 2.12.1
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Steven Baker
|
9
14
|
- David Chelimsky
|
10
15
|
autorequire:
|
11
16
|
bindir: bin
|
12
17
|
cert_chain: []
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
+
|
19
|
+
date: 2012-12-16 00:00:00 Z
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
18
23
|
none: false
|
19
|
-
requirements:
|
24
|
+
requirements:
|
20
25
|
- - ~>
|
21
|
-
- !ruby/object:Gem::Version
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
hash: 21
|
28
|
+
segments:
|
29
|
+
- 1
|
30
|
+
- 1
|
31
|
+
- 3
|
22
32
|
version: 1.1.3
|
23
|
-
type: :runtime
|
24
33
|
prerelease: false
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
version: 1.1.3
|
31
|
-
- !ruby/object:Gem::Dependency
|
32
|
-
name: rake
|
33
|
-
requirement: !ruby/object:Gem::Requirement
|
34
|
+
type: :runtime
|
35
|
+
name: diff-lcs
|
36
|
+
requirement: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
34
39
|
none: false
|
35
|
-
requirements:
|
40
|
+
requirements:
|
36
41
|
- - ~>
|
37
|
-
- !ruby/object:Gem::Version
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 79
|
44
|
+
segments:
|
45
|
+
- 10
|
46
|
+
- 0
|
47
|
+
- 0
|
38
48
|
version: 10.0.0
|
39
|
-
type: :development
|
40
49
|
prerelease: false
|
41
|
-
version_requirements: !ruby/object:Gem::Requirement
|
42
|
-
none: false
|
43
|
-
requirements:
|
44
|
-
- - ~>
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
version: 10.0.0
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: cucumber
|
49
|
-
requirement: !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
|
-
requirements:
|
52
|
-
- - ~>
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 1.1.9
|
55
50
|
type: :development
|
56
|
-
|
57
|
-
|
51
|
+
name: rake
|
52
|
+
requirement: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
58
55
|
none: false
|
59
|
-
requirements:
|
56
|
+
requirements:
|
60
57
|
- - ~>
|
61
|
-
- !ruby/object:Gem::Version
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 1
|
60
|
+
segments:
|
61
|
+
- 1
|
62
|
+
- 1
|
63
|
+
- 9
|
62
64
|
version: 1.1.9
|
63
|
-
- !ruby/object:Gem::Dependency
|
64
|
-
name: aruba
|
65
|
-
requirement: !ruby/object:Gem::Requirement
|
66
|
-
none: false
|
67
|
-
requirements:
|
68
|
-
- - ~>
|
69
|
-
- !ruby/object:Gem::Version
|
70
|
-
version: 0.4.11
|
71
|
-
type: :development
|
72
65
|
prerelease: false
|
73
|
-
|
66
|
+
type: :development
|
67
|
+
name: cucumber
|
68
|
+
requirement: *id003
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
74
71
|
none: false
|
75
|
-
requirements:
|
72
|
+
requirements:
|
76
73
|
- - ~>
|
77
|
-
- !ruby/object:Gem::Version
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
hash: 25
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
- 4
|
79
|
+
- 11
|
78
80
|
version: 0.4.11
|
81
|
+
prerelease: false
|
82
|
+
type: :development
|
83
|
+
name: aruba
|
84
|
+
requirement: *id004
|
79
85
|
description: rspec expectations (should[_not] and matchers)
|
80
86
|
email: rspec-users@rubyforge.org
|
81
87
|
executables: []
|
88
|
+
|
82
89
|
extensions: []
|
90
|
+
|
83
91
|
extra_rdoc_files: []
|
84
|
-
|
92
|
+
|
93
|
+
files:
|
85
94
|
- lib/rspec-expectations.rb
|
86
95
|
- lib/rspec/expectations.rb
|
87
96
|
- lib/rspec/expectations/deprecation.rb
|
@@ -211,38 +220,39 @@ files:
|
|
211
220
|
- spec/support/ruby_version.rb
|
212
221
|
- spec/support/shared_examples.rb
|
213
222
|
homepage: http://github.com/rspec/rspec-expectations
|
214
|
-
licenses:
|
223
|
+
licenses:
|
215
224
|
- MIT
|
216
225
|
post_install_message:
|
217
|
-
rdoc_options:
|
226
|
+
rdoc_options:
|
218
227
|
- --charset=UTF-8
|
219
|
-
require_paths:
|
228
|
+
require_paths:
|
220
229
|
- lib
|
221
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
230
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
222
231
|
none: false
|
223
|
-
requirements:
|
224
|
-
- -
|
225
|
-
- !ruby/object:Gem::Version
|
226
|
-
|
227
|
-
segments:
|
232
|
+
requirements:
|
233
|
+
- - ">="
|
234
|
+
- !ruby/object:Gem::Version
|
235
|
+
hash: 3
|
236
|
+
segments:
|
228
237
|
- 0
|
229
|
-
|
230
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
238
|
+
version: "0"
|
239
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
231
240
|
none: false
|
232
|
-
requirements:
|
233
|
-
- -
|
234
|
-
- !ruby/object:Gem::Version
|
235
|
-
|
236
|
-
segments:
|
241
|
+
requirements:
|
242
|
+
- - ">="
|
243
|
+
- !ruby/object:Gem::Version
|
244
|
+
hash: 3
|
245
|
+
segments:
|
237
246
|
- 0
|
238
|
-
|
247
|
+
version: "0"
|
239
248
|
requirements: []
|
249
|
+
|
240
250
|
rubyforge_project: rspec
|
241
251
|
rubygems_version: 1.8.24
|
242
252
|
signing_key:
|
243
253
|
specification_version: 3
|
244
|
-
summary: rspec-expectations-2.12.
|
245
|
-
test_files:
|
254
|
+
summary: rspec-expectations-2.12.1
|
255
|
+
test_files:
|
246
256
|
- features/README.md
|
247
257
|
- features/Upgrade.md
|
248
258
|
- features/built_in_matchers/README.md
|