wikitext 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ext/ary.h +99 -0
- data/ext/depend +22 -0
- data/ext/extconf.rb +23 -0
- data/ext/parser.c +2174 -0
- data/ext/parser.h +31 -0
- data/ext/str.h +135 -0
- data/ext/token.c +109 -0
- data/ext/token.h +95 -0
- data/ext/wikitext.c +60 -0
- data/ext/wikitext.h +30 -0
- data/ext/wikitext_ragel.c +3354 -0
- data/ext/wikitext_ragel.h +17 -0
- data/spec/autolinking_spec.rb +122 -0
- data/spec/blockquote_spec.rb +570 -0
- data/spec/em_spec.rb +97 -0
- data/spec/encoding_spec.rb +124 -0
- data/spec/entity_spec.rb +40 -0
- data/spec/external_link_spec.rb +289 -0
- data/spec/h1_spec.rb +59 -0
- data/spec/h2_spec.rb +59 -0
- data/spec/h3_spec.rb +59 -0
- data/spec/h4_spec.rb +59 -0
- data/spec/h5_spec.rb +59 -0
- data/spec/h6_spec.rb +59 -0
- data/spec/indentation_spec.rb +70 -0
- data/spec/integration_spec.rb +265 -0
- data/spec/internal_link_spec.rb +445 -0
- data/spec/line_endings_spec.rb +81 -0
- data/spec/link_encoding_spec.rb +132 -0
- data/spec/link_sanitizing_spec.rb +228 -0
- data/spec/nowiki_spec.rb +155 -0
- data/spec/p_spec.rb +44 -0
- data/spec/pre_spec.rb +411 -0
- data/spec/regressions_spec.rb +45 -0
- data/spec/spec_helper.rb +77 -0
- data/spec/strong_em_spec.rb +89 -0
- data/spec/strong_spec.rb +99 -0
- data/spec/tokenizing_spec.rb +190 -0
- data/spec/tt_spec.rb +100 -0
- data/spec/ul_spec.rb +307 -0
- data/spec/wikitext_spec.rb +50 -0
- metadata +93 -0
@@ -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 "world"</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 & b</a></p>\n}
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should allow ampersand entities (special exception)' do
|
85
|
+
@parser.parse('[[a & b]]').should == %Q{<p><a href="/wiki/a%20%26%20b">a & b</a></p>\n}
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should allow quote entities (special exception)' do
|
89
|
+
@parser.parse('[[a " b]]').should == %Q{<p><a href="/wiki/a%20%22%20b">a " 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, "bar" & baz €</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 ©</a></p>\n}
|
202
|
+
@parser.parse('[[foo|bar ©]]').should == expected
|
203
|
+
|
204
|
+
# explicitly test " because it is tokenized separately from the other named entities
|
205
|
+
expected = %Q{<p><a href="/wiki/foo">bar "</a></p>\n}
|
206
|
+
@parser.parse('[[foo|bar "]]').should == expected
|
207
|
+
|
208
|
+
# explicitly test & because it is tokenized separately from the other named entities
|
209
|
+
expected = %Q{<p><a href="/wiki/foo">bar &</a></p>\n}
|
210
|
+
@parser.parse('[[foo|bar &]]').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 €</a></p>\n}
|
215
|
+
@parser.parse('[[foo|bar €]]').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 €</a></p>\n}
|
220
|
+
@parser.parse('[[foo|bar €]]').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 €</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 <</a></p>\n}
|
230
|
+
@parser.parse('[[foo|bar <]]').should == expected
|
231
|
+
|
232
|
+
expected = %Q{<p><a href="/wiki/foo">bar ></a></p>\n}
|
233
|
+
@parser.parse('[[foo|bar >]]').should == expected
|
234
|
+
|
235
|
+
expected = %Q{<p><a href="/wiki/foo">bar &</a></p>\n}
|
236
|
+
@parser.parse('[[foo|bar &]]').should == expected
|
237
|
+
|
238
|
+
expected = %Q{<p><a href="/wiki/foo">bar "baz"</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 € b]]').should == "<p>[[a € 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
|