rspec-expectations 2.7.0 → 2.8.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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'