"""Deterministic comparison and callback regressions; no remote parsing.""" import unittest from unittest.mock import patch import app from core.conllu_utils import compare_trees def token(form="word", token_id="1", upos="NOUN", head="0", relation="root"): return f"{token_id}\t{form}\t_\t{upos}\t_\t_\t{head}\t{relation}\t_\t_\n" class ComparisonTests(unittest.TestCase): def compare(self, a, b): return compare_trees(a, "A", b, "B") def test_identical_and_annotation_differences(self): a = token() self.assertTrue(self.compare(a, a)["identical"]) for b, expected in ((token(upos="VERB"), "POS"), (token(head="2", relation="obj"), "Syntax Arc"), (token(upos="VERB", relation="obj"), "POS & Syntax")): with self.subTest(expected=expected): result = self.compare(a, b) self.assertFalse(result["identical"]) self.assertEqual(result["diff_table"].iloc[0]["Difference"], expected) def test_missing_data_never_establishes_identity(self): for a, b in ((token(), ""), ("", token()), ("", ""), (token(), "# comment\n")): with self.subTest(a=a, b=b): self.assertFalse(self.compare(a, b)["identical"]) def test_tokenization_mismatch_prevents_arc_comparison(self): for b, expected in ((token("other", upos="VERB"), "Token Alignment Mismatch"), (token(token_id="2"), "Token Alignment Mismatch"), (token() + token("extra", "2"), "Token Count Mismatch")): with self.subTest(expected=expected): result = self.compare(token(), b) self.assertFalse(result["identical"]) self.assertEqual(result["discrepancy_count"], 1) self.assertEqual(result["diff_table"].iloc[0]["Difference"], expected) self.assertIn("cannot be compared", result["diff_summary"]) def test_multiword_headers_and_empty_nodes_are_skipped(self): extra = token("combined", "1-2") + token("empty", "1.1") self.assertTrue(self.compare(token(), extra + token())["identical"]) class CallbackTests(unittest.TestCase): def run_callback(self, responses): with patch.object(app.client, "parse_sentence", side_effect=responses): result = app.run_single_or_compare( "English", "word", "UDPipe · english-ewt-ud-2.17-251125", True, "UDPipe · english-gum-ud-2.17-251125" ) self.assertEqual(len(result), 6) return result def test_result_freshness_tracks_every_parser_input(self): check = next(block.fn for block in app.demo.fns.values() if block.fn and block.fn.__name__ == "check_result_freshness") original = ("English", "word", "model-a", True, "model-b", False) self.assertEqual(check(*original, original, "comparison summary"), "comparison summary") for position, replacement in enumerate(("German", "new text", "other", False, "other", True)): changed = list(original) changed[position] = replacement self.assertIn("Input changed", check(*changed, original, "comparison summary")) def test_example_noop_keeps_fourteen_outputs(self): callback = next(block.fn for block in app.demo.fns.values() if block.fn and block.fn.__name__ == "on_example_input") self.assertEqual(len(callback(None, "English", "a", "b", False, None)), 14) def test_secondary_failure_preserves_primary_and_clears_differences(self): for response in ({"conllu": "", "error": "Timeout "}, {"conllu": "", "error": None}, {"conllu": "# comment\n", "error": None}): with self.subTest(response=response): result = self.run_callback([{"conllu": token(), "error": None}, response]) self.assertIn("", result[3]) self.assertFalse(result[4]["visible"]) self.assertTrue(result[5].empty) def test_primary_failure_clears_outputs(self): for response in ({"conllu": "", "error": "Timeout "}, {"conllu": "", "error": None}): result = self.run_callback([response]) self.assertIn("Error:", result[0]) self.assertNotIn("", result[0]) self.assertTrue(result[1].empty) self.assertEqual(result[2:4], ("", "")) self.assertFalse(result[4]["visible"]) self.assertTrue(result[5].empty) def test_successful_comparison_status(self): for b, identical in ((token(), True), (token("different"), False), (token(upos="VERB"), False)): result = self.run_callback([{"conllu": token(), "error": None}, {"conllu": b, "error": None}]) self.assertEqual("Matching analyses" in result[3], identical) self.assertEqual(result[4]["visible"], not identical) if __name__ == "__main__": unittest.main()