addressable 2.6.0 → 2.8.5

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
  #
@@ -23,8 +22,8 @@ if !defined?(Addressable::VERSION)
23
22
  module Addressable
24
23
  module VERSION
25
24
  MAJOR = 2
26
- MINOR = 6
27
- TINY = 0
25
+ MINOR = 8
26
+ TINY = 5
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
@@ -294,7 +294,9 @@ begin
294
294
  it_should_behave_like "converting from unicode to ASCII"
295
295
  it_should_behave_like "converting from ASCII to unicode"
296
296
  end
297
- rescue LoadError
297
+ rescue LoadError => error
298
+ raise error if ENV["CI"] && TestHelper.native_supported?
299
+
298
300
  # Cannot test the native implementation without libidn support.
299
301
  warn('Could not load native IDN implementation.')
300
302
  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");
@@ -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");
@@ -19,6 +18,7 @@
19
18
  require "spec_helper"
20
19
 
21
20
  require "bigdecimal"
21
+ require "timeout"
22
22
  require "addressable/template"
23
23
 
24
24
  shared_examples_for 'expands' do |tests|
@@ -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
- if expansion.is_a?(Array)
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
@@ -77,6 +73,15 @@ describe "==" do
77
73
  end
78
74
  end
79
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
+
80
85
  describe "Type conversion" do
81
86
  subject {
82
87
  {
@@ -200,7 +205,7 @@ describe "Level 4" do
200
205
  :path => "/foo/bar",
201
206
  :semi => ";",
202
207
  :list => %w(red green blue),
203
- :keys => {"semi" => ';', "dot" => '.', "comma" => ','}
208
+ :keys => {"semi" => ';', "dot" => '.', :comma => ','}
204
209
  }
205
210
  }
206
211
  context "Expansion with value modifiers" do
@@ -209,22 +214,8 @@ describe "Level 4" do
209
214
  '{var:30}' => 'value',
210
215
  '{list}' => 'red,green,blue',
211
216
  '{list*}' => 'red,green,blue',
212
- '{keys}' => [
213
- 'semi,%3B,dot,.,comma,%2C',
214
- 'dot,.,semi,%3B,comma,%2C',
215
- 'comma,%2C,semi,%3B,dot,.',
216
- 'semi,%3B,comma,%2C,dot,.',
217
- 'dot,.,comma,%2C,semi,%3B',
218
- 'comma,%2C,dot,.,semi,%3B'
219
- ],
220
- '{keys*}' => [
221
- 'semi=%3B,dot=.,comma=%2C',
222
- 'dot=.,semi=%3B,comma=%2C',
223
- 'comma=%2C,semi=%3B,dot=.',
224
- 'semi=%3B,comma=%2C,dot=.',
225
- 'dot=.,comma=%2C,semi=%3B',
226
- 'comma=%2C,dot=.,semi=%3B'
227
- ]
217
+ '{keys}' => 'semi,%3B,dot,.,comma,%2C',
218
+ '{keys*}' => 'semi=%3B,dot=.,comma=%2C',
228
219
  }
229
220
  end
230
221
  context "Operator + with value modifiers" do
@@ -232,22 +223,8 @@ describe "Level 4" do
232
223
  '{+path:6}/here' => '/foo/b/here',
233
224
  '{+list}' => 'red,green,blue',
234
225
  '{+list*}' => 'red,green,blue',
235
- '{+keys}' => [
236
- 'semi,;,dot,.,comma,,',
237
- 'dot,.,semi,;,comma,,',
238
- 'comma,,,semi,;,dot,.',
239
- 'semi,;,comma,,,dot,.',
240
- 'dot,.,comma,,,semi,;',
241
- 'comma,,,dot,.,semi,;'
242
- ],
243
- '{+keys*}' => [
244
- 'semi=;,dot=.,comma=,',
245
- 'dot=.,semi=;,comma=,',
246
- 'comma=,,semi=;,dot=.',
247
- 'semi=;,comma=,,dot=.',
248
- 'dot=.,comma=,,semi=;',
249
- 'comma=,,dot=.,semi=;'
250
- ]
226
+ '{+keys}' => 'semi,;,dot,.,comma,,',
227
+ '{+keys*}' => 'semi=;,dot=.,comma=,',
251
228
  }
252
229
  end
