Compare commits

...

46 Commits

Author SHA1 Message Date
Parker Moore
ce36f227eb Release 💎 3.0.5 2016-04-26 17:37:12 -07:00
Parker Moore
7edba91fdd Release 💎 v3.0.5 2016-04-26 17:35:49 -07:00
Parker Moore
30e7123648 Merge pull request #4846 from jekyll/fix-multiple-backwards-compatibilizes
Remove call to #backwards_compatibilize in Configuration.from
2016-04-26 17:34:58 -07:00
Parker Moore
1aa33ebb7b Remove call to #backwards_compatibilize in Configuration.from 2016-04-26 17:02:16 -07:00
Parker Moore
6dfae84da2 Release 💎 3.0.4 2016-04-18 14:00:25 -07:00
Parker Moore
c1c2884b9e Release 💎 v3.0.4 2016-04-18 13:58:24 -07:00
Parker Moore
0c8208afd7 Merge pull request #4806 from jekyll/3.0-stable-defaults
3.0.x: Fix defaults for Documents (posts/collection docs)
2016-04-18 13:48:21 -07:00
Parker Moore
2cd308aa00 test_document: scopes are based on relative_path 2016-04-18 13:12:40 -07:00
Parker Moore
64f2fcf37d Document#read: frontmatter.all should get relative_path not URL 2016-04-18 12:57:33 -07:00
Florian Thomas
10cefca2a2 add failing test for scope values in subdirs
ref #4458
2016-04-18 12:56:29 -07:00
Parker Moore
27f1ada057 Merge pull request #4753 from jekyll/parkr/permalink-fix
Configuration: allow users to specify a collections.posts.permalink directly
2016-04-13 01:03:27 -04:00
Parker Moore
1c0b6c5f6c Site#site_payload: sort collections by label 2016-04-08 10:50:58 -07:00
Parker Moore
726378cf59 Configuration#add_default_collections: fix bug where DEFAULTS['collections'] is modified 2016-04-08 10:49:37 -07:00
Parker Moore
18c62cde98 Add Configuration.from & use in Jekyll.configuration.
This process streamlines the creation of new configurations. Creating a new
site will choke if not all the correct options are given.
Configuration.from will ensure the overrides have all string keys and
ensures all the common issues & defaults are in place so a Site can be
created.

A common use:

    config = Configuration.from({ 'permalink' => '/:title/' }) # etc
    site = Jekyll::Site.new(config)
