1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-30 10:36:35 +02:00
joplin/packages/app-cli/tests/MdToHtml.ts

364 lines
12 KiB
TypeScript
Raw Normal View History

import MdToHtml, { LinkRenderingType } from '@joplin/renderer/MdToHtml';
const { filename } = require('@joplin/lib/path-utils');
import { setupDatabaseAndSynchronizer, switchClient } from '@joplin/lib/testing/test-utils';
import shim from '@joplin/lib/shim';
import { RenderOptions } from '@joplin/renderer/types';
import { isResourceUrl, resourceUrlToId } from '@joplin/lib/models/utils/resourceUtils';
const { themeStyle } = require('@joplin/lib/theme');
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
function newTestMdToHtml(options: any = null) {
options = {
ResourceModel: {
isResourceUrl: isResourceUrl,
urlToId: resourceUrlToId,
},
fsDriver: shim.fsDriver(),
...options,
};
return new MdToHtml(options);
}
describe('MdToHtml', () => {
2022-11-15 12:23:50 +02:00
beforeEach(async () => {
await setupDatabaseAndSynchronizer(1);
await switchClient(1);
});
it('should convert from Markdown to Html', (async () => {
const basePath = `${__dirname}/md_to_html`;
const files = await shim.fsDriver().readDirStats(basePath);
const mdToHtml = newTestMdToHtml();
for (let i = 0; i < files.length; i++) {
const mdFilename = files[i].path;
if (mdFilename.indexOf('.md') < 0) continue;
const mdFilePath = `${basePath}/${mdFilename}`;
const htmlPath = `${basePath}/${filename(mdFilePath)}.html`;
2023-05-17 17:09:17 +02:00
// if (mdFilename !== 'sanitize_9.md') continue;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const mdToHtmlOptions: RenderOptions = {
bodyOnly: true,
};
if (mdFilename === 'checkbox_alternative.md') {
mdToHtmlOptions.plugins = {
checkbox: {
Plugins: Added support for content scripts - For now, supports Markdown-it plugins - Also fixed slow rendering of notes in some cases - Simplified how Markdown-It plugins are created and cleaned MdToHtml code commit 89576de2896c99134f25f2a2db25008514cb1315 Merge: c75aa21f 5292fc14 Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 21 00:23:00 2020 +0100 Merge branch 'release-1.3' into plugin_content_scripts commit c75aa21ffdc42764d71dc9deadba7a7ef4233995 Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 21 00:19:52 2020 +0100 Fixed tests commit 075187729d11a16d385b651cbf1ebb89f14935e0 Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 21 00:11:53 2020 +0100 Fixed tests commit 14696b8c651e7afdaf71269bcdbadf0d58d3ef8a Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 23:27:58 2020 +0100 Fixed slow rendering of note commit 61c09f5bf856481f91b00cfe87ff05596c63d4bc Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 22:35:21 2020 +0100 Clean up commit 9f7ea7d865a990b3a21cc8c59093390d9db61653 Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 20:05:31 2020 +0100 Updated doc commit 98bf3bde8d6663f2f91ff965304b4aac00bdd98b Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 19:56:34 2020 +0100 Finished converting plugins commit fe90d92e01427bd2b38200393713ea28763507a9 Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 17:52:02 2020 +0100 Simplified how Markdown-It plugins are created commit 47c7b864cbb864d5df79849f27625aecf312df4b Author: Laurent Cozic <laurent@cozic.net> Date: Mon Oct 19 16:40:11 2020 +0100 Clean up rules commit d927a238bb635a4be45f9216d776f7d07cb0a584 Author: Laurent Cozic <laurent@cozic.net> Date: Mon Oct 19 14:29:40 2020 +0100 Fixed tests commit 388a56c5dde4c382e3ee0035791137150adaba1b Author: Laurent Cozic <laurent@cozic.net> Date: Mon Oct 19 14:00:47 2020 +0100 Add support for content scripts
2020-10-21 01:23:55 +02:00
checkboxRenderingType: 2,
},
};
} else if (mdFilename.startsWith('sourcemap_')) {
mdToHtmlOptions.mapsToLine = true;
} else if (mdFilename.startsWith('resource_')) {
mdToHtmlOptions.resources = {};
}
const markdown = await shim.fsDriver().readFile(mdFilePath);
let expectedHtml = await shim.fsDriver().readFile(htmlPath);
const result = await mdToHtml.render(markdown, null, mdToHtmlOptions);
let actualHtml = result.html;
expectedHtml = expectedHtml.replace(/\r?\n/g, '\n');
actualHtml = actualHtml.replace(/\r?\n/g, '\n');
if (actualHtml !== expectedHtml) {
2022-04-26 13:52:48 +02:00
const msg: string[] = [
'',
`Error converting file: ${mdFilename}`,
'--------------------------------- Got:',
actualHtml,
'--------------------------------- Raw:',
actualHtml.split('\n'),
'--------------------------------- Expected (Lines)',
2022-04-26 13:52:48 +02:00
expectedHtml.split('\n'),
'--------------------------------- Expected (Text)',
expectedHtml,
2022-04-26 13:52:48 +02:00
'--------------------------------------------',
'',
];
// eslint-disable-next-line no-console
2022-04-26 13:52:48 +02:00
console.info(msg.join('\n'));
expect(false).toBe(true);
// return;
} else {
expect(true).toBe(true);
}
}
}));
it('should return enabled plugin assets', (async () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
const pluginOptions: any = {};
const pluginNames = MdToHtml.pluginNames();
for (const n of pluginNames) pluginOptions[n] = { enabled: false };
{
const mdToHtml = newTestMdToHtml({ pluginOptions: pluginOptions });
const assets = await mdToHtml.allAssets(themeStyle(1));
expect(assets.length).toBe(1); // Base note style should always be returned
}
{
pluginOptions['checkbox'].enabled = true;
const mdToHtml = newTestMdToHtml({ pluginOptions: pluginOptions });
const assets = await mdToHtml.allAssets(themeStyle(1));
expect(assets.length).toBe(2);
expect(assets[1].mime).toBe('text/css');
const content = await shim.fsDriver().readFile(assets[1].path);
expect(content.indexOf('joplin-checklist') >= 0).toBe(true);
}
}));
it('should wrapped the rendered Markdown', (async () => {
const mdToHtml = newTestMdToHtml();
// In this case, the HTML contains both the style and
// the rendered markdown wrapped in a DIV.
const result = await mdToHtml.render('just **testing**');
Plugins: Added support for content scripts - For now, supports Markdown-it plugins - Also fixed slow rendering of notes in some cases - Simplified how Markdown-It plugins are created and cleaned MdToHtml code commit 89576de2896c99134f25f2a2db25008514cb1315 Merge: c75aa21f 5292fc14 Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 21 00:23:00 2020 +0100 Merge branch 'release-1.3' into plugin_content_scripts commit c75aa21ffdc42764d71dc9deadba7a7ef4233995 Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 21 00:19:52 2020 +0100 Fixed tests commit 075187729d11a16d385b651cbf1ebb89f14935e0 Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 21 00:11:53 2020 +0100 Fixed tests commit 14696b8c651e7afdaf71269bcdbadf0d58d3ef8a Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 23:27:58 2020 +0100 Fixed slow rendering of note commit 61c09f5bf856481f91b00cfe87ff05596c63d4bc Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 22:35:21 2020 +0100 Clean up commit 9f7ea7d865a990b3a21cc8c59093390d9db61653 Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 20:05:31 2020 +0100 Updated doc commit 98bf3bde8d6663f2f91ff965304b4aac00bdd98b Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 19:56:34 2020 +0100 Finished converting plugins commit fe90d92e01427bd2b38200393713ea28763507a9 Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 17:52:02 2020 +0100 Simplified how Markdown-It plugins are created commit 47c7b864cbb864d5df79849f27625aecf312df4b Author: Laurent Cozic <laurent@cozic.net> Date: Mon Oct 19 16:40:11 2020 +0100 Clean up rules commit d927a238bb635a4be45f9216d776f7d07cb0a584 Author: Laurent Cozic <laurent@cozic.net> Date: Mon Oct 19 14:29:40 2020 +0100 Fixed tests commit 388a56c5dde4c382e3ee0035791137150adaba1b Author: Laurent Cozic <laurent@cozic.net> Date: Mon Oct 19 14:00:47 2020 +0100 Add support for content scripts
2020-10-21 01:23:55 +02:00
expect(result.cssStrings.length).toBeGreaterThan(0);
expect(result.html.indexOf('rendered-md') >= 0).toBe(true);
}));
it('should return the rendered body only', (async () => {
const mdToHtml = newTestMdToHtml();
2020-11-05 18:58:23 +02:00
// In this case, the HTML contains only the rendered markdown, with
// no wrapper and no style. The style is instead in the cssStrings
// property.
{
const result = await mdToHtml.render('just **testing**', null, { bodyOnly: true });
expect(result.cssStrings.length).toBeGreaterThan(0);
expect(result.html.trim()).toBe('just <strong>testing</strong>');
}
// But it should not remove the wrapping <p> tags if there's more
// than one line
{
const result = await mdToHtml.render('one\n\ntwo', null, { bodyOnly: true });
expect(result.html.trim()).toBe('<p>one</p>\n<p>two</p>');
}
}));
it('should render an empty string', (async () => {
const mdToHtml = newTestMdToHtml();
const result = await mdToHtml.render('', null, { splitted: true });
// The TinyMCE component checks for this exact string to apply a hack,
// so make sure it doesn't change from version to version.
expect(result.html).toBe('<div id="rendered-md"></div>');
}));
it('should split HTML and CSS', (async () => {
const mdToHtml = newTestMdToHtml();
2020-11-05 18:58:23 +02:00
// It is similar to the bodyOnly option, excepts that the rendered
// Markdown is wrapped in a DIV
const result = await mdToHtml.render('just **testing**', null, { splitted: true });
Plugins: Added support for content scripts - For now, supports Markdown-it plugins - Also fixed slow rendering of notes in some cases - Simplified how Markdown-It plugins are created and cleaned MdToHtml code commit 89576de2896c99134f25f2a2db25008514cb1315 Merge: c75aa21f 5292fc14 Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 21 00:23:00 2020 +0100 Merge branch 'release-1.3' into plugin_content_scripts commit c75aa21ffdc42764d71dc9deadba7a7ef4233995 Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 21 00:19:52 2020 +0100 Fixed tests commit 075187729d11a16d385b651cbf1ebb89f14935e0 Author: Laurent Cozic <laurent@cozic.net> Date: Wed Oct 21 00:11:53 2020 +0100 Fixed tests commit 14696b8c651e7afdaf71269bcdbadf0d58d3ef8a Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 23:27:58 2020 +0100 Fixed slow rendering of note commit 61c09f5bf856481f91b00cfe87ff05596c63d4bc Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 22:35:21 2020 +0100 Clean up commit 9f7ea7d865a990b3a21cc8c59093390d9db61653 Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 20:05:31 2020 +0100 Updated doc commit 98bf3bde8d6663f2f91ff965304b4aac00bdd98b Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 19:56:34 2020 +0100 Finished converting plugins commit fe90d92e01427bd2b38200393713ea28763507a9 Author: Laurent Cozic <laurent@cozic.net> Date: Tue Oct 20 17:52:02 2020 +0100 Simplified how Markdown-It plugins are created commit 47c7b864cbb864d5df79849f27625aecf312df4b Author: Laurent Cozic <laurent@cozic.net> Date: Mon Oct 19 16:40:11 2020 +0100 Clean up rules commit d927a238bb635a4be45f9216d776f7d07cb0a584 Author: Laurent Cozic <laurent@cozic.net> Date: Mon Oct 19 14:29:40 2020 +0100 Fixed tests commit 388a56c5dde4c382e3ee0035791137150adaba1b Author: Laurent Cozic <laurent@cozic.net> Date: Mon Oct 19 14:00:47 2020 +0100 Add support for content scripts
2020-10-21 01:23:55 +02:00
expect(result.cssStrings.length).toBeGreaterThan(0);
expect(result.html.trim()).toBe('<div id="rendered-md"><p>just <strong>testing</strong></p>\n</div>');
}));
Desktop: Resolves #176: Added experimental WYSIWYG editor (#2556) * Trying to get TuiEditor to work * Tests with TinyMCE * Fixed build * Improved asset loading * Added support for Joplin source blocks * Added support for Joplin source blocks * Better integration * Make sure noteDidUpdate event is always dispatched at the right time * Minor tweaks * Fixed tests * Add support for checkboxes * Minor refactoring * Added support for file attachments * Add support for fenced code blocks * Fix new line issue on code block * Added support for Fountain scripts * Refactoring * Better handling of saving and loading notes * Fix saving and loading ntoes * Handle multi-note selection and fixed new note creation issue * Fixed newline issue in test * Fixed newline issue in test * Improve saving and loading * Improve saving and loading note * Removed undeeded prop * Fixed issue when new note being saved is incorrectly reloaded * Refactoring and improve saving of note when unmounting component * Fixed TypeScript error * Small changes * Improved further handling of saving and loading notes * Handle provisional notes and fixed various saving and loading bugs * Adding back support for HTML notes * Added support for HTML notes * Better handling of editable nodes * Preserve image HTML tag when the size is set * Handle switching between editor when the note has note finished saving * Handle templates * Handle templates * Handle loading note that is being saved * Handle note being reloaded via sync * Clean up * Clean up and improved logging * Fixed TS error * Fixed a few issues * Fixed test * Logging * Various improvements * Add blockquote support * Moved CWD operation to shim * Removed deleted files * Added support for Joplin commands
2020-03-10 01:24:57 +02:00
it('should render links correctly', (async () => {
const testCases = [
// 0: input
// 1: output with linkify = off
// 2: output with linkify = on
[
'https://example.com',
'https://example.com',
'<a data-from-md title=\'https://example.com\' href=\'https://example.com\'>https://example.com</a>',
],
[
'file://C:\\AUTOEXEC.BAT',
'file://C:\\AUTOEXEC.BAT',
'<a data-from-md title=\'file://C:%5CAUTOEXEC.BAT\' href=\'file://C:%5CAUTOEXEC.BAT\'>file://C:\\AUTOEXEC.BAT</a>',
],
[
'example.com',
'example.com',
'example.com',
],
[
'oo.ps',
'oo.ps',
'oo.ps',
],
[
'test@example.com',
'test@example.com',
'test@example.com',
],
[
'<https://example.com>',
'<a data-from-md title=\'https://example.com\' href=\'https://example.com\'>https://example.com</a>',
'<a data-from-md title=\'https://example.com\' href=\'https://example.com\'>https://example.com</a>',
],
[
'[ok](https://example.com)',
'<a data-from-md title=\'https://example.com\' href=\'https://example.com\'>ok</a>',
'<a data-from-md title=\'https://example.com\' href=\'https://example.com\'>ok</a>',
],
[
'[bla.pdf](file:///Users/tessus/Downloads/bla.pdf)',
'<a data-from-md title=\'file:///Users/tessus/Downloads/bla.pdf\' href=\'file:///Users/tessus/Downloads/bla.pdf\'>bla.pdf</a>',
'<a data-from-md title=\'file:///Users/tessus/Downloads/bla.pdf\' href=\'file:///Users/tessus/Downloads/bla.pdf\'>bla.pdf</a>',
],
];
const mdToHtmlLinkifyOn = newTestMdToHtml({
pluginOptions: {
linkify: { enabled: true },
link_open: {
linkRenderingType: LinkRenderingType.HrefHandler,
},
},
});
const mdToHtmlLinkifyOff = newTestMdToHtml({
pluginOptions: {
linkify: { enabled: false },
},
});
const renderOptions = {
bodyOnly: true,
plainResourceRendering: true,
linkRenderingType: LinkRenderingType.HrefHandler,
};
for (const testCase of testCases) {
const [input, expectedLinkifyOff, expectedLinkifyOn] = testCase;
{
const actual = await mdToHtmlLinkifyOn.render(input, null, renderOptions);
expect(actual.html).toBe(expectedLinkifyOn);
}
{
const actual = await mdToHtmlLinkifyOff.render(input, null, renderOptions);
expect(actual.html).toBe(expectedLinkifyOff);
}
}
}));
Desktop: Resolves #176: Added experimental WYSIWYG editor (#2556) * Trying to get TuiEditor to work * Tests with TinyMCE * Fixed build * Improved asset loading * Added support for Joplin source blocks * Added support for Joplin source blocks * Better integration * Make sure noteDidUpdate event is always dispatched at the right time * Minor tweaks * Fixed tests * Add support for checkboxes * Minor refactoring * Added support for file attachments * Add support for fenced code blocks * Fix new line issue on code block * Added support for Fountain scripts * Refactoring * Better handling of saving and loading notes * Fix saving and loading ntoes * Handle multi-note selection and fixed new note creation issue * Fixed newline issue in test * Fixed newline issue in test * Improve saving and loading * Improve saving and loading note * Removed undeeded prop * Fixed issue when new note being saved is incorrectly reloaded * Refactoring and improve saving of note when unmounting component * Fixed TypeScript error * Small changes * Improved further handling of saving and loading notes * Handle provisional notes and fixed various saving and loading bugs * Adding back support for HTML notes * Added support for HTML notes * Better handling of editable nodes * Preserve image HTML tag when the size is set * Handle switching between editor when the note has note finished saving * Handle templates * Handle templates * Handle loading note that is being saved * Handle note being reloaded via sync * Clean up * Clean up and improved logging * Fixed TS error * Fixed a few issues * Fixed test * Logging * Various improvements * Add blockquote support * Moved CWD operation to shim * Removed deleted files * Added support for Joplin commands
2020-03-10 01:24:57 +02:00
it.each([
'[test](http://example.com/)',
'[test](mailto:test@example.com)',
])('should add onclick handlers to links when linkRenderingType is JavaScriptHandler (%j)', async (markdown) => {
const mdToHtml = newTestMdToHtml();
const renderWithoutOnClickOptions = {
bodyOnly: true,
linkRenderingType: LinkRenderingType.HrefHandler,
};
expect(
(await mdToHtml.render(markdown, undefined, renderWithoutOnClickOptions)).html,
).not.toContain('onclick');
const renderWithOnClickOptions = {
bodyOnly: true,
linkRenderingType: LinkRenderingType.JavaScriptHandler,
};
expect(
(await mdToHtml.render(markdown, undefined, renderWithOnClickOptions)).html,
).toMatch(/<a data-from-md .*onclick=['"].*['"].*>/);
});
it('should return attributes of line numbers', (async () => {
const mdToHtml = newTestMdToHtml();
// Mapping information between source lines and html elements is
// annotated.
{
const input = '# Head\nFruits\n- Apple\n';
const result = await mdToHtml.render(input, null, { bodyOnly: true, mapsToLine: true });
expect(result.html.trim()).toBe('<h1 id="head" class="maps-to-line" source-line="0" source-line-end="1">Head</h1>\n' +
'<p class="maps-to-line" source-line="1" source-line-end="2">Fruits</p>\n' +
'<ul>\n<li class="maps-to-line" source-line="2" source-line-end="3">Apple</li>\n</ul>',
);
}
}));
it('should attach source blocks to block KaTeX', async () => {
const mdToHtml = newTestMdToHtml();
const katex = [
'3 + 3',
'\n\\int_0^1 x dx\n\n',
'\n\\int_0^1 x dx\n3 + 3\n',
'\n\t2^{3^4}\n\t3 + 3\n',
'3\n4',
];
const surroundingTextChoices = [
['', ''],
['Test', ''],
['Test', 'Test!'],
['Test\n\n', '\n\nTest!'],
];
const tests = [];
for (const texSource of katex) {
for (const [start, end] of surroundingTextChoices) {
tests.push([texSource, `${start}\n$$${texSource}$$\n${end}`]);
}
}
for (const [tex, input] of tests) {
const html = await mdToHtml.render(input, null, { bodyOnly: true });
const opening = '<pre class="joplin-source" data-joplin-language="katex" data-joplin-source-open="$$&#10;" data-joplin-source-close="&#10;$$&#10;">';
const closing = '</pre>';
// Remove any single leading and trailing newlines, those are included in data-joplin-source-open
// and data-joplin-source-close.
const trimmedTex = tex.replace(/^[\n]/, '').replace(/[\n]$/, '');
expect(html.html).toContain(opening + trimmedTex + closing);
}
});
it('should render inline KaTeX after a numbered equation', async () => {
const mdToHtml = newTestMdToHtml();
// This test is intended to verify that inline KaTeX renders correctly
// after creating a numbered equation with \begin{align}...\end{align}.
//
// See https://github.com/laurent22/joplin/issues/9455 for details.
const markdown = [
'$$',
'\\begin{align}\\text{Block}\\end{align}',
'$$',
'',
'$\\text{Inline}$',
].join('\n');
const { html } = await mdToHtml.render(markdown, null, { bodyOnly: true });
// Because we don't control the output of KaTeX, this test should be as general as
// possible while still verifying that rendering (without an error) occurs.
// Should have rendered the inline and block content without errors
expect(html).toContain('Inline</span>');
expect(html).toContain('Block</span>');
});
it('should sanitize KaTeX errors', async () => {
const markdown = '$\\a<svg>$';
const renderResult = await newTestMdToHtml().render(markdown, null, { bodyOnly: true });
// Should not contain the HTML in unsanitized form
expect(renderResult.html).not.toContain('<svg>');
});
});