require 'minitest/unit' require 'pp' module Test module Unit module Assertions include MiniTest::Assertions def mu_pp(obj) obj.pretty_inspect.chomp end UNASSIGNED = Object.new # :nodoc: def assert(test, msg = UNASSIGNED) case msg when UNASSIGNED msg = nil when String, Proc else bt = caller.reject { |s| s.rindex(MiniTest::MINI_DIR, 0) } raise ArgumentError, "assertion message must be String or Proc, but #{msg.class} was given.", bt end super end def assert_raise(*args, &b) assert_raises(*args, &b) end def assert_nothing_raised(*args) self._assertions += 1 if Module === args.last msg = nil else msg = args.pop end begin line = __LINE__; yield rescue MiniTest::Skip raise rescue Exception => e bt = e.backtrace as = e.instance_of?(MiniTest::Assertion) if as ans = /\A#{Regexp.quote(__FILE__)}:#{line}:in /o bt.reject! {|ln| ans =~ ln} end if ((args.empty? && !as) || args.any? {|a| a.instance_of?(Module) ? e.is_a?(a) : e.class == a }) msg = message(msg) { "Exception raised:\n<#{mu_pp(e)}>" } raise MiniTest::Assertion, msg.call, bt else raise end end nil end def assert_nothing_thrown(msg=nil) begin yield rescue ArgumentError => error raise error if /\Auncaught throw (.+)\z/m !~ error.message msg = message(msg) { "<#{$1}> was thrown when nothing was expected" } flunk(msg) end assert(true, "Expected nothing to be thrown") end def assert_equal(exp, act, msg = nil) msg = message(msg) { exp_str = mu_pp(exp) act_str = mu_pp(act) exp_comment = '' act_comment = '' if exp_str == act_str if (exp.is_a?(String) && act.is_a?(String)) || (exp.is_a?(Regexp) && act.is_a?(Regexp)) exp_comment = " (#{exp.encoding})" act_comment = " (#{act.encoding})" elsif exp.is_a?(Float) && act.is_a?(Float) exp_str = "%\#.#{Float::DIG+2}g" % exp act_str = "%\#.#{Float::DIG+2}g" % act elsif exp.is_a?(Time) && act.is_a?(Time) if exp.subsec * 1000_000_000 == exp.nsec exp_comment = " (#{exp.nsec}[ns])" else exp_comment = " (subsec=#{exp.subsec})" end if act.subsec * 1000_000_000 == act.nsec act_comment = " (#{act.nsec}[ns])" else act_comment = " (subsec=#{act.subsec})" end elsif exp.class != act.class # a subclass of Range, for example. exp_comment = " (#{exp.class})" act_comment = " (#{act.class})" end elsif !Encoding.compatible?(exp_str, act_str) if exp.is_a?(String) && act.is_a?(String) exp_str = exp.dump act_str = act.dump exp_comment = " (#{exp.encoding})" act_comment = " (#{act.encoding})" else exp_str = exp_str.dump act_str = act_str.dump end end "<#{exp_str}>#{exp_comment} expected but was\n<#{act_str}>#{act_comment}" } assert(exp == act, msg) end def assert_not_nil(exp, msg=nil) msg = message(msg) { "<#{mu_pp(exp)}> expected to not be nil" } assert(!exp.nil?, msg) end def assert_not_equal(exp, act, msg=nil) msg = message(msg) { "<#{mu_pp(exp)}> expected to be != to\n<#{mu_pp(act)}>" } assert(exp != act, msg) end def assert_no_match(regexp, string, msg=nil) assert_instance_of(Regexp, regexp, "The first argument to assert_no_match should be a Regexp.") self._assertions -= 1 msg = message(msg) { "<#{mu_pp(regexp)}> expected to not match\n<#{mu_pp(string)}>" } assert(regexp !~ string, msg) end def assert_not_same(expected, actual, message="") msg = message(msg) { build_message(message, < with id expected to not be equal\\? to with id . EOT assert(!actual.equal?(expected), msg) end # get rid of overcounting def assert_respond_to obj, meth, msg = nil super if !caller[0].rindex(MiniTest::MINI_DIR, 0) || !obj.respond_to?(meth) end ms = instance_methods(true).map {|sym| sym.to_s } ms.grep(/\Arefute_/) do |m| mname = ('assert_not_' << m.to_s[/.*?_(.*)/, 1]) alias_method(mname, m) unless ms.include? mname end def build_message(head, template=nil, *arguments) template &&= template.chomp template.gsub(/\?/) { mu_pp(arguments.shift) } end end end end