#
# h2. spec/matchers/archive_contents_matcher.rb -- matches contents of archive to disk
#
# == About
#
# An RSpec matcher which tests that an archive of files has the same
# contents as various paths on disk.
#
# Author:: (Philip flip Kromer, Dhruv Bansal) for Infinite Monkeywrench Project (mailto:coders@infochimps.org)
# Copyright:: Copyright (c) 2008 infochimps.org
# License:: GPL 3.0
# Website:: http://infinitemonkeywrench.org/
#
require 'find'
module Spec
module Matchers
module IMW
# Match the contents of the archive against files or directories
# in +paths+.
#
# Options include:
#
# :relative_to:: a leading path which will be stripped
# from all +paths+ before comparison with the contents of the
# directory.
class ArchiveContentsMatchPaths
private
def initialize paths,opts = {}
opts.reverse_merge!({:relative_to => nil})
paths = [paths] if paths.class == String
@paths = paths
@relative_to = opts[:relative_to]
find_paths_contents
end
def find_paths_contents
# find all the files
contents = []
@paths.each do |path|
path = File.expand_path path
if File.file? path then
contents << path
elsif File.directory? path then
contents += Find.files_in_directory(path)
end
end
# strip leading path
contents.map! do |path|
# the +1 is because we want a relative path
path = path[@relative_to.length + 1,path.size]
end
@paths_contents = contents.to_set
end
def pretty_print set
set.to_a.join("\n\t")
end
public
def matches? archive
@archive = archive
@archive_contents = @archive.contents.to_set
@archive_contents == @paths_contents
end
def failure_message
missing_from_archive = "missing from archive:\n\t#{pretty_print(@paths_contents - @archive_contents)}\n"
missing_from_paths = "missing from paths:\n\t#{pretty_print(@archive_contents - @paths_contents)}\n"
common = "common to both:\n\t#{pretty_print(@archive_contents & @paths_contents)}\n"
"expected contents of archive (#{@archive.path}) and paths (#{@paths.join(", ")}) to be identical.\n#{missing_from_archive}\n#{missing_from_paths}\n#{common}"
end
def negative_failure_message
"expected contents of archive (#{@archive.path}) and paths (#{@paths.join(", ")}) to differ."
end
end
# Invokes the matcher Spec::Matchers::IMW::ArchiveContentsMatchPaths
def contain_paths_like paths, opts = {}
ArchiveContentsMatchPaths.new(paths,opts)
end
end
end
end
# puts "#{File.basename(__FILE__)}: An archive is something that is bigger on the inside than it is on the outside." # at bottom