dottie 0.0.1 → 0.0.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 +15 -0
- data/lib/dottie.rb +102 -4
- data/lib/dottie/freckle.rb +6 -1
- data/lib/dottie/methods.rb +25 -0
- data/lib/dottie/version.rb +1 -1
- data/spec/dottie_spec.rb +195 -0
- data/spec/freckle_spec.rb +52 -0
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e8fe0e0c66b729b6ab64a79adc1160b60c4187dc
|
4
|
+
data.tar.gz: bbc78b403f71ffdaadc8a5fbb2bc0a8bf94c5b36
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ae21085526870fdd772f49ada018d955bac6078e4044a7dfda291927c6adcaca167e6d9b5fc3f591dd792522336e4f8d8fd6e960034a1b61aca130c7ff4ad8ce
|
7
|
+
data.tar.gz: c13c35c1968f029ef37c6c392d10b8266eda5ba71d3f95f3cb55833d3a914b28ac5eaff692a2b5c79006e1e386e9df401552f34ad8a48abc4d673ae2cd517e59
|
data/README.md
CHANGED
@@ -115,6 +115,21 @@ complex.hash # => {"a"=>[{"b"=>"x"}, {"d"=>"e"}]}
|
|
115
115
|
# add another array element
|
116
116
|
complex['a[2]'] = 'y'
|
117
117
|
complex.hash # => {"a"=>[{"b"=>"x"}, {"d"=>"e"}, "y"]}
|
118
|
+
|
119
|
+
# elements can also be prepended and appended to arrays
|
120
|
+
complex['a[+]'] = 'z' # can also use 'a[<<]' and 'a[append]'
|
121
|
+
complex.hash # => {"a"=>[{"b"=>"x"}, {"d"=>"e"}, "y", "z"]}
|
122
|
+
|
123
|
+
complex['a[-]'] = 'p' # can also use 'a[>>]' and 'a[prepend]'
|
124
|
+
complex.hash # => {"a"=>["p", {"b"=>"x"}, {"d"=>"e"}, "y", "z"]}
|
125
|
+
|
126
|
+
# use delete as you would on a Hash
|
127
|
+
complex.delete('a[1].b') # => "x"
|
128
|
+
complex.hash # => {"a"=>["p", {}, {"d"=>"e"}, "y", "z"]}
|
129
|
+
|
130
|
+
# delete an element at an array index
|
131
|
+
complex.delete('a[1]') # => {}
|
132
|
+
complex.hash # => {"a"=>["p", {"d"=>"e"}, "y", "z"]}
|
118
133
|
```
|
119
134
|
|
120
135
|
### Dottie Usage Options
|
data/lib/dottie.rb
CHANGED
@@ -10,7 +10,11 @@ module Dottie
|
|
10
10
|
# Creates a new Dottie::Freckle from a standard Ruby Hash or Array.
|
11
11
|
|
12
12
|
def self.[](obj)
|
13
|
-
Dottie::Freckle
|
13
|
+
if obj.is_a?(Dottie::Freckle)
|
14
|
+
obj
|
15
|
+
else
|
16
|
+
Dottie::Freckle.new(obj)
|
17
|
+
end
|
14
18
|
end
|
15
19
|
|
16
20
|
##
|
@@ -21,6 +25,8 @@ module Dottie
|
|
21
25
|
Dottie.key_parts(key).each do |k|
|
22
26
|
obj = case obj
|
23
27
|
when Hash, Array
|
28
|
+
# use an array index if it appears that's what was intended
|
29
|
+
k = k.to_i if obj.is_a?(Array) && k.to_i.to_s == k
|
24
30
|
obj[k]
|
25
31
|
else
|
26
32
|
nil
|
@@ -39,8 +45,17 @@ module Dottie
|
|
39
45
|
# set the value if this is the last key part
|
40
46
|
if i == key_parts.size - 1
|
41
47
|
case obj
|
42
|
-
when Hash
|
48
|
+
when Hash
|
43
49
|
obj[k] = value
|
50
|
+
when Array
|
51
|
+
case k
|
52
|
+
when '-', 'prepend', '>>'
|
53
|
+
obj.unshift(value)
|
54
|
+
when '+', 'append', '<<'
|
55
|
+
obj << value
|
56
|
+
else
|
57
|
+
obj[k] = value
|
58
|
+
end
|
44
59
|
else
|
45
60
|
raise TypeError.new("expected Hash or Array but got #{obj.class.name}")
|
46
61
|
end
|
@@ -49,7 +64,8 @@ module Dottie
|
|
49
64
|
obj = case obj
|
50
65
|
when Hash, Array
|
51
66
|
# look ahead at the next key to see if an array should be created
|
52
|
-
if key_parts[i + 1].is_a?(Integer)
|
67
|
+
if key_parts[i + 1].is_a?(Integer) ||
|
68
|
+
key_parts[i + 1] =~ /\A(-|\+|prepend|append|>>|<<)\z/
|
53
69
|
obj[k] ||= []
|
54
70
|
else
|
55
71
|
obj[k] ||= {}
|
@@ -57,7 +73,7 @@ module Dottie
|
|
57
73
|
when nil
|
58
74
|
# look at the key to see if an array should be created
|
59
75
|
case k
|
60
|
-
when Integer
|
76
|
+
when Integer, '-', '+', 'prepend', 'append', '>>', '<<'
|
61
77
|
obj[k] = []
|
62
78
|
else
|
63
79
|
obj[k] = {}
|
@@ -113,6 +129,71 @@ module Dottie
|
|
113
129
|
end
|
114
130
|
end
|
115
131
|
|
132
|
+
##
|
133
|
+
# Deletes the value at the specified key and returns it.
|
134
|
+
|
135
|
+
def self.delete(obj, key)
|
136
|
+
if Dottie.has_key?(obj, key)
|
137
|
+
key_parts = Dottie.key_parts(key)
|
138
|
+
if key_parts.size > 1
|
139
|
+
key = Dottie.build_key(key_parts[0..-2])
|
140
|
+
obj = Dottie.get(obj, key)
|
141
|
+
end
|
142
|
+
if obj.is_a?(Array) && key_parts.last.is_a?(Fixnum)
|
143
|
+
obj.delete_at(key_parts.last)
|
144
|
+
else
|
145
|
+
obj.delete(key_parts.last)
|
146
|
+
end
|
147
|
+
else
|
148
|
+
nil
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
##
|
153
|
+
# Flattens a Hash or Array to a single-depth Hash with Dottie-style keys.
|
154
|
+
|
155
|
+
def self.flatten(obj, options = {}, path = nil, flat = nil)
|
156
|
+
path ||= []
|
157
|
+
flat ||= {}
|
158
|
+
case obj
|
159
|
+
when Hash
|
160
|
+
obj.each do |k, v|
|
161
|
+
this_path = path + [k]
|
162
|
+
case v
|
163
|
+
when Hash, Array
|
164
|
+
flat[this_path.join('.')] = options[:keys_only] ? nil : v if options[:intermediate]
|
165
|
+
Dottie.flatten(v, options, this_path, flat)
|
166
|
+
else
|
167
|
+
flat[this_path.join('.')] = options[:keys_only] ? nil : v
|
168
|
+
end
|
169
|
+
end
|
170
|
+
when Array
|
171
|
+
obj.each_with_index do |v, i|
|
172
|
+
this_path = path.dup
|
173
|
+
if this_path.any?
|
174
|
+
this_path[-1] = this_path[-1].to_s + "[#{i}]"
|
175
|
+
else
|
176
|
+
this_path = ["[#{i}]"]
|
177
|
+
end
|
178
|
+
case v
|
179
|
+
when Hash, Array
|
180
|
+
flat[this_path.join('.')] = options[:keys_only] ? nil : v if options[:intermediate]
|
181
|
+
Dottie.flatten(v, options, this_path, flat)
|
182
|
+
else
|
183
|
+
flat[this_path.join('.')] = options[:keys_only] ? nil : v
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
flat
|
188
|
+
end
|
189
|
+
|
190
|
+
##
|
191
|
+
# Gets an array of the Dottie-style keys that exist in a Hash or Array.
|
192
|
+
|
193
|
+
def self.keys(obj, options = {})
|
194
|
+
Dottie.flatten(obj, { keys_only: true }.merge(options)).keys
|
195
|
+
end
|
196
|
+
|
116
197
|
##
|
117
198
|
# Checks whether a key looks like a key Dottie understands.
|
118
199
|
|
@@ -150,4 +231,21 @@ module Dottie
|
|
150
231
|
end
|
151
232
|
end
|
152
233
|
|
234
|
+
##
|
235
|
+
# Builds a Dottie key from an Array of strings and integers.
|
236
|
+
|
237
|
+
def self.build_key(parts)
|
238
|
+
key = ''
|
239
|
+
parts.each_with_index do |part, i|
|
240
|
+
case part
|
241
|
+
when String
|
242
|
+
key << '.' unless i == 0
|
243
|
+
key << part
|
244
|
+
when Fixnum
|
245
|
+
key << "[#{part}]"
|
246
|
+
end
|
247
|
+
end
|
248
|
+
key
|
249
|
+
end
|
250
|
+
|
153
251
|
end
|
data/lib/dottie/freckle.rb
CHANGED
data/lib/dottie/methods.rb
CHANGED
@@ -56,6 +56,31 @@ module Dottie
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
+
##
|
60
|
+
# Deletes the value at the specified key and returns it.
|
61
|
+
|
62
|
+
def delete(key)
|
63
|
+
if Dottie.dottie_key?(key)
|
64
|
+
Dottie.delete(wrapped_object_or_self, key)
|
65
|
+
else
|
66
|
+
super
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
#
|
72
|
+
|
73
|
+
def dottie_flatten
|
74
|
+
Dottie.flatten(wrapped_object_or_self)
|
75
|
+
end
|
76
|
+
|
77
|
+
##
|
78
|
+
#
|
79
|
+
|
80
|
+
def dottie_keys(intermediate = false)
|
81
|
+
Dottie.keys(wrapped_object_or_self, intermediate: intermediate)
|
82
|
+
end
|
83
|
+
|
59
84
|
private
|
60
85
|
|
61
86
|
##
|
data/lib/dottie/version.rb
CHANGED
data/spec/dottie_spec.rb
CHANGED
@@ -20,6 +20,30 @@ describe Dottie do
|
|
20
20
|
arr = ['a', 'b', 'c']
|
21
21
|
expect(Dottie(arr)).to be_a Dottie::Freckle
|
22
22
|
end
|
23
|
+
it 'returns a Dottie::Freckle<Hash> instead of rewrapping it using Dottie[]' do
|
24
|
+
dottie = Dottie[{ 'a' => 'b' }]
|
25
|
+
expect(Dottie[dottie]).to eq dottie
|
26
|
+
end
|
27
|
+
it 'returns a Dottie::Freckle<Array> instead of rewrapping it using Dottie[]' do
|
28
|
+
dottie = Dottie[['a', 'b', 'c']]
|
29
|
+
expect(Dottie[dottie]).to eq dottie
|
30
|
+
end
|
31
|
+
it 'returns a Dottie::Freckle<Hash> instead of rewrapping it using Dottie()' do
|
32
|
+
dottie = Dottie({ 'a' => 'b' })
|
33
|
+
expect(Dottie(dottie)).to eq dottie
|
34
|
+
end
|
35
|
+
it 'returns a Dottie::Freckle<Array> instead of rewrapping it using Dottie()' do
|
36
|
+
dottie = Dottie(['a', 'b', 'c'])
|
37
|
+
expect(Dottie(dottie)).to eq dottie
|
38
|
+
end
|
39
|
+
['a', nil, 1].each do |val|
|
40
|
+
it "fails to create a Dottie::Freckle from an invalid type (#{val.class}) using Dottie[]" do
|
41
|
+
expect{ Dottie[val] }.to raise_error(TypeError)
|
42
|
+
end
|
43
|
+
it "fails to create a Dottie::Freckle from an invalid type (#{val.class}) using Dottie()" do
|
44
|
+
expect{ Dottie(val) }.to raise_error(TypeError)
|
45
|
+
end
|
46
|
+
end
|
23
47
|
|
24
48
|
end
|
25
49
|
|
@@ -120,6 +144,20 @@ describe Dottie do
|
|
120
144
|
end
|
121
145
|
end
|
122
146
|
|
147
|
+
context 'lax keys' do
|
148
|
+
let(:hash) {{ 'a' => 'b', 'c' => [{ 'd' => 'e', '0' => 1 }, { 'f' => 'g' }] }}
|
149
|
+
|
150
|
+
it 'reads a targeted array index number as an integer' do
|
151
|
+
expect(Dottie.get(hash, 'c.0.d')).to eq 'e'
|
152
|
+
end
|
153
|
+
it 'reads a targeted hash key number as a string' do
|
154
|
+
expect(Dottie.get(hash, 'c.0.0')).to eq 1
|
155
|
+
end
|
156
|
+
it 'reads an targeted hash key integer as an integer' do
|
157
|
+
expect(Dottie.get(hash, 'c.0[0]')).to be_nil
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
123
161
|
end
|
124
162
|
|
125
163
|
describe 'key existence' do
|
@@ -255,6 +293,31 @@ describe Dottie do
|
|
255
293
|
end
|
256
294
|
end
|
257
295
|
|
296
|
+
context 'array prepend/append' do
|
297
|
+
before :each do
|
298
|
+
@hash = { 'a' => 'b', 'c' => ['g', 'h', 'i'] }
|
299
|
+
end
|
300
|
+
|
301
|
+
%w( - prepend >> ).each do |key|
|
302
|
+
it "prepends an array element with [#{key}]" do
|
303
|
+
Dottie.set(@hash, "c[#{key}]", 'f')
|
304
|
+
expect(@hash).to eq({ 'a' => 'b', 'c' => ['f', 'g', 'h', 'i'] })
|
305
|
+
end
|
306
|
+
end
|
307
|
+
%w( + append << ).each do |key|
|
308
|
+
it "appends an array element with [#{key}]" do
|
309
|
+
Dottie.set(@hash, "c[#{key}]", 'j')
|
310
|
+
expect(@hash).to eq({ 'a' => 'b', 'c' => ['g', 'h', 'i', 'j'] })
|
311
|
+
end
|
312
|
+
end
|
313
|
+
%w( - + prepend append >> << ).each do |key|
|
314
|
+
it "creates an array at a non-existent key with [#{key}]" do
|
315
|
+
Dottie.set(@hash, "r[#{key}]", 's')
|
316
|
+
expect(@hash).to eq({ 'a' => 'b', 'c' => ['g', 'h', 'i'], 'r' => ['s'] })
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
258
321
|
context 'invalid' do
|
259
322
|
before :each do
|
260
323
|
@hash = { 'a' => 'b', 'c' => { 'd' => 'e' }, 'f' => ['g', 'h'] }
|
@@ -277,6 +340,110 @@ describe Dottie do
|
|
277
340
|
|
278
341
|
end
|
279
342
|
|
343
|
+
describe 'deleting' do
|
344
|
+
|
345
|
+
context 'simple' do
|
346
|
+
before :each do
|
347
|
+
@hash = { 'a' => 'b', 'c' => { 'd' => 'e' } }
|
348
|
+
end
|
349
|
+
|
350
|
+
it 'deletes a standard key' do
|
351
|
+
ret = Dottie.delete(@hash, 'c')
|
352
|
+
expect(ret).to eq({ 'd' => 'e' })
|
353
|
+
expect(@hash).to eq({ 'a' => 'b' })
|
354
|
+
end
|
355
|
+
it 'deletes a dotted key' do
|
356
|
+
ret = Dottie.delete(@hash, 'c.d')
|
357
|
+
expect(ret).to eq 'e'
|
358
|
+
expect(@hash).to eq({ 'a' => 'b', 'c' => {} })
|
359
|
+
end
|
360
|
+
it 'returns nil when attempting to delete a non-existent standard key' do
|
361
|
+
ret = Dottie.delete(@hash, 'x')
|
362
|
+
expect(ret).to be_nil
|
363
|
+
expect(@hash).to eq({ 'a' => 'b', 'c' => { 'd' => 'e' } })
|
364
|
+
end
|
365
|
+
it 'returns nil when attempting to delete a non-existent dotted key' do
|
366
|
+
ret = Dottie.delete(@hash, 'x.y')
|
367
|
+
expect(ret).to be_nil
|
368
|
+
expect(@hash).to eq({ 'a' => 'b', 'c' => { 'd' => 'e' } })
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
context 'array indexes' do
|
373
|
+
before :each do
|
374
|
+
@hash = { 'a' => 'b', 'c' => [{ 'd' => 'e', 'f' => 'g' }, { 'h' => 'i' }] }
|
375
|
+
end
|
376
|
+
|
377
|
+
it 'deletes an element from an array (positive index)' do
|
378
|
+
ret = Dottie.delete(@hash, 'c[0]')
|
379
|
+
expect(ret).to eq({ 'd' => 'e', 'f' => 'g' })
|
380
|
+
expect(@hash).to eq({ 'a' => 'b', 'c' => [{ 'h' => 'i' }] })
|
381
|
+
end
|
382
|
+
it 'deletes an element from an array (negative index)' do
|
383
|
+
ret = Dottie.delete(@hash, 'c[-1]')
|
384
|
+
expect(ret).to eq({ 'h' => 'i' })
|
385
|
+
expect(@hash).to eq({ 'a' => 'b', 'c' => [{ 'd' => 'e', 'f' => 'g' }] })
|
386
|
+
end
|
387
|
+
it 'deletes an element from an array (first)' do
|
388
|
+
ret = Dottie.delete(@hash, 'c[first]')
|
389
|
+
expect(ret).to eq({ 'd' => 'e', 'f' => 'g' })
|
390
|
+
expect(@hash).to eq({ 'a' => 'b', 'c' => [{ 'h' => 'i' }] })
|
391
|
+
end
|
392
|
+
it 'deletes an element from an array (last)' do
|
393
|
+
ret = Dottie.delete(@hash, 'c[last]')
|
394
|
+
expect(ret).to eq({ 'h' => 'i' })
|
395
|
+
expect(@hash).to eq({ 'a' => 'b', 'c' => [{ 'd' => 'e', 'f' => 'g' }] })
|
396
|
+
end
|
397
|
+
it 'deletes an element from a nested structure' do
|
398
|
+
ret = Dottie.delete(@hash, 'c[0].d')
|
399
|
+
expect(ret).to eq('e')
|
400
|
+
expect(@hash).to eq({ 'a' => 'b', 'c' => [{ 'f' => 'g' }, { 'h' => 'i' }] })
|
401
|
+
end
|
402
|
+
it 'returns nil when attempting to delete a non-existent array index' do
|
403
|
+
ret = Dottie.delete(@hash, 'c[3]')
|
404
|
+
expect(ret).to be_nil
|
405
|
+
expect(@hash).to eq({ 'a' => 'b', 'c' => [{ 'd' => 'e', 'f' => 'g' }, { 'h' => 'i' }] })
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
end
|
410
|
+
|
411
|
+
describe 'flattening' do
|
412
|
+
|
413
|
+
context 'hash' do
|
414
|
+
let(:hash) {{ 'a' => 'b', 'c' => { 'd' => ['e', 'f', 'g'] } }}
|
415
|
+
|
416
|
+
it 'flattens a hash' do
|
417
|
+
expect(Dottie.flatten(hash)).to eq({ 'a' => 'b', 'c.d[0]' => 'e', 'c.d[1]' => 'f', 'c.d[2]' => 'g' })
|
418
|
+
end
|
419
|
+
it 'gets flattened hash keys' do
|
420
|
+
expect(Dottie.keys(hash)).to eq ['a', 'c.d[0]', 'c.d[1]', 'c.d[2]']
|
421
|
+
end
|
422
|
+
it 'gets all flattened hash keys' do
|
423
|
+
expect(Dottie.keys(hash, intermediate: true)).to eq ['a', 'c', 'c.d', 'c.d[0]', 'c.d[1]', 'c.d[2]']
|
424
|
+
end
|
425
|
+
end
|
426
|
+
|
427
|
+
context 'array' do
|
428
|
+
let(:arr) { ['x', { 'a' => 'b', 'c' => { 'd' => ['e', 'f', 'g'] } }, 'y'] }
|
429
|
+
|
430
|
+
it 'flattens an array' do
|
431
|
+
expect(Dottie.flatten(arr)).to eq({
|
432
|
+
'[0]' => 'x',
|
433
|
+
'[1].a' => 'b', '[1].c.d[0]' => 'e', '[1].c.d[1]' => 'f', '[1].c.d[2]' => 'g',
|
434
|
+
'[2]' => 'y' })
|
435
|
+
end
|
436
|
+
it 'gets flattened array keys' do
|
437
|
+
expect(Dottie.keys(arr)).to eq ['[0]', '[1].a', '[1].c.d[0]', '[1].c.d[1]', '[1].c.d[2]', '[2]']
|
438
|
+
end
|
439
|
+
it 'gets all flattened array keys' do
|
440
|
+
expect(Dottie.keys(arr, intermediate: true)).to eq [
|
441
|
+
'[0]', '[1]', '[1].a', '[1].c', '[1].c.d', '[1].c.d[0]', '[1].c.d[1]', '[1].c.d[2]', '[2]']
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
445
|
+
end
|
446
|
+
|
280
447
|
describe 'key identification' do
|
281
448
|
|
282
449
|
it 'recognizes a dotted key' do
|
@@ -400,6 +567,34 @@ describe Dottie do
|
|
400
567
|
|
401
568
|
end
|
402
569
|
|
570
|
+
describe 'key building' do
|
571
|
+
|
572
|
+
it 'builds a single-element key' do
|
573
|
+
expect(Dottie.build_key(['a'])).to eq 'a'
|
574
|
+
end
|
575
|
+
|
576
|
+
it 'builds a dotted key' do
|
577
|
+
expect(Dottie.build_key(['a', 'b', 'c'])).to eq 'a.b.c'
|
578
|
+
end
|
579
|
+
|
580
|
+
it 'builds a dotted key a number' do
|
581
|
+
expect(Dottie.build_key(['a', '0', '1', 'b'])).to eq 'a.0.1.b'
|
582
|
+
end
|
583
|
+
|
584
|
+
it 'builds a complex key with a positive integer' do
|
585
|
+
expect(Dottie.build_key(['a', 0, 'b'])).to eq 'a[0].b'
|
586
|
+
end
|
587
|
+
|
588
|
+
it 'builds a complex key with a negative integer' do
|
589
|
+
expect(Dottie.build_key(['a', -1, 'b'])).to eq 'a[-1].b'
|
590
|
+
end
|
591
|
+
|
592
|
+
it 'builds a complex key with consecutive integers' do
|
593
|
+
expect(Dottie.build_key(['a', 0, 1, 'b'])).to eq 'a[0][1].b'
|
594
|
+
end
|
595
|
+
|
596
|
+
end
|
597
|
+
|
403
598
|
describe 'key format variants' do
|
404
599
|
let(:arr) { ['a', 0, 'b', 1, 'c', -2, 'd', -1, 'e'] }
|
405
600
|
|
data/spec/freckle_spec.rb
CHANGED
@@ -2,6 +2,22 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Dottie::Freckle do
|
4
4
|
|
5
|
+
describe 'instantiation' do
|
6
|
+
|
7
|
+
it 'creates a Dottie::Freckle from a Hash' do
|
8
|
+
expect(Dottie::Freckle.new({ 'a' => 'b' })).to be_a Dottie::Freckle
|
9
|
+
end
|
10
|
+
it 'creates a Dottie::Freckle from an Array' do
|
11
|
+
expect(Dottie::Freckle.new(['a', 'b', 'c'])).to be_a Dottie::Freckle
|
12
|
+
end
|
13
|
+
['a', nil, 1].each do |val|
|
14
|
+
it "fails to create a Dottie::Freckle from an invalid type (#{val.class})" do
|
15
|
+
expect{ Dottie::Freckle.new(val) }.to raise_error(TypeError)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
5
21
|
describe 'general' do
|
6
22
|
|
7
23
|
context 'Hash' do
|
@@ -271,4 +287,40 @@ describe Dottie::Freckle do
|
|
271
287
|
|
272
288
|
end
|
273
289
|
|
290
|
+
describe 'flattening' do
|
291
|
+
|
292
|
+
context 'hash' do
|
293
|
+
let(:freckle) { Dottie::Freckle.new({ 'a' => 'b', 'c' => { 'd' => ['e', 'f', 'g'] } }) }
|
294
|
+
|
295
|
+
it 'flattens a hash' do
|
296
|
+
expect(freckle.dottie_flatten).to eq({ 'a' => 'b', 'c.d[0]' => 'e', 'c.d[1]' => 'f', 'c.d[2]' => 'g' })
|
297
|
+
end
|
298
|
+
it 'gets flattened hash keys' do
|
299
|
+
expect(freckle.dottie_keys).to eq ['a', 'c.d[0]', 'c.d[1]', 'c.d[2]']
|
300
|
+
end
|
301
|
+
it 'gets all flattened hash keys' do
|
302
|
+
expect(freckle.dottie_keys(true)).to eq ['a', 'c', 'c.d', 'c.d[0]', 'c.d[1]', 'c.d[2]']
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
context 'array' do
|
307
|
+
let(:freckle) { Dottie::Freckle.new(['x', { 'a' => 'b', 'c' => { 'd' => ['e', 'f', 'g'] } }, 'y']) }
|
308
|
+
|
309
|
+
it 'flattens an array' do
|
310
|
+
expect(freckle.dottie_flatten).to eq({
|
311
|
+
'[0]' => 'x',
|
312
|
+
'[1].a' => 'b', '[1].c.d[0]' => 'e', '[1].c.d[1]' => 'f', '[1].c.d[2]' => 'g',
|
313
|
+
'[2]' => 'y' })
|
314
|
+
end
|
315
|
+
it 'gets flattened array keys' do
|
316
|
+
expect(freckle.dottie_keys).to eq ['[0]', '[1].a', '[1].c.d[0]', '[1].c.d[1]', '[1].c.d[2]', '[2]']
|
317
|
+
end
|
318
|
+
it 'gets all flattened array keys' do
|
319
|
+
expect(freckle.dottie_keys(true)).to eq [
|
320
|
+
'[0]', '[1]', '[1].a', '[1].c', '[1].c.d', '[1].c.d[0]', '[1].c.d[1]', '[1].c.d[2]', '[2]']
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
end
|
325
|
+
|
274
326
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dottie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Pearson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-08-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -101,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
101
101
|
version: '0'
|
102
102
|
requirements: []
|
103
103
|
rubyforge_project:
|
104
|
-
rubygems_version: 2.
|
104
|
+
rubygems_version: 2.4.5
|
105
105
|
signing_key:
|
106
106
|
specification_version: 4
|
107
107
|
summary: Deep Hash and Array access with dotted keys
|
@@ -111,4 +111,3 @@ test_files:
|
|
111
111
|
- spec/freckle_spec.rb
|
112
112
|
- spec/hash_spec.rb
|
113
113
|
- spec/spec_helper.rb
|
114
|
-
has_rdoc:
|