hashie 3.4.3 → 3.4.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6121c5c81c02643a5ac8bcf1633e09c0d18dd238
4
- data.tar.gz: bfa9a6bed6dc2aef1f034297f30bc66ebe72b7ef
3
+ metadata.gz: 08dd1e6f13c8a218c2d8417c194f598e7b063e34
4
+ data.tar.gz: 2a3431f1435c2cc7fae475303d8eaa3e0c68f709
5
5
  SHA512:
6
- metadata.gz: cad338b78028860f36e964e2d531d793419e7ae533f2f33c452c60cd5e3df0a5e1f7838da102ed7b3b39f2be5c8ef3123bed779f477d970533b69d91ff6c27fd
7
- data.tar.gz: 5bbb4adec507c10102832cca447f302ff5693e97131bc8d4c13f0e14038cff6605ceed36e77153d7bfa078aefe838513216ac64da945af464cb9a8213dbd5cd2
6
+ metadata.gz: f802e665c81b36ff942f27f500ab7928db9cfa1812a74ecccdf68bcbb2ef3c4df7c16c6c8ff9e44b9bc62246474a8a0027092f07ed1f92c92ef4793fb0e8bc53
7
+ data.tar.gz: d1fb7562ac07a170355729e8dbbaa0ceee73c6307a7175109363d8b95e823db45461693d7469b28c86616090dfd2bfc1ce984296db00c7b4511d54feca6f31b5
@@ -1,154 +1,320 @@
1
- ## 3.4.2 (10/25/2015)
1
+ # Change Log
2
2
 
