rspec-expectations 2.6.0 → 2.7.0.rc1

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 (51) hide show
  1. data/README.md +2 -2
  2. data/features/built_in_matchers/README.md +7 -5
  3. data/features/built_in_matchers/be.feature +1 -1
  4. data/features/built_in_matchers/cover.feature +1 -1
  5. data/features/built_in_matchers/expect_error.feature +59 -26
  6. data/features/built_in_matchers/have.feature +2 -2
  7. data/features/built_in_matchers/predicates.feature +1 -1
  8. data/features/step_definitions/additional_cli_steps.rb +1 -1
  9. data/features/support/env.rb +1 -1
  10. data/lib/rspec/expectations.rb +0 -2
  11. data/lib/rspec/expectations/deprecation.rb +6 -4
  12. data/lib/rspec/expectations/errors.rb +4 -7
  13. data/lib/rspec/expectations/extensions.rb +1 -0
  14. data/lib/rspec/expectations/extensions/array.rb +2 -0
  15. data/lib/rspec/expectations/extensions/kernel.rb +18 -44
  16. data/lib/rspec/expectations/{backward_compatibility.rb → extensions/object.rb} +5 -3
  17. data/lib/rspec/expectations/fail_with.rb +8 -5
  18. data/lib/rspec/expectations/version.rb +5 -4
  19. data/lib/rspec/matchers.rb +77 -73
  20. data/lib/rspec/matchers/be.rb +42 -51
  21. data/lib/rspec/matchers/be_within.rb +1 -1
  22. data/lib/rspec/matchers/change.rb +5 -13
  23. data/lib/rspec/matchers/dsl.rb +2 -1
  24. data/lib/rspec/matchers/eq.rb +3 -3
  25. data/lib/rspec/matchers/extensions/{instance_exec.rb → instance_eval_with_args.rb} +15 -7
  26. data/lib/rspec/matchers/has.rb +11 -6
  27. data/lib/rspec/matchers/have.rb +36 -19
  28. data/lib/rspec/matchers/match_array.rb +1 -1
  29. data/lib/rspec/matchers/matcher.rb +5 -5
  30. data/spec/rspec/matchers/change_spec.rb +38 -0
  31. data/spec/rspec/matchers/description_generation_spec.rb +32 -32
  32. data/spec/rspec/matchers/eq_spec.rb +2 -2
  33. data/spec/rspec/matchers/has_spec.rb +33 -1
  34. data/spec/rspec/matchers/have_spec.rb +64 -7
  35. data/spec/rspec/matchers/match_array_spec.rb +0 -3
  36. data/spec/rspec/matchers/operator_matcher_spec.rb +10 -4
  37. data/spec/rspec/matchers/raise_error_spec.rb +6 -6
  38. data/spec/support/classes.rb +21 -10
  39. metadata +51 -62
  40. data/.document +0 -5
  41. data/.gitignore +0 -10
  42. data/.travis.yml +0 -7
  43. data/Gemfile +0 -40
  44. data/Guardfile +0 -5
  45. data/License.txt +0 -22
  46. data/Rakefile +0 -81
  47. data/cucumber.yml +0 -10
  48. data/features/.nav +0 -29
  49. data/features/Changelog.md +0 -101
  50. data/rspec-expectations.gemspec +0 -27
  51. data/specs.watchr +0 -57
@@ -10,15 +10,15 @@ module RSpec
10
10
  end
11
11
 
12
12
  def failure_message_for_should
13
- "expected ##{predicate(@expected)}(#{@args[0].inspect}) to return true, got false"
13
+ "expected ##{predicate(@expected)}#{failure_message_args_description} to return true, got false"
14
14
  end
15
15
 
16
16
  def failure_message_for_should_not
17
- "expected ##{predicate(@expected)}(#{@args[0].inspect}) to return false, got true"
17
+ "expected ##{predicate(@expected)}#{failure_message_args_description} to return false, got true"
18
18
  end
19
19
 
