hashr 2.0.0.rc1 → 2.0.0.rc2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 865d5c744eb989eb6faa51b252a52b83ac31fd49
4
- data.tar.gz: a69e87efba10818c1af7036e02d75327210dbc3b
3
+ metadata.gz: 71976fe0fa3a09290f4f79dae7e349480579ad9d
4
+ data.tar.gz: 55dd79646eaf06b86937ced119b3d4b488780de4
5
5
  SHA512:
6
- metadata.gz: 1e2285af349146a905c6bcc53f5bdacc9d644f2ca48e05e69d700e18082d2285dd1b49e16670808a470e72e6ced4795ceb614d6d4eeded4310e61c9f1ffb559e
7
- data.tar.gz: 993a3e986b50d2c9c34bd2ce153f2a25c10d0530962cca561880361f9080d83cdbb87f83de34b3dc11029ed88a5cf479d9de259396dc7d09b089f00d9820a336
6
+ metadata.gz: 3b9fe63ebf17bf22d5253887afbf67e8b090462df7b64291a89b425b1e32665b405905d1984371e13752a0d18e54f53ee700f0997b571f80291db58bd61dbfee
7
+ data.tar.gz: a46cc5aad1af026c325080a73a01045ef4878f66c2072da21f0265024d9a63c6e5567a53bbfacf36d926b706821639964e60d300960711cd69dae781e67f72cb
@@ -76,7 +76,7 @@ class Hashr < BasicObject
76
76
 
77
77
  def to_h
78
78
  @data.inject({}) do |hash, (key, value)|
79
- hash.merge(key => value.respond_to?(:to_h) ? value.to_h : value)
79
+ hash.merge(key => value.is_a?(Hashr) || value.is_a?(Hash) ? value.to_h : value)
80
80
  end
81
81
  end
82
82
  alias to_hash to_h
@@ -1,3 +1,3 @@
1
1
  class Hashr < BasicObject
2
- VERSION = '2.0.0.rc1'
2
+ VERSION = '2.0.0.rc2'
3
3
  end
