rspec-expectations 2.11.3 → 3.11.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.
- 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
|
-
|