rspec-expectations 2.0.0.a1 → 2.0.0.a2

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 (48) hide show
  1. data/.document +3 -3
  2. data/.gitignore +1 -0
  3. data/License.txt +2 -2
  4. data/Rakefile +17 -10
  5. data/Upgrade.markdown +38 -0
  6. data/lib/rspec/expectations.rb +1 -0
  7. data/lib/rspec/expectations/extensions.rb +1 -0
  8. data/lib/rspec/expectations/extensions/rspec/core/example_group.rb +19 -0
  9. data/lib/rspec/expectations/version.rb +16 -0
  10. data/lib/rspec/matchers.rb +0 -2
  11. data/lib/rspec/matchers/exist.rb +2 -2
  12. data/lib/rspec/matchers/extensions/instance_exec.rb +27 -19
  13. data/lib/rspec/matchers/include.rb +17 -16
  14. data/lib/rspec/matchers/matcher.rb +71 -25
  15. data/rspec-expectations.gemspec +66 -19
  16. data/spec/rspec/matchers/be_close_spec.rb +50 -0
  17. data/spec/rspec/matchers/be_instance_of_spec.rb +36 -0
  18. data/spec/rspec/matchers/be_kind_of_spec.rb +33 -0
  19. data/spec/rspec/matchers/be_spec.rb +311 -0
  20. data/spec/rspec/matchers/change_spec.rb +349 -0
  21. data/spec/rspec/matchers/compatibility_spec.rb +28 -0
  22. data/spec/rspec/matchers/description_generation_spec.rb +160 -0
  23. data/spec/rspec/matchers/dsl_spec.rb +25 -0
  24. data/spec/rspec/matchers/eql_spec.rb +33 -0
  25. data/spec/rspec/matchers/equal_spec.rb +57 -0
  26. data/spec/rspec/matchers/exist_spec.rb +65 -0
  27. data/spec/rspec/matchers/has_spec.rb +81 -0
  28. data/spec/rspec/matchers/have_spec.rb +407 -0
  29. data/spec/rspec/matchers/include_spec.rb +88 -0
  30. data/spec/rspec/matchers/match_array_spec.rb +108 -0
  31. data/spec/rspec/matchers/match_spec.rb +57 -0
  32. data/spec/rspec/matchers/matcher_methods_spec.rb +63 -0
  33. data/spec/rspec/matchers/matcher_spec.rb +289 -0
  34. data/spec/rspec/matchers/matchers_spec.rb +2 -0
  35. data/spec/rspec/matchers/operator_matcher_spec.rb +191 -0
  36. data/spec/rspec/matchers/raise_error_spec.rb +333 -0
  37. data/spec/rspec/matchers/respond_to_spec.rb +116 -0
  38. data/spec/rspec/matchers/satisfy_spec.rb +36 -0
  39. data/spec/rspec/matchers/throw_symbol_spec.rb +96 -0
  40. data/spec/spec_helper.rb +13 -1
  41. data/spec/support/classes.rb +51 -0
  42. metadata +60 -15
  43. data/VERSION +0 -1
  44. data/VERSION.yml +0 -5
  45. data/lib/rspec/matchers/simple_matcher.rb +0 -133
  46. data/lib/rspec/matchers/wrap_expectation.rb +0 -55
  47. data/spec/rspec/expectations/wrap_expectation_spec.rb +0 -30
  48. data/spec/support/macros.rb +0 -29
