File size: 6,491 Bytes
ffb5352
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f47a29e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ffb5352
 
 
 
 
 
 
24a79a8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ffb5352
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
"""Voice flips, coordinated-verb splitting, and per-request structure rotation."""

from __future__ import annotations

from app.engine import orchestrator
from app.engine.split import try_split_coordinated_verbs, try_split_long_sentence
from app.engine.variation import rotate
from app.engine.voice import active_to_passive, passive_to_active


def test_passive_to_active_recovers_the_agent():
    text = (
        "Areas for improvement can be identified by businesses that actively "
        "listen to customer feedback."
    )
    assert passive_to_active(text) == (
        "Businesses that actively listen to customer feedback can identify "
        "areas for improvement."
    )


def test_passive_to_active_keeps_perfect_and_past_tense():
    assert passive_to_active("The budget has been approved by the committee.") == (
        "The committee has approved the budget."
    )
    assert passive_to_active("The report was reviewed by readers yesterday.") == (
        "Readers reviewed the report yesterday."
    )


def test_passive_to_active_needs_an_explicit_agent():
    assert passive_to_active("The window was broken.") is None


def test_passive_to_active_skips_negation_needing_do_support():
    # "The editor did not correct mistakes" cannot be built by surface rebuild.
    assert passive_to_active("Mistakes were not corrected by the editor.") is None


def test_active_to_passive_refuses_to_relocate_a_fronted_phrase():
    """Leftovers land after the agent, which would strip the opener's scope."""
    text = (
        "By consistently delivering high-quality service, organizations can "
        "establish a strong reputation."
    )
    assert active_to_passive(text) is None


def test_active_to_passive_refuses_to_strand_a_preverbal_adverb():
    assert active_to_passive(
        "Organizations can also encourage positive recommendations."
    ) is None
    assert active_to_passive("Maria carefully submitted the final report.") is None


def test_active_to_passive_keeps_hyphenated_compounds_intact():
    result = active_to_passive("The team published the high-quality version last week.")
    assert result == "The high-quality version was published by the team last week."


def test_active_and_passive_are_not_mutually_reachable():
    text = "Readers reviewed the report yesterday."
    passive = active_to_passive(text)
    assert passive is not None
    assert passive_to_active(passive) is not None


def test_active_to_passive_refuses_misattached_coordinate_tails():
    """spaCy may hang list verbs as advcl; rebuilding would strand them."""
    text = (
        "Customers appreciate companies that respond quickly to their questions, "
        "resolve issues efficiently, and treat them with respect."
    )
    assert active_to_passive(text) is None


def test_unfront_opener_moves_prepositional_prefix():
    from app.engine.templates import try_unfront_opener

    assert try_unfront_opener(
        "For the success of any business, supplying excellent customer service "
        "is vital."
    ) == (
        "Supplying excellent customer service is vital for the success of any "
        "business."
    )
    assert try_unfront_opener(
        "By consistently delivering high-quality service, organizations can "
        "establish a strong reputation."
    ) == (
        "Organizations can establish a strong reputation by consistently "
        "delivering high-quality service."
    )
    # Discourse connectives must stay fronted.
    assert try_unfront_opener(
        "However, the committee approved the budget today."
    ) is None


def test_coordinated_split_repeats_subject_instead_of_stranding_a_verb():
    text = (
        "By consistently delivering high-quality service, organizations can "
        "establish a strong reputation, gain customer retention, and encourage "
        "positive word-of-mouth recommendations."
    )
    assert try_split_coordinated_verbs(text) == (
        "By consistently delivering high-quality service, organizations can "
        "establish a strong reputation and gain customer retention. "
        "Organizations can also encourage positive word-of-mouth recommendations."
    )


def test_coordinated_split_refuses_ambiguous_relative_clause():
    """The verb list belongs to "organizations", not to "Customers"."""
    text = (
        "Customers appreciate organizations that respond promptly to their "
        "questions, resolve issues efficiently, and treat them with respect."
    )
    assert try_split_coordinated_verbs(text) is None


def test_plain_split_refuses_to_strand_a_bare_verb_phrase():
    text = (
        "By consistently delivering high-quality service, organizations can "
        "establish a strong reputation, gain customer retention, and encourage "
        "positive word-of-mouth recommendations."
    )
    result = try_split_long_sentence(text)
    assert result is None or "Encourage positive" not in result


def test_rotation_keeps_weak_options_behind_the_band():
    options = [("best", 0.90), ("near", 0.78), ("weak", 0.40)]
    for seed in range(6):
        ordered = rotate(
            options, seed=seed, confidence_of=lambda item: item[1]
        )
        assert ordered[-1] == ("weak", 0.40)
        assert set(ordered) == set(options)


def test_rotation_without_seed_preserves_order():
    options = [("a", 0.9), ("b", 0.8)]
    assert rotate(options, seed=None, confidence_of=lambda i: i[1]) == options


def test_same_sentence_takes_different_structures(structural_variation):
    text = "The teacher graded the papers carefully yesterday."
    outputs = {
        orchestrator.rewrite_document(
            text,
            use_lexical_refinement=False,
            use_paraphrase=False,
            use_minilm_safety=False,
        ).text
        for _ in range(12)
    }
    assert len(outputs) > 1
    for candidate in outputs:
        assert "teacher" in candidate
        assert "papers" in candidate


def test_directional_place_is_not_fronted():
    """"To school, Ram went" is marked; locative fronting stays available."""
    outputs = {
        orchestrator.rewrite_document(
            "Ram went to school yesterday happily.",
            use_lexical_refinement=False,
            use_paraphrase=False,
            use_minilm_safety=False,
            variation_seed=seed,
        ).text
        for seed in range(1, 10)
    }
    for candidate in outputs:
        assert not candidate.lower().startswith("to school,")