2016-04-08 10:16:16 -07:00
Parker Moore
02e8e671fb Remove use of Marshal in runtime code. 2016-04-04 14:45:09 -07:00
Parker Moore
440026adf6 Add tests for Configuration#add_default_collections 2016-04-04 13:56:40 -07:00
Parker Moore
275c08fa34 Don't read a config file if the filename is empty. 2016-04-04 13:13:23 -07:00
Parker Moore
50577b5839 Use Marshal to duplicate configuration defaults to prevent manipulation 2016-04-04 13:13:06 -07:00
Parker Moore
f2beef33e6 Refactor some tests to prevent manipulation of Jekyll::Config::DEFAULTS 2016-04-04 13:12:30 -07:00
Parker Moore
88a07674b6 Only write collections.posts.permalink if permalink is set. 2016-04-04 11:49:24 -07:00
Parker Moore
9ff7e549bf Test#build_configs shouldn't overwrite default collections 2016-04-04 11:49:10 -07:00
Parker Moore
b98a6fe5d8 Configuration: allow users to specify a collections.posts.permalink directly instead of overwriting with permalink 2016-04-04 09:23:59 -07:00
Parker Moore
d0e00ca12d Release 💎 3.0.3 2016-02-08 11:01:54 -08:00
Parker Moore
fe17a79e03 Merge pull request #4498 from jekyll/3.0.3-release
Release v3.0.3
2016-02-08 11:00:56 -08:00
Parker Moore
fdae8ce148 By me! 2016-02-08 11:00:30 -08:00
Parker Moore
53b781bbd1 Release v3.0.3 2016-02-08 10:47:22 -08:00
Parker Moore
c87a060ae8 Merge pull request #4493 from jekyll/fix-extension-weirdness
Fix extension weirdness with folders
2016-02-08 10:36:13 -08:00
Parker Moore
3f0e34b398 update pre-existing tests to align with changes 2016-02-08 10:00:13 -08:00
Parker Moore
7211ca9270 Add tests for non-html inputs being output as html 2016-02-08 09:36:46 -08:00
Parker Moore
9f8a4bc486 Fix extension weirdness with folders 2016-02-07 18:03:45 -08:00
Parker Moore
c2a75dee36 Merge pull request #4468 from jekyll/escape-the-tildes
Jekyll.sanitized_path: escape tildes before sanitizing a questionable path
2016-02-07 17:25:43 -08:00
Parker Moore
1f8e8f6b34 Merge pull request #4479 from jekyll/only-exclude-on-excluded
EntryFilter: only include 'excluded' log on excluded files
2016-02-05 15:02:19 -08:00
Parker Moore
888eb90f6f EntryFilter: only include 'excluded' log on excluded files 2016-02-05 13:28:27 -08:00
Parker Moore
4508e91a02 only prefix the path if it starts with a tilde 2016-02-03 15:22:11 -08:00
Parker Moore
1363492425 Jekyll.sanitized_path: escape tildes before sanitizing a questionable path 2016-02-03 13:25:31 -08:00
Parker Moore
599ad5b754 Merge pull request #4453 from jekyll/set-linenumbers-3.0
LiquidRenderer#parse: parse with line numbers.
2016-02-02 17:01:23 -08:00
Parker Moore
cdf169df94 Merge pull request #4446 from jekyll/fix-cmp
Document#<=>: protect against nil comparison in dates.
2016-02-02 17:01:10 -08:00
Parker Moore
d91a4eb266 LiquidRenderer#parse: parse with line numbers. 2016-02-02 14:45:03 -08:00
Parker Moore
a8afa8a65d Document#<=>: protect against nil comparison in dates. 2016-02-02 10:48:24 -08:00
Parker Moore
c538d80c54 Also release docs. 2016-01-20 14:15:47 -08:00
Parker Moore
d842f02b20 Release 💎 3.0.2 2016-01-20 14:14:22 -08:00
Parker Moore
3dfc0f26e1 We can release from 3.0-stable 2016-01-20 14:14:15 -08:00
Parker Moore
8e27409029 Merge branch '3.0-stable' of github.com:jekyll/jekyll into 3.0-stable
* '3.0-stable' of github.com:jekyll/jekyll:
  Document: throw a useful error when an invalid date is given
2016-01-20 14:10:57 -08:00
Parker Moore
766149cd83 Release 💎 v3.0.2 2016-01-20 14:10:47 -08:00
Parker Moore
f4523cb897 Merge pull request #4378 from jekyll/invalid-date-error
Document: throw a useful error when an invalid date is given
2016-01-20 14:07:22 -08:00
Parker Moore
805b117238 Document: throw a useful error when an invalid date is given 2016-01-20 12:23:48 -08:00
29 changed files with 447 additions and 110 deletions

View File

