spec Cache
This commit is contained in:
parent
cb629bf7ec
commit
8100830c16
@ -119,9 +119,11 @@ module Rscons
|
||||
end
|
||||
|
||||
# all cached dependencies must have their checksums match
|
||||
@cache[:targets][target][:deps].map do |dep_cache|
|
||||
dep_cache[:checksum] == lookup_checksum(dep_cache[:fname])
|
||||
end.all?
|
||||
@cache[:targets][target][:deps].each do |dep_cache|
|
||||
return false unless dep_cache[:checksum] == lookup_checksum(dep_cache[:fname])
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
# Store cache information about a target built by a builder
|
||||
@ -150,16 +152,14 @@ module Rscons
|
||||
# removal upon a "clean" operation.
|
||||
def mkdir_p(path)
|
||||
parts = path.split(/[\\\/]/)
|
||||
(0..parts.size).each do |i|
|
||||
(0..parts.size-1).each do |i|
|
||||
subpath = File.join(*parts[0, i + 1]).encode(__ENCODING__)
|
||||
unless File.exists?(subpath)
|
||||
FileUtils.mkdir(subpath)
|
||||
unless @cache[:directories].include?(subpath)
|
||||
@cache[:directories][subpath] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Return a list of directories which were created as a part of the build
|
||||
def directories
|
||||
@ -179,7 +179,7 @@ module Rscons
|
||||
# Calculate and return a file's checksum
|
||||
# @param file [String] The file name.
|
||||
def calculate_checksum(file)
|
||||
@lookup_checksums[file] = Digest::MD5.hexdigest(File.read(file, {mode: 'rb'})).encode(__ENCODING__) rescue ''
|
||||
@lookup_checksums[file] = Digest::MD5.hexdigest(File.read(file, mode: 'rb')).encode(__ENCODING__) rescue ''
|
||||
end
|
||||
end
|
||||
end
|
||||
|
204
spec/rscons/cache_spec.rb
Normal file
204
spec/rscons/cache_spec.rb
Normal file
@ -0,0 +1,204 @@
|
||||
module Rscons
|
||||
describe Cache do
|
||||
before do
|
||||
File.stub(:read) { nil }
|
||||
end
|
||||
|
||||
def build_from(cache)
|
||||
YAML.should_receive(:load).and_return(cache)
|
||||
Cache.new
|
||||
end
|
||||
|
||||
describe ".clear" do
|
||||
it "removes the cache file" do
|
||||
FileUtils.should_receive(:rm_f).with(Cache::CACHE_FILE)
|
||||
Cache.clear
|
||||
end
|
||||
end
|
||||
|
||||
describe "#initialize" do
|
||||
context "when corrupt" do
|
||||
it "prints a warning and defaults to an empty hash" do
|
||||
YAML.should_receive(:load).and_return("string")
|
||||
$stderr.should_receive(:puts).with(/Warning:.*was.corrupt/)
|
||||
Cache.new.instance_variable_get(:@cache).is_a?(Hash).should be_true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#write" do
|
||||
it "should fill in :version and write to file" do
|
||||
cache = {}
|
||||
fh = $stdout
|
||||
fh.should_receive(:puts)
|
||||
File.should_receive(:open).and_yield(fh)
|
||||
build_from(cache).write
|
||||
cache[:version].should == Rscons::VERSION
|
||||
end
|
||||
end
|
||||
|
||||
describe "#up_to_date?" do
|
||||
it "returns false when target file does not exist" do
|
||||
File.should_receive(:exists?).with("target").and_return(false)
|
||||
build_from({}).up_to_date?("target", "command", []).should be_false
|
||||
end
|
||||
|
||||
it "returns false when target is not registered in the cache" do
|
||||
File.should_receive(:exists?).with("target").and_return(true)
|
||||
build_from({}).up_to_date?("target", "command", []).should be_false
|
||||
end
|
||||
|
||||
it "returns false when the target's checksum does not match" do
|
||||
_cache = {targets: {"target" => {checksum: "abc"}}}
|
||||
cache = build_from(_cache)
|
||||
File.should_receive(:exists?).with("target").and_return(true)
|
||||
cache.should_receive(:calculate_checksum).with("target").and_return("def")
|
||||
cache.up_to_date?("target", "command", []).should be_false
|
||||
end
|
||||
|
||||
it "returns false when the build command has changed" do
|
||||
_cache = {targets: {"target" => {checksum: "abc", command: "old command"}}}
|
||||
cache = build_from(_cache)
|
||||
File.should_receive(:exists?).with("target").and_return(true)
|
||||
cache.should_receive(:calculate_checksum).with("target").and_return("abc")
|
||||
cache.up_to_date?("target", "command", []).should be_false
|
||||
end
|
||||
|
||||
it "returns false when there is a new dependency" do
|
||||
_cache = {targets: {"target" => {checksum: "abc",
|
||||
command: "command",
|
||||
deps: [{fname: "dep.1"}]}}}
|
||||
cache = build_from(_cache)
|
||||
File.should_receive(:exists?).with("target").and_return(true)
|
||||
cache.should_receive(:calculate_checksum).with("target").and_return("abc")
|
||||
cache.up_to_date?("target", "command", ["dep.1", "dep.2"]).should be_false
|
||||
end
|
||||
|
||||
it "returns false when a dependency's checksum has changed" do
|
||||
_cache = {targets: {"target" => {checksum: "abc",
|
||||
command: "command",
|
||||
deps: [{fname: "dep.1",
|
||||
checksum: "dep.1.chk"},
|
||||
{fname: "dep.2",
|
||||
checksum: "dep.2.chk"},
|
||||
{fname: "extra.dep",
|
||||
checksum: "extra.dep.chk"}]}}}
|
||||
cache = build_from(_cache)
|
||||
File.should_receive(:exists?).with("target").and_return(true)
|
||||
cache.should_receive(:calculate_checksum).with("target").and_return("abc")
|
||||
cache.should_receive(:calculate_checksum).with("dep.1").and_return("dep.1.chk")
|
||||
cache.should_receive(:calculate_checksum).with("dep.2").and_return("dep.2.changed")
|
||||
cache.up_to_date?("target", "command", ["dep.1", "dep.2"]).should be_false
|
||||
end
|
||||
|
||||
it "returns false with strict_deps=true when cache has an extra dependency" do
|
||||
_cache = {targets: {"target" => {checksum: "abc",
|
||||
command: "command",
|
||||
deps: [{fname: "dep.1",
|
||||
checksum: "dep.1.chk"},
|
||||
{fname: "dep.2",
|
||||
checksum: "dep.2.chk"},
|
||||
{fname: "extra.dep",
|
||||
checksum: "extra.dep.chk"}]}}}
|
||||
cache = build_from(_cache)
|
||||
File.should_receive(:exists?).with("target").and_return(true)
|
||||
cache.should_receive(:calculate_checksum).with("target").and_return("abc")
|
||||
cache.up_to_date?("target", "command", ["dep.1", "dep.2"], strict_deps: true).should be_false
|
||||
end
|
||||
|
||||
it "returns true when no condition for false is met" do
|
||||
_cache = {targets: {"target" => {checksum: "abc",
|
||||
command: "command",
|
||||
deps: [{fname: "dep.1",
|
||||
checksum: "dep.1.chk"},
|
||||
{fname: "dep.2",
|
||||
checksum: "dep.2.chk"},
|
||||
{fname: "extra.dep",
|
||||
checksum: "extra.dep.chk"}]}}}
|
||||
cache = build_from(_cache)
|
||||
File.should_receive(:exists?).with("target").and_return(true)
|
||||
cache.should_receive(:calculate_checksum).with("target").and_return("abc")
|
||||
cache.should_receive(:calculate_checksum).with("dep.1").and_return("dep.1.chk")
|
||||
cache.should_receive(:calculate_checksum).with("dep.2").and_return("dep.2.chk")
|
||||
cache.should_receive(:calculate_checksum).with("extra.dep").and_return("extra.dep.chk")
|
||||
cache.up_to_date?("target", "command", ["dep.1", "dep.2"]).should be_true
|
||||
end
|
||||
end
|
||||
|
||||
describe "#register_build" do
|
||||
it "stores the given information in the cache" do
|
||||
_cache = {}
|
||||
cache = build_from(_cache)
|
||||
cache.should_receive(:calculate_checksum).with("the target").and_return("the checksum")
|
||||
cache.should_receive(:calculate_checksum).with("dep 1").and_return("dep 1 checksum")
|
||||
cache.should_receive(:calculate_checksum).with("dep 2").and_return("dep 2 checksum")
|
||||
cache.register_build("the target", "the command", ["dep 1", "dep 2"])
|
||||
cached_target = cache.instance_variable_get(:@cache)[:targets]["the target"]
|
||||
cached_target.should_not be_nil
|
||||
cached_target[:command].should == "the command"
|
||||
cached_target[:checksum].should == "the checksum"
|
||||
cached_target[:deps].should == [
|
||||
{fname: "dep 1", checksum: "dep 1 checksum"},
|
||||
{fname: "dep 2", checksum: "dep 2 checksum"},
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
describe "#targets" do
|
||||
it "returns a list of targets that are cached" do
|
||||
cache = {targets: {"t1" => {}, "t2" => {}, "t3" => {}}}
|
||||
build_from(cache).targets.should == ["t1", "t2", "t3"]
|
||||
end
|
||||
end
|
||||
|
||||
describe "#mkdir_p" do
|
||||
it "makes directories and records any created in the cache" do
|
||||
_cache = {}
|
||||
cache = build_from(_cache)
|
||||
File.should_receive(:exists?).with("one").and_return(true)
|
||||
File.should_receive(:exists?).with("one/two").and_return(false)
|
||||
FileUtils.should_receive(:mkdir).with("one/two")
|
||||
File.should_receive(:exists?).with("one/two/three").and_return(false)
|
||||
FileUtils.should_receive(:mkdir).with("one/two/three")
|
||||
File.should_receive(:exists?).with("one").and_return(true)
|
||||
File.should_receive(:exists?).with("one/two").and_return(true)
|
||||
File.should_receive(:exists?).with("one/two/four").and_return(false)
|
||||
FileUtils.should_receive(:mkdir).with("one/two/four")
|
||||
cache.mkdir_p("one/two/three")
|
||||
cache.mkdir_p("one\\two\\four")
|
||||
cache.directories.should == ["one/two", "one/two/three", "one/two/four"]
|
||||
end
|
||||
end
|
||||
|
||||
describe "#directories" do
|
||||
it "returns a list of directories that are cached" do
|
||||
_cache = {directories: {"dir1" => true, "dir2" => true}}
|
||||
build_from(_cache).directories.should == ["dir1", "dir2"]
|
||||
end
|
||||
end
|
||||
|
||||
describe "#lookup_checksum" do
|
||||
it "does not re-calculate the checksum when it is already cached" do
|
||||
cache = build_from({})
|
||||
cache.instance_variable_set(:@lookup_checksums, {"f1" => "f1.chk"})
|
||||
cache.should_not_receive(:calculate_checksum)
|
||||
cache.send(:lookup_checksum, "f1").should == "f1.chk"
|
||||
end
|
||||
|
||||
it "calls calculate_checksum when the checksum is not cached" do
|
||||
cache = build_from({})
|
||||
cache.should_receive(:calculate_checksum).with("f1").and_return("ck")
|
||||
cache.send(:lookup_checksum, "f1").should == "ck"
|
||||
end
|
||||
end
|
||||
|
||||
describe "#calculate_checksum" do
|
||||
it "calculates the MD5 of the file contents" do
|
||||
contents = "contents"
|
||||
File.should_receive(:read).with("fname", mode: "rb").and_return(contents)
|
||||
Digest::MD5.should_receive(:hexdigest).with(contents).and_return("the_checksum")
|
||||
build_from({}).send(:calculate_checksum, "fname").should == "the_checksum"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user