import unittest
import asyncio

import cython

import statically


ONE_HUNDRED = 100
execute = asyncio.get_event_loop().run_until_complete


def is_cython_function(obj):
    return 'cython_function_or_method' in str(type(obj))

def anext(agen):
    gen = agen.asend(None)
    try:
        gen.send(None)
    except StopIteration as error:
        return error.args[0]


class CompilationSuite(unittest.TestCase):
    def test_function(self):
        @statically.typed
        def identity(x: cython.int):
            return x
        self.assertEqual(identity(14), 14)

    def test_is_compiled(self):
        @statically.typed
        def compiled(x: cython.int):
            return x
        self.assertTrue(is_cython_function(compiled))

    def test_non_local_var_in_class(self):
        one = 1
        @statically.typed
        class Class:
            number = 100 + one
        self.assertEqual(Class.number, 101)

    def test_non_local_var_in_method(self):
        two = 2
        class Class:
            @statically.typed
            def add_two(self, x):
                return x + two
        obj = Class()
        self.assertEqual(obj.add_two(100), 102)

    def test_non_local_var_in_function(self):
        tree = 3
        @statically.typed
        def add_tree(x):
            return x + tree
        self.assertEqual(add_tree(100), 103)

    def test_non_local_var_in_generator_function(self):
        four = 4
        @statically.typed
        def add_four(x):
            yield x + four
        self.assertEqual(next(add_four(100)), 104)

    def test_non_local_var_in_coroutine_function(self):
        five = 5
        @statically.typed
        async def add_five(x):
            return x + five
        self.assertEqual(execute(add_five(100)), 105)

    def test_global_var_in_class(self):
        @statically.typed
        class Class_:
            number = 1 + ONE_HUNDRED
        self.assertEqual(Class_.number, 101)

    def test_global_var_in_method(self):
        class Class:
            @statically.typed
            def add_one_hundred(self, x):
                return ONE_HUNDRED + x
        obj = Class()
        self.assertEqual(obj.add_one_hundred(2), 102)

    def test_global_var_in_function(self):
        @statically.typed
        def add_one_hundred(x):
            return ONE_HUNDRED + x
        self.assertEqual(add_one_hundred(3), 103)

    def test_global_var_in_generator_function(self):
        @statically.typed
        def add_one_hundred(x):
            yield ONE_HUNDRED + x
        self.assertEqual(next(add_one_hundred(4)), 104)

    def test_global_var_in_coroutine_function(self):
        @statically.typed
        async def add_one_hundred(x):
            return ONE_HUNDRED + x
        self.assertEqual(execute(add_one_hundred(5)), 105)

    @unittest.skipUnless(statically.has_async_gen_fun, "Test does not apply for this version of Python")
    def test_async_generator(self):
        message = r"Async generator funcions are not supported."
        with self.assertRaisesRegex(TypeError, message):
             from test_statically_async import generator


if __name__ == '__main__':
    unittest.main()

@@ -28,22 +28,175 @@
 cio%0A
-%0Aimport cython
+import subprocess%0Aimport sys%0Aimport os.path%0A%0Aimport cython%0Atry:%0A    import IPython%0Aexcept ImportError:%0A    ipython_installed = False%0Aelse:%0A    ipython_installed = True
 %0A%0Aim
@@ -374,16 +374,17 @@
 (obj))%0A%0A
+%0A
 def anex
@@ -3265,16 +3265,788 @@
 rator%0A%0A%0A
+@unittest.skipUnless(ipython_installed, %22IPython not installed%22)%0Aclass IPythonSuite(unittest.TestCase):%0A    def test_ipython(self):%0A        base_dir = os.path.dirname(sys.executable)%0A        executable = os.path.join(base_dir, %22ipython%22)%0A        process = subprocess.Popen(%5Bexecutable%5D, stdin=subprocess.PIPE,%0A                                   stdout=subprocess.PIPE)%0A        script = %22import statically%5Cn%22 %5C%0A                 %22@statically.typed%5Cn%22 %5C%0A                 %22def add(a: int, b: int): return a + b%5Cn%5Cn%22 %5C%0A                 %22'cython_function_or_method' in str(type(add))%5Cn%22.encode()%0A        stdout, _ = process.communicate(script)%0A        lines = stdout.decode().split(%22%5Cn%22)%0A        process.terminate()%0A        self.assertEqual(lines%5B-4%5D, %22In %5B3%5D: Out%5B3%5D: True%22)%0A%0A%0A
 if __nam

Add IPython testcase