github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/public/libs/to-markdown/test/to-markdown-test.js (about)

     1  /* global QUnit, test, equal, throws, asyncTest, start */
     2  
     3  'use strict';
     4  
     5  if (typeof module !== 'undefined' && module.exports) {
     6    var toMarkdown = require('../index');
     7  }
     8  
     9  // Test cases are in the format: [html, expectedMarkdown, message];
    10  function runTestCases(testCases) {
    11    for (var i = 0; i < testCases.length; i++) {
    12      var testCase = testCases[i];
    13      equal(toMarkdown(testCase[0]), testCase[1], testCase[2]);
    14    }
    15  }
    16  
    17  QUnit.module('Markdown');
    18  
    19  test('paragraphs', function() {
    20    runTestCases([
    21      ['<p>Lorem ipsum</p>', 'Lorem ipsum', 'p'],
    22      ['<p>Lorem</p><p>ipsum</p>', 'Lorem\n\nipsum', 'Multiple ps']
    23    ]);
    24  });
    25  
    26  test('emphasis', function() {
    27    runTestCases([
    28      ['<b>Hello world</b>', '**Hello world**', 'b'],
    29      ['<strong>Hello world</strong>', '**Hello world**', 'strong'],
    30      ['<i>Hello world</i>', '_Hello world_', 'i'],
    31      ['<em>Hello world</em>', '_Hello world_', 'em'],
    32      ['<em>Hello</em> <em>world</em>', '_Hello_ _world_', 'Multiple ems']
    33    ]);
    34  });
    35  
    36  test('code', function() {
    37    runTestCases([
    38      ['<code>print()</code>', '`print()`']
    39    ]);
    40  });
    41  
    42  test('headings', function() {
    43    runTestCases([
    44      ['<h1>Hello world</h1>', '# Hello world', 'h1'],
    45      ['<h3>Hello world</h3>', '### Hello world', 'h3'],
    46      ['<h6>Hello world</h6>', '###### Hello world', 'h6'],
    47      ['<h4><i>Hello</i> world</h4>', '#### _Hello_ world', 'h4 with child'],
    48      ['<h8>Hello world</h8>', '<h8>Hello world</h8>', 'invalid heading']
    49    ]);
    50  });
    51  
    52  test('horizontal rules', function() {
    53    runTestCases([
    54      ['<hr />', '* * *', 'hr'],
    55      ['<hr></hr>', '* * *', 'open/closed hr']
    56    ]);
    57  });
    58  
    59  test('line breaks', function() {
    60    runTestCases([
    61      ['Hello<br />world', 'Hello  \nworld']
    62    ]);
    63  });
    64  
    65  test('images', function() {
    66    runTestCases([
    67      ['<img src="http://example.com/logo.png" />', '![](http://example.com/logo.png)', 'img with no alt'],
    68      ['<img src=logo.png>', '![](logo.png)', 'img with relative src'],
    69      ['<img src=logo.png alt="Example logo">', '![Example logo](logo.png)', 'img with alt'],
    70      ['<img>', '', 'img no src']
    71    ]);
    72  });
    73  
    74  test('anchors', function() {
    75    runTestCases([
    76      ['<a href="http://example.com/about">About us</a>', '[About us](http://example.com/about)', 'a'],
    77      ['<a href="http://example.com/about" title="About this company">About us</a>', '[About us](http://example.com/about "About this company")', 'a with title'],
    78      ['<a id="donuts3">About us</a>', '<a id="donuts3">About us</a>', 'a with no src'],
    79      ['<a href="http://example.com/about"><span>About us</span></a>', '[<span>About us</span>](http://example.com/about)', 'with a span']
    80    ]);
    81  });
    82  
    83  test('pre/code blocks', function() {
    84    runTestCases([
    85      [
    86        ['<pre><code>def hello_world',
    87        '  # 42 &lt; 9001',
    88        '  "Hello world!"',
    89        'end</code></pre>'].join('\n'),
    90  
    91        ['    def hello_world',
    92        '      # 42 < 9001',
    93        '      "Hello world!"',
    94        '    end'].join('\n')
    95      ],
    96      [
    97        ['<pre><code>def foo',
    98        '  # 42 &lt; 9001',
    99        '  \'Hello world!\'',
   100        'end</code></pre>',
   101        '<p>next:</p>',
   102        '<pre><code>def bar',
   103        '  # 42 &lt; 9001',
   104        '  \'Hello world!\'',
   105        'end</code></pre>'].join('\n'),
   106  
   107        ['    def foo',
   108        '      # 42 < 9001',
   109        '      \'Hello world!\'',
   110        '    end',
   111        '',
   112        'next:',
   113        '',
   114        '    def bar',
   115        '      # 42 < 9001',
   116        '      \'Hello world!\'',
   117        '    end'].join('\n'),
   118  
   119        'Multiple pre/code blocks'
   120      ],
   121      ['<pre>preformatted</pre>', '<pre>preformatted</pre>', 'Plain pre']
   122    ]);
   123  });
   124  
   125  test('lists', function() {
   126    runTestCases([
   127      ['1986. What a great season.', '1986\\. What a great season.', 'ol triggers are escaped'],
   128      ['<ol>\n\t<li>Hello world</li>\n\t<li>Foo bar</li>\n</ol>', '1.  Hello world\n2.  Foo bar', 'ol'],
   129      ['<ul>\n\t<li>Hello world</li>\n\t<li>Foo bar</li>\n</ul>', '*   Hello world\n*   Foo bar', 'ul'],
   130      [
   131        ['<ul>',
   132        '  <li>Hello world</li>',
   133        '  <li>Lorem ipsum</li>',
   134        '</ul>',
   135        '<ul>',
   136        '  <li>Hello world</li>',
   137        '  <li>Lorem ipsum</li>',
   138        '</ul>'].join('\n'),
   139  
   140        ['*   Hello world',
   141        '*   Lorem ipsum',
   142        '',
   143        '*   Hello world',
   144        '*   Lorem ipsum'].join('\n'),
   145  
   146        'Multiple uls'
   147      ],
   148      [
   149        '<ul><li><p>Hello world</p></li><li>Lorem ipsum</li></ul>',
   150        '*   Hello world\n\n*   Lorem ipsum',
   151        'ul with p'
   152      ],
   153      [
   154        ['<ol>',
   155        '  <li>',
   156        '    <p>This is a list item with two paragraphs.</p>',
   157        '    <p>Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.</p>',
   158        '  </li>',
   159        '  <li>',
   160        '    <p>Suspendisse id sem consectetuer libero luctus adipiscing.</p>',
   161        '  </li>',
   162        '</ol>'].join('\n'),
   163  
   164        ['1.  This is a list item with two paragraphs.',
   165        '',
   166        '    Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.',
   167        '',
   168        '2.  Suspendisse id sem consectetuer libero luctus adipiscing.'].join('\n'),
   169  
   170        'ol with multiple ps'
   171      ],
   172      [
   173        ['<ul>',
   174        '  <li>This is a list item at root level</li>',
   175        '  <li>This is another item at root level</li>',
   176        '  <li>',
   177        '    <ul>',
   178        '      <li>This is a nested list item</li>',
   179        '      <li>This is another nested list item</li>',
   180        '      <li>',
   181        '        <ul>',
   182        '          <li>This is a deeply nested list item</li>',
   183        '          <li>This is another deeply nested list item</li>',
   184        '          <li>This is a third deeply nested list item</li>',
   185        '        </ul>',
   186        '      </li>',
   187        '    </ul>',
   188        '  </li>',
   189        '  <li>This is a third item at root level</li>',
   190        '</ul>'].join('\n'),
   191  
   192        ['*   This is a list item at root level',
   193        '*   This is another item at root level',
   194        '*   *   This is a nested list item',
   195        '    *   This is another nested list item',
   196        '    *   *   This is a deeply nested list item',
   197        '        *   This is another deeply nested list item',
   198        '        *   This is a third deeply nested list item',
   199        '*   This is a third item at root level'].join('\n'),
   200  
   201        'Nested uls'
   202      ],
   203      [
   204        ['<ul>',
   205        '  <li>This is a list item at root level</li>',
   206        '  <li>This is another item at root level</li>',
   207        '  <li>',
   208        '    <ol>',
   209        '      <li>This is a nested list item</li>',
   210        '      <li>This is another nested list item</li>',
   211        '      <li>',
   212        '        <ul>',
   213        '          <li>This is a deeply nested list item</li>',
   214        '          <li>This is another deeply nested list item</li>',
   215        '          <li>This is a third deeply nested list item</li>',
   216        '        </ul>',
   217        '      </li>',
   218        '    </ol>',
   219        '  </li>',
   220        '  <li>This is a third item at root level</li>',
   221        '</ul>'].join('\n'),
   222  
   223        ['*   This is a list item at root level',
   224        '*   This is another item at root level',
   225        '*   1.  This is a nested list item',
   226        '    2.  This is another nested list item',
   227        '    3.  *   This is a deeply nested list item',
   228        '        *   This is another deeply nested list item',
   229        '        *   This is a third deeply nested list item',
   230        '*   This is a third item at root level'].join('\n'),
   231  
   232        'Nested ols'
   233      ],
   234      [
   235        ['<ul>',
   236        '  <li>',
   237        '    <p>A list item with a blockquote:</p>',
   238        '    <blockquote>',
   239        '      <p>This is a blockquote inside a list item.</p>',
   240        '    </blockquote>',
   241        '  </li>',
   242        '</ul>'].join('\n'),
   243  
   244        ['*   A list item with a blockquote:',
   245        '',
   246        '    > This is a blockquote inside a list item.'].join('\n'),
   247  
   248        'ul with blockquote'
   249      ]
   250    ]);
   251  });
   252  
   253  test('blockquotes', function() {
   254    runTestCases([
   255      [
   256        ['<blockquote>',
   257        '  <p>This is a blockquote with two paragraphs.</p>',
   258        '',
   259        '  <p>Donec sit amet nisl.</p>',
   260        '</blockquote>'].join('\n'),
   261  
   262        ['> This is a blockquote with two paragraphs.',
   263        '> ',
   264        '> Donec sit amet nisl.'].join('\n'),
   265  
   266        'blockquote with two ps'
   267      ],
   268      [
   269        ['<blockquote>',
   270        '  <p>This is the first level of quoting.</p>',
   271        '',
   272        '  <blockquote>',
   273        '    <p>This is nested blockquote.</p>',
   274        '  </blockquote>',
   275        '',
   276        '  <p>Back to the first level.</p>',
   277        '</blockquote>'].join('\n'),
   278  
   279        ['> This is the first level of quoting.',
   280        '> ',
   281        '> > This is nested blockquote.',
   282        '> ',
   283        '> Back to the first level.'].join('\n'),
   284  
   285        'Nested blockquotes'
   286      ],
   287      [
   288        ['<blockquote>',
   289        '  <h2>This is a header.</h2>',
   290        '  <ol>',
   291        '    <li>This is the first list item.</li>',
   292        '    <li>This is the second list item.</li>',
   293        '  </ol>',
   294        '  <p>Here\'s some example code:</p>',
   295        '  <pre><code>return 1 &lt; 2 ? shell_exec(\'echo $input | $markdown_script\') : 0;</code></pre>',
   296        '</blockquote>'].join('\n'),
   297  
   298        ['> ## This is a header.',
   299        '> ',
   300        '> 1.  This is the first list item.',
   301        '> 2.  This is the second list item.',
   302        '> ',
   303        '> Here\'s some example code:',
   304        '> ',
   305        '>     return 1 < 2 ? shell_exec(\'echo $input | $markdown_script\') : 0;'].join('\n'),
   306  
   307        'html in blockquote'
   308      ]
   309    ]);
   310  });
   311  
   312  test('block-level', function () {
   313    runTestCases([
   314      ['<div>Hello</div><div>world</div>', '<div>Hello</div>\n\n<div>world</div>', 'divs separated by \\n\\n'],
   315      ['<div><em>hello</em></div>', '<div>_hello_</div>']
   316    ]);
   317  });
   318  
   319  test('comments', function () {
   320    equal(toMarkdown('<!-- comment -->'), '', 'comments removed');
   321  });
   322  
   323  test('leading/trailing whitespace', function() {
   324    runTestCases([
   325      [
   326        '<p>I <a href="http://example.com">need</a> <a href="http://www.example.com">more</a> spaces!</p>',
   327        'I [need](http://example.com) [more](http://www.example.com) spaces!',
   328        'Whitespace between inline elements'
   329      ],
   330      ['<h1>\n    Header text', '# Header text', 'Leading whitespace in h1'],
   331      [
   332        ['<ol>',
   333        '  <li>Chapter One',
   334        '    <ol>',
   335        '      <li>Section One</li>',
   336        '      <li>Section Two </li>',
   337        '      <li>Section Three </li>',
   338        '    </ol>',
   339        '  </li>',
   340        '  <li>Chapter Two</li>',
   341        '  <li>Chapter Three  </li>',
   342        '</ol>'].join('\n'),
   343  
   344        ['1.  Chapter One',
   345        '    1.  Section One',
   346        '    2.  Section Two',
   347        '    3.  Section Three',
   348        '2.  Chapter Two',
   349        '3.  Chapter Three'].join('\n'),
   350  
   351        'Trailing whitespace in li'
   352      ],
   353      [
   354        ['<ul>',
   355        '  <li>', // Multilined
   356        '    Foo ',
   357        '  </li>',
   358        '  <li>', // Bizarre formatting
   359        '    <strong>Bar </strong> </li>',
   360        '  <li>Baz</li>',
   361        '</ul>',
   362        '<ol>',
   363        '  <li> Hello',
   364        '                      world',
   365        '  </li>',
   366        '</ol>'].join('\n'),
   367  
   368        ['*   Foo',
   369        '*   **Bar**',
   370        '*   Baz',
   371        '',
   372        '1.  Hello world'].join('\n')
   373      ],
   374      [
   375        'Hello world.<em> Foo </em><strong>bar </strong>',
   376        'Hello world. _Foo_ **bar**',
   377        'Whitespace in inline elements'
   378      ]
   379    ]);
   380  });
   381  
   382  test('blank', function () {
   383    runTestCases([
   384      ['<div></div>', '', 'Blank div'],
   385      ['<em></em>', '', 'Blank em'],
   386      ['<strong><br></strong>', '', 'Blank strong with br'],
   387      ['<a href="#foo"></a>', '[](#foo)', 'Blank a'],
   388    ]);
   389  });
   390  
   391  test('custom converters', function() {
   392    var html, converter, md = '*Hello world*';
   393    var replacement = function (innerHTML) {
   394      return '*' + innerHTML + '*';
   395    };
   396  
   397    html = '<span>Hello world</span>';
   398    converter = {
   399      filter: 'span',
   400      replacement: replacement
   401    };
   402    equal(toMarkdown(html, {converters: [converter]}), md, 'Custom filter string');
   403  
   404    html = '<span>Hello world</span>';
   405    converter = {
   406      filter: ['span'],
   407      replacement: replacement
   408    };
   409    equal(toMarkdown(html, {converters: [converter]}), md, 'Custom filter array');
   410  
   411    html = '<span style="font-style: italic">Hello world</span>';
   412    converter = {
   413      filter: function (node) {
   414        return node.tagName === 'SPAN' && /italic/i.test(node.style.fontStyle);
   415      },
   416      replacement: replacement
   417    };
   418    equal(toMarkdown(html, {converters: [converter]}), md, 'Custom filter function');
   419  });
   420  
   421  test('invalid input', function () {
   422    throws(function () { toMarkdown(null); }, /null is not a string/, 'null input');
   423    throws(function () { toMarkdown(void(0)); }, /undefined is not a string/, 'undefined input');
   424  
   425    throws(function () { toMarkdown(null); }, function (e) {
   426      return e.name === 'TypeError';
   427    }, 'error type');
   428  });
   429  
   430  asyncTest('img[onerror]', 1, function () {
   431    start();
   432    equal(toMarkdown('>\'>"><img src=x onerror="(function () { ok(true); })()">'), '>\'>">![](x)', 'We expect img[onerror] functions not to run');
   433  });