@@ -1,4 +1,18 @@
## HEAD
## 3.0.3 / 2016-02-08
### Bug Fixes
* Fix extension weirdness with folders (#4493)
* EntryFilter: only include 'excluded' log on excluded files (#4479)
* `Jekyll.sanitized_path`: escape tildes before sanitizing a questionable path (#4468)
* `LiquidRenderer#parse`: parse with line numbers (#4453)
* `Document#<=>`: protect against nil comparison in dates. (#4446)
## 3.0.2 / 2016-01-20
### Bug Fixes
* Document: throw a useful error when an invalid date is given (#4378)
### Development Fixes

View File

@@ -288,13 +288,13 @@ end
desc "Release #{name} v#{version}"
task :release => :build do
unless `git branch` =~ /^\* master$/
puts "You must be on the master branch to release!"
unless `git branch` =~ /^\* 3\.0-stable$/
puts "You must be on the 3.0-stable branch to release!"
exit!
end
sh "git commit --allow-empty -m 'Release :gem: #{version}'"
sh "git tag v#{version}"
sh "git push origin master"
sh "git push origin 3.0-stable"
sh "git push origin v#{version}"
sh "gem push pkg/#{name}-#{version}.gem"
end
@@ -315,8 +315,8 @@ end
namespace :docs do
desc "Release #{docs_name} v#{version}"
task :release => :build do
unless `git branch` =~ /^\* master$/
puts "You must be on the master branch to release!"
unless `git branch` =~ /^\* 3\.0-stable$/
puts "You must be on the 3.0-stable branch to release!"
exit!
end
sh "gem push pkg/#{docs_name}-#{version}.gem"

View File

@@ -76,6 +76,26 @@ Feature: frontmatter defaults
And I should see "main: <p>content of site/special/2013/10/14/about1.html</p>" in "_site/special/2013/10/14/about1.html"
And I should see "main: <p>content of site/special/2013/10/14/about2.html</p>" in "_site/special/2013/10/14/about2.html"
Scenario: Use frontmatter scopes for subdirectories
Given I have a _layouts directory
And I have a main layout that contains "main: {{ content }}"
And I have a _posts/en directory
And I have the following post under "en":
| title | date | content |
| helloworld | 2014-09-01 | {{page.lang}} is the current language |
And I have a _posts/de directory
And I have the following post under "de":
| title | date | content |
| hallowelt | 2014-09-01 | {{page.lang}} is the current language |
And I have a configuration file with "defaults" set to "[{scope: {path: "_posts/en"}, values: {layout: "main", lang: "en"}}, {scope: {path: "_posts/de"}, values: {layout: "main", lang: "de"}}]"
When I run jekyll build
Then the _site directory should exist
And I should see "main: <p>en is the current language</p>" in "_site/2014/09/01/helloworld.html"
And I should see "main: <p>de is the current language</p>" in "_site/2014/09/01/hallowelt.html"
Scenario: Override frontmatter defaults by type
Given I have a _posts directory
And I have the following post:

View File

@@ -36,6 +36,20 @@ Feature: Post data
Then the _site directory should exist
And I should see "Post date: 27 Mar 2009" in "_site/2009/03/27/star-wars.html"
Scenario: Use post.date variable with invalid
Given I have a _posts directory
And I have a "_posts/2016-01-01-test.md" page with date "tuesday" that contains "I have a bad date."
When I run jekyll build
Then the _site directory should not exist
And I should see "Document '_posts/2016-01-01-test.md' does not have a valid date in the YAML front matter." in the build output
Scenario: Invalid date in filename
Given I have a _posts directory
And I have a "_posts/2016-22-01-test.md" page that contains "I have a bad date."
When I run jekyll build
Then the _site directory should not exist
And I should see "Document '_posts/2016-22-01-test.md' does not have a valid date in the filename." in the build output
Scenario: Use post.id variable
Given I have a _posts directory
And I have a _layouts directory

View File

@@ -96,14 +96,13 @@ module Jekyll
#
# Returns the final configuration Hash.
def configuration(override = Hash.new)
config = Configuration[Configuration::DEFAULTS]
override = Configuration[override].stringify_keys
config = Configuration.new
unless override.delete('skip_config_files')
config = config.read_config_files(config.config_files(override))
end
# Merge DEFAULTS < _config.yml < override
config = Utils.deep_merge_hashes(config, override).stringify_keys
config = Configuration.from Utils.deep_merge_hashes(config, override).stringify_keys
set_timezone(config['timezone']) if config['timezone']
config
@@ -153,8 +152,9 @@ module Jekyll
def sanitized_path(base_directory, questionable_path)
return base_directory if base_directory.eql?(questionable_path)
questionable_path.insert(0, '/') if questionable_path.start_with?('~')
clean_path = File.expand_path(questionable_path, "/")
clean_path = clean_path.sub(/\A\w\:\//, '/')
clean_path.sub!(/\A\w\:\//, '/')
unless clean_path.start_with?(base_directory.sub(/\A\w\:\//, '/'))
File.join(base_directory, clean_path)

View File

@@ -80,7 +80,24 @@ module Jekyll
'coderay_css' => 'style'
}
}
}]
}].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
#
@@ -177,6 +194,7 @@ module Jekyll
begin
files.each do |config_file|
next if config_file.nil? or config_file.empty?
new_config = read_config_file(config_file)
configuration = Utils.deep_merge_hashes(configuration, new_config)
end
@@ -243,7 +261,7 @@ module Jekyll
" as a list of comma-separated values."
config[option] = csv_to_array(config[option])
end
config[option].map!(&:to_s)
config[option].map!(&:to_s) if config[option]
end
if (config['kramdown'] || {}).key?('use_coderay')
@@ -278,14 +296,22 @@ module Jekyll
def add_default_collections
config = clone
# It defaults to `{}`, so this is only if someone sets it to null manually.
return config if config['collections'].nil?
# Ensure we have a hash.
if config['collections'].is_a?(Array)
config['collections'] = Hash[config['collections'].map{|c| [c, {}]}]
end
config['collections']['posts'] ||= {}
config['collections']['posts']['output'] = true
config['collections']['posts']['permalink'] = style_to_permalink(config['permalink'])
config['collections'] = Utils.deep_merge_hashes(
{ 'posts' => {} }, config['collections']
).tap do |collections|
collections['posts']['output'] = true
if config['permalink']
collections['posts']['permalink'] ||= style_to_permalink(config['permalink'])
end
end
config
end

View File

@@ -58,7 +58,7 @@ module Jekyll
# Merge some data in with this document's data.
#
# Returns the merged data.
def merge_data!(other)
def merge_data!(other, source: "YAML front matter")
if other.key?('categories') && !other['categories'].nil?
if other['categories'].is_a?(String)
other['categories'] = other['categories'].split(" ").map(&:strip)
@@ -67,7 +67,7 @@ module Jekyll
end
Utils.deep_merge_hashes!(data, other)
if data.key?('date') && !data['date'].is_a?(Time)
data['date'] = Utils.parse_date(data['date'].to_s, "Document '#{relative_path}' does not have a valid date in the YAML front matter.")
data['date'] = Utils.parse_date(data['date'].to_s, "Document '#{relative_path}' does not have a valid date in the #{source}.")
end
data
end
@@ -235,8 +235,11 @@ module Jekyll
def destination(base_directory)
dest = site.in_dest_dir(base_directory)
path = site.in_dest_dir(dest, URL.unescape_path(url))
path = File.join(path, "index.html") if url.end_with?("/")
path << output_ext unless path.end_with?(output_ext)
if url.end_with? "/"
path = File.join(path, "index.html")
else
path << output_ext unless path.end_with?(output_ext)
end
path
end
@@ -286,21 +289,24 @@ module Jekyll
@data = SafeYAML.load_file(path)
else
begin
defaults = @site.frontmatter_defaults.all(url, collection.label.to_sym)
merge_data!(defaults) unless defaults.empty?
defaults = @site.frontmatter_defaults.all(relative_path, collection.label.to_sym)
merge_data!(defaults, source: "front matter defaults") unless defaults.empty?
self.content = File.read(path, merged_file_read_opts(opts))
if content =~ YAML_FRONT_MATTER_REGEXP
self.content = $POSTMATCH
data_file = SafeYAML.load($1)
merge_data!(data_file) if data_file
merge_data!(data_file, source: "YAML front matter") if data_file
end
post_read
rescue SyntaxError => e
puts "YAML Exception reading #{path}: #{e.message}"
Jekyll.logger.error "Error:", "YAML Exception reading #{path}: #{e.message}"
rescue Exception => e
puts "Error reading file #{path}: #{e.message}"
if e.is_a? Jekyll::Errors::FatalException
raise e
end
Jekyll.logger.error "Error:", "could not read file #{path}: #{e.message}"
end
end
end
@@ -311,8 +317,10 @@ module Jekyll
merge_data!({
"slug" => slug,
"ext" => ext
})
merge_data!({"date" => date}) if data['date'].nil? || data['date'].to_i == site.time.to_i
}, source: "filename")
if data['date'].nil? || data['date'].to_i == site.time.to_i
merge_data!({"date" => date}, source: "filename")
end
data['title'] ||= slug.split('-').select {|w| w.capitalize! || w }.join(' ')
end
populate_categories
@@ -332,7 +340,7 @@ module Jekyll
superdirs = relative_path.sub(/#{special_dir}(.*)/, '').split(File::SEPARATOR).reject do |c|
c.empty? || c.eql?(special_dir) || c.eql?(basename)
end
merge_data!({ 'categories' => superdirs })
merge_data!({ 'categories' => superdirs }, source: "file path")
end
def populate_categories
@@ -393,7 +401,7 @@ module Jekyll
def <=>(other)
return nil if !other.respond_to?(:data)
cmp = data['date'] <=> other.data['date']
cmp = path <=> other.path if cmp == 0
cmp = path <=> other.path if cmp.nil? || cmp == 0
cmp
end

View File

@@ -47,7 +47,7 @@ module Jekyll
def excluded?(entry)
excluded = glob_include?(site.exclude, relative_to_source(entry))
Jekyll.logger.debug "EntryFilter:", "excluded?(#{relative_to_source(entry)}) ==> #{excluded}"
Jekyll.logger.debug "EntryFilter:", "excluded #{relative_to_source(entry)}" if excluded
excluded
end

View File

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

View File

@@ -135,8 +135,11 @@ module Jekyll
# Returns the destination file path String.
def destination(dest)
path = site.in_dest_dir(dest, URL.unescape_path(url))
path = File.join(path, "index.html") if url.end_with?("/")
path << output_ext unless path.end_with?(output_ext)
if url.end_with? "/"
path = File.join(path, "index.html")
else
path << output_ext unless path.end_with?(output_ext)
end
path
end

View File

@@ -224,7 +224,7 @@ module Jekyll
# Build a hash map based on the specified post attribute ( post attr =>
# array of posts ) then sort each array in reverse order.
hash = Hash.new { |h, key| h[key] = [] }
posts.docs.each { |p| p.data[post_attr].each { |t| hash[t] << p } }
posts.docs.each { |p| p.data[post_attr].each { |t| hash[t] << p } if p.data[post_attr] }
hash.values.each { |posts| posts.sort!.reverse! }
hash
end
@@ -273,7 +273,7 @@ module Jekyll
"html_pages" => pages.select { |page| page.html? || page.url.end_with?("/") },
"categories" => post_attr_hash('categories'),
"tags" => post_attr_hash('tags'),
"collections" => collections.values.map(&:to_liquid),
"collections" => collections.values.sort_by(&:label).map(&:to_liquid),
"documents" => documents,
"data" => site_data
}))

