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.
@@ -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 the it's #puke method.
15
- def puke c, m, x
16
- case x
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 = @skips + 1
19
- x = "Skipped:\n#{m}(#{c}) [#{location x}]:\n#{x.message}\n"
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 = @failures + 1
22
- x = "Failure:\n#{m}(#{c}) [#{location x}]:\n#{x.message}\n"
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
- @errors = @errors + 1
28
- b = MiniTest::filter_backtrace(x.backtrace).join("\n ")
29
- x = "Error:\n#{m}(#{c}):\n#{x.class}: #{x.message}\n #{b}\n"
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 << x
32
- x[0, 1]
40
+ @report << e
41
+ e[0, 1]
33
42
  end
43
+
34
44
  end
35
45
  end
36
46
 
@@ -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:
@@ -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
- # #assert simple validates that it evalutate to true.
17
- # An optional message argument can be given in this
18
- # case which will be used instead of the deafult message.
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
- class ::Object #:nodoc:
70
- include AE::Assert
71
- end
72
-
73
- # Copyright (c) 2008,2009 Thomas Sawyer
84
+ # Copyright (c) 2008 Thomas Sawyer
@@ -13,15 +13,16 @@ module AE
13
13
  #
14
14
  class Assertion < Exception
15
15
 
16
- # DEPRECATE: This will be removed in favor of Assertor#counts.
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 - the failure message
24
- # options - such as :backtrace
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)
@@ -1,6 +1,6 @@
1
1
  require 'ae/assertion'
2
2
  require 'ae/basic_object'
3
- require 'ansi/diff'
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? && !block
144
+ return self if !block && args.empty?
150
145
 
151
- target = block || args.shift
146
+ target = args.shift unless block
152
147
  error = nil
153
148
 
154
- # Lambda
155
- if ::Proc === target || target.respond_to?(:to_proc)
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
- # Matcher
168
- elsif target.respond_to?(:matches?) # Matchers
169
- pass = target.matches?(@delegate)
170
- error = @message || matcher_message(target) #|| target.inspect
171
- if target.respond_to?(:exception)
172
- #error_class = target.failure_class
173
- error = target.exception #(:backtrace=>@backtrace, :negated=>@negated)
174
- end
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? && !block # same as #assert
189
+ return self if !block && args.empty? # same as #assert
194
190
 
195
- target = block || args.shift
196
- error = nil
191
+ pass = false
192
+ error = nil
197
193
 
198
- # Lambda
199
- if ::Proc === target #|| target.respond_to?(:to_proc)
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
- # Matcher
224
- elsif target.respond_to?(:matches?)
225
- pass = target.matches?(@delegate)
226
- error = @message || matcher_message(target) #|| target.inspect
227
- if target.respond_to?(:exception)
228
- #error_class = target.failure_class
229
- error = target.exception #failure(:backtrace=>@backtrace, :negated=>@negated)
230
- end
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 Equals
226
+ # Case Equality
233
227
  else
234
- pass = (target === @delegate)
235
- error = @message || "#{target.inspect} === #{@delegate.inspect}"
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
- private
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,2009 Thomas Sawyer
428
+ # Copyright (c) 2008 Thomas Sawyer