addressable 2.8.0 → 2.8.7

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.
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # encoding:utf-8
4
3
  #--
5
4
  # Copyright (C) Bob Aman
6
5
  #
@@ -24,7 +23,7 @@ if !defined?(Addressable::VERSION)
24
23
  module VERSION
25
24
  MAJOR = 2
26
25
  MINOR = 8
27
- TINY = 0
26
+ TINY = 7
28
27
 
29
28
  STRING = [MAJOR, MINOR, TINY].join('.')
30
29
  end
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # coding: utf-8
4
3
  # Copyright (C) Bob Aman
5
4
  #
6
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -39,6 +38,12 @@ shared_examples_for "converting from unicode to ASCII" do
39
38
  )).to eq("www.xn--8ws00zhy3a.com")
40
39
  end
41
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
+
42
47
  it "should convert 'www.Iñtërnâtiônàlizætiøn.com' correctly" do
43
48
  "www.Iñtërnâtiônàlizætiøn.com"
44
49
  expect(Addressable::IDNA.to_ascii(
@@ -250,11 +255,6 @@ shared_examples_for "converting from ASCII to unicode" do
250
255
  "example..host"
251
256
  )).to eq("example..host")
252
257
  end
253
-
254
- it "should normalize 'string' correctly" do
255
- expect(Addressable::IDNA.unicode_normalize_kc(:'string')).to eq("string")
256
- expect(Addressable::IDNA.unicode_normalize_kc("string")).to eq("string")
257
- end
258
258
  end
259
259
 
260
260
  describe Addressable::IDNA, "when using the pure-Ruby implementation" do
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # coding: utf-8
4
3
  # Copyright (C) Bob Aman
5
4
  #
6
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # coding: utf-8
4
3
  # Copyright (C) Bob Aman
5
4
  #
6
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # coding: utf-8
4
3
  # Copyright (C) Bob Aman
5
4
  #
6
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -27,11 +26,7 @@ shared_examples_for 'expands' do |tests|
27
26
  exp = expansion.is_a?(Array) ? expansion.first : expansion
28
27
  it "#{template} to #{exp}" do
29
28
  tmpl = Addressable::Template.new(template).expand(subject)
30
- if expansion.is_a?(Array)
31
- expect(expansion.any?{|i| i == tmpl.to_str}).to be true
32
- else
33
- expect(tmpl.to_str).to eq(expansion)
34
- end
29
+ expect(tmpl.to_str).to eq(expansion)
35
30
  end
36
31
  end
37
32
  end
@@ -78,6 +73,15 @@ describe "==" do
78
73
  end
79
74
  end
80
75
 
76
+ describe "#to_regexp" do
77
+ it "does not match the first line of multiline strings" do
78
+ uri = "https://www.example.com/bar"
79
+ template = Addressable::Template.new(uri)
80
+ expect(template.match(uri)).not_to be_nil
81
+ expect(template.match("#{uri}\ngarbage")).to be_nil
82
+ end
83
+ end
84
+
81
85
  describe "Type conversion" do
82
86
  subject {
83
87
  {
@@ -201,7 +205,7 @@ describe "Level 4" do
201
205
  :path => "/foo/bar",
202
206
  :semi => ";",
203
207
  :list => %w(red green blue),
204
- :keys => {"semi" => ';', "dot" => '.', "comma" => ','}
208
+ :keys => {"semi" => ';', "dot" => '.', :comma => ','}
205
209
  }
206
210
  }
207
211
  context "Expansion with value modifiers" do
@@ -210,22 +214,8 @@ describe "Level 4" do
210
214
  '{var:30}' => 'value',
211
215
  '{list}' => 'red,green,blue',
212
216
  '{list*}' => 'red,green,blue',
213
- '{keys}' => [
214
- 'semi,%3B,dot,.,comma,%2C',
215
- 'dot,.,semi,%3B,comma,%2C',
216
- 'comma,%2C,semi,%3B,dot,.',
217
- 'semi,%3B,comma,%2C,dot,.',
218
- 'dot,.,comma,%2C,semi,%3B',
219
- 'comma,%2C,dot,.,semi,%3B'
220
- ],
221
- '{keys*}' => [
222
- 'semi=%3B,dot=.,comma=%2C',
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
- ]
217
+ '{keys}' => 'semi,%3B,dot,.,comma,%2C',
218
+ '{keys*}' => 'semi=%3B,dot=.,comma=%2C',
229
219
  }
