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
|
||||||
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)
|
VectorOf = Contracts::CollectionOf::Factory.new(::Hamster::Vector)
|
||||||
ResourceList = Contracts::ArrayOf[IsA['Middleman::Sitemap::Resource']]
|
ResourceList = Contracts::ArrayOf[IsA['Middleman::Sitemap::Resource']]
|
||||||
end
|
end
|
||||||
|
|
|
@ -87,8 +87,8 @@ module Middleman
|
||||||
end
|
end
|
||||||
|
|
||||||
# Data about this resource, populated from frontmatter or extensions.
|
# Data about this resource, populated from frontmatter or extensions.
|
||||||
# @return [IndifferentHash]
|
# @return [Hash]
|
||||||
Contract IsA['Middleman::Util::IndifferentHash']
|
Contract RespondTo[:indifferent_access?]
|
||||||
def data
|
def data
|
||||||
::Middleman::Util.recursively_enhance(metadata[:page])
|
::Middleman::Util.recursively_enhance(metadata[:page])
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,8 +11,8 @@ require 'rack/mime'
|
||||||
# DbC
|
# DbC
|
||||||
require 'middleman-core/contracts'
|
require 'middleman-core/contracts'
|
||||||
|
|
||||||
# Immutable Data
|
# Indifferent Access
|
||||||
require 'hamster'
|
require 'hashie'
|
||||||
|
|
||||||
# For URI templating
|
# For URI templating
|
||||||
require 'addressable/uri'
|
require 'addressable/uri'
|
||||||
|
@ -76,56 +76,25 @@ module Middleman
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class IndifferentHash < ::Hamster::Hash
|
class EnhancedHash < ::Hash
|
||||||
def [](key)
|
include ::Hashie::Extensions::MergeInitializer
|
||||||
if key?(key.to_sym)
|
include ::Hashie::Extensions::MethodReader
|
||||||
super(key.to_sym)
|
include ::Hashie::Extensions::IndifferentAccess
|
||||||
elsif key?(key.to_s)
|
|
||||||
super(key.to_s)
|
|
||||||
else
|
|
||||||
super
|
|
||||||
end
|
|
||||||
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
|
end
|
||||||
|
|
||||||
# Recursively convert a normal Hash into a IndifferentHash
|
# Recursively convert a normal Hash into a EnhancedHash
|
||||||
#
|
#
|
||||||
# @private
|
# @private
|
||||||
# @param [Hash] data Normal hash
|
# @param [Hash] data Normal hash
|
||||||
# @return [Middleman::Util::IndifferentHash]
|
# @return [Hash]
|
||||||
FrozenDataStructure = Frozen[Or[IndifferentHash, Array, String, TrueClass, FalseClass, Fixnum, NilClass]]
|
Contract Maybe[Hash] => Maybe[Or[Array, EnhancedHash]]
|
||||||
Contract Maybe[Or[String, Array, Hash, IndifferentHash]] => Maybe[FrozenDataStructure]
|
|
||||||
def recursively_enhance(obj)
|
def recursively_enhance(obj)
|
||||||
case obj
|
if obj.is_a? ::Array
|
||||||
when ::Hash
|
obj.map { |e| recursively_enhance(e) }.freeze
|
||||||
res = obj.map { |key, value| [recursively_enhance(key), recursively_enhance(value)] }
|
elsif obj.is_a? ::Hash
|
||||||
IndifferentHash.new(res)
|
EnhancedHash.new(obj).freeze
|
||||||
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
|
|
||||||
else
|
else
|
||||||
obj.dup.freeze
|
obj
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ module Middleman
|
||||||
|
|
||||||
# Get the frontmatter and plain content from a file
|
# Get the frontmatter and plain content from a file
|
||||||
# @param [String] path
|
# @param [String] path
|
||||||
# @return [Array<Middleman::Util::IndifferentHash, String>]
|
# @return [Array<Hash, String>]
|
||||||
Contract Pathname, Maybe[Symbol] => [Hash, Maybe[String]]
|
Contract Pathname, Maybe[Symbol] => [Hash, Maybe[String]]
|
||||||
def parse(full_path, known_type=nil)
|
def parse(full_path, known_type=nil)
|
||||||
data = {}
|
data = {}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
module Middleman
|
module Middleman
|
||||||
# Current Version
|
# Current Version
|
||||||
# @return [String]
|
# @return [String]
|
||||||
VERSION = '4.0.0.beta.2' unless const_defined?(:VERSION)
|
VERSION = '4.0.0.beta.3' unless const_defined?(:VERSION)
|
||||||
end
|
end
|
||||||
|
|
|
@ -52,6 +52,7 @@ Gem::Specification.new do |s|
|
||||||
# Testing
|
# Testing
|
||||||
s.add_dependency('contracts', ['~> 0.9.0'])
|
s.add_dependency('contracts', ['~> 0.9.0'])
|
||||||
|
|
||||||
# Immutability
|
# Hash stuff
|
||||||
|
s.add_dependency('hashie', ['~> 3.4'])
|
||||||
s.add_dependency('hamster', ['~> 1.0'])
|
s.add_dependency('hamster', ['~> 1.0'])
|
||||||
end
|
end
|
||||||
|
|
|
@ -54,43 +54,23 @@ describe Middleman::Util do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "::recursively_enhance" do
|
describe "::recursively_enhance" do
|
||||||
it "returns IndifferentHash if given one" do
|
it "returns Hashie extended Hash if given a hash" 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
|
|
||||||
input = {test: "subject"}
|
input = {test: "subject"}
|
||||||
subject = Middleman::Util.recursively_enhance input
|
subject = Middleman::Util.recursively_enhance input
|
||||||
|
|
||||||
expect( subject ).to be_a Middleman::Util::IndifferentHash
|
|
||||||
expect( subject.test ).to eq "subject"
|
expect( subject.test ).to eq "subject"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns Array with strings, or IndifferentHash, true, false" do
|
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"}
|
regular_hash = {regular: "hash"}
|
||||||
input = [ indifferent_hash, regular_hash, true, false ]
|
input = [ indifferent_hash, regular_hash, true, false ]
|
||||||
subject = Middleman::Util.recursively_enhance input
|
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[1].regular ).to eq "hash"
|
||||||
expect( subject[2] ).to eq true
|
expect( subject[2] ).to eq true
|
||||||
expect( subject[3] ).to eq false
|
expect( subject[3] ).to eq false
|
||||||
end
|
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
|
||||||
|
|
||||||
end
|
end
|
Loading…
Reference in a new issue