Тестирование расширений

Расширения в библиотеке Marked позволяют модифицировать или дополнять стандартный процесс разметки Markdown. Они могут добавлять новые синтаксические конструкции, изменять поведение существующих элементов или полностью перехватывать обработку определённых блоков и инлайн-элементов. Для обеспечения стабильности и корректной работы расширений необходимо системное тестирование.

Структура расширений

Расширения бывают двух типов:

  1. Блочные (block) – обрабатывают элементы на уровне строк и абзацев, например, заголовки, списки, блоки кода.
  2. Инлайн (inline) – обрабатывают содержимое внутри строки, например, ссылки, эмодзи, жирный или курсив.

Каждое расширение задается объектом с обязательными полями:

  • name – уникальное имя расширения;
  • levelblock или inline;
  • start – функция или массив индексов начала возможного применения правила (оптимизация поиска);
  • tokenizer – функция, определяющая токен, который будет распознан;
  • renderer – функция, определяющая, как токен преобразуется в HTML.

Тестирование токенизации

Токенизация является ключевым этапом работы расширения. Она отвечает за корректное определение границ синтаксических конструкций и формирование токенов для дальнейшей обработки.

  1. Проверка корректности распознавания токенов Необходимо тестировать каждый тип токена на корректность распознавания:

    const tokens = marked.lexer("**текст**", { extensions: [myExtension] });
    console.assert(tokens[0].type === 'strong', "Токен не распознан как жирный текст");
  2. Проверка границ токена Важно удостовериться, что токен не захватывает лишние символы:

    const tokens = marked.lexer("**текст** остальное", { extensions: [myExtension] });
    console.assert(tokens[0].raw === '**текст**', "Токен захватил лишние символы");
  3. Обработка ошибок и некорректного Markdown Расширение должно корректно обрабатывать неполные конструкции:

    const tokens = marked.lexer("**текст", { extensions: [myExtension] });
    console.assert(tokens[0].type === 'text', "Некорректный Markdown должен оставаться текстом");

Тестирование рендеринга

После токенизации важным этапом является рендеринг HTML из токенов. Тесты должны проверять соответствие ожидаемого HTML и фактического:

const html = marked.parse("**текст**", { extensions: [myExtension] });
console.assert(html === "<strong>текст</strong>", "Рендеринг не совпадает с ожиданием");

Особенности тестирования рендеринга:

  • Проверка вложенных конструкций (**_текст_**);
  • Проверка смешанных блоков (> блок > **жирный**);
  • Убедиться, что расширение не ломает стандартные правила Markdown.

Использование моков и фиктивных данных

Для комплексного тестирования расширений рекомендуется применять моки — искусственные данные, имитирующие сложные структуры Markdown.

Пример создания фиктивного документа для теста:

const mockMarkdown = `
# Заголовок 1

> Цитата с **жирным** и _курсивом_

- Список 1
- Список 2
`;

const html = marked.parse(mockMarkdown, { extensions: [myExtension] });

Такой подход позволяет проверять одновременно несколько правил расширения и выявлять конфликтные ситуации между ними.

Автоматизация тестирования

Для автоматизации тестов удобно использовать Jest или Mocha. Основная структура теста включает:

  1. Подготовку Markdown с различными кейсами;
  2. Применение расширения через marked.parse или marked.lexer;
  3. Сравнение результата с ожидаемым токеном или HTML.

Пример автоматического теста:

test("Тест жирного текста", () => {
    const md = "**тест**";
    const html = marked.parse(md, { extensions: [myExtension] });
    expect(html).toBe("<strong>тест</strong>");
});

Регрессионное тестирование

Любое расширение может взаимодействовать с другими правилами или стандартными токенами. Регрессионные тесты фиксируют ранее правильное поведение:

  • Проверка старых кейсов после добавления новых правил;
  • Сравнение HTML до и после изменения расширения;
  • Фиксация изменений в контрольных примерах.

Проверка производительности

Некоторые расширения могут значительно замедлять обработку больших документов. Рекомендуется:

  • Профилировать обработку больших файлов Markdown;
  • Ограничивать сложность регулярных выражений;
  • Использовать оптимизированные функции start, чтобы ускорить поиск токенов.

Совместимость с обновлениями Marked

Расширения должны оставаться совместимыми с новыми версиями Marked:

  • Проверка всех тестов при обновлении библиотеки;
  • Обновление tokenizer и renderer при изменениях внутренних структур;
  • Поддержка новых типов токенов, добавленных в Marked.

Тщательное тестирование расширений обеспечивает надежность, предсказуемость и стабильность Markdown-приложений, минимизируя вероятность ошибок при обработке сложных документов.