230
220
  end
231
221
  context "Operator + with value modifiers" do
@@ -233,22 +223,8 @@ describe "Level 4" do
233
223
  '{+path:6}/here' => '/foo/b/here',
234
224
  '{+list}' => 'red,green,blue',
235
225
  '{+list*}' => 'red,green,blue',
236
- '{+keys}' => [
237
- 'semi,;,dot,.,comma,,',
238
- 'dot,.,semi,;,comma,,',
239
- 'comma,,,semi,;,dot,.',
240
- 'semi,;,comma,,,dot,.',
241
- 'dot,.,comma,,,semi,;',
242
- 'comma,,,dot,.,semi,;'
243
- ],
244
- '{+keys*}' => [
245
- 'semi=;,dot=.,comma=,',
246
- 'dot=.,semi=;,comma=,',
247
- 'comma=,,semi=;,dot=.',
248
- 'semi=;,comma=,,dot=.',
249
- 'dot=.,comma=,,semi=;',
250
- 'comma=,,dot=.,semi=;'
251
- ]
226
+ '{+keys}' => 'semi,;,dot,.,comma,,',
227
+ '{+keys*}' => 'semi=;,dot=.,comma=,',
252
228
  }
253
229
  end
254
230
  context "Operator # with value modifiers" do
@@ -256,22 +232,8 @@ describe "Level 4" do
256
232
  '{#path:6}/here' => '#/foo/b/here',
257
233
  '{#list}' => '#red,green,blue',
258
234
  '{#list*}' => '#red,green,blue',
259
- '{#keys}' => [
260
- '#semi,;,dot,.,comma,,',
261
- '#dot,.,semi,;,comma,,',
262
- '#comma,,,semi,;,dot,.',
263
- '#semi,;,comma,,,dot,.',
264
- '#dot,.,comma,,,semi,;',
265
- '#comma,,,dot,.,semi,;'
266
- ],
267
- '{#keys*}' => [
268
- '#semi=;,dot=.,comma=,',
269
- '#dot=.,semi=;,comma=,',
270
- '#comma=,,semi=;,dot=.',
271
- '#semi=;,comma=,,dot=.',
272
- '#dot=.,comma=,,semi=;',
273
- '#comma=,,dot=.,semi=;'
274
- ]
235
+ '{#keys}' => '#semi,;,dot,.,comma,,',
236
+ '{#keys*}' => '#semi=;,dot=.,comma=,',
275
237
  }
276
238
  end
277
239
  context "Operator . with value modifiers" do
@@ -279,22 +241,8 @@ describe "Level 4" do
279
241
  'X{.var:3}' => 'X.val',
280
242
  'X{.list}' => 'X.red,green,blue',
281
243
  'X{.list*}' => 'X.red.green.blue',
282
- 'X{.keys}' => [
283
- 'X.semi,%3B,dot,.,comma,%2C',
284
- 'X.dot,.,semi,%3B,comma,%2C',
285
- 'X.comma,%2C,semi,%3B,dot,.',
286
- 'X.semi,%3B,comma,%2C,dot,.',
287
- 'X.dot,.,comma,%2C,semi,%3B',
288
- 'X.comma,%2C,dot,.,semi,%3B'
289
- ],
290
- 'X{.keys*}' => [
291
- 'X.semi=%3B.dot=..comma=%2C',
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
- ]
244
+ 'X{.keys}' => 'X.semi,%3B,dot,.,comma,%2C',
245
+ 'X{.keys*}' => 'X.semi=%3B.dot=..comma=%2C',
298
246
  }
299
247
  end
300
248
  context "Operator / with value modifiers" do
@@ -303,22 +251,8 @@ describe "Level 4" do
303
251
  '{/list}' => '/red,green,blue',
304
252
  '{/list*}' => '/red/green/blue',
305
253
  '{/list*,path:4}' => '/red/green/blue/%2Ffoo',
