furi 0.0.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
data/lib/furi/utils.rb ADDED
@@ -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
+
data/lib/furi/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Furi
2
- VERSION = "0.0.2"
2
+ VERSION = "0.2.3"
3
3
  end
metadata CHANGED
@@ -1,72 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: furi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bogdan Gusiev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-07 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: bundler
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.7'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.7'
27
- - !ruby/object:Gem::Dependency
28
- name: rake
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '10.0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '10.0'
41
- - !ruby/object:Gem::Dependency
42
- name: rspec
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: byebug
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- description: The phylosophy of this gem is to make any URI modification or parsing
11
+ date: 2021-04-05 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: The philosophy of this gem is to make any URI modification or parsing
70
14
  operation to take only one line of code and never more
71
15
  email:
72
16
  - agresso@gmail.com
@@ -74,22 +18,28 @@ executables: []
74
18
  extensions: []
75
19
  extra_rdoc_files: []
76
20
  files:
21
+ - ".github/workflows/ci.yml"
77
22
  - ".gitignore"
78
23
  - ".rspec"
24
+ - CHANGELOG.md
79
25
  - Gemfile
80
26
  - LICENSE.txt
81
27
  - README.md
82
28
  - Rakefile
83
29
  - furi.gemspec
84
30
  - lib/furi.rb
31
+ - lib/furi/query_token.rb
32
+ - lib/furi/uri.rb
33
+ - lib/furi/utils.rb
85
34
  - lib/furi/version.rb
86
- - spec/furi_spec.rb
87
- - spec/spec_helper.rb
88
- homepage: ''
35
+ homepage: https://github.com/bogdan/furi
89
36
  licenses:
90
37
  - MIT
91
- metadata: {}
92
- post_install_message:
38
+ metadata:
39
+ allowed_push_host: https://rubygems.org
40
+ homepage_uri: https://github.com/bogdan/furi
41
+ source_code_uri: https://github.com/bogdan/furi
42
+ post_install_message:
93
43
  rdoc_options: []
94
44
  require_paths:
95
45
  - lib
@@ -97,18 +47,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
97
47
  requirements:
98
48
  - - ">="
99
49
  - !ruby/object:Gem::Version
100
- version: '0'
50
+ version: 2.4.0
101
51
  required_rubygems_version: !ruby/object:Gem::Requirement
102
52
  requirements:
103
53
  - - ">="
104
54
  - !ruby/object:Gem::Version
105
55
  version: '0'
106
56
  requirements: []
107
- rubyforge_project:
108
- rubygems_version: 2.4.5
109
- signing_key:
57
+ rubygems_version: 3.2.0
58
+ signing_key:
110
59
  specification_version: 4
111
60
  summary: Make URI processing as easy as it should be
