furi 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,16 @@
1
+
2
+ module Furi
3
+ class Utils
4
+ class << self
5
+ def stringify_keys(hash)
6
+ result = {}
7
+ hash.each_key do |key|
8
+ value = hash[key]
9
+ result[key.to_s] = value.is_a?(Hash) ? stringify_keys(value) : value
10
+ end
11
+ result
12
+ end
13
+ end
14
+ end
15
+ end
16
+
@@ -1,3 +1,3 @@
1
1
  module Furi
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -65,20 +65,62 @@ describe Furi do
65
65
 
66
66
 
67
67
  describe "#parse" do
68
+
69
+ it "parses URL with everything" do
70
+ expect("http://user:pass@www.gusiev.com:8080/articles/index.html?a=1&b=2#header").to have_parts(
71
+ location: 'http://user:pass@www.gusiev.com:8080',
72
+ protocol: 'http',
73
+ schema: 'http',
74
+ authority: 'user:pass@www.gusiev.com:8080',
75
+ hostinfo: 'www.gusiev.com:8080',
76
+ host: 'www.gusiev.com',
77
+ subdomain: 'www',
78
+ domain: 'gusiev.com',
79
+ domainzone: 'com',
80
+ port: 8080,
81
+ userinfo: 'user:pass',
82
+ username: 'user',
83
+ password: 'pass',
84
+
85
+ resource: '/articles/index.html?a=1&b=2#header',
86
+ path: "/articles/index.html",
87
+ filename: 'index.html',
88
+ extension: 'html',
89
+ query_string: "a=1&b=2",
90
+ query_tokens: [['a', '1'], ['b', '2']],
91
+ query: {'a' => '1', 'b' => '2'},
92
+ request: '/articles/index.html?a=1&b=2',
93
+ anchor: 'header',
94
+ fragment: 'header',
95
+ home_page?: false,
96
+ )
97
+
98
+ end
68
99
  it "parses URL without path" do
69
100
  expect("http://gusiev.com").to have_parts(
70
101
  protocol: 'http',
71
102
  hostname: 'gusiev.com',
72
- query_string: "",
103
+ query_string: nil,
73
104
  query: {},
74
105
  path: nil,
75
106
  path!: '/',
76
107
  port: nil,
77
108
  request: '/',
78
109
  resource: '/',
110
+ location: 'http://gusiev.com',
111
+ home_page?: true,
79
112
  )
80
113
  end
81
114
 
115
+ it "parses URL with root path" do
116
+ expect("http://gusiev.com/?a=b").to have_parts(
117
+ hostname: 'gusiev.com',
118
+ path: '/',
119
+ path!: '/',
120
+ request: '/?a=b',
121
+ home_page?: true,
122
+ )
123
+ end
82
124
  it "extracts anchor" do
83
125
  expect("http://gusiev.com/posts/index.html?a=b#zz").to have_parts(
84
126
  anchor: 'zz',
@@ -88,6 +130,9 @@ describe Furi do
88
130
  protocol: 'http',
89
131
  resource: '/posts/index.html?a=b#zz',
90
132
  request: '/posts/index.html?a=b',
133
+ location: 'http://gusiev.com',
134
+ filename: 'index.html',
135
+ extension: 'html',
91
136
  )
92
137
  end
93
138
 
@@ -97,6 +142,21 @@ describe Furi do
97
142
  hostname: nil,
98
143
  port: nil,
99
144
  protocol: nil,
145
+ location: nil,
146
+ extension: 'html',
147
+ home_page?: false,
148
+ )
149
+ end
150
+
151
+ it "works with path ending at slash" do
152
+
153
+ expect("/posts/").to have_parts(
154
+ path: '/posts/',
155
+ directory: '/posts',
156
+ filename: nil,
157
+ 'filename!' => '',
158
+ extension: nil,
159
+ home_page?: false,
100
160
  )
101
161
  end
102
162
 
@@ -105,8 +165,9 @@ describe Furi do
105
165
  username: 'user',
106
166
  password: 'pass',
107
167
  hostname: 'gusiev.com',
