furi 0.0.2 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +11 -0
- data/lib/furi.rb +184 -64
- data/lib/furi/version.rb +1 -1
- data/spec/furi_spec.rb +71 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62a4088dd18cb4ac9857d1512d78497ea28edd82
|
4
|
+
data.tar.gz: 3603fa3688b41b7b2ba700676db29f930bb11bf3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 762e38c65d27a36323bf0ed410b25633e95788ce10a8a97163195918a47e038610defe4fe8f7f5b635d554c42b09cc3c5d4fbc1974dee9ec5d4e645d646923c1
|
7
|
+
data.tar.gz: 59f5e066fb0f09bcac768b99b11589d4257f391352e27d4d6874c2ae1d2d783f8bc56fde491906669b5aed5d22f16c17a8f424cbab486bd2b3123243c7b38873
|
data/Rakefile
CHANGED
data/lib/furi.rb
CHANGED
@@ -4,32 +4,44 @@ require "uri"
|
|
4
4
|
module Furi
|
5
5
|
|
6
6
|
PARTS = [
|
7
|
-
:anchor, :protocol, :
|
8
|
-
:path, :
|
7
|
+
:anchor, :protocol, :query_tokens,
|
8
|
+
:path, :host, :port, :username, :password
|
9
9
|
]
|
10
10
|
ALIASES = {
|
11
|
-
protocol: [:schema],
|
11
|
+
protocol: [:schema, :scheme],
|
12
12
|
anchor: [:fragment],
|
13
|
+
host: [:hostname],
|
14
|
+
username: [:user],
|
13
15
|
}
|
14
16
|
|
15
|
-
DELEGATES = [:port!]
|
16
|
-
|
17
|
-
|
18
|
-
"http" => 80,
|
19
|
-
"https" => 443,
|
20
|
-
"ftp" => 21,
|
21
|
-
"tftp" => 69,
|
22
|
-
"sftp" => 22,
|
23
|
-
"ssh" => 22,
|
24
|
-
"svn+ssh" => 22,
|
25
|
-
"telnet" => 23,
|
26
|
-
"nntp" => 119,
|
27
|
-
"gopher" => 70,
|
28
|
-
"wais" => 210,
|
29
|
-
"ldap" => 389,
|
30
|
-
"prospero" => 1525
|
17
|
+
DELEGATES = [:port!, :host!]
|
18
|
+
|
19
|
+
PROTOCOLS = {
|
20
|
+
"http" => {port: 80, ssl: false},
|
21
|
+
"https" => {port: 443, ssl: true},
|
22
|
+
"ftp" => {port: 21},
|
23
|
+
"tftp" => {port: 69},
|
24
|
+
"sftp" => {port: 22},
|
25
|
+
"ssh" => {port: 22, ssl: true},
|
26
|
+
"svn+ssh" => {port: 22, ssl: true},
|
27
|
+
"telnet" => {port: 23},
|
28
|
+
"nntp" => {port: 119},
|
29
|
+
"gopher" => {port: 70},
|
30
|
+
"wais" => {port: 210},
|
31
|
+
"ldap" => {port: 389},
|
32
|
+
"prospero" => {port: 1525},
|
31
33
|
}
|
32
34
|
|
35
|
+
SSL_MAPPING = {
|
36
|
+
'http' => 'https',
|
37
|
+
'ftp' => 'sftp',
|
38
|
+
'svn' => 'svn+ssh',
|
39
|
+
}
|
40
|
+
|
41
|
+
WEB_PROTOCOL = ['http', 'https']
|
42
|
+
|
43
|
+
ROOT = '/'
|
44
|
+
|
33
45
|
class Expressions
|
34
46
|
attr_accessor :protocol
|
35
47
|
|
@@ -62,6 +74,10 @@ module Furi
|
|
62
74
|
parse(string).update(parts).to_s
|
63
75
|
end
|
64
76
|
|
77
|
+
def self.merge(string, parts)
|
78
|
+
parse(string).merge(parts).to_s
|
79
|
+
end
|
80
|
+
|
65
81
|
def self.serialize_tokens(query, namespace = nil)
|
66
82
|
case query
|
67
83
|
when Hash
|
@@ -107,7 +123,8 @@ module Furi
|
|
107
123
|
end
|
108
124
|
|
109
125
|
def self.query_tokens(query)
|
110
|
-
|
126
|
+
case query
|
127
|
+
when Enumerable, Enumerator
|
111
128
|
query.map do |token|
|
112
129
|
case token
|
113
130
|
when QueryToken
|
@@ -120,10 +137,14 @@ module Furi
|
|
120
137
|
raise ArgumentError, "Can not parse query token #{token.inspect}"
|
121
138
|
end
|
122
139
|
end
|
123
|
-
|
124
|
-
|
140
|
+
when nil, ''
|
141
|
+
[]
|
142
|
+
when String
|
143
|
+
query.gsub(/\A\?/, '').split(/[&;] */n).map do |p|
|
125
144
|
QueryToken.parse(p)
|
126
145
|
end
|
146
|
+
else
|
147
|
+
raise ArgumentError, "Can not parse #{query.inspect} query tokens"
|
127
148
|
end
|
128
149
|
end
|
129
150
|
|
@@ -166,8 +187,8 @@ module Furi
|
|
166
187
|
return params
|
167
188
|
end
|
168
189
|
|
169
|
-
def self.serialize(
|
170
|
-
serialize_tokens(
|
190
|
+
def self.serialize(query, namespace = nil)
|
191
|
+
serialize_tokens(query, namespace).join("&")
|
171
192
|
end
|
172
193
|
|
173
194
|
class QueryToken
|
@@ -187,6 +208,10 @@ module Furi
|
|
187
208
|
[name, value]
|
188
209
|
end
|
189
210
|
|
211
|
+
def ==(other)
|
212
|
+
to_s == other.to_s
|
213
|
+
end
|
214
|
+
|
190
215
|
def to_s
|
191
216
|
"#{::URI.encode_www_form_component(name.to_s)}=#{::URI.encode_www_form_component(value.to_s)}"
|
192
217
|
end
|
@@ -213,6 +238,7 @@ module Furi
|
|
213
238
|
end
|
214
239
|
|
215
240
|
def initialize(argument)
|
241
|
+
@query_tokens = []
|
216
242
|
case argument
|
217
243
|
when String
|
218
244
|
parse_uri_string(argument)
|
@@ -230,7 +256,25 @@ module Furi
|
|
230
256
|
|
231
257
|
def merge(parts)
|
232
258
|
parts.each do |part, value|
|
233
|
-
|
259
|
+
case part.to_sym
|
260
|
+
when :query
|
261
|
+
merge_query(value)
|
262
|
+
else
|
263
|
+
send(:"#{part}=", value)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
self
|
267
|
+
end
|
268
|
+
|
269
|
+
def merge_query(query)
|
270
|
+
case query
|
271
|
+
when Hash
|
272
|
+
self.query = self.query.merge(Furi::Utils.stringify_keys(query))
|
273
|
+
when String, Array
|
274
|
+
self.query_tokens += Furi.query_tokens(query)
|
275
|
+
when nil
|
276
|
+
else
|
277
|
+
raise ArgumentError, "#{query.inspect} can not be merged"
|
234
278
|
end
|
235
279
|
end
|
236
280
|
|
@@ -243,24 +287,9 @@ module Furi
|
|
243
287
|
nil
|
244
288
|
end
|
245
289
|
end
|
246
|
-
|
247
|
-
def host
|
248
|
-
|
249
|
-
[hostname, explicit_port].compact.join(":")
|
250
|
-
elsif port
|
251
|
-
raise FormattingError, "can not build URI with port but without hostname"
|
252
|
-
else
|
253
|
-
nil
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
|
-
def host=(string)
|
258
|
-
@port = nil
|
259
|
-
if string.include?(":")
|
260
|
-
string, @port = string.split(":", 2)
|
261
|
-
@port = @port.to_i
|
262
|
-
end
|
263
|
-
@hostname = string.empty? ? nil : string
|
290
|
+
|
291
|
+
def host=(host)
|
292
|
+
@host = host
|
264
293
|
end
|
265
294
|
|
266
295
|
def to_s
|
@@ -272,8 +301,9 @@ module Furi
|
|
272
301
|
result << userinfo
|
273
302
|
end
|
274
303
|
result << host if host
|
275
|
-
result <<
|
276
|
-
|
304
|
+
result << ":" << port if explicit_port
|
305
|
+
result << (host ? path : path!)
|
306
|
+
if query_tokens.any?
|
277
307
|
result << "?" << query_string
|
278
308
|
end
|
279
309
|
if anchor
|
@@ -282,45 +312,66 @@ module Furi
|
|
282
312
|
result.join
|
283
313
|
end
|
284
314
|
|
315
|
+
|
316
|
+
def request
|
317
|
+
result = []
|
318
|
+
result << path!
|
319
|
+
result << "?" << query_string if query_tokens.any?
|
320
|
+
result.join
|
321
|
+
end
|
322
|
+
|
323
|
+
def request_uri
|
324
|
+
request
|
325
|
+
end
|
326
|
+
|
285
327
|
def query
|
286
328
|
return @query if query_level?
|
287
|
-
@query = Furi.parse_nested_query(
|
329
|
+
@query = Furi.parse_nested_query(query_tokens)
|
288
330
|
end
|
289
331
|
|
290
332
|
|
291
333
|
def query=(value)
|
292
334
|
@query = nil
|
335
|
+
@query_tokens = []
|
293
336
|
case value
|
294
|
-
when String
|
295
|
-
@
|
296
|
-
when Array
|
297
|
-
@query = Furi.query_tokens(value)
|
337
|
+
when String, Array
|
338
|
+
@query_tokens = Furi.query_tokens(value)
|
298
339
|
when Hash
|
299
340
|
@query = value
|
341
|
+
@query_tokens = Furi.serialize_tokens(value)
|
300
342
|
when nil
|
301
343
|
else
|
302
344
|
raise ArgumentError, 'Query can only be Hash or String'
|
303
345
|
end
|
304
346
|
end
|
305
347
|
|
306
|
-
def hostname=(hostname)
|
307
|
-
@hostname = hostname
|
308
|
-
end
|
309
|
-
|
310
348
|
def port=(port)
|
311
|
-
|
312
|
-
|
313
|
-
|
349
|
+
if port != nil
|
350
|
+
@port = port.to_i
|
351
|
+
if @port == 0
|
352
|
+
raise ArgumentError, "port should be an Integer > 0"
|
353
|
+
end
|
354
|
+
else
|
355
|
+
@port = nil
|
314
356
|
end
|
315
357
|
@port
|
316
358
|
end
|
317
359
|
|
360
|
+
def query_tokens=(tokens)
|
361
|
+
@query = nil
|
362
|
+
@query_tokens = tokens
|
363
|
+
end
|
364
|
+
|
318
365
|
def username=(username)
|
319
|
-
@username = username
|
366
|
+
@username = username.nil? ? nil : username.to_s
|
320
367
|
end
|
321
368
|
|
322
369
|
def password=(password)
|
323
|
-
@password = password
|
370
|
+
@password = password.nil? ? nil : password.to_s
|
371
|
+
end
|
372
|
+
|
373
|
+
def path=(path)
|
374
|
+
@path = path.to_s
|
324
375
|
end
|
325
376
|
|
326
377
|
def protocol=(protocol)
|
@@ -328,8 +379,11 @@ module Furi
|
|
328
379
|
end
|
329
380
|
|
330
381
|
def query_string
|
331
|
-
|
332
|
-
|
382
|
+
if query_level?
|
383
|
+
Furi.serialize(@query)
|
384
|
+
else
|
385
|
+
query_tokens.join("&")
|
386
|
+
end
|
333
387
|
end
|
334
388
|
|
335
389
|
def expressions
|
@@ -341,7 +395,49 @@ module Furi
|
|
341
395
|
end
|
342
396
|
|
343
397
|
def default_port
|
344
|
-
protocol ?
|
398
|
+
protocol && PROTOCOLS[protocol] ? PROTOCOLS[protocol][:port] : nil
|
399
|
+
end
|
400
|
+
|
401
|
+
def ssl?
|
402
|
+
!!(protocol && PROTOCOLS[protocol][:ssl])
|
403
|
+
end
|
404
|
+
|
405
|
+
def ssl
|
406
|
+
ssl?
|
407
|
+
end
|
408
|
+
|
409
|
+
def ssl=(ssl)
|
410
|
+
self.protocol = find_protocol_for_ssl(ssl)
|
411
|
+
end
|
412
|
+
|
413
|
+
def filename
|
414
|
+
path.split("/").last
|
415
|
+
end
|
416
|
+
|
417
|
+
def default_web_port?
|
418
|
+
WEB_PROTOCOL.any? do |web_protocol|
|
419
|
+
PROTOCOLS[web_protocol][:port] == port!
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
def web_protocol?
|
424
|
+
WEB_PROTOCOL.include?(protocol)
|
425
|
+
end
|
426
|
+
|
427
|
+
def resource
|
428
|
+
[request, anchor].compact.join("#")
|
429
|
+
end
|
430
|
+
|
431
|
+
def path!
|
432
|
+
path || ROOT
|
433
|
+
end
|
434
|
+
|
435
|
+
def host!
|
436
|
+
host || ""
|
437
|
+
end
|
438
|
+
|
439
|
+
def ==(other)
|
440
|
+
to_s == other.to_s
|
345
441
|
end
|
346
442
|
|
347
443
|
protected
|
@@ -359,7 +455,7 @@ module Furi
|
|
359
455
|
@anchor = @anchor.empty? ? nil : @anchor.join("#")
|
360
456
|
if string.include?("?")
|
361
457
|
string, query_string = string.split("?", 2)
|
362
|
-
|
458
|
+
self.query_tokens = Furi.query_tokens(query_string)
|
363
459
|
end
|
364
460
|
|
365
461
|
if string.include?("://")
|
@@ -383,11 +479,35 @@ module Furi
|
|
383
479
|
userinfo, string = string.split("@", 2)
|
384
480
|
@username, @password = userinfo.split(":", 2)
|
385
481
|
end
|
386
|
-
|
482
|
+
host, port = string.split(":", 2)
|
483
|
+
self.host = host if host
|
484
|
+
self.port = port if port
|
485
|
+
end
|
486
|
+
|
487
|
+
def find_protocol_for_ssl(ssl)
|
488
|
+
if SSL_MAPPING.key?(protocol)
|
489
|
+
ssl ? SSL_MAPPING[protocol] : protocol
|
490
|
+
elsif SSL_MAPPING.values.include?(protocol)
|
491
|
+
ssl ? protocol : SSL_MAPPING.invert[protocol]
|
492
|
+
else
|
493
|
+
raise ArgumentError, "Can not specify ssl for #{protocol.inspect} protocol"
|
494
|
+
end
|
387
495
|
end
|
388
496
|
|
389
497
|
end
|
390
498
|
|
391
499
|
class FormattingError < StandardError
|
392
500
|
end
|
501
|
+
|
502
|
+
class Utils
|
503
|
+
class << self
|
504
|
+
def stringify_keys(hash)
|
505
|
+
result = {}
|
506
|
+
hash.each_key do |key|
|
507
|
+
result[key.to_s] = hash[key]
|
508
|
+
end
|
509
|
+
result
|
510
|
+
end
|
511
|
+
end
|
512
|
+
end
|
393
513
|
end
|
data/lib/furi/version.rb
CHANGED
data/spec/furi_spec.rb
CHANGED
@@ -69,10 +69,13 @@ describe Furi do
|
|
69
69
|
expect("http://gusiev.com").to have_parts(
|
70
70
|
protocol: 'http',
|
71
71
|
hostname: 'gusiev.com',
|
72
|
-
query_string:
|
72
|
+
query_string: "",
|
73
73
|
query: {},
|
74
74
|
path: nil,
|
75
|
+
path!: '/',
|
75
76
|
port: nil,
|
77
|
+
request: '/',
|
78
|
+
resource: '/',
|
76
79
|
)
|
77
80
|
end
|
78
81
|
|
@@ -83,6 +86,8 @@ describe Furi do
|
|
83
86
|
path: '/posts/index.html',
|
84
87
|
port: nil,
|
85
88
|
protocol: 'http',
|
89
|
+
resource: '/posts/index.html?a=b#zz',
|
90
|
+
request: '/posts/index.html?a=b',
|
86
91
|
)
|
87
92
|
end
|
88
93
|
|
@@ -100,7 +105,7 @@ describe Furi do
|
|
100
105
|
username: 'user',
|
101
106
|
password: 'pass',
|
102
107
|
hostname: 'gusiev.com',
|
103
|
-
query_string:
|
108
|
+
query_string: "",
|
104
109
|
anchor: nil,
|
105
110
|
)
|
106
111
|
end
|
@@ -110,7 +115,7 @@ describe Furi do
|
|
110
115
|
username: 'user',
|
111
116
|
password: nil,
|
112
117
|
hostname: 'gusiev.com',
|
113
|
-
query_string:
|
118
|
+
query_string: "",
|
114
119
|
anchor: nil,
|
115
120
|
)
|
116
121
|
end
|
@@ -130,14 +135,16 @@ describe Furi do
|
|
130
135
|
userinfo: 'user:pass',
|
131
136
|
protocol: 'http',
|
132
137
|
port: 80,
|
133
|
-
query_string:
|
138
|
+
query_string: "",
|
134
139
|
)
|
135
140
|
end
|
136
141
|
it "parses url with query" do
|
137
142
|
expect("/index.html?a=b&c=d").to have_parts(
|
138
143
|
host: nil,
|
144
|
+
host!: '',
|
139
145
|
query_string: 'a=b&c=d',
|
140
|
-
query: {'a' => 'b', 'c' => 'd'}
|
146
|
+
query: {'a' => 'b', 'c' => 'd'},
|
147
|
+
request: '/index.html?a=b&c=d',
|
141
148
|
)
|
142
149
|
end
|
143
150
|
|
@@ -148,6 +155,23 @@ describe Furi do
|
|
148
155
|
"port!" => 80
|
149
156
|
)
|
150
157
|
end
|
158
|
+
it "parses nested query" do
|
159
|
+
expect("gusiev.com?a[]=1&a[]=2&b[c]=1&b[d]=2").to have_parts(
|
160
|
+
host: 'gusiev.com',
|
161
|
+
query: {"a" => ["1","2"], "b" => {"c" => "1", "d" => "2"}},
|
162
|
+
)
|
163
|
+
end
|
164
|
+
|
165
|
+
it "find out protocol security" do
|
166
|
+
expect("gusiev.com:443").to have_parts(
|
167
|
+
host: 'gusiev.com',
|
168
|
+
:"ssl" => false
|
169
|
+
)
|
170
|
+
expect("https://gusiev.com:443").to have_parts(
|
171
|
+
host: 'gusiev.com',
|
172
|
+
:"ssl" => true
|
173
|
+
)
|
174
|
+
end
|
151
175
|
end
|
152
176
|
describe ".update" do
|
153
177
|
|
@@ -160,6 +184,8 @@ describe Furi do
|
|
160
184
|
expect(Furi.update("/index.html", hostname: 'gusiev.com')).to eq('gusiev.com/index.html')
|
161
185
|
expect(Furi.update("http://www.gusiev.com/index.html", hostname: 'gusiev.com')).to eq('http://gusiev.com/index.html')
|
162
186
|
expect(Furi.update("/index.html", hostname: 'gusiev.com')).to eq('gusiev.com/index.html')
|
187
|
+
expect(Furi.update("gusiev.com/index.html?a=b", hostname: nil)).to eq('/index.html?a=b')
|
188
|
+
expect(Furi.update("gusiev.com?a=b", hostname: nil)).to eq('/?a=b')
|
163
189
|
end
|
164
190
|
|
165
191
|
it "updates port" do
|
@@ -168,6 +194,13 @@ describe Furi do
|
|
168
194
|
expect(Furi.update("gusiev.com:33/index.html", port: 80)).to eq('gusiev.com:80/index.html')
|
169
195
|
expect(Furi.update("http://gusiev.com:33/index.html", port: 80)).to eq('http://gusiev.com/index.html')
|
170
196
|
end
|
197
|
+
|
198
|
+
it "updates ssl" do
|
199
|
+
expect(Furi.update("http://gusiev.com", ssl: true)).to eq('https://gusiev.com')
|
200
|
+
expect(Furi.update("https://gusiev.com", ssl: true)).to eq('https://gusiev.com')
|
201
|
+
expect(Furi.update("https://gusiev.com", ssl: false)).to eq('http://gusiev.com')
|
202
|
+
expect(Furi.update("http://gusiev.com", ssl: false)).to eq('http://gusiev.com')
|
203
|
+
end
|
171
204
|
it "updates protocol" do
|
172
205
|
expect(Furi.update("http://gusiev.com", protocol: '')).to eq('//gusiev.com')
|
173
206
|
expect(Furi.update("http://gusiev.com", protocol: nil)).to eq('gusiev.com')
|
@@ -187,9 +220,42 @@ describe Furi do
|
|
187
220
|
expect(Furi.build(hostname: 'hello.com', port: 88)).to eq('hello.com:88')
|
188
221
|
expect(Furi.build(schema: 'https', hostname: 'hello.com', port: 88)).to eq('https://hello.com:88')
|
189
222
|
expect(Furi.build(schema: 'http', hostname: 'hello.com', port: 80)).to eq('http://hello.com')
|
223
|
+
expect(Furi.build(path: '/index.html', query: {a: 1, b: 2})).to eq('/index.html?a=1&b=2')
|
190
224
|
end
|
191
225
|
end
|
192
226
|
|
227
|
+
describe ".merge" do
|
228
|
+
it "should work" do
|
229
|
+
expect(Furi.merge("//gusiev.com", query: {a: 1})).to eq('//gusiev.com?a=1')
|
230
|
+
expect(Furi.merge("//gusiev.com?a=1", query: {b: 2})).to eq('//gusiev.com?a=1&b=2')
|
231
|
+
expect(Furi.merge("//gusiev.com?a=1", query: {a: 2})).to eq('//gusiev.com?a=2')
|
232
|
+
expect(Furi.merge("//gusiev.com?a=1", query: [['a', 2], ['b', 3]])).to eq('//gusiev.com?a=1&a=2&b=3')
|
233
|
+
expect(Furi.merge("//gusiev.com?a=1&b=2", query: '?a=3')).to eq('//gusiev.com?a=1&b=2&a=3')
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
describe "#==" do
|
238
|
+
it "should work" do
|
239
|
+
expect(Furi.parse('http://gusiev.com:80') == Furi.parse('http://gusiev.com')).to be_truthy
|
240
|
+
expect(Furi.parse('http://gusiev.com') == Furi.parse('https://gusiev.com')).to be_falsey
|
241
|
+
expect(Furi.parse('http://gusiev.com') == Furi.parse('http://gusiev.com')).to be_truthy
|
242
|
+
expect(Furi.parse('http://gusiev.com.ua') == Furi.parse('http://gusiev.com')).to be_falsey
|
243
|
+
expect(Furi.parse('http://gusiev.com?a=1&a=1') == Furi.parse('http://gusiev.com?a=1')).to be_falsey
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
describe "#clone" do
|
248
|
+
it "should work" do
|
249
|
+
|
250
|
+
uri = Furi.parse('http://gusiev.com')
|
251
|
+
expect(uri.clone == uri).to be_truthy
|
252
|
+
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
|
+
end
|
258
|
+
end
|
193
259
|
|
194
260
|
describe "serialize" do
|
195
261
|
it "should work" do
|
@@ -302,7 +368,6 @@ describe Furi do
|
|
302
368
|
|
303
369
|
lambda { Furi.parse_nested_query("x[y]=1&x[y][][w]=2") }.
|
304
370
|
should raise_error(TypeError, "expected Array (got String) for param `y'")
|
305
|
-
|
306
371
|
end
|
307
372
|
|
308
373
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: furi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bogdan Gusiev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-07-
|
11
|
+
date: 2015-07-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|