253
230
  context "Operator # with value modifiers" do
@@ -255,22 +232,8 @@ describe "Level 4" do
255
232
  '{#path:6}/here' => '#/foo/b/here',
256
233
  '{#list}' => '#red,green,blue',
257
234
  '{#list*}' => '#red,green,blue',
258
- '{#keys}' => [
259
- '#semi,;,dot,.,comma,,',
260
- '#dot,.,semi,;,comma,,',
261
- '#comma,,,semi,;,dot,.',
262
- '#semi,;,comma,,,dot,.',
263
- '#dot,.,comma,,,semi,;',
264
- '#comma,,,dot,.,semi,;'
265
- ],
266
- '{#keys*}' => [
267
- '#semi=;,dot=.,comma=,',
268
- '#dot=.,semi=;,comma=,',
269
- '#comma=,,semi=;,dot=.',
270
- '#semi=;,comma=,,dot=.',
271
- '#dot=.,comma=,,semi=;',
272
- '#comma=,,dot=.,semi=;'
273
- ]
235
+ '{#keys}' => '#semi,;,dot,.,comma,,',
236
+ '{#keys*}' => '#semi=;,dot=.,comma=,',
274
237
  }
275
238
  end
276
239
  context "Operator . with value modifiers" do
@@ -278,22 +241,8 @@ describe "Level 4" do
278
241
  'X{.var:3}' => 'X.val',
279
242
  'X{.list}' => 'X.red,green,blue',
280
243
  'X{.list*}' => 'X.red.green.blue',
281
- 'X{.keys}' => [
282
- 'X.semi,%3B,dot,.,comma,%2C',
283
- 'X.dot,.,semi,%3B,comma,%2C',
284
- 'X.comma,%2C,semi,%3B,dot,.',
285
- 'X.semi,%3B,comma,%2C,dot,.',
286
- 'X.dot,.,comma,%2C,semi,%3B',
287
- 'X.comma,%2C,dot,.,semi,%3B'
288
- ],
289
- 'X{.keys*}' => [
290
- 'X.semi=%3B.dot=..comma=%2C',
291
- 'X.dot=..semi=%3B.comma=%2C',
292
- 'X.comma=%2C.semi=%3B.dot=.',
293
- 'X.semi=%3B.comma=%2C.dot=.',
294
- 'X.dot=..comma=%2C.semi=%3B',
295
- 'X.comma=%2C.dot=..semi=%3B'
296
- ]
244
+ 'X{.keys}' => 'X.semi,%3B,dot,.,comma,%2C',
245
+ 'X{.keys*}' => 'X.semi=%3B.dot=..comma=%2C',
297
246
  }
298
247
  end
299
248
  context "Operator / with value modifiers" do
@@ -302,22 +251,8 @@ describe "Level 4" do
302
251
  '{/list}' => '/red,green,blue',
303
252
  '{/list*}' => '/red/green/blue',
304
253
  '{/list*,path:4}' => '/red/green/blue/%2Ffoo',
305
- '{/keys}' => [
306
- '/semi,%3B,dot,.,comma,%2C',
307
- '/dot,.,semi,%3B,comma,%2C',
308
- '/comma,%2C,semi,%3B,dot,.',
309
- '/semi,%3B,comma,%2C,dot,.',
310
- '/dot,.,comma,%2C,semi,%3B',
311
- '/comma,%2C,dot,.,semi,%3B'
312
- ],
313
- '{/keys*}' => [
314
- '/semi=%3B/dot=./comma=%2C',
315
- '/dot=./semi=%3B/comma=%2C',
316
- '/comma=%2C/semi=%3B/dot=.',
317
- '/semi=%3B/comma=%2C/dot=.',
318
- '/dot=./comma=%2C/semi=%3B',
319
- '/comma=%2C/dot=./semi=%3B'
320
- ]
254
+ '{/keys}' => '/semi,%3B,dot,.,comma,%2C',
255
+ '{/keys*}' => '/semi=%3B/dot=./comma=%2C',
321
256
  }
322
257
  end
323
258
  context "Operator ; with value modifiers" do
@@ -325,22 +260,8 @@ describe "Level 4" do
325
260
  '{;hello:5}' => ';hello=Hello',
326
261
  '{;list}' => ';list=red,green,blue',
