hashie 3.4.3 → 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.
Files changed (73) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +516 -129
  3. data/CONTRIBUTING.md +24 -7
  4. data/LICENSE +1 -1
  5. data/README.md +408 -50
  6. data/Rakefile +18 -1
  7. data/UPGRADING.md +157 -7
  8. data/hashie.gemspec +14 -8
  9. data/lib/hashie/array.rb +21 -0
  10. data/lib/hashie/clash.rb +24 -12
  11. data/lib/hashie/dash.rb +56 -31
  12. data/lib/hashie/extensions/active_support/core_ext/hash.rb +14 -0
  13. data/lib/hashie/extensions/array/pretty_inspect.rb +19 -0
  14. data/lib/hashie/extensions/coercion.rb +30 -17
  15. data/lib/hashie/extensions/dash/indifferent_access.rb +30 -1
  16. data/lib/hashie/extensions/dash/predefined_values.rb +88 -0
  17. data/lib/hashie/extensions/dash/property_translation.rb +59 -28
  18. data/lib/hashie/extensions/deep_fetch.rb +5 -3
  19. data/lib/hashie/extensions/deep_find.rb +14 -5
  20. data/lib/hashie/extensions/deep_locate.rb +40 -21
  21. data/lib/hashie/extensions/deep_merge.rb +26 -10
  22. data/lib/hashie/extensions/ignore_undeclared.rb +6 -4
  23. data/lib/hashie/extensions/indifferent_access.rb +49 -8
  24. data/lib/hashie/extensions/key_conflict_warning.rb +55 -0
  25. data/lib/hashie/extensions/mash/define_accessors.rb +90 -0
  26. data/lib/hashie/extensions/mash/keep_original_keys.rb +53 -0
  27. data/lib/hashie/extensions/mash/permissive_respond_to.rb +61 -0
  28. data/lib/hashie/extensions/mash/safe_assignment.rb +3 -1
  29. data/lib/hashie/extensions/mash/symbolize_keys.rb +38 -0
  30. data/lib/hashie/extensions/method_access.rb +77 -19
  31. data/lib/hashie/extensions/parsers/yaml_erb_parser.rb +29 -5
  32. data/lib/hashie/extensions/ruby_version.rb +60 -0
  33. data/lib/hashie/extensions/ruby_version_check.rb +21 -0
  34. data/lib/hashie/extensions/strict_key_access.rb +16 -13
  35. data/lib/hashie/extensions/stringify_keys.rb +1 -1
  36. data/lib/hashie/extensions/symbolize_keys.rb +13 -2
  37. data/lib/hashie/hash.rb +18 -11
  38. data/lib/hashie/logger.rb +18 -0
  39. data/lib/hashie/mash.rb +177 -43
  40. data/lib/hashie/railtie.rb +21 -0
  41. data/lib/hashie/rash.rb +7 -7
  42. data/lib/hashie/utils.rb +44 -0
  43. data/lib/hashie/version.rb +1 -1
  44. data/lib/hashie.rb +33 -17
  45. metadata +28 -95
  46. data/spec/hashie/clash_spec.rb +0 -48
  47. data/spec/hashie/dash_spec.rb +0 -513
  48. data/spec/hashie/extensions/autoload_spec.rb +0 -24
  49. data/spec/hashie/extensions/coercion_spec.rb +0 -625
  50. data/spec/hashie/extensions/dash/coercion_spec.rb +0 -13
  51. data/spec/hashie/extensions/dash/indifferent_access_spec.rb +0 -84
  52. data/spec/hashie/extensions/deep_fetch_spec.rb +0 -97
  53. data/spec/hashie/extensions/deep_find_spec.rb +0 -45
  54. data/spec/hashie/extensions/deep_locate_spec.rb +0 -124
  55. data/spec/hashie/extensions/deep_merge_spec.rb +0 -65
  56. data/spec/hashie/extensions/ignore_undeclared_spec.rb +0 -46
  57. data/spec/hashie/extensions/indifferent_access_spec.rb +0 -219
  58. data/spec/hashie/extensions/indifferent_access_with_rails_hwia_spec.rb +0 -208
  59. data/spec/hashie/extensions/key_conversion_spec.rb +0 -12
  60. data/spec/hashie/extensions/mash/safe_assignment_spec.rb +0 -50
  61. data/spec/hashie/extensions/merge_initializer_spec.rb +0 -23
  62. data/spec/hashie/extensions/method_access_spec.rb +0 -184
  63. data/spec/hashie/extensions/strict_key_access_spec.rb +0 -110
  64. data/spec/hashie/extensions/stringify_keys_spec.rb +0 -124
  65. data/spec/hashie/extensions/symbolize_keys_spec.rb +0 -129
  66. data/spec/hashie/hash_spec.rb +0 -84
  67. data/spec/hashie/mash_spec.rb +0 -680
  68. data/spec/hashie/parsers/yaml_erb_parser_spec.rb +0 -29
  69. data/spec/hashie/rash_spec.rb +0 -77
  70. data/spec/hashie/trash_spec.rb +0 -268
  71. data/spec/hashie/version_spec.rb +0 -7
  72. data/spec/spec_helper.rb +0 -16
  73. data/spec/support/module_context.rb +0 -11
