|
1 | 1 | import io
|
| 2 | +import re |
2 | 3 | import sys
|
3 | 4 |
|
4 | 5 | import pytest
|
|
21 | 22 | def test_handler():
|
22 | 23 | console = Console(file=io.StringIO(), width=100, color_system=None)
|
23 | 24 | expected_old_handler = sys.excepthook
|
| 25 | + |
| 26 | + def level1(): |
| 27 | + level2() |
| 28 | + |
| 29 | + def level2(): |
| 30 | + return 1 / 0 |
| 31 | + |
24 | 32 | try:
|
25 | 33 | old_handler = install(console=console)
|
26 | 34 | try:
|
27 |
| - 1 / 0 |
| 35 | + level1() |
28 | 36 | except Exception:
|
29 | 37 | exc_type, exc_value, traceback = sys.exc_info()
|
30 | 38 | sys.excepthook(exc_type, exc_value, traceback)
|
31 | 39 | rendered_exception = console.file.getvalue()
|
32 | 40 | print(repr(rendered_exception))
|
33 | 41 | assert "Traceback" in rendered_exception
|
34 | 42 | assert "ZeroDivisionError" in rendered_exception
|
| 43 | + |
| 44 | + frame_blank_line_possible_preambles = ( |
| 45 | + # Start of the stack rendering: |
| 46 | + "╭─────────────────────────────── Traceback (most recent call last) ────────────────────────────────╮", |
| 47 | + # Each subsequent frame (starting with the file name) should then be preceded with a blank line: |
| 48 | + "│" + (" " * 98) + "│", |
| 49 | + ) |
| 50 | + for frame_start in re.finditer( |
| 51 | + "^│ .+rich/tests/test_traceback\.py:", |
| 52 | + rendered_exception, |
| 53 | + flags=re.MULTILINE, |
| 54 | + ): |
| 55 | + frame_start_index = frame_start.start() |
| 56 | + for preamble in frame_blank_line_possible_preambles: |
| 57 | + preamble_start, preamble_end = ( |
| 58 | + frame_start_index - len(preamble) - 1, |
| 59 | + frame_start_index - 1, |
| 60 | + ) |
| 61 | + if rendered_exception[preamble_start:preamble_end] == preamble: |
| 62 | + break |
| 63 | + else: |
| 64 | + pytest.fail( |
| 65 | + f"Frame {frame_start[0]} doesn't have the expected preamble" |
| 66 | + ) |
35 | 67 | finally:
|
36 | 68 | sys.excepthook = old_handler
|
37 | 69 | assert old_handler == expected_old_handler
|
|
0 commit comments