327
262
  '{;list*}' => ';list=red;list=green;list=blue',
328
- '{;keys}' => [
329
- ';keys=semi,%3B,dot,.,comma,%2C',
330
- ';keys=dot,.,semi,%3B,comma,%2C',
331
- ';keys=comma,%2C,semi,%3B,dot,.',
332
- ';keys=semi,%3B,comma,%2C,dot,.',
333
- ';keys=dot,.,comma,%2C,semi,%3B',
334
- ';keys=comma,%2C,dot,.,semi,%3B'
335
- ],
336
- '{;keys*}' => [
337
- ';semi=%3B;dot=.;comma=%2C',
338
- ';dot=.;semi=%3B;comma=%2C',
339
- ';comma=%2C;semi=%3B;dot=.',
340
- ';semi=%3B;comma=%2C;dot=.',
341
- ';dot=.;comma=%2C;semi=%3B',
342
- ';comma=%2C;dot=.;semi=%3B'
343
- ]
263
+ '{;keys}' => ';keys=semi,%3B,dot,.,comma,%2C',
264
+ '{;keys*}' => ';semi=%3B;dot=.;comma=%2C',
344
265
  }
345
266
  end
346
267
  context "Operator ? with value modifiers" do
@@ -348,22 +269,8 @@ describe "Level 4" do
348
269
  '{?var:3}' => '?var=val',
349
270
  '{?list}' => '?list=red,green,blue',
350
271
  '{?list*}' => '?list=red&list=green&list=blue',
351
- '{?keys}' => [
352
- '?keys=semi,%3B,dot,.,comma,%2C',
353
- '?keys=dot,.,semi,%3B,comma,%2C',
354
- '?keys=comma,%2C,semi,%3B,dot,.',
355
- '?keys=semi,%3B,comma,%2C,dot,.',
356
- '?keys=dot,.,comma,%2C,semi,%3B',
357
- '?keys=comma,%2C,dot,.,semi,%3B'
358
- ],
359
- '{?keys*}' => [
360
- '?semi=%3B&dot=.&comma=%2C',
361
- '?dot=.&semi=%3B&comma=%2C',
362
- '?comma=%2C&semi=%3B&dot=.',
363
- '?semi=%3B&comma=%2C&dot=.',
364
- '?dot=.&comma=%2C&semi=%3B',
365
- '?comma=%2C&dot=.&semi=%3B'
366
- ]
272
+ '{?keys}' => '?keys=semi,%3B,dot,.,comma,%2C',
273
+ '{?keys*}' => '?semi=%3B&dot=.&comma=%2C',
367
274
  }
368
275
  end
369
276
  context "Operator & with value modifiers" do
@@ -371,22 +278,8 @@ describe "Level 4" do
371
278
  '{&var:3}' => '&var=val',
372
279
  '{&list}' => '&list=red,green,blue',
373
280
  '{&list*}' => '&list=red&list=green&list=blue',
374
- '{&keys}' => [
375
- '&keys=semi,%3B,dot,.,comma,%2C',
376
- '&keys=dot,.,semi,%3B,comma,%2C',
377
- '&keys=comma,%2C,semi,%3B,dot,.',
378
- '&keys=semi,%3B,comma,%2C,dot,.',
379
- '&keys=dot,.,comma,%2C,semi,%3B',
380
- '&keys=comma,%2C,dot,.,semi,%3B'
381
- ],
382
- '{&keys*}' => [
383
- '&semi=%3B&dot=.&comma=%2C',
384
- '&dot=.&semi=%3B&comma=%2C',
385
- '&comma=%2C&semi=%3B&dot=.',
386
- '&semi=%3B&comma=%2C&dot=.',
387
- '&dot=.&comma=%2C&semi=%3B',
388
- '&comma=%2C&dot=.&semi=%3B'
389
- ]
281
+ '{&keys}' => '&keys=semi,%3B,dot,.,comma,%2C',
282
+ '{&keys*}' => '&semi=%3B&dot=.&comma=%2C',
390
283
  }
391
284
  end
392
285
  end
@@ -395,7 +288,7 @@ describe "Modifiers" do
395
288
  {
396
289
  :var => "value",
397
290
  :semi => ";",
398
- :year => %w(1965 2000 2012),
291
+ :year => [1965, 2000, 2012],
399
292
  :dom => %w(example com)
400
293
  }