@@ -0,0 +1,50 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+ module Rspec
3
+ module Matchers
4
+ describe "[actual.should] be_close(expected, delta)" do
5
+ it "matches when actual == expected" do
6
+ be_close(5.0, 0.5).matches?(5.0).should be_true
7
+ end
8
+ it "matches when actual < (expected + delta)" do
9
+ be_close(5.0, 0.5).matches?(5.49).should be_true
10
+ end
11
+ it "matches when actual > (expected - delta)" do
12
+ be_close(5.0, 0.5).matches?(4.51).should be_true
13
+ end
14
+ it "does not match when actual == (expected - delta)" do
15
+ be_close(5.0, 0.5).matches?(4.5).should be_false
16
+ end
17
+ it "does not match when actual < (expected - delta)" do
18
+ be_close(5.0, 0.5).matches?(4.49).should be_false
19
+ end
20
+ it "does not match when actual == (expected + delta)" do
21
+ be_close(5.0, 0.5).matches?(5.5).should be_false
22
+ end
23
+ it "does not match when actual > (expected + delta)" do
24
+ be_close(5.0, 0.5).matches?(5.51).should be_false
25
+ end
26
+ it "provides a failure message for should" do
27
+ #given
28
+ matcher = be_close(5.0, 0.5)
29
+ #when
30
+ matcher.matches?(5.51)
31
+ #then
32
+ matcher.failure_message_for_should.should == "expected 5.0 +/- (< 0.5), got 5.51"
33
+ end
34
+
35
+ it "provides a failure message for should tno" do
36
+ #given
37
+ matcher = be_close(5.0, 0.5)
38
+ #when
39
+ matcher.matches?(5.49)
40
+ #then
41
+ matcher.failure_message_for_should_not.should == "expected 5.0 +/- (< 0.5), got 5.49"
42
+ end
43
+ it "provides a description" do
44
+ matcher = be_close(5.0, 0.5)
45
+ matcher.matches?(5.1)
46
+ matcher.description.should == "be close to 5.0 (within +- 0.5)"
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,36 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+
3
+ module Rspec
4
+ module Matchers
5
+ [:be_an_instance_of, :be_instance_of].each do |method|
6
+ describe "actual.should #{method}(expected)" do
7
+ it "passes if actual is instance of expected class" do
8
+ 5.should send(method, Fixnum)
9
+ end
10
+
11
+ it "fails if actual is instance of subclass of expected class" do
12
+ lambda { 5.should send(method, Numeric) }.should fail_with(%Q{expected 5 to be an instance of Numeric})
13
+ end
14
+
15
+ it "fails with failure message for should unless actual is instance of expected class" do
16
+ lambda { "foo".should send(method, Array) }.should fail_with(%Q{expected "foo" to be an instance of Array})
17
+ end
18
+
19
+ it "provides a description" do
20
+ matcher = be_an_instance_of(Fixnum)
21
+ matcher.matches?(Numeric)
22
+ matcher.description.should == "be an instance of Fixnum"
23
+ end
24
+ end
25
+
26
+ describe "actual.should_not #{method}(expected)" do
27
+
28
+ it "fails with failure message for should_not if actual is instance of expected class" do
29
+ lambda { "foo".should_not send(method, String) }.should fail_with(%Q{expected "foo" not to be an instance of String})
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,33 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+
3
+ module Rspec
4
+ module Matchers
5
+ [:be_a_kind_of, :be_kind_of].each do |method|
6
+ describe "actual.should #{method}(expected)" do
7
+ it "passes if actual is instance of expected class" do
8
+ 5.should send(method, Fixnum)
9
+ end
10
+
11
+ it "passes if actual is instance of subclass of expected class" do
12
+ 5.should send(method, Numeric)
13
+ end
14
+
15
+ it "fails with failure message for should unless actual is kind of expected class" do
16
+ lambda { "foo".should send(method, Array) }.should fail_with(%Q{expected "foo" to be a kind of Array})
17
+ end
18
+
19
+ it "provides a description" do
20
+ matcher = be_a_kind_of(String)
21
+ matcher.matches?("this")
22
+ matcher.description.should == "be a kind of String"
23
+ end
24
+ end
25
+
26
+ describe "actual.should_not #{method}(expected)" do
27
+ it "fails with failure message for should_not if actual is kind of expected class" do
28
+ lambda { "foo".should_not send(method, String) }.should fail_with(%Q{expected "foo" not to be a kind of String})
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,311 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+
3
+ describe "should be_predicate" do
4
+ it "should pass when actual returns true for :predicate?" do
5
+ actual = stub("actual", :happy? => true)
6
+ actual.should be_happy
7
+ end
8
+
9
+ it "should pass when actual returns true for :predicates? (present tense)" do
10
+ actual = stub("actual", :exists? => true, :exist? => true)
11
+ actual.should be_exist
12
+ end
13
+
14
+ it "should fail when actual returns false for :predicate?" do
15
+ actual = stub("actual", :happy? => false)
16
+ lambda {
17
+ actual.should be_happy
18
+ }.should fail_with("expected happy? to return true, got false")
19
+ end
20
+
21
+ it "should fail when actual returns false for :predicate?" do
22
+ actual = stub("actual", :happy? => nil)
23
+ lambda {
24
+ actual.should be_happy
25
+ }.should fail_with("expected happy? to return true, got nil")
26
+ end
27
+
28
+ it "should fail when actual does not respond to :predicate?" do
29
+ lambda {
30
+ Object.new.should be_happy
31
+ }.should raise_error(NameError, /happy\?/)
32
+ end
33
+
34
+ it "should fail on error other than NameError" do
35
+ actual = stub("actual")
36
+ actual.should_receive(:foo?).and_raise("aaaah")
37
+ lambda {
38
+ actual.should be_foo
39
+ }.should raise_error(/aaaah/)
40
+ end
41
+
42
+ it "should fail on error other than NameError (with the present tense predicate)" do
43
+ actual = Object.new
44
+ actual.should_receive(:foos?).and_raise("aaaah")
45
+ lambda {
46
+ actual.should be_foo
47
+ }.should raise_error(/aaaah/)
48
+ end
49
+ end
50
+
51
+ describe "should_not be_predicate" do
52
+ it "should pass when actual returns false for :sym?" do
53
+ actual = stub("actual", :happy? => false)
54
+ actual.should_not be_happy
55
+ end
56
+
57
+ it "should pass when actual returns nil for :sym?" do
58
+ actual = stub("actual", :happy? => nil)
59
+ actual.should_not be_happy
60
+ end
61
+
62
+ it "should fail when actual returns true for :sym?" do
63
+ actual = stub("actual", :happy? => true)
64
+ lambda {
65
+ actual.should_not be_happy
66
+ }.should fail_with("expected happy? to return false, got true")
67
+ end
68
+
69
+ it "should fail when actual does not respond to :sym?" do
70
+ lambda {
71
+ Object.new.should_not be_happy
72
+ }.should raise_error(NameError)
73
+ end
74
+ end
75
+
76
+ describe "should be_predicate(*args)" do
77
+ it "should pass when actual returns true for :predicate?(*args)" do
78
+ actual = mock("actual")
79
+ actual.should_receive(:older_than?).with(3).and_return(true)
80
+ actual.should be_older_than(3)
81
+ end
82
+
83
+ it "should fail when actual returns false for :predicate?(*args)" do
84
+ actual = mock("actual")
85
+ actual.should_receive(:older_than?).with(3).and_return(false)
86
+ lambda {
87
+ actual.should be_older_than(3)
88
+ }.should fail_with("expected older_than?(3) to return true, got false")
89
+ end
90
+
91
+ it "should fail when actual does not respond to :predicate?" do
92
+ lambda {
93
+ Object.new.should be_older_than(3)
94
+ }.should raise_error(NameError)
95
+ end
96
+ end
97
+
98
+ describe "should_not be_predicate(*args)" do
99
+ it "should pass when actual returns false for :predicate?(*args)" do
100
+ actual = mock("actual")
101
+ actual.should_receive(:older_than?).with(3).and_return(false)
102
+ actual.should_not be_older_than(3)
103
+ end
104
+
105
+ it "should fail when actual returns true for :predicate?(*args)" do
106
+ actual = mock("actual")
107
+ actual.should_receive(:older_than?).with(3).and_return(true)
108
+ lambda {
109
+ actual.should_not be_older_than(3)
110
+ }.should fail_with("expected older_than?(3) to return false, got true")
111
+ end
112
+
113
+ it "should fail when actual does not respond to :predicate?" do
114
+ lambda {
115
+ Object.new.should_not be_older_than(3)
116
+ }.should raise_error(NameError)
117
+ end
118
+ end
119
+
120
+ describe "should be_true" do
121
+ it "should pass when actual equal(true)" do
122
+ true.should be_true
123
+ end
124
+
125
+ it "should fail when actual equal(false)" do
126
+ lambda {
127
+ false.should be_true
128
+ }.should fail_with("expected true, got false")
129
+ end
130
+ end
131
+
132
+ describe "should be_false" do
133
+ it "should pass when actual equal(false)" do
134
+ false.should be_false
135
+ end
136
+
137
+ it "should fail when actual equal(true)" do
138
+ lambda {
139
+ true.should be_false
140
+ }.should fail_with("expected false, got true")
141
+ end
142
+ end
143
+
144
+ describe "should be_nil" do
145
+ it "should pass when actual is nil" do
146
+ nil.should be_nil
147
+ end
148
+
149
+ it "should fail when actual is not nil" do
150
+ lambda {
151
+ :not_nil.should be_nil
152
+ }.should fail_with("expected nil, got :not_nil")
153
+ end
154
+ end
155
+
156
+ describe "should_not be_nil" do
157
+ it "should pass when actual is not nil" do
158
+ :not_nil.should_not be_nil
159
+ end
160
+
161
+ it "should fail when actual is nil" do
162
+ lambda {
163
+ nil.should_not be_nil
164
+ }.should fail_with("expected not nil, got nil")
165
+ end
166
+ end
167
+
168
+ describe "should be <" do
169
+ it "should pass when < operator returns true" do
170
+ 3.should be < 4
171
+ end
172
+
173
+ it "should fail when < operator returns false" do
174
+ lambda { 3.should be < 3 }.should fail_with("expected < 3, got 3")
175
+ end
176
+ end
177
+
178
+ describe "should be <=" do
179
+ it "should pass when <= operator returns true" do
180
+ 3.should be <= 4
181
+ 4.should be <= 4
182
+ end
183
+
184
+ it "should fail when <= operator returns false" do
185
+ lambda { 3.should be <= 2 }.should fail_with("expected <= 2, got 3")
186
+ end
187
+ end
188
+
189
+ describe "should be >=" do
190
+ it "should pass when >= operator returns true" do
191
+ 4.should be >= 4
192
+ 5.should be >= 4
193
+ end
194
+
195
+ it "should fail when >= operator returns false" do
196
+ lambda { 3.should be >= 4 }.should fail_with("expected >= 4, got 3")
197
+ end
198
+ end
199
+
200
+ describe "should be >" do
201
+ it "should pass when > operator returns true" do
202
+ 5.should be > 4
203
+ end
204
+
205
+ it "should fail when > operator returns false" do
206
+ lambda { 3.should be > 4 }.should fail_with("expected > 4, got 3")
207
+ end
208
+ end
209
+
210
+ describe "should be ==" do
211
+ it "should pass when == operator returns true" do
212
+ 5.should be == 5
213
+ end
214
+
215
+ it "should fail when == operator returns false" do
216
+ lambda { 3.should be == 4 }.should fail_with("expected == 4, got 3")
217
+ end
218
+ end
219
+
220
+ describe "should be ===" do
221
+ it "should pass when === operator returns true" do
222
+ Hash.should be === Hash.new
223
+ end
224
+
225
+ it "should fail when === operator returns false" do
226
+ lambda { Hash.should be === "not a hash" }.should fail_with(%[expected === not a hash, got Hash])
227
+ end
228
+ end
229
+
230
+ describe "should_not with operators" do
231
+ it "should coach user to stop using operators with should_not" do
232
+ lambda {
233
+ 5.should_not be < 6
234
+ }.should raise_error(/not only FAILED,\nit is a bit confusing./m)
235
+ end
236
+ end
237
+
238
+ describe "should be" do
239
+ it "should pass if actual is true or a set value" do
240
+ true.should be
241
+ 1.should be
242
+ end
243
+
244
+ it "should fail if actual is false" do
245
+ lambda {false.should be}.should fail_with("expected true, got false")
246
+ end
247
+
248
+ it "should fail if actual is nil" do
249
+ lambda {nil.should be}.should fail_with("expected true, got nil")
250
+ end
251
+ end
252
+
253
+ describe "should be(value)" do
254
+ it "should pass if actual.equal?(value)" do
255
+ 5.should be(5)
256
+ end
257
+ it "should fail if !actual.equal?(value)" do
258
+ lambda { 5.should be(6) }.should fail_with("expected 6, got 5")
259
+ end
260
+ end
261
+
262
+ describe "'should be' with operator" do
263
+ it "should include 'be' in the description" do
264
+ (be > 6).description.should =~ /be > 6/
265
+ (be >= 6).description.should =~ /be >= 6/
266
+ (be <= 6).description.should =~ /be <= 6/
267
+ (be < 6).description.should =~ /be < 6/
268
+ end
269
+ end
270
+
271
+
272
+ describe "arbitrary predicate with DelegateClass" do
273
+ it "should access methods defined in the delegating class (LH[#48])" do
274
+ require 'delegate'
275
+ class ArrayDelegate < DelegateClass(Array)
276
+ def initialize(array)
277
+ @internal_array = array
278
+ super(@internal_array)
279
+ end
280
+
281
+ def large?
282
+ @internal_array.size >= 5
283
+ end
284
+ end
285
+
286
+ delegate = ArrayDelegate.new([1,2,3,4,5,6])
287
+ delegate.should be_large
288
+ end
289
+ end
290
+
291
+ describe "be_a, be_an" do
292
+ it "should pass when class matches" do
293
+ "foobar".should be_a(String)
294
+ [1,2,3].should be_an(Array)
295
+ end
296
+
297
+ it "should fail when class does not match" do
298
+ "foobar".should_not be_a(Hash)
299
+ [1,2,3].should_not be_an(Integer)
300
+ end
301
+ end
302
+
303
+ describe "be_an_instance_of" do
304
+ it "passes when direct class matches" do
305
+ 5.should be_an_instance_of(Fixnum)
306
+ end
307
+
308
+ it "fails when class is higher up hierarchy" do
309
+ 5.should_not be_an_instance_of(Numeric)
310
+ end
311
+ end
@@ -0,0 +1,349 @@
1
+ #Based on patch from Wilson Bilkovich
2
+
3
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
4
+ class SomethingExpected
5
+ attr_accessor :some_value
6
+ end
7
+
8
+ describe "should change(actual, message)" do
9
+ before(:each) do
10
+ @instance = SomethingExpected.new
11
+ @instance.some_value = 5
12
+ end
13
+
14
+ it "should pass when actual is modified by the block" do
15
+ expect {@instance.some_value = 6}.to change(@instance, :some_value)
16
+ end
17
+
18
+ it "should fail when actual is not modified by the block" do
19
+ expect do
20
+ expect {}.to change(@instance, :some_value)
21
+ end.to fail_with("some_value should have changed, but is still 5")
22
+ end
23
+
24
+ it "provides a #description" do
25
+ change(@instance, :some_value).description.should == "change #some_value"
26
+ end
27
+ end
28
+
29
+ describe "should_not change(actual, message)" do
30
+ before(:each) do
31
+ @instance = SomethingExpected.new
32
+ @instance.some_value = 5
33
+ end
34
+
35
+ it "should pass when actual is not modified by the block" do
36
+ expect { }.to_not change(@instance, :some_value)
37
+ end
38
+
39
+ it "should fail when actual is not modified by the block" do
40
+ expect do
41
+ expect {@instance.some_value = 6}.to_not change(@instance, :some_value)
42
+ end.to fail_with("some_value should not have changed, but did change from 5 to 6")
43
+ end
44
+ end
45
+
46
+ describe "should change { block }" do
47
+ before(:each) do
48
+ @instance = SomethingExpected.new
49
+ @instance.some_value = 5
50
+ end
51
+
52
+ it "should pass when actual is modified by the block" do
53
+ expect {@instance.some_value = 6}.to change { @instance.some_value }
54
+ end
55
+
56
+ it "should fail when actual is not modified by the block" do
57
+ expect do
58
+ expect {}.to change{ @instance.some_value }
59
+ end.to fail_with("result should have changed, but is still 5")
60
+ end
61
+
62
+ it "should warn if passed a block using do/end instead of {}" do
63
+ expect do
64
+ expect {}.to change do; end
65
+ end.to raise_error(Rspec::Matchers::MatcherError, /block passed to should or should_not/)
66
+ end
67
+
68
+ it "provides a #description" do
69
+ change { @instance.some_value }.description.should == "change #result"
70
+ end
71
+ end
72
+
73
+ describe "should_not change { block }" do
74
+ before(:each) do
75
+ @instance = SomethingExpected.new
76
+ @instance.some_value = 5
77
+ end
78
+
79
+ it "should pass when actual is modified by the block" do
80
+ expect {}.to_not change{ @instance.some_value }
81
+ end
82
+
83
+ it "should fail when actual is not modified by the block" do
84
+ expect do
85
+ expect {@instance.some_value = 6}.to_not change { @instance.some_value }
86
+ end.to fail_with("result should not have changed, but did change from 5 to 6")
87
+ end
88
+
89
+ it "should warn if passed a block using do/end instead of {}" do
90
+ expect do
91
+ expect {}.to_not change do; end
92
+ end.to raise_error(Rspec::Matchers::MatcherError, /block passed to should or should_not/)
93
+ end
94
+ end
95
+
96
+ describe "should change(actual, message).by(expected)" do
97
+ before(:each) do
98
+ @instance = SomethingExpected.new
99
+ @instance.some_value = 5
100
+ end
101
+
102
+ it "should pass when attribute is changed by expected amount" do
103
+ expect { @instance.some_value += 1 }.to change(@instance, :some_value).by(1)
104
+ end
105
+
106
+ it "should fail when the attribute is changed by unexpected amount" do
107
+ expect do
108
+ expect { @instance.some_value += 2 }.to change(@instance, :some_value).by(1)
109
+ end.to fail_with("some_value should have been changed by 1, but was changed by 2")
110
+ end
111
+
112
+ it "should fail when the attribute is changed by unexpected amount in the opposite direction" do
113
+ expect do
114
+ expect { @instance.some_value -= 1 }.to change(@instance, :some_value).by(1)
115
+ end.to fail_with("some_value should have been changed by 1, but was changed by -1")
116
+ end
117
+ end
118
+
119
+ describe "should change{ block }.by(expected)" do
120
+ before(:each) do
121
+ @instance = SomethingExpected.new
122
+ @instance.some_value = 5
123
+ end
124
+
125
+ it "should pass when attribute is changed by expected amount" do
126
+ expect { @instance.some_value += 1 }.to change{@instance.some_value}.by(1)
127
+ end
128
+
129
+ it "should fail when the attribute is changed by unexpected amount" do
130
+ expect do
131
+ expect { @instance.some_value += 2 }.to change{@instance.some_value}.by(1)
132
+ end.to fail_with("result should have been changed by 1, but was changed by 2")
133
+ end
134
+
135
+ it "should fail when the attribute is changed by unexpected amount in the opposite direction" do
136
+ expect do
137
+ expect { @instance.some_value -= 1 }.to change{@instance.some_value}.by(1)
138
+ end.to fail_with("result should have been changed by 1, but was changed by -1")
139
+ end
140
+ end
141
+
142
+ describe "should change(actual, message).by_at_least(expected)" do
143
+ before(:each) do
144
+ @instance = SomethingExpected.new
145
+ @instance.some_value = 5
146
+ end
147
+
148
+ it "should pass when attribute is changed by greater than the expected amount" do
149
+ expect { @instance.some_value += 2 }.to change(@instance, :some_value).by_at_least(1)
150
+ end
151
+
152
+ it "should pass when attribute is changed by the expected amount" do
153
+ expect { @instance.some_value += 2 }.to change(@instance, :some_value).by_at_least(2)
154
+ end
155
+
156
+ it "should fail when the attribute is changed by less than the expected amount" do
157
+ expect do
158
+ expect { @instance.some_value += 1 }.to change(@instance, :some_value).by_at_least(2)
159
+ end.to fail_with("some_value should have been changed by at least 2, but was changed by 1")
160
+ end
161
+
162
+ end
163
+
164
+ describe "should change{ block }.by_at_least(expected)" do
165
+ before(:each) do
166
+ @instance = SomethingExpected.new
167
+ @instance.some_value = 5
168
+ end
169
+
170
+ it "should pass when attribute is changed by greater than expected amount" do
171
+ expect { @instance.some_value += 2 }.to change{@instance.some_value}.by_at_least(1)
172
+ end
173
+
174
+ it "should pass when attribute is changed by the expected amount" do
175
+ expect { @instance.some_value += 2 }.to change{@instance.some_value}.by_at_least(2)
176
+ end
177
+
178
+ it "should fail when the attribute is changed by less than the unexpected amount" do
179
+ expect do
180
+ expect { @instance.some_value += 1 }.to change{@instance.some_value}.by_at_least(2)
181
+ end.to fail_with("result should have been changed by at least 2, but was changed by 1")
182
+ end
183
+ end
184
+
185
+
186
+ describe "should change(actual, message).by_at_most(expected)" do
187
+ before(:each) do
188
+ @instance = SomethingExpected.new
189
+ @instance.some_value = 5
190
+ end
191
+
192
+ it "should pass when attribute is changed by less than the expected amount" do
193
+ expect { @instance.some_value += 2 }.to change(@instance, :some_value).by_at_most(3)
194
+ end
195
+
196
+ it "should pass when attribute is changed by the expected amount" do
197
+ expect { @instance.some_value += 2 }.to change(@instance, :some_value).by_at_most(2)
198
+ end
199
+
200
+ it "should fail when the attribute is changed by greater than the expected amount" do
201
+ expect do
202
+ expect { @instance.some_value += 2 }.to change(@instance, :some_value).by_at_most(1)
203
+ end.to fail_with("some_value should have been changed by at most 1, but was changed by 2")
204
+ end
205
+
206
+ end
207
+
208
+ describe "should change{ block }.by_at_most(expected)" do
209
+ before(:each) do
210
+ @instance = SomethingExpected.new
211
+ @instance.some_value = 5
212
+ end
213
+
214
+ it "should pass when attribute is changed by less than expected amount" do
215
+ expect { @instance.some_value += 2 }.to change{@instance.some_value}.by_at_most(3)
216
+ end
217
+
218
+ it "should pass when attribute is changed by the expected amount" do
219
+ expect { @instance.some_value += 2 }.to change{@instance.some_value}.by_at_most(2)
220
+ end
221
+
222
+ it "should fail when the attribute is changed by greater than the unexpected amount" do
223
+ expect do
224
+ expect { @instance.some_value += 2 }.to change{@instance.some_value}.by_at_most(1)
225
+ end.to fail_with("result should have been changed by at most 1, but was changed by 2")
226
+ end
227
+ end
228
+
229
+ describe "should change(actual, message).from(old)" do
230
+ before(:each) do
231
+ @instance = SomethingExpected.new
232
+ @instance.some_value = 'string'
233
+ end
234
+
235
+ it "should pass when attribute is == to expected value before executing block" do
236
+ expect { @instance.some_value = "astring" }.to change(@instance, :some_value).from("string")
237
+ end
238
+
239
+ it "should fail when attribute is not == to expected value before executing block" do
240
+ expect do
241
+ expect { @instance.some_value = "knot" }.to change(@instance, :some_value).from("cat")
242
+ end.to fail_with("some_value should have initially been \"cat\", but was \"string\"")
243
+ end
244
+ end
245
+
246
+ describe "should change{ block }.from(old)" do
247
+ before(:each) do
248
+ @instance = SomethingExpected.new
249
+ @instance.some_value = 'string'
250
+ end
251
+
252
+ it "should pass when attribute is == to expected value before executing block" do
253
+ expect { @instance.some_value = "astring" }.to change{@instance.some_value}.from("string")
254
+ end
255
+
256
+ it "should fail when attribute is not == to expected value before executing block" do
257
+ expect do
258
+ expect { @instance.some_value = "knot" }.to change{@instance.some_value}.from("cat")
259
+ end.to fail_with("result should have initially been \"cat\", but was \"string\"")
260
+ end
261
+ end
262
+
263
+ describe "should change(actual, message).to(new)" do
264
+ before(:each) do
265
+ @instance = SomethingExpected.new
266
+ @instance.some_value = 'string'
267
+ end
268
+
269
+ it "should pass when attribute is == to expected value after executing block" do
270
+ expect { @instance.some_value = "cat" }.to change(@instance, :some_value).to("cat")
271
+ end
272
+
273
+ it "should fail when attribute is not == to expected value after executing block" do
274
+ expect do
275
+ expect { @instance.some_value = "cat" }.to change(@instance, :some_value).from("string").to("dog")
276
+ end.to fail_with("some_value should have been changed to \"dog\", but is now \"cat\"")
277
+ end
278
+ end
279
+
280
+ describe "should change{ block }.to(new)" do
281
+ before(:each) do
282
+ @instance = SomethingExpected.new
283
+ @instance.some_value = 'string'
284
+ end
285
+
286
+ it "should pass when attribute is == to expected value after executing block" do
287
+ expect { @instance.some_value = "cat" }.to change{@instance.some_value}.to("cat")
288
+ end
289
+
290
+ it "should fail when attribute is not == to expected value after executing block" do
291
+ expect do
292
+ expect { @instance.some_value = "cat" }.to change{@instance.some_value}.from("string").to("dog")
293
+ end.to fail_with("result should have been changed to \"dog\", but is now \"cat\"")
294
+ end
295
+ end
296
+
297
+ describe "should change(actual, message).from(old).to(new)" do
298
+ before(:each) do
299
+ @instance = SomethingExpected.new
300
+ @instance.some_value = 'string'
301
+ end
302
+
303
+ it "should pass when #to comes before #from" do
304
+ expect { @instance.some_value = "cat" }.to change(@instance, :some_value).to("cat").from("string")
305
+ end
306
+
307
+ it "should pass when #from comes before #to" do
308
+ expect { @instance.some_value = "cat" }.to change(@instance, :some_value).from("string").to("cat")
309
+ end
310
+
311
+ it "should show the correct messaging when #after and #to are different" do
312
+ expect do
313
+ expect { @instance.some_value = "cat" }.to change(@instance, :some_value).from("string").to("dog")
314
+ end.to fail_with("some_value should have been changed to \"dog\", but is now \"cat\"")
315
+ end
316
+
317
+ it "should show the correct messaging when #before and #from are different" do
318
+ expect do
319
+ expect { @instance.some_value = "cat" }.to change(@instance, :some_value).from("not_string").to("cat")
320
+ end.to fail_with("some_value should have initially been \"not_string\", but was \"string\"")
321
+ end
322
+ end
323
+
324
+ describe "should change{ block }.from(old).to(new)" do
325
+ before(:each) do
326
+ @instance = SomethingExpected.new
327
+ @instance.some_value = 'string'
328
+ end
329
+
330
+ it "should pass when #to comes before #from" do
331
+ expect { @instance.some_value = "cat" }.to change{@instance.some_value}.to("cat").from("string")
332
+ end
333
+
334
+ it "should pass when #from comes before #to" do
335
+ expect { @instance.some_value = "cat" }.to change{@instance.some_value}.from("string").to("cat")
336
+ end
337
+ end
338
+
339
+ describe Rspec::Matchers::Change do
340
+ it "should work when the receiver has implemented #send" do
341
+ @instance = SomethingExpected.new
342
+ @instance.some_value = "string"
343
+ def @instance.send(*args); raise "DOH! Library developers shouldn't use #send!" end
344
+
345
+ expect {
346
+ expect { @instance.some_value = "cat" }.to change(@instance, :some_value)
347
+ }.to_not raise_error
348
+ end
349
+ end