rspec-expectations 2.5.0 → 2.6.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. data/.travis.yml +7 -0
  2. data/Gemfile +13 -11
  3. data/README.md +2 -0
  4. data/Rakefile +28 -17
  5. data/features/Changelog.md +16 -0
  6. data/features/built_in_matchers/be.feature +4 -4
  7. data/features/built_in_matchers/be_within.feature +1 -1
  8. data/features/built_in_matchers/equality.feature +5 -5
  9. data/features/built_in_matchers/exist.feature +1 -1
  10. data/features/built_in_matchers/expect_change.feature +2 -2
  11. data/features/built_in_matchers/expect_error.feature +7 -7
  12. data/features/built_in_matchers/have.feature +2 -2
  13. data/features/built_in_matchers/include.feature +3 -3
  14. data/features/built_in_matchers/match.feature +2 -2
  15. data/features/built_in_matchers/operators.feature +3 -3
  16. data/features/built_in_matchers/predicates.feature +5 -5
  17. data/features/built_in_matchers/respond_to.feature +2 -2
  18. data/features/built_in_matchers/satisfy.feature +1 -1
  19. data/features/built_in_matchers/throw_symbol.feature +3 -3
  20. data/features/built_in_matchers/types.feature +2 -2
  21. data/features/custom_matchers/access_running_example.feature +2 -2
  22. data/features/custom_matchers/define_diffable_matcher.feature +1 -1
  23. data/features/custom_matchers/define_matcher.feature +40 -11
  24. data/features/custom_matchers/define_matcher_outside_rspec.feature +1 -1
  25. data/features/custom_matchers/define_matcher_with_fluent_interface.feature +1 -1
  26. data/features/customized_message.feature +1 -1
  27. data/features/diffing.feature +4 -4
  28. data/features/implicit_docstrings.feature +2 -2
  29. data/features/step_definitions/additional_cli_steps.rb +2 -2
  30. data/features/support/env.rb +5 -1
  31. data/features/test_frameworks/test_unit.feature +1 -1
  32. data/lib/rspec/expectations/backward_compatibility.rb +22 -1
  33. data/lib/rspec/expectations/version.rb +1 -1
  34. data/lib/rspec/matchers.rb +10 -5
  35. data/lib/rspec/matchers/change.rb +47 -32
  36. data/lib/rspec/matchers/has.rb +15 -11
  37. data/lib/rspec/matchers/matcher.rb +4 -0
  38. data/spec/rspec/matchers/be_spec.rb +0 -4
  39. data/spec/rspec/matchers/change_spec.rb +84 -9
  40. data/spec/rspec/matchers/description_generation_spec.rb +41 -25
  41. data/spec/rspec/matchers/has_spec.rb +2 -2
  42. data/spec/rspec/matchers/have_spec.rb +21 -21
  43. data/spec/rspec/matchers/matcher_spec.rb +46 -0
  44. data/spec/rspec/matchers/matchers_spec.rb +3 -23
  45. data/spec/rspec/matchers/method_missing_spec.rb +23 -0
  46. data/spec/spec_helper.rb +2 -0
  47. metadata +23 -18
  48. data/spec/suite.rb +0 -1
@@ -41,7 +41,7 @@ Feature: respond_to matcher
41
41
  it { should_not respond_to(:length, :flatten) }
42
42
  end
43
43
  """
44
- When I run "rspec respond_to_matcher_spec.rb"
44
+ When I run `rspec respond_to_matcher_spec.rb`
45
45
  Then the output should contain all of these:
46
46
  | 10 examples, 6 failures |
47
47
  | expected "a string" to respond to :to_model |
@@ -69,7 +69,7 @@ Feature: respond_to matcher
69
69
  it { should_not respond_to(:between?).with(2).arguments }
70
70
  end
71
71
  """
72
- When I run "rspec respond_to_matcher_argument_checking_spec.rb"
72
+ When I run `rspec respond_to_matcher_argument_checking_spec.rb`
73
73
  Then the output should contain all of these:
