ae 1.7.4 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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