furi 0.0.2 → 0.2.3

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.
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