3 # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
5 # See LICENSE.txt for permissions.
15 require 'rubygems/source_info_cache'
16 require 'rubygems/package'
18 require File.join(File.expand_path(File.dirname(__FILE__)), 'mockgemui')
21 def self.source_index=(si)
25 def self.win_platform=(val)
45 raise ArgumentError, 'need full URI' unless path =~ %r'^http://'
47 raise Gem::RemoteFetcher::FetchError, "no data for #{path}" if data.nil?
48 data.respond_to?(:call) ? data.call : data
54 raise ArgumentError, 'need full URI' unless path =~ %r'^http://'
56 raise Gem::RemoteFetcher::FetchError, "no data for #{path}" if data.nil?
57 data.respond_to?(:call) ? data.call : data.length
60 def download spec, source_uri, install_dir = Gem.dir
61 name = "#{spec.full_name}.gem"
62 path = File.join(install_dir, 'cache', name)
64 Gem.ensure_gem_subdirectories install_dir
66 if source_uri =~ /^http/ then
67 File.open(path, "wb") do |f|
68 f.write fetch_path(File.join(source_uri, "gems", name))
71 FileUtils.cp source_uri, path
78 class RubyGemTestCase < Test::Unit::TestCase
80 include Gem::DefaultUserInteraction
82 undef_method :default_test if instance_methods.include? 'default_test' or
83 instance_methods.include? :default_test
90 Dir.chdir Dir.tmpdir do tmpdir = Dir.pwd end # HACK OSX /private/tmp
91 @tempdir = File.join tmpdir, "test_rubygems_#{$$}"
93 @gemhome = File.join @tempdir, "gemhome"
94 @gemcache = File.join(@gemhome, "source_cache")
95 @usrcache = File.join(@gemhome, ".gem", "user_cache")
96 @latest_usrcache = File.join(@gemhome, ".gem", "latest_user_cache")
98 FileUtils.mkdir_p @gemhome
100 ENV['GEMCACHE'] = @usrcache
101 Gem.use_paths(@gemhome)
102 Gem.loaded_specs.clear
104 Gem.configuration.verbose = true
105 Gem.configuration.update_sources = true
107 @gem_repo = "http://gems.example.com"
108 Gem.sources.replace [@gem_repo]
110 @orig_BASERUBY = Gem::ConfigMap[:BASERUBY]
111 Gem::ConfigMap[:BASERUBY] = Gem::ConfigMap[:RUBY_INSTALL_NAME]
113 @orig_arch = Gem::ConfigMap[:arch]
116 util_set_arch 'i386-mswin32'
118 util_set_arch 'i686-darwin8.10.1'
121 @marshal_version = "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}"
123 @private_key = File.expand_path File.join(File.dirname(__FILE__),
125 @public_cert = File.expand_path File.join(File.dirname(__FILE__),
130 Gem::ConfigMap[:BASERUBY] = @orig_BASERUBY
131 Gem::ConfigMap[:arch] = @orig_arch
133 if defined? Gem::RemoteFetcher then
134 Gem::RemoteFetcher.instance_variable_set :@fetcher, nil
137 FileUtils.rm_rf @tempdir
139 ENV.delete 'GEMCACHE'
140 ENV.delete 'GEM_HOME'
141 ENV.delete 'GEM_PATH'
144 Gem::SourceInfoCache.instance_variable_set :@cache, nil
148 require 'rubygems/installer'
150 use_ui MockGemUi.new do
151 Dir.chdir @tempdir do
152 Gem::Builder.new(gem).build
156 gem = File.join(@tempdir, "#{gem.full_name}.gem").untaint
157 Gem::Installer.new(gem).install
160 def prep_cache_files(lc)
161 @usr_si ||= Gem::SourceIndex.new
162 @usr_sice ||= Gem::SourceInfoCacheEntry.new @usr_si, 0
164 @sys_si ||= Gem::SourceIndex.new
165 @sys_sice ||= Gem::SourceInfoCacheEntry.new @sys_si, 0
167 latest_si = Gem::SourceIndex.new
168 latest_si.add_specs(*@sys_si.latest_specs)
169 latest_sys_sice = Gem::SourceInfoCacheEntry.new latest_si, 0
171 latest_si = Gem::SourceIndex.new
172 latest_si.add_specs(*@usr_si.latest_specs)
173 latest_usr_sice = Gem::SourceInfoCacheEntry.new latest_si, 0
175 [ [lc.system_cache_file, @sys_sice],
176 [lc.latest_system_cache_file, latest_sys_sice],
177 [lc.user_cache_file, @usr_sice],
178 [lc.latest_user_cache_file, latest_usr_sice],
179 ].each do |filename, data|
180 FileUtils.mkdir_p File.dirname(filename).untaint
182 open filename.dup.untaint, 'wb' do |f|
183 f.write Marshal.dump({ @gem_repo => data })
189 open path.dup.untaint, 'rb' do |io|
194 def read_binary(path)
199 path = File.join(@gemhome, path)
200 dir = File.dirname path
201 FileUtils.mkdir_p dir
203 open path, 'wb' do |io|
210 def quick_gem(gemname, version='2')
211 require 'rubygems/specification'
213 spec = Gem::Specification.new do |s|
214 s.platform = Gem::Platform::RUBY
218 s.email = 'example@example.com'
219 s.homepage = 'http://example.com'
221 s.summary = "this is a summary"
222 s.description = "This is a test description"
224 yield(s) if block_given?
227 path = File.join "specifications", "#{spec.full_name}.gemspec"
228 written_path = write_file path do |io|
229 io.write(spec.to_ruby)
232 spec.loaded_from = written_path
237 def util_build_gem(spec)
238 dir = File.join(@gemhome, 'gems', spec.full_name)
239 FileUtils.mkdir_p dir
242 spec.files.each do |file|
243 next if File.exist? file
244 FileUtils.mkdir_p File.dirname(file)
245 File.open file, 'w' do |fp| fp.puts "# #{file}" end
248 use_ui MockGemUi.new do
249 Gem::Builder.new(spec).build
252 FileUtils.mv "#{spec.full_name}.gem",
253 File.join(@gemhome, 'cache', "#{spec.original_name}.gem")
257 def util_gem(name, version, &block)
258 spec = quick_gem(name, version, &block)
262 cache_file = File.join @tempdir, 'gems', "#{spec.original_name}.gem"
263 FileUtils.mv File.join(@gemhome, 'cache', "#{spec.original_name}.gem"),
265 FileUtils.rm File.join(@gemhome, 'specifications',
266 "#{spec.full_name}.gemspec")
268 spec.loaded_from = nil
276 s.files = %w[lib/code.rb]
277 s.require_paths = %w[lib]
280 @a1 = quick_gem('a', '1', &init)
281 @a2 = quick_gem('a', '2', &init)
282 @a_evil9 = quick_gem('a_evil', '9', &init)
283 @b2 = quick_gem('b', '2', &init)
284 @c1_2 = quick_gem('c', '1.2', &init)
285 @pl1 = quick_gem 'pl', '1' do |s| # l for legacy
286 s.files = %w[lib/code.rb]
287 s.require_paths = %w[lib]
288 s.platform = Gem::Platform.new 'i386-linux'
289 s.instance_variable_set :@original_platform, 'i386-linux'
292 write_file File.join(*%W[gems #{@a1.original_name} lib code.rb]) do end
293 write_file File.join(*%W[gems #{@a2.original_name} lib code.rb]) do end
294 write_file File.join(*%W[gems #{@b2.original_name} lib code.rb]) do end
295 write_file File.join(*%W[gems #{@c1_2.original_name} lib code.rb]) do end
296 write_file File.join(*%W[gems #{@pl1.original_name} lib code.rb]) do end
298 [@a1, @a2, @a_evil9, @b2, @c1_2, @pl1].each { |spec| util_build_gem spec }
300 FileUtils.rm_r File.join(@gemhome, 'gems', @pl1.original_name)
302 Gem.source_index = nil
306 # Set the platform to +cpu+ and +os+
308 def util_set_arch(arch)
309 Gem::ConfigMap[:arch] = arch
310 platform = Gem::Platform.new arch
312 Gem.instance_variable_set :@platforms, nil
313 Gem::Platform.instance_variable_set :@local, nil
318 def util_setup_fake_fetcher
321 require 'rubygems/remote_fetcher'
323 @uri = URI.parse @gem_repo
324 @fetcher = FakeFetcher.new
329 @all_gems = [@a1, @a2, @a_evil9, @b2, @c1_2].sort
330 @all_gem_names = @all_gems.map { |gem| gem.full_name }
332 gem_names = [@a1.full_name, @a2.full_name, @b2.full_name]
333 @gem_names = gem_names.sort.join("\n")
335 @source_index = Gem::SourceIndex.new
336 @source_index.add_spec @a1
337 @source_index.add_spec @a2
338 @source_index.add_spec @a_evil9
339 @source_index.add_spec @c1_2
341 Gem::RemoteFetcher.instance_variable_set :@fetcher, @fetcher
344 def util_setup_source_info_cache(*specs)
345 require 'rubygems/source_info_cache_entry'
347 specs = Hash[*specs.map { |spec| [spec.full_name, spec] }.flatten]
348 si = Gem::SourceIndex.new specs
350 sice = Gem::SourceInfoCacheEntry.new si, 0
351 sic = Gem::SourceInfoCache.new
353 sic.set_cache_data( { @gem_repo => sice } )
358 Gem::SourceInfoCache.instance_variable_set :@cache, sic
363 Zlib::Deflate.deflate data
366 def self.win_platform?
374 # NOTE Allow tests to use a random (but controlled) port number instead of
375 # a hardcoded one. This helps CI tools when running parallels builds on
376 # the same builder slave.
377 def self.process_based_port
378 @@process_based_port ||= 8000 + $$ % 1000
381 def process_based_port
382 self.class.process_based_port
391 def initialize(string = '')
392 @tempfile = Tempfile.new "TempIO-#{@@count ++ 1}"
394 @tempfile.write string
398 def method_missing(meth, *args, &block)
399 @tempfile.send(meth, *args, &block)
402 def respond_to?(meth)
403 @tempfile.respond_to? meth
409 Gem.read_binary @tempfile.path