class AssertionError < RuntimeError; end class MustAssertions < ExtraBlankSlate def initialize obj @obj = obj end def == o @obj == o end def never_called false end def nil @obj.equal? nil end def a klass if klass.class == Array klass.any?{|k| @obj.is_a? k} else @obj.is_a? klass 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 *enum Array(enum).include? @obj end def true !!@obj end def false !@obj end def empty @obj.empty? end def blank @obj.blank? end def > o @obj > o end def < o @obj < o end def be @prefix = 'be' self end def have @prefix = 'have' self end def self.assertions special = %w{be have} instance_methods.select{|m| m !~ /^__/ and m != 'be'} end protected def method_missing m, *args, &b raise RuntimeError, "Assertion '#{m}' is unknown!", caller[1..-1] end def failed method, negative, *args unless args.empty? Kernel.raise AssertionError, " ASSERTION FAILED (#{caller[1]}): #{@obj.inspect} must #{'not ' if negative}#{"#{@prefix} " if @prefix}#{method} #{args.first} ", caller[3..-1] else Kernel.raise AssertionError, " ASSERTION FAILED (#{caller[1]}): #{@obj.inspect} must #{'not ' if negative}#{"#{@prefix} " if @prefix}#{method} ", caller[3..-1] 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) end end end class MustNot < MustAssertions assertions.each do |m| desition = "_#{m}" alias_method desition, m define_method m do |*args| failed m, true, *args if __send__(desition, *args) 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