File size: 8,018 Bytes
8f6d79d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7b67b50
8f6d79d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7b67b50
 
 
 
 
 
 
 
 
 
8f6d79d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39cfcd1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7b67b50
8f6d79d
 
 
7b67b50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67f284e
7b67b50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8f6d79d
 
c212805
 
 
 
 
 
 
 
 
 
 
 
8f6d79d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
"""Short-document structural rewrite tests."""

from __future__ import annotations

import os

# Keep tests offline and fast — no LanguageTool / MiniLM
os.environ.setdefault("LANGUAGE_TOOL_ENABLED", "false")
os.environ.setdefault("LANGUAGE_TOOL_URL", "")
os.environ.setdefault("GRAMMAR_FIX_OUTPUT", "false")
os.environ.setdefault("ENGINE_USE_MINILM_SAFETY", "false")

from app.engine.classify import classify_sentence
from app.engine.orchestrator import rewrite_document
from app.engine.plan import build_plan
from app.engine.rewrite import generate_from_plan
from app.engine.voice import active_to_passive


def test_ram_school_reorder():
    src = "Ram went to school yesterday happily."
    result = rewrite_document(src)
    out = result.text.strip().rstrip(".")
    # Accept either full template or time-front
    assert "Yesterday" in result.text
    assert "Ram" in result.text
    assert "school" in result.text.lower()
    assert "happily" in result.text.lower()
    assert "went" in result.text.lower()
    # Should not be identical
    assert result.text.strip().lower() != src.strip().lower()
    rewritten = [s for s in result.sentences if s.status == "rewritten"]
    assert rewritten, f"expected rewrite, got {result.sentences}"


def test_negation_preserved():
    src = "Ram did not go to school yesterday."
    result = rewrite_document(src)
    low = result.text.lower()
    assert "not" in low or "n't" in low
    assert "ram" in low


def test_entity_preserved():
    src = "Alice visited Paris yesterday happily."
    result = rewrite_document(src)
    assert "Alice" in result.text
    assert "Paris" in result.text


def test_url_and_email_passthrough():
    src = (
        "Please read https://example.com/docs carefully today.\n\n"
        "Contact support at help@example.com for details."
    )
    result = rewrite_document(src)
    assert "https://example.com/docs" in result.text
    assert "help@example.com" in result.text


def test_email_placeholder_is_fully_restored_after_rewrite():
    src = "Alice emailed the invoice to bob@example.com on July 12 carefully."
    result = rewrite_document(src)
    assert "bob@example.com" in result.text
    assert "PROTECTED" not in result.text
    assert result.text == (
        "On July 12, Alice emailed the invoice carefully to bob@example.com."
    )


def test_heading_and_list_untouched():
    src = (
        "# Introduction\n\n"
        "Ram went to school yesterday happily.\n\n"
        "- First bullet item here\n"
        "- Second bullet item here"
    )
    result = rewrite_document(src)
    assert "# Introduction" in result.text or "Introduction" in result.text
    assert "- First bullet item here" in result.text
    assert "- Second bullet item here" in result.text


def test_code_block_untouched():
    src = (
        "Ram went to school yesterday happily.\n\n"
        "```python\nprint('hello')\n```\n\n"
        "Bob walked home today slowly."
    )
    result = rewrite_document(src)
    assert "```python" in result.text
    assert "print('hello')" in result.text


def test_multiline_table_and_formula_untouched():
    table = "| Name | Score |\n| --- | ---: |\n| Ram | 42 |"
    formula = "$$\nE = mc^2\n$$"
    src = f"{table}\n\n{formula}"
    result = rewrite_document(src)
    assert table in result.text
    assert formula in result.text
    assert all(record.status == "passthrough" for record in result.sentences)


def test_citation_sentence_untouched():
    src = "The result improved significantly (Smith et al., 2020)."
    result = rewrite_document(src)
    assert result.text == src
    assert result.sentences[0].status == "skipped"
    assert result.sentences[0].sentence_type == "citation"


def test_safe_initial_complex_clause_reordered():
    src = "Although the weather was bad, Ram went to school yesterday."
    result = rewrite_document(src)
    assert classify_sentence(src) == "complex"
    assert result.text == "Ram went to school yesterday, although the weather was bad."
    assert result.sentences[0].status == "rewritten"
    assert result.sentences[0].template_id == "complex_clause_swap"


def test_when_clause_reordered_from_dependency_parse():
    src = "When the meeting ended, everyone returned to their offices quietly."
    result = rewrite_document(src)
    assert result.text == (
        "Everyone returned to their offices quietly when the meeting ended."
    )
    assert result.sentences[0].status == "rewritten"


def test_relative_clause_without_safe_move_is_skipped():
    src = "They contain thousands of books that provide information on many subjects."
    result = rewrite_document(src, force_rewrite=False)
    assert classify_sentence(src) == "complex"
    assert result.text == src
    assert result.sentences[0].status == "skipped"


def test_time_preposition_moves_with_expression():
    src = "Maria submitted the final report on Monday carefully."
    result = rewrite_document(src)
    assert result.text == "On Monday, Maria carefully submitted the final report."
    assert not result.text.rstrip(".").endswith(" on")


def test_dynamic_passive_fallback_handles_complex_object():
    src = (
        "Technology has transformed the way students learn and teachers "
        "deliver instruction."
    )
    result = rewrite_document(src)
    assert result.text == (
        "The way students learn and teachers deliver instruction has been "
        "transformed by technology."
    )
    assert result.sentences[0].template_id == "active_to_passive"


def test_dynamic_passive_fallback_handles_result_complement():
    src = (
        "Online learning platforms, digital textbooks, and interactive educational "
        "tools have made education more accessible than ever before."
    )
    result = rewrite_document(src)
    assert result.text == (
        "Education has been made more accessible than ever before by online "
        "learning platforms, digital textbooks, and interactive educational tools."
    )
    assert result.sentences[0].template_id == "active_to_passive"


def test_passive_conversion_is_not_forced_on_intransitive_sentence():
    assert active_to_passive("Ram slept peacefully.") is None


def test_dynamic_passive_preserves_tense_aspect_and_modals():
    assert active_to_passive("The team completed the task.") == (
        "The task was completed by the team."
    )
    assert active_to_passive("The team can complete the task.") == (
        "The task can be completed by the team."
    )
    assert active_to_passive("The team is reviewing the proposal.") == (
        "The proposal is being reviewed by the team."
    )
    assert active_to_passive("The team has completed the tasks.") == (
        "The tasks have been completed by the team."
    )


def test_short_comma_openers_are_not_moved_into_invalid_positions():
    source = (
        "Daily, planning tasks and setting priorities efficiently allow "
        "people to complete their work more. Also, avoiding procrastination "
        "and focusing on one task at a time improves productivity."
    )
    result = rewrite_document(source)
    assert "Efficiently, Daily" not in result.text
    assert "time Also improves" not in result.text
    assert "allow more people to complete their work more" not in result.text


def test_structured_output_fields():
    src = "Ram went to school yesterday happily."
    result = rewrite_document(src)
    assert result.sentences
    assert result.mapping
    assert result.stats.sentences >= 1
    assert result.engine == "structural-reorder"


def test_plan_then_generate():
    src = "Ram went to school yesterday happily."
    plan = build_plan(src)
    assert plan.safe
    text = generate_from_plan(plan)
    assert text
    assert "Yesterday" in text or "happily" in text.lower()