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