Allow signaling issues in label verification
This commit is contained in:
1 parent
3754c0c11a
commit
9925362352
21 files changed
+1347
-36
No files matched your search
@@ -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()
|
||||
Reference in new issue
Block a user