108
- query_string: "",
168
+ query_string: nil,
109
169
  anchor: nil,
170
+ location: 'http://user:pass@gusiev.com',
110
171
  )
111
172
  end
112
173
 
@@ -115,16 +176,16 @@ describe Furi do
115
176
  username: 'user',
116
177
  password: nil,
117
178
  hostname: 'gusiev.com',
118
- query_string: "",
179
+ query_string: nil,
119
180
  anchor: nil,
181
+ location: 'http://user@gusiev.com',
120
182
  )
121
183
  end
122
184
 
123
185
 
124
186
  it "supports aliases" do
125
187
  expect("http://gusiev.com#zz").to have_parts(
126
- schema: 'http',
127
- fragment: 'zz',
188
+ location: 'http://gusiev.com',
128
189
  )
129
190
  end
130
191
 
@@ -135,9 +196,19 @@ describe Furi do
135
196
  userinfo: 'user:pass',
136
197
  protocol: 'http',
137
198
  port: 80,
138
- query_string: "",
199
+ query_string: nil,
139
200
  )
140
201
  end
202
+
203
+ it "parses custom port" do
204
+ expect("http://gusiev.com:8080").to have_parts(
205
+ hostname: 'gusiev.com',
206
+ hostinfo: 'gusiev.com:8080',
207
+ protocol: 'http',
208
+ port: 8080,
209
+ )
210
+
211
+ end
141
212
  it "parses url with query" do
142
213
  expect("/index.html?a=b&c=d").to have_parts(
143
214
  host: nil,
@@ -145,6 +216,7 @@ describe Furi do
145
216
  query_string: 'a=b&c=d',
146
217
  query: {'a' => 'b', 'c' => 'd'},
147
218
  request: '/index.html?a=b&c=d',
219
+ home_page?: true,
148
220
  )
149
221
  end
150
222
 
@@ -172,9 +244,98 @@ describe Furi do
172
244
  :"ssl" => true
173
245
  )
174
246
  end
247
+
248
+ it "parses host into parts" do
249
+ expect("http://www.gusiev.com.ua").to have_parts(
250
+ domain: 'gusiev.com.ua',
251
+ subdomain: 'www',
252
+ domainname: 'gusiev',
253
+ domainzone: 'com.ua'
254
+ )
255
+ expect("http://www.com.ua").to have_parts(
256
+ domain: 'www.com.ua',
257
+ subdomain: nil,
258
+ domainname: 'www',
259
+ domainzone: 'com.ua'
260
+ )
261
+ expect("http://com.ua").to have_parts(
262
+ domain: 'com.ua',
263
+ subdomain: nil,
264
+ domainname: 'com',
265
+ domainzone: 'ua'
266
+ )
267
+ expect("http://www.blog.gusiev.com.ua").to have_parts(
268
+ domain: 'gusiev.com.ua',
269
+ subdomain: 'www.blog',
270
+ domainname: 'gusiev',
271
+ domainzone: 'com.ua'
272
+ )
273
+ end
274
+
275
+ it "parses double # in anchor" do
276
+ expect("/index?a=1#c#d").to have_parts(
277
+ anchor: 'c#d',
278
+ query_string: "a=1",
279
+ path: '/index',
280
+ )
281
+ end
282
+ it "parses blank port with protocol" do
283
+ expect("http://gusiev.com:/hello").to have_parts(
284
+ path: '/hello',
285
+ port: nil,
286
+ host: 'gusiev.com',
287
+ protocol: 'http',
288
+ )
289
+ end
290
+ it "parses blank port without protocol" do
291
+ expect("gusiev.com:/hello").to have_parts(
292
+ path: '/hello',
293
+ port: nil,
294
+ host: 'gusiev.com',
295
+ protocol: nil,
296
+ )
297
+ end
298
+
299
+ it "parses 0 port as blank port" do
300
+ expect("http://gusiev.com:0/hello").to have_parts(
301
+ path: '/hello',
302
+ port: 0,
303
+ host: 'gusiev.com',
304
+ protocol: 'http',
305
+ )
306
+ end
307
+
308
+ describe "ipv6 host" do
309
+ it "parses host and port" do
310
+ expect("http://[2406:da00:ff00::6b14:8d43]:8080/").to have_parts(
311
+ path: '/',
312
+ port: 8080,
313
+ host: '[2406:da00:ff00::6b14:8d43]',
314
+ protocol: 'http',
315
+ )
316
+ end
317
+ it "parses host and nil port" do
318
+
319
+ expect("http://[2406:da00:ff00::6b14:8d43]:/hello").to have_parts(
320
+ path: '/hello',
321
+ port: nil,
322
+ host: '[2406:da00:ff00::6b14:8d43]',
323
+ protocol: 'http',
324
+ )
325
+ end
326
+
327
+ it "parses host without protocol and port" do
328
+ expect("[2406:da00:ff00::6b14:8d43]/hello").to have_parts(
329
+ path: '/hello',
330
+ port: nil,
331
+ host: '[2406:da00:ff00::6b14:8d43]',
332
+ protocol: nil,
333
+ )
334
+ end
335
+ end
175
336
  end
