]> git.wincent.com - wikitext.git/blob - spec/ul_spec.rb
b05fa291e828524b13baf35ec8ac1d5f9f6b7485
[wikitext.git] / spec / ul_spec.rb
1 #!/usr/bin/env ruby
2 # Copyright 2007-2009 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 File.join(File.dirname(__FILE__), 'spec_helper.rb')
26 require 'wikitext'
27
28 describe Wikitext::Parser, 'parsing unordered lists' do
29   before do
30     @parser = Wikitext::Parser.new
31   end
32
33   it 'should recognize a single item list' do
34     @parser.parse('*foo').should == "<ul>\n  <li>foo</li>\n</ul>\n"
35   end
36
37   it 'should allow and consume optional space after the last <ul> marker' do
38     @parser.parse('* foo').should == "<ul>\n  <li>foo</li>\n</ul>\n"    # exactly one space consumed
39     @parser.parse('*  foo').should == "<ul>\n  <li>foo</li>\n</ul>\n"   # multiple spaces consumed
40   end
41
42   it 'should consider a space after an <ul> marker to indicate that it will be the last marker' do
43     @parser.parse('* * foo').should == "<ul>\n  <li>* foo</li>\n</ul>\n"
44   end
45
46   it 'should only recognize <ul> markers if they or a direct ancestor start in the left column' do
47     @parser.parse(' * foo').should == "<pre>* foo</pre>\n"
48   end
49
50   it 'should recognize <ul> markers nested inside blockquote blocks' do
51     expected = dedent <<-END
52       <blockquote>
53         <ul>
54           <li>foo</li>
55         </ul>
56       </blockquote>
57     END
58     @parser.parse('> * foo').should == expected
59   end
60
61   it 'should display excess <ul> markers as literals' do
62     #┬áthis provides feedback to the user
63     @parser.parse('** foo').should == "<ul>\n  <li>* foo</li>\n</ul>\n"
64     @parser.parse('*** foo').should == "<ul>\n  <li>** foo</li>\n</ul>\n"
65   end
66
67   it 'should recognize a multi-item, single-level list' do
68     expected = dedent <<-END
69       <ul>
70         <li>foo</li>
71         <li>bar</li>
72       </ul>
73     END
74     @parser.parse("* foo\n* bar").should == expected
75   end
76
77   it 'should recognize a multi-item, nested list (two levels)' do
78     # indentation of nested lists is tricky
79     # the last </li> appears too far to the left
80     # the difficult is that sometimes li has to act like a block level element (like blockquote, does emit before dedent)
81     # and at other times it has to act like p (doesn't emit before dedent)
82     # so basically when nested we need to do an emitting dedent
83     # and when not we need to do a non-emitting one
84     expected = dedent <<-END
85       <ul>
86         <li>foo
87           <ul>
88             <li>bar</li>
89           </ul>
90         </li>
91       </ul>
92     END
93   @parser.parse("* foo\n** bar").should == expected
94   end
95
96   it 'should recognize a multi-item, nested list (three levels)' do
97     expected = dedent <<-END
98       <ul>
99         <li>foo
100           <ul>
101             <li>bar
102               <ul>
103                 <li>baz</li>
104               </ul>
105             </li>
106           </ul>
107         </li>
108       </ul>
109     END
110     @parser.parse("* foo\n** bar\n*** baz").should == expected
111   end
112
113   it 'should recognize lists in which nesting level increases and then is maintained' do
114     expected = dedent <<-END
115       <ul>
116         <li>foo
117           <ul>
118             <li>bar</li>
119             <li>baz</li>
120           </ul>
121         </li>
122       </ul>
123     END
124     @parser.parse("* foo\n** bar\n** baz").should == expected
125   end
126
127   it 'should recognize lists in which nesting level increases and then decreases' do
128     expected = dedent <<-END
129       <ul>
130         <li>foo
131           <ul>
132             <li>bar</li>
133           </ul>
134         </li>
135         <li>baz</li>
136       </ul>
137     END
138     @parser.parse("* foo\n** bar\n* baz").should == expected
139   end
140
141   it 'should be terminated by subsequent paragraph at the same level' do
142     expected = dedent <<-END
143       <ul>
144         <li>foo</li>
145       </ul>
146       <p>bar</p>
147     END
148     @parser.parse("* foo\nbar").should == expected
149   end
150
151   it 'should be terminated by subsequent blockquote at the same level' do
152     expected = dedent <<-END
153       <ul>
154         <li>foo</li>
155       </ul>
156       <blockquote>
157         <p>bar</p>
158       </blockquote>
159     END
160     @parser.parse("* foo\n> bar").should == expected
161   end
162
163   it 'should be terminated by subsequent heading at the same level' do
164     @parser.parse("* foo\n====== bar ======").should == "<ul>\n  <li>foo</li>\n</ul>\n<h6>bar</h6>\n"
165     @parser.parse("* foo\n===== bar =====").should == "<ul>\n  <li>foo</li>\n</ul>\n<h5>bar</h5>\n"
166     @parser.parse("* foo\n==== bar ====").should == "<ul>\n  <li>foo</li>\n</ul>\n<h4>bar</h4>\n"
167     @parser.parse("* foo\n=== bar ===").should == "<ul>\n  <li>foo</li>\n</ul>\n<h3>bar</h3>\n"
168     @parser.parse("* foo\n== bar ==").should == "<ul>\n  <li>foo</li>\n</ul>\n<h2>bar</h2>\n"
169     @parser.parse("* foo\n= bar =").should == "<ul>\n  <li>foo</li>\n</ul>\n<h1>bar</h1>\n"
170   end
171
172   it 'should be terminated by subsequent <pre> block at the same level' do
173     @parser.parse("* foo\n bar").should == "<ul>\n  <li>foo</li>\n</ul>\n<pre>bar</pre>\n"
174   end
175
176   it 'should be terminated by subsequent ordered list at the same level' do
177     expected = dedent 6,<<-END
178       <ul>
179         <li>foo</li>
180       </ul>
181       <ol>
182         <li>bar</li>
183       </ol>
184     END
185     @parser.parse("* foo\n# bar").should == expected
186   end
187
188   it 'should recognize lists which contain nested ordered lists' do
189     expected = dedent <<-END
190       <ul>
191         <li>foo
192           <ol>
193             <li>bar</li>
194           </ol>
195         </li>
196       </ul>
197     END
198     @parser.parse("* foo\n*# bar").should == expected
199
200     input = dedent <<-END
201       * foo
202       *# bar
203       *# baz
204     END
205     expected = dedent <<-END
206       <ul>
207         <li>foo
208           <ol>
209             <li>bar</li>
210             <li>baz</li>
211           </ol>
212         </li>
213       </ul>
214     END
215     @parser.parse(input).should == expected
216   end
217
218   it 'should automatically close open TT_START elements on reaching the end of the line' do
219     # this (and the same for all other span-level elements) was a bug
220     input = dedent <<-END
221       * <tt>hello
222       * world
223     END
224     expected = dedent <<-END
225       <ul>
226         <li><tt>hello</tt></li>
227         <li>world</li>
228       </ul>
229     END
230     @parser.parse(input).should == expected
231   end
232
233   it 'should automatically close open TT elements on reaching the end of the line' do
234     input = dedent <<-END
235       * `hello
236       * world
237     END
238     expected = dedent <<-END
239       <ul>
240         <li><tt>hello</tt></li>
241         <li>world</li>
242       </ul>
243     END
244     @parser.parse(input).should == expected
245   end
246
247   it 'should automatically close open EM_START elements on reaching the end of the line' do
248     input = dedent <<-END
249       * <em>hello
250       * world
251     END
252     expected = dedent <<-END
253       <ul>
254         <li><em>hello</em></li>
255         <li>world</li>
256       </ul>
257     END
258     @parser.parse(input).should == expected
259   end
260
261   it 'should automatically close open EM elements on reaching the end of the line' do
262     input = dedent <<-END
263       * ''hello
264       * world
265     END
266     expected = dedent <<-END
267       <ul>
268         <li><em>hello</em></li>
269         <li>world</li>
270       </ul>
271     END
272     @parser.parse(input).should == expected
273   end
274
275   it 'should automatically close open STRONG_START elements on reaching the end of the line' do
276     input = dedent <<-END
277       * <strong>hello
278       * world
279     END
280     expected = dedent <<-END
281       <ul>
282         <li><strong>hello</strong></li>
283         <li>world</li>
284       </ul>
285     END
286     @parser.parse(input).should == expected
287   end
288
289   it 'should automatically close open STRONG elements on reaching the end of the line' do
290     input = dedent <<-END
291       * '''hello
292       * world
293     END
294     expected = dedent <<-END
295       <ul>
296         <li><strong>hello</strong></li>
297         <li>world</li>
298       </ul>
299     END
300     @parser.parse(input).should == expected
301   end
302
303   it 'should automatically close open STRONG_EM elements on reaching the end of the line' do
304     input = dedent <<-END
305       * '''''hello
306       * world
307     END
308     expected = dedent <<-END
309       <ul>
310         <li><strong><em>hello</em></strong></li>
311         <li>world</li>
312       </ul>
313     END
314     @parser.parse(input).should == expected
315   end
316 end