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)', 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 assert_equal 'thefile', File.read(File.join(util_gem_dir, 'thefile'))
134 def test_extract_files_bad_dest
135 @installer.gem_dir = 'somedir'
136 @installer.format = nil
137 e = assert_raise ArgumentError do
138 @installer.extract_files
141 assert_equal 'format required to extract from', e.message
144 def test_extract_files_relative
146 def format.file_entries
147 [[{'size' => 10, 'mode' => 0644, 'path' => '../thefile'}, '../thefile']]
150 @installer.format = format
152 e = assert_raise Gem::InstallError do
153 @installer.extract_files
156 assert_equal "attempt to install file into \"../thefile\" under #{util_gem_dir.inspect}",
158 assert_equal false, File.file?(File.join(@tempdir, '../thefile')),
159 "You may need to remove this file if you broke the test once"
162 def test_extract_files_absolute
164 def format.file_entries
165 [[{'size' => 8, 'mode' => 0644, 'path' => '/thefile'}, '/thefile']]
168 @installer.format = format
170 e = assert_raise Gem::InstallError do
171 @installer.extract_files
174 assert_equal 'attempt to install file into "/thefile"', e.message
175 assert_equal false, File.file?(File.join('/thefile')),
176 "You may need to remove this file if you broke the test once"
179 def test_generate_bin_bindir
180 @installer.wrappers = true
182 @spec.executables = ["my_exec"]
185 exec_file = @installer.formatted_program_filename "my_exec"
186 exec_path = File.join util_gem_dir(@spec.version), exec_file
187 File.open exec_path, 'w' do |f|
188 f.puts '#!/usr/bin/ruby'
191 @installer.gem_dir = util_gem_dir
193 @installer.generate_bin
195 assert_equal true, File.directory?(util_inst_bindir)
196 installed_exec = File.join(util_inst_bindir, "my_exec")
197 assert_equal true, File.exist?(installed_exec)
198 assert_equal(0100755, File.stat(installed_exec).mode) unless win_platform?
200 wrapper = File.read installed_exec
201 assert_match %r|generated by RubyGems|, wrapper
204 def test_generate_bin_script
205 @installer.wrappers = true
207 @installer.gem_dir = util_gem_dir
209 @installer.generate_bin
210 assert_equal true, File.directory?(util_inst_bindir)
211 installed_exec = File.join(util_inst_bindir, "my_exec")
212 assert_equal true, File.exist?(installed_exec)
213 assert_equal(0100755, File.stat(installed_exec).mode) unless win_platform?
215 wrapper = File.read installed_exec
216 assert_match %r|generated by RubyGems|, wrapper
219 def test_generate_bin_script_format
220 @installer.format_executable = true
221 @installer.wrappers = true
223 @installer.gem_dir = util_gem_dir
225 Gem::Installer.exec_format = 'foo-%s-bar'
226 @installer.generate_bin
227 assert_equal true, File.directory?(util_inst_bindir)
228 installed_exec = File.join util_inst_bindir, 'foo-my_exec-bar'
229 assert_equal true, File.exist?(installed_exec)
231 Gem::Installer.exec_format = nil
234 def test_generate_bin_script_format_disabled
235 @installer.wrappers = true
237 @installer.gem_dir = util_gem_dir
239 Gem::Installer.exec_format = 'foo-%s-bar'
240 @installer.generate_bin
241 assert_equal true, File.directory?(util_inst_bindir)
242 installed_exec = File.join util_inst_bindir, 'my_exec'
243 assert_equal true, File.exist?(installed_exec)
245 Gem::Installer.exec_format = nil
248 def test_generate_bin_script_install_dir
249 @installer.wrappers = true
250 @spec.executables = ["my_exec"]
252 gem_dir = File.join "#{@gemhome}2", 'gems', @spec.full_name
253 gem_bindir = File.join gem_dir, 'bin'
254 FileUtils.mkdir_p gem_bindir
255 File.open File.join(gem_bindir, "my_exec"), 'w' do |f|
259 @installer.gem_home = "#{@gemhome}2"
260 @installer.gem_dir = gem_dir
262 @installer.generate_bin
264 installed_exec = File.join("#{@gemhome}2", 'bin', 'my_exec')
265 assert_equal true, File.exist?(installed_exec)
266 assert_equal(0100755, File.stat(installed_exec).mode) unless win_platform?
268 wrapper = File.read installed_exec
269 assert_match %r|generated by RubyGems|, wrapper
272 def test_generate_bin_script_no_execs
273 @installer.wrappers = true
274 @installer.generate_bin
275 assert_equal false, File.exist?(util_inst_bindir)
278 def test_generate_bin_script_no_perms
279 @installer.wrappers = true
282 Dir.mkdir util_inst_bindir
283 File.chmod 0000, util_inst_bindir
285 assert_raises Gem::FilePermissionError do
286 @installer.generate_bin
290 File.chmod 0700, util_inst_bindir unless $DEBUG
293 def test_generate_bin_script_no_shebang
294 @installer.wrappers = true
295 @spec.executables = ["my_exec"]
297 gem_dir = File.join @gemhome, 'gems', @spec.full_name
298 gem_bindir = File.join gem_dir, 'bin'
299 FileUtils.mkdir_p gem_bindir
300 File.open File.join(gem_bindir, "my_exec"), 'w' do |f|
301 f.puts "blah blah blah"
304 @installer.generate_bin
306 installed_exec = File.join @gemhome, 'bin', 'my_exec'
307 assert_equal true, File.exist?(installed_exec)
308 assert_equal 0100755, File.stat(installed_exec).mode unless win_platform?
310 wrapper = File.read installed_exec
311 assert_match %r|generated by RubyGems|, wrapper
312 # HACK some gems don't have #! in their executables, restore 2008/06
313 #assert_no_match %r|generated by RubyGems|, wrapper
316 def test_generate_bin_symlink
317 return if win_platform? #Windows FS do not support symlinks
319 @installer.wrappers = false
321 @installer.gem_dir = util_gem_dir
323 @installer.generate_bin
324 assert_equal true, File.directory?(util_inst_bindir)
325 installed_exec = File.join(util_inst_bindir, "my_exec")
326 assert_equal true, File.symlink?(installed_exec)
327 assert_equal(File.join(util_gem_dir, "bin", "my_exec"),
328 File.readlink(installed_exec))
331 def test_generate_bin_symlink_no_execs
332 @installer.wrappers = false
333 @installer.generate_bin
334 assert_equal false, File.exist?(util_inst_bindir)
337 def test_generate_bin_symlink_no_perms
338 @installer.wrappers = false
340 @installer.gem_dir = util_gem_dir
342 Dir.mkdir util_inst_bindir
343 File.chmod 0000, util_inst_bindir
345 assert_raises Gem::FilePermissionError do
346 @installer.generate_bin
350 File.chmod 0700, util_inst_bindir unless $DEBUG
353 def test_generate_bin_symlink_update_newer
354 return if win_platform? #Windows FS do not support symlinks
356 @installer.wrappers = false
358 @installer.gem_dir = util_gem_dir
360 @installer.generate_bin
361 installed_exec = File.join(util_inst_bindir, "my_exec")
362 assert_equal(File.join(util_gem_dir, "bin", "my_exec"),
363 File.readlink(installed_exec))
365 @spec = Gem::Specification.new do |s|
366 s.files = ['lib/code.rb']
369 s.summary = "summary"
370 s.description = "desc"
371 s.require_path = 'lib'
375 @installer.gem_dir = File.join util_gem_dir('3')
376 @installer.generate_bin
377 installed_exec = File.join(util_inst_bindir, "my_exec")
378 assert_equal(File.join(util_gem_bindir('3'), "my_exec"),
379 File.readlink(installed_exec),
380 "Ensure symlink moved to latest version")
383 def test_generate_bin_symlink_update_older
384 return if win_platform? #Windows FS do not support symlinks
386 @installer.wrappers = false
388 @installer.gem_dir = util_gem_dir
390 @installer.generate_bin
391 installed_exec = File.join(util_inst_bindir, "my_exec")
392 assert_equal(File.join(util_gem_dir, "bin", "my_exec"),
393 File.readlink(installed_exec))
395 spec = Gem::Specification.new do |s|
396 s.files = ['lib/code.rb']
399 s.summary = "summary"
400 s.description = "desc"
401 s.require_path = 'lib'
405 @installer.gem_dir = util_gem_dir('1')
406 @installer.spec = spec
408 @installer.generate_bin
410 installed_exec = File.join(util_inst_bindir, "my_exec")
411 assert_equal(File.join(util_gem_dir('2'), "bin", "my_exec"),
412 File.readlink(installed_exec),
413 "Ensure symlink not moved")
416 def test_generate_bin_symlink_update_remove_wrapper
417 return if win_platform? #Windows FS do not support symlinks
419 @installer.wrappers = true
421 @installer.gem_dir = util_gem_dir
423 @installer.generate_bin
424 installed_exec = File.join(util_inst_bindir, "my_exec")
425 assert_equal true, File.exist?(installed_exec)
427 @spec = Gem::Specification.new do |s|
428 s.files = ['lib/code.rb']
431 s.summary = "summary"
432 s.description = "desc"
433 s.require_path = 'lib'
436 @installer.wrappers = false
438 @installer.gem_dir = util_gem_dir '3'
439 @installer.generate_bin
440 installed_exec = File.join(util_inst_bindir, "my_exec")
441 assert_equal(File.join(util_gem_dir('3'), "bin", "my_exec"),
442 File.readlink(installed_exec),
443 "Ensure symlink moved to latest version")
446 def test_generate_bin_symlink_win32
447 old_win_platform = Gem.win_platform?
448 Gem.win_platform = true
449 @installer.wrappers = false
451 @installer.gem_dir = util_gem_dir
454 @installer.generate_bin
457 assert_equal true, File.directory?(util_inst_bindir)
458 installed_exec = File.join(util_inst_bindir, "my_exec")
459 assert_equal true, File.exist?(installed_exec)
461 assert_match(/Unable to use symlinks on Windows, installing wrapper/i,
464 wrapper = File.read installed_exec
465 assert_match(/generated by RubyGems/, wrapper)
467 Gem.win_platform = old_win_platform
470 def test_generate_bin_uses_default_shebang
471 return if win_platform? #Windows FS do not support symlinks
473 @installer.wrappers = true
476 @installer.generate_bin
478 default_shebang = File.join(Config::CONFIG['bindir'], Config::CONFIG['ruby_install_name'])
479 shebang_line = open("#{@gemhome}/bin/my_exec") { |f| f.readlines.first }
480 assert_match(/\A#!/, shebang_line)
481 assert_match(/#{default_shebang}/, shebang_line)
485 spec = quick_gem 'a' do |s| s.platform = Gem::Platform.new 'mswin32' end
486 gem = File.join @tempdir, "#{spec.full_name}.gem"
489 FileUtils.mv File.join(@gemhome, 'cache', "#{spec.full_name}.gem"),
492 installer = Gem::Installer.new gem
494 assert_equal File.join(@gemhome, 'gems', spec.full_name), installer.gem_dir
501 assert_equal @spec, @installer.install
504 gemdir = File.join @gemhome, 'gems', @spec.full_name
505 assert File.exist?(gemdir)
507 exe = File.join(gemdir, 'bin', 'executable')
508 assert File.exist?(exe)
509 exe_mode = File.stat(exe).mode & 0111
510 assert_equal 0111, exe_mode, "0%o" % exe_mode unless win_platform?
512 assert File.exist?(File.join(gemdir, 'lib', 'code.rb'))
514 assert File.exist?(File.join(gemdir, 'ext', 'a', 'Rakefile'))
516 spec_file = File.join(@gemhome, 'specifications',
517 "#{@spec.full_name}.gemspec")
519 assert_equal spec_file, @spec.loaded_from
520 assert File.exist?(spec_file)
523 def test_install_bad_gem
527 Dir.chdir @tempdir do Gem::Builder.new(@spec).build end
528 gem = File.join @tempdir, "#{@spec.full_name}.gem"
531 gem_data = File.open gem, 'rb' do |fp| fp.read 1024 end
532 File.open gem, 'wb' do |fp| fp.write gem_data end
534 e = assert_raise Gem::InstallError do
536 @installer = Gem::Installer.new gem
541 assert_equal "invalid gem format for #{gem}", e.message
544 def test_install_check_dependencies
545 @spec.add_dependency 'b', '> 5'
549 assert_raise Gem::InstallError do
555 def test_install_force
557 installer = Gem::Installer.new old_ruby_required, :force => true
561 gem_dir = File.join(@gemhome, 'gems', 'old_ruby_required-1')
562 assert File.exist?(gem_dir)
565 def test_install_ignore_dependencies
566 @spec.add_dependency 'b', '> 5'
568 @installer.ignore_dependencies = true
571 assert_equal @spec, @installer.install
574 gemdir = File.join @gemhome, 'gems', @spec.full_name
575 assert File.exist?(gemdir)
577 exe = File.join(gemdir, 'bin', 'executable')
578 assert File.exist?(exe)
579 exe_mode = File.stat(exe).mode & 0111
580 assert_equal 0111, exe_mode, "0%o" % exe_mode unless win_platform?
581 assert File.exist?(File.join(gemdir, 'lib', 'code.rb'))
583 assert File.exist?(File.join(@gemhome, 'specifications',
584 "#{@spec.full_name}.gemspec"))
587 def test_install_missing_dirs
588 FileUtils.rm_f File.join(Gem.dir, 'cache')
589 FileUtils.rm_f File.join(Gem.dir, 'docs')
590 FileUtils.rm_f File.join(Gem.dir, 'specifications')
593 Dir.chdir @tempdir do Gem::Builder.new(@spec).build end
594 gem = File.join @tempdir, "#{@spec.full_name}.gem"
599 File.directory? File.join(Gem.dir, 'cache')
600 File.directory? File.join(Gem.dir, 'docs')
601 File.directory? File.join(Gem.dir, 'specifications')
603 assert File.exist?(File.join(@gemhome, 'cache', "#{@spec.full_name}.gem"))
604 assert File.exist?(File.join(@gemhome, 'specifications',
605 "#{@spec.full_name}.gemspec"))
608 def test_install_with_message
609 @spec.post_install_message = 'I am a shiny gem!'
612 Dir.chdir @tempdir do Gem::Builder.new(@spec).build end
617 assert_match %r|I am a shiny gem!|, @ui.output
620 def test_install_writable
623 orig_mode = File.stat(Gem.dir).mode
624 File.chmod 0000, Gem.dir
626 e = assert_raise Gem::FilePermissionError do
630 assert_equal "You don't have write permissions into the #{@gemhome} directory.",
633 File.chmod orig_mode, Gem.dir
636 def test_install_wrong_ruby_version
638 installer = Gem::Installer.new old_ruby_required
639 e = assert_raise Gem::InstallError do
642 assert_equal 'old_ruby_required requires Ruby version = 1.4.6',
647 def test_install_wrong_rubygems_version
648 spec = quick_gem 'old_rubygems_required', '1' do |s|
649 s.required_rubygems_version = '< 0'
654 gem = File.join @gemhome, 'cache', "#{spec.full_name}.gem"
657 @installer = Gem::Installer.new gem
658 e = assert_raise Gem::InstallError do
661 assert_equal 'old_rubygems_required requires RubyGems version < 0',
666 def test_installation_satisfies_dependency_eh
667 dep = Gem::Dependency.new 'a', '>= 2'
668 assert @installer.installation_satisfies_dependency?(dep)
670 dep = Gem::Dependency.new 'a', '> 2'
671 assert ! @installer.installation_satisfies_dependency?(dep)
675 util_make_exec '2', "#!/usr/bin/ruby"
677 shebang = @installer.shebang 'my_exec'
679 assert_equal "#!#{Gem.ruby}", shebang
682 def test_shebang_arguments
683 util_make_exec '2', "#!/usr/bin/ruby -ws"
685 shebang = @installer.shebang 'my_exec'
687 assert_equal "#!#{Gem.ruby} -ws", shebang
690 def test_shebang_empty
691 util_make_exec '2', ''
693 shebang = @installer.shebang 'my_exec'
694 assert_equal "#!#{Gem.ruby}", shebang
698 util_make_exec '2', "#!/usr/bin/env ruby"
700 shebang = @installer.shebang 'my_exec'
702 assert_equal "#!#{Gem.ruby}", shebang
705 def test_shebang_env_arguments
706 util_make_exec '2', "#!/usr/bin/env ruby -ws"
708 shebang = @installer.shebang 'my_exec'
710 assert_equal "#!#{Gem.ruby} -ws", shebang
713 def test_shebang_env_shebang
714 util_make_exec '2', ''
715 @installer.env_shebang = true
717 shebang = @installer.shebang 'my_exec'
718 assert_equal "#!/usr/bin/env #{Gem::ConfigMap[:RUBY_INSTALL_NAME]}", shebang
721 def test_shebang_nested
722 util_make_exec '2', "#!/opt/local/ruby/bin/ruby"
724 shebang = @installer.shebang 'my_exec'
726 assert_equal "#!#{Gem.ruby}", shebang
729 def test_shebang_nested_arguments
730 util_make_exec '2', "#!/opt/local/ruby/bin/ruby -ws"
732 shebang = @installer.shebang 'my_exec'
734 assert_equal "#!#{Gem.ruby} -ws", shebang
737 def test_shebang_version
738 util_make_exec '2', "#!/usr/bin/ruby18"
740 shebang = @installer.shebang 'my_exec'
742 assert_equal "#!#{Gem.ruby}", shebang
745 def test_shebang_version_arguments
746 util_make_exec '2', "#!/usr/bin/ruby18 -ws"
748 shebang = @installer.shebang 'my_exec'
750 assert_equal "#!#{Gem.ruby} -ws", shebang
753 def test_shebang_version_env
754 util_make_exec '2', "#!/usr/bin/env ruby18"
756 shebang = @installer.shebang 'my_exec'
758 assert_equal "#!#{Gem.ruby}", shebang
761 def test_shebang_version_env_arguments
762 util_make_exec '2', "#!/usr/bin/env ruby18 -ws"
764 shebang = @installer.shebang 'my_exec'
766 assert_equal "#!#{Gem.ruby} -ws", shebang
772 dest = File.join @gemhome, 'gems', @spec.full_name
774 @installer.unpack dest
776 assert File.exist?(File.join(dest, 'lib', 'code.rb'))
777 assert File.exist?(File.join(dest, 'bin', 'executable'))
781 spec_dir = File.join @gemhome, 'specifications'
782 spec_file = File.join spec_dir, "#{@spec.full_name}.gemspec"
783 FileUtils.rm spec_file
784 assert !File.exist?(spec_file)
786 @installer.spec = @spec
787 @installer.gem_home = @gemhome
789 @installer.write_spec
791 assert File.exist?(spec_file)
792 assert_equal @spec, eval(File.read(spec_file))
795 def old_ruby_required
796 spec = quick_gem 'old_ruby_required', '1' do |s|
797 s.required_ruby_version = '= 1.4.6'
802 File.join @gemhome, 'cache', "#{spec.full_name}.gem"