Miscs improvements (Interro02)

This commit is contained in:
2026-09-15 14:18:22 +02:00
parent 0a86403ca6
commit 9b22a8a137
15 changed files with 893 additions and 118 deletions
+106 -2
View File
@@ -46,6 +46,7 @@ from copienator_gui.app import (
from copienator_gui.diagnostics import collect_diagnostics
from copienator_gui.runner import ProcessRunner
from copienator_gui.state import StateStore
from copienator_gui import workflow as workflow_module
from copienator_gui.workflow import build_command, build_workflow, evaluation_argument
from copienator.commands.copies_tools import rename_all, rotate_all
from copienator.platform import (
@@ -490,7 +491,7 @@ class StandardCliTests(unittest.TestCase):
"giving_names": (
"giving_names",
"default",
{"target": evaluation, "annotation_dir": "BGnot"},
{"target": evaluation, "annotation_dir": "BGnot", "update": True},
),
"grouping": ("grouping", "default", {"target": evaluation}),
"post_correction": (
@@ -1225,6 +1226,27 @@ class StandardCliTests(unittest.TestCase):
self.assertEqual(module.results, {"Ex 1": []})
self.assertEqual(module.tasks_to_process, [("new.jpg", "Ex 1")])
def test_correction_reserves_unique_group_indices_concurrently(self) -> None:
module = self.modules["correction"]
with tempfile.TemporaryDirectory() as directory:
groups = Path(directory) / "Par label"
label_dir = groups / "Ex 8 : 2)"
label_dir.mkdir(parents=True)
(label_dir / "Group_3.jpg").write_bytes(b"existing")
with patch.object(module, "GROUPS_DIR", groups):
module.reserved_group_indices.clear()
with ThreadPoolExecutor(max_workers=8) as executor:
indices = list(
executor.map(
module.reserve_next_group_idx,
["Ex 8 : 2)"] * 8,
)
)
self.assertEqual(sorted(indices), list(range(3, 11)))
self.assertEqual(len(indices), len(set(indices)))
def test_correction_reset_restores_old_and_deletes_new_files(self) -> None:
module = self.modules["correction"]
with tempfile.TemporaryDirectory() as directory:
@@ -1333,6 +1355,43 @@ class StandardCliTests(unittest.TestCase):
def test_post_correction_main_cleans_json_atomically(self) -> None:
module = self.modules["post_correction"]
cleaned_text = module.clean_string(
r"outside_name already\_escaped; "
r"bad $\\mathbb{U}_n = \\{z \\in \\mathbb{C}\\}$; "
r"valid $\begin{cases} A=0 \\ B=1 \end{cases}$",
{},
)
self.assertEqual(
cleaned_text,
r"outside\_name already\_escaped; "
r"bad $\mathbb{U}_n = \{z \in \mathbb{C}\}$; "
r"valid $\begin{cases} A=0 \\ B=1 \end{cases}$",
)
self.assertEqual(module.clean_string(cleaned_text, {}), cleaned_text)
corrupted_json_escapes = (
"Formulas $"
+ "\x0c"
+ "rac{1}{2}$, $"
+ "\t"
+ "heta "
+ "\x0c"
+ "euille 0 [2"
+ "\t"
+ "extbackslash pi]$, $e "
+ "\t"
+ "imes x$, and ["
+ "\n"
+ "egthinspace[0,n]"
)
self.assertEqual(
module.clean_string(corrupted_json_escapes, {}),
r"Formulas $\frac{1}{2}$, $\theta \equiv 0 [2\pi]$, "
r"$e \times x$, and [\negthinspace[0,n]",
)
self.assertEqual(
module.clean_string("x ∈ A and B ⊂ C", {}),
r"x \ensuremath{\in} A and B \ensuremath{\subset} C",
)
with tempfile.TemporaryDirectory() as directory:
evaluation = Path(directory) / "Exam"
evaluation.mkdir()
@@ -1892,6 +1951,12 @@ class WorkflowTests(unittest.TestCase):
self.assertTrue(spec.help.strip())
self.assertTrue(spec.help.rstrip().endswith("."))
def test_final_score_documents_immediate_gestion_classe_prerequisite(self) -> None:
description = self.steps["final_score"].description
self.assertIn("gestion_classe wse", description)
self.assertIn("juste avant", description)
self.assertIn("histogramme.pdf", description)
def test_options_previously_requiring_free_form_arguments_have_controls(self) -> None:
status = self.command(
"batch_status",
@@ -1914,7 +1979,46 @@ class WorkflowTests(unittest.TestCase):
)
self.assertEqual(
command_arguments(grouped),
[self.evaluation, "--refaire", "--annotation-dir", "Bnot"],
[
self.evaluation,
"--refaire",
"--annotation-dir",
"Bnot",
"--no-return-answers-context",
"--return-answers-question",
"--return-answers-solution",
],
)
def test_return_answer_controls_follow_configuration_and_can_be_hidden(self) -> None:
with patch.multiple(
workflow_module.configuration,
RETURN_ANSWERS_ENABLED=True,
RETURN_ANSWERS_CONTEXT=True,
RETURN_ANSWERS_QUESTION=False,
RETURN_ANSWERS_SOLUTION=True,
):
step = next(
item for item in build_workflow(True) if item.id == "read_annotations"
)
specs = {spec.name: spec for spec in step.arguments}
self.assertIs(specs["return_answers_context"].default, True)
self.assertIs(specs["return_answers_question"].default, False)
self.assertIs(specs["return_answers_solution"].default, True)
with patch.object(
workflow_module.configuration, "RETURN_ANSWERS_ENABLED", False
):
hidden_step = next(
item for item in build_workflow(True) if item.id == "read_annotations"
)
self.assertFalse(
{
"return_answers_context",
"return_answers_question",
"return_answers_solution",
}
& {spec.name for spec in hidden_step.arguments}
)
def test_verbose_is_added_only_to_commands_that_support_it(self) -> None: