Skip to content

Commit 1fe8412

Browse files
[3.12] gh-106368: Increase Argument Clinic BlockParser test coverage (GH-106759) (#106769)
(cherry picked from commit 2d7d1aa) Co-authored-by: Erlend E. Aasland <[email protected]>
1 parent 4f3edd6 commit 1fe8412

File tree

1 file changed

+96
-4
lines changed

1 file changed

+96
-4
lines changed

Lib/test/test_clinic.py

+96-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,19 @@
1818
from clinic import DSLParser
1919

2020

21+
class _ParserBase(TestCase):
22+
maxDiff = None
23+
24+
def expect_parser_failure(self, parser, _input):
25+
with support.captured_stdout() as stdout:
26+
with self.assertRaises(SystemExit):
27+
parser(_input)
28+
return stdout.getvalue()
29+
30+
def parse_function_should_fail(self, _input):
31+
return self.expect_parser_failure(self.parse_function, _input)
32+
33+
2134
class FakeConverter:
2235
def __init__(self, name, args):
2336
self.name = name
@@ -88,7 +101,15 @@ def directive(self, name, args):
88101

89102
_module_and_class = clinic.Clinic._module_and_class
90103

91-
class ClinicWholeFileTest(TestCase):
104+
105+
class ClinicWholeFileTest(_ParserBase):
106+
def setUp(self):
107+
self.clinic = clinic.Clinic(clinic.CLanguage(None), filename="test.c")
108+
109+
def expect_failure(self, raw):
110+
_input = dedent(raw).strip()
111+
return self.expect_parser_failure(self.clinic.parse, _input)
112+
92113
def test_eol(self):
93114
# regression test:
94115
# clinic's block parser didn't recognize
@@ -98,15 +119,86 @@ def test_eol(self):
98119
# so it would spit out an end line for you.
99120
# and since you really already had one,
100121
# the last line of the block got corrupted.
101-
c = clinic.Clinic(clinic.CLanguage(None), filename="file")
102122
raw = "/*[clinic]\nfoo\n[clinic]*/"
103-
cooked = c.parse(raw).splitlines()
123+
cooked = self.clinic.parse(raw).splitlines()
104124
end_line = cooked[2].rstrip()
105125
# this test is redundant, it's just here explicitly to catch
106126
# the regression test so we don't forget what it looked like
107127
self.assertNotEqual(end_line, "[clinic]*/[clinic]*/")
108128
self.assertEqual(end_line, "[clinic]*/")
109129

130+
def test_mangled_marker_line(self):
131+
raw = """
132+
/*[clinic input]
133+
[clinic start generated code]*/
134+
/*[clinic end generated code: foo]*/
135+
"""
136+
msg = (
137+
'Error in file "test.c" on line 3:\n'
138+
"Mangled Argument Clinic marker line: '/*[clinic end generated code: foo]*/'\n"
139+
)
140+
out = self.expect_failure(raw)
141+
self.assertEqual(out, msg)
142+
143+
def test_checksum_mismatch(self):
144+
raw = """
145+
/*[clinic input]
146+
[clinic start generated code]*/
147+
/*[clinic end generated code: output=0123456789abcdef input=fedcba9876543210]*/
148+
"""
149+
msg = (
150+
'Error in file "test.c" on line 3:\n'
151+
'Checksum mismatch!\n'
152+
'Expected: 0123456789abcdef\n'
153+
'Computed: da39a3ee5e6b4b0d\n'
154+
)
155+
out = self.expect_failure(raw)
156+
self.assertIn(msg, out)
157+
158+
def test_garbage_after_stop_line(self):
159+
raw = """
160+
/*[clinic input]
161+
[clinic start generated code]*/foobarfoobar!
162+
"""
163+
msg = (
164+
'Error in file "test.c" on line 2:\n'
165+
"Garbage after stop line: 'foobarfoobar!'\n"
166+
)
167+
out = self.expect_failure(raw)
168+
self.assertEqual(out, msg)
169+
170+
def test_whitespace_before_stop_line(self):
171+
raw = """
172+
/*[clinic input]
173+
[clinic start generated code]*/
174+
"""
175+
msg = (
176+
'Error in file "test.c" on line 2:\n'
177+
"Whitespace is not allowed before the stop line: ' [clinic start generated code]*/'\n"
178+
)
179+
out = self.expect_failure(raw)
180+
self.assertEqual(out, msg)
181+
182+
def test_parse_with_body_prefix(self):
183+
clang = clinic.CLanguage(None)
184+
clang.body_prefix = "//"
185+
clang.start_line = "//[{dsl_name} start]"
186+
clang.stop_line = "//[{dsl_name} stop]"
187+
cl = clinic.Clinic(clang, filename="test.c")
188+
raw = dedent("""
189+
//[clinic start]
190+
//module test
191+
//[clinic stop]
192+
""").strip()
193+
out = cl.parse(raw)
194+
expected = dedent("""
195+
//[clinic start]
196+
//module test
197+
//
198+
//[clinic stop]
199+
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=65fab8adff58cf08]*/
200+
""").lstrip() # Note, lstrip() because of the newline
201+
self.assertEqual(out, expected)
110202

111203

112204
class ClinicGroupPermuterTest(TestCase):
@@ -285,7 +377,7 @@ def test_clinic_1(self):
285377
""")
286378

287379

288-
class ClinicParserTest(TestCase):
380+
class ClinicParserTest(_ParserBase):
289381
def checkDocstring(self, fn, expected):
290382
self.assertTrue(hasattr(fn, "docstring"))
291383
self.assertEqual(fn.docstring.strip(),

0 commit comments

Comments
 (0)