from ..utils import TranspileTestCase


class MethodTests(TranspileTestCase):
    def test_method(self):
        self.assertCodeExecution("""
            class TestObj:
                def myfunc(self, value):
                    print(value * 3)
                    return value + 5

            obj = TestObj()
            print("value =", obj.myfunc(5))
            """)

    def test_noargs_method(self):
        self.assertCodeExecution("""
            class TestObj:
                def myfunc(self, ):
                    print('Hello')
                    return 5

            obj = TestObj()
            print("value =", obj.myfunc())
            """)

    def test_void_method(self):
        self.assertCodeExecution("""
            class TestObj:
                def myfunc(self, value):
                    print(value * 3)

            obj = TestObj()
            obj.myfunc(5)
            """)

    def test_inner_function(self):
        self.assertCodeExecution("""
            class TestObj:
                def myfunc(self, value):
                    print(value * 3)

                    def myinner(value2):
                        print(value2 * 4)
                        return value2 + 6

                    print("inner value =", myinner(10))
                    return value + 5

            obj = TestObj()
            print("outer =", obj.myfunc(5))
            """, run_in_function=False)

    def test_closure(self):
        self.assertCodeExecution("""
            class TestObj:
                def myfunc(self, value):
                    print(value * 3)

                    def myinner(value2):
                        print(value2 * value)
                        return value2 + 6

                    print("inner value =", myinner(10))
                    return value + 5

            obj = TestObj()
            print("outer =", obj.myfunc(5))
            """)

    def test_default_args(self):
        self.assertCodeExecution("""
            class TestObj:
                def myfunc(self, x, y=1, z=2):
                    print("x =", x)
                    print("y =", y)
                    print("z =", z)

            obj = TestObj()
            obj.myfunc(37)
            """, run_in_function=False)

    def test_override_some_default_args(self):
        self.assertCodeExecution("""
            class TestObj:
                def myfunc(self, x, y=1, z=2):
                    print("x =", x)
                    print("y =", y)
                    print("z =", z)

            obj = TestObj()
            obj.myfunc(37, 42)
            """, run_in_function=False)

    def test_overide_all_default_args(self):
        self.assertCodeExecution("""
            class TestObj:
                def myfunc(self, x, y=1, z=2):
                    print("x =", x)
                    print("y =", y)
                    print("z =", z)

            obj = TestObj()
            obj.myfunc(37, 42, 99)
            """, run_in_function=False)

    def test_use_kwargs(self):
        self.assertCodeExecution("""
            class TestObj:
                def myfunc(self, x, y=1, z=2):
                    print("x =", x)
                    print("y =", y)
                    print("z =", z)

            obj = TestObj()
            obj.myfunc(37, y=42)
            """, run_in_function=False)

    def test_use_kwargs_non_sequential(self):
        self.assertCodeExecution("""
            class TestObj:
                def myfunc(self, x, y=1, z=2):
                    print("x =", x)
                    print("y =", y)
                    print("z =", z)

            obj = TestObj()
            obj.myfunc(37, z=42)
            """, run_in_function=False)

    def test_use_all_kwargs(self):
        self.assertCodeExecution("""
            class TestObj:
                def myfunc(self, x, y=1, z=2):
                    print("x =", x)
                    print("y =", y)
                    print("z =", z)

            obj = TestObj()
            obj.myfunc(x=37, y=42, z=99)
            """, run_in_function=False)

    def test_use_all_kwargs_different_order(self):
        self.assertCodeExecution("""
            class TestObj:
                def myfunc(self, x, y=1, z=2):
                    print("x =", x)
                    print("y =", y)
                    print("z =", z)

            obj = TestObj()
            obj.myfunc(z=99, y=42, x=37)
            """, run_in_function=False)

    def test_call_method_with_var_args(self):
        self.assertCodeExecution("""
            class TestObj:
                def myfunc(self, *args):
                    print(args)
                    return args[0]

            obj = TestObj()
            print("first arg =", obj.myfunc(1, 2, 3, 4, 5))
            """, run_in_function=False)

    def test_call_method_with_kw(self):
        self.assertCodeExecution("""
            class TestObj:
                def myfunc(self, **kwargs):
                    print(kwargs['first'] * 3)
                    print(kwargs['second'] * 3)

                    return kwargs['first'] + kwargs['second']

            obj = TestObj()
            print("values sum =", obj.myfunc(first=1, second=2))
            """, run_in_function=False)

    def test_call_method_kw(self):
        self.assertCodeExecution("""
            class TestObj:
                def myfunc(self, **kwargs):
                    print(kwargs['first'] * 3)
                    print(kwargs['second'] * 3)

                    return kwargs['first'] + kwargs['second']

            obj = TestObj()
            values = {'first': 1, 'second': 2}
            print("values sum =", obj.myfunc(**values))
            """, run_in_function=False)

    def test_call_method_var_kw(self):
        self.assertCodeExecution("""
            class TestObj:
                def myfunc(self, *args, **kwargs):
                    print(kwargs['first'] * 3)
                    print(kwargs['second'] * 3)
                    print(args)

                    return kwargs['first'] + kwargs['second']

            obj = TestObj()
            values_tuple = (1, 2, 3, 4)
            values_dict = {'first': 1, 'second': 2}
            print("values sum =", obj.myfunc(*values_tuple, **values_dict))
            """, run_in_function=False)

    def test_call_method_var(self):
        self.assertCodeExecution("""
            class TestObj:
                def myfunc(self, *args):
                    print(args)

                    return len(args)

            obj = TestObj()
            values_tuple = (1, 2, 3, 4)
            print("values count =", obj.myfunc(*values_tuple))
            """, run_in_function=False)

@@ -6659,28 +6659,445 @@
 %22%22%22, run_in_function=False)%0A
+%0A    @expectedFailure%0A    def test_method_caching_not_visible_in_dict(self):%0A        self.assertCodeExecution(%22%22%22%0A            class TestObj:%0A                def myfunc(self):%0A                    print(0)%0A%0A            obj = TestObj()%0A            obj.myfunc()%0A%0A            try:%0A                print(obj.__dict__)%0A            except AttributeError as err:%0A                print(err)%0A        %22%22%22, run_in_function=False)%0A

add test for __dict__ inspection