addressable 2.5.0 → 2.8.8

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.
@@ -1,4 +1,5 @@
1
- # coding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  # Copyright (C) Bob Aman
3
4
  #
4
5
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,6 +20,7 @@ require "spec_helper"
19
20
  require "addressable/uri"
20
21
  require "uri"
21
22
  require "ipaddr"
23
+ require "yaml"
22
24
 
23
25
  if !"".respond_to?("force_encoding")
24
26
  class String
@@ -63,124 +65,116 @@ end
63
65
 
64
66
  describe Addressable::URI, "when created with a non-numeric port number" do
65
67
  it "should raise an error" do
66
- expect(lambda do
68
+ expect do
67
69
  Addressable::URI.new(:port => "bogus")
68
- end).to raise_error(Addressable::URI::InvalidURIError)
70
+ end.to raise_error(Addressable::URI::InvalidURIError)
69
71
  end
70
72
  end
71
73
 
72
74
  describe Addressable::URI, "when created with a invalid encoded port number" do
73
75
  it "should raise an error" do
74
- expect(lambda do
76
+ expect do
75
77
  Addressable::URI.new(:port => "%eb")
76
- end).to raise_error(Addressable::URI::InvalidURIError)
78
+ end.to raise_error(Addressable::URI::InvalidURIError)
77
79
  end
78
80
  end
79
81
 
80
82
  describe Addressable::URI, "when created with a non-string scheme" do
81
83
  it "should raise an error" do
82
- expect(lambda do
84
+ expect do
83
85
  Addressable::URI.new(:scheme => :bogus)
84
- end).to raise_error(TypeError)
86
+ end.to raise_error(TypeError)
85
87
  end
86
88
  end
87
89
 
88
90
  describe Addressable::URI, "when created with a non-string user" do
89
91
  it "should raise an error" do
90
- expect(lambda do
92
+ expect do
91
93
  Addressable::URI.new(:user => :bogus)
92
- end).to raise_error(TypeError)
94
+ end.to raise_error(TypeError)
93
95
  end
94
96
  end
95
97
 
96
98
  describe Addressable::URI, "when created with a non-string password" do
97
99
  it "should raise an error" do
98
- expect(lambda do
100
+ expect do
99
101
  Addressable::URI.new(:password => :bogus)
100
- end).to raise_error(TypeError)
102
+ end.to raise_error(TypeError)
101
103
  end
102
104
  end
103
105
 
104
106
  describe Addressable::URI, "when created with a non-string userinfo" do
105
107
  it "should raise an error" do
106
- expect(lambda do
108
+ expect do
107
109
  Addressable::URI.new(:userinfo => :bogus)
108
- end).to raise_error(TypeError)
110
+ end.to raise_error(TypeError)
109
111
  end
110
112
  end
111
113
 
112
114
  describe Addressable::URI, "when created with a non-string host" do
113
115
  it "should raise an error" do
114
- expect(lambda do
116
+ expect do
115
117
  Addressable::URI.new(:host => :bogus)
116
- end).to raise_error(TypeError)
117
- end
118
- end
119
-
120
- describe Addressable::URI, "when created with a non-string authority" do
121
- it "should raise an error" do
122
- expect(lambda do
123
- Addressable::URI.new(:authority => :bogus)
124
- end).to raise_error(TypeError)
118
+ end.to raise_error(TypeError)
125
119
  end
126
120
  end
127
121
 
128
122
  describe Addressable::URI, "when created with a non-string authority" do
129
123
  it "should raise an error" do
130
- expect(lambda do
124
+ expect do
131
125
  Addressable::URI.new(:authority => :bogus)
132
- end).to raise_error(TypeError)
126
+ end.to raise_error(TypeError)
133
127
  end
134
128
  end
135
129
 
136
130
  describe Addressable::URI, "when created with a non-string path" do
137
131
  it "should raise an error" do
138
- expect(lambda do
132
+ expect do
139
133
  Addressable::URI.new(:path => :bogus)
140
- end).to raise_error(TypeError)
134
+ end.to raise_error(TypeError)
141
135
  end
142
136
  end
143
137
 
144
138
  describe Addressable::URI, "when created with a non-string query" do
145
139
  it "should raise an error" do
146
- expect(lambda do
140
+ expect do
147
141
  Addressable::URI.new(:query => :bogus)
148
- end).to raise_error(TypeError)
142
+ end.to raise_error(TypeError)
149
143
  end
150
144
  end
151
145
 
152
146
  describe Addressable::URI, "when created with a non-string fragment" do
153
147
  it "should raise an error" do
154
- expect(lambda do
148
+ expect do
155
149
  Addressable::URI.new(:fragment => :bogus)
156
- end).to raise_error(TypeError)
150
+ end.to raise_error(TypeError)
157
151
  end
158
152
  end
159
153
 
160
154
  describe Addressable::URI, "when created with a scheme but no hierarchical " +
161
155
  "segment" do
162
156
  it "should raise an error" do
163
- expect(lambda do
157
+ expect do
164
158
  Addressable::URI.parse("http:")
165
- end).to raise_error(Addressable::URI::InvalidURIError)
159
+ end.to raise_error(Addressable::URI::InvalidURIError)
166
160
  end
167
161
  end
168
162
 
169
163
  describe Addressable::URI, "quote handling" do
170
164
  describe 'in host name' do
171
165
  it "should raise an error for single quote" do
172
- expect(lambda do
166
+ expect do
173
167
  Addressable::URI.parse("http://local\"host/")
174
- end).to raise_error(Addressable::URI::InvalidURIError)
168
+ end.to raise_error(Addressable::URI::InvalidURIError)
175
169
  end
176
170
  end
177
171
  end
178
172
 
179
173
  describe Addressable::URI, "newline normalization" do
180
174
  it "should not accept newlines in scheme" do
181
- expect(lambda do
175
+ expect do
182
176
  Addressable::URI.parse("ht%0atp://localhost/")
183
- end).to raise_error(Addressable::URI::InvalidURIError)
177
+ end.to raise_error(Addressable::URI::InvalidURIError)
184
178
  end
185
179
 
186
180
  it "should not unescape newline in path" do
@@ -205,47 +199,47 @@ describe Addressable::URI, "newline normalization" do
205
199
 
206
200
  it "should not accept newline in hostname" do
207
201
  uri = Addressable::URI.parse("http://localhost/")
208
- expect(lambda do
202
+ expect do
209
203
  uri.host = "local\nhost"
210
- end).to raise_error(Addressable::URI::InvalidURIError)
204
+ end.to raise_error(Addressable::URI::InvalidURIError)
211
205
  end
212
206
  end
213
207
 
214
208
  describe Addressable::URI, "when created with ambiguous path" do
215
209
  it "should raise an error" do
216
- expect(lambda do
210
+ expect do
217
211
  Addressable::URI.parse("::http")
218
- end).to raise_error(Addressable::URI::InvalidURIError)
212
+ end.to raise_error(Addressable::URI::InvalidURIError)
219
213
  end
220
214
  end
221
215
 
222
216
  describe Addressable::URI, "when created with an invalid host" do
223
217
  it "should raise an error" do
224
- expect(lambda do
218
+ expect do
225
219
  Addressable::URI.new(:host => "<invalid>")
226
- end).to raise_error(Addressable::URI::InvalidURIError)
220
+ end.to raise_error(Addressable::URI::InvalidURIError)
227
221
  end
228
222
  end
229
223
 
230
224
  describe Addressable::URI, "when created with a host consisting of " +
231
225
  "sub-delims characters" do
232
226
  it "should not raise an error" do
233
- expect(lambda do
227
+ expect do
234
228
  Addressable::URI.new(
235
229
  :host => Addressable::URI::CharacterClasses::SUB_DELIMS.gsub(/\\/, '')
236
230
  )
237
- end).not_to raise_error
231
+ end.not_to raise_error
238
232
  end
239
233
  end
240
234
 
241
235
  describe Addressable::URI, "when created with a host consisting of " +
242
236
  "unreserved characters" do
243
237
  it "should not raise an error" do
244
- expect(lambda do
238
+ expect do
245
239
  Addressable::URI.new(
246
240
  :host => Addressable::URI::CharacterClasses::UNRESERVED.gsub(/\\/, '')
247
241
  )
248
- end).not_to raise_error
242
+ end.not_to raise_error
249
243
  end
250
244
  end
251
245
 
@@ -275,83 +269,83 @@ describe Addressable::URI, "when created from nil components" do
275
269
  end
276
270
 
277
271
  it "should raise an error if the scheme is set to whitespace" do
