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.
- data/README.md +2 -2
- data/features/built_in_matchers/README.md +7 -5
- data/features/built_in_matchers/be.feature +1 -1
- data/features/built_in_matchers/cover.feature +1 -1
- data/features/built_in_matchers/expect_error.feature +59 -26
- data/features/built_in_matchers/have.feature +2 -2
- data/features/built_in_matchers/predicates.feature +1 -1
- data/features/step_definitions/additional_cli_steps.rb +1 -1
- data/features/support/env.rb +1 -1
- data/lib/rspec/expectations.rb +0 -2
- data/lib/rspec/expectations/deprecation.rb +6 -4
- data/lib/rspec/expectations/errors.rb +4 -7
- data/lib/rspec/expectations/extensions.rb +1 -0
- data/lib/rspec/expectations/extensions/array.rb +2 -0
- data/lib/rspec/expectations/extensions/kernel.rb +18 -44
- data/lib/rspec/expectations/{backward_compatibility.rb → extensions/object.rb} +5 -3
- data/lib/rspec/expectations/fail_with.rb +8 -5
- data/lib/rspec/expectations/version.rb +5 -4
- data/lib/rspec/matchers.rb +77 -73
- data/lib/rspec/matchers/be.rb +42 -51
- data/lib/rspec/matchers/be_within.rb +1 -1
- data/lib/rspec/matchers/change.rb +5 -13
- data/lib/rspec/matchers/dsl.rb +2 -1
- data/lib/rspec/matchers/eq.rb +3 -3
- data/lib/rspec/matchers/extensions/{instance_exec.rb → instance_eval_with_args.rb} +15 -7
- data/lib/rspec/matchers/has.rb +11 -6
- data/lib/rspec/matchers/have.rb +36 -19
- data/lib/rspec/matchers/match_array.rb +1 -1
- data/lib/rspec/matchers/matcher.rb +5 -5
- data/spec/rspec/matchers/change_spec.rb +38 -0
- data/spec/rspec/matchers/description_generation_spec.rb +32 -32
- data/spec/rspec/matchers/eq_spec.rb +2 -2
- data/spec/rspec/matchers/has_spec.rb +33 -1
- data/spec/rspec/matchers/have_spec.rb +64 -7
- data/spec/rspec/matchers/match_array_spec.rb +0 -3
- data/spec/rspec/matchers/operator_matcher_spec.rb +10 -4
- data/spec/rspec/matchers/raise_error_spec.rb +6 -6
- data/spec/support/classes.rb +21 -10
- metadata +51 -62
- data/.document +0 -5
- data/.gitignore +0 -10
- data/.travis.yml +0 -7
- data/Gemfile +0 -40
- data/Guardfile +0 -5
- data/License.txt +0 -22
- data/Rakefile +0 -81
- data/cucumber.yml +0 -10
- data/features/.nav +0 -29
- data/features/Changelog.md +0 -101
- data/rspec-expectations.gemspec +0 -27
- data/specs.watchr +0 -57
data/lib/rspec/matchers/has.rb
CHANGED
@@ -10,15 +10,15 @@ module RSpec
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def failure_message_for_should
|
13
|
-
"expected ##{predicate(@expected)}
|
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)}
|
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
|
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
|
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
|
data/lib/rspec/matchers/have.rb
CHANGED
@@ -2,7 +2,11 @@ module RSpec
|
|
2
2
|
module Matchers
|
3
3
|
class Have #:nodoc:
|
4
4
|
def initialize(expected, relativity=:exactly)
|
5
|
-
@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?(
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
-
|
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 #
|
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?(
|
71
|
-
@expected.respond_to?(
|
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)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
3
|
class Matcher
|
4
|
-
include RSpec::Matchers::
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
9
|
-
"this".should
|
10
|
-
RSpec::Matchers.generated_description.should
|
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
|
14
|
-
"this".should_not
|
15
|
-
RSpec::Matchers.generated_description.should
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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 == "
|
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(
|
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
|