summaryrefslogtreecommitdiffstats
path: root/contrib/tools/cython/Cython/Compiler/Tests/TestCode.py
blob: cb66c7a9bb069c6d8739c87fc629b476f39e3b93 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import textwrap
from unittest import TestCase

from .. import Naming
from ..Code import _indent_chunk, UtilityCode, process_utility_ccode

class TestIndent(TestCase):
    def _test_indentations(self, chunk, expected):
        for indentation in range(16):
            expected_indented = textwrap.indent(expected, ' ' * indentation)
            for line in expected_indented.splitlines():
                # Validate before the comparison that empty lines got stripped also by textwrap.indent().
                self.assertTrue(line == '' or line.strip(), repr(line))

            with self.subTest(indentation=indentation):
                result = _indent_chunk(chunk, indentation_length=indentation)
                self.assertEqual(expected_indented, result)

    def test_indent_empty(self):
        self._test_indentations('', '')

    def test_indent_empty_lines(self):
        self._test_indentations('\n', '\n')
        self._test_indentations('\n'*2, '\n'*2)
        self._test_indentations('\n'*3, '\n'*3)
        self._test_indentations(' \n'*2, '\n'*2)
        self._test_indentations('\n  \n \n    \n', '\n'*4)

    def test_indent_one_line(self):
        self._test_indentations('abc', 'abc')

    def test_indent_chunk(self):
        chunk = """
            x = 1
            if x == 2:
                print("False")
            else:
                print("True")
        """
        expected = """
x = 1
if x == 2:
    print("False")
else:
    print("True")
"""
        self._test_indentations(chunk, expected)

    def test_indent_empty_line(self):
        chunk = """
            x = 1

            if x == 2:
                print("False")
            else:
                print("True")
        """
        expected = """
x = 1

if x == 2:
    print("False")
else:
    print("True")
"""
        self._test_indentations(chunk, expected)

    def test_indent_empty_line_unclean(self):
        lines = """
            x = 1

            if x == 2:
                print("False")
            else:
                print("True")
        """.splitlines(keepends=True)
        lines[2] = '            \n'
        chunk = ''.join(lines)
        expected = """
x = 1

if x == 2:
    print("False")
else:
    print("True")
"""
        self._test_indentations(chunk, expected)


class TestUtilityCodeProcessing(TestCase):
    def _process(self, code):
        utility_code = UtilityCode()
        formatted_code, is_module_specific = process_utility_ccode(utility_code, None, code)
        self.assertFalse(is_module_specific)  # cannot currently test this case
        return formatted_code

    def assert_formatted_code(self, code: str, expected: str, dedent=False):
        if dedent:
            expected = textwrap.dedent(expected)
        expected = expected.strip() + '\n\n'
        formatted = self._process(code)
        self.assertEqual(formatted, expected)

    def test_format_cstring(self):
        self.assert_formatted_code('''
        Some Text and a CSTRING("""
        spanning "multiple" 'lines'.
        Really.
        """);   # end of C string
        ''',
        expected=r'''
        Some Text and a "\n"
        "        spanning \042multiple\042 'lines'.\n"
        "        Really.\n"
        "        \n"
        ;   # end of C string
        ''',
        dedent=True)

    def test_cglobal(self):
        self.assert_formatted_code("""
        CGLOBAL(name)
        NAMED_CGLOBAL(empty_tuple)
        """,
        expected=f"""
        {Naming.modulestateglobal_cname}->name
        {Naming.modulestateglobal_cname}->{Naming.empty_tuple}
        """)

    def test_empty_builtin(self):
        self.assert_formatted_code("""
        EMPTY(tuple)EMPTY(bytes)
        EMPTY(tuple);EMPTY(bytes)
        EMPTY(unicode)
        EMPTY(bytes)
        EMPTY(tuple)
        """,
        expected=f"""
        {Naming.modulestateglobal_cname}->{Naming.empty_tuple}{Naming.modulestateglobal_cname}->{Naming.empty_bytes}
        {Naming.modulestateglobal_cname}->{Naming.empty_tuple};{Naming.modulestateglobal_cname}->{Naming.empty_bytes}
        {Naming.modulestateglobal_cname}->{Naming.empty_unicode}
        {Naming.modulestateglobal_cname}->{Naming.empty_bytes}
        {Naming.modulestateglobal_cname}->{Naming.empty_tuple}
        """)