spec/dottie_spec.rb in dottie-0.0.1 vs spec/dottie_spec.rb in dottie-0.0.2
- old
+ new
@@ -18,10 +18,34 @@
end
it 'creates a Dottie::Freckle from an Array using Dottie()' do
arr = ['a', 'b', 'c']
expect(Dottie(arr)).to be_a Dottie::Freckle
end
+ it 'returns a Dottie::Freckle<Hash> instead of rewrapping it using Dottie[]' do
+ dottie = Dottie[{ 'a' => 'b' }]
+ expect(Dottie[dottie]).to eq dottie
+ end
+ it 'returns a Dottie::Freckle<Array> instead of rewrapping it using Dottie[]' do
+ dottie = Dottie[['a', 'b', 'c']]
+ expect(Dottie[dottie]).to eq dottie
+ end
+ it 'returns a Dottie::Freckle<Hash> instead of rewrapping it using Dottie()' do
+ dottie = Dottie({ 'a' => 'b' })
+ expect(Dottie(dottie)).to eq dottie
+ end
+ it 'returns a Dottie::Freckle<Array> instead of rewrapping it using Dottie()' do
+ dottie = Dottie(['a', 'b', 'c'])
+ expect(Dottie(dottie)).to eq dottie
+ end
+ ['a', nil, 1].each do |val|
+ it "fails to create a Dottie::Freckle from an invalid type (#{val.class}) using Dottie[]" do
+ expect{ Dottie[val] }.to raise_error(TypeError)
+ end
+ it "fails to create a Dottie::Freckle from an invalid type (#{val.class}) using Dottie()" do
+ expect{ Dottie(val) }.to raise_error(TypeError)
+ end
+ end
end
describe 'reading' do
@@ -118,10 +142,24 @@
it 'returns nil for a missing array' do
expect(Dottie.get(hash, 'x[4][5]')).to be_nil
end
end
+ context 'lax keys' do
+ let(:hash) {{ 'a' => 'b', 'c' => [{ 'd' => 'e', '0' => 1 }, { 'f' => 'g' }] }}
+
+ it 'reads a targeted array index number as an integer' do
+ expect(Dottie.get(hash, 'c.0.d')).to eq 'e'
+ end
+ it 'reads a targeted hash key number as a string' do
+ expect(Dottie.get(hash, 'c.0.0')).to eq 1
+ end
+ it 'reads an targeted hash key integer as an integer' do
+ expect(Dottie.get(hash, 'c.0[0]')).to be_nil
+ end
+ end
+
end
describe 'key existence' do
let(:hash) {{ 'a' => 'b', 'c' => { 'd' => ['e', 'f', 'g'] } }}
@@ -253,10 +291,35 @@
Dottie.set(@hash, 'c[3]', 'g')
expect(@hash).to eq({ 'a' => 'b', 'c' => ['d', 'e', 'f', 'g'] })
end
end
+ context 'array prepend/append' do
+ before :each do
+ @hash = { 'a' => 'b', 'c' => ['g', 'h', 'i'] }
+ end
+
+ %w( - prepend >> ).each do |key|
+ it "prepends an array element with [#{key}]" do
+ Dottie.set(@hash, "c[#{key}]", 'f')
+ expect(@hash).to eq({ 'a' => 'b', 'c' => ['f', 'g', 'h', 'i'] })
+ end
+ end
+ %w( + append << ).each do |key|
+ it "appends an array element with [#{key}]" do
+ Dottie.set(@hash, "c[#{key}]", 'j')
+ expect(@hash).to eq({ 'a' => 'b', 'c' => ['g', 'h', 'i', 'j'] })
+ end
+ end
+ %w( - + prepend append >> << ).each do |key|
+ it "creates an array at a non-existent key with [#{key}]" do
+ Dottie.set(@hash, "r[#{key}]", 's')
+ expect(@hash).to eq({ 'a' => 'b', 'c' => ['g', 'h', 'i'], 'r' => ['s'] })
+ end
+ end
+ end
+
context 'invalid' do
before :each do
@hash = { 'a' => 'b', 'c' => { 'd' => 'e' }, 'f' => ['g', 'h'] }
end
@@ -275,10 +338,114 @@
end
end
end
+ describe 'deleting' do
+
+ context 'simple' do
+ before :each do
+ @hash = { 'a' => 'b', 'c' => { 'd' => 'e' } }
+ end
+
+ it 'deletes a standard key' do
+ ret = Dottie.delete(@hash, 'c')
+ expect(ret).to eq({ 'd' => 'e' })
+ expect(@hash).to eq({ 'a' => 'b' })
+ end
+ it 'deletes a dotted key' do
+ ret = Dottie.delete(@hash, 'c.d')
+ expect(ret).to eq 'e'
+ expect(@hash).to eq({ 'a' => 'b', 'c' => {} })
+ end
+ it 'returns nil when attempting to delete a non-existent standard key' do
+ ret = Dottie.delete(@hash, 'x')
+ expect(ret).to be_nil
+ expect(@hash).to eq({ 'a' => 'b', 'c' => { 'd' => 'e' } })
+ end
+ it 'returns nil when attempting to delete a non-existent dotted key' do
+ ret = Dottie.delete(@hash, 'x.y')
+ expect(ret).to be_nil
+ expect(@hash).to eq({ 'a' => 'b', 'c' => { 'd' => 'e' } })
+ end
+ end
+
+ context 'array indexes' do
+ before :each do
+ @hash = { 'a' => 'b', 'c' => [{ 'd' => 'e', 'f' => 'g' }, { 'h' => 'i' }] }
+ end
+
+ it 'deletes an element from an array (positive index)' do
+ ret = Dottie.delete(@hash, 'c[0]')
+ expect(ret).to eq({ 'd' => 'e', 'f' => 'g' })
+ expect(@hash).to eq({ 'a' => 'b', 'c' => [{ 'h' => 'i' }] })
+ end
+ it 'deletes an element from an array (negative index)' do
+ ret = Dottie.delete(@hash, 'c[-1]')
+ expect(ret).to eq({ 'h' => 'i' })
+ expect(@hash).to eq({ 'a' => 'b', 'c' => [{ 'd' => 'e', 'f' => 'g' }] })
+ end
+ it 'deletes an element from an array (first)' do
+ ret = Dottie.delete(@hash, 'c[first]')
+ expect(ret).to eq({ 'd' => 'e', 'f' => 'g' })
+ expect(@hash).to eq({ 'a' => 'b', 'c' => [{ 'h' => 'i' }] })
+ end
+ it 'deletes an element from an array (last)' do
+ ret = Dottie.delete(@hash, 'c[last]')
+ expect(ret).to eq({ 'h' => 'i' })
+ expect(@hash).to eq({ 'a' => 'b', 'c' => [{ 'd' => 'e', 'f' => 'g' }] })
+ end
+ it 'deletes an element from a nested structure' do
+ ret = Dottie.delete(@hash, 'c[0].d')
+ expect(ret).to eq('e')
+ expect(@hash).to eq({ 'a' => 'b', 'c' => [{ 'f' => 'g' }, { 'h' => 'i' }] })
+ end
+ it 'returns nil when attempting to delete a non-existent array index' do
+ ret = Dottie.delete(@hash, 'c[3]')
+ expect(ret).to be_nil
+ expect(@hash).to eq({ 'a' => 'b', 'c' => [{ 'd' => 'e', 'f' => 'g' }, { 'h' => 'i' }] })
+ end
+ end
+
+ end
+
+ describe 'flattening' do
+
+ context 'hash' do
+ let(:hash) {{ 'a' => 'b', 'c' => { 'd' => ['e', 'f', 'g'] } }}
+
+ it 'flattens a hash' do
+ expect(Dottie.flatten(hash)).to eq({ 'a' => 'b', 'c.d[0]' => 'e', 'c.d[1]' => 'f', 'c.d[2]' => 'g' })
+ end
+ it 'gets flattened hash keys' do
+ expect(Dottie.keys(hash)).to eq ['a', 'c.d[0]', 'c.d[1]', 'c.d[2]']
+ end
+ it 'gets all flattened hash keys' do
+ expect(Dottie.keys(hash, intermediate: true)).to eq ['a', 'c', 'c.d', 'c.d[0]', 'c.d[1]', 'c.d[2]']
+ end
+ end
+
+ context 'array' do
+ let(:arr) { ['x', { 'a' => 'b', 'c' => { 'd' => ['e', 'f', 'g'] } }, 'y'] }
+
+ it 'flattens an array' do
+ expect(Dottie.flatten(arr)).to eq({
+ '[0]' => 'x',
+ '[1].a' => 'b', '[1].c.d[0]' => 'e', '[1].c.d[1]' => 'f', '[1].c.d[2]' => 'g',
+ '[2]' => 'y' })
+ end
+ it 'gets flattened array keys' do
+ expect(Dottie.keys(arr)).to eq ['[0]', '[1].a', '[1].c.d[0]', '[1].c.d[1]', '[1].c.d[2]', '[2]']
+ end
+ it 'gets all flattened array keys' do
+ expect(Dottie.keys(arr, intermediate: true)).to eq [
+ '[0]', '[1]', '[1].a', '[1].c', '[1].c.d', '[1].c.d[0]', '[1].c.d[1]', '[1].c.d[2]', '[2]']
+ end
+ end
+
+ end
+
describe 'key identification' do
it 'recognizes a dotted key' do
key = 'a.b.c'
expect(Dottie.dottie_key?(key)).to be_true
@@ -394,9 +561,37 @@
it 'collapses multiple dots into a single dot' do
str = 'a.b..c'
arr = ['a', 'b', 'c']
expect(Dottie.key_parts(str)).to eq arr
+ end
+
+ end
+
+ describe 'key building' do
+
+ it 'builds a single-element key' do
+ expect(Dottie.build_key(['a'])).to eq 'a'
+ end
+
+ it 'builds a dotted key' do
+ expect(Dottie.build_key(['a', 'b', 'c'])).to eq 'a.b.c'
+ end
+
+ it 'builds a dotted key a number' do
+ expect(Dottie.build_key(['a', '0', '1', 'b'])).to eq 'a.0.1.b'
+ end
+
+ it 'builds a complex key with a positive integer' do
+ expect(Dottie.build_key(['a', 0, 'b'])).to eq 'a[0].b'
+ end
+
+ it 'builds a complex key with a negative integer' do
+ expect(Dottie.build_key(['a', -1, 'b'])).to eq 'a[-1].b'
+ end
+
+ it 'builds a complex key with consecutive integers' do
+ expect(Dottie.build_key(['a', 0, 1, 'b'])).to eq 'a[0][1].b'
end
end
describe 'key format variants' do