112
- test_files:
113
- - spec/furi_spec.rb
114
- - spec/spec_helper.rb
61
+ test_files: []
data/spec/furi_spec.rb DELETED
@@ -1,310 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Furi do
4
-
5
- class PartsMatcher
6
-
7
- def initialize(expectation)
8
- @expectation = expectation
9
- end
10
-
11
- def matches?(text)
12
- @uri = Furi.parse(text)
13
- @expectation.each do |part, value|
14
- if @uri.send(part) != value
15
- @unmatched_part = part
16
- return false
17
- end
18
- end
19
- return true
20
- end
21
-
22
- def failure_message
23
- "Expected #{@unmatched_part.inspect} to equal #{@expectation[@unmatched_part].inspect}, but it was #{@uri.send(@unmatched_part).inspect}"
24
- end
25
-
26
- end
27
-
28
- class SerializeAs
29
- def initialize(expectation)
30
- @expectation = expectation
31
- if @expectation.is_a?(Array)
32
- @expectation = @expectation.map do |item|
33
- item.split("=").map {|z| CGI.escape(z.to_s)}.join("=")
34
- end.join("&")
35
- end
36
- end
37
-
38
- def matches?(hash)
39
- @hash = hash
40
- Furi.serialize(hash) == @expectation
41
- end
42
-
43
- def failure_message
44
- "Expected #{@hash.inspect} to serialize as #{@expectation.inspect}, but was serialized as #{Furi.serialize(@hash)}.\n" +
45
- "Debug: #{unserialize(@expectation)}, but was serialized as #{unserialize(Furi.serialize(@hash))}"
46
- end
47
-
48
- def unserialize(string)
49
- string.split("&").map do |z|
50
- z.split("=").map do |q|
51
- CGI.unescape(q)
52
- end
53
- end.inspect
54
- end
55
- end
56
-
57
- def have_parts(parts)
58
- PartsMatcher.new(parts)
59
- end
60
-
61
- def serialize_as(value)
62
- SerializeAs.new(value)
63
- end
64
-
65
-
66
-
67
- describe "#parse" do
68
- it "parses URL without path" do
69
- expect("http://gusiev.com").to have_parts(
70
- protocol: 'http',
71
- hostname: 'gusiev.com',
72
- query_string: nil,
73
- query: {},
74
- path: nil,
75
- port: nil,
76
- )
77
- end
78
-
79
- it "extracts anchor" do
80
- expect("http://gusiev.com/posts/index.html?a=b#zz").to have_parts(
81
- anchor: 'zz',
82
- query_string: 'a=b',
83
- path: '/posts/index.html',
84
- port: nil,
85
- protocol: 'http',
86
- )
87
- end
88
-
89
- it "works with path without URL" do
90
- expect("/posts/index.html").to have_parts(
91
- path: '/posts/index.html',
92
- hostname: nil,
93
- port: nil,
94
- protocol: nil,
95
- )
96
- end
97
-
98
- it "parses uri with user and password" do
99
- expect("http://user:pass@gusiev.com").to have_parts(
100
- username: 'user',
101
- password: 'pass',
102
- hostname: 'gusiev.com',
103
- query_string: nil,
104
- anchor: nil,
105
- )
106
- end
107
-
108
- it "parses uri with user and without password" do
109
- expect("http://user@gusiev.com").to have_parts(
110
- username: 'user',
111
- password: nil,
112
- hostname: 'gusiev.com',
113
- query_string: nil,
114
- anchor: nil,
115
- )
116
- end
117
-
118
-
119
- it "supports aliases" do
120
- expect("http://gusiev.com#zz").to have_parts(
121
- schema: 'http',
122
- fragment: 'zz',
123
- )
124
- end
125
-
126
- it "parses uri with explicit port and auth data" do
127
- expect("http://user:pass@gusiev.com:80").to have_parts(
128
- username: 'user',
129
- password: 'pass',
130
- userinfo: 'user:pass',
131
- protocol: 'http',
132
- port: 80,
133
- query_string: nil,
134
- )
135
- end
136
- it "parses url with query" do
137
- expect("/index.html?a=b&c=d").to have_parts(
138
- host: nil,
139
- query_string: 'a=b&c=d',
140
- query: {'a' => 'b', 'c' => 'd'}
141
- )
142
- end
143
-
144
- it "finds out port if not explicitly defined`" do
145
- expect("http://gusiev.com").to have_parts(
146
- protocol: 'http',
147
- port: nil,
148
- "port!" => 80
149
- )
150
- end
151
- end
152
- describe ".update" do
153
-
154
- it "support update for query" do
155
- expect(Furi.update("/index.html?a=b", query: {c: 'd'})).to eq('/index.html?c=d')
156
- end
157
-
158
- it "updates hostname" do
159
- expect(Furi.update("www.gusiev.com/index.html", hostname: 'gusiev.com')).to eq('gusiev.com/index.html')
160
- expect(Furi.update("/index.html", hostname: 'gusiev.com')).to eq('gusiev.com/index.html')
161
- expect(Furi.update("http://www.gusiev.com/index.html", hostname: 'gusiev.com')).to eq('http://gusiev.com/index.html')
162
- expect(Furi.update("/index.html", hostname: 'gusiev.com')).to eq('gusiev.com/index.html')
163
- end
164
-
165
- it "updates port" do
166
- expect(Furi.update("gusiev.com", port: 33)).to eq('gusiev.com:33')
167
- expect(Furi.update("gusiev.com/index.html", port: 33)).to eq('gusiev.com:33/index.html')
168
- expect(Furi.update("gusiev.com:33/index.html", port: 80)).to eq('gusiev.com:80/index.html')
169
- expect(Furi.update("http://gusiev.com:33/index.html", port: 80)).to eq('http://gusiev.com/index.html')
170
- end
171
- it "updates protocol" do
172
- expect(Furi.update("http://gusiev.com", protocol: '')).to eq('//gusiev.com')
173
- expect(Furi.update("http://gusiev.com", protocol: nil)).to eq('gusiev.com')
174
- expect(Furi.update("http://gusiev.com", protocol: 'https')).to eq('https://gusiev.com')
175
- expect(Furi.update("gusiev.com", protocol: 'http')).to eq('http://gusiev.com')
176
- expect(Furi.update("gusiev.com", protocol: 'http:')).to eq('http://gusiev.com')
177
- expect(Furi.update("gusiev.com", protocol: 'http:/')).to eq('http://gusiev.com')
178
- expect(Furi.update("gusiev.com", protocol: 'http://')).to eq('http://gusiev.com')
179
- end
180
-
181
- end
182
-
183
- describe ".build" do
184
- it "should work correctly" do
185
- expect(Furi.build(hostname: 'hello.com')).to eq('hello.com')
186
- expect(Furi.build(hostname: 'hello.com', port: 88)).to eq('hello.com:88')
187
- expect(Furi.build(hostname: 'hello.com', port: 88)).to eq('hello.com:88')
188
- expect(Furi.build(schema: 'https', hostname: 'hello.com', port: 88)).to eq('https://hello.com:88')
189
- expect(Furi.build(schema: 'http', hostname: 'hello.com', port: 80)).to eq('http://hello.com')
190
- end
191
- end
192
-
193
-
194
- describe "serialize" do
195
- it "should work" do
196
- expect({a: 'b'}).to serialize_as("a=b")
197
- expect(a: nil).to serialize_as("a=")
198
- expect(nil).to serialize_as("")
199
- expect(b: 2, a: 1).to serialize_as("b=2&a=1")
200
- expect(a: {b: {c: []}}).to serialize_as("")
201
- expect({:a => {:b => 'c'}}).to serialize_as("a%5Bb%5D=c")
202
- expect(q: [1,2]).to serialize_as("q%5B%5D=1&q%5B%5D=2")
203
- expect(a: {b: [1,2]}).to serialize_as("a%5Bb%5D%5B%5D=1&a%5Bb%5D%5B%5D=2")
204
- expect(q: "cowboy hat?").to serialize_as("q=cowboy+hat%3F")
205
- expect(a: true).to serialize_as("a=true")
206
- expect(a: false).to serialize_as("a=false")
207
- expect(a: [nil, 0]).to serialize_as("a%5B%5D=&a%5B%5D=0")
208
- expect({f: ["b", 42, "your base"] }).to serialize_as("f%5B%5D=b&f%5B%5D=42&f%5B%5D=your+base")
209
- expect({"a[]" => 1 }).to serialize_as("a%5B%5D=1")
210
- expect({"a[b]" => [1] }).to serialize_as(["a[b][]=1"])
211
- expect("a" => [1, 2], "b" => "blah" ).to serialize_as("a%5B%5D=1&a%5B%5D=2&b=blah")
212
-
213
- expect(a: [1,{c: 2, b: 3}, 4]).to serialize_as(["a[]=1", "a[][c]=2", "a[][b]=3", "a[]=4"])
214
- expect(->{
215
- Furi.serialize([1,2])
216
- }).to raise_error(ArgumentError)
217
- expect(->{
218
- Furi.serialize(a: [1,[2]])
219
- }).to raise_error(ArgumentError)
220
-
221
-
222
- params = { b:{ c:3, d:[4,5], e:{ x:[6], y:7, z:[8,9] }}};
223
- expect(CGI.unescape(Furi.serialize(params))).to eq("b[c]=3&b[d][]=4&b[d][]=5&b[e][x][]=6&b[e][y]=7&b[e][z][]=8&b[e][z][]=9")
224
-
225
- end
226
- end
227
-
228
- describe "parse_nested_query" do
229
- it "should work" do
230
- Furi.parse_nested_query("foo").
231
- should eq "foo" => nil
232
- Furi.parse_nested_query("foo=").
233
- should eq "foo" => ""
234
- Furi.parse_nested_query("foo=bar").
235
- should eq "foo" => "bar"
236
- Furi.parse_nested_query("foo=\"bar\"").
237
- should eq "foo" => "\"bar\""
238
-
239
- Furi.parse_nested_query("foo=bar&foo=quux").
240
- should eq "foo" => "quux"
241
- Furi.parse_nested_query("foo&foo=").
242
- should eq "foo" => ""
243
- Furi.parse_nested_query("foo=1&bar=2").
244
- should eq "foo" => "1", "bar" => "2"
245
- Furi.parse_nested_query("&foo=1&&bar=2").
246
- should eq "foo" => "1", "bar" => "2"
247
- Furi.parse_nested_query("foo&bar=").
248
- should eq "foo" => nil, "bar" => ""
249
- Furi.parse_nested_query("foo=bar&baz=").
250
- should eq "foo" => "bar", "baz" => ""
251
- Furi.parse_nested_query("my+weird+field=q1%212%22%27w%245%267%2Fz8%29%3F").
252
- should eq "my weird field" => "q1!2\"'w$5&7/z8)?"
253
-
254
- Furi.parse_nested_query("a=b&pid%3D1234=1023").
255
- should eq "pid=1234" => "1023", "a" => "b"
256
-
257
- Furi.parse_nested_query("foo[]").
258
- should eq "foo" => [nil]
259
- Furi.parse_nested_query("foo[]=").
260
- should eq "foo" => [""]
261
- Furi.parse_nested_query("foo[]=bar").
262
- should eq "foo" => ["bar"]
263
-
264
- Furi.parse_nested_query("foo[]=1&foo[]=2").
265
- should eq "foo" => ["1", "2"]
266
- Furi.parse_nested_query("foo=bar&baz[]=1&baz[]=2&baz[]=3").
267
- should eq "foo" => "bar", "baz" => ["1", "2", "3"]
268
- Furi.parse_nested_query("foo[]=bar&baz[]=1&baz[]=2&baz[]=3").
269
- should eq "foo" => ["bar"], "baz" => ["1", "2", "3"]
270
-
271
- Furi.parse_nested_query("x[y][z]=1").
272
- should eq "x" => {"y" => {"z" => "1"}}
273
- Furi.parse_nested_query("x[y][z][]=1").
274
- should eq "x" => {"y" => {"z" => ["1"]}}
275
- Furi.parse_nested_query("x[y][z]=1&x[y][z]=2").
276
- should eq "x" => {"y" => {"z" => "2"}}
277
- Furi.parse_nested_query("x[y][z][]=1&x[y][z][]=2").
278
- should eq "x" => {"y" => {"z" => ["1", "2"]}}
279
-
280
- Furi.parse_nested_query("x[y][][z]=1").
281
- should eq "x" => {"y" => [{"z" => "1"}]}
282
- Furi.parse_nested_query("x[y][][z][]=1").
283
- should eq "x" => {"y" => [{"z" => ["1"]}]}
284
- Furi.parse_nested_query("x[y][][z]=1&x[y][][w]=2").
285
- should eq "x" => {"y" => [{"z" => "1", "w" => "2"}]}
286
-
287
- Furi.parse_nested_query("x[y][][v][w]=1").
288
- should eq "x" => {"y" => [{"v" => {"w" => "1"}}]}
289
- Furi.parse_nested_query("x[y][][z]=1&x[y][][v][w]=2").
290
- should eq "x" => {"y" => [{"z" => "1", "v" => {"w" => "2"}}]}
291
-
292
- Furi.parse_nested_query("x[y][][z]=1&x[y][][z]=2").
293
- should eq "x" => {"y" => [{"z" => "1"}, {"z" => "2"}]}
294
- Furi.parse_nested_query("x[y][][z]=1&x[y][][w]=a&x[y][][z]=2&x[y][][w]=3").
295
- should eq "x" => {"y" => [{"z" => "1", "w" => "a"}, {"z" => "2", "w" => "3"}]}
296
-
297
- lambda { Furi.parse_nested_query("x[y]=1&x[y]z=2") }.
298
- should raise_error(TypeError, "expected Hash (got String) for param `y'")
299
-
300
- lambda { Furi.parse_nested_query("x[y]=1&x[]=1") }.
301
- should raise_error(TypeError, /expected Array \(got [^)]*\) for param `x'/)
302
-
303
- lambda { Furi.parse_nested_query("x[y]=1&x[y][][w]=2") }.
304
- should raise_error(TypeError, "expected Array (got String) for param `y'")
305
-
306
- end
307
-
308
- end
309
-
310
- end