wikitext 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,445 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright 2007-2008 Wincent Colaiuta
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require File.join(File.dirname(__FILE__), 'spec_helper.rb')
17
+ require 'wikitext'
18
+
19
+ describe Wikitext::Parser, 'internal links' do
20
+ before do
21
+ @parser = Wikitext::Parser.new
22
+ end
23
+
24
+ it 'should pass through unexpected link end tokens literally' do
25
+ @parser.parse('foo ]] bar').should == "<p>foo ]] bar</p>\n" # in plain scope
26
+ @parser.parse("foo '']]'' bar").should == "<p>foo <em>]]</em> bar</p>\n" # in EM scope
27
+ @parser.parse("foo ''']]''' bar").should == "<p>foo <strong>]]</strong> bar</p>\n" # in STRONG scope
28
+ @parser.parse("foo ''''']]''''' bar").should == "<p>foo <strong><em>]]</em></strong> bar</p>\n" # in STRONG_EM scope
29
+ @parser.parse('foo <tt>]]</tt> bar').should == "<p>foo <tt>]]</tt> bar</p>\n" # in TT scope
30
+ @parser.parse('= foo ]] bar =').should == "<h1>foo ]] bar</h1>\n" # in H1 scope
31
+ @parser.parse('== foo ]] bar ==').should == "<h2>foo ]] bar</h2>\n" # in H2 scope
32
+ @parser.parse('=== foo ]] bar ===').should == "<h3>foo ]] bar</h3>\n" # in H3 scope
33
+ @parser.parse('==== foo ]] bar ====').should == "<h4>foo ]] bar</h4>\n" # in H4 scope
34
+ @parser.parse('===== foo ]] bar =====').should == "<h5>foo ]] bar</h5>\n" # in H5 scope
35
+ @parser.parse('====== foo ]] bar ======').should == "<h6>foo ]] bar</h6>\n" # in H6 scope
36
+ @parser.parse('> ]]').should == "<blockquote>\n <p>]]</p>\n</blockquote>\n" # in BLOCKQUOTE scope
37
+ end
38
+
39
+ it 'should turn single words into links' do
40
+ @parser.parse('[[foo]]').should == %Q{<p><a href="/wiki/foo">foo</a></p>\n}
41
+ end
42
+
43
+ it 'should turn multiple words into links' do
44
+ @parser.parse('[[foo bar]]').should == %Q{<p><a href="/wiki/foo%20bar">foo bar</a></p>\n}
45
+ end
46
+
47
+ it 'should trim leading whitespace' do
48
+ @parser.parse('[[ foo]]').should == %Q{<p><a href="/wiki/foo">foo</a></p>\n}
49
+ @parser.parse('[[ foo]]').should == %Q{<p><a href="/wiki/foo">foo</a></p>\n}
50
+ @parser.parse('[[ foo]]').should == %Q{<p><a href="/wiki/foo">foo</a></p>\n}
51
+ @parser.parse('[[ foo]]').should == %Q{<p><a href="/wiki/foo">foo</a></p>\n}
52
+ end
53
+
54
+ it 'should trim trailing whitespace' do
55
+ @parser.parse('[[foo ]]').should == %Q{<p><a href="/wiki/foo">foo</a></p>\n}
56
+ @parser.parse('[[foo ]]').should == %Q{<p><a href="/wiki/foo">foo</a></p>\n}
57
+ @parser.parse('[[foo ]]').should == %Q{<p><a href="/wiki/foo">foo</a></p>\n}
58
+ @parser.parse('[[foo ]]').should == %Q{<p><a href="/wiki/foo">foo</a></p>\n} # was a bug (exception)
59
+ @parser.parse('[[foo ]]').should == %Q{<p><a href="/wiki/foo">foo</a></p>\n} # was a bug (crash)
60
+ end
61
+
62
+ it 'should trim leading and trailing whitespace (combined)' do
63
+ @parser.parse('[[ foo ]]').should == %Q{<p><a href="/wiki/foo">foo</a></p>\n}
64
+ @parser.parse('[[ foo ]]').should == %Q{<p><a href="/wiki/foo">foo</a></p>\n}
65
+ @parser.parse('[[ foo ]]').should == %Q{<p><a href="/wiki/foo">foo</a></p>\n}
66
+ @parser.parse('[[ foo ]]').should == %Q{<p><a href="/wiki/foo">foo</a></p>\n}
67
+ end
68
+
69
+ it 'should leave embedded whitespace intact' do
70
+ @parser.parse('[[ foo bar ]]').should == %Q{<p><a href="/wiki/foo%20bar">foo bar</a></p>\n}
71
+ @parser.parse('[[foo bar ]]').should == %Q{<p><a href="/wiki/foo%20bar">foo bar</a></p>\n}
72
+ @parser.parse('[[ foo bar ]]').should == %Q{<p><a href="/wiki/foo%20bar">foo bar</a></p>\n}
73
+ end
74
+
75
+ it 'should encode and sanitize quotes' do
76
+ # note how percent encoding is used in the href, and named entities in the link text
77
+ @parser.parse('[[hello "world"]]').should == %Q{<p><a href="/wiki/hello%20%22world%22">hello &quot;world&quot;</a></p>\n}
78
+ end
79
+
80
+ it 'should encode and sanitize ampersands' do
81
+ @parser.parse('[[a & b]]').should == %Q{<p><a href="/wiki/a%20%26%20b">a &amp; b</a></p>\n}
82
+ end
83
+
84
+ it 'should allow ampersand entities (special exception)' do
85
+ @parser.parse('[[a &amp; b]]').should == %Q{<p><a href="/wiki/a%20%26%20b">a &amp; b</a></p>\n}
86
+ end
87
+
88
+ it 'should allow quote entities (special exception)' do
89
+ @parser.parse('[[a &quot; b]]').should == %Q{<p><a href="/wiki/a%20%22%20b">a &quot; b</a></p>\n}
90
+ end
91
+
92
+ it 'should handle mixed scenarios (quotes, ampersands, non-ASCII characers)' do
93
+ expected = %Q{<p><a href="/wiki/foo%2c%20%22bar%22%20%26%20baz%20%e2%82%ac">foo, &quot;bar&quot; &amp; baz &#x20ac;</a></p>\n}
94
+ @parser.parse('[[foo, "bar" & baz €]]').should == expected
95
+ end
96
+
97
+ it 'should handle links in paragraph flows' do
98
+ expected = %Q{<p>foo <a href="/wiki/bar">bar</a> baz</p>\n}
99
+ @parser.parse('foo [[bar]] baz').should == expected # was a bug
100
+ end
101
+
102
+ describe 'custom link text' do
103
+ it 'should recognize link text placed after the separator' do
104
+ @parser.parse('[[foo|bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
105
+ end
106
+
107
+ it 'should trim whitespace to the left of the separator' do
108
+ @parser.parse('[[foo |bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
109
+ @parser.parse('[[foo |bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
110
+ @parser.parse('[[foo |bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
111
+ @parser.parse('[[foo |bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
112
+ @parser.parse('[[foo |bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
113
+ @parser.parse('[[foo |bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
114
+ end
115
+
116
+ it 'should trim whitespace to the right of the separator' do
117
+ @parser.parse('[[foo| bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
118
+ @parser.parse('[[foo| bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
119
+ @parser.parse('[[foo| bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
120
+ @parser.parse('[[foo| bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
121
+ @parser.parse('[[foo| bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
122
+ @parser.parse('[[foo| bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
123
+ end
124
+
125
+ it 'should trim whitespace on both sides of the separator (at the same time)' do
126
+ @parser.parse('[[foo | bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
127
+ @parser.parse('[[foo | bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
128
+ @parser.parse('[[foo | bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
129
+ @parser.parse('[[foo | bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
130
+ @parser.parse('[[foo | bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
131
+ @parser.parse('[[foo | bar]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
132
+ end
133
+
134
+ it 'should trim trailing whitespace from the link text' do
135
+ @parser.parse('[[foo|bar ]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
136
+ @parser.parse('[[foo|bar ]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
137
+ @parser.parse('[[foo|bar ]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
138
+ @parser.parse('[[foo|bar ]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
139
+ @parser.parse('[[foo|bar ]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
140
+ @parser.parse('[[foo|bar ]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
141
+ end
142
+
143
+ it 'should trim leading and trailing whitespace from the link text' do
144
+ @parser.parse('[[foo| bar ]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
145
+ @parser.parse('[[foo| bar ]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
146
+ @parser.parse('[[foo| bar ]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
147
+ @parser.parse('[[foo| bar ]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
148
+ @parser.parse('[[foo| bar ]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
149
+ @parser.parse('[[foo| bar ]]').should == %Q{<p><a href="/wiki/foo">bar</a></p>\n}
150
+ end
151
+
152
+ it 'should treat a separator inside the link text as part of the link text' do
153
+ @parser.parse('[[foo|bar|baz]]').should == %Q{<p><a href="/wiki/foo">bar|baz</a></p>\n}
154
+ end
155
+
156
+ it 'should treat separators outside of links as normal text' do
157
+ @parser.parse('foo|bar').should == %Q{<p>foo|bar</p>\n}
158
+ end
159
+
160
+ it 'should allow em markup in the custom link text' do
161
+ expected = %Q{<p><a href="/wiki/foo">bar <em>baz</em></a></p>\n}
162
+ @parser.parse("[[foo|bar ''baz'']]").should == expected
163
+ end
164
+
165
+ it 'should automatically close unclosed em markup in the custom link text' do
166
+ expected = %Q{<p><a href="/wiki/foo">bar <em>baz</em></a></p>\n}
167
+ @parser.parse("[[foo|bar ''baz]]").should == expected
168
+ end
169
+
170
+ it 'should allow strong markup in the custom link text' do
171
+ expected = %Q{<p><a href="/wiki/foo">bar <strong>baz</strong></a></p>\n}
172
+ @parser.parse("[[foo|bar '''baz''']]").should == expected
173
+ end
174
+
175
+ it 'should automatically close unclosed strong markup in the custom link text' do
176
+ expected = %Q{<p><a href="/wiki/foo">bar <strong>baz</strong></a></p>\n}
177
+ @parser.parse("[[foo|bar '''baz]]").should == expected
178
+ end
179
+
180
+ it 'should allow strong/em markup in the custom link text' do
181
+ expected = %Q{<p><a href="/wiki/foo">bar <strong><em>baz</em></strong></a></p>\n}
182
+ @parser.parse("[[foo|bar '''''baz''''']]").should == expected
183
+ end
184
+
185
+ it 'should automatically close unclosed strong/em markup in the custom link text' do
186
+ expected = %Q{<p><a href="/wiki/foo">bar <strong><em>baz</em></strong></a></p>\n}
187
+ @parser.parse("[[foo|bar '''''baz]]").should == expected
188
+ end
189
+
190
+ it 'should allow tt markup in the custom link text' do
191
+ expected = %Q{<p><a href="/wiki/foo">bar <tt>baz</tt></a></p>\n}
192
+ @parser.parse('[[foo|bar <tt>baz</tt>]]').should == expected
193
+ end
194
+
195
+ it 'should automatically close unclosed tt markup in the custom link text' do
196
+ expected = %Q{<p><a href="/wiki/foo">bar <tt>baz</tt></a></p>\n}
197
+ @parser.parse('[[foo|bar <tt>baz]]').should == expected
198
+ end
199
+
200
+ it 'should allow named entities in the custom link text' do
201
+ expected = %Q{<p><a href="/wiki/foo">bar &copy;</a></p>\n}
202
+ @parser.parse('[[foo|bar &copy;]]').should == expected
203
+
204
+ # explicitly test &quot; because it is tokenized separately from the other named entities
205
+ expected = %Q{<p><a href="/wiki/foo">bar &quot;</a></p>\n}
206
+ @parser.parse('[[foo|bar &quot;]]').should == expected
207
+
208
+ # explicitly test &amp; because it is tokenized separately from the other named entities
209
+ expected = %Q{<p><a href="/wiki/foo">bar &amp;</a></p>\n}
210
+ @parser.parse('[[foo|bar &amp;]]').should == expected
211
+ end
212
+
213
+ it 'should allow decimal entities in the custom link text' do
214
+ expected = %Q{<p><a href="/wiki/foo">bar &#8364;</a></p>\n}
215
+ @parser.parse('[[foo|bar &#8364;]]').should == expected
216
+ end
217
+
218
+ it 'should allow hexadecimal entities in the custom link text' do
219
+ expected = %Q{<p><a href="/wiki/foo">bar &#x20ac;</a></p>\n}
220
+ @parser.parse('[[foo|bar &#x20ac;]]').should == expected
221
+ end
222
+
223
+ it 'should sanitize non-ASCII characters in the custom link text' do
224
+ expected = %Q{<p><a href="/wiki/foo">bar &#x20ac;</a></p>\n}
225
+ @parser.parse('[[foo|bar €]]').should == expected
226
+ end
227
+
228
+ it 'should sanitize characters that have special meaning in HTML in the custom link text' do
229
+ expected = %Q{<p><a href="/wiki/foo">bar &lt;</a></p>\n}
230
+ @parser.parse('[[foo|bar <]]').should == expected
231
+
232
+ expected = %Q{<p><a href="/wiki/foo">bar &gt;</a></p>\n}
233
+ @parser.parse('[[foo|bar >]]').should == expected
234
+
235
+ expected = %Q{<p><a href="/wiki/foo">bar &amp;</a></p>\n}
236
+ @parser.parse('[[foo|bar &]]').should == expected
237
+
238
+ expected = %Q{<p><a href="/wiki/foo">bar &quot;baz&quot;</a></p>\n}
239
+ @parser.parse('[[foo|bar "baz"]]').should == expected
240
+ end
241
+
242
+ it 'should allow nowiki markup in the custom link text' do
243
+ expected = %Q{<p><a href="/wiki/foo">bar [[</a></p>\n}
244
+ @parser.parse("[[foo|bar <nowiki>[[</nowiki>]]").should == expected
245
+
246
+ expected = %Q{<p><a href="/wiki/foo">bar [</a></p>\n}
247
+ @parser.parse("[[foo|bar <nowiki>[</nowiki>]]").should == expected
248
+
249
+ expected = %Q{<p><a href="/wiki/foo">bar ]]</a></p>\n}
250
+ @parser.parse("[[foo|bar <nowiki>]]</nowiki>]]").should == expected
251
+
252
+ expected = %Q{<p><a href="/wiki/foo">bar ]</a></p>\n}
253
+ @parser.parse("[[foo|bar <nowiki>]</nowiki>]]").should == expected
254
+ end
255
+ end
256
+
257
+ describe 'overriding the link prefix' do
258
+ it 'should be able to override the link prefix' do
259
+ @parser.internal_link_prefix = '/custom/'
260
+ @parser.parse('[[foo]]').should == %Q{<p><a href="/custom/foo">foo</a></p>\n}
261
+ end
262
+
263
+ it 'should interpet a nil link prefix as meaning no prefix' do
264
+ @parser.internal_link_prefix = nil
265
+ @parser.parse('[[foo]]').should == %Q{<p><a href="foo">foo</a></p>\n}
266
+ end
267
+ end
268
+
269
+ describe 'special links' do
270
+ it 'should recognize links of the form "bug/10" as special links' do
271
+ @parser.parse('[[bug/10]]').should == %Q{<p><a href="/bug/10">bug/10</a></p>\n}
272
+ @parser.parse('[[issue/25]]').should == %Q{<p><a href="/issue/25">issue/25</a></p>\n}
273
+ @parser.parse('[[post/7]]').should == %Q{<p><a href="/post/7">post/7</a></p>\n}
274
+ end
275
+
276
+ it 'should not recognize special links when "treat_slash_as_special" is set to false' do
277
+ @parser.treat_slash_as_special = false
278
+ @parser.parse('[[bug/10]]').should == %Q{<p><a href="/wiki/bug%2f10">bug/10</a></p>\n}
279
+ @parser.parse('[[issue/25]]').should == %Q{<p><a href="/wiki/issue%2f25">issue/25</a></p>\n}
280
+ @parser.parse('[[post/7]]').should == %Q{<p><a href="/wiki/post%2f7">post/7</a></p>\n}
281
+ end
282
+
283
+ it 'should accept custom link text in conjunction with special links' do
284
+ @parser.parse('[[bug/10|bug #10]]').should == %Q{<p><a href="/bug/10">bug #10</a></p>\n}
285
+ end
286
+
287
+ it 'should ignore link prefix overrides when emitting special links' do
288
+ @parser.internal_link_prefix = '/custom/'
289
+ @parser.parse('[[bug/10]]').should == %Q{<p><a href="/bug/10">bug/10</a></p>\n}
290
+ end
291
+
292
+ it 'should not classify links as special merely because of the presence of a slash' do
293
+ # we want the syntax to be tight to minimize false positives
294
+ @parser.parse('[[foo/bar]]').should == %Q{<p><a href="/wiki/foo%2fbar">foo/bar</a></p>\n}
295
+ end
296
+
297
+ it 'should not accept special links which have a leading forward slash' do
298
+ # this is a syntax error
299
+ @parser.parse('[[/bug/10]]').should == %Q{<p><a href="/wiki/%2fbug%2f10">/bug/10</a></p>\n}
300
+ end
301
+ end
302
+
303
+ describe 'invalid links' do
304
+ it 'should not allow entities in the link text' do
305
+ @parser.parse('[[a &euro; b]]').should == "<p>[[a &euro; b]]</p>\n"
306
+ end
307
+
308
+ it 'should not allow URIs in the link text' do
309
+ expected = %Q{<p>[[hello <a href="http://example.com/" class="external">http://example.com/</a> world]]</p>\n}
310
+ @parser.parse('[[hello http://example.com/ world]]').should == expected
311
+ end
312
+
313
+ it 'should handle embedded [[ inside links' do
314
+ # note how first part "[[foo " in itself is invalid and so gets rejected and echoed literally
315
+ expected = %Q{<p>[[foo <a href="/wiki/bar">bar</a></p>\n}
316
+ @parser.parse('[[foo [[bar]]').should == expected
317
+ end
318
+
319
+ it 'should handled embedded ]] inside links' do
320
+ # note how the link gets terminated early and the trailing part is rejected and echoed literally
321
+ expected = %Q{<p><a href="/wiki/foo">foo</a>bar]]</p>\n}
322
+ @parser.parse('[[foo ]]bar]]').should == expected
323
+ end
324
+
325
+ it 'should handle embedded [ inside links' do
326
+ # [ is not allowed at all so the entire link is rendered invalid
327
+ expected = "<p>[[foo [bar]]</p>\n"
328
+ @parser.parse('[[foo [bar]]').should == expected
329
+ end
330
+
331
+ it 'should handle embedded ] inside links' do
332
+ # [ is not allowed at all so the entire link is rendered invalid
333
+ expected = "<p>[[foo ]bar]]</p>\n"
334
+ @parser.parse('[[foo ]bar]]').should == expected
335
+ end
336
+
337
+ describe 'unterminated link targets (end-of-file)' do
338
+ it 'should rollback and show the unterminated link' do
339
+ @parser.parse('[[foo').should == %Q{<p>[[foo</p>\n}
340
+ end
341
+
342
+ it 'should not trim leading whitespace when rolling back' do
343
+ @parser.parse('[[ foo').should == %Q{<p>[[ foo</p>\n}
344
+ @parser.parse('[[ foo').should == %Q{<p>[[ foo</p>\n}
345
+ @parser.parse('[[ foo').should == %Q{<p>[[ foo</p>\n}
346
+ @parser.parse('[[ foo').should == %Q{<p>[[ foo</p>\n}
347
+ end
348
+
349
+ it 'should not trim trailing whitespace when rolling back' do
350
+ @parser.parse('[[foo ').should == %Q{<p>[[foo </p>\n}
351
+ @parser.parse('[[foo ').should == %Q{<p>[[foo </p>\n}
352
+ @parser.parse('[[foo ').should == %Q{<p>[[foo </p>\n}
353
+ @parser.parse('[[foo ').should == %Q{<p>[[foo </p>\n}
354
+ end
355
+
356
+ it 'should not trim leadig and trailing whitespace (combined) when rolling back' do
357
+ @parser.parse('[[ foo ').should == %Q{<p>[[ foo </p>\n}
358
+ @parser.parse('[[ foo ').should == %Q{<p>[[ foo </p>\n}
359
+ @parser.parse('[[ foo ').should == %Q{<p>[[ foo </p>\n}
360
+ @parser.parse('[[ foo ').should == %Q{<p>[[ foo </p>\n}
361
+ end
362
+ end
363
+
364
+ describe 'unterminated link targets (end-of-line)' do
365
+ it 'should rollback and show the unterminated link' do
366
+ @parser.parse("[[foo\n").should == %Q{<p>[[foo</p>\n}
367
+ end
368
+
369
+ it 'should not trim leading whitespace when rolling back' do
370
+ @parser.parse("[[ foo\n").should == %Q{<p>[[ foo</p>\n}
371
+ @parser.parse("[[ foo\n").should == %Q{<p>[[ foo</p>\n}
372
+ @parser.parse("[[ foo\n").should == %Q{<p>[[ foo</p>\n}
373
+ @parser.parse("[[ foo\n").should == %Q{<p>[[ foo</p>\n}
374
+ end
375
+
376
+ it 'should not trim trailing whitespace when rolling back' do
377
+ @parser.parse("[[foo \n").should == %Q{<p>[[foo </p>\n}
378
+ @parser.parse("[[foo \n").should == %Q{<p>[[foo </p>\n}
379
+ @parser.parse("[[foo \n").should == %Q{<p>[[foo </p>\n}
380
+ @parser.parse("[[foo \n").should == %Q{<p>[[foo </p>\n}
381
+ end
382
+
383
+ it 'should not trim leading and trailing whitespace (combined) when rolling back' do
384
+ @parser.parse("[[ foo \n").should == %Q{<p>[[ foo </p>\n}
385
+ @parser.parse("[[ foo \n").should == %Q{<p>[[ foo </p>\n}
386
+ @parser.parse("[[ foo \n").should == %Q{<p>[[ foo </p>\n}
387
+ @parser.parse("[[ foo \n").should == %Q{<p>[[ foo </p>\n}
388
+ end
389
+ end
390
+
391
+ describe 'missing link text' do
392
+ it 'should use link target' do
393
+ @parser.parse('[[foo|]]').should == %Q{<p><a href="/wiki/foo">foo</a></p>\n}
394
+ end
395
+ end
396
+
397
+ describe 'link cut off at separator (end-of-file)' do
398
+ it 'should rollback and show the unterminated link' do
399
+ @parser.parse('[[foo|').should == %Q{<p>[[foo|</p>\n}
400
+ @parser.parse('[[foo| ').should == %Q{<p>[[foo| </p>\n}
401
+ @parser.parse('[[foo| ').should == %Q{<p>[[foo| </p>\n}
402
+ @parser.parse('[[foo| ').should == %Q{<p>[[foo| </p>\n}
403
+ @parser.parse('[[foo| ').should == %Q{<p>[[foo| </p>\n}
404
+ @parser.parse('[[foo| ').should == %Q{<p>[[foo| </p>\n}
405
+ @parser.parse('[[foo| ').should == %Q{<p>[[foo| </p>\n}
406
+ end
407
+ end
408
+
409
+ describe 'link cut off at separator (end-of-line)' do
410
+ it 'should rollback and show the unterminated link' do
411
+ @parser.parse("[[foo|\n").should == %Q{<p>[[foo|</p>\n}
412
+ @parser.parse("[[foo| \n").should == %Q{<p>[[foo| </p>\n}
413
+ @parser.parse("[[foo| \n").should == %Q{<p>[[foo| </p>\n}
414
+ @parser.parse("[[foo| \n").should == %Q{<p>[[foo| </p>\n}
415
+ @parser.parse("[[foo| \n").should == %Q{<p>[[foo| </p>\n}
416
+ @parser.parse("[[foo| \n").should == %Q{<p>[[foo| </p>\n}
417
+ @parser.parse("[[foo| \n").should == %Q{<p>[[foo| </p>\n}
418
+ end
419
+ end
420
+
421
+ describe 'unterminated link text (end-of-file)' do
422
+ it 'should rollback and show the unterminated link' do
423
+ @parser.parse('[[foo|hello').should == %Q{<p>[[foo|hello</p>\n}
424
+ @parser.parse('[[foo|hello ').should == %Q{<p>[[foo|hello </p>\n}
425
+ @parser.parse('[[foo|hello ').should == %Q{<p>[[foo|hello </p>\n}
426
+ @parser.parse('[[foo|hello ').should == %Q{<p>[[foo|hello </p>\n}
427
+ @parser.parse('[[foo|hello ').should == %Q{<p>[[foo|hello </p>\n}
428
+ @parser.parse('[[foo|hello ').should == %Q{<p>[[foo|hello </p>\n}
429
+ @parser.parse('[[foo|hello ').should == %Q{<p>[[foo|hello </p>\n}
430
+ end
431
+ end
432
+
433
+ describe 'unterminated link text (end-of-line)' do
434
+ it 'should rollback and show the unterminated link' do
435
+ @parser.parse("[[foo|hello\n").should == %Q{<p>[[foo|hello</p>\n}
436
+ @parser.parse("[[foo|hello \n").should == %Q{<p>[[foo|hello </p>\n}
437
+ @parser.parse("[[foo|hello \n").should == %Q{<p>[[foo|hello </p>\n}
438
+ @parser.parse("[[foo|hello \n").should == %Q{<p>[[foo|hello </p>\n}
439
+ @parser.parse("[[foo|hello \n").should == %Q{<p>[[foo|hello </p>\n}
440
+ @parser.parse("[[foo|hello \n").should == %Q{<p>[[foo|hello </p>\n}
441
+ @parser.parse("[[foo|hello \n").should == %Q{<p>[[foo|hello </p>\n}
442
+ end
443
+ end
444
+ end
445
+ end
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright 2007-2008 Wincent Colaiuta
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require File.join(File.dirname(__FILE__), 'spec_helper.rb')
17
+ require 'wikitext'
18
+
19
+ describe Wikitext::Parser do
20
+ before do
21
+ @parser = Wikitext::Parser.new
22
+ end
23
+
24
+ it 'should default to UNIX line endings' do
25
+ @parser.line_ending.should == "\n"
26
+ end
27
+
28
+ it 'should greedily match Mac line endings in input if possible' do
29
+ # note how the embedded "\r\n" is interpreted as a single token (and converted to exactly one space)
30
+ # it is not treated as two separate tokens
31
+ @parser.parse("foo\r\nbar").should == "<p>foo bar</p>\n"
32
+ end
33
+ end
34
+
35
+ describe Wikitext::Parser, 'with UNIX line endings' do
36
+ before do
37
+ @parser = Wikitext::Parser.new
38
+ @parser.line_ending = "\n"
39
+ end
40
+
41
+ it 'should convert line endings within spans to a single space' do
42
+ @parser.parse("foo\nbar").should == "<p>foo bar</p>\n"
43
+ end
44
+
45
+ it 'should normalize non-UNIX line endings' do
46
+ @parser.parse("foo\rbar").should == "<p>foo bar</p>\n"
47
+ @parser.parse("foo\r\nbar").should == "<p>foo bar</p>\n"
48
+ end
49
+ end
50
+
51
+ describe Wikitext::Parser, 'with Windows line endings' do
52
+ before do
53
+ @parser = Wikitext::Parser.new
54
+ @parser.line_ending = "\r"
55
+ end
56
+
57
+ it 'should convert line endings within spans to a single space' do
58
+ @parser.parse("foo\rbar").should == "<p>foo bar</p>\r"
59
+ end
60
+
61
+ it 'should normalize non-Windows line endings' do
62
+ @parser.parse("foo\nbar").should == "<p>foo bar</p>\r"
63
+ @parser.parse("foo\r\nbar").should == "<p>foo bar</p>\r"
64
+ end
65
+ end
66
+
67
+ describe Wikitext::Parser, 'with Mac line endings' do
68
+ before do
69
+ @parser = Wikitext::Parser.new
70
+ @parser.line_ending = "\r\n"
71
+ end
72
+
73
+ it 'should convert line endings within spans to a single space' do
74
+ @parser.parse("foo\r\nbar").should == "<p>foo bar</p>\r\n"
75
+ end
76
+
77
+ it 'should normalize non-Mac line endings' do
78
+ @parser.parse("foo\nbar").should == "<p>foo bar</p>\r\n"
79
+ @parser.parse("foo\rbar").should == "<p>foo bar</p>\r\n"
80
+ end
81
+ end