hashie 3.4.6 → 3.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +29 -0
- data/README.md +11 -1
- data/UPGRADING.md +12 -0
- data/hashie.gemspec +1 -1
- data/lib/hashie.rb +20 -2
- data/lib/hashie/array.rb +8 -1
- data/lib/hashie/dash.rb +5 -1
- data/lib/hashie/extensions/coercion.rb +8 -4
- data/lib/hashie/extensions/dash/indifferent_access.rb +2 -1
- data/lib/hashie/extensions/deep_locate.rb +3 -4
- data/lib/hashie/extensions/deep_merge.rb +1 -1
- data/lib/hashie/extensions/ruby_version.rb +60 -0
- data/lib/hashie/extensions/ruby_version_check.rb +1 -1
- data/lib/hashie/mash.rb +15 -0
- data/lib/hashie/utils.rb +16 -0
- data/lib/hashie/version.rb +1 -1
- data/spec/hashie/array_spec.rb +12 -0
- data/spec/hashie/dash_spec.rb +11 -0
- data/spec/hashie/extensions/coercion_spec.rb +8 -2
- data/spec/hashie/extensions/deep_find_spec.rb +25 -0
- data/spec/hashie/extensions/deep_merge_spec.rb +7 -2
- data/spec/hashie/extensions/indifferent_access_spec.rb +37 -0
- data/spec/hashie/mash_spec.rb +8 -0
- data/spec/hashie/utils_spec.rb +25 -0
- data/spec/hashie_spec.rb +13 -0
- data/spec/spec_helper.rb +5 -2
- data/spec/support/logger.rb +22 -0
- data/spec/support/ruby_version_check.rb +2 -1
- metadata +15 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b9465a1bbfbb1047d8ad8a17483073cec81dd65
|
4
|
+
data.tar.gz: 955e55fec9b59772e24b2bfca191b9c8c2195a04
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f676666e411dc1aa67a65f5548fff4093445a7beaca8f1634e37d5eb8b0122679bc65abd90073c46140b7b87fb57d5fca54a89a63bf2b08942767e482f39406a
|
7
|
+
data.tar.gz: cc3f221711869e4ced90b33d8f873bad001f310946593e9f8c6b67e035b85f1591e4af05a8440dced9a41a004dc244795fbb215a173de866ba5239ce3ae1f8dc
|
data/CHANGELOG.md
CHANGED
@@ -6,6 +6,35 @@ scheme are considered to be bugs.
|
|
6
6
|
|
7
7
|
[semver]: http://semver.org/spec/v2.0.0.html
|
8
8
|
|
9
|
+
## [3.5.0] - 2017-01-31
|
10
|
+
|
11
|
+
* [#386](https://github.com/intridea/hashie/pull/386): Fix for #385: Make `deep_merge` always `deep_dup` nested hashes before merging them in so that there are no shared references between the two hashes being merged. - [@mltsy](https://github.com/mltsy).
|
12
|
+
* [#389](https://github.com/intridea/hashie/pull/389): Support Ruby 2.4.0 - [@camelmasa](https://github.com/camelmasa).
|
13
|
+
|
14
|
+
[3.5.0]: https://github.com/intridea/hashie/compare/v3.4.6...v3.5.0
|
15
|
+
|
16
|
+
### Added
|
17
|
+
|
18
|
+
* [#381](https://github.com/intridea/hashie/pull/381): Add a logging layer that lets us report potential issues to our users. As the first logged issue, report when a `Hashie::Mash` is attempting to overwrite a built-in method, since that is one of our number one questions - [@michaelherold](https://github.com/michaelherold).
|
19
|
+
|
20
|
+
### Changed
|
21
|
+
|
22
|
+
* [#384](https://github.com/intridea/hashie/pull/384): Updated to CodeClimate 1.x - [@boffbowsh](https://github.com/boffbowsh).
|
23
|
+
|
24
|
+
### Fixed
|
25
|
+
|
26
|
+
* [#369](https://github.com/intridea/hashie/pull/369): If a translation for a property exists when using IndifferentAccess and IgnoreUndeclared, use the translation to find the property - [@whitethunder](https://github.com/whitethunder).
|
27
|
+
* [#376](https://github.com/intridea/hashie/pull/376): Leave string index unchanged if it can't be converted to integer for Array#dig - [@sazor](https://github.com/sazor).
|
28
|
+
* [#377](https://github.com/intridea/hashie/pull/377): Dont use Rubygems to check ruby version - [@sazor](https://github.com/sazor).
|
29
|
+
* [#378](https://github.com/intridea/hashie/pull/378): Deep find all searches inside all nested hashes - [@sazor](https://github.com/sazor).
|
30
|
+
* [#380](https://github.com/intridea/hashie/pull/380): Evaluate procs default values of Dash in object initialization - [@sazor](https://github.com/sazor).
|
31
|
+
|
32
|
+
### Miscellanous
|
33
|
+
|
34
|
+
* [#387](https://github.com/intridea/hashie/pull/387): Fix builds failing due to Rake 11 having a breaking change - [@michaelherold](https://github.com/michaelherold).
|
35
|
+
|
36
|
+
## [3.4.6] - 2016-09-16
|
37
|
+
|
9
38
|
[3.4.6]: https://github.com/intridea/hashie/compare/v3.4.5...v3.4.6
|
10
39
|
|
11
40
|
### Fixed
|
data/README.md
CHANGED
@@ -20,7 +20,7 @@ $ gem install hashie
|
|
20
20
|
|
21
21
|
## Upgrading
|
22
22
|
|
23
|
-
You're reading the documentation for the
|
23
|
+
You're reading the documentation for the next release of Hashie, which should be 3.4.7. Please read [UPGRADING](UPGRADING.md) when upgrading from a previous version. The current stable release is [3.4.6](https://github.com/intridea/hashie/blob/v3.4.6/README.md).
|
24
24
|
|
25
25
|
## Hash Extensions
|
26
26
|
|
@@ -28,6 +28,15 @@ The library is broken up into a number of atomically includable Hash extension m
|
|
28
28
|
|
29
29
|
Any of the extensions listed below can be mixed into a class by `include`-ing `Hashie::Extensions::ExtensionName`.
|
30
30
|
|
31
|
+
## Logging
|
32
|
+
|
33
|
+
Hashie has a built-in logger that you can override. By default, it logs to `STDOUT` but can be replaced by any `Logger` class. The logger is accessible on the Hashie module, as shown below:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
# Set the logger to the Rails logger
|
37
|
+
Hashie.logger = Rails.logger
|
38
|
+
```
|
39
|
+
|
31
40
|
### Coercion
|
32
41
|
|
33
42
|
Coercions allow you to set up "coercion rules" based either on the key or the value type to massage data as it's being inserted into the Hash. Key coercions might be used, for example, in lightweight data modeling applications such as an API client:
|
@@ -35,6 +44,7 @@ Coercions allow you to set up "coercion rules" based either on the key or the va
|
|
35
44
|
```ruby
|
36
45
|
class Tweet < Hash
|
37
46
|
include Hashie::Extensions::Coercion
|
47
|
+
include Hashie::Extensions::MergeInitializer
|
38
48
|
coerce_key :user, User
|
39
49
|
end
|
40
50
|
|
data/UPGRADING.md
CHANGED
@@ -1,6 +1,18 @@
|
|
1
1
|
Upgrading Hashie
|
2
2
|
================
|
3
3
|
|
4
|
+
### Upgrading to 3.4.7
|
5
|
+
|
6
|
+
#### Procs as default values for Dash
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
class MyHash < Hashie::Dash
|
10
|
+
property :time, default: -> { Time.now }
|
11
|
+
end
|
12
|
+
```
|
13
|
+
|
14
|
+
In versions < 3.4.7 `Time.now` will be evaluated when `time` property is accessed directly first time.
|
15
|
+
In version >= 3.4.7 `Time.now` is evaluated in time of object initialization.
|
4
16
|
### Upgrading to 3.4.4
|
5
17
|
|
6
18
|
#### Mash subclasses and reverse_merge
|
data/hashie.gemspec
CHANGED
@@ -16,7 +16,7 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.files += Dir['spec/**/*.rb']
|
17
17
|
gem.test_files = Dir['spec/**/*.rb']
|
18
18
|
|
19
|
-
gem.add_development_dependency 'rake'
|
19
|
+
gem.add_development_dependency 'rake', '< 11'
|
20
20
|
gem.add_development_dependency 'rspec', '~> 3.0'
|
21
21
|
gem.add_development_dependency 'rspec-pending_for', '~> 0.1'
|
22
22
|
end
|
data/lib/hashie.rb
CHANGED
@@ -1,6 +1,22 @@
|
|
1
|
+
require 'logger'
|
1
2
|
require 'hashie/version'
|
2
3
|
|
3
4
|
module Hashie
|
5
|
+
# The logger that Hashie uses for reporting errors.
|
6
|
+
#
|
7
|
+
# @return [Logger]
|
8
|
+
def self.logger
|
9
|
+
@logger ||= Logger.new(STDOUT)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Sets the logger that Hashie uses for reporting errors.
|
13
|
+
#
|
14
|
+
# @param logger [Logger] The logger to set as Hashie's logger.
|
15
|
+
# @return [void]
|
16
|
+
def self.logger=(logger)
|
17
|
+
@logger = logger
|
18
|
+
end
|
19
|
+
|
4
20
|
autoload :Clash, 'hashie/clash'
|
5
21
|
autoload :Dash, 'hashie/dash'
|
6
22
|
autoload :Hash, 'hashie/hash'
|
@@ -8,6 +24,7 @@ module Hashie
|
|
8
24
|
autoload :Trash, 'hashie/trash'
|
9
25
|
autoload :Rash, 'hashie/rash'
|
10
26
|
autoload :Array, 'hashie/array'
|
27
|
+
autoload :Utils, 'hashie/utils'
|
11
28
|
|
12
29
|
module Extensions
|
13
30
|
autoload :Coercion, 'hashie/extensions/coercion'
|
@@ -27,8 +44,9 @@ module Hashie
|
|
27
44
|
autoload :PrettyInspect, 'hashie/extensions/pretty_inspect'
|
28
45
|
autoload :KeyConversion, 'hashie/extensions/key_conversion'
|
29
46
|
autoload :MethodAccessWithOverride, 'hashie/extensions/method_access'
|
30
|
-
autoload :StrictKeyAccess,
|
31
|
-
autoload :
|
47
|
+
autoload :StrictKeyAccess, 'hashie/extensions/strict_key_access'
|
48
|
+
autoload :RubyVersion, 'hashie/extensions/ruby_version'
|
49
|
+
autoload :RubyVersionCheck, 'hashie/extensions/ruby_version_check'
|
32
50
|
|
33
51
|
module Parsers
|
34
52
|
autoload :YamlErbParser, 'hashie/extensions/parsers/yaml_erb_parser'
|
data/lib/hashie/array.rb
CHANGED
@@ -7,7 +7,14 @@ module Hashie
|
|
7
7
|
include Hashie::Extensions::RubyVersionCheck
|
8
8
|
with_minimum_ruby('2.3.0') do
|
9
9
|
def dig(*indexes)
|
10
|
-
|
10
|
+
converted_indexes = indexes.map do |idx|
|
11
|
+
begin
|
12
|
+
Integer(idx)
|
13
|
+
rescue ArgumentError
|
14
|
+
idx
|
15
|
+
end
|
16
|
+
end
|
17
|
+
super(*converted_indexes)
|
11
18
|
end
|
12
19
|
end
|
13
20
|
end
|
data/lib/hashie/dash.rb
CHANGED
@@ -97,7 +97,11 @@ module Hashie
|
|
97
97
|
self.class.defaults.each_pair do |prop, value|
|
98
98
|
self[prop] = begin
|
99
99
|
val = value.dup
|
100
|
-
val.is_a?(Proc)
|
100
|
+
if val.is_a?(Proc)
|
101
|
+
val.arity == 1 ? val.call(self) : val.call
|
102
|
+
else
|
103
|
+
val
|
104
|
+
end
|
101
105
|
rescue TypeError
|
102
106
|
value
|
103
107
|
end
|
@@ -12,10 +12,14 @@ module Hashie
|
|
12
12
|
Symbol => :to_sym
|
13
13
|
}
|
14
14
|
|
15
|
-
ABSTRACT_CORE_TYPES =
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
ABSTRACT_CORE_TYPES = if RubyVersion.new(RUBY_VERSION) >= RubyVersion.new('2.4.0')
|
16
|
+
{ Numeric => [Integer, Float, Complex, Rational] }
|
17
|
+
else
|
18
|
+
{
|
19
|
+
Integer => [Fixnum, Bignum],
|
20
|
+
Numeric => [Fixnum, Bignum, Float, Complex, Rational]
|
21
|
+
}
|
22
|
+
end
|
19
23
|
|
20
24
|
def self.included(base)
|
21
25
|
base.send :include, InstanceMethods
|
@@ -11,6 +11,7 @@ module Hashie
|
|
11
11
|
# Check to see if the specified property has already been
|
12
12
|
# defined.
|
13
13
|
def property?(name)
|
14
|
+
name = translations[name.to_sym] if included_modules.include?(Hashie::Extensions::Dash::PropertyTranslation) && translation_exists?(name)
|
14
15
|
name = name.to_s
|
15
16
|
!!properties.find { |property| property.to_s == name }
|
16
17
|
end
|
@@ -21,7 +22,7 @@ module Hashie
|
|
21
22
|
end
|
22
23
|
|
23
24
|
def transformed_property(property_name, value)
|
24
|
-
transform = transforms[property_name] || transforms[
|
25
|
+
transform = transforms[property_name] || transforms[property_name.to_sym]
|
25
26
|
transform.call(value)
|
26
27
|
end
|
27
28
|
|
@@ -76,10 +76,9 @@ module Hashie
|
|
76
76
|
if object.is_a?(::Enumerable)
|
77
77
|
if object.any? { |value| _match_comparator?(value, comparator, object) }
|
78
78
|
result.push object
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
end
|
79
|
+
end
|
80
|
+
(object.respond_to?(:values) ? object.values : object.entries).each do |value|
|
81
|
+
_deep_locate(comparator, value, result)
|
83
82
|
end
|
84
83
|
end
|
85
84
|
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# Copyright (c) Chad Fowler, Rich Kilmer, Jim Weirich and others.
|
2
|
+
# Portions copyright (c) Engine Yard and Andre Arko
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# 'Software'), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
module Hashie
|
16
|
+
module Extensions
|
17
|
+
class RubyVersion
|
18
|
+
include Comparable
|
19
|
+
|
20
|
+
attr_accessor :segments
|
21
|
+
|
22
|
+
def initialize(version)
|
23
|
+
@segments = split_to_segments(version)
|
24
|
+
end
|
25
|
+
|
26
|
+
def <=>(other)
|
27
|
+
lhsegments = segments
|
28
|
+
rhsegments = other.segments
|
29
|
+
|
30
|
+
lhsize = lhsegments.size
|
31
|
+
rhsize = rhsegments.size
|
32
|
+
limit = (lhsize > rhsize ? lhsize : rhsize) - 1
|
33
|
+
|
34
|
+
i = 0
|
35
|
+
|
36
|
+
while i <= limit
|
37
|
+
lhs = lhsegments[i] || 0
|
38
|
+
rhs = rhsegments[i] || 0
|
39
|
+
i += 1
|
40
|
+
|
41
|
+
next if lhs == rhs
|
42
|
+
return -1 if lhs.is_a?(String) && rhs.is_a?(Numeric)
|
43
|
+
return 1 if lhs.is_a?(Numeric) && rhs.is_a?(String)
|
44
|
+
|
45
|
+
return lhs <=> rhs
|
46
|
+
end
|
47
|
+
|
48
|
+
0
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def split_to_segments(version)
|
54
|
+
version.scan(/[0-9]+|[a-z]+/i).map do |segment|
|
55
|
+
/^\d+$/ =~ segment ? segment.to_i : segment
|
56
|
+
end.freeze
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/hashie/mash.rb
CHANGED
@@ -109,6 +109,8 @@ module Hashie
|
|
109
109
|
# a string before it is set, and Hashes will be converted
|
110
110
|
# into Mashes for nesting purposes.
|
111
111
|
def custom_writer(key, value, convert = true) #:nodoc:
|
112
|
+
key_as_symbol = key.to_sym
|
113
|
+
log_built_in_message(key_as_symbol) if methods.include?(key_as_symbol)
|
112
114
|
regular_writer(convert_key(key), convert ? convert_value(value) : value)
|
113
115
|
end
|
114
116
|
|
@@ -295,5 +297,18 @@ module Hashie
|
|
295
297
|
val
|
296
298
|
end
|
297
299
|
end
|
300
|
+
|
301
|
+
private
|
302
|
+
|
303
|
+
def log_built_in_message(method_key)
|
304
|
+
method_information = Hashie::Utils.method_information(method(method_key))
|
305
|
+
|
306
|
+
Hashie.logger.warn(
|
307
|
+
'You are setting a key that conflicts with a built-in method ' \
|
308
|
+
"#{self.class}##{method_key} #{method_information}. " \
|
309
|
+
'This can cause unexpected behavior when accessing the key via as a ' \
|
310
|
+
'property. You can still access the key via the #[] method.'
|
311
|
+
)
|
312
|
+
end
|
298
313
|
end
|
299
314
|
end
|
data/lib/hashie/utils.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
module Hashie
|
2
|
+
# A collection of helper methods that can be used throughout the gem.
|
3
|
+
module Utils
|
4
|
+
# Describes a method by where it was defined.
|
5
|
+
#
|
6
|
+
# @param bound_method [Method] The method to describe.
|
7
|
+
# @return [String]
|
8
|
+
def self.method_information(bound_method)
|
9
|
+
if bound_method.source_location
|
10
|
+
"defined at #{bound_method.source_location.join(':')}"
|
11
|
+
else
|
12
|
+
"defined in #{bound_method.owner}"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/hashie/version.rb
CHANGED
data/spec/hashie/array_spec.rb
CHANGED
@@ -12,6 +12,18 @@ describe Array do
|
|
12
12
|
it 'works with a numeric index' do
|
13
13
|
expect(array.dig(1)).to eq(:b)
|
14
14
|
end
|
15
|
+
|
16
|
+
context 'when array is empty' do
|
17
|
+
let(:array) { Hashie::Array.new([]) }
|
18
|
+
|
19
|
+
it 'works with a first numeric and next string index' do
|
20
|
+
expect(array.dig(0, 'hello')).to eq(nil)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'throws an error with first string and next numeric index' do
|
24
|
+
expect { array.dig('hello', 0) }.to raise_error(TypeError)
|
25
|
+
end
|
26
|
+
end
|
15
27
|
end
|
16
28
|
end
|
17
29
|
end
|
data/spec/hashie/dash_spec.rb
CHANGED
@@ -12,6 +12,10 @@ class DashTest < Hashie::Dash
|
|
12
12
|
property :count, default: 0
|
13
13
|
end
|
14
14
|
|
15
|
+
class DashTestDefaultProc < Hashie::Dash
|
16
|
+
property :fields, default: -> { [] }
|
17
|
+
end
|
18
|
+
|
15
19
|
class DashNoRequiredTest < Hashie::Dash
|
16
20
|
property :first_name
|
17
21
|
property :email
|
@@ -51,6 +55,13 @@ class DeferredWithSelfTest < Hashie::Dash
|
|
51
55
|
property :updated_at, default: ->(test) { test.created_at }
|
52
56
|
end
|
53
57
|
|
58
|
+
describe DashTestDefaultProc do
|
59
|
+
it 'as_json behaves correctly with default proc' do
|
60
|
+
object = described_class.new
|
61
|
+
expect(object.as_json).to be == { 'fields' => [] }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
54
65
|
describe DashTest do
|
55
66
|
def property_required_error(property)
|
56
67
|
[ArgumentError, "The property '#{property}' is required for #{subject.class.name}."]
|
@@ -558,8 +558,14 @@ describe Hashie::Extensions::Coercion do
|
|
558
558
|
end
|
559
559
|
|
560
560
|
it 'raises a CoercionError when coercion is not possible' do
|
561
|
-
|
562
|
-
|
561
|
+
type = if Hashie::Extensions::RubyVersion.new(RUBY_VERSION) >= Hashie::Extensions::RubyVersion.new('2.4.0')
|
562
|
+
Integer
|
563
|
+
else
|
564
|
+
Fixnum
|
565
|
+
end
|
566
|
+
|
567
|
+
subject.coerce_value type, Symbol
|
568
|
+
expect { instance[:hi] = 1 }.to raise_error(Hashie::CoercionError, /Cannot coerce property :hi from #{type} to Symbol/)
|
563
569
|
end
|
564
570
|
|
565
571
|
it 'coerces Integer to String' do
|
@@ -42,6 +42,31 @@ describe Hashie::Extensions::DeepFind do
|
|
42
42
|
it 'returns nil if it does not find any matches' do
|
43
43
|
expect(instance.deep_find_all(:wahoo)).to be_nil
|
44
44
|
end
|
45
|
+
|
46
|
+
context 'when match value is hash itself' do
|
47
|
+
let(:hash) do
|
48
|
+
{
|
49
|
+
title: {
|
50
|
+
type: :string
|
51
|
+
},
|
52
|
+
library: {
|
53
|
+
books: [
|
54
|
+
{ title: 'Call of the Wild' },
|
55
|
+
{ title: 'Moby Dick' }
|
56
|
+
],
|
57
|
+
shelves: nil,
|
58
|
+
location: {
|
59
|
+
address: '123 Library St.',
|
60
|
+
title: 'Main Library'
|
61
|
+
}
|
62
|
+
}
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'detects all values from a nested hash' do
|
67
|
+
expect(instance.deep_find_all(:title)).to eq([{ type: :string }, 'Call of the Wild', 'Moby Dick', 'Main Library'])
|
68
|
+
end
|
69
|
+
end
|
45
70
|
end
|
46
71
|
|
47
72
|
context 'on an ActiveSupport::HashWithIndifferentAccess' do
|
@@ -14,8 +14,8 @@ describe Hashie::Extensions::DeepMerge do
|
|
14
14
|
|
15
15
|
context 'without &block' do
|
16
16
|
let(:h1) { subject.new.merge(a: 'a', a1: 42, b: 'b', c: { c1: 'c1', c2: { a: 'b' }, c3: { d1: 'd1' } }) }
|
17
|
-
let(:h2) { { a: 1, a1: 1, c: { c1: 2, c2: 'c2', c3: { d2: 'd2' } } } }
|
18
|
-
let(:expected_hash) { { a: 1, a1: 1, b: 'b', c: { c1: 2, c2: 'c2', c3: { d1: 'd1', d2: 'd2' } } } }
|
17
|
+
let(:h2) { { a: 1, a1: 1, c: { c1: 2, c2: 'c2', c3: { d2: 'd2' } }, e: { e1: 1 } } }
|
18
|
+
let(:expected_hash) { { a: 1, a1: 1, b: 'b', c: { c1: 2, c2: 'c2', c3: { d1: 'd1', d2: 'd2' } }, e: { e1: 1 } } }
|
19
19
|
|
20
20
|
it 'deep merges two hashes' do
|
21
21
|
expect(h1.deep_merge(h2)).to eq expected_hash
|
@@ -25,6 +25,11 @@ describe Hashie::Extensions::DeepMerge do
|
|
25
25
|
h1.deep_merge!(h2)
|
26
26
|
expect(h1).to eq expected_hash
|
27
27
|
end
|
28
|
+
|
29
|
+
it 'merges new nested hash entries by value, not by reference' do
|
30
|
+
h1.deep_merge!(h2)
|
31
|
+
expect { h1[:e][:e1] = 'changed' }.not_to change { h2[:e][:e1] }
|
32
|
+
end
|
28
33
|
end
|
29
34
|
|
30
35
|
context 'with &block' do
|
@@ -31,6 +31,13 @@ describe Hashie::Extensions::IndifferentAccess do
|
|
31
31
|
property :foo
|
32
32
|
end
|
33
33
|
|
34
|
+
class IndifferentHashWithIgnoreUndeclaredAndPropertyTranslation < Hashie::Dash
|
35
|
+
include Hashie::Extensions::IgnoreUndeclared
|
36
|
+
include Hashie::Extensions::Dash::PropertyTranslation
|
37
|
+
include Hashie::Extensions::IndifferentAccess
|
38
|
+
property :foo, from: :bar
|
39
|
+
end
|
40
|
+
|
34
41
|
describe '#merge' do
|
35
42
|
it 'indifferently merges in a hash' do
|
36
43
|
indifferent_hash = Class.new(::Hash) do
|
@@ -66,6 +73,36 @@ describe Hashie::Extensions::IndifferentAccess do
|
|
66
73
|
end
|
67
74
|
end
|
68
75
|
|
76
|
+
describe 'when translating properties and ignoring undeclared' do
|
77
|
+
let(:value) { 'baz' }
|
78
|
+
|
79
|
+
subject { IndifferentHashWithIgnoreUndeclaredAndPropertyTranslation.new(params) }
|
80
|
+
|
81
|
+
context 'and the hash keys are strings' do
|
82
|
+
let(:params) { { 'bar' => value } }
|
83
|
+
|
84
|
+
it 'sets the property' do
|
85
|
+
expect(subject[:foo]).to eq value
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'and the hash keys are symbols' do
|
90
|
+
let(:params) { { bar: 'baz' } }
|
91
|
+
|
92
|
+
it 'sets the property' do
|
93
|
+
expect(subject[:foo]).to eq value
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'and there are undeclared keys' do
|
98
|
+
let(:params) { { 'bar' => 'baz', 'fail' => false } }
|
99
|
+
|
100
|
+
it 'sets the property' do
|
101
|
+
expect(subject[:foo]).to eq value
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
69
106
|
shared_examples_for 'hash with indifferent access' do
|
70
107
|
it 'is able to access via string or symbol' do
|
71
108
|
h = subject.build(abc: 123)
|
data/spec/hashie/mash_spec.rb
CHANGED
@@ -134,6 +134,14 @@ describe Hashie::Mash do
|
|
134
134
|
expect(subject.type).to eq 'Steve'
|
135
135
|
end
|
136
136
|
|
137
|
+
shared_context 'with a logger' do
|
138
|
+
it 'logs a warning when overriding built-in methods' do
|
139
|
+
Hashie::Mash.new('trust' => { 'two' => 2 })
|
140
|
+
|
141
|
+
expect(logger_output).to match('Hashie::Mash#trust')
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
137
145
|
context 'updating' do
|
138
146
|
subject do
|
139
147
|
described_class.new(
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
def a_method_to_match_against
|
4
|
+
'Hello world!'
|
5
|
+
end
|
6
|
+
|
7
|
+
RSpec.describe Hashie::Utils do
|
8
|
+
describe '.method_information' do
|
9
|
+
it 'states the module or class that a native method was defined in' do
|
10
|
+
bound_method = method(:trust)
|
11
|
+
|
12
|
+
message = Hashie::Utils.method_information(bound_method)
|
13
|
+
|
14
|
+
expect(message).to match('Kernel')
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'states the line a Ruby method was defined at' do
|
18
|
+
bound_method = method(:a_method_to_match_against)
|
19
|
+
|
20
|
+
message = Hashie::Utils.method_information(bound_method)
|
21
|
+
|
22
|
+
expect(message).to match('spec/hashie/utils_spec.rb')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/spec/hashie_spec.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Hashie do
|
4
|
+
describe '.logger' do
|
5
|
+
shared_context 'with a logger' do
|
6
|
+
it 'is available via an accessor' do
|
7
|
+
Hashie.logger.info('Fee fi fo fum')
|
8
|
+
|
9
|
+
expect(logger_output).to match('Fee fi fo fum')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
if ENV['CI']
|
2
|
-
require '
|
3
|
-
|
2
|
+
require 'simplecov'
|
3
|
+
SimpleCov.start
|
4
4
|
end
|
5
5
|
|
6
6
|
require 'pry'
|
@@ -10,6 +10,9 @@ require 'hashie'
|
|
10
10
|
require 'rspec/pending_for'
|
11
11
|
require './spec/support/ruby_version_check'
|
12
12
|
|
13
|
+
require 'active_support'
|
14
|
+
require 'active_support/core_ext'
|
15
|
+
|
13
16
|
RSpec.configure do |config|
|
14
17
|
config.extend RubyVersionCheck
|
15
18
|
config.expect_with :rspec do |expect|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# A shared context that allows you to check the output of Hashie's logger.
|
2
|
+
#
|
3
|
+
# @example
|
4
|
+
# shared_context 'with a logger' do
|
5
|
+
# Hashie.logger.info 'What is happening in here?!'
|
6
|
+
#
|
7
|
+
# expect(logger_output).to match('What is happening in here?!')
|
8
|
+
# end
|
9
|
+
RSpec.shared_context 'with a logger' do
|
10
|
+
# @private
|
11
|
+
let(:log) { StringIO.new }
|
12
|
+
|
13
|
+
# The output string from the logger
|
14
|
+
let(:logger_output) { log.rewind && log.string }
|
15
|
+
|
16
|
+
around(:each) do |example|
|
17
|
+
original_logger = Hashie.logger
|
18
|
+
Hashie.logger = Logger.new(log)
|
19
|
+
example.run
|
20
|
+
Hashie.logger = original_logger
|
21
|
+
end
|
22
|
+
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
|
+
version: 3.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Bleigh
|
@@ -9,22 +9,22 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2017-01-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
|
-
version: '
|
20
|
+
version: '11'
|
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
|
-
version: '
|
27
|
+
version: '11'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: rspec
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -90,6 +90,7 @@ files:
|
|
90
90
|
- lib/hashie/extensions/method_access.rb
|
91
91
|
- lib/hashie/extensions/parsers/yaml_erb_parser.rb
|
92
92
|
- lib/hashie/extensions/pretty_inspect.rb
|
93
|
+
- lib/hashie/extensions/ruby_version.rb
|
93
94
|
- lib/hashie/extensions/ruby_version_check.rb
|
94
95
|
- lib/hashie/extensions/strict_key_access.rb
|
95
96
|
- lib/hashie/extensions/stringify_keys.rb
|
@@ -98,6 +99,7 @@ files:
|
|
98
99
|
- lib/hashie/mash.rb
|
99
100
|
- lib/hashie/rash.rb
|
100
101
|
- lib/hashie/trash.rb
|
102
|
+
- lib/hashie/utils.rb
|
101
103
|
- lib/hashie/version.rb
|
102
104
|
- spec/hashie/array_spec.rb
|
103
105
|
- spec/hashie/clash_spec.rb
|
@@ -125,8 +127,11 @@ files:
|
|
125
127
|
- spec/hashie/parsers/yaml_erb_parser_spec.rb
|
126
128
|
- spec/hashie/rash_spec.rb
|
127
129
|
- spec/hashie/trash_spec.rb
|
130
|
+
- spec/hashie/utils_spec.rb
|
128
131
|
- spec/hashie/version_spec.rb
|
132
|
+
- spec/hashie_spec.rb
|
129
133
|
- spec/spec_helper.rb
|
134
|
+
- spec/support/logger.rb
|
130
135
|
- spec/support/module_context.rb
|
131
136
|
- spec/support/ruby_version_check.rb
|
132
137
|
homepage: https://github.com/intridea/hashie
|
@@ -149,7 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
149
154
|
version: '0'
|
150
155
|
requirements: []
|
151
156
|
rubyforge_project:
|
152
|
-
rubygems_version: 2.
|
157
|
+
rubygems_version: 2.6.7
|
153
158
|
signing_key:
|
154
159
|
specification_version: 4
|
155
160
|
summary: Your friendly neighborhood hash library.
|
@@ -180,7 +185,10 @@ test_files:
|
|
180
185
|
- spec/hashie/parsers/yaml_erb_parser_spec.rb
|
181
186
|
- spec/hashie/rash_spec.rb
|
182
187
|
- spec/hashie/trash_spec.rb
|
188
|
+
- spec/hashie/utils_spec.rb
|
183
189
|
- spec/hashie/version_spec.rb
|
190
|
+
- spec/hashie_spec.rb
|
184
191
|
- spec/spec_helper.rb
|
192
|
+
- spec/support/logger.rb
|
185
193
|
- spec/support/module_context.rb
|
186
194
|
- spec/support/ruby_version_check.rb
|