176
337
  describe ".update" do
177
-
338
+
178
339
  it "support update for query" do
179
340
  expect(Furi.update("/index.html?a=b", query: {c: 'd'})).to eq('/index.html?c=d')
180
341
  end
@@ -193,6 +354,47 @@ describe Furi do
193
354
  expect(Furi.update("gusiev.com/index.html", port: 33)).to eq('gusiev.com:33/index.html')
194
355
  expect(Furi.update("gusiev.com:33/index.html", port: 80)).to eq('gusiev.com:80/index.html')
195
356
  expect(Furi.update("http://gusiev.com:33/index.html", port: 80)).to eq('http://gusiev.com/index.html')
357
+ expect(Furi.update("http://gusiev.com:33/index.html", port: nil)).to eq('http://gusiev.com/index.html')
358
+ expect(Furi.update("http://gusiev.com:33/index.html", port: 0)).to eq('http://gusiev.com:0/index.html')
359
+ expect(Furi.update("http://gusiev.com:33/index.html", port: '')).to eq('http://gusiev.com/index.html')
360
+ end
361
+ it "updates directory" do
362
+ expect(Furi.update("gusiev.com", directory: 'articles')).to eq('gusiev.com/articles')
363
+ expect(Furi.update("gusiev.com/", directory: 'articles')).to eq('gusiev.com/articles')
364
+ expect(Furi.update("gusiev.com/index#header", directory: '/posts')).to eq('gusiev.com/posts/index#header')
365
+ expect(Furi.update("gusiev.com/articles/#header", directory: nil)).to eq('gusiev.com/#header')
366
+ expect(Furi.update("gusiev.com/articles/index?a=b", directory: 'posts')).to eq('gusiev.com/posts/index?a=b')
367
+ expect(Furi.update("/articles/index?a=b", directory: '/posts')).to eq('/posts/index?a=b')
368
+ expect(Furi.update("/articles/index.html?a=b", directory: '/posts/')).to eq('/posts/index.html?a=b')
369
+ end
370
+ it "updates filename" do
371
+ expect(Furi.update("gusiev.com", filename: 'article')).to eq('gusiev.com/article')
372
+ expect(Furi.update("gusiev.com/", filename: 'article')).to eq('gusiev.com/article')
373
+ expect(Furi.update("gusiev.com/article1#header", filename: '/article2')).to eq('gusiev.com/article2#header')
374
+ expect(Furi.update("gusiev.com/article#header", filename: nil)).to eq('gusiev.com/#header')
375
+ expect(Furi.update("gusiev.com/articles/article1?a=b", filename: 'article2')).to eq('gusiev.com/articles/article2?a=b')
376
+ expect(Furi.update("/articles/article1?a=b", filename: '/article2')).to eq('/articles/article2?a=b')
377
+ expect(Furi.update("/articles/article1.xml?a=b", filename: 'article2.html')).to eq('/articles/article2.html?a=b')
378
+ end
379
+ it "updates extension" do
380
+ expect(->{
381
+ Furi.update("gusiev.com/", extension: 'xml')
382
+ }).to raise_error(Furi::FormattingError)
383
+ expect(Furi.update("gusiev.com/article#header", extension: 'html')).to eq('gusiev.com/article.html#header')
384
+ expect(Furi.update("gusiev.com/article.html?header", extension: nil)).to eq('gusiev.com/article?header')
385
+ expect(Furi.update("gusiev.com/article.xml?a=b", extension: 'html')).to eq('gusiev.com/article.html?a=b')
386
+ end
387
+ it "updates resource" do
388
+ expect(Furi.update("gusiev.com", resource: '/article?a=1#hello')).to eq('gusiev.com/article?a=1#hello')
389
+ expect(Furi.update("gusiev.com/article1#header", resource: '/article2')).to eq('gusiev.com/article2')
390
+ expect(Furi.update("gusiev.com/article#header", resource: nil)).to eq('gusiev.com')
391
+ expect(Furi.update("gusiev.com/article1?a=b", resource: 'article2')).to eq('gusiev.com/article2')
392
+ end
393
+ it "updates path" do
394
+ expect(Furi.update("gusiev.com", path: '/article')).to eq('gusiev.com/article')
395
+ expect(Furi.update("gusiev.com/article1#header", path: '/article2')).to eq('gusiev.com/article2#header')
396
+ expect(Furi.update("gusiev.com/article#header", path: nil)).to eq('gusiev.com#header')
397
+ expect(Furi.update("gusiev.com/article1?a=b", path: 'article2')).to eq('gusiev.com/article2?a=b')
196
398
  end
