Mon, 18 Sep 06

Testing Object#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 setup
    @foo = Foo.new
  end

  def test_implementation_1
    def @foo.method_exists?(method_sym)
      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_methods + protected_methods + private_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
      respond_to?(method_sym, include_private=true)
    end

    assert_method_exists_is_working
  end

end