1require 'rubygems/test_case' 2require 'rubygems/dependency_installer' 3require 'rubygems/security' 4 5class TestGemDependencyInstaller < Gem::TestCase 6 7 def setup 8 super 9 10 @gems_dir = File.join @tempdir, 'gems' 11 @cache_dir = File.join @gemhome, 'cache' 12 13 FileUtils.mkdir @gems_dir 14 15 Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new 16 end 17 18 def util_setup_gems 19 @a1, @a1_gem = util_gem 'a', '1' do |s| s.executables << 'a_bin' end 20 @a1_pre, @a1_pre_gem = util_gem 'a', '1.a' 21 @b1, @b1_gem = util_gem 'b', '1' do |s| 22 s.add_dependency 'a' 23 s.add_development_dependency 'aa' 24 end 25 26 @c1, @c1_gem = util_gem 'c', '1' do |s| 27 s.add_development_dependency 'b' 28 end 29 30 @d1, @d1_gem = util_gem 'd', '1' do |s| 31 s.add_development_dependency 'c' 32 end 33 34 util_clear_gems 35 util_reset_gems 36 end 37 38 def test_available_set_for_name 39 util_setup_gems 40 p1a, = util_gem 'a', '10.a' 41 util_setup_spec_fetcher p1a, @a1, @a1_pre 42 43 inst = Gem::DependencyInstaller.new 44 45 available = inst.available_set_for 'a', Gem::Requirement.default 46 47 assert_equal %w[a-1], available.set.map { |s| s.spec.full_name } 48 end 49 50 def test_available_set_for_name_prerelease 51 util_setup_gems 52 p1a, = util_gem 'a', '10.a' 53 util_setup_spec_fetcher p1a, @a1, @a1_pre 54 55 inst = Gem::DependencyInstaller.new :prerelease => true 56 57 available = inst.available_set_for 'a', Gem::Requirement.default 58 59 assert_equal %w[a-10.a], 60 available.sorted.map { |s| s.spec.full_name } 61 end 62 63 def test_available_set_for_dep 64 util_setup_gems 65 p1a, = util_gem 'a', '10.a' 66 util_setup_spec_fetcher p1a, @a1, @a1_pre 67 68 inst = Gem::DependencyInstaller.new 69 70 dep = Gem::Dependency.new 'a', Gem::Requirement.default 71 72 available = inst.available_set_for dep, Gem::Requirement.default 73 74 assert_equal %w[a-1], available.set.map { |s| s.spec.full_name } 75 end 76 77 def test_available_set_for_dep_prerelease 78 util_setup_gems 79 p1a, = util_gem 'a', '10.a' 80 util_setup_spec_fetcher p1a, @a1, @a1_pre 81 82 inst = Gem::DependencyInstaller.new :prerelease => true 83 84 dep = Gem::Dependency.new 'a', Gem::Requirement.default 85 dep.prerelease = true 86 87 available = inst.available_set_for dep, Gem::Requirement.default 88 89 assert_equal %w[a-10.a], 90 available.sorted.map { |s| s.spec.full_name } 91 end 92 93 def test_install 94 util_setup_gems 95 96 FileUtils.mv @a1_gem, @tempdir 97 inst = nil 98 99 Dir.chdir @tempdir do 100 inst = Gem::DependencyInstaller.new 101 inst.install 'a' 102 end 103 104 assert_equal %w[a-1], Gem::Specification.map(&:full_name) 105 assert_equal [@a1], inst.installed_gems 106 end 107 108 def test_install_prerelease 109 util_setup_gems 110 111 p1a, gem = util_gem 'a', '10.a' 112 113 util_setup_spec_fetcher(p1a, @a1, @a1_pre) 114 util_clear_gems 115 116 p1a_data = Gem.read_binary(gem) 117 118 @fetcher.data['http://gems.example.com/gems/a-10.a.gem'] = p1a_data 119 120 dep = Gem::Dependency.new "a" 121 inst = Gem::DependencyInstaller.new :prerelease => true 122 inst.install dep 123 124 assert_equal %w[a-10.a], Gem::Specification.map(&:full_name) 125 assert_equal [p1a], inst.installed_gems 126 end 127 128 def test_install_when_only_prerelease 129 p1a, gem = util_gem 'p', '1.a' 130 131 util_setup_spec_fetcher(p1a) 132 util_clear_gems 133 134 p1a_data = Gem.read_binary(gem) 135 136 @fetcher.data['http://gems.example.com/gems/p-1.a.gem'] = p1a_data 137 138 dep = Gem::Dependency.new "p" 139 inst = Gem::DependencyInstaller.new 140 inst.install dep 141 142 assert_equal %w[], Gem::Specification.map(&:full_name) 143 assert_equal [], inst.installed_gems 144 end 145 146 def test_install_prerelease_skipped_when_normal_ver 147 util_setup_gems 148 149 util_setup_spec_fetcher(@a1, @a1_pre) 150 util_clear_gems 151 152 p1a_data = Gem.read_binary(@a1_gem) 153 154 @fetcher.data['http://gems.example.com/gems/a-1.gem'] = p1a_data 155 156 dep = Gem::Dependency.new "a" 157 inst = Gem::DependencyInstaller.new :prerelease => true 158 inst.install dep 159 160 assert_equal %w[a-1], Gem::Specification.map(&:full_name) 161 assert_equal [@a1], inst.installed_gems 162 end 163 164 def test_install_all_dependencies 165 util_setup_gems 166 167 _, e1_gem = util_gem 'e', '1' do |s| 168 s.add_dependency 'b' 169 end 170 171 util_clear_gems 172 173 FileUtils.mv @a1_gem, @tempdir 174 FileUtils.mv @b1_gem, @tempdir 175 FileUtils.mv e1_gem, @tempdir 176 inst = nil 177 178 Dir.chdir @tempdir do 179 inst = Gem::DependencyInstaller.new :ignore_dependencies => true 180 inst.install 'b' 181 end 182 183 Dir.chdir @tempdir do 184 inst = Gem::DependencyInstaller.new 185 inst.install 'e' 186 end 187 188 assert_equal %w[e-1 a-1], inst.installed_gems.map { |s| s.full_name } 189 end 190 191 def test_install_ignore_satified_deps 192 util_setup_gems 193 194 _, e1_gem = util_gem 'e', '1' do |s| 195 s.add_dependency 'b' 196 end 197 198 util_clear_gems 199 200 FileUtils.mv @a1_gem, @tempdir 201 FileUtils.mv @b1_gem, @tempdir 202 FileUtils.mv e1_gem, @tempdir 203 204 Dir.chdir @tempdir do 205 i = Gem::DependencyInstaller.new :ignore_dependencies => true 206 i.install 'b' 207 end 208 209 inst = nil 210 211 Dir.chdir @tempdir do 212 inst = Gem::DependencyInstaller.new :minimal_deps => true 213 inst.install 'e' 214 end 215 216 assert_equal %w[e-1], inst.installed_gems.map { |s| s.full_name } 217 end 218 219 def test_install_cache_dir 220 util_setup_gems 221 222 dir = "dir" 223 Dir.mkdir dir 224 FileUtils.mv @a1_gem, dir 225 FileUtils.mv @b1_gem, dir 226 inst = nil 227 228 Dir.chdir dir do 229 inst = Gem::DependencyInstaller.new :cache_dir => @tempdir 230 inst.install 'b' 231 end 232 233 assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name } 234 235 assert File.exist? File.join(@gemhome, "cache", @a1.file_name) 236 assert File.exist? File.join(@gemhome, "cache", @b1.file_name) 237 end 238 239 def test_install_dependencies_satisfied 240 util_setup_gems 241 242 a2, a2_gem = util_gem 'a', '2' 243 244 FileUtils.rm_rf File.join(@gemhome, 'gems') 245 246 Gem::Specification.reset 247 248 FileUtils.mv @a1_gem, @tempdir 249 FileUtils.mv a2_gem, @tempdir # not in index 250 FileUtils.mv @b1_gem, @tempdir 251 inst = nil 252 253 Dir.chdir @tempdir do 254 inst = Gem::DependencyInstaller.new 255 inst.install 'a', Gem::Requirement.create("= 2") 256 end 257 258 FileUtils.rm File.join(@tempdir, a2.file_name) 259 260 Dir.chdir @tempdir do 261 inst = Gem::DependencyInstaller.new 262 inst.install 'b' 263 end 264 265 assert_equal %w[a-2 b-1], Gem::Specification.map(&:full_name) 266 assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name } 267 end 268 269 # This asserts that if a gem's dependency is satisfied by an 270 # already installed gem, RubyGems doesn't installed a newer 271 # version 272 def test_install_doesnt_upgrade_installed_depedencies 273 util_setup_gems 274 275 a2, a2_gem = util_gem 'a', '2' 276 a3, a3_gem = util_gem 'a', '3' 277 278 util_setup_spec_fetcher @a1, a3, @b1 279 280 FileUtils.rm_rf File.join(@gemhome, 'gems') 281 282 Gem::Specification.reset 283 284 FileUtils.mv @a1_gem, @tempdir 285 FileUtils.mv a2_gem, @tempdir # not in index 286 FileUtils.mv @b1_gem, @tempdir 287 FileUtils.mv a3_gem, @tempdir 288 289 inst = nil 290 291 Dir.chdir @tempdir do 292 inst = Gem::DependencyInstaller.new 293 inst.install 'a', Gem::Requirement.create("= 2") 294 end 295 296 FileUtils.rm File.join(@tempdir, a2.file_name) 297 298 Dir.chdir @tempdir do 299 inst = Gem::DependencyInstaller.new 300 inst.install 'b' 301 end 302 303 assert_equal %w[a-2 b-1], Gem::Specification.map(&:full_name) 304 assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name } 305 end 306 307 def test_install_dependency 308 util_setup_gems 309 310 done_installing_ran = false 311 inst = nil 312 313 Gem.done_installing do |installer, specs| 314 done_installing_ran = true 315 assert_equal inst, installer 316 assert_equal [@a1, @b1], specs 317 end 318 319 FileUtils.mv @a1_gem, @tempdir 320 FileUtils.mv @b1_gem, @tempdir 321 322 Dir.chdir @tempdir do 323 inst = Gem::DependencyInstaller.new(:build_docs_in_background => false) 324 inst.install 'b' 325 end 326 327 assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name } 328 329 assert done_installing_ran, 'post installs hook was not run' 330 end 331 332 def test_install_dependency_development 333 util_setup_gems 334 335 @aa1, @aa1_gem = util_gem 'aa', '1' 336 337 util_reset_gems 338 339 FileUtils.mv @a1_gem, @tempdir 340 FileUtils.mv @aa1_gem, @tempdir 341 FileUtils.mv @b1_gem, @tempdir 342 inst = nil 343 344 Dir.chdir @tempdir do 345 inst = Gem::DependencyInstaller.new(:development => true) 346 inst.install 'b' 347 end 348 349 assert_equal %w[a-1 aa-1 b-1], inst.installed_gems.map { |s| s.full_name } 350 end 351 352 def test_install_dependency_development_deep 353 util_setup_gems 354 355 @aa1, @aa1_gem = util_gem 'aa', '1' 356 357 util_reset_gems 358 359 FileUtils.mv @a1_gem, @tempdir 360 FileUtils.mv @aa1_gem, @tempdir 361 FileUtils.mv @b1_gem, @tempdir 362 FileUtils.mv @c1_gem, @tempdir 363 FileUtils.mv @d1_gem, @tempdir 364 inst = nil 365 366 Dir.chdir @tempdir do 367 inst = Gem::DependencyInstaller.new(:development => true) 368 inst.install 'd' 369 end 370 371 assert_equal %w[a-1 aa-1 b-1 c-1 d-1], inst.installed_gems.map { |s| s.full_name } 372 end 373 374 def test_install_dependency_development_shallow 375 util_setup_gems 376 377 @aa1, @aa1_gem = util_gem 'aa', '1' 378 379 util_reset_gems 380 381 FileUtils.mv @a1_gem, @tempdir 382 FileUtils.mv @aa1_gem, @tempdir 383 FileUtils.mv @b1_gem, @tempdir 384 FileUtils.mv @c1_gem, @tempdir 385 FileUtils.mv @d1_gem, @tempdir 386 inst = nil 387 388 Dir.chdir @tempdir do 389 inst = Gem::DependencyInstaller.new(:development => true, :dev_shallow => true) 390 inst.install 'd' 391 end 392 393 assert_equal %w[c-1 d-1], inst.installed_gems.map { |s| s.full_name } 394 end 395 396 def test_install_dependency_existing 397 util_setup_gems 398 399 Gem::Installer.new(@a1_gem).install 400 FileUtils.mv @a1_gem, @tempdir 401 FileUtils.mv @b1_gem, @tempdir 402 inst = nil 403 404 Dir.chdir @tempdir do 405 inst = Gem::DependencyInstaller.new 406 inst.install 'b' 407 end 408 409 assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name } 410 end 411 412 def test_install_dependency_old 413 _, e1_gem = util_gem 'e', '1' 414 _, f1_gem = util_gem 'f', '1', 'e' => nil 415 _, f2_gem = util_gem 'f', '2' 416 417 FileUtils.mv e1_gem, @tempdir 418 FileUtils.mv f1_gem, @tempdir 419 FileUtils.mv f2_gem, @tempdir 420 inst = nil 421 422 Dir.chdir @tempdir do 423 inst = Gem::DependencyInstaller.new 424 inst.install 'f' 425 end 426 427 assert_equal %w[f-2], inst.installed_gems.map { |s| s.full_name } 428 end 429 430 def test_install_local 431 util_setup_gems 432 433 FileUtils.mv @a1_gem, @tempdir 434 inst = nil 435 436 Dir.chdir @tempdir do 437 inst = Gem::DependencyInstaller.new :domain => :local 438 inst.install 'a-1.gem' 439 end 440 441 assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } 442 end 443 444 def test_install_local_dependency 445 util_setup_gems 446 447 FileUtils.mv @a1_gem, @tempdir 448 FileUtils.mv @b1_gem, @tempdir 449 450 inst = nil 451 452 Dir.chdir @tempdir do 453 inst = Gem::DependencyInstaller.new :domain => :local 454 inst.install 'b-1.gem' 455 end 456 457 assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name } 458 end 459 460 def test_install_local_dependency_installed 461 util_setup_gems 462 463 FileUtils.mv @a1_gem, @tempdir 464 FileUtils.mv @b1_gem, @tempdir 465 466 inst = nil 467 468 Dir.chdir @tempdir do 469 Gem::Installer.new('a-1.gem').install 470 471 inst = Gem::DependencyInstaller.new :domain => :local 472 inst.install 'b-1.gem' 473 end 474 475 assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name } 476 end 477 478 def test_install_local_subdir 479 util_setup_gems 480 481 inst = nil 482 483 Dir.chdir @tempdir do 484 inst = Gem::DependencyInstaller.new :domain => :local 485 inst.install 'gems/a-1.gem' 486 end 487 488 assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } 489 end 490 491 def test_install_env_shebang 492 util_setup_gems 493 494 FileUtils.mv @a1_gem, @tempdir 495 inst = nil 496 497 Dir.chdir @tempdir do 498 inst = Gem::DependencyInstaller.new :env_shebang => true, :wrappers => true, :format_executable => false 499 inst.install 'a' 500 end 501 502 env = "/\\S+/env" unless Gem.win_platform? 503 504 assert_match %r|\A#!#{env} #{Gem::ConfigMap[:ruby_install_name]}\n|, 505 File.read(File.join(@gemhome, 'bin', 'a_bin')) 506 end 507 508 def test_install_force 509 util_setup_gems 510 511 FileUtils.mv @b1_gem, @tempdir 512 si = util_setup_spec_fetcher @b1 513 @fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml 514 inst = nil 515 516 Dir.chdir @tempdir do 517 inst = Gem::DependencyInstaller.new :force => true 518 inst.install 'b' 519 end 520 521 assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name } 522 end 523 524 def test_install_build_args 525 util_setup_gems 526 527 FileUtils.mv @a1_gem, @tempdir 528 inst = nil 529 build_args = %w[--a --b="c"] 530 531 Dir.chdir @tempdir do 532 inst = Gem::DependencyInstaller.new( 533 :build_args => build_args) 534 inst.install 'a' 535 end 536 537 assert_equal build_args.join("\n"), File.read(inst.installed_gems.first.build_info_file).strip 538 end 539 540 def test_install_ignore_dependencies 541 util_setup_gems 542 543 FileUtils.mv @b1_gem, @tempdir 544 inst = nil 545 546 Dir.chdir @tempdir do 547 inst = Gem::DependencyInstaller.new :ignore_dependencies => true 548 inst.install 'b' 549 end 550 551 assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name } 552 end 553 554 def test_install_install_dir 555 util_setup_gems 556 557 FileUtils.mv @a1_gem, @tempdir 558 FileUtils.mv @b1_gem, @tempdir 559 560 inst = Gem::Installer.new @a1.file_name 561 inst.install 562 563 gemhome2 = File.join @tempdir, 'gemhome2' 564 Dir.mkdir gemhome2 565 inst = nil 566 567 Dir.chdir @tempdir do 568 inst = Gem::DependencyInstaller.new :install_dir => gemhome2 569 inst.install 'b' 570 end 571 572 assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name } 573 574 assert File.exist?(File.join(gemhome2, 'specifications', @a1.spec_name)) 575 assert File.exist?(File.join(gemhome2, 'cache', @a1.file_name)) 576 end 577 578 def test_install_domain_both 579 util_setup_gems 580 581 a1_data = nil 582 File.open @a1_gem, 'rb' do |fp| 583 a1_data = fp.read 584 end 585 586 @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data 587 588 FileUtils.mv @b1_gem, @tempdir 589 inst = nil 590 591 Dir.chdir @tempdir do 592 inst = Gem::DependencyInstaller.new :domain => :both 593 inst.install 'b' 594 end 595 596 assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name } 597 a1, b1 = inst.installed_gems 598 599 assert_equal a1.spec_file, a1.loaded_from 600 assert_equal b1.spec_file, b1.loaded_from 601 end 602 603 def test_install_domain_both_no_network 604 util_setup_gems 605 606 @fetcher.data["http://gems.example.com/gems/Marshal.#{@marshal_version}"] = 607 proc do 608 raise Gem::RemoteFetcher::FetchError 609 end 610 611 FileUtils.mv @a1_gem, @tempdir 612 FileUtils.mv @b1_gem, @tempdir 613 inst = nil 614 615 Dir.chdir @tempdir do 616 inst = Gem::DependencyInstaller.new :domain => :both 617 inst.install 'b' 618 end 619 620 assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name } 621 end 622 623 def test_install_domain_local 624 util_setup_gems 625 626 FileUtils.mv @b1_gem, @tempdir 627 inst = nil 628 629 Dir.chdir @tempdir do 630 e = assert_raises Gem::DependencyError do 631 inst = Gem::DependencyInstaller.new :domain => :local 632 inst.install 'b' 633 end 634 635 expected = "Unable to resolve dependencies: b requires a (>= 0)" 636 assert_equal expected, e.message 637 end 638 639 assert_equal [], inst.installed_gems.map { |s| s.full_name } 640 end 641 642 def test_install_domain_remote 643 util_setup_gems 644 645 a1_data = nil 646 File.open @a1_gem, 'rb' do |fp| 647 a1_data = fp.read 648 end 649 650 @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data 651 652 inst = Gem::DependencyInstaller.new :domain => :remote 653 inst.install 'a' 654 655 assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } 656 end 657 658 def test_install_dual_repository 659 util_setup_gems 660 661 FileUtils.mv @a1_gem, @tempdir 662 FileUtils.mv @b1_gem, @tempdir 663 inst = nil 664 665 gemhome2 = "#{@gemhome}2" 666 667 Dir.chdir @tempdir do 668 inst = Gem::DependencyInstaller.new :install_dir => gemhome2 669 inst.install 'a' 670 end 671 672 ENV['GEM_HOME'] = @gemhome 673 ENV['GEM_PATH'] = [@gemhome, gemhome2].join File::PATH_SEPARATOR 674 Gem.clear_paths 675 676 Dir.chdir @tempdir do 677 inst = Gem::DependencyInstaller.new 678 inst.install 'b' 679 end 680 681 assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name } 682 end 683 684 def test_install_reinstall 685 util_setup_gems 686 687 Gem::Installer.new(@a1_gem).install 688 FileUtils.mv @a1_gem, @tempdir 689 inst = nil 690 691 Dir.chdir @tempdir do 692 inst = Gem::DependencyInstaller.new 693 inst.install 'a' 694 end 695 696 assert_equal %w[a-1], Gem::Specification.map(&:full_name) 697 assert_equal %w[a-1], inst.installed_gems.map(&:full_name) 698 end 699 700 def test_install_remote 701 util_setup_gems 702 703 a1_data = nil 704 File.open @a1_gem, 'rb' do |fp| 705 a1_data = fp.read 706 end 707 708 @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data 709 710 inst = Gem::DependencyInstaller.new 711 712 Dir.chdir @tempdir do 713 inst.install 'a' 714 end 715 716 assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } 717 end 718 719 def test_install_remote_dep 720 util_setup_gems 721 722 a1_data = nil 723 File.open @a1_gem, 'rb' do |fp| 724 a1_data = fp.read 725 end 726 727 @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data 728 729 inst = Gem::DependencyInstaller.new 730 731 Dir.chdir @tempdir do 732 dep = Gem::Dependency.new @a1.name, @a1.version 733 inst.install dep 734 end 735 736 assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } 737 end 738 739 def test_install_remote_platform_newer 740 util_setup_gems 741 742 a2_o, a2_o_gem = util_gem 'a', '2' do |s| 743 s.platform = Gem::Platform.new %w[cpu other_platform 1] 744 end 745 746 util_clear_gems 747 748 si = util_setup_spec_fetcher @a1, a2_o 749 750 @fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml 751 752 a1_data = nil 753 a2_o_data = nil 754 755 File.open @a1_gem, 'rb' do |fp| a1_data = fp.read end 756 File.open a2_o_gem, 'rb' do |fp| a2_o_data = fp.read end 757 758 @fetcher.data["http://gems.example.com/gems/#{@a1.file_name}"] = 759 a1_data 760 @fetcher.data["http://gems.example.com/gems/#{a2_o.file_name}"] = 761 a2_o_data 762 763 inst = Gem::DependencyInstaller.new :domain => :remote 764 inst.install 'a' 765 766 assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } 767 end 768 769 if defined? OpenSSL then 770 def test_install_security_policy 771 util_setup_gems 772 773 data = File.open(@a1_gem, 'rb') { |f| f.read } 774 @fetcher.data['http://gems.example.com/gems/a-1.gem'] = data 775 776 data = File.open(@b1_gem, 'rb') { |f| f.read } 777 @fetcher.data['http://gems.example.com/gems/b-1.gem'] = data 778 779 policy = Gem::Security::HighSecurity 780 inst = Gem::DependencyInstaller.new :security_policy => policy 781 782 e = assert_raises Gem::Security::Exception do 783 inst.install 'b' 784 end 785 786 assert_equal 'unsigned gems are not allowed by the High Security policy', 787 e.message 788 789 assert_equal %w[], inst.installed_gems.map { |s| s.full_name } 790 end 791 end 792 793 # Wrappers don't work on mswin 794 unless win_platform? then 795 def test_install_no_wrappers 796 util_setup_gems 797 798 @fetcher.data['http://gems.example.com/gems/a-1.gem'] = read_binary(@a1_gem) 799 800 inst = Gem::DependencyInstaller.new :wrappers => false, :format_executable => false 801 inst.install 'a' 802 803 refute_match(%r|This file was generated by RubyGems.|, 804 File.read(File.join(@gemhome, 'bin', 'a_bin'))) 805 end 806 end 807 808 def test_install_version 809 util_setup_d 810 811 data = File.open(@d2_gem, 'rb') { |f| f.read } 812 @fetcher.data['http://gems.example.com/gems/d-2.gem'] = data 813 814 data = File.open(@d1_gem, 'rb') { |f| f.read } 815 @fetcher.data['http://gems.example.com/gems/d-1.gem'] = data 816 817 inst = Gem::DependencyInstaller.new 818 819 inst.install 'd', '= 1' 820 821 assert_equal %w[d-1], inst.installed_gems.map { |s| s.full_name } 822 end 823 824 def test_install_version_default 825 util_setup_d 826 827 data = File.open(@d2_gem, 'rb') { |f| f.read } 828 @fetcher.data['http://gems.example.com/gems/d-2.gem'] = data 829 830 data = File.open(@d1_gem, 'rb') { |f| f.read } 831 @fetcher.data['http://gems.example.com/gems/d-1.gem'] = data 832 833 inst = Gem::DependencyInstaller.new 834 inst.install 'd' 835 836 assert_equal %w[d-2], inst.installed_gems.map { |s| s.full_name } 837 end 838 839 def test_find_gems_gems_with_sources 840 util_setup_gems 841 842 inst = Gem::DependencyInstaller.new 843 dep = Gem::Dependency.new 'b', '>= 0' 844 845 Gem::Specification.reset 846 847 set = inst.find_gems_with_sources(dep) 848 849 assert_kind_of Gem::AvailableSet, set 850 851 s = set.set.first 852 853 assert_equal @b1, s.spec 854 assert_equal Gem::Source.new(@gem_repo), s.source 855 end 856 857 def test_find_spec_by_name_and_version_wildcard 858 util_gem 'a', 1 859 FileUtils.mv 'gems/a-1.gem', @tempdir 860 861 FileUtils.touch 'rdoc.gem' 862 863 inst = Gem::DependencyInstaller.new 864 865 available = inst.find_spec_by_name_and_version('*.gem') 866 867 assert_equal %w[a-1], available.all_specs.map { |spec| spec.full_name } 868 end 869 870 def test_find_spec_by_name_and_version_wildcard_bad_gem 871 FileUtils.touch 'rdoc.gem' 872 873 inst = Gem::DependencyInstaller.new 874 875 assert_raises Gem::Package::FormatError do 876 inst.find_spec_by_name_and_version '*.gem' 877 end 878 end 879 880 def test_find_spec_by_name_and_version_bad_gem 881 FileUtils.touch 'rdoc.gem' 882 883 inst = Gem::DependencyInstaller.new 884 885 e = assert_raises Gem::Package::FormatError do 886 inst.find_spec_by_name_and_version 'rdoc.gem' 887 end 888 889 full_path = File.join @tempdir, 'rdoc.gem' 890 assert_equal "package metadata is missing in #{full_path}", e.message 891 end 892 893 def test_find_spec_by_name_and_version_directory 894 Dir.mkdir 'rdoc' 895 896 inst = Gem::DependencyInstaller.new 897 898 e = assert_raises Gem::SpecificGemNotFoundException do 899 inst.find_spec_by_name_and_version 'rdoc' 900 end 901 902 assert_equal "Could not find a valid gem 'rdoc' (>= 0) " + 903 "locally or in a repository", 904 e.message 905 end 906 907 def test_find_spec_by_name_and_version_file 908 FileUtils.touch 'rdoc' 909 910 inst = Gem::DependencyInstaller.new 911 912 e = assert_raises Gem::SpecificGemNotFoundException do 913 inst.find_spec_by_name_and_version 'rdoc' 914 end 915 916 assert_equal "Could not find a valid gem 'rdoc' (>= 0) " + 917 "locally or in a repository", 918 e.message 919 end 920 921 def test_find_gems_with_sources_local 922 util_setup_gems 923 924 FileUtils.mv @a1_gem, @tempdir 925 inst = Gem::DependencyInstaller.new 926 dep = Gem::Dependency.new 'a', '>= 0' 927 set = nil 928 929 Dir.chdir @tempdir do 930 set = inst.find_gems_with_sources dep 931 end 932 933 gems = set.sorted 934 935 assert_equal 2, gems.length 936 local = gems.first 937 assert_equal 'a-1', local.spec.full_name, 'local spec' 938 assert_equal File.join(@tempdir, @a1.file_name), 939 local.source.download(local.spec), 'local path' 940 941 remote = gems.last 942 assert_equal 'a-1', remote.spec.full_name, 'remote spec' 943 assert_equal Gem::Source.new(@gem_repo), remote.source, 'remote path' 944 945 end 946 947 def test_find_gems_with_sources_prerelease 948 util_setup_gems 949 950 installer = Gem::DependencyInstaller.new 951 952 dependency = Gem::Dependency.new('a', Gem::Requirement.default) 953 954 releases = 955 installer.find_gems_with_sources(dependency).all_specs 956 957 assert releases.any? { |s| s.name == 'a' and s.version.to_s == '1' } 958 refute releases.any? { |s| s.name == 'a' and s.version.to_s == '1.a' } 959 960 dependency.prerelease = true 961 962 prereleases = 963 installer.find_gems_with_sources(dependency).all_specs 964 965 assert_equal [@a1_pre, @a1], prereleases 966 end 967 968 def test_find_gems_with_sources_with_bad_source 969 Gem.sources.replace ["http://not-there.nothing"] 970 971 installer = Gem::DependencyInstaller.new 972 973 dep = Gem::Dependency.new('a') 974 975 out = installer.find_gems_with_sources(dep) 976 977 assert out.empty? 978 assert_kind_of Gem::SourceFetchProblem, installer.errors.first 979 end 980 981 def assert_resolve expected, *specs 982 util_clear_gems 983 util_setup_spec_fetcher(*specs) 984 Gem::Specification.reset 985 986 inst = Gem::DependencyInstaller.new 987 inst.find_spec_by_name_and_version specs.first.name 988 inst.gather_dependencies 989 990 actual = inst.gems_to_install.map { |s| s.full_name } 991 assert_equal expected, actual 992 end 993 994 def assert_resolve_pre expected, *specs 995 util_clear_gems 996 997 util_setup_spec_fetcher(*specs) 998 Gem::Specification.reset 999 1000 spec = specs.first 1001 1002 inst = Gem::DependencyInstaller.new :prerelease => true 1003 inst.find_spec_by_name_and_version spec.name, spec.version 1004 inst.gather_dependencies 1005 1006 actual = inst.gems_to_install.map { |s| s.full_name } 1007 assert_equal expected, actual 1008 end 1009 1010 def test_gather_dependencies 1011 util_setup_gems 1012 util_reset_gems 1013 1014 inst = Gem::DependencyInstaller.new 1015 inst.find_spec_by_name_and_version 'b' 1016 inst.gather_dependencies 1017 1018 assert_equal %w[a-1 b-1], inst.gems_to_install.map { |s| s.full_name } 1019 end 1020 1021 ## 1022 # [A1] depends on 1023 # [B] > 0 (satisfied by 2.0) 1024 # [B1] depends on 1025 # [C] > 0 (satisfied by 1.0) 1026 # [B2] depends on nothing! 1027 # [C1] depends on nothing 1028 1029 def test_gather_dependencies_dropped 1030 a1, = util_spec 'a', '1', 'b' => nil 1031 b1, = util_spec 'b', '1', 'c' => nil 1032 b2, = util_spec 'b', '2' 1033 c1, = util_spec 'c', '1' 1034 1035 assert_resolve %w[b-2 a-1], a1, b1, b2, c1 1036 end 1037 1038 ## 1039 # [A] depends on 1040 # [B] >= 1.0 (satisfied by 1.1) depends on 1041 # [Z] 1042 # [C] >= 1.0 depends on 1043 # [B] = 1.0 1044 # 1045 # and should backtrack to resolve using b-1.0, pruning Z from the 1046 # resolve. 1047 1048 def test_gather_dependencies_raggi_the_edgecase_generator 1049 a, _ = util_spec 'a', '1.0', 'b' => '>= 1.0', 'c' => '>= 1.0' 1050 b1, _ = util_spec 'b', '1.0' 1051 b2, _ = util_spec 'b', '1.1', 'z' => '>= 1.0' 1052 c, _ = util_spec 'c', '1.0', 'b' => '= 1.0' 1053 1054 assert_resolve %w[b-1.0 c-1.0 a-1.0], a, b1, b2, c 1055 end 1056 1057 ## 1058 # [A] depends on 1059 # [B] >= 1.0 (satisfied by 2.0) 1060 # [C] = 1.0 depends on 1061 # [B] ~> 1.0 1062 # 1063 # and should resolve using b-1.0 1064 1065 def test_gather_dependencies_over 1066 a, _ = util_spec 'a', '1.0', 'b' => '>= 1.0', 'c' => '= 1.0' 1067 b1, _ = util_spec 'b', '1.0' 1068 b2, _ = util_spec 'b', '2.0' 1069 c, _ = util_spec 'c', '1.0', 'b' => '~> 1.0' 1070 1071 assert_resolve %w[b-1.0 c-1.0 a-1.0], a, b1, b2, c 1072 end 1073 1074 ## 1075 # [A] depends on 1076 # [B] ~> 1.0 (satisfied by 1.1) 1077 # [C] = 1.0 depends on 1078 # [B] = 1.0 1079 # 1080 # and should resolve using b-1.0 1081 # 1082 # TODO: this is not under, but over... under would require depth 1083 # first resolve through a dependency that is later pruned. 1084 1085 def test_gather_dependencies_under 1086 a, _ = util_spec 'a', '1.0', 'b' => '~> 1.0', 'c' => '= 1.0' 1087 b10, _ = util_spec 'b', '1.0' 1088 b11, _ = util_spec 'b', '1.1' 1089 c, _ = util_spec 'c', '1.0', 'b' => '= 1.0' 1090 1091 assert_resolve %w[b-1.0 c-1.0 a-1.0], a, b10, b11, c 1092 end 1093 1094 # under 1095 # 1096 # [A] depends on 1097 # [B] ~> 1.0 (satisfied by 1.0) 1098 # [C] = 1.0 depends on 1099 # [B] = 2.0 1100 1101 def test_gather_dependencies_divergent 1102 a, _ = util_spec 'a', '1.0', 'b' => '~> 1.0', 'c' => '= 1.0' 1103 b1, _ = util_spec 'b', '1.0' 1104 b2, _ = util_spec 'b', '2.0' 1105 c, _ = util_spec 'c', '1.0', 'b' => '= 2.0' 1106 1107 assert_raises Gem::DependencyError do 1108 assert_resolve :ignored, a, b1, b2, c 1109 end 1110 end 1111 1112 def test_gather_dependencies_platform_alternate 1113 util_setup_wxyz 1114 util_set_arch 'cpu-my_platform1' 1115 1116 assert_resolve %w[x-1-cpu-my_platform-1 w-1], @w1, @x1_m 1117 end 1118 1119 def test_gather_dependencies_platform_bump 1120 util_setup_wxyz 1121 1122 assert_resolve %w[y-1 z-1], @z1, @y1 1123 end 1124 1125 def test_gather_dependencies_prerelease 1126 util_setup_gems 1127 util_setup_c1_pre 1128 1129 assert_resolve_pre %w[a-1.a b-1 c-1.a], @c1_pre, @a1_pre, @b1 1130 end 1131 1132 def test_gather_dependencies_old_required 1133 util_setup_d 1134 e1, = util_spec 'e', '1', 'd' => '= 1' 1135 util_clear_gems 1136 1137 assert_resolve %w[d-1 e-1], e1, @d1, @d2 1138 end 1139 1140 def util_write_a1_bin 1141 write_file File.join('gems', 'a-1', 'bin', 'a_bin') do |fp| 1142 fp.puts "#!/usr/bin/ruby" 1143 end 1144 end 1145 1146 def util_setup_c1_pre 1147 @c1_pre, @c1_pre_gem = util_spec 'c', '1.a' do |s| 1148 s.add_dependency 'a', '1.a' 1149 s.add_dependency 'b', '1' 1150 end 1151 1152 util_reset_gems 1153 end 1154 1155 def util_setup_d 1156 @d1, @d1_gem = util_gem 'd', '1' 1157 @d2, @d2_gem = util_gem 'd', '2' 1158 1159 util_reset_gems 1160 end 1161 1162 def util_setup_wxyz 1163 @x1_m, @x1_m_gem = util_spec 'x', '1' do |s| 1164 s.platform = Gem::Platform.new %w[cpu my_platform 1] 1165 end 1166 1167 @x1_o, @x1_o_gem = util_spec 'x', '1' do |s| 1168 s.platform = Gem::Platform.new %w[cpu other_platform 1] 1169 end 1170 1171 @w1, @w1_gem = util_spec 'w', '1', 'x' => nil 1172 1173 @y1, @y1_gem = util_spec 'y', '1' 1174 @y1_1_p, @y1_1_p_gem = util_spec 'y', '1.1' do |s| 1175 s.platform = Gem::Platform.new %w[cpu my_platform 1] 1176 end 1177 1178 @z1, @z1_gem = util_spec 'z', '1', 'y' => nil 1179 1180 util_reset_gems 1181 end 1182 1183 def util_reset_gems 1184 @a1 ||= nil 1185 @b1 ||= nil 1186 @a1_pre ||= nil 1187 @c1_pre ||= nil 1188 @d1 ||= nil 1189 @d2 ||= nil 1190 @w1 ||= nil 1191 @x1_m ||= nil 1192 @x1_o ||= nil 1193 @y1 ||= nil 1194 @y1_1_p ||= nil 1195 @z1 ||= nil 1196 1197 util_setup_spec_fetcher(*[@a1, @a1_pre, @b1, @c1_pre, 1198 @d1, @d2, @x1_m, @x1_o, @w1, @y1, 1199 @y1_1_p, @z1].compact) 1200 1201 util_clear_gems 1202 end 1203end 1204