-
Notifications
You must be signed in to change notification settings - Fork 93
Expand file tree
/
Copy pathtest_app_errors.py
More file actions
128 lines (107 loc) · 5.04 KB
/
Copy pathtest_app_errors.py
File metadata and controls
128 lines (107 loc) · 5.04 KB
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
from __future__ import annotations
import unittest
from pathlib import Path
from app.errors import UNKNOWN_CODE, describe_failure, flatten, report_text
def raised(error: BaseException, cause: BaseException | None = None) -> BaseException:
"""Return `error` as it would arrive at the GUI: raised, with a traceback."""
try:
if cause is None:
raise error
try:
raise cause
except BaseException as inner: # noqa: BLE001 - rebuilding a real chain
raise error from inner
except BaseException as caught: # noqa: BLE001
return caught
class FlattenTests(unittest.TestCase):
def test_the_cause_survives_the_generic_wrapper(self):
"""The core wraps every failure in "Failed to translate <path>", so only
the chain says what actually went wrong."""
error = raised(
RuntimeError("Failed to translate book.pdf"),
ValueError("code=8: invalid key in dict"),
)
flattened = flatten(error)
self.assertIn("Failed to translate book.pdf", flattened)
self.assertIn("invalid key in dict", flattened)
class DescribeFailureTests(unittest.TestCase):
def test_a_broken_native_library_is_recognised(self):
failure = describe_failure(
raised(ImportError("pikepdf's extension library (pikepdf._core) failed to import."))
)
self.assertEqual(failure.code, "E-CORE-01")
self.assertIn("giải nén", failure.advice)
def test_an_unreadable_pdf_is_recognised_through_its_cause(self):
failure = describe_failure(
raised(
RuntimeError("PDF translation core failed"),
ValueError("FzErrorSyntax: code=8: invalid key in dict"),
)
)
self.assertEqual(failure.code, "E-PDF-02")
def test_an_existing_output_is_a_skip_not_a_failure(self):
failure = describe_failure(
raised(RuntimeError("Output already exists: C:/out/book-vi.pdf."))
)
self.assertEqual(failure.code, "E-OUT-05")
self.assertIn("Ghi đè", failure.advice)
def test_a_network_failure_is_recognised(self):
failure = describe_failure(raised(TimeoutError("Max retries exceeded")))
self.assertEqual(failure.code, "E-NET-04")
def test_an_unmapped_failure_keeps_its_original_text(self):
failure = describe_failure(raised(RuntimeError("something nobody mapped")))
self.assertEqual(failure.code, UNKNOWN_CODE)
self.assertIn("something nobody mapped", failure.detail)
def test_every_failure_offers_a_summary_and_an_action(self):
for error in (
ImportError("pikepdf._core"),
RuntimeError("FzErrorSyntax"),
TimeoutError("timed out"),
RuntimeError("unmapped"),
):
with self.subTest(error=error):
failure = describe_failure(raised(error))
self.assertTrue(failure.summary.strip())
self.assertTrue(failure.advice.strip())
self.assertIn(failure.code, failure.headline)
class ReportTextTests(unittest.TestCase):
def test_the_report_carries_what_a_maintainer_needs(self):
"""A user who cannot read the error also cannot retype it, so the copied
block has to stand on its own."""
failure = describe_failure(raised(ImportError("pikepdf._core failed")))
report = report_text(
failure, Path("C:/x/Skin.pdf"), "0.2.2", Path("C:/x/pdf-translate.log")
)
for expected in ("Skin.pdf", "0.2.2", failure.code, "pdf-translate.log"):
with self.subTest(expected=expected):
self.assertIn(expected, report)
def test_a_missing_log_is_simply_omitted(self):
failure = describe_failure(raised(RuntimeError("boom")))
self.assertNotIn("Log", report_text(failure, Path("a.pdf"), "0.2.2"))
class ScannedDocumentTests(unittest.TestCase):
def test_the_ocr_refusal_reaches_the_scan_advice(self):
"""E-PDF-03 was written for this case but nothing ever raised it, so a
scan was reported to the user as a finished translation."""
failure = describe_failure(
raised(
RuntimeError(
"No text could be extracted from tk.pdf: the selected pages are "
"image-only scans. This tool does not perform OCR, so run OCR on "
"the PDF first and translate the result."
)
)
)
self.assertEqual(failure.code, "E-PDF-03")
self.assertIn("scan", failure.summary.lower())
self.assertIn("Bật OCR", failure.advice)
def test_unsafe_ocr_page_has_specific_fail_closed_advice(self):
failure = describe_failure(
RuntimeError(
"OCR found no text that could be translated safely in form.pdf "
"(page 1: preserved (dense rules or form grid))"
)
)
self.assertEqual(failure.code, "E-OCR-07")
self.assertIn("giữ nguyên", failure.advice)
if __name__ == "__main__":
unittest.main()