better faulty encoding detection

This commit is contained in:
sebastien committed 2026-09-29 08:03:47 +02:00
1 parent ec8e79bb1a
commit 2a4c5f4f7c
12 files changed
+299 -25

No files matched your search

+61
View File
@@ -21,6 +21,7 @@ from pypdf import PdfReader, PdfWriter
from copienator import (
CliError,
EvaluationWorkspace,
ExitCode,
WorkspaceNotFoundError,
WorkspaceValidationError,
atomic_update_json,
@@ -1058,6 +1059,26 @@ class StandardCliTests(unittest.TestCase):
previous_image, previous_json, previous_meta
)
def test_plotting_accepts_lowercase_and_uppercase_previous_shortcuts(self) -> None:
module = self.modules["plotting"]
root = Mock()
root.winfo_screenwidth.return_value = 1200
root.winfo_screenheight.return_value = 800
label = Mock()
with patch.object(module.tk, "Label", return_value=label), patch.object(
module.ImageViewer, "poll_queue"
):
viewer = module.ImageViewer(
root,
SimpleNamespace(root=Path("/evaluation")),
set(),
queue.Queue(),
)
root.bind.assert_any_call("p", viewer.on_previous)
root.bind.assert_any_call("P", viewer.on_previous)
def test_plotting_validates_plain_and_directional_labels(self) -> None:
module = self.modules["plotting"]
self.assertEqual(
@@ -1317,6 +1338,16 @@ class StandardCliTests(unittest.TestCase):
self.assertEqual(result["list"][0]["label"], "??Ex 10 : 1)a)")
self.assertIn("keeping them with a ?? prefix", output.getvalue())
def test_correction_response_preserves_ambiguous_latex_commands(self) -> None:
module = self.modules["correction"]
parsed = module.parse_correction_response(
r'[{"result":{"feedback":[{"text":"$\forall x, f \big(x\big) \to x$"}]}}]'
)
self.assertEqual(
parsed[0]["result"]["feedback"][0]["text"],
r"$\forall x, f \big(x\big) \to x$",
)
def test_correction_overwrite_keeps_previous_state_until_a_commit(self) -> None:
module = self.modules["correction"]
with tempfile.TemporaryDirectory() as directory:
@@ -1774,6 +1805,23 @@ class StandardCliTests(unittest.TestCase):
r"Formulas $\frac{1}{2}$, $\theta \equiv 0 [2\pi]$, "
r"$e \times x$, and [\negthinspace[0,n]",
)
decoded_math_commands = (
"$"
+ "\x0corall x, f "
+ "\x08ig(x\x08ig) "
+ "\to "
+ "\text{false}$"
)
self.assertEqual(
module.clean_string(decoded_math_commands, {}),
r"$\forall x, f \big(x\big) \to \text{false}$",
)
self.assertEqual(
module.unresolved_math_control_paths(
{"feedback": ["Plain\fprose", "$unknown\fform$"]}
),
["$['feedback'][1]"],
)
self.assertEqual(
module.clean_string("x ∈ A and B ⊂ C", {}),
r"x \ensuremath{\in} A and B \ensuremath{\subset} C",
@@ -1800,6 +1848,19 @@ class StandardCliTests(unittest.TestCase):
self.assertEqual((evaluation / "correction.json").read_bytes(), cleaned)
self.assertEqual(backup.read_bytes(), original)
with tempfile.TemporaryDirectory() as directory:
evaluation = Path(directory) / "Exam"
evaluation.mkdir()
atomic_write_json(
evaluation / "correction.json",
{"text": "$unknown\fcommand$"},
)
output = io.StringIO()
with redirect_stdout(output):
result = module.run(EvaluationWorkspace(evaluation))
self.assertEqual(result, ExitCode.PARTIAL)
self.assertIn("$['text']", output.getvalue())
def test_manual_resolution_with_no_actions_is_safe(self) -> None:
module = self.modules["resolve_manual"]
with tempfile.TemporaryDirectory() as directory: