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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +64 -0
- data/Gemfile +14 -16
- data/README.md +12 -10
- data/Rakefile +14 -8
- data/addressable.gemspec +28 -0
- data/lib/addressable/idna/native.rb +8 -3
- data/lib/addressable/idna/pure.rb +20 -191
- data/lib/addressable/idna.rb +0 -1
- data/lib/addressable/template.rb +37 -53
- data/lib/addressable/uri.rb +257 -176
- data/lib/addressable/version.rb +2 -3
- data/spec/addressable/idna_spec.rb +9 -7
- data/spec/addressable/net_http_compat_spec.rb +0 -1
- data/spec/addressable/security_spec.rb +0 -1
- data/spec/addressable/template_spec.rb +78 -265
- data/spec/addressable/uri_spec.rb +503 -208
- data/spec/spec_helper.rb +9 -0
- data/tasks/gem.rake +9 -7
- data/tasks/profile.rake +72 -0
- data/tasks/rspec.rake +1 -1
- metadata +16 -15
- data/spec/addressable/rack_mount_compat_spec.rb +0 -106
data/lib/addressable/version.rb
CHANGED
@@ -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 =
|
27
|
-
TINY =
|
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");
|
@@ -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
|
-
|
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" => '.',
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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 =>
|
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" => "."
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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 }
|