@@ -1,77 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Hashie::Rash do
4
- subject do
5
- Hashie::Rash.new(
6
- /hello/ => 'hello',
7
- /world/ => 'world',
8
- 'other' => 'whee',
9
- true => false,
10
- 1 => 'awesome',
11
- 1..1000 => 'rangey',
12
- /(bcd)/ => proc { |m| m[1] }
13
- # /.+/ => "EVERYTHING"
14
- )
15
- end
16
-
17
- it 'finds strings' do
18
- expect(subject['other']).to eq 'whee'
19
- expect(subject['well hello there']).to eq 'hello'
20
- expect(subject['the world is round']).to eq 'world'
21
- expect(subject.all('hello world').sort).to eq %w(hello world)
22
- end
23
-
24
- it 'finds regexps' do
25
- expect(subject[/other/]).to eq 'whee'
26
- end
27
-
28
- it 'finds other objects' do
29
- expect(subject[true]).to eq false
30
- expect(subject[1]).to eq 'awesome'
31
- end
32
-
33
- it 'finds numbers from ranges' do
34
- expect(subject[250]).to eq 'rangey'
35
- expect(subject[999]).to eq 'rangey'
36
- expect(subject[1000]).to eq 'rangey'
37
- expect(subject[1001]).to be_nil
38
- end
39
-
40
- it 'finds floats from ranges' do
41
- expect(subject[10.1]).to eq 'rangey'
42
- expect(subject[1.0]).to eq 'rangey'
43
- expect(subject[1000.1]).to be_nil
44
- end
45
-
46
- it 'evaluates proc values' do
47
- expect(subject['abcdef']).to eq 'bcd'
48
- expect(subject['ffffff']).to be_nil
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
77
- end
@@ -1,268 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Hashie::Trash do
4
- class TrashTest < Hashie::Trash
5
- property :first_name, from: :firstName
6
- end
7
-
8
- let(:trash) { TrashTest.new }
9
-
10
- describe 'translating properties' do
11
- it 'adds the property to the list' do
12
- expect(TrashTest.properties).to include(:first_name)
13
- end
14
-
15
- it 'creates a method for reading the property' do
16
- expect(trash).to respond_to(:first_name)
17
- end
18
-
19
- it 'creates a method for writing the property' do
20
- expect(trash).to respond_to(:first_name=)
21
- end
22
-
23
- it 'creates a method for writing the translated property' do
24
- expect(trash).to respond_to(:firstName=)
25
- end
26
-
27
- it 'does not create a method for reading the translated property' do
28
- expect(trash).not_to respond_to(:firstName)
29
- end
30
-
31
- it 'maintains translations hash mapping from the original to the translated name' do
32
- expect(TrashTest.translations[:firstName]).to eq(:first_name)
33
- end
34
-
35
- it 'maintains inverse translations hash mapping from the translated to the original name' do
36
- expect(TrashTest.inverse_translations[:first_name]).to eq :firstName
37
- end
38
-
39
- it '#permitted_input_keys contain the :from key of properties with translations' do
40
- expect(TrashTest.permitted_input_keys).to include :firstName
41
- end
42
- end
43
-
44
- describe 'standard properties' do
45
- class TrashTestPermitted < Hashie::Trash
46
- property :id
47
- end
48
-
49
- it '#permitted_input_keys contain names of properties without translations' do
50
- expect(TrashTestPermitted.permitted_input_keys).to include :id
51
- end
52
- end
53
-
54
- describe 'writing to properties' do
55
- it 'does not write to a non-existent property using []=' do
56
- expect { trash['abc'] = 123 }.to raise_error(NoMethodError)
57
- end
58
-
59
- it 'writes to an existing property using []=' do
60
- expect { trash[:first_name] = 'Bob' }.not_to raise_error
61
- expect(trash.first_name).to eq('Bob')
62
- expect { trash['first_name'] = 'John' }.to raise_error(NoMethodError)
63
- end
64
-
65
- it 'writes to a translated property using []=' do
66
- expect { trash[:firstName] = 'Bob' }.not_to raise_error
67
- expect { trash['firstName'] = 'Bob' }.to raise_error(NoMethodError)
68
- end
69
-
70
- it 'reads/writes to an existing property using a method call' do
71
- trash.first_name = 'Franklin'
72
- expect(trash.first_name).to eq 'Franklin'
73
- end
74
-
75
- it 'writes to an translated property using a method call' do
76
- trash.firstName = 'Franklin'
77
- expect(trash.first_name).to eq 'Franklin'
78
- end
79
-
80
- it 'writes to a translated property using #replace' do
81
- trash.replace(firstName: 'Franklin')
82
- expect(trash.first_name).to eq 'Franklin'
83
- end
84
-
85
- it 'writes to a non-translated property using #replace' do
86
- trash.replace(first_name: 'Franklin')
87
- expect(trash.first_name).to eq 'Franklin'
88
- end
89
- end
90
-
91
- describe ' initializing with a Hash' do
92
- it 'does not initialize non-existent properties' do
93
- expect { TrashTest.new(bork: 'abc') }.to raise_error(NoMethodError)
94
- end
95
-
96
- it 'sets the desired properties' do
97
- expect(TrashTest.new(first_name: 'Michael').first_name).to eq 'Michael'
98
- end
99
-
100
- context 'with both the translated property and the property' do
101
- it 'sets the desired properties' do
102
- expect(TrashTest.new(first_name: 'Michael', firstName: 'Maeve').first_name).to eq 'Michael'
103
- end
104
- end
105
-
106
- it 'sets the translated properties' do
107
- expect(TrashTest.new(firstName: 'Michael').first_name).to eq 'Michael'
108
- end
109
- end
110
-
111
- describe 'translating properties using a proc' do
112
- class TrashLambdaTest < Hashie::Trash
113
- property :first_name, from: :firstName, with: ->(value) { value.reverse }
114
- end
115
-
116
- let(:lambda_trash) { TrashLambdaTest.new }
117
-
118
- it 'translates the value given on initialization with the given lambda' do
119
- expect(TrashLambdaTest.new(firstName: 'Michael').first_name).to eq 'Michael'.reverse
120
- end
121
-
122
- it 'does not translate the value if given with the right property' do
123
- expect(TrashTest.new(first_name: 'Michael').first_name).to eq 'Michael'
124
- end
125
-
126
- it 'translates the value given as property with the given lambda' do
127
- lambda_trash.firstName = 'Michael'
128
- expect(lambda_trash.first_name).to eq 'Michael'.reverse
129
- end
130
-
131
- it 'does not translate the value given as right property' do
132
- lambda_trash.first_name = 'Michael'
133
- expect(lambda_trash.first_name).to eq 'Michael'
134
- end
135
- end
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
-
160
- describe 'uses with or transform_with interchangeably' do
161
- class TrashLambdaTestTransformWith < Hashie::Trash
162
- property :first_name, from: :firstName, transform_with: ->(value) { value.reverse }
163
- end
164
-
165
- let(:lambda_trash) { TrashLambdaTestTransformWith.new }
166
-
167
- it 'translates the value given as property with the given lambda' do
168
- lambda_trash.firstName = 'Michael'
169
- expect(lambda_trash.first_name).to eq 'Michael'.reverse
170
- end
171
-
172
- it 'does not translate the value given as right property' do
173
- lambda_trash.first_name = 'Michael'
174
- expect(lambda_trash.first_name).to eq 'Michael'
175
- end
176
- end
177
-
178
- describe 'translating properties without from option using a proc' do
179
- class TrashLambdaTestWithProperties < Hashie::Trash
180
- property :first_name, transform_with: ->(value) { value.reverse }
181
- end
182
-
183
- let(:lambda_trash) { TrashLambdaTestWithProperties.new }
184
-
185
- it 'translates the value given as property with the given lambda' do
186
- lambda_trash.first_name = 'Michael'
187
- expect(lambda_trash.first_name).to eq 'Michael'.reverse
188
- end
189
-
190
- it 'transforms the value when given in constructor' do
191
- expect(TrashLambdaTestWithProperties.new(first_name: 'Michael').first_name).to eq 'Michael'.reverse
192
- end
193
-
194
- context 'when :from option is given' do
195
- class TrashLambdaTest3 < Hashie::Trash
196
- property :first_name, from: :firstName, transform_with: ->(value) { value.reverse }
197
- end
198
-
199
- it 'does not override the :from option in the constructor' do
200
- expect(TrashLambdaTest3.new(first_name: 'Michael').first_name).to eq 'Michael'
201
- end
202
-
203
- it 'does not override the :from option when given as property' do
204
- t = TrashLambdaTest3.new
205
- t.first_name = 'Michael'
206
- expect(t.first_name).to eq 'Michael'
207
- end
208
- end
209
- end
210
-
211
- describe 'inheritable transforms' do
212
- class TransformA < Hashie::Trash
213
- property :some_value, transform_with: ->(v) { v.to_i }
214
- end
215
-
216
- class TransformB < TransformA
217
- property :some_other_value, transform_with: ->(v) { v.to_i }
218
- end
219
-
220
- class TransformC < TransformB
221
- property :some_value, transform_with: ->(v) { -v.to_i }
222
- end
223
-
224
- it 'inherit properties transforms' do
225
- expect(TransformB.new(some_value: '123', some_other_value: '456').some_value).to eq(123)
226
- end
227
-
228
- it 'replaces property transform' do
229
- expect(TransformC.new(some_value: '123', some_other_value: '456').some_value).to eq(-123)
230
- end
231
- end
232
-
233
- describe 'inheritable translations' do
234
- class TranslationA < Hashie::Trash
235
- property :some_value, from: 'someValue', with: ->(v) { v.to_i }
236
- end
237
-
238
- class TranslationB < TranslationA
239
- property :some_other_value, from: 'someOtherValue'
240
- end
241
-
242
- it 'inherit properties translations' do
243
- expect(TranslationB.new('someValue' => '123').some_value).to eq(123)
244
- end
245
- end
246
-
247
- it 'raises an error when :from have the same value as property' do
248
- expect do
249
- class WrongTrash < Hashie::Trash
250
- property :first_name, from: :first_name
251
- end
252
- end.to raise_error(ArgumentError)
253
- end
254
-
255
- context 'when subclassing' do
256
- class Person < Hashie::Trash
257
- property :first_name, from: :firstName
258
- end
259
-
260
- class Hobbit < Person; end
261
-
262
- subject { Hobbit.new(firstName: 'Frodo') }
263
-
264
- it 'keeps translation definitions in subclasses' do
265
- expect(subject.first_name).to eq('Frodo')
266
- end
267
- end
268
- end
@@ -1,7 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Hashie do
4
- it 'has a version' do
5
- expect(Hashie::VERSION).not_to be_nil
6
- end
7
- end
data/spec/spec_helper.rb DELETED
@@ -1,16 +0,0 @@
1
- if ENV['CI']
2
- require 'codeclimate-test-reporter'
3
- CodeClimate::TestReporter.start
4
- end
5
-
6
- require 'pry'
7
-
8
- require 'rspec'
9
- require 'hashie'
10
- require 'rspec/pending_for'
11
-
12
- RSpec.configure do |config|
13
- config.expect_with :rspec do |expect|
14
- expect.syntax = :expect
15
- end
16
- end
@@ -1,11 +0,0 @@
1
- shared_context 'included hash module' do
2
- let!(:dummy_class) do
3
- klass = Class.new(::Hash)
4
- klass.send :include, described_class
5
- klass
6
- end
7
-
8
- subject do
9
- dummy_class.new
10
- end
11
- end