197
399
 
198
400
  it "updates ssl" do
@@ -201,6 +403,7 @@ describe Furi do
201
403
  expect(Furi.update("https://gusiev.com", ssl: false)).to eq('http://gusiev.com')
202
404
  expect(Furi.update("http://gusiev.com", ssl: false)).to eq('http://gusiev.com')
203
405
  end
406
+
204
407
  it "updates protocol" do
205
408
  expect(Furi.update("http://gusiev.com", protocol: '')).to eq('//gusiev.com')
206
409
  expect(Furi.update("http://gusiev.com", protocol: nil)).to eq('gusiev.com')
@@ -211,6 +414,44 @@ describe Furi do
211
414
  expect(Furi.update("gusiev.com", protocol: 'http://')).to eq('http://gusiev.com')
212
415
  end
213
416
 
417
+ it "updates userinfo" do
418
+ expect(Furi.update("http://gusiev.com", userinfo: 'hello:world')).to eq('http://hello:world@gusiev.com')
419
+ expect(Furi.update("http://aa:bb@gusiev.com", userinfo: 'hello:world')).to eq('http://hello:world@gusiev.com')
420
+ expect(Furi.update("http://aa:bb@gusiev.com", userinfo: nil)).to eq('http://gusiev.com')
421
+ expect(Furi.update("http://aa@gusiev.com", userinfo: 'hello:world')).to eq('http://hello:world@gusiev.com')
422
+ end
423
+
424
+ it "updates authority" do
425
+ expect(Furi.update("http://user:pass@gusiev.com:8080/index.html", authority: 'gusiev.com')).to eq('http://gusiev.com/index.html')
426
+ end
427
+
428
+ it "updates request" do
429
+ expect(Furi.update("http://gusiev.com:8080/index.html?c=d", request: '/blog.html?a=b')).to eq('http://gusiev.com:8080/blog.html?a=b')
430
+ end
431
+
432
+ it "updates domainzone" do
433
+ expect(Furi.update("http://gusiev.com:8080", domainzone: 'com.ua')).to eq('http://gusiev.com.ua:8080')
434
+ expect(Furi.update("http://gusiev.com.ua:8080", domainzone: 'com')).to eq('http://gusiev.com:8080')
435
+ expect(Furi.update("http://gusiev.com.ua:8080", domainzone: nil)).to eq('http://gusiev:8080')
436
+ end
437
+
438
+ it "updates domainname" do
439
+ expect(Furi.update("http://gusiev.com", domainname: 'google')).to eq('http://google.com')
440
+ expect(Furi.update("http://gusiev.com", domainname: nil)).to eq('http://com')
441
+ end
442
+ it "updates subdomain" do
443
+ expect(Furi.update("http://gusiev.com", subdomain: 'blog')).to eq('http://blog.gusiev.com')
444
+ expect(Furi.update("http://blog.gusiev.com", subdomain: nil)).to eq('http://gusiev.com')
445
+ end
446
+
447
+ it "updates location" do
448
+ expect(Furi.update("/index.html", location: 'http://gusiev.com')).to eq('http://gusiev.com/index.html')
449
+ expect(Furi.update("/index.html", location: 'http://gusiev.com/')).to eq('http://gusiev.com/index.html')
450
+ expect(Furi.update("gusiev.com:433/index.html", location: 'gusiev.com:80')).to eq('gusiev.com:80/index.html')
451
+ expect(Furi.update("gusiev.com:433/index.html", location: nil)).to eq('/index.html')
452
+ expect(Furi.update("http://gusiev.com:433/index.html", location: nil)).to eq('/index.html')
453
+ end
454
+
214
455
  end
