minitest - assert_instance_of と assert_kind_of について
def assert_instance_of cls, obj, msg = nil msg = message(msg) { "Expected #{mu_pp(obj)} to be an instance of #{cls}, not #{obj.class}" } flip = (Module === obj) && ! (Module === cls) # HACK for specs obj, cls = cls, obj if flip assert cls === obj, msg end def assert_kind_of cls, obj, msg = nil # TODO: merge with instance_of msg = message(msg) { "Expected #{mu_pp(obj)} to be a kind of #{cls}, not #{obj.class}" } flip = (Module === obj) && ! (Module === cls) # HACK for specs obj, cls = cls, obj if flip assert obj.kind_of?(cls), msg end
えーと。
refe2 Class#=== より抜粋すると、
Class < Module#=== --- ===(obj) -> bool (中略) 言い替えると obj.kind_of?(self) が true の場合、 true を返します。
つまり、
assert cls === obj, msg
# v
assert obj.kind_of?(cls), msg
assert_instance_ofとassert_kind_ofは等価だったんだよ!!!
な、何だっ(ry
元祖Test::Unitでは refe2 Test::Unit::Assertions#assert_instance_ofを抜粋すると
Test::Unit::Assertions#assert_instance_of --- assert_instance_of(klass, object, message="") -> () object が klass の直接のインスタンスであるなら、パスします。 [[m:Object#instance_of?]]も参照して下さい。 [[m:Test::Unit::Assertions#assert_kind_of]] との違いに注意して下さい。
だそうで。
元祖の定義はこう。
def assert_instance_of(klass, object, message="") _wrap_assertion do assert_equal(Class, klass.class, "assert_instance_of takes a Class as its first argument") full_message = build_message(message, <<EOT, object, klass, object.class) <?> expected to be an instance of <?> but was <?>. EOT assert_block(full_message){object.instance_of?(klass)} end end
多分 Class#===(obj) が obj.instance_of?(self) と再定義されてると思っちゃってるのかな。