278
- expect(lambda do
272
+ expect do
279
273
  @uri.scheme = "\t \n"
280
- end).to raise_error(Addressable::URI::InvalidURIError)
274
+ end.to raise_error(Addressable::URI::InvalidURIError, /'\t \n'/)
281
275
  end
282
276
 
283
277
  it "should raise an error if the scheme is set to all digits" do
284
- expect(lambda do
278
+ expect do
285
279
  @uri.scheme = "123"
286
- end).to raise_error(Addressable::URI::InvalidURIError)
280
+ end.to raise_error(Addressable::URI::InvalidURIError, /'123'/)
287
281
  end
288
282
 
289
283
  it "should raise an error if the scheme begins with a digit" do
290
- expect(lambda do
284
+ expect do
291
285
  @uri.scheme = "1scheme"
292
- end).to raise_error(Addressable::URI::InvalidURIError)
286
+ end.to raise_error(Addressable::URI::InvalidURIError, /'1scheme'/)
293
287
  end
294
288
 
295
289
  it "should raise an error if the scheme begins with a plus" do
296
- expect(lambda do
290
+ expect do
297
291
  @uri.scheme = "+scheme"
298
- end).to raise_error(Addressable::URI::InvalidURIError)
292
+ end.to raise_error(Addressable::URI::InvalidURIError, /'\+scheme'/)
299
293
  end
300
294
 
301
295
  it "should raise an error if the scheme begins with a dot" do
302
- expect(lambda do
296
+ expect do
303
297
  @uri.scheme = ".scheme"
304
- end).to raise_error(Addressable::URI::InvalidURIError)
298
+ end.to raise_error(Addressable::URI::InvalidURIError, /'\.scheme'/)
305
299
  end
306
300
 
307
301
  it "should raise an error if the scheme begins with a dash" do
308
- expect(lambda do
302
+ expect do
309
303
  @uri.scheme = "-scheme"
310
- end).to raise_error(Addressable::URI::InvalidURIError)
304
+ end.to raise_error(Addressable::URI::InvalidURIError, /'-scheme'/)
311
305
  end
312
306
 
313
307
  it "should raise an error if the scheme contains an illegal character" do
314
- expect(lambda do
308
+ expect do
315
309
  @uri.scheme = "scheme!"
316
- end).to raise_error(Addressable::URI::InvalidURIError)
310
+ end.to raise_error(Addressable::URI::InvalidURIError, /'scheme!'/)
317
311
  end
318
312
 
319
313
  it "should raise an error if the scheme contains whitespace" do
320
- expect(lambda do
314
+ expect do
321
315
  @uri.scheme = "sch eme"
322
- end).to raise_error(Addressable::URI::InvalidURIError)
316
+ end.to raise_error(Addressable::URI::InvalidURIError, /'sch eme'/)
323
317
  end
324
318
 
325
319
  it "should raise an error if the scheme contains a newline" do
326
- expect(lambda do
320
+ expect do
327
321
  @uri.scheme = "sch\neme"
328
- end).to raise_error(Addressable::URI::InvalidURIError)
322
+ end.to raise_error(Addressable::URI::InvalidURIError)
329
323
  end
330
324
 
331
325
  it "should raise an error if set into an invalid state" do
332
- expect(lambda do
326
+ expect do
333
327
  @uri.user = "user"
334
- end).to raise_error(Addressable::URI::InvalidURIError)
328
+ end.to raise_error(Addressable::URI::InvalidURIError)
335
329
  end
336
330
 
337
331
  it "should raise an error if set into an invalid state" do
338
- expect(lambda do
332
+ expect do
339
333
  @uri.password = "pass"
340
- end).to raise_error(Addressable::URI::InvalidURIError)
334
+ end.to raise_error(Addressable::URI::InvalidURIError)
341
335
  end
342
336
 
343
337
  it "should raise an error if set into an invalid state" do
344
- expect(lambda do
338
+ expect do
345
339
  @uri.scheme = "http"
346
340
  @uri.fragment = "fragment"
347
- end).to raise_error(Addressable::URI::InvalidURIError)
341
+ end.to raise_error(Addressable::URI::InvalidURIError)
348
342
  end
349
343
 
350
344
  it "should raise an error if set into an invalid state" do
351
- expect(lambda do
345
+ expect do
352
346
  @uri.fragment = "fragment"
353
347
  @uri.scheme = "http"
354
- end).to raise_error(Addressable::URI::InvalidURIError)
348
+ end.to raise_error(Addressable::URI::InvalidURIError)
355
349
  end
356
350
  end
357
351
 
@@ -963,6 +957,10 @@ describe Addressable::URI, "when frozen" do
963
957
  expect(@uri.normalize.query).to eq("a=1")
964
958
  end
965
959
 
960
+ it "returns '/%70a%74%68?a=%31' for #request_uri" do
961
+ expect(@uri.request_uri).to eq("/%70a%74%68?a=%31")
962
+ end
963
+
966
964
  it "returns '1%323' for #fragment" do
967
965
  expect(@uri.fragment).to eq("1%323")
968
966
  end
@@ -1001,6 +999,72 @@ describe Addressable::URI, "when frozen" do
1001
999
  end
1002
1000
  end
1003
1001
 
1002
+ describe Addressable::URI, "when normalized and then deeply frozen" do
1003
+ before do
1004
+ @uri = Addressable::URI.parse(
1005
+ "http://user:password@example.com:8080/path?query=value#fragment"
1006
+ ).normalize!
1007
+
1008
+ @uri.instance_variables.each do |var|
1009
+ @uri.instance_variable_set(var, @uri.instance_variable_get(var).freeze)
1010
+ end
1011
+
1012
+ @uri.freeze
1013
+ end
1014
+
1015
+ it "#normalized_scheme should not error" do
1016
+ expect { @uri.normalized_scheme }.not_to raise_error
1017
+ end
1018
+
1019
+ it "#normalized_user should not error" do
1020
+ expect { @uri.normalized_user }.not_to raise_error
1021
+ end
1022
+
1023
+ it "#normalized_password should not error" do
1024
+ expect { @uri.normalized_password }.not_to raise_error
1025
+ end
1026
+
1027
+ it "#normalized_userinfo should not error" do
1028
+ expect { @uri.normalized_userinfo }.not_to raise_error
1029
+ end
1030
+
1031
+ it "#normalized_host should not error" do
1032
+ expect { @uri.normalized_host }.not_to raise_error
1033
+ end
1034
+
1035
+ it "#normalized_authority should not error" do
1036
+ expect { @uri.normalized_authority }.not_to raise_error
1037
+ end
1038
+
1039
+ it "#normalized_port should not error" do
1040
+ expect { @uri.normalized_port }.not_to raise_error
1041
+ end
1042
+
1043
+ it "#normalized_site should not error" do
1044
+ expect { @uri.normalized_site }.not_to raise_error
1045
+ end
1046
+
1047
+ it "#normalized_path should not error" do
1048
+ expect { @uri.normalized_path }.not_to raise_error
1049
+ end
1050
+
1051
+ it "#normalized_query should not error" do
1052
+ expect { @uri.normalized_query }.not_to raise_error
1053
+ end
1054
+
1055
+ it "#normalized_fragment should not error" do
1056
+ expect { @uri.normalized_fragment }.not_to raise_error
1057
+ end
1058
+
1059
+ it "should be frozen" do
1060
+ expect(@uri).to be_frozen
1061
+ end
1062
+
1063
+ it "should not allow destructive operations" do
1064
+ expect { @uri.normalize! }.to raise_error(RuntimeError)
1065
+ end
1066
+ end
1067
+
1004
1068
  describe Addressable::URI, "when created from string components" do
1005
1069
  before do
