]> git.wincent.com - wikitext.git/blob - spec/regressions_spec.rb
Fix for lines beginning with slashes in PRE blocks
[wikitext.git] / spec / regressions_spec.rb
1 # encoding: utf-8
2 # Copyright 2008-2011 Wincent Colaiuta. All rights reserved.
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are met:
6 #
7 # 1. Redistributions of source code must retain the above copyright notice,
8 #    this list of conditions and the following disclaimer.
9 # 2. Redistributions in binary form must reproduce the above copyright notice,
10 #    this list of conditions and the following disclaimer in the documentation
11 #    and/or other materials provided with the distribution.
12
13 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
17 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
23 # POSSIBILITY OF SUCH DAMAGE.
24
25 require 'spec_helper'
26
27 # this is a general-purpose file in which I'll add specs for former bugs to make sure that they don't regress
28 describe Wikitext::Parser, 'regressions' do
29   before do
30     @parser = Wikitext::Parser.new
31   end
32
33   # turns out that this was never a bug in wikitext -- it was a bug in the host application -- but keeping the test does no harm
34   it 'should correctly transform example #1' do
35     input = dedent <<-END
36       = Leopard =
37       
38       * punto 1
39       * punto 2
40       
41       Y [[otro articulo]].
42     END
43     expected = dedent <<-END
44       <h1>Leopard</h1>
45       <ul>
46         <li>punto 1</li>
47         <li>punto 2</li>
48       </ul>
49       <p>Y <a href="/wiki/otro_articulo">otro articulo</a>.</p>
50     END
51     @parser.parse(input).should == expected
52   end
53
54   # discovered at: http://rails.wincent.com/wiki/nginx_log_rotation
55   # fixed by 0a328f1
56   it 'should allow empty lines in PRE blocks marked up with a leading space' do
57     input = dedent <<-END
58        # -d turns on debug mode: output is verbose, no actual changes are made to the log files
59        sudo logrotate -d /etc/logrotate.d/nginx
60        
61        # if the debug output looks good, proceed with a real rotation (-v turns on verbose output)
62        sudo logrotate -v /etc/logrotate.d/nginx
63     END
64     expected = dedent <<-END
65       <pre># -d turns on debug mode: output is verbose, no actual changes are made to the log files
66       sudo logrotate -d /etc/logrotate.d/nginx
67       
68       # if the debug output looks good, proceed with a real rotation (-v turns on verbose output)
69       sudo logrotate -v /etc/logrotate.d/nginx</pre>
70     END
71     @parser.parse(input).should == expected
72   end
73
74   # discovered at: http://rails.wincent.com/wiki/Installing_Ragel_5.2.0_on_Mac_OS_X_Tiger
75   # fixed by a616841
76   it 'should handle PRE_START blocks which follow unordered lists' do
77     input = dedent <<-END
78       * Get link to latest source code from: http://www.cs.queensu.ca/~thurston/ragel/
79       
80       <pre>wget http://www.cs.queensu.ca/~thurston/ragel/ragel-5.20.tar.gz
81       tar xzvf ragel-5.20.tar.gz
82       cd ragel-5.20</pre>
83     END
84     expected = dedent <<-END
85       <ul>
86         <li>Get link to latest source code from: <a href="http://www.cs.queensu.ca/~thurston/ragel/" class="external">http://www.cs.queensu.ca/~thurston/ragel/</a></li>
87       </ul>
88       <pre>wget <a href="http://www.cs.queensu.ca/~thurston/ragel/ragel-5.20.tar.gz" class="external">http://www.cs.queensu.ca/~thurston/ragel/ragel-5.20.tar.gz</a>
89       tar xzvf ragel-5.20.tar.gz
90       cd ragel-5.20</pre>
91     END
92     @parser.parse(input).should == expected
93   end
94
95   # discovered at: http://rails.wincent.com/wiki/Movable_Type_security_notes
96   # fixed by a616841
97   it 'should handle PRE_START blocks which follow ordered lists' do
98     input = dedent <<-END
99       # Turn off the [[Movable Type]] search function; use Google instead (it's better anyway) with a form something like this:
100       
101       <pre><form method="get"...></pre>
102     END
103     expected = dedent <<-END
104       <ol>
105         <li>Turn off the <a href="/wiki/Movable_Type">Movable Type</a> search function; use Google instead (it's better anyway) with a form something like this:</li>
106       </ol>
107       <pre>&lt;form method=&quot;get&quot;...&gt;</pre>
108     END
109     @parser.parse(input).should == expected
110   end
111
112   # discovered at: http://rails.wincent.com/wiki/Movable_Type_security_notes
113   # fixed by 191b75d
114   it 'should respect additional indentation found inside PRE blocks' do
115     # note the two extra spaces on each line
116     input = dedent <<-END
117          <input type="text" name="q" size="20" maxlength="255" value="" />
118          <input type="hidden" name="hl" value="en" />
119     END
120
121     # problem is the spaces were being emitted _before_ the CRLF
122     expected = dedent <<-END
123       <pre>  &lt;input type=&quot;text&quot; name=&quot;q&quot; size=&quot;20&quot; maxlength=&quot;255&quot; value=&quot;&quot; /&gt;
124         &lt;input type=&quot;hidden&quot; name=&quot;hl&quot; value=&quot;en&quot; /&gt;</pre>
125     END
126     @parser.parse(input).should == expected
127   end
128
129   # this is the general case of the bug covered in the previous spec
130   # any token that appears as the first token after a PRE token can manifest this bug
131   # PRINTABLE didn't only because it called wiki_start_para_if_necessary(), which handled the pending CRLF
132   it 'should emit pending newlines for all token types found inside PRE and PRE_START blocks' do
133     # PRE_START
134     input = dedent <<-END
135        foo
136        <pre>bar
137     END
138     expected = dedent <<-END
139       <pre>foo
140       &lt;pre&gt;bar</pre>
141     END
142     @parser.parse(input).should == expected
143
144     # PRE_END
145     input = dedent <<-END
146        foo
147        </pre>bar
148     END
149     expected = dedent <<-END
150       <pre>foo
151       &lt;/pre&gt;bar</pre>
152     END
153     @parser.parse(input).should == expected
154
155     # BLOCKQUOTE_START
156     input = dedent <<-END
157        foo
158        <blockquote>bar
159     END
160     expected = dedent <<-END
161       <pre>foo
162       &lt;blockquote&gt;bar</pre>
163     END
164     @parser.parse(input).should == expected
165
166     # BLOCKQUOTE_END
167     input = dedent <<-END
168        foo
169        </blockquote>bar
170     END
171     expected = dedent <<-END
172       <pre>foo
173       &lt;/blockquote&gt;bar</pre>
174     END
175     @parser.parse(input).should == expected
176
177     # NO_WIKI_START
178     input = dedent <<-END
179        foo
180        <nowiki>bar
181     END
182     expected = dedent <<-END
183       <pre>foo
184       &lt;nowiki&gt;bar</pre>
185     END
186     @parser.parse(input).should == expected
187
188     # STRONG_EM
189     input = dedent <<-END
190        foo
191        '''''bar
192     END
193     expected = dedent <<-END
194       <pre>foo
195       '''''bar</pre>
196     END
197     @parser.parse(input).should == expected
198
199     # STRONG
200     input = dedent <<-END
201        foo
202        '''bar
203     END
204     expected = dedent <<-END
205       <pre>foo
206       '''bar</pre>
207     END
208     @parser.parse(input).should == expected
209
210     # STRONG_START
211     input = dedent <<-END
212        foo
213        <strong>bar
214     END
215     expected = dedent <<-END
216       <pre>foo
217       &lt;strong&gt;bar</pre>
218     END
219     @parser.parse(input).should == expected
220
221     # STRONG_END
222     input = dedent <<-END
223        foo
224        </strong>bar
225     END
226     expected = dedent <<-END
227       <pre>foo
228       &lt;/strong&gt;bar</pre>
229     END
230     @parser.parse(input).should == expected
231
232     # EM
233     input = dedent <<-END
234        foo
235        ''bar
236     END
237     expected = dedent <<-END
238       <pre>foo
239       ''bar</pre>
240     END
241     @parser.parse(input).should == expected
242
243     # EM_START
244     input = dedent <<-END
245        foo
246        <em>bar
247     END
248     expected = dedent <<-END
249       <pre>foo
250       &lt;em&gt;bar</pre>
251     END
252     @parser.parse(input).should == expected
253
254     # EM_END
255     input = dedent <<-END
256        foo
257        </em>bar
258     END
259     expected = dedent <<-END
260       <pre>foo
261       &lt;/em&gt;bar</pre>
262     END
263     @parser.parse(input).should == expected
264
265     # TT
266     input = dedent <<-END
267        foo
268        `bar
269     END
270     expected = dedent <<-END
271       <pre>foo
272       `bar</pre>
273     END
274     @parser.parse(input).should == expected
275
276     # TT_START
277     input = dedent <<-END
278        foo
279        <tt>bar
280     END
281     expected = dedent <<-END
282       <pre>foo
283       &lt;tt&gt;bar</pre>
284     END
285     @parser.parse(input).should == expected
286
287     # TT_END
288     input = dedent <<-END
289        foo
290        </tt>bar
291     END
292     expected = dedent <<-END
293       <pre>foo
294       &lt;/tt&gt;bar</pre>
295     END
296     @parser.parse(input).should == expected
297
298     # H6_END
299     input = dedent <<-END
300        foo
301        ======
302        bar
303     END
304     expected = dedent <<-END
305       <pre>foo
306       ======
307       bar</pre>
308     END
309     @parser.parse(input).should == expected
310
311     # H5_END
312     input = dedent <<-END
313        foo
314        =====
315        bar
316     END
317     expected = dedent <<-END
318       <pre>foo
319       =====
320       bar</pre>
321     END
322     @parser.parse(input).should == expected
323
324     # H4_END
325     input = dedent <<-END
326        foo
327        ====
328        bar
329     END
330     expected = dedent <<-END
331       <pre>foo
332       ====
333       bar</pre>
334     END
335     @parser.parse(input).should == expected
336
337     # H3_END
338     input = dedent <<-END
339        foo
340        ===
341        bar
342     END
343     expected = dedent <<-END
344       <pre>foo
345       ===
346       bar</pre>
347     END
348     @parser.parse(input).should == expected
349
350     # H2_END
351     input = dedent <<-END
352        foo
353        ==
354        bar
355     END
356     expected = dedent <<-END
357       <pre>foo
358       ==
359       bar</pre>
360     END
361     @parser.parse(input).should == expected
362
363     # H1_END
364     input = dedent <<-END
365        foo
366        =
367        bar
368     END
369     expected = dedent <<-END
370       <pre>foo
371       =
372       bar</pre>
373     END
374     @parser.parse(input).should == expected
375
376     # MAIL
377     input = dedent <<-END
378        foo
379        bar@baz.com
380     END
381     expected = dedent <<-END
382       <pre>foo
383       bar@baz.com</pre>
384     END
385     @parser.parse(input).should == expected
386
387     # LINK_START
388     input = dedent <<-END
389        foo
390        [[bar
391     END
392     expected = dedent <<-END
393       <pre>foo
394       [[bar</pre>
395     END
396     @parser.parse(input).should == expected
397
398     # LINK_END
399     input = dedent <<-END
400        foo
401        ]]bar
402     END
403     expected = dedent <<-END
404       <pre>foo
405       ]]bar</pre>
406     END
407     @parser.parse(input).should == expected
408
409     # EXT_LINK_START
410     input = dedent <<-END
411        foo
412        [bar
413     END
414     expected = dedent <<-END
415       <pre>foo
416       [bar</pre>
417     END
418     @parser.parse(input).should == expected
419
420     # EXT_LINK_END
421     input = dedent <<-END
422        foo
423        ]bar
424     END
425     expected = dedent <<-END
426       <pre>foo
427       ]bar</pre>
428     END
429     @parser.parse(input).should == expected
430
431     # IMG_START
432     input = dedent <<-END
433        foo
434        {{bar
435     END
436     expected = dedent <<-END
437       <pre>foo
438       {{bar</pre>
439     END
440     @parser.parse(input).should == expected
441
442     # these tokens weren't affected by the bug, seeing as they either call wiki_start_para_if_necessary()
443     # or they can only appear in PRE_START (not PRE) thanks to the tokenizer
444     # but we add specs for them to make sure that the issue never crops up for them in the future
445
446     # PRE (in PRE_START)
447     input = dedent <<-END
448       <pre>foo
449        bar</pre>
450     END
451     expected = dedent <<-END
452       <pre>foo
453        bar</pre>
454     END
455     @parser.parse(input).should == expected
456
457     # BLOCKQUOTE (in PRE_START)
458     input = dedent <<-END
459       <pre>foo
460       > bar</pre>
461     END
462     expected = dedent <<-END
463       <pre>foo
464       &gt; bar</pre>
465     END
466     @parser.parse(input).should == expected
467
468     # OL (in PRE_START)
469     input = dedent <<-END
470       <pre># foo
471       # bar</pre>
472     END
473     expected = dedent <<-END
474       <pre># foo
475       # bar</pre>
476     END
477     @parser.parse(input).should == expected
478
479     # UL (in PRE_START)
480     input = dedent <<-END
481       <pre>* foo
482       * bar</pre>
483     END
484     expected = dedent <<-END
485       <pre>* foo
486       * bar</pre>
487     END
488     @parser.parse(input).should == expected
489
490     # H6_START (in PRE_START)
491     input = dedent <<-END
492       <pre>foo
493       ====== bar
494       baz</pre>
495     END
496     expected = dedent <<-END
497       <pre>foo
498       ====== bar
499       baz</pre>
500     END
501     @parser.parse(input).should == expected
502
503     # H5_START (in PRE_START)
504     input = dedent <<-END
505       <pre>foo
506       ===== bar
507       baz</pre>
508     END
509     expected = dedent <<-END
510       <pre>foo
511       ===== bar
512       baz</pre>
513     END
514     @parser.parse(input).should == expected
515
516     # H4_START (in PRE_START)
517     input = dedent <<-END
518       <pre>foo
519       ==== bar
520       baz</pre>
521     END
522     expected = dedent <<-END
523       <pre>foo
524       ==== bar
525       baz</pre>
526     END
527     @parser.parse(input).should == expected
528
529     # H3_START (in PRE_START)
530     input = dedent <<-END
531       <pre>foo
532       === bar
533       baz</pre>
534     END
535     expected = dedent <<-END
536       <pre>foo
537       === bar
538       baz</pre>
539     END
540     @parser.parse(input).should == expected
541
542     # H2_START (in PRE_START)
543     input = dedent <<-END
544       <pre>foo
545       == bar
546       baz</pre>
547     END
548     expected = dedent <<-END
549       <pre>foo
550       == bar
551       baz</pre>
552     END
553     @parser.parse(input).should == expected
554
555     # H1_START (in PRE_START)
556     input = dedent <<-END
557       <pre>foo
558       = bar
559       baz</pre>
560     END
561     expected = dedent <<-END
562       <pre>foo
563       = bar
564       baz</pre>
565     END
566     @parser.parse(input).should == expected
567
568     # NO_WIKI_END
569     input = dedent <<-END
570        foo
571        </nowiki>bar
572     END
573     expected = dedent <<-END
574       <pre>foo
575       &lt;/nowiki&gt;bar</pre>
576     END
577     @parser.parse(input).should == expected
578
579     # SEPARATOR
580     input = dedent <<-END
581        foo
582        |bar
583     END
584     expected = dedent <<-END
585       <pre>foo
586       |bar</pre>
587     END
588     @parser.parse(input).should == expected
589
590     # QUOT_ENTITY
591     input = dedent <<-END
592        foo
593        &quot;bar
594     END
595     expected = dedent <<-END
596       <pre>foo
597       &quot;bar</pre>
598     END
599     @parser.parse(input).should == expected
600
601     # AMP_ENTITY
602     input = dedent <<-END
603        foo
604        &amp;bar
605     END
606     expected = dedent <<-END
607       <pre>foo
608       &amp;bar</pre>
609     END
610     @parser.parse(input).should == expected
611
612     # NAMED_ENTITY
613     input = dedent <<-END
614        foo
615        &raquo;bar
616     END
617     expected = dedent <<-END
618       <pre>foo
619       &raquo;bar</pre>
620     END
621     @parser.parse(input).should == expected
622
623     # DECIMAL_ENTITY
624     input = dedent <<-END
625        foo
626        &#1234;bar
627     END
628     expected = dedent <<-END
629       <pre>foo
630       &#1234;bar</pre>
631     END
632     @parser.parse(input).should == expected
633
634     # HEX_ENTITY
635     input = dedent <<-END
636        foo
637        &#x2022;bar
638     END
639     expected = dedent <<-END
640       <pre>foo
641       &#x2022;bar</pre>
642     END
643     @parser.parse(input).should == expected
644
645     # QUOT
646     input = dedent <<-END
647        foo
648        "bar
649     END
650     expected = dedent <<-END
651       <pre>foo
652       &quot;bar</pre>
653     END
654     @parser.parse(input).should == expected
655
656     # AMP
657     input = dedent <<-END
658        foo
659        &bar
660     END
661     expected = dedent <<-END
662       <pre>foo
663       &amp;bar</pre>
664     END
665     @parser.parse(input).should == expected
666
667     # LESS
668     input = dedent <<-END
669        foo
670        <bar
671     END
672     expected = dedent <<-END
673       <pre>foo
674       &lt;bar</pre>
675     END
676     @parser.parse(input).should == expected
677
678     # GREATER
679     input = dedent <<-END
680        foo
681        >bar
682     END
683     expected = dedent <<-END
684       <pre>foo
685       &gt;bar</pre>
686     END
687     @parser.parse(input).should == expected
688
689     # URI
690     input = dedent <<-END
691        foo
692        http://example.com/
693     END
694     expected = dedent <<-END
695       <pre>foo
696       <a href="http://example.com/" class="external">http://example.com/</a></pre>
697     END
698     @parser.parse(input).should == expected
699
700     # PRINTABLE
701     input = dedent <<-END
702        foo
703        bar
704     END
705     expected = dedent <<-END
706       <pre>foo
707       bar</pre>
708     END
709     @parser.parse(input).should == expected
710
711     # IMG_END
712     input = dedent <<-END
713        foo
714        }}bar
715     END
716     expected = dedent <<-END
717       <pre>foo
718       }}bar</pre>
719     END
720     @parser.parse(input).should == expected
721
722     # LEFT_CURLY
723     input = dedent <<-END
724        foo
725        {bar
726     END
727     expected = dedent <<-END
728       <pre>foo
729       {bar</pre>
730     END
731     @parser.parse(input).should == expected
732
733     # RIGHT_CURLY
734     input = dedent <<-END
735        foo
736        }bar
737     END
738     expected = dedent <<-END
739       <pre>foo
740       }bar</pre>
741     END
742     @parser.parse(input).should == expected
743
744     # DEFAULT
745     input = dedent <<-END
746        foo
747        ÔéČbar
748     END
749     expected = dedent <<-END
750       <pre>foo
751       &#x20ac;bar</pre>
752     END
753     @parser.parse(input).should == expected
754   end
755
756   # discovered at: http://rails.wincent.com/wiki/Testing_cookies_in_Rails
757   it 'should handle BLOCKQUOTE_START blocks which follow lists' do
758     # example text taken from wiki article and edited for brevity
759     input = dedent <<-END
760       * This article
761       <blockquote>The cookies</blockquote>
762     END
763     expected = dedent <<-END
764       <ul>
765         <li>This article</li>
766       </ul>
767       <blockquote>
768         <p>The cookies</p>
769       </blockquote>
770     END
771     @parser.parse(input).should == expected
772   end
773
774   # https://wincent.com/issues/818
775   it 'should handle BLOCKQUOTE_START blocks which follow BLOCKQUOTE shorthand' do
776     input = dedent <<-END
777       > foo
778       <blockquote>bar</blockquote>
779     END
780     expected = dedent <<-END
781       <blockquote>
782         <p>foo</p>
783       </blockquote>
784       <blockquote>
785         <p>bar</p>
786       </blockquote>
787     END
788     @parser.parse(input).should == expected
789   end
790
791   # https://wincent.com/issues/818
792   it 'should handle PRE_START blocks which follow BLOCKQUOTE shorthand' do
793     input = dedent <<-END
794       > foo
795       <pre>bar</pre>
796     END
797     expected = dedent <<-END
798       <blockquote>
799         <p>foo</p>
800       </blockquote>
801       <pre>bar</pre>
802     END
803     @parser.parse(input).should == expected
804   end
805
806   # https://wincent.com/issues/818
807   it 'should handle BLOCKQUOTE_START blocks which follow nested BLOCKQUOTE shorthand' do
808     input = dedent <<-END
809       >>> foo
810       <blockquote>bar</blockquote>
811     END
812     expected = dedent <<-END
813       <blockquote>
814         <blockquote>
815           <blockquote>
816             <p>foo</p>
817           </blockquote>
818         </blockquote>
819       </blockquote>
820       <blockquote>
821         <p>bar</p>
822       </blockquote>
823     END
824     @parser.parse(input).should == expected
825   end
826
827   # https://wincent.com/issues/818
828   it 'should handle PRE_START blocks which follow nested BLOCKQUOTE shorthand' do
829     input = dedent <<-END
830       >>> foo
831       <pre>bar</pre>
832     END
833     expected = dedent <<-END
834       <blockquote>
835         <blockquote>
836           <blockquote>
837             <p>foo</p>
838           </blockquote>
839         </blockquote>
840       </blockquote>
841       <pre>bar</pre>
842     END
843     @parser.parse(input).should == expected
844   end
845
846   # https://wincent.com/issues/1289
847   it 'should handle empty (zero-width) link targets' do
848     # these were badly broken (caused exceptions to be raised)
849     @parser.parse('[[]]').should == "<p>[[]]</p>\n"
850     @parser.parse('[[|]]').should == "<p>[[|]]</p>\n"
851     @parser.parse('[[|foo]]').should == "<p>[[|foo]]</p>\n"
852
853     # was working, but check here anyway to guard against regressions
854     @parser.parse('[[foo|]]').should == %Q{<p><a href="/wiki/foo">foo</a></p>\n}
855   end
856
857   it 'should handle empty (whitespace only) link targets' do
858     # no exception raised, but clearly not desirable behaviour
859     # formerly these all returned: <p><a href="/wiki/"></a></p>\n
860     @parser.parse('[[ ]]').should == "<p>[[ ]]</p>\n"
861     @parser.parse('[[  ]]').should == "<p>[[  ]]</p>\n"
862     @parser.parse('[[  |]]').should == "<p>[[  |]]</p>\n"
863
864     # and this one returned: <p><a href="/wiki/">foo</a></p>\n
865     @parser.parse('[[  |foo]]').should == "<p>[[  |foo]]</p>\n"
866   end
867
868   # first manifested itself in this comment: https://wincent.com/comments/6427
869   it 'handles "`[/`"' do
870     # This is, of course, an invalid link, but it could be handled more
871     # gracefully (we were opening a <code> span and instead of just rolling
872     # back the failed link and then proceeding with the parse and closing
873     # the span, we skipped the second backtick, causing the remainder of
874     # the input to appear inside the <code> span).
875     #
876     # Although the bug manifested itself with backticks, it could also have
877     # happened with any non-space token appearing after a EXT_LINK_START +
878     # PATH sequence (any such token would just be dropped on the floor).
879     @parser.parse('with `[/` then').should == "<p>with <code>[/</code> then</p>\n"
880
881     # related example from the original ticket: https://wincent.com/issues/1726
882     @parser.parse('[/bar?baz=bat link]').should == "<p>[/bar?baz=bat link]</p>\n"
883   end
884
885   it 'handles "[http://foo.com]"' do
886     # Same bug as above, but with a EXT_LINK_START + URI rather than
887     # EXT_LINK_START + PATH; again we expect to see a SPACE, but when we
888     # see something else, we roll back and drop the unexpected token on
889     # the floor.
890     expected = %Q{<p>[<a href="http://foo.com" class="external">http://foo.com</a>]</p>\n}
891     @parser.parse('[http://foo.com]').should == expected
892   end
893
894   # https://wincent.com/issues/1891
895   it 'handles shorthand PRE blocks containing lines starting with slashes' do
896     expected = "<pre>/a\n/b\n/c</pre>\n"
897     @parser.parse(" /a\n /b\n /c").should == expected
898   end
899 end