class AssertionError < RuntimeError; end class MustAssertions < BasicObject attr_reader :obj def initialize obj @obj = obj end def == o @obj == o end def =~ o @obj =~ o end def never_called false end def nil @obj.equal? nil end def defined @obj != nil end def respond_to method @obj.respond_to? method end def a *args if args.class == ::Array args.any?{|k| @obj.is_a? k} else @obj.is_a? args end end alias_method :an, :a # def be klass = nil # if klass.class == Array # klass.any?{|k| @obj.respond_to :is?, k} # else # @obj.respond_to :is?, klass # end # end def include o @obj.include? o end def in *args if args.size == 1 obj = args.first if obj.is_a?(::Array) or obj.is_a?(::Range) obj.include? @obj else args.include? @obj end else args.include? @obj end end def true !!@obj end def false !@obj end def empty @obj.empty? end def blank @obj.blank? end def present !@obj.blank? end def > o @obj > o end def < o @obj < o end def >= o @obj >= o end def <= o @obj <= o end def exist *args @obj.exist? *args end def be @prefix = 'be' self end def have @prefix = 'have' self end def self.assertions special = [:be, :have] public_instance_methods.select{|m| m !~ /^__/ and !special.include?(m)} end protected # def method_missing m, *args, &b # raise ::RuntimeError, "Assertion '#{m}' is unknown!", caller[1..-1] # end def failed method, negative, *args stack = ::Object.send(:caller).sfilter('must.rb') unless args.empty? ::Object.send :raise, ::AssertionError, " ASSERTION FAILED (#{stack.first}): #{@obj.inspect} must #{'not ' if negative}#{"#{@prefix} " if @prefix}#{method} #{args.collect{|a| a.inspect}.join(', ')} ", stack else ::Object.send :raise, ::AssertionError, " ASSERTION FAILED (#{stack.first}): #{@obj.inspect} must #{'not ' if negative}#{"#{@prefix} " if @prefix}#{method} ", stack end end end class Must < MustAssertions assertions.each do |m| desition = "_#{m}" alias_method desition, m define_method m do |*args| failed m, false, *args unless __send__(desition, *args) @obj end end def inspect "<#Must>" end end class MustNot < MustAssertions assertions.each do |m| desition = "_#{m}".to_sym alias_method desition, m define_method m do |*args| failed m, true, *args if __send__(desition, *args) @obj end end end Object.class_eval do def must Must.new(self) end def must_not MustNot.new(self) end def must_be must.be end def must_not_be must_not.be end # def must_have # must.have # end # # def must_not_have # must_not.have # end end