Class: AE::Assertor
- Inherits:
- BasicObject
- Includes:
- Subjunctive
- Defined in:
- lib/ae/assertor.rb,
lib/ae/subjunctive.rb,
lib/ae/adapters/minitest.rb,
lib/ae/adapters/testunit.rb
Overview
:nodoc:
Constant Summary collapse
- ZERO_COUNTS =
Initial settings of assertion counts.
{:total=>0,:pass=>0,:fail=>0}
Class Method Summary collapse
-
.assert(pass, error = nil, negated = nil, backtrace = nil) ⇒ Object
Basic assertion.
-
.assertion_error ⇒ Object
Returns the Exception class to be raised when an assertion fails.
- .const_missing(const) ⇒ Object
-
.counts ⇒ Object
Returns Hash used to track assertion counts.
-
.increment_counts(pass) ⇒ Object
MiniTest tracks assertion counts internally.
-
.raise_assertion(error, negated, backtrace = nil) ⇒ Object
The intent of the method is to raise an assertion failure class that the test framework supports.
-
.recount(reset = nil) ⇒ Object
Reset assertion counts.
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.
-
#expect(*args, &block) ⇒ Object
Internal expect, provides all functionality associated with external #expect method.
- #flunk(message = nil, backtrace = nil) ⇒ Object
-
#initialize(delegate, opts = {}) ⇒ Assertor
constructor
New Assertor.
- #inspect ⇒ Object
-
#not(msg = nil) ⇒ Object
Negate the meaning of the assertion.
- #send(op, *a, &b) ⇒ Object
Methods included from Subjunctive
Methods inherited from BasicObject
find_hidden_method, hide, reveal
Constructor Details
#initialize(delegate, opts = {}) ⇒ Assertor
New Assertor.
111 112 113 114 115 116 |
# File 'lib/ae/assertor.rb', line 111 def initialize(delegate, opts={}) #, backtrace) @delegate = delegate = 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, *args, &block) ⇒ Object (private)
Converts a missing method into an Assertion.
346 347 348 349 350 351 352 |
# File 'lib/ae/assertor.rb', line 346 def method_missing(sym, *args, &block) error = || (sym, *args, &block) || (sym, *args, &block) pass = @delegate.__send__(sym, *args, &block) __assert__(pass, error) end |
Class Method Details
.assert(pass, error = nil, negated = nil, backtrace = nil) ⇒ Object
Basic assertion. This method by-passes all the Assertor fluent constructs and performs the underlying assertion procedure. It is used by Assertor as the end call of an assertion.
62 63 64 65 66 67 68 69 70 |
# File 'lib/ae/assertor.rb', line 62 def self.assert(pass, error=nil, negated=nil, backtrace=nil) pass = negated ^ !!pass increment_counts(pass) if !pass backtrace = backtrace || caller raise_assertion(error, negated, backtrace) end return pass end |
.assertion_error ⇒ Object
Returns the Exception class to be raised when an assertion fails.
85 86 87 |
# File 'lib/ae/assertor.rb', line 85 def self.assertion_error ::Assertion end |
.const_missing(const) ⇒ Object
415 416 417 |
# File 'lib/ae/assertor.rb', line 415 def self.const_missing(const) ::Object.const_get(const) end |
.counts ⇒ Object
Returns Hash used to track assertion counts.
25 26 27 |
# File 'lib/ae/assertor.rb', line 25 def self.counts $ASSERTION_COUNTS end |
.increment_counts(pass) ⇒ Object
MiniTest tracks assertion counts internally. To work with AE we override increment_counts to also update AE's own counter.
49 50 51 52 53 54 55 56 57 |
# File 'lib/ae/assertor.rb', line 49 def self.increment_counts(pass) counts[:total] += 1 if pass counts[:pass] += 1 else counts[:fail] += 1 end return counts end |
.raise_assertion(error, negated, backtrace = nil) ⇒ Object
The intent of the method is to raise an assertion failure class that the test framework supports.
74 75 76 77 78 79 80 81 82 |
# File 'lib/ae/assertor.rb', line 74 def self.raise_assertion(error, negated, backtrace=nil) if not ::Exception === error error = assertion_error.new(error) end error.set_negative(negated) error.set_backtrace(backtrace || caller) error.set_assertion(true) fail error end |
.recount(reset = nil) ⇒ Object
Reset assertion counts.
reset - Hash which can be used to set counts manually (optional).
Returns the Hash of previous counts.
34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/ae/assertor.rb', line 34 def self.recount(reset=nil) old_counts = counts.dup if reset reset.each do |type, value| counts[type.to_sym] = value end else counts.replace(ZERO_COUNTS.dup) end return old_counts 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.
244 245 246 |
# File 'lib/ae/assertor.rb', line 244 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
Returns true or false based on assertions success.
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/ae/assertor.rb', line 143 def assert(*args, &block) return self if !block && args.empty? target = args.shift unless block error = nil # Block if block match = args.shift result = block.arity > 0 ? block.call(@delegate) : block.call if match pass = (match == result) error = || "#{match.inspect} == #{result.inspect}" else pass = result error = || block.inspect # "#{result.inspect}" end # Proc-style elsif proc_assertion?(target) pass, error = proc_apply(target) # Assay-style assertions #elsif assay_assertion?(target) # pass, error = assay_assertion_apply(target) # RSpec-style matchers elsif rspec_matcher?(target) pass, error = rspec_matcher_apply(target) # Truthiness else pass = target # truthiness error = args.shift # optional message for TestUnit compatiability end __assert__(pass, error) end |
#expect(*args, &block) ⇒ Object
Internal expect, provides all functionality associated with external #expect method. (See Expect#expect)
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/ae/assertor.rb', line 188 def expect(*args, &block) return self if !block && args.empty? # same as #assert pass = false error = nil if block match = args.shift || @delegate # TODO: see above 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 error = "#{match} not raised" rescue match => error pass = true error = "#{match} raised" rescue ::Exception => error pass = false error = "#{match} expected but #{error.class} was raised" ensure $DEBUG = debug end else result = block.arity > 0 ? block.call(@delegte) : block.call pass = (match === result) error = || "#{match.inspect} === #{result.inspect}" end ## Matcher #elsif target.respond_to?(:matches?) # pass = target.matches?(@delegate) # error = @message || matcher_message(target) #|| target.inspect # if target.respond_to?(:exception) # #error_class = target.failure_class # error = target.exception #failure(:backtrace=>@backtrace, :negated=>@negated) # end # Case Equality else target = args.shift pass = (target === @delegate) error = || "#{target.inspect} === #{@delegate.inspect}" end __assert__(pass, error) end |
#flunk(message = nil, backtrace = nil) ⇒ Object
237 238 239 |
# File 'lib/ae/assertor.rb', line 237 def flunk(=nil, backtrace=nil) __assert__(false, || ) end |
#inspect ⇒ Object
254 255 256 |
# File 'lib/ae/assertor.rb', line 254 def inspect @delegate.inspect end |
#not(msg = nil) ⇒ Object
Negate the meaning of the assertion.
122 123 124 125 126 |
# File 'lib/ae/assertor.rb', line 122 def not(msg=nil) @negated = !@negated = msg if msg self end |
#send(op, *a, &b) ⇒ Object
249 250 251 |
# File 'lib/ae/assertor.rb', line 249 def send(op, *a, &b) method_missing(op, *a, &b) end |