74
74
  | 8 examples, 4 failures |
75
75
  | expected 7 to respond to :zero? with 1 argument |
@@ -23,7 +23,7 @@ Feature: satisfy matcher
23
23
  it { should satisfy { |v| v > 15 } }
24
24
  end
25
25
  """
26
- When I run "rspec satisfy_matcher_spec.rb"
26
+ When I run `rspec satisfy_matcher_spec.rb`
27
27
  Then the output should contain all of these:
28
28
  | 4 examples, 2 failures |
29
29
  | expected 10 not to satisfy block |
@@ -28,7 +28,7 @@ Feature: throw_symbol matcher
28
28
  specify { expect { 5 + 5 }.to throw_symbol }
29
29
  end
30
30
  """
31
- When I run "rspec throw_symbol_matcher_spec.rb"
31
+ When I run `rspec throw_symbol_matcher_spec.rb`
32
32
  Then the output should contain all of these:
33
33
  | 6 examples, 3 failures |
34
34
  | expected no Symbol to be thrown, got :foo |
@@ -51,7 +51,7 @@ Feature: throw_symbol matcher
51
51
  specify { expect { throw :bar }.to throw_symbol(:foo) }
52
52
  end
53
53
  """
54
- When I run "rspec throw_symbol_matcher_spec.rb"
54
+ When I run `rspec throw_symbol_matcher_spec.rb`
55
55
  Then the output should contain all of these:
56
56
  | 8 examples, 4 failures |
57
57
  | expected :foo not to be thrown, got :foo |
@@ -75,7 +75,7 @@ Feature: throw_symbol matcher
75
75
  specify { expect { throw :foo }.to throw_symbol(:foo, 7) }
76
76
  end
77
77
  """
78
- When I run "rspec throw_symbol_argument_matcher_spec.rb"
78
+ When I run `rspec throw_symbol_argument_matcher_spec.rb`
79
79
  Then the output should contain all of these:
80
80
  | 8 examples, 4 failures |
81
81
  | expected :foo with 7 not to be thrown, got :foo with 7 |
@@ -60,7 +60,7 @@ Feature: specify types of objects
60
60
  it { should be_a(String) }
61
61
  end
62
62
  """
63
- When I run "rspec be_kind_of_matcher_spec.rb"
63
+ When I run `rspec be_kind_of_matcher_spec.rb`
64
64
  Then the output should contain all of these:
65
65
  | 24 examples, 12 failures |
66
66
  | expected 17 not to be a kind of Fixnum |
@@ -105,7 +105,7 @@ Feature: specify types of objects
105
105
  it { should be_an_instance_of(String) }
106
106
  end
107
107
  """
108
- When I run "rspec be_instance_of_matcher_spec.rb"
108
+ When I run `rspec be_instance_of_matcher_spec.rb`
109
109
  Then the output should contain all of these:
110
110
  | 16 examples, 8 failures |
111
111
  | expected 17 not to be an instance of Fixnum |
@@ -28,7 +28,7 @@ Feature: access running example
28
28
  end
29
29
  end
30
30
  """
31
- When I run "rspec ./example_spec.rb"
31
+ When I run `rspec ./example_spec.rb`
32
32
  Then the output should contain "1 example, 0 failures"
33
33
 
34
34
  Scenario: call method _not_ defined on example from matcher
@@ -46,7 +46,7 @@ Feature: access running example
46
46
  end
47
47
  end
48
48
  """
49
- When I run "rspec ./example_spec.rb"
49
+ When I run `rspec ./example_spec.rb`
50
50
  Then the output should contain "1 example, 1 failure"
51
51
  And the output should contain "undefined local variable"
52
52
  And the output should contain "RSpec::Matchers::Matcher"
@@ -20,7 +20,7 @@ Feature: define diffable matcher
20
20
  it {should be_just_like("that")}
21
21
  end
