class AssertionError < StandardError; end class MustAssertions < ExtraBlankSlate 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 !nil end def respond_to method @obj.respond_to? method 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 *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 arg @obj.exist? arg 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 stack = caller.sfilter('must.rb') unless args.empty? Kernel.raise AssertionError, " ASSERTION FAILED (#{stack.first}): #{@obj.inspect} must #{'not ' if negative}#{"#{@prefix} " if @prefix}#{method} #{args.first.inspect} ", stack else Kernel.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 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) @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