215
456
 
216
457
  describe ".build" do
@@ -221,6 +462,18 @@ describe Furi do
221
462
  expect(Furi.build(schema: 'https', hostname: 'hello.com', port: 88)).to eq('https://hello.com:88')
222
463
  expect(Furi.build(schema: 'http', hostname: 'hello.com', port: 80)).to eq('http://hello.com')
223
464
  expect(Furi.build(path: '/index.html', query: {a: 1, b: 2})).to eq('/index.html?a=1&b=2')
465
+ expect(Furi.build(path: '/', host: 'gusiev.com', query: {a: 1})).to eq('gusiev.com/?a=1')
466
+ expect(Furi.build(path: '/articles/', host: 'gusiev.com', query: {a: 1})).to eq('gusiev.com/articles/?a=1')
467
+ expect(Furi.build(user: 'user', hostname: 'hello.com')).to eq('user@hello.com')
468
+ expect(Furi.build(protocol: 'http', host: 'hello.com', port: 80)).to eq('http://hello.com')
469
+ expect(Furi.build(query: 'a=b')).to eq('/?a=b')
470
+
471
+ expect(->{
472
+ Furi.build(host: nil, port: 80)
473
+ }).to raise_error(Furi::FormattingError)
474
+ expect(->{
475
+ Furi.build(host: 'localhost', password: 'pass')
476
+ }).to raise_error(Furi::FormattingError)
224
477
  end
225
478
  end
226
479
 
@@ -234,6 +487,27 @@ describe Furi do
234
487
  end
235
488
  end
236
489
 
490
+ describe ".defaults" do
491
+ it "should set protocol" do
492
+ expect(Furi.defaults("gusiev.com", protocol: 'http')).to eq('http://gusiev.com')
493
+ expect(Furi.defaults("gusiev.com", protocol: '//')).to eq('//gusiev.com')
494
+ expect(Furi.defaults("//gusiev.com", protocol: 'http')).to eq('//gusiev.com')
495
+ expect(Furi.defaults("https://gusiev.com", protocol: 'http')).to eq('https://gusiev.com')
496
+ end
497
+ it "should set host" do
498
+ expect(Furi.defaults("https://gusiev.com", subdomain: 'www')).to eq('https://www.gusiev.com')
499
+ expect(Furi.defaults("https://blog.gusiev.com", subdomain: 'www')).to eq('https://blog.gusiev.com')
500
+ expect(Furi.defaults("/index.html", host: 'gusiev.com', protocol: 'http')).to eq('http://gusiev.com/index.html')
501
+ end
502
+ it "should set query" do
503
+ expect(Furi.defaults("gusiev.com?a=1", query: {a: 2})).to eq('gusiev.com?a=1')
504
+ expect(Furi.defaults("gusiev.com?a=1", query: {b: 2})).to eq('gusiev.com?a=1&b=2')
505
+ expect(Furi.defaults("//gusiev.com?a=1", query_string: 'b=2')).to eq('//gusiev.com?a=1')
506
+ expect(Furi.defaults("//gusiev.com", query_string: 'b=2')).to eq('//gusiev.com?b=2')
507
+ expect(Furi.defaults("//gusiev.com?a=1&b=2", query: '?a=3')).to eq('//gusiev.com?a=1&b=2')
508
+ end
509
+ end
510
+
237
511
  describe "#==" do
