rspec-expectations 2.9.1 → 2.10.0

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.
data/.yardopts CHANGED
@@ -1,3 +1,6 @@
1
- --no-private
2
1
  --exclude features
2
+ --no-private
3
3
  --markup markdown
4
+ -
5
+ Changelog.md
6
+ License.txt
@@ -1,5 +1,23 @@
1
+ ### 2.10.0 / 2012-05-03
2
+ [full changelog](http://github.com/rspec/rspec-expectations/compare/v2.9.1...v2.10.0)
3
+
4
+ Enhancements
5
+
6
+ * Add new `start_with` and `end_with` matchers (Jeremy Wadsack)
7
+ * Add new matchers for specifying yields (Myron Marson):
8
+ * `expect {...}.to yield_control`
9
+ * `expect {...}.to yield_with_args(1, 2, 3)`
10
+ * `expect {...}.to yield_with_no_args`
11
+ * `expect {...}.to yield_successive_args(1, 2, 3)`
12
+ * `match_unless_raises` takes multiple exception args
13
+
14
+ Bug fixes
15
+
16
+ * Fix `be_within` matcher to be inclusive of delta.
17
+ * Fix message-specific specs to pass on Rubinius (John Firebaugh)
18
+
1
19
  ### 2.9.1 / 2012-04-03
2
- [full changelog](http://github.com/rspec/rspec-expectations/compare/v2.9.0...2.9.1)
20
+ [full changelog](http://github.com/rspec/rspec-expectations/compare/v2.9.0...v2.9.1)
3
21
 
4
22
  Bug fixes
5
23
 
data/README.md CHANGED
@@ -112,6 +112,21 @@ expect { ... }.to throw_symbol(:symbol)
112
112
  expect { ... }.to throw_symbol(:symbol, 'value')
113
113
  ```
114
114
 
115
+ ### Yielding
116
+
117
+ ```ruby
118
+ expect { |b| 5.tap(&b) }.to yield_control # passes regardless of yielded args
119
+
120
+ expect { |b| yield_if_true(true, &b) }.to yield_with_no_args # passes only if no args are yielded
121
+
122
+ expect { |b| 5.tap(&b) }.to yield_with_args(5)
123
+ expect { |b| 5.tap(&b) }.to yield_with_args(Fixnum)
124
+ expect { |b| "a string".tap(&b) }.to yield_with_args(/str/)
125
+
126
+ expect { |b| [1, 2, 3].each(&b) }.to yield_successive_args(1, 2, 3)
127
+ expect { |b| { :a => 1, :b => 2 }.each(&b) }.to yield_successive_args([:a, 1], [:b, 2])
128
+ ```
129
+
115
130
  ### Predicate matchers
116
131
 
117
132
  ```ruby
@@ -129,6 +144,8 @@ actual.should have_xxx(:arg) # passes if actual.has_xxx?(:arg)
129
144
 
130
145
  ```ruby
131
146
  actual.should include(expected)
147
+ actual.should start_with(expected)
148
+ actual.should end_with(expected)
132
149
  ```
133
150
 
134
151
  #### Examples
@@ -136,8 +153,14 @@ actual.should include(expected)
136
153
  ```ruby
137
154
  [1,2,3].should include(1)
138
155
  [1,2,3].should include(1, 2)
156
+ [1,2,3].should start_with(1)
157
+ [1,2,3].should start_with(1,2)
158
+ [1,2,3].should end_with(3)
159
+ [1,2,3].should end_with(2,3)
139
160
  {:a => 'b'}.should include(:a => 'b')
140
161
  "this string".should include("is str")
162
+ "this string".should start_with("this")
163
+ "this string".should end_with("ring")
141
164
  ```
142
165
 
143
166
  ## Also see
File without changes
@@ -23,21 +23,24 @@ Feature: be_within matcher
23
23
  """
24
24
  describe 27.5 do
25
25
  it { should be_within(0.5).of(27.9) }
26
+ it { should be_within(0.5).of(28.0) }
26
27
  it { should be_within(0.5).of(27.1) }
27
- it { should_not be_within(0.5).of(28) }
28
- it { should_not be_within(0.5).of(27) }
28
+ it { should be_within(0.5).of(27.0) }
29
+
30
+ it { should_not be_within(0.5).of(28.1) }
31
+ it { should_not be_within(0.5).of(26.9) }
29
32
 
30
33
  # deliberate failures
31
- it { should_not be_within(0.5).of(27.9) }
32
- it { should_not be_within(0.5).of(27.1) }
33
- it { should be_within(0.5).of(28) }
34
- it { should be_within(0.5).of(27) }
34
+ it { should_not be_within(0.5).of(28) }
35
+ it { should_not be_within(0.5).of(27) }
36
+ it { should be_within(0.5).of(28.1) }
37
+ it { should be_within(0.5).of(26.9) }
35
38
  end
36
39
  """
37
40
  When I run `rspec be_within_matcher_spec.rb`
38
41
  Then the output should contain all of these:
39
- | 8 examples, 4 failures |
40
- | expected 27.5 not to be within 0.5 of 27.9 |
41
- | expected 27.5 not to be within 0.5 of 27.1 |
42
- | expected 27.5 to be within 0.5 of 28 |
43
- | expected 27.5 to be within 0.5 of 27 |
42
+ | 10 examples, 4 failures |
43
+ | expected 27.5 not to be within 0.5 of 28 |
44
+ | expected 27.5 not to be within 0.5 of 27 |
45
+ | expected 27.5 to be within 0.5 of 28.1 |
46
+ | expected 27.5 to be within 0.5 of 26.9 |
@@ -0,0 +1,46 @@
1
+ Feature: end_with matcher
2
+
3
+ Use the `end_with` matcher to specify that a string or array ends with the
4
+ expected characters or elements.
5
+
6
+ "this string".should end_with "string"
7
+ "this string".should_not end_with "stringy"
8
+ [0, 1, 2].should end_with 1, 2
9
+
10
+ Scenario: string usage
11
+ Given a file named "example_spec.rb" with:
12
+ """
13
+ describe "this string" do
14
+ it { should end_with "string" }
15
+ it { should_not end_with "stringy" }
16
+
17
+ # deliberate failures
18
+ it { should_not end_with "string" }
19
+ it { should end_with "stringy" }
20
+ end
21
+ """
22
+ When I run `rspec example_spec.rb`
23
+ Then the output should contain all of these:
24
+ | 4 examples, 2 failures |
25
+ | expected "this string" not to end with "string" |
26
+ | expected "this string" to end with "stringy" |
27
+
28
+ Scenario: array usage
29
+ Given a file named "example_spec.rb" with:
30
+ """
31
+ describe [0, 1, 2, 3, 4] do
32
+ it { should end_with 4 }
33
+ it { should end_with 3, 4 }
34
+ it { should_not end_with 3 }
35
+ it { should_not end_with 0, 1, 2, 3, 4, 5 }
36
+
37
+ # deliberate failures
38
+ it { should_not end_with 4 }
39
+ it { should end_with 3 }
40
+ end
41
+ """
42
+ When I run `rspec example_spec.rb`
43
+ Then the output should contain all of these:
44
+ | 6 examples, 2 failures |
45
+ | expected [0, 1, 2, 3, 4] not to end with 4 |
46
+ | expected [0, 1, 2, 3, 4] to end with 3 |
@@ -0,0 +1,46 @@
1
+ Feature: start_with matcher
2
+
3
+ Use the `start_with` matcher to specify that a string or array starts with
4
+ the expected characters or elements.
5
+
6
+ "this string".should start_with("this")
7
+ "this string".should_not start_with("that")
8
+ [0,1,2].should start_with(0, 1)
9
+
10
+ Scenario: with a string
11
+ Given a file named "example_spec.rb" with:
12
+ """
13
+ describe "this string" do
14
+ it { should start_with "this" }
15
+ it { should_not start_with "that" }
16
+
17
+ # deliberate failures
18
+ it { should_not start_with "this" }
19
+ it { should start_with "that" }
20
+ end
21
+ """
22
+ When I run `rspec example_spec.rb`
23
+ Then the output should contain all of these:
24
+ | 4 examples, 2 failures |
25
+ | expected "this string" not to start with "this" |
26
+ | expected "this string" to start with "that" |
27
+
28
+ Scenario: with an array
29
+ Given a file named "example_spec.rb" with:
30
+ """
31
+ describe [0, 1, 2, 3, 4] do
32
+ it { should start_with 0 }
33
+ it { should start_with(0, 1)}
34
+ it { should_not start_with(2) }
35
+ it { should_not start_with(0, 1, 2, 3, 4, 5) }
36
+
37
+ # deliberate failures
38
+ it { should_not start_with 0 }
39
+ it { should start_with 3 }
40
+ end
41
+ """
42
+ When I run `rspec example_spec.rb`
43
+ Then the output should contain all of these:
44
+ | 6 examples, 2 failures |
45
+ | expected [0, 1, 2, 3, 4] not to start with 0 |
46
+ | expected [0, 1, 2, 3, 4] to start with 3 |
@@ -0,0 +1,146 @@
1
+ Feature: yield matchers
2
+
3
+ There are four related matchers that allow you to specify whether
4
+ or not a method yields, how many times it yields, whether or not
5
+ it yields with arguments, and what those arguments are.
6
+
7
+ * `yield_control` matches if the method-under-test yields, regardless
8
+ of whether or not arguments are yielded.
9
+ * `yield_with_args` matches if the method-under-test yields with
10
+ arguments. If arguments are provided to this matcher, it will
11
+ only pass if the actual yielded arguments match the expected ones
12
+ using `===` or `==`.
13
+ * `yield_with_no_args` matches if the method-under-test yields with
14
+ no arguments.
15
+ * `yield_successive_args` is designed for iterators, and will match
16
+ if the method-under-test yields the same number of times as arguments
17
+ passed to this matcher, and all actual yielded arguments match the
18
+ expected ones using `===` or `==`.
19
+
20
+ Note: your expect block _must_ accept an argument that is then passed on to
21
+ the method-under-test as a block. This acts as a "probe" that allows the matcher
22
+ to detect whether or not your method yields, and, if so, how many times and what
23
+ the yielded arguments are.
24
+
25
+ Background:
26
+ Given a file named "my_class.rb" with:
27
+ """
28
+ class MyClass
29
+ def self.yield_once_with(*args)
30
+ yield *args
31
+ end
32
+
33
+ def self.raw_yield
34
+ yield
35
+ end
36
+
37
+ def self.dont_yield
38
+ end
39
+ end
40
+ """
41
+
42
+ Scenario: yield_control matcher
43
+ Given a file named "yield_control_spec.rb" with:
44
+ """
45
+ require './my_class'
46
+
47
+ describe "yield_control matcher" do
48
+ specify { expect { |b| MyClass.yield_once_with(1, &b) }.to yield_control }
49
+ specify { expect { |b| MyClass.dont_yield(&b) }.not_to yield_control }
50
+
51
+ # deliberate failures
52
+ specify { expect { |b| MyClass.yield_once_with(1, &b) }.not_to yield_control }
53
+ specify { expect { |b| MyClass.dont_yield(&b) }.to yield_control }
54
+ end
55
+ """
56
+ When I run `rspec yield_control_spec.rb`
57
+ Then the output should contain all of these:
58
+ | 4 examples, 2 failures |
59
+ | expected given block to yield control |
60
+ | expected given block not to yield control |
61
+
62
+ Scenario: yield_with_args matcher
63
+ Given a file named "yield_with_args_spec.rb" with:
64
+ """
65
+ require './my_class'
66
+
67
+ describe "yield_with_args matcher" do
68
+ specify { expect { |b| MyClass.yield_once_with("foo", &b) }.to yield_with_args }
69
+ specify { expect { |b| MyClass.yield_once_with("foo", &b) }.to yield_with_args("foo") }
70
+ specify { expect { |b| MyClass.yield_once_with("foo", &b) }.to yield_with_args(String) }
71
+ specify { expect { |b| MyClass.yield_once_with("foo", &b) }.to yield_with_args(/oo/) }
72
+
73
+ specify { expect { |b| MyClass.yield_once_with("foo", "bar", &b) }.to yield_with_args("foo", "bar") }
74
+ specify { expect { |b| MyClass.yield_once_with("foo", "bar", &b) }.to yield_with_args(String, String) }
75
+ specify { expect { |b| MyClass.yield_once_with("foo", "bar", &b) }.to yield_with_args(/fo/, /ar/) }
76
+
77
+ specify { expect { |b| MyClass.yield_once_with("foo", "bar", &b) }.not_to yield_with_args(17, "baz") }
78
+
79
+ # deliberate failures
80
+ specify { expect { |b| MyClass.yield_once_with("foo", &b) }.not_to yield_with_args }
81
+ specify { expect { |b| MyClass.yield_once_with("foo", &b) }.not_to yield_with_args("foo") }
82
+ specify { expect { |b| MyClass.yield_once_with("foo", &b) }.not_to yield_with_args(String) }
83
+ specify { expect { |b| MyClass.yield_once_with("foo", &b) }.not_to yield_with_args(/oo/) }
84
+ specify { expect { |b| MyClass.yield_once_with("foo", "bar", &b) }.not_to yield_with_args("foo", "bar") }
85
+ specify { expect { |b| MyClass.yield_once_with("foo", "bar", &b) }.to yield_with_args(17, "baz") }
86
+ end
87
+ """
88
+ When I run `rspec yield_with_args_spec.rb`
89
+ Then the output should contain all of these:
90
+ | 14 examples, 6 failures |
91
+ | expected given block not to yield with arguments, but did |
92
+ | expected given block not to yield with arguments, but yielded with expected arguments |
93
+ | expected given block to yield with arguments, but yielded with unexpected arguments |
94
+
95
+ Scenario: yield_with_no_args matcher
96
+ Given a file named "yield_with_no_args_spec.rb" with:
97
+ """
98
+ require './my_class'
99
+
100
+ describe "yield_with_no_args matcher" do
101
+ specify { expect { |b| MyClass.raw_yield(&b) }.to yield_with_no_args }
102
+ specify { expect { |b| MyClass.dont_yield(&b) }.not_to yield_with_no_args }
103
+ specify { expect { |b| MyClass.yield_once_with("a", &b) }.not_to yield_with_no_args }
104
+
105
+ # deliberate failures
106
+ specify { expect { |b| MyClass.raw_yield(&b) }.not_to yield_with_no_args }
107
+ specify { expect { |b| MyClass.dont_yield(&b) }.to yield_with_no_args }
108
+ specify { expect { |b| MyClass.yield_once_with("a", &b) }.to yield_with_no_args }
109
+ end
110
+ """
111
+ When I run `rspec yield_with_no_args_spec.rb`
112
+ Then the output should contain all of these:
113
+ | 6 examples, 3 failures |
114
+ | expected given block not to yield with no arguments, but did |
115
+ | expected given block to yield with no arguments, but did not yield |
116
+ | expected given block to yield with no arguments, but yielded with arguments: ["a"] |
117
+
118
+ Scenario: yield_successive_args matcher
119
+ Given a file named "yield_successive_args_spec.rb" with:
120
+ """
121
+ def array
122
+ [1, 2, 3]
123
+ end
124
+
125
+ def array_of_tuples
126
+ [[:a, :b], [:c, :d]]
127
+ end
128
+
129
+ describe "yield_successive_args matcher" do
130
+ specify { expect { |b| array.each(&b) }.to yield_successive_args(1, 2, 3) }
131
+ specify { expect { |b| array_of_tuples.each(&b) }.to yield_successive_args([:a, :b], [:c, :d]) }
132
+ specify { expect { |b| array.each(&b) }.to yield_successive_args(Fixnum, Fixnum, Fixnum) }
133
+ specify { expect { |b| array.each(&b) }.not_to yield_successive_args(1, 2) }
134
+
135
+ # deliberate failures
136
+ specify { expect { |b| array.each(&b) }.not_to yield_successive_args(1, 2, 3) }
137
+ specify { expect { |b| array_of_tuples.each(&b) }.not_to yield_successive_args([:a, :b], [:c, :d]) }
138
+ specify { expect { |b| array.each(&b) }.not_to yield_successive_args(Fixnum, Fixnum, Fixnum) }
139
+ specify { expect { |b| array.each(&b) }.to yield_successive_args(1, 2) }
140
+ end
141
+ """
142
+ When I run `rspec yield_successive_args_spec.rb`
143
+ Then the output should contain all of these:
144
+ | 8 examples, 4 failures |
145
+ | expected given block not to yield successively with arguments, but yielded with expected arguments |
146
+ | expected given block to yield successively with arguments, but yielded with unexpected arguments |
@@ -2,7 +2,7 @@ module RSpec
2
2
  module Expectations
3
3
  # @private
4
4
  module Version
5
- STRING = '2.9.1'
5
+ STRING = '2.10.0'
6
6
  end
7
7
  end
8
8
  end
@@ -355,6 +355,20 @@ module RSpec
355
355
  BuiltIn::Cover.new(*values)
356
356
  end if (1..2).respond_to?(:cover?)
357
357
 
358
+ # Matches if the actual value ends with the expected value(s). In the case
359
+ # of a string, matches against the last `expected.length` characters of the
360
+ # actual string. In the case of an array, matches against the last
361
+ # `expected.length` elements of the actual array.
362
+ #
363
+ # @example
364
+ #
365
+ # "this string".should end_with "string"
366
+ # [0, 1, 2, 3, 4].should end_with 4
367
+ # [0, 2, 3, 4, 4].should end_with 3, 4
368
+ def end_with(*expected)
369
+ BuiltIn::EndWith.new(*expected)
370
+ end
371
+
358
372
  # Passes if <tt>actual == expected</tt>.
359
373
  #
360
374
  # See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more information about equality in Ruby.
@@ -534,6 +548,20 @@ module RSpec
534
548
  BuiltIn::Satisfy.new(&block)
535
549
  end
536
550
 
551
+ # Matches if the actual value starts with the expected value(s). In the
552
+ # case of a string, matches against the first `expected.length` characters
553
+ # of the actual string. In the case of an array, matches against the first
554
+ # `expected.length` elements of the actual array.
555
+ #
556
+ # @example
557
+ #
558
+ # "this string".should start_with "this s"
559
+ # [0, 1, 2, 3, 4].should start_with 0
560
+ # [0, 2, 3, 4, 4].should start_with 0, 1
561
+ def start_with(*expected)
562
+ BuiltIn::StartWith.new(*expected)
563
+ end
564
+
537
565
  # Given no argument, matches if a proc throws any Symbol.
538
566
  #
539
567
  # Given a Symbol, matches if the given proc throws the specified Symbol.
@@ -554,6 +582,88 @@ module RSpec
554
582
  BuiltIn::ThrowSymbol.new(expected_symbol, expected_arg)
555
583
  end
556
584
 
585
+ # Passes if the method called in the expect block yields, regardless
586
+ # of whether or not arguments are yielded.
587
+ #
588
+ # @example
589
+ #
590
+ # expect { |b| 5.tap(&b) }.to yield_control
591
+ # expect { |b| "a".to_sym(&b) }.not_to yield_control
592
+ #
593
+ # @note Your expect block must accept a parameter and pass it on to
594
+ # the method-under-test as a block.
595
+ # @note This matcher is not designed for use with methods that yield
596
+ # multiple times.
597
+ def yield_control
598
+ BuiltIn::YieldControl.new
599
+ end
600
+
601
+ # Passes if the method called in the expect block yields with
602
+ # no arguments. Fails if it does not yield, or yields with arguments.
603
+ #
604
+ # @example
605
+ #
606
+ # expect { |b| User.transaction(&b) }.to yield_with_no_args
607
+ # expect { |b| 5.tap(&b) }.not_to yield_with_no_args # because it yields with `5`
608
+ # expect { |b| "a".to_sym(&b) }.not_to yield_with_no_args # because it does not yield
609
+ #
610
+ # @note Your expect block must accept a parameter and pass it on to
611
+ # the method-under-test as a block.
612
+ # @note This matcher is not designed for use with methods that yield
613
+ # multiple times.
614
+ def yield_with_no_args
615
+ BuiltIn::YieldWithNoArgs.new
616
+ end
617
+
618
+ # Given no arguments, matches if the method called in the expect
619
+ # block yields with arguments (regardless of what they are or how
620
+ # many there are).
621
+ #
622
+ # Given arguments, matches if the method called in the expect block
623
+ # yields with arguments that match the given arguments.
624
+ #
625
+ # Argument matching is done using `===` (the case match operator)
626
+ # and `==`. If the expected and actual arguments match with either
627
+ # operator, the matcher will pass.
628
+ #
629
+ # @example
630
+ #
631
+ # expect { |b| 5.tap(&b) }.to yield_with_args # because #tap yields an arg
632
+ # expect { |b| 5.tap(&b) }.to yield_with_args(5) # because 5 == 5
633
+ # expect { |b| 5.tap(&b) }.to yield_with_args(Fixnum) # because Fixnum === 5
634
+ # expect { |b| File.open("f.txt", &b) }.to yield_with_args(/txt/) # because /txt/ === "f.txt"
635
+ #
636
+ # expect { |b| User.transaction(&b) }.not_to yield_with_args # because it yields no args
637
+ # expect { |b| 5.tap(&b) }.not_to yield_with_args(1, 2, 3)
638
+ #
639
+ # @note Your expect block must accept a parameter and pass it on to
640
+ # the method-under-test as a block.
641
+ # @note This matcher is not designed for use with methods that yield
642
+ # multiple times.
643
+ def yield_with_args(*args)
644
+ BuiltIn::YieldWithArgs.new(*args)
645
+ end
646
+
647
+ # Designed for use with methods that repeatedly yield (such as
648
+ # iterators). Passes if the method called in the expect block yields
649
+ # multiple times with arguments matching those given.
650
+ #
651
+ # Argument matching is done using `===` (the case match operator)
652
+ # and `==`. If the expected and actual arguments match with either
653
+ # operator, the matcher will pass.
654
+ #
655
+ # @example
656
+ #
657
+ # expect { |b| [1, 2, 3].each(&b) }.to yield_successive_args(1, 2, 3)
658
+ # expect { |b| { :a => 1, :b => 2 }.each(&b) }.to yield_successive_args([:a, 1], [:b, 2])
659
+ # expect { |b| [1, 2, 3].each(&b) }.not_to yield_successive_args(1, 2)
660
+ #
661
+ # @note Your expect block must accept a parameter and pass it on to
662
+ # the method-under-test as a block.
663
+ def yield_successive_args(*args)
664
+ BuiltIn::YieldSuccessiveArgs.new(*args)
665
+ end
666
+
557
667
  # Passes if actual contains all of the expected regardless of order.
558
668
  # This works for collections. Pass in multiple args and it will only
559
669
  # pass if all args are found in collection.