rspec-expectations 2.0.0.beta.22 → 2.6.0
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/.gitignore +1 -1
- data/.travis.yml +7 -0
- data/Gemfile +35 -13
- data/Guardfile +5 -0
- data/License.txt +1 -1
- data/README.md +43 -0
- data/Rakefile +51 -9
- data/cucumber.yml +9 -2
- data/features/.nav +29 -0
- data/features/Changelog.md +101 -0
- data/features/README.markdown +45 -8
- data/features/built_in_matchers/README.md +71 -0
- data/features/built_in_matchers/be.feature +135 -0
- data/features/built_in_matchers/be_within.feature +43 -0
- data/features/built_in_matchers/cover.feature +45 -0
- data/features/{matchers → built_in_matchers}/equality.feature +16 -13
- data/features/built_in_matchers/exist.feature +43 -0
- data/features/built_in_matchers/expect_change.feature +59 -0
- data/features/built_in_matchers/expect_error.feature +105 -0
- data/features/built_in_matchers/have.feature +103 -0
- data/features/built_in_matchers/include.feature +121 -0
- data/features/built_in_matchers/match.feature +50 -0
- data/features/built_in_matchers/operators.feature +221 -0
- data/features/built_in_matchers/predicates.feature +128 -0
- data/features/built_in_matchers/respond_to.feature +78 -0
- data/features/built_in_matchers/satisfy.feature +31 -0
- data/features/built_in_matchers/throw_symbol.feature +85 -0
- data/features/built_in_matchers/types.feature +114 -0
- data/features/{matchers → custom_matchers}/access_running_example.feature +2 -2
- data/features/{matchers → custom_matchers}/define_diffable_matcher.feature +1 -1
- data/features/{matchers → custom_matchers}/define_matcher.feature +91 -9
- data/features/{matchers → custom_matchers}/define_matcher_outside_rspec.feature +1 -1
- data/features/{matchers → custom_matchers}/define_matcher_with_fluent_interface.feature +8 -11
- data/features/customized_message.feature +22 -0
- data/features/{expectations/diffing.feature → diffing.feature} +16 -16
- data/features/{expectations/implicit_docstrings.feature → implicit_docstrings.feature} +4 -4
- data/features/step_definitions/additional_cli_steps.rb +22 -0
- data/features/support/env.rb +5 -1
- data/features/test_frameworks/test_unit.feature +46 -0
- data/lib/rspec/expectations/backward_compatibility.rb +22 -1
- data/lib/rspec/expectations/deprecation.rb +36 -0
- data/lib/rspec/expectations/extensions.rb +0 -1
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/expectations.rb +2 -1
- data/lib/rspec/matchers/be.rb +4 -4
- data/lib/rspec/matchers/be_close.rb +2 -17
- data/lib/rspec/matchers/be_within.rb +40 -0
- data/lib/rspec/matchers/block_aliases.rb +19 -0
- data/lib/rspec/matchers/change.rb +74 -49
- data/lib/rspec/matchers/cover.rb +35 -0
- data/lib/rspec/matchers/exist.rb +13 -3
- data/lib/rspec/matchers/has.rb +15 -11
- data/lib/rspec/matchers/have.rb +5 -5
- data/lib/rspec/matchers/include.rb +14 -5
- data/lib/rspec/matchers/matcher.rb +39 -13
- data/lib/rspec/matchers/method_missing.rb +6 -3
- data/lib/rspec/matchers/operator_matcher.rb +12 -3
- data/lib/rspec/matchers/respond_to.rb +23 -9
- data/lib/rspec/matchers/satisfy.rb +4 -0
- data/lib/rspec/matchers/throw_symbol.rb +43 -26
- data/lib/rspec/matchers.rb +15 -3
- data/rspec-expectations.gemspec +2 -6
- data/spec/rspec/matchers/be_close_spec.rb +11 -39
- data/spec/rspec/matchers/be_spec.rb +8 -8
- data/spec/rspec/matchers/be_within_spec.rb +64 -0
- data/spec/rspec/matchers/change_spec.rb +88 -9
- data/spec/rspec/matchers/cover_spec.rb +65 -0
- data/spec/rspec/matchers/description_generation_spec.rb +41 -25
- data/spec/rspec/matchers/exist_spec.rb +90 -51
- data/spec/rspec/matchers/has_spec.rb +2 -2
- data/spec/rspec/matchers/have_spec.rb +291 -291
- data/spec/rspec/matchers/include_spec.rb +318 -65
- data/spec/rspec/matchers/matcher_spec.rb +91 -0
- data/spec/rspec/matchers/matchers_spec.rb +29 -0
- data/spec/rspec/matchers/method_missing_spec.rb +23 -0
- data/spec/rspec/matchers/operator_matcher_spec.rb +36 -10
- data/spec/rspec/matchers/respond_to_spec.rb +177 -1
- data/spec/rspec/matchers/satisfy_spec.rb +4 -0
- data/spec/rspec/matchers/throw_symbol_spec.rb +27 -10
- data/spec/spec_helper.rb +10 -35
- data/spec/support/classes.rb +1 -1
- data/spec/support/matchers.rb +22 -0
- data/spec/support/ruby_version.rb +10 -0
- metadata +95 -114
- data/History.md +0 -16
- data/README.markdown +0 -23
- data/features/expectations/attribute_of_subject.feature +0 -19
- data/features/expectations/customized_message.feature +0 -54
- data/features/matchers/expect_change.feature +0 -65
- data/features/matchers/expect_error.feature +0 -44
- data/lib/rspec/expectations/extensions/rspec/core/example_group.rb +0 -19
- data/spec/suite.rb +0 -1
- /data/{Upgrade.markdown → features/Upgrade.md} +0 -0
|
@@ -1,23 +1,21 @@
|
|
|
1
1
|
module RSpec
|
|
2
2
|
module Matchers
|
|
3
|
-
|
|
4
|
-
#Based on patch from Wilson Bilkovich
|
|
5
3
|
class Change #:nodoc:
|
|
6
4
|
def initialize(receiver=nil, message=nil, &block)
|
|
7
5
|
@message = message
|
|
8
6
|
@value_proc = block || lambda {receiver.__send__(message)}
|
|
9
|
-
@
|
|
10
|
-
@
|
|
7
|
+
@expected_after = @expected_before = @minimum = @maximum = @expected_delta = nil
|
|
8
|
+
@eval_before = @eval_after = false
|
|
11
9
|
end
|
|
12
10
|
|
|
13
11
|
def matches?(event_proc)
|
|
14
12
|
raise_block_syntax_error if block_given?
|
|
15
13
|
|
|
16
|
-
@
|
|
14
|
+
@actual_before = evaluate_value_proc
|
|
17
15
|
event_proc.call
|
|
18
|
-
@
|
|
19
|
-
|
|
20
|
-
changed? && matches_before? && matches_after? &&
|
|
16
|
+
@actual_after = evaluate_value_proc
|
|
17
|
+
|
|
18
|
+
(!change_expected? || changed?) && matches_before? && matches_after? && matches_expected_delta? && matches_min? && matches_max?
|
|
21
19
|
end
|
|
22
20
|
|
|
23
21
|
def raise_block_syntax_error
|
|
@@ -28,35 +26,40 @@ MESSAGE
|
|
|
28
26
|
end
|
|
29
27
|
|
|
30
28
|
def evaluate_value_proc
|
|
31
|
-
@value_proc.call
|
|
29
|
+
case val = @value_proc.call
|
|
30
|
+
when Array, Hash
|
|
31
|
+
val.dup
|
|
32
|
+
else
|
|
33
|
+
val
|
|
34
|
+
end
|
|
32
35
|
end
|
|
33
36
|
|
|
34
37
|
def failure_message_for_should
|
|
35
|
-
if @
|
|
36
|
-
"#{message} should have initially been #{@
|
|
37
|
-
elsif @
|
|
38
|
-
"#{message} should have been changed to #{@
|
|
39
|
-
elsif @
|
|
40
|
-
"#{message} should have been changed by #{@
|
|
38
|
+
if @eval_before && !expected_matches_actual?(@expected_before, @actual_before)
|
|
39
|
+
"#{message} should have initially been #{@expected_before.inspect}, but was #{@actual_before.inspect}"
|
|
40
|
+
elsif @eval_after && !expected_matches_actual?(@expected_after, @actual_after)
|
|
41
|
+
"#{message} should have been changed to #{@expected_after.inspect}, but is now #{@actual_after.inspect}"
|
|
42
|
+
elsif @expected_delta
|
|
43
|
+
"#{message} should have been changed by #{@expected_delta.inspect}, but was changed by #{actual_delta.inspect}"
|
|
41
44
|
elsif @minimum
|
|
42
45
|
"#{message} should have been changed by at least #{@minimum.inspect}, but was changed by #{actual_delta.inspect}"
|
|
43
46
|
elsif @maximum
|
|
44
47
|
"#{message} should have been changed by at most #{@maximum.inspect}, but was changed by #{actual_delta.inspect}"
|
|
45
48
|
else
|
|
46
|
-
"#{message} should have changed, but is still #{@
|
|
49
|
+
"#{message} should have changed, but is still #{@actual_before.inspect}"
|
|
47
50
|
end
|
|
48
51
|
end
|
|
49
52
|
|
|
50
53
|
def actual_delta
|
|
51
|
-
@
|
|
54
|
+
@actual_after - @actual_before
|
|
52
55
|
end
|
|
53
56
|
|
|
54
57
|
def failure_message_for_should_not
|
|
55
|
-
"#{message} should not have changed, but did change from #{@
|
|
58
|
+
"#{message} should not have changed, but did change from #{@actual_before.inspect} to #{@actual_after.inspect}"
|
|
56
59
|
end
|
|
57
60
|
|
|
58
|
-
def by(
|
|
59
|
-
@
|
|
61
|
+
def by(expected_delta)
|
|
62
|
+
@expected_delta = expected_delta
|
|
60
63
|
self
|
|
61
64
|
end
|
|
62
65
|
|
|
@@ -71,14 +74,14 @@ MESSAGE
|
|
|
71
74
|
end
|
|
72
75
|
|
|
73
76
|
def to(to)
|
|
74
|
-
@
|
|
75
|
-
@
|
|
77
|
+
@eval_after = true
|
|
78
|
+
@expected_after = to
|
|
76
79
|
self
|
|
77
80
|
end
|
|
78
81
|
|
|
79
|
-
def from (
|
|
80
|
-
@
|
|
81
|
-
@
|
|
82
|
+
def from (before)
|
|
83
|
+
@eval_before = true
|
|
84
|
+
@expected_before = before
|
|
82
85
|
self
|
|
83
86
|
end
|
|
84
87
|
|
|
@@ -92,39 +95,59 @@ MESSAGE
|
|
|
92
95
|
@message || "result"
|
|
93
96
|
end
|
|
94
97
|
|
|
98
|
+
def change_expected?
|
|
99
|
+
@expected_delta != 0
|
|
100
|
+
end
|
|
101
|
+
|
|
95
102
|
def changed?
|
|
96
|
-
@
|
|
103
|
+
@actual_before != @actual_after
|
|
97
104
|
end
|
|
98
105
|
|
|
99
106
|
def matches_before?
|
|
100
|
-
@
|
|
107
|
+
@eval_before ? expected_matches_actual?(@expected_before, @actual_before) : true
|
|
101
108
|
end
|
|
102
109
|
|
|
103
110
|
def matches_after?
|
|
104
|
-
@
|
|
111
|
+
@eval_after ? expected_matches_actual?(@expected_after, @actual_after) : true
|
|
105
112
|
end
|
|
106
113
|
|
|
107
|
-
def
|
|
108
|
-
@
|
|
114
|
+
def matches_expected_delta?
|
|
115
|
+
@expected_delta ? (@actual_before + @expected_delta == @actual_after) : true
|
|
109
116
|
end
|
|
110
117
|
|
|
111
118
|
def matches_min?
|
|
112
|
-
@minimum ? (@
|
|
119
|
+
@minimum ? (@actual_after - @actual_before >= @minimum) : true
|
|
113
120
|
end
|
|
114
121
|
|
|
115
122
|
def matches_max?
|
|
116
|
-
@maximum ? (@
|
|
123
|
+
@maximum ? (@actual_after - @actual_before <= @maximum) : true
|
|
117
124
|
end
|
|
118
125
|
|
|
126
|
+
def expected_matches_actual?(expected, actual)
|
|
127
|
+
expected === actual
|
|
128
|
+
end
|
|
119
129
|
end
|
|
120
130
|
|
|
121
131
|
# :call-seq:
|
|
122
|
-
# should change(receiver, message
|
|
123
|
-
# should change(receiver, message
|
|
124
|
-
# should change(receiver, message
|
|
125
|
-
# should_not change(receiver, message
|
|
132
|
+
# should change(receiver, message)
|
|
133
|
+
# should change(receiver, message).by(value)
|
|
134
|
+
# should change(receiver, message).from(old).to(new)
|
|
135
|
+
# should_not change(receiver, message)
|
|
126
136
|
#
|
|
127
|
-
#
|
|
137
|
+
# should change {...}
|
|
138
|
+
# should change {...}.by(value)
|
|
139
|
+
# should change {...}.from(old).to(new)
|
|
140
|
+
# should_not change {...}
|
|
141
|
+
#
|
|
142
|
+
# Applied to a proc, specifies that its execution will cause some value to
|
|
143
|
+
# change.
|
|
144
|
+
#
|
|
145
|
+
# You can either pass <tt>receiver</tt> and <tt>message</tt>, or a block,
|
|
146
|
+
# but not both.
|
|
147
|
+
#
|
|
148
|
+
# When passing a block, it must use the <tt>{ ... }</tt> format, not
|
|
149
|
+
# do/end, as <tt>{ ... }</tt> binds to the +change+ method, whereas do/end
|
|
150
|
+
# would errantly bind to the +should+ or +should_not+ method.
|
|
128
151
|
#
|
|
129
152
|
# == Examples
|
|
130
153
|
#
|
|
@@ -157,22 +180,24 @@ MESSAGE
|
|
|
157
180
|
# employee.develop_great_new_social_networking_app
|
|
158
181
|
# }.should change(employee, :title).from("Mail Clerk").to("CEO")
|
|
159
182
|
#
|
|
160
|
-
#
|
|
161
|
-
#
|
|
162
|
-
#
|
|
183
|
+
# lambda {
|
|
184
|
+
# doctor.leave_office
|
|
185
|
+
# }.should change(doctor, :sign).from(/is in/).to(/is out/)
|
|
163
186
|
#
|
|
164
|
-
#
|
|
165
|
-
#
|
|
187
|
+
# user = User.new(:type => "admin")
|
|
188
|
+
# lambda {
|
|
189
|
+
# user.symbolize_type
|
|
190
|
+
# }.should change(user, :type).from(String).to(Symbol)
|
|
166
191
|
#
|
|
167
|
-
# ==
|
|
168
|
-
# <tt>should_not change</tt> only supports the form with no
|
|
169
|
-
# subsequent calls to <tt>by</tt>, <tt>by_at_least</tt>,
|
|
170
|
-
# <tt>by_at_most</tt>, <tt>to</tt> or <tt>from</tt>.
|
|
192
|
+
# == Notes
|
|
171
193
|
#
|
|
172
|
-
#
|
|
173
|
-
#
|
|
174
|
-
#
|
|
194
|
+
# Evaluates <tt>receiver.message</tt> or <tt>block</tt> before and after it
|
|
195
|
+
# evaluates the proc object (generated by the lambdas in the examples
|
|
196
|
+
# above).
|
|
175
197
|
#
|
|
198
|
+
# <tt>should_not change</tt> only supports the form with no subsequent
|
|
199
|
+
# calls to <tt>by</tt>, <tt>by_at_least</tt>, <tt>by_at_most</tt>,
|
|
200
|
+
# <tt>to</tt> or <tt>from</tt>.
|
|
176
201
|
def change(receiver=nil, message=nil, &block)
|
|
177
202
|
Matchers::Change.new(receiver, message, &block)
|
|
178
203
|
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module RSpec
|
|
2
|
+
module Matchers
|
|
3
|
+
# :call-seq:
|
|
4
|
+
# should cover(expected)
|
|
5
|
+
# should_not cover(expected)
|
|
6
|
+
#
|
|
7
|
+
# Passes if actual covers expected. This works for
|
|
8
|
+
# Ranges. You can also pass in multiple args
|
|
9
|
+
# and it will only pass if all args are found in Range.
|
|
10
|
+
#
|
|
11
|
+
# == Examples
|
|
12
|
+
# (1..10).should cover(5)
|
|
13
|
+
# (1..10).should cover(4, 6)
|
|
14
|
+
# (1..10).should cover(4, 6, 11) # will fail
|
|
15
|
+
# (1..10).should_not cover(11)
|
|
16
|
+
# (1..10).should_not cover(5) # will fail
|
|
17
|
+
#
|
|
18
|
+
# == Warning: Ruby >= 1.9 only
|
|
19
|
+
def cover(*values)
|
|
20
|
+
Matcher.new :cover, *values do |*_values|
|
|
21
|
+
match_for_should do |range|
|
|
22
|
+
_values.all? &covered_by(range)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
match_for_should_not do |range|
|
|
26
|
+
_values.none? &covered_by(range)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def covered_by(range)
|
|
30
|
+
lambda {|value| range.cover?(value)}
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
data/lib/rspec/matchers/exist.rb
CHANGED
|
@@ -4,11 +4,21 @@ module RSpec
|
|
|
4
4
|
# should exist
|
|
5
5
|
# should_not exist
|
|
6
6
|
#
|
|
7
|
-
# Passes if actual.exist?
|
|
8
|
-
def exist(
|
|
7
|
+
# Passes if actual.exist? or actual.exists?
|
|
8
|
+
def exist(*args)
|
|
9
9
|
Matcher.new :exist do
|
|
10
10
|
match do |actual|
|
|
11
|
-
|
|
11
|
+
predicates = [:exist?, :exists?].select { |p| actual.respond_to?(p) }
|
|
12
|
+
existance_values = predicates.map { |p| actual.send(p, *args) }
|
|
13
|
+
uniq_truthy_values = existance_values.map { |v| !!v }.uniq
|
|
14
|
+
|
|
15
|
+
case uniq_truthy_values.size
|
|
16
|
+
when 0; raise NoMethodError.new("#{actual.inspect} does not respond to either #exist? or #exists?")
|
|
17
|
+
when 1; existance_values.first
|
|
18
|
+
else raise "#exist? and #exists? returned different values:\n\n" +
|
|
19
|
+
" exist?: #{existance_values.first}\n" +
|
|
20
|
+
"exists?: #{existance_values.last}"
|
|
21
|
+
end
|
|
12
22
|
end
|
|
13
23
|
end
|
|
14
24
|
end
|
data/lib/rspec/matchers/has.rb
CHANGED
|
@@ -1,35 +1,39 @@
|
|
|
1
1
|
module RSpec
|
|
2
2
|
module Matchers
|
|
3
|
-
|
|
4
3
|
class Has
|
|
5
|
-
|
|
6
4
|
def initialize(expected, *args)
|
|
7
5
|
@expected, @args = expected, args
|
|
8
6
|
end
|
|
9
|
-
|
|
7
|
+
|
|
10
8
|
def matches?(actual)
|
|
11
9
|
actual.__send__(predicate(@expected), *@args)
|
|
12
10
|
end
|
|
13
|
-
|
|
11
|
+
|
|
14
12
|
def failure_message_for_should
|
|
15
13
|
"expected ##{predicate(@expected)}(#{@args[0].inspect}) to return true, got false"
|
|
16
14
|
end
|
|
17
|
-
|
|
15
|
+
|
|
18
16
|
def failure_message_for_should_not
|
|
19
17
|
"expected ##{predicate(@expected)}(#{@args[0].inspect}) to return false, got true"
|
|
20
18
|
end
|
|
21
|
-
|
|
19
|
+
|
|
22
20
|
def description
|
|
23
|
-
|
|
21
|
+
[method_description(@expected), args_description(@args)].compact.join(' ')
|
|
24
22
|
end
|
|
25
|
-
|
|
23
|
+
|
|
26
24
|
private
|
|
27
|
-
|
|
28
25
|
def predicate(sym)
|
|
29
26
|
"#{sym.to_s.sub("have_","has_")}?".to_sym
|
|
30
27
|
end
|
|
31
|
-
|
|
28
|
+
|
|
29
|
+
def method_description(method)
|
|
30
|
+
method.to_s.gsub('_', ' ')
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def args_description(args)
|
|
34
|
+
return nil if args.empty?
|
|
35
|
+
args.map { |arg| arg.inspect }.join(', ')
|
|
36
|
+
end
|
|
32
37
|
end
|
|
33
|
-
|
|
34
38
|
end
|
|
35
39
|
end
|
data/lib/rspec/matchers/have.rb
CHANGED
|
@@ -4,7 +4,7 @@ module RSpec
|
|
|
4
4
|
def initialize(expected, relativity=:exactly)
|
|
5
5
|
@expected = (expected == :no ? 0 : expected)
|
|
6
6
|
@relativity = relativity
|
|
7
|
-
@actual = nil
|
|
7
|
+
@actual = @collection_name = @plural_collection_name = nil
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
def relativities
|
|
@@ -73,10 +73,10 @@ EOF
|
|
|
73
73
|
|
|
74
74
|
private
|
|
75
75
|
|
|
76
|
-
def method_missing(
|
|
77
|
-
@collection_name =
|
|
78
|
-
if inflector = (defined?(ActiveSupport::Inflector) ? ActiveSupport::Inflector : (defined?(Inflector) ? Inflector : nil))
|
|
79
|
-
@plural_collection_name = inflector.pluralize(
|
|
76
|
+
def method_missing(method, *args, &block)
|
|
77
|
+
@collection_name = method
|
|
78
|
+
if inflector = (defined?(ActiveSupport::Inflector) && ActiveSupport::Inflector.respond_to?(:pluralize) ? ActiveSupport::Inflector : (defined?(Inflector) ? Inflector : nil))
|
|
79
|
+
@plural_collection_name = inflector.pluralize(method.to_s)
|
|
80
80
|
end
|
|
81
81
|
@args = args
|
|
82
82
|
@block = block
|
|
@@ -18,10 +18,21 @@ module RSpec
|
|
|
18
18
|
# "spread".should_not include("red")
|
|
19
19
|
def include(*expected)
|
|
20
20
|
Matcher.new :include, *expected do |*_expected|
|
|
21
|
-
|
|
22
|
-
|
|
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|
|
|
23
34
|
if comparing_hash_values?(actual, expected)
|
|
24
|
-
expected.
|
|
35
|
+
expected.send(hash_predicate) {|k,v| actual[k] == v}
|
|
25
36
|
elsif comparing_hash_keys?(actual, expected)
|
|
26
37
|
actual.has_key?(expected)
|
|
27
38
|
else
|
|
@@ -37,9 +48,7 @@ module RSpec
|
|
|
37
48
|
def comparing_hash_values?(actual, expected) # :nodoc:
|
|
38
49
|
actual.is_a?(Hash) && expected.is_a?(Hash)
|
|
39
50
|
end
|
|
40
|
-
|
|
41
51
|
end
|
|
42
|
-
|
|
43
52
|
end
|
|
44
53
|
end
|
|
45
54
|
end
|
|
@@ -11,7 +11,9 @@ module RSpec
|
|
|
11
11
|
@expected = expected
|
|
12
12
|
@actual = nil
|
|
13
13
|
@diffable = false
|
|
14
|
-
@expected_exception, @rescued_exception = nil
|
|
14
|
+
@expected_exception, @rescued_exception = nil, nil
|
|
15
|
+
@match_for_should_not_block = nil
|
|
16
|
+
|
|
15
17
|
@messages = {
|
|
16
18
|
:description => lambda {"#{name_to_sentence}#{expected_to_sentence}"},
|
|
17
19
|
:failure_message_for_should => lambda {|actual| "expected #{actual.inspect} to #{name_to_sentence}#{expected_to_sentence}"},
|
|
@@ -22,7 +24,7 @@ module RSpec
|
|
|
22
24
|
end
|
|
23
25
|
end
|
|
24
26
|
|
|
25
|
-
#Used internally by
|
|
27
|
+
#Used internally by +should+ and +should_not+.
|
|
26
28
|
def matches?(actual)
|
|
27
29
|
@actual = actual
|
|
28
30
|
if @expected_exception
|
|
@@ -41,10 +43,32 @@ module RSpec
|
|
|
41
43
|
end
|
|
42
44
|
end
|
|
43
45
|
|
|
46
|
+
# Used internally by +should_not+
|
|
47
|
+
def does_not_match?(actual)
|
|
48
|
+
@actual = actual
|
|
49
|
+
@match_for_should_not_block ?
|
|
50
|
+
instance_exec(actual, &@match_for_should_not_block) :
|
|
51
|
+
!matches?(actual)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def include(*args)
|
|
55
|
+
singleton_class.__send__(:include, *args)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def define_method(name, &block) # :nodoc:
|
|
59
|
+
singleton_class.__send__(:define_method, name, &block)
|
|
60
|
+
end
|
|
61
|
+
|
|
44
62
|
# See RSpec::Matchers
|
|
45
63
|
def match(&block)
|
|
46
64
|
@match_block = block
|
|
47
65
|
end
|
|
66
|
+
alias match_for_should match
|
|
67
|
+
|
|
68
|
+
# See RSpec::Matchers
|
|
69
|
+
def match_for_should_not(&block)
|
|
70
|
+
@match_for_should_not_block = block
|
|
71
|
+
end
|
|
48
72
|
|
|
49
73
|
# See RSpec::Matchers
|
|
50
74
|
def match_unless_raises(exception=Exception, &block)
|
|
@@ -79,21 +103,19 @@ module RSpec
|
|
|
79
103
|
|
|
80
104
|
# See RSpec::Matchers
|
|
81
105
|
def chain(method, &block)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
self
|
|
86
|
-
end
|
|
106
|
+
define_method method do |*args|
|
|
107
|
+
block.call(*args)
|
|
108
|
+
self
|
|
87
109
|
end
|
|
88
110
|
end
|
|
89
111
|
|
|
90
112
|
private
|
|
91
113
|
|
|
92
|
-
def method_missing(
|
|
93
|
-
if $matcher_execution_context.respond_to?(
|
|
94
|
-
$matcher_execution_context.send
|
|
114
|
+
def method_missing(method, *args, &block)
|
|
115
|
+
if $matcher_execution_context.respond_to?(method)
|
|
116
|
+
$matcher_execution_context.send method, *args, &block
|
|
95
117
|
else
|
|
96
|
-
super(
|
|
118
|
+
super(method, *args, &block)
|
|
97
119
|
end
|
|
98
120
|
end
|
|
99
121
|
|
|
@@ -110,8 +132,7 @@ module RSpec
|
|
|
110
132
|
# cause features to fail and that will make users unhappy. So don't.
|
|
111
133
|
orig_private_methods = private_methods
|
|
112
134
|
yield
|
|
113
|
-
|
|
114
|
-
(private_methods - orig_private_methods).each {|m| st.__send__ :public, m}
|
|
135
|
+
(private_methods - orig_private_methods).each {|m| singleton_class.__send__ :public, m}
|
|
115
136
|
end
|
|
116
137
|
|
|
117
138
|
def cache_or_call_cached(key, &block)
|
|
@@ -134,6 +155,11 @@ module RSpec
|
|
|
134
155
|
to_sentence(@expected)
|
|
135
156
|
end
|
|
136
157
|
|
|
158
|
+
unless method_defined?(:singleton_class)
|
|
159
|
+
def singleton_class
|
|
160
|
+
class << self; self; end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
137
163
|
end
|
|
138
164
|
end
|
|
139
165
|
end
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
module RSpec
|
|
2
2
|
module Matchers
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
|
|
4
|
+
private
|
|
5
|
+
|
|
6
|
+
def method_missing(method, *args, &block) # :nodoc:
|
|
7
|
+
return Matchers::BePredicate.new(method, *args, &block) if method.to_s =~ /^be_/
|
|
8
|
+
return Matchers::Has.new(method, *args, &block) if method.to_s =~ /^have_/
|
|
6
9
|
super
|
|
7
10
|
end
|
|
8
11
|
end
|
|
@@ -29,6 +29,15 @@ module RSpec
|
|
|
29
29
|
eval_match(@actual, operator, expected)
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
|
+
|
|
33
|
+
negative_operator = operator.sub(/^=/, '!')
|
|
34
|
+
if negative_operator != operator && respond_to?(negative_operator)
|
|
35
|
+
define_method(negative_operator) do |expected|
|
|
36
|
+
opposite_should = ::RSpec::Matchers.last_should == :should ? :should_not : :should
|
|
37
|
+
raise "RSpec does not support `#{::RSpec::Matchers.last_should} #{negative_operator} expected`. " +
|
|
38
|
+
"Use `#{opposite_should} #{operator} expected` instead."
|
|
39
|
+
end
|
|
40
|
+
end
|
|
32
41
|
end
|
|
33
42
|
|
|
34
43
|
['==', '===', '=~', '>', '>=', '<', '<='].each do |operator|
|
|
@@ -58,9 +67,9 @@ module RSpec
|
|
|
58
67
|
if actual.__send__(operator, expected)
|
|
59
68
|
true
|
|
60
69
|
elsif ['==','===', '=~'].include?(operator)
|
|
61
|
-
fail_with_message("expected: #{expected.inspect}
|
|
70
|
+
fail_with_message("expected: #{expected.inspect}\n got: #{actual.inspect} (using #{operator})")
|
|
62
71
|
else
|
|
63
|
-
fail_with_message("expected: #{operator} #{expected.inspect}
|
|
72
|
+
fail_with_message("expected: #{operator} #{expected.inspect}\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
|
|
64
73
|
end
|
|
65
74
|
end
|
|
66
75
|
|
|
@@ -69,7 +78,7 @@ module RSpec
|
|
|
69
78
|
class NegativeOperatorMatcher < OperatorMatcher #:nodoc:
|
|
70
79
|
def __delegate_operator(actual, operator, expected)
|
|
71
80
|
return false unless actual.__send__(operator, expected)
|
|
72
|
-
return fail_with_message("expected not: #{operator} #{expected.inspect}
|
|
81
|
+
return fail_with_message("expected not: #{operator} #{expected.inspect}\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
|
|
73
82
|
end
|
|
74
83
|
|
|
75
84
|
end
|
|
@@ -5,23 +5,22 @@ module RSpec
|
|
|
5
5
|
def initialize(*names)
|
|
6
6
|
@names = names
|
|
7
7
|
@expected_arity = nil
|
|
8
|
-
@names_not_responded_to = []
|
|
9
8
|
end
|
|
10
9
|
|
|
11
10
|
def matches?(actual)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
find_failing_method_names(actual, :reject).empty?
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def does_not_match?(actual)
|
|
15
|
+
find_failing_method_names(actual, :select).empty?
|
|
17
16
|
end
|
|
18
17
|
|
|
19
18
|
def failure_message_for_should
|
|
20
|
-
"expected #{@actual.inspect} to respond to #{@
|
|
19
|
+
"expected #{@actual.inspect} to respond to #{@failing_method_names.collect {|name| name.inspect }.join(', ')}#{with_arity}"
|
|
21
20
|
end
|
|
22
21
|
|
|
23
22
|
def failure_message_for_should_not
|
|
24
|
-
|
|
23
|
+
failure_message_for_should.sub(/to respond to/, 'not to respond to')
|
|
25
24
|
end
|
|
26
25
|
|
|
27
26
|
def description
|
|
@@ -39,9 +38,24 @@ module RSpec
|
|
|
39
38
|
alias :arguments :argument
|
|
40
39
|
|
|
41
40
|
private
|
|
41
|
+
|
|
42
|
+
def find_failing_method_names(actual, filter_method)
|
|
43
|
+
@actual = actual
|
|
44
|
+
@failing_method_names = @names.send(filter_method) do |name|
|
|
45
|
+
@actual.respond_to?(name) && matches_arity?(actual, name)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
42
48
|
|
|
43
49
|
def matches_arity?(actual, name)
|
|
44
|
-
|
|
50
|
+
return true unless @expected_arity
|
|
51
|
+
|
|
52
|
+
actual_arity = actual.method(name).arity
|
|
53
|
+
if actual_arity < 0
|
|
54
|
+
# ~ inverts the one's complement and gives us the number of required args
|
|
55
|
+
~actual_arity <= @expected_arity
|
|
56
|
+
else
|
|
57
|
+
actual_arity == @expected_arity
|
|
58
|
+
end
|
|
45
59
|
end
|
|
46
60
|
|
|
47
61
|
def with_arity
|