addressable 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,32 @@
1
+ #--
2
+ # Addressable, Copyright (c) 2006-2007 Bob Aman
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ module Addressable
25
+ module ADDRESSABLE_VERSION #:nodoc:
26
+ MAJOR = 0
27
+ MINOR = 1
28
+ TINY = 0
29
+
30
+ STRING = [MAJOR, MINOR, TINY].join('.')
31
+ end
32
+ end
@@ -0,0 +1,251 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/contrib/rubyforgepublisher'
8
+ require 'spec/rake/spectask'
9
+
10
+ require File.join(File.dirname(__FILE__), 'lib/addressable', 'version')
11
+
12
+ PKG_DISPLAY_NAME = 'Addressable'
13
+ PKG_NAME = PKG_DISPLAY_NAME.downcase
14
+ PKG_VERSION = Addressable::ADDRESSABLE_VERSION::STRING
15
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
16
+
17
+ RELEASE_NAME = "REL #{PKG_VERSION}"
18
+
19
+ RUBY_FORGE_PROJECT = PKG_NAME
20
+ RUBY_FORGE_USER = "sporkmonger"
21
+ RUBY_FORGE_PATH = "/var/www/gforge-projects/#{RUBY_FORGE_PROJECT}"
22
+
23
+ PKG_SUMMARY = "URI Implementation"
24
+ PKG_DESCRIPTION = <<-TEXT
25
+ Addressable is a replacement for the URI implementation that is part of
26
+ Ruby's standard library. It more closely conforms to the relevant RFCs and
27
+ adds support for IRIs and URI templates.
28
+ TEXT
29
+
30
+ PKG_FILES = FileList[
31
+ "lib/**/*", "spec/**/*", "vendor/**/*",
32
+ "doc/**/*", "specdoc/**/*", "coverage/**/*",
33
+ "[A-Z]*", "rakefile"
34
+ ].exclude(/\bCVS\b|~$/).exclude(/database\.yml/).exclude(/[_\.]svn$/)
35
+
36
+ module Rake
37
+ def self.browse(filepath)
38
+ if RUBY_PLATFORM =~ /mswin/
39
+ system(filepath)
40
+ else
41
+ try_browsers = lambda do
42
+ result = true
43
+ if !(`which firefox 2>&1` =~ /no firefox/)
44
+ system("firefox #{filepath}")
45
+ elsif !(`which mozilla 2>&1` =~ /no mozilla/)
46
+ system("mozilla #{filepath}")
47
+ elsif !(`which netscape 2>&1` =~ /no netscape/)
48
+ system("netscape #{filepath}")
49
+ elsif !(`which links 2>&1` =~ /no links/)
50
+ system("links #{filepath}")
51
+ elsif !(`which lynx 2>&1` =~ /no lynx/)
52
+ system("lynx #{filepath}")
53
+ else
54
+ result = false
55
+ end
56
+ result
57
+ end
58
+ opened = false
59
+ if RUBY_PLATFORM =~ /darwin/
60
+ opened = true
61
+ system("open #{filepath}")
62
+ elsif !(`which gnome-open 2>&1` =~ /no gnome-open/)
63
+ success =
64
+ !(`gnome-open #{filepath} 2>&1` =~ /There is no default action/)
65
+ if !success
66
+ opened = try_browsers.call()
67
+ else
68
+ opened = true
69
+ end
70
+ else
71
+ opened = try_browsers.call()
72
+ end
73
+ if !opened
74
+ puts "Don't know how to browse to location."
75
+ end
76
+ end
77
+ end
78
+ end
79
+
80
+ task :default => [ "spec:run" ]
81
+
82
+ gem_spec = Gem::Specification.new do |s|
83
+ s.name = PKG_NAME
84
+ s.version = PKG_VERSION
85
+ s.summary = PKG_SUMMARY
86
+ s.description = PKG_DESCRIPTION
87
+
88
+ s.files = PKG_FILES.to_a
89
+
90
+ s.has_rdoc = true
91
+ s.extra_rdoc_files = %w( README )
92
+ s.rdoc_options.concat ['--main', 'README']
93
+
94
+ s.add_dependency('rake', '>= 0.7.2')
95
+ s.add_dependency('rspec', '>= 0.7.1')
96
+
97
+ s.require_path = 'lib'
98
+
99
+ s.author = "Bob Aman"
100
+ s.email = "bob@sporkmonger.com"
101
+ s.homepage = "http://sporkmonger.com/"
102
+ s.rubyforge_project = "addressable"
103
+ end
104
+
105
+ Rake::GemPackageTask.new(gem_spec) do |p|
106
+ p.gem_spec = gem_spec
107
+ p.need_tar = true
108
+ p.need_zip = true
109
+ end
110
+
111
+ Rake::RDocTask.new do |rdoc|
112
+ rdoc.rdoc_dir = 'doc'
113
+ rdoc.title = "Addressable -- URI Implementation"
114
+ rdoc.options << '--line-numbers' << '--inline-source' <<
115
+ '--accessor' << 'cattr_accessor=object'
116
+ rdoc.template = "#{ENV['template']}.rb" if ENV['template']
117
+ rdoc.rdoc_files.include('README', 'CHANGELOG', 'LICENSE')
118
+ rdoc.rdoc_files.include('lib/**/*.rb')
119
+ end
120
+
121
+ namespace :rcov do
122
+ desc 'Open the RCov code coverage report in a browser.'
123
+ task :browse do
124
+ if !File.exists?(File.expand_path(
125
+ File.dirname(__FILE__) + '/coverage/index.html'))
126
+ Rake::Task["spec:run"].invoke
127
+ end
128
+ Rake.browse(File.expand_path(
129
+ File.dirname(__FILE__) + '/coverage/index.html'))
130
+ end
131
+ end
132
+
133
+ namespace :spec do
134
+ desc "Run all the specs"
135
+ Spec::Rake::SpecTask.new(:run) do |t|
136
+ t.spec_files = FileList['spec/**/*_spec.rb']
137
+ t.spec_opts = ['--color']
138
+ t.rcov = true
139
+ t.rcov_opts = [
140
+ # Don't include the actual spec files in the coverage report
141
+ '--exclude', '"spec\/.*"'
142
+ ]
143
+ end
144
+
145
+ desc "Run all the specs"
146
+ Spec::Rake::SpecTask.new(:run_without_rcov) do |t|
147
+ t.spec_files = FileList['spec/**/*_spec.rb']
148
+ t.spec_opts = ['--color']
149
+ end
150
+
151
+ namespace :heckle do
152
+ desc "Heckle the URI class"
153
+ Spec::Rake::SpecTask.new(:uri) do |t|
154
+ t.spec_files = FileList['spec/addressable/uri_spec.rb']
155
+ t.spec_opts = ['--heckle', 'Addressable::URI']
156
+ end
157
+ end
158
+
159
+ # desc "Start up autotest for RSpec"
160
+ # task :autospec do
161
+ # require 'autotest'
162
+ # require 'autotest/growl'
163
+ # require 'autotest/redgreen'
164
+ # require 'vendor/autospec/lib/autospec'
165
+ # Autospec.run
166
+ # end
167
+
168
+ desc "Print Specdoc for all specs"
169
+ Spec::Rake::SpecTask.new(:doc) do |t|
170
+ t.spec_files = FileList[
171
+ 'spec/**/*_spec.rb'
172
+ ]
173
+ t.spec_opts = ["--format", "specdoc"]
174
+ end
175
+
176
+ desc "Generate HTML Specdocs for all specs"
177
+ Spec::Rake::SpecTask.new(:html) do |t|
178
+ if !File.exists?(
179
+ File.expand_path(File.dirname(__FILE__) + '/specdoc/'))
180
+ puts "Creating specdoc folder..."
181
+ Dir.mkdir(File.expand_path(File.dirname(__FILE__) + '/specdoc/'))
182
+ end
183
+
184
+ t.spec_files = FileList['spec/**/*_spec.rb']
185
+ t.spec_opts = ["--format", "html"]
186
+ t.out = File.expand_path(
187
+ File.dirname(__FILE__) + '/specdoc/index.html')
188
+ end
189
+
190
+ desc 'Open the RSpec HTML specifications in a browser.'
191
+ task :browse => [ "spec:html" ] do
192
+ Rake.browse(File.expand_path(
193
+ File.dirname(__FILE__) + '/specdoc/index.html'))
194
+ end
195
+ end
196
+
197
+ namespace :publish do
198
+ desc "Publish the coverage report"
199
+ task :coverage => [ "spec:run" ] do
200
+ Rake::SshDirPublisher.new(
201
+ "#{RUBY_FORGE_USER}@rubyforge.org",
202
+ "#{RUBY_FORGE_PATH}/coverage/",
203
+ "coverage"
204
+ ).upload
205
+ end
206
+
207
+ desc "Publish the specifications"
208
+ task :specs => [ "spec:html" ] do
209
+ Rake::SshDirPublisher.new(
210
+ "#{RUBY_FORGE_USER}@rubyforge.org",
211
+ "#{RUBY_FORGE_PATH}/specdoc/",
212
+ "specdoc"
213
+ ).upload
214
+ end
215
+
216
+ desc "Publish the API documentation"
217
+ task :api => [ "rdoc" ] do
218
+ Rake::SshDirPublisher.new(
219
+ "#{RUBY_FORGE_USER}@rubyforge.org",
220
+ "#{RUBY_FORGE_PATH}/api/",
221
+ "doc"
222
+ ).upload
223
+ end
224
+
225
+ desc "Runs all of the publishing tasks"
226
+ task :all => ["publish:coverage", "publish:api", "publish:specs"] do
227
+ end
228
+ end
229
+
230
+ task :lines do
231
+ lines, codelines, total_lines, total_codelines = 0, 0, 0, 0
232
+
233
+ for file_name in FileList["lib/**/*.rb"]
234
+ f = File.open(file_name)
235
+
236
+ while line = f.gets
237
+ lines += 1
238
+ next if line =~ /^\s*$/
239
+ next if line =~ /^\s*#/
240
+ codelines += 1
241
+ end
242
+ puts "L: #{sprintf("%4d", lines)}, LOC #{sprintf("%4d", codelines)} | #{file_name}"
243
+
244
+ total_lines += lines
245
+ total_codelines += codelines
246
+
247
+ lines, codelines = 0, 0
248
+ end
249
+
250
+ puts "Total: Lines #{total_lines}, LOC #{total_codelines}"
251
+ end
@@ -0,0 +1,2278 @@
1
+ #--
2
+ # Addressable, Copyright (c) 2006-2007 Bob Aman
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../../lib'))
25
+ $:.uniq!
26
+
27
+ require 'addressable/uri'
28
+
29
+ class ExampleProcessor
30
+ def self.validate(name, value)
31
+ return !!(value =~ /^[\w ]+$/) if name == "query"
32
+ return true
33
+ end
34
+
35
+ def self.transform(name, value)
36
+ return value.gsub(/ /, "+") if name == "query"
37
+ return value
38
+ end
39
+ end
40
+
41
+ context "A completely nil URI" do
42
+ specify "should raise an error" do
43
+ (lambda do
44
+ Addressable::URI.new(nil, nil, nil, nil, nil, nil, nil, nil)
45
+ end).should.raise(Addressable::URI::InvalidURIError)
46
+ end
47
+ end
48
+
49
+ context "A URI with a non-numeric port number" do
50
+ specify "should raise an error" do
51
+ (lambda do
52
+ Addressable::URI.new(nil, nil, nil, nil, "bogus", nil, nil, nil)
53
+ end).should.raise(Addressable::URI::InvalidURIError)
54
+ end
55
+ end
56
+
57
+ context "A URI with a scheme but no hierarchical segment" do
58
+ specify "should raise an error" do
59
+ (lambda do
60
+ Addressable::URI.parse("http:")
61
+ end).should.raise(Addressable::URI::InvalidURIError)
62
+ end
63
+ end
64
+
65
+ context "A constructed URI" do
66
+ setup do
67
+ @uri = Addressable::URI.new(
68
+ "http", nil, nil, "example.com", nil, nil, nil, nil)
69
+ end
70
+
71
+ specify "should be equal to the equivalent parsed URI" do
72
+ @uri.should == Addressable::URI.parse("http://example.com")
73
+ end
74
+ end
75
+
76
+ # Section 1.1.2 of RFC 3986
77
+ context "ftp://ftp.is.co.za/rfc/rfc1808.txt" do
78
+ setup do
79
+ @uri = Addressable::URI.parse("ftp://ftp.is.co.za/rfc/rfc1808.txt")
80
+ end
81
+
82
+ specify "should use the 'ftp' scheme" do
83
+ @uri.scheme.should == "ftp"
84
+ end
85
+
86
+ specify "should be considered to be ip-based" do
87
+ @uri.should.be.ip_based
88
+ end
89
+
90
+ specify "should have a host of 'ftp.is.co.za'" do
91
+ @uri.host.should == "ftp.is.co.za"
92
+ end
93
+
94
+ specify "should have a path of '/rfc/rfc1808.txt'" do
95
+ @uri.path.should == "/rfc/rfc1808.txt"
96
+ end
97
+
98
+ specify "should be considered to be in normal form" do
99
+ @uri.normalize.should.be.eql @uri
100
+ end
101
+ end
102
+
103
+ # Section 1.1.2 of RFC 3986
104
+ context "http://www.ietf.org/rfc/rfc2396.txt" do
105
+ setup do
106
+ @uri = Addressable::URI.parse("http://www.ietf.org/rfc/rfc2396.txt")
107
+ end
108
+
109
+ specify "should use the 'http' scheme" do
110
+ @uri.scheme.should == "http"
111
+ end
112
+
113
+ specify "should be considered to be ip-based" do
114
+ @uri.should.be.ip_based
115
+ end
116
+
117
+ specify "should have a host of 'www.ietf.org'" do
118
+ @uri.host.should == "www.ietf.org"
119
+ end
120
+
121
+ specify "should have a path of '/rfc/rfc2396.txt'" do
122
+ @uri.path.should == "/rfc/rfc2396.txt"
123
+ end
124
+
125
+ specify "should be considered to be in normal form" do
126
+ @uri.normalize.should.be.eql @uri
127
+ end
128
+ end
129
+
130
+ # Section 1.1.2 of RFC 3986
131
+ context "ldap://[2001:db8::7]/c=GB?objectClass?one" do
132
+ setup do
133
+ @uri = Addressable::URI.parse("ldap://[2001:db8::7]/c=GB?objectClass?one")
134
+ end
135
+
136
+ specify "should use the 'ldap' scheme" do
137
+ @uri.scheme.should == "ldap"
138
+ end
139
+
140
+ specify "should be considered to be ip-based" do
141
+ @uri.should.be.ip_based
142
+ end
143
+
144
+ specify "should have a host of '[2001:db8::7]'" do
145
+ @uri.host.should == "[2001:db8::7]"
146
+ end
147
+
148
+ specify "should have a path of '/c=GB'" do
149
+ @uri.path.should == "/c=GB"
150
+ end
151
+
152
+ specify "should have a query of 'objectClass?one'" do
153
+ @uri.query.should == "objectClass?one"
154
+ end
155
+
156
+ specify "should be considered to be in normal form" do
157
+ @uri.normalize.should.be.eql @uri
158
+ end
159
+ end
160
+
161
+ # Section 1.1.2 of RFC 3986
162
+ context "mailto:John.Doe@example.com" do
163
+ setup do
164
+ @uri = Addressable::URI.parse("mailto:John.Doe@example.com")
165
+ end
166
+
167
+ specify "should use the 'mailto' scheme" do
168
+ @uri.scheme.should == "mailto"
169
+ end
170
+
171
+ specify "should not be considered to be ip-based" do
172
+ @uri.should.not.be.ip_based
173
+ end
174
+
175
+ specify "should have a path of 'John.Doe@example.com'" do
176
+ @uri.path.should == "John.Doe@example.com"
177
+ end
178
+
179
+ specify "should be considered to be in normal form" do
180
+ @uri.normalize.should.be.eql @uri
181
+ end
182
+ end
183
+
184
+ # Section 1.1.2 of RFC 3986
185
+ context "news:comp.infosystems.www.servers.unix" do
186
+ setup do
187
+ @uri = Addressable::URI.parse("news:comp.infosystems.www.servers.unix")
188
+ end
189
+
190
+ specify "should use the 'news' scheme" do
191
+ @uri.scheme.should == "news"
192
+ end
193
+
194
+ specify "should not be considered to be ip-based" do
195
+ @uri.should.not.be.ip_based
196
+ end
197
+
198
+ specify "should have a path of 'comp.infosystems.www.servers.unix'" do
199
+ @uri.path.should == "comp.infosystems.www.servers.unix"
200
+ end
201
+
202
+ specify "should be considered to be in normal form" do
203
+ @uri.normalize.should.be.eql @uri
204
+ end
205
+ end
206
+
207
+ # Section 1.1.2 of RFC 3986
208
+ context "tel:+1-816-555-1212" do
209
+ setup do
210
+ @uri = Addressable::URI.parse("tel:+1-816-555-1212")
211
+ end
212
+
213
+ specify "should use the 'tel' scheme" do
214
+ @uri.scheme.should == "tel"
215
+ end
216
+
217
+ specify "should not be considered to be ip-based" do
218
+ @uri.should.not.be.ip_based
219
+ end
220
+
221
+ specify "should have a path of '+1-816-555-1212'" do
222
+ @uri.path.should == "+1-816-555-1212"
223
+ end
224
+
225
+ specify "should be considered to be in normal form" do
226
+ @uri.normalize.should.be.eql @uri
227
+ end
228
+ end
229
+
230
+ # Section 1.1.2 of RFC 3986
231
+ context "telnet://192.0.2.16:80/" do
232
+ setup do
233
+ @uri = Addressable::URI.parse("telnet://192.0.2.16:80/")
234
+ end
235
+
236
+ specify "should use the 'telnet' scheme" do
237
+ @uri.scheme.should == "telnet"
238
+ end
239
+
240
+ specify "should have a host of '192.0.2.16'" do
241
+ @uri.host.should == "192.0.2.16"
242
+ end
243
+
244
+ specify "should have a port of '80'" do
245
+ @uri.port.should == 80
246
+ end
247
+
248
+ specify "should be considered to be ip-based" do
249
+ @uri.should.be.ip_based
250
+ end
251
+
252
+ specify "should have a path of '/'" do
253
+ @uri.path.should == "/"
254
+ end
255
+
256
+ specify "should be considered to be in normal form" do
257
+ @uri.normalize.should.be.eql @uri
258
+ end
259
+ end
260
+
261
+ # Section 1.1.2 of RFC 3986
262
+ context "urn:oasis:names:specification:docbook:dtd:xml:4.1.2" do
263
+ setup do
264
+ @uri = Addressable::URI.parse(
265
+ "urn:oasis:names:specification:docbook:dtd:xml:4.1.2")
266
+ end
267
+
268
+ specify "should use the 'urn' scheme" do
269
+ @uri.scheme.should == "urn"
270
+ end
271
+
272
+ specify "should not be considered to be ip-based" do
273
+ @uri.should.not.be.ip_based
274
+ end
275
+
276
+ specify "should have a path of " +
277
+ "'oasis:names:specification:docbook:dtd:xml:4.1.2'" do
278
+ @uri.path.should == "oasis:names:specification:docbook:dtd:xml:4.1.2"
279
+ end
280
+
281
+ specify "should be considered to be in normal form" do
282
+ @uri.normalize.should.be.eql @uri
283
+ end
284
+ end
285
+
286
+ context "http://example.com" do
287
+ setup do
288
+ @uri = Addressable::URI.parse("http://example.com")
289
+ end
290
+
291
+ specify "when inspected, should have the correct URI" do
292
+ @uri.inspect.should.include "http://example.com"
293
+ end
294
+
295
+ specify "should use the 'http' scheme" do
296
+ @uri.scheme.should == "http"
297
+ end
298
+
299
+ specify "should be considered to be ip-based" do
300
+ @uri.should.be.ip_based
301
+ end
302
+
303
+ specify "should have an authority segment of 'example.com'" do
304
+ @uri.authority.should == "example.com"
305
+ end
306
+
307
+ specify "should have a host of 'example.com'" do
308
+ @uri.host.should == "example.com"
309
+ end
310
+
311
+ specify "should be considered ip-based" do
312
+ @uri.should.be.ip_based
313
+ end
314
+
315
+ specify "should have no username" do
316
+ @uri.user.should == nil
317
+ end
318
+
319
+ specify "should have no password" do
320
+ @uri.password.should == nil
321
+ end
322
+
323
+ specify "should use port 80" do
324
+ @uri.port.should == 80
325
+ end
326
+
327
+ specify "should not have a specified port" do
328
+ @uri.specified_port.should == nil
329
+ end
330
+
331
+ specify "should have an empty path" do
332
+ @uri.path.should == ""
333
+ end
334
+
335
+ specify "should have no query string" do
336
+ @uri.query.should == nil
337
+ end
338
+
339
+ specify "should have no fragment" do
340
+ @uri.fragment.should == nil
341
+ end
342
+
343
+ specify "should be considered absolute" do
344
+ @uri.should.be.absolute
345
+ end
346
+
347
+ specify "should not be considered relative" do
348
+ @uri.should.not.be.relative
349
+ end
350
+
351
+ specify "should not be exactly equal to 42" do
352
+ @uri.eql?(42).should == false
353
+ end
354
+
355
+ specify "should not be equal to 42" do
356
+ (@uri == 42).should == false
357
+ end
358
+
359
+ specify "should not be roughly equal to 42" do
360
+ (@uri === 42).should == false
361
+ end
362
+
363
+ specify "should be exactly equal to http://example.com" do
364
+ @uri.eql?(Addressable::URI.parse("http://example.com")).should == true
365
+ end
366
+
367
+ specify "should be roughly equal to http://example.com/" do
368
+ (@uri === Addressable::URI.parse("http://example.com/")).should == true
369
+ end
370
+
371
+ specify "should be roughly equal to the string 'http://example.com/'" do
372
+ (@uri === "http://example.com/").should == true
373
+ end
374
+
375
+ specify "should not be roughly equal to the string " +
376
+ "'http://example.com:bogus/'" do
377
+ (lambda do
378
+ (@uri === "http://example.com:bogus/").should == false
379
+ end).should.not.raise
380
+ end
381
+
382
+ specify "should result in itself when merged with itself" do
383
+ @uri.merge(@uri).to_s.should == "http://example.com"
384
+ @uri.merge!(@uri).to_s.should == "http://example.com"
385
+ end
386
+
387
+ # Section 6.2.3 of RFC 3986
388
+ specify "should be equivalent to http://example.com/" do
389
+ @uri.should == Addressable::URI.parse("http://example.com/")
390
+ end
391
+
392
+ # Section 6.2.3 of RFC 3986
393
+ specify "should be equivalent to http://example.com:/" do
394
+ @uri.should == Addressable::URI.parse("http://example.com:/")
395
+ end
396
+
397
+ # Section 6.2.3 of RFC 3986
398
+ specify "should be equivalent to http://example.com:80/" do
399
+ @uri.should == Addressable::URI.parse("http://example.com:80/")
400
+ end
401
+
402
+ # Section 6.2.2.1 of RFC 3986
403
+ specify "should be equivalent to http://EXAMPLE.COM/" do
404
+ @uri.should == Addressable::URI.parse("http://EXAMPLE.COM/")
405
+ end
406
+
407
+ specify "should have a route of '/path/' to 'http://example.com/path/'" do
408
+ @uri.route_to("http://example.com/path/").should ==
409
+ Addressable::URI.parse("/path/")
410
+ end
411
+
412
+ specify "should have a route of '/' from 'http://example.com/path/'" do
413
+ @uri.route_from("http://example.com/path/").should ==
414
+ Addressable::URI.parse("/")
415
+ end
416
+
417
+ specify "should have a route of '#' to 'http://example.com/'" do
418
+ @uri.route_to("http://example.com/").should ==
419
+ Addressable::URI.parse("#")
420
+ end
421
+
422
+ specify "should have a route of 'http://elsewhere.com/' to " +
423
+ "'http://elsewhere.com/'" do
424
+ @uri.route_to("http://elsewhere.com/").should ==
425
+ Addressable::URI.parse("http://elsewhere.com/")
426
+ end
427
+
428
+ specify "should have the correct username after assignment" do
429
+ @uri.user = "newuser"
430
+ @uri.user.should == "newuser"
431
+ @uri.password.should == nil
432
+ @uri.to_s.should == "http://newuser@example.com"
433
+ end
434
+
435
+ specify "should have the correct password after assignment" do
436
+ @uri.password = "newpass"
437
+ @uri.password.should == "newpass"
438
+ @uri.user.should == ""
439
+ @uri.to_s.should == "http://:newpass@example.com"
440
+ end
441
+
442
+ specify "should have the correct user/pass after repeated assignment" do
443
+ @uri.user = nil
444
+ @uri.user.should == nil
445
+ @uri.password = "newpass"
446
+ @uri.password.should == "newpass"
447
+ # Username cannot be nil if the password is set
448
+ @uri.user.should == ""
449
+ @uri.to_s.should == "http://:newpass@example.com"
450
+ @uri.user = "newuser"
451
+ @uri.user.should == "newuser"
452
+ @uri.password = nil
453
+ @uri.password.should == nil
454
+ @uri.to_s.should == "http://newuser@example.com"
455
+ @uri.user = "newuser"
456
+ @uri.user.should == "newuser"
457
+ @uri.password = ""
458
+ @uri.password.should == ""
459
+ @uri.to_s.should == "http://newuser:@example.com"
460
+ @uri.password = "newpass"
461
+ @uri.password.should == "newpass"
462
+ @uri.user = nil
463
+ # Username cannot be nil if the password is set
464
+ @uri.user.should == ""
465
+ @uri.to_s.should == "http://:newpass@example.com"
466
+ end
467
+
468
+ specify "should have the correct user/pass after userinfo assignment" do
469
+ @uri.user = "newuser"
470
+ @uri.user.should == "newuser"
471
+ @uri.password = "newpass"
472
+ @uri.password.should == "newpass"
473
+ @uri.userinfo = nil
474
+ @uri.userinfo.should == nil
475
+ @uri.user.should == nil
476
+ @uri.password.should == nil
477
+ end
478
+
479
+ specify "should correctly convert to a hash" do
480
+ @uri.to_h.should == {
481
+ :scheme => "http",
482
+ :user => nil,
483
+ :password => nil,
484
+ :host => "example.com",
485
+ :port => nil,
486
+ :path => "",
487
+ :query => nil,
488
+ :fragment => nil
489
+ }
490
+ end
491
+ end
492
+
493
+ context "http://example.com/" do
494
+ setup do
495
+ @uri = Addressable::URI.parse("http://example.com/")
496
+ end
497
+
498
+ # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence
499
+ specify "should be equivalent to http://example.com" do
500
+ @uri.should == Addressable::URI.parse("http://example.com")
501
+ end
502
+
503
+ # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence
504
+ specify "should be equivalent to HTTP://example.com/" do
505
+ @uri.should == Addressable::URI.parse("HTTP://example.com/")
506
+ end
507
+
508
+ # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence
509
+ specify "should be equivalent to http://example.com:/" do
510
+ @uri.should == Addressable::URI.parse("http://example.com:/")
511
+ end
512
+
513
+ # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence
514
+ specify "should be equivalent to http://example.com:80/" do
515
+ @uri.should == Addressable::URI.parse("http://example.com:80/")
516
+ end
517
+
518
+ # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence
519
+ specify "should be equivalent to http://Example.com/" do
520
+ @uri.should == Addressable::URI.parse("http://Example.com/")
521
+ end
522
+
523
+ specify "should have the correct username after assignment" do
524
+ @uri.user = nil
525
+ @uri.user.should == nil
526
+ @uri.password.should == nil
527
+ @uri.to_s.should == "http://example.com/"
528
+ end
529
+
530
+ specify "should have the correct password after assignment" do
531
+ @uri.password = nil
532
+ @uri.password.should == nil
533
+ @uri.user.should == nil
534
+ @uri.to_s.should == "http://example.com/"
535
+ end
536
+
537
+ specify "should correctly convert to a hash" do
538
+ @uri.to_h.should == {
539
+ :scheme => "http",
540
+ :user => nil,
541
+ :password => nil,
542
+ :host => "example.com",
543
+ :port => nil,
544
+ :path => "/",
545
+ :query => nil,
546
+ :fragment => nil
547
+ }
548
+ end
549
+ end
550
+
551
+ context "http://example.com/~smith/" do
552
+ setup do
553
+ @uri = Addressable::URI.parse("http://example.com/~smith/")
554
+ end
555
+
556
+ # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence
557
+ specify "should be equivalent to http://example.com/%7Esmith/" do
558
+ @uri.should == Addressable::URI.parse("http://example.com/%7Esmith/")
559
+ end
560
+
561
+ # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence
562
+ specify "should be equivalent to http://example.com/%7esmith/" do
563
+ @uri.should == Addressable::URI.parse("http://example.com/%7esmith/")
564
+ end
565
+ end
566
+
567
+ context "http://example.com/%C3%87" do
568
+ setup do
569
+ @uri = Addressable::URI.parse("http://example.com/%C3%87")
570
+ end
571
+
572
+ # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence
573
+ specify "should be equivalent to 'http://example.com/C%CC%A7'" do
574
+ @uri.should == Addressable::URI.parse("http://example.com/C%CC%A7")
575
+ end
576
+
577
+ specify "should not change if encoded with the normalizing algorithm" do
578
+ Addressable::URI.normalized_encode(@uri).to_s.should ==
579
+ "http://example.com/%C3%87"
580
+ end
581
+
582
+ specify "if percent encoded should be 'http://example.com/C%25CC%25A7'" do
583
+ Addressable::URI.encode(@uri).to_s.should ==
584
+ "http://example.com/%25C3%2587"
585
+ end
586
+ end
587
+
588
+ context "http://example.com/?q=string" do
589
+ setup do
590
+ @uri = Addressable::URI.parse("http://example.com/?q=string")
591
+ end
592
+
593
+ specify "should use the 'http' scheme" do
594
+ @uri.scheme.should == "http"
595
+ end
596
+
597
+ specify "should have an authority segment of 'example.com'" do
598
+ @uri.authority.should == "example.com"
599
+ end
600
+
601
+ specify "should have a host of 'example.com'" do
602
+ @uri.host.should == "example.com"
603
+ end
604
+
605
+ specify "should have no username" do
606
+ @uri.user.should == nil
607
+ end
608
+
609
+ specify "should have no password" do
610
+ @uri.password.should == nil
611
+ end
612
+
613
+ specify "should use port 80" do
614
+ @uri.port.should == 80
615
+ end
616
+
617
+ specify "should have a path of '/'" do
618
+ @uri.path.should == "/"
619
+ end
620
+
621
+ specify "should have a query string of 'q=string'" do
622
+ @uri.query.should == "q=string"
623
+ end
624
+
625
+ specify "should have no fragment" do
626
+ @uri.fragment.should == nil
627
+ end
628
+
629
+ specify "should be considered absolute" do
630
+ @uri.should.be.absolute
631
+ end
632
+
633
+ specify "should not be considered relative" do
634
+ @uri.should.not.be.relative
635
+ end
636
+
637
+ specify "should be considered to be in normal form" do
638
+ @uri.normalize.should.be.eql @uri
639
+ end
640
+ end
641
+
642
+ context "http://example.com:80/" do
643
+ setup do
644
+ @uri = Addressable::URI.parse("http://example.com:80/")
645
+ end
646
+
647
+ specify "should use the 'http' scheme" do
648
+ @uri.scheme.should == "http"
649
+ end
650
+
651
+ specify "should have an authority segment of 'example.com:80'" do
652
+ @uri.authority.should == "example.com:80"
653
+ end
654
+
655
+ specify "should have a host of 'example.com'" do
656
+ @uri.host.should == "example.com"
657
+ end
658
+
659
+ specify "should have no username" do
660
+ @uri.user.should == nil
661
+ end
662
+
663
+ specify "should have no password" do
664
+ @uri.password.should == nil
665
+ end
666
+
667
+ specify "should use port 80" do
668
+ @uri.port.should == 80
669
+ end
670
+
671
+ specify "should have a path of '/'" do
672
+ @uri.path.should == "/"
673
+ end
674
+
675
+ specify "should have no query string" do
676
+ @uri.query.should == nil
677
+ end
678
+
679
+ specify "should have no fragment" do
680
+ @uri.fragment.should == nil
681
+ end
682
+
683
+ specify "should be considered absolute" do
684
+ @uri.should.be.absolute
685
+ end
686
+
687
+ specify "should not be considered relative" do
688
+ @uri.should.not.be.relative
689
+ end
690
+
691
+ specify "should be exactly equal to http://example.com:80/" do
692
+ @uri.eql?(Addressable::URI.parse("http://example.com:80/")).should == true
693
+ end
694
+
695
+ specify "should be roughly equal to http://example.com/" do
696
+ (@uri === Addressable::URI.parse("http://example.com/")).should == true
697
+ end
698
+
699
+ specify "should be roughly equal to the string 'http://example.com/'" do
700
+ (@uri === "http://example.com/").should == true
701
+ end
702
+
703
+ specify "should not be roughly equal to the string " +
704
+ "'http://example.com:bogus/'" do
705
+ (lambda do
706
+ (@uri === "http://example.com:bogus/").should == false
707
+ end).should.not.raise
708
+ end
709
+
710
+ specify "should result in itself when merged with itself" do
711
+ @uri.merge(@uri).to_s.should == "http://example.com:80/"
712
+ @uri.merge!(@uri).to_s.should == "http://example.com:80/"
713
+ end
714
+
715
+ # Section 6.2.3 of RFC 3986
716
+ specify "should be equal to http://example.com/" do
717
+ @uri.should == Addressable::URI.parse("http://example.com/")
718
+ end
719
+
720
+ # Section 6.2.3 of RFC 3986
721
+ specify "should be equal to http://example.com:/" do
722
+ @uri.should == Addressable::URI.parse("http://example.com:/")
723
+ end
724
+
725
+ # Section 6.2.3 of RFC 3986
726
+ specify "should be equal to http://example.com:80/" do
727
+ @uri.should == Addressable::URI.parse("http://example.com:80/")
728
+ end
729
+
730
+ # Section 6.2.2.1 of RFC 3986
731
+ specify "should be equal to http://EXAMPLE.COM/" do
732
+ @uri.should == Addressable::URI.parse("http://EXAMPLE.COM/")
733
+ end
734
+ end
735
+
736
+ context "relative/path/to/resource" do
737
+ setup do
738
+ @uri = Addressable::URI.parse("relative/path/to/resource")
739
+ end
740
+
741
+ specify "should not have a scheme" do
742
+ @uri.scheme.should == nil
743
+ end
744
+
745
+ specify "should not be considered ip-based" do
746
+ @uri.should.not.be.ip_based
747
+ end
748
+
749
+ specify "should not have an authority segment" do
750
+ @uri.authority.should == nil
751
+ end
752
+
753
+ specify "should not have a host" do
754
+ @uri.host.should == nil
755
+ end
756
+
757
+ specify "should have no username" do
758
+ @uri.user.should == nil
759
+ end
760
+
761
+ specify "should have no password" do
762
+ @uri.password.should == nil
763
+ end
764
+
765
+ specify "should not have a port" do
766
+ @uri.port.should == nil
767
+ end
768
+
769
+ specify "should have a path of 'relative/path/to/resource'" do
770
+ @uri.path.should == "relative/path/to/resource"
771
+ end
772
+
773
+ specify "should have no query string" do
774
+ @uri.query.should == nil
775
+ end
776
+
777
+ specify "should have no fragment" do
778
+ @uri.fragment.should == nil
779
+ end
780
+
781
+ specify "should not be considered absolute" do
782
+ @uri.should.not.be.absolute
783
+ end
784
+
785
+ specify "should be considered relative" do
786
+ @uri.should.be.relative
787
+ end
788
+
789
+ specify "should raise an error if routing is attempted" do
790
+ (lambda do
791
+ @uri.route_to("http://example.com/")
792
+ end).should.raise
793
+ (lambda do
794
+ @uri.route_from("http://example.com/")
795
+ end).should.raise
796
+ end
797
+ end
798
+
799
+ context "http://example.com/file.txt" do
800
+ setup do
801
+ @uri = Addressable::URI.parse("http://example.com/file.txt")
802
+ end
803
+
804
+ specify "should have a scheme of 'http'" do
805
+ @uri.scheme.should == "http"
806
+ end
807
+
808
+ specify "should have an authority segment of 'example.com'" do
809
+ @uri.authority.should == "example.com"
810
+ end
811
+
812
+ specify "should have a host of 'example.com'" do
813
+ @uri.host.should == "example.com"
814
+ end
815
+
816
+ specify "should have no username" do
817
+ @uri.user.should == nil
818
+ end
819
+
820
+ specify "should have no password" do
821
+ @uri.password.should == nil
822
+ end
823
+
824
+ specify "should use port 80" do
825
+ @uri.port.should == 80
826
+ end
827
+
828
+ specify "should have a path of '/file.txt'" do
829
+ @uri.path.should == "/file.txt"
830
+ end
831
+
832
+ specify "should have an extname of '.txt'" do
833
+ @uri.extname.should == ".txt"
834
+ end
835
+
836
+ specify "should have no query string" do
837
+ @uri.query.should == nil
838
+ end
839
+
840
+ specify "should have no fragment" do
841
+ @uri.fragment.should == nil
842
+ end
843
+ end
844
+
845
+ context "http://example.com/file.txt;x=y" do
846
+ setup do
847
+ @uri = Addressable::URI.parse("http://example.com/file.txt;x=y")
848
+ end
849
+
850
+ specify "should have a scheme of 'http'" do
851
+ @uri.scheme.should == "http"
852
+ end
853
+
854
+ specify "should have a scheme of 'http'" do
855
+ @uri.scheme.should == "http"
856
+ end
857
+
858
+ specify "should have an authority segment of 'example.com'" do
859
+ @uri.authority.should == "example.com"
860
+ end
861
+
862
+ specify "should have a host of 'example.com'" do
863
+ @uri.host.should == "example.com"
864
+ end
865
+
866
+ specify "should have no username" do
867
+ @uri.user.should == nil
868
+ end
869
+
870
+ specify "should have no password" do
871
+ @uri.password.should == nil
872
+ end
873
+
874
+ specify "should use port 80" do
875
+ @uri.port.should == 80
876
+ end
877
+
878
+ specify "should have a path of '/file.txt;x=y'" do
879
+ @uri.path.should == "/file.txt;x=y"
880
+ end
881
+
882
+ specify "should have an extname of '.txt'" do
883
+ @uri.extname.should == ".txt"
884
+ end
885
+
886
+ specify "should have no query string" do
887
+ @uri.query.should == nil
888
+ end
889
+
890
+ specify "should have no fragment" do
891
+ @uri.fragment.should == nil
892
+ end
893
+
894
+ specify "should be considered to be in normal form" do
895
+ @uri.normalize.should.be.eql @uri
896
+ end
897
+ end
898
+
899
+ context "mailto:user@example.com" do
900
+ setup do
901
+ @uri = Addressable::URI.parse("mailto:user@example.com")
902
+ end
903
+
904
+ specify "should have a scheme of 'mailto'" do
905
+ @uri.scheme.should == "mailto"
906
+ end
907
+
908
+ specify "should not be considered to be ip-based" do
909
+ @uri.should.not.be.ip_based
910
+ end
911
+
912
+ specify "should have a path of 'user@example.com'" do
913
+ @uri.path.should == "user@example.com"
914
+ end
915
+
916
+ specify "should have no user" do
917
+ @uri.user.should == nil
918
+ end
919
+
920
+ specify "should be considered to be in normal form" do
921
+ @uri.normalize.should.be.eql @uri
922
+ end
923
+ end
924
+
925
+ context "tag:example.com,2006-08-18:/path/to/something" do
926
+ setup do
927
+ @uri = Addressable::URI.parse(
928
+ "tag:example.com,2006-08-18:/path/to/something")
929
+ end
930
+
931
+ specify "should have a scheme of 'tag'" do
932
+ @uri.scheme.should == "tag"
933
+ end
934
+
935
+ specify "should be considered to be ip-based" do
936
+ @uri.should.not.be.ip_based
937
+ end
938
+
939
+ specify "should have a path of " +
940
+ "'example.com,2006-08-18:/path/to/something'" do
941
+ @uri.path.should == "example.com,2006-08-18:/path/to/something"
942
+ end
943
+
944
+ specify "should have no user" do
945
+ @uri.user.should == nil
946
+ end
947
+
948
+ specify "should be considered to be in normal form" do
949
+ @uri.normalize.should.be.eql @uri
950
+ end
951
+ end
952
+
953
+ context "http://example.com/x;y/" do
954
+ setup do
955
+ @uri = Addressable::URI.parse("http://example.com/x;y/")
956
+ end
957
+
958
+ specify "should be considered to be in normal form" do
959
+ @uri.normalize.should.be.eql @uri
960
+ end
961
+ end
962
+
963
+ context "http://example.com/?x=1&y=2" do
964
+ setup do
965
+ @uri = Addressable::URI.parse("http://example.com/?x=1&y=2")
966
+ end
967
+
968
+ specify "should be considered to be in normal form" do
969
+ @uri.normalize.should.be.eql @uri
970
+ end
971
+ end
972
+
973
+ context "view-source:http://example.com/" do
974
+ setup do
975
+ @uri = Addressable::URI.parse("view-source:http://example.com/")
976
+ end
977
+
978
+ specify "should have a scheme of 'view-source'" do
979
+ @uri.scheme.should == "view-source"
980
+ end
981
+
982
+ specify "should have a path of 'http://example.com/'" do
983
+ @uri.path.should == "http://example.com/"
984
+ end
985
+
986
+ specify "should be considered to be in normal form" do
987
+ @uri.normalize.should.be.eql @uri
988
+ end
989
+ end
990
+
991
+ context "http://user:pass@example.com/path/to/resource?query=x#fragment" do
992
+ setup do
993
+ @uri = Addressable::URI.parse(
994
+ "http://user:pass@example.com/path/to/resource?query=x#fragment")
995
+ end
996
+
997
+ specify "should use the 'http' scheme" do
998
+ @uri.scheme.should == "http"
999
+ end
1000
+
1001
+ specify "should have an authority segment of 'user:pass@example.com'" do
1002
+ @uri.authority.should == "user:pass@example.com"
1003
+ end
1004
+
1005
+ specify "should have a username of 'user'" do
1006
+ @uri.user.should == "user"
1007
+ end
1008
+
1009
+ specify "should have a password of 'pass'" do
1010
+ @uri.password.should == "pass"
1011
+ end
1012
+
1013
+ specify "should have a host of 'example.com'" do
1014
+ @uri.host.should == "example.com"
1015
+ end
1016
+
1017
+ specify "should use port 80" do
1018
+ @uri.port.should == 80
1019
+ end
1020
+
1021
+ specify "should have a path of '/path/to/resource'" do
1022
+ @uri.path.should == "/path/to/resource"
1023
+ end
1024
+
1025
+ specify "should have a query string of 'query=x'" do
1026
+ @uri.query.should == "query=x"
1027
+ end
1028
+
1029
+ specify "should have a fragment of 'fragment'" do
1030
+ @uri.fragment.should == "fragment"
1031
+ end
1032
+
1033
+ specify "should be considered to be in normal form" do
1034
+ @uri.normalize.should.be.eql @uri
1035
+ end
1036
+
1037
+ specify "should have a route of '/path/' to " +
1038
+ "'http://user:pass@example.com/path/'" do
1039
+ @uri.route_to("http://user:pass@example.com/path/").should ==
1040
+ Addressable::URI.parse("/path/")
1041
+ end
1042
+
1043
+ specify "should have a route of '/path/to/resource?query=x#fragment' " +
1044
+ "from 'http://user:pass@example.com/path/'" do
1045
+ @uri.route_from("http://user:pass@example.com/path/").should ==
1046
+ Addressable::URI.parse("/path/to/resource?query=x#fragment")
1047
+ end
1048
+
1049
+ specify "should have a route of '?query=x#fragment' " +
1050
+ "from 'http://user:pass@example.com/path/to/resource'" do
1051
+ @uri.route_from("http://user:pass@example.com/path/to/resource").should ==
1052
+ Addressable::URI.parse("?query=x#fragment")
1053
+ end
1054
+
1055
+ specify "should have a route of '#fragment' " +
1056
+ "from 'http://user:pass@example.com/path/to/resource?query=x'" do
1057
+ @uri.route_from(
1058
+ "http://user:pass@example.com/path/to/resource?query=x").should ==
1059
+ Addressable::URI.parse("#fragment")
1060
+ end
1061
+
1062
+ specify "should have a route of '#fragment' from " +
1063
+ "'http://user:pass@example.com/path/to/resource?query=x#fragment'" do
1064
+ @uri.route_from(
1065
+ "http://user:pass@example.com/path/to/resource?query=x#fragment"
1066
+ ).should == Addressable::URI.parse("#fragment")
1067
+ end
1068
+
1069
+ specify "should have a route of 'http://elsewhere.com/' to " +
1070
+ "'http://elsewhere.com/'" do
1071
+ @uri.route_to("http://elsewhere.com/").should ==
1072
+ Addressable::URI.parse("http://elsewhere.com/")
1073
+ end
1074
+
1075
+ specify "should have the correct scheme after assignment" do
1076
+ @uri.scheme = "ftp"
1077
+ @uri.scheme.should == "ftp"
1078
+ @uri.to_s.should ==
1079
+ "ftp://user:pass@example.com/path/to/resource?query=x#fragment"
1080
+ end
1081
+
1082
+ specify "should have the correct authority segment after assignment" do
1083
+ @uri.authority = "newuser:newpass@example.com:80"
1084
+ @uri.authority.should == "newuser:newpass@example.com:80"
1085
+ @uri.user.should == "newuser"
1086
+ @uri.password.should == "newpass"
1087
+ @uri.host.should == "example.com"
1088
+ @uri.port.should == 80
1089
+ @uri.specified_port.should == 80
1090
+ @uri.to_s.should ==
1091
+ "http://newuser:newpass@example.com:80" +
1092
+ "/path/to/resource?query=x#fragment"
1093
+ end
1094
+
1095
+ specify "should have the correct userinfo segment after assignment" do
1096
+ @uri.userinfo = "newuser:newpass"
1097
+ @uri.userinfo.should == "newuser:newpass"
1098
+ @uri.authority.should == "newuser:newpass@example.com"
1099
+ @uri.user.should == "newuser"
1100
+ @uri.password.should == "newpass"
1101
+ @uri.host.should == "example.com"
1102
+ @uri.port.should == 80
1103
+ @uri.specified_port.should == nil
1104
+ @uri.to_s.should ==
1105
+ "http://newuser:newpass@example.com" +
1106
+ "/path/to/resource?query=x#fragment"
1107
+ end
1108
+
1109
+ specify "should have the correct username after assignment" do
1110
+ @uri.user = "newuser"
1111
+ @uri.user.should == "newuser"
1112
+ @uri.authority.should == "newuser:pass@example.com"
1113
+ end
1114
+
1115
+ specify "should have the correct password after assignment" do
1116
+ @uri.password = "newpass"
1117
+ @uri.password.should == "newpass"
1118
+ @uri.authority.should == "user:newpass@example.com"
1119
+ end
1120
+
1121
+ specify "should have the correct host after assignment" do
1122
+ @uri.host = "newexample.com"
1123
+ @uri.host.should == "newexample.com"
1124
+ @uri.authority.should == "user:pass@newexample.com"
1125
+ end
1126
+
1127
+ specify "should have the correct port after assignment" do
1128
+ @uri.port = 8080
1129
+ @uri.port.should == 8080
1130
+ @uri.authority.should == "user:pass@example.com:8080"
1131
+ end
1132
+
1133
+ specify "should have the correct path after assignment" do
1134
+ @uri.path = "/newpath/to/resource"
1135
+ @uri.path.should == "/newpath/to/resource"
1136
+ @uri.to_s.should ==
1137
+ "http://user:pass@example.com/newpath/to/resource?query=x#fragment"
1138
+ end
1139
+
1140
+ specify "should have the correct query string after assignment" do
1141
+ @uri.query = "newquery=x"
1142
+ @uri.query.should == "newquery=x"
1143
+ @uri.to_s.should ==
1144
+ "http://user:pass@example.com/path/to/resource?newquery=x#fragment"
1145
+ end
1146
+
1147
+ specify "should have the correct fragment after assignment" do
1148
+ @uri.fragment = "newfragment"
1149
+ @uri.fragment.should == "newfragment"
1150
+ @uri.to_s.should ==
1151
+ "http://user:pass@example.com/path/to/resource?query=x#newfragment"
1152
+ end
1153
+ end
1154
+
1155
+ context "http://user@example.com" do
1156
+ setup do
1157
+ @uri = Addressable::URI.parse("http://user@example.com")
1158
+ end
1159
+
1160
+ specify "should use the 'http' scheme" do
1161
+ @uri.scheme.should == "http"
1162
+ end
1163
+
1164
+ specify "should have a username of 'user'" do
1165
+ @uri.user.should == "user"
1166
+ end
1167
+
1168
+ specify "should have no password" do
1169
+ @uri.password.should == nil
1170
+ end
1171
+
1172
+ specify "should have a host of 'example.com'" do
1173
+ @uri.host.should == "example.com"
1174
+ end
1175
+
1176
+ specify "should use port 80" do
1177
+ @uri.port.should == 80
1178
+ end
1179
+
1180
+ specify "should have the correct username after assignment" do
1181
+ @uri.user = "newuser"
1182
+ @uri.user.should == "newuser"
1183
+ @uri.password.should == nil
1184
+ @uri.to_s.should == "http://newuser@example.com"
1185
+ end
1186
+
1187
+ specify "should have the correct password after assignment" do
1188
+ @uri.password = "newpass"
1189
+ @uri.password.should == "newpass"
1190
+ @uri.to_s.should == "http://user:newpass@example.com"
1191
+ end
1192
+
1193
+ specify "should have the correct userinfo segment after assignment" do
1194
+ @uri.userinfo = "newuser:newpass"
1195
+ @uri.userinfo.should == "newuser:newpass"
1196
+ @uri.user.should == "newuser"
1197
+ @uri.password.should == "newpass"
1198
+ @uri.host.should == "example.com"
1199
+ @uri.port.should == 80
1200
+ @uri.specified_port.should == nil
1201
+ @uri.to_s.should == "http://newuser:newpass@example.com"
1202
+ end
1203
+
1204
+ specify "should have the correct userinfo segment after nil assignment" do
1205
+ @uri.userinfo = nil
1206
+ @uri.userinfo.should == nil
1207
+ @uri.user.should == nil
1208
+ @uri.password.should == nil
1209
+ @uri.host.should == "example.com"
1210
+ @uri.port.should == 80
1211
+ @uri.specified_port.should == nil
1212
+ @uri.to_s.should == "http://example.com"
1213
+ end
1214
+
1215
+ specify "should have the correct authority segment after assignment" do
1216
+ @uri.authority = "newuser@example.com"
1217
+ @uri.authority.should == "newuser@example.com"
1218
+ @uri.user.should == "newuser"
1219
+ @uri.password.should == nil
1220
+ @uri.host.should == "example.com"
1221
+ @uri.port.should == 80
1222
+ @uri.specified_port.should == nil
1223
+ @uri.to_s.should == "http://newuser@example.com"
1224
+ end
1225
+
1226
+ specify "should raise an error after nil assignment of authority segment" do
1227
+ (lambda do
1228
+ # This would create an invalid URI
1229
+ @uri.authority = nil
1230
+ end).should.raise
1231
+ end
1232
+ end
1233
+
1234
+ context "http://user:@example.com" do
1235
+ setup do
1236
+ @uri = Addressable::URI.parse("http://user:@example.com")
1237
+ end
1238
+
1239
+ specify "should use the 'http' scheme" do
1240
+ @uri.scheme.should == "http"
1241
+ end
1242
+
1243
+ specify "should have a username of 'user'" do
1244
+ @uri.user.should == "user"
1245
+ end
1246
+
1247
+ specify "should have a password of ''" do
1248
+ @uri.password.should == ""
1249
+ end
1250
+
1251
+ specify "should have a host of 'example.com'" do
1252
+ @uri.host.should == "example.com"
1253
+ end
1254
+
1255
+ specify "should use port 80" do
1256
+ @uri.port.should == 80
1257
+ end
1258
+
1259
+ specify "should have the correct username after assignment" do
1260
+ @uri.user = "newuser"
1261
+ @uri.user.should == "newuser"
1262
+ @uri.password.should == ""
1263
+ @uri.to_s.should == "http://newuser:@example.com"
1264
+ end
1265
+
1266
+ specify "should have the correct password after assignment" do
1267
+ @uri.password = "newpass"
1268
+ @uri.password.should == "newpass"
1269
+ @uri.to_s.should == "http://user:newpass@example.com"
1270
+ end
1271
+
1272
+ specify "should have the correct authority segment after assignment" do
1273
+ @uri.authority = "newuser:@example.com"
1274
+ @uri.authority.should == "newuser:@example.com"
1275
+ @uri.user.should == "newuser"
1276
+ @uri.password.should == ""
1277
+ @uri.host.should == "example.com"
1278
+ @uri.port.should == 80
1279
+ @uri.specified_port.should == nil
1280
+ @uri.to_s.should == "http://newuser:@example.com"
1281
+ end
1282
+ end
1283
+
1284
+ context "http://:pass@example.com" do
1285
+ setup do
1286
+ @uri = Addressable::URI.parse("http://:pass@example.com")
1287
+ end
1288
+
1289
+ specify "should use the 'http' scheme" do
1290
+ @uri.scheme.should == "http"
1291
+ end
1292
+
1293
+ specify "should have a username of ''" do
1294
+ @uri.user.should == ""
1295
+ end
1296
+
1297
+ specify "should have a password of 'pass'" do
1298
+ @uri.password.should == "pass"
1299
+ end
1300
+
1301
+ specify "should have a userinfo of ':pass'" do
1302
+ @uri.userinfo.should == ":pass"
1303
+ end
1304
+
1305
+ specify "should have a host of 'example.com'" do
1306
+ @uri.host.should == "example.com"
1307
+ end
1308
+
1309
+ specify "should use port 80" do
1310
+ @uri.port.should == 80
1311
+ end
1312
+
1313
+ specify "should have the correct username after assignment" do
1314
+ @uri.user = "newuser"
1315
+ @uri.user.should == "newuser"
1316
+ @uri.password.should == "pass"
1317
+ @uri.to_s.should == "http://newuser:pass@example.com"
1318
+ end
1319
+
1320
+ specify "should have the correct password after assignment" do
1321
+ @uri.password = "newpass"
1322
+ @uri.password.should == "newpass"
1323
+ @uri.user.should == ""
1324
+ @uri.to_s.should == "http://:newpass@example.com"
1325
+ end
1326
+
1327
+ specify "should have the correct authority segment after assignment" do
1328
+ @uri.authority = ":newpass@example.com"
1329
+ @uri.authority.should == ":newpass@example.com"
1330
+ @uri.user.should == ""
1331
+ @uri.password.should == "newpass"
1332
+ @uri.host.should == "example.com"
1333
+ @uri.port.should == 80
1334
+ @uri.specified_port.should == nil
1335
+ @uri.to_s.should == "http://:newpass@example.com"
1336
+ end
1337
+ end
1338
+
1339
+ context "http://:@example.com" do
1340
+ setup do
1341
+ @uri = Addressable::URI.parse("http://:@example.com")
1342
+ end
1343
+
1344
+ specify "should use the 'http' scheme" do
1345
+ @uri.scheme.should == "http"
1346
+ end
1347
+
1348
+ specify "should have a username of ''" do
1349
+ @uri.user.should == ""
1350
+ end
1351
+
1352
+ specify "should have a password of ''" do
1353
+ @uri.password.should == ""
1354
+ end
1355
+
1356
+ specify "should have a host of 'example.com'" do
1357
+ @uri.host.should == "example.com"
1358
+ end
1359
+
1360
+ specify "should use port 80" do
1361
+ @uri.port.should == 80
1362
+ end
1363
+
1364
+ specify "should have the correct username after assignment" do
1365
+ @uri.user = "newuser"
1366
+ @uri.user.should == "newuser"
1367
+ @uri.password.should == ""
1368
+ @uri.to_s.should == "http://newuser:@example.com"
1369
+ end
1370
+
1371
+ specify "should have the correct password after assignment" do
1372
+ @uri.password = "newpass"
1373
+ @uri.password.should == "newpass"
1374
+ @uri.user.should == ""
1375
+ @uri.to_s.should == "http://:newpass@example.com"
1376
+ end
1377
+
1378
+ specify "should have the correct authority segment after assignment" do
1379
+ @uri.authority = ":@newexample.com"
1380
+ @uri.authority.should == ":@newexample.com"
1381
+ @uri.user.should == ""
1382
+ @uri.password.should == ""
1383
+ @uri.host.should == "newexample.com"
1384
+ @uri.port.should == 80
1385
+ @uri.specified_port.should == nil
1386
+ @uri.to_s.should == "http://:@newexample.com"
1387
+ end
1388
+ end
1389
+
1390
+ context "#example" do
1391
+ setup do
1392
+ @uri = Addressable::URI.parse("#example")
1393
+ end
1394
+
1395
+ specify "should be considered relative" do
1396
+ @uri.should.be.relative
1397
+ end
1398
+
1399
+ specify "should have a host of nil" do
1400
+ @uri.host.should == nil
1401
+ end
1402
+
1403
+ specify "should have a path of ''" do
1404
+ @uri.path.should == ""
1405
+ end
1406
+
1407
+ specify "should have a query string of nil" do
1408
+ @uri.query.should == nil
1409
+ end
1410
+
1411
+ specify "should have a fragment of 'example'" do
1412
+ @uri.fragment.should == "example"
1413
+ end
1414
+ end
1415
+
1416
+ context "The network-path reference //example.com/" do
1417
+ setup do
1418
+ @uri = Addressable::URI.parse("//example.com/")
1419
+ end
1420
+
1421
+ specify "should be considered relative" do
1422
+ @uri.should.be.relative
1423
+ end
1424
+
1425
+ specify "should have a host of 'example.com'" do
1426
+ @uri.host.should == "example.com"
1427
+ end
1428
+
1429
+ specify "should have a path of '/'" do
1430
+ @uri.path.should == "/"
1431
+ end
1432
+ end
1433
+
1434
+ context "feed://http://example.com/" do
1435
+ setup do
1436
+ @uri = Addressable::URI.parse("feed://http://example.com/")
1437
+ end
1438
+
1439
+ specify "should have a path of 'http://example.com/'" do
1440
+ @uri.path.should == "http://example.com/"
1441
+ end
1442
+
1443
+ specify "should normalize to 'http://example.com/'" do
1444
+ @uri.normalize.to_s.should == "http://example.com/"
1445
+ @uri.normalize!.to_s.should == "http://example.com/"
1446
+ end
1447
+ end
1448
+
1449
+ context "feed:http://example.com/" do
1450
+ setup do
1451
+ @uri = Addressable::URI.parse("feed:http://example.com/")
1452
+ end
1453
+
1454
+ specify "should have a path of 'http://example.com/'" do
1455
+ @uri.path.should == "http://example.com/"
1456
+ end
1457
+
1458
+ specify "should normalize to 'http://example.com/'" do
1459
+ @uri.normalize.to_s.should == "http://example.com/"
1460
+ @uri.normalize!.to_s.should == "http://example.com/"
1461
+ end
1462
+ end
1463
+
1464
+ context "example://a/b/c/%7Bfoo%7D" do
1465
+ setup do
1466
+ @uri = Addressable::URI.parse("example://a/b/c/%7Bfoo%7D")
1467
+ end
1468
+
1469
+ # Section 6.2.2 of RFC 3986
1470
+ specify "should be equivalent to eXAMPLE://a/./b/../b/%63/%7bfoo%7d" do
1471
+ @uri.should ==
1472
+ Addressable::URI.parse("eXAMPLE://a/./b/../b/%63/%7bfoo%7d")
1473
+ end
1474
+ end
1475
+
1476
+ context "http://example.com/indirect/path/./to/../resource/" do
1477
+ setup do
1478
+ @uri = Addressable::URI.parse(
1479
+ "http://example.com/indirect/path/./to/../resource/")
1480
+ end
1481
+
1482
+ specify "should use the 'http' scheme" do
1483
+ @uri.scheme.should == "http"
1484
+ end
1485
+
1486
+ specify "should have a host of 'example.com'" do
1487
+ @uri.host.should == "example.com"
1488
+ end
1489
+
1490
+ specify "should use port 80" do
1491
+ @uri.port.should == 80
1492
+ end
1493
+
1494
+ specify "should have a path of '/indirect/path/./to/../resource/'" do
1495
+ @uri.path.should == "/indirect/path/./to/../resource/"
1496
+ end
1497
+
1498
+ # Section 6.2.2.3 of RFC 3986
1499
+ specify "should have a normalized path of '/indirect/path/resource/'" do
1500
+ @uri.normalize.path.should == "/indirect/path/resource/"
1501
+ @uri.normalize!.path.should == "/indirect/path/resource/"
1502
+ end
1503
+ end
1504
+
1505
+ context "A base uri of http://a/b/c/d;p?q" do
1506
+ setup do
1507
+ @uri = Addressable::URI.parse("http://a/b/c/d;p?q")
1508
+ end
1509
+
1510
+ # Section 5.4.1 of RFC 3986
1511
+ specify "when joined with 'g:h' should resolve to g:h" do
1512
+ (@uri + "g:h").to_s.should == "g:h"
1513
+ Addressable::URI.join(@uri, "g:h").to_s.should == "g:h"
1514
+ end
1515
+
1516
+ # Section 5.4.1 of RFC 3986
1517
+ specify "when joined with 'g' should resolve to http://a/b/c/g" do
1518
+ (@uri + "g").to_s.should == "http://a/b/c/g"
1519
+ Addressable::URI.join(@uri.to_s, "g").to_s.should == "http://a/b/c/g"
1520
+ end
1521
+
1522
+ # Section 5.4.1 of RFC 3986
1523
+ specify "when joined with './g' should resolve to http://a/b/c/g" do
1524
+ (@uri + "./g").to_s.should == "http://a/b/c/g"
1525
+ Addressable::URI.join(@uri.to_s, "./g").to_s.should == "http://a/b/c/g"
1526
+ end
1527
+
1528
+ # Section 5.4.1 of RFC 3986
1529
+ specify "when joined with 'g/' should resolve to http://a/b/c/g/" do
1530
+ (@uri + "g/").to_s.should == "http://a/b/c/g/"
1531
+ Addressable::URI.join(@uri.to_s, "g/").to_s.should == "http://a/b/c/g/"
1532
+ end
1533
+
1534
+ # Section 5.4.1 of RFC 3986
1535
+ specify "when joined with '/g' should resolve to http://a/g" do
1536
+ (@uri + "/g").to_s.should == "http://a/g"
1537
+ Addressable::URI.join(@uri.to_s, "/g").to_s.should == "http://a/g"
1538
+ end
1539
+
1540
+ # Section 5.4.1 of RFC 3986
1541
+ specify "when joined with '//g' should resolve to http://g" do
1542
+ (@uri + "//g").to_s.should == "http://g"
1543
+ Addressable::URI.join(@uri.to_s, "//g").to_s.should == "http://g"
1544
+ end
1545
+
1546
+ # Section 5.4.1 of RFC 3986
1547
+ specify "when joined with '?y' should resolve to http://a/b/c/d;p?y" do
1548
+ (@uri + "?y").to_s.should == "http://a/b/c/d;p?y"
1549
+ Addressable::URI.join(@uri.to_s, "?y").to_s.should == "http://a/b/c/d;p?y"
1550
+ end
1551
+
1552
+ # Section 5.4.1 of RFC 3986
1553
+ specify "when joined with 'g?y' should resolve to http://a/b/c/g?y" do
1554
+ (@uri + "g?y").to_s.should == "http://a/b/c/g?y"
1555
+ Addressable::URI.join(@uri.to_s, "g?y").to_s.should == "http://a/b/c/g?y"
1556
+ end
1557
+
1558
+ # Section 5.4.1 of RFC 3986
1559
+ specify "when joined with '#s' should resolve to http://a/b/c/d;p?q#s" do
1560
+ (@uri + "#s").to_s.should == "http://a/b/c/d;p?q#s"
1561
+ Addressable::URI.join(@uri.to_s, "#s").to_s.should == "http://a/b/c/d;p?q#s"
1562
+ end
1563
+
1564
+ # Section 5.4.1 of RFC 3986
1565
+ specify "when joined with 'g#s' should resolve to http://a/b/c/g#s" do
1566
+ (@uri + "g#s").to_s.should == "http://a/b/c/g#s"
1567
+ Addressable::URI.join(@uri.to_s, "g#s").to_s.should == "http://a/b/c/g#s"
1568
+ end
1569
+
1570
+ # Section 5.4.1 of RFC 3986
1571
+ specify "when joined with 'g?y#s' should resolve to http://a/b/c/g?y#s" do
1572
+ (@uri + "g?y#s").to_s.should == "http://a/b/c/g?y#s"
1573
+ Addressable::URI.join(
1574
+ @uri.to_s, "g?y#s").to_s.should == "http://a/b/c/g?y#s"
1575
+ end
1576
+
1577
+ # Section 5.4.1 of RFC 3986
1578
+ specify "when joined with ';x' should resolve to http://a/b/c/;x" do
1579
+ (@uri + ";x").to_s.should == "http://a/b/c/;x"
1580
+ Addressable::URI.join(@uri.to_s, ";x").to_s.should == "http://a/b/c/;x"
1581
+ end
1582
+
1583
+ # Section 5.4.1 of RFC 3986
1584
+ specify "when joined with 'g;x' should resolve to http://a/b/c/g;x" do
1585
+ (@uri + "g;x").to_s.should == "http://a/b/c/g;x"
1586
+ Addressable::URI.join(@uri.to_s, "g;x").to_s.should == "http://a/b/c/g;x"
1587
+ end
1588
+
1589
+ # Section 5.4.1 of RFC 3986
1590
+ specify "when joined with 'g;x?y#s' should resolve to http://a/b/c/g;x?y#s" do
1591
+ (@uri + "g;x?y#s").to_s.should == "http://a/b/c/g;x?y#s"
1592
+ Addressable::URI.join(
1593
+ @uri.to_s, "g;x?y#s").to_s.should == "http://a/b/c/g;x?y#s"
1594
+ end
1595
+
1596
+ # Section 5.4.1 of RFC 3986
1597
+ specify "when joined with '' should resolve to http://a/b/c/d;p?q" do
1598
+ (@uri + "").to_s.should == "http://a/b/c/d;p?q"
1599
+ Addressable::URI.join(@uri.to_s, "").to_s.should == "http://a/b/c/d;p?q"
1600
+ end
1601
+
1602
+ # Section 5.4.1 of RFC 3986
1603
+ specify "when joined with '.' should resolve to http://a/b/c/" do
1604
+ (@uri + ".").to_s.should == "http://a/b/c/"
1605
+ Addressable::URI.join(@uri.to_s, ".").to_s.should == "http://a/b/c/"
1606
+ end
1607
+
1608
+ # Section 5.4.1 of RFC 3986
1609
+ specify "when joined with './' should resolve to http://a/b/c/" do
1610
+ (@uri + "./").to_s.should == "http://a/b/c/"
1611
+ Addressable::URI.join(@uri.to_s, "./").to_s.should == "http://a/b/c/"
1612
+ end
1613
+
1614
+ # Section 5.4.1 of RFC 3986
1615
+ specify "when joined with '..' should resolve to http://a/b/" do
1616
+ (@uri + "..").to_s.should == "http://a/b/"
1617
+ Addressable::URI.join(@uri.to_s, "..").to_s.should == "http://a/b/"
1618
+ end
1619
+
1620
+ # Section 5.4.1 of RFC 3986
1621
+ specify "when joined with '../' should resolve to http://a/b/" do
1622
+ (@uri + "../").to_s.should == "http://a/b/"
1623
+ Addressable::URI.join(@uri.to_s, "../").to_s.should == "http://a/b/"
1624
+ end
1625
+
1626
+ # Section 5.4.1 of RFC 3986
1627
+ specify "when joined with '../g' should resolve to http://a/b/g" do
1628
+ (@uri + "../g").to_s.should == "http://a/b/g"
1629
+ Addressable::URI.join(@uri.to_s, "../g").to_s.should == "http://a/b/g"
1630
+ end
1631
+
1632
+ # Section 5.4.1 of RFC 3986
1633
+ specify "when joined with '../..' should resolve to http://a/" do
1634
+ (@uri + "../..").to_s.should == "http://a/"
1635
+ Addressable::URI.join(@uri.to_s, "../..").to_s.should == "http://a/"
1636
+ end
1637
+
1638
+ # Section 5.4.1 of RFC 3986
1639
+ specify "when joined with '../../' should resolve to http://a/" do
1640
+ (@uri + "../../").to_s.should == "http://a/"
1641
+ Addressable::URI.join(@uri.to_s, "../../").to_s.should == "http://a/"
1642
+ end
1643
+
1644
+ # Section 5.4.1 of RFC 3986
1645
+ specify "when joined with '../../g' should resolve to http://a/g" do
1646
+ (@uri + "../../g").to_s.should == "http://a/g"
1647
+ Addressable::URI.join(@uri.to_s, "../../g").to_s.should == "http://a/g"
1648
+ end
1649
+
1650
+ # Section 5.4.2 of RFC 3986
1651
+ specify "when joined with '../../../g' should resolve to http://a/g" do
1652
+ (@uri + "../../../g").to_s.should == "http://a/g"
1653
+ Addressable::URI.join(@uri.to_s, "../../../g").to_s.should == "http://a/g"
1654
+ end
1655
+
1656
+ specify "when joined with '../.././../g' should resolve to http://a/g" do
1657
+ (@uri + "../.././../g").to_s.should == "http://a/g"
1658
+ Addressable::URI.join(@uri.to_s, "../.././../g").to_s.should == "http://a/g"
1659
+ end
1660
+
1661
+ # Section 5.4.2 of RFC 3986
1662
+ specify "when joined with '../../../../g' should resolve to http://a/g" do
1663
+ (@uri + "../../../../g").to_s.should == "http://a/g"
1664
+ Addressable::URI.join(
1665
+ @uri.to_s, "../../../../g").to_s.should == "http://a/g"
1666
+ end
1667
+
1668
+ # Section 5.4.2 of RFC 3986
1669
+ specify "when joined with '/./g' should resolve to http://a/g" do
1670
+ (@uri + "/./g").to_s.should == "http://a/g"
1671
+ Addressable::URI.join(@uri.to_s, "/./g").to_s.should == "http://a/g"
1672
+ end
1673
+
1674
+ # Section 5.4.2 of RFC 3986
1675
+ specify "when joined with '/../g' should resolve to http://a/g" do
1676
+ (@uri + "/../g").to_s.should == "http://a/g"
1677
+ Addressable::URI.join(@uri.to_s, "/../g").to_s.should == "http://a/g"
1678
+ end
1679
+
1680
+ # Section 5.4.2 of RFC 3986
1681
+ specify "when joined with 'g.' should resolve to http://a/b/c/g." do
1682
+ (@uri + "g.").to_s.should == "http://a/b/c/g."
1683
+ Addressable::URI.join(@uri.to_s, "g.").to_s.should == "http://a/b/c/g."
1684
+ end
1685
+
1686
+ # Section 5.4.2 of RFC 3986
1687
+ specify "when joined with '.g' should resolve to http://a/b/c/.g" do
1688
+ (@uri + ".g").to_s.should == "http://a/b/c/.g"
1689
+ Addressable::URI.join(@uri.to_s, ".g").to_s.should == "http://a/b/c/.g"
1690
+ end
1691
+
1692
+ # Section 5.4.2 of RFC 3986
1693
+ specify "when joined with 'g..' should resolve to http://a/b/c/g.." do
1694
+ (@uri + "g..").to_s.should == "http://a/b/c/g.."
1695
+ Addressable::URI.join(@uri.to_s, "g..").to_s.should == "http://a/b/c/g.."
1696
+ end
1697
+
1698
+ # Section 5.4.2 of RFC 3986
1699
+ specify "when joined with '..g' should resolve to http://a/b/c/..g" do
1700
+ (@uri + "..g").to_s.should == "http://a/b/c/..g"
1701
+ Addressable::URI.join(@uri.to_s, "..g").to_s.should == "http://a/b/c/..g"
1702
+ end
1703
+
1704
+ # Section 5.4.2 of RFC 3986
1705
+ specify "when joined with './../g' should resolve to http://a/b/g" do
1706
+ (@uri + "./../g").to_s.should == "http://a/b/g"
1707
+ Addressable::URI.join(@uri.to_s, "./../g").to_s.should == "http://a/b/g"
1708
+ end
1709
+
1710
+ # Section 5.4.2 of RFC 3986
1711
+ specify "when joined with './g/.' should resolve to http://a/b/c/g/" do
1712
+ (@uri + "./g/.").to_s.should == "http://a/b/c/g/"
1713
+ Addressable::URI.join(@uri.to_s, "./g/.").to_s.should == "http://a/b/c/g/"
1714
+ end
1715
+
1716
+ # Section 5.4.2 of RFC 3986
1717
+ specify "when joined with 'g/./h' should resolve to http://a/b/c/g/h" do
1718
+ (@uri + "g/./h").to_s.should == "http://a/b/c/g/h"
1719
+ Addressable::URI.join(@uri.to_s, "g/./h").to_s.should == "http://a/b/c/g/h"
1720
+ end
1721
+
1722
+ # Section 5.4.2 of RFC 3986
1723
+ specify "when joined with 'g/../h' should resolve to http://a/b/c/h" do
1724
+ (@uri + "g/../h").to_s.should == "http://a/b/c/h"
1725
+ Addressable::URI.join(@uri.to_s, "g/../h").to_s.should == "http://a/b/c/h"
1726
+ end
1727
+
1728
+ # Section 5.4.2 of RFC 3986
1729
+ specify "when joined with 'g;x=1/./y' " +
1730
+ "should resolve to http://a/b/c/g;x=1/y" do
1731
+ (@uri + "g;x=1/./y").to_s.should == "http://a/b/c/g;x=1/y"
1732
+ Addressable::URI.join(
1733
+ @uri.to_s, "g;x=1/./y").to_s.should == "http://a/b/c/g;x=1/y"
1734
+ end
1735
+
1736
+ # Section 5.4.2 of RFC 3986
1737
+ specify "when joined with 'g;x=1/../y' should resolve to http://a/b/c/y" do
1738
+ (@uri + "g;x=1/../y").to_s.should == "http://a/b/c/y"
1739
+ Addressable::URI.join(
1740
+ @uri.to_s, "g;x=1/../y").to_s.should == "http://a/b/c/y"
1741
+ end
1742
+
1743
+ # Section 5.4.2 of RFC 3986
1744
+ specify "when joined with 'g?y/./x' " +
1745
+ "should resolve to http://a/b/c/g?y/./x" do
1746
+ (@uri + "g?y/./x").to_s.should == "http://a/b/c/g?y/./x"
1747
+ Addressable::URI.join(
1748
+ @uri.to_s, "g?y/./x").to_s.should == "http://a/b/c/g?y/./x"
1749
+ end
1750
+
1751
+ # Section 5.4.2 of RFC 3986
1752
+ specify "when joined with 'g?y/../x' " +
1753
+ "should resolve to http://a/b/c/g?y/../x" do
1754
+ (@uri + "g?y/../x").to_s.should == "http://a/b/c/g?y/../x"
1755
+ Addressable::URI.join(
1756
+ @uri.to_s, "g?y/../x").to_s.should == "http://a/b/c/g?y/../x"
1757
+ end
1758
+
1759
+ # Section 5.4.2 of RFC 3986
1760
+ specify "when joined with 'g#s/./x' " +
1761
+ "should resolve to http://a/b/c/g#s/./x" do
1762
+ (@uri + "g#s/./x").to_s.should == "http://a/b/c/g#s/./x"
1763
+ Addressable::URI.join(
1764
+ @uri.to_s, "g#s/./x").to_s.should == "http://a/b/c/g#s/./x"
1765
+ end
1766
+
1767
+ # Section 5.4.2 of RFC 3986
1768
+ specify "when joined with 'g#s/../x' " +
1769
+ "should resolve to http://a/b/c/g#s/../x" do
1770
+ (@uri + "g#s/../x").to_s.should == "http://a/b/c/g#s/../x"
1771
+ Addressable::URI.join(
1772
+ @uri.to_s, "g#s/../x").to_s.should == "http://a/b/c/g#s/../x"
1773
+ end
1774
+
1775
+ # Section 5.4.2 of RFC 3986
1776
+ specify "when joined with 'http:g' should resolve to http:g" do
1777
+ (@uri + "http:g").to_s.should == "http:g"
1778
+ Addressable::URI.join(@uri.to_s, "http:g").to_s.should == "http:g"
1779
+ end
1780
+
1781
+ # Edge case to be sure
1782
+ specify "when joined with '//example.com/' should " +
1783
+ "resolve to http://example.com/" do
1784
+ (@uri + "//example.com/").to_s.should == "http://example.com/"
1785
+ Addressable::URI.join(
1786
+ @uri.to_s, "//example.com/").to_s.should == "http://example.com/"
1787
+ end
1788
+ end
1789
+
1790
+ context "http://www.詹姆斯.com/" do
1791
+ setup do
1792
+ @uri = Addressable::URI.parse("http://www.詹姆斯.com/")
1793
+ end
1794
+
1795
+ specify "should be equivalent to 'http://www.xn--8ws00zhy3a.com/'" do
1796
+ if Addressable::URI::IDNA.send(:use_libidn?)
1797
+ @uri.should ==
1798
+ Addressable::URI.parse("http://www.xn--8ws00zhy3a.com/")
1799
+ else
1800
+ puts "\nSkipping IDN specification because GNU libidn is unavailable."
1801
+ end
1802
+ end
1803
+
1804
+ specify "should not have domain name encoded during normalization" do
1805
+ Addressable::URI.normalized_encode(@uri.to_s).should ==
1806
+ "http://www.詹姆斯.com/"
1807
+ end
1808
+ end
1809
+
1810
+ context "http://www.詹姆斯.com/ some spaces /" do
1811
+ setup do
1812
+ @uri = Addressable::URI.parse("http://www.詹姆斯.com/ some spaces /")
1813
+ end
1814
+
1815
+ specify "should be equivalent to " +
1816
+ "'http://www.xn--8ws00zhy3a.com/%20some%20spaces%20/'" do
1817
+ if Addressable::URI::IDNA.send(:use_libidn?)
1818
+ @uri.should ==
1819
+ Addressable::URI.parse(
1820
+ "http://www.xn--8ws00zhy3a.com/%20some%20spaces%20/")
1821
+ else
1822
+ puts "\nSkipping IDN specification because GNU libidn is unavailable."
1823
+ end
1824
+ end
1825
+
1826
+ specify "should not have domain name encoded during normalization" do
1827
+ Addressable::URI.normalized_encode(@uri.to_s).should ==
1828
+ "http://www.詹姆斯.com/%20some%20spaces%20/"
1829
+ end
1830
+ end
1831
+
1832
+ context "http://www.xn--8ws00zhy3a.com/" do
1833
+ setup do
1834
+ @uri = Addressable::URI.parse("http://www.xn--8ws00zhy3a.com/")
1835
+ end
1836
+
1837
+ specify "should be displayed as http://www.詹姆斯.com/" do
1838
+ if Addressable::URI::IDNA.send(:use_libidn?)
1839
+ @uri.display_uri.to_s.should == "http://www.詹姆斯.com/"
1840
+ else
1841
+ puts "\nSkipping IDN specification because GNU libidn is unavailable."
1842
+ end
1843
+ end
1844
+ end
1845
+
1846
+ context "http://www.詹姆斯.com/atomtests/iri/詹.html" do
1847
+ setup do
1848
+ @uri = Addressable::URI.parse("http://www.詹姆斯.com/atomtests/iri/詹.html")
1849
+ end
1850
+
1851
+ specify "should normalize to " +
1852
+ "http://www.xn--8ws00zhy3a.com/atomtests/iri/%E8%A9%B9.html" do
1853
+ if Addressable::URI::IDNA.send(:use_libidn?)
1854
+ @uri.normalize.to_s.should ==
1855
+ "http://www.xn--8ws00zhy3a.com/atomtests/iri/%E8%A9%B9.html"
1856
+ @uri.normalize!.to_s.should ==
1857
+ "http://www.xn--8ws00zhy3a.com/atomtests/iri/%E8%A9%B9.html"
1858
+ else
1859
+ puts "\nSkipping IDN specification because GNU libidn is unavailable."
1860
+ end
1861
+ end
1862
+ end
1863
+
1864
+ context "Unavailable libidn bindings" do
1865
+ setup do
1866
+ Addressable::URI::IDNA.instance_variable_set("@use_libidn", false)
1867
+ end
1868
+
1869
+ teardown do
1870
+ Addressable::URI::IDNA.instance_variable_set("@use_libidn", nil)
1871
+ Addressable::URI::IDNA.send(:use_libidn?)
1872
+ end
1873
+
1874
+ specify "should cause the URI::IDNA module to raise an exception when " +
1875
+ "an operation is attempted" do
1876
+ (lambda do
1877
+ Addressable::URI::IDNA.to_ascii("www.詹姆斯.com")
1878
+ end).should.raise
1879
+ (lambda do
1880
+ Addressable::URI::IDNA.to_unicode("www.xn--8ws00zhy3a.com")
1881
+ end).should.raise
1882
+ end
1883
+
1884
+ specify "should not cause normalization routines to error out" do
1885
+ (lambda do
1886
+ uri = Addressable::URI.parse(
1887
+ "http://www.詹姆斯.com/atomtests/iri/詹.html")
1888
+ uri.normalize
1889
+ end).should.not.raise
1890
+ end
1891
+
1892
+ specify "should not cause display uri routines to error out" do
1893
+ (lambda do
1894
+ uri = Addressable::URI.parse(
1895
+ "http://www.xn--8ws00zhy3a.com/atomtests/iri/%E8%A9%B9.html")
1896
+ uri.display_uri
1897
+ end).should.not.raise
1898
+ end
1899
+ end
1900
+
1901
+ context "The URI::IDNA module with rubygems and idn missing" do
1902
+ setup do
1903
+ module Kernel
1904
+ alias_method :saved_require, :require
1905
+ def require(path)
1906
+ raise LoadError,
1907
+ "Libraries cannot be loaded during this test."
1908
+ end
1909
+ end
1910
+ Addressable::URI::IDNA.instance_variable_set("@use_libidn", nil)
1911
+ end
1912
+
1913
+ teardown do
1914
+ module Kernel
1915
+ def require(path)
1916
+ saved_require(path)
1917
+ end
1918
+ alias_method :require, :saved_require
1919
+ end
1920
+ Addressable::URI::IDNA.instance_variable_set("@use_libidn", nil)
1921
+ Addressable::URI::IDNA.send(:use_libidn?)
1922
+ end
1923
+
1924
+ specify "should not raise an exception while checking " +
1925
+ "if libidn is available" do
1926
+ (lambda do
1927
+ Addressable::URI::IDNA.send(:use_libidn?)
1928
+ end).should.not.raise
1929
+ end
1930
+
1931
+ specify "should not cause normalization routines to error out" do
1932
+ (lambda do
1933
+ uri = Addressable::URI.parse(
1934
+ "http://www.詹姆斯.com/atomtests/iri/詹.html")
1935
+ uri.normalize
1936
+ end).should.not.raise
1937
+ end
1938
+
1939
+ specify "should not cause display uri routines to error out" do
1940
+ (lambda do
1941
+ uri = Addressable::URI.parse(
1942
+ "http://www.xn--8ws00zhy3a.com/atomtests/iri/%E8%A9%B9.html")
1943
+ uri.display_uri
1944
+ end).should.not.raise
1945
+ end
1946
+ end
1947
+
1948
+ context "http://under_score.example.com/" do
1949
+ specify "should not cause an error" do
1950
+ (lambda do
1951
+ Addressable::URI.parse("http://under_score.example.com/")
1952
+ end).should.not.raise
1953
+ end
1954
+ end
1955
+
1956
+ context "./this:that" do
1957
+ setup do
1958
+ @uri = Addressable::URI.parse("./this:that")
1959
+ end
1960
+
1961
+ specify "should be considered relative" do
1962
+ @uri.should.be.relative
1963
+ end
1964
+
1965
+ specify "should have no scheme" do
1966
+ @uri.scheme.should == nil
1967
+ end
1968
+ end
1969
+
1970
+ context "this:that" do
1971
+ setup do
1972
+ @uri = Addressable::URI.parse("this:that")
1973
+ end
1974
+
1975
+ specify "should be considered absolute" do
1976
+ @uri.should.be.absolute
1977
+ end
1978
+
1979
+ specify "should have a scheme of 'this'" do
1980
+ @uri.scheme.should == "this"
1981
+ end
1982
+ end
1983
+
1984
+ context "A large body of arbitrary text" do
1985
+ setup do
1986
+ @text = File.open(File.expand_path(
1987
+ File.dirname(__FILE__) + "/../data/rfc3986.txt")) { |file| file.read }
1988
+ end
1989
+
1990
+ specify "should have all obvious URIs extractable from it" do
1991
+ @uris = Addressable::URI.extract(@text)
1992
+ @uris.should.include "http://www.w3.org/People/Berners-Lee/"
1993
+ @uris.should.include "http://roy.gbiv.com/"
1994
+ @uris.should.include "http://larry.masinter.net/"
1995
+ @uris = Addressable::URI.extract(@text,
1996
+ :base => "http://example.com/", :parse => true)
1997
+ @uris.should.include(
1998
+ Addressable::URI.parse("http://www.w3.org/People/Berners-Lee/"))
1999
+ @uris.should.include(
2000
+ Addressable::URI.parse("http://roy.gbiv.com/"))
2001
+ @uris.should.include(
2002
+ Addressable::URI.parse("http://larry.masinter.net/"))
2003
+ end
2004
+ end
2005
+
2006
+ context "Arbitrary text containing invalid URIs" do
2007
+ setup do
2008
+ @text = <<-TEXT
2009
+ This is an invalid URI:
2010
+ http://example.com:bogus/path/to/something/
2011
+ This is a valid URI:
2012
+ http://example.com:80/path/to/something/
2013
+ TEXT
2014
+ end
2015
+
2016
+ specify "should ignore invalid URIs when extracting" do
2017
+ @uris = Addressable::URI.extract(@text)
2018
+ @uris.should.include "http://example.com:80/path/to/something/"
2019
+ @uris.should.not.include "http://example.com:bogus/path/to/something/"
2020
+ @uris.size.should == 1
2021
+ end
2022
+ end
2023
+
2024
+ context "A relative path" do
2025
+ setup do
2026
+ @path = 'relative/path/to/something'
2027
+ end
2028
+
2029
+ specify "should convert to " +
2030
+ "\'relative/path/to/something\'" do
2031
+ @uri = Addressable::URI.convert_path(@path)
2032
+ @uri.to_s.should == "relative/path/to/something"
2033
+ end
2034
+ end
2035
+
2036
+ context "The root directory" do
2037
+ setup do
2038
+ if RUBY_PLATFORM =~ /mswin/
2039
+ @path = "C:\\"
2040
+ else
2041
+ @path = "/"
2042
+ end
2043
+ end
2044
+
2045
+ if RUBY_PLATFORM =~ /mswin/
2046
+ specify "should convert to \'file:///c:/\'" do
2047
+ @uri = Addressable::URI.convert_path(@path)
2048
+ @uri.to_s.should == "file:///c:/"
2049
+ end
2050
+ else
2051
+ specify "should convert to \'file:///\'" do
2052
+ @uri = Addressable::URI.convert_path(@path)
2053
+ @uri.to_s.should == "file:///"
2054
+ end
2055
+ end
2056
+ end
2057
+
2058
+ context "A unix-style path" do
2059
+ setup do
2060
+ @path = '/home/user/'
2061
+ end
2062
+
2063
+ specify "should convert to " +
2064
+ "\'file:///home/user/\'" do
2065
+ @uri = Addressable::URI.convert_path(@path)
2066
+ @uri.to_s.should == "file:///home/user/"
2067
+ end
2068
+ end
2069
+
2070
+ context "A windows-style path" do
2071
+ setup do
2072
+ @path = "c:\\windows\\My Documents 100%20\\foo.txt"
2073
+ end
2074
+
2075
+ specify "should convert to " +
2076
+ "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do
2077
+ @uri = Addressable::URI.convert_path(@path)
2078
+ @uri.to_s.should == "file:///c:/windows/My%20Documents%20100%20/foo.txt"
2079
+ end
2080
+ end
2081
+
2082
+ context "A windows-style file protocol URI with backslashes" do
2083
+ setup do
2084
+ @path = "file://c:\\windows\\My Documents 100%20\\foo.txt"
2085
+ end
2086
+
2087
+ specify "should convert to " +
2088
+ "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do
2089
+ @uri = Addressable::URI.convert_path(@path)
2090
+ @uri.to_s.should == "file:///c:/windows/My%20Documents%20100%20/foo.txt"
2091
+ end
2092
+ end
2093
+
2094
+ context "A windows-style file protocol URI with pipe" do
2095
+ setup do
2096
+ @path = "file:///c|/windows/My%20Documents%20100%20/foo.txt"
2097
+ end
2098
+
2099
+ specify "should convert to " +
2100
+ "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do
2101
+ @uri = Addressable::URI.convert_path(@path)
2102
+ @uri.to_s.should == "file:///c:/windows/My%20Documents%20100%20/foo.txt"
2103
+ end
2104
+ end
2105
+
2106
+ context "A windows-style file protocol URI" do
2107
+ setup do
2108
+ @path = "file:///c:/windows/My%20Documents%20100%20/foo.txt"
2109
+ end
2110
+
2111
+ specify "should convert to " +
2112
+ "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do
2113
+ @uri = Addressable::URI.convert_path(@path)
2114
+ @uri.to_s.should == "file:///c:/windows/My%20Documents%20100%20/foo.txt"
2115
+ end
2116
+ end
2117
+
2118
+ context "An http protocol URI" do
2119
+ setup do
2120
+ @path = "http://example.com/"
2121
+ end
2122
+
2123
+ specify "should not be converted at all" do
2124
+ @uri = Addressable::URI.convert_path(@path)
2125
+ @uri.to_s.should == "http://example.com/"
2126
+ end
2127
+ end
2128
+
2129
+ context "The template pattern 'http://example.com/search/{query}/' " +
2130
+ "when processed with the ExampleProcessor" do
2131
+ setup do
2132
+ @pattern = "http://example.com/search/{query}/"
2133
+ end
2134
+
2135
+ specify "should expand to " +
2136
+ "'http://example.com/search/an+example+search+query/' " +
2137
+ "with a mapping of {\"query\" => \"an example search query\"} " do
2138
+ Addressable::URI.expand_template(
2139
+ "http://example.com/search/{query}/",
2140
+ {"query" => "an example search query"},
2141
+ ExampleProcessor).to_s.should ==
2142
+ "http://example.com/search/an+example+search+query/"
2143
+ end
2144
+
2145
+ specify "should raise an error " +
2146
+ "with a mapping of {\"query\" => \"invalid!\"}" do
2147
+ (lambda do
2148
+ Addressable::URI.expand_template(
2149
+ "http://example.com/search/{query}/",
2150
+ {"query" => "invalid!"},
2151
+ ExampleProcessor).to_s
2152
+ end).should.raise
2153
+ end
2154
+ end
2155
+
2156
+ # Section 3.3.1 of the URI Template draft
2157
+ context "The mapping supplied in Section 3.3.1 of the URI Template draft" do
2158
+ setup do
2159
+ @mapping = {
2160
+ "a" => "fred",
2161
+ "b" => "barney",
2162
+ "c" => "cheeseburger",
2163
+ "d" => "one two three",
2164
+ "e" => "20% tricky",
2165
+ "f" => "",
2166
+ "20" => "this-is-spinal-tap",
2167
+ "scheme" => "https",
2168
+ "p" => "quote=to+be+or+not+to+be",
2169
+ "q" => "hullo#world"
2170
+ }
2171
+ end
2172
+
2173
+ specify "when used to expand 'http://example.org/page1\#{a}' should " +
2174
+ "result in 'http://example.org/page1#fred'" do
2175
+ Addressable::URI.expand_template(
2176
+ "http://example.org/page1\#{a}",
2177
+ @mapping).to_s.should == "http://example.org/page1#fred"
2178
+ end
2179
+
2180
+ specify "when used to expand 'http://example.org/{a}/{b}/' should " +
2181
+ "result in 'http://example.org/fred/barney/'" do
2182
+ Addressable::URI.expand_template(
2183
+ "http://example.org/{a}/{b}/",
2184
+ @mapping).to_s.should == "http://example.org/fred/barney/"
2185
+ end
2186
+
2187
+ specify "when used to expand 'http://example.org/{a}{b}/' should " +
2188
+ "result in 'http://example.org/fredbarney/'" do
2189
+ Addressable::URI.expand_template(
2190
+ "http://example.org/{a}{b}/",
2191
+ @mapping).to_s.should == "http://example.org/fredbarney/"
2192
+ end
2193
+
2194
+ specify "when used to expand 'http://example.com/order/{c}/{c}/{c}/' " +
2195
+ "should result in " +
2196
+ "'http://example.com/order/cheeseburger/cheeseburger/cheeseburger/'" do
2197
+ Addressable::URI.expand_template(
2198
+ "http://example.com/order/{c}/{c}/{c}/",
2199
+ @mapping).to_s.should ==
2200
+ "http://example.com/order/cheeseburger/cheeseburger/cheeseburger/"
2201
+ end
2202
+
2203
+ specify "when used to expand 'http://example.org/{d}' " +
2204
+ "should result in 'http://example.org/one%20two%20three'" do
2205
+ Addressable::URI.expand_template(
2206
+ "http://example.org/{d}",
2207
+ @mapping).to_s.should == "http://example.org/one%20two%20three"
2208
+ end
2209
+
2210
+ specify "when used to expand 'http://example.org/{e}' " +
2211
+ "should result in 'http://example.org/20%25%20tricky'" do
2212
+ Addressable::URI.expand_template(
2213
+ "http://example.org/{e}",
2214
+ @mapping).to_s.should == "http://example.org/20%25%20tricky"
2215
+ end
2216
+
2217
+ specify "when used to expand 'http://example.com/{f}/' " +
2218
+ "should result in 'http://example.com//'" do
2219
+ Addressable::URI.expand_template(
2220
+ "http://example.com/{f}/",
2221
+ @mapping).to_s.should == "http://example.com//"
2222
+ end
2223
+
2224
+ specify "when used to expand " +
2225
+ "'{scheme}://{20}.example.org?date={wilma}&option={a}' " +
2226
+ "should result in " +
2227
+ "'https://this-is-spinal-tap.example.org?date=&option=fred'" do
2228
+ Addressable::URI.expand_template(
2229
+ "{scheme}://{20}.example.org?date={wilma}&option={a}",
2230
+ @mapping).to_s.should ==
2231
+ "https://this-is-spinal-tap.example.org?date=&option=fred"
2232
+ end
2233
+
2234
+ specify "when used to expand 'http://example.org?{p}' " +
2235
+ "should result in 'http://example.org?quote=to+be+or+not+to+be'" do
2236
+ Addressable::URI.expand_template(
2237
+ "http://example.org?{p}",
2238
+ @mapping).to_s.should == "http://example.org?quote=to+be+or+not+to+be"
2239
+ end
2240
+
2241
+ specify "when used to expand 'http://example.com/{q}' " +
2242
+ "should result in 'http://example.com/hullo#world'" do
2243
+ Addressable::URI.expand_template(
2244
+ "http://example.com/{q}",
2245
+ @mapping).to_s.should == "http://example.com/hullo#world"
2246
+ end
2247
+ end
2248
+
2249
+ context "A mapping that contains a template-var within a value" do
2250
+ setup do
2251
+ @mapping = {
2252
+ "a" => "{b}",
2253
+ "b" => "barney",
2254
+ }
2255
+ end
2256
+
2257
+ specify "when used to expand 'http://example.com/{a}/{b}/' " +
2258
+ "should result in 'http://example.com/%7Bb%7D/barney/'" do
2259
+ Addressable::URI.expand_template(
2260
+ "http://example.com/{a}/{b}/",
2261
+ @mapping).to_s.should == "http://example.com/%7Bb%7D/barney/"
2262
+ end
2263
+ end
2264
+
2265
+ context "A mapping that contains values that are already percent-encoded" do
2266
+ setup do
2267
+ @mapping = {
2268
+ "a" => "%7Bb%7D"
2269
+ }
2270
+ end
2271
+
2272
+ specify "when used to expand 'http://example.com/{a}/' " +
2273
+ "should result in 'http://example.com/%257Bb%257D/'" do
2274
+ Addressable::URI.expand_template(
2275
+ "http://example.com/{a}/",
2276
+ @mapping).to_s.should == "http://example.com/%257Bb%257D/"
2277
+ end
2278
+ end