20
20
  def description
21
- [method_description(@expected), args_description(@args)].compact.join(' ')
21
+ [method_description(@expected), args_description].compact.join(' ')
22
22
  end
23
23
 
24
24
  private
@@ -30,9 +30,14 @@ module RSpec
30
30
  method.to_s.gsub('_', ' ')
31
31
  end
32
32
 
33
- def args_description(args)
34
- return nil if args.empty?
35
- args.map { |arg| arg.inspect }.join(', ')
33
+ def args_description
34
+ return nil if @args.empty?
35
+ @args.map { |arg| arg.inspect }.join(', ')
36
+ end
37
+
38
+ def failure_message_args_description
39
+ desc = args_description
40
+ "(#{desc})" if desc
36
41
  end
37
42
  end
38
43
  end
@@ -2,7 +2,11 @@ module RSpec
2
2
  module Matchers
3
3
  class Have #:nodoc:
4
4
  def initialize(expected, relativity=:exactly)
5
- @expected = (expected == :no ? 0 : expected)
5
+ @expected = case expected
6
+ when :no then 0
7
+ when String then expected.to_i
8
+ else expected
9
+ end
6
10
  @relativity = relativity
7
11
  @actual = @collection_name = @plural_collection_name = nil
8
12
  end
@@ -15,26 +19,36 @@ module RSpec
15
19
  }
16
20
  end
17
21
 
18
- def matches?(collection_owner)
19
- if collection_owner.respond_to?(@collection_name)
20
- collection = collection_owner.__send__(@collection_name, *@args, &@block)
21
- elsif (@plural_collection_name && collection_owner.respond_to?(@plural_collection_name))
22
- collection = collection_owner.__send__(@plural_collection_name, *@args, &@block)
23
- elsif (collection_owner.respond_to?(:length) || collection_owner.respond_to?(:size))
24
- collection = collection_owner
22
+ def matches?(collection_or_owner)
23
+ collection = determine_collection(collection_or_owner)
24
+ query_method = determine_query_method(collection)
25
+ raise not_a_collection unless query_method
26
+ @actual = collection.send(query_method)
27
+ case @relativity
28
+ when :at_least then @actual >= @expected
29
+ when :at_most then @actual <= @expected
30
+ else @actual == @expected
31
+ end
32
+ end
33
+
34
+ def determine_collection(collection_or_owner)
35
+ if collection_or_owner.respond_to?(@collection_name)
36
+ collection_or_owner.send(@collection_name, *@args, &@block)
37
+ elsif (@plural_collection_name && collection_or_owner.respond_to?(@plural_collection_name))
38
+ collection_or_owner.send(@plural_collection_name, *@args, &@block)
39
+ elsif determine_query_method(collection_or_owner)
40
+ collection_or_owner
25
41
  else
26
- collection_owner.__send__(@collection_name, *@args, &@block)
42
+ collection_or_owner.send(@collection_name, *@args, &@block)
27
43
  end
28
- @actual = collection.size if collection.respond_to?(:size)
29
- @actual = collection.length if collection.respond_to?(:length)
30
- raise not_a_collection if @actual.nil?
31
- return @actual >= @expected if @relativity == :at_least
32
- return @actual <= @expected if @relativity == :at_most
33
- return @actual == @expected
34
44
  end
35
-
45
+
46
+ def determine_query_method(collection)
47
+ [:size, :length, :count].detect {|m| collection.respond_to?(m)}
48
+ end
49
+
36
50
  def not_a_collection
37
- "expected #{@collection_name} to be a collection but it does not respond to #length or #size"
51
+ "expected #{@collection_name} to be a collection but it does not respond to #length, #size or #count"
38
52
  end
39
53
 
40
54
  def failure_message_for_should
@@ -67,8 +81,8 @@ EOF
67
81
  "have #{relative_expectation} #{@collection_name}"
68
82
  end
69
83
 
