MiniTest::Unit::TestCase
RubyGemTestCase provides a variety of methods for testing rubygems and gem-related behavior in a sandbox. Through RubyGemTestCase you can install and uninstall gems, fetch remote gems through a stub fetcher and be assured your normal set of gems is not affected.
Tests are always run at a safe level of 1.
Returns the make command for the current platform. For versions of Ruby built on MS Windows with VC++ or Borland it will return ‘nmake’. On all other platforms, including Cygwin, it will return ‘make’.
# File lib/rubygems/test_case.rb, line 753 753: def self.make_command 754: ENV["make"] || (vc_windows? ? 'nmake' : 'make') 755: end
Allows tests to use a random (but controlled) port number instead of a hardcoded one. This helps CI tools when running parallels builds on the same builder slave.
# File lib/rubygems/test_case.rb, line 778 778: def self.process_based_port 779: @@process_based_port ||= 8000 + $$ % 1000 780: end
Finds the path to the ruby executable
# File lib/rubygems/test_case.rb, line 810 810: def self.rubybin 811: ruby = ENV["RUBY"] 812: return ruby if ruby 813: ruby = "ruby" 814: rubyexe = "#{ruby}.exe" 815: 816: 3.times do 817: if File.exist? ruby and File.executable? ruby and !File.directory? ruby 818: return File.expand_path(ruby) 819: end 820: if File.exist? rubyexe and File.executable? rubyexe 821: return File.expand_path(rubyexe) 822: end 823: ruby = File.join("..", ruby) 824: end 825: 826: begin 827: require "rbconfig" 828: File.join(RbConfig::CONFIG["bindir"], 829: RbConfig::CONFIG["ruby_install_name"] + 830: RbConfig::CONFIG["EXEEXT"]) 831: rescue LoadError 832: "ruby" 833: end 834: end
# File lib/rubygems/test_case.rb, line 340 340: def all_spec_names 341: Gem::Specification.map(&:full_name) 342: end
TODO: move to minitest
# File lib/rubygems/test_case.rb, line 84 84: def assert_path_exists path, msg = nil 85: msg = message(msg) { "Expected path '#{path}' to exist" } 86: assert File.exist?(path), msg 87: end
Allows the proper version of rake to be used for the test.
# File lib/rubygems/test_case.rb, line 792 792: def build_rake_in 793: gem_ruby = Gem.ruby 794: Gem.ruby = @@ruby 795: env_rake = ENV["rake"] 796: ENV["rake"] = @@rake 797: yield @@rake 798: ensure 799: Gem.ruby = gem_ruby 800: if env_rake 801: ENV["rake"] = env_rake 802: else 803: ENV.delete("rake") 804: end 805: end
creates a temporary directory with hax
# File lib/rubygems/test_case.rb, line 291 291: def create_tmpdir 292: tmpdir = nil 293: Dir.chdir Dir.tmpdir do tmpdir = Dir.pwd end # HACK OSX /private/tmp 294: tmpdir = File.join tmpdir, "test_rubygems_#{$$}" 295: FileUtils.mkdir_p tmpdir 296: return tmpdir 297: end
Construct a new Gem::Dependency.
# File lib/rubygems/test_case.rb, line 850 850: def dep name, *requirements 851: Gem::Dependency.new name, *requirements 852: end
Builds and installs the Gem::Specification spec
# File lib/rubygems/test_case.rb, line 246 246: def install_gem spec 247: require 'rubygems/installer' 248: 249: use_ui Gem::MockGemUi.new do 250: Dir.chdir @tempdir do 251: Gem::Builder.new(spec).build 252: end 253: end 254: 255: gem = File.join(@tempdir, File.basename(spec.cache_file)).untaint 256: 257: Gem::Installer.new(gem, :wrappers => true).install 258: end
Builds and installs the Gem::Specification spec into the user dir
# File lib/rubygems/test_case.rb, line 263 263: def install_gem_user spec 264: require 'rubygems/installer' 265: 266: use_ui Gem::MockGemUi.new do 267: Dir.chdir @tempdir do 268: Gem::Builder.new(spec).build 269: end 270: end 271: 272: gem = File.join(@tempdir, File.basename(spec.cache_file)).untaint 273: 274: i = Gem::Installer.new(gem, :wrappers => true, :user_install => true) 275: i.install 276: i.spec 277: end
Install the provided specs
# File lib/rubygems/test_case.rb, line 444 444: def install_specs(*specs) 445: Gem::Specification.add_specs(*specs) 446: Gem.searcher = nil 447: end
Returns the make command for the current platform. For versions of Ruby built on MS Windows with VC++ or Borland it will return ‘nmake’. On all other platforms, including Cygwin, it will return ‘make’.
# File lib/rubygems/test_case.rb, line 762 762: def make_command 763: ENV["make"] || (vc_windows? ? 'nmake' : 'make') 764: end
Enables pretty-print for all tests
# File lib/rubygems/test_case.rb, line 302 302: def mu_pp(obj) 303: s = '' 304: s = PP.pp obj, s 305: s = s.force_encoding(Encoding.default_external) if defined? Encoding 306: s.chomp 307: end
Create a new spec (or gem if passed an array of files) and set it up properly. Use this instead of util_spec and util_gem.
# File lib/rubygems/test_case.rb, line 453 453: def new_spec name, version, deps = nil, *files 454: require 'rubygems/specification' 455: 456: spec = Gem::Specification.new do |s| 457: s.platform = Gem::Platform::RUBY 458: s.name = name 459: s.version = version 460: s.author = 'A User' 461: s.email = 'example@example.com' 462: s.homepage = 'http://example.com' 463: s.summary = "this is a summary" 464: s.description = "This is a test description" 465: 466: Array(deps).each do |n, req| 467: s.add_dependency n, (req || '>= 0') 468: end 469: 470: s.files.push(*files) unless files.empty? 471: 472: yield s if block_given? 473: end 474: 475: spec.loaded_from = spec.spec_file 476: 477: unless files.empty? then 478: write_file spec.spec_file do |io| 479: io.write spec.to_ruby_for_cache 480: end 481: 482: util_build_gem spec 483: 484: cache_file = File.join @tempdir, 'gems', "#{spec.full_name}.gem" 485: FileUtils.mkdir_p File.dirname cache_file 486: FileUtils.mv spec.cache_file, cache_file 487: FileUtils.rm spec.spec_file 488: end 489: 490: spec 491: end
Returns whether or not the nmake command could be found.
# File lib/rubygems/test_case.rb, line 769 769: def nmake_found? 770: system('nmake /? 1>NUL 2>&1') 771: end
# File lib/rubygems/test_case.rb, line 785 785: def process_based_port 786: self.class.process_based_port 787: end
Creates a Gem::Specification with a minimum of extra work. name and version are the gem’s name and version, platform, author, email, homepage, summary and description are defaulted. The specification is yielded for customization.
The gem is added to the installed gems in +@gemhome+ and to the current source_index.
Use this with # to build an installed gem.
# File lib/rubygems/test_case.rb, line 355 355: def quick_gem(name, version='2') 356: require 'rubygems/specification' 357: 358: spec = Gem::Specification.new do |s| 359: s.platform = Gem::Platform::RUBY 360: s.name = name 361: s.version = version 362: s.author = 'A User' 363: s.email = 'example@example.com' 364: s.homepage = 'http://example.com' 365: s.summary = "this is a summary" 366: s.description = "This is a test description" 367: 368: yield(s) if block_given? 369: end 370: 371: Gem::Specification.map # HACK: force specs to (re-)load before we write 372: 373: written_path = write_file spec.spec_file do |io| 374: io.write spec.to_ruby_for_cache 375: end 376: 377: spec.loaded_from = spec.loaded_from = written_path 378: 379: Gem::Specification.add_spec spec.for_cache 380: 381: return spec 382: end
# File lib/rubygems/test_case.rb, line 384 384: def quick_spec name, version = '2' 385: # TODO: deprecate 386: require 'rubygems/specification' 387: 388: spec = Gem::Specification.new do |s| 389: s.platform = Gem::Platform::RUBY 390: s.name = name 391: s.version = version 392: s.author = 'A User' 393: s.email = 'example@example.com' 394: s.homepage = 'http://example.com' 395: s.summary = "this is a summary" 396: s.description = "This is a test description" 397: 398: yield(s) if block_given? 399: end 400: 401: spec.loaded_from = spec.spec_file 402: 403: Gem::Specification.add_spec spec 404: 405: return spec 406: end
Reads a binary file at path
# File lib/rubygems/test_case.rb, line 321 321: def read_binary(path) 322: Gem.read_binary path 323: end
Reads a Marshal file at path
# File lib/rubygems/test_case.rb, line 312 312: def read_cache(path) 313: open path.dup.untaint, 'rb' do |io| 314: Marshal.load io.read 315: end 316: end
TODO: move to minitest
# File lib/rubygems/test_case.rb, line 90 90: def refute_path_exists path, msg = nil 91: msg = message(msg) { "Expected path '#{path}' to not exist" } 92: refute File.exist?(path), msg 93: end
Constructs a new Gem::Requirement.
# File lib/rubygems/test_case.rb, line 857 857: def req *requirements 858: return requirements.first if Gem::Requirement === requirements.first 859: Gem::Requirement.create requirements 860: end
# prepares a sandboxed location to install gems. All installs are directed to a temporary directory. All install plugins are removed.
If the RUBY environment variable is set the given path is used for Gem::ruby. The local platform is set to i386-mswin32 for Windows or i686-darwin8.10.1 otherwise.
If the KEEP_FILES environment variable is set the files will not be removed from /tmp/test_rubygems_#{$$}.#{Time.now.to_i}.
# File lib/rubygems/test_case.rb, line 113 113: def setup 114: super 115: 116: @orig_gem_home = ENV['GEM_HOME'] 117: @orig_gem_path = ENV['GEM_PATH'] 118: 119: @current_dir = Dir.pwd 120: @ui = Gem::MockGemUi.new 121: 122: tmpdir = nil 123: Dir.chdir Dir.tmpdir do tmpdir = Dir.pwd end # HACK OSX /private/tmp 124: 125: if ENV['KEEP_FILES'] then 126: @tempdir = File.join(tmpdir, "test_rubygems_#{$$}.#{Time.now.to_i}") 127: else 128: @tempdir = File.join(tmpdir, "test_rubygems_#{$$}") 129: end 130: @tempdir.untaint 131: @gemhome = File.join @tempdir, 'gemhome' 132: @userhome = File.join @tempdir, 'userhome' 133: 134: @orig_ruby = if ruby = ENV['RUBY'] then 135: Gem.class_eval { ruby, @ruby = @ruby, ruby } 136: ruby 137: end 138: 139: Gem.ensure_gem_subdirectories @gemhome 140: 141: @orig_LOAD_PATH = $LOAD_PATH.dup 142: $LOAD_PATH.map! { |s| File.expand_path s } 143: 144: Dir.chdir @tempdir 145: 146: @orig_ENV_HOME = ENV['HOME'] 147: ENV['HOME'] = @userhome 148: Gem.instance_variable_set :@user_home, nil 149: 150: FileUtils.mkdir_p @gemhome 151: FileUtils.mkdir_p @userhome 152: 153: Gem.use_paths(@gemhome) 154: 155: Gem.loaded_specs.clear 156: Gem.unresolved_deps.clear 157: 158: Gem.configuration.verbose = true 159: Gem.configuration.update_sources = true 160: 161: @gem_repo = "http://gems.example.com/" 162: @uri = URI.parse @gem_repo 163: Gem.sources.replace [@gem_repo] 164: 165: Gem.searcher = nil 166: Gem::SpecFetcher.fetcher = nil 167: 168: @orig_BASERUBY = Gem::ConfigMap[:BASERUBY] 169: Gem::ConfigMap[:BASERUBY] = Gem::ConfigMap[:ruby_install_name] 170: 171: @orig_arch = Gem::ConfigMap[:arch] 172: 173: if win_platform? 174: util_set_arch 'i386-mswin32' 175: else 176: util_set_arch 'i686-darwin8.10.1' 177: end 178: 179: @marshal_version = "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}" 180: 181: # TODO: move to installer test cases 182: Gem.post_build_hooks.clear 183: Gem.post_install_hooks.clear 184: Gem.post_uninstall_hooks.clear 185: Gem.pre_install_hooks.clear 186: Gem.pre_uninstall_hooks.clear 187: 188: # TODO: move to installer test cases 189: Gem.post_build do |installer| 190: @post_build_hook_arg = installer 191: true 192: end 193: 194: Gem.post_install do |installer| 195: @post_install_hook_arg = installer 196: end 197: 198: Gem.post_uninstall do |uninstaller| 199: @post_uninstall_hook_arg = uninstaller 200: end 201: 202: Gem.pre_install do |installer| 203: @pre_install_hook_arg = installer 204: true 205: end 206: 207: Gem.pre_uninstall do |uninstaller| 208: @pre_uninstall_hook_arg = uninstaller 209: end 210: end
Constructs a new Gem::Specification.
# File lib/rubygems/test_case.rb, line 865 865: def spec name, version, &block 866: Gem::Specification.new name, v(version), &block 867: end
# restores the process to its original state and removes the tempdir unless the KEEP_FILES environment variable was set.
# File lib/rubygems/test_case.rb, line 216 216: def teardown 217: $LOAD_PATH.replace @orig_LOAD_PATH 218: 219: Gem::ConfigMap[:BASERUBY] = @orig_BASERUBY 220: Gem::ConfigMap[:arch] = @orig_arch 221: 222: if defined? Gem::RemoteFetcher then 223: Gem::RemoteFetcher.fetcher = nil 224: end 225: 226: Dir.chdir @current_dir 227: 228: FileUtils.rm_rf @tempdir unless ENV['KEEP_FILES'] 229: 230: ENV['GEM_HOME'] = @orig_gem_home 231: ENV['GEM_PATH'] = @orig_gem_path 232: 233: _ = @orig_ruby 234: Gem.class_eval { @ruby = _ } if _ 235: 236: if @orig_ENV_HOME then 237: ENV['HOME'] = @orig_ENV_HOME 238: else 239: ENV.delete 'HOME' 240: end 241: end
Uninstalls the Gem::Specification spec
# File lib/rubygems/test_case.rb, line 281 281: def uninstall_gem spec 282: require 'rubygems/uninstaller' 283: 284: Gem::Uninstaller.new(spec.name, 285: :executables => true, :user_install => true).uninstall 286: end
Builds a gem from spec and places it in File.join @gemhome, 'cache'. Automatically creates files based on spec.files
# File lib/rubygems/test_case.rb, line 412 412: def util_build_gem(spec) 413: dir = spec.gem_dir 414: FileUtils.mkdir_p dir 415: 416: Dir.chdir dir do 417: spec.files.each do |file| 418: next if File.exist? file 419: FileUtils.mkdir_p File.dirname(file) 420: File.open file, 'w' do |fp| fp.puts "# #{file}" end 421: end 422: 423: use_ui Gem::MockGemUi.new do 424: Gem::Builder.new(spec).build 425: end 426: 427: cache = spec.cache_file 428: FileUtils.mv File.basename(cache), cache 429: end 430: end
Removes all installed gems from +@gemhome+.
# File lib/rubygems/test_case.rb, line 435 435: def util_clear_gems 436: FileUtils.rm_rf File.join(@gemhome, "gems") # TODO: use Gem::Dirs 437: FileUtils.rm_rf File.join(@gemhome, "specifications") 438: Gem::Specification.reset 439: end
Creates a gem with name, version and deps. The specification will be yielded before gem creation for customization. The gem will be placed in File.join @tempdir, 'gems'. The specification and .gem file location are returned.
# File lib/rubygems/test_case.rb, line 517 517: def util_gem(name, version, deps = nil, &block) 518: # TODO: deprecate 519: raise "deps or block, not both" if deps and block 520: 521: if deps then 522: block = proc do |s| 523: deps.each do |n, req| 524: s.add_dependency n, (req || '>= 0') 525: end 526: end 527: end 528: 529: spec = quick_gem(name, version, &block) 530: 531: util_build_gem spec 532: 533: cache_file = File.join @tempdir, 'gems', "#{spec.original_name}.gem" 534: FileUtils.mkdir_p File.dirname cache_file 535: FileUtils.mv spec.cache_file, cache_file 536: FileUtils.rm spec.spec_file 537: 538: spec.loaded_from = nil 539: 540: [spec, cache_file] 541: end
Gzips data.
# File lib/rubygems/test_case.rb, line 546 546: def util_gzip(data) 547: out = StringIO.new 548: 549: Zlib::GzipWriter.wrap out do |io| 550: io.write data 551: end 552: 553: out.string 554: end
Creates several default gems which all have a lib/code.rb file. The gems are not installed but are available in the cache dir.
+@a1+ | gem a version 1, this is the best-described gem. |
+@a2+ | gem a version 2 |
+@a3a | gem a version 3.a |
+@a_evil9+ | gem a_evil version 9, use this to ensure similarly-named gems don’t collide with a. |
+@b2+ | gem b version 2 |
+@c1_2+ | gem c version 1.2 |
+@pl1+ | gem pl version 1, this gem has a legacy platform of i386-linux. |
Additional prerelease gems may also be created:
+@a2_pre+ | gem a version 2.a |
TODO: nuke this and fix tests. this should speed up a lot
# File lib/rubygems/test_case.rb, line 574 574: def util_make_gems(prerelease = false) 575: @a1 = quick_gem 'a', '1' do |s| 576: s.files = ]lib/code.rb] 577: s.require_paths = ]lib] 578: s.date = Gem::Specification::TODAY - 86400 579: s.homepage = 'http://a.example.com' 580: s.email = ]example@example.com example2@example.com] 581: s.authors = ]Example Example2] 582: s.description = This line is really, really long. So long, in fact, that it is more than eighty characters long! The purpose of this line is for testing wrapping behavior because sometimes people don't wrap their text to eighty characters. Without the wrapping, the text might not look good in the RSS feed.Also, a list: * An entry that\'s actually kind of sort * an entry that\'s really long, which will probably get wrapped funny. That's ok, somebody wasn't thinking straight when they made it more than eighty characters. 583: end 584: 585: init = proc do |s| 586: s.files = ]lib/code.rb] 587: s.require_paths = ]lib] 588: end 589: 590: @a2 = quick_gem('a', '2', &init) 591: @a3a = quick_gem('a', '3.a', &init) 592: @a_evil9 = quick_gem('a_evil', '9', &init) 593: @b2 = quick_gem('b', '2', &init) 594: @c1_2 = quick_gem('c', '1.2', &init) 595: 596: @pl1 = quick_gem 'pl', '1' do |s| # l for legacy 597: s.files = ]lib/code.rb] 598: s.require_paths = ]lib] 599: s.platform = Gem::Platform.new 'i386-linux' 600: s.instance_variable_set :@original_platform, 'i386-linux' 601: end 602: 603: if prerelease 604: @a2_pre = quick_gem('a', '2.a', &init) 605: write_file File.join(*]gems #{@a2_pre.original_name} lib code.rb]) 606: util_build_gem @a2_pre 607: end 608: 609: write_file File.join(*]gems #{@a1.original_name} lib code.rb]) 610: write_file File.join(*]gems #{@a2.original_name} lib code.rb]) 611: write_file File.join(*]gems #{@a3a.original_name} lib code.rb]) 612: write_file File.join(*]gems #{@b2.original_name} lib code.rb]) 613: write_file File.join(*]gems #{@c1_2.original_name} lib code.rb]) 614: write_file File.join(*]gems #{@pl1.original_name} lib code.rb]) 615: 616: [@a1, @a2, @a3a, @a_evil9, @b2, @c1_2, @pl1].each do |spec| 617: util_build_gem spec 618: end 619: 620: FileUtils.rm_r File.join(@gemhome, "gems", @pl1.original_name) 621: end
Set the platform to arch
# File lib/rubygems/test_case.rb, line 632 632: def util_set_arch(arch) 633: Gem::ConfigMap[:arch] = arch 634: platform = Gem::Platform.new arch 635: 636: Gem.instance_variable_set :@platforms, nil 637: Gem::Platform.instance_variable_set :@local, nil 638: 639: platform 640: end
Sets up a fake fetcher using the gems from #. Optionally additional prerelease gems may be included.
Gems created by this method may be fetched using Gem::RemoteFetcher.
# File lib/rubygems/test_case.rb, line 648 648: def util_setup_fake_fetcher(prerelease = false) 649: require 'zlib' 650: require 'socket' 651: require 'rubygems/remote_fetcher' 652: 653: @fetcher = Gem::FakeFetcher.new 654: 655: util_make_gems(prerelease) 656: Gem::Specification.reset 657: 658: @all_gems = [@a1, @a2, @a3a, @a_evil9, @b2, @c1_2].sort 659: @all_gem_names = @all_gems.map { |gem| gem.full_name } 660: 661: gem_names = [@a1.full_name, @a2.full_name, @a3a.full_name, @b2.full_name] 662: @gem_names = gem_names.sort.join("\n") 663: 664: Gem::RemoteFetcher.fetcher = @fetcher 665: end
Sets up Gem::SpecFetcher to return information from the gems in specs. Best used with +@all_gems+ from #.
# File lib/rubygems/test_case.rb, line 671 671: def util_setup_spec_fetcher(*specs) 672: specs -= Gem::Specification._all 673: Gem::Specification.add_specs(*specs) 674: 675: spec_fetcher = Gem::SpecFetcher.fetcher 676: 677: prerelease, _ = Gem::Specification.partition { |spec| 678: spec.version.prerelease? 679: } 680: 681: spec_fetcher.specs[@uri] = [] 682: Gem::Specification.each do |spec| 683: spec_tuple = [spec.name, spec.version, spec.original_platform] 684: spec_fetcher.specs[@uri] << spec_tuple 685: end 686: 687: spec_fetcher.latest_specs[@uri] = [] 688: Gem::Specification.latest_specs.each do |spec| 689: spec_tuple = [spec.name, spec.version, spec.original_platform] 690: spec_fetcher.latest_specs[@uri] << spec_tuple 691: end 692: 693: spec_fetcher.prerelease_specs[@uri] = [] 694: prerelease.each do |spec| 695: spec_tuple = [spec.name, spec.version, spec.original_platform] 696: spec_fetcher.prerelease_specs[@uri] << spec_tuple 697: end 698: 699: v = Gem.marshal_version 700: 701: Gem::Specification.each do |spec| 702: path = "#{@gem_repo}quick/Marshal.#{v}/#{spec.original_name}.gemspec.rz" 703: data = Marshal.dump spec 704: data_deflate = Zlib::Deflate.deflate data 705: @fetcher.data[path] = data_deflate 706: end unless Gem::RemoteFetcher === @fetcher # HACK for test_download_to_cache 707: 708: nil # force errors 709: end
Creates a spec with name, version and deps.
# File lib/rubygems/test_case.rb, line 496 496: def util_spec(name, version, deps = nil, &block) 497: # TODO: deprecate 498: raise "deps or block, not both" if deps and block 499: 500: if deps then 501: block = proc do |s| 502: deps.each do |n, req| 503: s.add_dependency n, (req || '>= 0') 504: end 505: end 506: end 507: 508: quick_spec(name, version, &block) 509: end
Deflates data
# File lib/rubygems/test_case.rb, line 714 714: def util_zip(data) 715: Zlib::Deflate.deflate data 716: end
Construct a new Gem::Version.
# File lib/rubygems/test_case.rb, line 872 872: def v string 873: Gem::Version.create string 874: end
Returns whether or not we’re on a version of Ruby built with VC++ (or Borland) versus Cygwin, Mingw, etc.
# File lib/rubygems/test_case.rb, line 744 744: def vc_windows? 745: RUBY_PLATFORM.match('mswin') 746: end
Is this test being run on a Windows platform?
# File lib/rubygems/test_case.rb, line 728 728: def win_platform? 729: Gem.win_platform? 730: end
Writes a binary file to path which is relative to +@gemhome+
# File lib/rubygems/test_case.rb, line 328 328: def write_file(path) 329: path = File.join @gemhome, path unless Pathname.new(path).absolute? 330: dir = File.dirname path 331: FileUtils.mkdir_p dir 332: 333: open path, 'wb' do |io| 334: yield io if block_given? 335: end 336: 337: path 338: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.