module Minitest::Assertions
def self.diff
def self.diff return @diff if defined? @diff @diff = if (RbConfig::CONFIG["host_os"] =~ /mswin|mingw/ && system("diff.exe", __FILE__, __FILE__)) then "diff.exe -u" elsif Minitest::Test.maglev? then "diff -u" elsif system("gdiff", __FILE__, __FILE__) "gdiff -u" # solaris and kin suck elsif system("diff", __FILE__, __FILE__) "diff -u" else nil end end
def self.diff= o
def self.diff= o @diff = o end
def _synchronize # :nodoc:
def _synchronize # :nodoc: yield end
def assert test, msg = nil
def assert test, msg = nil self.assertions += 1 unless test then msg ||= "Expected #{mu_pp test} to be truthy." msg = msg.call if Proc === msg raise Minitest::Assertion, msg end true end
def assert_empty obj, msg = nil
def assert_empty obj, msg = nil msg = message(msg) { "Expected #{mu_pp(obj)} to be empty" } assert_respond_to obj, :empty? assert obj.empty?, msg end
def assert_equal exp, act, msg = nil
def assert_equal exp, act, msg = nil msg = message(msg, E) { diff exp, act } result = assert exp == act, msg if nil == exp then if Minitest::VERSION =~ /^6/ then refute_nil exp, "Use assert_nil if expecting nil." else where = Minitest.filter_backtrace(caller).first where = where.split(/:in /, 2).first # clean up noise warn "DEPRECATED: Use assert_nil if expecting nil from #{where}. This will fail in Minitest 6." end end result end
def assert_in_delta exp, act, delta = 0.001, msg = nil
def assert_in_delta exp, act, delta = 0.001, msg = nil n = (exp - act).abs msg = message(msg) { "Expected |#{exp} - #{act}| (#{n}) to be <= #{delta}" } assert delta >= n, msg end
def assert_in_epsilon exp, act, epsilon = 0.001, msg = nil
def assert_in_epsilon exp, act, epsilon = 0.001, msg = nil assert_in_delta exp, act, [exp.abs, act.abs].min * epsilon, msg end
def assert_includes collection, obj, msg = nil
def assert_includes collection, obj, msg = nil msg = message(msg) { "Expected #{mu_pp(collection)} to include #{mu_pp(obj)}" } assert_respond_to collection, :include? assert collection.include?(obj), msg end
def assert_instance_of cls, obj, msg = nil
def assert_instance_of cls, obj, msg = nil msg = message(msg) { "Expected #{mu_pp(obj)} to be an instance of #{cls}, not #{obj.class}" } assert obj.instance_of?(cls), msg end
def assert_kind_of cls, obj, msg = nil
def assert_kind_of cls, obj, msg = nil msg = message(msg) { "Expected #{mu_pp(obj)} to be a kind of #{cls}, not #{obj.class}" } assert obj.kind_of?(cls), msg end
def assert_match matcher, obj, msg = nil
def assert_match matcher, obj, msg = nil msg = message(msg) { "Expected #{mu_pp matcher} to match #{mu_pp obj}" } assert_respond_to matcher, :"=~" matcher = Regexp.new Regexp.escape matcher if String === matcher assert matcher =~ obj, msg end
def assert_mock mock
def assert_mock mock assert mock.verify end
def assert_nil obj, msg = nil
def assert_nil obj, msg = nil msg = message(msg) { "Expected #{mu_pp(obj)} to be nil" } assert obj.nil?, msg end
def assert_operator o1, op, o2 = UNDEFINED, msg = nil
def assert_operator o1, op, o2 = UNDEFINED, msg = nil return assert_predicate o1, op, msg if UNDEFINED == o2 msg = message(msg) { "Expected #{mu_pp(o1)} to be #{op} #{mu_pp(o2)}" } assert o1.__send__(op, o2), msg end
def assert_output stdout = nil, stderr = nil
def assert_output stdout = nil, stderr = nil flunk "assert_output requires a block to capture output." unless block_given? out, err = capture_io do yield end err_msg = Regexp === stderr ? :assert_match : :assert_equal if stderr out_msg = Regexp === stdout ? :assert_match : :assert_equal if stdout y = send err_msg, stderr, err, "In stderr" if err_msg x = send out_msg, stdout, out, "In stdout" if out_msg (!stdout || x) && (!stderr || y) end
def assert_predicate o1, op, msg = nil
def assert_predicate o1, op, msg = nil msg = message(msg) { "Expected #{mu_pp(o1)} to be #{op}" } assert o1.__send__(op), msg end
def assert_raises *exp
def assert_raises *exp flunk "assert_raises requires a block to capture errors." unless block_given? msg = "#{exp.pop}.\n" if String === exp.last exp << StandardError if exp.empty? begin yield rescue *exp => e pass # count assertion return e rescue Minitest::Skip, Minitest::Assertion # don't count assertion raise rescue SignalException, SystemExit raise rescue Exception => e flunk proc { exception_details(e, "#{msg}#{mu_pp(exp)} exception expected, not") } end exp = exp.first if exp.size == 1 flunk "#{msg}#{mu_pp(exp)} expected but nothing was raised." end
def assert_respond_to obj, meth, msg = nil
def assert_respond_to obj, meth, msg = nil msg = message(msg) { "Expected #{mu_pp(obj)} (#{obj.class}) to respond to ##{meth}" } assert obj.respond_to?(meth), msg end
def assert_same exp, act, msg = nil
def assert_same exp, act, msg = nil msg = message(msg) { data = [mu_pp(act), act.object_id, mu_pp(exp), exp.object_id] "Expected %s (oid=%d) to be the same as %s (oid=%d)" % data } assert exp.equal?(act), msg end
def assert_send send_ary, m = nil
def assert_send send_ary, m = nil where = Minitest.filter_backtrace(caller).first where = where.split(/:in /, 2).first # clean up noise warn "DEPRECATED: assert_send. From #{where}" recv, msg, *args = send_ary m = message(m) { "Expected #{mu_pp(recv)}.#{msg}(*#{mu_pp(args)}) to return true" } assert recv.__send__(msg, *args), m end
def assert_silent
def assert_silent assert_output "", "" do yield end end
def assert_throws sym, msg = nil
def assert_throws sym, msg = nil default = "Expected #{mu_pp(sym)} to have been thrown" caught = true catch(sym) do begin yield rescue ThreadError => e # wtf?!? 1.8 + threads == suck default += ", not \:#{e.message[/uncaught throw \`(\w+?)\'/, 1]}" rescue ArgumentError => e # 1.9 exception raise e unless e.message.include?("uncaught throw") default += ", not #{e.message.split(/ /).last}" rescue NameError => e # 1.8 exception raise e unless e.name == sym default += ", not #{e.name.inspect}" end caught = false end assert caught, message(msg) { default } end
def capture_io
def capture_io _synchronize do begin captured_stdout, captured_stderr = StringIO.new, StringIO.new orig_stdout, orig_stderr = $stdout, $stderr $stdout, $stderr = captured_stdout, captured_stderr yield return captured_stdout.string, captured_stderr.string ensure $stdout = orig_stdout $stderr = orig_stderr end end end
def capture_subprocess_io
def capture_subprocess_io _synchronize do begin require "tempfile" captured_stdout, captured_stderr = Tempfile.new("out"), Tempfile.new("err") orig_stdout, orig_stderr = $stdout.dup, $stderr.dup $stdout.reopen captured_stdout $stderr.reopen captured_stderr yield $stdout.rewind $stderr.rewind return captured_stdout.read, captured_stderr.read ensure captured_stdout.unlink captured_stderr.unlink $stdout.reopen orig_stdout $stderr.reopen orig_stderr end end end
def diff exp, act
def diff exp, act expect = mu_pp_for_diff exp butwas = mu_pp_for_diff act result = nil e1, e2 = expect.include?("\n"), expect.include?("\\n") b1, b2 = butwas.include?("\n"), butwas.include?("\\n") need_to_diff = (e1 ^ e2 || b1 ^ b2 || expect.size > 30 || butwas.size > 30 || expect == butwas) && Minitest::Assertions.diff return "Expected: #{mu_pp exp}\n Actual: #{mu_pp act}" unless need_to_diff Tempfile.open("expect") do |a| a.puts expect a.flush Tempfile.open("butwas") do |b| b.puts butwas b.flush result = `#{Minitest::Assertions.diff} #{a.path} #{b.path}` result.sub!(/^\-\-\- .+/, "--- expected") result.sub!(/^\+\+\+ .+/, "+++ actual") if result.empty? then klass = exp.class result = [ "No visible difference in the #{klass}#inspect output.\n", "You should look at the implementation of #== on ", "#{klass} or its members.\n", expect, ].join end end end result end
def exception_details e, msg
def exception_details e, msg [ "#{msg}", "Class: <#{e.class}>", "Message: <#{e.message.inspect}>", "---Backtrace---", "#{Minitest.filter_backtrace(e.backtrace).join("\n")}", "---------------", ].join "\n" end
def flunk msg = nil
def flunk msg = nil msg ||= "Epic Fail!" assert false, msg end
def message msg = nil, ending = nil, &default
def message msg = nil, ending = nil, &default proc { msg = msg.call.chomp(".") if Proc === msg custom_message = "#{msg}.\n" unless msg.nil? or msg.to_s.empty? "#{custom_message}#{default.call}#{ending || "."}" } end
def mu_pp obj
def mu_pp obj s = obj.inspect if defined? Encoding then s = s.encode Encoding.default_external if String === obj && (obj.encoding != Encoding.default_external || !obj.valid_encoding?) then enc = "# encoding: #{obj.encoding}" val = "# valid: #{obj.valid_encoding?}" s = "#{enc}\n#{val}\n#{s}" end end s end
def mu_pp_for_diff obj
def mu_pp_for_diff obj str = mu_pp obj # both '\n' & '\\n' (_after_ mu_pp (aka inspect)) single = !!str.match(/(?<!\\|^)\\n/) double = !!str.match(/(?<=\\|^)\\n/) process = if single ^ double then if single then lambda { |s| s == "\\n" ? "\n" : s } # unescape else lambda { |s| s == "\\\\n" ? "\\n\n" : s } # unescape a bit, add nls end else :itself # leave it alone end str. gsub(/\\?\\n/, &process). gsub(/:0x[a-fA-F0-9]{4,}/m, ":0xXXXXXX") # anonymize hex values end
def pass _msg = nil
def pass _msg = nil assert true end
def refute test, msg = nil
def refute test, msg = nil msg ||= message { "Expected #{mu_pp(test)} to not be truthy" } not assert !test, msg end
def refute_empty obj, msg = nil
def refute_empty obj, msg = nil msg = message(msg) { "Expected #{mu_pp(obj)} to not be empty" } assert_respond_to obj, :empty? refute obj.empty?, msg end
def refute_equal exp, act, msg = nil
def refute_equal exp, act, msg = nil msg = message(msg) { "Expected #{mu_pp(act)} to not be equal to #{mu_pp(exp)}" } refute exp == act, msg end
def refute_in_delta exp, act, delta = 0.001, msg = nil
def refute_in_delta exp, act, delta = 0.001, msg = nil n = (exp - act).abs msg = message(msg) { "Expected |#{exp} - #{act}| (#{n}) to not be <= #{delta}" } refute delta >= n, msg end
def refute_in_epsilon a, b, epsilon = 0.001, msg = nil
def refute_in_epsilon a, b, epsilon = 0.001, msg = nil refute_in_delta a, b, a * epsilon, msg end
def refute_includes collection, obj, msg = nil
def refute_includes collection, obj, msg = nil msg = message(msg) { "Expected #{mu_pp(collection)} to not include #{mu_pp(obj)}" } assert_respond_to collection, :include? refute collection.include?(obj), msg end
def refute_instance_of cls, obj, msg = nil
def refute_instance_of cls, obj, msg = nil msg = message(msg) { "Expected #{mu_pp(obj)} to not be an instance of #{cls}" } refute obj.instance_of?(cls), msg end
def refute_kind_of cls, obj, msg = nil
def refute_kind_of cls, obj, msg = nil msg = message(msg) { "Expected #{mu_pp(obj)} to not be a kind of #{cls}" } refute obj.kind_of?(cls), msg end
def refute_match matcher, obj, msg = nil
def refute_match matcher, obj, msg = nil msg = message(msg) { "Expected #{mu_pp matcher} to not match #{mu_pp obj}" } assert_respond_to matcher, :"=~" matcher = Regexp.new Regexp.escape matcher if String === matcher refute matcher =~ obj, msg end
def refute_nil obj, msg = nil
def refute_nil obj, msg = nil msg = message(msg) { "Expected #{mu_pp(obj)} to not be nil" } refute obj.nil?, msg end
def refute_operator o1, op, o2 = UNDEFINED, msg = nil
def refute_operator o1, op, o2 = UNDEFINED, msg = nil return refute_predicate o1, op, msg if UNDEFINED == o2 msg = message(msg) { "Expected #{mu_pp(o1)} to not be #{op} #{mu_pp(o2)}" } refute o1.__send__(op, o2), msg end
def refute_predicate o1, op, msg = nil
def refute_predicate o1, op, msg = nil msg = message(msg) { "Expected #{mu_pp(o1)} to not be #{op}" } refute o1.__send__(op), msg end
def refute_respond_to obj, meth, msg = nil
def refute_respond_to obj, meth, msg = nil msg = message(msg) { "Expected #{mu_pp(obj)} to not respond to #{meth}" } refute obj.respond_to?(meth), msg end
def refute_same exp, act, msg = nil
def refute_same exp, act, msg = nil msg = message(msg) { data = [mu_pp(act), act.object_id, mu_pp(exp), exp.object_id] "Expected %s (oid=%d) to not be the same as %s (oid=%d)" % data } refute exp.equal?(act), msg end
def skip msg = nil, bt = caller
def skip msg = nil, bt = caller msg ||= "Skipped, no message given" @skip = true raise Minitest::Skip, msg, bt end
def skipped?
def skipped? defined?(@skip) and @skip end