70
- def respond_to?(sym)
71
- @expected.respond_to?(sym) || super
84
+ def respond_to?(m)
85
+ @expected.respond_to?(m) || super
72
86
  end
73
87
 
74
88
  private
@@ -117,6 +131,9 @@ EOF
117
131
  # # Passes if [1,2,3].length == 3
118
132
  # [1,2,3].should have(3).items #"items" is pure sugar
119
133
  #
134
+ # # Passes if ['a', 'b', 'c'].count == 3
135
+ # [1,2,3].should have(3).items #"items" is pure sugar
136
+ #
120
137
  # # Passes if "this string".length == 11
121
138
  # "this string".should have(11).characters #"characters" is pure sugar
122
139
  def have(n)
@@ -34,7 +34,7 @@ module RSpec
34
34
  private
35
35
 
36
36
  def safe_sort(array)
37
- array.all?{|item| item.respond_to?(:<=>)} ? array.sort : array
37
+ array.sort rescue array
38
38
  end
39
39
 
40
40
  def difference_between_arrays(array_1, array_2)
@@ -1,7 +1,7 @@
1
1
  module RSpec
2
2
  module Matchers
3
3
  class Matcher
4
- include RSpec::Matchers::InstanceExec
4
+ include RSpec::Matchers::Extensions::InstanceEvalWithArgs
5
5
  include RSpec::Matchers::Pretty
6
6
  include RSpec::Matchers
7
7
 
@@ -20,7 +20,7 @@ module RSpec
20
20
  :failure_message_for_should_not => lambda {|actual| "expected #{actual.inspect} not to #{name_to_sentence}#{expected_to_sentence}"}
21
21
  }
22
22
  making_declared_methods_public do
23
- instance_exec(*@expected, &declarations)
23
+ instance_eval_with_args(*@expected, &declarations)
24
24
  end
25
25
  end
26
26
 
@@ -29,14 +29,14 @@ module RSpec
29
29
  @actual = actual
30
30
  if @expected_exception
31
31
  begin
32
- instance_exec(actual, &@match_block)
32
+ instance_eval_with_args(actual, &@match_block)
33
33
  true
34
34
  rescue @expected_exception => @rescued_exception
35
35
  false
36
36
  end
37
37
  else
38
38
  begin
39
- instance_exec(actual, &@match_block)
39
+ instance_eval_with_args(actual, &@match_block)
40
40
  rescue RSpec::Expectations::ExpectationNotMetError
41
41
  false
42
42
  end
@@ -47,7 +47,7 @@ module RSpec
47
47
  def does_not_match?(actual)
48
48
  @actual = actual
49
49
  @match_for_should_not_block ?
50
- instance_exec(actual, &@match_for_should_not_block) :
50
+ instance_eval_with_args(actual, &@match_for_should_not_block) :
51
51
  !matches?(actual)
52
52
  end
53
53
 
@@ -95,6 +95,44 @@ describe "should change(actual, message)" do
95
95
  end.to fail
96
96
  end
97
97
  end
98
+
99
+ context "with an arbitrary enumerable" do
100
+ before(:each) do
101
+ @instance = SomethingExpected.new
102
+ @instance.some_value = Class.new do
103
+ include Enumerable
104
+
105
+ attr_reader :elements
106
+
107
+ def initialize(*elements)
108
+ @elements = elements.dup
109
+ end
110
+
111
+ def <<(element)
112
+ elements << element
113
+ end
114
+
115
+ def dup
116
+ self.class.new *elements
117
+ end
118
+
119
+ def ==(other)
120
+ elements == other.elements
121
+ end
122
+ end.new
123
+ end
124
+
125
+ it "passes when actual is modified by the block" do
126
+ expect {@instance.some_value << 1}.to change(@instance, :some_value)
127
+ end
128
+
129
+ it "fails when actual is not modified by the block" do
130
+ expect do
131
+ expect {}.to change(@instance, :some_value)
132
+ end.to fail_with(/^some_value should have changed, but is still/)
133
+ end
134
+
135
+ end
98
136
  end