22
22
  """
23
- When I run "rspec ./diffable_matcher_spec.rb --diff"
23
+ When I run `rspec ./diffable_matcher_spec.rb --diff`
24
24
  Then the exit status should not be 0
25
25
 
26
26
  And the output should contain "should be just like that"
@@ -34,7 +34,7 @@ Feature: define matcher
34
34
  end
35
35
 
36
36
  """
37
- When I run "rspec ./matcher_with_default_message_spec.rb --format documentation"
37
+ When I run `rspec ./matcher_with_default_message_spec.rb --format documentation`
38
38
  Then the exit status should not be 0
39
39
 
40
40
  And the output should contain "should be a multiple of 3"
@@ -65,7 +65,7 @@ Feature: define matcher
65
65
  it {should be_a_multiple_of(4)}
66
66
  end
67
67
  """
68
- When I run "rspec ./matcher_with_failure_message_spec.rb"
68
+ When I run `rspec ./matcher_with_failure_message_spec.rb`
69
69
  Then the exit status should not be 0
70
70
  And the stdout should contain "1 example, 1 failure"
71
71
  And the stdout should contain "expected that 9 would be a multiple of 4"
@@ -89,7 +89,7 @@ Feature: define matcher
89
89
  it {should_not be_a_multiple_of(3)}
90
90
  end
91
91
  """
92
- When I run "rspec ./matcher_with_failure_for_message_spec.rb"
92
+ When I run `rspec ./matcher_with_failure_for_message_spec.rb`
93
93
  Then the exit status should not be 0
94
94
  And the stdout should contain "1 example, 1 failure"
95
95
  And the stdout should contain "expected that 9 would not be a multiple of 3"
@@ -116,7 +116,7 @@ Feature: define matcher
116
116
  it {should_not be_a_multiple_of(4)}
117
117
  end
118
118
  """
119
- When I run "rspec ./matcher_overriding_description_spec.rb --format documentation"
119
+ When I run `rspec ./matcher_overriding_description_spec.rb --format documentation`
120
120
  Then the exit status should be 0
121
121
  And the stdout should contain "2 examples, 0 failures"
122
122
  And the stdout should contain "should be multiple of 3"
@@ -141,7 +141,7 @@ Feature: define matcher
141
141
  it {should have_7_fingers}
142
142
  end
143
143
  """
144
- When I run "rspec ./matcher_with_no_args_spec.rb --format documentation"
144
+ When I run `rspec ./matcher_with_no_args_spec.rb --format documentation`
145
145
  Then the exit status should be 0
146
146
  And the stdout should contain "1 example, 0 failures"
147
147
  And the stdout should contain "should have 7 fingers"
@@ -161,7 +161,7 @@ Feature: define matcher
161
161
  it {should be_the_sum_of(1,2,3,4)}
162
162
  end
163
163
  """
164
- When I run "rspec ./matcher_with_multiple_args_spec.rb --format documentation"
164
+ When I run `rspec ./matcher_with_multiple_args_spec.rb --format documentation`
165
165
  Then the exit status should be 0
166
166
  And the stdout should contain "1 example, 0 failures"
167
167
  And the stdout should contain "should be the sum of 1, 2, 3, and 4"
@@ -187,7 +187,7 @@ Feature: define matcher
187
187
  end
188
188
  end
189
189
  """
190
- When I run "rspec ./matcher_with_internal_helper_spec.rb"
190
+ When I run `rspec ./matcher_with_internal_helper_spec.rb`
191
191
  Then the exit status should be 0
192
192
  And the stdout should contain "1 example, 0 failures"
193
193
 
@@ -220,7 +220,7 @@ Feature: define matcher
220
220
  end
221
221
  """
222
222
 
223
- When I run "rspec ./scoped_matcher_spec.rb"
223
+ When I run `rspec ./scoped_matcher_spec.rb`
224
224
  Then the stdout should contain "2 examples, 0 failures"
225
225
 
226
226
  Scenario: scoped in an example group
@@ -254,7 +254,7 @@ Feature: define matcher
254
254
  end
255
255
  """
256
256
 
