""" Test that plain output preserves input exactly except for markup. Output should equal: input.replace("^", "").replace("_", "") """ import pytest import sys import html import re from pathlib import Path # Add parent directory to path to import app module sys.path.insert(0, str(Path(__file__).parent.parent)) from app import ( DEFAULT_MODEL_ID, DEFAULT_MODEL_LABEL, MODEL_OPTIONS, _resolve_model_id, _render_plain_line_per_word, _render_styled_line_per_word, macronize, macronize_ui, preprocess_and_syllabify, ) def strip_markup(text: str) -> str: """Remove markup characters from text.""" return text.replace("^", "").replace("_", "") def strip_color(text: str) -> str: """Remove pretty-output color markup.""" return html.unescape(re.sub(r"?span[^>]*>", "", text)) # Test cases with Greek lines TEST_CASES = [ # Basic simple word "νεανίας", # Multiple words with spaces "νεανίας ἀάατός ἐστιν", # With final sigma "καὶ καλός", # Multiple spaces "καλὰ μὲν", # Single letter "ἢ", # Word with punctuation preserved "τυφλὸς ἤ", # Multi-word with accents "Ἀτρεΐδαι τε καὶ ἄλλοι", # Longer passage "νεανίας ἀάατός ἐστιν καὶ καλός", # Expanded ξ and trailing comma must be restored exactly "καλὰ μὲν ἠέξευ, καλὰ δ᾽ ἔτραφες, οὐράνιε Ζεῦ", ] @pytest.mark.parametrize("input_line", TEST_CASES) def test_plain_output_preserves_input_without_markup(input_line): """ Test that the plain output is identical to input after removing markup. The output should be: input.replace("^", "").replace("_", "") This ensures: - All original characters are preserved - Spaces are preserved exactly - Final sigmas are preserved - Only the markup (^ and _) are added """ # Get the rendered plain line plain_output = _render_plain_line_per_word(input_line, DEFAULT_MODEL_ID) # Strip markup from the output to get back the base text output_without_markup = strip_markup(plain_output) # The expected result: input with no markup # (We don't normalize final sigma - we preserve exactly what was in the input) input_expected = input_line print(f"\nInput: {repr(input_line)}") print(f"Output: {repr(plain_output)}") print(f"Output without markup: {repr(output_without_markup)}") print(f"Expected: {repr(input_expected)}") # The core assertion: output without markup should match input assert output_without_markup == input_expected, ( f"Output without markup doesn't match input.\n" f"Expected: {repr(input_expected)}\n" f"Got: {repr(output_without_markup)}" ) def test_styled_output_uses_plain_formatting_with_colored_vowels(monkeypatch): input_line = "νεανίας ἀάατός ἐστιν καὶ καλός. τὰ παῖδες τὰ καλά" labels_by_word = { "νεανίασ": [("νε", 0), ("α", 1), ("νί", 2), ("ασ", 0)], "ἀάατόσ": [("ἀ", 2), ("ά", 1), ("α", 2), ("τόσ", 0)], "ἐστιν": [("ἐσ", 0), ("τιν", 2)], "καὶ": [("καὶ", 0)], "καλόσ.": [("κα", 2), ("λό", 0), ("σ.", 0)], "τὰ": [("τὰ", 2)], "παῖδεσ": [("παῖ", 0), ("δεσ", 0)], "καλά": [("κα", 1), ("λά", 1)], } def fake_classify_line(word, model_id): return labels_by_word[word] monkeypatch.setattr("app.classify_line", fake_classify_line) styled_output = _render_styled_line_per_word(input_line, DEFAULT_MODEL_ID) expected = ( 'νε' 'α' 'νί' 'ας ' 'ἀ' 'ά' 'α' 'τός ' 'ἐστιν ' 'καὶ ' 'καλός. ' 'τὰ ' 'παῖδες ' 'τὰ ' 'καλά' ) assert styled_output == expected assert "vowel clear" not in styled_output @pytest.mark.parametrize("input_line", TEST_CASES) def test_styled_output_preserves_input_without_color(monkeypatch, input_line): def fake_classify_line(word, model_id): return [ (syllable, 1 if idx % 2 == 0 else 2) for idx, syllable in enumerate(preprocess_and_syllabify(word)) ] monkeypatch.setattr("app.classify_line", fake_classify_line) styled_output = _render_styled_line_per_word(input_line, DEFAULT_MODEL_ID) assert strip_color(styled_output) == input_line def test_plain_output_box_contains_only_output_lines(monkeypatch): monkeypatch.setattr("app._render_plain_line_per_word", lambda line, model_id: f"marked {line}") monkeypatch.setattr("app._render_styled_line_per_word", lambda line, model_id: line) html_output, plain_output = macronize_ui("alpha\nbeta", DEFAULT_MODEL_LABEL) assert plain_output == "marked alpha\nmarked beta" assert '