Allow mash error silencing (#488)
This commit is contained in:
parent
ca3604516b
commit
1a30427c9d
|
@ -1,6 +1,6 @@
|
|||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config`
|
||||
# on 2019-08-13 23:33:30 -0400 using RuboCop version 0.52.1.
|
||||
# on 2019-10-10 00:07:29 -0400 using RuboCop version 0.52.1.
|
||||
# The point is for the user to remove these configuration records
|
||||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
|
@ -14,6 +14,12 @@ Metrics/AbcSize:
|
|||
Metrics/CyclomaticComplexity:
|
||||
Max: 11
|
||||
|
||||
# Offense count: 1
|
||||
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
||||
# URISchemes: http, https
|
||||
Metrics/LineLength:
|
||||
Max: 111
|
||||
|
||||
# Offense count: 18
|
||||
# Configuration parameters: CountComments.
|
||||
Metrics/MethodLength:
|
||||
|
@ -23,6 +29,6 @@ Metrics/MethodLength:
|
|||
Metrics/PerceivedComplexity:
|
||||
Max: 10
|
||||
|
||||
# Offense count: 39
|
||||
# Offense count: 41
|
||||
Style/Documentation:
|
||||
Enabled: false
|
||||
|
|
|
@ -15,7 +15,8 @@ scheme are considered to be bugs.
|
|||
* [#323](https://github.com/intridea/hashie/pull/323): Added `Hashie::Extensions::Mash::DefineAccessors` - [@marshall-lee](https://github.com/marshall-lee).
|
||||
* [#474](https://github.com/intridea/hashie/pull/474): Expose `YAML#safe_load` options in `Mash#load` - [@riouruma](https://github.com/riouruma), [@dblock](https://github.com/dblock).
|
||||
* [#478](https://github.com/intridea/hashie/pull/478): Added optional array parameter to `Hashie::Mash.disable_warnings` - [@bobbymcwho](https://github.com/bobbymcwho).
|
||||
* [#481](https://github.com/intridea/hashie/pull/481): Ruby 2.6 - Support Hash#merge and #merge! called with multiple Hashes/Mashes - [@bobbymcwho](https://github.com/bobbymcwho).
|
||||
* [#481](https://github.com/intridea/hashie/pull/481): Ruby 2.6 - Support `Hash#merge` and `#merge!` called with multiple Hashes/Mashes - [@bobbymcwho](https://github.com/bobbymcwho).
|
||||
* [#488](https://github.com/intridea/hashie/pull/488): Added ability to create an anonymous `Hashie::Mash` subclass with key conflict errors silenced using `Hashie::Mash.quiet.new` - [@bobbymcwho](https://github.com/bobbymcwho).
|
||||
* Your contribution here.
|
||||
|
||||
### Changed
|
||||
|
|
|
@ -557,6 +557,13 @@ end
|
|||
Response.new(merge: 'true', compact: true, zip: '90210', zap: 'electric')
|
||||
```
|
||||
|
||||
If you would like to create an anonymous subclass of a Hashie::Mash with key conflict warnings disabled:
|
||||
|
||||
```ruby
|
||||
Hashie::Mash.quiet.new(zip: '90210', compact: true) # no errors logged
|
||||
Hashie::Mash.quiet(:zip).new(zip: '90210', compact: true) # error logged for compact
|
||||
```
|
||||
|
||||
### How does the wrapping of Mash sub-Hashes work?
|
||||
|
||||
Mash duplicates any sub-Hashes that you add to it and wraps them in a Mash. This allows for infinite chaining of nested Hashes within a Mash without modifying the object(s) that are passed into the Mash. When you subclass Mash, the subclass wraps any sub-Hashes in its own class. This preserves any extensions that you mixed into the Mash subclass and allows them to work within the sub-Hashes, in addition to the main containing Mash.
|
||||
|
|
|
@ -36,10 +36,14 @@ p cool_parents
|
|||
|
||||
This may make places where you had to re-make the Mash redundant, and may cause unintended side effects if your application was expecting a plain old ruby Hash.
|
||||
|
||||
### Ruby 2.6: Mash#merge and Mash#merge!
|
||||
#### Ruby 2.6: Mash#merge and Mash#merge!
|
||||
|
||||
In Ruby > 2.6.0, Hashie now supports passing multiple hash and Mash objects to Mash#merge and Mash#merge!.
|
||||
|
||||
#### Hashie::Mash::CannotDisableMashWarnings error class is removed
|
||||
|
||||
There shouldn't really be a case that anyone was relying on catching this specific error, but if so, they should change it to rescue Hashie::Extensions::KeyConflictWarning::CannotDisableMashWarnings
|
||||
|
||||
### Upgrading to 3.7.0
|
||||
|
||||
#### Mash#load takes options
|
||||
|
|
|
@ -12,26 +12,26 @@ module Hashie
|
|||
autoload :Utils, 'hashie/utils'
|
||||
|
||||
module Extensions
|
||||
autoload :Coercion, 'hashie/extensions/coercion'
|
||||
autoload :DeepMerge, 'hashie/extensions/deep_merge'
|
||||
autoload :IgnoreUndeclared, 'hashie/extensions/ignore_undeclared'
|
||||
autoload :IndifferentAccess, 'hashie/extensions/indifferent_access'
|
||||
autoload :MergeInitializer, 'hashie/extensions/merge_initializer'
|
||||
autoload :MethodAccess, 'hashie/extensions/method_access'
|
||||
autoload :MethodQuery, 'hashie/extensions/method_access'
|
||||
autoload :MethodReader, 'hashie/extensions/method_access'
|
||||
autoload :MethodWriter, 'hashie/extensions/method_access'
|
||||
autoload :StringifyKeys, 'hashie/extensions/stringify_keys'
|
||||
autoload :SymbolizeKeys, 'hashie/extensions/symbolize_keys'
|
||||
autoload :DeepFetch, 'hashie/extensions/deep_fetch'
|
||||
autoload :DeepFind, 'hashie/extensions/deep_find'
|
||||
autoload :DeepLocate, 'hashie/extensions/deep_locate'
|
||||
autoload :PrettyInspect, 'hashie/extensions/pretty_inspect'
|
||||
autoload :KeyConversion, 'hashie/extensions/key_conversion'
|
||||
autoload :Coercion, 'hashie/extensions/coercion'
|
||||
autoload :DeepMerge, 'hashie/extensions/deep_merge'
|
||||
autoload :IgnoreUndeclared, 'hashie/extensions/ignore_undeclared'
|
||||
autoload :IndifferentAccess, 'hashie/extensions/indifferent_access'
|
||||
autoload :MergeInitializer, 'hashie/extensions/merge_initializer'
|
||||
autoload :MethodAccess, 'hashie/extensions/method_access'
|
||||
autoload :MethodQuery, 'hashie/extensions/method_access'
|
||||
autoload :MethodReader, 'hashie/extensions/method_access'
|
||||
autoload :MethodWriter, 'hashie/extensions/method_access'
|
||||
autoload :StringifyKeys, 'hashie/extensions/stringify_keys'
|
||||
autoload :SymbolizeKeys, 'hashie/extensions/symbolize_keys'
|
||||
autoload :DeepFetch, 'hashie/extensions/deep_fetch'
|
||||
autoload :DeepFind, 'hashie/extensions/deep_find'
|
||||
autoload :DeepLocate, 'hashie/extensions/deep_locate'
|
||||
autoload :PrettyInspect, 'hashie/extensions/pretty_inspect'
|
||||
autoload :KeyConversion, 'hashie/extensions/key_conversion'
|
||||
autoload :MethodAccessWithOverride, 'hashie/extensions/method_access'
|
||||
autoload :StrictKeyAccess, 'hashie/extensions/strict_key_access'
|
||||
autoload :RubyVersion, 'hashie/extensions/ruby_version'
|
||||
autoload :RubyVersionCheck, 'hashie/extensions/ruby_version_check'
|
||||
autoload :StrictKeyAccess, 'hashie/extensions/strict_key_access'
|
||||
autoload :RubyVersion, 'hashie/extensions/ruby_version'
|
||||
autoload :RubyVersionCheck, 'hashie/extensions/ruby_version_check'
|
||||
|
||||
module Parsers
|
||||
autoload :YamlErbParser, 'hashie/extensions/parsers/yaml_erb_parser'
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
module Hashie
|
||||
module Extensions
|
||||
module KeyConflictWarning
|
||||
class CannotDisableMashWarnings < StandardError
|
||||
def initialize
|
||||
super(
|
||||
'You cannot disable warnings on the base Mash class. ' \
|
||||
'Please subclass the Mash and disable it in the subclass.'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# Disable the logging of warnings based on keys conflicting keys/methods
|
||||
#
|
||||
# @api semipublic
|
||||
# @return [void]
|
||||
def disable_warnings(*method_keys)
|
||||
raise CannotDisableMashWarnings if self == Hashie::Mash
|
||||
if method_keys.any?
|
||||
disabled_warnings.concat(method_keys).tap(&:flatten!).uniq!
|
||||
else
|
||||
disabled_warnings.clear
|
||||
end
|
||||
|
||||
@disable_warnings = true
|
||||
end
|
||||
|
||||
# Checks whether this class disables warnings for conflicting keys/methods
|
||||
#
|
||||
# @api semipublic
|
||||
# @return [Boolean]
|
||||
def disable_warnings?(method_key = nil)
|
||||
return disabled_warnings.include?(method_key) if disabled_warnings.any? && method_key
|
||||
@disable_warnings ||= false
|
||||
end
|
||||
|
||||
# Returns an array of blacklisted methods that this class disables warnings for.
|
||||
#
|
||||
# @api semipublic
|
||||
# @return [Boolean]
|
||||
def disabled_warnings
|
||||
@_disabled_warnings ||= []
|
||||
end
|
||||
|
||||
# Inheritance hook that sets class configuration when inherited.
|
||||
#
|
||||
# @api semipublic
|
||||
# @return [void]
|
||||
def inherited(subclass)
|
||||
super
|
||||
subclass.disable_warnings(disabled_warnings) if disable_warnings?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,6 +2,7 @@ require 'hashie/hash'
|
|||
require 'hashie/array'
|
||||
require 'hashie/utils'
|
||||
require 'hashie/logger'
|
||||
require 'hashie/extensions/key_conflict_warning'
|
||||
|
||||
module Hashie
|
||||
# Mash allows you to create pseudo-objects that have method-like
|
||||
|
@ -62,59 +63,10 @@ module Hashie
|
|||
class Mash < Hash
|
||||
include Hashie::Extensions::PrettyInspect
|
||||
include Hashie::Extensions::RubyVersionCheck
|
||||
extend Hashie::Extensions::KeyConflictWarning
|
||||
|
||||
ALLOWED_SUFFIXES = %w[? ! = _].freeze
|
||||
|
||||
class CannotDisableMashWarnings < StandardError
|
||||
def initialize
|
||||
super(
|
||||
'You cannot disable warnings on the base Mash class. ' \
|
||||
'Please subclass the Mash and disable it in the subclass.'
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# Disable the logging of warnings based on keys conflicting keys/methods
|
||||
#
|
||||
# @api semipublic
|
||||
# @return [void]
|
||||
def self.disable_warnings(*method_keys)
|
||||
raise CannotDisableMashWarnings if self == Hashie::Mash
|
||||
if method_keys.any?
|
||||
disable_warnings_blacklist.concat(method_keys).tap(&:flatten!).uniq!
|
||||
else
|
||||
disable_warnings_blacklist.clear
|
||||
end
|
||||
|
||||
@disable_warnings = true
|
||||
end
|
||||
|
||||
# Checks whether this class disables warnings for conflicting keys/methods
|
||||
#
|
||||
# @api semipublic
|
||||
# @return [Boolean]
|
||||
def self.disable_warnings?(method_key = nil)
|
||||
return disable_warnings_blacklist.include?(method_key) if disable_warnings_blacklist.any? && method_key
|
||||
@disable_warnings ||= false
|
||||
end
|
||||
|
||||
# Returns an array of blacklisted methods that this class disables warnings for.
|
||||
#
|
||||
# @api semipublic
|
||||
# @return [Boolean]
|
||||
def self.disable_warnings_blacklist
|
||||
@_disable_warnings_blacklist ||= []
|
||||
end
|
||||
|
||||
# Inheritance hook that sets class configuration when inherited.
|
||||
#
|
||||
# @api semipublic
|
||||
# @return [void]
|
||||
def self.inherited(subclass)
|
||||
super
|
||||
subclass.disable_warnings(disable_warnings_blacklist) if disable_warnings?
|
||||
end
|
||||
|
||||
def self.load(path, options = {})
|
||||
@_mashes ||= new
|
||||
|
||||
|
@ -149,6 +101,20 @@ module Hashie
|
|||
default ? super(default) : super(&blk)
|
||||
end
|
||||
|
||||
# Creates a new anonymous subclass with key conflict
|
||||
# warnings disabled. You may pass an array of method
|
||||
# symbols to restrict the warnings blacklist to.
|
||||
# Hashie::Mash.quiet.new(hash) all warnings disabled.
|
||||
# Hashie::Mash.quiet(:zip).new(hash) only zip warning
|
||||
# is disabled.
|
||||
def self.quiet(*method_keys)
|
||||
(@memoized_classes ||= {})[method_keys] ||
|
||||
Class.new(self).tap do |k|
|
||||
k.send(:disable_warnings, *method_keys)
|
||||
@memoized_classes[method_keys] = k
|
||||
end
|
||||
end
|
||||
|
||||
class << self; alias [] new; end
|
||||
|
||||
alias regular_reader []
|
||||
|
|
|
@ -160,7 +160,9 @@ describe Hashie::Mash do
|
|||
end
|
||||
|
||||
it 'cannot disable logging on the base Mash' do
|
||||
expect { Hashie::Mash.disable_warnings }.to raise_error(Hashie::Mash::CannotDisableMashWarnings)
|
||||
expected_error = Hashie::Extensions::KeyConflictWarning::CannotDisableMashWarnings
|
||||
|
||||
expect { Hashie::Mash.disable_warnings }.to raise_error(expected_error)
|
||||
end
|
||||
|
||||
it 'carries over the disable for warnings on grandchild classes' do
|
||||
|
@ -200,7 +202,7 @@ describe Hashie::Mash do
|
|||
|
||||
grandchild_class.new('address' => { 'zip' => '90210' }, 'merge' => true)
|
||||
|
||||
expect(grandchild_class.disable_warnings_blacklist).to eq(%i[zip merge])
|
||||
expect(grandchild_class.disabled_warnings).to eq(%i[zip merge])
|
||||
expect(logger_output).to be_blank
|
||||
end
|
||||
|
||||
|
@ -213,7 +215,7 @@ describe Hashie::Mash do
|
|||
disable_warnings :cycle
|
||||
end
|
||||
|
||||
expect(child_class.disable_warnings_blacklist).to eq(%i[zip merge cycle])
|
||||
expect(child_class.disabled_warnings).to eq(%i[zip merge cycle])
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -226,7 +228,7 @@ describe Hashie::Mash do
|
|||
|
||||
child_class.new('address' => { 'zip' => '90210' }, 'merge' => true, 'cycle' => 'bi')
|
||||
|
||||
expect(child_class.disable_warnings_blacklist).to eq([])
|
||||
expect(child_class.disabled_warnings).to eq([])
|
||||
expect(logger_output).to be_blank
|
||||
end
|
||||
end
|
||||
|
@ -962,6 +964,19 @@ describe Hashie::Mash do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.quiet' do
|
||||
it 'returns a subclass of the calling class' do
|
||||
expect(Hashie::Mash.quiet.new).to be_a(Hashie::Mash)
|
||||
end
|
||||
|
||||
it 'memoizes and returns classes' do
|
||||
call_one = Hashie::Mash.quiet
|
||||
call_two = Hashie::Mash.quiet
|
||||
expect(Hashie::Mash.instance_variable_get('@memoized_classes').count).to eq(1)
|
||||
expect(call_one).to eq(call_two)
|
||||
end
|
||||
end
|
||||
|
||||
with_minimum_ruby('2.3.0') do
|
||||
describe '#dig' do
|
||||
subject { described_class.new(a: { b: 1 }) }
|
||||
|
|
Loading…
Reference in New Issue