rspec-expectations 2.11.3 → 3.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/.document +1 -1
- data/.yardopts +1 -1
- data/Changelog.md +1026 -21
- data/{License.txt → LICENSE.md} +5 -3
- data/README.md +174 -78
- data/lib/rspec/expectations/block_snippet_extractor.rb +253 -0
- data/lib/rspec/expectations/configuration.rb +230 -0
- data/lib/rspec/expectations/expectation_target.rb +130 -55
- data/lib/rspec/expectations/fail_with.rb +17 -33
- data/lib/rspec/expectations/failure_aggregator.rb +212 -0
- data/lib/rspec/expectations/handler.rb +163 -29
- data/lib/rspec/expectations/minitest_integration.rb +58 -0
- data/lib/rspec/expectations/syntax.rb +68 -54
- data/lib/rspec/expectations/version.rb +1 -1
- data/lib/rspec/expectations.rb +59 -24
- data/lib/rspec/matchers/aliased_matcher.rb +116 -0
- data/lib/rspec/matchers/built_in/all.rb +86 -0
- data/lib/rspec/matchers/built_in/base_matcher.rb +150 -20
- data/lib/rspec/matchers/built_in/be.rb +115 -109
- data/lib/rspec/matchers/built_in/be_between.rb +77 -0
- data/lib/rspec/matchers/built_in/be_instance_of.rb +16 -1
- data/lib/rspec/matchers/built_in/be_kind_of.rb +10 -1
- data/lib/rspec/matchers/built_in/be_within.rb +43 -17
- data/lib/rspec/matchers/built_in/change.rb +392 -75
- data/lib/rspec/matchers/built_in/compound.rb +290 -0
- data/lib/rspec/matchers/built_in/contain_exactly.rb +302 -0
- data/lib/rspec/matchers/built_in/count_expectation.rb +169 -0
- data/lib/rspec/matchers/built_in/cover.rb +3 -0
- data/lib/rspec/matchers/built_in/eq.rb +26 -8
- data/lib/rspec/matchers/built_in/eql.rb +19 -8
- data/lib/rspec/matchers/built_in/equal.rb +56 -19
- data/lib/rspec/matchers/built_in/exist.rb +74 -10
- data/lib/rspec/matchers/built_in/has.rb +141 -22
- data/lib/rspec/matchers/built_in/have_attributes.rb +114 -0
- data/lib/rspec/matchers/built_in/include.rb +175 -20
- data/lib/rspec/matchers/built_in/match.rb +95 -1
- data/lib/rspec/matchers/built_in/operators.rb +128 -0
- data/lib/rspec/matchers/built_in/output.rb +207 -0
- data/lib/rspec/matchers/built_in/raise_error.rb +212 -38
- data/lib/rspec/matchers/built_in/respond_to.rb +155 -29
- data/lib/rspec/matchers/built_in/satisfy.rb +39 -9
- data/lib/rspec/matchers/built_in/start_or_end_with.rb +94 -0
- data/lib/rspec/matchers/built_in/throw_symbol.rb +58 -14
- data/lib/rspec/matchers/built_in/yield.rb +252 -98
- data/lib/rspec/matchers/built_in.rb +47 -33
- data/lib/rspec/matchers/composable.rb +171 -0
- data/lib/rspec/matchers/dsl.rb +530 -10
- data/lib/rspec/matchers/english_phrasing.rb +58 -0
- data/lib/rspec/matchers/expecteds_for_multiple_diffs.rb +82 -0
- data/lib/rspec/matchers/fail_matchers.rb +42 -0
- data/lib/rspec/matchers/generated_descriptions.rb +15 -10
- data/lib/rspec/matchers/matcher_delegator.rb +35 -0
- data/lib/rspec/matchers/matcher_protocol.rb +105 -0
- data/lib/rspec/matchers.rb +604 -252
- data.tar.gz.sig +0 -0
- metadata +178 -278
- metadata.gz.sig +0 -0
- data/features/README.md +0 -49
- data/features/Upgrade.md +0 -53
- data/features/built_in_matchers/README.md +0 -90
- data/features/built_in_matchers/be.feature +0 -173
- data/features/built_in_matchers/be_within.feature +0 -46
- data/features/built_in_matchers/cover.feature +0 -45
- data/features/built_in_matchers/end_with.feature +0 -46
- data/features/built_in_matchers/equality.feature +0 -145
- data/features/built_in_matchers/exist.feature +0 -43
- data/features/built_in_matchers/expect_change.feature +0 -59
- data/features/built_in_matchers/expect_error.feature +0 -138
- data/features/built_in_matchers/have.feature +0 -103
- data/features/built_in_matchers/include.feature +0 -121
- data/features/built_in_matchers/match.feature +0 -50
- data/features/built_in_matchers/operators.feature +0 -221
- data/features/built_in_matchers/predicates.feature +0 -128
- data/features/built_in_matchers/respond_to.feature +0 -78
- data/features/built_in_matchers/satisfy.feature +0 -31
- data/features/built_in_matchers/start_with.feature +0 -46
- data/features/built_in_matchers/throw_symbol.feature +0 -85
- data/features/built_in_matchers/types.feature +0 -114
- data/features/built_in_matchers/yield.feature +0 -146
- data/features/custom_matchers/access_running_example.feature +0 -53
- data/features/custom_matchers/define_diffable_matcher.feature +0 -27
- data/features/custom_matchers/define_matcher.feature +0 -340
- data/features/custom_matchers/define_matcher_outside_rspec.feature +0 -38
- data/features/custom_matchers/define_matcher_with_fluent_interface.feature +0 -24
- data/features/customized_message.feature +0 -22
- data/features/diffing.feature +0 -85
- data/features/implicit_docstrings.feature +0 -52
- data/features/step_definitions/additional_cli_steps.rb +0 -22
- data/features/support/env.rb +0 -5
- data/features/syntax_configuration.feature +0 -68
- data/features/test_frameworks/test_unit.feature +0 -46
- data/lib/rspec/expectations/deprecation.rb +0 -38
- data/lib/rspec/expectations/differ.rb +0 -81
- data/lib/rspec/expectations/errors.rb +0 -9
- data/lib/rspec/expectations/extensions/array.rb +0 -9
- data/lib/rspec/expectations/extensions/object.rb +0 -39
- data/lib/rspec/expectations/extensions.rb +0 -2
- data/lib/rspec/matchers/be_close.rb +0 -9
- data/lib/rspec/matchers/built_in/have.rb +0 -108
- data/lib/rspec/matchers/built_in/match_array.rb +0 -45
- data/lib/rspec/matchers/built_in/start_and_end_with.rb +0 -48
- data/lib/rspec/matchers/compatibility.rb +0 -14
- data/lib/rspec/matchers/configuration.rb +0 -66
- data/lib/rspec/matchers/extensions/instance_eval_with_args.rb +0 -39
- data/lib/rspec/matchers/matcher.rb +0 -299
- data/lib/rspec/matchers/method_missing.rb +0 -12
- data/lib/rspec/matchers/operator_matcher.rb +0 -84
- data/lib/rspec/matchers/pretty.rb +0 -60
- data/lib/rspec-expectations.rb +0 -1
- data/spec/rspec/expectations/differ_spec.rb +0 -153
- data/spec/rspec/expectations/expectation_target_spec.rb +0 -65
- data/spec/rspec/expectations/extensions/kernel_spec.rb +0 -67
- data/spec/rspec/expectations/fail_with_spec.rb +0 -70
- data/spec/rspec/expectations/handler_spec.rb +0 -206
- data/spec/rspec/matchers/base_matcher_spec.rb +0 -60
- data/spec/rspec/matchers/be_close_spec.rb +0 -22
- data/spec/rspec/matchers/be_instance_of_spec.rb +0 -40
- data/spec/rspec/matchers/be_kind_of_spec.rb +0 -37
- data/spec/rspec/matchers/be_spec.rb +0 -452
- data/spec/rspec/matchers/be_within_spec.rb +0 -80
- data/spec/rspec/matchers/change_spec.rb +0 -528
- data/spec/rspec/matchers/configuration_spec.rb +0 -202
- data/spec/rspec/matchers/cover_spec.rb +0 -69
- data/spec/rspec/matchers/description_generation_spec.rb +0 -176
- data/spec/rspec/matchers/dsl_spec.rb +0 -57
- data/spec/rspec/matchers/eq_spec.rb +0 -54
- data/spec/rspec/matchers/eql_spec.rb +0 -41
- data/spec/rspec/matchers/equal_spec.rb +0 -60
- data/spec/rspec/matchers/exist_spec.rb +0 -110
- data/spec/rspec/matchers/has_spec.rb +0 -118
- data/spec/rspec/matchers/have_spec.rb +0 -461
- data/spec/rspec/matchers/include_spec.rb +0 -367
- data/spec/rspec/matchers/match_array_spec.rb +0 -124
- data/spec/rspec/matchers/match_spec.rb +0 -61
- data/spec/rspec/matchers/matcher_spec.rb +0 -434
- data/spec/rspec/matchers/matchers_spec.rb +0 -31
- data/spec/rspec/matchers/method_missing_spec.rb +0 -24
- data/spec/rspec/matchers/operator_matcher_spec.rb +0 -221
- data/spec/rspec/matchers/raise_error_spec.rb +0 -344
- data/spec/rspec/matchers/respond_to_spec.rb +0 -295
- data/spec/rspec/matchers/satisfy_spec.rb +0 -44
- data/spec/rspec/matchers/start_with_end_with_spec.rb +0 -182
- data/spec/rspec/matchers/throw_symbol_spec.rb +0 -116
- data/spec/rspec/matchers/yield_spec.rb +0 -402
- data/spec/spec_helper.rb +0 -27
- data/spec/support/classes.rb +0 -56
- data/spec/support/in_sub_process.rb +0 -31
- data/spec/support/matchers.rb +0 -22
- data/spec/support/ruby_version.rb +0 -10
- data/spec/support/shared_examples.rb +0 -13
@@ -1,299 +0,0 @@
|
|
1
|
-
require 'set'
|
2
|
-
|
3
|
-
module RSpec
|
4
|
-
module Matchers
|
5
|
-
module DSL
|
6
|
-
# Provides the context in which the block passed to RSpec::Matchers.define
|
7
|
-
# will be evaluated.
|
8
|
-
class Matcher
|
9
|
-
include RSpec::Matchers::Extensions::InstanceEvalWithArgs
|
10
|
-
include RSpec::Matchers::Pretty
|
11
|
-
include RSpec::Matchers
|
12
|
-
|
13
|
-
attr_reader :expected, :actual, :rescued_exception
|
14
|
-
attr_accessor :matcher_execution_context
|
15
|
-
|
16
|
-
# @api private
|
17
|
-
def initialize(name, &declarations)
|
18
|
-
@name = name
|
19
|
-
@declarations = declarations
|
20
|
-
@actual = nil
|
21
|
-
@diffable = false
|
22
|
-
@expected_exception, @rescued_exception = nil, nil
|
23
|
-
@match_for_should_not_block = nil
|
24
|
-
@messages = {}
|
25
|
-
end
|
26
|
-
|
27
|
-
PERSISTENT_INSTANCE_VARIABLES = [
|
28
|
-
:@name, :@declarations, :@diffable, :@messages,
|
29
|
-
:@match_block, :@match_for_should_not_block,
|
30
|
-
:@expected_exception
|
31
|
-
].to_set
|
32
|
-
|
33
|
-
# @api private
|
34
|
-
def for_expected(*expected)
|
35
|
-
@expected = expected
|
36
|
-
dup.instance_eval do
|
37
|
-
instance_variables.map {|ivar| ivar.intern}.each do |ivar|
|
38
|
-
instance_variable_set(ivar, nil) unless (PERSISTENT_INSTANCE_VARIABLES + [:@expected]).include?(ivar)
|
39
|
-
end
|
40
|
-
making_declared_methods_public do
|
41
|
-
instance_eval_with_args(*@expected, &@declarations)
|
42
|
-
end
|
43
|
-
self
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
# @api private
|
48
|
-
# Used internally by +should+ and +should_not+.
|
49
|
-
def matches?(actual)
|
50
|
-
@actual = actual
|
51
|
-
if @expected_exception
|
52
|
-
begin
|
53
|
-
instance_eval_with_args(actual, &@match_block)
|
54
|
-
true
|
55
|
-
rescue @expected_exception => @rescued_exception
|
56
|
-
false
|
57
|
-
end
|
58
|
-
else
|
59
|
-
begin
|
60
|
-
instance_eval_with_args(actual, &@match_block)
|
61
|
-
rescue RSpec::Expectations::ExpectationNotMetError
|
62
|
-
false
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# Stores the block that is used to determine whether this matcher passes
|
68
|
-
# or fails. The block should return a boolean value. When the matcher is
|
69
|
-
# passed to `should` and the block returns `true`, then the expectation
|
70
|
-
# passes. Similarly, when the matcher is passed to `should_not` and the
|
71
|
-
# block returns `false`, then the expectation passes.
|
72
|
-
#
|
73
|
-
# Use `match_for_should` when used in conjuntion with
|
74
|
-
# `match_for_should_not`.
|
75
|
-
#
|
76
|
-
# @example
|
77
|
-
#
|
78
|
-
# RSpec::Matchers.define :be_even do
|
79
|
-
# match do |actual|
|
80
|
-
# actual.even?
|
81
|
-
# end
|
82
|
-
# end
|
83
|
-
#
|
84
|
-
# 4.should be_even # passes
|
85
|
-
# 3.should_not be_even # passes
|
86
|
-
# 3.should be_even # fails
|
87
|
-
# 4.should_not be_even # fails
|
88
|
-
#
|
89
|
-
# @yield [Object] actual the actual value (or receiver of should)
|
90
|
-
def match(&block)
|
91
|
-
@match_block = block
|
92
|
-
end
|
93
|
-
|
94
|
-
alias_method :match_for_should, :match
|
95
|
-
|
96
|
-
# Use this to define the block for a negative expectation (`should_not`)
|
97
|
-
# when the positive and negative forms require different handling. This
|
98
|
-
# is rarely necessary, but can be helpful, for example, when specifying
|
99
|
-
# asynchronous processes that require different timeouts.
|
100
|
-
#
|
101
|
-
# @yield [Object] actual the actual value (or receiver of should)
|
102
|
-
def match_for_should_not(&block)
|
103
|
-
@match_for_should_not_block = block
|
104
|
-
end
|
105
|
-
|
106
|
-
# Use this instead of `match` when the block will raise an exception
|
107
|
-
# rather than returning false to indicate a failure.
|
108
|
-
#
|
109
|
-
# @example
|
110
|
-
#
|
111
|
-
# RSpec::Matchers.define :accept_as_valid do |candidate_address|
|
112
|
-
# match_unless_raises ValidationException do |validator|
|
113
|
-
# validator.validate(candidate_address)
|
114
|
-
# end
|
115
|
-
# end
|
116
|
-
#
|
117
|
-
# email_validator.should accept_as_valid("person@company.com")
|
118
|
-
def match_unless_raises(exception=Exception, &block)
|
119
|
-
@expected_exception = exception
|
120
|
-
match(&block)
|
121
|
-
end
|
122
|
-
|
123
|
-
# Customize the failure messsage to use when this matcher is invoked with
|
124
|
-
# `should`. Only use this when the message generated by default doesn't
|
125
|
-
# suit your needs.
|
126
|
-
#
|
127
|
-
# @example
|
128
|
-
#
|
129
|
-
# RSpec::Matchers.define :have_strength do |expected|
|
130
|
-
# match { ... }
|
131
|
-
#
|
132
|
-
# failure_message_for_should do |actual|
|
133
|
-
# "Expected strength of #{expected}, but had #{actual.strength}"
|
134
|
-
# end
|
135
|
-
# end
|
136
|
-
#
|
137
|
-
# @yield [Object] actual the actual object
|
138
|
-
def failure_message_for_should(&block)
|
139
|
-
cache_or_call_cached(:failure_message_for_should, &block)
|
140
|
-
end
|
141
|
-
|
142
|
-
# Customize the failure messsage to use when this matcher is invoked with
|
143
|
-
# `should_not`. Only use this when the message generated by default
|
144
|
-
# doesn't suit your needs.
|
145
|
-
#
|
146
|
-
# @example
|
147
|
-
#
|
148
|
-
# RSpec::Matchers.define :have_strength do |expected|
|
149
|
-
# match { ... }
|
150
|
-
#
|
151
|
-
# failure_message_for_should_not do |actual|
|
152
|
-
# "Expected not to have strength of #{expected}, but did"
|
153
|
-
# end
|
154
|
-
# end
|
155
|
-
#
|
156
|
-
# @yield [Object] actual the actual object
|
157
|
-
# @yield [Object] actual the actual object
|
158
|
-
def failure_message_for_should_not(&block)
|
159
|
-
cache_or_call_cached(:failure_message_for_should_not, &block)
|
160
|
-
end
|
161
|
-
|
162
|
-
|
163
|
-
# Customize the description to use for one-liners. Only use this when
|
164
|
-
# the description generated by default doesn't suit your needs.
|
165
|
-
#
|
166
|
-
# @example
|
167
|
-
#
|
168
|
-
# RSpec::Matchers.define :qualify_for do |expected|
|
169
|
-
# match { ... }
|
170
|
-
#
|
171
|
-
# description do
|
172
|
-
# "qualify for #{expected}"
|
173
|
-
# end
|
174
|
-
# end
|
175
|
-
def description(&block)
|
176
|
-
cache_or_call_cached(:description, &block)
|
177
|
-
end
|
178
|
-
|
179
|
-
# Tells the matcher to diff the actual and expected values in the failure
|
180
|
-
# message.
|
181
|
-
def diffable
|
182
|
-
@diffable = true
|
183
|
-
end
|
184
|
-
|
185
|
-
# Convenience for defining methods on this matcher to create a fluent
|
186
|
-
# interface. The trick about fluent interfaces is that each method must
|
187
|
-
# return self in order to chain methods together. `chain` handles that
|
188
|
-
# for you.
|
189
|
-
#
|
190
|
-
# @example
|
191
|
-
#
|
192
|
-
# RSpec::Matchers.define :have_errors_on do |key|
|
193
|
-
# chain :with do |message|
|
194
|
-
# @message = message
|
195
|
-
# end
|
196
|
-
#
|
197
|
-
# match do |actual|
|
198
|
-
# actual.errors[key] == @message
|
199
|
-
# end
|
200
|
-
# end
|
201
|
-
#
|
202
|
-
# minor.should have_errors_on(:age).with("Not old enough to participate")
|
203
|
-
def chain(method, &block)
|
204
|
-
define_method method do |*args|
|
205
|
-
block.call(*args)
|
206
|
-
self
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
# @api private
|
211
|
-
# Used internally by objects returns by +should+ and +should_not+.
|
212
|
-
def diffable?
|
213
|
-
@diffable
|
214
|
-
end
|
215
|
-
|
216
|
-
# @api private
|
217
|
-
# Used internally by +should_not+
|
218
|
-
def does_not_match?(actual)
|
219
|
-
@actual = actual
|
220
|
-
@match_for_should_not_block ?
|
221
|
-
instance_eval_with_args(actual, &@match_for_should_not_block) :
|
222
|
-
!matches?(actual)
|
223
|
-
end
|
224
|
-
|
225
|
-
def respond_to?(method, include_private=false)
|
226
|
-
super || matcher_execution_context.respond_to?(method, include_private)
|
227
|
-
end
|
228
|
-
|
229
|
-
private
|
230
|
-
|
231
|
-
def method_missing(method, *args, &block)
|
232
|
-
if matcher_execution_context.respond_to?(method)
|
233
|
-
matcher_execution_context.send method, *args, &block
|
234
|
-
else
|
235
|
-
super(method, *args, &block)
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
def include(*args)
|
240
|
-
singleton_class.__send__(:include, *args)
|
241
|
-
end
|
242
|
-
|
243
|
-
def define_method(name, &block)
|
244
|
-
singleton_class.__send__(:define_method, name, &block)
|
245
|
-
end
|
246
|
-
|
247
|
-
def making_declared_methods_public
|
248
|
-
# Our home-grown instance_exec in ruby 1.8.6 results in any methods
|
249
|
-
# declared in the block eval'd by instance_exec in the block to which we
|
250
|
-
# are yielding here are scoped private. This is NOT the case for Ruby
|
251
|
-
# 1.8.7 or 1.9.
|
252
|
-
#
|
253
|
-
# Also, due some crazy scoping that I don't understand, these methods
|
254
|
-
# are actually available in the specs (something about the matcher being
|
255
|
-
# defined in the scope of RSpec::Matchers or within an example), so not
|
256
|
-
# doing the following will not cause specs to fail, but they *will*
|
257
|
-
# cause features to fail and that will make users unhappy. So don't.
|
258
|
-
orig_private_methods = private_methods
|
259
|
-
yield
|
260
|
-
(private_methods - orig_private_methods).each {|m| singleton_class.__send__ :public, m}
|
261
|
-
end
|
262
|
-
|
263
|
-
def cache_or_call_cached(key, &block)
|
264
|
-
block ? cache(key, &block) : call_cached(key)
|
265
|
-
end
|
266
|
-
|
267
|
-
def cache(key, &block)
|
268
|
-
@messages[key] = block
|
269
|
-
end
|
270
|
-
|
271
|
-
def call_cached(key)
|
272
|
-
if @messages.has_key?(key)
|
273
|
-
@messages[key].arity == 1 ? @messages[key].call(@actual) : @messages[key].call
|
274
|
-
else
|
275
|
-
send("default_#{key}")
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
def default_description
|
280
|
-
"#{name_to_sentence}#{expected_to_sentence}"
|
281
|
-
end
|
282
|
-
|
283
|
-
def default_failure_message_for_should
|
284
|
-
"expected #{actual.inspect} to #{name_to_sentence}#{expected_to_sentence}"
|
285
|
-
end
|
286
|
-
|
287
|
-
def default_failure_message_for_should_not
|
288
|
-
"expected #{actual.inspect} not to #{name_to_sentence}#{expected_to_sentence}"
|
289
|
-
end
|
290
|
-
|
291
|
-
unless method_defined?(:singleton_class)
|
292
|
-
def singleton_class
|
293
|
-
class << self; self; end
|
294
|
-
end
|
295
|
-
end
|
296
|
-
end
|
297
|
-
end
|
298
|
-
end
|
299
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
module RSpec
|
2
|
-
module Matchers
|
3
|
-
|
4
|
-
private
|
5
|
-
|
6
|
-
def method_missing(method, *args, &block)
|
7
|
-
return Matchers::BuiltIn::BePredicate.new(method, *args, &block) if method.to_s =~ /^be_/
|
8
|
-
return Matchers::BuiltIn::Has.new(method, *args, &block) if method.to_s =~ /^have_/
|
9
|
-
super
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
@@ -1,84 +0,0 @@
|
|
1
|
-
module RSpec
|
2
|
-
module Matchers
|
3
|
-
class OperatorMatcher
|
4
|
-
class << self
|
5
|
-
def registry
|
6
|
-
@registry ||= {}
|
7
|
-
end
|
8
|
-
|
9
|
-
def register(klass, operator, matcher)
|
10
|
-
registry[klass] ||= {}
|
11
|
-
registry[klass][operator] = matcher
|
12
|
-
end
|
13
|
-
|
14
|
-
def get(klass, operator)
|
15
|
-
registry[klass] && registry[klass][operator]
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def initialize(actual)
|
20
|
-
@actual = actual
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.use_custom_matcher_or_delegate(operator)
|
24
|
-
define_method(operator) do |expected|
|
25
|
-
if matcher = OperatorMatcher.get(@actual.class, operator)
|
26
|
-
@actual.send(::RSpec::Matchers.last_should, matcher.new(expected))
|
27
|
-
else
|
28
|
-
eval_match(@actual, operator, expected)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
negative_operator = operator.sub(/^=/, '!')
|
33
|
-
if negative_operator != operator && respond_to?(negative_operator)
|
34
|
-
define_method(negative_operator) do |expected|
|
35
|
-
opposite_should = ::RSpec::Matchers.last_should == :should ? :should_not : :should
|
36
|
-
raise "RSpec does not support `#{::RSpec::Matchers.last_should} #{negative_operator} expected`. " +
|
37
|
-
"Use `#{opposite_should} #{operator} expected` instead."
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
['==', '===', '=~', '>', '>=', '<', '<='].each do |operator|
|
43
|
-
use_custom_matcher_or_delegate operator
|
44
|
-
end
|
45
|
-
|
46
|
-
def fail_with_message(message)
|
47
|
-
RSpec::Expectations.fail_with(message, @expected, @actual)
|
48
|
-
end
|
49
|
-
|
50
|
-
def description
|
51
|
-
"#{@operator} #{@expected.inspect}"
|
52
|
-
end
|
53
|
-
|
54
|
-
private
|
55
|
-
|
56
|
-
def eval_match(actual, operator, expected)
|
57
|
-
::RSpec::Matchers.last_matcher = self
|
58
|
-
@operator, @expected = operator, expected
|
59
|
-
__delegate_operator(actual, operator, expected)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
module BuiltIn
|
64
|
-
class PositiveOperatorMatcher < OperatorMatcher
|
65
|
-
def __delegate_operator(actual, operator, expected)
|
66
|
-
if actual.__send__(operator, expected)
|
67
|
-
true
|
68
|
-
elsif ['==','===', '=~'].include?(operator)
|
69
|
-
fail_with_message("expected: #{expected.inspect}\n got: #{actual.inspect} (using #{operator})")
|
70
|
-
else
|
71
|
-
fail_with_message("expected: #{operator} #{expected.inspect}\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
class NegativeOperatorMatcher < OperatorMatcher
|
77
|
-
def __delegate_operator(actual, operator, expected)
|
78
|
-
return false unless actual.__send__(operator, expected)
|
79
|
-
return fail_with_message("expected not: #{operator} #{expected.inspect}\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
@@ -1,60 +0,0 @@
|
|
1
|
-
module RSpec
|
2
|
-
module Matchers
|
3
|
-
module Pretty
|
4
|
-
def split_words(sym)
|
5
|
-
sym.to_s.gsub(/_/,' ')
|
6
|
-
end
|
7
|
-
|
8
|
-
def to_sentence(words)
|
9
|
-
return "" unless words
|
10
|
-
words = Array(words).map{|w| w.inspect}
|
11
|
-
case words.length
|
12
|
-
when 0
|
13
|
-
""
|
14
|
-
when 1
|
15
|
-
" #{words[0]}"
|
16
|
-
when 2
|
17
|
-
" #{words[0]} and #{words[1]}"
|
18
|
-
else
|
19
|
-
" #{words[0...-1].join(', ')}, and #{words[-1]}"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def _pretty_print(array)
|
24
|
-
result = ""
|
25
|
-
array.each_with_index do |item, index|
|
26
|
-
if index < (array.length - 2)
|
27
|
-
result << "#{item.inspect}, "
|
28
|
-
elsif index < (array.length - 1)
|
29
|
-
result << "#{item.inspect} and "
|
30
|
-
else
|
31
|
-
result << "#{item.inspect}"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
result
|
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
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
data/lib/rspec-expectations.rb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
require "rspec/expectations"
|
@@ -1,153 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'ostruct'
|
3
|
-
|
4
|
-
module RSpec
|
5
|
-
module Expectations
|
6
|
-
describe Differ do
|
7
|
-
let(:differ) { RSpec::Expectations::Differ.new }
|
8
|
-
|
9
|
-
describe '#diff_as_string' do
|
10
|
-
it "outputs unified diff of two strings" do
|
11
|
-
expected="foo\nbar\nzap\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nline\n"
|
12
|
-
actual="foo\nzap\nbar\nthis\nis\nsoo\nvery\nvery\nequal\ninsert\na\nanother\nline\n"
|
13
|
-
expected_diff= <<'EOD'
|
14
|
-
|
15
|
-
|
16
|
-
@@ -1,6 +1,6 @@
|
17
|
-
foo
|
18
|
-
-zap
|
19
|
-
bar
|
20
|
-
+zap
|
21
|
-
this
|
22
|
-
is
|
23
|
-
soo
|
24
|
-
@@ -9,6 +9,5 @@
|
25
|
-
equal
|
26
|
-
insert
|
27
|
-
a
|
28
|
-
-another
|
29
|
-
line
|
30
|
-
EOD
|
31
|
-
|
32
|
-
diff = differ.diff_as_string(expected, actual)
|
33
|
-
diff.should eql(expected_diff)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
describe '#diff_as_object' do
|
38
|
-
it "outputs unified diff message of two objects" do
|
39
|
-
animal_class = Class.new do
|
40
|
-
def initialize(name, species)
|
41
|
-
@name, @species = name, species
|
42
|
-
end
|
43
|
-
|
44
|
-
def inspect
|
45
|
-
<<-EOA
|
46
|
-
<Animal
|
47
|
-
name=#{@name},
|
48
|
-
species=#{@species}
|
49
|
-
>
|
50
|
-
EOA
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
expected = animal_class.new "bob", "giraffe"
|
55
|
-
actual = animal_class.new "bob", "tortoise"
|
56
|
-
|
57
|
-
expected_diff = <<'EOD'
|
58
|
-
|
59
|
-
@@ -1,5 +1,5 @@
|
60
|
-
<Animal
|
61
|
-
name=bob,
|
62
|
-
- species=tortoise
|
63
|
-
+ species=giraffe
|
64
|
-
>
|
65
|
-
EOD
|
66
|
-
|
67
|
-
diff = differ.diff_as_object(expected,actual)
|
68
|
-
diff.should == expected_diff
|
69
|
-
end
|
70
|
-
|
71
|
-
it "outputs a message if the diff is empty" do
|
72
|
-
diff = differ.diff_as_object('foo', 'foo')
|
73
|
-
diff.should eq(
|
74
|
-
"foo.==(foo) returned false even though the diff between " \
|
75
|
-
"foo and foo is empty. Check the implementation of foo.==."
|
76
|
-
)
|
77
|
-
end
|
78
|
-
|
79
|
-
it "outputs unified diff message of two arrays" do
|
80
|
-
expected = [ :foo, 'bar', :baz, 'quux', :metasyntactic, 'variable', :delta, 'charlie', :width, 'quite wide' ]
|
81
|
-
actual = [ :foo, 'bar', :baz, 'quux', :metasyntactic, 'variable', :delta, 'tango' , :width, 'very wide' ]
|
82
|
-
|
83
|
-
expected_diff = <<'EOD'
|
84
|
-
|
85
|
-
|
86
|
-
@@ -5,7 +5,7 @@
|
87
|
-
:metasyntactic,
|
88
|
-
"variable",
|
89
|
-
:delta,
|
90
|
-
- "tango",
|
91
|
-
+ "charlie",
|
92
|
-
:width,
|
93
|
-
- "very wide"]
|
94
|
-
+ "quite wide"]
|
95
|
-
EOD
|
96
|
-
|
97
|
-
diff = differ.diff_as_object(expected,actual)
|
98
|
-
diff.should == expected_diff
|
99
|
-
end
|
100
|
-
|
101
|
-
it "outputs unified diff message of two hashes" do
|
102
|
-
expected = { :foo => 'bar', :baz => 'quux', :metasyntactic => 'variable', :delta => 'charlie', :width =>'quite wide' }
|
103
|
-
actual = { :foo => 'bar', :metasyntactic => 'variable', :delta => 'charlotte', :width =>'quite wide' }
|
104
|
-
|
105
|
-
expected_diff = <<'EOD'
|
106
|
-
|
107
|
-
@@ -1,4 +1,5 @@
|
108
|
-
-:delta => "charlotte",
|
109
|
-
+:baz => "quux",
|
110
|
-
+:delta => "charlie",
|
111
|
-
:foo => "bar",
|
112
|
-
:metasyntactic => "variable",
|
113
|
-
:width => "quite wide"
|
114
|
-
EOD
|
115
|
-
|
116
|
-
diff = differ.diff_as_object(expected,actual)
|
117
|
-
diff.should == expected_diff
|
118
|
-
end
|
119
|
-
|
120
|
-
it "outputs unified diff of single line strings" do
|
121
|
-
expected = "this is one string"
|
122
|
-
actual = "this is another string"
|
123
|
-
|
124
|
-
expected_diff = <<'EOD'
|
125
|
-
|
126
|
-
@@ -1,2 +1,2 @@
|
127
|
-
-"this is another string"
|
128
|
-
+"this is one string"
|
129
|
-
EOD
|
130
|
-
|
131
|
-
diff = differ.diff_as_object(expected,actual)
|
132
|
-
diff.should == expected_diff
|
133
|
-
end
|
134
|
-
|
135
|
-
it "outputs unified diff of multi line strings" do
|
136
|
-
expected = "this is:\n one string"
|
137
|
-
actual = "this is:\n another string"
|
138
|
-
|
139
|
-
expected_diff = <<'EOD'
|
140
|
-
|
141
|
-
@@ -1,3 +1,3 @@
|
142
|
-
this is:
|
143
|
-
- another string
|
144
|
-
+ one string
|
145
|
-
EOD
|
146
|
-
|
147
|
-
diff = differ.diff_as_object(expected,actual)
|
148
|
-
diff.should == expected_diff
|
149
|
-
end
|
150
|
-
end
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
module RSpec
|
4
|
-
module Expectations
|
5
|
-
# so our examples below can set expectations about the target
|
6
|
-
ExpectationTarget.send(:attr_reader, :target)
|
7
|
-
|
8
|
-
describe ExpectationTarget do
|
9
|
-
context 'when constructed via #expect' do
|
10
|
-
it 'constructs a new instance targetting the given argument' do
|
11
|
-
expect(7).target.should eq(7)
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'constructs a new instance targetting the given block' do
|
15
|
-
block = lambda {}
|
16
|
-
expect(&block).target.should be(block)
|
17
|
-
end
|
18
|
-
|
19
|
-
it 'raises an ArgumentError when given an argument and a block' do
|
20
|
-
lambda { expect(7) { } }.should raise_error(ArgumentError)
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'raises an ArgumentError when given neither an argument nor a block' do
|
24
|
-
lambda { expect }.should raise_error(ArgumentError)
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'can be passed nil' do
|
28
|
-
expect(nil).target.should be_nil
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'passes a valid positive expectation' do
|
32
|
-
expect(5).to eq(5)
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'passes a valid negative expectation' do
|
36
|
-
expect(5).to_not eq(4)
|
37
|
-
expect(5).not_to eq(4)
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'fails an invalid positive expectation' do
|
41
|
-
lambda { expect(5).to eq(4) }.should fail_with(/expected: 4.*got: 5/m)
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'fails an invalid negative expectation' do
|
45
|
-
message = /expected 5 not to be a kind of Fixnum/
|
46
|
-
lambda { expect(5).to_not be_a(Fixnum) }.should fail_with(message)
|
47
|
-
lambda { expect(5).not_to be_a(Fixnum) }.should fail_with(message)
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'does not support operator matchers from #to' do
|
51
|
-
expect {
|
52
|
-
expect(3).to == 3
|
53
|
-
}.to raise_error(ArgumentError)
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'does not support operator matchers from #not_to' do
|
57
|
-
expect {
|
58
|
-
expect(3).not_to == 4
|
59
|
-
}.to raise_error(ArgumentError)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|