Class: Assertor
- Inherits:
- AE::BasicObject
- Includes:
- AE::Subjunctive
- Defined in:
- lib/ae/assertor.rb,
lib/ae/subjunctive.rb
Overview
module AE
Instance Method Summary collapse
-
#=~(match) ⇒ Object
Ruby seems to have a quark in it’s implementation whereby this must be defined explicitly, otherwise it somehow skips #method_missing.
-
#assert(*args, &block) ⇒ Object
Internal assert, provides all functionality associated with external #assert method.
-
#exception?(object) ⇒ Boolean
Is the
object
and Exception or an instance of one. -
#expect(*args, &block) ⇒ Object
Internal expect, provides all functionality associated with external #expect method.
- #flunk(message = nil) ⇒ Object
-
#initialize(delegate, opts = {}) ⇒ Assertor
constructor
New Assertor.
-
#not(msg = nil) ⇒ Object
Negate the meaning of the assertion.
- #send(op, *a, &b) ⇒ Object
Methods included from AE::Subjunctive
Methods inherited from AE::BasicObject
find_hidden_method, hide, reveal
Constructor Details
#initialize(delegate, opts = {}) ⇒ Assertor
New Assertor.
25 26 27 28 29 30 |
# File 'lib/ae/assertor.rb', line 25 def initialize(delegate, opts={}) #, backtrace) @delegate = delegate @message = opts[:message] @backtrace = opts[:backtrace] || caller #[1..-1] @negated = !!opts[:negated] end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(sym, *a, &b) ⇒ Object (private)
Converts a missing methods into an Assertion.
157 158 159 160 161 |
# File 'lib/ae/assertor.rb', line 157 def method_missing(sym, *a, &b) pass = @delegate.__send__(sym, *a, &b) #pass = @delegate.public_send(sym, *a, &b) __assert__(pass, @message || __msg__(sym, *a, &b)) end |
Instance Method Details
#=~(match) ⇒ Object
Ruby seems to have a quark in it’s implementation whereby this must be defined explicitly, otherwise it somehow skips #method_missing.
144 145 146 |
# File 'lib/ae/assertor.rb', line 144 def =~(match) method_missing(:"=~", match) end |
#assert(*args, &block) ⇒ Object
Internal assert, provides all functionality associated with external #assert method. (See Assert#assert)
NOTE: I’m calling YAGNI on using extra arguments to pass to the block. The interface is much nicer if a macro is created to handle any neccessry arguments. Eg.
assert something(parameter)
instead of
assert something, parameter
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/ae/assertor.rb', line 54 def assert(*args, &block) return self if args.empty? && !block target = block || args.shift if ::Proc === target || target.respond_to?(:to_proc) block = target.to_proc match = args.shift result = block.arity > 0 ? block.call(@delegate) : block.call if match pass = (match == result) msg = @message || "#{match.inspect} == #{result.inspect}" else pass = result msg = @message || block.inspect # "#{result.inspect}" end elsif target.respond_to?(:matches?) pass = target.matches?(@delegate) msg = @message || (target) || target.inspect else pass = target # truthiness msg = args.shift # optional mesage for TestUnit compatiability end __assert__(pass, msg) end |
#exception?(object) ⇒ Boolean
Is the object
and Exception or an instance of one. – TODO: Should we use a more libreral determination of exception. e.g. respond_to?(:exception)
. ++
132 133 134 |
# File 'lib/ae/assertor.rb', line 132 def exception?(object) ::Exception === object or ::Class === object and object.ancestors.include?(::Exception) end |
#expect(*args, &block) ⇒ Object
Internal expect, provides all functionality associated with external #expect method. (See Expect#expect)
– TODO: Should we deprecate the receiver matches in favor of #expected ? In other words, should the || @delegate
be dropped? ++
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/ae/assertor.rb', line 88 def expect(*args, &block) return self if args.empty? && !block_given? # same as #assert target = block || args.shift if ::Proc === target #|| target.respond_to?(:to_proc) #block = target.to_proc match = args.shift || @delegate if exception?(match) $DEBUG, debug = false, $DEBUG # b/c it always spits-out a NameError begin block.arity > 0 ? block.call(@delegate) : block.call pass = false msg = "#{match} not raised" rescue match => error pass = true msg = "#{match} raised" rescue ::Exception => error pass = false msg = "#{match} expected but #{error.class} was raised" ensure $DEBUG = debug end else result = block.arity > 0 ? block.call(@delegte) : block.call pass = (match === result) msg = @message || "#{match.inspect} === #{result.inspect}" end elsif target.respond_to?(:matches?) pass = target.matches?(@delegate) msg = @message || (target) || target.inspect else pass = (target === @delegate) msg = @message || "#{target.inspect} === #{@delegate.inspect}" end __assert__(pass, msg) end |
#flunk(message = nil) ⇒ Object
137 138 139 |
# File 'lib/ae/assertor.rb', line 137 def flunk(=nil) __assert__(false, || @message) end |
#not(msg = nil) ⇒ Object
Negate the meaning of the assertion.
TODO: Should this return a new Assertor instead of inplace negation?
35 36 37 38 39 |
# File 'lib/ae/assertor.rb', line 35 def not(msg=nil) @negated = !@negated @message = msg if msg self end |
#send(op, *a, &b) ⇒ Object
149 150 151 |
# File 'lib/ae/assertor.rb', line 149 def send(op, *a, &b) method_missing(op, *a, &b) end |