306
- '{/keys}' => [
307
- '/semi,%3B,dot,.,comma,%2C',
308
- '/dot,.,semi,%3B,comma,%2C',
309
- '/comma,%2C,semi,%3B,dot,.',
310
- '/semi,%3B,comma,%2C,dot,.',
311
- '/dot,.,comma,%2C,semi,%3B',
312
- '/comma,%2C,dot,.,semi,%3B'
313
- ],
314
- '{/keys*}' => [
315
- '/semi=%3B/dot=./comma=%2C',
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
- ]
254
+ '{/keys}' => '/semi,%3B,dot,.,comma,%2C',
255
+ '{/keys*}' => '/semi=%3B/dot=./comma=%2C',
322
256
  }
323
257
  end
324
258
  context "Operator ; with value modifiers" do
@@ -326,22 +260,8 @@ describe "Level 4" do
326
260
  '{;hello:5}' => ';hello=Hello',
327
261
  '{;list}' => ';list=red,green,blue',
328
262
  '{;list*}' => ';list=red;list=green;list=blue',
329
- '{;keys}' => [
330
- ';keys=semi,%3B,dot,.,comma,%2C',
331
- ';keys=dot,.,semi,%3B,comma,%2C',
332
- ';keys=comma,%2C,semi,%3B,dot,.',
333
- ';keys=semi,%3B,comma,%2C,dot,.',
334
- ';keys=dot,.,comma,%2C,semi,%3B',
335
- ';keys=comma,%2C,dot,.,semi,%3B'
336
- ],
337
- '{;keys*}' => [
338
- ';semi=%3B;dot=.;comma=%2C',
339
- ';dot=.;semi=%3B;comma=%2C',
340
- ';comma=%2C;semi=%3B;dot=.',
341
- ';semi=%3B;comma=%2C;dot=.',
342
- ';dot=.;comma=%2C;semi=%3B',
343
- ';comma=%2C;dot=.;semi=%3B'
344
- ]
263
+ '{;keys}' => ';keys=semi,%3B,dot,.,comma,%2C',
264
+ '{;keys*}' => ';semi=%3B;dot=.;comma=%2C',
345
265
  }
346
266
  end
347
267
  context "Operator ? with value modifiers" do
@@ -349,22 +269,8 @@ describe "Level 4" do
349
269
  '{?var:3}' => '?var=val',
350
270
  '{?list}' => '?list=red,green,blue',
351
271
  '{?list*}' => '?list=red&list=green&list=blue',
352
- '{?keys}' => [
353
- '?keys=semi,%3B,dot,.,comma,%2C',
354
- '?keys=dot,.,semi,%3B,comma,%2C',
355
- '?keys=comma,%2C,semi,%3B,dot,.',
356
- '?keys=semi,%3B,comma,%2C,dot,.',
357
- '?keys=dot,.,comma,%2C,semi,%3B',
358
- '?keys=comma,%2C,dot,.,semi,%3B'
359
- ],
360
- '{?keys*}' => [
361
- '?semi=%3B&dot=.&comma=%2C',
362
- '?dot=.&semi=%3B&comma=%2C',
363
- '?comma=%2C&semi=%3B&dot=.',
364
- '?semi=%3B&comma=%2C&dot=.',
365
- '?dot=.&comma=%2C&semi=%3B',
366
- '?comma=%2C&dot=.&semi=%3B'
367
- ]
272
+ '{?keys}' => '?keys=semi,%3B,dot,.,comma,%2C',
273
+ '{?keys*}' => '?semi=%3B&dot=.&comma=%2C',
368
274
  }
369
275
  end
370
276
  context "Operator & with value modifiers" do
@@ -372,22 +278,8 @@ describe "Level 4" do
372
278
  '{&var:3}' => '&var=val',
373
279
  '{&list}' => '&list=red,green,blue',
374
280
  '{&list*}' => '&list=red&list=green&list=blue',
