Replace Hamster hash for user-accessible data with Hashie Indifferent access
This commit is contained in:
parent
fb6bca234f
commit
bb6b8c7f13
|
@ -18,16 +18,6 @@ if ENV['TEST'] || ENV['CONTRACTS'] == 'true'
|
|||
end
|
||||
end
|
||||
|
||||
class Frozen < CallableClass
|
||||
def initialize(contract)
|
||||
@contract = contract
|
||||
end
|
||||
|
||||
def valid?(val)
|
||||
(val.frozen? || val.nil? || [::TrueClass, ::FalseClass, ::Fixnum].include?(val.class)) && Contract.valid?(val, @contract)
|
||||
end
|
||||
end
|
||||
|
||||
VectorOf = Contracts::CollectionOf::Factory.new(::Hamster::Vector)
|
||||
ResourceList = Contracts::ArrayOf[IsA['Middleman::Sitemap::Resource']]
|
||||
end
|
||||
|
|
|
@ -87,8 +87,8 @@ module Middleman
|
|||
end
|
||||
|
||||
# Data about this resource, populated from frontmatter or extensions.
|
||||
# @return [IndifferentHash]
|
||||
Contract IsA['Middleman::Util::IndifferentHash']
|
||||
# @return [Hash]
|
||||
Contract RespondTo[:indifferent_access?]
|
||||
def data
|
||||
::Middleman::Util.recursively_enhance(metadata[:page])
|
||||
end
|
||||
|
|
|
@ -11,8 +11,8 @@ require 'rack/mime'
|
|||
# DbC
|
||||
require 'middleman-core/contracts'
|
||||
|
||||
# Immutable Data
|
||||
require 'hamster'
|
||||
# Indifferent Access
|
||||
require 'hashie'
|
||||
|
||||
# For URI templating
|
||||
require 'addressable/uri'
|
||||
|
@ -76,56 +76,25 @@ module Middleman
|
|||
end
|
||||
end
|
||||
|
||||
class IndifferentHash < ::Hamster::Hash
|
||||
def [](key)
|
||||
if key?(key.to_sym)
|
||||
super(key.to_sym)
|
||||
elsif key?(key.to_s)
|
||||
super(key.to_s)
|
||||
else
|
||||
super
|
||||
end
|
||||
class EnhancedHash < ::Hash
|
||||
include ::Hashie::Extensions::MergeInitializer
|
||||
include ::Hashie::Extensions::MethodReader
|
||||
include ::Hashie::Extensions::IndifferentAccess
|
||||
end
|
||||
|
||||
def method_missing(key, *_args)
|
||||
if key?(key.to_sym)
|
||||
self[key.to_sym]
|
||||
elsif key?(key.to_s)
|
||||
self[key.to_s]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Recursively convert a normal Hash into a IndifferentHash
|
||||
# Recursively convert a normal Hash into a EnhancedHash
|
||||
#
|
||||
# @private
|
||||
# @param [Hash] data Normal hash
|
||||
# @return [Middleman::Util::IndifferentHash]
|
||||
FrozenDataStructure = Frozen[Or[IndifferentHash, Array, String, TrueClass, FalseClass, Fixnum, NilClass]]
|
||||
Contract Maybe[Or[String, Array, Hash, IndifferentHash]] => Maybe[FrozenDataStructure]
|
||||
# @return [Hash]
|
||||
Contract Maybe[Hash] => Maybe[Or[Array, EnhancedHash]]
|
||||
def recursively_enhance(obj)
|
||||
case obj
|
||||
when ::Hash
|
||||
res = obj.map { |key, value| [recursively_enhance(key), recursively_enhance(value)] }
|
||||
IndifferentHash.new(res)
|
||||
when IndifferentHash
|
||||
obj.map { |key, value| [recursively_enhance(key), recursively_enhance(value)] }
|
||||
when ::Array
|
||||
res = obj.map { |element| recursively_enhance(element) }
|
||||
Hamster::Vector.new(res)
|
||||
when ::SortedSet
|
||||
# This clause must go before ::Set clause, since ::SortedSet is a ::Set.
|
||||
res = obj.map { |element| recursively_enhance(element) }
|
||||
Hamster::SortedSet.new(res)
|
||||
when ::Set
|
||||
res = obj.map { |element| recursively_enhance(element) }
|
||||
Hamster::Set.new(res)
|
||||
when Hamster::Vector, Hamster::Set, Hamster::SortedSet
|
||||
obj.map { |element| recursively_enhance(element) }
|
||||
when ::TrueClass, ::FalseClass, ::Fixnum, ::Symbol, ::NilClass, ::Float
|
||||
obj
|
||||
if obj.is_a? ::Array
|
||||
obj.map { |e| recursively_enhance(e) }.freeze
|
||||
elsif obj.is_a? ::Hash
|
||||
EnhancedHash.new(obj).freeze
|
||||
else
|
||||
obj.dup.freeze
|
||||
obj
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ module Middleman
|
|||
|
||||
# Get the frontmatter and plain content from a file
|
||||
# @param [String] path
|
||||
# @return [Array<Middleman::Util::IndifferentHash, String>]
|
||||
# @return [Array<Hash, String>]
|
||||
Contract Pathname, Maybe[Symbol] => [Hash, Maybe[String]]
|
||||
def parse(full_path, known_type=nil)
|
||||
data = {}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
module Middleman
|
||||
# Current Version
|
||||
# @return [String]
|
||||
VERSION = '4.0.0.beta.2' unless const_defined?(:VERSION)
|
||||
VERSION = '4.0.0.beta.3' unless const_defined?(:VERSION)
|
||||
end
|
||||
|
|
|
@ -52,6 +52,7 @@ Gem::Specification.new do |s|
|
|||
# Testing
|
||||
s.add_dependency('contracts', ['~> 0.9.0'])
|
||||
|
||||
# Immutability
|
||||
# Hash stuff
|
||||
s.add_dependency('hashie', ['~> 3.4'])
|
||||
s.add_dependency('hamster', ['~> 1.0'])
|
||||
end
|
||||
|
|
|
@ -54,43 +54,23 @@ describe Middleman::Util do
|
|||
end
|
||||
|
||||
describe "::recursively_enhance" do
|
||||
it "returns IndifferentHash if given one" do
|
||||
input = Middleman::Util::IndifferentHash.new({test: "subject"})
|
||||
subject = Middleman::Util.recursively_enhance input
|
||||
|
||||
expect( subject ).to be_a Middleman::Util::IndifferentHash
|
||||
expect( subject.test ).to eq "subject"
|
||||
end
|
||||
|
||||
it "returns IndifferentHash if given a hash" do
|
||||
it "returns Hashie extended Hash if given a hash" do
|
||||
input = {test: "subject"}
|
||||
subject = Middleman::Util.recursively_enhance input
|
||||
|
||||
expect( subject ).to be_a Middleman::Util::IndifferentHash
|
||||
expect( subject.test ).to eq "subject"
|
||||
end
|
||||
|
||||
it "returns Array with strings, or IndifferentHash, true, false" do
|
||||
indifferent_hash = Middleman::Util::IndifferentHash.new({test: "subject"})
|
||||
indifferent_hash = {test: "subject"}
|
||||
regular_hash = {regular: "hash"}
|
||||
input = [ indifferent_hash, regular_hash, true, false ]
|
||||
subject = Middleman::Util.recursively_enhance input
|
||||
|
||||
expect( subject[0] ).to be_a Middleman::Util::IndifferentHash
|
||||
expect( subject[1] ).to be_a Middleman::Util::IndifferentHash
|
||||
expect( subject[1].regular ).to eq "hash"
|
||||
expect( subject[2] ).to eq true
|
||||
expect( subject[3] ).to eq false
|
||||
end
|
||||
|
||||
it "returns duplicated & frozen original object if not special cased" do
|
||||
input = "foo"
|
||||
subject = Middleman::Util.recursively_enhance input
|
||||
|
||||
expect( subject ).to eq input
|
||||
expect( subject.object_id ).not_to eq input.object_id
|
||||
expect( subject ).to be_frozen
|
||||
end
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in a new issue