addressable 2.8.1 → 2.8.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +76 -42
- data/Rakefile +11 -5
- data/addressable.gemspec +28 -0
- data/lib/addressable/idna/native.rb +8 -2
- data/lib/addressable/idna/pure.rb +10 -182
- data/lib/addressable/template.rb +9 -10
- data/lib/addressable/uri.rb +176 -134
- data/lib/addressable/version.rb +1 -1
- data/spec/addressable/idna_spec.rb +6 -5
- data/spec/addressable/template_spec.rb +60 -264
- data/spec/addressable/uri_spec.rb +95 -0
- data/tasks/gem.rake +1 -1
- metadata +5 -4
data/lib/addressable/version.rb
CHANGED
@@ -38,6 +38,12 @@ shared_examples_for "converting from unicode to ASCII" do
|
|
38
38
|
)).to eq("www.xn--8ws00zhy3a.com")
|
39
39
|
end
|
40
40
|
|
41
|
+
it "also accepts unicode strings encoded as ascii-8bit" do
|
42
|
+
expect(Addressable::IDNA.to_ascii(
|
43
|
+
"www.詹姆斯.com".b
|
44
|
+
)).to eq("www.xn--8ws00zhy3a.com")
|
45
|
+
end
|
46
|
+
|
41
47
|
it "should convert 'www.Iñtërnâtiônàlizætiøn.com' correctly" do
|
42
48
|
"www.Iñtërnâtiônàlizætiøn.com"
|
43
49
|
expect(Addressable::IDNA.to_ascii(
|
@@ -249,11 +255,6 @@ shared_examples_for "converting from ASCII to unicode" do
|
|
249
255
|
"example..host"
|
250
256
|
)).to eq("example..host")
|
251
257
|
end
|
252
|
-
|
253
|
-
it "should normalize 'string' correctly" do
|
254
|
-
expect(Addressable::IDNA.unicode_normalize_kc(:'string')).to eq("string")
|
255
|
-
expect(Addressable::IDNA.unicode_normalize_kc("string")).to eq("string")
|
256
|
-
end
|
257
258
|
end
|
258
259
|
|
259
260
|
describe Addressable::IDNA, "when using the pure-Ruby implementation" do
|
@@ -26,11 +26,7 @@ shared_examples_for 'expands' do |tests|
|
|
26
26
|
exp = expansion.is_a?(Array) ? expansion.first : expansion
|
27
27
|
it "#{template} to #{exp}" do
|
28
28
|
tmpl = Addressable::Template.new(template).expand(subject)
|
29
|
-
|
30
|
-
expect(expansion.any?{|i| i == tmpl.to_str}).to be true
|
31
|
-
else
|
32
|
-
expect(tmpl.to_str).to eq(expansion)
|
33
|
-
end
|
29
|
+
expect(tmpl.to_str).to eq(expansion)
|
34
30
|
end
|
35
31
|
end
|
36
32
|
end
|
@@ -209,7 +205,7 @@ describe "Level 4" do
|
|
209
205
|
:path => "/foo/bar",
|
210
206
|
:semi => ";",
|
211
207
|
:list => %w(red green blue),
|
212
|
-
:keys => {"semi" => ';', "dot" => '.',
|
208
|
+
:keys => {"semi" => ';', "dot" => '.', :comma => ','}
|
213
209
|
}
|
214
210
|
}
|
215
211
|
context "Expansion with value modifiers" do
|
@@ -218,22 +214,8 @@ describe "Level 4" do
|
|
218
214
|
'{var:30}' => 'value',
|
219
215
|
'{list}' => 'red,green,blue',
|
220
216
|
'{list*}' => 'red,green,blue',
|
221
|
-
'{keys}' =>
|
222
|
-
|
223
|
-
'dot,.,semi,%3B,comma,%2C',
|
224
|
-
'comma,%2C,semi,%3B,dot,.',
|
225
|
-
'semi,%3B,comma,%2C,dot,.',
|
226
|
-
'dot,.,comma,%2C,semi,%3B',
|
227
|
-
'comma,%2C,dot,.,semi,%3B'
|
228
|
-
],
|
229
|
-
'{keys*}' => [
|
230
|
-
'semi=%3B,dot=.,comma=%2C',
|
231
|
-
'dot=.,semi=%3B,comma=%2C',
|
232
|
-
'comma=%2C,semi=%3B,dot=.',
|
233
|
-
'semi=%3B,comma=%2C,dot=.',
|
234
|
-
'dot=.,comma=%2C,semi=%3B',
|
235
|
-
'comma=%2C,dot=.,semi=%3B'
|
236
|
-
]
|
217
|
+
'{keys}' => 'semi,%3B,dot,.,comma,%2C',
|
218
|
+
'{keys*}' => 'semi=%3B,dot=.,comma=%2C',
|
237
219
|
}
|
238
220
|
end
|
239
221
|
context "Operator + with value modifiers" do
|
@@ -241,22 +223,8 @@ describe "Level 4" do
|
|
241
223
|
'{+path:6}/here' => '/foo/b/here',
|
242
224
|
'{+list}' => 'red,green,blue',
|
243
225
|
'{+list*}' => 'red,green,blue',
|
244
|
-
'{+keys}' =>
|
245
|
-
|
246
|
-
'dot,.,semi,;,comma,,',
|
247
|
-
'comma,,,semi,;,dot,.',
|
248
|
-
'semi,;,comma,,,dot,.',
|
249
|
-
'dot,.,comma,,,semi,;',
|
250
|
-
'comma,,,dot,.,semi,;'
|
251
|
-
],
|
252
|
-
'{+keys*}' => [
|
253
|
-
'semi=;,dot=.,comma=,',
|
254
|
-
'dot=.,semi=;,comma=,',
|
255
|
-
'comma=,,semi=;,dot=.',
|
256
|
-
'semi=;,comma=,,dot=.',
|
257
|
-
'dot=.,comma=,,semi=;',
|
258
|
-
'comma=,,dot=.,semi=;'
|
259
|
-
]
|
226
|
+
'{+keys}' => 'semi,;,dot,.,comma,,',
|
227
|
+
'{+keys*}' => 'semi=;,dot=.,comma=,',
|
260
228
|
}
|
261
229
|
end
|
262
230
|
context "Operator # with value modifiers" do
|
@@ -264,22 +232,8 @@ describe "Level 4" do
|
|
264
232
|
'{#path:6}/here' => '#/foo/b/here',
|
265
233
|
'{#list}' => '#red,green,blue',
|
266
234
|
'{#list*}' => '#red,green,blue',
|
267
|
-
'{#keys}' =>
|
268
|
-
|
269
|
-
'#dot,.,semi,;,comma,,',
|
270
|
-
'#comma,,,semi,;,dot,.',
|
271
|
-
'#semi,;,comma,,,dot,.',
|
272
|
-
'#dot,.,comma,,,semi,;',
|
273
|
-
'#comma,,,dot,.,semi,;'
|
274
|
-
],
|
275
|
-
'{#keys*}' => [
|
276
|
-
'#semi=;,dot=.,comma=,',
|
277
|
-
'#dot=.,semi=;,comma=,',
|
278
|
-
'#comma=,,semi=;,dot=.',
|
279
|
-
'#semi=;,comma=,,dot=.',
|
280
|
-
'#dot=.,comma=,,semi=;',
|
281
|
-
'#comma=,,dot=.,semi=;'
|
282
|
-
]
|
235
|
+
'{#keys}' => '#semi,;,dot,.,comma,,',
|
236
|
+
'{#keys*}' => '#semi=;,dot=.,comma=,',
|
283
237
|
}
|
284
238
|
end
|
285
239
|
context "Operator . with value modifiers" do
|
@@ -287,22 +241,8 @@ describe "Level 4" do
|
|
287
241
|
'X{.var:3}' => 'X.val',
|
288
242
|
'X{.list}' => 'X.red,green,blue',
|
289
243
|
'X{.list*}' => 'X.red.green.blue',
|
290
|
-
'X{.keys}' =>
|
291
|
-
|
292
|
-
'X.dot,.,semi,%3B,comma,%2C',
|
293
|
-
'X.comma,%2C,semi,%3B,dot,.',
|
294
|
-
'X.semi,%3B,comma,%2C,dot,.',
|
295
|
-
'X.dot,.,comma,%2C,semi,%3B',
|
296
|
-
'X.comma,%2C,dot,.,semi,%3B'
|
297
|
-
],
|
298
|
-
'X{.keys*}' => [
|
299
|
-
'X.semi=%3B.dot=..comma=%2C',
|
300
|
-
'X.dot=..semi=%3B.comma=%2C',
|
301
|
-
'X.comma=%2C.semi=%3B.dot=.',
|
302
|
-
'X.semi=%3B.comma=%2C.dot=.',
|
303
|
-
'X.dot=..comma=%2C.semi=%3B',
|
304
|
-
'X.comma=%2C.dot=..semi=%3B'
|
305
|
-
]
|
244
|
+
'X{.keys}' => 'X.semi,%3B,dot,.,comma,%2C',
|
245
|
+
'X{.keys*}' => 'X.semi=%3B.dot=..comma=%2C',
|
306
246
|
}
|
307
247
|
end
|
308
248
|
context "Operator / with value modifiers" do
|
@@ -311,22 +251,8 @@ describe "Level 4" do
|
|
311
251
|
'{/list}' => '/red,green,blue',
|
312
252
|
'{/list*}' => '/red/green/blue',
|
313
253
|
'{/list*,path:4}' => '/red/green/blue/%2Ffoo',
|
314
|
-
'{/keys}' =>
|
315
|
-
|
316
|
-
'/dot,.,semi,%3B,comma,%2C',
|
317
|
-
'/comma,%2C,semi,%3B,dot,.',
|
318
|
-
'/semi,%3B,comma,%2C,dot,.',
|
319
|
-
'/dot,.,comma,%2C,semi,%3B',
|
320
|
-
'/comma,%2C,dot,.,semi,%3B'
|
321
|
-
],
|
322
|
-
'{/keys*}' => [
|
323
|
-
'/semi=%3B/dot=./comma=%2C',
|
324
|
-
'/dot=./semi=%3B/comma=%2C',
|
325
|
-
'/comma=%2C/semi=%3B/dot=.',
|
326
|
-
'/semi=%3B/comma=%2C/dot=.',
|
327
|
-
'/dot=./comma=%2C/semi=%3B',
|
328
|
-
'/comma=%2C/dot=./semi=%3B'
|
329
|
-
]
|
254
|
+
'{/keys}' => '/semi,%3B,dot,.,comma,%2C',
|
255
|
+
'{/keys*}' => '/semi=%3B/dot=./comma=%2C',
|
330
256
|
}
|
331
257
|
end
|
332
258
|
context "Operator ; with value modifiers" do
|
@@ -334,22 +260,8 @@ describe "Level 4" do
|
|
334
260
|
'{;hello:5}' => ';hello=Hello',
|
335
261
|
'{;list}' => ';list=red,green,blue',
|
336
262
|
'{;list*}' => ';list=red;list=green;list=blue',
|
337
|
-
'{;keys}' =>
|
338
|
-
|
339
|
-
';keys=dot,.,semi,%3B,comma,%2C',
|
340
|
-
';keys=comma,%2C,semi,%3B,dot,.',
|
341
|
-
';keys=semi,%3B,comma,%2C,dot,.',
|
342
|
-
';keys=dot,.,comma,%2C,semi,%3B',
|
343
|
-
';keys=comma,%2C,dot,.,semi,%3B'
|
344
|
-
],
|
345
|
-
'{;keys*}' => [
|
346
|
-
';semi=%3B;dot=.;comma=%2C',
|
347
|
-
';dot=.;semi=%3B;comma=%2C',
|
348
|
-
';comma=%2C;semi=%3B;dot=.',
|
349
|
-
';semi=%3B;comma=%2C;dot=.',
|
350
|
-
';dot=.;comma=%2C;semi=%3B',
|
351
|
-
';comma=%2C;dot=.;semi=%3B'
|
352
|
-
]
|
263
|
+
'{;keys}' => ';keys=semi,%3B,dot,.,comma,%2C',
|
264
|
+
'{;keys*}' => ';semi=%3B;dot=.;comma=%2C',
|
353
265
|
}
|
354
266
|
end
|
355
267
|
context "Operator ? with value modifiers" do
|
@@ -357,22 +269,8 @@ describe "Level 4" do
|
|
357
269
|
'{?var:3}' => '?var=val',
|
358
270
|
'{?list}' => '?list=red,green,blue',
|
359
271
|
'{?list*}' => '?list=red&list=green&list=blue',
|
360
|
-
'{?keys}' =>
|
361
|
-
|
362
|
-
'?keys=dot,.,semi,%3B,comma,%2C',
|
363
|
-
'?keys=comma,%2C,semi,%3B,dot,.',
|
364
|
-
'?keys=semi,%3B,comma,%2C,dot,.',
|
365
|
-
'?keys=dot,.,comma,%2C,semi,%3B',
|
366
|
-
'?keys=comma,%2C,dot,.,semi,%3B'
|
367
|
-
],
|
368
|
-
'{?keys*}' => [
|
369
|
-
'?semi=%3B&dot=.&comma=%2C',
|
370
|
-
'?dot=.&semi=%3B&comma=%2C',
|
371
|
-
'?comma=%2C&semi=%3B&dot=.',
|
372
|
-
'?semi=%3B&comma=%2C&dot=.',
|
373
|
-
'?dot=.&comma=%2C&semi=%3B',
|
374
|
-
'?comma=%2C&dot=.&semi=%3B'
|
375
|
-
]
|
272
|
+
'{?keys}' => '?keys=semi,%3B,dot,.,comma,%2C',
|
273
|
+
'{?keys*}' => '?semi=%3B&dot=.&comma=%2C',
|
376
274
|
}
|
377
275
|
end
|
378
276
|
context "Operator & with value modifiers" do
|
@@ -380,22 +278,8 @@ describe "Level 4" do
|
|
380
278
|
'{&var:3}' => '&var=val',
|
381
279
|
'{&list}' => '&list=red,green,blue',
|
382
280
|
'{&list*}' => '&list=red&list=green&list=blue',
|
383
|
-
'{&keys}' =>
|
384
|
-
|
385
|
-
'&keys=dot,.,semi,%3B,comma,%2C',
|
386
|
-
'&keys=comma,%2C,semi,%3B,dot,.',
|
387
|
-
'&keys=semi,%3B,comma,%2C,dot,.',
|
388
|
-
'&keys=dot,.,comma,%2C,semi,%3B',
|
389
|
-
'&keys=comma,%2C,dot,.,semi,%3B'
|
390
|
-
],
|
391
|
-
'{&keys*}' => [
|
392
|
-
'&semi=%3B&dot=.&comma=%2C',
|
393
|
-
'&dot=.&semi=%3B&comma=%2C',
|
394
|
-
'&comma=%2C&semi=%3B&dot=.',
|
395
|
-
'&semi=%3B&comma=%2C&dot=.',
|
396
|
-
'&dot=.&comma=%2C&semi=%3B',
|
397
|
-
'&comma=%2C&dot=.&semi=%3B'
|
398
|
-
]
|
281
|
+
'{&keys}' => '&keys=semi,%3B,dot,.,comma,%2C',
|
282
|
+
'{&keys*}' => '&semi=%3B&dot=.&comma=%2C',
|
399
283
|
}
|
400
284
|
end
|
401
285
|
end
|
@@ -404,7 +288,7 @@ describe "Modifiers" do
|
|
404
288
|
{
|
405
289
|
:var => "value",
|
406
290
|
:semi => ";",
|
407
|
-
:year =>
|
291
|
+
:year => [1965, 2000, 2012],
|
408
292
|
:dom => %w(example com)
|
409
293
|
}
|
410
294
|
}
|
@@ -437,7 +321,7 @@ describe "Expansion" do
|
|
437
321
|
:base => "http://example.com/home/",
|
438
322
|
:path => "/foo/bar",
|
439
323
|
:list => ["red", "green", "blue"],
|
440
|
-
:keys => {"semi" => ";","dot" => "."
|
324
|
+
:keys => {"semi" => ";","dot" => ".",:comma => ","},
|
441
325
|
:v => "6",
|
442
326
|
:x => "1024",
|
443
327
|
:y => "768",
|
@@ -475,22 +359,8 @@ describe "Expansion" do
|
|
475
359
|
'{var:30}' => 'value',
|
476
360
|
'{list}' => 'red,green,blue',
|
477
361
|
'{list*}' => 'red,green,blue',
|
478
|
-
'{keys}' =>
|
479
|
-
|
480
|
-
'dot,.,semi,%3B,comma,%2C',
|
481
|
-
'comma,%2C,semi,%3B,dot,.',
|
482
|
-
'semi,%3B,comma,%2C,dot,.',
|
483
|
-
'dot,.,comma,%2C,semi,%3B',
|
484
|
-
'comma,%2C,dot,.,semi,%3B'
|
485
|
-
],
|
486
|
-
'{keys*}' => [
|
487
|
-
'semi=%3B,dot=.,comma=%2C',
|
488
|
-
'dot=.,semi=%3B,comma=%2C',
|
489
|
-
'comma=%2C,semi=%3B,dot=.',
|
490
|
-
'semi=%3B,comma=%2C,dot=.',
|
491
|
-
'dot=.,comma=%2C,semi=%3B',
|
492
|
-
'comma=%2C,dot=.,semi=%3B'
|
493
|
-
]
|
362
|
+
'{keys}' => 'semi,%3B,dot,.,comma,%2C',
|
363
|
+
'{keys*}' => 'semi=%3B,dot=.,comma=%2C',
|
494
364
|
}
|
495
365
|
end
|
496
366
|
context "reserved expansion (+)" do
|
@@ -510,22 +380,8 @@ describe "Expansion" do
|
|
510
380
|
'{+path:6}/here' => '/foo/b/here',
|
511
381
|
'{+list}' => 'red,green,blue',
|
512
382
|
'{+list*}' => 'red,green,blue',
|
513
|
-
'{+keys}' =>
|
514
|
-
|
515
|
-
'dot,.,semi,;,comma,,',
|
516
|
-
'comma,,,semi,;,dot,.',
|
517
|
-
'semi,;,comma,,,dot,.',
|
518
|
-
'dot,.,comma,,,semi,;',
|
519
|
-
'comma,,,dot,.,semi,;'
|
520
|
-
],
|
521
|
-
'{+keys*}' => [
|
522
|
-
'semi=;,dot=.,comma=,',
|
523
|
-
'dot=.,semi=;,comma=,',
|
524
|
-
'comma=,,semi=;,dot=.',
|
525
|
-
'semi=;,comma=,,dot=.',
|
526
|
-
'dot=.,comma=,,semi=;',
|
527
|
-
'comma=,,dot=.,semi=;'
|
528
|
-
]
|
383
|
+
'{+keys}' => 'semi,;,dot,.,comma,,',
|
384
|
+
'{+keys*}' => 'semi=;,dot=.,comma=,',
|
529
385
|
}
|
530
386
|
end
|
531
387
|
context "fragment expansion (#)" do
|
@@ -540,22 +396,8 @@ describe "Expansion" do
|
|
540
396
|
'{#path:6}/here' => '#/foo/b/here',
|
541
397
|
'{#list}' => '#red,green,blue',
|
542
398
|
'{#list*}' => '#red,green,blue',
|
543
|
-
'{#keys}' =>
|
544
|
-
|
545
|
-
'#dot,.,semi,;,comma,,',
|
546
|
-
'#comma,,,semi,;,dot,.',
|
547
|
-
'#semi,;,comma,,,dot,.',
|
548
|
-
'#dot,.,comma,,,semi,;',
|
549
|
-
'#comma,,,dot,.,semi,;'
|
550
|
-
],
|
551
|
-
'{#keys*}' => [
|
552
|
-
'#semi=;,dot=.,comma=,',
|
553
|
-
'#dot=.,semi=;,comma=,',
|
554
|
-
'#comma=,,semi=;,dot=.',
|
555
|
-
'#semi=;,comma=,,dot=.',
|
556
|
-
'#dot=.,comma=,,semi=;',
|
557
|
-
'#comma=,,dot=.,semi=;'
|
558
|
-
]
|
399
|
+
'{#keys}' => '#semi,;,dot,.,comma,,',
|
400
|
+
'{#keys*}' => '#semi=;,dot=.,comma=,',
|
559
401
|
}
|
560
402
|
end
|
561
403
|
context "label expansion (.)" do
|
@@ -570,22 +412,8 @@ describe "Expansion" do
|
|
570
412
|
'X{.var:3}' => 'X.val',
|
571
413
|
'X{.list}' => 'X.red,green,blue',
|
572
414
|
'X{.list*}' => 'X.red.green.blue',
|
573
|
-
'X{.keys}' =>
|
574
|
-
|
575
|
-
'X.dot,.,semi,%3B,comma,%2C',
|
576
|
-
'X.comma,%2C,semi,%3B,dot,.',
|
577
|
-
'X.semi,%3B,comma,%2C,dot,.',
|
578
|
-
'X.dot,.,comma,%2C,semi,%3B',
|
579
|
-
'X.comma,%2C,dot,.,semi,%3B'
|
580
|
-
],
|
581
|
-
'X{.keys*}' => [
|
582
|
-
'X.semi=%3B.dot=..comma=%2C',
|
583
|
-
'X.dot=..semi=%3B.comma=%2C',
|
584
|
-
'X.comma=%2C.semi=%3B.dot=.',
|
585
|
-
'X.semi=%3B.comma=%2C.dot=.',
|
586
|
-
'X.dot=..comma=%2C.semi=%3B',
|
587
|
-
'X.comma=%2C.dot=..semi=%3B'
|
588
|
-
],
|
415
|
+
'X{.keys}' => 'X.semi,%3B,dot,.,comma,%2C',
|
416
|
+
'X{.keys*}' => 'X.semi=%3B.dot=..comma=%2C',
|
589
417
|
'X{.empty_keys}' => 'X',
|
590
418
|
'X{.empty_keys*}' => 'X'
|
591
419
|
}
|
@@ -604,22 +432,8 @@ describe "Expansion" do
|
|
604
432
|
'{/list}' => '/red,green,blue',
|
605
433
|
'{/list*}' => '/red/green/blue',
|
606
434
|
'{/list*,path:4}' => '/red/green/blue/%2Ffoo',
|
607
|
-
'{/keys}' =>
|
608
|
-
|
609
|
-
'/dot,.,semi,%3B,comma,%2C',
|
610
|
-
'/comma,%2C,semi,%3B,dot,.',
|
611
|
-
'/semi,%3B,comma,%2C,dot,.',
|
612
|
-
'/dot,.,comma,%2C,semi,%3B',
|
613
|
-
'/comma,%2C,dot,.,semi,%3B'
|
614
|
-
],
|
615
|
-
'{/keys*}' => [
|
616
|
-
'/semi=%3B/dot=./comma=%2C',
|
617
|
-
'/dot=./semi=%3B/comma=%2C',
|
618
|
-
'/comma=%2C/semi=%3B/dot=.',
|
619
|
-
'/semi=%3B/comma=%2C/dot=.',
|
620
|
-
'/dot=./comma=%2C/semi=%3B',
|
621
|
-
'/comma=%2C/dot=./semi=%3B'
|
622
|
-
]
|
435
|
+
'{/keys}' => '/semi,%3B,dot,.,comma,%2C',
|
436
|
+
'{/keys*}' => '/semi=%3B/dot=./comma=%2C',
|
623
437
|
}
|
624
438
|
end
|
625
439
|
context "path-style expansion (;)" do
|
@@ -635,22 +449,8 @@ describe "Expansion" do
|
|
635
449
|
'{;hello:5}' => ';hello=Hello',
|
636
450
|
'{;list}' => ';list=red,green,blue',
|
637
451
|
'{;list*}' => ';list=red;list=green;list=blue',
|
638
|
-
'{;keys}' =>
|
639
|
-
|
640
|
-
';keys=dot,.,semi,%3B,comma,%2C',
|
641
|
-
';keys=comma,%2C,semi,%3B,dot,.',
|
642
|
-
';keys=semi,%3B,comma,%2C,dot,.',
|
643
|
-
';keys=dot,.,comma,%2C,semi,%3B',
|
644
|
-
';keys=comma,%2C,dot,.,semi,%3B'
|
645
|
-
],
|
646
|
-
'{;keys*}' => [
|
647
|
-
';semi=%3B;dot=.;comma=%2C',
|
648
|
-
';dot=.;semi=%3B;comma=%2C',
|
649
|
-
';comma=%2C;semi=%3B;dot=.',
|
650
|
-
';semi=%3B;comma=%2C;dot=.',
|
651
|
-
';dot=.;comma=%2C;semi=%3B',
|
652
|
-
';comma=%2C;dot=.;semi=%3B'
|
653
|
-
]
|
452
|
+
'{;keys}' => ';keys=semi,%3B,dot,.,comma,%2C',
|
453
|
+
'{;keys*}' => ';semi=%3B;dot=.;comma=%2C',
|
654
454
|
}
|
655
455
|
end
|
656
456
|
context "form query expansion (?)" do
|
@@ -663,22 +463,8 @@ describe "Expansion" do
|
|
663
463
|
'{?var:3}' => '?var=val',
|
664
464
|
'{?list}' => '?list=red,green,blue',
|
665
465
|
'{?list*}' => '?list=red&list=green&list=blue',
|
666
|
-
'{?keys}' =>
|
667
|
-
|
668
|
-
'?keys=dot,.,semi,%3B,comma,%2C',
|
669
|
-
'?keys=comma,%2C,semi,%3B,dot,.',
|
670
|
-
'?keys=semi,%3B,comma,%2C,dot,.',
|
671
|
-
'?keys=dot,.,comma,%2C,semi,%3B',
|
672
|
-
'?keys=comma,%2C,dot,.,semi,%3B'
|
673
|
-
],
|
674
|
-
'{?keys*}' => [
|
675
|
-
'?semi=%3B&dot=.&comma=%2C',
|
676
|
-
'?dot=.&semi=%3B&comma=%2C',
|
677
|
-
'?comma=%2C&semi=%3B&dot=.',
|
678
|
-
'?semi=%3B&comma=%2C&dot=.',
|
679
|
-
'?dot=.&comma=%2C&semi=%3B',
|
680
|
-
'?comma=%2C&dot=.&semi=%3B'
|
681
|
-
]
|
466
|
+
'{?keys}' => '?keys=semi,%3B,dot,.,comma,%2C',
|
467
|
+
'{?keys*}' => '?semi=%3B&dot=.&comma=%2C',
|
682
468
|
}
|
683
469
|
end
|
684
470
|
context "form query expansion (&)" do
|
@@ -691,22 +477,8 @@ describe "Expansion" do
|
|
691
477
|
'{&var:3}' => '&var=val',
|
692
478
|
'{&list}' => '&list=red,green,blue',
|
693
479
|
'{&list*}' => '&list=red&list=green&list=blue',
|
694
|
-
'{&keys}' =>
|
695
|
-
|
696
|
-
'&keys=dot,.,semi,%3B,comma,%2C',
|
697
|
-
'&keys=comma,%2C,semi,%3B,dot,.',
|
698
|
-
'&keys=semi,%3B,comma,%2C,dot,.',
|
699
|
-
'&keys=dot,.,comma,%2C,semi,%3B',
|
700
|
-
'&keys=comma,%2C,dot,.,semi,%3B'
|
701
|
-
],
|
702
|
-
'{&keys*}' => [
|
703
|
-
'&semi=%3B&dot=.&comma=%2C',
|
704
|
-
'&dot=.&semi=%3B&comma=%2C',
|
705
|
-
'&comma=%2C&semi=%3B&dot=.',
|
706
|
-
'&semi=%3B&comma=%2C&dot=.',
|
707
|
-
'&dot=.&comma=%2C&semi=%3B',
|
708
|
-
'&comma=%2C&dot=.&semi=%3B'
|
709
|
-
]
|
480
|
+
'{&keys}' => '&keys=semi,%3B,dot,.,comma,%2C',
|
481
|
+
'{&keys*}' => '&semi=%3B&dot=.&comma=%2C',
|
710
482
|
}
|
711
483
|
end
|
712
484
|
context "non-string key in match data" do
|
@@ -1021,6 +793,19 @@ describe Addressable::Template do
|
|
1021
793
|
)
|
1022
794
|
end
|
1023
795
|
|
796
|
+
it "normalizes as unicode even with wrong encoding specified" do
|
797
|
+
template = subject.partial_expand("query" => "Cafe\u0301".b)
|
798
|
+
expect(template.pattern).to eq(
|
799
|
+
"http://example.com/{resource}/Caf%C3%A9/"
|
800
|
+
)
|
801
|
+
end
|
802
|
+
|
803
|
+
it "raises on invalid unicode input" do
|
804
|
+
expect {
|
805
|
+
subject.partial_expand("query" => "M\xE9thode".b)
|
806
|
+
}.to raise_error(ArgumentError, "invalid byte sequence in UTF-8")
|
807
|
+
end
|
808
|
+
|
1024
809
|
it "does not normalize unicode when byte semantics requested" do
|
1025
810
|
template = subject.partial_expand({"query" => "Cafe\u0301"}, nil, false)
|
1026
811
|
expect(template.pattern).to eq(
|
@@ -1081,6 +866,17 @@ describe Addressable::Template do
|
|
1081
866
|
expect(uri).to eq("http://example.com/search/Caf%C3%A9/")
|
1082
867
|
end
|
1083
868
|
|
869
|
+
it "normalizes as unicode even with wrong encoding specified" do
|
870
|
+
uri = subject.expand("query" => "Cafe\u0301".b).to_str
|
871
|
+
expect(uri).to eq("http://example.com/search/Caf%C3%A9/")
|
872
|
+
end
|
873
|
+
|
874
|
+
it "raises on invalid unicode input" do
|
875
|
+
expect {
|
876
|
+
subject.expand("query" => "M\xE9thode".b).to_str
|
877
|
+
}.to raise_error(ArgumentError, "invalid byte sequence in UTF-8")
|
878
|
+
end
|
879
|
+
|
1084
880
|
it "does not normalize unicode when byte semantics requested" do
|
1085
881
|
uri = subject.expand({ "query" => "Cafe\u0301" }, nil, false).to_str
|
1086
882
|
expect(uri).to eq("http://example.com/search/Cafe%CC%81/")
|
@@ -20,6 +20,7 @@ require "spec_helper"
|
|
20
20
|
require "addressable/uri"
|
21
21
|
require "uri"
|
22
22
|
require "ipaddr"
|
23
|
+
require "yaml"
|
23
24
|
|
24
25
|
if !"".respond_to?("force_encoding")
|
25
26
|
class String
|
@@ -3021,6 +3022,20 @@ describe Addressable::URI, "when parsed from " +
|
|
3021
3022
|
end
|
3022
3023
|
end
|
3023
3024
|
|
3025
|
+
describe Addressable::URI, "when parsed with empty port" do
|
3026
|
+
subject(:uri) do
|
3027
|
+
Addressable::URI.parse("//example.com:")
|
3028
|
+
end
|
3029
|
+
|
3030
|
+
it "should not infer a port" do
|
3031
|
+
expect(uri.port).to be(nil)
|
3032
|
+
end
|
3033
|
+
|
3034
|
+
it "should have a site value of '//example.com'" do
|
3035
|
+
expect(uri.site).to eq("//example.com")
|
3036
|
+
end
|
3037
|
+
end
|
3038
|
+
|
3024
3039
|
describe Addressable::URI, "when parsed from " +
|
3025
3040
|
"'http://example.com/%2E/'" do
|
3026
3041
|
before do
|
@@ -5939,6 +5954,26 @@ describe Addressable::URI, "when normalizing a path with an encoded slash" do
|
|
5939
5954
|
end
|
5940
5955
|
end
|
5941
5956
|
|
5957
|
+
describe Addressable::URI, "when normalizing a path with special unicode" do
|
5958
|
+
it "does not stop at or ignore null bytes" do
|
5959
|
+
expect(Addressable::URI.parse("/path%00segment/").normalize.path).to eq(
|
5960
|
+
"/path%00segment/"
|
5961
|
+
)
|
5962
|
+
end
|
5963
|
+
|
5964
|
+
it "does apply NFC unicode normalization" do
|
5965
|
+
expect(Addressable::URI.parse("/%E2%84%A6").normalize.path).to eq(
|
5966
|
+
"/%CE%A9"
|
5967
|
+
)
|
5968
|
+
end
|
5969
|
+
|
5970
|
+
it "does not apply NFKC unicode normalization" do
|
5971
|
+
expect(Addressable::URI.parse("/%C2%AF%C2%A0").normalize.path).to eq(
|
5972
|
+
"/%C2%AF%C2%A0"
|
5973
|
+
)
|
5974
|
+
end
|
5975
|
+
end
|
5976
|
+
|
5942
5977
|
describe Addressable::URI, "when normalizing a partially encoded string" do
|
5943
5978
|
it "should result in correct percent encoded sequence" do
|
5944
5979
|
expect(Addressable::URI.normalize_component(
|
@@ -6734,6 +6769,37 @@ describe Addressable::URI, "when initializing a subclass of Addressable::URI" do
|
|
6734
6769
|
end
|
6735
6770
|
end
|
6736
6771
|
|
6772
|
+
describe Addressable::URI, "support serialization roundtrip" do
|
6773
|
+
before do
|
6774
|
+
@uri = Addressable::URI.new(
|
6775
|
+
:scheme => "http",
|
6776
|
+
:user => "user",
|
6777
|
+
:password => "password",
|
6778
|
+
:host => "example.com",
|
6779
|
+
:port => 80,
|
6780
|
+
:path => "/path",
|
6781
|
+
:query => "query=value",
|
6782
|
+
:fragment => "fragment"
|
6783
|
+
)
|
6784
|
+
end
|
6785
|
+
|
6786
|
+
it "is in a working state after being serialized with Marshal" do
|
6787
|
+
@uri = Addressable::URI.parse("http://example.com")
|
6788
|
+
cloned_uri = Marshal.load(Marshal.dump(@uri))
|
6789
|
+
expect(cloned_uri.normalized_scheme).to be == @uri.normalized_scheme
|
6790
|
+
end
|
6791
|
+
|
6792
|
+
it "is in a working state after being serialized with YAML" do
|
6793
|
+
@uri = Addressable::URI.parse("http://example.com")
|
6794
|
+
cloned_uri = if YAML.respond_to?(:unsafe_load)
|
6795
|
+
YAML.unsafe_load(YAML.dump(@uri))
|
6796
|
+
else
|
6797
|
+
YAML.load(YAML.dump(@uri))
|
6798
|
+
end
|
6799
|
+
expect(cloned_uri.normalized_scheme).to be == @uri.normalized_scheme
|
6800
|
+
end
|
6801
|
+
end
|
6802
|
+
|
6737
6803
|
describe Addressable::URI, "when initialized in a non-main `Ractor`" do
|
6738
6804
|
it "should have the same value as if used in the main `Ractor`" do
|
6739
6805
|
pending("Ruby 3.0+ for `Ractor` support") unless defined?(Ractor)
|
@@ -6743,3 +6809,32 @@ describe Addressable::URI, "when initialized in a non-main `Ractor`" do
|
|
6743
6809
|
).to eq(main)
|
6744
6810
|
end
|
6745
6811
|
end
|
6812
|
+
|
6813
|
+
describe Addressable::URI, "when deferring validation" do
|
6814
|
+
subject(:deferred) { uri.instance_variable_get(:@validation_deferred) }
|
6815
|
+
|
6816
|
+
let(:uri) { Addressable::URI.parse("http://example.com") }
|
6817
|
+
|
6818
|
+
it "defers validation within the block" do
|
6819
|
+
uri.defer_validation do
|
6820
|
+
expect(deferred).to be true
|
6821
|
+
end
|
6822
|
+
end
|
6823
|
+
|
6824
|
+
it "always resets deferral afterward" do
|
6825
|
+
expect { uri.defer_validation { raise "boom" } }.to raise_error("boom")
|
6826
|
+
expect(deferred).to be false
|
6827
|
+
end
|
6828
|
+
|
6829
|
+
it "returns nil" do
|
6830
|
+
res = uri.defer_validation {}
|
6831
|
+
expect(res).to be nil
|
6832
|
+
end
|
6833
|
+
end
|
6834
|
+
|
6835
|
+
describe Addressable::URI, "YAML safe loading" do
|
6836
|
+
it "doesn't serialize anonymous objects" do
|
6837
|
+
url = Addressable::URI.parse("http://example.com/")
|
6838
|
+
expect(YAML.dump(url)).to_not include("!ruby/object {}")
|
6839
|
+
end
|
6840
|
+
end
|
data/tasks/gem.rake
CHANGED
@@ -31,7 +31,7 @@ namespace :gem do
|
|
31
31
|
s.homepage = "https://github.com/sporkmonger/addressable"
|
32
32
|
s.license = "Apache-2.0"
|
33
33
|
s.metadata = {
|
34
|
-
"changelog_uri" => "https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md"
|
34
|
+
"changelog_uri" => "https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md#v#{PKG_VERSION}"
|
35
35
|
}
|
36
36
|
end
|
37
37
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: addressable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.8.
|
4
|
+
version: 2.8.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bob Aman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: public_suffix
|
@@ -65,6 +65,7 @@ files:
|
|
65
65
|
- LICENSE.txt
|
66
66
|
- README.md
|
67
67
|
- Rakefile
|
68
|
+
- addressable.gemspec
|
68
69
|
- data/unicode.data
|
69
70
|
- lib/addressable.rb
|
70
71
|
- lib/addressable/idna.rb
|
@@ -90,7 +91,7 @@ homepage: https://github.com/sporkmonger/addressable
|
|
90
91
|
licenses:
|
91
92
|
- Apache-2.0
|
92
93
|
metadata:
|
93
|
-
changelog_uri: https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md
|
94
|
+
changelog_uri: https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md#v2.8.6
|
94
95
|
post_install_message:
|
95
96
|
rdoc_options:
|
96
97
|
- "--main"
|
@@ -108,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
109
|
- !ruby/object:Gem::Version
|
109
110
|
version: '0'
|
110
111
|
requirements: []
|
111
|
-
rubygems_version: 3.
|
112
|
+
rubygems_version: 3.4.22
|
112
113
|
signing_key:
|
113
114
|
specification_version: 4
|
114
115
|
summary: URI Implementation
|