401
294
  }
@@ -428,7 +321,7 @@ describe "Expansion" do
428
321
  :base => "http://example.com/home/",
429
322
  :path => "/foo/bar",
430
323
  :list => ["red", "green", "blue"],
431
- :keys => {"semi" => ";","dot" => ".","comma" => ","},
324
+ :keys => {"semi" => ";","dot" => ".",:comma => ","},
432
325
  :v => "6",
433
326
  :x => "1024",
434
327
  :y => "768",
@@ -466,22 +359,8 @@ describe "Expansion" do
466
359
  '{var:30}' => 'value',
467
360
  '{list}' => 'red,green,blue',
468
361
  '{list*}' => 'red,green,blue',
469
- '{keys}' => [
470
- 'semi,%3B,dot,.,comma,%2C',
471
- 'dot,.,semi,%3B,comma,%2C',
472
- 'comma,%2C,semi,%3B,dot,.',
473
- 'semi,%3B,comma,%2C,dot,.',
474
- 'dot,.,comma,%2C,semi,%3B',
475
- 'comma,%2C,dot,.,semi,%3B'
476
- ],
477
- '{keys*}' => [
478
- 'semi=%3B,dot=.,comma=%2C',
479
- 'dot=.,semi=%3B,comma=%2C',
480
- 'comma=%2C,semi=%3B,dot=.',
481
- 'semi=%3B,comma=%2C,dot=.',
482
- 'dot=.,comma=%2C,semi=%3B',
483
- 'comma=%2C,dot=.,semi=%3B'
484
- ]
362
+ '{keys}' => 'semi,%3B,dot,.,comma,%2C',
363
+ '{keys*}' => 'semi=%3B,dot=.,comma=%2C',
485
364
  }
486
365
  end
487
366
  context "reserved expansion (+)" do
@@ -501,22 +380,8 @@ describe "Expansion" do
501
380
  '{+path:6}/here' => '/foo/b/here',
502
381
  '{+list}' => 'red,green,blue',
503
382
  '{+list*}' => 'red,green,blue',
504
- '{+keys}' => [
505
- 'semi,;,dot,.,comma,,',
506
- 'dot,.,semi,;,comma,,',
507
- 'comma,,,semi,;,dot,.',
508
- 'semi,;,comma,,,dot,.',
509
- 'dot,.,comma,,,semi,;',
510
- 'comma,,,dot,.,semi,;'
511
- ],
512
- '{+keys*}' => [
513
- 'semi=;,dot=.,comma=,',
514
- 'dot=.,semi=;,comma=,',
515
- 'comma=,,semi=;,dot=.',
516
- 'semi=;,comma=,,dot=.',
517
- 'dot=.,comma=,,semi=;',
518
- 'comma=,,dot=.,semi=;'
519
- ]
383
+ '{+keys}' => 'semi,;,dot,.,comma,,',
384
+ '{+keys*}' => 'semi=;,dot=.,comma=,',
520
385
  }
521
386
  end
522
387
  context "fragment expansion (#)" do
@@ -531,22 +396,8 @@ describe "Expansion" do
531
396
  '{#path:6}/here' => '#/foo/b/here',
532
397
  '{#list}' => '#red,green,blue',
533
398
  '{#list*}' => '#red,green,blue',
534
- '{#keys}' => [
535
- '#semi,;,dot,.,comma,,',
536
- '#dot,.,semi,;,comma,,',
537
- '#comma,,,semi,;,dot,.',
538
- '#semi,;,comma,,,dot,.',
539
- '#dot,.,comma,,,semi,;',
540
- '#comma,,,dot,.,semi,;'
541
- ],
542
- '{#keys*}' => [
543
- '#semi=;,dot=.,comma=,',
544
- '#dot=.,semi=;,comma=,',
545
- '#comma=,,semi=;,dot=.',
546
- '#semi=;,comma=,,dot=.',
547
- '#dot=.,comma=,,semi=;',
548
- '#comma=,,dot=.,semi=;'
549
- ]
399
+ '{#keys}' => '#semi,;,dot,.,comma,,',
400
+ '{#keys*}' => '#semi=;,dot=.,comma=,',
550
401
  }
551
402
  end
552
403
  context "label expansion (.)" do
