mislav-addressable 2.1.1

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.
@@ -0,0 +1,36 @@
1
+ # encoding:utf-8
2
+ #--
3
+ # Addressable, Copyright (c) 2006-2008 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 = 1
31
+ TINY = 1
32
+
33
+ STRING = [MAJOR, MINOR, TINY].join('.')
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,197 @@
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/idna"
29
+
30
+ describe Addressable::IDNA, "when converting from unicode to ASCII" do
31
+ it "should convert 'www.google.com' correctly" do
32
+ Addressable::IDNA.to_ascii("www.google.com").should == "www.google.com"
33
+ end
34
+
35
+ it "should convert 'www.詹姆斯.com' correctly" do
36
+ Addressable::IDNA.to_ascii(
37
+ "www.詹姆斯.com"
38
+ ).should == "www.xn--8ws00zhy3a.com"
39
+ end
40
+
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"
43
+ Addressable::IDNA.to_ascii(
44
+ "www.I\xC3\xB1t\xC3\xABrn\xC3\xA2ti\xC3\xB4" +
45
+ "n\xC3\xA0liz\xC3\xA6ti\xC3\xB8n.com"
46
+ ).should == "www.xn--itrntinliztin-vdb0a5exd8ewcye.com"
47
+ end
48
+
49
+ it "should convert 'www.Iñtërnâtiônàlizætiøn.com' correctly" do
50
+ Addressable::IDNA.to_ascii(
51
+ "www.In\xCC\x83te\xCC\x88rna\xCC\x82tio\xCC\x82n" +
52
+ "a\xCC\x80liz\xC3\xA6ti\xC3\xB8n.com"
53
+ ).should == "www.xn--itrntinliztin-vdb0a5exd8ewcye.com"
54
+ end
55
+
56
+ it "should convert " +
57
+ "'www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp' " +
58
+ "correctly" do
59
+ Addressable::IDNA.to_ascii(
60
+ "www.\343\201\273\343\202\223\343\201\250\343\201\206\343\201\253\343" +
61
+ "\201\252\343\201\214\343\201\204\343\202\217\343\201\221\343\201\256" +
62
+ "\343\202\217\343\201\213\343\202\211\343\201\252\343\201\204\343\201" +
63
+ "\251\343\202\201\343\201\204\343\202\223\343\202\201\343\201\204\343" +
64
+ "\201\256\343\202\211\343\201\271\343\202\213\343\201\276\343\201\240" +
65
+ "\343\201\252\343\201\214\343\201\217\343\201\227\343\201\252\343\201" +
66
+ "\204\343\201\250\343\201\237\343\202\212\343\201\252\343\201\204." +
67
+ "w3.mag.keio.ac.jp"
68
+ ).should ==
69
+ "www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3" +
70
+ "fg11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp"
71
+ end
72
+
73
+ it "should convert " +
74
+ "'www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp' " +
75
+ "correctly" do
76
+ Addressable::IDNA.to_ascii(
77
+ "www.\343\201\273\343\202\223\343\201\250\343\201\206\343\201\253\343" +
78
+ "\201\252\343\201\213\343\202\231\343\201\204\343\202\217\343\201\221" +
79
+ "\343\201\256\343\202\217\343\201\213\343\202\211\343\201\252\343\201" +
80
+ "\204\343\201\250\343\202\231\343\202\201\343\201\204\343\202\223\343" +
81
+ "\202\201\343\201\204\343\201\256\343\202\211\343\201\270\343\202\231" +
82
+ "\343\202\213\343\201\276\343\201\237\343\202\231\343\201\252\343\201" +
83
+ "\213\343\202\231\343\201\217\343\201\227\343\201\252\343\201\204\343" +
84
+ "\201\250\343\201\237\343\202\212\343\201\252\343\201\204." +
85
+ "w3.mag.keio.ac.jp"
86
+ ).should ==
87
+ "www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3" +
88
+ "fg11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp"
89
+ end
90
+
91
+ it "should convert '点心和烤鸭.w3.mag.keio.ac.jp' correctly" do
92
+ Addressable::IDNA.to_ascii(
93
+ "点心和烤鸭.w3.mag.keio.ac.jp"
94
+ ).should == "xn--0trv4xfvn8el34t.w3.mag.keio.ac.jp"
95
+ end
96
+
97
+ it "should convert '가각갂갃간갅갆갇갈갉힢힣.com' correctly" do
98
+ Addressable::IDNA.to_ascii(
99
+ "가각갂갃간갅갆갇갈갉힢힣.com"
100
+ ).should == "xn--o39acdefghijk5883jma.com"
101
+ end
102
+
103
+ it "should convert " +
104
+ "'\347\242\274\346\250\231\346\272\226\350" +
105
+ "\220\254\345\234\213\347\242\274.com' correctly" do
106
+ Addressable::IDNA.to_ascii(
107
+ "\347\242\274\346\250\231\346\272\226\350" +
108
+ "\220\254\345\234\213\347\242\274.com"
109
+ ).should == "xn--9cs565brid46mda086o.com"
110
+ end
111
+
112
+ it "should convert 'リ宠퐱〹.com' correctly" do
113
+ Addressable::IDNA.to_ascii(
114
+ "\357\276\230\345\256\240\355\220\261\343\200\271.com"
115
+ ).should == "xn--eek174hoxfpr4k.com"
116
+ end
117
+
118
+ it "should convert 'リ宠퐱卄.com' correctly" do
119
+ Addressable::IDNA.to_ascii(
120
+ "\343\203\252\345\256\240\355\220\261\345\215\204.com"
121
+ ).should == "xn--eek174hoxfpr4k.com"
122
+ end
123
+
124
+ it "should convert 'ᆵ' correctly" do
125
+ Addressable::IDNA.to_ascii(
126
+ "\341\206\265"
127
+ ).should == "xn--4ud"
128
+ end
129
+
130
+ it "should convert 'ᆵ' correctly" do
131
+ Addressable::IDNA.to_ascii(
132
+ "\357\276\257"
133
+ ).should == "xn--4ud"
134
+ end
135
+ end
136
+
137
+ describe Addressable::IDNA, "when converting from ASCII to unicode" do
138
+ it "should convert 'www.google.com' correctly" do
139
+ Addressable::IDNA.to_unicode("www.google.com").should == "www.google.com"
140
+ end
141
+
142
+ it "should convert 'www.詹姆斯.com' correctly" do
143
+ Addressable::IDNA.to_unicode(
144
+ "www.xn--8ws00zhy3a.com"
145
+ ).should == "www.詹姆斯.com"
146
+ end
147
+
148
+ it "should convert 'www.iñtërnâtiônàlizætiøn.com' correctly" do
149
+ Addressable::IDNA.to_unicode(
150
+ "www.xn--itrntinliztin-vdb0a5exd8ewcye.com"
151
+ ).should == "www.iñtërnâtiônàlizætiøn.com"
152
+ end
153
+
154
+ it "should convert " +
155
+ "'www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp' " +
156
+ "correctly" do
157
+ Addressable::IDNA.to_unicode(
158
+ "www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3" +
159
+ "fg11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp"
160
+ ).should ==
161
+ "www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp"
162
+ end
163
+
164
+ it "should convert '点心和烤鸭.w3.mag.keio.ac.jp' correctly" do
165
+ Addressable::IDNA.to_unicode(
166
+ "xn--0trv4xfvn8el34t.w3.mag.keio.ac.jp"
167
+ ).should == "点心和烤鸭.w3.mag.keio.ac.jp"
168
+ end
169
+
170
+ it "should convert '가각갂갃간갅갆갇갈갉힢힣.com' correctly" do
171
+ Addressable::IDNA.to_unicode(
172
+ "xn--o39acdefghijk5883jma.com"
173
+ ).should == "가각갂갃간갅갆갇갈갉힢힣.com"
174
+ end
175
+
176
+ it "should convert " +
177
+ "'\347\242\274\346\250\231\346\272\226\350" +
178
+ "\220\254\345\234\213\347\242\274.com' correctly" do
179
+ Addressable::IDNA.to_unicode(
180
+ "xn--9cs565brid46mda086o.com"
181
+ ).should ==
182
+ "\347\242\274\346\250\231\346\272\226\350" +
183
+ "\220\254\345\234\213\347\242\274.com"
184
+ end
185
+
186
+ it "should convert 'リ宠퐱卄.com' correctly" do
187
+ Addressable::IDNA.to_unicode(
188
+ "xn--eek174hoxfpr4k.com"
189
+ ).should == "\343\203\252\345\256\240\355\220\261\345\215\204.com"
190
+ end
191
+
192
+ it "should convert 'ᆵ' correctly" do
193
+ Addressable::IDNA.to_unicode(
194
+ "xn--4ud"
195
+ ).should == "\341\206\265"
196
+ end
197
+ end
@@ -0,0 +1,2123 @@
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 with symbol keys" do
1345
+ before do
1346
+ @mapping = { :name => "fred" }
1347
+ end
1348
+
1349
+ it "should result in 'fred' when used to expand '{foo}'" do
1350
+ Addressable::Template.new(
1351
+ "{name}"
1352
+ ).expand(@mapping).to_s.should == "fred"
1353
+ end
1354
+ end
1355
+
1356
+ describe Addressable::URI, "when given a mapping with numeric values" do
1357
+ before do
1358
+ @mapping = { :id => 123 }
1359
+ end
1360
+
1361
+ it "should result in 'fred' when used to expand '{foo}'" do
1362
+ Addressable::Template.new(
1363
+ "{id}"
1364
+ ).expand(@mapping).to_s.should == "123"
1365
+ end
1366
+ end
1367
+
1368
+ describe Addressable::URI, "when given a mapping containing values " +
1369
+ "that are already percent-encoded" do
1370
+ before do
1371
+ @mapping = {
1372
+ "a" => "%7Bb%7D"
1373
+ }
1374
+ end
1375
+
1376
+ it "should result in 'http://example.com/%257Bb%257D/' " +
1377
+ "when used to expand 'http://example.com/{a}/'" do
1378
+ Addressable::Template.new(
1379
+ "http://example.com/{a}/"
1380
+ ).expand(@mapping).to_s.should == "http://example.com/%257Bb%257D/"
1381
+ end
1382
+ end
1383
+
1384
+ describe Addressable::URI, "when given a pattern with bogus operators" do
1385
+ it "should raise an InvalidTemplateOperatorError" do
1386
+ (lambda do
1387
+ Addressable::Template.new(
1388
+ "http://example.com/{-bogus|/|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/{-prefix|/|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/{-suffix|/|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/{-join|/|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
+
1433
+ it "should raise an InvalidTemplateOperatorError" do
1434
+ (lambda do
1435
+ Addressable::Template.new(
1436
+ "http://example.com/{-list|/|a,b,c}/"
1437
+ ).expand({
1438
+ "a" => ["a"], "b" => ["b"], "c" => "c"
1439
+ })
1440
+ end).should raise_error(
1441
+ Addressable::Template::InvalidTemplateOperatorError
1442
+ )
1443
+ end
1444
+ end
1445
+
1446
+ describe Addressable::Template, "with a partially expanded template" do
1447
+ before do
1448
+ @initial_template = Addressable::Template.new(
1449
+ "http://example.com/{one}/{two}/"
1450
+ )
1451
+ @partial_template = @initial_template.partial_expand({"one" => "1"})
1452
+ end
1453
+
1454
+ it "should produce the same result when fully expanded" do
1455
+ @initial_template.expand({"one" => "1", "two" => "2"}).should ==
1456
+ @partial_template.expand({"two" => "2"})
1457
+ end
1458
+ end
1459
+
1460
+ describe Addressable::Template, "with a partially expanded template" do
1461
+ before do
1462
+ @initial_template = Addressable::Template.new(
1463
+ "http://example.com/{one}/{two}/"
1464
+ )
1465
+ @partial_template = @initial_template.partial_expand({"two" => "2"})
1466
+ end
1467
+
1468
+ it "should produce the same result when fully expanded" do
1469
+ @initial_template.expand({"one" => "1", "two" => "2"}).should ==
1470
+ @partial_template.expand({"one" => "1"})
1471
+ end
1472
+ end
1473
+
1474
+ describe Addressable::Template, "with a partially expanded template" do
1475
+ before do
1476
+ @initial_template = Addressable::Template.new(
1477
+ "http://example.com/{one}/{two}/"
1478
+ )
1479
+ @partial_template = @initial_template.partial_expand({"two" => "2"})
1480
+ end
1481
+
1482
+ it "should produce the same result when fully expanded" do
1483
+ @initial_template.expand({"one" => "1", "two" => "2"}).should ==
1484
+ @partial_template.expand({"one" => "1"})
1485
+ end
1486
+ end
1487
+
1488
+ describe Addressable::Template, "with a partially expanded template" do
1489
+ before do
1490
+ @initial_template = Addressable::Template.new(
1491
+ "http://example.com/{one=1}/{two=2}/"
1492
+ )
1493
+ @partial_template = @initial_template.partial_expand({"one" => "3"})
1494
+ end
1495
+
1496
+ it "should produce the same result when fully expanded" do
1497
+ @initial_template.expand({"one" => "3", "two" => "4"}).should ==
1498
+ @partial_template.expand({"two" => "4"})
1499
+ end
1500
+
1501
+ it "should produce the correct result when fully expanded" do
1502
+ @partial_template.expand({}).should === "http://example.com/3/2/"
1503
+ end
1504
+ end
1505
+
1506
+ describe Addressable::Template, "with a partially expanded template" do
1507
+ before do
1508
+ @initial_template = Addressable::Template.new(
1509
+ "http://example.com/{one=1}/{two=2}/"
1510
+ )
1511
+ @partial_template = @initial_template.partial_expand({"two" => "4"})
1512
+ end
1513
+
1514
+ it "should produce the same result when fully expanded" do
1515
+ @initial_template.expand({"one" => "3", "two" => "4"}).should ==
1516
+ @partial_template.expand({"one" => "3"})
1517
+ end
1518
+
1519
+ it "should produce the correct result when fully expanded" do
1520
+ @partial_template.expand({}).should === "http://example.com/1/4/"
1521
+ end
1522
+ end
1523
+
1524
+ describe Addressable::Template, "with a partially expanded template" do
1525
+ before do
1526
+ @initial_template = Addressable::Template.new(
1527
+ "http://example.com/{-opt|found|one,two,three}"
1528
+ )
1529
+ @partial_template = @initial_template.partial_expand({})
1530
+ end
1531
+
1532
+ it "should produce the same result when fully expanded" do
1533
+ @initial_template.expand({"one" => "1"}).to_str.should ==
1534
+ @partial_template.expand({"two" => "2"}).to_str
1535
+ end
1536
+
1537
+ it "should produce the correct result when fully expanded" do
1538
+ @partial_template.expand({}).to_str.should == "http://example.com/"
1539
+ end
1540
+
1541
+ it "should produce the correct result when fully expanded" do
1542
+ @partial_template.expand({"one" => "1"}).to_str.should ==
1543
+ "http://example.com/found"
1544
+ end
1545
+
1546
+ it "should produce the correct result when fully expanded" do
1547
+ @partial_template.expand({"two" => "2"}).to_str.should ==
1548
+ "http://example.com/found"
1549
+ end
1550
+
1551
+ it "should produce the correct result when fully expanded" do
1552
+ @partial_template.expand({"three" => "3"}).to_str.should ==
1553
+ "http://example.com/found"
1554
+ end
1555
+
1556
+ it "should produce the correct result when fully expanded" do
1557
+ @partial_template.expand({"four" => "4"}).to_str.should ==
1558
+ "http://example.com/"
1559
+ end
1560
+
1561
+ it "should produce the correct result when fully expanded" do
1562
+ @partial_template.expand({"one" => "1", "two" => "2"}).to_str.should ==
1563
+ "http://example.com/found"
1564
+ end
1565
+ end
1566
+
1567
+ describe Addressable::Template, "with a partially expanded template" do
1568
+ before do
1569
+ @initial_template = Addressable::Template.new(
1570
+ "http://example.com/{-opt|found|one,two,three}"
1571
+ )
1572
+ @partial_template = @initial_template.partial_expand({"one" => "1"})
1573
+ end
1574
+
1575
+ it "should produce the same result when fully expanded" do
1576
+ @initial_template.expand({"one" => "1"}).to_str.should ==
1577
+ @partial_template.expand({"two" => "2"}).to_str
1578
+ end
1579
+
1580
+ it "should produce the correct result when fully expanded" do
1581
+ @partial_template.expand({}).to_str.should == "http://example.com/found"
1582
+ end
1583
+
1584
+ it "should produce the correct pattern" do
1585
+ @partial_template.pattern.should == "http://example.com/found"
1586
+ end
1587
+ end
1588
+
1589
+ describe Addressable::Template, "with a partially expanded template" do
1590
+ before do
1591
+ @initial_template = Addressable::Template.new(
1592
+ "http://example.com/{-neg|notfound|one,two,three}"
1593
+ )
1594
+ @partial_template = @initial_template.partial_expand({})
1595
+ end
1596
+
1597
+ it "should produce the same result when fully expanded" do
1598
+ @initial_template.expand({"one" => "1"}).to_str.should ==
1599
+ @partial_template.expand({"two" => "2"}).to_str
1600
+ end
1601
+
1602
+ it "should produce the correct result when fully expanded" do
1603
+ @partial_template.expand({}).to_str.should == "http://example.com/notfound"
1604
+ end
1605
+
1606
+ it "should produce the correct result when fully expanded" do
1607
+ @partial_template.expand({"one" => "1"}).to_str.should ==
1608
+ "http://example.com/"
1609
+ end
1610
+
1611
+ it "should produce the correct result when fully expanded" do
1612
+ @partial_template.expand({"two" => "2"}).to_str.should ==
1613
+ "http://example.com/"
1614
+ end
1615
+
1616
+ it "should produce the correct result when fully expanded" do
1617
+ @partial_template.expand({"three" => "3"}).to_str.should ==
1618
+ "http://example.com/"
1619
+ end
1620
+
1621
+ it "should produce the correct result when fully expanded" do
1622
+ @partial_template.expand({"four" => "4"}).to_str.should ==
1623
+ "http://example.com/notfound"
1624
+ end
1625
+
1626
+ it "should produce the correct result when fully expanded" do
1627
+ @partial_template.expand({"one" => "1", "two" => "2"}).to_str.should ==
1628
+ "http://example.com/"
1629
+ end
1630
+ end
1631
+
1632
+ describe Addressable::Template, "with a partially expanded template" do
1633
+ before do
1634
+ @initial_template = Addressable::Template.new(
1635
+ "http://example.com/{-neg|notfound|one,two,three}"
1636
+ )
1637
+ @partial_template = @initial_template.partial_expand({"one" => "1"})
1638
+ end
1639
+
1640
+ it "should produce the same result when fully expanded" do
1641
+ @initial_template.expand({"one" => "1"}).to_str.should ==
1642
+ @partial_template.expand({"two" => "2"}).to_str
1643
+ end
1644
+
1645
+ it "should produce the correct result when fully expanded" do
1646
+ @partial_template.expand({}).to_str.should == "http://example.com/"
1647
+ end
1648
+
1649
+ it "should produce the correct pattern" do
1650
+ @partial_template.pattern.should == "http://example.com/"
1651
+ end
1652
+ end
1653
+
1654
+ describe Addressable::Template, "with a partially expanded template" do
1655
+ before do
1656
+ @initial_template = Addressable::Template.new(
1657
+ "http://example.com/?{-prefix|x=|one}"
1658
+ )
1659
+ @partial_template = @initial_template.partial_expand({})
1660
+ end
1661
+
1662
+ it "should produce the same result when fully expanded" do
1663
+ @initial_template.expand({"one" => "1"}).to_str.should ==
1664
+ @partial_template.expand({"one" => "1"}).to_str
1665
+ end
1666
+
1667
+ it "should produce the correct result when fully expanded" do
1668
+ @partial_template.expand({}).to_str.should == "http://example.com/?"
1669
+ end
1670
+
1671
+ it "should produce the correct result when fully expanded" do
1672
+ @partial_template.expand({"one" => "1"}).to_str.should ==
1673
+ "http://example.com/?x=1"
1674
+ end
1675
+
1676
+ it "should produce the correct result when fully expanded" do
1677
+ @partial_template.expand({"two" => "2"}).to_str.should ==
1678
+ "http://example.com/?"
1679
+ end
1680
+
1681
+ it "should produce the correct result when fully expanded" do
1682
+ @partial_template.expand({"one" => "1", "two" => "2"}).to_str.should ==
1683
+ "http://example.com/?x=1"
1684
+ end
1685
+ end
1686
+
1687
+ describe Addressable::Template, "with a partially expanded template" do
1688
+ before do
1689
+ @initial_template = Addressable::Template.new(
1690
+ "http://example.com/?{-prefix|x=|one}"
1691
+ )
1692
+ @partial_template = @initial_template.partial_expand({"one" => "1"})
1693
+ end
1694
+
1695
+ it "should produce the same result when fully expanded" do
1696
+ @initial_template.expand({"one" => "1"}).to_str.should ==
1697
+ @partial_template.expand({}).to_str
1698
+ end
1699
+
1700
+ it "should produce the correct result when fully expanded" do
1701
+ @partial_template.expand({}).to_str.should == "http://example.com/?x=1"
1702
+ end
1703
+
1704
+ it "should produce the correct pattern" do
1705
+ @partial_template.pattern.should == "http://example.com/?x=1"
1706
+ end
1707
+ end
1708
+
1709
+ describe Addressable::Template, "with a partially expanded template" do
1710
+ before do
1711
+ @initial_template = Addressable::Template.new(
1712
+ "http://example.com/?{-suffix|=x|one}"
1713
+ )
1714
+ @partial_template = @initial_template.partial_expand({})
1715
+ end
1716
+
1717
+ it "should produce the same result when fully expanded" do
1718
+ @initial_template.expand({"one" => "1"}).to_str.should ==
1719
+ @partial_template.expand({"one" => "1"}).to_str
1720
+ end
1721
+
1722
+ it "should produce the correct result when fully expanded" do
1723
+ @partial_template.expand({}).to_str.should == "http://example.com/?"
1724
+ end
1725
+
1726
+ it "should produce the correct result when fully expanded" do
1727
+ @partial_template.expand({"one" => "1"}).to_str.should ==
1728
+ "http://example.com/?1=x"
1729
+ end
1730
+
1731
+ it "should produce the correct result when fully expanded" do
1732
+ @partial_template.expand({"two" => "2"}).to_str.should ==
1733
+ "http://example.com/?"
1734
+ end
1735
+
1736
+ it "should produce the correct result when fully expanded" do
1737
+ @partial_template.expand({"one" => "1", "two" => "2"}).to_str.should ==
1738
+ "http://example.com/?1=x"
1739
+ end
1740
+ end
1741
+
1742
+ describe Addressable::Template, "with a partially expanded template" do
1743
+ before do
1744
+ @initial_template = Addressable::Template.new(
1745
+ "http://example.com/?{-suffix|=x|one}"
1746
+ )
1747
+ @partial_template = @initial_template.partial_expand({"one" => "1"})
1748
+ end
1749
+
1750
+ it "should produce the same result when fully expanded" do
1751
+ @initial_template.expand({"one" => "1"}).to_str.should ==
1752
+ @partial_template.expand({}).to_str
1753
+ end
1754
+
1755
+ it "should produce the correct result when fully expanded" do
1756
+ @partial_template.expand({}).to_str.should == "http://example.com/?1=x"
1757
+ end
1758
+
1759
+ it "should produce the correct pattern" do
1760
+ @partial_template.pattern.should == "http://example.com/?1=x"
1761
+ end
1762
+ end
1763
+
1764
+ describe Addressable::Template, "with a partially expanded template" do
1765
+ before do
1766
+ @initial_template = Addressable::Template.new(
1767
+ "http://example.com/?{-join|&|one}"
1768
+ )
1769
+ @partial_template = @initial_template.partial_expand({})
1770
+ end
1771
+
1772
+ it "should produce the same result when fully expanded" do
1773
+ @initial_template.expand({"one" => "1"}).to_str.should ==
1774
+ @partial_template.expand({"one" => "1"}).to_str
1775
+ end
1776
+
1777
+ it "should produce the correct result when fully expanded" do
1778
+ @partial_template.expand({}).to_str.should == "http://example.com/?"
1779
+ end
1780
+
1781
+ it "should produce the correct result when fully expanded" do
1782
+ @partial_template.pattern.should == @initial_template.pattern
1783
+ end
1784
+ end
1785
+
1786
+ describe Addressable::Template, "with a partially expanded template" do
1787
+ before do
1788
+ @initial_template = Addressable::Template.new(
1789
+ "http://example.com/?{-join|&|one,two}"
1790
+ )
1791
+ @partial_template = @initial_template.partial_expand({"one" => "1"})
1792
+ end
1793
+
1794
+ it "should produce the same result when fully expanded" do
1795
+ @initial_template.expand({"one" => "1", "two" => "2"}).to_str.should ==
1796
+ @partial_template.expand({"two" => "2"}).to_str
1797
+ end
1798
+
1799
+ it "should produce the correct result when fully expanded" do
1800
+ @partial_template.expand({}).to_str.should == "http://example.com/?one=1"
1801
+ end
1802
+ end
1803
+
1804
+ describe Addressable::Template, "with a partially expanded template" do
1805
+ before do
1806
+ @initial_template = Addressable::Template.new(
1807
+ "http://example.com/?{-join|&|one,two}"
1808
+ )
1809
+ @partial_template = @initial_template.partial_expand({"two" => "2"})
1810
+ end
1811
+
1812
+ it "should produce the same result when fully expanded" do
1813
+ @initial_template.expand({"one" => "1", "two" => "2"}).to_str.should ==
1814
+ @partial_template.expand({"one" => "1"}).to_str
1815
+ end
1816
+
1817
+ it "should produce the correct result when fully expanded" do
1818
+ @partial_template.expand({}).to_str.should == "http://example.com/?two=2"
1819
+ end
1820
+ end
1821
+
1822
+ describe Addressable::Template, "with a partially expanded template" do
1823
+ before do
1824
+ @initial_template = Addressable::Template.new(
1825
+ "http://example.com/?{-join|&|one,two,three}"
1826
+ )
1827
+ @partial_template = @initial_template.partial_expand({"one" => "1"})
1828
+ end
1829
+
1830
+ it "should produce the same result when fully expanded" do
1831
+ @initial_template.expand({
1832
+ "one" => "1", "two" => "2", "three" => "3"
1833
+ }).to_str.should ==
1834
+ @partial_template.expand({"two" => "2", "three" => "3"}).to_str
1835
+ end
1836
+
1837
+ it "should produce the correct result when fully expanded" do
1838
+ @partial_template.expand({}).to_str.should == "http://example.com/?one=1"
1839
+ end
1840
+
1841
+ it "should produce the correct result when fully expanded" do
1842
+ @partial_template.expand({"two" => "2"}).to_str.should ==
1843
+ "http://example.com/?one=1&two=2"
1844
+ end
1845
+
1846
+ it "should produce the correct result when fully expanded" do
1847
+ @partial_template.expand({"three" => "3"}).to_str.should ==
1848
+ "http://example.com/?one=1&three=3"
1849
+ end
1850
+ end
1851
+
1852
+ describe Addressable::Template, "with a partially expanded template" do
1853
+ before do
1854
+ @initial_template = Addressable::Template.new(
1855
+ "http://example.com/?{-join|&|one,two,three}"
1856
+ )
1857
+ @partial_template = @initial_template.partial_expand({"two" => "2"})
1858
+ end
1859
+
1860
+ it "should produce the same result when fully expanded" do
1861
+ @initial_template.expand({
1862
+ "one" => "1", "two" => "2", "three" => "3"
1863
+ }).to_str.should ==
1864
+ @partial_template.expand({"one" => "1", "three" => "3"}).to_str
1865
+ end
1866
+
1867
+ it "should produce the correct result when fully expanded" do
1868
+ @partial_template.expand({}).to_str.should == "http://example.com/?two=2"
1869
+ end
1870
+
1871
+ it "should produce the correct result when fully expanded" do
1872
+ @partial_template.expand({"one" => "1"}).to_str.should ==
1873
+ "http://example.com/?one=1&two=2"
1874
+ end
1875
+
1876
+ it "should produce the correct result when fully expanded" do
1877
+ @partial_template.expand({"three" => "3"}).to_str.should ==
1878
+ "http://example.com/?two=2&three=3"
1879
+ end
1880
+ end
1881
+
1882
+ describe Addressable::Template, "with a partially expanded template" do
1883
+ before do
1884
+ @initial_template = Addressable::Template.new(
1885
+ "http://example.com/?{-join|&|one,two,three}"
1886
+ )
1887
+ @partial_template = @initial_template.partial_expand({"three" => "3"})
1888
+ end
1889
+
1890
+ it "should produce the same result when fully expanded" do
1891
+ @initial_template.expand({
1892
+ "one" => "1", "two" => "2", "three" => "3"
1893
+ }).to_str.should ==
1894
+ @partial_template.expand({"one" => "1", "two" => "2"}).to_str
1895
+ end
1896
+
1897
+ it "should produce the correct result when fully expanded" do
1898
+ @partial_template.expand({}).to_str.should == "http://example.com/?three=3"
1899
+ end
1900
+
1901
+ it "should produce the correct result when fully expanded" do
1902
+ @partial_template.expand({"one" => "1"}).to_str.should ==
1903
+ "http://example.com/?one=1&three=3"
1904
+ end
1905
+
1906
+ it "should produce the correct result when fully expanded" do
1907
+ @partial_template.expand({"two" => "2"}).to_str.should ==
1908
+ "http://example.com/?two=2&three=3"
1909
+ end
1910
+ end
1911
+
1912
+ describe Addressable::Template, "with a partially expanded template" do
1913
+ before do
1914
+ @initial_template = Addressable::Template.new(
1915
+ "http://example.com/?{-join|&|one,two,three}"
1916
+ )
1917
+ @partial_template = @initial_template.partial_expand({
1918
+ "one" => "1", "two" => "2"
1919
+ })
1920
+ end
1921
+
1922
+ it "should produce the same result when fully expanded" do
1923
+ @initial_template.expand({
1924
+ "one" => "1", "two" => "2", "three" => "3"
1925
+ }).to_str.should ==
1926
+ @partial_template.expand({"three" => "3"}).to_str
1927
+ end
1928
+
1929
+ it "should produce the correct result when fully expanded" do
1930
+ @partial_template.expand({}).to_str.should ==
1931
+ "http://example.com/?one=1&two=2"
1932
+ end
1933
+
1934
+ it "should produce the correct result when fully expanded" do
1935
+ @partial_template.expand({"three" => "3"}).to_str.should ==
1936
+ "http://example.com/?one=1&two=2&three=3"
1937
+ end
1938
+ end
1939
+
1940
+ describe Addressable::Template, "with a partially expanded template" do
1941
+ before do
1942
+ @initial_template = Addressable::Template.new(
1943
+ "http://example.com/?{-join|&|one,two,three}"
1944
+ )
1945
+ @partial_template = @initial_template.partial_expand({
1946
+ "one" => "1", "three" => "3"
1947
+ })
1948
+ end
1949
+
1950
+ it "should produce the same result when fully expanded" do
1951
+ @initial_template.expand({
1952
+ "one" => "1", "two" => "2", "three" => "3"
1953
+ }).to_str.should ==
1954
+ @partial_template.expand({"two" => "2"}).to_str
1955
+ end
1956
+
1957
+ it "should produce the correct result when fully expanded" do
1958
+ @partial_template.expand({}).to_str.should ==
1959
+ "http://example.com/?one=1&three=3"
1960
+ end
1961
+
1962
+ it "should produce the correct result when fully expanded" do
1963
+ @partial_template.expand({"two" => "2"}).to_str.should ==
1964
+ "http://example.com/?one=1&two=2&three=3"
1965
+ end
1966
+ end
1967
+
1968
+ describe Addressable::Template, "with a partially expanded template" do
1969
+ before do
1970
+ @initial_template = Addressable::Template.new(
1971
+ "http://example.com/?{-join|&|one,two,three}"
1972
+ )
1973
+ @partial_template = @initial_template.partial_expand({
1974
+ "two" => "2", "three" => "3"
1975
+ })
1976
+ end
1977
+
1978
+ it "should produce the same result when fully expanded" do
1979
+ @initial_template.expand({
1980
+ "one" => "1", "two" => "2", "three" => "3"
1981
+ }).to_str.should ==
1982
+ @partial_template.expand({"one" => "1"}).to_str
1983
+ end
1984
+
1985
+ it "should produce the correct result when fully expanded" do
1986
+ @partial_template.expand({}).to_str.should ==
1987
+ "http://example.com/?two=2&three=3"
1988
+ end
1989
+
1990
+ it "should produce the correct result when fully expanded" do
1991
+ @partial_template.expand({"one" => "1"}).to_str.should ==
1992
+ "http://example.com/?one=1&two=2&three=3"
1993
+ end
1994
+ end
1995
+
1996
+ describe Addressable::Template, "with a partially expanded template" do
1997
+ before do
1998
+ @initial_template = Addressable::Template.new(
1999
+ "http://example.com/?{-join|&|one,two,three}"
2000
+ )
2001
+ end
2002
+
2003
+ it "should raise an error when partially expanding a bogus operator" do
2004
+ (lambda do
2005
+ @initial_template.partial_expand({"one" => ["1"]})
2006
+ end).should raise_error(
2007
+ Addressable::Template::InvalidTemplateOperatorError
2008
+ )
2009
+ (lambda do
2010
+ @initial_template.partial_expand({"two" => "2", "three" => ["3"]})
2011
+ end).should raise_error(
2012
+ Addressable::Template::InvalidTemplateOperatorError
2013
+ )
2014
+ end
2015
+ end
2016
+
2017
+ describe Addressable::Template, "with a partially expanded template" do
2018
+ before do
2019
+ @initial_template = Addressable::Template.new(
2020
+ "http://example.com/{-list|/|numbers}/{-list|/|letters}/"
2021
+ )
2022
+ @partial_template = @initial_template.partial_expand({})
2023
+ end
2024
+
2025
+ it "should produce the same result when fully expanded" do
2026
+ @initial_template.expand({
2027
+ "numbers" => ["1", "2", "3"], "letters" => ["a", "b", "c"]
2028
+ }).to_str.should == @partial_template.expand({
2029
+ "numbers" => ["1", "2", "3"], "letters" => ["a", "b", "c"]
2030
+ }).to_str
2031
+ end
2032
+
2033
+ it "should produce the correct result when fully expanded" do
2034
+ @partial_template.expand({}).to_str.should == "http://example.com///"
2035
+ end
2036
+
2037
+ it "should produce the correct result when fully expanded" do
2038
+ @partial_template.pattern.should == @initial_template.pattern
2039
+ end
2040
+ end
2041
+
2042
+ describe Addressable::Template, "with a partially expanded template" do
2043
+ before do
2044
+ @initial_template = Addressable::Template.new(
2045
+ "http://example.com/{-list|/|numbers}/{-list|/|letters}/"
2046
+ )
2047
+ @partial_template = @initial_template.partial_expand({
2048
+ "numbers" => ["1", "2", "3"]
2049
+ })
2050
+ end
2051
+
2052
+ it "should produce the same result when fully expanded" do
2053
+ @initial_template.expand({
2054
+ "numbers" => ["1", "2", "3"], "letters" => ["a", "b", "c"]
2055
+ }).to_str.should == @partial_template.expand({
2056
+ "letters" => ["a", "b", "c"]
2057
+ }).to_str
2058
+ end
2059
+
2060
+ it "should produce the correct result when fully expanded" do
2061
+ @partial_template.expand({}).to_str.should == "http://example.com/1/2/3//"
2062
+ end
2063
+ end
2064
+
2065
+ describe Addressable::Template, "with a partially expanded template" do
2066
+ before do
2067
+ @initial_template = Addressable::Template.new(
2068
+ "http://example.com/{-list|/|numbers}/{-list|/|letters}/"
2069
+ )
2070
+ @partial_template = @initial_template.partial_expand({
2071
+ "letters" => ["a", "b", "c"]
2072
+ })
2073
+ end
2074
+
2075
+ it "should produce the same result when fully expanded" do
2076
+ @initial_template.expand({
2077
+ "numbers" => ["1", "2", "3"], "letters" => ["a", "b", "c"]
2078
+ }).to_str.should == @partial_template.expand({
2079
+ "numbers" => ["1", "2", "3"]
2080
+ }).to_str
2081
+ end
2082
+
2083
+ it "should produce the correct result when fully expanded" do
2084
+ @partial_template.expand({}).to_str.should == "http://example.com//a/b/c/"
2085
+ end
2086
+ end
2087
+
2088
+ describe Addressable::Template, "with a partially expanded template" do
2089
+ before do
2090
+ @initial_template = Addressable::Template.new(
2091
+ "http://example.com/{-list|/|numbers}/{-list|/|letters}/"
2092
+ )
2093
+ end
2094
+
2095
+ it "should raise an error when partially expanding a bogus operator" do
2096
+ (lambda do
2097
+ @initial_template.partial_expand({"numbers" => "1"})
2098
+ end).should raise_error(
2099
+ Addressable::Template::InvalidTemplateOperatorError
2100
+ )
2101
+ (lambda do
2102
+ @initial_template.partial_expand({"letters" => "a"})
2103
+ end).should raise_error(
2104
+ Addressable::Template::InvalidTemplateOperatorError
2105
+ )
2106
+ end
2107
+ end
2108
+
2109
+ describe Addressable::Template, "with a partially expanded template" do
2110
+ before do
2111
+ @initial_template = Addressable::Template.new(
2112
+ "http://example.com/{-bogus|/|one,two}/"
2113
+ )
2114
+ end
2115
+
2116
+ it "should raise an error when partially expanding a bogus operator" do
2117
+ (lambda do
2118
+ @initial_template.partial_expand({"one" => "1"})
2119
+ end).should raise_error(
2120
+ Addressable::Template::InvalidTemplateOperatorError
2121
+ )
2122
+ end
2123
+ end