# Copyright (c) 2026 Lark Technologies Pte. Ltd. # SPDX-License-Identifier: MIT from __future__ import annotations import unittest import xml_text_overlap_lint class XmlTextOverlapLintTest(unittest.TestCase): def assertNoXmlTextOverlapLintIssues(self, result: dict, sample_name: str) -> None: issue_summaries = [] for slide in result.get("slides", []): for issue in slide.get("issues", []): issue_summaries.append( f"slide {slide['slide_number']}: {issue['level']} {issue['code']} {issue['message']}" ) if result.get("issues"): for issue in result["issues"]: issue_summaries.append(f"{issue['level']} {issue['code']} {issue['message']}") self.assertEqual( result["summary"]["error_count"], 0, f"{sample_name} has XML text overlap lint errors:\n" + "\n".join(issue_summaries), ) self.assertEqual( result["summary"]["warning_count"], 0, f"{sample_name} has XML text overlap lint warnings:\n" + "\n".join(issue_summaries), ) def test_xml_text_overlap_lint_accepts_inline_fixture_xml_samples(self) -> None: samples = { "image-led-cover": """

Quarterly Review

Focus, progress, and next steps

""", "content-grid": """

Execution Snapshot

Plan

Build

Launch

""", } self.assertTrue(samples) for sample_name, sample_xml in samples.items(): with self.subTest(sample=sample_name): result = xml_text_overlap_lint.lint_xml( sample_xml, sample_name, ) self.assertNoXmlTextOverlapLintIssues(result, sample_name) def test_lint_xml_reports_unescaped_ampersand_in_text(self) -> None: result = xml_text_overlap_lint.lint_xml( """

Q&A

""" ) issue = result["issues"][0] self.assertEqual(result["summary"]["error_count"], 1) self.assertEqual(issue["code"], "xml_not_well_formed") self.assertIsInstance(issue["line"], int) self.assertIsInstance(issue["column"], int) self.assertIn("Q&A", issue["context"]) self.assertIn("&", issue["hint"]) def test_lint_xml_reports_unescaped_ampersand_in_attribute(self) -> None: result = xml_text_overlap_lint.lint_xml( """

link

""" ) issue = result["issues"][0] self.assertEqual(issue["code"], "xml_not_well_formed") self.assertIn("attribute", issue["hint"]) self.assertIn("a=1&b=2", issue["hint"]) def test_lint_xml_accepts_escaped_entities_without_suspicious_entity_warning(self) -> None: result = xml_text_overlap_lint.lint_xml( """

Q&A

""" ) self.assertEqual(result["summary"]["error_count"], 0) self.assertNotIn("issues", result) def test_lint_xml_accepts_chinese_full_width_punctuation(self) -> None: result = xml_text_overlap_lint.lint_xml( """

承诺:按期交付;持续复盘|风险透明

""" ) self.assertEqual(result["summary"]["error_count"], 0) def test_lint_xml_single_slide_uses_default_canvas_without_bounds_checks(self) -> None: result = xml_text_overlap_lint.lint_xml( """

Body text outside the canvas

""" ) self.assertEqual(result["slide_size"], {"width": 960, "height": 540}) self.assertEqual(result["summary"]["slide_count"], 1) self.assertEqual(result["summary"]["error_count"], 0) def test_lint_xml_detects_overlapping_text_boxes(self) -> None: result = xml_text_overlap_lint.lint_xml( """

Title

Body

""" ) self.assertEqual(result["summary"]["error_count"], 1) self.assertEqual(result["slides"][0]["issues"][0]["code"], "bbox_overlap") def test_lint_xml_does_not_check_bounds_or_text_height(self) -> None: result = xml_text_overlap_lint.lint_xml( """

This paragraph is intentionally much longer than the box can safely contain.

Body text outside the canvas

""" ) self.assertEqual(result["summary"]["error_count"], 0) self.assertEqual(result["summary"]["warning_count"], 0) def test_lint_xml_allows_template_style_bleed_and_text_over_images(self) -> None: result = xml_text_overlap_lint.lint_xml( """

Title

Subtitle

""" ) self.assertEqual(result["summary"]["error_count"], 0) self.assertEqual(result["summary"]["warning_count"], 0) def test_lint_xml_does_not_check_small_out_of_bounds_elements(self) -> None: result = xml_text_overlap_lint.lint_xml( """ """ ) self.assertEqual(result["summary"]["error_count"], 0) def test_lint_xml_ignores_obviously_misplaced_large_visuals(self) -> None: result = xml_text_overlap_lint.lint_xml( """ """ ) self.assertEqual(result["summary"]["error_count"], 0) def test_lint_xml_allows_reasonable_large_visual_bleed(self) -> None: result = xml_text_overlap_lint.lint_xml( """ """ ) self.assertEqual(result["summary"]["error_count"], 0) def test_lint_xml_detects_invalid_template_text_stack_overlap(self) -> None: cases = [ ( "subtitle-too-high", """

Title

Subtitle

""", ), ] for name, shapes in cases: with self.subTest(name=name): result = xml_text_overlap_lint.lint_xml( f""" {shapes} """ ) self.assertEqual(result["summary"]["error_count"], 1) self.assertEqual(result["slides"][0]["issues"][0]["code"], "bbox_overlap") if __name__ == "__main__": unittest.main()