dottie 0.0.1

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.
@@ -0,0 +1,274 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dottie::Freckle do
4
+
5
+ describe 'general' do
6
+
7
+ context 'Hash' do
8
+ let(:freckle) { Dottie::Freckle.new({ 'a' => 'b' }) }
9
+
10
+ it 'makes the original Hash accessible' do
11
+ expect(freckle.hash).to eq({ 'a' => 'b' })
12
+ end
13
+ it 'makes the original Hash accessible' do
14
+ expect(freckle.wrapped_object).to eq({ 'a' => 'b' })
15
+ end
16
+ it 'raises an error if the wrong type is requested' do
17
+ expect{ freckle.array }.to raise_error TypeError
18
+ end
19
+ end
20
+
21
+ context 'Array' do
22
+ let(:freckle) { Dottie::Freckle.new([1, 2]) }
23
+
24
+ it 'makes the original Array accessible' do
25
+ expect(freckle.array).to eq([1, 2])
26
+ end
27
+ it 'makes the original Array accessible' do
28
+ expect(freckle.wrapped_object).to eq([1, 2])
29
+ end
30
+ it 'raises an error if the wrong type is requested' do
31
+ expect{ freckle.hash }.to raise_error TypeError
32
+ end
33
+ end
34
+
35
+ end
36
+
37
+ describe 'reading' do
38
+
39
+ context 'simple' do
40
+ let(:freckle) { Dottie::Freckle.new({ 'a' => 'b', 'c' => { 'd' => 'e' } }) }
41
+
42
+ it 'reads a standard key' do
43
+ expect(freckle['a']).to eq 'b'
44
+ end
45
+ it 'returns nil for a missing standard key' do
46
+ expect(freckle['d']).to be_nil
47
+ end
48
+ it 'reads a dotted key' do
49
+ expect(freckle['c.d']).to eq 'e'
50
+ end
51
+ it 'returns nil for a missing dotted key' do
52
+ expect(freckle['c.e']).to be_nil
53
+ end
54
+ it 'returns nil for a missing nested dotted key' do
55
+ expect(freckle['c.e.g.x.y']).to be_nil
56
+ end
57
+ end
58
+
59
+ context 'ending array indexes' do
60
+ let(:freckle) { Dottie::Freckle.new({ 'a' => 'b', 'c' => %w( d e f ) }) }
61
+
62
+ it 'reads an integer key' do
63
+ expect(freckle['c[0]']).to eq 'd'
64
+ end
65
+ it 'reads a negative integer key' do
66
+ expect(freckle['c[-1]']).to eq 'f'
67
+ end
68
+ it 'reads a named key (first)' do
69
+ expect(freckle['c[first]']).to eq 'd'
70
+ end
71
+ it 'reads a named key (last)' do
72
+ expect(freckle['c[last]']).to eq 'f'
73
+ end
74
+ it 'returns nil for a missing index' do
75
+ expect(freckle['c[4]']).to be_nil
76
+ end
77
+ it 'returns nil for a missing array' do
78
+ expect(freckle['x[4]']).to be_nil
79
+ end
80
+ end
81
+
82
+ context 'middle array indexes' do
83
+ let(:freckle) { Dottie::Freckle.new({ 'a' => 'b', 'c' => [{ 'd' => 'e' }, { 'f' => 'g' }] }) }
84
+
85
+ it 'reads an integer key' do
86
+ expect(freckle['c[0].d']).to eq 'e'
87
+ end
88
+ it 'reads a negative integer key' do
89
+ expect(freckle['c[-1].f']).to eq 'g'
90
+ end
91
+ it 'reads a named key (first)' do
92
+ expect(freckle['c[first].d']).to eq 'e'
93
+ end
94
+ it 'reads a named key (last)' do
95
+ expect(freckle['c[last].f']).to eq 'g'
96
+ end
97
+ it 'returns nil for a missing index' do
98
+ expect(freckle['c[4].r']).to be_nil
99
+ end
100
+ it 'returns nil for a missing array' do
101
+ expect(freckle['x[4].s']).to be_nil
102
+ end
103
+ end
104
+
105
+ context 'consecutive array indexes' do
106
+ let(:freckle) { Dottie::Freckle.new({ 'a' => 'b', 'c' => [ [{}, { 'd' => 'e' }] ] }) }
107
+
108
+ it 'reads an integer key' do
109
+ expect(freckle['c[0][1].d']).to eq 'e'
110
+ end
111
+ it 'reads a negative integer key' do
112
+ expect(freckle['c[-1][1].d']).to eq 'e'
113
+ end
114
+ it 'reads a named key (first)' do
115
+ expect(freckle['c[first][last].d']).to eq 'e'
116
+ end
117
+ it 'reads a named key (last)' do
118
+ expect(freckle['c[last][last].d']).to eq 'e'
119
+ end
120
+ it 'returns nil for a missing index' do
121
+ expect(freckle['c[4][5]']).to be_nil
122
+ end
123
+ it 'returns nil for a missing array' do
124
+ expect(freckle['x[4][5]']).to be_nil
125
+ end
126
+ end
127
+
128
+ end
129
+
130
+ describe 'key existence' do
131
+ let(:freckle) { Dottie::Freckle.new({ 'a' => 'b', 'c' => { 'd' => ['e', 'f', 'g'] } }) }
132
+
133
+ it "finds a standard key" do
134
+ expect(freckle.has_key?('a')).to be_true
135
+ end
136
+ it "does not find a missing standard key" do
137
+ expect(freckle.has_key?('x')).to be_false
138
+ end
139
+ it "finds a Dottie key (Hash value)" do
140
+ expect(freckle.has_key?('c.d')).to be_true
141
+ end
142
+ it "finds a Dottie key (Array element)" do
143
+ expect(freckle.has_key?('c.d[0]')).to be_true
144
+ end
145
+ it "does not find a missing Dottie key (first part is a String)" do
146
+ expect(freckle.has_key?('a.b')).to be_false
147
+ end
148
+ it "does not find a missing Dottie key (first part exists)" do
149
+ expect(freckle.has_key?('c.x')).to be_false
150
+ end
151
+ it "does not find a missing Dottie key (outside Array bounds)" do
152
+ expect(freckle.has_key?('c.d[4]')).to be_false
153
+ end
154
+ it "does not find a missing Dottie key (no part exists)" do
155
+ expect(freckle.has_key?('x.y')).to be_false
156
+ end
157
+ end
158
+
159
+ describe 'fetching' do
160
+ let(:freckle) { Dottie::Freckle.new({ 'a' => 'b', 'c' => { 'd' => ['e', 'f', 'g'] } }) }
161
+
162
+ context 'no default' do
163
+ it 'fetches a standard key' do
164
+ expect(freckle.fetch('a')).to eq 'b'
165
+ end
166
+ it 'fetches a Dottie key (Hash value)' do
167
+ expect(freckle.fetch('c.d')).to eq ['e', 'f', 'g']
168
+ end
169
+ it 'fetches a Dottie key (Array element)' do
170
+ expect(freckle.fetch('c.d[1]')).to eq 'f'
171
+ end
172
+ it 'raises on a missing standard key' do
173
+ expect{ freckle.fetch('x') }.to raise_error KeyError
174
+ end
175
+ it 'raises on a missing Dottie key' do
176
+ expect{ freckle.fetch('x.y') }.to raise_error KeyError
177
+ end
178
+ end
179
+
180
+ context 'with default' do
181
+ it 'fetches a standard key' do
182
+ expect(freckle.fetch('a', 'z')).to eq 'b'
183
+ end
184
+ it 'fetches a Dottie key' do
185
+ expect(freckle.fetch('c.d', 'z')).to eq ['e', 'f', 'g']
186
+ end
187
+ it 'returns a default for a missing standard key' do
188
+ expect(freckle.fetch('x', 'z')).to eq 'z'
189
+ end
190
+ it 'returns a default for a missing Dottie key' do
191
+ expect(freckle.fetch('x', 'z')).to eq 'z'
192
+ end
193
+ end
194
+
195
+ context 'with block' do
196
+ it 'fetches a standard key' do
197
+ expect(freckle.fetch('a'){ |key| key.upcase }).to eq 'b'
198
+ end
199
+ it 'fetches a Dottie key' do
200
+ expect(freckle.fetch('c.d'){ |key| key.upcase }).to eq ['e', 'f', 'g']
201
+ end
202
+ it 'yields to a block for a missing standard key' do
203
+ expect(freckle.fetch('x'){ |key| key.upcase }).to eq 'X'
204
+ end
205
+ it 'yields to a block for a missing Dottie key' do
206
+ expect(freckle.fetch('x.y'){ |key| key.upcase }).to eq 'X.Y'
207
+ end
208
+ end
209
+
210
+ end
211
+
212
+ describe 'writing' do
213
+
214
+ context 'simple' do
215
+ before :each do
216
+ @freckle = Dottie::Freckle.new({ 'a' => 'b', 'c' => { 'd' => 'e' } })
217
+ end
218
+
219
+ it 'overwrites a standard key' do
220
+ @freckle['a'] = 'x'
221
+ expect(@freckle.hash).to eq({ 'a' => 'x', 'c' => { 'd' => 'e' } })
222
+ end
223
+ it 'creates a hash at a non-existent standard key' do
224
+ @freckle['y'] = 'z'
225
+ expect(@freckle.hash).to eq({ 'a' => 'b', 'c' => { 'd' => 'e' }, 'y' => 'z' })
226
+ end
227
+ it 'overwrites a dotted key' do
228
+ @freckle['c.d'] = 'm'
229
+ expect(@freckle.hash).to eq({ 'a' => 'b', 'c' => { 'd' => 'm' } })
230
+ end
231
+ it 'creates a hash at a non-existent dotted key' do
232
+ @freckle['n.o'] = 'p'
233
+ expect(@freckle.hash).to eq({ 'a' => 'b', 'c' => { 'd' => 'e' }, 'n' => { 'o' => 'p' } })
234
+ end
235
+ end
236
+
237
+ context 'array indexes' do
238
+ before :each do
239
+ @freckle = Dottie::Freckle.new({ 'a' => 'b', 'c' => %w( d e f ) })
240
+ end
241
+
242
+ it 'overwrites an array element (positive index)' do
243
+ @freckle['c[0]'] = 'x'
244
+ expect(@freckle.hash).to eq({ 'a' => 'b', 'c' => ['x', 'e', 'f'] })
245
+ end
246
+ it 'overwrites an array element (negative index)' do
247
+ @freckle['c[-2]'] = 'y'
248
+ expect(@freckle.hash).to eq({ 'a' => 'b', 'c' => ['d', 'y', 'f'] })
249
+ end
250
+ it 'overwrites an array element ("first")' do
251
+ @freckle['c[first]'] = 'm'
252
+ expect(@freckle.hash).to eq({ 'a' => 'b', 'c' => ['m', 'e', 'f'] })
253
+ end
254
+ it 'overwrites an array element ("last")' do
255
+ @freckle['c[last]'] = 'n'
256
+ expect(@freckle.hash).to eq({ 'a' => 'b', 'c' => ['d', 'e', 'n'] })
257
+ end
258
+ it 'creates an array at a non-existent key (positive index)' do
259
+ @freckle['r[0]'] = 's'
260
+ expect(@freckle.hash).to eq({ 'a' => 'b', 'c' => ['d', 'e', 'f'], 'r' => ['s'] })
261
+ end
262
+ it 'creates an array at a non-existent key ("first")' do
263
+ @freckle['r[first]'] = 's'
264
+ expect(@freckle.hash).to eq({ 'a' => 'b', 'c' => ['d', 'e', 'f'], 'r' => ['s'] })
265
+ end
266
+ it 'adds an array element' do
267
+ @freckle['c[3]'] = 'g'
268
+ expect(@freckle.hash).to eq({ 'a' => 'b', 'c' => ['d', 'e', 'f', 'g'] })
269
+ end
270
+ end
271
+
272
+ end
273
+
274
+ end
data/spec/hash_spec.rb ADDED
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+ require 'dottie/ext'
3
+
4
+ describe Hash do
5
+
6
+ describe 'Dottie extensions' do
7
+ before :each do
8
+ @hash = { 'a' => 'b', 'c' => { 'd' => 'e' } }
9
+ end
10
+
11
+ context 'untouched' do
12
+ it "should not have Dottie's behavior" do
13
+ expect(@hash['a.b']).to be_nil
14
+ end
15
+ end
16
+
17
+ context 'wrapped' do
18
+ let(:freckle) { @hash.dottie }
19
+
20
+ it 'is no longer a Hash' do
21
+ expect(freckle).to_not be_a Hash
22
+ end
23
+ it 'wraps a Hash in a Dottie::Freckle' do
24
+ expect(freckle).to be_a Dottie::Freckle
25
+ end
26
+ it 'acts like a regular Hash for standard keys' do
27
+ expect(freckle['a']).to eq 'b'
28
+ end
29
+ it "has Dottie's behavior" do
30
+ expect(freckle['c.d']).to eq 'e'
31
+ end
32
+ it "does not add Dottie's behavior to the original Hash" do
33
+ expect(@hash['a.b']).to be_nil
34
+ end
35
+ end
36
+
37
+ context 'mixed in' do
38
+ before :each do
39
+ @hash.dottie!
40
+ end
41
+
42
+ it 'is still a Hash' do
43
+ expect(@hash).to be_a Hash
44
+ end
45
+ it 'acts like a regular Hash for standard keys' do
46
+ expect(@hash['a']).to eq 'b'
47
+ end
48
+ it "adds Dottie's behavior to a Hash" do
49
+ expect(@hash['c.d']).to eq 'e'
50
+ end
51
+ end
52
+
53
+ end
54
+
55
+ end
@@ -0,0 +1 @@
1
+ require 'dottie'
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dottie
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Nick Pearson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-08 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.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '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
+ description: |-
56
+ Deeply access nested Hash/Array data structures
57
+ without checking for the existence of every node
58
+ along the way.
59
+ email:
60
+ - nick@banyantheory.com
61
+ executables: []
62
+ extensions: []
63
+ extra_rdoc_files: []
64
+ files:
65
+ - ".gitignore"
66
+ - Gemfile
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - dottie.gemspec
71
+ - lib/dottie.rb
72
+ - lib/dottie/ext.rb
73
+ - lib/dottie/ext/array.rb
74
+ - lib/dottie/ext/hash.rb
75
+ - lib/dottie/freckle.rb
76
+ - lib/dottie/helper.rb
77
+ - lib/dottie/methods.rb
78
+ - lib/dottie/version.rb
79
+ - spec/array_spec.rb
80
+ - spec/dottie_spec.rb
81
+ - spec/freckle_spec.rb
82
+ - spec/hash_spec.rb
83
+ - spec/spec_helper.rb
84
+ homepage: https://github.com/nickpearson/dottie
85
+ licenses:
86
+ - MIT
87
+ metadata: {}
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project:
104
+ rubygems_version: 2.2.2
105
+ signing_key:
106
+ specification_version: 4
107
+ summary: Deep Hash and Array access with dotted keys
108
+ test_files:
109
+ - spec/array_spec.rb
110
+ - spec/dottie_spec.rb
111
+ - spec/freckle_spec.rb
112
+ - spec/hash_spec.rb
113
+ - spec/spec_helper.rb
114
+ has_rdoc: