Merge pull request #2112 from jekyll/no-core-ext

This commit is contained in:
Parker Moore 2014-03-04 17:01:45 -05:00
commit 2985758136
16 changed files with 127 additions and 95 deletions

View File

@ -39,7 +39,7 @@ Gem::Specification.new do |s|
s.add_runtime_dependency('redcarpet', "~> 3.1") s.add_runtime_dependency('redcarpet', "~> 3.1")
s.add_runtime_dependency('toml', '~> 0.1.0') s.add_runtime_dependency('toml', '~> 0.1.0')
s.add_runtime_dependency('jekyll-coffeescript', '~> 1.0') s.add_runtime_dependency('jekyll-coffeescript', '~> 1.0')
s.add_runtime_dependency('jekyll-sass-converter', '~> 1.0.0.rc1') s.add_runtime_dependency('jekyll-sass-converter', '~> 1.0.0.rc3')
s.add_development_dependency('rake', "~> 10.1") s.add_development_dependency('rake', "~> 10.1")
s.add_development_dependency('rdoc', "~> 3.11") s.add_development_dependency('rdoc', "~> 3.11")

View File

@ -30,7 +30,7 @@ require 'toml'
# internal requires # internal requires
require 'jekyll/version' require 'jekyll/version'
require 'jekyll/core_ext' require 'jekyll/utils'
require 'jekyll/stevenson' require 'jekyll/stevenson'
require 'jekyll/deprecator' require 'jekyll/deprecator'
require 'jekyll/configuration' require 'jekyll/configuration'
@ -83,7 +83,7 @@ module Jekyll
config = config.read_config_files(config.config_files(override)) config = config.read_config_files(config.config_files(override))
# Merge DEFAULTS < _config.yml < override # Merge DEFAULTS < _config.yml < override
config = config.deep_merge(override).stringify_keys config = Utils.deep_merge_hashes(config, override).stringify_keys
set_timezone(config['timezone']) if config['timezone'] set_timezone(config['timezone']) if config['timezone']
config config

View File

@ -159,7 +159,7 @@ module Jekyll
begin begin
files.each do |config_file| files.each do |config_file|
new_config = read_config_file(config_file) new_config = read_config_file(config_file)
configuration = configuration.deep_merge(new_config) configuration = Utils.deep_merge_hashes(configuration, new_config)
end end
rescue ArgumentError => err rescue ArgumentError => err
Jekyll.logger.warn "WARNING:", "Error reading configuration. " + Jekyll.logger.warn "WARNING:", "Error reading configuration. " +

View File

@ -20,7 +20,7 @@ module Jekyll
end end
end end
Kramdown::Document.new(content, @config["kramdown"].symbolize_keys).to_html Kramdown::Document.new(content, Utils.symbolize_hash_keys(@config["kramdown"])).to_html
end end
end end

View File