238
512
  it "should work" do
239
513
  expect(Furi.parse('http://gusiev.com:80') == Furi.parse('http://gusiev.com')).to be_truthy
@@ -241,6 +515,8 @@ describe Furi do
241
515
  expect(Furi.parse('http://gusiev.com') == Furi.parse('http://gusiev.com')).to be_truthy
242
516
  expect(Furi.parse('http://gusiev.com.ua') == Furi.parse('http://gusiev.com')).to be_falsey
243
517
  expect(Furi.parse('http://gusiev.com?a=1&a=1') == Furi.parse('http://gusiev.com?a=1')).to be_falsey
518
+ pending
519
+ expect(Furi.parse('http://gUSiev.cOm?A=1') == Furi.parse('http://gusiev.com?a=1')).to be_truthy
244
520
  end
245
521
  end
246
522
 
@@ -250,17 +526,13 @@ describe Furi do
250
526
  uri = Furi.parse('http://gusiev.com')
251
527
  expect(uri.clone == uri).to be_truthy
252
528
  expect(uri.clone.merge_query([[:a, 1]]) == uri).to be_falsey
253
- expect(Furi.parse('http://gusiev.com') == Furi.parse('https://gusiev.com')).to be_falsey
254
- expect(Furi.parse('http://gusiev.com') == Furi.parse('http://gusiev.com')).to be_truthy
255
- expect(Furi.parse('http://gusiev.com.ua') == Furi.parse('http://gusiev.com')).to be_falsey
256
- expect(Furi.parse('http://gusiev.com?a=1&a=1') == Furi.parse('http://gusiev.com?a=1')).to be_falsey
257
529
  end
258
530
  end
259
531
 
260
532
  describe "serialize" do
261
533
  it "should work" do
262
534
  expect({a: 'b'}).to serialize_as("a=b")
263
- expect(a: nil).to serialize_as("a=")
535
+ expect(a: nil).to serialize_as("a")
264
536
  expect(nil).to serialize_as("")
265
537
  expect(b: 2, a: 1).to serialize_as("b=2&a=1")
266
538
  expect(a: {b: {c: []}}).to serialize_as("")
@@ -270,7 +542,7 @@ describe Furi do
270
542
  expect(q: "cowboy hat?").to serialize_as("q=cowboy+hat%3F")
271
543
  expect(a: true).to serialize_as("a=true")
272
544
  expect(a: false).to serialize_as("a=false")
273
- expect(a: [nil, 0]).to serialize_as("a%5B%5D=&a%5B%5D=0")
545
+ expect(a: [nil, 0]).to serialize_as("a%5B%5D&a%5B%5D=0")
274
546
  expect({f: ["b", 42, "your base"] }).to serialize_as("f%5B%5D=b&f%5B%5D=42&f%5B%5D=your+base")
275
547
  expect({"a[]" => 1 }).to serialize_as("a%5B%5D=1")
276
548
  expect({"a[b]" => [1] }).to serialize_as(["a[b][]=1"])
@@ -291,85 +563,106 @@ describe Furi do
291
563
  end
292
564
  end
293
565
 
294
- describe "parse_nested_query" do
566
+ describe ".query_tokens" do
295
567
  it "should work" do
