addressable 2.5.0 → 2.8.8
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 +138 -34
- data/Gemfile +15 -16
- data/README.md +20 -21
- data/Rakefile +16 -11
- data/addressable.gemspec +28 -0
- data/lib/addressable/idna/native.rb +12 -5
- data/lib/addressable/idna/pure.rb +4257 -214
- data/lib/addressable/idna.rb +2 -1
- data/lib/addressable/template.rb +76 -98
- data/lib/addressable/uri.rb +338 -228
- data/lib/addressable/version.rb +4 -3
- data/lib/addressable.rb +2 -0
- data/spec/addressable/idna_spec.rb +29 -13
- data/spec/addressable/net_http_compat_spec.rb +2 -1
- data/spec/addressable/security_spec.rb +2 -1
- data/spec/addressable/template_spec.rb +144 -267
- data/spec/addressable/uri_spec.rb +598 -216
- data/spec/spec_helper.rb +12 -0
- data/tasks/clobber.rake +2 -0
- data/tasks/gem.rake +18 -9
- data/tasks/git.rake +2 -0
- data/tasks/metrics.rake +2 -0
- data/tasks/profile.rake +72 -0
- data/tasks/rspec.rake +3 -1
- data/tasks/yard.rake +2 -0
- metadata +25 -22
- data/data/unicode.data +0 -0
- data/spec/addressable/rack_mount_compat_spec.rb +0 -104
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
#
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
# Copyright (C) Bob Aman
|
|
3
4
|
#
|
|
4
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
@@ -17,6 +18,7 @@
|
|
|
17
18
|
require "spec_helper"
|
|
18
19
|
|
|
19
20
|
require "bigdecimal"
|
|
21
|
+
require "timeout"
|
|
20
22
|
require "addressable/template"
|
|
21
23
|
|
|
22
24
|
shared_examples_for 'expands' do |tests|
|
|
@@ -24,11 +26,7 @@ shared_examples_for 'expands' do |tests|
|
|
|
24
26
|
exp = expansion.is_a?(Array) ? expansion.first : expansion
|
|
25
27
|
it "#{template} to #{exp}" do
|
|
26
28
|
tmpl = Addressable::Template.new(template).expand(subject)
|
|
27
|
-
|
|
28
|
-
expect(expansion.any?{|i| i == tmpl.to_str}).to be true
|
|
29
|
-
else
|
|
30
|
-
expect(tmpl.to_str).to eq(expansion)
|
|
31
|
-
end
|
|
29
|
+
expect(tmpl.to_str).to eq(expansion)
|
|
32
30
|
end
|
|
33
31
|
end
|
|
34
32
|
end
|
|
@@ -75,6 +73,15 @@ describe "==" do
|
|
|
75
73
|
end
|
|
76
74
|
end
|
|
77
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
|
+
|
|
78
85
|
describe "Type conversion" do
|
|
79
86
|
subject {
|
|
80
87
|
{
|
|
@@ -82,7 +89,7 @@ describe "Type conversion" do
|
|
|
82
89
|
:hello => 1234,
|
|
83
90
|
:nothing => nil,
|
|
84
91
|
:sym => :symbolic,
|
|
85
|
-
:decimal => BigDecimal
|
|
92
|
+
:decimal => BigDecimal('1')
|
|
86
93
|
}
|
|
87
94
|
}
|
|
88
95
|
|
|
@@ -91,7 +98,7 @@ describe "Type conversion" do
|
|
|
91
98
|
'{hello}' => '1234',
|
|
92
99
|
'{nothing}' => '',
|
|
93
100
|
'{sym}' => 'symbolic',
|
|
94
|
-
'{decimal}' => '0.1E1'
|
|
101
|
+
'{decimal}' => RUBY_VERSION < '2.4.0' ? '0.1E1' : '0.1e1'
|
|
95
102
|
}
|
|
96
103
|
end
|
|
97
104
|
|
|
@@ -198,7 +205,7 @@ describe "Level 4" do
|
|
|
198
205
|
:path => "/foo/bar",
|
|
199
206
|
:semi => ";",
|
|
200
207
|
:list => %w(red green blue),
|
|
201
|
-
:keys => {"semi" => ';', "dot" => '.',
|
|
208
|
+
:keys => {"semi" => ';', "dot" => '.', :comma => ','}
|
|
202
209
|
}
|
|
203
210
|
}
|
|
204
211
|
context "Expansion with value modifiers" do
|
|
@@ -207,22 +214,8 @@ describe "Level 4" do
|
|
|
207
214
|
'{var:30}' => 'value',
|
|
208
215
|
'{list}' => 'red,green,blue',
|
|
209
216
|
'{list*}' => 'red,green,blue',
|
|
210
|
-
'{keys}' =>
|
|
211
|
-
|
|
212
|
-
'dot,.,semi,%3B,comma,%2C',
|
|
213
|
-
'comma,%2C,semi,%3B,dot,.',
|
|
214
|
-
'semi,%3B,comma,%2C,dot,.',
|
|
215
|
-
'dot,.,comma,%2C,semi,%3B',
|
|
216
|
-
'comma,%2C,dot,.,semi,%3B'
|
|
217
|
-
],
|
|
218
|
-
'{keys*}' => [
|
|
219
|
-
'semi=%3B,dot=.,comma=%2C',
|
|
220
|
-
'dot=.,semi=%3B,comma=%2C',
|
|
221
|
-
'comma=%2C,semi=%3B,dot=.',
|
|
222
|
-
'semi=%3B,comma=%2C,dot=.',
|
|
223
|
-
'dot=.,comma=%2C,semi=%3B',
|
|
224
|
-
'comma=%2C,dot=.,semi=%3B'
|
|
225
|
-
]
|
|
217
|
+
'{keys}' => 'semi,%3B,dot,.,comma,%2C',
|
|
218
|
+
'{keys*}' => 'semi=%3B,dot=.,comma=%2C',
|
|
226
219
|
}
|
|
227
220
|
end
|
|
228
221
|
context "Operator + with value modifiers" do
|
|
@@ -230,22 +223,8 @@ describe "Level 4" do
|
|
|
230
223
|
'{+path:6}/here' => '/foo/b/here',
|
|
231
224
|
'{+list}' => 'red,green,blue',
|
|
232
225
|
'{+list*}' => 'red,green,blue',
|
|
233
|
-
'{+keys}' =>
|
|
234
|
-
|
|
235
|
-
'dot,.,semi,;,comma,,',
|
|
236
|
-
'comma,,,semi,;,dot,.',
|
|
237
|
-
'semi,;,comma,,,dot,.',
|
|
238
|
-
'dot,.,comma,,,semi,;',
|
|
239
|
-
'comma,,,dot,.,semi,;'
|
|
240
|
-
],
|
|
241
|
-
'{+keys*}' => [
|
|
242
|
-
'semi=;,dot=.,comma=,',
|
|
243
|
-
'dot=.,semi=;,comma=,',
|
|
244
|
-
'comma=,,semi=;,dot=.',
|
|
245
|
-
'semi=;,comma=,,dot=.',
|
|
246
|
-
'dot=.,comma=,,semi=;',
|
|
247
|
-
'comma=,,dot=.,semi=;'
|
|
248
|
-
]
|
|
226
|
+
'{+keys}' => 'semi,;,dot,.,comma,,',
|
|
227
|
+
'{+keys*}' => 'semi=;,dot=.,comma=,',
|
|
249
228
|
}
|
|
250
229
|
end
|
|
251
230
|
context "Operator # with value modifiers" do
|
|
@@ -253,22 +232,8 @@ describe "Level 4" do
|
|
|
253
232
|
'{#path:6}/here' => '#/foo/b/here',
|
|
254
233
|
'{#list}' => '#red,green,blue',
|
|
255
234
|
'{#list*}' => '#red,green,blue',
|
|
256
|
-
'{#keys}' =>
|
|
257
|
-
|
|
258
|
-
'#dot,.,semi,;,comma,,',
|
|
259
|
-
'#comma,,,semi,;,dot,.',
|
|
260
|
-
'#semi,;,comma,,,dot,.',
|
|
261
|
-
'#dot,.,comma,,,semi,;',
|
|
262
|
-
'#comma,,,dot,.,semi,;'
|
|
263
|
-
],
|
|
264
|
-
'{#keys*}' => [
|
|
265
|
-
'#semi=;,dot=.,comma=,',
|
|
266
|
-
'#dot=.,semi=;,comma=,',
|
|
267
|
-
'#comma=,,semi=;,dot=.',
|
|
268
|
-
'#semi=;,comma=,,dot=.',
|
|
269
|
-
'#dot=.,comma=,,semi=;',
|
|
270
|
-
'#comma=,,dot=.,semi=;'
|
|
271
|
-
]
|
|
235
|
+
'{#keys}' => '#semi,;,dot,.,comma,,',
|
|
236
|
+
'{#keys*}' => '#semi=;,dot=.,comma=,',
|
|
272
237
|
}
|
|
273
238
|
end
|
|
274
239
|
context "Operator . with value modifiers" do
|
|
@@ -276,22 +241,8 @@ describe "Level 4" do
|
|
|
276
241
|
'X{.var:3}' => 'X.val',
|
|
277
242
|
'X{.list}' => 'X.red,green,blue',
|
|
278
243
|
'X{.list*}' => 'X.red.green.blue',
|
|
279
|
-
'X{.keys}' =>
|
|
280
|
-
|
|
281
|
-
'X.dot,.,semi,%3B,comma,%2C',
|
|
282
|
-
'X.comma,%2C,semi,%3B,dot,.',
|
|
283
|
-
'X.semi,%3B,comma,%2C,dot,.',
|
|
284
|
-
'X.dot,.,comma,%2C,semi,%3B',
|
|
285
|
-
'X.comma,%2C,dot,.,semi,%3B'
|
|
286
|
-
],
|
|
287
|
-
'X{.keys*}' => [
|
|
288
|
-
'X.semi=%3B.dot=..comma=%2C',
|
|
289
|
-
'X.dot=..semi=%3B.comma=%2C',
|
|
290
|
-
'X.comma=%2C.semi=%3B.dot=.',
|
|
291
|
-
'X.semi=%3B.comma=%2C.dot=.',
|
|
292
|
-
'X.dot=..comma=%2C.semi=%3B',
|
|
293
|
-
'X.comma=%2C.dot=..semi=%3B'
|
|
294
|
-
]
|
|
244
|
+
'X{.keys}' => 'X.semi,%3B,dot,.,comma,%2C',
|
|
245
|
+
'X{.keys*}' => 'X.semi=%3B.dot=..comma=%2C',
|
|
295
246
|
}
|
|
296
247
|
end
|
|
297
248
|
context "Operator / with value modifiers" do
|
|
@@ -300,22 +251,8 @@ describe "Level 4" do
|
|
|
300
251
|
'{/list}' => '/red,green,blue',
|
|
301
252
|
'{/list*}' => '/red/green/blue',
|
|
302
253
|
'{/list*,path:4}' => '/red/green/blue/%2Ffoo',
|
|
303
|
-
'{/keys}' =>
|
|
304
|
-
|
|
305
|
-
'/dot,.,semi,%3B,comma,%2C',
|
|
306
|
-
'/comma,%2C,semi,%3B,dot,.',
|
|
307
|
-
'/semi,%3B,comma,%2C,dot,.',
|
|
308
|
-
'/dot,.,comma,%2C,semi,%3B',
|
|
309
|
-
'/comma,%2C,dot,.,semi,%3B'
|
|
310
|
-
],
|
|
311
|
-
'{/keys*}' => [
|
|
312
|
-
'/semi=%3B/dot=./comma=%2C',
|
|
313
|
-
'/dot=./semi=%3B/comma=%2C',
|
|
314
|
-
'/comma=%2C/semi=%3B/dot=.',
|
|
315
|
-
'/semi=%3B/comma=%2C/dot=.',
|
|
316
|
-
'/dot=./comma=%2C/semi=%3B',
|
|
317
|
-
'/comma=%2C/dot=./semi=%3B'
|
|
318
|
-
]
|
|
254
|
+
'{/keys}' => '/semi,%3B,dot,.,comma,%2C',
|
|
255
|
+
'{/keys*}' => '/semi=%3B/dot=./comma=%2C',
|
|
319
256
|
}
|
|
320
257
|
end
|
|
321
258
|
context "Operator ; with value modifiers" do
|
|
@@ -323,22 +260,8 @@ describe "Level 4" do
|
|
|
323
260
|
'{;hello:5}' => ';hello=Hello',
|
|
324
261
|
'{;list}' => ';list=red,green,blue',
|
|
325
262
|
'{;list*}' => ';list=red;list=green;list=blue',
|
|
326
|
-
'{;keys}' =>
|
|
327
|
-
|
|
328
|
-
';keys=dot,.,semi,%3B,comma,%2C',
|
|
329
|
-
';keys=comma,%2C,semi,%3B,dot,.',
|
|
330
|
-
';keys=semi,%3B,comma,%2C,dot,.',
|
|
331
|
-
';keys=dot,.,comma,%2C,semi,%3B',
|
|
332
|
-
';keys=comma,%2C,dot,.,semi,%3B'
|
|
333
|
-
],
|
|
334
|
-
'{;keys*}' => [
|
|
335
|
-
';semi=%3B;dot=.;comma=%2C',
|
|
336
|
-
';dot=.;semi=%3B;comma=%2C',
|
|
337
|
-
';comma=%2C;semi=%3B;dot=.',
|
|
338
|
-
';semi=%3B;comma=%2C;dot=.',
|
|
339
|
-
';dot=.;comma=%2C;semi=%3B',
|
|
340
|
-
';comma=%2C;dot=.;semi=%3B'
|
|
341
|
-
]
|
|
263
|
+
'{;keys}' => ';keys=semi,%3B,dot,.,comma,%2C',
|
|
264
|
+
'{;keys*}' => ';semi=%3B;dot=.;comma=%2C',
|
|
342
265
|
}
|
|
343
266
|
end
|
|
344
267
|
context "Operator ? with value modifiers" do
|
|
@@ -346,22 +269,8 @@ describe "Level 4" do
|
|
|
346
269
|
'{?var:3}' => '?var=val',
|
|
347
270
|
'{?list}' => '?list=red,green,blue',
|
|
348
271
|
'{?list*}' => '?list=red&list=green&list=blue',
|
|
349
|
-
'{?keys}' =>
|
|
350
|
-
|
|
351
|
-
'?keys=dot,.,semi,%3B,comma,%2C',
|
|
352
|
-
'?keys=comma,%2C,semi,%3B,dot,.',
|
|
353
|
-
'?keys=semi,%3B,comma,%2C,dot,.',
|
|
354
|
-
'?keys=dot,.,comma,%2C,semi,%3B',
|
|
355
|
-
'?keys=comma,%2C,dot,.,semi,%3B'
|
|
356
|
-
],
|
|
357
|
-
'{?keys*}' => [
|
|
358
|
-
'?semi=%3B&dot=.&comma=%2C',
|
|
359
|
-
'?dot=.&semi=%3B&comma=%2C',
|
|
360
|
-
'?comma=%2C&semi=%3B&dot=.',
|
|
361
|
-
'?semi=%3B&comma=%2C&dot=.',
|
|
362
|
-
'?dot=.&comma=%2C&semi=%3B',
|
|
363
|
-
'?comma=%2C&dot=.&semi=%3B'
|
|
364
|
-
]
|
|
272
|
+
'{?keys}' => '?keys=semi,%3B,dot,.,comma,%2C',
|
|
273
|
+
'{?keys*}' => '?semi=%3B&dot=.&comma=%2C',
|
|
365
274
|
}
|
|
366
275
|
end
|
|
367
276
|
context "Operator & with value modifiers" do
|
|
@@ -369,22 +278,8 @@ describe "Level 4" do
|
|
|
369
278
|
'{&var:3}' => '&var=val',
|
|
370
279
|
'{&list}' => '&list=red,green,blue',
|
|
371
280
|
'{&list*}' => '&list=red&list=green&list=blue',
|
|
372
|
-
'{&keys}' =>
|
|
373
|
-
|
|
374
|
-
'&keys=dot,.,semi,%3B,comma,%2C',
|
|
375
|
-
'&keys=comma,%2C,semi,%3B,dot,.',
|
|
376
|
-
'&keys=semi,%3B,comma,%2C,dot,.',
|
|
377
|
-
'&keys=dot,.,comma,%2C,semi,%3B',
|
|
378
|
-
'&keys=comma,%2C,dot,.,semi,%3B'
|
|
379
|
-
],
|
|
380
|
-
'{&keys*}' => [
|
|
381
|
-
'&semi=%3B&dot=.&comma=%2C',
|
|
382
|
-
'&dot=.&semi=%3B&comma=%2C',
|
|
383
|
-
'&comma=%2C&semi=%3B&dot=.',
|
|
384
|
-
'&semi=%3B&comma=%2C&dot=.',
|
|
385
|
-
'&dot=.&comma=%2C&semi=%3B',
|
|
386
|
-
'&comma=%2C&dot=.&semi=%3B'
|
|
387
|
-
]
|
|
281
|
+
'{&keys}' => '&keys=semi,%3B,dot,.,comma,%2C',
|
|
282
|
+
'{&keys*}' => '&semi=%3B&dot=.&comma=%2C',
|
|
388
283
|
}
|
|
389
284
|
end
|
|
390
285
|
end
|
|
@@ -393,7 +288,7 @@ describe "Modifiers" do
|
|
|
393
288
|
{
|
|
394
289
|
:var => "value",
|
|
395
290
|
:semi => ";",
|
|
396
|
-
:year =>
|
|
291
|
+
:year => [1965, 2000, 2012],
|
|
397
292
|
:dom => %w(example com)
|
|
398
293
|
}
|
|
399
294
|
}
|
|
@@ -426,7 +321,7 @@ describe "Expansion" do
|
|
|
426
321
|
:base => "http://example.com/home/",
|
|
427
322
|
:path => "/foo/bar",
|
|
428
323
|
:list => ["red", "green", "blue"],
|
|
429
|
-
:keys => {"semi" => ";","dot" => "."
|
|
324
|
+
:keys => {"semi" => ";","dot" => ".",:comma => ","},
|
|
430
325
|
:v => "6",
|
|
431
326
|
:x => "1024",
|
|
432
327
|
:y => "768",
|
|
@@ -464,22 +359,8 @@ describe "Expansion" do
|
|
|
464
359
|
'{var:30}' => 'value',
|
|
465
360
|
'{list}' => 'red,green,blue',
|
|
466
361
|
'{list*}' => 'red,green,blue',
|
|
467
|
-
'{keys}' =>
|
|
468
|
-
|
|
469
|
-
'dot,.,semi,%3B,comma,%2C',
|
|
470
|
-
'comma,%2C,semi,%3B,dot,.',
|
|
471
|
-
'semi,%3B,comma,%2C,dot,.',
|
|
472
|
-
'dot,.,comma,%2C,semi,%3B',
|
|
473
|
-
'comma,%2C,dot,.,semi,%3B'
|
|
474
|
-
],
|
|
475
|
-
'{keys*}' => [
|
|
476
|
-
'semi=%3B,dot=.,comma=%2C',
|
|
477
|
-
'dot=.,semi=%3B,comma=%2C',
|
|
478
|
-
'comma=%2C,semi=%3B,dot=.',
|
|
479
|
-
'semi=%3B,comma=%2C,dot=.',
|
|
480
|
-
'dot=.,comma=%2C,semi=%3B',
|
|
481
|
-
'comma=%2C,dot=.,semi=%3B'
|
|
482
|
-
]
|
|
362
|
+
'{keys}' => 'semi,%3B,dot,.,comma,%2C',
|
|
363
|
+
'{keys*}' => 'semi=%3B,dot=.,comma=%2C',
|
|
483
364
|
}
|
|
484
365
|
end
|
|
485
366
|
context "reserved expansion (+)" do
|
|
@@ -499,22 +380,8 @@ describe "Expansion" do
|
|
|
499
380
|
'{+path:6}/here' => '/foo/b/here',
|
|
500
381
|
'{+list}' => 'red,green,blue',
|
|
501
382
|
'{+list*}' => 'red,green,blue',
|
|
502
|
-
'{+keys}' =>
|
|
503
|
-
|
|
504
|
-
'dot,.,semi,;,comma,,',
|
|
505
|
-
'comma,,,semi,;,dot,.',
|
|
506
|
-
'semi,;,comma,,,dot,.',
|
|
507
|
-
'dot,.,comma,,,semi,;',
|
|
508
|
-
'comma,,,dot,.,semi,;'
|
|
509
|
-
],
|
|
510
|
-
'{+keys*}' => [
|
|
511
|
-
'semi=;,dot=.,comma=,',
|
|
512
|
-
'dot=.,semi=;,comma=,',
|
|
513
|
-
'comma=,,semi=;,dot=.',
|
|
514
|
-
'semi=;,comma=,,dot=.',
|
|
515
|
-
'dot=.,comma=,,semi=;',
|
|
516
|
-
'comma=,,dot=.,semi=;'
|
|
517
|
-
]
|
|
383
|
+
'{+keys}' => 'semi,;,dot,.,comma,,',
|
|
384
|
+
'{+keys*}' => 'semi=;,dot=.,comma=,',
|
|
518
385
|
}
|
|
519
386
|
end
|
|
520
387
|
context "fragment expansion (#)" do
|
|
@@ -529,22 +396,8 @@ describe "Expansion" do
|
|
|
529
396
|
'{#path:6}/here' => '#/foo/b/here',
|
|
530
397
|
'{#list}' => '#red,green,blue',
|
|
531
398
|
'{#list*}' => '#red,green,blue',
|
|
532
|
-
'{#keys}' =>
|
|
533
|
-
|
|
534
|
-
'#dot,.,semi,;,comma,,',
|
|
535
|
-
'#comma,,,semi,;,dot,.',
|
|
536
|
-
'#semi,;,comma,,,dot,.',
|
|
537
|
-
'#dot,.,comma,,,semi,;',
|
|
538
|
-
'#comma,,,dot,.,semi,;'
|
|
539
|
-
],
|
|
540
|
-
'{#keys*}' => [
|
|
541
|
-
'#semi=;,dot=.,comma=,',
|
|
542
|
-
'#dot=.,semi=;,comma=,',
|
|
543
|
-
'#comma=,,semi=;,dot=.',
|
|
544
|
-
'#semi=;,comma=,,dot=.',
|
|
545
|
-
'#dot=.,comma=,,semi=;',
|
|
546
|
-
'#comma=,,dot=.,semi=;'
|
|
547
|
-
]
|
|
399
|
+
'{#keys}' => '#semi,;,dot,.,comma,,',
|
|
400
|
+
'{#keys*}' => '#semi=;,dot=.,comma=,',
|
|
548
401
|
}
|
|
549
402
|
end
|
|
550
403
|
context "label expansion (.)" do
|
|
@@ -559,22 +412,8 @@ describe "Expansion" do
|
|
|
559
412
|
'X{.var:3}' => 'X.val',
|
|
560
413
|
'X{.list}' => 'X.red,green,blue',
|
|
561
414
|
'X{.list*}' => 'X.red.green.blue',
|
|
562
|
-
'X{.keys}' =>
|
|
563
|
-
|
|
564
|
-
'X.dot,.,semi,%3B,comma,%2C',
|
|
565
|
-
'X.comma,%2C,semi,%3B,dot,.',
|
|
566
|
-
'X.semi,%3B,comma,%2C,dot,.',
|
|
567
|
-
'X.dot,.,comma,%2C,semi,%3B',
|
|
568
|
-
'X.comma,%2C,dot,.,semi,%3B'
|
|
569
|
-
],
|
|
570
|
-
'X{.keys*}' => [
|
|
571
|
-
'X.semi=%3B.dot=..comma=%2C',
|
|
572
|
-
'X.dot=..semi=%3B.comma=%2C',
|
|
573
|
-
'X.comma=%2C.semi=%3B.dot=.',
|
|
574
|
-
'X.semi=%3B.comma=%2C.dot=.',
|
|
575
|
-
'X.dot=..comma=%2C.semi=%3B',
|
|
576
|
-
'X.comma=%2C.dot=..semi=%3B'
|
|
577
|
-
],
|
|
415
|
+
'X{.keys}' => 'X.semi,%3B,dot,.,comma,%2C',
|
|
416
|
+
'X{.keys*}' => 'X.semi=%3B.dot=..comma=%2C',
|
|
578
417
|
'X{.empty_keys}' => 'X',
|
|
579
418
|
'X{.empty_keys*}' => 'X'
|
|
580
419
|
}
|
|
@@ -593,22 +432,8 @@ describe "Expansion" do
|
|
|
593
432
|
'{/list}' => '/red,green,blue',
|
|
594
433
|
'{/list*}' => '/red/green/blue',
|
|
595
434
|
'{/list*,path:4}' => '/red/green/blue/%2Ffoo',
|
|
596
|
-
'{/keys}' =>
|
|
597
|
-
|
|
598
|
-
'/dot,.,semi,%3B,comma,%2C',
|
|
599
|
-
'/comma,%2C,semi,%3B,dot,.',
|
|
600
|
-
'/semi,%3B,comma,%2C,dot,.',
|
|
601
|
-
'/dot,.,comma,%2C,semi,%3B',
|
|
602
|
-
'/comma,%2C,dot,.,semi,%3B'
|
|
603
|
-
],
|
|
604
|
-
'{/keys*}' => [
|
|
605
|
-
'/semi=%3B/dot=./comma=%2C',
|
|
606
|
-
'/dot=./semi=%3B/comma=%2C',
|
|
607
|
-
'/comma=%2C/semi=%3B/dot=.',
|
|
608
|
-
'/semi=%3B/comma=%2C/dot=.',
|
|
609
|
-
'/dot=./comma=%2C/semi=%3B',
|
|
610
|
-
'/comma=%2C/dot=./semi=%3B'
|
|
611
|
-
]
|
|
435
|
+
'{/keys}' => '/semi,%3B,dot,.,comma,%2C',
|
|
436
|
+
'{/keys*}' => '/semi=%3B/dot=./comma=%2C',
|
|
612
437
|
}
|
|
613
438
|
end
|
|
614
439
|
context "path-style expansion (;)" do
|
|
@@ -624,22 +449,8 @@ describe "Expansion" do
|
|
|
624
449
|
'{;hello:5}' => ';hello=Hello',
|
|
625
450
|
'{;list}' => ';list=red,green,blue',
|
|
626
451
|
'{;list*}' => ';list=red;list=green;list=blue',
|
|
627
|
-
'{;keys}' =>
|
|
628
|
-
|
|
629
|
-
';keys=dot,.,semi,%3B,comma,%2C',
|
|
630
|
-
';keys=comma,%2C,semi,%3B,dot,.',
|
|
631
|
-
';keys=semi,%3B,comma,%2C,dot,.',
|
|
632
|
-
';keys=dot,.,comma,%2C,semi,%3B',
|
|
633
|
-
';keys=comma,%2C,dot,.,semi,%3B'
|
|
634
|
-
],
|
|
635
|
-
'{;keys*}' => [
|
|
636
|
-
';semi=%3B;dot=.;comma=%2C',
|
|
637
|
-
';dot=.;semi=%3B;comma=%2C',
|
|
638
|
-
';comma=%2C;semi=%3B;dot=.',
|
|
639
|
-
';semi=%3B;comma=%2C;dot=.',
|
|
640
|
-
';dot=.;comma=%2C;semi=%3B',
|
|
641
|
-
';comma=%2C;dot=.;semi=%3B'
|
|
642
|
-
]
|
|
452
|
+
'{;keys}' => ';keys=semi,%3B,dot,.,comma,%2C',
|
|
453
|
+
'{;keys*}' => ';semi=%3B;dot=.;comma=%2C',
|
|
643
454
|
}
|
|
644
455
|
end
|
|
645
456
|
context "form query expansion (?)" do
|
|
@@ -652,22 +463,8 @@ describe "Expansion" do
|
|
|
652
463
|
'{?var:3}' => '?var=val',
|
|
653
464
|
'{?list}' => '?list=red,green,blue',
|
|
654
465
|
'{?list*}' => '?list=red&list=green&list=blue',
|
|
655
|
-
'{?keys}' =>
|
|
656
|
-
|
|
657
|
-
'?keys=dot,.,semi,%3B,comma,%2C',
|
|
658
|
-
'?keys=comma,%2C,semi,%3B,dot,.',
|
|
659
|
-
'?keys=semi,%3B,comma,%2C,dot,.',
|
|
660
|
-
'?keys=dot,.,comma,%2C,semi,%3B',
|
|
661
|
-
'?keys=comma,%2C,dot,.,semi,%3B'
|
|
662
|
-
],
|
|
663
|
-
'{?keys*}' => [
|
|
664
|
-
'?semi=%3B&dot=.&comma=%2C',
|
|
665
|
-
'?dot=.&semi=%3B&comma=%2C',
|
|
666
|
-
'?comma=%2C&semi=%3B&dot=.',
|
|
667
|
-
'?semi=%3B&comma=%2C&dot=.',
|
|
668
|
-
'?dot=.&comma=%2C&semi=%3B',
|
|
669
|
-
'?comma=%2C&dot=.&semi=%3B'
|
|
670
|
-
]
|
|
466
|
+
'{?keys}' => '?keys=semi,%3B,dot,.,comma,%2C',
|
|
467
|
+
'{?keys*}' => '?semi=%3B&dot=.&comma=%2C',
|
|
671
468
|
}
|
|
672
469
|
end
|
|
673
470
|
context "form query expansion (&)" do
|
|
@@ -680,22 +477,8 @@ describe "Expansion" do
|
|
|
680
477
|
'{&var:3}' => '&var=val',
|
|
681
478
|
'{&list}' => '&list=red,green,blue',
|
|
682
479
|
'{&list*}' => '&list=red&list=green&list=blue',
|
|
683
|
-
'{&keys}' =>
|
|
684
|
-
|
|
685
|
-
'&keys=dot,.,semi,%3B,comma,%2C',
|
|
686
|
-
'&keys=comma,%2C,semi,%3B,dot,.',
|
|
687
|
-
'&keys=semi,%3B,comma,%2C,dot,.',
|
|
688
|
-
'&keys=dot,.,comma,%2C,semi,%3B',
|
|
689
|
-
'&keys=comma,%2C,dot,.,semi,%3B'
|
|
690
|
-
],
|
|
691
|
-
'{&keys*}' => [
|
|
692
|
-
'&semi=%3B&dot=.&comma=%2C',
|
|
693
|
-
'&dot=.&semi=%3B&comma=%2C',
|
|
694
|
-
'&comma=%2C&semi=%3B&dot=.',
|
|
695
|
-
'&semi=%3B&comma=%2C&dot=.',
|
|
696
|
-
'&dot=.&comma=%2C&semi=%3B',
|
|
697
|
-
'&comma=%2C&dot=.&semi=%3B'
|
|
698
|
-
]
|
|
480
|
+
'{&keys}' => '&keys=semi,%3B,dot,.,comma,%2C',
|
|
481
|
+
'{&keys*}' => '&semi=%3B&dot=.&comma=%2C',
|
|
699
482
|
}
|
|
700
483
|
end
|
|
701
484
|
context "non-string key in match data" do
|
|
@@ -949,6 +732,36 @@ describe Addressable::Template do
|
|
|
949
732
|
)
|
|
950
733
|
end
|
|
951
734
|
end
|
|
735
|
+
context "issue #307 - partial_expand form query with nil params" do
|
|
736
|
+
subject do
|
|
737
|
+
Addressable::Template.new("http://example.com/{?one,two,three}/")
|
|
738
|
+
end
|
|
739
|
+
it "builds a new pattern with two=nil" do
|
|
740
|
+
expect(subject.partial_expand(two: nil).pattern).to eq(
|
|
741
|
+
"http://example.com/{?one}{&three}/"
|
|
742
|
+
)
|
|
743
|
+
end
|
|
744
|
+
it "builds a new pattern with one=nil and two=nil" do
|
|
745
|
+
expect(subject.partial_expand(one: nil, two: nil).pattern).to eq(
|
|
746
|
+
"http://example.com/{?three}/"
|
|
747
|
+
)
|
|
748
|
+
end
|
|
749
|
+
it "builds a new pattern with one=1 and two=nil" do
|
|
750
|
+
expect(subject.partial_expand(one: 1, two: nil).pattern).to eq(
|
|
751
|
+
"http://example.com/?one=1{&three}/"
|
|
752
|
+
)
|
|
753
|
+
end
|
|
754
|
+
it "builds a new pattern with one=nil and two=2" do
|
|
755
|
+
expect(subject.partial_expand(one: nil, two: 2).pattern).to eq(
|
|
756
|
+
"http://example.com/?two=2{&three}/"
|
|
757
|
+
)
|
|
758
|
+
end
|
|
759
|
+
it "builds a new pattern with one=nil" do
|
|
760
|
+
expect(subject.partial_expand(one: nil).pattern).to eq(
|
|
761
|
+
"http://example.com/{?two}{&three}/"
|
|
762
|
+
)
|
|
763
|
+
end
|
|
764
|
+
end
|
|
952
765
|
context "partial_expand with query string" do
|
|
953
766
|
subject {
|
|
954
767
|
Addressable::Template.new("http://example.com/{?two,one}/")
|
|
@@ -969,6 +782,37 @@ describe Addressable::Template do
|
|
|
969
782
|
)
|
|
970
783
|
end
|
|
971
784
|
end
|
|
785
|
+
context "partial expand with unicode values" do
|
|
786
|
+
subject do
|
|
787
|
+
Addressable::Template.new("http://example.com/{resource}/{query}/")
|
|
788
|
+
end
|
|
789
|
+
it "normalizes unicode by default" do
|
|
790
|
+
template = subject.partial_expand("query" => "Cafe\u0301")
|
|
791
|
+
expect(template.pattern).to eq(
|
|
792
|
+
"http://example.com/{resource}/Caf%C3%A9/"
|
|
793
|
+
)
|
|
794
|
+
end
|
|
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
|
+
|
|
809
|
+
it "does not normalize unicode when byte semantics requested" do
|
|
810
|
+
template = subject.partial_expand({"query" => "Cafe\u0301"}, nil, false)
|
|
811
|
+
expect(template.pattern).to eq(
|
|
812
|
+
"http://example.com/{resource}/Cafe%CC%81/"
|
|
813
|
+
)
|
|
814
|
+
end
|
|
815
|
+
end
|
|
972
816
|
end
|
|
973
817
|
describe "Partial expand with strings" do
|
|
974
818
|
context "partial_expand with two simple values" do
|
|
@@ -1013,6 +857,31 @@ describe Addressable::Template do
|
|
|
1013
857
|
end
|
|
1014
858
|
end
|
|
1015
859
|
describe "Expand" do
|
|
860
|
+
context "expand with unicode values" do
|
|
861
|
+
subject do
|
|
862
|
+
Addressable::Template.new("http://example.com/search/{query}/")
|
|
863
|
+
end
|
|
864
|
+
it "normalizes unicode by default" do
|
|
865
|
+
uri = subject.expand("query" => "Cafe\u0301").to_str
|
|
866
|
+
expect(uri).to eq("http://example.com/search/Caf%C3%A9/")
|
|
867
|
+
end
|
|
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
|
+
|
|
880
|
+
it "does not normalize unicode when byte semantics requested" do
|
|
881
|
+
uri = subject.expand({ "query" => "Cafe\u0301" }, nil, false).to_str
|
|
882
|
+
expect(uri).to eq("http://example.com/search/Cafe%CC%81/")
|
|
883
|
+
end
|
|
884
|
+
end
|
|
1016
885
|
context "expand with a processor" do
|
|
1017
886
|
subject {
|
|
1018
887
|
Addressable::Template.new("http://example.com/search/{query}/")
|
|
@@ -1276,6 +1145,14 @@ describe Addressable::Template do
|
|
|
1276
1145
|
expect(subject).not_to match("foo_bar*")
|
|
1277
1146
|
expect(subject).not_to match("foo_bar:20")
|
|
1278
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
|
|
1279
1156
|
end
|
|
1280
1157
|
context "VARIABLE_LIST" do
|
|
1281
1158
|
subject { Addressable::Template::VARIABLE_LIST }
|