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

Side by Side Diff: samples/markdown/test/markdown_tests.dart

Issue 10154010: test rename overhaul: step 3 _tests.dart => _test.dart (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 8 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('markdown_tests');
7
8 #import('../lib.dart');
9
10 // TODO(rnystrom): Better path to unittest.
11 #import('../../../lib/unittest/unittest.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
72 group('Setext headers', () {
73 validate('h1', '''
74 text
75 ===
76 ''', '''
77 <h1>text</h1>
78 ''');
79
80 validate('h2', '''
81 text
82 ---
83 ''', '''
84 <h2>text</h2>
85 ''');
86
87 validate('h1 on first line becomes text', '''
88 ===
89 ''', '''
90 <p>===</p>
91 ''');
92
93 validate('h2 on first line becomes text', '''
94 -
95 ''', '''
96 <p>-</p>
97 ''');
98
99 validate('h1 turns preceding list into text', '''
100 - list
101 ===
102 ''', '''
103 <h1>- list</h1>
104 ''');
105
106 validate('h2 turns preceding list into text', '''
107 - list
108 ===
109 ''', '''
110 <h1>- list</h1>
111 ''');
112
113 validate('h1 turns preceding blockquote into text', '''
114 > quote
115 ===
116 ''', '''
117 <h1>> quote</h1>
118 ''');
119
120 validate('h2 turns preceding blockquote into text', '''
121 > quote
122 ===
123 ''', '''
124 <h1>> quote</h1>
125 ''');
126 });
127
128 group('Headers', () {
129 validate('h1', '''
130 # header
131 ''', '''
132 <h1>header</h1>
133 ''');
134
135 validate('h2', '''
136 ## header
137 ''', '''
138 <h2>header</h2>
139 ''');
140
141 validate('h3', '''
142 ### header
143 ''', '''
144 <h3>header</h3>
145 ''');
146
147 validate('h4', '''
148 #### header
149 ''', '''
150 <h4>header</h4>
151 ''');
152
153 validate('h5', '''
154 ##### header
155 ''', '''
156 <h5>header</h5>
157 ''');
158
159 validate('h6', '''
160 ###### header
161 ''', '''
162 <h6>header</h6>
163 ''');
164
165 validate('trailing "#" are removed', '''
166 # header ######
167 ''', '''
168 <h1>header</h1>
169 ''');
170
171 });
172
173 group('Unordered lists', () {
174 validate('asterisk, plus and hyphen', '''
175 * star
176 - dash
177 + plus
178 ''', '''
179 <ul>
180 <li>star</li>
181 <li>dash</li>
182 <li>plus</li>
183 </ul>
184 ''');
185
186 validate('allow numbered lines after first', '''
187 * a
188 1. b
189 ''', '''
190 <ul>
191 <li>a</li>
192 <li>b</li>
193 </ul>
194 ''');
195
196 validate('allow a tab after the marker', '''
197 *\ta
198 +\tb
199 -\tc
200 1.\td
201 ''', '''
202 <ul>
203 <li>a</li>
204 <li>b</li>
205 <li>c</li>
206 <li>d</li>
207 </ul>
208 ''');
209
210 validate('wrap items in paragraphs if blank lines separate', '''
211 * one
212
213 * two
214 ''', '''
215 <ul>
216 <li><p>one</p></li>
217 <li><p>two</p></li>
218 </ul>
219 ''');
220
221 validate('force paragraph on item before and after blank lines', '''
222 * one
223 * two
224
225 * three
226 ''', '''
227 <ul>
228 <li>one</li>
229 <li>
230 <p>two</p>
231 </li>
232 <li>
233 <p>three</p>
234 </li>
235 </ul>
236 ''');
237
238 validate('do not force paragraph if item is already block', '''
239 * > quote
240
241 * # header
242 ''', '''
243 <ul>
244 <li><blockquote><p>quote</p></blockquote></li>
245 <li><h1>header</h1></li>
246 </ul>
247 ''');
248
249 validate('can contain multiple paragraphs', '''
250 * one
251
252 two
253
254 * three
255 ''', '''
256 <ul>
257 <li>
258 <p>one</p>
259 <p>two</p>
260 </li>
261 <li>
262 <p>three</p>
263 </li>
264 </ul>
265 ''');
266
267 // TODO(rnystrom): This is how most other markdown parsers handle
268 // this but that seems like a nasty special case. For now, let's not
269 // worry about it.
270 /*
271 validate('can nest using indentation', '''
272 * parent
273 * child
274 ''', '''
275 <ul>
276 <li>parent
277 <ul><li>child</li></ul></li>
278 </ul>
279 ''');
280 */
281 });
282
283 group('Ordered lists', () {
284 validate('start with numbers', '''
285 1. one
286 45. two
287 12345. three
288 ''', '''
289 <ol>
290 <li>one</li>
291 <li>two</li>
292 <li>three</li>
293 </ol>
294 ''');
295
296 validate('allow unordered lines after first', '''
297 1. a
298 * b
299 ''', '''
300 <ol>
301 <li>a</li>
302 <li>b</li>
303 </ol>
304 ''');
305 });
306
307 group('Blockquotes', () {
308 validate('single line', '''
309 > blah
310 ''', '''
311 <blockquote>
312 <p>blah</p>
313 </blockquote>
314 ''');
315
316 validate('with two paragraphs', '''
317 > first
318 >
319 > second
320 ''', '''
321 <blockquote>
322 <p>first</p>
323 <p>second</p>
324 </blockquote>
325 ''');
326
327 validate('nested', '''
328 > one
329 >> two
330 > > > three
331 ''', '''
332 <blockquote>
333 <p>one</p>
334 <blockquote>
335 <p>two</p>
336 <blockquote>
337 <p>three</p>
338 </blockquote>
339 </blockquote>
340 </blockquote>
341 ''');
342 });
343
344 group('Code blocks', () {
345 validate('single line', '''
346 code
347 ''', '''
348 <pre><code>code</code></pre>
349 ''');
350
351 validate('include leading whitespace after indentation', '''
352 zero
353 one
354 two
355 three
356 ''', '''
357 <pre><code>zero
358 one
359 two
360 three</code></pre>
361 ''');
362
363 validate('escape HTML characters', '''
364 <&>
365 ''', '''
366 <pre><code>&lt;&amp;&gt;</code></pre>
367 ''');
368 });
369
370 group('Horizontal rules', () {
371 validate('from dashes', '''
372 ---
373 ''', '''
374 <hr />
375 ''');
376
377 validate('from asterisks', '''
378 ***
379 ''', '''
380 <hr />
381 ''');
382
383 validate('from underscores', '''
384 ___
385 ''', '''
386 <hr />
387 ''');
388
389 validate('can include up to two spaces', '''
390 _ _ _
391 ''', '''
392 <hr />
393 ''');
394 });
395
396 group('Block-level HTML', () {
397 validate('single line', '''
398 <table></table>
399 ''', '''
400 <table></table>
401 ''');
402
403 validate('multi-line', '''
404 <table>
405 blah
406 </table>
407 ''', '''
408 <table>
409 blah
410 </table>
411 ''');
412
413 validate('blank line ends block', '''
414 <table>
415 blah
416 </table>
417
418 para
419 ''', '''
420 <table>
421 blah
422 </table>
423 <p>para</p>
424 ''');
425
426 validate('HTML can be bogus', '''
427 <bogus>
428 blah
429 </weird>
430
431 para
432 ''', '''
433 <bogus>
434 blah
435 </weird>
436 <p>para</p>
437 ''');
438 });
439
440 group('Strong', () {
441 validate('using asterisks', '''
442 before **strong** after
443 ''', '''
444 <p>before <strong>strong</strong> after</p>
445 ''');
446
447 validate('using underscores', '''
448 before __strong__ after
449 ''', '''
450 <p>before <strong>strong</strong> after</p>
451 ''');
452
453 validate('unmatched asterisks', '''
454 before ** after
455 ''', '''
456 <p>before ** after</p>
457 ''');
458
459 validate('unmatched underscores', '''
460 before __ after
461 ''', '''
462 <p>before __ after</p>
463 ''');
464
465 validate('multiple spans in one text', '''
466 a **one** b __two__ c
467 ''', '''
468 <p>a <strong>one</strong> b <strong>two</strong> c</p>
469 ''');
470
471 validate('multi-line', '''
472 before **first
473 second** after
474 ''', '''
475 <p>before <strong>first
476 second</strong> after</p>
477 ''');
478 });
479
480 group('Emphasis and strong', () {
481 validate('single asterisks', '''
482 before *em* after
483 ''', '''
484 <p>before <em>em</em> after</p>
485 ''');
486
487 validate('single underscores', '''
488 before _em_ after
489 ''', '''
490 <p>before <em>em</em> after</p>
491 ''');
492
493 validate('double asterisks', '''
494 before **strong** after
495 ''', '''
496 <p>before <strong>strong</strong> after</p>
497 ''');
498
499 validate('double underscores', '''
500 before __strong__ after
501 ''', '''
502 <p>before <strong>strong</strong> after</p>
503 ''');
504
505 validate('unmatched asterisk', '''
506 before *after
507 ''', '''
508 <p>before *after</p>
509 ''');
510
511 validate('unmatched underscore', '''
512 before _after
513 ''', '''
514 <p>before _after</p>
515 ''');
516
517 validate('multiple spans in one text', '''
518 a *one* b _two_ c
519 ''', '''
520 <p>a <em>one</em> b <em>two</em> c</p>
521 ''');
522
523 validate('multi-line', '''
524 before *first
525 second* after
526 ''', '''
527 <p>before <em>first
528 second</em> after</p>
529 ''');
530
531 validate('not processed when surrounded by spaces', '''
532 a * b * c _ d _ e
533 ''', '''
534 <p>a * b * c _ d _ e</p>
535 ''');
536
537 validate('strong then emphasis', '''
538 **strong***em*
539 ''', '''
540 <p><strong>strong</strong><em>em</em></p>
541 ''');
542
543 validate('emphasis then strong', '''
544 *em***strong**
545 ''', '''
546 <p><em>em</em><strong>strong</strong></p>
547 ''');
548
549 validate('emphasis inside strong', '''
550 **strong *em***
551 ''', '''
552 <p><strong>strong <em>em</em></strong></p>
553 ''');
554
555 validate('mismatched in nested', '''
556 *a _b* c_
557 ''', '''
558 <p><em>a _b</em> c_</p>
559 ''');
560
561 validate('cannot nest tags of same type', '''
562 *a _b *c* d_ e*
563 ''', '''
564 <p><em>a _b </em>c<em> d_ e</em></p>
565 ''');
566 });
567
568 group('Inline code', () {
569 validate('simple case', '''
570 before `source` after
571 ''', '''
572 <p>before <code>source</code> after</p>
573 ''');
574
575 validate('unmatched backtick', '''
576 before ` after
577 ''', '''
578 <p>before ` after</p>
579 ''');
580 validate('multiple spans in one text', '''
581 a `one` b `two` c
582 ''', '''
583 <p>a <code>one</code> b <code>two</code> c</p>
584 ''');
585
586 validate('multi-line', '''
587 before `first
588 second` after
589 ''', '''
590 <p>before <code>first
591 second</code> after</p>
592 ''');
593
594 validate('double backticks', '''
595 before ``can `contain` backticks`` after
596 ''', '''
597 <p>before <code>can `contain` backticks</code> after</p>
598 ''');
599
600 validate('double backticks with spaces', '''
601 before `` `tick` `` after
602 ''', '''
603 <p>before <code>`tick`</code> after</p>
604 ''');
605
606 validate('multiline double backticks with spaces', '''
607 before ``in `tick`
608 another`` after
609 ''', '''
610 <p>before <code>in `tick`
611 another</code> after</p>
612 ''');
613
614 validate('ignore markup inside code', '''
615 before `*b* _c_` after
616 ''', '''
617 <p>before <code>*b* _c_</code> after</p>
618 ''');
619
620 validate('escape HTML characters', '''
621 `<&>`
622 ''', '''
623 <p><code>&lt;&amp;&gt;</code></p>
624 ''');
625
626 validate('escape HTML tags', '''
627 '*' `<em>`
628 ''', '''
629 <p>'*' <code>&lt;em&gt;</code></p>
630 ''');
631 });
632
633 group('HTML encoding', () {
634 validate('less than and ampersand are escaped', '''
635 < &
636 ''', '''
637 <p>&lt; &amp;</p>
638 ''');
639 validate('greater than is not escaped', '''
640 not you >
641 ''', '''
642 <p>not you ></p>
643 ''');
644 validate('existing entities are untouched', '''
645 &amp;
646 ''', '''
647 <p>&amp;</p>
648 ''');
649 });
650
651 group('Autolinks', () {
652 validate('basic link', '''
653 before <http://foo.com/> after
654 ''', '''
655 <p>before <a href="http://foo.com/">http://foo.com/</a> after</p>
656 ''');
657 validate('handles ampersand in url', '''
658 <http://foo.com/?a=1&b=2>
659 ''', '''
660 <p><a href="http://foo.com/?a=1&b=2">http://foo.com/?a=1&amp;b=2</a></p>
661 ''');
662 });
663
664 group('Reference links', () {
665 validate('double quotes for title', '''
666 links [are] [a] awesome
667
668 [a]: http://foo.com "woo"
669 ''', '''
670 <p>links <a href="http://foo.com" title="woo">are</a> awesome</p>
671 ''');
672 validate('single quoted title', """
673 links [are] [a] awesome
674
675 [a]: http://foo.com 'woo'
676 """, '''
677 <p>links <a href="http://foo.com" title="woo">are</a> awesome</p>
678 ''');
679 validate('parentheses for title', '''
680 links [are] [a] awesome
681
682 [a]: http://foo.com (woo)
683 ''', '''
684 <p>links <a href="http://foo.com" title="woo">are</a> awesome</p>
685 ''');
686 validate('no title', '''
687 links [are] [a] awesome
688
689 [a]: http://foo.com
690 ''', '''
691 <p>links <a href="http://foo.com">are</a> awesome</p>
692 ''');
693 validate('unknown link becomes plaintext', '''
694 [not] [known]
695 ''', '''
696 <p>[not] [known]</p>
697 ''');
698 validate('can style link contents', '''
699 links [*are*] [a] awesome
700
701 [a]: http://foo.com
702 ''', '''
703 <p>links <a href="http://foo.com"><em>are</em></a> awesome</p>
704 ''');
705 validate('inline styles after a bad link are processed', '''
706 [bad] `code`
707 ''', '''
708 <p>[bad] <code>code</code></p>
709 ''');
710 });
711
712 group('Inline links', () {
713 validate('double quotes for title', '''
714 links [are](http://foo.com "woo") awesome
715 ''', '''
716 <p>links <a href="http://foo.com" title="woo">are</a> awesome</p>
717 ''');
718 validate('no title', '''
719 links [are] (http://foo.com) awesome
720 ''', '''
721 <p>links <a href="http://foo.com">are</a> awesome</p>
722 ''');
723 validate('can style link contents', '''
724 links [*are*](http://foo.com) awesome
725 ''', '''
726 <p>links <a href="http://foo.com"><em>are</em></a> awesome</p>
727 ''');
728 });
729 }
730
731 validate(String description, String markdown, String html) {
732 test(description, () {
733 markdown = cleanUpLiteral(markdown);
734 html = cleanUpLiteral(html);
735
736 var result = markdownToHtml(markdown);
737 var passed = compareOutput(html, result);
738
739 if (!passed) {
740 // Remove trailing newline.
741 html = html.substring(0, html.length - 1);
742
743 print('FAIL: $description');
744 print(' expect: ${html.replaceAll("\n", "\n ")}');
745 print(' actual: ${result.replaceAll("\n", "\n ")}');
746 print('');
747 }
748
749 expect(passed).isTrue();
750 });
751 }
752
753 /// The tests uses triple-quoted strings, which will include leading indentation
754 /// to make them look nice in code. But we don't want the markdown parser to
755 /// actually see that, so this cleans it all up.
756 ///
757 /// Note that this is very sensitive to how the literals are styled. They should
758 /// be:
759 /// '''
760 /// Text starts on own line. Lines up with subsequent lines.
761 /// Lines are indented exactly 8 characters from the left margin.
762 /// Close is on the same line.'''
763 ///
764 cleanUpLiteral(String text) {
765 var lines = text.split('\n');
766 for (var j = 0; j < lines.length; j++) {
767 if (lines[j].length > 8) {
768 lines[j] = lines[j].substring(8, lines[j].length);
769 } else {
770 lines[j] = '';
771 }
772 }
773
774 return Strings.join(lines, '\n');
775 }
776
777 /// Does a loose comparison of the two strings of HTML. Ignores differences in
778 /// newlines and indentation.
779 compareOutput(String a, String b) {
780 int i = 0;
781 int j = 0;
782
783 skipIgnored(String s, int i) {
784 // Ignore newlines.
785 while ((i < s.length) && (s[i] == '\n')) {
786 i++;
787 // Ignore indentation.
788 while ((i < s.length) && (s[i] == ' ')) i++;
789 }
790
791 return i;
792 }
793
794 while (true) {
795 i = skipIgnored(a, i);
796 j = skipIgnored(b, j);
797
798 // If one string runs out of non-ignored strings, the other must too.
799 if (i == a.length) return j == b.length;
800 if (j == b.length) return i == a.length;
801
802 if (a[i] != b[j]) return false;
803 i++;
804 j++;
805 }
806 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698