296
- Furi.parse_nested_query("foo").
568
+ Furi.query_tokens("a=1").should eq [['a', 1]]
569
+ Furi.query_tokens("a==").should eq [['a', '=']]
570
+ Furi.query_tokens("a==1").should eq [['a', '=1']]
571
+ Furi.query_tokens("a=1&").should eq [['a', 1], ["", nil]]
572
+ Furi.query_tokens("&a=1").should eq [["", nil], ['a', 1]]
573
+ Furi.query_tokens("=").should eq [["", ""], ]
574
+ Furi.query_tokens(" ").should eq [[" ", nil], ]
575
+ Furi.query_tokens(" =").should eq [[" ", ''], ]
576
+ Furi.query_tokens("= ").should eq [["", ' '], ]
577
+ Furi.query_tokens("a=1&b").should eq [['a', 1], ["b", nil]]
578
+ Furi.query_tokens("a=&b").should eq [['a', ''], ['b', nil]]
579
+ Furi.query_tokens("a=1&b=2").should eq [['a', 1], ['b', 2]]
580
+ end
581
+ end
582
+
583
+ describe "parse_query" do
584
+ it "should work" do
585
+ Furi.parse_query("foo").
297
586
  should eq "foo" => nil
298
- Furi.parse_nested_query("foo=").
587
+ Furi.parse_query("foo=").
299
588
  should eq "foo" => ""
300
- Furi.parse_nested_query("foo=bar").
589
+ Furi.parse_query("foo=bar").
301
590
  should eq "foo" => "bar"
302
- Furi.parse_nested_query("foo=\"bar\"").
591
+ Furi.parse_query("foo=\"bar\"").
303
592
  should eq "foo" => "\"bar\""
304
593
 
305
- Furi.parse_nested_query("foo=bar&foo=quux").
594
+ Furi.parse_query("foo=bar&foo=quux").
306
595
  should eq "foo" => "quux"
307
- Furi.parse_nested_query("foo&foo=").
596
+ Furi.parse_query("foo&foo=").
308
597
  should eq "foo" => ""
309
- Furi.parse_nested_query("foo=1&bar=2").
598
+ Furi.parse_query("foo=1&bar=2").
310
599
  should eq "foo" => "1", "bar" => "2"
311
- Furi.parse_nested_query("&foo=1&&bar=2").
600
+ Furi.parse_query("&foo=1&&bar=2").
312
601
  should eq "foo" => "1", "bar" => "2"
313
- Furi.parse_nested_query("foo&bar=").
602
+ Furi.parse_query("foo&bar=").
314
603
  should eq "foo" => nil, "bar" => ""
315
- Furi.parse_nested_query("foo=bar&baz=").
604
+ Furi.parse_query("foo=bar&baz=").
316
605
  should eq "foo" => "bar", "baz" => ""
317
- Furi.parse_nested_query("my+weird+field=q1%212%22%27w%245%267%2Fz8%29%3F").
606
+ Furi.parse_query("my+weird+field=q1%212%22%27w%245%267%2Fz8%29%3F").
318
607
  should eq "my weird field" => "q1!2\"'w$5&7/z8)?"
319
608
 
320
- Furi.parse_nested_query("a=b&pid%3D1234=1023").
609
+ Furi.parse_query("a=b&pid%3D1234=1023").
321
610
  should eq "pid=1234" => "1023", "a" => "b"
322
611
 
323
- Furi.parse_nested_query("foo[]").
612
+ Furi.parse_query("foo[]").
324
613
  should eq "foo" => [nil]
325
- Furi.parse_nested_query("foo[]=").
614
+ Furi.parse_query("foo[]=").
326
615
  should eq "foo" => [""]
327
- Furi.parse_nested_query("foo[]=bar").
616
+ Furi.parse_query("foo[]=bar").
328
617
  should eq "foo" => ["bar"]
329
618
 
330
- Furi.parse_nested_query("foo[]=1&foo[]=2").
619
+ Furi.parse_query("foo[]=1&foo[]=2").
331
620
  should eq "foo" => ["1", "2"]
332
- Furi.parse_nested_query("foo=bar&baz[]=1&baz[]=2&baz[]=3").
621
+ Furi.parse_query("foo=bar&baz[]=1&baz[]=2&baz[]=3").
333
622
  should eq "foo" => "bar", "baz" => ["1", "2", "3"]
334
- Furi.parse_nested_query("foo[]=bar&baz[]=1&baz[]=2&baz[]=3").
623
+ Furi.parse_query("foo[]=bar&baz[]=1&baz[]=2&baz[]=3").
335
624
  should eq "foo" => ["bar"], "baz" => ["1", "2", "3"]
