furi 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|