hashie 3.4.0 → 3.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +11 -9
- data/README.md +44 -0
- data/lib/hashie.rb +1 -0
- data/lib/hashie/extensions/coercion.rb +1 -1
- data/lib/hashie/extensions/deep_find.rb +4 -21
- data/lib/hashie/extensions/deep_locate.rb +94 -0
- data/lib/hashie/extensions/indifferent_access.rb +4 -4
- data/lib/hashie/mash.rb +5 -0
- data/lib/hashie/version.rb +1 -1
- data/spec/hashie/extensions/coercion_spec.rb +21 -3
- data/spec/hashie/extensions/deep_locate_spec.rb +124 -0
- data/spec/hashie/extensions/indifferent_access_with_rails_hwia_spec.rb +13 -1
- data/spec/hashie/mash_spec.rb +13 -0
- metadata +15 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: baf45b7b9cc1092c508f33cb545eb5abeb80fbb1
|
4
|
+
data.tar.gz: a4ec3c9ca8c979fdaf484ecdcf3afc61c7f024ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0fccd3accf920a79b1f0085cf12a3d6c6b972338b153c296af295f5462fa56a15e18b5a0bebd950861a26fac4160e60b830ca66c15edcfcd1a7717b426c8c4c3
|
7
|
+
data.tar.gz: a68c79809154aeab6320943e7239a441ca62f328936e774b5b4219c9a68764481f4251a91586a4d88764ed6b23b41870d58dc1ca33b52003bff559aa0f319965
|
data/CHANGELOG.md
CHANGED
@@ -1,22 +1,24 @@
|
|
1
|
-
##
|
1
|
+
## 3.4.1
|
2
2
|
|
3
|
-
*
|
3
|
+
* [#269](https://github.com/intridea/hashie/pull/272): Added Hashie::Extensions::DeepLocate - [@msievers](https://github.com/msievers).
|
4
|
+
* [#270](https://github.com/intridea/hashie/pull/277): Fixed ArgumentError raised when using IndifferentAccess and HashWithIndifferentAccess - [@gardenofwine](https://github.com/gardenofwine).
|
5
|
+
* [#281](https://github.com/intridea/hashie/pull/281): Added #reverse_merge to Mash to override ActiveSupport's version - [@mgold](https://github.com/mgold).
|
6
|
+
* [#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).
|
4
7
|
|
5
|
-
## 3.4.0 (02/02/
|
8
|
+
## 3.4.0 (02/02/2015)
|
6
9
|
|
7
10
|
* [#271](https://github.com/intridea/hashie/pull/271): Added ability to define defaults based on current hash - [@gregory](https://github.com/gregory).
|
8
11
|
* [#247](https://github.com/intridea/hashie/pull/247): Fixed #stringify_keys and #symbolize_keys collision with ActiveSupport - [@bartoszkopinski](https://github.com/bartoszkopinski).
|
9
12
|
* [#249](https://github.com/intridea/hashie/pull/249): SafeAssignment will now also protect hash-style assignments - [@jrochkind](https://github.com/jrochkind).
|
10
13
|
* [#251](https://github.com/intridea/hashie/pull/251): Added block support to indifferent access #fetch - [@jgraichen](https://github.com/jgraichen).
|
11
|
-
* [#252](https://github.com/
|
12
|
-
* [#256](https://github.com/
|
13
|
-
* [#259](https://github.com/
|
14
|
-
* [#260](https://github.com/
|
14
|
+
* [#252](https://github.com/intridea/hashie/pull/252): Added support for conditionally required Hashie::Dash attributes - [@ccashwell](https://github.com/ccashwell).
|
15
|
+
* [#256](https://github.com/intridea/hashie/pull/256): Inherit key coercions - [@Erol](https://github.com/Erol).
|
16
|
+
* [#259](https://github.com/intridea/hashie/pull/259): Fixed handling of default proc values in Mash - [@Erol](https://github.com/Erol).
|
17
|
+
* [#260](https://github.com/intridea/hashie/pull/260): Added block support to Extensions::DeepMerge - [@galathius](https://github.com/galathius).
|
15
18
|
* [#254](https://github.com/intridea/hashie/pull/254): Added public utility methods for stringify and symbolize keys - [@maxlinc](https://github.com/maxlinc).
|
16
|
-
* [#261](https://github.com/intridea/hashie/pull/261): Fixed bug where Dash.property modifies argument object - [@
|
19
|
+
* [#261](https://github.com/intridea/hashie/pull/261): Fixed bug where Dash.property modifies argument object - [@d-tw](https://github.com/d-tw).
|
17
20
|
* [#264](https://github.com/intridea/hashie/pull/264): Methods such as abc? return true/false with Hashie::Extensions::MethodReader - [@Zloy](https://github.com/Zloy).
|
18
21
|
* [#269](https://github.com/intridea/hashie/pull/269): Add #extractable_options? so ActiveSupport Array#extract_options! can extract it - [@ridiculous](https://github.com/ridiculous).
|
19
|
-
* Your contribution here.
|
20
22
|
|
21
23
|
## 3.3.2 (11/26/2014)
|
22
24
|
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Hashie
|
2
2
|
|
3
|
+
[![Join the chat at https://gitter.im/intridea/hashie](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/intridea/hashie?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
4
|
+
|
3
5
|
[![Gem Version](http://img.shields.io/gem/v/hashie.svg)](http://badge.fury.io/rb/hashie)
|
4
6
|
[![Build Status](http://img.shields.io/travis/intridea/hashie.svg)](https://travis-ci.org/intridea/hashie)
|
5
7
|
[![Dependency Status](https://gemnasium.com/intridea/hashie.svg)](https://gemnasium.com/intridea/hashie)
|
@@ -313,6 +315,48 @@ user.deep_find_all(:name) #=> [{ first: 'Bob', last: 'Boberts' }, 'Rubyists', 'O
|
|
313
315
|
user.deep_select(:name) #=> [{ first: 'Bob', last: 'Boberts' }, 'Rubyists', 'Open source enthusiasts']
|
314
316
|
```
|
315
317
|
|
318
|
+
### DeepLocate
|
319
|
+
|
320
|
+
This extension can be mixed in to provide a depth first search based search for enumerables matching a given comparator callable.
|
321
|
+
|
322
|
+
It returns all enumerables which contain at least one element, for which the given comparator returns ```true```.
|
323
|
+
|
324
|
+
Because the container objects are returned, the result elements can be modified in place. This way, one can perform modifications on deeply nested hashes without the need to know the exact paths.
|
325
|
+
|
326
|
+
```ruby
|
327
|
+
|
328
|
+
books = [
|
329
|
+
{
|
330
|
+
title: "Ruby for beginners",
|
331
|
+
pages: 120
|
332
|
+
},
|
333
|
+
{
|
334
|
+
title: "CSS for intermediates",
|
335
|
+
pages: 80
|
336
|
+
},
|
337
|
+
{
|
338
|
+
title: "Collection of ruby books",
|
339
|
+
books: [
|
340
|
+
{
|
341
|
+
title: "Ruby for the rest of us",
|
342
|
+
pages: 576
|
343
|
+
}
|
344
|
+
]
|
345
|
+
}
|
346
|
+
]
|
347
|
+
|
348
|
+
books.extend(Hashie::Extensions::DeepLocate)
|
349
|
+
|
350
|
+
# for ruby 1.9 leave *no* space between the lambda rocket and the braces
|
351
|
+
# http://ruby-journal.com/becareful-with-space-in-lambda-hash-rocket-syntax-between-ruby-1-dot-9-and-2-dot-0/
|
352
|
+
|
353
|
+
books.deep_locate -> (key, value, object) { key == :title && value.include?("Ruby") }
|
354
|
+
# => [{:title=>"Ruby for beginners", :pages=>120}, {:title=>"Ruby for the rest of us", :pages=>576}]
|
355
|
+
|
356
|
+
books.deep_locate -> (key, value, object) { key == :pages && value <= 120 }
|
357
|
+
# => [{:title=>"Ruby for beginners", :pages=>120}, {:title=>"CSS for intermediates", :pages=>80}]
|
358
|
+
```
|
359
|
+
|
316
360
|
## Mash
|
317
361
|
|
318
362
|
Mash is an extended Hash that gives simple pseudo-object functionality that can be built from hashes and easily extended. It is intended to give the user easier access to the objects within the Mash through a property-like syntax, while still retaining all Hash functionality.
|
data/lib/hashie.rb
CHANGED
@@ -22,6 +22,7 @@ module Hashie
|
|
22
22
|
autoload :SymbolizeKeys, 'hashie/extensions/symbolize_keys'
|
23
23
|
autoload :DeepFetch, 'hashie/extensions/deep_fetch'
|
24
24
|
autoload :DeepFind, 'hashie/extensions/deep_find'
|
25
|
+
autoload :DeepLocate, 'hashie/extensions/deep_locate'
|
25
26
|
autoload :PrettyInspect, 'hashie/extensions/pretty_inspect'
|
26
27
|
autoload :KeyConversion, 'hashie/extensions/key_conversion'
|
27
28
|
autoload :MethodAccessWithOverride, 'hashie/extensions/method_access'
|
@@ -27,32 +27,15 @@ module Hashie
|
|
27
27
|
private
|
28
28
|
|
29
29
|
def _deep_find(key, object = self)
|
30
|
-
|
31
|
-
return object[key] if object.key?(key)
|
32
|
-
|
33
|
-
reduce_to_match(key, object.values)
|
34
|
-
elsif object.is_a?(Enumerable)
|
35
|
-
reduce_to_match(key, object)
|
36
|
-
end
|
30
|
+
_deep_find_all(key, object).first
|
37
31
|
end
|
38
32
|
|
39
33
|
def _deep_find_all(key, object = self, matches = [])
|
40
|
-
|
41
|
-
|
42
|
-
object.values.each { |v| _deep_find_all(key, v, matches) }
|
43
|
-
elsif object.is_a?(Enumerable)
|
44
|
-
object.each { |v| _deep_find_all(key, v, matches) }
|
34
|
+
deep_locate_result = Hashie::Extensions::DeepLocate.deep_locate(key, object).tap do |result|
|
35
|
+
result.map! { |element| element[key] }
|
45
36
|
end
|
46
37
|
|
47
|
-
matches
|
48
|
-
end
|
49
|
-
|
50
|
-
def reduce_to_match(key, enumerable)
|
51
|
-
enumerable.reduce(nil) do |found, value|
|
52
|
-
return found if found
|
53
|
-
|
54
|
-
_deep_find(key, value)
|
55
|
-
end
|
38
|
+
matches.concat(deep_locate_result)
|
56
39
|
end
|
57
40
|
end
|
58
41
|
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module Hashie
|
2
|
+
module Extensions
|
3
|
+
module DeepLocate
|
4
|
+
# The module level implementation of #deep_locate, incase you do not want
|
5
|
+
# to include/extend the base datastructure. For further examples please
|
6
|
+
# see #deep_locate.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# books = [
|
10
|
+
# {
|
11
|
+
# title: "Ruby for beginners",
|
12
|
+
# pages: 120
|
13
|
+
# },
|
14
|
+
# ...
|
15
|
+
# ]
|
16
|
+
#
|
17
|
+
# Hashie::Extensions::DeepLocate.deep_locate -> (key, value, object) { key == :title }, books
|
18
|
+
# # => [{:title=>"Ruby for beginners", :pages=>120}, ...]
|
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
|
26
|
+
|
27
|
+
_deep_locate(comparator, object)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Performs a depth-first search on deeply nested data structures for a
|
31
|
+
# given comparator callable and returns each Enumerable, for which the
|
32
|
+
# callable returns true for at least one the its elements.
|
33
|
+
#
|
34
|
+
# @example
|
35
|
+
# books = [
|
36
|
+
# {
|
37
|
+
# title: "Ruby for beginners",
|
38
|
+
# pages: 120
|
39
|
+
# },
|
40
|
+
# {
|
41
|
+
# title: "CSS for intermediates",
|
42
|
+
# pages: 80
|
43
|
+
# },
|
44
|
+
# {
|
45
|
+
# title: "Collection of ruby books",
|
46
|
+
# books: [
|
47
|
+
# {
|
48
|
+
# title: "Ruby for the rest of us",
|
49
|
+
# pages: 576
|
50
|
+
# }
|
51
|
+
# ]
|
52
|
+
# }
|
53
|
+
# ]
|
54
|
+
#
|
55
|
+
# books.extend(Hashie::Extensions::DeepLocate)
|
56
|
+
#
|
57
|
+
# # for ruby 1.9 leave *no* space between the lambda rocket and the braces
|
58
|
+
# # http://ruby-journal.com/becareful-with-space-in-lambda-hash-rocket-syntax-between-ruby-1-dot-9-and-2-dot-0/
|
59
|
+
#
|
60
|
+
# books.deep_locate -> (key, value, object) { key == :title && value.include?("Ruby") }
|
61
|
+
# # => [{:title=>"Ruby for beginners", :pages=>120}, {:title=>"Ruby for the rest of us", :pages=>576}]
|
62
|
+
#
|
63
|
+
# books.deep_locate -> (key, value, object) { key == :pages && value <= 120 }
|
64
|
+
# # => [{:title=>"Ruby for beginners", :pages=>120}, {:title=>"CSS for intermediates", :pages=>80}]
|
65
|
+
def deep_locate(comparator)
|
66
|
+
Hashie::Extensions::DeepLocate.deep_locate(comparator, self)
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def self._deep_locate(comparator, object, result = [])
|
72
|
+
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
|
82
|
+
result.push object
|
83
|
+
else
|
84
|
+
(object.respond_to?(:values) ? object.values : object.entries).each do |value|
|
85
|
+
_deep_locate(comparator, value, result)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
result
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -76,16 +76,16 @@ module Hashie
|
|
76
76
|
# is injecting itself into member hashes.
|
77
77
|
def convert!
|
78
78
|
keys.each do |k|
|
79
|
-
regular_writer convert_key(k),
|
79
|
+
regular_writer convert_key(k), indifferent_value(regular_delete(k))
|
80
80
|
end
|
81
81
|
self
|
82
82
|
end
|
83
83
|
|
84
|
-
def
|
84
|
+
def indifferent_value(value)
|
85
85
|
if hash_lacking_indifference?(value)
|
86
86
|
IndifferentAccess.inject!(value)
|
87
87
|
elsif value.is_a?(::Array)
|
88
|
-
value.replace(value.map { |e|
|
88
|
+
value.replace(value.map { |e| indifferent_value(e) })
|
89
89
|
else
|
90
90
|
value
|
91
91
|
end
|
@@ -104,7 +104,7 @@ module Hashie
|
|
104
104
|
end
|
105
105
|
|
106
106
|
def indifferent_writer(key, value)
|
107
|
-
regular_writer convert_key(key),
|
107
|
+
regular_writer convert_key(key), indifferent_value(value)
|
108
108
|
end
|
109
109
|
|
110
110
|
def indifferent_fetch(key, *args, &block)
|
data/lib/hashie/mash.rb
CHANGED
data/lib/hashie/version.rb
CHANGED
@@ -47,8 +47,13 @@ describe Hashie::Extensions::Coercion do
|
|
47
47
|
coerce_key :bar, Integer
|
48
48
|
end
|
49
49
|
|
50
|
+
class OtherNestedCoercableHash < BaseCoercableHash
|
51
|
+
coerce_key :foo, Symbol
|
52
|
+
end
|
53
|
+
|
50
54
|
class RootCoercableHash < BaseCoercableHash
|
51
55
|
coerce_key :nested, NestedCoercableHash
|
56
|
+
coerce_key :other, OtherNestedCoercableHash
|
52
57
|
coerce_key :nested_list, Array[NestedCoercableHash]
|
53
58
|
coerce_key :nested_hash, Hash[String => NestedCoercableHash]
|
54
59
|
end
|
@@ -62,6 +67,13 @@ describe Hashie::Extensions::Coercion do
|
|
62
67
|
subject { RootCoercableHash }
|
63
68
|
let(:instance) { subject.new }
|
64
69
|
|
70
|
+
it 'does not add coercions to superclass' do
|
71
|
+
instance[:nested] = { foo: 'bar' }
|
72
|
+
instance[:other] = { foo: 'bar' }
|
73
|
+
expect(instance[:nested][:foo]).to be_a String
|
74
|
+
expect(instance[:other][:foo]).to be_a Symbol
|
75
|
+
end
|
76
|
+
|
65
77
|
it 'coerces nested objects' do
|
66
78
|
instance[:nested] = { foo: 123, bar: '456' }
|
67
79
|
test_nested_object(instance[:nested])
|
@@ -406,17 +418,23 @@ describe Hashie::Extensions::Coercion do
|
|
406
418
|
end
|
407
419
|
|
408
420
|
context 'when subclassing' do
|
409
|
-
class
|
421
|
+
class MyOwnBase < Hash
|
410
422
|
include Hashie::Extensions::Coercion
|
423
|
+
end
|
411
424
|
|
425
|
+
class MyOwnHash < MyOwnBase
|
412
426
|
coerce_key :value, Integer
|
413
427
|
end
|
414
428
|
|
415
|
-
class
|
429
|
+
class MyOwnSubclass < MyOwnHash
|
416
430
|
end
|
417
431
|
|
418
432
|
it 'inherits key coercions' do
|
419
|
-
expect(
|
433
|
+
expect(MyOwnHash.key_coercions).to eql(MyOwnSubclass.key_coercions)
|
434
|
+
end
|
435
|
+
|
436
|
+
it 'the superclass does not accumulate coerced attributes from subclasses' do
|
437
|
+
expect(MyOwnBase.key_coercions).to eq({})
|
420
438
|
end
|
421
439
|
end
|
422
440
|
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Hashie::Extensions::DeepLocate do
|
4
|
+
let(:hash) do
|
5
|
+
{
|
6
|
+
from: 0,
|
7
|
+
size: 25,
|
8
|
+
query: {
|
9
|
+
bool: {
|
10
|
+
must: [
|
11
|
+
{
|
12
|
+
query_string: {
|
13
|
+
query: 'foobar',
|
14
|
+
default_operator: 'AND',
|
15
|
+
fields: [
|
16
|
+
'title^2',
|
17
|
+
'_all'
|
18
|
+
]
|
19
|
+
}
|
20
|
+
},
|
21
|
+
{
|
22
|
+
match: {
|
23
|
+
field_1: 'value_1'
|
24
|
+
}
|
25
|
+
},
|
26
|
+
{
|
27
|
+
range: {
|
28
|
+
lsr09: {
|
29
|
+
gte: 2014
|
30
|
+
}
|
31
|
+
}
|
32
|
+
}
|
33
|
+
],
|
34
|
+
should: [
|
35
|
+
{
|
36
|
+
match: {
|
37
|
+
field_2: 'value_2'
|
38
|
+
}
|
39
|
+
}
|
40
|
+
],
|
41
|
+
must_not: [
|
42
|
+
{
|
43
|
+
range: {
|
44
|
+
lsr10: {
|
45
|
+
gte: 2014
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
]
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '.deep_locate' do
|
56
|
+
context 'if called with a non-callable comparator' do
|
57
|
+
it 'creates a key comparator on-th-fly' do
|
58
|
+
expect(described_class.deep_locate(:lsr10, hash)).to eq([hash[:query][:bool][:must_not][0][:range]])
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'locates enumerables for which the given comparator returns true for at least one element' do
|
63
|
+
examples = [
|
64
|
+
[
|
65
|
+
->(key, _value, _object) { key == :fields },
|
66
|
+
[
|
67
|
+
hash[:query][:bool][:must].first[:query_string]
|
68
|
+
]
|
69
|
+
],
|
70
|
+
[
|
71
|
+
->(_key, value, _object) { value.is_a?(String) && value.include?('value') },
|
72
|
+
[
|
73
|
+
hash[:query][:bool][:must][1][:match],
|
74
|
+
hash[:query][:bool][:should][0][:match]
|
75
|
+
]
|
76
|
+
],
|
77
|
+
[
|
78
|
+
lambda do |_key, _value, object|
|
79
|
+
object.is_a?(Array) &&
|
80
|
+
!object.extend(described_class).deep_locate(:match).empty?
|
81
|
+
end,
|
82
|
+
[
|
83
|
+
hash[:query][:bool][:must],
|
84
|
+
hash[:query][:bool][:should]
|
85
|
+
]
|
86
|
+
]
|
87
|
+
]
|
88
|
+
|
89
|
+
examples.each do |comparator, expected_result|
|
90
|
+
expect(described_class.deep_locate(comparator, hash)).to eq(expected_result)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'returns an empty array if nothing was found' do
|
95
|
+
expect(described_class.deep_locate(:muff, foo: 'bar')).to eq([])
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'if extending an existing object' do
|
100
|
+
let(:extended_hash) do
|
101
|
+
hash.extend(described_class)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'adds #deep_locate' do
|
105
|
+
expect(extended_hash.deep_locate(:bool)).to eq([hash[:query]])
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'if included in a hash' do
|
110
|
+
let(:derived_hash_with_extension_included) do
|
111
|
+
Class.new(Hash) do
|
112
|
+
include Hashie::Extensions::DeepLocate
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
let(:instance) do
|
117
|
+
derived_hash_with_extension_included.new.update(hash)
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'adds #deep_locate' do
|
121
|
+
expect(instance.deep_locate(:bool)).to eq([hash[:query]])
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# This set of tests verifies that Hashie::Extensions::IndifferentAccess works with
|
2
2
|
# ActiveSupport HashWithIndifferentAccess hashes. See #164 and #166 for details.
|
3
3
|
|
4
|
-
require 'spec_helper'
|
5
4
|
require 'active_support/hash_with_indifferent_access'
|
5
|
+
require 'active_support/core_ext/hash'
|
6
|
+
require 'spec_helper'
|
6
7
|
|
7
8
|
describe Hashie::Extensions::IndifferentAccess do
|
8
9
|
class IndifferentHashWithMergeInitializer < Hash
|
@@ -35,6 +36,10 @@ describe Hashie::Extensions::IndifferentAccess do
|
|
35
36
|
include Hashie::Extensions::MergeInitializer
|
36
37
|
end
|
37
38
|
|
39
|
+
class MashWithIndifferentAccess < Hashie::Mash
|
40
|
+
include Hashie::Extensions::IndifferentAccess
|
41
|
+
end
|
42
|
+
|
38
43
|
shared_examples_for 'hash with indifferent access' do
|
39
44
|
it 'is able to access via string or symbol' do
|
40
45
|
indifferent_hash = ActiveSupport::HashWithIndifferentAccess.new(abc: 123)
|
@@ -193,4 +198,11 @@ describe Hashie::Extensions::IndifferentAccess do
|
|
193
198
|
expect(instance[:foo]).to be_a(ActiveSupport::HashWithIndifferentAccess)
|
194
199
|
end
|
195
200
|
end
|
201
|
+
|
202
|
+
describe 'Mash with indifferent access' do
|
203
|
+
it 'is able to be created for a deep nested HashWithIndifferentAccess' do
|
204
|
+
indifferent_hash = ActiveSupport::HashWithIndifferentAccess.new(abc: { def: 123 })
|
205
|
+
MashWithIndifferentAccess.new(indifferent_hash)
|
206
|
+
end
|
207
|
+
end
|
196
208
|
end
|
data/spec/hashie/mash_spec.rb
CHANGED
@@ -651,4 +651,17 @@ describe Hashie::Mash do
|
|
651
651
|
expect(args).to eq [101, 'bar']
|
652
652
|
end
|
653
653
|
end
|
654
|
+
|
655
|
+
describe '#reverse_merge' do
|
656
|
+
subject { described_class.new(a: 1, b: 2) }
|
657
|
+
|
658
|
+
it 'unifies strings and symbols' do
|
659
|
+
expect(subject.reverse_merge(a: 2).length).to eq 2
|
660
|
+
expect(subject.reverse_merge('a' => 2).length).to eq 2
|
661
|
+
end
|
662
|
+
|
663
|
+
it 'does not overwrite values' do
|
664
|
+
expect(subject.reverse_merge(a: 5).a).to eq subject.a
|
665
|
+
end
|
666
|
+
end
|
654
667
|
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.
|
4
|
+
version: 3.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Bleigh
|
@@ -9,34 +9,34 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-03-31 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- -
|
18
|
+
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: '0'
|
21
21
|
type: :development
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- -
|
25
|
+
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '0'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: rspec
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
|
-
- - ~>
|
32
|
+
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
34
|
version: '3.0'
|
35
35
|
type: :development
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
|
-
- - ~>
|
39
|
+
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '3.0'
|
42
42
|
description: Hashie is a collection of classes and mixins that make hashes more powerful.
|
@@ -47,20 +47,22 @@ executables: []
|
|
47
47
|
extensions: []
|
48
48
|
extra_rdoc_files: []
|
49
49
|
files:
|
50
|
-
- .yardopts
|
50
|
+
- ".yardopts"
|
51
51
|
- CHANGELOG.md
|
52
52
|
- CONTRIBUTING.md
|
53
53
|
- LICENSE
|
54
54
|
- README.md
|
55
|
-
- UPGRADING.md
|
56
55
|
- Rakefile
|
56
|
+
- UPGRADING.md
|
57
57
|
- hashie.gemspec
|
58
|
+
- lib/hashie.rb
|
58
59
|
- lib/hashie/clash.rb
|
59
60
|
- lib/hashie/dash.rb
|
60
61
|
- lib/hashie/extensions/coercion.rb
|
61
62
|
- lib/hashie/extensions/dash/indifferent_access.rb
|
62
63
|
- lib/hashie/extensions/deep_fetch.rb
|
63
64
|
- lib/hashie/extensions/deep_find.rb
|
65
|
+
- lib/hashie/extensions/deep_locate.rb
|
64
66
|
- lib/hashie/extensions/deep_merge.rb
|
65
67
|
- lib/hashie/extensions/ignore_undeclared.rb
|
66
68
|
- lib/hashie/extensions/indifferent_access.rb
|
@@ -77,7 +79,6 @@ files:
|
|
77
79
|
- lib/hashie/rash.rb
|
78
80
|
- lib/hashie/trash.rb
|
79
81
|
- lib/hashie/version.rb
|
80
|
-
- lib/hashie.rb
|
81
82
|
- spec/hashie/clash_spec.rb
|
82
83
|
- spec/hashie/dash_spec.rb
|
83
84
|
- spec/hashie/extensions/autoload_spec.rb
|
@@ -85,6 +86,7 @@ files:
|
|
85
86
|
- spec/hashie/extensions/dash/indifferent_access_spec.rb
|
86
87
|
- spec/hashie/extensions/deep_fetch_spec.rb
|
87
88
|
- spec/hashie/extensions/deep_find_spec.rb
|
89
|
+
- spec/hashie/extensions/deep_locate_spec.rb
|
88
90
|
- spec/hashie/extensions/deep_merge_spec.rb
|
89
91
|
- spec/hashie/extensions/ignore_undeclared_spec.rb
|
90
92
|
- spec/hashie/extensions/indifferent_access_spec.rb
|
@@ -113,17 +115,17 @@ require_paths:
|
|
113
115
|
- lib
|
114
116
|
required_ruby_version: !ruby/object:Gem::Requirement
|
115
117
|
requirements:
|
116
|
-
- -
|
118
|
+
- - ">="
|
117
119
|
- !ruby/object:Gem::Version
|
118
120
|
version: '0'
|
119
121
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
122
|
requirements:
|
121
|
-
- -
|
123
|
+
- - ">="
|
122
124
|
- !ruby/object:Gem::Version
|
123
125
|
version: '0'
|
124
126
|
requirements: []
|
125
127
|
rubyforge_project:
|
126
|
-
rubygems_version: 2.
|
128
|
+
rubygems_version: 2.2.2
|
127
129
|
signing_key:
|
128
130
|
specification_version: 4
|
129
131
|
summary: Your friendly neighborhood hash library.
|
@@ -135,6 +137,7 @@ test_files:
|
|
135
137
|
- spec/hashie/extensions/dash/indifferent_access_spec.rb
|
136
138
|
- spec/hashie/extensions/deep_fetch_spec.rb
|
137
139
|
- spec/hashie/extensions/deep_find_spec.rb
|
140
|
+
- spec/hashie/extensions/deep_locate_spec.rb
|
138
141
|
- spec/hashie/extensions/deep_merge_spec.rb
|
139
142
|
- spec/hashie/extensions/ignore_undeclared_spec.rb
|
140
143
|
- spec/hashie/extensions/indifferent_access_spec.rb
|