import { source, oneLineTrim } from 'common-tags';
import { Context, MdNode, Parser, HTMLConvertorMap } from '@toast-ui/toastmark';
import { Node, Schema } from 'prosemirror-model';
import { createSpecs } from '@/wysiwyg/specCreator';
import Convertor from '@/convertors/convertor';
import { WwToDOMAdaptor } from '@/wysiwyg/adaptor/wwToDOMAdaptor';
import EventEmitter from '@/event/eventEmitter';
import { ToMdConvertorMap, ToMdConvertorContext, NodeInfo, MarkInfo } from '@t/convertor';
import { createHTMLSchemaMap } from '@/wysiwyg/nodes/html';
import { sanitizeHTML } from '@/sanitizer/htmlSanitizer';
import { createHTMLrenderer } from './markdown/util';
function createSchema() {
const specs = createSpecs({});
return new Schema({
nodes: specs.nodes,
marks: specs.marks,
});
}
describe('Convertor', () => {
let convertor: Convertor;
let schema: Schema;
const parser = new Parser({
disallowedHtmlBlockTags: ['br', 'img'],
});
function assertConverting(markdown: string, expected: string) {
const mdNode = parser.parse(markdown);
const wwNode = convertor.toWysiwygModel(mdNode);
const result = convertor.toMarkdownText(wwNode!);
expect(result).toBe(expected);
}
beforeEach(() => {
schema = createSchema();
convertor = new Convertor(schema, {}, {}, new EventEmitter());
});
describe('should convert between markdown and wysiwyg node to', () => {
it('empty content', () => {
assertConverting('', '');
});
it('paragraph', () => {
const markdown = 'foo';
assertConverting(markdown, markdown);
});
it('headings', () => {
const markdown = source`
# heading1
## heading2
### heading3
#### heading4
##### heading5
###### heading6
`;
const expected = source`
# heading1
## heading2
### heading3
#### heading4
##### heading5
###### heading6
`;
assertConverting(markdown, expected);
});
it('codeBlock', () => {
const markdown = source`
\`\`\`
foo
\`\`\`
`;
assertConverting(markdown, markdown);
});
it('bullet list', () => {
const markdown = source`
* foo
* bar
* qux
* baz
`;
assertConverting(markdown, markdown);
});
it('ordered list', () => {
const markdown = source`
1. foo
2. bar
3. baz
`;
assertConverting(markdown, markdown);
});
it('blockQuote', () => {
const markdown = source`
> foo
> bar
>> baz
> > qux
> >> quxx
`;
const expected = source`
> foo
> bar
> > baz
> > qux
> > > quxx
`;
assertConverting(markdown, expected);
});
it('thematicBreak', () => {
const markdown = source`
---
***
- - -
* * * *
`;
const expected = source`
***
***
***
***
`;
assertConverting(markdown, expected);
});
it('image', () => {
const markdown = source`




`;
const expected = source`




`;
assertConverting(markdown, expected);
});
it('link', () => {
const markdown = source`
[](url)foo
[text](url)
[text](ur*l)
[Editor](https://github.com/nhn_test/tui.editor)
[this.is_a_test_link.com](this.is_a_test_link.com)
[text](url?key=abc&attribute=abc)
`;
const expected = source`
foo
[text](url)
[text](ur*l)
[Editor](https://github.com/nhn_test/tui.editor)
[this.is_a_test_link.com](this.is_a_test_link.com)
[text](url?key=abc&attribute=abc)
`;
assertConverting(markdown, expected);
});
it('code', () => {
const markdown = '`foo bar baz`';
assertConverting(markdown, markdown);
});
it('emphasis (strong, italic) syntax', () => {
const markdown = source`
**foo**
__bar__
*baz*
_qux_
`;
const expected = source`
**foo**
**bar**
*baz*
*qux*
`;
assertConverting(markdown, expected);
});
it('strike', () => {
const markdown = '~~strike~~';
assertConverting(markdown, markdown);
});
it('table', () => {
const markdown = source`
| thead | thead |
| --- | --- |
| tbody | tbody |
| thead |thead |
| -- | ----- |
| tbody|tbody|
| tbody|tbody|
|||
|-|-|
|||
`;
const expected = source`
| thead | thead |
| ----- | ----- |
| tbody | tbody |
| thead | thead |
| ----- | ----- |
| tbody | tbody |
| tbody | tbody |
| | |
| --- | --- |
| | |
`;
assertConverting(markdown, `${expected}\n`);
});
it('table with column align syntax', () => {
const markdown = source`
| default | left | right | center |
| --- | :--- | ---: | :---: |
| tbody | tbody | tbody | tbody |
| | | | |
| --- | :--- | ---: | :---: |
| default | left | right | center |
`;
const expected = source`
| default | left | right | center |
| ------- | :--- | ----: | :----: |
| tbody | tbody | tbody | tbody |
| | | | |
| --- | :--- | ---: | :---: |
| default | left | right | center |
`;
assertConverting(markdown, `${expected}\n`);
});
it('table with inline syntax', () => {
const markdown = source`
|  | foo  baz |
| ---- | ---- |
| [linkText](linkUrl) | foo [linkText](linkUrl) baz |
| **foo** _bar_ ~~baz~~ | **foo** *bar* ~~baz~~ [linkText](linkUrl) |
`;
const expected = source`
|  | foo  baz |
| --- | -------- |
| [linkText](linkUrl) | foo [linkText](linkUrl) baz |
| **foo** *bar* ~~baz~~ | **foo** *bar* ~~baz~~ [linkText](linkUrl) |
`;
assertConverting(markdown, `${expected}\n`);
});
// @TODO: should normalize table cell
// it('should normalize wrong table syntax when converting', () => {
// const markdown = source`
// | col1 | col2 | col3 |
// | --- | --- |
// | cell1 | cell2 | cell3 |
// `;
// const expected = source`
// | col1 | col2 | col3 |
// | ---- | ---- | ---- |
// | cell1 | cell2 | |
// `;
// assertConverting(markdown, `${expected}\n`);
// });
it('task', () => {
const markdown = source`
* [ ] foo
* [x] baz
* [x] bar
1. [x] foo
2. [ ] bar
`;
assertConverting(markdown, markdown);
});
it('list in blockQuote', () => {
const markdown = source`
> * foo
> * baz
> * bar
>> 1. qux
> > 2. quxx
`;
const expected = source`
> * foo
> * baz
> * bar
> > 1. qux
> > 2. quxx
`;
assertConverting(markdown, expected);
});
it('block nodes in list', () => {
const markdown = source`
1. foo
\`\`\`
bar
\`\`\`
> bam
`;
const expected = source`
1. foo
\`\`\`
bar
\`\`\`
> bam
`;
assertConverting(markdown, expected);
});
it('soft break', () => {
const markdown = source`
foo
bar
baz
qux
`;
const expected = source`
foo
bar
baz
qux
`;
assertConverting(markdown, expected);
});
it('
', () => {
const markdown = source`
foo
bar
baz
qux
`;
const expected = source`
foo
bar
baz
qux
`;
assertConverting(markdown, expected);
});
it('
with soft break', () => {
const markdown = source`
foo
bar
baz
qux
quux
quuz
`;
const expected = source`
foo
bar
baz
qux
quux
quuz
`;
assertConverting(markdown, expected);
});
it('
with html inline node', () => {
const markdown = source`
foo
bar
Para Word
`;
const expected = source`
foo
bar
Para Word
`;
assertConverting(markdown, expected);
});
it('
with following
', () => {
const markdown = source`
text1
text2
text3
`;
const expected = source`
text1
text2
text3
`;
assertConverting(markdown, expected);
});
it('
in the middle of the paragraph', () => {
const markdown = source`
text1
te
xt2
text3
`;
const expected = source`
text1
te
xt2
text3
`;
assertConverting(markdown, expected);
});
it('should convert html comment', () => {
const markdown = source`
`;
assertConverting(markdown, markdown);
});
});
describe('convert inline html', () => {
it('emphasis type', () => {
const markdown = source`
foo
foo
foo
foo
foo
foo
foo
`;
assertConverting(markdown, markdown);
});
it('link type', () => {
const markdown = source`
foo
`;
assertConverting(markdown, markdown);
});
it('table with
', () => {
const markdown = source`
| thead
thead | thead |
| ----- | ----- |
| tbody
tbody | tbody |
| tbody | tbody
tbody
tbody |
| tbody | **tbody**
_tbody_
~~tbody~~
\`tbody\` |
| tbody | 
[link](linkUrl) |
`;
const expected = source`
| thead
thead | thead |
| ---------- | ----- |
| tbody
tbody | tbody |
| tbody | tbody
tbody
tbody |
| tbody | **tbody**
*tbody*
~~tbody~~
\`tbody\` |
| tbody | 
[link](linkUrl) |
`;
assertConverting(markdown, `${expected}\n`);
});
it('table with list', () => {
const markdown = source`
| thead |
| ----- |
|
paragraph
code`; assertConverting(markdown, markdown); }); it('blockquote', () => { const markdown = source`
foo
foo`; const expected = oneLineTrim`foo
foo
foo`; assertConverting(markdown, expected); }); it('bullet list', () => { const markdown = source`foo
| foo |
|---|
| bar |
`; const expected = oneLineTrim`foobar
`; assertConverting(markdown, expected); }); }); describe('convert custom inline', () => { it('with info only', () => { const markdown = source`$$custom$$`; const expected = oneLineTrim`$$custom$$`; assertConverting(markdown, expected); }); it('with info and text', () => { const markdown = source`$$custom inline$$`; const expected = oneLineTrim`$$custom inline$$`; assertConverting(markdown, expected); }); }); describe('sanitize when using html', () => { it('href attribute with link', () => { const markdown = source` xss xss xss xss xss xss 123xss `; const expected = source` xss xss xss xss xss xss 123xss `; assertConverting(markdown, expected); }); it('src attribute with image', () => { const markdown = source`foobar