Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(637)

Side by Side Diff: dart/third_party/pkg/markdown/test/markdown_test.dart

Issue 20722006: Removed compiler/ directory from repository (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 /// Unit tests for markdown.
6 library markdownTests;
7
8 import 'package:unittest/unittest.dart';
9
10 // TODO(rnystrom): Use "package:" URL (#4968).
11 import '../lib/markdown.dart';
12
13 /// Most of these tests are based on observing how showdown behaves:
14 /// http://softwaremaniacs.org/playground/showdown-highlight/
15 void main() {
16 group('Paragraphs', () {
17 validate('consecutive lines form a single paragraph', '''
18 This is the first line.
19 This is the second line.
20 ''', '''
21 <p>This is the first line.
22 This is the second line.</p>
23 ''');
24
25 // TODO(rnystrom): The rules here for what happens to lines following a
26 // paragraph appear to be completely arbitrary in markdown. If it makes the
27 // code significantly cleaner, we should consider ourselves free to change
28 // these tests.
29
30 validate('are terminated by a header', '''
31 para
32 # header
33 ''', '''
34 <p>para</p>
35 <h1>header</h1>
36 ''');
37
38 validate('are terminated by a setext header', '''
39 para
40 header
41 ==
42 ''', '''
43 <p>para</p>
44 <h1>header</h1>
45 ''');
46
47 validate('are terminated by a hr', '''
48 para
49 ___
50 ''', '''
51 <p>para</p>
52 <hr />
53 ''');
54
55 validate('consume an unordered list', '''
56 para
57 * list
58 ''', '''
59 <p>para
60 * list</p>
61 ''');
62
63 validate('consume an ordered list', '''
64 para
65 1. list
66 ''', '''
67 <p>para
68 1. list</p>
69 ''');
70
71 // Windows line endings have a \r\n format
72 // instead of the unix \n format.
73 validate('take account of windows line endings', '''
74 line1\r\n\r\n line2\r\n
75 ''', '''
76 <p>line1</p>
77 <p>line2</p>
78 ''');
79 });
80
81 group('Setext headers', () {
82 validate('h1', '''
83 text
84 ===
85 ''', '''
86 <h1>text</h1>
87 ''');
88
89 validate('h2', '''
90 text
91 ---
92 ''', '''
93 <h2>text</h2>
94 ''');
95
96 validate('h1 on first line becomes text', '''
97 ===
98 ''', '''
99 <p>===</p>
100 ''');
101
102 validate('h2 on first line becomes text', '''
103 -
104 ''', '''
105 <p>-</p>
106 ''');
107
108 validate('h1 turns preceding list into text', '''
109 - list
110 ===
111 ''', '''
112 <h1>- list</h1>
113 ''');
114
115 validate('h2 turns preceding list into text', '''
116 - list
117 ===
118 ''', '''
119 <h1>- list</h1>
120 ''');
121
122 validate('h1 turns preceding blockquote into text', '''
123 > quote
124 ===
125 ''', '''
126 <h1>> quote</h1>
127 ''');
128
129 validate('h2 turns preceding blockquote into text', '''
130 > quote
131 ===
132 ''', '''
133 <h1>> quote</h1>
134 ''');
135 });
136
137 group('Headers', () {
138 validate('h1', '''
139 # header
140 ''', '''
141 <h1>header</h1>
142 ''');
143
144 validate('h2', '''
145 ## header
146 ''', '''
147 <h2>header</h2>
148 ''');
149
150 validate('h3', '''
151 ### header
152 ''', '''
153 <h3>header</h3>
154 ''');
155
156 validate('h4', '''
157 #### header
158 ''', '''
159 <h4>header</h4>
160 ''');
161
162 validate('h5', '''
163 ##### header
164 ''', '''
165 <h5>header</h5>
166 ''');
167
168 validate('h6', '''
169 ###### header
170 ''', '''
171 <h6>header</h6>
172 ''');
173
174 validate('trailing "#" are removed', '''
175 # header ######
176 ''', '''
177 <h1>header</h1>
178 ''');
179
180 });
181
182 group('Unordered lists', () {
183 validate('asterisk, plus and hyphen', '''
184 * star
185 - dash
186 + plus
187 ''', '''
188 <ul>
189 <li>star</li>
190 <li>dash</li>
191 <li>plus</li>
192 </ul>
193 ''');
194
195 validate('allow numbered lines after first', '''
196 * a
197 1. b
198 ''', '''
199 <ul>
200 <li>a</li>
201 <li>b</li>
202 </ul>
203 ''');
204
205 validate('allow a tab after the marker', '''
206 *\ta
207 +\tb
208 -\tc
209 1.\td
210 ''', '''
211 <ul>
212 <li>a</li>
213 <li>b</li>
214 <li>c</li>
215 <li>d</li>
216 </ul>
217 ''');
218
219 validate('wrap items in paragraphs if blank lines separate', '''
220 * one
221
222 * two
223 ''', '''
224 <ul>
225 <li><p>one</p></li>
226 <li><p>two</p></li>
227 </ul>
228 ''');
229
230 validate('force paragraph on item before and after blank lines', '''
231 * one
232 * two
233
234 * three
235 ''', '''
236 <ul>
237 <li>one</li>
238 <li>
239 <p>two</p>
240 </li>
241 <li>
242 <p>three</p>
243 </li>
244 </ul>
245 ''');
246
247 validate('do not force paragraph if item is already block', '''
248 * > quote
249
250 * # header
251 ''', '''
252 <ul>
253 <li><blockquote><p>quote</p></blockquote></li>
254 <li><h1>header</h1></li>
255 </ul>
256 ''');
257
258 validate('can contain multiple paragraphs', '''
259 * one
260
261 two
262
263 * three
264 ''', '''
265 <ul>
266 <li>
267 <p>one</p>
268 <p>two</p>
269 </li>
270 <li>
271 <p>three</p>
272 </li>
273 </ul>
274 ''');
275
276 validate('can span newlines', '''
277 * one
278 two
279 * three
280 ''', '''
281 <ul>
282 <li>
283 <p>one
284 two</p>
285 </li>
286 <li>
287 three
288 </li>
289 </ul>
290 ''');
291
292 // TODO(rnystrom): This is how most other markdown parsers handle
293 // this but that seems like a nasty special case. For now, let's not
294 // worry about it.
295 /*
296 validate('can nest using indentation', '''
297 * parent
298 * child
299 ''', '''
300 <ul>
301 <li>parent
302 <ul><li>child</li></ul></li>
303 </ul>
304 ''');
305 */
306 });
307
308 group('Ordered lists', () {
309 validate('start with numbers', '''
310 1. one
311 45. two
312 12345. three
313 ''', '''
314 <ol>
315 <li>one</li>
316 <li>two</li>
317 <li>three</li>
318 </ol>
319 ''');
320
321 validate('allow unordered lines after first', '''
322 1. a
323 * b
324 ''', '''
325 <ol>
326 <li>a</li>
327 <li>b</li>
328 </ol>
329 ''');
330 });
331
332 group('Blockquotes', () {
333 validate('single line', '''
334 > blah
335 ''', '''
336 <blockquote>
337 <p>blah</p>
338 </blockquote>
339 ''');
340
341 validate('with two paragraphs', '''
342 > first
343 >
344 > second
345 ''', '''
346 <blockquote>
347 <p>first</p>
348 <p>second</p>
349 </blockquote>
350 ''');
351
352 validate('nested', '''
353 > one
354 >> two
355 > > > three
356 ''', '''
357 <blockquote>
358 <p>one</p>
359 <blockquote>
360 <p>two</p>
361 <blockquote>
362 <p>three</p>
363 </blockquote>
364 </blockquote>
365 </blockquote>
366 ''');
367 });
368
369 group('Code blocks', () {
370 validate('single line', '''
371 code
372 ''', '''
373 <pre><code>code</code></pre>
374 ''');
375
376 validate('include leading whitespace after indentation', '''
377 zero
378 one
379 two
380 three
381 ''', '''
382 <pre><code>zero
383 one
384 two
385 three</code></pre>
386 ''');
387
388 validate('code blocks separated by newlines form one block', '''
389 zero
390 one
391
392 two
393
394 three
395 ''', '''
396 <pre><code>zero
397 one
398
399 two
400
401 three</code></pre>
402 ''');
403
404 validate('code blocks separated by two newlines form multiple blocks', '''
405 zero
406 one
407
408
409 two
410
411
412 three
413 ''', '''
414 <pre><code>zero
415 one</code></pre>
416 <pre><code>two</code></pre>
417 <pre><code>three</code></pre>
418 ''');
419
420 validate('escape HTML characters', '''
421 <&>
422 ''', '''
423 <pre><code>&lt;&amp;&gt;</code></pre>
424 ''');
425 });
426
427 group('Fenced code blocks', () {
428 validate('without an optional language identifier', '''
429 ```
430 code
431 ```
432 ''', '''
433 <pre><code>code
434 </code></pre>
435 ''');
436
437 validate('with an optional language identifier', '''
438 ```dart
439 code
440 ```
441 ''', '''
442 <pre><code>code
443 </code></pre>
444 ''');
445
446 validate('escape HTML characters', '''
447 ```
448 <&>
449 ```
450 ''', '''
451 <pre><code>&lt;&amp;&gt;
452 </code></pre>
453 ''');
454 });
455
456 group('Horizontal rules', () {
457 validate('from dashes', '''
458 ---
459 ''', '''
460 <hr />
461 ''');
462
463 validate('from asterisks', '''
464 ***
465 ''', '''
466 <hr />
467 ''');
468
469 validate('from underscores', '''
470 ___
471 ''', '''
472 <hr />
473 ''');
474
475 validate('can include up to two spaces', '''
476 _ _ _
477 ''', '''
478 <hr />
479 ''');
480 });
481
482 group('Block-level HTML', () {
483 validate('single line', '''
484 <table></table>
485 ''', '''
486 <table></table>
487 ''');
488
489 validate('multi-line', '''
490 <table>
491 blah
492 </table>
493 ''', '''
494 <table>
495 blah
496 </table>
497 ''');
498
499 validate('blank line ends block', '''
500 <table>
501 blah
502 </table>
503
504 para
505 ''', '''
506 <table>
507 blah
508 </table>
509 <p>para</p>
510 ''');
511
512 validate('HTML can be bogus', '''
513 <bogus>
514 blah
515 </weird>
516
517 para
518 ''', '''
519 <bogus>
520 blah
521 </weird>
522 <p>para</p>
523 ''');
524 });
525
526 group('Strong', () {
527 validate('using asterisks', '''
528 before **strong** after
529 ''', '''
530 <p>before <strong>strong</strong> after</p>
531 ''');
532
533 validate('using underscores', '''
534 before __strong__ after
535 ''', '''
536 <p>before <strong>strong</strong> after</p>
537 ''');
538
539 validate('unmatched asterisks', '''
540 before ** after
541 ''', '''
542 <p>before ** after</p>
543 ''');
544
545 validate('unmatched underscores', '''
546 before __ after
547 ''', '''
548 <p>before __ after</p>
549 ''');
550
551 validate('multiple spans in one text', '''
552 a **one** b __two__ c
553 ''', '''
554 <p>a <strong>one</strong> b <strong>two</strong> c</p>
555 ''');
556
557 validate('multi-line', '''
558 before **first
559 second** after
560 ''', '''
561 <p>before <strong>first
562 second</strong> after</p>
563 ''');
564 });
565
566 group('Emphasis and strong', () {
567 validate('single asterisks', '''
568 before *em* after
569 ''', '''
570 <p>before <em>em</em> after</p>
571 ''');
572
573 validate('single underscores', '''
574 before _em_ after
575 ''', '''
576 <p>before <em>em</em> after</p>
577 ''');
578
579 validate('double asterisks', '''
580 before **strong** after
581 ''', '''
582 <p>before <strong>strong</strong> after</p>
583 ''');
584
585 validate('double underscores', '''
586 before __strong__ after
587 ''', '''
588 <p>before <strong>strong</strong> after</p>
589 ''');
590
591 validate('unmatched asterisk', '''
592 before *after
593 ''', '''
594 <p>before *after</p>
595 ''');
596
597 validate('unmatched underscore', '''
598 before _after
599 ''', '''
600 <p>before _after</p>
601 ''');
602
603 validate('multiple spans in one text', '''
604 a *one* b _two_ c
605 ''', '''
606 <p>a <em>one</em> b <em>two</em> c</p>
607 ''');
608
609 validate('multi-line', '''
610 before *first
611 second* after
612 ''', '''
613 <p>before <em>first
614 second</em> after</p>
615 ''');
616
617 validate('not processed when surrounded by spaces', '''
618 a * b * c _ d _ e
619 ''', '''
620 <p>a * b * c _ d _ e</p>
621 ''');
622
623 validate('strong then emphasis', '''
624 **strong***em*
625 ''', '''
626 <p><strong>strong</strong><em>em</em></p>
627 ''');
628
629 validate('emphasis then strong', '''
630 *em***strong**
631 ''', '''
632 <p><em>em</em><strong>strong</strong></p>
633 ''');
634
635 validate('emphasis inside strong', '''
636 **strong *em***
637 ''', '''
638 <p><strong>strong <em>em</em></strong></p>
639 ''');
640
641 validate('mismatched in nested', '''
642 *a _b* c_
643 ''', '''
644 <p><em>a _b</em> c_</p>
645 ''');
646
647 validate('cannot nest tags of same type', '''
648 *a _b *c* d_ e*
649 ''', '''
650 <p><em>a _b </em>c<em> d_ e</em></p>
651 ''');
652 });
653
654 group('Inline code', () {
655 validate('simple case', '''
656 before `source` after
657 ''', '''
658 <p>before <code>source</code> after</p>
659 ''');
660
661 validate('unmatched backtick', '''
662 before ` after
663 ''', '''
664 <p>before ` after</p>
665 ''');
666 validate('multiple spans in one text', '''
667 a `one` b `two` c
668 ''', '''
669 <p>a <code>one</code> b <code>two</code> c</p>
670 ''');
671
672 validate('multi-line', '''
673 before `first
674 second` after
675 ''', '''
676 <p>before <code>first
677 second</code> after</p>
678 ''');
679
680 validate('simple double backticks', '''
681 before ``source`` after
682 ''', '''
683 <p>before <code>source</code> after</p>
684 ''');
685
686 validate('double backticks', '''
687 before ``can `contain` backticks`` after
688 ''', '''
689 <p>before <code>can `contain` backticks</code> after</p>
690 ''');
691
692 validate('double backticks with spaces', '''
693 before `` `tick` `` after
694 ''', '''
695 <p>before <code>`tick`</code> after</p>
696 ''');
697
698 validate('multiline double backticks with spaces', '''
699 before ``in `tick`
700 another`` after
701 ''', '''
702 <p>before <code>in `tick`
703 another</code> after</p>
704 ''');
705
706 validate('ignore markup inside code', '''
707 before `*b* _c_` after
708 ''', '''
709 <p>before <code>*b* _c_</code> after</p>
710 ''');
711
712 validate('escape HTML characters', '''
713 `<&>`
714 ''', '''
715 <p><code>&lt;&amp;&gt;</code></p>
716 ''');
717
718 validate('escape HTML tags', '''
719 '*' `<em>`
720 ''', '''
721 <p>'*' <code>&lt;em&gt;</code></p>
722 ''');
723 });
724
725 group('HTML encoding', () {
726 validate('less than and ampersand are escaped', '''
727 < &
728 ''', '''
729 <p>&lt; &amp;</p>
730 ''');
731 validate('greater than is not escaped', '''
732 not you >
733 ''', '''
734 <p>not you ></p>
735 ''');
736 validate('existing entities are untouched', '''
737 &amp;
738 ''', '''
739 <p>&amp;</p>
740 ''');
741 });
742
743 group('Autolinks', () {
744 validate('basic link', '''
745 before <http://foo.com/> after
746 ''', '''
747 <p>before <a href="http://foo.com/">http://foo.com/</a> after</p>
748 ''');
749 validate('handles ampersand in url', '''
750 <http://foo.com/?a=1&b=2>
751 ''', '''
752 <p><a href="http://foo.com/?a=1&b=2">http://foo.com/?a=1&amp;b=2</a></p>
753 ''');
754 });
755
756 group('Reference links', () {
757 validate('double quotes for title', '''
758 links [are] [a] awesome
759
760 [a]: http://foo.com "woo"
761 ''', '''
762 <p>links <a href="http://foo.com" title="woo">are</a> awesome</p>
763 ''');
764 validate('single quoted title', """
765 links [are] [a] awesome
766
767 [a]: http://foo.com 'woo'
768 """, '''
769 <p>links <a href="http://foo.com" title="woo">are</a> awesome</p>
770 ''');
771 validate('parentheses for title', '''
772 links [are] [a] awesome
773
774 [a]: http://foo.com (woo)
775 ''', '''
776 <p>links <a href="http://foo.com" title="woo">are</a> awesome</p>
777 ''');
778 validate('no title', '''
779 links [are] [a] awesome
780
781 [a]: http://foo.com
782 ''', '''
783 <p>links <a href="http://foo.com">are</a> awesome</p>
784 ''');
785 validate('unknown link becomes plaintext', '''
786 [not] [known]
787 ''', '''
788 <p>[not] [known]</p>
789 ''');
790 validate('can style link contents', '''
791 links [*are*] [a] awesome
792
793 [a]: http://foo.com
794 ''', '''
795 <p>links <a href="http://foo.com"><em>are</em></a> awesome</p>
796 ''');
797 validate('inline styles after a bad link are processed', '''
798 [bad] `code`
799 ''', '''
800 <p>[bad] <code>code</code></p>
801 ''');
802 validate('empty reference uses text from link', '''
803 links [are][] awesome
804
805 [are]: http://foo.com
806 ''', '''
807 <p>links <a href="http://foo.com">are</a> awesome</p>
808 ''');
809 validate('references are case-insensitive', '''
810 links [ARE][] awesome
811
812 [are]: http://foo.com
813 ''', '''
814 <p>links <a href="http://foo.com">ARE</a> awesome</p>
815 ''');
816 });
817
818 group('Inline links', () {
819 validate('double quotes for title', '''
820 links [are](http://foo.com "woo") awesome
821 ''', '''
822 <p>links <a href="http://foo.com" title="woo">are</a> awesome</p>
823 ''');
824 validate('no title', '''
825 links [are] (http://foo.com) awesome
826 ''', '''
827 <p>links <a href="http://foo.com">are</a> awesome</p>
828 ''');
829 validate('can style link contents', '''
830 links [*are*](http://foo.com) awesome
831 ''', '''
832 <p>links <a href="http://foo.com"><em>are</em></a> awesome</p>
833 ''');
834 });
835
836 group('Resolver', () {
837 var nyanResolver = (text) => new Text('~=[,,_${text}_,,]:3');
838 validate('simple resolver', '''
839 resolve [this] thing
840 ''', '''
841 <p>resolve ~=[,,_this_,,]:3 thing</p>
842 ''', linkResolver: nyanResolver);
843 });
844
845 group('Custom inline syntax', () {
846 List<InlineSyntax> nyanSyntax =
847 [new TextSyntax('nyan', sub: '~=[,,_,,]:3')];
848 validate('simple inline syntax', '''
849 nyan
850 ''', '''
851 <p>~=[,,_,,]:3</p>
852 ''', inlineSyntaxes: nyanSyntax);
853
854 // TODO(amouravski): need more tests here for custom syntaxes, as some
855 // things are not quite working properly. The regexps are sometime a little
856 // too greedy, I think.
857 });
858 }
859
860 /**
861 * Removes eight spaces of leading indentation from a multiline string.
862 *
863 * Note that this is very sensitive to how the literals are styled. They should
864 * be:
865 * '''
866 * Text starts on own line. Lines up with subsequent lines.
867 * Lines are indented exactly 8 characters from the left margin.'''
868 *
869 * This does nothing if text is only a single line.
870 */
871 // TODO(nweiz): Make this auto-detect the indentation level from the first
872 // non-whitespace line.
873 String cleanUpLiteral(String text) {
874 var lines = text.split('\n');
875 if (lines.length <= 1) return text;
876
877 for (var j = 0; j < lines.length; j++) {
878 if (lines[j].length > 8) {
879 lines[j] = lines[j].substring(8, lines[j].length);
880 } else {
881 lines[j] = '';
882 }
883 }
884
885 return lines.join('\n');
886 }
887
888 validate(String description, String markdown, String html,
889 {bool verbose: false, inlineSyntaxes, linkResolver}) {
890 test(description, () {
891 markdown = cleanUpLiteral(markdown);
892 html = cleanUpLiteral(html);
893
894 var result = markdownToHtml(markdown, inlineSyntaxes: inlineSyntaxes,
895 linkResolver: linkResolver);
896 var passed = compareOutput(html, result);
897
898 if (!passed) {
899 // Remove trailing newline.
900 html = html.substring(0, html.length - 1);
901
902 print('FAIL: $description');
903 print(' expect: ${html.replaceAll("\n", "\n ")}');
904 print(' actual: ${result.replaceAll("\n", "\n ")}');
905 print('');
906 }
907
908 expect(passed, isTrue, verbose: verbose);
909 });
910 }
911
912 /// Does a loose comparison of the two strings of HTML. Ignores differences in
913 /// newlines and indentation.
914 compareOutput(String a, String b) {
915 int i = 0;
916 int j = 0;
917
918 skipIgnored(String s, int i) {
919 // Ignore newlines.
920 while ((i < s.length) && (s[i] == '\n')) {
921 i++;
922 // Ignore indentation.
923 while ((i < s.length) && (s[i] == ' ')) i++;
924 }
925
926 return i;
927 }
928
929 while (true) {
930 i = skipIgnored(a, i);
931 j = skipIgnored(b, j);
932
933 // If one string runs out of non-ignored strings, the other must too.
934 if (i == a.length) return j == b.length;
935 if (j == b.length) return i == a.length;
936
937 if (a[i] != b[j]) return false;
938 i++;
939 j++;
940 }
941 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698