sr-couchy 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. data/README.textile +77 -0
  2. data/Rakefile +46 -0
  3. data/bin/couchy +80 -0
  4. data/couchy.gemspec +58 -0
  5. data/lib/couchy.rb +21 -0
  6. data/lib/couchy/database.rb +129 -0
  7. data/lib/couchy/server.rb +89 -0
  8. data/spec/couchy_spec.rb +71 -0
  9. data/spec/database_spec.rb +417 -0
  10. data/spec/fixtures/attachments/test.html +11 -0
  11. data/spec/fixtures/views/lib.js +3 -0
  12. data/spec/fixtures/views/test_view/lib.js +3 -0
  13. data/spec/fixtures/views/test_view/only-map.js +4 -0
  14. data/spec/fixtures/views/test_view/test-map.js +3 -0
  15. data/spec/fixtures/views/test_view/test-reduce.js +3 -0
  16. data/spec/spec.opts +6 -0
  17. data/spec/spec_helper.rb +5 -0
  18. data/test/couchy_test.rb +13 -0
  19. data/test/database_test.rb +193 -0
  20. data/test/server_test.rb +211 -0
  21. data/test/test_helper.rb +10 -0
  22. data/vendor/addressable/.gitignore +7 -0
  23. data/vendor/addressable/CHANGELOG +51 -0
  24. data/vendor/addressable/LICENSE +20 -0
  25. data/vendor/addressable/README +24 -0
  26. data/vendor/addressable/Rakefile +51 -0
  27. data/vendor/addressable/lib/addressable/idna.rb +4867 -0
  28. data/vendor/addressable/lib/addressable/uri.rb +2212 -0
  29. data/vendor/addressable/lib/addressable/version.rb +35 -0
  30. data/vendor/addressable/spec/addressable/idna_spec.rb +196 -0
  31. data/vendor/addressable/spec/addressable/uri_spec.rb +3827 -0
  32. data/vendor/addressable/spec/data/rfc3986.txt +3419 -0
  33. data/vendor/addressable/tasks/clobber.rake +2 -0
  34. data/vendor/addressable/tasks/gem.rake +62 -0
  35. data/vendor/addressable/tasks/git.rake +40 -0
  36. data/vendor/addressable/tasks/metrics.rake +22 -0
  37. data/vendor/addressable/tasks/rdoc.rake +29 -0
  38. data/vendor/addressable/tasks/rubyforge.rake +89 -0
  39. data/vendor/addressable/tasks/spec.rake +107 -0
  40. data/vendor/addressable/website/index.html +107 -0
  41. metadata +113 -0