@@ -0,0 +1,15 @@
1
+ describe Hash do
2
+ describe 'deep_symbolize_keys' do
3
+ it 'symbolizes keys on nested hashes' do
4
+ hash = { 'foo' => { 'bar' => 'bar' } }
5
+ expected = { :foo => { :bar => 'bar' } }
6
+ expect(hash.deep_symbolize_keys).to eq(expected)
7
+ end
8
+
9
+ it 'walks arrays' do
10
+ hash = { 'foo' => [{ 'bar' => 'bar', 'baz' => { 'buz' => 'buz' } }] }
11
+ expected = { :foo => [{ :bar => 'bar', :baz => { :buz => 'buz' } }] }
12
+ expect(hash.deep_symbolize_keys).to eq(expected)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ describe Hashr::Delegate::Conditional do
2
+ let(:klass) { Class.new(Hashr) { include Hashr::Delegate::Conditional } }
3
+
4
+ it 'delegates key?' do
5
+ hashr = klass.new(foo: 'foo')
6
+ expect(hashr.key?(:foo)).to eq(true)
7
+ end
8
+
9
+ it 'delegates select' do
10
+ hashr = klass.new(foo: 'foo', bar: 'bar')
11
+ expect(hashr.select { |key, value| key == :bar }.to_h).to eq(bar: 'bar')
12
+ end
13
+
14
+ it 'delegates delete' do
15
+ hashr = klass.new(foo: 'foo', bar: 'bar')
16
+ hashr.delete(:foo)
17
+ expect(hashr.to_h).to eq(bar: 'bar')
18
+ end
19
+ end
@@ -0,0 +1,64 @@
1
+ describe Hashr::Env do
2
+ let(:klass) do
3
+ Class.new(Hashr) do
4
+ extend Hashr::Env
5
+
6
+ self.env_namespace = 'hashr'
7
+
8
+ define string: 'string',
9
+ hash: { key: 'value' },
10
+ array: ['foo', 'bar'],
11
+ bool: false
12
+ end
13
+ end
14
+
15
+ after do
16
+ ENV.keys.each { |key| ENV.delete(key) if key.start_with?('HASHR_') }
17
+ end
18
+
19
+ it 'defaults to an env var' do
20
+ ENV['HASHR_STRING'] = 'env string'
21
+ expect(klass.new.string).to eq('env string')
22
+ end
23
+
24
+ it 'defaults to a nested env var' do
25
+ ENV['HASHR_HASH_KEY'] = 'env value'
26
+ expect(klass.new.hash.key).to eq('env value')
27
+ end
28
+
29
+ describe 'type casts based on the default' do
30
+ describe 'to boolean' do
31
+ it 'true given' do
32
+ ENV['HASHR_BOOL'] = 'true'
33
+ expect(klass.new.bool).to eq(true)
34
+ end
35
+
36
+ it 'false given' do
37
+ ENV['HASHR_BOOL'] = 'false'
38
+ expect(klass.new.bool).to eq(false)
39
+ end
40
+
41
+ it 'empty string given' do
42
+ ENV['HASHR_BOOL'] = ''
43
+ expect(klass.new.bool).to eq(false)
44
+ end
45
+ end
46
+
47
+ describe 'to an array' do
48
+ it 'splits a comma-separated string' do
49
+ ENV['HASHR_ARRAY'] = 'env foo,env bar'
50
+ expect(klass.new.array).to eq(['env foo', 'env bar'])
51
+ end
52
+
53
+ it 'returns an empty array for an empty string' do
54
+ ENV['HASHR_ARRAY'] = ''
55
+ expect(klass.new.array).to eq([])
56
+ end
57
+ end
58
+ end
59
+
60
+ it 'data takes precedence over an env var' do
61
+ ENV['HASHR_STRING'] = 'env string'
62
+ expect(klass.new(string: 'data string').string).to eq('data string')
63
+ end
64
+ end
@@ -0,0 +1,266 @@
1
+ describe Hashr do
2
+ describe 'initialization' do
3
+ it 'takes nil' do
4
+ expect { Hashr.new(nil) }.to_not raise_error
5
+ end
6
+
7
+ it 'does not explode on a numerical key' do
8
+ expect { Hashr.new(1 => 2) }.to_not raise_error
9
+ end
10
+
11
+ it 'does not explode on a true key' do
12
+ expect { Hashr.new(true => 'on') }.to_not raise_error
13
+ end
14
+
15
+ it 'raises an ArgumentError when given a string' do
16
+ expect { Hashr.new('foo') }.to raise_error(ArgumentError)
17
+ end
18
+
19
+ it 'passing a block allows to define methods on the singleton class' do
20
+ hashr = Hashr.new(count: 5) do
21
+ def count
22
+ @data.count
23
+ end
24
+ end
25
+ expect(hashr.count).to eq(5)
26
+ end
27
+ end
28
+
29
+ describe 'defined?' do
30
+ it 'returns true when a key is defined' do
31
+ hashr = Hashr.new(foo: 'foo')
32
+ expect(hashr.defined?(:foo)).to eq(true)
33
+ end
34
+
35
+ it 'returns false when a key is not defined' do
36
+ hashr = Hashr.new(foo: 'foo')
37
+ expect(hashr.defined?(:bar)).to eq(false)
38
+ end
39
+
40
+ it 'works with a numerical key' do
41
+ hashr = Hashr.new(1 => 'foo')
42
+ expect(hashr.defined?(1)).to eq(true)
43
+ end
44
+
45
+ it 'works with a true key' do
46
+ hashr = Hashr.new(true => 'foo')
47
+ expect(hashr.defined?(true)).to eq(true)
48
+ end
49
+
50
+ it 'is indifferent about symbols/strings (string given, symbol used)' do
51
+ hashr = Hashr.new('foo' => 'bar')
52
+ expect(hashr.defined?(:foo)).to eq(true)
53
+ end
54
+
55
+ it 'is indifferent about symbols/strings (symbol given, string used)' do
56
+ hashr = Hashr.new(foo: :bar)
57
+ expect(hashr.defined?('foo')).to eq(true)
58
+ end
59
+ end
60
+
61
+ describe 'hash access' do
62
+ it 'is indifferent about symbols/strings (string given, symbol used)' do
63
+ hashr = Hashr.new('foo' => { 'bar' => 'baz' })
64
+ expect(hashr[:foo][:bar]).to eq('baz')
65
+ end
66
+
67
+ it 'is indifferent about symbols/strings (symbol given, string used)' do
68
+ hashr = Hashr.new(foo: { bar: 'baz' })
69
+ expect(hashr['foo']['bar']).to eq('baz')
70
+ end
71
+
72
+ it 'allows accessing keys with Hash core method names (count)' do
73
+ expect(Hashr.new(count: 2).count).to eq(2)
74
+ end
75
+
76
+ it 'allows accessing keys with Hash core method names (key)' do
77
+ expect(Hashr.new(key: 'key').key).to eq('key')
78
+ end
79
+ end
80
+
81
+ describe 'hash assignment' do
82
+ let(:hashr) { Hashr.new }
83
+
84
+ it 'works with a string key' do
85
+ hashr['foo'] = 'foo'
86
+ expect(hashr.foo).to eq('foo')
87
+ end
88
+
89
+ it 'works with a symbol key' do
90
+ hashr[:foo] = 'foo'
91
+ expect(hashr.foo).to eq('foo')
92
+ end
93
+ end
94
+
95
+ describe 'method access' do
96
+ describe 'on an existing key' do
97
+ it 'returns the value' do
98
+ expect(Hashr.new(foo: 'foo').foo).to eq('foo')
99
+ end
100
+
101
+ it 'returns a nested hash' do
102
+ expect(Hashr.new(foo: { bar: 'bar' }).foo).to eq(bar: 'bar')
103
+ end
104
+
105
+ it 'returns a nested array' do
106
+ expect(Hashr.new(foo: ['bar', 'buz']).foo).to eq(['bar', 'buz'])
107
+ end
108
+ end
109
+
110
+ describe 'on an existing nested key' do
111
+ it 'returns the value' do
112
+ expect(Hashr.new(foo: { bar: 'bar' }).foo.bar).to eq('bar')
113
+ end
114
+
115
+ it 'returns a nested array' do
116
+ expect(Hashr.new(foo: { bar: ['bar', 'buz'] }).foo.bar).to eq(['bar', 'buz'])
117
+ end
118
+ end
119
+
120
+ describe 'on an non-existing key' do
121
+ it 'it returns nil' do
122
+ expect(Hashr.new(foo: 'foo').bar).to eq(nil)
123
+ end
124
+
125
+ it 'it returns nil (nested key)' do
126
+ expect(Hashr.new(foo: { bar: 'bar' }).foo.baz).to eq(nil)
127
+ end
128
+ end
129
+
130
+ describe 'predicate methods' do
131
+ it 'returns true if the key has a value' do
132
+ expect(Hashr.new(foo: { bar: 'bar' }).foo.bar?).to eq(true)
133
+ end
134
+
135
+ it 'returns false if the key does not have a value' do
136
+ expect(Hashr.new(foo: { bar: 'bar' }).foo.baz?).to eq(false)
137
+ end
138
+ end
139
+
140
+ describe 'respond_to?' do
141
+ it 'returns true for existing keys' do
142
+ expect(Hashr.new(foo: 'bar').respond_to?(:foo)).to eq(true)
143
+ end
144
+
145
+ it 'returns false for missing keys' do
146
+ expect(Hashr.new.respond_to?(:foo)).to eq(true)
147
+ end
148
+ end
149
+ end
150
+
151
+ describe 'method assignment' do
152
+ let(:hashr) { Hashr.new }
153
+
154
+ it 'assigns a string' do
155
+ hashr.foo = 'foo'
156
+ expect(hashr.foo).to eq('foo')
157
+ end
158
+
159
+ it 'converts a hash into a Hashr instance' do
160
+ hashr.foo = { bar: { baz: 'baz' } }
161
+ expect(hashr.foo.bar.baz).to eq('baz')
162
+ end
163
+ end
164
+
165
+ describe 'values_at' do
166
+ let(:hashr) { Hashr.new(foo: 'foo', bar: 'bar') }
167
+
168
+ it 'returns values for the given keys' do
169
+ expect(hashr.values_at(:foo, :bar)).to eq(['foo', 'bar'])
170
+ end
171
+ end
172
+
173
+ describe 'is_a?' do
174
+ let(:klass) { Class.new(Class.new(Hashr)) { default foo: 'foo' } }
175
+
176
+ it 'returns true if the object has the given superclass' do
177
+ expect(klass.new.is_a?(Hashr)).to eq(true)
178
+ end
179
+
180
+ it 'returns false if the object does not have the given superclass' do
181
+ expect(klass.new.is_a?(Hash)).to eq(false)
182
+ end
183
+ end
184
+
185
+ describe 'conversion' do
186
+ let(:hash) { Hashr.new(foo: { 'bar' => 'baz' }).to_h }
187
+
188
+ it 'converts the Hashr instance to a hash' do
189
+ expect(hash.class).to eq(Hash)
190
+ end
191
+
192
+ it 'converts nested instances to hashes' do
193
+ expect(hash[:foo].class).to eq(Hash)
194
+ end
195
+
196
+ it 'populates the hash with the symbolized keys' do
197
+ expect(hash[:foo][:bar]).to eq('baz')
198
+ end
199
+ end
200
+
201
+ describe 'defaults' do
202
+ describe 'using a symbolized hash' do
203
+ let(:klass) { Class.new(Hashr) { default foo: 'foo' } }
204
+
205
+ it 'defines the default' do
206
+ expect(klass.new['foo']).to eq('foo')
207
+ end
208
+ end
209
+
210
+ describe 'using a stringified hash' do
211
+ let(:klass) { Class.new(Hashr) { default 'foo' => 'foo' } }
212
+
213
+ it 'defines the default' do
214
+ expect(klass.new[:foo]).to eq('foo')
215
+ end
216
+ end
217
+
218
+ describe 'with a nested hash' do
219
+ let(:klass) { Class.new(Hashr) { default foo: { bar: { baz: 'baz' } } } }
220
+
221
+ it 'defines the default' do
222
+ expect(klass.new['foo'][:bar]['baz']).to eq('baz')
223
+ end
224
+ end
225
+
226
+ describe 'with a nested array' do
227
+ let(:klass) { Class.new(Hashr) { default foo: ['bar'] } }
228
+
229
+ it 'defines the default' do
230
+ expect(klass.new.foo.first).to eq('bar')
231
+ end
232
+ end
233
+
234
+ describe 'keeps existing defaults' do
235
+ let(:klass) { Class.new(Hashr) { default foo: 'foo'; default bar: 'bar' } }
236
+
237
+ it 'defines the existing default' do
238
+ expect(klass.new.foo).to eq('foo')
239
+ end
240
+
241
+ it 'defines the new default' do
242
+ expect(klass.new.bar).to eq('bar')
243
+ end
244
+ end
245
+
246
+ describe 'deep_merges inherited defaults' do
247
+ let(:klass) { Class.new(Class.new(Hashr) { default foo: 'foo' }) { default bar: 'bar' } }
248
+
249
+ it 'defines the inherited default' do
250
+ expect(klass.new.foo).to eq('foo')
251
+ end
252
+
253
+ it 'defines the default' do
254
+ expect(klass.new.bar).to eq('bar')
255
+ end
256
+ end
257
+ end
258
+
259
+ describe 'constant lookup' do
260
+ let(:klass) { Class.new(Hashr) { def env; ENV; end } }
261
+
262
+ it 'finds global consts' do
263
+ expect(klass.new.env).to eq(ENV)
264
+ end
265
+ end
266
+ end
@@ -0,0 +1 @@
1
+ require 'hashr'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hashr
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.rc1
4
+ version: 2.0.0.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Fuchs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-07 00:00:00.000000000 Z
11
+ date: 2015-10-15 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Simple Hash extension to make working with nested hashes (e.g. for configuration)
14
14
  easier and less error-prone.
@@ -26,6 +26,11 @@ files:
26
26
  - lib/hashr/delegate/hash.rb
27
27
  - lib/hashr/env.rb
28
28
  - lib/hashr/version.rb
29
+ - spec/core_ext_spec.rb
30
+ - spec/hashr/delegate/conditional_spec.rb
31
+ - spec/hashr/env_spec.rb
32
+ - spec/hashr_spec.rb
33
+ - spec/spec_helper.rb
29
34
  homepage: http://github.com/svenfuchs/hashr
30
35
  licenses: []
31
36
  metadata: {}