Merge pull request #1808 from stevenosloan/loosen_data_store_contracts

loosen contracts for setting/returning data in Datastore
This commit is contained in:
Thomas Reynolds 2016-02-17 15:06:53 -08:00
commit 476287452d
3 changed files with 110 additions and 4 deletions

View file

@ -67,7 +67,7 @@ module Middleman
# @param [Symbol] name Name of the data, used for namespacing # @param [Symbol] name Name of the data, used for namespacing
# @param [Hash] content The content for this data # @param [Hash] content The content for this data
# @return [Hash] # @return [Hash]
Contract Symbol, Hash => Hash Contract Symbol, Or[Hash, Array] => Hash
def store(name=nil, content=nil) def store(name=nil, content=nil)
@local_sources[name.to_s] = content unless name.nil? || content.nil? @local_sources[name.to_s] = content unless name.nil? || content.nil?
@local_sources @local_sources
@ -148,7 +148,7 @@ module Middleman
# #
# @param [String, Symbol] path The name of the data namespace # @param [String, Symbol] path The name of the data namespace
# @return [Hash, nil] # @return [Hash, nil]
Contract Or[String, Symbol] => Maybe[Hash] Contract Or[String, Symbol] => Maybe[Or[Array, IsA['Middleman::Util::EnhancedHash']]]
def data_for_path(path) def data_for_path(path)
response = if store.key?(path.to_s) response = if store.key?(path.to_s)
store[path.to_s] store[path.to_s]

View file

@ -29,7 +29,7 @@ module Middleman
if obj.is_a? ::Array if obj.is_a? ::Array
obj.map { |e| recursively_enhance(e) } obj.map { |e| recursively_enhance(e) }
elsif obj.is_a? ::Hash elsif obj.is_a? ::Hash
::Hashie::Mash.new(obj) EnhancedHash.new(obj)
else else
obj obj
end end

View file

@ -7,6 +7,112 @@ end
describe Middleman::CoreExtensions::Data::DataStore do describe Middleman::CoreExtensions::Data::DataStore do
describe "#store" do
before :each do
@subject = described_class.new instance_double("Middleman::Application"),
Middleman::CoreExtensions::Data::DATA_FILE_MATCHER
end
context "when given a name and data" do
it "adds data at the given name" do
@subject.store :foo, { 'bar' => 'baz' }
@subject.store :baz, [:wu, :tang]
expect( @subject.store['foo'] ).to eq({ 'bar' => 'baz' })
expect( @subject.store['baz'] ).to match_array [:wu, :tang]
end
it "overwrites previous keys if given the same key" do
@subject.store :foo, { 'bar' => 'baz' }
@subject.store :foo, [:wu, :tang]
expect( @subject.store['foo'] ).to match_array [:wu, :tang]
end
end
context "when given no args" do
it "returns @local_sources instance var" do
@subject.instance_variable_set :"@local_sources", { foo: 'bar' }
expect( @subject.store ).to eq({ foo: 'bar' })
end
end
end
describe "#callbacks" do
before :each do
@subject = described_class.new instance_double("Middleman::Application"),
Middleman::CoreExtensions::Data::DATA_FILE_MATCHER
end
context "when given a name and proc" do
it "adds a callback at the given name" do
@subject.callbacks :foo, lambda { "bar" }
callback = @subject.instance_variable_get(:@callback_sources)['foo']
expect( callback.call ).to eq "bar"
end
it "overwrites previous keys if given the same key" do
@subject.callbacks :foo, lambda { "bar" }
@subject.callbacks :foo, lambda { "baz" }
callback = @subject.instance_variable_get(:@callback_sources)['foo']
expect( callback.call ).to eq "baz"
end
end
context "when given no args" do
it "returns @callback_sources instance var" do
@subject.instance_variable_set :"@callback_sources", { foo: 'bar' }
expect( @subject.callbacks ).to eq({ foo: 'bar' })
end
end
end
describe "#data_for_path" do
before :each do
@subject = described_class.new instance_double("Middleman::Application"),
Middleman::CoreExtensions::Data::DATA_FILE_MATCHER
end
context "given path matches local data" do
it "returns hash for key" do
@subject.store :foo, { 'bar' => 'baz' }
expect( @subject.data_for_path(:foo) ).to eq({ 'bar' => 'baz' })
end
it "returns array for key" do
@subject.store :foo, [:bar, :baz]
expect( @subject.data_for_path(:foo) ).to match_array [:bar, :baz]
end
end
context "given path matches callback data" do
it "returns value of calback lambda" do
@subject.callbacks :foo, lambda { { 'bar' => 'baz' } }
@subject.callbacks :wu, lambda { [:tang, :clan] }
expect( @subject.data_for_path(:foo) ).to eq({ 'bar' => 'baz' })
expect( @subject.data_for_path(:wu) ).to match_array [:tang, :clan]
end
end
context "given path matches both sources" do
it "returns match from local data" do
@subject.store :foo, { 'local' => 'data' }
@subject.callbacks :foo, lambda { { 'callback' => 'data' } }
expect( @subject.data_for_path(:foo) ).to eq({ 'local' => 'data' })
end
end
context "given path matches no sources" do
it "returns nil" do
expect( @subject.data_for_path(:missing) ).to be_nil
end
end
end
describe "#key?" do describe "#key?" do
it "returns true if key included in local_data, local_sources, or callback_sources" do it "returns true if key included in local_data, local_sources, or callback_sources" do