@@ -0,0 +1,35 @@
1
+ #--
2
+ # Addressable, Copyright (c) 2006-2008 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
+ # Used to prevent the class/module from being loaded more than once
25
+ if !defined?(Addressable::VERSION)
26
+ module Addressable
27
+ module VERSION #:nodoc:
28
+ MAJOR = 2
29
+ MINOR = 0
30
+ TINY = 0
31
+
32
+ STRING = [MAJOR, MINOR, TINY].join('.')
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,196 @@
1
+ # coding:utf-8
2
+ #--
3
+ # Addressable, Copyright (c) 2006-2007 Bob Aman
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ #++
24
+
25
+ $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../../lib'))
26
+ $:.uniq!
27
+
28
+ require "addressable/idna"
29
+
30
+ describe Addressable::IDNA, "when converting from unicode to ASCII" do
31
+ it "should convert 'www.google.com' correctly" do
32
+ Addressable::IDNA.to_ascii("www.google.com").should == "www.google.com"
33
+ end
34
+
35
+ it "should convert 'www.詹姆斯.com' correctly" do
36
+ Addressable::IDNA.to_ascii(
37
+ "www.詹姆斯.com"
38
+ ).should == "www.xn--8ws00zhy3a.com"
39
+ end
40
+
41
+ it "should convert 'www.Iñtërnâtiônàlizætiøn.com' correctly" do
42
+ Addressable::IDNA.to_ascii(
43
+ "www.I\303\261t\303\253rn\303\242ti\303\264" +
44
+ "n\303\240liz\303\246ti\303\270n.com"
45
+ ).should == "www.xn--itrntinliztin-vdb0a5exd8ewcye.com"
46
+ end
47
+
48
+ it "should convert 'www.Iñtërnâtiônàlizætiøn.com' correctly" do
49
+ Addressable::IDNA.to_ascii(
50
+ "www.In\314\203te\314\210rna\314\202tio\314\202n" +
51
+ "a\314\200liz\303\246ti\303\270n.com"
52
+ ).should == "www.xn--itrntinliztin-vdb0a5exd8ewcye.com"
53
+ end
54
+
55
+ it "should convert " +
56
+ "'www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp' " +
57
+ "correctly" do
58
+ Addressable::IDNA.to_ascii(
59
+ "www.\343\201\273\343\202\223\343\201\250\343\201\206\343\201\253\343" +
60
+ "\201\252\343\201\214\343\201\204\343\202\217\343\201\221\343\201\256" +
61
+ "\343\202\217\343\201\213\343\202\211\343\201\252\343\201\204\343\201" +
62
+ "\251\343\202\201\343\201\204\343\202\223\343\202\201\343\201\204\343" +
63
+ "\201\256\343\202\211\343\201\271\343\202\213\343\201\276\343\201\240" +
64
+ "\343\201\252\343\201\214\343\201\217\343\201\227\343\201\252\343\201" +
65
+ "\204\343\201\250\343\201\237\343\202\212\343\201\252\343\201\204." +
66
+ "w3.mag.keio.ac.jp"
67
+ ).should ==
68
+ "www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3" +
69
+ "fg11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp"
70
+ end
71
+
72
+ it "should convert " +
73
+ "'www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp' " +
74
+ "correctly" do
75
+ Addressable::IDNA.to_ascii(
76
+ "www.\343\201\273\343\202\223\343\201\250\343\201\206\343\201\253\343" +
77
+ "\201\252\343\201\213\343\202\231\343\201\204\343\202\217\343\201\221" +
78
+ "\343\201\256\343\202\217\343\201\213\343\202\211\343\201\252\343\201" +
79
+ "\204\343\201\250\343\202\231\343\202\201\343\201\204\343\202\223\343" +
80
+ "\202\201\343\201\204\343\201\256\343\202\211\343\201\270\343\202\231" +
81
+ "\343\202\213\343\201\276\343\201\237\343\202\231\343\201\252\343\201" +
82
+ "\213\343\202\231\343\201\217\343\201\227\343\201\252\343\201\204\343" +
83
+ "\201\250\343\201\237\343\202\212\343\201\252\343\201\204." +
84
+ "w3.mag.keio.ac.jp"
85
+ ).should ==
86
+ "www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3" +
87
+ "fg11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp"
88
+ end
89
+
90
+ it "should convert '点心和烤鸭.w3.mag.keio.ac.jp' correctly" do
91
+ Addressable::IDNA.to_ascii(
92
+ "点心和烤鸭.w3.mag.keio.ac.jp"
93
+ ).should == "xn--0trv4xfvn8el34t.w3.mag.keio.ac.jp"
94
+ end
95
+
96
+ it "should convert '가각갂갃간갅갆갇갈갉힢힣.com' correctly" do
97
+ Addressable::IDNA.to_ascii(
98
+ "가각갂갃간갅갆갇갈갉힢힣.com"
99
+ ).should == "xn--o39acdefghijk5883jma.com"
100
+ end
101
+
102
+ it "should convert " +
103
+ "'\347\242\274\346\250\231\346\272\226\350" +
104
+ "\220\254\345\234\213\347\242\274.com' correctly" do
105
+ Addressable::IDNA.to_ascii(
106
+ "\347\242\274\346\250\231\346\272\226\350" +
107
+ "\220\254\345\234\213\347\242\274.com"
108
+ ).should == "xn--9cs565brid46mda086o.com"
109
+ end
110
+
111
+ it "should convert 'リ宠퐱〹.com' correctly" do
112
+ Addressable::IDNA.to_ascii(
113
+ "\357\276\230\345\256\240\355\220\261\343\200\271.com"
114
+ ).should == "xn--eek174hoxfpr4k.com"
115
+ end
116
+
117
+ it "should convert 'リ宠퐱卄.com' correctly" do
118
+ Addressable::IDNA.to_ascii(
119
+ "\343\203\252\345\256\240\355\220\261\345\215\204.com"
120
+ ).should == "xn--eek174hoxfpr4k.com"
121
+ end
122
+
123
+ it "should convert 'ᆵ' correctly" do
124
+ Addressable::IDNA.to_ascii(
125
+ "\341\206\265"
126
+ ).should == "xn--4ud"
127
+ end
128
+
129
+ it "should convert 'ᆵ' correctly" do
130
+ Addressable::IDNA.to_ascii(
131
+ "\357\276\257"
132
+ ).should == "xn--4ud"
133
+ end
134
+ end
135
+
136
+ describe Addressable::IDNA, "when converting from ASCII to unicode" do
137
+ it "should convert 'www.google.com' correctly" do
138
+ Addressable::IDNA.to_unicode("www.google.com").should == "www.google.com"
139
+ end
140
+
141
+ it "should convert 'www.詹姆斯.com' correctly" do
142
+ Addressable::IDNA.to_unicode(
143
+ "www.xn--8ws00zhy3a.com"
144
+ ).should == "www.詹姆斯.com"
145
+ end
146
+
147
+ it "should convert 'www.iñtërnâtiônàlizætiøn.com' correctly" do
148
+ Addressable::IDNA.to_unicode(
149
+ "www.xn--itrntinliztin-vdb0a5exd8ewcye.com"
150
+ ).should == "www.iñtërnâtiônàlizætiøn.com"
151
+ end
152
+
153
+ it "should convert " +
154
+ "'www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp' " +
155
+ "correctly" do
156
+ Addressable::IDNA.to_unicode(
157
+ "www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3" +
158
+ "fg11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp"
159
+ ).should ==
160
+ "www.ほんとうにながいわけのわからないどめいんめいのらべるまだながくしないとたりない.w3.mag.keio.ac.jp"
161
+ end
162
+
163
+ it "should convert '点心和烤鸭.w3.mag.keio.ac.jp' correctly" do
164
+ Addressable::IDNA.to_unicode(
165
+ "xn--0trv4xfvn8el34t.w3.mag.keio.ac.jp"
166
+ ).should == "点心和烤鸭.w3.mag.keio.ac.jp"
167
+ end
168
+
169
+ it "should convert '가각갂갃간갅갆갇갈갉힢힣.com' correctly" do
170
+ Addressable::IDNA.to_unicode(
171
+ "xn--o39acdefghijk5883jma.com"
172
+ ).should == "가각갂갃간갅갆갇갈갉힢힣.com"
173
+ end
174
+
175
+ it "should convert " +
176
+ "'\347\242\274\346\250\231\346\272\226\350" +
177
+ "\220\254\345\234\213\347\242\274.com' correctly" do
178
+ Addressable::IDNA.to_unicode(
179
+ "xn--9cs565brid46mda086o.com"
180
+ ).should ==
181
+ "\347\242\274\346\250\231\346\272\226\350" +
182
+ "\220\254\345\234\213\347\242\274.com"
183
+ end
184
+
185
+ it "should convert 'リ宠퐱卄.com' correctly" do
186
+ Addressable::IDNA.to_unicode(
187
+ "xn--eek174hoxfpr4k.com"
188
+ ).should == "\343\203\252\345\256\240\355\220\261\345\215\204.com"
189
+ end
190
+
191
+ it "should convert 'ᆵ' correctly" do
192
+ Addressable::IDNA.to_unicode(
193
+ "xn--4ud"
194
+ ).should == "\341\206\265"
195
+ end
196
+ end
@@ -0,0 +1,3827 @@
1
+ # coding:utf-8
2
+ #--
3
+ # Addressable, Copyright (c) 2006-2007 Bob Aman
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining
6
+ # a copy of this software and associated documentation files (the
7
+ # "Software"), to deal in the Software without restriction, including
8
+ # without limitation the rights to use, copy, modify, merge, publish,
9
+ # distribute, sublicense, and/or sell copies of the Software, and to
10
+ # permit persons to whom the Software is furnished to do so, subject to
11
+ # the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be
14
+ # included in all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ #++
24
+
25
+ $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../../lib'))
26
+ $:.uniq!
27
+
28
+ require "addressable/uri"
29
+
30
+ if !"".respond_to?("force_encoding")
31
+ class String
32
+ def force_encoding(encoding)
33
+ # Do nothing, just make sure this gets called.
34
+ end
35
+ end
36
+
37
+ class Encoding
38
+ UTF_8 = Encoding.new
39
+ ASCII_8BIT = Encoding.new
40
+ end
41
+ end
42
+
43
+ class ExampleProcessor
44
+ def self.validate(name, value)
45
+ return !!(value =~ /^[\w ]+$/) if name == "query"
46
+ return true
47
+ end
48
+
49
+ def self.transform(name, value)
50
+ return value.gsub(/ /, "+") if name == "query"
51
+ return value
52
+ end
53
+
54
+ def self.restore(name, value)
55
+ return value.gsub(/\+/, " ") if name == "query"
56
+ return value
57
+ end
58
+
59
+ def self.match(name)
60
+ return ".*?" if name == "first"
61
+ return ".*"
62
+ end
63
+ end
64
+
65
+ class SlashlessProcessor
66
+ def self.match(name)
67
+ return "[^/\\n]*"
68
+ end
69
+ end
70
+
71
+ describe Addressable::URI, "when created with a non-numeric port number" do
72
+ it "should raise an error" do
73
+ (lambda do
74
+ Addressable::URI.new(:port => "bogus")
75
+ end).should raise_error(Addressable::URI::InvalidURIError)
76
+ end
77
+ end
78
+
79
+ describe Addressable::URI, "when created with a scheme but no hierarchical " +
80
+ "segment" do
81
+ it "should raise an error" do
82
+ (lambda do
83
+ Addressable::URI.parse("http:")
84
+ end).should raise_error(Addressable::URI::InvalidURIError)
85
+ end
86
+ end
87
+
88
+ describe Addressable::URI, "when created from nil components" do
89
+ before do
90
+ @uri = Addressable::URI.new
91
+ end
92
+
93
+ it "should have an empty path" do
94
+ @uri.path.should == ""
95
+ end
96
+
97
+ it "should be an empty uri" do
98
+ @uri.to_s.should == ""
99
+ end
100
+ end
101
+
102
+ describe Addressable::URI, "when created from string components" do
103
+ before do
104
+ @uri = Addressable::URI.new(
105
+ :scheme => "http", :host => "example.com"
106
+ )
107
+ end
108
+
109
+ it "should be equal to the equivalent parsed URI" do
110
+ @uri.should == Addressable::URI.parse("http://example.com")
111
+ end
112
+
113
+ it "should raise an error if invalid components omitted" do
114
+ (lambda do
115
+ @uri.omit(:bogus)
116
+ end).should raise_error(ArgumentError)
117
+ (lambda do
118
+ @uri.omit(:scheme, :bogus, :path)
119
+ end).should raise_error(ArgumentError)
120
+ end
121
+ end
122
+
123
+ describe Addressable::URI, "when created with a nil host but " +
124
+ "non-nil authority components" do
125
+ it "should raise an error" do
126
+ (lambda do
127
+ Addressable::URI.new(:user => "user", :password => "pass", :port => 80)
128
+ end).should raise_error(Addressable::URI::InvalidURIError)
129
+ end
130
+ end
131
+
132
+ describe Addressable::URI, "when created with both an authority and a user" do
133
+ it "should raise an error" do
134
+ (lambda do
135
+ Addressable::URI.new(:user => "user", :authority => "user@example.com:80")
136
+ end).should raise_error(ArgumentError)
137
+ end
138
+ end
139
+
140
+ describe Addressable::URI, "when created with an authority and no port" do
141
+ before do
142
+ @uri = Addressable::URI.new(:authority => "user@example.com")
143
+ end
144
+
145
+ it "should not infer a port" do
146
+ @uri.port.should == nil
147
+ @uri.inferred_port.should == nil
148
+ end
149
+ end
150
+
151
+ describe Addressable::URI, "when created with both a userinfo and a user" do
152
+ it "should raise an error" do
153
+ (lambda do
154
+ Addressable::URI.new(:user => "user", :userinfo => "user:pass")
155
+ end).should raise_error(ArgumentError)
156
+ end
157
+ end
158
+
159
+ describe Addressable::URI, "when created with a path that hasn't been " +
160
+ "prefixed with a '/' but a host specified" do
161
+ it "should prefix a '/' to the path" do
162
+ Addressable::URI.new(
163
+ :scheme => "http", :host => "example.com", :path => "path"
164
+ ).should == Addressable::URI.parse("http://example.com/path")
165
+ end
166
+ end
167
+
168
+ describe Addressable::URI, "when created with a path that hasn't been " +
169
+ "prefixed with a '/' but no host specified" do
170
+ it "should prefix a '/' to the path" do
171
+ Addressable::URI.new(
172
+ :scheme => "http", :path => "path"
173
+ ).should == Addressable::URI.parse("http:path")
174
+ end
175
+ end
176
+
177
+ # Section 1.1.2 of RFC 3986
178
+ describe Addressable::URI, " when parsed from " +
179
+ "'ftp://ftp.is.co.za/rfc/rfc1808.txt'" do
180
+ before do
181
+ @uri = Addressable::URI.parse("ftp://ftp.is.co.za/rfc/rfc1808.txt")
182
+ end
183
+
184
+ it "should use the 'ftp' scheme" do
185
+ @uri.scheme.should == "ftp"
186
+ end
187
+
188
+ it "should be considered to be ip-based" do
189
+ @uri.should be_ip_based
190
+ end
191
+
192
+ it "should have a host of 'ftp.is.co.za'" do
193
+ @uri.host.should == "ftp.is.co.za"
194
+ end
195
+
196
+ it "should have a path of '/rfc/rfc1808.txt'" do
197
+ @uri.path.should == "/rfc/rfc1808.txt"
198
+ end
199
+
200
+ it "should be considered to be in normal form" do
201
+ @uri.normalize.should be_eql(@uri)
202
+ end
203
+ end
204
+
205
+ # Section 1.1.2 of RFC 3986
206
+ describe Addressable::URI, " when parsed from " +
207
+ "'http://www.ietf.org/rfc/rfc2396.txt'" do
208
+ before do
209
+ @uri = Addressable::URI.parse("http://www.ietf.org/rfc/rfc2396.txt")
210
+ end
211
+
212
+ it "should use the 'http' scheme" do
213
+ @uri.scheme.should == "http"
214
+ end
215
+
216
+ it "should be considered to be ip-based" do
217
+ @uri.should be_ip_based
218
+ end
219
+
220
+ it "should have a host of 'www.ietf.org'" do
221
+ @uri.host.should == "www.ietf.org"
222
+ end
223
+
224
+ it "should have a path of '/rfc/rfc2396.txt'" do
225
+ @uri.path.should == "/rfc/rfc2396.txt"
226
+ end
227
+
228
+ it "should be considered to be in normal form" do
229
+ @uri.normalize.should be_eql(@uri)
230
+ end
231
+
232
+ it "should correctly omit components" do
233
+ @uri.omit(:scheme).to_s.should == "//www.ietf.org/rfc/rfc2396.txt"
234
+ @uri.omit(:path).to_s.should == "http://www.ietf.org"
235
+ end
236
+
237
+ it "should correctly omit components destructively" do
238
+ @uri.omit!(:scheme)
239
+ @uri.to_s.should == "//www.ietf.org/rfc/rfc2396.txt"
240
+ end
241
+ end
242
+
243
+ # Section 1.1.2 of RFC 3986
244
+ describe Addressable::URI, "when parsed from " +
245
+ "'ldap://[2001:db8::7]/c=GB?objectClass?one'" do
246
+ before do
247
+ @uri = Addressable::URI.parse("ldap://[2001:db8::7]/c=GB?objectClass?one")
248
+ end
249
+
250
+ it "should use the 'ldap' scheme" do
251
+ @uri.scheme.should == "ldap"
252
+ end
253
+
254
+ it "should be considered to be ip-based" do
255
+ @uri.should be_ip_based
256
+ end
257
+
258
+ it "should have a host of '[2001:db8::7]'" do
259
+ @uri.host.should == "[2001:db8::7]"
260
+ end
261
+
262
+ it "should have a path of '/c=GB'" do
263
+ @uri.path.should == "/c=GB"
264
+ end
265
+
266
+ it "should have a query of 'objectClass?one'" do
267
+ @uri.query.should == "objectClass?one"
268
+ end
269
+
270
+ it "should be considered to be in normal form" do
271
+ @uri.normalize.should be_eql(@uri)
272
+ end
273
+
274
+ it "should correctly omit components" do
275
+ @uri.omit(:scheme, :authority).to_s.should == "/c=GB?objectClass?one"
276
+ @uri.omit(:path).to_s.should == "ldap://[2001:db8::7]?objectClass?one"
277
+ end
278
+
279
+ it "should correctly omit components destructively" do
280
+ @uri.omit!(:scheme, :authority)
281
+ @uri.to_s.should == "/c=GB?objectClass?one"
282
+ end
283
+ end
284
+
285
+ # Section 1.1.2 of RFC 3986
286
+ describe Addressable::URI, " when parsed from " +
287
+ "'mailto:John.Doe@example.com'" do
288
+ before do
289
+ @uri = Addressable::URI.parse("mailto:John.Doe@example.com")
290
+ end
291
+
292
+ it "should use the 'mailto' scheme" do
293
+ @uri.scheme.should == "mailto"
294
+ end
295
+
296
+ it "should not be considered to be ip-based" do
297
+ @uri.should_not be_ip_based
298
+ end
299
+
300
+ it "should have a path of 'John.Doe@example.com'" do
301
+ @uri.path.should == "John.Doe@example.com"
302
+ end
303
+
304
+ it "should be considered to be in normal form" do
305
+ @uri.normalize.should be_eql(@uri)
306
+ end
307
+ end
308
+
309
+ # Section 1.1.2 of RFC 3986
310
+ describe Addressable::URI, " when parsed from " +
311
+ "'news:comp.infosystems.www.servers.unix'" do
312
+ before do
313
+ @uri = Addressable::URI.parse("news:comp.infosystems.www.servers.unix")
314
+ end
315
+
316
+ it "should use the 'news' scheme" do
317
+ @uri.scheme.should == "news"
318
+ end
319
+
320
+ it "should not be considered to be ip-based" do
321
+ @uri.should_not be_ip_based
322
+ end
323
+
324
+ it "should have a path of 'comp.infosystems.www.servers.unix'" do
325
+ @uri.path.should == "comp.infosystems.www.servers.unix"
326
+ end
327
+
328
+ it "should be considered to be in normal form" do
329
+ @uri.normalize.should be_eql(@uri)
330
+ end
331
+ end
332
+
333
+ # Section 1.1.2 of RFC 3986
334
+ describe Addressable::URI, "when parsed from " +
335
+ "'tel:+1-816-555-1212'" do
336
+ before do
337
+ @uri = Addressable::URI.parse("tel:+1-816-555-1212")
338
+ end
339
+
340
+ it "should use the 'tel' scheme" do
341
+ @uri.scheme.should == "tel"
342
+ end
343
+
344
+ it "should not be considered to be ip-based" do
345
+ @uri.should_not be_ip_based
346
+ end
347
+
348
+ it "should have a path of '+1-816-555-1212'" do
349
+ @uri.path.should == "+1-816-555-1212"
350
+ end
351
+
352
+ it "should be considered to be in normal form" do
353
+ @uri.normalize.should be_eql(@uri)
354
+ end
355
+ end
356
+
357
+ # Section 1.1.2 of RFC 3986
358
+ describe Addressable::URI, " when parsed from " +
359
+ "'telnet://192.0.2.16:80/'" do
360
+ before do
361
+ @uri = Addressable::URI.parse("telnet://192.0.2.16:80/")
362
+ end
363
+
364
+ it "should use the 'telnet' scheme" do
365
+ @uri.scheme.should == "telnet"
366
+ end
367
+
368
+ it "should have a host of '192.0.2.16'" do
369
+ @uri.host.should == "192.0.2.16"
370
+ end
371
+
372
+ it "should have a port of '80'" do
373
+ @uri.port.should == 80
374
+ end
375
+
376
+ it "should be considered to be ip-based" do
377
+ @uri.should be_ip_based
378
+ end
379
+
380
+ it "should have a path of '/'" do
381
+ @uri.path.should == "/"
382
+ end
383
+
384
+ it "should be considered to be in normal form" do
385
+ @uri.normalize.should be_eql(@uri)
386
+ end
387
+ end
388
+
389
+ # Section 1.1.2 of RFC 3986
390
+ describe Addressable::URI, " when parsed from " +
391
+ "'urn:oasis:names:specification:docbook:dtd:xml:4.1.2'" do
392
+ before do
393
+ @uri = Addressable::URI.parse(
394
+ "urn:oasis:names:specification:docbook:dtd:xml:4.1.2")
395
+ end
396
+
397
+ it "should use the 'urn' scheme" do
398
+ @uri.scheme.should == "urn"
399
+ end
400
+
401
+ it "should not be considered to be ip-based" do
402
+ @uri.should_not be_ip_based
403
+ end
404
+
405
+ it "should have a path of " +
406
+ "'oasis:names:specification:docbook:dtd:xml:4.1.2'" do
407
+ @uri.path.should == "oasis:names:specification:docbook:dtd:xml:4.1.2"
408
+ end
409
+
410
+ it "should be considered to be in normal form" do
411
+ @uri.normalize.should be_eql(@uri)
412
+ end
413
+ end
414
+
415
+ describe Addressable::URI, " when parsed from " +
416
+ "'http://example.com'" do
417
+ before do
418
+ @uri = Addressable::URI.parse("http://example.com")
419
+ end
420
+
421
+ it "when inspected, should have the correct URI" do
422
+ @uri.inspect.should include("http://example.com")
423
+ end
424
+
425
+ it "when inspected, should have the correct class name" do
426
+ @uri.inspect.should include("Addressable::URI")
427
+ end
428
+
429
+ it "when inspected, should have the correct object id" do
430
+ @uri.inspect.should include("%#0x" % @uri.object_id)
431
+ end
432
+
433
+ it "should use the 'http' scheme" do
434
+ @uri.scheme.should == "http"
435
+ end
436
+
437
+ it "should be considered to be ip-based" do
438
+ @uri.should be_ip_based
439
+ end
440
+
441
+ it "should have an authority segment of 'example.com'" do
442
+ @uri.authority.should == "example.com"
443
+ end
444
+
445
+ it "should have a host of 'example.com'" do
446
+ @uri.host.should == "example.com"
447
+ end
448
+
449
+ it "should be considered ip-based" do
450
+ @uri.should be_ip_based
451
+ end
452
+
453
+ it "should have no username" do
454
+ @uri.user.should == nil
455
+ end
456
+
457
+ it "should have no password" do
458
+ @uri.password.should == nil
459
+ end
460
+
461
+ it "should use port 80" do
462
+ @uri.inferred_port.should == 80
463
+ end
464
+
465
+ it "should not have a specified port" do
466
+ @uri.port.should == nil
467
+ end
468
+
469
+ it "should have an empty path" do
470
+ @uri.path.should == ""
471
+ end
472
+
473
+ it "should have no query string" do
474
+ @uri.query.should == nil
475
+ @uri.query_values.should == nil
476
+ end
477
+
478
+ it "should have no fragment" do
479
+ @uri.fragment.should == nil
480
+ end
481
+
482
+ it "should be considered absolute" do
483
+ @uri.should be_absolute
484
+ end
485
+
486
+ it "should not be considered relative" do
487
+ @uri.should_not be_relative
488
+ end
489
+
490
+ it "should not be exactly equal to 42" do
491
+ @uri.eql?(42).should == false
492
+ end
493
+
494
+ it "should not be equal to 42" do
495
+ (@uri == 42).should == false
496
+ end
497
+
498
+ it "should not be roughly equal to 42" do
499
+ (@uri === 42).should == false
500
+ end
501
+
502
+ it "should be exactly equal to http://example.com" do
503
+ @uri.eql?(Addressable::URI.parse("http://example.com")).should == true
504
+ end
505
+
506
+ it "should be roughly equal to http://example.com/" do
507
+ (@uri === Addressable::URI.parse("http://example.com/")).should == true
508
+ end
509
+
510
+ it "should be roughly equal to the string 'http://example.com/'" do
511
+ (@uri === "http://example.com/").should == true
512
+ end
513
+
514
+ it "should not be roughly equal to the string " +
515
+ "'http://example.com:bogus/'" do
516
+ (lambda do
517
+ (@uri === "http://example.com:bogus/").should == false
518
+ end).should_not raise_error
519
+ end
520
+
521
+ it "should result in itself when joined with itself" do
522
+ @uri.join(@uri).to_s.should == "http://example.com"
523
+ @uri.join!(@uri).to_s.should == "http://example.com"
524
+ end
525
+
526
+ # Section 6.2.3 of RFC 3986
527
+ it "should be equivalent to http://example.com/" do
528
+ @uri.should == Addressable::URI.parse("http://example.com/")
529
+ end
530
+
531
+ # Section 6.2.3 of RFC 3986
532
+ it "should be equivalent to http://example.com:/" do
533
+ @uri.should == Addressable::URI.parse("http://example.com:/")
534
+ end
535
+
536
+ # Section 6.2.3 of RFC 3986
537
+ it "should be equivalent to http://example.com:80/" do
538
+ @uri.should == Addressable::URI.parse("http://example.com:80/")
539
+ end
540
+
541
+ # Section 6.2.2.1 of RFC 3986
542
+ it "should be equivalent to http://EXAMPLE.COM/" do
543
+ @uri.should == Addressable::URI.parse("http://EXAMPLE.COM/")
544
+ end
545
+
546
+ it "should have a route of '/path/' to 'http://example.com/path/'" do
547
+ @uri.route_to("http://example.com/path/").should ==
548
+ Addressable::URI.parse("/path/")
549
+ end
550
+
551
+ it "should have a route of '/' from 'http://example.com/path/'" do
552
+ @uri.route_from("http://example.com/path/").should ==
553
+ Addressable::URI.parse("/")
554
+ end
555
+
556
+ it "should have a route of '#' to 'http://example.com/'" do
557
+ @uri.route_to("http://example.com/").should ==
558
+ Addressable::URI.parse("#")
559
+ end
560
+
561
+ it "should have a route of 'http://elsewhere.com/' to " +
562
+ "'http://elsewhere.com/'" do
563
+ @uri.route_to("http://elsewhere.com/").should ==
564
+ Addressable::URI.parse("http://elsewhere.com/")
565
+ end
566
+
567
+ it "when joined with 'relative/path' should be " +
568
+ "'http://example.com/relative/path'" do
569
+ @uri.join('relative/path').should ==
570
+ Addressable::URI.parse("http://example.com/relative/path")
571
+ end
572
+
573
+ it "when joined with a bogus object a TypeError should be raised" do
574
+ (lambda do
575
+ @uri.join(42)
576
+ end).should raise_error(TypeError)
577
+ end
578
+
579
+ it "should have the correct username after assignment" do
580
+ @uri.user = "newuser"
581
+ @uri.user.should == "newuser"
582
+ @uri.password.should == nil
583
+ @uri.to_s.should == "http://newuser@example.com"
584
+ end
585
+
586
+ it "should have the correct password after assignment" do
587
+ @uri.password = "newpass"
588
+ @uri.password.should == "newpass"
589
+ @uri.user.should == ""
590
+ @uri.to_s.should == "http://:newpass@example.com"
591
+ end
592
+
593
+ it "should have the correct user/pass after repeated assignment" do
594
+ @uri.user = nil
595
+ @uri.user.should == nil
596
+ @uri.password = "newpass"
597
+ @uri.password.should == "newpass"
598
+ # Username cannot be nil if the password is set
599
+ @uri.user.should == ""
600
+ @uri.to_s.should == "http://:newpass@example.com"
601
+ @uri.user = "newuser"
602
+ @uri.user.should == "newuser"
603
+ @uri.password = nil
604
+ @uri.password.should == nil
605
+ @uri.to_s.should == "http://newuser@example.com"
606
+ @uri.user = "newuser"
607
+ @uri.user.should == "newuser"
608
+ @uri.password = ""
609
+ @uri.password.should == ""
610
+ @uri.to_s.should == "http://newuser:@example.com"
611
+ @uri.password = "newpass"
612
+ @uri.password.should == "newpass"
613
+ @uri.user = nil
614
+ # Username cannot be nil if the password is set
615
+ @uri.user.should == ""
616
+ @uri.to_s.should == "http://:newpass@example.com"
617
+ end
618
+
619
+ it "should have the correct user/pass after userinfo assignment" do
620
+ @uri.user = "newuser"
621
+ @uri.user.should == "newuser"
622
+ @uri.password = "newpass"
623
+ @uri.password.should == "newpass"
624
+ @uri.userinfo = nil
625
+ @uri.userinfo.should == nil
626
+ @uri.user.should == nil
627
+ @uri.password.should == nil
628
+ end
629
+
630
+ it "should correctly convert to a hash" do
631
+ @uri.to_hash.should == {
632
+ :scheme => "http",
633
+ :user => nil,
634
+ :password => nil,
635
+ :host => "example.com",
636
+ :port => nil,
637
+ :path => "",
638
+ :query => nil,
639
+ :fragment => nil
640
+ }
641
+ end
642
+
643
+ it "should be identical to its duplicate" do
644
+ @uri.should == @uri.dup
645
+ end
646
+ end
647
+
648
+ describe Addressable::URI, " when parsed from " +
649
+ "'http://example.com/'" do
650
+ before do
651
+ @uri = Addressable::URI.parse("http://example.com/")
652
+ end
653
+
654
+ # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence
655
+ it "should be equivalent to http://example.com" do
656
+ @uri.should == Addressable::URI.parse("http://example.com")
657
+ end
658
+
659
+ # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence
660
+ it "should be equivalent to HTTP://example.com/" do
661
+ @uri.should == Addressable::URI.parse("HTTP://example.com/")
662
+ end
663
+
664
+ # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence
665
+ it "should be equivalent to http://example.com:/" do
666
+ @uri.should == Addressable::URI.parse("http://example.com:/")
667
+ end
668
+
669
+ # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence
670
+ it "should be equivalent to http://example.com:80/" do
671
+ @uri.should == Addressable::URI.parse("http://example.com:80/")
672
+ end
673
+
674
+ # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence
675
+ it "should be equivalent to http://Example.com/" do
676
+ @uri.should == Addressable::URI.parse("http://Example.com/")
677
+ end
678
+
679
+ it "should have the correct username after assignment" do
680
+ @uri.user = nil
681
+ @uri.user.should == nil
682
+ @uri.password.should == nil
683
+ @uri.to_s.should == "http://example.com/"
684
+ end
685
+
686
+ it "should have the correct password after assignment" do
687
+ @uri.password = nil
688
+ @uri.password.should == nil
689
+ @uri.user.should == nil
690
+ @uri.to_s.should == "http://example.com/"
691
+ end
692
+
693
+ it "should correctly convert to a hash" do
694
+ @uri.to_hash.should == {
695
+ :scheme => "http",
696
+ :user => nil,
697
+ :password => nil,
698
+ :host => "example.com",
699
+ :port => nil,
700
+ :path => "/",
701
+ :query => nil,
702
+ :fragment => nil
703
+ }
704
+ end
705
+
706
+ it "should be identical to its duplicate" do
707
+ @uri.should == @uri.dup
708
+ end
709
+
710
+ it "should have the same hash as its duplicate" do
711
+ @uri.hash.should == @uri.dup.hash
712
+ end
713
+
714
+ it "should have a different hash from its equivalent String value" do
715
+ @uri.hash.should_not == @uri.to_s.hash
716
+ end
717
+
718
+ it "should have the same hash as an equivalent URI" do
719
+ @uri.hash.should == Addressable::URI.parse("http://example.com:80/").hash
720
+ end
721
+ end
722
+
723
+ describe Addressable::URI, " when parsed from " +
724
+ "'http://@example.com/'" do
725
+ before do
726
+ @uri = Addressable::URI.parse("http://@example.com/")
727
+ end
728
+
729
+ it "should be equivalent to http://example.com" do
730
+ @uri.should == Addressable::URI.parse("http://example.com")
731
+ end
732
+
733
+ it "should correctly convert to a hash" do
734
+ @uri.to_hash.should == {
735
+ :scheme => "http",
736
+ :user => "",
737
+ :password => nil,
738
+ :host => "example.com",
739
+ :port => nil,
740
+ :path => "/",
741
+ :query => nil,
742
+ :fragment => nil
743
+ }
744
+ end
745
+
746
+ it "should be identical to its duplicate" do
747
+ @uri.should == @uri.dup
748
+ end
749
+ end
750
+
751
+ describe Addressable::URI, " when parsed from " +
752
+ "'http://example.com./'" do
753
+ before do
754
+ @uri = Addressable::URI.parse("http://example.com./")
755
+ end
756
+
757
+ it "should be equivalent to http://example.com" do
758
+ @uri.should == Addressable::URI.parse("http://example.com")
759
+ end
760
+
761
+ it "should not be considered to be in normal form" do
762
+ @uri.normalize.should_not be_eql(@uri)
763
+ end
764
+
765
+ it "should be identical to its duplicate" do
766
+ @uri.should == @uri.dup
767
+ end
768
+ end
769
+
770
+ describe Addressable::URI, " when parsed from " +
771
+ "'http://:@example.com/'" do
772
+ before do
773
+ @uri = Addressable::URI.parse("http://:@example.com/")
774
+ end
775
+
776
+ it "should be equivalent to http://example.com" do
777
+ @uri.should == Addressable::URI.parse("http://example.com")
778
+ end
779
+
780
+ it "should correctly convert to a hash" do
781
+ @uri.to_hash.should == {
782
+ :scheme => "http",
783
+ :user => "",
784
+ :password => "",
785
+ :host => "example.com",
786
+ :port => nil,
787
+ :path => "/",
788
+ :query => nil,
789
+ :fragment => nil
790
+ }
791
+ end
792
+
793
+ it "should be identical to its duplicate" do
794
+ @uri.should == @uri.dup
795
+ end
796
+ end
797
+
798
+ describe Addressable::URI, " when parsed from " +
799
+ "'http://example.com/~smith/'" do
800
+ before do
801
+ @uri = Addressable::URI.parse("http://example.com/~smith/")
802
+ end
803
+
804
+ # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence
805
+ it "should be equivalent to http://example.com/%7Esmith/" do
806
+ @uri.should == Addressable::URI.parse("http://example.com/%7Esmith/")
807
+ end
808
+
809
+ # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence
810
+ it "should be equivalent to http://example.com/%7esmith/" do
811
+ @uri.should == Addressable::URI.parse("http://example.com/%7esmith/")
812
+ end
813
+
814
+ it "should be identical to its duplicate" do
815
+ @uri.should == @uri.dup
816
+ end
817
+ end
818
+
819
+ describe Addressable::URI, " when parsed from " +
820
+ "'http://example.com/%C3%87'" do
821
+ before do
822
+ @uri = Addressable::URI.parse("http://example.com/%C3%87")
823
+ end
824
+
825
+ # Based on http://intertwingly.net/blog/2004/07/31/URI-Equivalence
826
+ it "should be equivalent to 'http://example.com/C%CC%A7'" do
827
+ @uri.should == Addressable::URI.parse("http://example.com/C%CC%A7")
828
+ end
829
+
830
+ it "should not change if encoded with the normalizing algorithm" do
831
+ Addressable::URI.normalized_encode(@uri).to_s.should ==
832
+ "http://example.com/%C3%87"
833
+ end
834
+
835
+ it "should raise an error if encoding with an unexpected return type" do
836
+ (lambda do
837
+ Addressable::URI.normalized_encode(@uri, Integer)
838
+ end).should raise_error(TypeError)
839
+ end
840
+
841
+ it "if percent encoded should be 'http://example.com/C%25CC%25A7'" do
842
+ Addressable::URI.encode(@uri).to_s.should ==
843
+ "http://example.com/%25C3%2587"
844
+ end
845
+
846
+ it "if percent encoded should be 'http://example.com/C%25CC%25A7'" do
847
+ Addressable::URI.encode(@uri, Addressable::URI).should ==
848
+ Addressable::URI.parse("http://example.com/%25C3%2587")
849
+ end
850
+
851
+ it "should raise an error if encoding with an unexpected return type" do
852
+ (lambda do
853
+ Addressable::URI.encode(@uri, Integer)
854
+ end).should raise_error(TypeError)
855
+ end
856
+
857
+ it "should be identical to its duplicate" do
858
+ @uri.should == @uri.dup
859
+ end
860
+ end
861
+
862
+ describe Addressable::URI, " when parsed from " +
863
+ "'http://example.com/?q=string'" do
864
+ before do
865
+ @uri = Addressable::URI.parse("http://example.com/?q=string")
866
+ end
867
+
868
+ it "should use the 'http' scheme" do
869
+ @uri.scheme.should == "http"
870
+ end
871
+
872
+ it "should have an authority segment of 'example.com'" do
873
+ @uri.authority.should == "example.com"
874
+ end
875
+
876
+ it "should have a host of 'example.com'" do
877
+ @uri.host.should == "example.com"
878
+ end
879
+
880
+ it "should have no username" do
881
+ @uri.user.should == nil
882
+ end
883
+
884
+ it "should have no password" do
885
+ @uri.password.should == nil
886
+ end
887
+
888
+ it "should use port 80" do
889
+ @uri.inferred_port.should == 80
890
+ end
891
+
892
+ it "should have a path of '/'" do
893
+ @uri.path.should == "/"
894
+ end
895
+
896
+ it "should have a query string of 'q=string'" do
897
+ @uri.query.should == "q=string"
898
+ end
899
+
900
+ it "should have no fragment" do
901
+ @uri.fragment.should == nil
902
+ end
903
+
904
+ it "should be considered absolute" do
905
+ @uri.should be_absolute
906
+ end
907
+
908
+ it "should not be considered relative" do
909
+ @uri.should_not be_relative
910
+ end
911
+
912
+ it "should be considered to be in normal form" do
913
+ @uri.normalize.should be_eql(@uri)
914
+ end
915
+
916
+ it "should be identical to its duplicate" do
917
+ @uri.should == @uri.dup
918
+ end
919
+ end
920
+
921
+ describe Addressable::URI, " when parsed from " +
922
+ "'http://example.com:80/'" do
923
+ before do
924
+ @uri = Addressable::URI.parse("http://example.com:80/")
925
+ end
926
+
927
+ it "should use the 'http' scheme" do
928
+ @uri.scheme.should == "http"
929
+ end
930
+
931
+ it "should have an authority segment of 'example.com:80'" do
932
+ @uri.authority.should == "example.com:80"
933
+ end
934
+
935
+ it "should have a host of 'example.com'" do
936
+ @uri.host.should == "example.com"
937
+ end
938
+
939
+ it "should have no username" do
940
+ @uri.user.should == nil
941
+ end
942
+
943
+ it "should have no password" do
944
+ @uri.password.should == nil
945
+ end
946
+
947
+ it "should use port 80" do
948
+ @uri.port.should == 80
949
+ end
950
+
951
+ it "should have a path of '/'" do
952
+ @uri.path.should == "/"
953
+ end
954
+
955
+ it "should have no query string" do
956
+ @uri.query.should == nil
957
+ end
958
+
959
+ it "should have no fragment" do
960
+ @uri.fragment.should == nil
961
+ end
962
+
963
+ it "should be considered absolute" do
964
+ @uri.should be_absolute
965
+ end
966
+
967
+ it "should not be considered relative" do
968
+ @uri.should_not be_relative
969
+ end
970
+
971
+ it "should be exactly equal to http://example.com:80/" do
972
+ @uri.eql?(Addressable::URI.parse("http://example.com:80/")).should == true
973
+ end
974
+
975
+ it "should be roughly equal to http://example.com/" do
976
+ (@uri === Addressable::URI.parse("http://example.com/")).should == true
977
+ end
978
+
979
+ it "should be roughly equal to the string 'http://example.com/'" do
980
+ (@uri === "http://example.com/").should == true
981
+ end
982
+
983
+ it "should not be roughly equal to the string " +
984
+ "'http://example.com:bogus/'" do
985
+ (lambda do
986
+ (@uri === "http://example.com:bogus/").should == false
987
+ end).should_not raise_error
988
+ end
989
+
990
+ it "should result in itself when joined with itself" do
991
+ @uri.join(@uri).to_s.should == "http://example.com:80/"
992
+ @uri.join!(@uri).to_s.should == "http://example.com:80/"
993
+ end
994
+
995
+ # Section 6.2.3 of RFC 3986
996
+ it "should be equal to http://example.com/" do
997
+ @uri.should == Addressable::URI.parse("http://example.com/")
998
+ end
999
+
1000
+ # Section 6.2.3 of RFC 3986
1001
+ it "should be equal to http://example.com:/" do
1002
+ @uri.should == Addressable::URI.parse("http://example.com:/")
1003
+ end
1004
+
1005
+ # Section 6.2.3 of RFC 3986
1006
+ it "should be equal to http://example.com:80/" do
1007
+ @uri.should == Addressable::URI.parse("http://example.com:80/")
1008
+ end
1009
+
1010
+ # Section 6.2.2.1 of RFC 3986
1011
+ it "should be equal to http://EXAMPLE.COM/" do
1012
+ @uri.should == Addressable::URI.parse("http://EXAMPLE.COM/")
1013
+ end
1014
+
1015
+ it "should correctly convert to a hash" do
1016
+ @uri.to_hash.should == {
1017
+ :scheme => "http",
1018
+ :user => nil,
1019
+ :password => nil,
1020
+ :host => "example.com",
1021
+ :port => 80,
1022
+ :path => "/",
1023
+ :query => nil,
1024
+ :fragment => nil
1025
+ }
1026
+ end
1027
+
1028
+ it "should be identical to its duplicate" do
1029
+ @uri.should == @uri.dup
1030
+ end
1031
+ end
1032
+
1033
+ describe Addressable::URI, " when parsed from " +
1034
+ "'http://example.com:8080/'" do
1035
+ before do
1036
+ @uri = Addressable::URI.parse("http://example.com:8080/")
1037
+ end
1038
+
1039
+ it "should use the 'http' scheme" do
1040
+ @uri.scheme.should == "http"
1041
+ end
1042
+
1043
+ it "should have an authority segment of 'example.com:8080'" do
1044
+ @uri.authority.should == "example.com:8080"
1045
+ end
1046
+
1047
+ it "should have a host of 'example.com'" do
1048
+ @uri.host.should == "example.com"
1049
+ end
1050
+
1051
+ it "should have no username" do
1052
+ @uri.user.should == nil
1053
+ end
1054
+
1055
+ it "should have no password" do
1056
+ @uri.password.should == nil
1057
+ end
1058
+
1059
+ it "should use port 8080" do
1060
+ @uri.port.should == 8080
1061
+ end
1062
+
1063
+ it "should have a path of '/'" do
1064
+ @uri.path.should == "/"
1065
+ end
1066
+
1067
+ it "should have no query string" do
1068
+ @uri.query.should == nil
1069
+ end
1070
+
1071
+ it "should have no fragment" do
1072
+ @uri.fragment.should == nil
1073
+ end
1074
+
1075
+ it "should be considered absolute" do
1076
+ @uri.should be_absolute
1077
+ end
1078
+
1079
+ it "should not be considered relative" do
1080
+ @uri.should_not be_relative
1081
+ end
1082
+
1083
+ it "should be exactly equal to http://example.com:8080/" do
1084
+ @uri.eql?(Addressable::URI.parse(
1085
+ "http://example.com:8080/")).should == true
1086
+ end
1087
+
1088
+ it "should have a route of 'http://example.com:8080/' from " +
1089
+ "'http://example.com/path/to/'" do
1090
+ @uri.route_from("http://example.com/path/to/").should ==
1091
+ Addressable::URI.parse("http://example.com:8080/")
1092
+ end
1093
+
1094
+ it "should have a route of 'http://example.com:8080/' from " +
1095
+ "'http://example.com:80/path/to/'" do
1096
+ @uri.route_from("http://example.com:80/path/to/").should ==
1097
+ Addressable::URI.parse("http://example.com:8080/")
1098
+ end
1099
+
1100
+ it "should have a route of '/' from " +
1101
+ "'http://example.com:8080/path/to/'" do
1102
+ @uri.route_from("http://example.com:8080/path/to/").should ==
1103
+ Addressable::URI.parse("/")
1104
+ end
1105
+
1106
+ it "should have a route of 'http://example.com:8080/' from " +
1107
+ "'http://user:pass@example.com/path/to/'" do
1108
+ @uri.route_from("http://user:pass@example.com/path/to/").should ==
1109
+ Addressable::URI.parse("http://example.com:8080/")
1110
+ end
1111
+
1112
+ it "should correctly convert to a hash" do
1113
+ @uri.to_hash.should == {
1114
+ :scheme => "http",
1115
+ :user => nil,
1116
+ :password => nil,
1117
+ :host => "example.com",
1118
+ :port => 8080,
1119
+ :path => "/",
1120
+ :query => nil,
1121
+ :fragment => nil
1122
+ }
1123
+ end
1124
+
1125
+ it "should be identical to its duplicate" do
1126
+ @uri.should == @uri.dup
1127
+ end
1128
+ end
1129
+
1130
+ describe Addressable::URI, " when parsed from " +
1131
+ "'http://example.com/path/to/resource/'" do
1132
+ before do
1133
+ @uri = Addressable::URI.parse("http://example.com/path/to/resource/")
1134
+ end
1135
+
1136
+ it "should use the 'http' scheme" do
1137
+ @uri.scheme.should == "http"
1138
+ end
1139
+
1140
+ it "should have an authority segment of 'example.com'" do
1141
+ @uri.authority.should == "example.com"
1142
+ end
1143
+
1144
+ it "should have a host of 'example.com'" do
1145
+ @uri.host.should == "example.com"
1146
+ end
1147
+
1148
+ it "should have no username" do
1149
+ @uri.user.should == nil
1150
+ end
1151
+
1152
+ it "should have no password" do
1153
+ @uri.password.should == nil
1154
+ end
1155
+
1156
+ it "should use port 80" do
1157
+ @uri.inferred_port.should == 80
1158
+ end
1159
+
1160
+ it "should have a path of '/path/to/resource/'" do
1161
+ @uri.path.should == "/path/to/resource/"
1162
+ end
1163
+
1164
+ it "should have no query string" do
1165
+ @uri.query.should == nil
1166
+ end
1167
+
1168
+ it "should have no fragment" do
1169
+ @uri.fragment.should == nil
1170
+ end
1171
+
1172
+ it "should be considered absolute" do
1173
+ @uri.should be_absolute
1174
+ end
1175
+
1176
+ it "should not be considered relative" do
1177
+ @uri.should_not be_relative
1178
+ end
1179
+
1180
+ it "should be exactly equal to http://example.com:8080/" do
1181
+ @uri.eql?(Addressable::URI.parse(
1182
+ "http://example.com/path/to/resource/")).should == true
1183
+ end
1184
+
1185
+ it "should have a route of 'resource/' from " +
1186
+ "'http://example.com/path/to/'" do
1187
+ @uri.route_from("http://example.com/path/to/").should ==
1188
+ Addressable::URI.parse("resource/")
1189
+ end
1190
+
1191
+ it "should have a route of 'resource/' from " +
1192
+ "'http://example.com:80/path/to/'" do
1193
+ @uri.route_from("http://example.com:80/path/to/").should ==
1194
+ Addressable::URI.parse("resource/")
1195
+ end
1196
+
1197
+ it "should have a route of 'http://example.com/path/to/' from " +
1198
+ "'http://example.com:8080/path/to/'" do
1199
+ @uri.route_from("http://example.com:8080/path/to/").should ==
1200
+ Addressable::URI.parse("http://example.com/path/to/resource/")
1201
+ end
1202
+
1203
+ it "should have a route of 'http://example.com/path/to/' from " +
1204
+ "'http://user:pass@example.com/path/to/'" do
1205
+ @uri.route_from("http://user:pass@example.com/path/to/").should ==
1206
+ Addressable::URI.parse("http://example.com/path/to/resource/")
1207
+ end
1208
+
1209
+ it "should have a route of '/path/to/resource/' from " +
1210
+ "'http://example.com/to/resource/'" do
1211
+ @uri.route_from("http://example.com/to/resource/").should ==
1212
+ Addressable::URI.parse("/path/to/resource/")
1213
+ end
1214
+
1215
+ it "should correctly convert to a hash" do
1216
+ @uri.to_hash.should == {
1217
+ :scheme => "http",
1218
+ :user => nil,
1219
+ :password => nil,
1220
+ :host => "example.com",
1221
+ :port => nil,
1222
+ :path => "/path/to/resource/",
1223
+ :query => nil,
1224
+ :fragment => nil
1225
+ }
1226
+ end
1227
+
1228
+ it "should be identical to its duplicate" do
1229
+ @uri.should == @uri.dup
1230
+ end
1231
+ end
1232
+
1233
+ describe Addressable::URI, "when parsed from " +
1234
+ "'relative/path/to/resource'" do
1235
+ before do
1236
+ @uri = Addressable::URI.parse("relative/path/to/resource")
1237
+ end
1238
+
1239
+ it "should not have a scheme" do
1240
+ @uri.scheme.should == nil
1241
+ end
1242
+
1243
+ it "should not be considered ip-based" do
1244
+ @uri.should_not be_ip_based
1245
+ end
1246
+
1247
+ it "should not have an authority segment" do
1248
+ @uri.authority.should == nil
1249
+ end
1250
+
1251
+ it "should not have a host" do
1252
+ @uri.host.should == nil
1253
+ end
1254
+
1255
+ it "should have no username" do
1256
+ @uri.user.should == nil
1257
+ end
1258
+
1259
+ it "should have no password" do
1260
+ @uri.password.should == nil
1261
+ end
1262
+
1263
+ it "should not have a port" do
1264
+ @uri.port.should == nil
1265
+ end
1266
+
1267
+ it "should have a path of 'relative/path/to/resource'" do
1268
+ @uri.path.should == "relative/path/to/resource"
1269
+ end
1270
+
1271
+ it "should have no query string" do
1272
+ @uri.query.should == nil
1273
+ end
1274
+
1275
+ it "should have no fragment" do
1276
+ @uri.fragment.should == nil
1277
+ end
1278
+
1279
+ it "should not be considered absolute" do
1280
+ @uri.should_not be_absolute
1281
+ end
1282
+
1283
+ it "should be considered relative" do
1284
+ @uri.should be_relative
1285
+ end
1286
+
1287
+ it "should raise an error if routing is attempted" do
1288
+ (lambda do
1289
+ @uri.route_to("http://example.com/")
1290
+ end).should raise_error(ArgumentError, /relative\/path\/to\/resource/)
1291
+ (lambda do
1292
+ @uri.route_from("http://example.com/")
1293
+ end).should raise_error(ArgumentError, /relative\/path\/to\/resource/)
1294
+ end
1295
+
1296
+ it "when joined with 'another/relative/path' should be " +
1297
+ "'relative/path/to/another/relative/path'" do
1298
+ @uri.join('another/relative/path').should ==
1299
+ Addressable::URI.parse("relative/path/to/another/relative/path")
1300
+ end
1301
+
1302
+ it "should be identical to its duplicate" do
1303
+ @uri.should == @uri.dup
1304
+ end
1305
+ end
1306
+
1307
+ describe Addressable::URI, "when parsed from " +
1308
+ "'relative_path_with_no_slashes'" do
1309
+ before do
1310
+ @uri = Addressable::URI.parse("relative_path_with_no_slashes")
1311
+ end
1312
+
1313
+ it "should not have a scheme" do
1314
+ @uri.scheme.should == nil
1315
+ end
1316
+
1317
+ it "should not be considered ip-based" do
1318
+ @uri.should_not be_ip_based
1319
+ end
1320
+
1321
+ it "should not have an authority segment" do
1322
+ @uri.authority.should == nil
1323
+ end
1324
+
1325
+ it "should not have a host" do
1326
+ @uri.host.should == nil
1327
+ end
1328
+
1329
+ it "should have no username" do
1330
+ @uri.user.should == nil
1331
+ end
1332
+
1333
+ it "should have no password" do
1334
+ @uri.password.should == nil
1335
+ end
1336
+
1337
+ it "should not have a port" do
1338
+ @uri.port.should == nil
1339
+ end
1340
+
1341
+ it "should have a path of 'relative_path_with_no_slashes'" do
1342
+ @uri.path.should == "relative_path_with_no_slashes"
1343
+ end
1344
+
1345
+ it "should have no query string" do
1346
+ @uri.query.should == nil
1347
+ end
1348
+
1349
+ it "should have no fragment" do
1350
+ @uri.fragment.should == nil
1351
+ end
1352
+
1353
+ it "should not be considered absolute" do
1354
+ @uri.should_not be_absolute
1355
+ end
1356
+
1357
+ it "should be considered relative" do
1358
+ @uri.should be_relative
1359
+ end
1360
+
1361
+ it "when joined with 'another_relative_path' should be " +
1362
+ "'another_relative_path'" do
1363
+ @uri.join('another_relative_path').should ==
1364
+ Addressable::URI.parse("another_relative_path")
1365
+ end
1366
+ end
1367
+
1368
+ describe Addressable::URI, " when parsed from " +
1369
+ "'http://example.com/file.txt'" do
1370
+ before do
1371
+ @uri = Addressable::URI.parse("http://example.com/file.txt")
1372
+ end
1373
+
1374
+ it "should have a scheme of 'http'" do
1375
+ @uri.scheme.should == "http"
1376
+ end
1377
+
1378
+ it "should have an authority segment of 'example.com'" do
1379
+ @uri.authority.should == "example.com"
1380
+ end
1381
+
1382
+ it "should have a host of 'example.com'" do
1383
+ @uri.host.should == "example.com"
1384
+ end
1385
+
1386
+ it "should have no username" do
1387
+ @uri.user.should == nil
1388
+ end
1389
+
1390
+ it "should have no password" do
1391
+ @uri.password.should == nil
1392
+ end
1393
+
1394
+ it "should use port 80" do
1395
+ @uri.inferred_port.should == 80
1396
+ end
1397
+
1398
+ it "should have a path of '/file.txt'" do
1399
+ @uri.path.should == "/file.txt"
1400
+ end
1401
+
1402
+ it "should have a basename of 'file.txt'" do
1403
+ @uri.basename.should == "file.txt"
1404
+ end
1405
+
1406
+ it "should have an extname of '.txt'" do
1407
+ @uri.extname.should == ".txt"
1408
+ end
1409
+
1410
+ it "should have no query string" do
1411
+ @uri.query.should == nil
1412
+ end
1413
+
1414
+ it "should have no fragment" do
1415
+ @uri.fragment.should == nil
1416
+ end
1417
+ end
1418
+
1419
+ describe Addressable::URI, " when parsed from " +
1420
+ "'http://example.com/file.txt;parameter'" do
1421
+ before do
1422
+ @uri = Addressable::URI.parse("http://example.com/file.txt;parameter")
1423
+ end
1424
+
1425
+ it "should have a scheme of 'http'" do
1426
+ @uri.scheme.should == "http"
1427
+ end
1428
+
1429
+ it "should have an authority segment of 'example.com'" do
1430
+ @uri.authority.should == "example.com"
1431
+ end
1432
+
1433
+ it "should have a host of 'example.com'" do
1434
+ @uri.host.should == "example.com"
1435
+ end
1436
+
1437
+ it "should have no username" do
1438
+ @uri.user.should == nil
1439
+ end
1440
+
1441
+ it "should have no password" do
1442
+ @uri.password.should == nil
1443
+ end
1444
+
1445
+ it "should use port 80" do
1446
+ @uri.inferred_port.should == 80
1447
+ end
1448
+
1449
+ it "should have a path of '/file.txt;parameter'" do
1450
+ @uri.path.should == "/file.txt;parameter"
1451
+ end
1452
+
1453
+ it "should have a basename of 'file.txt'" do
1454
+ @uri.basename.should == "file.txt"
1455
+ end
1456
+
1457
+ it "should have an extname of '.txt'" do
1458
+ @uri.extname.should == ".txt"
1459
+ end
1460
+
1461
+ it "should have no query string" do
1462
+ @uri.query.should == nil
1463
+ end
1464
+
1465
+ it "should have no fragment" do
1466
+ @uri.fragment.should == nil
1467
+ end
1468
+ end
1469
+
1470
+ describe Addressable::URI, " when parsed from " +
1471
+ "'http://example.com/file.txt;x=y'" do
1472
+ before do
1473
+ @uri = Addressable::URI.parse("http://example.com/file.txt;x=y")
1474
+ end
1475
+
1476
+ it "should have a scheme of 'http'" do
1477
+ @uri.scheme.should == "http"
1478
+ end
1479
+
1480
+ it "should have a scheme of 'http'" do
1481
+ @uri.scheme.should == "http"
1482
+ end
1483
+
1484
+ it "should have an authority segment of 'example.com'" do
1485
+ @uri.authority.should == "example.com"
1486
+ end
1487
+
1488
+ it "should have a host of 'example.com'" do
1489
+ @uri.host.should == "example.com"
1490
+ end
1491
+
1492
+ it "should have no username" do
1493
+ @uri.user.should == nil
1494
+ end
1495
+
1496
+ it "should have no password" do
1497
+ @uri.password.should == nil
1498
+ end
1499
+
1500
+ it "should use port 80" do
1501
+ @uri.inferred_port.should == 80
1502
+ end
1503
+
1504
+ it "should have a path of '/file.txt;x=y'" do
1505
+ @uri.path.should == "/file.txt;x=y"
1506
+ end
1507
+
1508
+ it "should have an extname of '.txt'" do
1509
+ @uri.extname.should == ".txt"
1510
+ end
1511
+
1512
+ it "should have no query string" do
1513
+ @uri.query.should == nil
1514
+ end
1515
+
1516
+ it "should have no fragment" do
1517
+ @uri.fragment.should == nil
1518
+ end
1519
+
1520
+ it "should be considered to be in normal form" do
1521
+ @uri.normalize.should be_eql(@uri)
1522
+ end
1523
+ end
1524
+
1525
+ describe Addressable::URI, " when parsed from " +
1526
+ "'svn+ssh://developername@rubyforge.org/var/svn/project'" do
1527
+ before do
1528
+ @uri = Addressable::URI.parse(
1529
+ "svn+ssh://developername@rubyforge.org/var/svn/project"
1530
+ )
1531
+ end
1532
+
1533
+ it "should have a scheme of 'svn+ssh'" do
1534
+ @uri.scheme.should == "svn+ssh"
1535
+ end
1536
+
1537
+ it "should be considered to be ip-based" do
1538
+ @uri.should be_ip_based
1539
+ end
1540
+
1541
+ it "should have a path of '/var/svn/project'" do
1542
+ @uri.path.should == "/var/svn/project"
1543
+ end
1544
+
1545
+ it "should have a username of 'developername'" do
1546
+ @uri.user.should == "developername"
1547
+ end
1548
+
1549
+ it "should have no password" do
1550
+ @uri.password.should == nil
1551
+ end
1552
+
1553
+ it "should be considered to be in normal form" do
1554
+ @uri.normalize.should be_eql(@uri)
1555
+ end
1556
+ end
1557
+
1558
+ describe Addressable::URI, " when parsed from " +
1559
+ "'ssh+svn://developername@rubyforge.org/var/svn/project'" do
1560
+ before do
1561
+ @uri = Addressable::URI.parse(
1562
+ "ssh+svn://developername@rubyforge.org/var/svn/project"
1563
+ )
1564
+ end
1565
+
1566
+ it "should have a scheme of 'ssh+svn'" do
1567
+ @uri.scheme.should == "ssh+svn"
1568
+ end
1569
+
1570
+ it "should have a normalized scheme of 'svn+ssh'" do
1571
+ @uri.normalized_scheme.should == "svn+ssh"
1572
+ end
1573
+
1574
+ it "should not be considered to be ip-based" do
1575
+ @uri.should_not be_ip_based
1576
+ end
1577
+
1578
+ it "should have a path of '/var/svn/project'" do
1579
+ @uri.path.should == "/var/svn/project"
1580
+ end
1581
+
1582
+ it "should have a username of 'developername'" do
1583
+ @uri.user.should == "developername"
1584
+ end
1585
+
1586
+ it "should have no password" do
1587
+ @uri.password.should == nil
1588
+ end
1589
+
1590
+ it "should not be considered to be in normal form" do
1591
+ @uri.normalize.should_not be_eql(@uri)
1592
+ end
1593
+ end
1594
+
1595
+ describe Addressable::URI, " when parsed from " +
1596
+ "'mailto:user@example.com'" do
1597
+ before do
1598
+ @uri = Addressable::URI.parse("mailto:user@example.com")
1599
+ end
1600
+
1601
+ it "should have a scheme of 'mailto'" do
1602
+ @uri.scheme.should == "mailto"
1603
+ end
1604
+
1605
+ it "should not be considered to be ip-based" do
1606
+ @uri.should_not be_ip_based
1607
+ end
1608
+
1609
+ it "should have a path of 'user@example.com'" do
1610
+ @uri.path.should == "user@example.com"
1611
+ end
1612
+
1613
+ it "should have no user" do
1614
+ @uri.user.should == nil
1615
+ end
1616
+
1617
+ it "should be considered to be in normal form" do
1618
+ @uri.normalize.should be_eql(@uri)
1619
+ end
1620
+ end
1621
+
1622
+ describe Addressable::URI, " when parsed from " +
1623
+ "'tag:example.com,2006-08-18:/path/to/something'" do
1624
+ before do
1625
+ @uri = Addressable::URI.parse(
1626
+ "tag:example.com,2006-08-18:/path/to/something")
1627
+ end
1628
+
1629
+ it "should have a scheme of 'tag'" do
1630
+ @uri.scheme.should == "tag"
1631
+ end
1632
+
1633
+ it "should be considered to be ip-based" do
1634
+ @uri.should_not be_ip_based
1635
+ end
1636
+
1637
+ it "should have a path of " +
1638
+ "'example.com,2006-08-18:/path/to/something'" do
1639
+ @uri.path.should == "example.com,2006-08-18:/path/to/something"
1640
+ end
1641
+
1642
+ it "should have no user" do
1643
+ @uri.user.should == nil
1644
+ end
1645
+
1646
+ it "should be considered to be in normal form" do
1647
+ @uri.normalize.should be_eql(@uri)
1648
+ end
1649
+ end
1650
+
1651
+ describe Addressable::URI, " when parsed from " +
1652
+ "'http://example.com/x;y/'" do
1653
+ before do
1654
+ @uri = Addressable::URI.parse("http://example.com/x;y/")
1655
+ end
1656
+
1657
+ it "should be considered to be in normal form" do
1658
+ @uri.normalize.should be_eql(@uri)
1659
+ end
1660
+ end
1661
+
1662
+ describe Addressable::URI, " when parsed from " +
1663
+ "'http://example.com/?x=1&y=2'" do
1664
+ before do
1665
+ @uri = Addressable::URI.parse("http://example.com/?x=1&y=2")
1666
+ end
1667
+
1668
+ it "should be considered to be in normal form" do
1669
+ @uri.normalize.should be_eql(@uri)
1670
+ end
1671
+ end
1672
+
1673
+ describe Addressable::URI, " when parsed from " +
1674
+ "'view-source:http://example.com/'" do
1675
+ before do
1676
+ @uri = Addressable::URI.parse("view-source:http://example.com/")
1677
+ end
1678
+
1679
+ it "should have a scheme of 'view-source'" do
1680
+ @uri.scheme.should == "view-source"
1681
+ end
1682
+
1683
+ it "should have a path of 'http://example.com/'" do
1684
+ @uri.path.should == "http://example.com/"
1685
+ end
1686
+
1687
+ it "should be considered to be in normal form" do
1688
+ @uri.normalize.should be_eql(@uri)
1689
+ end
1690
+ end
1691
+
1692
+ describe Addressable::URI, " when parsed from " +
1693
+ "'http://user:pass@example.com/path/to/resource?query=x#fragment'" do
1694
+ before do
1695
+ @uri = Addressable::URI.parse(
1696
+ "http://user:pass@example.com/path/to/resource?query=x#fragment")
1697
+ end
1698
+
1699
+ it "should use the 'http' scheme" do
1700
+ @uri.scheme.should == "http"
1701
+ end
1702
+
1703
+ it "should have an authority segment of 'user:pass@example.com'" do
1704
+ @uri.authority.should == "user:pass@example.com"
1705
+ end
1706
+
1707
+ it "should have a username of 'user'" do
1708
+ @uri.user.should == "user"
1709
+ end
1710
+
1711
+ it "should have a password of 'pass'" do
1712
+ @uri.password.should == "pass"
1713
+ end
1714
+
1715
+ it "should have a host of 'example.com'" do
1716
+ @uri.host.should == "example.com"
1717
+ end
1718
+
1719
+ it "should use port 80" do
1720
+ @uri.inferred_port.should == 80
1721
+ end
1722
+
1723
+ it "should have a path of '/path/to/resource'" do
1724
+ @uri.path.should == "/path/to/resource"
1725
+ end
1726
+
1727
+ it "should have a query string of 'query=x'" do
1728
+ @uri.query.should == "query=x"
1729
+ end
1730
+
1731
+ it "should have a fragment of 'fragment'" do
1732
+ @uri.fragment.should == "fragment"
1733
+ end
1734
+
1735
+ it "should be considered to be in normal form" do
1736
+ @uri.normalize.should be_eql(@uri)
1737
+ end
1738
+
1739
+ it "should have a route of '/path/' to " +
1740
+ "'http://user:pass@example.com/path/'" do
1741
+ @uri.route_to("http://user:pass@example.com/path/").should ==
1742
+ Addressable::URI.parse("/path/")
1743
+ end
1744
+
1745
+ it "should have a route of '/path/to/resource?query=x#fragment' " +
1746
+ "from 'http://user:pass@example.com/path/'" do
1747
+ @uri.route_from("http://user:pass@example.com/path/").should ==
1748
+ Addressable::URI.parse("to/resource?query=x#fragment")
1749
+ end
1750
+
1751
+ it "should have a route of '?query=x#fragment' " +
1752
+ "from 'http://user:pass@example.com/path/to/resource'" do
1753
+ @uri.route_from("http://user:pass@example.com/path/to/resource").should ==
1754
+ Addressable::URI.parse("?query=x#fragment")
1755
+ end
1756
+
1757
+ it "should have a route of '#fragment' " +
1758
+ "from 'http://user:pass@example.com/path/to/resource?query=x'" do
1759
+ @uri.route_from(
1760
+ "http://user:pass@example.com/path/to/resource?query=x").should ==
1761
+ Addressable::URI.parse("#fragment")
1762
+ end
1763
+
1764
+ it "should have a route of '#fragment' from " +
1765
+ "'http://user:pass@example.com/path/to/resource?query=x#fragment'" do
1766
+ @uri.route_from(
1767
+ "http://user:pass@example.com/path/to/resource?query=x#fragment"
1768
+ ).should == Addressable::URI.parse("#fragment")
1769
+ end
1770
+
1771
+ it "should have a route of 'http://elsewhere.com/' to " +
1772
+ "'http://elsewhere.com/'" do
1773
+ @uri.route_to("http://elsewhere.com/").should ==
1774
+ Addressable::URI.parse("http://elsewhere.com/")
1775
+ end
1776
+
1777
+ it "should have a route of " +
1778
+ "'http://user:pass@example.com/path/to/resource?query=x#fragment' " +
1779
+ "from 'http://example.com/path/to/'" do
1780
+ @uri.route_from("http://elsewhere.com/path/to/").should ==
1781
+ Addressable::URI.parse(
1782
+ "http://user:pass@example.com/path/to/resource?query=x#fragment")
1783
+ end
1784
+
1785
+ it "should have the correct scheme after assignment" do
1786
+ @uri.scheme = "ftp"
1787
+ @uri.scheme.should == "ftp"
1788
+ @uri.to_s.should ==
1789
+ "ftp://user:pass@example.com/path/to/resource?query=x#fragment"
1790
+ end
1791
+
1792
+ it "should have the correct authority segment after assignment" do
1793
+ @uri.authority = "newuser:newpass@example.com:80"
1794
+ @uri.authority.should == "newuser:newpass@example.com:80"
1795
+ @uri.user.should == "newuser"
1796
+ @uri.password.should == "newpass"
1797
+ @uri.userinfo.should == "newuser:newpass"
1798
+ @uri.normalized_userinfo.should == "newuser:newpass"
1799
+ @uri.host.should == "example.com"
1800
+ @uri.port.should == 80
1801
+ @uri.inferred_port.should == 80
1802
+ @uri.to_s.should ==
1803
+ "http://newuser:newpass@example.com:80" +
1804
+ "/path/to/resource?query=x#fragment"
1805
+ end
1806
+
1807
+ it "should have the correct userinfo segment after assignment" do
1808
+ @uri.userinfo = "newuser:newpass"
1809
+ @uri.userinfo.should == "newuser:newpass"
1810
+ @uri.authority.should == "newuser:newpass@example.com"
1811
+ @uri.user.should == "newuser"
1812
+ @uri.password.should == "newpass"
1813
+ @uri.host.should == "example.com"
1814
+ @uri.port.should == nil
1815
+ @uri.inferred_port.should == 80
1816
+ @uri.to_s.should ==
1817
+ "http://newuser:newpass@example.com" +
1818
+ "/path/to/resource?query=x#fragment"
1819
+ end
1820
+
1821
+ it "should have the correct username after assignment" do
1822
+ @uri.user = "newuser"
1823
+ @uri.user.should == "newuser"
1824
+ @uri.authority.should == "newuser:pass@example.com"
1825
+ end
1826
+
1827
+ it "should have the correct password after assignment" do
1828
+ @uri.password = "newpass"
1829
+ @uri.password.should == "newpass"
1830
+ @uri.authority.should == "user:newpass@example.com"
1831
+ end
1832
+
1833
+ it "should have the correct host after assignment" do
1834
+ @uri.host = "newexample.com"
1835
+ @uri.host.should == "newexample.com"
1836
+ @uri.authority.should == "user:pass@newexample.com"
1837
+ end
1838
+
1839
+ it "should have the correct port after assignment" do
1840
+ @uri.port = 8080
1841
+ @uri.port.should == 8080
1842
+ @uri.authority.should == "user:pass@example.com:8080"
1843
+ end
1844
+
1845
+ it "should have the correct path after assignment" do
1846
+ @uri.path = "/newpath/to/resource"
1847
+ @uri.path.should == "/newpath/to/resource"
1848
+ @uri.to_s.should ==
1849
+ "http://user:pass@example.com/newpath/to/resource?query=x#fragment"
1850
+ end
1851
+
1852
+ it "should have the correct path after nil assignment" do
1853
+ @uri.path = nil
1854
+ @uri.path.should == ""
1855
+ @uri.to_s.should ==
1856
+ "http://user:pass@example.com?query=x#fragment"
1857
+ end
1858
+
1859
+ it "should have the correct query string after assignment" do
1860
+ @uri.query = "newquery=x"
1861
+ @uri.query.should == "newquery=x"
1862
+ @uri.to_s.should ==
1863
+ "http://user:pass@example.com/path/to/resource?newquery=x#fragment"
1864
+ end
1865
+
1866
+ it "should have the correct query string after hash assignment" do
1867
+ @uri.query_values = {"?uestion mark"=>"=sign", "hello"=>"günther"}
1868
+ @uri.query.split("&").should include("%3Fuestion%20mark=%3Dsign")
1869
+ @uri.query.split("&").should include("hello=g%C3%BCnther")
1870
+ @uri.query_values.should == {"?uestion mark"=>"=sign", "hello"=>"günther"}
1871
+ end
1872
+
1873
+ it "should have the correct query string after flag hash assignment" do
1874
+ @uri.query_values = {'flag?1' => true, 'fl=ag2' => true, 'flag3' => true}
1875
+ @uri.query.split("&").should include("flag%3F1")
1876
+ @uri.query.split("&").should include("fl%3Dag2")
1877
+ @uri.query.split("&").should include("flag3")
1878
+ @uri.query_values.should == {
1879
+ 'flag?1' => true, 'fl=ag2' => true, 'flag3' => true
1880
+ }
1881
+ end
1882
+
1883
+ it "should have the correct fragment after assignment" do
1884
+ @uri.fragment = "newfragment"
1885
+ @uri.fragment.should == "newfragment"
1886
+ @uri.to_s.should ==
1887
+ "http://user:pass@example.com/path/to/resource?query=x#newfragment"
1888
+
1889
+ @uri.fragment = nil
1890
+ @uri.fragment.should == nil
1891
+ @uri.to_s.should ==
1892
+ "http://user:pass@example.com/path/to/resource?query=x"
1893
+ end
1894
+
1895
+ it "should have the correct values after a merge" do
1896
+ @uri.merge(:fragment => "newfragment").to_s.should ==
1897
+ "http://user:pass@example.com/path/to/resource?query=x#newfragment"
1898
+ end
1899
+
1900
+ it "should have the correct values after a merge" do
1901
+ @uri.merge(:fragment => nil).to_s.should ==
1902
+ "http://user:pass@example.com/path/to/resource?query=x"
1903
+ end
1904
+
1905
+ it "should have the correct values after a merge" do
1906
+ @uri.merge(:userinfo => "newuser:newpass").to_s.should ==
1907
+ "http://newuser:newpass@example.com/path/to/resource?query=x#fragment"
1908
+ end
1909
+
1910
+ it "should have the correct values after a merge" do
1911
+ @uri.merge(:userinfo => nil).to_s.should ==
1912
+ "http://example.com/path/to/resource?query=x#fragment"
1913
+ end
1914
+
1915
+ it "should have the correct values after a merge" do
1916
+ @uri.merge(:path => "newpath").to_s.should ==
1917
+ "http://user:pass@example.com/newpath?query=x#fragment"
1918
+ end
1919
+
1920
+ it "should have the correct values after a merge" do
1921
+ @uri.merge(:port => "42", :path => "newpath", :query => "").to_s.should ==
1922
+ "http://user:pass@example.com:42/newpath?#fragment"
1923
+ end
1924
+
1925
+ it "should have the correct values after a merge" do
1926
+ @uri.merge(:authority => "foo:bar@baz:42").to_s.should ==
1927
+ "http://foo:bar@baz:42/path/to/resource?query=x#fragment"
1928
+ @uri.to_s.should ==
1929
+ "http://user:pass@example.com/path/to/resource?query=x#fragment"
1930
+ end
1931
+
1932
+ it "should have the correct values after a destructive merge" do
1933
+ @uri.merge!(:authority => "foo:bar@baz:42")
1934
+ @uri.to_s.should ==
1935
+ "http://foo:bar@baz:42/path/to/resource?query=x#fragment"
1936
+ end
1937
+
1938
+ it "should fail to merge with bogus values" do
1939
+ (lambda do
1940
+ @uri.merge(:port => "bogus")
1941
+ end).should raise_error(Addressable::URI::InvalidURIError)
1942
+ end
1943
+
1944
+ it "should fail to merge with bogus parameters" do
1945
+ (lambda do
1946
+ @uri.merge(42)
1947
+ end).should raise_error(TypeError)
1948
+ end
1949
+
1950
+ it "should fail to merge with bogus parameters" do
1951
+ (lambda do
1952
+ @uri.merge("http://example.com/")
1953
+ end).should raise_error(TypeError)
1954
+ end
1955
+
1956
+ it "should fail to merge with both authority and subcomponents" do
1957
+ (lambda do
1958
+ @uri.merge(:authority => "foo:bar@baz:42", :port => "42")
1959
+ end).should raise_error(ArgumentError)
1960
+ end
1961
+
1962
+ it "should fail to merge with both userinfo and subcomponents" do
1963
+ (lambda do
1964
+ @uri.merge(:userinfo => "foo:bar", :user => "foo")
1965
+ end).should raise_error(ArgumentError)
1966
+ end
1967
+
1968
+ it "should be identical to its duplicate" do
1969
+ @uri.should == @uri.dup
1970
+ end
1971
+ end
1972
+
1973
+ describe Addressable::URI, " when parsed from " +
1974
+ "'http://user@example.com'" do
1975
+ before do
1976
+ @uri = Addressable::URI.parse("http://user@example.com")
1977
+ end
1978
+
1979
+ it "should use the 'http' scheme" do
1980
+ @uri.scheme.should == "http"
1981
+ end
1982
+
1983
+ it "should have a username of 'user'" do
1984
+ @uri.user.should == "user"
1985
+ end
1986
+
1987
+ it "should have no password" do
1988
+ @uri.password.should == nil
1989
+ end
1990
+
1991
+ it "should have a userinfo of 'user'" do
1992
+ @uri.userinfo.should == "user"
1993
+ end
1994
+
1995
+ it "should have a normalized userinfo of 'user'" do
1996
+ @uri.normalized_userinfo.should == "user"
1997
+ end
1998
+
1999
+ it "should have a host of 'example.com'" do
2000
+ @uri.host.should == "example.com"
2001
+ end
2002
+
2003
+ it "should use port 80" do
2004
+ @uri.inferred_port.should == 80
2005
+ end
2006
+
2007
+ it "should have the correct username after assignment" do
2008
+ @uri.user = "newuser"
2009
+ @uri.user.should == "newuser"
2010
+ @uri.password.should == nil
2011
+ @uri.to_s.should == "http://newuser@example.com"
2012
+ end
2013
+
2014
+ it "should have the correct password after assignment" do
2015
+ @uri.password = "newpass"
2016
+ @uri.password.should == "newpass"
2017
+ @uri.to_s.should == "http://user:newpass@example.com"
2018
+ end
2019
+
2020
+ it "should have the correct userinfo segment after assignment" do
2021
+ @uri.userinfo = "newuser:newpass"
2022
+ @uri.userinfo.should == "newuser:newpass"
2023
+ @uri.user.should == "newuser"
2024
+ @uri.password.should == "newpass"
2025
+ @uri.host.should == "example.com"
2026
+ @uri.port.should == nil
2027
+ @uri.inferred_port.should == 80
2028
+ @uri.to_s.should == "http://newuser:newpass@example.com"
2029
+ end
2030
+
2031
+ it "should have the correct userinfo segment after nil assignment" do
2032
+ @uri.userinfo = nil
2033
+ @uri.userinfo.should == nil
2034
+ @uri.user.should == nil
2035
+ @uri.password.should == nil
2036
+ @uri.host.should == "example.com"
2037
+ @uri.port.should == nil
2038
+ @uri.inferred_port.should == 80
2039
+ @uri.to_s.should == "http://example.com"
2040
+ end
2041
+
2042
+ it "should have the correct authority segment after assignment" do
2043
+ @uri.authority = "newuser@example.com"
2044
+ @uri.authority.should == "newuser@example.com"
2045
+ @uri.user.should == "newuser"
2046
+ @uri.password.should == nil
2047
+ @uri.host.should == "example.com"
2048
+ @uri.port.should == nil
2049
+ @uri.inferred_port.should == 80
2050
+ @uri.to_s.should == "http://newuser@example.com"
2051
+ end
2052
+
2053
+ it "should raise an error after nil assignment of authority segment" do
2054
+ (lambda do
2055
+ # This would create an invalid URI
2056
+ @uri.authority = nil
2057
+ end).should raise_error
2058
+ end
2059
+ end
2060
+
2061
+ describe Addressable::URI, " when parsed from " +
2062
+ "'http://user:@example.com'" do
2063
+ before do
2064
+ @uri = Addressable::URI.parse("http://user:@example.com")
2065
+ end
2066
+
2067
+ it "should use the 'http' scheme" do
2068
+ @uri.scheme.should == "http"
2069
+ end
2070
+
2071
+ it "should have a username of 'user'" do
2072
+ @uri.user.should == "user"
2073
+ end
2074
+
2075
+ it "should have a password of ''" do
2076
+ @uri.password.should == ""
2077
+ end
2078
+
2079
+ it "should have a normalized userinfo of 'user:'" do
2080
+ @uri.normalized_userinfo.should == "user:"
2081
+ end
2082
+
2083
+ it "should have a host of 'example.com'" do
2084
+ @uri.host.should == "example.com"
2085
+ end
2086
+
2087
+ it "should use port 80" do
2088
+ @uri.inferred_port.should == 80
2089
+ end
2090
+
2091
+ it "should have the correct username after assignment" do
2092
+ @uri.user = "newuser"
2093
+ @uri.user.should == "newuser"
2094
+ @uri.password.should == ""
2095
+ @uri.to_s.should == "http://newuser:@example.com"
2096
+ end
2097
+
2098
+ it "should have the correct password after assignment" do
2099
+ @uri.password = "newpass"
2100
+ @uri.password.should == "newpass"
2101
+ @uri.to_s.should == "http://user:newpass@example.com"
2102
+ end
2103
+
2104
+ it "should have the correct authority segment after assignment" do
2105
+ @uri.authority = "newuser:@example.com"
2106
+ @uri.authority.should == "newuser:@example.com"
2107
+ @uri.user.should == "newuser"
2108
+ @uri.password.should == ""
2109
+ @uri.host.should == "example.com"
2110
+ @uri.port.should == nil
2111
+ @uri.inferred_port.should == 80
2112
+ @uri.to_s.should == "http://newuser:@example.com"
2113
+ end
2114
+ end
2115
+
2116
+ describe Addressable::URI, " when parsed from " +
2117
+ "'http://:pass@example.com'" do
2118
+ before do
2119
+ @uri = Addressable::URI.parse("http://:pass@example.com")
2120
+ end
2121
+
2122
+ it "should use the 'http' scheme" do
2123
+ @uri.scheme.should == "http"
2124
+ end
2125
+
2126
+ it "should have a username of ''" do
2127
+ @uri.user.should == ""
2128
+ end
2129
+
2130
+ it "should have a password of 'pass'" do
2131
+ @uri.password.should == "pass"
2132
+ end
2133
+
2134
+ it "should have a userinfo of ':pass'" do
2135
+ @uri.userinfo.should == ":pass"
2136
+ end
2137
+
2138
+ it "should have a normalized userinfo of ':pass'" do
2139
+ @uri.normalized_userinfo.should == ":pass"
2140
+ end
2141
+
2142
+ it "should have a host of 'example.com'" do
2143
+ @uri.host.should == "example.com"
2144
+ end
2145
+
2146
+ it "should use port 80" do
2147
+ @uri.inferred_port.should == 80
2148
+ end
2149
+
2150
+ it "should have the correct username after assignment" do
2151
+ @uri.user = "newuser"
2152
+ @uri.user.should == "newuser"
2153
+ @uri.password.should == "pass"
2154
+ @uri.to_s.should == "http://newuser:pass@example.com"
2155
+ end
2156
+
2157
+ it "should have the correct password after assignment" do
2158
+ @uri.password = "newpass"
2159
+ @uri.password.should == "newpass"
2160
+ @uri.user.should == ""
2161
+ @uri.to_s.should == "http://:newpass@example.com"
2162
+ end
2163
+
2164
+ it "should have the correct authority segment after assignment" do
2165
+ @uri.authority = ":newpass@example.com"
2166
+ @uri.authority.should == ":newpass@example.com"
2167
+ @uri.user.should == ""
2168
+ @uri.password.should == "newpass"
2169
+ @uri.host.should == "example.com"
2170
+ @uri.port.should == nil
2171
+ @uri.inferred_port.should == 80
2172
+ @uri.to_s.should == "http://:newpass@example.com"
2173
+ end
2174
+ end
2175
+
2176
+ describe Addressable::URI, " when parsed from " +
2177
+ "'http://:@example.com'" do
2178
+ before do
2179
+ @uri = Addressable::URI.parse("http://:@example.com")
2180
+ end
2181
+
2182
+ it "should use the 'http' scheme" do
2183
+ @uri.scheme.should == "http"
2184
+ end
2185
+
2186
+ it "should have a username of ''" do
2187
+ @uri.user.should == ""
2188
+ end
2189
+
2190
+ it "should have a password of ''" do
2191
+ @uri.password.should == ""
2192
+ end
2193
+
2194
+ it "should have a normalized userinfo of nil" do
2195
+ @uri.normalized_userinfo.should == nil
2196
+ end
2197
+
2198
+ it "should have a host of 'example.com'" do
2199
+ @uri.host.should == "example.com"
2200
+ end
2201
+
2202
+ it "should use port 80" do
2203
+ @uri.inferred_port.should == 80
2204
+ end
2205
+
2206
+ it "should have the correct username after assignment" do
2207
+ @uri.user = "newuser"
2208
+ @uri.user.should == "newuser"
2209
+ @uri.password.should == ""
2210
+ @uri.to_s.should == "http://newuser:@example.com"
2211
+ end
2212
+
2213
+ it "should have the correct password after assignment" do
2214
+ @uri.password = "newpass"
2215
+ @uri.password.should == "newpass"
2216
+ @uri.user.should == ""
2217
+ @uri.to_s.should == "http://:newpass@example.com"
2218
+ end
2219
+
2220
+ it "should have the correct authority segment after assignment" do
2221
+ @uri.authority = ":@newexample.com"
2222
+ @uri.authority.should == ":@newexample.com"
2223
+ @uri.user.should == ""
2224
+ @uri.password.should == ""
2225
+ @uri.host.should == "newexample.com"
2226
+ @uri.port.should == nil
2227
+ @uri.inferred_port.should == 80
2228
+ @uri.to_s.should == "http://:@newexample.com"
2229
+ end
2230
+ end
2231
+
2232
+ describe Addressable::URI, " when parsed from " +
2233
+ "'#example'" do
2234
+ before do
2235
+ @uri = Addressable::URI.parse("#example")
2236
+ end
2237
+
2238
+ it "should be considered relative" do
2239
+ @uri.should be_relative
2240
+ end
2241
+
2242
+ it "should have a host of nil" do
2243
+ @uri.host.should == nil
2244
+ end
2245
+
2246
+ it "should have a path of ''" do
2247
+ @uri.path.should == ""
2248
+ end
2249
+
2250
+ it "should have a query string of nil" do
2251
+ @uri.query.should == nil
2252
+ end
2253
+
2254
+ it "should have a fragment of 'example'" do
2255
+ @uri.fragment.should == "example"
2256
+ end
2257
+ end
2258
+
2259
+ describe Addressable::URI, " when parsed from " +
2260
+ "the network-path reference '//example.com/'" do
2261
+ before do
2262
+ @uri = Addressable::URI.parse("//example.com/")
2263
+ end
2264
+
2265
+ it "should be considered relative" do
2266
+ @uri.should be_relative
2267
+ end
2268
+
2269
+ it "should have a host of 'example.com'" do
2270
+ @uri.host.should == "example.com"
2271
+ end
2272
+
2273
+ it "should have a path of '/'" do
2274
+ @uri.path.should == "/"
2275
+ end
2276
+
2277
+ it "should raise an error if routing is attempted" do
2278
+ (lambda do
2279
+ @uri.route_to("http://example.com/")
2280
+ end).should raise_error(ArgumentError, /\/\/example.com\//)
2281
+ (lambda do
2282
+ @uri.route_from("http://example.com/")
2283
+ end).should raise_error(ArgumentError, /\/\/example.com\//)
2284
+ end
2285
+ end
2286
+
2287
+ describe Addressable::URI, " when parsed from " +
2288
+ "'feed://http://example.com/'" do
2289
+ before do
2290
+ @uri = Addressable::URI.parse("feed://http://example.com/")
2291
+ end
2292
+
2293
+ it "should have a host of 'http'" do
2294
+ @uri.host.should == "http"
2295
+ end
2296
+
2297
+ it "should have a path of '//example.com/'" do
2298
+ @uri.path.should == "//example.com/"
2299
+ end
2300
+ end
2301
+
2302
+ describe Addressable::URI, " when parsed from " +
2303
+ "'feed:http://example.com/'" do
2304
+ before do
2305
+ @uri = Addressable::URI.parse("feed:http://example.com/")
2306
+ end
2307
+
2308
+ it "should have a path of 'http://example.com/'" do
2309
+ @uri.path.should == "http://example.com/"
2310
+ end
2311
+
2312
+ it "should normalize to 'http://example.com/'" do
2313
+ @uri.normalize.to_s.should == "http://example.com/"
2314
+ @uri.normalize!.to_s.should == "http://example.com/"
2315
+ end
2316
+ end
2317
+
2318
+ describe Addressable::URI, "when parsed from " +
2319
+ "'example://a/b/c/%7Bfoo%7D'" do
2320
+ before do
2321
+ @uri = Addressable::URI.parse("example://a/b/c/%7Bfoo%7D")
2322
+ end
2323
+
2324
+ # Section 6.2.2 of RFC 3986
2325
+ it "should be equivalent to eXAMPLE://a/./b/../b/%63/%7bfoo%7d" do
2326
+ @uri.should ==
2327
+ Addressable::URI.parse("eXAMPLE://a/./b/../b/%63/%7bfoo%7d")
2328
+ end
2329
+ end
2330
+
2331
+ describe Addressable::URI, " when parsed from " +
2332
+ "'http://example.com/indirect/path/./to/../resource/'" do
2333
+ before do
2334
+ @uri = Addressable::URI.parse(
2335
+ "http://example.com/indirect/path/./to/../resource/")
2336
+ end
2337
+
2338
+ it "should use the 'http' scheme" do
2339
+ @uri.scheme.should == "http"
2340
+ end
2341
+
2342
+ it "should have a host of 'example.com'" do
2343
+ @uri.host.should == "example.com"
2344
+ end
2345
+
2346
+ it "should use port 80" do
2347
+ @uri.inferred_port.should == 80
2348
+ end
2349
+
2350
+ it "should have a path of '/indirect/path/./to/../resource/'" do
2351
+ @uri.path.should == "/indirect/path/./to/../resource/"
2352
+ end
2353
+
2354
+ # Section 6.2.2.3 of RFC 3986
2355
+ it "should have a normalized path of '/indirect/path/resource/'" do
2356
+ @uri.normalize.path.should == "/indirect/path/resource/"
2357
+ @uri.normalize!.path.should == "/indirect/path/resource/"
2358
+ end
2359
+ end
2360
+
2361
+ describe Addressable::URI, " when parsed from " +
2362
+ "'http://under_score.example.com/'" do
2363
+ it "should not cause an error" do
2364
+ (lambda do
2365
+ Addressable::URI.parse("http://under_score.example.com/")
2366
+ end).should_not raise_error
2367
+ end
2368
+ end
2369
+
2370
+ describe Addressable::URI, " when parsed from " +
2371
+ "'./this:that'" do
2372
+ before do
2373
+ @uri = Addressable::URI.parse("./this:that")
2374
+ end
2375
+
2376
+ it "should be considered relative" do
2377
+ @uri.should be_relative
2378
+ end
2379
+
2380
+ it "should have no scheme" do
2381
+ @uri.scheme.should == nil
2382
+ end
2383
+ end
2384
+
2385
+ describe Addressable::URI, "when parsed from " +
2386
+ "'this:that'" do
2387
+ before do
2388
+ @uri = Addressable::URI.parse("this:that")
2389
+ end
2390
+
2391
+ it "should be considered absolute" do
2392
+ @uri.should be_absolute
2393
+ end
2394
+
2395
+ it "should have a scheme of 'this'" do
2396
+ @uri.scheme.should == "this"
2397
+ end
2398
+ end
2399
+
2400
+ describe Addressable::URI, " when parsed from '?one=1&two=2&three=3'" do
2401
+ before do
2402
+ @uri = Addressable::URI.parse("?one=1&two=2&three=3")
2403
+ end
2404
+
2405
+ it "should have the correct query values" do
2406
+ @uri.query_values.should == {"one" => "1", "two" => "2", "three" => "3"}
2407
+ end
2408
+
2409
+ it "should raise an error for invalid query value notations" do
2410
+ (lambda do
2411
+ @uri.query_values(:notation => :bogus)
2412
+ end).should raise_error(ArgumentError)
2413
+ end
2414
+ end
2415
+
2416
+ describe Addressable::URI, " when parsed from '?one[two][three]=four'" do
2417
+ before do
2418
+ @uri = Addressable::URI.parse("?one[two][three]=four")
2419
+ end
2420
+
2421
+ it "should have the correct query values" do
2422
+ @uri.query_values.should == {"one" => {"two" => {"three" => "four"}}}
2423
+ end
2424
+
2425
+ it "should have the correct flat notation query values" do
2426
+ @uri.query_values(:notation => :flat).should == {
2427
+ "one[two][three]" => "four"
2428
+ }
2429
+ end
2430
+ end
2431
+
2432
+ describe Addressable::URI, " when parsed from '?one.two.three=four'" do
2433
+ before do
2434
+ @uri = Addressable::URI.parse("?one.two.three=four")
2435
+ end
2436
+
2437
+ it "should have the correct dot notation query values" do
2438
+ @uri.query_values(:notation => :dot).should == {
2439
+ "one" => {"two" => {"three" => "four"}}
2440
+ }
2441
+ end
2442
+
2443
+ it "should have the correct flat notation query values" do
2444
+ @uri.query_values(:notation => :flat).should == {
2445
+ "one.two.three" => "four"
2446
+ }
2447
+ end
2448
+ end
2449
+
2450
+ describe Addressable::URI, " when parsed from " +
2451
+ "'?one[two][three]=four&one[two][five]=six'" do
2452
+ before do
2453
+ @uri = Addressable::URI.parse("?one[two][three]=four&one[two][five]=six")
2454
+ end
2455
+
2456
+ it "should have the correct dot notation query values" do
2457
+ @uri.query_values(:notation => :subscript).should == {
2458
+ "one" => {"two" => {"three" => "four", "five" => "six"}}
2459
+ }
2460
+ end
2461
+
2462
+ it "should have the correct flat notation query values" do
2463
+ @uri.query_values(:notation => :flat).should == {
2464
+ "one[two][three]" => "four",
2465
+ "one[two][five]" => "six"
2466
+ }
2467
+ end
2468
+ end
2469
+
2470
+ describe Addressable::URI, " when parsed from " +
2471
+ "'?one.two.three=four&one.two.five=six'" do
2472
+ before do
2473
+ @uri = Addressable::URI.parse("?one.two.three=four&one.two.five=six")
2474
+ end
2475
+
2476
+ it "should have the correct dot notation query values" do
2477
+ @uri.query_values(:notation => :dot).should == {
2478
+ "one" => {"two" => {"three" => "four", "five" => "six"}}
2479
+ }
2480
+ end
2481
+
2482
+ it "should have the correct flat notation query values" do
2483
+ @uri.query_values(:notation => :flat).should == {
2484
+ "one.two.three" => "four",
2485
+ "one.two.five" => "six"
2486
+ }
2487
+ end
2488
+ end
2489
+
2490
+ describe Addressable::URI, " when parsed from " +
2491
+ "'?one[two][three][]=four&one[two][three][]=five'" do
2492
+ before do
2493
+ @uri = Addressable::URI.parse(
2494
+ "?one[two][three][]=four&one[two][three][]=five"
2495
+ )
2496
+ end
2497
+
2498
+ it "should have the correct dot notation query values" do
2499
+ @uri.query_values(:notation => :subscript).should == {
2500
+ "one" => {"two" => {"three" => ["four", "five"]}}
2501
+ }
2502
+ end
2503
+
2504
+ it "should raise an error if a key is repeated in the flat notation" do
2505
+ (lambda do
2506
+ @uri.query_values(:notation => :flat)
2507
+ end).should raise_error(ArgumentError)
2508
+ end
2509
+ end
2510
+
2511
+ describe Addressable::URI, " when parsed from " +
2512
+ "'http://www.詹姆斯.com/'" do
2513
+ before do
2514
+ @uri = Addressable::URI.parse("http://www.詹姆斯.com/")
2515
+ end
2516
+
2517
+ it "should be equivalent to 'http://www.xn--8ws00zhy3a.com/'" do
2518
+ @uri.should ==
2519
+ Addressable::URI.parse("http://www.xn--8ws00zhy3a.com/")
2520
+ end
2521
+
2522
+ it "should not have domain name encoded during normalization" do
2523
+ Addressable::URI.normalized_encode(@uri.to_s).should ==
2524
+ "http://www.詹姆斯.com/"
2525
+ end
2526
+ end
2527
+
2528
+ describe Addressable::URI, " when parsed from " +
2529
+ "'http://www.詹姆斯.com/ some spaces /'" do
2530
+ before do
2531
+ @uri = Addressable::URI.parse("http://www.詹姆斯.com/ some spaces /")
2532
+ end
2533
+
2534
+ it "should be equivalent to " +
2535
+ "'http://www.xn--8ws00zhy3a.com/%20some%20spaces%20/'" do
2536
+ @uri.should ==
2537
+ Addressable::URI.parse(
2538
+ "http://www.xn--8ws00zhy3a.com/%20some%20spaces%20/")
2539
+ end
2540
+
2541
+ it "should not have domain name encoded during normalization" do
2542
+ Addressable::URI.normalized_encode(@uri.to_s).should ==
2543
+ "http://www.詹姆斯.com/%20some%20spaces%20/"
2544
+ end
2545
+ end
2546
+
2547
+ describe Addressable::URI, " when parsed from " +
2548
+ "'http://www.xn--8ws00zhy3a.com/'" do
2549
+ before do
2550
+ @uri = Addressable::URI.parse("http://www.xn--8ws00zhy3a.com/")
2551
+ end
2552
+
2553
+ it "should be displayed as http://www.詹姆斯.com/" do
2554
+ @uri.display_uri.to_s.should == "http://www.詹姆斯.com/"
2555
+ end
2556
+ end
2557
+
2558
+ describe Addressable::URI, " when parsed from " +
2559
+ "'http://www.詹姆斯.com/atomtests/iri/詹.html'" do
2560
+ before do
2561
+ @uri = Addressable::URI.parse("http://www.詹姆斯.com/atomtests/iri/詹.html")
2562
+ end
2563
+
2564
+ it "should normalize to " +
2565
+ "http://www.xn--8ws00zhy3a.com/atomtests/iri/%E8%A9%B9.html" do
2566
+ @uri.normalize.to_s.should ==
2567
+ "http://www.xn--8ws00zhy3a.com/atomtests/iri/%E8%A9%B9.html"
2568
+ @uri.normalize!.to_s.should ==
2569
+ "http://www.xn--8ws00zhy3a.com/atomtests/iri/%E8%A9%B9.html"
2570
+ end
2571
+ end
2572
+
2573
+ describe Addressable::URI, " when parsed from a percent-encoded IRI" do
2574
+ before do
2575
+ @uri = Addressable::URI.parse(
2576
+ "http://www.%E3%81%BB%E3%82%93%E3%81%A8%E3%81%86%E3%81%AB%E3%81%AA" +
2577
+ "%E3%81%8C%E3%81%84%E3%82%8F%E3%81%91%E3%81%AE%E3%82%8F%E3%81%8B%E3" +
2578
+ "%82%89%E3%81%AA%E3%81%84%E3%81%A9%E3%82%81%E3%81%84%E3%82%93%E3%82" +
2579
+ "%81%E3%81%84%E3%81%AE%E3%82%89%E3%81%B9%E3%82%8B%E3%81%BE%E3%81%A0" +
2580
+ "%E3%81%AA%E3%81%8C%E3%81%8F%E3%81%97%E3%81%AA%E3%81%84%E3%81%A8%E3" +
2581
+ "%81%9F%E3%82%8A%E3%81%AA%E3%81%84.w3.mag.keio.ac.jp"
2582
+ )
2583
+ end
2584
+
2585
+ it "should normalize to something sane" do
2586
+ @uri.normalize.to_s.should ==
2587
+ "http://www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3f" +
2588
+ "g11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp/"
2589
+ @uri.normalize!.to_s.should ==
2590
+ "http://www.xn--n8jaaaaai5bhf7as8fsfk3jnknefdde3f" +
2591
+ "g11amb5gzdb4wi9bya3kc6lra.w3.mag.keio.ac.jp/"
2592
+ end
2593
+ end
2594
+
2595
+ describe Addressable::URI, "with a base uri of 'http://a/b/c/d;p?q'" do
2596
+ before do
2597
+ @uri = Addressable::URI.parse("http://a/b/c/d;p?q")
2598
+ end
2599
+
2600
+ # Section 5.4.1 of RFC 3986
2601
+ it "when joined with 'g:h' should resolve to g:h" do
2602
+ (@uri + "g:h").to_s.should == "g:h"
2603
+ Addressable::URI.join(@uri, "g:h").to_s.should == "g:h"
2604
+ end
2605
+
2606
+ # Section 5.4.1 of RFC 3986
2607
+ it "when joined with 'g' should resolve to http://a/b/c/g" do
2608
+ (@uri + "g").to_s.should == "http://a/b/c/g"
2609
+ Addressable::URI.join(@uri.to_s, "g").to_s.should == "http://a/b/c/g"
2610
+ end
2611
+
2612
+ # Section 5.4.1 of RFC 3986
2613
+ it "when joined with './g' should resolve to http://a/b/c/g" do
2614
+ (@uri + "./g").to_s.should == "http://a/b/c/g"
2615
+ Addressable::URI.join(@uri.to_s, "./g").to_s.should == "http://a/b/c/g"
2616
+ end
2617
+
2618
+ # Section 5.4.1 of RFC 3986
2619
+ it "when joined with 'g/' should resolve to http://a/b/c/g/" do
2620
+ (@uri + "g/").to_s.should == "http://a/b/c/g/"
2621
+ Addressable::URI.join(@uri.to_s, "g/").to_s.should == "http://a/b/c/g/"
2622
+ end
2623
+
2624
+ # Section 5.4.1 of RFC 3986
2625
+ it "when joined with '/g' should resolve to http://a/g" do
2626
+ (@uri + "/g").to_s.should == "http://a/g"
2627
+ Addressable::URI.join(@uri.to_s, "/g").to_s.should == "http://a/g"
2628
+ end
2629
+
2630
+ # Section 5.4.1 of RFC 3986
2631
+ it "when joined with '//g' should resolve to http://g" do
2632
+ (@uri + "//g").to_s.should == "http://g"
2633
+ Addressable::URI.join(@uri.to_s, "//g").to_s.should == "http://g"
2634
+ end
2635
+
2636
+ # Section 5.4.1 of RFC 3986
2637
+ it "when joined with '?y' should resolve to http://a/b/c/d;p?y" do
2638
+ (@uri + "?y").to_s.should == "http://a/b/c/d;p?y"
2639
+ Addressable::URI.join(@uri.to_s, "?y").to_s.should == "http://a/b/c/d;p?y"
2640
+ end
2641
+
2642
+ # Section 5.4.1 of RFC 3986
2643
+ it "when joined with 'g?y' should resolve to http://a/b/c/g?y" do
2644
+ (@uri + "g?y").to_s.should == "http://a/b/c/g?y"
2645
+ Addressable::URI.join(@uri.to_s, "g?y").to_s.should == "http://a/b/c/g?y"
2646
+ end
2647
+
2648
+ # Section 5.4.1 of RFC 3986
2649
+ it "when joined with '#s' should resolve to http://a/b/c/d;p?q#s" do
2650
+ (@uri + "#s").to_s.should == "http://a/b/c/d;p?q#s"
2651
+ Addressable::URI.join(@uri.to_s, "#s").to_s.should == "http://a/b/c/d;p?q#s"
2652
+ end
2653
+
2654
+ # Section 5.4.1 of RFC 3986
2655
+ it "when joined with 'g#s' should resolve to http://a/b/c/g#s" do
2656
+ (@uri + "g#s").to_s.should == "http://a/b/c/g#s"
2657
+ Addressable::URI.join(@uri.to_s, "g#s").to_s.should == "http://a/b/c/g#s"
2658
+ end
2659
+
2660
+ # Section 5.4.1 of RFC 3986
2661
+ it "when joined with 'g?y#s' should resolve to http://a/b/c/g?y#s" do
2662
+ (@uri + "g?y#s").to_s.should == "http://a/b/c/g?y#s"
2663
+ Addressable::URI.join(
2664
+ @uri.to_s, "g?y#s").to_s.should == "http://a/b/c/g?y#s"
2665
+ end
2666
+
2667
+ # Section 5.4.1 of RFC 3986
2668
+ it "when joined with ';x' should resolve to http://a/b/c/;x" do
2669
+ (@uri + ";x").to_s.should == "http://a/b/c/;x"
2670
+ Addressable::URI.join(@uri.to_s, ";x").to_s.should == "http://a/b/c/;x"
2671
+ end
2672
+
2673
+ # Section 5.4.1 of RFC 3986
2674
+ it "when joined with 'g;x' should resolve to http://a/b/c/g;x" do
2675
+ (@uri + "g;x").to_s.should == "http://a/b/c/g;x"
2676
+ Addressable::URI.join(@uri.to_s, "g;x").to_s.should == "http://a/b/c/g;x"
2677
+ end
2678
+
2679
+ # Section 5.4.1 of RFC 3986
2680
+ it "when joined with 'g;x?y#s' should resolve to http://a/b/c/g;x?y#s" do
2681
+ (@uri + "g;x?y#s").to_s.should == "http://a/b/c/g;x?y#s"
2682
+ Addressable::URI.join(
2683
+ @uri.to_s, "g;x?y#s").to_s.should == "http://a/b/c/g;x?y#s"
2684
+ end
2685
+
2686
+ # Section 5.4.1 of RFC 3986
2687
+ it "when joined with '' should resolve to http://a/b/c/d;p?q" do
2688
+ (@uri + "").to_s.should == "http://a/b/c/d;p?q"
2689
+ Addressable::URI.join(@uri.to_s, "").to_s.should == "http://a/b/c/d;p?q"
2690
+ end
2691
+
2692
+ # Section 5.4.1 of RFC 3986
2693
+ it "when joined with '.' should resolve to http://a/b/c/" do
2694
+ (@uri + ".").to_s.should == "http://a/b/c/"
2695
+ Addressable::URI.join(@uri.to_s, ".").to_s.should == "http://a/b/c/"
2696
+ end
2697
+
2698
+ # Section 5.4.1 of RFC 3986
2699
+ it "when joined with './' should resolve to http://a/b/c/" do
2700
+ (@uri + "./").to_s.should == "http://a/b/c/"
2701
+ Addressable::URI.join(@uri.to_s, "./").to_s.should == "http://a/b/c/"
2702
+ end
2703
+
2704
+ # Section 5.4.1 of RFC 3986
2705
+ it "when joined with '..' should resolve to http://a/b/" do
2706
+ (@uri + "..").to_s.should == "http://a/b/"
2707
+ Addressable::URI.join(@uri.to_s, "..").to_s.should == "http://a/b/"
2708
+ end
2709
+
2710
+ # Section 5.4.1 of RFC 3986
2711
+ it "when joined with '../' should resolve to http://a/b/" do
2712
+ (@uri + "../").to_s.should == "http://a/b/"
2713
+ Addressable::URI.join(@uri.to_s, "../").to_s.should == "http://a/b/"
2714
+ end
2715
+
2716
+ # Section 5.4.1 of RFC 3986
2717
+ it "when joined with '../g' should resolve to http://a/b/g" do
2718
+ (@uri + "../g").to_s.should == "http://a/b/g"
2719
+ Addressable::URI.join(@uri.to_s, "../g").to_s.should == "http://a/b/g"
2720
+ end
2721
+
2722
+ # Section 5.4.1 of RFC 3986
2723
+ it "when joined with '../..' should resolve to http://a/" do
2724
+ (@uri + "../..").to_s.should == "http://a/"
2725
+ Addressable::URI.join(@uri.to_s, "../..").to_s.should == "http://a/"
2726
+ end
2727
+
2728
+ # Section 5.4.1 of RFC 3986
2729
+ it "when joined with '../../' should resolve to http://a/" do
2730
+ (@uri + "../../").to_s.should == "http://a/"
2731
+ Addressable::URI.join(@uri.to_s, "../../").to_s.should == "http://a/"
2732
+ end
2733
+
2734
+ # Section 5.4.1 of RFC 3986
2735
+ it "when joined with '../../g' should resolve to http://a/g" do
2736
+ (@uri + "../../g").to_s.should == "http://a/g"
2737
+ Addressable::URI.join(@uri.to_s, "../../g").to_s.should == "http://a/g"
2738
+ end
2739
+
2740
+ # Section 5.4.2 of RFC 3986
2741
+ it "when joined with '../../../g' should resolve to http://a/g" do
2742
+ (@uri + "../../../g").to_s.should == "http://a/g"
2743
+ Addressable::URI.join(@uri.to_s, "../../../g").to_s.should == "http://a/g"
2744
+ end
2745
+
2746
+ it "when joined with '../.././../g' should resolve to http://a/g" do
2747
+ (@uri + "../.././../g").to_s.should == "http://a/g"
2748
+ Addressable::URI.join(@uri.to_s, "../.././../g").to_s.should == "http://a/g"
2749
+ end
2750
+
2751
+ # Section 5.4.2 of RFC 3986
2752
+ it "when joined with '../../../../g' should resolve to http://a/g" do
2753
+ (@uri + "../../../../g").to_s.should == "http://a/g"
2754
+ Addressable::URI.join(
2755
+ @uri.to_s, "../../../../g").to_s.should == "http://a/g"
2756
+ end
2757
+
2758
+ # Section 5.4.2 of RFC 3986
2759
+ it "when joined with '/./g' should resolve to http://a/g" do
2760
+ (@uri + "/./g").to_s.should == "http://a/g"
2761
+ Addressable::URI.join(@uri.to_s, "/./g").to_s.should == "http://a/g"
2762
+ end
2763
+
2764
+ # Section 5.4.2 of RFC 3986
2765
+ it "when joined with '/../g' should resolve to http://a/g" do
2766
+ (@uri + "/../g").to_s.should == "http://a/g"
2767
+ Addressable::URI.join(@uri.to_s, "/../g").to_s.should == "http://a/g"
2768
+ end
2769
+
2770
+ # Section 5.4.2 of RFC 3986
2771
+ it "when joined with 'g.' should resolve to http://a/b/c/g." do
2772
+ (@uri + "g.").to_s.should == "http://a/b/c/g."
2773
+ Addressable::URI.join(@uri.to_s, "g.").to_s.should == "http://a/b/c/g."
2774
+ end
2775
+
2776
+ # Section 5.4.2 of RFC 3986
2777
+ it "when joined with '.g' should resolve to http://a/b/c/.g" do
2778
+ (@uri + ".g").to_s.should == "http://a/b/c/.g"
2779
+ Addressable::URI.join(@uri.to_s, ".g").to_s.should == "http://a/b/c/.g"
2780
+ end
2781
+
2782
+ # Section 5.4.2 of RFC 3986
2783
+ it "when joined with 'g..' should resolve to http://a/b/c/g.." do
2784
+ (@uri + "g..").to_s.should == "http://a/b/c/g.."
2785
+ Addressable::URI.join(@uri.to_s, "g..").to_s.should == "http://a/b/c/g.."
2786
+ end
2787
+
2788
+ # Section 5.4.2 of RFC 3986
2789
+ it "when joined with '..g' should resolve to http://a/b/c/..g" do
2790
+ (@uri + "..g").to_s.should == "http://a/b/c/..g"
2791
+ Addressable::URI.join(@uri.to_s, "..g").to_s.should == "http://a/b/c/..g"
2792
+ end
2793
+
2794
+ # Section 5.4.2 of RFC 3986
2795
+ it "when joined with './../g' should resolve to http://a/b/g" do
2796
+ (@uri + "./../g").to_s.should == "http://a/b/g"
2797
+ Addressable::URI.join(@uri.to_s, "./../g").to_s.should == "http://a/b/g"
2798
+ end
2799
+
2800
+ # Section 5.4.2 of RFC 3986
2801
+ it "when joined with './g/.' should resolve to http://a/b/c/g/" do
2802
+ (@uri + "./g/.").to_s.should == "http://a/b/c/g/"
2803
+ Addressable::URI.join(@uri.to_s, "./g/.").to_s.should == "http://a/b/c/g/"
2804
+ end
2805
+
2806
+ # Section 5.4.2 of RFC 3986
2807
+ it "when joined with 'g/./h' should resolve to http://a/b/c/g/h" do
2808
+ (@uri + "g/./h").to_s.should == "http://a/b/c/g/h"
2809
+ Addressable::URI.join(@uri.to_s, "g/./h").to_s.should == "http://a/b/c/g/h"
2810
+ end
2811
+
2812
+ # Section 5.4.2 of RFC 3986
2813
+ it "when joined with 'g/../h' should resolve to http://a/b/c/h" do
2814
+ (@uri + "g/../h").to_s.should == "http://a/b/c/h"
2815
+ Addressable::URI.join(@uri.to_s, "g/../h").to_s.should == "http://a/b/c/h"
2816
+ end
2817
+
2818
+ # Section 5.4.2 of RFC 3986
2819
+ it "when joined with 'g;x=1/./y' " +
2820
+ "should resolve to http://a/b/c/g;x=1/y" do
2821
+ (@uri + "g;x=1/./y").to_s.should == "http://a/b/c/g;x=1/y"
2822
+ Addressable::URI.join(
2823
+ @uri.to_s, "g;x=1/./y").to_s.should == "http://a/b/c/g;x=1/y"
2824
+ end
2825
+
2826
+ # Section 5.4.2 of RFC 3986
2827
+ it "when joined with 'g;x=1/../y' should resolve to http://a/b/c/y" do
2828
+ (@uri + "g;x=1/../y").to_s.should == "http://a/b/c/y"
2829
+ Addressable::URI.join(
2830
+ @uri.to_s, "g;x=1/../y").to_s.should == "http://a/b/c/y"
2831
+ end
2832
+
2833
+ # Section 5.4.2 of RFC 3986
2834
+ it "when joined with 'g?y/./x' " +
2835
+ "should resolve to http://a/b/c/g?y/./x" do
2836
+ (@uri + "g?y/./x").to_s.should == "http://a/b/c/g?y/./x"
2837
+ Addressable::URI.join(
2838
+ @uri.to_s, "g?y/./x").to_s.should == "http://a/b/c/g?y/./x"
2839
+ end
2840
+
2841
+ # Section 5.4.2 of RFC 3986
2842
+ it "when joined with 'g?y/../x' " +
2843
+ "should resolve to http://a/b/c/g?y/../x" do
2844
+ (@uri + "g?y/../x").to_s.should == "http://a/b/c/g?y/../x"
2845
+ Addressable::URI.join(
2846
+ @uri.to_s, "g?y/../x").to_s.should == "http://a/b/c/g?y/../x"
2847
+ end
2848
+
2849
+ # Section 5.4.2 of RFC 3986
2850
+ it "when joined with 'g#s/./x' " +
2851
+ "should resolve to http://a/b/c/g#s/./x" do
2852
+ (@uri + "g#s/./x").to_s.should == "http://a/b/c/g#s/./x"
2853
+ Addressable::URI.join(
2854
+ @uri.to_s, "g#s/./x").to_s.should == "http://a/b/c/g#s/./x"
2855
+ end
2856
+
2857
+ # Section 5.4.2 of RFC 3986
2858
+ it "when joined with 'g#s/../x' " +
2859
+ "should resolve to http://a/b/c/g#s/../x" do
2860
+ (@uri + "g#s/../x").to_s.should == "http://a/b/c/g#s/../x"
2861
+ Addressable::URI.join(
2862
+ @uri.to_s, "g#s/../x").to_s.should == "http://a/b/c/g#s/../x"
2863
+ end
2864
+
2865
+ # Section 5.4.2 of RFC 3986
2866
+ it "when joined with 'http:g' should resolve to http:g" do
2867
+ (@uri + "http:g").to_s.should == "http:g"
2868
+ Addressable::URI.join(@uri.to_s, "http:g").to_s.should == "http:g"
2869
+ end
2870
+
2871
+ # Edge case to be sure
2872
+ it "when joined with '//example.com/' should " +
2873
+ "resolve to http://example.com/" do
2874
+ (@uri + "//example.com/").to_s.should == "http://example.com/"
2875
+ Addressable::URI.join(
2876
+ @uri.to_s, "//example.com/").to_s.should == "http://example.com/"
2877
+ end
2878
+
2879
+ it "when joined with a bogus object a TypeError should be raised" do
2880
+ (lambda do
2881
+ Addressable::URI.join(@uri, 42)
2882
+ end).should raise_error(TypeError)
2883
+ end
2884
+ end
2885
+
2886
+ describe Addressable::URI, "when extracting from an arbitrary text" do
2887
+ before do
2888
+ @text = File.open(File.expand_path(
2889
+ File.dirname(__FILE__) + "/../data/rfc3986.txt")) { |file| file.read }
2890
+ end
2891
+
2892
+ it "should have all obvious URIs extractable from it" do
2893
+ @uris = Addressable::URI.extract(@text)
2894
+ @uris.should include("http://www.w3.org/People/Berners-Lee/")
2895
+ @uris.should include("http://roy.gbiv.com/")
2896
+ @uris.should include("http://larry.masinter.net/")
2897
+ @uris = Addressable::URI.extract(@text,
2898
+ :base => "http://example.com/", :parse => true)
2899
+ @uris.should include(
2900
+ Addressable::URI.parse("http://www.w3.org/People/Berners-Lee/"))
2901
+ @uris.should include(
2902
+ Addressable::URI.parse("http://roy.gbiv.com/"))
2903
+ @uris.should include(
2904
+ Addressable::URI.parse("http://larry.masinter.net/"))
2905
+ end
2906
+ end
2907
+
2908
+ describe Addressable::URI, "when extracting from an arbitrary text " +
2909
+ "containing invalid URIs" do
2910
+ before do
2911
+ @text = <<-TEXT
2912
+ This is an invalid URI:
2913
+ http://example.com:bogus/path/to/something/
2914
+ This is a valid URI:
2915
+ http://example.com:80/path/to/something/
2916
+ TEXT
2917
+ end
2918
+
2919
+ it "should ignore invalid URIs when extracting" do
2920
+ @uris = Addressable::URI.extract(@text)
2921
+ @uris.should include("http://example.com:80/path/to/something/")
2922
+ @uris.should_not include("http://example.com:bogus/path/to/something/")
2923
+ @uris.size.should == 1
2924
+ end
2925
+ end
2926
+
2927
+ describe Addressable::URI, "when converting the path " +
2928
+ "'relative/path/to/something'" do
2929
+ before do
2930
+ @path = 'relative/path/to/something'
2931
+ end
2932
+
2933
+ it "should convert to " +
2934
+ "\'relative/path/to/something\'" do
2935
+ @uri = Addressable::URI.convert_path(@path)
2936
+ @uri.to_s.should == "relative/path/to/something"
2937
+ end
2938
+
2939
+ it "should join with an absolute file path correctly" do
2940
+ @base = Addressable::URI.convert_path("/absolute/path/")
2941
+ @uri = Addressable::URI.convert_path(@path)
2942
+ (@base + @uri).to_s.should ==
2943
+ "file:///absolute/path/relative/path/to/something"
2944
+ end
2945
+ end
2946
+
2947
+ describe Addressable::URI, "when converting a bogus path" do
2948
+ it "should raise a TypeError" do
2949
+ (lambda do
2950
+ Addressable::URI.convert_path(42)
2951
+ end).should raise_error(TypeError)
2952
+ end
2953
+ end
2954
+
2955
+ describe Addressable::URI, "when given the root directory" do
2956
+ before do
2957
+ if RUBY_PLATFORM =~ /mswin/
2958
+ @path = "C:\\"
2959
+ else
2960
+ @path = "/"
2961
+ end
2962
+ end
2963
+
2964
+ if RUBY_PLATFORM =~ /mswin/
2965
+ it "should convert to \'file:///c:/\'" do
2966
+ @uri = Addressable::URI.convert_path(@path)
2967
+ @uri.to_s.should == "file:///c:/"
2968
+ end
2969
+ else
2970
+ it "should convert to \'file:///\'" do
2971
+ @uri = Addressable::URI.convert_path(@path)
2972
+ @uri.to_s.should == "file:///"
2973
+ end
2974
+ end
2975
+ end
2976
+
2977
+ describe Addressable::URI, "when given the path '/home/user/'" do
2978
+ before do
2979
+ @path = '/home/user/'
2980
+ end
2981
+
2982
+ it "should convert to " +
2983
+ "\'file:///home/user/\'" do
2984
+ @uri = Addressable::URI.convert_path(@path)
2985
+ @uri.to_s.should == "file:///home/user/"
2986
+ end
2987
+ end
2988
+
2989
+ describe Addressable::URI, " when given the path " +
2990
+ "'c:\\windows\\My Documents 100%20\\foo.txt'" do
2991
+ before do
2992
+ @path = "c:\\windows\\My Documents 100%20\\foo.txt"
2993
+ end
2994
+
2995
+ it "should convert to " +
2996
+ "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do
2997
+ @uri = Addressable::URI.convert_path(@path)
2998
+ @uri.to_s.should == "file:///c:/windows/My%20Documents%20100%20/foo.txt"
2999
+ end
3000
+ end
3001
+
3002
+ describe Addressable::URI, " when given the path " +
3003
+ "'file://c:\\windows\\My Documents 100%20\\foo.txt'" do
3004
+ before do
3005
+ @path = "file://c:\\windows\\My Documents 100%20\\foo.txt"
3006
+ end
3007
+
3008
+ it "should convert to " +
3009
+ "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do
3010
+ @uri = Addressable::URI.convert_path(@path)
3011
+ @uri.to_s.should == "file:///c:/windows/My%20Documents%20100%20/foo.txt"
3012
+ end
3013
+ end
3014
+
3015
+ describe Addressable::URI, " when given the path " +
3016
+ "'file:c:\\windows\\My Documents 100%20\\foo.txt'" do
3017
+ before do
3018
+ @path = "file:c:\\windows\\My Documents 100%20\\foo.txt"
3019
+ end
3020
+
3021
+ it "should convert to " +
3022
+ "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do
3023
+ @uri = Addressable::URI.convert_path(@path)
3024
+ @uri.to_s.should == "file:///c:/windows/My%20Documents%20100%20/foo.txt"
3025
+ end
3026
+ end
3027
+
3028
+ describe Addressable::URI, " when given the path " +
3029
+ "'file:/c:\\windows\\My Documents 100%20\\foo.txt'" do
3030
+ before do
3031
+ @path = "file:/c:\\windows\\My Documents 100%20\\foo.txt"
3032
+ end
3033
+
3034
+ it "should convert to " +
3035
+ "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do
3036
+ @uri = Addressable::URI.convert_path(@path)
3037
+ @uri.to_s.should == "file:///c:/windows/My%20Documents%20100%20/foo.txt"
3038
+ end
3039
+ end
3040
+
3041
+ describe Addressable::URI, " when given the path " +
3042
+ "'file:///c|/windows/My%20Documents%20100%20/foo.txt'" do
3043
+ before do
3044
+ @path = "file:///c|/windows/My%20Documents%20100%20/foo.txt"
3045
+ end
3046
+
3047
+ it "should convert to " +
3048
+ "\'file:///c:/windows/My%20Documents%20100%20/foo.txt\'" do
3049
+ @uri = Addressable::URI.convert_path(@path)
3050
+ @uri.to_s.should == "file:///c:/windows/My%20Documents%20100%20/foo.txt"
3051
+ end
3052
+ end
3053
+
3054
+ describe Addressable::URI, "when given an http protocol URI" do
3055
+ before do
3056
+ @path = "http://example.com/"
3057
+ end
3058
+
3059
+ it "should not do any conversion at all" do
3060
+ @uri = Addressable::URI.convert_path(@path)
3061
+ @uri.to_s.should == "http://example.com/"
3062
+ end
3063
+ end
3064
+
3065
+ describe Addressable::URI, " when given the template pattern " +
3066
+ "'http://example.com/search/{query}/' " +
3067
+ "to be processed with the ExampleProcessor" do
3068
+ before do
3069
+ @pattern = "http://example.com/search/{query}/"
3070
+ end
3071
+
3072
+ it "should expand to " +
3073
+ "'http://example.com/search/an+example+search+query/' " +
3074
+ "with a mapping of {\"query\" => \"an example search query\"} " do
3075
+ Addressable::URI.expand_template(
3076
+ "http://example.com/search/{query}/",
3077
+ {"query" => "an example search query"},
3078
+ ExampleProcessor).to_s.should ==
3079
+ "http://example.com/search/an+example+search+query/"
3080
+ end
3081
+
3082
+ it "should raise an error " +
3083
+ "with a mapping of {\"query\" => \"invalid!\"}" do
3084
+ (lambda do
3085
+ Addressable::URI.expand_template(
3086
+ "http://example.com/search/{query}/",
3087
+ {"query" => "invalid!"},
3088
+ ExampleProcessor).to_s
3089
+ end).should raise_error
3090
+ end
3091
+ end
3092
+
3093
+ # Section 3.3.1 of the URI Template draft v 01
3094
+ describe Addressable::URI, " when given the mapping supplied in " +
3095
+ "Section 3.3.1 of the URI Template draft v 01" do
3096
+ before do
3097
+ @mapping = {
3098
+ "a" => "fred",
3099
+ "b" => "barney",
3100
+ "c" => "cheeseburger",
3101
+ "d" => "one two three",
3102
+ "e" => "20% tricky",
3103
+ "f" => "",
3104
+ "20" => "this-is-spinal-tap",
3105
+ "scheme" => "https",
3106
+ "p" => "quote=to+be+or+not+to+be",
3107
+ "q" => "hullo#world"
3108
+ }
3109
+ end
3110
+
3111
+ it "should result in 'http://example.org/page1#fred' " +
3112
+ "when used to expand 'http://example.org/page1\#{a}'" do
3113
+ Addressable::URI.expand_template(
3114
+ "http://example.org/page1\#{a}",
3115
+ @mapping
3116
+ ).to_s.should == "http://example.org/page1#fred"
3117
+ end
3118
+
3119
+ it "should result in 'http://example.org/fred/barney/' " +
3120
+ "when used to expand 'http://example.org/{a}/{b}/'" do
3121
+ Addressable::URI.expand_template(
3122
+ "http://example.org/{a}/{b}/",
3123
+ @mapping
3124
+ ).to_s.should == "http://example.org/fred/barney/"
3125
+ end
3126
+
3127
+ it "should result in 'http://example.org/fredbarney/' " +
3128
+ "when used to expand 'http://example.org/{a}{b}/'" do
3129
+ Addressable::URI.expand_template(
3130
+ "http://example.org/{a}{b}/",
3131
+ @mapping
3132
+ ).to_s.should == "http://example.org/fredbarney/"
3133
+ end
3134
+
3135
+ it "should result in " +
3136
+ "'http://example.com/order/cheeseburger/cheeseburger/cheeseburger/' " +
3137
+ "when used to expand 'http://example.com/order/{c}/{c}/{c}/'" do
3138
+ Addressable::URI.expand_template(
3139
+ "http://example.com/order/{c}/{c}/{c}/",
3140
+ @mapping
3141
+ ).to_s.should ==
3142
+ "http://example.com/order/cheeseburger/cheeseburger/cheeseburger/"
3143
+ end
3144
+
3145
+ it "should result in 'http://example.org/one%20two%20three' " +
3146
+ "when used to expand 'http://example.org/{d}'" do
3147
+ Addressable::URI.expand_template(
3148
+ "http://example.org/{d}",
3149
+ @mapping
3150
+ ).to_s.should == "http://example.org/one%20two%20three"
3151
+ end
3152
+
3153
+ it "should result in 'http://example.org/20%25%20tricky' " +
3154
+ "when used to expand 'http://example.org/{e}'" do
3155
+ Addressable::URI.expand_template(
3156
+ "http://example.org/{e}",
3157
+ @mapping
3158
+ ).to_s.should == "http://example.org/20%25%20tricky"
3159
+ end
3160
+
3161
+ it "should result in 'http://example.com//' " +
3162
+ "when used to expand 'http://example.com/{f}/'" do
3163
+ Addressable::URI.expand_template(
3164
+ "http://example.com/{f}/",
3165
+ @mapping
3166
+ ).to_s.should == "http://example.com//"
3167
+ end
3168
+
3169
+ it "should result in " +
3170
+ "'https://this-is-spinal-tap.example.org?date=&option=fred' " +
3171
+ "when used to expand " +
3172
+ "'{scheme}://{20}.example.org?date={wilma}&option={a}'" do
3173
+ Addressable::URI.expand_template(
3174
+ "{scheme}://{20}.example.org?date={wilma}&option={a}",
3175
+ @mapping
3176
+ ).to_s.should ==
3177
+ "https://this-is-spinal-tap.example.org?date=&option=fred"
3178
+ end
3179
+
3180
+ # The v 01 draft conflicts with the v 03 draft here.
3181
+ # The Addressable implementation uses v 03.
3182
+ it "should result in " +
3183
+ "'http://example.org?quote%3Dto%2Bbe%2Bor%2Bnot%2Bto%2Bbe' " +
3184
+ "when used to expand 'http://example.org?{p}'" do
3185
+ Addressable::URI.expand_template(
3186
+ "http://example.org?{p}",
3187
+ @mapping
3188
+ ).to_s.should == "http://example.org?quote%3Dto%2Bbe%2Bor%2Bnot%2Bto%2Bbe"
3189
+ end
3190
+
3191
+ # The v 01 draft conflicts with the v 03 draft here.
3192
+ # The Addressable implementation uses v 03.
3193
+ it "should result in 'http://example.com/hullo%23world' " +
3194
+ "when used to expand 'http://example.com/{q}'" do
3195
+ Addressable::URI.expand_template(
3196
+ "http://example.com/{q}",
3197
+ @mapping
3198
+ ).to_s.should == "http://example.com/hullo%23world"
3199
+ end
3200
+ end
3201
+
3202
+ # Section 4.5 of the URI Template draft v 03
3203
+ describe Addressable::URI, " when given the mapping supplied in " +
3204
+ "Section 4.5 of the URI Template draft v 03" do
3205
+ before do
3206
+ @mapping = {
3207
+ "foo" => "ϓ",
3208
+ "bar" => "fred",
3209
+ "baz" => "10,20,30",
3210
+ "qux" => ["10","20","30"],
3211
+ "corge" => [],
3212
+ "grault" => "",
3213
+ "garply" => "a/b/c",
3214
+ "waldo" => "ben & jerrys",
3215
+ "fred" => ["fred", "", "wilma"],
3216
+ "plugh" => ["ẛ", "ṡ"],
3217
+ "1-a_b.c" => "200"
3218
+ }
3219
+ end
3220
+
3221
+ it "should result in 'http://example.org/?q=fred' " +
3222
+ "when used to expand 'http://example.org/?q={bar}'" do
3223
+ Addressable::URI.expand_template(
3224
+ "http://example.org/?q={bar}",
3225
+ @mapping
3226
+ ).to_s.should == "http://example.org/?q=fred"
3227
+ end
3228
+
3229
+ it "should result in '/' " +
3230
+ "when used to expand '/{xyzzy}'" do
3231
+ Addressable::URI.expand_template(
3232
+ "/{xyzzy}",
3233
+ @mapping
3234
+ ).to_s.should == "/"
3235
+ end
3236
+
3237
+ it "should result in " +
3238
+ "'http://example.org/?foo=%CE%8E&bar=fred&baz=10%2C20%2C30' " +
3239
+ "when used to expand " +
3240
+ "'http://example.org/?{-join|&|foo,bar,xyzzy,baz}'" do
3241
+ Addressable::URI.expand_template(
3242
+ "http://example.org/?{-join|&|foo,bar,xyzzy,baz}",
3243
+ @mapping
3244
+ ).to_s.should ==
3245
+ "http://example.org/?foo=%CE%8E&bar=fred&baz=10%2C20%2C30"
3246
+ end
3247
+
3248
+ it "should result in 'http://example.org/?d=10,20,30' " +
3249
+ "when used to expand 'http://example.org/?d={-list|,|qux}'" do
3250
+ Addressable::URI.expand_template(
3251
+ "http://example.org/?d={-list|,|qux}",
3252
+ @mapping
3253
+ ).to_s.should == "http://example.org/?d=10,20,30"
3254
+ end
3255
+
3256
+ it "should result in 'http://example.org/?d=10&d=20&d=30' " +
3257
+ "when used to expand 'http://example.org/?d={-list|&d=|qux}'" do
3258
+ Addressable::URI.expand_template(
3259
+ "http://example.org/?d={-list|&d=|qux}",
3260
+ @mapping
3261
+ ).to_s.should == "http://example.org/?d=10&d=20&d=30"
3262
+ end
3263
+
3264
+ it "should result in 'http://example.org/fredfred/a%2Fb%2Fc' " +
3265
+ "when used to expand 'http://example.org/{bar}{bar}/{garply}'" do
3266
+ Addressable::URI.expand_template(
3267
+ "http://example.org/{bar}{bar}/{garply}",
3268
+ @mapping
3269
+ ).to_s.should == "http://example.org/fredfred/a%2Fb%2Fc"
3270
+ end
3271
+
3272
+ it "should result in 'http://example.org/fred/fred//wilma' " +
3273
+ "when used to expand 'http://example.org/{bar}{-prefix|/|fred}'" do
3274
+ Addressable::URI.expand_template(
3275
+ "http://example.org/{bar}{-prefix|/|fred}",
3276
+ @mapping
3277
+ ).to_s.should == "http://example.org/fred/fred//wilma"
3278
+ end
3279
+
3280
+ it "should result in ':%E1%B9%A1:%E1%B9%A1:' " +
3281
+ "when used to expand '{-neg|:|corge}{-suffix|:|plugh}'" do
3282
+ Addressable::URI.expand_template(
3283
+ "{-neg|:|corge}{-suffix|:|plugh}",
3284
+ @mapping
3285
+ ).to_s.should == ":%E1%B9%A1:%E1%B9%A1:"
3286
+ end
3287
+
3288
+ it "should result in '../ben%20%26%20jerrys/' " +
3289
+ "when used to expand '../{waldo}/'" do
3290
+ Addressable::URI.expand_template(
3291
+ "../{waldo}/",
3292
+ @mapping
3293
+ ).to_s.should == "../ben%20%26%20jerrys/"
3294
+ end
3295
+
3296
+ it "should result in 'telnet:192.0.2.16:80' " +
3297
+ "when used to expand 'telnet:192.0.2.16{-opt|:80|grault}'" do
3298
+ Addressable::URI.expand_template(
3299
+ "telnet:192.0.2.16{-opt|:80|grault}",
3300
+ @mapping
3301
+ ).to_s.should == "telnet:192.0.2.16:80"
3302
+ end
3303
+
3304
+ it "should result in ':200:' " +
3305
+ "when used to expand ':{1-a_b.c}:'" do
3306
+ Addressable::URI.expand_template(
3307
+ ":{1-a_b.c}:",
3308
+ @mapping
3309
+ ).to_s.should == ":200:"
3310
+ end
3311
+ end
3312
+
3313
+ describe Addressable::URI, "when given a mapping that contains a " +
3314
+ "template-var within a value" do
3315
+ before do
3316
+ @mapping = {
3317
+ "a" => "{b}",
3318
+ "b" => "barney",
3319
+ }
3320
+ end
3321
+
3322
+ it "should result in 'http://example.com/%7Bb%7D/barney/' " +
3323
+ "when used to expand 'http://example.com/{a}/{b}/'" do
3324
+ Addressable::URI.expand_template(
3325
+ "http://example.com/{a}/{b}/",
3326
+ @mapping).to_s.should == "http://example.com/%7Bb%7D/barney/"
3327
+ end
3328
+
3329
+ it "should result in 'http://example.com//%7Bb%7D/' " +
3330
+ "when used to expand 'http://example.com/{-opt|foo|foo}/{a}/'" do
3331
+ Addressable::URI.expand_template(
3332
+ "http://example.com/{-opt|foo|foo}/{a}/",
3333
+ @mapping).to_s.should == "http://example.com//%7Bb%7D/"
3334
+ end
3335
+
3336
+ it "should result in 'http://example.com//%7Bb%7D/' " +
3337
+ "when used to expand 'http://example.com/{-neg|foo|b}/{a}/'" do
3338
+ Addressable::URI.expand_template(
3339
+ "http://example.com/{-neg|foo|b}/{a}/",
3340
+ @mapping).to_s.should == "http://example.com//%7Bb%7D/"
3341
+ end
3342
+
3343
+ it "should result in 'http://example.com//barney/%7Bb%7D/' " +
3344
+ "when used to expand 'http://example.com/{-prefix|/|b}/{a}/'" do
3345
+ Addressable::URI.expand_template(
3346
+ "http://example.com/{-prefix|/|b}/{a}/",
3347
+ @mapping).to_s.should == "http://example.com//barney/%7Bb%7D/"
3348
+ end
3349
+
3350
+ it "should result in 'http://example.com/barney//%7Bb%7D/' " +
3351
+ "when used to expand 'http://example.com/{-suffix|/|b}/{a}/'" do
3352
+ Addressable::URI.expand_template(
3353
+ "http://example.com/{-suffix|/|b}/{a}/",
3354
+ @mapping).to_s.should == "http://example.com/barney//%7Bb%7D/"
3355
+ end
3356
+
3357
+ it "should result in 'http://example.com/%7Bb%7D/?b=barney&c=42' " +
3358
+ "when used to expand 'http://example.com/{a}/?{-join|&|b,c=42}'" do
3359
+ Addressable::URI.expand_template(
3360
+ "http://example.com/{a}/?{-join|&|b,c=42}",
3361
+ @mapping).to_s.should == "http://example.com/%7Bb%7D/?b=barney&c=42"
3362
+ end
3363
+
3364
+ it "should result in 'http://example.com/42/?b=barney' " +
3365
+ "when used to expand 'http://example.com/{c=42}/?{-join|&|b}'" do
3366
+ Addressable::URI.expand_template(
3367
+ "http://example.com/{c=42}/?{-join|&|b}",
3368
+ @mapping).to_s.should == "http://example.com/42/?b=barney"
3369
+ end
3370
+ end
3371
+
3372
+ describe Addressable::URI, "when given a single variable mapping" do
3373
+ before do
3374
+ @mapping = {
3375
+ "foo" => "fred"
3376
+ }
3377
+ end
3378
+
3379
+ it "should result in 'fred' when used to expand '{foo}'" do
3380
+ Addressable::URI.expand_template(
3381
+ "{foo}",
3382
+ @mapping
3383
+ ).to_s.should == "fred"
3384
+ end
3385
+
3386
+ it "should result in 'wilma' when used to expand '{bar=wilma}'" do
3387
+ Addressable::URI.expand_template(
3388
+ "{bar=wilma}",
3389
+ @mapping
3390
+ ).to_s.should == "wilma"
3391
+ end
3392
+
3393
+ it "should result in '' when used to expand '{baz}'" do
3394
+ Addressable::URI.expand_template(
3395
+ "{baz}",
3396
+ @mapping
3397
+ ).to_s.should == ""
3398
+ end
3399
+ end
3400
+
3401
+ describe Addressable::URI, "when given a mapping containing values " +
3402
+ "that are already percent-encoded" do
3403
+ before do
3404
+ @mapping = {
3405
+ "a" => "%7Bb%7D"
3406
+ }
3407
+ end
3408
+
3409
+ it "should result in 'http://example.com/%257Bb%257D/' " +
3410
+ "when used to expand 'http://example.com/{a}/'" do
3411
+ Addressable::URI.expand_template(
3412
+ "http://example.com/{a}/",
3413
+ @mapping).to_s.should == "http://example.com/%257Bb%257D/"
3414
+ end
3415
+ end
3416
+
3417
+ describe Addressable::URI, "when given a mapping containing bogus values" do
3418
+ it "should raise a TypeError" do
3419
+ (lambda do
3420
+ Addressable::URI.expand_template(
3421
+ "http://example.com/{bogus}/", {
3422
+ "bogus" => 42
3423
+ }
3424
+ )
3425
+ end).should raise_error(TypeError)
3426
+ end
3427
+ end
3428
+
3429
+ describe Addressable::URI, "when given a pattern with bogus operators" do
3430
+ it "should raise an InvalidTemplateOperatorError" do
3431
+ (lambda do
3432
+ Addressable::URI.expand_template(
3433
+ "http://example.com/{-bogus|/|a,b,c}/", {
3434
+ "a" => "a", "b" => "b", "c" => "c"
3435
+ }
3436
+ )
3437
+ end).should raise_error(Addressable::URI::InvalidTemplateOperatorError)
3438
+ end
3439
+
3440
+ it "should raise an InvalidTemplateOperatorError" do
3441
+ (lambda do
3442
+ Addressable::URI.expand_template(
3443
+ "http://example.com/{-prefix|/|a,b,c}/", {
3444
+ "a" => "a", "b" => "b", "c" => "c"
3445
+ }
3446
+ )
3447
+ end).should raise_error(Addressable::URI::InvalidTemplateOperatorError)
3448
+ end
3449
+
3450
+ it "should raise an InvalidTemplateOperatorError" do
3451
+ (lambda do
3452
+ Addressable::URI.expand_template(
3453
+ "http://example.com/{-suffix|/|a,b,c}/", {
3454
+ "a" => "a", "b" => "b", "c" => "c"
3455
+ }
3456
+ )
3457
+ end).should raise_error(Addressable::URI::InvalidTemplateOperatorError)
3458
+ end
3459
+
3460
+ it "should raise an InvalidTemplateOperatorError" do
3461
+ (lambda do
3462
+ Addressable::URI.expand_template(
3463
+ "http://example.com/{-join|/|a,b,c}/", {
3464
+ "a" => ["a"], "b" => ["b"], "c" => "c"
3465
+ }
3466
+ )
3467
+ end).should raise_error(Addressable::URI::InvalidTemplateOperatorError)
3468
+ end
3469
+
3470
+ it "should raise an InvalidTemplateOperatorError" do
3471
+ (lambda do
3472
+ Addressable::URI.expand_template(
3473
+ "http://example.com/{-list|/|a,b,c}/", {
3474
+ "a" => ["a"], "b" => ["b"], "c" => "c"
3475
+ }
3476
+ )
3477
+ end).should raise_error(Addressable::URI::InvalidTemplateOperatorError)
3478
+ end
3479
+ end
3480
+
3481
+ describe Addressable::URI, "when given a mapping that contains an Array" do
3482
+ before do
3483
+ @mapping = {"query" => "an example search query".split(" ")}
3484
+ end
3485
+
3486
+ it "should result in 'http://example.com/search/an+example+search+query/'" +
3487
+ " when used to expand 'http://example.com/search/{-list|+|query}/'" do
3488
+ Addressable::URI.expand_template(
3489
+ "http://example.com/search/{-list|+|query}/",
3490
+ @mapping).to_s.should ==
3491
+ "http://example.com/search/an+example+search+query/"
3492
+ end
3493
+ end
3494
+
3495
+ class SuperString
3496
+ def initialize(string)
3497
+ @string = string.to_s
3498
+ end
3499
+
3500
+ def to_str
3501
+ return @string
3502
+ end
3503
+ end
3504
+
3505
+ describe Addressable::URI, " when parsing a non-String object" do
3506
+ it "should correctly parse anything with a 'to_str' method" do
3507
+ Addressable::URI.parse(SuperString.new(42))
3508
+ end
3509
+
3510
+ it "should raise a TypeError for objects than cannot be converted" do
3511
+ (lambda do
3512
+ Addressable::URI.parse(42)
3513
+ end).should raise_error(TypeError)
3514
+ end
3515
+
3516
+ it "should correctly parse heuristically anything with a 'to_str' method" do
3517
+ Addressable::URI.heuristic_parse(SuperString.new(42))
3518
+ end
3519
+
3520
+ it "should raise a TypeError for objects than cannot be converted" do
3521
+ (lambda do
3522
+ Addressable::URI.heuristic_parse(42)
3523
+ end).should raise_error(TypeError)
3524
+ end
3525
+ end
3526
+
3527
+ describe Addressable::URI, "when encoding a multibyte string" do
3528
+ it "should result in correct percent encoded sequence" do
3529
+ Addressable::URI.encode_component("günther").should == "g%C3%BCnther"
3530
+ end
3531
+
3532
+ it "should result in correct percent encoded sequence" do
3533
+ Addressable::URI.encode_component(
3534
+ "günther", /[^a-zA-Z0-9\:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\-\.\_\~]/
3535
+ ).should == "g%C3%BCnther"
3536
+ end
3537
+ end
3538
+
3539
+ describe Addressable::URI, "when unencoding a multibyte string" do
3540
+ it "should result in correct percent encoded sequence" do
3541
+ Addressable::URI.unencode_component("g%C3%BCnther").should == "günther"
3542
+ end
3543
+
3544
+ it "should result in correct percent encoded sequence as a URI" do
3545
+ Addressable::URI.unencode(
3546
+ "/path?g%C3%BCnther", ::Addressable::URI
3547
+ ).should == Addressable::URI.new(
3548
+ :path => "/path", :query => "günther"
3549
+ )
3550
+ end
3551
+ end
3552
+
3553
+ describe Addressable::URI, "when unencoding a bogus object" do
3554
+ it "should raise a TypeError" do
3555
+ (lambda do
3556
+ Addressable::URI.unencode_component(42)
3557
+ end).should raise_error(TypeError)
3558
+ end
3559
+
3560
+ it "should raise a TypeError" do
3561
+ (lambda do
3562
+ Addressable::URI.unencode("/path?g%C3%BCnther", Integer)
3563
+ end).should raise_error(TypeError)
3564
+ end
3565
+ end
3566
+
3567
+ describe Addressable::URI, "when encoding a bogus object" do
3568
+ it "should raise a TypeError" do
3569
+ (lambda do
3570
+ Addressable::URI.encode(42)
3571
+ end).should raise_error(TypeError)
3572
+ end
3573
+
3574
+ it "should raise a TypeError" do
3575
+ (lambda do
3576
+ Addressable::URI.normalized_encode(42)
3577
+ end).should raise_error(TypeError)
3578
+ end
3579
+
3580
+ it "should raise a TypeError" do
3581
+ (lambda do
3582
+ Addressable::URI.encode_component("günther", 42)
3583
+ end).should raise_error(TypeError)
3584
+ end
3585
+
3586
+ it "should raise a TypeError" do
3587
+ (lambda do
3588
+ Addressable::URI.encode_component(42)
3589
+ end).should raise_error(TypeError)
3590
+ end
3591
+ end
3592
+
3593
+ describe Addressable::URI, " when parsed from " +
3594
+ "'/'" do
3595
+ before do
3596
+ @uri = Addressable::URI.parse("/")
3597
+ end
3598
+
3599
+ it "should have the correct mapping when extracting values " +
3600
+ "using the pattern '/'" do
3601
+ @uri.extract_mapping("/").should == {}
3602
+ end
3603
+ end
3604
+
3605
+ describe Addressable::URI, " when parsed from '/one/'" do
3606
+ before do
3607
+ @uri = Addressable::URI.parse("/one/")
3608
+ end
3609
+
3610
+ it "should not match the pattern '/two/'" do
3611
+ @uri.extract_mapping("/two/").should == nil
3612
+ end
3613
+
3614
+ it "should have the correct mapping when extracting values " +
3615
+ "using the pattern '/{number}/'" do
3616
+ @uri.extract_mapping("/{number}/").should == {"number" => "one"}
3617
+ end
3618
+ end
3619
+
3620
+ describe Addressable::URI, " when parsed from '/one/two/'" do
3621
+ before do
3622
+ @uri = Addressable::URI.parse("/one/two/")
3623
+ end
3624
+
3625
+ it "should not match the pattern '/{number}/' " +
3626
+ "with the SlashlessProcessor" do
3627
+ @uri.extract_mapping("/{number}/", SlashlessProcessor).should == nil
3628
+ end
3629
+
3630
+ it "should have the correct mapping when extracting values " +
3631
+ "using the pattern '/{number}/' without a processor" do
3632
+ @uri.extract_mapping("/{number}/").should == {
3633
+ "number" => "one/two"
3634
+ }
3635
+ end
3636
+
3637
+ it "should have the correct mapping when extracting values " +
3638
+ "using the pattern '/{first}/{second}/' with the SlashlessProcessor" do
3639
+ @uri.extract_mapping("/{first}/{second}/", SlashlessProcessor).should == {
3640
+ "first" => "one",
3641
+ "second" => "two"
3642
+ }
3643
+ end
3644
+ end
3645
+
3646
+ describe Addressable::URI, " when parsed from " +
3647
+ "'http://example.com/search/an+example+search+query/'" do
3648
+ before do
3649
+ @uri = Addressable::URI.parse(
3650
+ "http://example.com/search/an+example+search+query/")
3651
+ end
3652
+
3653
+ it "should have the correct mapping when extracting values using " +
3654
+ "the pattern 'http://example.com/search/{query}/' with the " +
3655
+ "ExampleProcessor" do
3656
+ @uri.extract_mapping(
3657
+ "http://example.com/search/{query}/", ExampleProcessor
3658
+ ).should == {
3659
+ "query" => "an example search query"
3660
+ }
3661
+ end
3662
+
3663
+ it "should return nil when extracting values using " +
3664
+ "a non-matching pattern" do
3665
+ @uri.extract_mapping(
3666
+ "http://bogus.com/{thingy}/"
3667
+ ).should == nil
3668
+ end
3669
+ end
3670
+
3671
+ describe Addressable::URI, " when parsed from " +
3672
+ "'http://example.com/a/b/c/'" do
3673
+ before do
3674
+ @uri = Addressable::URI.parse(
3675
+ "http://example.com/a/b/c/")
3676
+ end
3677
+
3678
+ it "should have the correct mapping when extracting values " +
3679
+ "using the pattern " +
3680
+ "'http://example.com/{first}/{second}/' with the ExampleProcessor" do
3681
+ @uri.extract_mapping(
3682
+ "http://example.com/{first}/{second}/", ExampleProcessor
3683
+ ).should == {
3684
+ "first" => "a",
3685
+ "second" => "b/c"
3686
+ }
3687
+ end
3688
+ end
3689
+
3690
+ describe Addressable::URI, " when parsed from " +
3691
+ "'http://example.com/one/spacer/two/'" do
3692
+ before do
3693
+ @uri = Addressable::URI.parse("http://example.com/one/spacer/two/")
3694
+ end
3695
+
3696
+ it "should have the correct mapping when extracting values " +
3697
+ "using the pattern " +
3698
+ "'http://example.com/{first}/spacer/{second}/'" do
3699
+ @uri.extract_mapping(
3700
+ "http://example.com/{first}/spacer/{second}/").should == {
3701
+ "first" => "one",
3702
+ "second" => "two"
3703
+ }
3704
+ end
3705
+ end
3706
+
3707
+ describe Addressable::URI, " when given the input " +
3708
+ "'/path/to/resource'" do
3709
+ before do
3710
+ @input = "/path/to/resource"
3711
+ end
3712
+
3713
+ it "should heuristically parse to '/path/to/resource'" do
3714
+ @uri = Addressable::URI.heuristic_parse(@input)
3715
+ @uri.to_s.should == "/path/to/resource"
3716
+ end
3717
+ end
3718
+
3719
+ describe Addressable::URI, " when given the input " +
3720
+ "'relative/path/to/resource'" do
3721
+ before do
3722
+ @input = "relative/path/to/resource"
3723
+ end
3724
+
3725
+ it "should heuristically parse to 'relative/path/to/resource'" do
3726
+ @uri = Addressable::URI.heuristic_parse(@input)
3727
+ @uri.to_s.should == "relative/path/to/resource"
3728
+ end
3729
+ end
3730
+
3731
+ describe Addressable::URI, " when given the input " +
3732
+ "'example.com'" do
3733
+ before do
3734
+ @input = "example.com"
3735
+ end
3736
+
3737
+ it "should heuristically parse to 'http://example.com'" do
3738
+ @uri = Addressable::URI.heuristic_parse(@input)
3739
+ @uri.to_s.should == "http://example.com"
3740
+ end
3741
+ end
3742
+
3743
+ describe Addressable::URI, " when given the input " +
3744
+ "'example.com' and a scheme hint of 'ftp'" do
3745
+ before do
3746
+ @input = "example.com"
3747
+ @hints = {:scheme => 'ftp'}
3748
+ end
3749
+
3750
+ it "should heuristically parse to 'http://example.com'" do
3751
+ @uri = Addressable::URI.heuristic_parse(@input, @hints)
3752
+ @uri.to_s.should == "ftp://example.com"
3753
+ end
3754
+ end
3755
+
3756
+ describe Addressable::URI, " when given the input " +
3757
+ "'example.com:21' and a scheme hint of 'ftp'" do
3758
+ before do
3759
+ @input = "example.com:21"
3760
+ @hints = {:scheme => 'ftp'}
3761
+ end
3762
+
3763
+ it "should heuristically parse to 'http://example.com:21'" do
3764
+ @uri = Addressable::URI.heuristic_parse(@input, @hints)
3765
+ @uri.to_s.should == "ftp://example.com:21"
3766
+ end
3767
+ end
3768
+
3769
+ describe Addressable::URI, " when given the input " +
3770
+ "'example.com/path/to/resource'" do
3771
+ before do
3772
+ @input = "example.com/path/to/resource"
3773
+ end
3774
+
3775
+ it "should heuristically parse to 'http://example.com/path/to/resource'" do
3776
+ @uri = Addressable::URI.heuristic_parse(@input)
3777
+ @uri.to_s.should == "http://example.com/path/to/resource"
3778
+ end
3779
+ end
3780
+
3781
+ describe Addressable::URI, " when given the input " +
3782
+ "'http:///example.com'" do
3783
+ before do
3784
+ @input = "http:///example.com"
3785
+ end
3786
+
3787
+ it "should heuristically parse to 'http://example.com'" do
3788
+ @uri = Addressable::URI.heuristic_parse(@input)
3789
+ @uri.to_s.should == "http://example.com"
3790
+ end
3791
+ end
3792
+
3793
+ describe Addressable::URI, " when given the input " +
3794
+ "'feed:///example.com'" do
3795
+ before do
3796
+ @input = "feed:///example.com"
3797
+ end
3798
+
3799
+ it "should heuristically parse to 'feed://example.com'" do
3800
+ @uri = Addressable::URI.heuristic_parse(@input)
3801
+ @uri.to_s.should == "feed://example.com"
3802
+ end
3803
+ end
3804
+
3805
+ describe Addressable::URI, " when given the input " +
3806
+ "'file://path/to/resource/'" do
3807
+ before do
3808
+ @input = "file://path/to/resource/"
3809
+ end
3810
+
3811
+ it "should heuristically parse to 'file:///path/to/resource/'" do
3812
+ @uri = Addressable::URI.heuristic_parse(@input)
3813
+ @uri.to_s.should == "file:///path/to/resource/"
3814
+ end
3815
+ end
3816
+
3817
+ describe Addressable::URI, " when given the input " +
3818
+ "'feed://http://example.com'" do
3819
+ before do
3820
+ @input = "feed://http://example.com"
3821
+ end
3822
+
3823
+ it "should heuristically parse to 'feed:http://example.com'" do
3824
+ @uri = Addressable::URI.heuristic_parse(@input)
3825
+ @uri.to_s.should == "feed:http://example.com"
3826
+ end
3827
+ end