lib/ae/assertor.rb in ae-1.2.3 vs lib/ae/assertor.rb in ae-1.3.0

- old
+ new

@@ -25,47 +25,106 @@ @message = opts[:message] @backtrace = opts[:backtrace] || caller #[1..-1] @negated = !!opts[:negated] end + # Negate the meaning of the assertion. # - def not(msg=nil, &block) + # TODO: Should this return a new Assertor instead of inplace negation? + def not(msg=nil) @negated = !@negated - block ? assert(msg, &block) : self + @message = msg if msg + self end # Internal assert, provides all functionality associated - # with external #assert Object method. + # with external #assert method. (See Assert#assert) # - # TODO: I'm calling YAGNI on any extra arguments to the block. + # 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 + # def assert(*args, &block) return self if args.empty? && !block_given? - block = args.shift if !block_given? && Proc === args.first - if block - pass = block.arity > 0 ? block.call(@delegate) : block.call #@delegate.instance_eval(&block) - msg = args.shift || @message || block.inspect + + 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 || matcher_message(target) || target.inspect else - pass = args.shift # truthiness - msg = args.shift + pass = target # truthiness + msg = args.shift # optional mesage for TestUnit compatiability end + __assert__(pass, msg) end + # Internal expect, provides all functionality associated + # with external #expect method. (See Expect#expect) # - #def expect(*args, &block) - # return self if args.empty? && !block_given? - # block = args.shift if !block_given? && Proc === args.first - # if block - # pass = block.arity > 0 ? block.call(@delegate) : block.call #@delegate.instance_eval(&block) - # msg = args.shift || @message || block.inspect - # else - # pass = args.shift # truthiness - # msg = args.shift - # end - # __assert__(pass, msg) - #end + #-- + # TODO: Should we deprecate the receiver matches in favor of #expected ? + # In other words, should the <code>|| @delegate</code> be dropped? + # + # TODO: respond_to?(:exception) && match = exception if Exception === match + #++ + def expect(*args, &block) + # same as #assert if no arguments of block given + return self if args.empty? && !block_given? + target = block || args.shift + + if Proc === target || target.respond_to?(:to_proc) + block = target.to_proc + match = args.shift || @delegate + if Exception === match || (Class===match && match.ancestors.include?(Exception)) + 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" + 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 || matcher_message(target) || target.inspect + else + pass = (target === @delegate) + msg = @message || "#{target.inspect} === #{@delegate.inspect}" + end + + #flunk(msg, caller) unless pass + __assert__(pass, msg) + end + # def flunk(msg=nil) $failures += 1 fail Assertion.new(msg || @message, :backtrace=>@backtrace) end @@ -108,9 +167,22 @@ $assertions += 1 unless @negated ^ pass flunk(msg || @message) #raise Assertion.new(msg, :backtrace=>@backtrace) end @negated ? !pass : !!pass + end + + # + def matcher_message(matcher) + if @negated + if matcher.respond_to?(:negative_failure_message) + return matcher.failure_message + end + end + if matcher.respond_to?(:failure_message) + return matcher.failure_message + end + false end # TODO: Ultimately better messages might be nice. # #def self.message(op,&block)