rspec-expectations 2.7.0 → 2.8.0.rc1

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 (38) hide show
  1. data/README.md +117 -9
  2. data/lib/rspec/expectations.rb +24 -16
  3. data/lib/rspec/expectations/handler.rb +1 -1
  4. data/lib/rspec/expectations/version.rb +1 -1
  5. data/lib/rspec/matchers.rb +91 -91
  6. data/lib/rspec/matchers/base_matcher.rb +41 -0
  7. data/lib/rspec/matchers/be.rb +31 -12
  8. data/lib/rspec/matchers/be_instance_of.rb +10 -12
  9. data/lib/rspec/matchers/be_kind_of.rb +10 -12
  10. data/lib/rspec/matchers/be_within.rb +36 -26
  11. data/lib/rspec/matchers/block_aliases.rb +2 -1
  12. data/lib/rspec/matchers/change.rb +1 -1
  13. data/lib/rspec/matchers/cover.rb +20 -19
  14. data/lib/rspec/matchers/eq.rb +22 -32
  15. data/lib/rspec/matchers/eql.rb +22 -28
  16. data/lib/rspec/matchers/equal.rb +37 -27
  17. data/lib/rspec/matchers/exist.rb +26 -18
  18. data/lib/rspec/matchers/have.rb +22 -28
  19. data/lib/rspec/matchers/include.rb +45 -37
  20. data/lib/rspec/matchers/match.rb +10 -10
  21. data/lib/rspec/matchers/match_array.rb +1 -7
  22. data/lib/rspec/matchers/matcher.rb +0 -8
  23. data/lib/rspec/matchers/operator_matcher.rb +0 -2
  24. data/lib/rspec/matchers/pretty.rb +25 -2
  25. data/lib/rspec/matchers/raise_error.rb +2 -16
  26. data/lib/rspec/matchers/respond_to.rb +1 -6
  27. data/lib/rspec/matchers/satisfy.rb +1 -6
  28. data/lib/rspec/matchers/throw_symbol.rb +2 -11
  29. data/spec/rspec/expectations/handler_spec.rb +1 -1
  30. data/spec/rspec/matchers/change_spec.rb +1 -1
  31. data/spec/rspec/matchers/description_generation_spec.rb +2 -2
  32. data/spec/rspec/matchers/eq_spec.rb +1 -1
  33. data/spec/rspec/matchers/eql_spec.rb +2 -2
  34. data/spec/rspec/matchers/equal_spec.rb +1 -1
  35. data/spec/rspec/matchers/include_spec.rb +4 -0
  36. data/spec/rspec/matchers/raise_error_spec.rb +2 -2
  37. data/spec/spec_helper.rb +1 -0
  38. metadata +15 -10
data/README.md CHANGED
@@ -1,21 +1,129 @@
1
1
  # RSpec Expectations
2
2
 
3
- rspec-expectations adds `should` and `should_not` to every object and includes
4
- several standard matchers in RSpec::Matchers
3
+ [RSpec::Expectations](../RSpec/Expectations) lets you express expected outcomes
4
+ on an object in an example.
5
+
6
+ account.balance.should eq(Money.new(37.42, :USD))
5
7
 
6
8
  ## Install
7
9
 
