327 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			327 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Ruby
		
	
	
	
require "helper"
 | 
						|
 | 
						|
class TestRegenerator < JekyllUnitTest
 | 
						|
  context "The site regenerator" do
 | 
						|
    setup do
 | 
						|
      FileUtils.rm_rf(source_dir(".jekyll-metadata"))
 | 
						|
 | 
						|
      @site = fixture_site({
 | 
						|
        "collections" => {
 | 
						|
          "methods" => {
 | 
						|
            "output" => true
 | 
						|
          }
 | 
						|
        },
 | 
						|
        "incremental" => true
 | 
						|
      })
 | 
						|
 | 
						|
      @site.read
 | 
						|
      @page = @site.pages.first
 | 
						|
      @post = @site.posts.first
 | 
						|
      @document = @site.docs_to_write.first
 | 
						|
      @asset_file = @site.pages.find(&:asset_file?)
 | 
						|
      @regenerator = @site.regenerator
 | 
						|
    end
 | 
						|
 | 
						|
    should "regenerate documents and assets if changed or not in metadata" do
 | 
						|
      assert @regenerator.regenerate?(@page)
 | 
						|
      assert @regenerator.regenerate?(@post)
 | 
						|
      assert @regenerator.regenerate?(@document)
 | 
						|
      assert @regenerator.regenerate?(@asset_file)
 | 
						|
    end
 | 
						|
 | 
						|
    should "not regenerate if not changed" do
 | 
						|
      # Process files
 | 
						|
      @regenerator.regenerate?(@page)
 | 
						|
      @regenerator.regenerate?(@post)
 | 
						|
      @regenerator.regenerate?(@document)
 | 
						|
      @regenerator.regenerate?(@asset_file)
 | 
						|
 | 
						|
      # we need to create the destinations for these files,
 | 
						|
      # because regenerate? checks if the destination exists
 | 
						|
      [@page, @post, @document, @asset_file].each do |item|
 | 
						|
        next unless item.respond_to?(:destination)
 | 
						|
        dest = item.destination(@site.dest)
 | 
						|
        FileUtils.mkdir_p(File.dirname(dest))
 | 
						|
        FileUtils.touch(dest)
 | 
						|
      end
 | 
						|
      @regenerator.write_metadata
 | 
						|
      @regenerator = Regenerator.new(@site)
 | 
						|
 | 
						|
      # these should pass, since nothing has changed, and the
 | 
						|
      # loop above made sure the designations exist
 | 
						|
      assert !@regenerator.regenerate?(@page)
 | 
						|
      assert !@regenerator.regenerate?(@post)
 | 
						|
      assert !@regenerator.regenerate?(@document)
 | 
						|
    end
 | 
						|
 | 
						|
    should "regenerate if destination missing" do
 | 
						|
      # Process files
 | 
						|
      @regenerator.regenerate?(@page)
 | 
						|
      @regenerator.regenerate?(@post)
 | 
						|
      @regenerator.regenerate?(@document)
 | 
						|
      @regenerator.regenerate?(@asset_file)
 | 
						|
 | 
						|
      @regenerator.write_metadata
 | 
						|
      @regenerator = Regenerator.new(@site)
 | 
						|
 | 
						|
      # make sure the files don't actually exist
 | 
						|
      [@page, @post, @document, @asset_file].each do |item|
 | 
						|
        if item.respond_to?(:destination)
 | 
						|
          dest = item.destination(@site.dest)
 | 
						|
          File.unlink(dest) if File.exist?(dest)
 | 
						|
        end
 | 
						|
      end
 | 
						|
 | 
						|
      # while nothing has changed, the output files were not
 | 
						|
      # generated, so they still need to be regenerated
 | 
						|
      assert @regenerator.regenerate?(@page)
 | 
						|
      assert @regenerator.regenerate?(@post)
 | 
						|
      assert @regenerator.regenerate?(@document)
 | 
						|
    end
 | 
						|
 | 
						|
    should "always regenerate asset files" do
 | 
						|
      assert @regenerator.regenerate?(@asset_file)
 | 
						|
    end
 | 
						|
 | 
						|
    should "always regenerate objects that don't respond to :path" do
 | 
						|
      assert @regenerator.regenerate?(Object.new)
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  context "The site regenerator" do
 | 
						|
    setup do
 | 
						|
      FileUtils.rm_rf(source_dir(".jekyll-metadata"))
 | 
						|
      @site = fixture_site({
 | 
						|
        "incremental" => true
 | 
						|
      })
 | 
						|
 | 
						|
      @site.read
 | 
						|
      @post = @site.posts.first
 | 
						|
      @regenerator = @site.regenerator
 | 
						|
      @regenerator.regenerate?(@post)
 | 
						|
 | 
						|
      @layout_path = source_dir("_layouts/default.html")
 | 
						|
    end
 | 
						|
 | 
						|
    teardown do
 | 
						|
      File.rename(@layout_path + ".tmp", @layout_path)
 | 
						|
    end
 | 
						|
 | 
						|
    should "handle deleted/nonexistent dependencies" do
 | 
						|
      assert_equal 1, @regenerator.metadata.size
 | 
						|
      path = @regenerator.metadata.keys[0]
 | 
						|
 | 
						|
      assert_exist @layout_path
 | 
						|
      @regenerator.add_dependency(path, @layout_path)
 | 
						|
 | 
						|
      File.rename(@layout_path, @layout_path + ".tmp")
 | 
						|
      refute File.exist?(@layout_path)
 | 
						|
 | 
						|
      @regenerator.clear_cache
 | 
						|
      assert @regenerator.regenerate?(@post)
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  context "The site metadata" do
 | 
						|
    setup do
 | 
						|
      FileUtils.rm_rf(source_dir(".jekyll-metadata"))
 | 
						|
 | 
						|
      @site = Site.new(Jekyll.configuration({
 | 
						|
        "source"      => source_dir,
 | 
						|
        "destination" => dest_dir,
 | 
						|
        "incremental" => true
 | 
						|
      }))
 | 
						|
 | 
						|
      @site.process
 | 
						|
      @path = @site.in_source_dir(@site.pages.first.path)
 | 
						|
      @regenerator = @site.regenerator
 | 
						|
    end
 | 
						|
 | 
						|
    should "store modification times" do
 | 
						|
      assert_equal File.mtime(@path), @regenerator.metadata[@path]["mtime"]
 | 
						|
    end
 | 
						|
 | 
						|
    should "cache processed entries" do
 | 
						|
      assert @regenerator.cache[@path]
 | 
						|
    end
 | 
						|
 | 
						|
    should "clear the cache on clear_cache" do
 | 
						|
      # @path will be in the cache because the
 | 
						|
      # site will have processed it
 | 
						|
      assert @regenerator.cache[@path]
 | 
						|
 | 
						|
      @regenerator.clear_cache
 | 
						|
      assert_equal @regenerator.cache, {}
 | 
						|
    end
 | 
						|
 | 
						|
    should "write to the metadata file" do
 | 
						|
      @regenerator.clear
 | 
						|
      @regenerator.add(@path)
 | 
						|
      @regenerator.write_metadata
 | 
						|
      assert File.file?(source_dir(".jekyll-metadata"))
 | 
						|
    end
 | 
						|
 | 
						|
    should "read from the metadata file" do
 | 
						|
      @regenerator = Regenerator.new(@site)
 | 
						|
      assert_equal File.mtime(@path), @regenerator.metadata[@path]["mtime"]
 | 
						|
    end
 | 
						|
 | 
						|
    should "read legacy YAML metadata" do
 | 
						|
      metadata_file = source_dir(".jekyll-metadata")
 | 
						|
      @regenerator = Regenerator.new(@site)
 | 
						|
 | 
						|
      File.open(metadata_file, "w") do |f|
 | 
						|
        f.write(@regenerator.metadata.to_yaml)
 | 
						|
      end
 | 
						|
 | 
						|
      @regenerator = Regenerator.new(@site)
 | 
						|
      assert_equal File.mtime(@path), @regenerator.metadata[@path]["mtime"]
 | 
						|
    end
 | 
						|
 | 
						|
    should "not crash when reading corrupted marshal file" do
 | 
						|
      metadata_file = source_dir(".jekyll-metadata")
 | 
						|
      File.open(metadata_file, "w") do |file|
 | 
						|
        file.puts Marshal.dump({ :foo => "bar" })[0, 5]
 | 
						|
      end
 | 
						|
 | 
						|
      @regenerator = Regenerator.new(@site)
 | 
						|
      assert_equal({}, @regenerator.metadata)
 | 
						|
    end
 | 
						|
 | 
						|
    # Methods
 | 
						|
 | 
						|
    should "be able to add a path to the metadata" do
 | 
						|
      @regenerator.clear
 | 
						|
      @regenerator.add(@path)
 | 
						|
      assert_equal File.mtime(@path), @regenerator.metadata[@path]["mtime"]
 | 
						|
      assert_equal [], @regenerator.metadata[@path]["deps"]
 | 
						|
      assert @regenerator.cache[@path]
 | 
						|
    end
 | 
						|
 | 
						|
    should "return true on nonexistent path" do
 | 
						|
      @regenerator.clear
 | 
						|
      assert @regenerator.add("/bogus/path.md")
 | 
						|
      assert @regenerator.modified?("/bogus/path.md")
 | 
						|
    end
 | 
						|
 | 
						|
    should "be able to force a path to regenerate" do
 | 
						|
      @regenerator.clear
 | 
						|
      @regenerator.force(@path)
 | 
						|
      assert @regenerator.cache[@path]
 | 
						|
      assert @regenerator.modified?(@path)
 | 
						|
    end
 | 
						|
 | 
						|
    should "be able to clear metadata and cache" do
 | 
						|
      @regenerator.clear
 | 
						|
      @regenerator.add(@path)
 | 
						|
      assert_equal 1, @regenerator.metadata.length
 | 
						|
      assert_equal 1, @regenerator.cache.length
 | 
						|
      @regenerator.clear
 | 
						|
      assert_equal 0, @regenerator.metadata.length
 | 
						|
      assert_equal 0, @regenerator.cache.length
 | 
						|
    end
 | 
						|
 | 
						|
    should "not regenerate a path if it is not modified" do
 | 
						|
      @regenerator.clear
 | 
						|
      @regenerator.add(@path)
 | 
						|
      @regenerator.write_metadata
 | 
						|
      @regenerator = Regenerator.new(@site)
 | 
						|
 | 
						|
      assert !@regenerator.modified?(@path)
 | 
						|
    end
 | 
						|
 | 
						|
    should "not regenerate if path in cache is false" do
 | 
						|
      @regenerator.clear
 | 
						|
      @regenerator.add(@path)
 | 
						|
      @regenerator.write_metadata
 | 
						|
      @regenerator = Regenerator.new(@site)
 | 
						|
 | 
						|
      assert !@regenerator.modified?(@path)
 | 
						|
      assert !@regenerator.cache[@path]
 | 
						|
      assert !@regenerator.modified?(@path)
 | 
						|
    end
 | 
						|
 | 
						|
    should "regenerate if path in not in metadata" do
 | 
						|
      @regenerator.clear
 | 
						|
      @regenerator.add(@path)
 | 
						|
 | 
						|
      assert @regenerator.modified?(@path)
 | 
						|
    end
 | 
						|
 | 
						|
    should "regenerate if path in cache is true" do
 | 
						|
      @regenerator.clear
 | 
						|
      @regenerator.add(@path)
 | 
						|
 | 
						|
      assert @regenerator.modified?(@path)
 | 
						|
      assert @regenerator.cache[@path]
 | 
						|
      assert @regenerator.modified?(@path)
 | 
						|
    end
 | 
						|
 | 
						|
    should "regenerate if file is modified" do
 | 
						|
      @regenerator.clear
 | 
						|
      @regenerator.add(@path)
 | 
						|
      @regenerator.metadata[@path]["mtime"] = Time.at(0)
 | 
						|
      @regenerator.write_metadata
 | 
						|
      @regenerator = Regenerator.new(@site)
 | 
						|
 | 
						|
      refute_same File.mtime(@path), @regenerator.metadata[@path]["mtime"]
 | 
						|
      assert @regenerator.modified?(@path)
 | 
						|
    end
 | 
						|
 | 
						|
    should "regenerate if dependency is modified" do
 | 
						|
      @regenerator.clear
 | 
						|
      @regenerator.add(@path)
 | 
						|
      @regenerator.write_metadata
 | 
						|
      @regenerator = Regenerator.new(@site)
 | 
						|
 | 
						|
      @regenerator.add_dependency(@path, "new.dependency")
 | 
						|
      assert_equal ["new.dependency"], @regenerator.metadata[@path]["deps"]
 | 
						|
      assert @regenerator.modified?("new.dependency")
 | 
						|
      assert @regenerator.modified?(@path)
 | 
						|
    end
 | 
						|
 | 
						|
    should "not regenerate again if multiple dependencies" do
 | 
						|
      multi_deps = @regenerator.metadata.select { |_k, v| v["deps"].length > 2 }
 | 
						|
      multi_dep_path = multi_deps.keys.first
 | 
						|
 | 
						|
      assert @regenerator.metadata[multi_dep_path]["deps"].length > 2
 | 
						|
 | 
						|
      assert @regenerator.modified?(multi_dep_path)
 | 
						|
 | 
						|
      @site.process
 | 
						|
      @regenerator.clear_cache
 | 
						|
 | 
						|
      refute @regenerator.modified?(multi_dep_path)
 | 
						|
    end
 | 
						|
 | 
						|
    should "regenerate everything if metadata is disabled" do
 | 
						|
      @site.config["incremental"] = false
 | 
						|
      @regenerator.clear
 | 
						|
      @regenerator.add(@path)
 | 
						|
      @regenerator.write_metadata
 | 
						|
      @regenerator = Regenerator.new(@site)
 | 
						|
 | 
						|
      assert @regenerator.modified?(@path)
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  context "when incremental regeneration is disabled" do
 | 
						|
    setup do
 | 
						|
      FileUtils.rm_rf(source_dir(".jekyll-metadata"))
 | 
						|
      @site = Site.new(Jekyll.configuration({
 | 
						|
        "source"      => source_dir,
 | 
						|
        "destination" => dest_dir,
 | 
						|
        "incremental" => false
 | 
						|
      }))
 | 
						|
 | 
						|
      @site.process
 | 
						|
      @path = @site.in_source_dir(@site.pages.first.path)
 | 
						|
      @regenerator = @site.regenerator
 | 
						|
    end
 | 
						|
 | 
						|
    should "not create .jekyll-metadata" do
 | 
						|
      refute File.file?(source_dir(".jekyll-metadata"))
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 |