130 self, result, expected_list=None, expected_dict=None, msg=None
133 Unit test assertion to compare a :class:`ParseResults` object with an optional ``expected_list``,
134 and compare any defined results names with an optional ``expected_dict``.
136 if expected_list
is not None:
138 if expected_dict
is not None:
170 self, run_tests_report, expected_parse_results=None, msg=None
173 Unit test assertion to evaluate output of ``ParserElement.runTests()``. If a list of
174 list-dict tuples is given as the ``expected_parse_results`` argument, then these are zipped
175 with the report tuples returned by ``runTests`` and evaluated using ``assertParseResultsEquals``.
176 Finally, asserts that the overall ``runTests()`` success value is ``True``.
178 :param run_tests_report: tuple(bool, [tuple(str, ParseResults or Exception)]) returned from runTests
179 :param expected_parse_results (optional): [tuple(str, list, dict, Exception)]
181 run_test_success, run_test_results = run_tests_report
183 if expected_parse_results
is not None:
186 for rpt, expected
in zip(run_test_results, expected_parse_results)
188 for test_string, result, expected
in merged:
193 (exp
for exp
in expected
if isinstance(exp, str)),
None
195 expected_exception = next(
203 if expected_exception
is not None:
204 with self.assertRaises(
205 expected_exception=expected_exception, msg=fail_msg
or msg
210 expected_list = next(
211 (exp
for exp
in expected
if isinstance(exp, list)),
None
213 expected_dict = next(
214 (exp
for exp
in expected
if isinstance(exp, dict)),
None
216 if (expected_list, expected_dict) != (
None,
None):
219 expected_list=expected_list,
220 expected_dict=expected_dict,
225 print(f
"no validation for {test_string!r}")
229 run_test_success, msg=msg
if msg
is not None else "failed runTests"
242 expand_tabs: bool =
True,
248 Helpful method for debugging a parser - prints a string with line and column numbers.
249 (Line and column numbers are 1-based.)
251 :param s: tuple(bool, str - string to be printed with line and column numbers
252 :param start_line: int - (optional) starting line number in s to print (default=1)
253 :param end_line: int - (optional) ending line number in s to print (default=len(s))
254 :param expand_tabs: bool - (optional) expand tabs to spaces, to match the pyparsing default
255 :param eol_mark: str - (optional) string to mark the end of lines, helps visualize trailing spaces (default="|")
256 :param mark_spaces: str - (optional) special character to display in place of spaces
257 :param mark_control: str - (optional) convert non-printing control characters to a placeholding
258 character; valid values:
259 - "unicode" - replaces control chars with Unicode symbols, such as "␍" and "␊"
260 - any single character string - replace control characters with given string
261 - None (default) - string is displayed as-is
263 :return: str - input string with leading line numbers and column number headers
267 if mark_control
is not None:
269 if mark_control ==
"unicode":
273 transtable_map[127] = 0x2421
277 ord_mark_control =
ord(mark_control)
279 {c: ord_mark_control
for c
in list(
range(0, 32)) + [127]}
282 if mark_spaces
is not None and mark_spaces !=
" ":
283 if mark_spaces ==
"unicode":
288 if start_line
is None:
292 end_line = min(end_line,
len(s))
293 start_line = min(max(1, start_line), end_line)
295 if mark_control !=
"unicode":
298 s_lines = [line +
"␊" for line
in s.split(
"␊")[start_line - 1 : end_line]]
302 lineno_width =
len(str(end_line))
303 max_line_len = max(
len(line)
for line
in s_lines)
304 lead =
" " * (lineno_width + 1)
305 if max_line_len >= 99:
309 f
"{' ' * 99}{(i + 1) % 100}"
310 for i
in range(max(max_line_len // 100, 1))
319 +
"".join(f
" {(i + 1) % 10}" for i
in range(-(-max_line_len // 10)))
322 header2 = lead +
"1234567890" * (-(-max_line_len // 10)) +
"\n"
327 f
"{i:{lineno_width}d}:{line}{eol_mark}"
328 for i, line
in enumerate(s_lines, start=start_line)