hashie 3.2.0 → 3.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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
@@ -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
@@ -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 :first_name
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: lambda { |value| value.reverse }
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: lambda { |value| value.reverse }
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: lambda { |value| value.reverse }
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: lambda { |value| value.reverse }
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
@@ -1,4 +1,5 @@
1
1
  require 'rubygems'
2
+ require 'pry'
2
3
 
3
4
  $LOAD_PATH.unshift(File.dirname(__FILE__))
4
5
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
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.2.0
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-07-10 00:00:00.000000000 Z
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