Added Rubocop.
This commit is contained in:
parent
578f829eb2
commit
881c6edfe7
|
@ -0,0 +1,36 @@
|
|||
AllCops:
|
||||
Excludes:
|
||||
- vendor/**
|
||||
- bin/**
|
||||
- .bundle/**
|
||||
|
||||
LineLength:
|
||||
Enabled: false
|
||||
|
||||
MethodLength:
|
||||
Enabled: false
|
||||
|
||||
ClassLength:
|
||||
Enabled: false
|
||||
|
||||
Documentation:
|
||||
# don't require classes to be documented
|
||||
Enabled: false
|
||||
|
||||
Encoding:
|
||||
# no need to always specify encoding
|
||||
Enabled: false
|
||||
|
||||
Lambda:
|
||||
# TODO: replace all lambda with -> or Proc
|
||||
Enabled: false
|
||||
|
||||
CyclomaticComplexity:
|
||||
Enabled: false
|
||||
|
||||
DoubleNegation:
|
||||
Enabled: false
|
||||
|
||||
CaseEquality:
|
||||
Enabled: false
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
## Next Release
|
||||
|
||||
* Removed support for Ruby 1.8.7 - [@dblock](https://github.com/dblock).
|
||||
* Ruby style now enforced with Rubocop - [@dblock](https://github.com/dblock).
|
||||
* [#107](https://github.com/intridea/hashie/pull/107): Fixed excessive value conversions causing poor performance of deep merge in Hashie::Mash - [@davemitchell](https://github.com/dblock), [@dblock](https://github.com/dblock).
|
||||
* [#69](https://github.com/intridea/hashie/issues/69): Fixed assigning multiple properties in Hashie::Trash - [@einzige](https://github.com/einzige).
|
||||
* [#100](https://github.com/intridea/hashie/pull/100): IndifferentAccess#store will respect indifference - [@jrochkind](https://github.com/jrochkind).
|
||||
|
|
6
Rakefile
6
Rakefile
|
@ -6,8 +6,10 @@ Bundler::GemHelper.install_tasks
|
|||
|
||||
require 'rspec/core/rake_task'
|
||||
RSpec::Core::RakeTask.new do |spec|
|
||||
# spec.libs << 'lib' << 'spec'
|
||||
spec.pattern = 'spec/**/*_spec.rb'
|
||||
end
|
||||
|
||||
task :default => :spec
|
||||
require 'rubocop/rake_task'
|
||||
Rubocop::RakeTask.new(:rubocop)
|
||||
|
||||
task default: [:rubocop, :spec]
|
||||
|
|
|
@ -3,10 +3,10 @@ require 'hashie/hash'
|
|||
module Hashie
|
||||
#
|
||||
# A Clash is a "Chainable Lazy Hash". Inspired by libraries such as Arel,
|
||||
# a Clash allows you to chain together method arguments to build a
|
||||
# a Clash allows you to chain together method arguments to build a
|
||||
# hash, something that's especially useful if you're doing something
|
||||
# like constructing a complex options hash. Here's a basic example:
|
||||
#
|
||||
#
|
||||
# c = Hashie::Clash.new.conditions(:foo => 'bar').order(:created_at)
|
||||
# c # => {:conditions => {:foo => 'bar'}, :order => :created_at}
|
||||
#
|
||||
|
@ -25,7 +25,7 @@ module Hashie
|
|||
class ChainError < ::StandardError; end
|
||||
# The parent Clash if this Clash was created via chaining.
|
||||
attr_reader :_parent
|
||||
|
||||
|
||||
# Initialize a new clash by passing in a Hash to
|
||||
# convert and, optionally, the parent to which this
|
||||
# Clash is chained.
|
||||
|
@ -35,7 +35,7 @@ module Hashie
|
|||
self[k.to_sym] = v
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# Jump back up a level if you are using bang method
|
||||
# chaining. For example:
|
||||
#
|
||||
|
@ -43,44 +43,44 @@ module Hashie
|
|||
# c.baz!.foo(123) # => c[:baz]
|
||||
# c.baz!._end! # => c
|
||||
def _end!
|
||||
self._parent
|
||||
_parent
|
||||
end
|
||||
|
||||
|
||||
def id(*args) #:nodoc:
|
||||
method_missing(:id, *args)
|
||||
end
|
||||
|
||||
|
||||
def merge_store(key, *args) #:nodoc:
|
||||
case args.length
|
||||
when 1
|
||||
val = args.first
|
||||
val = self[key].merge(val) if self[key].is_a?(::Hash) && val.is_a?(::Hash)
|
||||
else
|
||||
val = args
|
||||
when 1
|
||||
val = args.first
|
||||
val = self[key].merge(val) if self[key].is_a?(::Hash) && val.is_a?(::Hash)
|
||||
else
|
||||
val = args
|
||||
end
|
||||
|
||||
self[key.to_sym] = val
|
||||
self
|
||||
end
|
||||
|
||||
|
||||
def method_missing(name, *args) #:nodoc:
|
||||
name = name.to_s
|
||||
if name.match(/!$/) && args.empty?
|
||||
key = name[0...-1].to_sym
|
||||
|
||||
|
||||
if self[key].nil?
|
||||
self[key] = Clash.new({}, self)
|
||||
elsif self[key].is_a?(::Hash) && !self[key].is_a?(Clash)
|
||||
self[key] = Clash.new(self[key], self)
|
||||
else
|
||||
raise ChainError, "Tried to chain into a non-hash key."
|
||||
fail ChainError, 'Tried to chain into a non-hash key.'
|
||||
end
|
||||
|
||||
|
||||
self[key]
|
||||
elsif args.any?
|
||||
key = name.to_sym
|
||||
self.merge_store(key, *args)
|
||||
merge_store(key, *args)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -30,17 +30,17 @@ module Hashie
|
|||
def self.property(property_name, options = {})
|
||||
property_name = property_name.to_sym
|
||||
|
||||
self.properties << property_name
|
||||
properties << property_name
|
||||
|
||||
if options.has_key?(:default)
|
||||
self.defaults[property_name] = options[:default]
|
||||
elsif self.defaults.has_key?(property_name)
|
||||
self.defaults.delete property_name
|
||||
if options.key?(:default)
|
||||
defaults[property_name] = options[:default]
|
||||
elsif defaults.key?(property_name)
|
||||
defaults.delete property_name
|
||||
end
|
||||
|
||||
unless instance_methods.map { |m| m.to_s }.include?("#{property_name}=")
|
||||
define_method(property_name) { |&block| self.[](property_name.to_s, &block) }
|
||||
property_assignment = property_name.to_s.concat("=").to_sym
|
||||
property_assignment = property_name.to_s.concat('=').to_sym
|
||||
define_method(property_assignment) { |value| self.[]=(property_name.to_s, value) }
|
||||
end
|
||||
|
||||
|
@ -61,9 +61,9 @@ module Hashie
|
|||
def self.inherited(klass)
|
||||
super
|
||||
(@subclasses ||= Set.new) << klass
|
||||
klass.instance_variable_set('@properties', self.properties.dup)
|
||||
klass.instance_variable_set('@defaults', self.defaults.dup)
|
||||
klass.instance_variable_set('@required_properties', self.required_properties.dup)
|
||||
klass.instance_variable_set('@properties', properties.dup)
|
||||
klass.instance_variable_set('@defaults', defaults.dup)
|
||||
klass.instance_variable_set('@required_properties', required_properties.dup)
|
||||
end
|
||||
|
||||
# Check to see if the specified property has already been
|
||||
|
@ -122,15 +122,15 @@ module Hashie
|
|||
end
|
||||
|
||||
def merge(other_hash)
|
||||
new_dash = self.dup
|
||||
other_hash.each do |k,v|
|
||||
new_dash = dup
|
||||
other_hash.each do |k, v|
|
||||
new_dash[k] = block_given? ? yield(k, self[k], v) : v
|
||||
end
|
||||
new_dash
|
||||
end
|
||||
|
||||
def merge!(other_hash)
|
||||
other_hash.each do |k,v|
|
||||
other_hash.each do |k, v|
|
||||
self[k] = block_given? ? yield(k, self[k], v) : v
|
||||
end
|
||||
self
|
||||
|
@ -145,35 +145,34 @@ module Hashie
|
|||
|
||||
private
|
||||
|
||||
def initialize_attributes(attributes)
|
||||
attributes.each_pair do |att, value|
|
||||
self[att] = value
|
||||
end if attributes
|
||||
end
|
||||
def initialize_attributes(attributes)
|
||||
attributes.each_pair do |att, value|
|
||||
self[att] = value
|
||||
end if attributes
|
||||
end
|
||||
|
||||
def assert_property_exists!(property)
|
||||
unless self.class.property?(property)
|
||||
raise NoMethodError, "The property '#{property}' is not defined for this Dash."
|
||||
end
|
||||
def assert_property_exists!(property)
|
||||
unless self.class.property?(property)
|
||||
fail NoMethodError, "The property '#{property}' is not defined for this Dash."
|
||||
end
|
||||
end
|
||||
|
||||
def assert_required_properties_set!
|
||||
self.class.required_properties.each do |required_property|
|
||||
assert_property_set!(required_property)
|
||||
end
|
||||
def assert_required_properties_set!
|
||||
self.class.required_properties.each do |required_property|
|
||||
assert_property_set!(required_property)
|
||||
end
|
||||
end
|
||||
|
||||
def assert_property_set!(property)
|
||||
if send(property).nil?
|
||||
raise ArgumentError, "The property '#{property}' is required for this Dash."
|
||||
end
|
||||
def assert_property_set!(property)
|
||||
if send(property).nil?
|
||||
fail ArgumentError, "The property '#{property}' is required for this Dash."
|
||||
end
|
||||
end
|
||||
|
||||
def assert_property_required!(property, value)
|
||||
if self.class.required?(property) && value.nil?
|
||||
raise ArgumentError, "The property '#{property}' is required for this Dash."
|
||||
end
|
||||
def assert_property_required!(property, value)
|
||||
if self.class.required?(property) && value.nil?
|
||||
fail ArgumentError, "The property '#{property}' is required for this Dash."
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,7 +21,7 @@ module Hashie
|
|||
super(key, value)
|
||||
end
|
||||
|
||||
def custom_writer(key, value, convert=true)
|
||||
def custom_writer(key, value, convert = true)
|
||||
self[key] = value
|
||||
end
|
||||
|
||||
|
@ -53,7 +53,7 @@ module Hashie
|
|||
attrs.each { |key| @key_coercions[key] = into }
|
||||
end
|
||||
|
||||
alias :coerce_keys :coerce_key
|
||||
alias_method :coerce_keys, :coerce_key
|
||||
|
||||
# Returns a hash of any existing key coercions.
|
||||
def key_coercions
|
||||
|
@ -87,7 +87,7 @@ module Hashie
|
|||
# end
|
||||
# end
|
||||
def coerce_value(from, into, options = {})
|
||||
options = {:strict => true}.merge(options)
|
||||
options = { strict: true }.merge(options)
|
||||
|
||||
if options[:strict]
|
||||
(@strict_value_coercions ||= {})[from] = into
|
||||
|
@ -100,9 +100,13 @@ module Hashie
|
|||
end
|
||||
|
||||
# Return all value coercions that have the :strict rule as true.
|
||||
def strict_value_coercions; @strict_value_coercions || {} end
|
||||
def strict_value_coercions
|
||||
@strict_value_coercions || {}
|
||||
end
|
||||
# Return all value coercions that have the :strict rule as false.
|
||||
def lenient_value_coercions; @value_coercions || {} end
|
||||
def lenient_value_coercions
|
||||
@value_coercions || {}
|
||||
end
|
||||
|
||||
# Fetch the value coercion, if any, for the specified object.
|
||||
def value_coercion(value)
|
||||
|
|
|
@ -3,7 +3,7 @@ module Hashie
|
|||
module DeepMerge
|
||||
# Returns a new hash with +self+ and +other_hash+ merged recursively.
|
||||
def deep_merge(other_hash)
|
||||
self.dup.deep_merge!(other_hash)
|
||||
dup.deep_merge!(other_hash)
|
||||
end
|
||||
|
||||
# Returns a new hash with +self+ and +other_hash+ merged recursively.
|
||||
|
@ -18,7 +18,7 @@ module Hashie
|
|||
def _recursive_merge(hash, other_hash)
|
||||
if other_hash.is_a?(::Hash) && hash.is_a?(::Hash)
|
||||
other_hash.each do |k, v|
|
||||
hash[k] = hash.has_key?(k) ? _recursive_merge(hash[k], v) : v
|
||||
hash[k] = hash.key?(k) ? _recursive_merge(hash[k], v) : v
|
||||
end
|
||||
hash
|
||||
else
|
||||
|
|
|
@ -62,7 +62,7 @@ module Hashie
|
|||
# is injecting itself into member hashes.
|
||||
def convert!
|
||||
keys.each do |k|
|
||||
regular_writer convert_key(k), convert_value(self.regular_delete(k))
|
||||
regular_writer convert_key(k), convert_value(regular_delete(k))
|
||||
end
|
||||
self
|
||||
end
|
||||
|
@ -76,7 +76,7 @@ module Hashie
|
|||
value
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def indifferent_default(key = nil)
|
||||
return self[convert_key(key)] if key?(key)
|
||||
regular_default(key)
|
||||
|
@ -84,18 +84,34 @@ module Hashie
|
|||
|
||||
def indifferent_update(other_hash)
|
||||
return regular_update(other_hash) if hash_with_indifference?(other_hash)
|
||||
other_hash.each_pair do |k,v|
|
||||
other_hash.each_pair do |k, v|
|
||||
self[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
def indifferent_writer(key, value); regular_writer convert_key(key), convert_value(value) end
|
||||
def indifferent_fetch(key, *args); regular_fetch convert_key(key), *args end
|
||||
def indifferent_delete(key); regular_delete convert_key(key) end
|
||||
def indifferent_key?(key); regular_key? convert_key(key) end
|
||||
def indifferent_values_at(*indices); indices.map{|i| self[i] } end
|
||||
|
||||
def indifferent_access?; true end
|
||||
def indifferent_writer(key, value)
|
||||
regular_writer convert_key(key), convert_value(value)
|
||||
end
|
||||
|
||||
def indifferent_fetch(key, *args)
|
||||
regular_fetch convert_key(key), *args
|
||||
end
|
||||
|
||||
def indifferent_delete(key)
|
||||
regular_delete convert_key(key)
|
||||
end
|
||||
|
||||
def indifferent_key?(key)
|
||||
regular_key? convert_key(key)
|
||||
end
|
||||
|
||||
def indifferent_values_at(*indices)
|
||||
indices.map { |i| self[i] }
|
||||
end
|
||||
|
||||
def indifferent_access?
|
||||
true
|
||||
end
|
||||
|
||||
def indifferent_replace(other_hash)
|
||||
(keys - other_hash.keys).each { |key| delete(key) }
|
||||
|
|
|
@ -10,7 +10,7 @@ module Hashie
|
|||
def stringify_keys!
|
||||
keys.each do |k|
|
||||
stringify_keys_recursively!(self[k])
|
||||
self[k.to_s] = self.delete(k)
|
||||
self[k.to_s] = delete(k)
|
||||
end
|
||||
self
|
||||
end
|
||||
|
@ -51,7 +51,7 @@ module Hashie
|
|||
def symbolize_keys!
|
||||
keys.each do |k|
|
||||
symbolize_keys_recursively!(self[k])
|
||||
self[k.to_sym] = self.delete(k)
|
||||
self[k.to_sym] = delete(k)
|
||||
end
|
||||
self
|
||||
end
|
||||
|
@ -81,7 +81,7 @@ module Hashie
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
module KeyConversion
|
||||
def self.included(base)
|
||||
base.send :include, SymbolizeKeys
|
||||
|
|
|
@ -5,8 +5,8 @@ module Hashie
|
|||
# to access your hash's keys. It will recognize keys
|
||||
# either as strings or symbols.
|
||||
#
|
||||
# Note that while nil keys will be returned as nil,
|
||||
# undefined keys will raise NoMethodErrors. Also note that
|
||||
# Note that while nil keys will be returned as nil,
|
||||
# undefined keys will raise NoMethodErrors. Also note that
|
||||
# #respond_to? has been patched to appropriately recognize
|
||||
# key methods.
|
||||
#
|
||||
|
@ -18,9 +18,9 @@ module Hashie
|
|||
# user = User.new
|
||||
# user['first_name'] = 'Michael'
|
||||
# user.first_name # => 'Michael'
|
||||
#
|
||||
#
|
||||
# user[:last_name] = 'Bleigh'
|
||||
# user.last_name # => 'Bleigh'
|
||||
# user.last_name # => 'Bleigh'
|
||||
#
|
||||
# user[:birthday] = nil
|
||||
# user.birthday # => nil
|
||||
|
@ -31,7 +31,7 @@ module Hashie
|
|||
return true if key?(name.to_s) || key?(name.to_sym)
|
||||
super
|
||||
end
|
||||
|
||||
|
||||
def method_missing(name, *args)
|
||||
return self[name.to_s] if key?(name.to_s)
|
||||
return self[name.to_sym] if key?(name.to_sym)
|
||||
|
@ -64,7 +64,7 @@ module Hashie
|
|||
|
||||
def method_missing(name, *args)
|
||||
if args.size == 1 && name.to_s =~ /(.*)=$/
|
||||
return self[convert_key($1)] = args.first
|
||||
return self[convert_key(Regexp.last_match[1])] = args.first
|
||||
end
|
||||
|
||||
super
|
||||
|
@ -97,13 +97,13 @@ module Hashie
|
|||
# h.hji? # => NoMethodError
|
||||
module MethodQuery
|
||||
def respond_to?(name, include_private = false)
|
||||
return true if name.to_s =~ /(.*)\?$/ && (key?($1) || key?($1.to_sym))
|
||||
return true if name.to_s =~ /(.*)\?$/ && (key?(Regexp.last_match[1]) || key?(Regexp.last_match[1].to_sym))
|
||||
super
|
||||
end
|
||||
|
||||
def method_missing(name, *args)
|
||||
if args.empty? && name.to_s =~ /(.*)\?$/ && (key?($1) || key?($1.to_sym))
|
||||
return self[$1] || self[$1.to_sym]
|
||||
if args.empty? && name.to_s =~ /(.*)\?$/ && (key?(Regexp.last_match[1]) || key?(Regexp.last_match[1].to_sym))
|
||||
return self[Regexp.last_match[1]] || self[Regexp.last_match[1].to_sym]
|
||||
end
|
||||
|
||||
super
|
||||
|
|
|
@ -28,6 +28,8 @@ module Hashie
|
|||
end
|
||||
|
||||
module ClassMethods
|
||||
attr_reader :permitted_keys
|
||||
|
||||
def key(key, options = {})
|
||||
(@permitted_keys ||= []) << key
|
||||
|
||||
|
@ -37,10 +39,6 @@ module Hashie
|
|||
|
||||
permitted_keys
|
||||
end
|
||||
|
||||
def permitted_keys
|
||||
@permitted_keys
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,7 +8,7 @@ module Hashie
|
|||
include HashExtensions
|
||||
|
||||
# Converts a mash back to a hash (with stringified or symbolized keys)
|
||||
def to_hash(options={})
|
||||
def to_hash(options = {})
|
||||
out = {}
|
||||
keys.each do |k|
|
||||
assignment_key = k.to_s
|
||||
|
|
|
@ -11,10 +11,8 @@ module Hashie
|
|||
# Destructively convert all of the keys of a Hash
|
||||
# to their string representations.
|
||||
def hashie_stringify_keys!
|
||||
self.keys.each do |k|
|
||||
unless String === k
|
||||
self[k.to_s] = self.delete(k)
|
||||
end
|
||||
keys.each do |k|
|
||||
self[k.to_s] = delete(k) unless String === k
|
||||
end
|
||||
self
|
||||
end
|
||||
|
@ -22,7 +20,7 @@ module Hashie
|
|||
# Convert all of the keys of a Hash
|
||||
# to their string representations.
|
||||
def hashie_stringify_keys
|
||||
self.dup.stringify_keys!
|
||||
dup.stringify_keys!
|
||||
end
|
||||
|
||||
# Convert this hash into a Mash
|
||||
|
@ -38,11 +36,11 @@ module Hashie
|
|||
end
|
||||
|
||||
def hashie_inspect
|
||||
ret = "#<#{self.class.to_s}"
|
||||
ret = "#<#{self.class}"
|
||||
stringify_keys.keys.sort.each do |key|
|
||||
ret << " #{key}=#{self[key].inspect}"
|
||||
end
|
||||
ret << ">"
|
||||
ret << '>'
|
||||
ret
|
||||
end
|
||||
end
|
||||
|
|
|
@ -68,14 +68,14 @@ module Hashie
|
|||
default ? super(default) : super(&blk)
|
||||
end
|
||||
|
||||
class << self; alias [] new; end
|
||||
class << self; alias_method :[], :new; end
|
||||
|
||||
def id #:nodoc:
|
||||
self["id"]
|
||||
self['id']
|
||||
end
|
||||
|
||||
def type #:nodoc:
|
||||
self["type"]
|
||||
self['type']
|
||||
end
|
||||
|
||||
alias_method :regular_reader, :[]
|
||||
|
@ -92,7 +92,7 @@ module Hashie
|
|||
# Sets an attribute in the Mash. Key will be converted to
|
||||
# a string before it is set, and Hashes will be converted
|
||||
# into Mashes for nesting purposes.
|
||||
def custom_writer(key,value,convert=true) #:nodoc:
|
||||
def custom_writer(key, value, convert = true) #:nodoc:
|
||||
regular_writer(convert_key(key), convert ? convert_value(value) : value)
|
||||
end
|
||||
|
||||
|
@ -129,7 +129,7 @@ module Hashie
|
|||
alias_method :regular_dup, :dup
|
||||
# Duplicates the current mash as a new mash.
|
||||
def dup
|
||||
self.class.new(self, self.default)
|
||||
self.class.new(self, default)
|
||||
end
|
||||
|
||||
def key?(key)
|
||||
|
@ -149,9 +149,9 @@ module Hashie
|
|||
# Recursively merges this mash with the passed
|
||||
# in hash, merging each hash in the hierarchy.
|
||||
def deep_update(other_hash, &blk)
|
||||
other_hash.each_pair do |k,v|
|
||||
other_hash.each_pair do |k, v|
|
||||
key = convert_key(k)
|
||||
if regular_reader(key).is_a?(Mash) and v.is_a?(::Hash)
|
||||
if regular_reader(key).is_a?(Mash) && v.is_a?(::Hash)
|
||||
custom_reader(key).deep_update(v, &blk)
|
||||
else
|
||||
value = convert_value(v, true)
|
||||
|
@ -173,7 +173,7 @@ module Hashie
|
|||
# Merges (non-recursively) the hash from the argument,
|
||||
# changing the receiving hash
|
||||
def shallow_update(other_hash)
|
||||
other_hash.each_pair do |k,v|
|
||||
other_hash.each_pair do |k, v|
|
||||
regular_writer(convert_key(k), convert_value(v, true))
|
||||
end
|
||||
self
|
||||
|
@ -187,12 +187,11 @@ module Hashie
|
|||
|
||||
# Will return true if the Mash has had a key
|
||||
# set in addition to normal respond_to? functionality.
|
||||
def respond_to?(method_name, include_private=false)
|
||||
def respond_to?(method_name, include_private = false)
|
||||
return true if key?(method_name) || prefix_method?(method_name)
|
||||
super
|
||||
end
|
||||
|
||||
|
||||
def prefix_method?(method_name)
|
||||
method_name = method_name.to_s
|
||||
method_name.end_with?(*ALLOWED_SUFFIXES) && key?(method_name.chop)
|
||||
|
@ -203,13 +202,13 @@ module Hashie
|
|||
suffixes_regex = ALLOWED_SUFFIXES.join
|
||||
match = method_name.to_s.match(/(.*?)([#{suffixes_regex}]?)$/)
|
||||
case match[2]
|
||||
when "="
|
||||
when '='
|
||||
self[match[1]] = args.first
|
||||
when "?"
|
||||
when '?'
|
||||
!!self[match[1]]
|
||||
when "!"
|
||||
when '!'
|
||||
initializing_reader(match[1])
|
||||
when "_"
|
||||
when '_'
|
||||
underbang_reader(match[1])
|
||||
else
|
||||
default(method_name)
|
||||
|
@ -222,19 +221,19 @@ module Hashie
|
|||
key.to_s
|
||||
end
|
||||
|
||||
def convert_value(val, duping=false) #:nodoc:
|
||||
def convert_value(val, duping = false) #:nodoc:
|
||||
case val
|
||||
when self.class
|
||||
val.dup
|
||||
when Hash
|
||||
duping ? val.dup : val
|
||||
when ::Hash
|
||||
val = val.dup if duping
|
||||
self.class.new(val)
|
||||
when Array
|
||||
val.collect{ |e| convert_value(e) }
|
||||
else
|
||||
val
|
||||
when self.class
|
||||
val.dup
|
||||
when Hash
|
||||
duping ? val.dup : val
|
||||
when ::Hash
|
||||
val = val.dup if duping
|
||||
self.class.new(val)
|
||||
when Array
|
||||
val.map { |e| convert_value(e) }
|
||||
else
|
||||
val
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,7 +8,6 @@ module Hashie
|
|||
# such as a Java api, where the keys are named differently from how we would
|
||||
# in Ruby.
|
||||
class Trash < Dash
|
||||
|
||||
# Defines a property on the Trash. Options are as follows:
|
||||
#
|
||||
# * <tt>:default</tt> - Specify a default value for this property, to be
|
||||
|
@ -25,7 +24,7 @@ module Hashie
|
|||
|
||||
if options[:from]
|
||||
if property_name == options[:from]
|
||||
raise ArgumentError, "Property name (#{property_name}) and :from option must not be the same"
|
||||
fail ArgumentError, "Property name (#{property_name}) and :from option must not be the same"
|
||||
end
|
||||
|
||||
translations[options[:from]] ||= {}
|
||||
|
@ -33,8 +32,8 @@ module Hashie
|
|||
|
||||
# NOTE: may overwrite existing method multiple times
|
||||
define_method "#{options[:from]}=" do |val|
|
||||
self.class.translations[options[:from]].each do |property_name, with|
|
||||
self[property_name] = with.respond_to?(:call) ? with.call(val) : val
|
||||
self.class.translations[options[:from]].each do |name, with|
|
||||
self[name] = with.respond_to?(:call) ? with.call(val) : val
|
||||
end
|
||||
end
|
||||
else
|
||||
|
@ -74,7 +73,7 @@ module Hashie
|
|||
#
|
||||
def property_exists?(property)
|
||||
unless self.class.property?(property.to_sym)
|
||||
raise NoMethodError, "The property '#{property}' is not defined for this Trash."
|
||||
fail NoMethodError, "The property '#{property}' is not defined for this Trash."
|
||||
end
|
||||
true
|
||||
end
|
||||
|
@ -84,7 +83,7 @@ module Hashie
|
|||
# Deletes any keys that have a translation
|
||||
def initialize_attributes(attributes)
|
||||
return unless attributes
|
||||
attributes_copy = attributes.dup.delete_if do |k,v|
|
||||
attributes_copy = attributes.dup.delete_if do |k, v|
|
||||
if self.class.translations.include?(k.to_sym)
|
||||
self[k] = v
|
||||
true
|
||||
|
@ -93,4 +92,4 @@ module Hashie
|
|||
super attributes_copy
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,46 +4,46 @@ describe Hashie::Clash do
|
|||
before do
|
||||
@c = Hashie::Clash.new
|
||||
end
|
||||
|
||||
|
||||
it 'should be able to set an attribute via method_missing' do
|
||||
@c.foo('bar')
|
||||
@c[:foo].should == 'bar'
|
||||
@c[:foo].should eq 'bar'
|
||||
end
|
||||
|
||||
|
||||
it 'should be able to set multiple attributes' do
|
||||
@c.foo('bar').baz('wok')
|
||||
@c.should == {:foo => 'bar', :baz => 'wok'}
|
||||
@c.should eq(foo: 'bar', baz: 'wok')
|
||||
end
|
||||
|
||||
|
||||
it 'should convert multiple arguments into an array' do
|
||||
@c.foo(1, 2, 3)
|
||||
@c[:foo].should == [1,2,3]
|
||||
@c[:foo].should eq [1, 2, 3]
|
||||
end
|
||||
|
||||
|
||||
it 'should be able to use bang notation to create a new Clash on a key' do
|
||||
@c.foo!
|
||||
@c[:foo].should be_kind_of(Hashie::Clash)
|
||||
end
|
||||
|
||||
|
||||
it 'should be able to chain onto the new Clash when using bang notation' do
|
||||
@c.foo!.bar('abc').baz(123)
|
||||
@c.should == {:foo => {:bar => 'abc', :baz => 123}}
|
||||
@c.should eq(foo: { bar: 'abc', baz: 123 })
|
||||
end
|
||||
|
||||
|
||||
it 'should be able to jump back up to the parent in the chain with #_end!' do
|
||||
@c.foo!.bar('abc')._end!.baz(123)
|
||||
@c.should == {:foo => {:bar => 'abc'}, :baz => 123}
|
||||
@c.should eq(foo: { bar: 'abc' }, baz: 123)
|
||||
end
|
||||
|
||||
|
||||
it 'should merge rather than replace existing keys' do
|
||||
@c.where(:abc => 'def').where(:hgi => 123)
|
||||
@c.should == {:where => {:abc => 'def', :hgi => 123}}
|
||||
@c.where(abc: 'def').where(hgi: 123)
|
||||
@c.should eq(where: { abc: 'def', hgi: 123 })
|
||||
end
|
||||
|
||||
it 'should be able to replace all of its own keys with #replace' do
|
||||
@c.foo(:bar).hello(:world)
|
||||
@c.replace(:baz => 123, :hgi => 123).should == {:baz => 123, :hgi => 123}
|
||||
@c.should == {:baz => 123, :hgi => 123}
|
||||
@c.replace(baz: 123, hgi: 123).should eq(baz: 123, hgi: 123)
|
||||
@c.should eq(baz: 123, hgi: 123)
|
||||
@c[:foo].should be_nil
|
||||
@c[:hello].should be_nil
|
||||
end
|
||||
|
|
|
@ -7,15 +7,15 @@ Hashie::Hash.class_eval do
|
|||
end
|
||||
|
||||
class DashTest < Hashie::Dash
|
||||
property :first_name, :required => true
|
||||
property :first_name, required: true
|
||||
property :email
|
||||
property :count, :default => 0
|
||||
property :count, default: 0
|
||||
end
|
||||
|
||||
class DashNoRequiredTest < Hashie::Dash
|
||||
property :first_name
|
||||
property :email
|
||||
property :count, :default => 0
|
||||
property :count, default: 0
|
||||
end
|
||||
|
||||
class PropertyBangTest < Hashie::Dash
|
||||
|
@ -23,29 +23,29 @@ class PropertyBangTest < Hashie::Dash
|
|||
end
|
||||
|
||||
class Subclassed < DashTest
|
||||
property :last_name, :required => true
|
||||
property :last_name, required: true
|
||||
end
|
||||
|
||||
class DashDefaultTest < Hashie::Dash
|
||||
property :aliases, :default => ["Snake"]
|
||||
property :aliases, default: ['Snake']
|
||||
end
|
||||
|
||||
class DeferredTest < Hashie::Dash
|
||||
property :created_at, :default => Proc.new { Time.now }
|
||||
property :created_at, default: proc { Time.now }
|
||||
end
|
||||
|
||||
describe DashTest do
|
||||
|
||||
subject { DashTest.new(:first_name => 'Bob', :email => 'bob@example.com') }
|
||||
subject { DashTest.new(first_name: 'Bob', email: 'bob@example.com') }
|
||||
|
||||
it('subclasses Hashie::Hash') { should respond_to(:to_mash) }
|
||||
|
||||
its(:to_s) { should == '#<DashTest count=0 email="bob@example.com" first_name="Bob">' }
|
||||
its(:to_s) { should eq '#<DashTest count=0 email="bob@example.com" first_name="Bob">' }
|
||||
|
||||
it 'lists all set properties in inspect' do
|
||||
subject.first_name = 'Bob'
|
||||
subject.email = 'bob@example.com'
|
||||
subject.inspect.should == '#<DashTest count=0 email="bob@example.com" first_name="Bob">'
|
||||
subject.inspect.should eq '#<DashTest count=0 email="bob@example.com" first_name="Bob">'
|
||||
end
|
||||
|
||||
its(:count) { should be_zero }
|
||||
|
@ -78,13 +78,13 @@ describe DashTest do
|
|||
|
||||
it 'works for an existing property using []=' do
|
||||
subject['first_name'] = 'Bob'
|
||||
subject['first_name'].should == 'Bob'
|
||||
subject[:first_name].should == 'Bob'
|
||||
subject['first_name'].should eq 'Bob'
|
||||
subject[:first_name].should eq 'Bob'
|
||||
end
|
||||
|
||||
it 'works for an existing property using a method call' do
|
||||
subject.first_name = 'Franklin'
|
||||
subject.first_name.should == 'Franklin'
|
||||
subject.first_name.should eq 'Franklin'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -93,18 +93,18 @@ describe DashTest do
|
|||
lambda { subject['nonexistent'] }.should raise_error(NoMethodError)
|
||||
end
|
||||
|
||||
it "should be able to retrieve properties through blocks" do
|
||||
subject["first_name"] = "Aiden"
|
||||
it 'should be able to retrieve properties through blocks' do
|
||||
subject['first_name'] = 'Aiden'
|
||||
value = nil
|
||||
subject.[]("first_name") { |v| value = v }
|
||||
value.should == "Aiden"
|
||||
subject.[]('first_name') { |v| value = v }
|
||||
value.should eq 'Aiden'
|
||||
end
|
||||
|
||||
it "should be able to retrieve properties through blocks with method calls" do
|
||||
subject["first_name"] = "Frodo"
|
||||
it 'should be able to retrieve properties through blocks with method calls' do
|
||||
subject['first_name'] = 'Frodo'
|
||||
value = nil
|
||||
subject.first_name { |v| value = v }
|
||||
value.should == "Frodo"
|
||||
value.should eq 'Frodo'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -113,20 +113,20 @@ describe DashTest do
|
|||
DeferredTest.new['created_at'].should be_instance_of(Time)
|
||||
end
|
||||
|
||||
it "should not evalute proc after subsequent reads" do
|
||||
it 'should not evalute proc after subsequent reads' do
|
||||
deferred = DeferredTest.new
|
||||
deferred['created_at'].object_id.should == deferred['created_at'].object_id
|
||||
deferred['created_at'].object_id.should eq deferred['created_at'].object_id
|
||||
end
|
||||
end
|
||||
|
||||
describe '.new' do
|
||||
it 'fails with non-existent properties' do
|
||||
lambda { described_class.new(:bork => '') }.should raise_error(NoMethodError)
|
||||
lambda { described_class.new(bork: '') }.should raise_error(NoMethodError)
|
||||
end
|
||||
|
||||
it 'should set properties that it is able to' do
|
||||
obj = described_class.new :first_name => 'Michael'
|
||||
obj.first_name.should == 'Michael'
|
||||
obj = described_class.new first_name: 'Michael'
|
||||
obj.first_name.should eq 'Michael'
|
||||
end
|
||||
|
||||
it 'accepts nil' do
|
||||
|
@ -135,83 +135,83 @@ describe DashTest do
|
|||
|
||||
it 'accepts block to define a global default' do
|
||||
obj = described_class.new { |hash, key| key.to_s.upcase }
|
||||
obj.first_name.should == 'FIRST_NAME'
|
||||
obj.first_name.should eq 'FIRST_NAME'
|
||||
obj.count.should be_zero
|
||||
end
|
||||
|
||||
it "fails when required values are missing" do
|
||||
it 'fails when required values are missing' do
|
||||
expect { DashTest.new }.to raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
it "does not overwrite default values" do
|
||||
it 'does not overwrite default values' do
|
||||
obj1 = DashDefaultTest.new
|
||||
obj1.aliases << "El Rey"
|
||||
obj1.aliases << 'El Rey'
|
||||
obj2 = DashDefaultTest.new
|
||||
obj2.aliases.should_not include "El Rey"
|
||||
obj2.aliases.should_not include 'El Rey'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#merge' do
|
||||
it 'creates a new instance of the Dash' do
|
||||
new_dash = subject.merge(:first_name => 'Robert')
|
||||
subject.object_id.should_not == new_dash.object_id
|
||||
new_dash = subject.merge(first_name: 'Robert')
|
||||
subject.object_id.should_not eq new_dash.object_id
|
||||
end
|
||||
|
||||
it 'merges the given hash' do
|
||||
new_dash = subject.merge(:first_name => 'Robert', :email => 'robert@example.com')
|
||||
new_dash.first_name.should == 'Robert'
|
||||
new_dash.email.should == 'robert@example.com'
|
||||
new_dash = subject.merge(first_name: 'Robert', email: 'robert@example.com')
|
||||
new_dash.first_name.should eq 'Robert'
|
||||
new_dash.email.should eq 'robert@example.com'
|
||||
end
|
||||
|
||||
it 'fails with non-existent properties' do
|
||||
expect { subject.merge(:middle_name => 'James') }.to raise_error(NoMethodError)
|
||||
expect { subject.merge(middle_name: 'James') }.to raise_error(NoMethodError)
|
||||
end
|
||||
|
||||
it 'errors out when attempting to set a required property to nil' do
|
||||
expect { subject.merge(:first_name => nil) }.to raise_error(ArgumentError)
|
||||
expect { subject.merge(first_name: nil) }.to raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
context "given a block" do
|
||||
context 'given a block' do
|
||||
it "sets merged key's values to the block's return value" do
|
||||
subject.merge(:first_name => 'Jim') do |key, oldval, newval|
|
||||
subject.merge(first_name: 'Jim') do |key, oldval, newval|
|
||||
"#{key}: #{newval} #{oldval}"
|
||||
end.first_name.should == 'first_name: Jim Bob'
|
||||
end.first_name.should eq 'first_name: Jim Bob'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#merge!' do
|
||||
it 'modifies the existing instance of the Dash' do
|
||||
original_dash = subject.merge!(:first_name => 'Robert')
|
||||
subject.object_id.should == original_dash.object_id
|
||||
original_dash = subject.merge!(first_name: 'Robert')
|
||||
subject.object_id.should eq original_dash.object_id
|
||||
end
|
||||
|
||||
it 'merges the given hash' do
|
||||
subject.merge!(:first_name => 'Robert', :email => 'robert@example.com')
|
||||
subject.first_name.should == 'Robert'
|
||||
subject.email.should == 'robert@example.com'
|
||||
subject.merge!(first_name: 'Robert', email: 'robert@example.com')
|
||||
subject.first_name.should eq 'Robert'
|
||||
subject.email.should eq 'robert@example.com'
|
||||
end
|
||||
|
||||
it 'fails with non-existent properties' do
|
||||
expect { subject.merge!(:middle_name => 'James') }.to raise_error(NoMethodError)
|
||||
expect { subject.merge!(middle_name: 'James') }.to raise_error(NoMethodError)
|
||||
end
|
||||
|
||||
it 'errors out when attempting to set a required property to nil' do
|
||||
expect { subject.merge!(:first_name => nil) }.to raise_error(ArgumentError)
|
||||
expect { subject.merge!(first_name: nil) }.to raise_error(ArgumentError)
|
||||
end
|
||||
|
||||
context "given a block" do
|
||||
context 'given a block' do
|
||||
it "sets merged key's values to the block's return value" do
|
||||
subject.merge!(:first_name => 'Jim') do |key, oldval, newval|
|
||||
subject.merge!(first_name: 'Jim') do |key, oldval, newval|
|
||||
"#{key}: #{newval} #{oldval}"
|
||||
end.first_name.should == 'first_name: Jim Bob'
|
||||
end.first_name.should eq 'first_name: Jim Bob'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'properties' do
|
||||
it 'lists defined properties' do
|
||||
described_class.properties.should == Set.new([:first_name, :email, :count])
|
||||
described_class.properties.should eq Set.new([:first_name, :email, :count])
|
||||
end
|
||||
|
||||
it 'checks if a property exists' do
|
||||
|
@ -229,7 +229,7 @@ describe DashTest do
|
|||
end
|
||||
|
||||
it 'lists declared defaults' do
|
||||
described_class.defaults.should == { :count => 0 }
|
||||
described_class.defaults.should eq(count: 0)
|
||||
end
|
||||
|
||||
it 'allows properties that end in bang' do
|
||||
|
@ -238,28 +238,27 @@ describe DashTest do
|
|||
end
|
||||
|
||||
describe '#replace' do
|
||||
before { subject.replace(:first_name => "Cain") }
|
||||
before { subject.replace(first_name: 'Cain') }
|
||||
|
||||
it 'return self' do
|
||||
subject.replace(:email => "bar").to_hash.
|
||||
should == {"email" => "bar", "count" => 0}
|
||||
subject.replace(email: 'bar').to_hash.should eq('email' => 'bar', 'count' => 0)
|
||||
end
|
||||
|
||||
it 'sets all specified keys to their corresponding values' do
|
||||
subject.first_name.should == "Cain"
|
||||
subject.first_name.should eq 'Cain'
|
||||
end
|
||||
|
||||
it 'leaves only specified keys and keys with default values' do
|
||||
subject.keys.sort.should == ['count', 'first_name']
|
||||
subject.keys.sort.should eq %w(count first_name)
|
||||
subject.email.should be_nil
|
||||
subject.count.should == 0
|
||||
subject.count.should eq 0
|
||||
end
|
||||
|
||||
context 'when replacing keys with default values' do
|
||||
before { subject.replace(:count => 3) }
|
||||
before { subject.replace(count: 3) }
|
||||
|
||||
it 'sets all specified keys to their corresponding values' do
|
||||
subject.count.should == 3
|
||||
subject.count.should eq 3
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -291,21 +290,21 @@ describe Hashie::Dash, 'inheritance' do
|
|||
|
||||
it 'allows overriding a default on an existing property' do
|
||||
@top.property :echo
|
||||
@middle.property :echo, :default => 123
|
||||
@bottom.properties.to_a.should == [:echo]
|
||||
@bottom.new.echo.should == 123
|
||||
@middle.property :echo, default: 123
|
||||
@bottom.properties.to_a.should eq [:echo]
|
||||
@bottom.new.echo.should eq 123
|
||||
end
|
||||
|
||||
it 'allows clearing an existing default' do
|
||||
@top.property :echo
|
||||
@middle.property :echo, :default => 123
|
||||
@middle.property :echo, default: 123
|
||||
@bottom.property :echo
|
||||
@bottom.properties.to_a.should == [:echo]
|
||||
@bottom.properties.to_a.should eq [:echo]
|
||||
@bottom.new.echo.should be_nil
|
||||
end
|
||||
|
||||
it 'should allow nil defaults' do
|
||||
@bottom.property :echo, :default => nil
|
||||
@bottom.property :echo, default: nil
|
||||
@bottom.new.should have_key('echo')
|
||||
end
|
||||
|
||||
|
@ -313,7 +312,7 @@ end
|
|||
|
||||
describe Subclassed do
|
||||
|
||||
subject { Subclassed.new(:first_name => 'Bob', :last_name => 'McNob', :email => 'bob@example.com') }
|
||||
subject { Subclassed.new(first_name: 'Bob', last_name: 'McNob', email: 'bob@example.com') }
|
||||
|
||||
its(:count) { should be_zero }
|
||||
|
||||
|
|
|
@ -2,12 +2,16 @@ require 'spec_helper'
|
|||
|
||||
describe Hashie::Extensions::Coercion do
|
||||
class Initializable
|
||||
attr_reader :coerced, :value
|
||||
|
||||
def initialize(obj, coerced = false)
|
||||
@coerced = coerced
|
||||
@value = obj.class.to_s
|
||||
end
|
||||
def coerced?; @coerced end
|
||||
attr_reader :value
|
||||
|
||||
def coerced?
|
||||
!!@coerced
|
||||
end
|
||||
end
|
||||
|
||||
class Coercable < Initializable
|
||||
|
@ -22,8 +26,10 @@ describe Hashie::Extensions::Coercion do
|
|||
include Hashie::Extensions::MergeInitializer
|
||||
end
|
||||
end
|
||||
|
||||
subject { ExampleCoercableHash }
|
||||
let(:instance){ subject.new }
|
||||
|
||||
let(:instance) { subject.new }
|
||||
|
||||
describe '.coerce_key' do
|
||||
it { subject.should be_respond_to(:coerce_key) }
|
||||
|
@ -31,15 +37,15 @@ describe Hashie::Extensions::Coercion do
|
|||
it 'should run through coerce on a specified key' do
|
||||
subject.coerce_key :foo, Coercable
|
||||
|
||||
instance[:foo] = "bar"
|
||||
instance[:foo] = 'bar'
|
||||
instance[:foo].should be_coerced
|
||||
end
|
||||
|
||||
it "should support an array of keys" do
|
||||
it 'should support an array of keys' do
|
||||
subject.coerce_keys :foo, :bar, Coercable
|
||||
|
||||
instance[:foo] = "bar"
|
||||
instance[:bar] = "bax"
|
||||
instance[:foo] = 'bar'
|
||||
instance[:bar] = 'bax'
|
||||
instance[:foo].should be_coerced
|
||||
instance[:bar].should be_coerced
|
||||
end
|
||||
|
@ -47,14 +53,14 @@ describe Hashie::Extensions::Coercion do
|
|||
it 'should just call #new if no coerce method is available' do
|
||||
subject.coerce_key :foo, Initializable
|
||||
|
||||
instance[:foo] = "bar"
|
||||
instance[:foo].value.should == "String"
|
||||
instance[:foo] = 'bar'
|
||||
instance[:foo].value.should eq 'String'
|
||||
instance[:foo].should_not be_coerced
|
||||
end
|
||||
|
||||
it "should coerce when the merge initializer is used" do
|
||||
it 'should coerce when the merge initializer is used' do
|
||||
subject.coerce_key :foo, Coercable
|
||||
instance = subject.new(:foo => "bar")
|
||||
instance = subject.new(foo: 'bar')
|
||||
|
||||
instance[:foo].should be_coerced
|
||||
end
|
||||
|
@ -63,22 +69,21 @@ describe Hashie::Extensions::Coercion do
|
|||
before { subject.coerce_key :foo, :bar, Coercable }
|
||||
|
||||
let(:instance) do
|
||||
subject.new(:foo => "bar").
|
||||
replace(:foo => "foz", :bar => "baz", :hi => "bye")
|
||||
subject.new(foo: 'bar').replace(foo: 'foz', bar: 'baz', hi: 'bye')
|
||||
end
|
||||
|
||||
it "should coerce relevant keys" do
|
||||
it 'should coerce relevant keys' do
|
||||
instance[:foo].should be_coerced
|
||||
instance[:bar].should be_coerced
|
||||
instance[:hi].should_not respond_to(:coerced?)
|
||||
end
|
||||
|
||||
it "should set correct values" do
|
||||
instance[:hi].should == "bye"
|
||||
it 'should set correct values' do
|
||||
instance[:hi].should eq 'bye'
|
||||
end
|
||||
end
|
||||
|
||||
context "when used with a Mash" do
|
||||
context 'when used with a Mash' do
|
||||
class UserMash < Hashie::Mash
|
||||
end
|
||||
class TweetMash < Hashie::Mash
|
||||
|
@ -86,26 +91,26 @@ describe Hashie::Extensions::Coercion do
|
|||
coerce_key :user, UserMash
|
||||
end
|
||||
|
||||
it "should coerce with instance initialization" do
|
||||
tweet = TweetMash.new(:user => {:email => 'foo@bar.com'})
|
||||
it 'should coerce with instance initialization' do
|
||||
tweet = TweetMash.new(user: { email: 'foo@bar.com' })
|
||||
tweet[:user].should be_a(UserMash)
|
||||
end
|
||||
|
||||
it "should coerce when setting with attribute style" do
|
||||
it 'should coerce when setting with attribute style' do
|
||||
tweet = TweetMash.new
|
||||
tweet.user = {:email => 'foo@bar.com'}
|
||||
tweet.user = { email: 'foo@bar.com' }
|
||||
tweet[:user].should be_a(UserMash)
|
||||
end
|
||||
|
||||
it "should coerce when setting with string index" do
|
||||
it 'should coerce when setting with string index' do
|
||||
tweet = TweetMash.new
|
||||
tweet['user'] = {:email => 'foo@bar.com'}
|
||||
tweet['user'] = { email: 'foo@bar.com' }
|
||||
tweet[:user].should be_a(UserMash)
|
||||
end
|
||||
|
||||
it "should coerce when setting with symbol index" do
|
||||
it 'should coerce when setting with symbol index' do
|
||||
tweet = TweetMash.new
|
||||
tweet[:user] = {:email => 'foo@bar.com'}
|
||||
tweet[:user] = { email: 'foo@bar.com' }
|
||||
tweet[:user].should be_a(UserMash)
|
||||
end
|
||||
end
|
||||
|
@ -116,8 +121,8 @@ describe Hashie::Extensions::Coercion do
|
|||
it 'should coerce any value of the exact right class' do
|
||||
subject.coerce_value String, Coercable
|
||||
|
||||
instance[:foo] = "bar"
|
||||
instance[:bar] = "bax"
|
||||
instance[:foo] = 'bar'
|
||||
instance[:bar] = 'bax'
|
||||
instance[:hi] = :bye
|
||||
instance[:foo].should be_coerced
|
||||
instance[:bar].should be_coerced
|
||||
|
@ -128,7 +133,7 @@ describe Hashie::Extensions::Coercion do
|
|||
subject.coerce_value String, Coercable
|
||||
|
||||
instance[:foo] = :bar
|
||||
instance.replace(:foo => "bar", :bar => "bax")
|
||||
instance.replace(foo: 'bar', bar: 'bax')
|
||||
instance[:foo].should be_coerced
|
||||
instance[:bar].should be_coerced
|
||||
end
|
||||
|
@ -137,7 +142,7 @@ describe Hashie::Extensions::Coercion do
|
|||
klass = Class.new(String)
|
||||
subject.coerce_value klass, Coercable
|
||||
|
||||
instance[:foo] = "bar"
|
||||
instance[:foo] = 'bar'
|
||||
instance[:foo].should_not be_kind_of(Coercable)
|
||||
instance[:foo] = klass.new
|
||||
instance[:foo].should be_kind_of(Coercable)
|
||||
|
|
|
@ -3,19 +3,19 @@ require 'spec_helper'
|
|||
describe Hashie::Extensions::DeepMerge do
|
||||
class DeepMergeHash < Hash; include Hashie::Extensions::DeepMerge end
|
||||
|
||||
subject{ DeepMergeHash }
|
||||
subject { DeepMergeHash }
|
||||
|
||||
let(:h1) { subject.new.merge(:a => "a", :a1 => 42, :b => "b", :c => { :c1 => "c1", :c2 => {:a => "b"}, :c3 => { :d1 => "d1" } }) }
|
||||
let(:h2) { { :a => 1, :a1 => 1, :c => { :c1 => 2, :c2 => "c2", :c3 => { :d2 => "d2" } } } }
|
||||
let(:expected_hash) { { :a => 1, :a1 => 1, :b => "b", :c => { :c1 => 2, :c2 => "c2", :c3 => { :d1 => "d1", :d2 => "d2" } } } }
|
||||
let(:h1) { subject.new.merge(a: 'a', a1: 42, b: 'b', c: { c1: 'c1', c2: { a: 'b' }, c3: { d1: 'd1' } }) }
|
||||
let(:h2) { { a: 1, a1: 1, c: { c1: 2, c2: 'c2', c3: { d2: 'd2' } } } }
|
||||
let(:expected_hash) { { a: 1, a1: 1, b: 'b', c: { c1: 2, c2: 'c2', c3: { d1: 'd1', d2: 'd2' } } } }
|
||||
|
||||
it 'deep merges two hashes' do
|
||||
h1.deep_merge(h2).should == expected_hash
|
||||
h1.deep_merge(h2).should eq expected_hash
|
||||
end
|
||||
|
||||
it 'deep merges another hash in place via bang method' do
|
||||
h1.deep_merge!(h2)
|
||||
h1.should == expected_hash
|
||||
h1.should eq expected_hash
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -5,36 +5,35 @@ describe Hashie::Extensions::IndifferentAccess do
|
|||
include Hashie::Extensions::MergeInitializer
|
||||
include Hashie::Extensions::IndifferentAccess
|
||||
end
|
||||
subject{ IndifferentHash }
|
||||
subject { IndifferentHash }
|
||||
|
||||
it 'should be able to access via string or symbol' do
|
||||
h = subject.new(:abc => 123)
|
||||
h[:abc].should == 123
|
||||
h['abc'].should == 123
|
||||
h = subject.new(abc: 123)
|
||||
h[:abc].should eq 123
|
||||
h['abc'].should eq 123
|
||||
end
|
||||
|
||||
|
||||
describe '#store' do
|
||||
it 'should indifferently save values' do
|
||||
h = subject.new
|
||||
h.store(:abc, 123)
|
||||
h[:abc].should == 123
|
||||
h['abc'].should == 123
|
||||
h[:abc].should eq 123
|
||||
h['abc'].should eq 123
|
||||
end
|
||||
end
|
||||
|
||||
describe '#values_at' do
|
||||
it 'should indifferently find values' do
|
||||
h = subject.new(:foo => 'bar', 'baz' => 'qux')
|
||||
h.values_at('foo', :baz).should == %w(bar qux)
|
||||
h.values_at('foo', :baz).should eq %w(bar qux)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#fetch' do
|
||||
it 'should work like normal fetch, but indifferent' do
|
||||
h = subject.new(:foo => 'bar')
|
||||
h.fetch(:foo).should == h.fetch('foo')
|
||||
h.fetch(:foo).should == 'bar'
|
||||
h = subject.new(foo: 'bar')
|
||||
h.fetch(:foo).should eq h.fetch('foo')
|
||||
h.fetch(:foo).should eq 'bar'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -48,7 +47,7 @@ describe Hashie::Extensions::IndifferentAccess do
|
|||
end
|
||||
|
||||
describe '#key?' do
|
||||
let(:h) { subject.new(:foo => 'bar') }
|
||||
let(:h) { subject.new(foo: 'bar') }
|
||||
|
||||
it 'should find it indifferently' do
|
||||
h.should be_key(:foo)
|
||||
|
@ -64,27 +63,27 @@ describe Hashie::Extensions::IndifferentAccess do
|
|||
end
|
||||
|
||||
describe '#update' do
|
||||
subject{ IndifferentHash.new(:foo => 'bar') }
|
||||
subject { IndifferentHash.new(foo: 'bar') }
|
||||
it 'should allow keys to be indifferent still' do
|
||||
subject.update(:baz => 'qux')
|
||||
subject['foo'].should == 'bar'
|
||||
subject['baz'].should == 'qux'
|
||||
subject.update(baz: 'qux')
|
||||
subject['foo'].should eq 'bar'
|
||||
subject['baz'].should eq 'qux'
|
||||
end
|
||||
|
||||
it 'should recursively inject indifference into sub-hashes' do
|
||||
subject.update(:baz => {:qux => 'abc'})
|
||||
subject['baz']['qux'].should == 'abc'
|
||||
subject.update(baz: { qux: 'abc' })
|
||||
subject['baz']['qux'].should eq 'abc'
|
||||
end
|
||||
|
||||
it 'should not change the ancestors of the injected object class' do
|
||||
subject.update(:baz => {:qux => 'abc'})
|
||||
subject.update(baz: { qux: 'abc' })
|
||||
Hash.new.should_not be_respond_to(:indifferent_access?)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#replace' do
|
||||
subject do
|
||||
IndifferentHash.new(:foo => 'bar').replace(:bar => 'baz', :hi => 'bye')
|
||||
IndifferentHash.new(foo: 'bar').replace(bar: 'baz', hi: 'bye')
|
||||
end
|
||||
|
||||
it 'returns self' do
|
||||
|
@ -100,10 +99,10 @@ describe Hashie::Extensions::IndifferentAccess do
|
|||
|
||||
it 'creates new keys with indifferent access' do
|
||||
[:bar, 'bar', :hi, 'hi'].each { |k| subject.key?(k).should be_true }
|
||||
subject[:bar].should == 'baz'
|
||||
subject['bar'].should == 'baz'
|
||||
subject[:hi].should == 'bye'
|
||||
subject['hi'].should == 'bye'
|
||||
subject[:bar].should eq 'baz'
|
||||
subject['bar'].should eq 'baz'
|
||||
subject[:hi].should eq 'bye'
|
||||
subject['hi'].should eq 'bye'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,14 +6,14 @@ describe Hashie::Extensions::KeyConversion do
|
|||
klass.send :include, Hashie::Extensions::KeyConversion
|
||||
klass
|
||||
end
|
||||
let(:instance){ subject.new }
|
||||
let(:instance) { subject.new }
|
||||
|
||||
describe '#stringify_keys!' do
|
||||
it 'should convert keys to strings' do
|
||||
instance[:abc] = 'abc'
|
||||
instance[123] = '123'
|
||||
instance.stringify_keys!
|
||||
(instance.keys & %w(abc 123)).size.should == 2
|
||||
(instance.keys & %w(abc 123)).size.should eq 2
|
||||
end
|
||||
|
||||
it 'should do deep conversion within nested hashes' do
|
||||
|
@ -21,7 +21,7 @@ describe Hashie::Extensions::KeyConversion do
|
|||
instance[:ab][:cd] = subject.new
|
||||
instance[:ab][:cd][:ef] = 'abcdef'
|
||||
instance.stringify_keys!
|
||||
instance.should == {'ab' => {'cd' => {'ef' => 'abcdef'}}}
|
||||
instance.should eq('ab' => { 'cd' => { 'ef' => 'abcdef' } })
|
||||
end
|
||||
|
||||
it 'should do deep conversion within nested arrays' do
|
||||
|
@ -31,11 +31,11 @@ describe Hashie::Extensions::KeyConversion do
|
|||
instance[:ab][0][:cd] = 'abcd'
|
||||
instance[:ab][1][:ef] = 'abef'
|
||||
instance.stringify_keys!
|
||||
instance.should == {'ab' => [{'cd' => 'abcd'}, {'ef' => 'abef'}]}
|
||||
instance.should eq('ab' => [{ 'cd' => 'abcd' }, { 'ef' => 'abef' }])
|
||||
end
|
||||
|
||||
it 'should return itself' do
|
||||
instance.stringify_keys!.should == instance
|
||||
instance.stringify_keys!.should eq instance
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -43,14 +43,14 @@ describe Hashie::Extensions::KeyConversion do
|
|||
it 'should convert keys to strings' do
|
||||
instance[:abc] = 'def'
|
||||
copy = instance.stringify_keys
|
||||
copy['abc'].should == 'def'
|
||||
copy['abc'].should eq 'def'
|
||||
end
|
||||
|
||||
it 'should not alter the original' do
|
||||
instance[:abc] = 'def'
|
||||
copy = instance.stringify_keys
|
||||
instance.keys.should == [:abc]
|
||||
copy.keys.should == %w(abc)
|
||||
instance.keys.should eq [:abc]
|
||||
copy.keys.should eq %w(abc)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -59,7 +59,7 @@ describe Hashie::Extensions::KeyConversion do
|
|||
instance['abc'] = 'abc'
|
||||
instance['def'] = 'def'
|
||||
instance.symbolize_keys!
|
||||
(instance.keys & [:abc, :def]).size.should == 2
|
||||
(instance.keys & [:abc, :def]).size.should eq 2
|
||||
end
|
||||
|
||||
it 'should do deep conversion within nested hashes' do
|
||||
|
@ -67,7 +67,7 @@ describe Hashie::Extensions::KeyConversion do
|
|||
instance['ab']['cd'] = subject.new
|
||||
instance['ab']['cd']['ef'] = 'abcdef'
|
||||
instance.symbolize_keys!
|
||||
instance.should == {:ab => {:cd => {:ef => 'abcdef'}}}
|
||||
instance.should eq(ab: { cd: { ef: 'abcdef' } })
|
||||
end
|
||||
|
||||
it 'should do deep conversion within nested arrays' do
|
||||
|
@ -77,11 +77,11 @@ describe Hashie::Extensions::KeyConversion do
|
|||
instance['ab'][0]['cd'] = 'abcd'
|
||||
instance['ab'][1]['ef'] = 'abef'
|
||||
instance.symbolize_keys!
|
||||
instance.should == {:ab => [{:cd => 'abcd'}, {:ef => 'abef'}]}
|
||||
instance.should eq(ab: [{ cd: 'abcd' }, { ef: 'abef' }])
|
||||
end
|
||||
|
||||
it 'should return itself' do
|
||||
instance.symbolize_keys!.should == instance
|
||||
instance.symbolize_keys!.should eq instance
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -89,14 +89,14 @@ describe Hashie::Extensions::KeyConversion do
|
|||
it 'should convert keys to symbols' do
|
||||
instance['abc'] = 'def'
|
||||
copy = instance.symbolize_keys
|
||||
copy[:abc].should == 'def'
|
||||
copy[:abc].should eq 'def'
|
||||
end
|
||||
|
||||
it 'should not alter the original' do
|
||||
instance['abc'] = 'def'
|
||||
copy = instance.symbolize_keys
|
||||
instance.keys.should == ['abc']
|
||||
copy.keys.should == [:abc]
|
||||
instance.keys.should eq ['abc']
|
||||
copy.keys.should eq [:abc]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,19 +2,19 @@ require 'spec_helper'
|
|||
|
||||
describe Hashie::Extensions::MergeInitializer do
|
||||
class MergeInitializerHash < Hash; include Hashie::Extensions::MergeInitializer end
|
||||
subject{ MergeInitializerHash }
|
||||
subject { MergeInitializerHash }
|
||||
|
||||
it 'should initialize fine with no arguments' do
|
||||
subject.new.should == {}
|
||||
subject.new.should eq({})
|
||||
end
|
||||
|
||||
it 'should initialize with a hash' do
|
||||
subject.new(:abc => 'def').should == {:abc => 'def'}
|
||||
subject.new(abc: 'def').should eq(abc: 'def')
|
||||
end
|
||||
|
||||
it 'should initialize with a hash and a default' do
|
||||
h = subject.new({:abc => 'def'}, 'bar')
|
||||
h[:foo].should == 'bar'
|
||||
h[:abc].should == 'def'
|
||||
h = subject.new({ abc: 'def' }, 'bar')
|
||||
h[:foo].should eq 'bar'
|
||||
h[:abc].should eq 'def'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,27 +2,29 @@ require 'spec_helper'
|
|||
|
||||
describe Hashie::Extensions::MethodReader do
|
||||
class ReaderHash < Hash
|
||||
def initialize(hash = {}); self.update(hash) end
|
||||
def initialize(hash = {
|
||||
}); update(hash)
|
||||
end
|
||||
include Hashie::Extensions::MethodReader
|
||||
end
|
||||
subject{ ReaderHash }
|
||||
subject { ReaderHash }
|
||||
|
||||
it 'should read string keys from the method' do
|
||||
subject.new('awesome' => 'sauce').awesome.should == 'sauce'
|
||||
subject.new('awesome' => 'sauce').awesome.should eq 'sauce'
|
||||
end
|
||||
|
||||
it 'should read symbol keys from the method' do
|
||||
subject.new(:awesome => 'sauce').awesome.should == 'sauce'
|
||||
subject.new(awesome: 'sauce').awesome.should eq 'sauce'
|
||||
end
|
||||
|
||||
it 'should read nil and false values out properly' do
|
||||
h = subject.new(:nil => nil, :false => false)
|
||||
h.nil.should == nil
|
||||
h.false.should == false
|
||||
h = subject.new(nil: nil, false: false)
|
||||
h.nil.should eq nil
|
||||
h.false.should eq false
|
||||
end
|
||||
|
||||
it 'should raise a NoMethodError for undefined keys' do
|
||||
lambda{ subject.new.awesome }.should raise_error(NoMethodError)
|
||||
lambda { subject.new.awesome }.should raise_error(NoMethodError)
|
||||
end
|
||||
|
||||
describe '#respond_to?' do
|
||||
|
@ -31,7 +33,7 @@ describe Hashie::Extensions::MethodReader do
|
|||
end
|
||||
|
||||
it 'should be true for symbol keys' do
|
||||
subject.new(:awesome => 'sauce').should be_respond_to(:awesome)
|
||||
subject.new(awesome: 'sauce').should be_respond_to(:awesome)
|
||||
end
|
||||
|
||||
it 'should be false for non-keys' do
|
||||
|
@ -44,21 +46,21 @@ describe Hashie::Extensions::MethodWriter do
|
|||
class WriterHash < Hash
|
||||
include Hashie::Extensions::MethodWriter
|
||||
end
|
||||
subject{ WriterHash.new }
|
||||
subject { WriterHash.new }
|
||||
|
||||
it 'should write from a method call' do
|
||||
subject.awesome = 'sauce'
|
||||
subject['awesome'].should == 'sauce'
|
||||
subject['awesome'].should eq 'sauce'
|
||||
end
|
||||
|
||||
it 'should convert the key using the #convert_key method' do
|
||||
subject.stub!(:convert_key).and_return(:awesome)
|
||||
subject.awesome = 'sauce'
|
||||
subject[:awesome].should == 'sauce'
|
||||
subject[:awesome].should eq 'sauce'
|
||||
end
|
||||
|
||||
it 'should still NoMethodError on non equals-ending methods' do
|
||||
lambda{ subject.awesome }.should raise_error(NoMethodError)
|
||||
lambda { subject.awesome }.should raise_error(NoMethodError)
|
||||
end
|
||||
|
||||
it 'should #respond_to? properly' do
|
||||
|
@ -69,25 +71,27 @@ end
|
|||
|
||||
describe Hashie::Extensions::MethodQuery do
|
||||
class QueryHash < Hash
|
||||
def initialize(hash = {}); self.update(hash) end
|
||||
def initialize(hash = {
|
||||
}); update(hash)
|
||||
end
|
||||
include Hashie::Extensions::MethodQuery
|
||||
end
|
||||
subject{ QueryHash }
|
||||
|
||||
subject { QueryHash }
|
||||
|
||||
it 'should be true for non-nil string key values' do
|
||||
subject.new('abc' => 123).should be_abc
|
||||
end
|
||||
|
||||
it 'should be true for non-nil symbol key values' do
|
||||
subject.new(:abc => 123).should be_abc
|
||||
subject.new(abc: 123).should be_abc
|
||||
end
|
||||
|
||||
it 'should be false for nil key values' do
|
||||
subject.new(:abc => false).should_not be_abc
|
||||
subject.new(abc: false).should_not be_abc
|
||||
end
|
||||
|
||||
it 'should raise a NoMethodError for non-set keys' do
|
||||
lambda{ subject.new.abc? }.should raise_error(NoMethodError)
|
||||
lambda { subject.new.abc? }.should raise_error(NoMethodError)
|
||||
end
|
||||
|
||||
it 'should respond_to? for existing string keys' do
|
||||
|
@ -95,7 +99,7 @@ describe Hashie::Extensions::MethodQuery do
|
|||
end
|
||||
|
||||
it 'should respond_to? for existing symbol keys' do
|
||||
subject.new(:abc => 'def').should be_respond_to(:abc?)
|
||||
subject.new(abc: 'def').should be_respond_to(:abc?)
|
||||
end
|
||||
|
||||
it 'should not respond_to? for non-existent keys' do
|
||||
|
@ -107,6 +111,6 @@ describe Hashie::Extensions::MethodAccess do
|
|||
it 'should include all of the other method mixins' do
|
||||
klass = Class.new(Hash)
|
||||
klass.send :include, Hashie::Extensions::MethodAccess
|
||||
(klass.ancestors & [Hashie::Extensions::MethodReader, Hashie::Extensions::MethodWriter, Hashie::Extensions::MethodQuery]).size.should == 3
|
||||
(klass.ancestors & [Hashie::Extensions::MethodReader, Hashie::Extensions::MethodWriter, Hashie::Extensions::MethodQuery]).size.should eq 3
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Hash do
|
||||
it "should be convertible to a Hashie::Mash" do
|
||||
mash = Hashie::Hash[:some => "hash"].to_mash
|
||||
it 'should be convertible to a Hashie::Mash' do
|
||||
mash = Hashie::Hash[some: 'hash'].to_mash
|
||||
mash.is_a?(Hashie::Mash).should be_true
|
||||
mash.some.should == "hash"
|
||||
mash.some.should eq 'hash'
|
||||
end
|
||||
|
||||
it "#stringify_keys! should turn all keys into strings" do
|
||||
hash = Hashie::Hash[:a => "hey", 123 => "bob"]
|
||||
|
||||
it '#stringify_keys! should turn all keys into strings' do
|
||||
hash = Hashie::Hash[:a => 'hey', 123 => 'bob']
|
||||
hash.stringify_keys!
|
||||
hash.should == Hashie::Hash["a" => "hey", "123" => "bob"]
|
||||
hash.should eq Hashie::Hash['a' => 'hey', '123' => 'bob']
|
||||
end
|
||||
|
||||
it "#stringify_keys should return a hash with stringified keys" do
|
||||
hash = Hashie::Hash[:a => "hey", 123 => "bob"]
|
||||
|
||||
it '#stringify_keys should return a hash with stringified keys' do
|
||||
hash = Hashie::Hash[:a => 'hey', 123 => 'bob']
|
||||
stringified_hash = hash.stringify_keys
|
||||
hash.should == Hashie::Hash[:a => "hey", 123 => "bob"]
|
||||
stringified_hash.should == Hashie::Hash["a" => "hey", "123" => "bob"]
|
||||
hash.should eq Hashie::Hash[:a => 'hey', 123 => 'bob']
|
||||
stringified_hash.should eq Hashie::Hash['a' => 'hey', '123' => 'bob']
|
||||
end
|
||||
|
||||
it "#to_hash should return a hash with stringified keys" do
|
||||
hash = Hashie::Hash["a" => "hey", 123 => "bob", "array" => [1, 2, 3]]
|
||||
|
||||
it '#to_hash should return a hash with stringified keys' do
|
||||
hash = Hashie::Hash['a' => 'hey', 123 => 'bob', 'array' => [1, 2, 3]]
|
||||
stringified_hash = hash.to_hash
|
||||
stringified_hash.should == {"a" => "hey", "123" => "bob", "array" => [1, 2, 3]}
|
||||
stringified_hash.should eq('a' => 'hey', '123' => 'bob', 'array' => [1, 2, 3])
|
||||
end
|
||||
|
||||
it "#to_hash with symbolize_keys set to true should return a hash with symbolized keys" do
|
||||
hash = Hashie::Hash["a" => "hey", 123 => "bob", "array" => [1, 2, 3]]
|
||||
symbolized_hash = hash.to_hash(:symbolize_keys => true)
|
||||
symbolized_hash.should == {:a => "hey", :"123" => "bob", :array => [1, 2, 3]}
|
||||
|
||||
it '#to_hash with symbolize_keys set to true should return a hash with symbolized keys' do
|
||||
hash = Hashie::Hash['a' => 'hey', 123 => 'bob', 'array' => [1, 2, 3]]
|
||||
symbolized_hash = hash.to_hash(symbolize_keys: true)
|
||||
symbolized_hash.should eq(:a => 'hey', :"123" => 'bob', :array => [1, 2, 3])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,223 +6,223 @@ describe Hashie::Mash do
|
|||
@mash = Hashie::Mash.new
|
||||
end
|
||||
|
||||
it "should inherit from hash" do
|
||||
it 'should inherit from hash' do
|
||||
@mash.is_a?(Hash).should be_true
|
||||
end
|
||||
|
||||
it "should be able to set hash values through method= calls" do
|
||||
@mash.test = "abc"
|
||||
@mash["test"].should == "abc"
|
||||
it 'should be able to set hash values through method= calls' do
|
||||
@mash.test = 'abc'
|
||||
@mash['test'].should eq 'abc'
|
||||
end
|
||||
|
||||
it "should be able to retrieve set values through method calls" do
|
||||
@mash["test"] = "abc"
|
||||
@mash.test.should == "abc"
|
||||
it 'should be able to retrieve set values through method calls' do
|
||||
@mash['test'] = 'abc'
|
||||
@mash.test.should eq 'abc'
|
||||
end
|
||||
|
||||
it "should be able to retrieve set values through blocks" do
|
||||
@mash["test"] = "abc"
|
||||
it 'should be able to retrieve set values through blocks' do
|
||||
@mash['test'] = 'abc'
|
||||
value = nil
|
||||
@mash.[]("test") { |v| value = v }
|
||||
value.should == "abc"
|
||||
@mash.[]('test') { |v| value = v }
|
||||
value.should eq 'abc'
|
||||
end
|
||||
|
||||
it "should be able to retrieve set values through blocks with method calls" do
|
||||
@mash["test"] = "abc"
|
||||
it 'should be able to retrieve set values through blocks with method calls' do
|
||||
@mash['test'] = 'abc'
|
||||
value = nil
|
||||
@mash.test { |v| value = v }
|
||||
value.should == "abc"
|
||||
value.should eq 'abc'
|
||||
end
|
||||
|
||||
it "should test for already set values when passed a ? method" do
|
||||
it 'should test for already set values when passed a ? method' do
|
||||
@mash.test?.should be_false
|
||||
@mash.test = "abc"
|
||||
@mash.test = 'abc'
|
||||
@mash.test?.should be_true
|
||||
end
|
||||
|
||||
it "should return false on a ? method if a value has been set to nil or false" do
|
||||
it 'should return false on a ? method if a value has been set to nil or false' do
|
||||
@mash.test = nil
|
||||
@mash.should_not be_test
|
||||
@mash.test = false
|
||||
@mash.should_not be_test
|
||||
end
|
||||
|
||||
it "should make all [] and []= into strings for consistency" do
|
||||
@mash["abc"] = 123
|
||||
it 'should make all [] and []= into strings for consistency' do
|
||||
@mash['abc'] = 123
|
||||
@mash.key?('abc').should be_true
|
||||
@mash["abc"].should == 123
|
||||
@mash['abc'].should eq 123
|
||||
end
|
||||
|
||||
it "should have a to_s that is identical to its inspect" do
|
||||
it 'should have a to_s that is identical to its inspect' do
|
||||
@mash.abc = 123
|
||||
@mash.to_s.should == @mash.inspect
|
||||
@mash.to_s.should eq @mash.inspect
|
||||
end
|
||||
|
||||
it "should return nil instead of raising an error for attribute-esque method calls" do
|
||||
it 'should return nil instead of raising an error for attribute-esque method calls' do
|
||||
@mash.abc.should be_nil
|
||||
end
|
||||
|
||||
it "should return the default value if set like Hash" do
|
||||
it 'should return the default value if set like Hash' do
|
||||
@mash.default = 123
|
||||
@mash.abc.should == 123
|
||||
@mash.abc.should eq 123
|
||||
end
|
||||
|
||||
it "should gracefully handle being accessed with arguments" do
|
||||
@mash.abc("foobar").should == nil
|
||||
it 'should gracefully handle being accessed with arguments' do
|
||||
@mash.abc('foobar').should eq nil
|
||||
@mash.abc = 123
|
||||
@mash.abc("foobar").should == 123
|
||||
@mash.abc('foobar').should eq 123
|
||||
end
|
||||
|
||||
it "should return a Hashie::Mash when passed a bang method to a non-existenct key" do
|
||||
it 'should return a Hashie::Mash when passed a bang method to a non-existenct key' do
|
||||
@mash.abc!.is_a?(Hashie::Mash).should be_true
|
||||
end
|
||||
|
||||
it "should return the existing value when passed a bang method for an existing key" do
|
||||
@mash.name = "Bob"
|
||||
@mash.name!.should == "Bob"
|
||||
it 'should return the existing value when passed a bang method for an existing key' do
|
||||
@mash.name = 'Bob'
|
||||
@mash.name!.should eq 'Bob'
|
||||
end
|
||||
|
||||
it "should return a Hashie::Mash when passed an under bang method to a non-existenct key" do
|
||||
it 'should return a Hashie::Mash when passed an under bang method to a non-existenct key' do
|
||||
@mash.abc_.is_a?(Hashie::Mash).should be_true
|
||||
end
|
||||
|
||||
it "should return the existing value when passed an under bang method for an existing key" do
|
||||
@mash.name = "Bob"
|
||||
@mash.name_.should == "Bob"
|
||||
it 'should return the existing value when passed an under bang method for an existing key' do
|
||||
@mash.name = 'Bob'
|
||||
@mash.name_.should eq 'Bob'
|
||||
end
|
||||
|
||||
it "#initializing_reader should return a Hashie::Mash when passed a non-existent key" do
|
||||
it '#initializing_reader should return a Hashie::Mash when passed a non-existent key' do
|
||||
@mash.initializing_reader(:abc).is_a?(Hashie::Mash).should be_true
|
||||
end
|
||||
|
||||
it "should allow for multi-level assignment through bang methods" do
|
||||
@mash.author!.name = "Michael Bleigh"
|
||||
@mash.author.should == Hashie::Mash.new(:name => "Michael Bleigh")
|
||||
@mash.author!.website!.url = "http://www.mbleigh.com/"
|
||||
@mash.author.website.should == Hashie::Mash.new(:url => "http://www.mbleigh.com/")
|
||||
it 'should allow for multi-level assignment through bang methods' do
|
||||
@mash.author!.name = 'Michael Bleigh'
|
||||
@mash.author.should eq Hashie::Mash.new(name: 'Michael Bleigh')
|
||||
@mash.author!.website!.url = 'http://www.mbleigh.com/'
|
||||
@mash.author.website.should eq Hashie::Mash.new(url: 'http://www.mbleigh.com/')
|
||||
end
|
||||
|
||||
it "should allow for multi-level under bang testing" do
|
||||
it 'should allow for multi-level under bang testing' do
|
||||
@mash.author_.website_.url.should be_nil
|
||||
@mash.author_.website_.url?.should == false
|
||||
@mash.author_.website_.url?.should eq false
|
||||
@mash.author.should be_nil
|
||||
end
|
||||
|
||||
it "should not call super if id is not a key" do
|
||||
@mash.id.should == nil
|
||||
it 'should not call super if id is not a key' do
|
||||
@mash.id.should eq nil
|
||||
end
|
||||
|
||||
it "should return the value if id is a key" do
|
||||
@mash.id = "Steve"
|
||||
@mash.id.should == "Steve"
|
||||
it 'should return the value if id is a key' do
|
||||
@mash.id = 'Steve'
|
||||
@mash.id.should eq 'Steve'
|
||||
end
|
||||
|
||||
it "should not call super if type is not a key" do
|
||||
@mash.type.should == nil
|
||||
it 'should not call super if type is not a key' do
|
||||
@mash.type.should eq nil
|
||||
end
|
||||
|
||||
it "should return the value if type is a key" do
|
||||
@mash.type = "Steve"
|
||||
@mash.type.should == "Steve"
|
||||
it 'should return the value if type is a key' do
|
||||
@mash.type = 'Steve'
|
||||
@mash.type.should eq 'Steve'
|
||||
end
|
||||
|
||||
context "updating" do
|
||||
subject {
|
||||
described_class.new :first_name => "Michael", :last_name => "Bleigh",
|
||||
:details => {:email => "michael@asf.com", :address => "Nowhere road"}
|
||||
}
|
||||
context 'updating' do
|
||||
subject do
|
||||
described_class.new first_name: 'Michael', last_name: 'Bleigh',
|
||||
details: { email: 'michael@asf.com', address: 'Nowhere road' }
|
||||
end
|
||||
|
||||
describe "#deep_update" do
|
||||
it "should recursively Hashie::Mash Hashie::Mashes and hashes together" do
|
||||
subject.deep_update(:details => {:email => "michael@intridea.com", :city => "Imagineton"})
|
||||
subject.first_name.should == "Michael"
|
||||
subject.details.email.should == "michael@intridea.com"
|
||||
subject.details.address.should == "Nowhere road"
|
||||
subject.details.city.should == "Imagineton"
|
||||
describe '#deep_update' do
|
||||
it 'should recursively Hashie::Mash Hashie::Mashes and hashes together' do
|
||||
subject.deep_update(details: { email: 'michael@intridea.com', city: 'Imagineton' })
|
||||
subject.first_name.should eq 'Michael'
|
||||
subject.details.email.should eq 'michael@intridea.com'
|
||||
subject.details.address.should eq 'Nowhere road'
|
||||
subject.details.city.should eq 'Imagineton'
|
||||
end
|
||||
|
||||
it "should convert values only once" do
|
||||
it 'should convert values only once' do
|
||||
class ConvertedMash < Hashie::Mash
|
||||
end
|
||||
|
||||
rhs = ConvertedMash.new({:email => "foo@bar.com"})
|
||||
rhs = ConvertedMash.new(email: 'foo@bar.com')
|
||||
subject.should_receive(:convert_value).exactly(1).times
|
||||
subject.deep_update(rhs)
|
||||
end
|
||||
|
||||
it "should make #update deep by default" do
|
||||
subject.update(:details => {:address => "Fake street"}).should eql(subject)
|
||||
subject.details.address.should == "Fake street"
|
||||
subject.details.email.should == "michael@asf.com"
|
||||
it 'should make #update deep by default' do
|
||||
subject.update(details: { address: 'Fake street' }).should eql(subject)
|
||||
subject.details.address.should eq 'Fake street'
|
||||
subject.details.email.should eq 'michael@asf.com'
|
||||
end
|
||||
|
||||
it "should clone before a #deep_merge" do
|
||||
duped = subject.deep_merge(:details => {:address => "Fake street"})
|
||||
it 'should clone before a #deep_merge' do
|
||||
duped = subject.deep_merge(details: { address: 'Fake street' })
|
||||
duped.should_not eql(subject)
|
||||
duped.details.address.should == "Fake street"
|
||||
subject.details.address.should == "Nowhere road"
|
||||
duped.details.email.should == "michael@asf.com"
|
||||
duped.details.address.should eq 'Fake street'
|
||||
subject.details.address.should eq 'Nowhere road'
|
||||
duped.details.email.should eq 'michael@asf.com'
|
||||
end
|
||||
|
||||
it "regular #merge should be deep" do
|
||||
duped = subject.merge(:details => {:email => "michael@intridea.com"})
|
||||
it 'regular #merge should be deep' do
|
||||
duped = subject.merge(details: { email: 'michael@intridea.com' })
|
||||
duped.should_not eql(subject)
|
||||
duped.details.email.should == "michael@intridea.com"
|
||||
duped.details.address.should == "Nowhere road"
|
||||
duped.details.email.should eq 'michael@intridea.com'
|
||||
duped.details.address.should eq 'Nowhere road'
|
||||
end
|
||||
|
||||
# http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-update
|
||||
it "accepts a block" do
|
||||
duped = subject.merge(:details => {:address => "Pasadena CA"}) {|key, oldv, newv| [oldv, newv].join(', ')}
|
||||
duped.details.address.should == 'Nowhere road, Pasadena CA'
|
||||
it 'accepts a block' do
|
||||
duped = subject.merge(details: { address: 'Pasadena CA' }) { |key, oldv, newv| [oldv, newv].join(', ') }
|
||||
duped.details.address.should eq 'Nowhere road, Pasadena CA'
|
||||
end
|
||||
end
|
||||
|
||||
describe "shallow update" do
|
||||
it "should shallowly Hashie::Mash Hashie::Mashes and hashes together" do
|
||||
subject.shallow_update(:details => {
|
||||
:email => "michael@intridea.com", :city => "Imagineton"
|
||||
describe 'shallow update' do
|
||||
it 'should shallowly Hashie::Mash Hashie::Mashes and hashes together' do
|
||||
subject.shallow_update(details: {
|
||||
email: 'michael@intridea.com', city: 'Imagineton'
|
||||
}).should eql(subject)
|
||||
|
||||
subject.first_name.should == "Michael"
|
||||
subject.details.email.should == "michael@intridea.com"
|
||||
subject.first_name.should eq 'Michael'
|
||||
subject.details.email.should eq 'michael@intridea.com'
|
||||
subject.details.address.should be_nil
|
||||
subject.details.city.should == "Imagineton"
|
||||
subject.details.city.should eq 'Imagineton'
|
||||
end
|
||||
|
||||
it "should clone before a #regular_merge" do
|
||||
duped = subject.shallow_merge(:details => {:address => "Fake street"})
|
||||
it 'should clone before a #regular_merge' do
|
||||
duped = subject.shallow_merge(details: { address: 'Fake street' })
|
||||
duped.should_not eql(subject)
|
||||
end
|
||||
|
||||
it "regular merge should be shallow" do
|
||||
duped = subject.shallow_merge(:details => {:address => "Fake street"})
|
||||
duped.details.address.should == "Fake street"
|
||||
subject.details.address.should == "Nowhere road"
|
||||
it 'regular merge should be shallow' do
|
||||
duped = subject.shallow_merge(details: { address: 'Fake street' })
|
||||
duped.details.address.should eq 'Fake street'
|
||||
subject.details.address.should eq 'Nowhere road'
|
||||
duped.details.email.should be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe '#replace' do
|
||||
before do
|
||||
subject.replace(:middle_name => "Cain",
|
||||
:details => {:city => "Imagination"})
|
||||
subject.replace(middle_name: 'Cain',
|
||||
details: { city: 'Imagination' })
|
||||
end
|
||||
|
||||
it 'return self' do
|
||||
subject.replace(:foo => "bar").to_hash.should == {"foo" => "bar"}
|
||||
subject.replace(foo: 'bar').to_hash.should eq('foo' => 'bar')
|
||||
end
|
||||
|
||||
it 'sets all specified keys to their corresponding values' do
|
||||
subject.middle_name?.should be_true
|
||||
subject.details?.should be_true
|
||||
subject.middle_name.should == "Cain"
|
||||
subject.middle_name.should eq 'Cain'
|
||||
subject.details.city?.should be_true
|
||||
subject.details.city.should == "Imagination"
|
||||
subject.details.city.should eq 'Imagination'
|
||||
end
|
||||
|
||||
it 'leaves only specified keys' do
|
||||
subject.keys.sort.should == ['details', 'middle_name']
|
||||
subject.keys.sort.should eq %w(details middle_name)
|
||||
subject.first_name?.should be_false
|
||||
subject.should_not respond_to(:first_name)
|
||||
subject.last_name?.should be_false
|
||||
|
@ -245,22 +245,22 @@ describe Hashie::Mash do
|
|||
end
|
||||
end
|
||||
|
||||
it "should convert hash assignments into Hashie::Mashes" do
|
||||
@mash.details = {:email => 'randy@asf.com', :address => {:state => 'TX'} }
|
||||
@mash.details.email.should == 'randy@asf.com'
|
||||
@mash.details.address.state.should == 'TX'
|
||||
it 'should convert hash assignments into Hashie::Mashes' do
|
||||
@mash.details = { email: 'randy@asf.com', address: { state: 'TX' } }
|
||||
@mash.details.email.should eq 'randy@asf.com'
|
||||
@mash.details.address.state.should eq 'TX'
|
||||
end
|
||||
|
||||
it "should not convert the type of Hashie::Mashes childs to Hashie::Mash" do
|
||||
it 'should not convert the type of Hashie::Mashes childs to Hashie::Mash' do
|
||||
class MyMash < Hashie::Mash
|
||||
end
|
||||
|
||||
record = MyMash.new
|
||||
record.son = MyMash.new
|
||||
record.son.class.should == MyMash
|
||||
record.son.class.should eq MyMash
|
||||
end
|
||||
|
||||
it "should not change the class of Mashes when converted" do
|
||||
it 'should not change the class of Mashes when converted' do
|
||||
class SubMash < Hashie::Mash
|
||||
end
|
||||
|
||||
|
@ -270,7 +270,7 @@ describe Hashie::Mash do
|
|||
record['submash'].should be_kind_of(SubMash)
|
||||
end
|
||||
|
||||
it "should respect the class when passed a bang method for a non-existent key" do
|
||||
it 'should respect the class when passed a bang method for a non-existent key' do
|
||||
record = Hashie::Mash.new
|
||||
record.non_existent!.should be_kind_of(Hashie::Mash)
|
||||
|
||||
|
@ -281,7 +281,7 @@ describe Hashie::Mash do
|
|||
son.non_existent!.should be_kind_of(SubMash)
|
||||
end
|
||||
|
||||
it "should respect the class when passed an under bang method for a non-existent key" do
|
||||
it 'should respect the class when passed an under bang method for a non-existent key' do
|
||||
record = Hashie::Mash.new
|
||||
record.non_existent_.should be_kind_of(Hashie::Mash)
|
||||
|
||||
|
@ -292,172 +292,172 @@ describe Hashie::Mash do
|
|||
son.non_existent_.should be_kind_of(SubMash)
|
||||
end
|
||||
|
||||
it "should respect the class when converting the value" do
|
||||
it 'should respect the class when converting the value' do
|
||||
record = Hashie::Mash.new
|
||||
record.details = Hashie::Mash.new({:email => "randy@asf.com"})
|
||||
record.details = Hashie::Mash.new(email: 'randy@asf.com')
|
||||
record.details.should be_kind_of(Hashie::Mash)
|
||||
end
|
||||
|
||||
it "should respect another subclass when converting the value" do
|
||||
it 'should respect another subclass when converting the value' do
|
||||
record = Hashie::Mash.new
|
||||
|
||||
class SubMash < Hashie::Mash
|
||||
end
|
||||
|
||||
son = SubMash.new({:email => "foo@bar.com"})
|
||||
son = SubMash.new(email: 'foo@bar.com')
|
||||
record.details = son
|
||||
record.details.should be_kind_of(SubMash)
|
||||
end
|
||||
|
||||
describe "#respond_to?" do
|
||||
describe '#respond_to?' do
|
||||
it 'should respond to a normal method' do
|
||||
Hashie::Mash.new.should be_respond_to(:key?)
|
||||
end
|
||||
|
||||
it 'should respond to a set key' do
|
||||
Hashie::Mash.new(:abc => 'def').should be_respond_to(:abc)
|
||||
Hashie::Mash.new(abc: 'def').should be_respond_to(:abc)
|
||||
end
|
||||
|
||||
it 'should respond to a set key with a suffix' do
|
||||
%w(= ? ! _).each do |suffix|
|
||||
Hashie::Mash.new(:abc => 'def').should be_respond_to(:"abc#{suffix}")
|
||||
Hashie::Mash.new(abc: 'def').should be_respond_to(:"abc#{suffix}")
|
||||
end
|
||||
end
|
||||
|
||||
it 'should not respond to an unknown key with a suffix' do
|
||||
%w(= ? ! _).each do |suffix|
|
||||
Hashie::Mash.new(:abc => 'def').should_not be_respond_to(:"xyz#{suffix}")
|
||||
Hashie::Mash.new(abc: 'def').should_not be_respond_to(:"xyz#{suffix}")
|
||||
end
|
||||
end
|
||||
|
||||
it "should not respond to an unknown key without a suffix" do
|
||||
Hashie::Mash.new(:abc => 'def').should_not be_respond_to(:xyz)
|
||||
it 'should not respond to an unknown key without a suffix' do
|
||||
Hashie::Mash.new(abc: 'def').should_not be_respond_to(:xyz)
|
||||
end
|
||||
|
||||
it "should not respond to permitted?" do
|
||||
it 'should not respond to permitted?' do
|
||||
Hashie::Mash.new.should_not be_respond_to(:permitted?)
|
||||
end
|
||||
end
|
||||
|
||||
context "#initialize" do
|
||||
it "should convert an existing hash to a Hashie::Mash" do
|
||||
converted = Hashie::Mash.new({:abc => 123, :name => "Bob"})
|
||||
converted.abc.should == 123
|
||||
converted.name.should == "Bob"
|
||||
context '#initialize' do
|
||||
it 'should convert an existing hash to a Hashie::Mash' do
|
||||
converted = Hashie::Mash.new(abc: 123, name: 'Bob')
|
||||
converted.abc.should eq 123
|
||||
converted.name.should eq 'Bob'
|
||||
end
|
||||
|
||||
it "should convert hashes recursively into Hashie::Mashes" do
|
||||
converted = Hashie::Mash.new({:a => {:b => 1, :c => {:d => 23}}})
|
||||
it 'should convert hashes recursively into Hashie::Mashes' do
|
||||
converted = Hashie::Mash.new(a: { b: 1, c: { d: 23 } })
|
||||
converted.a.is_a?(Hashie::Mash).should be_true
|
||||
converted.a.b.should == 1
|
||||
converted.a.c.d.should == 23
|
||||
converted.a.b.should eq 1
|
||||
converted.a.c.d.should eq 23
|
||||
end
|
||||
|
||||
it "should convert hashes in arrays into Hashie::Mashes" do
|
||||
converted = Hashie::Mash.new({:a => [{:b => 12}, 23]})
|
||||
converted.a.first.b.should == 12
|
||||
converted.a.last.should == 23
|
||||
it 'should convert hashes in arrays into Hashie::Mashes' do
|
||||
converted = Hashie::Mash.new(a: [{ b: 12 }, 23])
|
||||
converted.a.first.b.should eq 12
|
||||
converted.a.last.should eq 23
|
||||
end
|
||||
|
||||
it "should convert an existing Hashie::Mash into a Hashie::Mash" do
|
||||
initial = Hashie::Mash.new(:name => 'randy', :address => {:state => 'TX'})
|
||||
it 'should convert an existing Hashie::Mash into a Hashie::Mash' do
|
||||
initial = Hashie::Mash.new(name: 'randy', address: { state: 'TX' })
|
||||
copy = Hashie::Mash.new(initial)
|
||||
initial.name.should == copy.name
|
||||
initial.__id__.should_not == copy.__id__
|
||||
copy.address.state.should == 'TX'
|
||||
initial.name.should eq copy.name
|
||||
initial.__id__.should_not eq copy.__id__
|
||||
copy.address.state.should eq 'TX'
|
||||
copy.address.state = 'MI'
|
||||
initial.address.state.should == 'TX'
|
||||
copy.address.__id__.should_not == initial.address.__id__
|
||||
initial.address.state.should eq 'TX'
|
||||
copy.address.__id__.should_not eq initial.address.__id__
|
||||
end
|
||||
|
||||
it "should accept a default block" do
|
||||
initial = Hashie::Mash.new { |h,i| h[i] = []}
|
||||
it 'should accept a default block' do
|
||||
initial = Hashie::Mash.new { |h, i| h[i] = [] }
|
||||
initial.default_proc.should_not be_nil
|
||||
initial.default.should be_nil
|
||||
initial.test.should == []
|
||||
initial.test.should eq []
|
||||
initial.test?.should be_true
|
||||
end
|
||||
|
||||
it "should convert Hashie::Mashes within Arrays back to Hashes" do
|
||||
initial_hash = {"a" => [{"b" => 12, "c" =>["d" => 50, "e" => 51]}, 23]}
|
||||
it 'should convert Hashie::Mashes within Arrays back to Hashes' do
|
||||
initial_hash = { 'a' => [{ 'b' => 12, 'c' => ['d' => 50, 'e' => 51] }, 23] }
|
||||
converted = Hashie::Mash.new(initial_hash)
|
||||
converted.to_hash["a"].first.is_a?(Hashie::Mash).should be_false
|
||||
converted.to_hash["a"].first.is_a?(Hash).should be_true
|
||||
converted.to_hash["a"].first["c"].first.is_a?(Hashie::Mash).should be_false
|
||||
converted.to_hash['a'].first.is_a?(Hashie::Mash).should be_false
|
||||
converted.to_hash['a'].first.is_a?(Hash).should be_true
|
||||
converted.to_hash['a'].first['c'].first.is_a?(Hashie::Mash).should be_false
|
||||
end
|
||||
end
|
||||
|
||||
describe "#fetch" do
|
||||
let(:hash) { {:one => 1, :other => false} }
|
||||
describe '#fetch' do
|
||||
let(:hash) { { one: 1, other: false } }
|
||||
let(:mash) { Hashie::Mash.new(hash) }
|
||||
|
||||
context "when key exists" do
|
||||
it "returns the value" do
|
||||
context 'when key exists' do
|
||||
it 'returns the value' do
|
||||
mash.fetch(:one).should eql(1)
|
||||
end
|
||||
|
||||
it "returns the value even if the value is falsy" do
|
||||
it 'returns the value even if the value is falsy' do
|
||||
mash.fetch(:other).should eql(false)
|
||||
end
|
||||
|
||||
context "when key has other than original but acceptable type" do
|
||||
it "returns the value" do
|
||||
context 'when key has other than original but acceptable type' do
|
||||
it 'returns the value' do
|
||||
mash.fetch('one').should eql(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when key does not exist" do
|
||||
it "should raise KeyError" do
|
||||
context 'when key does not exist' do
|
||||
it 'should raise KeyError' do
|
||||
error = RUBY_VERSION =~ /1.8/ ? IndexError : KeyError
|
||||
expect { mash.fetch(:two) }.to raise_error(error)
|
||||
end
|
||||
|
||||
context "with default value given" do
|
||||
it "returns default value" do
|
||||
context 'with default value given' do
|
||||
it 'returns default value' do
|
||||
mash.fetch(:two, 8).should eql(8)
|
||||
end
|
||||
|
||||
it "returns default value even if it is falsy" do
|
||||
it 'returns default value even if it is falsy' do
|
||||
mash.fetch(:two, false).should eql(false)
|
||||
end
|
||||
end
|
||||
|
||||
context "with block given" do
|
||||
it "returns default value" do
|
||||
mash.fetch(:two) {|key|
|
||||
"block default value"
|
||||
}.should eql("block default value")
|
||||
context 'with block given' do
|
||||
it 'returns default value' do
|
||||
mash.fetch(:two) do|key|
|
||||
'block default value'
|
||||
end.should eql('block default value')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#to_hash" do
|
||||
let(:hash) { { "outer" => { "inner" => 42 }, "testing" => [1, 2, 3] } }
|
||||
describe '#to_hash' do
|
||||
let(:hash) { { 'outer' => { 'inner' => 42 }, 'testing' => [1, 2, 3] } }
|
||||
let(:mash) { Hashie::Mash.new(hash) }
|
||||
|
||||
it "returns a standard Hash" do
|
||||
it 'returns a standard Hash' do
|
||||
mash.to_hash.should be_a(::Hash)
|
||||
end
|
||||
|
||||
it "includes all keys" do
|
||||
it 'includes all keys' do
|
||||
mash.to_hash.keys.should eql(%w(outer testing))
|
||||
end
|
||||
|
||||
it "converts keys to symbols when symbolize_keys option is true" do
|
||||
mash.to_hash(:symbolize_keys => true).keys.should include(:outer)
|
||||
mash.to_hash(:symbolize_keys => true).keys.should_not include("outer")
|
||||
it 'converts keys to symbols when symbolize_keys option is true' do
|
||||
mash.to_hash(symbolize_keys: true).keys.should include(:outer)
|
||||
mash.to_hash(symbolize_keys: true).keys.should_not include('outer')
|
||||
end
|
||||
|
||||
it "leaves keys as strings when symbolize_keys option is false" do
|
||||
mash.to_hash(:symbolize_keys => false).keys.should include("outer")
|
||||
mash.to_hash(:symbolize_keys => false).keys.should_not include(:outer)
|
||||
it 'leaves keys as strings when symbolize_keys option is false' do
|
||||
mash.to_hash(symbolize_keys: false).keys.should include('outer')
|
||||
mash.to_hash(symbolize_keys: false).keys.should_not include(:outer)
|
||||
end
|
||||
|
||||
it "symbolizes keys recursively" do
|
||||
mash.to_hash(:symbolize_keys => true)[:outer].keys.should include(:inner)
|
||||
mash.to_hash(:symbolize_keys => true)[:outer].keys.should_not include("inner")
|
||||
it 'symbolizes keys recursively' do
|
||||
mash.to_hash(symbolize_keys: true)[:outer].keys.should include(:inner)
|
||||
mash.to_hash(symbolize_keys: true)[:outer].keys.should_not include('inner')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@ require 'spec_helper'
|
|||
|
||||
describe Hashie::Trash do
|
||||
class TrashTest < Hashie::Trash
|
||||
property :first_name, :from => :firstName
|
||||
property :first_name, from: :firstName
|
||||
end
|
||||
|
||||
let(:trash) { TrashTest.new }
|
||||
|
@ -32,124 +32,124 @@ describe Hashie::Trash do
|
|||
describe 'writing to properties' do
|
||||
|
||||
it 'does not write to a non-existent property using []=' do
|
||||
lambda{trash['abc'] = 123}.should raise_error(NoMethodError)
|
||||
lambda { trash['abc'] = 123 }.should raise_error(NoMethodError)
|
||||
end
|
||||
|
||||
it 'writes to an existing property using []=' do
|
||||
lambda{trash['first_name'] = 'Bob'}.should_not raise_error
|
||||
lambda { trash['first_name'] = 'Bob' }.should_not raise_error
|
||||
end
|
||||
|
||||
it 'writes to a translated property using []=' do
|
||||
lambda{trash['firstName'] = 'Bob'}.should_not raise_error
|
||||
lambda { trash['firstName'] = 'Bob' }.should_not raise_error
|
||||
end
|
||||
|
||||
it 'reads/writes to an existing property using a method call' do
|
||||
trash.first_name = 'Franklin'
|
||||
trash.first_name.should == 'Franklin'
|
||||
trash.first_name.should eq 'Franklin'
|
||||
end
|
||||
|
||||
it 'writes to an translated property using a method call' do
|
||||
trash.firstName = 'Franklin'
|
||||
trash.first_name.should == 'Franklin'
|
||||
trash.first_name.should eq 'Franklin'
|
||||
end
|
||||
|
||||
it 'writes to a translated property using #replace' do
|
||||
trash.replace(:firstName => 'Franklin')
|
||||
trash.first_name.should == 'Franklin'
|
||||
trash.replace(firstName: 'Franklin')
|
||||
trash.first_name.should eq 'Franklin'
|
||||
end
|
||||
|
||||
it 'writes to a non-translated property using #replace' do
|
||||
trash.replace(:first_name => 'Franklin')
|
||||
trash.first_name.should == 'Franklin'
|
||||
trash.replace(first_name: 'Franklin')
|
||||
trash.first_name.should eq 'Franklin'
|
||||
end
|
||||
end
|
||||
|
||||
describe ' initializing with a Hash' do
|
||||
it 'does not initialize non-existent properties' do
|
||||
lambda{TrashTest.new(:bork => 'abc')}.should raise_error(NoMethodError)
|
||||
lambda { TrashTest.new(bork: 'abc') }.should raise_error(NoMethodError)
|
||||
end
|
||||
|
||||
it 'sets the desired properties' do
|
||||
TrashTest.new(:first_name => 'Michael').first_name.should == 'Michael'
|
||||
TrashTest.new(first_name: 'Michael').first_name.should eq 'Michael'
|
||||
end
|
||||
|
||||
context "with both the translated property and the property" do
|
||||
context 'with both the translated property and the property' do
|
||||
it 'sets the desired properties' do
|
||||
TrashTest.new(:first_name => 'Michael', :firstName=>'Maeve').first_name.should == 'Michael'
|
||||
TrashTest.new(first_name: 'Michael', firstName: 'Maeve').first_name.should eq 'Michael'
|
||||
end
|
||||
end
|
||||
|
||||
it 'sets the translated properties' do
|
||||
TrashTest.new(:firstName => 'Michael').first_name.should == 'Michael'
|
||||
TrashTest.new(firstName: 'Michael').first_name.should eq 'Michael'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'translating properties using a proc' do
|
||||
class TrashLambdaTest < Hashie::Trash
|
||||
property :first_name, :from => :firstName, :with => lambda { |value| value.reverse }
|
||||
property :first_name, from: :firstName, with: lambda { |value| value.reverse }
|
||||
end
|
||||
|
||||
let(:lambda_trash) { TrashLambdaTest.new }
|
||||
|
||||
it 'should translate the value given on initialization with the given lambda' do
|
||||
TrashLambdaTest.new(:firstName => 'Michael').first_name.should == 'Michael'.reverse
|
||||
TrashLambdaTest.new(firstName: 'Michael').first_name.should eq 'Michael'.reverse
|
||||
end
|
||||
|
||||
it 'should not translate the value if given with the right property' do
|
||||
TrashTest.new(:first_name => 'Michael').first_name.should == 'Michael'
|
||||
TrashTest.new(first_name: 'Michael').first_name.should eq 'Michael'
|
||||
end
|
||||
|
||||
it 'should translate the value given as property with the given lambda' do
|
||||
lambda_trash.firstName = 'Michael'
|
||||
lambda_trash.first_name.should == 'Michael'.reverse
|
||||
lambda_trash.first_name.should eq 'Michael'.reverse
|
||||
end
|
||||
|
||||
it 'should not translate the value given as right property' do
|
||||
lambda_trash.first_name = 'Michael'
|
||||
lambda_trash.first_name.should == 'Michael'
|
||||
lambda_trash.first_name.should eq 'Michael'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'translating properties without from option using a proc' do
|
||||
|
||||
class TrashLambdaTest2 < Hashie::Trash
|
||||
property :first_name, :transform_with => lambda { |value| value.reverse }
|
||||
property :first_name, transform_with: lambda { |value| value.reverse }
|
||||
end
|
||||
|
||||
let(:lambda_trash) { TrashLambdaTest2.new }
|
||||
|
||||
it 'should translate the value given as property with the given lambda' do
|
||||
lambda_trash.first_name = 'Michael'
|
||||
lambda_trash.first_name.should == 'Michael'.reverse
|
||||
lambda_trash.first_name.should eq 'Michael'.reverse
|
||||
end
|
||||
|
||||
it 'should transform the value when given in constructor' do
|
||||
TrashLambdaTest2.new(:first_name => 'Michael').first_name.should == 'Michael'.reverse
|
||||
TrashLambdaTest2.new(first_name: 'Michael').first_name.should eq 'Michael'.reverse
|
||||
end
|
||||
|
||||
context "when :from option is given" do
|
||||
context 'when :from option is given' do
|
||||
class TrashLambdaTest3 < Hashie::Trash
|
||||
property :first_name, :from => :firstName, :transform_with => lambda { |value| value.reverse }
|
||||
property :first_name, from: :firstName, transform_with: lambda { |value| value.reverse }
|
||||
end
|
||||
|
||||
it 'should not override the :from option in the constructor' do
|
||||
TrashLambdaTest3.new(:first_name => 'Michael').first_name.should == 'Michael'
|
||||
TrashLambdaTest3.new(first_name: 'Michael').first_name.should eq 'Michael'
|
||||
end
|
||||
|
||||
it 'should not override the :from option when given as property' do
|
||||
t = TrashLambdaTest3.new
|
||||
t.first_name = 'Michael'
|
||||
t.first_name.should == 'Michael'
|
||||
t.first_name.should eq 'Michael'
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
it "should raise an error when :from have the same value as property" do
|
||||
expect {
|
||||
it 'should raise an error when :from have the same value as property' do
|
||||
expect do
|
||||
class WrongTrash < Hashie::Trash
|
||||
property :first_name, :from => :first_name
|
||||
property :first_name, from: :first_name
|
||||
end
|
||||
}.to raise_error(ArgumentError)
|
||||
end.to raise_error(ArgumentError)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue