1 |
wakaba |
1.1 |
#!/usr/bin/perl |
2 |
|
|
use strict; |
3 |
|
|
|
4 |
|
|
use lib qw[/home/wakaba/work/manakai/lib]; |
5 |
|
|
## ISSUE: Message::URI::URIReference module. |
6 |
|
|
|
7 |
|
|
use Test; |
8 |
wakaba |
1.2 |
BEGIN { plan tests => 81 } |
9 |
wakaba |
1.1 |
|
10 |
|
|
my $Cases = [ |
11 |
|
|
{ |
12 |
|
|
data => q<http://localhost/%40/>, |
13 |
|
|
errors => [], |
14 |
|
|
}, |
15 |
|
|
{ |
16 |
|
|
data => q<>, |
17 |
|
|
errors => [], |
18 |
|
|
}, |
19 |
|
|
{ |
20 |
|
|
data => q<abcdef>, |
21 |
|
|
errors => [], |
22 |
|
|
}, |
23 |
|
|
{ |
24 |
|
|
data => q<%7Fabc:efg>, |
25 |
wakaba |
1.4 |
errors => ['m::syntax error:iriref3987'], |
26 |
wakaba |
1.1 |
}, |
27 |
|
|
{ |
28 |
|
|
data => q<http://test/[53::0]>, |
29 |
wakaba |
1.4 |
errors => ['m::syntax error:iriref3987'], |
30 |
wakaba |
1.1 |
}, |
31 |
|
|
{ |
32 |
|
|
data => q<100%!>, |
33 |
wakaba |
1.4 |
errors => ['m::syntax error:iriref3987'], |
34 |
wakaba |
1.1 |
}, |
35 |
|
|
{ |
36 |
|
|
data => q<%a2>, |
37 |
wakaba |
1.5 |
errors => ['w:0.2:URL:lowercase hexadecimal digit'], |
38 |
wakaba |
1.1 |
}, |
39 |
|
|
{ |
40 |
|
|
data => q<%a2?>, |
41 |
wakaba |
1.5 |
errors => ['w:0.2:URL:lowercase hexadecimal digit'], |
42 |
wakaba |
1.1 |
}, |
43 |
|
|
{ |
44 |
|
|
data => q<?%a2>, |
45 |
wakaba |
1.5 |
errors => ['w:1.3:URL:lowercase hexadecimal digit'], |
46 |
wakaba |
1.1 |
}, |
47 |
|
|
{ |
48 |
|
|
data => q<%a2%1b>, |
49 |
wakaba |
1.5 |
errors => ['w:0.2:URL:lowercase hexadecimal digit', |
50 |
|
|
'w:3.5:URL:lowercase hexadecimal digit'], |
51 |
wakaba |
1.1 |
}, |
52 |
|
|
{ |
53 |
|
|
data => q<http://%5b/>, |
54 |
wakaba |
1.5 |
errors => ['w:7.9:URL:lowercase hexadecimal digit', |
55 |
wakaba |
1.4 |
'w::URL:non-DNS host'], |
56 |
wakaba |
1.1 |
}, |
57 |
|
|
{ |
58 |
|
|
data => q<http://%5b/%25a/bv/%cc>, |
59 |
wakaba |
1.5 |
errors => ['w:7.9:URL:lowercase hexadecimal digit', |
60 |
|
|
'w:19.21:URL:lowercase hexadecimal digit', |
61 |
wakaba |
1.4 |
'w::URL:non-DNS host'], |
62 |
wakaba |
1.1 |
}, |
63 |
|
|
{ |
64 |
|
|
data => q<%41>, |
65 |
wakaba |
1.5 |
errors => ['w:0.2:URL:percent-encoded unreserved'], |
66 |
wakaba |
1.1 |
}, |
67 |
|
|
{ |
68 |
|
|
data => q<%41%7E>, |
69 |
wakaba |
1.5 |
errors => ['w:0.2:URL:percent-encoded unreserved', |
70 |
|
|
'w:3.5:URL:percent-encoded unreserved'], |
71 |
wakaba |
1.1 |
}, |
72 |
|
|
{ |
73 |
|
|
data => q</%41>, |
74 |
wakaba |
1.5 |
errors => ['w:1.3:URL:percent-encoded unreserved'], |
75 |
wakaba |
1.1 |
}, |
76 |
|
|
{ |
77 |
|
|
data => q<http://%5a/>, |
78 |
wakaba |
1.5 |
errors => ['w:7.9:URL:lowercase hexadecimal digit', |
79 |
|
|
'w:7.9:URL:percent-encoded unreserved'], |
80 |
wakaba |
1.1 |
}, |
81 |
|
|
{ |
82 |
|
|
data => q<./%2E%2E>, |
83 |
wakaba |
1.5 |
errors => ['w:2.4:URL:percent-encoded unreserved', |
84 |
|
|
'w:5.7:URL:percent-encoded unreserved'], |
85 |
wakaba |
1.1 |
}, |
86 |
|
|
{ |
87 |
|
|
data => q<http://www.example.com/%7Euser/>, |
88 |
wakaba |
1.5 |
errors => ['w:23.25:URL:percent-encoded unreserved'], |
89 |
wakaba |
1.1 |
}, |
90 |
|
|
{ |
91 |
|
|
data => q<HTTP://example/>, |
92 |
wakaba |
1.4 |
errors => ['w::URL:uppercase scheme name'], |
93 |
wakaba |
1.1 |
}, |
94 |
|
|
{ |
95 |
|
|
data => q<Http://example/>, |
96 |
wakaba |
1.4 |
errors => ['w::URL:uppercase scheme name'], |
97 |
wakaba |
1.1 |
}, |
98 |
|
|
{ |
99 |
|
|
data => q<datA:,>, |
100 |
wakaba |
1.4 |
errors => ['w::URL:uppercase scheme name'], |
101 |
wakaba |
1.1 |
}, |
102 |
|
|
{ |
103 |
|
|
data => q<dat%41:,>, |
104 |
wakaba |
1.4 |
errors => ['m::syntax error:iriref3987', |
105 |
|
|
'w::URL:uppercase scheme name', |
106 |
wakaba |
1.5 |
'w:3.5:URL:percent-encoded unreserved'], |
107 |
wakaba |
1.1 |
}, |
108 |
|
|
{ |
109 |
|
|
data => q<g%5A:,>, |
110 |
wakaba |
1.4 |
errors => ['m::syntax error:iriref3987', |
111 |
|
|
'w::URL:uppercase scheme name', |
112 |
wakaba |
1.5 |
'w:1.3:URL:percent-encoded unreserved'], |
113 |
wakaba |
1.1 |
}, |
114 |
|
|
{ |
115 |
|
|
data => q<g%7A:,>, |
116 |
wakaba |
1.4 |
errors => ['m::syntax error:iriref3987', |
117 |
wakaba |
1.5 |
'w:1.3:URL:percent-encoded unreserved'], |
118 |
wakaba |
1.1 |
}, |
119 |
|
|
{ |
120 |
|
|
data => q<http://www.test:2222/>, |
121 |
|
|
errors => [], |
122 |
|
|
}, |
123 |
|
|
{ |
124 |
|
|
data => q<http://www.example:0/>, |
125 |
|
|
errors => [], |
126 |
|
|
}, |
127 |
|
|
{ |
128 |
|
|
data => q<http://www@example:/>, |
129 |
wakaba |
1.4 |
errors => ['w::URL:empty port'], |
130 |
wakaba |
1.1 |
}, |
131 |
|
|
{ |
132 |
|
|
data => q<http://www.test:/>, |
133 |
wakaba |
1.4 |
errors => ['w::URL:empty port'], |
134 |
wakaba |
1.1 |
}, |
135 |
|
|
{ |
136 |
|
|
data => q<http://user:password@example/>, |
137 |
wakaba |
1.4 |
errors => ['w::URL:password'], |
138 |
wakaba |
1.1 |
}, |
139 |
|
|
{ |
140 |
|
|
data => q<http://EXAMPLE/>, |
141 |
wakaba |
1.5 |
errors => ['w::URL:uppercase host'], |
142 |
wakaba |
1.1 |
}, |
143 |
|
|
{ |
144 |
|
|
data => q<http://USER@example/>, |
145 |
|
|
errors => [], |
146 |
|
|
}, |
147 |
|
|
{ |
148 |
|
|
data => q<http://[v0.aaa]/>, |
149 |
wakaba |
1.5 |
errors => ['w:1.2:URL:address format:v0'], |
150 |
wakaba |
1.1 |
}, |
151 |
|
|
{ |
152 |
|
|
data => q<http://user@[v0.aaa]/>, |
153 |
wakaba |
1.5 |
errors => ['w:1.2:URL:address format:v0'], |
154 |
wakaba |
1.1 |
}, |
155 |
|
|
{ |
156 |
wakaba |
1.2 |
data => q<http://user@[V0A.aaa]/>, |
157 |
wakaba |
1.5 |
errors => ['w:1.3:URL:address format:V0A', |
158 |
|
|
'w::URL:uppercase host'], |
159 |
wakaba |
1.2 |
}, |
160 |
|
|
{ |
161 |
wakaba |
1.1 |
data => q<http://127.0.0.1/>, |
162 |
|
|
errors => [], |
163 |
|
|
}, |
164 |
|
|
{ |
165 |
|
|
data => q<http://123456789012345678901234567890123456789012345678901234567890123.test/>, |
166 |
|
|
errors => [], |
167 |
|
|
}, |
168 |
|
|
{ |
169 |
|
|
data => q<http://1234567890123456789012345678901234567890123456789012345678901234.test/>, |
170 |
wakaba |
1.4 |
errors => ['w::URL:non-DNS host'], |
171 |
wakaba |
1.1 |
}, |
172 |
|
|
{ |
173 |
|
|
data => q<http://123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123/>, |
174 |
|
|
errors => [], |
175 |
|
|
}, |
176 |
|
|
{ |
177 |
|
|
data => q<http://123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123./>, |
178 |
wakaba |
1.5 |
errors => ['w:256.256:URL:long host'], |
179 |
|
|
}, |
180 |
|
|
{ |
181 |
|
|
data => q<http://123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.123456789012345678901234567890123456789012345678901234567890123.456789/>, |
182 |
|
|
errors => ['w:256.262:URL:long host'], |
183 |
wakaba |
1.1 |
}, |
184 |
|
|
{ |
185 |
|
|
data => q<http://a_b.test/>, |
186 |
wakaba |
1.4 |
errors => ['w::URL:non-DNS host'], |
187 |
wakaba |
1.1 |
}, |
188 |
|
|
{ |
189 |
|
|
data => q<http://%61.test/>, |
190 |
wakaba |
1.5 |
errors => ['w:7.9:URL:percent-encoded unreserved'], |
191 |
wakaba |
1.1 |
}, |
192 |
|
|
{ |
193 |
|
|
data => q<http://a.test/>, |
194 |
|
|
errors => [], |
195 |
|
|
}, |
196 |
|
|
{ |
197 |
|
|
data => q<http://1.test/>, |
198 |
|
|
errors => [], |
199 |
|
|
}, |
200 |
|
|
{ |
201 |
|
|
data => q<http://a-1.test/>, |
202 |
|
|
errors => [], |
203 |
|
|
}, |
204 |
|
|
{ |
205 |
|
|
data => q<http://1-a.test/>, |
206 |
|
|
errors => [], |
207 |
|
|
}, |
208 |
|
|
{ |
209 |
|
|
data => q<http://a-.test/>, |
210 |
wakaba |
1.4 |
errors => ['w::URL:non-DNS host'], |
211 |
wakaba |
1.1 |
}, |
212 |
|
|
{ |
213 |
|
|
data => q<http://-a.test/>, |
214 |
wakaba |
1.4 |
errors => ['w::URL:non-DNS host'], |
215 |
wakaba |
1.1 |
}, |
216 |
|
|
{ |
217 |
|
|
data => q<http://a.b.test/>, |
218 |
|
|
errors => [], |
219 |
|
|
}, |
220 |
|
|
{ |
221 |
|
|
data => q<http://a.bc.test/>, |
222 |
|
|
errors => [], |
223 |
|
|
}, |
224 |
|
|
{ |
225 |
|
|
data => q<http://a.b-c.test/>, |
226 |
wakaba |
1.2 |
errors => [], |
227 |
|
|
}, |
228 |
|
|
{ |
229 |
|
|
data => qq<http://\x{123}\x{456}.test/>, |
230 |
wakaba |
1.4 |
errors => ['w::URL:non-DNS host'], |
231 |
wakaba |
1.2 |
}, |
232 |
|
|
{ |
233 |
|
|
data => qq<http://\x{4E00}%80.test/>, |
234 |
wakaba |
1.4 |
errors => ['w::URL:non-DNS host', |
235 |
|
|
'm::URL:non UTF-8 host'], |
236 |
wakaba |
1.2 |
}, |
237 |
|
|
{ |
238 |
|
|
data => q<http://a.%E3%81%82%E3%81%84.test/>, |
239 |
wakaba |
1.4 |
errors => ['w::URL:non-DNS host'], |
240 |
wakaba |
1.2 |
}, |
241 |
|
|
{ |
242 |
|
|
data => q<example://a/b/c/%7Bfoo%7D>, |
243 |
|
|
errors => [], |
244 |
|
|
}, |
245 |
|
|
{ |
246 |
|
|
data => q<eXAMPLE://a/./b/../b/%63/%7bfoo%7d>, |
247 |
wakaba |
1.4 |
errors => ['w::URL:uppercase scheme name', |
248 |
wakaba |
1.5 |
'w:21.23:URL:percent-encoded unreserved', |
249 |
|
|
'w:25.27:URL:lowercase hexadecimal digit', |
250 |
|
|
'w:31.33:URL:lowercase hexadecimal digit', |
251 |
wakaba |
1.4 |
'w::URL:dot-segment'], |
252 |
wakaba |
1.2 |
}, |
253 |
|
|
{ |
254 |
|
|
data => q<example://a/.htaccess>, |
255 |
|
|
errors => [], |
256 |
|
|
}, |
257 |
|
|
{ |
258 |
|
|
data => q<example://a/.>, |
259 |
wakaba |
1.4 |
errors => ['w::URL:dot-segment'], |
260 |
wakaba |
1.2 |
}, |
261 |
|
|
{ |
262 |
|
|
data => q<http://example.com>, |
263 |
wakaba |
1.4 |
errors => ['w::URL:empty path'], |
264 |
wakaba |
1.2 |
}, |
265 |
|
|
{ |
266 |
|
|
data => q<http://example.com/>, |
267 |
|
|
errors => [], |
268 |
|
|
}, |
269 |
|
|
{ |
270 |
|
|
data => q<http://example.com:/>, |
271 |
wakaba |
1.4 |
errors => ['w::URL:empty port'], |
272 |
wakaba |
1.2 |
}, |
273 |
|
|
{ |
274 |
|
|
data => q<http://example.com:80/>, |
275 |
wakaba |
1.4 |
errors => ['w::URL:default port'], |
276 |
wakaba |
1.2 |
}, |
277 |
|
|
{ |
278 |
|
|
data => q<hTTP://example.com:80/>, |
279 |
wakaba |
1.4 |
errors => ['w::URL:uppercase scheme name', |
280 |
|
|
'w::URL:default port'], |
281 |
wakaba |
1.2 |
}, |
282 |
|
|
{ |
283 |
|
|
data => q<%68ttp://example.com:80/>, |
284 |
wakaba |
1.4 |
errors => ['m::syntax error:iriref3987', |
285 |
wakaba |
1.5 |
'w:0.2:URL:percent-encoded unreserved', |
286 |
wakaba |
1.4 |
'w::URL:default port'], |
287 |
wakaba |
1.2 |
}, |
288 |
|
|
{ |
289 |
|
|
data => q<file://user@/>, |
290 |
wakaba |
1.4 |
errors => ['w::URL:empty host'], |
291 |
wakaba |
1.2 |
}, |
292 |
|
|
{ |
293 |
|
|
data => q<http://example.com/?>, |
294 |
|
|
errors => [], |
295 |
|
|
}, |
296 |
|
|
{ |
297 |
|
|
data => q<mailto:Joe@Example.COM>, |
298 |
|
|
errors => [], |
299 |
|
|
}, |
300 |
|
|
{ |
301 |
|
|
data => q<mailto:Joe@example.com>, |
302 |
|
|
errors => [], |
303 |
|
|
}, |
304 |
|
|
{ |
305 |
|
|
data => q<http://example.com/data>, |
306 |
|
|
errors => [], |
307 |
|
|
}, |
308 |
|
|
{ |
309 |
|
|
data => q<ftp://cnn.example.com&story=breaking_news@10.0.0.1/top_story.htm>, |
310 |
|
|
errors => [], |
311 |
|
|
}, |
312 |
|
|
{ |
313 |
|
|
data => qq<http://r\xE9sum\xE9.example.org>, |
314 |
wakaba |
1.4 |
errors => ['w::URL:non-DNS host', |
315 |
|
|
'w::URL:empty path'], |
316 |
wakaba |
1.2 |
}, |
317 |
|
|
{ |
318 |
|
|
data => qq<http://validator.w3.org/check?uri=http%3A%2F%2Fr\xE9;sum\xE9.example.com>, |
319 |
|
|
errors => [], |
320 |
|
|
}, |
321 |
|
|
{ |
322 |
|
|
data => q<http://validator.w3.org/check?uri=http%3A%2F%2Fr%C3%A9sum%C3%A9.example.com>, |
323 |
|
|
errors => [], |
324 |
|
|
}, |
325 |
|
|
{ |
326 |
|
|
data => qq<http://example.com/\x{10300}\x{10301}\x{10302}>, |
327 |
|
|
errors => [], |
328 |
|
|
}, |
329 |
|
|
{ |
330 |
|
|
data => q<http://example.com/%F0%90%8C%80%F0%90%8C%81%F0%90%8C%82>, |
331 |
|
|
errors => [], |
332 |
|
|
}, |
333 |
|
|
{ |
334 |
|
|
data => q<http://www.example.org/r%E9sum%E9.html>, |
335 |
|
|
errors => [], |
336 |
|
|
}, |
337 |
|
|
{ |
338 |
|
|
data => q<http://xn--99zt52a.example.org/%e2%80%ae>, |
339 |
wakaba |
1.5 |
errors => ['w:31.33:URL:lowercase hexadecimal digit', |
340 |
|
|
'w:37.39:URL:lowercase hexadecimal digit'], |
341 |
wakaba |
1.2 |
}, |
342 |
|
|
{ |
343 |
|
|
data => qq<example://a/b/c/%7Bfoo%7D/ros\xE9>, |
344 |
|
|
errors => [], |
345 |
|
|
}, |
346 |
|
|
{ |
347 |
|
|
data => qq<eXAMPLE://a/./b/../b/%63/%7bfoo%7d/ros%C3%A9>, |
348 |
wakaba |
1.4 |
errors => ['w::URL:uppercase scheme name', |
349 |
wakaba |
1.5 |
'w:21.23:URL:percent-encoded unreserved', |
350 |
|
|
'w:25.27:URL:lowercase hexadecimal digit', |
351 |
|
|
'w:31.33:URL:lowercase hexadecimal digit', |
352 |
wakaba |
1.4 |
'w::URL:dot-segment'], |
353 |
wakaba |
1.2 |
}, |
354 |
|
|
{ |
355 |
wakaba |
1.5 |
data => qq<http://www.example.org/..abc/>, |
356 |
|
|
errors => [], |
357 |
|
|
}, |
358 |
|
|
{ |
359 |
|
|
data => qq<http://www.example.org/../abc/>, |
360 |
|
|
errors => ['w::URL:dot-segment'], |
361 |
|
|
}, |
362 |
|
|
{ |
363 |
wakaba |
1.2 |
data => qq<http://www.example.org/r\xE9sum\xE9.html>, |
364 |
|
|
errors => [], |
365 |
|
|
}, |
366 |
|
|
{ |
367 |
|
|
data => qq<http://www.example.org/re\x{301}sume\x{301}.html>, |
368 |
|
|
errors => [], ## TODO: not in NFC |
369 |
|
|
}, |
370 |
|
|
{ |
371 |
|
|
data => q<http://www.example.org/r%E9sum%E9.xml#r%C3%A9sum%C3%A9>, |
372 |
wakaba |
1.1 |
errors => [], |
373 |
|
|
}, |
374 |
|
|
]; |
375 |
|
|
|
376 |
|
|
require Whatpm::URIChecker; |
377 |
|
|
|
378 |
|
|
for my $test (@$Cases) { |
379 |
|
|
@{$test->{errors}} = sort {$a cmp $b} @{$test->{errors}}; |
380 |
|
|
my @errors; |
381 |
|
|
Whatpm::URIChecker->check_iri_reference ($test->{data}, sub { |
382 |
|
|
my %opt = @_; |
383 |
|
|
push @errors, $opt{level} . ':' . |
384 |
wakaba |
1.5 |
(defined $opt{pos_start} ? $opt{pos_start} . '.' . $opt{pos_end} : '') . ':' . |
385 |
wakaba |
1.4 |
$opt{type} . |
386 |
wakaba |
1.5 |
(defined $opt{text} ? ':' . $opt{text} : ''); |
387 |
wakaba |
1.1 |
}); |
388 |
|
|
@errors = sort {$a cmp $b} @errors; |
389 |
|
|
|
390 |
|
|
ok join ("\n", @errors), join ("\n", @{$test->{errors}}), $test->{data}; |
391 |
|
|
} |