diff --git a/lib/jekyll.rb b/lib/jekyll.rb index eb55fb8e..a14a970f 100644 --- a/lib/jekyll.rb +++ b/lib/jekyll.rb @@ -68,66 +68,88 @@ module Jekyll require 'jekyll/command' require 'jekyll/liquid_extensions' - # Public: Tells you which Jekyll environment you are building in so you can skip tasks - # if you need to. This is useful when doing expensive compression tasks on css and - # images and allows you to skip that when working in development. + class << self + # Public: Tells you which Jekyll environment you are building in so you can skip tasks + # if you need to. This is useful when doing expensive compression tasks on css and + # images and allows you to skip that when working in development. - def self.env - ENV["JEKYLL_ENV"] || "development" - end - - # Public: Generate a Jekyll configuration Hash by merging the default - # options with anything in _config.yml, and adding the given options on top. - # - # override - A Hash of config directives that override any options in both - # the defaults and the config file. See Jekyll::Configuration::DEFAULTS for a - # list of option names and their defaults. - # - # Returns the final configuration Hash. - def self.configuration(override) - config = Configuration[Configuration::DEFAULTS] - override = Configuration[override].stringify_keys - config = config.read_config_files(config.config_files(override)) - - # Merge DEFAULTS < _config.yml < override - config = Utils.deep_merge_hashes(config, override).stringify_keys - set_timezone(config['timezone']) if config['timezone'] - - config - end - - # Static: Set the TZ environment variable to use the timezone specified - # - # timezone - the IANA Time Zone - # - # Returns nothing - def self.set_timezone(timezone) - ENV['TZ'] = timezone - end - - def self.logger - @logger ||= LogAdapter.new(Stevenson.new) - end - - def self.logger=(writer) - @logger = LogAdapter.new(writer) - end - - # Public: File system root - # - # Returns the root of the filesystem as a Pathname - def self.fs_root - @fs_root ||= "/" - end - - def self.sanitized_path(base_directory, questionable_path) - clean_path = File.expand_path(questionable_path, fs_root) - clean_path.gsub!(/\A\w\:\//, '/') - unless clean_path.start_with?(base_directory) - File.join(base_directory, clean_path) - else - clean_path + def env + ENV["JEKYLL_ENV"] || "development" end + + # Public: Generate a Jekyll configuration Hash by merging the default + # options with anything in _config.yml, and adding the given options on top. + # + # override - A Hash of config directives that override any options in both + # the defaults and the config file. See Jekyll::Configuration::DEFAULTS for a + # list of option names and their defaults. + # + # Returns the final configuration Hash. + def configuration(override = Hash.new) + config = Configuration[Configuration::DEFAULTS] + override = Configuration[override].stringify_keys + 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 + set_timezone(config['timezone']) if config['timezone'] + + config + end + + # Public: Set the TZ environment variable to use the timezone specified + # + # timezone - the IANA Time Zone + # + # Returns nothing + def set_timezone(timezone) + ENV['TZ'] = timezone + end + + # Public: Fetch the logger instance for this Jekyll process. + # + # Returns the LogAdapter instance. + def logger + @logger ||= LogAdapter.new(Stevenson.new) + end + + # Public: Set the log writer. + # New log writer must respond to the same methods + # as Ruby's interal Logger. + # + # writer - the new Logger-compatible log transport + # + # Returns the new logger. + def logger=(writer) + @logger = LogAdapter.new(writer) + end + + # Public: An array of sites + # + # Returns the Jekyll sites created. + def sites + @sites ||= [] + end + + # Public: Ensures the questionable path is prefixed with the base directory + # and prepends the questionable path with the base directory if false. + # + # base_directory - the directory with which to prefix the questionable path + # questionable_path - the path we're unsure about, and want prefixed + # + # Returns the sanitized path. + def sanitized_path(base_directory, questionable_path) + clean_path = File.expand_path(questionable_path, "/") + clean_path.gsub!(/\A\w\:\//, '/') + unless clean_path.start_with?(base_directory) + File.join(base_directory, clean_path) + else + clean_path + end + end + end end diff --git a/lib/jekyll/cleaner.rb b/lib/jekyll/cleaner.rb index 1786a317..6dd59ea0 100644 --- a/lib/jekyll/cleaner.rb +++ b/lib/jekyll/cleaner.rb @@ -29,7 +29,7 @@ module Jekyll # Returns a Set with the file paths def existing_files files = Set.new - Dir.glob(File.join(site.dest, "**", "*"), File::FNM_DOTMATCH) do |file| + Dir.glob(site.in_dest_dir("**", "*"), File::FNM_DOTMATCH) do |file| files << file unless file =~ /\/\.{1,2}$/ || file =~ keep_file_regex || keep_dirs.include?(file) end files @@ -76,7 +76,7 @@ module Jekyll # # Returns a Set with the directory paths def keep_dirs - site.keep_files.map { |file| parent_dirs(File.join(site.dest, file)) }.flatten.to_set + site.keep_files.map { |file| parent_dirs(site.in_dest_dir(file)) }.flatten.to_set end # Private: Creates a regular expression from the config's keep_files array diff --git a/lib/jekyll/collection.rb b/lib/jekyll/collection.rb index 33654f45..73e480dd 100644 --- a/lib/jekyll/collection.rb +++ b/lib/jekyll/collection.rb @@ -35,7 +35,8 @@ module Jekyll # Returns the sorted array of docs. def read filtered_entries.each do |file_path| - full_path = Jekyll.sanitized_path(directory, file_path) + full_path = collection_dir(file_path) + next if File.directory?(full_path) if Utils.has_yaml_header? full_path doc = Jekyll::Document.new(full_path, { site: site, collection: self }) doc.read @@ -54,9 +55,10 @@ module Jekyll # relative to the collection's directory def entries return Array.new unless exists? - Dir.glob(File.join(directory, "**", "*.*")).map do |entry| - entry[File.join(directory, "")] = ''; entry - end + @entries ||= + Dir.glob(collection_dir("**", "*.*")).map do |entry| + entry["#{collection_dir}/"] = ''; entry + end end # Filtered version of the entries in this collection. @@ -65,9 +67,13 @@ module Jekyll # Returns a list of filtered entry paths. def filtered_entries return Array.new unless exists? - Dir.chdir(directory) do - entry_filter.filter(entries).reject { |f| File.directory?(f) } - end + @filtered_entries ||= + Dir.chdir(directory) do + entry_filter.filter(entries).reject do |f| + path = collection_dir(f) + File.directory?(path) || (File.symlink?(f) && site.safe) + end + end end # The directory for this Collection, relative to the site source. @@ -78,12 +84,25 @@ module Jekyll @relative_directory ||= "_#{label}" end - # The full path to the directory containing the + # The full path to the directory containing the collection. # # Returns a String containing th directory name where the collection # is stored on the filesystem. def directory - @directory ||= Jekyll.sanitized_path(site.source, relative_directory) + @directory ||= site.in_source_dir(relative_directory) + end + + # The full path to the directory containing the collection, with + # optional subpaths. + # + # *files - (optional) any other path pieces relative to the + # directory to append to the path + # + # Returns a String containing th directory name where the collection + # is stored on the filesystem. + def collection_dir(*files) + return directory if files.empty? + site.in_source_dir(relative_directory, *files) end # Checks whether the directory "exists" for this collection. diff --git a/lib/jekyll/convertible.rb b/lib/jekyll/convertible.rb index 74c27117..2b52bca3 100644 --- a/lib/jekyll/convertible.rb +++ b/lib/jekyll/convertible.rb @@ -43,7 +43,7 @@ module Jekyll # Returns nothing. def read_yaml(base, name, opts = {}) begin - self.content = File.read(Jekyll.sanitized_path(base, name), + self.content = File.read(site.in_source_dir(base, name), merged_file_read_opts(opts)) if content =~ /\A(---\s*\n.*?\n?)^((---|\.\.\.)\s*$\n?)/m self.content = $POSTMATCH diff --git a/lib/jekyll/document.rb b/lib/jekyll/document.rb index 95a2bdcd..003c04eb 100644 --- a/lib/jekyll/document.rb +++ b/lib/jekyll/document.rb @@ -159,7 +159,8 @@ module Jekyll # # Returns the full path to the output file of this document. def destination(base_directory) - path = Jekyll.sanitized_path(base_directory, url) + dest = site.in_dest_dir(base_directory) + path = site.in_dest_dir(dest, url) path = File.join(path, "index.html") if url =~ /\/$/ path end diff --git a/lib/jekyll/draft.rb b/lib/jekyll/draft.rb index 7b1d9aca..16daefdf 100644 --- a/lib/jekyll/draft.rb +++ b/lib/jekyll/draft.rb @@ -14,8 +14,8 @@ module Jekyll end # Get the full path to the directory containing the draft files - def containing_dir(source, dir) - File.join(source, dir, '_drafts') + def containing_dir(dir) + site.in_source_dir(dir, '_drafts') end # The path to the draft source file, relative to the site source diff --git a/lib/jekyll/excerpt.rb b/lib/jekyll/excerpt.rb index 958e3f3c..41d4976c 100644 --- a/lib/jekyll/excerpt.rb +++ b/lib/jekyll/excerpt.rb @@ -106,7 +106,7 @@ module Jekyll # Returns excerpt String def extract_excerpt(post_content) separator = site.config['excerpt_separator'] - head, _, tail = post_content.partition(separator) + head, _, tail = post_content.to_s.partition(separator) "" << head << "\n\n" << tail.scan(/^\[[^\]]+\]:.+$/).join("\n") end diff --git a/lib/jekyll/layout_reader.rb b/lib/jekyll/layout_reader.rb index a9172c06..a8466beb 100644 --- a/lib/jekyll/layout_reader.rb +++ b/lib/jekyll/layout_reader.rb @@ -38,12 +38,12 @@ module Jekyll end def layout_directory_inside_source - Jekyll.sanitized_path(site.source, site.config['layouts']) + site.in_source_dir(site.config['layouts']) end def layout_directory_in_cwd dir = Jekyll.sanitized_path(Dir.pwd, site.config['layouts']) - if File.directory?(dir) + if File.directory?(dir) && !site.safe dir else nil diff --git a/lib/jekyll/page.rb b/lib/jekyll/page.rb index dcbd3ac5..98f730bf 100644 --- a/lib/jekyll/page.rb +++ b/lib/jekyll/page.rb @@ -140,7 +140,7 @@ module Jekyll # # Returns the destination file path String. def destination(dest) - path = Jekyll.sanitized_path(dest, URL.unescape_path(url)) + path = site.in_dest_dir(dest, URL.unescape_path(url)) path = File.join(path, "index.html") if url =~ /\/$/ path end diff --git a/lib/jekyll/plugin_manager.rb b/lib/jekyll/plugin_manager.rb index 7b817e38..c52a5205 100644 --- a/lib/jekyll/plugin_manager.rb +++ b/lib/jekyll/plugin_manager.rb @@ -66,7 +66,7 @@ module Jekyll # Returns an Array of plugin search paths def plugins_path if (site.config['plugins'] == Jekyll::Configuration::DEFAULTS['plugins']) - [Jekyll.sanitized_path(site.source, site.config['plugins'])] + [site.in_source_dir(site.config['plugins'])] else Array(site.config['plugins']).map { |d| File.expand_path(d) } end diff --git a/lib/jekyll/post.rb b/lib/jekyll/post.rb index 68b85acb..c377e376 100644 --- a/lib/jekyll/post.rb +++ b/lib/jekyll/post.rb @@ -49,7 +49,7 @@ module Jekyll def initialize(site, source, dir, name) @site = site @dir = dir - @base = containing_dir(source, dir) + @base = containing_dir(dir) @name = name self.categories = dir.downcase.split('/').reject { |x| x.empty? } @@ -88,8 +88,8 @@ module Jekyll end # Get the full path to the directory containing the post files - def containing_dir(source, dir) - return File.join(source, dir, '_posts') + def containing_dir(dir) + site.in_source_dir(dir, '_posts') end # Read the YAML frontmatter. @@ -268,7 +268,7 @@ module Jekyll # Returns destination file path String. def destination(dest) # The url needs to be unescaped in order to preserve the correct filename - path = Jekyll.sanitized_path(dest, URL.unescape_path(url)) + path = site.in_dest_dir(dest, URL.unescape_path(url)) path = File.join(path, "index.html") if path[/\.html?$/].nil? path end diff --git a/lib/jekyll/related_posts.rb b/lib/jekyll/related_posts.rb index be0513fc..041ee551 100644 --- a/lib/jekyll/related_posts.rb +++ b/lib/jekyll/related_posts.rb @@ -46,8 +46,7 @@ module Jekyll end def most_recent_posts - recent_posts = site.posts.reverse - [post] - recent_posts.first(10) + @most_recent_posts ||= (site.posts.reverse - [post]).first(10) end def display(output) diff --git a/lib/jekyll/site.rb b/lib/jekyll/site.rb index 502e3ecb..115b4133 100644 --- a/lib/jekyll/site.rb +++ b/lib/jekyll/site.rb @@ -3,11 +3,12 @@ require 'csv' module Jekyll class Site - attr_accessor :config, :layouts, :posts, :pages, :static_files, - :exclude, :include, :source, :dest, :lsi, :highlighter, - :permalink_style, :time, :future, :unpublished, :safe, :plugins, :limit_posts, - :show_drafts, :keep_files, :baseurl, :data, :file_read_opts, :gems, - :plugin_manager + attr_reader :source, :dest, :config + attr_accessor :layouts, :posts, :pages, :static_files, + :exclude, :include, :lsi, :highlighter, :permalink_style, + :time, :future, :unpublished, :safe, :plugins, :limit_posts, + :show_drafts, :keep_files, :baseurl, :data, :file_read_opts, + :gems, :plugin_manager attr_accessor :converters, :generators @@ -15,16 +16,16 @@ module Jekyll # # config - A Hash containing site configuration details. def initialize(config) - self.config = config.clone + @config = config.clone %w[safe lsi highlighter baseurl exclude include future unpublished show_drafts limit_posts keep_files gems].each do |opt| self.send("#{opt}=", config[opt]) end - self.source = File.expand_path(config['source']) - self.dest = File.expand_path(config['destination']) - self.permalink_style = config['permalink'].to_sym + # Source and destination may not be changed after the site has been created. + @source = File.expand_path(config['source']).freeze + @dest = File.expand_path(config['destination']).freeze self.plugin_manager = Jekyll::PluginManager.new(self) self.plugins = plugin_manager.plugins_path @@ -32,6 +33,10 @@ module Jekyll self.file_read_opts = {} self.file_read_opts[:encoding] = config['encoding'] if config['encoding'] + self.permalink_style = config['permalink'].to_sym + + Jekyll.sites << self + reset setup end @@ -88,6 +93,30 @@ module Jekyll end end + # Public: Prefix a given path with the source directory. + # + # paths - (optional) path elements to a file or directory within the + # source directory + # + # Returns a path which is prefixed with the source directory. + def in_source_dir(*paths) + paths.reduce(source) do |base, path| + Jekyll.sanitized_path(base, path) + end + end + + # Public: Prefix a given path with the destination directory. + # + # paths - (optional) path elements to a file or directory within the + # destination directory + # + # Returns a path which is prefixed with the destination directory. + def in_dest_dir(*paths) + paths.reduce(dest) do |base, path| + Jekyll.sanitized_path(base, path) + end + end + # The list of collections and their corresponding Jekyll::Collection instances. # If config['collections'] is set, a new instance is created for each item in the collection. # If config['collections'] is not set, a new hash is returned. @@ -132,7 +161,7 @@ module Jekyll # # Returns nothing. def read_directories(dir = '') - base = File.join(source, dir) + base = in_source_dir(dir) entries = Dir.chdir(base) { filter_entries(Dir.entries('.'), base) } read_posts(dir) @@ -141,7 +170,7 @@ module Jekyll limit_posts! if limit_posts > 0 # limit the posts if :limit_posts option is set entries.each do |f| - f_abs = File.join(base, f) + f_abs = in_source_dir(base, f) if File.directory?(f_abs) f_rel = File.join(dir, f) read_directories(f_rel) unless dest.sub(/\/$/, '') == f_abs @@ -198,7 +227,7 @@ module Jekyll # # Returns nothing def read_data(dir) - base = Jekyll.sanitized_path(source, dir) + base = in_source_dir(dir) read_data_to(base, self.data) end @@ -217,7 +246,7 @@ module Jekyll end entries.each do |entry| - path = Jekyll.sanitized_path(dir, entry) + path = in_source_dir(dir, entry) next if File.symlink?(path) && safe key = sanitize_filename(File.basename(entry, '.*')) @@ -407,10 +436,10 @@ module Jekyll # # Returns the list of entries to process def get_entries(dir, subfolder) - base = File.join(source, dir, subfolder) + base = in_source_dir(dir, subfolder) return [] unless File.exist?(base) entries = Dir.chdir(base) { filter_entries(Dir['**/*'], base) } - entries.delete_if { |e| File.directory?(File.join(base, e)) } + entries.delete_if { |e| File.directory?(in_source_dir(base, e)) } end # Aggregate post information diff --git a/lib/jekyll/static_file.rb b/lib/jekyll/static_file.rb index 02087e49..eae85b54 100644 --- a/lib/jekyll/static_file.rb +++ b/lib/jekyll/static_file.rb @@ -37,7 +37,7 @@ module Jekyll # # Returns destination file path. def destination(dest) - File.join(*[dest, destination_rel_dir, @name].compact) + @site.in_dest_dir(*[dest, destination_rel_dir, @name].compact) end def destination_rel_dir diff --git a/lib/jekyll/tags/include.rb b/lib/jekyll/tags/include.rb index c6b1ed9c..3eb4d7c0 100644 --- a/lib/jekyll/tags/include.rb +++ b/lib/jekyll/tags/include.rb @@ -161,7 +161,7 @@ eos end def resolved_includes_dir(context) - Jekyll.sanitized_path(context.registers[:site].source, page_path(context)) + context.registers[:site].in_source_dir(page_path(context)) end end end diff --git a/test/helper.rb b/test/helper.rb index 97be56ad..3103e117 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -30,10 +30,10 @@ class Test::Unit::TestCase end def site_configuration(overrides = {}) + full_overrides = build_configs(overrides, build_configs({"destination" => dest_dir})) build_configs({ "source" => source_dir, - "destination" => dest_dir - }, build_configs(overrides)) + }, full_overrides) end def dest_dir(*subdirs) diff --git a/test/test_cleaner.rb b/test/test_cleaner.rb index e9bcc0f5..304ce623 100644 --- a/test/test_cleaner.rb +++ b/test/test_cleaner.rb @@ -4,15 +4,16 @@ class TestCleaner < Test::Unit::TestCase context "directory in keep_files" do setup do clear_dest - stub(Jekyll).configuration do - Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir}) - end FileUtils.mkdir_p(dest_dir('to_keep/child_dir')) FileUtils.touch(File.join(dest_dir('to_keep'), 'index.html')) FileUtils.touch(File.join(dest_dir('to_keep/child_dir'), 'index.html')) - @site = Site.new(Jekyll.configuration) + @site = Site.new(Jekyll.configuration({ + "skip_config_files" => true, + "source" => source_dir, + "destination" => dest_dir + })) @site.keep_files = ['to_keep/child_dir'] @cleaner = Site::Cleaner.new(@site) @@ -43,14 +44,15 @@ class TestCleaner < Test::Unit::TestCase context "directory containing no files and non-empty directories" do setup do clear_dest - stub(Jekyll).configuration do - Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir}) - end FileUtils.mkdir_p(source_dir('no_files_inside/child_dir')) FileUtils.touch(File.join(source_dir('no_files_inside/child_dir'), 'index.html')) - @site = Site.new(Jekyll.configuration) + @site = Site.new(Jekyll.configuration({ + "skip_config_files" => true, + "source" => source_dir, + "destination" => dest_dir + })) @site.process @cleaner = Site::Cleaner.new(@site) diff --git a/test/test_collections.rb b/test/test_collections.rb index 97b891ef..1975e402 100644 --- a/test/test_collections.rb +++ b/test/test_collections.rb @@ -187,6 +187,7 @@ class TestCollections < Test::Unit::TestCase should "not allow symlinks" do assert_not_include @collection.filtered_entries, "um_hi.md" + assert_not_include @collection.filtered_entries, "/um_hi.md" end should "not include the symlinked file in the list of docs" do diff --git a/test/test_convertible.rb b/test/test_convertible.rb index 28f99952..6482ad90 100644 --- a/test/test_convertible.rb +++ b/test/test_convertible.rb @@ -4,7 +4,11 @@ require 'ostruct' class TestConvertible < Test::Unit::TestCase context "yaml front-matter" do setup do - @convertible = OpenStruct.new + @convertible = OpenStruct.new( + "site" => Site.new(Jekyll.configuration( + "source" => File.expand_path('../fixtures', __FILE__) + )) + ) @convertible.extend Jekyll::Convertible @base = File.expand_path('../fixtures', __FILE__) end diff --git a/test/test_document.rb b/test/test_document.rb index 3464cd2b..90c16b82 100644 --- a/test/test_document.rb +++ b/test/test_document.rb @@ -13,6 +13,10 @@ class TestDocument < Test::Unit::TestCase @document = @site.collections["methods"].docs.first end + should "exist" do + assert !@document.nil? + end + should "know its relative path" do assert_equal "_methods/configuration.md", @document.relative_path end diff --git a/test/test_draft.rb b/test/test_draft.rb index b1b3d08d..5843665b 100644 --- a/test/test_draft.rb +++ b/test/test_draft.rb @@ -8,8 +8,7 @@ class TestDraft < Test::Unit::TestCase context "A Draft" do setup do clear_dest - stub(Jekyll).configuration { Jekyll::Configuration::DEFAULTS } - @site = Site.new(Jekyll.configuration) + @site = Site.new(site_configuration) end should "ensure valid drafts are valid" do diff --git a/test/test_entry_filter.rb b/test/test_entry_filter.rb index e562277e..5c5711cb 100644 --- a/test/test_entry_filter.rb +++ b/test/test_entry_filter.rb @@ -3,10 +3,7 @@ require 'helper' class TestEntryFilter < Test::Unit::TestCase context "Filtering entries" do setup do - stub(Jekyll).configuration do - Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir}) - end - @site = Site.new(Jekyll.configuration) + @site = Site.new(site_configuration) end should "filter entries" do @@ -50,10 +47,7 @@ class TestEntryFilter < Test::Unit::TestCase end should "filter symlink entries when safe mode enabled" do - stub(Jekyll).configuration do - Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir, 'safe' => true}) - end - site = Site.new(Jekyll.configuration) + site = Site.new(site_configuration('safe' => true)) stub(File).symlink?('symlink.js') {true} files = %w[symlink.js] assert_equal [], site.filter_entries(files) @@ -66,10 +60,7 @@ class TestEntryFilter < Test::Unit::TestCase end should "not include symlinks in safe mode" do - stub(Jekyll).configuration do - Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir, 'safe' => true}) - end - site = Site.new(Jekyll.configuration) + site = Site.new(site_configuration('safe' => true)) site.read_directories("symlink-test") assert_equal [], site.pages @@ -77,10 +68,7 @@ class TestEntryFilter < Test::Unit::TestCase end should "include symlinks in unsafe mode" do - stub(Jekyll).configuration do - Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir, 'safe' => false}) - end - site = Site.new(Jekyll.configuration) + site = Site.new(site_configuration) site.read_directories("symlink-test") assert_not_equal [], site.pages @@ -90,10 +78,7 @@ class TestEntryFilter < Test::Unit::TestCase context "#glob_include?" do setup do - stub(Jekyll).configuration do - Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir}) - end - @site = Site.new(Jekyll.configuration) + @site = Site.new(site_configuration) @filter = EntryFilter.new(@site) end diff --git a/test/test_excerpt.rb b/test/test_excerpt.rb index b6300fde..200a46be 100644 --- a/test/test_excerpt.rb +++ b/test/test_excerpt.rb @@ -13,10 +13,7 @@ class TestExcerpt < Test::Unit::TestCase context "With extraction disabled" do setup do clear_dest - stub(Jekyll).configuration do - Jekyll::Configuration::DEFAULTS.merge({'excerpt_separator' => ''}) - end - @site = Site.new(Jekyll.configuration) + @site = Site.new(site_configuration('excerpt_separator' => '')) @post = setup_post("2013-07-22-post-excerpt-with-layout.markdown") end @@ -29,8 +26,7 @@ class TestExcerpt < Test::Unit::TestCase context "An extracted excerpt" do setup do clear_dest - stub(Jekyll).configuration { Jekyll::Configuration::DEFAULTS } - @site = Site.new(Jekyll.configuration) + @site = Site.new(site_configuration) @post = setup_post("2013-07-22-post-excerpt-with-layout.markdown") @excerpt = @post.send :extract_excerpt end diff --git a/test/test_page.rb b/test/test_page.rb index b34b511c..20ed3198 100644 --- a/test/test_page.rb +++ b/test/test_page.rb @@ -15,8 +15,11 @@ class TestPage < Test::Unit::TestCase context "A Page" do setup do clear_dest - stub(Jekyll).configuration { Jekyll::Configuration::DEFAULTS } - @site = Site.new(Jekyll.configuration) + @site = Site.new(Jekyll.configuration({ + "source" => source_dir, + "destination" => dest_dir, + "skip_config_files" => true + })) end context "processing pages" do diff --git a/test/test_post.rb b/test/test_post.rb index 48e2eb03..582d100a 100644 --- a/test/test_post.rb +++ b/test/test_post.rb @@ -15,8 +15,11 @@ class TestPost < Test::Unit::TestCase context "A Post" do setup do clear_dest - stub(Jekyll).configuration { Jekyll::Configuration::DEFAULTS } - @site = Site.new(Jekyll.configuration) + @site = Site.new(Jekyll.configuration({ + "skip_config_files" => true, + "source" => source_dir, + "destination" => dest_dir + })) end should "ensure valid posts are valid" do @@ -145,7 +148,7 @@ class TestPost < Test::Unit::TestCase do_render(post) post.write(dest_dir) - assert !File.exist?(unexpected) + assert !File.exist?(unexpected), "../../../baddie.html should not exist." assert File.exist?(File.expand_path("baddie.html", dest_dir)) end @@ -606,7 +609,7 @@ class TestPost < Test::Unit::TestCase should "include templates" do post = setup_post("2008-12-13-include.markdown") - post.site.source = File.join(File.dirname(__FILE__), 'source') + post.site.instance_variable_set(:@source, File.join(File.dirname(__FILE__), 'source')) do_render(post) assert_equal "<<<
Tom Preston-Werner\ngithub.com/mojombo
\n\nThis is cool
\n >>>", post.output @@ -685,7 +688,7 @@ class TestPost < Test::Unit::TestCase context "site config with category" do setup do - config = Jekyll::Configuration::DEFAULTS.merge({ + config = site_configuration({ 'defaults' => [ 'scope' => { 'path' => '' @@ -712,7 +715,7 @@ class TestPost < Test::Unit::TestCase context "site config with categories" do setup do - config = Jekyll::Configuration::DEFAULTS.merge({ + config = site_configuration({ 'defaults' => [ 'scope' => { 'path' => '' diff --git a/test/test_site.rb b/test/test_site.rb index 7c42862a..4b8409e7 100644 --- a/test/test_site.rb +++ b/test/test_site.rb @@ -8,7 +8,7 @@ class TestSite < Test::Unit::TestCase end should "look for plugins under the site directory by default" do - site = Site.new(Jekyll::Configuration::DEFAULTS.merge({'source' => File.expand_path(source_dir)})) + site = Site.new(site_configuration) assert_equal [File.join(source_dir, '_plugins')], site.plugins end @@ -44,30 +44,35 @@ class TestSite < Test::Unit::TestCase end context "creating sites" do setup do - stub(Jekyll).configuration do - Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir}) - end - @site = Site.new(Jekyll.configuration) + @site = Site.new(site_configuration) @num_invalid_posts = 4 end + teardown do + if defined?(MyGenerator) + self.class.send(:remove_const, :MyGenerator) + end + end + should "have an empty tag hash by default" do assert_equal Hash.new, @site.tags end should "give site with parsed pages and posts to generators" do - @site.reset - @site.read class MyGenerator < Generator def generate(site) site.pages.dup.each do |page| raise "#{page} isn't a page" unless page.is_a?(Page) raise "#{page} doesn't respond to :name" unless page.respond_to?(:name) end + site.file_read_opts[:secret_message] = 'hi' end end + @site = Site.new(site_configuration) + @site.read @site.generate assert_not_equal 0, @site.pages.size + assert_equal 'hi', @site.file_read_opts[:secret_message] end should "reset data before processing" do @@ -221,22 +226,14 @@ class TestSite < Test::Unit::TestCase context 'error handling' do should "raise if destination is included in source" do - stub(Jekyll).configuration do - Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => source_dir}) - end - assert_raise Jekyll::Errors::FatalException do - site = Site.new(Jekyll.configuration) + site = Site.new(site_configuration('destination' => source_dir)) end end should "raise if destination is source" do - stub(Jekyll).configuration do - Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => File.join(source_dir, "..")}) - end - assert_raise Jekyll::Errors::FatalException do - site = Site.new(Jekyll.configuration) + site = Site.new(site_configuration('destination' => File.join(source_dir, ".."))) end end end @@ -281,7 +278,7 @@ class TestSite < Test::Unit::TestCase end should 'remove orphaned files in destination - keep_files .svn' do - config = Jekyll::Configuration::DEFAULTS.merge({'source' => source_dir, 'destination' => dest_dir, 'keep_files' => ['.svn']}) + config = site_configuration('keep_files' => %w{.svn}) @site = Site.new(config) @site.process assert !File.exist?(dest_dir('.htpasswd')) @@ -308,7 +305,7 @@ class TestSite < Test::Unit::TestCase end custom_processor = "CustomMarkdown" - s = Site.new(Jekyll.configuration.merge({ 'markdown' => custom_processor })) + s = Site.new(site_configuration('markdown' => custom_processor)) assert_nothing_raised do s.process end @@ -331,7 +328,7 @@ class TestSite < Test::Unit::TestCase end bad_processor = "Custom::Markdown" - s = Site.new(Jekyll.configuration.merge({ 'markdown' => bad_processor })) + s = Site.new(site_configuration('markdown' => bad_processor)) assert_raise Jekyll::Errors::FatalException do s.process end @@ -345,13 +342,13 @@ class TestSite < Test::Unit::TestCase should 'not throw an error at initialization time' do bad_processor = 'not a processor name' assert_nothing_raised do - Site.new(Jekyll.configuration.merge({ 'markdown' => bad_processor })) + Site.new(site_configuration('markdown' => bad_processor)) end end should 'throw FatalException at process time' do bad_processor = 'not a processor name' - s = Site.new(Jekyll.configuration.merge({ 'markdown' => bad_processor })) + s = Site.new(site_configuration('markdown' => bad_processor)) assert_raise Jekyll::Errors::FatalException do s.process end @@ -360,7 +357,7 @@ class TestSite < Test::Unit::TestCase context 'data directory' do should 'auto load yaml files' do - site = Site.new(Jekyll.configuration) + site = Site.new(site_configuration) site.process file_content = SafeYAML.load_file(File.join(source_dir, '_data', 'members.yaml')) @@ -370,7 +367,7 @@ class TestSite < Test::Unit::TestCase end should 'auto load yml files' do - site = Site.new(Jekyll.configuration) + site = Site.new(site_configuration) site.process file_content = SafeYAML.load_file(File.join(source_dir, '_data', 'languages.yml')) @@ -380,7 +377,7 @@ class TestSite < Test::Unit::TestCase end should 'auto load json files' do - site = Site.new(Jekyll.configuration) + site = Site.new(site_configuration) site.process file_content = SafeYAML.load_file(File.join(source_dir, '_data', 'members.json')) @@ -390,7 +387,7 @@ class TestSite < Test::Unit::TestCase end should 'auto load yaml files in subdirectory' do - site = Site.new(Jekyll.configuration) + site = Site.new(site_configuration) site.process file_content = SafeYAML.load_file(File.join(source_dir, '_data', 'categories', 'dairy.yaml')) @@ -400,7 +397,7 @@ class TestSite < Test::Unit::TestCase end should "load symlink files in unsafe mode" do - site = Site.new(Jekyll.configuration.merge({'safe' => false})) + site = Site.new(site_configuration('safe' => false)) site.process file_content = SafeYAML.load_file(File.join(source_dir, '_data', 'products.yml')) @@ -410,7 +407,7 @@ class TestSite < Test::Unit::TestCase end should "not load symlink files in safe mode" do - site = Site.new(Jekyll.configuration.merge({'safe' => true})) + site = Site.new(site_configuration('safe' => true)) site.process assert_nil site.data['products']