В библиотеке Marked рендерер отвечает за
преобразование синтаксических элементов Markdown в HTML. Каждый тип
элемента имеет соответствующий метод рендерера: heading,
paragraph, link, list,
listitem и другие. Понимание структуры рендерера важно для
юнит-тестирования, так как тесты должны проверять корректность вывода
HTML при различных входных данных.
Рендереры в Marked создаются через класс Renderer:
const { Renderer } = require('marked');
const renderer = new Renderer();
Методы рендерера можно переопределять:
renderer.heading = (text, level) => `<h${level}>${text.toUpperCase()}</h${level}>`;
Юнит-тестирование должно проверять, что при вызове метода с определёнными аргументами возвращается ожидаемый HTML.
Для тестирования рендереров рекомендуется использовать фреймворк Jest или Mocha с Chai. Основная цель — изолированное тестирование методов рендерера без необходимости парсить весь Markdown.
Пример базовой конфигурации Jest:
// renderer.test.js
const { Renderer } = require('marked');
describe('Renderer', () => {
let renderer;
beforeEach(() => {
renderer = new Renderer();
});
test('heading генерирует корректный HTML', () => {
const result = renderer.heading('Test', 2);
expect(result).toBe('<h2>Test</h2>');
});
});
Метод heading(text, level) получает текст и уровень
заголовка. Тесты должны покрывать все уровни от 1 до 6 и проверять
правильное формирование HTML.
test.each([1,2,3,4,5,6])('heading уровня %i', (level) => {
const result = renderer.heading('Title', level);
expect(result).toBe(`<h${level}>Title</h${level}>`);
});
Метод paragraph(text) преобразует текст в тег
<p>.
test('paragraph возвращает текст в тег <p>', () => {
const result = renderer.paragraph('Hello world');
expect(result).toBe('<p>Hello world</p>\n');
});
Методы list(body, ordered, start) и
listitem(text) отвечают за генерацию
<ul>/<ol> и <li>.
test('listitem формирует <li>', () => {
const result = renderer.listitem('Item');
expect(result).toBe('<li>Item</li>\n');
});
test('ordered list формируется с атрибутом start', () => {
const result = renderer.list('Item', true, 3);
expect(result).toBe('<ol start="3">\nItem</ol>\n');
});
Методы link(href, title, text) и
image(href, title, text) позволяют тестировать генерацию
атрибутов HTML.
test('link формирует корректный <a>', () => {
const result = renderer.link('https://example.com', 'Example', 'Click');
expect(result).toBe('<a href="https://example.com" title="Example">Click</a>');
});
test('image формирует <img>', () => {
const result = renderer.image('img.png', 'Alt text', 'Image');
expect(result).toBe('<img src="img.png" alt="Alt text" title="Image">');
});
Marked позволяет полностью переопределять методы рендерера. Юнит-тесты должны проверять поведение кастомных методов.
renderer.paragraph = text => `<p class="custom">${text}</p>`;
test('кастомный paragraph добавляет класс', () => {
const result = renderer.paragraph('Custom text');
expect(result).toBe('<p class="custom">Custom text</p>');
});
Некорректные данные, содержащие HTML или скрипты, должны корректно обрабатываться. Тесты должны проверять экранирование и предотвращение XSS-уязвимостей.
test('paragraph экранирует HTML', () => {
const result = renderer.paragraph('<script>alert(1)</script>');
expect(result).toBe('<p><script>alert(1)</script></p>\n');
});
test.each для параметризованных сценариев
(разные уровни заголовков, списков и т.д.).Юнит-тестирование рендереров Marked обеспечивает надёжность генерации HTML, предсказуемость кастомных настроек и защиту от ошибок форматирования или XSS. Оно позволяет безопасно модифицировать рендереры и внедрять кастомные шаблоны без риска поломки базовой функциональности.