View File

@@ -1,3 +1,3 @@
module Jekyll
VERSION = '3.0.1'
VERSION = '3.0.5'
end

View File

@@ -4,6 +4,33 @@ title: History
permalink: "/docs/history/"
---
## 3.0.3 / 2016-02-08
{: #v3-0-3}
### Bug Fixes
{: #bug-fixes-v3-0-3}
* Fix extension weirdness with folders ([#4493]({{ site.repository }}/issues/4493))
* EntryFilter: only include 'excluded' log on excluded files ([#4479]({{ site.repository }}/issues/4479))
* `Jekyll.sanitized_path`: escape tildes before sanitizing a questionable path ([#4468]({{ site.repository }}/issues/4468))
* `LiquidRenderer#parse`: parse with line numbers ([#4453]({{ site.repository }}/issues/4453))
* `Document#<=>`: protect against nil comparison in dates. ([#4446]({{ site.repository }}/issues/4446))
## 3.0.2 / 2016-01-20
{: #v3-0-2}
### Bug Fixes
{: #bug-fixes-v3-0-2}
- Document: throw a useful error when an invalid date is given ([#4378]({{ site.repository }}/issues/4378))
### Development Fixes
{: #development-fixes-v3-0-2}
- `jekyll-docs` should be easily release-able ([#4152]({{ site.repository }}/issues/4152))
## 3.0.1 / 2015-11-17
{: #v3-0-1}

View File

@@ -0,0 +1,14 @@
---
layout: news_item
title: 'Jekyll 3.0.2 Released'
date: 2016-01-20 14:08:18 -0800
author: parkr
version: 3.0.2
categories: [release]
---
A crucial bug was found in v3.0.1 which caused invalid post dates to go
unnoticed in the build chain until the error that popped up was unhelpful.
v3.0.2 [throws errors as you'd expect](https://github.com/jekyll/jekyll/issues/4375)
when there is a post like `_posts/2016-22-01-future.md` or a post has an
invalid date like `date: "tuesday"` in their front matter.

View File

@@ -0,0 +1,31 @@
---
layout: news_item
title: 'Jekyll 3.0.3 Released'
date: 2016-02-08 10:39:08 -0800
author: parkr
version: 3.0.3
categories: [release]
---
[GitHub Pages upgraded to Jekyll 3.0.2][1] last week and there has been a
joyous reception so far! This release is to address some bugs that affected
some users during the cut-over. The fixes include:
* Fix problem where outputting to a folder would have two extensions
* Handle tildes (`~`) in filenames properly
* Fix issue when comparing documents without dates
* Include line numbers in liquid error output
Read more on the [changelog](/docs/history/#v3-0-3) with links to the
related patches.
Please keep [submitting bugs][2] as you find them! Please do take a look
[in our various help resources](/help/) before filing a bug and use [our
forum][3] for asking questions and getting help on a specific problem
you're having.
Happy Jekylling!
[1]: https://github.com/blog/2100-github-pages-now-faster-and-simpler-with-jekyll-3-0
[2]: {{ site.repository }}/issues
[3]: https://talk.jekyllrb.com/

View File

@@ -1 +1 @@
3.0.1
3.0.2

View File

@@ -42,8 +42,30 @@ Minitest::Reporters.use! [
)
]
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
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)
RSpec::Mocks::ExampleMethods::ExpectHost.instance_method(:expect).\
@@ -66,9 +88,12 @@ class JekyllUnitTest < Minitest::Test
Jekyll::Site.new(site_configuration(overrides))
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)
.fix_common_issues.backwards_compatibilize.add_default_collections
end
def site_configuration(overrides = {})
@@ -78,15 +103,10 @@ class JekyllUnitTest < Minitest::Test
}))
build_configs({
"source" => source_dir
}, full_overrides)
end
def dest_dir(*subdirs)
test_dir('dest', *subdirs)
end
def source_dir(*subdirs)
test_dir('source', *subdirs)
}, full_overrides).
fix_common_issues.
backwards_compatibilize.
add_default_collections
end
def clear_dest
@@ -94,10 +114,6 @@ class JekyllUnitTest < Minitest::Test
FileUtils.rm_rf(source_dir('.jekyll-metadata'))
end
def test_dir(*subdirs)
File.join(File.dirname(__FILE__), *subdirs)
end
def directory_with_contents(path)
FileUtils.rm_rf(path)
FileUtils.mkdir(path)

View File

@@ -0,0 +1,4 @@
---
---
I should be output to `/with.dots/mit/index.html`.

View File

@@ -0,0 +1,5 @@
---
permalink: /contacts/humans/
---
I should be output to `/contacts/humans/index.html`.

0
test/source/~hi.txt Normal file
View File

View File

@@ -203,7 +203,7 @@ class TestCollections < JekyllUnitTest
end
should "contain one document" do
assert_equal 2, @collection.docs.size
assert_equal 3, @collection.docs.size
end
should "allow dots in the filename" do

View File

@@ -1,7 +1,62 @@
require 'helper'
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.html"}}
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
setup do
@@ -126,27 +181,27 @@ class TestConfiguration < JekyllUnitTest
end
context "loading configuration" 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")
end
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($stderr).to receive(:puts).with("Configuration file: none".yellow)
assert_equal @@defaults, Jekyll.configuration({})
assert_equal site_configuration, Jekyll.configuration(@@test_config)
end
should "load configuration as hash" do
allow(SafeYAML).to receive(:load_file).with(@path).and_return(Hash.new)
allow($stdout).to receive(:puts).with("Configuration file: #{@path}")
assert_equal @@defaults, Jekyll.configuration({})
assert_equal site_configuration, Jekyll.configuration(@@test_config)
end
should "fire warning with bad config" do
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("Configuration file: (INVALID) #{@path}".yellow)
assert_equal @@defaults, Jekyll.configuration({})
assert_equal site_configuration, Jekyll.configuration(@@test_config)
end
should "fire warning when user-specified config file isn't there" do
@@ -165,8 +220,8 @@ class TestConfiguration < JekyllUnitTest
context "loading config from external file" do
setup do
@paths = {
:default => File.join(Dir.pwd, '_config.yml'),
:other => File.join(Dir.pwd, '_config.live.yml'),
:default => source_dir('_config.yml'),
:other => source_dir('_config.live.yml'),
:toml => source_dir('_config.dev.toml'),
:empty => ""
}
@@ -175,24 +230,31 @@ class TestConfiguration < JekyllUnitTest
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($stdout).to receive(:puts).with("Configuration file: #{@paths[:default]}")
assert_equal @@defaults, Jekyll.configuration({})
assert_equal site_configuration, Jekyll.configuration(@@test_config)
end
should "load different config if specified" do
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]}")
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
should "load default config if path passed is empty" do
allow(SafeYAML).to receive(:load_file).with(@paths[:default]).and_return({})
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
should "successfully load a TOML file" do
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
end
@@ -205,7 +267,9 @@ class TestConfiguration < JekyllUnitTest
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[: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
should "load multiple config files and last config should win" do
@@ -213,7 +277,63 @@ class TestConfiguration < JekyllUnitTest
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[: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.html"
}}})
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.html"
}}})
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.html"
}}})
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

View File

@@ -124,7 +124,7 @@ class TestDocument < JekyllUnitTest
@site = fixture_site({
"collections" => ["slides"],
"defaults" => [{
"scope"=> {"path"=>"slides", "type"=>"slides"},
"scope"=> {"path"=>"_slides", "type"=>"slides"},
"values"=> {
"nested"=> {
"key"=>"value123",
@@ -380,4 +380,33 @@ class TestDocument < JekyllUnitTest
end
context "a document in a collection with a non-HTML-able filename" do
setup do
@site = fixture_site({
"collections" => {
"with.dots" => {
"output" => true,
"permalink" => "/:collection/:path/"
}
},
})
@site.process
@document = @site.collections["with.dots"].docs.find { |doc| doc.relative_path == "_with.dots/mit.txt" }
@dest_file = dest_dir("with.dots", "mit", "index.html")
end
should "produce the right URL" do
assert_equal "/with.dots/mit/", @document.url
end
should "produce the right destination" do
assert_equal @dest_file, @document.destination(dest_dir)
end
should "be output in the correct place" do
assert_equal true, File.file?(@dest_file)
end
end
end

View File

@@ -257,7 +257,7 @@ class TestFilters < JekyllUnitTest
assert_equal 2, g["items"].size
when ""
assert g["items"].is_a?(Array), "The list of grouped items for '' is not an Array."
assert_equal 11, g["items"].size
assert_equal 12, g["items"].size
end
end
end

View File

@@ -4,9 +4,7 @@ class TestFrontMatterDefaults < JekyllUnitTest
context "A site with full front matter defaults" do
setup do
@site = Site.new(Jekyll.configuration({
"source" => source_dir,
"destination" => dest_dir,
@site = fixture_site({
"defaults" => [{
"scope" => {
"path" => "contacts",
@@ -16,7 +14,7 @@ class TestFrontMatterDefaults < JekyllUnitTest
"key" => "val"
}
}]
}))
})
@site.process
@affected = @site.pages.find { |page| page.relative_path == "/contacts/bar.html" }
@not_affected = @site.pages.find { |page| page.relative_path == "about.html" }
@@ -30,9 +28,7 @@ class TestFrontMatterDefaults < JekyllUnitTest
context "A site with front matter type pages and an extension" do
setup do
@site = Site.new(Jekyll.configuration({
"source" => source_dir,
"destination" => dest_dir,
@site = fixture_site({
"defaults" => [{
"scope" => {
"path" => "index.html"
@@ -41,7 +37,7 @@ class TestFrontMatterDefaults < JekyllUnitTest
"key" => "val"
}
}]
}))
})
@site.process
@affected = @site.pages.find { |page| page.relative_path == "index.html" }
@@ -56,9 +52,7 @@ class TestFrontMatterDefaults < JekyllUnitTest
context "A site with front matter defaults with no type" do
setup do
@site = Site.new(Jekyll.configuration({
"source" => source_dir,
"destination" => dest_dir,
@site = fixture_site({
"defaults" => [{
"scope" => {
"path" => "win"
@@ -67,7 +61,8 @@ class TestFrontMatterDefaults < JekyllUnitTest
"key" => "val"
}
}]
}))
})
@site.process
@affected = @site.posts.docs.find { |page| page.relative_path =~ /win\// }
@not_affected = @site.pages.find { |page| page.relative_path == "about.html" }
@@ -81,9 +76,7 @@ class TestFrontMatterDefaults < JekyllUnitTest
context "A site with front matter defaults with no path and a deprecated type" do
setup do
@site = Site.new(Jekyll.configuration({
"source" => source_dir,
"destination" => dest_dir,
@site = fixture_site({
"defaults" => [{
"scope" => {
"type" => "page"
@@ -92,7 +85,8 @@ class TestFrontMatterDefaults < JekyllUnitTest
"key" => "val"
}
}]
}))
})
@site.process
@affected = @site.pages
@not_affected = @site.posts.docs
@@ -106,9 +100,7 @@ class TestFrontMatterDefaults < JekyllUnitTest
context "A site with front matter defaults with no path" do
setup do
@site = Site.new(Jekyll.configuration({
"source" => source_dir,
"destination" => dest_dir,
@site = fixture_site({
"defaults" => [{
"scope" => {
"type" => "pages"
@@ -117,7 +109,7 @@ class TestFrontMatterDefaults < JekyllUnitTest
"key" => "val"
}
}]
}))
})
@site.process
@affected = @site.pages
@not_affected = @site.posts.docs
@@ -131,9 +123,7 @@ class TestFrontMatterDefaults < JekyllUnitTest
context "A site with front matter defaults with no path or type" do
setup do
@site = Site.new(Jekyll.configuration({
"source" => source_dir,
"destination" => dest_dir,
@site = fixture_site({
"defaults" => [{
"scope" => {
},
@@ -141,7 +131,7 @@ class TestFrontMatterDefaults < JekyllUnitTest
"key" => "val"
}
}]
}))
})
@site.process
@affected = @site.pages
@not_affected = @site.posts
@@ -155,15 +145,13 @@ class TestFrontMatterDefaults < JekyllUnitTest
context "A site with front matter defaults with no scope" do
setup do
@site = Site.new(Jekyll.configuration({
"source" => source_dir,
"destination" => dest_dir,
@site = fixture_site({
"defaults" => [{
"values" => {
"key" => "val"
}
}]
}))
})
@site.process
@affected = @site.pages
@not_affected = @site.posts

View File

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

View File

@@ -310,6 +310,18 @@ class TestPage < JekyllUnitTest
assert File.directory?(dest_dir)
assert File.exist?(File.join(dest_dir, 'contacts', 'bar', 'index.html'))
end
should "write properly without html extension in source file" do
page = setup_page('/contacts', 'humans.txt')
page.site.permalink_style = "/:categories/:year/:month/:day/:title/"
do_render(page)
page.write(dest_dir)
dest = dest_dir('contacts', 'humans', 'index.html')
assert File.directory?(dest_dir)
assert_equal dest, page.destination(dest_dir)
assert File.exist?(dest), "contacts/humans/index.html should exist"
end
end
end

View File

@@ -15,4 +15,13 @@ class TestPathSanitization < JekyllUnitTest
assert_equal "/tmp/foobar/jail/..c:/..c:/..c:/etc/passwd", Jekyll.sanitized_path("/tmp/foobar/jail", "..c:/..c:/..c:/etc/passwd")
end
end
should "escape tilde" do
assert_equal source_dir("~hi.txt"), Jekyll.sanitized_path(source_dir, "~hi.txt")
assert_equal source_dir("files", "~hi.txt"), Jekyll.sanitized_path(source_dir, "files/../files/~hi.txt")
end
should "remove path traversals" do
assert_equal source_dir("files", "hi.txt"), Jekyll.sanitized_path(source_dir, "f./../../../../../../files/hi.txt")
end
end

View File

@@ -3,7 +3,7 @@ require 'helper'
class TestSite < JekyllUnitTest
context "configuring sites" 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
end
@@ -13,32 +13,32 @@ class TestSite < JekyllUnitTest
end
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(build_configs({ 'plugins_dir' => '/tmp/plugins' }))
assert_equal ['/tmp/plugins'], site.plugins
end
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(build_configs({ 'plugins_dir' => ['/tmp/plugins', '/tmp/otherplugins'] }))
assert_equal ['/tmp/plugins', '/tmp/otherplugins'], site.plugins
end
should "have an empty array for plugins if nothing is passed" do
site = Site.new(Jekyll::Configuration::DEFAULTS.merge({'plugins_dir' => []}))
site = Site.new(build_configs({ 'plugins_dir' => [] }))
assert_equal [], site.plugins
end
should "have an empty array for plugins if nil is passed" do
site = Site.new(Jekyll::Configuration::DEFAULTS.merge({'plugins_dir' => nil}))
site = Site.new(build_configs({ 'plugins_dir' => nil }))
assert_equal [], site.plugins
end
should "expose default baseurl" do
site = Site.new(Jekyll::Configuration::DEFAULTS)
site = Site.new(default_configuration)
assert_equal Jekyll::Configuration::DEFAULTS['baseurl'], site.baseurl
end
should "expose baseurl passed in from config" do
site = Site.new(Jekyll::Configuration::DEFAULTS.merge({'baseurl' => '/blog'}))
site = Site.new(build_configs({ 'baseurl' => '/blog' }))
assert_equal '/blog', site.baseurl
end
end
@@ -177,6 +177,7 @@ class TestSite < JekyllUnitTest
environment.html
exploit.md
foo.md
humans.txt
index.html
index.html
main.scss