addressable 2.6.0 → 2.8.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 }