257
- When I run "rspec scoped_matcher_spec.rb"
257
+ When I run `rspec scoped_matcher_spec.rb`
258
258
  Then the output should contain "3 examples, 0 failures"
259
259
 
260
260
  Scenario: matcher with separate logic for should and should_not
@@ -279,7 +279,7 @@ Feature: define matcher
279
279
  it { should_not contain(1, 4) }
280
280
  end
281
281
  """
282
- When I run "rspec matcher_with_separate_should_not_logic_spec.rb"
282
+ When I run `rspec matcher_with_separate_should_not_logic_spec.rb`
283
283
  Then the output should contain all of these:
284
284
  | 4 examples, 2 failures |
285
285
  | expected [1, 2, 3] to contain 1 and 4 |
@@ -304,7 +304,36 @@ Feature: define matcher
304
304
  it { should_not be_a_multiple_of(3) }
305
305
  end
306
306
  """
307
- When I run "rspec define_method_spec.rb"
307
+ When I run `rspec define_method_spec.rb`
308
+ Then the output should contain all of these:
309
+ | 4 examples, 2 failures |
310
+ | expected 9 to be a multiple of 2 |
311
+ | expected 9 not to be a multiple of 3 |
312
+
313
+ Scenario: include a module with helper methods in the matcher
314
+ Given a file named "include_module_spec.rb" with:
315
+ """
316
+ module MatcherHelpers
317
+ def is_multiple?(actual, expected)
318
+ actual % expected == 0
319
+ end
320
+ end
321
+
322
+ RSpec::Matchers.define :be_a_multiple_of do |expected|
323
+ include MatcherHelpers
324
+ match { |actual| is_multiple?(actual, expected) }
325
+ end
326
+
327
+ describe 9 do
328
+ it { should be_a_multiple_of(3) }
329
+ it { should_not be_a_multiple_of(4) }
330
+
331
+ # deliberate failures
332
+ it { should be_a_multiple_of(2) }
333
+ it { should_not be_a_multiple_of(3) }
334
+ end
335
+ """
336
+ When I run `rspec include_module_spec.rb`
308
337
  Then the output should contain all of these:
309
338
  | 4 examples, 2 failures |
310
339
  | expected 9 to be a multiple of 2 |
@@ -32,7 +32,7 @@ Feature: define matcher outside rspec
32
32
 
33
33
  end
34
34
  """
35
- When I run "ruby test_multiples.rb"
35
+ When I run `ruby test_multiples.rb`
36
36
  Then the exit status should not be 0
37
37
  And the output should contain "expected 9 to be a multiple of 4"
38
38
  And the output should contain "2 tests, 0 assertions, 0 failures, 1 errors"
@@ -19,6 +19,6 @@ Feature: define matcher with fluent interface
19
19
  it { should be_bigger_than(4).but_smaller_than(6) }
20
20
  end
21
21
  """
22
- When I run "rspec between_spec.rb --format documentation"
22
+ When I run `rspec between_spec.rb --format documentation`
23
23
  Then the output should contain "1 example, 0 failures"
24
24
  And the output should contain "should be bigger than 4"
@@ -18,5 +18,5 @@ Feature: customized message
18
18
  end
19
19
 
20
20
  """
21
- When I run "rspec example_spec.rb --format documentation"
21
+ When I run `rspec example_spec.rb --format documentation`
22
22
  Then the output should contain "expected empty array, got [1]"
@@ -21,7 +21,7 @@ Feature: diffing
21
21
  end
22
22
  end
23
23
  """
24
- When I run "rspec example_spec.rb"
24
+ When I run `rspec example_spec.rb`
25
25
  Then the output should contain:
26
26
  """
27
27
  Diff:
@@ -47,7 +47,7 @@ Feature: diffing
47
47
  end
48
48
  end
49
49
  """
50
- When I run "rspec example_spec.rb"
50
+ When I run `rspec example_spec.rb`
51
51
  Then the output should contain:
52
52
  """
53
53
  Diff:
@@ -69,7 +69,7 @@ Feature: diffing
69
69
  end
70
70
  end
71
71
  """