99
137
 
100
138
  describe "should_not change(actual, message)" do
@@ -5,75 +5,75 @@ describe "Matchers should be able to generate their own descriptions" do
5
5
  RSpec::Matchers.clear_generated_description
6
6
  end
7
7
 
8
- it "should == expected" do
9
- "this".should == "this"
10
- RSpec::Matchers.generated_description.should == "should == \"this\""
8
+ it "should eq expected" do
9
+ "this".should eq "this"
10
+ RSpec::Matchers.generated_description.should eq "should eq this"
11
11
  end
12
12
 
13
- it "should not == expected" do
14
- "this".should_not == "that"
15
- RSpec::Matchers.generated_description.should == "should not == \"that\""
13
+ it "should not eq expected" do
14
+ "this".should_not eq "that"
15
+ RSpec::Matchers.generated_description.should eq "should not eq that"
16
16
  end
17
17
 
18
18
  it "should be empty (arbitrary predicate)" do
19
19
  [].should be_empty
20
- RSpec::Matchers.generated_description.should == "should be empty"
20
+ RSpec::Matchers.generated_description.should eq "should be empty"
21
21
  end
22
22
 
23
23
  it "should not be empty (arbitrary predicate)" do
24
24
  [1].should_not be_empty
25
- RSpec::Matchers.generated_description.should == "should not be empty"
25
+ RSpec::Matchers.generated_description.should eq "should not be empty"
26
26
  end
27
27
 
28
28
  it "should be true" do
29
29
  true.should be_true
30
- RSpec::Matchers.generated_description.should == "should be true"
30
+ RSpec::Matchers.generated_description.should eq "should be true"
31
31
  end
32
32
 
33
33
  it "should be false" do
34
34
  false.should be_false
35
- RSpec::Matchers.generated_description.should == "should be false"
35
+ RSpec::Matchers.generated_description.should eq "should be false"
36
36
  end
37
37
 
38
38
  it "should be nil" do
39
39
  nil.should be_nil
40
- RSpec::Matchers.generated_description.should == "should be nil"
40
+ RSpec::Matchers.generated_description.should eq "should be nil"
41
41
  end
42
42
 
43
43
  it "should be > n" do
44
44
  5.should be > 3
45
- RSpec::Matchers.generated_description.should == "should be > 3"
45
+ RSpec::Matchers.generated_description.should eq "should be > 3"
46
46
  end
47
47
 
48
48
  it "should be predicate arg1, arg2 and arg3" do
49
49
  5.0.should be_between(0,10)
50
- RSpec::Matchers.generated_description.should == "should be between 0 and 10"
50
+ RSpec::Matchers.generated_description.should eq "should be between 0 and 10"
51
51
  end
52
52
 
53
53
  it "should equal" do
54
54
  expected = "expected"
55
55
  expected.should equal(expected)
56
- RSpec::Matchers.generated_description.should == "should equal \"expected\""
56
+ RSpec::Matchers.generated_description.should eq "should equal \"expected\""
57
57
  end
58
58
 
59
59
  it "should_not equal" do
60
60
  5.should_not equal(37)
61
- RSpec::Matchers.generated_description.should == "should not equal 37"
61
+ RSpec::Matchers.generated_description.should eq "should not equal 37"
62
62
  end
63
63
 
64
64
  it "should eql" do
65
65
  "string".should eql("string")
66
- RSpec::Matchers.generated_description.should == "should eql \"string\""
66
+ RSpec::Matchers.generated_description.should eq "should eql \"string\""
67
67
  end
68
68
 
69
69
  it "should not eql" do
70
70
  "a".should_not eql(:a)
71
- RSpec::Matchers.generated_description.should == "should not eql :a"
71
+ RSpec::Matchers.generated_description.should eq "should not eql :a"
72
72
  end
73
73
 
74
74
  it "should have_key" do
75
75
  {:a => "a"}.should have_key(:a)