336
625
 
337
- Furi.parse_nested_query("x[y][z]=1").
626
+ Furi.parse_query("x[y][z]=1").
338
627
  should eq "x" => {"y" => {"z" => "1"}}
339
- Furi.parse_nested_query("x[y][z][]=1").
628
+ Furi.parse_query("x[y][z][]=1").
340
629
  should eq "x" => {"y" => {"z" => ["1"]}}
341
- Furi.parse_nested_query("x[y][z]=1&x[y][z]=2").
630
+ Furi.parse_query("x[y][z]=1&x[y][z]=2").
342
631
  should eq "x" => {"y" => {"z" => "2"}}
343
- Furi.parse_nested_query("x[y][z][]=1&x[y][z][]=2").
632
+ Furi.parse_query("x[y][z][]=1&x[y][z][]=2").
344
633
  should eq "x" => {"y" => {"z" => ["1", "2"]}}
345
634
 
346
- Furi.parse_nested_query("x[y][][z]=1").
635
+ Furi.parse_query("x[y][][z]=1").
347
636
  should eq "x" => {"y" => [{"z" => "1"}]}
348
- Furi.parse_nested_query("x[y][][z][]=1").
637
+ Furi.parse_query("x[y][][z][]=1").
349
638
  should eq "x" => {"y" => [{"z" => ["1"]}]}
350
- Furi.parse_nested_query("x[y][][z]=1&x[y][][w]=2").
639
+ Furi.parse_query("x[y][][z]=1&x[y][][w]=2").
351
640
  should eq "x" => {"y" => [{"z" => "1", "w" => "2"}]}
352
641
 
353
- Furi.parse_nested_query("x[y][][v][w]=1").
642
+ Furi.parse_query("x[y][][v][w]=1").
354
643
  should eq "x" => {"y" => [{"v" => {"w" => "1"}}]}
355
- Furi.parse_nested_query("x[y][][z]=1&x[y][][v][w]=2").
644
+ Furi.parse_query("x[y][][z]=1&x[y][][v][w]=2").
356
645
  should eq "x" => {"y" => [{"z" => "1", "v" => {"w" => "2"}}]}
357
646
 
358
- Furi.parse_nested_query("x[y][][z]=1&x[y][][z]=2").
647
+ Furi.parse_query("x[y][][z]=1&x[y][][z]=2").
359
648
  should eq "x" => {"y" => [{"z" => "1"}, {"z" => "2"}]}
360
- Furi.parse_nested_query("x[y][][z]=1&x[y][][w]=a&x[y][][z]=2&x[y][][w]=3").
649
+ Furi.parse_query("x[y][][z]=1&x[y][][w]=a&x[y][][z]=2&x[y][][w]=3").
361
650
  should eq "x" => {"y" => [{"z" => "1", "w" => "a"}, {"z" => "2", "w" => "3"}]}
362
651
 
363
- lambda { Furi.parse_nested_query("x[y]=1&x[y]z=2") }.
652
+ lambda { Furi.parse_query("x[y]=1&x[y]z=2") }.
364
653
  should raise_error(TypeError, "expected Hash (got String) for param `y'")
365
654
 
366
- lambda { Furi.parse_nested_query("x[y]=1&x[]=1") }.
655
+ lambda { Furi.parse_query("x[y]=1&x[]=1") }.
367
656
  should raise_error(TypeError, /expected Array \(got [^)]*\) for param `x'/)
368
657
 
369
- lambda { Furi.parse_nested_query("x[y]=1&x[y][][w]=2") }.
658
+ lambda { Furi.parse_query("x[y]=1&x[y][][w]=2") }.
370
659
  should raise_error(TypeError, "expected Array (got String) for param `y'")
371
660
  end
372
661
 
373
662
  end
374
663
 
664
+ it "should support inspect" do
665
+ expect(Furi.parse('http://google.com').inspect).to eq("#<Furi::Uri \"http://google.com\">")
666
+ end
667
+
375
668
  end