rspec-expectations 2.7.0 → 2.8.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +117 -9
- data/lib/rspec/expectations.rb +24 -16
- data/lib/rspec/expectations/handler.rb +1 -1
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/matchers.rb +91 -91
- data/lib/rspec/matchers/base_matcher.rb +41 -0
- data/lib/rspec/matchers/be.rb +31 -12
- data/lib/rspec/matchers/be_instance_of.rb +10 -12
- data/lib/rspec/matchers/be_kind_of.rb +10 -12
- data/lib/rspec/matchers/be_within.rb +36 -26
- data/lib/rspec/matchers/block_aliases.rb +2 -1
- data/lib/rspec/matchers/change.rb +1 -1
- data/lib/rspec/matchers/cover.rb +20 -19
- data/lib/rspec/matchers/eq.rb +22 -32
- data/lib/rspec/matchers/eql.rb +22 -28
- data/lib/rspec/matchers/equal.rb +37 -27
- data/lib/rspec/matchers/exist.rb +26 -18
- data/lib/rspec/matchers/have.rb +22 -28
- data/lib/rspec/matchers/include.rb +45 -37
- data/lib/rspec/matchers/match.rb +10 -10
- data/lib/rspec/matchers/match_array.rb +1 -7
- data/lib/rspec/matchers/matcher.rb +0 -8
- data/lib/rspec/matchers/operator_matcher.rb +0 -2
- data/lib/rspec/matchers/pretty.rb +25 -2
- data/lib/rspec/matchers/raise_error.rb +2 -16
- data/lib/rspec/matchers/respond_to.rb +1 -6
- data/lib/rspec/matchers/satisfy.rb +1 -6
- data/lib/rspec/matchers/throw_symbol.rb +2 -11
- data/spec/rspec/expectations/handler_spec.rb +1 -1
- data/spec/rspec/matchers/change_spec.rb +1 -1
- data/spec/rspec/matchers/description_generation_spec.rb +2 -2
- data/spec/rspec/matchers/eq_spec.rb +1 -1
- data/spec/rspec/matchers/eql_spec.rb +2 -2
- data/spec/rspec/matchers/equal_spec.rb +1 -1
- data/spec/rspec/matchers/include_spec.rb +4 -0
- data/spec/rspec/matchers/raise_error_spec.rb +2 -2
- data/spec/spec_helper.rb +1 -0
- metadata +15 -10
data/lib/rspec/matchers/equal.rb
CHANGED
@@ -1,27 +1,16 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
actual.equal?(_expected_)
|
15
|
-
end
|
16
|
-
|
17
|
-
def inspect_object(o)
|
18
|
-
"#<#{o.class}:#{o.object_id}> => #{o.inspect}"
|
19
|
-
end
|
20
|
-
|
21
|
-
failure_message_for_should do |actual|
|
22
|
-
<<-MESSAGE
|
23
|
-
|
24
|
-
expected #{inspect_object(_expected_)}
|
3
|
+
class Equal
|
4
|
+
include BaseMatcher
|
5
|
+
|
6
|
+
def matches?(actual)
|
7
|
+
super(actual).equal?(expected)
|
8
|
+
end
|
9
|
+
|
10
|
+
def failure_message_for_should
|
11
|
+
return <<-MESSAGE
|
12
|
+
|
13
|
+
expected #{inspect_object(expected)}
|
25
14
|
got #{inspect_object(actual)}
|
26
15
|
|
27
16
|
Compared using equal?, which compares object identity,
|
@@ -30,19 +19,40 @@ but expected and actual are not the same object. Use
|
|
30
19
|
object identity in this example.
|
31
20
|
|
32
21
|
MESSAGE
|
33
|
-
|
22
|
+
end
|
34
23
|
|
35
|
-
|
36
|
-
|
24
|
+
def failure_message_for_should_not
|
25
|
+
return <<-MESSAGE
|
37
26
|
|
38
27
|
expected not #{inspect_object(actual)}
|
39
|
-
got #{inspect_object(
|
28
|
+
got #{inspect_object(expected)}
|
40
29
|
|
41
30
|
Compared using equal?, which compares object identity.
|
42
31
|
|
43
32
|
MESSAGE
|
44
|
-
end
|
45
33
|
end
|
34
|
+
|
35
|
+
def diffable?
|
36
|
+
true
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def inspect_object(o)
|
42
|
+
"#<#{o.class}:#{o.object_id}> => #{o.inspect}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Passes if <tt>actual.equal?(expected)</tt> (object identity).
|
47
|
+
#
|
48
|
+
# See http://www.ruby-doc.org/core/classes/Object.html#M001057 for more information about equality in Ruby.
|
49
|
+
#
|
50
|
+
# @example
|
51
|
+
#
|
52
|
+
# 5.should equal(5) # Fixnums are equal
|
53
|
+
# "5".should_not equal("5") # Strings that look the same are not the same object
|
54
|
+
def equal(expected)
|
55
|
+
Equal.new(expected)
|
46
56
|
end
|
47
57
|
end
|
48
58
|
end
|
data/lib/rspec/matchers/exist.rb
CHANGED
@@ -1,26 +1,34 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
3
|
+
class Exist
|
4
|
+
include BaseMatcher
|
5
|
+
|
6
|
+
def initialize(*args)
|
7
|
+
super(args)
|
8
|
+
end
|
9
|
+
|
10
|
+
def matches?(actual)
|
11
|
+
super(actual)
|
12
|
+
predicates = [:exist?, :exists?].select { |p| actual.respond_to?(p) }
|
13
|
+
existance_values = predicates.map { |p| actual.send(p, *expected) }
|
14
|
+
uniq_truthy_values = existance_values.map { |v| !!v }.uniq
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
16
|
+
case uniq_truthy_values.size
|
17
|
+
when 0; raise NoMethodError.new("#{actual.inspect} does not respond to either #exist? or #exists?")
|
18
|
+
when 1; existance_values.first
|
19
|
+
else raise "#exist? and #exists? returned different values:\n\n" +
|
20
|
+
" exist?: #{existance_values.first}\n" +
|
21
|
+
"exists?: #{existance_values.last}"
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
25
|
+
|
26
|
+
# Passes if `actual.exist?` or `actual.exists?`
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# File.should exist("path/to/file")
|
30
|
+
def exist(*args)
|
31
|
+
Exist.new(*args)
|
32
|
+
end
|
25
33
|
end
|
26
34
|
end
|
data/lib/rspec/matchers/have.rb
CHANGED
@@ -102,28 +102,22 @@ EOF
|
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
|
-
#
|
106
|
-
#
|
107
|
-
# should_not have(number).named_collection__or__sugar
|
105
|
+
# Passes if receiver is a collection with the submitted number of items OR
|
106
|
+
# if the receiver OWNS a collection with the submitted number of items.
|
108
107
|
#
|
109
|
-
#
|
110
|
-
#
|
111
|
-
#
|
108
|
+
# If the receiver OWNS the collection, you must use the name of the
|
109
|
+
# collection. So if a `Team` instance has a collection named `#players`,
|
110
|
+
# you must use that name to set the expectation.
|
112
111
|
#
|
113
|
-
# If the receiver
|
114
|
-
#
|
115
|
-
#
|
116
|
-
#
|
112
|
+
# If the receiver IS the collection, you can use any name you like for
|
113
|
+
# `named_collection`. We'd recommend using either "elements", "members", or
|
114
|
+
# "items" as these are all standard ways of describing the things IN a
|
115
|
+
# collection.
|
117
116
|
#
|
118
|
-
#
|
119
|
-
#
|
120
|
-
# either "elements", "members", or "items" as these are all
|
121
|
-
# standard ways of describing the things IN a collection.
|
117
|
+
# This also works for Strings, letting you set expectations about their
|
118
|
+
# lengths.
|
122
119
|
#
|
123
|
-
#
|
124
|
-
# about its length
|
125
|
-
#
|
126
|
-
# == Examples
|
120
|
+
# @example
|
127
121
|
#
|
128
122
|
# # Passes if team.players.size == 11
|
129
123
|
# team.should have(11).players
|
@@ -141,26 +135,26 @@ EOF
|
|
141
135
|
end
|
142
136
|
alias :have_exactly :have
|
143
137
|
|
144
|
-
# :call-seq:
|
145
|
-
# should have_at_least(number).items
|
146
|
-
#
|
147
138
|
# Exactly like have() with >=.
|
148
139
|
#
|
149
|
-
#
|
140
|
+
# @example
|
141
|
+
# "this".should have_at_least(3).letters
|
150
142
|
#
|
151
|
-
#
|
143
|
+
# ### Warning:
|
144
|
+
#
|
145
|
+
# `should_not have_at_least` is not supported
|
152
146
|
def have_at_least(n)
|
153
147
|
Matchers::Have.new(n, :at_least)
|
154
148
|
end
|
155
149
|
|
156
|
-
# :call-seq:
|
157
|
-
# should have_at_most(number).items
|
158
|
-
#
|
159
150
|
# Exactly like have() with <=.
|
160
151
|
#
|
161
|
-
#
|
152
|
+
# @example
|
153
|
+
# should have_at_most(number).items
|
154
|
+
#
|
155
|
+
# ### Warning:
|
162
156
|
#
|
163
|
-
#
|
157
|
+
# `should_not have_at_most` is not supported
|
164
158
|
def have_at_most(n)
|
165
159
|
Matchers::Have.new(n, :at_most)
|
166
160
|
end
|
@@ -1,14 +1,53 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
class Include
|
4
|
+
include BaseMatcher
|
5
|
+
|
6
|
+
def initialize(*expected)
|
7
|
+
super(expected)
|
8
|
+
end
|
9
|
+
|
10
|
+
def matches?(actual)
|
11
|
+
perform_match(:all?, :all?, super(actual), expected)
|
12
|
+
end
|
13
|
+
|
14
|
+
def does_not_match?(actual)
|
15
|
+
@actual = actual
|
16
|
+
perform_match(:none?, :any?, actual, expected)
|
17
|
+
end
|
18
|
+
|
19
|
+
def description
|
20
|
+
"include#{expected_to_sentence}"
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def perform_match(predicate, hash_predicate, actuals, expecteds)
|
26
|
+
expecteds.send(predicate) do |expected|
|
27
|
+
if comparing_hash_values?(actuals, expected)
|
28
|
+
expected.send(hash_predicate) {|k,v| actuals[k] == v}
|
29
|
+
elsif comparing_hash_keys?(actuals, expected)
|
30
|
+
actuals.has_key?(expected)
|
31
|
+
else
|
32
|
+
actuals.include?(expected)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def comparing_hash_keys?(actual, expected)
|
38
|
+
actual.is_a?(Hash) && !expected.is_a?(Hash)
|
39
|
+
end
|
40
|
+
|
41
|
+
def comparing_hash_values?(actual, expected)
|
42
|
+
actual.is_a?(Hash) && expected.is_a?(Hash)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
7
46
|
# Passes if actual includes expected. This works for
|
8
47
|
# collections and Strings. You can also pass in multiple args
|
9
48
|
# and it will only pass if all args are found in collection.
|
10
49
|
#
|
11
|
-
#
|
50
|
+
# @example
|
12
51
|
#
|
13
52
|
# [1,2,3].should include(3)
|
14
53
|
# [1,2,3].should include(2,3) #would pass
|
@@ -17,38 +56,7 @@ module RSpec
|
|
17
56
|
# "spread".should include("read")
|
18
57
|
# "spread".should_not include("red")
|
19
58
|
def include(*expected)
|
20
|
-
|
21
|
-
|
22
|
-
diffable
|
23
|
-
|
24
|
-
match_for_should do |actual|
|
25
|
-
perform_match(:all?, :all?, actual, _expected)
|
26
|
-
end
|
27
|
-
|
28
|
-
match_for_should_not do |actual|
|
29
|
-
perform_match(:none?, :any?, actual, _expected)
|
30
|
-
end
|
31
|
-
|
32
|
-
def perform_match(predicate, hash_predicate, actual, _expected)
|
33
|
-
_expected.send(predicate) do |expected|
|
34
|
-
if comparing_hash_values?(actual, expected)
|
35
|
-
expected.send(hash_predicate) {|k,v| actual[k] == v}
|
36
|
-
elsif comparing_hash_keys?(actual, expected)
|
37
|
-
actual.has_key?(expected)
|
38
|
-
else
|
39
|
-
actual.include?(expected)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def comparing_hash_keys?(actual, expected)
|
45
|
-
actual.is_a?(Hash) && !expected.is_a?(Hash)
|
46
|
-
end
|
47
|
-
|
48
|
-
def comparing_hash_values?(actual, expected)
|
49
|
-
actual.is_a?(Hash) && expected.is_a?(Hash)
|
50
|
-
end
|
51
|
-
end
|
59
|
+
Include.new(*expected)
|
52
60
|
end
|
53
61
|
end
|
54
62
|
end
|
data/lib/rspec/matchers/match.rb
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
class Match
|
4
|
+
include BaseMatcher
|
5
|
+
|
6
|
+
def matches?(actual)
|
7
|
+
super(actual).match(expected)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
7
11
|
# Given a Regexp or String, passes if actual.match(pattern)
|
8
12
|
#
|
9
|
-
#
|
13
|
+
# @example
|
10
14
|
#
|
11
15
|
# email.should match(/^([^\s]+)((?:[-a-z0-9]+\.)+[a-z]{2,})$/i)
|
12
16
|
# email.should match("@example.com")
|
13
17
|
def match(expected)
|
14
|
-
|
15
|
-
match do |actual|
|
16
|
-
actual.match(_expected_)
|
17
|
-
end
|
18
|
-
end
|
18
|
+
Match.new(expected)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module RSpec
|
2
2
|
module Matchers
|
3
|
-
|
4
3
|
class MatchArray
|
5
4
|
include RSpec::Matchers::Pretty
|
6
5
|
|
@@ -46,20 +45,15 @@ module RSpec
|
|
46
45
|
end
|
47
46
|
difference
|
48
47
|
end
|
49
|
-
|
50
|
-
|
51
48
|
end
|
52
49
|
|
53
|
-
# :call-seq:
|
54
|
-
# should =~ expected
|
55
|
-
#
|
56
50
|
# Passes if actual contains all of the expected regardless of order.
|
57
51
|
# This works for collections. Pass in multiple args and it will only
|
58
52
|
# pass if all args are found in collection.
|
59
53
|
#
|
60
54
|
# NOTE: there is no should_not version of array.should =~ other_array
|
61
55
|
#
|
62
|
-
#
|
56
|
+
# @example
|
63
57
|
#
|
64
58
|
# [1,2,3].should =~ [1,2,3] # => would pass
|
65
59
|
# [1,2,3].should =~ [2,3,1] # => would pass
|
@@ -147,14 +147,6 @@ module RSpec
|
|
147
147
|
@messages[key].arity == 1 ? @messages[key].call(@actual) : @messages[key].call
|
148
148
|
end
|
149
149
|
|
150
|
-
def name_to_sentence
|
151
|
-
split_words(@name)
|
152
|
-
end
|
153
|
-
|
154
|
-
def expected_to_sentence
|
155
|
-
to_sentence(@expected)
|
156
|
-
end
|
157
|
-
|
158
150
|
unless method_defined?(:singleton_class)
|
159
151
|
def singleton_class
|
160
152
|
class << self; self; end
|
@@ -6,7 +6,8 @@ module RSpec
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def to_sentence(words)
|
9
|
-
|
9
|
+
return "" unless words
|
10
|
+
words = Array(words).map{|w| w.inspect}
|
10
11
|
case words.length
|
11
12
|
when 0
|
12
13
|
""
|
@@ -32,6 +33,28 @@ module RSpec
|
|
32
33
|
end
|
33
34
|
result
|
34
35
|
end
|
36
|
+
|
37
|
+
def name_to_sentence
|
38
|
+
split_words(name)
|
39
|
+
end
|
40
|
+
|
41
|
+
def expected_to_sentence
|
42
|
+
to_sentence(@expected) if defined?(@expected)
|
43
|
+
end
|
44
|
+
|
45
|
+
def name
|
46
|
+
defined?(@name) ? @name : underscore(self.class.name.split("::").last)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Borrowed from ActiveSupport
|
50
|
+
def underscore(camel_cased_word)
|
51
|
+
word = camel_cased_word.to_s.dup
|
52
|
+
word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
|
53
|
+
word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
|
54
|
+
word.tr!("-", "_")
|
55
|
+
word.downcase!
|
56
|
+
word
|
57
|
+
end
|
35
58
|
end
|
36
59
|
end
|
37
|
-
end
|
60
|
+
end
|
@@ -25,7 +25,7 @@ module RSpec
|
|
25
25
|
rescue Exception => @actual_error
|
26
26
|
# This clause should be empty, but rcov will not report it as covered
|
27
27
|
# unless something (anything) is executed within the clause
|
28
|
-
|
28
|
+
"http://eigenclass.org/hiki.rb?rcov-0.8.0"
|
29
29
|
end
|
30
30
|
|
31
31
|
unless negative_expectation?
|
@@ -90,27 +90,13 @@ module RSpec
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
-
# :call-seq:
|
94
|
-
# should raise_error()
|
95
|
-
# should raise_error(NamedError)
|
96
|
-
# should raise_error(NamedError, String)
|
97
|
-
# should raise_error(NamedError, Regexp)
|
98
|
-
# should raise_error() { |error| ... }
|
99
|
-
# should raise_error(NamedError) { |error| ... }
|
100
|
-
# should raise_error(NamedError, String) { |error| ... }
|
101
|
-
# should raise_error(NamedError, Regexp) { |error| ... }
|
102
|
-
# should_not raise_error()
|
103
|
-
# should_not raise_error(NamedError)
|
104
|
-
# should_not raise_error(NamedError, String)
|
105
|
-
# should_not raise_error(NamedError, Regexp)
|
106
|
-
#
|
107
93
|
# With no args, matches if any error is raised.
|
108
94
|
# With a named error, matches only if that specific error is raised.
|
109
95
|
# With a named error and messsage specified as a String, matches only if both match.
|
110
96
|
# With a named error and messsage specified as a Regexp, matches only if both match.
|
111
97
|
# Pass an optional block to perform extra verifications on the exception matched
|
112
98
|
#
|
113
|
-
#
|
99
|
+
# @example
|
114
100
|
#
|
115
101
|
# lambda { do_something_risky }.should raise_error
|
116
102
|
# lambda { do_something_risky }.should raise_error(PoorRiskDecisionError)
|