375
- '{&keys}' => [
376
- '&keys=semi,%3B,dot,.,comma,%2C',
377
- '&keys=dot,.,semi,%3B,comma,%2C',
378
- '&keys=comma,%2C,semi,%3B,dot,.',
379
- '&keys=semi,%3B,comma,%2C,dot,.',
380
- '&keys=dot,.,comma,%2C,semi,%3B',
381
- '&keys=comma,%2C,dot,.,semi,%3B'
382
- ],
383
- '{&keys*}' => [
384
- '&semi=%3B&dot=.&comma=%2C',
385
- '&dot=.&semi=%3B&comma=%2C',
386
- '&comma=%2C&semi=%3B&dot=.',
387
- '&semi=%3B&comma=%2C&dot=.',
388
- '&dot=.&comma=%2C&semi=%3B',
389
- '&comma=%2C&dot=.&semi=%3B'
390
- ]
281
+ '{&keys}' => '&keys=semi,%3B,dot,.,comma,%2C',
282
+ '{&keys*}' => '&semi=%3B&dot=.&comma=%2C',
391
283
  }
392
284
  end
393
285
  end
@@ -396,7 +288,7 @@ describe "Modifiers" do
396
288
  {
397
289
  :var => "value",
398
290
  :semi => ";",
399
- :year => %w(1965 2000 2012),
291
+ :year => [1965, 2000, 2012],
400
292
  :dom => %w(example com)
401
293
  }
402
294
  }
@@ -429,7 +321,7 @@ describe "Expansion" do
429
321
  :base => "http://example.com/home/",
430
322
  :path => "/foo/bar",
431
323
  :list => ["red", "green", "blue"],
432
- :keys => {"semi" => ";","dot" => ".","comma" => ","},
324
+ :keys => {"semi" => ";","dot" => ".",:comma => ","},
433
325
  :v => "6",
434
326
  :x => "1024",
435
327
  :y => "768",
@@ -467,22 +359,8 @@ describe "Expansion" do
467
359
  '{var:30}' => 'value',
468
360
  '{list}' => 'red,green,blue',
469
361
  '{list*}' => 'red,green,blue',
470
- '{keys}' => [
471
- 'semi,%3B,dot,.,comma,%2C',
472
- 'dot,.,semi,%3B,comma,%2C',
473
- 'comma,%2C,semi,%3B,dot,.',
474
- 'semi,%3B,comma,%2C,dot,.',
475
- 'dot,.,comma,%2C,semi,%3B',
476
- 'comma,%2C,dot,.,semi,%3B'
477
- ],
478
- '{keys*}' => [
479
- 'semi=%3B,dot=.,comma=%2C',
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
- ]
362
+ '{keys}' => 'semi,%3B,dot,.,comma,%2C',
363
+ '{keys*}' => 'semi=%3B,dot=.,comma=%2C',
486
364
  }
487
365
  end
488
366
  context "reserved expansion (+)" do
@@ -502,22 +380,8 @@ describe "Expansion" do
502
380
  '{+path:6}/here' => '/foo/b/here',
503
381
  '{+list}' => 'red,green,blue',
504
382
  '{+list*}' => 'red,green,blue',
505
- '{+keys}' => [
506
- 'semi,;,dot,.,comma,,',
507
- 'dot,.,semi,;,comma,,',
508
- 'comma,,,semi,;,dot,.',
509
- 'semi,;,comma,,,dot,.',
510
- 'dot,.,comma,,,semi,;',
511
- 'comma,,,dot,.,semi,;'
512
- ],
513
- '{+keys*}' => [
514
- 'semi=;,dot=.,comma=,',
515
- 'dot=.,semi=;,comma=,',
516
- 'comma=,,semi=;,dot=.',
517
- 'semi=;,comma=,,dot=.',
518
- 'dot=.,comma=,,semi=;',
519
- 'comma=,,dot=.,semi=;'
520
- ]
383
+ '{+keys}' => 'semi,;,dot,.,comma,,',
384
+ '{+keys*}' => 'semi=;,dot=.,comma=,',
521
385
  }
522
386
  end
523
387
  context "fragment expansion (#)" do
@@ -532,22 +396,8 @@ describe "Expansion" do
532
396
  '{#path:6}/here' => '#/foo/b/here',
533
397
  '{#list}' => '#red,green,blue',
