rspec-expectations 2.7.0 → 2.8.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.
- 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)
|