"""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()