Merge branch 'master' into pathawks-fp/jsonify-drops

* master: (38 commits)
  Mention where it came from. [ci skip]
  Update history to reflect merge of #4944 [ci skip]
  Update history to reflect merge of #4943 [ci skip]
  Mention where it came from. [ci skip]
  Update history to reflect merge of #4942 [ci skip]
  Update history to reflect merge of #4941
  External: remove &block arg, use block_given?
  Update history to reflect merge of #4936 [ci skip]
  lib/jekyll.rb: require document_drop to ease our pain
  Sort the results of the require_all glob.
  Rubocop fixes
  Reset {{ layout }} between each render & merge layout data properly
  Add failing test for layout data inheritance bug (#4433)
  Add failing test for layout bug (#4897)
  Fix tests for plugins in configuration.
  Define Drop#each so we can use the new frozen/duping behavior
  Don't default 'include' and 'exclude' to an empty array
  Fix some minor things in the tests
  Freeze configuration defaults & duplicate in deep_merge_hashes if need be.
  Remove merge conflicts I forgot to fix.
  ...
This commit is contained in:
Parker Moore 2016-05-25 15:55:47 -07:00
commit e56e58e498
No known key found for this signature in database
GPG Key ID: 193CDEBA72063C58
30 changed files with 427 additions and 201 deletions

View File

@ -7,51 +7,28 @@ AllCops:
- lib/jekyll/collection.rb - lib/jekyll/collection.rb
- lib/jekyll/command.rb - lib/jekyll/command.rb
- lib/jekyll/configuration.rb - lib/jekyll/configuration.rb
- lib/jekyll/converter.rb
- lib/jekyll/converters/identity.rb - lib/jekyll/converters/identity.rb
- lib/jekyll/converters/markdown
- lib/jekyll/converters/markdown/kramdown_parser.rb - lib/jekyll/converters/markdown/kramdown_parser.rb
- lib/jekyll/converters/markdown/rdiscount_parser.rb
- lib/jekyll/converters/markdown/redcarpet_parser.rb - lib/jekyll/converters/markdown/redcarpet_parser.rb
- lib/jekyll/converters/markdown.rb - lib/jekyll/converters/markdown.rb
- lib/jekyll/converters/smartypants.rb
- lib/jekyll/convertible.rb - lib/jekyll/convertible.rb
- lib/jekyll/deprecator.rb - lib/jekyll/deprecator.rb
- lib/jekyll/document.rb - lib/jekyll/document.rb
- lib/jekyll/drops/collection_drop.rb
- lib/jekyll/drops/document_drop.rb
- lib/jekyll/drops/drop.rb
- lib/jekyll/drops/jekyll_drop.rb
- lib/jekyll/drops/site_drop.rb - lib/jekyll/drops/site_drop.rb
- lib/jekyll/drops/unified_payload_drop.rb
- lib/jekyll/drops/url_drop.rb
- lib/jekyll/entry_filter.rb - lib/jekyll/entry_filter.rb
- lib/jekyll/errors.rb
- lib/jekyll/excerpt.rb
- lib/jekyll/external.rb
- lib/jekyll/filters.rb - lib/jekyll/filters.rb
- lib/jekyll/frontmatter_defaults.rb - lib/jekyll/frontmatter_defaults.rb
- lib/jekyll/generator.rb
- lib/jekyll/hooks.rb
- lib/jekyll/layout.rb - lib/jekyll/layout.rb
- lib/jekyll/liquid_extensions.rb
- lib/jekyll/liquid_renderer/file.rb
- lib/jekyll/liquid_renderer/table.rb - lib/jekyll/liquid_renderer/table.rb
- lib/jekyll/liquid_renderer.rb - lib/jekyll/liquid_renderer.rb
- lib/jekyll/log_adapter.rb
- lib/jekyll/page.rb - lib/jekyll/page.rb
- lib/jekyll/plugin.rb
- lib/jekyll/plugin_manager.rb - lib/jekyll/plugin_manager.rb
- lib/jekyll/publisher.rb
- lib/jekyll/reader.rb - lib/jekyll/reader.rb
- lib/jekyll/readers/collection_reader.rb
- lib/jekyll/readers/data_reader.rb
- lib/jekyll/readers/layout_reader.rb - lib/jekyll/readers/layout_reader.rb
- lib/jekyll/readers/page_reader.rb - lib/jekyll/readers/page_reader.rb
- lib/jekyll/readers/post_reader.rb - lib/jekyll/readers/post_reader.rb
- lib/jekyll/readers/static_file_reader.rb - lib/jekyll/readers/static_file_reader.rb
- lib/jekyll/regenerator.rb - lib/jekyll/regenerator.rb
- lib/jekyll/related_posts.rb
- lib/jekyll/renderer.rb - lib/jekyll/renderer.rb
- lib/jekyll/site.rb - lib/jekyll/site.rb
- lib/jekyll/static_file.rb - lib/jekyll/static_file.rb

View File

@ -43,6 +43,13 @@
* 3.2.x/master: Fix defaults for Documents (posts/collection docs) (#4808) * 3.2.x/master: Fix defaults for Documents (posts/collection docs) (#4808)
* Don't rescue LoadError or bundler load errors for Bundler. (#4857) * Don't rescue LoadError or bundler load errors for Bundler. (#4857)
### Forward Ports
* From v3.1.4: Add ExcerptDrop and remove excerpt's ability to refer to itself in Liquid (#4941)
* From v3.1.4: Configuration permalink fix and addition of Configuration.from and sorting `site.collections` by label (#4942)
* From v3.1.4: Fix `{{ layout }}` oddities (proper inheritance & fixing overflow of old data) (#4943)
* From v3.1.5: Sort the results of the `require_all` glob (#4944)
### Development Fixes ### Development Fixes
* Add project maintainer profile links (#4591) * Add project maintainer profile links (#4591)
@ -60,6 +67,7 @@
* Update `jekyll/commands*` to pass rubocop rules (#4888) * Update `jekyll/commands*` to pass rubocop rules (#4888)
* Clean up many test files to pass Rubocop rules (#4902) * Clean up many test files to pass Rubocop rules (#4902)
* Rubocop cleanup for some utils and further test files (#4916) * Rubocop cleanup for some utils and further test files (#4916)
* Rubocop: Low hanging fruit (#4936)
### Site Enhancements ### Site Enhancements

View File

@ -35,3 +35,36 @@ Feature: Layout data
When I run jekyll build When I run jekyll build
Then the "_site/index.html" file should exist Then the "_site/index.html" file should exist
And I should see "page content\n foo: my custom data" in "_site/index.html" And I should see "page content\n foo: my custom data" in "_site/index.html"
Scenario: Inherit custom layout data and clear when not present
Given I have a _layouts directory
And I have a "_layouts/default.html" file with content:
"""
---
bar: i'm default
---
{{ content }} foo: '{{ layout.foo }}' bar: '{{ layout.bar }}'
"""
And I have a "_layouts/special.html" file with content:
"""
---
layout: default
foo: my special data
bar: im special
---
{{ content }}
"""
And I have a "_layouts/page.html" file with content:
"""
---
layout: default
bar: im page
---
{{ content }}
"""
And I have an "index.html" page with layout "special" that contains "page content"
And I have an "jekyll.html" page with layout "page" that contains "page content"
When I run jekyll build
Then the "_site/index.html" file should exist
And I should see "page content\n foo: 'my special data' bar: 'im special'" in "_site/index.html"
And I should see "page content\n foo: '' bar: 'im page'" in "_site/jekyll.html"

View File

@ -7,7 +7,7 @@ $LOAD_PATH.unshift File.dirname(__FILE__) # For use/testing when no gem is insta
# Returns nothing. # Returns nothing.
def require_all(path) def require_all(path)
glob = File.join(File.dirname(__FILE__), path, '*.rb') glob = File.join(File.dirname(__FILE__), path, '*.rb')
Dir[glob].each do |f| Dir[glob].sort.each do |f|
require f require f
end end
end end
@ -98,18 +98,16 @@ module Jekyll
# list of option names and their defaults. # list of option names and their defaults.
# #
# Returns the final configuration Hash. # Returns the final configuration Hash.
def configuration(override = {}) def configuration(override = Hash.new)
config = Configuration[Configuration::DEFAULTS] config = Configuration.new
override = Configuration[override].stringify_keys
unless override.delete('skip_config_files') unless override.delete('skip_config_files')
config = config.read_config_files(config.config_files(override)) config = config.read_config_files(config.config_files(override))
end end
# Merge DEFAULTS < _config.yml < override # Merge DEFAULTS < _config.yml < override
config = Utils.deep_merge_hashes(config, override).stringify_keys Configuration.from(Utils.deep_merge_hashes(config, override)).tap do |config|
set_timezone(config['timezone']) if config['timezone'] set_timezone(config['timezone']) if config['timezone']
end
config
end end
# Public: Set the TZ environment variable to use the timezone specified # Public: Set the TZ environment variable to use the timezone specified
@ -173,6 +171,7 @@ module Jekyll
end end
require "jekyll/drops/drop" require "jekyll/drops/drop"
require "jekyll/drops/document_drop"
require_all 'jekyll/commands' require_all 'jekyll/commands'
require_all 'jekyll/converters' require_all 'jekyll/converters'
require_all 'jekyll/converters/markdown' require_all 'jekyll/converters/markdown'

View File

@ -72,7 +72,24 @@ module Jekyll
'hard_wrap' => false, 'hard_wrap' => false,
'footnote_nr' => 1 'footnote_nr' => 1
} }
}] }.map { |k, v| [k, v.freeze] }].freeze
class << self
# Static: Produce a Configuration ready for use in a Site.
# It takes the input, fills in the defaults where values do not
# exist, and patches common issues including migrating options for
# backwards compatiblity. Except where a key or value is being fixed,
# the user configuration will override the defaults.
#
# user_config - a Hash or Configuration of overrides.
#
# Returns a Configuration filled with defaults and fixed for common
# problems and backwards-compatibility.
def from(user_config)
Utils.deep_merge_hashes(DEFAULTS, Configuration[user_config].stringify_keys).
fix_common_issues.add_default_collections
end
end
# Public: Turn all keys into string # Public: Turn all keys into string
# #
@ -169,6 +186,7 @@ module Jekyll
begin begin
files.each do |config_file| files.each do |config_file|
next if config_file.nil? or config_file.empty?
new_config = read_config_file(config_file) new_config = read_config_file(config_file)
configuration = Utils.deep_merge_hashes(configuration, new_config) configuration = Utils.deep_merge_hashes(configuration, new_config)
end end
@ -228,7 +246,6 @@ module Jekyll
end end
%w(include exclude).each do |option| %w(include exclude).each do |option|
config[option] ||= []
if config[option].is_a?(String) if config[option].is_a?(String)
Jekyll::Deprecator.deprecation_message "The '#{option}' configuration option" \ Jekyll::Deprecator.deprecation_message "The '#{option}' configuration option" \
" must now be specified as an array, but you specified" \ " must now be specified as an array, but you specified" \
@ -236,7 +253,7 @@ module Jekyll
" as a list of comma-separated values." " as a list of comma-separated values."
config[option] = csv_to_array(config[option]) config[option] = csv_to_array(config[option])
end end
config[option].map!(&:to_s) config[option].map!(&:to_s) if config[option]
end end
if (config['kramdown'] || {}).key?('use_coderay') if (config['kramdown'] || {}).key?('use_coderay')
@ -271,14 +288,22 @@ module Jekyll
def add_default_collections def add_default_collections
config = clone config = clone
# It defaults to `{}`, so this is only if someone sets it to null manually.
return config if config['collections'].nil? return config if config['collections'].nil?
# Ensure we have a hash.
if config['collections'].is_a?(Array) if config['collections'].is_a?(Array)
config['collections'] = Hash[config['collections'].map { |c| [c, {}] }] config['collections'] = Hash[config['collections'].map { |c| [c, {}] }]
end end
config['collections']['posts'] ||= {}
config['collections']['posts']['output'] = true config['collections'] = Utils.deep_merge_hashes(
config['collections']['posts']['permalink'] = style_to_permalink(config['permalink']) { 'posts' => {} }, config['collections']
).tap do |collections|
collections['posts']['output'] = true
if config['permalink']
collections['posts']['permalink'] ||= style_to_permalink(config['permalink'])
end
end
config config
end end

View File

@ -5,14 +5,14 @@ module Jekyll
def initialize(config) def initialize(config)
Jekyll::External.require_with_graceful_fail "rdiscount" Jekyll::External.require_with_graceful_fail "rdiscount"
@config = config @config = config
@rdiscount_extensions = @config['rdiscount']['extensions'].map(&:to_sym) @rdiscount_extensions = @config["rdiscount"]["extensions"].map(&:to_sym)
end end
def convert(content) def convert(content)
rd = RDiscount.new(content, *@rdiscount_extensions) rd = RDiscount.new(content, *@rdiscount_extensions)
html = rd.to_html html = rd.to_html
if @config['rdiscount']['toc_token'] if @config["rdiscount"]["toc_token"]
html = replace_generated_toc(rd, html, @config['rdiscount']['toc_token']) html = replace_generated_toc(rd, html, @config["rdiscount"]["toc_token"])
end end
html html
end end
@ -21,7 +21,7 @@ module Jekyll
def replace_generated_toc(rd, html, toc_token) def replace_generated_toc(rd, html, toc_token)
if rd.generate_toc && html.include?(toc_token) if rd.generate_toc && html.include?(toc_token)
utf8_toc = rd.toc_content utf8_toc = rd.toc_content
utf8_toc.force_encoding('utf-8') if utf8_toc.respond_to?(:force_encoding) utf8_toc.force_encoding("utf-8") if utf8_toc.respond_to?(:force_encoding)
html.gsub(toc_token, utf8_toc) html.gsub(toc_token, utf8_toc)
else else
html html

View File

@ -209,10 +209,13 @@ module Jekyll
used = Set.new([layout]) used = Set.new([layout])
# Reset the payload layout data to ensure it starts fresh for each page.
payload["layout"] = nil
while layout while layout
Jekyll.logger.debug "Rendering Layout:", path Jekyll.logger.debug "Rendering Layout:", path
payload["content"] = output payload["content"] = output
payload["layout"] = Utils.deep_merge_hashes(payload["layout"] || {}, layout.data) payload["layout"] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {})
self.output = render_liquid(layout.content, self.output = render_liquid(layout.content,
payload, payload,

View File

@ -19,13 +19,13 @@ module Jekyll
end end
def excerpt def excerpt
fallback_data['excerpt'].to_s fallback_data["excerpt"].to_s
end end
def <=>(other) def <=>(other)
return nil unless other.is_a? DocumentDrop return nil unless other.is_a? DocumentDrop
cmp = self['date'] <=> other['date'] cmp = self["date"] <=> other["date"]
cmp = self['path'] <=> other['path'] if cmp.nil? || cmp == 0 cmp = self["path"] <=> other["path"] if cmp.nil? || cmp == 0
cmp cmp
end end

View File

@ -5,7 +5,7 @@ module Jekyll
class Drop < Liquid::Drop class Drop < Liquid::Drop
include Enumerable include Enumerable
NON_CONTENT_METHODS = [:[], :[]=, :inspect, :to_h, :fallback_data, :collapse_document].freeze NON_CONTENT_METHODS = [:fallback_data, :collapse_document].freeze
# Get or set whether the drop class is mutable. # Get or set whether the drop class is mutable.
# Mutability determines whether or not pre-defined fields may be # Mutability determines whether or not pre-defined fields may be
@ -15,11 +15,11 @@ module Jekyll
# #
# Returns the mutability of the class # Returns the mutability of the class
def self.mutable(is_mutable = nil) def self.mutable(is_mutable = nil)
if is_mutable @is_mutable = if is_mutable
@is_mutable = is_mutable is_mutable
else else
@is_mutable = false false
end end
end end
def self.mutable? def self.mutable?
@ -88,7 +88,7 @@ module Jekyll
# Returns an Array of strings which represent method-specific keys. # Returns an Array of strings which represent method-specific keys.
def content_methods def content_methods
@content_methods ||= ( @content_methods ||= (
self.class.instance_methods(false) - NON_CONTENT_METHODS self.class.instance_methods - Jekyll::Drops::Drop.instance_methods - NON_CONTENT_METHODS
).map(&:to_s).reject do |method| ).map(&:to_s).reject do |method|
method.end_with?("=") method.end_with?("=")
end end
@ -136,7 +136,7 @@ module Jekyll
# #
# Returns a pretty generation of the hash representation of the Drop. # Returns a pretty generation of the hash representation of the Drop.
def inspect def inspect
require 'json' require "json"
JSON.pretty_generate to_h JSON.pretty_generate to_h
end end
@ -165,6 +165,12 @@ module Jekyll
keys.each(&block) keys.each(&block)
end end
def each(&block)
each_key.each do |key|
yield key, self[key]
end
end
def merge(other, &block) def merge(other, &block)
self.dup.tap do |me| self.dup.tap do |me|
if block.nil? if block.nil?

View File

@ -0,0 +1,15 @@
# encoding: UTF-8
module Jekyll
module Drops
class ExcerptDrop < DocumentDrop
def layout
@obj.doc.data["layout"]
end
def excerpt
nil
end
end
end
end

View File

@ -28,7 +28,7 @@ module Jekyll
end end
def collections def collections
@site_collections ||= @obj.collections.values.map(&:to_liquid) @site_collections ||= @obj.collections.values.sort_by(&:label).map(&:to_liquid)
end end
private private

View File

@ -19,20 +19,20 @@ module Jekyll
end end
def title def title
Utils.slugify(@obj.data['slug'], :mode => "pretty", :cased => true) || Utils.slugify(@obj.data["slug"], :mode => "pretty", :cased => true) ||
Utils.slugify(@obj.basename_without_ext, :mode => "pretty", :cased => true) Utils.slugify(@obj.basename_without_ext, :mode => "pretty", :cased => true)
end end
def slug def slug
Utils.slugify(@obj.data['slug']) || Utils.slugify(@obj.basename_without_ext) Utils.slugify(@obj.data["slug"]) || Utils.slugify(@obj.basename_without_ext)
end end
def categories def categories
category_set = Set.new category_set = Set.new
Array(@obj.data['categories']).each do |category| Array(@obj.data["categories"]).each do |category|
category_set << category.to_s.downcase category_set << category.to_s.downcase
end end
category_set.to_a.join('/') category_set.to_a.join("/")
end end
def year def year

View File

@ -7,7 +7,7 @@ module Jekyll
attr_writer :output attr_writer :output
def_delegators :@doc, :site, :name, :ext, :relative_path, :extname, def_delegators :@doc, :site, :name, :ext, :relative_path, :extname,
:render_with_liquid?, :collection, :related_posts :render_with_liquid?, :collection, :related_posts, :url
# Initialize this Excerpt instance. # Initialize this Excerpt instance.
# #
@ -59,10 +59,7 @@ module Jekyll
end end
def to_liquid def to_liquid
doc.data['excerpt'] = nil Jekyll::Drops::ExcerptDrop.new(self)
@to_liquid ||= doc.to_liquid
doc.data['excerpt'] = self
@to_liquid
end end
# Returns the shorthand String identifier of this doc. # Returns the shorthand String identifier of this doc.

View File

@ -17,13 +17,13 @@ module Jekyll
# #
# names - a string gem name or array of gem names # names - a string gem name or array of gem names
# #
def require_if_present(names, &block) def require_if_present(names)
Array(names).each do |name| Array(names).each do |name|
begin begin
require name require name
rescue LoadError rescue LoadError
Jekyll.logger.debug "Couldn't load #{name}. Skipping." Jekyll.logger.debug "Couldn't load #{name}. Skipping."
block.call(name) if block yield(name) if block_given?
false false
end end
end end
@ -39,7 +39,7 @@ module Jekyll
def require_with_graceful_fail(names) def require_with_graceful_fail(names)
Array(names).each do |name| Array(names).each do |name|
begin begin
Jekyll.logger.debug "Requiring:", "#{name}" Jekyll.logger.debug "Requiring:", name.to_s
require name require name
rescue LoadError => e rescue LoadError => e
Jekyll.logger.error "Dependency Error:", <<-MSG Jekyll.logger.error "Dependency Error:", <<-MSG
@ -50,7 +50,7 @@ The full error message from Ruby is: '#{e.message}'
If you run into trouble, you can find helpful resources at http://jekyllrb.com/help/! If you run into trouble, you can find helpful resources at http://jekyllrb.com/help/!
MSG MSG
raise Jekyll::Errors::MissingDependencyException.new(name) raise Jekyll::Errors::MissingDependencyException, name
end end
end end
end end

View File

@ -4,38 +4,38 @@ module Jekyll
# compatibility layer for octopress-hooks users # compatibility layer for octopress-hooks users
PRIORITY_MAP = { PRIORITY_MAP = {
:low => 10, :low => 10,
:normal => 20, :normal => 20,
:high => 30 :high => 30
}.freeze }.freeze
# initial empty hooks # initial empty hooks
@registry = { @registry = {
:site => { :site => {
:after_init => [], :after_init => [],
:after_reset => [], :after_reset => [],
:post_read => [], :post_read => [],
:pre_render => [], :pre_render => [],
:post_render => [], :post_render => [],
:post_write => [] :post_write => []
}, },
:pages => { :pages => {
:post_init => [], :post_init => [],
:pre_render => [], :pre_render => [],
:post_render => [], :post_render => [],
:post_write => [] :post_write => []
}, },
:posts => { :posts => {
:post_init => [], :post_init => [],
:pre_render => [], :pre_render => [],
:post_render => [], :post_render => [],
:post_write => [] :post_write => []
}, },
:documents => { :documents => {
:post_init => [], :post_init => [],
:pre_render => [], :pre_render => [],
:post_render => [], :post_render => [],
:post_write => [] :post_write => []
} }
} }
@ -61,10 +61,10 @@ module Jekyll
# register a single hook to be called later, internal API # register a single hook to be called later, internal API
def self.register_one(owner, event, priority, &block) def self.register_one(owner, event, priority, &block)
@registry[owner] ||={ @registry[owner] ||={
:post_init => [], :post_init => [],
:pre_render => [], :pre_render => [],
:post_render => [], :post_render => [],
:post_write => [] :post_write => []
} }
unless @registry[owner][event] unless @registry[owner][event]

View File

@ -8,7 +8,7 @@ module Jekyll
def parse(content) def parse(content)
measure_time do measure_time do
@template = Liquid::Template.parse(content, line_numbers: true) @template = Liquid::Template.parse(content, :line_numbers => true)
end end
self self

View File

@ -7,7 +7,7 @@ module Jekyll
:info => ::Logger::INFO, :info => ::Logger::INFO,
:warn => ::Logger::WARN, :warn => ::Logger::WARN,
:error => ::Logger::ERROR :error => ::Logger::ERROR
} }.freeze
# Public: Create a new instance of a log writer # Public: Create a new instance of a log writer
# #
@ -98,7 +98,7 @@ module Jekyll
# #
# Returns the formatted message # Returns the formatted message
def message(topic, message) def message(topic, message)
msg = formatted_topic(topic) + message.to_s.gsub(/\s+/, ' ') msg = formatted_topic(topic) + message.to_s.gsub(/\s+/, " ")
messages << msg messages << msg
msg msg
end end

View File

@ -1,12 +1,12 @@
module Jekyll module Jekyll
class Plugin class Plugin
PRIORITIES = { PRIORITIES = {
:low => -10, :low => -10,
:highest => 100, :highest => 100,
:lowest => -100, :lowest => -100,
:normal => 0, :normal => 0,
:high => 10 :high => 10
} }.freeze
# #

View File

@ -76,7 +76,7 @@ module Jekyll
# #
# Returns an Array of plugin search paths # Returns an Array of plugin search paths
def plugins_path def plugins_path
if site.config['plugins_dir'] == Jekyll::Configuration::DEFAULTS['plugins_dir'] if site.config['plugins_dir'].eql? Jekyll::Configuration::DEFAULTS['plugins_dir']
[site.in_source_dir(site.config['plugins_dir'])] [site.in_source_dir(site.config['plugins_dir'])]
else else
Array(site.config['plugins_dir']).map { |d| File.expand_path(d) } Array(site.config['plugins_dir']).map { |d| File.expand_path(d) }

View File

@ -15,7 +15,7 @@ module Jekyll
private private
def can_be_published?(thing) def can_be_published?(thing)
thing.data.fetch('published', true) || @site.unpublished thing.data.fetch("published", true) || @site.unpublished
end end
end end
end end

View File

@ -30,14 +30,14 @@ module Jekyll
return unless File.directory?(dir) && !@entry_filter.symlink?(dir) return unless File.directory?(dir) && !@entry_filter.symlink?(dir)
entries = Dir.chdir(dir) do entries = Dir.chdir(dir) do
Dir['*.{yaml,yml,json,csv}'] + Dir['*'].select { |fn| File.directory?(fn) } Dir["*.{yaml,yml,json,csv}"] + Dir["*"].select { |fn| File.directory?(fn) }
end end
entries.each do |entry| entries.each do |entry|
path = @site.in_source_dir(dir, entry) path = @site.in_source_dir(dir, entry)
next if @entry_filter.symlink?(path) next if @entry_filter.symlink?(path)
key = sanitize_filename(File.basename(entry, '.*')) key = sanitize_filename(File.basename(entry, ".*"))
if File.directory?(path) if File.directory?(path)
read_data_to(path, data[key] = {}) read_data_to(path, data[key] = {})
else else
@ -51,20 +51,20 @@ module Jekyll
# Returns the contents of the data file. # Returns the contents of the data file.
def read_data_file(path) def read_data_file(path)
case File.extname(path).downcase case File.extname(path).downcase
when '.csv' when ".csv"
CSV.read(path, { CSV.read(path, {
:headers => true, :headers => true,
:encoding => site.config['encoding'] :encoding => site.config["encoding"]
}).map(&:to_hash) }).map(&:to_hash)
else else
SafeYAML.load_file(path) SafeYAML.load_file(path)
end end
end end
def sanitize_filename(name) def sanitize_filename(name)
name.gsub!(/[^\w\s-]+/, '') name.gsub!(/[^\w\s-]+/, "")
name.gsub!(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2') name.gsub!(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2')
name.gsub(/\s+/, '_') name.gsub(/\s+/, "_")
end end
end end
end end

View File

@ -9,7 +9,7 @@ module Jekyll
def initialize(post) def initialize(post)
@post = post @post = post
@site = post.site @site = post.site
Jekyll::External.require_with_graceful_fail('classifier-reborn') if site.lsi Jekyll::External.require_with_graceful_fail("classifier-reborn") if site.lsi
end end
def build def build

View File

@ -136,10 +136,13 @@ module Jekyll
used = Set.new([layout]) used = Set.new([layout])
# Reset the payload layout data to ensure it starts fresh for each page.
payload["layout"] = nil
while layout while layout
payload['content'] = output payload['content'] = output
payload['page'] = document.to_liquid payload['page'] = document.to_liquid
payload['layout'] = Utils.deep_merge_hashes(payload['layout'] || {}, layout.data) payload['layout'] = Utils.deep_merge_hashes(layout.data, payload["layout"] || {})
output = render_liquid( output = render_liquid(
layout.content, layout.content,

View File

@ -54,6 +54,10 @@ module Jekyll
target.default_proc = overwrite.default_proc target.default_proc = overwrite.default_proc
end end
target.each do |key, val|
target[key] = val.dup if val.frozen? && duplicable?(val)
end
target target
end end
@ -61,6 +65,15 @@ module Jekyll
value.is_a?(Hash) || value.is_a?(Drops::Drop) value.is_a?(Hash) || value.is_a?(Drops::Drop)
end end
def duplicable?(obj)
case obj
when nil, false, true, Symbol, Numeric
false
else
true
end
end
# Read array from the supplied hash favouring the singular key # Read array from the supplied hash favouring the singular key
# and then the plural key, and handling any nil entries. # and then the plural key, and handling any nil entries.
# #

View File

@ -28,7 +28,7 @@ require "minitest/autorun"
require "minitest/reporters" require "minitest/reporters"
require "minitest/profile" require "minitest/profile"
require "rspec/mocks" require "rspec/mocks"
require "jekyll" require_relative "../lib/jekyll.rb"
Jekyll.logger = Logger.new(StringIO.new) Jekyll.logger = Logger.new(StringIO.new)
@ -61,8 +61,30 @@ module Minitest::Assertions
end end
end end
module DirectoryHelpers
def dest_dir(*subdirs)
test_dir("dest", *subdirs)
end
def source_dir(*subdirs)
test_dir("source", *subdirs)
end
def test_dir(*subdirs)
File.join(File.dirname(__FILE__), *subdirs)
end
end
class JekyllUnitTest < Minitest::Test class JekyllUnitTest < Minitest::Test
include ::RSpec::Mocks::ExampleMethods include ::RSpec::Mocks::ExampleMethods
include DirectoryHelpers
extend DirectoryHelpers
def mu_pp(obj)
s = obj.is_a?(Hash) ? JSON.pretty_generate(obj) : obj.inspect
s = s.encode Encoding.default_external if defined? Encoding
s
end
def mocks_expect(*args) def mocks_expect(*args)
RSpec::Mocks::ExampleMethods::ExpectHost.instance_method(:expect)\ RSpec::Mocks::ExampleMethods::ExpectHost.instance_method(:expect)\
@ -85,9 +107,12 @@ class JekyllUnitTest < Minitest::Test
Jekyll::Site.new(site_configuration(overrides)) Jekyll::Site.new(site_configuration(overrides))
end end
def build_configs(overrides, base_hash = Jekyll::Configuration::DEFAULTS) def default_configuration
Marshal.load(Marshal.dump(Jekyll::Configuration::DEFAULTS))
end
def build_configs(overrides, base_hash = default_configuration)
Utils.deep_merge_hashes(base_hash, overrides) Utils.deep_merge_hashes(base_hash, overrides)
.fix_common_issues.backwards_compatibilize.add_default_collections
end end
def site_configuration(overrides = {}) def site_configuration(overrides = {})
@ -98,14 +123,9 @@ class JekyllUnitTest < Minitest::Test
build_configs({ build_configs({
"source" => source_dir "source" => source_dir
}, full_overrides) }, full_overrides)
end .fix_common_issues
.backwards_compatibilize
def dest_dir(*subdirs) .add_default_collections
test_dir("dest", *subdirs)
end
def source_dir(*subdirs)
test_dir("source", *subdirs)
end end
def clear_dest def clear_dest
@ -113,10 +133,6 @@ class JekyllUnitTest < Minitest::Test
FileUtils.rm_rf(source_dir(".jekyll-metadata")) FileUtils.rm_rf(source_dir(".jekyll-metadata"))
end end
def test_dir(*subdirs)
File.join(File.dirname(__FILE__), *subdirs)
end
def directory_with_contents(path) def directory_with_contents(path)
FileUtils.rm_rf(path) FileUtils.rm_rf(path)
FileUtils.mkdir(path) FileUtils.mkdir(path)

View File

@ -1,7 +1,62 @@
require 'helper' require 'helper'
class TestConfiguration < JekyllUnitTest class TestConfiguration < JekyllUnitTest
@@defaults = Jekyll::Configuration::DEFAULTS.add_default_collections.freeze @@test_config = {
"source" => new(nil).source_dir,
"destination" => dest_dir
}
context ".from" do
should "create a Configuration object" do
assert_instance_of Configuration, Configuration.from({})
end
should "merge input over defaults" do
result = Configuration.from({"source" => "blah"})
refute_equal result["source"], Configuration::DEFAULTS["source"]
assert_equal result["source"], "blah"
end
should "fix common mistakes" do
result = Configuration.from({"paginate" => 0})
assert_nil result["paginate"], "Expected 'paginate' to be corrected to 'nil', but was #{result["paginate"].inspect}"
end
should "add default collections" do
result = Configuration.from({})
assert_equal result["collections"], {"posts" => {"output" => true, "permalink" => "/:categories/:year/:month/:day/:title:output_ext"}}
end
should "NOT backwards-compatibilize" do
assert Configuration.from("watch" => true)["watch"], "Expected the 'watch' key to not be removed."
end
end
context "#add_default_collections" do
should "no-op if collections is nil" do
result = Configuration[{"collections" => nil}].add_default_collections
assert_nil result["collections"]
end
should "turn an array into a hash" do
result = Configuration[{"collections" => %w{methods}}].add_default_collections
assert_instance_of Hash, result["collections"]
assert_equal result["collections"], {"posts" => {"output" => true}, "methods" => {}}
end
should "only assign collections.posts.permalink if a permalink is specified" do
result = Configuration[{"permalink" => "pretty", "collections" => {}}].add_default_collections
assert_equal result["collections"], {"posts" => {"output" => true, "permalink" => "/:categories/:year/:month/:day/:title/"}}
result = Configuration[{"permalink" => nil, "collections" => {}}].add_default_collections
assert_equal result["collections"], {"posts" => {"output" => true}}
end
should "forces posts to output" do
result = Configuration[{"collections" => {"posts" => {"output" => false}}}].add_default_collections
assert_equal result["collections"]["posts"]["output"], true
end
end
context "#stringify_keys" do context "#stringify_keys" do
setup do setup do
@ -154,27 +209,27 @@ class TestConfiguration < JekyllUnitTest
end end
context "loading configuration" do context "loading configuration" do
setup do setup do
@path = File.join(Dir.pwd, '_config.yml') @path = source_dir('_config.yml')
@user_config = File.join(Dir.pwd, "my_config_file.yml") @user_config = File.join(Dir.pwd, "my_config_file.yml")
end end
should "fire warning with no _config.yml" do should "fire warning with no _config.yml" do
allow(SafeYAML).to receive(:load_file).with(@path) { raise SystemCallError, "No such file or directory - #{@path}" } allow(SafeYAML).to receive(:load_file).with(@path) { raise SystemCallError, "No such file or directory - #{@path}" }
allow($stderr).to receive(:puts).with("Configuration file: none".yellow) allow($stderr).to receive(:puts).with("Configuration file: none".yellow)
assert_equal @@defaults, Jekyll.configuration({}) assert_equal site_configuration, Jekyll.configuration(@@test_config)
end end
should "load configuration as hash" do should "load configuration as hash" do
allow(SafeYAML).to receive(:load_file).with(@path).and_return(Hash.new) allow(SafeYAML).to receive(:load_file).with(@path).and_return(Hash.new)
allow($stdout).to receive(:puts).with("Configuration file: #{@path}") allow($stdout).to receive(:puts).with("Configuration file: #{@path}")
assert_equal @@defaults, Jekyll.configuration({}) assert_equal site_configuration, Jekyll.configuration(@@test_config)
end end
should "fire warning with bad config" do should "fire warning with bad config" do
allow(SafeYAML).to receive(:load_file).with(@path).and_return(Array.new) allow(SafeYAML).to receive(:load_file).with(@path).and_return(Array.new)
allow($stderr).to receive(:puts).and_return(("WARNING: ".rjust(20) + "Error reading configuration. Using defaults (and options).").yellow) allow($stderr).to receive(:puts).and_return(("WARNING: ".rjust(20) + "Error reading configuration. Using defaults (and options).").yellow)
allow($stderr).to receive(:puts).and_return("Configuration file: (INVALID) #{@path}".yellow) allow($stderr).to receive(:puts).and_return("Configuration file: (INVALID) #{@path}".yellow)
assert_equal @@defaults, Jekyll.configuration({}) assert_equal site_configuration, Jekyll.configuration(@@test_config)
end end
should "fire warning when user-specified config file isn't there" do should "fire warning when user-specified config file isn't there" do
@ -193,8 +248,8 @@ class TestConfiguration < JekyllUnitTest
context "loading config from external file" do context "loading config from external file" do
setup do setup do
@paths = { @paths = {
:default => File.join(Dir.pwd, '_config.yml'), :default => source_dir('_config.yml'),
:other => File.join(Dir.pwd, '_config.live.yml'), :other => source_dir('_config.live.yml'),
:toml => source_dir('_config.dev.toml'), :toml => source_dir('_config.dev.toml'),
:empty => "" :empty => ""
} }
@ -203,24 +258,31 @@ class TestConfiguration < JekyllUnitTest
should "load default plus posts config if no config_file is set" do should "load default plus posts config if no config_file is set" do
allow(SafeYAML).to receive(:load_file).with(@paths[:default]).and_return({}) allow(SafeYAML).to receive(:load_file).with(@paths[:default]).and_return({})
allow($stdout).to receive(:puts).with("Configuration file: #{@paths[:default]}") allow($stdout).to receive(:puts).with("Configuration file: #{@paths[:default]}")
assert_equal @@defaults, Jekyll.configuration({}) assert_equal site_configuration, Jekyll.configuration(@@test_config)
end end
should "load different config if specified" do should "load different config if specified" do
allow(SafeYAML).to receive(:load_file).with(@paths[:other]).and_return({"baseurl" => "http://wahoo.dev"}) allow(SafeYAML).to receive(:load_file).with(@paths[:other]).and_return({"baseurl" => "http://wahoo.dev"})
allow($stdout).to receive(:puts).with("Configuration file: #{@paths[:other]}") allow($stdout).to receive(:puts).with("Configuration file: #{@paths[:other]}")
assert_equal Utils.deep_merge_hashes(@@defaults, { "baseurl" => "http://wahoo.dev" }), Jekyll.configuration({ "config" => @paths[:other] }) Jekyll.configuration({ "config" => @paths[:other] })
assert_equal \
site_configuration({ "baseurl" => "http://wahoo.dev" }),
Jekyll.configuration(@@test_config.merge({ "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
allow(SafeYAML).to receive(:load_file).with(@paths[:default]).and_return({}) allow(SafeYAML).to receive(:load_file).with(@paths[:default]).and_return({})
allow($stdout).to receive(:puts).with("Configuration file: #{@paths[:default]}") allow($stdout).to receive(:puts).with("Configuration file: #{@paths[:default]}")
assert_equal @@defaults, Jekyll.configuration({ "config" => @paths[:empty] }) assert_equal \
site_configuration,
Jekyll.configuration(@@test_config.merge({ "config" => [@paths[:empty]] }))
end end
should "successfully load a TOML file" do should "successfully load a TOML file" do
Jekyll.logger.log_level = :warn Jekyll.logger.log_level = :warn
assert_equal @@defaults.clone.merge({ "baseurl" => "/you-beautiful-blog-you", "title" => "My magnificent site, wut" }), Jekyll.configuration({ "config" => [@paths[:toml]] }) assert_equal \
site_configuration({ "baseurl" => "/you-beautiful-blog-you", "title" => "My magnificent site, wut" }),
Jekyll.configuration(@@test_config.merge({ "config" => [@paths[:toml]] }))
Jekyll.logger.log_level = :info Jekyll.logger.log_level = :info
end end
@ -233,7 +295,9 @@ class TestConfiguration < JekyllUnitTest
allow($stdout).to receive(:puts).with("Configuration file: #{@paths[:default]}") allow($stdout).to receive(:puts).with("Configuration file: #{@paths[:default]}")
allow($stdout).to receive(:puts).with("Configuration file: #{@paths[:other]}") allow($stdout).to receive(:puts).with("Configuration file: #{@paths[:other]}")
allow($stdout).to receive(:puts).with("Configuration file: #{@paths[:toml]}") allow($stdout).to receive(:puts).with("Configuration file: #{@paths[:toml]}")
assert_equal @@defaults, Jekyll.configuration({ "config" => [@paths[:default], @paths[:other], @paths[:toml]] }) assert_equal \
site_configuration,
Jekyll.configuration(@@test_config.merge({ "config" => [@paths[:default], @paths[:other], @paths[:toml]] }))
end end
should "load multiple config files and last config should win" do should "load multiple config files and last config should win" do
@ -241,7 +305,63 @@ class TestConfiguration < JekyllUnitTest
allow(SafeYAML).to receive(:load_file).with(@paths[:other]).and_return({"baseurl" => "http://wahoo.dev"}) allow(SafeYAML).to receive(:load_file).with(@paths[:other]).and_return({"baseurl" => "http://wahoo.dev"})
allow($stdout).to receive(:puts).with("Configuration file: #{@paths[:default]}") allow($stdout).to receive(:puts).with("Configuration file: #{@paths[:default]}")
allow($stdout).to receive(:puts).with("Configuration file: #{@paths[:other]}") allow($stdout).to receive(:puts).with("Configuration file: #{@paths[:other]}")
assert_equal Utils.deep_merge_hashes(@@defaults, { "baseurl" => "http://wahoo.dev" }), Jekyll.configuration({ "config" => [@paths[:default], @paths[:other]] }) assert_equal \
site_configuration({ "baseurl" => "http://wahoo.dev" }),
Jekyll.configuration(@@test_config.merge({ "config" => [@paths[:default], @paths[:other]] }))
end
end
context "#add_default_collections" do
should "not do anything if collections is nil" do
conf = Configuration[default_configuration].tap {|c| c['collections'] = nil }
assert_equal conf.add_default_collections, conf
assert_nil conf.add_default_collections['collections']
end
should "converts collections to a hash if an array" do
conf = Configuration[default_configuration].tap {|c| c['collections'] = ['docs'] }
assert_equal conf.add_default_collections, conf.merge({
"collections" => {
"docs" => {},
"posts" => {
"output" => true,
"permalink" => "/:categories/:year/:month/:day/:title:output_ext"
}}})
end
should "force collections.posts.output = true" do
conf = Configuration[default_configuration].tap {|c| c['collections'] = {'posts' => {'output' => false}} }
assert_equal conf.add_default_collections, conf.merge({
"collections" => {
"posts" => {
"output" => true,
"permalink" => "/:categories/:year/:month/:day/:title:output_ext"
}}})
end
should "set collections.posts.permalink if it's not set" do
conf = Configuration[default_configuration]
assert_equal conf.add_default_collections, conf.merge({
"collections" => {
"posts" => {
"output" => true,
"permalink" => "/:categories/:year/:month/:day/:title:output_ext"
}}})
end
should "leave collections.posts.permalink alone if it is set" do
posts_permalink = "/:year/:title/"
conf = Configuration[default_configuration].tap do |c|
c['collections'] = {
"posts" => { "permalink" => posts_permalink }
}
end
assert_equal conf.add_default_collections, conf.merge({
"collections" => {
"posts" => {
"output" => true,
"permalink" => posts_permalink
}}})
end end
end end
end end

36
test/test_excerpt_drop.rb Normal file
View File

@ -0,0 +1,36 @@
require "helper"
class TestExcerptDrop < JekyllUnitTest
context "an excerpt drop" do
setup do
@site = fixture_site
@site.read
@doc = @site.docs_to_write.find { |d| !d.data["layout"].nil? }
@doc_drop = @doc.to_liquid
@excerpt = @doc.data["excerpt"]
@excerpt_drop = @excerpt.to_liquid
end
should "have the right thing" do
assert @doc.is_a? Jekyll::Document
assert @doc_drop.is_a? Jekyll::Drops::DocumentDrop
assert @excerpt.is_a? Jekyll::Excerpt
assert @excerpt_drop.is_a? Jekyll::Drops::ExcerptDrop
end
should "not have an excerpt" do
assert_nil @excerpt.data["excerpt"]
assert @excerpt_drop.class.invokable? "excerpt"
assert_nil @excerpt_drop["excerpt"]
end
should "inherit the layout for the drop but not the excerpt" do
assert_nil @excerpt.data["layout"]
assert_equal @excerpt_drop["layout"], @doc_drop["layout"]
end
should "inherit values from the document" do
assert_equal @excerpt_drop.keys.sort, @doc_drop.keys.sort
end
end
end

View File

@ -3,10 +3,8 @@ require "helper"
class TestFrontMatterDefaults < JekyllUnitTest class TestFrontMatterDefaults < JekyllUnitTest
context "A site with full front matter defaults" do context "A site with full front matter defaults" do
setup do setup do
@site = Site.new(Jekyll.configuration({ @site = fixture_site({
"source" => source_dir, "defaults" => [{
"destination" => dest_dir,
"defaults" => [{
"scope" => { "scope" => {
"path" => "contacts", "path" => "contacts",
"type" => "page" "type" => "page"
@ -15,7 +13,7 @@ class TestFrontMatterDefaults < JekyllUnitTest
"key" => "val" "key" => "val"
} }
}] }]
})) })
@site.process @site.process
@affected = @site.pages.find { |page| page.relative_path == "/contacts/bar.html" } @affected = @site.pages.find { |page| page.relative_path == "/contacts/bar.html" }
@not_affected = @site.pages.find { |page| page.relative_path == "about.html" } @not_affected = @site.pages.find { |page| page.relative_path == "about.html" }
@ -29,10 +27,8 @@ class TestFrontMatterDefaults < JekyllUnitTest
context "A site with front matter type pages and an extension" do context "A site with front matter type pages and an extension" do
setup do setup do
@site = Site.new(Jekyll.configuration({ @site = fixture_site({
"source" => source_dir, "defaults" => [{
"destination" => dest_dir,
"defaults" => [{
"scope" => { "scope" => {
"path" => "index.html" "path" => "index.html"
}, },
@ -40,7 +36,7 @@ class TestFrontMatterDefaults < JekyllUnitTest
"key" => "val" "key" => "val"
} }
}] }]
})) })
@site.process @site.process
@affected = @site.pages.find { |page| page.relative_path == "index.html" } @affected = @site.pages.find { |page| page.relative_path == "index.html" }
@ -55,10 +51,8 @@ class TestFrontMatterDefaults < JekyllUnitTest
context "A site with front matter defaults with no type" do context "A site with front matter defaults with no type" do
setup do setup do
@site = Site.new(Jekyll.configuration({ @site = fixture_site({
"source" => source_dir, "defaults" => [{
"destination" => dest_dir,
"defaults" => [{
"scope" => { "scope" => {
"path" => "win" "path" => "win"
}, },
@ -66,7 +60,8 @@ class TestFrontMatterDefaults < JekyllUnitTest
"key" => "val" "key" => "val"
} }
}] }]
})) })
@site.process @site.process
@affected = @site.posts.docs.find { |page| page.relative_path =~ %r!win\/! } @affected = @site.posts.docs.find { |page| page.relative_path =~ %r!win\/! }
@not_affected = @site.pages.find { |page| page.relative_path == "about.html" } @not_affected = @site.pages.find { |page| page.relative_path == "about.html" }
@ -80,10 +75,8 @@ class TestFrontMatterDefaults < JekyllUnitTest
context "A site with front matter defaults with no path and a deprecated type" do context "A site with front matter defaults with no path and a deprecated type" do
setup do setup do
@site = Site.new(Jekyll.configuration({ @site = fixture_site({
"source" => source_dir, "defaults" => [{
"destination" => dest_dir,
"defaults" => [{
"scope" => { "scope" => {
"type" => "page" "type" => "page"
}, },
@ -91,7 +84,8 @@ class TestFrontMatterDefaults < JekyllUnitTest
"key" => "val" "key" => "val"
} }
}] }]
})) })
@site.process @site.process
@affected = @site.pages @affected = @site.pages
@not_affected = @site.posts.docs @not_affected = @site.posts.docs
@ -106,10 +100,8 @@ class TestFrontMatterDefaults < JekyllUnitTest
context "A site with front matter defaults with no path" do context "A site with front matter defaults with no path" do
setup do setup do
@site = Site.new(Jekyll.configuration({ @site = fixture_site({
"source" => source_dir, "defaults" => [{
"destination" => dest_dir,
"defaults" => [{
"scope" => { "scope" => {
"type" => "pages" "type" => "pages"
}, },
@ -117,7 +109,7 @@ class TestFrontMatterDefaults < JekyllUnitTest
"key" => "val" "key" => "val"
} }
}] }]
})) })
@site.process @site.process
@affected = @site.pages @affected = @site.pages
@not_affected = @site.posts.docs @not_affected = @site.posts.docs
@ -132,17 +124,15 @@ class TestFrontMatterDefaults < JekyllUnitTest
context "A site with front matter defaults with no path or type" do context "A site with front matter defaults with no path or type" do
setup do setup do
@site = Site.new(Jekyll.configuration({ @site = fixture_site({
"source" => source_dir, "defaults" => [{
"destination" => dest_dir,
"defaults" => [{
"scope" => { "scope" => {
}, },
"values" => { "values" => {
"key" => "val" "key" => "val"
} }
}] }]
})) })
@site.process @site.process
@affected = @site.pages @affected = @site.pages
@not_affected = @site.posts @not_affected = @site.posts
@ -156,15 +146,13 @@ class TestFrontMatterDefaults < JekyllUnitTest
context "A site with front matter defaults with no scope" do context "A site with front matter defaults with no scope" do
setup do setup do
@site = Site.new(Jekyll.configuration({ @site = fixture_site({
"source" => source_dir, "defaults" => [{
"destination" => dest_dir,
"defaults" => [{
"values" => { "values" => {
"key" => "val" "key" => "val"
} }
}] }]
})) })
@site.process @site.process
@affected = @site.pages @affected = @site.pages
@not_affected = @site.posts @not_affected = @site.posts

View File

@ -4,10 +4,8 @@ class TestGeneratedSite < JekyllUnitTest
context "generated sites" do context "generated sites" do
setup do setup do
clear_dest clear_dest
config = Jekyll::Configuration::DEFAULTS.merge({ "source" => source_dir,
"destination" => dest_dir })
@site = fixture_site(config) @site = fixture_site
@site.process @site.process
@index = File.read(dest_dir("index.html")) @index = File.read(dest_dir("index.html"))
end end
@ -65,10 +63,7 @@ OUTPUT
context "generating limited posts" do context "generating limited posts" do
setup do setup do
clear_dest clear_dest
config = Jekyll::Configuration::DEFAULTS.merge({ "source" => source_dir, @site = fixture_site("limit_posts" => 5)
"destination" => dest_dir,
"limit_posts" => 5 })
@site = fixture_site(config)
@site.process @site.process
@index = File.read(dest_dir("index.html")) @index = File.read(dest_dir("index.html"))
end end
@ -80,24 +75,16 @@ OUTPUT
should "ensure limit posts is 0 or more" do should "ensure limit posts is 0 or more" do
assert_raises ArgumentError do assert_raises ArgumentError do
clear_dest clear_dest
config = Jekyll::Configuration::DEFAULTS.merge({ @site = fixture_site("limit_posts" => -1)
"source" => source_dir,
"destination" => dest_dir,
"limit_posts" => -1
})
@site = fixture_site(config)
end end
end end
should "acceptable limit post is 0" do should "acceptable limit post is 0" do
clear_dest clear_dest
config = Jekyll::Configuration::DEFAULTS.merge({ assert(
"source" => source_dir, fixture_site("limit_posts" => 0),
"destination" => dest_dir, "Couldn't create a site with limit_posts=0."
"limit_posts" => 0 )
})
assert Site.new(config), "Couldn't create a site with the given limit_posts."
end end
end end
end end

View File

@ -3,42 +3,42 @@ require 'helper'
class TestSite < JekyllUnitTest class TestSite < JekyllUnitTest
context "configuring sites" do context "configuring sites" do
should "have an array for plugins by default" do should "have an array for plugins by default" do
site = Site.new(Jekyll::Configuration::DEFAULTS) site = Site.new default_configuration
assert_equal [File.join(Dir.pwd, '_plugins')], site.plugins assert_equal [File.join(Dir.pwd, '_plugins')], site.plugins
end end
should "look for plugins under the site directory by default" do should "look for plugins under the site directory by default" do
site = Site.new(site_configuration) site = Site.new(site_configuration)
assert_equal [File.join(source_dir, '_plugins')], site.plugins assert_equal [source_dir('_plugins')], site.plugins
end end
should "have an array for plugins if passed as a string" do should "have an array for plugins if passed as a string" do
site = Site.new(Jekyll::Configuration::DEFAULTS.merge({'plugins_dir' => '/tmp/plugins'})) site = Site.new(site_configuration({ 'plugins_dir' => '/tmp/plugins' }))
assert_equal ['/tmp/plugins'], site.plugins assert_equal ['/tmp/plugins'], site.plugins
end end
should "have an array for plugins if passed as an array" do should "have an array for plugins if passed as an array" do
site = Site.new(Jekyll::Configuration::DEFAULTS.merge({'plugins_dir' => ['/tmp/plugins', '/tmp/otherplugins']})) site = Site.new(site_configuration({ 'plugins_dir' => ['/tmp/plugins', '/tmp/otherplugins'] }))
assert_equal ['/tmp/plugins', '/tmp/otherplugins'], site.plugins assert_equal ['/tmp/plugins', '/tmp/otherplugins'], site.plugins
end end
should "have an empty array for plugins if nothing is passed" do should "have an empty array for plugins if nothing is passed" do
site = Site.new(Jekyll::Configuration::DEFAULTS.merge({'plugins_dir' => []})) site = Site.new(site_configuration({ 'plugins_dir' => [] }))
assert_equal [], site.plugins assert_equal [], site.plugins
end end
should "have an empty array for plugins if nil is passed" do should "have the default for plugins if nil is passed" do
site = Site.new(Jekyll::Configuration::DEFAULTS.merge({'plugins_dir' => nil})) site = Site.new(site_configuration({ 'plugins_dir' => nil }))
assert_equal [], site.plugins assert_equal [source_dir('_plugins')], site.plugins
end end
should "expose default baseurl" do should "expose default baseurl" do
site = Site.new(Jekyll::Configuration::DEFAULTS) site = Site.new(default_configuration)
assert_equal Jekyll::Configuration::DEFAULTS['baseurl'], site.baseurl assert_equal Jekyll::Configuration::DEFAULTS['baseurl'], site.baseurl
end end
should "expose baseurl passed in from config" do should "expose baseurl passed in from config" do
site = Site.new(Jekyll::Configuration::DEFAULTS.merge({'baseurl' => '/blog'})) site = Site.new(site_configuration({ 'baseurl' => '/blog' }))
assert_equal '/blog', site.baseurl assert_equal '/blog', site.baseurl
end end
end end