summaryrefslogtreecommitdiff
path: root/spec/ruby/core/kernel/Integer_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/core/kernel/Integer_spec.rb')
-rw-r--r--spec/ruby/core/kernel/Integer_spec.rb845
1 files changed, 845 insertions, 0 deletions
diff --git a/spec/ruby/core/kernel/Integer_spec.rb b/spec/ruby/core/kernel/Integer_spec.rb
new file mode 100644
index 0000000000..978fd8ef08
--- /dev/null
+++ b/spec/ruby/core/kernel/Integer_spec.rb
@@ -0,0 +1,845 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+describe :kernel_integer, shared: true do
+ it "returns a Bignum for a Bignum" do
+ Integer(2e100).should == 2e100
+ end
+
+ it "returns a Fixnum for a Fixnum" do
+ Integer(100).should == 100
+ end
+
+ it "raises a TypeError when to_int returns not-an-Integer object and to_i returns nil" do
+ obj = mock("object")
+ obj.should_receive(:to_int).and_return("1")
+ obj.should_receive(:to_i).and_return(nil)
+ -> {
+ Integer(obj)
+ }.should raise_consistent_error(TypeError, "can't convert MockObject into Integer (MockObject#to_i gives nil)")
+ end
+
+ it "return a result of to_i when to_int does not return an Integer" do
+ obj = mock("object")
+ obj.should_receive(:to_int).and_return("1")
+ obj.should_receive(:to_i).and_return(42)
+ Integer(obj).should == 42
+ end
+
+ it "returns a result of to_str" do
+ obj = mock("obj")
+ obj.should_receive(:to_str).and_return("1")
+
+ Integer(obj).should == 1
+ end
+
+ it "returns a result of to_int when both to_int and to_str are defined" do
+ obj = mock("obj")
+ obj.should_receive(:to_int).and_return(1)
+ obj.should_not_receive(:to_str)
+
+ Integer(obj).should == 1
+ end
+
+ it "returns a result of to_str when both to_str and to_i are defined" do
+ obj = mock("obj")
+ obj.should_receive(:to_str).and_return("1")
+ obj.should_not_receive(:to_i)
+
+ Integer(obj).should == 1
+ end
+
+ it "raises a TypeError when passed nil" do
+ -> { Integer(nil) }.should.raise(TypeError, "can't convert nil into Integer")
+ end
+
+ it "returns an Integer object" do
+ Integer(2).should.instance_of?(Integer)
+ Integer(9**99).should.instance_of?(Integer)
+ end
+
+ it "truncates Floats" do
+ Integer(3.14).should == 3
+ Integer(90.8).should == 90
+ end
+
+ it "calls to_i on Rationals" do
+ Integer(Rational(8,3)).should == 2
+ Integer(3.quo(2)).should == 1
+ end
+
+ it "returns the value of to_int if the result is a Fixnum" do
+ obj = mock("object")
+ obj.should_receive(:to_int).and_return(1)
+ obj.should_not_receive(:to_i)
+ Integer(obj).should == 1
+ end
+
+ it "returns the value of to_int if the result is a Bignum" do
+ obj = mock("object")
+ obj.should_receive(:to_int).and_return(2 * 10**100)
+ obj.should_not_receive(:to_i)
+ Integer(obj).should == 2 * 10**100
+ end
+
+ it "calls to_i on an object whose to_int returns nil" do
+ obj = mock("object")
+ obj.should_receive(:to_int).and_return(nil)
+ obj.should_receive(:to_i).and_return(1)
+ Integer(obj).should == 1
+ end
+
+ it "raises a TypeError if to_i returns a value that is not an Integer" do
+ obj = mock("object")
+ obj.should_receive(:to_i).and_return("1")
+ -> {
+ Integer(obj)
+ }.should raise_consistent_error(TypeError, "can't convert MockObject into Integer (MockObject#to_i gives String)")
+ end
+
+ it "raises a TypeError if no to_int or to_i methods exist" do
+ obj = mock("object")
+ -> {
+ Integer(obj)
+ }.should.raise(TypeError, "can't convert MockObject into Integer")
+ end
+
+ it "raises a TypeError if to_int returns nil and no to_i exists" do
+ obj = mock("object")
+ obj.should_receive(:to_i).and_return(nil)
+ -> {
+ Integer(obj)
+ }.should raise_consistent_error(TypeError, "can't convert MockObject into Integer (MockObject#to_i gives nil)")
+ end
+
+ it "raises a FloatDomainError when passed NaN" do
+ -> { Integer(nan_value) }.should.raise(FloatDomainError)
+ end
+
+ it "raises a FloatDomainError when passed Infinity" do
+ -> { Integer(infinity_value) }.should.raise(FloatDomainError)
+ end
+
+ describe "when passed exception: false" do
+ describe "and to_i returns a value that is not an Integer" do
+ it "swallows an error" do
+ obj = mock("object")
+ obj.should_receive(:to_i).and_return("1")
+ Integer(obj, exception: false).should == nil
+ end
+ end
+
+ describe "and no to_int or to_i methods exist" do
+ it "swallows an error" do
+ obj = mock("object")
+ Integer(obj, exception: false).should == nil
+ end
+ end
+
+ describe "and to_int returns nil and no to_i exists" do
+ it "swallows an error" do
+ obj = mock("object")
+ obj.should_receive(:to_i).and_return(nil)
+ Integer(obj, exception: false).should == nil
+ end
+ end
+
+ describe "and passed NaN" do
+ it "swallows an error" do
+ Integer(nan_value, exception: false).should == nil
+ end
+ end
+
+ describe "and passed Infinity" do
+ it "swallows an error" do
+ Integer(infinity_value, exception: false).should == nil
+ end
+ end
+
+ describe "and passed nil" do
+ it "swallows an error" do
+ Integer(nil, exception: false).should == nil
+ end
+ end
+
+ describe "and passed a String that contains numbers" do
+ it "normally parses it and returns an Integer" do
+ Integer("42", exception: false).should == 42
+ end
+ end
+
+ describe "and passed a String that can't be converted to an Integer" do
+ it "swallows an error" do
+ Integer("abc", exception: false).should == nil
+ end
+ end
+ end
+end
+
+describe :kernel_integer_string, shared: true do
+ it "raises an ArgumentError if the String is a null byte" do
+ -> { Integer("\0") }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError if the String starts with a null byte" do
+ -> { Integer("\01") }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError if the String ends with a null byte" do
+ -> { Integer("1\0") }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError if the String contains a null byte" do
+ -> { Integer("1\01") }.should.raise(ArgumentError)
+ end
+
+ it "ignores leading whitespace" do
+ Integer(" 1").should == 1
+ Integer(" 1").should == 1
+ Integer("\t\n1").should == 1
+ end
+
+ it "ignores trailing whitespace" do
+ Integer("1 ").should == 1
+ Integer("1 ").should == 1
+ Integer("1\t\n").should == 1
+ end
+
+ it "raises an ArgumentError if there are leading _s" do
+ -> { Integer("_1") }.should.raise(ArgumentError)
+ -> { Integer("___1") }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError if there are trailing _s" do
+ -> { Integer("1_") }.should.raise(ArgumentError)
+ -> { Integer("1___") }.should.raise(ArgumentError)
+ end
+
+ it "ignores an embedded _" do
+ Integer("1_1").should == 11
+ end
+
+ it "raises an ArgumentError if there are multiple embedded _s" do
+ -> { Integer("1__1") }.should.raise(ArgumentError)
+ -> { Integer("1___1") }.should.raise(ArgumentError)
+ end
+
+ it "ignores a single leading +" do
+ Integer("+1").should == 1
+ end
+
+ it "raises an ArgumentError if there is a space between the + and number" do
+ -> { Integer("+ 1") }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError if there are multiple leading +s" do
+ -> { Integer("++1") }.should.raise(ArgumentError)
+ -> { Integer("+++1") }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError if there are trailing +s" do
+ -> { Integer("1+") }.should.raise(ArgumentError)
+ -> { Integer("1+++") }.should.raise(ArgumentError)
+ end
+
+ it "makes the number negative if there's a leading -" do
+ Integer("-1").should == -1
+ end
+
+ it "raises an ArgumentError if there are multiple leading -s" do
+ -> { Integer("--1") }.should.raise(ArgumentError)
+ -> { Integer("---1") }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError if there are trailing -s" do
+ -> { Integer("1-") }.should.raise(ArgumentError)
+ -> { Integer("1---") }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError if there is a period" do
+ -> { Integer("0.0") }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError for an empty String" do
+ -> { Integer("") }.should.raise(ArgumentError)
+ end
+
+ describe "when passed exception: false" do
+ describe "and multiple leading -s" do
+ it "swallows an error" do
+ Integer("---1", exception: false).should == nil
+ end
+ end
+
+ describe "and multiple trailing -s" do
+ it "swallows an error" do
+ Integer("1---", exception: false).should == nil
+ end
+ end
+
+ describe "and an argument that contains a period" do
+ it "swallows an error" do
+ Integer("0.0", exception: false).should == nil
+ end
+ end
+
+ describe "and an empty string" do
+ it "swallows an error" do
+ Integer("", exception: false).should == nil
+ end
+ end
+ end
+
+ it "parses the value as 0 if the string consists of a single zero character" do
+ Integer("0").should == 0
+ end
+
+ %w(x X).each do |x|
+ it "parses the value as a hex number if there's a leading 0#{x}" do
+ Integer("0#{x}1").should == 0x1
+ Integer("0#{x}dd").should == 0xdd
+ end
+
+ it "is a positive hex number if there's a leading +0#{x}" do
+ Integer("+0#{x}1").should == 0x1
+ Integer("+0#{x}dd").should == 0xdd
+ end
+
+ it "is a negative hex number if there's a leading -0#{x}" do
+ Integer("-0#{x}1").should == -0x1
+ Integer("-0#{x}dd").should == -0xdd
+ end
+
+ it "raises an ArgumentError if the number cannot be parsed as hex" do
+ -> { Integer("0#{x}g") }.should.raise(ArgumentError)
+ end
+ end
+
+ %w(b B).each do |b|
+ it "parses the value as a binary number if there's a leading 0#{b}" do
+ Integer("0#{b}1").should == 0b1
+ Integer("0#{b}10").should == 0b10
+ end
+
+ it "is a positive binary number if there's a leading +0#{b}" do
+ Integer("+0#{b}1").should == 0b1
+ Integer("+0#{b}10").should == 0b10
+ end
+
+ it "is a negative binary number if there's a leading -0#{b}" do
+ Integer("-0#{b}1").should == -0b1
+ Integer("-0#{b}10").should == -0b10
+ end
+
+ it "raises an ArgumentError if the number cannot be parsed as binary" do
+ -> { Integer("0#{b}2") }.should.raise(ArgumentError)
+ end
+ end
+
+ ["o", "O", ""].each do |o|
+ it "parses the value as an octal number if there's a leading 0#{o}" do
+ Integer("0#{o}1").should == 0O1
+ Integer("0#{o}10").should == 0O10
+ end
+
+ it "is a positive octal number if there's a leading +0#{o}" do
+ Integer("+0#{o}1").should == 0O1
+ Integer("+0#{o}10").should == 0O10
+ end
+
+ it "is a negative octal number if there's a leading -0#{o}" do
+ Integer("-0#{o}1").should == -0O1
+ Integer("-0#{o}10").should == -0O10
+ end
+
+ it "raises an ArgumentError if the number cannot be parsed as octal" do
+ -> { Integer("0#{o}9") }.should.raise(ArgumentError)
+ end
+ end
+
+ %w(D d).each do |d|
+ it "parses the value as a decimal number if there's a leading 0#{d}" do
+ Integer("0#{d}1").should == 1
+ Integer("0#{d}10").should == 10
+ end
+
+ it "is a positive decimal number if there's a leading +0#{d}" do
+ Integer("+0#{d}1").should == 1
+ Integer("+0#{d}10").should == 10
+ end
+
+ it "is a negative decimal number if there's a leading -0#{d}" do
+ Integer("-0#{d}1").should == -1
+ Integer("-0#{d}10").should == -10
+ end
+
+ it "raises an ArgumentError if the number cannot be parsed as decimal" do
+ -> { Integer("0#{d}a") }.should.raise(ArgumentError)
+ end
+ end
+end
+
+describe :kernel_integer_string_base, shared: true do
+ it "raises an ArgumentError if the String is a null byte" do
+ -> { Integer("\0", 2) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError if the String starts with a null byte" do
+ -> { Integer("\01", 3) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError if the String ends with a null byte" do
+ -> { Integer("1\0", 4) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError if the String contains a null byte" do
+ -> { Integer("1\01", 5) }.should.raise(ArgumentError)
+ end
+
+ it "ignores leading whitespace" do
+ Integer(" 16", 16).should == 22
+ Integer(" 16", 16).should == 22
+ Integer("\t\n16", 16).should == 22
+ end
+
+ it "ignores trailing whitespace" do
+ Integer("16 ", 16).should == 22
+ Integer("16 ", 16).should == 22
+ Integer("16\t\n", 16).should == 22
+ end
+
+ it "raises an ArgumentError if there are leading _s" do
+ -> { Integer("_1", 7) }.should.raise(ArgumentError)
+ -> { Integer("___1", 7) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError if there are trailing _s" do
+ -> { Integer("1_", 12) }.should.raise(ArgumentError)
+ -> { Integer("1___", 12) }.should.raise(ArgumentError)
+ end
+
+ it "ignores an embedded _" do
+ Integer("1_1", 4).should == 5
+ end
+
+ it "raises an ArgumentError if there are multiple embedded _s" do
+ -> { Integer("1__1", 4) }.should.raise(ArgumentError)
+ -> { Integer("1___1", 4) }.should.raise(ArgumentError)
+ end
+
+ it "ignores a single leading +" do
+ Integer("+10", 3).should == 3
+ end
+
+ it "raises an ArgumentError if there is a space between the + and number" do
+ -> { Integer("+ 1", 3) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError if there are multiple leading +s" do
+ -> { Integer("++1", 3) }.should.raise(ArgumentError)
+ -> { Integer("+++1", 3) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError if there are trailing +s" do
+ -> { Integer("1+", 3) }.should.raise(ArgumentError)
+ -> { Integer("1+++", 12) }.should.raise(ArgumentError)
+ end
+
+ it "makes the number negative if there's a leading -" do
+ Integer("-19", 20).should == -29
+ end
+
+ it "raises an ArgumentError if there are multiple leading -s" do
+ -> { Integer("--1", 9) }.should.raise(ArgumentError)
+ -> { Integer("---1", 9) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError if there are trailing -s" do
+ -> { Integer("1-", 12) }.should.raise(ArgumentError)
+ -> { Integer("1---", 12) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError if there is a period" do
+ -> { Integer("0.0", 3) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError for an empty String" do
+ -> { Integer("", 12) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError for a base of 1" do
+ -> { Integer("1", 1) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError for a base of 37" do
+ -> { Integer("1", 37) }.should.raise(ArgumentError)
+ end
+
+ it "accepts wholly lowercase alphabetic strings for bases > 10" do
+ Integer('ab',12).should == 131
+ Integer('af',20).should == 215
+ Integer('ghj',30).should == 14929
+ end
+
+ it "accepts wholly uppercase alphabetic strings for bases > 10" do
+ Integer('AB',12).should == 131
+ Integer('AF',20).should == 215
+ Integer('GHJ',30).should == 14929
+ end
+
+ it "accepts mixed-case alphabetic strings for bases > 10" do
+ Integer('Ab',12).should == 131
+ Integer('aF',20).should == 215
+ Integer('GhJ',30).should == 14929
+ end
+
+ it "accepts alphanumeric strings for bases > 10" do
+ Integer('a3e',19).should == 3681
+ Integer('12q',31).should == 1049
+ Integer('c00o',29).should == 292692
+ end
+
+ it "raises an ArgumentError for letters invalid in the given base" do
+ -> { Integer('z',19) }.should.raise(ArgumentError)
+ -> { Integer('c00o',2) }.should.raise(ArgumentError)
+ end
+
+ %w(x X).each do |x|
+ it "parses the value as a hex number if there's a leading 0#{x} and a base of 16" do
+ Integer("0#{x}10", 16).should == 16
+ Integer("0#{x}dd", 16).should == 221
+ end
+
+ it "is a positive hex number if there's a leading +0#{x} and base of 16" do
+ Integer("+0#{x}1", 16).should == 0x1
+ Integer("+0#{x}dd", 16).should == 0xdd
+ end
+
+ it "is a negative hex number if there's a leading -0#{x} and a base of 16" do
+ Integer("-0#{x}1", 16).should == -0x1
+ Integer("-0#{x}dd", 16).should == -0xdd
+ end
+
+ 2.upto(15) do |base|
+ it "raises an ArgumentError if the number begins with 0#{x} and the base is #{base}" do
+ -> { Integer("0#{x}1", base) }.should.raise(ArgumentError)
+ end
+ end
+
+ it "raises an ArgumentError if the number cannot be parsed as hex and the base is 16" do
+ -> { Integer("0#{x}g", 16) }.should.raise(ArgumentError)
+ end
+ end
+
+ %w(b B).each do |b|
+ it "parses the value as a binary number if there's a leading 0#{b} and the base is 2" do
+ Integer("0#{b}1", 2).should == 0b1
+ Integer("0#{b}10", 2).should == 0b10
+ end
+
+ it "is a positive binary number if there's a leading +0#{b} and a base of 2" do
+ Integer("+0#{b}1", 2).should == 0b1
+ Integer("+0#{b}10", 2).should == 0b10
+ end
+
+ it "is a negative binary number if there's a leading -0#{b} and a base of 2" do
+ Integer("-0#{b}1", 2).should == -0b1
+ Integer("-0#{b}10", 2).should == -0b10
+ end
+
+ it "raises an ArgumentError if the number cannot be parsed as binary and the base is 2" do
+ -> { Integer("0#{b}2", 2) }.should.raise(ArgumentError)
+ end
+ end
+
+ ["o", "O"].each do |o|
+ it "parses the value as an octal number if there's a leading 0#{o} and a base of 8" do
+ Integer("0#{o}1", 8).should == 0O1
+ Integer("0#{o}10", 8).should == 0O10
+ end
+
+ it "is a positive octal number if there's a leading +0#{o} and a base of 8" do
+ Integer("+0#{o}1", 8).should == 0O1
+ Integer("+0#{o}10", 8).should == 0O10
+ end
+
+ it "is a negative octal number if there's a leading -0#{o} and a base of 8" do
+ Integer("-0#{o}1", 8).should == -0O1
+ Integer("-0#{o}10", 8).should == -0O10
+ end
+
+ it "raises an ArgumentError if the number cannot be parsed as octal and the base is 8" do
+ -> { Integer("0#{o}9", 8) }.should.raise(ArgumentError)
+ end
+
+ 2.upto(7) do |base|
+ it "raises an ArgumentError if the number begins with 0#{o} and the base is #{base}" do
+ -> { Integer("0#{o}1", base) }.should.raise(ArgumentError)
+ end
+ end
+ end
+
+ %w(D d).each do |d|
+ it "parses the value as a decimal number if there's a leading 0#{d} and a base of 10" do
+ Integer("0#{d}1", 10).should == 1
+ Integer("0#{d}10",10).should == 10
+ end
+
+ it "is a positive decimal number if there's a leading +0#{d} and a base of 10" do
+ Integer("+0#{d}1", 10).should == 1
+ Integer("+0#{d}10", 10).should == 10
+ end
+
+ it "is a negative decimal number if there's a leading -0#{d} and a base of 10" do
+ Integer("-0#{d}1", 10).should == -1
+ Integer("-0#{d}10", 10).should == -10
+ end
+
+ it "raises an ArgumentError if the number cannot be parsed as decimal and the base is 10" do
+ -> { Integer("0#{d}a", 10) }.should.raise(ArgumentError)
+ end
+
+ 2.upto(9) do |base|
+ it "raises an ArgumentError if the number begins with 0#{d} and the base is #{base}" do
+ -> { Integer("0#{d}1", base) }.should.raise(ArgumentError)
+ end
+ end
+ end
+
+ it "raises an ArgumentError if a base is given for a non-String value" do
+ -> { Integer(98, 15) }.should.raise(ArgumentError, "base specified for non string value")
+ end
+
+ it "tries to convert the base to an integer using to_int" do
+ obj = mock('8')
+ obj.should_receive(:to_int).and_return(8)
+
+ Integer("777", obj).should == 0777
+ end
+
+ it "raises a TypeError if it is not an integer and does not respond to #to_i" do
+ -> {
+ Integer("777", "8")
+ }.should.raise(TypeError, "no implicit conversion of String into Integer")
+ end
+
+ describe "when passed exception: false" do
+ describe "and valid argument" do
+ it "returns an Integer number" do
+ Integer("100", 10, exception: false).should == 100
+ Integer("100", 2, exception: false).should == 4
+ end
+ end
+
+ describe "and invalid argument" do
+ it "swallows an error" do
+ Integer("999", 2, exception: false).should == nil
+ Integer("abc", 10, exception: false).should == nil
+ end
+ end
+ end
+end
+
+describe :kernel_Integer, shared: true do
+ it "raises an ArgumentError when the String contains digits out of range of radix 2" do
+ str = "23456789abcdefghijklmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 2) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 3" do
+ str = "3456789abcdefghijklmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 3) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 4" do
+ str = "456789abcdefghijklmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 4) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 5" do
+ str = "56789abcdefghijklmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 5) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 6" do
+ str = "6789abcdefghijklmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 6) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 7" do
+ str = "789abcdefghijklmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 7) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 8" do
+ str = "89abcdefghijklmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 8) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 9" do
+ str = "9abcdefghijklmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 9) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 10" do
+ str = "abcdefghijklmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 10) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 11" do
+ str = "bcdefghijklmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 11) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 12" do
+ str = "cdefghijklmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 12) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 13" do
+ str = "defghijklmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 13) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 14" do
+ str = "efghijklmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 14) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 15" do
+ str = "fghijklmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 15) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 16" do
+ str = "ghijklmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 16) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 17" do
+ str = "hijklmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 17) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 18" do
+ str = "ijklmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 18) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 19" do
+ str = "jklmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 19) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 20" do
+ str = "klmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 20) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 21" do
+ str = "lmnopqrstuvwxyz"
+ -> { @object.send(@method, str, 21) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 22" do
+ str = "mnopqrstuvwxyz"
+ -> { @object.send(@method, str, 22) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 23" do
+ str = "nopqrstuvwxyz"
+ -> { @object.send(@method, str, 23) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 24" do
+ str = "opqrstuvwxyz"
+ -> { @object.send(@method, str, 24) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 25" do
+ str = "pqrstuvwxyz"
+ -> { @object.send(@method, str, 25) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 26" do
+ str = "qrstuvwxyz"
+ -> { @object.send(@method, str, 26) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 27" do
+ str = "rstuvwxyz"
+ -> { @object.send(@method, str, 27) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 28" do
+ str = "stuvwxyz"
+ -> { @object.send(@method, str, 28) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 29" do
+ str = "tuvwxyz"
+ -> { @object.send(@method, str, 29) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 30" do
+ str = "uvwxyz"
+ -> { @object.send(@method, str, 30) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 31" do
+ str = "vwxyz"
+ -> { @object.send(@method, str, 31) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 32" do
+ str = "wxyz"
+ -> { @object.send(@method, str, 32) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 33" do
+ str = "xyz"
+ -> { @object.send(@method, str, 33) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 34" do
+ str = "yz"
+ -> { @object.send(@method, str, 34) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 35" do
+ str = "z"
+ -> { @object.send(@method, str, 35) }.should.raise(ArgumentError)
+ end
+
+ it "raises an ArgumentError when the String contains digits out of range of radix 36" do
+ -> { @object.send(@method, "{", 36) }.should.raise(ArgumentError)
+ end
+end
+
+describe "Kernel.Integer" do
+ it_behaves_like :kernel_Integer, :Integer_method, KernelSpecs
+
+ # TODO: fix these specs
+ it_behaves_like :kernel_integer, :Integer, Kernel
+ it_behaves_like :kernel_integer_string, :Integer
+
+ it_behaves_like :kernel_integer_string_base, :Integer
+
+ it "is a public method" do
+ Kernel.Integer(10).should == 10
+ end
+end
+
+describe "Kernel#Integer" do
+ it_behaves_like :kernel_Integer, :Integer_function, KernelSpecs
+
+ # TODO: fix these specs
+ it_behaves_like :kernel_integer, :Integer, Object.new
+ it_behaves_like :kernel_integer_string, :Integer
+
+ it_behaves_like :kernel_integer_string_base, :Integer
+
+ it "is a private method" do
+ Kernel.private_instance_methods(false).should.include?(:Integer)
+ end
+end
cbfebc626c7dac89'>test/rubygems/test_gem_package.rb824
-rw-r--r--test/rubygems/test_gem_package_old.rb89
-rw-r--r--test/rubygems/test_gem_package_tar_header.rb146
-rw-r--r--test/rubygems/test_gem_package_tar_reader.rb89
-rw-r--r--test/rubygems/test_gem_package_tar_reader_entry.rb134
-rw-r--r--test/rubygems/test_gem_package_tar_writer.rb250
-rw-r--r--test/rubygems/test_gem_package_task.rb80
-rw-r--r--test/rubygems/test_gem_path_support.rb84
-rw-r--r--test/rubygems/test_gem_platform.rb296
-rw-r--r--test/rubygems/test_gem_rdoc.rb269
-rw-r--r--test/rubygems/test_gem_remote_fetcher.rb919
-rw-r--r--test/rubygems/test_gem_request.rb362
-rw-r--r--test/rubygems/test_gem_request_connection_pools.rb120
-rw-r--r--test/rubygems/test_gem_request_set.rb597
-rw-r--r--test/rubygems/test_gem_request_set_gem_dependency_api.rb814
-rw-r--r--test/rubygems/test_gem_request_set_lockfile.rb1238
-rw-r--r--test/rubygems/test_gem_requirement.rb376
-rw-r--r--test/rubygems/test_gem_resolver.rb733
-rw-r--r--test/rubygems/test_gem_resolver_activation_request.rb73
-rw-r--r--test/rubygems/test_gem_resolver_api_set.rb208
-rw-r--r--test/rubygems/test_gem_resolver_api_specification.rb144
-rw-r--r--test/rubygems/test_gem_resolver_best_set.rb137
-rw-r--r--test/rubygems/test_gem_resolver_composed_set.rb45
-rw-r--r--test/rubygems/test_gem_resolver_conflict.rb87
-rw-r--r--test/rubygems/test_gem_resolver_dependency_request.rb84
-rw-r--r--test/rubygems/test_gem_resolver_git_set.rb189
-rw-r--r--test/rubygems/test_gem_resolver_git_specification.rb112
-rw-r--r--test/rubygems/test_gem_resolver_index_set.rb89
-rw-r--r--test/rubygems/test_gem_resolver_index_specification.rb89
-rw-r--r--test/rubygems/test_gem_resolver_installed_specification.rb49
-rw-r--r--test/rubygems/test_gem_resolver_installer_set.rb247
-rw-r--r--test/rubygems/test_gem_resolver_local_specification.rb45
-rw-r--r--test/rubygems/test_gem_resolver_lock_set.rb63
-rw-r--r--test/rubygems/test_gem_resolver_lock_specification.rb98
-rw-r--r--test/rubygems/test_gem_resolver_requirement_list.rb20
-rw-r--r--test/rubygems/test_gem_resolver_specification.rb64
-rw-r--r--test/rubygems/test_gem_resolver_vendor_set.rb83
-rw-r--r--test/rubygems/test_gem_resolver_vendor_specification.rb83
-rw-r--r--test/rubygems/test_gem_security.rb306
-rw-r--r--test/rubygems/test_gem_security_policy.rb540
-rw-r--r--test/rubygems/test_gem_security_signer.rb208
-rw-r--r--test/rubygems/test_gem_security_trust_dir.rb98
-rw-r--r--test/rubygems/test_gem_server.rb404
-rw-r--r--test/rubygems/test_gem_silent_ui.rb116
-rw-r--r--test/rubygems/test_gem_source.rb227
-rw-r--r--test/rubygems/test_gem_source_fetch_problem.rb19
-rw-r--r--test/rubygems/test_gem_source_git.rb297
-rw-r--r--test/rubygems/test_gem_source_installed.rb36
-rw-r--r--test/rubygems/test_gem_source_list.rb111
-rw-r--r--test/rubygems/test_gem_source_local.rb106
-rw-r--r--test/rubygems/test_gem_source_lock.rb114
-rw-r--r--test/rubygems/test_gem_source_specific_file.rb75
-rw-r--r--test/rubygems/test_gem_source_vendor.rb31
-rw-r--r--test/rubygems/test_gem_spec_fetcher.rb310
-rw-r--r--test/rubygems/test_gem_specification.rb3089
-rw-r--r--test/rubygems/test_gem_stream_ui.rb238
-rw-r--r--test/rubygems/test_gem_stub_specification.rb191
-rw-r--r--test/rubygems/test_gem_text.rb58
-rw-r--r--test/rubygems/test_gem_uninstaller.rb483
-rw-r--r--test/rubygems/test_gem_unsatisfiable_dependency_error.rb32
-rw-r--r--test/rubygems/test_gem_uri_formatter.rb28
-rw-r--r--test/rubygems/test_gem_util.rb31
-rw-r--r--test/rubygems/test_gem_validator.rb45
-rw-r--r--test/rubygems/test_gem_version.rb213
-rw-r--r--test/rubygems/test_gem_version_option.rb151
-rw-r--r--test/rubygems/test_kernel.rb61
-rw-r--r--test/rubygems/test_require.rb275
-rw-r--r--test/rubygems/wrong_key_cert.pem18
-rw-r--r--test/rubygems/wrong_key_cert_32.pem18
174 files changed, 33052 insertions, 0 deletions
diff --git a/test/rubygems/alternate_cert.pem b/test/rubygems/alternate_cert.pem
new file mode 100644
index 0000000000..a5a82910d9
--- /dev/null
+++ b/test/rubygems/alternate_cert.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC9zCCAd+gAwIBAgIBADANBgkqhkiG9w0BAQUFADAtMRIwEAYDVQQDDAlhbHRl
+cm5hdGUxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTEyMTIwODAwMDAwMFoY
+Dzk5OTkxMjMxMjM1OTU5WjAtMRIwEAYDVQQDDAlhbHRlcm5hdGUxFzAVBgoJkiaJ
+k/IsZAEZFgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
+vZQipBa1xH3M9OonkrUYhGZeX9UHAcJhe6jJbUr/uHXkh1Tu2ERWNnblm85upqBf
+jyZEnKer7uBcwwkkvmisVgC8uBECymsBxuEIw0rfiKYEnLu0B6SiWFYz3dYPS92b
+BK7Vks2/kNyXUmLLGoZ3id2K0eK5C/AJ0j+p84OqPnVhylsjrZmXfIZrh7lkHhgC
+IrzPefjE3pOloi/tz6fh2ktb0FYKQMfweT3Ba2TMeflG13PEOW80AD5w0THxDutG
+G0zPNCDyDEoT7UU1a3B3RMHYuUxEk1GUEYWq9L6a6SMpZISWTSpCp0Ww1QB55PON
+iCCn+o6vcIy46jI71dATAQIDAQABoyAwHjAcBgNVHREEFTATgRFhbHRlcm5hdGVA
+ZXhhbXBsZTANBgkqhkiG9w0BAQUFAAOCAQEAtiOe4Ws0hQdxlPCHcngMoWeWMg/d
+EtYHy1vD9oTOEGax6y319ShFNzCTG5Mk9dVXdVTrwml9+SrqmLbcckzr05TpSq3t
+JcNjx+qMwU31655DY+r2Le1mbrhhXilLJ++KjhaIzeqmA55MFLNBdMrApL0v2Tf9
+e9aiL8W8jXPX24uJd5eaFTsPV3NfcYV/iDyf1zv2Fe3NO8e0V1luQxJd3v+ILlRo
+YAkm2DK83G++YkvgsopRdOFfFsY3Gb6XtL87iGOWRbdNK90pThpfORcKoTus7QLx
+l7vsHsOJF5NZwLiBF9ufKH6fUV3Fy25JwB/z8kR8Bkplcl0F8jpJYrd6NQ==
+-----END CERTIFICATE-----
diff --git a/test/rubygems/alternate_cert_32.pem b/test/rubygems/alternate_cert_32.pem
new file mode 100644
index 0000000000..6ef8999ee7
--- /dev/null
+++ b/test/rubygems/alternate_cert_32.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC9TCCAd2gAwIBAgIBATANBgkqhkiG9w0BAQUFADAtMRIwEAYDVQQDDAlhbHRl
+cm5hdGUxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTEyMTIwODAwMDAwMFoX
+DTM4MDExOTAzMTQwN1owLTESMBAGA1UEAwwJYWx0ZXJuYXRlMRcwFQYKCZImiZPy
+LGQBGRYHZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL2U
+IqQWtcR9zPTqJ5K1GIRmXl/VBwHCYXuoyW1K/7h15IdU7thEVjZ25ZvObqagX48m
+RJynq+7gXMMJJL5orFYAvLgRAsprAcbhCMNK34imBJy7tAekolhWM93WD0vdmwSu
+1ZLNv5Dcl1JiyxqGd4nditHiuQvwCdI/qfODqj51YcpbI62Zl3yGa4e5ZB4YAiK8
+z3n4xN6TpaIv7c+n4dpLW9BWCkDH8Hk9wWtkzHn5RtdzxDlvNAA+cNEx8Q7rRhtM
+zzQg8gxKE+1FNWtwd0TB2LlMRJNRlBGFqvS+mukjKWSElk0qQqdFsNUAeeTzjYgg
+p/qOr3CMuOoyO9XQEwECAwEAAaMgMB4wHAYDVR0RBBUwE4ERYWx0ZXJuYXRlQGV4
+YW1wbGUwDQYJKoZIhvcNAQEFBQADggEBABB+jdfwANRtIQKCvv+1VnYm+3QSfshy
+TI5Kk50TphheDJ7VbYyTmOxPUTsFzn0cX8zD1jBOtdVdyy6u7qUHOw6ZrDKdgg4I
+95lJJibFrVXeazTByHhe31u08lMfp/6kdYwSornHUWmEHhAT60nvSbkLblW/jgPo
+i1pFY5hcGJAE6kFQLQpjgl8TbUTioA8wYOKJA5ITItBXO7fYMQKDS2jYR3JMiNLR
+FxgN8SzSUB0S7deI5O9fMLYL006zHP5u0qcZjVFvFJdtt3WsqDUu8E6O4QgVwvq1
+MPNUBfuNdMek1LnIUZgr7Jek+0wvbnZCGyEaVakcV74cq8fjEgWr3C0=
+-----END CERTIFICATE-----
diff --git a/test/rubygems/alternate_key.pem b/test/rubygems/alternate_key.pem
new file mode 100644
index 0000000000..14ca734aba
--- /dev/null
+++ b/test/rubygems/alternate_key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAvZQipBa1xH3M9OonkrUYhGZeX9UHAcJhe6jJbUr/uHXkh1Tu
+2ERWNnblm85upqBfjyZEnKer7uBcwwkkvmisVgC8uBECymsBxuEIw0rfiKYEnLu0
+B6SiWFYz3dYPS92bBK7Vks2/kNyXUmLLGoZ3id2K0eK5C/AJ0j+p84OqPnVhylsj
+rZmXfIZrh7lkHhgCIrzPefjE3pOloi/tz6fh2ktb0FYKQMfweT3Ba2TMeflG13PE
+OW80AD5w0THxDutGG0zPNCDyDEoT7UU1a3B3RMHYuUxEk1GUEYWq9L6a6SMpZISW
+TSpCp0Ww1QB55PONiCCn+o6vcIy46jI71dATAQIDAQABAoIBAArXgfOoaNTH7QTE
+r2awfKp1wEfywufS2ghcasiZVW6TL3Kd5NrxbYzH1/HFKIbW/SAOrDXZUPfkVOnC
+iBtrmQ+CE0jjkClLXVqmW/3vNkF2XSUphu44+B/dLjItn8pS7h6icQxoP+Bk/TJ0
++/CUaBm2Vc4TDUolfCpOAcYvbXkM3BL+N/XN2JHX52D2ljXtryrNm/sFnabUVo96
+ghWqln8TqpYTagcs/JkEQ5YxwqFuBLofz3SgzCnf8ub8WTIpYhWzWZ4yHjZSL7AS
+54mkJarKWMUYcL/Qeuy1U9vxLrbC9V7cPzSkzYxPZF7XlYaJcAbItX182ufZ1uNX
+3JlQS5ECgYEA+6fbg+WKy5AazEs8YokPjq1X1P01o95KUWFg+68ALowQXEYcExew
+PG0BKW11WrR6Bnn41++13k8Qsrq7Tl8ynCO6ANhoWAxUksdJDAuEgQqpFuRXwa/D
+d++8WlWD4XYqLwiE+h72alE/Ce/SdfPPsyBeHtXo7fih378WyZn7K9cCgYEAwNnw
+zjndLtj9bxd4awHHWgQ7QpKCmtLMGlg7Teo9aODMO80G3h8NEEG6Ou6LHn88tqgH
+yu0WcjJmhINAzNzmABdw+WuV4C94glwtXctQ0w4byuLOaKSh3ggWUnKf56A2KyPh
+JHPe/+A1DTKAgBvU/i5Vx0kZBkUMiiEVcIOgHOcCgYBNkt6998IjIdbA5uhET4+2
+IYUTqMIiM2GhWG026CkcMBzS9OGumPzAg7F5/b3RKhT7bhnhJolfb+vrzFf0vq+x
+JeouXIc9rP9dB4Vi6yH7TTf2UIkksXOFwybCid3PYEd8nBmxqF25RDY0b/LmXTPH
+OdEJnFLjGGN9vz/dAVRFnQKBgQC8hE8hSO8uHG+haRANim+VTw2exhllvypFlnpi
+b9gX7ae3zXQpLbFXcujZMtZLuZVf+GGlvJ10hFAyuRtfJ5CuBjwplUGtJLpotDKk
+vVsE9YW1joC3SjfxE3a+oc4uXi6VfT1YpOwYtNMnU3bJxGsxDZpMdOhBeL4JSM3s
+br7VgQKBgBDdJHRQOkP41Iq7CjcheTJMeXsQJt+HLHSIpEkxi8v/9bLKPbRVRo7e
+8mmEr9mvjrNLVZMrQpgngRGbFzcdi9iDv+4m0OKU7BGZyWy1gtlUV77FqsL7EEl3
+gdM670c2kkrni5DdpTLpNgF6zRKK7ArZ6kSgmuEYJCGHHlpbkg3f
+-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/bad_rake.rb b/test/rubygems/bad_rake.rb
new file mode 100644
index 0000000000..379a4c986e
--- /dev/null
+++ b/test/rubygems/bad_rake.rb
@@ -0,0 +1 @@
+exit 1
diff --git a/test/rubygems/bogussources.rb b/test/rubygems/bogussources.rb
new file mode 100644
index 0000000000..008e3a1de5
--- /dev/null
+++ b/test/rubygems/bogussources.rb
@@ -0,0 +1,8 @@
+#--
+# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
+# All rights reserved.
+# See LICENSE.txt for permissions.
+#++
+
+require 'rubygems'
+Gem.use_paths("test/mock/gems")
diff --git a/test/rubygems/ca_cert.pem b/test/rubygems/ca_cert.pem
new file mode 100644
index 0000000000..5207531bc2
--- /dev/null
+++ b/test/rubygems/ca_cert.pem
@@ -0,0 +1,68 @@
+-----BEGIN CERTIFICATE-----
+MIID0DCCArigAwIBAgIBADANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES
+MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X
+DTA0MDEzMDAwNDIzMloXDTM2MDEyMjAwNDIzMlowPDELMAkGA1UEBgwCSlAxEjAQ
+BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQswCQYDVQQDDAJDQTCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANbv0x42BTKFEQOE+KJ2XmiSdZpR
+wjzQLAkPLRnLB98tlzs4xo+y4RyY/rd5TT9UzBJTIhP8CJi5GbS1oXEerQXB3P0d
+L5oSSMwGGyuIzgZe5+vZ1kgzQxMEKMMKlzA73rbMd4Jx3u5+jdbP0EDrPYfXSvLY
+bS04n2aX7zrN3x5KdDrNBfwBio2/qeaaj4+9OxnwRvYP3WOvqdW0h329eMfHw0pi
+JI0drIVdsEqClUV4pebT/F+CPUPkEh/weySgo9wANockkYu5ujw2GbLFcO5LXxxm
+dEfcVr3r6t6zOA4bJwL0W/e6LBcrwiG/qPDFErhwtgTLYf6Er67SzLyA66UCAwEA
+AaOB3DCB2TAPBgNVHRMBAf8EBTADAQH/MDEGCWCGSAGG+EIBDQQkFiJSdWJ5L09w
+ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBRJ7Xd380KzBV7f
+USKIQ+O/vKbhDzAOBgNVHQ8BAf8EBAMCAQYwZAYDVR0jBF0wW4AUSe13d/NCswVe
+31EiiEPjv7ym4Q+hQKQ+MDwxCzAJBgNVBAYMAkpQMRIwEAYDVQQKDAlKSU4uR1Iu
+SlAxDDAKBgNVBAsMA1JSUjELMAkGA1UEAwwCQ0GCAQAwDQYJKoZIhvcNAQEFBQAD
+ggEBAIu/mfiez5XN5tn2jScgShPgHEFJBR0BTJBZF6xCk0jyqNx/g9HMj2ELCuK+
+r/Y7KFW5c5M3AQ+xWW0ZSc4kvzyTcV7yTVIwj2jZ9ddYMN3nupZFgBK1GB4Y05GY
+MJJFRkSu6d/Ph5ypzBVw2YMT/nsOo5VwMUGLgS7YVjU+u/HNWz80J3oO17mNZllj
+PvORJcnjwlroDnS58KoJ7GDgejv3ESWADvX1OHLE4cRkiQGeLoEU4pxdCxXRqX0U
+PbwIkZN9mXVcrmPHq8MWi4eC/V7hnbZETMHuWhUoiNdOEfsAXr3iP4KjyyRdwc7a
+d/xgcK06UVQRL/HbEYGiQL056mc=
+-----END CERTIFICATE-----
+
+-----BEGIN CERTIFICATE-----
+MIIDaDCCAlCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES
+MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X
+DTA0MDEzMDAwNDMyN1oXDTM1MDEyMjAwNDMyN1owPzELMAkGA1UEBgwCSlAxEjAQ
+BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQ4wDAYDVQQDDAVTdWJDQTCC
+ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0Ou7AyRcRXnB/kVHv/6kwe
+ANzgg/DyJfsAUqW90m7Lu1nqyug8gK0RBd77yU0w5HOAMHTVSdpjZK0g2sgx4Mb1
+d/213eL9TTl5MRVEChTvQr8q5DVG/8fxPPE7fMI8eOAzd98/NOAChk+80r4Sx7fC
+kGVEE1bKwY1MrUsUNjOY2d6t3M4HHV3HX1V8ShuKfsHxgCmLzdI8U+5CnQedFgkm
+3e+8tr8IX5RR1wA1Ifw9VadF7OdI/bGMzog/Q8XCLf+WPFjnK7Gcx6JFtzF6Gi4x
+4dp1Xl45JYiVvi9zQ132wu8A1pDHhiNgQviyzbP+UjcB/tsOpzBQF8abYzgEkWEC
+AwEAAaNyMHAwDwYDVR0TAQH/BAUwAwEB/zAxBglghkgBhvhCAQ0EJBYiUnVieS9P
+cGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUlCjXWLsReYzH
+LzsxwVnCXmKoB/owCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCJ/OyN
+rT8Cq2Y+G2yA/L1EMRvvxwFBqxavqaqHl/6rwsIBFlB3zbqGA/0oec6MAVnYynq4
+c4AcHTjx3bQ/S4r2sNTZq0DH4SYbQzIobx/YW8PjQUJt8KQdKMcwwi7arHP7A/Ha
+LKu8eIC2nsUBnP4NhkYSGhbmpJK+PFD0FVtD0ZIRlY/wsnaZNjWWcnWF1/FNuQ4H
+ySjIblqVQkPuzebv3Ror6ZnVDukn96Mg7kP4u6zgxOeqlJGRe1M949SS9Vudjl8X
+SF4aZUUB9pQGhsqQJVqaz2OlhGOp9D0q54xko/rekjAIcuDjl1mdX4F2WRrzpUmZ
+uY/bPeOBYiVsOYVe
+-----END CERTIFICATE-----
+
+-----BEGIN CERTIFICATE-----
+MIIDtTCCAp2gAwIBAgIJANz6ehBcVuuiMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQwHhcNMTMwNTAxMTQ0NTQxWhcNMjMwMzEwMTQ0NTQxWjBF
+MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
+ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
+CgKCAQEAzlpZwhEYoALOEKU4lmMw5l3YI/gadzDOoELtdcidvVvovKK8IIOTDwbA
+3XcjwV0UPGEPOK4Uk1aD0EKkOQVg8ivSre2a3FFGffs2kXck+doJMzAA+pf8tvFk
+QsETVOurOp74GN+er2xbbRSDVxQKq6d+QTe1E60btyXQS5M1Nt5SvLn8dazZJgvv
+3yzJQ1IOQl+xeEO0WVVhPIx5Mx3VtjjcDyl8aewPkYkzia6UOrAyQZnl5sIzWGOb
+kYKCNeKjTPepzlbMx0dN6jBupPYGNB+4FYY9GezInjGbRP5np5382wd3EWwsVzic
+Nau8kXHTL2r7GzNvoy0p//iPCqx9FQIDAQABo4GnMIGkMB0GA1UdDgQWBBS7B027
+H/ZIkW3ngm1SrR0X/aTCwDB1BgNVHSMEbjBsgBS7B027H/ZIkW3ngm1SrR0X/aTC
+wKFJpEcwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV
+BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJANz6ehBcVuuiMAwGA1UdEwQF
+MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAC0glUrUiylTfuOWlwkQvi74oiYC5CzW
+Jfusg6o/Gg1XEuJhaHiYMsK/do16gSc6Za3934rHQbYu3mesyFkCWF9kD4J6/hEO
+OQL8xmmgN7wS6GXy6oIODpny0MgnFrV4gd1aEx69NIfL/wXaM8Gw2sj1TnuGLs8+
+HFmWLRRH3WSR7ZLnqYzPVJwhHu8vtZBL9HZk1J6xyq00Nwi2Cz5WdiHamgaza3TS
+OgBdWwDeSClwhrTJni4d30dbq+eNMByIZ7QNGBQivpFzDxeNV/2UBrTU0CilKG5Q
+j7ZwknfKeA4xUTd8TMK3vKab5JJCfjbXOTHZQsYUcEEGSjOMS8/YVQs=
+-----END CERTIFICATE-----
diff --git a/test/rubygems/child_cert.pem b/test/rubygems/child_cert.pem
new file mode 100644
index 0000000000..3079a9e604
--- /dev/null
+++ b/test/rubygems/child_cert.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC7DCCAdSgAwIBAgIBAjANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTEyMTIwODAwMDAwMFoYDzk5
+OTkxMjMxMjM1OTU5WjApMQ4wDAYDVQQDDAVjaGlsZDEXMBUGCgmSJomT8ixkARkW
+B2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKf7+1q0cR
+MhC/RM6Whpon/5IxuSve3CCxxdN0LcSbUisFMlf28Zj+S545SKFc6gHFcnYLZZsy
+Gm4FWEd4DhNpg/kgoDPuPGwQp2DEOvKnnneB/Shj8V+6oLrjXaZFAu8Q916c5/BL
+z+PlHIIsO/Q865XOK+5z1sZi0xval8QT7u4Usrcy86gevflCbpBAWkNPa/DZDqA9
+nk0vB2XDSHvhavcrYLfDrYAnFz3wiZ70LYQrmdeOqkPpaiw//Qpzqp+vtuF2br6U
+iYWpN+dhdFsIxAwIE5kWZ1kk6OBJ4kHvr+Sh8Oqbf6WFBhW/lQa9wldA0xhNwhGr
+1FDEfC+0g/BvAgMBAAGjHDAaMBgGA1UdEQQRMA+BDWNoaWxkQGV4YW1wbGUwDQYJ
+KoZIhvcNAQEFBQADggEBAGuRKUhUhtmObY00za/qw71wjqtNZad5+k9acM/xh/my
++YEBSlj8ZIWD1H0kUmAO0Pmwab6ziFA8IrAo0N1D897o7eP83KzVeVxoJi1g+8rS
+u16bF7cC5zT9S/N/ZNTVz9ERjRAD7MdcbXEikKPaqjqzZBViClqpO8YQ6Z9bFgXk
+gV9plX1ki17H+EuXNs21gqsy+8NAxTlXKuF5JKriBOQ9XW62496F/yZPw6XQ50My
+R21cOLiDdoXDmS4Wo7bJ+sbR3N1JbhqZ7Wt9DkQnMtXw4xOcFM5PsVIsmn1KhGGp
+v8GAxxUMzFoPvsx+XcV9TWjR1seYlXnvdlx65YYtZg8=
+-----END CERTIFICATE-----
diff --git a/test/rubygems/child_cert_32.pem b/test/rubygems/child_cert_32.pem
new file mode 100644
index 0000000000..35ba720d6c
--- /dev/null
+++ b/test/rubygems/child_cert_32.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC6jCCAdKgAwIBAgIBAzANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTEyMTIwODAwMDAwMFoXDTM4
+MDExOTAzMTQwN1owKTEOMAwGA1UEAwwFY2hpbGQxFzAVBgoJkiaJk/IsZAEZFgdl
+eGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyn+/tatHETIQ
+v0TOloaaJ/+SMbkr3twgscXTdC3Em1IrBTJX9vGY/kueOUihXOoBxXJ2C2WbMhpu
+BVhHeA4TaYP5IKAz7jxsEKdgxDryp553gf0oY/FfuqC6412mRQLvEPdenOfwS8/j
+5RyCLDv0POuVzivuc9bGYtMb2pfEE+7uFLK3MvOoHr35Qm6QQFpDT2vw2Q6gPZ5N
+Lwdlw0h74Wr3K2C3w62AJxc98Ime9C2EK5nXjqpD6WosP/0Kc6qfr7bhdm6+lImF
+qTfnYXRbCMQMCBOZFmdZJOjgSeJB76/kofDqm3+lhQYVv5UGvcJXQNMYTcIRq9RQ
+xHwvtIPwbwIDAQABoxwwGjAYBgNVHREEETAPgQ1jaGlsZEBleGFtcGxlMA0GCSqG
+SIb3DQEBBQUAA4IBAQAzsudxe1TkFtYmCmnT2LVeafo6dVinRJGmdSWeUfNfqRM4
+fgDVg21ym/4Y/bIW3W2lPe9aYNk/leCkh1rewf5XWAQtJTD0+2Ssn/YsxFi62H2l
+RLdDC/t21zG2rNAlYhGc1P4gPFdrqRVkGMYy4Wl6QFBG9U6431NcUKfA+o3uYveh
+8ANbIItQF1FWKGClKeg4FpbPfHRzLtBV+zR8hXX0pxi7Eqwn6IME9jyAoAI2QOqU
+5QVCToPWFFKmn29djnLIq6oG8AS0o1dtiJbyqNgB5yarJFX+P6ym1jvTEmWAzk8v
+N5++ztI1NWdWhtzhEJkJrzRu3Q0yYIPJaJ+mY9vp
+-----END CERTIFICATE-----
diff --git a/test/rubygems/child_key.pem b/test/rubygems/child_key.pem
new file mode 100644
index 0000000000..c56d0699c8
--- /dev/null
+++ b/test/rubygems/child_key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAyn+/tatHETIQv0TOloaaJ/+SMbkr3twgscXTdC3Em1IrBTJX
+9vGY/kueOUihXOoBxXJ2C2WbMhpuBVhHeA4TaYP5IKAz7jxsEKdgxDryp553gf0o
+Y/FfuqC6412mRQLvEPdenOfwS8/j5RyCLDv0POuVzivuc9bGYtMb2pfEE+7uFLK3
+MvOoHr35Qm6QQFpDT2vw2Q6gPZ5NLwdlw0h74Wr3K2C3w62AJxc98Ime9C2EK5nX
+jqpD6WosP/0Kc6qfr7bhdm6+lImFqTfnYXRbCMQMCBOZFmdZJOjgSeJB76/kofDq
+m3+lhQYVv5UGvcJXQNMYTcIRq9RQxHwvtIPwbwIDAQABAoIBAEJkNgerG0bRAlqj
+hZQml35LtbPlwTN1OqbudFCf/NjrzL0Mb3jAZ2fghQTFAlrDQkdpKri73HFF5xKL
+igsbmlO6+EAxJjWSy9998SUFKq+4LfiJduelqLw4nG2VM8Fmn9kRMY0CIm/IvjBM
+84TrNz2OA/SvxKNoJG0cSAKYRao+00s+xNIu8lr6CqvXqnFO6gzbxQvJ0J0TnKVf
+AezArZZI3VaPXmC8yo2U6v9r7/2txr12QnDPDk9YMwJ7OR+7qzujAPvtHy44t4en
+AsTetle9AXveIBC7zpl0pp27wN8tKIdh8n+jxPfES9ecn4FjfreWiwzzZSSCitqQ
+p7cQdTkCgYEA9U/y38KUjV05FO7AeeMJYmy/o3WxjcZF8lUtuCsGzogD0JbnNj7R
+BF9TwlNnkeSJsPYKMG17dnoZhgY3J96mWhQbEH9CyXNdgQladE9/qH9gCCW9BXyo
+z3urNc77F/44J+1OoegpWGS8Hdm7OGsESLF1wLet+5cRbVHtU2brqQMCgYEA01JK
+AnATj+vACcAtr1Gu9eGE/6EqAM+H/bfQzGtqkxEmY8QihW//XWH/vOZDVZZYLUoc
+9MkSUHNGwZ7ESAgoZWc1D5xxp3sT2+vV192TS+QBe3TT5AXhAGH9uL+qz7Gz4ihH
+ebt4p49u5SJVY+3vv+nck/YgEiBw4PrfwSdugSUCgYB86U/XpoH0FaMKSKRTrErM
+BmnytuxJL8vQIJVeMPKPWezvWtey5HuUCWJiEgwr2r5OEIqRrD3wzy2N9D5Dm/kC
+5zf8x4BfidHz8apQjWaIiwuAOo8saxSeSe+dP57V0coQcqLWiJv8+ZZccNEHYl7V
+ER/PmPgLoxnpm40IKeEXtwKBgCwUEAfuJMZyYD4obd8R5LK49ar0jPRaVX1gqBbb
+mQFQJHfO43x93gA2fseCKC1kDMR1nxCYGE/bm7irSznTKcns+y5kbXiHvZ6z1IkQ
+WLcNuhlsRv5bE5Gm3ut4X0KvSFw2FqKXrhUVYAY/YRxU9xtKxo2+WvYs+h6TdbSu
+auhZAoGAThhKJW0Rf+LX1zlVaq+GXrj2rkYVSBwChMHbmmp49q6crldfLi15KbI/
+LRoUwjnQLQVNT0j090/rlNVv+pcQLqZ/pDHXQOMwrYuhbbLsda/FqTo3Qb/XnwHX
+qRrjdgGk5OC3gJt8EaHHdq+ty/eF4xQ0fUPMvIj8fwowxGyextI=
+-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/client.pem b/test/rubygems/client.pem
new file mode 100644
index 0000000000..63a52c574a
--- /dev/null
+++ b/test/rubygems/client.pem
@@ -0,0 +1,49 @@
+-----BEGIN CERTIFICATE-----
+MIIDgTCCAmmgAwIBAgICEAIwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQVUx
+EzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMg
+UHR5IEx0ZDAeFw0xMzA1MDExNTAxMzFaFw0yMzAzMTAxNTAxMzFaMEUxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCw
++lcrpdWcloQCgAlxcM3GjvBxZ3yjzi6SgXKRBSi54i0J1LXxznWKcJ5P/O1+j+7i
+LjHK+OWqsa0+EbKTwSu+0tx20h0z++YJF9GWEoCwT5aH1kor/0+EQLgYnxBaF8GC
+2xAbkRkWmbSu2aLDIey3lg7lqAazYqdS2wH0UjSDjFKDLxz9LwpfFm0yGL3DgwLW
++dobYkgt1A6F/8Pz6D2FjwYKcM8JE6w7KJSJDUvXcv2E18wmhZ/qF/MtFAF4coB1
+f5ALnz8YqY6eyDF5aY/VfaHZvXdirLlMH6/miie9GBVMnJWF0ah5ssbsMvcpmnDJ
+qkiYju2e1oLFEE7zztU/AgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgEN
+BB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBTcOELj
+hSUdiLrdRF3CFZDZkWaGzDAfBgNVHSMEGDAWgBS7B027H/ZIkW3ngm1SrR0X/aTC
+wDANBgkqhkiG9w0BAQUFAAOCAQEAlQMzHlnT6L1qqA4hL6tABPbiMsVwXyKCcfNB
+zBn82Wkxgbg7Mp31fbR6/qvGeXOtaX6IdPdgtVf8nh1NURk0MmFBP+gfnwfNBD+m
+Q1cldDt9kY2LGIrPii40xbugF1/xqEYcZMgXU08aEvQ2IHX46J8wZoqMa2KhrU8/
+mzY0F+UEFOGWtKDgUzz3dyBPsdzVrX+SXULwH0lqZX8Nsw5LyfrlVt3xQvS5Ogm4
+kYlt8kqhF8lUS3WTbuADrIs3NaDPRWSs1iLRRFgosgUtHN7tkrkrVaHeBo0KbAJG
+mMqtxSY0XZI9WBxffP9UtoY3EiTWNVWLtuCN3OSvryP6NDe4BA==
+-----END CERTIFICATE-----
+
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAsPpXK6XVnJaEAoAJcXDNxo7wcWd8o84ukoFykQUoueItCdS1
+8c51inCeT/ztfo/u4i4xyvjlqrGtPhGyk8ErvtLcdtIdM/vmCRfRlhKAsE+Wh9ZK
+K/9PhEC4GJ8QWhfBgtsQG5EZFpm0rtmiwyHst5YO5agGs2KnUtsB9FI0g4xSgy8c
+/S8KXxZtMhi9w4MC1vnaG2JILdQOhf/D8+g9hY8GCnDPCROsOyiUiQ1L13L9hNfM
+JoWf6hfzLRQBeHKAdX+QC58/GKmOnsgxeWmP1X2h2b13Yqy5TB+v5oonvRgVTJyV
+hdGoebLG7DL3KZpwyapImI7tntaCxRBO887VPwIDAQABAoIBAFOpdG3gzlNg3/Ti
+nBQxdEVqKwYhGs3A2UlOwl8F5lPBNPNRx9UQeYZBaMV9VrQezJnFpqpB8Sg5KCGQ
+ci/hAJIL0kalW0LI0Nz5ko10H7u5U/rQ9W1JG0j041JYV32Pf14husKdXBPQA5co
+sQW30tSSrmYogUpp15mWiJz8A3EvqiCTlQv5JwwMFGnjVl8+HNfuLghK/vqY/Eb9
+YmwTKxPFejqN7E0Mud2ylNiuPTSLwBy8UvV9uxOlDc6lMyZjVRO0woiEzrjw5dKF
+yf5tUkICRcPkekcx+XtpGrCMlRLl770bZBZX+YNmbYXVWhFp09cNR+U0KZqPNcDp
+jg73vXECgYEA3huOKzfHGt3qUdMlEHd1FvQhW9fYIrmUSnuVYQJOnY8lFfKfmrOH
+gpwOIHDNiVHYlhAJaNocCLYx4hWHgZXarY7NKxmlY2+Vp8mcCIf2Cw3Kr/sFklUJ
+KpiRxqEPGR7U4C/E31kkH/C+w7m9Zh3ndhltU2Pki9/Eq0lk8YClMMkCgYEAy/vU
+jxzviIk8bll5uCIuXJyCfao7ywaZABbL6a20kdVGKrHj57O/OJ2WZVwBihhB7OS+
+QsKC/J8LrUJkobOFtQvQ8O23uep5rB6kqCkXsXCG4SCl2L5xZySBp/qhiqbuMwvp
+EAWPSIA6UNoR0J2rDYVmq6jtY526wQf5ivE8IccCgYEAphfzJAyNH2FOZixArmS2
+shiUjasG3UjsRRrP5YClK5wtPpF2m2if8KMkyUux2HvVPLr3XmqkxjsBaLFy6QwY
+QOvmL9H45Tg/sP7KaXLLIw8IQLu2OezPcwQvF1u//6gXxyLR1bhClIQjFBjlMuUv
+/xgasl6kPZlz6Cd1jkgGwEkCgYAI1IT2EQWZfn9cM4leXDRvk+LeN8FQ35897r6z
+Be78JSRdcsfv3ssXU1MQXjQ+2x/3dkt6LltnPidOP8KFcXUHSlSoKVI7vRe5SLZO
+BUFeUAW2tygWwt+73Eu0jtfxXZqQISLcq7DxLYPYvifpRPoDotO3+J8WIdzUwFig
+GCNHPwKBgHqXOyRef7ykVUCptMf61/BvNU8NP1f9PkKQBMYQZC39UwqEQ675QBUh
+hSG9t/kyc44zUVmBeKIlWHVyLQ83Dv+ennz/D9t7tstet0VMKvALNdiVT0sjFKN7
+1VINygCeFkqrlTXlOwFcRSo1gHn3/JIrhSgRuYKHSf0GZOcN6d9l
+-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/data/gem-private_key.pem b/test/rubygems/data/gem-private_key.pem
new file mode 100644
index 0000000000..3e4be4cd9a
--- /dev/null
+++ b/test/rubygems/data/gem-private_key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAz0tTOtsJuHDKAEXrQx0f6DUEzBEUTSLR1fk0iEHsY9rDCQxm
+sw5Bf2UnVhdD03B4/XzIK+pat2CMQc37/vLIBuVgS7g/fzatGiM0m5rAHtycr0XU
+8Ek6zjx4iSv70OLjybY+/utHCEc838awGDMCFR21jYxgATPVwqAIyasvwbKh/Vhw
+uErFPqT9G8BKTHsaX+H+ADIRH001OmWkjB6EyjF05114kNMa0+2C7daV9hoBL3md
+hCt6zOGcapl/9LkGxhcNEUB/So16V1ZQldg9macGyWktyNTSfctlF+f8okAmicG3
+XIwaW8UTmjFCmvDs/h1R/uKpe2IOHz87n29d2QIDAQABAoIBAQCR6n/nyg+JmTtX
+/d+hGns/RTLfQpZ7xarXZ9gmoeD4WSE42VXhbIOGXXnXDAFecKl6Jb/xycGZm4if
+OZPM3rEWyZeDNWrc7WvkHiwF7GSYVMqmRg2iJqoSSla+mAtl+pBFiNfHMW6K0Tp0
+erOyFRW+L2+A9/MMZaRun6AP9URkn0jz2kwmMFf+6szmzVn6fPFzZDRI+hEeaDmi
+LBzSrfrddrIBX+xGEoBj6RmfnKBCSUVSSxOauYjd4mVjVYxvMH4SV1hXDUS5GPl5
+MbCiBb7bpNIg/8ljMoRrQiqk0XwwS7MaCqPtMhUtpSmC/zSjAfmoN7AOc/Xh69cQ
+OCMNZH9BAoGBAPBlsuuU6fg0gVTKDdR12jHx03uRRt8/nPxHnpJkZCIh9XKh1LtY
+bkumi9HZpp3mzDiaGg/rwfCwNckKx8NLhICLgkric6ClrKftxTu6C8tBAb5YDi6u
+74KYnV8lMY/unzBtIloPgM3uluS292POmrWZpKwhvHLD71MewzMor5HFAoGBANy/
+mwsBs8i3Gzk8Twjq8effhPpE7kpxhC7bhwmjX3q41EjQWDT8M6xb1P9dRSsCIebi
+kqP1yhl27dJpA8r5WqE/z89xhBvObAGRv41eXxOI0LaH2k5lJQrUeSC+51dy+BEB
+T3GXD4C5ezZHQ8Wz/oL73uikrfhD+AqOZT2YbMEFAoGBAJvWEWpOGm3f+4bvhI+Z
+5lxCG4oa3wqRvj58XvsfQRovUWGCLtlTtgwsZq8enLf3iaOXohV4Czzvva4Z4u1i
+4v5BcbEBo1scixRBOn5BWKvl9C9j/a2dkX3jWQD4p2xaj69gz8f6DNFyPTb+tNhq
+cjgO5YUASZ1MDrSfWIKteULRAoGAZkZv8x2KyofrmQ0UITGZerDYz4t4TA1kDMGx
+QwnqhtVzpXjCJWpkFotFmDsCfPaz9mErR8PtKvcrIL1/AF+fWe5Sve3+I1P0PpXk
+hf8fVdGhwbAXuRKrouTmagGI9b9Sp65PvHUcvasyJufFwqeuV8mScX87CzeSiHGI
+/ozMdnECgYEAq4+losrhe0DEmiC9zVPvwRXjbSixDsSJxHfOcqIsZqhUgBiZ4TJD
+SrkuukrMZib6BAD+PtCJS1TBbJyyvL3QecizhHSIh3ZnT0HnaRPatLEYmU65+3kE
+kTqL4ik92bJnnWowy677sydl1lzBJDVa9ZlTs7BFSd8y/0DZaUxGg2I=
+-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/data/gem-public_cert.pem b/test/rubygems/data/gem-public_cert.pem
new file mode 100644
index 0000000000..885bf7f369
--- /dev/null
+++ b/test/rubygems/data/gem-public_cert.pem
@@ -0,0 +1,20 @@
+-----BEGIN CERTIFICATE-----
+MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMREwDwYDVQQDDAhydWJ5
+Z2VtczEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUxEzARBgoJkiaJk/IsZAEZFgNj
+b20wHhcNMDcwODAyMDMyNTQyWhcNMDgwODAxMDMyNTQyWjBBMREwDwYDVQQDDAhy
+dWJ5Z2VtczEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUxEzARBgoJkiaJk/IsZAEZ
+FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPS1M62wm4cMoA
+RetDHR/oNQTMERRNItHV+TSIQexj2sMJDGazDkF/ZSdWF0PTcHj9fMgr6lq3YIxB
+zfv+8sgG5WBLuD9/Nq0aIzSbmsAe3JyvRdTwSTrOPHiJK/vQ4uPJtj7+60cIRzzf
+xrAYMwIVHbWNjGABM9XCoAjJqy/BsqH9WHC4SsU+pP0bwEpMexpf4f4AMhEfTTU6
+ZaSMHoTKMXTnXXiQ0xrT7YLt1pX2GgEveZ2EK3rM4ZxqmX/0uQbGFw0RQH9KjXpX
+VlCV2D2ZpwbJaS3I1NJ9y2UX5/yiQCaJwbdcjBpbxROaMUKa8Oz+HVH+4ql7Yg4f
+Pzufb13ZAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
+BBRYTAoj4cn8CWZMHFnHGQgoO5jyFTANBgkqhkiG9w0BAQUFAAOCAQEATRrJC05l
+dOmx67Sy3bU+AVXkOr7B9nn2Myqo9uSIAncPoElN6aHr/Q8wOOjtok4r0JcHPe1e
+eotDCZUE1Jkl13Tpv26rOfOOUHtGlyAIAtpsUGOraaJkSut4WKLr1/KckyAAEtgP
+c13A0s0mEiWFRuYxIdEi54561pTT2qQBE/DUPGoYD5rUg9XYAlSovMMwG99Oca7L
+cI6vCymr1bzzddExoywBNOy0fbBT62I3ICBGbH5yOVVKVmlxeo2Zp10FCj0kDrnq
+OuMJSDr5I2XPYqoC+W4YSbwn55o2jGIUX1lOq2Hvj4tFgSxlnJZn0tUhBfR3gSOn
+IFnrqu8PlZsLFw==
+-----END CERTIFICATE-----
diff --git a/test/rubygems/data/null-type.gemspec.rz b/test/rubygems/data/null-type.gemspec.rz
new file mode 100644
index 0000000000..bad99289d1
--- /dev/null
+++ b/test/rubygems/data/null-type.gemspec.rz
Binary files differ
diff --git a/test/rubygems/encrypted_private_key.pem b/test/rubygems/encrypted_private_key.pem
new file mode 100644
index 0000000000..2a9affd18b
--- /dev/null
+++ b/test/rubygems/encrypted_private_key.pem
@@ -0,0 +1,30 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-CBC,27887B3B3BAA3B18
+
+GUZSuxjWdx6b35JMzppCBpAfK3l9IV9D3Oculgz8yT8+qFY5iXiij+fdBQ1fgUdl
+nT3f1wC5Cj1adIQq3UYo4+MK1p3HGKYB/H600YVHNvOgnLaMybSW0uyeKwoweZrC
+mRqN41O8slS6tFY3/BdKXV8qnT7SDl28rYFejVm3Ocb9PtrREA7H48089hME2+yF
+xm8VvGWsHTfdMO9gei4aAU6OVNxvOttc6fMOV3JZYmuKRiVX8Y6y4m+YLA8rTGG7
+kiUi/Ik1YjNa4aVef8kS/xX9sfO3+Q14vE/eOU6qt0u+6zYQcyJvC9grkWolokK0
+ak/yRIDW+irVAK1niEtwnPFSs3koKemwuh2VDMX5GddLJCQmV5Ne4beI6obWVXJY
+6qaKQTMK/BulsoBnxc8Ql9izulfqpRUpWBNUBllhWg/wxnzRxzraPIlLchV6j8aa
+klRVJy1kxgnlk5+RYsDNiNyWBTB0y81Op3svA5oB05dX0AcWEoFoQruLl448IQiC
+WlQV/uDZrqqDu6JAA4D9VNpZuHB6IsGEqaRi4veWwkICbgblOLFpYS4TIxbpNqMT
+8AX7IpDEPL3Rv1NMaByfbBA2VI2HeEPELU0ietwU0KOHcxHJv8QV9ZtppeTiL3pb
+cqYdfcw89eI9h4gy5p4zrrUJM60ONC2DppRmCPZzaFqVajX2DpoEuNZGW+ZUMp3g
+l300ChvAIRjriU/ju6qmVCrJqJNG5zThAvlK/SapBSKly7vSV7q7HlVzM7Dkanqh
++aYl5MwbaSKCcQ7F2uGNgsdollQpAS3iRC1FRe06IkIaL+BzdqFc++qt36ALPiBa
+zhgjT6dTP0iRIoc1dANsJ13rmlLrEEetmIWTeEpKiVCRBHRVu8BPLtIGmiDT+0c9
+d5lwrtdha3SOq5tafqufTQ7Yxi2XteuVSFwDSmzP9l+fBXMYRWPW1otHwg42nPhn
+9SvXl3MJtYKpbzvO5IeqZ0OdTNz+gZwroCBy0ZaIPSYi88LRUzWKDp7gbqBA/ouL
+UEX5T5J4vnXJfPdTmISorPmQblqdFG+A2qCmyou6RumdKHYg/uCeMFNkLDzexTC4
+LooO0clIKKlNFktdkIq3mEaZbSf4UdVSfxRfvbLWXR1orE6ObHpJamuDFWYwWrMY
+qH4asefD8j3lmB1lwpsAbyWeOtIMGnxO6ayo2jzpQQuTVduMCR/HREuoT/6klKiT
+T58OWLa7/GHdoPv0HFNktPNXsgpmdC37IoRZhgbiTSJV6y1gEgdM3reJFXPNXTN6
+q/QCAl5UZWBEmTA2CHvrmekN58X5dv1JEl/RIKtevP/7SZp/TtJMjkKqc1Nvx8EZ
+4pvkMdlbY8cwATORSUdGPCGtPy5x+aDuQWgHOz3G/gGNmGQy98CD3AucI9tcbTiz
+VPdsnumUvkhD5suZCTEBa8JI5d/nCY7/hA6n58fC2eojIFchgtUuJoOFb6GYHItA
+V1couQWj89PubyDPbS0vjxkiCxEk3CK1eDPsjHs/8NEcn582DXkKThZZvfwUu4sR
+EzPlmAeU38pCpJ7jWZtpaAttMTRXMzIY9O0bzU+K3DrtG85OQ6c48g==
+-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/expired_cert.pem b/test/rubygems/expired_cert.pem
new file mode 100644
index 0000000000..3578be835a
--- /dev/null
+++ b/test/rubygems/expired_cert.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC7DCCAdSgAwIBAgIBBDANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTcwMDEwMTAwMDAwMFoXDTcw
+MDEwMTAwMDAwMFowKjEPMA0GA1UEAwwGbm9ib2R5MRcwFQYKCZImiZPyLGQBGRYH
+ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdlNYcvFB6x
+gpT8QcnMybVelGLUKyQL/hQPTK9J5FyqB8hEDLt2ruMwKsHU6fu/mgG+sLvHF1nq
+WhZADhn6rwCfNP03025vktOZ6iJfU60vytY/f3gkiGNkP21l0hz0+Ms15f+52gk+
+sFXqwGBbDteI0x57UsHi+KAN67QuPDnthYDtwhXIA5pcdx2wH+NW8F82HEZvm1hc
+pA75BDVk4vPxnpDfvPOKSYn9dWghmUtaPmqyVvs8XkDxHDfY54/D3ziPehP+zQzE
+g8C07Sq/z6vLSOQ3uaYn0nBDuNE6XP3ijJ4Zvs2eJEdOMyS1H3CsnkWiePCrLtKd
+w8d/F+D5bocCAwEAAaMdMBswGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwDQYJ
+KoZIhvcNAQEFBQADggEBABksVqMxMq/VKjS5Z1tr6G5GlcgvpNjUb+OOEfBc66vK
+Bv3aPrmNR6IE/+o2r0tTIJh4npeE9ASL+Ht0/sphdpOuzfOToPnmptIxHEWg4ub4
+n2qDasmQGDi96xLBZe4DV/5I4WkIQiuyXubVkriRLygng4VRohgFWVfLok9OXhYB
+1NAEIXj9NVKIwFmrOgQEPNYdCVL0U82GhbhbB79gSzvRA2hJOuXhTGLgiAp+lstn
+ppWlcNsg/t1JhJ2unBk9XhhrqUEBQxQcvA2jt1KnlpY/x+ubfB86J6D6l4ve9plE
+uXBltZ2qNFM70SWsPzohQxHfyzmIRKQLM3PXjbma/Lg=
+-----END CERTIFICATE-----
diff --git a/test/rubygems/fake_certlib/openssl.rb b/test/rubygems/fake_certlib/openssl.rb
new file mode 100644
index 0000000000..9de90c0a10
--- /dev/null
+++ b/test/rubygems/fake_certlib/openssl.rb
@@ -0,0 +1,7 @@
+#--
+# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
+# All rights reserved.
+# See LICENSE.txt for permissions.
+#++
+
+raise LoadError, "no such file to load -- openssl"
diff --git a/test/rubygems/fix_openssl_warnings.rb b/test/rubygems/fix_openssl_warnings.rb
new file mode 100644
index 0000000000..66d6cdf3eb
--- /dev/null
+++ b/test/rubygems/fix_openssl_warnings.rb
@@ -0,0 +1,12 @@
+##
+# HACK: this drives me BONKERS
+
+if defined? OpenSSL then
+ class OpenSSL::X509::ExtensionFactory
+ alias :old_create_ext :create_ext
+ def create_ext(*args)
+ @config ||= nil
+ old_create_ext(*args)
+ end
+ end
+end if RUBY_VERSION < "1.9"
diff --git a/test/rubygems/foo/discover.rb b/test/rubygems/foo/discover.rb
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/rubygems/foo/discover.rb
diff --git a/test/rubygems/future_cert.pem b/test/rubygems/future_cert.pem
new file mode 100644
index 0000000000..4f3d8607e2
--- /dev/null
+++ b/test/rubygems/future_cert.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC8DCCAdigAwIBAgIBBjANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCIYDzk5OTkxMjMxMjM1OTU5WhgP
+OTk5OTEyMzEyMzU5NTlaMCoxDzANBgNVBAMMBm5vYm9keTEXMBUGCgmSJomT8ixk
+ARkWB2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCnZTWH
+LxQesYKU/EHJzMm1XpRi1CskC/4UD0yvSeRcqgfIRAy7dq7jMCrB1On7v5oBvrC7
+xxdZ6loWQA4Z+q8AnzT9N9Nub5LTmeoiX1OtL8rWP394JIhjZD9tZdIc9PjLNeX/
+udoJPrBV6sBgWw7XiNMee1LB4vigDeu0Ljw57YWA7cIVyAOaXHcdsB/jVvBfNhxG
+b5tYXKQO+QQ1ZOLz8Z6Q37zzikmJ/XVoIZlLWj5qslb7PF5A8Rw32OePw984j3oT
+/s0MxIPAtO0qv8+ry0jkN7mmJ9JwQ7jROlz94oyeGb7NniRHTjMktR9wrJ5Fonjw
+qy7SncPHfxfg+W6HAgMBAAGjHTAbMBkGA1UdEQQSMBCBDm5vYm9keUBleGFtcGxl
+MA0GCSqGSIb3DQEBBQUAA4IBAQAErYGXM7S3B8i9n4U+RJoxSel/BmQ6lS09uqqr
+2wWTwzkAmupsBuXJmNt1/Z2CZ/ogf/YPYeD5KBuUNtxNGchD+ngws6TnKWZ3kyOi
+MVX7Ec7gTMFSuXSNOz/9MCMjIF4elglB6X2M5IVRqoTP/FHwlGxLx1+aIGnls5uJ
+HELoCi7uaWPHjzF9pfDmqV3FXG2jQuqIngGwIJR1/JzxcNfWW4g2fGOJ1eTNJmRK
+nDXHd2hotbar4+QIoFwMh1nSGx3v3FdqzM6bWvt2r3VK4a9E5FIyNpQ0gC4JInjL
+TlIXGWEwzE3I0sWH6EbnE74VTi96oFXntWqqMcmMJYFLHcun
+-----END CERTIFICATE-----
diff --git a/test/rubygems/future_cert_32.pem b/test/rubygems/future_cert_32.pem
new file mode 100644
index 0000000000..b7325f14b2
--- /dev/null
+++ b/test/rubygems/future_cert_32.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC7DCCAdSgAwIBAgIBBzANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTM4MDExOTAzMTQwN1oXDTM4
+MDExOTAzMTQwN1owKjEPMA0GA1UEAwwGbm9ib2R5MRcwFQYKCZImiZPyLGQBGRYH
+ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdlNYcvFB6x
+gpT8QcnMybVelGLUKyQL/hQPTK9J5FyqB8hEDLt2ruMwKsHU6fu/mgG+sLvHF1nq
+WhZADhn6rwCfNP03025vktOZ6iJfU60vytY/f3gkiGNkP21l0hz0+Ms15f+52gk+
+sFXqwGBbDteI0x57UsHi+KAN67QuPDnthYDtwhXIA5pcdx2wH+NW8F82HEZvm1hc
+pA75BDVk4vPxnpDfvPOKSYn9dWghmUtaPmqyVvs8XkDxHDfY54/D3ziPehP+zQzE
+g8C07Sq/z6vLSOQ3uaYn0nBDuNE6XP3ijJ4Zvs2eJEdOMyS1H3CsnkWiePCrLtKd
+w8d/F+D5bocCAwEAAaMdMBswGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwDQYJ
+KoZIhvcNAQEFBQADggEBAGrtVuj/iourBMAH2bQI6sQsuCJcL5HN6IXCoAcQyQEI
+LR/roZyHI3fg+FfTzUII7wxPSneo4soSKXYxQYuE1JYPxTcQE5lFv9jbzl6eplsN
+LcAMnrjB4xJoRkSg4mbPxwEICngnWRQuY+lOsquSkRXAAl+5bW/OBfxr8XWcGjmG
+ZRGmOwKzUiv7p7zyJkkEFb7m6ugg0GKop23jtv6Rou5+2lXLBqm8T0de30pM0arM
+vAnd2a8UbPnmR0DzrCtksU62UIqhVoFFicntdaEiBF/Pk9YhLCfTXwInWL8+p48r
+PBzrKMTb56YQZXVAG9aypn42pnPCMPC4ojCxfC0N3n0=
+-----END CERTIFICATE-----
diff --git a/test/rubygems/good_rake.rb b/test/rubygems/good_rake.rb
new file mode 100644
index 0000000000..ca916d098d
--- /dev/null
+++ b/test/rubygems/good_rake.rb
@@ -0,0 +1 @@
+exit 0
diff --git a/test/rubygems/grandchild_cert.pem b/test/rubygems/grandchild_cert.pem
new file mode 100644
index 0000000000..5e5fe0113e
--- /dev/null
+++ b/test/rubygems/grandchild_cert.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC9TCCAd2gAwIBAgIBCDANBgkqhkiG9w0BAQUFADApMQ4wDAYDVQQDDAVjaGls
+ZDEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwIBcNMTIxMjA4MDAwMDAwWhgPOTk5
+OTEyMzEyMzU5NTlaMC4xEzARBgNVBAMMCmdyYW5kY2hpbGQxFzAVBgoJkiaJk/Is
+ZAEZFgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkfgy
+EbzcRpXvpNA0s75R8gOVk7ENEPX5uXUElbzHbVEmHkC/NFsWZXV0vxGFfZrrnEkT
+Y2kDaMMkfZX9rriRIvsZpxyqrdX87QfQTZ1ktDoytVnd+gw9A6AXB6PR7uoPymso
+f/lZYJ8BWP9fIU39nogiptFqsgkpOtKSFjJfMILkcMAeBPs2B5HV5l4oLrpJ7Ns/
+0vazCXGakTByAXNKBagJWR43gh+RUQWF6Uh04VQTQ7ENGWI83088SKAPtCCcgKxr
+ROHI025S7o7vEfDEqEn+gtu+4ndaLuRp+2AmF3YK8dEDiLXrrvEvG1r4+gIB/6tS
+MUfkkJtBleZrDoIAgQIDAQABoyEwHzAdBgNVHREEFjAUgRJncmFuZGNoaWxkQGV4
+YW1wbGUwDQYJKoZIhvcNAQEFBQADggEBAFNdoYo7A9eThXpNy1buoVpeVR19VpEG
+nvzen8ipQ7uGQ/62aBvJlqgj2/xFKWidtMNH8769SY94ePembHWABFvVBZpMU5ZO
+LYuC5rUSpJcxfw6T5eLytYHOAr56kWjQB6AVF4mQ5IavQ0MoHsm1RZ7L9amNQY1J
+zFIJpN4/T4wJ/+M58zCUFKg0aC3uUcYRgc44xhxmzceUoI3H8Bx1gqfuVM9KleLA
+Bi/BdD6GTQ16stbQP/fso5kjwAUr2x0NttwkzO0Sd7y3G7RXCmJux3zQrdu+3HoF
+edxj9I39tX+v8AbCFl2vO162ZGwLGewdk1FImb28c96t3B17jL1U/H4=
+-----END CERTIFICATE-----
diff --git a/test/rubygems/grandchild_cert_32.pem b/test/rubygems/grandchild_cert_32.pem
new file mode 100644
index 0000000000..e4486a74ad
--- /dev/null
+++ b/test/rubygems/grandchild_cert_32.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC8zCCAdugAwIBAgIBCTANBgkqhkiG9w0BAQUFADApMQ4wDAYDVQQDDAVjaGls
+ZDEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwHhcNMTIxMjA4MDAwMDAwWhcNMzgw
+MTE5MDMxNDA3WjAuMRMwEQYDVQQDDApncmFuZGNoaWxkMRcwFQYKCZImiZPyLGQB
+GRYHZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJH4MhG8
+3EaV76TQNLO+UfIDlZOxDRD1+bl1BJW8x21RJh5AvzRbFmV1dL8RhX2a65xJE2Np
+A2jDJH2V/a64kSL7Gaccqq3V/O0H0E2dZLQ6MrVZ3foMPQOgFwej0e7qD8prKH/5
+WWCfAVj/XyFN/Z6IIqbRarIJKTrSkhYyXzCC5HDAHgT7NgeR1eZeKC66SezbP9L2
+swlxmpEwcgFzSgWoCVkeN4IfkVEFhelIdOFUE0OxDRliPN9PPEigD7QgnICsa0Th
+yNNuUu6O7xHwxKhJ/oLbvuJ3Wi7kaftgJhd2CvHRA4i1667xLxta+PoCAf+rUjFH
+5JCbQZXmaw6CAIECAwEAAaMhMB8wHQYDVR0RBBYwFIESZ3JhbmRjaGlsZEBleGFt
+cGxlMA0GCSqGSIb3DQEBBQUAA4IBAQAu14Hgglh3K914FUFC+O2HRQdgK+JaeZJ+
+vjaPxzpXcwlIMqTTphjWMk0b55iOQohXHYewYg9ToErYGfqGURH4MVSCJr+LecZX
+xuty8JC6KvTaVGfZNPIkCF92LupleV7YVg9Ew4KvCZGrodXr+XlWHpJWx7KJT+1Z
+yUC36boJUj+VDtnqq9weUgtfkh/RFoZdlRK76WiaGzKuNFBJz3n0yBhzDcMo+av3
+GeSEx8C1eu/01U8ZO5PK49HuMdNJFpB3W18gGOzT9eqDfTIEdEsrTG5cxlEgQUBW
+jHFnqSBK5LgPAqRP6GRdBW4ZtZ4yS/7+n8otsvFGwXPHOSSvtoNu
+-----END CERTIFICATE-----
diff --git a/test/rubygems/grandchild_key.pem b/test/rubygems/grandchild_key.pem
new file mode 100644
index 0000000000..a9b9aef624
--- /dev/null
+++ b/test/rubygems/grandchild_key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpgIBAAKCAQEAkfgyEbzcRpXvpNA0s75R8gOVk7ENEPX5uXUElbzHbVEmHkC/
+NFsWZXV0vxGFfZrrnEkTY2kDaMMkfZX9rriRIvsZpxyqrdX87QfQTZ1ktDoytVnd
++gw9A6AXB6PR7uoPymsof/lZYJ8BWP9fIU39nogiptFqsgkpOtKSFjJfMILkcMAe
+BPs2B5HV5l4oLrpJ7Ns/0vazCXGakTByAXNKBagJWR43gh+RUQWF6Uh04VQTQ7EN
+GWI83088SKAPtCCcgKxrROHI025S7o7vEfDEqEn+gtu+4ndaLuRp+2AmF3YK8dED
+iLXrrvEvG1r4+gIB/6tSMUfkkJtBleZrDoIAgQIDAQABAoIBAQCFbg4+vpfQghBM
+ZPI399oqUvJwziA2h9Kdn4TwZ18Y41vnvaHKdxUS63orihWvSmTjOL1bWsv+AJuj
+nO8GvroU8tlxM7glLX2FImZb/GrogGaH9bz+bB995+IFXs9xCE4k5y1fRgxYUSDH
+PLC13ffe6WxbdwSD9/HTTlaxqZvv1+UWxyYD0CSwopww5YdqISkVHq2UsmszK49X
+hn6zzK+DT4YA04Tbv2Go9kCYLmsgrL2/dPJulDtJhX3AckbdkodSlBAmxe7XsKEO
+TEzNDGgPZyZ+MXttBnLt1vk8ZrSJWcFG+E6DMbGUZ7rz6g98bUS1LI6PiqIp5BfS
+sr0cGQl9AoGBAMGj7SCp1GMo8wOJpzzSGJ4PCc/fpG9NcTBqtmoUTuvMk4frkGXJ
+dSS68KB0t0EGStbUFIZuylchC7RSzXs0uOZxkgaGcJT5qXXFP0Djy3/qoQMnJ2Yl
+uhD6UsetPXbozK6MPs3mh9VqSDNbf2AM034nTod3I9sV471HZLwAhQk7AoGBAMD6
+Mmvy8DEa62VDTW6P1f4b6Pi6dOiZhGbNz5Xlh5jHplSMYReQGBVmr9szrV7qytGP
+ZcBhEqTc53u2mEhSmRXQflRxJ7U2m8Xl3DClhxELHNGCJ9jEY52M4ZDJkvGj5v3t
+pbTbE/g3zxmAaYZCOKIzYv5bSSStNpauxdomxuFzAoGBAJFohH97qEZSELJ+YrwU
+VHIUfty/Zt5BvBaMe7CK0XzWIY72gHc+4Z2UV29WVeoZTIenuEX+2ii1YvGlIDI9
+s/8wF2SY/d+Q3wTV+prCtCS5TvFsLHTTLbbkEtdoqvgo9tK3881wKF5FMjSGp867
+svFPmPO2rpEtDdgrzWQzy7LTAoGBAK077Sea3qQ2VjqBQHGQDbofs/QU7f4gUgs3
+lrIpaqBsGZSssDxGzlfn5tYQfgJHI+sbn2wjuGjnJaaZM/s4qtQ6Zi3Hpq22aAAv
+aIsDDUzvfN9WyA5/vi0g2xzu10q0qBgrziWcxUB+WRu7ev9bUxvIpYVQzUhvdiGu
+o05CoSahAoGBAKoCGMGKkub+LnWazPkN2BAS6LblV+JIYWRI+DSGpz0UBk4Br546
+ozZq2GsLCQYWJabJ5RE9Are6rl9AvFQXMaWywOBe3TUz7SmLIxMjWpXKiX5YIFkS
+tOiEEmET4ZYS87flEmldnmeDFLHHbMLOw5S0dJa4PyFRn6j9su8d8mWw
+-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/invalid_client.pem b/test/rubygems/invalid_client.pem
new file mode 100644
index 0000000000..e0d39519d9
--- /dev/null
+++ b/test/rubygems/invalid_client.pem
@@ -0,0 +1,49 @@
+-----BEGIN CERTIFICATE-----
+MIIDgTCCAmmgAwIBAgICEAIwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQVUx
+EzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMg
+UHR5IEx0ZDAeFw0xMzA1MDExNTAxMzFaFw0yMzAzMTAxNTAxMzFaMEUxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
+aWRnaXRzIFB0eXXXdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCw
++lcrpdWcloQCgAlxcM3GjvBxZ3yjzi6SgXKRBSi54i0J1LXxznWKcJ5P/O1+j+7i
+LjHK+OWqsa0+EbKTwSu+0tx20h0z++YJF9GWEoCwT5aH1kor/0+EQLgYnxBaF8GC
+2xAbkRkWmbSu2aLDIey3lg7lqAazYqdS2wH0UjSDjFKDLxz9LwpfFm0yGL3DgwLW
++dobYkgt1A6F/8Pz6D2FjwYKcM8JE6w7KJSJDUvXcv2E18wmhZ/qF/MtFAF4coB1
+f5ALnz8YqY6eyDF5aY/VfaHZvXdirLlMH6/miie9GBVMnJWF0ah5ssbsMvcpmnDJ
+qkiYju2e1oLFEE7zztU/AgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgEN
+BB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBTcOELj
+hSUdiLrdRF3CFZDZkWaGzDAfBgNVHSMEGDAWgBS7B027H/ZIkW3ngm1SrR0X/aTC
+wDANBgkqhkiG9w0BAQUFAAOCAQEAlQMzHlnT6L1qqA4hL6tABPbiMsVwXyKCcfNB
+zBn82Wkxgbg7Mp31fbR6/qvGeXOtaX6IdPdgtVf8nh1NURk0MmFBP+gfnwfNBD+m
+Q1cldDt9kY2LGIrPii40xbugF1/xqEYcZMgXU08aEvQ2IHX46J8wZoqMa2KhrU8/
+mzY0F+UEFOGWtKDgUzz3dyBPsdzVrX+SXULwH0lqZX8Nsw5LyfrlVt3xQvS5Ogm4
+kYlt8kqhF8lUS3WTbuADrIs3NaDPRWSs1iLRRFgosgUtHN7tkrkrVaHeBo0KbAJG
+mMqtxSY0XZI9WBxffP9UtoY3EiTWNVWLtuCN3OSvryP6NDe4BA==
+-----END CERTIFICATE-----
+
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAsPpXK6XVnJaEAoAJcXDNxo7wcWd8o84ukoFykQUoueItCdS1
+8c51inCeT/ztfo/u4i4xyvjlqrGtPhGyk8ErvtLcdtIdM/vmCRfRlhKAsE+Wh9ZK
+K/9PhEC4GJ8QWhfBgtsQG5EZFpm0rtmiwyHst5YO5agGs2KnUtsB9FI0g4xSgy8c
+/S8KXxZtMhi9w4MC1vnaG2JILdQOhf/D8+g9hY8GCnDPCROsOyiUiQ1L13L9hNfM
+JoWf6hfzLRQBeHKAdX+QC58/GKmOnsgxeWmP1X2h2b13Yqy5TB+v5oonvRgVTJyV
+hdGoebLG7DL3KZpwyapImI7tntaCxRBO887VPwIDAQABAoIBAFOpdG3gzlNg3/Ti
+nBQxdEVqKwYhGs3A2UlOwl8F5lPBNPNRx9UQeYZBaMV9VrQezJnFpqpB8Sg5KCGQ
+ci/hAJIL0kalW0LI0Nz5ko10H7u5U/rQ9W1JG0j041JYV32Pf14husKdXBPQA5co
+sQW30tSSrmYogUpp15mWiJz8A3EvqiCTlQv5JwwMFGnjVl8+HNfuLghK/vqY/Eb9
+YmwTKxPFejqN7E0Mud2ylNiuPTSLwBy8UvV9uxOlDc6lMyZjVRO0woiEzrjw5dKF
+yf5tUkICRcPkekcx+XtpGrCMlRLl770bZBZX+YNmbYXVWhFp09cNR+U0KZqPNcDp
+jg73vXECgYEA3huOKzfHGt3qUdMlEHd1FvQhW9fYIrmUSnuVYQJOnY8lFfKfmrOH
+gpwOIHDNiVHYlhAJaNocCLYx4hWHgZXarY7NKxmlY2+Vp8mcCIf2Cw3Kr/sFklUJ
+KpiRxqEPGR7U4C/E31kkH/C+w7m9Zh3ndhltU2Pki9/Eq0lk8YClMMkCgYEAy/vU
+jxzviIk8bll5uCIuXJyCfao7ywaZABbL6a20kdVGKrHj57O/OJ2WZVwBihhB7OS+
+QsKC/J8LrUJkobOFtQvQ8O23uep5rB6kqCkXsXCG4SCl2L5xZySBp/qhiqbuMwvp
+EAWPSIA6UNoR0J2rDYVmq6jtY526wQf5ivE8IccCgYEAphfzJAyNH2FOZixArmS2
+shiUjasG3UjsRRrP5YClK5wtPpF2m2if8KMkyUux2HvVPLr3XmqkxjsBaLFy6QwY
+QOvmL9H45Tg/sP7KaXLLIw8IQLu2OezPcwQvF1u//6gXxyLR1bhClIQjFBjlMuUv
+/xgasl6kPZlz6Cd1jkgGwEkCgYAI1IT2EQWZfn9cM4leXDRvk+LeN8FQ35897r6z
+Be78JSRdcsfv3ssXU1MQXjQ+2x/3dkt6LltnPidOP8KFcXUHSlSoKVI7vRe5SLZO
+BUFeUAW2tygWwt+73Eu0jtfxXZqQISLcq7DxLYPYvifpRPoDotO3+J8WIdzUwFig
+GCNHPwKBgHqXOyRef7ykVUCptMf61/BvNU8NP1f9PkKQBMYQZC39UwqEQ675QBUh
+hSG9t/kyc44zUVmBeKIlWHVyLQ83Dv+ennz/D9t7tstet0VMKvALNdiVT0sjFKN7
+1VINygCeFkqrlTXlOwFcRSo1gHn3/JIrhSgRuYKHSf0GZOcN6d9l
+-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/invalid_issuer_cert.pem b/test/rubygems/invalid_issuer_cert.pem
new file mode 100644
index 0000000000..31812aa2a3
--- /dev/null
+++ b/test/rubygems/invalid_issuer_cert.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC8DCCAdigAwIBAgIBCjANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTEyMTIwODAwMDAwMFoYDzk5
+OTkxMjMxMjM1OTU5WjArMRAwDgYDVQQDDAdpbnZhbGlkMRcwFQYKCZImiZPyLGQB
+GRYHZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM0ycOSh
+SOKDGhDlPZ3+JAWwp7KB2ps/VlLhIsZl0uAHzCAGPNI1I46gmla1g7Gh429fYeJ0
+VgeRTxI/rRWNJ0HX2I9jhaJqAkiOqV5Rk6RkJv/0lU1VSu1IBjKRmV6qXiNeBWA8
+duEPNdd6zKX7UoKcYgmG3BMDuEy67AqWUgZOjc9WUnd6i+mwWciMuNqul69vMvB5
+go4c/rgtp1Y3PhLDIrheYP9s+Bza1MNp0FUFlrPnL5gzZTsP/IX2u7kF3CEhKCZX
+ZPX0oZc/pbqIS2OuQ9T6ft6StSwA+9IhAyCeJ9bGyBYK78SyiSfELKyGKbk74SmR
+AqjpN2PJX3o/gk8CAwEAAaMeMBwwGgYDVR0RBBMwEYEPaW52YWxpZEBleGFtcGxl
+MA0GCSqGSIb3DQEBBQUAA4IBAQAfnWXhF0gpfdJPgYtgA8gUdezW9pImBWlWaZmX
+DJhdGBe4pAtsGYHCC1B2lcyRYhQQEibfFrtHeJk1O/vmVw7cuIltVxkpof/0hWA2
+zqpO7UWjYuVxxaZuWGF6MhFWLHLHq1Q8ppXEcMPyP/mGcf3bjYmyFk0f1IslTMVn
+2CJPXO2k8v07dH1ljgcM9X0wmPILQzDzLAJzwPD1iB602ODuie9xXH6ySaVU0n9p
++EJfW1GZysdbcUJ36osY0AO8kjjFbgJG/kM34WFGDixm+jDfMvZTsxlRZc2XNBgS
+2PWvb4CJ1kDwIoMzdSt9MavbvSHkxJllplpUpQqv0Or1Dh9y
+-----END CERTIFICATE-----
diff --git a/test/rubygems/invalid_issuer_cert_32.pem b/test/rubygems/invalid_issuer_cert_32.pem
new file mode 100644
index 0000000000..3a06ceb4fa
--- /dev/null
+++ b/test/rubygems/invalid_issuer_cert_32.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC7jCCAdagAwIBAgIBCzANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTEyMTIwODAwMDAwMFoXDTM4
+MDExOTAzMTQwN1owKzEQMA4GA1UEAwwHaW52YWxpZDEXMBUGCgmSJomT8ixkARkW
+B2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNMnDkoUji
+gxoQ5T2d/iQFsKeygdqbP1ZS4SLGZdLgB8wgBjzSNSOOoJpWtYOxoeNvX2HidFYH
+kU8SP60VjSdB19iPY4WiagJIjqleUZOkZCb/9JVNVUrtSAYykZleql4jXgVgPHbh
+DzXXesyl+1KCnGIJhtwTA7hMuuwKllIGTo3PVlJ3eovpsFnIjLjarpevbzLweYKO
+HP64LadWNz4SwyK4XmD/bPgc2tTDadBVBZaz5y+YM2U7D/yF9ru5BdwhISgmV2T1
+9KGXP6W6iEtjrkPU+n7ekrUsAPvSIQMgnifWxsgWCu/EsoknxCyshim5O+EpkQKo
+6TdjyV96P4JPAgMBAAGjHjAcMBoGA1UdEQQTMBGBD2ludmFsaWRAZXhhbXBsZTAN
+BgkqhkiG9w0BAQUFAAOCAQEAPNSZx48cauKsTdhSwdzYSnIYjzPT6ZxoJXCpX8hu
+uOwyZ85i5nSX8rQvjv3IAtQpKQ+1G6odOXkt+zMz1z4dtpo3uEydpWOFKESna1vy
+d3qF+iWUxY8varWOi0lE6ZfFVDsrruVz9m9dcTm2MlGspBeUZrHH2BixEr1/pUAI
+DdBtptZ5qNIxZ4GQJGqrw9j410hjKwm0xV8eWP/D6N640bTzZu06iZbO49exmMSc
+eH3jJMmynviDK3H+GqXIrnSbjbo5hRbEGv0FlYBQijYQw0ttp416Go7kS6cCPSy3
+nUPSMSPr+o5WqU1BKxIdJJSHVZIUk7LfKDOo7LUOJhygwA==
+-----END CERTIFICATE-----
diff --git a/test/rubygems/invalid_key.pem b/test/rubygems/invalid_key.pem
new file mode 100644
index 0000000000..74bedabcda
--- /dev/null
+++ b/test/rubygems/invalid_key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAzTJw5KFI4oMaEOU9nf4kBbCnsoHamz9WUuEixmXS4AfMIAY8
+0jUjjqCaVrWDsaHjb19h4nRWB5FPEj+tFY0nQdfYj2OFomoCSI6pXlGTpGQm//SV
+TVVK7UgGMpGZXqpeI14FYDx24Q8113rMpftSgpxiCYbcEwO4TLrsCpZSBk6Nz1ZS
+d3qL6bBZyIy42q6Xr28y8HmCjhz+uC2nVjc+EsMiuF5g/2z4HNrUw2nQVQWWs+cv
+mDNlOw/8hfa7uQXcISEoJldk9fShlz+luohLY65D1Pp+3pK1LAD70iEDIJ4n1sbI
+FgrvxLKJJ8QsrIYpuTvhKZECqOk3Y8lfej+CTwIDAQABAoIBAFo5I4pjoDh4jK2B
+HmapqA0Yb6P9lLFOWBZ5B2FUxDPdOdOa6oNC+i9sTnBxv0YLeIUv20pG/My3B51u
+ghxHxEsfLQlfKRMQqZBdqfrew5w0rTE9yagHKLrMQG1bt6P4JQxH+vUloN+0YGgu
+hm005EKpoDGwKnPx3sdeKQs+rTI37fGLw40ZPSod2B7UkSna4/u/uXa1yFbONlqq
+P4ozsDd1xoCaBJfwie2h93KneSPwyHHumlVgbFAJcQycuD5qproYbea9PppppQ+4
+17M9ccuQpS2j9rZWgk7+KqwLrYqzajmtHoQH4zkBYd0JQ4ywGKg307xDhppMZpq3
+uMqnXgECgYEA9iYB7vX91Q3HsRtUAd0aZ91lDIv9RXBP+PuK3OUrtChdtZx7Mih3
+uTgtfVEnP7bxgnPpwecnF4Ncginuu7TBtxjoztFjuFNzk/8Fz/J3i/H3oB0SdjhL
+uqVa6P4hPak7FnWynZHivuuIe+eKYLvK0TCMbYaz6G81xi0Whtbm498CgYEA1Wja
+PgscP/9YykCC6eRP+ixo6chGzSNJR+WRW9CJYpXEicPlaT5AI3nSZVXXSLvXIbq9
+NoExPu47pDzr9Gd02qYmFWUOolUa21W4s/x4d7lU+wJzS6ZNTFoC8woZagL2kZ5G
++we5ifbUz7eG+ahZODGMGA9BJVT3PI6zPdKtr5ECgYEAy0ORnypGBXUOrUMa+TsD
+fjfGJTlI2dmoQLw/7K/Wijw3PizNUxs12p74eZ7VYXkKMKbVpwjiMDmK3/YOrbTT
+rwaD4Z3p0iIftFwJCbJ5Y/hZez/mqfdNGgFIdFS/UHL6V060RAhfjTdlCqSmkcEh
+9+M2Y4+z60JCzrcW/hxiqFMCgYEAj9ntwoSatkjZAPwbQq2ze18UGQH3N6/hZaVJ
+JiqbcOijYnm52gcsFL25JLWIOG7lxMarZGIRX+oWKc8m/cf+7KOyaBmGk8XqJI7T
+wf8c9RboQYqVTRj8YcsK0eis2NjGe8HE9tFuL6FCMgHz6bWg7k/3rwAZWaC8RwWp
+rLKmgQECgYBXGjEvogVeYMgnpzjoaa99wvfp6FtbRx1jZ+FOSBoH5uCRDalD5Q16
+0UVnoPcnj0Hi7Hvvl6jTLesRW/LDra5Hqyxs4yuSBagEUFv/PvY0eYGZ5egGZgaa
+PlVmxgk33xYXar8wGHLkstwqZY/OqT89cKvJqeLKMb0G2Re13oPVww==
+-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/invalid_signer_cert.pem b/test/rubygems/invalid_signer_cert.pem
new file mode 100644
index 0000000000..6d6c648d32
--- /dev/null
+++ b/test/rubygems/invalid_signer_cert.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC8TCCAdmgAwIBAgIBDDANBgkqhkiG9w0BAQUFADArMRAwDgYDVQQDDAdpbnZh
+bGlkMRcwFQYKCZImiZPyLGQBGRYHZXhhbXBsZTAgFw0xMjEyMDgwMDAwMDBaGA85
+OTk5MTIzMTIzNTk1OVowKzEQMA4GA1UEAwwHaW52YWxpZDEXMBUGCgmSJomT8ixk
+ARkWB2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNMnDk
+oUjigxoQ5T2d/iQFsKeygdqbP1ZS4SLGZdLgB8wgBjzSNSOOoJpWtYOxoeNvX2Hi
+dFYHkU8SP60VjSdB19iPY4WiagJIjqleUZOkZCb/9JVNVUrtSAYykZleql4jXgVg
+PHbhDzXXesyl+1KCnGIJhtwTA7hMuuwKllIGTo3PVlJ3eovpsFnIjLjarpevbzLw
+eYKOHP64LadWNz4SwyK4XmD/bPgc2tTDadBVBZaz5y+YM2U7D/yF9ru5BdwhISgm
+V2T19KGXP6W6iEtjrkPU+n7ekrUsAPvSIQMgnifWxsgWCu/EsoknxCyshim5O+Ep
+kQKo6TdjyV96P4JPAgMBAAGjHjAcMBoGA1UdEQQTMBGBD2ludmFsaWRAZXhhbXBs
+ZTANBgkqhkiG9w0BAQUFAAOCAQEAd0sGT1z4eppqGMxGdx5ZjXRbgKJZNwz2jHGJ
+CbceA4slPLQOwLXKscXm7QkhMg7L0SJWX2WgLbY/Re5jrexgXnM/fxiIW/wLo5Bv
+V+ajcbZt0uC5scX9DSpwUftlQiMIARbwWb5Lg4UDzT3nB44BgrUIx/YC2084BSsb
+Lrr3YNW4ZGyxN6qVIILCemg3YpsmFspQtsCdRUsn/5Hjc0J05qA6XDSNXRZYYGA2
+tstMcYuwmhp6WjIEWU0i6t84ZKzOrNm2qwjhT6nYYJvvKQtexa1W/WTM5IHKcxiA
+oWnrRCZWt33UtHF4//zjXSJm0S8gb8FDRicxS5CbDiVe20GDkA==
+-----END CERTIFICATE-----
diff --git a/test/rubygems/invalid_signer_cert_32.pem b/test/rubygems/invalid_signer_cert_32.pem
new file mode 100644
index 0000000000..0f4ddcf50e
--- /dev/null
+++ b/test/rubygems/invalid_signer_cert_32.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC7zCCAdegAwIBAgIBDTANBgkqhkiG9w0BAQUFADArMRAwDgYDVQQDDAdpbnZh
+bGlkMRcwFQYKCZImiZPyLGQBGRYHZXhhbXBsZTAeFw0xMjEyMDgwMDAwMDBaFw0z
+ODAxMTkwMzE0MDdaMCsxEDAOBgNVBAMMB2ludmFsaWQxFzAVBgoJkiaJk/IsZAEZ
+FgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzTJw5KFI
+4oMaEOU9nf4kBbCnsoHamz9WUuEixmXS4AfMIAY80jUjjqCaVrWDsaHjb19h4nRW
+B5FPEj+tFY0nQdfYj2OFomoCSI6pXlGTpGQm//SVTVVK7UgGMpGZXqpeI14FYDx2
+4Q8113rMpftSgpxiCYbcEwO4TLrsCpZSBk6Nz1ZSd3qL6bBZyIy42q6Xr28y8HmC
+jhz+uC2nVjc+EsMiuF5g/2z4HNrUw2nQVQWWs+cvmDNlOw/8hfa7uQXcISEoJldk
+9fShlz+luohLY65D1Pp+3pK1LAD70iEDIJ4n1sbIFgrvxLKJJ8QsrIYpuTvhKZEC
+qOk3Y8lfej+CTwIDAQABox4wHDAaBgNVHREEEzARgQ9pbnZhbGlkQGV4YW1wbGUw
+DQYJKoZIhvcNAQEFBQADggEBAE8RJTY1E6DBOEt5azE9wQGJ7yrWJNHLhtP0nmkd
+eaIraloJcqss86qgbH4NY81mvm7nhB6/UEcbm218b6roTDOEjvBp1sKtZ7sqt+J0
+gFqAocBStTkPucmbsDr0B6bUmeHxgpCt+QoaOh6Fwh5yizfpl9i7oMU4QLhf1eZ3
+K1PrPvUle2JFfzJ3SFDlU9C/oA9yDQGnJ7efUCFKvg9M9CzgAHFJyQNb/47tmqHF
+2uxSwEy+ADbD0fPw0r5zkejEimBHWcaTHxqQ12GhS5PkUBYm/qW9a6wyBBO2nO6u
+Tr1zrCDc728aPjN4Qh76xUy/hyCcSgXalhz1LMHgv0VDx/M=
+-----END CERTIFICATE-----
diff --git a/test/rubygems/invalidchild_cert.pem b/test/rubygems/invalidchild_cert.pem
new file mode 100644
index 0000000000..5a79c83396
--- /dev/null
+++ b/test/rubygems/invalidchild_cert.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC+TCCAeGgAwIBAgIBDjANBgkqhkiG9w0BAQUFADApMQ4wDAYDVQQDDAVjaGls
+ZDEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwIBcNMTIxMjA4MDAwMDAwWhgPOTk5
+OTEyMzEyMzU5NTlaMDAxFTATBgNVBAMMDGludmFsaWRjaGlsZDEXMBUGCgmSJomT
+8ixkARkWB2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDl
+rDAlDZwmP6Zxc4sSaOdSRRXJBmbQubxmWpqU8bXrTKCkvg1l/2U6weJIS52zW6Te
+Zok7Uus5jywyeNSJ/MBHb7X5ytAPQsvLu/3WFwaVfHJzimQI4vtmx9+CDgZzipYp
+ett7IF18He8DPiFur1xCn8pp0qOOV8mXL/8TpUgJfmaOJosqgFqorj5niqF52IwJ
+vtur/gwpq2xpCtYaCUB/dFzzefLV37kt58S6jTmZnYf4kIdFKhhyTeGmDRf/wOz+
+kK/H/aKtpsYgzI//bo+bsuWNFceIdWrdCBr63cVs4ql7VN7p2xfn9ckEfwH6wFut
+QLquA/6fRkgUFF8fxUiHAgMBAAGjIzAhMB8GA1UdEQQYMBaBFGludmFsaWRjaGls
+ZEBleGFtcGxlMA0GCSqGSIb3DQEBBQUAA4IBAQBvNQFrG8ye8vyHmnfX5n3++OEu
+k6a+Jr8BlLL3jqI8LPmANGgd4May7HXua4bVZjAx+EtChXd1jcCP8pJ1AZaSHZIF
+icdhxfKjD6JfvgVQOKQluOfDJ0Tg1GyONZK29m7fOrsHbB+OIaJhsce3MEXdGVpF
+cppM3lEaI2PGaASWf3gqVOytTdRFqMStaDWY5rfy+LxgBeGkw9GjUkdMxdFZBs00
+dunhXTI8pk/QyqGhoDH3/iHansIB6CCH9C5gysEuFErp/mpvobCVn1aLcs7EY6vC
+1BZL1LMVJ8fL1gGwpgDe6R+X5oba/wzwt3wXrC2e4r9zy2qtWgfS/REYA49B
+-----END CERTIFICATE-----
diff --git a/test/rubygems/invalidchild_cert_32.pem b/test/rubygems/invalidchild_cert_32.pem
new file mode 100644
index 0000000000..126b60a325
--- /dev/null
+++ b/test/rubygems/invalidchild_cert_32.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC9zCCAd+gAwIBAgIBDzANBgkqhkiG9w0BAQUFADApMQ4wDAYDVQQDDAVjaGls
+ZDEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwHhcNMTIxMjA4MDAwMDAwWhcNMzgw
+MTE5MDMxNDA3WjAwMRUwEwYDVQQDDAxpbnZhbGlkY2hpbGQxFzAVBgoJkiaJk/Is
+ZAEZFgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5aww
+JQ2cJj+mcXOLEmjnUkUVyQZm0Lm8ZlqalPG160ygpL4NZf9lOsHiSEuds1uk3maJ
+O1LrOY8sMnjUifzAR2+1+crQD0LLy7v91hcGlXxyc4pkCOL7Zsffgg4Gc4qWKXrb
+eyBdfB3vAz4hbq9cQp/KadKjjlfJly//E6VICX5mjiaLKoBaqK4+Z4qhediMCb7b
+q/4MKatsaQrWGglAf3Rc83ny1d+5LefEuo05mZ2H+JCHRSoYck3hpg0X/8Ds/pCv
+x/2irabGIMyP/26Pm7LljRXHiHVq3Qga+t3FbOKpe1Te6dsX5/XJBH8B+sBbrUC6
+rgP+n0ZIFBRfH8VIhwIDAQABoyMwITAfBgNVHREEGDAWgRRpbnZhbGlkY2hpbGRA
+ZXhhbXBsZTANBgkqhkiG9w0BAQUFAAOCAQEAn81wRiztOz+u74TbUqBfkpG4QMZW
+4mjGbM9eF6swyQ3fpdJO9hM9VK8V46IIoxqp5sqd9j2ZB7DAB1Fr84LD1NopWPZD
+Ui07O/qfwX360alIBwRsRKdZJdH0YykXZErPbMkQOk8SM4SVD0yUoGea6HwHBwKs
+UXK9LDhTm73o7k0md34dwa0s/rG0cUhfVuDWB2cZ6o5Y6B4ZXcTMG60QAoH763NP
+eyBzrlfIz/03O6K7HKGgQc35WaMeNXovrZcOWHgtpSjev5Ugu7LnLiTYOwn82c3r
+7bjGiFG4g6k7aSzHigUasqG0v7NLz1ZQ1mgMTIqwXWRap0RCuIJl11UF4g==
+-----END CERTIFICATE-----
diff --git a/test/rubygems/invalidchild_key.pem b/test/rubygems/invalidchild_key.pem
new file mode 100644
index 0000000000..9706c9566e
--- /dev/null
+++ b/test/rubygems/invalidchild_key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpgIBAAKCAQEA5awwJQ2cJj+mcXOLEmjnUkUVyQZm0Lm8ZlqalPG160ygpL4N
+Zf9lOsHiSEuds1uk3maJO1LrOY8sMnjUifzAR2+1+crQD0LLy7v91hcGlXxyc4pk
+COL7Zsffgg4Gc4qWKXrbeyBdfB3vAz4hbq9cQp/KadKjjlfJly//E6VICX5mjiaL
+KoBaqK4+Z4qhediMCb7bq/4MKatsaQrWGglAf3Rc83ny1d+5LefEuo05mZ2H+JCH
+RSoYck3hpg0X/8Ds/pCvx/2irabGIMyP/26Pm7LljRXHiHVq3Qga+t3FbOKpe1Te
+6dsX5/XJBH8B+sBbrUC6rgP+n0ZIFBRfH8VIhwIDAQABAoIBAQC59hllZwev0Ims
+AqnwVhA2hMmG4zAMgNcS6PmQ78Ukp/7KZTfkBk6orKPTdaZSuzla+hrTdegPyuU2
+WK9+qq/lJ4ZootakBKmOZMC6wBoMn57r/nnQ2DhGmD9YxpJiqyu6mkdsAmCvRm1o
+ar4XKNXC/C6gUHUto9cOG0alWYZiZ/VMe/nhPTChr2Dhd+bavO1yx7/CxB+VQMfQ
+l6ihbv//3KgPJAElbaI7jfOGzX6KlwXSGf70REmZQnPGN4/n46/dLFFuA1HzcA5Z
+37NU1zgN2nIrXld8rsR1mSy6EwU46sW3AkEwv6SUajCjz7PCmmWxRaQErGJjZrUq
+sujNj5RBAoGBAPgdiY+6B7WvmLlCBCwI4PXjgRQ/6A1Ycgvi1LdSQzccSHddogNI
+tWKa0pIrYyH7y7jB/UzstFSnsOXAf4H6Xt70VUrFPq1/dRRw1CtSLA1sFspBAD8v
+aGl9R0XqWOk1t60mfgES9b4LJu46cTm7UMfyC7EbWkqHYWqf15umRgwrAoGBAOz4
+nZGqBVBW/ERDs+Imf9NcwDeuwllQ0S9ZBPHF///SQ4Rscz2Bl8GhjhTHldLNJg9k
+HjP8W2BOPas66K3WM+WC3AiGrdJfs6Ju3r27X4wA0hnNc6bcoRaoSNRaqThSkgCH
+l34l7yrB1gwpa5HlIfYXjHfJ7coX7WRMQK7wmVsVAoGBAJ/Y97z/DuSAgpYn7+Qm
+vDfuIETZfzjJ2H/L3VtVxjQFJrKwQiZ3e1RRhoPhK/bC79bSM8yRWwSHHLKIOB2X
+HfPp2eFX/i9sxBMtNaPLRtJG5s/a3LvYYR5FNdvXRPzKPNFy0Q8EFgofyS8Fu9iD
+02FdkSbDBoKpgZtd61w93TcNAoGBAKtM4SKeRC8aYku6oTtW10pkHvNhmk5UVJMk
+h6V6mx9D0NjWSMvqdVhcv8eXq19yOxQfLJIp16gbhwrTj8WyNVuwp/xl1xtfYQyH
+lu6Sl3QuV7KdSQATN0OYrOUNEIyNa8uEOOfQ5j4DVwb9niwd9dnelgU17HYNq+a4
+FH4hoMotAoGBAJk/9+RPAdxqJsr/oVp9E4wU9ffpZ2Lr0faN7/WqBFPPhhFOMWu2
+zj8fcRaP/9Wv9g2xK/GfCKhrX8FMfq/NMkZsNx6V3W0M8Zbarp9ZvA4Sj0OvsZAO
+J1NQjkvFjMCE0A29jtjY1zRmLzoC+Ds7Ola8IOKvAN8SM1X/CC6bOgGz
+-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/plugin/exception/rubygems_plugin.rb b/test/rubygems/plugin/exception/rubygems_plugin.rb
new file mode 100644
index 0000000000..16c417e84d
--- /dev/null
+++ b/test/rubygems/plugin/exception/rubygems_plugin.rb
@@ -0,0 +1,2 @@
+TestGem::TEST_PLUGIN_EXCEPTION = :loaded
+raise Exception.new('boom')
diff --git a/test/rubygems/plugin/load/rubygems_plugin.rb b/test/rubygems/plugin/load/rubygems_plugin.rb
new file mode 100644
index 0000000000..c7c72777aa
--- /dev/null
+++ b/test/rubygems/plugin/load/rubygems_plugin.rb
@@ -0,0 +1,3 @@
+class TestGem
+ TEST_PLUGIN_LOAD = :loaded
+end
diff --git a/test/rubygems/plugin/standarderror/rubygems_plugin.rb b/test/rubygems/plugin/standarderror/rubygems_plugin.rb
new file mode 100644
index 0000000000..4b577a6518
--- /dev/null
+++ b/test/rubygems/plugin/standarderror/rubygems_plugin.rb
@@ -0,0 +1,2 @@
+TestGem::TEST_PLUGIN_STANDARDERROR = :loaded
+raise StandardError.new('boom')
diff --git a/test/rubygems/private_key.pem b/test/rubygems/private_key.pem
new file mode 100644
index 0000000000..c6ed3fc24e
--- /dev/null
+++ b/test/rubygems/private_key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAp2U1hy8UHrGClPxByczJtV6UYtQrJAv+FA9Mr0nkXKoHyEQM
+u3au4zAqwdTp+7+aAb6wu8cXWepaFkAOGfqvAJ80/TfTbm+S05nqIl9TrS/K1j9/
+eCSIY2Q/bWXSHPT4yzXl/7naCT6wVerAYFsO14jTHntSweL4oA3rtC48Oe2FgO3C
+FcgDmlx3HbAf41bwXzYcRm+bWFykDvkENWTi8/GekN+884pJif11aCGZS1o+arJW
++zxeQPEcN9jnj8PfOI96E/7NDMSDwLTtKr/Pq8tI5De5pifScEO40Tpc/eKMnhm+
+zZ4kR04zJLUfcKyeRaJ48Ksu0p3Dx38X4PluhwIDAQABAoIBAAx09qfJtBiYoxwN
+LaQjzjrl/+re2RsEnXLGtLEysYDH0m5vyfbFXTxg4D2uZ38pgf9xPluq9CznyK5x
+M9txEUbdkibp2Z0VRnrisE7Ag0yXCuQos4awSUoEMsgkVJ99B2qv5x7BqN0ZQiwS
+nSBOhms5rmRNTxpIlrHqd0jgS/EPggnqVzNcM4/K8PJFthwEBKDmzOyiRByvz54Y
+shzOnTjGtV2oGNgwpzmCXce1yO7dh2IdKnSnmeFwyU88GxEYnGh5MIFuTiyErP72
+k6iEUfiXy0hxk/iXmKs8UyD1lVnwTNWcZcpV8yw4a06Z6nkSnwQm0SSOVIo/w35V
+jdVdUkECgYEA3GhZ70MD/Q47GFvz6BovwQvxhjFN+nIEbBfi7OTkuXprKdhVhjaR
+nERPZpZjHWrcfgbFcvPY7/GJLTPN/VF1nhOsOZpzfAmCgBujRXrzlAGpU877ZNJA
+QKPgzo+iv/RsQCIdrzF1gwHkqD2v1HRLaqb2+dVumiG4Qp3NXgasT2cCgYEAwm1U
+uRDXgQKGODeLK8eSVpfMjD5umBVu7m4D3ZmipbN6sMBxGMAlsU40eQ7DBFH0AFft
+s2D88JdjlwoOrbXYYpOc6iWD/QkygJfPpA9VQx92hv8KBd82gLHuXYMd0T0G3yZO
+gPPioeRgl2TvgVCfjn6AYr3Ubt3rB5aBlSplE+ECgYEAiXhcf6rg1fkGSs8vddi/
+aDy2y+f8pvRuZa0QUIkDT9xW8qaH0Uo/z6ObknTCJRr9o209wdDtwdp4oMTq+dDQ
+92N1zAfVd8vGpXiXgUKKognXPvqeOegZQzfzg2J7NBaTXfzpXtgOX0PTBkxTWsOe
+NkslR/YjIedeMc6SxM6MsokCgYA3mTYyGevWe5dQOin1IgPp+UzICg5sNSzcx98Z
+HpcRVWrPYqi00DW3J0sAF0WTVbA17O8PbbvHPTOAfKLH8Alp3xZvKr08vcWQWllJ
+bA0Qvc2SOxptpXAbi0ZDvXvoWtA9PeITJCr56qnogTewPhLyl6A1HF3EOne8WsDB
+nDb9YQKBgEyUDWhDBGXUfQN0fWy5ksqCCeHXQzvt6aEUstWvkkbnnarUfLAhBIqC
+2B6omokICmWzvAfDt3UsRbb3QJUBxbbVsZVM7Vr+kY2cQ1Ma093I/2mXDoq3bV+j
+LZM5+Uc7xSfiCi1hbVhGm96DXofudddo86W5mhXp3xhcQP1Fl4JZ
+-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/public_cert.pem b/test/rubygems/public_cert.pem
new file mode 100644
index 0000000000..5642a6f4ef
--- /dev/null
+++ b/test/rubygems/public_cert.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC7jCCAdagAwIBAgIBEDANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTEyMTIwODAwMDAwMFoYDzk5
+OTkxMjMxMjM1OTU5WjAqMQ8wDQYDVQQDDAZub2JvZHkxFzAVBgoJkiaJk/IsZAEZ
+FgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp2U1hy8U
+HrGClPxByczJtV6UYtQrJAv+FA9Mr0nkXKoHyEQMu3au4zAqwdTp+7+aAb6wu8cX
+WepaFkAOGfqvAJ80/TfTbm+S05nqIl9TrS/K1j9/eCSIY2Q/bWXSHPT4yzXl/7na
+CT6wVerAYFsO14jTHntSweL4oA3rtC48Oe2FgO3CFcgDmlx3HbAf41bwXzYcRm+b
+WFykDvkENWTi8/GekN+884pJif11aCGZS1o+arJW+zxeQPEcN9jnj8PfOI96E/7N
+DMSDwLTtKr/Pq8tI5De5pifScEO40Tpc/eKMnhm+zZ4kR04zJLUfcKyeRaJ48Ksu
+0p3Dx38X4PluhwIDAQABox0wGzAZBgNVHREEEjAQgQ5ub2JvZHlAZXhhbXBsZTAN
+BgkqhkiG9w0BAQUFAAOCAQEAVmEqsyWID85F39fRKe09sFfguIAUJ8H7/8N9lHP/
+dBLbHmESgPaqh0u57Ys3Jf73ecVtJ93CYJlescvytg16rzLpbEwrojvJwYtLLeLP
+Nx0pKopmJ5+/wxvymrmq149mc9esQXgS1SSAN0X3mcYLNcsAQj4p1vG/1Q8GxMO3
+F655Dqj/8RFXDQOM6yEjRTaOrm1bYGSENog3K7aVGcfYfQeFf97QBId84Ov8B1NY
+EmZsUGqvGkMzfj7y7sWBlFqeZl8HUtGp9dFW7ONg+Ui8Gtqdxv43YFdEg3cA7juj
+X9Abwpdj93pgmleN6zEyT0hYx5S7/dadxLgZat+NTpXnrA==
+-----END CERTIFICATE-----
diff --git a/test/rubygems/public_cert_32.pem b/test/rubygems/public_cert_32.pem
new file mode 100644
index 0000000000..dcc8a62214
--- /dev/null
+++ b/test/rubygems/public_cert_32.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC7DCCAdSgAwIBAgIBETANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv
+ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTEyMTIwODAwMDAwMFoXDTM4
+MDExOTAzMTQwN1owKjEPMA0GA1UEAwwGbm9ib2R5MRcwFQYKCZImiZPyLGQBGRYH
+ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdlNYcvFB6x
+gpT8QcnMybVelGLUKyQL/hQPTK9J5FyqB8hEDLt2ruMwKsHU6fu/mgG+sLvHF1nq
+WhZADhn6rwCfNP03025vktOZ6iJfU60vytY/f3gkiGNkP21l0hz0+Ms15f+52gk+
+sFXqwGBbDteI0x57UsHi+KAN67QuPDnthYDtwhXIA5pcdx2wH+NW8F82HEZvm1hc
+pA75BDVk4vPxnpDfvPOKSYn9dWghmUtaPmqyVvs8XkDxHDfY54/D3ziPehP+zQzE
+g8C07Sq/z6vLSOQ3uaYn0nBDuNE6XP3ijJ4Zvs2eJEdOMyS1H3CsnkWiePCrLtKd
+w8d/F+D5bocCAwEAAaMdMBswGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwDQYJ
+KoZIhvcNAQEFBQADggEBABx3grWVpcJ2RRP/vhT9X7xxdAeEwNahEb4pqHcN57Mm
+S1vH1anaNk9BK4sZLf82Ers6DeGQC8PrBunwBvCdOhFvBMBgcUDGzjJgMyc4RXmi
+0WQPtWXjntXtNm3mlvJM7k4ezMLZwUIRL7+UQXewdM778phZdDVoqpuInAiz/A/x
++gJvTJF4lUVf7wEwNljrRIIOGZaX1S/qJb1rw+hugbB6kA2WLJehsZfzSNxaM+cT
+LlgUh2luXvX1ZSwMQJ1SrZQ9rZLwuaBV2kcVUfAi0peQ03ETZdhjrMRmIbpa+iw5
+vmviY+p7FvjhkwCrVNjiF0CEtPAL3dGi2YHBMDkWY3U=
+-----END CERTIFICATE-----
diff --git a/test/rubygems/public_key.pem b/test/rubygems/public_key.pem
new file mode 100644
index 0000000000..7c29dcd614
--- /dev/null
+++ b/test/rubygems/public_key.pem
@@ -0,0 +1,9 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp2U1hy8UHrGClPxByczJ
+tV6UYtQrJAv+FA9Mr0nkXKoHyEQMu3au4zAqwdTp+7+aAb6wu8cXWepaFkAOGfqv
+AJ80/TfTbm+S05nqIl9TrS/K1j9/eCSIY2Q/bWXSHPT4yzXl/7naCT6wVerAYFsO
+14jTHntSweL4oA3rtC48Oe2FgO3CFcgDmlx3HbAf41bwXzYcRm+bWFykDvkENWTi
+8/GekN+884pJif11aCGZS1o+arJW+zxeQPEcN9jnj8PfOI96E/7NDMSDwLTtKr/P
+q8tI5De5pifScEO40Tpc/eKMnhm+zZ4kR04zJLUfcKyeRaJ48Ksu0p3Dx38X4Plu
+hwIDAQAB
+-----END PUBLIC KEY-----
diff --git a/test/rubygems/rubygems/commands/crash_command.rb b/test/rubygems/rubygems/commands/crash_command.rb
new file mode 100644
index 0000000000..624be9fd32
--- /dev/null
+++ b/test/rubygems/rubygems/commands/crash_command.rb
@@ -0,0 +1,5 @@
+class Gem::Commands::CrashCommand < Gem::Command
+
+ raise "crash"
+
+end
diff --git a/test/rubygems/rubygems_plugin.rb b/test/rubygems/rubygems_plugin.rb
new file mode 100644
index 0000000000..6c08f97c6d
--- /dev/null
+++ b/test/rubygems/rubygems_plugin.rb
@@ -0,0 +1,21 @@
+require 'rubygems/command_manager'
+
+##
+# This is an example of exactly what NOT to do.
+#
+# DO NOT include code like this in your rubygems_plugin.rb
+
+class Gem::Commands::InterruptCommand < Gem::Command
+
+ def initialize
+ super('interrupt', 'Raises an Interrupt Exception', {})
+ end
+
+ def execute
+ raise Interrupt, "Interrupt exception"
+ end
+
+end
+
+Gem::CommandManager.instance.register_command :interrupt
+
diff --git a/test/rubygems/sff/discover.rb b/test/rubygems/sff/discover.rb
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/rubygems/sff/discover.rb
diff --git a/test/rubygems/simple_gem.rb b/test/rubygems/simple_gem.rb
new file mode 100644
index 0000000000..d7c035675c
--- /dev/null
+++ b/test/rubygems/simple_gem.rb
@@ -0,0 +1,66 @@
+SIMPLE_GEM = <<-GEMDATA
+ MD5SUM = "989bf34a1cbecd52e0ea66b662b3a405"
+ if $0 == __FILE__
+ require 'optparse'
+
+ options = {}
+ ARGV.options do |opts|
+ opts.on_tail("--help", "show this message") {puts opts; exit}
+ opts.on('--dir=DIRNAME', "Installation directory for the Gem") {|options[:directory]|}
+ opts.on('--force', "Force Gem to install, bypassing dependency checks") {|options[:force]|}
+ opts.on('--gen-rdoc', "Generate RDoc documentation for the Gem") {|options[:gen_rdoc]|}
+ opts.parse!
+ end
+
+ require 'rubygems'
+ @directory = options[:directory] || Gem.dir
+ @force = options[:force]
+
+ gem = Gem::Installer.new(__FILE__).install(@force, @directory)
+ if options[:gen_rdoc]
+ Gem::DocManager.new(gem).generate_rdoc
+ end
+end
+
+__END__
+--- !ruby/object:Gem::Specification
+rubygems_version: "1.0"
+name: testing
+version: !ruby/object:Gem::Version
+ version: 1.2.3
+date: 2004-03-18 22:01:52.859121 -05:00
+platform:
+summary: This exercise the gem testing stuff.
+require_paths:
+ - lib
+files:
+ - lib/foo.rb
+ - lib/test
+ - lib/test.rb
+ - lib/test/wow.rb
+autorequire: test
+test_suite_file: foo
+requirements:
+ - a computer processor
+---
+-
+ size: 109
+ mode: 420
+ path: lib/foo.rb
+-
+ size: 0
+ mode: 420
+ path: lib/test.rb
+-
+ size: 15
+ mode: 420
+ path: lib/test/wow.rb
+---
+eJwVjDEKgDAUQ/eeIpsKguhY3ARPoHMp9quF0mL7e39/h5DwQpLpqz4TOqbC
+U42eO6WuYEvBntIhECuaaX1KqXXLmy2kAEc32szExK+PjyBAlpTZyK0N/Twu
+g1CKTjX9BGAj1w==
+---
+eJwDAAAAAAE=
+---
+eJwrKC0pVlAvzy9XyE3MU+cCACwiBP4=
+GEMDATA
diff --git a/test/rubygems/specifications/bar-0.0.2.gemspec b/test/rubygems/specifications/bar-0.0.2.gemspec
new file mode 100644
index 0000000000..ceefa4ed16
--- /dev/null
+++ b/test/rubygems/specifications/bar-0.0.2.gemspec
@@ -0,0 +1,9 @@
+# -*- encoding: utf-8 -*-
+
+Gem::Specification.new do |s|
+ s.name = "bar"
+ s.version = "0.0.2"
+ s.platform = "ruby"
+ s.require_paths = ["lib"]
+ s.summary = "A very bar gem"
+end
diff --git a/test/rubygems/specifications/foo-0.0.1.gemspec b/test/rubygems/specifications/foo-0.0.1.gemspec
new file mode 100644
index 0000000000..7fbc56429f
--- /dev/null
+++ b/test/rubygems/specifications/foo-0.0.1.gemspec
Binary files differ
diff --git a/test/rubygems/ssl_cert.pem b/test/rubygems/ssl_cert.pem
new file mode 100644
index 0000000000..998ccc5892
--- /dev/null
+++ b/test/rubygems/ssl_cert.pem
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIC/zCCAeegAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQGDAJKUDES
+MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxDjAMBgNVBAMMBVN1YkNB
+MB4XDTA0MDEzMTAzMTMxNloXDTMzMDEyMzAzMTMxNlowQzELMAkGA1UEBgwCSlAx
+EjAQBgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMRIwEAYDVQQDDAlsb2Nh
+bGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANFJTxWqup3nV9dsJAku
+p+WaXnPNIzcpAA3qMGZDJTJsfa8Du7ZxTP0XJK5mETttBrn711cJxAuP3KjqnW9S
+vtZ9lY2sXJ6Zj62sN5LwG3VVe25dI28yR1EsbHjJ5Zjf9tmggMC6am52dxuHbt5/
+vHo4ngJuKE/U+eeGRivMn6gFAgMBAAGjgYUwgYIwDAYDVR0TAQH/BAIwADAxBglg
+hkgBhvhCAQ0EJBYiUnVieS9PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAd
+BgNVHQ4EFgQUpZIyygD9JxFYHHOTEuWOLbCKfckwCwYDVR0PBAQDAgWgMBMGA1Ud
+JQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBBQUAA4IBAQBwAIj5SaBHaA5X31IP
+CFCJiep96awfp7RANO0cuUj+ZpGoFn9d6FXY0g+Eg5wAkCNIzZU5NHN9xsdOpnUo
+zIBbyTfQEPrge1CMWMvL6uGaoEXytq84VTitF/xBTky4KtTn6+es4/e7jrrzeUXQ
+RC46gkHObmDT91RkOEGjHLyld2328jo3DIN/VTHIryDeVHDWjY5dENwpwdkhhm60
+DR9IrNBbXWEe9emtguNXeN0iu1ux0lG1Hc6pWGQxMlRKNvGh0yZB9u5EVe38tOV0
+jQaoNyL7qzcQoXD3Dmbi1p0iRmg/+HngISsz8K7k7MBNVsSclztwgCzTZOBiVtkM
+rRlQ
+-----END CERTIFICATE-----
diff --git a/test/rubygems/ssl_key.pem b/test/rubygems/ssl_key.pem
new file mode 100644
index 0000000000..9ba2218a03
--- /dev/null
+++ b/test/rubygems/ssl_key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDRSU8Vqrqd51fXbCQJLqflml5zzSM3KQAN6jBmQyUybH2vA7u2
+cUz9FySuZhE7bQa5+9dXCcQLj9yo6p1vUr7WfZWNrFyemY+trDeS8Bt1VXtuXSNv
+MkdRLGx4yeWY3/bZoIDAumpudncbh27ef7x6OJ4CbihP1PnnhkYrzJ+oBQIDAQAB
+AoGBAIf4CstW2ltQO7+XYGoex7Hh8s9lTSW/G2vu5Hbr1LTHy3fzAvdq8MvVR12O
+rk9fa+lU9vhzPc0NMB0GIDZ9GcHuhW5hD1Wg9OSCbTOkZDoH3CAFqonjh4Qfwv5W
+IPAFn9KHukdqGXkwEMdErsUaPTy9A1V/aROVEaAY+HJgq/eZAkEA/BP1QMV04WEZ
+Oynzz7/lLizJGGxp2AOvEVtqMoycA/Qk+zdKP8ufE0wbmCE3Qd6GoynavsHb6aGK
+gQobb8zDZwJBANSK6MrXlrZTtEaeZuyOB4mAmRzGzOUVkUyULUjEx2GDT93ujAma
+qm/2d3E+wXAkNSeRpjUmlQXy/2oSqnGvYbMCQQDRM+cYyEcGPUVpWpnj0shrF/QU
+9vSot/X1G775EMTyaw6+BtbyNxVgOIu2J+rqGbn3c+b85XqTXOPL0A2RLYkFAkAm
+syhSDtE9X55aoWsCNZY/vi+i4rvaFoQ/WleogVQAeGVpdo7/DK9t9YWoFBIqth0L
+mGSYFu9ZhvZkvQNV8eYrAkBJ+rOIaLDsmbrgkeDruH+B/9yrm4McDtQ/rgnOGYnH
+LjLpLLOrgUxqpzLWe++EwSLwK2//dHO+SPsQJ4xsyQJy
+-----END RSA PRIVATE KEY-----
diff --git a/test/rubygems/test_bundled_ca.rb b/test/rubygems/test_bundled_ca.rb
new file mode 100644
index 0000000000..711cd1b8f2
--- /dev/null
+++ b/test/rubygems/test_bundled_ca.rb
@@ -0,0 +1,60 @@
+require 'rubygems/test_case'
+require 'net/https'
+require 'rubygems/request'
+
+# = Testing Bundled CA
+#
+# The tested hosts are explained in detail here: https://github.com/rubygems/rubygems/commit/5e16a5428f973667cabfa07e94ff939e7a83ebd9
+#
+class TestBundledCA < Gem::TestCase
+
+ THIS_FILE = File.expand_path __FILE__
+
+ def bundled_certificate_store
+ store = OpenSSL::X509::Store.new
+
+ ssl_cert_glob =
+ File.expand_path '../../../lib/rubygems/ssl_certs/*.pem', THIS_FILE
+
+ Dir[ssl_cert_glob].each do |ssl_cert|
+ store.add_file ssl_cert
+ end
+
+ store
+ end
+
+ def assert_https(host)
+ if self.respond_to? :_assertions # minitest <= 4
+ self._assertions += 1
+ else # minitest >= 5
+ self.assertions += 1
+ end
+ http = Net::HTTP.new(host, 443)
+ http.use_ssl = true
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
+ http.cert_store = bundled_certificate_store
+ http.get('/')
+ rescue Errno::ENOENT, Errno::ETIMEDOUT
+ skip "#{host} seems offline, I can't tell whether ssl would work."
+ rescue OpenSSL::SSL::SSLError => e
+ # Only fail for certificate verification errors
+ if e.message =~ /certificate verify failed/
+ flunk "#{host} is not verifiable using the included certificates. Error was: #{e.message}"
+ end
+ raise
+ end
+
+ def test_accessing_rubygems
+ assert_https('rubygems.org')
+ end
+
+ def test_accessing_cloudfront
+ assert_https('d2chzxaqi4y7f8.cloudfront.net')
+ end
+
+ def test_accessing_s3
+ assert_https('s3.amazonaws.com')
+ end
+
+end if ENV['TRAVIS']
+
diff --git a/test/rubygems/test_config.rb b/test/rubygems/test_config.rb
new file mode 100644
index 0000000000..7829e90dcf
--- /dev/null
+++ b/test/rubygems/test_config.rb
@@ -0,0 +1,14 @@
+require 'rubygems/test_case'
+require 'rubygems'
+
+class TestConfig < Gem::TestCase
+
+ def test_datadir
+ util_make_gems
+ spec = Gem::Specification.find_by_name("a")
+ spec.activate
+ assert_equal "#{spec.full_gem_path}/data/a", Gem.datadir('a')
+ end
+
+end
+
diff --git a/test/rubygems/test_deprecate.rb b/test/rubygems/test_deprecate.rb
new file mode 100644
index 0000000000..ed4e9aa5ff
--- /dev/null
+++ b/test/rubygems/test_deprecate.rb
@@ -0,0 +1,76 @@
+require 'rubygems/test_case'
+# require 'rubygems/builder'
+# require 'rubygems/package'
+require 'rubygems/deprecate'
+
+class TestDeprecate < Gem::TestCase
+
+ def setup
+ super
+
+ # Gem::Deprecate.saved_warnings.clear
+ @original_skip = Gem::Deprecate.skip
+ Gem::Deprecate.skip = false
+ end
+
+ def teardown
+ super
+
+ # Gem::Deprecate.saved_warnings.clear
+ Gem::Deprecate.skip = @original_skip
+ end
+
+ def test_defaults
+ assert_equal false, @original_skip
+ end
+
+ def test_assignment
+ Gem::Deprecate.skip = false
+ assert_equal false, Gem::Deprecate.skip
+
+ Gem::Deprecate.skip = true
+ assert_equal true, Gem::Deprecate.skip
+
+ Gem::Deprecate.skip = nil
+ assert([true,false].include? Gem::Deprecate.skip)
+ end
+
+ def test_skip
+ Gem::Deprecate.skip_during do
+ assert_equal true, Gem::Deprecate.skip
+ end
+
+ Gem::Deprecate.skip = nil
+ end
+
+ class Thing
+ extend Gem::Deprecate
+ attr_accessor :message
+ def foo
+ @message = "foo"
+ end
+ def bar
+ @message = "bar"
+ end
+ deprecate :foo, :bar, 2099, 3
+ end
+
+ def test_deprecated_method_calls_the_old_method
+ capture_io do
+ thing = Thing.new
+ thing.foo
+ assert_equal "foo", thing.message
+ end
+ end
+
+ def test_deprecated_method_outputs_a_warning
+ out, err = capture_io do
+ thing = Thing.new
+ thing.foo
+ end
+
+ assert_equal "", out
+ assert_match(/Thing#foo is deprecated; use bar instead\./, err)
+ assert_match(/on or after 2099-03-01/, err)
+ end
+end
diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb
new file mode 100644
index 0000000000..0da28bb9fb
--- /dev/null
+++ b/test/rubygems/test_gem.rb
@@ -0,0 +1,1593 @@
+# coding: US-ASCII
+require 'rubygems/test_case'
+require 'rubygems'
+require 'rubygems/command'
+require 'rubygems/installer'
+require 'pathname'
+require 'tmpdir'
+
+# TODO: push this up to test_case.rb once battle tested
+$SAFE=1
+$LOAD_PATH.map! do |path|
+ path.dup.untaint
+end
+
+class TestGem < Gem::TestCase
+
+ PLUGINS_LOADED = []
+
+ def setup
+ super
+
+ PLUGINS_LOADED.clear
+
+ common_installer_setup
+
+ ENV.delete 'RUBYGEMS_GEMDEPS'
+ @additional = %w[a b].map { |d| File.join @tempdir, d }
+
+ util_remove_interrupt_command
+ end
+
+ def test_self_finish_resolve
+ save_loaded_features do
+ a1 = new_spec "a", "1", "b" => "> 0"
+ b1 = new_spec "b", "1", "c" => ">= 1"
+ b2 = new_spec "b", "2", "c" => ">= 2"
+ c1 = new_spec "c", "1"
+ c2 = new_spec "c", "2"
+
+ install_specs a1, b1, b2, c1, c2
+
+ a1.activate
+
+ assert_equal %w(a-1), loaded_spec_names
+ assert_equal ["b (> 0)"], unresolved_names
+
+ Gem.finish_resolve
+
+ assert_equal %w(a-1 b-2 c-2), loaded_spec_names
+ assert_equal [], unresolved_names
+ end
+ end
+
+ def test_self_finish_resolve_wtf
+ save_loaded_features do
+ a1 = new_spec "a", "1", "b" => "> 0", "d" => "> 0" # this
+ b1 = new_spec "b", "1", { "c" => ">= 1" }, "lib/b.rb" # this
+ b2 = new_spec "b", "2", { "c" => ">= 2" }, "lib/b.rb"
+ c1 = new_spec "c", "1" # this
+ c2 = new_spec "c", "2"
+ d1 = new_spec "d", "1", { "c" => "< 2" }, "lib/d.rb"
+ d2 = new_spec "d", "2", { "c" => "< 2" }, "lib/d.rb" # this
+
+ install_specs a1, b1, b2, c1, c2, d1, d2
+
+ a1.activate
+
+ assert_equal %w(a-1), loaded_spec_names
+ assert_equal ["b (> 0)", "d (> 0)"], unresolved_names
+
+ Gem.finish_resolve
+
+ assert_equal %w(a-1 b-1 c-1 d-2), loaded_spec_names
+ assert_equal [], unresolved_names
+ end
+ end
+
+ def test_self_install
+ spec_fetcher do |f|
+ f.gem 'a', 1
+ f.spec 'a', 2
+ end
+
+ gemhome2 = "#{@gemhome}2"
+
+ installed = Gem.install 'a', '= 1', :install_dir => gemhome2
+
+ assert_equal %w[a-1], installed.map { |spec| spec.full_name }
+
+ assert_path_exists File.join(gemhome2, 'gems', 'a-1')
+ end
+
+ def test_require_missing
+ save_loaded_features do
+ assert_raises ::LoadError do
+ require "q"
+ end
+ end
+ end
+
+ def test_require_does_not_glob
+ save_loaded_features do
+ a1 = new_spec "a", "1", nil, "lib/a1.rb"
+
+ install_specs a1
+
+ assert_raises ::LoadError do
+ require "a*"
+ end
+
+ assert_equal [], loaded_spec_names
+ end
+ end
+
+ def test_self_bin_path_no_exec_name
+ e = assert_raises ArgumentError do
+ Gem.bin_path 'a'
+ end
+
+ assert_equal 'you must supply exec_name', e.message
+ end
+
+ def test_self_bin_path_bin_name
+ util_exec_gem
+ assert_equal @abin_path, Gem.bin_path('a', 'abin')
+ end
+
+ def test_self_bin_path_bin_name_version
+ util_exec_gem
+ assert_equal @abin_path, Gem.bin_path('a', 'abin', '4')
+ end
+
+ def test_self_bin_path_nonexistent_binfile
+ util_spec 'a', '2' do |s|
+ s.executables = ['exec']
+ end
+ assert_raises(Gem::GemNotFoundException) do
+ Gem.bin_path('a', 'other', '2')
+ end
+ end
+
+ def test_self_bin_path_no_bin_file
+ util_spec 'a', '1'
+ assert_raises(ArgumentError) do
+ Gem.bin_path('a', nil, '1')
+ end
+ end
+
+ def test_self_bin_path_not_found
+ assert_raises(Gem::GemNotFoundException) do
+ Gem.bin_path('non-existent', 'blah')
+ end
+ end
+
+ def test_self_bin_path_bin_file_gone_in_latest
+ util_exec_gem
+ util_spec 'a', '10' do |s|
+ s.executables = []
+ end
+ # Should not find a-10's non-abin (bug)
+ assert_equal @abin_path, Gem.bin_path('a', 'abin')
+ end
+
+ def test_self_bindir
+ assert_equal File.join(@gemhome, 'bin'), Gem.bindir
+ assert_equal File.join(@gemhome, 'bin'), Gem.bindir(Gem.dir)
+ assert_equal File.join(@gemhome, 'bin'), Gem.bindir(Pathname.new(Gem.dir))
+ end
+
+ def test_self_bindir_default_dir
+ default = Gem.default_dir
+
+ assert_equal Gem.default_bindir, Gem.bindir(default)
+ end
+
+ def test_self_clear_paths
+ assert_match(/gemhome$/, Gem.dir)
+ assert_match(/gemhome$/, Gem.path.first)
+
+ Gem.clear_paths
+
+ assert_nil Gem::Specification.send(:class_variable_get, :@@all)
+ end
+
+ def test_self_configuration
+ expected = Gem::ConfigFile.new []
+ Gem.configuration = nil
+
+ assert_equal expected, Gem.configuration
+ end
+
+ def test_self_datadir
+ foo = nil
+
+ Dir.chdir @tempdir do
+ FileUtils.mkdir_p 'data'
+ File.open File.join('data', 'foo.txt'), 'w' do |fp|
+ fp.puts 'blah'
+ end
+
+ foo = util_spec 'foo' do |s| s.files = %w[data/foo.txt] end
+ install_gem foo
+ end
+
+ gem 'foo'
+
+ expected = File.join @gemhome, 'gems', foo.full_name, 'data', 'foo'
+
+ assert_equal expected, Gem.datadir('foo')
+ end
+
+ def test_self_datadir_nonexistent_package
+ assert_nil Gem.datadir('xyzzy')
+ end
+
+ def test_self_default_exec_format
+ ruby_install_name 'ruby' do
+ assert_equal '%s', Gem.default_exec_format
+ end
+ end
+
+ def test_self_default_exec_format_18
+ ruby_install_name 'ruby18' do
+ assert_equal '%s18', Gem.default_exec_format
+ end
+ end
+
+ def test_self_default_exec_format_jruby
+ ruby_install_name 'jruby' do
+ assert_equal 'j%s', Gem.default_exec_format
+ end
+ end
+
+ def test_default_path
+ orig_vendordir = RbConfig::CONFIG['vendordir']
+ RbConfig::CONFIG['vendordir'] = File.join @tempdir, 'vendor'
+
+ FileUtils.rm_rf Gem.user_home
+
+ expected = [Gem.default_dir]
+
+ assert_equal expected, Gem.default_path
+ ensure
+ RbConfig::CONFIG['vendordir'] = orig_vendordir
+ end
+
+ def test_default_path_missing_vendor
+ orig_vendordir = RbConfig::CONFIG['vendordir']
+ RbConfig::CONFIG.delete 'vendordir'
+
+ FileUtils.rm_rf Gem.user_home
+
+ expected = [Gem.default_dir]
+
+ assert_equal expected, Gem.default_path
+ ensure
+ RbConfig::CONFIG['vendordir'] = orig_vendordir
+ end
+
+ def test_default_path_user_home
+ orig_vendordir = RbConfig::CONFIG['vendordir']
+ RbConfig::CONFIG['vendordir'] = File.join @tempdir, 'vendor'
+
+ expected = [Gem.user_dir, Gem.default_dir]
+
+ assert_equal expected, Gem.default_path
+ ensure
+ RbConfig::CONFIG['vendordir'] = orig_vendordir
+ end
+
+ def test_default_path_vendor_dir
+ orig_vendordir = RbConfig::CONFIG['vendordir']
+ RbConfig::CONFIG['vendordir'] = File.join @tempdir, 'vendor'
+
+ FileUtils.mkdir_p Gem.vendor_dir
+
+ FileUtils.rm_rf Gem.user_home
+
+ expected = [Gem.default_dir, Gem.vendor_dir]
+
+ assert_equal expected, Gem.default_path
+ ensure
+ RbConfig::CONFIG['vendordir'] = orig_vendordir
+ end
+
+ def test_self_default_sources
+ assert_equal %w[https://rubygems.org/], Gem.default_sources
+ end
+
+ def test_self_detect_gemdeps
+ skip 'Insecure operation - chdir' if RUBY_VERSION <= "1.8.7"
+ rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], '-'
+
+ FileUtils.mkdir_p 'detect/a/b'
+ FileUtils.mkdir_p 'detect/a/Isolate'
+
+ FileUtils.touch 'detect/Isolate'
+
+ begin
+ Dir.chdir 'detect/a/b'
+
+ assert_empty Gem.detect_gemdeps
+ ensure
+ Dir.chdir @tempdir
+ end
+ ensure
+ ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
+ end
+
+ def test_self_dir
+ assert_equal @gemhome, Gem.dir
+ end
+
+ def test_self_ensure_gem_directories
+ FileUtils.rm_r @gemhome
+ Gem.use_paths @gemhome
+
+ Gem.ensure_gem_subdirectories @gemhome
+
+ assert_path_exists File.join @gemhome, 'build_info'
+ assert_path_exists File.join @gemhome, 'cache'
+ assert_path_exists File.join @gemhome, 'doc'
+ assert_path_exists File.join @gemhome, 'extensions'
+ assert_path_exists File.join @gemhome, 'gems'
+ assert_path_exists File.join @gemhome, 'specifications'
+ end
+
+ def test_self_ensure_gem_directories_permissions
+ FileUtils.rm_r @gemhome
+ Gem.use_paths @gemhome
+
+ Gem.ensure_gem_subdirectories @gemhome, 0750
+
+ assert File.directory? File.join(@gemhome, "cache")
+
+ assert_equal 0750, File::Stat.new(@gemhome).mode & 0777
+ assert_equal 0750, File::Stat.new(File.join(@gemhome, "cache")).mode & 0777
+ end unless win_platform?
+
+ def test_self_ensure_gem_directories_safe_permissions
+ FileUtils.rm_r @gemhome
+ Gem.use_paths @gemhome
+
+ old_umask = File.umask
+ File.umask 0
+ Gem.ensure_gem_subdirectories @gemhome
+
+ assert_equal 0, File::Stat.new(@gemhome).mode & 002
+ assert_equal 0, File::Stat.new(File.join(@gemhome, "cache")).mode & 002
+ ensure
+ File.umask old_umask
+ end unless win_platform?
+
+ def test_self_ensure_gem_directories_missing_parents
+ gemdir = File.join @tempdir, 'a/b/c/gemdir'
+ FileUtils.rm_rf File.join(@tempdir, 'a') rescue nil
+ refute File.exist?(File.join(@tempdir, 'a')),
+ "manually remove #{File.join @tempdir, 'a'}, tests are broken"
+ Gem.use_paths gemdir
+
+ Gem.ensure_gem_subdirectories gemdir
+
+ assert File.directory?(util_cache_dir)
+ end
+
+ unless win_platform? then # only for FS that support write protection
+ def test_self_ensure_gem_directories_write_protected
+ gemdir = File.join @tempdir, "egd"
+ FileUtils.rm_r gemdir rescue nil
+ refute File.exist?(gemdir), "manually remove #{gemdir}, tests are broken"
+ FileUtils.mkdir_p gemdir
+ FileUtils.chmod 0400, gemdir
+ Gem.use_paths gemdir
+
+ Gem.ensure_gem_subdirectories gemdir
+
+ refute File.exist?(util_cache_dir)
+ ensure
+ FileUtils.chmod 0600, gemdir
+ end
+
+ def test_self_ensure_gem_directories_write_protected_parents
+ parent = File.join(@tempdir, "egd")
+ gemdir = "#{parent}/a/b/c"
+
+ FileUtils.rm_r parent rescue nil
+ refute File.exist?(parent), "manually remove #{parent}, tests are broken"
+ FileUtils.mkdir_p parent
+ FileUtils.chmod 0400, parent
+ Gem.use_paths(gemdir)
+
+ Gem.ensure_gem_subdirectories gemdir
+
+ refute File.exist? File.join(gemdir, "gems")
+ ensure
+ FileUtils.chmod 0600, parent
+ end
+ end
+
+ def test_self_extension_dir_shared
+ enable_shared 'yes' do
+ assert_equal Gem.ruby_api_version, Gem.extension_api_version
+ end
+ end
+
+ def test_self_extension_dir_static
+ enable_shared 'no' do
+ assert_equal "#{Gem.ruby_api_version}-static", Gem.extension_api_version
+ end
+ end
+
+ def test_self_find_files
+ cwd = File.expand_path("test/rubygems", @@project_dir)
+ $LOAD_PATH.unshift cwd
+
+ discover_path = File.join 'lib', 'sff', 'discover.rb'
+
+ foo1, foo2 = %w(1 2).map { |version|
+ spec = quick_gem 'sff', version do |s|
+ s.files << discover_path
+ end
+
+ write_file(File.join 'gems', spec.full_name, discover_path) do |fp|
+ fp.puts "# #{spec.full_name}"
+ end
+
+ spec
+ }
+
+ Gem.refresh
+
+ expected = [
+ File.expand_path('test/rubygems/sff/discover.rb', @@project_dir),
+ File.join(foo2.full_gem_path, discover_path),
+ File.join(foo1.full_gem_path, discover_path),
+ ]
+
+ assert_equal expected, Gem.find_files('sff/discover')
+ assert_equal expected, Gem.find_files('sff/**.rb'), '[ruby-core:31730]'
+ ensure
+ assert_equal cwd, $LOAD_PATH.shift
+ end
+
+ def test_self_find_latest_files
+ cwd = File.expand_path("test/rubygems", @@project_dir)
+ $LOAD_PATH.unshift cwd
+
+ discover_path = File.join 'lib', 'sff', 'discover.rb'
+
+ _, foo2 = %w(1 2).map { |version|
+ spec = quick_gem 'sff', version do |s|
+ s.files << discover_path
+ end
+
+ write_file(File.join 'gems', spec.full_name, discover_path) do |fp|
+ fp.puts "# #{spec.full_name}"
+ end
+
+ spec
+ }
+
+ Gem.refresh
+
+ expected = [
+ File.expand_path('test/rubygems/sff/discover.rb', @@project_dir),
+ File.join(foo2.full_gem_path, discover_path),
+ ]
+
+ assert_equal expected, Gem.find_latest_files('sff/discover')
+ assert_equal expected, Gem.find_latest_files('sff/**.rb'), '[ruby-core:31730]'
+ ensure
+ assert_equal cwd, $LOAD_PATH.shift
+ end
+
+ def test_self_latest_spec_for
+ gems = spec_fetcher do |fetcher|
+ fetcher.spec 'a', 1
+ fetcher.spec 'a', '3.a'
+ fetcher.spec 'a', 2
+ end
+
+ spec = Gem.latest_spec_for 'a'
+
+ assert_equal gems['a-2'], spec
+ end
+
+ def test_self_latest_rubygems_version
+ spec_fetcher do |fetcher|
+ fetcher.spec 'rubygems-update', '1.8.23'
+ fetcher.spec 'rubygems-update', '1.8.24'
+ fetcher.spec 'rubygems-update', '2.0.0.preview3'
+ end
+
+ version = Gem.latest_rubygems_version
+
+ assert_equal Gem::Version.new('1.8.24'), version
+ end
+
+ def test_self_latest_version_for
+ spec_fetcher do |fetcher|
+ fetcher.spec 'a', 1
+ fetcher.spec 'a', 2
+ fetcher.spec 'a', '3.a'
+ end
+
+ version = Gem.latest_version_for 'a'
+
+ assert_equal Gem::Version.new(2), version
+ end
+
+ def test_self_loaded_specs
+ foo = util_spec 'foo'
+ install_gem foo
+
+ foo.activate
+
+ assert_equal true, Gem.loaded_specs.keys.include?('foo')
+ end
+
+ def util_path
+ ENV.delete "GEM_HOME"
+ ENV.delete "GEM_PATH"
+ end
+
+ def test_self_path
+ assert_equal [Gem.dir], Gem.path
+ end
+
+ def test_self_path_default
+ util_path
+
+ if defined?(APPLE_GEM_HOME)
+ orig_APPLE_GEM_HOME = APPLE_GEM_HOME
+ Object.send :remove_const, :APPLE_GEM_HOME
+ end
+
+ Gem.instance_variable_set :@paths, nil
+
+ assert_equal [Gem.default_path, Gem.dir].flatten.uniq, Gem.path
+ ensure
+ Object.const_set :APPLE_GEM_HOME, orig_APPLE_GEM_HOME if orig_APPLE_GEM_HOME
+ end
+
+ unless win_platform?
+ def test_self_path_APPLE_GEM_HOME
+ util_path
+
+ Gem.clear_paths
+ apple_gem_home = File.join @tempdir, 'apple_gem_home'
+
+ old, $-w = $-w, nil
+ Object.const_set :APPLE_GEM_HOME, apple_gem_home
+ $-w = old
+
+ assert_includes Gem.path, apple_gem_home
+ ensure
+ Object.send :remove_const, :APPLE_GEM_HOME
+ end
+
+ def test_self_path_APPLE_GEM_HOME_GEM_PATH
+ Gem.clear_paths
+ ENV['GEM_PATH'] = @gemhome
+ apple_gem_home = File.join @tempdir, 'apple_gem_home'
+ Gem.const_set :APPLE_GEM_HOME, apple_gem_home
+
+ refute Gem.path.include?(apple_gem_home)
+ ensure
+ Gem.send :remove_const, :APPLE_GEM_HOME
+ end
+ end
+
+ def test_self_path_ENV_PATH
+ path_count = Gem.path.size
+ Gem.clear_paths
+
+ ENV['GEM_PATH'] = @additional.join(File::PATH_SEPARATOR)
+
+ assert_equal @additional, Gem.path[0,2]
+
+ assert_equal path_count + @additional.size, Gem.path.size,
+ "extra path components: #{Gem.path[2..-1].inspect}"
+ assert_equal Gem.dir, Gem.path.last
+ end
+
+ def test_self_path_duplicate
+ Gem.clear_paths
+ util_ensure_gem_dirs
+ dirs = @additional + [@gemhome] + [File.join(@tempdir, 'a')]
+
+ ENV['GEM_HOME'] = @gemhome
+ ENV['GEM_PATH'] = dirs.join File::PATH_SEPARATOR
+
+ assert_equal @gemhome, Gem.dir
+
+ paths = [Gem.dir]
+ assert_equal @additional + paths, Gem.path
+ end
+
+ def test_self_path_overlap
+ Gem.clear_paths
+
+ util_ensure_gem_dirs
+ ENV['GEM_HOME'] = @gemhome
+ ENV['GEM_PATH'] = @additional.join(File::PATH_SEPARATOR)
+
+ assert_equal @gemhome, Gem.dir
+
+ paths = [Gem.dir]
+ assert_equal @additional + paths, Gem.path
+ end
+
+ def test_self_platforms
+ assert_equal [Gem::Platform::RUBY, Gem::Platform.local], Gem.platforms
+ end
+
+ def test_self_prefix
+ assert_equal @@project_dir, Gem.prefix
+ end
+
+ def test_self_prefix_libdir
+ orig_libdir = RbConfig::CONFIG['libdir']
+ RbConfig::CONFIG['libdir'] = @@project_dir
+
+ assert_nil Gem.prefix
+ ensure
+ RbConfig::CONFIG['libdir'] = orig_libdir
+ end
+
+ def test_self_prefix_sitelibdir
+ orig_sitelibdir = RbConfig::CONFIG['sitelibdir']
+ RbConfig::CONFIG['sitelibdir'] = @@project_dir
+
+ assert_nil Gem.prefix
+ ensure
+ RbConfig::CONFIG['sitelibdir'] = orig_sitelibdir
+ end
+
+ def test_self_read_binary
+ open 'test', 'w' do |io|
+ io.write "\xCF\x80"
+ end
+
+ assert_equal ["\xCF", "\x80"], Gem.read_binary('test').chars.to_a
+
+ skip 'chmod not supported' if Gem.win_platform?
+
+ begin
+ File.chmod 0444, 'test'
+
+ assert_equal ["\xCF", "\x80"], Gem.read_binary('test').chars.to_a
+ ensure
+ File.chmod 0644, 'test'
+ end
+ end
+
+ def test_self_refresh
+ skip 'Insecure operation - mkdir' if RUBY_VERSION <= "1.8.7"
+ util_make_gems
+
+ a1_spec = @a1.spec_file
+ moved_path = File.join @tempdir, File.basename(a1_spec)
+
+ FileUtils.mv a1_spec, moved_path
+
+ Gem.refresh
+
+ refute_includes Gem::Specification.all_names, @a1.full_name
+
+ FileUtils.mv moved_path, a1_spec
+
+ Gem.refresh
+
+ assert_includes Gem::Specification.all_names, @a1.full_name
+ end
+
+ def test_self_refresh_keeps_loaded_specs_activated
+ skip 'Insecure operation - mkdir' if RUBY_VERSION <= "1.8.7"
+ util_make_gems
+
+ a1_spec = @a1.spec_file
+ moved_path = File.join @tempdir, File.basename(a1_spec)
+
+ FileUtils.mv a1_spec, moved_path
+
+ Gem.refresh
+
+ s = Gem::Specification.first
+ s.activate
+
+ Gem.refresh
+
+ Gem::Specification.each{|spec| assert spec.activated? if spec == s}
+
+ Gem.loaded_specs.delete(s)
+ Gem.refresh
+ end
+
+ def test_self_ruby_escaping_spaces_in_path
+ orig_ruby = Gem.ruby
+ orig_bindir = RbConfig::CONFIG['bindir']
+ orig_ruby_install_name = RbConfig::CONFIG['ruby_install_name']
+ orig_exe_ext = RbConfig::CONFIG['EXEEXT']
+
+ RbConfig::CONFIG['bindir'] = "C:/Ruby 1.8/bin"
+ RbConfig::CONFIG['ruby_install_name'] = "ruby"
+ RbConfig::CONFIG['EXEEXT'] = ".exe"
+ Gem.instance_variable_set("@ruby", nil)
+
+ assert_equal "\"C:/Ruby 1.8/bin/ruby.exe\"", Gem.ruby
+ ensure
+ Gem.instance_variable_set("@ruby", orig_ruby)
+ RbConfig::CONFIG['bindir'] = orig_bindir
+ RbConfig::CONFIG['ruby_install_name'] = orig_ruby_install_name
+ RbConfig::CONFIG['EXEEXT'] = orig_exe_ext
+ end
+
+ def test_self_ruby_path_without_spaces
+ orig_ruby = Gem.ruby
+ orig_bindir = RbConfig::CONFIG['bindir']
+ orig_ruby_install_name = RbConfig::CONFIG['ruby_install_name']
+ orig_exe_ext = RbConfig::CONFIG['EXEEXT']
+
+ RbConfig::CONFIG['bindir'] = "C:/Ruby18/bin"
+ RbConfig::CONFIG['ruby_install_name'] = "ruby"
+ RbConfig::CONFIG['EXEEXT'] = ".exe"
+ Gem.instance_variable_set("@ruby", nil)
+
+ assert_equal "C:/Ruby18/bin/ruby.exe", Gem.ruby
+ ensure
+ Gem.instance_variable_set("@ruby", orig_ruby)
+ RbConfig::CONFIG['bindir'] = orig_bindir
+ RbConfig::CONFIG['ruby_install_name'] = orig_ruby_install_name
+ RbConfig::CONFIG['EXEEXT'] = orig_exe_ext
+ end
+
+ def test_self_ruby_api_version
+ orig_ruby_version, RbConfig::CONFIG['ruby_version'] = RbConfig::CONFIG['ruby_version'], '1.2.3'
+
+ Gem.instance_variable_set :@ruby_api_version, nil
+
+ assert_equal '1.2.3', Gem.ruby_api_version
+ ensure
+ Gem.instance_variable_set :@ruby_api_version, nil
+
+ RbConfig::CONFIG['ruby_version'] = orig_ruby_version
+ end
+
+ def test_self_ruby_version_1_8_5
+ util_set_RUBY_VERSION '1.8.5'
+
+ assert_equal Gem::Version.new('1.8.5'), Gem.ruby_version
+ ensure
+ util_restore_RUBY_VERSION
+ end
+
+ def test_self_ruby_version_1_8_6p287
+ util_set_RUBY_VERSION '1.8.6', 287
+
+ assert_equal Gem::Version.new('1.8.6.287'), Gem.ruby_version
+ ensure
+ util_restore_RUBY_VERSION
+ end
+
+ def test_self_ruby_version_1_9_2dev_r23493
+ util_set_RUBY_VERSION '1.9.2', -1, 23493
+
+ assert_equal Gem::Version.new('1.9.2.dev.23493'), Gem.ruby_version
+ ensure
+ util_restore_RUBY_VERSION
+ end
+
+ def test_self_rubygems_version
+ assert_equal Gem::Version.new(Gem::VERSION), Gem.rubygems_version
+ end
+
+ def test_self_paths_eq
+ other = File.join @tempdir, 'other'
+ path = [@userhome, other].join File::PATH_SEPARATOR
+
+ #
+ # FIXME remove after fixing test_case
+ #
+ ENV["GEM_HOME"] = @gemhome
+ Gem.paths = { "GEM_PATH" => path }
+
+ assert_equal [@userhome, other, @gemhome], Gem.path
+ end
+
+ def test_self_paths_eq_nonexistent_home
+ ENV['GEM_HOME'] = @gemhome
+ Gem.clear_paths
+
+ other = File.join @tempdir, 'other'
+
+ ENV['HOME'] = other
+
+ Gem.paths = { "GEM_PATH" => other }
+
+ assert_equal [other, @gemhome], Gem.path
+ end
+
+ def test_self_post_build
+ assert_equal 1, Gem.post_build_hooks.length
+
+ Gem.post_build do |installer| end
+
+ assert_equal 2, Gem.post_build_hooks.length
+ end
+
+ def test_self_post_install
+ assert_equal 1, Gem.post_install_hooks.length
+
+ Gem.post_install do |installer| end
+
+ assert_equal 2, Gem.post_install_hooks.length
+ end
+
+ def test_self_done_installing
+ assert_empty Gem.done_installing_hooks
+
+ Gem.done_installing do |gems| end
+
+ assert_equal 1, Gem.done_installing_hooks.length
+ end
+
+ def test_self_post_reset
+ assert_empty Gem.post_reset_hooks
+
+ Gem.post_reset { }
+
+ assert_equal 1, Gem.post_reset_hooks.length
+ end
+
+ def test_self_post_uninstall
+ assert_equal 1, Gem.post_uninstall_hooks.length
+
+ Gem.post_uninstall do |installer| end
+
+ assert_equal 2, Gem.post_uninstall_hooks.length
+ end
+
+ def test_self_pre_install
+ assert_equal 1, Gem.pre_install_hooks.length
+
+ Gem.pre_install do |installer| end
+
+ assert_equal 2, Gem.pre_install_hooks.length
+ end
+
+ def test_self_pre_reset
+ assert_empty Gem.pre_reset_hooks
+
+ Gem.pre_reset { }
+
+ assert_equal 1, Gem.pre_reset_hooks.length
+ end
+
+ def test_self_pre_uninstall
+ assert_equal 1, Gem.pre_uninstall_hooks.length
+
+ Gem.pre_uninstall do |installer| end
+
+ assert_equal 2, Gem.pre_uninstall_hooks.length
+ end
+
+ def test_self_sources
+ assert_equal %w[http://gems.example.com/], Gem.sources
+ end
+
+ def test_self_try_activate_missing_dep
+ a = util_spec 'a', '1.0', 'b' => '>= 1.0'
+
+ a_file = File.join a.gem_dir, 'lib', 'a_file.rb'
+
+ write_file a_file do |io|
+ io.puts '# a_file.rb'
+ end
+
+ e = assert_raises Gem::LoadError do
+ Gem.try_activate 'a_file'
+ end
+
+ assert_match %r%Could not find 'b' %, e.message
+ end
+
+ def test_self_try_activate_missing_extensions
+ util_spec 'ext', '1' do |s|
+ s.extensions = %w[ext/extconf.rb]
+ s.mark_version
+ s.installed_by_version = v('2.2')
+ end
+
+ _, err = capture_io do
+ refute Gem.try_activate 'nonexistent'
+ end
+
+ expected = "Ignoring ext-1 because its extensions are not built. " +
+ "Try: gem pristine ext-1\n"
+
+ assert_equal expected, err
+ end
+
+ def test_self_use_paths
+ util_ensure_gem_dirs
+
+ Gem.use_paths @gemhome, @additional
+
+ assert_equal @gemhome, Gem.dir
+ assert_equal @additional + [Gem.dir], Gem.path
+ end
+
+ def test_self_user_dir
+ parts = [@userhome, '.gem', Gem.ruby_engine]
+ parts << RbConfig::CONFIG['ruby_version'] unless RbConfig::CONFIG['ruby_version'].empty?
+
+ assert_equal File.join(parts), Gem.user_dir
+ end
+
+ def test_self_user_home
+ if ENV['HOME'] then
+ assert_equal ENV['HOME'], Gem.user_home
+ else
+ assert true, 'count this test'
+ end
+ end
+
+ def test_self_needs
+ util_clear_gems
+ a = util_spec "a", "1"
+ b = util_spec "b", "1", "c" => nil
+ c = util_spec "c", "2"
+
+ install_specs a, b, c
+
+ Gem.needs do |r|
+ r.gem "a"
+ r.gem "b", "= 1"
+ end
+
+ activated = Gem::Specification.map { |x| x.full_name }
+
+ assert_equal %w!a-1 b-1 c-2!, activated.sort
+ end
+
+ def test_self_needs_picks_up_unresolved_deps
+ skip 'loading from unsafe file' if RUBY_VERSION <= "1.8.7"
+ save_loaded_features do
+ util_clear_gems
+ a = util_spec "a", "1"
+ b = util_spec "b", "1", "c" => nil
+ c = util_spec "c", "2"
+ d = new_spec "d", "1", {'e' => '= 1'}, "lib/d.rb"
+ e = util_spec "e", "1"
+
+ install_specs a, b, c, d, e
+
+ Gem.needs do |r|
+ r.gem "a"
+ r.gem "b", "= 1"
+
+ require 'd'
+ end
+
+ assert_equal %w!a-1 b-1 c-2 d-1 e-1!, loaded_spec_names
+ end
+ end
+
+ def test_self_gunzip
+ input = "\x1F\x8B\b\0\xED\xA3\x1AQ\0\x03\xCBH" +
+ "\xCD\xC9\xC9\a\0\x86\xA6\x106\x05\0\0\0"
+
+ output = Gem.gunzip input
+
+ assert_equal 'hello', output
+
+ return unless Object.const_defined? :Encoding
+
+ assert_equal Encoding::BINARY, output.encoding
+ end
+
+ def test_self_gzip
+ input = 'hello'
+
+ output = Gem.gzip input
+
+ zipped = StringIO.new output
+
+ assert_equal 'hello', Zlib::GzipReader.new(zipped).read
+
+ return unless Object.const_defined? :Encoding
+
+ assert_equal Encoding::BINARY, output.encoding
+ end
+
+ if Gem.win_platform? && '1.9' > RUBY_VERSION
+ # Ruby 1.9 properly handles ~ path expansion, so no need to run such tests.
+ def test_self_user_home_userprofile
+
+ Gem.clear_paths
+
+ # safe-keep env variables
+ orig_home, orig_user_profile = ENV['HOME'], ENV['USERPROFILE']
+
+ # prepare for the test
+ ENV.delete('HOME')
+ ENV['USERPROFILE'] = "W:\\Users\\RubyUser"
+
+ assert_equal 'W:/Users/RubyUser', Gem.user_home
+
+ ensure
+ ENV['HOME'] = orig_home
+ ENV['USERPROFILE'] = orig_user_profile
+ end
+
+ def test_self_user_home_user_drive_and_path
+ Gem.clear_paths
+
+ # safe-keep env variables
+ orig_home, orig_user_profile = ENV['HOME'], ENV['USERPROFILE']
+ orig_home_drive, orig_home_path = ENV['HOMEDRIVE'], ENV['HOMEPATH']
+
+ # prepare the environment
+ ENV.delete('HOME')
+ ENV.delete('USERPROFILE')
+ ENV['HOMEDRIVE'] = 'Z:'
+ ENV['HOMEPATH'] = "\\Users\\RubyUser"
+
+ assert_equal 'Z:/Users/RubyUser', Gem.user_home
+
+ ensure
+ ENV['HOME'] = orig_home
+ ENV['USERPROFILE'] = orig_user_profile
+ ENV['HOMEDRIVE'] = orig_home_drive
+ ENV['HOMEPATH'] = orig_home_path
+ end
+ end
+
+ def test_self_vendor_dir
+ expected =
+ File.join RbConfig::CONFIG['vendordir'], 'gems',
+ RbConfig::CONFIG['ruby_version']
+
+ assert_equal expected, Gem.vendor_dir
+ end
+
+ def test_self_vendor_dir_ENV_GEM_VENDOR
+ ENV['GEM_VENDOR'] = File.join @tempdir, 'vendor', 'gems'
+
+ assert_equal ENV['GEM_VENDOR'], Gem.vendor_dir
+ refute Gem.vendor_dir.frozen?
+ end
+
+ def test_self_vendor_dir_missing
+ orig_vendordir = RbConfig::CONFIG['vendordir']
+ RbConfig::CONFIG.delete 'vendordir'
+
+ assert_nil Gem.vendor_dir
+ ensure
+ RbConfig::CONFIG['vendordir'] = orig_vendordir
+ end
+
+ def test_load_plugins
+ skip 'Insecure operation - chdir' if RUBY_VERSION <= "1.8.7"
+ plugin_path = File.join "lib", "rubygems_plugin.rb"
+
+ Dir.chdir @tempdir do
+ FileUtils.mkdir_p 'lib'
+ File.open plugin_path, "w" do |fp|
+ fp.puts "class TestGem; PLUGINS_LOADED << 'plugin'; end"
+ end
+
+ foo1 = util_spec 'foo', '1' do |s|
+ s.files << plugin_path
+ end
+
+ install_gem foo1
+
+ foo2 = util_spec 'foo', '2' do |s|
+ s.files << plugin_path
+ end
+
+ install_gem foo2
+ end
+
+ Gem.searcher = nil
+ Gem::Specification.reset
+
+ gem 'foo'
+
+ Gem.load_plugins
+
+ assert_equal %w[plugin], PLUGINS_LOADED
+ end
+
+ def test_load_env_plugins
+ with_plugin('load') { Gem.load_env_plugins }
+ assert_equal :loaded, TEST_PLUGIN_LOAD rescue nil
+
+ util_remove_interrupt_command
+
+ # Should attempt to cause a StandardError
+ with_plugin('standarderror') { Gem.load_env_plugins }
+ assert_equal :loaded, TEST_PLUGIN_STANDARDERROR rescue nil
+
+ util_remove_interrupt_command
+
+ # Should attempt to cause an Exception
+ with_plugin('exception') { Gem.load_env_plugins }
+ assert_equal :loaded, TEST_PLUGIN_EXCEPTION rescue nil
+ end
+
+ def test_gem_path_ordering
+ refute_equal Gem.dir, Gem.user_dir
+
+ write_file File.join(@tempdir, 'lib', "g.rb") { |fp| fp.puts "" }
+ write_file File.join(@tempdir, 'lib', 'm.rb') { |fp| fp.puts "" }
+
+ g = new_spec 'g', '1', nil, "lib/g.rb"
+ m = new_spec 'm', '1', nil, "lib/m.rb"
+
+ install_gem g, :install_dir => Gem.dir
+ m0 = install_gem m, :install_dir => Gem.dir
+ m1 = install_gem m, :install_dir => Gem.user_dir
+
+ assert_equal m0.gem_dir, File.join(Gem.dir, "gems", "m-1")
+ assert_equal m1.gem_dir, File.join(Gem.user_dir, "gems", "m-1")
+
+ tests = [
+ [:dir0, [ Gem.dir, Gem.user_dir], m0],
+ [:dir1, [ Gem.user_dir, Gem.dir], m1]
+ ]
+
+ tests.each do |_name, _paths, expected|
+ Gem.paths = { 'GEM_HOME' => _paths.first, 'GEM_PATH' => _paths }
+ Gem::Specification.reset
+ Gem.searcher = nil
+
+ assert_equal Gem::Dependency.new('m','1').to_specs,
+ Gem::Dependency.new('m','1').to_specs.sort
+
+ assert_equal \
+ [expected.gem_dir],
+ Gem::Dependency.new('m','1').to_specs.map(&:gem_dir).sort,
+ "Wrong specs for #{_name}"
+
+ spec = Gem::Dependency.new('m','1').to_spec
+
+ assert_equal \
+ File.join(_paths.first, "gems", "m-1"),
+ spec.gem_dir,
+ "Wrong spec before require for #{_name}"
+ refute spec.activated?, "dependency already activated for #{_name}"
+
+ gem "m"
+
+ spec = Gem::Dependency.new('m','1').to_spec
+ assert spec.activated?, "dependency not activated for #{_name}"
+
+ assert_equal \
+ File.join(_paths.first, "gems", "m-1"),
+ spec.gem_dir,
+ "Wrong spec after require for #{_name}"
+
+ spec.instance_variable_set :@activated, false
+ Gem.loaded_specs.delete(spec.name)
+ $:.delete(File.join(spec.gem_dir, "lib"))
+ end
+ end
+
+ def test_gem_path_ordering_short
+ write_file File.join(@tempdir, 'lib', "g.rb") { |fp| fp.puts "" }
+ write_file File.join(@tempdir, 'lib', 'm.rb') { |fp| fp.puts "" }
+
+ g = new_spec 'g', '1', nil, "lib/g.rb"
+ m = new_spec 'm', '1', nil, "lib/m.rb"
+
+ install_gem g, :install_dir => Gem.dir
+ install_gem m, :install_dir => Gem.dir
+ install_gem m, :install_dir => Gem.user_dir
+
+ Gem.paths = {
+ 'GEM_HOME' => Gem.dir,
+ 'GEM_PATH' => [ Gem.dir, Gem.user_dir]
+ }
+
+ assert_equal \
+ File.join(Gem.dir, "gems", "m-1"),
+ Gem::Dependency.new('m','1').to_spec.gem_dir,
+ "Wrong spec selected"
+ end
+
+ def test_auto_activation_of_specific_gemdeps_file
+ util_clear_gems
+
+ a = new_spec "a", "1", nil, "lib/a.rb"
+ b = new_spec "b", "1", nil, "lib/b.rb"
+ c = new_spec "c", "1", nil, "lib/c.rb"
+
+ install_specs a, b, c
+
+ path = File.join @tempdir, "gem.deps.rb"
+
+ File.open path, "w" do |f|
+ f.puts "gem 'a'"
+ f.puts "gem 'b'"
+ f.puts "gem 'c'"
+ end
+
+ ENV['RUBYGEMS_GEMDEPS'] = path
+
+ Gem.detect_gemdeps
+
+ assert_equal %w!a-1 b-1 c-1!, loaded_spec_names
+ end
+
+ def test_auto_activation_of_detected_gemdeps_file
+ skip 'Insecure operation - chdir' if RUBY_VERSION <= "1.8.7"
+ util_clear_gems
+
+ a = new_spec "a", "1", nil, "lib/a.rb"
+ b = new_spec "b", "1", nil, "lib/b.rb"
+ c = new_spec "c", "1", nil, "lib/c.rb"
+
+ install_specs a, b, c
+
+ path = File.join @tempdir, "gem.deps.rb"
+
+ File.open path, "w" do |f|
+ f.puts "gem 'a'"
+ f.puts "gem 'b'"
+ f.puts "gem 'c'"
+ end
+
+ ENV['RUBYGEMS_GEMDEPS'] = "-"
+
+ assert_equal [a,b,c], Gem.detect_gemdeps.sort_by { |s| s.name }
+ end
+
+ LIB_PATH = File.expand_path "../../../lib".untaint, __FILE__.untaint
+
+ def test_looks_for_gemdeps_files_automatically_on_start
+ util_clear_gems
+
+ a = new_spec "a", "1", nil, "lib/a.rb"
+ b = new_spec "b", "1", nil, "lib/b.rb"
+ c = new_spec "c", "1", nil, "lib/c.rb"
+
+ install_specs a, b, c
+
+ path = File.join @tempdir, "gem.deps.rb"
+
+ File.open path, "w" do |f|
+ f.puts "gem 'a'"
+ f.puts "gem 'b'"
+ f.puts "gem 'c'"
+ end
+
+ path = File.join(@tempdir, "gd-tmp")
+ install_gem a, :install_dir => path
+ install_gem b, :install_dir => path
+ install_gem c, :install_dir => path
+
+ ENV['GEM_PATH'] = path
+ ENV['RUBYGEMS_GEMDEPS'] = "-"
+
+ out = `#{Gem.ruby.dup.untaint} -I #{LIB_PATH.untaint} -rubygems -e "p Gem.loaded_specs.values.map(&:full_name).sort"`
+
+ assert_equal '["a-1", "b-1", "c-1"]', out.strip
+ end
+
+ def test_looks_for_gemdeps_files_automatically_on_start_in_parent_dir
+ util_clear_gems
+
+ a = new_spec "a", "1", nil, "lib/a.rb"
+ b = new_spec "b", "1", nil, "lib/b.rb"
+ c = new_spec "c", "1", nil, "lib/c.rb"
+
+ install_specs a, b, c
+
+ path = File.join @tempdir, "gem.deps.rb"
+
+ File.open path, "w" do |f|
+ f.puts "gem 'a'"
+ f.puts "gem 'b'"
+ f.puts "gem 'c'"
+ end
+
+ path = File.join(@tempdir, "gd-tmp")
+ install_gem a, :install_dir => path
+ install_gem b, :install_dir => path
+ install_gem c, :install_dir => path
+
+ ENV['GEM_PATH'] = path
+ ENV['RUBYGEMS_GEMDEPS'] = "-"
+
+ Dir.mkdir "sub1"
+ out = Dir.chdir "sub1" do
+ `#{Gem.ruby.dup.untaint} -I #{LIB_PATH.untaint} -rubygems -e "p Gem.loaded_specs.values.map(&:full_name).sort"`
+ end
+
+ Dir.rmdir "sub1"
+
+ assert_equal '["a-1", "b-1", "c-1"]', out.strip
+ end
+
+ def test_register_default_spec
+ Gem.clear_default_specs
+
+ old_style = Gem::Specification.new do |spec|
+ spec.files = ["foo.rb", "bar.rb"]
+ end
+
+ Gem.register_default_spec old_style
+
+ assert_equal old_style, Gem.find_unresolved_default_spec("foo.rb")
+ assert_equal old_style, Gem.find_unresolved_default_spec("bar.rb")
+ assert_equal nil, Gem.find_unresolved_default_spec("baz.rb")
+
+ Gem.clear_default_specs
+
+ new_style = Gem::Specification.new do |spec|
+ spec.files = ["lib/foo.rb", "ext/bar.rb", "bin/exec", "README"]
+ spec.require_paths = ["lib", "ext"]
+ end
+
+ Gem.register_default_spec new_style
+
+ assert_equal new_style, Gem.find_unresolved_default_spec("foo.rb")
+ assert_equal new_style, Gem.find_unresolved_default_spec("bar.rb")
+ assert_equal nil, Gem.find_unresolved_default_spec("exec")
+ assert_equal nil, Gem.find_unresolved_default_spec("README")
+ end
+
+ def test_default_gems_use_full_paths
+ begin
+ if defined?(RUBY_ENGINE) then
+ engine = RUBY_ENGINE
+ Object.send :remove_const, :RUBY_ENGINE
+ end
+ Object.const_set :RUBY_ENGINE, 'ruby'
+
+ refute Gem.default_gems_use_full_paths?
+ ensure
+ Object.send :remove_const, :RUBY_ENGINE
+ Object.const_set :RUBY_ENGINE, engine if engine
+ end
+
+ begin
+ if defined?(RUBY_ENGINE) then
+ engine = RUBY_ENGINE
+ Object.send :remove_const, :RUBY_ENGINE
+ end
+ Object.const_set :RUBY_ENGINE, 'jruby'
+ assert Gem.default_gems_use_full_paths?
+ ensure
+ Object.send :remove_const, :RUBY_ENGINE
+ Object.const_set :RUBY_ENGINE, engine if engine
+ end
+ end
+
+ def test_use_gemdeps
+ gem_deps_file = 'gem.deps.rb'.untaint
+ spec = util_spec 'a', 1
+
+ refute spec.activated?
+
+ open gem_deps_file, 'w' do |io|
+ io.write 'gem "a"'
+ end
+
+ Gem.use_gemdeps gem_deps_file
+
+ assert spec.activated?
+ end
+
+ def test_use_gemdeps_ENV
+ rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], nil
+
+ spec = util_spec 'a', 1
+
+ refute spec.activated?
+
+ open 'gem.deps.rb', 'w' do |io|
+ io.write 'gem "a"'
+ end
+
+ Gem.use_gemdeps
+
+ refute spec.activated?
+ ensure
+ ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
+ end
+
+ def test_use_gemdeps_argument_missing
+ e = assert_raises ArgumentError do
+ Gem.use_gemdeps 'gem.deps.rb'
+ end
+
+ assert_equal 'Unable to find gem dependencies file at gem.deps.rb',
+ e.message
+ end
+
+ def test_use_gemdeps_argument_missing_match_ENV
+ rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] =
+ ENV['RUBYGEMS_GEMDEPS'], 'gem.deps.rb'
+
+ e = assert_raises ArgumentError do
+ Gem.use_gemdeps 'gem.deps.rb'
+ end
+
+ assert_equal 'Unable to find gem dependencies file at gem.deps.rb',
+ e.message
+ ensure
+ ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
+ end
+
+ def test_use_gemdeps_automatic
+ skip 'Insecure operation - chdir' if RUBY_VERSION <= "1.8.7"
+ rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], '-'
+
+ spec = util_spec 'a', 1
+
+ refute spec.activated?
+
+ open 'Gemfile', 'w' do |io|
+ io.write 'gem "a"'
+ end
+
+ Gem.use_gemdeps
+
+ assert spec.activated?
+ ensure
+ ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
+ end
+
+ def test_use_gemdeps_automatic_missing
+ skip 'Insecure operation - chdir' if RUBY_VERSION <= "1.8.7"
+ rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], '-'
+
+ Gem.use_gemdeps
+
+ assert true # count
+ ensure
+ ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
+ end
+
+ def test_use_gemdeps_disabled
+ rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], ''
+
+ spec = util_spec 'a', 1
+
+ refute spec.activated?
+
+ open 'gem.deps.rb', 'w' do |io|
+ io.write 'gem "a"'
+ end
+
+ Gem.use_gemdeps
+
+ refute spec.activated?
+ ensure
+ ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
+ end
+
+ def test_use_gemdeps_missing_gem
+ skip 'Insecure operation - read' if RUBY_VERSION <= "1.8.7"
+ rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], 'x'
+
+ open 'x', 'w' do |io|
+ io.write 'gem "a"'
+ end
+
+ expected = <<-EXPECTED
+Unable to resolve dependency: user requested 'a (>= 0)'
+You may need to `gem install -g` to install missing gems
+
+ EXPECTED
+
+ assert_output nil, expected do
+ Gem.use_gemdeps
+ end
+ ensure
+ ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
+ end
+
+ def test_use_gemdeps_specific
+ skip 'Insecure operation - read' if RUBY_VERSION <= "1.8.7"
+ rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], 'x'
+
+ spec = util_spec 'a', 1
+
+ refute spec.activated?
+
+ open 'x', 'w' do |io|
+ io.write 'gem "a"'
+ end
+
+ Gem.use_gemdeps
+
+ assert spec.activated?
+ ensure
+ ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps
+ end
+
+ def ruby_install_name name
+ orig_RUBY_INSTALL_NAME = RbConfig::CONFIG['ruby_install_name']
+ RbConfig::CONFIG['ruby_install_name'] = name
+
+ yield
+ ensure
+ if orig_RUBY_INSTALL_NAME then
+ RbConfig::CONFIG['ruby_install_name'] = orig_RUBY_INSTALL_NAME
+ else
+ RbConfig::CONFIG.delete 'ruby_install_name'
+ end
+ end
+
+ def with_plugin(path)
+ test_plugin_path = File.expand_path("test/rubygems/plugin/#{path}",
+ @@project_dir)
+
+ # A single test plugin should get loaded once only, in order to preserve
+ # sane test semantics.
+ refute_includes $LOAD_PATH, test_plugin_path
+ $LOAD_PATH.unshift test_plugin_path
+
+ capture_io do
+ yield
+ end
+ ensure
+ $LOAD_PATH.delete test_plugin_path
+ end
+
+ def util_ensure_gem_dirs
+ Gem.ensure_gem_subdirectories @gemhome
+
+ #
+ # FIXME what does this solve precisely? -ebh
+ #
+ @additional.each do |dir|
+ Gem.ensure_gem_subdirectories @gemhome
+ end
+ end
+
+ def util_exec_gem
+ spec, _ = util_spec 'a', '4' do |s|
+ s.executables = ['exec', 'abin']
+ end
+
+ @exec_path = File.join spec.full_gem_path, spec.bindir, 'exec'
+ @abin_path = File.join spec.full_gem_path, spec.bindir, 'abin'
+ end
+
+ def util_set_RUBY_VERSION(version, patchlevel = nil, revision = nil)
+ if Gem.instance_variables.include? :@ruby_version or
+ Gem.instance_variables.include? '@ruby_version' then
+ Gem.send :remove_instance_variable, :@ruby_version
+ end
+
+ @RUBY_VERSION = RUBY_VERSION
+ @RUBY_PATCHLEVEL = RUBY_PATCHLEVEL if defined?(RUBY_PATCHLEVEL)
+ @RUBY_REVISION = RUBY_REVISION if defined?(RUBY_REVISION)
+
+ Object.send :remove_const, :RUBY_VERSION
+ Object.send :remove_const, :RUBY_PATCHLEVEL if defined?(RUBY_PATCHLEVEL)
+ Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
+
+ Object.const_set :RUBY_VERSION, version
+ Object.const_set :RUBY_PATCHLEVEL, patchlevel if patchlevel
+ Object.const_set :RUBY_REVISION, revision if revision
+ end
+
+ def util_restore_RUBY_VERSION
+ Object.send :remove_const, :RUBY_VERSION
+ Object.send :remove_const, :RUBY_PATCHLEVEL if defined?(RUBY_PATCHLEVEL)
+ Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION)
+
+ Object.const_set :RUBY_VERSION, @RUBY_VERSION
+ Object.const_set :RUBY_PATCHLEVEL, @RUBY_PATCHLEVEL if
+ defined?(@RUBY_PATCHLEVEL)
+ Object.const_set :RUBY_REVISION, @RUBY_REVISION if
+ defined?(@RUBY_REVISION)
+ end
+
+ def util_remove_interrupt_command
+ Gem::Commands.send :remove_const, :InterruptCommand if
+ Gem::Commands.const_defined? :InterruptCommand
+ end
+
+ def util_cache_dir
+ File.join Gem.dir, "cache"
+ end
+end
diff --git a/test/rubygems/test_gem_available_set.rb b/test/rubygems/test_gem_available_set.rb
new file mode 100644
index 0000000000..2b515447a3
--- /dev/null
+++ b/test/rubygems/test_gem_available_set.rb
@@ -0,0 +1,128 @@
+require 'rubygems/test_case'
+require 'rubygems/available_set'
+require 'rubygems/security'
+
+class TestGemAvailableSet < Gem::TestCase
+
+ def setup
+ super
+
+ @source = Gem::Source.new(@gem_repo)
+ end
+
+ def test_add_and_empty
+ a1, _ = util_gem 'a', '1'
+
+ set = Gem::AvailableSet.new
+ assert set.empty?
+
+ set.add a1, @source
+
+ refute set.empty?
+
+ assert_equal [a1], set.all_specs
+ end
+
+ def test_find_all
+ a1, a1_gem = util_gem 'a', 1
+ a1a, a1a_gem = util_gem 'a', '1.a'
+
+ a1_source = Gem::Source::SpecificFile.new a1_gem
+ a1a_source = Gem::Source::SpecificFile.new a1a_gem
+
+ set = Gem::AvailableSet.new
+ set.add a1, a1_source
+ set.add a1a, a1a_source
+
+ dep = Gem::Resolver::DependencyRequest.new dep('a'), nil
+
+ assert_equal %w[a-1], set.find_all(dep).map { |spec| spec.full_name }
+
+ dep = Gem::Resolver::DependencyRequest.new dep('a', '>= 0.a'), nil
+
+ assert_equal %w[a-1 a-1.a],
+ set.find_all(dep).map { |spec| spec.full_name }.sort
+ end
+
+ def test_match_platform
+ a1, _ = util_gem 'a', '1' do |g|
+ g.platform = "something-weird-yep"
+ end
+
+ a1c, _ = util_gem 'a', '2' do |g|
+ g.platform = Gem::Platform.local
+ end
+
+ a2, _ = util_gem 'a', '2'
+
+ set = Gem::AvailableSet.new
+ set.add a1, @source
+ set.add a1c, @source
+ set.add a2, @source
+
+ set.match_platform!
+
+ assert_equal [a1c, a2], set.all_specs
+ end
+
+ def test_best
+ a1, _ = util_gem 'a', '1'
+ a2, _ = util_gem 'a', '2'
+
+ set = Gem::AvailableSet.new
+ set.add a1, @source
+ set.add a2, @source
+
+ set.pick_best!
+
+ assert_equal [a2], set.all_specs
+ end
+
+ def test_remove_installed_bang
+ a1, _ = util_gem 'a', '1'
+
+ a1.activate
+
+ set = Gem::AvailableSet.new
+ set.add a1, @source
+
+ dep = Gem::Dependency.new "a", ">= 0"
+
+ set.remove_installed! dep
+
+ assert set.empty?
+ end
+
+ def test_sorted_normal_versions
+ a1, _ = util_gem 'a', '1'
+ a2, _ = util_gem 'a', '2'
+
+ set = Gem::AvailableSet.new
+ set.add a1, @source
+ set.add a2, @source
+
+ g = set.sorted
+
+ assert_equal a2, g[0].spec
+ assert_equal a1, g[1].spec
+ end
+
+ def test_sorted_respect_pre
+ a1a, _ = util_gem 'a', '1.a'
+ a1, _ = util_gem 'a', '1'
+ a2a, _ = util_gem 'a', '2.a'
+ a2, _ = util_gem 'a', '2'
+ a3a, _ = util_gem 'a', '3.a'
+
+ set = Gem::AvailableSet.new
+ set.add a1, @source
+ set.add a1a, @source
+ set.add a3a, @source
+ set.add a2a, @source
+ set.add a2, @source
+
+ g = set.sorted.map { |t| t.spec }
+
+ assert_equal [a3a, a2, a2a, a1, a1a], g
+ end
+end
diff --git a/test/rubygems/test_gem_command.rb b/test/rubygems/test_gem_command.rb
new file mode 100644
index 0000000000..48cbc98d8c
--- /dev/null
+++ b/test/rubygems/test_gem_command.rb
@@ -0,0 +1,243 @@
+require 'rubygems/test_case'
+require 'rubygems/command'
+
+class Gem::Command
+ public :parser
+end
+
+class TestGemCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @xopt = nil
+
+ Gem::Command.common_options.clear
+ Gem::Command.common_options << [
+ ['-x', '--exe', 'Execute'], lambda do |*a|
+ @xopt = true
+ end
+ ]
+
+ @cmd_name = 'doit'
+ @cmd = Gem::Command.new @cmd_name, 'summary'
+ end
+
+ def test_self_add_specific_extra_args
+ added_args = %w[--all]
+ @cmd.add_option '--all' do |v,o| end
+
+ Gem::Command.add_specific_extra_args @cmd_name, added_args
+
+ assert_equal added_args, Gem::Command.specific_extra_args(@cmd_name)
+
+ h = @cmd.add_extra_args []
+
+ assert_equal added_args, h
+ end
+
+ def test_self_add_specific_extra_args_unknown
+ added_args = %w[--definitely_not_there]
+
+ Gem::Command.add_specific_extra_args @cmd_name, added_args
+
+ assert_equal added_args, Gem::Command.specific_extra_args(@cmd_name)
+
+ h = @cmd.add_extra_args []
+
+ assert_equal [], h
+ end
+
+ def test_basic_accessors
+ assert_equal "doit", @cmd.command
+ assert_equal "gem doit", @cmd.program_name
+ assert_equal "summary", @cmd.summary
+ end
+
+ def test_common_option_in_class
+ assert Array === Gem::Command.common_options
+ end
+
+ def test_defaults
+ @cmd.add_option('-h', '--help [COMMAND]', 'Get help on COMMAND') do |value, options|
+ options[:help] = value
+ end
+
+ @cmd.defaults = { :help => true }
+
+ @cmd.when_invoked do |options|
+ assert options[:help], "Help options should default true"
+ end
+
+ use_ui @ui do
+ @cmd.invoke
+ end
+
+ assert_match %r|Usage: gem doit|, @ui.output
+ end
+
+ def test_invoke
+ done = false
+ @cmd.when_invoked { done = true }
+
+ use_ui @ui do
+ @cmd.invoke
+ end
+
+ assert done
+ end
+
+ def test_invoke_with_bad_options
+ use_ui @ui do
+ @cmd.when_invoked do true end
+
+ ex = assert_raises OptionParser::InvalidOption do
+ @cmd.invoke('-zzz')
+ end
+
+ assert_match(/invalid option:/, ex.message)
+ end
+ end
+
+ def test_invoke_with_common_options
+ @cmd.when_invoked do true end
+
+ use_ui @ui do
+ @cmd.invoke "-x"
+ end
+
+ assert @xopt, "Should have done xopt"
+ end
+
+ def test_invoke_with_build_args
+ @cmd.when_invoked { true }
+
+ use_ui @ui do
+ @cmd.invoke_with_build_args ["-x"], ["--awesome=true"]
+ end
+
+ assert_equal ["--awesome=true"], @cmd.options[:build_args]
+ end
+
+ # Returning false from the command handler invokes the usage output.
+ def test_invoke_with_help
+ done = false
+
+ use_ui @ui do
+ @cmd.add_option('-h', '--help [COMMAND]', 'Get help on COMMAND') do |value, options|
+ options[:help] = true
+ done = true
+ end
+
+ @cmd.invoke('--help')
+
+ assert done
+ end
+
+ assert_match(/Usage/, @ui.output)
+ assert_match(/gem doit/, @ui.output)
+ assert_match(/\[options\]/, @ui.output)
+ assert_match(/-h/, @ui.output)
+ assert_match(/--help \[COMMAND\]/, @ui.output)
+ assert_match(/Get help on COMMAND/, @ui.output)
+ assert_match(/-x/, @ui.output)
+ assert_match(/--exe/, @ui.output)
+ assert_match(/Execute/, @ui.output)
+ assert_match(/Common Options:/, @ui.output)
+ end
+
+ def test_invoke_with_options
+ @cmd.add_option('-h', '--help [COMMAND]', 'Get help on COMMAND') do |value, options|
+ options[:help] = true
+ end
+
+ @cmd.when_invoked do |opts|
+ assert opts[:help]
+ end
+
+ use_ui @ui do
+ @cmd.invoke '-h'
+ end
+
+ assert_match %r|Usage: gem doit|, @ui.output
+ end
+
+ def test_option_recognition
+ @cmd.add_option('-h', '--help [COMMAND]', 'Get help on COMMAND') do |value, options|
+ options[:help] = true
+ end
+ @cmd.add_option('-f', '--file FILE', 'File option') do |value, options|
+ options[:help] = true
+ end
+ assert @cmd.handles?(['-x'])
+ assert @cmd.handles?(['-h'])
+ assert @cmd.handles?(['-h', 'command'])
+ assert @cmd.handles?(['--help', 'command'])
+ assert @cmd.handles?(['-f', 'filename'])
+ assert @cmd.handles?(['--file=filename'])
+ refute @cmd.handles?(['-z'])
+ refute @cmd.handles?(['-f'])
+ refute @cmd.handles?(['--toothpaste'])
+
+ args = ['-h', 'command']
+ @cmd.handles?(args)
+ assert_equal ['-h', 'command'], args
+ end
+
+ def test_show_lookup_failure_suggestions_local
+ correct = "non_existent_with_hint"
+ misspelled = "nonexistent_with_hint"
+
+ spec_fetcher do |fetcher|
+ fetcher.spec correct, 2
+ end
+
+ use_ui @ui do
+ @cmd.show_lookup_failure misspelled, Gem::Requirement.default, [], :local
+ end
+
+ expected = <<-EXPECTED
+ERROR: Could not find a valid gem 'nonexistent_with_hint' (>= 0) in any repository
+ EXPECTED
+
+ assert_equal expected, @ui.error
+ end
+
+ def test_show_lookup_failure_suggestions_none
+ spec_fetcher do |fetcher|
+ fetcher.spec 'correct', 2
+ end
+
+ use_ui @ui do
+ @cmd.show_lookup_failure 'other', Gem::Requirement.default, [], :remote
+ end
+
+ expected = <<-EXPECTED
+ERROR: Could not find a valid gem 'other' (>= 0) in any repository
+ EXPECTED
+
+ assert_equal expected, @ui.error
+ end
+
+ def test_show_lookup_failure_suggestions_remote
+ correct = "non_existent_with_hint"
+ misspelled = "nonexistent_with_hint"
+
+ spec_fetcher do |fetcher|
+ fetcher.spec correct, 2
+ end
+
+ use_ui @ui do
+ @cmd.show_lookup_failure misspelled, Gem::Requirement.default, [], :remote
+ end
+
+ expected = <<-EXPECTED
+ERROR: Could not find a valid gem 'nonexistent_with_hint' (>= 0) in any repository
+ERROR: Possible alternatives: non_existent_with_hint
+ EXPECTED
+
+ assert_equal expected, @ui.error
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_command_manager.rb b/test/rubygems/test_gem_command_manager.rb
new file mode 100644
index 0000000000..f6433c5cc3
--- /dev/null
+++ b/test/rubygems/test_gem_command_manager.rb
@@ -0,0 +1,263 @@
+require 'rubygems/test_case'
+require 'rubygems/command_manager'
+
+class TestGemCommandManager < Gem::TestCase
+
+ def setup
+ super
+
+ @command_manager = Gem::CommandManager.new
+ end
+
+ def test_find_command
+ command = @command_manager.find_command 'install'
+
+ assert_kind_of Gem::Commands::InstallCommand, command
+
+ command = @command_manager.find_command 'ins'
+
+ assert_kind_of Gem::Commands::InstallCommand, command
+ end
+
+ def test_find_command_ambiguous
+ e = assert_raises Gem::CommandLineError do
+ @command_manager.find_command 'u'
+ end
+
+ assert_equal 'Ambiguous command u matches [uninstall, unpack, update]',
+ e.message
+ end
+
+ def test_find_command_ambiguous_exact
+ ins_command = Class.new
+ Gem::Commands.send :const_set, :InsCommand, ins_command
+
+ @command_manager.register_command :ins
+
+ command = @command_manager.find_command 'ins'
+
+ assert_kind_of ins_command, command
+ ensure
+ Gem::Commands.send :remove_const, :InsCommand
+ end
+
+ def test_find_command_unknown
+ e = assert_raises Gem::CommandLineError do
+ @command_manager.find_command 'xyz'
+ end
+
+ assert_equal 'Unknown command xyz', e.message
+ end
+
+ def test_run_interrupt
+ old_load_path = $:.dup
+ $: << File.expand_path("test/rubygems", @@project_dir)
+ Gem.load_env_plugins
+
+ @command_manager.register_command :interrupt
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::TermError do
+ @command_manager.run %w[interrupt]
+ end
+ assert_equal '', ui.output
+ assert_equal "ERROR: Interrupted\n", ui.error
+ end
+ ensure
+ $:.replace old_load_path
+ Gem::CommandManager.reset
+ end
+
+ def test_run_crash_command
+ old_load_path = $:.dup
+ $: << File.expand_path("test/rubygems", @@project_dir)
+
+ @command_manager.register_command :crash
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::TermError do
+ @command_manager.run %w[crash]
+ end
+ assert_equal '', ui.output
+ err = ui.error.split("\n").first
+ assert_equal "ERROR: Loading command: crash (RuntimeError)", err
+ end
+ ensure
+ $:.replace old_load_path
+ @command_manager.unregister_command :crash
+ end
+
+ def test_process_args_bad_arg
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::TermError do
+ @command_manager.process_args %w[--bad-arg]
+ end
+ end
+
+ assert_match(/invalid option: --bad-arg/i, @ui.error)
+ end
+
+ # HACK move to install command test
+ def test_process_args_install
+ #capture all install options
+ use_ui @ui do
+ check_options = nil
+ @command_manager['install'].when_invoked do |options|
+ check_options = options
+ true
+ end
+
+ #check defaults
+ @command_manager.process_args %w[install]
+ assert_equal %w[ri], check_options[:document].sort
+ assert_equal false, check_options[:force]
+ assert_equal :both, check_options[:domain]
+ assert_equal true, check_options[:wrappers]
+ assert_equal Gem::Requirement.default, check_options[:version]
+ assert_equal nil, check_options[:install_dir]
+ assert_equal nil, check_options[:bin_dir]
+
+ #check settings
+ check_options = nil
+ @command_manager.process_args %w[
+ install --force --local --rdoc --install-dir .
+ --version 3.0 --no-wrapper --bindir .
+ ]
+ assert_equal %w[rdoc ri], check_options[:document].sort
+ assert_equal true, check_options[:force]
+ assert_equal :local, check_options[:domain]
+ assert_equal false, check_options[:wrappers]
+ assert_equal Gem::Requirement.new('3.0'), check_options[:version]
+ assert_equal Dir.pwd, check_options[:install_dir]
+ assert_equal Dir.pwd, check_options[:bin_dir]
+
+ #check remote domain
+ check_options = nil
+ @command_manager.process_args %w[install --remote]
+ assert_equal :remote, check_options[:domain]
+
+ #check both domain
+ check_options = nil
+ @command_manager.process_args %w[install --both]
+ assert_equal :both, check_options[:domain]
+
+ #check both domain
+ check_options = nil
+ @command_manager.process_args %w[install --both]
+ assert_equal :both, check_options[:domain]
+ end
+ end
+
+ # HACK move to uninstall command test
+ def test_process_args_uninstall
+ #capture all uninstall options
+ check_options = nil
+ @command_manager['uninstall'].when_invoked do |options|
+ check_options = options
+ true
+ end
+
+ #check defaults
+ @command_manager.process_args %w[uninstall]
+ assert_equal Gem::Requirement.default, check_options[:version]
+
+ #check settings
+ check_options = nil
+ @command_manager.process_args %w[uninstall foobar --version 3.0]
+ assert_equal "foobar", check_options[:args].first
+ assert_equal Gem::Requirement.new('3.0'), check_options[:version]
+ end
+
+ # HACK move to check command test
+ def test_process_args_check
+ #capture all check options
+ check_options = nil
+ @command_manager['check'].when_invoked do |options|
+ check_options = options
+ true
+ end
+
+ #check defaults
+ @command_manager.process_args %w[check]
+ assert_equal true, check_options[:alien]
+
+ #check settings
+ check_options = nil
+ @command_manager.process_args %w[check foobar --alien]
+ assert_equal true, check_options[:alien]
+ end
+
+ # HACK move to build command test
+ def test_process_args_build
+ #capture all build options
+ check_options = nil
+ @command_manager['build'].when_invoked do |options|
+ check_options = options
+ true
+ end
+
+ #check defaults
+ @command_manager.process_args %w[build]
+ #NOTE: Currently no defaults
+
+ #check settings
+ check_options = nil
+ @command_manager.process_args %w[build foobar.rb]
+ assert_equal 'foobar.rb', check_options[:args].first
+ end
+
+ # HACK move to query command test
+ def test_process_args_query
+ #capture all query options
+ check_options = nil
+ @command_manager['query'].when_invoked do |options|
+ check_options = options
+ true
+ end
+
+ #check defaults
+ @command_manager.process_args %w[query]
+ assert_equal(//, check_options[:name])
+ assert_equal :local, check_options[:domain]
+ assert_equal false, check_options[:details]
+
+ #check settings
+ check_options = nil
+ @command_manager.process_args %w[query --name foobar --local --details]
+ assert_equal(/foobar/i, check_options[:name])
+ assert_equal :local, check_options[:domain]
+ assert_equal true, check_options[:details]
+
+ #remote domain
+ check_options = nil
+ @command_manager.process_args %w[query --remote]
+ assert_equal :remote, check_options[:domain]
+
+ #both (local/remote) domains
+ check_options = nil
+ @command_manager.process_args %w[query --both]
+ assert_equal :both, check_options[:domain]
+ end
+
+ # HACK move to update command test
+ def test_process_args_update
+ #capture all update options
+ check_options = nil
+ @command_manager['update'].when_invoked do |options|
+ check_options = options
+ true
+ end
+
+ #check defaults
+ @command_manager.process_args %w[update]
+ assert_includes check_options[:document], 'rdoc'
+
+ #check settings
+ check_options = nil
+ @command_manager.process_args %w[update --force --rdoc --install-dir .]
+ assert_includes check_options[:document], 'ri'
+ assert_equal true, check_options[:force]
+ assert_equal Dir.pwd, check_options[:install_dir]
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_commands_build_command.rb b/test/rubygems/test_gem_commands_build_command.rb
new file mode 100644
index 0000000000..5f870c0765
--- /dev/null
+++ b/test/rubygems/test_gem_commands_build_command.rb
@@ -0,0 +1,110 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/build_command'
+require 'rubygems/package'
+
+class TestGemCommandsBuildCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @gem = util_spec 'some_gem' do |s|
+ s.rubyforge_project = 'example'
+ end
+
+ @cmd = Gem::Commands::BuildCommand.new
+ end
+
+ def test_execute
+ gemspec_file = File.join(@tempdir, @gem.spec_name)
+
+ File.open gemspec_file, 'w' do |gs|
+ gs.write @gem.to_ruby
+ end
+
+ util_test_build_gem @gem, gemspec_file
+ end
+
+ def test_execute_bad_spec
+ @gem.date = "2010-11-08"
+
+ gemspec_file = File.join(@tempdir, @gem.spec_name)
+
+ File.open gemspec_file, 'w' do |gs|
+ gs.write @gem.to_ruby.sub(/11-08/, "11-8")
+ end
+
+ @cmd.options[:args] = [gemspec_file]
+
+ out, err = use_ui @ui do
+ capture_io do
+ assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+ end
+ end
+
+ assert_equal "", out
+ assert_match(/invalid date format in specification/, err)
+
+ assert_equal '', @ui.output
+ assert_equal "ERROR: Error loading gemspec. Aborting.\n", @ui.error
+ end
+
+ def test_execute_missing_file
+ @cmd.options[:args] = %w[some_gem]
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+ end
+
+ assert_equal '', @ui.output
+ assert_equal "ERROR: Gemspec file not found: some_gem\n", @ui.error
+ end
+
+ def util_test_build_gem(gem, gemspec_file, check_licenses=true)
+ @cmd.options[:args] = [gemspec_file]
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ output = @ui.output.split "\n"
+ assert_equal " Successfully built RubyGem", output.shift
+ assert_equal " Name: some_gem", output.shift
+ assert_equal " Version: 2", output.shift
+ assert_equal " File: some_gem-2.gem", output.shift
+ assert_equal [], output
+
+ if check_licenses
+ assert_match "WARNING: licenses is empty", @ui.error
+ end
+
+ gem_file = File.join @tempdir, File.basename(gem.cache_file)
+ assert File.exist?(gem_file)
+
+ spec = Gem::Package.new(gem_file).spec
+
+ assert_equal "some_gem", spec.name
+ assert_equal "this is a summary", spec.summary
+ end
+
+ def test_execute_force
+ gemspec_file = File.join(@tempdir, @gem.spec_name)
+
+ @gem.send :remove_instance_variable, :@rubygems_version
+
+ File.open gemspec_file, 'w' do |gs|
+ gs.write @gem.to_ruby
+ end
+
+ @cmd.options[:args] = [gemspec_file]
+ @cmd.options[:force] = true
+
+ util_test_build_gem @gem, gemspec_file, false
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_commands_cert_command.rb b/test/rubygems/test_gem_commands_cert_command.rb
new file mode 100644
index 0000000000..4c1dcc25c0
--- /dev/null
+++ b/test/rubygems/test_gem_commands_cert_command.rb
@@ -0,0 +1,670 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/cert_command'
+require 'rubygems/fix_openssl_warnings' if RUBY_VERSION < "1.9"
+
+unless defined?(OpenSSL::SSL) then
+ warn 'Skipping `gem cert` tests. openssl not found.'
+end
+
+class TestGemCommandsCertCommand < Gem::TestCase
+
+ ALTERNATE_CERT = load_cert 'alternate'
+
+ ALTERNATE_KEY_FILE = key_path 'alternate'
+ PRIVATE_KEY_FILE = key_path 'private'
+ PUBLIC_KEY_FILE = key_path 'public'
+
+ ALTERNATE_CERT_FILE = cert_path 'alternate'
+ CHILD_CERT_FILE = cert_path 'child'
+ PUBLIC_CERT_FILE = cert_path 'public'
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::CertCommand.new
+
+ @trust_dir = Gem::Security.trust_dir
+ end
+
+ def test_certificates_matching
+ @trust_dir.trust_cert PUBLIC_CERT
+ @trust_dir.trust_cert ALTERNATE_CERT
+
+ matches = @cmd.certificates_matching ''
+
+ # HACK OpenSSL::X509::Certificate#== is Object#==, so do this the hard way
+ match = matches.next
+ assert_equal ALTERNATE_CERT.to_pem, match.first.to_pem
+ assert_equal @trust_dir.cert_path(ALTERNATE_CERT), match.last
+
+ match = matches.next
+ assert_equal PUBLIC_CERT.to_pem, match.first.to_pem
+ assert_equal @trust_dir.cert_path(PUBLIC_CERT), match.last
+
+ assert_raises StopIteration do
+ matches.next
+ end
+ end
+
+ def test_certificates_matching_filter
+ @trust_dir.trust_cert PUBLIC_CERT
+ @trust_dir.trust_cert ALTERNATE_CERT
+
+ matches = @cmd.certificates_matching 'alternate'
+
+ match = matches.next
+ assert_equal ALTERNATE_CERT.to_pem, match.first.to_pem
+ assert_equal @trust_dir.cert_path(ALTERNATE_CERT), match.last
+
+ assert_raises StopIteration do
+ matches.next
+ end
+ end
+
+ def test_execute_add
+ @cmd.handle_options %W[--add #{PUBLIC_CERT_FILE}]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ cert_path = @trust_dir.cert_path PUBLIC_CERT
+
+ assert_path_exists cert_path
+
+ assert_equal "Added '/CN=nobody/DC=example'\n", @ui.output
+ assert_empty @ui.error
+ end
+
+ def test_execute_add_twice
+ self.class.cert_path 'alternate'
+
+ @cmd.handle_options %W[
+ --add #{PUBLIC_CERT_FILE}
+ --add #{ALTERNATE_CERT_FILE}
+ ]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EXPECTED
+Added '/CN=nobody/DC=example'
+Added '/CN=alternate/DC=example'
+ EXPECTED
+
+ assert_equal expected, @ui.output
+ assert_empty @ui.error
+ end
+
+ def test_execute_build
+ passphrase = 'Foo bar'
+
+ @cmd.handle_options %W[--build nobody@example.com]
+
+ @build_ui = Gem::MockGemUi.new "#{passphrase}\n#{passphrase}"
+
+ use_ui @build_ui do
+ @cmd.execute
+ end
+
+ output = @build_ui.output.squeeze("\n").split "\n"
+
+ assert_equal "Passphrase for your Private Key: ",
+ output.shift
+ assert_equal "Please repeat the passphrase for your Private Key: ",
+ output.shift
+ assert_equal "Certificate: #{File.join @tempdir, 'gem-public_cert.pem'}",
+ output.shift
+ assert_equal "Private Key: #{File.join @tempdir, 'gem-private_key.pem'}",
+ output.shift
+
+ assert_equal "Don't forget to move the key file to somewhere private!",
+ output.shift
+
+ assert_empty output
+ assert_empty @build_ui.error
+
+ assert_path_exists File.join(@tempdir, 'gem-private_key.pem')
+ assert_path_exists File.join(@tempdir, 'gem-public_cert.pem')
+ end
+
+ def test_execute_build_bad_passphrase_confirmation
+ passphrase = 'Foo bar'
+ passphrase_confirmation = 'Fu bar'
+
+ @cmd.handle_options %W[--build nobody@example.com]
+
+ @build_ui = Gem::MockGemUi.new "#{passphrase}\n#{passphrase_confirmation}"
+
+ use_ui @build_ui do
+ e = assert_raises Gem::CommandLineError do
+ @cmd.execute
+ end
+
+ output = @build_ui.output.squeeze("\n").split "\n"
+
+ assert_equal "Passphrase for your Private Key: ",
+ output.shift
+ assert_equal "Please repeat the passphrase for your Private Key: ",
+ output.shift
+
+ assert_empty output
+
+ assert_equal "Passphrase and passphrase confirmation don't match",
+ e.message
+
+ end
+
+ refute_path_exists File.join(@tempdir, 'gem-private_key.pem')
+ refute_path_exists File.join(@tempdir, 'gem-public_cert.pem')
+ end
+
+ def test_execute_build_key
+ @cmd.handle_options %W[
+ --build nobody@example.com
+ --private-key #{PRIVATE_KEY_FILE}
+ ]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ output = @ui.output.split "\n"
+
+ assert_equal "Certificate: #{File.join @tempdir, 'gem-public_cert.pem'}",
+ output.shift
+
+ assert_empty output
+ assert_empty @ui.error
+
+ assert_path_exists File.join(@tempdir, 'gem-public_cert.pem')
+ refute_path_exists File.join(@tempdir, 'gem-private_key.pem')
+ end
+
+ def test_execute_build_encrypted_key
+ @cmd.handle_options %W[
+ --build nobody@example.com
+ --private-key #{ENCRYPTED_PRIVATE_KEY_PATH}
+ ]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ output = @ui.output.split "\n"
+
+ assert_equal "Certificate: #{File.join @tempdir, 'gem-public_cert.pem'}",
+ output.shift
+
+ assert_empty output
+ assert_empty @ui.error
+
+ assert_path_exists File.join(@tempdir, 'gem-public_cert.pem')
+ end
+
+ def test_execute_certificate
+ use_ui @ui do
+ @cmd.handle_options %W[--certificate #{PUBLIC_CERT_FILE}]
+ end
+
+ assert_equal '', @ui.output
+ assert_equal '', @ui.error
+
+ assert_equal PUBLIC_CERT.to_pem, @cmd.options[:issuer_cert].to_pem
+ end
+
+ def test_execute_list
+ @trust_dir.trust_cert PUBLIC_CERT
+ @trust_dir.trust_cert ALTERNATE_CERT
+
+ @cmd.handle_options %W[--list]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "/CN=alternate/DC=example\n/CN=nobody/DC=example\n",
+ @ui.output
+ assert_empty @ui.error
+ end
+
+ def test_execute_list_filter
+ @trust_dir.trust_cert PUBLIC_CERT
+ @trust_dir.trust_cert ALTERNATE_CERT
+
+ @cmd.handle_options %W[--list nobody]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "/CN=nobody/DC=example\n", @ui.output
+ assert_empty @ui.error
+ end
+
+ def test_execute_private_key
+ use_ui @ui do
+ @cmd.send :handle_options, %W[--private-key #{PRIVATE_KEY_FILE}]
+ end
+
+ assert_equal '', @ui.output
+ assert_equal '', @ui.error
+
+ assert_equal PRIVATE_KEY.to_pem, @cmd.options[:key].to_pem
+ end
+
+ def test_execute_encrypted_private_key
+ use_ui @ui do
+ @cmd.send :handle_options, %W[--private-key #{ENCRYPTED_PRIVATE_KEY_PATH}]
+ end
+
+ assert_equal '', @ui.output
+ assert_equal '', @ui.error
+
+ assert_equal ENCRYPTED_PRIVATE_KEY.to_pem, @cmd.options[:key].to_pem
+ end
+
+ def test_execute_remove
+ @trust_dir.trust_cert PUBLIC_CERT
+
+ cert_path = @trust_dir.cert_path PUBLIC_CERT
+
+ assert_path_exists cert_path
+
+ @cmd.handle_options %W[--remove nobody]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "Removed '/CN=nobody/DC=example'\n", @ui.output
+ assert_equal '', @ui.error
+
+ refute_path_exists cert_path
+ end
+
+ def test_execute_remove_multiple
+ @trust_dir.trust_cert PUBLIC_CERT
+ @trust_dir.trust_cert ALTERNATE_CERT
+
+ public_path = @trust_dir.cert_path PUBLIC_CERT
+ alternate_path = @trust_dir.cert_path ALTERNATE_CERT
+
+ assert_path_exists public_path
+ assert_path_exists alternate_path
+
+ @cmd.handle_options %W[--remove example]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EXPECTED
+Removed '/CN=alternate/DC=example'
+Removed '/CN=nobody/DC=example'
+ EXPECTED
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+
+ refute_path_exists public_path
+ refute_path_exists alternate_path
+ end
+
+ def test_execute_remove_twice
+ @trust_dir.trust_cert PUBLIC_CERT
+ @trust_dir.trust_cert ALTERNATE_CERT
+
+ public_path = @trust_dir.cert_path PUBLIC_CERT
+ alternate_path = @trust_dir.cert_path ALTERNATE_CERT
+
+ assert_path_exists public_path
+ assert_path_exists alternate_path
+
+ @cmd.handle_options %W[--remove nobody --remove alternate]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EXPECTED
+Removed '/CN=nobody/DC=example'
+Removed '/CN=alternate/DC=example'
+ EXPECTED
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+
+ refute_path_exists public_path
+ refute_path_exists alternate_path
+ end
+
+ def test_execute_sign
+ path = File.join @tempdir, 'cert.pem'
+ Gem::Security.write ALTERNATE_CERT, path, 0600
+
+ assert_equal '/CN=alternate/DC=example', ALTERNATE_CERT.issuer.to_s
+
+ @cmd.handle_options %W[
+ --private-key #{PRIVATE_KEY_FILE}
+ --certificate #{PUBLIC_CERT_FILE}
+
+ --sign #{path}
+ ]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal '', @ui.output
+ assert_equal '', @ui.error
+
+ cert = OpenSSL::X509::Certificate.new File.read path
+
+ assert_equal '/CN=nobody/DC=example', cert.issuer.to_s
+
+ mask = 0100600 & (~File.umask)
+
+ assert_equal mask, File.stat(path).mode unless win_platform?
+ end
+
+ def test_execute_sign_encrypted_key
+ path = File.join @tempdir, 'cert.pem'
+ Gem::Security.write ALTERNATE_CERT, path, 0600
+
+ assert_equal '/CN=alternate/DC=example', ALTERNATE_CERT.issuer.to_s
+
+ @cmd.handle_options %W[
+ --private-key #{ENCRYPTED_PRIVATE_KEY_PATH}
+ --certificate #{PUBLIC_CERT_FILE}
+
+ --sign #{path}
+ ]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal '', @ui.output
+ assert_equal '', @ui.error
+
+ cert = OpenSSL::X509::Certificate.new File.read path
+
+ assert_equal '/CN=nobody/DC=example', cert.issuer.to_s
+
+ mask = 0100600 & (~File.umask)
+
+ assert_equal mask, File.stat(path).mode unless win_platform?
+ end
+
+ def test_execute_sign_default
+ FileUtils.mkdir_p File.join Gem.user_home, '.gem'
+
+ private_key_path = File.join Gem.user_home, '.gem', 'gem-private_key.pem'
+ Gem::Security.write PRIVATE_KEY, private_key_path
+
+ public_cert_path = File.join Gem.user_home, '.gem', 'gem-public_cert.pem'
+ Gem::Security.write PUBLIC_CERT, public_cert_path
+
+ path = File.join @tempdir, 'cert.pem'
+ Gem::Security.write ALTERNATE_CERT, path, 0600
+
+ assert_equal '/CN=alternate/DC=example', ALTERNATE_CERT.issuer.to_s
+
+ @cmd.handle_options %W[--sign #{path}]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal '', @ui.output
+ assert_equal '', @ui.error
+
+ cert = OpenSSL::X509::Certificate.new File.read path
+
+ assert_equal '/CN=nobody/DC=example', cert.issuer.to_s
+
+ mask = 0100600 & (~File.umask)
+
+ assert_equal mask, File.stat(path).mode unless win_platform?
+ end
+
+ def test_execute_sign_default_encrypted_key
+ FileUtils.mkdir_p File.join(Gem.user_home, '.gem')
+
+ private_key_path = File.join Gem.user_home, '.gem', 'gem-private_key.pem'
+ Gem::Security.write ENCRYPTED_PRIVATE_KEY, private_key_path, 0600, PRIVATE_KEY_PASSPHRASE
+
+ public_cert_path = File.join Gem.user_home, '.gem', 'gem-public_cert.pem'
+ Gem::Security.write PUBLIC_CERT, public_cert_path
+
+ path = File.join @tempdir, 'cert.pem'
+ Gem::Security.write ALTERNATE_CERT, path, 0600
+
+ assert_equal '/CN=alternate/DC=example', ALTERNATE_CERT.issuer.to_s
+
+ @cmd.handle_options %W[--sign #{path}]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal '', @ui.output
+ assert_equal '', @ui.error
+
+ cert = OpenSSL::X509::Certificate.new File.read path
+
+ assert_equal '/CN=nobody/DC=example', cert.issuer.to_s
+
+ mask = 0100600 & (~File.umask)
+
+ assert_equal mask, File.stat(path).mode unless win_platform?
+ end
+
+ def test_execute_sign_no_cert
+ FileUtils.mkdir_p File.join Gem.user_home, '.gem'
+
+ private_key_path = File.join Gem.user_home, '.gem', 'gem-private_key.pem'
+ Gem::Security.write PRIVATE_KEY, private_key_path
+
+ path = File.join @tempdir, 'cert.pem'
+ Gem::Security.write ALTERNATE_CERT, path, 0600
+
+ assert_equal '/CN=alternate/DC=example', ALTERNATE_CERT.issuer.to_s
+
+ @cmd.handle_options %W[--sign #{path}]
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+ end
+
+ assert_equal '', @ui.output
+
+ expected = <<-EXPECTED
+ERROR: --certificate not specified and ~/.gem/gem-public_cert.pem does not exist
+ EXPECTED
+
+ assert_equal expected, @ui.error
+ end
+
+ def test_execute_sign_no_key
+ FileUtils.mkdir_p File.join Gem.user_home, '.gem'
+
+ public_cert_path = File.join Gem.user_home, '.gem', 'gem-public_cert.pem'
+ Gem::Security.write PUBLIC_CERT, public_cert_path
+
+ path = File.join @tempdir, 'cert.pem'
+ Gem::Security.write ALTERNATE_CERT, path, 0600
+
+ assert_equal '/CN=alternate/DC=example', ALTERNATE_CERT.issuer.to_s
+
+ @cmd.handle_options %W[--sign #{path}]
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+ end
+
+ assert_equal '', @ui.output
+
+ expected = <<-EXPECTED
+ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exist
+ EXPECTED
+
+ assert_equal expected, @ui.error
+ end
+
+ def test_handle_options
+ @cmd.handle_options %W[
+ --add #{PUBLIC_CERT_FILE}
+ --add #{ALTERNATE_CERT_FILE}
+
+ --remove nobody
+ --remove example
+
+ --list
+ --list example
+
+ --build nobody@example
+ --build other@example
+ ]
+
+ assert_equal [PUBLIC_CERT.to_pem, ALTERNATE_CERT.to_pem],
+ @cmd.options[:add].map { |cert| cert.to_pem }
+
+ assert_equal %w[nobody example], @cmd.options[:remove]
+
+ assert_equal %w[nobody@example other@example],
+ @cmd.options[:build].map { |name| name.to_s }
+
+ assert_equal ['', 'example'], @cmd.options[:list]
+ end
+
+ def test_handle_options_add_bad
+ nonexistent = File.join @tempdir, 'nonexistent'
+ e = assert_raises OptionParser::InvalidArgument do
+ @cmd.handle_options %W[--add #{nonexistent}]
+ end
+
+ assert_equal "invalid argument: --add #{nonexistent}: does not exist",
+ e.message
+
+ bad = File.join @tempdir, 'bad'
+ FileUtils.touch bad
+
+ e = assert_raises OptionParser::InvalidArgument do
+ @cmd.handle_options %W[--add #{bad}]
+ end
+
+ assert_equal "invalid argument: --add #{bad}: invalid X509 certificate",
+ e.message
+ end
+
+ def test_handle_options_certificate
+ nonexistent = File.join @tempdir, 'nonexistent'
+ e = assert_raises OptionParser::InvalidArgument do
+ @cmd.handle_options %W[--certificate #{nonexistent}]
+ end
+
+ assert_equal "invalid argument: --certificate #{nonexistent}: does not exist",
+ e.message
+
+ bad = File.join @tempdir, 'bad'
+ FileUtils.touch bad
+
+ e = assert_raises OptionParser::InvalidArgument do
+ @cmd.handle_options %W[--certificate #{bad}]
+ end
+
+ assert_equal "invalid argument: " +
+ "--certificate #{bad}: invalid X509 certificate",
+ e.message
+ end
+
+ def test_handle_options_key_bad
+ nonexistent = File.join @tempdir, 'nonexistent'
+ e = assert_raises OptionParser::InvalidArgument do
+ @cmd.handle_options %W[--private-key #{nonexistent}]
+ end
+
+ assert_equal "invalid argument: " +
+ "--private-key #{nonexistent}: does not exist",
+ e.message
+
+ bad = File.join @tempdir, 'bad'
+ FileUtils.touch bad
+
+ e = assert_raises OptionParser::InvalidArgument do
+ @cmd.handle_options %W[--private-key #{bad}]
+ end
+
+ assert_equal "invalid argument: --private-key #{bad}: invalid RSA key",
+ e.message
+
+ e = assert_raises OptionParser::InvalidArgument do
+ @cmd.handle_options %W[--private-key #{PUBLIC_KEY_FILE}]
+ end
+
+ assert_equal "invalid argument: " +
+ "--private-key #{PUBLIC_KEY_FILE}: private key not found",
+ e.message
+ end
+
+ def test_handle_options_sign
+ @cmd.handle_options %W[
+ --private-key #{ALTERNATE_KEY_FILE}
+ --private-key #{PRIVATE_KEY_FILE}
+
+ --certificate #{ALTERNATE_CERT_FILE}
+ --certificate #{PUBLIC_CERT_FILE}
+
+ --sign #{ALTERNATE_CERT_FILE}
+ --sign #{CHILD_CERT_FILE}
+ ]
+
+ assert_equal PRIVATE_KEY.to_pem, @cmd.options[:key].to_pem
+ assert_equal PUBLIC_CERT.to_pem, @cmd.options[:issuer_cert].to_pem
+
+ assert_equal [ALTERNATE_CERT_FILE, CHILD_CERT_FILE], @cmd.options[:sign]
+ end
+
+ def test_handle_options_sign_encrypted_key
+ @cmd.handle_options %W[
+ --private-key #{ALTERNATE_KEY_FILE}
+ --private-key #{ENCRYPTED_PRIVATE_KEY_PATH}
+
+ --certificate #{ALTERNATE_CERT_FILE}
+ --certificate #{PUBLIC_CERT_FILE}
+
+ --sign #{ALTERNATE_CERT_FILE}
+ --sign #{CHILD_CERT_FILE}
+ ]
+
+ assert_equal ENCRYPTED_PRIVATE_KEY.to_pem, @cmd.options[:key].to_pem
+ assert_equal PUBLIC_CERT.to_pem, @cmd.options[:issuer_cert].to_pem
+
+ assert_equal [ALTERNATE_CERT_FILE, CHILD_CERT_FILE], @cmd.options[:sign]
+ end
+
+ def test_handle_options_sign_nonexistent
+ nonexistent = File.join @tempdir, 'nonexistent'
+ e = assert_raises OptionParser::InvalidArgument do
+ @cmd.handle_options %W[
+ --private-key #{ALTERNATE_KEY_FILE}
+
+ --certificate #{ALTERNATE_CERT_FILE}
+
+ --sign #{nonexistent}
+ ]
+ end
+
+ assert_equal "invalid argument: --sign #{nonexistent}: does not exist",
+ e.message
+ end
+
+end if defined?(OpenSSL::SSL)
+
diff --git a/test/rubygems/test_gem_commands_check_command.rb b/test/rubygems/test_gem_commands_check_command.rb
new file mode 100644
index 0000000000..67db6a3206
--- /dev/null
+++ b/test/rubygems/test_gem_commands_check_command.rb
@@ -0,0 +1,68 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/check_command'
+
+class TestGemCommandsCheckCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::CheckCommand.new
+ end
+
+ def gem name
+ spec = quick_gem name do |gem|
+ gem.files = %W[lib/#{name}.rb Rakefile]
+ end
+
+ write_file File.join(*%W[gems #{spec.full_name} lib #{name}.rb])
+ write_file File.join(*%W[gems #{spec.full_name} Rakefile])
+
+ spec
+ end
+
+ def test_initialize
+ assert_equal "check", @cmd.command
+ assert_equal "gem check", @cmd.program_name
+ assert_match(/Check/, @cmd.summary)
+ end
+
+ def test_handle_options
+ @cmd.handle_options %w[--no-alien --no-gems --doctor --dry-run]
+
+ assert @cmd.options[:doctor]
+ refute @cmd.options[:alien]
+ assert @cmd.options[:dry_run]
+ refute @cmd.options[:gems]
+ end
+
+ def test_handle_options_defaults
+ @cmd.handle_options []
+
+ assert @cmd.options[:alien]
+ assert @cmd.options[:gems]
+ refute @cmd.options[:doctor]
+ refute @cmd.options[:dry_run]
+ end
+
+ def test_doctor
+ gem 'a'
+ b = gem 'b'
+
+ FileUtils.rm b.spec_file
+
+ assert_path_exists b.gem_dir
+ refute_path_exists b.spec_file
+
+ Gem.use_paths @gemhome
+
+ capture_io do
+ use_ui @ui do
+ @cmd.doctor
+ end
+ end
+
+ refute_path_exists b.gem_dir
+ refute_path_exists b.spec_file
+ end
+
+end
diff --git a/test/rubygems/test_gem_commands_cleanup_command.rb b/test/rubygems/test_gem_commands_cleanup_command.rb
new file mode 100644
index 0000000000..fdaac545af
--- /dev/null
+++ b/test/rubygems/test_gem_commands_cleanup_command.rb
@@ -0,0 +1,167 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/cleanup_command'
+
+class TestGemCommandsCleanupCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::CleanupCommand.new
+
+ @a_1 = util_spec 'a', 1
+ @a_2 = util_spec 'a', 2
+
+ install_gem @a_1
+ install_gem @a_2
+ end
+
+ def test_handle_options_d
+ @cmd.handle_options %w[-d]
+ assert @cmd.options[:dryrun]
+ end
+
+ def test_handle_options_dry_run
+ @cmd.handle_options %w[--dryrun]
+ assert @cmd.options[:dryrun]
+ end
+
+ def test_handle_options_n
+ @cmd.handle_options %w[-n]
+ assert @cmd.options[:dryrun]
+ end
+
+ def test_execute
+ @cmd.options[:args] = %w[a]
+
+ @cmd.execute
+
+ refute_path_exists @a_1.gem_dir
+ end
+
+ def test_execute_all_dependencies
+ @b_1 = util_spec 'b', 1 do |s| s.add_dependency 'a', '1' end
+ @b_2 = util_spec 'b', 2 do |s| s.add_dependency 'a', '2' end
+
+ install_gem @b_1
+ install_gem @b_2
+
+ @cmd.options[:args] = []
+
+ @cmd.execute
+
+ refute_path_exists @a_1.gem_dir
+ refute_path_exists @b_1.gem_dir
+ end
+
+ def test_execute_all
+ gemhome2 = File.join @tempdir, 'gemhome2'
+
+ Gem.ensure_gem_subdirectories gemhome2
+
+ Gem.use_paths @gemhome, gemhome2
+
+ @b_1 = util_spec 'b', 1
+ @b_2 = util_spec 'b', 2
+
+ install_gem @b_1
+ install_gem @b_2
+
+ @cmd.options[:args] = []
+
+ @cmd.execute
+
+ assert_equal @gemhome, Gem.dir, 'GEM_HOME'
+ assert_equal [@gemhome, gemhome2], Gem.path.sort, 'GEM_PATH'
+
+ refute_path_exists @a_1.gem_dir
+ refute_path_exists @b_1.gem_dir
+ end
+
+ def test_execute_all_user
+ @a_1_1 = util_spec 'a', '1.1'
+ @a_1_1 = install_gem_user @a_1_1 # pick up user install path
+
+ Gem::Specification.dirs = [Gem.dir, Gem.user_dir]
+
+ assert_path_exists @a_1.gem_dir
+ assert_path_exists @a_1_1.gem_dir
+
+ @cmd.options[:args] = %w[a]
+
+ @cmd.execute
+
+ refute_path_exists @a_1.gem_dir
+ refute_path_exists @a_1_1.gem_dir
+ end
+
+ def test_execute_all_user_no_sudo
+ FileUtils.chmod 0555, @gemhome
+
+ @a_1_1 = util_spec 'a', '1.1'
+ @a_1_1 = install_gem_user @a_1_1 # pick up user install path
+
+ Gem::Specification.dirs = [Gem.dir, Gem.user_dir]
+
+ assert_path_exists @a_1.gem_dir
+ assert_path_exists @a_1_1.gem_dir
+
+ @cmd.options[:args] = %w[a]
+
+ @cmd.execute
+
+ assert_path_exists @a_1.gem_dir
+ refute_path_exists @a_1_1.gem_dir
+ ensure
+ FileUtils.chmod 0755, @gemhome
+ end unless win_platform?
+
+ def test_execute_dry_run
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:dryrun] = true
+
+ @cmd.execute
+
+ assert_path_exists @a_1.gem_dir
+ end
+
+ def test_execute_keeps_older_versions_with_deps
+ @b_1 = util_spec 'b', 1
+ @b_2 = util_spec 'b', 2
+
+ @c = util_spec 'c', 1 do |s|
+ s.add_dependency 'b', '1'
+ end
+
+ install_gem @c
+ install_gem @b_1
+ install_gem @b_2
+
+ @cmd.options[:args] = []
+
+ @cmd.execute
+
+ assert_path_exists @b_1.gem_dir
+ end
+
+ def test_execute_ignore_default_gem_verbose
+ Gem.configuration.verbose = :really
+
+ @b_1 = util_spec 'b', 1
+ @b_default = new_default_spec "b", "2"
+ @b_2 = util_spec 'b', 3
+
+ install_gem @b_1
+ install_default_specs @b_default
+ install_gem @b_2
+
+ @cmd.options[:args] = []
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r%^Skipped default gems: b-2%, @ui.output
+ assert_empty @ui.error
+ end
+end
+
diff --git a/test/rubygems/test_gem_commands_contents_command.rb b/test/rubygems/test_gem_commands_contents_command.rb
new file mode 100644
index 0000000000..fb6906afd2
--- /dev/null
+++ b/test/rubygems/test_gem_commands_contents_command.rb
@@ -0,0 +1,239 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/contents_command'
+
+class TestGemCommandsContentsCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::ContentsCommand.new
+ end
+
+ def gem name, version = 2
+ spec = quick_gem name, version do |gem|
+ gem.files = %W[lib/#{name}.rb Rakefile]
+ end
+ write_file File.join(*%W[gems #{spec.full_name} lib #{name}.rb])
+ write_file File.join(*%W[gems #{spec.full_name} Rakefile])
+ end
+
+ def test_execute
+ @cmd.options[:args] = %w[foo]
+
+ gem 'foo'
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|lib/foo\.rb|, @ui.output
+ assert_match %r|Rakefile|, @ui.output
+ assert_equal "", @ui.error
+ end
+
+ def test_execute_all
+ @cmd.options[:all] = true
+
+ gem 'foo'
+ gem 'bar'
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|lib/foo\.rb|, @ui.output
+ assert_match %r|lib/bar\.rb|, @ui.output
+ assert_match %r|Rakefile|, @ui.output
+ assert_equal "", @ui.error
+ end
+
+ def test_execute_bad_gem
+ @cmd.options[:args] = %w[foo]
+
+ assert_raises Gem::MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_match %r|Unable to find gem 'foo' in default gem paths|, @ui.output
+ assert_match %r|Directories searched:|, @ui.output
+ assert_equal "", @ui.error
+ end
+
+ def test_execute_exact_match
+ @cmd.options[:args] = %w[foo]
+ gem 'foo'
+ gem 'bar'
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|lib/foo\.rb|, @ui.output
+ assert_match %r|Rakefile|, @ui.output
+ assert_equal "", @ui.error
+ end
+
+ def test_execute_lib_only
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:lib_only] = true
+
+ gem 'foo'
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|lib/foo\.rb|, @ui.output
+ refute_match %r|Rakefile|, @ui.output
+
+ assert_equal "", @ui.error
+ end
+
+ def test_execute_missing_single
+ @cmd.options[:args] = %w[foo]
+
+ assert_raises Gem::MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_match "Unable to find gem 'foo'", @ui.output
+ assert_empty @ui.error
+ end
+
+ def test_execute_missing_multiple
+ @cmd.options[:args] = %w[foo bar]
+
+ gem 'foo'
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match "lib/foo.rb", @ui.output
+ assert_match "Unable to find gem 'bar'", @ui.output
+
+ assert_empty @ui.error
+ end
+
+ def test_execute_multiple
+ @cmd.options[:args] = %w[foo bar]
+
+ gem 'foo'
+ gem 'bar'
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|lib/foo\.rb|, @ui.output
+ assert_match %r|lib/bar\.rb|, @ui.output
+ assert_match %r|Rakefile|, @ui.output
+ assert_equal "", @ui.error
+ end
+
+ def test_execute_show_install_dir
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:show_install_dir] = true
+
+ gem 'foo'
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = File.join @gemhome, 'gems', 'foo-2'
+
+ assert_equal "#{expected}\n", @ui.output
+ assert_equal "", @ui.error
+ end
+
+ def test_execute_show_install_dir_version
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:show_install_dir] = true
+ @cmd.options[:version] = Gem::Requirement.new '= 1'
+
+ gem 'foo', 1
+ gem 'foo', 2
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = File.join @gemhome, 'gems', 'foo-1'
+
+ assert_equal "#{expected}\n", @ui.output
+ assert_equal "", @ui.error
+ end
+
+ def test_execute_no_prefix
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:prefix] = false
+
+ gem 'foo'
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+Rakefile
+lib/foo.rb
+ EOF
+
+ assert_equal expected, @ui.output
+
+ assert_equal "", @ui.error
+ end
+
+ def test_execute_default_gem
+ default_gem_spec = new_default_spec("default", "2.0.0.0",
+ nil, "default/gem.rb")
+ default_gem_spec.executables = ["default_command"]
+ default_gem_spec.files += ["default_gem.so"]
+ install_default_specs(default_gem_spec)
+
+ @cmd.options[:args] = %w[default]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = [
+ File.join(RbConfig::CONFIG['bindir'], 'default_command'),
+ File.join(RbConfig::CONFIG['rubylibdir'], 'default/gem.rb'),
+ File.join(RbConfig::CONFIG['archdir'], 'default_gem.so')
+ ].sort.join "\n"
+
+ assert_equal expected, @ui.output.chomp
+ assert_equal "", @ui.error
+ end
+
+ def test_handle_options
+ refute @cmd.options[:lib_only]
+ assert @cmd.options[:prefix]
+ assert_empty @cmd.options[:specdirs]
+ assert_nil @cmd.options[:version]
+ refute @cmd.options[:show_install_dir]
+
+ @cmd.send :handle_options, %w[
+ -l
+ -s
+ foo
+ --version 0.0.2
+ --no-prefix
+ --show-install-dir
+ ]
+
+ assert @cmd.options[:lib_only]
+ refute @cmd.options[:prefix]
+ assert_equal %w[foo], @cmd.options[:specdirs]
+ assert_equal Gem::Requirement.new('0.0.2'), @cmd.options[:version]
+ assert @cmd.options[:show_install_dir]
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_commands_dependency_command.rb b/test/rubygems/test_gem_commands_dependency_command.rb
new file mode 100644
index 0000000000..e22b240afe
--- /dev/null
+++ b/test/rubygems/test_gem_commands_dependency_command.rb
@@ -0,0 +1,221 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/dependency_command'
+
+class TestGemCommandsDependencyCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::DependencyCommand.new
+ @cmd.options[:domain] = :local
+ end
+
+ def test_execute
+ quick_gem 'foo' do |gem|
+ gem.add_dependency 'bar', '> 1'
+ gem.add_dependency 'baz', '> 1'
+ end
+
+ @cmd.options[:args] = %w[foo]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "Gem foo-2\n bar (> 1)\n baz (> 1)\n\n",
+ @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_no_args
+ spec_fetcher do |fetcher|
+ fetcher.spec 'a', 1
+ fetcher.spec 'a', '2.a'
+ fetcher.spec 'dep_x', 1, 'x' => '>= 1'
+ fetcher.legacy_platform
+ end
+
+ @cmd.options[:args] = []
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+Gem a-1
+
+Gem a-2.a
+
+Gem dep_x-1
+ x (>= 1)
+
+Gem pl-1-x86-linux
+
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_no_match
+ @cmd.options[:args] = %w[foo]
+
+ assert_raises Gem::MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal "No gems found matching foo (>= 0)\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_pipe_format
+ util_spec 'foo' do |gem|
+ gem.add_dependency 'bar', '> 1'
+ end
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:pipe_format] = true
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "bar --version '> 1'\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_regexp
+ spec_fetcher do |fetcher|
+ fetcher.spec 'a', 1
+ fetcher.spec 'a', '2.a'
+ fetcher.spec 'a_evil', 9
+ fetcher.spec 'b', 2
+ end
+
+ @cmd.options[:args] = %w[/[ab]/]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+Gem a-1
+
+Gem a-2.a
+
+Gem a_evil-9
+
+Gem b-2
+
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_reverse
+ # FIX: this shouldn't need to write out, but fails if you switch it
+ quick_gem 'foo' do |gem|
+ gem.add_dependency 'bar', '> 1'
+ end
+
+ quick_gem 'baz' do |gem|
+ gem.add_dependency 'foo'
+ end
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:reverse_dependencies] = true
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+Gem foo-2
+ bar (> 1)
+ Used by
+ baz-2 (foo (>= 0))
+
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_reverse_remote
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:reverse_dependencies] = true
+ @cmd.options[:domain] = :remote
+
+ assert_raises Gem::MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ expected = <<-EOF
+ERROR: Only reverse dependencies for local gems are supported.
+ EOF
+
+ assert_equal '', @ui.output
+ assert_equal expected, @ui.error
+ end
+
+ def test_execute_remote
+ spec_fetcher do |fetcher|
+ fetcher.spec 'foo', 2, 'bar' => '> 1'
+ end
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:domain] = :remote
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "Gem foo-2\n bar (> 1)\n\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_remote_version
+ @fetcher = Gem::FakeFetcher.new
+ Gem::RemoteFetcher.fetcher = @fetcher
+
+ spec_fetcher do |fetcher|
+ fetcher.spec 'a', 1
+ fetcher.spec 'a', 2
+ end
+
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:domain] = :remote
+ @cmd.options[:version] = req '= 1'
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "Gem a-1\n\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_prerelease
+ spec_fetcher do |fetcher|
+ fetcher.spec 'a', '2.a'
+ end
+
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:domain] = :remote
+ @cmd.options[:prerelease] = true
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "Gem a-2.a\n\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_commands_environment_command.rb b/test/rubygems/test_gem_commands_environment_command.rb
new file mode 100644
index 0000000000..81ff55d357
--- /dev/null
+++ b/test/rubygems/test_gem_commands_environment_command.rb
@@ -0,0 +1,153 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/environment_command'
+
+class TestGemCommandsEnvironmentCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::EnvironmentCommand.new
+ end
+
+ def test_execute
+ orig_sources = Gem.sources.dup
+ orig_path, ENV['PATH'] = ENV['PATH'], %w[/usr/local/bin /usr/bin /bin].join(File::PATH_SEPARATOR)
+ Gem.sources.replace %w[http://gems.example.com]
+ Gem.configuration['gemcutter_key'] = 'blah'
+
+ @cmd.send :handle_options, %w[]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|RUBYGEMS VERSION: (\d\.)+\d|, @ui.output
+ assert_match %r|RUBY VERSION: \d\.\d\.\d \(.*\) \[.*\]|, @ui.output
+ assert_match %r|INSTALLATION DIRECTORY: #{Regexp.escape @gemhome}|,
+ @ui.output
+ assert_match %r|RUBYGEMS PREFIX: |, @ui.output
+ assert_match %r|RUBY EXECUTABLE:.*#{RbConfig::CONFIG['ruby_install_name']}|,
+ @ui.output
+ assert_match %r|SYSTEM CONFIGURATION DIRECTORY:|, @ui.output
+ assert_match %r|EXECUTABLE DIRECTORY:|, @ui.output
+ assert_match %r|RUBYGEMS PLATFORMS:|, @ui.output
+ assert_match %r|- #{Gem::Platform.local}|, @ui.output
+ assert_match %r|GEM PATHS:|, @ui.output
+ assert_match %r|- #{Regexp.escape @gemhome}|, @ui.output
+ assert_match %r|GEM CONFIGURATION:|, @ui.output
+ assert_match %r|"gemcutter_key" => "\*\*\*\*"|, @ui.output
+ assert_match %r|:verbose => |, @ui.output
+ assert_match %r|REMOTE SOURCES:|, @ui.output
+
+ assert_match %r|- SHELL PATH:|, @ui.output
+ assert_match %r|- /usr/local/bin$|, @ui.output
+ assert_match %r|- /usr/bin$|, @ui.output
+ assert_match %r|- /bin$|, @ui.output
+
+ assert_empty @ui.error
+
+ ensure
+ Gem.sources.replace orig_sources
+ ENV['PATH'] = orig_path
+ end
+
+ def test_execute_gemdir
+ @cmd.send :handle_options, %w[gemdir]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "#{@gemhome}\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_gempath
+ @cmd.send :handle_options, %w[gempath]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "#{@gemhome}\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_gempath_multiple
+ Gem.clear_paths
+ path = [@gemhome, "#{@gemhome}2"].join File::PATH_SEPARATOR
+ ENV['GEM_PATH'] = path
+
+ @cmd.send :handle_options, %w[gempath]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "#{Gem.path.join File::PATH_SEPARATOR}\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_packageversion
+ @cmd.send :handle_options, %w[packageversion]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "#{Gem::RubyGemsPackageVersion}\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_remotesources
+ orig_sources = Gem.sources.dup
+ Gem.sources.replace %w[http://gems.example.com]
+
+ @cmd.send :handle_options, %w[remotesources]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "http://gems.example.com\n", @ui.output
+ assert_equal '', @ui.error
+
+ ensure
+ Gem.sources.replace orig_sources
+ end
+
+ def test_execute_unknown
+ @cmd.send :handle_options, %w[unknown]
+
+ assert_raises Gem::CommandLineError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal '', @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_version
+ @cmd.send :handle_options, %w[version]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "#{Gem::VERSION}\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_platform
+ @cmd.send :handle_options, %w[platform]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "#{Gem.platforms.join File::PATH_SEPARATOR}\n", @ui.output
+ assert_equal '', @ui.error
+ end
+end
diff --git a/test/rubygems/test_gem_commands_fetch_command.rb b/test/rubygems/test_gem_commands_fetch_command.rb
new file mode 100644
index 0000000000..c452e79f14
--- /dev/null
+++ b/test/rubygems/test_gem_commands_fetch_command.rb
@@ -0,0 +1,126 @@
+require 'rubygems/test_case'
+require 'rubygems/package'
+require 'rubygems/security'
+require 'rubygems/commands/fetch_command'
+
+class TestGemCommandsFetchCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::FetchCommand.new
+ end
+
+ def test_execute
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ end
+
+ refute_path_exists File.join(@tempdir, 'cache'), 'sanity check'
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ a2 = specs['a-2']
+
+ assert_path_exists(File.join(@tempdir, a2.file_name),
+ "#{a2.full_name} not fetched")
+ refute_path_exists File.join(@tempdir, 'cache'),
+ 'gem repository directories must not be created'
+ end
+
+ def test_execute_latest
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'a', 1
+ fetcher.gem 'a', 2
+ end
+
+ refute_path_exists File.join(@tempdir, 'cache'), 'sanity check'
+
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:version] = req('>= 0.1')
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ a2 = specs['a-2']
+ assert_path_exists(File.join(@tempdir, a2.file_name),
+ "#{a2.full_name} not fetched")
+ refute_path_exists File.join(@tempdir, 'cache'),
+ 'gem repository directories must not be created'
+ end
+
+ def test_execute_prerelease
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ fetcher.gem 'a', '2.a'
+ end
+
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:prerelease] = true
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ a2 = specs['a-2']
+
+ assert_path_exists(File.join(@tempdir, a2.file_name),
+ "#{a2.full_name} not fetched")
+ end
+
+ def test_execute_specific_prerelease
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ fetcher.gem 'a', '2.a'
+ end
+
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:prerelease] = true
+ @cmd.options[:version] = "2.a"
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ a2_pre = specs['a-2.a']
+
+ assert_path_exists(File.join(@tempdir, a2_pre.file_name),
+ "#{a2_pre.full_name} not fetched")
+ end
+
+ def test_execute_version
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'a', 1
+ fetcher.gem 'a', 2
+ end
+
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:version] = Gem::Requirement.new '1'
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ a1 = specs['a-1']
+
+ assert_path_exists(File.join(@tempdir, a1.file_name),
+ "#{a1.full_name} not fetched")
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_commands_generate_index_command.rb b/test/rubygems/test_gem_commands_generate_index_command.rb
new file mode 100644
index 0000000000..2e478d9c9e
--- /dev/null
+++ b/test/rubygems/test_gem_commands_generate_index_command.rb
@@ -0,0 +1,50 @@
+require 'rubygems/test_case'
+require 'rubygems/indexer'
+require 'rubygems/commands/generate_index_command'
+
+class TestGemCommandsGenerateIndexCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::GenerateIndexCommand.new
+ @cmd.options[:directory] = @gemhome
+ end
+
+ def test_execute
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ specs = File.join @gemhome, "specs.4.8.gz"
+
+ assert File.exist?(specs), specs
+ end
+
+ def test_handle_options_directory
+ return if win_platform?
+ refute_equal '/nonexistent', @cmd.options[:directory]
+
+ @cmd.handle_options %w[--directory /nonexistent]
+
+ assert_equal '/nonexistent', @cmd.options[:directory]
+ end
+
+ def test_handle_options_directory_windows
+ return unless win_platform?
+
+ refute_equal '/nonexistent', @cmd.options[:directory]
+
+ @cmd.handle_options %w[--directory C:/nonexistent]
+
+ assert_equal 'C:/nonexistent', @cmd.options[:directory]
+ end
+
+ def test_handle_options_update
+ @cmd.handle_options %w[--update]
+
+ assert @cmd.options[:update]
+ end
+
+end if ''.respond_to? :to_xs
+
diff --git a/test/rubygems/test_gem_commands_help_command.rb b/test/rubygems/test_gem_commands_help_command.rb
new file mode 100644
index 0000000000..bed6095827
--- /dev/null
+++ b/test/rubygems/test_gem_commands_help_command.rb
@@ -0,0 +1,74 @@
+require "rubygems"
+require "rubygems/test_case"
+require "rubygems/commands/help_command"
+require "rubygems/package"
+require "rubygems/command_manager"
+require File.expand_path('../rubygems_plugin', __FILE__)
+
+class TestGemCommandsHelpCommand < Gem::TestCase
+ def setup
+ super
+
+ @cmd = Gem::Commands::HelpCommand.new
+
+ load File.expand_path('../rubygems_plugin.rb', __FILE__) unless
+ Gem::Commands.const_defined? :InterruptCommand
+ end
+
+ def test_gem_help_bad
+ util_gem 'bad' do |out, err|
+ assert_equal('', out)
+ assert_match "Unknown command bad", err
+ end
+ end
+
+ def test_gem_help_gem_dependencies
+ util_gem 'gem_dependencies' do |out, err|
+ assert_match 'gem.deps.rb', out
+ assert_equal '', err
+ end
+ end
+
+ def test_gem_help_platforms
+ util_gem 'platforms' do |out, err|
+ assert_match(/x86-freebsd/, out)
+ assert_equal '', err
+ end
+ end
+
+ def test_gem_help_commands
+ mgr = Gem::CommandManager.new
+
+ util_gem 'commands' do |out, err|
+ mgr.command_names.each do |cmd|
+ assert_match(/\s+#{cmd}\s+\S+/, out)
+ end
+
+ if defined?(OpenSSL::SSL) then
+ assert_empty err
+
+ refute_match 'No command found for ', out
+ end
+ end
+ end
+
+ def test_gem_no_args_shows_help
+ util_gem do |out, err|
+ assert_match(/Usage:/, out)
+ assert_match(/gem install/, out)
+ assert_equal '', err
+ end
+ end
+
+ def util_gem *args
+ @cmd.options[:args] = args
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ yield @ui.output, @ui.error
+ end
+end
diff --git a/test/rubygems/test_gem_commands_install_command.rb b/test/rubygems/test_gem_commands_install_command.rb
new file mode 100644
index 0000000000..f03285ae85
--- /dev/null
+++ b/test/rubygems/test_gem_commands_install_command.rb
@@ -0,0 +1,997 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/install_command'
+require 'rubygems/rdoc'
+
+class TestGemCommandsInstallCommand < Gem::TestCase
+
+ def setup
+ super
+ common_installer_setup
+
+ @cmd = Gem::Commands::InstallCommand.new
+ @cmd.options[:document] = []
+
+ @gemdeps = "tmp_install_gemdeps"
+ @orig_args = Gem::Command.build_args
+
+ common_installer_setup
+ end
+
+ def teardown
+ super
+
+ common_installer_teardown
+
+ Gem::Command.build_args = @orig_args
+ File.unlink @gemdeps if File.file? @gemdeps
+ File.unlink "#{@gemdeps}.lock" if File.file? "#{@gemdeps}.lock"
+ end
+
+ def test_execute_exclude_prerelease
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ fetcher.gem 'a', '2.pre'
+ end
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ assert_equal %w[a-2], @cmd.installed_specs.map { |spec| spec.full_name }
+ end
+
+ def test_execute_explicit_version_includes_prerelease
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ fetcher.gem 'a', '2.a'
+ end
+
+ a2_pre = specs['a-2.a']
+
+ @cmd.handle_options [a2_pre.name, '--version', a2_pre.version.to_s,
+ "--no-ri", "--no-rdoc"]
+ assert @cmd.options[:prerelease]
+ assert @cmd.options[:version].satisfied_by?(a2_pre.version)
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ assert_equal %w[a-2.a], @cmd.installed_specs.map { |spec| spec.full_name }
+ end
+
+ def test_execute_local
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ end
+
+ @cmd.options[:domain] = :local
+
+ FileUtils.mv specs['a-2'].cache_file, @tempdir
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ orig_dir = Dir.pwd
+ begin
+ Dir.chdir @tempdir
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ ensure
+ Dir.chdir orig_dir
+ end
+ end
+
+ assert_equal %w[a-2], @cmd.installed_specs.map { |spec| spec.full_name }
+
+ assert_match "1 gem installed", @ui.output
+ end
+
+ def test_execute_no_user_install
+ skip 'skipped on MS Windows (chmod has no effect)' if win_platform?
+
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ end
+
+ @cmd.options[:user_install] = false
+
+ FileUtils.mv specs['a-2'].cache_file, @tempdir
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ orig_dir = Dir.pwd
+ begin
+ FileUtils.chmod 0755, @userhome
+ FileUtils.chmod 0555, @gemhome
+
+ Dir.chdir @tempdir
+ assert_raises Gem::FilePermissionError do
+ @cmd.execute
+ end
+ ensure
+ Dir.chdir orig_dir
+ FileUtils.chmod 0755, @gemhome
+ end
+ end
+ end
+
+ def test_execute_local_missing
+ spec_fetcher
+
+ @cmd.options[:domain] = :local
+
+ @cmd.options[:args] = %w[no_such_gem]
+
+ use_ui @ui do
+ e = assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+ assert_equal 2, e.exit_code
+ end
+
+ # HACK no repository was checked
+ assert_match(/ould not find a valid gem 'no_such_gem'/, @ui.error)
+ end
+
+ def test_execute_no_gem
+ @cmd.options[:args] = %w[]
+
+ assert_raises Gem::CommandLineError do
+ @cmd.execute
+ end
+ end
+
+ def test_execute_nonexistent
+ spec_fetcher
+
+ @cmd.options[:args] = %w[nonexistent]
+
+ use_ui @ui do
+ e = assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+ assert_equal 2, e.exit_code
+ end
+
+ assert_match(/ould not find a valid gem 'nonexistent'/, @ui.error)
+ end
+
+ def test_execute_bad_source
+ spec_fetcher
+
+ # This is needed because we need to exercise the cache path
+ # within SpecFetcher
+ path = File.join Gem.spec_cache_dir, "not-there.nothing%80", "latest_specs.4.8"
+
+ FileUtils.mkdir_p File.dirname(path)
+
+ File.open path, "w" do |f|
+ f.write Marshal.dump([])
+ end
+
+ Gem.sources.replace ["http://not-there.nothing"]
+
+ @cmd.options[:args] = %w[nonexistent]
+
+ use_ui @ui do
+ e = assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+ assert_equal 2, e.exit_code
+ end
+
+ errs = @ui.error.split("\n")
+
+ assert_match(/ould not find a valid gem 'nonexistent'/, errs.shift)
+ assert_match(%r!Unable to download data from http://not-there.nothing!, errs.shift)
+ end
+
+ def test_execute_nonexistent_hint_disabled
+ misspelled = "nonexistent_with_hint"
+ correctly_spelled = "non_existent_with_hint"
+
+ spec_fetcher do |fetcher|
+ fetcher.spec correctly_spelled, 2
+ end
+
+ @cmd.options[:args] = [misspelled]
+ @cmd.options[:suggest_alternate] = false
+
+ use_ui @ui do
+ e = assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+
+ assert_equal 2, e.exit_code
+ end
+
+ expected = <<-EXPECTED
+ERROR: Could not find a valid gem 'nonexistent_with_hint' (>= 0) in any repository
+ EXPECTED
+
+ assert_equal expected, @ui.error
+ end
+
+ def test_execute_nonexistent_with_hint
+ misspelled = "nonexistent_with_hint"
+ correctly_spelled = "non_existent_with_hint"
+
+ spec_fetcher do |fetcher|
+ fetcher.spec correctly_spelled, 2
+ end
+
+ @cmd.options[:args] = [misspelled]
+
+ use_ui @ui do
+ e = assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+
+ assert_equal 2, e.exit_code
+ end
+
+ expected = "ERROR: Could not find a valid gem 'nonexistent_with_hint' (>= 0) in any repository
+ERROR: Possible alternatives: non_existent_with_hint
+"
+
+ assert_equal expected, @ui.error
+ end
+
+ def test_execute_nonexistent_with_dashes
+ misspelled = "non-existent_with-hint"
+ correctly_spelled = "nonexistent-with_hint"
+
+ spec_fetcher do |fetcher|
+ fetcher.spec correctly_spelled, 2
+ fetcher.clear
+ end
+
+ @cmd.options[:args] = [misspelled]
+
+ use_ui @ui do
+ e = assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+
+ assert_equal 2, e.exit_code
+ end
+
+ expected = [
+ "ERROR: Could not find a valid gem 'non-existent_with-hint' (>= 0) in any repository",
+ "ERROR: Possible alternatives: nonexistent-with_hint"
+ ]
+
+ output = @ui.error.split "\n"
+
+ assert_equal expected, output
+ end
+
+ def test_execute_conflicting_install_options
+ @cmd.options[:user_install] = true
+ @cmd.options[:install_dir] = "whatever"
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+ end
+
+ expected = "ERROR: Use --install-dir or --user-install but not both\n"
+
+ assert_equal expected, @ui.error
+ end
+
+ def test_execute_prerelease_skipped_when_no_flag_set
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 1
+ fetcher.gem 'a', '3.a'
+ end
+
+ @cmd.options[:prerelease] = false
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ assert_equal %w[a-1], @cmd.installed_specs.map { |spec| spec.full_name }
+ end
+
+ def test_execute_prerelease_wins_over_previous_ver
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 1
+ fetcher.gem 'a', '2.a'
+ fetcher.clear
+ end
+
+ @cmd.options[:prerelease] = true
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ assert_equal %w[a-2.a], @cmd.installed_specs.map { |spec| spec.full_name }
+ end
+
+ def test_execute_prerelease_skipped_when_non_pre_available
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', '2.pre'
+ fetcher.gem 'a', 2
+ end
+
+ @cmd.options[:prerelease] = true
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ assert_equal %w[a-2], @cmd.installed_specs.map { |spec| spec.full_name }
+ end
+
+ def test_execute_rdoc
+ skip if RUBY_VERSION <= "1.8.7"
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ end
+
+ Gem.done_installing(&Gem::RDoc.method(:generation_hook))
+
+ @cmd.options[:document] = %w[rdoc ri]
+ @cmd.options[:domain] = :local
+
+ a2 = specs['a-2']
+ FileUtils.mv a2.cache_file, @tempdir
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ # Don't use Dir.chdir with a block, it warnings a lot because
+ # of a downstream Dir.chdir with a block
+ old = Dir.getwd
+
+ begin
+ Dir.chdir @tempdir
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ ensure
+ Dir.chdir old
+ end
+ end
+
+ wait_for_child_process_to_exit
+
+ assert_path_exists File.join(a2.doc_dir, 'ri')
+ assert_path_exists File.join(a2.doc_dir, 'rdoc')
+ end
+
+ def test_execute_saves_build_args
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ end
+
+ args = %w!--with-awesome=true --more-awesome=yes!
+
+ Gem::Command.build_args = args
+
+ a2 = specs['a-2']
+ FileUtils.mv a2.cache_file, @tempdir
+
+ @cmd.options[:domain] = :local
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ # Don't use Dir.chdir with a block, it warnings a lot because
+ # of a downstream Dir.chdir with a block
+ old = Dir.getwd
+
+ begin
+ Dir.chdir @tempdir
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ ensure
+ Dir.chdir old
+ end
+ end
+
+ path = a2.build_info_file
+ assert_path_exists path
+
+ assert_equal args, a2.build_args
+ end
+
+
+ def test_execute_remote
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ end
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ assert_equal %w[a-2], @cmd.installed_specs.map { |spec| spec.full_name }
+
+ assert_match "1 gem installed", @ui.output
+ end
+
+ def test_execute_remote_ignores_files
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'a', 1
+ fetcher.gem 'a', 2
+ end
+
+ @cmd.options[:domain] = :remote
+
+ a1 = specs['a-1']
+ a2 = specs['a-2']
+
+ FileUtils.mv a2.cache_file, @tempdir
+
+ @fetcher.data["#{@gem_repo}gems/#{a2.file_name}"] =
+ read_binary(a1.cache_file)
+
+ @cmd.options[:args] = [a2.name]
+
+ gemdir = File.join @gemhome, 'specifications'
+
+ a2_gemspec = File.join(gemdir, "a-2.gemspec")
+ a1_gemspec = File.join(gemdir, "a-1.gemspec")
+
+ FileUtils.rm_rf a1_gemspec
+ FileUtils.rm_rf a2_gemspec
+
+ start = Dir["#{gemdir}/*"]
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+ end
+
+ assert_equal %w[a-1], @cmd.installed_specs.map { |spec| spec.full_name }
+
+ assert_match "1 gem installed", @ui.output
+
+ fin = Dir["#{gemdir}/*"]
+
+ assert_equal [a1_gemspec], fin - start
+ end
+
+ def test_execute_two
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ fetcher.gem 'b', 2
+ end
+
+ FileUtils.mv specs['a-2'].cache_file, @tempdir
+ FileUtils.mv specs['b-2'].cache_file, @tempdir
+
+ @cmd.options[:domain] = :local
+
+ @cmd.options[:args] = %w[a b]
+
+ use_ui @ui do
+ orig_dir = Dir.pwd
+ begin
+ Dir.chdir @tempdir
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ ensure
+ Dir.chdir orig_dir
+ end
+ end
+
+ assert_equal %w[a-2 b-2], @cmd.installed_specs.map { |spec| spec.full_name }
+
+ assert_match "2 gems installed", @ui.output
+ end
+
+ def test_execute_two_version
+ @cmd.options[:args] = %w[a b]
+ @cmd.options[:version] = Gem::Requirement.new("> 1")
+
+ use_ui @ui do
+ e = assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+
+ assert_equal 1, e.exit_code
+ end
+
+ assert_empty @cmd.installed_specs
+
+ msg = "ERROR: Can't use --version w/ multiple gems. Use name:ver instead."
+
+ assert_empty @ui.output
+ assert_equal msg, @ui.error.chomp
+ end
+
+ def test_execute_conservative
+ spec_fetcher do |fetcher|
+ fetcher.gem 'b', 2
+
+ fetcher.clear
+
+ fetcher.gem 'a', 2
+ end
+
+ @cmd.options[:conservative] = true
+
+ @cmd.options[:args] = %w[a b]
+
+ use_ui @ui do
+ orig_dir = Dir.pwd
+ begin
+ Dir.chdir @tempdir
+ assert_raises Gem::MockGemUi::SystemExitException do
+ @cmd.execute
+ end
+ ensure
+ Dir.chdir orig_dir
+ end
+ end
+
+ assert_equal %w[b-2], @cmd.installed_specs.map { |spec| spec.full_name }
+
+ assert_equal "", @ui.error
+ assert_match "1 gem installed", @ui.output
+ end
+
+ def test_install_gem_ignore_dependencies_both
+ done_installing = false
+ Gem.done_installing do
+ done_installing = true
+ end
+
+ spec = quick_spec 'a', 2
+
+ util_build_gem spec
+
+ FileUtils.mv spec.cache_file, @tempdir
+
+ @cmd.options[:ignore_dependencies] = true
+
+ @cmd.install_gem 'a', '>= 0'
+
+ assert_equal %w[a-2], @cmd.installed_specs.map { |s| s.full_name }
+
+ assert done_installing, 'documentation was not generated'
+ end
+
+ def test_install_gem_ignore_dependencies_remote
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ end
+
+ @cmd.options[:ignore_dependencies] = true
+
+ @cmd.install_gem 'a', '>= 0'
+
+ assert_equal %w[a-2], @cmd.installed_specs.map { |spec| spec.full_name }
+ end
+
+ def test_install_gem_ignore_dependencies_specific_file
+ spec = quick_spec 'a', 2
+
+ util_build_gem spec
+
+ FileUtils.mv spec.cache_file, @tempdir
+
+ @cmd.options[:ignore_dependencies] = true
+
+ @cmd.install_gem File.join(@tempdir, spec.file_name), nil
+
+ assert_equal %w[a-2], @cmd.installed_specs.map { |s| s.full_name }
+ end
+
+ def test_parses_requirement_from_gemname
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ fetcher.gem 'b', 2
+ end
+
+ @cmd.options[:domain] = :local
+
+ req = "a:10.0"
+
+ @cmd.options[:args] = [req]
+
+ e = nil
+ use_ui @ui do
+ orig_dir = Dir.pwd
+ begin
+ Dir.chdir @tempdir
+ e = assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+ ensure
+ Dir.chdir orig_dir
+ end
+ end
+
+ assert_equal 2, e.exit_code
+ assert_match %r!Could not find a valid gem 'a' \(= 10.0\)!, @ui.error
+ end
+
+ def test_show_errors_on_failure
+ Gem.sources.replace ["http://not-there.nothing"]
+
+ @cmd.options[:args] = ["blah"]
+
+ e = nil
+ use_ui @ui do
+ orig_dir = Dir.pwd
+ begin
+ Dir.chdir @tempdir
+ e = assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+ ensure
+ Dir.chdir orig_dir
+ end
+ end
+
+ assert_equal 2, e.exit_code
+
+ assert_match 'Unable to download data', @ui.error
+ end
+
+ def test_show_source_problems_even_on_success
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ fetcher.clear
+ end
+
+ Gem.sources << "http://nonexistent.example"
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ assert_equal %w[a-2], @cmd.installed_specs.map { |spec| spec.full_name }
+
+ assert_match "1 gem installed", @ui.output
+
+ e = @ui.error
+
+ x = "WARNING: Unable to pull data from 'http://nonexistent.example': no data for http://nonexistent.example/specs.4.8.gz (http://nonexistent.example/specs.4.8.gz)\n"
+ assert_equal x, e
+ end
+
+ def test_execute_uses_from_a_gemdeps
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ end
+
+ File.open @gemdeps, "w" do |f|
+ f << "gem 'a'"
+ end
+
+ @cmd.options[:gemdeps] = @gemdeps
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ assert_equal %w[], @cmd.installed_specs.map { |spec| spec.full_name }
+
+ assert_match "Using a (2)", @ui.output
+ assert File.exist?("#{@gemdeps}.lock")
+ end
+
+ def test_execute_uses_from_a_gemdeps_with_no_lock
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ end
+
+ File.open @gemdeps, "w" do |f|
+ f << "gem 'a'"
+ end
+
+ @cmd.handle_options %w[--no-lock]
+ @cmd.options[:gemdeps] = @gemdeps
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ assert_equal %w[], @cmd.installed_specs.map { |spec| spec.full_name }
+
+ assert_match "Using a (2)", @ui.output
+ assert !File.exist?("#{@gemdeps}.lock")
+ end
+
+ def test_execute_installs_from_a_gemdeps_with_conservative
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ fetcher.clear
+ fetcher.gem 'a', 1
+ end
+
+ File.open @gemdeps, "w" do |f|
+ f << "gem 'a'"
+ end
+
+ @cmd.handle_options %w[--conservative]
+ @cmd.options[:gemdeps] = @gemdeps
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ assert_equal %w[], @cmd.installed_specs.map { |spec| spec.full_name }
+
+ assert_match "Using a (1)", @ui.output
+ end
+
+ def test_execute_installs_from_a_gemdeps
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ fetcher.clear
+ end
+
+ File.open @gemdeps, "w" do |f|
+ f << "gem 'a'"
+ end
+
+ @cmd.options[:gemdeps] = @gemdeps
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ assert_equal %w[a-2], @cmd.installed_specs.map { |spec| spec.full_name }
+
+ assert_match "Installing a (2)", @ui.output
+ end
+
+ def test_execute_installs_deps_a_gemdeps
+ spec_fetcher do |fetcher|
+ fetcher.gem 'q', '1.0'
+ fetcher.gem 'r', '2.0', 'q' => nil
+ fetcher.clear
+ end
+
+ File.open @gemdeps, "w" do |f|
+ f << "gem 'r'"
+ end
+
+ @cmd.options[:gemdeps] = @gemdeps
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ names = @cmd.installed_specs.map { |spec| spec.full_name }
+
+ assert_equal %w[q-1.0 r-2.0], names
+
+ assert_match "Installing q (1.0)", @ui.output
+ assert_match "Installing r (2.0)", @ui.output
+ end
+
+ def test_execute_uses_deps_a_gemdeps
+ spec_fetcher do |fetcher|
+ fetcher.gem 'r', '2.0', 'q' => nil
+
+ fetcher.clear
+
+ fetcher.spec 'q', '1.0'
+ end
+
+ File.open @gemdeps, "w" do |f|
+ f << "gem 'r'"
+ end
+
+ @cmd.options[:gemdeps] = @gemdeps
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ names = @cmd.installed_specs.map { |spec| spec.full_name }
+
+ assert_equal %w[r-2.0], names
+
+ assert_match "Using q (1.0)", @ui.output
+ assert_match "Installing r (2.0)", @ui.output
+ end
+
+ def test_execute_installs_deps_a_gemdeps_into_a_path
+ spec_fetcher do |fetcher|
+ fetcher.gem 'q', '1.0'
+ fetcher.gem 'r', '2.0', 'q' => nil
+ fetcher.clear
+ end
+
+ File.open @gemdeps, "w" do |f|
+ f << "gem 'r'"
+ end
+
+ @cmd.options[:install_dir] = "gf-path"
+ @cmd.options[:gemdeps] = @gemdeps
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ names = @cmd.installed_specs.map { |spec| spec.full_name }
+
+ assert_equal %w[q-1.0 r-2.0], names
+
+ assert_match "Installing q (1.0)", @ui.output
+ assert_match "Installing r (2.0)", @ui.output
+
+ assert File.file?("gf-path/specifications/q-1.0.gemspec"), "not installed"
+ assert File.file?("gf-path/specifications/r-2.0.gemspec"), "not installed"
+ end
+
+ def test_execute_with_gemdeps_path_ignores_system
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'q', '1.0'
+ fetcher.gem 'r', '2.0', 'q' => nil
+ fetcher.clear
+ end
+
+ Gem::Specification.add_specs specs['q-1.0']
+
+ File.open @gemdeps, "w" do |f|
+ f << "gem 'r'"
+ end
+
+ @cmd.options[:install_dir] = "gf-path"
+ @cmd.options[:gemdeps] = @gemdeps
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ names = @cmd.installed_specs.map { |spec| spec.full_name }
+
+ assert_equal %w[q-1.0 r-2.0], names
+
+ assert_match "Installing q (1.0)", @ui.output
+ assert_match "Installing r (2.0)", @ui.output
+
+ assert File.file?("gf-path/specifications/q-1.0.gemspec"), "not installed"
+ assert File.file?("gf-path/specifications/r-2.0.gemspec"), "not installed"
+ end
+
+ def test_execute_uses_deps_a_gemdeps_with_a_path
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'q', '1.0'
+ fetcher.gem 'r', '2.0', 'q' => nil
+ end
+
+ i = Gem::Installer.new specs['q-1.0'].cache_file, :install_dir => "gf-path"
+ i.install
+
+ assert File.file?("gf-path/specifications/q-1.0.gemspec"), "not installed"
+
+ File.open @gemdeps, "w" do |f|
+ f << "gem 'r'"
+ end
+
+ @cmd.options[:install_dir] = "gf-path"
+ @cmd.options[:gemdeps] = @gemdeps
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::SystemExitException, @ui.error do
+ @cmd.execute
+ end
+ end
+
+ names = @cmd.installed_specs.map { |spec| spec.full_name }
+
+ assert_equal %w[r-2.0], names
+
+ assert_match "Using q (1.0)", @ui.output
+ assert_match "Installing r (2.0)", @ui.output
+ end
+
+ def test_handle_options_file
+ FileUtils.touch 'Gemfile'
+
+ @cmd.handle_options %w[-g Gemfile]
+
+ assert_equal 'Gemfile', @cmd.options[:gemdeps]
+
+ FileUtils.rm 'Gemfile'
+
+ FileUtils.touch 'gem.deps.rb'
+
+ @cmd.handle_options %w[--file gem.deps.rb]
+
+ assert_equal 'gem.deps.rb', @cmd.options[:gemdeps]
+
+ FileUtils.rm 'gem.deps.rb'
+
+ FileUtils.touch 'Isolate'
+
+ @cmd.handle_options %w[-g]
+
+ assert_equal 'Isolate', @cmd.options[:gemdeps]
+
+ FileUtils.touch 'Gemfile'
+
+ @cmd.handle_options %w[-g]
+
+ assert_equal 'Gemfile', @cmd.options[:gemdeps]
+
+ FileUtils.touch 'gem.deps.rb'
+
+ @cmd.handle_options %w[-g]
+
+ assert_equal 'gem.deps.rb', @cmd.options[:gemdeps]
+ end
+
+ def test_handle_options_suggest
+ assert @cmd.options[:suggest_alternate]
+
+ @cmd.handle_options %w[--no-suggestions]
+
+ refute @cmd.options[:suggest_alternate]
+
+ @cmd.handle_options %w[--suggestions]
+
+ assert @cmd.options[:suggest_alternate]
+ end
+
+ def test_handle_options_without
+ @cmd.handle_options %w[--without test]
+
+ assert_equal [:test], @cmd.options[:without_groups]
+
+ @cmd.handle_options %w[--without test,development]
+
+ assert_equal [:test, :development], @cmd.options[:without_groups]
+ end
+
+end
diff --git a/test/rubygems/test_gem_commands_list_command.rb b/test/rubygems/test_gem_commands_list_command.rb
new file mode 100644
index 0000000000..b03f166e1b
--- /dev/null
+++ b/test/rubygems/test_gem_commands_list_command.rb
@@ -0,0 +1,33 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/list_command'
+
+class TestGemCommandsListCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::ListCommand.new
+
+ spec_fetcher do |fetcher|
+ fetcher.spec 'c', 1
+ end
+
+ @fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] = proc do
+ raise Gem::RemoteFetcher::FetchError
+ end
+ end
+
+ def test_execute_installed
+ @cmd.handle_options %w[c --installed]
+
+ assert_raises Gem::MockGemUi::SystemExitException do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal "true\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+end
diff --git a/test/rubygems/test_gem_commands_lock_command.rb b/test/rubygems/test_gem_commands_lock_command.rb
new file mode 100644
index 0000000000..8f30b7f2cc
--- /dev/null
+++ b/test/rubygems/test_gem_commands_lock_command.rb
@@ -0,0 +1,68 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/lock_command'
+
+class TestGemCommandsLockCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @a1 = quick_gem 'a', '1'
+ @b1 = quick_gem 'b', '1' do |s|
+ s.add_runtime_dependency 'a'
+ end
+
+ @d1 = quick_gem 'd', '1' do |s|
+ s.add_runtime_dependency 'z'
+ end
+
+ @cmd = Gem::Commands::LockCommand.new
+ end
+
+ def test_execute
+ @cmd.handle_options %w[b-1]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EXPECTED
+require 'rubygems'
+gem 'b', '= 1'
+gem 'a', '= 1'
+ EXPECTED
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_missing_dependency
+ @cmd.handle_options %w[d-1]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EXPECTED
+require 'rubygems'
+gem 'd', '= 1'
+# Unable to satisfy 'z (>= 0)' from currently installed gems
+ EXPECTED
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_strict
+ @cmd.handle_options %w[c-1 --strict]
+
+ e = assert_raises Gem::Exception do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal 'Could not find gem c-1, try using the full name', e.message
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_commands_mirror.rb b/test/rubygems/test_gem_commands_mirror.rb
new file mode 100644
index 0000000000..2f6fe52401
--- /dev/null
+++ b/test/rubygems/test_gem_commands_mirror.rb
@@ -0,0 +1,32 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/mirror_command'
+
+class TestGemCommandsMirrorCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::MirrorCommand.new
+
+ @mirror_specs = Gem::Specification.find_all_by_name('rubygems-mirror').each do |spec|
+ Gem::Specification.remove_spec spec
+ end
+ end
+
+ def teardown
+ @mirror_specs.each do |spec|
+ Gem::Specification.add_spec spec
+ end
+
+ super
+ end
+
+ def test_execute
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r%Install the rubygems-mirror%i, @ui.error
+ end
+
+end
diff --git a/test/rubygems/test_gem_commands_open_command.rb b/test/rubygems/test_gem_commands_open_command.rb
new file mode 100644
index 0000000000..25f22c81b3
--- /dev/null
+++ b/test/rubygems/test_gem_commands_open_command.rb
@@ -0,0 +1,46 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/open_command'
+
+class TestGemCommandsOpenCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::OpenCommand.new
+ end
+
+ def gem name
+ spec = quick_gem name do |gem|
+ gem.files = %W[lib/#{name}.rb Rakefile]
+ end
+ write_file File.join(*%W[gems #{spec.full_name} lib #{name}.rb])
+ write_file File.join(*%W[gems #{spec.full_name} Rakefile])
+ end
+
+ def test_execute
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:editor] = "#{Gem.ruby} -e0 --"
+
+ gem 'foo'
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "", @ui.error
+ end
+
+ def test_execute_bad_gem
+ @cmd.options[:args] = %w[foo]
+
+ assert_raises Gem::MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_match %r|Unable to find gem 'foo'|, @ui.output
+ assert_equal "", @ui.error
+ end
+
+end
diff --git a/test/rubygems/test_gem_commands_outdated_command.rb b/test/rubygems/test_gem_commands_outdated_command.rb
new file mode 100644
index 0000000000..d369c6b14b
--- /dev/null
+++ b/test/rubygems/test_gem_commands_outdated_command.rb
@@ -0,0 +1,33 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/outdated_command'
+
+class TestGemCommandsOutdatedCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::OutdatedCommand.new
+ end
+
+ def test_initialize
+ assert @cmd.handles?(%W[--platform #{Gem::Platform.local}])
+ end
+
+ def test_execute
+ spec_fetcher do |fetcher|
+ fetcher.spec 'foo', '1.0'
+ fetcher.spec 'foo', '2.0'
+ fetcher.clear
+ fetcher.gem 'foo', '0.1'
+ fetcher.gem 'foo', '0.2'
+ end
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "foo (0.2 < 2.0)\n", @ui.output
+ assert_equal "", @ui.error
+ end
+end
+
diff --git a/test/rubygems/test_gem_commands_owner_command.rb b/test/rubygems/test_gem_commands_owner_command.rb
new file mode 100644
index 0000000000..5d7b66137e
--- /dev/null
+++ b/test/rubygems/test_gem_commands_owner_command.rb
@@ -0,0 +1,204 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/owner_command'
+
+class TestGemCommandsOwnerCommand < Gem::TestCase
+
+ def setup
+ super
+
+ ENV["RUBYGEMS_HOST"] = nil
+ @fetcher = Gem::FakeFetcher.new
+ Gem::RemoteFetcher.fetcher = @fetcher
+ Gem.configuration.rubygems_api_key = "ed244fbf2b1a52e012da8616c512fa47f9aa5250"
+
+ @cmd = Gem::Commands::OwnerCommand.new
+ end
+
+ def test_show_owners
+ response = <<EOF
+---
+- email: user1@example.com
+- email: user2@example.com
+EOF
+
+ @fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners.yaml"] = [response, 200, 'OK']
+
+ use_ui @ui do
+ @cmd.show_owners("freewill")
+ end
+
+ assert_equal Net::HTTP::Get, @fetcher.last_request.class
+ assert_equal Gem.configuration.rubygems_api_key, @fetcher.last_request["Authorization"]
+
+ assert_match %r{Owners for gem: freewill}, @ui.output
+ assert_match %r{- user1@example.com}, @ui.output
+ assert_match %r{- user2@example.com}, @ui.output
+ end
+
+ def test_show_owners_setting_up_host_through_env_var
+ response = "- email: user1@example.com\n"
+ host = "http://rubygems.example"
+ ENV["RUBYGEMS_HOST"] = host
+
+ @fetcher.data["#{host}/api/v1/gems/freewill/owners.yaml"] = [response, 200, 'OK']
+
+ use_ui @ui do
+ @cmd.show_owners("freewill")
+ end
+
+ assert_match %r{Owners for gem: freewill}, @ui.output
+ assert_match %r{- user1@example.com}, @ui.output
+ end
+
+ def test_show_owners_setting_up_host
+ response = "- email: user1@example.com\n"
+ host = "http://rubygems.example"
+ @cmd.host = host
+
+ @fetcher.data["#{host}/api/v1/gems/freewill/owners.yaml"] = [response, 200, 'OK']
+
+ use_ui @ui do
+ @cmd.show_owners("freewill")
+ end
+
+ assert_match %r{Owners for gem: freewill}, @ui.output
+ assert_match %r{- user1@example.com}, @ui.output
+ end
+
+ def test_show_owners_denied
+ response = "You don't have permission to push to this gem"
+ @fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners.yaml"] = [response, 403, 'Forbidden']
+
+ assert_raises Gem::MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.show_owners("freewill")
+ end
+ end
+
+ assert_match response, @ui.output
+ end
+
+ def test_show_owners_key
+ response = "- email: user1@example.com\n"
+ @fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners.yaml"] = [response, 200, 'OK']
+ File.open Gem.configuration.credentials_path, 'a' do |f|
+ f.write ':other: 701229f217cdf23b1344c7b4b54ca97'
+ end
+ Gem.configuration.load_api_keys
+
+ @cmd.handle_options %w(-k other)
+ @cmd.show_owners('freewill')
+
+ assert_equal '701229f217cdf23b1344c7b4b54ca97', @fetcher.last_request['Authorization']
+ end
+
+ def test_add_owners
+ response = "Owner added successfully."
+ @fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 200, 'OK']
+
+ use_ui @ui do
+ @cmd.add_owners("freewill", ["user-new1@example.com"])
+ end
+
+ assert_equal Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal Gem.configuration.rubygems_api_key, @fetcher.last_request["Authorization"]
+ assert_equal "email=user-new1%40example.com", @fetcher.last_request.body
+
+ assert_match response, @ui.output
+ end
+
+ def test_add_owners_denied
+ response = "You don't have permission to push to this gem"
+ @fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 403, 'Forbidden']
+
+ use_ui @ui do
+ @cmd.add_owners("freewill", ["user-new1@example.com"])
+ end
+
+ assert_match response, @ui.output
+ end
+
+ def test_add_owner_with_host_option_through_execute
+ host = "http://rubygems.example"
+ add_owner_response = "Owner added successfully."
+ show_owners_response = "- email: user1@example.com\n"
+ @fetcher.data["#{host}/api/v1/gems/freewill/owners"] = [add_owner_response, 200, 'OK']
+ @fetcher.data["#{host}/api/v1/gems/freewill/owners.yaml"] = [show_owners_response, 200, 'OK']
+
+ @cmd.handle_options %W[--host #{host} --add user-new1@example.com freewill]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match add_owner_response, @ui.output
+ assert_match %r{Owners for gem: freewill}, @ui.output
+ assert_match %r{- user1@example.com}, @ui.output
+ end
+
+ def test_add_owners_key
+ response = "Owner added successfully."
+ @fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 200, 'OK']
+ File.open Gem.configuration.credentials_path, 'a' do |f|
+ f.write ':other: 701229f217cdf23b1344c7b4b54ca97'
+ end
+ Gem.configuration.load_api_keys
+
+ @cmd.handle_options %w(-k other)
+ @cmd.add_owners('freewill', ['user-new1@example.com'])
+
+ assert_equal '701229f217cdf23b1344c7b4b54ca97', @fetcher.last_request['Authorization']
+ end
+
+ def test_remove_owners
+ response = "Owner removed successfully."
+ @fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 200, 'OK']
+
+ use_ui @ui do
+ @cmd.remove_owners("freewill", ["user-remove1@example.com"])
+ end
+
+ assert_equal Net::HTTP::Delete, @fetcher.last_request.class
+ assert_equal Gem.configuration.rubygems_api_key, @fetcher.last_request["Authorization"]
+ assert_equal "email=user-remove1%40example.com", @fetcher.last_request.body
+
+ assert_match response, @ui.output
+ end
+
+ def test_remove_owners_denied
+ response = "You don't have permission to push to this gem"
+ @fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 403, 'Forbidden']
+
+ use_ui @ui do
+ @cmd.remove_owners("freewill", ["user-remove1@example.com"])
+ end
+
+ assert_match response, @ui.output
+ end
+
+ def test_remove_owners_key
+ response = "Owner removed successfully."
+ @fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 200, 'OK']
+ File.open Gem.configuration.credentials_path, 'a' do |f|
+ f.write ':other: 701229f217cdf23b1344c7b4b54ca97'
+ end
+ Gem.configuration.load_api_keys
+
+ @cmd.handle_options %w(-k other)
+ @cmd.remove_owners('freewill', ['user-remove1@example.com'])
+
+ assert_equal '701229f217cdf23b1344c7b4b54ca97', @fetcher.last_request['Authorization']
+ end
+
+ def test_remove_owners_missing
+ response = 'Owner could not be found.'
+ @fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 404, 'Not Found']
+
+ use_ui @ui do
+ @cmd.remove_owners("freewill", ["missing@example"])
+ end
+
+ assert_equal "Removing missing@example: #{response}\n", @ui.output
+ end
+
+end
diff --git a/test/rubygems/test_gem_commands_pristine_command.rb b/test/rubygems/test_gem_commands_pristine_command.rb
new file mode 100644
index 0000000000..7ea2b042c9
--- /dev/null
+++ b/test/rubygems/test_gem_commands_pristine_command.rb
@@ -0,0 +1,370 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/pristine_command'
+
+class TestGemCommandsPristineCommand < Gem::TestCase
+
+ def setup
+ super
+ @cmd = Gem::Commands::PristineCommand.new
+ end
+
+ def test_execute
+ a = util_spec 'a' do |s|
+ s.executables = %w[foo]
+ s.files = %w[bin/foo lib/a.rb]
+ end
+
+ write_file File.join(@tempdir, 'lib', 'a.rb') do |fp|
+ fp.puts "puts __FILE__"
+ end
+ write_file File.join(@tempdir, 'bin', 'foo') do |fp|
+ fp.puts "#!/usr/bin/ruby"
+ end
+
+ install_gem a
+
+ foo_path = File.join @gemhome, 'gems', a.full_name, 'bin', 'foo'
+ a_rb_path = File.join @gemhome, 'gems', a.full_name, 'lib', 'a.rb'
+
+ write_file foo_path do |io|
+ io.puts 'I changed it!'
+ end
+
+ write_file a_rb_path do |io|
+ io.puts 'I changed it!'
+ end
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "#!/usr/bin/ruby\n", File.read(foo_path), foo_path
+ assert_equal "puts __FILE__\n", File.read(a_rb_path), a_rb_path
+
+ out = @ui.output.split "\n"
+
+ assert_equal "Restoring gems to pristine condition...", out.shift
+ assert_equal "Restored #{a.full_name}", out.shift
+ assert_empty out, out.inspect
+ end
+
+ def test_execute_all
+ a = util_spec 'a' do |s| s.executables = %w[foo] end
+ write_file File.join(@tempdir, 'bin', 'foo') do |fp|
+ fp.puts "#!/usr/bin/ruby"
+ end
+
+ install_gem a
+
+ gem_bin = File.join @gemhome, 'gems', a.full_name, 'bin', 'foo'
+ gem_stub = File.join @gemhome, 'bin', 'foo'
+
+ FileUtils.rm gem_bin
+ FileUtils.rm gem_stub
+
+ @cmd.handle_options %w[--all]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert File.exist?(gem_bin)
+ assert File.exist?(gem_stub)
+
+ out = @ui.output.split "\n"
+
+ assert_equal "Restoring gems to pristine condition...", out.shift
+ assert_equal "Restored #{a.full_name}", out.shift
+ assert_empty out, out.inspect
+ end
+
+ def test_execute_env_shebang
+ a = util_spec 'a' do |s|
+ s.executables = %w[foo]
+ s.files = %w[bin/foo]
+ end
+ write_file File.join(@tempdir, 'bin', 'foo') do |fp|
+ fp.puts "#!/usr/bin/ruby"
+ end
+
+ install_gem a
+
+ gem_exec = File.join @gemhome, 'bin', 'foo'
+
+ FileUtils.rm gem_exec
+
+ @cmd.handle_options %w[--all --env-shebang]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_path_exists gem_exec
+
+ if win_platform?
+ assert_match %r%\A#!\s*ruby%, File.read(gem_exec)
+ else
+ assert_match %r%\A#!\s*/usr/bin/env ruby%, File.read(gem_exec)
+ end
+ end
+
+ def test_execute_extensions_explicit
+ a = util_spec 'a' do |s| s.extensions << 'ext/a/extconf.rb' end
+
+ ext_path = File.join @tempdir, 'ext', 'a', 'extconf.rb'
+ write_file ext_path do |io|
+ io.write <<-'RUBY'
+ File.open "Makefile", "w" do |f|
+ f.puts "clean:\n\techo cleaned\n"
+ f.puts "all:\n\techo built\n"
+ f.puts "install:\n\techo installed\n"
+ end
+ RUBY
+ end
+
+ b = util_spec 'b'
+
+ install_gem a
+ install_gem b
+
+ @cmd.options[:extensions] = true
+ @cmd.options[:extensions_set] = true
+ @cmd.options[:args] = []
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+
+ assert_equal 'Restoring gems to pristine condition...', out.shift
+ assert_equal 'Building native extensions. This could take a while...',
+ out.shift
+ assert_equal "Restored #{a.full_name}", out.shift
+ assert_empty out, out.inspect
+ end
+
+ def test_execute_no_extension
+ a = util_spec 'a' do |s| s.extensions << 'ext/a/extconf.rb' end
+
+ ext_path = File.join @tempdir, 'ext', 'a', 'extconf.rb'
+ write_file ext_path do |io|
+ io.write '# extconf.rb'
+ end
+
+ util_build_gem a
+
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:extensions] = false
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+
+ assert_equal 'Restoring gems to pristine condition...', out.shift
+ assert_equal "Skipped #{a.full_name}, it needs to compile an extension",
+ out.shift
+ assert_empty out, out.inspect
+ end
+
+ def test_execute_with_extension_with_build_args
+ a = util_spec 'a' do |s| s.extensions << 'ext/a/extconf.rb' end
+
+ ext_path = File.join @tempdir, 'ext', 'a', 'extconf.rb'
+ write_file ext_path do |io|
+ io.write <<-'RUBY'
+ File.open "Makefile", "w" do |f|
+ f.puts "clean:\n\techo cleaned\n"
+ f.puts "all:\n\techo built\n"
+ f.puts "install:\n\techo installed\n"
+ end
+ RUBY
+ end
+
+ build_args = %w!--with-awesome=true --sweet!
+
+ install_gem a, :build_args => build_args
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+
+ assert_equal 'Restoring gems to pristine condition...', out.shift
+ assert_equal "Building native extensions with: '--with-awesome=true --sweet'", out.shift
+ assert_equal "This could take a while...", out.shift
+ assert_equal "Restored #{a.full_name}", out.shift
+ assert_empty out, out.inspect
+ end
+
+ def test_execute_many
+ a = util_spec 'a'
+ b = util_spec 'b'
+
+ install_gem a
+ install_gem b
+
+ @cmd.options[:args] = %w[a b]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+
+ assert_equal "Restoring gems to pristine condition...", out.shift
+ assert_equal "Restored #{a.full_name}", out.shift
+ assert_equal "Restored #{b.full_name}", out.shift
+ assert_empty out, out.inspect
+ end
+
+ def test_execute_many_multi_repo
+ a = util_spec 'a'
+ install_gem a
+
+ Gem.clear_paths
+ gemhome2 = File.join @tempdir, 'gemhome2'
+ Gem.paths = { "GEM_PATH" => [gemhome2, @gemhome], "GEM_HOME" => gemhome2 }
+
+ b = util_spec 'b'
+ install_gem b
+
+ @cmd.options[:args] = %w[a b]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+
+ assert_equal "Restoring gems to pristine condition...", out.shift
+ assert_equal "Restored #{a.full_name}", out.shift
+ assert_equal "Restored #{b.full_name}", out.shift
+ assert_empty out, out.inspect
+
+ assert_path_exists File.join(@gemhome, "gems", 'a-2')
+ refute_path_exists File.join(gemhome2, "gems", 'a-2')
+ assert_path_exists File.join(gemhome2, "gems", 'b-2')
+ refute_path_exists File.join(@gemhome, "gems", 'b-2')
+ end
+
+ def test_execute_missing_cache_gem
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'a', 1
+ fetcher.gem 'a', 2
+ fetcher.gem 'a', 3
+ fetcher.gem 'a', '3.a'
+ end
+
+ FileUtils.rm specs['a-2'].cache_file
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+
+ [
+ "Restoring gems to pristine condition...",
+ "Restored a-1",
+ "Cached gem for a-2 not found, attempting to fetch...",
+ "Restored a-2",
+ "Restored a-3.a",
+ "Restored a-3",
+ ].each do |line|
+ assert_equal line, out.shift
+ end
+
+ assert_empty out, out.inspect
+ end
+
+ def test_execute_no_gem
+ @cmd.options[:args] = %w[]
+
+ e = assert_raises Gem::CommandLineError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_match %r|at least one gem name|, e.message
+ end
+
+ def test_execute_only_executables
+ a = util_spec 'a' do |s|
+ s.executables = %w[foo]
+ s.files = %w[bin/foo lib/a.rb]
+ end
+ write_file File.join(@tempdir, 'lib', 'a.rb') do |fp|
+ fp.puts "puts __FILE__"
+ end
+ write_file File.join(@tempdir, 'bin', 'foo') do |fp|
+ fp.puts "#!/usr/bin/ruby"
+ end
+
+ install_gem a
+
+ gem_lib = File.join @gemhome, 'gems', a.full_name, 'lib', 'a.rb'
+ gem_exec = File.join @gemhome, 'bin', 'foo'
+
+ FileUtils.rm gem_exec
+ FileUtils.rm gem_lib
+
+ @cmd.handle_options %w[--all --only-executables]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert File.exist? gem_exec
+ refute File.exist? gem_lib
+ end
+
+ def test_execute_default_gem
+ default_gem_spec = new_default_spec("default", "2.0.0.0",
+ nil, "default/gem.rb")
+ install_default_specs(default_gem_spec)
+
+ @cmd.options[:args] = %w[default]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal([
+ "Restoring gems to pristine condition...",
+ "Skipped default-2.0.0.0, it is a default gem",
+ ],
+ @ui.output.split("\n"))
+ assert_empty(@ui.error)
+ end
+
+ def test_handle_options
+ @cmd.handle_options %w[]
+
+ refute @cmd.options[:all]
+
+ assert @cmd.options[:extensions]
+ refute @cmd.options[:extensions_set]
+
+ assert_equal Gem::Requirement.default, @cmd.options[:version]
+ end
+
+ def test_handle_options_extensions
+ @cmd.handle_options %w[--extensions]
+
+ assert @cmd.options[:extensions]
+ assert @cmd.options[:extensions_set]
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_commands_push_command.rb b/test/rubygems/test_gem_commands_push_command.rb
new file mode 100644
index 0000000000..7d3d2efb88
--- /dev/null
+++ b/test/rubygems/test_gem_commands_push_command.rb
@@ -0,0 +1,262 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/push_command'
+
+class TestGemCommandsPushCommand < Gem::TestCase
+
+ def setup
+ super
+ ENV["RUBYGEMS_HOST"] = nil
+ Gem.host = Gem::DEFAULT_HOST
+ Gem.configuration.disable_default_gem_server = false
+
+ @gems_dir = File.join @tempdir, 'gems'
+ @cache_dir = File.join @gemhome, "cache"
+
+ FileUtils.mkdir @gems_dir
+
+ Gem.configuration.rubygems_api_key =
+ "ed244fbf2b1a52e012da8616c512fa47f9aa5250"
+
+ @spec, @path = util_gem "freewill", "1.0.0"
+ @host = 'https://rubygems.example'
+ @api_key = Gem.configuration.rubygems_api_key
+
+ @fetcher = Gem::FakeFetcher.new
+ Gem::RemoteFetcher.fetcher = @fetcher
+
+ @cmd = Gem::Commands::PushCommand.new
+
+ class << Gem
+ alias_method :orig_latest_rubygems_version, :latest_rubygems_version
+
+ def latest_rubygems_version
+ Gem.rubygems_version
+ end
+ end
+ end
+
+ def teardown
+ super
+
+ class << Gem
+ remove_method :latest_rubygems_version
+ alias_method :latest_rubygems_version, :orig_latest_rubygems_version
+ end
+ end
+
+ def send_battery
+ use_ui @ui do
+ @cmd.instance_variable_set :@host, @host
+ @cmd.send_gem(@path)
+ end
+
+ assert_match %r{Pushing gem to #{@host}...}, @ui.output
+
+ assert_equal Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal Gem.read_binary(@path), @fetcher.last_request.body
+ assert_equal File.size(@path), @fetcher.last_request["Content-Length"].to_i
+ assert_equal "application/octet-stream", @fetcher.last_request["Content-Type"]
+ assert_equal @api_key, @fetcher.last_request["Authorization"]
+
+ assert_match @response, @ui.output
+ end
+
+ def test_execute
+ @response = "Successfully registered gem: freewill (1.0.0)"
+ @fetcher.data["#{Gem.host}/api/v1/gems"] = [@response, 200, 'OK']
+
+ @cmd.options[:args] = [@path]
+
+ @cmd.execute
+
+ assert_equal Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal Gem.read_binary(@path), @fetcher.last_request.body
+ assert_equal "application/octet-stream",
+ @fetcher.last_request["Content-Type"]
+ end
+
+ def test_execute_host
+ host = 'https://other.example'
+
+ @response = "Successfully registered gem: freewill (1.0.0)"
+ @fetcher.data["#{host}/api/v1/gems"] = [@response, 200, 'OK']
+ @fetcher.data["#{Gem.host}/api/v1/gems"] =
+ ['fail', 500, 'Internal Server Error']
+
+ @cmd.options[:host] = host
+ @cmd.options[:args] = [@path]
+
+ @cmd.execute
+
+ assert_equal Net::HTTP::Post, @fetcher.last_request.class
+ assert_equal Gem.read_binary(@path), @fetcher.last_request.body
+ assert_equal "application/octet-stream",
+ @fetcher.last_request["Content-Type"]
+ end
+
+ def test_sending_when_default_host_disabled
+ Gem.configuration.disable_default_gem_server = true
+ response = "You must specify a gem server"
+
+ assert_raises Gem::MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.send_gem(@path)
+ end
+ end
+
+ assert_match response, @ui.error
+ end
+
+ def test_sending_when_default_host_disabled_with_override
+ ENV["RUBYGEMS_HOST"] = @host
+ Gem.configuration.disable_default_gem_server = true
+ @response = "Successfully registered gem: freewill (1.0.0)"
+ @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK']
+
+ send_battery
+ end
+
+ def test_sending_gem_to_metadata_host
+ @host = "http://rubygems.engineyard.com"
+
+ @spec, @path = util_gem "freebird", "1.0.1" do |spec|
+ spec.metadata['default_gem_server'] = @host
+ end
+
+ @api_key = "EYKEY"
+
+ keys = {
+ :rubygems_api_key => 'KEY',
+ @host => @api_key
+ }
+
+ FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path
+ open Gem.configuration.credentials_path, 'w' do |f|
+ f.write keys.to_yaml
+ end
+ Gem.configuration.load_api_keys
+
+ FileUtils.rm Gem.configuration.credentials_path
+
+ @response = "Successfully registered gem: freebird (1.0.1)"
+ @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK']
+ send_battery
+ end
+
+ def test_sending_gem
+ @response = "Successfully registered gem: freewill (1.0.0)"
+ @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK']
+
+ send_battery
+ end
+
+ def test_sending_gem_to_allowed_push_host
+ @host = "http://privategemserver.com"
+
+ @spec, @path = util_gem "freebird", "1.0.1" do |spec|
+ spec.metadata['allowed_push_host'] = @host
+ end
+
+ @api_key = "PRIVKEY"
+
+ keys = {
+ :rubygems_api_key => 'KEY',
+ @host => @api_key
+ }
+
+ FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path
+ open Gem.configuration.credentials_path, 'w' do |f|
+ f.write keys.to_yaml
+ end
+ Gem.configuration.load_api_keys
+
+ FileUtils.rm Gem.configuration.credentials_path
+
+ @response = "Successfully registered gem: freebird (1.0.1)"
+ @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK']
+ send_battery
+ end
+
+ def test_sending_gem_to_disallowed_default_host
+ @spec, @path = util_gem "freebird", "1.0.1" do |spec|
+ spec.metadata['allowed_push_host'] = "https://privategemserver.com"
+ end
+
+ response = %{ERROR: "#{@host}" is not allowed by the gemspec, which only allows "https://privategemserver.com"}
+
+ assert_raises Gem::MockGemUi::TermError do
+ send_battery
+ end
+
+ assert_match response, @ui.error
+ end
+
+ def test_sending_gem_to_disallowed_push_host
+ @host = "https://somebodyelse.com"
+
+ @spec, @path = util_gem "freebird", "1.0.1" do |spec|
+ spec.metadata['allowed_push_host'] = "https://privategemserver.com"
+ end
+
+ @api_key = "PRIVKEY"
+
+ keys = {
+ :rubygems_api_key => 'KEY',
+ @host => @api_key
+ }
+
+ FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path
+ open Gem.configuration.credentials_path, 'w' do |f|
+ f.write keys.to_yaml
+ end
+ Gem.configuration.load_api_keys
+
+ FileUtils.rm Gem.configuration.credentials_path
+
+ response = 'ERROR: "https://somebodyelse.com" is not allowed by the gemspec, which only allows "https://privategemserver.com"'
+
+ assert_raises Gem::MockGemUi::TermError do
+ send_battery
+ end
+
+ assert_match response, @ui.error
+ end
+
+ def test_raises_error_with_no_arguments
+ def @cmd.sign_in(*); end
+ assert_raises Gem::CommandLineError do
+ @cmd.execute
+ end
+ end
+
+ def test_sending_gem_denied
+ response = "You don't have permission to push to this gem"
+ @fetcher.data["#{@host}/api/v1/gems"] = [response, 403, 'Forbidden']
+ @cmd.instance_variable_set :@host, @host
+
+ assert_raises Gem::MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.send_gem(@path)
+ end
+ end
+
+ assert_match response, @ui.output
+ end
+
+ def test_sending_gem_key
+ @response = "Successfully registered gem: freewill (1.0.0)"
+ @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, "OK"]
+ File.open Gem.configuration.credentials_path, 'a' do |f|
+ f.write ':other: 701229f217cdf23b1344c7b4b54ca97'
+ end
+ Gem.configuration.load_api_keys
+
+ @cmd.handle_options %w(-k other)
+ @cmd.instance_variable_set :@host, @host
+ @cmd.send_gem(@path)
+
+ assert_equal Gem.configuration.api_keys[:other],
+ @fetcher.last_request["Authorization"]
+ end
+
+end
diff --git a/test/rubygems/test_gem_commands_query_command.rb b/test/rubygems/test_gem_commands_query_command.rb
new file mode 100644
index 0000000000..43fa82571d
--- /dev/null
+++ b/test/rubygems/test_gem_commands_query_command.rb
@@ -0,0 +1,668 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/query_command'
+
+class TestGemCommandsQueryCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::QueryCommand.new
+
+ @specs = spec_fetcher do |fetcher|
+ fetcher.spec 'a', 1
+ fetcher.spec 'a', 2
+ fetcher.spec 'a', '3.a'
+ end
+
+ @fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] = proc do
+ raise Gem::RemoteFetcher::FetchError
+ end
+ end
+
+ def test_execute
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
+
+ @cmd.handle_options %w[-r]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** REMOTE GEMS ***
+
+a (2)
+pl (1 i386-linux)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_platform
+ spec_fetcher do |fetcher|
+ fetcher.clear
+
+ fetcher.spec 'a', 1
+ fetcher.spec 'a', 1 do |s|
+ s.platform = 'x86-linux'
+ end
+
+ fetcher.spec 'a', 2 do |s|
+ s.platform = 'universal-darwin'
+ end
+ end
+
+ @cmd.handle_options %w[-r -a]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** REMOTE GEMS ***
+
+a (2 universal-darwin, 1 ruby x86-linux)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_all
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
+
+ @cmd.handle_options %w[-r --all]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** REMOTE GEMS ***
+
+a (2, 1)
+pl (1 i386-linux)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_all_prerelease
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
+
+ @cmd.handle_options %w[-r --all --prerelease]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** REMOTE GEMS ***
+
+a (3.a, 2, 1)
+pl (1 i386-linux)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_details
+ spec_fetcher do |fetcher|
+ fetcher.spec 'a', 2 do |s|
+ s.summary = 'This is a lot of text. ' * 4
+ s.authors = ['Abraham Lincoln', 'Hirohito']
+ s.homepage = 'http://a.example.com/'
+ end
+
+ fetcher.legacy_platform
+ end
+
+ @cmd.handle_options %w[-r -d]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** REMOTE GEMS ***
+
+a (2)
+ Authors: Abraham Lincoln, Hirohito
+ Homepage: http://a.example.com/
+
+ This is a lot of text. This is a lot of text. This is a lot of text.
+ This is a lot of text.
+
+pl (1)
+ Platform: i386-linux
+ Author: A User
+ Homepage: http://example.com
+
+ this is a summary
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_details_platform
+ spec_fetcher do |fetcher|
+ fetcher.clear
+
+ fetcher.spec 'a', 1 do |s|
+ s.platform = 'x86-linux'
+ end
+
+ fetcher.spec 'a', 2 do |s|
+ s.summary = 'This is a lot of text. ' * 4
+ s.authors = ['Abraham Lincoln', 'Hirohito']
+ s.homepage = 'http://a.example.com/'
+ s.platform = 'universal-darwin'
+ end
+
+ fetcher.legacy_platform
+ end
+
+ @cmd.handle_options %w[-r -d]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** REMOTE GEMS ***
+
+a (2, 1)
+ Platforms:
+ 1: x86-linux
+ 2: universal-darwin
+ Authors: Abraham Lincoln, Hirohito
+ Homepage: http://a.example.com/
+
+ This is a lot of text. This is a lot of text. This is a lot of text.
+ This is a lot of text.
+
+pl (1)
+ Platform: i386-linux
+ Author: A User
+ Homepage: http://example.com
+
+ this is a summary
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_installed
+ @cmd.handle_options %w[-n a --installed]
+
+ assert_raises Gem::MockGemUi::SystemExitException do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal "true\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_installed_inverse
+ @cmd.handle_options %w[-n a --no-installed]
+
+ e = assert_raises Gem::MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal "false\n", @ui.output
+ assert_equal '', @ui.error
+
+ assert_equal 1, e.exit_code
+ end
+
+ def test_execute_installed_inverse_not_installed
+ @cmd.handle_options %w[-n not_installed --no-installed]
+
+ assert_raises Gem::MockGemUi::SystemExitException do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal "true\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_installed_no_name
+ @cmd.handle_options %w[--installed]
+
+ e = assert_raises Gem::MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal '', @ui.output
+ assert_equal "ERROR: You must specify a gem name\n", @ui.error
+
+ assert_equal 4, e.exit_code
+ end
+
+ def test_execute_installed_not_installed
+ @cmd.handle_options %w[-n not_installed --installed]
+
+ e = assert_raises Gem::MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal "false\n", @ui.output
+ assert_equal '', @ui.error
+
+ assert_equal 1, e.exit_code
+ end
+
+ def test_execute_installed_version
+ @cmd.handle_options %w[-n a --installed --version 2]
+
+ assert_raises Gem::MockGemUi::SystemExitException do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal "true\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_installed_version_not_installed
+ @cmd.handle_options %w[-n c --installed --version 2]
+
+ e = assert_raises Gem::MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal "false\n", @ui.output
+ assert_equal '', @ui.error
+
+ assert_equal 1, e.exit_code
+ end
+
+ def test_execute_local
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
+
+ @cmd.options[:domain] = :local
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** LOCAL GEMS ***
+
+a (3.a, 2, 1)
+pl (1 i386-linux)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_local_notty
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
+
+ @cmd.handle_options %w[]
+
+ @ui.outs.tty = false
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+a (3.a, 2, 1)
+pl (1 i386-linux)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_local_quiet
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
+
+ @cmd.options[:domain] = :local
+ Gem.configuration.verbose = false
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+a (3.a, 2, 1)
+pl (1 i386-linux)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_no_versions
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
+
+ @cmd.handle_options %w[-r --no-versions]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** REMOTE GEMS ***
+
+a
+pl
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_notty
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
+
+ @cmd.handle_options %w[-r]
+
+ @ui.outs.tty = false
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+a (2)
+pl (1 i386-linux)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_prerelease
+ @cmd.handle_options %w[-r --prerelease]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** REMOTE GEMS ***
+
+a (3.a)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_prerelease_local
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
+
+ @cmd.handle_options %w[-l --prerelease]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** LOCAL GEMS ***
+
+a (3.a, 2, 1)
+pl (1 i386-linux)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal "WARNING: prereleases are always shown locally\n", @ui.error
+ end
+
+ def test_execute_remote
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
+
+ @cmd.options[:domain] = :remote
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** REMOTE GEMS ***
+
+a (2)
+pl (1 i386-linux)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_remote_notty
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
+
+ @cmd.handle_options %w[]
+
+ @ui.outs.tty = false
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+a (3.a, 2, 1)
+pl (1 i386-linux)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_remote_quiet
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
+
+ @cmd.options[:domain] = :remote
+ Gem.configuration.verbose = false
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+a (2)
+pl (1 i386-linux)
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_local_details
+ spec_fetcher do |fetcher|
+ fetcher.clear
+
+ fetcher.spec 'a', 1 do |s|
+ s.platform = 'x86-linux'
+ end
+
+ fetcher.spec 'a', 2 do |s|
+ s.summary = 'This is a lot of text. ' * 4
+ s.authors = ['Abraham Lincoln', 'Hirohito']
+ s.homepage = 'http://a.example.com/'
+ s.platform = 'universal-darwin'
+ end
+
+ fetcher.legacy_platform
+ end
+
+ @cmd.handle_options %w[-l -d]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ str = @ui.output
+
+ str.gsub!(/\(\d\): [^\n]*/, "-")
+ str.gsub!(/at: [^\n]*/, "at: -")
+
+ expected = <<-EOF
+
+*** LOCAL GEMS ***
+
+a (2, 1)
+ Platforms:
+ 1: x86-linux
+ 2: universal-darwin
+ Authors: Abraham Lincoln, Hirohito
+ Homepage: http://a.example.com/
+ Installed at -
+ -
+
+ This is a lot of text. This is a lot of text. This is a lot of text.
+ This is a lot of text.
+
+pl (1)
+ Platform: i386-linux
+ Author: A User
+ Homepage: http://example.com
+ Installed at: -
+
+ this is a summary
+ EOF
+
+ assert_equal expected, @ui.output
+ end
+
+ def test_execute_default_details
+ spec_fetcher do |fetcher|
+ fetcher.clear
+
+ fetcher.spec 'a', 2
+ end
+
+ a1 = new_default_spec 'a', 1
+ install_default_specs a1
+
+ @cmd.handle_options %w[-l -d]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+
+*** LOCAL GEMS ***
+
+a (2, 1)
+ Author: A User
+ Homepage: http://example.com
+ Installed at (2): #{@gemhome}
+ (1, default): #{a1.base_dir}
+
+ this is a summary
+ EOF
+
+ assert_equal expected, @ui.output
+ end
+
+ def test_make_entry
+ a_2_name = @specs['a-2'].original_name
+
+ @fetcher.data.delete \
+ "#{@gem_repo}quick/Marshal.#{Gem.marshal_version}/#{a_2_name}.gemspec.rz"
+
+ a2 = @specs['a-2']
+ entry_tuples = [
+ [Gem::NameTuple.new(a2.name, a2.version, a2.platform),
+ Gem.sources.first],
+ ]
+
+ platforms = { a2.version => [a2.platform] }
+
+ entry = @cmd.send :make_entry, entry_tuples, platforms
+
+ assert_equal 'a (2)', entry
+ end
+
+ # Test for multiple args handling!
+ def test_execute_multiple_args
+ spec_fetcher do |fetcher|
+ fetcher.legacy_platform
+ end
+
+ @cmd.handle_options %w[a pl]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r%^a %, @ui.output
+ assert_match %r%^pl %, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_show_gems
+ @cmd.options[:name] = //
+ @cmd.options[:domain] = :remote
+
+ use_ui @ui do
+ @cmd.send :show_gems, /a/i, false
+ end
+
+ assert_match %r%^a %, @ui.output
+ refute_match %r%^pl %, @ui.output
+ assert_empty @ui.error
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_commands_search_command.rb b/test/rubygems/test_gem_commands_search_command.rb
new file mode 100644
index 0000000000..fb8debc245
--- /dev/null
+++ b/test/rubygems/test_gem_commands_search_command.rb
@@ -0,0 +1,17 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/search_command'
+
+class TestGemCommandsSearchCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::SearchCommand.new
+ end
+
+ def test_initialize
+ assert_equal :remote, @cmd.defaults[:domain]
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_commands_server_command.rb b/test/rubygems/test_gem_commands_server_command.rb
new file mode 100644
index 0000000000..db27a4c932
--- /dev/null
+++ b/test/rubygems/test_gem_commands_server_command.rb
@@ -0,0 +1,59 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/server_command'
+
+class TestGemCommandsServerCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::ServerCommand.new
+ end
+
+ def test_handle_options
+ @cmd.send :handle_options, %w[-p 8808 --no-daemon]
+
+ assert_equal false, @cmd.options[:daemon]
+ assert_equal [], @cmd.options[:gemdir]
+ assert_equal 8808, @cmd.options[:port]
+
+ @cmd.send :handle_options, %w[-p 9999 -d /nonexistent --daemon]
+
+ assert_equal true, @cmd.options[:daemon]
+ assert_equal [File.expand_path('/nonexistent')], @cmd.options[:gemdir]
+ assert_equal 9999, @cmd.options[:port]
+ end
+
+ def test_handle_options_gemdir
+ @cmd.send :handle_options, %w[--dir a --dir b]
+
+ assert_equal [File.expand_path('a'), File.expand_path('b')],
+ @cmd.options[:gemdir]
+ end
+
+ def test_handle_options_port
+ @cmd.send :handle_options, %w[-p 0]
+ assert_equal 0, @cmd.options[:port]
+
+ @cmd.send :handle_options, %w[-p 65535]
+ assert_equal 65535, @cmd.options[:port]
+
+ @cmd.send :handle_options, %w[-p http]
+ assert_equal 80, @cmd.options[:port]
+
+ e = assert_raises OptionParser::InvalidArgument do
+ @cmd.send :handle_options, %w[-p nonexistent]
+ end
+
+ assert_equal 'invalid argument: -p nonexistent: no such named service',
+ e.message
+
+ e = assert_raises OptionParser::InvalidArgument do
+ @cmd.send :handle_options, %w[-p 65536]
+ end
+
+ assert_equal 'invalid argument: -p 65536: not a port number',
+ e.message
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_commands_setup_command.rb b/test/rubygems/test_gem_commands_setup_command.rb
new file mode 100644
index 0000000000..2fe3384954
--- /dev/null
+++ b/test/rubygems/test_gem_commands_setup_command.rb
@@ -0,0 +1,138 @@
+# coding: UTF-8
+
+require 'rubygems/test_case'
+require 'rubygems/commands/setup_command'
+
+class TestGemCommandsSetupCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @install_dir = File.join @tempdir, 'install'
+ @cmd = Gem::Commands::SetupCommand.new
+ @cmd.options[:prefix] = @install_dir
+
+ FileUtils.mkdir_p 'bin'
+ FileUtils.mkdir_p 'lib/rubygems/ssl_certs'
+
+ open 'bin/gem', 'w' do |io| io.puts '# gem' end
+ open 'lib/rubygems.rb', 'w' do |io| io.puts '# rubygems.rb' end
+ open 'lib/rubygems/test_case.rb', 'w' do |io| io.puts '# test_case.rb' end
+ open 'lib/rubygems/ssl_certs/foo.pem', 'w' do |io| io.puts 'PEM' end
+ end
+
+ def test_pem_files_in
+ assert_equal %w[rubygems/ssl_certs/foo.pem],
+ @cmd.pem_files_in('lib').sort
+ end
+
+ def test_rb_files_in
+ assert_equal %w[rubygems.rb rubygems/test_case.rb],
+ @cmd.rb_files_in('lib').sort
+ end
+
+ def test_install_lib
+ @cmd.extend FileUtils
+
+ Dir.mktmpdir 'lib' do |dir|
+ @cmd.install_lib dir
+
+ assert_path_exists File.join(dir, 'rubygems.rb')
+ assert_path_exists File.join(dir, 'rubygems/ssl_certs/foo.pem')
+ end
+ end
+
+ def test_remove_old_lib_files
+ lib = File.join @install_dir, 'lib'
+ lib_rubygems = File.join lib, 'rubygems'
+ lib_rubygems_defaults = File.join lib_rubygems, 'defaults'
+
+ securerandom_rb = File.join lib, 'securerandom.rb'
+
+ engine_defaults_rb = File.join lib_rubygems_defaults, 'jruby.rb'
+ os_defaults_rb = File.join lib_rubygems_defaults, 'operating_system.rb'
+
+ old_builder_rb = File.join lib_rubygems, 'builder.rb'
+ old_format_rb = File.join lib_rubygems, 'format.rb'
+
+ FileUtils.mkdir_p lib_rubygems_defaults
+
+ open securerandom_rb, 'w' do |io| io.puts '# securerandom.rb' end
+
+ open old_builder_rb, 'w' do |io| io.puts '# builder.rb' end
+ open old_format_rb, 'w' do |io| io.puts '# format.rb' end
+
+ open engine_defaults_rb, 'w' do |io| io.puts '# jruby.rb' end
+ open os_defaults_rb, 'w' do |io| io.puts '# operating_system.rb' end
+
+ @cmd.remove_old_lib_files lib
+
+ refute_path_exists old_builder_rb
+ refute_path_exists old_format_rb
+
+ assert_path_exists securerandom_rb
+ assert_path_exists engine_defaults_rb
+ assert_path_exists os_defaults_rb
+ end
+
+ def test_show_release_notes
+ @default_external = nil
+ capture_io do
+ @default_external, Encoding.default_external =
+ Encoding.default_external, Encoding::US_ASCII
+ end if Object.const_defined? :Encoding
+
+ @cmd.options[:previous_version] = Gem::Version.new '2.0.2'
+
+ open 'History.txt', 'w' do |io|
+ io.puts <<-History_txt
+# coding: UTF-8
+
+=== #{Gem::VERSION} / 2013-03-26
+
+* Bug fixes:
+ * Fixed release note display for LANG=C when installing rubygems
+ * π is tasty
+
+=== 2.0.2 / 2013-03-06
+
+* Bug fixes:
+ * Other bugs fixed
+
+=== 2.0.1 / 2013-03-05
+
+* Bug fixes:
+ * Yet more bugs fixed
+ History_txt
+ end
+
+ use_ui @ui do
+ @cmd.show_release_notes
+ end
+
+ expected = <<-EXPECTED
+=== #{Gem::VERSION} / 2013-03-26
+
+* Bug fixes:
+ * Fixed release note display for LANG=C when installing rubygems
+ * π is tasty
+
+=== 2.0.2 / 2013-03-06
+
+* Bug fixes:
+ * Other bugs fixed
+
+ EXPECTED
+
+ output = @ui.output
+ output.force_encoding Encoding::UTF_8 if Object.const_defined? :Encoding
+
+ assert_equal expected, @ui.output
+ ensure
+ capture_io do
+ Encoding.default_external = @default_external
+ end if @default_external
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_commands_sources_command.rb b/test/rubygems/test_gem_commands_sources_command.rb
new file mode 100644
index 0000000000..8ee0fd3cb7
--- /dev/null
+++ b/test/rubygems/test_gem_commands_sources_command.rb
@@ -0,0 +1,248 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/sources_command'
+
+class TestGemCommandsSourcesCommand < Gem::TestCase
+
+ def setup
+ super
+
+ spec_fetcher
+
+ @cmd = Gem::Commands::SourcesCommand.new
+
+ @new_repo = "http://beta-gems.example.com"
+ end
+
+ def test_initialize_proxy
+ assert @cmd.handles?(['--http-proxy', 'http://proxy.example.com'])
+ end
+
+ def test_execute
+ @cmd.handle_options []
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+*** CURRENT SOURCES ***
+
+#{@gem_repo}
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_add
+ spec_fetcher do |fetcher|
+ fetcher.spec 'a', 1
+ end
+
+ specs = Gem::Specification.map { |spec|
+ [spec.name, spec.version, spec.original_platform]
+ }
+
+ specs_dump_gz = StringIO.new
+ Zlib::GzipWriter.wrap specs_dump_gz do |io|
+ Marshal.dump specs, io
+ end
+
+ @fetcher.data["#{@new_repo}/specs.#{@marshal_version}.gz"] =
+ specs_dump_gz.string
+
+ @cmd.handle_options %W[--add #{@new_repo}]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal [@gem_repo, @new_repo], Gem.sources
+
+ expected = <<-EOF
+#{@new_repo} added to sources
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_add_nonexistent_source
+ uri = "http://beta-gems.example.com/specs.#{@marshal_version}.gz"
+ @fetcher.data[uri] = proc do
+ raise Gem::RemoteFetcher::FetchError.new('it died', uri)
+ end
+
+ @cmd.handle_options %w[--add http://beta-gems.example.com]
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+ end
+
+ expected = <<-EOF
+Error fetching http://beta-gems.example.com:
+\tit died (#{uri})
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_add_redundant_source
+ @cmd.handle_options %W[--add #{@gem_repo}]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal [@gem_repo], Gem.sources
+
+ expected = <<-EOF
+source #{@gem_repo} already present in the cache
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_add_http_rubygems_org
+ http_rubygems_org = 'http://rubygems.org'
+
+ spec_fetcher do |fetcher|
+ fetcher.spec 'a', 1
+ end
+
+ specs = Gem::Specification.map { |spec|
+ [spec.name, spec.version, spec.original_platform]
+ }
+
+ specs_dump_gz = StringIO.new
+ Zlib::GzipWriter.wrap specs_dump_gz do |io|
+ Marshal.dump specs, io
+ end
+
+ @fetcher.data["#{http_rubygems_org}/specs.#{@marshal_version}.gz"] =
+ specs_dump_gz.string
+
+ @cmd.handle_options %W[--add #{http_rubygems_org}]
+
+ ui = Gem::MockGemUi.new "n"
+
+ use_ui ui do
+ assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+ end
+
+ assert_equal [@gem_repo], Gem.sources
+
+ expected = <<-EXPECTED
+ EXPECTED
+
+ assert_equal expected, @ui.output
+ assert_empty @ui.error
+ end
+
+ def test_execute_add_bad_uri
+ @cmd.handle_options %w[--add beta-gems.example.com]
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+ end
+
+ assert_equal [@gem_repo], Gem.sources
+
+ expected = <<-EOF
+beta-gems.example.com is not a URI
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_clear_all
+ @cmd.handle_options %w[--clear-all]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+*** Removed specs cache ***
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+
+ dir = Gem.spec_cache_dir
+ refute File.exist?(dir), 'cache dir removed'
+ end
+
+ def test_execute_list
+ @cmd.handle_options %w[--list]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = <<-EOF
+*** CURRENT SOURCES ***
+
+#{@gem_repo}
+ EOF
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_remove
+ @cmd.handle_options %W[--remove #{@gem_repo}]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = "#{@gem_repo} removed from sources\n"
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_remove_no_network
+ @cmd.handle_options %W[--remove #{@gem_repo}]
+
+ @fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] = proc do
+ raise Gem::RemoteFetcher::FetchError
+ end
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ expected = "#{@gem_repo} removed from sources\n"
+
+ assert_equal expected, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_update
+ @cmd.handle_options %w[--update]
+
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 1
+ end
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "source cache successfully updated\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_commands_specification_command.rb b/test/rubygems/test_gem_commands_specification_command.rb
new file mode 100644
index 0000000000..80564f9dce
--- /dev/null
+++ b/test/rubygems/test_gem_commands_specification_command.rb
@@ -0,0 +1,250 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/specification_command'
+
+class TestGemCommandsSpecificationCommand < Gem::TestCase
+
+ def setup
+ super
+
+ @cmd = Gem::Commands::SpecificationCommand.new
+ end
+
+ def test_execute
+ foo = util_spec 'foo'
+
+ install_specs foo
+
+ @cmd.options[:args] = %w[foo]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|Gem::Specification|, @ui.output
+ assert_match %r|name: foo|, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_all
+ util_spec 'foo', '0.0.1'
+ util_spec 'foo', '0.0.2'
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:all] = true
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|Gem::Specification|, @ui.output
+ assert_match %r|name: foo|, @ui.output
+ assert_match %r|version: 0.0.1|, @ui.output
+ assert_match %r|version: 0.0.2|, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_all_conflicts_with_version
+ util_spec 'foo', '0.0.1'
+ util_spec 'foo', '0.0.2'
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:all] = true
+ @cmd.options[:version] = "1"
+
+ assert_raises Gem::MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal '', @ui.output
+ assert_equal "ERROR: Specify --all or -v, not both\n", @ui.error
+ end
+
+ def test_execute_bad_name
+ @cmd.options[:args] = %w[foo]
+
+ assert_raises Gem::MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal '', @ui.output
+ assert_equal "ERROR: No gem matching 'foo (>= 0)' found\n", @ui.error
+ end
+
+ def test_execute_bad_name_with_version
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:version] = "1.3.2"
+
+ assert_raises Gem::MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_equal '', @ui.output
+ assert_equal "ERROR: No gem matching 'foo (= 1.3.2)' found\n", @ui.error
+ end
+
+ def test_execute_exact_match
+ util_spec 'foo'
+ util_spec 'foo_bar'
+
+ @cmd.options[:args] = %w[foo]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|Gem::Specification|, @ui.output
+ assert_match %r|name: foo|, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_field
+ foo = new_spec 'foo', '2'
+
+ install_specs foo
+
+ @cmd.options[:args] = %w[foo name]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "foo", YAML.load(@ui.output)
+ end
+
+ def test_execute_file
+ foo = util_spec 'foo' do |s|
+ s.files = %w[lib/code.rb]
+ end
+
+ util_build_gem foo
+
+ @cmd.options[:args] = [foo.cache_file]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|Gem::Specification|, @ui.output
+ assert_match %r|name: foo|, @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_marshal
+ foo = new_spec 'foo', '2'
+
+ install_specs foo
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:format] = :marshal
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal foo, Marshal.load(@ui.output)
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_remote
+ spec_fetcher do |fetcher|
+ fetcher.spec 'foo', 1
+ end
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:domain] = :remote
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|\A--- !ruby/object:Gem::Specification|, @ui.output
+ assert_match %r|name: foo|, @ui.output
+ end
+
+ def test_execute_remote_with_version
+ spec_fetcher do |fetcher|
+ fetcher.spec 'foo', "1"
+ fetcher.spec 'foo', "2"
+ end
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:version] = "1"
+ @cmd.options[:domain] = :remote
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ spec = Gem::Specification.from_yaml @ui.output
+
+ assert_equal Gem::Version.new("1"), spec.version
+ end
+
+ def test_execute_remote_without_prerelease
+ spec_fetcher do |fetcher|
+ fetcher.spec 'foo', '2.0.0'
+ fetcher.spec 'foo', '2.0.1.pre'
+ end
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:domain] = :remote
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|\A--- !ruby/object:Gem::Specification|, @ui.output
+ assert_match %r|name: foo|, @ui.output
+
+ spec = YAML.load @ui.output
+
+ assert_equal Gem::Version.new("2.0.0"), spec.version
+ end
+
+ def test_execute_remote_with_prerelease
+ spec_fetcher do |fetcher|
+ fetcher.spec 'foo', '2.0.0'
+ fetcher.spec 'foo', '2.0.1.pre'
+ end
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:domain] = :remote
+ @cmd.options[:prerelease] = true
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|\A--- !ruby/object:Gem::Specification|, @ui.output
+ assert_match %r|name: foo|, @ui.output
+
+ spec = YAML.load @ui.output
+
+ assert_equal Gem::Version.new("2.0.1.pre"), spec.version
+ end
+
+ def test_execute_ruby
+ foo = util_spec 'foo'
+
+ install_specs foo
+
+ @cmd.options[:args] = %w[foo]
+ @cmd.options[:format] = :ruby
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r|Gem::Specification.new|, @ui.output
+ assert_match %r|s.name = "foo"|, @ui.output
+ assert_equal '', @ui.error
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_commands_stale_command.rb b/test/rubygems/test_gem_commands_stale_command.rb
new file mode 100644
index 0000000000..ca80784749
--- /dev/null
+++ b/test/rubygems/test_gem_commands_stale_command.rb
@@ -0,0 +1,40 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/stale_command'
+
+class TestGemCommandsStaleCommand < Gem::TestCase
+
+ def setup
+ super
+ @cmd = Gem::Commands::StaleCommand.new
+ end
+
+ def test_execute_sorts
+ files = %w[lib/foo_bar.rb Rakefile]
+ foo_bar = util_spec 'foo_bar' do |gem|
+ gem.files = files
+ end
+
+ bar_baz = util_spec 'bar_baz' do |gem|
+ gem.files = files
+ end
+
+ files.each do |file|
+ filename = File.join(bar_baz.full_gem_path, file)
+ FileUtils.mkdir_p File.dirname filename
+ FileUtils.touch(filename, :mtime => Time.now)
+
+ filename = File.join(foo_bar.full_gem_path, file)
+ FileUtils.mkdir_p File.dirname filename
+ FileUtils.touch(filename, :mtime => Time.now - 86400)
+ end
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ lines = @ui.output.split("\n")
+ assert_equal("#{foo_bar.name}-#{foo_bar.version}", lines[0].split.first)
+ assert_equal("#{bar_baz.name}-#{bar_baz.version}", lines[1].split.first)
+ end
+
+end
diff --git a/test/rubygems/test_gem_commands_uninstall_command.rb b/test/rubygems/test_gem_commands_uninstall_command.rb
new file mode 100644
index 0000000000..4f045c5e3d
--- /dev/null
+++ b/test/rubygems/test_gem_commands_uninstall_command.rb
@@ -0,0 +1,281 @@
+require 'rubygems/installer_test_case'
+require 'rubygems/commands/uninstall_command'
+
+class TestGemCommandsUninstallCommand < Gem::InstallerTestCase
+
+ def setup
+ super
+
+ build_rake_in do
+ use_ui @ui do
+ @installer.install
+ end
+ end
+
+ @cmd = Gem::Commands::UninstallCommand.new
+ @executable = File.join(@gemhome, 'bin', 'executable')
+ end
+
+ def test_execute_all_named
+ util_make_gems
+
+ default = new_default_spec 'default', '1'
+ install_default_gems default
+
+ gemhome2 = "#{@gemhome}2"
+
+ a_4 = util_spec 'a', 4
+ install_gem a_4, :install_dir => gemhome2
+
+ Gem::Specification.dirs = [@gemhome, gemhome2]
+
+ assert_includes Gem::Specification.all_names, 'a-1'
+ assert_includes Gem::Specification.all_names, 'a-4'
+ assert_includes Gem::Specification.all_names, 'b-2'
+ assert_includes Gem::Specification.all_names, 'default-1'
+
+ @cmd.options[:all] = true
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal %w[a-4 a_evil-9 b-2 c-1.2 default-1 dep_x-1 pl-1-x86-linux x-1],
+ Gem::Specification.all_names.sort
+ end
+
+ def test_execute_dependency_order
+ c = quick_gem 'c' do |spec|
+ spec.add_dependency 'a'
+ end
+
+ util_build_gem c
+ installer = util_installer c, @gemhome
+ use_ui @ui do installer.install end
+
+ ui = Gem::MockGemUi.new
+
+ @cmd.options[:args] = %w[a c]
+ @cmd.options[:executables] = true
+
+ use_ui ui do
+ @cmd.execute
+ end
+
+ output = ui.output.split "\n"
+
+ assert_equal 'Successfully uninstalled c-2', output.shift
+ assert_equal "Removing executable", output.shift
+ assert_equal 'Successfully uninstalled a-2', output.shift
+ end
+
+ def test_execute_removes_executable
+ ui = Gem::MockGemUi.new
+
+ util_setup_gem ui
+
+ build_rake_in do
+ use_ui ui do
+ @installer.install
+ end
+ end
+
+ if win_platform? then
+ assert File.exist?(@executable)
+ else
+ assert File.symlink?(@executable)
+ end
+
+ # Evil hack to prevent false removal success
+ FileUtils.rm_f @executable
+
+ open @executable, "wb+" do |f| f.puts "binary" end
+
+ @cmd.options[:executables] = true
+ @cmd.options[:args] = [@spec.name]
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ output = @ui.output.split "\n"
+ assert_match(/Removing executable/, output.shift)
+ assert_match(/Successfully uninstalled/, output.shift)
+ assert_equal false, File.exist?(@executable)
+ assert_nil output.shift, "UI output should have contained only two lines"
+ end
+
+ def test_execute_removes_formatted_executable
+ FileUtils.rm_f @executable # Wish this didn't happen in #setup
+
+ Gem::Installer.exec_format = 'foo-%s-bar'
+
+ @installer.format_executable = true
+ @installer.install
+
+ formatted_executable = File.join @gemhome, 'bin', 'foo-executable-bar'
+ assert_equal true, File.exist?(formatted_executable)
+
+ @cmd.options[:executables] = true
+ @cmd.options[:format_executable] = true
+ @cmd.execute
+
+ assert_equal false, File.exist?(formatted_executable)
+ rescue
+ Gem::Installer.exec_format = nil
+ end
+
+ def test_execute_prerelease
+ @spec = util_spec "pre", "2.b"
+ @gem = File.join @tempdir, @spec.file_name
+ FileUtils.touch @gem
+
+ util_setup_gem
+
+ build_rake_in do
+ use_ui @ui do
+ @installer.install
+ end
+ end
+
+ @cmd.options[:executables] = true
+ @cmd.options[:args] = ["pre"]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ output = @ui.output
+ assert_match(/Successfully uninstalled/, output)
+ end
+
+ def test_execute_with_force_leaves_executable
+ ui = Gem::MockGemUi.new
+
+ util_make_gems
+ util_setup_gem ui
+
+ @cmd.options[:version] = '1'
+ @cmd.options[:force] = true
+ @cmd.options[:args] = ['a']
+
+ use_ui ui do
+ @cmd.execute
+ end
+
+ assert !Gem::Specification.all_names.include?('a')
+ assert File.exist? File.join(@gemhome, 'bin', 'executable')
+ end
+
+ def test_execute_with_force_uninstalls_all_versions
+ ui = Gem::MockGemUi.new "y\n"
+
+ util_make_gems
+ util_setup_gem ui
+
+ assert Gem::Specification.find_all_by_name('a').length > 1
+
+ @cmd.options[:force] = true
+ @cmd.options[:args] = ['a']
+
+ use_ui ui do
+ @cmd.execute
+ end
+
+ refute_includes Gem::Specification.all_names, 'a'
+ end
+
+ def test_execute_with_force_ignores_dependencies
+ ui = Gem::MockGemUi.new
+
+ util_make_gems
+ util_setup_gem ui
+
+ assert Gem::Specification.find_all_by_name('dep_x').length > 0
+ assert Gem::Specification.find_all_by_name('x').length > 0
+
+ @cmd.options[:force] = true
+ @cmd.options[:args] = ['x']
+
+ use_ui ui do
+ @cmd.execute
+ end
+
+ assert Gem::Specification.find_all_by_name('dep_x').length > 0
+ assert Gem::Specification.find_all_by_name('x').length == 0
+ end
+
+ def test_execute_all
+ util_make_gems
+
+ default = new_default_spec 'default', '1'
+ install_default_gems default
+
+ gemhome2 = "#{@gemhome}2"
+
+ a_4 = util_spec 'a', 4
+ install_gem a_4, :install_dir => gemhome2
+
+ Gem::Specification.dirs = [@gemhome, gemhome2]
+
+ assert_includes Gem::Specification.all_names, 'a-1'
+ assert_includes Gem::Specification.all_names, 'a-4'
+ assert_includes Gem::Specification.all_names, 'default-1'
+
+ @cmd.options[:all] = true
+ @cmd.options[:args] = []
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal %w[a-4 default-1], Gem::Specification.all_names.sort
+ end
+
+ def test_handle_options
+ @cmd.handle_options %w[]
+
+ assert_equal false, @cmd.options[:check_dev]
+ assert_equal nil, @cmd.options[:install_dir]
+ assert_equal true, @cmd.options[:user_install]
+ assert_equal Gem::Requirement.default, @cmd.options[:version]
+ assert_equal false, @cmd.options[:vendor]
+ end
+
+ def test_handle_options_vendor
+ use_ui @ui do
+ @cmd.handle_options %w[--vendor]
+ end
+
+ assert @cmd.options[:vendor]
+ assert_equal Gem.vendor_dir, @cmd.options[:install_dir]
+
+ assert_empty @ui.output
+
+ expected = <<-EXPECTED
+WARNING: Use your OS package manager to uninstall vendor gems
+ EXPECTED
+
+ assert_match expected, @ui.error
+ end
+
+ def test_handle_options_vendor_missing
+ orig_vendordir = RbConfig::CONFIG['vendordir']
+ RbConfig::CONFIG.delete 'vendordir'
+
+ e = assert_raises OptionParser::InvalidOption do
+ @cmd.handle_options %w[--vendor]
+ end
+
+ assert_equal 'invalid option: --vendor your platform is not supported',
+ e.message
+
+ refute @cmd.options[:vendor]
+ refute @cmd.options[:install_dir]
+
+ ensure
+ RbConfig::CONFIG['vendordir'] = orig_vendordir
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_commands_unpack_command.rb b/test/rubygems/test_gem_commands_unpack_command.rb
new file mode 100644
index 0000000000..59f6cc6c74
--- /dev/null
+++ b/test/rubygems/test_gem_commands_unpack_command.rb
@@ -0,0 +1,210 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/unpack_command'
+
+class TestGemCommandsUnpackCommand < Gem::TestCase
+
+ def setup
+ super
+
+ Dir.chdir @tempdir do
+ @cmd = Gem::Commands::UnpackCommand.new
+ end
+ end
+
+ def test_find_in_cache
+ util_make_gems
+
+ assert_equal(
+ @cmd.find_in_cache(File.basename @a1.cache_file),
+ @a1.cache_file,
+ 'found a-1.gem in the cache'
+ )
+ end
+
+ def test_get_path
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'a', 1
+ end
+
+ dep = Gem::Dependency.new 'a', 1
+ assert_equal(
+ @cmd.get_path(dep),
+ specs['a-1'].cache_file,
+ 'fetches a-1 and returns the cache path'
+ )
+
+ FileUtils.rm specs['a-1'].cache_file
+
+ assert_equal(
+ @cmd.get_path(dep),
+ specs['a-1'].cache_file,
+ 'when removed from cache, refetches a-1'
+ )
+ end
+
+ def test_execute
+ util_make_gems
+
+ @cmd.options[:args] = %w[a b]
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert File.exist?(File.join(@tempdir, 'a-3.a')), 'a should be unpacked'
+ assert File.exist?(File.join(@tempdir, 'b-2')), 'b should be unpacked'
+ end
+
+ def test_execute_gem_path
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', '3.a'
+ end
+
+ Gem.clear_paths
+
+ gemhome2 = File.join @tempdir, 'gemhome2'
+
+ Gem.paths = { "GEM_PATH" => [gemhome2, @gemhome], "GEM_HOME" => gemhome2 }
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert File.exist?(File.join(@tempdir, 'a-3.a'))
+ end
+
+ def test_execute_gem_path_missing
+ spec_fetcher
+
+ Gem.clear_paths
+
+ gemhome2 = File.join @tempdir, 'gemhome2'
+
+ Gem.paths = { "GEM_PATH" => [gemhome2, @gemhome], "GEM_HOME" => gemhome2 }
+
+ @cmd.options[:args] = %w[z]
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert_equal '', @ui.output
+ end
+
+ def test_execute_remote
+ spec_fetcher do |fetcher|
+ fetcher.spec 'a', 1
+ fetcher.gem 'a', 2
+
+ fetcher.clear
+ end
+
+ Gem.configuration.verbose = :really
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert File.exist?(File.join(@tempdir, 'a-2')), 'a should be unpacked'
+ end
+
+ def test_execute_spec
+ util_make_gems
+
+ @cmd.options[:args] = %w[a b]
+ @cmd.options[:spec] = true
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert File.exist?(File.join(@tempdir, 'a-3.a.gemspec'))
+ assert File.exist?(File.join(@tempdir, 'b-2.gemspec'))
+ end
+
+ def test_execute_sudo
+ skip 'Cannot perform this test on windows (chmod)' if win_platform?
+
+ util_make_gems
+
+ FileUtils.chmod 0555, @gemhome
+
+ @cmd.options[:args] = %w[b]
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert File.exist?(File.join(@tempdir, 'b-2')), 'b should be unpacked'
+ ensure
+ FileUtils.chmod 0755, @gemhome
+ end
+
+ def test_execute_with_target_option
+ util_make_gems
+
+ target = 'with_target'
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:target] = target
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert File.exist?(File.join(@tempdir, target, 'a-3.a'))
+ end
+
+ def test_execute_exact_match
+ foo_spec = util_spec 'foo'
+ foo_bar_spec = util_spec 'foo_bar'
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ Gem::Package.build foo_spec
+ Gem::Package.build foo_bar_spec
+ end
+ end
+
+ foo_path = File.join(@tempdir, "#{foo_spec.full_name}.gem")
+ foo_bar_path = File.join(@tempdir, "#{foo_bar_spec.full_name}.gem")
+ Gem::Installer.new(foo_path).install
+ Gem::Installer.new(foo_bar_path).install
+
+ @cmd.options[:args] = %w[foo]
+
+ use_ui @ui do
+ Dir.chdir @tempdir do
+ @cmd.execute
+ end
+ end
+
+ assert_path_exists File.join(@tempdir, foo_spec.full_name)
+ end
+
+ def test_handle_options_metadata
+ refute @cmd.options[:spec]
+
+ @cmd.send :handle_options, %w[--spec a]
+
+ assert @cmd.options[:spec]
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_commands_update_command.rb b/test/rubygems/test_gem_commands_update_command.rb
new file mode 100644
index 0000000000..2b3bb56855
--- /dev/null
+++ b/test/rubygems/test_gem_commands_update_command.rb
@@ -0,0 +1,530 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/update_command'
+
+begin
+ gem "rdoc"
+rescue Gem::LoadError
+ # ignore
+end
+
+class TestGemCommandsUpdateCommand < Gem::TestCase
+
+ def setup
+ super
+ common_installer_setup
+
+ @cmd = Gem::Commands::UpdateCommand.new
+
+ @cmd.options[:document] = []
+
+ @specs = spec_fetcher do |fetcher|
+ fetcher.gem 'a', 1
+ fetcher.gem 'a', 2
+ fetcher.gem 'a', '3.a'
+
+ fetcher.clear
+ end
+
+ @a1_path = @specs['a-1'].cache_file
+ @a2_path = @specs['a-1'].cache_file
+ @a3a_path = @specs['a-3.a'].cache_file
+ end
+
+ def test_execute
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+
+ fetcher.clear
+
+ fetcher.spec 'a', 1
+ end
+
+ @cmd.options[:args] = []
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating installed gems", out.shift
+ assert_equal "Updating a", out.shift
+ assert_equal "Gems updated: a", out.shift
+ assert_empty out
+ end
+
+ def test_execute_multiple
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ fetcher.gem 'ab', 2
+
+ fetcher.clear
+
+ fetcher.spec 'a', 1
+ fetcher.spec 'ab', 1
+ end
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating installed gems", out.shift
+ assert_equal "Updating a", out.shift
+ assert_equal "Gems updated: a", out.shift
+ assert_empty out
+ end
+
+ def test_execute_system
+ spec_fetcher do |fetcher|
+ fetcher.gem 'rubygems-update', 9 do |s| s.files = %w[setup.rb] end
+
+ fetcher.clear
+ end
+
+ @cmd.options[:args] = []
+ @cmd.options[:system] = true
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating rubygems-update", out.shift
+ assert_equal "Installing RubyGems 9", out.shift
+ assert_equal "RubyGems system software updated", out.shift
+
+ assert_empty out
+ end
+
+ def test_execute_system_at_latest
+ spec_fetcher do |fetcher|
+ fetcher.gem 'rubygems-update', Gem::VERSION do |s|
+ s.files = %w[setup.rb]
+ end
+
+ fetcher.clear
+ end
+
+ @cmd.options[:args] = []
+ @cmd.options[:system] = true
+
+ assert_raises Gem::MockGemUi::SystemExitException do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Latest version currently installed. Aborting.", out.shift
+ assert_empty out
+ end
+
+ def test_execute_system_multiple
+ spec_fetcher do |fetcher|
+ fetcher.gem 'rubygems-update', 8 do |s| s.files = %w[setup.rb] end
+ fetcher.gem 'rubygems-update', 9 do |s| s.files = %w[setup.rb] end
+
+ fetcher.clear
+ end
+
+ @cmd.options[:args] = []
+ @cmd.options[:system] = true
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating rubygems-update", out.shift
+ assert_equal "Installing RubyGems 9", out.shift
+ assert_equal "RubyGems system software updated", out.shift
+
+ assert_empty out
+ end
+
+ def test_execute_system_specific
+ spec_fetcher do |fetcher|
+ fetcher.gem 'rubygems-update', 8 do |s| s.files = %w[setup.rb] end
+ fetcher.gem 'rubygems-update', 9 do |s| s.files = %w[setup.rb] end
+
+ fetcher.clear
+ end
+
+ @cmd.options[:args] = []
+ @cmd.options[:system] = "8"
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating rubygems-update", out.shift
+ assert_equal "Installing RubyGems 8", out.shift
+ assert_equal "RubyGems system software updated", out.shift
+
+ assert_empty out
+ end
+
+ def test_execute_system_specifically_to_latest_version
+ spec_fetcher do |fetcher|
+ fetcher.gem 'rubygems-update', 8 do |s| s.files = %w[setup.rb] end
+ fetcher.gem 'rubygems-update', 9 do |s| s.files = %w[setup.rb] end
+
+ fetcher.clear
+ end
+
+ @cmd.options[:args] = []
+ @cmd.options[:system] = "9"
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating rubygems-update", out.shift
+ assert_equal "Installing RubyGems 9", out.shift
+ assert_equal "RubyGems system software updated", out.shift
+
+ assert_empty out
+ end
+
+ def test_execute_system_with_gems
+ @cmd.options[:args] = %w[gem]
+ @cmd.options[:system] = true
+
+ assert_raises Gem::MockGemUi::TermError do
+ use_ui @ui do
+ @cmd.execute
+ end
+ end
+
+ assert_empty @ui.output
+ assert_equal "ERROR: Gem names are not allowed with the --system option\n",
+ @ui.error
+ end
+
+ # before:
+ # a1 -> c1.2
+ # after:
+ # a2 -> b2 # new dependency
+ # a2 -> c2
+
+ def test_execute_dependencies
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2, 'b' => 2, 'c' => 2
+ fetcher.gem 'b', 2
+ fetcher.gem 'c', 2
+
+ fetcher.clear
+
+ fetcher.spec 'a', 1, 'c' => '1.2'
+ fetcher.spec 'c', '1.2'
+ end
+
+ Gem::Specification.reset
+
+ @cmd.options[:args] = []
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating installed gems", out.shift
+ assert_equal "Updating a", out.shift
+ assert_equal "Gems updated: a b c",
+ out.shift
+
+ assert_empty out
+ end
+
+ def test_execute_rdoc
+ skip if RUBY_VERSION <= "1.8.7"
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+
+ fetcher.clear
+
+ fetcher.spec 'a', 1
+ end
+
+ Gem.done_installing(&Gem::RDoc.method(:generation_hook))
+
+ @cmd.options[:document] = %w[rdoc ri]
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ wait_for_child_process_to_exit
+
+ a2 = @specs['a-2']
+
+ assert_path_exists File.join(a2.doc_dir, 'rdoc')
+ end
+
+ def test_execute_named
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+
+ fetcher.clear
+
+ fetcher.spec 'a', 1
+ end
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating installed gems", out.shift
+ assert_equal "Updating a", out.shift
+ assert_equal "Gems updated: a", out.shift
+
+ assert_empty out
+ end
+
+ def test_execute_named_some_up_to_date
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ fetcher.clear
+ fetcher.spec 'a', 1
+
+ fetcher.spec 'b', 2
+ end
+
+ @cmd.options[:args] = %w[a b]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating installed gems", out.shift
+ assert_equal "Updating a", out.shift
+ assert_equal "Gems updated: a", out.shift
+ assert_equal "Gems already up-to-date: b", out.shift
+
+ assert_empty out
+ end
+
+ def test_execute_named_up_to_date
+ spec_fetcher do |fetcher|
+ fetcher.spec 'a', 2
+ end
+
+ @cmd.options[:args] = %w[a]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating installed gems", out.shift
+ assert_equal "Nothing to update", out.shift
+
+ assert_empty out
+ end
+
+ def test_execute_named_up_to_date_prerelease
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', '3.a'
+
+ fetcher.clear
+
+ fetcher.gem 'a', 2
+ end
+
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:prerelease] = true
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating installed gems", out.shift
+ assert_equal "Updating a", out.shift
+ assert_equal "Gems updated: a", out.shift
+
+ assert_empty out
+ end
+
+ def test_execute_up_to_date
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+ end
+
+ @cmd.options[:args] = []
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ out = @ui.output.split "\n"
+ assert_equal "Updating installed gems", out.shift
+ assert_equal "Nothing to update", out.shift
+
+ assert_empty out
+ end
+
+ def test_execute_user_install
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', 2
+
+ fetcher.clear
+
+ fetcher.spec 'a', 1
+ end
+
+ @cmd.handle_options %w[--user-install]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ installer = @cmd.installer
+ user_install = installer.instance_variable_get :@user_install
+
+ assert user_install, 'user_install must be set on the installer'
+ end
+
+ def test_fetch_remote_gems
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'a', 1
+ fetcher.gem 'a', 2
+ end
+
+ expected = [
+ [Gem::NameTuple.new('a', v(2), Gem::Platform::RUBY),
+ Gem::Source.new(@gem_repo)],
+ ]
+
+ assert_equal expected, @cmd.fetch_remote_gems(specs['a-1'])
+ end
+
+ def test_fetch_remote_gems_error
+ Gem.sources.replace %w[http://nonexistent.example]
+
+ assert_raises Gem::RemoteFetcher::FetchError do
+ @cmd.fetch_remote_gems @specs['a-1']
+ end
+ end
+
+ def test_fetch_remote_gems_mismatch
+ platform = Gem::Platform.new 'x86-freebsd9'
+
+ specs = spec_fetcher do |fetcher|
+ fetcher.spec 'a', 1
+ fetcher.spec 'a', 2
+ fetcher.spec 'a', 2 do |s| s.platform = platform end
+ end
+
+ expected = [
+ [Gem::NameTuple.new('a', v(2), Gem::Platform::RUBY),
+ Gem::Source.new(@gem_repo)],
+ ]
+
+ assert_equal expected, @cmd.fetch_remote_gems(specs['a-1'])
+ end
+
+ def test_fetch_remote_gems_prerelease
+ specs = spec_fetcher do |fetcher|
+ fetcher.gem 'a', 1
+ fetcher.gem 'a', 2
+ fetcher.gem 'a', '3.a'
+ end
+
+ @cmd.options[:prerelease] = true
+
+ expected = [
+ [Gem::NameTuple.new('a', v(2), Gem::Platform::RUBY),
+ Gem::Source.new(@gem_repo)],
+ [Gem::NameTuple.new('a', v('3.a'), Gem::Platform::RUBY),
+ Gem::Source.new(@gem_repo)],
+ ]
+
+ assert_equal expected, @cmd.fetch_remote_gems(specs['a-1'])
+ end
+
+ def test_handle_options_system
+ @cmd.handle_options %w[--system]
+
+ expected = {
+ :args => [],
+ :document => %w[rdoc ri],
+ :force => false,
+ :system => true,
+ }
+
+ assert_equal expected, @cmd.options
+ end
+
+ def test_handle_options_system_non_version
+ assert_raises ArgumentError do
+ @cmd.handle_options %w[--system non-version]
+ end
+ end
+
+ def test_handle_options_system_specific
+ @cmd.handle_options %w[--system 1.3.7]
+
+ expected = {
+ :args => [],
+ :document => %w[rdoc ri],
+ :force => false,
+ :system => "1.3.7",
+ }
+
+ assert_equal expected, @cmd.options
+ end
+
+ def test_update_gem_unresolved_dependency
+ spec_fetcher do |fetcher|
+ fetcher.spec 'a', 1
+ fetcher.gem 'a', 2 do |s|
+ s.add_dependency 'b', '>= 2'
+ end
+
+ fetcher.spec 'b', 1
+ end
+
+ @cmd.update_gem 'a'
+
+ assert_empty @cmd.updated
+ end
+
+ def test_update_rubygems_arguments
+ @cmd.options[:system] = true
+
+ arguments = @cmd.update_rubygems_arguments
+
+ assert_equal '--prefix', arguments.shift
+ assert_equal Gem.prefix, arguments.shift
+ assert_equal '--no-rdoc', arguments.shift
+ assert_equal '--no-ri', arguments.shift
+ assert_equal '--previous-version', arguments.shift
+ assert_equal Gem::VERSION, arguments.shift
+ assert_empty arguments
+ end
+
+ def test_update_rubygems_arguments_1_8_x
+ @cmd.options[:system] = '1.8.26'
+
+ arguments = @cmd.update_rubygems_arguments
+
+ assert_equal '--prefix', arguments.shift
+ assert_equal Gem.prefix, arguments.shift
+ assert_equal '--no-rdoc', arguments.shift
+ assert_equal '--no-ri', arguments.shift
+ assert_empty arguments
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_commands_which_command.rb b/test/rubygems/test_gem_commands_which_command.rb
new file mode 100644
index 0000000000..7ce26c861a
--- /dev/null
+++ b/test/rubygems/test_gem_commands_which_command.rb
@@ -0,0 +1,85 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/which_command'
+
+class TestGemCommandsWhichCommand < Gem::TestCase
+
+ def setup
+ super
+ Gem::Specification.reset
+ @cmd = Gem::Commands::WhichCommand.new
+ end
+
+ def test_execute
+ util_foo_bar
+
+ @cmd.handle_options %w[foo_bar]
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output
+ assert_equal '', @ui.error
+ end
+
+ def test_execute_directory
+ @cmd.handle_options %w[directory]
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+ end
+
+ assert_equal '', @ui.output
+ assert_match %r%Can.t find ruby library file or shared library directory\n%,
+ @ui.error
+ end
+
+ def test_execute_one_missing
+ # TODO: this test fails in isolation
+
+ util_foo_bar
+
+ @cmd.handle_options %w[foo_bar missinglib]
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+ end
+
+ assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output
+ assert_match %r%Can.t find ruby library file or shared library missinglib\n%,
+ @ui.error
+ end
+
+ def test_execute_missing
+ @cmd.handle_options %w[missinglib]
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+ end
+
+ assert_equal '', @ui.output
+ assert_match %r%Can.t find ruby library file or shared library missinglib\n%,
+ @ui.error
+ end
+
+ def util_foo_bar
+ files = %w[lib/foo_bar.rb lib/directory/baz.rb Rakefile]
+ @foo_bar = util_spec 'foo_bar' do |gem|
+ gem.files = files
+ end
+
+ files.each do |file|
+ filename = File.join(@foo_bar.full_gem_path, file)
+ FileUtils.mkdir_p File.dirname filename
+ FileUtils.touch filename
+ end
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_commands_yank_command.rb b/test/rubygems/test_gem_commands_yank_command.rb
new file mode 100644
index 0000000000..469fd15bd9
--- /dev/null
+++ b/test/rubygems/test_gem_commands_yank_command.rb
@@ -0,0 +1,97 @@
+require 'rubygems/test_case'
+require 'rubygems/commands/yank_command'
+
+class TestGemCommandsYankCommand < Gem::TestCase
+ def setup
+ super
+
+ @cmd = Gem::Commands::YankCommand.new
+ @cmd.host = 'http://example'
+
+ @fetcher = Gem::RemoteFetcher.fetcher
+
+ Gem.configuration.rubygems_api_key = 'key'
+ Gem.configuration.api_keys[:KEY] = 'other'
+ end
+
+ def test_handle_options
+ @cmd.handle_options %w[a --version 1.0 --platform x86-darwin -k KEY]
+
+ assert_equal %w[a], @cmd.options[:args]
+ assert_equal :KEY, @cmd.options[:key]
+ assert_nil @cmd.options[:platform]
+ assert_equal req('= 1.0'), @cmd.options[:version]
+ end
+
+ def test_handle_options_missing_argument
+ %w[-v --version -p --platform].each do |option|
+ assert_raises OptionParser::MissingArgument do
+ @cmd.handle_options %W[a #{option}]
+ end
+ end
+ end
+
+ def test_execute
+ yank_uri = 'http://example/api/v1/gems/yank'
+ @fetcher.data[yank_uri] = ['Successfully yanked', 200, 'OK']
+
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:added_platform] = true
+ @cmd.options[:version] = req('= 1.0')
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r%Yanking gem from http://example%, @ui.output
+ assert_match %r%Successfully yanked%, @ui.output
+
+ platform = Gem.platforms[1]
+ body = @fetcher.last_request.body.split('&').sort
+ assert_equal %W[gem_name=a platform=#{platform} version=1.0], body
+
+ assert_equal 'key', @fetcher.last_request['Authorization']
+
+ assert_equal [yank_uri], @fetcher.paths
+ end
+
+ def test_execute_key
+ yank_uri = 'http://example/api/v1/gems/yank'
+ @fetcher.data[yank_uri] = ['Successfully yanked', 200, 'OK']
+
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:version] = req('= 1.0')
+ @cmd.options[:key] = :KEY
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ body = @fetcher.last_request.body.split('&').sort
+ assert_equal %w[gem_name=a version=1.0], body
+ assert_equal 'other', @fetcher.last_request['Authorization']
+ end
+
+ def test_execute_undo
+ unyank_uri = 'http://example/api/v1/gems/unyank'
+ @fetcher.data[unyank_uri] = ['Successfully unyanked', 200, 'OK']
+
+ @cmd.options[:args] = %w[a]
+ @cmd.options[:version] = req('= 1.0')
+ @cmd.options[:undo] = true
+
+ use_ui @ui do
+ @cmd.execute
+ end
+
+ assert_match %r%Unyanking gem from http://example%, @ui.output
+ assert_match %r%Successfully unyanked%, @ui.output
+
+ body = @fetcher.last_request.body.split('&').sort
+ assert_equal %w[gem_name=a version=1.0], body
+
+ assert_equal [unyank_uri], @fetcher.paths
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_config_file.rb b/test/rubygems/test_gem_config_file.rb
new file mode 100644
index 0000000000..5077f37359
--- /dev/null
+++ b/test/rubygems/test_gem_config_file.rb
@@ -0,0 +1,467 @@
+require 'rubygems/test_case'
+require 'rubygems/config_file'
+
+class TestGemConfigFile < Gem::TestCase
+
+ def setup
+ super
+
+ @temp_conf = File.join @tempdir, '.gemrc'
+
+ @cfg_args = %W[--config-file #{@temp_conf}]
+
+ @orig_SYSTEM_WIDE_CONFIG_FILE = Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE
+ Gem::ConfigFile.send :remove_const, :SYSTEM_WIDE_CONFIG_FILE
+ Gem::ConfigFile.send :const_set, :SYSTEM_WIDE_CONFIG_FILE,
+ File.join(@tempdir, 'system-gemrc')
+ Gem::ConfigFile::OPERATING_SYSTEM_DEFAULTS.clear
+ Gem::ConfigFile::PLATFORM_DEFAULTS.clear
+
+ @env_gemrc = ENV['GEMRC']
+ ENV['GEMRC'] = ''
+
+ util_config_file
+ end
+
+ def teardown
+ Gem::ConfigFile::OPERATING_SYSTEM_DEFAULTS.clear
+ Gem::ConfigFile::PLATFORM_DEFAULTS.clear
+ Gem::ConfigFile.send :remove_const, :SYSTEM_WIDE_CONFIG_FILE
+ Gem::ConfigFile.send :const_set, :SYSTEM_WIDE_CONFIG_FILE,
+ @orig_SYSTEM_WIDE_CONFIG_FILE
+
+ ENV['GEMRC'] = @env_gemrc
+
+ super
+ end
+
+ def test_initialize
+ assert_equal @temp_conf, @cfg.config_file_name
+
+ assert_equal false, @cfg.backtrace
+ assert_equal true, @cfg.update_sources
+ assert_equal Gem::ConfigFile::DEFAULT_BULK_THRESHOLD, @cfg.bulk_threshold
+ assert_equal true, @cfg.verbose
+ assert_equal [@gem_repo], Gem.sources
+
+ File.open @temp_conf, 'w' do |fp|
+ fp.puts ":backtrace: true"
+ fp.puts ":update_sources: false"
+ fp.puts ":bulk_threshold: 10"
+ fp.puts ":verbose: false"
+ fp.puts ":sources:"
+ fp.puts " - http://more-gems.example.com"
+ fp.puts "install: --wrappers"
+ fp.puts ":gempath:"
+ fp.puts "- /usr/ruby/1.8/lib/ruby/gems/1.8"
+ fp.puts "- /var/ruby/1.8/gem_home"
+ fp.puts ":ssl_verify_mode: 0"
+ fp.puts ":ssl_ca_cert: /etc/ssl/certs"
+ end
+
+ util_config_file
+
+ assert_equal true, @cfg.backtrace
+ assert_equal 10, @cfg.bulk_threshold
+ assert_equal false, @cfg.verbose
+ assert_equal false, @cfg.update_sources
+ assert_equal %w[http://more-gems.example.com], Gem.sources
+ assert_equal '--wrappers', @cfg[:install]
+ assert_equal(['/usr/ruby/1.8/lib/ruby/gems/1.8', '/var/ruby/1.8/gem_home'],
+ @cfg.path)
+ assert_equal 0, @cfg.ssl_verify_mode
+ assert_equal '/etc/ssl/certs', @cfg.ssl_ca_cert
+ end
+
+ def test_initialize_handle_arguments_config_file
+ util_config_file %W[--config-file #{@temp_conf}]
+
+ assert_equal @temp_conf, @cfg.config_file_name
+ end
+
+ def test_initialize_handle_arguments_config_file_with_other_params
+ util_config_file %W[--config-file #{@temp_conf} --backtrace]
+
+ assert_equal @temp_conf, @cfg.config_file_name
+ end
+
+ def test_initialize_handle_arguments_config_file_equals
+ util_config_file %W[--config-file=#{@temp_conf}]
+
+ assert_equal @temp_conf, @cfg.config_file_name
+ end
+
+ def test_initialize_operating_system_override
+ Gem::ConfigFile::OPERATING_SYSTEM_DEFAULTS[:bulk_threshold] = 1
+ Gem::ConfigFile::OPERATING_SYSTEM_DEFAULTS['install'] = '--no-env-shebang'
+
+ Gem::ConfigFile::PLATFORM_DEFAULTS[:bulk_threshold] = 2
+
+ util_config_file
+
+ assert_equal 2, @cfg.bulk_threshold
+ assert_equal '--no-env-shebang', @cfg[:install]
+ end
+
+ def test_initialize_platform_override
+ Gem::ConfigFile::PLATFORM_DEFAULTS[:bulk_threshold] = 2
+ Gem::ConfigFile::PLATFORM_DEFAULTS['install'] = '--no-env-shebang'
+
+ File.open Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE, 'w' do |fp|
+ fp.puts ":bulk_threshold: 3"
+ end
+
+ util_config_file
+
+ assert_equal 3, @cfg.bulk_threshold
+ assert_equal '--no-env-shebang', @cfg[:install]
+ end
+
+ def test_initialize_system_wide_override
+ File.open Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE, 'w' do |fp|
+ fp.puts ":backtrace: false"
+ fp.puts ":bulk_threshold: 2048"
+ end
+
+ File.open @temp_conf, 'w' do |fp|
+ fp.puts ":backtrace: true"
+ end
+
+ util_config_file
+
+ assert_equal 2048, @cfg.bulk_threshold
+ assert_equal true, @cfg.backtrace
+ end
+
+ def test_initialize_environment_variable_override
+ File.open Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE, 'w' do |fp|
+ fp.puts ':backtrace: false'
+ fp.puts ':verbose: false'
+ fp.puts ':bulk_threshold: 2048'
+ end
+
+ conf1 = File.join @tempdir, 'gemrc1'
+ File.open conf1, 'w' do |fp|
+ fp.puts ':backtrace: true'
+ end
+
+ conf2 = File.join @tempdir, 'gemrc2'
+ File.open conf2, 'w' do |fp|
+ fp.puts ':verbose: true'
+ end
+
+ conf3 = File.join @tempdir, 'gemrc3'
+ File.open conf3, 'w' do |fp|
+ fp.puts ':verbose: :loud'
+ end
+
+ ENV['GEMRC'] = conf1 + ':' + conf2 + ';' + conf3
+
+ util_config_file
+
+ assert_equal true, @cfg.backtrace
+ assert_equal :loud, @cfg.verbose
+ assert_equal 2048, @cfg.bulk_threshold
+ end
+
+ def test_api_keys
+ assert_nil @cfg.instance_variable_get :@api_keys
+
+ temp_cred = File.join Gem.user_home, '.gem', 'credentials'
+ FileUtils.mkdir File.dirname(temp_cred)
+ File.open temp_cred, 'w', 0600 do |fp|
+ fp.puts ':rubygems_api_key: 701229f217cdf23b1344c7b4b54ca97'
+ end
+
+ util_config_file
+
+ assert_equal({:rubygems => '701229f217cdf23b1344c7b4b54ca97'},
+ @cfg.api_keys)
+ end
+
+ def test_check_credentials_permissions
+ skip 'chmod not supported' if win_platform?
+
+ @cfg.rubygems_api_key = 'x'
+
+ File.chmod 0644, @cfg.credentials_path
+
+ use_ui @ui do
+ assert_raises Gem::MockGemUi::TermError do
+ @cfg.load_api_keys
+ end
+ end
+
+ assert_empty @ui.output
+
+ expected = <<-EXPECTED
+ERROR: Your gem push credentials file located at:
+
+\t#{@cfg.credentials_path}
+
+has file permissions of 0644 but 0600 is required.
+
+To fix this error run:
+
+\tchmod 0600 #{@cfg.credentials_path}
+
+You should reset your credentials at:
+
+\thttps://rubygems.org/profile/edit
+
+if you believe they were disclosed to a third party.
+ EXPECTED
+
+ assert_equal expected, @ui.error
+ end
+
+ def test_handle_arguments
+ args = %w[--backtrace --bunch --of --args here]
+
+ @cfg.handle_arguments args
+
+ assert_equal %w[--bunch --of --args here], @cfg.args
+ end
+
+ def test_handle_arguments_backtrace
+ assert_equal false, @cfg.backtrace
+
+ args = %w[--backtrace]
+
+ @cfg.handle_arguments args
+
+ assert_equal true, @cfg.backtrace
+ end
+
+ def test_handle_arguments_debug
+ assert_equal false, $DEBUG
+
+ args = %w[--debug]
+
+ _, err = capture_io do
+ @cfg.handle_arguments args
+ end
+
+ assert_match 'NOTE', err
+
+ assert_equal true, $DEBUG
+ ensure
+ $DEBUG = false
+ end
+
+ def test_handle_arguments_override
+ File.open @temp_conf, 'w' do |fp|
+ fp.puts ":backtrace: false"
+ end
+
+ util_config_file %W[--backtrace --config-file=#{@temp_conf}]
+
+ assert_equal true, @cfg.backtrace
+ end
+
+ def test_handle_arguments_traceback
+ assert_equal false, @cfg.backtrace
+
+ args = %w[--traceback]
+
+ @cfg.handle_arguments args
+
+ assert_equal true, @cfg.backtrace
+ end
+
+ def test_load_api_keys
+ temp_cred = File.join Gem.user_home, '.gem', 'credentials'
+ FileUtils.mkdir File.dirname(temp_cred)
+ File.open temp_cred, 'w', 0600 do |fp|
+ fp.puts ":rubygems_api_key: 701229f217cdf23b1344c7b4b54ca97"
+ fp.puts ":other: a5fdbb6ba150cbb83aad2bb2fede64c"
+ end
+
+ util_config_file
+
+ assert_equal({:rubygems => '701229f217cdf23b1344c7b4b54ca97',
+ :other => 'a5fdbb6ba150cbb83aad2bb2fede64c'}, @cfg.api_keys)
+ end
+
+ def test_load_api_keys_bad_permission
+ skip 'chmod not supported' if win_platform?
+
+ @cfg.rubygems_api_key = 'x'
+
+ File.chmod 0644, @cfg.credentials_path
+
+ assert_raises Gem::MockGemUi::TermError do
+ @cfg.load_api_keys
+ end
+ end
+
+ def test_really_verbose
+ assert_equal false, @cfg.really_verbose
+
+ @cfg.verbose = true
+
+ assert_equal false, @cfg.really_verbose
+
+ @cfg.verbose = 1
+
+ assert_equal true, @cfg.really_verbose
+ end
+
+ def test_rubygems_api_key_equals
+ @cfg.rubygems_api_key = 'x'
+
+ assert_equal 'x', @cfg.rubygems_api_key
+
+ expected = {
+ :rubygems_api_key => 'x',
+ }
+
+ assert_equal expected, YAML.load_file(@cfg.credentials_path)
+
+ unless win_platform? then
+ stat = File.stat @cfg.credentials_path
+
+ assert_equal 0600, stat.mode & 0600
+ end
+ end
+
+ def test_rubygems_api_key_equals_bad_permission
+ skip 'chmod not supported' if win_platform?
+
+ @cfg.rubygems_api_key = 'x'
+
+ File.chmod 0644, @cfg.credentials_path
+
+ assert_raises Gem::MockGemUi::TermError do
+ @cfg.rubygems_api_key = 'y'
+ end
+
+ expected = {
+ :rubygems_api_key => 'x',
+ }
+
+ assert_equal expected, YAML.load_file(@cfg.credentials_path)
+
+ stat = File.stat @cfg.credentials_path
+
+ assert_equal 0644, stat.mode & 0644
+ end
+
+ def test_write
+ @cfg.backtrace = true
+ @cfg.update_sources = false
+ @cfg.bulk_threshold = 10
+ @cfg.verbose = false
+ Gem.sources.replace %w[http://more-gems.example.com]
+ @cfg[:install] = '--wrappers'
+
+ @cfg.write
+
+ util_config_file
+
+ # These should not be written out to the config file.
+ assert_equal false, @cfg.backtrace, 'backtrace'
+ assert_equal Gem::ConfigFile::DEFAULT_BULK_THRESHOLD, @cfg.bulk_threshold,
+ 'bulk_threshold'
+ assert_equal true, @cfg.update_sources, 'update_sources'
+ assert_equal true, @cfg.verbose, 'verbose'
+
+ assert_equal '--wrappers', @cfg[:install], 'install'
+
+ # this should be written out to the config file.
+ assert_equal %w[http://more-gems.example.com], Gem.sources
+ end
+
+ def test_write_from_hash
+ File.open @temp_conf, 'w' do |fp|
+ fp.puts ":backtrace: true"
+ fp.puts ":bulk_threshold: 10"
+ fp.puts ":update_sources: false"
+ fp.puts ":verbose: false"
+ fp.puts ":sources:"
+ fp.puts " - http://more-gems.example.com"
+ fp.puts ":ssl_verify_mode: 2"
+ fp.puts ":ssl_ca_cert: /nonexistent/ca_cert.pem"
+ fp.puts ":ssl_client_cert: /nonexistent/client_cert.pem"
+ fp.puts "install: --wrappers"
+ end
+
+ util_config_file
+
+ @cfg.backtrace = :junk
+ @cfg.update_sources = :junk
+ @cfg.bulk_threshold = 20
+ @cfg.verbose = :junk
+ Gem.sources.replace %w[http://even-more-gems.example.com]
+ @cfg[:install] = '--wrappers --no-rdoc'
+
+ @cfg.write
+
+ util_config_file
+
+ # These should not be written out to the config file
+ assert_equal true, @cfg.backtrace, 'backtrace'
+ assert_equal 10, @cfg.bulk_threshold, 'bulk_threshold'
+ assert_equal false, @cfg.update_sources, 'update_sources'
+ assert_equal false, @cfg.verbose, 'verbose'
+
+ assert_equal 2, @cfg.ssl_verify_mode
+ assert_equal '/nonexistent/ca_cert.pem', @cfg.ssl_ca_cert
+ assert_equal '/nonexistent/client_cert.pem', @cfg.ssl_client_cert
+
+ assert_equal '--wrappers --no-rdoc', @cfg[:install], 'install'
+
+ assert_equal %w[http://even-more-gems.example.com], Gem.sources
+ end
+
+ def test_ignore_invalid_config_file
+ File.open @temp_conf, 'w' do |fp|
+ fp.puts "some-non-yaml-hash-string"
+ end
+
+ begin
+ verbose, $VERBOSE = $VERBOSE, nil
+
+ util_config_file
+ ensure
+ $VERBOSE = verbose
+ end
+ end
+
+ def test_load_ssl_verify_mode_from_config
+ File.open @temp_conf, 'w' do |fp|
+ fp.puts ":ssl_verify_mode: 1"
+ end
+ util_config_file
+ assert_equal(1, @cfg.ssl_verify_mode)
+ end
+
+ def test_load_ssl_ca_cert_from_config
+ File.open @temp_conf, 'w' do |fp|
+ fp.puts ":ssl_ca_cert: /home/me/certs"
+ end
+ util_config_file
+ assert_equal('/home/me/certs', @cfg.ssl_ca_cert)
+ end
+
+ def test_load_ssl_client_cert_from_config
+ File.open @temp_conf, 'w' do |fp|
+ fp.puts ":ssl_client_cert: /home/me/mine.pem"
+ end
+ util_config_file
+ assert_equal('/home/me/mine.pem', @cfg.ssl_client_cert)
+ end
+
+ def util_config_file(args = @cfg_args)
+ @cfg = Gem::ConfigFile.new args
+ end
+
+ def test_disable_default_gem_server
+ File.open @temp_conf, 'w' do |fp|
+ fp.puts ":disable_default_gem_server: true"
+ end
+ util_config_file
+ assert_equal(true, @cfg.disable_default_gem_server)
+ end
+end
+
diff --git a/test/rubygems/test_gem_dependency.rb b/test/rubygems/test_gem_dependency.rb
new file mode 100644
index 0000000000..c43ff0e03d
--- /dev/null
+++ b/test/rubygems/test_gem_dependency.rb
@@ -0,0 +1,357 @@
+require 'rubygems/test_case'
+require 'rubygems/dependency'
+
+class TestGemDependency < Gem::TestCase
+
+ def test_initialize
+ d = dep "pkg", "> 1.0"
+
+ assert_equal "pkg", d.name
+ assert_equal req("> 1.0"), d.requirement
+ end
+
+ def test_initialize_type_bad
+ e = assert_raises ArgumentError do
+ Gem::Dependency.new 'monkey' => '1.0'
+ end
+
+ assert_equal 'dependency name must be a String, was {"monkey"=>"1.0"}',
+ e.message
+ end
+
+ def test_initialize_double
+ d = dep "pkg", "> 1.0", "< 2.0"
+ assert_equal req("> 1.0", "< 2.0"), d.requirement
+ end
+
+ def test_initialize_empty
+ d = dep "pkg"
+ assert_equal req(">= 0"), d.requirement
+ end
+
+ def test_initialize_prerelease
+ d = dep 'd', '1.a'
+
+ assert d.prerelease?
+
+ d = dep 'd', '= 1.a'
+
+ assert d.prerelease?
+ end
+
+ def test_initialize_type
+ assert_equal :runtime, dep("pkg").type
+ assert_equal :development, dep("pkg", [], :development).type
+
+ assert_raises ArgumentError do
+ dep "pkg", :sometimes
+ end
+ end
+
+ def test_initialize_version
+ d = dep "pkg", v("2")
+ assert_equal req("= 2"), d.requirement
+ end
+
+ def test_equals2
+ o = dep "other"
+ d = dep "pkg", "> 1.0"
+ d1 = dep "pkg", "> 1.1"
+
+ assert_equal d, d.dup
+ assert_equal d.dup, d
+
+ refute_equal d, d1
+ refute_equal d1, d
+
+ refute_equal d, o
+ refute_equal o, d
+
+ refute_equal d, Object.new
+ refute_equal Object.new, d
+ end
+
+ def test_equals2_type
+ refute_equal dep("pkg", :runtime), dep("pkg", :development)
+ end
+
+ def test_equals_tilde
+ d = dep "a", "0"
+
+ assert_match d, d, "match self"
+ assert_match dep("a", ">= 0"), d, "match version exact"
+ assert_match dep("a", ">= 0"), dep("a", "1"), "match version"
+ refute_match dep("a"), Object.new
+
+ Gem::Deprecate.skip_during do
+ assert_match dep(/a/, ">= 0"), d, "match simple regexp"
+ assert_match dep(/a|b/, ">= 0"), d, "match scary regexp"
+ refute_match dep(/a/), dep("b")
+ end
+ end
+
+ def test_equals_tilde_escape
+ refute_match dep("a|b"), dep("a", "1")
+ Gem::Deprecate.skip_during do
+ assert_match dep(/a|b/), dep("a", "1")
+ end
+ end
+
+ def test_equals_tilde_object
+ o = Object.new
+ def o.name ; 'a' end
+ def o.version ; '0' end
+
+ assert_match dep("a"), o
+ end
+
+ def test_equals_tilde_spec
+ assert_match dep("a", ">= 0"), spec("a", "0")
+ assert_match dep("a", "1"), spec("a", "1")
+ Gem::Deprecate.skip_during do
+ assert_match dep(/a/, ">= 0"), spec("a", "0")
+ assert_match dep(/a|b/, ">= 0"), spec("b", "0")
+ refute_match dep(/a/, ">= 0"), spec("b", "0")
+ end
+ end
+
+ def test_hash
+ d = dep "pkg", "1.0"
+
+ assert_equal d.hash, d.dup.hash
+ assert_equal d.dup.hash, d.hash
+
+ refute_equal dep("pkg", "1.0").hash, dep("pkg", "2.0").hash, "requirement"
+ refute_equal dep("pkg", "1.0").hash, dep("abc", "1.0").hash, "name"
+ refute_equal dep("pkg", :development), dep("pkg", :runtime), "type"
+ end
+
+ def test_match_eh_name_tuple
+ a_dep = dep 'a'
+
+ a_tup = Gem::NameTuple.new 'a', 1
+ b_tup = Gem::NameTuple.new 'b', 2
+ c_tup = Gem::NameTuple.new 'c', '2.a'
+
+ assert a_dep.match? a_tup
+ refute a_dep.match? b_tup
+
+ b_dep = dep 'b', '>= 3'
+
+ refute b_dep.match? b_tup
+
+ c_dep = dep 'c', '>= 1'
+
+ refute c_dep.match? c_tup
+
+ c_dep = dep 'c'
+
+ refute c_dep.match? c_tup
+
+ c_dep = dep 'c', '2.a'
+
+ assert c_dep.match? c_tup
+ end
+
+ def test_match_eh_allow_prerelease
+ a_dep = dep 'a'
+
+ a_tup = Gem::NameTuple.new 'a', 1
+ b_tup = Gem::NameTuple.new 'b', 2
+ c_tup = Gem::NameTuple.new 'c', '2.a'
+
+ assert a_dep.match? a_tup, nil, true
+ refute a_dep.match? b_tup, nil, true
+
+ b_dep = dep 'b', '>= 3'
+
+ refute b_dep.match? b_tup, nil, true
+
+ c_dep = dep 'c', '>= 1'
+
+ assert c_dep.match? c_tup, nil, true
+
+ c_dep = dep 'c'
+
+ assert c_dep.match? c_tup, nil, true
+
+ c_dep = dep 'c', '2.a'
+
+ assert c_dep.match? c_tup, nil, true
+ end
+
+ def test_match_eh_specification
+ a_dep = dep 'a'
+
+ a_spec = util_spec 'a', 1
+ b_spec = util_spec 'b', 2
+ c_spec = util_spec 'c', '2.a'
+
+ assert a_dep.match? a_spec
+ refute a_dep.match? b_spec
+
+ b_dep = dep 'b', '>= 3'
+
+ refute b_dep.match? b_spec
+
+ c_dep = dep 'c', '>= 1'
+
+ refute c_dep.match? c_spec
+
+ c_dep = dep 'c'
+
+ refute c_dep.match? c_spec
+
+ c_dep = dep 'c', '2.a'
+
+ assert c_dep.match? c_spec
+ end
+
+ def test_matches_spec_eh
+ spec = util_spec 'b', 2
+
+ refute dep('a') .matches_spec?(spec), 'name mismatch'
+ assert dep('b') .matches_spec?(spec), 'name match'
+ refute dep('b', '= 1') .matches_spec?(spec), 'requirement mismatch'
+ assert dep('b', '~> 2').matches_spec?(spec), 'requirement match'
+ end
+
+ def test_matches_spec_eh_prerelease
+ spec = util_spec 'b', '2.1.a'
+
+ refute dep('a') .matches_spec?(spec), 'name mismatch'
+ assert dep('b') .matches_spec?(spec), 'name match'
+ refute dep('b', '= 1') .matches_spec?(spec), 'requirement mismatch'
+ assert dep('b', '~> 2') .matches_spec?(spec), 'requirement match'
+ assert dep('b', '~> 2.a').matches_spec?(spec), 'prerelease requirement'
+ end
+
+ def test_merge
+ a1 = dep 'a', '~> 1.0'
+ a2 = dep 'a', '= 1.0'
+
+ a3 = a1.merge a2
+
+ assert_equal dep('a', '~> 1.0', '= 1.0'), a3
+ end
+
+ def test_merge_default
+ a1 = dep 'a'
+ a2 = dep 'a', '1'
+
+ a3 = a1.merge a2
+
+ assert_equal dep('a', '1'), a3
+ end
+
+ def test_merge_name_mismatch
+ a = dep 'a'
+ b = dep 'b'
+
+ e = assert_raises ArgumentError do
+ a.merge b
+ end
+
+ assert_equal 'a (>= 0) and b (>= 0) have different names',
+ e.message
+ end
+
+ def test_merge_other_default
+ a1 = dep 'a', '1'
+ a2 = dep 'a'
+
+ a3 = a1.merge a2
+
+ assert_equal dep('a', '1'), a3
+ end
+
+ def test_prerelease_eh
+ d = dep "pkg", "= 1"
+
+ refute d.prerelease?
+
+ d.prerelease = true
+
+ assert d.prerelease?
+
+ d = dep "pkg", "= 1.a"
+
+ assert d.prerelease?
+
+ d.prerelease = false
+
+ assert d.prerelease?
+
+ d = dep "pkg", "> 1.a", "> 2"
+
+ assert d.prerelease?
+ end
+
+ def test_specific
+ refute dep('a', '> 1').specific?
+
+ assert dep('a', '= 1').specific?
+ end
+
+ def test_to_spec
+ util_spec 'a', '1'
+ a_2 = util_spec 'a', '2'
+
+ a_dep = dep 'a', '>= 0'
+
+ assert_equal a_2, a_dep.to_spec
+ end
+
+ def test_to_spec_prerelease
+ a_1 = util_spec 'a', '1'
+ a_1_1_a = util_spec 'a', '1.1.a'
+
+ a_dep = dep 'a', '>= 0'
+
+ assert_equal a_1, a_dep.to_spec
+
+ a_pre_dep = dep 'a', '>= 0'
+ a_pre_dep.prerelease = true
+
+ assert_equal a_1_1_a, a_pre_dep.to_spec
+ end
+
+ def test_to_specs_suggests_other_versions
+ a = util_spec 'a', '1.0', 'b' => '>= 1.0'
+
+ a_file = File.join a.gem_dir, 'lib', 'a_file.rb'
+
+ write_file a_file do |io|
+ io.puts '# a_file.rb'
+ end
+
+ dep = Gem::Dependency.new "a", "= 2.0"
+
+ e = assert_raises Gem::LoadError do
+ dep.to_specs
+ end
+
+ assert_match "Could not find 'a' (= 2.0) - did find: [a-1.0]", e.message
+ end
+
+ def test_to_specs_indicates_total_gem_set_size
+ a = util_spec 'a', '1.0', 'b' => '>= 1.0'
+
+ a_file = File.join a.gem_dir, 'lib', 'a_file.rb'
+
+ write_file a_file do |io|
+ io.puts '# a_file.rb'
+ end
+
+ dep = Gem::Dependency.new "b", "= 2.0"
+
+ e = assert_raises Gem::LoadError do
+ dep.to_specs
+ end
+
+ assert_match "Could not find 'b' (= 2.0) among 1 total gem(s)", e.message
+ end
+
+
+end
+
diff --git a/test/rubygems/test_gem_dependency_installer.rb b/test/rubygems/test_gem_dependency_installer.rb
new file mode 100644
index 0000000000..8a0470761e
--- /dev/null
+++ b/test/rubygems/test_gem_dependency_installer.rb
@@ -0,0 +1,1208 @@
+require 'rubygems/test_case'
+require 'rubygems/dependency_installer'
+require 'rubygems/security'
+
+class TestGemDependencyInstaller < Gem::TestCase
+
+ def setup
+ super
+ common_installer_setup
+
+ @gems_dir = File.join @tempdir, 'gems'
+ @cache_dir = File.join @gemhome, 'cache'
+
+ FileUtils.mkdir @gems_dir
+
+ Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new
+ end
+
+ def util_setup_gems
+ @a1, @a1_gem = util_gem 'a', '1' do |s| s.executables << 'a_bin' end
+ @a1_pre, @a1_pre_gem = util_gem 'a', '1.a'
+ @b1, @b1_gem = util_gem 'b', '1' do |s|
+ s.add_dependency 'a'
+ s.add_development_dependency 'aa'
+ end
+
+ @c1, @c1_gem = util_gem 'c', '1' do |s|
+ s.add_development_dependency 'b'
+ end
+
+ @d1, @d1_gem = util_gem 'd', '1' do |s|
+ s.add_development_dependency 'c'
+ end
+
+ util_clear_gems
+ util_reset_gems
+ end
+
+ def test_available_set_for_name
+ util_setup_gems
+ p1a, = util_gem 'a', '10.a'
+ util_setup_spec_fetcher p1a, @a1, @a1_pre
+
+ inst = Gem::DependencyInstaller.new
+
+ available = inst.available_set_for 'a', Gem::Requirement.default
+
+ assert_equal %w[a-1], available.set.map { |s| s.spec.full_name }
+ end
+
+ def test_available_set_for_name_prerelease
+ util_setup_gems
+ p1a, = util_gem 'a', '10.a'
+ util_setup_spec_fetcher p1a, @a1, @a1_pre
+
+ inst = Gem::DependencyInstaller.new :prerelease => true
+
+ available = inst.available_set_for 'a', Gem::Requirement.default
+
+ assert_equal %w[a-10.a],
+ available.sorted.map { |s| s.spec.full_name }
+ end
+
+ def test_available_set_for_dep
+ util_setup_gems
+ p1a, = util_gem 'a', '10.a'
+ util_setup_spec_fetcher p1a, @a1, @a1_pre
+
+ inst = Gem::DependencyInstaller.new
+
+ dep = Gem::Dependency.new 'a', Gem::Requirement.default
+
+ available = inst.available_set_for dep, Gem::Requirement.default
+
+ assert_equal %w[a-1], available.set.map { |s| s.spec.full_name }
+ end
+
+ def test_available_set_for_dep_prerelease
+ util_setup_gems
+ p1a, = util_gem 'a', '10.a'
+ util_setup_spec_fetcher p1a, @a1, @a1_pre
+
+ inst = Gem::DependencyInstaller.new :prerelease => true
+
+ dep = Gem::Dependency.new 'a', Gem::Requirement.default
+ dep.prerelease = true
+
+ available = inst.available_set_for dep, Gem::Requirement.default
+
+ assert_equal %w[a-10.a],
+ available.sorted.map { |s| s.spec.full_name }
+ end
+
+ def test_install
+ util_setup_gems
+
+ FileUtils.mv @a1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new
+ inst.install 'a'
+ end
+
+ assert_equal %w[a-1], Gem::Specification.map(&:full_name)
+ assert_equal [@a1], inst.installed_gems
+ end
+
+ def test_install_prerelease
+ util_setup_gems
+
+ p1a, gem = util_gem 'a', '10.a'
+
+ util_setup_spec_fetcher(p1a, @a1, @a1_pre)
+ util_clear_gems
+
+ p1a_data = Gem.read_binary(gem)
+
+ @fetcher.data['http://gems.example.com/gems/a-10.a.gem'] = p1a_data
+
+ dep = Gem::Dependency.new "a"
+ inst = Gem::DependencyInstaller.new :prerelease => true
+ inst.install dep
+
+ assert_equal %w[a-10.a], Gem::Specification.map(&:full_name)
+ assert_equal [p1a], inst.installed_gems
+ end
+
+ def test_install_prerelease_bug_990
+ spec_fetcher do |fetcher|
+ fetcher.gem 'a', '1.b' do |s|
+ s.add_dependency 'b', '~> 1.a'
+ end
+
+ fetcher.gem 'b', '1.b' do |s|
+ s.add_dependency 'c', '>= 1'
+ end
+
+ fetcher.gem 'c', '1.1.b'
+ end
+
+ dep = Gem::Dependency.new 'a'
+
+ inst = Gem::DependencyInstaller.new :prerelease => true
+ inst.install dep
+
+ assert_equal %w[a-1.b b-1.b c-1.1.b], Gem::Specification.map(&:full_name)
+ end
+
+ def test_install_when_only_prerelease
+ p1a, gem = util_gem 'p', '1.a'
+
+ util_setup_spec_fetcher(p1a)
+ util_clear_gems
+
+ p1a_data = Gem.read_binary(gem)
+
+ @fetcher.data['http://gems.example.com/gems/p-1.a.gem'] = p1a_data
+
+ dep = Gem::Dependency.new "p"
+ inst = Gem::DependencyInstaller.new
+ assert_raises Gem::UnsatisfiableDependencyError do
+ inst.install dep
+ end
+
+ assert_equal %w[], Gem::Specification.map(&:full_name)
+ assert_equal [], inst.installed_gems
+ end
+
+ def test_install_prerelease_skipped_when_normal_ver
+ util_setup_gems
+
+ util_setup_spec_fetcher(@a1, @a1_pre)
+ util_clear_gems
+
+ p1a_data = Gem.read_binary(@a1_gem)
+
+ @fetcher.data['http://gems.example.com/gems/a-1.gem'] = p1a_data
+
+ dep = Gem::Dependency.new "a"
+ inst = Gem::DependencyInstaller.new :prerelease => true
+ inst.install dep
+
+ assert_equal %w[a-1], Gem::Specification.map(&:full_name)
+ assert_equal [@a1], inst.installed_gems
+ end
+
+ def test_install_all_dependencies
+ util_setup_gems
+
+ _, e1_gem = util_gem 'e', '1' do |s|
+ s.add_dependency 'b'
+ end
+
+ util_clear_gems
+
+ FileUtils.mv @a1_gem, @tempdir
+ FileUtils.mv @b1_gem, @tempdir
+ FileUtils.mv e1_gem, @tempdir
+
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new :ignore_dependencies => true
+ inst.install 'b'
+ end
+
+ assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name },
+ 'sanity check'
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new
+ inst.install 'e'
+ end
+
+ assert_equal %w[a-1 e-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_cache_dir
+ util_setup_gems
+
+ dir = "dir"
+ Dir.mkdir dir
+ FileUtils.mv @a1_gem, dir
+ FileUtils.mv @b1_gem, dir
+ inst = nil
+
+ Dir.chdir dir do
+ inst = Gem::DependencyInstaller.new :cache_dir => @tempdir
+ inst.install 'b'
+ end
+
+ assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name }
+
+ assert File.exist? File.join(@gemhome, "cache", @a1.file_name)
+ assert File.exist? File.join(@gemhome, "cache", @b1.file_name)
+ end
+
+ def test_install_dependencies_satisfied
+ util_setup_gems
+
+ a2, a2_gem = util_gem 'a', '2'
+
+ FileUtils.rm_rf File.join(@gemhome, 'gems')
+
+ Gem::Specification.reset
+
+ FileUtils.mv @a1_gem, @tempdir
+ FileUtils.mv a2_gem, @tempdir # not in index
+ FileUtils.mv @b1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new
+ inst.install 'a', req("= 2")
+ end
+
+ assert_equal %w[a-2], inst.installed_gems.map { |s| s.full_name },
+ 'sanity check'
+
+ FileUtils.rm File.join(@tempdir, a2.file_name)
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new
+ inst.install 'b'
+ end
+
+ assert_equal %w[a-2 b-1], Gem::Specification.map(&:full_name)
+ assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ # This asserts that if a gem's dependency is satisfied by an
+ # already installed gem, RubyGems doesn't installed a newer
+ # version
+ def test_install_doesnt_upgrade_installed_depedencies
+ util_setup_gems
+
+ a2, a2_gem = util_gem 'a', '2'
+ a3, a3_gem = util_gem 'a', '3'
+
+ util_setup_spec_fetcher @a1, a3, @b1
+
+ FileUtils.rm_rf File.join(@gemhome, 'gems')
+
+ Gem::Specification.reset
+
+ FileUtils.mv @a1_gem, @tempdir
+ FileUtils.mv a2_gem, @tempdir # not in index
+ FileUtils.mv @b1_gem, @tempdir
+ FileUtils.mv a3_gem, @tempdir
+
+ Dir.chdir @tempdir do
+ Gem::DependencyInstaller.new.install 'a', req("= 2")
+ end
+
+ FileUtils.rm File.join(@tempdir, a2.file_name)
+
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new
+ inst.install 'b'
+ end
+
+ assert_equal %w[a-2 b-1], Gem::Specification.map(&:full_name)
+ assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_dependency
+ util_setup_gems
+
+ done_installing_ran = false
+ inst = nil
+
+ Gem.done_installing do |installer, specs|
+ done_installing_ran = true
+ refute_nil installer
+ assert_equal [@a1, @b1], specs
+ end
+
+ FileUtils.mv @a1_gem, @tempdir
+ FileUtils.mv @b1_gem, @tempdir
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new(:build_docs_in_background => false)
+ inst.install 'b'
+ end
+
+ assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name }
+
+ assert done_installing_ran, 'post installs hook was not run'
+ end
+
+ def test_install_dependency_development
+ util_setup_gems
+
+ @aa1, @aa1_gem = util_gem 'aa', '1'
+
+ util_reset_gems
+
+ FileUtils.mv @a1_gem, @tempdir
+ FileUtils.mv @aa1_gem, @tempdir
+ FileUtils.mv @b1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new(:development => true)
+ inst.install 'b'
+ end
+
+ assert_equal %w[a-1 aa-1 b-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_dependency_development_deep
+ util_setup_gems
+
+ @aa1, @aa1_gem = util_gem 'aa', '1'
+
+ util_reset_gems
+
+ FileUtils.mv @a1_gem, @tempdir
+ FileUtils.mv @aa1_gem, @tempdir
+ FileUtils.mv @b1_gem, @tempdir
+ FileUtils.mv @c1_gem, @tempdir
+ FileUtils.mv @d1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new(:development => true)
+ inst.install 'd'
+ end
+
+ assert_equal %w[a-1 aa-1 b-1 c-1 d-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_dependency_development_shallow
+ util_setup_gems
+
+ @aa1, @aa1_gem = util_gem 'aa', '1'
+
+ util_reset_gems
+
+ FileUtils.mv @a1_gem, @tempdir
+ FileUtils.mv @aa1_gem, @tempdir
+ FileUtils.mv @b1_gem, @tempdir
+ FileUtils.mv @c1_gem, @tempdir
+ FileUtils.mv @d1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new(:development => true, :dev_shallow => true)
+ inst.install 'd'
+ end
+
+ assert_equal %w[c-1 d-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_dependency_existing
+ util_setup_gems
+
+ Gem::Installer.new(@a1_gem).install
+ FileUtils.mv @a1_gem, @tempdir
+ FileUtils.mv @b1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new
+ inst.install 'b'
+ end
+
+ assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_dependency_existing_extension
+ extconf_rb = File.join @gemhome, 'gems', 'e-1', 'extconf.rb'
+ FileUtils.mkdir_p File.dirname extconf_rb
+
+ open extconf_rb, 'w' do |io|
+ io.write <<-EXTCONF_RB
+ require 'mkmf'
+ create_makefile 'e'
+ EXTCONF_RB
+ end
+
+ e1 = new_spec 'e', '1', nil, 'extconf.rb' do |s|
+ s.extensions << 'extconf.rb'
+ end
+ e1_gem = File.join @tempdir, 'gems', "#{e1.full_name}.gem"
+
+ _, f1_gem = util_gem 'f', '1', 'e' => nil
+
+ Gem::Installer.new(e1_gem).install
+ FileUtils.rm_r e1.extension_dir
+
+ FileUtils.mv e1_gem, @tempdir
+ FileUtils.mv f1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new
+ inst.install 'f'
+ end
+
+ assert_equal %w[f-1], inst.installed_gems.map { |s| s.full_name }
+
+ assert_path_exists e1.extension_dir
+ end
+
+ def test_install_dependency_old
+ _, e1_gem = util_gem 'e', '1'
+ _, f1_gem = util_gem 'f', '1', 'e' => nil
+ _, f2_gem = util_gem 'f', '2'
+
+ FileUtils.mv e1_gem, @tempdir
+ FileUtils.mv f1_gem, @tempdir
+ FileUtils.mv f2_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new
+ inst.install 'f'
+ end
+
+ assert_equal %w[f-2], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_local
+ util_setup_gems
+
+ FileUtils.mv @a1_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new :domain => :local
+ inst.install 'a-1.gem'
+ end
+
+ assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }
+ end
+
+ def test_install_local_prerelease
+ util_setup_gems
+
+ FileUtils.mv @a1_pre_gem, @tempdir
+ inst = nil
+
+ Dir.chdir @tempdir do
+ inst = Gem::DependencyInstaller.new :domain => :local
+ inst.install 'a-1.a.gem'
+ end
+
+ assert_equal %w[a-1.a], inst.installed_gems.map { |s| s.full_name }
+ end