addressable 2.0.2 → 2.1.0

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,3 +1,4 @@
1
+ # encoding:utf-8
1
2
  #--
2
3
  # Addressable, Copyright (c) 2006-2008 Bob Aman
3
4
  #
@@ -26,8 +27,8 @@ if !defined?(Addressable::VERSION)
26
27
  module Addressable
27
28
  module VERSION #:nodoc:
28
29
  MAJOR = 2
29
- MINOR = 0
30
- TINY = 2
30
+ MINOR = 1
31
+ TINY = 0
31
32
 
32
33
  STRING = [MAJOR, MINOR, TINY].join('.')
33
34
  end
@@ -1,4 +1,4 @@
1
- # coding:utf-8
1
+ # encoding:utf-8
2
2
  #--
3
3
  # Addressable, Copyright (c) 2006-2007 Bob Aman
4
4
  #
@@ -39,16 +39,17 @@ describe Addressable::IDNA, "when converting from unicode to ASCII" do
39
39
  end
40
40
 
41
41
  it "should convert 'www.Iñtërnâtiônàlizætiøn.com' correctly" do
42
+ "www.Iñtërnâtiônàlizætiøn.com"
42
43
  Addressable::IDNA.to_ascii(
43
- "www.I\303\261t\303\253rn\303\242ti\303\264" +
44
- "n\303\240liz\303\246ti\303\270n.com"
44
+ "www.I\xC3\xB1t\xC3\xABrn\xC3\xA2ti\xC3\xB4" +
45
+ "n\xC3\xA0liz\xC3\xA6ti\xC3\xB8n.com"
45
46
  ).should == "www.xn--itrntinliztin-vdb0a5exd8ewcye.com"
46
47
  end
47
48
 
48
49
  it "should convert 'www.Iñtërnâtiônàlizætiøn.com' correctly" do
49
50
  Addressable::IDNA.to_ascii(
50
- "www.In\314\203te\314\210rna\314\202tio\314\202n" +
51
- "a\314\200liz\303\246ti\303\270n.com"
51
+ "www.In\xCC\x83te\xCC\x88rna\xCC\x82tio\xCC\x82n" +
52
+ "a\xCC\x80liz\xC3\xA6ti\xC3\xB8n.com"
52
53
  ).should == "www.xn--itrntinliztin-vdb0a5exd8ewcye.com"
53
54
  end
54
55
 