3
+ All notable changes to this project will be documented in this file. This
4
+ project adheres to [Semantic Versioning 2.0.0][semver]. Any violations of this
5
+ scheme are considered to be bugs.
6
+
7
+ [semver]: http://semver.org/spec/v2.0.0.html
8
+
9
+ ## [3.4.4] - 2016-04-29
10
+
11
+ [3.4.4]: https://github.com/intridea/hashie/compare/v3.4.3...v3.4.4
12
+
13
+ ### Added
14
+
15
+ * [#349](https://github.com/intridea/hashie/pull/349): Convert `Hashie::Mash#dig` arguments for Ruby 2.3.0 - [@k0kubun](https://github.com/k0kubun).
16
+
17
+ ### Fixed
18
+
19
+ * [#240](https://github.com/intridea/hashie/pull/240): Fixed nesting twice with Clash keys - [@bartoszkopinski](https://github.com/bartoszkopinski).
20
+ * [#317](https://github.com/intridea/hashie/pull/317): Ensure `Hashie::Extensions::MethodQuery` methods return boolean values - [@michaelherold](https://github.com/michaelherold).
21
+ * [#319](https://github.com/intridea/hashie/pull/319): Fix a regression from 3.4.1 where `Hashie::Extensions::DeepFind` is no longer indifference-aware - [@michaelherold](https://github.com/michaelherold).
22
+ * [#322](https://github.com/intridea/hashie/pull/322): Fixed `reverse_merge` issue with `Mash` subclasses - [@marshall-lee](https://github.com/marshall-lee).
23
+ * [#346](https://github.com/intridea/hashie/pull/346): Fixed `merge` breaking indifferent access - [@docwhat](https://github.com/docwhat), [@michaelherold](https://github.com/michaelherold).
24
+ * [#350](https://github.com/intridea/hashie/pull/350): Fixed from string translations used with `IgnoreUndeclared` - [@marshall-lee](https://github.com/marshall-lee).
25
+
26
+ ## [3.4.3] - 2015-10-25
27
+
28
+ [3.4.3]: https://github.com/intridea/hashie/compare/v3.4.2...v3.4.3
29
+
30
+ ### Added
31
+
32
+ * [#306](https://github.com/intridea/hashie/pull/306): Added `Hashie::Extensions::Dash::Coercion` - [@marshall-lee](https://github.com/marshall-lee).
3
33
  * [#314](https://github.com/intridea/hashie/pull/314): Added a `StrictKeyAccess` extension that will raise an error whenever a key is accessed that does not exist in the hash - [@pboling](https://github.com/pboling).
34
+
35
+ ### Fixed
36
+
4
37
  * [#304](https://github.com/intridea/hashie/pull/304): Ensured compatibility of `Hash` extensions with singleton objects - [@regexident](https://github.com/regexident).
5
- * [#306](https://github.com/intridea/hashie/pull/306): Added `Hashie::Extensions::Dash::Coercion` - [@marshall-lee](https://github.com/marshall-lee).
6
38
  * [#310](https://github.com/intridea/hashie/pull/310): Fixed `Hashie::Extensions::SafeAssignment` bug with private methods - [@marshall-lee](https://github.com/marshall-lee).
39
+
40
+ ### Miscellaneous
41
+
7
42
  * [#313](https://github.com/intridea/hashie/pull/313): Restrict pending spec to only Ruby versions 2.2.0-2.2.2 - [@pboling](https://github.com/pboling).
8
43
  * [#315](https://github.com/intridea/hashie/pull/315): Default `bin/` scripts: `console` and `setup` - [@pboling](https://github.com/pboling).
9
44
 
10
- ## 3.4.2 (6/2/2015)
45
+ ## [3.4.2] - 2015-06-02
46
+
47
+ [3.4.2]: https://github.com/intridea/hashie/compare/v3.4.1...v3.4.2
48
+
49
+ ### Added
11
50
 
12
- * [#292](https://github.com/intridea/hashie/pull/292): Removed `Mash#id` and `Mash#type` - [@jrochkind](https://github.com/jrochkind).
13
51
  * [#297](https://github.com/intridea/hashie/pull/297): Extracted `Trash`'s behavior into a new `Dash::PropertyTranslation` extension - [@michaelherold](https://github.com/michaelherold).
14
52
 
15
- ## 3.4.1 (3/31/2015)
53
+ ### Removed
54
+
55
+ * [#292](https://github.com/intridea/hashie/pull/292): Removed `Mash#id` and `Mash#type` - [@jrochkind](https://github.com/jrochkind).
56
+
57
+ ## [3.4.1] - 2015-03-31
58
+
59
+ [3.4.1]: https://github.com/intridea/hashie/compare/v3.4.0...v3.4.1
60
+
61
+ ### Added
16
62
 
17
63
  * [#269](https://github.com/intridea/hashie/pull/272): Added Hashie::Extensions::DeepLocate - [@msievers](https://github.com/msievers).
18
- * [#270](https://github.com/intridea/hashie/pull/277): Fixed ArgumentError raised when using IndifferentAccess and HashWithIndifferentAccess - [@gardenofwine](https://github.com/gardenofwine).
19
64
  * [#281](https://github.com/intridea/hashie/pull/281): Added #reverse_merge to Mash to override ActiveSupport's version - [@mgold](https://github.com/mgold).
65
+
66
+ ### Fixed
67
+
68
+ * [#270](https://github.com/intridea/hashie/pull/277): Fixed ArgumentError raised when using IndifferentAccess and HashWithIndifferentAccess - [@gardenofwine](https://github.com/gardenofwine).
20
69
  * [#282](https://github.com/intridea/hashie/pull/282): Fixed coercions in a subclass accumulating in the superclass - [@maxlinc](https://github.com/maxlinc), [@martinstreicher](https://github.com/martinstreicher).
21
70
 
22
- ## 3.4.0 (2/02/2015)
71
+ ## [3.4.0] - 2015-02-02
72
+
73
+ [3.4.0]: https://github.com/intridea/hashie/compare/v3.3.2...v3.4.0
74
+
75
+ ### Added
23
76
 
24
- * [#271](https://github.com/intridea/hashie/pull/271): Added ability to define defaults based on current hash - [@gregory](https://github.com/gregory).
25
- * [#247](https://github.com/intridea/hashie/pull/247): Fixed #stringify_keys and #symbolize_keys collision with ActiveSupport - [@bartoszkopinski](https://github.com/bartoszkopinski).
26
- * [#249](https://github.com/intridea/hashie/pull/249): SafeAssignment will now also protect hash-style assignments - [@jrochkind](https://github.com/jrochkind).
27
77
  * [#251](https://github.com/intridea/hashie/pull/251): Added block support to indifferent access #fetch - [@jgraichen](https://github.com/jgraichen).
28
78
  * [#252](https://github.com/intridea/hashie/pull/252): Added support for conditionally required Hashie::Dash attributes - [@ccashwell](https://github.com/ccashwell).
79
+ * [#254](https://github.com/intridea/hashie/pull/254): Added public utility methods for stringify and symbolize keys - [@maxlinc](https://github.com/maxlinc).
80
+ * [#260](https://github.com/intridea/hashie/pull/260): Added block support to Extensions::DeepMerge - [@galathius](https://github.com/galathius).
81
+ * [#271](https://github.com/intridea/hashie/pull/271): Added ability to define defaults based on current hash - [@gregory](https://github.com/gregory).
82
+
83
+ ### Changed
84
+
85
+ * [#249](https://github.com/intridea/hashie/pull/249): SafeAssignment will now also protect hash-style assignments - [@jrochkind](https://github.com/jrochkind).
86
+ * [#264](https://github.com/intridea/hashie/pull/264): Methods such as abc? return true/false with Hashie::Extensions::MethodReader - [@Zloy](https://github.com/Zloy).
87
+
88
+ ### Fixed
89
+
90
+ * [#247](https://github.com/intridea/hashie/pull/247): Fixed #stringify_keys and #symbolize_keys collision with ActiveSupport - [@bartoszkopinski](https://github.com/bartoszkopinski).
29
91
  * [#256](https://github.com/intridea/hashie/pull/256): Inherit key coercions - [@Erol](https://github.com/Erol).
30
92
  * [#259](https://github.com/intridea/hashie/pull/259): Fixed handling of default proc values in Mash - [@Erol](https://github.com/Erol).
31
- * [#260](https://github.com/intridea/hashie/pull/260): Added block support to Extensions::DeepMerge - [@galathius](https://github.com/galathius).
32
- * [#254](https://github.com/intridea/hashie/pull/254): Added public utility methods for stringify and symbolize keys - [@maxlinc](https://github.com/maxlinc).
33
93
  * [#261](https://github.com/intridea/hashie/pull/261): Fixed bug where Dash.property modifies argument object - [@d-tw](https://github.com/d-tw).
34
- * [#264](https://github.com/intridea/hashie/pull/264): Methods such as abc? return true/false with Hashie::Extensions::MethodReader - [@Zloy](https://github.com/Zloy).
35
94
  * [#269](https://github.com/intridea/hashie/pull/269): Add #extractable_options? so ActiveSupport Array#extract_options! can extract it - [@ridiculous](https://github.com/ridiculous).
36
95
 
37
- ## 3.3.2 (11/26/2014)
96
+ ## [3.3.2] - 2014-11-26
97
+
98
+ [3.3.2]: https://github.com/intridea/hashie/compare/v3.3.1...v3.3.2
99
+
100
+ ### Added
38
101
 
39
- * [#233](https://github.com/intridea/hashie/pull/233): Custom error messages for required properties in Hashie::Dash subclasses - [@joss](https://github.com/joss).
40
102
  * [#231](https://github.com/intridea/hashie/pull/231): Added support for coercion on class type that inherit from Hash - [@gregory](https://github.com/gregory).
41
- * [#228](https://github.com/intridea/hashie/pull/228): Made Hashie::Extensions::Parsers::YamlErbParser pass template filename to ERB - [@jperville](https://github.com/jperville).
42
- * [#224](https://github.com/intridea/hashie/pull/224): Merging Hashie::Mash now correctly only calls the block on duplicate values - [@amysutedja](https://github.com/amysutedja).
43
- * [#221](https://github.com/intridea/hashie/pull/221): Reduce amount of allocated objects on calls with suffixes in Hashie::Mash - [@kubum](https://github.com/kubum).
103
+ * [#233](https://github.com/intridea/hashie/pull/233): Custom error messages for required properties in Hashie::Dash subclasses - [@joss](https://github.com/joss).
44
104
  * [#245](https://github.com/intridea/hashie/pull/245): Added Hashie::Extensions::MethodAccessWithOverride to autoloads - [@Fritzinger](https://github.com/Fritzinger).
45
105
 
46
- ## 3.3.1 (8/26/2014)
106
+ ### Fixed
107
+
108
+ * [#221](https://github.com/intridea/hashie/pull/221): Reduce amount of allocated objects on calls with suffixes in Hashie::Mash - [@kubum](https://github.com/kubum).
109
+ * [#224](https://github.com/intridea/hashie/pull/224): Merging Hashie::Mash now correctly only calls the block on duplicate values - [@amysutedja](https://github.com/amysutedja).
110
+ * [#228](https://github.com/intridea/hashie/pull/228): Made Hashie::Extensions::Parsers::YamlErbParser pass template filename to ERB - [@jperville](https://github.com/jperville).
111
+
112
+ ## [3.3.1] - 2014-08-26
113
+
114
+ [3.3.1]: https://github.com/intridea/hashie/compare/v3.3.0...v3.3.1
115
+
116
+ ### Added
47
117
 
48
118
  * [#183](https://github.com/intridea/hashie/pull/183): Added Mash#load with YAML file support - [@gregory](https://github.com/gregory).
49
- * [#195](https://github.com/intridea/hashie/pull/195): Ensure that the same object is returned after injecting IndifferentAccess - [@michaelherold](https://github.com/michaelherold).
50
- * [#201](https://github.com/intridea/hashie/pull/201): Hashie::Trash transforms can be inherited - [@fobocaster](https://github.com/fobocaster).
51
119
  * [#189](https://github.com/intridea/hashie/pull/189): Added Rash#fetch - [@medcat](https://github.com/medcat).
52
- * [#200](https://github.com/intridea/hashie/pull/200): Improved coercion: primitives and error handling - [@maxlinc](https://github.com/maxlinc).
53
120
  * [#204](https://github.com/intridea/hashie/pull/204): Added Hashie::Extensions::MethodOverridingWriter and MethodAccessWithOverride - [@michaelherold](https://github.com/michaelherold).
54
121
  * [#205](http://github.com/intridea/hashie/pull/205): Added Hashie::Extensions::Mash::SafeAssignment - [@michaelherold](https://github.com/michaelherold).
55
- * [#206](http://github.com/intridea/hashie/pull/206): Fixed stack overflow from repetitively including coercion in subclasses - [@michaelherold](https://github.com/michaelherold).
56
- * [#207](http://github.com/intridea/hashie/pull/207): Fixed inheritance of transformations in Trash - [@fobocaster](https://github.com/fobocaster).
57
122
  * [#209](http://github.com/intridea/hashie/pull/209): Added Hashie::Extensions::DeepFind - [@michaelherold](https://github.com/michaelherold).
123
+
124
+ ### Fixed
125
+
58
126
  * [#69](https://github.com/intridea/hashie/pull/69): Fixed regression in assigning multiple properties in Hashie::Trash - [@michaelherold](https://github.com/michaelherold), [@einzige](https://github.com/einzige), [@dblock](https://github.com/dblock).
127
+ * [#195](https://github.com/intridea/hashie/pull/195): Ensure that the same object is returned after injecting IndifferentAccess - [@michaelherold](https://github.com/michaelherold).
128
+ * [#201](https://github.com/intridea/hashie/pull/201): Hashie::Trash transforms can be inherited - [@fobocaster](https://github.com/fobocaster).
129
+ * [#200](https://github.com/intridea/hashie/pull/200): Improved coercion: primitives and error handling - [@maxlinc](https://github.com/maxlinc).
130
+ * [#206](http://github.com/intridea/hashie/pull/206): Fixed stack overflow from repetitively including coercion in subclasses - [@michaelherold](https://github.com/michaelherold).
131
+ * [#207](http://github.com/intridea/hashie/pull/207): Fixed inheritance of transformations in Trash - [@fobocaster](https://github.com/fobocaster).
59
132
 
60
- ## 3.2.0 (7/10/2014)
133
+ ## [3.2.0] - 2014-07-10
134
+
135
+ [3.2.0]: https://github.com/intridea/hashie/compare/v3.1.0...v3.2.0
136
+
137
+ ### Added
61
138
 
62
- * [#164](https://github.com/intridea/hashie/pull/164), [#165](https://github.com/intridea/hashie/pull/165), [#166](https://github.com/intridea/hashie/pull/166): Fixed stack overflow when coercing mashes that contain ActiveSupport::HashWithIndifferentAccess values - [@numinit](https://github.com/numinit), [@kgrz](https://github.com/kgrz).
63
139
  * [#177](https://github.com/intridea/hashie/pull/177): Added support for coercing enumerables and collections - [@gregory](https://github.com/gregory).
140
+
141
+ ### Changed
142
+
64
143
  * [#179](https://github.com/intridea/hashie/pull/179): Mash#values_at will convert each key before doing the lookup - [@nahiluhmot](https://github.com/nahiluhmot).
65
144
  * [#184](https://github.com/intridea/hashie/pull/184): Allow ranges on Rash to match all Numeric types - [@medcat](https://github.com/medcat).
145
+
146
+ ### Fixed
147
+
148
+ * [#164](https://github.com/intridea/hashie/pull/164), [#165](https://github.com/intridea/hashie/pull/165), [#166](https://github.com/intridea/hashie/pull/166): Fixed stack overflow when coercing mashes that contain ActiveSupport::HashWithIndifferentAccess values - [@numinit](https://github.com/numinit), [@kgrz](https://github.com/kgrz).
66
149
  * [#187](https://github.com/intridea/hashie/pull/187): Automatically require version - [@medcat](https://github.com/medcat).
67
150
  * [#190](https://github.com/intridea/hashie/issues/190): Fixed `coerce_key` with `from` Trash feature and Coercion extension - [@gregory](https://github.com/gregory).
68
151
  * [#192](https://github.com/intridea/hashie/pull/192): Fixed StringifyKeys#stringify_keys! to recursively stringify keys of embedded ::Hash types - [@dblock](https://github.com/dblock).
69
152
 
70
- ## 3.1.0 (6/25/2014)
153
+ ## [3.1.0] - 2014-06-25
154
+
155
+ [3.1.0]: https://github.com/intridea/hashie/compare/v3.0.0...v3.1.0
156
+
157
+ ### Added
158
+
159
+ * [#172](https://github.com/intridea/hashie/pull/172): Added Dash and Trash#update_attributes! - [@gregory](https://github.com/gregory).
160
+
161
+ ### Changed
71
162
 
72
163
  * [#169](https://github.com/intridea/hashie/pull/169): Hash#to_hash will also convert nested objects that implement to_hash - [@gregory](https://github.com/gregory).
164
+ * [#173](https://github.com/intridea/hashie/pull/173): Auto include Dash::IndifferentAccess when IndifferentAccess is included in Dash - [@gregory](https://github.com/gregory).
165
+
166
+ ### Fixed
167
+
73
168
  * [#171](https://github.com/intridea/hashie/pull/171): Include Trash and Dash class name when raising `NoMethodError` - [@gregory](https://github.com/gregory).
74
- * [#172](https://github.com/intridea/hashie/pull/172): Added Dash and Trash#update_attributes! - [@gregory](https://github.com/gregory).
75
- * [#173](https://github.com/intridea/hashie/pull/173): Auto include Dash::IndifferentAccess when IndiferentAccess is included in Dash - [@gregory](https://github.com/gregory).
76
169
  * [#174](https://github.com/intridea/hashie/pull/174): Fixed `from` and `transform_with` Trash features when IndifferentAccess is included - [@gregory](https://github.com/gregory).
77
170
 
78
- ## 3.0.0 (6/3/2014)
171
+ ## [3.0.0] - 2014-06-03
172
+
173
+ [3.0.0]: https://github.com/intridea/hashie/compare/v2.1.2...v3.0.0
79
174
 
80
175
  **Note:** This version introduces several backward incompatible API changes. See [UPGRADING](UPGRADING.md) for details.
81
176
 
82
- * [#150](https://github.com/intridea/hashie/pull/159): Handle nil intermediate object on deep fetch - [@stephenaument](https://github.com/stephenaument).
83
- * [#146](https://github.com/intridea/hashie/issues/146): Mash#respond_to? inconsistent with #method_missing and does not respond to #permitted? - [@dblock](https://github.com/dblock).
177
+ ### Added
178
+
179
+ * [#149](https://github.com/intridea/hashie/issues/149): Allow IgnoreUndeclared and DeepMerge to be used with undeclared properties - [@jhaesus](https://github.com/jhaesus).
180
+
181
+ ### Changed
182
+
84
183
  * [#152](https://github.com/intridea/hashie/pull/152): Do not convert keys to String in Hashie::Dash and Hashie::Trash, use Hashie::Extensions::Dash::IndifferentAccess to achieve backward compatible behavior - [@dblock](https://github.com/dblock).
85
184
  * [#152](https://github.com/intridea/hashie/pull/152): Do not automatically stringify keys in Hashie::Hash#to_hash, pass `:stringify_keys` to achieve backward compatible behavior - [@dblock](https://github.com/dblock).
185
+
186
+ ### Fixed
187
+
188
+ * [#146](https://github.com/intridea/hashie/issues/146): Mash#respond_to? inconsistent with #method_missing and does not respond to #permitted? - [@dblock](https://github.com/dblock).
86
189
  * [#148](https://github.com/intridea/hashie/pull/148): Consolidated Hashie::Hash#stringify_keys implementation - [@dblock](https://github.com/dblock).
87
- * [#149](https://github.com/intridea/hashie/issues/149): Allow IgnoreUndeclared and DeepMerge to be used with undeclared properties - [@jhaesus](https://github.com/jhaesus).
190
+ * [#159](https://github.com/intridea/hashie/pull/159): Handle nil intermediate object on deep fetch - [@stephenaument](https://github.com/stephenaument).
191
+
192
+ ## [2.1.2] - 2014-05-12
88
193
 
89
- ## 2.1.2 (5/12/2014)
194
+ [2.1.2]: https://github.com/intridea/hashie/compare/v2.1.1...v2.1.2
195
+
196
+ ### Changed
90
197
 
91
198
  * [#169](https://github.com/intridea/hashie/pull/169): Hash#to_hash will also convert nested objects that implement `to_hash` - [@gregory](https://github.com/gregory).
92
199
 
93
- ## 2.1.1 (4/12/2014)
200
+ ## [2.1.1] - 2014-04-12
201
+
202
+ [2.1.1]: https://github.com/intridea/hashie/compare/v2.1.0...v2.1.1
203
+
204
+ ### Fixed
94
205
 
206
+ * [#131](https://github.com/intridea/hashie/pull/131): Added IgnoreUndeclared, an extension to silently ignore undeclared properties at intialization - [@righi](https://github.com/righi).
207
+ * [#138](https://github.com/intridea/hashie/pull/138): Added Hashie::Rash, a hash whose keys can be regular expressions or ranges - [@epitron](https://github.com/epitron).
95
208
  * [#144](https://github.com/intridea/hashie/issues/144): Fixed regression invoking `to_hash` with no parameters - [@mbleigh](https://github.com/mbleigh).
96
209
 
97
- ## 2.1.0 (4/6/2014)
210
+ ## [2.1.0] - 2014-04-06
211
+
212
+ [2.1.0]: https://github.com/intridea/hashie/compare/v2.0.5...v2.1.0
213
+
214
+ ### Added
98
215
 
99
216
  * [#134](https://github.com/intridea/hashie/pull/134): Add deep_fetch extension for nested access - [@tylerdooling](https://github.com/tylerdooling).
217
+
218
+ ### Changed
219
+
220
+ * [#89](https://github.com/intridea/hashie/issues/89): Do not respond to every method with suffix in Hashie::Mash, fixes Rails strong_parameters - [@Maxim-Filimonov](https://github.com/Maxim-Filimonov).
221
+
222
+ ### Removed
223
+
100
224
  * Removed support for Ruby 1.8.7 - [@dblock](https://github.com/dblock).
101
- * Ruby style now enforced with Rubocop - [@dblock](https://github.com/dblock).
102
- * [#138](https://github.com/intridea/hashie/pull/138): Added Hashie::Rash, a hash whose keys can be regular expressions or ranges - [@epitron](https://github.com/epitron).
103
- * [#131](https://github.com/intridea/hashie/pull/131): Added IgnoreUndeclared, an extension to silently ignore undeclared properties at intialization - [@righi](https://github.com/righi).
104
225
  * [#136](https://github.com/intridea/hashie/issues/136): Removed Hashie::Extensions::Structure - [@markiz](https://github.com/markiz).
105
- * [#107](https://github.com/intridea/hashie/pull/107): Fixed excessive value conversions, poor performance of deep merge in Hashie::Mash - [@davemitchell](https://github.com/dblock), [@dblock](https://github.com/dblock).
226
+
227
+ ### Fixed
228
+
106
229
  * [#69](https://github.com/intridea/hashie/issues/69): Fixed assigning multiple properties in Hashie::Trash - [@einzige](https://github.com/einzige).
230
+ * [#99](https://github.com/intridea/hashie/issues/99): Hash#deep_merge raises errors when it encounters integers - [@defsprite](https://github.com/defsprite).
107
231
  * [#100](https://github.com/intridea/hashie/pull/100): IndifferentAccess#store will respect indifference - [@jrochkind](https://github.com/jrochkind).
108
232
  * [#103](https://github.com/intridea/hashie/pull/103): Fixed support for Hashie::Dash properties that end in bang - [@thedavemarshall](https://github.com/thedavemarshall).
109
- * [89](https://github.com/intridea/hashie/issues/89): Do not respond to every method with suffix in Hashie::Mash, fixes Rails strong_parameters - [@Maxim-Filimonov](https://github.com/Maxim-Filimonov).
233
+ * [#107](https://github.com/intridea/hashie/pull/107): Fixed excessive value conversions, poor performance of deep merge in Hashie::Mash - [@davemitchell](https://github.com/dblock), [@dblock](https://github.com/dblock).
110
234
  * [#110](https://github.com/intridea/hashie/pull/110): Correctly use Hash#default from Mash#method_missing - [@ryansouza](https://github.com/ryansouza).
111
- * [#120](https://github.com/intridea/hashie/pull/120): Pass options to recursive to_hash calls - [@pwillett](https://github.com/pwillett).
112
- * [#113](https://github.com/intridea/hashie/issues/113): Fixed Hash#merge with Hashie::Dash - [@spencer1248](https://github.com/spencer1248).
113
- * [#99](https://github.com/intridea/hashie/issues/99): Hash#deep_merge raises errors when it encounters integers - [@defsprite](https://github.com/defsprite).
114
- * [#133](https://github.com/intridea/hashie/pull/133): Fixed Hash##to_hash with symbolize_keys - [@mhuggins](https://github.com/mhuggins).
115
- * [#130](https://github.com/intridea/hashie/pull/130): IndifferentAccess now works without MergeInitializer - [@npj](https://github.com/npj).
116
235
  * [#111](https://github.com/intridea/hashie/issues/111): Trash#translations correctly maps original to translated names - [@artm](https://github.com/artm).
236
+ * [#113](https://github.com/intridea/hashie/issues/113): Fixed Hash#merge with Hashie::Dash - [@spencer1248](https://github.com/spencer1248).
237
+ * [#120](https://github.com/intridea/hashie/pull/120): Pass options to recursive to_hash calls - [@pwillett](https://github.com/pwillett).
117
238
  * [#129](https://github.com/intridea/hashie/pull/129): Added Trash#permitted_input_keys and inverse_translations - [@artm](https://github.com/artm).
239
+ * [#130](https://github.com/intridea/hashie/pull/130): IndifferentAccess now works without MergeInitializer - [@npj](https://github.com/npj).
240
+ * [#133](https://github.com/intridea/hashie/pull/133): Fixed Hash##to_hash with symbolize_keys - [@mhuggins](https://github.com/mhuggins).
241
+
242
+ ### Miscellaneous
243
+
244
+ * Ruby style now enforced with Rubocop - [@dblock](https://github.com/dblock).
245
+
246
+ ## [2.0.5] - 2013-05-10
118
247
 
119
- ## 2.0.5
248
+ [2.0.5]: https://github.com/intridea/hashie/compare/v2.0.4...v2.0.5
249
+
250
+ ### Fixed
120
251
 
121
252
  * [#96](https://github.com/intridea/hashie/pull/96): Make coercion work better with non-symbol keys in Hashie::Mash - [@wapcaplet](https://github.com/wapcaplet).
122
253
 
123
- ## 2.0.4
254
+ ## [2.0.4] - 2013-04-24
255
+
256
+ [2.0.4]: https://github.com/intridea/hashie/compare/v2.0.3...v2.0.4
257
+
258
+ ### Fixed
259
+
260
+ * [#94](https://github.com/intridea/hashie/pull/94): Make #fetch method consistent with normal Hash - [@markiz](https://github.com/markiz).
261
+
262
+ ### Miscellaneous
124
263
 
125
- * [#04](https://github.com/intridea/hashie/pull/94): Make #fetch method consistent with normal Hash - [@markiz](https://github.com/markiz).
126
264
  * [#90](https://github.com/intridea/hashie/pull/90): Various doc tweaks - [@craiglittle](https://github.com/craiglittle).
127
265
 
128
- ## 2.0.3
266
+ ## [2.0.3] - 2013-03-18
267
+
268
+ [2.0.3]: https://github.com/intridea/hashie/compare/v2.0.2...v2.0.3
269
+
270
+ ### Fixed
129
271
 
130
- * [#88](https://github.com/intridea/hashie/pull/88): Hashie::Mash.new(abc: true).respond_to?(:abc?) works - [@7even](https://github.com/7even).
131
272
  * [#68](https://github.com/intridea/hashie/pull/68): Fix #replace - [@jimeh](https://github.com/jimeh).
273
+ * [#88](https://github.com/intridea/hashie/pull/88): Hashie::Mash.new(abc: true).respond_to?(:abc?) works - [@7even](https://github.com/7even).
274
+
275
+ ## [2.0.2] - 2013-02-26
132
276
 
133
- ## 2.0.2
277
+ [2.0.2]: https://github.com/intridea/hashie/compare/v2.0.1...v2.0.2
278
+
279
+ ### Fixed
134
280
 
135
281
  * [#85](https://github.com/intridea/hashie/pull/85): adding symbolize_keys back to to_hash - [@cromulus](https://github.com/cromulus).
136
282
 
137
- ## 2.0.1
283
+ ## [2.0.1] - 2013-02-26
284
+
285
+ [2.0.1]: https://github.com/intridea/hashie/compare/v2.0.0...v2.0.1
286
+
287
+ ### Removed
138
288
 
139
289
  * [#81](https://github.com/intridea/hashie/pull/81): remove Mash#object_id override - [@matschaffer](https://github.com/matschaffer).
290
+
291
+ ### Miscellaneous
292
+
140
293
  * Gem cleanup: removed VERSION, Gemfile.lock [@jch](https://github.com/jch), [@mbleigh](https://github.com/mbleigh).
141
294
 
142
- ## 2.0.0
295
+ ## [2.0.0] - 2013-02-16
296
+
297
+ [2.0.0]: https://github.com/intridea/hashie/compare/v1.2.0...v2.0.0
298
+
299
+ ### Added
300
+
301
+ * [#41](https://github.com/intridea/hashie/pull/41): DeepMerge extension - [@nashby](https://github.com/nashby).
302
+ * [#78](https://github.com/intridea/hashie/pull/78): Merge and update accepts a block - [@jch](https://github.com/jch).
303
+
304
+ ### Changed
143
305
 
144
- * [#72](https://github.com/intridea/hashie/pull/72): Updated gemspec with license info - [@jordimassaguerpla](https://github.com/jordimassaguerpla).
145
- * [#27](https://github.com/intridea/hashie/pull/27): Initialized with merge coerces values - [@mattfawcett](https://github.com/mattfawcett).
146
306
  * [#28](https://github.com/intridea/hashie/pull/28): Hashie::Extensions::Coercion coerce_keys takes arguments - [@mattfawcett](https://github.com/mattfawcett).
307
+ * [#77](https://github.com/intridea/hashie/pull/77): Remove id, type, and object_id as special allowable keys [@jch](https://github.com/jch).
308
+
309
+ ### Fixed
310
+
311
+ * [#27](https://github.com/intridea/hashie/pull/27): Initialized with merge coerces values - [@mattfawcett](https://github.com/mattfawcett).
147
312
  * [#39](https://github.com/intridea/hashie/pull/39): Trash removes translated values on initialization - [@sleverbor](https://github.com/sleverbor).
148
- * [#66](https://github.com/intridea/hashie/pull/66): Mash#fetch works with symbol or string keys - [@arthwood](https://github.com/arthwood).
149
313
  * [#49](https://github.com/intridea/hashie/pull/49): Hashie::Hash inherits from ::Hash to avoid ambiguity - [@meh](https://github.com/meh), [@orend](https://github.com/orend).
150
314
  * [#62](https://github.com/intridea/hashie/pull/62): update respond_to? method signature to match ruby core definition - [@dlupu](https://github.com/dlupu).
151
- * [#41](https://github.com/intridea/hashie/pull/41): DeepMerge extension - [@nashby](https://github.com/nashby).
152
315
  * [#63](https://github.com/intridea/hashie/pull/63): Dash defaults are dup'ed before assigned - [@ohrite](https://github.com/ohrite).
153
- * [#77](https://github.com/intridea/hashie/pull/77): Remove id, type, and object_id as special allowable keys [@jch](https://github.com/jch).
154
- * [#78](https://github.com/intridea/hashie/pull/78): Merge and update accepts a block - [@jch](https://github.com/jch).
316
+ * [#66](https://github.com/intridea/hashie/pull/66): Mash#fetch works with symbol or string keys - [@arthwood](https://github.com/arthwood).
317
+
318
+ ### Miscellaneous
319
+
320
+ * [#72](https://github.com/intridea/hashie/pull/72): Updated gemspec with license info - [@jordimassaguerpla](https://github.com/jordimassaguerpla).
@@ -52,7 +52,17 @@ Document any external behavior in the [README](README.md).
52
52
 
53
53
  #### Update Changelog
54
54
 
55
- Add a line to [CHANGELOG](CHANGELOG.md) under *Next Release*. Make it look like every other line, including your name and link to your Github account.
55
+ Add a line to [CHANGELOG](CHANGELOG.md) under *Unreleased*. Make it look like every other line, including your name and link to your Github account.
56
+
57
+ There are several categorizations of changes that you can choose from. Add your line to the appropriate section, following these conventions:
58
+
59
+ * **Added** - When you add a new behavior to any class or module (or add a new extension) that does not break backwards compatibility, you should mark it as "added". This is generally a fully new behavior that does not touch any pre-existing public API. Changes here require a MINOR version bump, following the Semantic Versioning specification.
60
+ * **Changed** - You should mark any change to the behavior of a public API on any class or module as "changed". Changes here require a MAJOR version bump, following the Semantic Versioning specification.
61
+ * **Deprecated** - Any time you deprecate part of the public API on any class or module you should mark the change as "deprecated". Deprecated behavior will be removed in the next MAJOR version bump, but should be left in until then. Changes here require a MINOR version bump, following the Semantic Versioning specification.
62
+ * **Removed** - You should mark any behavior that you removed from a public API on any class or module as "removed". Changes here require a MAJOR version bump, following the Semantic Versioning specification.
63
+ * **Fixed** - Any time you fix a bug you should mark as "fixed". Changes here require a PATCH version bump.
64
+ * **Security** - You should mark any security issue that you fix as "security". Changes here require a PATCH version bump.
65
+ * **Miscellaneous** - Mark any other changes you make (i.e. documentation updates, test harness changes, etc.) as "miscellaneous". Changes here require a PATCH version bump.
56
66
 
57
67
  #### Commit Changes
58
68
 
data/README.md CHANGED
@@ -18,13 +18,13 @@ Hashie is available as a RubyGem:
18
18
  $ gem install hashie
19
19
  ```
20
20
 
21
- ## Stable Release
21
+ ## Upgrading
22
22
 
23
- You're reading the documentation for the stable release [3.4.3](https://github.com/intridea/hashie/blob/v3.4.3/README.md).
23
+ You're reading the documentation for the stable release of Hashie, 3.4.4. Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version.
24
24
 
25
25
  ## Hash Extensions
26
26
 
27
- The library is broken up into a number of atomically includeable Hash extension modules as described below. This provides maximum flexibility for users to mix and match functionality while maintaining feature parity with earlier versions of Hashie.
27
+ The library is broken up into a number of atomically includable Hash extension modules as described below. This provides maximum flexibility for users to mix and match functionality while maintaining feature parity with earlier versions of Hashie.
28
28
 
29
29
  Any of the extensions listed below can be mixed into a class by `include`-ing `Hashie::Extensions::ExtensionName`.
30
30
 
@@ -135,11 +135,11 @@ class Tweet < Hash
135
135
  coerce_key :retweeted, ->(v) do
136
136
  case v
137
137
  when String
138
- return !!(v =~ /^(true|t|yes|y|1)$/i)
138
+ !!(v =~ /\A(true|t|yes|y|1)\z/i)
139
139
  when Numeric
140
- return !v.to_i.zero?
140
+ !v.to_i.zero?
141
141
  else
142
- return v == true
142
+ v == true
143
143
  end
144
144
  end
145
145
  end
@@ -237,9 +237,30 @@ overriding.__zip #=> [[['zip', 'a-dee-doo-dah']]]
237
237
 
238
238
  ### IndifferentAccess
239
239
 
240
- This extension can be mixed in to instantly give you indifferent access to your Hash subclass. This works just like the params hash in Rails and other frameworks where whether you provide symbols or strings to access keys, you will get the same results.
240
+ This extension can be mixed in to your Hash subclass to allow you to use Strings or Symbols interchangeably as keys; similar to the `params` hash in Rails.
241
241
 
242
- A unique feature of Hashie's IndifferentAccess mixin is that it will inject itself recursively into subhashes *without* reinitializing the hash in question. This means you can safely merge together indifferent and non-indifferent hashes arbitrarily deeply without worrying about whether you'll be able to `hash[:other][:another]` properly.
242
+ In addition, IndifferentAccess will also inject itself into sub-hashes so they behave the same.
243
+
244
+ Example:
245
+
246
+ ```ruby
247
+ class MyHash < Hash
248
+ include Hashie::Extensions::MergeInitializer
249
+ include Hashie::Extensions::IndifferentAccess
250
+ end
251
+
252
+ myhash = MyHash.new(:cat => 'meow', 'dog' => 'woof')
253
+ myhash['cat'] # => "meow"
254
+ myhash[:cat] # => "meow"
255
+ myhash[:dog] # => "woof"
256
+ myhash['dog'] # => "woof"
257
+
258
+ # Auto-Injecting into sub-hashes.
259
+ myhash['fishes'] = {}
260
+ myhash['fishes'].class # => Hash
261
+ myhash['fishes'][:food] = 'flakes'
262
+ myhash['fishes']['food'] # => "flakes"
263
+ ```
243
264
 
244
265
  ### IgnoreUndeclared
245
266
 
@@ -1,6 +1,17 @@
1
1
  Upgrading Hashie
2
2
  ================
3
3
 
4
+ ### Upgrading to 3.4.4
5
+
6
+ #### Mash subclasses and reverse_merge
7
+
8
+ ```ruby
9
+ class MyMash < Hashie::Mash
10
+ end
11
+ ```
12
+
13
+ In versions >= 3.4.4 `MyMash#reverse_merge` returns an instance of `MyMash` but in previous versions it was a `Hashie::Mash` instance.
14
+
4
15
  ### Upgrading to 3.2.2
5
16
 
6
17
  #### Testing if key defined
@@ -12,9 +12,9 @@ Gem::Specification.new do |gem|
12
12
 
13
13
  gem.require_paths = ['lib']
14
14
  gem.files = %w(.yardopts CHANGELOG.md CONTRIBUTING.md LICENSE README.md UPGRADING.md Rakefile hashie.gemspec)
15
- gem.files += Dir['lib/**/*.rb']
16
- gem.files += Dir['spec/**/*.rb']
17
- gem.test_files = Dir['spec/**/*.rb']
15
+ gem.files += Dir['lib/**/*.rb']
16
+ gem.files += Dir['spec/**/*.rb']
17
+ gem.test_files = Dir['spec/**/*.rb']
18
18
 
19
19
  gem.add_development_dependency 'rake'
20
20
  gem.add_development_dependency 'rspec', '~> 3.0'
@@ -54,7 +54,7 @@ module Hashie
54
54
  case args.length
55
55
  when 1
56
56
  val = args.first
57
- val = self[key].merge(val) if self[key].is_a?(::Hash) && val.is_a?(::Hash)
57
+ val = self.class.new(self[key]).merge(val) if self[key].is_a?(::Hash) && val.is_a?(::Hash)
58
58
  else
59
59
  val = args
60
60
  end
@@ -64,22 +64,23 @@ module Hashie
64
64
  end
65
65
 
66
66
  def method_missing(name, *args) #:nodoc:
67
- name = name.to_s
68
- if name.match(/!$/) && args.empty?
67
+ if args.empty? && name.to_s.end_with?('!')
69
68
  key = name[0...-1].to_sym
70
69
 
71
- if self[key].nil?
72
- self[key] = Clash.new({}, self)
73
- elsif self[key].is_a?(::Hash) && !self[key].is_a?(Clash)
74
- self[key] = Clash.new(self[key], self)
70
+ case self[key]
71
+ when NilClass
72
+ self[key] = self.class.new({}, self)
73
+ when Clash
74
+ self[key]
75
+ when Hash
76
+ self[key] = self.class.new(self[key], self)
75
77
  else
76
78
  fail ChainError, 'Tried to chain into a non-hash key.'
77
79
  end
78
-
79
- self[key]
80
80
  elsif args.any?
81
- key = name.to_sym
82
- merge_store(key, *args)
81
+ merge_store(name, *args)
82
+ else
83
+ super
83
84
  end
84
85
  end
85
86
  end
@@ -111,7 +111,7 @@ module Hashie
111
111
  options = { strict: true }.merge(options)
112
112
 
113
113
  if ABSTRACT_CORE_TYPES.key? from
114
- ABSTRACT_CORE_TYPES[from].each do | type |
114
+ ABSTRACT_CORE_TYPES[from].each do |type|
115
115
  coerce_value type, into, options
116
116
  end
117
117
  end
@@ -130,6 +130,7 @@ module Hashie
130
130
  def strict_value_coercions
131
131
  @strict_value_coercions ||= {}
132
132
  end
133
+
133
134
  # Return all value coercions that have the :strict rule as false.
134
135
  def lenient_value_coercions
135
136
  @lenient_value_coercions ||= {}
@@ -158,7 +159,8 @@ module Hashie
158
159
  type, key_type, value_type = type.class, *type.first
159
160
  build_hash_coercion(type, key_type, value_type)
160
161
  else # Enumerable but not Hash: Array, Set
161
- type, value_type = type.class, type.first
162
+ value_type = type.first
163
+ type = type.class
162
164
  build_container_coercion(type, value_type)
163
165
  end
164
166
  elsif CORE_TYPES.key? type
@@ -17,12 +17,7 @@ module Hashie
17
17
  # Hashie::Extensions::DeepLocate.deep_locate -> (key, value, object) { key == :title }, books
18
18
  # # => [{:title=>"Ruby for beginners", :pages=>120}, ...]
19
19
  def self.deep_locate(comparator, object)
20
- # ensure comparator is a callable
21
- unless comparator.respond_to?(:call)
22
- comparator = lambda do |non_callable_object|
23
- ->(key, _, _) { key == non_callable_object }
24
- end.call(comparator)
25
- end
20
+ comparator = _construct_key_comparator(comparator, object) unless comparator.respond_to?(:call)
26
21
 
27
22
  _deep_locate(comparator, object)
28
23
  end
@@ -68,17 +63,18 @@ module Hashie
68
63
 
69
64
  private
70
65
 
66
+ def self._construct_key_comparator(search_key, object)
67
+ search_key = search_key.to_s if defined?(::ActiveSupport) && object.is_a?(::ActiveSupport::HashWithIndifferentAccess)
68
+ search_key = search_key.to_s if object.respond_to?(:indifferent_access?) && object.indifferent_access?
69
+
70
+ lambda do |non_callable_object|
71
+ ->(key, _, _) { key == non_callable_object }
72
+ end.call(search_key)
73
+ end
74
+
71
75
  def self._deep_locate(comparator, object, result = [])
72
76
  if object.is_a?(::Enumerable)
73
- if object.any? do |value|
74
- if object.is_a?(::Hash)
75
- key, value = value
76
- else
77
- key = nil
78
- end
79
-
80
- comparator.call(key, value, object)
81
- end
77
+ if object.any? { |value| _match_comparator?(value, comparator, object) }
82
78
  result.push object
83
79
  else
84
80
  (object.respond_to?(:values) ? object.values : object.entries).each do |value|
@@ -89,6 +85,16 @@ module Hashie
89
85
 
90
86
  result
91
87
  end
88
+
89
+ def self._match_comparator?(value, comparator, object)
90
+ if object.is_a?(::Hash)
91
+ key, value = value
92
+ else
93
+ key = nil
94
+ end
95
+
96
+ comparator.call(key, value, object)
97
+ end
92
98
  end
93
99
  end
94
100
  end
@@ -30,10 +30,13 @@ module Hashie
30
30
  # p.email # => NoMethodError
31
31
  module IgnoreUndeclared
32
32
  def initialize_attributes(attributes)
33
+ return unless attributes
34
+ klass = self.class
35
+ translations = klass.respond_to?(:translations) && klass.translations
33
36
  attributes.each_pair do |att, value|
34
- next unless self.class.property?(att) || (self.class.respond_to?(:translations) && self.class.translations.include?(att.to_sym))
37
+ next unless klass.property?(att) || (translations && translations.include?(att))
35
38
  self[att] = value
36
- end if attributes
39
+ end
37
40
  end
38
41
 
39
42
  def property_exists?(property)
@@ -133,6 +133,14 @@ module Hashie
133
133
  self
134
134
  end
135
135
 
136
+ def merge(*)
137
+ super.convert!
138
+ end
139
+
140
+ def merge!(*)
141
+ super.convert!
142
+ end
143
+
136
144
  protected
137
145
 
138
146
  def hash_lacking_indifference?(other)
@@ -107,16 +107,41 @@ module Hashie
107
107
  # h.hji? # => NoMethodError
108
108
  module MethodQuery
109
109
  def respond_to?(name, include_private = false)
110
- return true if name.to_s =~ /(.*)\?$/ && (key?(Regexp.last_match[1]) || key?(Regexp.last_match[1].to_sym))
111
- super
110
+ if query_method?(name) && indifferent_key?(key_from_query_method(name))
111
+ true
112
+ else
113
+ super
114
+ end
112
115
  end
113
116
 
114
117
  def method_missing(name, *args)
115
- if args.empty? && name.to_s =~ /(.*)\?$/ && (key?(Regexp.last_match[1]) || key?(Regexp.last_match[1].to_sym))
116
- return self[Regexp.last_match[1]] || self[Regexp.last_match[1].to_sym]
118
+ return super unless args.empty?
119
+
120
+ if query_method?(name)
121
+ key = key_from_query_method(name)
122
+ if indifferent_key?(key)
123
+ !!(self[key] || self[key.to_sym])
124
+ else
125
+ super
126
+ end
127
+ else
128
+ super
117
129
  end
130
+ end
118
131
 
119
- super
132
+ private
133
+
134
+ def indifferent_key?(name)
135
+ name = name.to_s
136
+ key?(name) || key?(name.to_sym)
137
+ end
138
+
139
+ def key_from_query_method(query_method)
140
+ query_method.to_s[0..-2]
141
+ end
142
+
143
+ def query_method?(name)
144
+ name.to_s.end_with?('?')
120
145
  end
121
146
  end
122
147
 
@@ -247,7 +247,13 @@ module Hashie
247
247
 
248
248
  # another ActiveSupport method, see issue #270
249
249
  def reverse_merge(other_hash)
250
- Hashie::Mash.new(other_hash).merge(self)
250
+ self.class.new(other_hash).merge(self)
251
+ end
252
+
253
+ if RUBY_VERSION >= '2.3.0'
254
+ def dig(*keys)
255
+ super(*keys.map { |key| convert_key(key) })
256
+ end
251
257
  end
252
258
 
253
259
  protected
@@ -1,3 +1,3 @@
1
1
  module Hashie
2
- VERSION = '3.4.3'
2
+ VERSION = '3.4.4'
3
3
  end
@@ -1,8 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Hashie::Clash do
4
- subject { Hashie::Clash.new }
5
-
6
4
  it 'is able to set an attribute via method_missing' do
7
5
  subject.foo('bar')
8
6
  expect(subject[:foo]).to eq 'bar'
@@ -45,4 +43,28 @@ describe Hashie::Clash do
45
43
  expect(subject[:foo]).to be_nil
46
44
  expect(subject[:hello]).to be_nil
47
45
  end
46
+
47
+ it 'merges multiple bang notation calls' do
48
+ subject.where!.foo(123)
49
+ subject.where!.bar(321)
50
+ expect(subject).to eq(where: { foo: 123, bar: 321 })
51
+ end
52
+
53
+ it 'raises an exception when method is missing' do
54
+ expect { subject.boo }.to raise_error(NoMethodError)
55
+ end
56
+
57
+ describe 'when inherited' do
58
+ subject { Class.new(described_class).new }
59
+
60
+ it 'bang nodes are instances of a subclass' do
61
+ subject.where!.foo(123)
62
+ expect(subject[:where]).to be_instance_of(subject.class)
63
+ end
64
+
65
+ it 'merged nodes are instances of a subclass' do
66
+ subject.where(abc: 'def').where(hgi: 123)
67
+ expect(subject[:where]).to be_instance_of(subject.class)
68
+ end
69
+ end
48
70
  end
@@ -511,3 +511,26 @@ context 'Dynamic Dash Class' do
511
511
  expect(my_property).to eq(my_orig)
512
512
  end
513
513
  end
514
+
515
+ context 'with method access' do
516
+ class DashWithMethodAccess < Hashie::Dash
517
+ include Hashie::Extensions::IndifferentAccess
518
+ include Hashie::Extensions::MethodQuery
519
+
520
+ property :test
521
+ end
522
+
523
+ subject(:dash) { DashWithMethodAccess.new(test: 'value') }
524
+
525
+ describe '#test' do
526
+ subject { dash.test }
527
+
528
+ it { is_expected.to eq('value') }
529
+ end
530
+
531
+ describe '#test?' do
532
+ subject { dash.test? }
533
+
534
+ it { is_expected.to eq true }
535
+ end
536
+ end
@@ -87,7 +87,7 @@ describe Hashie::Extensions::Coercion do
87
87
  ]
88
88
  expect(instance[:nested_list]).to be_a Array
89
89
  expect(instance[:nested_list].size).to eq(3)
90
- instance[:nested_list].each do | nested |
90
+ instance[:nested_list].each do |nested|
91
91
  test_nested_object nested
92
92
  end
93
93
  end
@@ -100,7 +100,7 @@ describe Hashie::Extensions::Coercion do
100
100
  }
101
101
  expect(instance[:nested_hash]).to be_a Hash
102
102
  expect(instance[:nested_hash].size).to eq(3)
103
- instance[:nested_hash].each do | key, nested |
103
+ instance[:nested_hash].each do |key, nested|
104
104
  expect(key).to be_a(String)
105
105
  test_nested_object nested
106
106
  end
@@ -251,9 +251,9 @@ describe Hashie::Extensions::Coercion do
251
251
  xyz: 987
252
252
  }
253
253
  expect(instance[:foo]).to eq(
254
- 'abc' => '123',
255
- 'xyz' => '987'
256
- )
254
+ 'abc' => '123',
255
+ 'xyz' => '987'
256
+ )
257
257
  end
258
258
 
259
259
  it 'can coerce via a proc' do
@@ -571,7 +571,7 @@ describe Hashie::Extensions::Coercion do
571
571
  float: 2.7,
572
572
  rational: Rational(2, 3),
573
573
  complex: Complex(1)
574
- }.each do | k, v |
574
+ }.each do |k, v|
575
575
  instance[k] = v
576
576
  if v.is_a? Integer
577
577
  expect(instance[k]).to be_a(String)
@@ -592,7 +592,7 @@ describe Hashie::Extensions::Coercion do
592
592
  float: 2.7,
593
593
  rational: Rational(2, 3),
594
594
  complex: Complex(1)
595
- }.each do | k, v |
595
+ }.each do |k, v|
596
596
  instance[k] = v
597
597
  expect(instance[k]).to be_a(String)
598
598
  expect(instance[k]).to eq(v.to_s)
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'active_support/core_ext/hash/indifferent_access'
2
3
 
3
4
  describe Hashie::Extensions::DeepFind do
4
5
  subject { Class.new(Hash) { include Hashie::Extensions::DeepFind } }
@@ -42,4 +43,71 @@ describe Hashie::Extensions::DeepFind do
42
43
  expect(instance.deep_find_all(:wahoo)).to be_nil
43
44
  end
44
45
  end
46
+
47
+ context 'on an ActiveSupport::HashWithIndifferentAccess' do
48
+ subject(:instance) { hash.with_indifferent_access.extend(Hashie::Extensions::DeepFind) }
49
+
50
+ describe '#deep_find' do
51
+ it 'indifferently detects a value from a nested hash' do
52
+ expect(instance.deep_find(:address)).to eq('123 Library St.')
53
+ expect(instance.deep_find('address')).to eq('123 Library St.')
54
+ end
55
+
56
+ it 'indifferently detects a value from a nested array' do
57
+ expect(instance.deep_find(:title)).to eq('Call of the Wild')
58
+ expect(instance.deep_find('title')).to eq('Call of the Wild')
59
+ end
60
+
61
+ it 'indifferently returns nil if it does not find a match' do
62
+ expect(instance.deep_find(:wahoo)).to be_nil
63
+ expect(instance.deep_find('wahoo')).to be_nil
64
+ end
65
+ end
66
+
67
+ describe '#deep_find_all' do
68
+ it 'indifferently detects all values from a nested hash' do
69
+ expect(instance.deep_find_all(:title)).to eq(['Call of the Wild', 'Moby Dick', 'Main Library'])
70
+ expect(instance.deep_find_all('title')).to eq(['Call of the Wild', 'Moby Dick', 'Main Library'])
71
+ end
72
+
73
+ it 'indifferently returns nil if it does not find any matches' do
74
+ expect(instance.deep_find_all(:wahoo)).to be_nil
75
+ expect(instance.deep_find_all('wahoo')).to be_nil
76
+ end
77
+ end
78
+ end
79
+
80
+ context 'on a Hash including Hashie::Extensions::IndifferentAccess' do
81
+ let(:klass) { Class.new(Hash) { include Hashie::Extensions::IndifferentAccess } }
82
+ subject(:instance) { klass[hash.dup].extend(Hashie::Extensions::DeepFind) }
83
+
84
+ describe '#deep_find' do
85
+ it 'indifferently detects a value from a nested hash' do
86
+ expect(instance.deep_find(:address)).to eq('123 Library St.')
87
+ expect(instance.deep_find('address')).to eq('123 Library St.')
88
+ end
89
+
90
+ it 'indifferently detects a value from a nested array' do
91
+ expect(instance.deep_find(:title)).to eq('Call of the Wild')
92
+ expect(instance.deep_find('title')).to eq('Call of the Wild')
93
+ end
94
+
95
+ it 'indifferently returns nil if it does not find a match' do
96
+ expect(instance.deep_find(:wahoo)).to be_nil
97
+ expect(instance.deep_find('wahoo')).to be_nil
98
+ end
99
+ end
100
+
101
+ describe '#deep_find_all' do
102
+ it 'indifferently detects all values from a nested hash' do
103
+ expect(instance.deep_find_all(:title)).to eq(['Call of the Wild', 'Moby Dick', 'Main Library'])
104
+ expect(instance.deep_find_all('title')).to eq(['Call of the Wild', 'Moby Dick', 'Main Library'])
105
+ end
106
+
107
+ it 'indifferently returns nil if it does not find any matches' do
108
+ expect(instance.deep_find_all(:wahoo)).to be_nil
109
+ expect(instance.deep_find_all('wahoo')).to be_nil
110
+ end
111
+ end
112
+ end
45
113
  end
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'active_support/core_ext/hash/indifferent_access'
2
3
 
3
4
  describe Hashie::Extensions::DeepLocate do
4
5
  let(:hash) do
@@ -121,4 +122,16 @@ describe Hashie::Extensions::DeepLocate do
121
122
  expect(instance.deep_locate(:bool)).to eq([hash[:query]])
122
123
  end
123
124
  end
125
+
126
+ context 'on an ActiveSupport::HashWithIndifferentAccess' do
127
+ let(:instance) { hash.dup.with_indifferent_access }
128
+
129
+ it 'can locate symbolic keys' do
130
+ expect(described_class.deep_locate(:lsr10, instance)).to eq ['lsr10' => { 'gte' => 2014 }]
131
+ end
132
+
133
+ it 'can locate string keys' do
134
+ expect(described_class.deep_locate('lsr10', instance)).to eq ['lsr10' => { 'gte' => 2014 }]
135
+ end
136
+ end
124
137
  end
@@ -6,6 +6,7 @@ describe Hashie::Extensions::IgnoreUndeclared do
6
6
  include Hashie::Extensions::IgnoreUndeclared
7
7
  property :city
8
8
  property :state, from: :provence
9
+ property :str_state, from: 'str_provence'
9
10
  end
10
11
 
11
12
  subject { ForgivingTrash }
@@ -19,7 +20,7 @@ describe Hashie::Extensions::IgnoreUndeclared do
19
20
  end
20
21
 
21
22
  it 'works with translated properties (with string keys)' do
22
- expect(subject.new(provence: 'Ontario').state).to eq('Ontario')
23
+ expect(subject.new('str_provence' => 'Ontario').str_state).to eq('Ontario')
23
24
  end
24
25
 
25
26
  it 'requires properties to be declared on assignment' do
@@ -31,6 +31,32 @@ describe Hashie::Extensions::IndifferentAccess do
31
31
  property :foo
32
32
  end
33
33
 
34
+ describe '#merge' do
35
+ it 'indifferently merges in a hash' do
36
+ indifferent_hash = Class.new(::Hash) do
37
+ include Hashie::Extensions::IndifferentAccess
38
+ end.new
39
+
40
+ merged_hash = indifferent_hash.merge(:cat => 'meow')
41
+
42
+ expect(merged_hash[:cat]).to eq('meow')
43
+ expect(merged_hash['cat']).to eq('meow')
44
+ end
45
+ end
46
+
47
+ describe '#merge!' do
48
+ it 'indifferently merges in a hash' do
49
+ indifferent_hash = Class.new(::Hash) do
50
+ include Hashie::Extensions::IndifferentAccess
51
+ end.new
52
+
53
+ indifferent_hash.merge!(:cat => 'meow')
54
+
55
+ expect(indifferent_hash[:cat]).to eq('meow')
56
+ expect(indifferent_hash['cat']).to eq('meow')
57
+ end
58
+ end
59
+
34
60
  describe 'when included in dash' do
35
61
  let(:params) { { foo: 'bar' } }
36
62
  subject { IndifferentHashWithDash.new(params) }
@@ -54,13 +80,13 @@ describe Hashie::Extensions::IndifferentAccess do
54
80
  end
55
81
 
56
82
  it 'returns the same instance of the hash that was set' do
57
- hash = Hash.new
83
+ hash = {}
58
84
  h = subject.build(foo: hash)
59
85
  expect(h.values_at(:foo)[0]).to be(hash)
60
86
  end
61
87
 
62
88
  it 'returns the same instance of the array that was set' do
63
- array = Array.new
89
+ array = []
64
90
  h = subject.build(foo: array)
65
91
  expect(h.values_at(:foo)[0]).to be(array)
66
92
  end
@@ -86,13 +112,13 @@ describe Hashie::Extensions::IndifferentAccess do
86
112
  end
87
113
 
88
114
  it 'returns the same instance of the hash that was set' do
89
- hash = Hash.new
115
+ hash = {}
90
116
  h = subject.build(foo: hash)
91
117
  expect(h.fetch(:foo)).to be(hash)
92
118
  end
93
119
 
94
120
  it 'returns the same instance of the array that was set' do
95
- array = Array.new
121
+ array = []
96
122
  h = subject.build(foo: array)
97
123
  expect(h.fetch(:foo)).to be(array)
98
124
  end
@@ -156,7 +182,7 @@ describe Hashie::Extensions::IndifferentAccess do
156
182
 
157
183
  it 'does not change the ancestors of the injected object class' do
158
184
  h.update(baz: { qux: 'abc' })
159
- expect(Hash.new).not_to be_respond_to(:indifferent_access?)
185
+ expect({}).not_to be_respond_to(:indifferent_access?)
160
186
  end
161
187
  end
162
188
 
@@ -118,7 +118,7 @@ describe Hashie::Extensions::IndifferentAccess do
118
118
 
119
119
  it 'does not change the ancestors of the injected object class' do
120
120
  h.update(baz: { qux: 'abc' })
121
- expect(Hash.new).not_to be_respond_to(:indifferent_access?)
121
+ expect({}).not_to be_respond_to(:indifferent_access?)
122
122
  end
123
123
  end
124
124
 
@@ -92,15 +92,19 @@ describe Hashie::Extensions::MethodQuery do
92
92
  subject { QueryHash }
93
93
 
94
94
  it 'is true for non-nil string key values' do
95
- expect(subject.new('abc' => 123)).to be_abc
95
+ expect(subject.new('abc' => 123).abc?).to eq true
96
96
  end
97
97
 
98
98
  it 'is true for non-nil symbol key values' do
99
- expect(subject.new(abc: 123)).to be_abc
99
+ expect(subject.new(abc: 123).abc?).to eq true
100
+ end
101
+
102
+ it 'is false for false key values' do
103
+ expect(subject.new(abc: false).abc?).to eq false
100
104
  end
101
105
 
102
106
  it 'is false for nil key values' do
103
- expect(subject.new(abc: false)).not_to be_abc
107
+ expect(subject.new(abc: nil).abc?).to eq false
104
108
  end
105
109
 
106
110
  it 'raises a NoMethodError for non-set keys' do
@@ -8,21 +8,21 @@ describe Hash do
8
8
  end
9
9
 
10
10
  it '#stringify_keys! turns all keys into strings' do
11
- hash = Hashie::Hash[:a => 'hey', 123 => 'bob']
11
+ hash = Hashie::Hash[a: 'hey', 123 => 'bob']
12
12
  hash.stringify_keys!
13
13
  expect(hash).to eq Hashie::Hash['a' => 'hey', '123' => 'bob']
14
14
  end
15
15
 
16
16
  it '#stringify_keys! turns all keys into strings recursively' do
17
- hash = Hashie::Hash[:a => 'hey', 123 => { 345 => 'hey' }]
17
+ hash = Hashie::Hash[a: 'hey', 123 => { 345 => 'hey' }]
18
18
  hash.stringify_keys!
19
19
  expect(hash).to eq Hashie::Hash['a' => 'hey', '123' => { '345' => 'hey' }]
20
20
  end
21
21
 
22
22
  it '#stringify_keys returns a hash with stringified keys' do
23
- hash = Hashie::Hash[:a => 'hey', 123 => 'bob']
23
+ hash = Hashie::Hash[a: 'hey', 123 => 'bob']
24
24
  stringified_hash = hash.stringify_keys
25
- expect(hash).to eq Hashie::Hash[:a => 'hey', 123 => 'bob']
25
+ expect(hash).to eq Hashie::Hash[a: 'hey', 123 => 'bob']
26
26
  expect(stringified_hash).to eq Hashie::Hash['a' => 'hey', '123' => 'bob']
27
27
  end
28
28
 
@@ -41,7 +41,7 @@ describe Hash do
41
41
  it '#to_hash with symbolize_keys set to true returns a hash with symbolized keys' do
42
42
  hash = Hashie::Hash['a' => 'hey', 123 => 'bob', 'array' => [1, 2, 3]]
43
43
  symbolized_hash = hash.to_hash(symbolize_keys: true)
44
- expect(symbolized_hash).to eq(:a => 'hey', :"123" => 'bob', :array => [1, 2, 3])
44
+ expect(symbolized_hash).to eq(a: 'hey', :"123" => 'bob', array: [1, 2, 3])
45
45
  end
46
46
 
47
47
  it "#to_hash should not blow up when #to_hash doesn't accept arguments" do
@@ -78,7 +78,7 @@ describe Hash do
78
78
  it '#to_hash with symbolize_keys set to true returns a hash with symbolized keys' do
79
79
  hash = Hashie::Hash['a' => 'hey', 123 => 'bob', 'array' => [1, 2, 3], subhash: ClassRespondsToHash.new]
80
80
  symbolized_hash = hash.to_hash(symbolize_keys: true)
81
- expect(symbolized_hash).to eq(:a => 'hey', :"123" => 'bob', :array => [1, 2, 3], subhash: { :a => 'hey', :b => 'bar', :'123' => 'bob', :array => [1, 2, 3] })
81
+ expect(symbolized_hash).to eq(a: 'hey', :"123" => 'bob', array: [1, 2, 3], subhash: { a: 'hey', b: 'bar', :'123' => 'bob', array: [1, 2, 3] })
82
82
  end
83
83
  end
84
84
  end
@@ -676,5 +676,25 @@ describe Hashie::Mash do
676
676
  it 'does not overwrite values' do
677
677
  expect(subject.reverse_merge(a: 5).a).to eq subject.a
678
678
  end
679
+
680
+ context 'when using with subclass' do
681
+ let(:subclass) { Class.new(Hashie::Mash) }
682
+ subject { subclass.new(a: 1) }
683
+
684
+ it 'creates an instance of subclass' do
685
+ expect(subject.reverse_merge(a: 5)).to be_kind_of(subclass)
686
+ end
687
+ end
688
+ end
689
+
690
+ if RUBY_VERSION >= '2.3.0'
691
+ describe '#dig' do
692
+ subject { described_class.new(a: { b: 1 }) }
693
+
694
+ it 'accepts both string and symbol as key' do
695
+ expect(subject.dig(:a, :b)).to eq(1)
696
+ expect(subject.dig('a', 'b')).to eq(1)
697
+ end
698
+ end
679
699
  end
680
700
  end
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.3
4
+ version: 3.4.4
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: 2015-10-25 00:00:00.000000000 Z
12
+ date: 2016-04-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -144,7 +144,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
144
144
  version: '0'
145
145
  requirements: []
146
146
  rubyforge_project:
147
- rubygems_version: 2.4.8
147
+ rubygems_version: 2.4.6
148
148
  signing_key:
149
149
  specification_version: 4
150
150
  summary: Your friendly neighborhood hash library.