honkster-addressable 2.1.2

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