iuri 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f823ae8478599ae553df7854ab74819fd56e1301
4
- data.tar.gz: 81dc21e0b3899b2ddd6908f95fc5d0919e6ee861
3
+ metadata.gz: 80c50f10a15c87f8aedd47924a82bd4069c1a9e3
4
+ data.tar.gz: a78f253736108f72b6b27bdae2ace3563859e6d5
5
5
  SHA512:
6
- metadata.gz: 131316b2a076b97a9d386651a9aa92f24f4f50506b9507b311c3956d06ddba0273836b6f7d03b6d981d9b49e2065f504404dc8f8de608e39ab7586c90668e7b5
7
- data.tar.gz: 8b59b357b357509a98cf600e1e2b80133a7b3aefdf10eb27259bf73c9b67fa7f17e926e3fd6d29b90f4a7d752f8c366e63f49a6faa7b47681ab030800e974bf0
6
+ metadata.gz: 8c904845ebc55971e9f3d968e49b5b1b28a088d97db83ed20477f144e19e608d0057e51bbbdcebea703ce0eb1e9b05509942cac4cd7ad57494be1b92e3742500
7
+ data.tar.gz: 015553c5aa28b0aa769f498b33ccadb870792272a0acbcb229719aa55928dd1c48bf92fab889a6a9640cd5fa3afe437f2270dce6502e8ace1d5fdb9bc131ad04
@@ -0,0 +1,3 @@
1
+ rvm:
2
+ - "2.1.2"
3
+ - "2.1.3"
data/README.md CHANGED
@@ -1,42 +1,158 @@
1
1
  # IURI
2
2
 
