rspec-expectations 2.9.1 → 2.10.0

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