hashie 3.2.0 → 3.3.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +13 -15
- data/.travis.yml +2 -2
- data/CHANGELOG.md +18 -0
- data/Gemfile +12 -4
- data/Guardfile +4 -4
- data/README.md +161 -2
- data/RELEASING.md +83 -0
- data/UPGRADING.md +16 -0
- data/lib/hashie.rb +7 -2
- data/lib/hashie/extensions/coercion.rb +58 -12
- data/lib/hashie/extensions/deep_find.rb +59 -0
- data/lib/hashie/extensions/indifferent_access.rb +2 -2
- data/lib/hashie/extensions/mash/safe_assignment.rb +13 -0
- data/lib/hashie/extensions/method_access.rb +75 -0
- data/lib/hashie/extensions/parsers/yaml_erb_parser.rb +21 -0
- data/lib/hashie/mash.rb +25 -1
- data/lib/hashie/rash.rb +26 -0
- data/lib/hashie/trash.rb +35 -15
- data/lib/hashie/version.rb +1 -1
- data/spec/hashie/extensions/coercion_spec.rb +286 -2
- data/spec/hashie/extensions/dash/indifferent_access_spec.rb +1 -1
- data/spec/hashie/extensions/deep_find_spec.rb +45 -0
- data/spec/hashie/extensions/indifferent_access_spec.rb +48 -0
- data/spec/hashie/extensions/mash/safe_assignment_spec.rb +17 -0
- data/spec/hashie/extensions/method_access_spec.rb +55 -0
- data/spec/hashie/mash_spec.rb +92 -0
- data/spec/hashie/rash_spec.rb +27 -0
- data/spec/hashie/trash_spec.rb +64 -5
- data/spec/spec_helper.rb +1 -0
- metadata +10 -2
@@ -0,0 +1,17 @@
|
|
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
|
+
end
|
17
|
+
end
|
@@ -119,3 +119,58 @@ describe Hashie::Extensions::MethodAccess do
|
|
119
119
|
expect((klass.ancestors & [Hashie::Extensions::MethodReader, Hashie::Extensions::MethodWriter, Hashie::Extensions::MethodQuery]).size).to eq 3
|
120
120
|
end
|
121
121
|
end
|
122
|
+
|
123
|
+
describe Hashie::Extensions::MethodOverridingWriter do
|
124
|
+
class OverridingHash < Hash
|
125
|
+
include Hashie::Extensions::MethodOverridingWriter
|
126
|
+
end
|
127
|
+
|
128
|
+
subject { OverridingHash.new }
|
129
|
+
|
130
|
+
it 'writes from a method call' do
|
131
|
+
subject.awesome = 'sauce'
|
132
|
+
expect(subject['awesome']).to eq 'sauce'
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'convertes the key using the #convert_key method' do
|
136
|
+
allow(subject).to receive(:convert_key).and_return(:awesome)
|
137
|
+
subject.awesome = 'sauce'
|
138
|
+
expect(subject[:awesome]).to eq 'sauce'
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'raises NoMethodError on non equals-ending methods' do
|
142
|
+
expect { subject.awesome }.to raise_error(NoMethodError)
|
143
|
+
end
|
144
|
+
|
145
|
+
it '#respond_to_missing? correctly' do
|
146
|
+
expect(subject).to respond_to(:abc=)
|
147
|
+
expect(subject).not_to respond_to(:abc)
|
148
|
+
expect(subject.method(:abc=)).not_to be_nil
|
149
|
+
end
|
150
|
+
|
151
|
+
context 'when writing a Hash method' do
|
152
|
+
before { subject.zip = 'a-dee-doo-dah' }
|
153
|
+
|
154
|
+
it 'overrides the original method' do
|
155
|
+
expect(subject.zip).to eq 'a-dee-doo-dah'
|
156
|
+
end
|
157
|
+
|
158
|
+
it 'aliases the method with two leading underscores' do
|
159
|
+
expect(subject.__zip).to eq [[%w(zip a-dee-doo-dah)]]
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'does not re-alias when overriding an already overridden method' do
|
163
|
+
subject.zip = 'test'
|
164
|
+
expect(subject.zip).to eq 'test'
|
165
|
+
expect(subject.__zip).to eq [[%w(zip test)]]
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe Hashie::Extensions::MethodAccessWithOverride do
|
171
|
+
it 'includes all of the other method mixins' do
|
172
|
+
klass = Class.new(Hash)
|
173
|
+
klass.send :include, Hashie::Extensions::MethodAccessWithOverride
|
174
|
+
expect((klass.ancestors & [Hashie::Extensions::MethodReader, Hashie::Extensions::MethodOverridingWriter, Hashie::Extensions::MethodQuery]).size).to eq 3
|
175
|
+
end
|
176
|
+
end
|
data/spec/hashie/mash_spec.rb
CHANGED
@@ -499,4 +499,96 @@ describe Hashie::Mash do
|
|
499
499
|
end
|
500
500
|
end
|
501
501
|
end
|
502
|
+
|
503
|
+
describe '.load(filename, options = {})' do
|
504
|
+
let(:config) do
|
505
|
+
{
|
506
|
+
'production' => {
|
507
|
+
'foo' => 'production_foo'
|
508
|
+
}
|
509
|
+
}
|
510
|
+
end
|
511
|
+
let(:path) { 'database.yml' }
|
512
|
+
let(:parser) { double(:parser) }
|
513
|
+
|
514
|
+
subject { described_class.load(path, parser: parser) }
|
515
|
+
|
516
|
+
before do |ex|
|
517
|
+
unless ex.metadata == :test_cache
|
518
|
+
described_class.instance_variable_set('@_mashes', nil) # clean the cached mashes
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
context 'if the file exists' do
|
523
|
+
before do
|
524
|
+
expect(File).to receive(:file?).with(path).and_return(true)
|
525
|
+
expect(parser).to receive(:perform).with(path).and_return(config)
|
526
|
+
end
|
527
|
+
|
528
|
+
it { is_expected.to be_a(Hashie::Mash) }
|
529
|
+
|
530
|
+
it 'return a Mash from a file' do
|
531
|
+
expect(subject.production).not_to be_nil
|
532
|
+
expect(subject.production.keys).to eq config['production'].keys
|
533
|
+
expect(subject.production.foo).to eq config['production']['foo']
|
534
|
+
end
|
535
|
+
|
536
|
+
it 'freeze the attribtues' do
|
537
|
+
expect { subject.production = {} }.to raise_exception(RuntimeError, /can't modify frozen/)
|
538
|
+
end
|
539
|
+
end
|
540
|
+
|
541
|
+
context 'if the fils does not exists' do
|
542
|
+
before do
|
543
|
+
expect(File).to receive(:file?).with(path).and_return(false)
|
544
|
+
end
|
545
|
+
|
546
|
+
it 'raise an ArgumentError' do
|
547
|
+
expect { subject }.to raise_exception(ArgumentError)
|
548
|
+
end
|
549
|
+
end
|
550
|
+
|
551
|
+
describe 'results are cached' do
|
552
|
+
let(:parser) { double(:parser) }
|
553
|
+
|
554
|
+
subject { described_class.load(path, parser: parser) }
|
555
|
+
|
556
|
+
before do
|
557
|
+
expect(File).to receive(:file?).with(path).and_return(true)
|
558
|
+
expect(File).to receive(:file?).with("#{path}+1").and_return(true)
|
559
|
+
expect(parser).to receive(:perform).once.with(path).and_return(config)
|
560
|
+
expect(parser).to receive(:perform).once.with("#{path}+1").and_return(config)
|
561
|
+
end
|
562
|
+
|
563
|
+
it 'cache the loaded yml file', :test_cache do
|
564
|
+
2.times do
|
565
|
+
expect(subject).to be_a(described_class)
|
566
|
+
expect(described_class.load("#{path}+1", parser: parser)).to be_a(described_class)
|
567
|
+
end
|
568
|
+
|
569
|
+
expect(subject.object_id).to eq subject.object_id
|
570
|
+
end
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
describe '#to_module(mash_method_name)' do
|
575
|
+
let(:mash) { described_class.new }
|
576
|
+
subject { Class.new.extend mash.to_module }
|
577
|
+
|
578
|
+
it 'defines a settings method on the klass class that extends the module' do
|
579
|
+
expect(subject).to respond_to(:settings)
|
580
|
+
expect(subject.settings).to eq mash
|
581
|
+
end
|
582
|
+
|
583
|
+
context 'when a settings_method_name is set' do
|
584
|
+
let(:mash_method_name) { 'config' }
|
585
|
+
|
586
|
+
subject { Class.new.extend mash.to_module(mash_method_name) }
|
587
|
+
|
588
|
+
it 'defines a settings method on the klass class that extends the module' do
|
589
|
+
expect(subject).to respond_to(mash_method_name.to_sym)
|
590
|
+
expect(subject.send(mash_method_name.to_sym)).to eq mash
|
591
|
+
end
|
592
|
+
end
|
593
|
+
end
|
502
594
|
end
|
data/spec/hashie/rash_spec.rb
CHANGED
@@ -47,4 +47,31 @@ describe Hashie::Rash do
|
|
47
47
|
expect(subject['abcdef']).to eq 'bcd'
|
48
48
|
expect(subject['ffffff']).to be_nil
|
49
49
|
end
|
50
|
+
|
51
|
+
it 'finds using the find method' do
|
52
|
+
expect(subject.fetch(10.1)).to eq 'rangey'
|
53
|
+
expect(subject.fetch(true)).to be false
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'raises in find unless a key matches' do
|
57
|
+
expect { subject.fetch(1_000_000) }.to raise_error(KeyError)
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'yields in find unless a key matches' do
|
61
|
+
expect { |y| subject.fetch(1_000_000, &y) }.to yield_control
|
62
|
+
expect { |y| subject.fetch(10.1, &y) }.to_not yield_control
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'gives a default value' do
|
66
|
+
expect(subject.fetch(10.1, 'noop')).to eq 'rangey'
|
67
|
+
expect(subject.fetch(1_000_000, 'noop')).to eq 'noop'
|
68
|
+
expect(subject.fetch(1_000_000) { 'noop' }).to eq 'noop'
|
69
|
+
expect(subject.fetch(1_000_000) { |k| k }).to eq 1_000_000
|
70
|
+
expect(subject.fetch(1_000_000, 'noop') { 'op' }).to eq 'op'
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'responds to hash methods' do
|
74
|
+
expect(subject.respond_to?(:to_a)).to be true
|
75
|
+
expect(subject.methods).to_not include(:to_a)
|
76
|
+
end
|
50
77
|
end
|
data/spec/hashie/trash_spec.rb
CHANGED
@@ -29,7 +29,7 @@ describe Hashie::Trash do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
it 'maintains translations hash mapping from the original to the translated name' do
|
32
|
-
expect(TrashTest.translations[:firstName]).to eq
|
32
|
+
expect(TrashTest.translations[:firstName]).to eq(:first_name)
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'maintains inverse translations hash mapping from the translated to the original name' do
|
@@ -110,7 +110,7 @@ describe Hashie::Trash do
|
|
110
110
|
|
111
111
|
describe 'translating properties using a proc' do
|
112
112
|
class TrashLambdaTest < Hashie::Trash
|
113
|
-
property :first_name, from: :firstName, with:
|
113
|
+
property :first_name, from: :firstName, with: ->(value) { value.reverse }
|
114
114
|
end
|
115
115
|
|
116
116
|
let(:lambda_trash) { TrashLambdaTest.new }
|
@@ -134,9 +134,32 @@ describe Hashie::Trash do
|
|
134
134
|
end
|
135
135
|
end
|
136
136
|
|
137
|
+
describe 'translating multiple properties using a proc' do
|
138
|
+
class SomeDataModel < Hashie::Trash
|
139
|
+
property :value_a, from: :config, with: ->(config) { config.a }
|
140
|
+
property :value_b, from: :config, with: ->(config) { config.b }
|
141
|
+
end
|
142
|
+
|
143
|
+
ConfigDataModel = Struct.new(:a, :b)
|
144
|
+
|
145
|
+
subject { SomeDataModel.new(config: ConfigDataModel.new('value in a', 'value in b')) }
|
146
|
+
|
147
|
+
it 'translates the first key' do
|
148
|
+
expect(subject.value_a).to eq 'value in a'
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'translates the second key' do
|
152
|
+
expect(subject.value_b).to eq 'value in b'
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'maintains translations hash mapping from the original to the translated name' do
|
156
|
+
expect(SomeDataModel.translations).to eq(config: [:value_a, :value_b])
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
137
160
|
describe 'uses with or transform_with interchangeably' do
|
138
161
|
class TrashLambdaTestTransformWith < Hashie::Trash
|
139
|
-
property :first_name, from: :firstName, transform_with:
|
162
|
+
property :first_name, from: :firstName, transform_with: ->(value) { value.reverse }
|
140
163
|
end
|
141
164
|
|
142
165
|
let(:lambda_trash) { TrashLambdaTestTransformWith.new }
|
@@ -154,7 +177,7 @@ describe Hashie::Trash do
|
|
154
177
|
|
155
178
|
describe 'translating properties without from option using a proc' do
|
156
179
|
class TrashLambdaTestWithProperties < Hashie::Trash
|
157
|
-
property :first_name, transform_with:
|
180
|
+
property :first_name, transform_with: ->(value) { value.reverse }
|
158
181
|
end
|
159
182
|
|
160
183
|
let(:lambda_trash) { TrashLambdaTestWithProperties.new }
|
@@ -170,7 +193,7 @@ describe Hashie::Trash do
|
|
170
193
|
|
171
194
|
context 'when :from option is given' do
|
172
195
|
class TrashLambdaTest3 < Hashie::Trash
|
173
|
-
property :first_name, from: :firstName, transform_with:
|
196
|
+
property :first_name, from: :firstName, transform_with: ->(value) { value.reverse }
|
174
197
|
end
|
175
198
|
|
176
199
|
it 'does not override the :from option in the constructor' do
|
@@ -186,6 +209,42 @@ describe Hashie::Trash do
|
|
186
209
|
end
|
187
210
|
end
|
188
211
|
|
212
|
+
describe 'inheritable transforms' do
|
213
|
+
class TransformA < Hashie::Trash
|
214
|
+
property :some_value, transform_with: ->(v) { v.to_i }
|
215
|
+
end
|
216
|
+
|
217
|
+
class TransformB < TransformA
|
218
|
+
property :some_other_value, transform_with: ->(v) { v.to_i }
|
219
|
+
end
|
220
|
+
|
221
|
+
class TransformC < TransformB
|
222
|
+
property :some_value, transform_with: ->(v) { -v.to_i }
|
223
|
+
end
|
224
|
+
|
225
|
+
it 'inherit properties transforms' do
|
226
|
+
expect(TransformB.new(some_value: '123', some_other_value: '456').some_value).to eq(123)
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'replaces property transform' do
|
230
|
+
expect(TransformC.new(some_value: '123', some_other_value: '456').some_value).to eq(-123)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
describe 'inheritable translations' do
|
235
|
+
class TranslationA < Hashie::Trash
|
236
|
+
property :some_value, from: 'someValue', with: ->(v) { v.to_i }
|
237
|
+
end
|
238
|
+
|
239
|
+
class TranslationB < TranslationA
|
240
|
+
property :some_other_value, from: 'someOtherValue'
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'inherit properties translations' do
|
244
|
+
expect(TranslationB.new('someValue' => '123').some_value).to eq(123)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
189
248
|
it 'raises an error when :from have the same value as property' do
|
190
249
|
expect do
|
191
250
|
class WrongTrash < Hashie::Trash
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hashie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Bleigh
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-08-26 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -58,6 +58,7 @@ files:
|
|
58
58
|
- Guardfile
|
59
59
|
- LICENSE
|
60
60
|
- README.md
|
61
|
+
- RELEASING.md
|
61
62
|
- Rakefile
|
62
63
|
- UPGRADING.md
|
63
64
|
- hashie.gemspec
|
@@ -67,12 +68,15 @@ files:
|
|
67
68
|
- lib/hashie/extensions/coercion.rb
|
68
69
|
- lib/hashie/extensions/dash/indifferent_access.rb
|
69
70
|
- lib/hashie/extensions/deep_fetch.rb
|
71
|
+
- lib/hashie/extensions/deep_find.rb
|
70
72
|
- lib/hashie/extensions/deep_merge.rb
|
71
73
|
- lib/hashie/extensions/ignore_undeclared.rb
|
72
74
|
- lib/hashie/extensions/indifferent_access.rb
|
73
75
|
- lib/hashie/extensions/key_conversion.rb
|
76
|
+
- lib/hashie/extensions/mash/safe_assignment.rb
|
74
77
|
- lib/hashie/extensions/merge_initializer.rb
|
75
78
|
- lib/hashie/extensions/method_access.rb
|
79
|
+
- lib/hashie/extensions/parsers/yaml_erb_parser.rb
|
76
80
|
- lib/hashie/extensions/pretty_inspect.rb
|
77
81
|
- lib/hashie/extensions/stringify_keys.rb
|
78
82
|
- lib/hashie/extensions/symbolize_keys.rb
|
@@ -86,11 +90,13 @@ files:
|
|
86
90
|
- spec/hashie/extensions/coercion_spec.rb
|
87
91
|
- spec/hashie/extensions/dash/indifferent_access_spec.rb
|
88
92
|
- spec/hashie/extensions/deep_fetch_spec.rb
|
93
|
+
- spec/hashie/extensions/deep_find_spec.rb
|
89
94
|
- spec/hashie/extensions/deep_merge_spec.rb
|
90
95
|
- spec/hashie/extensions/ignore_undeclared_spec.rb
|
91
96
|
- spec/hashie/extensions/indifferent_access_spec.rb
|
92
97
|
- spec/hashie/extensions/indifferent_access_with_rails_hwia_spec.rb
|
93
98
|
- spec/hashie/extensions/key_conversion_spec.rb
|
99
|
+
- spec/hashie/extensions/mash/safe_assignment_spec.rb
|
94
100
|
- spec/hashie/extensions/merge_initializer_spec.rb
|
95
101
|
- spec/hashie/extensions/method_access_spec.rb
|
96
102
|
- spec/hashie/hash_spec.rb
|
@@ -129,11 +135,13 @@ test_files:
|
|
129
135
|
- spec/hashie/extensions/coercion_spec.rb
|
130
136
|
- spec/hashie/extensions/dash/indifferent_access_spec.rb
|
131
137
|
- spec/hashie/extensions/deep_fetch_spec.rb
|
138
|
+
- spec/hashie/extensions/deep_find_spec.rb
|
132
139
|
- spec/hashie/extensions/deep_merge_spec.rb
|
133
140
|
- spec/hashie/extensions/ignore_undeclared_spec.rb
|
134
141
|
- spec/hashie/extensions/indifferent_access_spec.rb
|
135
142
|
- spec/hashie/extensions/indifferent_access_with_rails_hwia_spec.rb
|
136
143
|
- spec/hashie/extensions/key_conversion_spec.rb
|
144
|
+
- spec/hashie/extensions/mash/safe_assignment_spec.rb
|
137
145
|
- spec/hashie/extensions/merge_initializer_spec.rb
|
138
146
|
- spec/hashie/extensions/method_access_spec.rb
|
139
147
|
- spec/hashie/hash_spec.rb
|