# tests/test_typograph.py # Тестирует основной класс Typographer и его конвейер обработки. import pytest from etpgrf import Typographer from etpgrf.config import CHAR_NBSP, CHAR_THIN_SP, CHAR_NDASH, CHAR_MDASH TYPOGRAPHER_HTML_TEST_CASES = [ # --- Базовая обработка без HTML --- ('mnemonic', 'Простой текст с "кавычками".', f'Простой текст с «кавычками».'), ('mixed', 'Простой текст с "кавычками".', f'Простой текст с «кавычками».'), ('unicode', 'Простой текст с "кавычками".', f'Простой текст с{CHAR_NBSP}«кавычками».'), # --- Базовая обработка с HTML --- ('mnemonic', '

Простой параграф с «кавычками».

', '

Простой параграф с «кавычками».

'), ('mixed', '

Простой параграф с "кавычками".

', '

Простой параграф с «кавычками».

'), ('unicode', '

Простой параграф с "кавычками".

', f'

Простой параграф с{CHAR_NBSP}«кавычками».

'), # --- Рекурсивный обход --- ('mnemonic', '

Текст, а внутри для проверки "жирный" текст.

', '

Текст, а внутри для проверки «жирный» текст.

'), ('mixed', '

Текст, а внутри для проверки "жирный" текст.

', '

Текст, а внутри для проверки «жирный» текст.

'), ('unicode', '

Текст, а внутри для проверки "жирный" текст.

', f'

Текст, а{CHAR_NBSP}внутри для{CHAR_NBSP}проверки «жирный» текст.

'), # --- Вложенные теги с предлогом в тексте --- ('mnemonic', '

Текст с предлогом в доме.

', '

Текст с предлогом в доме.

'), ('mixed', '

Текст с предлогом в доме.

', '

Текст с предлогом в доме.

'), ('unicode', '

Текст с предлогом в доме.

', f'

Текст с{CHAR_NBSP}предлогом в{CHAR_NBSP}доме.

'), # --- Обработка соседних текстовых узлов --- ('mnemonic', '

Союз и слово и еще один союз а текст.

', '

Союз и слово и еще один союз а текст.

'), ('mixed', '

Союз и слово и еще один союз а текст.

', '

Союз и слово и еще один союз а текст.

'), ('unicode', '

Союз и слово и еще один союз а текст.

', f'

Союз и{CHAR_NBSP}слово и{CHAR_NBSP}еще один союз а{CHAR_NBSP}текст.

'), # --- Проверка тегов ', '

Текст «до».

'), ('mixed', '

Текст "до".

', '

Текст «до».

'), ('mixed', '

Текст "до".

Ctrl + C', '

Текст «до».

Ctrl + C'), ('mixed', '

Текст "до".

Sample "text"', '

Текст «до».

Sample "text"'), ('mixed', '

Текст "до".

x=5', '

Текст «до».

x=5'), # --- Проверка тегов с атрибутами --- ('mixed', 'Текст "снаружи"', 'Текст «снаружи»'), ('mixed', 'Текст "снаружи"', 'Текст «снаружи»'), ('mixed', 'Текст "снаружи"', 'Текст «снаружи»'), ('mnemonic', 'Текст "снаружи"', 'Текст «снаружи»'), # --- Комплексный интеграционный тест --- ('mnemonic', '

Он сказал: "В 1941-1945 гг. -- было 100 тыс. руб. и т. д."

', '

Он сказал: «В 1941–1945 гг. – было 100 тыс. руб.' ' и т. д.»

'), ('mixed', '

Он сказал: "В 1941-1945 гг. -- было 100 тыс. руб. и т. д."

', '

Он сказал: «В 1941–1945 гг. – было 100 тыс. руб.' ' и т. д.»

'), ('unicode', '

Он сказал: "В 1941-1945 гг. -- было 100 тыс. руб. и т. д."

', f'

Он{CHAR_NBSP}сказал: «В{CHAR_NBSP}1941{CHAR_NDASH}1945{CHAR_NBSP}гг.{CHAR_NBSP}{CHAR_NDASH} было' f' 100{CHAR_NBSP}тыс.{CHAR_THIN_SP}руб. и{CHAR_NBSP}т.{CHAR_THIN_SP}д.»

'), # --- Теги внутри кавычек --- ('mnemonic', '

"Почему", "зачем" и "кому это выгодно" -- вопросы требующие ответа.

', '

«Почему», «зачем» и «кому это выгодно' '» – вопросы требующие ответа.

'), ('mixed', '

"Почему", "зачем" и "кому это выгодно" -- вопросы требующие ответа.

', '

«Почему», «зачем» и «кому это выгодно» – вопросы требующие ответа.

'), ('unicode', '

"Почему", "зачем" и "кому это выгодно" -- вопросы требующие ответа.

', f'

«Почему», «зачем» и{CHAR_NBSP}«кому это выгодно»{CHAR_NBSP}{CHAR_NDASH} вопросы требующие ответа.

'), # --- Проверка пустого текста и узлов с пробелами --- ('mnemonic', '

\n\t

Слово

', '

\n

Слово

'), ('mixed', '

\n\t

Слово

', '

\n

Слово

'), ('unicode', '

\n\t

Слово

', '

\n

Слово

'), # --- Самозакрывающиеся теги и теги с атрибутами --- # ВАЖНО: порядок атрибутов в типографированном тексте может быть произвольным ('mnemonic', '

Текст с картинкой image и текстом.

', '

Текст с картинкой image и текстом.

'), ('mnemonic', '

Текст с <br>
А это новая строка.

', '

Текст с <br>
А это новая строка.

'), ('mixed', '

Текст с картинкой image и текстом.

', '

Текст с картинкой image и текстом.

'), ('mixed', '

Текст с <br>
А это новая строка.

', '

Текст с <br>
А это новая строка.

'), ('unicode', '

Текст с картинкой image и текстом.

', f'

Текст с{CHAR_NBSP}картинкой image и{CHAR_NBSP}текстом.

'), ('unicode', '

Текст с <br>
А это новая строка.

', f'

Текст с{CHAR_NBSP}<br>
А{CHAR_NBSP}это новая строка.

'), ] @pytest.mark.parametrize("mode, input_html, expected_html", TYPOGRAPHER_HTML_TEST_CASES) def test_typographer_html_processing(mode, input_html, expected_html): """ Проверяет полный конвейер Typographer при обработке HTML. """ typo = Typographer(langs='ru', process_html=True, mode=mode) actual_html = typo.process(input_html) assert actual_html == expected_html def test_typographer_plain_text_processing(): """ Проверяет, что в режиме process_html=False типограф маскирует HTML-теги и обрабатывает весь текст. """ typo = Typographer(langs='ru', process_html=False) input_text = 'Текст "без" HTML, но с предлогом в доме.' expected_text = '<i>Текст «без» <b>HTML</b>, но с предлогом в доме.</i>' actual_text = typo.process(input_text) assert actual_text == expected_text