rspec-expectations 2.6.0 → 2.7.0.rc1

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