@@ -0,0 +1,2111 @@
1
+ # encoding:utf-8
2
+ #--
3
+ # Addressable, Copyright (c) 2006-2007 Bob Aman
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ #++
24
+
25
+ $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../../lib'))
26
+ $:.uniq!
27
+
28
+ require "addressable/uri"
29
+ require "addressable/template"
30
+
31
+ if !"".respond_to?("force_encoding")
32
+ class String
33
+ def force_encoding(encoding)
34
+ @encoding = encoding
35
+ end
36
+
37
+ def encoding
38
+ @encoding ||= Encoding::ASCII_8BIT
39
+ end
40
+ end
41
+
42
+ class Encoding
43
+ def initialize(name)
44
+ @name = name
45
+ end
46
+
47
+ def to_s
48
+ return @name
49
+ end
50
+
51
+ UTF_8 = Encoding.new("UTF-8")
52
+ ASCII_8BIT = Encoding.new("US-ASCII")
53
+ end
54
+ end
55
+
56
+ class ExampleProcessor
57
+ def self.validate(name, value)
58
+ return !!(value =~ /^[\w ]+$/) if name == "query"
59
+ return true
60
+ end
61
+
62
+ def self.transform(name, value)
63
+ return value.gsub(/ /, "+") if name == "query"
64
+ return value
65
+ end
66
+
67
+ def self.restore(name, value)
68
+ return value.gsub(/\+/, " ") if name == "query"
69
+ return value.tr("A-Za-z", "N-ZA-Mn-za-m") if name == "rot13"
70
+ return value
71
+ end
72
+
73
+ def self.match(name)
74
+ return ".*?" if name == "first"
75
+ return ".*"
76
+ end
77
+ end
78
+
79
+ class SlashlessProcessor
80
+ def self.match(name)
81
+ return "[^/\\n]*"
82
+ end
83
+ end
84
+
85
+ class NoOpProcessor
86
+ def self.transform(name, value)
87
+ value
88
+ end
89
+ end
90
+
91
+ describe Addressable::Template do
92
+ it "should raise a TypeError for invalid patterns" do
93
+ (lambda do
94
+ Addressable::Template.new(42)
95
+ end).should raise_error(TypeError, "Can't convert Fixnum into String.")
96
+ end
97
+ end
98
+
99
+ describe Addressable::Template, "created with the pattern '/'" do
100
+ before do
101
+ @template = Addressable::Template.new("/")
102
+ end
103
+
104
+ it "should have no variables" do
105
+ @template.variables.should be_empty
106
+ end
107
+
108
+ it "should have the correct mapping when extracting from '/'" do
109
+ @template.extract("/").should == {}
110
+ end
111
+ end
112
+
113
+ describe Addressable::URI, "when parsed from '/one/'" do
114
+ before do
115
+ @uri = Addressable::URI.parse("/one/")
116
+ end
117
+
118
+ it "should not match the pattern '/two/'" do
119
+ Addressable::Template.new("/two/").extract(@uri).should == nil
120
+ end
121
+
122
+ it "should have the correct mapping when extracting values " +
123
+ "using the pattern '/{number}/'" do
124
+ Addressable::Template.new(
125
+ "/{number}/"
126
+ ).extract(@uri).should == {"number" => "one"}
127
+ end
128
+ end
129
+
130
+ describe Addressable::Template, "created with the pattern '/{number}/'" do
131
+ before do
132
+ @template = Addressable::Template.new("/{number}/")
133
+ end
134
+
135
+ it "should have the variables ['number']" do
136
+ @template.variables.should == ["number"]
137
+ end
138
+
139
+ it "should not match the pattern '/'" do
140
+ @template.match("/").should == nil
141
+ end
142
+
143
+ it "should match the pattern '/two/'" do
144
+ @template.match("/two/").mapping.should == {"number" => "two"}
145
+ end
146
+ end
147
+
148
+ describe Addressable::Template,
149
+ "created with the pattern '/{number}/{number}/'" do
150
+ before do
151
+ @template = Addressable::Template.new("/{number}/{number}/")
152
+ end
153
+
154
+ it "should have one variable" do
155
+ @template.variables.should == ["number"]
156
+ end
157
+
158
+ it "should have the correct mapping when extracting from '/1/1/'" do
159
+ @template.extract("/1/1/").should == {"number" => "1"}
160
+ end
161
+
162
+ it "should not match '/1/2/'" do
163
+ @template.match("/1/2/").should == nil
164
+ end
165
+
166
+ it "should not match '/2/1/'" do
167
+ @template.match("/2/1/").should == nil
168
+ end
169
+
170
+ it "should not match '/1/'" do
171
+ @template.match("/1/").should == nil
172
+ end
173
+
174
+ it "should not match '/1/1/1/'" do
175
+ @template.match("/1/1/1/").should == nil
176
+ end
177
+
178
+ it "should not match '/1/2/3/'" do
179
+ @template.match("/1/2/3/").should == nil
180
+ end
181
+ end
182
+
183
+ describe Addressable::Template,
184
+ "created with the pattern '/{number}{-prefix|.|number}'" do
185
+ before do
186
+ @template = Addressable::Template.new("/{number}{-prefix|.|number}")
187
+ end
188
+
189
+ it "should have one variable" do
190
+ @template.variables.should == ["number"]
191
+ end
192
+
193
+ it "should have the correct mapping when extracting from '/1.1'" do
194
+ @template.extract("/1.1").should == {"number" => "1"}
195
+ end
196
+
197
+ it "should have the correct mapping when extracting from '/99.99'" do
198
+ @template.extract("/99.99").should == {"number" => "99"}
199
+ end
200
+
201
+ it "should not match '/1.2'" do
202
+ @template.match("/1.2").should == nil
203
+ end
204
+
205
+ it "should not match '/2.1'" do
206
+ @template.match("/2.1").should == nil
207
+ end
208
+
209
+ it "should not match '/1'" do
210
+ @template.match("/1").should == nil
211
+ end
212
+
213
+ it "should not match '/1.1.1'" do
214
+ @template.match("/1.1.1").should == nil
215
+ end
216
+
217
+ it "should not match '/1.23'" do
218
+ @template.match("/1.23").should == nil
219
+ end
220
+ end
221
+
222
+ describe Addressable::Template,
223
+ "created with the pattern '/{number}/{-suffix|/|number}'" do
224
+ before do
225
+ @template = Addressable::Template.new("/{number}/{-suffix|/|number}")
226
+ end
227
+
228
+ it "should have one variable" do
229
+ @template.variables.should == ["number"]
230
+ end
231
+
232
+ it "should have the correct mapping when extracting from '/1/1/'" do
233
+ @template.extract("/1/1/").should == {"number" => "1"}
234
+ end
235
+
236
+ it "should have the correct mapping when extracting from '/99/99/'" do
237
+ @template.extract("/99/99/").should == {"number" => "99"}
238
+ end
239
+
240
+ it "should not match '/1/1'" do
241
+ @template.match("/1/1").should == nil
242
+ end
243
+
244
+ it "should not match '/11/'" do
245
+ @template.match("/11/").should == nil
246
+ end
247
+
248
+ it "should not match '/1/2/'" do
249
+ @template.match("/1/2/").should == nil
250
+ end
251
+
252
+ it "should not match '/2/1/'" do
253
+ @template.match("/2/1/").should == nil
254
+ end
255
+
256
+ it "should not match '/1/'" do
257
+ @template.match("/1/").should == nil
258
+ end
259
+
260
+ it "should not match '/1/1/1/'" do
261
+ @template.match("/1/1/1/").should == nil
262
+ end
263
+
264
+ it "should not match '/1/23/'" do
265
+ @template.match("/1/23/").should == nil
266
+ end
267
+ end
268
+
269
+ describe Addressable::Template,
270
+ "created with the pattern '/{number}/?{-join|&|number}'" do
271
+ before do
272
+ @template = Addressable::Template.new(
273
+ "/{number}/?{-join|&|number,letter}"
274
+ )
275
+ end
276
+
277
+ it "should have one variable" do
278
+ @template.variables.should == ["number", "letter"]
279
+ end
280
+
281
+ it "should have the correct mapping when extracting from '/1/?number=1'" do
282
+ @template.extract("/1/?number=1").should == {"number" => "1"}
283
+ end
284
+
285
+ it "should have the correct mapping when extracting " +
286
+ "from '/99/?number=99'" do
287
+ @template.extract("/99/?number=99").should == {"number" => "99"}
288
+ end
289
+
290
+ it "should have the correct mapping when extracting " +
291
+ "from '/1/?number=1&letter=a'" do
292
+ @template.extract("/1/?number=1&letter=a").should == {
293
+ "number" => "1", "letter" => "a"
294
+ }
295
+ end
296
+
297
+ it "should not match '/1/?number=1&bogus=foo'" do
298
+ @template.match("/1/?number=1&bogus=foo").should == nil
299
+ end
300
+
301
+ it "should not match '/1/?number=2'" do
302
+ @template.match("/1/?number=2").should == nil
303
+ end
304
+
305
+ it "should not match '/2/?number=1'" do
306
+ @template.match("/2/?number=1").should == nil
307
+ end
308
+
309
+ it "should not match '/1/?'" do
310
+ @template.match("/1/?").should == nil
311
+ end
312
+ end
313
+
314
+ describe Addressable::Template,
315
+ "created with the pattern '/{number}/{-list|/|number}/'" do
316
+ before do
317
+ @template = Addressable::Template.new("/{number}/{-list|/|number}/")
318
+ end
319
+
320
+ it "should have one variable" do
321
+ @template.variables.should == ["number"]
322
+ end
323
+
324
+ it "should not match '/1/1/'" do
325
+ @template.match("/1/1/").should == nil
326
+ end
327
+
328
+ it "should not match '/1/2/'" do
329
+ @template.match("/1/2/").should == nil
330
+ end
331
+
332
+ it "should not match '/2/1/'" do
333
+ @template.match("/2/1/").should == nil
334
+ end
335
+
336
+ it "should not match '/1/1/1/'" do
337
+ @template.match("/1/1/1/").should == nil
338
+ end
339
+
340
+ it "should not match '/1/1/1/1/'" do
341
+ @template.match("/1/1/1/1/").should == nil
342
+ end
343
+ end
344
+
345
+ describe Addressable::Template, "created with the pattern " +
346
+ "'http://www.example.com/?{-join|&|query,number}'" do
347
+ before do
348
+ @template = Addressable::Template.new(
349
+ "http://www.example.com/?{-join|&|query,number}"
350
+ )
351
+ end
352
+
353
+ it "when inspected, should have the correct class name" do
354
+ @template.inspect.should include("Addressable::Template")
355
+ end
356
+
357
+ it "when inspected, should have the correct object id" do
358
+ @template.inspect.should include("%#0x" % @template.object_id)
359
+ end
360
+
361
+ it "should have the variables ['query', 'number']" do
362
+ @template.variables.should == ["query", "number"]
363
+ end
364
+
365
+ it "should not match the pattern 'http://www.example.com/'" do
366
+ @template.match("http://www.example.com/").should == nil
367
+ end
368
+
369
+ it "should match the pattern 'http://www.example.com/?'" do
370
+ @template.match("http://www.example.com/?").mapping.should == {}
371
+ end
372
+
373
+ it "should match the pattern " +
374
+ "'http://www.example.com/?query=mycelium'" do
375
+ match = @template.match(
376
+ "http://www.example.com/?query=mycelium"
377
+ )
378
+ match.variables.should == ["query", "number"]
379
+ match.values.should == ["mycelium", nil]
380
+ match.mapping.should == {"query" => "mycelium"}
381
+ match.inspect.should =~ /MatchData/
382
+ end
383
+
384
+ it "should match the pattern " +
385
+ "'http://www.example.com/?query=mycelium&number=100'" do
386
+ @template.match(
387
+ "http://www.example.com/?query=mycelium&number=100"
388
+ ).mapping.should == {"query" => "mycelium", "number" => "100"}
389
+ end
390
+ end
391
+
392
+ describe Addressable::URI, "when parsed from '/one/two/'" do
393
+ before do
394
+ @uri = Addressable::URI.parse("/one/two/")
395
+ end
396
+
397
+ it "should not match the pattern '/{number}/' " +
398
+ "with the SlashlessProcessor" do
399
+ Addressable::Template.new(
400
+ "/{number}/"
401
+ ).extract(@uri, SlashlessProcessor).should == nil
402
+ end
403
+
404
+ it "should have the correct mapping when extracting values " +
405
+ "using the pattern '/{number}/' without a processor" do
406
+ Addressable::Template.new("/{number}/").extract(@uri).should == {
407
+ "number" => "one/two"
408
+ }
409
+ end
410
+
411
+ it "should have the correct mapping when extracting values " +
412
+ "using the pattern '/{first}/{second}/' with the SlashlessProcessor" do
413
+ Addressable::Template.new(
414
+ "/{first}/{second}/"
415
+ ).extract(@uri, SlashlessProcessor).should == {
416
+ "first" => "one",
417
+ "second" => "two"
418
+ }
419
+ end
420
+ end
421
+
422
+ describe Addressable::URI, "when parsed from " +
423
+ "'http://example.com/search/an+example+search+query/'" do
424
+ before do
425
+ @uri = Addressable::URI.parse(
426
+ "http://example.com/search/an+example+search+query/")
427
+ end
428
+
429
+ it "should have the correct mapping when extracting values using " +
430
+ "the pattern 'http://example.com/search/{query}/' with the " +
431
+ "ExampleProcessor" do
432
+ Addressable::Template.new(
433
+ "http://example.com/search/{query}/"
434
+ ).extract(@uri, ExampleProcessor).should == {
435
+ "query" => "an example search query"
436
+ }
437
+ end
438
+
439
+ it "should have the correct mapping when extracting values " +
440
+ "using the pattern " +
441
+ "'http://example.com/search/{-list|+|query}/'" do
442
+ Addressable::Template.new(
443
+ "http://example.com/search/{-list|+|query}/"
444
+ ).extract(@uri).should == {
445
+ "query" => ["an", "example", "search", "query"]
446
+ }
447
+ end
448
+
449
+ it "should return nil when extracting values using " +
450
+ "a non-matching pattern" do
451
+ Addressable::Template.new(
452
+ "http://bogus.com/{thingy}/"
453
+ ).extract(@uri).should == nil
454
+ end
455
+ end
456
+
457
+ describe Addressable::URI, "when parsed from " +
458
+ "'http://example.com/a/b/c/'" do
459
+ before do
460
+ @uri = Addressable::URI.parse(
461
+ "http://example.com/a/b/c/")
462
+ end
463
+
464
+ it "should have the correct mapping when extracting values " +
465
+ "using the pattern " +
466
+ "'http://example.com/{first}/{second}/' with the ExampleProcessor" do
467
+ Addressable::Template.new(
468
+ "http://example.com/{first}/{second}/"
469
+ ).extract(@uri, ExampleProcessor).should == {
470
+ "first" => "a",
471
+ "second" => "b/c"
472
+ }
473
+ end
474
+
475
+ it "should have the correct mapping when extracting values " +
476
+ "using the pattern " +
477
+ "'http://example.com/{first}/{-list|/|second}/'" do
478
+ Addressable::Template.new(
479
+ "http://example.com/{first}/{-list|/|second}/"
480
+ ).extract(@uri).should == {
481
+ "first" => "a",
482
+ "second" => ["b", "c"]
483
+ }
484
+ end
485
+
486
+ it "should have the correct mapping when extracting values " +
487
+ "using the pattern " +
488
+ "'http://example.com/{first}/{-list|/|rot13}/' " +
489
+ "with the ExampleProcessor" do
490
+ Addressable::Template.new(
491
+ "http://example.com/{first}/{-list|/|rot13}/"
492
+ ).extract(@uri, ExampleProcessor).should == {
493
+ "first" => "a",
494
+ "rot13" => ["o", "p"]
495
+ }
496
+ end
497
+
498
+ it "should have the correct mapping when extracting values " +
499
+ "using the pattern " +
500
+ "'http://example.com/{-list|/|rot13}/' " +
501
+ "with the ExampleProcessor" do
502
+ Addressable::Template.new(
503
+ "http://example.com/{-list|/|rot13}/"
504
+ ).extract(@uri, ExampleProcessor).should == {
505
+ "rot13" => ["n", "o", "p"]
506
+ }
507
+ end
508
+
509
+ it "should not map to anything when extracting values " +
510
+ "using the pattern " +
511
+ "'http://example.com/{-list|/|rot13}/'" do
512
+ Addressable::Template.new(
513
+ "http://example.com/{-join|/|a,b,c}/"
514
+ ).extract(@uri).should == nil
515
+ end
516
+ end
517
+
518
+ describe Addressable::URI, "when parsed from " +
519
+ "'http://example.com/?a=one&b=two&c=three'" do
520
+ before do
521
+ @uri = Addressable::URI.parse("http://example.com/?a=one&b=two&c=three")
522
+ end
523
+
524
+ it "should have the correct mapping when extracting values " +
525
+ "using the pattern " +
526
+ "'http://example.com/?{-join|&|a,b,c}'" do
527
+ Addressable::Template.new(
528
+ "http://example.com/?{-join|&|a,b,c}"
529
+ ).extract(@uri).should == {
530
+ "a" => "one",
531
+ "b" => "two",
532
+ "c" => "three"
533
+ }
534
+ end
535
+ end
536
+
537
+ describe Addressable::URI, "when parsed from " +
538
+ "'http://example.com/?rot13=frperg'" do
539
+ before do
540
+ @uri = Addressable::URI.parse("http://example.com/?rot13=frperg")
541
+ end
542
+
543
+ it "should have the correct mapping when extracting values " +
544
+ "using the pattern " +
545
+ "'http://example.com/?{-join|&|rot13}' with the ExampleProcessor" do
546
+ Addressable::Template.new(
547
+ "http://example.com/?{-join|&|rot13}"
548
+ ).extract(@uri, ExampleProcessor).should == {
549
+ "rot13" => "secret"
550
+ }
551
+ end
552
+ end
553
+
554
+ describe Addressable::URI, "when parsed from " +
555
+ "'http://example.org///something///'" do
556
+ before do
557
+ @uri = Addressable::URI.parse("http://example.org///something///")
558
+ end
559
+
560
+ it "should have the correct mapping when extracting values " +
561
+ "using the pattern 'http://example.org{-prefix|/|parts}/'" do
562
+ Addressable::Template.new(
563
+ "http://example.org{-prefix|/|parts}/"
564
+ ).extract(@uri).should == {
565
+ "parts" => ["", "", "something", "", ""]
566
+ }
567
+ end
568
+
569
+ it "should have the correct mapping when extracting values " +
570
+ "using the pattern 'http://example.org/{-suffix|/|parts}'" do
571
+ Addressable::Template.new(
572
+ "http://example.org/{-suffix|/|parts}"
573
+ ).extract(@uri).should == {
574
+ "parts" => ["", "", "something", "", ""]
575
+ }
576
+ end
577
+
578
+ it "should have the correct mapping when extracting values " +
579
+ "using the pattern 'http://example.org/{-list|/|parts}'" do
580
+ Addressable::Template.new(
581
+ "http://example.org/{-list|/|parts}"
582
+ ).extract(@uri).should == {
583
+ "parts" => ["", "", "something", "", ""]
584
+ }
585
+ end
586
+ end
587
+
588
+ describe Addressable::URI, "when parsed from " +
589
+ "'http://example.com/one/spacer/two/'" do
590
+ before do
591
+ @uri = Addressable::URI.parse("http://example.com/one/spacer/two/")
592
+ end
593
+
594
+ it "should have the correct mapping when extracting values " +
595
+ "using the pattern " +
596
+ "'http://example.com/{first}/spacer/{second}/'" do
597
+ Addressable::Template.new(
598
+ "http://example.com/{first}/spacer/{second}/"
599
+ ).extract(@uri).should == {
600
+ "first" => "one",
601
+ "second" => "two"
602
+ }
603
+ end
604
+
605
+ it "should have the correct mapping when extracting values " +
606
+ "using the pattern " +
607
+ "'http://example.com{-prefix|/|stuff}/'" do
608
+ Addressable::Template.new(
609
+ "http://example.com{-prefix|/|stuff}/"
610
+ ).extract(@uri).should == {
611
+ "stuff" => ["one", "spacer", "two"]
612
+ }
613
+ end
614
+
615
+ it "should have the correct mapping when extracting values " +
616
+ "using the pattern " +
617
+ "'http://example.com/o{-prefix|/|stuff}/'" do
618
+ Addressable::Template.new(
619
+ "http://example.com/o{-prefix|/|stuff}/"
620
+ ).extract(@uri).should == nil
621
+ end
622
+
623
+ it "should have the correct mapping when extracting values " +
624
+ "using the pattern " +
625
+ "'http://example.com/{first}/spacer{-prefix|/|stuff}/'" do
626
+ Addressable::Template.new(
627
+ "http://example.com/{first}/spacer{-prefix|/|stuff}/"
628
+ ).extract(@uri).should == {
629
+ "first" => "one",
630
+ "stuff" => "two"
631
+ }
632
+ end
633
+
634
+ it "should not match anything when extracting values " +
635
+ "using the incorrect suffix pattern " +
636
+ "'http://example.com/{-prefix|/|stuff}/'" do
637
+ Addressable::Template.new(
638
+ "http://example.com/{-prefix|/|stuff}/"
639
+ ).extract(@uri).should == nil
640
+ end
641
+
642
+ it "should have the correct mapping when extracting values " +
643
+ "using the pattern " +
644
+ "'http://example.com{-prefix|/|rot13}/' with the ExampleProcessor" do
645
+ Addressable::Template.new(
646
+ "http://example.com{-prefix|/|rot13}/"
647
+ ).extract(@uri, ExampleProcessor).should == {
648
+ "rot13" => ["bar", "fcnpre", "gjb"]
649
+ }
650
+ end
651
+
652
+ it "should have the correct mapping when extracting values " +
653
+ "using the pattern " +
654
+ "'http://example.com{-prefix|/|rot13}' with the ExampleProcessor" do
655
+ Addressable::Template.new(
656
+ "http://example.com{-prefix|/|rot13}"
657
+ ).extract(@uri, ExampleProcessor).should == {
658
+ "rot13" => ["bar", "fcnpre", "gjb", ""]
659
+ }
660
+ end
661
+
662
+ it "should not match anything when extracting values " +
663
+ "using the incorrect suffix pattern " +
664
+ "'http://example.com/{-prefix|/|rot13}' with the ExampleProcessor" do
665
+ Addressable::Template.new(
666
+ "http://example.com/{-prefix|/|rot13}"
667
+ ).extract(@uri, ExampleProcessor).should == nil
668
+ end
669
+
670
+ it "should have the correct mapping when extracting values " +
671
+ "using the pattern " +
672
+ "'http://example.com/{-suffix|/|stuff}'" do
673
+ Addressable::Template.new(
674
+ "http://example.com/{-suffix|/|stuff}"
675
+ ).extract(@uri).should == {
676
+ "stuff" => ["one", "spacer", "two"]
677
+ }
678
+ end
679
+
680
+ it "should have the correct mapping when extracting values " +
681
+ "using the pattern " +
682
+ "'http://example.com/{-suffix|/|stuff}o'" do
683
+ Addressable::Template.new(
684
+ "http://example.com/{-suffix|/|stuff}o"
685
+ ).extract(@uri).should == nil
686
+ end
687
+
688
+ it "should have the correct mapping when extracting values " +
689
+ "using the pattern " +
690
+ "'http://example.com/o{-suffix|/|stuff}'" do
691
+ Addressable::Template.new(
692
+ "http://example.com/o{-suffix|/|stuff}"
693
+ ).extract(@uri).should == {"stuff"=>["ne", "spacer", "two"]}
694
+ end
695
+
696
+ it "should have the correct mapping when extracting values " +
697
+ "using the pattern " +
698
+ "'http://example.com/{first}/spacer/{-suffix|/|stuff}'" do
699
+ Addressable::Template.new(
700
+ "http://example.com/{first}/spacer/{-suffix|/|stuff}"
701
+ ).extract(@uri).should == {
702
+ "first" => "one",
703
+ "stuff" => "two"
704
+ }
705
+ end
706
+
707
+ it "should not match anything when extracting values " +
708
+ "using the incorrect suffix pattern " +
709
+ "'http://example.com/{-suffix|/|stuff}/'" do
710
+ Addressable::Template.new(
711
+ "http://example.com/{-suffix|/|stuff}/"
712
+ ).extract(@uri).should == nil
713
+ end
714
+
715
+ it "should have the correct mapping when extracting values " +
716
+ "using the pattern " +
717
+ "'http://example.com/{-suffix|/|rot13}' with the ExampleProcessor" do
718
+ Addressable::Template.new(
719
+ "http://example.com/{-suffix|/|rot13}"
720
+ ).extract(@uri, ExampleProcessor).should == {
721
+ "rot13" => ["bar", "fcnpre", "gjb"]
722
+ }
723
+ end
724
+
725
+ it "should have the correct mapping when extracting values " +
726
+ "using the pattern " +
727
+ "'http://example.com{-suffix|/|rot13}' with the ExampleProcessor" do
728
+ Addressable::Template.new(
729
+ "http://example.com{-suffix|/|rot13}"
730
+ ).extract(@uri, ExampleProcessor).should == {
731
+ "rot13" => ["", "bar", "fcnpre", "gjb"]
732
+ }
733
+ end
734
+
735
+ it "should not match anything when extracting values " +
736
+ "using the incorrect suffix pattern " +
737
+ "'http://example.com/{-suffix|/|rot13}/' with the ExampleProcessor" do
738
+ Addressable::Template.new(
739
+ "http://example.com/{-suffix|/|rot13}/"
740
+ ).extract(@uri, ExampleProcessor).should == nil
741
+ end
742
+ end
743
+
744
+ describe Addressable::URI, "when parsed from " +
745
+ "'http://example.com/?email=bob@sporkmonger.com'" do
746
+ before do
747
+ @uri = Addressable::URI.parse(
748
+ "http://example.com/?email=bob@sporkmonger.com"
749
+ )
750
+ end
751
+
752
+ it "should not match anything when extracting values " +
753
+ "using the incorrect opt pattern " +
754
+ "'http://example.com/?email={-opt|bogus@bogus.com|test}'" do
755
+ Addressable::Template.new(
756
+ "http://example.com/?email={-opt|bogus@bogus.com|test}"
757
+ ).extract(@uri).should == nil
758
+ end
759
+
760
+ it "should not match anything when extracting values " +
761
+ "using the incorrect neg pattern " +
762
+ "'http://example.com/?email={-neg|bogus@bogus.com|test}'" do
763
+ Addressable::Template.new(
764
+ "http://example.com/?email={-neg|bogus@bogus.com|test}"
765
+ ).extract(@uri).should == nil
766
+ end
767
+
768
+ it "should indicate a match when extracting values " +
769
+ "using the opt pattern " +
770
+ "'http://example.com/?email={-opt|bob@sporkmonger.com|test}'" do
771
+ Addressable::Template.new(
772
+ "http://example.com/?email={-opt|bob@sporkmonger.com|test}"
773
+ ).extract(@uri).should == {}
774
+ end
775
+
776
+ it "should indicate a match when extracting values " +
777
+ "using the neg pattern " +
778
+ "'http://example.com/?email={-neg|bob@sporkmonger.com|test}'" do
779
+ Addressable::Template.new(
780
+ "http://example.com/?email={-neg|bob@sporkmonger.com|test}"
781
+ ).extract(@uri).should == {}
782
+ end
783
+ end
784
+
785
+ describe Addressable::URI, "when parsed from " +
786
+ "'http://example.com/?email='" do
787
+ before do
788
+ @uri = Addressable::URI.parse(
789
+ "http://example.com/?email="
790
+ )
791
+ end
792
+
793
+ it "should indicate a match when extracting values " +
794
+ "using the opt pattern " +
795
+ "'http://example.com/?email={-opt|bob@sporkmonger.com|test}'" do
796
+ Addressable::Template.new(
797
+ "http://example.com/?email={-opt|bob@sporkmonger.com|test}"
798
+ ).extract(@uri).should == {}
799
+ end
800
+
801
+ it "should indicate a match when extracting values " +
802
+ "using the neg pattern " +
803
+ "'http://example.com/?email={-neg|bob@sporkmonger.com|test}'" do
804
+ Addressable::Template.new(
805
+ "http://example.com/?email={-neg|bob@sporkmonger.com|test}"
806
+ ).extract(@uri).should == {}
807
+ end
808
+ end
809
+
810
+ describe Addressable::URI, "when parsed from " +
811
+ "'http://example.com/a/b/c/?one=1&two=2#foo'" do
812
+ before do
813
+ @uri = Addressable::URI.parse(
814
+ "http://example.com/a/b/c/?one=1&two=2#foo"
815
+ )
816
+ end
817
+
818
+ it "should have the correct mapping when extracting values " +
819
+ "using the pattern " +
820
+ "'http://{host}/{-suffix|/|segments}?{-join|&|one,two}\#{fragment}'" do
821
+ Addressable::Template.new(
822
+ "http://{host}/{-suffix|/|segments}?{-join|&|one,two}\#{fragment}"
823
+ ).extract(@uri).should == {
824
+ "host" => "example.com",
825
+ "segments" => ["a", "b", "c"],
826
+ "one" => "1",
827
+ "two" => "2",
828
+ "fragment" => "foo"
829
+ }
830
+ end
831
+
832
+ it "should not match when extracting values " +
833
+ "using the pattern " +
834
+ "'http://{host}/{-suffix|/|segments}?{-join|&|one}\#{fragment}'" do
835
+ Addressable::Template.new(
836
+ "http://{host}/{-suffix|/|segments}?{-join|&|one}\#{fragment}"
837
+ ).extract(@uri).should == nil
838
+ end
839
+
840
+ it "should not match when extracting values " +
841
+ "using the pattern " +
842
+ "'http://{host}/{-suffix|/|segments}?{-join|&|bogus}\#{fragment}'" do
843
+ Addressable::Template.new(
844
+ "http://{host}/{-suffix|/|segments}?{-join|&|bogus}\#{fragment}"
845
+ ).extract(@uri).should == nil
846
+ end
847
+
848
+ it "should not match when extracting values " +
849
+ "using the pattern " +
850
+ "'http://{host}/{-suffix|/|segments}?" +
851
+ "{-join|&|one,bogus}\#{fragment}'" do
852
+ Addressable::Template.new(
853
+ "http://{host}/{-suffix|/|segments}?{-join|&|one,bogus}\#{fragment}"
854
+ ).extract(@uri).should == nil
855
+ end
856
+
857
+ it "should not match when extracting values " +
858
+ "using the pattern " +
859
+ "'http://{host}/{-suffix|/|segments}?" +
860
+ "{-join|&|one,two,bogus}\#{fragment}'" do
861
+ Addressable::Template.new(
862
+ "http://{host}/{-suffix|/|segments}?{-join|&|one,two,bogus}\#{fragment}"
863
+ ).extract(@uri).should == {
864
+ "host" => "example.com",
865
+ "segments" => ["a", "b", "c"],
866
+ "one" => "1",
867
+ "two" => "2",
868
+ "fragment" => "foo"
869
+ }
870
+ end
871
+ end
872
+
873
+ describe Addressable::URI, "when given a pattern with bogus operators" do
874
+ before do
875
+ @uri = Addressable::URI.parse("http://example.com/a/b/c/")
876
+ end
877
+
878
+ it "should raise an InvalidTemplateOperatorError" do
879
+ (lambda do
880
+ Addressable::Template.new(
881
+ "http://example.com/{-bogus|/|a,b,c}/"
882
+ ).extract(@uri)
883
+ end).should raise_error(
884
+ Addressable::Template::InvalidTemplateOperatorError
885
+ )
886
+ end
887
+
888
+ it "should raise an InvalidTemplateOperatorError" do
889
+ (lambda do
890
+ Addressable::Template.new(
891
+ "http://example.com{-prefix|/|a,b,c}/"
892
+ ).extract(@uri)
893
+ end).should raise_error(
894
+ Addressable::Template::InvalidTemplateOperatorError
895
+ )
896
+ end
897
+
898
+ it "should raise an InvalidTemplateOperatorError" do
899
+ (lambda do
900
+ Addressable::Template.new(
901
+ "http://example.com/{-suffix|/|a,b,c}"
902
+ ).extract(@uri)
903
+ end).should raise_error(
904
+ Addressable::Template::InvalidTemplateOperatorError
905
+ )
906
+ end
907
+
908
+ it "should raise an InvalidTemplateOperatorError" do
909
+ (lambda do
910
+ Addressable::Template.new(
911
+ "http://example.com/{-list|/|a,b,c}/"
912
+ ).extract(@uri)
913
+ end).should raise_error(
914
+ Addressable::Template::InvalidTemplateOperatorError
915
+ )
916
+ end
917
+ end
918
+
919
+ describe Addressable::URI, "when given a mapping that contains an Array" do
920
+ before do
921
+ @mapping = {"query" => "an example search query".split(" ")}
922
+ end
923
+
924
+ it "should result in 'http://example.com/search/an+example+search+query/'" +
925
+ " when used to expand 'http://example.com/search/{-list|+|query}/'" do
926
+ Addressable::Template.new(
927
+ "http://example.com/search/{-list|+|query}/"
928
+ ).expand(@mapping).to_str.should ==
929
+ "http://example.com/search/an+example+search+query/"
930
+ end
931
+
932
+ it "should result in 'http://example.com/search/an+example+search+query/'" +
933
+ " when used to expand 'http://example.com/search/{-list|+|query}/'" +
934
+ " with a NoOpProcessor" do
935
+ Addressable::Template.new(
936
+ "http://example.com/search/{-list|+|query}/"
937
+ ).expand(@mapping, NoOpProcessor).to_str.should ==
938
+ "http://example.com/search/an+example+search+query/"
939
+ end
940
+ end
941
+
942
+ describe Addressable::URI, "when given an empty mapping" do
943
+ before do
944
+ @mapping = {}
945
+ end
946
+
947
+ it "should result in 'http://example.com/search/'" +
948
+ " when used to expand 'http://example.com/search/{-list|+|query}'" do
949
+ Addressable::Template.new(
950
+ "http://example.com/search/{-list|+|query}"
951
+ ).expand(@mapping).to_str.should == "http://example.com/search/"
952
+ end
953
+
954
+ it "should result in 'http://example.com'" +
955
+ " when used to expand 'http://example.com{-prefix|/|foo}'" do
956
+ Addressable::Template.new(
957
+ "http://example.com{-prefix|/|foo}"
958
+ ).expand(@mapping).to_str.should == "http://example.com"
959
+ end
960
+
961
+ it "should result in 'http://example.com'" +
962
+ " when used to expand 'http://example.com{-suffix|/|foo}'" do
963
+ Addressable::Template.new(
964
+ "http://example.com{-suffix|/|foo}"
965
+ ).expand(@mapping).to_str.should == "http://example.com"
966
+ end
967
+ end
968
+
969
+ describe Addressable::URI, "when given the template pattern " +
970
+ "'http://example.com/search/{query}/' " +
971
+ "to be processed with the ExampleProcessor" do
972
+ before do
973
+ @pattern = "http://example.com/search/{query}/"
974
+ end
975
+
976
+ it "should expand to " +
977
+ "'http://example.com/search/an+example+search+query/' " +
978
+ "with a mapping of {\"query\" => \"an example search query\"} " do
979
+ Addressable::Template.new(
980
+ "http://example.com/search/{query}/"
981
+ ).expand({
982
+ "query" => "an example search query"
983
+ }, ExampleProcessor).to_s.should ==
984
+ "http://example.com/search/an+example+search+query/"
985
+ end
986
+
987
+ it "should raise an error " +
988
+ "with a mapping of {\"query\" => \"invalid!\"}" do
989
+ (lambda do
990
+ Addressable::Template.new(
991
+ "http://example.com/search/{query}/"
992
+ ).expand({"query" => "invalid!"}, ExampleProcessor).to_s
993
+ end).should raise_error(Addressable::Template::InvalidTemplateValueError)
994
+ end
995
+ end
996
+
997
+ # Section 3.3.1 of the URI Template draft v 01
998
+ describe Addressable::URI, "when given the mapping supplied in " +
999
+ "Section 3.3.1 of the URI Template draft v 01" do
1000
+ before do
1001
+ @mapping = {
1002
+ "a" => "fred",
1003
+ "b" => "barney",
1004
+ "c" => "cheeseburger",
1005
+ "d" => "one two three",
1006
+ "e" => "20% tricky",
1007
+ "f" => "",
1008
+ "20" => "this-is-spinal-tap",
1009
+ "scheme" => "https",
1010
+ "p" => "quote=to+be+or+not+to+be",
1011
+ "q" => "hullo#world"
1012
+ }
1013
+ end
1014
+
1015
+ it "should result in 'http://example.org/page1#fred' " +
1016
+ "when used to expand 'http://example.org/page1\#{a}'" do
1017
+ Addressable::Template.new(
1018
+ "http://example.org/page1\#{a}"
1019
+ ).expand(@mapping).to_s.should == "http://example.org/page1#fred"
1020
+ end
1021
+
1022
+ it "should result in 'http://example.org/fred/barney/' " +
1023
+ "when used to expand 'http://example.org/{a}/{b}/'" do
1024
+ Addressable::Template.new(
1025
+ "http://example.org/{a}/{b}/"
1026
+ ).expand(@mapping).to_s.should == "http://example.org/fred/barney/"
1027
+ end
1028
+
1029
+ it "should result in 'http://example.org/fredbarney/' " +
1030
+ "when used to expand 'http://example.org/{a}{b}/'" do
1031
+ Addressable::Template.new(
1032
+ "http://example.org/{a}{b}/"
1033
+ ).expand(@mapping).to_s.should == "http://example.org/fredbarney/"
1034
+ end
1035
+
1036
+ it "should result in " +
1037
+ "'http://example.com/order/cheeseburger/cheeseburger/cheeseburger/' " +
1038
+ "when used to expand 'http://example.com/order/{c}/{c}/{c}/'" do
1039
+ Addressable::Template.new(
1040
+ "http://example.com/order/{c}/{c}/{c}/"
1041
+ ).expand(@mapping).to_s.should ==
1042
+ "http://example.com/order/cheeseburger/cheeseburger/cheeseburger/"
1043
+ end
1044
+
1045
+ it "should result in 'http://example.org/one%20two%20three' " +
1046
+ "when used to expand 'http://example.org/{d}'" do
1047
+ Addressable::Template.new(
1048
+ "http://example.org/{d}"
1049
+ ).expand(@mapping).to_s.should ==
1050
+ "http://example.org/one%20two%20three"
1051
+ end
1052
+
1053
+ it "should result in 'http://example.org/20%25%20tricky' " +
1054
+ "when used to expand 'http://example.org/{e}'" do
1055
+ Addressable::Template.new(
1056
+ "http://example.org/{e}"
1057
+ ).expand(@mapping).to_s.should ==
1058
+ "http://example.org/20%25%20tricky"
1059
+ end
1060
+
1061
+ it "should result in 'http://example.com//' " +
1062
+ "when used to expand 'http://example.com/{f}/'" do
1063
+ Addressable::Template.new(
1064
+ "http://example.com/{f}/"
1065
+ ).expand(@mapping).to_s.should ==
1066
+ "http://example.com//"
1067
+ end
1068
+
1069
+ it "should result in " +
1070
+ "'https://this-is-spinal-tap.example.org?date=&option=fred' " +
1071
+ "when used to expand " +
1072
+ "'{scheme}://{20}.example.org?date={wilma}&option={a}'" do
1073
+ Addressable::Template.new(
1074
+ "{scheme}://{20}.example.org?date={wilma}&option={a}"
1075
+ ).expand(@mapping).to_s.should ==
1076
+ "https://this-is-spinal-tap.example.org?date=&option=fred"
1077
+ end
1078
+
1079
+ # The v 01 draft conflicts with the v 03 draft here.
1080
+ # The Addressable implementation uses v 03.
1081
+ it "should result in " +
1082
+ "'http://example.org?quote%3Dto%2Bbe%2Bor%2Bnot%2Bto%2Bbe' " +
1083
+ "when used to expand 'http://example.org?{p}'" do
1084
+ Addressable::Template.new(
1085
+ "http://example.org?{p}"
1086
+ ).expand(@mapping).to_s.should ==
1087
+ "http://example.org?quote%3Dto%2Bbe%2Bor%2Bnot%2Bto%2Bbe"
1088
+ end
1089
+
1090
+ # The v 01 draft conflicts with the v 03 draft here.
1091
+ # The Addressable implementation uses v 03.
1092
+ it "should result in 'http://example.com/hullo%23world' " +
1093
+ "when used to expand 'http://example.com/{q}'" do
1094
+ Addressable::Template.new(
1095
+ "http://example.com/{q}"
1096
+ ).expand(@mapping).to_s.should == "http://example.com/hullo%23world"
1097
+ end
1098
+ end
1099
+
1100
+ # Section 4.5 of the URI Template draft v 03
1101
+ describe Addressable::URI, "when given the mapping supplied in " +
1102
+ "Section 4.5 of the URI Template draft v 03" do
1103
+ before do
1104
+ @mapping = {
1105
+ "foo" => "ϓ",
1106
+ "bar" => "fred",
1107
+ "baz" => "10,20,30",
1108
+ "qux" => ["10","20","30"],
1109
+ "corge" => [],
1110
+ "grault" => "",
1111
+ "garply" => "a/b/c",
1112
+ "waldo" => "ben & jerrys",
1113
+ "fred" => ["fred", "", "wilma"],
1114
+ "plugh" => ["ẛ", "ṡ"],
1115
+ "1-a_b.c" => "200"
1116
+ }
1117
+ end
1118
+
1119
+ it "should result in 'http://example.org/?q=fred' " +
1120
+ "when used to expand 'http://example.org/?q={bar}'" do
1121
+ Addressable::Template.new(
1122
+ "http://example.org/?q={bar}"
1123
+ ).expand(@mapping).to_s.should == "http://example.org/?q=fred"
1124
+ end
1125
+
1126
+ it "should result in '/' " +
1127
+ "when used to expand '/{xyzzy}'" do
1128
+ Addressable::Template.new(
1129
+ "/{xyzzy}"
1130
+ ).expand(@mapping).to_s.should == "/"
1131
+ end
1132
+
1133
+ it "should result in " +
1134
+ "'http://example.org/?foo=%CE%8E&bar=fred&baz=10%2C20%2C30' " +
1135
+ "when used to expand " +
1136
+ "'http://example.org/?{-join|&|foo,bar,xyzzy,baz}'" do
1137
+ Addressable::Template.new(
1138
+ "http://example.org/?{-join|&|foo,bar,xyzzy,baz}"
1139
+ ).expand(@mapping).to_s.should ==
1140
+ "http://example.org/?foo=%CE%8E&bar=fred&baz=10%2C20%2C30"
1141
+ end
1142
+
1143
+ it "should result in 'http://example.org/?d=10,20,30' " +
1144
+ "when used to expand 'http://example.org/?d={-list|,|qux}'" do
1145
+ Addressable::Template.new(
1146
+ "http://example.org/?d={-list|,|qux}"
1147
+ ).expand(
1148
+ @mapping
1149
+ ).to_s.should == "http://example.org/?d=10,20,30"
1150
+ end
1151
+
1152
+ it "should result in 'http://example.org/?d=10&d=20&d=30' " +
1153
+ "when used to expand 'http://example.org/?d={-list|&d=|qux}'" do
1154
+ Addressable::Template.new(
1155
+ "http://example.org/?d={-list|&d=|qux}"
1156
+ ).expand(
1157
+ @mapping
1158
+ ).to_s.should == "http://example.org/?d=10&d=20&d=30"
1159
+ end
1160
+
1161
+ it "should result in 'http://example.org/fredfred/a%2Fb%2Fc' " +
1162
+ "when used to expand 'http://example.org/{bar}{bar}/{garply}'" do
1163
+ Addressable::Template.new(
1164
+ "http://example.org/{bar}{bar}/{garply}"
1165
+ ).expand(
1166
+ @mapping
1167
+ ).to_s.should == "http://example.org/fredfred/a%2Fb%2Fc"
1168
+ end
1169
+
1170
+ it "should result in 'http://example.org/fred/fred//wilma' " +
1171
+ "when used to expand 'http://example.org/{bar}{-prefix|/|fred}'" do
1172
+ Addressable::Template.new(
1173
+ "http://example.org/{bar}{-prefix|/|fred}"
1174
+ ).expand(
1175
+ @mapping
1176
+ ).to_s.should == "http://example.org/fred/fred//wilma"
1177
+ end
1178
+
1179
+ it "should result in ':%E1%B9%A1:%E1%B9%A1:' " +
1180
+ "when used to expand '{-neg|:|corge}{-suffix|:|plugh}'" do
1181
+ Addressable::Template.new(
1182
+ "{-neg|:|corge}{-suffix|:|plugh}"
1183
+ ).expand(
1184
+ @mapping
1185
+ ).to_s.should == ":%E1%B9%A1:%E1%B9%A1:"
1186
+ end
1187
+
1188
+ it "should result in '../ben%20%26%20jerrys/' " +
1189
+ "when used to expand '../{waldo}/'" do
1190
+ Addressable::Template.new(
1191
+ "../{waldo}/"
1192
+ ).expand(
1193
+ @mapping
1194
+ ).to_s.should == "../ben%20%26%20jerrys/"
1195
+ end
1196
+
1197
+ it "should result in 'telnet:192.0.2.16:80' " +
1198
+ "when used to expand 'telnet:192.0.2.16{-opt|:80|grault}'" do
1199
+ Addressable::Template.new(
1200
+ "telnet:192.0.2.16{-opt|:80|grault}"
1201
+ ).expand(
1202
+ @mapping
1203
+ ).to_s.should == "telnet:192.0.2.16:80"
1204
+ end
1205
+
1206
+ it "should result in ':200:' " +
1207
+ "when used to expand ':{1-a_b.c}:'" do
1208
+ Addressable::Template.new(
1209
+ ":{1-a_b.c}:"
1210
+ ).expand(
1211
+ @mapping
1212
+ ).to_s.should == ":200:"
1213
+ end
1214
+ end
1215
+
1216
+ describe Addressable::URI, "when given a mapping that contains a " +
1217
+ "template-var within a value" do
1218
+ before do
1219
+ @mapping = {
1220
+ "a" => "{b}",
1221
+ "b" => "barney",
1222
+ }
1223
+ end
1224
+
1225
+ it "should result in 'http://example.com/%7Bb%7D/barney/' " +
1226
+ "when used to expand 'http://example.com/{a}/{b}/'" do
1227
+ Addressable::Template.new(
1228
+ "http://example.com/{a}/{b}/"
1229
+ ).expand(
1230
+ @mapping
1231
+ ).to_s.should == "http://example.com/%7Bb%7D/barney/"
1232
+ end
1233
+
1234
+ it "should result in 'http://example.com//%7Bb%7D/' " +
1235
+ "when used to expand 'http://example.com/{-opt|foo|foo}/{a}/'" do
1236
+ Addressable::Template.new(
1237
+ "http://example.com/{-opt|foo|foo}/{a}/"
1238
+ ).expand(
1239
+ @mapping
1240
+ ).to_s.should == "http://example.com//%7Bb%7D/"
1241
+ end
1242
+
1243
+ it "should result in 'http://example.com//%7Bb%7D/' " +
1244
+ "when used to expand 'http://example.com/{-neg|foo|b}/{a}/'" do
1245
+ Addressable::Template.new(
1246
+ "http://example.com/{-neg|foo|b}/{a}/"
1247
+ ).expand(
1248
+ @mapping
1249
+ ).to_s.should == "http://example.com//%7Bb%7D/"
1250
+ end
1251
+
1252
+ it "should result in 'http://example.com//barney/%7Bb%7D/' " +
1253
+ "when used to expand 'http://example.com/{-prefix|/|b}/{a}/'" do
1254
+ Addressable::Template.new(
1255
+ "http://example.com/{-prefix|/|b}/{a}/"
1256
+ ).expand(
1257
+ @mapping
1258
+ ).to_s.should == "http://example.com//barney/%7Bb%7D/"
1259
+ end
1260
+
1261
+ it "should result in 'http://example.com/barney//%7Bb%7D/' " +
1262
+ "when used to expand 'http://example.com/{-suffix|/|b}/{a}/'" do
1263
+ Addressable::Template.new(
1264
+ "http://example.com/{-suffix|/|b}/{a}/"
1265
+ ).expand(
1266
+ @mapping
1267
+ ).to_s.should == "http://example.com/barney//%7Bb%7D/"
1268
+ end
1269
+
1270
+ it "should result in 'http://example.com/%7Bb%7D/?b=barney&c=42' " +
1271
+ "when used to expand 'http://example.com/{a}/?{-join|&|b,c=42}'" do
1272
+ Addressable::Template.new(
1273
+ "http://example.com/{a}/?{-join|&|b,c=42}"
1274
+ ).expand(
1275
+ @mapping
1276
+ ).to_s.should == "http://example.com/%7Bb%7D/?b=barney&c=42"
1277
+ end
1278
+
1279
+ it "should result in 'http://example.com/42/?b=barney' " +
1280
+ "when used to expand 'http://example.com/{c=42}/?{-join|&|b}'" do
1281
+ Addressable::Template.new(
1282
+ "http://example.com/{c=42}/?{-join|&|b}"
1283
+ ).expand(@mapping).to_s.should == "http://example.com/42/?b=barney"
1284
+ end
1285
+ end
1286
+
1287
+ describe Addressable::URI, "when given a single variable mapping" do
1288
+ before do
1289
+ @mapping = {
1290
+ "foo" => "fred"
1291
+ }
1292
+ end
1293
+
1294
+ it "should result in 'fred' when used to expand '{foo}'" do
1295
+ Addressable::Template.new(
1296
+ "{foo}"
1297
+ ).expand(@mapping).to_s.should == "fred"
1298
+ end
1299
+
1300
+ it "should result in 'wilma' when used to expand '{bar=wilma}'" do
1301
+ Addressable::Template.new(
1302
+ "{bar=wilma}"
1303
+ ).expand(@mapping).to_s.should == "wilma"
1304
+ end
1305
+
1306
+ it "should result in '' when used to expand '{baz}'" do
1307
+ Addressable::Template.new(
1308
+ "{baz}"
1309
+ ).expand(@mapping).to_s.should == ""
1310
+ end
1311
+ end
1312
+
1313
+ describe Addressable::URI, "when given a simple mapping" do
1314
+ before do
1315
+ @mapping = {
1316
+ "foo" => "fred",
1317
+ "bar" => "barney",
1318
+ "baz" => ""
1319
+ }
1320
+ end
1321
+
1322
+ it "should result in 'foo=fred&bar=barney&baz=' when used to expand " +
1323
+ "'{-join|&|foo,bar,baz,qux}'" do
1324
+ Addressable::Template.new(
1325
+ "{-join|&|foo,bar,baz,qux}"
1326
+ ).expand(@mapping).to_s.should == "foo=fred&bar=barney&baz="
1327
+ end
1328
+
1329
+ it "should result in 'bar=barney' when used to expand " +
1330
+ "'{-join|&|bar}'" do
1331
+ Addressable::Template.new(
1332
+ "{-join|&|bar}"
1333
+ ).expand(@mapping).to_s.should == "bar=barney"
1334
+ end
1335
+
1336
+ it "should result in '' when used to expand " +
1337
+ "'{-join|&|qux}'" do
1338
+ Addressable::Template.new(
1339
+ "{-join|&|qux}"
1340
+ ).expand(@mapping).to_s.should == ""
1341
+ end
1342
+ end
1343
+
1344
+ describe Addressable::URI, "when given a mapping containing values " +
1345
+ "that are already percent-encoded" do
1346
+ before do
1347
+ @mapping = {
1348
+ "a" => "%7Bb%7D"
1349
+ }
1350
+ end
1351
+
1352
+ it "should result in 'http://example.com/%257Bb%257D/' " +
1353
+ "when used to expand 'http://example.com/{a}/'" do
1354
+ Addressable::Template.new(
1355
+ "http://example.com/{a}/"
1356
+ ).expand(@mapping).to_s.should == "http://example.com/%257Bb%257D/"
1357
+ end
1358
+ end
1359
+
1360
+ describe Addressable::URI, "when given a mapping containing bogus values" do
1361
+ it "should raise a TypeError" do
1362
+ (lambda do
1363
+ Addressable::Template.new(
1364
+ "http://example.com/{bogus}/"
1365
+ ).expand({
1366
+ "bogus" => 42
1367
+ })
1368
+ end).should raise_error(TypeError)
1369
+ end
1370
+ end
1371
+
1372
+ describe Addressable::URI, "when given a pattern with bogus operators" do
1373
+ it "should raise an InvalidTemplateOperatorError" do
1374
+ (lambda do
1375
+ Addressable::Template.new(
1376
+ "http://example.com/{-bogus|/|a,b,c}/"
1377
+ ).expand({
1378
+ "a" => "a", "b" => "b", "c" => "c"
1379
+ })
1380
+ end).should raise_error(
1381
+ Addressable::Template::InvalidTemplateOperatorError
1382
+ )
1383
+ end
1384
+
1385
+ it "should raise an InvalidTemplateOperatorError" do
1386
+ (lambda do
1387
+ Addressable::Template.new(
1388
+ "http://example.com/{-prefix|/|a,b,c}/"
1389
+ ).expand({
1390
+ "a" => "a", "b" => "b", "c" => "c"
1391
+ })
1392
+ end).should raise_error(
1393
+ Addressable::Template::InvalidTemplateOperatorError
1394
+ )
1395
+ end
1396
+
1397
+ it "should raise an InvalidTemplateOperatorError" do
1398
+ (lambda do
1399
+ Addressable::Template.new(
1400
+ "http://example.com/{-suffix|/|a,b,c}/"
1401
+ ).expand({
1402
+ "a" => "a", "b" => "b", "c" => "c"
1403
+ })
1404
+ end).should raise_error(
1405
+ Addressable::Template::InvalidTemplateOperatorError
1406
+ )
1407
+ end
1408
+
1409
+ it "should raise an InvalidTemplateOperatorError" do
1410
+ (lambda do
1411
+ Addressable::Template.new(
1412
+ "http://example.com/{-join|/|a,b,c}/"
1413
+ ).expand({
1414
+ "a" => ["a"], "b" => ["b"], "c" => "c"
1415
+ })
1416
+ end).should raise_error(
1417
+ Addressable::Template::InvalidTemplateOperatorError
1418
+ )
1419
+ end
1420
+
1421
+ it "should raise an InvalidTemplateOperatorError" do
1422
+ (lambda do
1423
+ Addressable::Template.new(
1424
+ "http://example.com/{-list|/|a,b,c}/"
1425
+ ).expand({
1426
+ "a" => ["a"], "b" => ["b"], "c" => "c"
1427
+ })
1428
+ end).should raise_error(
1429
+ Addressable::Template::InvalidTemplateOperatorError
1430
+ )
1431
+ end
1432
+ end
1433
+
1434
+ describe Addressable::Template, "with a partially expanded template" do
1435
+ before do
1436
+ @initial_template = Addressable::Template.new(
1437
+ "http://example.com/{one}/{two}/"
1438
+ )
1439
+ @partial_template = @initial_template.partial_expand({"one" => "1"})
1440
+ end
1441
+
1442
+ it "should produce the same result when fully expanded" do
1443
+ @initial_template.expand({"one" => "1", "two" => "2"}).should ==
1444
+ @partial_template.expand({"two" => "2"})
1445
+ end
1446
+ end
1447
+
1448
+ describe Addressable::Template, "with a partially expanded template" do
1449
+ before do
1450
+ @initial_template = Addressable::Template.new(
1451
+ "http://example.com/{one}/{two}/"
1452
+ )
1453
+ @partial_template = @initial_template.partial_expand({"two" => "2"})
1454
+ end
1455
+
1456
+ it "should produce the same result when fully expanded" do
1457
+ @initial_template.expand({"one" => "1", "two" => "2"}).should ==
1458
+ @partial_template.expand({"one" => "1"})
1459
+ end
1460
+ end
1461
+
1462
+ describe Addressable::Template, "with a partially expanded template" do
1463
+ before do
1464
+ @initial_template = Addressable::Template.new(
1465
+ "http://example.com/{one}/{two}/"
1466
+ )
1467
+ @partial_template = @initial_template.partial_expand({"two" => "2"})
1468
+ end
1469
+
1470
+ it "should produce the same result when fully expanded" do
1471
+ @initial_template.expand({"one" => "1", "two" => "2"}).should ==
1472
+ @partial_template.expand({"one" => "1"})
1473
+ end
1474
+ end
1475
+
1476
+ describe Addressable::Template, "with a partially expanded template" do
1477
+ before do
1478
+ @initial_template = Addressable::Template.new(
1479
+ "http://example.com/{one=1}/{two=2}/"
1480
+ )
1481
+ @partial_template = @initial_template.partial_expand({"one" => "3"})
1482
+ end
1483
+
1484
+ it "should produce the same result when fully expanded" do
1485
+ @initial_template.expand({"one" => "3", "two" => "4"}).should ==
1486
+ @partial_template.expand({"two" => "4"})
1487
+ end
1488
+
1489
+ it "should produce the correct result when fully expanded" do
1490
+ @partial_template.expand({}).should === "http://example.com/3/2/"
1491
+ end
1492
+ end
1493
+
1494
+ describe Addressable::Template, "with a partially expanded template" do
1495
+ before do
1496
+ @initial_template = Addressable::Template.new(
1497
+ "http://example.com/{one=1}/{two=2}/"
1498
+ )
1499
+ @partial_template = @initial_template.partial_expand({"two" => "4"})
1500
+ end
1501
+
1502
+ it "should produce the same result when fully expanded" do
1503
+ @initial_template.expand({"one" => "3", "two" => "4"}).should ==
1504
+ @partial_template.expand({"one" => "3"})
1505
+ end
1506
+
1507
+ it "should produce the correct result when fully expanded" do
1508
+ @partial_template.expand({}).should === "http://example.com/1/4/"
1509
+ end
1510
+ end
1511
+
1512
+ describe Addressable::Template, "with a partially expanded template" do
1513
+ before do
1514
+ @initial_template = Addressable::Template.new(
1515
+ "http://example.com/{-opt|found|one,two,three}"
1516
+ )
1517
+ @partial_template = @initial_template.partial_expand({})
1518
+ end
1519
+
1520
+ it "should produce the same result when fully expanded" do
1521
+ @initial_template.expand({"one" => "1"}).to_str.should ==
1522
+ @partial_template.expand({"two" => "2"}).to_str
1523
+ end
1524
+
1525
+ it "should produce the correct result when fully expanded" do
1526
+ @partial_template.expand({}).to_str.should == "http://example.com/"
1527
+ end
1528
+
1529
+ it "should produce the correct result when fully expanded" do
1530
+ @partial_template.expand({"one" => "1"}).to_str.should ==
1531
+ "http://example.com/found"
1532
+ end
1533
+
1534
+ it "should produce the correct result when fully expanded" do
1535
+ @partial_template.expand({"two" => "2"}).to_str.should ==
1536
+ "http://example.com/found"
1537
+ end
1538
+
1539
+ it "should produce the correct result when fully expanded" do
1540
+ @partial_template.expand({"three" => "3"}).to_str.should ==
1541
+ "http://example.com/found"
1542
+ end
1543
+
1544
+ it "should produce the correct result when fully expanded" do
1545
+ @partial_template.expand({"four" => "4"}).to_str.should ==
1546
+ "http://example.com/"
1547
+ end
1548
+
1549
+ it "should produce the correct result when fully expanded" do
1550
+ @partial_template.expand({"one" => "1", "two" => "2"}).to_str.should ==
1551
+ "http://example.com/found"
1552
+ end
1553
+ end
1554
+
1555
+ describe Addressable::Template, "with a partially expanded template" do
1556
+ before do
1557
+ @initial_template = Addressable::Template.new(
1558
+ "http://example.com/{-opt|found|one,two,three}"
1559
+ )
1560
+ @partial_template = @initial_template.partial_expand({"one" => "1"})
1561
+ end
1562
+
1563
+ it "should produce the same result when fully expanded" do
1564
+ @initial_template.expand({"one" => "1"}).to_str.should ==
1565
+ @partial_template.expand({"two" => "2"}).to_str
1566
+ end
1567
+
1568
+ it "should produce the correct result when fully expanded" do
1569
+ @partial_template.expand({}).to_str.should == "http://example.com/found"
1570
+ end
1571
+
1572
+ it "should produce the correct pattern" do
1573
+ @partial_template.pattern.should == "http://example.com/found"
1574
+ end
1575
+ end
1576
+
1577
+ describe Addressable::Template, "with a partially expanded template" do
1578
+ before do
1579
+ @initial_template = Addressable::Template.new(
1580
+ "http://example.com/{-neg|notfound|one,two,three}"
1581
+ )
1582
+ @partial_template = @initial_template.partial_expand({})
1583
+ end
1584
+
1585
+ it "should produce the same result when fully expanded" do
1586
+ @initial_template.expand({"one" => "1"}).to_str.should ==
1587
+ @partial_template.expand({"two" => "2"}).to_str
1588
+ end
1589
+
1590
+ it "should produce the correct result when fully expanded" do
1591
+ @partial_template.expand({}).to_str.should == "http://example.com/notfound"
1592
+ end
1593
+
1594
+ it "should produce the correct result when fully expanded" do
1595
+ @partial_template.expand({"one" => "1"}).to_str.should ==
1596
+ "http://example.com/"
1597
+ end
1598
+
1599
+ it "should produce the correct result when fully expanded" do
1600
+ @partial_template.expand({"two" => "2"}).to_str.should ==
1601
+ "http://example.com/"
1602
+ end
1603
+
1604
+ it "should produce the correct result when fully expanded" do
1605
+ @partial_template.expand({"three" => "3"}).to_str.should ==
1606
+ "http://example.com/"
1607
+ end
1608
+
1609
+ it "should produce the correct result when fully expanded" do
1610
+ @partial_template.expand({"four" => "4"}).to_str.should ==
1611
+ "http://example.com/notfound"
1612
+ end
1613
+
1614
+ it "should produce the correct result when fully expanded" do
1615
+ @partial_template.expand({"one" => "1", "two" => "2"}).to_str.should ==
1616
+ "http://example.com/"
1617
+ end
1618
+ end
1619
+
1620
+ describe Addressable::Template, "with a partially expanded template" do
1621
+ before do
1622
+ @initial_template = Addressable::Template.new(
1623
+ "http://example.com/{-neg|notfound|one,two,three}"
1624
+ )
1625
+ @partial_template = @initial_template.partial_expand({"one" => "1"})
1626
+ end
1627
+
1628
+ it "should produce the same result when fully expanded" do
1629
+ @initial_template.expand({"one" => "1"}).to_str.should ==
1630
+ @partial_template.expand({"two" => "2"}).to_str
1631
+ end
1632
+
1633
+ it "should produce the correct result when fully expanded" do
1634
+ @partial_template.expand({}).to_str.should == "http://example.com/"
1635
+ end
1636
+
1637
+ it "should produce the correct pattern" do
1638
+ @partial_template.pattern.should == "http://example.com/"
1639
+ end
1640
+ end
1641
+
1642
+ describe Addressable::Template, "with a partially expanded template" do
1643
+ before do
1644
+ @initial_template = Addressable::Template.new(
1645
+ "http://example.com/?{-prefix|x=|one}"
1646
+ )
1647
+ @partial_template = @initial_template.partial_expand({})
1648
+ end
1649
+
1650
+ it "should produce the same result when fully expanded" do
1651
+ @initial_template.expand({"one" => "1"}).to_str.should ==
1652
+ @partial_template.expand({"one" => "1"}).to_str
1653
+ end
1654
+
1655
+ it "should produce the correct result when fully expanded" do
1656
+ @partial_template.expand({}).to_str.should == "http://example.com/?"
1657
+ end
1658
+
1659
+ it "should produce the correct result when fully expanded" do
1660
+ @partial_template.expand({"one" => "1"}).to_str.should ==
1661
+ "http://example.com/?x=1"
1662
+ end
1663
+
1664
+ it "should produce the correct result when fully expanded" do
1665
+ @partial_template.expand({"two" => "2"}).to_str.should ==
1666
+ "http://example.com/?"
1667
+ end
1668
+
1669
+ it "should produce the correct result when fully expanded" do
1670
+ @partial_template.expand({"one" => "1", "two" => "2"}).to_str.should ==
1671
+ "http://example.com/?x=1"
1672
+ end
1673
+ end
1674
+
1675
+ describe Addressable::Template, "with a partially expanded template" do
1676
+ before do
1677
+ @initial_template = Addressable::Template.new(
1678
+ "http://example.com/?{-prefix|x=|one}"
1679
+ )
1680
+ @partial_template = @initial_template.partial_expand({"one" => "1"})
1681
+ end
1682
+
1683
+ it "should produce the same result when fully expanded" do
1684
+ @initial_template.expand({"one" => "1"}).to_str.should ==
1685
+ @partial_template.expand({}).to_str
1686
+ end
1687
+
1688
+ it "should produce the correct result when fully expanded" do
1689
+ @partial_template.expand({}).to_str.should == "http://example.com/?x=1"
1690
+ end
1691
+
1692
+ it "should produce the correct pattern" do
1693
+ @partial_template.pattern.should == "http://example.com/?x=1"
1694
+ end
1695
+ end
1696
+
1697
+ describe Addressable::Template, "with a partially expanded template" do
1698
+ before do
1699
+ @initial_template = Addressable::Template.new(
1700
+ "http://example.com/?{-suffix|=x|one}"
1701
+ )
1702
+ @partial_template = @initial_template.partial_expand({})
1703
+ end
1704
+
1705
+ it "should produce the same result when fully expanded" do
1706
+ @initial_template.expand({"one" => "1"}).to_str.should ==
1707
+ @partial_template.expand({"one" => "1"}).to_str
1708
+ end
1709
+
1710
+ it "should produce the correct result when fully expanded" do
1711
+ @partial_template.expand({}).to_str.should == "http://example.com/?"
1712
+ end
1713
+
1714
+ it "should produce the correct result when fully expanded" do
1715
+ @partial_template.expand({"one" => "1"}).to_str.should ==
1716
+ "http://example.com/?1=x"
1717
+ end
1718
+
1719
+ it "should produce the correct result when fully expanded" do
1720
+ @partial_template.expand({"two" => "2"}).to_str.should ==
1721
+ "http://example.com/?"
1722
+ end
1723
+
1724
+ it "should produce the correct result when fully expanded" do
1725
+ @partial_template.expand({"one" => "1", "two" => "2"}).to_str.should ==
1726
+ "http://example.com/?1=x"
1727
+ end
1728
+ end
1729
+
1730
+ describe Addressable::Template, "with a partially expanded template" do
1731
+ before do
1732
+ @initial_template = Addressable::Template.new(
1733
+ "http://example.com/?{-suffix|=x|one}"
1734
+ )
1735
+ @partial_template = @initial_template.partial_expand({"one" => "1"})
1736
+ end
1737
+
1738
+ it "should produce the same result when fully expanded" do
1739
+ @initial_template.expand({"one" => "1"}).to_str.should ==
1740
+ @partial_template.expand({}).to_str
1741
+ end
1742
+
1743
+ it "should produce the correct result when fully expanded" do
1744
+ @partial_template.expand({}).to_str.should == "http://example.com/?1=x"
1745
+ end
1746
+
1747
+ it "should produce the correct pattern" do
1748
+ @partial_template.pattern.should == "http://example.com/?1=x"
1749
+ end
1750
+ end
1751
+
1752
+ describe Addressable::Template, "with a partially expanded template" do
1753
+ before do
1754
+ @initial_template = Addressable::Template.new(
1755
+ "http://example.com/?{-join|&|one}"
1756
+ )
1757
+ @partial_template = @initial_template.partial_expand({})
1758
+ end
1759
+
1760
+ it "should produce the same result when fully expanded" do
1761
+ @initial_template.expand({"one" => "1"}).to_str.should ==
1762
+ @partial_template.expand({"one" => "1"}).to_str
1763
+ end
1764
+
1765
+ it "should produce the correct result when fully expanded" do
1766
+ @partial_template.expand({}).to_str.should == "http://example.com/?"
1767
+ end
1768
+
1769
+ it "should produce the correct result when fully expanded" do
1770
+ @partial_template.pattern.should == @initial_template.pattern
1771
+ end
1772
+ end
1773
+
1774
+ describe Addressable::Template, "with a partially expanded template" do
1775
+ before do
1776
+ @initial_template = Addressable::Template.new(
1777
+ "http://example.com/?{-join|&|one,two}"
1778
+ )
1779
+ @partial_template = @initial_template.partial_expand({"one" => "1"})
1780
+ end
1781
+
1782
+ it "should produce the same result when fully expanded" do
1783
+ @initial_template.expand({"one" => "1", "two" => "2"}).to_str.should ==
1784
+ @partial_template.expand({"two" => "2"}).to_str
1785
+ end
1786
+
1787
+ it "should produce the correct result when fully expanded" do
1788
+ @partial_template.expand({}).to_str.should == "http://example.com/?one=1"
1789
+ end
1790
+ end
1791
+
1792
+ describe Addressable::Template, "with a partially expanded template" do
1793
+ before do
1794
+ @initial_template = Addressable::Template.new(
1795
+ "http://example.com/?{-join|&|one,two}"
1796
+ )
1797
+ @partial_template = @initial_template.partial_expand({"two" => "2"})
1798
+ end
1799
+
1800
+ it "should produce the same result when fully expanded" do
1801
+ @initial_template.expand({"one" => "1", "two" => "2"}).to_str.should ==
1802
+ @partial_template.expand({"one" => "1"}).to_str
1803
+ end
1804
+
1805
+ it "should produce the correct result when fully expanded" do
1806
+ @partial_template.expand({}).to_str.should == "http://example.com/?two=2"
1807
+ end
1808
+ end
1809
+
1810
+ describe Addressable::Template, "with a partially expanded template" do
1811
+ before do
1812
+ @initial_template = Addressable::Template.new(
1813
+ "http://example.com/?{-join|&|one,two,three}"
1814
+ )
1815
+ @partial_template = @initial_template.partial_expand({"one" => "1"})
1816
+ end
1817
+
1818
+ it "should produce the same result when fully expanded" do
1819
+ @initial_template.expand({
1820
+ "one" => "1", "two" => "2", "three" => "3"
1821
+ }).to_str.should ==
1822
+ @partial_template.expand({"two" => "2", "three" => "3"}).to_str
1823
+ end
1824
+
1825
+ it "should produce the correct result when fully expanded" do
1826
+ @partial_template.expand({}).to_str.should == "http://example.com/?one=1"
1827
+ end
1828
+
1829
+ it "should produce the correct result when fully expanded" do
1830
+ @partial_template.expand({"two" => "2"}).to_str.should ==
1831
+ "http://example.com/?one=1&two=2"
1832
+ end
1833
+
1834
+ it "should produce the correct result when fully expanded" do
1835
+ @partial_template.expand({"three" => "3"}).to_str.should ==
1836
+ "http://example.com/?one=1&three=3"
1837
+ end
1838
+ end
1839
+
1840
+ describe Addressable::Template, "with a partially expanded template" do
1841
+ before do
1842
+ @initial_template = Addressable::Template.new(
1843
+ "http://example.com/?{-join|&|one,two,three}"
1844
+ )
1845
+ @partial_template = @initial_template.partial_expand({"two" => "2"})
1846
+ end
1847
+
1848
+ it "should produce the same result when fully expanded" do
1849
+ @initial_template.expand({
1850
+ "one" => "1", "two" => "2", "three" => "3"
1851
+ }).to_str.should ==
1852
+ @partial_template.expand({"one" => "1", "three" => "3"}).to_str
1853
+ end
1854
+
1855
+ it "should produce the correct result when fully expanded" do
1856
+ @partial_template.expand({}).to_str.should == "http://example.com/?two=2"
1857
+ end
1858
+
1859
+ it "should produce the correct result when fully expanded" do
1860
+ @partial_template.expand({"one" => "1"}).to_str.should ==
1861
+ "http://example.com/?one=1&two=2"
1862
+ end
1863
+
1864
+ it "should produce the correct result when fully expanded" do
1865
+ @partial_template.expand({"three" => "3"}).to_str.should ==
1866
+ "http://example.com/?two=2&three=3"
1867
+ end
1868
+ end
1869
+
1870
+ describe Addressable::Template, "with a partially expanded template" do
1871
+ before do
1872
+ @initial_template = Addressable::Template.new(
1873
+ "http://example.com/?{-join|&|one,two,three}"
1874
+ )
1875
+ @partial_template = @initial_template.partial_expand({"three" => "3"})
1876
+ end
1877
+
1878
+ it "should produce the same result when fully expanded" do
1879
+ @initial_template.expand({
1880
+ "one" => "1", "two" => "2", "three" => "3"
1881
+ }).to_str.should ==
1882
+ @partial_template.expand({"one" => "1", "two" => "2"}).to_str
1883
+ end
1884
+
1885
+ it "should produce the correct result when fully expanded" do
1886
+ @partial_template.expand({}).to_str.should == "http://example.com/?three=3"
1887
+ end
1888
+
1889
+ it "should produce the correct result when fully expanded" do
1890
+ @partial_template.expand({"one" => "1"}).to_str.should ==
1891
+ "http://example.com/?one=1&three=3"
1892
+ end
1893
+
1894
+ it "should produce the correct result when fully expanded" do
1895
+ @partial_template.expand({"two" => "2"}).to_str.should ==
1896
+ "http://example.com/?two=2&three=3"
1897
+ end
1898
+ end
1899
+
1900
+ describe Addressable::Template, "with a partially expanded template" do
1901
+ before do
1902
+ @initial_template = Addressable::Template.new(
1903
+ "http://example.com/?{-join|&|one,two,three}"
1904
+ )
1905
+ @partial_template = @initial_template.partial_expand({
1906
+ "one" => "1", "two" => "2"
1907
+ })
1908
+ end
1909
+
1910
+ it "should produce the same result when fully expanded" do
1911
+ @initial_template.expand({
1912
+ "one" => "1", "two" => "2", "three" => "3"
1913
+ }).to_str.should ==
1914
+ @partial_template.expand({"three" => "3"}).to_str
1915
+ end
1916
+
1917
+ it "should produce the correct result when fully expanded" do
1918
+ @partial_template.expand({}).to_str.should ==
1919
+ "http://example.com/?one=1&two=2"
1920
+ end
1921
+
1922
+ it "should produce the correct result when fully expanded" do
1923
+ @partial_template.expand({"three" => "3"}).to_str.should ==
1924
+ "http://example.com/?one=1&two=2&three=3"
1925
+ end
1926
+ end
1927
+
1928
+ describe Addressable::Template, "with a partially expanded template" do
1929
+ before do
1930
+ @initial_template = Addressable::Template.new(
1931
+ "http://example.com/?{-join|&|one,two,three}"
1932
+ )
1933
+ @partial_template = @initial_template.partial_expand({
1934
+ "one" => "1", "three" => "3"
1935
+ })
1936
+ end
1937
+
1938
+ it "should produce the same result when fully expanded" do
1939
+ @initial_template.expand({
1940
+ "one" => "1", "two" => "2", "three" => "3"
1941
+ }).to_str.should ==
1942
+ @partial_template.expand({"two" => "2"}).to_str
1943
+ end
1944
+
1945
+ it "should produce the correct result when fully expanded" do
1946
+ @partial_template.expand({}).to_str.should ==
1947
+ "http://example.com/?one=1&three=3"
1948
+ end
1949
+
1950
+ it "should produce the correct result when fully expanded" do
1951
+ @partial_template.expand({"two" => "2"}).to_str.should ==
1952
+ "http://example.com/?one=1&two=2&three=3"
1953
+ end
1954
+ end
1955
+
1956
+ describe Addressable::Template, "with a partially expanded template" do
1957
+ before do
1958
+ @initial_template = Addressable::Template.new(
1959
+ "http://example.com/?{-join|&|one,two,three}"
1960
+ )
1961
+ @partial_template = @initial_template.partial_expand({
1962
+ "two" => "2", "three" => "3"
1963
+ })
1964
+ end
1965
+
1966
+ it "should produce the same result when fully expanded" do
1967
+ @initial_template.expand({
1968
+ "one" => "1", "two" => "2", "three" => "3"
1969
+ }).to_str.should ==
1970
+ @partial_template.expand({"one" => "1"}).to_str
1971
+ end
1972
+
1973
+ it "should produce the correct result when fully expanded" do
1974
+ @partial_template.expand({}).to_str.should ==
1975
+ "http://example.com/?two=2&three=3"
1976
+ end
1977
+
1978
+ it "should produce the correct result when fully expanded" do
1979
+ @partial_template.expand({"one" => "1"}).to_str.should ==
1980
+ "http://example.com/?one=1&two=2&three=3"
1981
+ end
1982
+ end
1983
+
1984
+ describe Addressable::Template, "with a partially expanded template" do
1985
+ before do
1986
+ @initial_template = Addressable::Template.new(
1987
+ "http://example.com/?{-join|&|one,two,three}"
1988
+ )
1989
+ end
1990
+
1991
+ it "should raise an error when partially expanding a bogus operator" do
1992
+ (lambda do
1993
+ @initial_template.partial_expand({"one" => ["1"]})
1994
+ end).should raise_error(
1995
+ Addressable::Template::InvalidTemplateOperatorError
1996
+ )
1997
+ (lambda do
1998
+ @initial_template.partial_expand({"two" => "2", "three" => ["3"]})
1999
+ end).should raise_error(
2000
+ Addressable::Template::InvalidTemplateOperatorError
2001
+ )
2002
+ end
2003
+ end
2004
+
2005
+ describe Addressable::Template, "with a partially expanded template" do
2006
+ before do
2007
+ @initial_template = Addressable::Template.new(
2008
+ "http://example.com/{-list|/|numbers}/{-list|/|letters}/"
2009
+ )
2010
+ @partial_template = @initial_template.partial_expand({})
2011
+ end
2012
+
2013
+ it "should produce the same result when fully expanded" do
2014
+ @initial_template.expand({
2015
+ "numbers" => ["1", "2", "3"], "letters" => ["a", "b", "c"]
2016
+ }).to_str.should == @partial_template.expand({
2017
+ "numbers" => ["1", "2", "3"], "letters" => ["a", "b", "c"]
2018
+ }).to_str
2019
+ end
2020
+
2021
+ it "should produce the correct result when fully expanded" do
2022
+ @partial_template.expand({}).to_str.should == "http://example.com///"
2023
+ end
2024
+
2025
+ it "should produce the correct result when fully expanded" do
2026
+ @partial_template.pattern.should == @initial_template.pattern
2027
+ end
2028
+ end
2029
+
2030
+ describe Addressable::Template, "with a partially expanded template" do
2031
+ before do
2032
+ @initial_template = Addressable::Template.new(
2033
+ "http://example.com/{-list|/|numbers}/{-list|/|letters}/"
2034
+ )
2035
+ @partial_template = @initial_template.partial_expand({
2036
+ "numbers" => ["1", "2", "3"]
2037
+ })
2038
+ end
2039
+
2040
+ it "should produce the same result when fully expanded" do
2041
+ @initial_template.expand({
2042
+ "numbers" => ["1", "2", "3"], "letters" => ["a", "b", "c"]
2043
+ }).to_str.should == @partial_template.expand({
2044
+ "letters" => ["a", "b", "c"]
2045
+ }).to_str
2046
+ end
2047
+
2048
+ it "should produce the correct result when fully expanded" do
2049
+ @partial_template.expand({}).to_str.should == "http://example.com/1/2/3//"
2050
+ end
2051
+ end
2052
+
2053
+ describe Addressable::Template, "with a partially expanded template" do
2054
+ before do
2055
+ @initial_template = Addressable::Template.new(
2056
+ "http://example.com/{-list|/|numbers}/{-list|/|letters}/"
2057
+ )
2058
+ @partial_template = @initial_template.partial_expand({
2059
+ "letters" => ["a", "b", "c"]
2060
+ })
2061
+ end
2062
+
2063
+ it "should produce the same result when fully expanded" do
2064
+ @initial_template.expand({
2065
+ "numbers" => ["1", "2", "3"], "letters" => ["a", "b", "c"]
2066
+ }).to_str.should == @partial_template.expand({
2067
+ "numbers" => ["1", "2", "3"]
2068
+ }).to_str
2069
+ end
2070
+
2071
+ it "should produce the correct result when fully expanded" do
2072
+ @partial_template.expand({}).to_str.should == "http://example.com//a/b/c/"
2073
+ end
2074
+ end
2075
+
2076
+ describe Addressable::Template, "with a partially expanded template" do
2077
+ before do
2078
+ @initial_template = Addressable::Template.new(
2079
+ "http://example.com/{-list|/|numbers}/{-list|/|letters}/"
2080
+ )
2081
+ end
2082
+
2083
+ it "should raise an error when partially expanding a bogus operator" do
2084
+ (lambda do
2085
+ @initial_template.partial_expand({"numbers" => "1"})
2086
+ end).should raise_error(
2087
+ Addressable::Template::InvalidTemplateOperatorError
2088
+ )
2089
+ (lambda do
2090
+ @initial_template.partial_expand({"letters" => "a"})
2091
+ end).should raise_error(
2092
+ Addressable::Template::InvalidTemplateOperatorError
2093
+ )
2094
+ end
2095
+ end
2096
+
2097
+ describe Addressable::Template, "with a partially expanded template" do
2098
+ before do
2099
+ @initial_template = Addressable::Template.new(
2100
+ "http://example.com/{-bogus|/|one,two}/"
2101
+ )
2102
+ end
2103
+
2104
+ it "should raise an error when partially expanding a bogus operator" do
2105
+ (lambda do
2106
+ @initial_template.partial_expand({"one" => "1"})
2107
+ end).should raise_error(
2108
+ Addressable::Template::InvalidTemplateOperatorError
2109
+ )
2110
+ end
2111
+ end