addressable 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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