bundle-new/spec/support/helpers.rb

360 lines
10 KiB
Ruby

module Spec
module Helpers
def reset!
@in_p, @out_p, @err_p = nil, nil, nil
Dir["#{tmp}/{gems/*,*}"].each do |dir|
next if %(base remote1 gems rubygems).include?(File.basename(dir))
unless ENV['BUNDLER_SUDO_TESTS']
FileUtils.rm_rf(dir)
else
`sudo rm -rf #{dir}`
end
end
FileUtils.mkdir_p(tmp)
FileUtils.mkdir_p(home)
end
attr_reader :out, :err, :exitstatus
def in_app_root(&blk)
Dir.chdir(bundled_app, &blk)
end
def in_app_root2(&blk)
Dir.chdir(bundled_app2, &blk)
end
def in_app_root_custom(root, &blk)
Dir.chdir(root, &blk)
end
def run(cmd, *args)
opts = args.last.is_a?(Hash) ? args.pop : {}
expect_err = opts.delete(:expect_err)
env = opts.delete(:env)
groups = args.map {|a| a.inspect }.join(", ")
setup = "require 'rubygems' ; require 'bundler' ; Bundler.setup(#{groups})\n"
@out = ruby(setup + cmd, :expect_err => expect_err, :env => env)
end
def load_error_run(ruby, name, *args)
cmd = <<-RUBY
begin
#{ruby}
rescue LoadError => e
$stderr.puts "ZOMG LOAD ERROR" if e.message.include?("-- #{name}")
end
RUBY
opts = args.last.is_a?(Hash) ? args.pop : {}
opts.merge!(:expect_err => true)
args += [opts]
run(cmd, *args)
end
def lib
File.expand_path('../../../lib', __FILE__)
end
def bundle(cmd, options = {})
expect_err = options.delete(:expect_err)
exitstatus = options.delete(:exitstatus)
sudo = "sudo" if options.delete(:sudo)
options["no-color"] = true unless options.key?("no-color") || %w(exec conf).include?(cmd.to_s[0..3])
bundle_bin = File.expand_path('../../../bin/bundle', __FILE__)
requires = options.delete(:requires) || []
requires << File.expand_path('../fakeweb/'+options.delete(:fakeweb)+'.rb', __FILE__) if options.key?(:fakeweb)
requires << File.expand_path('../artifice/'+options.delete(:artifice)+'.rb', __FILE__) if options.key?(:artifice)
requires_str = requires.map{|r| "-r#{r}"}.join(" ")
env = (options.delete(:env) || {}).map{|k,v| "#{k}='#{v}'"}.join(" ")
args = options.map do |k,v|
v == true ? " --#{k}" : " --#{k} #{v}" if v
end.join
cmd = "#{env} #{sudo} #{Gem.ruby} -I#{lib} #{requires_str} #{bundle_bin} #{cmd}#{args}"
if exitstatus
sys_status(cmd)
else
sys_exec(cmd, expect_err){|i| yield i if block_given? }
end
end
def bundle_ruby(options = {})
expect_err = options.delete(:expect_err)
exitstatus = options.delete(:exitstatus)
options["no-color"] = true unless options.key?("no-color")
bundle_bin = File.expand_path('../../../bin/bundle_ruby', __FILE__)
requires = options.delete(:requires) || []
requires << File.expand_path('../fakeweb/'+options.delete(:fakeweb)+'.rb', __FILE__) if options.key?(:fakeweb)
requires << File.expand_path('../artifice/'+options.delete(:artifice)+'.rb', __FILE__) if options.key?(:artifice)
requires_str = requires.map{|r| "-r#{r}"}.join(" ")
env = (options.delete(:env) || {}).map{|k,v| "#{k}='#{v}' "}.join
cmd = "#{env}#{Gem.ruby} -I#{lib} #{requires_str} #{bundle_bin}"
if exitstatus
sys_status(cmd)
else
sys_exec(cmd, expect_err){|i| yield i if block_given? }
end
end
def ruby(ruby, options = {})
expect_err = options.delete(:expect_err)
env = (options.delete(:env) || {}).map{|k,v| "#{k}='#{v}' "}.join
ruby.gsub!(/["`\$]/) {|m| "\\#{m}" }
lib_option = options[:no_lib] ? "" : " -I#{lib}"
sys_exec(%{#{env}#{Gem.ruby}#{lib_option} -e "#{ruby}"}, expect_err)
end
def load_error_ruby(ruby, name, opts = {})
cmd = <<-R
begin
#{ruby}
rescue LoadError => e
$stderr.puts "ZOMG LOAD ERROR"# if e.message.include?("-- #{name}")
end
R
ruby(cmd, opts.merge(:expect_err => true))
end
def gembin(cmd)
lib = File.expand_path("../../../lib", __FILE__)
old, ENV['RUBYOPT'] = ENV['RUBYOPT'], "#{ENV['RUBYOPT']} -I#{lib}"
cmd = bundled_app("bin/#{cmd}") unless cmd.to_s.include?("/")
sys_exec(cmd.to_s)
ensure
ENV['RUBYOPT'] = old
end
def sys_exec(cmd, expect_err = false)
Open3.popen3(cmd.to_s) do |stdin, stdout, stderr|
@in_p, @out_p, @err_p = stdin, stdout, stderr
yield @in_p if block_given?
@in_p.close
@out = @out_p.read_available_bytes.strip
@err = @err_p.read_available_bytes.strip
end
puts @err unless expect_err || @err.empty? || !$show_err
@out
end
def sys_status(cmd)
@err = nil
@out = %x{#{cmd}}.strip
@exitstatus = $?.exitstatus
end
def config(config = nil)
path = bundled_app('.bundle/config')
return YAML.load_file(path) unless config
FileUtils.mkdir_p(File.dirname(path))
File.open(path, 'w') do |f|
f.puts config.to_yaml
end
config
end
def gemfile(*args)
path = bundled_app("Gemfile")
path = args.shift if args.first.is_a?(Pathname)
str = args.shift || ""
path.dirname.mkpath
File.open(path.to_s, 'w') do |f|
f.puts strip_whitespace(str)
end
end
def lockfile(*args)
path = bundled_app("Gemfile.lock")
path = args.shift if args.first.is_a?(Pathname)
str = args.shift || ""
File.open(path.to_s, 'w') do |f|
f.puts strip_whitespace(str)
end
end
def strip_whitespace(str)
# Trim the leading spaces
spaces = str[/\A\s+/, 0] || ""
str.gsub(/^#{spaces}/, '')
end
def install_gemfile(*args)
gemfile(*args)
opts = args.last.is_a?(Hash) ? args.last : {}
opts[:retry] ||= 0
bundle :install, opts
end
def install_gems(*gems)
gems.each do |g|
path = "#{gem_repo1}/gems/#{g}.gem"
raise "OMG `#{path}` does not exist!" unless File.exist?(path)
gem_command :install, "--no-rdoc --no-ri --ignore-dependencies #{path}"
end
end
alias install_gem install_gems
def with_gem_path_as(path)
gem_home, gem_path = ENV['GEM_HOME'], ENV['GEM_PATH']
ENV['GEM_HOME'], ENV['GEM_PATH'] = path.to_s, path.to_s
yield
ensure
ENV['GEM_HOME'], ENV['GEM_PATH'] = gem_home, gem_path
end
def break_git!
FileUtils.mkdir_p(tmp("broken_path"))
File.open(tmp("broken_path/git"), "w", 0755) do |f|
f.puts "#!/usr/bin/env ruby\nSTDERR.puts 'This is not the git you are looking for'\nexit 1"
end
ENV["PATH"] = "#{tmp("broken_path")}:#{ENV["PATH"]}"
end
def fake_man!
FileUtils.mkdir_p(tmp("fake_man"))
File.open(tmp("fake_man/man"), "w", 0755) do |f|
f.puts "#!/usr/bin/env ruby\nputs ARGV.inspect\n"
end
ENV["PATH"] = "#{tmp("fake_man")}:#{ENV["PATH"]}"
end
def kill_path!
ENV["PATH"] = ""
end
def system_gems(*gems)
gems = gems.flatten
FileUtils.rm_rf(system_gem_path)
FileUtils.mkdir_p(system_gem_path)
Gem.clear_paths
gem_home, gem_path, path = ENV['GEM_HOME'], ENV['GEM_PATH'], ENV['PATH']
ENV['GEM_HOME'], ENV['GEM_PATH'] = system_gem_path.to_s, system_gem_path.to_s
install_gems(*gems)
if block_given?
begin
yield
ensure
ENV['GEM_HOME'], ENV['GEM_PATH'] = gem_home, gem_path
ENV['PATH'] = path
end
end
end
def realworld_system_gems(*gems)
gems = gems.flatten
FileUtils.rm_rf(system_gem_path)
FileUtils.mkdir_p(system_gem_path)
Gem.clear_paths
gem_home, gem_path, path = ENV['GEM_HOME'], ENV['GEM_PATH'], ENV['PATH']
ENV['GEM_HOME'], ENV['GEM_PATH'] = system_gem_path.to_s, system_gem_path.to_s
gems.each do |gem|
gem_command :install, "--no-rdoc --no-ri #{gem}"
end
if block_given?
begin
yield
ensure
ENV['GEM_HOME'], ENV['GEM_PATH'] = gem_home, gem_path
ENV['PATH'] = path
end
end
end
def cache_gems(*gems)
gems = gems.flatten
FileUtils.rm_rf("#{bundled_app}/vendor/cache")
FileUtils.mkdir_p("#{bundled_app}/vendor/cache")
gems.each do |g|
path = "#{gem_repo1}/gems/#{g}.gem"
raise "OMG `#{path}` does not exist!" unless File.exist?(path)
FileUtils.cp(path, "#{bundled_app}/vendor/cache")
end
end
def simulate_new_machine
system_gems []
FileUtils.rm_rf default_bundle_path
FileUtils.rm_rf bundled_app('.bundle')
end
def simulate_platform(platform)
old, ENV['BUNDLER_SPEC_PLATFORM'] = ENV['BUNDLER_SPEC_PLATFORM'], platform.to_s
yield if block_given?
ensure
ENV['BUNDLER_SPEC_PLATFORM'] = old if block_given?
end
def simulate_ruby_engine(engine, version = "1.6.0")
return if engine == local_ruby_engine
old, ENV['BUNDLER_SPEC_RUBY_ENGINE'] = ENV['BUNDLER_SPEC_RUBY_ENGINE'], engine
old_version, ENV['BUNDLER_SPEC_RUBY_ENGINE_VERSION'] = ENV['BUNDLER_SPEC_RUBY_ENGINE_VERSION'], version
yield if block_given?
ensure
ENV['BUNDLER_SPEC_RUBY_ENGINE'] = old if block_given?
ENV['BUNDLER_SPEC_RUBY_ENGINE_VERSION'] = old_version if block_given?
end
def simulate_bundler_version(version)
old, ENV['BUNDLER_SPEC_VERSION'] = ENV['BUNDLER_SPEC_VERSION'], version.to_s
yield if block_given?
ensure
ENV['BUNDLER_SPEC_VERSION'] = old if block_given?
end
def revision_for(path)
Dir.chdir(path) { `git rev-parse HEAD`.strip }
end
def capture_output
fake_stdout = StringIO.new
actual_stdout = $stdout
$stdout = fake_stdout
yield
fake_stdout.rewind
fake_stdout.read
ensure
$stdout = actual_stdout
end
def with_read_only(pattern)
chmod = lambda do |dirmode, filemode|
lambda do |f|
mode = File.directory?(f) ? dirmode : filemode
File.chmod(mode, f)
end
end
Dir[pattern].each(&chmod[0555, 0444])
yield
ensure
Dir[pattern].each(&chmod[0755, 0644])
end
end
end