3
- Build complex URIs with chainability and immutability. If you're familiar
4
- with URI then you already know how to use it.
3
+ [![Build Status](https://travis-ci.org/tatey/iuri.svg?branch=master)](https://travis-ci.org/tatey/iuri)
4
+
5
+ Build complex URIs with chainability and immutability. No string
6
+ concatenation required. If you're familiar with `URI` then you already know
7
+ how to use it.
8
+
9
+ First it starts like this.
10
+
11
+ ``` ruby
12
+ "https://lifx.co/api/v1/devices".
13
+ ```
14
+
15
+ Then you need to target different hosts in development, staging and
16
+ production.
17
+
18
+ ``` ruby
19
+ "#{ENV['API_SCHEME']}://#{ENV['API_HOST']}/api/v1/devices"
20
+ ```
21
+
22
+ Then staging becomes protected by basic authentication.
23
+
24
+ ``` ruby
25
+ if ENV['API_CREDENTIALS']
26
+ "#{ENV['API_SCHEME']}://#{ENV['API_CREDENTIALS']}@#{ENV['API_HOST']}/api/v1/devices"
27
+ else
28
+ "#{ENV['API_SCHEME']}://#{ENV['API_HOST']}/api/v1/devices"
29
+ end
30
+ ```
31
+
32
+ Then you need to target different paths.
33
+
34
+ ``` ruby
35
+ def devices_url
36
+ base_url + '/api/v1/devices'
37
+ end
38
+
39
+ def accounts_url
40
+ base_url + '/api/v1/accounts'
41
+ end
42
+
43
+ def base_url
44
+ if ENV['API_CREDENTIALS']
45
+ "#{ENV['API_SCHEME']}://#{ENV['API_CREDENTIALS']}@#{ENV['API_HOST']}"
46
+ else
47
+ "#{ENV['API_SCHEME']}://#{ENV['API_HOST']}"
48
+ end
49
+ end
50
+ ```
51
+
52
+ Now you've added three environment variables and you're vulnerable to
53
+ developers mistyping URLs. With `IURI` there's a better way.
54
+
55
+ ``` ruby
56
+ # Development
57
+ # ENV['API_BASE_URL'] = 'http://lifx.dev'
58
+ #
59
+ # Staging
60
+ # ENV['API_BASE_URL'] = 'https://user:pass@staging.lifx.co'
61
+ #
62
+ # Production
63
+ # ENV['API_BASE_URL'] = 'https://lifx.co'
64
+
65
+ def devices_url
66
+ API_BASE_URL.merge(path: "/api/v1/devices")
67
+ end
68
+
69
+ def accounts_url
70
+ API_BASE_URL.merge(path: "/api/v1/accounts")
71
+ end
72
+
73
+ def API_BASE_URL
74
+ IURI.parse(ENV['API_BASE_URL'])
75
+ end
76
+ ```
5
77
 
6
- ## Installation
7
-
8
- Add this line to your application's Gemfile:
9
-
10
- gem 'iuri'
11
-
12
- And then execute:
13
-
14
- $ bundle
78
+ ## Usage
15
79
 
16
- Or install it yourself as:
80
+ Parse URL and append a path.
81
+
82
+ ``` ruby
83
+ uri = IURI.parse("https://user:secret@lifx.co").merge(path: "/api/v1/devices")
84
+ uri.to_s # => "https://user:secret@lifx.co/api/v1/devices"
85
+ ```
86
+
87
+ Preferring components to strings gives you greater flexibility over the
88
+ base URL. Here we include a query string at the end of the URL and change
89
+ the path as required.
90
+
91
+ ``` ruby
92
+ uri = IURI.parse("https://lifx.co?api_key=secret").merge(path: "/api/v1/devices")
93
+ uri.to_s # => "https://lifx.co/api/v1/devices?api_key=secret"
94
+ ```
95
+
96
+ Queries can also be built with a hash avoiding worrying about formatting
97
+ and escaping. Deep hashes are OK.
98
+
99
+ ``` ruby
100
+ uri = IURI.parse("https://lifx.co").merge(params: {api_key: 'secret'})
101
+ uri.to_s # => "https://lifx.co/?api_key=secret"
102
+ ```
103
+
104
+ Supports the same components as `URI`. Here's a sample of commonly used
105
+ components.
106
+
107
+ ``` ruby
108
+ iuri = IURI.parse("https://lifx.co").merge({
109
+ path: "/api/v1/devices"
110
+ query: "api_key=secret"
111
+ user: "user"
112
+ password: "secret"
113
+ })
114
+
115
+ iuri.path # => "/api/v1/devices"
116
+ iuri.query # => "api_key=secret"
117
+ iuri.user # => "user"
118
+ iuri.password # => "secret"
119
+ ```
120
+
121
+ Each `merge` returns a copy guaranteeing that constants and variables
122
+ remain unchanged.
123
+
124
+ ``` ruby
125
+ uri1 = IURI.parse("https://lifx.co")
126
+ uri2 = uri1.merge(path: "/api/v1/devices")
127
+ uri1.to_s # => "https://lifx.co"
128
+ uri2.to_s # => "https://lifx.co/api/v1/devices"
129
+ ```
17
130
 
18
- $ gem install iuri
131
+ ## Installation
19
132
 
20
- ## Usage
133
+ First, add this line to your application's Gemfile.
21
134
 
22
- Change components of a URI using a hash. Changes are chainable and each
23
- one returns a new instance.
135
+ ``` ruby
136
+ gem 'iuri'
137
+ ```
24
138
 
25
- Example:
139
+ Then, then execute.
26
140
 
27
- uri1 = IURI.parse("https://user:secret@lifx.co")
28
- uri2 = uri1.merge(path: "/api/v1/foos")
29
- uri2.to_s # => "https://user:secret@lifx.co/api/v1/foos"
141
+ ```
142
+ $ bundle
143
+ ```
30
144
 
31
145
  ## Tests
32
146
 
33
147
  Run the entire test suite.
34
148
 
35
- $ rake
149
+ ```
150
+ $ rake
151
+ ```
36
152
 
37
153
  ## Contributing
38
154
 
39
- 1. Fork it ( https://github.com/tatey/iuri/fork )
155
+ 1. Fork it (https://github.com/tatey/iuri/fork)
40
156
  2. Create your feature branch (`git checkout -b my-new-feature`)
41
157
  3. Commit your changes (`git commit -am 'Add some feature'`)
42
158
  4. Push to the branch (`git push origin my-new-feature`)
data/Rakefile CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'bundler/gem_tasks'
2
+ require 'bundler/setup'
2
3
  require 'rake/testtask'
3
4
 
4
5
  Rake::TestTask.new :test do |test|
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ['Tate Johnson']
10
10
  spec.email = ['tate@lifx.co']
11
11
  spec.summary = %q{Build complex URIs with chainability and immutability.}
12
- spec.description = %q{Build complex URIs with chainability and immutability.}
13
- spec.homepage = ''
12
+ spec.description = %q{Build complex URIs with chainability and immutability. No string concatenation required.}
13
+ spec.homepage = 'https://github.com/tatey/iuri'
14
14
  spec.license = 'MIT'
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
@@ -19,5 +19,6 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib"]
20
20
 
21
21
  spec.add_development_dependency 'bundler', '~> 1.6'
22
+ spec.add_development_dependency 'minitest', '~> 5.4.2'
22
23
  spec.add_development_dependency 'rake'
23
24
  end
@@ -1,40 +1,69 @@
1
+ require 'delegate'
1
2
  require 'uri'
2
3
  require 'iuri/version'
3
4
 
4
- class IURI
5
- def initialize(uri)
6
- @uri = uri
7
- end
8
-
5
+ module IURI
9
6
  def self.parse(string)
10
7
  uri = URI.parse(string)
11
- new(uri)
8
+ Generic.new(uri)
12
9
  end
13
10
 
14
- # Change components of a URI using a hash. Changes are chainable and
15
- # each one returns a new instance.
16
- #
17
- # Example:
18
- # uri1 = MergeableURI.parse("https://lifx.co")
19
- # uri2 = uri1.merge(path: "/foo/bar")
20
- # uri2.to_s # => "https://lifx.co/foo/bar"
21
- #
22
- # @param options [Hash] Components
23
- # @return [MergeableURI] A new instance
24
- def merge(options)
25
- copy = @uri.dup
26
- options.each do |key, value|
27
- writer = :"#{key}="
28
- if copy.respond_to?(writer)
29
- copy.send(writer, value)
11
+ class Generic < SimpleDelegator
12
+ # Change components of a URI using a hash. Changes are chainable and
13
+ # each one returns a new instance.
14
+ #
15
+ # Example:
16
+ # uri1 = IURI.parse("https://lifx.co")
17
+ # uri2 = uri1.merge(path: "/foo/bar")
18
+ # uri2.to_s # => "https://lifx.co/foo/bar"
19
+ #
20
+ # @param options [Hash] Components
21
+ # @return [URI] A new instance
22
+ def merge(components)
23
+ copy = clone
24
+ components.each do |key, value|
25
+ writer = :"#{key}="
26
+ if copy.respond_to?(writer)
27
+ copy.send(writer, value)
28
+ else
29
+ raise KeyError, "key not found: \"#{key}\""
30
+ end
31
+ end
32
+ copy
33
+ end
34
+
35
+ def params=(new_params)
36
+ self.query = build_nested_query(new_params)
37
+ end
38
+
39
+ def inspect
40
+ super.sub('#<URI', '#<IURI')
41
+ end
42
+
43
+ private
44
+
45
+ # A special thanks to rack for this one.
46
+ # See https://github.com/rack/rack/blob/e98a9f7ef0ddd9589145ea953948c73a8ce3caa9/lib/rack/utils.rb
47
+ def build_nested_query(value, prefix = nil)
48
+ case value
49
+ when Array
50
+ value.map { |v|
51
+ build_nested_query(v, "#{prefix}[]")
52
+ }.join("&")
53
+ when Hash
54
+ value.map { |k, v|
55
+ build_nested_query(v, prefix ? "#{prefix}[#{escape(k)}]" : escape(k))
56
+ }.reject(&:empty?).join('&')
57
+ when nil
58
+ prefix
30
59
  else
31
- raise KeyError, "key not found: \"#{key}\""
60
+ raise ArgumentError, "value must be a Hash" if prefix.nil?
61
+ "#{prefix}=#{escape(value)}"
32
62
  end
33
63
  end
34
- self.class.new(copy)
35
- end
36
64
 
37
- def to_s
38
- @uri.to_s
65
+ def escape(value)
66
+ URI.encode_www_form_component(value)
67
+ end
39
68
  end
40
69
  end
@@ -1,3 +1,3 @@
1
- class IURI
2
- VERSION = '1.0.0'
1
+ module IURI
2
+ VERSION = '1.1.0'
3
3
  end
@@ -2,23 +2,45 @@ require 'minitest/autorun'
2
2
  require 'iuri'
3
3
 
4
4
  class IURITest < Minitest::Test
5
- def test_it_sets_known_components
5
+ def test_setting_known_components
6
6
  uri1 = IURI.parse('http://lifx.co')
7
7
  uri2 = uri1.merge(scheme: 'https', path: '/foo/bar', query: 'baz=true')
8
8
 
9
9
  assert_equal 'https://lifx.co/foo/bar?baz=true', uri2.to_s
10
10
  end
11
11
 
12
- def test_it_raises_unknown_components
12
+ def test_setting_unknown_components_raises_key_error
13
13
  assert_raises(KeyError) do
14
14
  IURI.parse('http://lifx.co').merge(combobulator: 42)
15
15
  end
16
16
  end
17
17
 
18
- def test_it_is_a_copy
18
+ def test_setting_params
19
+ uri1 = IURI.parse('http://lifx.co')
20
+ uri2 = uri1.merge(params: {a: '1', b: ['1', '2', '3'], c: {d: '1'}})
21
+
22
+ assert_equal 'http://lifx.co?a=1&b[]=1&b[]=2&b[]=3&c[d]=1', uri2.to_s
23
+ end
24
+
25
+ def test_getting_known_components
26
+ uri = IURI.parse('http://lifx.co/foo/bar?baz=true')
27
+
28
+ assert uri.scheme, 'http'
29
+ assert uri.host, 'lifx.co'
30
+ assert uri.path, '/foo/bar'
31
+ assert uri.query, 'baz=true'
32
+ end
33
+
34
+ def test_merge_returns_copy
19
35
  uri1 = IURI.parse('http://lifx.co')
20
36
  uri2 = uri1.merge(path: '/foo/bar')
21
37
 
22
38
  refute_same uri1, uri2
23
39
  end
40
+
41
+ def test_inspect
42
+ uri = IURI.parse('http://lifx.co')
43
+
44
+ assert_match /\A#<IURI/, uri.inspect
45
+ end
24
46
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iuri
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tate Johnson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-16 00:00:00.000000000 Z
11
+ date: 2014-10-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: minitest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 5.4.2
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 5.4.2
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: rake
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -38,7 +52,8 @@ dependencies:
38
52
  - - ">="
39
53
  - !ruby/object:Gem::Version
40
54
  version: '0'
41
- description: Build complex URIs with chainability and immutability.
55
+ description: Build complex URIs with chainability and immutability. No string concatenation
56
+ required.
42
57
  email:
43
58
  - tate@lifx.co
44
59
  executables: []
@@ -46,6 +61,7 @@ extensions: []
46
61
  extra_rdoc_files: []
47
62
  files:
48
63
  - ".gitignore"
64
+ - ".travis.yml"
49
65
  - Gemfile
50
66
  - LICENSE.txt
51
67
  - README.md
@@ -54,7 +70,7 @@ files:
54
70
  - lib/iuri.rb
55
71
  - lib/iuri/version.rb
56
72
  - test/iuri_test.rb
57
- homepage: ''
73
+ homepage: https://github.com/tatey/iuri
58
74
  licenses:
59
75
  - MIT
60
76
  metadata: {}
@@ -80,4 +96,3 @@ specification_version: 4
80
96
  summary: Build complex URIs with chainability and immutability.
81
97
  test_files:
82
98
  - test/iuri_test.rb
83
- has_rdoc: