summaryrefslogtreecommitdiff
path: root/spec/frontend/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer_spec.js
blob: a90d3528d60682f64bcd2d76c8a46e17c8605d97 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import buildHTMLToMarkdownRenderer from '~/vue_shared/components/rich_content_editor/services/build_html_to_markdown_renderer';

describe('HTMLToMarkdownRenderer', () => {
  let baseRenderer;
  let htmlToMarkdownRenderer;
  const NODE = { nodeValue: 'mock_node' };

  beforeEach(() => {
    baseRenderer = {
      trim: jest.fn(input => `trimmed ${input}`),
      getSpaceCollapsedText: jest.fn(input => `space collapsed ${input}`),
      getSpaceControlled: jest.fn(input => `space controlled ${input}`),
      convert: jest.fn(),
    };
  });

  describe('TEXT_NODE visitor', () => {
    it('composes getSpaceControlled, getSpaceCollapsedText, and trim services', () => {
      htmlToMarkdownRenderer = buildHTMLToMarkdownRenderer(baseRenderer);

      expect(htmlToMarkdownRenderer.TEXT_NODE(NODE)).toBe(
        `space controlled trimmed space collapsed ${NODE.nodeValue}`,
      );
    });
  });

  describe('LI OL, LI UL visitor', () => {
    const oneLevelNestedList = '\n    * List item 1\n    * List item 2';
    const twoLevelNestedList = '\n  * List item 1\n    * List item 2';
    const spaceInContentList = '\n  * List    item 1\n  * List item 2';

    it.each`
      list                  | indentSpaces | result
      ${oneLevelNestedList} | ${2}         | ${'\n  * List item 1\n  * List item 2'}
      ${oneLevelNestedList} | ${3}         | ${'\n   * List item 1\n   * List item 2'}
      ${oneLevelNestedList} | ${6}         | ${'\n      * List item 1\n      * List item 2'}
      ${twoLevelNestedList} | ${4}         | ${'\n    * List item 1\n        * List item 2'}
      ${spaceInContentList} | ${1}         | ${'\n * List    item 1\n * List item 2'}
    `('changes the list indentation to $indentSpaces spaces', ({ list, indentSpaces, result }) => {
      htmlToMarkdownRenderer = buildHTMLToMarkdownRenderer(baseRenderer, {
        subListIndentSpaces: indentSpaces,
      });

      baseRenderer.convert.mockReturnValueOnce(list);

      expect(htmlToMarkdownRenderer['LI OL, LI UL'](NODE, list)).toBe(result);
      expect(baseRenderer.convert).toHaveBeenCalledWith(NODE, list);
    });
  });

  describe('UL LI visitor', () => {
    it.each`
      listItem           | unorderedListBulletChar | result             | bulletChar
      ${'* list item'}   | ${undefined}            | ${'- list item'}   | ${'default'}
      ${'  - list item'} | ${'*'}                  | ${'  * list item'} | ${'*'}
      ${'  * list item'} | ${'-'}                  | ${'  - list item'} | ${'-'}
    `(
      'uses $bulletChar bullet char in unordered list items when $unorderedListBulletChar is set in config',
      ({ listItem, unorderedListBulletChar, result }) => {
        htmlToMarkdownRenderer = buildHTMLToMarkdownRenderer(baseRenderer, {
          unorderedListBulletChar,
        });
        baseRenderer.convert.mockReturnValueOnce(listItem);

        expect(htmlToMarkdownRenderer['UL LI'](NODE, listItem)).toBe(result);
        expect(baseRenderer.convert).toHaveBeenCalledWith(NODE, listItem);
      },
    );
  });

  describe('OL LI visitor', () => {
    it.each`
      listItem              | result              | incrementListMarker | action
      ${'2. list item'}     | ${'1. list item'}   | ${false}            | ${'increments'}
      ${'  3. list item'}   | ${'  1. list item'} | ${false}            | ${'increments'}
      ${'  123. list item'} | ${'  1. list item'} | ${false}            | ${'increments'}
      ${'3. list item'}     | ${'3. list item'}   | ${true}             | ${'does not increment'}
    `(
      '$action a list item counter when incrementListMaker is $incrementListMarker',
      ({ listItem, result, incrementListMarker }) => {
        const subContent = null;

        htmlToMarkdownRenderer = buildHTMLToMarkdownRenderer(baseRenderer, {
          incrementListMarker,
        });
        baseRenderer.convert.mockReturnValueOnce(listItem);

        expect(htmlToMarkdownRenderer['OL LI'](NODE, subContent)).toBe(result);
        expect(baseRenderer.convert).toHaveBeenCalledWith(NODE, subContent);
      },
    );
  });

  describe('STRONG, B visitor', () => {
    it.each`
      input                | strongCharacter | result
      ${'**strong text**'} | ${'_'}          | ${'__strong text__'}
      ${'__strong text__'} | ${'*'}          | ${'**strong text**'}
    `(
      'converts $input to $result when strong character is $strongCharacter',
      ({ input, strongCharacter, result }) => {
        htmlToMarkdownRenderer = buildHTMLToMarkdownRenderer(baseRenderer, {
          strong: strongCharacter,
        });

        baseRenderer.convert.mockReturnValueOnce(input);

        expect(htmlToMarkdownRenderer['STRONG, B'](NODE, input)).toBe(result);
        expect(baseRenderer.convert).toHaveBeenCalledWith(NODE, input);
      },
    );
  });

  describe('EM, I visitor', () => {
    it.each`
      input              | emphasisCharacter | result
      ${'*strong text*'} | ${'_'}            | ${'_strong text_'}
      ${'_strong text_'} | ${'*'}            | ${'*strong text*'}
    `(
      'converts $input to $result when emphasis character is $emphasisCharacter',
      ({ input, emphasisCharacter, result }) => {
        htmlToMarkdownRenderer = buildHTMLToMarkdownRenderer(baseRenderer, {
          emphasis: emphasisCharacter,
        });

        baseRenderer.convert.mockReturnValueOnce(input);

        expect(htmlToMarkdownRenderer['EM, I'](NODE, input)).toBe(result);
        expect(baseRenderer.convert).toHaveBeenCalledWith(NODE, input);
      },
    );
  });
});