diff --git a/middleman-core/lib/middleman-core/core_extensions/data.rb b/middleman-core/lib/middleman-core/core_extensions/data.rb index 2f2f4280..18057465 100644 --- a/middleman-core/lib/middleman-core/core_extensions/data.rb +++ b/middleman-core/lib/middleman-core/core_extensions/data.rb @@ -67,7 +67,7 @@ module Middleman # @param [Symbol] name Name of the data, used for namespacing # @param [Hash] content The content for this data # @return [Hash] - Contract Symbol, Hash => Hash + Contract Symbol, Or[Hash, Array] => Hash def store(name=nil, content=nil) @local_sources[name.to_s] = content unless name.nil? || content.nil? @local_sources @@ -148,7 +148,7 @@ module Middleman # # @param [String, Symbol] path The name of the data namespace # @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) response = if store.key?(path.to_s) store[path.to_s] diff --git a/middleman-core/lib/middleman-core/util/data.rb b/middleman-core/lib/middleman-core/util/data.rb index 2bab7fe0..1a521b8d 100644 --- a/middleman-core/lib/middleman-core/util/data.rb +++ b/middleman-core/lib/middleman-core/util/data.rb @@ -29,7 +29,7 @@ module Middleman if obj.is_a? ::Array obj.map { |e| recursively_enhance(e) } elsif obj.is_a? ::Hash - ::Hashie::Mash.new(obj) + EnhancedHash.new(obj) else obj end diff --git a/middleman-core/spec/middleman-core/core_extensions/data_spec.rb b/middleman-core/spec/middleman-core/core_extensions/data_spec.rb index 7c7ddb46..1f0099c9 100644 --- a/middleman-core/spec/middleman-core/core_extensions/data_spec.rb +++ b/middleman-core/spec/middleman-core/core_extensions/data_spec.rb @@ -7,6 +7,112 @@ end 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 it "returns true if key included in local_data, local_sources, or callback_sources" do @@ -38,4 +144,4 @@ describe Middleman::CoreExtensions::Data::DataStore do end -end \ No newline at end of file +end