@@ -561,22 +412,8 @@ describe "Expansion" do
561
412
  'X{.var:3}' => 'X.val',
562
413
  'X{.list}' => 'X.red,green,blue',
563
414
  'X{.list*}' => 'X.red.green.blue',
564
- 'X{.keys}' => [
565
- 'X.semi,%3B,dot,.,comma,%2C',
566
- 'X.dot,.,semi,%3B,comma,%2C',
567
- 'X.comma,%2C,semi,%3B,dot,.',
568
- 'X.semi,%3B,comma,%2C,dot,.',
569
- 'X.dot,.,comma,%2C,semi,%3B',
570
- 'X.comma,%2C,dot,.,semi,%3B'
571
- ],
572
- 'X{.keys*}' => [
573
- 'X.semi=%3B.dot=..comma=%2C',
574
- 'X.dot=..semi=%3B.comma=%2C',
575
- 'X.comma=%2C.semi=%3B.dot=.',
576
- 'X.semi=%3B.comma=%2C.dot=.',
577
- 'X.dot=..comma=%2C.semi=%3B',
578
- 'X.comma=%2C.dot=..semi=%3B'
579
- ],
415
+ 'X{.keys}' => 'X.semi,%3B,dot,.,comma,%2C',
416
+ 'X{.keys*}' => 'X.semi=%3B.dot=..comma=%2C',
580
417
  'X{.empty_keys}' => 'X',
581
418
  'X{.empty_keys*}' => 'X'
582
419
  }
@@ -595,22 +432,8 @@ describe "Expansion" do
595
432
  '{/list}' => '/red,green,blue',
596
433
  '{/list*}' => '/red/green/blue',
597
434
  '{/list*,path:4}' => '/red/green/blue/%2Ffoo',
598
- '{/keys}' => [
599
- '/semi,%3B,dot,.,comma,%2C',
600
- '/dot,.,semi,%3B,comma,%2C',
601
- '/comma,%2C,semi,%3B,dot,.',
602
- '/semi,%3B,comma,%2C,dot,.',
603
- '/dot,.,comma,%2C,semi,%3B',
604
- '/comma,%2C,dot,.,semi,%3B'
605
- ],
606
- '{/keys*}' => [
607
- '/semi=%3B/dot=./comma=%2C',
608
- '/dot=./semi=%3B/comma=%2C',
609
- '/comma=%2C/semi=%3B/dot=.',
610
- '/semi=%3B/comma=%2C/dot=.',
611
- '/dot=./comma=%2C/semi=%3B',
612
- '/comma=%2C/dot=./semi=%3B'
613
- ]
435
+ '{/keys}' => '/semi,%3B,dot,.,comma,%2C',
436
+ '{/keys*}' => '/semi=%3B/dot=./comma=%2C',
614
437
  }
615
438
  end
616
439
  context "path-style expansion (;)" do
@@ -626,22 +449,8 @@ describe "Expansion" do
626
449
  '{;hello:5}' => ';hello=Hello',
627
450
  '{;list}' => ';list=red,green,blue',
628
451
  '{;list*}' => ';list=red;list=green;list=blue',
629
- '{;keys}' => [
630
- ';keys=semi,%3B,dot,.,comma,%2C',
631
- ';keys=dot,.,semi,%3B,comma,%2C',
632
- ';keys=comma,%2C,semi,%3B,dot,.',
633
- ';keys=semi,%3B,comma,%2C,dot,.',
634
- ';keys=dot,.,comma,%2C,semi,%3B',
635
- ';keys=comma,%2C,dot,.,semi,%3B'
636
- ],
637
- '{;keys*}' => [
638
- ';semi=%3B;dot=.;comma=%2C',
639
- ';dot=.;semi=%3B;comma=%2C',
640
- ';comma=%2C;semi=%3B;dot=.',
641
- ';semi=%3B;comma=%2C;dot=.',
642
- ';dot=.;comma=%2C;semi=%3B',
643
- ';comma=%2C;dot=.;semi=%3B'
644
- ]
452
+ '{;keys}' => ';keys=semi,%3B,dot,.,comma,%2C',
453
+ '{;keys*}' => ';semi=%3B;dot=.;comma=%2C',
645
454
  }
646
455
  end
647
456
  context "form query expansion (?)" do