76
- RSpec::Matchers.generated_description.should == "should have key :a"
76
+ RSpec::Matchers.generated_description.should eq "should have key :a"
77
77
  end
78
78
 
79
79
  it "should have_some_method" do
@@ -81,7 +81,7 @@ describe "Matchers should be able to generate their own descriptions" do
81
81
  def object.has_eyes_closed?; true; end
82
82
 
83
83
  object.should have_eyes_closed
84
- RSpec::Matchers.generated_description.should == 'should have eyes closed'
84
+ RSpec::Matchers.generated_description.should eq 'should have eyes closed'
85
85
  end
86
86
 
87
87
  it "should have_some_method(args*)" do
@@ -89,67 +89,67 @@ describe "Matchers should be able to generate their own descriptions" do
89
89
  def object.has_taste_for?(*args); true; end
90
90
 
91
91
  object.should have_taste_for("wine", "cheese")
92
- RSpec::Matchers.generated_description.should == 'should have taste for "wine", "cheese"'
92
+ RSpec::Matchers.generated_description.should eq 'should have taste for "wine", "cheese"'
93
93
  end
94
94
 
95
95
  it "should have n items" do
96
96
  team.should have(3).players
97
- RSpec::Matchers.generated_description.should == "should have 3 players"
97
+ RSpec::Matchers.generated_description.should eq "should have 3 players"
98
98
  end
99
99
 
100
100
  it "should have at least n items" do
101
101
  team.should have_at_least(2).players
102
- RSpec::Matchers.generated_description.should == "should have at least 2 players"
102
+ RSpec::Matchers.generated_description.should eq "should have at least 2 players"
103
103
  end
104
104
 
105
105
  it "should have at most n items" do
106
106
  team.should have_at_most(4).players
107
- RSpec::Matchers.generated_description.should == "should have at most 4 players"
107
+ RSpec::Matchers.generated_description.should eq "should have at most 4 players"
108
108
  end
109
109
 
110
110
  it "should include" do
111
111
  [1,2,3].should include(3)
112
- RSpec::Matchers.generated_description.should == "should include 3"
112
+ RSpec::Matchers.generated_description.should eq "should include 3"
113
113
  end
114
114
 
115
115
  it "array.should =~ [1,2,3]" do
116
116
  [1,2,3].should =~ [1,2,3]
117
- RSpec::Matchers.generated_description.should == "should contain exactly 1, 2 and 3"
117
+ RSpec::Matchers.generated_description.should eq "should contain exactly 1, 2 and 3"
118
118
  end
119
119
 
120
120
  it "should match" do
121
121
  "this string".should match(/this string/)
122
- RSpec::Matchers.generated_description.should == "should match /this string/"
122
+ RSpec::Matchers.generated_description.should eq "should match /this string/"
123
123
  end
124
124
 
125
125
  it "should raise_error" do
126
126
  lambda { raise }.should raise_error
127
- RSpec::Matchers.generated_description.should == "should raise Exception"
127
+ RSpec::Matchers.generated_description.should eq "should raise Exception"
128
128
  end
129
129
 
130
130
  it "should raise_error with type" do
131
131
  lambda { raise }.should raise_error(RuntimeError)
132
- RSpec::Matchers.generated_description.should == "should raise RuntimeError"
132
+ RSpec::Matchers.generated_description.should eq "should raise RuntimeError"
133
133
  end
134
134
 
135
135
  it "should raise_error with type and message" do
136
136
  lambda { raise "there was an error" }.should raise_error(RuntimeError, "there was an error")
137
- RSpec::Matchers.generated_description.should == "should raise RuntimeError with \"there was an error\""
137
+ RSpec::Matchers.generated_description.should eq "should raise RuntimeError with \"there was an error\""
138
138
  end
139
139
 
140
140
  it "should respond_to" do
141
141
  [].should respond_to(:insert)
142
- RSpec::Matchers.generated_description.should == "should respond to #insert"
142
+ RSpec::Matchers.generated_description.should eq "should respond to #insert"
143
143
  end
