@tryfabric/martian
Version:
Converts Markdown to Notion Blocks and RichText
281 lines (237 loc) • 7.57 kB
text/typescript
import * as md from '../src/markdown';
import {text} from '../src/markdown';
import * as notion from '../src/notion';
import {parseBlocks, parseRichText} from '../src/parser/internal';
describe('gfm parser', () => {
const options = {allowUnsupportedObjectType: false, strictImageUrls: true};
it('should parse paragraph with nested annotations', () => {
const ast = md.root(
md.paragraph(
md.text('Hello '),
md.emphasis(md.text('world '), md.strong(md.text('foo'))),
md.text('! '),
md.inlineCode('code')
)
);
const actual = parseBlocks(ast, options);
const expected = [
notion.paragraph([
notion.richText('Hello '),
notion.richText('world ', {
annotations: {italic: true},
}),
notion.richText('foo', {
annotations: {italic: true, bold: true},
}),
notion.richText('! '),
notion.richText('code', {
annotations: {code: true},
}),
]),
];
expect(actual).toStrictEqual(expected);
});
it('should parse text with hrefs and annotations', () => {
const ast = md.root(
md.paragraph(
md.text('hello world '),
md.link(
'https://example.com',
md.text('this is a '),
md.emphasis(md.text('url'))
),
md.text(' end')
)
);
const actual = parseBlocks(ast, options);
const expected = [
notion.paragraph([
notion.richText('hello world '),
notion.richText('this is a ', {
url: 'https://example.com',
}),
notion.richText('url', {
annotations: {italic: true},
url: 'https://example.com',
}),
notion.richText(' end'),
]),
];
expect(actual).toStrictEqual(expected);
});
it('should parse thematic breaks', () => {
const ast = md.root(
md.paragraph(md.text('hello')),
md.thematicBreak(),
md.paragraph(md.text('world'))
);
const actual = parseBlocks(ast, options);
const expected = [
notion.paragraph([notion.richText('hello')]),
notion.paragraph([notion.richText('world')]),
];
expect(actual).toStrictEqual(expected);
});
it('should parse headings', () => {
const ast = md.root(
md.heading(1, md.text('heading1')),
md.heading(2, md.text('heading2')),
md.heading(3, md.text('heading3')),
md.heading(4, md.text('heading4'))
);
const actual = parseBlocks(ast, options);
const expected = [
notion.headingOne([notion.richText('heading1')]),
notion.headingTwo([notion.richText('heading2')]),
notion.headingThree([notion.richText('heading3')]),
notion.headingThree([notion.richText('heading4')]),
];
expect(actual).toStrictEqual(expected);
});
it('should parse code block and set the language to plain text if none is provided', () => {
const ast = md.root(
md.paragraph(md.text('hello')),
md.code('const foo = () => {}', undefined)
);
const actual = parseBlocks(ast);
const expected = [
notion.paragraph([notion.richText('hello')]),
notion.code([notion.richText('const foo = () => {}')], 'plain text'),
];
expect(actual).toStrictEqual(expected);
});
it('should parse code block and set the proper language', () => {
const ast = md.root(
md.paragraph(md.text('hello')),
md.code('public class Foo {}', 'java')
);
const actual = parseBlocks(ast, options);
const expected = [
notion.paragraph([notion.richText('hello')]),
notion.code([notion.richText('public class Foo {}')], 'java'),
];
expect(actual).toStrictEqual(expected);
});
it('should parse code block and set the language to plain text if it is not supported by Notion', () => {
const ast = md.root(
md.paragraph(md.text('hello')),
md.code('const foo = () => {}', 'not-supported')
);
const actual = parseBlocks(ast);
const expected = [
notion.paragraph([notion.richText('hello')]),
notion.code([notion.richText('const foo = () => {}')], 'plain text'),
];
expect(actual).toStrictEqual(expected);
});
it('should parse block quote', () => {
const ast = md.root(
md.blockquote(
md.heading(1, md.text('hello'), md.emphasis(md.text('world')))
)
);
const actual = parseBlocks(ast, options);
const expected = [
notion.blockquote(
[],
[
notion.headingOne([
notion.richText('hello'),
notion.richText('world', {
annotations: {italic: true},
}),
]),
]
),
];
expect(actual).toStrictEqual(expected);
});
it('should parse list', () => {
const ast = md.root(
md.paragraph(md.text('hello')),
md.unorderedList(
md.listItem(md.paragraph(md.text('a'))),
md.listItem(md.paragraph(md.emphasis(md.text('b')))),
md.listItem(md.paragraph(md.strong(md.text('c'))))
),
md.orderedList(md.listItem(md.paragraph(md.text('d'))))
);
const actual = parseBlocks(ast, options);
const expected = [
notion.paragraph([notion.richText('hello')]),
notion.bulletedListItem([notion.richText('a')]),
notion.bulletedListItem([
notion.richText('b', {annotations: {italic: true}}),
]),
notion.bulletedListItem([
notion.richText('c', {annotations: {bold: true}}),
]),
notion.numberedListItem([notion.richText('d')]),
];
expect(actual).toStrictEqual(expected);
});
it('should parse github extensions', () => {
const ast = md.root(
md.paragraph(
md.link('https://example.com', md.text('https://example.com'))
),
md.paragraph(md.strikethrough(md.text('strikethrough content'))),
md.table(
md.tableRow(
md.tableCell(md.text('a')),
md.tableCell(md.text('b')),
md.tableCell(md.text('c')),
md.tableCell(md.text('d'))
)
),
md.unorderedList(
md.checkedListItem(false, md.paragraph(md.text('to do'))),
md.checkedListItem(true, md.paragraph(md.text('done')))
)
);
const actual = parseBlocks(ast, options);
const expected = [
notion.paragraph([
notion.richText('https://example.com', {
url: 'https://example.com',
}),
]),
notion.paragraph([
notion.richText('strikethrough content', {
annotations: {strikethrough: true},
}),
]),
notion.table(
[
notion.tableRow([
[notion.richText('a')],
[notion.richText('b')],
[notion.richText('c')],
[notion.richText('d')],
]),
],
4
),
notion.toDo(false, [notion.richText('to do')]),
notion.toDo(true, [notion.richText('done')]),
];
expect(actual).toStrictEqual(expected);
});
it('should parse rich text', () => {
const ast = md.root(
md.paragraph(
md.text('a'),
md.strong(md.emphasis(md.text('b')), md.text('c')),
md.link('https://example.com', text('d'))
)
);
const actual = parseRichText(ast);
const expected = [
notion.richText('a'),
notion.richText('b', {annotations: {italic: true, bold: true}}),
notion.richText('c', {annotations: {bold: true}}),
notion.richText('d', {url: 'https://example.com'}),
];
expect(actual).toStrictEqual(expected);
});
});