@@ -654,22 +463,8 @@ describe "Expansion" do
654
463
  '{?var:3}' => '?var=val',
655
464
  '{?list}' => '?list=red,green,blue',
656
465
  '{?list*}' => '?list=red&list=green&list=blue',
657
- '{?keys}' => [
658
- '?keys=semi,%3B,dot,.,comma,%2C',
659
- '?keys=dot,.,semi,%3B,comma,%2C',
660
- '?keys=comma,%2C,semi,%3B,dot,.',
661
- '?keys=semi,%3B,comma,%2C,dot,.',
662
- '?keys=dot,.,comma,%2C,semi,%3B',
663
- '?keys=comma,%2C,dot,.,semi,%3B'
664
- ],
665
- '{?keys*}' => [
666
- '?semi=%3B&dot=.&comma=%2C',
667
- '?dot=.&semi=%3B&comma=%2C',
668
- '?comma=%2C&semi=%3B&dot=.',
669
- '?semi=%3B&comma=%2C&dot=.',
670
- '?dot=.&comma=%2C&semi=%3B',
671
- '?comma=%2C&dot=.&semi=%3B'
672
- ]
466
+ '{?keys}' => '?keys=semi,%3B,dot,.,comma,%2C',
467
+ '{?keys*}' => '?semi=%3B&dot=.&comma=%2C',
673
468
  }
674
469
  end
675
470
  context "form query expansion (&)" do
@@ -682,22 +477,8 @@ describe "Expansion" do
682
477
  '{&var:3}' => '&var=val',
683
478
  '{&list}' => '&list=red,green,blue',
684
479
  '{&list*}' => '&list=red&list=green&list=blue',
685
- '{&keys}' => [
686
- '&keys=semi,%3B,dot,.,comma,%2C',
687
- '&keys=dot,.,semi,%3B,comma,%2C',
688
- '&keys=comma,%2C,semi,%3B,dot,.',
689
- '&keys=semi,%3B,comma,%2C,dot,.',
690
- '&keys=dot,.,comma,%2C,semi,%3B',
691
- '&keys=comma,%2C,dot,.,semi,%3B'
692
- ],
693
- '{&keys*}' => [
694
- '&semi=%3B&dot=.&comma=%2C',
695
- '&dot=.&semi=%3B&comma=%2C',
696
- '&comma=%2C&semi=%3B&dot=.',
697
- '&semi=%3B&comma=%2C&dot=.',
698
- '&dot=.&comma=%2C&semi=%3B',
699
- '&comma=%2C&dot=.&semi=%3B'
700
- ]
480
+ '{&keys}' => '&keys=semi,%3B,dot,.,comma,%2C',
481
+ '{&keys*}' => '&semi=%3B&dot=.&comma=%2C',
701
482
  }
702
483
  end
703
484
  context "non-string key in match data" do
@@ -1012,6 +793,19 @@ describe Addressable::Template do
1012
793
  )
1013
794
  end
1014
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
+
1015
809
  it "does not normalize unicode when byte semantics requested" do
1016
810
  template = subject.partial_expand({"query" => "Cafe\u0301"}, nil, false)
1017
811
  expect(template.pattern).to eq(
@@ -1072,6 +866,17 @@ describe Addressable::Template do
1072
866
  expect(uri).to eq("http://example.com/search/Caf%C3%A9/")
1073
867
  end
1074
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
+
1075
880
  it "does not normalize unicode when byte semantics requested" do
1076
881
  uri = subject.expand({ "query" => "Cafe\u0301" }, nil, false).to_str
1077
882
  expect(uri).to eq("http://example.com/search/Cafe%CC%81/")
@@ -1340,6 +1145,14 @@ describe Addressable::Template do
1340
1145
  expect(subject).not_to match("foo_bar*")
1341
1146
  expect(subject).not_to match("foo_bar:20")
1342
1147
  end
1148
+
1149
+ it 'should parse in a reasonable time' do
1150
+ expect do
1151
+ Timeout.timeout(0.1) do
1152
+ expect(subject).not_to match("0"*25 + "!")
1153
+ end
1154
+ end.not_to raise_error
1155
+ end
1343
1156
  end
1344
1157
  context "VARIABLE_LIST" do
1345
1158
  subject { Addressable::Template::VARIABLE_LIST }