72
- When I run "rspec example_spec.rb"
72
+ When I run `rspec example_spec.rb`
73
73
  Then the output should not contain "Diff:"
74
74
 
75
75
  Scenario: no diff for numbers
@@ -81,5 +81,5 @@ Feature: diffing
81
81
  end
82
82
  end
83
83
  """
84
- When I run "rspec example_spec.rb"
84
+ When I run `rspec example_spec.rb`
85
85
  Then the output should not contain "Diff:"
@@ -18,7 +18,7 @@ Feature: implicit docstrings
18
18
  end
19
19
  """
20
20
 
21
- When I run "rspec ./implicit_docstrings_spec.rb -fdoc"
21
+ When I run `rspec ./implicit_docstrings_spec.rb -fdoc`
22
22
 
23
23
  Then the output should contain "should be < 5"
24
24
  And the output should contain "should include 2"
@@ -44,7 +44,7 @@ Feature: implicit docstrings
44
44
  end
45
45
  """
46
46
 
47
- When I run "rspec ./failing_implicit_docstrings_spec.rb -fdoc"
47
+ When I run `rspec ./failing_implicit_docstrings_spec.rb -fdoc`
48
48
 
49
49
  Then the output should contain "should equal 2"
50
50
  And the output should contain "should be > 5"
@@ -1,7 +1,7 @@
1
1
  # Useful for when the output is slightly different on different versions of ruby
2
2
  Then /^the output should contain "([^"]*)" or "([^"]*)"$/ do |string1, string2|
3
- unless [string1, string2].any? { |s| combined_output =~ Regexp.compile(s) }
4
- fail %Q{Neither "#{string1}" or "#{string2}" were found in:\n#{combined_output}}
3
+ unless [string1, string2].any? { |s| all_output =~ regexp(s) }
4
+ fail %Q{Neither "#{string1}" or "#{string2}" were found in:\n#{all_output}}
5
5
  end
6
6
  end
7
7
 
@@ -1 +1,5 @@
1
- require 'aruba'
1
+ require 'aruba/cucumber'
2
+
3
+ Before do
4
+ @aruba_timeout_seconds = 3
5
+ end
@@ -40,7 +40,7 @@ Feature: Test::Unit integration
40
40
  end
41
41
  end
42
42
  """
43
- When I run "ruby rspec_expectations_test.rb"
43
+ When I run `ruby rspec_expectations_test.rb`
44
44
  Then the output should contain "4 tests, 0 assertions, 1 failures, 0 errors" or "4 tests, 0 assertions, 0 failures, 1 errors"
45
45
  And the output should contain "expected empty? to return true, got false"
46
46
  And the output should contain "be_an_int is deprecated"
@@ -3,7 +3,28 @@ module RSpec
3
3
  module Expectations
4
4
  module ConstMissing
5
5
  def const_missing(name)
6
- name == :Rspec ? RSpec : super(name)
6
+ case name
7
+ when :Rspec, :Spec
8
+ RSpec.warn_deprecation <<-WARNING
9
+ *****************************************************************
10
+ DEPRECATION WARNING: you are using a deprecated constant that will
11
+ be removed from a future version of RSpec.
12
+
13
+ #{caller(0)[2]}
14
+
15
+ * #{name} is deprecated.
16
+ * RSpec is the new top-level module in RSpec-2
17
+ ***************************************************************
18
+ WARNING
19
+ RSpec
20
+ else
21
+ begin
22
+ super
23
+ rescue Exception => e
24
+ e.backtrace.reject! {|l| l =~ Regexp.compile(__FILE__) }
25
+ raise e
26
+ end
27
+ end
7
28
  end
8
29
  end
9
30
 
@@ -1,7 +1,7 @@
1
1
  module RSpec # :nodoc:
2
2
  module Expectations # :nodoc:
3
3
  module Version # :nodoc:
4
- STRING = '2.5.0'
4
+ STRING = '2.6.0.rc2'
5
5
  end
6
6
  end
