import pytest
from funcy.decorators import *


def test_decorator_no_args():
    @decorator
    def inc(call):
        return call() + 1

    @inc
    def ten():
        return 10

    assert ten() == 11


def test_decorator_with_args():
    @decorator
    def add(call, n):
        return call() + n

    @add(2)
    def ten():
        return 10

    assert ten() == 12


def test_decorator_access_arg():
    @decorator
    def multiply(call):
        return call() * call.n

    @multiply
    def square(n):
        return n

    assert square(5) == 25


def test_decorator_access_nonexistent_arg():
    @decorator
    def return_x(call):
        return call.x

    @return_x
    def f():
        pass

    with pytest.raises(AttributeError): f()


def test_decorator_with_method():
    @decorator
    def inc(call):
        return call() + 1

    class A(object):
        def ten(self):
            return 10

        @classmethod
        def ten_cls(cls):
            return 10

        @staticmethod
        def ten_static():
            return 10

    assert inc(A().ten)() == 11
    assert inc(A.ten_cls)() == 11
    assert inc(A.ten_cls)() == 11
    assert inc(A.ten_static)() == 11


def test_decorator_with_method_descriptor():
    @decorator
    def exclaim(call):
        return call() + '!'

    assert exclaim(str.upper)('hi') == 'HI!'


def test_chain_arg_access():
    @decorator
    def decor(call):
        return call.x + call()

    @decor
    @decor
    def func(x):
        return x

    assert func(2) == 6

@@ -1523,8 +1523,532 @@
 2) == 6%0A
+%0A%0Adef test_meta_attribtes():%0A    @decorator%0A    def decor(call):%0A        return call()%0A%0A    def func(x):%0A        %22Some doc%22%0A        return x%0A%0A    decorated = decor(func)%0A    double_decorated = decor(decorated)%0A%0A    assert decorated.__name__ == 'func'%0A    assert decorated.__module__ == __name__%0A    assert decorated.__doc__ == %22Some doc%22%0A    assert decorated.__wrapped__ is func%0A    assert decorated.__original__ is func%0A%0A    assert double_decorated.__wrapped__ is decorated%0A    assert double_decorated.__original__ is func%0A

Test @decorators preserving/setting meta