8
- gem install rspec # for rspec-core, rspec-expectations, rspec-mocks
9
- gem install rspec-expectations # for rspec-expectations only
10
+ If you want to use rspec-expectations with rspec, just install the rspec gem
11
+ and RubyGems will also install rspec-expectations for you (along with
12
+ rspec-core and rspec-mocks):
13
+
14
+ gem install rspec
15
+
16
+ If you want to use rspec-expectations with another tool, like Test::Unit,
17
+ Minitest, or Cucumber, you can install it directly:
18
+
19
+ gem install rspec-expectations
20
+
21
+ ## Basic usage
22
+
23
+ Here's an example using rspec-core:
24
+
25
+ describe Order do
26
+ it "sums the prices of the items in its line items" do
27
+ order = Order.new
28
+ order.add_entry(LineItem.new(:item => Item.new(
29
+ :price => Money.new(1.11, :USD)
30
+ )
31
+ order.add_entry(LineItem.new(:item => Item.new(
32
+ :price => Money.new(2.22, :USD),
33
+ :quantity => 2
34
+ )
35
+ order.total.should eq(Money.new(5.55, :USD))
36
+ end
37
+ end
38
+
39
+ The `describe` and `it` methods come from rspec-core. The `Order`, `LineItem`,
40
+ and `Item` classes would be from _your_ code. The last line of the example
41
+ expresses an expected outcome. If `order.total == Money.new(5.55, :USD)`, then
42
+ the example passes. If not, it fails with a message like:
43
+
44
+ expected: #<Money @value=5.55 @currency=:USD>
45
+ got: #<Money @value=1.11 @currency=:USD>
46
+
47
+ ## Built-in matchers
48
+
49
+ ### Equivalence
50
+
51
+ actual.should eq(expected) # passes if actual == expected
52
+ actual.should == expected # passes if actual == expected
53
+ actual.should eql(expected) # passes if actual.eql?(expected)
54
+
55
+ ### Identity
56
+
57
+ actual.should be(expected) # passes if actual.equal?(expected)
58
+ actual.should equal(expected) # passes if actual.equal?(expected)
59
+
60
+ ### Comparisons
61
+
62
+ actual.should be > expected
63
+ actual.should be >= expected
64
+ actual.should be <= expected
65
+ actual.should be < expected
66
+ actual.should be_within(delta).of(expected)
67
+
68
+ ### Regular expressions
69
+
70
+ actual.should =~ /expression/
71
+ actual.should match(/expression/)
72
+
73
+ ### Types/classes
74
+
75
+ actual.should be_an_instance_of(expected)
76
+ actual.should be_a_kind_of(expected)
77
+
78
+ ### Truthiness
79
+
80
+ actual.should be_true # passes if actual is truthy (not nil or false)
81
+ actual.should be_false # passes if actual is falsy (nil or false)
82
+ actual.should be_nil # passes if actual is nil
83
+
84
+ ### Expecting errors
85
+
86
+ expect { ... }.to raise_error
87
+ expect { ... }.to raise_error(ErrorClass)
88
+ expect { ... }.to raise_error("message")
89
+ expect { ... }.to raise_error(ErrorClass, "message")
90
+
91
+ ### Expecting throws
92
+
93
+ expect { ... }.to throw_symbol
94
+ expect { ... }.to throw_symbol(:symbol)
95
+ expect { ... }.to throw_symbol(:symbol, 'value')
96
+
97
+ ### Predicate matchers
98
+
99
+ actual.should be_xxx # passes if actual.xxx?
100
+ actual.should have_xxx(:arg) # passes if actual.has_xxx?(:arg)
101
+
102
+ See [RSpec::Matchers](../RSpec/Matchers) for more about predicate matchers.
103
+
104
+ ### Ranges (Ruby >= 1.9 only)
105
+
106
+ (1..10).should cover(3)
107
+
108
+ ### Collection membership
109
+
110
+ actual.should include(expected)
111
+
112
+ #### Examples
10
113
 
11
- ## Matchers
114
+ [1,2,3].should include(1)
115
+ [1,2,3].should include(1, 2)
116
+ {:a => 'b'}.should include(:a => 'b')
117
+ "this string".should include("is str")
12
118
 
13
- Matchers are objects used to compose expectations:
119
+ ## Learn more
14
120
 
15
- result.should eq("this value")
121
+ See [RSpec::Expectations](../RSpec/Expectations) for more information about
122
+ `should` and `should_not` and how they work.
16
123
 
17
- In that example, `eq("this value")` returns a `Matcher` object that
18
- compares the actual `result` to the expected `"this value"`.
124
+ See [RSpec::Matchers](../RSpec/Matchers) for more information about the
125
+ built-in matchers that ship with rspec-expectations, and how to write your own
126
+ custom matchers.
19
127
 
20
128
  ## Also see
21
129
 
@@ -8,30 +8,38 @@ require 'rspec/expectations/version'
8
8
  require 'rspec/expectations/differ'
9
9
 
10
10
  module RSpec
11
- # RSpec::Expectations lets you set expectations on your objects.
11
+ # RSpec::Expectations adds two instance methods to every object:
12
12
  #
13
- # result.should == 37
14
- # team.should have(11).players_on_the_field
13
+ # should(matcher=nil)
14
+ # should_not(matcher=nil)
15
15
  #
16
- # == How Expectations work.
16
+ # Both methods take an optional matcher object (See
17
+ # [RSpec::Matchers](../RSpec/Matchers)). When `should` is invoked with a
18
+ # matcher, it turns around and calls `matcher.matches?(self)`. For example,
19
+ # in the expression:
17
20
  #
18
- # RSpec::Expectations adds two methods to Object:
21
+ # order.total.should eq(Money.new(5.55, :USD))
19
22
  #
20
- # should(matcher=nil)
21
- # should_not(matcher=nil)
23
+ # the `should` method invokes the equivalent of `eq.matches?(order.total)`. If
24
+ # `matches?` returns true, the expectation is met and execution continues. If
25
+ # `false`, then the spec fails with the message returned by
26
+ # `eq.failure_message_for_should`.
22
27
  #
23
- # Both methods take an optional Expression Matcher (See RSpec::Matchers).
28
+ # Given the expression:
24
29
  #
25
- # When +should+ receives an Expression Matcher, it calls <tt>matches?(self)</tt>. If
26
- # it returns +true+, the spec passes and execution continues. If it returns
27
- # +false+, then the spec fails with the message returned by <tt>matcher.failure_message</tt>.
30
+ # order.entries.should_not include(entry)
28
31
  #
29
- # Similarly, when +should_not+ receives a matcher, it calls <tt>matches?(self)</tt>. If
30
- # it returns +false+, the spec passes and execution continues. If it returns
31
- # +true+, then the spec fails with the message returned by <tt>matcher.negative_failure_message</tt>.
32
+ # the `should_not` method invokes the equivalent of
33
+ # `include.matches?(order.entries)`, but it interprets `false` as success, and
34
+ # `true` as a failure, using the message generated by
35
+ # `eq.failure_message_for_should_not`.
32
36
  #
33
- # RSpec ships with a standard set of useful matchers, and writing your own
34
- # matchers is quite simple. See RSpec::Matchers for details.
37
+ # rspec-expectations ships with a standard set of useful matchers, and writing
38
+ # your own matchers is quite simple.
39
+ #
40
+ # See [RSpec::Matchers](../RSpec/Matchers) for more information about the
41
+ # built-in matchers that ship with rspec-expectations, and how to write your
42
+ # own custom matchers.
35
43
  module Expectations
36
44
  end
37
45
  end
@@ -16,7 +16,7 @@ module RSpec
16
16
  matcher.failure_message
17
17
 
18
18
  if matcher.respond_to?(:diffable?) && matcher.diffable?
19
- ::RSpec::Expectations.fail_with message, matcher.expected.first, matcher.actual
19
+ ::RSpec::Expectations.fail_with message, matcher.expected, matcher.actual
20
20
  else
21
21
  ::RSpec::Expectations.fail_with message
22
22
  end
@@ -2,7 +2,7 @@ module RSpec
2
2
  module Expectations
3
3
  # @private
4
4
  module Version
5
- STRING = '2.7.0'
5
+ STRING = '2.8.0.rc1'
6
6
  end
7
7
  end
8
8
  end
@@ -1,102 +1,102 @@
1
1
  module RSpec
2
- # rspec-expecations provides a number of useful Matchers we use to compose
3
- # expectations. A Matcher is any object that responds to the following:
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
4
  #
5
- # matches?(actual)
6
- # failure_message_for_should
5
+ # matches?(actual)
6
+ # failure_message_for_should
7
7
  #
8
8
  # These methods are also part of the matcher protocol, but are optional:
9
9
  #
10
- # does_not_match?(actual)
11
- # failure_message_for_should_not
12
- # description #optional
10
+ # does_not_match?(actual)
11
+ # failure_message_for_should_not
12
+ # description
13
13
  #
14
- # == Predicates
14
+ # ## Predicates
15
15
  #
16
- # In addition to those Expression Matchers that are defined explicitly, RSpec will
17
- # create custom Matchers on the fly for any arbitrary predicate, giving your specs
18
- # a much more natural language feel.
16
+ # In addition to matchers that are defined explicitly, RSpec will create
17
+ # custom matchers on the fly for any arbitrary predicate, giving your specs a
18
+ # much more natural language feel.
19
19
  #
20
20
  # A Ruby predicate is a method that ends with a "?" and returns true or false.
21
- # Common examples are +empty?+, +nil?+, and +instance_of?+.
21
+ # Common examples are `empty?`, `nil?`, and `instance_of?`.
22
22
  #
23
- # All you need to do is write +should be_+ followed by the predicate without
23
+ # All you need to do is write `should be_` followed by the predicate without
24
24
  # the question mark, and RSpec will figure it out from there. For example:
25
25
  #
26
- # [].should be_empty # => [].empty?() | passes
27
- # [].should_not be_empty # => [].empty?() | fails
26
+ # [].should be_empty # => [].empty?() | passes
27
+ # [].should_not be_empty # => [].empty?() | fails
28
28
  #
29
29
  # In addtion to prefixing the predicate matchers with "be_", you can also use "be_a_"
30
30
  # and "be_an_", making your specs read much more naturally:
31
31
  #
32
- # "a string".should be_an_instance_of(String) =>"a string".instance_of?(String) #passes
32
+ # "a string".should be_an_instance_of(String) =>"a string".instance_of?(String) #passes
33
33
  #
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
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
38
38
  #
39
- # RSpec will also create custom matchers for predicates like +has_key?+. To
39
+ # RSpec will also create custom matchers for predicates like `has_key?`. To
40
40
  # use this feature, just state that the object should have_key(:key) and RSpec will
41
41
  # call has_key?(:key) on the target. For example:
42
42
  #
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
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
45
45
  #
46
46
  # You can use this feature to invoke any predicate that begins with "has_", whether it is
47
- # part of the Ruby libraries (like +Hash#has_key?+) or a method you wrote on your own class.
47
+ # part of the Ruby libraries (like `Hash#has_key?`) or a method you wrote on your own class.
48
48
  #
49
- # == Custom Matchers
49
+ # ## Custom Matchers
50
50
  #
51
- # When you find that none of the stock Expectation Matchers provide a natural
52
- # feeling expectation, you can very easily write your own using RSpec's matcher
53
- # DSL or writing one from scratch.
51
+ # When you find that none of the stock matchers provide a natural feeling
52
+ # expectation, you can very easily write your own using RSpec's matcher DSL
53
+ # or writing one from scratch.
54
54
  #
55
- # === Matcher DSL
55
+ # ### Matcher DSL
56
56
  #
57
57
  # Imagine that you are writing a game in which players can be in various
58
58
  # zones on a virtual board. To specify that bob should be in zone 4, you
59
59
  # could say:
60
60
  #
61
- # bob.current_zone.should eql(Zone.new("4"))
61
+ # bob.current_zone.should eql(Zone.new("4"))
62
62
  #
63
63
  # But you might find it more expressive to say:
64
64
  #
65
- # bob.should be_in_zone("4")
65
+ # bob.should be_in_zone("4")
66
66
  #
67
67
  # and/or
68
68
  #
69
- # bob.should_not be_in_zone("3")
69
+ # bob.should_not be_in_zone("3")
70
70
  #
71
71
  # You can create such a matcher like so:
72
72
  #
73
- # RSpec::Matchers.define :be_in_zone do |zone|
74
- # match do |player|
75
- # player.in_zone?(zone)
76
- # end
77
- # end
73
+ # RSpec::Matchers.define :be_in_zone do |zone|
74
+ # match do |player|
75
+ # player.in_zone?(zone)
76
+ # end
77
+ # end
78
78
  #
79
79
  # This will generate a <tt>be_in_zone</tt> method that returns a matcher
80
80
  # with logical default messages for failures. You can override the failure
81
81
  # messages and the generated description as follows:
82
82
  #
83
- # RSpec::Matchers.define :be_in_zone do |zone|
84
- # match do |player|
85
- # player.in_zone?(zone)
86
- # end
83
+ # RSpec::Matchers.define :be_in_zone do |zone|
84
+ # match do |player|
85
+ # player.in_zone?(zone)
86
+ # end
87
87
  #
88
- # failure_message_for_should do |player|
89
- # # generate and return the appropriate string.
90
- # end
88
+ # failure_message_for_should do |player|
89
+ # # generate and return the appropriate string.
90
+ # end
91
91
  #
92
- # failure_message_for_should_not do |player|
93
- # # generate and return the appropriate string.
94
- # end
92
+ # failure_message_for_should_not do |player|
93
+ # # generate and return the appropriate string.
94
+ # end
95
95
  #
96
- # description do
97
- # # generate and return the appropriate string.
98
- # end
99
- # end
96
+ # description do
97
+ # # generate and return the appropriate string.
98
+ # end
99
+ # end
100
100
  #
101
101
  # Each of the message-generation methods has access to the block arguments
102
102
  # passed to the <tt>create</tt> method (in this case, <tt>zone</tt>). The
@@ -104,67 +104,66 @@ module RSpec
104
104
  # <tt>failure_message_for_should_not</tt>) are passed the actual value (the
105
105
  # receiver of <tt>should</tt> or <tt>should_not</tt>).
106
106
  #
107
- # === Custom Matcher from scratch
107
+ # ### Custom Matcher from scratch
108
108
  #
109
109
  # You could also write a custom matcher from scratch, as follows:
110
110
  #
111
- # class BeInZone
112
- # def initialize(expected)
113
- # @expected = expected
114
- # end
111
+ # class BeInZone
112
+ # def initialize(expected)
113
+ # @expected = expected
114
+ # end
115
115
  #
116
- # def matches?(target)
117
- # @target = target
118
- # @target.current_zone.eql?(Zone.new(@expected))
119
- # end
116
+ # def matches?(target)
117
+ # @target = target
118
+ # @target.current_zone.eql?(Zone.new(@expected))
119
+ # end
120
120
  #
121
- # def failure_message_for_should
122
- # "expected #{@target.inspect} to be in Zone #{@expected}"
123
- # end
121
+ # def failure_message_for_should
122
+ # "expected #{@target.inspect} to be in Zone #{@expected}"
123
+ # end
124
124
  #
125
- # def failure_message_for_should_not
126
- # "expected #{@target.inspect} not to be in Zone #{@expected}"
127
- # end
128
- # end
125
+ # def failure_message_for_should_not
126
+ # "expected #{@target.inspect} not to be in Zone #{@expected}"
127
+ # end
128
+ # end
129
129
  #
130
130
  # ... and a method like this:
131
131
  #
132
- # def be_in_zone(expected)
133
- # BeInZone.new(expected)
134
- # end
132
+ # def be_in_zone(expected)
133
+ # BeInZone.new(expected)
134
+ # end
135
135
  #
136
136
  # And then expose the method to your specs. This is normally done
137
137
  # by including the method and the class in a module, which is then
138
138
  # included in your spec:
139
139
  #
140
- # module CustomGameMatchers
141
- # class BeInZone
142
- # # ...
143
- # end
140
+ # module CustomGameMatchers
141
+ # class BeInZone
142
+ # # ...
143
+ # end
144
144
  #
145
- # def be_in_zone(expected)
146
- # # ...
147
- # end
148
- # end
145
+ # def be_in_zone(expected)
146
+ # # ...
147
+ # end
148
+ # end
149
149
  #
150
- # describe "Player behaviour" do
151
- # include CustomGameMatchers
152
- # # ...
153
- # end
150
+ # describe "Player behaviour" do
151
+ # include CustomGameMatchers
152
+ # # ...
153
+ # end
154
154
  #
155
155
  # or you can include in globally in a spec_helper.rb file <tt>require</tt>d
156
156
  # from your spec file(s):
157
157
  #
158
- # RSpec::configure do |config|
159
- # config.include(CustomGameMatchers)
160
- # end
158
+ # RSpec::configure do |config|
159
+ # config.include(CustomGameMatchers)
160
+ # end
161
161
  module Matchers
162
- # Include Matchers for other test frameworks.
163
- # Note that MiniTest _must_ come before TU because on ruby 1.9,
164
- # T::U::TC is a subclass of MT::U::TC and a 1.9 bug can lead
165
- # to infinite recursion from the `super` call in our method_missing
166
- # hook. See this gist for more info:
167
- # https://gist.github.com/845896
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
168
167
  if defined?(MiniTest::Unit::TestCase)
169
168
  MiniTest::Unit::TestCase.send(:include, self)
170
169
  end
@@ -176,6 +175,7 @@ end
176
175
 
177
176
  require 'rspec/matchers/extensions/instance_eval_with_args'
178
177
  require 'rspec/matchers/pretty'
178
+ require 'rspec/matchers/base_matcher'
179
179
  require 'rspec/matchers/matcher'
180
180
  require 'rspec/matchers/operator_matcher'
181
181
  require 'rspec/matchers/be'