furi 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +24 -12
- data/lib/furi.rb +17 -8
- data/lib/furi/query_token.rb +3 -3
- data/lib/furi/uri.rb +13 -13
- data/lib/furi/version.rb +1 -1
- data/spec/furi_spec.rb +32 -17
- 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: e47171efdec80d8610e7dea95a1eed17876ea14b
|
4
|
+
data.tar.gz: 33a2e11ef018c0d5c9d6695ced7c15e9f3dd3fb4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e0c644b931d878b69b6d902aad0772aefa16a5ff4066db3bab871912dbe1e0b4ed91b41d4fb1b921ddfe36119f60293081e6b924cab8747865c1aa1451d3ebe
|
7
|
+
data.tar.gz: 1bbc865cbe5551b416a28243260e01e01409b600f32fd83b8b3a3da320cc7f9f6ce1bdc82363d92a1b8dd1941de99356e38a4d2903a57ad2f8ef956db4a22f23
|
data/README.md
CHANGED
@@ -29,21 +29,34 @@ Here are basic:
|
|
29
29
|
### Utility Methods
|
30
30
|
|
31
31
|
|
32
|
+
Parsing the URI fragments:
|
33
|
+
|
32
34
|
``` ruby
|
33
35
|
Furi.host("http://gusiev.com") # => "gusiev.com"
|
34
36
|
Furi.port("http://gusiev.com") # => nil
|
35
37
|
Furi.port!("http://gusiev.com") # => 80
|
38
|
+
```
|
36
39
|
|
40
|
+
Updating the URI parts:
|
41
|
+
|
42
|
+
```
|
37
43
|
Furi.update("http://gusiev.com", protocol: '') # => "//gusiev.com"
|
38
44
|
Furi.update("http://gusiev.com?source=google", query: {email: "a@b.com"})
|
39
45
|
# => "http://gusiev.com?source=google&email=a@b.com"
|
40
46
|
Furi.replace("http://gusiev.com?source=google", query: {email: "a@b.com"})
|
41
47
|
# => "http://gusiev.com?email=a@b.com"
|
42
48
|
|
49
|
+
Furi.defaults("http://gusiev.com", subdomain: 'www') # => "http://www.gusiev.com"
|
50
|
+
Furi.defaults("http://blog.gusiev.com", subdomain: 'www') # => "http://blog.gusiev.com"
|
51
|
+
|
52
|
+
```
|
53
|
+
|
54
|
+
Building an URI from initial parts:
|
55
|
+
|
56
|
+
``` ruby
|
57
|
+
|
43
58
|
Furi.build(protocol: '//', host: 'gusiev.com', path: '/assets/application.js')
|
44
59
|
# => "//gusiev.com/assets/application.js"
|
45
|
-
|
46
|
-
Furi.defaults("http://gusiev.com", subdomain: 'www') # => "http://www.gusiev.com"
|
47
60
|
```
|
48
61
|
|
49
62
|
### Working with Object
|
@@ -93,13 +106,13 @@ uri.merge_query(person: {email: 'a@b.com'})
|
|
93
106
|
/ __|___ __|__ ______|______ | _________|__________ ____|____ |
|
94
107
|
/ / \ / \ / \ / \/ \ / \ / \
|
95
108
|
http://username:zhongguo@www.example.com:80/hello/world/article.html?name=bogdan#info
|
96
|
-
\_/ \_/ \___/ \_/ \__________/
|
97
|
-
| | | | |
|
98
|
-
protocol subdomain | domainzone directory
|
99
|
-
| |
|
100
|
-
domainname /
|
101
|
-
\___/
|
102
|
-
|
|
109
|
+
\_/ \_/ \___/ \_/ \__________/\ / \_/
|
110
|
+
| | | | | \___/ |
|
111
|
+
protocol subdomain | domainzone directory | extension
|
112
|
+
| | filename |
|
113
|
+
domainname / \_____/
|
114
|
+
\___/ |
|
115
|
+
| file
|
103
116
|
domain
|
104
117
|
```
|
105
118
|
|
@@ -110,9 +123,8 @@ Giving credit...
|
|
110
123
|
|
111
124
|
## TODO
|
112
125
|
|
113
|
-
*
|
114
|
-
*
|
115
|
-
* escaping in path
|
126
|
+
* Improve URI.join algorithm to match the one used in Addressible library
|
127
|
+
* Implement filename
|
116
128
|
|
117
129
|
## Contributing
|
118
130
|
|
data/lib/furi.rb
CHANGED
@@ -14,7 +14,7 @@ module Furi
|
|
14
14
|
COMBINED_PARTS = [
|
15
15
|
:hostinfo, :userinfo, :authority, :ssl, :domain, :domainname,
|
16
16
|
:domainzone, :request, :location, :query,
|
17
|
-
:extension, :
|
17
|
+
:directory, :extension, :file
|
18
18
|
]
|
19
19
|
PARTS = ESSENTIAL_PARTS + COMBINED_PARTS
|
20
20
|
|
@@ -152,7 +152,7 @@ module Furi
|
|
152
152
|
QueryToken.parse(p)
|
153
153
|
end
|
154
154
|
else
|
155
|
-
raise
|
155
|
+
raise QueryParseError, "can not parse #{query.inspect} query tokens"
|
156
156
|
end
|
157
157
|
end
|
158
158
|
|
@@ -175,7 +175,16 @@ module Furi
|
|
175
175
|
end.reduce(:join)
|
176
176
|
end
|
177
177
|
|
178
|
-
class
|
178
|
+
class Error < StandardError
|
179
|
+
end
|
180
|
+
|
181
|
+
class FormattingError < Error
|
182
|
+
end
|
183
|
+
|
184
|
+
class ParseError < Error
|
185
|
+
end
|
186
|
+
|
187
|
+
class QueryParseError < Error
|
179
188
|
end
|
180
189
|
|
181
190
|
protected
|
@@ -195,13 +204,13 @@ module Furi
|
|
195
204
|
result
|
196
205
|
when Array
|
197
206
|
if namespace.nil? || namespace.empty?
|
198
|
-
raise
|
207
|
+
raise FormattingError, "Can not serialize Array without namespace"
|
199
208
|
end
|
200
209
|
|
201
210
|
namespace = "#{namespace}[]"
|
202
211
|
query.map do |item|
|
203
212
|
if item.is_a?(Array)
|
204
|
-
raise
|
213
|
+
raise FormattingError, "Can not serialize #{item.inspect} as element of an Array"
|
205
214
|
end
|
206
215
|
serialize_tokens(item, namespace)
|
207
216
|
end
|
@@ -227,14 +236,14 @@ module Furi
|
|
227
236
|
elsif after == "[]"
|
228
237
|
current ||= []
|
229
238
|
unless current.is_a?(Array)
|
230
|
-
raise
|
239
|
+
raise QueryParseError, "expected Array (got #{current.class}) for param `#{namespace}'"
|
231
240
|
end
|
232
241
|
current << value
|
233
242
|
elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
|
234
243
|
child_key = $1
|
235
244
|
current ||= []
|
236
245
|
unless current.is_a?(Array)
|
237
|
-
raise
|
246
|
+
raise QueryParseError, "expected Array (got #{current.class}) for param `#{namespace}'"
|
238
247
|
end
|
239
248
|
if current.last.is_a?(Hash) && !current.last.key?(child_key)
|
240
249
|
parse_query_token(current.last, child_key, value)
|
@@ -244,7 +253,7 @@ module Furi
|
|
244
253
|
else
|
245
254
|
current ||= {}
|
246
255
|
unless current.is_a?(Hash)
|
247
|
-
raise
|
256
|
+
raise QueryParseError, "expected Hash (got #{current.class}) for param `#{namespace}'"
|
248
257
|
end
|
249
258
|
current = parse_query_token(current, after, value)
|
250
259
|
end
|
data/lib/furi/query_token.rb
CHANGED
@@ -20,7 +20,7 @@ module Furi
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def self.raise_parse_error(token)
|
23
|
-
raise
|
23
|
+
raise QueryParseError, "Can not parse query token #{token.inspect}"
|
24
24
|
end
|
25
25
|
|
26
26
|
def initialize(name, value)
|
@@ -40,8 +40,8 @@ module Furi
|
|
40
40
|
|
41
41
|
def to_s
|
42
42
|
encoded_key = ::URI.encode_www_form_component(name.to_s)
|
43
|
-
|
44
|
-
!value.nil? ?
|
43
|
+
|
44
|
+
!value.nil? ?
|
45
45
|
"#{encoded_key}=#{::URI.encode_www_form_component(value.to_s)}" :
|
46
46
|
encoded_key
|
47
47
|
end
|
data/lib/furi/uri.rb
CHANGED
@@ -25,7 +25,7 @@ module Furi
|
|
25
25
|
when ::URI::Generic
|
26
26
|
parse_uri_string(argument.to_s)
|
27
27
|
else
|
28
|
-
raise
|
28
|
+
raise ParseError, "wrong Uri argument"
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -77,7 +77,7 @@ module Furi
|
|
77
77
|
self.query_tokens += Furi.query_tokens(query)
|
78
78
|
when nil
|
79
79
|
else
|
80
|
-
raise
|
80
|
+
raise QueryParseError, "#{query.inspect} can not be merged"
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
@@ -244,7 +244,7 @@ module Furi
|
|
244
244
|
@query = value
|
245
245
|
when nil
|
246
246
|
else
|
247
|
-
raise
|
247
|
+
raise QueryParseError, 'Query can only be Hash or String'
|
248
248
|
end
|
249
249
|
end
|
250
250
|
|
@@ -312,14 +312,14 @@ module Furi
|
|
312
312
|
|
313
313
|
def directory=(string)
|
314
314
|
string ||= "/"
|
315
|
-
if
|
315
|
+
if file && string !~ %r{/\z}
|
316
316
|
string += '/'
|
317
317
|
end
|
318
|
-
self.path = string +
|
318
|
+
self.path = string + file.to_s
|
319
319
|
end
|
320
320
|
|
321
321
|
def extension
|
322
|
-
return nil unless
|
322
|
+
return nil unless file
|
323
323
|
file_tokens.size > 1 ? file_tokens.last : nil
|
324
324
|
end
|
325
325
|
|
@@ -327,7 +327,7 @@ module Furi
|
|
327
327
|
tokens = file_tokens
|
328
328
|
case tokens.size
|
329
329
|
when 0
|
330
|
-
raise Furi::FormattingError, "can not assign extension when there is no
|
330
|
+
raise Furi::FormattingError, "can not assign extension when there is no file"
|
331
331
|
when 1
|
332
332
|
tokens.push(string)
|
333
333
|
else
|
@@ -337,10 +337,10 @@ module Furi
|
|
337
337
|
tokens.pop
|
338
338
|
end
|
339
339
|
end
|
340
|
-
self.
|
340
|
+
self.file = tokens.join(".")
|
341
341
|
end
|
342
342
|
|
343
|
-
def
|
343
|
+
def file=(name)
|
344
344
|
unless name
|
345
345
|
return unless path
|
346
346
|
else
|
@@ -395,13 +395,13 @@ module Furi
|
|
395
395
|
self.protocol = find_protocol_for_ssl(ssl)
|
396
396
|
end
|
397
397
|
|
398
|
-
def
|
398
|
+
def file
|
399
399
|
result = path_tokens.last
|
400
400
|
result == "" ? nil : result
|
401
401
|
end
|
402
402
|
|
403
|
-
def
|
404
|
-
|
403
|
+
def file!
|
404
|
+
file || ''
|
405
405
|
end
|
406
406
|
|
407
407
|
def default_web_port?
|
@@ -486,7 +486,7 @@ module Furi
|
|
486
486
|
protected
|
487
487
|
|
488
488
|
def file_tokens
|
489
|
-
|
489
|
+
file ? file.split('.') : []
|
490
490
|
end
|
491
491
|
|
492
492
|
def query_level?
|
data/lib/furi/version.rb
CHANGED
data/spec/furi_spec.rb
CHANGED
@@ -90,7 +90,7 @@ describe Furi do
|
|
90
90
|
|
91
91
|
resource: '/articles/index.html?a=1&b=2#header',
|
92
92
|
path: "/articles/index.html",
|
93
|
-
|
93
|
+
file: 'index.html',
|
94
94
|
extension: 'html',
|
95
95
|
query_string: "a=1&b=2",
|
96
96
|
query_tokens: [['a', '1'], ['b', '2']],
|
@@ -139,7 +139,7 @@ describe Furi do
|
|
139
139
|
resource: '/posts/index.html?a=b#zz',
|
140
140
|
request: '/posts/index.html?a=b',
|
141
141
|
location: 'http://gusiev.com',
|
142
|
-
|
142
|
+
file: 'index.html',
|
143
143
|
extension: 'html',
|
144
144
|
)
|
145
145
|
end
|
@@ -161,8 +161,8 @@ describe Furi do
|
|
161
161
|
expect("/posts/").to have_parts(
|
162
162
|
path: '/posts/',
|
163
163
|
directory: '/posts',
|
164
|
-
|
165
|
-
'
|
164
|
+
file: nil,
|
165
|
+
'file!' => '',
|
166
166
|
extension: nil,
|
167
167
|
home_page?: false,
|
168
168
|
)
|
@@ -396,14 +396,14 @@ describe Furi do
|
|
396
396
|
expect(Furi.replace("/articles/index?a=b", directory: '/posts')).to eq('/posts/index?a=b')
|
397
397
|
expect(Furi.replace("/articles/index.html?a=b", directory: '/posts/')).to eq('/posts/index.html?a=b')
|
398
398
|
end
|
399
|
-
it "replace
|
400
|
-
expect(Furi.replace("gusiev.com",
|
401
|
-
expect(Furi.replace("gusiev.com/",
|
402
|
-
expect(Furi.replace("gusiev.com/article1#header",
|
403
|
-
expect(Furi.replace("gusiev.com/article#header",
|
404
|
-
expect(Furi.replace("gusiev.com/articles/article1?a=b",
|
405
|
-
expect(Furi.replace("/articles/article1?a=b",
|
406
|
-
expect(Furi.replace("/articles/article1.xml?a=b",
|
399
|
+
it "replace file" do
|
400
|
+
expect(Furi.replace("gusiev.com", file: 'article')).to eq('gusiev.com/article')
|
401
|
+
expect(Furi.replace("gusiev.com/", file: 'article')).to eq('gusiev.com/article')
|
402
|
+
expect(Furi.replace("gusiev.com/article1#header", file: '/article2')).to eq('gusiev.com/article2#header')
|
403
|
+
expect(Furi.replace("gusiev.com/article#header", file: nil)).to eq('gusiev.com/#header')
|
404
|
+
expect(Furi.replace("gusiev.com/articles/article1?a=b", file: 'article2')).to eq('gusiev.com/articles/article2?a=b')
|
405
|
+
expect(Furi.replace("/articles/article1?a=b", file: '/article2')).to eq('/articles/article2?a=b')
|
406
|
+
expect(Furi.replace("/articles/article1.xml?a=b", file: 'article2.html')).to eq('/articles/article2.html?a=b')
|
407
407
|
end
|
408
408
|
it "replace extension" do
|
409
409
|
expect(->{
|
@@ -554,6 +554,21 @@ describe Furi do
|
|
554
554
|
expect(Furi.defaults("//gusiev.com", query_string: 'b=2')).to eq('//gusiev.com?b=2')
|
555
555
|
expect(Furi.defaults("//gusiev.com?a=1&b=2", query: '?a=3')).to eq('//gusiev.com?a=1&b=2')
|
556
556
|
end
|
557
|
+
it "should set file" do
|
558
|
+
expect(Furi.defaults("gusiev.com?a=1", file: 'index.html')).to eq('gusiev.com/index.html?a=1')
|
559
|
+
expect(Furi.defaults("gusiev.com/posts?a=1", file: 'index.html')).to eq('gusiev.com/posts?a=1')
|
560
|
+
expect(Furi.defaults("gusiev.com/posts/?a=1", file: 'index.html')).to eq('gusiev.com/posts/index.html?a=1')
|
561
|
+
expect(Furi.defaults("gusiev.com/posts/?a=1", file: 'index.html')).to eq('gusiev.com/posts/index.html?a=1')
|
562
|
+
end
|
563
|
+
it "should set extension" do
|
564
|
+
expect {
|
565
|
+
Furi.defaults("gusiev.com?a=1", extension: 'html')
|
566
|
+
}.to raise_error(Furi::FormattingError)
|
567
|
+
expect(Furi.defaults("gusiev.com?a=1", file: 'index.html', extension: 'html')).to eq('gusiev.com/index.html?a=1')
|
568
|
+
expect(Furi.defaults("gusiev.com/posts?a=1", extension: 'html')).to eq('gusiev.com/posts.html?a=1')
|
569
|
+
#expect(Furi.defaults("gusiev.com/posts/?a=1", file: 'index.html')).to eq('gusiev.com/posts/index.html?a=1')
|
570
|
+
#expect(Furi.defaults("gusiev.com/posts/?a=1", file: 'index.html')).to eq('gusiev.com/posts/index.html?a=1')
|
571
|
+
end
|
557
572
|
end
|
558
573
|
|
559
574
|
describe "#==" do
|
@@ -623,10 +638,10 @@ describe Furi do
|
|
623
638
|
expect(a: [1,{c: 2, b: 3}, 4]).to serialize_as(["a[]=1", "a[][c]=2", "a[][b]=3", "a[]=4"])
|
624
639
|
expect(->{
|
625
640
|
Furi.serialize([1,2])
|
626
|
-
}).to raise_error(
|
641
|
+
}).to raise_error(Furi::FormattingError)
|
627
642
|
expect(->{
|
628
643
|
Furi.serialize(a: [1,[2]])
|
629
|
-
}).to raise_error(
|
644
|
+
}).to raise_error(Furi::FormattingError)
|
630
645
|
|
631
646
|
|
632
647
|
params = { b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }}};
|
@@ -722,13 +737,13 @@ describe Furi do
|
|
722
737
|
should eq "x" => {"y" => [{"z" => "1", "w" => "a"}, {"z" => "2", "w" => "3"}]}
|
723
738
|
|
724
739
|
lambda { Furi.parse_query("x[y]=1&x[y]z=2") }.
|
725
|
-
should raise_error(
|
740
|
+
should raise_error(Furi::QueryParseError, "expected Hash (got String) for param `y'")
|
726
741
|
|
727
742
|
lambda { Furi.parse_query("x[y]=1&x[]=1") }.
|
728
|
-
should raise_error(
|
743
|
+
should raise_error(Furi::QueryParseError, /expected Array \(got [^)]*\) for param `x'/)
|
729
744
|
|
730
745
|
lambda { Furi.parse_query("x[y]=1&x[y][][w]=2") }.
|
731
|
-
should raise_error(
|
746
|
+
should raise_error(Furi::QueryParseError, "expected Array (got String) for param `y'")
|
732
747
|
end
|
733
748
|
|
734
749
|
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.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bogdan Gusiev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-12-
|
11
|
+
date: 2016-12-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|