require 'test/yarvtest'


class TestMethod < YarvTestBase
  
  def test_simple_method
    ae <<-'EOS'
    def m_simple_method
      1
    end
    m_simple_method()
    EOS
  end

  def test_polymorphic
    ae %q{
      o1 = 'str'
      o2 = 1
      str = ''
      i = 1
      while i<10
        i+=1
        o = (i%2==0) ? o1 : o2
        str += o.to_s
      end
      str
    }
  end

  def test_arg
    ae <<-'EOS'
    def m_arg(a1, a2)
      a1+a2
    end
    m_arg(1,2)
    EOS
  end

  def test_rec
    ae <<-'EOS'
    def m_rec n
      if n > 1
        n + m_rec(n-1)
      else
        1
      end
    end
    m_rec(10)
    EOS
  end

  def test_splat
    ae %q{
      def m a
        a
      end

      m(*1)
    }

    ae %q{
      def m a, b
        [a, b]
      end

      m(*[1,2])
    }

    ae %q{
      def m a, b, c
        [a, b, c]
      end

      m(1, *[2, 3])
    }

    ae %q{
      def m a, b, c
        [a, b, c]
      end

      m(1, 2, *[3])
    }
  end

  def test_rest
    ae %q{
      def m *a
        a
      end

      m
    }

    ae %q{
      def m *a
        a
      end

      m 1
    }

    ae %q{
      def m *a
        a
      end

      m 1, 2, 3
    }

    ae %q{
      def m x, *a
        [x, a]
      end

      m 1
    }

    ae %q{
      def m x, *a
        [x, a]
      end

      m 1, 2
    }

    ae %q{
      def m x, *a
        [x, a]
      end

      m 1, 2, 3, 4
    }
  end

  def test_opt
    ae %q{
      def m a=1
        a
      end
      m
    }
    ae %q{
      def m a=1
        a
      end
      m 2
    }
    ae %q{
      def m a=1, b=2
        [a, b]
      end
      m
    }
    ae %q{
      def m a=1, b=2
        [a, b]
      end
      m 10
    }
    ae %q{
      def m a=1, b=2
        [a, b]
      end
      m 10, 20
    }
    ae %q{
      def m x, a=1, b=2
        [x, a, b]
      end
      m 10
    }
    ae %q{
      def m x, a=1, b=2
        [x, a, b]
      end
      m 10, 20
    }
    ae %q{
      def m x, a=1, b=2
        [x, a, b]
      end
      m 10, 20, 30
    }


  end
  

  def test_singletonmethod
    ae %q{
      lobj = Object.new
      def lobj.m
        :singleton
      end

      lobj.m
    }

    ae %q{
      class C
        def m
          :C_m
        end
      end

      lobj = C.new

      def lobj.m
        :Singleton_m
      end

      lobj.m
    }
  end

  def test_alias
    ae %q{
      def m1
        :ok
      end

      alias :m2 :m1
      m1
    }
    
    ae %q{
      def m1
        :ok
      end

      alias m2 m1
      m1
    }
    
    ae %q{
      def m1
        :ok
      end

      alias m2 :m1
      m1
    }

    ae %q{
      def m1
        :ok
      end

      alias :m2 m1
      m1
    }

  end

  def test_split
    ae %q{
      'abc'.split(/b/)
    }
    ae %q{
      1.times{|bi|
        'abc'.split(/b/)
      }
    }
  end

  def test_block_pass
    ae %q{
      def getproc &b
        b
      end
      def m
        yield
      end
      m(&getproc{
        "test"
      })
    }
    ae %q{
      def getproc &b
        b
      end
      def m a
        yield a
      end
      m(123, &getproc{|block_a|
        block_a
      })
    }
    ae %q{
      def getproc &b
        b
      end
      def m *a
        yield a
      end
      m(123, 456, &getproc{|block_a|
        block_a
      })
    }
    ae %q{
      def getproc &b
        b
      end

      [1,2,3].map(&getproc{|block_e| block_e*block_e})
    }
  end

  def test_method_missing
    ae %q{
      class C
        def method_missing id
          id
        end
      end
      C.new.hoge
    } do
      remove_const :C
    end
    
  end

  def test_svar
    ae %q{
      'abc'.match(/a(b)c/)
      $1
    }
  end
  
end


