fields-addressable 2.2.3.1

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