2 # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
4 # See LICENSE.txt for permissions.
7 require File.join(File.expand_path(File.dirname(__FILE__)),
8 'gem_installer_test_case')
10 class TestGemInstaller < GemInstallerTestCase
12 def test_app_script_text
13 util_make_exec '2', ''
18 # This file was generated by RubyGems.
20 # The application 'a' is installed as part of a gem, and
21 # this file is here to facilitate running it.
28 if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
37 wrapper = @installer.app_script_text 'my_exec'
38 assert_equal expected, wrapper
41 def test_build_extensions_none
43 @installer.build_extensions
46 assert_equal '', @ui.output
47 assert_equal '', @ui.error
49 assert !File.exist?('gem_make.out')
52 def test_build_extensions_extconf_bad
53 @spec.extensions << 'extconf.rb'
55 e = assert_raise Gem::Installer::ExtensionBuildError do
57 @installer.build_extensions
61 assert_match(/\AERROR: Failed to build gem native extension.$/, e.message)
63 assert_equal "Building native extensions. This could take a while...\n",
65 assert_equal '', @ui.error
67 gem_make_out = File.join @gemhome, 'gems', @spec.full_name, 'gem_make.out'
69 #{Gem.ruby} extconf.rb
70 #{Gem.ruby}: No such file or directory -- extconf.rb (LoadError)
73 assert_equal expected, File.read(gem_make_out)
76 def test_build_extensions_unsupported
77 @spec.extensions << nil
79 e = assert_raise Gem::Installer::ExtensionBuildError do
81 @installer.build_extensions
85 assert_match(/^No builder for extension ''$/, e.message)
87 assert_equal "Building native extensions. This could take a while...\n",
89 assert_equal '', @ui.error
91 assert_equal "No builder for extension ''\n", File.read('gem_make.out')
93 FileUtils.rm_f 'gem_make.out'
96 def test_ensure_dependency
97 dep = Gem::Dependency.new 'a', '>= 2'
98 assert @installer.ensure_dependency(@spec, dep)
100 dep = Gem::Dependency.new 'b', '> 2'
101 e = assert_raise Gem::InstallError do
102 @installer.ensure_dependency @spec, dep
105 assert_equal 'a requires b (> 2, runtime)', e.message
108 def test_expand_and_validate_gem_dir
109 @installer.gem_dir = '/nonexistent'
110 expanded_gem_dir = @installer.send(:expand_and_validate_gem_dir)
112 expected = File.expand_path('/nonexistent').downcase
113 expanded_gem_dir = expanded_gem_dir.downcase
115 expected = '/nonexistent'
118 assert_equal expected, expanded_gem_dir
121 def test_extract_files
123 def format.file_entries
124 [[{'size' => 7, 'mode' => 0400, 'path' => 'thefile'}, 'thefile']]
127 @installer.format = format
129 @installer.extract_files
131 thefile_path = File.join(util_gem_dir, 'thefile')
132 assert_equal 'thefile', File.read(thefile_path)
134 unless Gem.win_platform? then
135 assert_equal 0400, File.stat(thefile_path).mode & 0777
139 def test_extract_files_bad_dest
140 @installer.gem_dir = 'somedir'
141 @installer.format = nil
142 e = assert_raise ArgumentError do
143 @installer.extract_files
146 assert_equal 'format required to extract from', e.message
149 def test_extract_files_relative
151 def format.file_entries
152 [[{'size' => 10, 'mode' => 0644, 'path' => '../thefile'}, '../thefile']]
155 @installer.format = format
157 e = assert_raise Gem::InstallError do
158 @installer.extract_files
161 assert_equal "attempt to install file into \"../thefile\" under #{util_gem_dir.inspect}",
163 assert_equal false, File.file?(File.join(@tempdir, '../thefile')),
164 "You may need to remove this file if you broke the test once"
167 def test_extract_files_absolute
169 def format.file_entries
170 [[{'size' => 8, 'mode' => 0644, 'path' => '/thefile'}, '/thefile']]
173 @installer.format = format
175 e = assert_raise Gem::InstallError do
176 @installer.extract_files
179 assert_equal 'attempt to install file into "/thefile"', e.message
180 assert_equal false, File.file?(File.join('/thefile')),
181 "You may need to remove this file if you broke the test once"
184 def test_generate_bin_bindir
185 @installer.wrappers = true
187 @spec.executables = ["my_exec"]
190 exec_file = @installer.formatted_program_filename "my_exec"
191 exec_path = File.join util_gem_dir(@spec.version), exec_file
192 File.open exec_path, 'w' do |f|
193 f.puts '#!/usr/bin/ruby'
196 @installer.gem_dir = util_gem_dir
198 @installer.generate_bin
200 assert_equal true, File.directory?(util_inst_bindir)
201 installed_exec = File.join(util_inst_bindir, "my_exec")
202 assert_equal true, File.exist?(installed_exec)
203 assert_equal(0100755, File.stat(installed_exec).mode) unless win_platform?
205 wrapper = File.read installed_exec
206 assert_match %r|generated by RubyGems|, wrapper
209 def test_generate_bin_script
210 @installer.wrappers = true
212 @installer.gem_dir = util_gem_dir
214 @installer.generate_bin
215 assert_equal true, File.directory?(util_inst_bindir)
216 installed_exec = File.join(util_inst_bindir, "my_exec")
217 assert_equal true, File.exist?(installed_exec)
218 assert_equal(0100755, File.stat(installed_exec).mode) unless win_platform?
220 wrapper = File.read installed_exec
221 assert_match %r|generated by RubyGems|, wrapper
224 def test_generate_bin_script_format
225 @installer.format_executable = true
226 @installer.wrappers = true
228 @installer.gem_dir = util_gem_dir
230 Gem::Installer.exec_format = 'foo-%s-bar'
231 @installer.generate_bin
232 assert_equal true, File.directory?(util_inst_bindir)
233 installed_exec = File.join util_inst_bindir, 'foo-my_exec-bar'
234 assert_equal true, File.exist?(installed_exec)
236 Gem::Installer.exec_format = nil
239 def test_generate_bin_script_format_disabled
240 @installer.wrappers = true
242 @installer.gem_dir = util_gem_dir
244 Gem::Installer.exec_format = 'foo-%s-bar'
245 @installer.generate_bin
246 assert_equal true, File.directory?(util_inst_bindir)
247 installed_exec = File.join util_inst_bindir, 'my_exec'
248 assert_equal true, File.exist?(installed_exec)
250 Gem::Installer.exec_format = nil
253 def test_generate_bin_script_install_dir
254 @installer.wrappers = true
255 @spec.executables = ["my_exec"]
257 gem_dir = File.join "#{@gemhome}2", 'gems', @spec.full_name
258 gem_bindir = File.join gem_dir, 'bin'
259 FileUtils.mkdir_p gem_bindir
260 File.open File.join(gem_bindir, "my_exec"), 'w' do |f|
264 @installer.gem_home = "#{@gemhome}2"
265 @installer.gem_dir = gem_dir
267 @installer.generate_bin
269 installed_exec = File.join("#{@gemhome}2", 'bin', 'my_exec')
270 assert_equal true, File.exist?(installed_exec)
271 assert_equal(0100755, File.stat(installed_exec).mode) unless win_platform?
273 wrapper = File.read installed_exec
274 assert_match %r|generated by RubyGems|, wrapper
277 def test_generate_bin_script_no_execs
278 @installer.wrappers = true
279 @installer.generate_bin
280 assert_equal false, File.exist?(util_inst_bindir)
283 def test_generate_bin_script_no_perms
284 @installer.wrappers = true
287 Dir.mkdir util_inst_bindir
288 File.chmod 0000, util_inst_bindir
290 assert_raises Gem::FilePermissionError do
291 @installer.generate_bin
295 File.chmod 0700, util_inst_bindir unless $DEBUG
298 def test_generate_bin_script_no_shebang
299 @installer.wrappers = true
300 @spec.executables = ["my_exec"]
302 gem_dir = File.join @gemhome, 'gems', @spec.full_name
303 gem_bindir = File.join gem_dir, 'bin'
304 FileUtils.mkdir_p gem_bindir
305 File.open File.join(gem_bindir, "my_exec"), 'w' do |f|
306 f.puts "blah blah blah"
309 @installer.generate_bin
311 installed_exec = File.join @gemhome, 'bin', 'my_exec'
312 assert_equal true, File.exist?(installed_exec)
313 assert_equal 0100755, File.stat(installed_exec).mode unless win_platform?
315 wrapper = File.read installed_exec
316 assert_match %r|generated by RubyGems|, wrapper
317 # HACK some gems don't have #! in their executables, restore 2008/06
318 #assert_no_match %r|generated by RubyGems|, wrapper
321 def test_generate_bin_script_wrappers
322 @installer.wrappers = true
324 @installer.gem_dir = util_gem_dir
325 installed_exec = File.join(util_inst_bindir, "my_exec")
327 real_exec = File.join util_gem_dir, 'bin', 'my_exec'
329 # fake --no-wrappers for previous install
330 FileUtils.mkdir_p File.dirname(installed_exec)
331 FileUtils.ln_s real_exec, installed_exec
333 @installer.generate_bin
334 assert_equal true, File.directory?(util_inst_bindir)
335 assert_equal true, File.exist?(installed_exec)
336 assert_equal(0100755, File.stat(installed_exec).mode) unless win_platform?
338 assert_match %r|generated by RubyGems|, File.read(installed_exec)
340 assert_no_match %r|generated by RubyGems|, File.read(real_exec),
341 'real executable overwritten'
344 def test_generate_bin_symlink
345 return if win_platform? #Windows FS do not support symlinks
347 @installer.wrappers = false
349 @installer.gem_dir = util_gem_dir
351 @installer.generate_bin
352 assert_equal true, File.directory?(util_inst_bindir)
353 installed_exec = File.join(util_inst_bindir, "my_exec")
354 assert_equal true, File.symlink?(installed_exec)
355 assert_equal(File.join(util_gem_dir, "bin", "my_exec"),
356 File.readlink(installed_exec))
359 def test_generate_bin_symlink_no_execs
360 @installer.wrappers = false
361 @installer.generate_bin
362 assert_equal false, File.exist?(util_inst_bindir)
365 def test_generate_bin_symlink_no_perms
366 @installer.wrappers = false
368 @installer.gem_dir = util_gem_dir
370 Dir.mkdir util_inst_bindir
371 File.chmod 0000, util_inst_bindir
373 assert_raises Gem::FilePermissionError do
374 @installer.generate_bin
378 File.chmod 0700, util_inst_bindir unless $DEBUG
381 def test_generate_bin_symlink_update_newer
382 return if win_platform? #Windows FS do not support symlinks
384 @installer.wrappers = false
386 @installer.gem_dir = util_gem_dir
388 @installer.generate_bin
389 installed_exec = File.join(util_inst_bindir, "my_exec")
390 assert_equal(File.join(util_gem_dir, "bin", "my_exec"),
391 File.readlink(installed_exec))
393 @spec = Gem::Specification.new do |s|
394 s.files = ['lib/code.rb']
397 s.summary = "summary"
398 s.description = "desc"
399 s.require_path = 'lib'
403 @installer.gem_dir = File.join util_gem_dir('3')
404 @installer.generate_bin
405 installed_exec = File.join(util_inst_bindir, "my_exec")
406 assert_equal(File.join(util_gem_bindir('3'), "my_exec"),
407 File.readlink(installed_exec),
408 "Ensure symlink moved to latest version")
411 def test_generate_bin_symlink_update_older
412 return if win_platform? #Windows FS do not support symlinks
414 @installer.wrappers = false
416 @installer.gem_dir = util_gem_dir
418 @installer.generate_bin
419 installed_exec = File.join(util_inst_bindir, "my_exec")
420 assert_equal(File.join(util_gem_dir, "bin", "my_exec"),
421 File.readlink(installed_exec))
423 spec = Gem::Specification.new do |s|
424 s.files = ['lib/code.rb']
427 s.summary = "summary"
428 s.description = "desc"
429 s.require_path = 'lib'
433 @installer.gem_dir = util_gem_dir('1')
434 @installer.spec = spec
436 @installer.generate_bin
438 installed_exec = File.join(util_inst_bindir, "my_exec")
439 assert_equal(File.join(util_gem_dir('2'), "bin", "my_exec"),
440 File.readlink(installed_exec),
441 "Ensure symlink not moved")
444 def test_generate_bin_symlink_update_remove_wrapper
445 return if win_platform? #Windows FS do not support symlinks
447 @installer.wrappers = true
449 @installer.gem_dir = util_gem_dir
451 @installer.generate_bin
452 installed_exec = File.join(util_inst_bindir, "my_exec")
453 assert_equal true, File.exist?(installed_exec)
455 @spec = Gem::Specification.new do |s|
456 s.files = ['lib/code.rb']
459 s.summary = "summary"
460 s.description = "desc"
461 s.require_path = 'lib'
464 @installer.wrappers = false
466 @installer.gem_dir = util_gem_dir '3'
467 @installer.generate_bin
468 installed_exec = File.join(util_inst_bindir, "my_exec")
469 assert_equal(File.join(util_gem_dir('3'), "bin", "my_exec"),
470 File.readlink(installed_exec),
471 "Ensure symlink moved to latest version")
474 def test_generate_bin_symlink_win32
475 old_win_platform = Gem.win_platform?
476 Gem.win_platform = true
477 @installer.wrappers = false
479 @installer.gem_dir = util_gem_dir
482 @installer.generate_bin
485 assert_equal true, File.directory?(util_inst_bindir)
486 installed_exec = File.join(util_inst_bindir, "my_exec")
487 assert_equal true, File.exist?(installed_exec)
489 assert_match(/Unable to use symlinks on Windows, installing wrapper/i,
492 wrapper = File.read installed_exec
493 assert_match(/generated by RubyGems/, wrapper)
495 Gem.win_platform = old_win_platform
498 def test_generate_bin_uses_default_shebang
499 return if win_platform? #Windows FS do not support symlinks
501 @installer.wrappers = true
504 @installer.generate_bin
506 default_shebang = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
507 shebang_line = open("#{@gemhome}/bin/my_exec") { |f| f.readlines.first }
508 assert_match(/\A#!/, shebang_line)
509 assert_match(/#{default_shebang}/, shebang_line)
513 spec = quick_gem 'a' do |s| s.platform = Gem::Platform.new 'mswin32' end
514 gem = File.join @tempdir, "#{spec.full_name}.gem"
517 FileUtils.mv File.join(@gemhome, 'cache', "#{spec.full_name}.gem"),
520 installer = Gem::Installer.new gem
522 assert_equal File.join(@gemhome, 'gems', spec.full_name), installer.gem_dir
529 assert_equal @spec, @installer.install
532 gemdir = File.join @gemhome, 'gems', @spec.full_name
533 assert File.exist?(gemdir)
535 exe = File.join(gemdir, 'bin', 'executable')
536 assert File.exist?(exe)
537 exe_mode = File.stat(exe).mode & 0111
538 assert_equal 0111, exe_mode, "0%o" % exe_mode unless win_platform?
540 assert File.exist?(File.join(gemdir, 'lib', 'code.rb'))
542 assert File.exist?(File.join(gemdir, 'ext', 'a', 'Rakefile'))
544 spec_file = File.join(@gemhome, 'specifications',
545 "#{@spec.full_name}.gemspec")
547 assert_equal spec_file, @spec.loaded_from
548 assert File.exist?(spec_file)
551 def test_install_bad_gem
555 Dir.chdir @tempdir do Gem::Builder.new(@spec).build end
556 gem = File.join @tempdir, "#{@spec.full_name}.gem"
559 gem_data = File.open gem, 'rb' do |fp| fp.read 1024 end
560 File.open gem, 'wb' do |fp| fp.write gem_data end
562 e = assert_raise Gem::InstallError do
564 @installer = Gem::Installer.new gem
569 assert_equal "invalid gem format for #{gem}", e.message
572 def test_install_check_dependencies
573 @spec.add_dependency 'b', '> 5'
577 assert_raise Gem::InstallError do
583 def test_install_force
585 installer = Gem::Installer.new old_ruby_required, :force => true
589 gem_dir = File.join(@gemhome, 'gems', 'old_ruby_required-1')
590 assert File.exist?(gem_dir)
593 def test_install_ignore_dependencies
594 @spec.add_dependency 'b', '> 5'
596 @installer.ignore_dependencies = true
599 assert_equal @spec, @installer.install
602 gemdir = File.join @gemhome, 'gems', @spec.full_name
603 assert File.exist?(gemdir)
605 exe = File.join(gemdir, 'bin', 'executable')
606 assert File.exist?(exe)
607 exe_mode = File.stat(exe).mode & 0111
608 assert_equal 0111, exe_mode, "0%o" % exe_mode unless win_platform?
609 assert File.exist?(File.join(gemdir, 'lib', 'code.rb'))
611 assert File.exist?(File.join(@gemhome, 'specifications',
612 "#{@spec.full_name}.gemspec"))
615 def test_install_missing_dirs
616 FileUtils.rm_f File.join(Gem.dir, 'cache')
617 FileUtils.rm_f File.join(Gem.dir, 'docs')
618 FileUtils.rm_f File.join(Gem.dir, 'specifications')
621 Dir.chdir @tempdir do Gem::Builder.new(@spec).build end
622 gem = File.join @tempdir, "#{@spec.full_name}.gem"
627 File.directory? File.join(Gem.dir, 'cache')
628 File.directory? File.join(Gem.dir, 'docs')
629 File.directory? File.join(Gem.dir, 'specifications')
631 assert File.exist?(File.join(@gemhome, 'cache', "#{@spec.full_name}.gem"))
632 assert File.exist?(File.join(@gemhome, 'specifications',
633 "#{@spec.full_name}.gemspec"))
636 def test_install_with_message
637 @spec.post_install_message = 'I am a shiny gem!'
640 Dir.chdir @tempdir do Gem::Builder.new(@spec).build end
645 assert_match %r|I am a shiny gem!|, @ui.output
648 def test_install_writable
651 orig_mode = File.stat(Gem.dir).mode
652 File.chmod 0000, Gem.dir
654 e = assert_raise Gem::FilePermissionError do
658 assert_equal "You don't have write permissions into the #{@gemhome} directory.",
661 File.chmod orig_mode, Gem.dir
664 def test_install_wrong_ruby_version
666 installer = Gem::Installer.new old_ruby_required
667 e = assert_raise Gem::InstallError do
670 assert_equal 'old_ruby_required requires Ruby version = 1.4.6',
675 def test_install_wrong_rubygems_version
676 spec = quick_gem 'old_rubygems_required', '1' do |s|
677 s.required_rubygems_version = '< 0'
682 gem = File.join @gemhome, 'cache', "#{spec.full_name}.gem"
685 @installer = Gem::Installer.new gem
686 e = assert_raise Gem::InstallError do
689 assert_equal 'old_rubygems_required requires RubyGems version < 0',
694 def test_installation_satisfies_dependency_eh
695 dep = Gem::Dependency.new 'a', '>= 2'
696 assert @installer.installation_satisfies_dependency?(dep)
698 dep = Gem::Dependency.new 'a', '> 2'
699 assert ! @installer.installation_satisfies_dependency?(dep)
703 util_make_exec '2', "#!/usr/bin/ruby"
705 shebang = @installer.shebang 'my_exec'
707 assert_equal "#!#{Gem.ruby}", shebang
710 def test_shebang_arguments
711 util_make_exec '2', "#!/usr/bin/ruby -ws"
713 shebang = @installer.shebang 'my_exec'
715 assert_equal "#!#{Gem.ruby} -ws", shebang
718 def test_shebang_empty
719 util_make_exec '2', ''
721 shebang = @installer.shebang 'my_exec'
722 assert_equal "#!#{Gem.ruby}", shebang
726 util_make_exec '2', "#!/usr/bin/env ruby"
728 shebang = @installer.shebang 'my_exec'
730 assert_equal "#!#{Gem.ruby}", shebang
733 def test_shebang_env_arguments
734 util_make_exec '2', "#!/usr/bin/env ruby -ws"
736 shebang = @installer.shebang 'my_exec'
738 assert_equal "#!#{Gem.ruby} -ws", shebang
741 def test_shebang_env_shebang
742 util_make_exec '2', ''
743 @installer.env_shebang = true
745 shebang = @installer.shebang 'my_exec'
746 assert_equal "#!/usr/bin/env #{Gem::ConfigMap[:RUBY_INSTALL_NAME]}", shebang
749 def test_shebang_nested
750 util_make_exec '2', "#!/opt/local/ruby/bin/ruby"
752 shebang = @installer.shebang 'my_exec'
754 assert_equal "#!#{Gem.ruby}", shebang
757 def test_shebang_nested_arguments
758 util_make_exec '2', "#!/opt/local/ruby/bin/ruby -ws"
760 shebang = @installer.shebang 'my_exec'
762 assert_equal "#!#{Gem.ruby} -ws", shebang
765 def test_shebang_version
766 util_make_exec '2', "#!/usr/bin/ruby18"
768 shebang = @installer.shebang 'my_exec'
770 assert_equal "#!#{Gem.ruby}", shebang
773 def test_shebang_version_arguments
774 util_make_exec '2', "#!/usr/bin/ruby18 -ws"
776 shebang = @installer.shebang 'my_exec'
778 assert_equal "#!#{Gem.ruby} -ws", shebang
781 def test_shebang_version_env
782 util_make_exec '2', "#!/usr/bin/env ruby18"
784 shebang = @installer.shebang 'my_exec'
786 assert_equal "#!#{Gem.ruby}", shebang
789 def test_shebang_version_env_arguments
790 util_make_exec '2', "#!/usr/bin/env ruby18 -ws"
792 shebang = @installer.shebang 'my_exec'
794 assert_equal "#!#{Gem.ruby} -ws", shebang
800 dest = File.join @gemhome, 'gems', @spec.full_name
802 @installer.unpack dest
804 assert File.exist?(File.join(dest, 'lib', 'code.rb'))
805 assert File.exist?(File.join(dest, 'bin', 'executable'))
809 spec_dir = File.join @gemhome, 'specifications'
810 spec_file = File.join spec_dir, "#{@spec.full_name}.gemspec"
811 FileUtils.rm spec_file
812 assert !File.exist?(spec_file)
814 @installer.spec = @spec
815 @installer.gem_home = @gemhome
817 @installer.write_spec
819 assert File.exist?(spec_file)
820 assert_equal @spec, eval(File.read(spec_file))
823 def old_ruby_required
824 spec = quick_gem 'old_ruby_required', '1' do |s|
825 s.required_ruby_version = '= 1.4.6'
830 File.join @gemhome, 'cache', "#{spec.full_name}.gem"