Allow signaling issues in label verification

This commit is contained in:
sebastien committed 2026-10-11 21:05:27 +02:00
1 parent 3754c0c11a
commit 9925362352
21 files changed
+1347 -36

No files matched your search

+110
View File
@@ -0,0 +1,110 @@
import tempfile
import unittest
from pathlib import Path
from types import SimpleNamespace
from unittest.mock import patch
from PIL import Image
from reportlab.pdfgen import canvas
from copienator.commands.reading_grouped_annotations import (
context_content_key, get_extra_pdfs_as_images, save_paginated_pdf,
)
class PdfSupplementTests(unittest.TestCase):
def setUp(self):
temporary = tempfile.TemporaryDirectory()
self.addCleanup(temporary.cleanup)
self.root = Path(temporary.name)
(self.root / "Text2").mkdir()
(self.root / "Sol2").mkdir()
self.labels = ["Q1", "Q2", "Q3"]
self.rendered = []
def render(path):
self.rendered.append(Path(path).name)
return Image.new("RGB", (100, 30), "white"), 30, 100
self.renderer = SimpleNamespace(make_base_image=render)
def pdf(self, folder, name, text):
path = self.root / folder / name
document = canvas.Canvas(str(path))
document.drawString(20, 800, text)
document.save()
return path
def extras(self, label, seen):
return get_extra_pdfs_as_images(
self.root, label, self.renderer, self.labels, seen_contexts=seen,
)
def test_content_deduplication_across_ranges_and_copy_reset(self):
self.pdf("Text2", "CTXT Q1 -> Q2.pdf", "Bob collects coupons: N >= 1")
self.pdf("Text2", "CTXT Q2 -> Q3.pdf", "Bob collects coupons: N >= 1")
self.pdf("Text2", "CTXT Q2 -> Q2.pdf", "Bob collects coupons: N >= 2")
seen = set()
self.assertEqual(len(self.extras("Q1", seen)), 1)
self.assertEqual(len(self.extras("Q2", seen)), 1)
self.assertEqual(len(self.extras("Q3", seen)), 0)
self.assertEqual(len(seen), 2)
self.assertEqual(len(self.extras("Q3", set())), 1)
def test_first_retained_question_gets_context_and_semantic_borders(self):
self.pdf("Text2", "CTXT Q1 -> Q3.pdf", "Context")
self.pdf("Text2", "CTXT Q2 -> Q3.pdf", "Other context")
self.pdf("Text2", "Q2.pdf", "Question")
self.pdf("Sol2", "Q2.pdf", "Solution")
# Q1 was filtered out; it never consumes the shared context.
images = self.extras("Q2", set())
self.assertEqual([i.getpixel((0, 0)) for i in images],
[(255, 255, 255), (255, 255, 255), (0, 0, 0), (0, 0, 255)])
self.assertTrue(all(i.getpixel((50, 15)) == (255, 255, 255) for i in images))
def test_missing_question_does_not_shift_solution_border(self):
self.pdf("Text2", "CTXT Q1 -> Q3.pdf", "Context")
self.pdf("Sol2", "Q2.pdf", "Solution")
images = self.extras("Q2", set())
self.assertEqual([i.getpixel((0, 0)) for i in images],
[(255, 255, 255), (0, 0, 255)])
def test_unrendered_context_is_not_consumed(self):
self.pdf("Text2", "CTXT Q1 -> Q3.pdf", "Context")
seen = set()
with patch.object(self.renderer, "make_base_image", return_value=(None, 0, 0)):
self.assertEqual(self.extras("Q1", seen), [])
self.assertFalse(seen)
self.assertEqual(len(self.extras("Q2", seen)), 1)
def test_missing_solution_does_not_shift_border_to_student_answer(self):
self.pdf("Text2", "Q2.pdf", "Question")
images = self.extras("Q2", set())
answer = Image.new("RGB", (100, 200), "white")
captured = []
def save(page, *args, **kwargs):
captured.extend([page.copy(), *kwargs['append_images']])
with patch.object(Image.Image, "save", save):
save_paginated_pdf([images + [answer], [answer]], self.root / "out.pdf")
self.assertEqual(len(captured), 2)
self.assertEqual(captured[0].getpixel((11, 7)), (0, 0, 0))
self.assertEqual(captured[0].getpixel((11, 37)), (255, 255, 255))
self.assertEqual(captured[1].getpixel((11, 7)), (255, 255, 255))
self.assertEqual(answer.getpixel((0, 0)), (255, 255, 255))
def test_empty_extracted_text_does_not_merge_distinct_contexts(self):
paths = []
for name, color in [("a.pdf", "red"), ("b.pdf", "blue")]:
path = self.root / name
document = canvas.Canvas(str(path))
document.setFillColor(color)
document.rect(20, 20, 100, 100, fill=1)
document.save()
paths.append(path)
self.assertNotEqual(context_content_key(paths[0]), context_content_key(paths[1]))
if __name__ == "__main__":
unittest.main()