1006
1070
  @uri = Addressable::URI.new(
@@ -1017,31 +1081,31 @@ describe Addressable::URI, "when created from string components" do
1017
1081
  end
1018
1082
 
1019
1083
  it "should raise an error if invalid components omitted" do
1020
- expect(lambda do
1084
+ expect do
1021
1085
  @uri.omit(:bogus)
1022
- end).to raise_error(ArgumentError)
1023
- expect(lambda do
1086
+ end.to raise_error(ArgumentError)
1087
+ expect do
1024
1088
  @uri.omit(:scheme, :bogus, :path)
1025
- end).to raise_error(ArgumentError)
1089
+ end.to raise_error(ArgumentError)
1026
1090
  end
1027
1091
  end
1028
1092
 
1029
1093
  describe Addressable::URI, "when created with a nil host but " +
1030
1094
  "non-nil authority components" do
1031
1095
  it "should raise an error" do
1032
- expect(lambda do
1096
+ expect do
1033
1097
  Addressable::URI.new(:user => "user", :password => "pass", :port => 80)
1034
- end).to raise_error(Addressable::URI::InvalidURIError)
1098
+ end.to raise_error(Addressable::URI::InvalidURIError)
1035
1099
  end
1036
1100
  end
1037
1101
 
1038
1102
  describe Addressable::URI, "when created with both an authority and a user" do
1039
1103
  it "should raise an error" do
1040
- expect(lambda do
1104
+ expect do
1041
1105
  Addressable::URI.new(
1042
1106
  :user => "user", :authority => "user@example.com:80"
1043
1107
  )
1044
- end).to raise_error(ArgumentError)
1108
+ end.to raise_error(ArgumentError)
1045
1109
  end
1046
1110
  end
1047
1111
 
@@ -1079,33 +1143,33 @@ end
1079
1143
 
1080
1144
  describe Addressable::URI, "when created with a host with a backslash" do
1081
1145
  it "should raise an error" do
1082
- expect(lambda do
1146
+ expect do
1083
1147
  Addressable::URI.new(:authority => "example\\example")
1084
- end).to raise_error(Addressable::URI::InvalidURIError)
1148
+ end.to raise_error(Addressable::URI::InvalidURIError)
1085
1149
  end
1086
1150
  end
1087
1151
 
1088
1152
  describe Addressable::URI, "when created with a host with a slash" do
1089
1153
  it "should raise an error" do
1090
- expect(lambda do
1154
+ expect do
1091
1155
  Addressable::URI.new(:authority => "example/example")
1092
- end).to raise_error(Addressable::URI::InvalidURIError)
1156
+ end.to raise_error(Addressable::URI::InvalidURIError)
1093
1157
  end
1094
1158
  end
1095
1159
 
1096
1160
  describe Addressable::URI, "when created with a host with a space" do
1097
1161
  it "should raise an error" do
1098
- expect(lambda do
1162
+ expect do
1099
1163
  Addressable::URI.new(:authority => "example example")
1100
- end).to raise_error(Addressable::URI::InvalidURIError)
1164
+ end.to raise_error(Addressable::URI::InvalidURIError)
1101
1165
  end
1102
1166
  end
1103
1167
 
1104
1168
  describe Addressable::URI, "when created with both a userinfo and a user" do
1105
1169
  it "should raise an error" do
1106
- expect(lambda do
1170
+ expect do
1107
1171
  Addressable::URI.new(:user => "user", :userinfo => "user:pass")
1108
- end).to raise_error(ArgumentError)
1172
+ end.to raise_error(ArgumentError)
1109
1173
  end
1110
1174
  end
1111
1175
 
@@ -1197,18 +1261,18 @@ describe Addressable::URI, "when parsed from something that looks " +
1197
1261
  "like a URI object" do
1198
1262
  it "should parse without error" do
1199
1263
  uri = Addressable::URI.parse(Fake::URI::HTTP.new("http://example.com/"))
1200
- expect(lambda do
1264
+ expect do
1201
1265
  Addressable::URI.parse(uri)
1202
- end).not_to raise_error
1266
+ end.not_to raise_error
1203
1267
  end
1204
1268
  end
1205
1269
 
1206
1270
  describe Addressable::URI, "when parsed from a standard library URI object" do
1207
1271
  it "should parse without error" do
1208
1272
  uri = Addressable::URI.parse(URI.parse("http://example.com/"))
1209
- expect(lambda do
1273
+ expect do
1210
1274
  Addressable::URI.parse(uri)
1211
- end).not_to raise_error
1275
+ end.not_to raise_error
1212
1276
  end
1213
1277
  end
1214
1278
 
@@ -1368,9 +1432,9 @@ describe Addressable::URI, "when parsed from " +
1368
1432
  end
1369
1433
 
1370
1434
  it "should not allow request URI assignment" do
1371
- expect(lambda do
1435
+ expect do
1372
1436
  @uri.request_uri = "/"
1373
- end).to raise_error(Addressable::URI::InvalidURIError)
1437
+ end.to raise_error(Addressable::URI::InvalidURIError)
1374
1438
  end
1375
1439
 
1376
1440
  it "should have a query of 'objectClass?one'" do
@@ -1392,9 +1456,9 @@ describe Addressable::URI, "when parsed from " +
1392
1456
  end
1393
1457
 
1394
1458
  it "should raise an error if omission would create an invalid URI" do
1395
- expect(lambda do
1459
+ expect do
1396
1460
  @uri.omit(:authority, :path)
1397
- end).to raise_error(Addressable::URI::InvalidURIError)
1461
+ end.to raise_error(Addressable::URI::InvalidURIError)
1398
1462
  end
1399
1463
 
1400
1464
  it "should have an origin of 'ldap://[2001:db8::7]'" do
@@ -1693,6 +1757,19 @@ describe Addressable::URI, "when parsed from " +
1693
1757
  expect(@uri.inspect).to include("%#0x" % @uri.object_id)
1694
1758
  end
1695
1759
 
1760
+ context "when Addressable::URI has been sub-classed" do
1761
+ class CustomURIClass < Addressable::URI
1762
+ end
1763
+
1764
+ before do
1765
+ @uri = CustomURIClass.parse("http://example.com")
1766
+ end
1767
+
1768
+ it "when inspected, should have the sub-classes name" do
1769
+ expect(@uri.inspect).to include("CustomURIClass")
1770
+ end
1771
+ end
1772
+
1696
1773
  it "should use the 'http' scheme" do
1697
1774
  expect(@uri.scheme).to eq("http")
1698
1775
  end
@@ -1780,9 +1857,9 @@ describe Addressable::URI, "when parsed from " +
1780
1857
 
1781
1858
  it "should not be roughly equal to the string " +
1782
1859
  "'http://example.com:bogus/'" do
1783
- expect(lambda do
1860
+ expect do
1784
1861
  expect(@uri === "http://example.com:bogus/").to eq(false)
1785
- end).not_to raise_error
1862
+ end.not_to raise_error
1786
1863
  end
1787
1864
 
1788
1865
  it "should result in itself when joined with itself" do
@@ -1812,21 +1889,21 @@ describe Addressable::URI, "when parsed from " +
1812
1889
  end
1813
1890
 
1814
1891
  it "should not allow origin assignment without scheme" do
1815
- expect(lambda do
1892
+ expect do
1816
1893
  @uri.origin = "example.com"
1817
- end).to raise_error(Addressable::URI::InvalidURIError)
1894
+ end.to raise_error(Addressable::URI::InvalidURIError)
1818
1895
  end
1819
1896
 
1820
1897
  it "should not allow origin assignment without host" do
1821
- expect(lambda do
1898
+ expect do
1822
1899
  @uri.origin = "http://"
1823
- end).to raise_error(Addressable::URI::InvalidURIError)
1900
+ end.to raise_error(Addressable::URI::InvalidURIError)
1824
1901
  end
1825
1902
 
1826
1903
  it "should not allow origin assignment with bogus type" do
1827
- expect(lambda do
1904
+ expect do
1828
1905
  @uri.origin = :bogus
1829
- end).to raise_error(TypeError)
1906
+ end.to raise_error(TypeError)
1830
1907
  end
1831
1908
 
1832
1909
  # Section 6.2.3 of RFC 3986
@@ -1882,9 +1959,9 @@ describe Addressable::URI, "when parsed from " +
1882
1959
  end
1883
1960
 
1884
1961
  it "when joined with a bogus object a TypeError should be raised" do
1885
- expect(lambda do
1962
+ expect do
1886
1963
  @uri.join(42)
1887
- end).to raise_error(TypeError)
1964
+ end.to raise_error(TypeError)
1888
1965
  end
1889
1966
 
1890
1967
  it "should have the correct username after assignment" do
@@ -1979,15 +2056,29 @@ end
1979
2056
 
1980
2057
  # Section 5.1.2 of RFC 2616
1981
2058
  describe Addressable::URI, "when parsed from " +
1982
- "'http://www.w3.org/pub/WWW/TheProject.html'" do
2059
+ "'HTTP://www.w3.org/pub/WWW/TheProject.html'" do
1983
2060
  before do
1984
- @uri = Addressable::URI.parse("http://www.w3.org/pub/WWW/TheProject.html")
2061
+ @uri = Addressable::URI.parse("HTTP://www.w3.org/pub/WWW/TheProject.html")
1985
2062
  end
1986
2063
 
1987
2064
  it "should have the correct request URI" do
1988
2065
  expect(@uri.request_uri).to eq("/pub/WWW/TheProject.html")
1989
2066
  end
1990
2067
 
2068
+ it "should have the correct request URI after assignment" do
2069
+ @uri.request_uri = "/pub/WWW/TheProject.html?"
2070
+ expect(@uri.request_uri).to eq("/pub/WWW/TheProject.html?")
2071
+ expect(@uri.path).to eq("/pub/WWW/TheProject.html")
2072
+ expect(@uri.query).to eq("")
2073
+ end
2074
+
2075
+ it "should have the correct request URI after assignment" do
2076
+ @uri.request_uri = "/some/where/else.html"
2077
+ expect(@uri.request_uri).to eq("/some/where/else.html")
2078
+ expect(@uri.path).to eq("/some/where/else.html")
2079
+ expect(@uri.query).to eq(nil)
2080
+ end
2081
+
1991
2082
  it "should have the correct request URI after assignment" do
1992
2083
  @uri.request_uri = "/some/where/else.html?query?string"
1993
2084
  expect(@uri.request_uri).to eq("/some/where/else.html?query?string")
@@ -2003,20 +2094,20 @@ describe Addressable::URI, "when parsed from " +
2003
2094
  end
2004
2095
 
2005
2096
  it "should raise an error if the site value is set to something bogus" do
2006
- expect(lambda do
2097
+ expect do
2007
2098
  @uri.site = 42
2008
- end).to raise_error(TypeError)
2099
+ end.to raise_error(TypeError)
2009
2100
  end
2010
2101
 
2011
2102
  it "should raise an error if the request URI is set to something bogus" do
2012
- expect(lambda do
2103
+ expect do
2013
2104
  @uri.request_uri = 42
2014
- end).to raise_error(TypeError)
2105
+ end.to raise_error(TypeError)
2015
2106
  end
2016
2107
 
2017
2108
  it "should correctly convert to a hash" do
2018
2109
  expect(@uri.to_hash).to eq({
2019
- :scheme => "http",
2110
+ :scheme => "HTTP",
2020
2111
  :user => nil,
2021
2112
  :password => nil,
2022
2113
  :host => "www.w3.org",
@@ -2060,9 +2151,9 @@ describe Addressable::URI, "when parsing IPv6 addresses" do
2060
2151
 
2061
2152
  it "should raise an error for " +
2062
2153
  "'http://[<invalid>]/'" do
2063
- expect(lambda do
2154
+ expect do
2064
2155
  Addressable::URI.parse("http://[<invalid>]/")
2065
- end).to raise_error(Addressable::URI::InvalidURIError)
2156
+ end.to raise_error(Addressable::URI::InvalidURIError)
2066
2157
  end
2067
2158
  end
2068
2159
 
@@ -2088,9 +2179,9 @@ describe Addressable::URI, "when assigning IPv6 address" do
2088
2179
  it "should not allow to set bare IPv6 address as host" do
2089
2180
  uri = Addressable::URI.parse("http://[::1]/")
2090
2181
  skip "not checked"
2091
- expect(lambda do
2182
+ expect do
2092
2183
  uri.host = '3ffe:1900:4545:3:200:f8ff:fe21:67cf'
2093
- end).to raise_error(Addressable::URI::InvalidURIError)
2184
+ end.to raise_error(Addressable::URI::InvalidURIError)
2094
2185
  end
2095
2186
  end
2096
2187
 
@@ -2122,9 +2213,9 @@ describe Addressable::URI, "when parsing IPvFuture addresses" do
2122
2213
 
2123
2214
  it "should raise an error for " +
2124
2215
  "'http://[v0.<invalid>]/'" do
2125
- expect(lambda do
2216
+ expect do
2126
2217
  Addressable::URI.parse("http://[v0.<invalid>]/")
2127
- end).to raise_error(Addressable::URI::InvalidURIError)
2218
+ end.to raise_error(Addressable::URI::InvalidURIError)
2128
2219
  end
2129
2220
  end
2130
2221
 
@@ -2468,9 +2559,9 @@ describe Addressable::URI, "when parsed from " +
2468
2559
  end
2469
2560
 
2470
2561
  it "should not raise an exception when normalized" do
2471
- expect(lambda do
2562
+ expect do
2472
2563
  @uri.normalize
2473
- end).not_to raise_error
2564
+ end.not_to raise_error
2474
2565
  end
2475
2566
 
2476
2567
  it "should be considered to be in normal form" do
@@ -2522,9 +2613,9 @@ describe Addressable::URI, "when parsed from " +
2522
2613
  end
2523
2614
 
2524
2615
  it "should not raise an exception when normalized" do
2525
- expect(lambda do
2616
+ expect do
2526
2617
  @uri.normalize
2527
- end).not_to raise_error
2618
+ end.not_to raise_error
2528
2619
  end
2529
2620
 
2530
2621
  it "should be considered to be in normal form" do
@@ -2547,9 +2638,9 @@ describe Addressable::URI, "when parsed from " +
2547
2638
  end
2548
2639
 
2549
2640
  it "should not raise an exception when normalized" do
2550
- expect(lambda do
2641
+ expect do
2551
2642
  @uri.normalize
2552
- end).not_to raise_error
2643
+ end.not_to raise_error
2553
2644
  end
2554
2645
 
2555
2646
  it "should be considered to be in normal form" do
@@ -2585,9 +2676,9 @@ describe Addressable::URI, "when parsed from " +
2585
2676
  end
2586
2677
 
2587
2678
  it "should raise an error if encoding with an unexpected return type" do
2588
- expect(lambda do
2679
+ expect do
2589
2680
  Addressable::URI.normalized_encode(@uri, Integer)
2590
- end).to raise_error(TypeError)
2681
+ end.to raise_error(TypeError)
2591
2682
  end
2592
2683
 
2593
2684
  it "if percent encoded should be 'http://example.com/C%25CC%25A7'" do
@@ -2603,9 +2694,9 @@ describe Addressable::URI, "when parsed from " +
2603
2694
  end
2604
2695
 
2605
2696
  it "should raise an error if encoding with an unexpected return type" do
2606
- expect(lambda do
2697
+ expect do
2607
2698
  Addressable::URI.encode(@uri, Integer)
2608
- end).to raise_error(TypeError)
2699
+ end.to raise_error(TypeError)
2609
2700
  end
2610
2701
 
2611
2702
  it "should be identical to its duplicate" do
@@ -2740,9 +2831,9 @@ describe Addressable::URI, "when parsed from " +
2740
2831
 
2741
2832
  it "should not be roughly equal to the string " +
2742
2833
  "'http://example.com:bogus/'" do
2743
- expect(lambda do
2834
+ expect do
2744
2835
  expect(@uri === "http://example.com:bogus/").to eq(false)
2745
- end).not_to raise_error
2836
+ end.not_to raise_error
2746
2837
  end
2747
2838
 
2748
2839
  it "should result in itself when joined with itself" do
@@ -2944,6 +3035,20 @@ describe Addressable::URI, "when parsed from " +
2944
3035
  end
2945
3036
  end
2946
3037
 
3038
+ describe Addressable::URI, "when parsed with empty port" do
3039
+ subject(:uri) do
3040
+ Addressable::URI.parse("//example.com:")
3041
+ end
3042
+
3043
+ it "should not infer a port" do
3044
+ expect(uri.port).to be(nil)
3045
+ end
3046
+
3047
+ it "should have a site value of '//example.com'" do
3048
+ expect(uri.site).to eq("//example.com")
3049
+ end
3050
+ end
3051
+
2947
3052
  describe Addressable::URI, "when parsed from " +
2948
3053
  "'http://example.com/%2E/'" do
2949
3054
  before do
@@ -3088,9 +3193,9 @@ describe Addressable::URI, "when parsed from " +
3088
3193
  end
3089
3194
 
3090
3195
  it "should become invalid when normalized" do
3091
- expect(lambda do
3196
+ expect do
3092
3197
  @uri.normalize
3093
- end).to raise_error(Addressable::URI::InvalidURIError, /authority/)
3198
+ end.to raise_error(Addressable::URI::InvalidURIError, /authority/)
3094
3199
  end
3095
3200
 
3096
3201
  it "should have a path of '/..//example.com'" do
@@ -3328,12 +3433,12 @@ describe Addressable::URI, "when parsed from " +
3328
3433
  end
3329
3434
 
3330
3435
  it "should raise an error if routing is attempted" do
3331
- expect(lambda do
3436
+ expect do
3332
3437
  @uri.route_to("http://example.com/")
3333
- end).to raise_error(ArgumentError, /relative\/path\/to\/resource/)
3334
- expect(lambda do
3438
+ end.to raise_error(ArgumentError, /relative\/path\/to\/resource/)
3439
+ expect do
3335
3440
  @uri.route_from("http://example.com/")
3336
- end).to raise_error(ArgumentError, /relative\/path\/to\/resource/)
3441
+ end.to raise_error(ArgumentError, /relative\/path\/to\/resource/)
3337
3442
  end
3338
3443
 
3339
3444
  it "when joined with 'another/relative/path' should be " +
@@ -3930,9 +4035,9 @@ describe Addressable::URI, "when parsed from " +
3930
4035
  end
3931
4036
 
3932
4037
  it "should raise an error if assigning a bogus object to the hostname" do
3933
- expect(lambda do
4038
+ expect do
3934
4039
  @uri.hostname = Object.new
3935
- end).to raise_error
4040
+ end.to raise_error(TypeError)
3936
4041
  end
3937
4042
 
3938
4043
  it "should have the correct port after assignment" do
@@ -4011,9 +4116,9 @@ describe Addressable::URI, "when parsed from " +
4011
4116
  end
4012
4117
 
4013
4118
  it "should raise an error if query values are set to a bogus type" do
4014
- expect(lambda do
4119
+ expect do
4015
4120
  @uri.query_values = "bogus"
4016
- end).to raise_error(TypeError)
4121
+ end.to raise_error(TypeError)
4017
4122
  end
4018
4123
 
4019
4124
  it "should have the correct fragment after assignment" do
@@ -4085,39 +4190,39 @@ describe Addressable::URI, "when parsed from " +
4085
4190
  end
4086
4191
 
4087
4192
  it "should fail to merge with bogus values" do
4088
- expect(lambda do
4193
+ expect do
4089
4194
  @uri.merge(:port => "bogus")
4090
- end).to raise_error(Addressable::URI::InvalidURIError)
4195
+ end.to raise_error(Addressable::URI::InvalidURIError)
4091
4196
  end
4092
4197
 
4093
4198
  it "should fail to merge with bogus values" do
4094
- expect(lambda do
4199
+ expect do
4095
4200
  @uri.merge(:authority => "bar@baz:bogus")
4096
- end).to raise_error(Addressable::URI::InvalidURIError)
4201
+ end.to raise_error(Addressable::URI::InvalidURIError)
4097
4202
  end
4098
4203
 
4099
4204
  it "should fail to merge with bogus parameters" do
4100
- expect(lambda do
4205
+ expect do
4101
4206
  @uri.merge(42)
4102
- end).to raise_error(TypeError)
4207
+ end.to raise_error(TypeError)
4103
4208
  end
4104
4209
 
4105
4210
  it "should fail to merge with bogus parameters" do
4106
- expect(lambda do
4211
+ expect do
4107
4212
  @uri.merge("http://example.com/")
4108
- end).to raise_error(TypeError)
4213
+ end.to raise_error(TypeError)
4109
4214
  end
4110
4215
 
4111
4216
  it "should fail to merge with both authority and subcomponents" do
4112
- expect(lambda do
4217
+ expect do
4113
4218
  @uri.merge(:authority => "foo:bar@baz:42", :port => "42")
4114
- end).to raise_error(ArgumentError)
4219
+ end.to raise_error(ArgumentError)
4115
4220
  end
4116
4221
 
4117
4222
  it "should fail to merge with both userinfo and subcomponents" do
4118
- expect(lambda do
4223
+ expect do
4119
4224
  @uri.merge(:userinfo => "foo:bar", :user => "foo")
4120
- end).to raise_error(ArgumentError)
4225
+ end.to raise_error(ArgumentError)
4121
4226
  end
4122
4227
 
4123
4228
  it "should be identical to its duplicate" do
@@ -4250,6 +4355,36 @@ describe Addressable::URI, "when parsed from " +
4250
4355
  end
4251
4356
  end
4252
4357
 
4358
+ describe Addressable::URI, "when parsed from 'https://example.com/?q=a+b'" do
4359
+ before do
4360
+ @uri = Addressable::URI.parse("https://example.com/?q=a+b")
4361
+ end
4362
+
4363
+ it "should have query_values of {'q' => 'a b'}" do
4364
+ expect(@uri.query_values).to eq("q" => "a b")
4365
+ end
4366
+ end
4367
+
4368
+ describe Addressable::URI, "when parsed from 'example.com?q=a+b'" do
4369
+ before do
4370
+ @uri = Addressable::URI.parse("example.com?q=a+b")
4371
+ end
4372
+
4373
+ it "should have query_values of {'q' => 'a b'}" do
4374
+ expect(@uri.query_values).to eq("q" => "a b")
4375
+ end
4376
+ end
4377
+
4378
+ describe Addressable::URI, "when parsed from 'mailto:?q=a+b'" do
4379
+ before do
4380
+ @uri = Addressable::URI.parse("mailto:?q=a+b")
4381
+ end
4382
+
4383
+ it "should have query_values of {'q' => 'a+b'}" do
4384
+ expect(@uri.query_values).to eq("q" => "a+b")
4385
+ end
4386
+ end
4387
+
4253
4388
  describe Addressable::URI, "when parsed from " +
4254
4389
  "'http://example.com/?q=a%2bb'" do
4255
4390
  before do
@@ -4291,6 +4426,46 @@ describe Addressable::URI, "when parsed from " +
4291
4426
  end
4292
4427
  end
4293
4428
 
4429
+ describe Addressable::URI, "when parsed from 'http://example/?b=1&a=2&c=3'" do
4430
+ before do
4431
+ @uri = Addressable::URI.parse("http://example/?b=1&a=2&c=3")
4432
+ end
4433
+
4434
+ it "should have a sorted normalized query of 'a=2&b=1&c=3'" do
4435
+ expect(@uri.normalized_query(:sorted)).to eq("a=2&b=1&c=3")
4436
+ end
4437
+ end
4438
+
4439
+ describe Addressable::URI, "when parsed from 'http://example/?&a&&c&'" do
4440
+ before do
4441
+ @uri = Addressable::URI.parse("http://example/?&a&&c&")
4442
+ end
4443
+
4444
+ it "should have a compacted normalized query of 'a&c'" do
4445
+ expect(@uri.normalized_query(:compacted)).to eq("a&c")
4446
+ end
4447
+ end
4448
+
4449
+ describe Addressable::URI, "when parsed from 'http://example.com/?a=1&a=1'" do
4450
+ before do
4451
+ @uri = Addressable::URI.parse("http://example.com/?a=1&a=1")
4452
+ end
4453
+
4454
+ it "should have a compacted normalized query of 'a=1'" do
4455
+ expect(@uri.normalized_query(:compacted)).to eq("a=1")
4456
+ end
4457
+ end
4458
+
4459
+ describe Addressable::URI, "when parsed from 'http://example.com/?a=1&a=2'" do
4460
+ before do
4461
+ @uri = Addressable::URI.parse("http://example.com/?a=1&a=2")
4462
+ end
4463
+
4464
+ it "should have a compacted normalized query of 'a=1&a=2'" do
4465
+ expect(@uri.normalized_query(:compacted)).to eq("a=1&a=2")
4466
+ end
4467
+ end
4468
+
4294
4469
  describe Addressable::URI, "when parsed from " +
4295
4470
  "'http://example.com/sound%2bvision'" do
4296
4471
  before do
@@ -4402,10 +4577,10 @@ describe Addressable::URI, "when parsed from " +
4402
4577
  end
4403
4578
 
4404
4579
  it "should raise an error after nil assignment of authority segment" do
4405
- expect(lambda do
4580
+ expect do
4406
4581
  # This would create an invalid URI
4407
4582
  @uri.authority = nil
4408
- end).to raise_error
4583
+ end.to raise_error(Addressable::URI::InvalidURIError)
4409
4584
  end
4410
4585
  end
4411
4586
 
@@ -4634,12 +4809,12 @@ describe Addressable::URI, "when parsed from " +
4634
4809
  end
4635
4810
 
4636
4811
  it "should raise an error if routing is attempted" do
4637
- expect(lambda do
4812
+ expect do
4638
4813
  @uri.route_to("http://example.com/")
4639
- end).to raise_error(ArgumentError, /\/\/example.com\//)
4640
- expect(lambda do
4814
+ end.to raise_error(ArgumentError, /\/\/example.com\//)
4815
+ expect do
4641
4816
  @uri.route_from("http://example.com/")
4642
- end).to raise_error(ArgumentError, /\/\/example.com\//)
4817
+ end.to raise_error(ArgumentError, /\/\/example.com\//)
4643
4818
  end
4644
4819
 
4645
4820
  it "should have a 'null' origin" do
@@ -4733,9 +4908,9 @@ end
4733
4908
  describe Addressable::URI, "when parsed from " +
4734
4909
  "'http://under_score.example.com/'" do
4735
4910
  it "should not cause an error" do
4736
- expect(lambda do
4911
+ expect do
4737
4912
  Addressable::URI.parse("http://under_score.example.com/")
4738
- end).not_to raise_error
4913
+ end.not_to raise_error
4739
4914
  end
4740
4915
  end
4741
4916
 
@@ -4807,9 +4982,9 @@ describe Addressable::URI, "when parsed from '?one=1&two=2&three=3'" do
4807
4982
  end
4808
4983
 
4809
4984
  it "should raise an error for invalid return type values" do
4810
- expect(lambda do
4811
- @uri.query_values(Fixnum)
4812
- end).to raise_error(ArgumentError)
4985
+ expect do
4986
+ @uri.query_values(Integer)
4987
+ end.to raise_error(ArgumentError)
4813
4988
  end
4814
4989
 
4815
4990
  it "should have the correct array query values" do
@@ -5410,9 +5585,9 @@ describe Addressable::URI, "with a base uri of 'http://a/b/c/d;p?q'" do
5410
5585
  end
5411
5586
 
5412
5587
  it "when joined with a bogus object a TypeError should be raised" do
5413
- expect(lambda do
5588
+ expect do
5414
5589
  Addressable::URI.join(@uri, 42)
5415
- end).to raise_error(TypeError)
5590
+ end.to raise_error(TypeError)
5416
5591
  end
5417
5592
  end
5418
5593
 
@@ -5439,9 +5614,9 @@ end
5439
5614
 
5440
5615
  describe Addressable::URI, "when converting a bogus path" do
5441
5616
  it "should raise a TypeError" do
5442
- expect(lambda do
5617
+ expect do
5443
5618
  Addressable::URI.convert_path(42)
5444
- end).to raise_error(TypeError)
5619
+ end.to raise_error(TypeError)
5445
5620
  end
5446
5621
  end
5447
5622
 
@@ -5494,6 +5669,31 @@ describe Addressable::URI, "when given the path '/one/two/'" do
5494
5669
  end
5495
5670
  end
5496
5671
 
5672
+ describe Addressable::URI, "when given the tld " do
5673
+ it "'uk' should have a tld of 'uk'" do
5674
+ uri = Addressable::URI.parse("http://example.com")
5675
+ uri.tld = "uk"
5676
+
5677
+ expect(uri.tld).to eq("uk")
5678
+ end
5679
+
5680
+ context "which " do
5681
+ let (:uri) { Addressable::URI.parse("http://www.comrade.net/path/to/source/") }
5682
+
5683
+ it "contains a subdomain" do
5684
+ uri.tld = "co.uk"
5685
+
5686
+ expect(uri.to_s).to eq("http://www.comrade.co.uk/path/to/source/")
5687
+ end
5688
+
5689
+ it "is part of the domain" do
5690
+ uri.tld = "com"
5691
+
5692
+ expect(uri.to_s).to eq("http://www.comrade.com/path/to/source/")
5693
+ end
5694
+ end
5695
+ end
5696
+
5497
5697
  describe Addressable::URI, "when given the path " +
5498
5698
  "'c:\\windows\\My Documents 100%20\\foo.txt'" do
5499
5699
  before do
@@ -5611,9 +5811,9 @@ describe Addressable::URI, "when parsing a non-String object" do
5611
5811
  end
5612
5812
 
5613
5813
  it "should raise a TypeError for objects than cannot be converted" do
5614
- expect(lambda do
5814
+ expect do
5615
5815
  Addressable::URI.parse(42)
5616
- end).to raise_error(TypeError)
5816
+ end.to raise_error(TypeError)
5617
5817
  end
5618
5818
 
5619
5819
  it "should correctly parse heuristically anything with a 'to_str' method" do
@@ -5621,9 +5821,9 @@ describe Addressable::URI, "when parsing a non-String object" do
5621
5821
  end
5622
5822
 
5623
5823
  it "should raise a TypeError for objects than cannot be converted" do
5624
- expect(lambda do
5824
+ expect do
5625
5825
  Addressable::URI.heuristic_parse(42)
5626
- end).to raise_error(TypeError)
5826
+ end.to raise_error(TypeError)
5627
5827
  end
5628
5828
  end
5629
5829
 
@@ -5667,9 +5867,9 @@ end
5667
5867
 
5668
5868
  describe Addressable::URI, "when form encoding a non-Array object" do
5669
5869
  it "should raise a TypeError for objects than cannot be converted" do
5670
- expect(lambda do
5870
+ expect do
5671
5871
  Addressable::URI.form_encode(42)
5672
- end).to raise_error(TypeError)
5872
+ end.to raise_error(TypeError)
5673
5873
  end
5674
5874
  end
5675
5875
 
@@ -5735,9 +5935,9 @@ describe Addressable::URI, "when form unencoding a non-String object" do
5735
5935
  end
5736
5936
 
5737
5937
  it "should raise a TypeError for objects than cannot be converted" do
5738
- expect(lambda do
5938
+ expect do
5739
5939
  Addressable::URI.form_unencode(42)
5740
- end).to raise_error(TypeError)
5940
+ end.to raise_error(TypeError)
5741
5941
  end
5742
5942
  end
5743
5943
 
@@ -5747,15 +5947,15 @@ describe Addressable::URI, "when normalizing a non-String object" do
5747
5947
  end
5748
5948
 
5749
5949
  it "should raise a TypeError for objects than cannot be converted" do
5750
- expect(lambda do
5950
+ expect do
5751
5951
  Addressable::URI.normalize_component(42)
5752
- end).to raise_error(TypeError)
5952
+ end.to raise_error(TypeError)
5753
5953
  end
5754
5954
 
5755
5955
  it "should raise a TypeError for objects than cannot be converted" do
5756
- expect(lambda do
5956
+ expect do
5757
5957
  Addressable::URI.normalize_component("component", 42)
5758
- end).to raise_error(TypeError)
5958
+ end.to raise_error(TypeError)
5759
5959
  end
5760
5960
  end
5761
5961
 
@@ -5767,6 +5967,26 @@ describe Addressable::URI, "when normalizing a path with an encoded slash" do
5767
5967
  end
5768
5968
  end
5769
5969
 
5970
+ describe Addressable::URI, "when normalizing a path with special unicode" do
5971
+ it "does not stop at or ignore null bytes" do
5972
+ expect(Addressable::URI.parse("/path%00segment/").normalize.path).to eq(
5973
+ "/path%00segment/"
5974
+ )
5975
+ end
5976
+
5977
+ it "does apply NFC unicode normalization" do
5978
+ expect(Addressable::URI.parse("/%E2%84%A6").normalize.path).to eq(
5979
+ "/%CE%A9"
5980
+ )
5981
+ end
5982
+
5983
+ it "does not apply NFKC unicode normalization" do
5984
+ expect(Addressable::URI.parse("/%C2%AF%C2%A0").normalize.path).to eq(
5985
+ "/%C2%AF%C2%A0"
5986
+ )
5987
+ end
5988
+ end
5989
+
5770
5990
  describe Addressable::URI, "when normalizing a partially encoded string" do
5771
5991
  it "should result in correct percent encoded sequence" do
5772
5992
  expect(Addressable::URI.normalize_component(
@@ -5827,6 +6047,18 @@ describe Addressable::URI, "when normalizing a string but leaving some character
5827
6047
  end
5828
6048
  end
5829
6049
 
6050
+ describe Addressable::URI, "when encoding IP literals" do
6051
+ it "should work for IPv4" do
6052
+ input = "http://127.0.0.1/"
6053
+ expect(Addressable::URI.encode(input)).to eq(input)
6054
+ end
6055
+
6056
+ it "should work for IPv6" do
6057
+ input = "http://[fe80::200:f8ff:fe21:67cf]/"
6058
+ expect(Addressable::URI.encode(input)).to eq(input)
6059
+ end
6060
+ end
6061
+
5830
6062
  describe Addressable::URI, "when encoding a string with existing encodings to upcase" do
5831
6063
  it "should result in correct percent encoded sequence" do
5832
6064
  expect(Addressable::URI.encode_component("JK%4c", "0-9A-IKM-Za-z%", "L")).to eq("%4AK%4C")
@@ -5874,6 +6106,11 @@ describe Addressable::URI, "when unencoding a multibyte string" do
5874
6106
  expect(Addressable::URI.unencode_component("ski=%BA%DAɫ")).to eq("ski=\xBA\xDAɫ")
5875
6107
  end
5876
6108
 
6109
+ it "should not fail with UTF-8 incompatible string" do
6110
+ url = "/M%E9/\xE9?p=\xFC".b
6111
+ expect(Addressable::URI.unencode_component(url)).to eq("/M\xE9/\xE9?p=\xFC")
6112
+ end
6113
+
5877
6114
  it "should result in correct percent encoded sequence as a URI" do
5878
6115
  expect(Addressable::URI.unencode(
5879
6116
  "/path?g%C3%BCnther", ::Addressable::URI
@@ -5899,41 +6136,41 @@ end
5899
6136
 
5900
6137
  describe Addressable::URI, "when unencoding a bogus object" do
5901
6138
  it "should raise a TypeError" do
5902
- expect(lambda do
6139
+ expect do
5903
6140
  Addressable::URI.unencode_component(42)
5904
- end).to raise_error(TypeError)
6141
+ end.to raise_error(TypeError)
5905
6142
  end
5906
6143
 
5907
6144
  it "should raise a TypeError" do
5908
- expect(lambda do
6145
+ expect do
5909
6146
  Addressable::URI.unencode("/path?g%C3%BCnther", Integer)
5910
- end).to raise_error(TypeError)
6147
+ end.to raise_error(TypeError)
5911
6148
  end
5912
6149
  end
5913
6150
 
5914
6151
  describe Addressable::URI, "when encoding a bogus object" do
5915
6152
  it "should raise a TypeError" do
5916
- expect(lambda do
6153
+ expect do
5917
6154
  Addressable::URI.encode(Object.new)
5918
- end).to raise_error(TypeError)
6155
+ end.to raise_error(TypeError)
5919
6156
  end
5920
6157
 
5921
6158
  it "should raise a TypeError" do
5922
- expect(lambda do
6159
+ expect do
5923
6160
  Addressable::URI.normalized_encode(Object.new)
5924
- end).to raise_error(TypeError)
6161
+ end.to raise_error(TypeError)
5925
6162
  end
5926
6163
 
5927
6164
  it "should raise a TypeError" do
5928
- expect(lambda do
6165
+ expect do
5929
6166
  Addressable::URI.encode_component("günther", Object.new)
5930
- end).to raise_error(TypeError)
6167
+ end.to raise_error(TypeError)
5931
6168
  end
5932
6169
 
5933
6170
  it "should raise a TypeError" do
5934
- expect(lambda do
6171
+ expect do
5935
6172
  Addressable::URI.encode_component(Object.new)
5936
- end).to raise_error(TypeError)
6173
+ end.to raise_error(TypeError)
5937
6174
  end
5938
6175
  end
5939
6176
 
@@ -5949,9 +6186,9 @@ describe Addressable::URI, "when given the input " +
5949
6186
  end
5950
6187
 
5951
6188
  it "should not raise error when frozen" do
5952
- expect(lambda do
6189
+ expect do
5953
6190
  Addressable::URI.heuristic_parse(@input).freeze.to_s
5954
- end).not_to raise_error
6191
+ end.not_to raise_error
5955
6192
  end
5956
6193
  end
5957
6194
 
@@ -6231,6 +6468,18 @@ describe Addressable::URI, "when given the input " +
6231
6468
  end
6232
6469
  end
6233
6470
 
6471
+ describe Addressable::URI, "when given the input which "\
6472
+ "start with digits and has specified port" do
6473
+ before do
6474
+ @input = "7777.example.org:8089"
6475
+ end
6476
+
6477
+ it "should heuristically parse to 'http://7777.example.org:8089'" do
6478
+ uri = Addressable::URI.heuristic_parse(@input)
6479
+ expect(uri.to_s).to eq("http://7777.example.org:8089")
6480
+ end
6481
+ end
6482
+
6234
6483
  describe Addressable::URI, "when given the input " +
6235
6484
  "'feed:///example.com'" do
6236
6485
  before do
@@ -6243,6 +6492,18 @@ describe Addressable::URI, "when given the input " +
6243
6492
  end
6244
6493
  end
6245
6494
 
6495
+ describe Addressable::URI, "when given the input " +
6496
+ "'file://localhost/path/to/resource/'" do
6497
+ before do
6498
+ @input = "file://localhost/path/to/resource/"
6499
+ end
6500
+
6501
+ it "should heuristically parse to 'file:///path/to/resource/'" do
6502
+ @uri = Addressable::URI.heuristic_parse(@input)
6503
+ expect(@uri.to_s).to eq("file:///path/to/resource/")
6504
+ end
6505
+ end
6506
+
6246
6507
  describe Addressable::URI, "when given the input " +
6247
6508
  "'file://path/to/resource/'" do
6248
6509
  before do
@@ -6255,6 +6516,18 @@ describe Addressable::URI, "when given the input " +
6255
6516
  end
6256
6517
  end
6257
6518
 
6519
+ describe Addressable::URI, "when given the input " +
6520
+ "'file://///path/to/resource/'" do
6521
+ before do
6522
+ @input = "file:///////path/to/resource/"
6523
+ end
6524
+
6525
+ it "should heuristically parse to 'file:////path/to/resource/'" do
6526
+ @uri = Addressable::URI.heuristic_parse(@input)
6527
+ expect(@uri.to_s).to eq("file:////path/to/resource/")
6528
+ end
6529
+ end
6530
+
6258
6531
  describe Addressable::URI, "when given the input " +
6259
6532
  "'feed://http://example.com'" do
6260
6533
  before do
@@ -6279,6 +6552,44 @@ describe Addressable::URI, "when given the input " +
6279
6552
  end
6280
6553
  end
6281
6554
 
6555
+ describe Addressable::URI, "when given the input: 'user@domain.com'" do
6556
+ before do
6557
+ @input = "user@domain.com"
6558
+ end
6559
+
6560
+ context "for heuristic parse" do
6561
+ it "should remain 'mailto:user@domain.com'" do
6562
+ uri = Addressable::URI.heuristic_parse("mailto:#{@input}")
6563
+ expect(uri.to_s).to eq("mailto:user@domain.com")
6564
+ end
6565
+
6566
+ it "should have a scheme of 'mailto'" do
6567
+ uri = Addressable::URI.heuristic_parse(@input)
6568
+ expect(uri.to_s).to eq("mailto:user@domain.com")
6569
+ expect(uri.scheme).to eq("mailto")
6570
+ end
6571
+
6572
+ it "should remain 'acct:user@domain.com'" do
6573
+ uri = Addressable::URI.heuristic_parse("acct:#{@input}")
6574
+ expect(uri.to_s).to eq("acct:user@domain.com")
6575
+ end
6576
+
6577
+ context "HTTP" do
6578
+ before do
6579
+ @uri = Addressable::URI.heuristic_parse("http://#{@input}/")
6580
+ end
6581
+
6582
+ it "should remain 'http://user@domain.com/'" do
6583
+ expect(@uri.to_s).to eq("http://user@domain.com/")
6584
+ end
6585
+
6586
+ it "should have the username 'user' for HTTP basic authentication" do
6587
+ expect(@uri.user).to eq("user")
6588
+ end
6589
+ end
6590
+ end
6591
+ end
6592
+
6282
6593
  describe Addressable::URI, "when assigning query values" do
6283
6594
  before do
6284
6595
  @uri = Addressable::URI.new
@@ -6290,54 +6601,54 @@ describe Addressable::URI, "when assigning query values" do
6290
6601
  end
6291
6602
 
6292
6603
  it "should raise an error attempting to assign {'a' => {'b' => ['c']}}" do
6293
- expect(lambda do
6604
+ expect do
6294
6605
  @uri.query_values = { 'a' => {'b' => ['c'] } }
6295
- end).to raise_error(TypeError)
6606
+ end.to raise_error(TypeError)
6296
6607
  end
6297
6608
 
6298
6609
  it "should raise an error attempting to assign " +
6299
6610
  "{:b => '2', :a => {:c => '1'}}" do
6300
- expect(lambda do
6611
+ expect do
6301
6612
  @uri.query_values = {:b => '2', :a => {:c => '1'}}
6302
- end).to raise_error(TypeError)
6613
+ end.to raise_error(TypeError)
6303
6614
  end
6304
6615
 
6305
6616
  it "should raise an error attempting to assign " +
6306
6617
  "{:a => 'a', :b => [{:c => 'c', :d => 'd'}, " +
6307
6618
  "{:e => 'e', :f => 'f'}]}" do
6308
- expect(lambda do
6619
+ expect do
6309
6620
  @uri.query_values = {
6310
6621
  :a => "a", :b => [{:c => "c", :d => "d"}, {:e => "e", :f => "f"}]
6311
6622
  }
6312
- end).to raise_error(TypeError)
6623
+ end.to raise_error(TypeError)
6313
6624
  end
6314
6625
 
6315
6626
  it "should raise an error attempting to assign " +
6316
6627
  "{:a => 'a', :b => [{:c => true, :d => 'd'}, " +
6317
6628
  "{:e => 'e', :f => 'f'}]}" do
6318
- expect(lambda do
6629
+ expect do
6319
6630
  @uri.query_values = {
6320
6631
  :a => 'a', :b => [{:c => true, :d => 'd'}, {:e => 'e', :f => 'f'}]
6321
6632
  }
6322
- end).to raise_error(TypeError)
6633
+ end.to raise_error(TypeError)
6323
6634
  end
6324
6635
 
6325
6636
  it "should raise an error attempting to assign " +
6326
6637
  "{:a => 'a', :b => {:c => true, :d => 'd'}}" do
6327
- expect(lambda do
6638
+ expect do
6328
6639
  @uri.query_values = {
6329
6640
  :a => 'a', :b => {:c => true, :d => 'd'}
6330
6641
  }
6331
- end).to raise_error(TypeError)
6642
+ end.to raise_error(TypeError)
6332
6643
  end
6333
6644
 
6334
6645
  it "should raise an error attempting to assign " +
6335
6646
  "{:a => 'a', :b => {:c => true, :d => 'd'}}" do
6336
- expect(lambda do
6647
+ expect do
6337
6648
  @uri.query_values = {
6338
6649
  :a => 'a', :b => {:c => true, :d => 'd'}
6339
6650
  }
6340
- end).to raise_error(TypeError)
6651
+ end.to raise_error(TypeError)
6341
6652
  end
6342
6653
 
6343
6654
  it "should correctly assign {:a => 1, :b => 1.5}" do
@@ -6348,13 +6659,13 @@ describe Addressable::URI, "when assigning query values" do
6348
6659
  it "should raise an error attempting to assign " +
6349
6660
  "{:z => 1, :f => [2, {999.1 => [3,'4']}, ['h', 'i']], " +
6350
6661
  ":a => {:b => ['c', 'd'], :e => true, :y => 0.5}}" do
6351
- expect(lambda do
6662
+ expect do
6352
6663
  @uri.query_values = {
6353
6664
  :z => 1,
6354
6665
  :f => [ 2, {999.1 => [3,'4']}, ['h', 'i'] ],
6355
6666
  :a => { :b => ['c', 'd'], :e => true, :y => 0.5 }
6356
6667
  }
6357
- end).to raise_error(TypeError)
6668
+ end.to raise_error(TypeError)
6358
6669
  end
6359
6670
 
6360
6671
  it "should correctly assign {}" do
@@ -6404,7 +6715,7 @@ describe Addressable::URI, "when assigning path values" do
6404
6715
  @uri.path = "acct:bob@sporkmonger.com"
6405
6716
  expect(@uri.path).to eq("acct:bob@sporkmonger.com")
6406
6717
  expect(@uri.normalize.to_str).to eq("acct%2Fbob@sporkmonger.com")
6407
- expect(lambda { @uri.to_s }).to raise_error(
6718
+ expect { @uri.to_s }.to raise_error(
6408
6719
  Addressable::URI::InvalidURIError
6409
6720
  )
6410
6721
  end
@@ -6422,26 +6733,26 @@ describe Addressable::URI, "when assigning path values" do
6422
6733
  end
6423
6734
 
6424
6735
  it "should not allow relative paths to be assigned on absolute URIs" do
6425
- expect(lambda do
6736
+ expect do
6426
6737
  @uri.scheme = "http"
6427
6738
  @uri.host = "example.com"
6428
6739
  @uri.path = "acct:bob@sporkmonger.com"
6429
- end).to raise_error(Addressable::URI::InvalidURIError)
6740
+ end.to raise_error(Addressable::URI::InvalidURIError)
6430
6741
  end
6431
6742
 
6432
6743
  it "should not allow relative paths to be assigned on absolute URIs" do
6433
- expect(lambda do
6744
+ expect do
6434
6745
  @uri.path = "acct:bob@sporkmonger.com"
6435
6746
  @uri.scheme = "http"
6436
6747
  @uri.host = "example.com"
6437
- end).to raise_error(Addressable::URI::InvalidURIError)
6748
+ end.to raise_error(Addressable::URI::InvalidURIError)
6438
6749
  end
6439
6750
 
6440
6751
  it "should not allow relative paths to be assigned on absolute URIs" do
6441
- expect(lambda do
6752
+ expect do
6442
6753
  @uri.path = "uuid:0b3ecf60-3f93-11df-a9c3-001f5bfffe12"
6443
6754
  @uri.scheme = "urn"
6444
- end).not_to raise_error
6755
+ end.not_to raise_error
6445
6756
  end
6446
6757
  end
6447
6758
 
@@ -6470,3 +6781,74 @@ describe Addressable::URI, "when initializing a subclass of Addressable::URI" do
6470
6781
  expect(@uri.class).to eq(@uri.join('path').class)
6471
6782
  end
6472
6783
  end
6784
+
6785
+ describe Addressable::URI, "support serialization roundtrip" do
6786
+ before do
6787
+ @uri = Addressable::URI.new(
6788
+ :scheme => "http",
6789
+ :user => "user",
6790
+ :password => "password",
6791
+ :host => "example.com",
6792
+ :port => 80,
6793
+ :path => "/path",
6794
+ :query => "query=value",
6795
+ :fragment => "fragment"
6796
+ )
6797
+ end
6798
+
6799
+ it "is in a working state after being serialized with Marshal" do
6800
+ @uri = Addressable::URI.parse("http://example.com")
6801
+ cloned_uri = Marshal.load(Marshal.dump(@uri))
6802
+ expect(cloned_uri.normalized_scheme).to be == @uri.normalized_scheme
6803
+ end
6804
+
6805
+ it "is in a working state after being serialized with YAML" do
6806
+ @uri = Addressable::URI.parse("http://example.com")
6807
+ cloned_uri = if YAML.respond_to?(:unsafe_load)
6808
+ YAML.unsafe_load(YAML.dump(@uri))
6809
+ else
6810
+ YAML.load(YAML.dump(@uri))
6811
+ end
6812
+ expect(cloned_uri.normalized_scheme).to be == @uri.normalized_scheme
6813
+ end
6814
+ end
6815
+
6816
+ describe Addressable::URI, "when initialized in a non-main `Ractor`" do
6817
+ it "should have the same value as if used in the main `Ractor`" do
6818
+ pending("Ruby 3.0+ for `Ractor` support") unless defined?(Ractor)
6819
+ value_method = RUBY_VERSION >= "3.5.0" ? :value : :take # see https://github.com/ruby/ruby/pull/13445
6820
+ main = Addressable::URI.parse("http://example.com")
6821
+ expect(
6822
+ Ractor.new { Addressable::URI.parse("http://example.com") }.public_send(value_method)
6823
+ ).to eq(main)
6824
+ end
6825
+ end
6826
+
6827
+ describe Addressable::URI, "when deferring validation" do
6828
+ subject(:deferred) { uri.instance_variable_get(:@validation_deferred) }
6829
+
6830
+ let(:uri) { Addressable::URI.parse("http://example.com") }
6831
+
6832
+ it "defers validation within the block" do
6833
+ uri.defer_validation do
6834
+ expect(deferred).to be true
6835
+ end
6836
+ end
6837
+
6838
+ it "always resets deferral afterward" do
6839
+ expect { uri.defer_validation { raise "boom" } }.to raise_error("boom")
6840
+ expect(deferred).to be false
6841
+ end
6842
+
6843
+ it "returns nil" do
6844
+ res = uri.defer_validation {}
6845
+ expect(res).to be nil
6846
+ end
6847
+ end
6848
+
6849
+ describe Addressable::URI, "YAML safe loading" do
6850
+ it "doesn't serialize anonymous objects" do
6851
+ url = Addressable::URI.parse("http://example.com/")
6852
+ expect(YAML.dump(url)).to_not include("!ruby/object {}")
6853
+ end
6854
+ end