7
7
  end
@@ -16,7 +16,7 @@ module RSpec
16
16
  #
17
17
  # In addition to those Expression Matchers that are defined explicitly, RSpec will
18
18
  # create custom Matchers on the fly for any arbitrary predicate, giving your specs
19
- # a much more natural language feel.
19
+ # a much more natural language feel.
20
20
  #
21
21
  # A Ruby predicate is a method that ends with a "?" and returns true or false.
22
22
  # Common examples are +empty?+, +nil?+, and +instance_of?+.
@@ -155,13 +155,18 @@ module RSpec
155
155
  # end
156
156
  #
157
157
  module Matchers
158
- # Include Matchers for other test frameworks
159
- if defined?(Test::Unit::TestCase)
160
- Test::Unit::TestCase.send(:include, self)
161
- end
158
+ # Include Matchers for other test frameworks.
159
+ # Note that MiniTest _must_ come before TU because on ruby 1.9,
160
+ # T::U::TC is a subclass of MT::U::TC and a 1.9 bug can lead
161
+ # to infinite recursion from the `super` call in our method_missing
162
+ # hook. See this gist for more info:
163
+ # https://gist.github.com/845896
162
164
  if defined?(MiniTest::Unit::TestCase)
163
165
  MiniTest::Unit::TestCase.send(:include, self)
164
166
  end
167
+ if defined?(Test::Unit::TestCase)
168
+ Test::Unit::TestCase.send(:include, self)
169
+ end
165
170
  end
166
171
  end
167
172
 
@@ -1,23 +1,21 @@
1
1
  module RSpec
2
2
  module Matchers
3
-
4
- #Based on patch from Wilson Bilkovich
5
3
  class Change #:nodoc:
6
4
  def initialize(receiver=nil, message=nil, &block)
7
5
  @message = message
8
6
  @value_proc = block || lambda {receiver.__send__(message)}
9
- @to = @from = @minimum = @maximum = @amount = nil
10
- @given_from = @given_to = false
7
+ @expected_after = @expected_before = @minimum = @maximum = @expected_delta = nil
8
+ @eval_before = @eval_after = false
11
9
  end
12
10
 
13
11
  def matches?(event_proc)
14
12
  raise_block_syntax_error if block_given?
15
13
 
16
- @before = evaluate_value_proc
14
+ @actual_before = evaluate_value_proc
17
15
  event_proc.call
18
- @after = evaluate_value_proc
16
+ @actual_after = evaluate_value_proc
19
17
 
20
- (!change_expected? || changed?) && matches_before? && matches_after? && matches_amount? && matches_min? && matches_max?
18
+ (!change_expected? || changed?) && matches_before? && matches_after? && matches_expected_delta? && matches_min? && matches_max?
21
19
  end
22
20
 
23
21
  def raise_block_syntax_error
@@ -28,35 +26,40 @@ MESSAGE
28
26
  end
29
27
 
30
28
  def evaluate_value_proc
31
- @value_proc.call
29
+ case val = @value_proc.call
30
+ when Array, Hash
31
+ val.dup
32
+ else
33
+ val
34
+ end
32
35
  end
33
36
 
34
37
  def failure_message_for_should
35
- if @given_from && @before != @from
36
- "#{message} should have initially been #{@from.inspect}, but was #{@before.inspect}"
37
- elsif @given_to && @to != @after
38
- "#{message} should have been changed to #{@to.inspect}, but is now #{@after.inspect}"
39
- elsif @amount
40
- "#{message} should have been changed by #{@amount.inspect}, but was changed by #{actual_delta.inspect}"
38
+ if @eval_before && !expected_matches_actual?(@expected_before, @actual_before)
39
+ "#{message} should have initially been #{@expected_before.inspect}, but was #{@actual_before.inspect}"
40
+ elsif @eval_after && !expected_matches_actual?(@expected_after, @actual_after)
41
+ "#{message} should have been changed to #{@expected_after.inspect}, but is now #{@actual_after.inspect}"
42
+ elsif @expected_delta
43
+ "#{message} should have been changed by #{@expected_delta.inspect}, but was changed by #{actual_delta.inspect}"
41
44
  elsif @minimum
