Removed obsolete bin scripts.
[rbx.git] / test / rubygems / test_gem_dependency_installer.rb
blob914d4aa2160593d48b54dc112e5d07eccd4dd927
1 require 'test/unit'
2 require File.join(File.expand_path(File.dirname(__FILE__)), 'gemutilities')
3 require 'rubygems/dependency_installer'
5 class TestGemDependencyInstaller < RubyGemTestCase
7   def setup
8     super
10     @gems_dir = File.join @tempdir, 'gems'
11     @cache_dir = File.join @gemhome, 'cache'
12     FileUtils.mkdir @gems_dir
14     write_file File.join('gems', 'a-1', 'bin', 'a_bin') do |fp|
15       fp.puts "#!/usr/bin/ruby"
16     end
17     @a1, @a1_gem = util_gem 'a', '1' do |s| s.executables << 'a_bin' end
19     @b1, @b1_gem = util_gem 'b', '1' do |s| s.add_dependency 'a' end
21     @d1, @d1_gem = util_gem 'd', '1'
22     @d2, @d2_gem = util_gem 'd', '2'
24     @x1_m, @x1_m_gem = util_gem 'x', '1' do |s|
25       s.platform = Gem::Platform.new %w[cpu my_platform 1]
26     end
28     @x1_o, @x1_o_gem = util_gem 'x', '1' do |s|
29       s.platform = Gem::Platform.new %w[cpu other_platform 1]
30     end
32     @w1, @w1_gem = util_gem 'w', '1' do |s| s.add_dependency 'x' end
34     @y1, @y1_gem = util_gem 'y', '1'
35     @y1_1_p, @y1_1_p_gem = util_gem 'y', '1.1' do |s|
36       s.platform = Gem::Platform.new %w[cpu my_platform 1]
37     end
39     @z1, @z1_gem = util_gem 'z', '1'   do |s| s.add_dependency 'y' end
41     si = util_setup_source_info_cache @a1, @b1, @d1, @d2, @x1_m, @x1_o, @w1,
42                                       @y1, @y1_1_p, @z1
44     @fetcher = FakeFetcher.new
45     Gem::RemoteFetcher.instance_variable_set :@fetcher, @fetcher
46     @fetcher.uri = URI.parse 'http://gems.example.com'
47     @fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml
49     FileUtils.rm_rf File.join(@gemhome, 'gems')
50   end
52   def test_install
53     FileUtils.mv @a1_gem, @tempdir
54     inst = nil
56     Dir.chdir @tempdir do
57       inst = Gem::DependencyInstaller.new
58       inst.install 'a'
59     end
61     assert_equal Gem::SourceIndex.new(@a1.full_name => @a1),
62                  Gem::SourceIndex.from_installed_gems
64     assert_equal [@a1], inst.installed_gems
65   end
67   def test_install_dependency
68     FileUtils.mv @a1_gem, @tempdir
69     FileUtils.mv @b1_gem, @tempdir
70     inst = nil
72     Dir.chdir @tempdir do
73       inst = Gem::DependencyInstaller.new
74       inst.install 'b'
75     end
77     assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name }
78   end
80   def test_install_dependency_existing
81     Gem::Installer.new(@a1_gem).install
82     FileUtils.mv @a1_gem, @tempdir
83     FileUtils.mv @b1_gem, @tempdir
84     inst = nil
86     Dir.chdir @tempdir do
87       inst = Gem::DependencyInstaller.new
88       inst.install 'b'
89     end
91     assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name }
92   end
94   def test_install_dependency_old
95     e1, e1_gem = util_gem 'e', '1'
96     f1, f1_gem = util_gem 'f', '1' do |s| s.add_dependency 'e' end
97     f2, f2_gem = util_gem 'f', '2'
99     FileUtils.mv e1_gem, @tempdir
100     FileUtils.mv f1_gem, @tempdir
101     FileUtils.mv f2_gem, @tempdir
102     inst = nil
104     Dir.chdir @tempdir do
105       inst = Gem::DependencyInstaller.new
106       inst.install 'f'
107     end
109     assert_equal %w[f-2], inst.installed_gems.map { |s| s.full_name }
110   end
112   def test_install_local
113     FileUtils.mv @a1_gem, @tempdir
114     inst = nil
116     Dir.chdir @tempdir do
117       inst = Gem::DependencyInstaller.new :domain => :local
118       inst.install 'a-1.gem'
119     end
121     assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
122   end
124   def test_install_local_dependency
125     FileUtils.mv @a1_gem, @tempdir
126     FileUtils.mv @b1_gem, @tempdir
128     inst = nil
130     Dir.chdir @tempdir do
131       inst = Gem::DependencyInstaller.new :domain => :local
132       inst.install 'b-1.gem'
133     end
135     assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name }
136   end
138   def test_install_local_dependency_installed
139     FileUtils.mv @a1_gem, @tempdir
140     FileUtils.mv @b1_gem, @tempdir
142     inst = nil
144     Dir.chdir @tempdir do
145       Gem::Installer.new('a-1.gem').install
147       inst = Gem::DependencyInstaller.new :domain => :local
148       inst.install 'b-1.gem'
149     end
151     assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name }
152   end
154   def test_install_local_subdir
155     inst = nil
157     Dir.chdir @tempdir do
158       inst = Gem::DependencyInstaller.new :domain => :local
159       inst.install 'gems/a-1.gem'
160     end
162     assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
163   end
165   def test_install_env_shebang
166     FileUtils.mv @a1_gem, @tempdir
167     inst = nil
169     Dir.chdir @tempdir do
170       inst = Gem::DependencyInstaller.new :env_shebang => true, :wrappers => true
171       inst.install 'a'
172     end
174     assert_match %r|\A#!/usr/bin/env #{Gem::ConfigMap[:RUBY_INSTALL_NAME]}\n|,
175                  File.read(File.join(@gemhome, 'bin', 'a_bin'))
176   end
178   def test_install_force
179     FileUtils.mv @b1_gem, @tempdir
180     si = util_setup_source_info_cache @b1
181     @fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml
182     inst = nil
184     Dir.chdir @tempdir do
185       inst = Gem::DependencyInstaller.new :force => true
186       inst.install 'b'
187     end
189     assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name }
190   end
192   def test_install_ignore_dependencies
193     FileUtils.mv @b1_gem, @tempdir
194     inst = nil
196     Dir.chdir @tempdir do
197       inst = Gem::DependencyInstaller.new :ignore_dependencies => true
198       inst.install 'b'
199     end
201     assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name }
202   end
204   def test_install_install_dir
205     FileUtils.mv @a1_gem, @tempdir
206     gemhome2 = File.join @tempdir, 'gemhome2'
207     Dir.mkdir gemhome2
208     inst = nil
210     Dir.chdir @tempdir do
211       inst = Gem::DependencyInstaller.new :install_dir => gemhome2
212       inst.install 'a'
213     end
215     assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
217     assert File.exist?(File.join(gemhome2, 'specifications',
218                                  "#{@a1.full_name}.gemspec"))
219     assert File.exist?(File.join(gemhome2, 'cache',
220                                  "#{@a1.full_name}.gem"))
221   end
223   def test_install_domain_both
224     a1_data = nil
225     File.open @a1_gem, 'rb' do |fp|
226       a1_data = fp.read
227     end
229     @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data
231     FileUtils.mv @b1_gem, @tempdir
232     inst = nil
234     Dir.chdir @tempdir do
235       inst = Gem::DependencyInstaller.new :domain => :both
236       inst.install 'b'
237     end
239     assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name }
240     a1, b1 = inst.installed_gems
242     a1_expected = File.join(@gemhome, 'specifications',
243                             "#{a1.full_name}.gemspec")
244     b1_expected = File.join(@gemhome, 'specifications',
245                             "#{b1.full_name}.gemspec")
247     assert_equal a1_expected, a1.loaded_from
248     assert_equal b1_expected, b1.loaded_from
249   end
251   def test_install_domain_both_no_network
252     Gem::SourceInfoCache.instance_variable_set :@cache, nil
254     @fetcher.data["http://gems.example.com/gems/Marshal.#{@marshal_version}"] =
255       proc do
256         raise Gem::RemoteFetcher::FetchError
257       end
259     FileUtils.mv @a1_gem, @tempdir
260     FileUtils.mv @b1_gem, @tempdir
261     inst = nil
263     Dir.chdir @tempdir do
264       inst = Gem::DependencyInstaller.new :domain => :both
265       inst.install 'b'
266     end
268     assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name }
269   end
271   def test_install_domain_local
272     FileUtils.mv @b1_gem, @tempdir
273     inst = nil
275     Dir.chdir @tempdir do
276       e = assert_raise Gem::InstallError do
277         inst = Gem::DependencyInstaller.new :domain => :local
278         inst.install 'b'
279       end
280       assert_equal 'b requires a (>= 0)', e.message
281     end
283     assert_equal [], inst.installed_gems.map { |s| s.full_name }
284   end
286   def test_install_domain_remote
287     a1_data = nil
288     File.open @a1_gem, 'rb' do |fp|
289       a1_data = fp.read
290     end
292     @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data
294     inst = Gem::DependencyInstaller.new :domain => :remote
295     inst.install 'a'
297     assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
298   end
300   def test_install_remote
301     a1_data = nil
302     File.open @a1_gem, 'rb' do |fp|
303       a1_data = fp.read
304     end
306     @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data
308     inst = Gem::DependencyInstaller.new
310     Dir.chdir @tempdir do
311       inst.install 'a'
312     end
314     assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
315   end
317   def test_install_remote_dep
318     a1_data = nil
319     File.open @a1_gem, 'rb' do |fp|
320       a1_data = fp.read
321     end
323     @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data
325     inst = Gem::DependencyInstaller.new
327     Dir.chdir @tempdir do
328       dep = Gem::Dependency.new @a1.name, @a1.version
329       inst.install dep
330     end
332     assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
333   end
335   def test_install_domain_remote_platform_newer
336     a2_o, a2_o_gem = util_gem 'a', '2' do |s|
337       s.platform = Gem::Platform.new %w[cpu other_platform 1]
338     end
340     si = util_setup_source_info_cache @a1, a2_o
342     @fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml
344     a1_data = nil
345     a2_o_data = nil
347     File.open @a1_gem, 'rb' do |fp| a1_data = fp.read end
348     File.open a2_o_gem, 'rb' do |fp| a2_o_data = fp.read end
350     @fetcher.data["http://gems.example.com/gems/#{@a1.full_name}.gem"] =
351       a1_data
352     @fetcher.data["http://gems.example.com/gems/#{a2_o.full_name}.gem"] =
353       a2_o_data
355     inst = Gem::DependencyInstaller.new :domain => :remote
356     inst.install 'a'
358     assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
359   end
361   def test_install_reinstall
362     Gem::Installer.new(@a1_gem).install
363     FileUtils.mv @a1_gem, @tempdir
364     inst = nil
366     Dir.chdir @tempdir do
367       inst = Gem::DependencyInstaller.new
368       inst.install 'a'
369     end
371     assert_equal Gem::SourceIndex.new(@a1.full_name => @a1),
372                  Gem::SourceIndex.from_installed_gems
374     assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
375   end
377   if defined? OpenSSL then
378     def test_install_security_policy
379       data = File.open(@a1_gem, 'rb') { |f| f.read }
380       @fetcher.data['http://gems.example.com/gems/a-1.gem'] = data
382       data = File.open(@b1_gem, 'rb') { |f| f.read }
383       @fetcher.data['http://gems.example.com/gems/b-1.gem'] = data
385       policy = Gem::Security::HighSecurity
386       inst = Gem::DependencyInstaller.new :security_policy => policy
388       e = assert_raise Gem::Exception do
389         inst.install 'b'
390       end
392       assert_equal 'Unsigned gem', e.message
394       assert_equal %w[], inst.installed_gems.map { |s| s.full_name }
395     end
396   end
398   # Wrappers don't work on mswin
399   unless win_platform? then
400     def test_install_no_wrappers
401       @fetcher.data['http://gems.example.com/gems/a-1.gem'] = read_binary(@a1_gem)
403       inst = Gem::DependencyInstaller.new :wrappers => false
404       inst.install 'a'
406       assert_no_match(%r|This file was generated by RubyGems.|,
407                       File.read(File.join(@gemhome, 'bin', 'a_bin')))
408     end
409   end
411   def test_install_version
412     data = File.open(@d2_gem, 'rb') { |f| f.read }
413     @fetcher.data['http://gems.example.com/gems/d-2.gem'] = data
415     data = File.open(@d1_gem, 'rb') { |f| f.read }
416     @fetcher.data['http://gems.example.com/gems/d-1.gem'] = data
418     inst = Gem::DependencyInstaller.new
420     inst.install 'd', '= 1'
422     assert_equal %w[d-1], inst.installed_gems.map { |s| s.full_name }
423   end
425   def test_install_version_default
426     data = File.open(@d2_gem, 'rb') { |f| f.read }
427     @fetcher.data['http://gems.example.com/gems/d-2.gem'] = data
429     data = File.open(@d1_gem, 'rb') { |f| f.read }
430     @fetcher.data['http://gems.example.com/gems/d-1.gem'] = data
432     inst = Gem::DependencyInstaller.new
433     inst.install 'd'
435     assert_equal %w[d-2], inst.installed_gems.map { |s| s.full_name }
436   end
438   def test_find_gems_gems_with_sources
439     inst = Gem::DependencyInstaller.new
440     dep = Gem::Dependency.new 'b', '>= 0'
442     assert_equal [[@b1, 'http://gems.example.com']],
443                  inst.find_gems_with_sources(dep)
444   end
446   def test_find_gems_with_sources_local
447     FileUtils.mv @a1_gem, @tempdir
448     inst = Gem::DependencyInstaller.new
449     dep = Gem::Dependency.new 'a', '>= 0'
450     gems = nil
452     Dir.chdir @tempdir do
453       gems = inst.find_gems_with_sources dep
454     end
456     assert_equal 2, gems.length
457     remote = gems.first
458     assert_equal 'a-1', remote.first.full_name, 'remote spec'
459     assert_equal 'http://gems.example.com', remote.last, 'remote path'
461     local = gems.last
462     assert_equal 'a-1', local.first.full_name, 'local spec'
463     assert_equal File.join(@tempdir, "#{@a1.full_name}.gem"),
464                  local.last, 'local path'
465   end
467   def test_gather_dependencies
468     inst = Gem::DependencyInstaller.new
469     inst.find_spec_by_name_and_version 'b'
470     inst.gather_dependencies
472     assert_equal %w[a-1 b-1], inst.gems_to_install.map { |s| s.full_name }
473   end
475   def test_gather_dependencies_dropped
476     b2, = util_gem 'b', '2'
477     c1, = util_gem 'c', '1' do |s| s.add_dependency 'b' end
479     si = util_setup_source_info_cache @a1, @b1, b2, c1
481     @fetcher = FakeFetcher.new
482     Gem::RemoteFetcher.instance_variable_set :@fetcher, @fetcher
483     @fetcher.uri = URI.parse 'http://gems.example.com'
484     @fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml
486     inst = Gem::DependencyInstaller.new
487     inst.find_spec_by_name_and_version 'c'
488     inst.gather_dependencies
490     assert_equal %w[b-2 c-1], inst.gems_to_install.map { |s| s.full_name }
491   end
493   def test_gather_dependencies_platform_alternate
494     util_set_arch 'cpu-my_platform1'
496     inst = Gem::DependencyInstaller.new
497     inst.find_spec_by_name_and_version 'w'
498     inst.gather_dependencies
500     assert_equal %w[x-1-cpu-my_platform-1 w-1],
501                  inst.gems_to_install.map { |s| s.full_name }
502   end
504   def test_gather_dependencies_platform_bump
505     inst = Gem::DependencyInstaller.new
506     inst.find_spec_by_name_and_version 'z'
507     inst.gather_dependencies
509     assert_equal %w[y-1 z-1], inst.gems_to_install.map { |s| s.full_name }
510   end
512   def test_gather_dependencies_old_required
513     e1, = util_gem 'e', '1' do |s| s.add_dependency 'd', '= 1' end
515     si = util_setup_source_info_cache @d1, @d2, e1
517     @fetcher = FakeFetcher.new
518     Gem::RemoteFetcher.instance_variable_set :@fetcher, @fetcher
519     @fetcher.uri = URI.parse 'http://gems.example.com'
520     @fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml
522     inst = Gem::DependencyInstaller.new
523     inst.find_spec_by_name_and_version 'e'
524     inst.gather_dependencies
526     assert_equal %w[d-1 e-1], inst.gems_to_install.map { |s| s.full_name }
527   end