@ -107,7 +107,7 @@ module Jekyll
further_data = Hash[(attrs || self.class::ATTRIBUTES_FOR_LIQUID).map { |attribute| further_data = Hash[(attrs || self.class::ATTRIBUTES_FOR_LIQUID).map { |attribute|
[attribute, send(attribute)] [attribute, send(attribute)]
}] }]
data.deep_merge(further_data) Utils.deep_merge_hashes(data, further_data)
end end
# Recursively render layouts # Recursively render layouts
@ -123,7 +123,7 @@ module Jekyll
used = Set.new([layout]) used = Set.new([layout])
while layout while layout
payload = payload.deep_merge({"content" => output, "page" => layout.data}) payload = Utils.deep_merge_hashes(payload, {"content" => output, "page" => layout.data})
self.output = render_liquid(layout.content, self.output = render_liquid(layout.content,
payload, payload,

View File

@ -1,55 +0,0 @@
class Hash
# Merges self with another hash, recursively.
#
# This code was lovingly stolen from some random gem:
# http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html
#
# Thanks to whoever made it.
def deep_merge(hash)
target = dup
hash.keys.each do |key|
if hash[key].is_a? Hash and self[key].is_a? Hash
target[key] = target[key].deep_merge(hash[key])
next
end
target[key] = hash[key]
end
target
end
# Read array from the supplied hash favouring the singular key
# and then the plural key, and handling any nil entries.
# +hash+ the hash to read from
# +singular_key+ the singular key
# +plural_key+ the plural key
#
# Returns an array
def pluralized_array(singular_key, plural_key)
hash = self
if hash.has_key?(singular_key)
array = [hash[singular_key]] if hash[singular_key]
elsif hash.has_key?(plural_key)
case hash[plural_key]
when String
array = hash[plural_key].split
when Array
array = hash[plural_key].compact
end
end
array || []
end
def symbolize_keys!
keys.each do |key|
self[(key.to_sym rescue key) || key] = delete(key)
end
self
end
def symbolize_keys
dup.symbolize_keys!
end
end

View File

@ -109,10 +109,10 @@ module Jekyll
# #
# Returns nothing. # Returns nothing.
def render(layouts, site_payload) def render(layouts, site_payload)
payload = { payload = Utils.deep_merge_hashes({
"page" => to_liquid, "page" => to_liquid,
'paginator' => pager.to_liquid 'paginator' => pager.to_liquid
}.deep_merge(site_payload) }, site_payload)
do_layout(payload, layouts) do_layout(payload, layouts)
end end

View File

@ -66,13 +66,13 @@ module Jekyll
def populate_categories def populate_categories
if categories.empty? if categories.empty?
self.categories = data.pluralized_array('category', 'categories').map {|c| c.to_s.downcase} self.categories = Utils.pluralized_array_from_hash(data, 'category', 'categories').map {|c| c.to_s.downcase}
end end
categories.flatten! categories.flatten!
end end
def populate_tags def populate_tags
self.tags = data.pluralized_array("tag", "tags").flatten self.tags = Utils.pluralized_array_from_hash(data, "tag", "tags").flatten
end end
# Get the full path to the directory containing the post files # Get the full path to the directory containing the post files
@ -241,10 +241,10 @@ module Jekyll
# Returns nothing. # Returns nothing.
def render(layouts, site_payload) def render(layouts, site_payload)
# construct payload # construct payload
payload = { payload = Utils.deep_merge_hashes({
"site" => { "related_posts" => related_posts(site_payload["site"]["posts"]) }, "site" => { "related_posts" => related_posts(site_payload["site"]["posts"]) },
"page" => to_liquid(EXCERPT_ATTRIBUTES_FOR_LIQUID) "page" => to_liquid(EXCERPT_ATTRIBUTES_FOR_LIQUID)
}.deep_merge(site_payload) }, site_payload)
if generate_excerpt? if generate_excerpt?
extracted_excerpt.do_layout(payload, {}) extracted_excerpt.do_layout(payload, {})

79
lib/jekyll/utils.rb Normal file
View File

@ -0,0 +1,79 @@
module Jekyll
module Utils
class << self
# Merges a master hash with another hash, recursively.
#
# master_hash - the "parent" hash whose values will be overridden
# other_hash - the other hash whose values will be persisted after the merge
#
# This code was lovingly stolen from some random gem:
# http://gemjack.com/gems/tartan-0.1.1/classes/Hash.html
#
# Thanks to whoever made it.
def deep_merge_hashes(master_hash, other_hash)
target = master_hash.dup
other_hash.keys.each do |key|
if other_hash[key].is_a? Hash and target[key].is_a? Hash
target[key] = Utils.deep_merge_hashes(target[key], other_hash[key])
next
end
target[key] = other_hash[key]
end
target
end
# Read array from the supplied hash favouring the singular key
# and then the plural key, and handling any nil entries.
#
# hash - the hash to read from
# singular_key - the singular key
# plural_key - the plural key
#
# Returns an array
def pluralized_array_from_hash(hash, singular_key, plural_key)
if hash.has_key?(singular_key)
array = [hash[singular_key]] if hash[singular_key]
elsif hash.has_key?(plural_key)
case hash[plural_key]
when String
array = hash[plural_key].split
when Array
array = hash[plural_key].compact
end
end
array || []
end
# Apply #to_sym to all keys in the hash
#
# hash - the hash to which to apply this transformation
#
# Returns a new hash with symbolized keys
def symbolize_hash_keys(hash)
target = hash.dup
target.keys.each do |key|
target[(key.to_sym rescue key) || key] = target.delete(key)
end
target
end
# Apply #to_s to all keys in the Hash
#
# hash - the hash to which to apply this transformation
#
# Returns a new hash with stringified keys
def stringify_hash_keys(hash)
target = hash.dup
target.keys.each do |key|
target[(key.to_s rescue key) || key] = target.delete(key)
end
target
end
end
end
end

View File

@ -28,6 +28,17 @@ STDERR.reopen(test(?e, '/dev/null') ? '/dev/null' : 'NUL:')
class Test::Unit::TestCase class Test::Unit::TestCase
include RR::Adapters::TestUnit include RR::Adapters::TestUnit
def build_configs(overrides, base_hash = Jekyll::Configuration::DEFAULTS)
Utils.deep_merge_hashes(base_hash, overrides)
end
def site_configuration(overrides = {})
build_configs({
"source" => source_dir,
"destination" => dest_dir
}, build_configs(overrides))
end
def dest_dir(*subdirs) def dest_dir(*subdirs)
test_dir('dest', *subdirs) test_dir('dest', *subdirs)
end end

View File

@ -156,7 +156,7 @@ class TestConfiguration < Test::Unit::TestCase
should "load different config if specified" do should "load different config if specified" do
mock(SafeYAML).load_file(@paths[:other]) { {"baseurl" => "http://wahoo.dev"} } mock(SafeYAML).load_file(@paths[:other]) { {"baseurl" => "http://wahoo.dev"} }
mock($stdout).puts("Configuration file: #{@paths[:other]}") mock($stdout).puts("Configuration file: #{@paths[:other]}")
assert_equal Jekyll::Configuration::DEFAULTS.deep_merge({ "baseurl" => "http://wahoo.dev" }), Jekyll.configuration({ "config" => @paths[:other] }) assert_equal Utils.deep_merge_hashes(Jekyll::Configuration::DEFAULTS, { "baseurl" => "http://wahoo.dev" }), Jekyll.configuration({ "config" => @paths[:other] })
end end
should "load default config if path passed is empty" do should "load default config if path passed is empty" do
@ -186,7 +186,7 @@ class TestConfiguration < Test::Unit::TestCase
mock(SafeYAML).load_file(@paths[:other]) { {"baseurl" => "http://wahoo.dev"} } mock(SafeYAML).load_file(@paths[:other]) { {"baseurl" => "http://wahoo.dev"} }
mock($stdout).puts("Configuration file: #{@paths[:default]}") mock($stdout).puts("Configuration file: #{@paths[:default]}")
mock($stdout).puts("Configuration file: #{@paths[:other]}") mock($stdout).puts("Configuration file: #{@paths[:other]}")
assert_equal Jekyll::Configuration::DEFAULTS.deep_merge({ "baseurl" => "http://wahoo.dev" }), Jekyll.configuration({ "config" => [@paths[:default], @paths[:other]] }) assert_equal Utils.deep_merge_hashes(Jekyll::Configuration::DEFAULTS, { "baseurl" => "http://wahoo.dev" }), Jekyll.configuration({ "config" => [@paths[:default], @paths[:other]] })
end end
end end
end end

View File

@ -35,7 +35,7 @@ class TestKramdown < Test::Unit::TestCase
assert_match /<p>(&#8220;|“)Pit(&#8217;|)hy(&#8221;|”)<\/p>/, @markdown.convert(%{"Pit'hy"}).strip assert_match /<p>(&#8220;|“)Pit(&#8217;|)hy(&#8221;|”)<\/p>/, @markdown.convert(%{"Pit'hy"}).strip
override = { 'kramdown' => { 'smart_quotes' => 'lsaquo,rsaquo,laquo,raquo' } } override = { 'kramdown' => { 'smart_quotes' => 'lsaquo,rsaquo,laquo,raquo' } }
markdown = Converters::Markdown.new(@config.deep_merge(override)) markdown = Converters::Markdown.new(Utils.deep_merge_hashes(@config, override))
assert_match /<p>(&#171;|«)Pit(&#8250;|)hy(&#187;|»)<\/p>/, markdown.convert(%{"Pit'hy"}).strip assert_match /<p>(&#171;|«)Pit(&#8250;|)hy(&#187;|»)<\/p>/, markdown.convert(%{"Pit'hy"}).strip
end end

View File

@ -3,12 +3,14 @@ require 'helper'
class TestPager < Test::Unit::TestCase class TestPager < Test::Unit::TestCase
def build_site(config = {}) def build_site(config = {})
base = Jekyll::Configuration::DEFAULTS.deep_merge({ base = build_configs({
'source' => source_dir, 'source' => source_dir,
'destination' => dest_dir, 'destination' => dest_dir,
'paginate' => 1 'paginate' => 1
}) })
site = Jekyll::Site.new(base.deep_merge(config)) site = Jekyll::Site.new(site_configuration(
{"paginate" => 1}.merge(config)
))
site.process site.process
site site
end end

View File

@ -1,13 +1,6 @@
require 'helper' require 'helper'
class TestSass < Test::Unit::TestCase class TestSass < Test::Unit::TestCase
def site_configuration(overrides = {})
Jekyll::Configuration::DEFAULTS.deep_merge(overrides).deep_merge({
"source" => source_dir,
"destination" => dest_dir
})
end
def converter(overrides = {}) def converter(overrides = {})
Jekyll::Converters::Sass.new(site_configuration({"sass" => overrides})) Jekyll::Converters::Sass.new(site_configuration({"sass" => overrides}))
end end

View File

@ -6,7 +6,9 @@ class TestTags < Test::Unit::TestCase
def create_post(content, override = {}, converter_class = Jekyll::Converters::Markdown) def create_post(content, override = {}, converter_class = Jekyll::Converters::Markdown)
stub(Jekyll).configuration do stub(Jekyll).configuration do
Jekyll::Configuration::DEFAULTS.deep_merge({'highlighter' => 'pygments'}).deep_merge(override) site_configuration({
"highlighter" => "pygments"
}.merge(override))
end end
site = Site.new(Jekyll.configuration) site = Site.new(Jekyll.configuration)
@ -545,7 +547,7 @@ CONTENT
context "include tag with variable and liquid filters" do context "include tag with variable and liquid filters" do
setup do setup do
stub(Jekyll).configuration do stub(Jekyll).configuration do
Jekyll::Configuration::DEFAULTS.deep_merge({'pygments' => true}).deep_merge({'source' => source_dir, 'destination' => dest_dir}) site_configuration({'pygments' => true})
end end
site = Site.new(Jekyll.configuration) site = Site.new(Jekyll.configuration)

View File

@ -1,63 +1,63 @@
require 'helper' require 'helper'
class TestCoreExt < Test::Unit::TestCase class TestUtils < Test::Unit::TestCase
context "hash" do context "hash" do
context "pluralized_array" do context "pluralized_array" do
should "return empty array with no values" do should "return empty array with no values" do
data = {} data = {}
assert_equal [], data.pluralized_array('tag', 'tags') assert_equal [], Utils.pluralized_array_from_hash(data, 'tag', 'tags')
end end
should "return empty array with no matching values" do should "return empty array with no matching values" do
data = { 'foo' => 'bar' } data = { 'foo' => 'bar' }
assert_equal [], data.pluralized_array('tag', 'tags') assert_equal [], Utils.pluralized_array_from_hash(data, 'tag', 'tags')
end end
should "return empty array with matching nil singular" do should "return empty array with matching nil singular" do
data = { 'foo' => 'bar', 'tag' => nil, 'tags' => ['dog', 'cat'] } data = { 'foo' => 'bar', 'tag' => nil, 'tags' => ['dog', 'cat'] }
assert_equal [], data.pluralized_array('tag', 'tags') assert_equal [], Utils.pluralized_array_from_hash(data, 'tag', 'tags')
end end
should "return single value array with matching singular" do should "return single value array with matching singular" do
data = { 'foo' => 'bar', 'tag' => 'dog', 'tags' => ['dog', 'cat'] } data = { 'foo' => 'bar', 'tag' => 'dog', 'tags' => ['dog', 'cat'] }
assert_equal ['dog'], data.pluralized_array('tag', 'tags') assert_equal ['dog'], Utils.pluralized_array_from_hash(data, 'tag', 'tags')
end end
should "return single value array with matching singular with spaces" do should "return single value array with matching singular with spaces" do
data = { 'foo' => 'bar', 'tag' => 'dog cat', 'tags' => ['dog', 'cat'] } data = { 'foo' => 'bar', 'tag' => 'dog cat', 'tags' => ['dog', 'cat'] }
assert_equal ['dog cat'], data.pluralized_array('tag', 'tags') assert_equal ['dog cat'], Utils.pluralized_array_from_hash(data, 'tag', 'tags')
end end
should "return empty array with matching nil plural" do should "return empty array with matching nil plural" do
data = { 'foo' => 'bar', 'tags' => nil } data = { 'foo' => 'bar', 'tags' => nil }
assert_equal [], data.pluralized_array('tag', 'tags') assert_equal [], Utils.pluralized_array_from_hash(data, 'tag', 'tags')
end end
should "return empty array with matching empty array" do should "return empty array with matching empty array" do
data = { 'foo' => 'bar', 'tags' => [] } data = { 'foo' => 'bar', 'tags' => [] }
assert_equal [], data.pluralized_array('tag', 'tags') assert_equal [], Utils.pluralized_array_from_hash(data, 'tag', 'tags')
end end
should "return single value array with matching plural with single string value" do should "return single value array with matching plural with single string value" do
data = { 'foo' => 'bar', 'tags' => 'dog' } data = { 'foo' => 'bar', 'tags' => 'dog' }
assert_equal ['dog'], data.pluralized_array('tag', 'tags') assert_equal ['dog'], Utils.pluralized_array_from_hash(data, 'tag', 'tags')
end end
should "return multiple value array with matching plural with single string value with spaces" do should "return multiple value array with matching plural with single string value with spaces" do
data = { 'foo' => 'bar', 'tags' => 'dog cat' } data = { 'foo' => 'bar', 'tags' => 'dog cat' }
assert_equal ['dog', 'cat'], data.pluralized_array('tag', 'tags') assert_equal ['dog', 'cat'], Utils.pluralized_array_from_hash(data, 'tag', 'tags')
end end
should "return single value array with matching plural with single value array" do should "return single value array with matching plural with single value array" do
data = { 'foo' => 'bar', 'tags' => ['dog'] } data = { 'foo' => 'bar', 'tags' => ['dog'] }
assert_equal ['dog'], data.pluralized_array('tag', 'tags') assert_equal ['dog'], Utils.pluralized_array_from_hash(data, 'tag', 'tags')
end end
should "return multiple value array with matching plural with multiple value array" do should "return multiple value array with matching plural with multiple value array" do
data = { 'foo' => 'bar', 'tags' => ['dog', 'cat'] } data = { 'foo' => 'bar', 'tags' => ['dog', 'cat'] }
assert_equal ['dog', 'cat'], data.pluralized_array('tag', 'tags') assert_equal ['dog', 'cat'], Utils.pluralized_array_from_hash(data, 'tag', 'tags')
end end
end end