Mon, 18 Sep 06

Testing Class::method_exists?

class Foo
  def foo; end; public :foo
  def bar; end; protected :bar
  def baz; end; private :baz
end

require 'test/unit'

Class.new(Test::Unit::TestCase) do

  def assert_not(expr)
    assert ! expr
  end

  def assert_method_exists_is_working
    [:foo, :bar, :baz].each do |sym|
      assert Foo.method_exists?(sym)
      assert Foo.method_exists?(sym.to_s)
    end
    assert_not Foo.method_exists?(:made_up_method)
    assert_not Foo.method_exists?('made_up_method')
  end

  def test_implementation_1
    def Foo.method_exists?(method_sym)
      instance_method(method_sym)
      true
    rescue
      false
    end

    assert_method_exists_is_working
  end

  def test_implementation_2
    def Foo.method_exists?(method_sym)
      methods = public_instance_methods + protected_instance_methods + private_instance_methods
      methods.include?(method_sym.to_s)
    end

    assert_method_exists_is_working
  end

  def test_implementation_3
    def Foo.method_exists?(method_sym)
      method_sym = method_sym.to_s
      public_method_defined?(method_sym) || protected_method_defined?(method_sym) || private_method_defined?(method_sym)
    end

    assert_method_exists_is_working
  end

end