hashie 3.4.2 → 5.0.0
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 +5 -5
- data/CHANGELOG.md +518 -122
- data/CONTRIBUTING.md +24 -7
- data/LICENSE +1 -1
- data/README.md +455 -48
- data/Rakefile +18 -1
- data/UPGRADING.md +157 -7
- data/hashie.gemspec +14 -7
- data/lib/hashie/array.rb +21 -0
- data/lib/hashie/clash.rb +24 -12
- data/lib/hashie/dash.rb +56 -31
- data/lib/hashie/extensions/active_support/core_ext/hash.rb +14 -0
- data/lib/hashie/extensions/array/pretty_inspect.rb +19 -0
- data/lib/hashie/extensions/coercion.rb +91 -52
- data/lib/hashie/extensions/dash/coercion.rb +25 -0
- data/lib/hashie/extensions/dash/indifferent_access.rb +30 -1
- data/lib/hashie/extensions/dash/predefined_values.rb +88 -0
- data/lib/hashie/extensions/dash/property_translation.rb +59 -30
- data/lib/hashie/extensions/deep_fetch.rb +5 -3
- data/lib/hashie/extensions/deep_find.rb +14 -5
- data/lib/hashie/extensions/deep_locate.rb +40 -21
- data/lib/hashie/extensions/deep_merge.rb +28 -10
- data/lib/hashie/extensions/ignore_undeclared.rb +6 -4
- data/lib/hashie/extensions/indifferent_access.rb +49 -8
- data/lib/hashie/extensions/key_conflict_warning.rb +55 -0
- data/lib/hashie/extensions/mash/define_accessors.rb +90 -0
- data/lib/hashie/extensions/mash/keep_original_keys.rb +53 -0
- data/lib/hashie/extensions/mash/permissive_respond_to.rb +61 -0
- data/lib/hashie/extensions/mash/safe_assignment.rb +3 -1
- data/lib/hashie/extensions/mash/symbolize_keys.rb +38 -0
- data/lib/hashie/extensions/method_access.rb +77 -19
- data/lib/hashie/extensions/parsers/yaml_erb_parser.rb +29 -5
- data/lib/hashie/extensions/ruby_version.rb +60 -0
- data/lib/hashie/extensions/ruby_version_check.rb +21 -0
- data/lib/hashie/extensions/strict_key_access.rb +77 -0
- data/lib/hashie/extensions/stringify_keys.rb +8 -5
- data/lib/hashie/extensions/symbolize_keys.rb +21 -7
- data/lib/hashie/hash.rb +18 -11
- data/lib/hashie/logger.rb +18 -0
- data/lib/hashie/mash.rb +196 -55
- data/lib/hashie/railtie.rb +21 -0
- data/lib/hashie/rash.rb +7 -7
- data/lib/hashie/utils.rb +44 -0
- data/lib/hashie/version.rb +1 -1
- data/lib/hashie.rb +34 -16
- metadata +30 -79
- data/spec/hashie/clash_spec.rb +0 -48
- data/spec/hashie/dash_spec.rb +0 -513
- data/spec/hashie/extensions/autoload_spec.rb +0 -24
- data/spec/hashie/extensions/coercion_spec.rb +0 -625
- data/spec/hashie/extensions/dash/indifferent_access_spec.rb +0 -84
- data/spec/hashie/extensions/deep_fetch_spec.rb +0 -97
- data/spec/hashie/extensions/deep_find_spec.rb +0 -45
- data/spec/hashie/extensions/deep_locate_spec.rb +0 -124
- data/spec/hashie/extensions/deep_merge_spec.rb +0 -45
- data/spec/hashie/extensions/ignore_undeclared_spec.rb +0 -46
- data/spec/hashie/extensions/indifferent_access_spec.rb +0 -219
- data/spec/hashie/extensions/indifferent_access_with_rails_hwia_spec.rb +0 -208
- data/spec/hashie/extensions/key_conversion_spec.rb +0 -12
- data/spec/hashie/extensions/mash/safe_assignment_spec.rb +0 -23
- data/spec/hashie/extensions/merge_initializer_spec.rb +0 -23
- data/spec/hashie/extensions/method_access_spec.rb +0 -184
- data/spec/hashie/extensions/stringify_keys_spec.rb +0 -101
- data/spec/hashie/extensions/symbolize_keys_spec.rb +0 -106
- data/spec/hashie/hash_spec.rb +0 -84
- data/spec/hashie/mash_spec.rb +0 -683
- data/spec/hashie/parsers/yaml_erb_parser_spec.rb +0 -29
- data/spec/hashie/rash_spec.rb +0 -77
- data/spec/hashie/trash_spec.rb +0 -268
- data/spec/hashie/version_spec.rb +0 -7
- data/spec/spec_helper.rb +0 -15
- data/spec/support/module_context.rb +0 -11
- data/spec/support/ruby_version.rb +0 -10
@@ -1,208 +0,0 @@
|
|
1
|
-
# This set of tests verifies that Hashie::Extensions::IndifferentAccess works with
|
2
|
-
# ActiveSupport HashWithIndifferentAccess hashes. See #164 and #166 for details.
|
3
|
-
|
4
|
-
require 'active_support/hash_with_indifferent_access'
|
5
|
-
require 'active_support/core_ext/hash'
|
6
|
-
require 'spec_helper'
|
7
|
-
|
8
|
-
describe Hashie::Extensions::IndifferentAccess do
|
9
|
-
class IndifferentHashWithMergeInitializer < Hash
|
10
|
-
include Hashie::Extensions::MergeInitializer
|
11
|
-
include Hashie::Extensions::IndifferentAccess
|
12
|
-
|
13
|
-
class << self
|
14
|
-
alias_method :build, :new
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
class IndifferentHashWithArrayInitializer < Hash
|
19
|
-
include Hashie::Extensions::IndifferentAccess
|
20
|
-
|
21
|
-
class << self
|
22
|
-
alias_method :build, :[]
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
class IndifferentHashWithTryConvertInitializer < Hash
|
27
|
-
include Hashie::Extensions::IndifferentAccess
|
28
|
-
|
29
|
-
class << self
|
30
|
-
alias_method :build, :try_convert
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
class CoercableHash < Hash
|
35
|
-
include Hashie::Extensions::Coercion
|
36
|
-
include Hashie::Extensions::MergeInitializer
|
37
|
-
end
|
38
|
-
|
39
|
-
class MashWithIndifferentAccess < Hashie::Mash
|
40
|
-
include Hashie::Extensions::IndifferentAccess
|
41
|
-
end
|
42
|
-
|
43
|
-
shared_examples_for 'hash with indifferent access' do
|
44
|
-
it 'is able to access via string or symbol' do
|
45
|
-
indifferent_hash = ActiveSupport::HashWithIndifferentAccess.new(abc: 123)
|
46
|
-
h = subject.build(indifferent_hash)
|
47
|
-
expect(h[:abc]).to eq 123
|
48
|
-
expect(h['abc']).to eq 123
|
49
|
-
end
|
50
|
-
|
51
|
-
describe '#values_at' do
|
52
|
-
it 'indifferently finds values' do
|
53
|
-
indifferent_hash = ActiveSupport::HashWithIndifferentAccess.new(
|
54
|
-
:foo => 'bar', 'baz' => 'qux'
|
55
|
-
)
|
56
|
-
h = subject.build(indifferent_hash)
|
57
|
-
expect(h.values_at('foo', :baz)).to eq %w(bar qux)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
describe '#fetch' do
|
62
|
-
it 'works like normal fetch, but indifferent' do
|
63
|
-
indifferent_hash = ActiveSupport::HashWithIndifferentAccess.new(foo: 'bar')
|
64
|
-
h = subject.build(indifferent_hash)
|
65
|
-
expect(h.fetch(:foo)).to eq h.fetch('foo')
|
66
|
-
expect(h.fetch(:foo)).to eq 'bar'
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
describe '#delete' do
|
71
|
-
it 'deletes indifferently' do
|
72
|
-
indifferent_hash = ActiveSupport::HashWithIndifferentAccess.new(
|
73
|
-
:foo => 'bar',
|
74
|
-
'baz' => 'qux'
|
75
|
-
)
|
76
|
-
h = subject.build(indifferent_hash)
|
77
|
-
h.delete('foo')
|
78
|
-
h.delete(:baz)
|
79
|
-
expect(h).to be_empty
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
describe '#key?' do
|
84
|
-
let(:h) do
|
85
|
-
indifferent_hash = ActiveSupport::HashWithIndifferentAccess.new(foo: 'bar')
|
86
|
-
subject.build(indifferent_hash)
|
87
|
-
end
|
88
|
-
|
89
|
-
it 'finds it indifferently' do
|
90
|
-
expect(h).to be_key(:foo)
|
91
|
-
expect(h).to be_key('foo')
|
92
|
-
end
|
93
|
-
|
94
|
-
%w(include? member? has_key?).each do |key_alias|
|
95
|
-
it "is aliased as #{key_alias}" do
|
96
|
-
expect(h.send(key_alias.to_sym, :foo)).to be(true)
|
97
|
-
expect(h.send(key_alias.to_sym, 'foo')).to be(true)
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
describe '#update' do
|
103
|
-
let(:h) do
|
104
|
-
indifferent_hash = ActiveSupport::HashWithIndifferentAccess.new(foo: 'bar')
|
105
|
-
subject.build(indifferent_hash)
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'allows keys to be indifferent still' do
|
109
|
-
h.update(baz: 'qux')
|
110
|
-
expect(h['foo']).to eq 'bar'
|
111
|
-
expect(h['baz']).to eq 'qux'
|
112
|
-
end
|
113
|
-
|
114
|
-
it 'recursively injects indifference into sub-hashes' do
|
115
|
-
h.update(baz: { qux: 'abc' })
|
116
|
-
expect(h['baz']['qux']).to eq 'abc'
|
117
|
-
end
|
118
|
-
|
119
|
-
it 'does not change the ancestors of the injected object class' do
|
120
|
-
h.update(baz: { qux: 'abc' })
|
121
|
-
expect(Hash.new).not_to be_respond_to(:indifferent_access?)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
describe '#replace' do
|
126
|
-
let(:h) do
|
127
|
-
indifferent_hash = ActiveSupport::HashWithIndifferentAccess.new(foo: 'bar')
|
128
|
-
subject.build(indifferent_hash).replace(bar: 'baz', hi: 'bye')
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'returns self' do
|
132
|
-
expect(h).to be_a(subject)
|
133
|
-
end
|
134
|
-
|
135
|
-
it 'removes old keys' do
|
136
|
-
[:foo, 'foo'].each do |k|
|
137
|
-
expect(h[k]).to be_nil
|
138
|
-
expect(h.key?(k)).to be_falsy
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
it 'creates new keys with indifferent access' do
|
143
|
-
[:bar, 'bar', :hi, 'hi'].each { |k| expect(h.key?(k)).to be_truthy }
|
144
|
-
expect(h[:bar]).to eq 'baz'
|
145
|
-
expect(h['bar']).to eq 'baz'
|
146
|
-
expect(h[:hi]).to eq 'bye'
|
147
|
-
expect(h['hi']).to eq 'bye'
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
describe '#try_convert' do
|
152
|
-
describe 'with conversion' do
|
153
|
-
let(:h) do
|
154
|
-
indifferent_hash = ActiveSupport::HashWithIndifferentAccess.new(foo: 'bar')
|
155
|
-
subject.try_convert(indifferent_hash)
|
156
|
-
end
|
157
|
-
|
158
|
-
it 'is a subject' do
|
159
|
-
expect(h).to be_a(subject)
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
describe 'without conversion' do
|
164
|
-
let(:h) { subject.try_convert('{ :foo => bar }') }
|
165
|
-
|
166
|
-
it 'is nil' do
|
167
|
-
expect(h).to be_nil
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
describe 'with merge initializer' do
|
174
|
-
subject { IndifferentHashWithMergeInitializer }
|
175
|
-
it_should_behave_like 'hash with indifferent access'
|
176
|
-
end
|
177
|
-
|
178
|
-
describe 'with array initializer' do
|
179
|
-
subject { IndifferentHashWithArrayInitializer }
|
180
|
-
it_should_behave_like 'hash with indifferent access'
|
181
|
-
end
|
182
|
-
|
183
|
-
describe 'with try convert initializer' do
|
184
|
-
subject { IndifferentHashWithTryConvertInitializer }
|
185
|
-
it_should_behave_like 'hash with indifferent access'
|
186
|
-
end
|
187
|
-
|
188
|
-
describe 'with coercion' do
|
189
|
-
subject { CoercableHash }
|
190
|
-
|
191
|
-
let(:instance) { subject.new }
|
192
|
-
|
193
|
-
it 'supports coercion for ActiveSupport::HashWithIndifferentAccess' do
|
194
|
-
subject.coerce_key :foo, ActiveSupport::HashWithIndifferentAccess.new(Coercable => Coercable)
|
195
|
-
instance[:foo] = { 'bar_key' => 'bar_value', 'bar2_key' => 'bar2_value' }
|
196
|
-
expect(instance[:foo].keys).to all(be_coerced)
|
197
|
-
expect(instance[:foo].values).to all(be_coerced)
|
198
|
-
expect(instance[:foo]).to be_a(ActiveSupport::HashWithIndifferentAccess)
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
describe 'Mash with indifferent access' do
|
203
|
-
it 'is able to be created for a deep nested HashWithIndifferentAccess' do
|
204
|
-
indifferent_hash = ActiveSupport::HashWithIndifferentAccess.new(abc: { def: 123 })
|
205
|
-
MashWithIndifferentAccess.new(indifferent_hash)
|
206
|
-
end
|
207
|
-
end
|
208
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'support/module_context'
|
3
|
-
|
4
|
-
describe Hashie::Extensions::KeyConversion do
|
5
|
-
include_context 'included hash module'
|
6
|
-
|
7
|
-
it { should respond_to(:stringify_keys) }
|
8
|
-
it { should respond_to(:stringify_keys!) }
|
9
|
-
|
10
|
-
it { should respond_to(:symbolize_keys) }
|
11
|
-
it { should respond_to(:symbolize_keys!) }
|
12
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Hashie::Extensions::Mash::SafeAssignment do
|
4
|
-
class MashWithSafeAssignment < Hashie::Mash
|
5
|
-
include Hashie::Extensions::Mash::SafeAssignment
|
6
|
-
end
|
7
|
-
|
8
|
-
context 'when included in Mash' do
|
9
|
-
subject { MashWithSafeAssignment.new }
|
10
|
-
|
11
|
-
context 'when attempting to override a method' do
|
12
|
-
it 'raises an error' do
|
13
|
-
expect { subject.zip = 'Test' }.to raise_error(ArgumentError)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
context 'when setting as a hash key' do
|
18
|
-
it 'still raises if conflicts with a method' do
|
19
|
-
expect { subject[:zip] = 'Test' }.to raise_error(ArgumentError)
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Hashie::Extensions::MergeInitializer do
|
4
|
-
class MergeInitializerHash < Hash
|
5
|
-
include Hashie::Extensions::MergeInitializer
|
6
|
-
end
|
7
|
-
|
8
|
-
subject { MergeInitializerHash }
|
9
|
-
|
10
|
-
it 'initializes with no arguments' do
|
11
|
-
expect(subject.new).to eq({})
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'initializes with a hash' do
|
15
|
-
expect(subject.new(abc: 'def')).to eq(abc: 'def')
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'initializes with a hash and a default' do
|
19
|
-
h = subject.new({ abc: 'def' }, 'bar')
|
20
|
-
expect(h[:foo]).to eq 'bar'
|
21
|
-
expect(h[:abc]).to eq 'def'
|
22
|
-
end
|
23
|
-
end
|
@@ -1,184 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Hashie::Extensions::MethodReader do
|
4
|
-
class ReaderHash < Hash
|
5
|
-
include Hashie::Extensions::MethodReader
|
6
|
-
|
7
|
-
def initialize(hash = {})
|
8
|
-
update(hash)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
subject { ReaderHash }
|
13
|
-
|
14
|
-
it 'reads string keys from the method' do
|
15
|
-
expect(subject.new('awesome' => 'sauce').awesome).to eq 'sauce'
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'reads symbol keys from the method' do
|
19
|
-
expect(subject.new(awesome: 'sauce').awesome).to eq 'sauce'
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'reads nil and false values out properly' do
|
23
|
-
h = subject.new(nil: nil, false: false)
|
24
|
-
expect(h.nil).to eq nil
|
25
|
-
expect(h.false).to eq false
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'raises a NoMethodError for undefined keys' do
|
29
|
-
expect { subject.new.awesome }.to raise_error(NoMethodError)
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'returns false for undefined keys if key with question has been called ' do
|
33
|
-
expect(subject.new.awesome?).to eq false
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'returns true for defined keys if key with question has been called' do
|
37
|
-
expect(subject.new(awesome: 'sauce').awesome?).to eq true
|
38
|
-
end
|
39
|
-
|
40
|
-
describe '#respond_to?' do
|
41
|
-
it 'is true for string keys' do
|
42
|
-
expect(subject.new('awesome' => 'sauce')).to be_respond_to(:awesome)
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'is true for symbol keys' do
|
46
|
-
expect(subject.new(awesome: 'sauce')).to be_respond_to(:awesome)
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'is false for non-keys' do
|
50
|
-
expect(subject.new).not_to be_respond_to(:awesome)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
describe Hashie::Extensions::MethodWriter do
|
56
|
-
class WriterHash < Hash
|
57
|
-
include Hashie::Extensions::MethodWriter
|
58
|
-
end
|
59
|
-
|
60
|
-
subject { WriterHash.new }
|
61
|
-
|
62
|
-
it 'writes from a method call' do
|
63
|
-
subject.awesome = 'sauce'
|
64
|
-
expect(subject['awesome']).to eq 'sauce'
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'converts the key using the #convert_key method' do
|
68
|
-
allow(subject).to receive(:convert_key).and_return(:awesome)
|
69
|
-
subject.awesome = 'sauce'
|
70
|
-
expect(subject[:awesome]).to eq 'sauce'
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'raises NoMethodError on non equals-ending methods' do
|
74
|
-
expect { subject.awesome }.to raise_error(NoMethodError)
|
75
|
-
end
|
76
|
-
|
77
|
-
it '#respond_to? correctly' do
|
78
|
-
expect(subject).to be_respond_to(:abc=)
|
79
|
-
expect(subject).not_to be_respond_to(:abc)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
describe Hashie::Extensions::MethodQuery do
|
84
|
-
class QueryHash < Hash
|
85
|
-
include Hashie::Extensions::MethodQuery
|
86
|
-
|
87
|
-
def initialize(hash = {})
|
88
|
-
update(hash)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
subject { QueryHash }
|
93
|
-
|
94
|
-
it 'is true for non-nil string key values' do
|
95
|
-
expect(subject.new('abc' => 123)).to be_abc
|
96
|
-
end
|
97
|
-
|
98
|
-
it 'is true for non-nil symbol key values' do
|
99
|
-
expect(subject.new(abc: 123)).to be_abc
|
100
|
-
end
|
101
|
-
|
102
|
-
it 'is false for nil key values' do
|
103
|
-
expect(subject.new(abc: false)).not_to be_abc
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'raises a NoMethodError for non-set keys' do
|
107
|
-
expect { subject.new.abc? }.to raise_error(NoMethodError)
|
108
|
-
end
|
109
|
-
|
110
|
-
it '#respond_to? for existing string keys' do
|
111
|
-
expect(subject.new('abc' => 'def')).to be_respond_to('abc?')
|
112
|
-
end
|
113
|
-
|
114
|
-
it '#respond_to? for existing symbol keys' do
|
115
|
-
expect(subject.new(abc: 'def')).to be_respond_to(:abc?)
|
116
|
-
end
|
117
|
-
|
118
|
-
it 'does not #respond_to? for non-existent keys' do
|
119
|
-
expect(subject.new).not_to be_respond_to('abc?')
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
describe Hashie::Extensions::MethodAccess do
|
124
|
-
it 'includes all of the other method mixins' do
|
125
|
-
klass = Class.new(Hash)
|
126
|
-
klass.send :include, Hashie::Extensions::MethodAccess
|
127
|
-
expect((klass.ancestors & [Hashie::Extensions::MethodReader, Hashie::Extensions::MethodWriter, Hashie::Extensions::MethodQuery]).size).to eq 3
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
describe Hashie::Extensions::MethodOverridingWriter do
|
132
|
-
class OverridingHash < Hash
|
133
|
-
include Hashie::Extensions::MethodOverridingWriter
|
134
|
-
end
|
135
|
-
|
136
|
-
subject { OverridingHash.new }
|
137
|
-
|
138
|
-
it 'writes from a method call' do
|
139
|
-
subject.awesome = 'sauce'
|
140
|
-
expect(subject['awesome']).to eq 'sauce'
|
141
|
-
end
|
142
|
-
|
143
|
-
it 'convertes the key using the #convert_key method' do
|
144
|
-
allow(subject).to receive(:convert_key).and_return(:awesome)
|
145
|
-
subject.awesome = 'sauce'
|
146
|
-
expect(subject[:awesome]).to eq 'sauce'
|
147
|
-
end
|
148
|
-
|
149
|
-
it 'raises NoMethodError on non equals-ending methods' do
|
150
|
-
expect { subject.awesome }.to raise_error(NoMethodError)
|
151
|
-
end
|
152
|
-
|
153
|
-
it '#respond_to_missing? correctly' do
|
154
|
-
expect(subject).to respond_to(:abc=)
|
155
|
-
expect(subject).not_to respond_to(:abc)
|
156
|
-
expect(subject.method(:abc=)).not_to be_nil
|
157
|
-
end
|
158
|
-
|
159
|
-
context 'when writing a Hash method' do
|
160
|
-
before { subject.zip = 'a-dee-doo-dah' }
|
161
|
-
|
162
|
-
it 'overrides the original method' do
|
163
|
-
expect(subject.zip).to eq 'a-dee-doo-dah'
|
164
|
-
end
|
165
|
-
|
166
|
-
it 'aliases the method with two leading underscores' do
|
167
|
-
expect(subject.__zip).to eq [[%w(zip a-dee-doo-dah)]]
|
168
|
-
end
|
169
|
-
|
170
|
-
it 'does not re-alias when overriding an already overridden method' do
|
171
|
-
subject.zip = 'test'
|
172
|
-
expect(subject.zip).to eq 'test'
|
173
|
-
expect(subject.__zip).to eq [[%w(zip test)]]
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
describe Hashie::Extensions::MethodAccessWithOverride do
|
179
|
-
it 'includes all of the other method mixins' do
|
180
|
-
klass = Class.new(Hash)
|
181
|
-
klass.send :include, Hashie::Extensions::MethodAccessWithOverride
|
182
|
-
expect((klass.ancestors & [Hashie::Extensions::MethodReader, Hashie::Extensions::MethodOverridingWriter, Hashie::Extensions::MethodQuery]).size).to eq 3
|
183
|
-
end
|
184
|
-
end
|
@@ -1,101 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'support/module_context'
|
3
|
-
|
4
|
-
def invoke(method)
|
5
|
-
if subject == object
|
6
|
-
subject.public_send(method)
|
7
|
-
else
|
8
|
-
subject.public_send(method, object)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
shared_examples 'stringify_keys!' do
|
13
|
-
it 'converts keys to strings' do
|
14
|
-
object[:abc] = 'abc'
|
15
|
-
object[123] = '123'
|
16
|
-
invoke :stringify_keys!
|
17
|
-
expect((object.keys & %w(abc 123)).size).to eq 2
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'converts nested instances of the same class' do
|
21
|
-
object[:ab] = dummy_class.new
|
22
|
-
object[:ab][:cd] = dummy_class.new
|
23
|
-
object[:ab][:cd][:ef] = 'abcdef'
|
24
|
-
invoke :stringify_keys!
|
25
|
-
expect(object).to eq('ab' => { 'cd' => { 'ef' => 'abcdef' } })
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'converts nested hashes' do
|
29
|
-
object[:ab] = { cd: { ef: 'abcdef' } }
|
30
|
-
invoke :stringify_keys!
|
31
|
-
expect(object).to eq('ab' => { 'cd' => { 'ef' => 'abcdef' } })
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'converts nested arrays' do
|
35
|
-
object[:ab] = []
|
36
|
-
object[:ab] << dummy_class.new
|
37
|
-
object[:ab] << dummy_class.new
|
38
|
-
object[:ab][0][:cd] = 'abcd'
|
39
|
-
object[:ab][1][:ef] = 'abef'
|
40
|
-
invoke :stringify_keys!
|
41
|
-
expect(object).to eq('ab' => [{ 'cd' => 'abcd' }, { 'ef' => 'abef' }])
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
shared_examples 'stringify_keys' do
|
46
|
-
it 'converts keys to strings' do
|
47
|
-
object[:abc] = 'def'
|
48
|
-
copy = invoke :stringify_keys
|
49
|
-
expect(copy['abc']).to eq 'def'
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'does not alter the original' do
|
53
|
-
object[:abc] = 'def'
|
54
|
-
copy = invoke :stringify_keys
|
55
|
-
expect(object.keys).to eq [:abc]
|
56
|
-
expect(copy.keys).to eq %w(abc)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
describe Hashie::Extensions::StringifyKeys do
|
61
|
-
include_context 'included hash module'
|
62
|
-
let(:object) { subject }
|
63
|
-
|
64
|
-
describe '#stringify_keys!' do
|
65
|
-
include_examples 'stringify_keys!'
|
66
|
-
|
67
|
-
it 'returns itself' do
|
68
|
-
expect(subject.stringify_keys!).to eq subject
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
context 'class methods' do
|
73
|
-
subject { described_class }
|
74
|
-
let(:object) { Hash.new }
|
75
|
-
|
76
|
-
describe '.stringify_keys' do
|
77
|
-
include_examples 'stringify_keys'
|
78
|
-
end
|
79
|
-
describe '.stringify_keys!' do
|
80
|
-
include_examples 'stringify_keys!'
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
describe Hashie do
|
86
|
-
let!(:dummy_class) do
|
87
|
-
klass = Class.new(::Hash)
|
88
|
-
klass.send :include, Hashie::Extensions::StringifyKeys
|
89
|
-
klass
|
90
|
-
end
|
91
|
-
|
92
|
-
subject { described_class }
|
93
|
-
let(:object) { Hash.new }
|
94
|
-
|
95
|
-
describe '.stringify_keys' do
|
96
|
-
include_examples 'stringify_keys'
|
97
|
-
end
|
98
|
-
describe '.stringify_keys!' do
|
99
|
-
include_examples 'stringify_keys!'
|
100
|
-
end
|
101
|
-
end
|
@@ -1,106 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'support/module_context'
|
3
|
-
|
4
|
-
def invoke(method)
|
5
|
-
if subject == object
|
6
|
-
subject.public_send(method)
|
7
|
-
else
|
8
|
-
subject.public_send(method, object)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
shared_examples 'symbolize_keys!' do
|
13
|
-
it 'converts keys to symbols' do
|
14
|
-
object['abc'] = 'abc'
|
15
|
-
object['def'] = 'def'
|
16
|
-
invoke :symbolize_keys!
|
17
|
-
expect((object.keys & [:abc, :def]).size).to eq 2
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'converts nested instances of the same class' do
|
21
|
-
object['ab'] = dummy_class.new
|
22
|
-
object['ab']['cd'] = dummy_class.new
|
23
|
-
object['ab']['cd']['ef'] = 'abcdef'
|
24
|
-
invoke :symbolize_keys!
|
25
|
-
expect(object).to eq(ab: { cd: { ef: 'abcdef' } })
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'converts nested hashes' do
|
29
|
-
object['ab'] = { 'cd' => { 'ef' => 'abcdef' } }
|
30
|
-
invoke :symbolize_keys!
|
31
|
-
expect(object).to eq(ab: { cd: { ef: 'abcdef' } })
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'performs deep conversion within nested arrays' do
|
35
|
-
object['ab'] = []
|
36
|
-
object['ab'] << dummy_class.new
|
37
|
-
object['ab'] << dummy_class.new
|
38
|
-
object['ab'][0]['cd'] = 'abcd'
|
39
|
-
object['ab'][1]['ef'] = 'abef'
|
40
|
-
new_object = invoke :symbolize_keys
|
41
|
-
expect(new_object).to eq(ab: [{ cd: 'abcd' }, { ef: 'abef' }])
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
shared_examples 'symbolize_keys' do
|
46
|
-
it 'converts keys to symbols' do
|
47
|
-
object['abc'] = 'def'
|
48
|
-
copy = invoke :symbolize_keys
|
49
|
-
expect(copy[:abc]).to eq 'def'
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'does not alter the original' do
|
53
|
-
object['abc'] = 'def'
|
54
|
-
copy = invoke :symbolize_keys
|
55
|
-
expect(object.keys).to eq ['abc']
|
56
|
-
expect(copy.keys).to eq [:abc]
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
describe Hashie::Extensions::SymbolizeKeys do
|
61
|
-
include_context 'included hash module'
|
62
|
-
let(:object) { subject }
|
63
|
-
|
64
|
-
describe '#symbolize_keys!' do
|
65
|
-
include_examples 'symbolize_keys!'
|
66
|
-
let(:object) { subject }
|
67
|
-
|
68
|
-
it 'returns itself' do
|
69
|
-
expect(subject.symbolize_keys!).to eq subject
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
describe '#symbolize_keys' do
|
74
|
-
include_examples 'symbolize_keys'
|
75
|
-
end
|
76
|
-
|
77
|
-
context 'class methods' do
|
78
|
-
subject { described_class }
|
79
|
-
let(:object) { Hash.new }
|
80
|
-
|
81
|
-
describe '.symbolize_keys' do
|
82
|
-
include_examples 'symbolize_keys'
|
83
|
-
end
|
84
|
-
describe '.symbolize_keys!' do
|
85
|
-
include_examples 'symbolize_keys!'
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
describe Hashie do
|
91
|
-
let!(:dummy_class) do
|
92
|
-
klass = Class.new(::Hash)
|
93
|
-
klass.send :include, Hashie::Extensions::StringifyKeys
|
94
|
-
klass
|
95
|
-
end
|
96
|
-
|
97
|
-
subject { described_class }
|
98
|
-
let(:object) { Hash.new }
|
99
|
-
|
100
|
-
describe '.symbolize_keys' do
|
101
|
-
include_examples 'symbolize_keys'
|
102
|
-
end
|
103
|
-
describe '.symbolize_keys!' do
|
104
|
-
include_examples 'symbolize_keys!'
|
105
|
-
end
|
106
|
-
end
|