rspec-expectations 2.12.0 → 2.12.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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...2.12.0)
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"
@@ -2,7 +2,7 @@ module RSpec
2
2
  module Expectations
3
3
  # @private
4
4
  module Version
5
- STRING = '2.12.0'
5
+ STRING = '2.12.1'
6
6
  end
7
7
  end
8
8
  end
@@ -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(Array, '=~', BuiltIn::MatchArray)
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
- registry[klass] && registry[klass][operator]
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
- version: 2.12.0
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
- date: 2012-11-13 00:00:00.000000000 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: diff-lcs
17
- requirement: !ruby/object:Gem::Requirement
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
- version_requirements: !ruby/object:Gem::Requirement
26
- none: false
27
- requirements:
28
- - - ~>
29
- - !ruby/object:Gem::Version
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
- prerelease: false
57
- version_requirements: !ruby/object:Gem::Requirement
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
- version_requirements: !ruby/object:Gem::Requirement
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
- files:
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
- version: '0'
227
- segments:
232
+ requirements:
233
+ - - ">="
234
+ - !ruby/object:Gem::Version
235
+ hash: 3
236
+ segments:
228
237
  - 0
229
- hash: -3915124233678140450
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
- version: '0'
236
- segments:
241
+ requirements:
242
+ - - ">="
243
+ - !ruby/object:Gem::Version
244
+ hash: 3
245
+ segments:
237
246
  - 0
238
- hash: -3915124233678140450
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.0
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