Тестирование плагинов

Для работы с плагинами в Markdown-it используется метод .use(). Он принимает функцию-плагин и опциональные параметры, которые могут модифицировать поведение плагина. Каждый плагин получает экземпляр движка Markdown-it, что позволяет ему регистрировать новые правила обработки токенов, изменять существующие или добавлять вспомогательные методы.

Пример подключения плагина:

const MarkdownIt = require('markdown-it');
const markdownItFootnote = require('markdown-it-footnote');

const md = new MarkdownIt();
md.use(markdownItFootnote);

После подключения плагина движок Markdown-it автоматически использует его возможности при обработке текста. Порядок подключения плагинов важен: плагины, добавленные раньше, обрабатывают текст раньше, а последующие могут модифицировать уже созданные токены.


Структура плагина и возможности модификации

Каждый плагин для Markdown-it может работать на нескольких уровнях:

  1. Парсер блоков – отвечает за создание блоков, таких как заголовки, списки или цитаты.
  2. Парсер inline – обрабатывает текст внутри блоков, например, выделение жирным или вставку ссылок.
  3. Рендереры – преобразуют токены в HTML.
  4. Хуки и вспомогательные методы – позволяют добавлять дополнительные вычисления или фильтры для токенов.

Типичная структура плагина выглядит так:

function myPlugin(md, options) {
    // Добавление правила inline
    md.inline.ruler.after('emphasis', 'my_inline_rule', function(state, silent) {
        // логика обработки
        return true; // если правило применено
    });

    // Изменение рендерера
    md.renderer.rules.my_inline_rule = function(tokens, idx) {
        return `<span class="highlight">${tokens[idx].content}</span>`;
    };
}

Тестирование плагинов

Тестирование плагинов необходимо для уверенности, что изменения правил обработки и рендеринга работают корректно, не ломая основной поток Markdown-it.

Юнит-тестирование правил

Markdown-it разделяет парсинг на токены, что позволяет тестировать правила отдельно. Для юнит-теста достаточно создать экземпляр движка с подключенным плагином и вызвать метод .parse() или .render().

const md = new MarkdownIt().use(myPlugin);

const tokens = md.parse('**тестовый текст**', {});
console.assert(tokens.some(t => t.type === 'my_inline_rule'), 'Плагин не сработал');

Тест проверяет наличие токена, добавленного плагином, что гарантирует срабатывание правила.

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

Для проверки HTML-вывода используется метод .render():

const html = md.render('**тестовый текст**');
console.assert(html.includes('<span class="highlight">'), 'Рендерер плагина не сработал');

Это обеспечивает проверку корректного отображения результата и соответствие ожидаемому HTML.


Использование фикстур и сценариев

Для сложных плагинов удобно использовать фикстуры — заранее подготовленные входные данные и ожидаемый результат. Фикстуры позволяют автоматически прогонять множество случаев:

const fixtures = [
    { input: '**важное**', expected: '<p><span class="highlight">важное</span></p>\n' },
    { input: 'Текст без выделения', expected: '<p>Текст без выделения</p>\n' },
];

fixtures.forEach(f => {
    const result = md.render(f.input);
    console.assert(result === f.expected, `Ошибка для входа: ${f.input}`);
});

Такой подход упрощает регрессионное тестирование при обновлении плагина.


Тестирование совместимости с другими плагинами

Markdown-it позволяет подключать несколько плагинов одновременно. Тестирование должно включать проверку на конфликты токенов и рендереров:

const md = new MarkdownIt()
    .use(markdownItFootnote)
    .use(myPlugin);

const html = md.render('Сноска[^1] **текст**');
console.assert(html.includes('<span class="highlight">'), 'Конфликт с другими плагинами');
console.assert(html.includes('<sup'), 'Сноски работают некорректно');

Это важно для плагинов, которые изменяют стандартные правила Markdown или используют те же имена токенов.


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

Для интеграции в CI/CD используют фреймворки вроде Jest или Mocha:

const { describe, it } = require('mocha');
const assert = require('assert');

describe('myPlugin', () => {
    const md = new MarkdownIt().use(myPlugin);

    it('должен оборачивать текст в span', () => {
        const html = md.render('**важное**');
        assert(html.includes('<span class="highlight">'));
    });
});

Автоматические тесты позволяют быстро проверять корректность работы плагина после внесения изменений и при обновлении зависимостей.


Логирование и отладка

Для анализа работы плагинов используется логирование токенов:

md.core.ruler.push('log_tokens', state => {
    console.log(state.tokens);
});

Такой подход позволяет отслеживать, какие токены создаются и в каком порядке, выявлять проблемы взаимодействия плагинов и корректно настраивать рендереры.


Поддержка конфигурации и параметров

Плагины часто принимают настройки. Для тестирования важно проверять корректность работы с разными комбинациями параметров:

const md = new MarkdownIt().use(myPlugin, { highlight: true });

const html = md.render('**текст**');
console.assert(html.includes('<span class="highlight">'), 'Плагин с настройками не сработал');

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


Инструменты и методы покрытия

Для оценки качества тестирования можно использовать инструменты покрытия кода (code coverage). Они показывают, какие строки плагина не были протестированы, и помогают выявить слабые места.

Примеры:

  • nyc + Mocha — простая интеграция для Node.js.
  • Jest — встроенный механизм покрытия и удобные отчёты.

Покрытие позволяет не только обнаружить пропущенные сценарии, но и поддерживать стабильность плагина при рефакторинге.