534
398
  '{#list*}' => '#red,green,blue',
535
- '{#keys}' => [
536
- '#semi,;,dot,.,comma,,',
537
- '#dot,.,semi,;,comma,,',
538
- '#comma,,,semi,;,dot,.',
539
- '#semi,;,comma,,,dot,.',
540
- '#dot,.,comma,,,semi,;',
541
- '#comma,,,dot,.,semi,;'
542
- ],
543
- '{#keys*}' => [
544
- '#semi=;,dot=.,comma=,',
545
- '#dot=.,semi=;,comma=,',
546
- '#comma=,,semi=;,dot=.',
547
- '#semi=;,comma=,,dot=.',
548
- '#dot=.,comma=,,semi=;',
549
- '#comma=,,dot=.,semi=;'
550
- ]
399
+ '{#keys}' => '#semi,;,dot,.,comma,,',
400
+ '{#keys*}' => '#semi=;,dot=.,comma=,',
551
401
  }
552
402
  end
553
403
  context "label expansion (.)" do
@@ -562,22 +412,8 @@ describe "Expansion" do
562
412
  'X{.var:3}' => 'X.val',
563
413
  'X{.list}' => 'X.red,green,blue',
564
414
  'X{.list*}' => 'X.red.green.blue',
565
- 'X{.keys}' => [
566
- 'X.semi,%3B,dot,.,comma,%2C',
567
- 'X.dot,.,semi,%3B,comma,%2C',
568
- 'X.comma,%2C,semi,%3B,dot,.',
569
- 'X.semi,%3B,comma,%2C,dot,.',
570
- 'X.dot,.,comma,%2C,semi,%3B',
571
- 'X.comma,%2C,dot,.,semi,%3B'
572
- ],
573
- 'X{.keys*}' => [
574
- 'X.semi=%3B.dot=..comma=%2C',
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
- ],
415
+ 'X{.keys}' => 'X.semi,%3B,dot,.,comma,%2C',
416
+ 'X{.keys*}' => 'X.semi=%3B.dot=..comma=%2C',
581
417
  'X{.empty_keys}' => 'X',
582
418
  'X{.empty_keys*}' => 'X'
583
419
  }
@@ -596,22 +432,8 @@ describe "Expansion" do
596
432
  '{/list}' => '/red,green,blue',
597
433
  '{/list*}' => '/red/green/blue',
598
434
  '{/list*,path:4}' => '/red/green/blue/%2Ffoo',
599
- '{/keys}' => [
600
- '/semi,%3B,dot,.,comma,%2C',
601
- '/dot,.,semi,%3B,comma,%2C',
602
- '/comma,%2C,semi,%3B,dot,.',
603
- '/semi,%3B,comma,%2C,dot,.',
604
- '/dot,.,comma,%2C,semi,%3B',
605
- '/comma,%2C,dot,.,semi,%3B'
606
- ],
607
- '{/keys*}' => [
608
- '/semi=%3B/dot=./comma=%2C',
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
- ]
435
+ '{/keys}' => '/semi,%3B,dot,.,comma,%2C',
436
+ '{/keys*}' => '/semi=%3B/dot=./comma=%2C',
615
437
  }
616
438
  end
617
439
  context "path-style expansion (;)" do
@@ -627,22 +449,8 @@ describe "Expansion" do
627
449
  '{;hello:5}' => ';hello=Hello',
628
450
  '{;list}' => ';list=red,green,blue',
629
451
  '{;list*}' => ';list=red;list=green;list=blue',
630
- '{;keys}' => [
631
- ';keys=semi,%3B,dot,.,comma,%2C',
632
- ';keys=dot,.,semi,%3B,comma,%2C',
633
- ';keys=comma,%2C,semi,%3B,dot,.',
634
- ';keys=semi,%3B,comma,%2C,dot,.',
635
- ';keys=dot,.,comma,%2C,semi,%3B',
636
- ';keys=comma,%2C,dot,.,semi,%3B'
637
- ],
638
- '{;keys*}' => [
639
- ';semi=%3B;dot=.;comma=%2C',
640
- ';dot=.;semi=%3B;comma=%2C',
641
- ';comma=%2C;semi=%3B;dot=.',
642
- ';semi=%3B;comma=%2C;dot=.',
643
- ';dot=.;comma=%2C;semi=%3B',
644
- ';comma=%2C;dot=.;semi=%3B'
645
- ]
452
+ '{;keys}' => ';keys=semi,%3B,dot,.,comma,%2C',
453
+ '{;keys*}' => ';semi=%3B;dot=.;comma=%2C',
646
454
  }
