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

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


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

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

    assert func(2) == 6

Add a test on failed arg introspection in chained decorators
Add a test on failed arg introspection in chained decorators

This is a consequence of not preserving function signature. So this
could be fixed by preserving signature or by some workaround.

  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
  
+ 
+ @pytest.mark.xfail
+ def test_chain_arg_access():
+     @decorator
+     def decor(call):
+         return call.x + call()
+ 
+     @decor
+     @decor
+     def func(x):
+         return x
+ 
+     assert func(2) == 6
+ 
Add a test on failed arg introspection in chained decorators
## Code Before:
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

## Instruction:
Add a test on failed arg introspection in chained decorators
## Code After:
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


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

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

    assert func(2) == 6