144
144
 
145
145
  it "should throw symbol" do
146
146
  lambda { throw :what_a_mess }.should throw_symbol
147
- RSpec::Matchers.generated_description.should == "should throw a Symbol"
147
+ RSpec::Matchers.generated_description.should eq "should throw a Symbol"
148
148
  end
149
149
 
150
150
  it "should throw symbol (with named symbol)" do
151
151
  lambda { throw :what_a_mess }.should throw_symbol(:what_a_mess)
152
- RSpec::Matchers.generated_description.should == "should throw :what_a_mess"
152
+ RSpec::Matchers.generated_description.should eq "should throw :what_a_mess"
153
153
  end
154
154
 
155
155
  def team
@@ -18,13 +18,13 @@ module RSpec
18
18
  it "describes itself" do
19
19
  matcher = eq(1)
20
20
  matcher.matches?(1)
21
- matcher.description.should == "== 1"
21
+ matcher.description.should == "eq 1"
22
22
  end
23
23
 
24
24
  it "provides message, expected and actual on #failure_message" do
25
25
  matcher = eq("1")
26
26
  matcher.matches?(1)
27
- matcher.failure_message_for_should.should == "\nexpected \"1\"\n got 1\n\n(compared using ==)\n"
27
+ matcher.failure_message_for_should.should == "\nexpected: \"1\"\n got: 1\n\n(compared using ==)\n"
28
28
  end
29
29
 
30
30
  it "provides message, expected and actual on #negative_failure_message" do
@@ -11,6 +11,22 @@ describe "should have_sym(*args)" do
11
11
  }.should fail_with("expected #has_key?(:a) to return true, got false")
12
12
  end
13
13
 
14
+ it 'does not include any args in the failure message if no args were given to the matcher' do
15
+ o = Object.new
16
+ def o.has_some_stuff?; false; end
17
+ expect {
18
+ o.should have_some_stuff
19
+ }.to fail_with("expected #has_some_stuff? to return true, got false")
20
+ end
21
+
22
+ it 'includes multiple args in the failure message if multiple args were given to the matcher' do
23
+ o = Object.new
24
+ def o.has_some_stuff?(*_); false; end
25
+ expect {
26
+ o.should have_some_stuff(:a, 7, "foo")
27
+ }.to fail_with('expected #has_some_stuff?(:a, 7, "foo") to return true, got false')
28
+ end
29
+
14
30
  it "fails if #has_sym?(*args) returns nil" do
15
31
  klass = Class.new do
16
32
  def has_foo?
@@ -18,7 +34,7 @@ describe "should have_sym(*args)" do
18
34
  end
19
35
  lambda {
20
36
  klass.new.should have_foo
21
- }.should fail_with("expected #has_foo?(nil) to return true, got false")
37
+ }.should fail_with(/expected #has_foo.* to return true, got false/)
22
38
  end
23
39
 
24
40
  it "fails if target does not respond to #has_sym?" do
@@ -68,6 +84,22 @@ describe "should_not have_sym(*args)" do
68
84
  end
69
85
  lambda { o.should_not have_sym(:foo) }.should raise_error("Funky exception")
70
86
  end
87
+
88
+ it 'does not include any args in the failure message if no args were given to the matcher' do
89
+ o = Object.new
90
+ def o.has_some_stuff?; true; end
91
+ expect {
92
+ o.should_not have_some_stuff
93
+ }.to fail_with("expected #has_some_stuff? to return false, got true")
94
+ end
95
+
96
+ it 'includes multiple args in the failure message if multiple args were given to the matcher' do
97
+ o = Object.new
98
+ def o.has_some_stuff?(*_); true; end
99
+ expect {
100
+ o.should_not have_some_stuff(:a, 7, "foo")
101
+ }.to fail_with('expected #has_some_stuff?(:a, 7, "foo") to return false, got true')
102
+ end
71
103
  end
72
104
 
73
105
  describe "has" do