mike-backend / backend /python-service /tests /test_comment_target_resolver.py
bardd's picture
Deploy Mike backend-only Space
06671aa verified
Raw History Blame Contribute Delete
8.22 kB
from __future__ import annotations
import sys
import os
import pytest
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
from comment_target_resolver import (
_build_char_map,
_normalize_for_match,
_find_all,
_resolve_target_in_paragraph,
resolve_single_target,
ResolveResult,
)
from models import ParagraphText
class TestCharMap:
def test_basic(self):
cm = _build_char_map("Hello World")
assert cm.normalized == "HelloWorld"
assert cm.orig_offsets == [0, 1, 2, 3, 4, 6, 7, 8, 9, 10]
def test_nbsp_stripped(self):
cm = _build_char_map("Hello\u00a0World")
assert cm.normalized == "HelloWorld"
def test_nbsp_offsets(self):
cm = _build_char_map("A\u00a0B")
assert cm.normalized == "AB"
assert cm.orig_offsets == [0, 2]
def test_nbsp(self):
cm = _build_char_map("Hello\u00a0World")
assert cm.normalized == "HelloWorld"
def test_smart_quotes(self):
cm = _build_char_map("\u201cHello\u201d")
assert cm.normalized == '"Hello"'
def test_em_dash(self):
cm = _build_char_map("A\u2014B")
assert cm.normalized == "A-B"
class TestNormalize:
def test_missing_spaces(self):
norm = _normalize_for_match("the Sellershall")
assert norm == "theSellershall"
def test_nbsp_normalized(self):
norm = _normalize_for_match("Hello\u00a0World")
assert norm == "HelloWorld"
def test_spaces_stripped(self):
norm = _normalize_for_match("The Seller shall")
assert norm == "TheSellershall"
class TestFindAll:
def test_single(self):
assert _find_all("abc", "b") == [1]
def test_multiple(self):
assert _find_all("ababa", "a") == [0, 2, 4]
def test_none(self):
assert _find_all("abc", "z") == []
class TestResolveTargetInParagraph:
def test_exact_match(self):
result = _resolve_target_in_paragraph(
"The Seller shall deliver the goods promptly.",
"shall deliver the goods",
"", "",
)
assert result is not None
assert result.strategy == "exact"
assert result.confidence == 1.0
assert result.target_text == "shall deliver the goods"
def test_exact_match_with_anchors(self):
result = _resolve_target_in_paragraph(
"The Seller shall deliver the goods promptly.",
"shall deliver the goods",
"Seller ",
" promptly",
)
assert result is not None
assert result.strategy == "exact"
assert result.was_resolved is False
assert result.before_anchor == "Seller "
assert result.after_anchor == " promptly"
def test_missing_spaces(self):
result = _resolve_target_in_paragraph(
"The Seller shall not be liable for any loss of revenue.",
"the Sellershall not be liable for anyloss of revenue",
"", "",
)
assert result is not None
assert result.strategy == "whitespace_normalized"
assert "Seller shall not be liable for any loss of revenue" in result.target_text
def test_missing_spaces_around_parens(self):
result = _resolve_target_in_paragraph(
"ABC Construction Ltd (The Buyer)",
"ABC Construction Ltd(TheBuyer)",
"", "",
)
assert result is not None
assert result.strategy == "whitespace_normalized"
assert result.target_text == "ABC Construction Ltd (The Buyer)"
def test_missing_space_after_punctuation(self):
result = _resolve_target_in_paragraph(
"from the factory. This warranty extends only to",
"factory.This warrantyextendsonly to",
"", "",
)
assert result is not None
assert result.strategy == "whitespace_normalized"
assert "factory. This warranty extends only" in result.target_text
def test_nbsp_vs_space(self):
result = _resolve_target_in_paragraph(
"The\u00a0materials remain the sole property of the Seller",
"The materials remain the sole property ofthe Seller",
"", "",
)
assert result is not None
assert result.strategy == "whitespace_normalized"
def test_smart_quotes(self):
result = _resolve_target_in_paragraph(
'He said \u201cno liability\u201d for damages.',
'He said "no liability" for damages',
"", "",
)
assert result is not None
assert result.strategy == "whitespace_normalized"
def test_em_dash(self):
result = _resolve_target_in_paragraph(
"Payment \u2014 if delayed \u2014 incurs interest.",
"Payment - if delayed - incurs interest.",
"", "",
)
assert result is not None
def test_duplicate_with_anchors(self):
para = "The Seller shall deliver. The Seller shall deliver promptly."
result = _resolve_target_in_paragraph(
para,
"The Sellershall deliver",
"The Seller", "promptly",
)
assert result is not None
assert result.strategy in ("anchor_normalized", "whitespace_normalized")
def test_no_match_returns_none(self):
result = _resolve_target_in_paragraph(
"Completely unrelated text here.",
"The Seller shall not be liable",
"", "",
)
assert result is None
def test_sentence_fallback(self):
para = "The Seller reserves all rights under this clause. The Buyer shall pay within 30 days. Force majeure does not apply."
result = _resolve_target_in_paragraph(
para,
"The Sellerreserves all rightsunder this clause",
"", "",
)
assert result is not None
assert result.strategy in ("whitespace_normalized", "sentence_fallback")
assert "The Seller reserves all rights under this clause" in result.target_text
def test_sentence_fallback_low_confidence_fails(self):
para = "The Seller reserves all rights. The Buyer shall pay. Force majeure does not apply."
result = _resolve_target_in_paragraph(
para,
"completely different and unrelated gibberish text",
"", "",
)
assert result is None
class TestResolveSingleTarget:
def test_with_paragraph_list(self):
paragraphs = [
ParagraphText(id="P_0001", text="The Seller shall deliver the goods."),
ParagraphText(id="P_0002", text="The Buyer shall pay the price."),
]
result = resolve_single_target(
paragraphs, "P_0001",
"the Sellershall deliver the goods",
"", "",
)
assert result.strategy == "whitespace_normalized"
assert result.paragraph_id == "P_0001"
assert "The Seller shall deliver the goods" in result.target_text
def test_missing_paragraph(self):
paragraphs = [
ParagraphText(id="P_0001", text="Some text."),
]
result = resolve_single_target(
paragraphs, "P_9999",
"Some text",
"", "",
)
assert result.strategy == "not_resolved"
assert result.confidence == 0.0
def test_paragraph_fallback(self):
paragraphs = [
ParagraphText(id="P_0001", text="Short paragraph here."),
]
result = resolve_single_target(
paragraphs, "P_0001",
"totally unrelated",
"", "",
allow_paragraph_fallback=True,
)
assert result.strategy == "paragraph_fallback"
def test_paragraph_fallback_disabled(self):
paragraphs = [
ParagraphText(id="P_0001", text="Short paragraph here."),
]
result = resolve_single_target(
paragraphs, "P_0001",
"totally unrelated",
"", "",
allow_paragraph_fallback=False,
)
assert result.strategy == "not_resolved"
assert result.confidence == 0.0
if __name__ == "__main__":
pytest.main([__file__, "-v"])