rspec-expectations 2.10.0 → 2.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/Changelog.md +24 -1
  2. data/README.md +36 -2
  3. data/features/built_in_matchers/be.feature +52 -14
  4. data/features/syntax_configuration.feature +68 -0
  5. data/lib/rspec/expectations.rb +2 -0
  6. data/lib/rspec/expectations/expectation_target.rb +52 -0
  7. data/lib/rspec/expectations/extensions.rb +0 -1
  8. data/lib/rspec/expectations/syntax.rb +105 -0
  9. data/lib/rspec/expectations/version.rb +1 -1
  10. data/lib/rspec/matchers.rb +12 -5
  11. data/lib/rspec/matchers/built_in/base_matcher.rb +16 -7
  12. data/lib/rspec/matchers/built_in/be.rb +27 -25
  13. data/lib/rspec/matchers/built_in/be_instance_of.rb +3 -5
  14. data/lib/rspec/matchers/built_in/be_kind_of.rb +3 -5
  15. data/lib/rspec/matchers/built_in/be_within.rb +17 -11
  16. data/lib/rspec/matchers/built_in/cover.rb +5 -6
  17. data/lib/rspec/matchers/built_in/eq.rb +4 -8
  18. data/lib/rspec/matchers/built_in/eql.rb +3 -5
  19. data/lib/rspec/matchers/built_in/equal.rb +6 -10
  20. data/lib/rspec/matchers/built_in/exist.rb +11 -13
  21. data/lib/rspec/matchers/built_in/include.rb +5 -6
  22. data/lib/rspec/matchers/built_in/match.rb +3 -4
  23. data/lib/rspec/matchers/built_in/match_array.rb +7 -14
  24. data/lib/rspec/matchers/built_in/start_and_end_with.rb +1 -3
  25. data/lib/rspec/matchers/built_in/yield.rb +2 -5
  26. data/lib/rspec/matchers/configuration.rb +66 -0
  27. data/spec/rspec/expectations/expectation_target_spec.rb +65 -0
  28. data/spec/rspec/expectations/extensions/kernel_spec.rb +22 -0
  29. data/spec/rspec/matchers/base_matcher_spec.rb +8 -6
  30. data/spec/rspec/matchers/be_spec.rb +2 -2
  31. data/spec/rspec/matchers/be_within_spec.rb +9 -1
  32. data/spec/rspec/matchers/configuration_spec.rb +160 -0
  33. data/spec/rspec/matchers/eq_spec.rb +16 -4
  34. data/spec/rspec/matchers/equal_spec.rb +7 -7
  35. data/spec/rspec/matchers/match_array_spec.rb +12 -0
  36. data/spec/rspec/matchers/yield_spec.rb +3 -3
  37. data/spec/support/in_sub_process.rb +31 -0
  38. metadata +16 -9
  39. data/lib/rspec/expectations/extensions/kernel.rb +0 -26
  40. data/lib/rspec/matchers/block_aliases.rb +0 -21
  41. data/spec/rspec/matchers/compatibility_spec.rb +0 -28
