ae 1.7.4 → 1.8.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/.ruby +38 -39
- data/.yardopts +7 -0
- data/HISTORY.rdoc +31 -16
- data/NOTICE.rdoc +33 -15
- data/README.rdoc +14 -19
- data/lib/ae.rb +12 -33
- data/lib/ae.yml +38 -39
- data/lib/ae/adapters/minitest.rb +25 -15
- data/lib/ae/adapters/testunit.rb +1 -1
- data/lib/ae/assert.rb +20 -9
- data/lib/ae/assertion.rb +8 -5
- data/lib/ae/assertor.rb +127 -68
- data/lib/ae/basic_object.rb +0 -1
- data/lib/ae/check.rb +138 -10
- data/lib/ae/expect.rb +3 -6
- data/lib/ae/legacy.rb +84 -8
- data/lib/ae/must.rb +20 -12
- data/lib/ae/pry.rb +9 -8
- data/lib/ae/should.rb +14 -9
- data/lib/ae/subjunctive.rb +5 -6
- data/lib/ae/version.rb +3 -1
- data/qed/03_assert.rdoc +12 -6
- metadata +63 -69
- data/APACHE2.txt +0 -206
- data/lib/ae/ok.rb +0 -38
data/lib/ae/adapters/minitest.rb
CHANGED
@@ -4,33 +4,43 @@ AE.assertion_error = ::MiniTest::Assertion
|
|
4
4
|
|
5
5
|
module MiniTest #:nodoc:
|
6
6
|
class Unit #:nodoc:
|
7
|
+
|
7
8
|
# MiniTest tracks assertion counts internally in it's Unit class via the
|
8
9
|
# +assertion_count+ attribute. To work with AE we need add in AE's assertion
|
9
10
|
# total by overriding the +assertion_count+ method.
|
11
|
+
#
|
12
|
+
# @return [Integer] Number of assertions made.
|
10
13
|
def assertion_count
|
11
14
|
@assertion_count + AE::Assertor.counts[:total]
|
12
15
|
end
|
16
|
+
|
13
17
|
# To teach MiniTest to recognize AE's expanded concept of assertions
|
14
|
-
# we add in an extra capture clause to
|
15
|
-
|
16
|
-
|
18
|
+
# we add in an extra capture clause to it's #puke method.
|
19
|
+
#
|
20
|
+
# @return [String] Status code is `S`, `F`, or `E`.
|
21
|
+
def puke k, m, e
|
22
|
+
case e
|
17
23
|
when MiniTest::Skip
|
18
|
-
@skips
|
19
|
-
|
24
|
+
@skips += 1
|
25
|
+
return "S" unless @verbose
|
26
|
+
e = "Skipped:\n#{m}(#{k}) [#{location e}]:\n#{e.message}\n"
|
20
27
|
when MiniTest::Assertion
|
21
|
-
@failures
|
22
|
-
|
23
|
-
when x.respond_to?(:assertion?) && x.assertion?
|
24
|
-
@failures = @failures + 1
|
25
|
-
x = "Failure:\n#{m}(#{c}) [#{location x}]:\n#{x.message}\n"
|
28
|
+
@failures += 1
|
29
|
+
e = "Failure:\n#{m}(#{k}) [#{location e}]:\n#{e.message}\n"
|
26
30
|
else
|
27
|
-
|
28
|
-
|
29
|
-
|
31
|
+
if e.respond_to?(:assertion?) && e.assertion?
|
32
|
+
@failures += 1
|
33
|
+
e = "Failure:\n#{m}(#{c}) [#{location e}]:\n#{e.message}\n"
|
34
|
+
else
|
35
|
+
@errors += 1
|
36
|
+
b = MiniTest::filter_backtrace(e.backtrace).join "\n "
|
37
|
+
e = "Error:\n#{m}(#{k}):\n#{e.class}: #{e.message}\n #{b}\n"
|
38
|
+
end
|
30
39
|
end
|
31
|
-
@report <<
|
32
|
-
|
40
|
+
@report << e
|
41
|
+
e[0, 1]
|
33
42
|
end
|
43
|
+
|
34
44
|
end
|
35
45
|
end
|
36
46
|
|
data/lib/ae/adapters/testunit.rb
CHANGED
@@ -10,7 +10,7 @@ AE.assertion_error = ::Test::Unit::AssertionFailedError
|
|
10
10
|
# In addition we teach #run to recognize any Exception class that
|
11
11
|
# responds to #assertion? in the affirmative as an assertion
|
12
12
|
# rather than an error.
|
13
|
-
|
13
|
+
#
|
14
14
|
module Test #:nodoc:
|
15
15
|
module Unit #:nodoc:
|
16
16
|
class TestCase #:nodoc:
|
data/lib/ae/assert.rb
CHANGED
@@ -12,10 +12,10 @@ module AE
|
|
12
12
|
#
|
13
13
|
# 4.assert == 3
|
14
14
|
#
|
15
|
-
# If only a single test argument is given then
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
15
|
+
# If only a single test argument is given then #assert
|
16
|
+
# simply validates that it evalutate to true. An optional
|
17
|
+
# message argument can be given in this case which will
|
18
|
+
# be used instead of the deafult message.
|
19
19
|
#
|
20
20
|
# assert(4==3, "not the same thing")
|
21
21
|
#
|
@@ -24,11 +24,14 @@ module AE
|
|
24
24
|
#
|
25
25
|
# assert{ 4==3 }
|
26
26
|
#
|
27
|
+
# @return [Assertor] Assertion functor.
|
27
28
|
def assert(*args, &block)
|
28
29
|
Assertor.new(self, :backtrace=>caller).assert(*args, &block)
|
29
30
|
end
|
30
31
|
|
31
32
|
# Same as 'object.assert == other'.
|
33
|
+
#
|
34
|
+
# @return [Assertor] Assertion functor.
|
32
35
|
def assert=(cmp)
|
33
36
|
Assertor.new(self, :backtrace=>caller).assert == cmp
|
34
37
|
end
|
@@ -37,11 +40,14 @@ module AE
|
|
37
40
|
#
|
38
41
|
# 4.refute == 4 #=> Assertion Error
|
39
42
|
#
|
43
|
+
# @return [Assertor] Assertion functor.
|
40
44
|
def refute(*args, &block)
|
41
45
|
Assertor.new(self, :backtrace=>caller).not.assert(*args, &block)
|
42
46
|
end
|
43
47
|
|
44
48
|
# Same as 'object.refute == other'.
|
49
|
+
#
|
50
|
+
# @return [Assertor] Assertion functor.
|
45
51
|
def refute=(cmp)
|
46
52
|
Assertor.new(self, :backtrace=>caller).not.assert == cmp
|
47
53
|
end
|
@@ -57,6 +63,15 @@ module AE
|
|
57
63
|
alias_method :assert!, :refute
|
58
64
|
|
59
65
|
# Directly raise an Assertion failure.
|
66
|
+
#
|
67
|
+
# @param message [String]
|
68
|
+
# Error message.
|
69
|
+
#
|
70
|
+
# @param backtrace [String]
|
71
|
+
# Backtrace, used to pass up an error from lower in the stack.
|
72
|
+
#
|
73
|
+
# @raise [Assertion]
|
74
|
+
# Assertion error with given `message`.
|
60
75
|
def flunk(message=nil, backtrace=nil)
|
61
76
|
#Assertor.new(self, :backtrace=>caller).assert(false, message)
|
62
77
|
Assertor.assert(false, message, backtrace || caller)
|
@@ -66,8 +81,4 @@ module AE
|
|
66
81
|
|
67
82
|
end
|
68
83
|
|
69
|
-
|
70
|
-
include AE::Assert
|
71
|
-
end
|
72
|
-
|
73
|
-
# Copyright (c) 2008,2009 Thomas Sawyer
|
84
|
+
# Copyright (c) 2008 Thomas Sawyer
|
data/lib/ae/assertion.rb
CHANGED
@@ -13,15 +13,16 @@ module AE
|
|
13
13
|
#
|
14
14
|
class Assertion < Exception
|
15
15
|
|
16
|
-
#
|
16
|
+
# @deprecated
|
17
|
+
# This will be removed in favor of `AE::Assertor.counts`.
|
17
18
|
def self.counts
|
18
19
|
AE::Assertor.counts
|
19
20
|
end
|
20
21
|
|
21
22
|
# New assertion (failure).
|
22
23
|
#
|
23
|
-
# message
|
24
|
-
# options
|
24
|
+
# @param message [String] the failure message
|
25
|
+
# @param options [Hash] options such as :backtrace
|
25
26
|
#
|
26
27
|
def initialize(message=nil, options={})
|
27
28
|
super(message)
|
@@ -38,7 +39,9 @@ module AE
|
|
38
39
|
true
|
39
40
|
end
|
40
41
|
|
42
|
+
# Parents error message prefixed with "(assertion)".
|
41
43
|
#
|
44
|
+
# @return [String] error message
|
42
45
|
def to_s
|
43
46
|
'(assertion) ' + super
|
44
47
|
end
|
@@ -47,5 +50,5 @@ module AE
|
|
47
50
|
|
48
51
|
end
|
49
52
|
|
50
|
-
# Set top-level Assertion to AE::Assertion
|
51
|
-
Assertion = AE::Assertion
|
53
|
+
# Set top-level Assertion to AE::Assertion if not already present.
|
54
|
+
Assertion = AE::Assertion unless defined?(Assertion)
|
data/lib/ae/assertor.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'ae/assertion'
|
2
2
|
require 'ae/basic_object'
|
3
|
-
require 'ansi
|
3
|
+
require 'ae/ansi'
|
4
4
|
|
5
5
|
module AE
|
6
6
|
|
@@ -91,7 +91,6 @@ module AE
|
|
91
91
|
#def self.assay?
|
92
92
|
# @_assay ||= defined?(::Assay)
|
93
93
|
#end
|
94
|
-
|
95
94
|
#
|
96
95
|
#def self.message(sym, neg, *args, &blk)
|
97
96
|
# if method = Message.lookup(sym)
|
@@ -116,11 +115,10 @@ module AE
|
|
116
115
|
@negated = !!opts[:negated]
|
117
116
|
end
|
118
117
|
|
118
|
+
# TODO: Should #not return a new Assertor instead of in place negation?
|
119
|
+
|
119
120
|
# Negate the meaning of the assertion.
|
120
121
|
#
|
121
|
-
#--
|
122
|
-
# TODO: Should this return a new Assertor instead of in place negation?
|
123
|
-
#++
|
124
122
|
def not(msg=nil)
|
125
123
|
@negated = !@negated
|
126
124
|
@message = msg if msg
|
@@ -141,19 +139,15 @@ module AE
|
|
141
139
|
# assert something, parameter
|
142
140
|
#
|
143
141
|
# Returns +true+ or +false+ based on assertions success.
|
144
|
-
|
145
|
-
# The use of #to_proc and #matches? as sepcial cases is not
|
146
|
-
# a robust solution.
|
147
|
-
#++
|
142
|
+
#
|
148
143
|
def assert(*args, &block)
|
149
|
-
return self if args.empty?
|
144
|
+
return self if !block && args.empty?
|
150
145
|
|
151
|
-
target =
|
146
|
+
target = args.shift unless block
|
152
147
|
error = nil
|
153
148
|
|
154
|
-
#
|
155
|
-
if
|
156
|
-
block = target.to_proc
|
149
|
+
# Block
|
150
|
+
if block
|
157
151
|
match = args.shift
|
158
152
|
result = block.arity > 0 ? block.call(@delegate) : block.call
|
159
153
|
if match
|
@@ -164,14 +158,17 @@ module AE
|
|
164
158
|
error = @message || block.inspect # "#{result.inspect}"
|
165
159
|
end
|
166
160
|
|
167
|
-
#
|
168
|
-
elsif
|
169
|
-
pass
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
161
|
+
# Proc-style
|
162
|
+
elsif proc_assertion?(target)
|
163
|
+
pass, error = proc_apply(target)
|
164
|
+
|
165
|
+
# Assay-style assertions
|
166
|
+
#elsif assay_assertion?(target)
|
167
|
+
# pass, error = assay_assertion_apply(target)
|
168
|
+
|
169
|
+
# RSpec-style matchers
|
170
|
+
elsif rspec_matcher?(target)
|
171
|
+
pass, error = rspec_matcher_apply(target)
|
175
172
|
|
176
173
|
# Truthiness
|
177
174
|
else
|
@@ -182,23 +179,20 @@ module AE
|
|
182
179
|
__assert__(pass, error)
|
183
180
|
end
|
184
181
|
|
182
|
+
# TODO: Should we deprecate the receiver matches in favor of #expected ?
|
183
|
+
# In other words, should <code>|| @delegate</code> be dropped?
|
184
|
+
|
185
185
|
# Internal expect, provides all functionality associated
|
186
186
|
# with external #expect method. (See Expect#expect)
|
187
187
|
#
|
188
|
-
#--
|
189
|
-
# TODO: Should we deprecate the receiver matches in favor of #expected ?
|
190
|
-
# In other words, should the <code>|| @delegate</code> be dropped?
|
191
|
-
#++
|
192
188
|
def expect(*args, &block)
|
193
|
-
return self if args.empty?
|
189
|
+
return self if !block && args.empty? # same as #assert
|
194
190
|
|
195
|
-
|
196
|
-
error
|
191
|
+
pass = false
|
192
|
+
error = nil
|
197
193
|
|
198
|
-
|
199
|
-
|
200
|
-
#block = target.to_proc
|
201
|
-
match = args.shift || @delegate
|
194
|
+
if block
|
195
|
+
match = args.shift || @delegate # TODO: see above
|
202
196
|
if exception?(match)
|
203
197
|
$DEBUG, debug = false, $DEBUG # b/c it always spits-out a NameError
|
204
198
|
begin
|
@@ -220,19 +214,20 @@ module AE
|
|
220
214
|
error = @message || "#{match.inspect} === #{result.inspect}"
|
221
215
|
end
|
222
216
|
|
223
|
-
|
224
|
-
elsif target.respond_to?(:matches?)
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
217
|
+
## Matcher
|
218
|
+
#elsif target.respond_to?(:matches?)
|
219
|
+
# pass = target.matches?(@delegate)
|
220
|
+
# error = @message || matcher_message(target) #|| target.inspect
|
221
|
+
# if target.respond_to?(:exception)
|
222
|
+
# #error_class = target.failure_class
|
223
|
+
# error = target.exception #failure(:backtrace=>@backtrace, :negated=>@negated)
|
224
|
+
# end
|
231
225
|
|
232
|
-
# Case
|
226
|
+
# Case Equality
|
233
227
|
else
|
234
|
-
|
235
|
-
|
228
|
+
target = args.shift
|
229
|
+
pass = (target === @delegate)
|
230
|
+
error = @message || "#{target.inspect} === #{@delegate.inspect}"
|
236
231
|
end
|
237
232
|
|
238
233
|
__assert__(pass, error)
|
@@ -260,20 +255,94 @@ module AE
|
|
260
255
|
@delegate.inspect
|
261
256
|
end
|
262
257
|
|
263
|
-
|
258
|
+
private
|
259
|
+
|
260
|
+
# AE-STYLE ASSERTIONS
|
261
|
+
|
262
|
+
#
|
263
|
+
def proc_assertion?(target)
|
264
|
+
::Proc === target || target.respond_to?(:call) || target.respond_to?(:to_proc)
|
265
|
+
end
|
266
|
+
|
267
|
+
#
|
268
|
+
def proc_apply(target)
|
269
|
+
call = target.method(:call) rescue target.to_proc
|
270
|
+
pass = call.arity != 0 ? call.call(@delegate) : call.call
|
271
|
+
error = @message || (
|
272
|
+
to_s = target.method(:to_s)
|
273
|
+
to_s.arity == 0 ? to_s.call : to_s.call(@negated)
|
274
|
+
)
|
275
|
+
return pass, error
|
276
|
+
end
|
277
|
+
|
278
|
+
# ASSAY-STYLE ASSERTIONS
|
279
|
+
# (not yet supported b/c api is not 100%)
|
280
|
+
|
281
|
+
# Is the `assertion` object an assay-style assertion?
|
282
|
+
def assay_assertion?(assertion)
|
283
|
+
assertion.respond_to?(:exception) && assertion.respond_to?(:pass?)
|
284
|
+
end
|
285
|
+
|
286
|
+
#
|
287
|
+
def assay_assertion_apply(assay)
|
288
|
+
if @negated
|
289
|
+
pass = assay.fail?(@delegate)
|
290
|
+
error = assay #.exception(@message || )
|
291
|
+
else
|
292
|
+
pass = assay.pass?(@delegate)
|
293
|
+
error = assay #.exception(@message || )
|
294
|
+
end
|
295
|
+
return pass, error
|
296
|
+
end
|
297
|
+
|
298
|
+
# RSPEC-STYLE MATCHERS
|
299
|
+
|
300
|
+
# Is `target` an Rspec-style Matcher?
|
301
|
+
def rspec_matcher?(target)
|
302
|
+
target.respond_to?(:matches?)
|
303
|
+
end
|
304
|
+
|
305
|
+
#
|
306
|
+
def rspec_matcher_apply(matcher)
|
307
|
+
pass = matcher.matches?(@delegate)
|
308
|
+
error = @message || rspec_matcher_message(matcher)
|
309
|
+
return pass, error
|
310
|
+
end
|
311
|
+
|
312
|
+
# TODO: Is there anything to be done with matcher.description?
|
313
|
+
|
314
|
+
#
|
315
|
+
def rspec_matcher_message(matcher)
|
316
|
+
if @negated
|
317
|
+
if matcher.respond_to?(:failure_message_for_should_not)
|
318
|
+
return matcher.failure_message_for_should_not
|
319
|
+
end
|
320
|
+
if matcher.respond_to?(:negative_failure_message)
|
321
|
+
return matcher.negative_failure_message
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
if matcher.respond_to?(:failure_message_for_should)
|
326
|
+
return matcher.failure_message_for_should
|
327
|
+
end
|
328
|
+
if matcher.respond_to?(:failure_message)
|
329
|
+
return matcher.failure_message
|
330
|
+
end
|
331
|
+
|
332
|
+
return matcher.to_s # TODO: or just `nil` ?
|
333
|
+
end
|
264
334
|
|
265
|
-
# Is the +object+ an Exception or an instance of one?
|
266
|
-
#--
|
267
335
|
# TODO: Should we use a more libreral determination of exception.
|
268
336
|
# e.g. <code>respond_to?(:exception)</code>.
|
269
|
-
|
337
|
+
|
338
|
+
# Is the +object+ an Exception or an instance of one?
|
270
339
|
def exception?(object)
|
271
340
|
::Exception === object or ::Class === object and object.ancestors.include?(::Exception)
|
272
341
|
end
|
273
342
|
|
274
|
-
# Converts a missing method into an Assertion.
|
275
|
-
#
|
276
343
|
# TODO: In future should probably be `@delegate.public_send(sym, *a, &b)`.
|
344
|
+
|
345
|
+
# Converts a missing method into an Assertion.
|
277
346
|
def method_missing(sym, *args, &block)
|
278
347
|
error = @message || compare_message(sym, *args, &block) || generic_message(sym, *args, &block)
|
279
348
|
|
@@ -282,29 +351,14 @@ module AE
|
|
282
351
|
__assert__(pass, error)
|
283
352
|
end
|
284
353
|
|
354
|
+
# TODO: Can the handling of the message be simplified/improved?
|
285
355
|
|
286
356
|
# Simple assert.
|
287
|
-
#--
|
288
|
-
# TODO: Can the handling of the message be simplified/improved?
|
289
|
-
#++
|
290
357
|
def __assert__(pass, error=nil)
|
291
358
|
Assertor.assert(pass, error, @negated, @backtrace)
|
292
359
|
end
|
293
360
|
|
294
361
|
#
|
295
|
-
def matcher_message(matcher)
|
296
|
-
if @negated
|
297
|
-
if matcher.respond_to?(:negative_failure_message)
|
298
|
-
return matcher.failure_message
|
299
|
-
end
|
300
|
-
else
|
301
|
-
if matcher.respond_to?(:failure_message)
|
302
|
-
return matcher.failure_message
|
303
|
-
end
|
304
|
-
end
|
305
|
-
return nil
|
306
|
-
end
|
307
|
-
|
308
362
|
COMPARISON_OPERATORS = { :"==" => :"!=" }
|
309
363
|
|
310
364
|
# Message to use when making a comparion assertion.
|
@@ -314,7 +368,9 @@ module AE
|
|
314
368
|
# terminals) you can either set `AE.ansi = false` or use the
|
315
369
|
# ANSI library's master switch to deactive all ANSI codes,
|
316
370
|
# which can be set in your test helper.
|
317
|
-
#
|
371
|
+
#
|
372
|
+
# @param operator [Symbol] operator/method
|
373
|
+
#
|
318
374
|
# @see http://rubyworks.github.com/ansi
|
319
375
|
def compare_message(operator, *args, &blk)
|
320
376
|
return nil unless COMPARISON_OPERATORS.key?(operator)
|
@@ -342,6 +398,9 @@ module AE
|
|
342
398
|
|
343
399
|
# Puts together a suitable error message.
|
344
400
|
#
|
401
|
+
# @param op [Symbol] operator/method
|
402
|
+
#
|
403
|
+
# @return [String] message
|
345
404
|
def generic_message(op, *a, &b)
|
346
405
|
inspection = @delegate.send(:inspect)
|
347
406
|
if @negated
|
@@ -366,4 +425,4 @@ end
|
|
366
425
|
# end
|
367
426
|
#end
|
368
427
|
|
369
|
-
# Copyright (c) 2008
|
428
|
+
# Copyright (c) 2008 Thomas Sawyer
|