lib/assay/assertion.rb in assay-0.3.0 vs lib/assay/assertion.rb in assay-0.4.0

- old
+ new

@@ -1,149 +1,123 @@ -require 'ansi/diff' -require 'assay/matcher' +require 'brass' -module Assay +require_relative 'core_ext/na' +require_relative 'core_ext/kernel' - # - class Assertion < Exception +require_relative 'assertor' +require_relative 'assertable' - # When displaying errors, use this as a rule of thumb - # for determining when the inspected object will be too - # big for a single line message. - SIZE_LIMIT = 13 +# TODO: Don't care for Proc === subject conditional code, but not +# sure how else to deal with lambda subjects. - # Returns Matcher for the failure class. - def self.to_matcher(*args, &blk) - Matcher.new(self, *args, &blk) - end +# Base class for all Assay classes. This class defines all the logic +# for assertions as exception classes as well as test assertion matchers. +# +class Assertion < Exception - # - def self.assertable_method - "assert_#{assertion_name}" - end + extend Assay::Assertable - # - def self.assert(*args, &blk) - opts = Hash === args.last ? args.pop : {} + # + # When displaying errors, use this as a rule of thumb + # for determining when the inspected object will be too + # big for a single line message. + # + SIZE_LIMIT = 13 - backtrace = opts[:backtrace] || caller - message = opts[:message] - - err = new(message, *args, &blk) - err.set_backtrace(backtrace) - err.assert - - #chk = check(*args, &blk) - #msg = fail_message(*args, &blk) - #if !chk - # msg = opts[:message] - # btr = opts[:backtrace] || caller - # err = new(msg, *args) - # err.set_backtrace(btr) - # fail err - #end + # + # Each new subclass must call the +register+ method. This is not an option! + # The method must be called in order to add the class to the Assertion + # name and operator indicies, so they might be looked-up efficiently by + # other libraries. + # + def self.register(op, name=nil) + case op.to_s + when /\W/ + @operator = op.to_sym + @assertive_name = name.to_sym if name + else + @operator = (op.to_s + '?').to_sym + @assertive_name = op.to_sym end - # - def self.refute(*args, &blk) - opts = Hash === args.last ? args.pop : {} + operator_index[operator] = self + name_index[assertive_name] = self + end - backtrace = opts[:backtrace] || caller - message = opts[:message] + # + # When Assertion is inherited, a list of all Assertion subclasses is kept. + # This can be used to assertions frameworks with dynamic implementations. + # + def self.inherited(base) + @@by_operator = nil + @@by_name = nil + subclasses << base + end - err = new(message, *args, &blk) - err.set_backtrace(backtrace) - err.refute + # + # List of all subclasses of Assertion. + # + def self.subclasses + @@subclasses ||= [] + end - #opts = Hash === args.last ? args.pop : {} - #chk = check!(*args, &blk) - ##msg = fail_message!(*args, &blk) - #if !chk - # msg = opts[:message] - # btr = opts[:backtrace] || caller - # err = new(msg, :backtrace=>btr, :arguments=>args) - # fail err - #end - end + # + # If operator is not given, returns a hash table of assertion classes + # indexed by operator. + # + def self.by_operator(operator=nil) + return operator_index.dup unless operator + operator_index[operator.to_sym] + end - # - def self.pass?(*args, &blk) - raise NotImplementedError - end + # + # If operator is not given, returns a hash table of assertion classes + # indexed by assertive name. + # + def self.by_name(name=nil) + return name_index.dup unless name + name_index[name.to_sym] + end - # - def self.fail?(*args, &blk) - ! pass?(*args, &blk) - end + private - # - def initialize(message=nil, *arguments, &block) - message ? super(message % arguments) : super() - - @mesg = message # why isn't this in @mesg from super()? - @arguments = arguments - @block = block - - #set_arguments options[:arguments] if options[:arguments] - #set_negative options[:negated] if options[:negated] - #set_backtrace options[:backtrace] if options[:backtrace] + def self.operator_index + @@operator_index ||= {} end - # Failure is always a type of assertion. - # - # This method allows Assay's classes to work in any test framework - # that supports this interface. - def assertion? - true # @assertion = true if @assertion.nil? + def self.name_index + @@name_index ||= {} end - # - def pass? - self.class.pass?(*@arguments, &@block) #^ @negative - end + # + # Setup new Assertion object. + # + def initialize(msg=nil) #, *criteria, &block) + super(msg) - # - def fail? - not pass? - end + #@criteria = criteria + #@block = block + #@not = false - # - def assert - #@negative = false - raise self unless pass? - end + @assertion = true - # - def refute - #@negative = true - raise self unless fail? - end + #options = (Hash === criteria.last ? criteria.pop : {}) + #set_backtrace(options[:backtrace]) if options[:backtrace] + #set_negative(options[:negated]) if options[:negated] + end - # - def negative? - @negative - end +end - # Set whether this failure was the inverse of it's normal meaning. - # For example, `!=` rather than `==`. - def set_negative(negative) - @negative = !!negative - end - # Set arguments used to make assertion. - def set_arguments(arguments) - @arguments = arguments - #@block = block - end +=begin - # - def to_s - if @negative - "NOT " + super() - else - super() - end - end + # + #def to_s + # #if @negative + # # "NOT " + super() + # #else + # super() + # #end + #end - end +=end -end