647
455
  end
648
456
  context "form query expansion (?)" do
@@ -655,22 +463,8 @@ describe "Expansion" do
655
463
  '{?var:3}' => '?var=val',
656
464
  '{?list}' => '?list=red,green,blue',
657
465
  '{?list*}' => '?list=red&list=green&list=blue',
658
- '{?keys}' => [
659
- '?keys=semi,%3B,dot,.,comma,%2C',
660
- '?keys=dot,.,semi,%3B,comma,%2C',
661
- '?keys=comma,%2C,semi,%3B,dot,.',
662
- '?keys=semi,%3B,comma,%2C,dot,.',
663
- '?keys=dot,.,comma,%2C,semi,%3B',
664
- '?keys=comma,%2C,dot,.,semi,%3B'
665
- ],
666
- '{?keys*}' => [
667
- '?semi=%3B&dot=.&comma=%2C',
668
- '?dot=.&semi=%3B&comma=%2C',
669
- '?comma=%2C&semi=%3B&dot=.',
670
- '?semi=%3B&comma=%2C&dot=.',
671
- '?dot=.&comma=%2C&semi=%3B',
672
- '?comma=%2C&dot=.&semi=%3B'
673
- ]
466
+ '{?keys}' => '?keys=semi,%3B,dot,.,comma,%2C',
467
+ '{?keys*}' => '?semi=%3B&dot=.&comma=%2C',
674
468
  }
675
469
  end
676
470
  context "form query expansion (&)" do
@@ -683,22 +477,8 @@ describe "Expansion" do
683
477
  '{&var:3}' => '&var=val',
684
478
  '{&list}' => '&list=red,green,blue',
685
479
  '{&list*}' => '&list=red&list=green&list=blue',
686
- '{&keys}' => [
687
- '&keys=semi,%3B,dot,.,comma,%2C',
688
- '&keys=dot,.,semi,%3B,comma,%2C',
689
- '&keys=comma,%2C,semi,%3B,dot,.',
690
- '&keys=semi,%3B,comma,%2C,dot,.',
691
- '&keys=dot,.,comma,%2C,semi,%3B',
692
- '&keys=comma,%2C,dot,.,semi,%3B'
693
- ],
694
- '{&keys*}' => [
695
- '&semi=%3B&dot=.&comma=%2C',
696
- '&dot=.&semi=%3B&comma=%2C',
697
- '&comma=%2C&semi=%3B&dot=.',
698
- '&semi=%3B&comma=%2C&dot=.',
699
- '&dot=.&comma=%2C&semi=%3B',
700
- '&comma=%2C&dot=.&semi=%3B'
701
- ]
480
+ '{&keys}' => '&keys=semi,%3B,dot,.,comma,%2C',
481
+ '{&keys*}' => '&semi=%3B&dot=.&comma=%2C',
702
482
  }
703
483
  end
704
484
  context "non-string key in match data" do
@@ -1013,6 +793,19 @@ describe Addressable::Template do
1013
793
  )
1014
794
  end
1015
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
+
1016
809
  it "does not normalize unicode when byte semantics requested" do
1017
810
  template = subject.partial_expand({"query" => "Cafe\u0301"}, nil, false)
1018
811
  expect(template.pattern).to eq(
@@ -1073,6 +866,17 @@ describe Addressable::Template do
1073
866
  expect(uri).to eq("http://example.com/search/Caf%C3%A9/")
1074
867
  end
1075
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
+
1076
880
  it "does not normalize unicode when byte semantics requested" do
1077
881
  uri = subject.expand({ "query" => "Cafe\u0301" }, nil, false).to_str
1078
882
  expect(uri).to eq("http://example.com/search/Cafe%CC%81/")