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.
@@ -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