aboutsummaryrefslogtreecommitdiff
path: root/js/test.js
blob: b231b21c704a24a9da3703f4cb745f23eb28545d (plain)
  1. #!/usr/bin/env node
  2. "use strict";
  3. var fs = require('fs');
  4. var commonmark = require('./lib/index.js');
  5. // Home made mini-version of the npm ansi module:
  6. var escSeq = function(s) {
  7. return function (){
  8. process.stdout.write('\u001b' + s);
  9. return this;
  10. };
  11. };
  12. var repeat = function(pattern, count) {
  13. if (count < 1) {
  14. return '';
  15. }
  16. var result = '';
  17. while (count > 1) {
  18. if (count & 1) {
  19. result += pattern;
  20. }
  21. count >>= 1, pattern += pattern;
  22. }
  23. return result + pattern;
  24. };
  25. var cursor = {
  26. write: function (s) {
  27. process.stdout.write(s);
  28. return this;
  29. },
  30. green: escSeq('[0;32m'),
  31. red: escSeq('[0;31m'),
  32. cyan: escSeq('[0;36m'),
  33. reset: escSeq('[0m')
  34. };
  35. var writer = new commonmark.HtmlRenderer();
  36. var reader = new commonmark.DocParser();
  37. var results = {
  38. passed: 0,
  39. failed: 0
  40. };
  41. var showSpaces = function(s) {
  42. var t = s;
  43. return t.replace(/\t/g, '→')
  44. .replace(/ /g, '␣');
  45. };
  46. var pathologicalTest = function(testcase, results) {
  47. cursor.write(testcase.name + ' ');
  48. console.time(' elapsed time');
  49. var actual = writer.render(reader.parse(testcase.input));
  50. if (actual === testcase.expected) {
  51. cursor.green().write('✓\n').reset();
  52. results.passed += 1;
  53. } else {
  54. cursor.red().write('✘\n');
  55. cursor.cyan();
  56. cursor.write('=== markdown ===============\n');
  57. cursor.write(showSpaces(testcase.input));
  58. cursor.write('=== expected ===============\n');
  59. cursor.write(showSpaces(testcase.expected));
  60. cursor.write('=== got ====================\n');
  61. cursor.write(showSpaces(actual));
  62. cursor.write('\n');
  63. cursor.reset();
  64. results.failed += 1;
  65. }
  66. console.timeEnd(' elapsed time');
  67. };
  68. fs.readFile('spec.txt', 'utf8', function(err, data) {
  69. if (err) {
  70. return console.log(err);
  71. }
  72. var i;
  73. var examples = [];
  74. var current_section = "";
  75. var example_number = 0;
  76. var tests = data
  77. .replace(/\r\n?/g, "\n") // Normalize newlines for platform independence
  78. .replace(/^<!-- END TESTS -->(.|[\n])*/m, '');
  79. tests.replace(/^\.\n([\s\S]*?)^\.\n([\s\S]*?)^\.$|^#{1,6} *(.*)$/gm,
  80. function(_, markdownSubmatch, htmlSubmatch, sectionSubmatch){
  81. if (sectionSubmatch) {
  82. current_section = sectionSubmatch;
  83. } else {
  84. example_number++;
  85. examples.push({markdown: markdownSubmatch,
  86. html: htmlSubmatch,
  87. section: current_section,
  88. number: example_number});
  89. }
  90. });
  91. current_section = "";
  92. cursor.write('Spec tests:\n\n');
  93. console.time("Elapsed time");
  94. for (i = 0; i < examples.length; i++) {
  95. var example = examples[i];
  96. if (example.section !== current_section) {
  97. if (current_section !== '') {
  98. cursor.write('\n');
  99. }
  100. current_section = example.section;
  101. cursor.reset().write(current_section).reset().write(' ');
  102. }
  103. var actual = writer.render(reader.parse(example.markdown.replace(/→/g, '\t')));
  104. if (actual === example.html) {
  105. results.passed++;
  106. cursor.green().write('✓').reset();
  107. } else {
  108. results.failed++;
  109. cursor.write('\n');
  110. cursor.red().write('✘ Example ' + example.number + '\n');
  111. cursor.cyan();
  112. cursor.write('=== markdown ===============\n');
  113. cursor.write(showSpaces(example.markdown));
  114. cursor.write('=== expected ===============\n');
  115. cursor.write(showSpaces(example.html));
  116. cursor.write('=== got ====================\n');
  117. cursor.write(showSpaces(actual));
  118. cursor.reset();
  119. }
  120. }
  121. cursor.write('\n');
  122. console.timeEnd("Elapsed time");
  123. // pathological cases
  124. cursor.write('\nPathological cases:\n');
  125. var cases = [
  126. { name: 'U+0000 in input',
  127. input: 'abc\u0000xyz\u0000\n',
  128. expected: '<p>abc\ufffdxyz\ufffd</p>\n' },
  129. { name: 'nested strong emph 10000 deep',
  130. input: repeat('*a **a ', 10000) + 'b' + repeat(' a** a*', 10000),
  131. expected: '<p>' + repeat('<em>a <strong>a ', 10000) + 'b' +
  132. repeat(' a</strong> a</em>', 10000) + '</p>\n' },
  133. { name: 'nested brackets 10000 deep',
  134. input: repeat('[', 10000) + 'a' + repeat(']', 10000),
  135. expected: '<p>' + repeat('[', 10000) + 'a' + repeat(']', 10000) +
  136. '</p>\n' },
  137. { name: 'nested block quote 10000 deep',
  138. input: repeat('> ', 10000) + 'a\n',
  139. expected: repeat('<blockquote>\n', 10000) + '<p>a</p>\n' +
  140. repeat('</blockquote>\n', 10000) }
  141. ];
  142. for (var i = 0; i < cases.length; i++) {
  143. pathologicalTest(cases[i], results);
  144. }
  145. cursor.write('\n');
  146. cursor.write(results.passed.toString() + ' tests passed, ' +
  147. results.failed.toString() + ' failed.\n');
  148. });