This commit is contained in:
sebastien committed 2026-10-21 22:28:27 +02:00
1 parent 0d8970061e
commit c30aac0572
14 files changed
+343 -48

No files matched your search

+77
View File
@@ -208,6 +208,28 @@ class DispatcherTests(unittest.TestCase):
class AtomicJsonTests(unittest.TestCase):
def test_label_json_repairs_only_trailing_commas_and_preserves_strings(self) -> None:
text = '{"list": [{"label": "comma,] and ,} and \\\"quoted\\\"",},],}\n'
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "Copie01_01.json"
path.write_text(text)
with self.assertRaises(json.JSONDecodeError):
read_json(path)
value = read_json(path, repair_trailing_commas=True)
self.assertEqual(value, {"list": [{"label": 'comma,] and ,} and "quoted"'}]})
self.assertEqual(json.loads(path.read_text()), value)
self.assertEqual(path.read_text(), text.replace('",}', '"}').replace('},]', '}]').replace('],}', ']}'))
def test_trailing_comma_repair_preserves_other_invalid_json(self) -> None:
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "Copie01_01.json"
for text in ('[,]', '{,}', '[1,,]', '{"list": [1,], "bad": }', '[1,] garbage'):
with self.subTest(text=text):
path.write_text(text)
with self.assertRaises(json.JSONDecodeError):
read_json(path, repair_trailing_commas=True)
self.assertEqual(path.read_text(), text)
def test_atomic_binary_round_trip(self) -> None:
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "result.jsonl"
@@ -969,6 +991,27 @@ class StandardCliTests(unittest.TestCase):
[original],
)
def test_page_splitter_excludes_statement_aliases_from_copy_inputs(self) -> None:
module = self.modules["page_splitter"]
with tempfile.TemporaryDirectory() as directory:
root = Path(directory) / "DS02VA"
copies = root / "Copies"
copies.mkdir(parents=True)
workspace = EvaluationWorkspace(root)
# Recognize a spaced alias even after it has been moved out of root.
for name in ("enonce.pdf", "énoncé.pdf", "DS02 VA.pdf"):
(copies / name).touch()
copy = copies / "Copie01.pdf"
copy.touch()
self.assertEqual(module._selected_inputs(workspace, copies), [copy])
statement = root / "DS02 VA.pdf"
statement.touch()
copy = root / "Copie01.pdf"
copy.touch()
self.assertEqual(module._selected_inputs(workspace, root), [copy])
with self.assertRaises(CliError):
module._selected_inputs(workspace, statement)
def test_plotting_batch_save_is_atomic(self) -> None:
module = self.modules["plotting"]
with tempfile.TemporaryDirectory() as directory:
@@ -1105,6 +1148,40 @@ class StandardCliTests(unittest.TestCase):
previous_image, previous_json, previous_meta
)
def test_plotting_edit_prepares_only_the_last_label_comma(self) -> None:
module = self.modules["plotting"]
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "Copie01_01.json"
text = '{"name": "literal ] and ,}", "list": [{"box_2d": [1,2,3,4], "label": "Ex 1"}], "other": [1,2]}\n'
path.write_text(text)
viewer = module.ImageViewer.__new__(module.ImageViewer)
viewer.is_viewing = True
viewer.current_json_path = path
with patch.object(module, "open_path") as opened:
viewer.on_edit(None)
opened.assert_called_once_with(path)
expected = text.replace('"Ex 1"}]', '"Ex 1"},]')
self.assertEqual(path.read_text(), expected)
module.prepare_label_json_for_edit(path)
self.assertEqual(path.read_text(), expected)
# Pasting a new item works without adding a separator first.
path.write_text(expected.replace('},]', '}, {"label": "Ex 2"},]'))
self.assertEqual([item['label'] for item in read_json(path, repair_trailing_commas=True)['list']], ['Ex 1', 'Ex 2'])
def test_plotting_edit_preserves_empty_lists_and_other_json_errors(self) -> None:
module = self.modules["plotting"]
with tempfile.TemporaryDirectory() as directory:
path = Path(directory) / "Copie01_01.json"
for text in ('{"list": []}', '{"list": [oops]}'):
path.write_text(text)
viewer = module.ImageViewer.__new__(module.ImageViewer)
viewer.is_viewing = True
viewer.current_json_path = path
with patch.object(module, "open_path") as opened:
viewer.on_edit(None)
opened.assert_called_once_with(path)
self.assertEqual(path.read_text(), text)
def test_plotting_accepts_lowercase_and_uppercase_previous_shortcuts(self) -> None:
module = self.modules["plotting"]
root = Mock()