42
45
  "#{message} should have been changed by at least #{@minimum.inspect}, but was changed by #{actual_delta.inspect}"
43
46
  elsif @maximum
44
47
  "#{message} should have been changed by at most #{@maximum.inspect}, but was changed by #{actual_delta.inspect}"
45
48
  else
46
- "#{message} should have changed, but is still #{@before.inspect}"
49
+ "#{message} should have changed, but is still #{@actual_before.inspect}"
47
50
  end
48
51
  end
49
52
 
50
53
  def actual_delta
51
- @after - @before
54
+ @actual_after - @actual_before
52
55
  end
53
56
 
54
57
  def failure_message_for_should_not
55
- "#{message} should not have changed, but did change from #{@before.inspect} to #{@after.inspect}"
58
+ "#{message} should not have changed, but did change from #{@actual_before.inspect} to #{@actual_after.inspect}"
56
59
  end
57
60
 
58
- def by(amount)
59
- @amount = amount
61
+ def by(expected_delta)
62
+ @expected_delta = expected_delta
60
63
  self
61
64
  end
62
65
 
@@ -71,14 +74,14 @@ MESSAGE
71
74
  end
72
75
 
73
76
  def to(to)
74
- @given_to = true
75
- @to = to
77
+ @eval_after = true
78
+ @expected_after = to
76
79
  self
77
80
  end
78
81
 
79
- def from (from)
80
- @given_from = true
81
- @from = from
82
+ def from (before)
83
+ @eval_before = true
84
+ @expected_before = before
82
85
  self
83
86
  end
84
87
 
@@ -93,33 +96,36 @@ MESSAGE
93
96
  end
94
97
 
95
98
  def change_expected?
96
- @amount != 0
99
+ @expected_delta != 0
97
100
  end
98
101
 
99
102
  def changed?
100
- @before != @after
103
+ @actual_before != @actual_after
101
104
  end
102
105
 
103
106
  def matches_before?
104
- @given_from ? @from == @before : true
107
+ @eval_before ? expected_matches_actual?(@expected_before, @actual_before) : true
105
108
  end
106
109
 
107
110
  def matches_after?
108
- @given_to ? @to == @after : true
111
+ @eval_after ? expected_matches_actual?(@expected_after, @actual_after) : true
109
112
  end
110
113
 
111
- def matches_amount?
112
- @amount ? (@before + @amount == @after) : true
114
+ def matches_expected_delta?
115
+ @expected_delta ? (@actual_before + @expected_delta == @actual_after) : true
113
116
  end
114
117
 
115
118
  def matches_min?
116
- @minimum ? (@after - @before >= @minimum) : true
119
+ @minimum ? (@actual_after - @actual_before >= @minimum) : true
117
120
  end
118
121
 
119
122
  def matches_max?
120
- @maximum ? (@after - @before <= @maximum) : true
123
+ @maximum ? (@actual_after - @actual_before <= @maximum) : true
121
124
  end
122
125
 
126
+ def expected_matches_actual?(expected, actual)
127
+ expected === actual
128
+ end
123
129
  end
124
130
 
125
131
  # :call-seq:
@@ -174,6 +180,15 @@ MESSAGE
174
180
  # employee.develop_great_new_social_networking_app
175
181
  # }.should change(employee, :title).from("Mail Clerk").to("CEO")
176
182
  #
183
+ # lambda {
184
+ # doctor.leave_office
185
+ # }.should change(doctor, :sign).from(/is in/).to(/is out/)
186
+ #
187
+ # user = User.new(:type => "admin")
188
+ # lambda {
189
+ # user.symbolize_type
190
+ # }.should change(user, :type).from(String).to(Symbol)
191
+ #
177
192
  # == Notes
178
193
  #
179
194
  # Evaluates <tt>receiver.message</tt> or <tt>block</tt> before and after it