summaryrefslogtreecommitdiff
path: root/spec/hashie/extensions/symbolize_keys_spec.rb
blob: be345ead64817689902473f67c9e6e65457c947c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
require 'spec_helper'
require 'support/module_context'

def invoke(method)
  if subject == object
    subject.public_send(method)
  else
    subject.public_send(method, object)
  end
end

shared_examples 'symbolize_keys!' do
  it 'converts keys to symbols' do
    object['abc'] = 'abc'
    object['def'] = 'def'
    invoke :symbolize_keys!
    expect((object.keys & %i[abc def]).size).to eq 2
  end

  it 'converts nested instances of the same class' do
    object['ab'] = dummy_class.new
    object['ab']['cd'] = dummy_class.new
    object['ab']['cd']['ef'] = 'abcdef'
    invoke :symbolize_keys!
    expect(object).to eq(ab: { cd: { ef: 'abcdef' } })
  end

  it 'converts nested hashes' do
    object['ab'] = { 'cd' => { 'ef' => 'abcdef' } }
    invoke :symbolize_keys!
    expect(object).to eq(ab: { cd: { ef: 'abcdef' } })
  end

  it 'performs deep conversion within nested arrays' do
    object['ab'] = []
    object['ab'] << dummy_class.new
    object['ab'] << dummy_class.new
    object['ab'][0]['cd'] = 'abcd'
    object['ab'][1]['ef'] = 'abef'
    new_object = invoke :symbolize_keys
    expect(new_object).to eq(ab: [{ cd: 'abcd' }, { ef: 'abef' }])
  end
end

shared_examples 'symbolize_keys' do
  it 'converts keys to symbols' do
    object['abc'] = 'def'
    copy = invoke :symbolize_keys
    expect(copy[:abc]).to eq 'def'
  end

  it 'does not alter the original' do
    object['abc'] = 'def'
    copy = invoke :symbolize_keys
    expect(object.keys).to eq ['abc']
    expect(copy.keys).to eq [:abc]
  end
end

describe Hashie::Extensions::SymbolizeKeys do
  include_context 'included hash module'
  let(:object) { subject }

  describe '#symbolize_keys!' do
    include_examples 'symbolize_keys!'
    let(:object) { subject }

    it 'returns itself' do
      expect(subject.symbolize_keys!).to eq subject
    end
  end

  describe '#symbolize_keys' do
    include_examples 'symbolize_keys'
  end

  context 'class methods' do
    subject { described_class }
    let(:object) { {} }

    describe '.symbolize_keys' do
      include_examples 'symbolize_keys'
    end
    describe '.symbolize_keys!' do
      include_examples 'symbolize_keys!'
    end
  end

  context 'singleton methods' do
    subject { Hash }
    let(:object) do
      subject.new.merge('a' => 1, 'b' => { 'c' => 2 }).extend(Hashie::Extensions::SymbolizeKeys)
    end
    let(:expected_hash) { { a: 1, b: { c: 2 } } }

    describe '.symbolize_keys' do
      it 'does not raise error' do
        expect { object.symbolize_keys }.not_to raise_error
      end
      it 'produces expected symbolized hash' do
        expect(object.symbolize_keys).to eq(expected_hash)
      end
    end
    describe '.symbolize_keys!' do
      it 'does not raise error' do
        expect { object.symbolize_keys! }.not_to raise_error
      end
      it 'produces expected symbolized hash' do
        expect(object.symbolize_keys!).to eq(expected_hash)
      end
    end
  end
end

describe Hashie do
  let!(:dummy_class) do
    klass = Class.new(::Hash)
    klass.send :include, Hashie::Extensions::StringifyKeys
    klass
  end

  subject { described_class }
  let(:object) { {} }

  describe '.symbolize_keys' do
    include_examples 'symbolize_keys'
  end
  describe '.symbolize_keys!' do
    include_examples 'symbolize_keys!'
  end
end