@@ -1,10 +1,33 @@
1
+ ### 2.11.0 / 2012-07-07
2
+ [full changelog](http://github.com/rspec/rspec-expectations/compare/v2.10.0...v2.11.0)
3
+
4
+ Enhancements
5
+
6
+ * Expand `expect` syntax so that it supports expections on bare values
7
+ in addition to blocks (Myron Marston).
8
+ * Add configuration options to control available expectation syntaxes
9
+ (Myron Marston):
10
+ * `RSpec.configuration.expect_with(:rspec) { |c| c.syntax = :expect }`
11
+ * `RSpec.configuration.expect_with(:rspec) { |c| c.syntax = :should }`
12
+ * `RSpec.configuration.expect_with(:rspec) { |c| c.syntax = [:should, :expect] }`
13
+ * `RSpec.configuration.add_should_and_should_not_to Delegator`
14
+
15
+ Bug fixes
16
+
17
+ * Allow only `Numeric` values to be the "actual" in the `be_within` matcher.
18
+ This prevents confusing error messages. (Su Zhang @zhangsu)
19
+ * Define `should` and `should_not` on `BasicObject` rather than `Kernel`
20
+ on 1.9. This makes `should` and `should_not` work properly with
21
+ `BasicObject`-subclassed proxy objects like `Delegator`. (Myron
22
+ Marston)
23
+
1
24
  ### 2.10.0 / 2012-05-03
2
25
  [full changelog](http://github.com/rspec/rspec-expectations/compare/v2.9.1...v2.10.0)
3
26
 
4
27
  Enhancements
5
28
 
6
29
  * Add new `start_with` and `end_with` matchers (Jeremy Wadsack)
7
- * Add new matchers for specifying yields (Myron Marson):
30
+ * Add new matchers for specifying yields (Myron Marston):
8
31
  * `expect {...}.to yield_control`
9
32
  * `expect {...}.to yield_with_args(1, 2, 3)`
10
33
  * `expect {...}.to yield_with_no_args`
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # RSpec Expectations
1
+ # RSpec Expectations [![Build Status](https://secure.travis-ci.org/rspec/rspec-expectations.png?branch=master)](http://travis-ci.org/rspec/rspec-expectations) [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/rspec/rspec-expectations)
2
2
 
3
3
  RSpec::Expectations lets you express expected outcomes on an object in an
4
4
  example.
@@ -62,7 +62,7 @@ actual.should eql(expected) # passes if actual.eql?(expected)
62
62
  actual.should be(expected) # passes if actual.equal?(expected)
63
63
  actual.should equal(expected) # passes if actual.equal?(expected)
64
64
  ```
65
-
65
+
66
66
  ### Comparisons
67
67
 
68
68
  ```ruby
@@ -163,6 +163,40 @@ actual.should end_with(expected)
163
163
  "this string".should end_with("ring")
164
164
  ```
165
165
 
166
+ ## Syntax Options
167
+
168
+ In addition to the `should` syntax, rspec-expectations supports
169
+ an additional `expect` syntax:
170
+
171
+ ```ruby
172
+ # rather than:
173
+ [1, 2, 3].should include(1)
174
+
175
+ #...you can use:
176
+ expect([1, 2, 3]).to include(1)
177
+
178
+ # rather than:
179
+ foo.should_not eq(bar)
180
+
181
+ #...you can use:
182
+ expect(foo).not_to eq(bar)
183
+ ```
184
+
185
+ If you want your project to only use one of these syntaxes, you can
186
+ configure it:
187
+
188
+ ```ruby
189
+ RSpec.configure do |config|
190
+ config.expect_with :rspec do |c|
191
+ c.syntax = :expect
192
+ # or
193
+ c.syntax = :should
194
+ # or
195
+ c.syntax = [:should, :expect]
196
+ end
197
+ end
198
+ ```
199
+
166
200
  ## Also see
167
201
 
168
202
  * [http://github.com/rspec/rspec](http://github.com/rspec/rspec)
@@ -26,13 +26,32 @@ Feature: "be" matchers
26
26
  end
27
27
  """
28
28
  When I run `rspec be_true_spec.rb`
29
- Then the output should contain all of these:
30
- | 10 examples, 5 failures |
31
- | expected true not to be true |
32
- | expected 7 not to be true |
33
- | expected "foo" not to be true |
34
- | expected nil to be true |
35
- | expected false to be true |
29
+ Then the output should contain "10 examples, 5 failures"
30
+ And the output should contain:
31
+ """
32
+ expected: non-true value
33
+ got: true
34
+ """
35
+ And the output should contain:
36
+ """
37
+ expected: non-true value
38
+ got: 7
39
+ """
40
+ And the output should contain:
41
+ """
42
+ expected: non-true value
43
+ got: "foo"
44
+ """
45
+ And the output should contain:
46
+ """
47
+ expected: true value
48
+ got: nil
49
+ """
50
+ And the output should contain:
51
+ """
52
+ expected: true value
53
+ got: false
54
+ """
36
55
 
37
56
  Scenario: be_false matcher
38
57
  Given a file named "be_false_spec.rb" with:
@@ -53,13 +72,32 @@ Feature: "be" matchers
53
72
  end
54
73
  """
55
74
  When I run `rspec be_false_spec.rb`
56
- Then the output should contain all of these:
57
- | 10 examples, 5 failures |
58
- | expected nil not to be false |
59
- | expected false not to be false |
60
- | expected true to be false |
61
- | expected 7 to be false |
62
- | expected "foo" to be false |
75
+ Then the output should contain "10 examples, 5 failures"
76
+ And the output should contain:
77
+ """
78
+ expected: non-false value
79
+ got: nil
80
+ """
81
+ And the output should contain:
82
+ """
83
+ expected: non-false value
84
+ got: false
85
+ """
86
+ And the output should contain:
87
+ """
88
+ expected: false value
89
+ got: true
90
+ """
91
+ And the output should contain:
92
+ """
93
+ expected: false value
94
+ got: 7
95
+ """
96
+ And the output should contain:
97
+ """
98
+ expected: false value
99
+ got: "foo"
100
+ """
63
101
 
64
102
  Scenario: be_nil matcher
65
103
  Given a file named "be_nil_spec.rb" with:
@@ -0,0 +1,68 @@
1
+ Feature: Syntax Configuration
2
+
3
+ In addition to the long-supported `should` syntax, rspec-expectations
4
+ supports an alternate `expect` syntax. If you want your project to
5
+ only use one syntax, you can configure the available syntaxes.
6
+
7
+ Background:
8
+ Given a file named "syntaxes_spec.rb" with:
9
+ """ruby
10
+ describe "using the should syntax" do
11
+ specify { 3.should eq(3) }
12
+ specify { 3.should_not eq(4) }
13
+ specify { lambda { raise "boom" }.should raise_error("boom") }
14
+ specify { lambda { }.should_not raise_error }
15
+ end
16
+
17
+ describe "using the expect syntax" do
18
+ specify { expect(3).to eq(3) }
19
+ specify { expect(3).not_to eq(4) }
20
+ specify { expect { raise "boom" }.to raise_error("boom") }
21
+ specify { expect { }.not_to raise_error }
22
+ end
23
+ """
24
+
25
+ Scenario: Both syntaxes are available by default
26
+ When I run `rspec syntaxes_spec.rb`
27
+ Then the examples should all pass
28
+
29
+ Scenario: Disable should syntax
30
+ Given a file named "disable_should_syntax.rb" with:
31
+ """ruby
32
+ RSpec.configure do |config|
33
+ config.expect_with :rspec do |c|
34
+ c.syntax = :expect
35
+ end
36
+ end
37
+ """
38
+ When I run `rspec disable_should_syntax.rb syntaxes_spec.rb`
39
+ Then the output should contain all of these:
40
+ | 8 examples, 4 failures |
41
+ | undefined method `should' |
42
+
43
+ Scenario: Disable expect syntax
44
+ Given a file named "disable_expect_syntax.rb" with:
45
+ """ruby
46
+ RSpec.configure do |config|
47
+ config.expect_with :rspec do |c|
48
+ c.syntax = :should
49
+ end
50
+ end
51
+ """
52
+ When I run `rspec disable_expect_syntax.rb syntaxes_spec.rb`
53
+ Then the output should contain all of these:
54
+ | 8 examples, 4 failures |
55
+ | undefined method `expect' |
56
+
57
+ Scenario: Explicitly enable both syntaxes
58
+ Given a file named "enable_both_syntaxes.rb" with:
59
+ """ruby
60
+ RSpec.configure do |config|
61
+ config.expect_with :rspec do |c|
62
+ c.syntax = [:should, :expect]
63
+ end
64
+ end
65
+ """
66
+ When I run `rspec enable_both_syntaxes.rb syntaxes_spec.rb`
67
+ Then the examples should all pass
68
+
@@ -1,5 +1,7 @@
1
1
  require 'rspec/expectations/extensions'
2
2
  require 'rspec/matchers'
3
+ require 'rspec/matchers/configuration'
4
+ require 'rspec/expectations/expectation_target'
3
5
  require 'rspec/expectations/fail_with'
4
6
  require 'rspec/expectations/errors'
5
7
  require 'rspec/expectations/deprecation'
@@ -0,0 +1,52 @@
1
+ module RSpec
2
+ module Expectations
3
+ # Wraps the target of an expectation.
4
+ # @example
5
+ # expect(something) # => ExpectationTarget wrapping something
6
+ class ExpectationTarget
7
+ # @api private
8
+ def initialize(target)
9
+ @target = target
10
+ end
11
+
12
+ # Runs the given expectation, passing if `matcher` returns true.
13
+ # @example
14
+ # expect(value).to eq(5)
15
+ # expect { perform }.to raise_error
16
+ # @param [Matcher]
17
+ # matcher
18
+ # @param [String] message optional message to display when the expectation fails
19
+ # @return [Boolean] true if the expectation succeeds (else raises)
20
+ # @see RSpec::Matchers
21
+ def to(matcher=nil, message=nil, &block)
22
+ prevent_operator_matchers(:to, matcher)
23
+ RSpec::Expectations::PositiveExpectationHandler.handle_matcher(@target, matcher, message, &block)
24
+ end
25
+
26
+ # Runs the given expectation, passing if `matcher` returns false.
27
+ # @example
28
+ # expect(value).to_not eq(5)
29
+ # expect(value).not_to eq(5)
30
+ # @param [Matcher]
31
+ # matcher
32
+ # @param [String] message optional message to display when the expectation fails
33
+ # @return [Boolean] false if the negative expectation succeeds (else raises)
34
+ # @see RSpec::Matchers
35
+ def to_not(matcher=nil, message=nil, &block)
36
+ prevent_operator_matchers(:to_not, matcher)
37
+ RSpec::Expectations::NegativeExpectationHandler.handle_matcher(@target, matcher, message, &block)
38
+ end
39
+ alias not_to to_not
40
+
41
+ private
42
+
43
+ def prevent_operator_matchers(verb, matcher)
44
+ return if matcher
45
+
46
+ raise ArgumentError, "The expect syntax does not support operator matchers, " +
47
+ "so you must pass a matcher to `##{verb}`."
48
+ end
49
+ end
50
+ end
51
+ end
52
+
@@ -1,3 +1,2 @@
1
- require 'rspec/expectations/extensions/kernel'
2
1
  require 'rspec/expectations/extensions/array'
3
2
  require 'rspec/expectations/extensions/object'
@@ -0,0 +1,105 @@
1
+ module RSpec
2
+ module Expectations
3
+ # @api private
4
+ # Provides methods for enabling and disabling the available
5
+ # syntaxes provided by rspec-expectations.
6
+ module Syntax
7
+ extend self
8
+
9
+ # @method should
10
+ # Passes if `matcher` returns true. Available on every `Object`.
11
+ # @example
12
+ # actual.should eq expected
13
+ # actual.should match /expression/
14
+ # @param [Matcher]
15
+ # matcher
16
+ # @param [String] message optional message to display when the expectation fails
17
+ # @return [Boolean] true if the expectation succeeds (else raises)
18
+ # @see RSpec::Matchers
19
+
20
+ # @method should_not
21
+ # Passes if `matcher` returns false. Available on every `Object`.
22
+ # @example
23
+ # actual.should_not eq expected
24
+ # @param [Matcher]
25
+ # matcher
26
+ # @param [String] message optional message to display when the expectation fails
27
+ # @return [Boolean] false if the negative expectation succeeds (else raises)
28
+ # @see RSpec::Matchers
29
+
30
+ # @method expect
31
+ # Wraps `target` in an `ExpectationTarget`
32
+ # @return [ExpectationTarget]
33
+
34
+ # @api private
35
+ # Determines where we add `should` and `should_not`.
36
+ def default_should_host
37
+ @default_should_host ||= defined?(::BasicObject) ?
38
+ ::BasicObject : ::Kernel
39
+ end
40
+
41
+ # @api private
42
+ # Enables the `should` syntax.
43
+ def enable_should(syntax_host = default_should_host)
44
+ return if should_enabled?(syntax_host)
45
+
46
+ syntax_host.module_eval do
47
+ def should(matcher=nil, message=nil, &block)
48
+ ::RSpec::Expectations::PositiveExpectationHandler.handle_matcher(self, matcher, message, &block)
49
+ end
50
+
51
+ def should_not(matcher=nil, message=nil, &block)
52
+ ::RSpec::Expectations::NegativeExpectationHandler.handle_matcher(self, matcher, message, &block)
53
+ end
54
+ end
55
+ end
56
+
57
+ # @api private
58
+ # Disables the `should` syntax.
59
+ def disable_should(syntax_host = default_should_host)
60
+ return unless should_enabled?(syntax_host)
61
+
62
+ syntax_host.module_eval do
63
+ undef should
64
+ undef should_not
65
+ end
66
+ end
67
+
68
+ # @api private
69
+ # Enables the `expect` syntax.
70
+ def enable_expect(syntax_host = ::RSpec::Matchers)
71
+ return if expect_enabled?(syntax_host)
72
+
73
+ syntax_host.module_eval do
74
+ def expect(*target, &target_block)
75
+ target << target_block if block_given?
76
+ raise ArgumentError.new("You must pass an argument or a block to #expect but not both.") unless target.size == 1
77
+ ::RSpec::Expectations::ExpectationTarget.new(target.first)
78
+ end
79
+ end
80
+ end
81
+
82
+ # @api private
83
+ # Disables the `expect` syntax.
84
+ def disable_expect(syntax_host = ::RSpec::Matchers)
85
+ return unless expect_enabled?(syntax_host)
86
+
87
+ syntax_host.module_eval do
88
+ undef expect
89
+ end
90
+ end
91
+
92
+ # @api private
93
+ # Indicates whether or not the `should` syntax is enabled.
94
+ def should_enabled?(syntax_host = default_should_host)
95
+ syntax_host.method_defined?(:should)
96
+ end
97
+
98
+ # @api private
99
+ # Indicates whether or not the `expect` syntax is enabled.
100
+ def expect_enabled?(syntax_host = ::RSpec::Matchers)
101
+ syntax_host.method_defined?(:expect)
102
+ end
103
+ end
104
+ end
105
+ end
@@ -2,7 +2,7 @@ module RSpec
2
2
  module Expectations
3
3
  # @private
4
4
  module Version
5
- STRING = '2.10.0'
5
+ STRING = '2.11.0'
6
6
  end
7
7
  end
8
8
  end
@@ -181,7 +181,6 @@ require 'rspec/matchers/matcher'
181
181
  require 'rspec/matchers/operator_matcher'
182
182
  require 'rspec/matchers/be_close'
183
183
 
184
- require 'rspec/matchers/block_aliases'
185
184
  require 'rspec/matchers/generated_descriptions'
186
185
  require 'rspec/matchers/method_missing'
187
186
  require 'rspec/matchers/compatibility'
@@ -664,19 +663,27 @@ module RSpec
664
663
  BuiltIn::YieldSuccessiveArgs.new(*args)
665
664
  end
666
665
 
667
- # Passes if actual contains all of the expected regardless of order.
668
- # This works for collections. Pass in multiple args and it will only
666
+ # Passes if actual contains all of the expected regardless of order.
667
+ # This works for collections. Pass in multiple args and it will only
669
668
  # pass if all args are found in collection.
670
669
  #
671
- # NOTE: there is no should_not version of array.should =~ other_array
672
- #
670
+ # @note This is also available using the `=~` operator with `should`,
671
+ # but `=~` is not supported with `expect`.
672
+ # @note There is no should_not version of array.should =~ other_array
673
+ #
673
674
  # @example
674
675
  #
676
+ # expect([1,2,3]).to match_array([1,2,3])
677
+ # expect([1,2,3]).to match_array([1,3,2])
675
678
  # [1,2,3].should =~ [1,2,3] # => would pass
676
679
  # [1,2,3].should =~ [2,3,1] # => would pass
677
680
  # [1,2,3,4].should =~ [1,2,3] # => would fail
678
681
  # [1,2,2,3].should =~ [1,2,3] # => would fail
679
682
  # [1,2,3].should =~ [1,2,3,4] # => would fail
683
+ def match_array(array)
684
+ BuiltIn::MatchArray.new(array)
685
+ end
686
+
680
687
  OperatorMatcher.register(Array, '=~', BuiltIn::MatchArray)
681
688
  end
682
689
  end