| """Phrase-level rewrite tests (verb–object spans).""" |
|
|
| from __future__ import annotations |
|
|
| import app.engine.phrase as phrase |
| from app.engine.phrase import rewrite_phrases |
|
|
|
|
| def test_positive_attitude_becomes_mindset_or_outlook(): |
| source = "They maintain a positive attitude." |
| result = rewrite_phrases(source, polish=True, use_t5=False, max_changes=1) |
| low = result.text.lower() |
| assert result.changes |
| assert "attitude" not in low or "mindset" in low or "outlook" in low |
| assert "acceptance" not in low |
| assert "defensive" not in low |
| assert "regard" not in low |
| assert any( |
| "mindset" in change.replacement.lower() |
| or "outlook" in change.replacement.lower() |
| for change in result.changes |
| ) |
|
|
|
|
| def test_customer_experience_is_not_world_or_living(): |
| source = ( |
| "Employees help create a satisfying customer experience for shoppers." |
| ) |
| result = rewrite_phrases(source, polish=True, use_t5=False, max_changes=2) |
| low = result.text.lower() |
| assert "customer world" not in low |
| assert "customer living" not in low |
| assert "customer souvenir" not in low |
| assert "customer experience" in low or not result.changes |
|
|
|
|
| def test_identify_areas_is_not_named_by_phrase(): |
| source = ( |
| "Businesses that listen to feedback can identify areas for improvement." |
| ) |
| result = rewrite_phrases(source, polish=True, use_t5=False, max_changes=2) |
| low = result.text.lower() |
| assert "name areas" not in low |
| assert "call areas" not in low |
| assert "identify" in low |
|
|
|
|
| def test_strengthen_loyalty_uses_t5_span_when_available(monkeypatch): |
| source = "Businesses strengthen customer loyalty." |
|
|
| def fake_t5(span_text: str, num_return: int = 4): |
| assert "strengthen" in span_text.lower() |
| return ["build customer loyalty", "boost customer loyalty"] |
|
|
| monkeypatch.setattr(phrase, "_t5_span_candidates", fake_t5) |
| result = rewrite_phrases(source, polish=True, use_t5=True, max_changes=1) |
| low = result.text.lower() |
| assert result.changes |
| assert "build customer loyalty" in low or "boost customer loyalty" in low |
| assert "tone customer" not in low |
| assert "allegiance" not in low |
|
|
|
|
| def test_phrase_does_not_cascade_same_verb(): |
| source = "They maintain a positive attitude." |
| result = rewrite_phrases(source, polish=True, use_t5=False, max_changes=2) |
| assert len(result.changes) == 1 |
|
|
|
|
| def test_t5_prompt_leak_and_clause_flip_are_rejected(monkeypatch): |
| source = "create a satisfying customer experience" |
|
|
| def fake_t5(span_text: str, num_return: int = 4): |
| return [ |
| "Create a satisfying customer experience with different wording but the same meaning :", |
| "Customer loyalty strengthens", |
| "create a satisfying customer experience to create", |
| "customer loyalty strengthens", |
| "build a satisfying customer experience", |
| ] |
|
|
| monkeypatch.setattr(phrase, "_t5_span_candidates", fake_t5) |
| |
| monkeypatch.setattr(phrase, "_wordnet_span_candidates", lambda *a, **k: []) |
| result = rewrite_phrases( |
| "Employees help create a satisfying customer experience.", |
| polish=True, |
| use_t5=True, |
| max_changes=1, |
| ) |
| low = result.text.lower() |
| assert "different wording" not in low |
| assert "same meaning" not in low |
| assert "customer loyalty strengthens" not in low |
| assert "to create" not in low |
| if result.changes: |
| assert "build a satisfying customer experience" in low |
|
|
|
|
| def test_span_candidate_ok_filters_prompt_echo(): |
| from app.engine.paraphrase import _span_candidate_ok |
|
|
| source = "strengthen customer loyalty" |
| assert _span_candidate_ok(source, "build customer loyalty") |
| assert not _span_candidate_ok( |
| source, |
| "Create a satisfying customer experience with different wording but the same meaning :", |
| ) |
| assert not _span_candidate_ok(source, "Customer loyalty strengthens") |
|
|