diff options
author | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-16 18:49:26 +0900 |
---|---|---|
committer | Jari Vetoniemi <jari.vetoniemi@indooratlas.com> | 2020-03-30 00:39:06 +0900 |
commit | fcbf63e62c627deae76c1b8cb8c0876c536ed811 (patch) | |
tree | 64cb17de3f41a2b6fef2368028fbd00349946994 /jni/ruby/test/rubygems |
Fresh start
Diffstat (limited to 'jni/ruby/test/rubygems')
174 files changed, 33393 insertions, 0 deletions
diff --git a/jni/ruby/test/rubygems/alternate_cert.pem b/jni/ruby/test/rubygems/alternate_cert.pem new file mode 100644 index 0000000..a5a8291 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/alternate_cert_32.pem b/jni/ruby/test/rubygems/alternate_cert_32.pem new file mode 100644 index 0000000..6ef8999 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/alternate_key.pem b/jni/ruby/test/rubygems/alternate_key.pem new file mode 100644 index 0000000..14ca734 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/bad_rake.rb b/jni/ruby/test/rubygems/bad_rake.rb new file mode 100644 index 0000000..379a4c9 --- /dev/null +++ b/jni/ruby/test/rubygems/bad_rake.rb @@ -0,0 +1 @@ +exit 1 diff --git a/jni/ruby/test/rubygems/bogussources.rb b/jni/ruby/test/rubygems/bogussources.rb new file mode 100644 index 0000000..008e3a1 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/ca_cert.pem b/jni/ruby/test/rubygems/ca_cert.pem new file mode 100644 index 0000000..5207531 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/child_cert.pem b/jni/ruby/test/rubygems/child_cert.pem new file mode 100644 index 0000000..3079a9e --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/child_cert_32.pem b/jni/ruby/test/rubygems/child_cert_32.pem new file mode 100644 index 0000000..35ba720 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/child_key.pem b/jni/ruby/test/rubygems/child_key.pem new file mode 100644 index 0000000..c56d069 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/client.pem b/jni/ruby/test/rubygems/client.pem new file mode 100644 index 0000000..63a52c5 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/data/gem-private_key.pem b/jni/ruby/test/rubygems/data/gem-private_key.pem new file mode 100644 index 0000000..3e4be4c --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/data/gem-public_cert.pem b/jni/ruby/test/rubygems/data/gem-public_cert.pem new file mode 100644 index 0000000..885bf7f --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/data/null-type.gemspec.rz b/jni/ruby/test/rubygems/data/null-type.gemspec.rz Binary files differnew file mode 100644 index 0000000..bad9928 --- /dev/null +++ b/jni/ruby/test/rubygems/data/null-type.gemspec.rz diff --git a/jni/ruby/test/rubygems/encrypted_private_key.pem b/jni/ruby/test/rubygems/encrypted_private_key.pem new file mode 100644 index 0000000..2a9affd --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/expired_cert.pem b/jni/ruby/test/rubygems/expired_cert.pem new file mode 100644 index 0000000..3578be8 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/fake_certlib/openssl.rb b/jni/ruby/test/rubygems/fake_certlib/openssl.rb new file mode 100644 index 0000000..9de90c0 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/fix_openssl_warnings.rb b/jni/ruby/test/rubygems/fix_openssl_warnings.rb new file mode 100644 index 0000000..66d6cdf --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/foo/discover.rb b/jni/ruby/test/rubygems/foo/discover.rb new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/jni/ruby/test/rubygems/foo/discover.rb diff --git a/jni/ruby/test/rubygems/future_cert.pem b/jni/ruby/test/rubygems/future_cert.pem new file mode 100644 index 0000000..4f3d860 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/future_cert_32.pem b/jni/ruby/test/rubygems/future_cert_32.pem new file mode 100644 index 0000000..b7325f1 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/good_rake.rb b/jni/ruby/test/rubygems/good_rake.rb new file mode 100644 index 0000000..ca916d0 --- /dev/null +++ b/jni/ruby/test/rubygems/good_rake.rb @@ -0,0 +1 @@ +exit 0 diff --git a/jni/ruby/test/rubygems/grandchild_cert.pem b/jni/ruby/test/rubygems/grandchild_cert.pem new file mode 100644 index 0000000..5e5fe01 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/grandchild_cert_32.pem b/jni/ruby/test/rubygems/grandchild_cert_32.pem new file mode 100644 index 0000000..e4486a7 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/grandchild_key.pem b/jni/ruby/test/rubygems/grandchild_key.pem new file mode 100644 index 0000000..a9b9aef --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/invalid_client.pem b/jni/ruby/test/rubygems/invalid_client.pem new file mode 100644 index 0000000..e0d3951 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/invalid_issuer_cert.pem b/jni/ruby/test/rubygems/invalid_issuer_cert.pem new file mode 100644 index 0000000..31812aa --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/invalid_issuer_cert_32.pem b/jni/ruby/test/rubygems/invalid_issuer_cert_32.pem new file mode 100644 index 0000000..3a06ceb --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/invalid_key.pem b/jni/ruby/test/rubygems/invalid_key.pem new file mode 100644 index 0000000..74bedab --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/invalid_signer_cert.pem b/jni/ruby/test/rubygems/invalid_signer_cert.pem new file mode 100644 index 0000000..6d6c648 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/invalid_signer_cert_32.pem b/jni/ruby/test/rubygems/invalid_signer_cert_32.pem new file mode 100644 index 0000000..0f4ddcf --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/invalidchild_cert.pem b/jni/ruby/test/rubygems/invalidchild_cert.pem new file mode 100644 index 0000000..5a79c83 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/invalidchild_cert_32.pem b/jni/ruby/test/rubygems/invalidchild_cert_32.pem new file mode 100644 index 0000000..126b60a --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/invalidchild_key.pem b/jni/ruby/test/rubygems/invalidchild_key.pem new file mode 100644 index 0000000..9706c95 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/plugin/exception/rubygems_plugin.rb b/jni/ruby/test/rubygems/plugin/exception/rubygems_plugin.rb new file mode 100644 index 0000000..16c417e --- /dev/null +++ b/jni/ruby/test/rubygems/plugin/exception/rubygems_plugin.rb @@ -0,0 +1,2 @@ +TestGem::TEST_PLUGIN_EXCEPTION = :loaded +raise Exception.new('boom') diff --git a/jni/ruby/test/rubygems/plugin/load/rubygems_plugin.rb b/jni/ruby/test/rubygems/plugin/load/rubygems_plugin.rb new file mode 100644 index 0000000..c7c7277 --- /dev/null +++ b/jni/ruby/test/rubygems/plugin/load/rubygems_plugin.rb @@ -0,0 +1,3 @@ +class TestGem + TEST_PLUGIN_LOAD = :loaded +end diff --git a/jni/ruby/test/rubygems/plugin/standarderror/rubygems_plugin.rb b/jni/ruby/test/rubygems/plugin/standarderror/rubygems_plugin.rb new file mode 100644 index 0000000..4b577a6 --- /dev/null +++ b/jni/ruby/test/rubygems/plugin/standarderror/rubygems_plugin.rb @@ -0,0 +1,2 @@ +TestGem::TEST_PLUGIN_STANDARDERROR = :loaded +raise StandardError.new('boom') diff --git a/jni/ruby/test/rubygems/private_key.pem b/jni/ruby/test/rubygems/private_key.pem new file mode 100644 index 0000000..c6ed3fc --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/public_cert.pem b/jni/ruby/test/rubygems/public_cert.pem new file mode 100644 index 0000000..5642a6f --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/public_cert_32.pem b/jni/ruby/test/rubygems/public_cert_32.pem new file mode 100644 index 0000000..dcc8a62 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/public_key.pem b/jni/ruby/test/rubygems/public_key.pem new file mode 100644 index 0000000..7c29dcd --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/rubygems/commands/crash_command.rb b/jni/ruby/test/rubygems/rubygems/commands/crash_command.rb new file mode 100644 index 0000000..624be9f --- /dev/null +++ b/jni/ruby/test/rubygems/rubygems/commands/crash_command.rb @@ -0,0 +1,5 @@ +class Gem::Commands::CrashCommand < Gem::Command + + raise "crash" + +end diff --git a/jni/ruby/test/rubygems/rubygems_plugin.rb b/jni/ruby/test/rubygems/rubygems_plugin.rb new file mode 100644 index 0000000..6c08f97 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/sff/discover.rb b/jni/ruby/test/rubygems/sff/discover.rb new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/jni/ruby/test/rubygems/sff/discover.rb diff --git a/jni/ruby/test/rubygems/simple_gem.rb b/jni/ruby/test/rubygems/simple_gem.rb new file mode 100644 index 0000000..d7c0356 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/specifications/bar-0.0.2.gemspec b/jni/ruby/test/rubygems/specifications/bar-0.0.2.gemspec new file mode 100644 index 0000000..ceefa4e --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/specifications/foo-0.0.1.gemspec b/jni/ruby/test/rubygems/specifications/foo-0.0.1.gemspec Binary files differnew file mode 100644 index 0000000..7fbc564 --- /dev/null +++ b/jni/ruby/test/rubygems/specifications/foo-0.0.1.gemspec diff --git a/jni/ruby/test/rubygems/ssl_cert.pem b/jni/ruby/test/rubygems/ssl_cert.pem new file mode 100644 index 0000000..998ccc5 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/ssl_key.pem b/jni/ruby/test/rubygems/ssl_key.pem new file mode 100644 index 0000000..9ba2218 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_bundled_ca.rb b/jni/ruby/test/rubygems/test_bundled_ca.rb new file mode 100644 index 0000000..711cd1b --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_config.rb b/jni/ruby/test/rubygems/test_config.rb new file mode 100644 index 0000000..7829e90 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_deprecate.rb b/jni/ruby/test/rubygems/test_deprecate.rb new file mode 100644 index 0000000..ed4e9aa --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem.rb b/jni/ruby/test/rubygems/test_gem.rb new file mode 100644 index 0000000..47f57ab --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem.rb @@ -0,0 +1,1576 @@ +# 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_active + a1 = util_spec 'a', '1' do |s| + s.executables = ['exec'] + end + + util_spec 'a', '2' do |s| + s.executables = ['exec'] + end + + a1.activate + + assert_match 'a-1/bin/exec', Gem.bin_path('a', 'exec', '>= 0') + 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 --version 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_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/jni/ruby/test/rubygems/test_gem_available_set.rb b/jni/ruby/test/rubygems/test_gem_available_set.rb new file mode 100644 index 0000000..2b51544 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_command.rb b/jni/ruby/test/rubygems/test_gem_command.rb new file mode 100644 index 0000000..48cbc98 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_command_manager.rb b/jni/ruby/test/rubygems/test_gem_command_manager.rb new file mode 100644 index 0000000..f6433c5 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_build_command.rb b/jni/ruby/test/rubygems/test_gem_commands_build_command.rb new file mode 100644 index 0000000..5f870c0 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_cert_command.rb b/jni/ruby/test/rubygems/test_gem_commands_cert_command.rb new file mode 100644 index 0000000..4c1dcc2 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_check_command.rb b/jni/ruby/test/rubygems/test_gem_commands_check_command.rb new file mode 100644 index 0000000..67db6a3 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_cleanup_command.rb b/jni/ruby/test/rubygems/test_gem_commands_cleanup_command.rb new file mode 100644 index 0000000..fdaac54 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_contents_command.rb b/jni/ruby/test/rubygems/test_gem_commands_contents_command.rb new file mode 100644 index 0000000..ae8e49f --- /dev/null +++ b/jni/ruby/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 = [ + [RbConfig::CONFIG['bindir'], 'default_command'], + [RbConfig::CONFIG['rubylibdir'], 'default/gem.rb'], + [RbConfig::CONFIG['archdir'], 'default_gem.so'] + ].sort.map{|a|File.join a}.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/jni/ruby/test/rubygems/test_gem_commands_dependency_command.rb b/jni/ruby/test/rubygems/test_gem_commands_dependency_command.rb new file mode 100644 index 0000000..e22b240 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_environment_command.rb b/jni/ruby/test/rubygems/test_gem_commands_environment_command.rb new file mode 100644 index 0000000..81ff55d --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_fetch_command.rb b/jni/ruby/test/rubygems/test_gem_commands_fetch_command.rb new file mode 100644 index 0000000..c452e79 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_generate_index_command.rb b/jni/ruby/test/rubygems/test_gem_commands_generate_index_command.rb new file mode 100644 index 0000000..2e478d9 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_help_command.rb b/jni/ruby/test/rubygems/test_gem_commands_help_command.rb new file mode 100644 index 0000000..bed6095 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_install_command.rb b/jni/ruby/test/rubygems/test_gem_commands_install_command.rb new file mode 100644 index 0000000..f03285a --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_list_command.rb b/jni/ruby/test/rubygems/test_gem_commands_list_command.rb new file mode 100644 index 0000000..b03f166 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_lock_command.rb b/jni/ruby/test/rubygems/test_gem_commands_lock_command.rb new file mode 100644 index 0000000..8f30b7f --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_mirror.rb b/jni/ruby/test/rubygems/test_gem_commands_mirror.rb new file mode 100644 index 0000000..2f6fe52 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_open_command.rb b/jni/ruby/test/rubygems/test_gem_commands_open_command.rb new file mode 100644 index 0000000..25f22c8 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_outdated_command.rb b/jni/ruby/test/rubygems/test_gem_commands_outdated_command.rb new file mode 100644 index 0000000..d369c6b --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_owner_command.rb b/jni/ruby/test/rubygems/test_gem_commands_owner_command.rb new file mode 100644 index 0000000..5d7b661 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_pristine_command.rb b/jni/ruby/test/rubygems/test_gem_commands_pristine_command.rb new file mode 100644 index 0000000..554d503 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_commands_pristine_command.rb @@ -0,0 +1,462 @@ +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_missing_cache_gem_when_multi_repo + specs = spec_fetcher do |fetcher| + fetcher.gem 'a', 1 + fetcher.gem 'b', 1 + end + + FileUtils.rm_rf File.join(@gemhome, 'gems', 'a-1') + FileUtils.rm_rf File.join(@gemhome, 'gems', 'b-1') + + install_gem specs["a-1"] + FileUtils.rm File.join(@gemhome, 'cache', 'a-1.gem') + + Gem.clear_paths + gemhome2 = File.join(@tempdir, 'gemhome2') + Gem.paths = { "GEM_PATH" => [gemhome2, @gemhome], "GEM_HOME" => gemhome2 } + + install_gem specs["b-1"] + FileUtils.rm File.join(gemhome2, 'cache', 'b-1.gem') + + @cmd.options[:args] = %w[a b] + + use_ui @ui do + @cmd.execute + end + + out = @ui.output.split "\n" + + [ + "Restoring gems to pristine condition...", + "Cached gem for a-1 not found, attempting to fetch...", + "Restored a-1", + "Cached gem for b-1 not found, attempting to fetch...", + "Restored b-1", + ].each do |line| + assert_equal line, out.shift + end + + assert_empty out, out.inspect + assert_empty @ui.error + + assert_path_exists File.join(@gemhome, "cache", 'a-1.gem') + refute_path_exists File.join(gemhome2, "cache", 'a-2.gem') + assert_path_exists File.join(@gemhome, "gems", 'a-1') + refute_path_exists File.join(gemhome2, "gems", 'a-1') + + assert_path_exists File.join(gemhome2, "cache", 'b-1.gem') + refute_path_exists File.join(@gemhome, "cache", 'b-2.gem') + assert_path_exists File.join(gemhome2, "gems", 'b-1') + refute_path_exists File.join(@gemhome, "gems", 'b-1') + 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_unknown_gem_at_remote_source + util_spec 'a' + + @cmd.options[:args] = %w[a] + + use_ui @ui do + @cmd.execute + end + + assert_equal([ + "Restoring gems to pristine condition...", + "Cached gem for a-2 not found, attempting to fetch...", + "Skipped a-2, it was not found from cache and remote sources" + ], @ui.output.split("\n")) + + assert_empty @ui.error + 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_execute_bundled_gem_on_old_rubies + util_set_RUBY_VERSION '1.9.3', 551 + + util_spec 'bigdecimal', '1.1.0' do |s| + s.summary = "This bigdecimal is bundled with Ruby" + end + + @cmd.options[:args] = %w[bigdecimal] + + use_ui @ui do + @cmd.execute + end + + assert_equal([ + "Restoring gems to pristine condition...", + "Skipped bigdecimal-1.1.0, it is bundled with old Ruby" + ], @ui.output.split("\n")) + + assert_empty @ui.error + ensure + util_restore_RUBY_VERSION + 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/jni/ruby/test/rubygems/test_gem_commands_push_command.rb b/jni/ruby/test/rubygems/test_gem_commands_push_command.rb new file mode 100644 index 0000000..7d3d2ef --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_query_command.rb b/jni/ruby/test/rubygems/test_gem_commands_query_command.rb new file mode 100644 index 0000000..43fa825 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_search_command.rb b/jni/ruby/test/rubygems/test_gem_commands_search_command.rb new file mode 100644 index 0000000..fb8debc --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_server_command.rb b/jni/ruby/test/rubygems/test_gem_commands_server_command.rb new file mode 100644 index 0000000..db27a4c --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_setup_command.rb b/jni/ruby/test/rubygems/test_gem_commands_setup_command.rb new file mode 100644 index 0000000..974c157 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_commands_setup_command.rb @@ -0,0 +1,136 @@ +# 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 + if Object.const_defined? :Encoding + @default_external = @ui.outs.external_encoding + @ui.outs.set_encoding Encoding::US_ASCII + end + + @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, output + ensure + @ui.outs.set_encoding @default_external if @default_external + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_commands_sources_command.rb b/jni/ruby/test/rubygems/test_gem_commands_sources_command.rb new file mode 100644 index 0000000..8ee0fd3 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_specification_command.rb b/jni/ruby/test/rubygems/test_gem_commands_specification_command.rb new file mode 100644 index 0000000..80564f9 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_stale_command.rb b/jni/ruby/test/rubygems/test_gem_commands_stale_command.rb new file mode 100644 index 0000000..ca80784 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_uninstall_command.rb b/jni/ruby/test/rubygems/test_gem_commands_uninstall_command.rb new file mode 100644 index 0000000..4f045c5 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_unpack_command.rb b/jni/ruby/test/rubygems/test_gem_commands_unpack_command.rb new file mode 100644 index 0000000..59f6cc6 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_update_command.rb b/jni/ruby/test/rubygems/test_gem_commands_update_command.rb new file mode 100644 index 0000000..6a32706 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_commands_update_command.rb @@ -0,0 +1,543 @@ +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_prerelease + spec_fetcher do |fetcher| + fetcher.spec 'a', '1.a' + fetcher.gem 'a', '1.b' + end + + @cmd.update_gem 'a', Gem::Requirement.new('= 1.b') + + refute_empty @cmd.updated + + assert @cmd.installer.instance_variable_get :@prerelease + 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/jni/ruby/test/rubygems/test_gem_commands_which_command.rb b/jni/ruby/test/rubygems/test_gem_commands_which_command.rb new file mode 100644 index 0000000..7ce26c8 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_commands_yank_command.rb b/jni/ruby/test/rubygems/test_gem_commands_yank_command.rb new file mode 100644 index 0000000..469fd15 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_config_file.rb b/jni/ruby/test/rubygems/test_gem_config_file.rb new file mode 100644 index 0000000..5077f37 --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_dependency.rb b/jni/ruby/test/rubygems/test_gem_dependency.rb new file mode 100644 index 0000000..c43ff0e --- /dev/null +++ b/jni/ruby/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/jni/ruby/test/rubygems/test_gem_dependency_installer.rb b/jni/ruby/test/rubygems/test_gem_dependency_installer.rb new file mode 100644 index 0000000..8a04707 --- /dev/null +++ b/jni/ruby/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 + + def test_install_local_dependency + util_setup_gems + + FileUtils.mv @a1_gem, @tempdir + FileUtils.mv @b1_gem, @tempdir + + inst = nil + + Dir.chdir @tempdir do + inst = Gem::DependencyInstaller.new :domain => :local + inst.install 'b-1.gem' + end + + assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name } + end + + def test_install_local_dependency_installed + util_setup_gems + + FileUtils.mv @a1_gem, @tempdir + FileUtils.mv @b1_gem, @tempdir + + inst = nil + + Dir.chdir @tempdir do + Gem::Installer.new('a-1.gem').install + + inst = Gem::DependencyInstaller.new :domain => :local + inst.install 'b-1.gem' + end + + assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name } + end + + def test_install_local_subdir + util_setup_gems + + inst = nil + + Dir.chdir @tempdir do + inst = Gem::DependencyInstaller.new :domain => :local + inst.install 'gems/a-1.gem' + end + + assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } + end + + def test_install_minimal_deps + util_setup_gems + + _, e1_gem = util_gem 'e', '1' do |s| + s.add_dependency 'b' + end + + _, b2_gem = util_gem 'b', '2' do |s| + s.add_dependency 'a' + end + + util_clear_gems + + FileUtils.mv @a1_gem, @tempdir + FileUtils.mv @b1_gem, @tempdir + FileUtils.mv b2_gem, @tempdir + FileUtils.mv e1_gem, @tempdir + + inst = nil + + Dir.chdir @tempdir do + inst = Gem::DependencyInstaller.new :ignore_dependencies => true + inst.install 'b', req('= 1') + end + + assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name }, + 'sanity check' + + Dir.chdir @tempdir do + inst = Gem::DependencyInstaller.new :minimal_deps => true + inst.install 'e' + end + + assert_equal %w[a-1 e-1], inst.installed_gems.map { |s| s.full_name } + end + + def test_install_no_document + util_setup_gems + + done_installing_called = false + + Gem.done_installing do |dep_installer, specs| + done_installing_called = true + assert_empty dep_installer.document + end + + inst = Gem::DependencyInstaller.new :domain => :local, :document => [] + + inst.install @a1_gem + + assert done_installing_called + end + + def test_install_env_shebang + util_setup_gems + + FileUtils.mv @a1_gem, @tempdir + inst = nil + + Dir.chdir @tempdir do + inst = Gem::DependencyInstaller.new :env_shebang => true, :wrappers => true, :format_executable => false + inst.install 'a' + end + + env = "/\\S+/env" unless Gem.win_platform? + + assert_match %r|\A#!#{env} #{RbConfig::CONFIG['ruby_install_name']}\n|, + File.read(File.join(@gemhome, 'bin', 'a_bin')) + end + + def test_install_force + util_setup_gems + + FileUtils.mv @b1_gem, @tempdir + si = util_setup_spec_fetcher @b1 + @fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml + inst = nil + + Dir.chdir @tempdir do + inst = Gem::DependencyInstaller.new :force => true + inst.install 'b' + end + + assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name } + end + + def test_install_build_args + util_setup_gems + + FileUtils.mv @a1_gem, @tempdir + inst = nil + build_args = %w[--a --b="c"] + + Dir.chdir @tempdir do + inst = Gem::DependencyInstaller.new( + :build_args => build_args) + inst.install 'a' + end + + assert_equal build_args.join("\n"), File.read(inst.installed_gems.first.build_info_file).strip + end + + def test_install_ignore_dependencies + util_setup_gems + + FileUtils.mv @b1_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 } + end + + def test_install_install_dir + util_setup_gems + + FileUtils.mv @a1_gem, @tempdir + FileUtils.mv @b1_gem, @tempdir + + inst = Gem::Installer.new @a1.file_name + inst.install + + gemhome2 = File.join @tempdir, 'gemhome2' + Dir.mkdir gemhome2 + inst = nil + + Dir.chdir @tempdir do + inst = Gem::DependencyInstaller.new :install_dir => gemhome2 + inst.install 'b' + end + + assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name } + + assert File.exist?(File.join(gemhome2, 'specifications', @a1.spec_name)) + assert File.exist?(File.join(gemhome2, 'cache', @a1.file_name)) + end + + def test_install_domain_both + util_setup_gems + + a1_data = nil + File.open @a1_gem, 'rb' do |fp| + a1_data = fp.read + end + + @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data + + FileUtils.mv @b1_gem, @tempdir + inst = nil + + Dir.chdir @tempdir do + inst = Gem::DependencyInstaller.new :domain => :both + inst.install 'b' + end + + assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name } + a1, b1 = inst.installed_gems + + assert_equal a1.spec_file, a1.loaded_from + assert_equal b1.spec_file, b1.loaded_from + end + + def test_install_domain_both_no_network + util_setup_gems + + @fetcher.data["http://gems.example.com/gems/Marshal.#{@marshal_version}"] = + proc do + raise Gem::RemoteFetcher::FetchError + end + + FileUtils.mv @a1_gem, @tempdir + FileUtils.mv @b1_gem, @tempdir + inst = nil + + Dir.chdir @tempdir do + inst = Gem::DependencyInstaller.new :domain => :both + inst.install 'b' + end + + assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name } + end + + def test_install_domain_local + util_setup_gems + + FileUtils.mv @b1_gem, @tempdir + inst = nil + + Dir.chdir @tempdir do + e = assert_raises Gem::UnsatisfiableDependencyError do + inst = Gem::DependencyInstaller.new :domain => :local + inst.install 'b' + end + + expected = "Unable to resolve dependency: 'b (>= 0)' requires 'a (>= 0)'" + assert_equal expected, e.message + end + + assert_equal [], inst.installed_gems.map { |s| s.full_name } + end + + def test_install_domain_remote + util_setup_gems + + a1_data = nil + File.open @a1_gem, 'rb' do |fp| + a1_data = fp.read + end + + @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data + + inst = Gem::DependencyInstaller.new :domain => :remote + inst.install 'a' + + assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } + end + + def test_install_dual_repository + util_setup_gems + + FileUtils.mv @a1_gem, @tempdir + FileUtils.mv @b1_gem, @tempdir + inst = nil + + gemhome2 = "#{@gemhome}2" + + Dir.chdir @tempdir do + inst = Gem::DependencyInstaller.new :install_dir => gemhome2 + inst.install 'a' + end + + assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name }, + 'sanity check' + + ENV['GEM_HOME'] = @gemhome + ENV['GEM_PATH'] = [@gemhome, gemhome2].join File::PATH_SEPARATOR + Gem.clear_paths + + 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_reinstall + util_setup_gems + + Gem::Installer.new(@a1_gem).install + 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 %w[a-1], inst.installed_gems.map(&:full_name) + end + + def test_install_remote + util_setup_gems + + a1_data = nil + File.open @a1_gem, 'rb' do |fp| + a1_data = fp.read + end + + @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data + + inst = Gem::DependencyInstaller.new + + Dir.chdir @tempdir do + inst.install 'a' + end + + assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } + end + + def test_install_remote_dep + util_setup_gems + + a1_data = nil + File.open @a1_gem, 'rb' do |fp| + a1_data = fp.read + end + + @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data + + inst = Gem::DependencyInstaller.new + + Dir.chdir @tempdir do + dep = Gem::Dependency.new @a1.name, @a1.version + inst.install dep + end + + assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } + end + + def test_install_remote_platform_newer + util_setup_gems + + a2_o, a2_o_gem = util_gem 'a', '2' do |s| + s.platform = Gem::Platform.new %w[cpu other_platform 1] + end + + si = util_setup_spec_fetcher @a1, a2_o + + util_clear_gems + + @fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml + + a1_data = nil + a2_o_data = nil + + File.open @a1_gem, 'rb' do |fp| a1_data = fp.read end + File.open a2_o_gem, 'rb' do |fp| a2_o_data = fp.read end + + @fetcher.data["http://gems.example.com/gems/#{@a1.file_name}"] = + a1_data + @fetcher.data["http://gems.example.com/gems/#{a2_o.file_name}"] = + a2_o_data + + inst = Gem::DependencyInstaller.new :domain => :remote + inst.install 'a' + + assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } + end + + def test_install_platform_is_ignored_when_a_file_is_specified + _, a_gem = util_gem 'a', '1' do |s| + s.platform = Gem::Platform.new %w[cpu other_platform 1] + end + + inst = Gem::DependencyInstaller.new :domain => :local + inst.install a_gem + + assert_equal %w[a-1-cpu-other_platform-1], inst.installed_gems.map { |s| s.full_name } + end + + if defined? OpenSSL then + def test_install_security_policy + util_setup_gems + + data = File.open(@a1_gem, 'rb') { |f| f.read } + @fetcher.data['http://gems.example.com/gems/a-1.gem'] = data + + data = File.open(@b1_gem, 'rb') { |f| f.read } + @fetcher.data['http://gems.example.com/gems/b-1.gem'] = data + + policy = Gem::Security::HighSecurity + inst = Gem::DependencyInstaller.new :security_policy => policy + + e = assert_raises Gem::Security::Exception do + inst.install 'b' + end + + assert_equal 'unsigned gems are not allowed by the High Security policy', + e.message + + assert_equal %w[], inst.installed_gems.map { |s| s.full_name } + end + end + + # Wrappers don't work on mswin + unless win_platform? then + def test_install_no_wrappers + util_setup_gems + + @fetcher.data['http://gems.example.com/gems/a-1.gem'] = read_binary(@a1_gem) + + inst = Gem::DependencyInstaller.new :wrappers => false, :format_executable => false + inst.install 'a' + + refute_match(%r|This file was generated by RubyGems.|, + File.read(File.join(@gemhome, 'bin', 'a_bin'))) + end + end + + def test_install_version + util_setup_d + + data = File.open(@d2_gem, 'rb') { |f| f.read } + @fetcher.data['http://gems.example.com/gems/d-2.gem'] = data + + data = File.open(@d1_gem, 'rb') { |f| f.read } + @fetcher.data['http://gems.example.com/gems/d-1.gem'] = data + + inst = Gem::DependencyInstaller.new + + inst.install 'd', '= 1' + + assert_equal %w[d-1], inst.installed_gems.map { |s| s.full_name } + end + + def test_install_version_default + util_setup_d + + data = File.open(@d2_gem, 'rb') { |f| f.read } + @fetcher.data['http://gems.example.com/gems/d-2.gem'] = data + + data = File.open(@d1_gem, 'rb') { |f| f.read } + @fetcher.data['http://gems.example.com/gems/d-1.gem'] = data + + inst = Gem::DependencyInstaller.new + inst.install 'd' + + assert_equal %w[d-2], inst.installed_gems.map { |s| s.full_name } + end + + def test_find_gems_gems_with_sources + util_setup_gems + + inst = Gem::DependencyInstaller.new + dep = Gem::Dependency.new 'b', '>= 0' + + Gem::Specification.reset + + set = inst.find_gems_with_sources(dep) + + assert_kind_of Gem::AvailableSet, set + + s = set.set.first + + assert_equal @b1, s.spec + assert_equal Gem::Source.new(@gem_repo), s.source + end + + def test_find_spec_by_name_and_version_wildcard + util_gem 'a', 1 + FileUtils.mv 'gems/a-1.gem', @tempdir + + FileUtils.touch 'rdoc.gem' + + inst = Gem::DependencyInstaller.new + + available = inst.find_spec_by_name_and_version('*.gem') + + assert_equal %w[a-1], available.each_spec.map { |spec| spec.full_name } + end + + def test_find_spec_by_name_and_version_wildcard_bad_gem + FileUtils.touch 'rdoc.gem' + + inst = Gem::DependencyInstaller.new + + assert_raises Gem::Package::FormatError do + inst.find_spec_by_name_and_version '*.gem' + end + end + + def test_find_spec_by_name_and_version_bad_gem + FileUtils.touch 'rdoc.gem' + + inst = Gem::DependencyInstaller.new + + e = assert_raises Gem::Package::FormatError do + inst.find_spec_by_name_and_version 'rdoc.gem' + end + + full_path = File.join @tempdir, 'rdoc.gem' + assert_equal "package metadata is missing in #{full_path}", e.message + end + + def test_find_spec_by_name_and_version_directory + Dir.mkdir 'rdoc' + + inst = Gem::DependencyInstaller.new + + e = assert_raises Gem::SpecificGemNotFoundException do + inst.find_spec_by_name_and_version 'rdoc' + end + + assert_equal "Could not find a valid gem 'rdoc' (>= 0) " + + "locally or in a repository", + e.message + end + + def test_find_spec_by_name_and_version_file + FileUtils.touch 'rdoc' + + inst = Gem::DependencyInstaller.new + + e = assert_raises Gem::SpecificGemNotFoundException do + inst.find_spec_by_name_and_version 'rdoc' + end + + assert_equal "Could not find a valid gem 'rdoc' (>= 0) " + + "locally or in a repository", + e.message + end + + def test_find_gems_with_sources_local + util_setup_gems + + FileUtils.mv @a1_gem, @tempdir + inst = Gem::DependencyInstaller.new + dep = Gem::Dependency.new 'a', '>= 0' + set = nil + + Dir.chdir @tempdir do + set = inst.find_gems_with_sources dep + end + + gems = set.sorted + + assert_equal 2, gems.length + + remote, local = gems + + assert_equal 'a-1', local.spec.full_name, 'local spec' + assert_equal File.join(@tempdir, @a1.file_name), + local.source.download(local.spec), 'local path' + + assert_equal 'a-1', remote.spec.full_name, 'remote spec' + assert_equal Gem::Source.new(@gem_repo), remote.source, 'remote path' + + end + + def test_find_gems_with_sources_prerelease + util_setup_gems + + installer = Gem::DependencyInstaller.new + + dependency = Gem::Dependency.new('a', Gem::Requirement.default) + + releases = + installer.find_gems_with_sources(dependency).all_specs + + assert releases.any? { |s| s.name == 'a' and s.version.to_s == '1' } + refute releases.any? { |s| s.name == 'a' and s.version.to_s == '1.a' } + + dependency.prerelease = true + + prereleases = + installer.find_gems_with_sources(dependency).all_specs + + assert_equal [@a1_pre, @a1], prereleases + end + + def test_find_gems_with_sources_with_bad_source + Gem.sources.replace ["http://not-there.nothing"] + + installer = Gem::DependencyInstaller.new + + dep = Gem::Dependency.new('a') + + out = installer.find_gems_with_sources(dep) + + assert out.empty? + assert_kind_of Gem::SourceFetchProblem, installer.errors.first + end + + def test_resolve_dependencies + util_setup_gems + + FileUtils.mv @a1_gem, @tempdir + FileUtils.mv @b1_gem, @tempdir + + inst = Gem::DependencyInstaller.new + request_set = inst.resolve_dependencies 'b', req('>= 0') + + requests = request_set.sorted_requests.map { |req| req.full_name } + + assert_equal %w[a-1 b-1], requests + end + + def test_resolve_dependencies_ignore_dependencies + util_setup_gems + + FileUtils.mv @a1_gem, @tempdir + FileUtils.mv @b1_gem, @tempdir + + inst = Gem::DependencyInstaller.new :ignore_dependencies => true + request_set = inst.resolve_dependencies 'b', req('>= 0') + + requests = request_set.sorted_requests.map { |req| req.full_name } + + assert request_set.ignore_dependencies + + assert_equal %w[b-1], requests + end + + def test_resolve_dependencies_local + util_setup_gems + + @a2, @a2_gem = util_gem 'a', '2' + FileUtils.mv @a1_gem, @tempdir + FileUtils.mv @a2_gem, @tempdir + + inst = Gem::DependencyInstaller.new + request_set = inst.resolve_dependencies 'a-1.gem', req('>= 0') + + requests = request_set.sorted_requests.map { |req| req.full_name } + + assert_equal %w[a-1], requests + end + + def util_write_a1_bin + write_file File.join('gems', 'a-1', 'bin', 'a_bin') do |fp| + fp.puts "#!/usr/bin/ruby" + end + end + + def util_setup_c1_pre + @c1_pre, @c1_pre_gem = util_spec 'c', '1.a' do |s| + s.add_dependency 'a', '1.a' + s.add_dependency 'b', '1' + end + + util_reset_gems + end + + def util_setup_d + @d1, @d1_gem = util_gem 'd', '1' + @d2, @d2_gem = util_gem 'd', '2' + + util_reset_gems + end + + def util_setup_wxyz + @x1_m, @x1_m_gem = util_spec 'x', '1' do |s| + s.platform = Gem::Platform.new %w[cpu my_platform 1] + end + + @x1_o, @x1_o_gem = util_spec 'x', '1' do |s| + s.platform = Gem::Platform.new %w[cpu other_platform 1] + end + + @w1, @w1_gem = util_spec 'w', '1', 'x' => nil + + @y1, @y1_gem = util_spec 'y', '1' + @y1_1_p, @y1_1_p_gem = util_spec 'y', '1.1' do |s| + s.platform = Gem::Platform.new %w[cpu my_platform 1] + end + + @z1, @z1_gem = util_spec 'z', '1', 'y' => nil + + util_reset_gems + end + + def util_reset_gems + @a1 ||= nil + @b1 ||= nil + @a1_pre ||= nil + @c1_pre ||= nil + @d1 ||= nil + @d2 ||= nil + @w1 ||= nil + @x1_m ||= nil + @x1_o ||= nil + @y1 ||= nil + @y1_1_p ||= nil + @z1 ||= nil + + util_setup_spec_fetcher(*[@a1, @a1_pre, @b1, @c1_pre, + @d1, @d2, @x1_m, @x1_o, @w1, @y1, + @y1_1_p, @z1].compact) + + util_clear_gems + end +end diff --git a/jni/ruby/test/rubygems/test_gem_dependency_list.rb b/jni/ruby/test/rubygems/test_gem_dependency_list.rb new file mode 100644 index 0000000..d25359e --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_dependency_list.rb @@ -0,0 +1,259 @@ +require 'rubygems/test_case' +require 'rubygems/dependency_list' + +class TestGemDependencyList < Gem::TestCase + + def setup + super + + util_clear_gems + + @deplist = Gem::DependencyList.new + + # TODO: switch to new_spec + @a1 = util_spec 'a', '1' + @a2 = util_spec 'a', '2' + @a3 = util_spec 'a', '3' + + @b1 = util_spec 'b', '1' do |s| s.add_dependency 'a', '>= 1' end + @b2 = util_spec 'b', '2' do |s| s.add_dependency 'a', '>= 1' end + + @c1 = util_spec 'c', '1' do |s| s.add_dependency 'b', '>= 1' end + @c2 = util_spec 'c', '2' + + @d1 = util_spec 'd', '1' do |s| s.add_dependency 'c', '>= 1' end + end + + def test_active_count + assert_equal 0, @deplist.send(:active_count, [], {}) + assert_equal 1, @deplist.send(:active_count, [@a1], {}) + assert_equal 0, @deplist.send(:active_count, [@a1], + { @a1.full_name => true }) + end + + def test_add + assert_equal [], @deplist.dependency_order + + @deplist.add @a1, @b2 + + assert_equal [@b2, @a1], @deplist.dependency_order + end + + def test_dependency_order + @deplist.add @a1, @b1, @c1, @d1 + + order = @deplist.dependency_order + + assert_equal %w[d-1 c-1 b-1 a-1], order.map { |s| s.full_name } + end + + def test_dependency_order_circle + @a1.add_dependency 'c', '>= 1' + @deplist.add @a1, @b1, @c1 + + order = @deplist.dependency_order + + assert_equal %w[b-1 c-1 a-1], order.map { |s| s.full_name } + end + + def test_dependency_order_development + e1 = util_spec 'e', '1' + f1 = util_spec 'f', '1' + g1 = util_spec 'g', '1' + + @a1.add_dependency 'e' + @a1.add_dependency 'f' + @a1.add_dependency 'g' + g1.add_development_dependency 'a' + + deplist = Gem::DependencyList.new true + deplist.add @a1, e1, f1, g1 + + order = deplist.dependency_order + + assert_equal %w[g-1 a-1 f-1 e-1], order.map { |s| s.full_name }, + 'development on' + + deplist2 = Gem::DependencyList.new + deplist2.add @a1, e1, f1, g1 + + order = deplist2.dependency_order + + assert_equal %w[a-1 g-1 f-1 e-1], order.map { |s| s.full_name }, + 'development off' + end + + def test_dependency_order_diamond + util_diamond + e1 = util_spec 'e', '1' + @deplist.add e1 + @a1.add_dependency 'e', '>= 1' + + order = @deplist.dependency_order + + assert_equal %w[d-1 c-2 b-1 a-2 e-1], order.map { |s| s.full_name }, + 'deps of trimmed specs not included' + end + + def test_dependency_order_no_dependencies + @deplist.add @a1, @c2 + + order = @deplist.dependency_order + + assert_equal %w[c-2 a-1], order.map { |s| s.full_name } + end + + def test_find_name + @deplist.add @a1, @b2 + + assert_equal "a-1", @deplist.find_name("a-1").full_name + assert_equal "b-2", @deplist.find_name("b-2").full_name + + assert_nil @deplist.find_name("c-2") + end + + def test_ok_eh + util_clear_gems + + assert @deplist.ok?, 'no dependencies' + + @deplist.add @b2 + + refute @deplist.ok?, 'unsatisfied dependency' + + @deplist.add @a1 + + assert @deplist.ok?, 'satisfied dependency' + end + + def test_why_not_ok_eh + util_clear_gems + + assert_equal({}, @deplist.why_not_ok?) + + @deplist.add @b2 + + exp = { + "b" => [ + Gem::Dependency.new("a", ">= 1") + ] + } + + assert_equal exp, @deplist.why_not_ok? + end + + def test_why_not_ok_eh_old_dependency + a = new_spec 'a', '1', + 'b' => '~> 1.0' + + b0 = new_spec 'b', '1.0', + 'd' => '>= 0' + + b1 = new_spec 'b', '1.1' + + util_clear_gems + + @deplist.clear + + @deplist.add a, b0, b1 + + assert_equal({}, @deplist.why_not_ok?) + end + + def test_ok_eh_mismatch + a1 = util_spec 'a', '1' + a2 = util_spec 'a', '2' + + b = util_spec 'b', '1' do |s| s.add_dependency 'a', '= 1' end + c = util_spec 'c', '1' do |s| s.add_dependency 'a', '= 2' end + + d = util_spec 'd', '1' do |s| + s.add_dependency 'b' + s.add_dependency 'c' + end + + @deplist.add a1, a2, b, c, d + + assert @deplist.ok?, 'this will break on require' + end + + def test_ok_eh_redundant + @deplist.add @a1, @a3, @b2 + + @deplist.remove_by_name("a-1") + + assert @deplist.ok? + end + + def test_ok_to_remove_eh + @deplist.add @a1 + + assert @deplist.ok_to_remove?("a-1") + + @deplist.add @b2 + + refute @deplist.ok_to_remove?("a-1") + + @deplist.add @a2 + + assert @deplist.ok_to_remove?("a-1") + assert @deplist.ok_to_remove?("a-2") + assert @deplist.ok_to_remove?("b-2") + end + + def test_ok_to_remove_eh_after_sibling_removed + @deplist.add @a1, @a2, @b2 + + assert @deplist.ok_to_remove?("a-1") + assert @deplist.ok_to_remove?("a-2") + + @deplist.remove_by_name("a-1") + + refute @deplist.ok_to_remove?("a-2") + end + + def test_remove_by_name + util_clear_gems + + @deplist.add @a1, @b2 + + @deplist.remove_by_name "a-1" + + refute @deplist.ok? + end + + def test_tsort_each_node + util_diamond + + order = %w[a-1 a-2 b-1 c-2 d-1] + + @deplist.tsort_each_node do |node| + assert_equal order.shift, node.full_name + end + + assert_empty order + end + + def test_tsort_each_child + util_diamond + + order = %w[a-2] + + @deplist.tsort_each_child(@b1) do |node| + assert_equal order.shift, node.full_name + end + + assert_empty order + end + + # d1 -> b1 -> a1 + # d1 -> c2 -> a2 + def util_diamond + @c2.add_dependency 'a', '>= 2' + @d1.add_dependency 'b' + + @deplist.add @a1, @a2, @b1, @c2, @d1 + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_dependency_resolution_error.rb b/jni/ruby/test/rubygems/test_gem_dependency_resolution_error.rb new file mode 100644 index 0000000..0442082 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_dependency_resolution_error.rb @@ -0,0 +1,28 @@ +require 'rubygems/test_case' + +class TestGemDependencyResolutionError < Gem::TestCase + + def setup + super + + @DR = Gem::Resolver + + @spec = util_spec 'a', 2 + + @a1_req = @DR::DependencyRequest.new dep('a', '= 1'), nil + @a2_req = @DR::DependencyRequest.new dep('a', '= 2'), nil + + @activated = @DR::ActivationRequest.new @spec, @a2_req + + @conflict = @DR::Conflict.new @a1_req, @activated + + @error = Gem::DependencyResolutionError.new @conflict + end + + def test_message + assert_match %r%^conflicting dependencies a \(= 1\) and a \(= 2\)$%, + @error.message + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_doctor.rb b/jni/ruby/test/rubygems/test_gem_doctor.rb new file mode 100644 index 0000000..f4d4659 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_doctor.rb @@ -0,0 +1,168 @@ +require 'rubygems/test_case' +require 'rubygems/doctor' + +class TestGemDoctor < Gem::TestCase + + 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_doctor + a = gem 'a' + b = gem 'b' + c = gem 'c' + + Gem.use_paths @userhome, @gemhome + + FileUtils.rm b.spec_file + + open c.spec_file, 'w' do |io| + io.write 'this will raise an exception when evaluated.' + end + + assert_path_exists File.join(a.gem_dir, 'Rakefile') + assert_path_exists File.join(a.gem_dir, 'lib', 'a.rb') + + assert_path_exists b.gem_dir + refute_path_exists b.spec_file + + assert_path_exists c.gem_dir + assert_path_exists c.spec_file + + doctor = Gem::Doctor.new @gemhome + + capture_io do + use_ui @ui do + doctor.doctor + end + end + + assert_path_exists File.join(a.gem_dir, 'Rakefile') + assert_path_exists File.join(a.gem_dir, 'lib', 'a.rb') + + refute_path_exists b.gem_dir + refute_path_exists b.spec_file + + refute_path_exists c.gem_dir + refute_path_exists c.spec_file + + expected = <<-OUTPUT +Checking #{@gemhome} +Removed file specifications/c-2.gemspec +Removed directory gems/b-2 +Removed directory gems/c-2 + + OUTPUT + + assert_equal expected, @ui.output + + assert_equal Gem.dir, @userhome + assert_equal Gem.path, [@gemhome, @userhome] + end + + def test_doctor_dry_run + a = gem 'a' + b = gem 'b' + c = gem 'c' + + Gem.use_paths @userhome, @gemhome + + FileUtils.rm b.spec_file + + open c.spec_file, 'w' do |io| + io.write 'this will raise an exception when evaluated.' + end + + assert_path_exists File.join(a.gem_dir, 'Rakefile') + assert_path_exists File.join(a.gem_dir, 'lib', 'a.rb') + + assert_path_exists b.gem_dir + refute_path_exists b.spec_file + + assert_path_exists c.gem_dir + assert_path_exists c.spec_file + + doctor = Gem::Doctor.new @gemhome, true + + capture_io do + use_ui @ui do + doctor.doctor + end + end + + assert_path_exists File.join(a.gem_dir, 'Rakefile') + assert_path_exists File.join(a.gem_dir, 'lib', 'a.rb') + + assert_path_exists b.gem_dir + refute_path_exists b.spec_file + + assert_path_exists c.gem_dir + assert_path_exists c.spec_file + + expected = <<-OUTPUT +Checking #{@gemhome} +Extra file specifications/c-2.gemspec +Extra directory gems/b-2 +Extra directory gems/c-2 + + OUTPUT + + assert_equal expected, @ui.output + + assert_equal Gem.dir, @userhome + assert_equal Gem.path, [@gemhome, @userhome] + end + + def test_doctor_non_gem_home + other_dir = File.join @tempdir, 'other', 'dir' + + FileUtils.mkdir_p other_dir + + doctor = Gem::Doctor.new @tempdir + + capture_io do + use_ui @ui do + doctor.doctor + end + end + + assert_path_exists other_dir + + expected = <<-OUTPUT +Checking #{@tempdir} +This directory does not appear to be a RubyGems repository, skipping + + OUTPUT + + assert_equal expected, @ui.output + end + + def test_doctor_child_missing + doctor = Gem::Doctor.new @gemhome + + doctor.doctor_child 'missing', '' + + assert true # count + end + + def test_gem_repository_eh + doctor = Gem::Doctor.new @gemhome + + refute doctor.gem_repository?, 'no gems installed' + + util_spec 'a' + + doctor = Gem::Doctor.new @gemhome + + assert doctor.gem_repository?, 'gems installed' + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_ext_builder.rb b/jni/ruby/test/rubygems/test_gem_ext_builder.rb new file mode 100644 index 0000000..5607096 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_ext_builder.rb @@ -0,0 +1,334 @@ +require 'rubygems/test_case' +require 'rubygems/ext' +require 'rubygems/installer' + +class TestGemExtBuilder < Gem::TestCase + + def setup + super + + @ext = File.join @tempdir, 'ext' + @dest_path = File.join @tempdir, 'prefix' + + FileUtils.mkdir_p @ext + FileUtils.mkdir_p @dest_path + + @orig_DESTDIR = ENV['DESTDIR'] + + @spec = util_spec 'a' + + @builder = Gem::Ext::Builder.new @spec, '' + end + + def teardown + ENV['DESTDIR'] = @orig_DESTDIR + + super + end + + def test_class_make + ENV['DESTDIR'] = 'destination' + results = [] + + Dir.chdir @ext do + open 'Makefile', 'w' do |io| + io.puts <<-MAKEFILE +all: +\t@#{Gem.ruby} -e "puts %Q{all: \#{ENV['DESTDIR']}}" + +clean: +\t@#{Gem.ruby} -e "puts %Q{clean: \#{ENV['DESTDIR']}}" + +install: +\t@#{Gem.ruby} -e "puts %Q{install: \#{ENV['DESTDIR']}}" + MAKEFILE + end + + Gem::Ext::Builder.make @dest_path, results + end + + results = results.join "\n" + + if RUBY_VERSION > '2.0' then + assert_match %r%"DESTDIR=#{ENV['DESTDIR']}" clean$%, results + assert_match %r%"DESTDIR=#{ENV['DESTDIR']}"$%, results + assert_match %r%"DESTDIR=#{ENV['DESTDIR']}" install$%, results + else + refute_match %r%"DESTDIR=#{ENV['DESTDIR']}" clean$%, results + refute_match %r%"DESTDIR=#{ENV['DESTDIR']}"$%, results + refute_match %r%"DESTDIR=#{ENV['DESTDIR']}" install$%, results + end + + if /nmake/ !~ results + assert_match %r%^clean: destination$%, results + assert_match %r%^all: destination$%, results + assert_match %r%^install: destination$%, results + end + end + + def test_class_make_no_clean + ENV['DESTDIR'] = 'destination' + results = [] + + Dir.chdir @ext do + open 'Makefile', 'w' do |io| + io.puts <<-MAKEFILE +all: +\t@#{Gem.ruby} -e "puts %Q{all: \#{ENV['DESTDIR']}}" + +install: +\t@#{Gem.ruby} -e "puts %Q{install: \#{ENV['DESTDIR']}}" + MAKEFILE + end + + Gem::Ext::Builder.make @dest_path, results + end + + results = results.join "\n" + + if RUBY_VERSION > '2.0' then + assert_match %r%"DESTDIR=#{ENV['DESTDIR']}" clean$%, results + assert_match %r%"DESTDIR=#{ENV['DESTDIR']}"$%, results + assert_match %r%"DESTDIR=#{ENV['DESTDIR']}" install$%, results + else + refute_match %r%"DESTDIR=#{ENV['DESTDIR']}" clean$%, results + refute_match %r%"DESTDIR=#{ENV['DESTDIR']}"$%, results + refute_match %r%"DESTDIR=#{ENV['DESTDIR']}" install$%, results + end + end + + def test_build_extensions + @spec.extensions << 'ext/extconf.rb' + + ext_dir = File.join @spec.gem_dir, 'ext' + + FileUtils.mkdir_p ext_dir + + extconf_rb = File.join ext_dir, 'extconf.rb' + + open extconf_rb, 'w' do |f| + f.write <<-'RUBY' + require 'mkmf' + + create_makefile 'a' + RUBY + end + + ext_lib_dir = File.join ext_dir, 'lib' + FileUtils.mkdir ext_lib_dir + FileUtils.touch File.join ext_lib_dir, 'a.rb' + FileUtils.mkdir File.join ext_lib_dir, 'a' + FileUtils.touch File.join ext_lib_dir, 'a', 'b.rb' + + use_ui @ui do + @builder.build_extensions + end + + assert_path_exists @spec.extension_dir + assert_path_exists @spec.gem_build_complete_path + assert_path_exists File.join @spec.extension_dir, 'gem_make.out' + assert_path_exists File.join @spec.extension_dir, 'a.rb' + assert_path_exists File.join @spec.gem_dir, 'lib', 'a.rb' + assert_path_exists File.join @spec.gem_dir, 'lib', 'a', 'b.rb' + end + + def test_build_extensions_with_gemhome_with_space + new_gemhome = File.join @tempdir, 'gem home' + File.rename(@gemhome, new_gemhome) + @gemhome = new_gemhome + Gem.use_paths(@gemhome) + @spec = util_spec 'a' + @builder = Gem::Ext::Builder.new @spec, '' + + test_build_extensions + end + + def test_build_extensions_install_ext_only + class << Gem + alias orig_install_extension_in_lib install_extension_in_lib + + def Gem.install_extension_in_lib + false + end + end + + @spec.extensions << 'ext/extconf.rb' + + ext_dir = File.join @spec.gem_dir, 'ext' + + FileUtils.mkdir_p ext_dir + + extconf_rb = File.join ext_dir, 'extconf.rb' + + open extconf_rb, 'w' do |f| + f.write <<-'RUBY' + require 'mkmf' + + create_makefile 'a' + RUBY + end + + ext_lib_dir = File.join ext_dir, 'lib' + FileUtils.mkdir ext_lib_dir + FileUtils.touch File.join ext_lib_dir, 'a.rb' + FileUtils.mkdir File.join ext_lib_dir, 'a' + FileUtils.touch File.join ext_lib_dir, 'a', 'b.rb' + + use_ui @ui do + @builder.build_extensions + end + + assert_path_exists @spec.extension_dir + assert_path_exists @spec.gem_build_complete_path + assert_path_exists File.join @spec.extension_dir, 'gem_make.out' + assert_path_exists File.join @spec.extension_dir, 'a.rb' + refute_path_exists File.join @spec.gem_dir, 'lib', 'a.rb' + refute_path_exists File.join @spec.gem_dir, 'lib', 'a', 'b.rb' + ensure + class << Gem + remove_method :install_extension_in_lib + + alias install_extension_in_lib orig_install_extension_in_lib + end + end + + def test_build_extensions_none + use_ui @ui do + @builder.build_extensions + end + + assert_equal '', @ui.output + assert_equal '', @ui.error + + refute_path_exists File.join @spec.extension_dir, 'gem_make.out' + end + + def test_build_extensions_rebuild_failure + FileUtils.mkdir_p @spec.extension_dir + FileUtils.touch @spec.gem_build_complete_path + + @spec.extensions << nil + + assert_raises Gem::Ext::BuildError do + use_ui @ui do + @builder.build_extensions + end + end + + refute_path_exists @spec.gem_build_complete_path + end + + def test_build_extensions_extconf_bad + @spec.extensions << 'extconf.rb' + + FileUtils.mkdir_p @spec.gem_dir + + e = assert_raises Gem::Ext::BuildError do + use_ui @ui do + @builder.build_extensions + end + end + + assert_match(/\AERROR: Failed to build gem native extension.$/, e.message) + + assert_equal "Building native extensions. This could take a while...\n", + @ui.output + assert_equal '', @ui.error + + gem_make_out = File.join @spec.extension_dir, 'gem_make.out' + + assert_match %r%#{Regexp.escape Gem.ruby}.* extconf\.rb%, + File.read(gem_make_out) + assert_match %r%: No such file%, + File.read(gem_make_out) + + refute_path_exists @spec.gem_build_complete_path + + skip "Gem.ruby is not the name of the binary being run in the end" \ + unless File.read(gem_make_out).include? "#{Gem.ruby}:" + + assert_match %r%#{Regexp.escape Gem.ruby}: No such file%, + File.read(gem_make_out) + end + + def test_build_extensions_unsupported + FileUtils.mkdir_p @spec.gem_dir + gem_make_out = File.join @spec.extension_dir, 'gem_make.out' + @spec.extensions << nil + + e = assert_raises Gem::Ext::BuildError do + use_ui @ui do + @builder.build_extensions + end + end + + assert_match(/^\s*No builder for extension ''$/, e.message) + + assert_equal "Building native extensions. This could take a while...\n", + @ui.output + assert_equal '', @ui.error + + assert_equal "No builder for extension ''\n", File.read(gem_make_out) + + refute_path_exists @spec.gem_build_complete_path + ensure + FileUtils.rm_f gem_make_out + end + + def test_build_extensions_with_build_args + args = ["--aa", "--bb"] + @builder.build_args = args + @spec.extensions << 'extconf.rb' + + FileUtils.mkdir_p @spec.gem_dir + + open File.join(@spec.gem_dir, "extconf.rb"), "w" do |f| + f.write <<-'RUBY' + puts "IN EXTCONF" + extconf_args = File.join File.dirname(__FILE__), 'extconf_args' + File.open extconf_args, 'w' do |f| + f.puts ARGV.inspect + end + + File.open 'Makefile', 'w' do |f| + f.puts "clean:\n\techo cleaned" + f.puts "default:\n\techo built" + f.puts "install:\n\techo installed" + end + RUBY + end + + use_ui @ui do + @builder.build_extensions + end + + path = File.join @spec.gem_dir, "extconf_args" + + assert_equal args.inspect, File.read(path).strip + assert_path_exists @spec.extension_dir + end + + def test_initialize + build_info_dir = File.join @gemhome, 'build_info' + + FileUtils.mkdir_p build_info_dir + + build_info_file = File.join build_info_dir, "#{@spec.full_name}.info" + + open build_info_file, 'w' do |io| + io.puts '--with-foo-dir=/nonexistent' + end + + builder = Gem::Ext::Builder.new @spec + + assert_equal %w[--with-foo-dir=/nonexistent], builder.build_args + end + + def test_initialize_build_args + builder = Gem::Ext::Builder.new @spec, %w[--with-foo-dir=/nonexistent] + + assert_equal %w[--with-foo-dir=/nonexistent], builder.build_args + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_ext_cmake_builder.rb b/jni/ruby/test/rubygems/test_gem_ext_cmake_builder.rb new file mode 100644 index 0000000..a36be47 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_ext_cmake_builder.rb @@ -0,0 +1,84 @@ +require 'rubygems/test_case' +require 'rubygems/ext' + +class TestGemExtCmakeBuilder < Gem::TestCase + + def setup + super + + `cmake #{Gem::Ext::Builder.redirector}` + + skip 'cmake not present' unless $?.success? + + @ext = File.join @tempdir, 'ext' + @dest_path = File.join @tempdir, 'prefix' + + FileUtils.mkdir_p @ext + FileUtils.mkdir_p @dest_path + end + + def test_self_build + File.open File.join(@ext, 'CMakeLists.txt'), 'w' do |cmakelists| + cmakelists.write <<-eo_cmake +cmake_minimum_required(VERSION 2.6) +install (FILES test.txt DESTINATION bin) + eo_cmake + end + + FileUtils.touch File.join(@ext, 'test.txt') + + output = [] + + Dir.chdir @ext do + Gem::Ext::CmakeBuilder.build nil, nil, @dest_path, output + end + + output = output.join "\n" + + assert_match \ + %r%^cmake \. -DCMAKE_INSTALL_PREFIX=#{Regexp.escape @dest_path}%, output + assert_match %r%#{Regexp.escape @ext}%, output + assert_contains_make_command '', output + assert_contains_make_command 'install', output + assert_match %r%test\.txt%, output + end + + def test_self_build_fail + output = [] + + error = assert_raises Gem::InstallError do + Dir.chdir @ext do + Gem::Ext::CmakeBuilder.build nil, nil, @dest_path, output + end + end + + output = output.join "\n" + + shell_error_msg = %r{(CMake Error: .*)} + sh_prefix_cmake = "cmake . -DCMAKE_INSTALL_PREFIX=" + + assert_match 'cmake failed', error.message + + assert_match %r%^#{sh_prefix_cmake}#{Regexp.escape @dest_path}%, output + assert_match %r%#{shell_error_msg}%, output + end + + def test_self_build_has_makefile + File.open File.join(@ext, 'Makefile'), 'w' do |makefile| + makefile.puts "all:\n\t@echo ok\ninstall:\n\t@echo ok" + end + + output = [] + + Dir.chdir @ext do + Gem::Ext::CmakeBuilder.build nil, nil, @dest_path, output + end + + output = output.join "\n" + + assert_contains_make_command '', output + assert_contains_make_command 'install', output + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_ext_configure_builder.rb b/jni/ruby/test/rubygems/test_gem_ext_configure_builder.rb new file mode 100644 index 0000000..34e9fcc --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_ext_configure_builder.rb @@ -0,0 +1,82 @@ +require 'rubygems/test_case' +require 'rubygems/ext' + +class TestGemExtConfigureBuilder < Gem::TestCase + + def setup + super + + @makefile_body = + "clean:\n\t@echo ok\nall:\n\t@echo ok\ninstall:\n\t@echo ok" + + @ext = File.join @tempdir, 'ext' + @dest_path = File.join @tempdir, 'prefix' + + FileUtils.mkdir_p @ext + FileUtils.mkdir_p @dest_path + end + + def test_self_build + skip("test_self_build skipped on MS Windows (VC++)") if vc_windows? + + File.open File.join(@ext, './configure'), 'w' do |configure| + configure.puts "#!/bin/sh\necho \"#{@makefile_body}\" > Makefile" + end + + output = [] + + Dir.chdir @ext do + Gem::Ext::ConfigureBuilder.build nil, nil, @dest_path, output + end + + assert_equal "sh ./configure --prefix=#{@dest_path}", output.shift + assert_equal "", output.shift + assert_contains_make_command 'clean', output.shift + assert_match(/^ok$/m, output.shift) + assert_contains_make_command '', output.shift + assert_match(/^ok$/m, output.shift) + assert_contains_make_command 'install', output.shift + assert_match(/^ok$/m, output.shift) + end + + def test_self_build_fail + skip("test_self_build_fail skipped on MS Windows (VC++)") if vc_windows? + output = [] + + error = assert_raises Gem::InstallError do + Dir.chdir @ext do + Gem::Ext::ConfigureBuilder.build nil, nil, @dest_path, output + end + end + + shell_error_msg = %r{(\./configure: .*)|((?:Can't|cannot) open \./configure(?:: No such file or directory)?)} + sh_prefix_configure = "sh ./configure --prefix=" + + assert_match 'configure failed', error.message + + assert_equal "#{sh_prefix_configure}#{@dest_path}", output.shift + assert_match %r(#{shell_error_msg}), output.shift + assert_equal true, output.empty? + end + + def test_self_build_has_makefile + if vc_windows? && !nmake_found? + skip("test_self_build_has_makefile skipped - nmake not found") + end + + File.open File.join(@ext, 'Makefile'), 'w' do |makefile| + makefile.puts @makefile_body + end + + output = [] + Dir.chdir @ext do + Gem::Ext::ConfigureBuilder.build nil, nil, @dest_path, output + end + + assert_contains_make_command 'clean', output[0] + assert_contains_make_command '', output[2] + assert_contains_make_command 'install', output[4] + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_ext_ext_conf_builder.rb b/jni/ruby/test/rubygems/test_gem_ext_ext_conf_builder.rb new file mode 100644 index 0000000..f2f467e --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_ext_ext_conf_builder.rb @@ -0,0 +1,206 @@ +# coding: UTF-8 + +require 'rubygems/test_case' +require 'rubygems/ext' + +class TestGemExtExtConfBuilder < Gem::TestCase + + def setup + super + + @ext = File.join @tempdir, 'ext' + @dest_path = File.join @tempdir, 'prefix' + + FileUtils.mkdir_p @ext + FileUtils.mkdir_p @dest_path + end + + def test_class_build + if vc_windows? && !nmake_found? + skip("test_class_build skipped - nmake not found") + end + + File.open File.join(@ext, 'extconf.rb'), 'w' do |extconf| + extconf.puts "require 'mkmf'\ncreate_makefile 'foo'" + end + + output = [] + + Dir.chdir @ext do + result = + Gem::Ext::ExtConfBuilder.build 'extconf.rb', nil, @dest_path, output + + assert_same result, output + end + + assert_match(/^#{Gem.ruby}.* extconf.rb/, output[0]) + assert_equal "creating Makefile\n", output[1] + assert_contains_make_command 'clean', output[2] + assert_contains_make_command '', output[4] + assert_contains_make_command 'install', output[6] + assert_empty Dir.glob(File.join(@ext, 'siteconf*.rb')) + end + + def test_class_build_rbconfig_make_prog + configure_args do + + File.open File.join(@ext, 'extconf.rb'), 'w' do |extconf| + extconf.puts "require 'mkmf'\ncreate_makefile 'foo'" + end + + output = [] + + Dir.chdir @ext do + Gem::Ext::ExtConfBuilder.build 'extconf.rb', nil, @dest_path, output + end + + assert_equal "creating Makefile\n", output[1] + assert_contains_make_command 'clean', output[2] + assert_contains_make_command '', output[4] + assert_contains_make_command 'install', output[6] + end + end + + def test_class_build_env_make + env_make = ENV.delete 'make' + ENV['make'] = 'anothermake' + + configure_args '' do + File.open File.join(@ext, 'extconf.rb'), 'w' do |extconf| + extconf.puts "require 'mkmf'\ncreate_makefile 'foo'" + end + + output = [] + + assert_raises Gem::InstallError do + Dir.chdir @ext do + Gem::Ext::ExtConfBuilder.build 'extconf.rb', nil, @dest_path, output + end + end + + assert_equal "creating Makefile\n", output[1] + assert_contains_make_command 'clean', output[2] + end + ensure + ENV['make'] = env_make + end + + def test_class_build_extconf_fail + if vc_windows? && !nmake_found? + skip("test_class_build_extconf_fail skipped - nmake not found") + end + + File.open File.join(@ext, 'extconf.rb'), 'w' do |extconf| + extconf.puts "require 'mkmf'" + extconf.puts "have_library 'nonexistent' or abort 'need libnonexistent'" + extconf.puts "create_makefile 'foo'" + end + + output = [] + + error = assert_raises Gem::InstallError do + Dir.chdir @ext do + Gem::Ext::ExtConfBuilder.build 'extconf.rb', nil, @dest_path, output + end + end + + assert_equal 'extconf failed, exit code 1', error.message + + assert_match(/^#{Gem.ruby}.* extconf.rb/, output[0]) + assert_path_exists File.join @dest_path, 'mkmf.log' + end + + def test_class_build_unconventional + if vc_windows? && !nmake_found? + skip("test_class_build skipped - nmake not found") + end + + File.open File.join(@ext, 'extconf.rb'), 'w' do |extconf| + extconf.puts <<-'EXTCONF' +include RbConfig + +ruby = + if ENV['RUBY'] then + ENV['RUBY'] + else + ruby_exe = "#{CONFIG['RUBY_INSTALL_NAME']}#{CONFIG['EXEEXT']}" + File.join CONFIG['bindir'], ruby_exe + end + +open 'Makefile', 'w' do |io| + io.write <<-Makefile +clean: ruby +all: ruby +install: ruby + +ruby: +\t#{ruby} -e0 + + Makefile +end + EXTCONF + end + + output = [] + + Dir.chdir @ext do + Gem::Ext::ExtConfBuilder.build 'extconf.rb', nil, @dest_path, output + end + + assert_contains_make_command 'clean', output[2] + assert_contains_make_command '', output[4] + assert_contains_make_command 'install', output[6] + assert_empty Dir.glob(File.join(@ext, 'siteconf*.rb')) + end + + def test_class_make + if vc_windows? && !nmake_found? + skip("test_class_make skipped - nmake not found") + end + + output = [] + makefile_path = File.join(@ext, 'Makefile') + File.open makefile_path, 'w' do |makefile| + makefile.puts "# π" + makefile.puts "RUBYARCHDIR = $(foo)$(target_prefix)" + makefile.puts "RUBYLIBDIR = $(bar)$(target_prefix)" + makefile.puts "clean:" + makefile.puts "all:" + makefile.puts "install:" + end + + Dir.chdir @ext do + Gem::Ext::ExtConfBuilder.make @ext, output + end + + assert_contains_make_command 'clean', output[0] + assert_contains_make_command '', output[2] + assert_contains_make_command 'install', output[4] + end + + def test_class_make_no_Makefile + error = assert_raises Gem::InstallError do + Dir.chdir @ext do + Gem::Ext::ExtConfBuilder.make @ext, ['output'] + end + end + + assert_equal 'Makefile not found', error.message + end + + def configure_args args = nil + configure_args = RbConfig::CONFIG['configure_args'] + RbConfig::CONFIG['configure_args'] = args if args + + yield + + ensure + if configure_args then + RbConfig::CONFIG['configure_args'] = configure_args + else + RbConfig::CONFIG.delete 'configure_args' + end + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_ext_rake_builder.rb b/jni/ruby/test/rubygems/test_gem_ext_rake_builder.rb new file mode 100644 index 0000000..0f4789a --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_ext_rake_builder.rb @@ -0,0 +1,64 @@ +require 'rubygems/test_case' +require 'rubygems/ext' + +class TestGemExtRakeBuilder < Gem::TestCase + def setup + super + + @ext = File.join @tempdir, 'ext' + @dest_path = File.join @tempdir, 'prefix' + + FileUtils.mkdir_p @ext + FileUtils.mkdir_p @dest_path + end + + def test_class_build + File.open File.join(@ext, 'mkrf_conf.rb'), 'w' do |mkrf_conf| + mkrf_conf.puts <<-EO_MKRF + File.open("Rakefile","w") do |f| + f.puts "task :default" + end + EO_MKRF + end + + output = [] + realdir = nil # HACK /tmp vs. /private/tmp + + build_rake_in do |rake| + Dir.chdir @ext do + realdir = Dir.pwd + Gem::Ext::RakeBuilder.build 'mkrf_conf.rb', nil, @dest_path, output + end + + output = output.join "\n" + + refute_match %r%^rake failed:%, output + assert_match %r%^#{Regexp.escape @@ruby} mkrf_conf\.rb%, output + assert_match %r%^#{Regexp.escape rake} RUBYARCHDIR=#{Regexp.escape @dest_path} RUBYLIBDIR=#{Regexp.escape @dest_path}%, output + end + end + + def test_class_build_fail + File.open File.join(@ext, 'mkrf_conf.rb'), 'w' do |mkrf_conf| + mkrf_conf.puts <<-EO_MKRF + File.open("Rakefile","w") do |f| + f.puts "task :default do abort 'fail' end" + end + EO_MKRF + end + + output = [] + + build_rake_in(false) do |rake| + error = assert_raises Gem::InstallError do + Dir.chdir @ext do + Gem::Ext::RakeBuilder.build "mkrf_conf.rb", nil, @dest_path, output + end + end + + assert_match %r%^rake failed%, error.message + end + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_gem_runner.rb b/jni/ruby/test/rubygems/test_gem_gem_runner.rb new file mode 100644 index 0000000..85ff725 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_gem_runner.rb @@ -0,0 +1,68 @@ +require 'rubygems/test_case' +require 'rubygems/gem_runner' + +class TestGemGemRunner < Gem::TestCase + + def setup + super + + @orig_args = Gem::Command.build_args + @runner = Gem::GemRunner.new + end + + def teardown + super + + Gem::Command.build_args = @orig_args + end + + def test_do_configuration + Gem.clear_paths + + temp_conf = File.join @tempdir, '.gemrc' + + other_gem_path = File.join @tempdir, 'other_gem_path' + other_gem_home = File.join @tempdir, 'other_gem_home' + + Gem.ensure_gem_subdirectories other_gem_path + Gem.ensure_gem_subdirectories other_gem_home + + File.open temp_conf, 'w' do |fp| + fp.puts "gem: --commands" + fp.puts "gemhome: #{other_gem_home}" + fp.puts "gempath:" + fp.puts " - #{other_gem_path}" + fp.puts "rdoc: --all" + end + + gr = Gem::GemRunner.new + gr.send :do_configuration, %W[--config-file #{temp_conf}] + + assert_equal [other_gem_path, other_gem_home], Gem.path + assert_equal %w[--commands], Gem::Command.extra_args + end + + def test_extract_build_args + args = %w[] + assert_equal [], @runner.extract_build_args(args) + assert_equal %w[], args + + args = %w[foo] + assert_equal [], @runner.extract_build_args(args) + assert_equal %w[foo], args + + args = %w[--foo] + assert_equal [], @runner.extract_build_args(args) + assert_equal %w[--foo], args + + args = %w[--foo --] + assert_equal [], @runner.extract_build_args(args) + assert_equal %w[--foo], args + + args = %w[--foo -- --bar] + assert_equal %w[--bar], @runner.extract_build_args(args) + assert_equal %w[--foo], args + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_gemcutter_utilities.rb b/jni/ruby/test/rubygems/test_gem_gemcutter_utilities.rb new file mode 100644 index 0000000..c117c8f --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_gemcutter_utilities.rb @@ -0,0 +1,234 @@ +require 'rubygems/test_case' +require 'rubygems' +require 'rubygems/command' +require 'rubygems/gemcutter_utilities' + +class TestGemGemcutterUtilities < Gem::TestCase + + def setup + super + + ENV['RUBYGEMS_HOST'] = nil + Gem.configuration.rubygems_api_key = nil + + @cmd = Gem::Command.new '', 'summary' + @cmd.extend Gem::GemcutterUtilities + end + + def teardown + ENV['RUBYGEMS_HOST'] = nil + Gem.configuration.rubygems_api_key = nil + + super + end + + def test_alternate_key_alternate_host + keys = { + :rubygems_api_key => 'KEY', + "http://rubygems.engineyard.com" => "EYKEY" + } + + FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path + + open Gem.configuration.credentials_path, 'w' do |f| + f.write keys.to_yaml + end + + ENV["RUBYGEMS_HOST"] = "http://rubygems.engineyard.com" + + Gem.configuration.load_api_keys + + assert_equal 'EYKEY', @cmd.api_key + end + + def test_api_key + keys = { :rubygems_api_key => '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 + + assert_equal 'KEY', @cmd.api_key + end + + def test_api_key_override + keys = { :rubygems_api_key => 'KEY', :other => 'OTHER' } + 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 + + @cmd.add_key_option + @cmd.handle_options %w[--key other] + + assert_equal 'OTHER', @cmd.api_key + end + + def test_host + assert_equal 'https://rubygems.org', @cmd.host + end + + def test_host_RUBYGEMS_HOST + ENV['RUBYGEMS_HOST'] = 'https://other.example' + + assert_equal 'https://other.example', @cmd.host + end + + def test_host_RUBYGEMS_HOST_empty + ENV['RUBYGEMS_HOST'] = '' + + assert_equal 'https://rubygems.org', @cmd.host + end + + def test_sign_in + api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' + util_sign_in [api_key, 200, 'OK'] + + assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output + assert @fetcher.last_request["authorization"] + assert_match %r{Signed in.}, @sign_in_ui.output + + credentials = YAML.load_file Gem.configuration.credentials_path + assert_equal api_key, credentials[:rubygems_api_key] + end + + def test_sign_in_with_host + api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' + + util_sign_in [api_key, 200, 'OK'], 'http://example.com', ['http://example.com'] + + assert_match "Enter your http://example.com credentials.", + @sign_in_ui.output + assert @fetcher.last_request["authorization"] + assert_match %r{Signed in.}, @sign_in_ui.output + + credentials = YAML.load_file Gem.configuration.credentials_path + assert_equal api_key, credentials[:rubygems_api_key] + end + + def test_sign_in_with_host_nil + api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' + + util_sign_in [api_key, 200, 'OK'], nil, [nil] + + assert_match "Enter your RubyGems.org credentials.", + @sign_in_ui.output + assert @fetcher.last_request["authorization"] + assert_match %r{Signed in.}, @sign_in_ui.output + + credentials = YAML.load_file Gem.configuration.credentials_path + assert_equal api_key, credentials[:rubygems_api_key] + end + + def test_sign_in_with_host_ENV + api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' + util_sign_in [api_key, 200, 'OK'], 'http://example.com' + + assert_match "Enter your http://example.com credentials.", + @sign_in_ui.output + assert @fetcher.last_request["authorization"] + assert_match %r{Signed in.}, @sign_in_ui.output + + credentials = YAML.load_file Gem.configuration.credentials_path + assert_equal api_key, credentials[:rubygems_api_key] + end + + def test_sign_in_skips_with_existing_credentials + api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' + Gem.configuration.rubygems_api_key = api_key + + util_sign_in [api_key, 200, 'OK'] + + assert_equal "", @sign_in_ui.output + end + + def test_sign_in_skips_with_key_override + api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' + Gem.configuration.api_keys[:KEY] = 'other' + @cmd.options[:key] = :KEY + util_sign_in [api_key, 200, 'OK'] + + assert_equal "", @sign_in_ui.output + end + + def test_sign_in_with_other_credentials_doesnt_overwrite_other_keys + api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' + other_api_key = 'f46dbb18bb6a9c97cdc61b5b85c186a17403cdcbf' + + FileUtils.mkdir_p File.dirname(Gem.configuration.credentials_path) + open Gem.configuration.credentials_path, 'w' do |f| + f.write Hash[:other_api_key, other_api_key].to_yaml + end + util_sign_in [api_key, 200, 'OK'] + + assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output + assert_match %r{Signed in.}, @sign_in_ui.output + + credentials = YAML.load_file Gem.configuration.credentials_path + assert_equal api_key, credentials[:rubygems_api_key] + assert_equal other_api_key, credentials[:other_api_key] + end + + def test_sign_in_with_bad_credentials + skip 'Always uses $stdin on windows' if Gem.win_platform? + + assert_raises Gem::MockGemUi::TermError do + util_sign_in ['Access Denied.', 403, 'Forbidden'] + end + + assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output + assert_match %r{Access Denied.}, @sign_in_ui.output + end + + def util_sign_in response, host = nil, args = [] + skip 'Always uses $stdin on windows' if Gem.win_platform? + + email = 'you@example.com' + password = 'secret' + + if host + ENV['RUBYGEMS_HOST'] = host + else + host = Gem.host + end + + @fetcher = Gem::FakeFetcher.new + @fetcher.data["#{host}/api/v1/api_key"] = response + Gem::RemoteFetcher.fetcher = @fetcher + + @sign_in_ui = Gem::MockGemUi.new "#{email}\n#{password}\n" + + use_ui @sign_in_ui do + if args.length > 0 then + @cmd.sign_in(*args) + else + @cmd.sign_in + end + end + end + + def test_verify_api_key + keys = {:other => 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'} + FileUtils.mkdir_p File.dirname(Gem.configuration.credentials_path) + File.open Gem.configuration.credentials_path, 'w' do |f| + f.write keys.to_yaml + end + Gem.configuration.load_api_keys + + assert_equal 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903', + @cmd.verify_api_key(:other) + end + + def test_verify_missing_api_key + assert_raises Gem::MockGemUi::TermError do + @cmd.verify_api_key :missing + end + end + +end diff --git a/jni/ruby/test/rubygems/test_gem_impossible_dependencies_error.rb b/jni/ruby/test/rubygems/test_gem_impossible_dependencies_error.rb new file mode 100644 index 0000000..9c9825c --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_impossible_dependencies_error.rb @@ -0,0 +1,61 @@ +require 'rubygems/test_case' + +class TestGemImpossibleDependenciesError < Gem::TestCase + + def test_message_conflict + request = dependency_request dep('net-ssh', '>= 2.0.13'), 'rye', '0.9.8' + + conflicts = [] + + # These conflicts are lies as their dependencies does not have the correct + # requested-by entries, but they are suitable for testing the message. + # See #485 to construct a correct conflict. + net_ssh_2_2_2 = + dependency_request dep('net-ssh', '>= 2.6.5'), 'net-ssh', '2.2.2', request + net_ssh_2_6_5 = + dependency_request dep('net-ssh', '~> 2.2.2'), 'net-ssh', '2.6.5', request + + conflict1 = Gem::Resolver::Conflict.new \ + net_ssh_2_6_5, net_ssh_2_6_5.requester + + conflict2 = Gem::Resolver::Conflict.new \ + net_ssh_2_2_2, net_ssh_2_2_2.requester + + conflicts << [net_ssh_2_6_5.requester.spec, conflict1] + conflicts << [net_ssh_2_2_2.requester.spec, conflict2] + + error = Gem::ImpossibleDependenciesError.new request, conflicts + + expected = <<-EXPECTED +rye-0.9.8 requires net-ssh (>= 2.0.13) but it conflicted: + Activated net-ssh-2.6.5 + which does not match conflicting dependency (~> 2.2.2) + + Conflicting dependency chains: + rye (= 0.9.8), 0.9.8 activated, depends on + net-ssh (>= 2.0.13), 2.6.5 activated + + versus: + rye (= 0.9.8), 0.9.8 activated, depends on + net-ssh (>= 2.0.13), 2.6.5 activated, depends on + net-ssh (~> 2.2.2) + + Activated net-ssh-2.2.2 + which does not match conflicting dependency (>= 2.6.5) + + Conflicting dependency chains: + rye (= 0.9.8), 0.9.8 activated, depends on + net-ssh (>= 2.0.13), 2.2.2 activated + + versus: + rye (= 0.9.8), 0.9.8 activated, depends on + net-ssh (>= 2.0.13), 2.2.2 activated, depends on + net-ssh (>= 2.6.5) + + EXPECTED + + assert_equal expected, error.message + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_indexer.rb b/jni/ruby/test/rubygems/test_gem_indexer.rb new file mode 100644 index 0000000..5ce0788 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_indexer.rb @@ -0,0 +1,366 @@ +require 'rubygems/test_case' +require 'rubygems/indexer' + +unless defined?(Builder::XChar) then + warn "Gem::Indexer tests are being skipped. Install builder gem." if $VERBOSE +end + +class TestGemIndexer < Gem::TestCase + + def setup + super + + util_clear_gems + util_make_gems + + @d2_0 = util_spec 'd', '2.0' do |s| + s.date = Gem::Specification::TODAY - 86400 * 3 + end + util_build_gem @d2_0 + + @d2_0_a = util_spec 'd', '2.0.a' + util_build_gem @d2_0_a + + @d2_0_b = util_spec 'd', '2.0.b' + util_build_gem @d2_0_b + + @default = new_default_spec 'default', 2 + install_default_gems @default + + @tempdir = File.join(@tempdir, 'indexer') + + gems = File.join(@tempdir, 'gems') + FileUtils.mkdir_p gems + FileUtils.mv Dir[File.join(@gemhome, "cache", '*.gem')], gems + + @indexer = Gem::Indexer.new(@tempdir) + end + + def test_initialize + assert_equal @tempdir, @indexer.dest_directory + assert_equal File.join(Dir.tmpdir, "gem_generate_index_#{$$}"), + @indexer.directory + + indexer = Gem::Indexer.new @tempdir + assert indexer.build_modern + + indexer = Gem::Indexer.new @tempdir, :build_modern => true + assert indexer.build_modern + end + + def test_build_indicies + @indexer.make_temp_directories + + use_ui @ui do + @indexer.build_indicies + end + + specs_path = File.join @indexer.directory, "specs.#{@marshal_version}" + specs_dump = Gem.read_binary specs_path + specs = Marshal.load specs_dump + + expected = [["a", Gem::Version.new("1"), "ruby"], + ["a", Gem::Version.new("2"), "ruby"], + ["a_evil", Gem::Version.new("9"), "ruby"], + ["b", Gem::Version.new("2"), "ruby"], + ["c", Gem::Version.new("1.2"), "ruby"], + ["d", Gem::Version.new("2.0"), "ruby"], + ["dep_x", Gem::Version.new("1"), "ruby"], + ["pl", Gem::Version.new("1"), "i386-linux"], + ["x", Gem::Version.new("1"), "ruby"]] + + assert_equal expected, specs + + latest_specs_path = File.join(@indexer.directory, + "latest_specs.#{@marshal_version}") + latest_specs_dump = Gem.read_binary latest_specs_path + latest_specs = Marshal.load latest_specs_dump + + expected = [["a", Gem::Version.new("2"), "ruby"], + ["a_evil", Gem::Version.new("9"), "ruby"], + ["b", Gem::Version.new("2"), "ruby"], + ["c", Gem::Version.new("1.2"), "ruby"], + ["d", Gem::Version.new("2.0"), "ruby"], + ["dep_x", Gem::Version.new("1"), "ruby"], + ["pl", Gem::Version.new("1"), "i386-linux"], + ["x", Gem::Version.new("1"), "ruby"]] + + assert_equal expected, latest_specs, 'latest_specs' + end + + def test_generate_index + use_ui @ui do + @indexer.generate_index + end + + quickdir = File.join @tempdir, 'quick' + marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}" + + assert File.directory?(quickdir) + assert File.directory?(marshal_quickdir) + + assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz" + assert_indexed marshal_quickdir, "#{File.basename(@a2.spec_file)}.rz" + + refute_indexed marshal_quickdir, File.basename(@c1_2.spec_file) + + assert_indexed @tempdir, "specs.#{@marshal_version}" + assert_indexed @tempdir, "specs.#{@marshal_version}.gz" + + assert_indexed @tempdir, "latest_specs.#{@marshal_version}" + assert_indexed @tempdir, "latest_specs.#{@marshal_version}.gz" + end + + def test_generate_index_modern + @indexer.build_modern = true + + use_ui @ui do + @indexer.generate_index + end + + refute_indexed @tempdir, 'yaml' + refute_indexed @tempdir, 'yaml.Z' + refute_indexed @tempdir, "Marshal.#{@marshal_version}" + refute_indexed @tempdir, "Marshal.#{@marshal_version}.Z" + + quickdir = File.join @tempdir, 'quick' + marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}" + + assert File.directory?(quickdir), 'quickdir should be directory' + assert File.directory?(marshal_quickdir) + + refute_indexed quickdir, "index" + refute_indexed quickdir, "index.rz" + + refute_indexed quickdir, "latest_index" + refute_indexed quickdir, "latest_index.rz" + + refute_indexed quickdir, "#{File.basename(@a1.spec_file)}.rz" + refute_indexed quickdir, "#{File.basename(@a2.spec_file)}.rz" + refute_indexed quickdir, "#{File.basename(@b2.spec_file)}.rz" + refute_indexed quickdir, "#{File.basename(@c1_2.spec_file)}.rz" + + refute_indexed quickdir, "#{@pl1.original_name}.gemspec.rz" + refute_indexed quickdir, "#{File.basename(@pl1.spec_file)}.rz" + + assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz" + assert_indexed marshal_quickdir, "#{File.basename(@a2.spec_file)}.rz" + + refute_indexed quickdir, "#{File.basename(@c1_2.spec_file)}" + refute_indexed marshal_quickdir, "#{File.basename(@c1_2.spec_file)}" + + assert_indexed @tempdir, "specs.#{@marshal_version}" + assert_indexed @tempdir, "specs.#{@marshal_version}.gz" + + assert_indexed @tempdir, "latest_specs.#{@marshal_version}" + assert_indexed @tempdir, "latest_specs.#{@marshal_version}.gz" + end + + def test_generate_index_modern_back_to_back + @indexer.build_modern = true + + use_ui @ui do + @indexer.generate_index + end + + @indexer = Gem::Indexer.new @tempdir + @indexer.build_modern = true + + use_ui @ui do + @indexer.generate_index + end + quickdir = File.join @tempdir, 'quick' + marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}" + + assert File.directory?(quickdir) + assert File.directory?(marshal_quickdir) + + assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz" + assert_indexed marshal_quickdir, "#{File.basename(@a2.spec_file)}.rz" + + assert_indexed @tempdir, "specs.#{@marshal_version}" + assert_indexed @tempdir, "specs.#{@marshal_version}.gz" + + assert_indexed @tempdir, "latest_specs.#{@marshal_version}" + assert_indexed @tempdir, "latest_specs.#{@marshal_version}.gz" + end + + def test_generate_index_ui + use_ui @ui do + @indexer.generate_index + end + + assert_match %r%^\.\.\.\.\.\.\.\.\.\.\.\.$%, @ui.output + assert_match %r%^Generating Marshal quick index gemspecs for 12 gems$%, + @ui.output + assert_match %r%^Complete$%, @ui.output + assert_match %r%^Generating specs index$%, @ui.output + assert_match %r%^Generating latest specs index$%, @ui.output + assert_match %r%^Generating prerelease specs index$%, @ui.output + assert_match %r%^Complete$%, @ui.output + assert_match %r%^Compressing indicies$%, @ui.output + + assert_equal '', @ui.error + end + + def test_generate_index_specs + use_ui @ui do + @indexer.generate_index + end + + specs_path = File.join @tempdir, "specs.#{@marshal_version}" + + specs_dump = Gem.read_binary specs_path + specs = Marshal.load specs_dump + + expected = [ + ['a', Gem::Version.new(1), 'ruby'], + ['a', Gem::Version.new(2), 'ruby'], + ['a_evil', Gem::Version.new(9), 'ruby'], + ['b', Gem::Version.new(2), 'ruby'], + ['c', Gem::Version.new('1.2'), 'ruby'], + ['d', Gem::Version.new('2.0'), 'ruby'], + ['dep_x', Gem::Version.new(1), 'ruby'], + ['pl', Gem::Version.new(1), 'i386-linux'], + ['x', Gem::Version.new(1), 'ruby'], + ] + + assert_equal expected, specs + + assert_same specs[0].first, specs[1].first, + 'identical names not identical' + + assert_same specs[0][1], specs[-1][1], + 'identical versions not identical' + + assert_same specs[0].last, specs[1].last, + 'identical platforms not identical' + + refute_same specs[1][1], specs[5][1], + 'different versions not different' + end + + def test_generate_index_latest_specs + use_ui @ui do + @indexer.generate_index + end + + latest_specs_path = File.join @tempdir, "latest_specs.#{@marshal_version}" + + latest_specs_dump = Gem.read_binary latest_specs_path + latest_specs = Marshal.load latest_specs_dump + + expected = [ + ['a', Gem::Version.new(2), 'ruby'], + ['a_evil', Gem::Version.new(9), 'ruby'], + ['b', Gem::Version.new(2), 'ruby'], + ['c', Gem::Version.new('1.2'), 'ruby'], + ['d', Gem::Version.new('2.0'), 'ruby'], + ['dep_x', Gem::Version.new(1), 'ruby'], + ['pl', Gem::Version.new(1), 'i386-linux'], + ['x', Gem::Version.new(1), 'ruby'], + ] + + assert_equal expected, latest_specs + + assert_same latest_specs[0][1], latest_specs[2][1], + 'identical versions not identical' + + assert_same latest_specs[0].last, latest_specs[1].last, + 'identical platforms not identical' + end + + def test_generate_index_prerelease_specs + use_ui @ui do + @indexer.generate_index + end + + prerelease_specs_path = File.join @tempdir, "prerelease_specs.#{@marshal_version}" + + prerelease_specs_dump = Gem.read_binary prerelease_specs_path + prerelease_specs = Marshal.load prerelease_specs_dump + + assert_equal [['a', Gem::Version.new('3.a'), 'ruby'], + ['d', Gem::Version.new('2.0.a'), 'ruby'], + ['d', Gem::Version.new('2.0.b'), 'ruby']], + prerelease_specs + end + + ## + # Emulate the starting state of Gem::Specification in a live environment, + # where it will carry the list of system gems + def with_system_gems + Gem::Specification.reset + + sys_gem = util_spec 'systemgem', '1.0' + util_build_gem sys_gem + Gem::Specification.add_spec sys_gem + yield + util_remove_gem sys_gem + end + + + def test_update_index + use_ui @ui do + @indexer.generate_index + end + + quickdir = File.join @tempdir, 'quick' + marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}" + + assert File.directory?(quickdir) + assert File.directory?(marshal_quickdir) + + @d2_1 = util_spec 'd', '2.1' + util_build_gem @d2_1 + @d2_1_tuple = [@d2_1.name, @d2_1.version, @d2_1.original_platform] + + @d2_1_a = util_spec 'd', '2.2.a' + util_build_gem @d2_1_a + @d2_1_a_tuple = [@d2_1_a.name, @d2_1_a.version, @d2_1_a.original_platform] + + gems = File.join @tempdir, 'gems' + + FileUtils.mv @d2_1.cache_file, gems + FileUtils.mv @d2_1_a.cache_file, gems + + with_system_gems do + use_ui @ui do + @indexer.update_index + end + + assert_indexed marshal_quickdir, "#{File.basename(@d2_1.spec_file)}.rz" + + specs_index = Marshal.load Gem.read_binary(@indexer.dest_specs_index) + + assert_includes specs_index, @d2_1_tuple + refute_includes specs_index, @d2_1_a_tuple + + latest_specs_index = Marshal.load \ + Gem.read_binary(@indexer.dest_latest_specs_index) + + assert_includes latest_specs_index, @d2_1_tuple + assert_includes latest_specs_index, + [@d2_0.name, @d2_0.version, @d2_0.original_platform] + refute_includes latest_specs_index, @d2_1_a_tuple + + pre_specs_index = Marshal.load \ + Gem.read_binary(@indexer.dest_prerelease_specs_index) + + assert_includes pre_specs_index, @d2_1_a_tuple + refute_includes pre_specs_index, @d2_1_tuple + end + end + + def assert_indexed(dir, name) + file = File.join dir, name + assert File.exist?(file), "#{file} does not exist" + end + + def refute_indexed(dir, name) + file = File.join dir, name + refute File.exist?(file), "#{file} exists" + end + +end if defined?(Builder::XChar) + diff --git a/jni/ruby/test/rubygems/test_gem_install_update_options.rb b/jni/ruby/test/rubygems/test_gem_install_update_options.rb new file mode 100644 index 0000000..de09d7a --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_install_update_options.rb @@ -0,0 +1,184 @@ +require 'rubygems/installer_test_case' +require 'rubygems/install_update_options' +require 'rubygems/command' +require 'rubygems/dependency_installer' + +class TestGemInstallUpdateOptions < Gem::InstallerTestCase + + def setup + super + + @cmd = Gem::Command.new 'dummy', 'dummy', + Gem::DependencyInstaller::DEFAULT_OPTIONS + @cmd.extend Gem::InstallUpdateOptions + @cmd.add_install_update_options + end + + def test_add_install_update_options + args = %w[ + --document + --build-root build_root + --format-exec + --ignore-dependencies + --rdoc + --ri + -E + -f + -i /install_to + -w + --vendor + ] + + args.concat %w[-P HighSecurity] if defined?(OpenSSL::SSL) + + assert @cmd.handles?(args) + end + + def test_build_root + @cmd.handle_options %w[--build-root build_root] + + assert_equal File.expand_path('build_root'), @cmd.options[:build_root] + end + + def test_doc + @cmd.handle_options %w[--doc] + + assert_equal %w[ri], @cmd.options[:document].sort + end + + def test_doc_rdoc + @cmd.handle_options %w[--doc=rdoc] + + assert_equal %w[rdoc], @cmd.options[:document] + + @cmd.handle_options %w[--doc ri] + + assert_equal %w[ri], @cmd.options[:document] + end + + def test_doc_rdoc_ri + @cmd.handle_options %w[--doc=rdoc,ri] + + assert_equal %w[rdoc ri], @cmd.options[:document] + end + + def test_doc_no + @cmd.handle_options %w[--no-doc] + + assert_equal [], @cmd.options[:document] + end + + def test_document + @cmd.handle_options %w[--document] + + assert_equal %w[ri], @cmd.options[:document].sort + end + + def test_document_no + @cmd.handle_options %w[--no-document] + + assert_equal %w[], @cmd.options[:document] + end + + def test_document_rdoc + @cmd.handle_options %w[--document=rdoc] + + assert_equal %w[rdoc], @cmd.options[:document] + + @cmd.handle_options %w[--document ri] + + assert_equal %w[ri], @cmd.options[:document] + end + + def test_rdoc + @cmd.handle_options %w[--rdoc] + + assert_equal %w[rdoc ri], @cmd.options[:document].sort + end + + def test_rdoc_no + @cmd.handle_options %w[--no-rdoc] + + assert_equal %w[ri], @cmd.options[:document] + end + + def test_ri + @cmd.handle_options %w[--no-ri] + + assert_equal %w[], @cmd.options[:document] + end + + def test_security_policy + skip 'openssl is missing' unless defined?(OpenSSL::SSL) + + @cmd.handle_options %w[-P HighSecurity] + + assert_equal Gem::Security::HighSecurity, @cmd.options[:security_policy] + end + + def test_security_policy_unknown + @cmd.add_install_update_options + + assert_raises OptionParser::InvalidArgument do + @cmd.handle_options %w[-P UnknownSecurity] + end + end + + def test_user_install_enabled + @cmd.handle_options %w[--user-install] + + assert @cmd.options[:user_install] + + @installer = Gem::Installer.new @gem, @cmd.options + @installer.install + assert_path_exists File.join(Gem.user_dir, 'gems') + assert_path_exists File.join(Gem.user_dir, 'gems', @spec.full_name) + end + + def test_user_install_disabled_read_only + if win_platform? + skip('test_user_install_disabled_read_only test skipped on MS Windows') + else + @cmd.handle_options %w[--no-user-install] + + refute @cmd.options[:user_install] + + FileUtils.chmod 0755, @userhome + FileUtils.chmod 0000, @gemhome + + Gem.use_paths @gemhome, @userhome + + assert_raises(Gem::FilePermissionError) do + Gem::Installer.new(@gem, @cmd.options).install + end + end + ensure + FileUtils.chmod 0755, @gemhome + end + + def test_vendor + @cmd.handle_options %w[--vendor] + + assert @cmd.options[:vendor] + assert_equal Gem.vendor_dir, @cmd.options[:install_dir] + end + + def test_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/jni/ruby/test/rubygems/test_gem_installer.rb b/jni/ruby/test/rubygems/test_gem_installer.rb new file mode 100644 index 0000000..6f8012f --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_installer.rb @@ -0,0 +1,1533 @@ +require 'rubygems/installer_test_case' + +class TestGemInstaller < Gem::InstallerTestCase + + def setup + super + common_installer_setup + + if __name__ =~ /^test_install(_|$)/ then + FileUtils.rm_r @spec.gem_dir + FileUtils.rm_r @user_spec.gem_dir + end + + @config = Gem.configuration + end + + def teardown + common_installer_teardown + + super + + Gem.configuration = @config + end + + def test_app_script_text + util_make_exec @spec, '' + + expected = <<-EOF +#!#{Gem.ruby} +# +# This file was generated by RubyGems. +# +# The application 'a' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'rubygems' + +version = \">= 0\" + +if ARGV.first + str = ARGV.first + str = str.dup.force_encoding("BINARY") if str.respond_to? :force_encoding + if str =~ /\\A_(.*)_\\z/ and Gem::Version.correct?($1) then + version = $1 + ARGV.shift + end +end + +gem 'a', version +load Gem.bin_path('a', 'executable', version) + EOF + + wrapper = @installer.app_script_text 'executable' + assert_equal expected, wrapper + end + + def test_check_executable_overwrite + @installer.generate_bin + + @spec = Gem::Specification.new do |s| + s.files = ['lib/code.rb'] + s.name = "a" + s.version = "3" + s.summary = "summary" + s.description = "desc" + s.require_path = 'lib' + end + + util_make_exec + @installer.gem_dir = util_gem_dir @spec + @installer.wrappers = true + @installer.generate_bin + + installed_exec = File.join util_inst_bindir, 'executable' + assert_path_exists installed_exec + + wrapper = File.read installed_exec + assert_match %r|generated by RubyGems|, wrapper + end + + def test_check_executable_overwrite_default_bin_dir + if defined?(RUBY_FRAMEWORK_VERSION) + orig_RUBY_FRAMEWORK_VERSION = RUBY_FRAMEWORK_VERSION + Object.send :remove_const, :RUBY_FRAMEWORK_VERSION + end + orig_bindir = RbConfig::CONFIG['bindir'] + RbConfig::CONFIG['bindir'] = Gem.bindir + + util_conflict_executable false + + ui = Gem::MockGemUi.new "n\n" + use_ui ui do + e = assert_raises Gem::InstallError do + @installer.generate_bin + end + + conflicted = File.join @gemhome, 'bin', 'executable' + assert_match %r%\A"executable" from a conflicts with (?:#{Regexp.quote(conflicted)}|installed executable from conflict)\z%, + e.message + end + ensure + Object.const_set :RUBY_FRAMEWORK_VERSION, orig_RUBY_FRAMEWORK_VERSION if + orig_RUBY_FRAMEWORK_VERSION + if orig_bindir then + RbConfig::CONFIG['bindir'] = orig_bindir + else + RbConfig::CONFIG.delete 'bindir' + end + end + + def test_check_executable_overwrite_format_executable + @installer.generate_bin + + @spec = Gem::Specification.new do |s| + s.files = ['lib/code.rb'] + s.name = "a" + s.version = "3" + s.summary = "summary" + s.description = "desc" + s.require_path = 'lib' + end + + open File.join(util_inst_bindir, 'executable'), 'w' do |io| + io.write <<-EXEC +#!/usr/local/bin/ruby +# +# This file was generated by RubyGems + +gem 'other', version + EXEC + end + + util_make_exec + Gem::Installer.exec_format = 'foo-%s-bar' + @installer.gem_dir = @spec.gem_dir + @installer.wrappers = true + @installer.format_executable = true + + @installer.generate_bin # should not raise + + installed_exec = File.join util_inst_bindir, 'foo-executable-bar' + assert_path_exists installed_exec + + wrapper = File.read installed_exec + assert_match %r|generated by RubyGems|, wrapper + end + + def test_check_executable_overwrite_other_gem + util_conflict_executable true + + ui = Gem::MockGemUi.new "n\n" + + use_ui ui do + e = assert_raises Gem::InstallError do + @installer.generate_bin + end + + assert_equal '"executable" from a conflicts with installed executable from conflict', + e.message + end + end + + def test_check_executable_overwrite_other_gem_force + util_conflict_executable true + @installer.wrappers = true + @installer.force = true + + @installer.generate_bin + + installed_exec = File.join util_inst_bindir, 'executable' + assert_path_exists installed_exec + + wrapper = File.read installed_exec + assert_match %r|generated by RubyGems|, wrapper + end + + def test_check_executable_overwrite_other_non_gem + util_conflict_executable false + @installer.wrappers = true + + @installer.generate_bin + + installed_exec = File.join util_inst_bindir, 'executable' + assert_path_exists installed_exec + + wrapper = File.read installed_exec + assert_match %r|generated by RubyGems|, wrapper + end unless Gem.win_platform? + + def test_check_that_user_bin_dir_is_in_path + bin_dir = @installer.bin_dir + + if Gem.win_platform? + bin_dir = bin_dir.downcase.gsub(File::SEPARATOR, File::ALT_SEPARATOR) + end + + orig_PATH, ENV['PATH'] = + ENV['PATH'], [ENV['PATH'], bin_dir].join(File::PATH_SEPARATOR) + + use_ui @ui do + @installer.check_that_user_bin_dir_is_in_path + end + + assert_empty @ui.error + ensure + ENV['PATH'] = orig_PATH + end + + def test_check_that_user_bin_dir_is_in_path_tilde + skip "Tilde is PATH is not supported under MS Windows" if win_platform? + + orig_PATH, ENV['PATH'] = + ENV['PATH'], [ENV['PATH'], '~/bin'].join(File::PATH_SEPARATOR) + + @installer.bin_dir.replace File.join @userhome, 'bin' + + use_ui @ui do + @installer.check_that_user_bin_dir_is_in_path + end + + assert_empty @ui.error + ensure + ENV['PATH'] = orig_PATH unless win_platform? + end + + def test_check_that_user_bin_dir_is_in_path_not_in_path + use_ui @ui do + @installer.check_that_user_bin_dir_is_in_path + end + + expected = @installer.bin_dir + + if Gem.win_platform? then + expected = expected.downcase.gsub(File::SEPARATOR, File::ALT_SEPARATOR) + end + + assert_match expected, @ui.error + end + + def test_ensure_dependency + util_spec 'a' + + dep = Gem::Dependency.new 'a', '>= 2' + assert @installer.ensure_dependency(@spec, dep) + + dep = Gem::Dependency.new 'b', '> 2' + e = assert_raises Gem::InstallError do + @installer.ensure_dependency @spec, dep + end + + assert_equal 'a requires b (> 2)', e.message + end + + def test_ensure_loadable_spec + a, a_gem = util_gem 'a', 2 do |s| + s.add_dependency 'garbage ~> 5' + end + + installer = Gem::Installer.new a_gem + + e = assert_raises Gem::InstallError do + installer.ensure_loadable_spec + end + + assert_equal "The specification for #{a.full_name} is corrupt " + + "(SyntaxError)", e.message + end + + def test_ensure_loadable_spec_security_policy + skip 'openssl is missing' unless defined?(OpenSSL::SSL) + + _, a_gem = util_gem 'a', 2 do |s| + s.add_dependency 'garbage ~> 5' + end + + policy = Gem::Security::HighSecurity + installer = Gem::Installer.new a_gem, :security_policy => policy + + assert_raises Gem::Security::Exception do + installer.ensure_loadable_spec + end + end + + def test_extract_files + @installer.extract_files + + assert_path_exists File.join util_gem_dir, 'bin/executable' + end + + def test_generate_bin_bindir + @installer.wrappers = true + + @spec.executables = %w[executable] + @spec.bindir = '.' + + exec_file = @installer.formatted_program_filename 'executable' + exec_path = File.join util_gem_dir(@spec), exec_file + File.open exec_path, 'w' do |f| + f.puts '#!/usr/bin/ruby' + end + + @installer.gem_dir = util_gem_dir + + @installer.generate_bin + + assert_equal true, File.directory?(util_inst_bindir) + installed_exec = File.join(util_inst_bindir, 'executable') + assert_path_exists installed_exec + assert_equal mask, File.stat(installed_exec).mode unless win_platform? + + wrapper = File.read installed_exec + assert_match %r|generated by RubyGems|, wrapper + end + + def test_generate_bin_bindir_with_user_install_warning + bin_dir = Gem.win_platform? ? File.expand_path(ENV["WINDIR"]).upcase : + "/usr/bin" + + options = { + :bin_dir => bin_dir, + :install_dir => "/non/existant" + } + + inst = Gem::Installer.new '', options + + Gem::Installer.path_warning = false + + use_ui @ui do + inst.check_that_user_bin_dir_is_in_path + end + + assert_equal "", @ui.error + end + + def test_generate_bin_script + @installer.wrappers = true + util_make_exec + @installer.gem_dir = util_gem_dir + + @installer.generate_bin + assert File.directory? util_inst_bindir + installed_exec = File.join util_inst_bindir, 'executable' + assert_path_exists installed_exec + assert_equal mask, File.stat(installed_exec).mode unless win_platform? + + wrapper = File.read installed_exec + assert_match %r|generated by RubyGems|, wrapper + end + + def test_generate_bin_script_format + @installer.format_executable = true + @installer.wrappers = true + util_make_exec + @installer.gem_dir = util_gem_dir + + Gem::Installer.exec_format = 'foo-%s-bar' + @installer.generate_bin + assert_equal true, File.directory?(util_inst_bindir) + installed_exec = File.join util_inst_bindir, 'foo-executable-bar' + assert_path_exists installed_exec + ensure + Gem::Installer.exec_format = nil + end + + def test_generate_bin_script_format_disabled + @installer.wrappers = true + util_make_exec + @installer.gem_dir = util_gem_dir + + Gem::Installer.exec_format = 'foo-%s-bar' + @installer.generate_bin + assert_equal true, File.directory?(util_inst_bindir) + installed_exec = File.join util_inst_bindir, 'executable' + assert_path_exists installed_exec + ensure + Gem::Installer.exec_format = nil + end + + def test_generate_bin_script_install_dir + @installer.wrappers = true + + gem_dir = File.join("#{@gemhome}2", "gems", @spec.full_name) + gem_bindir = File.join gem_dir, 'bin' + FileUtils.mkdir_p gem_bindir + File.open File.join(gem_bindir, 'executable'), 'w' do |f| + f.puts "#!/bin/ruby" + end + + @installer.gem_home = "#{@gemhome}2" + @installer.gem_dir = gem_dir + @installer.bin_dir = File.join "#{@gemhome}2", 'bin' + + @installer.generate_bin + + installed_exec = File.join("#{@gemhome}2", "bin", 'executable') + assert_path_exists installed_exec + assert_equal mask, File.stat(installed_exec).mode unless win_platform? + + wrapper = File.read installed_exec + assert_match %r|generated by RubyGems|, wrapper + end + + def test_generate_bin_script_no_execs + util_execless + + @installer.wrappers = true + @installer.generate_bin + + refute_path_exists util_inst_bindir, 'bin dir was created when not needed' + end + + def test_generate_bin_script_no_perms + @installer.wrappers = true + util_make_exec + + Dir.mkdir util_inst_bindir + + if win_platform? + skip('test_generate_bin_script_no_perms skipped on MS Windows') + else + FileUtils.chmod 0000, util_inst_bindir + + assert_raises Gem::FilePermissionError do + @installer.generate_bin + end + end + ensure + FileUtils.chmod 0755, util_inst_bindir unless ($DEBUG or win_platform?) + end + + def test_generate_bin_script_no_shebang + @installer.wrappers = true + @spec.executables = %w[executable] + + gem_dir = File.join @gemhome, 'gems', @spec.full_name + gem_bindir = File.join gem_dir, 'bin' + FileUtils.mkdir_p gem_bindir + File.open File.join(gem_bindir, 'executable'), 'w' do |f| + f.puts "blah blah blah" + end + + @installer.generate_bin + + installed_exec = File.join @gemhome, 'bin', 'executable' + assert_path_exists installed_exec + assert_equal mask, File.stat(installed_exec).mode unless win_platform? + + wrapper = File.read installed_exec + assert_match %r|generated by RubyGems|, wrapper + # HACK some gems don't have #! in their executables, restore 2008/06 + #assert_no_match %r|generated by RubyGems|, wrapper + end + + def test_generate_bin_script_wrappers + @installer.wrappers = true + util_make_exec + @installer.gem_dir = util_gem_dir + installed_exec = File.join(util_inst_bindir, 'executable') + + real_exec = File.join util_gem_dir, 'bin', 'executable' + + # fake --no-wrappers for previous install + unless Gem.win_platform? then + FileUtils.mkdir_p File.dirname(installed_exec) + FileUtils.ln_s real_exec, installed_exec + end + + @installer.generate_bin + assert_equal true, File.directory?(util_inst_bindir) + assert_path_exists installed_exec + assert_equal mask, File.stat(installed_exec).mode unless win_platform? + + assert_match %r|generated by RubyGems|, File.read(installed_exec) + + refute_match %r|generated by RubyGems|, File.read(real_exec), + 'real executable overwritten' + end + + def test_generate_bin_symlink + return if win_platform? #Windows FS do not support symlinks + + @installer.wrappers = false + util_make_exec + @installer.gem_dir = util_gem_dir + + @installer.generate_bin + assert_equal true, File.directory?(util_inst_bindir) + installed_exec = File.join util_inst_bindir, 'executable' + assert_equal true, File.symlink?(installed_exec) + assert_equal(File.join(util_gem_dir, 'bin', 'executable'), + File.readlink(installed_exec)) + end + + def test_generate_bin_symlink_no_execs + util_execless + + @installer.wrappers = false + @installer.generate_bin + + refute_path_exists util_inst_bindir + end + + def test_generate_bin_symlink_no_perms + @installer.wrappers = false + util_make_exec + @installer.gem_dir = util_gem_dir + + Dir.mkdir util_inst_bindir + + if win_platform? + skip('test_generate_bin_symlink_no_perms skipped on MS Windows') + else + FileUtils.chmod 0000, util_inst_bindir + + assert_raises Gem::FilePermissionError do + @installer.generate_bin + end + end + ensure + FileUtils.chmod 0755, util_inst_bindir unless ($DEBUG or win_platform?) + end + + def test_generate_bin_symlink_update_newer + return if win_platform? #Windows FS do not support symlinks + + @installer.wrappers = false + util_make_exec + @installer.gem_dir = util_gem_dir + + @installer.generate_bin + installed_exec = File.join(util_inst_bindir, 'executable') + assert_equal(File.join(util_gem_dir, 'bin', 'executable'), + File.readlink(installed_exec)) + + @spec = Gem::Specification.new do |s| + s.files = ['lib/code.rb'] + s.name = "a" + s.version = "3" + s.summary = "summary" + s.description = "desc" + s.require_path = 'lib' + end + + util_make_exec + @installer.gem_dir = util_gem_dir @spec + @installer.generate_bin + installed_exec = File.join(util_inst_bindir, 'executable') + assert_equal(@spec.bin_file('executable'), + File.readlink(installed_exec), + "Ensure symlink moved to latest version") + end + + def test_generate_bin_symlink_update_older + return if win_platform? #Windows FS do not support symlinks + + @installer.wrappers = false + util_make_exec + @installer.gem_dir = util_gem_dir + + @installer.generate_bin + installed_exec = File.join(util_inst_bindir, 'executable') + assert_equal(File.join(util_gem_dir, 'bin', 'executable'), + File.readlink(installed_exec)) + + spec = Gem::Specification.new do |s| + s.files = ['lib/code.rb'] + s.name = "a" + s.version = "1" + s.summary = "summary" + s.description = "desc" + s.require_path = 'lib' + end + + util_make_exec + one = @spec.dup + one.version = 1 + @installer.gem_dir = util_gem_dir one + @installer.spec = spec + + @installer.generate_bin + + installed_exec = File.join util_inst_bindir, 'executable' + expected = File.join util_gem_dir, 'bin', 'executable' + assert_equal(expected, + File.readlink(installed_exec), + "Ensure symlink not moved") + end + + def test_generate_bin_symlink_update_remove_wrapper + return if win_platform? #Windows FS do not support symlinks + + @installer.wrappers = true + util_make_exec + @installer.gem_dir = util_gem_dir + + @installer.generate_bin + + installed_exec = File.join util_inst_bindir, 'executable' + assert_path_exists installed_exec + + @spec = Gem::Specification.new do |s| + s.files = ['lib/code.rb'] + s.name = "a" + s.version = "3" + s.summary = "summary" + s.description = "desc" + s.require_path = 'lib' + end + util_make_exec + + util_installer @spec, @gemhome + @installer.wrappers = false + @installer.gem_dir = util_gem_dir + + @installer.generate_bin + + installed_exec = File.join util_inst_bindir, 'executable' + assert_equal(@spec.bin_file('executable'), + File.readlink(installed_exec), + "Ensure symlink moved to latest version") + end + + def test_generate_bin_symlink_win32 + old_win_platform = Gem.win_platform? + Gem.win_platform = true + old_alt_separator = File::ALT_SEPARATOR + File.__send__(:remove_const, :ALT_SEPARATOR) + File.const_set(:ALT_SEPARATOR, '\\') + @installer.wrappers = false + util_make_exec + @installer.gem_dir = util_gem_dir + + use_ui @ui do + @installer.generate_bin + end + + assert_equal true, File.directory?(util_inst_bindir) + installed_exec = File.join(util_inst_bindir, 'executable') + assert_path_exists installed_exec + + assert_match(/Unable to use symlinks on Windows, installing wrapper/i, + @ui.error) + + wrapper = File.read installed_exec + assert_match(/generated by RubyGems/, wrapper) + ensure + File.__send__(:remove_const, :ALT_SEPARATOR) + File.const_set(:ALT_SEPARATOR, old_alt_separator) + Gem.win_platform = old_win_platform + end + + def test_generate_bin_uses_default_shebang + return if win_platform? #Windows FS do not support symlinks + + @installer.wrappers = true + util_make_exec + + @installer.generate_bin + + default_shebang = Gem.ruby + shebang_line = open("#{@gemhome}/bin/executable") { |f| f.readlines.first } + assert_match(/\A#!/, shebang_line) + assert_match(/#{default_shebang}/, shebang_line) + end + + def test_initialize + spec = util_spec 'a' do |s| s.platform = Gem::Platform.new 'mswin32' end + gem = File.join @tempdir, spec.file_name + + Dir.mkdir util_inst_bindir + util_build_gem spec + FileUtils.mv spec.cache_file, @tempdir + + installer = Gem::Installer.new gem + + assert_equal File.join(@gemhome, 'gems', spec.full_name), installer.gem_dir + assert_equal File.join(@gemhome, 'bin'), installer.bin_dir + end + + def test_initialize_user_install + installer = Gem::Installer.new @gem, :user_install => true + + assert_equal File.join(Gem.user_dir, 'gems', @spec.full_name), + installer.gem_dir + assert_equal Gem.bindir(Gem.user_dir), installer.bin_dir + end + + def test_initialize_user_install_bin_dir + installer = + Gem::Installer.new @gem, :user_install => true, :bin_dir => @tempdir + + assert_equal File.join(Gem.user_dir, 'gems', @spec.full_name), + installer.gem_dir + assert_equal @tempdir, installer.bin_dir + end + + def test_install + Dir.mkdir util_inst_bindir + util_setup_gem + util_clear_gems + + gemdir = File.join @gemhome, 'gems', @spec.full_name + cache_file = File.join @gemhome, 'cache', @spec.file_name + stub_exe = File.join @gemhome, 'bin', 'executable' + rakefile = File.join gemdir, 'ext', 'a', 'Rakefile' + spec_file = File.join @gemhome, 'specifications', @spec.spec_name + + Gem.pre_install do |installer| + refute_path_exists cache_file, 'cache file must not exist yet' + refute_path_exists spec_file, 'spec file must not exist yet' + true + end + + Gem.post_build do |installer| + assert_path_exists gemdir, 'gem install dir must exist' + assert_path_exists rakefile, 'gem executable must exist' + refute_path_exists stub_exe, 'gem executable must not exist' + refute_path_exists spec_file, 'spec file must not exist yet' + true + end + + Gem.post_install do |installer| + assert_path_exists cache_file, 'cache file must exist' + assert_path_exists spec_file, 'spec file must exist' + end + + @newspec = nil + build_rake_in do + use_ui @ui do + @newspec = @installer.install + end + end + + assert_equal @spec, @newspec + assert_path_exists gemdir + assert_path_exists stub_exe, 'gem executable must exist' + + exe = File.join gemdir, 'bin', 'executable' + assert_path_exists exe + + exe_mode = File.stat(exe).mode & 0111 + assert_equal 0111, exe_mode, "0%o" % exe_mode unless win_platform? + + assert_path_exists File.join gemdir, 'lib', 'code.rb' + + assert_path_exists rakefile + + spec_file = File.join(@gemhome, 'specifications', @spec.spec_name) + + assert_equal spec_file, @newspec.loaded_from + assert_path_exists spec_file + + assert_same @installer, @post_build_hook_arg + assert_same @installer, @post_install_hook_arg + assert_same @installer, @pre_install_hook_arg + end + + def test_install_creates_working_binstub + Dir.mkdir util_inst_bindir + util_setup_gem + util_clear_gems + + @installer.wrappers = true + + gemdir = File.join @gemhome, 'gems', @spec.full_name + + @newspec = nil + build_rake_in do + use_ui @ui do + @newspec = @installer.install + end + end + + exe = File.join gemdir, 'bin', 'executable' + + e = assert_raises RuntimeError do + instance_eval File.read(exe) + end + + assert_match(/ran executable/, e.message) + end + + def test_install_creates_binstub_that_understand_version + Dir.mkdir util_inst_bindir + util_setup_gem + util_clear_gems + + @installer.wrappers = true + + @newspec = nil + build_rake_in do + use_ui @ui do + @newspec = @installer.install + end + end + + exe = File.join @gemhome, 'bin', 'executable' + + ARGV.unshift "_3.0_" + + begin + Gem::Specification.reset + + e = assert_raises Gem::LoadError do + instance_eval File.read(exe) + end + ensure + ARGV.shift if ARGV.first == "_3.0_" + end + + assert_match(/\(= 3\.0\)/, e.message) + end + + def test_install_creates_binstub_that_dont_trust_encoding + skip unless "".respond_to?(:force_encoding) + + Dir.mkdir util_inst_bindir + util_setup_gem + util_clear_gems + + @installer.wrappers = true + + @newspec = nil + build_rake_in do + use_ui @ui do + @newspec = @installer.install + end + end + + exe = File.join @gemhome, 'bin', 'executable' + + extra_arg = "\xE4pfel".force_encoding("UTF-8") + ARGV.unshift extra_arg + + begin + Gem::Specification.reset + + e = assert_raises RuntimeError do + instance_eval File.read(exe) + end + ensure + ARGV.shift if ARGV.first == extra_arg + end + + assert_match(/ran executable/, e.message) + end + + def test_install_with_no_prior_files + Dir.mkdir util_inst_bindir + util_clear_gems + + util_setup_gem + build_rake_in do + use_ui @ui do + assert_equal @spec, @installer.install + end + end + + gemdir = File.join(@gemhome, 'gems', @spec.full_name) + assert_path_exists File.join gemdir, 'lib', 'code.rb' + + util_setup_gem + # Morph spec to have lib/other.rb instead of code.rb and recreate + @spec.files = File.join('lib', 'other.rb') + Dir.chdir @tempdir do + File.open File.join('lib', 'other.rb'), 'w' do |f| f.puts '1' end + use_ui ui do + FileUtils.rm @gem + Gem::Package.build @spec + end + end + @installer = Gem::Installer.new @gem + build_rake_in do + use_ui @ui do + assert_equal @spec, @installer.install + end + end + + assert_path_exists File.join gemdir, 'lib', 'other.rb' + refute_path_exists File.join gemdir, 'lib', 'code.rb', + "code.rb from prior install of same gem shouldn't remain here" + end + + def test_install_force + use_ui @ui do + installer = Gem::Installer.new old_ruby_required, :force => true + installer.install + end + + gem_dir = File.join(@gemhome, 'gems', 'old_ruby_required-1') + assert_path_exists gem_dir + end + + def test_install_missing_dirs + FileUtils.rm_f File.join(Gem.dir, 'cache') + FileUtils.rm_f File.join(Gem.dir, 'docs') + FileUtils.rm_f File.join(Gem.dir, 'specifications') + + use_ui @ui do + @installer.install + end + + File.directory? File.join(Gem.dir, 'cache') + File.directory? File.join(Gem.dir, 'docs') + File.directory? File.join(Gem.dir, 'specifications') + + assert_path_exists File.join @gemhome, 'cache', @spec.file_name + assert_path_exists File.join @gemhome, 'specifications', @spec.spec_name + end + + def test_install_post_build_false + util_clear_gems + + Gem.post_build do + false + end + + use_ui @ui do + e = assert_raises Gem::InstallError do + @installer.install + end + + location = "#{__FILE__}:#{__LINE__ - 9}" + + assert_equal "post-build hook at #{location} failed for a-2", e.message + end + + spec_file = File.join @gemhome, 'specifications', @spec.spec_name + refute_path_exists spec_file + + gem_dir = File.join @gemhome, 'gems', @spec.full_name + refute_path_exists gem_dir + end + + def test_install_post_build_nil + util_clear_gems + + Gem.post_build do + nil + end + + use_ui @ui do + @installer.install + end + + spec_file = File.join @gemhome, 'specifications', @spec.spec_name + assert_path_exists spec_file + + gem_dir = File.join @gemhome, 'gems', @spec.full_name + assert_path_exists gem_dir + end + + def test_install_pre_install_false + util_clear_gems + + Gem.pre_install do + false + end + + use_ui @ui do + e = assert_raises Gem::InstallError do + @installer.install + end + + location = "#{__FILE__}:#{__LINE__ - 9}" + + assert_equal "pre-install hook at #{location} failed for a-2", e.message + end + + spec_file = File.join @gemhome, 'specifications', @spec.spec_name + refute_path_exists spec_file + end + + def test_install_pre_install_nil + util_clear_gems + + Gem.pre_install do + nil + end + + use_ui @ui do + @installer.install + end + + spec_file = File.join @gemhome, 'specifications', @spec.spec_name + assert_path_exists spec_file + end + + def test_install_with_message + @spec.post_install_message = 'I am a shiny gem!' + + use_ui @ui do + path = Gem::Package.build @spec + + @installer = Gem::Installer.new path + @installer.install + end + + assert_match %r|I am a shiny gem!|, @ui.output + end + + def test_install_extension_dir + gemhome2 = "#{@gemhome}2" + + @spec.extensions << "extconf.rb" + write_file File.join(@tempdir, "extconf.rb") do |io| + io.write <<-RUBY + require "mkmf" + create_makefile("#{@spec.name}") + RUBY + end + + @spec.files += %w[extconf.rb] + + use_ui @ui do + path = Gem::Package.build @spec + + installer = Gem::Installer.new path, :install_dir => gemhome2 + installer.install + end + + expected_makefile = File.join gemhome2, 'gems', @spec.full_name, 'Makefile' + + assert_path_exists expected_makefile + end + + def test_install_extension_and_script + @spec.extensions << "extconf.rb" + write_file File.join(@tempdir, "extconf.rb") do |io| + io.write <<-RUBY + require "mkmf" + create_makefile("#{@spec.name}") + RUBY + end + + rb = File.join("lib", "#{@spec.name}.rb") + @spec.files += [rb] + write_file File.join(@tempdir, rb) do |io| + io.write <<-RUBY + # #{@spec.name}.rb + RUBY + end + + Dir.mkdir(File.join("lib", @spec.name)) + rb2 = File.join("lib", @spec.name, "#{@spec.name}.rb") + @spec.files << rb2 + write_file File.join(@tempdir, rb2) do |io| + io.write <<-RUBY + # #{@spec.name}/#{@spec.name}.rb + RUBY + end + + refute_path_exists File.join @spec.gem_dir, rb + refute_path_exists File.join @spec.gem_dir, rb2 + use_ui @ui do + path = Gem::Package.build @spec + + @installer = Gem::Installer.new path + @installer.install + end + assert_path_exists File.join @spec.gem_dir, rb + assert_path_exists File.join @spec.gem_dir, rb2 + end + + def test_install_extension_flat + skip '1.9.2 and earlier mkmf.rb does not create TOUCH' if + RUBY_VERSION < '1.9.3' + + if RUBY_VERSION == "1.9.3" and RUBY_PATCHLEVEL <= 194 + skip "TOUCH was introduced into 1.9.3 after p194" + end + + @spec.require_paths = ["."] + + @spec.extensions << "extconf.rb" + + write_file File.join(@tempdir, "extconf.rb") do |io| + io.write <<-RUBY + require "mkmf" + + CONFIG['CC'] = '$(TOUCH) $@ ||' + CONFIG['LDSHARED'] = '$(TOUCH) $@ ||' + $ruby = '#{Gem.ruby}' + + create_makefile("#{@spec.name}") + RUBY + end + + # empty depend file for no auto dependencies + @spec.files += %W"depend #{@spec.name}.c".each {|file| + write_file File.join(@tempdir, file) + } + + so = File.join(@spec.gem_dir, "#{@spec.name}.#{RbConfig::CONFIG["DLEXT"]}") + refute_path_exists so + use_ui @ui do + path = Gem::Package.build @spec + + @installer = Gem::Installer.new path + @installer.install + end + assert_path_exists so + rescue + puts '-' * 78 + puts File.read File.join(@gemhome, 'gems', 'a-2', 'Makefile') + puts '-' * 78 + + path = File.join(@gemhome, 'gems', 'a-2', 'gem_make.out') + + if File.exist?(path) + puts File.read(path) + puts '-' * 78 + end + + raise + end + + def test_installation_satisfies_dependency_eh + util_spec 'a' + + dep = Gem::Dependency.new 'a', '>= 2' + assert @installer.installation_satisfies_dependency?(dep) + + dep = Gem::Dependency.new 'a', '> 2' + refute @installer.installation_satisfies_dependency?(dep) + end + + def test_installation_satisfies_dependency_eh_development + @installer.options[:development] = true + @installer.options[:dev_shallow] = true + + util_spec 'a' + + dep = Gem::Dependency.new 'a', :development + assert @installer.installation_satisfies_dependency?(dep) + end + + def test_pre_install_checks_dependencies + @spec.add_dependency 'b', '> 5' + util_setup_gem + + use_ui @ui do + assert_raises Gem::InstallError do + @installer.install + end + end + end + + def test_pre_install_checks_dependencies_ignore + @spec.add_dependency 'b', '> 5' + @installer.ignore_dependencies = true + + build_rake_in do + use_ui @ui do + assert @installer.pre_install_checks + end + end + end + + def test_pre_install_checks_dependencies_install_dir + gemhome2 = "#{@gemhome}2" + @spec.add_dependency 'd' + + quick_gem 'd', 2 + + gem = File.join @gemhome, @spec.file_name + + FileUtils.mv @gemhome, gemhome2 + FileUtils.mkdir @gemhome + + FileUtils.mv File.join(gemhome2, 'cache', @spec.file_name), gem + + # Don't leak any already activated gems into the installer, require + # that it work everything out on it's own. + Gem::Specification.reset + + installer = Gem::Installer.new gem, :install_dir => gemhome2 + + build_rake_in do + use_ui @ui do + assert installer.pre_install_checks + end + end + end + + def test_pre_install_checks_ruby_version + use_ui @ui do + installer = Gem::Installer.new old_ruby_required + e = assert_raises Gem::InstallError do + installer.pre_install_checks + end + assert_equal 'old_ruby_required requires Ruby version = 1.4.6.', + e.message + end + end + + def test_pre_install_checks_wrong_rubygems_version + spec = util_spec 'old_rubygems_required', '1' do |s| + s.required_rubygems_version = '< 0' + end + + util_build_gem spec + + gem = File.join(@gemhome, 'cache', spec.file_name) + + use_ui @ui do + @installer = Gem::Installer.new gem + e = assert_raises Gem::InstallError do + @installer.pre_install_checks + end + assert_equal 'old_rubygems_required requires RubyGems version < 0. ' + + "Try 'gem update --system' to update RubyGems itself.", e.message + end + end + + def test_shebang + util_make_exec @spec, "#!/usr/bin/ruby" + + shebang = @installer.shebang 'executable' + + assert_equal "#!#{Gem.ruby}", shebang + end + + def test_process_options + assert_nil @installer.build_root + assert_equal File.join(@gemhome, 'bin'), @installer.bin_dir + assert_equal @gemhome, @installer.gem_home + end + + def test_process_options_build_root + build_root = File.join @tempdir, 'build_root' + + @installer = Gem::Installer.new @gem, :build_root => build_root + + assert_equal Pathname(build_root), @installer.build_root + assert_equal File.join(build_root, @gemhome, 'bin'), @installer.bin_dir + assert_equal File.join(build_root, @gemhome), @installer.gem_home + end + + def test_shebang_arguments + util_make_exec @spec, "#!/usr/bin/ruby -ws" + + shebang = @installer.shebang 'executable' + + assert_equal "#!#{Gem.ruby} -ws", shebang + end + + def test_shebang_empty + util_make_exec @spec, '' + + shebang = @installer.shebang 'executable' + assert_equal "#!#{Gem.ruby}", shebang + end + + def test_shebang_env + util_make_exec @spec, "#!/usr/bin/env ruby" + + shebang = @installer.shebang 'executable' + + assert_equal "#!#{Gem.ruby}", shebang + end + + def test_shebang_env_arguments + util_make_exec @spec, "#!/usr/bin/env ruby -ws" + + shebang = @installer.shebang 'executable' + + assert_equal "#!#{Gem.ruby} -ws", shebang + end + + def test_shebang_env_shebang + util_make_exec @spec, '' + @installer.env_shebang = true + + shebang = @installer.shebang 'executable' + + env_shebang = "/usr/bin/env" unless Gem.win_platform? + + assert_equal("#!#{env_shebang} #{RbConfig::CONFIG['ruby_install_name']}", + shebang) + end + + def test_shebang_nested + util_make_exec @spec, "#!/opt/local/ruby/bin/ruby" + + shebang = @installer.shebang 'executable' + + assert_equal "#!#{Gem.ruby}", shebang + end + + def test_shebang_nested_arguments + util_make_exec @spec, "#!/opt/local/ruby/bin/ruby -ws" + + shebang = @installer.shebang 'executable' + + assert_equal "#!#{Gem.ruby} -ws", shebang + end + + def test_shebang_version + util_make_exec @spec, "#!/usr/bin/ruby18" + + shebang = @installer.shebang 'executable' + + assert_equal "#!#{Gem.ruby}", shebang + end + + def test_shebang_version_arguments + util_make_exec @spec, "#!/usr/bin/ruby18 -ws" + + shebang = @installer.shebang 'executable' + + assert_equal "#!#{Gem.ruby} -ws", shebang + end + + def test_shebang_version_env + util_make_exec @spec, "#!/usr/bin/env ruby18" + + shebang = @installer.shebang 'executable' + + assert_equal "#!#{Gem.ruby}", shebang + end + + def test_shebang_version_env_arguments + util_make_exec @spec, "#!/usr/bin/env ruby18 -ws" + + shebang = @installer.shebang 'executable' + + assert_equal "#!#{Gem.ruby} -ws", shebang + end + + def test_shebang_custom + conf = Gem::ConfigFile.new [] + conf[:custom_shebang] = 'test' + + Gem.configuration = conf + + util_make_exec @spec, "#!/usr/bin/ruby" + + shebang = @installer.shebang 'executable' + + assert_equal "#!test", shebang + end + + def test_shebang_custom_with_expands + bin_env = win_platform? ? '' : '/usr/bin/env' + conf = Gem::ConfigFile.new [] + conf[:custom_shebang] = '1 $env 2 $ruby 3 $exec 4 $name' + + Gem.configuration = conf + + util_make_exec @spec, "#!/usr/bin/ruby" + + shebang = @installer.shebang 'executable' + + assert_equal "#!1 #{bin_env} 2 #{Gem.ruby} 3 executable 4 a", shebang + end + + def test_shebang_custom_with_expands_and_arguments + bin_env = win_platform? ? '' : '/usr/bin/env' + conf = Gem::ConfigFile.new [] + conf[:custom_shebang] = '1 $env 2 $ruby 3 $exec' + + Gem.configuration = conf + + util_make_exec @spec, "#!/usr/bin/ruby -ws" + + shebang = @installer.shebang 'executable' + + assert_equal "#!1 #{bin_env} 2 #{Gem.ruby} -ws 3 executable", shebang + end + + def test_unpack + util_setup_gem + + dest = File.join @gemhome, 'gems', @spec.full_name + + @installer.unpack dest + + assert_path_exists File.join dest, 'lib', 'code.rb' + assert_path_exists File.join dest, 'bin', 'executable' + end + + def test_write_build_info_file + refute_path_exists @spec.build_info_file + + @installer.build_args = %w[ + --with-libyaml-dir /usr/local/Cellar/libyaml/0.1.4 + ] + + @installer.write_build_info_file + + assert_path_exists @spec.build_info_file + + expected = "--with-libyaml-dir\n/usr/local/Cellar/libyaml/0.1.4\n" + + assert_equal expected, File.read(@spec.build_info_file) + end + + def test_write_build_info_file_empty + refute_path_exists @spec.build_info_file + + @installer.write_build_info_file + + refute_path_exists @spec.build_info_file + end + + def test_write_build_info_file_install_dir + installer = Gem::Installer.new @gem, :install_dir => "#{@gemhome}2" + + installer.build_args = %w[ + --with-libyaml-dir /usr/local/Cellar/libyaml/0.1.4 + ] + + installer.write_build_info_file + + refute_path_exists @spec.build_info_file + assert_path_exists \ + File.join("#{@gemhome}2", 'build_info', "#{@spec.full_name}.info") + end + + def test_write_cache_file + cache_file = File.join @gemhome, 'cache', @spec.file_name + gem = File.join @gemhome, @spec.file_name + + FileUtils.mv cache_file, gem + refute_path_exists cache_file + + installer = Gem::Installer.new gem + installer.spec = @spec + installer.gem_home = @gemhome + + installer.write_cache_file + + assert_path_exists cache_file + end + + def test_write_spec + FileUtils.rm @spec.spec_file + refute_path_exists @spec.spec_file + + @installer.spec = @spec + @installer.gem_home = @gemhome + + @installer.write_spec + + assert_path_exists @spec.spec_file + + loaded = Gem::Specification.load @spec.spec_file + + assert_equal @spec, loaded + + assert_equal Gem.rubygems_version, @spec.installed_by_version + end + + def test_write_spec_writes_cached_spec + FileUtils.rm @spec.spec_file + refute_path_exists @spec.spec_file + + @spec.files = %w[a.rb b.rb c.rb] + + @installer.spec = @spec + @installer.gem_home = @gemhome + + @installer.write_spec + + # cached specs have no file manifest: + @spec.files = [] + + assert_equal @spec, eval(File.read(@spec.spec_file)) + end + + def test_dir + assert_match %r!/gemhome/gems/a-2$!, @installer.dir + end + + def test_default_gem + FileUtils.rm_f File.join(Gem.dir, 'specifications') + + @installer.wrappers = true + @installer.options[:install_as_default] = true + @installer.gem_dir = util_gem_dir @spec + @installer.generate_bin + + use_ui @ui do + @installer.install + end + + assert File.directory? util_inst_bindir + installed_exec = File.join util_inst_bindir, 'executable' + assert_path_exists installed_exec + + assert File.directory? File.join(Gem.dir, 'specifications') + assert File.directory? File.join(Gem.dir, 'specifications', 'default') + + default_spec = eval File.read File.join(Gem.dir, 'specifications', 'default', 'a-2.gemspec') + assert_equal Gem::Version.new("2"), default_spec.version + assert_equal ['bin/executable'], default_spec.files + end + + def old_ruby_required + spec = util_spec 'old_ruby_required', '1' do |s| + s.required_ruby_version = '= 1.4.6' + end + + util_build_gem spec + + spec.cache_file + end + + def util_execless + @spec = util_spec 'z' + util_build_gem @spec + + @installer = util_installer @spec, @gemhome + end + + def util_conflict_executable wrappers + conflict = quick_gem 'conflict' do |spec| + util_make_exec spec + end + + util_build_gem conflict + + installer = util_installer conflict, @gemhome + installer.wrappers = wrappers + installer.generate_bin + end + + def mask + 0100755 & (~File.umask) + end +end diff --git a/jni/ruby/test/rubygems/test_gem_local_remote_options.rb b/jni/ruby/test/rubygems/test_gem_local_remote_options.rb new file mode 100644 index 0000000..1a0338b --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_local_remote_options.rb @@ -0,0 +1,133 @@ +require 'rubygems/test_case' +require 'rubygems/local_remote_options' +require 'rubygems/command' + +class TestGemLocalRemoteOptions < Gem::TestCase + + def setup + super + + @cmd = Gem::Command.new 'dummy', 'dummy' + @cmd.extend Gem::LocalRemoteOptions + end + + def test_add_local_remote_options + @cmd.add_local_remote_options + + args = %w[-l -r -b -B 10 --source http://gems.example.com -p --update-sources] + assert @cmd.handles?(args) + end + + def test_both_eh + assert_equal false, @cmd.both? + + @cmd.options[:domain] = :local + + assert_equal false, @cmd.both? + + @cmd.options[:domain] = :both + + assert_equal true, @cmd.both? + end + + def test_clear_sources_option + @cmd.add_local_remote_options + + s = URI.parse "http://only-gems.example.com/" + + @cmd.handle_options %W[--clear-sources --source #{s}] + assert_equal [s.to_s], Gem.sources + end + + def test_clear_sources_option_idiot_proof + spec_fetcher + + @cmd.add_local_remote_options + @cmd.handle_options %W[--clear-sources] + assert_equal Gem.default_sources, Gem.sources + end + + def test_local_eh + assert_equal false, @cmd.local? + + @cmd.options[:domain] = :local + + assert_equal true, @cmd.local? + + @cmd.options[:domain] = :both + + assert_equal true, @cmd.local? + end + + def test_remote_eh + assert_equal false, @cmd.remote? + + @cmd.options[:domain] = :remote + + assert_equal true, @cmd.remote? + + @cmd.options[:domain] = :both + + assert_equal true, @cmd.remote? + end + + def test_source_option + @cmd.add_source_option + + s1 = URI.parse 'http://more-gems.example.com/' + s2 = URI.parse 'http://even-more-gems.example.com/' + s3 = URI.parse 'http://other-gems.example.com/some_subdir' + s4 = URI.parse 'http://more-gems.example.com/' # Intentional duplicate + + original_sources = Gem.sources.dup + + @cmd.handle_options %W[--source #{s1} --source #{s2} --source #{s3} --source #{s4}] + + original_sources << s1.to_s + original_sources << s2.to_s + original_sources << "#{s3}/" + + assert_equal original_sources, Gem.sources + end + + def test_short_source_option + @cmd.add_source_option + + original_sources = Gem.sources.dup + + source = URI.parse 'http://more-gems.example.com/' + @cmd.handle_options %W[-s #{source}] + + original_sources << source + + assert_equal original_sources, Gem.sources + end + + def test_update_sources_option + @cmd.add_update_sources_option + + Gem.configuration.update_sources = false + + @cmd.handle_options %W[--update-sources] + + assert_equal true, Gem.configuration.update_sources + + @cmd.handle_options %W[--no-update-sources] + + assert_equal false, Gem.configuration.update_sources + end + + def test_source_option_bad + @cmd.add_source_option + + s1 = 'htp://more-gems.example.com' + + assert_raises OptionParser::InvalidArgument do + @cmd.handle_options %W[--source #{s1}] + end + + assert_equal [@gem_repo], Gem.sources + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_name_tuple.rb b/jni/ruby/test/rubygems/test_gem_name_tuple.rb new file mode 100644 index 0000000..38320f7 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_name_tuple.rb @@ -0,0 +1,44 @@ +require 'rubygems/test_case' +require 'rubygems/name_tuple' + +class TestGemNameTuple < Gem::TestCase + + def test_full_name + n = Gem::NameTuple.new "a", Gem::Version.new(0), "ruby" + assert_equal "a-0", n.full_name + + n = Gem::NameTuple.new "a", Gem::Version.new(0), nil + assert_equal "a-0", n.full_name + + n = Gem::NameTuple.new "a", Gem::Version.new(0), "" + assert_equal "a-0", n.full_name + + n = Gem::NameTuple.new "a", Gem::Version.new(0), "other" + assert_equal "a-0-other", n.full_name + end + + def test_platform_normalization + n = Gem::NameTuple.new "a", Gem::Version.new(0), "ruby" + assert_equal "ruby", n.platform + + n = Gem::NameTuple.new "a", Gem::Version.new(0), nil + assert_equal "ruby", n.platform + + n = Gem::NameTuple.new "a", Gem::Version.new(0), "" + assert_equal "ruby", n.platform + end + + def test_spec_name + n = Gem::NameTuple.new "a", Gem::Version.new(0), "ruby" + assert_equal "a-0.gemspec", n.spec_name + end + + def test_spaceship + a = Gem::NameTuple.new 'a', Gem::Version.new(0), Gem::Platform::RUBY + a_p = Gem::NameTuple.new 'a', Gem::Version.new(0), Gem::Platform.local + + assert_equal 1, a_p.<=>(a) + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_package.rb b/jni/ruby/test/rubygems/test_gem_package.rb new file mode 100644 index 0000000..128dcdb --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_package.rb @@ -0,0 +1,824 @@ +# coding: UTF-8 + +require 'rubygems/package/tar_test_case' +require 'rubygems/simple_gem' + +class TestGemPackage < Gem::Package::TarTestCase + + def setup + super + + @spec = quick_gem 'a' do |s| + s.description = 'π' + s.files = %w[lib/code.rb] + end + + util_build_gem @spec + + @gem = @spec.cache_file + + @destination = File.join @tempdir, 'extract' + + FileUtils.mkdir_p @destination + end + + def test_class_new_old_format + open 'old_format.gem', 'wb' do |io| + io.write SIMPLE_GEM + end + + package = Gem::Package.new 'old_format.gem' + + assert package.spec + end + + def test_add_checksums + gem_io = StringIO.new + + spec = Gem::Specification.new 'build', '1' + spec.summary = 'build' + spec.authors = 'build' + spec.files = ['lib/code.rb'] + spec.date = Time.at 0 + spec.rubygems_version = Gem::Version.new '0' + + FileUtils.mkdir 'lib' + + open 'lib/code.rb', 'w' do |io| + io.write '# lib/code.rb' + end + + package = Gem::Package.new spec.file_name + package.spec = spec + package.build_time = 1 # 0 uses current time + package.setup_signer + + Gem::Package::TarWriter.new gem_io do |gem| + package.add_metadata gem + package.add_contents gem + package.add_checksums gem + end + + gem_io.rewind + + reader = Gem::Package::TarReader.new gem_io + + checksums = nil + tar = nil + + reader.each_entry do |entry| + case entry.full_name + when 'checksums.yaml.gz' then + Zlib::GzipReader.wrap entry do |io| + checksums = io.read + end + when 'data.tar.gz' then + tar = entry.read + end + end + + s = StringIO.new + + package.gzip_to s do |io| + io.write spec.to_yaml + end + + metadata_sha1 = Digest::SHA1.hexdigest s.string + metadata_sha512 = Digest::SHA512.hexdigest s.string + + expected = { + 'SHA512' => { + 'metadata.gz' => metadata_sha512, + 'data.tar.gz' => Digest::SHA512.hexdigest(tar), + } + } + + if defined?(OpenSSL::Digest) then + expected['SHA1'] = { + 'metadata.gz' => metadata_sha1, + 'data.tar.gz' => Digest::SHA1.hexdigest(tar), + } + end + + assert_equal expected, YAML.load(checksums) + end + + def test_add_files + spec = Gem::Specification.new + spec.files = %w[lib/code.rb lib/empty] + + FileUtils.mkdir_p 'lib/empty' + + open 'lib/code.rb', 'w' do |io| io.write '# lib/code.rb' end + open 'lib/extra.rb', 'w' do |io| io.write '# lib/extra.rb' end + + package = Gem::Package.new 'bogus.gem' + package.spec = spec + + tar = util_tar do |tar_io| + package.add_files tar_io + end + + tar.rewind + + files = [] + + Gem::Package::TarReader.new tar do |tar_io| + tar_io.each_entry do |entry| + files << entry.full_name + end + end + + assert_equal %w[lib/code.rb], files + end + + def test_build + spec = Gem::Specification.new 'build', '1' + spec.summary = 'build' + spec.authors = 'build' + spec.files = ['lib/code.rb'] + spec.rubygems_version = :junk + + FileUtils.mkdir 'lib' + + open 'lib/code.rb', 'w' do |io| + io.write '# lib/code.rb' + end + + package = Gem::Package.new spec.file_name + package.spec = spec + + package.build + + assert_equal Gem::VERSION, spec.rubygems_version + assert_path_exists spec.file_name + + reader = Gem::Package.new spec.file_name + assert_equal spec, reader.spec + + assert_equal %w[metadata.gz data.tar.gz checksums.yaml.gz], + reader.files + + assert_equal %w[lib/code.rb], reader.contents + end + + def test_build_auto_signed + skip 'openssl is missing' unless defined?(OpenSSL::SSL) + + 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' + FileUtils.cp PUBLIC_CERT_PATH, public_cert_path + + spec = Gem::Specification.new 'build', '1' + spec.summary = 'build' + spec.authors = 'build' + spec.files = ['lib/code.rb'] + + FileUtils.mkdir 'lib' + + open 'lib/code.rb', 'w' do |io| + io.write '# lib/code.rb' + end + + package = Gem::Package.new spec.file_name + package.spec = spec + + package.build + + assert_equal Gem::VERSION, spec.rubygems_version + assert_path_exists spec.file_name + + reader = Gem::Package.new spec.file_name + assert reader.verify + + assert_equal [PUBLIC_CERT.to_pem], reader.spec.cert_chain + + assert_equal %w[metadata.gz metadata.gz.sig + data.tar.gz data.tar.gz.sig + checksums.yaml.gz checksums.yaml.gz.sig], + reader.files + + assert_equal %w[lib/code.rb], reader.contents + end + + def test_build_auto_signed_encrypted_key + skip 'openssl is missing' unless defined?(OpenSSL::SSL) + + FileUtils.mkdir_p File.join(Gem.user_home, '.gem') + + private_key_path = File.join Gem.user_home, '.gem', 'gem-private_key.pem' + FileUtils.cp ENCRYPTED_PRIVATE_KEY_PATH, private_key_path + + public_cert_path = File.join Gem.user_home, '.gem', 'gem-public_cert.pem' + Gem::Security.write PUBLIC_CERT, public_cert_path + + spec = Gem::Specification.new 'build', '1' + spec.summary = 'build' + spec.authors = 'build' + spec.files = ['lib/code.rb'] + + FileUtils.mkdir 'lib' + + open 'lib/code.rb', 'w' do |io| + io.write '# lib/code.rb' + end + + package = Gem::Package.new spec.file_name + package.spec = spec + + package.build + + assert_equal Gem::VERSION, spec.rubygems_version + assert_path_exists spec.file_name + + reader = Gem::Package.new spec.file_name + assert reader.verify + + assert_equal [PUBLIC_CERT.to_pem], reader.spec.cert_chain + + assert_equal %w[metadata.gz metadata.gz.sig + data.tar.gz data.tar.gz.sig + checksums.yaml.gz checksums.yaml.gz.sig], + reader.files + + assert_equal %w[lib/code.rb], reader.contents + end + + def test_build_invalid + spec = Gem::Specification.new 'build', '1' + + package = Gem::Package.new spec.file_name + package.spec = spec + + e = assert_raises Gem::InvalidSpecificationException do + package.build + end + + assert_equal 'missing value for attribute summary', e.message + end + + def test_build_signed + skip 'openssl is missing' unless defined?(OpenSSL::SSL) + + spec = Gem::Specification.new 'build', '1' + spec.summary = 'build' + spec.authors = 'build' + spec.files = ['lib/code.rb'] + spec.cert_chain = [PUBLIC_CERT.to_pem] + spec.signing_key = PRIVATE_KEY + + FileUtils.mkdir 'lib' + + open 'lib/code.rb', 'w' do |io| + io.write '# lib/code.rb' + end + + package = Gem::Package.new spec.file_name + package.spec = spec + + package.build + + assert_equal Gem::VERSION, spec.rubygems_version + assert_path_exists spec.file_name + + reader = Gem::Package.new spec.file_name + assert reader.verify + + assert_equal spec, reader.spec + + assert_equal %w[metadata.gz metadata.gz.sig + data.tar.gz data.tar.gz.sig + checksums.yaml.gz checksums.yaml.gz.sig], + reader.files + + assert_equal %w[lib/code.rb], reader.contents + end + + def test_build_signed_encryped_key + skip 'openssl is missing' unless defined?(OpenSSL::SSL) + + spec = Gem::Specification.new 'build', '1' + spec.summary = 'build' + spec.authors = 'build' + spec.files = ['lib/code.rb'] + spec.cert_chain = [PUBLIC_CERT.to_pem] + spec.signing_key = ENCRYPTED_PRIVATE_KEY + + FileUtils.mkdir 'lib' + + open 'lib/code.rb', 'w' do |io| + io.write '# lib/code.rb' + end + + package = Gem::Package.new spec.file_name + package.spec = spec + + package.build + + assert_equal Gem::VERSION, spec.rubygems_version + assert_path_exists spec.file_name + + reader = Gem::Package.new spec.file_name + assert reader.verify + + assert_equal spec, reader.spec + + assert_equal %w[metadata.gz metadata.gz.sig + data.tar.gz data.tar.gz.sig + checksums.yaml.gz checksums.yaml.gz.sig], + reader.files + + assert_equal %w[lib/code.rb], reader.contents + end + + def test_contents + package = Gem::Package.new @gem + + assert_equal %w[lib/code.rb], package.contents + end + + def test_extract_files + package = Gem::Package.new @gem + + package.extract_files @destination + + extracted = File.join @destination, 'lib/code.rb' + assert_path_exists extracted + + mask = 0100666 & (~File.umask) + + assert_equal mask.to_s(8), File.stat(extracted).mode.to_s(8) unless + win_platform? + end + + def test_extract_files_empty + data_tgz = util_tar_gz do end + + gem = util_tar do |tar| + tar.add_file 'data.tar.gz', 0644 do |io| + io.write data_tgz.string + end + + tar.add_file 'metadata.gz', 0644 do |io| + Zlib::GzipWriter.wrap io do |gzio| + gzio.write @spec.to_yaml + end + end + end + + open 'empty.gem', 'wb' do |io| + io.write gem.string + end + + package = Gem::Package.new 'empty.gem' + + package.extract_files @destination + + assert_path_exists @destination + end + + def test_extract_tar_gz_absolute + package = Gem::Package.new @gem + + tgz_io = util_tar_gz do |tar| + tar.add_file '/absolute.rb', 0644 do |io| io.write 'hi' end + end + + e = assert_raises Gem::Package::PathError do + package.extract_tar_gz tgz_io, @destination + end + + assert_equal("installing into parent path /absolute.rb of " + + "#{@destination} is not allowed", e.message) + end + + def test_extract_tar_gz_directory + package = Gem::Package.new @gem + + tgz_io = util_tar_gz do |tar| + tar.mkdir 'lib', 0755 + tar.add_file 'lib/foo.rb', 0644 do |io| io.write 'hi' end + tar.mkdir 'lib/foo', 0755 + end + + package.extract_tar_gz tgz_io, @destination + + extracted = File.join @destination, 'lib/foo.rb' + assert_path_exists extracted + + extracted = File.join @destination, 'lib/foo' + assert_path_exists extracted + end + + def test_extract_tar_gz_dot_slash + package = Gem::Package.new @gem + + tgz_io = util_tar_gz do |tar| + tar.add_file './dot_slash.rb', 0644 do |io| io.write 'hi' end + end + + package.extract_tar_gz tgz_io, @destination + + extracted = File.join @destination, 'dot_slash.rb' + assert_path_exists extracted + end + + def test_extract_tar_gz_dot_file + package = Gem::Package.new @gem + + tgz_io = util_tar_gz do |tar| + tar.add_file '.dot_file.rb', 0644 do |io| io.write 'hi' end + end + + package.extract_tar_gz tgz_io, @destination + + extracted = File.join @destination, '.dot_file.rb' + assert_path_exists extracted + end + + def test_install_location + package = Gem::Package.new @gem + + file = 'file.rb' + file.taint + + destination = package.install_location file, @destination + + assert_equal File.join(@destination, 'file.rb'), destination + refute destination.tainted? + end + + def test_install_location_absolute + package = Gem::Package.new @gem + + e = assert_raises Gem::Package::PathError do + package.install_location '/absolute.rb', @destination + end + + assert_equal("installing into parent path /absolute.rb of " + + "#{@destination} is not allowed", e.message) + end + + def test_install_location_dots + package = Gem::Package.new @gem + + file = 'file.rb' + + destination = File.join @destination, 'foo', '..', 'bar' + + FileUtils.mkdir_p File.join @destination, 'foo' + FileUtils.mkdir_p File.expand_path destination + + destination = package.install_location file, destination + + # this test only fails on ruby missing File.realpath + assert_equal File.join(@destination, 'bar', 'file.rb'), destination + end + + def test_install_location_extra_slash + skip 'no File.realpath on 1.8' if RUBY_VERSION < '1.9' + package = Gem::Package.new @gem + + file = 'foo//file.rb' + file.taint + + destination = @destination.sub '/', '//' + + destination = package.install_location file, destination + + assert_equal File.join(@destination, 'foo', 'file.rb'), destination + refute destination.tainted? + end + + def test_install_location_relative + package = Gem::Package.new @gem + + e = assert_raises Gem::Package::PathError do + package.install_location '../relative.rb', @destination + end + + parent = File.expand_path File.join @destination, "../relative.rb" + + assert_equal("installing into parent path #{parent} of " + + "#{@destination} is not allowed", e.message) + end + + def test_load_spec + entry = StringIO.new Gem.gzip @spec.to_yaml + def entry.full_name() 'metadata.gz' end + + package = Gem::Package.new 'nonexistent.gem' + + spec = package.load_spec entry + + assert_equal @spec, spec + end + + def test_verify + package = Gem::Package.new @gem + + package.verify + + assert_equal @spec, package.spec + assert_equal %w[checksums.yaml.gz data.tar.gz metadata.gz], + package.files.sort + end + + def test_verify_checksum_bad + data_tgz = util_tar_gz do |tar| + tar.add_file 'lib/code.rb', 0444 do |io| + io.write '# lib/code.rb' + end + end + + data_tgz = data_tgz.string + + gem = util_tar do |tar| + metadata_gz = Gem.gzip @spec.to_yaml + + tar.add_file 'metadata.gz', 0444 do |io| + io.write metadata_gz + end + + tar.add_file 'data.tar.gz', 0444 do |io| + io.write data_tgz + end + + bogus_checksums = { + 'SHA1' => { + 'data.tar.gz' => 'bogus', + 'metadata.gz' => 'bogus', + }, + } + tar.add_file 'checksums.yaml.gz', 0444 do |io| + Zlib::GzipWriter.wrap io do |gz_io| + gz_io.write YAML.dump bogus_checksums + end + end + end + + open 'mismatch.gem', 'wb' do |io| + io.write gem.string + end + + package = Gem::Package.new 'mismatch.gem' + + e = assert_raises Gem::Package::FormatError do + package.verify + end + + assert_equal 'SHA1 checksum mismatch for data.tar.gz in mismatch.gem', + e.message + end + + def test_verify_checksum_missing + data_tgz = util_tar_gz do |tar| + tar.add_file 'lib/code.rb', 0444 do |io| + io.write '# lib/code.rb' + end + end + + data_tgz = data_tgz.string + + gem = util_tar do |tar| + metadata_gz = Gem.gzip @spec.to_yaml + + tar.add_file 'metadata.gz', 0444 do |io| + io.write metadata_gz + end + + digest = Digest::SHA1.new + digest << metadata_gz + + checksums = { + 'SHA1' => { + 'metadata.gz' => digest.hexdigest, + }, + } + + tar.add_file 'checksums.yaml.gz', 0444 do |io| + Zlib::GzipWriter.wrap io do |gz_io| + gz_io.write YAML.dump checksums + end + end + + tar.add_file 'data.tar.gz', 0444 do |io| + io.write data_tgz + end + end + + open 'data_checksum_missing.gem', 'wb' do |io| + io.write gem.string + end + + package = Gem::Package.new 'data_checksum_missing.gem' + + assert package.verify + end + + def test_verify_corrupt + tf = Tempfile.open 'corrupt' do |io| + data = Gem.gzip 'a' * 10 + io.write \ + tar_file_header('metadata.gz', "\000x", 0644, data.length, Time.now) + io.write data + io.rewind + + package = Gem::Package.new io.path + + e = assert_raises Gem::Package::FormatError do + package.verify + end + + assert_equal "tar is corrupt, name contains null byte in #{io.path}", + e.message + io + end + tf.close! if tf.respond_to? :close! + end + + def test_verify_empty + FileUtils.touch 'empty.gem' + + package = Gem::Package.new 'empty.gem' + + e = assert_raises Gem::Package::FormatError do + package.verify + end + + assert_equal 'package metadata is missing in empty.gem', e.message + end + + def test_verify_nonexistent + package = Gem::Package.new 'nonexistent.gem' + + e = assert_raises Gem::Package::FormatError do + package.verify + end + + assert_match %r%^No such file or directory%, e.message + assert_match %r%nonexistent.gem$%, e.message + end + + def test_verify_security_policy + skip 'openssl is missing' unless defined?(OpenSSL::SSL) + + package = Gem::Package.new @gem + package.security_policy = Gem::Security::HighSecurity + + e = assert_raises Gem::Security::Exception do + package.verify + end + + assert_equal 'unsigned gems are not allowed by the High Security policy', + e.message + + refute package.instance_variable_get(:@spec), '@spec must not be loaded' + assert_empty package.instance_variable_get(:@files), '@files must empty' + end + + def test_verify_security_policy_low_security + skip 'openssl is missing' unless defined?(OpenSSL::SSL) + + @spec.cert_chain = [PUBLIC_CERT.to_pem] + @spec.signing_key = PRIVATE_KEY + + FileUtils.mkdir_p 'lib' + FileUtils.touch 'lib/code.rb' + + build = Gem::Package.new @gem + build.spec = @spec + + build.build + + package = Gem::Package.new @gem + package.security_policy = Gem::Security::LowSecurity + + assert package.verify + end + + def test_verify_security_policy_checksum_missing + skip 'openssl is missing' unless defined?(OpenSSL::SSL) + + @spec.cert_chain = [PUBLIC_CERT.to_pem] + @spec.signing_key = PRIVATE_KEY + + build = Gem::Package.new @gem + build.spec = @spec + build.setup_signer + + FileUtils.mkdir 'lib' + FileUtils.touch 'lib/code.rb' + + open @gem, 'wb' do |gem_io| + Gem::Package::TarWriter.new gem_io do |gem| + build.add_metadata gem + build.add_contents gem + + # write bogus data.tar.gz to foil signature + bogus_data = Gem.gzip 'hello' + gem.add_file_simple 'data.tar.gz', 0444, bogus_data.length do |io| + io.write bogus_data + end + + # pre rubygems 2.0 gems do not add checksums + end + end + + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + package = Gem::Package.new @gem + package.security_policy = Gem::Security::HighSecurity + + e = assert_raises Gem::Security::Exception do + package.verify + end + + assert_equal 'invalid signature', e.message + + refute package.instance_variable_get(:@spec), '@spec must not be loaded' + assert_empty package.instance_variable_get(:@files), '@files must empty' + end + + def test_verify_truncate + open 'bad.gem', 'wb' do |io| + io.write File.read(@gem, 1024) # don't care about newlines + end + + package = Gem::Package.new 'bad.gem' + + e = assert_raises Gem::Package::FormatError do + package.verify + end + + assert_equal 'package content (data.tar.gz) is missing in bad.gem', + e.message + end + + # end #verify tests + + def test_verify_entry + entry = Object.new + def entry.full_name() raise ArgumentError, 'whatever' end + + package = Gem::Package.new @gem + + e = assert_raises Gem::Package::FormatError do + package.verify_entry entry + end + + assert_equal "package is corrupt, exception while verifying: whatever (ArgumentError) in #{@gem}", e.message + end + + def test_spec + package = Gem::Package.new @gem + + assert_equal @spec, package.spec + end + + def test_spec_from_io + # This functionality is used by rubygems.org to extract spec data from an + # uploaded gem before it is written to storage. + io = StringIO.new Gem.read_binary @gem + package = Gem::Package.new io + + assert_equal @spec, package.spec + end + + def test_spec_from_io_raises_gem_error_for_io_not_at_start + io = StringIO.new Gem.read_binary @gem + io.read(1) + assert_raises(Gem::Package::Error) do + Gem::Package.new io + end + end + + def util_tar + tar_io = StringIO.new + + Gem::Package::TarWriter.new tar_io do |tar| + yield tar + end + + tar_io.rewind + + tar_io + end + + def util_tar_gz(&block) + tar_io = util_tar(&block) + + tgz_io = StringIO.new + + # can't wrap TarWriter because it seeks + Zlib::GzipWriter.wrap tgz_io do |io| io.write tar_io.string end + + StringIO.new tgz_io.string + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_package_old.rb b/jni/ruby/test/rubygems/test_gem_package_old.rb new file mode 100644 index 0000000..6236dbb --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_package_old.rb @@ -0,0 +1,89 @@ +require 'rubygems/test_case' +require 'rubygems/simple_gem' + +class TestGemPackageOld < Gem::TestCase + + def setup + super + + open 'old_format.gem', 'wb' do |io| + io.write SIMPLE_GEM + end + + @package = Gem::Package::Old.new 'old_format.gem' + @destination = File.join @tempdir, 'extract' + + FileUtils.mkdir_p @destination + end + + def test_contents + assert_equal %w[lib/foo.rb lib/test.rb lib/test/wow.rb], @package.contents + end + + def test_contents_security_policy + skip 'openssl is missing' unless defined?(OpenSSL::SSL) + + @package.security_policy = Gem::Security::AlmostNoSecurity + + assert_raises Gem::Security::Exception do + @package.contents + end + end + + def test_extract_files + @package.extract_files @destination + + extracted = File.join @destination, 'lib/foo.rb' + assert_path_exists extracted + + mask = 0100644 & (~File.umask) + + assert_equal mask, File.stat(extracted).mode unless win_platform? + end + + def test_extract_files_security_policy + skip 'openssl is missing' unless defined?(OpenSSL::SSL) + + @package.security_policy = Gem::Security::AlmostNoSecurity + + assert_raises Gem::Security::Exception do + @package.extract_files @destination + end + end + + def test_spec + assert_equal 'testing', @package.spec.name + end + + def test_spec_security_policy + skip 'openssl is missing' unless defined?(OpenSSL::SSL) + + @package.security_policy = Gem::Security::AlmostNoSecurity + + assert_raises Gem::Security::Exception do + @package.spec + end + end + + def test_verify + skip 'openssl is missing' unless defined?(OpenSSL::SSL) + + assert @package.verify + + @package.security_policy = Gem::Security::NoSecurity + + assert @package.verify + + @package.security_policy = Gem::Security::AlmostNoSecurity + + e = assert_raises Gem::Security::Exception do + @package.verify + end + + assert_equal 'old format gems do not contain signatures ' + + 'and cannot be verified', + e.message + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_package_tar_header.rb b/jni/ruby/test/rubygems/test_gem_package_tar_header.rb new file mode 100644 index 0000000..9977e28 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_package_tar_header.rb @@ -0,0 +1,146 @@ +require 'rubygems/package/tar_test_case' +require 'rubygems/package' + +class TestGemPackageTarHeader < Gem::Package::TarTestCase + + def setup + super + + header = { + :name => 'x', + :mode => 0644, + :uid => 1000, + :gid => 10000, + :size => 100, + :mtime => 12345, + :typeflag => '0', + :linkname => 'link', + :uname => 'user', + :gname => 'group', + :devmajor => 1, + :devminor => 2, + :prefix => 'y', + } + + @tar_header = Gem::Package::TarHeader.new header + end + + def test_self_from + io = TempIO.new @tar_header.to_s + + new_header = Gem::Package::TarHeader.from io + + assert_headers_equal @tar_header, new_header + ensure + io.close! + end + + def test_initialize + assert_equal '', @tar_header.checksum, 'checksum' + assert_equal 1, @tar_header.devmajor, 'devmajor' + assert_equal 2, @tar_header.devminor, 'devminor' + assert_equal 10000, @tar_header.gid, 'gid' + assert_equal 'group', @tar_header.gname, 'gname' + assert_equal 'link', @tar_header.linkname, 'linkname' + assert_equal 'ustar', @tar_header.magic, 'magic' + assert_equal 0644, @tar_header.mode, 'mode' + assert_equal 12345, @tar_header.mtime, 'mtime' + assert_equal 'x', @tar_header.name, 'name' + assert_equal 'y', @tar_header.prefix, 'prefix' + assert_equal 100, @tar_header.size, 'size' + assert_equal '0', @tar_header.typeflag, 'typeflag' + assert_equal 1000, @tar_header.uid, 'uid' + assert_equal 'user', @tar_header.uname, 'uname' + assert_equal '00', @tar_header.version, 'version' + + refute_empty @tar_header, 'empty' + end + + def test_initialize_bad + assert_raises ArgumentError do + Gem::Package::TarHeader.new :name => '', :size => '', :mode => '' + end + + assert_raises ArgumentError do + Gem::Package::TarHeader.new :name => '', :size => '', :prefix => '' + end + + assert_raises ArgumentError do + Gem::Package::TarHeader.new :name => '', :prefix => '', :mode => '' + end + + assert_raises ArgumentError do + Gem::Package::TarHeader.new :prefix => '', :size => '', :mode => '' + end + end + + def test_initialize_typeflag + header = { + :mode => '', + :name => '', + :prefix => '', + :size => '', + :typeflag => '', + } + + tar_header = Gem::Package::TarHeader.new header + + assert_equal '0', tar_header.typeflag + end + + def test_empty_eh + refute_empty @tar_header + + @tar_header = Gem::Package::TarHeader.new :name => 'x', :prefix => '', + :mode => 0, :size => 0, + :empty => true + + assert_empty @tar_header + end + + def test_equals2 + assert_equal @tar_header, @tar_header + assert_equal @tar_header, @tar_header.dup + end + + def test_to_s + expected = <<-EOF.split("\n").join +x\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\0000000644\0000001750\0000023420\00000000000144\00000000030071 +\000012467\000 0link\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000ustar\00000user\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +group\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\0000000001\0000000002\000y\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000 + EOF + + assert_headers_equal expected, @tar_header + end + + def test_update_checksum + assert_equal '', @tar_header.checksum + + @tar_header.update_checksum + + assert_equal '012467', @tar_header.checksum + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_package_tar_reader.rb b/jni/ruby/test/rubygems/test_gem_package_tar_reader.rb new file mode 100644 index 0000000..aa45417 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_package_tar_reader.rb @@ -0,0 +1,89 @@ +require 'rubygems/package/tar_test_case' +require 'rubygems/package' + +class TestGemPackageTarReader < Gem::Package::TarTestCase + + def test_each_entry + tar = tar_dir_header "foo", "bar", 0, Time.now + tar << tar_file_header("bar", "baz", 0, 0, Time.now) + + io = TempIO.new tar + + entries = 0 + + Gem::Package::TarReader.new io do |tar_reader| + tar_reader.each_entry do |entry| + assert_kind_of Gem::Package::TarReader::Entry, entry + + entries += 1 + end + end + + assert_equal 2, entries + ensure + io.close! + end + + def test_rewind + content = ('a'..'z').to_a.join(" ") + + str = + tar_file_header("lib/foo", "", 010644, content.size, Time.now) + + content + "\0" * (512 - content.size) + str << "\0" * 1024 + + io = TempIO.new(str) + + Gem::Package::TarReader.new(io) do |tar_reader| + 3.times do + tar_reader.rewind + i = 0 + tar_reader.each_entry do |entry| + assert_equal(content, entry.read) + i += 1 + end + assert_equal(1, i) + end + end + ensure + io.close! + end + + def test_seek + tar = tar_dir_header "foo", "bar", 0, Time.now + tar << tar_file_header("bar", "baz", 0, 0, Time.now) + + io = TempIO.new tar + + Gem::Package::TarReader.new io do |tar_reader| + tar_reader.seek 'baz/bar' do |entry| + assert_kind_of Gem::Package::TarReader::Entry, entry + + assert_equal 'baz/bar', entry.full_name + end + + assert_equal 0, io.pos + end + ensure + io.close! + end + + def test_seek_missing + tar = tar_dir_header "foo", "bar", 0, Time.now + tar << tar_file_header("bar", "baz", 0, 0, Time.now) + + io = TempIO.new tar + + Gem::Package::TarReader.new io do |tar_reader| + tar_reader.seek 'nonexistent' do |entry| + flunk 'entry missing but entry-found block was run' + end + + assert_equal 0, io.pos + end + ensure + io.close! + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_package_tar_reader_entry.rb b/jni/ruby/test/rubygems/test_gem_package_tar_reader_entry.rb new file mode 100644 index 0000000..1143187 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_package_tar_reader_entry.rb @@ -0,0 +1,134 @@ +require 'rubygems/package/tar_test_case' +require 'rubygems/package' + +class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase + + def setup + super + + @contents = ('a'..'z').to_a.join * 100 + + @tar = '' + @tar << tar_file_header("lib/foo", "", 0, @contents.size, Time.now) + @tar << @contents + @tar << "\0" * (512 - (@tar.size % 512)) + + @entry = util_entry @tar + end + + def teardown + close_util_entry(@entry) + super + end + + def close_util_entry(entry) + entry.instance_variable_get(:@io).close! + end + + def test_bytes_read + assert_equal 0, @entry.bytes_read + + @entry.getc + + assert_equal 1, @entry.bytes_read + end + + def test_close + @entry.close + + assert @entry.bytes_read + + e = assert_raises IOError do @entry.eof? end + assert_equal 'closed Gem::Package::TarReader::Entry', e.message + + e = assert_raises IOError do @entry.getc end + assert_equal 'closed Gem::Package::TarReader::Entry', e.message + + e = assert_raises IOError do @entry.pos end + assert_equal 'closed Gem::Package::TarReader::Entry', e.message + + e = assert_raises IOError do @entry.read end + assert_equal 'closed Gem::Package::TarReader::Entry', e.message + + e = assert_raises IOError do @entry.rewind end + assert_equal 'closed Gem::Package::TarReader::Entry', e.message + end + + def test_closed_eh + @entry.close + + assert @entry.closed? + end + + def test_eof_eh + @entry.read + + assert @entry.eof? + end + + def test_full_name + assert_equal 'lib/foo', @entry.full_name + end + + def test_full_name_null + @entry.header.prefix << "\000" + + e = assert_raises Gem::Package::TarInvalidError do + @entry.full_name + end + + assert_equal 'tar is corrupt, name contains null byte', e.message + end + + def test_getc + assert_equal ?a, @entry.getc + end + + def test_directory_eh + assert_equal false, @entry.directory? + dir_ent = util_dir_entry + assert_equal true, dir_ent.directory? + ensure + close_util_entry(dir_ent) if dir_ent + end + + def test_file_eh + assert_equal true, @entry.file? + dir_ent = util_dir_entry + assert_equal false, dir_ent.file? + ensure + close_util_entry(dir_ent) if dir_ent + end + + def test_pos + assert_equal 0, @entry.pos + + @entry.getc + + assert_equal 1, @entry.pos + end + + def test_read + assert_equal @contents, @entry.read + end + + def test_read_big + assert_equal @contents, @entry.read(@contents.size * 2) + end + + def test_read_small + assert_equal @contents[0...100], @entry.read(100) + end + + def test_rewind + char = @entry.getc + + @entry.rewind + + assert_equal 0, @entry.pos + + assert_equal char, @entry.getc + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_package_tar_writer.rb b/jni/ruby/test/rubygems/test_gem_package_tar_writer.rb new file mode 100644 index 0000000..f087df3 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_package_tar_writer.rb @@ -0,0 +1,254 @@ +require 'rubygems/package/tar_test_case' +require 'rubygems/package/tar_writer' +require 'minitest/mock' + +class TestGemPackageTarWriter < Gem::Package::TarTestCase + + def setup + super + + @data = 'abcde12345' + @io = TempIO.new + @tar_writer = Gem::Package::TarWriter.new @io + end + + def teardown + @tar_writer.close unless @tar_writer.closed? + @io.close! + + super + end + + def test_add_file + Time.stub :now, Time.at(1458518157) do + @tar_writer.add_file 'x', 0644 do |f| f.write 'a' * 10 end + + assert_headers_equal(tar_file_header('x', '', 0644, 10, Time.now), + @io.string[0, 512]) + end + assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512] + assert_equal 1024, @io.pos + end + + def test_add_file_digest + digest_algorithms = Digest::SHA1, Digest::SHA512 + + Time.stub :now, Time.at(1458518157) do + digests = @tar_writer.add_file_digest 'x', 0644, digest_algorithms do |io| + io.write 'a' * 10 + end + + assert_equal '3495ff69d34671d1e15b33a63c1379fdedd3a32a', + digests['SHA1'].hexdigest + assert_equal '4714870aff6c97ca09d135834fdb58a6389a50c1' \ + '1fef8ec4afef466fb60a23ac6b7a9c92658f14df' \ + '4993d6b40a4e4d8424196afc347e97640d68de61' \ + 'e1cf14b0', + digests['SHA512'].hexdigest + + assert_headers_equal(tar_file_header('x', '', 0644, 10, Time.now), + @io.string[0, 512]) + end + assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512] + assert_equal 1024, @io.pos + end + + def test_add_file_digest_multiple + digest_algorithms = [Digest::SHA1, Digest::SHA512] + + Time.stub :now, Time.at(1458518157) do + digests = @tar_writer.add_file_digest 'x', 0644, digest_algorithms do |io| + io.write 'a' * 10 + end + + assert_equal '3495ff69d34671d1e15b33a63c1379fdedd3a32a', + digests['SHA1'].hexdigest + assert_equal '4714870aff6c97ca09d135834fdb58a6389a50c1' \ + '1fef8ec4afef466fb60a23ac6b7a9c92658f14df' \ + '4993d6b40a4e4d8424196afc347e97640d68de61' \ + 'e1cf14b0', + digests['SHA512'].hexdigest + + assert_headers_equal(tar_file_header('x', '', 0644, 10, Time.now), + @io.string[0, 512]) + end + assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512] + assert_equal 1024, @io.pos + end + + def test_add_file_signer + skip 'openssl is missing' unless defined?(OpenSSL::SSL) + + signer = Gem::Security::Signer.new PRIVATE_KEY, [PUBLIC_CERT] + + Time.stub :now, Time.at(1458518157) do + @tar_writer.add_file_signed 'x', 0644, signer do |io| + io.write 'a' * 10 + end + + assert_headers_equal(tar_file_header('x', '', 0644, 10, Time.now), + @io.string[0, 512]) + + + assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512] + + digest = signer.digest_algorithm.new + digest.update 'a' * 10 + + signature = signer.sign digest.digest + + assert_headers_equal(tar_file_header('x.sig', '', 0444, signature.length, + Time.now), + @io.string[1024, 512]) + assert_equal "#{signature}#{"\0" * (512 - signature.length)}", + @io.string[1536, 512] + + assert_equal 2048, @io.pos + end + + end + + def test_add_file_signer_empty + signer = Gem::Security::Signer.new nil, nil + + Time.stub :now, Time.at(1458518157) do + + @tar_writer.add_file_signed 'x', 0644, signer do |io| + io.write 'a' * 10 + end + + assert_headers_equal(tar_file_header('x', '', 0644, 10, Time.now), + @io.string[0, 512]) + end + assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512] + + assert_equal 1024, @io.pos + end + + def test_add_file_simple + Time.stub :now, Time.at(1458518157) do + @tar_writer.add_file_simple 'x', 0644, 10 do |io| io.write "a" * 10 end + + assert_headers_equal(tar_file_header('x', '', 0644, 10, Time.now), + @io.string[0, 512]) + end + + assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512] + assert_equal 1024, @io.pos + end + + def test_add_file_simple_padding + Time.stub :now, Time.at(1458518157) do + @tar_writer.add_file_simple 'x', 0, 100 + + assert_headers_equal tar_file_header('x', '', 0, 100, Time.now), + @io.string[0, 512] + end + + assert_equal "\0" * 512, @io.string[512, 512] + end + + def test_add_file_simple_data + @tar_writer.add_file_simple("lib/foo/bar", 0, 10) { |f| f.write @data } + @tar_writer.flush + + assert_equal @data + ("\0" * (512-@data.size)), + @io.string[512, 512] + end + + def test_add_file_simple_size + assert_raises Gem::Package::TarWriter::FileOverflow do + @tar_writer.add_file_simple("lib/foo/bar", 0, 10) do |io| + io.write "1" * 11 + end + end + end + + def test_add_file_unseekable + assert_raises Gem::Package::NonSeekableIO do + Gem::Package::TarWriter.new(Object.new).add_file 'x', 0 + end + end + + def test_close + @tar_writer.close + + assert_equal "\0" * 1024, @io.string + + e = assert_raises IOError do + @tar_writer.close + end + assert_equal 'closed Gem::Package::TarWriter', e.message + + e = assert_raises IOError do + @tar_writer.flush + end + assert_equal 'closed Gem::Package::TarWriter', e.message + + e = assert_raises IOError do + @tar_writer.add_file 'x', 0 + end + assert_equal 'closed Gem::Package::TarWriter', e.message + + e = assert_raises IOError do + @tar_writer.add_file_simple 'x', 0, 0 + end + assert_equal 'closed Gem::Package::TarWriter', e.message + + e = assert_raises IOError do + @tar_writer.mkdir 'x', 0 + end + assert_equal 'closed Gem::Package::TarWriter', e.message + end + + def test_mkdir + Time.stub :now, Time.at(1458518157) do + @tar_writer.mkdir 'foo', 0644 + + assert_headers_equal tar_dir_header('foo', '', 0644, Time.now), + @io.string[0, 512] + + assert_equal 512, @io.pos + end + end + + def test_split_name + assert_equal ['b' * 100, 'a' * 155], + @tar_writer.split_name("#{'a' * 155}/#{'b' * 100}") + + assert_equal ["#{'qwer/' * 19}bla", 'a' * 151], + @tar_writer.split_name("#{'a' * 151}/#{'qwer/' * 19}bla") + end + + def test_split_name_too_long_name + name = File.join 'a', 'b' * 100 + assert_equal ['b' * 100, 'a'], @tar_writer.split_name(name) + + name = File.join 'a', 'b' * 101 + exception = assert_raises Gem::Package::TooLongFileName do + @tar_writer.split_name name + end + assert_includes exception.message, name + end + + def test_split_name_too_long_prefix + name = File.join 'a' * 155, 'b' + assert_equal ['b', 'a' * 155], @tar_writer.split_name(name) + + name = File.join 'a' * 156, 'b' + exception = assert_raises Gem::Package::TooLongFileName do + @tar_writer.split_name name + end + assert_includes exception.message, name + end + + def test_split_name_too_long_total + name = 'a' * 257 + exception = assert_raises Gem::Package::TooLongFileName do + @tar_writer.split_name name + end + assert_includes exception.message, name + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_package_task.rb b/jni/ruby/test/rubygems/test_gem_package_task.rb new file mode 100644 index 0000000..1526e82 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_package_task.rb @@ -0,0 +1,80 @@ +require 'rubygems/test_case' +require 'rubygems' +require 'rubygems/package_task' + +class TestGemPackageTask < Gem::TestCase + + def setup + super + + Rake.application = Rake::Application.new + RakeFileUtils.verbose_flag = false + end + + def test_gem_package + gem = Gem::Specification.new do |g| + g.name = "pkgr" + g.version = "1.2.3" + + g.authors = %w[author] + g.files = %w[x] + g.summary = 'summary' + end + + pkg = Gem::PackageTask.new(gem) do |p| + p.package_files << "y" + end + + assert_equal %w[x y], pkg.package_files + + Dir.chdir @tempdir do + FileUtils.touch 'x' + FileUtils.touch 'y' + + Rake.application['package'].invoke + + assert_path_exists 'pkg/pkgr-1.2.3.gem' + end + end + + def test_gem_package_with_current_platform + gem = Gem::Specification.new do |g| + g.name = "pkgr" + g.version = "1.2.3" + g.files = Rake::FileList["x"].resolve + g.platform = Gem::Platform::CURRENT + end + pkg = Gem::PackageTask.new(gem) do |p| + p.package_files << "y" + end + assert_equal ["x", "y"], pkg.package_files + end + + def test_gem_package_with_ruby_platform + gem = Gem::Specification.new do |g| + g.name = "pkgr" + g.version = "1.2.3" + g.files = Rake::FileList["x"].resolve + g.platform = Gem::Platform::RUBY + end + pkg = Gem::PackageTask.new(gem) do |p| + p.package_files << "y" + end + assert_equal ["x", "y"], pkg.package_files + end + + def test_package_dir_path + gem = Gem::Specification.new do |g| + g.name = 'nokogiri' + g.version = '1.5.0' + g.platform = 'java' + end + + pkg = Gem::PackageTask.new gem + pkg.define + + assert_equal 'pkg/nokogiri-1.5.0-java', pkg.package_dir_path + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_path_support.rb b/jni/ruby/test/rubygems/test_gem_path_support.rb new file mode 100644 index 0000000..879cc98 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_path_support.rb @@ -0,0 +1,84 @@ +require 'rubygems/test_case' +require 'rubygems' +require 'fileutils' + +class TestGemPathSupport < Gem::TestCase + def setup + super + + ENV["GEM_HOME"] = @tempdir + ENV["GEM_PATH"] = [@tempdir, "something"].join(File::PATH_SEPARATOR) + end + + def test_initialize + ps = Gem::PathSupport.new + + assert_equal ENV["GEM_HOME"], ps.home + + expected = util_path + assert_equal expected, ps.path, "defaults to GEM_PATH" + end + + def test_initialize_home + ps = Gem::PathSupport.new "GEM_HOME" => "#{@tempdir}/foo" + + assert_equal File.join(@tempdir, "foo"), ps.home + + expected = util_path + [File.join(@tempdir, 'foo')] + assert_equal expected, ps.path + end + + if defined?(File::ALT_SEPARATOR) and File::ALT_SEPARATOR + def test_initialize_home_normalize + alternate = @tempdir.gsub(File::SEPARATOR, File::ALT_SEPARATOR) + ps = Gem::PathSupport.new "GEM_HOME" => alternate + + assert_equal @tempdir, ps.home, "normalize values" + end + end + + def test_initialize_path + ps = Gem::PathSupport.new "GEM_PATH" => %W[#{@tempdir}/foo #{@tempdir}/bar] + + assert_equal ENV["GEM_HOME"], ps.home + + expected = [ + File.join(@tempdir, 'foo'), + File.join(@tempdir, 'bar'), + ENV["GEM_HOME"], + ] + + assert_equal expected, ps.path + end + + def test_initialize_home_path + ps = Gem::PathSupport.new("GEM_HOME" => "#{@tempdir}/foo", + "GEM_PATH" => %W[#{@tempdir}/foo #{@tempdir}/bar]) + + assert_equal File.join(@tempdir, "foo"), ps.home + + expected = [File.join(@tempdir, 'foo'), File.join(@tempdir, 'bar')] + assert_equal expected, ps.path + end + + def util_path + ENV["GEM_PATH"].split(File::PATH_SEPARATOR) + end + + def test_initialize_spec + ENV["GEM_SPEC_CACHE"] = nil + + ps = Gem::PathSupport.new + assert_equal Gem.default_spec_cache_dir, ps.spec_cache_dir + + ENV["GEM_SPEC_CACHE"] = 'bar' + + ps = Gem::PathSupport.new + assert_equal ENV["GEM_SPEC_CACHE"], ps.spec_cache_dir + + ENV["GEM_SPEC_CACHE"] = File.join @tempdir, 'spec_cache' + + ps = Gem::PathSupport.new "GEM_SPEC_CACHE" => "foo" + assert_equal "foo", ps.spec_cache_dir + end +end diff --git a/jni/ruby/test/rubygems/test_gem_platform.rb b/jni/ruby/test/rubygems/test_gem_platform.rb new file mode 100644 index 0000000..17577dc --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_platform.rb @@ -0,0 +1,296 @@ +require 'rubygems/test_case' +require 'rubygems/platform' +require 'rbconfig' + +class TestGemPlatform < Gem::TestCase + + def test_self_local + util_set_arch 'i686-darwin8.10.1' + + assert_equal Gem::Platform.new(%w[x86 darwin 8]), Gem::Platform.local + end + + def test_self_match + assert Gem::Platform.match(nil), 'nil == ruby' + assert Gem::Platform.match(Gem::Platform.local), 'exact match' + assert Gem::Platform.match(Gem::Platform.local.to_s), '=~ match' + assert Gem::Platform.match(Gem::Platform::RUBY), 'ruby' + end + + def test_self_new + assert_equal Gem::Platform.local, Gem::Platform.new(Gem::Platform::CURRENT) + assert_equal Gem::Platform::RUBY, Gem::Platform.new(Gem::Platform::RUBY) + assert_equal Gem::Platform::RUBY, Gem::Platform.new(nil) + assert_equal Gem::Platform::RUBY, Gem::Platform.new('') + end + + def test_initialize + test_cases = { + 'amd64-freebsd6' => ['amd64', 'freebsd', '6'], + 'hppa2.0w-hpux11.31' => ['hppa2.0w', 'hpux', '11'], + 'java' => [nil, 'java', nil], + 'jruby' => [nil, 'java', nil], + 'universal-dotnet' => ['universal', 'dotnet', nil], + 'universal-dotnet2.0' => ['universal', 'dotnet', '2.0'], + 'universal-dotnet4.0' => ['universal', 'dotnet', '4.0'], + 'powerpc-aix5.3.0.0' => ['powerpc', 'aix', '5'], + 'powerpc-darwin7' => ['powerpc', 'darwin', '7'], + 'powerpc-darwin8' => ['powerpc', 'darwin', '8'], + 'powerpc-linux' => ['powerpc', 'linux', nil], + 'powerpc64-linux' => ['powerpc64', 'linux', nil], + 'sparc-solaris2.10' => ['sparc', 'solaris', '2.10'], + 'sparc-solaris2.8' => ['sparc', 'solaris', '2.8'], + 'sparc-solaris2.9' => ['sparc', 'solaris', '2.9'], + 'universal-darwin8' => ['universal', 'darwin', '8'], + 'universal-darwin9' => ['universal', 'darwin', '9'], + 'universal-macruby' => ['universal', 'macruby', nil], + 'i386-cygwin' => ['x86', 'cygwin', nil], + 'i686-darwin' => ['x86', 'darwin', nil], + 'i686-darwin8.4.1' => ['x86', 'darwin', '8'], + 'i386-freebsd4.11' => ['x86', 'freebsd', '4'], + 'i386-freebsd5' => ['x86', 'freebsd', '5'], + 'i386-freebsd6' => ['x86', 'freebsd', '6'], + 'i386-freebsd7' => ['x86', 'freebsd', '7'], + 'i386-freebsd' => ['x86', 'freebsd', nil], + 'universal-freebsd' => ['universal', 'freebsd', nil], + 'i386-java1.5' => ['x86', 'java', '1.5'], + 'x86-java1.6' => ['x86', 'java', '1.6'], + 'i386-java1.6' => ['x86', 'java', '1.6'], + 'i686-linux' => ['x86', 'linux', nil], + 'i586-linux' => ['x86', 'linux', nil], + 'i486-linux' => ['x86', 'linux', nil], + 'i386-linux' => ['x86', 'linux', nil], + 'i586-linux-gnu' => ['x86', 'linux', nil], + 'i386-linux-gnu' => ['x86', 'linux', nil], + 'i386-mingw32' => ['x86', 'mingw32', nil], + 'i386-mswin32' => ['x86', 'mswin32', nil], + 'i386-mswin32_80' => ['x86', 'mswin32', '80'], + 'i386-mswin32-80' => ['x86', 'mswin32', '80'], + 'x86-mswin32' => ['x86', 'mswin32', nil], + 'x86-mswin32_60' => ['x86', 'mswin32', '60'], + 'x86-mswin32-60' => ['x86', 'mswin32', '60'], + 'i386-netbsdelf' => ['x86', 'netbsdelf', nil], + 'i386-openbsd4.0' => ['x86', 'openbsd', '4.0'], + 'i386-solaris2.10' => ['x86', 'solaris', '2.10'], + 'i386-solaris2.8' => ['x86', 'solaris', '2.8'], + 'mswin32' => ['x86', 'mswin32', nil], + 'x86_64-linux' => ['x86_64', 'linux', nil], + 'x86_64-openbsd3.9' => ['x86_64', 'openbsd', '3.9'], + 'x86_64-openbsd4.0' => ['x86_64', 'openbsd', '4.0'], + 'x86_64-openbsd' => ['x86_64', 'openbsd', nil], + } + + test_cases.each do |arch, expected| + platform = Gem::Platform.new arch + assert_equal expected, platform.to_a, arch.inspect + end + end + + def test_initialize_command_line + expected = ['x86', 'mswin32', nil] + + platform = Gem::Platform.new 'i386-mswin32' + + assert_equal expected, platform.to_a, 'i386-mswin32' + + expected = ['x86', 'mswin32', '80'] + + platform = Gem::Platform.new 'i386-mswin32-80' + + assert_equal expected, platform.to_a, 'i386-mswin32-80' + + expected = ['x86', 'solaris', '2.10'] + + platform = Gem::Platform.new 'i386-solaris-2.10' + + assert_equal expected, platform.to_a, 'i386-solaris-2.10' + end + + def test_initialize_mswin32_vc6 + orig_RUBY_SO_NAME = RbConfig::CONFIG['RUBY_SO_NAME'] + RbConfig::CONFIG['RUBY_SO_NAME'] = 'msvcrt-ruby18' + + expected = ['x86', 'mswin32', nil] + + platform = Gem::Platform.new 'i386-mswin32' + + assert_equal expected, platform.to_a, 'i386-mswin32 VC6' + ensure + if orig_RUBY_SO_NAME then + RbConfig::CONFIG['RUBY_SO_NAME'] = orig_RUBY_SO_NAME + else + RbConfig::CONFIG.delete 'RUBY_SO_NAME' + end + end + + def test_initialize_platform + platform = Gem::Platform.new 'cpu-my_platform1' + + assert_equal 'cpu', platform.cpu + assert_equal 'my_platform', platform.os + assert_equal '1', platform.version + end + + def test_initialize_test + platform = Gem::Platform.new 'cpu-my_platform1' + assert_equal 'cpu', platform.cpu + assert_equal 'my_platform', platform.os + assert_equal '1', platform.version + + platform = Gem::Platform.new 'cpu-other_platform1' + assert_equal 'cpu', platform.cpu + assert_equal 'other_platform', platform.os + assert_equal '1', platform.version + end + + def test_to_s + if win_platform? then + assert_equal 'x86-mswin32-60', Gem::Platform.local.to_s + else + assert_equal 'x86-darwin-8', Gem::Platform.local.to_s + end + end + + def test_equals2 + my = Gem::Platform.new %w[cpu my_platform 1] + other = Gem::Platform.new %w[cpu other_platform 1] + + assert_equal my, my + refute_equal my, other + refute_equal other, my + end + + def test_equals3 + my = Gem::Platform.new %w[cpu my_platform 1] + other = Gem::Platform.new %w[cpu other_platform 1] + + assert(my === my) + refute(other === my) + refute(my === other) + end + + def test_equals3_cpu + ppc_darwin8 = Gem::Platform.new 'powerpc-darwin8.0' + uni_darwin8 = Gem::Platform.new 'universal-darwin8.0' + x86_darwin8 = Gem::Platform.new 'i686-darwin8.0' + + util_set_arch 'powerpc-darwin8' + assert((ppc_darwin8 === Gem::Platform.local), 'powerpc =~ universal') + assert((uni_darwin8 === Gem::Platform.local), 'powerpc =~ universal') + refute((x86_darwin8 === Gem::Platform.local), 'powerpc =~ universal') + + util_set_arch 'i686-darwin8' + refute((ppc_darwin8 === Gem::Platform.local), 'powerpc =~ universal') + assert((uni_darwin8 === Gem::Platform.local), 'x86 =~ universal') + assert((x86_darwin8 === Gem::Platform.local), 'powerpc =~ universal') + + util_set_arch 'universal-darwin8' + assert((ppc_darwin8 === Gem::Platform.local), 'universal =~ ppc') + assert((uni_darwin8 === Gem::Platform.local), 'universal =~ universal') + assert((x86_darwin8 === Gem::Platform.local), 'universal =~ x86') + end + + def test_equals3_cpu_arm + arm = Gem::Platform.new 'arm-linux' + armv5 = Gem::Platform.new 'armv5-linux' + armv7 = Gem::Platform.new 'armv7-linux' + + util_set_arch 'armv5-linux' + assert((arm === Gem::Platform.local), 'arm === armv5') + assert((armv5 === Gem::Platform.local), 'armv5 === armv5') + refute((armv7 === Gem::Platform.local), 'armv7 === armv5') + refute((Gem::Platform.local === arm), 'armv5 === arm') + + util_set_arch 'armv7-linux' + assert((arm === Gem::Platform.local), 'arm === armv7') + refute((armv5 === Gem::Platform.local), 'armv5 === armv7') + assert((armv7 === Gem::Platform.local), 'armv7 === armv7') + refute((Gem::Platform.local === arm), 'armv7 === arm') + end + + def test_equals3_version + util_set_arch 'i686-darwin8' + + x86_darwin = Gem::Platform.new ['x86', 'darwin', nil] + x86_darwin7 = Gem::Platform.new ['x86', 'darwin', '7'] + x86_darwin8 = Gem::Platform.new ['x86', 'darwin', '8'] + x86_darwin9 = Gem::Platform.new ['x86', 'darwin', '9'] + + assert((x86_darwin === Gem::Platform.local), 'x86_darwin === x86_darwin8') + assert((x86_darwin8 === Gem::Platform.local), 'x86_darwin8 === x86_darwin8') + + refute((x86_darwin7 === Gem::Platform.local), 'x86_darwin7 === x86_darwin8') + refute((x86_darwin9 === Gem::Platform.local), 'x86_darwin9 === x86_darwin8') + end + + def test_equals_tilde + util_set_arch 'i386-mswin32' + + assert_local_match 'mswin32' + assert_local_match 'i386-mswin32' + + # oddballs + assert_local_match 'i386-mswin32-mq5.3' + assert_local_match 'i386-mswin32-mq6' + refute_local_match 'win32-1.8.2-VC7' + refute_local_match 'win32-1.8.4-VC6' + refute_local_match 'win32-source' + refute_local_match 'windows' + + util_set_arch 'i686-linux' + assert_local_match 'i486-linux' + assert_local_match 'i586-linux' + assert_local_match 'i686-linux' + + util_set_arch 'i686-darwin8' + assert_local_match 'i686-darwin8.4.1' + assert_local_match 'i686-darwin8.8.2' + + util_set_arch 'java' + assert_local_match 'java' + assert_local_match 'jruby' + + util_set_arch 'universal-dotnet2.0' + assert_local_match 'universal-dotnet' + assert_local_match 'universal-dotnet-2.0' + refute_local_match 'universal-dotnet-4.0' + assert_local_match 'dotnet' + assert_local_match 'dotnet-2.0' + refute_local_match 'dotnet-4.0' + + util_set_arch 'universal-dotnet4.0' + assert_local_match 'universal-dotnet' + refute_local_match 'universal-dotnet-2.0' + assert_local_match 'universal-dotnet-4.0' + assert_local_match 'dotnet' + refute_local_match 'dotnet-2.0' + assert_local_match 'dotnet-4.0' + + util_set_arch 'universal-macruby-1.0' + assert_local_match 'universal-macruby' + assert_local_match 'macruby' + refute_local_match 'universal-macruby-0.10' + assert_local_match 'universal-macruby-1.0' + + util_set_arch 'powerpc-darwin' + assert_local_match 'powerpc-darwin' + + util_set_arch 'powerpc-darwin7' + assert_local_match 'powerpc-darwin7.9.0' + + util_set_arch 'powerpc-darwin8' + assert_local_match 'powerpc-darwin8.10.0' + + util_set_arch 'sparc-solaris2.8' + assert_local_match 'sparc-solaris2.8-mq5.3' + end + + def assert_local_match name + assert_match Gem::Platform.local, name + end + + def refute_local_match name + refute_match Gem::Platform.local, name + end +end + diff --git a/jni/ruby/test/rubygems/test_gem_rdoc.rb b/jni/ruby/test/rubygems/test_gem_rdoc.rb new file mode 100644 index 0000000..3ff06fe --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_rdoc.rb @@ -0,0 +1,269 @@ +require 'rubygems' +require 'rubygems/test_case' +require 'rubygems/rdoc' + +class TestGemRDoc < Gem::TestCase + Gem::RDoc.load_rdoc + rdoc_4 = Gem::Requirement.new('> 3').satisfied_by?(Gem::RDoc.rdoc_version) + + def setup + super + + @a = util_spec 'a' do |s| + s.rdoc_options = %w[--main MyTitle] + s.extra_rdoc_files = %w[README] + end + + write_file File.join(@tempdir, 'lib', 'a.rb') + write_file File.join(@tempdir, 'README') + + install_gem @a + + @hook = Gem::RDoc.new @a + + begin + Gem::RDoc.load_rdoc + rescue Gem::DocumentError => e + skip e.message + end + + Gem.configuration[:rdoc] = nil + end + + ## + # RDoc 4 ships with its own Gem::RDoc which overrides this one which is + # shipped for backwards compatibility. + + def rdoc_4? + Gem::Requirement.new('>= 4.0.0.preview2').satisfied_by? \ + @hook.class.rdoc_version + end + + def rdoc_3? + Gem::Requirement.new('~> 3.0').satisfied_by? @hook.class.rdoc_version + end + + def rdoc_3_8_or_better? + Gem::Requirement.new('>= 3.8').satisfied_by? @hook.class.rdoc_version + end + + def test_initialize + if rdoc_4? then + refute @hook.generate_rdoc + else + assert @hook.generate_rdoc + end + assert @hook.generate_ri + + rdoc = Gem::RDoc.new @a, false, false + + refute rdoc.generate_rdoc + refute rdoc.generate_ri + end + + def test_delete_legacy_args + args = %w[ + --inline-source + --one-file + --promiscuous + -p + ] + + @hook.delete_legacy_args args + + assert_empty args + end + + def test_document + skip 'RDoc 3 required' unless rdoc_3? + + options = RDoc::Options.new + options.files = [] + + rdoc = @hook.new_rdoc + @hook.instance_variable_set :@rdoc, rdoc + @hook.instance_variable_set :@file_info, [] + + @hook.document 'darkfish', options, @a.doc_dir('rdoc') + + assert @hook.rdoc_installed? + end unless rdoc_4 + + def test_generate + skip 'RDoc 3 required' unless rdoc_3? + + FileUtils.mkdir_p @a.doc_dir + FileUtils.mkdir_p File.join(@a.gem_dir, 'lib') + + @hook.generate + + assert @hook.rdoc_installed? + assert @hook.ri_installed? + + rdoc = @hook.instance_variable_get :@rdoc + + refute rdoc.options.hyperlink_all + end unless rdoc_4 + + def test_generate_configuration_rdoc_array + skip 'RDoc 3 required' unless rdoc_3? + + Gem.configuration[:rdoc] = %w[-A] + + FileUtils.mkdir_p @a.doc_dir + FileUtils.mkdir_p File.join(@a.gem_dir, 'lib') + + @hook.generate + + rdoc = @hook.instance_variable_get :@rdoc + + assert rdoc.options.hyperlink_all + end unless rdoc_4 + + def test_generate_configuration_rdoc_string + skip 'RDoc 3 required' unless rdoc_3? + + Gem.configuration[:rdoc] = '-A' + + FileUtils.mkdir_p @a.doc_dir + FileUtils.mkdir_p File.join(@a.gem_dir, 'lib') + + @hook.generate + + rdoc = @hook.instance_variable_get :@rdoc + + assert rdoc.options.hyperlink_all + end unless rdoc_4 + + def test_generate_disabled + @hook.generate_rdoc = false + @hook.generate_ri = false + + @hook.generate + + refute @hook.rdoc_installed? + refute @hook.ri_installed? + end + + def test_generate_force + skip 'RDoc 3 required' unless rdoc_3? + + FileUtils.mkdir_p @a.doc_dir 'ri' + FileUtils.mkdir_p @a.doc_dir 'rdoc' + FileUtils.mkdir_p File.join(@a.gem_dir, 'lib') + + @hook.force = true + + @hook.generate + + assert_path_exists File.join(@a.doc_dir('rdoc'), 'index.html') + assert_path_exists File.join(@a.doc_dir('ri'), 'cache.ri') + end unless rdoc_4 + + def test_generate_no_overwrite + skip 'RDoc 3 required' unless rdoc_3? + + FileUtils.mkdir_p @a.doc_dir 'ri' + FileUtils.mkdir_p @a.doc_dir 'rdoc' + FileUtils.mkdir_p File.join(@a.gem_dir, 'lib') + + @hook.generate + + refute_path_exists File.join(@a.doc_dir('rdoc'), 'index.html') + refute_path_exists File.join(@a.doc_dir('ri'), 'cache.ri') + end unless rdoc_4 + + def test_generate_legacy + skip 'RDoc < 3.8 required' if rdoc_3_8_or_better? + + FileUtils.mkdir_p @a.doc_dir + FileUtils.mkdir_p File.join(@a.gem_dir, 'lib') + + @hook.generate_legacy + + assert @hook.rdoc_installed? + assert @hook.ri_installed? + end unless rdoc_4 + + def test_legacy_rdoc + skip 'RDoc < 3.8 required' if rdoc_3_8_or_better? + + FileUtils.mkdir_p @a.doc_dir + FileUtils.mkdir_p File.join(@a.gem_dir, 'lib') + + @hook.legacy_rdoc '--op', @a.doc_dir('rdoc') + + assert @hook.rdoc_installed? + end unless rdoc_4 + + def test_new_rdoc + assert_kind_of RDoc::RDoc, @hook.new_rdoc + end + + def test_rdoc_installed? + refute @hook.rdoc_installed? + + FileUtils.mkdir_p @a.doc_dir 'rdoc' + + assert @hook.rdoc_installed? + end + + def test_remove + FileUtils.mkdir_p @a.doc_dir 'rdoc' + FileUtils.mkdir_p @a.doc_dir 'ri' + + @hook.remove + + refute @hook.rdoc_installed? + refute @hook.ri_installed? + + assert_path_exists @a.doc_dir + end + + def test_remove_unwritable + skip 'chmod not supported' if Gem.win_platform? + FileUtils.mkdir_p @a.base_dir + FileUtils.chmod 0, @a.base_dir + + e = assert_raises Gem::FilePermissionError do + @hook.remove + end + + assert_equal @a.base_dir, e.directory + ensure + FileUtils.chmod(0755, @a.base_dir) if File.directory?(@a.base_dir) + end + + def test_ri_installed? + refute @hook.ri_installed? + + FileUtils.mkdir_p @a.doc_dir 'ri' + + assert @hook.ri_installed? + end + + def test_setup + @hook.setup + + assert_path_exists @a.doc_dir + end + + def test_setup_unwritable + skip 'chmod not supported' if Gem.win_platform? + FileUtils.mkdir_p @a.doc_dir + FileUtils.chmod 0, @a.doc_dir + + e = assert_raises Gem::FilePermissionError do + @hook.setup + end + + assert_equal @a.doc_dir, e.directory + ensure + if File.exist? @a.doc_dir + FileUtils.chmod 0755, @a.doc_dir + FileUtils.rm_r @a.doc_dir + end + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_remote_fetcher.rb b/jni/ruby/test/rubygems/test_gem_remote_fetcher.rb new file mode 100644 index 0000000..63dd8fe --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_remote_fetcher.rb @@ -0,0 +1,987 @@ +require 'rubygems/test_case' + +require 'webrick' +begin + require 'webrick/https' +rescue LoadError => e + raise unless (e.respond_to?(:path) && e.path == 'openssl') || + e.message =~ / -- openssl$/ +end + +require 'rubygems/remote_fetcher' +require 'rubygems/package' +require 'minitest/mock' + +# = Testing Proxy Settings +# +# These tests check the proper proxy server settings by running two +# web servers. The web server at http://localhost:#{SERVER_PORT} +# represents the normal gem server and returns a gemspec with a rake +# version of 0.4.11. The web server at http://localhost:#{PROXY_PORT} +# represents the proxy server and returns a different dataset where +# rake has version 0.4.2. This allows us to detect which server is +# returning the data. +# +# Note that the proxy server is not a *real* proxy server. But our +# software doesn't really care, as long as we hit the proxy URL when a +# proxy is configured. + +class TestGemRemoteFetcher < Gem::TestCase + + include Gem::DefaultUserInteraction + + SERVER_DATA = <<-EOY +--- !ruby/object:Gem::Cache +gems: + rake-0.4.11: !ruby/object:Gem::Specification + rubygems_version: "0.7" + specification_version: 1 + name: rake + version: !ruby/object:Gem::Version + version: 0.4.11 + date: 2004-11-12 + summary: Ruby based make-like utility. + require_paths: + - lib + author: Jim Weirich + email: jim@weirichhouse.org + homepage: http://rake.rubyforge.org + rubyforge_project: rake + description: Rake is a Make-like program implemented in Ruby. Tasks and dependencies are specified in standard Ruby syntax. + autorequire: + default_executable: rake + bindir: bin + has_rdoc: true + required_ruby_version: !ruby/object:Gem::Version::Requirement + requirements: + - + - ">" + - !ruby/object:Gem::Version + version: 0.0.0 + version: + platform: ruby + files: + - README + test_files: [] + library_stubs: + rdoc_options: + extra_rdoc_files: + executables: + - rake + extensions: [] + requirements: [] + dependencies: [] + EOY + + PROXY_DATA = SERVER_DATA.gsub(/0.4.11/, '0.4.2') + + DIR = File.expand_path(File.dirname(__FILE__)) + + def setup + @proxies = %w[http_proxy HTTP_PROXY http_proxy_user HTTP_PROXY_USER http_proxy_pass HTTP_PROXY_PASS no_proxy NO_PROXY] + @old_proxies = @proxies.map {|k| ENV[k] } + @proxies.each {|k| ENV[k] = nil } + + super + self.class.start_servers + self.class.enable_yaml = true + self.class.enable_zip = false + + base_server_uri = "http://localhost:#{self.class.normal_server_port}" + @proxy_uri = "http://localhost:#{self.class.proxy_server_port}" + + @server_uri = base_server_uri + "/yaml" + @server_z_uri = base_server_uri + "/yaml.Z" + + # REFACTOR: copied from test_gem_dependency_installer.rb + @gems_dir = File.join @tempdir, 'gems' + @cache_dir = File.join @gemhome, "cache" + FileUtils.mkdir @gems_dir + + # TODO: why does the remote fetcher need it written to disk? + @a1, @a1_gem = util_gem 'a', '1' do |s| s.executables << 'a_bin' end + @a1.loaded_from = File.join(@gemhome, 'specifications', @a1.full_name) + + Gem::RemoteFetcher.fetcher = nil + + @fetcher = Gem::RemoteFetcher.fetcher + end + + def teardown + @fetcher.close_all + self.class.stop_servers + super + Gem.configuration[:http_proxy] = nil + @proxies.each_with_index {|k, i| ENV[k] = @old_proxies[i] } + end + + def test_self_fetcher + fetcher = Gem::RemoteFetcher.fetcher + refute_nil fetcher + assert_kind_of Gem::RemoteFetcher, fetcher + end + + def test_self_fetcher_with_proxy + proxy_uri = 'http://proxy.example.com' + Gem.configuration[:http_proxy] = proxy_uri + Gem::RemoteFetcher.fetcher = nil + + fetcher = Gem::RemoteFetcher.fetcher + + refute_nil fetcher + assert_kind_of Gem::RemoteFetcher, fetcher + assert_equal proxy_uri, fetcher.instance_variable_get(:@proxy).to_s + end + + def test_fetch_size_bad_uri + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + + e = assert_raises ArgumentError do + fetcher.fetch_size 'gems.example.com/yaml' + end + + assert_equal 'uri scheme is invalid: nil', e.message + end + + def test_fetch_size_socket_error + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + def fetcher.request(uri, request_class, last_modified = nil) + raise SocketError, "tarded" + end + + uri = 'http://gems.example.com/yaml' + e = assert_raises Gem::RemoteFetcher::FetchError do + fetcher.fetch_size uri + end + + assert_equal "SocketError: tarded (#{uri})", e.message + end + + def test_no_proxy + use_ui @ui do + assert_data_from_server @fetcher.fetch_path(@server_uri) + assert_equal SERVER_DATA.size, @fetcher.fetch_size(@server_uri) + end + end + + def test_api_endpoint + uri = URI.parse "http://example.com/foo" + target = MiniTest::Mock.new + target.expect :target, "gems.example.com" + + dns = MiniTest::Mock.new + dns.expect :getresource, target, [String, Object] + + fetch = Gem::RemoteFetcher.new nil, dns + assert_equal URI.parse("http://gems.example.com/foo"), fetch.api_endpoint(uri) + + target.verify + dns.verify + end + + def test_api_endpoint_ignores_trans_domain_values + uri = URI.parse "http://gems.example.com/foo" + target = MiniTest::Mock.new + target.expect :target, "blah.com" + + dns = MiniTest::Mock.new + dns.expect :getresource, target, [String, Object] + + fetch = Gem::RemoteFetcher.new nil, dns + assert_equal URI.parse("http://gems.example.com/foo"), fetch.api_endpoint(uri) + + target.verify + dns.verify + end + + def test_api_endpoint_ignores_trans_domain_values_that_starts_with_original + uri = URI.parse "http://example.com/foo" + target = MiniTest::Mock.new + target.expect :target, "example.combadguy.com" + + dns = MiniTest::Mock.new + dns.expect :getresource, target, [String, Object] + + fetch = Gem::RemoteFetcher.new nil, dns + assert_equal URI.parse("http://example.com/foo"), fetch.api_endpoint(uri) + + target.verify + dns.verify + end + + def test_api_endpoint_ignores_trans_domain_values_that_end_with_original + uri = URI.parse "http://example.com/foo" + target = MiniTest::Mock.new + target.expect :target, "badexample.com" + + dns = MiniTest::Mock.new + dns.expect :getresource, target, [String, Object] + + fetch = Gem::RemoteFetcher.new nil, dns + assert_equal URI.parse("http://example.com/foo"), fetch.api_endpoint(uri) + + target.verify + dns.verify + end + + def test_cache_update_path + uri = URI 'http://example/file' + path = File.join @tempdir, 'file' + + fetcher = util_fuck_with_fetcher 'hello' + + data = fetcher.cache_update_path uri, path + + assert_equal 'hello', data + + assert_equal 'hello', File.read(path) + end + + def test_cache_update_path_no_update + uri = URI 'http://example/file' + path = File.join @tempdir, 'file' + + fetcher = util_fuck_with_fetcher 'hello' + + data = fetcher.cache_update_path uri, path, false + + assert_equal 'hello', data + + refute_path_exists path + end + + def util_fuck_with_fetcher data, blow = false + fetcher = Gem::RemoteFetcher.fetcher + fetcher.instance_variable_set :@test_data, data + + unless blow then + def fetcher.fetch_path arg, *rest + @test_arg = arg + @test_data + end + else + def fetcher.fetch_path arg, *rest + # OMG I'm such an ass + class << self; remove_method :fetch_path; end + def self.fetch_path arg, *rest + @test_arg = arg + @test_data + end + + raise Gem::RemoteFetcher::FetchError.new("haha!", nil) + end + end + + fetcher + end + + def test_download + a1_data = nil + File.open @a1_gem, 'rb' do |fp| + a1_data = fp.read + end + + fetcher = util_fuck_with_fetcher a1_data + + a1_cache_gem = @a1.cache_file + assert_equal a1_cache_gem, fetcher.download(@a1, 'http://gems.example.com') + assert_equal("http://gems.example.com/gems/a-1.gem", + fetcher.instance_variable_get(:@test_arg).to_s) + assert File.exist?(a1_cache_gem) + end + + def test_download_with_auth + a1_data = nil + File.open @a1_gem, 'rb' do |fp| + a1_data = fp.read + end + + fetcher = util_fuck_with_fetcher a1_data + + a1_cache_gem = @a1.cache_file + assert_equal a1_cache_gem, fetcher.download(@a1, 'http://user:password@gems.example.com') + assert_equal("http://user:password@gems.example.com/gems/a-1.gem", + fetcher.instance_variable_get(:@test_arg).to_s) + assert File.exist?(a1_cache_gem) + end + + def test_download_with_encoded_auth + a1_data = nil + File.open @a1_gem, 'rb' do |fp| + a1_data = fp.read + end + + fetcher = util_fuck_with_fetcher a1_data + + a1_cache_gem = @a1.cache_file + assert_equal a1_cache_gem, fetcher.download(@a1, 'http://user:%25pas%25sword@gems.example.com') + assert_equal("http://user:%25pas%25sword@gems.example.com/gems/a-1.gem", + fetcher.instance_variable_get(:@test_arg).to_s) + assert File.exist?(a1_cache_gem) + end + + def test_download_cached + FileUtils.mv @a1_gem, @cache_dir + + inst = Gem::RemoteFetcher.fetcher + + assert_equal @a1.cache_file, inst.download(@a1, 'http://gems.example.com') + end + + def test_download_local + FileUtils.mv @a1_gem, @tempdir + local_path = File.join @tempdir, @a1.file_name + inst = nil + + Dir.chdir @tempdir do + inst = Gem::RemoteFetcher.fetcher + end + + assert_equal @a1.cache_file, inst.download(@a1, local_path) + end + + def test_download_local_space + space_path = File.join @tempdir, 'space path' + FileUtils.mkdir space_path + FileUtils.mv @a1_gem, space_path + local_path = File.join space_path, @a1.file_name + inst = nil + + Dir.chdir @tempdir do + inst = Gem::RemoteFetcher.fetcher + end + + assert_equal @a1.cache_file, inst.download(@a1, local_path) + end + + def test_download_install_dir + a1_data = File.open @a1_gem, 'rb' do |fp| + fp.read + end + + fetcher = util_fuck_with_fetcher a1_data + + install_dir = File.join @tempdir, 'more_gems' + + a1_cache_gem = File.join install_dir, "cache", @a1.file_name + FileUtils.mkdir_p(File.dirname(a1_cache_gem)) + actual = fetcher.download(@a1, 'http://gems.example.com', install_dir) + + assert_equal a1_cache_gem, actual + assert_equal("http://gems.example.com/gems/a-1.gem", + fetcher.instance_variable_get(:@test_arg).to_s) + + assert File.exist?(a1_cache_gem) + end + + unless win_platform? # File.chmod doesn't work + def test_download_local_read_only + FileUtils.mv @a1_gem, @tempdir + local_path = File.join @tempdir, @a1.file_name + inst = nil + FileUtils.chmod 0555, @a1.cache_dir + + Dir.chdir @tempdir do + inst = Gem::RemoteFetcher.fetcher + end + + assert_equal(File.join(@tempdir, @a1.file_name), + inst.download(@a1, local_path)) + ensure + FileUtils.chmod 0755, @a1.cache_dir + end + + def test_download_read_only + FileUtils.chmod 0555, @a1.cache_dir + FileUtils.chmod 0555, @gemhome + + fetcher = util_fuck_with_fetcher File.read(@a1_gem) + fetcher.download(@a1, 'http://gems.example.com') + a1_cache_gem = File.join Gem.user_dir, "cache", @a1.file_name + assert File.exist? a1_cache_gem + ensure + FileUtils.chmod 0755, @gemhome + FileUtils.chmod 0755, @a1.cache_dir + end + end + + def test_download_platform_legacy + original_platform = 'old-platform' + + e1, e1_gem = util_gem 'e', '1' do |s| + s.platform = Gem::Platform::CURRENT + s.instance_variable_set :@original_platform, original_platform + end + e1.loaded_from = File.join(@gemhome, 'specifications', e1.full_name) + + e1_data = nil + File.open e1_gem, 'rb' do |fp| + e1_data = fp.read + end + + fetcher = util_fuck_with_fetcher e1_data, :blow_chunks + + e1_cache_gem = e1.cache_file + + assert_equal e1_cache_gem, fetcher.download(e1, 'http://gems.example.com') + + assert_equal("http://gems.example.com/gems/#{e1.original_name}.gem", + fetcher.instance_variable_get(:@test_arg).to_s) + assert File.exist?(e1_cache_gem) + end + + def test_download_same_file + FileUtils.mv @a1_gem, @tempdir + local_path = File.join @tempdir, @a1.file_name + inst = nil + + Dir.chdir @tempdir do + inst = Gem::RemoteFetcher.fetcher + end + + cache_path = @a1.cache_file + FileUtils.mv local_path, cache_path + + gem = Gem::Package.new cache_path + + assert_equal cache_path, inst.download(gem.spec, cache_path) + end + + def test_download_unsupported + inst = Gem::RemoteFetcher.fetcher + + e = assert_raises ArgumentError do + inst.download @a1, 'ftp://gems.rubyforge.org' + end + + assert_equal 'unsupported URI scheme ftp', e.message + end + + def test_download_to_cache + @a2, @a2_gem = util_gem 'a', '2' + + util_setup_spec_fetcher @a1, @a2 + @fetcher.instance_variable_set :@a1, @a1 + @fetcher.instance_variable_set :@a2, @a2 + def @fetcher.fetch_path uri, mtime = nil, head = false + case uri.request_uri + when /#{@a1.spec_name}/ then + Gem.deflate Marshal.dump @a1 + when /#{@a2.spec_name}/ then + Gem.deflate Marshal.dump @a2 + else + uri.to_s + end + end + + gem = Gem::RemoteFetcher.fetcher.download_to_cache dep 'a' + + assert_equal @a2.file_name, File.basename(gem) + end + + def test_fetch_path_gzip + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + + def fetcher.fetch_http(uri, mtime, head = nil) + Gem.gzip 'foo' + end + + assert_equal 'foo', fetcher.fetch_path(@uri + 'foo.gz') + end + + def test_fetch_path_gzip_unmodified + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + + def fetcher.fetch_http(uri, mtime, head = nil) + nil + end + + assert_equal nil, fetcher.fetch_path(@uri + 'foo.gz', Time.at(0)) + end + + def test_fetch_path_io_error + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + + def fetcher.fetch_http(*) + raise EOFError + end + + url = 'http://example.com/uri' + + e = assert_raises Gem::RemoteFetcher::FetchError do + fetcher.fetch_path url + end + + assert_equal "EOFError: EOFError (#{url})", e.message + assert_equal url, e.uri + end + + def test_fetch_path_socket_error + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + + def fetcher.fetch_http(uri, mtime, head = nil) + raise SocketError + end + + url = 'http://example.com/uri' + + e = assert_raises Gem::RemoteFetcher::FetchError do + fetcher.fetch_path url + end + + assert_equal "SocketError: SocketError (#{url})", e.message + assert_equal url, e.uri + end + + def test_fetch_path_system_call_error + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + + def fetcher.fetch_http(uri, mtime = nil, head = nil) + raise Errno::ECONNREFUSED, 'connect(2)' + end + + url = 'http://example.com/uri' + + e = assert_raises Gem::RemoteFetcher::FetchError do + fetcher.fetch_path url + end + + assert_match %r|ECONNREFUSED:.*connect\(2\) \(#{Regexp.escape url}\)\z|, + e.message + assert_equal url, e.uri + end + + def test_fetch_path_unmodified + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + + def fetcher.fetch_http(uri, mtime, head = nil) + nil + end + + assert_equal nil, fetcher.fetch_path(URI.parse(@gem_repo), Time.at(0)) + end + + def test_implicit_no_proxy + use_ui @ui do + ENV['http_proxy'] = 'http://fakeurl:12345' + fetcher = Gem::RemoteFetcher.new :no_proxy + @fetcher = fetcher + assert_data_from_server fetcher.fetch_path(@server_uri) + end + end + + def test_implicit_proxy + use_ui @ui do + ENV['http_proxy'] = @proxy_uri + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + assert_data_from_proxy fetcher.fetch_path(@server_uri) + end + end + + def test_implicit_upper_case_proxy + use_ui @ui do + ENV['HTTP_PROXY'] = @proxy_uri + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + assert_data_from_proxy fetcher.fetch_path(@server_uri) + end + end + + def test_implicit_proxy_no_env + use_ui @ui do + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + assert_data_from_server fetcher.fetch_path(@server_uri) + end + end + + def test_fetch_http + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + url = 'http://gems.example.com/redirect' + + def fetcher.request(uri, request_class, last_modified = nil) + url = 'http://gems.example.com/redirect' + unless defined? @requested then + @requested = true + res = Net::HTTPMovedPermanently.new nil, 301, nil + res.add_field 'Location', url + res + else + res = Net::HTTPOK.new nil, 200, nil + def res.body() 'real_path' end + res + end + end + + data = fetcher.fetch_http URI.parse(url) + + assert_equal 'real_path', data + end + + def test_fetch_http_redirects + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + url = 'http://gems.example.com/redirect' + + def fetcher.request(uri, request_class, last_modified = nil) + url = 'http://gems.example.com/redirect' + res = Net::HTTPMovedPermanently.new nil, 301, nil + res.add_field 'Location', url + res + end + + e = assert_raises Gem::RemoteFetcher::FetchError do + fetcher.fetch_http URI.parse(url) + end + + assert_equal "too many redirects (#{url})", e.message + end + + def test_fetch_s3 + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + url = 's3://testuser:testpass@my-bucket/gems/specs.4.8.gz' + $fetched_uri = nil + + def fetcher.request(uri, request_class, last_modified = nil) + $fetched_uri = uri + res = Net::HTTPOK.new nil, 200, nil + def res.body() 'success' end + res + end + + def fetcher.s3_expiration + 1395098371 + end + + data = fetcher.fetch_s3 URI.parse(url) + + assert_equal 'https://my-bucket.s3.amazonaws.com/gems/specs.4.8.gz?AWSAccessKeyId=testuser&Expires=1395098371&Signature=eUTr7NkpZEet%2BJySE%2BfH6qukroI%3D', $fetched_uri.to_s + assert_equal 'success', data + ensure + $fetched_uri = nil + end + + def test_fetch_s3_no_creds + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + url = 's3://my-bucket/gems/specs.4.8.gz' + e = assert_raises Gem::RemoteFetcher::FetchError do + fetcher.fetch_s3 URI.parse(url) + end + + assert_match "credentials needed", e.message + end + + def test_observe_no_proxy_env_single_host + use_ui @ui do + ENV["http_proxy"] = @proxy_uri + ENV["no_proxy"] = URI::parse(@server_uri).host + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + assert_data_from_server fetcher.fetch_path(@server_uri) + end + end + + def test_observe_no_proxy_env_list + use_ui @ui do + ENV["http_proxy"] = @proxy_uri + ENV["no_proxy"] = "fakeurl.com, #{URI::parse(@server_uri).host}" + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + assert_data_from_server fetcher.fetch_path(@server_uri) + end + end + + def test_request_block + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + + assert_throws :block_called do + fetcher.request URI('http://example'), Net::HTTP::Get do |req| + assert_kind_of Net::HTTPGenericRequest, req + throw :block_called + end + end + end + + def test_yaml_error_on_size + use_ui @ui do + self.class.enable_yaml = false + fetcher = Gem::RemoteFetcher.new nil + @fetcher = fetcher + assert_error { fetcher.size } + end + end + + def test_ssl_connection + ssl_server = self.class.start_ssl_server + temp_ca_cert = File.join(DIR, 'ca_cert.pem') + with_configured_fetcher(":ssl_ca_cert: #{temp_ca_cert}") do |fetcher| + fetcher.fetch_path("https://localhost:#{ssl_server.config[:Port]}/yaml") + end + end + + def test_ssl_client_cert_auth_connection + skip 'openssl is missing' unless defined?(OpenSSL::SSL) + + ssl_server = self.class.start_ssl_server({ + :SSLVerifyClient => + OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT}) + + temp_ca_cert = File.join(DIR, 'ca_cert.pem') + temp_client_cert = File.join(DIR, 'client.pem') + + with_configured_fetcher( + ":ssl_ca_cert: #{temp_ca_cert}\n" + + ":ssl_client_cert: #{temp_client_cert}\n") do |fetcher| + fetcher.fetch_path("https://localhost:#{ssl_server.config[:Port]}/yaml") + end + end + + def test_do_not_allow_invalid_client_cert_auth_connection + skip 'openssl is missing' unless defined?(OpenSSL::SSL) + + ssl_server = self.class.start_ssl_server({ + :SSLVerifyClient => + OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT}) + + temp_ca_cert = File.join(DIR, 'ca_cert.pem') + temp_client_cert = File.join(DIR, 'invalid_client.pem') + + with_configured_fetcher( + ":ssl_ca_cert: #{temp_ca_cert}\n" + + ":ssl_client_cert: #{temp_client_cert}\n") do |fetcher| + assert_raises Gem::RemoteFetcher::FetchError do + fetcher.fetch_path("https://localhost:#{ssl_server.config[:Port]}/yaml") + end + end + end + + def test_do_not_allow_insecure_ssl_connection_by_default + ssl_server = self.class.start_ssl_server + with_configured_fetcher do |fetcher| + assert_raises Gem::RemoteFetcher::FetchError do + fetcher.fetch_path("https://localhost:#{ssl_server.config[:Port]}/yaml") + end + end + end + + def test_ssl_connection_allow_verify_none + ssl_server = self.class.start_ssl_server + with_configured_fetcher(":ssl_verify_mode: 0") do |fetcher| + fetcher.fetch_path("https://localhost:#{ssl_server.config[:Port]}/yaml") + end + end + + def test_do_not_follow_insecure_redirect + ssl_server = self.class.start_ssl_server + temp_ca_cert = File.join(DIR, 'ca_cert.pem'), + with_configured_fetcher(":ssl_ca_cert: #{temp_ca_cert}") do |fetcher| + assert_raises Gem::RemoteFetcher::FetchError do + fetcher.fetch_path("https://localhost:#{ssl_server.config[:Port]}/insecure_redirect?to=#{@server_uri}") + end + end + end + + def with_configured_fetcher(config_str = nil, &block) + if config_str + temp_conf = File.join @tempdir, '.gemrc' + File.open temp_conf, 'w' do |fp| + fp.puts config_str + end + Gem.configuration = Gem::ConfigFile.new %W[--config-file #{temp_conf}] + end + fetcher = Gem::RemoteFetcher.new + yield fetcher + ensure + fetcher.close_all + Gem.configuration = nil + end + + def assert_error(exception_class=Exception) + got_exception = false + + begin + yield + rescue exception_class + got_exception = true + end + + assert got_exception, "Expected exception conforming to #{exception_class}" + end + + def assert_data_from_server(data) + assert_match(/0\.4\.11/, data, "Data is not from server") + end + + def assert_data_from_proxy(data) + assert_match(/0\.4\.2/, data, "Data is not from proxy") + end + + class NilLog < WEBrick::Log + def log(level, data) #Do nothing + end + end + + class << self + attr_reader :normal_server, :proxy_server + attr_accessor :enable_zip, :enable_yaml + + def start_servers + @normal_server ||= start_server(SERVER_DATA) + @proxy_server ||= start_server(PROXY_DATA) + @enable_yaml = true + @enable_zip = false + @ssl_server = nil + @ssl_server_thread = nil + end + + def stop_servers + if @normal_server + @normal_server.kill.join + @normal_server = nil + end + if @proxy_server + @proxy_server.kill.join + @proxy_server = nil + end + if @ssl_server + @ssl_server.stop + @ssl_server = nil + end + if @ssl_server_thread + @ssl_server_thread.kill.join + @ssl_server_thread = nil + end + end + + def normal_server_port + @normal_server[:server].config[:Port] + end + + def proxy_server_port + @proxy_server[:server].config[:Port] + end + + DIR = File.expand_path(File.dirname(__FILE__)) + + def start_ssl_server(config = {}) + raise MiniTest::Skip, 'openssl not installed' unless + defined?(OpenSSL::SSL) + + null_logger = NilLog.new + server = WEBrick::HTTPServer.new({ + :Port => 0, + :Logger => null_logger, + :AccessLog => [], + :SSLEnable => true, + :SSLCACertificateFile => File.join(DIR, 'ca_cert.pem'), + :SSLCertificate => cert('ssl_cert.pem'), + :SSLPrivateKey => key('ssl_key.pem'), + :SSLVerifyClient => nil, + :SSLCertName => nil + }.merge(config)) + server.mount_proc("/yaml") { |req, res| + res.body = "--- true\n" + } + server.mount_proc("/insecure_redirect") { |req, res| + res.set_redirect(WEBrick::HTTPStatus::MovedPermanently, req.query['to']) + } + server.ssl_context.tmp_dh_callback = proc {|_, _, k| OpenSSL::PKey::DH.new(k) } + t = Thread.new do + begin + server.start + rescue Exception => ex + abort ex.message + puts "ERROR during server thread: #{ex.message}" + ensure + server.shutdown + end + end + while server.status != :Running + sleep 0.1 + unless t.alive? + t.join + raise + end + end + @ssl_server = server + @ssl_server_thread = t + server + end + + private + + def start_server(data) + null_logger = NilLog.new + s = WEBrick::HTTPServer.new( + :Port => 0, + :DocumentRoot => nil, + :Logger => null_logger, + :AccessLog => null_logger + ) + s.mount_proc("/kill") { |req, res| s.shutdown } + s.mount_proc("/yaml") { |req, res| + if @enable_yaml + res.body = data + res['Content-Type'] = 'text/plain' + res['content-length'] = data.size + else + res.status = "404" + res.body = "<h1>NOT FOUND</h1>" + res['Content-Type'] = 'text/html' + end + } + s.mount_proc("/yaml.Z") { |req, res| + if @enable_zip + res.body = Zlib::Deflate.deflate(data) + res['Content-Type'] = 'text/plain' + else + res.status = "404" + res.body = "<h1>NOT FOUND</h1>" + res['Content-Type'] = 'text/html' + end + } + th = Thread.new do + begin + s.start + rescue Exception => ex + abort "ERROR during server thread: #{ex.message}" + ensure + s.shutdown + end + end + th[:server] = s + th + end + + def cert(filename) + OpenSSL::X509::Certificate.new(File.read(File.join(DIR, filename))) + end + + def key(filename) + OpenSSL::PKey::RSA.new(File.read(File.join(DIR, filename))) + end + end + + def test_correct_for_windows_path + path = "/C:/WINDOWS/Temp/gems" + assert_equal "C:/WINDOWS/Temp/gems", @fetcher.correct_for_windows_path(path) + + path = "/home/skillet" + assert_equal "/home/skillet", @fetcher.correct_for_windows_path(path) + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_request.rb b/jni/ruby/test/rubygems/test_gem_request.rb new file mode 100644 index 0000000..c45d5d8 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_request.rb @@ -0,0 +1,362 @@ +require 'rubygems/test_case' +require 'rubygems/request' +require 'ostruct' +require 'base64' + +class TestGemRequest < Gem::TestCase + + CA_CERT_FILE = cert_path 'ca' + CHILD_CERT = load_cert 'child' + PUBLIC_CERT = load_cert 'public' + PUBLIC_CERT_FILE = cert_path 'public' + SSL_CERT = load_cert 'ssl' + + def make_request uri, request_class, last_modified, proxy + Gem::Request.create_with_proxy uri, request_class, last_modified, proxy + end + + def setup + @proxies = %w[http_proxy HTTP_PROXY http_proxy_user HTTP_PROXY_USER http_proxy_pass HTTP_PROXY_PASS no_proxy NO_PROXY] + @old_proxies = @proxies.map {|k| ENV[k] } + @proxies.each {|k| ENV[k] = nil } + + super + + @proxy_uri = "http://localhost:1234" + @uri = URI('http://example') + + @request = make_request @uri, nil, nil, nil + end + + def teardown + super + Gem.configuration[:http_proxy] = nil + @proxies.each_with_index {|k, i| ENV[k] = @old_proxies[i] } + end + + def test_initialize_proxy + proxy_uri = 'http://proxy.example.com' + + request = make_request @uri, nil, nil, proxy_uri + + assert_equal proxy_uri, request.proxy_uri.to_s + end + + def test_initialize_proxy_URI + proxy_uri = 'http://proxy.example.com' + + request = make_request @uri, nil, nil, URI(proxy_uri) + + assert_equal proxy_uri, request.proxy_uri.to_s + end + + def test_initialize_proxy_ENV + ENV['http_proxy'] = @proxy_uri + ENV['http_proxy_user'] = 'foo' + ENV['http_proxy_pass'] = 'bar' + + request = make_request @uri, nil, nil, nil + + proxy = request.proxy_uri + + assert_equal 'foo', proxy.user + assert_equal 'bar', proxy.password + end + + def test_initialize_proxy_ENV_https + ENV['https_proxy'] = @proxy_uri + + request = make_request URI('https://example'), nil, nil, nil + + proxy = request.proxy_uri + + assert_equal URI(@proxy_uri), proxy + end + + def test_configure_connection_for_https + connection = Net::HTTP.new 'localhost', 443 + + request = Class.new(Gem::Request) { + def self.get_cert_files + [TestGemRequest::PUBLIC_CERT_FILE] + end + }.create_with_proxy URI('https://example'), nil, nil, nil + + Gem::Request.configure_connection_for_https connection, request.cert_files + + cert_store = connection.cert_store + + assert cert_store.verify CHILD_CERT + end + + def test_configure_connection_for_https_ssl_ca_cert + ssl_ca_cert, Gem.configuration.ssl_ca_cert = + Gem.configuration.ssl_ca_cert, CA_CERT_FILE + + connection = Net::HTTP.new 'localhost', 443 + + request = Class.new(Gem::Request) { + def self.get_cert_files + [TestGemRequest::PUBLIC_CERT_FILE] + end + }.create_with_proxy URI('https://example'), nil, nil, nil + + Gem::Request.configure_connection_for_https connection, request.cert_files + + cert_store = connection.cert_store + + assert cert_store.verify CHILD_CERT + assert cert_store.verify SSL_CERT + ensure + Gem.configuration.ssl_ca_cert = ssl_ca_cert + end + + def test_get_proxy_from_env_fallback + ENV['http_proxy'] = @proxy_uri + request = make_request @uri, nil, nil, nil + proxy = request.proxy_uri + + assert_equal URI(@proxy_uri), proxy + end + + def test_get_proxy_from_env_https + ENV['https_proxy'] = @proxy_uri + uri = URI('https://example') + request = make_request uri, nil, nil, nil + + proxy = request.proxy_uri + + assert_equal URI(@proxy_uri), proxy + end + + def test_get_proxy_from_env_domain + ENV['http_proxy'] = @proxy_uri + ENV['http_proxy_user'] = 'foo\user' + ENV['http_proxy_pass'] = 'my bar' + request = make_request @uri, nil, nil, nil + + proxy = request.proxy_uri + + assert_equal 'foo\user', Gem::UriFormatter.new(proxy.user).unescape + assert_equal 'my bar', Gem::UriFormatter.new(proxy.password).unescape + end + + def test_get_proxy_from_env_escape + ENV['http_proxy'] = @proxy_uri + ENV['http_proxy_user'] = 'foo@user' + ENV['http_proxy_pass'] = 'my@bar' + request = make_request @uri, nil, nil, nil + + proxy = request.proxy_uri + + assert_equal 'foo%40user', proxy.user + assert_equal 'my%40bar', proxy.password + end + + def test_get_proxy_from_env_normalize + ENV['HTTP_PROXY'] = 'fakeurl:12345' + request = make_request @uri, nil, nil, nil + + assert_equal 'http://fakeurl:12345', request.proxy_uri.to_s + end + + def test_get_proxy_from_env_empty + ENV['HTTP_PROXY'] = '' + ENV.delete 'http_proxy' + request = make_request @uri, nil, nil, nil + + assert_nil request.proxy_uri + end + + def test_fetch + uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}" + response = util_stub_net_http(:body => :junk, :code => 200) do + @request = make_request(uri, Net::HTTP::Get, nil, nil) + + @request.fetch + end + + assert_equal 200, response.code + assert_equal :junk, response.body + end + + def test_fetch_basic_auth + uri = URI.parse "https://user:pass@example.rubygems/specs.#{Gem.marshal_version}" + conn = util_stub_net_http(:body => :junk, :code => 200) do |c| + @request = make_request(uri, Net::HTTP::Get, nil, nil) + @request.fetch + c + end + + auth_header = conn.payload['Authorization'] + assert_equal "Basic #{Base64.encode64('user:pass')}".strip, auth_header + end + + def test_fetch_basic_auth_encoded + uri = URI.parse "https://user:%7BDEScede%7Dpass@example.rubygems/specs.#{Gem.marshal_version}" + conn = util_stub_net_http(:body => :junk, :code => 200) do |c| + @request = make_request(uri, Net::HTTP::Get, nil, nil) + @request.fetch + c + end + + auth_header = conn.payload['Authorization'] + assert_equal "Basic #{Base64.encode64('user:{DEScede}pass')}".strip, auth_header + end + + def test_fetch_head + uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}" + response = util_stub_net_http(:body => '', :code => 200) do |conn| + @request = make_request(uri, Net::HTTP::Get, nil, nil) + @request.fetch + end + + assert_equal 200, response.code + assert_equal '', response.body + end + + def test_fetch_unmodified + uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}" + t = Time.utc(2013, 1, 2, 3, 4, 5) + conn, response = util_stub_net_http(:body => '', :code => 304) do |c| + @request = make_request(uri, Net::HTTP::Get, t, nil) + [c, @request.fetch] + end + + assert_equal 304, response.code + assert_equal '', response.body + + modified_header = conn.payload['if-modified-since'] + + assert_equal 'Wed, 02 Jan 2013 03:04:05 GMT', modified_header + end + + def test_user_agent + ua = make_request(@uri, nil, nil, nil).user_agent + + assert_match %r%^RubyGems/\S+ \S+ Ruby/\S+ \(.*?\)%, ua + assert_match %r%RubyGems/#{Regexp.escape Gem::VERSION}%, ua + assert_match %r% #{Regexp.escape Gem::Platform.local.to_s} %, ua + assert_match %r%Ruby/#{Regexp.escape RUBY_VERSION}%, ua + assert_match %r%\(#{Regexp.escape RUBY_RELEASE_DATE} %, ua + end + + def test_user_agent_engine + util_save_version + + Object.send :remove_const, :RUBY_ENGINE if defined?(RUBY_ENGINE) + Object.send :const_set, :RUBY_ENGINE, 'vroom' + + ua = make_request(@uri, nil, nil, nil).user_agent + + assert_match %r%\) vroom%, ua + ensure + util_restore_version + end + + def test_user_agent_engine_ruby + util_save_version + + Object.send :remove_const, :RUBY_ENGINE if defined?(RUBY_ENGINE) + Object.send :const_set, :RUBY_ENGINE, 'ruby' + + ua = make_request(@uri, nil, nil, nil).user_agent + + assert_match %r%\)%, ua + ensure + util_restore_version + end + + def test_user_agent_patchlevel + util_save_version + + Object.send :remove_const, :RUBY_PATCHLEVEL + Object.send :const_set, :RUBY_PATCHLEVEL, 5 + + ua = make_request(@uri, nil, nil, nil).user_agent + + assert_match %r% patchlevel 5\)%, ua + ensure + util_restore_version + end + + def test_user_agent_revision + util_save_version + + Object.send :remove_const, :RUBY_PATCHLEVEL + Object.send :const_set, :RUBY_PATCHLEVEL, -1 + Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION) + Object.send :const_set, :RUBY_REVISION, 6 + + ua = make_request(@uri, nil, nil, nil).user_agent + + assert_match %r% revision 6\)%, ua + assert_match %r%Ruby/#{Regexp.escape RUBY_VERSION}dev%, ua + ensure + util_restore_version + end + + def test_user_agent_revision_missing + util_save_version + + Object.send :remove_const, :RUBY_PATCHLEVEL + Object.send :const_set, :RUBY_PATCHLEVEL, -1 + Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION) + + ua = make_request(@uri, nil, nil, nil).user_agent + + assert_match %r%\(#{Regexp.escape RUBY_RELEASE_DATE}\)%, ua + ensure + util_restore_version + end + + def util_restore_version + Object.send :remove_const, :RUBY_ENGINE if defined?(RUBY_ENGINE) + Object.send :const_set, :RUBY_ENGINE, @orig_RUBY_ENGINE if + defined?(@orig_RUBY_ENGINE) + + Object.send :remove_const, :RUBY_PATCHLEVEL + Object.send :const_set, :RUBY_PATCHLEVEL, @orig_RUBY_PATCHLEVEL + + Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION) + Object.send :const_set, :RUBY_REVISION, @orig_RUBY_REVISION if + defined?(@orig_RUBY_REVISION) + end + + def util_save_version + @orig_RUBY_ENGINE = RUBY_ENGINE if defined? RUBY_ENGINE + @orig_RUBY_PATCHLEVEL = RUBY_PATCHLEVEL + @orig_RUBY_REVISION = RUBY_REVISION if defined? RUBY_REVISION + end + + def util_stub_net_http hash + old_client = Gem::Request::ConnectionPools.client + conn = Conn.new OpenStruct.new(hash) + Gem::Request::ConnectionPools.client = conn + yield conn + ensure + Gem::Request::ConnectionPools.client = old_client + end + + class Conn + attr_accessor :payload + + def new *args; self; end + def use_ssl=(bool); end + def verify_mode=(setting); end + def cert_store=(setting); end + def start; end + + def initialize(response) + @response = response + self.payload = nil + end + + def request(req) + self.payload = req + @response + end + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_request_connection_pools.rb b/jni/ruby/test/rubygems/test_gem_request_connection_pools.rb new file mode 100644 index 0000000..1cf6b27 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_request_connection_pools.rb @@ -0,0 +1,120 @@ +require 'rubygems/test_case' +require 'rubygems/request' +require 'timeout' + +class TestGemRequestConnectionPool < Gem::TestCase + class FakeHttp + def initialize *args + end + + def start + end + end + + def setup + super + @old_client = Gem::Request::ConnectionPools.client + Gem::Request::ConnectionPools.client = FakeHttp + + @proxy = URI 'http://proxy.example' + end + + def teardown + Gem::Request::ConnectionPools.client = @old_client + super + end + + def test_checkout_same_connection + uri = URI.parse('http://example/some_endpoint') + + pools = Gem::Request::ConnectionPools.new nil, [] + pool = pools.pool_for uri + conn = pool.checkout + pool.checkin conn + + assert_equal conn, pool.checkout + end + + def test_to_proxy_eh + pools = Gem::Request::ConnectionPools.new nil, [] + + env_no_proxy = %w[ + 1.no-proxy.example + 2.no-proxy.example + ] + + no_proxy = pools.send :no_proxy?, '2.no-proxy.example', env_no_proxy + + assert no_proxy, 'match' + + no_proxy = pools.send :no_proxy?, 'proxy.example', env_no_proxy + + refute no_proxy, 'mismatch' + end + + def test_to_proxy_eh_wildcard + pools = Gem::Request::ConnectionPools.new nil, [] + + env_no_proxy = %w[ + .no-proxy.example + ] + + no_proxy = pools.send :no_proxy?, '2.no-proxy.example', env_no_proxy + + assert no_proxy, 'wildcard matching subdomain' + + no_proxy = pools.send :no_proxy?, 'no-proxy.example', env_no_proxy + + assert no_proxy, 'wildcard matching dotless domain' + + no_proxy = pools.send :no_proxy?, 'proxy.example', env_no_proxy + + refute no_proxy, 'wildcard mismatch' + end + + def test_net_http_args + pools = Gem::Request::ConnectionPools.new nil, [] + + net_http_args = pools.send :net_http_args, URI('http://example'), nil + + assert_equal ['example', 80], net_http_args + end + + def test_net_http_args_proxy + pools = Gem::Request::ConnectionPools.new nil, [] + + net_http_args = pools.send :net_http_args, URI('http://example'), @proxy + + assert_equal ['example', 80, 'proxy.example', 80, nil, nil], net_http_args + end + + def test_net_http_args_no_proxy + orig_no_proxy, ENV['no_proxy'] = ENV['no_proxy'], 'example' + + pools = Gem::Request::ConnectionPools.new nil, [] + + net_http_args = pools.send :net_http_args, URI('http://example'), @proxy + + assert_equal ['example', 80, nil, nil], net_http_args + + ensure + ENV['no_proxy'] = orig_no_proxy + end + + def test_thread_waits_for_connection + uri = URI.parse('http://example/some_endpoint') + pools = Gem::Request::ConnectionPools.new nil, [] + pool = pools.pool_for uri + + pool.checkout + + t1 = Thread.new { + timeout(1) do + pool.checkout + end + } + assert_raises(Timeout::Error) do + t1.join + end + end +end diff --git a/jni/ruby/test/rubygems/test_gem_request_set.rb b/jni/ruby/test/rubygems/test_gem_request_set.rb new file mode 100644 index 0000000..3c1d5ac --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_request_set.rb @@ -0,0 +1,597 @@ +require 'rubygems/test_case' +require 'rubygems/request_set' + +class TestGemRequestSet < Gem::TestCase + def setup + super + + Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new + + @DR = Gem::Resolver + end + + def test_gem + util_spec "a", "2" + + rs = Gem::RequestSet.new + rs.gem "a", "= 2" + + assert_equal [Gem::Dependency.new("a", "=2")], rs.dependencies + end + + def test_gem_duplicate + rs = Gem::RequestSet.new + + rs.gem 'a', '1' + rs.gem 'a', '2' + + assert_equal [dep('a', '= 1', '= 2')], rs.dependencies + end + + def test_import + rs = Gem::RequestSet.new + rs.gem 'a' + + rs.import [dep('b')] + + assert_equal [dep('a'), dep('b')], rs.dependencies + end + + def test_install_from_gemdeps + spec_fetcher do |fetcher| + fetcher.gem 'a', 2 + end + + done_installing_ran = false + + Gem.done_installing do |installer, specs| + done_installing_ran = true + end + + rs = Gem::RequestSet.new + installed = [] + + open 'gem.deps.rb', 'w' do |io| + io.puts 'gem "a"' + io.flush + + result = rs.install_from_gemdeps :gemdeps => io.path do |req, installer| + installed << req.full_name + end + + assert_kind_of Array, result # what is supposed to be in here? + end + + assert_includes installed, 'a-2' + assert_path_exists File.join @gemhome, 'gems', 'a-2' + assert_path_exists 'gem.deps.rb.lock' + + assert rs.remote + refute done_installing_ran + end + + def test_install_from_gemdeps_explain + spec_fetcher do |fetcher| + fetcher.gem 'a', 2 + end + + rs = Gem::RequestSet.new + + open 'gem.deps.rb', 'w' do |io| + io.puts 'gem "a"' + io.flush + + expected = <<-EXPECTED +Gems to install: + a-2 + EXPECTED + + assert_output expected do + rs.install_from_gemdeps :gemdeps => io.path, :explain => true + end + end + end + + def test_install_from_gemdeps_install_dir + spec_fetcher do |fetcher| + fetcher.gem 'a', 2 + end + + util_clear_gems + refute_path_exists File.join Gem.dir, 'gems', 'a-2' + + rs = Gem::RequestSet.new + installed = [] + + open 'gem.deps.rb', 'w' do |io| + io.puts 'gem "a"' + end + + options = { + :gemdeps => 'gem.deps.rb', + :install_dir => "#{@gemhome}2", + } + + rs.install_from_gemdeps options do |req, installer| + installed << req.full_name + end + + assert_includes installed, 'a-2' + refute_path_exists File.join Gem.dir, 'gems', 'a-2' + end + + def test_install_from_gemdeps_local + spec_fetcher do |fetcher| + fetcher.gem 'a', 2 + end + + rs = Gem::RequestSet.new + + open 'gem.deps.rb', 'w' do |io| + io.puts 'gem "a"' + io.flush + + assert_raises Gem::UnsatisfiableDependencyError do + rs.install_from_gemdeps :gemdeps => io.path, :domain => :local + end + end + + refute rs.remote + end + + def test_install_from_gemdeps_lockfile + spec_fetcher do |fetcher| + fetcher.gem 'a', 1 + fetcher.gem 'a', 2 + fetcher.gem 'b', 1, 'a' => '>= 0' + fetcher.clear + end + + rs = Gem::RequestSet.new + installed = [] + + open 'gem.deps.rb.lock', 'w' do |io| + io.puts <<-LOCKFILE +GEM + remote: #{@gem_repo} + specs: + a (1) + b (1) + a (~> 1.0) + +PLATFORMS + #{Gem::Platform::RUBY} + +DEPENDENCIES + b + LOCKFILE + end + + open 'gem.deps.rb', 'w' do |io| + io.puts 'gem "b"' + end + + rs.install_from_gemdeps :gemdeps => 'gem.deps.rb' do |req, installer| + installed << req.full_name + end + + assert_includes installed, 'b-1' + assert_includes installed, 'a-1' + + assert_path_exists File.join @gemhome, 'specifications', 'a-1.gemspec' + assert_path_exists File.join @gemhome, 'specifications', 'b-1.gemspec' + end + + def test_install_from_gemdeps_version_mismatch + spec_fetcher do |fetcher| + fetcher.gem 'a', 2 + end + + rs = Gem::RequestSet.new + installed = [] + + open 'gem.deps.rb', 'w' do |io| + io.puts <<-GEM_DEPS +gem "a" +ruby "0" + GEM_DEPS + + io.flush + + rs.install_from_gemdeps :gemdeps => io.path do |req, installer| + installed << req.full_name + end + end + + assert_includes installed, 'a-2' + end + + def test_load_gemdeps + rs = Gem::RequestSet.new + + tf = Tempfile.open 'gem.deps.rb' do |io| + io.puts 'gem "a"' + io.flush + + gem_deps = rs.load_gemdeps io.path + + assert_kind_of Gem::RequestSet::GemDependencyAPI, gem_deps + io + end + tf.close! if tf.respond_to? :close! + + assert_equal [dep('a')], rs.dependencies + + assert rs.git_set + assert rs.vendor_set + end + + def test_load_gemdeps_installing + rs = Gem::RequestSet.new + + tf = Tempfile.open 'gem.deps.rb' do |io| + io.puts 'ruby "0"' + io.puts 'gem "a"' + io.flush + + gem_deps = rs.load_gemdeps io.path, [], true + + assert_kind_of Gem::RequestSet::GemDependencyAPI, gem_deps + io + end + tf.close! if tf.respond_to? :close! + + assert_equal [dep('a')], rs.dependencies + end + + def test_load_gemdeps_without_groups + rs = Gem::RequestSet.new + + tf = Tempfile.open 'gem.deps.rb' do |io| + io.puts 'gem "a", :group => :test' + io.flush + + rs.load_gemdeps io.path, [:test] + io + end + tf.close! if tf.respond_to? :close! + + assert_empty rs.dependencies + end + + def test_resolve + a = util_spec "a", "2", "b" => ">= 2" + b = util_spec "b", "2" + + rs = Gem::RequestSet.new + rs.gem "a" + + orig_errors = rs.errors + + res = rs.resolve StaticSet.new([a, b]) + assert_equal 2, res.size + + names = res.map { |s| s.full_name }.sort + + assert_equal ["a-2", "b-2"], names + + refute_same orig_errors, rs.errors + end + + def test_bug_bug_990 + a = util_spec 'a', '1.b', 'b' => '~> 1.a' + b = util_spec 'b', '1.b', 'c' => '>= 1' + c = util_spec 'c', '1.1.b' + + rs = Gem::RequestSet.new + rs.gem 'a' + rs.prerelease = true + + res = rs.resolve StaticSet.new([a, b, c]) + assert_equal 3, res.size + + names = res.map { |s| s.full_name }.sort + + assert_equal %w[a-1.b b-1.b c-1.1.b], names + end + + def test_resolve_development + a = util_spec 'a', 1 + spec = Gem::Resolver::SpecSpecification.new nil, a + + rs = Gem::RequestSet.new + rs.gem 'a' + rs.development = true + + res = rs.resolve StaticSet.new [spec] + assert_equal 1, res.size + + assert rs.resolver.development + refute rs.resolver.development_shallow + end + + def test_resolve_development_shallow + a = util_spec 'a', 1 do |s| s.add_development_dependency 'b' end + b = util_spec 'b', 1 do |s| s.add_development_dependency 'c' end + c = util_spec 'c', 1 + + a_spec = Gem::Resolver::SpecSpecification.new nil, a + b_spec = Gem::Resolver::SpecSpecification.new nil, b + c_spec = Gem::Resolver::SpecSpecification.new nil, c + + rs = Gem::RequestSet.new + rs.gem 'a' + rs.development = true + rs.development_shallow = true + + res = rs.resolve StaticSet.new [a_spec, b_spec, c_spec] + assert_equal 2, res.size + + assert rs.resolver.development + assert rs.resolver.development_shallow + end + + def test_resolve_git + name, _, repository, = git_gem + + rs = Gem::RequestSet.new + + tf = Tempfile.open 'gem.deps.rb' do |io| + io.puts <<-gems_deps_rb + gem "#{name}", :git => "#{repository}" + gems_deps_rb + + io.flush + + rs.load_gemdeps io.path + io + end + tf.close! if tf.respond_to? :close! + + res = rs.resolve + assert_equal 1, res.size + + names = res.map { |s| s.full_name }.sort + + assert_equal %w[a-1], names + + assert_equal [@DR::BestSet, @DR::GitSet, @DR::VendorSet], + rs.sets.map { |set| set.class } + end + + def test_resolve_ignore_dependencies + a = util_spec "a", "2", "b" => ">= 2" + b = util_spec "b", "2" + + rs = Gem::RequestSet.new + rs.gem "a" + rs.ignore_dependencies = true + + res = rs.resolve StaticSet.new([a, b]) + assert_equal 1, res.size + + names = res.map { |s| s.full_name }.sort + + assert_equal %w[a-2], names + end + + def test_resolve_incompatible + a1 = util_spec 'a', 1 + a2 = util_spec 'a', 2 + + rs = Gem::RequestSet.new + rs.gem 'a', '= 1' + rs.gem 'a', '= 2' + + set = StaticSet.new [a1, a2] + + assert_raises Gem::UnsatisfiableDependencyError do + rs.resolve set + end + end + + def test_resolve_vendor + a_name, _, a_directory = vendor_gem 'a', 1 do |s| + s.add_dependency 'b', '~> 2.0' + end + + b_name, _, b_directory = vendor_gem 'b', 2 + + rs = Gem::RequestSet.new + + tf = Tempfile.open 'gem.deps.rb' do |io| + io.puts <<-gems_deps_rb + gem "#{a_name}", :path => "#{a_directory}" + gem "#{b_name}", :path => "#{b_directory}" + gems_deps_rb + + io.flush + + rs.load_gemdeps io.path + io + end + tf.close! if tf.respond_to? :close! + + res = rs.resolve + assert_equal 2, res.size + + names = res.map { |s| s.full_name }.sort + + assert_equal ["a-1", "b-2"], names + + assert_equal [@DR::BestSet, @DR::GitSet, @DR::VendorSet], + rs.sets.map { |set| set.class } + end + + def test_sorted_requests + a = util_spec "a", "2", "b" => ">= 2" + b = util_spec "b", "2", "c" => ">= 2" + c = util_spec "c", "2" + + rs = Gem::RequestSet.new + rs.gem "a" + + rs.resolve StaticSet.new([a, b, c]) + + names = rs.sorted_requests.map { |s| s.full_name } + assert_equal %w!c-2 b-2 a-2!, names + end + + def test_install + done_installing_ran = false + + Gem.done_installing do + done_installing_ran = true + end + + spec_fetcher do |fetcher| + fetcher.gem "a", "1", "b" => "= 1" + fetcher.gem "b", "1" + + fetcher.clear + end + + rs = Gem::RequestSet.new + rs.gem 'a' + + rs.resolve + + reqs = [] + installers = [] + + installed = rs.install({}) do |req, installer| + reqs << req + installers << installer + end + + assert_equal %w[b-1 a-1], reqs.map { |req| req.full_name } + assert_equal %w[b-1 a-1], + installers.map { |installer| installer.spec.full_name } + + assert_path_exists File.join @gemhome, 'specifications', 'a-1.gemspec' + assert_path_exists File.join @gemhome, 'specifications', 'b-1.gemspec' + + assert_equal %w[b-1 a-1], installed.map { |s| s.full_name } + + assert done_installing_ran + end + + def test_install_into + spec_fetcher do |fetcher| + fetcher.gem "a", "1", "b" => "= 1" + fetcher.gem "b", "1" + end + + rs = Gem::RequestSet.new + rs.gem "a" + + rs.resolve + + installed = rs.install_into @tempdir do + assert_equal @tempdir, ENV['GEM_HOME'] + end + + assert_path_exists File.join @tempdir, 'specifications', 'a-1.gemspec' + assert_path_exists File.join @tempdir, 'specifications', 'b-1.gemspec' + + assert_equal %w!b-1 a-1!, installed.map { |s| s.full_name } + end + + def test_install_into_development_shallow + spec_fetcher do |fetcher| + fetcher.gem 'a', '1' do |s| + s.add_development_dependency 'b', '= 1' + end + + fetcher.gem 'b', '1' do |s| + s.add_development_dependency 'c', '= 1' + end + + fetcher.spec 'c', '1' + end + + rs = Gem::RequestSet.new + rs.development = true + rs.development_shallow = true + rs.gem 'a' + + rs.resolve + + options = { + :development => true, + :development_shallow => true, + } + + installed = rs.install_into @tempdir, true, options do + assert_equal @tempdir, ENV['GEM_HOME'] + end + + assert_equal %w[a-1 b-1], installed.map { |s| s.full_name }.sort + end + + def test_sorted_requests_development_shallow + a = util_spec 'a', 1 do |s| s.add_development_dependency 'b' end + b = util_spec 'b', 1 do |s| s.add_development_dependency 'c' end + c = util_spec 'c', 1 + + rs = Gem::RequestSet.new + rs.gem 'a' + rs.development = true + rs.development_shallow = true + + a_spec = Gem::Resolver::SpecSpecification.new nil, a + b_spec = Gem::Resolver::SpecSpecification.new nil, b + c_spec = Gem::Resolver::SpecSpecification.new nil, c + + rs.resolve StaticSet.new [a_spec, b_spec, c_spec] + + assert_equal %w[b-1 a-1], rs.sorted_requests.map { |req| req.full_name } + end + + def test_tsort_each_child_development + a = util_spec 'a', 1 do |s| s.add_development_dependency 'b' end + b = util_spec 'b', 1 do |s| s.add_development_dependency 'c' end + c = util_spec 'c', 1 + + rs = Gem::RequestSet.new + rs.gem 'a' + rs.development = true + rs.development_shallow = true + + a_spec = Gem::Resolver::SpecSpecification.new nil, a + b_spec = Gem::Resolver::SpecSpecification.new nil, b + c_spec = Gem::Resolver::SpecSpecification.new nil, c + + rs.resolve StaticSet.new [a_spec, b_spec, c_spec] + + a_req = Gem::Resolver::ActivationRequest.new a_spec, nil + + deps = rs.enum_for(:tsort_each_child, a_req).to_a + + assert_equal %w[b], deps.map { |dep| dep.name } + end + + def test_tsort_each_child_development_shallow + a = util_spec 'a', 1 do |s| s.add_development_dependency 'b' end + b = util_spec 'b', 1 do |s| s.add_development_dependency 'c' end + c = util_spec 'c', 1 + + rs = Gem::RequestSet.new + rs.gem 'a' + rs.development = true + rs.development_shallow = true + + a_spec = Gem::Resolver::SpecSpecification.new nil, a + b_spec = Gem::Resolver::SpecSpecification.new nil, b + c_spec = Gem::Resolver::SpecSpecification.new nil, c + + rs.resolve StaticSet.new [a_spec, b_spec, c_spec] + + b_req = Gem::Resolver::ActivationRequest.new b_spec, nil + + deps = rs.enum_for(:tsort_each_child, b_req).to_a + + assert_empty deps + end + +end diff --git a/jni/ruby/test/rubygems/test_gem_request_set_gem_dependency_api.rb b/jni/ruby/test/rubygems/test_gem_request_set_gem_dependency_api.rb new file mode 100644 index 0000000..65b30f8 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_request_set_gem_dependency_api.rb @@ -0,0 +1,823 @@ +require 'rubygems/test_case' +require 'rubygems/request_set' + +class TestGemRequestSetGemDependencyAPI < Gem::TestCase + + def setup + super + + @GDA = Gem::RequestSet::GemDependencyAPI + + @set = Gem::RequestSet.new + + @git_set = Gem::Resolver::GitSet.new + @vendor_set = Gem::Resolver::VendorSet.new + + @gda = @GDA.new @set, 'gem.deps.rb' + @gda.instance_variable_set :@git_set, @git_set + @gda.instance_variable_set :@vendor_set, @vendor_set + end + + def with_engine_version name, version + engine = RUBY_ENGINE if Object.const_defined? :RUBY_ENGINE + engine_version_const = "#{Gem.ruby_engine.upcase}_VERSION" + engine_version = Object.const_get engine_version_const + + Object.send :remove_const, :RUBY_ENGINE if engine + Object.send :remove_const, engine_version_const if name == 'ruby' and + Object.const_defined? engine_version_const + + new_engine_version_const = "#{name.upcase}_VERSION" + Object.const_set :RUBY_ENGINE, name if name + Object.const_set new_engine_version_const, version if version + + Gem.instance_variable_set :@ruby_version, Gem::Version.new(version) + + yield + + ensure + Object.send :remove_const, :RUBY_ENGINE if name + Object.send :remove_const, new_engine_version_const if version + + Object.send :remove_const, engine_version_const if name == 'ruby' and + Object.const_defined? engine_version_const + + Object.const_set :RUBY_ENGINE, engine if engine + Object.const_set engine_version_const, engine_version unless + Object.const_defined? engine_version_const + + Gem.send :remove_instance_variable, :@ruby_version if + Gem.instance_variables.include? :@ruby_version + end + + def test_gemspec_without_group + @gda.send :add_dependencies, [:development], [dep('a', '= 1')] + + assert_equal [dep('a', '= 1')], @set.dependencies + + @gda.without_groups << :development + + @gda.send :add_dependencies, [:development], [dep('b', '= 2')] + + assert_equal [dep('a', '= 1')], @set.dependencies + end + + def test_gem + @gda.gem 'a' + + assert_equal [dep('a')], @set.dependencies + + assert_equal %w[a], @gda.requires['a'] + + expected = { 'a' => nil } + + assert_equal expected, @gda.dependencies + end + + def test_gem_duplicate + @gda.gem 'a' + + _, err = capture_io do + @gda.gem 'a' + end + + expected = "Gem dependencies file gem.deps.rb requires a more than once." + + assert_match expected, err + end + + def test_gem_git + @gda.gem 'a', :git => 'git/a' + + assert_equal [dep('a')], @set.dependencies + + assert_equal %w[git/a master], @git_set.repositories['a'] + + expected = { 'a' => '!' } + + assert_equal expected, @gda.dependencies + end + + def test_gem_bitbucket + @gda.gem 'a', :bitbucket => 'example/repository' + + assert_equal [dep('a')], @set.dependencies + + assert_equal %w[https://example@bitbucket.org/example/repository.git master], + @git_set.repositories['a'] + + expected = { 'a' => '!' } + + assert_equal expected, @gda.dependencies + end + + def test_gem_bitbucket_expand_path + @gda.gem 'a', :bitbucket => 'example' + + assert_equal [dep('a')], @set.dependencies + + assert_equal %w[https://example@bitbucket.org/example/example.git master], + @git_set.repositories['a'] + + expected = { 'a' => '!' } + + assert_equal expected, @gda.dependencies + end + + def test_gem_git_branch + @gda.gem 'a', :git => 'git/a', :branch => 'other', :tag => 'v1' + + assert_equal [dep('a')], @set.dependencies + + assert_equal %w[git/a other], @git_set.repositories['a'] + end + + def test_gem_git_gist + @gda.gem 'a', :gist => 'a' + + assert_equal [dep('a')], @set.dependencies + + assert_equal %w[https://gist.github.com/a.git master], + @git_set.repositories['a'] + end + + def test_gem_git_ref + @gda.gem 'a', :git => 'git/a', :ref => 'abcd123', :branch => 'other' + + assert_equal [dep('a')], @set.dependencies + + assert_equal %w[git/a abcd123], @git_set.repositories['a'] + end + + def test_gem_git_submodules + @gda.gem 'a', :git => 'git/a', :submodules => true + + assert_equal [dep('a')], @set.dependencies + + assert_equal %w[git/a master], @git_set.repositories['a'] + assert_equal %w[git/a], @git_set.need_submodules.keys + end + + def test_gem_git_tag + @gda.gem 'a', :git => 'git/a', :tag => 'v1' + + assert_equal [dep('a')], @set.dependencies + + assert_equal %w[git/a v1], @git_set.repositories['a'] + end + + def test_gem_github + @gda.gem 'a', :github => 'example/repository' + + assert_equal [dep('a')], @set.dependencies + + assert_equal %w[git://github.com/example/repository.git master], + @git_set.repositories['a'] + + expected = { 'a' => '!' } + + assert_equal expected, @gda.dependencies + end + + def test_gem_github_expand_path + @gda.gem 'a', :github => 'example' + + assert_equal [dep('a')], @set.dependencies + + assert_equal %w[git://github.com/example/example.git master], + @git_set.repositories['a'] + + expected = { 'a' => '!' } + + assert_equal expected, @gda.dependencies + end + + def test_gem_group + @gda.gem 'a', :group => :test + + assert_equal [dep('a')], @set.dependencies + end + + def test_gem_group_without + @gda.without_groups << :test + + @gda.gem 'a', :group => :test + + assert_empty @set.dependencies + + expected = { 'a' => nil } + + assert_equal expected, @gda.dependencies + end + + def test_gem_groups + @gda.gem 'a', :groups => [:test, :development] + + assert_equal [dep('a')], @set.dependencies + end + + def test_gem_path + name, version, directory = vendor_gem + + @gda.gem name, :path => directory + + assert_equal [dep(name)], @set.dependencies + + loaded = @vendor_set.load_spec(name, version, Gem::Platform::RUBY, nil) + + assert_equal "#{name}-#{version}", loaded.full_name + + expected = { name => '!' } + + assert_equal expected, @gda.dependencies + end + + def test_gem_platforms + win_platform, Gem.win_platform = Gem.win_platform?, false + + with_engine_version 'ruby', '2.0.0' do + @gda.gem 'a', :platforms => :ruby + + refute_empty @set.dependencies + end + ensure + Gem.win_platform = win_platform + end + + def test_gem_platforms_bundler_ruby + win_platform, Gem.win_platform = Gem.win_platform?, false + + with_engine_version 'ruby', '2.0.0' do + set = Gem::RequestSet.new + gda = @GDA.new set, 'gem.deps.rb' + gda.gem 'a', :platforms => :ruby + + refute_empty set.dependencies + end + + with_engine_version 'rbx', '2.0.0' do + set = Gem::RequestSet.new + gda = @GDA.new set, 'gem.deps.rb' + gda.gem 'a', :platforms => :ruby + + refute_empty set.dependencies + end + + with_engine_version 'jruby', '1.7.6' do + set = Gem::RequestSet.new + gda = @GDA.new set, 'gem.deps.rb' + gda.gem 'a', :platforms => :ruby + + assert_empty set.dependencies + end + + Gem.win_platform = true + + with_engine_version 'ruby', '2.0.0' do + set = Gem::RequestSet.new + gda = @GDA.new set, 'gem.deps.rb' + gda.gem 'a', :platforms => :ruby + + assert_empty set.dependencies + end + + Gem.win_platform = win_platform + end + + def test_gem_platforms_engine + with_engine_version 'jruby', '1.7.6' do + @gda.gem 'a', :platforms => :mri + + assert_empty @set.dependencies + end + end + + def test_gem_platforms_maglev + win_platform, Gem.win_platform = Gem.win_platform?, false + + with_engine_version 'maglev', '1.0.0' do + set = Gem::RequestSet.new + gda = @GDA.new set, 'gem.deps.rb' + gda.gem 'a', :platforms => :ruby + + refute_empty set.dependencies + + set = Gem::RequestSet.new + gda = @GDA.new set, 'gem.deps.rb' + gda.gem 'a', :platforms => :maglev + + refute_empty set.dependencies + end + ensure + Gem.win_platform = win_platform + end + + def test_gem_platforms_multiple + win_platform, Gem.win_platform = Gem.win_platform?, false + + with_engine_version 'ruby', '2.0.0' do + @gda.gem 'a', :platforms => [:mswin, :jruby] + + assert_empty @set.dependencies + end + + ensure + Gem.win_platform = win_platform + end + + def test_gem_platforms_platform + win_platform, Gem.win_platform = Gem.win_platform?, false + + with_engine_version 'ruby', '2.0.0' do + @gda.gem 'a', :platforms => :jruby, :platform => :ruby + + refute_empty @set.dependencies + end + ensure + Gem.win_platform = win_platform + end + + def test_gem_platforms_version + with_engine_version 'ruby', '2.0.0' do + @gda.gem 'a', :platforms => :ruby_18 + + assert_empty @set.dependencies + end + end + + def test_gem_platforms_unknown + e = assert_raises ArgumentError do + @gda.gem 'a', :platforms => :unknown + end + + assert_equal 'unknown platform :unknown', e.message + end + + def test_gem_requires + @gda.gem 'a', :require => %w[b c] + @gda.gem 'd', :require => 'e' + + assert_equal [dep('a'), dep('d')], @set.dependencies + + assert_equal %w[b c], @gda.requires['a'] + assert_equal %w[e], @gda.requires['d'] + end + + def test_gem_requires_false + @gda.gem 'a', :require => false + + assert_equal [dep('a')], @set.dependencies + + assert_empty @gda.requires + end + + def test_gem_requires_without_group + @gda.without_groups << :test + + @gda.gem 'a', :group => :test + + assert_empty @set.dependencies + + assert_empty @gda.requires['a'] + end + + def test_gem_requirement + @gda.gem 'a', '~> 1.0' + + assert_equal [dep('a', '~> 1.0')], @set.dependencies + + expected = { 'a' => ['~> 1.0'] } + + assert_equal expected, @gda.dependencies + end + + def test_gem_requirements + @gda.gem 'b', '~> 1.0', '>= 1.0.2' + + assert_equal [dep('b', '~> 1.0', '>= 1.0.2')], @set.dependencies + + expected = { 'b' => ['~> 1.0', '>= 1.0.2'] } + + assert_equal expected, @gda.dependencies + end + + def test_gem_requirements_options + @gda.gem 'c', :git => 'https://example/c.git' + + assert_equal [dep('c')], @set.dependencies + end + + def test_gem_source_mismatch + name, _, directory = vendor_gem + + gda = @GDA.new @set, nil + gda.gem name + + e = assert_raises ArgumentError do + gda.gem name, :path => directory + end + + assert_equal "duplicate source path: #{directory} for gem #{name}", + e.message + + gda = @GDA.new @set, nil + gda.instance_variable_set :@vendor_set, @vendor_set + gda.gem name, :path => directory + + e = assert_raises ArgumentError do + gda.gem name + end + + assert_equal "duplicate source (default) for gem #{name}", + e.message + end + + def test_gem_deps_file + assert_equal 'gem.deps.rb', @gda.gem_deps_file + + gda = @GDA.new @set, 'foo/Gemfile' + + assert_equal 'Gemfile', gda.gem_deps_file + end + + def test_gem_group_method + groups = [] + + @gda.group :a do + groups = @gda.send :gem_group, 'a', :group => :b, :groups => [:c, :d] + end + + assert_equal [:a, :b, :c, :d], groups.sort_by { |group| group.to_s } + end + + def test_gemspec + spec = util_spec 'a', 1, 'b' => 2 + spec.add_development_dependency 'c', 3 + + open 'a.gemspec', 'w' do |io| + io.write spec.to_ruby_for_cache + end + + @gda.gemspec + + assert_equal [dep('a', '= 1'), dep('b', '= 2'), dep('c', '=3')], + @set.dependencies + + assert_equal %w[a], @gda.requires['a'] + + expected = { + 'a' => '!', + 'b' => req('= 2'), + 'c' => req('= 3'), + } + + assert_equal expected, @gda.dependencies + end + + def test_gemspec_bad + FileUtils.touch 'a.gemspec' + + e = assert_raises ArgumentError do + capture_io do + @gda.gemspec + end + end + + assert_equal 'invalid gemspec ./a.gemspec', e.message + end + + def test_gemspec_development_group + spec = util_spec 'a', 1, 'b' => 2 + spec.add_development_dependency 'c', 3 + + open 'a.gemspec', 'w' do |io| + io.write spec.to_ruby_for_cache + end + + @gda.without_groups << :other + + @gda.gemspec :development_group => :other + + assert_equal [dep('a', '= 1'), dep('b', '= 2')], @set.dependencies + + assert_equal %w[a], @gda.requires['a'] + end + + def test_gemspec_multiple + open 'a.gemspec', 'w' do |io| + spec = util_spec 'a', 1, 'b' => 2 + io.write spec.to_ruby_for_cache + end + + open 'b.gemspec', 'w' do |io| + spec = util_spec 'b', 2, 'c' => 3 + io.write spec.to_ruby_for_cache + end + + e = assert_raises ArgumentError do + @gda.gemspec + end + + assert_equal "found multiple gemspecs at #{@tempdir}, use the name: option to specify the one you want", e.message + end + + def test_gemspec_name + open 'a.gemspec', 'w' do |io| + spec = util_spec 'a', 1, 'b' => 2 + io.write spec.to_ruby_for_cache + end + + open 'b.gemspec', 'w' do |io| + spec = util_spec 'b', 2, 'c' => 3 + io.write spec.to_ruby_for_cache + end + + @gda.gemspec :name => 'b' + + assert_equal [dep('b', '= 2'), dep('c', '= 3')], @set.dependencies + end + + def test_gemspec_named + spec = util_spec 'a', 1, 'b' => 2 + + open 'other.gemspec', 'w' do |io| + io.write spec.to_ruby_for_cache + end + + @gda.gemspec + + assert_equal [dep('a', '= 1'), dep('b', '= 2')], @set.dependencies + end + + def test_gemspec_none + e = assert_raises ArgumentError do + @gda.gemspec + end + + assert_equal "no gemspecs found at #{@tempdir}", e.message + end + + def test_gemspec_path + spec = util_spec 'a', 1, 'b' => 2 + + FileUtils.mkdir 'other' + + open 'other/a.gemspec', 'w' do |io| + io.write spec.to_ruby_for_cache + end + + @gda.gemspec :path => 'other' + + assert_equal [dep('a', '= 1'), dep('b', '= 2')], @set.dependencies + end + + def test_git + @gda.git 'git://example/repo.git' do + @gda.gem 'a' + @gda.gem 'b' + end + + assert_equal [dep('a'), dep('b')], @set.dependencies + + assert_equal %w[git://example/repo.git master], @git_set.repositories['a'] + assert_equal %w[git://example/repo.git master], @git_set.repositories['b'] + end + + def test_git_source + @gda.git_source :example do |repo_name| + "git://example/#{repo_name}.git" + end + + @gda.gem 'a', :example => 'repo' + + assert_equal %w[git://example/repo.git master], @git_set.repositories['a'] + end + + def test_group + @gda.group :test do + @gda.gem 'a' + end + + assert_equal [dep('a')], @set.dependencies + end + + def test_load + tf = Tempfile.open 'gem.deps.rb' do |io| + io.write <<-GEM_DEPS +gem 'a' + +group :test do + gem 'b' +end + GEM_DEPS + io.flush + + gda = @GDA.new @set, io.path + + assert_equal gda, gda.load + + assert_equal [dep('a'), dep('b')], @set.dependencies + io + end + tf.close! if tf.respond_to? :close! + end + + def test_name_typo + assert_same @GDA, Gem::RequestSet::GemDepedencyAPI + end + + def test_pin_gem_source + gda = @GDA.new @set, nil + + gda.send :pin_gem_source, 'a' + gda.send :pin_gem_source, 'a' + + e = assert_raises ArgumentError do + gda.send :pin_gem_source, 'a', :path, 'vendor/a' + end + + assert_equal "duplicate source path: vendor/a for gem a", + e.message + + e = assert_raises ArgumentError do + gda.send :pin_gem_source, 'a', :git, 'git://example/repo.git' + end + + assert_equal "duplicate source git: git://example/repo.git for gem a", + e.message + end + + def test_platform_mswin + util_set_arch 'i686-darwin8.10.1' do + @gda.platform :mswin do + @gda.gem 'a' + end + + assert_empty @set.dependencies + end + + util_set_arch 'x86-mswin32-60' do + @gda.platform :mswin do + @gda.gem 'a' + end + + refute_empty @set.dependencies + end + end + + def test_platform_multiple + win_platform, Gem.win_platform = Gem.win_platform?, false + + gda = @GDA.new @set, nil + + with_engine_version 'ruby', '1.8.7' do + gda.platform :mri_19, :mri_20 do + gda.gem 'a' + end + end + + assert_empty @set.dependencies + + gda = @GDA.new @set, nil + + with_engine_version 'ruby', '2.0.0' do + gda.platform :mri_19, :mri_20 do + gda.gem 'a' + end + end + + refute_empty @set.dependencies + ensure + Gem.win_platform = win_platform + end + + def test_platform_ruby + win_platform, Gem.win_platform = Gem.win_platform?, false + + @gda.platform :ruby do + @gda.gem 'a' + end + + assert_equal [dep('a')], @set.dependencies + ensure + Gem.win_platform = win_platform + end + + def test_platforms + util_set_arch 'i686-darwin8.10.1' do + @gda.platforms :ruby do + @gda.gem 'a' + end + + assert_equal [dep('a')], @set.dependencies + + @gda.platforms :mswin do + @gda.gem 'b' + end + + assert_equal [dep('a')], @set.dependencies + end + + util_set_arch 'x86-mswin32-60' do + @gda.platforms :mswin do + @gda.gem 'c' + end + + assert_equal [dep('a'), dep('c')], @set.dependencies + end + end + + def test_ruby + assert @gda.ruby RUBY_VERSION + end + + def test_ruby_engine + with_engine_version 'jruby', '1.7.6' do + assert @gda.ruby RUBY_VERSION, + :engine => 'jruby', :engine_version => '1.7.6' + + end + end + + def test_ruby_engine_mismatch_engine + with_engine_version 'ruby', '2.0.0' do + e = assert_raises Gem::RubyVersionMismatch do + @gda.ruby RUBY_VERSION, :engine => 'jruby', :engine_version => '1.7.4' + end + + assert_equal 'Your ruby engine is ruby, but your gem.deps.rb requires jruby', + e.message + end + end + + def test_ruby_engine_mismatch_version + with_engine_version 'jruby', '1.7.6' do + e = assert_raises Gem::RubyVersionMismatch do + @gda.ruby RUBY_VERSION, :engine => 'jruby', :engine_version => '1.7.4' + end + + assert_equal 'Your ruby engine version is jruby 1.7.6, but your gem.deps.rb requires jruby 1.7.4', + e.message + end + end + + def test_ruby_engine_no_engine_version + e = assert_raises ArgumentError do + @gda.ruby RUBY_VERSION, :engine => 'jruby' + end + + assert_equal 'you must specify engine_version along with the ruby engine', + e.message + end + + def test_ruby_mismatch + e = assert_raises Gem::RubyVersionMismatch do + @gda.ruby '1.8.0' + end + + assert_equal "Your Ruby version is #{RUBY_VERSION}, but your gem.deps.rb requires 1.8.0", e.message + end + + def test_ruby_mismatch_installing + @gda.installing = true + + assert @gda.ruby '1.8.0' + end + + def test_source + sources = Gem.sources + + @gda.source 'http://first.example' + + assert_equal %w[http://first.example], Gem.sources + + assert_same sources, Gem.sources + + @gda.source 'http://second.example' + + assert_equal %w[http://first.example http://second.example], Gem.sources + end + + def test_with_engine_version + version = RUBY_VERSION + engine = Gem.ruby_engine + + engine_version_const = "#{Gem.ruby_engine.upcase}_VERSION" + engine_version = Object.const_get engine_version_const + + with_engine_version 'other', '1.2.3' do + assert_equal 'other', Gem.ruby_engine + assert_equal '1.2.3', OTHER_VERSION + + assert_equal version, RUBY_VERSION if engine + end + + assert_equal version, RUBY_VERSION + assert_equal engine, Gem.ruby_engine + + assert_equal engine_version, Object.const_get(engine_version_const) if + engine + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_request_set_lockfile.rb b/jni/ruby/test/rubygems/test_gem_request_set_lockfile.rb new file mode 100644 index 0000000..7c5cd5a --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_request_set_lockfile.rb @@ -0,0 +1,1276 @@ +require 'rubygems/test_case' +require 'rubygems/request_set' +require 'rubygems/request_set/lockfile' + +class TestGemRequestSetLockfile < Gem::TestCase + + def setup + super + + Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new + + util_set_arch 'i686-darwin8.10.1' + + @set = Gem::RequestSet.new + + @git_set = Gem::Resolver::GitSet.new + @vendor_set = Gem::Resolver::VendorSet.new + + @set.instance_variable_set :@git_set, @git_set + @set.instance_variable_set :@vendor_set, @vendor_set + + @gem_deps_file = 'gem.deps.rb' + + @lockfile = Gem::RequestSet::Lockfile.new @set, @gem_deps_file + end + + def write_gem_deps gem_deps + open @gem_deps_file, 'w' do |io| + io.write gem_deps + end + end + + def write_lockfile lockfile + @lock_file = File.expand_path "#{@gem_deps_file}.lock" + + open @lock_file, 'w' do |io| + io.write lockfile + end + end + + def test_add_DEPENDENCIES + spec_fetcher do |fetcher| + fetcher.spec 'a', 2 do |s| + s.add_development_dependency 'b' + end + end + + @set.gem 'a' + @set.resolve + @lockfile.instance_variable_set :@requests, @set.sorted_requests + + out = [] + + @lockfile.add_DEPENDENCIES out + + expected = [ + 'DEPENDENCIES', + ' a', + nil + ] + + assert_equal expected, out + end + + def test_add_DEPENDENCIES_from_gem_deps + spec_fetcher do |fetcher| + fetcher.spec 'a', 2 do |s| + s.add_development_dependency 'b' + end + end + + dependencies = { 'a' => '~> 2.0' } + + @set.gem 'a' + @set.resolve + @lockfile = + Gem::RequestSet::Lockfile.new @set, @gem_deps_file, dependencies + @lockfile.instance_variable_set :@requests, @set.sorted_requests + + out = [] + + @lockfile.add_DEPENDENCIES out + + expected = [ + 'DEPENDENCIES', + ' a (~> 2.0)', + nil + ] + + assert_equal expected, out + end + + def test_add_GEM + spec_fetcher do |fetcher| + fetcher.spec 'a', 2 do |s| + s.add_dependency 'b' + s.add_development_dependency 'c' + end + + fetcher.spec 'b', 2 + + fetcher.spec 'bundler', 1 + end + + @set.gem 'a' + @set.gem 'bundler' + @set.resolve + @lockfile.instance_variable_set :@requests, @set.sorted_requests + + spec_groups = @set.sorted_requests.group_by do |request| + request.spec.class + end + @lockfile.instance_variable_set :@spec_groups, spec_groups + + + out = [] + + @lockfile.add_GEM out + + expected = [ + 'GEM', + ' remote: http://gems.example.com/', + ' specs:', + ' a (2)', + ' b', + ' b (2)', + nil + ] + + assert_equal expected, out + end + + def test_add_PLATFORMS + spec_fetcher do |fetcher| + fetcher.spec 'a', 2 do |s| + s.add_dependency 'b' + end + + fetcher.spec 'b', 2 do |s| + s.platform = Gem::Platform::CURRENT + end + end + + @set.gem 'a' + @set.resolve + @lockfile.instance_variable_set :@requests, @set.sorted_requests + + out = [] + + @lockfile.add_PLATFORMS out + + expected = [ + 'PLATFORMS', + ' ruby', + ' x86-darwin-8', + nil + ] + + assert_equal expected, out + end + + def test_get + @lockfile.instance_variable_set :@tokens, [:token] + + assert_equal :token, @lockfile.get + end + + def test_get_type_mismatch + @lockfile.instance_variable_set :@tokens, [[:section, 'x', 5, 1]] + + e = assert_raises Gem::RequestSet::Lockfile::ParseError do + @lockfile.get :text + end + + expected = + 'unexpected token [:section, "x"], expected :text (at line 1 column 5)' + + assert_equal expected, e.message + + assert_equal 1, e.line + assert_equal 5, e.column + assert_equal File.expand_path("#{@gem_deps_file}.lock"), e.path + end + + def test_get_type_multiple + @lockfile.instance_variable_set :@tokens, [[:section, 'x', 5, 1]] + + assert @lockfile.get [:text, :section] + end + + def test_get_type_value_mismatch + @lockfile.instance_variable_set :@tokens, [[:section, 'x', 5, 1]] + + e = assert_raises Gem::RequestSet::Lockfile::ParseError do + @lockfile.get :section, 'y' + end + + expected = + 'unexpected token [:section, "x"], expected [:section, "y"] (at line 1 column 5)' + + assert_equal expected, e.message + + assert_equal 1, e.line + assert_equal 5, e.column + assert_equal File.expand_path("#{@gem_deps_file}.lock"), e.path + end + + def test_parse + write_lockfile <<-LOCKFILE.strip +GEM + remote: #{@gem_repo} + specs: + a (2) + +PLATFORMS + #{Gem::Platform::RUBY} + +DEPENDENCIES + a + LOCKFILE + + @lockfile.parse + + assert_equal [dep('a')], @set.dependencies + + assert_equal [Gem::Platform::RUBY], @lockfile.platforms + + lockfile_set = @set.sets.find do |set| + Gem::Resolver::LockSet === set + end + + assert lockfile_set, 'could not find a LockSet' + + assert_equal %w[a-2], lockfile_set.specs.map { |tuple| tuple.full_name } + end + + def test_parse_dependencies + write_lockfile <<-LOCKFILE +GEM + remote: #{@gem_repo} + specs: + a (2) + +PLATFORMS + #{Gem::Platform::RUBY} + +DEPENDENCIES + a (>= 1, <= 2) + LOCKFILE + + @lockfile.parse + + assert_equal [dep('a', '>= 1', '<= 2')], @set.dependencies + + assert_equal [Gem::Platform::RUBY], @lockfile.platforms + + lockfile_set = @set.sets.find do |set| + Gem::Resolver::LockSet === set + end + + assert lockfile_set, 'could not find a LockSet' + + assert_equal %w[a-2], lockfile_set.specs.map { |tuple| tuple.full_name } + end + + def test_parse_DEPENDENCIES_git + write_lockfile <<-LOCKFILE +GIT + remote: git://git.example/josevalim/rails-footnotes.git + revision: 3a6ac1971e91d822f057650cc5916ebfcbd6ee37 + specs: + rails-footnotes (3.7.9) + rails (>= 3.0.0) + +GIT + remote: git://git.example/svenfuchs/i18n-active_record.git + revision: 55507cf59f8f2173d38e07e18df0e90d25b1f0f6 + specs: + i18n-active_record (0.0.2) + i18n (>= 0.5.0) + +GEM + remote: http://gems.example/ + specs: + i18n (0.6.9) + rails (4.0.0) + +PLATFORMS + ruby + +DEPENDENCIES + i18n-active_record! + rails-footnotes! + LOCKFILE + + @lockfile.parse + + expected = [ + dep('i18n-active_record', '= 0.0.2'), + dep('rails-footnotes', '= 3.7.9'), + ] + + assert_equal expected, @set.dependencies + end + + def test_parse_DEPENDENCIES_git_version + write_lockfile <<-LOCKFILE +GIT + remote: git://github.com/progrium/ruby-jwt.git + revision: 8d74770c6cd92ea234b428b5d0c1f18306a4f41c + specs: + jwt (1.1) + +GEM + remote: http://gems.example/ + specs: + +PLATFORMS + ruby + +DEPENDENCIES + jwt (= 1.1)! + LOCKFILE + + @lockfile.parse + + expected = [ + dep('jwt', '= 1.1'), + ] + + assert_equal expected, @set.dependencies + end + + def test_parse_GEM + write_lockfile <<-LOCKFILE +GEM + specs: + a (2) + +PLATFORMS + ruby + +DEPENDENCIES + a + LOCKFILE + + @lockfile.parse + + assert_equal [dep('a', '>= 0')], @set.dependencies + + lockfile_set = @set.sets.find do |set| + Gem::Resolver::LockSet === set + end + + assert lockfile_set, 'found a LockSet' + + assert_equal %w[a-2], lockfile_set.specs.map { |s| s.full_name } + end + + def test_parse_GEM_remote_multiple + write_lockfile <<-LOCKFILE +GEM + remote: https://gems.example/ + remote: https://other.example/ + specs: + a (2) + +PLATFORMS + ruby + +DEPENDENCIES + a + LOCKFILE + + @lockfile.parse + + assert_equal [dep('a', '>= 0')], @set.dependencies + + lockfile_set = @set.sets.find do |set| + Gem::Resolver::LockSet === set + end + + assert lockfile_set, 'found a LockSet' + + assert_equal %w[a-2 a-2], lockfile_set.specs.map { |s| s.full_name } + + assert_equal %w[https://gems.example/ https://other.example/], + lockfile_set.specs.map { |s| s.source.uri.to_s } + end + + def test_parse_GIT + @set.instance_variable_set :@install_dir, 'install_dir' + + write_lockfile <<-LOCKFILE +GIT + remote: git://example/a.git + revision: master + specs: + a (2) + b (>= 3) + c + +DEPENDENCIES + a! + LOCKFILE + + @lockfile.parse + + assert_equal [dep('a', '= 2')], @set.dependencies + + lockfile_set = @set.sets.find do |set| + Gem::Resolver::LockSet === set + end + + refute lockfile_set, 'fount a LockSet' + + git_set = @set.sets.find do |set| + Gem::Resolver::GitSet === set + end + + assert git_set, 'could not find a GitSet' + + assert_equal %w[a-2], git_set.specs.values.map { |s| s.full_name } + + assert_equal [dep('b', '>= 3'), dep('c')], + git_set.specs.values.first.dependencies + + expected = { + 'a' => %w[git://example/a.git master], + } + + assert_equal expected, git_set.repositories + assert_equal 'install_dir', git_set.root_dir + end + + def test_parse_GIT_branch + write_lockfile <<-LOCKFILE +GIT + remote: git://example/a.git + revision: 1234abc + branch: 0-9-12-stable + specs: + a (2) + b (>= 3) + +DEPENDENCIES + a! + LOCKFILE + + @lockfile.parse + + assert_equal [dep('a', '= 2')], @set.dependencies + + lockfile_set = @set.sets.find do |set| + Gem::Resolver::LockSet === set + end + + refute lockfile_set, 'fount a LockSet' + + git_set = @set.sets.find do |set| + Gem::Resolver::GitSet === set + end + + assert git_set, 'could not find a GitSet' + + expected = { + 'a' => %w[git://example/a.git 1234abc], + } + + assert_equal expected, git_set.repositories + end + + def test_parse_GIT_ref + write_lockfile <<-LOCKFILE +GIT + remote: git://example/a.git + revision: 1234abc + ref: 1234abc + specs: + a (2) + b (>= 3) + +DEPENDENCIES + a! + LOCKFILE + + @lockfile.parse + + assert_equal [dep('a', '= 2')], @set.dependencies + + lockfile_set = @set.sets.find do |set| + Gem::Resolver::LockSet === set + end + + refute lockfile_set, 'fount a LockSet' + + git_set = @set.sets.find do |set| + Gem::Resolver::GitSet === set + end + + assert git_set, 'could not find a GitSet' + + expected = { + 'a' => %w[git://example/a.git 1234abc], + } + + assert_equal expected, git_set.repositories + end + + def test_parse_GIT_tag + write_lockfile <<-LOCKFILE +GIT + remote: git://example/a.git + revision: 1234abc + tag: v0.9.12 + specs: + a (2) + b (>= 3) + +DEPENDENCIES + a! + LOCKFILE + + @lockfile.parse + + assert_equal [dep('a', '= 2')], @set.dependencies + + lockfile_set = @set.sets.find do |set| + Gem::Resolver::LockSet === set + end + + refute lockfile_set, 'fount a LockSet' + + git_set = @set.sets.find do |set| + Gem::Resolver::GitSet === set + end + + assert git_set, 'could not find a GitSet' + + expected = { + 'a' => %w[git://example/a.git 1234abc], + } + + assert_equal expected, git_set.repositories + end + + def test_parse_PATH + _, _, directory = vendor_gem + + write_lockfile <<-LOCKFILE +PATH + remote: #{directory} + specs: + a (1) + b (2) + +DEPENDENCIES + a! + LOCKFILE + + @lockfile.parse + + assert_equal [dep('a', '= 1')], @set.dependencies + + lockfile_set = @set.sets.find do |set| + Gem::Resolver::LockSet === set + end + + refute lockfile_set, 'found a LockSet' + + vendor_set = @set.sets.find do |set| + Gem::Resolver::VendorSet === set + end + + assert vendor_set, 'could not find a VendorSet' + + assert_equal %w[a-1], vendor_set.specs.values.map { |s| s.full_name } + + spec = vendor_set.load_spec 'a', nil, nil, nil + + assert_equal [dep('b', '= 2')], spec.dependencies + end + + def test_parse_dependency + write_lockfile ' 1)' + + @lockfile.tokenize + + parsed = @lockfile.parse_dependency 'a', '=' + + assert_equal dep('a', '= 1'), parsed + + write_lockfile ')' + + @lockfile.tokenize + + parsed = @lockfile.parse_dependency 'a', '2' + + assert_equal dep('a', '= 2'), parsed + end + + def test_parse_gem_specs_dependency + write_lockfile <<-LOCKFILE +GEM + remote: #{@gem_repo} + specs: + a (2) + b (= 3) + c (~> 4) + d + e (~> 5.0, >= 5.0.1) + b (3-x86_64-linux) + +PLATFORMS + #{Gem::Platform::RUBY} + +DEPENDENCIES + a + LOCKFILE + + @lockfile.parse + + assert_equal [dep('a')], @set.dependencies + + assert_equal [Gem::Platform::RUBY], @lockfile.platforms + + lockfile_set = @set.sets.find do |set| + Gem::Resolver::LockSet === set + end + + assert lockfile_set, 'could not find a LockSet' + + assert_equal %w[a-2 b-3], lockfile_set.specs.map { |tuple| tuple.full_name } + + expected = [ + Gem::Platform::RUBY, + Gem::Platform.new('x86_64-linux'), + ] + + assert_equal expected, lockfile_set.specs.map { |tuple| tuple.platform } + + spec = lockfile_set.specs.first + + expected = [ + dep('b', '= 3'), + dep('c', '~> 4'), + dep('d'), + dep('e', '~> 5.0', '>= 5.0.1'), + ] + + assert_equal expected, spec.dependencies + end + + def test_parse_missing + @lockfile.parse + + lockfile_set = @set.sets.find do |set| + Gem::Resolver::LockSet === set + end + + refute lockfile_set + end + + def test_peek + @lockfile.instance_variable_set :@tokens, [:token] + + assert_equal :token, @lockfile.peek + + assert_equal :token, @lockfile.get + + assert_equal [:EOF], @lockfile.peek + end + + def test_relative_path_from + path = @lockfile.relative_path_from '/foo', '/foo/bar' + + assert_equal File.expand_path('/foo'), path + + path = @lockfile.relative_path_from '/foo', '/foo' + + assert_equal '.', path + end + + def test_skip + tokens = [[:token]] + + @lockfile.instance_variable_set :@tokens, tokens + + @lockfile.skip :token + + assert_empty tokens + end + + def test_token_pos + assert_equal [5, 0], @lockfile.token_pos(5) + + @lockfile.instance_variable_set :@line_pos, 2 + @lockfile.instance_variable_set :@line, 1 + + assert_equal [3, 1], @lockfile.token_pos(5) + end + + def test_tokenize + write_lockfile <<-LOCKFILE +GEM + remote: #{@gem_repo} + specs: + a (2) + b (= 2) + c (!= 3) + d (> 4) + e (< 5) + f (>= 6) + g (<= 7) + h (~> 8) + +PLATFORMS + #{Gem::Platform::RUBY} + +DEPENDENCIES + a + LOCKFILE + + expected = [ + [:section, 'GEM', 0, 0], + [:newline, nil, 3, 0], + + [:entry, 'remote', 2, 1], + [:text, @gem_repo, 10, 1], + [:newline, nil, 34, 1], + + [:entry, 'specs', 2, 2], + [:newline, nil, 8, 2], + + [:text, 'a', 4, 3], + [:l_paren, nil, 6, 3], + [:text, '2', 7, 3], + [:r_paren, nil, 8, 3], + [:newline, nil, 9, 3], + + [:text, 'b', 6, 4], + [:l_paren, nil, 8, 4], + [:requirement, '=', 9, 4], + [:text, '2', 11, 4], + [:r_paren, nil, 12, 4], + [:newline, nil, 13, 4], + + [:text, 'c', 6, 5], + [:l_paren, nil, 8, 5], + [:requirement, '!=', 9, 5], + [:text, '3', 12, 5], + [:r_paren, nil, 13, 5], + [:newline, nil, 14, 5], + + [:text, 'd', 6, 6], + [:l_paren, nil, 8, 6], + [:requirement, '>', 9, 6], + [:text, '4', 11, 6], + [:r_paren, nil, 12, 6], + [:newline, nil, 13, 6], + + [:text, 'e', 6, 7], + [:l_paren, nil, 8, 7], + [:requirement, '<', 9, 7], + [:text, '5', 11, 7], + [:r_paren, nil, 12, 7], + [:newline, nil, 13, 7], + + [:text, 'f', 6, 8], + [:l_paren, nil, 8, 8], + [:requirement, '>=', 9, 8], + [:text, '6', 12, 8], + [:r_paren, nil, 13, 8], + [:newline, nil, 14, 8], + + [:text, 'g', 6, 9], + [:l_paren, nil, 8, 9], + [:requirement, '<=', 9, 9], + [:text, '7', 12, 9], + [:r_paren, nil, 13, 9], + [:newline, nil, 14, 9], + + [:text, 'h', 6, 10], + [:l_paren, nil, 8, 10], + [:requirement, '~>', 9, 10], + [:text, '8', 12, 10], + [:r_paren, nil, 13, 10], + [:newline, nil, 14, 10], + + [:newline, nil, 0, 11], + + [:section, 'PLATFORMS', 0, 12], + [:newline, nil, 9, 12], + + [:text, Gem::Platform::RUBY, 2, 13], + [:newline, nil, 6, 13], + + [:newline, nil, 0, 14], + + [:section, 'DEPENDENCIES', 0, 15], + [:newline, nil, 12, 15], + + [:text, 'a', 2, 16], + [:newline, nil, 3, 16], + ] + + assert_equal expected, @lockfile.tokenize + end + + def test_tokenize_capitals + write_lockfile <<-LOCKFILE +GEM + remote: #{@gem_repo} + specs: + Ab (2) + +PLATFORMS + #{Gem::Platform::RUBY} + +DEPENDENCIES + Ab + LOCKFILE + + expected = [ + [:section, 'GEM', 0, 0], + [:newline, nil, 3, 0], + [:entry, 'remote', 2, 1], + [:text, @gem_repo, 10, 1], + [:newline, nil, 34, 1], + [:entry, 'specs', 2, 2], + [:newline, nil, 8, 2], + [:text, 'Ab', 4, 3], + [:l_paren, nil, 7, 3], + [:text, '2', 8, 3], + [:r_paren, nil, 9, 3], + [:newline, nil, 10, 3], + [:newline, nil, 0, 4], + [:section, 'PLATFORMS', 0, 5], + [:newline, nil, 9, 5], + [:text, Gem::Platform::RUBY, 2, 6], + [:newline, nil, 6, 6], + [:newline, nil, 0, 7], + [:section, 'DEPENDENCIES', 0, 8], + [:newline, nil, 12, 8], + [:text, 'Ab', 2, 9], + [:newline, nil, 4, 9], + ] + + assert_equal expected, @lockfile.tokenize + end + + def test_tokenize_conflict_markers + write_lockfile '<<<<<<<' + + e = assert_raises Gem::RequestSet::Lockfile::ParseError do + @lockfile.tokenize + end + + assert_equal "your #{@lock_file} contains merge conflict markers (at line 0 column 0)", + e.message + + write_lockfile '|||||||' + + e = assert_raises Gem::RequestSet::Lockfile::ParseError do + @lockfile.tokenize + end + + assert_equal "your #{@lock_file} contains merge conflict markers (at line 0 column 0)", + e.message + + write_lockfile '=======' + + e = assert_raises Gem::RequestSet::Lockfile::ParseError do + @lockfile.tokenize + end + + assert_equal "your #{@lock_file} contains merge conflict markers (at line 0 column 0)", + e.message + + write_lockfile '>>>>>>>' + + e = assert_raises Gem::RequestSet::Lockfile::ParseError do + @lockfile.tokenize + end + + assert_equal "your #{@lock_file} contains merge conflict markers (at line 0 column 0)", + e.message + end + + def test_tokenize_git + write_lockfile <<-LOCKFILE +DEPENDENCIES + a! + LOCKFILE + + expected = [ + [:section, 'DEPENDENCIES', 0, 0], + [:newline, nil, 12, 0], + + [:text, 'a', 2, 1], + [:bang, nil, 3, 1], + [:newline, nil, 4, 1], + ] + + assert_equal expected, @lockfile.tokenize + end + + def test_tokenize_missing + tokens = @lockfile.tokenize + + assert_empty tokens + end + + def test_tokenize_multiple + write_lockfile <<-LOCKFILE +GEM + remote: #{@gem_repo} + specs: + a (2) + b (~> 3.0, >= 3.0.1) + LOCKFILE + + expected = [ + [:section, 'GEM', 0, 0], + [:newline, nil, 3, 0], + + [:entry, 'remote', 2, 1], + [:text, @gem_repo, 10, 1], + [:newline, nil, 34, 1], + + [:entry, 'specs', 2, 2], + [:newline, nil, 8, 2], + + [:text, 'a', 4, 3], + [:l_paren, nil, 6, 3], + [:text, '2', 7, 3], + [:r_paren, nil, 8, 3], + [:newline, nil, 9, 3], + + [:text, 'b', 6, 4], + [:l_paren, nil, 8, 4], + [:requirement, '~>', 9, 4], + [:text, '3.0', 12, 4], + [:comma, nil, 15, 4], + [:requirement, '>=', 17, 4], + [:text, '3.0.1', 20, 4], + [:r_paren, nil, 25, 4], + [:newline, nil, 26, 4], + ] + + assert_equal expected, @lockfile.tokenize + end + + def test_to_s_gem + spec_fetcher do |fetcher| + fetcher.spec 'a', 2 + end + + @set.gem 'a' + + expected = <<-LOCKFILE +GEM + remote: #{@gem_repo} + specs: + a (2) + +PLATFORMS + #{Gem::Platform::RUBY} + +DEPENDENCIES + a + LOCKFILE + + assert_equal expected, @lockfile.to_s + end + + def test_to_s_gem_dependency + spec_fetcher do |fetcher| + fetcher.spec 'a', 2, 'c' => '>= 0', 'b' => '>= 0' + fetcher.spec 'b', 2 + fetcher.spec 'c', 2 + end + + @set.gem 'a' + + expected = <<-LOCKFILE +GEM + remote: #{@gem_repo} + specs: + a (2) + b + c + b (2) + c (2) + +PLATFORMS + #{Gem::Platform::RUBY} + +DEPENDENCIES + a + b + c + LOCKFILE + + assert_equal expected, @lockfile.to_s + end + + def test_to_s_gem_dependency_non_default + spec_fetcher do |fetcher| + fetcher.spec 'a', 2, 'b' => '>= 1' + fetcher.spec 'b', 2 + end + + @set.gem 'b' + @set.gem 'a' + + expected = <<-LOCKFILE +GEM + remote: #{@gem_repo} + specs: + a (2) + b (>= 1) + b (2) + +PLATFORMS + #{Gem::Platform::RUBY} + +DEPENDENCIES + a + b + LOCKFILE + + assert_equal expected, @lockfile.to_s + end + + def test_to_s_gem_dependency_requirement + spec_fetcher do |fetcher| + fetcher.spec 'a', 2, 'b' => '>= 0' + fetcher.spec 'b', 2 + end + + @set.gem 'a', '>= 1' + + expected = <<-LOCKFILE +GEM + remote: #{@gem_repo} + specs: + a (2) + b + b (2) + +PLATFORMS + #{Gem::Platform::RUBY} + +DEPENDENCIES + a (>= 1) + b + LOCKFILE + + assert_equal expected, @lockfile.to_s + end + + def test_to_s_gem_path + name, version, directory = vendor_gem + + @vendor_set.add_vendor_gem name, directory + + @set.gem 'a' + + expected = <<-LOCKFILE +PATH + remote: #{directory} + specs: + #{name} (#{version}) + +PLATFORMS + #{Gem::Platform::RUBY} + +DEPENDENCIES + a! + LOCKFILE + + assert_equal expected, @lockfile.to_s + end + + def test_to_s_gem_path_absolute + name, version, directory = vendor_gem + + @vendor_set.add_vendor_gem name, File.expand_path(directory) + + @set.gem 'a' + + expected = <<-LOCKFILE +PATH + remote: #{directory} + specs: + #{name} (#{version}) + +PLATFORMS + #{Gem::Platform::RUBY} + +DEPENDENCIES + a! + LOCKFILE + + assert_equal expected, @lockfile.to_s + end + + def test_to_s_gem_platform + spec_fetcher do |fetcher| + fetcher.spec 'a', 2 do |spec| + spec.platform = Gem::Platform.local + end + end + + @set.gem 'a' + + expected = <<-LOCKFILE +GEM + remote: #{@gem_repo} + specs: + a (2-#{Gem::Platform.local}) + +PLATFORMS + #{Gem::Platform.local} + +DEPENDENCIES + a + LOCKFILE + + assert_equal expected, @lockfile.to_s + end + + def test_to_s_gem_source + spec_fetcher do |fetcher| + fetcher.spec 'a', 2 + fetcher.clear + end + + spec_fetcher 'http://other.example/' do |fetcher| + fetcher.spec 'b', 2 + fetcher.clear + end + + Gem.sources << 'http://other.example/' + + @set.gem 'a' + @set.gem 'b' + + expected = <<-LOCKFILE +GEM + remote: #{@gem_repo} + specs: + a (2) + +GEM + remote: http://other.example/ + specs: + b (2) + +PLATFORMS + #{Gem::Platform::RUBY} + +DEPENDENCIES + a + b + LOCKFILE + + assert_equal expected, @lockfile.to_s + end + + def test_to_s_git + _, _, repository, = git_gem + + head = nil + + Dir.chdir repository do + FileUtils.mkdir 'b' + + Dir.chdir 'b' do + b = Gem::Specification.new 'b', 1 do |s| + s.add_dependency 'a', '~> 1.0' + s.add_dependency 'c', '~> 1.0' + end + + open 'b.gemspec', 'w' do |io| + io.write b.to_ruby + end + + system @git, 'add', 'b.gemspec' + system @git, 'commit', '--quiet', '-m', 'add b/b.gemspec' + end + + FileUtils.mkdir 'c' + + Dir.chdir 'c' do + c = Gem::Specification.new 'c', 1 + + open 'c.gemspec', 'w' do |io| + io.write c.to_ruby + end + + system @git, 'add', 'c.gemspec' + system @git, 'commit', '--quiet', '-m', 'add c/c.gemspec' + end + + head = `#{@git} rev-parse HEAD`.strip + end + + @git_set.add_git_gem 'a', repository, 'HEAD', true + @git_set.add_git_gem 'b', repository, 'HEAD', true + @git_set.add_git_gem 'c', repository, 'HEAD', true + + @set.gem 'b' + + expected = <<-LOCKFILE +GIT + remote: #{repository} + revision: #{head} + specs: + a (1) + b (1) + a (~> 1.0) + c (~> 1.0) + c (1) + +PLATFORMS + ruby + +DEPENDENCIES + a! + b! + c! + LOCKFILE + + assert_equal expected, @lockfile.to_s + end + + def test_unget + @lockfile.instance_variable_set :@current_token, :token + + @lockfile.unget + + assert_equal :token, @lockfile.get + end + + def test_write + @lockfile.write + + gem_deps_lock_file = "#{@gem_deps_file}.lock" + + assert_path_exists gem_deps_lock_file + + refute_empty File.read gem_deps_lock_file + end + + def test_write_error + @set.gem 'nonexistent' + + gem_deps_lock_file = "#{@gem_deps_file}.lock" + + open gem_deps_lock_file, 'w' do |io| + io.write 'hello' + end + + assert_raises Gem::UnsatisfiableDependencyError do + @lockfile.write + end + + assert_path_exists gem_deps_lock_file + + assert_equal 'hello', File.read(gem_deps_lock_file) + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_requirement.rb b/jni/ruby/test/rubygems/test_gem_requirement.rb new file mode 100644 index 0000000..6974ff0 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_requirement.rb @@ -0,0 +1,376 @@ +require 'rubygems/test_case' +require "rubygems/requirement" + +class TestGemRequirement < Gem::TestCase + + def test_concat + r = req '>= 1' + + r.concat ['< 2'] + + assert_equal [['>=', v(1)], ['<', v(2)]], r.requirements + end + + def test_equals2 + r = req "= 1.2" + assert_equal r, r.dup + assert_equal r.dup, r + + refute_requirement_equal "= 1.2", "= 1.3" + refute_requirement_equal "= 1.3", "= 1.2" + + refute_equal Object.new, req("= 1.2") + refute_equal req("= 1.2"), Object.new + end + + def test_initialize + assert_requirement_equal "= 2", "2" + assert_requirement_equal "= 2", ["2"] + assert_requirement_equal "= 2", v(2) + end + + def test_empty_requirements_is_none + r = Gem::Requirement.new + assert_equal true, r.none? + end + + def test_explicit_default_is_none + r = Gem::Requirement.new ">= 0" + assert_equal true, r.none? + end + + def test_basic_non_none + r = Gem::Requirement.new "= 1" + assert_equal false, r.none? + end + + def test_for_lockfile + assert_equal ' (~> 1.0)', req('~> 1.0').for_lockfile + + assert_equal ' (~> 1.0, >= 1.0.1)', req('>= 1.0.1', '~> 1.0').for_lockfile + + duped = req '= 1.0' + duped.requirements << ['=', v('1.0')] + + assert_equal ' (= 1.0)', duped.for_lockfile + + assert_nil Gem::Requirement.default.for_lockfile + end + + def test_parse + assert_equal ['=', Gem::Version.new(1)], Gem::Requirement.parse(' 1') + assert_equal ['=', Gem::Version.new(1)], Gem::Requirement.parse('= 1') + assert_equal ['>', Gem::Version.new(1)], Gem::Requirement.parse('> 1') + assert_equal ['=', Gem::Version.new(1)], Gem::Requirement.parse("=\n1") + + assert_equal ['=', Gem::Version.new(2)], + Gem::Requirement.parse(Gem::Version.new('2')) + end + + def test_parse_bad + [ + nil, + '', + '! 1', + '= junk', + '1..2', + ].each do |bad| + e = assert_raises Gem::Requirement::BadRequirementError do + Gem::Requirement.parse bad + end + + assert_equal "Illformed requirement [#{bad.inspect}]", e.message + end + + assert_equal Gem::Requirement::BadRequirementError.superclass, ArgumentError + end + + def test_prerelease_eh + r = req '= 1' + + refute r.prerelease? + + r = req '= 1.a' + + assert r.prerelease? + + r = req '> 1.a', '< 2' + + assert r.prerelease? + end + + def test_satisfied_by_eh_bang_equal + r = req '!= 1.2' + + assert_satisfied_by "1.1", r + refute_satisfied_by "1.2", r + assert_satisfied_by "1.3", r + + assert_raises ArgumentError do + assert_satisfied_by nil, r + end + end + + def test_satisfied_by_eh_blank + r = req "1.2" + + refute_satisfied_by "1.1", r + assert_satisfied_by "1.2", r + refute_satisfied_by "1.3", r + + assert_raises ArgumentError do + assert_satisfied_by nil, r + end + end + + def test_satisfied_by_eh_equal + r = req "= 1.2" + + refute_satisfied_by "1.1", r + assert_satisfied_by "1.2", r + refute_satisfied_by "1.3", r + + assert_raises ArgumentError do + assert_satisfied_by nil, r + end + end + + def test_satisfied_by_eh_gt + r = req "> 1.2" + + refute_satisfied_by "1.1", r + refute_satisfied_by "1.2", r + assert_satisfied_by "1.3", r + + assert_raises ArgumentError do + r.satisfied_by? nil + end + end + + def test_satisfied_by_eh_gte + r = req ">= 1.2" + + refute_satisfied_by "1.1", r + assert_satisfied_by "1.2", r + assert_satisfied_by "1.3", r + + assert_raises ArgumentError do + r.satisfied_by? nil + end + end + + def test_satisfied_by_eh_list + r = req "> 1.1", "< 1.3" + + refute_satisfied_by "1.1", r + assert_satisfied_by "1.2", r + refute_satisfied_by "1.3", r + + assert_raises ArgumentError do + r.satisfied_by? nil + end + end + + def test_satisfied_by_eh_lt + r = req "< 1.2" + + assert_satisfied_by "1.1", r + refute_satisfied_by "1.2", r + refute_satisfied_by "1.3", r + + assert_raises ArgumentError do + r.satisfied_by? nil + end + end + + def test_satisfied_by_eh_lte + r = req "<= 1.2" + + assert_satisfied_by "1.1", r + assert_satisfied_by "1.2", r + refute_satisfied_by "1.3", r + + assert_raises ArgumentError do + r.satisfied_by? nil + end + end + + def test_satisfied_by_eh_tilde_gt + r = req "~> 1.2" + + refute_satisfied_by "1.1", r + assert_satisfied_by "1.2", r + assert_satisfied_by "1.3", r + + assert_raises ArgumentError do + r.satisfied_by? nil + end + end + + def test_satisfied_by_eh_tilde_gt_v0 + r = req "~> 0.0.1" + + refute_satisfied_by "0.1.1", r + assert_satisfied_by "0.0.2", r + assert_satisfied_by "0.0.1", r + end + + def test_satisfied_by_eh_good + assert_satisfied_by "0.2.33", "= 0.2.33" + assert_satisfied_by "0.2.34", "> 0.2.33" + assert_satisfied_by "1.0", "= 1.0" + assert_satisfied_by "1.0", "1.0" + assert_satisfied_by "1.8.2", "> 1.8.0" + assert_satisfied_by "1.112", "> 1.111" + assert_satisfied_by "0.2", "> 0.0.0" + assert_satisfied_by "0.0.0.0.0.2", "> 0.0.0" + assert_satisfied_by "0.0.1.0", "> 0.0.0.1" + assert_satisfied_by "10.3.2", "> 9.3.2" + assert_satisfied_by "1.0.0.0", "= 1.0" + assert_satisfied_by "10.3.2", "!= 9.3.4" + assert_satisfied_by "10.3.2", "> 9.3.2" + assert_satisfied_by "10.3.2", "> 9.3.2" + assert_satisfied_by " 9.3.2", ">= 9.3.2" + assert_satisfied_by "9.3.2 ", ">= 9.3.2" + assert_satisfied_by "", "= 0" + assert_satisfied_by "", "< 0.1" + assert_satisfied_by " ", "< 0.1 " + assert_satisfied_by "", " < 0.1" + assert_satisfied_by " ", "> 0.a " + assert_satisfied_by "", " > 0.a" + assert_satisfied_by "3.1", "< 3.2.rc1" + + assert_satisfied_by "3.2.0", "> 3.2.0.rc1" + assert_satisfied_by "3.2.0.rc2", "> 3.2.0.rc1" + + assert_satisfied_by "3.0.rc2", "< 3.0" + assert_satisfied_by "3.0.rc2", "< 3.0.0" + assert_satisfied_by "3.0.rc2", "< 3.0.1" + + assert_satisfied_by "3.0.rc2", "> 0" + end + + def test_illformed_requirements + [ ">>> 1.3.5", "> blah" ].each do |rq| + assert_raises Gem::Requirement::BadRequirementError, "req [#{rq}] should fail" do + Gem::Requirement.new rq + end + end + end + + def test_satisfied_by_eh_non_versions + assert_raises ArgumentError do + req(">= 0").satisfied_by? Object.new + end + + assert_raises ArgumentError do + req(">= 0").satisfied_by? Gem::Requirement.default + end + end + + def test_satisfied_by_eh_boxed + refute_satisfied_by "1.3", "~> 1.4" + assert_satisfied_by "1.4", "~> 1.4" + assert_satisfied_by "1.5", "~> 1.4" + refute_satisfied_by "2.0", "~> 1.4" + + refute_satisfied_by "1.3", "~> 1.4.4" + refute_satisfied_by "1.4", "~> 1.4.4" + assert_satisfied_by "1.4.4", "~> 1.4.4" + assert_satisfied_by "1.4.5", "~> 1.4.4" + refute_satisfied_by "1.5", "~> 1.4.4" + refute_satisfied_by "2.0", "~> 1.4.4" + + refute_satisfied_by "1.1.pre", "~> 1.0.0" + refute_satisfied_by "1.1.pre", "~> 1.1" + refute_satisfied_by "2.0.a", "~> 1.0" + refute_satisfied_by "2.0.a", "~> 2.0" + + refute_satisfied_by "0.9", "~> 1" + assert_satisfied_by "1.0", "~> 1" + assert_satisfied_by "1.1", "~> 1" + refute_satisfied_by "2.0", "~> 1" + end + + def test_satisfied_by_eh_multiple + req = [">= 1.4", "<= 1.6", "!= 1.5"] + + refute_satisfied_by "1.3", req + assert_satisfied_by "1.4", req + refute_satisfied_by "1.5", req + assert_satisfied_by "1.6", req + refute_satisfied_by "1.7", req + refute_satisfied_by "2.0", req + end + + def test_satisfied_by_boxed + refute_satisfied_by "1.3", "~> 1.4" + assert_satisfied_by "1.4", "~> 1.4" + assert_satisfied_by "1.5", "~> 1.4" + refute_satisfied_by "2.0", "~> 1.4" + + refute_satisfied_by "1.3", "~> 1.4.4" + refute_satisfied_by "1.4", "~> 1.4.4" + assert_satisfied_by "1.4.4", "~> 1.4.4" + assert_satisfied_by "1.4.5", "~> 1.4.4" + refute_satisfied_by "1.5", "~> 1.4.4" + refute_satisfied_by "2.0", "~> 1.4.4" + end + + def test_specific + refute req('> 1') .specific? + refute req('>= 1').specific? + + assert req('!= 1').specific? + assert req('< 1') .specific? + assert req('<= 1').specific? + assert req('= 1') .specific? + assert req('~> 1').specific? + + assert req('> 1', '> 2').specific? # GIGO + end + + def test_bad + refute_satisfied_by "", "> 0.1" + refute_satisfied_by "1.2.3", "!= 1.2.3" + refute_satisfied_by "1.2.003.0.0", "!= 1.02.3" + refute_satisfied_by "4.5.6", "< 1.2.3" + refute_satisfied_by "1.0", "> 1.1" + refute_satisfied_by "", "= 0.1" + refute_satisfied_by "1.1.1", "> 1.1.1" + refute_satisfied_by "1.2", "= 1.1" + refute_satisfied_by "1.40", "= 1.1" + refute_satisfied_by "1.3", "= 1.40" + refute_satisfied_by "9.3.3", "<= 9.3.2" + refute_satisfied_by "9.3.1", ">= 9.3.2" + refute_satisfied_by "9.3.03", "<= 9.3.2" + refute_satisfied_by "1.0.0.1", "= 1.0" + end + + # Assert that two requirements are equal. Handles Gem::Requirements, + # strings, arrays, numbers, and versions. + + def assert_requirement_equal expected, actual + assert_equal req(expected), req(actual) + end + + # Assert that +version+ satisfies +requirement+. + + def assert_satisfied_by version, requirement + assert req(requirement).satisfied_by?(v(version)), + "#{requirement} is satisfied by #{version}" + end + + # Refute the assumption that two requirements are equal. + + def refute_requirement_equal unexpected, actual + refute_equal req(unexpected), req(actual) + end + + # Refute the assumption that +version+ satisfies +requirement+. + + def refute_satisfied_by version, requirement + refute req(requirement).satisfied_by?(v(version)), + "#{requirement} is not satisfied by #{version}" + end +end diff --git a/jni/ruby/test/rubygems/test_gem_resolver.rb b/jni/ruby/test/rubygems/test_gem_resolver.rb new file mode 100644 index 0000000..2b9e9fe --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver.rb @@ -0,0 +1,733 @@ +require 'rubygems/test_case' + +class TestGemResolver < Gem::TestCase + + def setup + super + + @DR = Gem::Resolver + end + + def make_dep(name, *req) + Gem::Dependency.new(name, *req) + end + + def set(*specs) + source = Gem::Source.new URI @gem_repo + + specs = specs.map do |spec| + Gem::Resolver::SpecSpecification.new nil, spec, source + end + + StaticSet.new(specs) + end + + def assert_resolves_to expected, resolver + actual = resolver.resolve + + exp = expected.sort_by { |s| s.full_name } + act = actual.map { |a| a.spec.spec }.sort_by { |s| s.full_name } + + msg = "Set of gems was not the same: #{exp.map { |x| x.full_name}.inspect} != #{act.map { |x| x.full_name}.inspect}" + + assert_equal exp, act, msg + rescue Gem::DependencyResolutionError => e + flunk e.message + end + + def test_self_compatibility + assert_same Gem::Resolver, Gem::DependencyResolver + end + + def test_self_compose_sets_best_set + best_set = @DR::BestSet.new + + composed = @DR.compose_sets best_set + + assert_equal best_set, composed + end + + def test_self_compose_sets_multiple + index_set = @DR::IndexSet.new + vendor_set = @DR::VendorSet.new + + composed = @DR.compose_sets index_set, vendor_set + + assert_kind_of Gem::Resolver::ComposedSet, composed + + assert_equal [index_set, vendor_set], composed.sets + end + + def test_self_compose_sets_nest + index_set = @DR::IndexSet.new + vendor_set = @DR::VendorSet.new + + inner = @DR.compose_sets index_set, vendor_set + + current_set = @DR::CurrentSet.new + + composed = @DR.compose_sets inner, current_set + + assert_kind_of Gem::Resolver::ComposedSet, composed + + assert_equal [index_set, vendor_set, current_set], composed.sets + end + + def test_self_compose_sets_nil + index_set = @DR::IndexSet.new + + composed = @DR.compose_sets index_set, nil + + assert_same index_set, composed + + e = assert_raises ArgumentError do + @DR.compose_sets nil + end + + assert_equal 'one set in the composition must be non-nil', e.message + end + + def test_self_compose_sets_single + index_set = @DR::IndexSet.new + + composed = @DR.compose_sets index_set + + assert_same index_set, composed + end + + def test_handle_conflict + a1 = util_spec 'a', 1 + + r1 = Gem::Resolver::DependencyRequest.new dep('a', '= 1'), nil + r2 = Gem::Resolver::DependencyRequest.new dep('a', '= 2'), nil + r3 = Gem::Resolver::DependencyRequest.new dep('a', '= 3'), nil + + existing = Gem::Resolver::ActivationRequest.new a1, r1, false + + res = Gem::Resolver.new [a1] + + res.handle_conflict r2, existing + res.handle_conflict r2, existing + res.handle_conflict r3, existing + + assert_equal 2, res.conflicts.length + end + + def test_requests + a1 = util_spec 'a', 1, 'b' => 2 + + r1 = Gem::Resolver::DependencyRequest.new dep('a', '= 1'), nil + + act = Gem::Resolver::ActivationRequest.new a1, r1, false + + res = Gem::Resolver.new [a1] + + reqs = Gem::Resolver::RequirementList.new + + res.requests a1, act, reqs + + assert_equal ['b (= 2)'], reqs.to_a.map { |req| req.to_s } + end + + def test_requests_development + a1 = util_spec 'a', 1, 'b' => 2 + + spec = Gem::Resolver::SpecSpecification.new nil, a1 + def spec.fetch_development_dependencies + @called = true + end + + r1 = Gem::Resolver::DependencyRequest.new dep('a', '= 1'), nil + + act = Gem::Resolver::ActivationRequest.new spec, r1, false + + res = Gem::Resolver.new [act] + res.development = true + + reqs = Gem::Resolver::RequirementList.new + + res.requests spec, act, reqs + + assert_equal ['b (= 2)'], reqs.to_a.map { |req| req.to_s } + + assert spec.instance_variable_defined? :@called + end + + def test_requests_ignore_dependencies + a1 = util_spec 'a', 1, 'b' => 2 + + r1 = Gem::Resolver::DependencyRequest.new dep('a', '= 1'), nil + + act = Gem::Resolver::ActivationRequest.new a1, r1, false + + res = Gem::Resolver.new [a1] + res.ignore_dependencies = true + + reqs = Gem::Resolver::RequirementList.new + + res.requests a1, act, reqs + + assert_empty reqs + end + + def test_resolve_conservative + a1_spec = util_spec 'a', 1 + a2_spec = util_spec 'a', 2 do |s| + s.add_dependency 'b', 2 + s.add_dependency 'c' + end + b1_spec = util_spec 'b', 1 + b2_spec = util_spec 'b', 2 + c1_spec = util_spec 'c', 1 do |s| s.add_dependency 'd', 2 end + c2_spec = util_spec 'c', 2 do |s| s.add_dependency 'd', 2 end + d1_spec = util_spec 'd', 1 do |s| s.add_dependency 'e' end + d2_spec = util_spec 'd', 2 do |s| s.add_dependency 'e' end + e1_spec = util_spec 'e', 1 + e2_spec = util_spec 'e', 2 + + a_dep = make_dep 'a', '= 2' + e_dep = make_dep 'e' + + # When requesting to install: + # a-2, e + deps = [a_dep, e_dep] + + s = set a1_spec, a2_spec, b1_spec, b2_spec, c1_spec, c2_spec, d1_spec, d2_spec, e1_spec, e2_spec + + res = Gem::Resolver.new deps, s + + # With the following gems already installed: + # a-1, b-1, c-1, e-1 + res.skip_gems = {'a'=>[a1_spec], 'b'=>[b1_spec], 'c'=>[c1_spec], 'e'=>[e1_spec]} + + # Make sure the following gems end up getting used/installed/upgraded: + # a-2 (upgraded) + # b-2 (upgraded), specific dependency from a-2 + # c-1 (used, not upgraded), open dependency from a-2 + # d-2 (installed), specific dependency from c-2 + # e-1 (used, not upgraded), open dependency from request + assert_resolves_to [a2_spec, b2_spec, c1_spec, d2_spec, e1_spec], res + end + + def test_resolve_development + a_spec = util_spec 'a', 1 do |s| s.add_development_dependency 'b' end + b_spec = util_spec 'b', 1 do |s| s.add_development_dependency 'c' end + c_spec = util_spec 'c', 1 + + a_dep = make_dep 'a', '= 1' + + deps = [a_dep] + + s = set a_spec, b_spec, c_spec + + res = Gem::Resolver.new deps, s + + res.development = true + + assert_resolves_to [a_spec, b_spec, c_spec], res + end + + def test_resolve_development_shallow + a_spec = util_spec 'a', 1 do |s| + s.add_development_dependency 'b' + s.add_runtime_dependency 'd' + end + + b_spec = util_spec 'b', 1 do |s| s.add_development_dependency 'c' end + c_spec = util_spec 'c', 1 + + d_spec = util_spec 'd', 1 do |s| s.add_development_dependency 'e' end + e_spec = util_spec 'e', 1 + + a_dep = make_dep 'a', '= 1' + + deps = [a_dep] + + s = set a_spec, b_spec, c_spec, d_spec, e_spec + + res = Gem::Resolver.new deps, s + + res.development = true + res.development_shallow = true + + assert_resolves_to [a_spec, b_spec, d_spec], res + end + + def test_resolve_remote_missing_dependency + @fetcher = Gem::FakeFetcher.new + Gem::RemoteFetcher.fetcher = @fetcher + + a_dep = make_dep 'a', '= 1' + + res = Gem::Resolver.new [a_dep], Gem::Resolver::IndexSet.new + + e = assert_raises Gem::UnsatisfiableDepedencyError do + res.resolve + end + + refute_empty e.errors + end + + def test_no_overlap_specificly + a = util_spec "a", '1' + b = util_spec "b", "1" + + ad = make_dep "a", "= 1" + bd = make_dep "b", "= 1" + + deps = [ad, bd] + + s = set(a, b) + + res = Gem::Resolver.new(deps, s) + + assert_resolves_to [a, b], res + end + + def test_pulls_in_dependencies + a = util_spec "a", '1' + b = util_spec "b", "1", "c" => "= 1" + c = util_spec "c", "1" + + ad = make_dep "a", "= 1" + bd = make_dep "b", "= 1" + + deps = [ad, bd] + + s = set(a, b, c) + + res = Gem::Resolver.new(deps, s) + + assert_resolves_to [a, b, c], res + end + + def test_picks_highest_version + a1 = util_spec "a", '1' + a2 = util_spec "a", '2' + + s = set(a1, a2) + + ad = make_dep "a" + + res = Gem::Resolver.new([ad], s) + + assert_resolves_to [a2], res + end + + def test_picks_best_platform + is = Gem::Resolver::IndexSpecification + unknown = Gem::Platform.new 'unknown' + a2_p1 = a3_p2 = nil + + spec_fetcher do |fetcher| + fetcher.spec 'a', 2 + a2_p1 = fetcher.spec 'a', 2 do |s| s.platform = Gem::Platform.local end + a3_p2 = fetcher.spec 'a', 3 do |s| s.platform = unknown end + end + + v2 = v(2) + v3 = v(3) + source = Gem::Source.new @gem_repo + + s = set + + a2 = is.new s, 'a', v2, source, Gem::Platform::RUBY + a2_p1 = is.new s, 'a', v2, source, Gem::Platform.local.to_s + a3_p2 = is.new s, 'a', v3, source, unknown + + s.add a3_p2 + s.add a2_p1 + s.add a2 + + ad = make_dep "a" + + res = Gem::Resolver.new([ad], s) + + assert_resolves_to [a2_p1.spec], res + end + + def test_only_returns_spec_once + a1 = util_spec "a", "1", "c" => "= 1" + b1 = util_spec "b", "1", "c" => "= 1" + + c1 = util_spec "c", "1" + + ad = make_dep "a" + bd = make_dep "b" + + s = set(a1, b1, c1) + + res = Gem::Resolver.new([ad, bd], s) + + assert_resolves_to [a1, b1, c1], res + end + + def test_picks_lower_version_when_needed + a1 = util_spec "a", "1", "c" => ">= 1" + b1 = util_spec "b", "1", "c" => "= 1" + + c1 = util_spec "c", "1" + c2 = util_spec "c", "2" + + ad = make_dep "a" + bd = make_dep "b" + + s = set(a1, b1, c1, c2) + + res = Gem::Resolver.new([ad, bd], s) + + assert_resolves_to [a1, b1, c1], res + end + + def test_conflict_resolution_only_effects_correct_spec + a1 = util_spec "a", "1", "c" => ">= 1" + b1 = util_spec "b", "1", "d" => ">= 1" + + d3 = util_spec "d", "3", "c" => "= 1" + d4 = util_spec "d", "4", "c" => "= 1" + + c1 = util_spec "c", "1" + c2 = util_spec "c", "2" + + ad = make_dep "a" + bd = make_dep "b" + + s = set(a1, b1, d3, d4, c1, c2) + + res = Gem::Resolver.new([ad, bd], s) + + assert_resolves_to [a1, b1, c1, d4], res + end + + def test_backoff_higher_version_to_satisfy_dep + t3 = util_spec "railties", "3.2" + t4 = util_spec "railties", "4.0" + + r3 = util_spec "rails", "3.2", "railties" => "= 3.2" + r4 = util_spec "rails", "4.0", "railties" => "= 4.0" + + rd = make_dep "rails", "3.2" + + c3 = util_spec "coffee", "3.0", "railties" => "~> 3.0" + c4 = util_spec "coffee", "4.0", "railties" => "~> 4.0" + + cd = make_dep "coffee" + + s = set(t3, t4, r3, r4, c3, c4) + + res = Gem::Resolver.new([rd, cd], s) + + assert_resolves_to [r3, t3, c3], res + end + + def test_raises_dependency_error + a1 = util_spec "a", "1", "c" => "= 1" + b1 = util_spec "b", "1", "c" => "= 2" + + c1 = util_spec "c", "1" + c2 = util_spec "c", "2" + + ad = make_dep "a" + bd = make_dep "b" + + s = set(a1, b1, c1, c2) + + r = Gem::Resolver.new([ad, bd], s) + + e = assert_raises Gem::DependencyResolutionError do + r.resolve + end + + deps = [make_dep("c", "= 1"), make_dep("c", "= 2")] + assert_equal deps, e.conflicting_dependencies + + con = e.conflict + + act = con.activated + assert_equal "c-2", act.spec.full_name + + parent = act.parent + assert_equal "b-1", parent.spec.full_name + + act = con.requester + assert_equal "a-1", act.spec.full_name + end + + def test_raises_when_a_gem_is_missing + ad = make_dep "a" + + r = Gem::Resolver.new([ad], set) + + e = assert_raises Gem::UnsatisfiableDepedencyError do + r.resolve + end + + assert_equal "Unable to resolve dependency: user requested 'a (>= 0)'", + e.message + + assert_equal "a (>= 0)", e.dependency.to_s + end + + def test_raises_when_a_gem_version_is_missing + a1 = util_spec "a", "1" + + ad = make_dep "a", "= 3" + + r = Gem::Resolver.new([ad], set(a1)) + + e = assert_raises Gem::UnsatisfiableDepedencyError do + r.resolve + end + + assert_equal "a (= 3)", e.dependency.to_s + end + + def test_raises_and_reports_a_toplevel_request_properly + a1 = util_spec "a", "1" + ad = make_dep "a", "= 3" + + r = Gem::Resolver.new([ad], set(a1)) + + e = assert_raises Gem::UnsatisfiableDepedencyError do + r.resolve + end + + assert_equal "Unable to resolve dependency: user requested 'a (= 3)'", + e.message + end + + def test_raises_and_reports_an_implicit_request_properly + a1 = util_spec "a", "1" do |s| + s.add_runtime_dependency 'b', '= 2' + end + + ad = make_dep "a", "= 1" + + r = Gem::Resolver.new([ad], set(a1)) + + e = assert_raises Gem::UnsatisfiableDepedencyError do + r.resolve + end + + assert_equal "Unable to resolve dependency: 'a (= 1)' requires 'b (= 2)'", + e.message + end + + def test_raises_when_possibles_are_exhausted + a1 = util_spec "a", "1", "c" => ">= 2" + b1 = util_spec "b", "1", "c" => "= 1" + + c1 = util_spec "c", "1" + c2 = util_spec "c", "2" + c3 = util_spec "c", "3" + + s = set(a1, b1, c1, c2, c3) + + ad = make_dep "a" + bd = make_dep "b" + + r = Gem::Resolver.new([ad, bd], s) + + e = assert_raises Gem::DependencyResolutionError do + r.resolve + end + + dependency = e.conflict.dependency + + assert_equal 'a', dependency.name + assert_equal req('>= 0'), dependency.requirement + + activated = e.conflict.activated + assert_equal 'c-1', activated.full_name + + assert_equal dep('c', '= 1'), activated.request.dependency + + assert_equal [dep('c', '>= 2'), dep('c', '= 1')], + e.conflict.conflicting_dependencies + end + + def test_keeps_resolving_after_seeing_satisfied_dep + a1 = util_spec "a", "1", "b" => "= 1", "c" => "= 1" + b1 = util_spec "b", "1" + c1 = util_spec "c", "1" + + ad = make_dep "a" + bd = make_dep "b" + + s = set(a1, b1, c1) + + r = Gem::Resolver.new([ad, bd], s) + + assert_resolves_to [a1, b1, c1], r + end + + def test_common_rack_activation_scenario + rack100 = util_spec "rack", "1.0.0" + rack101 = util_spec "rack", "1.0.1" + + lib1 = util_spec "lib", "1", "rack" => ">= 1.0.1" + + rails = util_spec "rails", "3", "actionpack" => "= 3" + ap = util_spec "actionpack", "3", "rack" => ">= 1.0.0" + + d1 = make_dep "rails" + d2 = make_dep "lib" + + s = set(lib1, rails, ap, rack100, rack101) + + r = Gem::Resolver.new([d1, d2], s) + + assert_resolves_to [rails, ap, rack101, lib1], r + + # check it with the deps reverse too + + r = Gem::Resolver.new([d2, d1], s) + + assert_resolves_to [lib1, rack101, rails, ap], r + end + + def test_backtracks_to_the_first_conflict + a1 = util_spec "a", "1" + a2 = util_spec "a", "2" + a3 = util_spec "a", "3" + a4 = util_spec "a", "4" + + d1 = make_dep "a" + d2 = make_dep "a", ">= 2" + d3 = make_dep "a", "= 1" + + s = set(a1, a2, a3, a4) + + r = Gem::Resolver.new([d1, d2, d3], s) + + assert_raises Gem::DependencyResolutionError do + r.resolve + end + end + + def test_resolve_conflict + a1 = util_spec 'a', 1 + a2 = util_spec 'a', 2 + + b2 = util_spec 'b', 2, 'a' => '~> 2.0' + + s = set a1, a2, b2 + + a_dep = dep 'a', '~> 1.0' + b_dep = dep 'b' + + r = Gem::Resolver.new [a_dep, b_dep], s + + assert_raises Gem::DependencyResolutionError do + r.resolve + end + end + + def test_resolve_bug_699 + a1 = util_spec 'a', '1', 'b' => '= 2', + 'c' => '~> 1.0.3' + + b1 = util_spec 'b', '2', 'c' => '~> 1.0' + + c1 = util_spec 'c', '1.0.9' + c2 = util_spec 'c', '1.1.0' + c3 = util_spec 'c', '1.2.0' + + s = set a1, b1, c1, c2, c3 + + a_dep = dep 'a', '= 1' + + r = Gem::Resolver.new [a_dep], s + + assert_resolves_to [a1, b1, c1], r + end + + def test_resolve_rollback + a1 = util_spec 'a', 1 + a2 = util_spec 'a', 2 + + b1 = util_spec 'b', 1, 'a' => '~> 1.0' + b2 = util_spec 'b', 2, 'a' => '~> 2.0' + + s = set a1, a2, b1, b2 + + a_dep = dep 'a', '~> 1.0' + b_dep = dep 'b' + + r = Gem::Resolver.new [a_dep, b_dep], s + + assert_resolves_to [a1, b1], r + end + + # actionmailer 2.3.4 + # activemerchant 1.5.0 + # activesupport 2.3.5, 2.3.4 + # Activemerchant needs activesupport >= 2.3.2. When you require activemerchant, it will activate the latest version that meets that requirement which is 2.3.5. Actionmailer on the other hand needs activesupport = 2.3.4. When rubygems tries to activate activesupport 2.3.4, it will raise an error. + + + def test_simple_activesupport_problem + sup1 = util_spec "activesupport", "2.3.4" + sup2 = util_spec "activesupport", "2.3.5" + + merch = util_spec "activemerchant", "1.5.0", "activesupport" => ">= 2.3.2" + mail = util_spec "actionmailer", "2.3.4", "activesupport" => "= 2.3.4" + + s = set(mail, merch, sup1, sup2) + + d1 = make_dep "activemerchant" + d2 = make_dep "actionmailer" + + r = Gem::Resolver.new([d1, d2], s) + + assert_resolves_to [merch, mail, sup1], r + end + + def test_second_level_backout + b1 = new_spec "b", "1", { "c" => ">= 1" }, "lib/b.rb" + b2 = new_spec "b", "2", { "c" => ">= 2" }, "lib/b.rb" + c1 = new_spec "c", "1" + 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" + + s = set(b1, b2, c1, c2, d1, d2) + + p1 = make_dep "b", "> 0" + p2 = make_dep "d", "> 0" + + r = Gem::Resolver.new([p1, p2], s) + + assert_resolves_to [b1, c1, d2], r + end + + def test_select_local_platforms + r = Gem::Resolver.new nil, nil + + a1 = util_spec 'a', 1 + a1_p1 = util_spec 'a', 1 do |s| s.platform = Gem::Platform.local end + a1_p2 = util_spec 'a', 1 do |s| s.platform = 'unknown' end + + selected = r.select_local_platforms [a1, a1_p1, a1_p2] + + assert_equal [a1, a1_p1], selected + end + + def test_raises_and_explains_when_platform_prevents_install + a1 = util_spec "a", "1" do |s| + s.platform = Gem::Platform.new %w[c p 1] + end + + ad = make_dep "a", "= 1" + + r = Gem::Resolver.new([ad], set(a1)) + + e = assert_raises Gem::UnsatisfiableDepedencyError do + r.resolve + end + + assert_match "No match for 'a (= 1)' on this platform. Found: c-p-1", + e.message + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_activation_request.rb b/jni/ruby/test/rubygems/test_gem_resolver_activation_request.rb new file mode 100644 index 0000000..c9163e2 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_activation_request.rb @@ -0,0 +1,73 @@ +require 'rubygems/test_case' + +class TestGemResolverActivationRequest < Gem::TestCase + + def setup + super + + @DR = Gem::Resolver + + @dep = @DR::DependencyRequest.new dep('a', '>= 0'), nil + + source = Gem::Source::Local.new + platform = Gem::Platform::RUBY + + @a1 = @DR::IndexSpecification.new nil, 'a', v(1), source, platform + @a2 = @DR::IndexSpecification.new nil, 'a', v(2), source, platform + @a3 = @DR::IndexSpecification.new nil, 'a', v(3), source, platform + + @req = @DR::ActivationRequest.new @a3, @dep, [@a1, @a2] + end + + def test_development_eh + refute @req.development? + + dep_req = @DR::DependencyRequest.new dep('a', '>= 0', :development), nil + + act_req = @DR::ActivationRequest.new @a3, dep_req, [@a1, @a2] + + assert act_req.development? + end + + def test_inspect + assert_match 'a-3', @req.inspect + assert_match 'from a (>= 0)', @req.inspect + assert_match '(others possible: a-1, a-2)', @req.inspect + end + + def test_inspect_legacy + req = @DR::ActivationRequest.new @a3, @dep, true + + assert_match '(others possible)', req.inspect + + req = @DR::ActivationRequest.new @a3, @dep, false + + refute_match '(others possible)', req.inspect + end + + def test_installed_eh + v_spec = Gem::Resolver::VendorSpecification.new nil, @a3 + + @req = @DR::ActivationRequest.new v_spec, @dep, [@a1, @a2] + + assert @req.installed? + end + + def test_others_possible_eh + assert @req.others_possible? + + req = @DR::ActivationRequest.new @a3, @dep, [] + + refute req.others_possible? + + req = @DR::ActivationRequest.new @a3, @dep, true + + assert req.others_possible? + + req = @DR::ActivationRequest.new @a3, @dep, false + + refute req.others_possible? + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_api_set.rb b/jni/ruby/test/rubygems/test_gem_resolver_api_set.rb new file mode 100644 index 0000000..4ae54d7 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_api_set.rb @@ -0,0 +1,208 @@ +require 'rubygems/test_case' + +class TestGemResolverAPISet < Gem::TestCase + + def setup + super + + @DR = Gem::Resolver + @dep_uri = URI "#{@gem_repo}api/v1/dependencies" + end + + def test_initialize + set = @DR::APISet.new + + assert_equal URI('https://rubygems.org/api/v1/dependencies'), set.dep_uri + assert_equal URI('https://rubygems.org'), set.uri + assert_equal Gem::Source.new(URI('https://rubygems.org')), set.source + end + + def test_initialize_deeper_uri + set = @DR::APISet.new 'https://rubygemsserver.com/mygems/api/v1/dependencies' + + assert_equal URI('https://rubygemsserver.com/mygems/api/v1/dependencies'), set.dep_uri + assert_equal URI('https://rubygemsserver.com/mygems/'), set.uri + assert_equal Gem::Source.new(URI('https://rubygemsserver.com/mygems/')), set.source + end + + def test_initialize_uri + set = @DR::APISet.new @dep_uri + + assert_equal URI("#{@gem_repo}api/v1/dependencies"), set.dep_uri + assert_equal URI("#{@gem_repo}"), set.uri + end + + def test_find_all + spec_fetcher + + data = [ + { :name => 'a', + :number => '1', + :platform => 'ruby', + :dependencies => [], }, + ] + + @fetcher.data["#{@dep_uri}?gems=a"] = Marshal.dump data + + set = @DR::APISet.new @dep_uri + + a_dep = @DR::DependencyRequest.new dep('a'), nil + + expected = [ + @DR::APISpecification.new(set, data.first) + ] + + assert_equal expected, set.find_all(a_dep) + end + + def test_find_all_cache + spec_fetcher + + data = [ + { :name => 'a', + :number => '1', + :platform => 'ruby', + :dependencies => [], }, + ] + + @fetcher.data["#{@dep_uri}?gems=a"] = Marshal.dump data + + set = @DR::APISet.new @dep_uri + + a_dep = @DR::DependencyRequest.new dep('a'), nil + + set.prefetch [a_dep] + + expected = [ + @DR::APISpecification.new(set, data.first) + ] + + assert_equal expected, set.find_all(a_dep) + + @fetcher.data.delete "#{@dep_uri}?gems=a" + end + + def test_find_all_local + set = @DR::APISet.new @dep_uri + set.remote = false + + a_dep = @DR::DependencyRequest.new dep('a'), nil + + assert_empty set.find_all(a_dep) + end + + def test_find_all_missing + spec_fetcher + + @fetcher.data["#{@dep_uri}?gems=a"] = Marshal.dump [] + + set = @DR::APISet.new @dep_uri + + a_dep = @DR::DependencyRequest.new dep('a'), nil + + assert_empty set.find_all(a_dep) + + @fetcher.data.delete "#{@dep_uri}?gems=a" + + assert_empty set.find_all(a_dep) + end + + def test_prefetch + spec_fetcher + + data = [ + { :name => 'a', + :number => '1', + :platform => 'ruby', + :dependencies => [], }, + ] + + @fetcher.data["#{@dep_uri}?gems=a,b"] = Marshal.dump data + @fetcher.data["#{@dep_uri}?gems=b"] = Marshal.dump [] + + set = @DR::APISet.new @dep_uri + + a_dep = @DR::DependencyRequest.new dep('a'), nil + b_dep = @DR::DependencyRequest.new dep('b'), nil + + set.prefetch [a_dep, b_dep] + + assert_equal %w[a-1], set.find_all(a_dep).map { |s| s.full_name } + assert_empty set.find_all(b_dep) + end + + def test_prefetch_cache + spec_fetcher + + data = [ + { :name => 'a', + :number => '1', + :platform => 'ruby', + :dependencies => [], }, + ] + + @fetcher.data["#{@dep_uri}?gems=a"] = Marshal.dump data + + set = @DR::APISet.new @dep_uri + + a_dep = @DR::DependencyRequest.new dep('a'), nil + b_dep = @DR::DependencyRequest.new dep('b'), nil + + set.prefetch [a_dep] + + @fetcher.data.delete "#{@dep_uri}?gems=a" + @fetcher.data["#{@dep_uri}?gems=b"] = Marshal.dump [] + + set.prefetch [a_dep, b_dep] + end + + def test_prefetch_cache_missing + spec_fetcher + + data = [ + { :name => 'a', + :number => '1', + :platform => 'ruby', + :dependencies => [], }, + ] + + @fetcher.data["#{@dep_uri}?gems=a,b"] = Marshal.dump data + + set = @DR::APISet.new @dep_uri + + a_dep = @DR::DependencyRequest.new dep('a'), nil + b_dep = @DR::DependencyRequest.new dep('b'), nil + + set.prefetch [a_dep, b_dep] + + @fetcher.data.delete "#{@dep_uri}?gems=a,b" + + set.prefetch [a_dep, b_dep] + end + + def test_prefetch_local + spec_fetcher + + data = [ + { :name => 'a', + :number => '1', + :platform => 'ruby', + :dependencies => [], }, + ] + + @fetcher.data["#{@dep_uri}?gems=a,b"] = Marshal.dump data + @fetcher.data["#{@dep_uri}?gems=b"] = Marshal.dump [] + + set = @DR::APISet.new @dep_uri + set.remote = false + + a_dep = @DR::DependencyRequest.new dep('a'), nil + b_dep = @DR::DependencyRequest.new dep('b'), nil + + set.prefetch [a_dep, b_dep] + + assert_empty set.instance_variable_get :@data + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_api_specification.rb b/jni/ruby/test/rubygems/test_gem_resolver_api_specification.rb new file mode 100644 index 0000000..dfa61e9 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_api_specification.rb @@ -0,0 +1,144 @@ +require 'rubygems/test_case' + +class TestGemResolverAPISpecification < Gem::TestCase + + def test_initialize + set = Gem::Resolver::APISet.new + data = { + :name => 'rails', + :number => '3.0.3', + :platform => Gem::Platform.local.to_s, + :dependencies => [ + ['bundler', '~> 1.0'], + ['railties', '= 3.0.3'], + ], + } + + spec = Gem::Resolver::APISpecification.new set, data + + assert_equal 'rails', spec.name + assert_equal Gem::Version.new('3.0.3'), spec.version + assert_equal Gem::Platform.local, spec.platform + + expected = [ + Gem::Dependency.new('bundler', '~> 1.0'), + Gem::Dependency.new('railties', '= 3.0.3'), + ] + + assert_equal expected, spec.dependencies + end + + def test_fetch_development_dependencies + specs = spec_fetcher do |fetcher| + fetcher.spec 'rails', '3.0.3' do |s| + s.add_runtime_dependency 'bundler', '~> 1.0' + s.add_runtime_dependency 'railties', '= 3.0.3' + s.add_development_dependency 'a', '= 1' + end + end + + rails = specs['rails-3.0.3'] + + repo = @gem_repo + 'api/v1/dependencies' + + set = Gem::Resolver::APISet.new repo + + data = { + :name => 'rails', + :number => '3.0.3', + :platform => 'ruby', + :dependencies => [ + ['bundler', '~> 1.0'], + ['railties', '= 3.0.3'], + ], + } + + util_setup_spec_fetcher rails + + spec = Gem::Resolver::APISpecification.new set, data + + spec.fetch_development_dependencies + + expected = [ + Gem::Dependency.new('bundler', '~> 1.0'), + Gem::Dependency.new('railties', '= 3.0.3'), + Gem::Dependency.new('a', '= 1', :development), + ] + + assert_equal expected, spec.dependencies + end + + def test_installable_platform_eh + set = Gem::Resolver::APISet.new + data = { + :name => 'a', + :number => '1', + :platform => 'ruby', + :dependencies => [], + } + + a_spec = Gem::Resolver::APISpecification.new set, data + + assert a_spec.installable_platform? + + data = { + :name => 'b', + :number => '1', + :platform => 'cpu-other_platform-1', + :dependencies => [], + } + + b_spec = Gem::Resolver::APISpecification.new set, data + + refute b_spec.installable_platform? + + data = { + :name => 'c', + :number => '1', + :platform => Gem::Platform.local.to_s, + :dependencies => [], + } + + c_spec = Gem::Resolver::APISpecification.new set, data + + assert c_spec.installable_platform? + end + + def test_source + set = Gem::Resolver::APISet.new + data = { + :name => 'a', + :number => '1', + :platform => 'ruby', + :dependencies => [], + } + + api_spec = Gem::Resolver::APISpecification.new set, data + + assert_equal set.source, api_spec.source + end + + def test_spec + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + end + + dep_uri = URI(@gem_repo) + 'api/v1/dependencies' + set = Gem::Resolver::APISet.new dep_uri + data = { + :name => 'a', + :number => '1', + :platform => 'ruby', + :dependencies => [], + } + + api_spec = Gem::Resolver::APISpecification.new set, data + + spec = api_spec.spec + + assert_kind_of Gem::Specification, spec + assert_equal 'a-1', spec.full_name + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_best_set.rb b/jni/ruby/test/rubygems/test_gem_resolver_best_set.rb new file mode 100644 index 0000000..055438c --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_best_set.rb @@ -0,0 +1,137 @@ +require 'rubygems/test_case' + +class TestGemResolverBestSet < Gem::TestCase + + def setup + super + + @DR = Gem::Resolver + end + + def test_initialize + set = @DR::BestSet.new + + assert_empty set.sets + end + + def test_find_all_index + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.spec 'a', 2 + fetcher.spec 'b', 1 + end + + set = @DR::BestSet.new + + dependency = dep 'a', '~> 1' + + req = @DR::DependencyRequest.new dependency, nil + + found = set.find_all req + + assert_equal %w[a-1], found.map { |s| s.full_name } + end + + def test_find_all_fallback + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + end + + set = @DR::BestSet.new + + api_uri = URI(@gem_repo) + './api/v1/dependencies' + + set.sets << Gem::Resolver::APISet.new(api_uri) + + dependency = dep 'a', '~> 1' + + req = @DR::DependencyRequest.new dependency, nil + + found = set.find_all req + + assert_equal %w[a-1], found.map { |s| s.full_name } + end + + def test_find_all_local + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.spec 'a', 2 + fetcher.spec 'b', 1 + end + + set = @DR::BestSet.new + set.remote = false + + dependency = dep 'a', '~> 1' + + req = @DR::DependencyRequest.new dependency, nil + + found = set.find_all req + + assert_empty found + end + + def test_prefetch + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + end + + set = @DR::BestSet.new + + set.prefetch [] + + refute_empty set.sets + end + + def test_prefetch_local + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + end + + set = @DR::BestSet.new + set.remote = false + + set.prefetch [] + + assert_empty set.sets + end + + def test_replace_failed_api_set + set = @DR::BestSet.new + + api_uri = URI(@gem_repo) + './api/v1/dependencies' + api_set = Gem::Resolver::APISet.new api_uri + + set.sets << api_set + + error_uri = api_uri + '?gems=a' + + error = Gem::RemoteFetcher::FetchError.new 'bogus', error_uri + + set.replace_failed_api_set error + + assert_equal 1, set.sets.size + + refute_includes set.sets, api_set + + assert_kind_of Gem::Resolver::IndexSet, set.sets.first + end + + def test_replace_failed_api_set_no_api_set + set = @DR::BestSet.new + + index_set = Gem::Resolver::IndexSet.new Gem::Source.new @gem_repo + + set.sets << index_set + + error = Gem::RemoteFetcher::FetchError.new 'bogus', @gem_repo + + e = assert_raises Gem::RemoteFetcher::FetchError do + set.replace_failed_api_set error + end + + assert_equal error, e + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_composed_set.rb b/jni/ruby/test/rubygems/test_gem_resolver_composed_set.rb new file mode 100644 index 0000000..f8455e1 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_composed_set.rb @@ -0,0 +1,45 @@ +require 'rubygems/test_case' + +class TestGemResolverComposedSet < Gem::TestCase + + def test_errors + index_set = Gem::Resolver::IndexSet.new + current_set = Gem::Resolver::CurrentSet.new + + set = Gem::Resolver::ComposedSet.new index_set, current_set + + set.instance_variable_get(:@errors) << :a + current_set.errors << :b + + assert_includes set.errors, :a + assert_includes set.errors, :b + assert_includes set.errors, index_set.errors.first + end + + def test_prerelease_equals + best_set = Gem::Resolver::BestSet.new + current_set = Gem::Resolver::CurrentSet.new + + set = Gem::Resolver::ComposedSet.new best_set, current_set + + set.prerelease = true + + assert set.prerelease + assert best_set.prerelease + assert current_set.prerelease + end + + def test_remote_equals + best_set = Gem::Resolver::BestSet.new + current_set = Gem::Resolver::CurrentSet.new + + set = Gem::Resolver::ComposedSet.new best_set, current_set + + set.remote = false + + refute best_set.remote? + refute current_set.remote? + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_conflict.rb b/jni/ruby/test/rubygems/test_gem_resolver_conflict.rb new file mode 100644 index 0000000..0cef0ca --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_conflict.rb @@ -0,0 +1,87 @@ +require 'rubygems/test_case' + +class TestGemResolverConflict < Gem::TestCase + + def test_self_compatibility + assert_same Gem::Resolver::Conflict, Gem::Resolver::DependencyConflict + end + + def test_explanation + root = + dependency_request dep('net-ssh', '>= 2.0.13'), 'rye', '0.9.8' + child = + dependency_request dep('net-ssh', '>= 2.6.5'), 'net-ssh', '2.2.2', root + + dep = Gem::Resolver::DependencyRequest.new dep('net-ssh', '>= 2.0.13'), nil + + spec = quick_spec 'net-ssh', '2.2.2' + active = + Gem::Resolver::ActivationRequest.new spec, dep + + conflict = + Gem::Resolver::Conflict.new child, active + + expected = <<-EXPECTED + Activated net-ssh-2.2.2 + which does not match conflicting dependency (>= 2.6.5) + + Conflicting dependency chains: + net-ssh (>= 2.0.13), 2.2.2 activated + + versus: + rye (= 0.9.8), 0.9.8 activated, depends on + net-ssh (>= 2.0.13), 2.2.2 activated, depends on + net-ssh (>= 2.6.5) + + EXPECTED + + assert_equal expected, conflict.explanation + end + + def test_explanation_user_request + @DR = Gem::Resolver + + spec = util_spec 'a', 2 + + a1_req = @DR::DependencyRequest.new dep('a', '= 1'), nil + a2_req = @DR::DependencyRequest.new dep('a', '= 2'), nil + + activated = @DR::ActivationRequest.new spec, a2_req + + conflict = @DR::Conflict.new a1_req, activated + + expected = <<-EXPECTED + Activated a-2 + which does not match conflicting dependency (= 1) + + Conflicting dependency chains: + a (= 2), 2 activated + + versus: + a (= 1) + + EXPECTED + + assert_equal expected, conflict.explanation + end + + def test_request_path + root = + dependency_request dep('net-ssh', '>= 2.0.13'), 'rye', '0.9.8' + + child = + dependency_request dep('other', '>= 1.0'), 'net-ssh', '2.2.2', root + + conflict = + Gem::Resolver::Conflict.new nil, nil + + expected = [ + 'net-ssh (>= 2.0.13), 2.2.2 activated', + 'rye (= 0.9.8), 0.9.8 activated' + ] + + assert_equal expected, conflict.request_path(child.requester) + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_dependency_request.rb b/jni/ruby/test/rubygems/test_gem_resolver_dependency_request.rb new file mode 100644 index 0000000..0665883 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_dependency_request.rb @@ -0,0 +1,84 @@ +require 'rubygems/test_case' + +class TestGemResolverDependencyRequest < Gem::TestCase + + def setup + super + + @DR = Gem::Resolver::DependencyRequest + end + + def test_development_eh + a_dep = dep 'a', '>= 1' + + a_dep_req = @DR.new a_dep, nil + + refute a_dep_req.development? + + b_dep = dep 'b', '>= 1', :development + + b_dep_req = @DR.new b_dep, nil + + assert b_dep_req.development? + end + + def test_match_eh + spec = util_spec 'a', 1 + dependency = dep 'a', '>= 1' + + dr = @DR.new dependency, nil + + assert dr.match? spec + end + + def test_match_eh_prerelease + spec = util_spec 'a', '1.a' + + a_dep = dep 'a', '>= 1' + a_dr = @DR.new a_dep, nil + + refute a_dr.match? spec + + a_pre_dep = dep 'a', '>= 1.a' + a_pre_dr = @DR.new a_pre_dep, nil + + assert a_pre_dr.match? spec + end + + def test_match_eh_prerelease_allow_prerelease + spec = util_spec 'a', '2.a' + + a_dep = dep 'a', '>= 1' + a_dr = @DR.new a_dep, nil + + assert a_dr.match? spec, true + end + + def test_matches_spec_eh + spec = util_spec 'a', 1 + dependency = dep 'a', '>= 1' + + dr = @DR.new dependency, nil + + assert dr.matches_spec? spec + end + + def test_matches_spec_eh_prerelease + spec = util_spec 'a', '1.a' + + dependency = dep 'a', '>= 0' + dr = @DR.new dependency, nil + + assert dr.matches_spec? spec + end + + def test_requirement + dependency = dep 'a', '>= 1' + + dr = @DR.new dependency, nil + + assert_equal dependency, dr.dependency + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_git_set.rb b/jni/ruby/test/rubygems/test_gem_resolver_git_set.rb new file mode 100644 index 0000000..3659193 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_git_set.rb @@ -0,0 +1,189 @@ +require 'rubygems/test_case' + +class TestGemResolverGitSet < Gem::TestCase + + def setup + super + + @set = Gem::Resolver::GitSet.new + + @reqs = Gem::Resolver::RequirementList.new + end + + def test_add_git_gem + name, version, repository, = git_gem + + @set.add_git_gem name, repository, 'master', false + + dependency = dep 'a' + + specs = @set.find_all dependency + + assert_equal "#{name}-#{version}", specs.first.full_name + + refute @set.need_submodules[repository] + end + + def test_add_git_gem_submodules + name, _, repository, = git_gem + + @set.add_git_gem name, repository, 'master', true + + dependency = dep 'a' + + refute_empty @set.find_all dependency + + assert @set.need_submodules[repository] + end + + def test_add_git_spec + name, version, repository, revision = git_gem + + @set.add_git_spec name, version, repository, revision, true + + dependency = dep 'a' + + specs = @set.find_all dependency + + spec = specs.first + + assert_equal "#{name}-#{version}", spec.full_name + + assert @set.need_submodules[repository] + + refute_path_exists spec.source.repo_cache_dir + end + + def test_find_all + name, _, repository, = git_gem + + @set.add_git_gem name, repository, 'master', false + + dependency = dep 'a', '~> 1.0' + req = Gem::Resolver::DependencyRequest.new dependency, nil + @reqs.add req + + @set.prefetch @reqs + + found = @set.find_all dependency + + assert_equal [@set.specs['a']], found + end + + def test_find_all_local + name, _, repository, = git_gem + + @set.add_git_gem name, repository, 'master', false + @set.remote = false + + dependency = dep 'a', '~> 1.0' + req = Gem::Resolver::DependencyRequest.new dependency, nil + @reqs.add req + + @set.prefetch @reqs + + assert_empty @set.find_all dependency + end + + def test_find_all_prerelease + name, _, repository, = git_gem 'a', '1.a' + + @set.add_git_gem name, repository, 'master', false + + dependency = dep 'a', '>= 0' + req = Gem::Resolver::DependencyRequest.new dependency, nil + @reqs.add req + + @set.prefetch @reqs + + found = @set.find_all dependency + + assert_empty found + + dependency = dep 'a', '>= 0.a' + req = Gem::Resolver::DependencyRequest.new dependency, nil + @reqs.add req + + @set.prefetch @reqs + + found = @set.find_all dependency + + refute_empty found + end + + def test_root_dir + assert_equal Gem.dir, @set.root_dir + + @set.root_dir = "#{@gemhome}2" + + assert_equal "#{@gemhome}2", @set.root_dir + end + + def test_prefetch + name, _, repository, = git_gem + + @set.add_git_gem name, repository, 'master', false + + dependency = dep name + req = Gem::Resolver::DependencyRequest.new dependency, nil + @reqs.add req + + @set.prefetch @reqs + + refute_empty @set.specs + end + + def test_prefetch_cache + name, _, repository, = git_gem + + @set.add_git_gem name, repository, 'master', false + + dependency = dep name + req = Gem::Resolver::DependencyRequest.new dependency, nil + @reqs.add req + + @set.prefetch @reqs + + spec = @set.specs[name] + + @set.prefetch @reqs + + assert_same spec, @set.specs[name] + end + + def test_prefetch_filter + name, _, repository, = git_gem + + @set.add_git_gem name, repository, 'master', false + + dependency = dep 'b' + req = Gem::Resolver::DependencyRequest.new dependency, nil + @reqs.add req + + @set.prefetch @reqs + + refute_empty @set.specs, 'the git source does not filter' + end + + def test_prefetch_root_dir + name, _, repository, = git_gem + + @set.add_git_gem name, repository, 'master', false + + dependency = dep name + req = Gem::Resolver::DependencyRequest.new dependency, nil + @reqs.add req + + @set.root_dir = "#{@gemhome}2" + + @set.prefetch @reqs + + refute_empty @set.specs + + spec = @set.specs.values.first + + assert_equal "#{@gemhome}2", spec.source.root_dir + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_git_specification.rb b/jni/ruby/test/rubygems/test_gem_resolver_git_specification.rb new file mode 100644 index 0000000..a31674a --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_git_specification.rb @@ -0,0 +1,112 @@ +require 'rubygems/test_case' + +class TestGemResolverGitSpecification < Gem::TestCase + + def setup + super + + @set = Gem::Resolver::GitSet.new + @spec = Gem::Specification.new 'a', 1 + end + + def test_equals2 + g_spec_a = Gem::Resolver::GitSpecification.new @set, @spec + + assert_equal g_spec_a, g_spec_a + + spec_b = Gem::Specification.new 'b', 1 + g_spec_b = Gem::Resolver::GitSpecification.new @set, spec_b + + refute_equal g_spec_a, g_spec_b + + g_set = Gem::Resolver::GitSet.new + g_spec_s = Gem::Resolver::GitSpecification.new g_set, @spec + + refute_equal g_spec_a, g_spec_s + + i_set = Gem::Resolver::IndexSet.new + source = Gem::Source.new @gem_repo + i_spec = Gem::Resolver::IndexSpecification.new( + i_set, 'a', v(1), source, Gem::Platform::RUBY) + + refute_equal g_spec_a, i_spec + end + + def test_add_dependency + git_gem 'a', 1 + + git_spec = Gem::Resolver::GitSpecification.new @set, @spec + + b_dep = dep 'b' + + git_spec.add_dependency b_dep + + assert_equal [b_dep], git_spec.dependencies + end + + def test_install + git_gem 'a', 1 + + git_spec = Gem::Resolver::GitSpecification.new @set, @spec + + called = false + + git_spec.install({}) do |installer| + called = installer + end + + assert called + end + + # functional test for Gem::Ext::Builder + + def test_install_extension + name, _, repository, = git_gem 'a', 1 do |s| + s.extensions << 'ext/extconf.rb' + end + + Dir.chdir 'git/a' do + FileUtils.mkdir_p 'ext/lib' + + open 'ext/extconf.rb', 'w' do |io| + io.puts 'require "mkmf"' + io.puts 'create_makefile "a"' + end + + FileUtils.touch 'ext/lib/b.rb' + + system @git, 'add', 'ext/extconf.rb' + system @git, 'add', 'ext/lib/b.rb' + + system @git, 'commit', '--quiet', '-m', 'Add extension files' + end + + source = Gem::Source::Git.new name, repository, 'master', true + + spec = source.specs.first + + git_spec = Gem::Resolver::GitSpecification.new @set, spec, source + + git_spec.install({}) + + assert_path_exists File.join git_spec.spec.extension_dir, 'b.rb' + end + + def test_install_installed + git_gem 'a', 1 + + git_spec = Gem::Resolver::GitSpecification.new @set, @spec + + git_spec.install({}) + + called = false + + git_spec.install({}) do |installer| + called = installer + end + + assert called + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_index_set.rb b/jni/ruby/test/rubygems/test_gem_resolver_index_set.rb new file mode 100644 index 0000000..04ef884 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_index_set.rb @@ -0,0 +1,89 @@ +require 'rubygems/test_case' + +class TestGemResolverIndexSet < Gem::TestCase + + def setup + super + + @DR = Gem::Resolver + end + + def test_initialize + set = @DR::IndexSet.new + + fetcher = set.instance_variable_get :@f + + assert_same Gem::SpecFetcher.fetcher, fetcher + end + + def test_initialize_source + set = @DR::IndexSet.new 'http://alternate.example' + + fetcher = set.instance_variable_get :@f + + refute_same Gem::SpecFetcher.fetcher, fetcher + + refute_empty set.errors + end + + def test_find_all + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.spec 'a', 2 + fetcher.spec 'b', 1 + end + + set = @DR::IndexSet.new + + dependency = dep 'a', '~> 1' + + req = @DR::DependencyRequest.new dependency, nil + + found = set.find_all req + + assert_equal %w[a-1], found.map { |s| s.full_name } + end + + def test_find_all_local + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.spec 'a', 2 + fetcher.spec 'b', 1 + end + + set = @DR::IndexSet.new + set.remote = false + + dependency = dep 'a', '~> 1' + + req = @DR::DependencyRequest.new dependency, nil + + assert_empty set.find_all req + end + + def test_find_all_prerelease + spec_fetcher do |fetcher| + fetcher.spec 'a', '1.a' + end + + set = @DR::IndexSet.new + + dependency = dep 'a' + + req = @DR::DependencyRequest.new dependency, nil + + found = set.find_all req + + assert_empty found + + dependency.prerelease = true + + req = @DR::DependencyRequest.new dependency, nil + + found = set.find_all req + + assert_equal %w[a-1.a], found.map { |s| s.full_name } + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_index_specification.rb b/jni/ruby/test/rubygems/test_gem_resolver_index_specification.rb new file mode 100644 index 0000000..e52f9c7 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_index_specification.rb @@ -0,0 +1,89 @@ +require 'rubygems/test_case' +require 'rubygems/available_set' + +class TestGemResolverIndexSpecification < Gem::TestCase + + def test_initialize + set = Gem::Resolver::IndexSet.new + source = Gem::Source.new @gem_repo + version = Gem::Version.new '3.0.3' + + spec = Gem::Resolver::IndexSpecification.new( + set, 'rails', version, source, Gem::Platform::RUBY) + + assert_equal 'rails', spec.name + assert_equal version, spec.version + assert_equal Gem::Platform::RUBY, spec.platform + + assert_equal source, spec.source + end + + def test_initialize_platform + set = Gem::Resolver::IndexSet.new + source = Gem::Source::Local.new + version = Gem::Version.new '3.0.3' + + spec = Gem::Resolver::IndexSpecification.new( + set, 'rails', version, source, Gem::Platform.local) + + assert_equal Gem::Platform.local.to_s, spec.platform + end + + def test_install + spec_fetcher do |fetcher| + fetcher.gem 'a', 2 + end + + set = Gem::Resolver::IndexSet.new + source = Gem::Source.new @gem_repo + + spec = Gem::Resolver::IndexSpecification.new( + set, 'a', v(2), source, Gem::Platform::RUBY) + + called = false + + spec.install({}) do |installer| + called = installer + end + + assert_path_exists File.join @gemhome, 'specifications', 'a-2.gemspec' + + assert_kind_of Gem::Installer, called + end + + def test_spec + specs = spec_fetcher do |fetcher| + fetcher.spec 'a', 2 + fetcher.spec 'a', 2 do |s| s.platform = Gem::Platform.local end + end + + source = Gem::Source.new @gem_repo + version = v 2 + + set = Gem::Resolver::IndexSet.new + i_spec = Gem::Resolver::IndexSpecification.new \ + set, 'a', version, source, Gem::Platform.local + + spec = i_spec.spec + + assert_equal specs["a-2-#{Gem::Platform.local}"].full_name, spec.full_name + end + + def test_spec_local + a_2_p = util_spec 'a', 2 do |s| s.platform = Gem::Platform.local end + Gem::Package.build a_2_p + + source = Gem::Source::Local.new + set = Gem::Resolver::InstallerSet.new :local + set.always_install << a_2_p + + i_spec = Gem::Resolver::IndexSpecification.new \ + set, 'a', v(2), source, Gem::Platform.local + + spec = i_spec.spec + + assert_equal a_2_p.full_name, spec.full_name + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_installed_specification.rb b/jni/ruby/test/rubygems/test_gem_resolver_installed_specification.rb new file mode 100644 index 0000000..d52876f --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_installed_specification.rb @@ -0,0 +1,49 @@ +require 'rubygems/test_case' + +class TestGemResolverInstalledSpecification < Gem::TestCase + + def setup + super + + @set = Gem::Resolver::CurrentSet.new + end + + def test_initialize + source_spec = util_spec 'a' + + spec = Gem::Resolver::InstalledSpecification.new @set, source_spec + + assert_equal 'a', spec.name + assert_equal Gem::Version.new(2), spec.version + assert_equal Gem::Platform::RUBY, spec.platform + end + + def test_install + a = util_spec 'a' + + spec = Gem::Resolver::InstalledSpecification.new @set, a + + called = :junk + + spec.install({}) do |installer| + called = installer + end + + assert_nil called + end + + def test_installable_platform_eh + b, b_gem = util_gem 'a', 1 do |s| + s.platform = Gem::Platform.new %w[cpu other_platform 1] + end + + source = Gem::Source::SpecificFile.new b_gem + + b_spec = Gem::Resolver::InstalledSpecification.new @set, b, source + + assert b_spec.installable_platform? + end + + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_installer_set.rb b/jni/ruby/test/rubygems/test_gem_resolver_installer_set.rb new file mode 100644 index 0000000..d7b917b --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_installer_set.rb @@ -0,0 +1,261 @@ +require 'rubygems/test_case' + +class TestGemResolverInstallerSet < Gem::TestCase + + def test_add_always_install + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.spec 'a', 2 + fetcher.clear + end + + util_gem 'a', 1 + + set = Gem::Resolver::InstallerSet.new :both + + set.add_always_install dep('a') + + assert_equal %w[a-2], set.always_install.map { |s| s.full_name } + + e = assert_raises Gem::UnsatisfiableDependencyError do + set.add_always_install dep('b') + end + + assert_equal dep('b'), e.dependency.dependency + end + + def test_add_always_install_errors + @fetcher = Gem::FakeFetcher.new + Gem::RemoteFetcher.fetcher = @fetcher + + set = Gem::Resolver::InstallerSet.new :both + + e = assert_raises Gem::UnsatisfiableDependencyError do + set.add_always_install dep 'a' + end + + refute_empty e.errors + end + + def test_add_always_install_platform + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.spec 'a', 2 do |s| + s.platform = Gem::Platform.new 'x86-freebsd-9' + end + fetcher.clear + end + + set = Gem::Resolver::InstallerSet.new :both + + set.add_always_install dep('a') + + assert_equal %w[a-1], set.always_install.map { |s| s.full_name } + end + + def test_add_always_install_prerelease + spec_fetcher do |fetcher| + fetcher.gem 'a', 1 + fetcher.gem 'a', '3.a' + end + + set = Gem::Resolver::InstallerSet.new :both + + set.add_always_install dep('a') + + assert_equal %w[a-1], set.always_install.map { |s| s.full_name } + end + + def test_add_always_install_prerelease_only + spec_fetcher do |fetcher| + fetcher.gem 'a', '3.a' + end + + set = Gem::Resolver::InstallerSet.new :both + + assert_raises Gem::UnsatisfiableDependencyError do + set.add_always_install dep('a') + end + end + + def test_add_local + a_1, a_1_gem = util_gem 'a', 1 + + a_1_source = Gem::Source::SpecificFile.new a_1_gem + + set = Gem::Resolver::InstallerSet.new :both + + set.add_local File.basename(a_1_gem), a_1, a_1_source + + assert set.local? File.basename(a_1_gem) + + FileUtils.rm a_1_gem + util_clear_gems + + req = Gem::Resolver::DependencyRequest.new dep('a'), nil + + assert_equal %w[a-1], set.find_all(req).map { |spec| spec.full_name } + end + + def test_consider_local_eh + set = Gem::Resolver::InstallerSet.new :remote + + refute set.consider_local? + + set = Gem::Resolver::InstallerSet.new :both + + assert set.consider_local? + + set = Gem::Resolver::InstallerSet.new :local + + assert set.consider_local? + end + + def test_consider_remote_eh + set = Gem::Resolver::InstallerSet.new :remote + + assert set.consider_remote? + + set = Gem::Resolver::InstallerSet.new :both + + assert set.consider_remote? + + set = Gem::Resolver::InstallerSet.new :local + + refute set.consider_remote? + end + + def test_errors + set = Gem::Resolver::InstallerSet.new :both + + set.instance_variable_get(:@errors) << :a + + req = Gem::Resolver::DependencyRequest.new dep('a'), nil + + set.find_all req + + assert_equal [:a, set.remote_set.errors.first], set.errors + end + + def test_find_all_always_install + spec_fetcher do |fetcher| + fetcher.spec 'a', 2 + fetcher.clear + end + + util_gem 'a', 1 + + set = Gem::Resolver::InstallerSet.new :both + + set.add_always_install dep 'a' + + req = Gem::Resolver::DependencyRequest.new dep('a'), nil + + assert_equal %w[a-2], set.find_all(req).map { |spec| spec.full_name } + end + + def test_find_all_prerelease + spec_fetcher do |fetcher| + fetcher.spec 'a', '1' + fetcher.spec 'a', '1.a' + fetcher.clear + end + + set = Gem::Resolver::InstallerSet.new :both + + req = Gem::Resolver::DependencyRequest.new dep('a'), nil + + assert_equal %w[a-1], set.find_all(req).map { |spec| spec.full_name } + + req = Gem::Resolver::DependencyRequest.new dep('a', '>= 0.a'), nil + + assert_equal %w[a-1 a-1.a], + set.find_all(req).map { |spec| spec.full_name }.sort + end + + def test_load_spec + specs = spec_fetcher do |fetcher| + fetcher.spec 'a', 2 + fetcher.spec 'a', 2 do |s| s.platform = Gem::Platform.local end + end + + source = Gem::Source.new @gem_repo + version = v 2 + + set = Gem::Resolver::InstallerSet.new :remote + + spec = set.load_spec 'a', version, Gem::Platform.local, source + + assert_equal specs["a-2-#{Gem::Platform.local}"].full_name, spec.full_name + end + + def test_prefetch + set = Gem::Resolver::InstallerSet.new :remote + def (set.remote_set).prefetch(_) + raise "called" + end + assert_raises(RuntimeError){ set.prefetch(nil) } + + set = Gem::Resolver::InstallerSet.new :local + def (set.remote_set).prefetch(_) + raise "called" + end + assert_equal nil, set.prefetch(nil) + end + + def test_prerelease_equals + set = Gem::Resolver::InstallerSet.new :remote + + refute set.prerelease + refute set.remote_set.prerelease + + set.prerelease = true + + assert set.prerelease + assert set.remote_set.prerelease + end + + def test_remote_equals_both + set = Gem::Resolver::InstallerSet.new :both + set.remote = true + + assert set.consider_local? + assert set.consider_remote? + + set = Gem::Resolver::InstallerSet.new :both + set.remote = false + + assert set.consider_local? + refute set.consider_remote? + end + + def test_remote_equals_local + set = Gem::Resolver::InstallerSet.new :local + set.remote = true + + assert set.consider_local? + assert set.consider_remote? + + set = Gem::Resolver::InstallerSet.new :local + set.remote = false + + assert set.consider_local? + refute set.consider_remote? + end + + def test_remote_equals_remote + set = Gem::Resolver::InstallerSet.new :remote + set.remote = true + + refute set.consider_local? + assert set.consider_remote? + + set = Gem::Resolver::InstallerSet.new :remote + set.remote = false + + refute set.consider_local? + refute set.consider_remote? + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_local_specification.rb b/jni/ruby/test/rubygems/test_gem_resolver_local_specification.rb new file mode 100644 index 0000000..fc3175a --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_local_specification.rb @@ -0,0 +1,45 @@ +require 'rubygems/test_case' +require 'rubygems/available_set' + +class TestGemResolverLocalSpecification < Gem::TestCase + + def setup + super + + @set = Gem::AvailableSet.new + end + + def test_install + specs = spec_fetcher do |fetcher| + fetcher.gem 'a', 2 + end + + source = Gem::Source::SpecificFile.new 'gems/a-2.gem' + + spec = Gem::Resolver::LocalSpecification.new @set, specs['a-2'], source + + called = false + + spec.install({}) do |installer| + called = installer + end + + assert_path_exists File.join @gemhome, 'specifications', 'a-2.gemspec' + + assert_kind_of Gem::Installer, called + end + + def test_installable_platform_eh + b, b_gem = util_gem 'a', 1 do |s| + s.platform = Gem::Platform.new %w[cpu other_platform 1] + end + + source = Gem::Source::SpecificFile.new b_gem + + b_spec = Gem::Resolver::InstalledSpecification.new @set, b, source + + assert b_spec.installable_platform? + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_lock_set.rb b/jni/ruby/test/rubygems/test_gem_resolver_lock_set.rb new file mode 100644 index 0000000..fdcb8ff --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_lock_set.rb @@ -0,0 +1,63 @@ +require 'rubygems/test_case' + +class TestGemResolverLockSet < Gem::TestCase + + def setup + super + + @sources = [Gem::Source.new(@gem_repo)] + @lock_source = Gem::Source::Lock.new @sources.first + + @set = Gem::Resolver::LockSet.new @sources + end + + def test_add + specs = @set.add 'a', '2', Gem::Platform::RUBY + spec = specs.first + + assert_equal %w[a-2], @set.specs.map { |t| t.full_name } + + assert_kind_of Gem::Resolver::LockSpecification, spec + + assert_equal @set, spec.set + assert_equal 'a', spec.name + assert_equal v(2), spec.version + assert_equal Gem::Platform::RUBY, spec.platform + assert_equal @lock_source, spec.source + end + + def test_find_all + @set.add 'a', '1.a', Gem::Platform::RUBY + @set.add 'a', '2', Gem::Platform::RUBY + @set.add 'b', '2', Gem::Platform::RUBY + + found = @set.find_all dep 'a' + + assert_equal %w[a-2], found.map { |s| s.full_name } + + found = @set.find_all dep 'a', '>= 0.a' + + assert_equal %w[a-1.a a-2], found.map { |s| s.full_name } + end + + def test_load_spec + spec_fetcher do |fetcher| + fetcher.spec 'a', 2 + end + + version = v(2) + @set.add 'a', version, Gem::Platform::RUBY + + loaded = @set.load_spec 'a', version, Gem::Platform::RUBY, nil + + assert_kind_of Gem::Specification, loaded + + assert_equal 'a-2', loaded.full_name + end + + def test_prefetch + assert_respond_to @set, :prefetch + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_lock_specification.rb b/jni/ruby/test/rubygems/test_gem_resolver_lock_specification.rb new file mode 100644 index 0000000..f8a336e --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_lock_specification.rb @@ -0,0 +1,98 @@ +require 'rubygems/test_case' +require 'rubygems/resolver' + +class TestGemResolverLockSpecification < Gem::TestCase + + def setup + super + + @LS = Gem::Resolver::LockSpecification + + @source = Gem::Source.new @gem_repo + @set = Gem::Resolver::LockSet.new [@source] + end + + def test_initialize + spec = @LS.new @set, 'a', v(2), @source, Gem::Platform::RUBY + + assert_equal 'a', spec.name + assert_equal v(2), spec.version + assert_equal Gem::Platform::RUBY, spec.platform + + assert_equal @source, spec.source + end + + def test_add_dependency + l_spec = @LS.new @set, 'a', v(2), @source, Gem::Platform::RUBY + + b_dep = dep('b', '>= 0') + + l_spec.add_dependency b_dep + + assert_equal [b_dep], l_spec.dependencies + end + + def test_install + spec_fetcher do |fetcher| + fetcher.gem 'a', 2 + fetcher.clear + end + + spec = @LS.new @set, 'a', v(2), @source, Gem::Platform::RUBY + + called = false + + spec.install({}) do |installer| + called = installer + end + + refute_nil called + end + + def test_install_installed + spec = @LS.new @set, 'a', v(2), @source, Gem::Platform::RUBY + + FileUtils.touch File.join(@gemhome, 'specifications', spec.spec.spec_name) + + called = false + + spec.install({}) do |installer| + called = installer + end + + assert_nil called + end + + def test_spec + version = v(2) + + l_spec = @LS.new @set, 'a', version, @source, Gem::Platform::RUBY + + b_dep = dep 'b', '>= 0' + c_dep = dep 'c', '~> 1' + + l_spec.add_dependency b_dep + l_spec.add_dependency c_dep + + spec = l_spec.spec + + assert_equal 'a', spec.name + assert_equal version, spec.version + assert_equal Gem::Platform::RUBY, spec.platform + + assert_equal [b_dep, c_dep], l_spec.spec.dependencies + end + + def test_spec_loaded + real_spec = util_spec 'a', 2 + real_spec.activate + + version = v(2) + + l_spec = @LS.new @set, 'a', version, @source, Gem::Platform::RUBY + + assert_same real_spec, l_spec.spec + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_requirement_list.rb b/jni/ruby/test/rubygems/test_gem_resolver_requirement_list.rb new file mode 100644 index 0000000..fd9dccb --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_requirement_list.rb @@ -0,0 +1,20 @@ +require 'rubygems/test_case' + +class TestGemResolverRequirementList < Gem::TestCase + + def setup + super + + @list = Gem::Resolver::RequirementList.new + end + + def test_each + dep = Gem::Dependency.new "a", "= 1" + req = Gem::Resolver::DependencyRequest.new(dep, nil) + @list.add req + + assert_equal [req], @list.each.to_a + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_specification.rb b/jni/ruby/test/rubygems/test_gem_resolver_specification.rb new file mode 100644 index 0000000..e1ec68a --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_specification.rb @@ -0,0 +1,64 @@ +require 'rubygems/test_case' + +class TestGemResolverSpecification < Gem::TestCase + + class TestSpec < Gem::Resolver::Specification + attr_writer :source + attr_reader :spec + + def initialize spec + super() + + @spec = spec + end + end + + def test_install + gemhome = "#{@gemhome}2" + spec_fetcher do |fetcher| + fetcher.gem 'a', 1 + end + + a = util_spec 'a', 1 + + a_spec = TestSpec.new a + a_spec.source = Gem::Source.new @gem_repo + + a_spec.install :install_dir => gemhome + + assert_path_exists File.join gemhome, 'gems', a.full_name + + expected = File.join gemhome, 'specifications', a.spec_name + + assert_equal expected, a_spec.spec.loaded_from + end + + def test_installable_platform_eh + a = util_spec 'a', 1 + + a_spec = TestSpec.new a + + assert a_spec.installable_platform? + + b = util_spec 'a', 1 do |s| + s.platform = Gem::Platform.new %w[cpu other_platform 1] + end + + b_spec = TestSpec.new b + + refute b_spec.installable_platform? + end + + def test_source + a = util_spec 'a', 1 + + source = Gem::Source.new @gem_repo + + a_spec = TestSpec.new a + a_spec.source = source + + assert_equal source, a_spec.source + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_vendor_set.rb b/jni/ruby/test/rubygems/test_gem_resolver_vendor_set.rb new file mode 100644 index 0000000..618e251 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_vendor_set.rb @@ -0,0 +1,83 @@ +require 'rubygems/test_case' + +class TestGemResolverVendorSet < Gem::TestCase + + def setup + super + + @set = Gem::Resolver::VendorSet.new + end + + def test_add_vendor_gem + name, version, directory = vendor_gem + + added = @set.add_vendor_gem name, directory + + spec = @set.load_spec name, version, Gem::Platform::RUBY, nil + + assert_equal spec, added + + assert_equal "#{name}-#{version}", spec.full_name + + assert_equal File.expand_path(directory), spec.full_gem_path + end + + def test_add_vendor_gem_missing + name, _, directory = vendor_gem + + FileUtils.rm_r directory + + e = assert_raises Gem::GemNotFoundException do + @set.add_vendor_gem name, directory + end + + assert_equal "unable to find #{directory}/#{name}.gemspec for gem #{name}", + e.message + end + + def test_find_all + name, version, directory = vendor_gem + + @set.add_vendor_gem name, directory + + dependency = dep 'a', '~> 1' + + req = Gem::Resolver::DependencyRequest.new dependency, nil + + found = @set.find_all req + + spec = @set.load_spec name, version, Gem::Platform::RUBY, nil + + source = Gem::Source::Vendor.new directory + + expected = [ + Gem::Resolver::VendorSpecification.new(@set, spec, source) + ] + + assert_equal expected, found + end + + def test_find_all_prerelease + name, _, directory = vendor_gem 'a', '1.a' + + @set.add_vendor_gem name, directory + + req = Gem::Resolver::DependencyRequest.new dep('a'), nil + + assert_empty @set.find_all req + + req = Gem::Resolver::DependencyRequest.new dep('a', '>= 0.a'), nil + + refute_empty @set.find_all req + end + + def test_load_spec + error = Object.const_defined?(:KeyError) ? KeyError : IndexError + + assert_raises error do + @set.load_spec 'b', v(1), Gem::Platform::RUBY, nil + end + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_resolver_vendor_specification.rb b/jni/ruby/test/rubygems/test_gem_resolver_vendor_specification.rb new file mode 100644 index 0000000..3d94cfe --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_resolver_vendor_specification.rb @@ -0,0 +1,83 @@ +require 'rubygems/test_case' + +class TestGemResolverVendorSpecification < Gem::TestCase + + def setup + super + + @set = Gem::Resolver::VendorSet.new + @spec = Gem::Specification.new 'a', 1 + end + + def test_equals2 + v_spec_a = Gem::Resolver::VendorSpecification.new @set, @spec + + assert_equal v_spec_a, v_spec_a + + spec_b = Gem::Specification.new 'b', 1 + v_spec_b = Gem::Resolver::VendorSpecification.new @set, spec_b + + refute_equal v_spec_a, v_spec_b + + v_set = Gem::Resolver::VendorSet.new + v_spec_s = Gem::Resolver::VendorSpecification.new v_set, @spec + + refute_equal v_spec_a, v_spec_s + + i_set = Gem::Resolver::IndexSet.new + source = Gem::Source.new @gem_repo + i_spec = Gem::Resolver::IndexSpecification.new( + i_set, 'a', v(1), source, Gem::Platform::RUBY) + + refute_equal v_spec_a, i_spec + end + + def test_dependencies + @spec.add_dependency 'b' + @spec.add_dependency 'c' + + v_spec = Gem::Resolver::VendorSpecification.new @set, @spec + + assert_equal [dep('b'), dep('c')], v_spec.dependencies + end + + def test_full_name + v_spec = Gem::Resolver::VendorSpecification.new @set, @spec + + assert_equal 'a-1', v_spec.full_name + end + + def test_install + spec = Gem::Resolver::VendorSpecification.new @set, @spec + + called = :junk + + spec.install({}) do |installer| + called = installer + end + + assert_nil called + end + + def test_name + v_spec = Gem::Resolver::VendorSpecification.new @set, @spec + + assert_equal 'a', v_spec.name + end + + def test_platform + v_spec = Gem::Resolver::VendorSpecification.new @set, @spec + + assert_equal Gem::Platform::RUBY, v_spec.platform + end + + def test_version + spec = Gem::Specification.new 'a', 1 + + v_spec = Gem::Resolver::VendorSpecification.new @set, spec + + assert_equal v(1), v_spec.version + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_security.rb b/jni/ruby/test/rubygems/test_gem_security.rb new file mode 100644 index 0000000..b8747b7 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_security.rb @@ -0,0 +1,306 @@ +require 'rubygems/test_case' +require 'rubygems/security' +require 'rubygems/fix_openssl_warnings' if RUBY_VERSION < "1.9" + +unless defined?(OpenSSL::SSL) then + warn 'Skipping Gem::Security tests. openssl not found.' +end + +class TestGemSecurity < Gem::TestCase + + CHILD_KEY = load_key 'child' + + ALTERNATE_CERT = load_cert 'child' + CHILD_CERT = load_cert 'child' + EXPIRED_CERT = load_cert 'expired' + + def setup + super + + @SEC = Gem::Security + end + + def test_class_create_cert + name = PUBLIC_CERT.subject + key = PRIVATE_KEY + + cert = @SEC.create_cert name, key, 60, Gem::Security::EXTENSIONS, 5 + + assert_kind_of OpenSSL::X509::Certificate, cert + + assert_equal 2, cert.version + assert_equal 5, cert.serial + assert_equal key.public_key.to_pem, cert.public_key.to_pem + assert_in_delta Time.now, cert.not_before, 10 + assert_in_delta Time.now + 60, cert.not_after, 10 + assert_equal name.to_s, cert.subject.to_s + + assert_equal 3, cert.extensions.length, + cert.extensions.map { |e| e.to_a.first } + + constraints = cert.extensions.find { |ext| ext.oid == 'basicConstraints' } + assert_equal 'CA:FALSE', constraints.value + + key_usage = cert.extensions.find { |ext| ext.oid == 'keyUsage' } + assert_equal 'Digital Signature, Key Encipherment, Data Encipherment', + key_usage.value + + key_ident = cert.extensions.find { |ext| ext.oid == 'subjectKeyIdentifier' } + assert_equal 59, key_ident.value.length + assert_equal '5F:43:6E:F6:9A:8E:45:25:E9:22:E3:7D:37:5E:A4:D5:36:02:85:1B', + key_ident.value + + assert_equal '', cert.issuer.to_s + assert_equal name.to_s, cert.subject.to_s + end + + def test_class_create_cert_self_signed + subject = PUBLIC_CERT.subject + + cert = @SEC.create_cert_self_signed subject, PRIVATE_KEY, 60 + + assert_equal '/CN=nobody/DC=example', cert.issuer.to_s + end + + def test_class_create_cert_email + email = 'nobody@example' + name = PUBLIC_CERT.subject + key = PRIVATE_KEY + + cert = @SEC.create_cert_email email, key, 60 + + assert_kind_of OpenSSL::X509::Certificate, cert + + assert_equal 2, cert.version + assert_equal 1, cert.serial + assert_equal key.public_key.to_pem, cert.public_key.to_pem + assert_in_delta Time.now, cert.not_before, 10 + assert_in_delta Time.now + 60, cert.not_after, 10 + assert_equal name.to_s, cert.subject.to_s + assert_equal name.to_s, cert.issuer.to_s + + assert_equal 5, cert.extensions.length, + cert.extensions.map { |e| e.to_a.first } + + constraints = cert.extensions.find { |ext| ext.oid == 'subjectAltName' } + assert_equal 'email:nobody@example', constraints.value + + constraints = cert.extensions.find { |ext| ext.oid == 'basicConstraints' } + assert_equal 'CA:FALSE', constraints.value + + key_usage = cert.extensions.find { |ext| ext.oid == 'keyUsage' } + assert_equal 'Digital Signature, Key Encipherment, Data Encipherment', + key_usage.value + + key_ident = cert.extensions.find { |ext| ext.oid == 'subjectKeyIdentifier' } + assert_equal 59, key_ident.value.length + assert_equal '5F:43:6E:F6:9A:8E:45:25:E9:22:E3:7D:37:5E:A4:D5:36:02:85:1B', + key_ident.value + end + + def test_class_create_key + key = @SEC.create_key 1024 + + assert_kind_of OpenSSL::PKey::RSA, key + end + + def test_class_email_to_name + assert_equal '/CN=nobody/DC=example', + @SEC.email_to_name('nobody@example').to_s + + assert_equal '/CN=nobody/DC=example/DC=com', + @SEC.email_to_name('nobody@example.com').to_s + + assert_equal '/CN=no.body/DC=example', + @SEC.email_to_name('no.body@example').to_s + + assert_equal '/CN=no_body/DC=example', + @SEC.email_to_name('no+body@example').to_s + end + + def test_class_re_sign + re_signed = Gem::Security.re_sign EXPIRED_CERT, PRIVATE_KEY, 60 + + assert_in_delta Time.now, re_signed.not_before, 10 + assert_in_delta Time.now + 60, re_signed.not_after, 10 + assert_equal EXPIRED_CERT.serial + 1, re_signed.serial + + assert re_signed.verify PUBLIC_KEY + end + + def test_class_re_sign_not_self_signed + e = assert_raises Gem::Security::Exception do + Gem::Security.re_sign CHILD_CERT, CHILD_KEY + end + + child_alt_name = CHILD_CERT.extensions.find do |extension| + extension.oid == 'subjectAltName' + end + + assert_equal "#{child_alt_name.value} is not self-signed, contact " + + "#{ALTERNATE_CERT.issuer} to obtain a valid certificate", + e.message + end + + def test_class_re_sign_wrong_key + e = assert_raises Gem::Security::Exception do + Gem::Security.re_sign ALTERNATE_CERT, PRIVATE_KEY + end + + assert_equal "incorrect signing key for re-signing " + + "#{ALTERNATE_CERT.subject}", + e.message + end + + def test_class_reset + trust_dir = @SEC.trust_dir + + @SEC.reset + + refute_equal trust_dir, @SEC.trust_dir + end + + def test_class_sign + issuer = PUBLIC_CERT.subject + signee = OpenSSL::X509::Name.parse "/CN=signee/DC=example" + + key = PRIVATE_KEY + cert = OpenSSL::X509::Certificate.new + cert.subject = signee + + cert.subject = signee + cert.public_key = key.public_key + + signed = @SEC.sign cert, key, PUBLIC_CERT, 60 + + assert_equal key.public_key.to_pem, signed.public_key.to_pem + assert_equal signee.to_s, signed.subject.to_s + assert_equal issuer.to_s, signed.issuer.to_s + + assert_in_delta Time.now, signed.not_before, 10 + assert_in_delta Time.now + 60, signed.not_after, 10 + + assert_equal 4, signed.extensions.length, + signed.extensions.map { |e| e.to_a.first } + + constraints = signed.extensions.find { |ext| ext.oid == 'issuerAltName' } + assert_equal 'email:nobody@example', constraints.value, 'issuerAltName' + + constraints = signed.extensions.find { |ext| ext.oid == 'basicConstraints' } + assert_equal 'CA:FALSE', constraints.value + + key_usage = signed.extensions.find { |ext| ext.oid == 'keyUsage' } + assert_equal 'Digital Signature, Key Encipherment, Data Encipherment', + key_usage.value + + key_ident = + signed.extensions.find { |ext| ext.oid == 'subjectKeyIdentifier' } + assert_equal 59, key_ident.value.length + assert_equal '5F:43:6E:F6:9A:8E:45:25:E9:22:E3:7D:37:5E:A4:D5:36:02:85:1B', + key_ident.value + + assert signed.verify key + end + + def test_class_sign_AltName + issuer = PUBLIC_CERT.subject + signee = OpenSSL::X509::Name.parse "/CN=signee/DC=example" + + cert = @SEC.create_cert_email 'signee@example', PRIVATE_KEY + + signed = @SEC.sign cert, PRIVATE_KEY, PUBLIC_CERT, 60 + + assert_equal PUBLIC_KEY.to_pem, signed.public_key.to_pem + assert_equal signee.to_s, signed.subject.to_s + assert_equal issuer.to_s, signed.issuer.to_s + + assert_in_delta Time.now, signed.not_before, 10 + assert_in_delta Time.now + 60, signed.not_after, 10 + + assert_equal 5, signed.extensions.length, + signed.extensions.map { |e| e.to_a.first } + + constraints = signed.extensions.find { |ext| ext.oid == 'issuerAltName' } + assert_equal 'email:nobody@example', constraints.value, 'issuerAltName' + + constraints = signed.extensions.find { |ext| ext.oid == 'subjectAltName' } + assert_equal 'email:signee@example', constraints.value, 'subjectAltName' + + constraints = signed.extensions.find { |ext| ext.oid == 'basicConstraints' } + assert_equal 'CA:FALSE', constraints.value + + key_usage = signed.extensions.find { |ext| ext.oid == 'keyUsage' } + assert_equal 'Digital Signature, Key Encipherment, Data Encipherment', + key_usage.value + + key_ident = + signed.extensions.find { |ext| ext.oid == 'subjectKeyIdentifier' } + assert_equal 59, key_ident.value.length + assert_equal '5F:43:6E:F6:9A:8E:45:25:E9:22:E3:7D:37:5E:A4:D5:36:02:85:1B', + key_ident.value + + assert signed.verify PUBLIC_KEY + end + + def test_class_trust_dir + trust_dir = @SEC.trust_dir + + expected = File.join Gem.user_home, '.gem/trust' + + assert_equal expected, trust_dir.dir + end + + def test_class_write + key = @SEC.create_key 1024 + + path = File.join @tempdir, 'test-private_key.pem' + + @SEC.write key, path + + assert_path_exists path + + key_from_file = File.read path + + assert_equal key.to_pem, key_from_file + end + + def test_class_write_encrypted + key = @SEC.create_key 1024 + + path = File.join @tempdir, 'test-private_encrypted_key.pem' + + passphrase = 'It should be long.' + + @SEC.write key, path, 0600, passphrase + + assert_path_exists path + + key_from_file = OpenSSL::PKey::RSA.new File.read(path), passphrase + + assert_equal key.to_pem, key_from_file.to_pem + end + + def test_class_write_encrypted_cipher + key = @SEC.create_key 1024 + + path = File.join @tempdir, 'test-private_encrypted__with_non_default_cipher_key.pem' + + passphrase = 'It should be long.' + + cipher = OpenSSL::Cipher.new 'AES-192-CBC' + + @SEC.write key, path, 0600, passphrase, cipher + + assert_path_exists path + + key_file_contents = File.read(path) + + assert key_file_contents.split("\n")[2].match(cipher.name) + + key_from_file = OpenSSL::PKey::RSA.new key_file_contents, passphrase + + assert_equal key.to_pem, key_from_file.to_pem + end + +end if defined?(OpenSSL::SSL) + diff --git a/jni/ruby/test/rubygems/test_gem_security_policy.rb b/jni/ruby/test/rubygems/test_gem_security_policy.rb new file mode 100644 index 0000000..d708306 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_security_policy.rb @@ -0,0 +1,540 @@ +# coding: UTF-8 + +require 'rubygems/test_case' + +unless defined?(OpenSSL::SSL) then + warn 'Skipping Gem::Security::Policy tests. openssl not found.' +end + +class TestGemSecurityPolicy < Gem::TestCase + + ALTERNATE_KEY = load_key 'alternate' + INVALID_KEY = load_key 'invalid' + CHILD_KEY = load_key 'child' + GRANDCHILD_KEY = load_key 'grandchild' + INVALIDCHILD_KEY = load_key 'invalidchild' + + ALTERNATE_CERT = load_cert 'alternate' + CA_CERT = load_cert 'ca' + CHILD_CERT = load_cert 'child' + EXPIRED_CERT = load_cert 'expired' + FUTURE_CERT = load_cert 'future' + GRANDCHILD_CERT = load_cert 'grandchild' + INVALIDCHILD_CERT = load_cert 'invalidchild' + INVALID_ISSUER_CERT = load_cert 'invalid_issuer' + INVALID_SIGNER_CERT = load_cert 'invalid_signer' + WRONG_KEY_CERT = load_cert 'wrong_key' + + def setup + super + + @spec = quick_gem 'a' do |s| + s.description = 'π' + s.files = %w[lib/code.rb] + end + + @sha1 = OpenSSL::Digest::SHA1 + @trust_dir = Gem::Security.trust_dir.dir # HACK use the object + + @no = Gem::Security::NoSecurity + @almost_no = Gem::Security::AlmostNoSecurity + @low = Gem::Security::LowSecurity + @medium = Gem::Security::MediumSecurity + @high = Gem::Security::HighSecurity + + @chain = Gem::Security::Policy.new( + 'Chain', + :verify_data => true, + :verify_signer => true, + :verify_chain => true, + :verify_root => false, + :only_trusted => false, + :only_signed => false + ) + + @root = Gem::Security::Policy.new( + 'Root', + :verify_data => true, + :verify_signer => true, + :verify_chain => true, + :verify_root => true, + :only_trusted => false, + :only_signed => false + ) + end + + def test_check_data + data = digest 'hello' + + signature = sign data + + assert @almost_no.check_data(PUBLIC_KEY, @sha1, signature, data) + end + + def test_check_data_invalid + data = digest 'hello' + + signature = sign data + + invalid = digest 'hello!' + + e = assert_raises Gem::Security::Exception do + @almost_no.check_data PUBLIC_KEY, @sha1, signature, invalid + end + + assert_equal 'invalid signature', e.message + end + + def test_check_chain + chain = [PUBLIC_CERT, CHILD_CERT, GRANDCHILD_CERT] + + assert @chain.check_chain chain, Time.now + end + + def test_check_chain_empty_chain + e = assert_raises Gem::Security::Exception do + @chain.check_chain [], Time.now + end + + assert_equal 'empty signing chain', e.message + end + + def test_check_chain_invalid + chain = [PUBLIC_CERT, CHILD_CERT, INVALIDCHILD_CERT] + + e = assert_raises Gem::Security::Exception do + @chain.check_chain chain, Time.now + end + + assert_equal "invalid signing chain: " + + "certificate #{INVALIDCHILD_CERT.subject} " + + "was not issued by #{CHILD_CERT.subject}", e.message + end + + def test_check_chain_no_chain + e = assert_raises Gem::Security::Exception do + @chain.check_chain nil, Time.now + end + + assert_equal 'missing signing chain', e.message + end + + def test_check_cert + assert @low.check_cert(PUBLIC_CERT, nil, Time.now) + end + + def test_check_cert_expired + e = assert_raises Gem::Security::Exception do + @low.check_cert EXPIRED_CERT, nil, Time.now + end + + assert_equal "certificate #{EXPIRED_CERT.subject} " + + "not valid after #{EXPIRED_CERT.not_after}", + e.message + end + + def test_check_cert_future + e = assert_raises Gem::Security::Exception do + @low.check_cert FUTURE_CERT, nil, Time.now + end + + assert_equal "certificate #{FUTURE_CERT.subject} " + + "not valid before #{FUTURE_CERT.not_before}", + e.message + end + + def test_check_cert_invalid_issuer + e = assert_raises Gem::Security::Exception do + @low.check_cert INVALID_ISSUER_CERT, PUBLIC_CERT, Time.now + end + + assert_equal "certificate #{INVALID_ISSUER_CERT.subject} " + + "was not issued by #{PUBLIC_CERT.subject}", + e.message + end + + def test_check_cert_issuer + assert @low.check_cert(CHILD_CERT, PUBLIC_CERT, Time.now) + end + + def test_check_cert_no_signer + e = assert_raises Gem::Security::Exception do + @high.check_cert(nil, nil, Time.now) + end + + assert_equal 'missing signing certificate', e.message + end + + def test_check_key + assert @almost_no.check_key(PUBLIC_CERT, PRIVATE_KEY) + end + + def test_check_key_no_signer + assert @almost_no.check_key(nil, nil) + + e = assert_raises Gem::Security::Exception do + @high.check_key(nil, nil) + end + + assert_equal 'missing key or signature', e.message + end + + def test_check_key_wrong_key + e = assert_raises Gem::Security::Exception do + @almost_no.check_key(PUBLIC_CERT, ALTERNATE_KEY) + end + + assert_equal "certificate #{PUBLIC_CERT.subject} " + + "does not match the signing key", e.message + end + + def test_check_root + chain = [PUBLIC_CERT, CHILD_CERT, INVALIDCHILD_CERT] + + assert @chain.check_root chain, Time.now + end + + def test_check_root_empty_chain + e = assert_raises Gem::Security::Exception do + @chain.check_root [], Time.now + end + + assert_equal 'missing root certificate', e.message + end + + def test_check_root_invalid_signer + chain = [INVALID_SIGNER_CERT] + + e = assert_raises Gem::Security::Exception do + @chain.check_root chain, Time.now + end + + assert_equal "certificate #{INVALID_SIGNER_CERT.subject} " + + "was not issued by #{INVALID_SIGNER_CERT.issuer}", + e.message + end + + def test_check_root_not_self_signed + chain = [INVALID_ISSUER_CERT] + + e = assert_raises Gem::Security::Exception do + @chain.check_root chain, Time.now + end + + assert_equal "root certificate #{INVALID_ISSUER_CERT.subject} " + + "is not self-signed (issuer #{INVALID_ISSUER_CERT.issuer})", + e.message + end + + def test_check_root_no_chain + e = assert_raises Gem::Security::Exception do + @chain.check_root nil, Time.now + end + + assert_equal 'missing signing chain', e.message + end + + def test_check_trust + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + assert @high.check_trust [PUBLIC_CERT], @sha1, @trust_dir + end + + def test_check_trust_child + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + assert @high.check_trust [PUBLIC_CERT, CHILD_CERT], @sha1, @trust_dir + end + + def test_check_trust_empty_chain + e = assert_raises Gem::Security::Exception do + @chain.check_trust [], @sha1, @trust_dir + end + + assert_equal 'missing root certificate', e.message + end + + def test_check_trust_mismatch + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + e = assert_raises Gem::Security::Exception do + @high.check_trust [WRONG_KEY_CERT], @sha1, @trust_dir + end + + assert_equal "trusted root certificate #{PUBLIC_CERT.subject} checksum " + + "does not match signing root certificate checksum", e.message + end + + def test_check_trust_no_chain + e = assert_raises Gem::Security::Exception do + @chain.check_trust nil, @sha1, @trust_dir + end + + assert_equal 'missing signing chain', e.message + end + + def test_check_trust_no_trust + e = assert_raises Gem::Security::Exception do + @high.check_trust [PUBLIC_CERT], @sha1, @trust_dir + end + + assert_equal "root cert #{PUBLIC_CERT.subject} is not trusted", e.message + end + + def test_check_trust_no_trust_child + e = assert_raises Gem::Security::Exception do + @high.check_trust [PUBLIC_CERT, CHILD_CERT], @sha1, @trust_dir + end + + assert_equal "root cert #{PUBLIC_CERT.subject} is not trusted " + + "(root of signing cert #{CHILD_CERT.subject})", e.message + end + + def test_subject + assert_equal 'email:nobody@example', @no.subject(PUBLIC_CERT) + assert_equal '/C=JP/O=JIN.GR.JP/OU=RRR/CN=CA', @no.subject(CA_CERT) + end + + def test_verify + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + assert @almost_no.verify [PUBLIC_CERT], nil, *dummy_signatures + end + + def test_verify_chain_signatures + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + assert @high.verify [PUBLIC_CERT], nil, *dummy_signatures + end + + def test_verify_chain_key + @almost_no.verify [PUBLIC_CERT], PRIVATE_KEY, *dummy_signatures + end + + def test_verify_no_digests + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + _, signatures = dummy_signatures + + e = assert_raises Gem::Security::Exception do + @almost_no.verify [PUBLIC_CERT], nil, {}, signatures + end + + assert_equal 'no digests provided (probable bug)', e.message + end + + def test_verify_no_digests_no_security + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + _, signatures = dummy_signatures + + e = assert_raises Gem::Security::Exception do + @no.verify [PUBLIC_CERT], nil, {}, signatures + end + + assert_equal 'missing digest for 0', e.message + end + + def test_verify_no_signatures + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + digests, = dummy_signatures + + use_ui @ui do + @no.verify [PUBLIC_CERT], nil, digests, {}, 'some_gem' + end + + assert_match "WARNING: some_gem is not signed\n", @ui.error + + assert_raises Gem::Security::Exception do + @high.verify [PUBLIC_CERT], nil, digests, {} + end + end + + def test_verify_no_signatures_no_digests + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + use_ui @ui do + @no.verify [PUBLIC_CERT], nil, {}, {}, 'some_gem' + end + + assert_empty @ui.output + assert_empty @ui.error + end + + def test_verify_not_enough_signatures + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + digests, signatures = dummy_signatures + + data = digest 'goodbye' + + signatures[1] = PRIVATE_KEY.sign @sha1.new, data.digest + + e = assert_raises Gem::Security::Exception do + @almost_no.verify [PUBLIC_CERT], nil, digests, signatures + end + + assert_equal 'missing digest for 1', e.message + end + + def test_verify_no_trust + digests, signatures = dummy_signatures + + use_ui @ui do + @low.verify [PUBLIC_CERT], nil, digests, signatures, 'some_gem' + end + + assert_equal "WARNING: email:nobody@example is not trusted for some_gem\n", + @ui.error + + assert_raises Gem::Security::Exception do + @medium.verify [PUBLIC_CERT], nil, digests, signatures + end + end + + def test_verify_wrong_digest_type + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + sha512 = OpenSSL::Digest::SHA512 + + data = sha512.new + data << 'hello' + + digests = { 'SHA512' => { 0 => data } } + signature = PRIVATE_KEY.sign sha512.new, data.digest + signatures = { 0 => signature } + + e = assert_raises Gem::Security::Exception do + @almost_no.verify [PUBLIC_CERT], nil, digests, signatures + end + + assert_equal 'no digests provided (probable bug)', e.message + end + + def test_verify_signatures_chain + @spec.cert_chain = [PUBLIC_CERT, CHILD_CERT] + + assert @chain.verify_signatures @spec, *dummy_signatures(CHILD_KEY) + end + + def test_verify_signatures_data + @spec.cert_chain = [PUBLIC_CERT] + + @almost_no.verify_signatures @spec, *dummy_signatures + end + + def test_verify_signatures_root + @spec.cert_chain = [PUBLIC_CERT, CHILD_CERT] + + assert @root.verify_signatures @spec, *dummy_signatures(CHILD_KEY) + end + + def test_verify_signatures_signer + @spec.cert_chain = [PUBLIC_CERT] + + assert @low.verify_signatures @spec, *dummy_signatures + end + + def test_verify_signatures_trust + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + @spec.cert_chain = [PUBLIC_CERT] + + assert @high.verify_signatures @spec, *dummy_signatures + end + + def test_verify_signatures + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + @spec.cert_chain = [PUBLIC_CERT.to_s] + + metadata_gz = Gem.gzip @spec.to_yaml + + package = Gem::Package.new 'nonexistent.gem' + package.checksums['SHA1'] = {} + + s = StringIO.new metadata_gz + def s.full_name() 'metadata.gz' end + + digests = package.digest s + metadata_gz_digest = digests['SHA1']['metadata.gz'] + + signatures = {} + signatures['metadata.gz'] = + PRIVATE_KEY.sign @sha1.new, metadata_gz_digest.digest + + assert @high.verify_signatures @spec, digests, signatures + end + + def test_verify_signatures_missing + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + @spec.cert_chain = [PUBLIC_CERT.to_s] + + metadata_gz = Gem.gzip @spec.to_yaml + + package = Gem::Package.new 'nonexistent.gem' + package.checksums['SHA1'] = {} + + s = StringIO.new metadata_gz + def s.full_name() 'metadata.gz' end + + digests = package.digest s + digests['SHA1']['data.tar.gz'] = OpenSSL::Digest.new 'SHA1', 'hello' + + metadata_gz_digest = digests['SHA1']['metadata.gz'] + + signatures = {} + signatures['metadata.gz'] = + PRIVATE_KEY.sign @sha1.new, metadata_gz_digest.digest + + e = assert_raises Gem::Security::Exception do + @high.verify_signatures @spec, digests, signatures + end + + assert_equal 'missing signature for data.tar.gz', e.message + end + + def test_verify_signatures_none + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + @spec.cert_chain = [PUBLIC_CERT.to_s] + + metadata_gz = Gem.gzip @spec.to_yaml + + package = Gem::Package.new 'nonexistent.gem' + package.checksums['SHA1'] = {} + + s = StringIO.new metadata_gz + def s.full_name() 'metadata.gz' end + + digests = package.digest s + digests['SHA1']['data.tar.gz'] = OpenSSL::Digest.new 'SHA1', 'hello' + + assert_raises Gem::Security::Exception do + @high.verify_signatures @spec, digests, {} + end + end + + def digest data + digester = @sha1.new + digester << data + digester + end + + def sign data, key = PRIVATE_KEY + key.sign @sha1.new, data.digest + end + + def dummy_signatures key = PRIVATE_KEY + data = digest 'hello' + + digests = { 'SHA1' => { 0 => data } } + signatures = { 0 => sign(data, key) } + + return digests, signatures + end + +end if defined?(OpenSSL::SSL) + diff --git a/jni/ruby/test/rubygems/test_gem_security_signer.rb b/jni/ruby/test/rubygems/test_gem_security_signer.rb new file mode 100644 index 0000000..f077a46 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_security_signer.rb @@ -0,0 +1,208 @@ +require 'rubygems/test_case' + +unless defined?(OpenSSL::SSL) then + warn 'Skipping Gem::Security::Signer tests. openssl not found.' +end + +class TestGemSecuritySigner < Gem::TestCase + + ALTERNATE_KEY = load_key 'alternate' + CHILD_KEY = load_key 'child' + GRANDCHILD_KEY = load_key 'grandchild' + + CHILD_CERT = load_cert 'child' + GRANDCHILD_CERT = load_cert 'grandchild' + EXPIRED_CERT = load_cert 'expired' + + def setup + super + + @cert_file = PUBLIC_CERT + end + + def test_initialize + signer = Gem::Security::Signer.new nil, nil + + assert_nil signer.key + assert_nil signer.cert_chain + end + + def test_initialize_cert_chain_empty + signer = Gem::Security::Signer.new PUBLIC_KEY, [] + + assert_empty signer.cert_chain + end + + def test_initialize_cert_chain_mixed + signer = Gem::Security::Signer.new nil, [@cert_file, CHILD_CERT] + + assert_equal [PUBLIC_CERT, CHILD_CERT].map { |c| c.to_pem }, + signer.cert_chain.map { |c| c.to_pem } + end + + def test_initialize_cert_chain_invalid + assert_raises OpenSSL::X509::CertificateError do + Gem::Security::Signer.new nil, ['garbage'] + end + end + + def test_initialize_cert_chain_path + signer = Gem::Security::Signer.new nil, [@cert_file] + + assert_equal [PUBLIC_CERT].map { |c| c.to_pem }, + signer.cert_chain.map { |c| c.to_pem } + end + + def test_initialize_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 + + signer = Gem::Security::Signer.new nil, nil + + assert_equal PRIVATE_KEY.to_pem, signer.key.to_pem + assert_equal [PUBLIC_CERT.to_pem], signer.cert_chain.map { |c| c.to_pem } + end + + def test_initialize_key_path + key_file = PRIVATE_KEY_PATH + + signer = Gem::Security::Signer.new key_file, nil + + assert_equal PRIVATE_KEY.to_s, signer.key.to_s + end + + def test_initialize_encrypted_key_path + key_file = ENCRYPTED_PRIVATE_KEY_PATH + + signer = Gem::Security::Signer.new key_file, nil, PRIVATE_KEY_PASSPHRASE + + assert_equal ENCRYPTED_PRIVATE_KEY.to_s, signer.key.to_s + end + + def test_extract_name + signer = Gem::Security::Signer.new nil, nil + + assert_equal 'child@example', signer.extract_name(CHILD_CERT) + end + + def test_load_cert_chain + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + signer = Gem::Security::Signer.new nil, [] + signer.cert_chain.replace [CHILD_CERT] + + signer.load_cert_chain + + assert_equal [PUBLIC_CERT.to_pem, CHILD_CERT.to_pem], + signer.cert_chain.map { |c| c.to_pem } + end + + def test_load_cert_chain_broken + Gem::Security.trust_dir.trust_cert CHILD_CERT + + signer = Gem::Security::Signer.new nil, [] + signer.cert_chain.replace [GRANDCHILD_CERT] + + signer.load_cert_chain + + assert_equal [CHILD_CERT.to_pem, GRANDCHILD_CERT.to_pem], + signer.cert_chain.map { |c| c.to_pem } + end + + def test_sign + signer = Gem::Security::Signer.new PRIVATE_KEY, [PUBLIC_CERT] + + signature = signer.sign 'hello' + + expected = <<-EXPECTED +pxSf9ScaghbMNmNp8fqSJj7BiIGpbuoOVYCOM3TJNH9STLILA5z3xKp3gM6w +VJ7aGsh9KCP485ftS3J9Kb/lKJsyoSkkRSQ5QG+LnyZwMuWlThPDR5o7q6al +0oxE7vvbbqxFqcT4ojWIkwxJxOluFWmt2D8I6QTX2vLAn09y+Kl66AOrT7R5 +UinbXkz04VwcNvkBqJyko3yWxFKiGNpntZQg4jIw4L+h97EOaZp8H96udzQH +Da3K0YZ6FsqLDFNnWAFhve3kmpE3CludpvDqH0piq0zKqnOiqAcvICIpPaJP +c7NM7KZZjj7G++SXjYTEI1PHSA7aFQ/i/+qSUvx+Pg== + EXPECTED + + assert_equal expected, [signature].pack('m') + end + + def test_sign_expired + signer = Gem::Security::Signer.new PRIVATE_KEY, [EXPIRED_CERT] + + assert_raises Gem::Security::Exception do + signer.sign 'hello' + end + end + + def test_sign_expired_auto_update + FileUtils.mkdir_p File.join(Gem.user_home, '.gem'), :mode => 0700 + + private_key_path = File.join(Gem.user_home, '.gem', 'gem-private_key.pem') + Gem::Security.write PRIVATE_KEY, private_key_path + + cert_path = File.join Gem.user_home, '.gem', 'gem-public_cert.pem' + Gem::Security.write EXPIRED_CERT, cert_path + + signer = Gem::Security::Signer.new PRIVATE_KEY, [EXPIRED_CERT] + + signer.sign 'hello' + + cert = OpenSSL::X509::Certificate.new File.read cert_path + + refute_equal EXPIRED_CERT.to_pem, cert.to_pem + assert_in_delta Time.now, cert.not_before, 10 + + expiry = EXPIRED_CERT.not_after.strftime "%Y%m%d%H%M%S" + + expired_path = + File.join Gem.user_home, '.gem', "gem-public_cert.pem.expired.#{expiry}" + + assert_path_exists expired_path + assert_equal EXPIRED_CERT.to_pem, File.read(expired_path) + end + + def test_sign_expired_auto_update_exists + FileUtils.mkdir_p File.join(Gem.user_home, '.gem'), :mode => 0700 + + expiry = EXPIRED_CERT.not_after.strftime "%Y%m%d%H%M%S" + expired_path = + File.join Gem.user_home, "gem-public_cert.pem.expired.#{expiry}" + + Gem::Security.write EXPIRED_CERT, expired_path + + private_key_path = File.join(Gem.user_home, 'gem-private_key.pem') + Gem::Security.write PRIVATE_KEY, private_key_path + + cert_path = File.join Gem.user_home, 'gem-public_cert.pem' + Gem::Security.write EXPIRED_CERT, cert_path + + signer = Gem::Security::Signer.new PRIVATE_KEY, [EXPIRED_CERT] + + e = assert_raises Gem::Security::Exception do + signer.sign 'hello' + end + + assert_match %r%certificate /CN=nobody/DC=example not valid%, e.message + end + + def test_sign_no_key + signer = Gem::Security::Signer.new nil, nil + + assert_nil signer.sign 'stuff' + end + + def test_sign_wrong_key + signer = Gem::Security::Signer.new ALTERNATE_KEY, [PUBLIC_CERT] + + assert_raises Gem::Security::Exception do + signer.sign 'hello' + end + end + +end if defined?(OpenSSL::SSL) + diff --git a/jni/ruby/test/rubygems/test_gem_security_trust_dir.rb b/jni/ruby/test/rubygems/test_gem_security_trust_dir.rb new file mode 100644 index 0000000..7b0d450 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_security_trust_dir.rb @@ -0,0 +1,98 @@ +require 'rubygems/test_case' + +unless defined?(OpenSSL::SSL) then + warn 'Skipping Gem::Security::TrustDir tests. openssl not found.' +end + +class TestGemSecurityTrustDir < Gem::TestCase + + CHILD_CERT = load_cert 'child' + + def setup + super + + @dest_dir = File.join @tempdir, 'trust' + + @trust_dir = Gem::Security::TrustDir.new @dest_dir + end + + def test_cert_path + digest = OpenSSL::Digest::SHA1.hexdigest PUBLIC_CERT.subject.to_s + + expected = File.join @dest_dir, "cert-#{digest}.pem" + + assert_equal expected, @trust_dir.cert_path(PUBLIC_CERT) + end + + def test_issuer_of + assert_nil @trust_dir.issuer_of(CHILD_CERT) + + @trust_dir.trust_cert PUBLIC_CERT + + assert_equal PUBLIC_CERT.to_pem, @trust_dir.issuer_of(CHILD_CERT).to_pem + end + + def test_load_certificate + @trust_dir.trust_cert PUBLIC_CERT + + path = @trust_dir.cert_path PUBLIC_CERT + + assert_equal PUBLIC_CERT.to_pem, @trust_dir.load_certificate(path).to_pem + end + + def test_name_path + digest = OpenSSL::Digest::SHA1.hexdigest PUBLIC_CERT.subject.to_s + + expected = File.join @dest_dir, "cert-#{digest}.pem" + + assert_equal expected, @trust_dir.name_path(PUBLIC_CERT.subject) + end + + def test_trust_cert + @trust_dir.trust_cert PUBLIC_CERT + + trusted = @trust_dir.cert_path PUBLIC_CERT + + assert_path_exists trusted + + mask = 0100600 & (~File.umask) + + assert_equal mask, File.stat(trusted).mode unless win_platform? + + assert_equal PUBLIC_CERT.to_pem, File.read(trusted) + end + + def test_verify + refute_path_exists @dest_dir + + @trust_dir.verify + + assert_path_exists @dest_dir + + mask = 040700 & (~File.umask) + + assert_equal mask, File.stat(@dest_dir).mode unless win_platform? + end + + def test_verify_file + FileUtils.touch @dest_dir + + e = assert_raises Gem::Security::Exception do + @trust_dir.verify + end + + assert_equal "trust directory #{@dest_dir} is not a directory", e.message + end + + def test_verify_wrong_permissions + FileUtils.mkdir_p @dest_dir, :mode => 0777 + + @trust_dir.verify + + mask = 040700 & (~File.umask) + + assert_equal mask, File.stat(@dest_dir).mode unless win_platform? + end + +end if defined?(OpenSSL::SSL) + diff --git a/jni/ruby/test/rubygems/test_gem_server.rb b/jni/ruby/test/rubygems/test_gem_server.rb new file mode 100644 index 0000000..9640486 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_server.rb @@ -0,0 +1,404 @@ +require 'rubygems/test_case' +require 'rubygems/server' +require 'stringio' + +class Gem::Server + attr_reader :server +end + +class TestGemServer < Gem::TestCase + def setup + super + + @a1 = quick_gem 'a', '1' + @a2 = quick_gem 'a', '2' + @a3_p = quick_gem 'a', '3.a' + + @server = Gem::Server.new Gem.dir, process_based_port, false + @req = WEBrick::HTTPRequest.new :Logger => nil + @res = WEBrick::HTTPResponse.new :HTTPVersion => '1.0' + end + + def test_doc_root_3 + orig_rdoc_version = Gem::RDoc.rdoc_version + Gem::RDoc.instance_variable_set :@rdoc_version, Gem::Version.new('3.12') + + assert_equal '/doc_root/X-1/rdoc/index.html', @server.doc_root('X-1') + + ensure + Gem::RDoc.instance_variable_set :@rdoc_version, orig_rdoc_version + end + + def test_doc_root_4 + orig_rdoc_version = Gem::RDoc.rdoc_version + Gem::RDoc.instance_variable_set :@rdoc_version, Gem::Version.new('4.0') + + assert_equal '/doc_root/X-1/', @server.doc_root('X-1') + + ensure + Gem::RDoc.instance_variable_set :@rdoc_version, orig_rdoc_version + end + + def test_have_rdoc_4_plus_eh + orig_rdoc_version = Gem::RDoc.rdoc_version + Gem::RDoc.instance_variable_set(:@rdoc_version, Gem::Version.new('4.0')) + + server = Gem::Server.new Gem.dir, 0, false + assert server.have_rdoc_4_plus? + + Gem::RDoc.instance_variable_set :@rdoc_version, Gem::Version.new('3.12') + + server = Gem::Server.new Gem.dir, 0, false + refute server.have_rdoc_4_plus? + + Gem::RDoc.instance_variable_set(:@rdoc_version, + Gem::Version.new('4.0.0.preview2')) + + server = Gem::Server.new Gem.dir, 0, false + assert server.have_rdoc_4_plus? + ensure + Gem::RDoc.instance_variable_set :@rdoc_version, orig_rdoc_version + end + + def test_spec_dirs + s = Gem::Server.new Gem.dir, process_based_port, false + + assert_equal [File.join(Gem.dir, 'specifications')], s.spec_dirs + + s = Gem::Server.new [Gem.dir, Gem.dir], process_based_port, false + + assert_equal [File.join(Gem.dir, 'specifications'), + File.join(Gem.dir, 'specifications')], s.spec_dirs + end + + def test_latest_specs + data = StringIO.new "GET /latest_specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n" + @req.parse data + + Gem::Deprecate.skip_during do + @server.latest_specs @req, @res + end + + assert_equal 200, @res.status, @res.body + assert_match %r| \d\d:\d\d:\d\d |, @res['date'] + assert_equal 'application/octet-stream', @res['content-type'] + assert_equal [['a', Gem::Version.new(2), Gem::Platform::RUBY]], + Marshal.load(@res.body) + end + + def test_latest_specs_gemdirs + data = StringIO.new "GET /latest_specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n" + dir = "#{@gemhome}2" + + spec = util_spec 'z', 9 + + specs_dir = File.join dir, 'specifications' + FileUtils.mkdir_p specs_dir + + open File.join(specs_dir, spec.spec_name), 'w' do |io| + io.write spec.to_ruby + end + + server = Gem::Server.new dir, process_based_port, false + + @req.parse data + + server.latest_specs @req, @res + + assert_equal 200, @res.status + + assert_equal [['z', v(9), Gem::Platform::RUBY]], Marshal.load(@res.body) + end + + def test_latest_specs_gz + data = StringIO.new "GET /latest_specs.#{Gem.marshal_version}.gz HTTP/1.0\r\n\r\n" + @req.parse data + + Gem::Deprecate.skip_during do + @server.latest_specs @req, @res + end + + assert_equal 200, @res.status, @res.body + assert_match %r| \d\d:\d\d:\d\d |, @res['date'] + assert_equal 'application/x-gzip', @res['content-type'] + assert_equal [['a', Gem::Version.new(2), Gem::Platform::RUBY]], + Marshal.load(Gem.gunzip(@res.body)) + end + + def test_listen + util_listen + + capture_io do + @server.listen + end + + assert_equal 1, @server.server.listeners.length + end + + def test_listen_addresses + util_listen + + capture_io do + @server.listen %w[a b] + end + + assert_equal 2, @server.server.listeners.length + end + + def test_prerelease_specs + data = StringIO.new "GET /prerelease_specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n" + @req.parse data + + Gem::Deprecate.skip_during do + @server.prerelease_specs @req, @res + end + + assert_equal 200, @res.status, @res.body + assert_match %r| \d\d:\d\d:\d\d |, @res['date'] + assert_equal 'application/octet-stream', @res['content-type'] + assert_equal [['a', v('3.a'), Gem::Platform::RUBY]], + Marshal.load(@res.body) + end + + def test_prerelease_specs_gz + data = StringIO.new "GET /prerelease_specs.#{Gem.marshal_version}.gz HTTP/1.0\r\n\r\n" + @req.parse data + + Gem::Deprecate.skip_during do + @server.prerelease_specs @req, @res + end + + assert_equal 200, @res.status, @res.body + assert_match %r| \d\d:\d\d:\d\d |, @res['date'] + assert_equal 'application/x-gzip', @res['content-type'] + assert_equal [['a', v('3.a'), Gem::Platform::RUBY]], + Marshal.load(Gem.gunzip(@res.body)) + end + + def test_quick_gemdirs + data = StringIO.new "GET /quick/Marshal.4.8/z-9.gemspec.rz HTTP/1.0\r\n\r\n" + dir = "#{@gemhome}2" + + server = Gem::Server.new dir, process_based_port, false + + @req.parse data + + server.quick @req, @res + + assert_equal 404, @res.status + + spec = util_spec 'z', 9 + + specs_dir = File.join dir, 'specifications' + + FileUtils.mkdir_p specs_dir + + open File.join(specs_dir, spec.spec_name), 'w' do |io| + io.write spec.to_ruby + end + + data.rewind + + req = WEBrick::HTTPRequest.new :Logger => nil + res = WEBrick::HTTPResponse.new :HTTPVersion => '1.0' + req.parse data + + server.quick req, res + + assert_equal 200, res.status + end + + def test_quick_missing + data = StringIO.new "GET /quick/Marshal.4.8/z-9.gemspec.rz HTTP/1.0\r\n\r\n" + @req.parse data + + @server.quick @req, @res + + assert_equal 404, @res.status, @res.body + assert_match %r| \d\d:\d\d:\d\d |, @res['date'] + assert_equal 'text/plain', @res['content-type'] + assert_equal 'No gems found matching "z" "9" nil', @res.body + assert_equal 404, @res.status + end + + def test_quick_marshal_a_1_gemspec_rz + data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-1.gemspec.rz HTTP/1.0\r\n\r\n" + @req.parse data + + @server.quick @req, @res + + assert_equal 200, @res.status, @res.body + assert @res['date'] + assert_equal 'application/x-deflate', @res['content-type'] + + spec = Marshal.load Gem.inflate(@res.body) + assert_equal 'a', spec.name + assert_equal Gem::Version.new(1), spec.version + end + + def test_quick_marshal_a_1_mswin32_gemspec_rz + quick_gem 'a', '1' do |s| s.platform = Gem::Platform.local end + + data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-1-#{Gem::Platform.local}.gemspec.rz HTTP/1.0\r\n\r\n" + @req.parse data + + @server.quick @req, @res + + assert_equal 200, @res.status, @res.body + assert @res['date'] + assert_equal 'application/x-deflate', @res['content-type'] + + spec = Marshal.load Gem.inflate(@res.body) + assert_equal 'a', spec.name + assert_equal Gem::Version.new(1), spec.version + assert_equal Gem::Platform.local, spec.platform + end + + def test_quick_marshal_a_3_a_gemspec_rz + data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-3.a.gemspec.rz HTTP/1.0\r\n\r\n" + @req.parse data + + @server.quick @req, @res + + assert_equal 200, @res.status, @res.body + assert @res['date'] + assert_equal 'application/x-deflate', @res['content-type'] + + spec = Marshal.load Gem.inflate(@res.body) + assert_equal 'a', spec.name + assert_equal v('3.a'), spec.version + end + + def test_quick_marshal_a_b_3_a_gemspec_rz + quick_gem 'a-b', '3.a' + + data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-b-3.a.gemspec.rz HTTP/1.0\r\n\r\n" + @req.parse data + + @server.quick @req, @res + + assert_equal 200, @res.status, @res.body + assert @res['date'] + assert_equal 'application/x-deflate', @res['content-type'] + + spec = Marshal.load Gem.inflate(@res.body) + assert_equal 'a-b', spec.name + assert_equal v('3.a'), spec.version + end + + def test_rdoc + data = StringIO.new "GET /rdoc?q=a HTTP/1.0\r\n\r\n" + @req.parse data + + @server.rdoc @req, @res + + assert_equal 200, @res.status, @res.body + assert_match %r|No documentation found|, @res.body + assert_equal 'text/html', @res['content-type'] + end + + def test_root + data = StringIO.new "GET / HTTP/1.0\r\n\r\n" + @req.parse data + + @server.root @req, @res + + assert_equal 200, @res.status, @res.body + assert_match %r| \d\d:\d\d:\d\d |, @res['date'] + assert_equal 'text/html', @res['content-type'] + end + + def test_root_gemdirs + data = StringIO.new "GET / HTTP/1.0\r\n\r\n" + dir = "#{@gemhome}2" + + spec = util_spec 'z', 9 + + specs_dir = File.join dir, 'specifications' + FileUtils.mkdir_p specs_dir + + open File.join(specs_dir, spec.spec_name), 'w' do |io| + io.write spec.to_ruby + end + + server = Gem::Server.new dir, process_based_port, false + + @req.parse data + + server.root @req, @res + + assert_equal 200, @res.status + assert_match 'z 9', @res.body + end + + def test_specs + data = StringIO.new "GET /specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n" + @req.parse data + + @server.specs @req, @res + + assert_equal 200, @res.status, @res.body + assert_match %r| \d\d:\d\d:\d\d |, @res['date'] + assert_equal 'application/octet-stream', @res['content-type'] + + assert_equal [['a', Gem::Version.new(1), Gem::Platform::RUBY], + ['a', Gem::Version.new(2), Gem::Platform::RUBY], + ['a', v('3.a'), Gem::Platform::RUBY]], + Marshal.load(@res.body) + end + + def test_specs_gemdirs + data = StringIO.new "GET /specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n" + dir = "#{@gemhome}2" + + spec = util_spec 'z', 9 + + specs_dir = File.join dir, 'specifications' + FileUtils.mkdir_p specs_dir + + open File.join(specs_dir, spec.spec_name), 'w' do |io| + io.write spec.to_ruby + end + + server = Gem::Server.new dir, process_based_port, false + + @req.parse data + + server.specs @req, @res + + assert_equal 200, @res.status + + assert_equal [['z', v(9), Gem::Platform::RUBY]], Marshal.load(@res.body) + end + + def test_specs_gz + data = StringIO.new "GET /specs.#{Gem.marshal_version}.gz HTTP/1.0\r\n\r\n" + @req.parse data + + @server.specs @req, @res + + assert_equal 200, @res.status, @res.body + assert_match %r| \d\d:\d\d:\d\d |, @res['date'] + assert_equal 'application/x-gzip', @res['content-type'] + + assert_equal [['a', Gem::Version.new(1), Gem::Platform::RUBY], + ['a', Gem::Version.new(2), Gem::Platform::RUBY], + ['a', v('3.a'), Gem::Platform::RUBY]], + Marshal.load(Gem.gunzip(@res.body)) + end + + def util_listen + webrick = Object.new + webrick.instance_variable_set :@listeners, [] + def webrick.listeners() @listeners end + def webrick.listen(host, port) + socket = Object.new + socket.instance_variable_set :@host, host + socket.instance_variable_set :@port, port + def socket.addr() [nil, @port, @host] end + @listeners << socket + end + + @server.instance_variable_set :@server, webrick + end +end diff --git a/jni/ruby/test/rubygems/test_gem_silent_ui.rb b/jni/ruby/test/rubygems/test_gem_silent_ui.rb new file mode 100644 index 0000000..01ff79d --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_silent_ui.rb @@ -0,0 +1,116 @@ +require 'rubygems/test_case' +require 'rubygems/user_interaction' +require 'timeout' + +class TestGemSilentUI < Gem::TestCase + + def setup + super + @sui = Gem::SilentUI.new + end + + def teardown + @sui.close + super + end + + def test_ask + value = nil + out, err = capture_io do + use_ui @sui do + value = @sui.ask 'Problem?' + end + end + + assert_empty out, 'No output' + assert_empty err, 'No output' + + assert_nil value, 'No value' + end + + def test_ask_for_password + value = nil + out, err = capture_io do + use_ui @sui do + value = @sui.ask_for_password 'Problem?' + end + end + + assert_empty out, 'No output' + assert_empty err, 'No output' + + assert_nil value, 'No value' + end + + def test_ask_yes_no + value = nil + out, err = capture_io do + use_ui @sui do + assert_raises(Gem::OperationNotSupportedError) do + @sui.ask_yes_no 'Problem?' + end + end + end + + assert_empty out, 'No output' + assert_empty err, 'No output' + + out, err = capture_io do + use_ui @sui do + value = @sui.ask_yes_no 'Problem?', true + end + end + + assert_empty out, 'No output' + assert_empty err, 'No output' + + assert value, 'Value is true' + + out, err = capture_io do + use_ui @sui do + value = @sui.ask_yes_no 'Problem?', false + end + end + + assert_empty out, 'No output' + assert_empty err, 'No output' + + assert_equal value, false, 'Value is false' + end + + def test_choose_from_list + value = nil + out, err = capture_io do + use_ui @sui do + value = @sui.choose_from_list 'Problem?', %w[yes no] + end + end + + assert_empty out, 'No output' + assert_empty err, 'No output' + + assert_equal [nil, nil], value, 'Value is nil!' + end + + def test_progress_reporter + out, err = capture_io do + use_ui @sui do + @sui.progress_reporter 10, 'hi' + end + end + + assert_empty out, 'No output' + assert_empty err, 'No output' + end + + def test_download_reporter + out, err = capture_io do + use_ui @sui do + @sui.download_reporter.fetch 'a.gem', 1024 + end + end + + assert_empty out, 'No output' + assert_empty err, 'No output' + end +end diff --git a/jni/ruby/test/rubygems/test_gem_source.rb b/jni/ruby/test/rubygems/test_gem_source.rb new file mode 100644 index 0000000..7d23eee --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_source.rb @@ -0,0 +1,241 @@ +require 'rubygems/test_case' +require 'rubygems/source' +require 'rubygems/indexer' + +class TestGemSource < Gem::TestCase + + def tuple(*args) + Gem::NameTuple.new(*args) + end + + def setup + super + + @specs = spec_fetcher do |fetcher| + fetcher.spec 'a', '1.a' + fetcher.gem 'a', 1 + fetcher.spec 'a', 2 + fetcher.spec 'b', 2 + end + + @source = Gem::Source.new(@gem_repo) + end + + def test_initialize_invalid_uri + assert_raises URI::InvalidURIError do + Gem::Source.new 'git@example:a.git' + end + end + + def test_initialize_git + repository = 'git@example:a.git' + + source = Gem::Source::Git.new 'a', repository, 'master', false + + assert_equal repository, source.uri + end + + def test_api_uri + assert_equal @source.api_uri, @source.uri + end + + def test_api_uri_resolved_from_remote_fetcher + uri = URI.parse "http://gem.example/foo" + @fetcher.api_endpoints[uri] = URI.parse "http://api.blah" + + src = Gem::Source.new uri + assert_equal URI.parse("http://api.blah"), src.api_uri + end + + def test_cache_dir_escapes_windows_paths + uri = URI.parse("file:///C:/WINDOWS/Temp/gem_repo") + root = Gem.spec_cache_dir + cache_dir = @source.cache_dir(uri).gsub(root, '') + assert cache_dir !~ /:/, "#{cache_dir} should not contain a :" + end + + def test_dependency_resolver_set_bundler_api + response = Net::HTTPResponse.new '1.1', 200, 'OK' + response.uri = URI('http://example') if response.respond_to? :uri + + @fetcher.data["#{@gem_repo}api/v1/dependencies"] = response + + set = @source.dependency_resolver_set + + assert_kind_of Gem::Resolver::APISet, set + end + + def test_dependency_resolver_set_file_uri + skip 'install builder gem' unless defined? Builder::XChar + + Gem::Indexer.new(@tempdir).generate_index + + source = Gem::Source.new "file://#{@tempdir}/" + + set = source.dependency_resolver_set + + assert_kind_of Gem::Resolver::IndexSet, set + end + + def test_dependency_resolver_set_marshal_api + set = @source.dependency_resolver_set + + assert_kind_of Gem::Resolver::IndexSet, set + end + + def test_fetch_spec + a1 = @specs['a-1'] + + spec_uri = "#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{a1.spec_name}" + + spec = @source.fetch_spec tuple('a', Gem::Version.new(1), 'ruby') + assert_equal a1.full_name, spec.full_name + + cache_dir = @source.cache_dir URI.parse(spec_uri) + + cache_file = File.join cache_dir, a1.spec_name + + assert File.exist?(cache_file) + end + + def test_fetch_spec_cached + a1 = @specs['a-1'] + + spec_uri = "#{@gem_repo}/#{Gem::MARSHAL_SPEC_DIR}#{a1.spec_name}" + @fetcher.data["#{spec_uri}.rz"] = nil + + cache_dir = @source.cache_dir URI.parse(spec_uri) + FileUtils.mkdir_p cache_dir + + cache_file = File.join cache_dir, a1.spec_name + + open cache_file, 'wb' do |io| + Marshal.dump a1, io + end + + spec = @source.fetch_spec tuple('a', Gem::Version.new(1), 'ruby') + assert_equal a1.full_name, spec.full_name + end + + def test_fetch_spec_platform + specs = spec_fetcher do |fetcher| + fetcher.legacy_platform + end + + spec = @source.fetch_spec tuple('pl', Gem::Version.new(1), 'i386-linux') + + assert_equal specs['pl-1-x86-linux'].full_name, spec.full_name + end + + def test_fetch_spec_platform_ruby + spec = @source.fetch_spec tuple('a', Gem::Version.new(1), nil) + assert_equal @specs['a-1'].full_name, spec.full_name + + spec = @source.fetch_spec tuple('a', Gem::Version.new(1), '') + assert_equal @specs['a-1'].full_name, spec.full_name + end + + def test_load_specs + released = @source.load_specs(:released).map { |spec| spec.full_name } + assert_equal %W[a-2 a-1 b-2], released + + cache_dir = File.join Gem.spec_cache_dir, 'gems.example.com%80' + assert File.exist?(cache_dir), "#{cache_dir} does not exist" + + cache_file = File.join cache_dir, "specs.#{Gem.marshal_version}" + assert File.exist?(cache_file) + end + + def test_load_specs_cached + latest_specs = @source.load_specs :latest + + # Make sure the cached version is actually different: + latest_specs << Gem::NameTuple.new('cached', Gem::Version.new('1.0.0'), 'ruby') + + @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] = nil + @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}"] = + ' ' * Marshal.dump(latest_specs).length + + cache_dir = File.join Gem.spec_cache_dir, 'gems.example.com%80' + + FileUtils.mkdir_p cache_dir + + cache_file = File.join cache_dir, "latest_specs.#{Gem.marshal_version}" + + open cache_file, 'wb' do |io| + Marshal.dump latest_specs, io + end + + cached_specs = @source.load_specs :latest + + assert_equal latest_specs, cached_specs + end + + def test_load_specs_cached_empty + latest_specs = @source.load_specs :latest + + # Make sure the cached version is actually different: + latest_specs << Gem::NameTuple.new('fixed', Gem::Version.new('1.0.0'), 'ruby') + # Setup valid data on the 'remote' + @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] = + util_gzip(Marshal.dump(latest_specs)) + + cache_dir = File.join Gem.spec_cache_dir, 'gems.example.com%80' + + FileUtils.mkdir_p cache_dir + + cache_file = File.join cache_dir, "latest_specs.#{Gem.marshal_version}" + + open cache_file, 'wb' do |io| + # Setup invalid data in the cache: + io.write Marshal.dump(latest_specs)[0, 10] + end + + fixed_specs = @source.load_specs :latest + + assert_equal latest_specs, fixed_specs + end + + def test_load_specs_from_unavailable_uri + src = Gem::Source.new("http://not-there.nothing") + + assert_raises Gem::RemoteFetcher::FetchError do + src.load_specs :latest + end + end + + def test_spaceship + remote = @source + specific = Gem::Source::SpecificFile.new @specs['a-1'].cache_file + installed = Gem::Source::Installed.new + local = Gem::Source::Local.new + + assert_equal( 0, remote. <=>(remote), 'remote <=> remote') + + assert_equal(-1, remote. <=>(specific), 'remote <=> specific') + assert_equal( 1, specific. <=>(remote), 'specific <=> remote') + + assert_equal(-1, remote. <=>(local), 'remote <=> local') + assert_equal( 1, local. <=>(remote), 'local <=> remote') + + assert_equal(-1, remote. <=>(installed), 'remote <=> installed') + assert_equal( 1, installed.<=>(remote), 'installed <=> remote') + + no_uri = @source.dup + no_uri.instance_variable_set :@uri, nil + + assert_equal(-1, remote. <=>(no_uri), 'remote <=> no_uri') + end + + def test_update_cache_eh + assert @source.update_cache? + end + + def test_update_cache_eh_home_nonexistent + FileUtils.rmdir Gem.user_home + + refute @source.update_cache? + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_source_fetch_problem.rb b/jni/ruby/test/rubygems/test_gem_source_fetch_problem.rb new file mode 100644 index 0000000..e8d4785 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_source_fetch_problem.rb @@ -0,0 +1,19 @@ +require 'rubygems/test_case' + +class TestGemSourceFetchProblem < Gem::TestCase + + def test_exception + source = Gem::Source.new @gem_repo + error = RuntimeError.new 'test' + + sf = Gem::SourceFetchProblem.new source, error + + e = assert_raises RuntimeError do + raise sf + end + + assert_equal 'test', e.message + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_source_git.rb b/jni/ruby/test/rubygems/test_gem_source_git.rb new file mode 100644 index 0000000..7e5bcca --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_source_git.rb @@ -0,0 +1,308 @@ +require 'rubygems/test_case' +require 'rubygems/source' + +class TestGemSourceGit < Gem::TestCase + + def setup + super + + @name, @version, @repository, @head = git_gem + + @hash = Digest::SHA1.hexdigest @repository + + @source = Gem::Source::Git.new @name, @repository, 'master', false + end + + def test_base_dir + assert_equal File.join(Gem.dir, 'bundler'), @source.base_dir + + @source.root_dir = "#{@gemhome}2" + + assert_equal File.join("#{@gemhome}2", 'bundler'), @source.base_dir + end + + def test_checkout + @source.checkout + + assert_path_exists File.join @source.install_dir, 'a.gemspec' + end + + def test_checkout_master + Dir.chdir @repository do + system @git, 'checkout', '-q', '-b', 'other' + system @git, 'mv', 'a.gemspec', 'b.gemspec' + system @git, 'commit', '-q', '-a', '-m', 'rename gemspec' + system @git, 'checkout', '-q', 'master' + end + + @source = Gem::Source::Git.new @name, @repository, 'other', false + + @source.checkout + + assert_path_exists File.join @source.install_dir, 'b.gemspec' + end + + def test_checkout_local + @source.remote = false + + @source.checkout + + install_dir = File.join Gem.dir, 'bundler', 'gems', "a-#{@head[0..11]}" + + refute_path_exists File.join install_dir, 'a.gemspec' + end + + def test_checkout_local_cached + @source.cache + + @source.remote = false + + @source.checkout + + assert_path_exists File.join @source.install_dir, 'a.gemspec' + end + + def test_checkout_submodules + source = Gem::Source::Git.new @name, @repository, 'master', true + + git_gem 'b' + + Dir.chdir 'git/a' do + Gem::Util.silent_system @git, 'submodule', '--quiet', + 'add', File.expand_path('../b'), 'b' + system @git, 'commit', '--quiet', '-m', 'add submodule b' + end + + source.checkout + + assert_path_exists File.join source.install_dir, 'a.gemspec' + assert_path_exists File.join source.install_dir, 'b/b.gemspec' + end + + def test_cache + assert @source.cache + + assert_path_exists @source.repo_cache_dir + + Dir.chdir @source.repo_cache_dir do + assert_equal @head, Gem::Util.popen(@git, 'rev-parse', 'master').strip + end + end + + def test_cache_local + @source.remote = false + + @source.cache + + refute_path_exists @source.repo_cache_dir + end + + def test_dir_shortref + @source.cache + + assert_equal @head[0..11], @source.dir_shortref + end + + def test_download + refute @source.download nil, nil + end + + def test_equals2 + assert_equal @source, @source + + assert_equal @source, @source.dup + + source = + Gem::Source::Git.new @source.name, @source.repository, 'other', false + + refute_equal @source, source + + source = + Gem::Source::Git.new @source.name, 'repo/other', @source.reference, false + + refute_equal @source, source + + source = + Gem::Source::Git.new 'b', @source.repository, @source.reference, false + + refute_equal @source, source + + source = + Gem::Source::Git.new @source.name, @source.repository, @source.reference, + true + + refute_equal @source, source + end + + def test_install_dir + @source.cache + + expected = File.join Gem.dir, 'bundler', 'gems', "a-#{@head[0..11]}" + + assert_equal expected, @source.install_dir + end + + def test_install_dir_local + @source.remote = false + + assert_nil @source.install_dir + end + + def test_repo_cache_dir + expected = + File.join Gem.dir, 'cache', 'bundler', 'git', "a-#{@hash}" + + assert_equal expected, @source.repo_cache_dir + + @source.root_dir = "#{@gemhome}2" + + expected = + File.join "#{@gemhome}2", 'cache', 'bundler', 'git', "a-#{@hash}" + + assert_equal expected, @source.repo_cache_dir + end + + def test_rev_parse + @source.cache + + assert_equal @head, @source.rev_parse + + Dir.chdir @repository do + system @git, 'checkout', '--quiet', '-b', 'other' + end + + master_head = @head + + git_gem 'a', 2 + + source = Gem::Source::Git.new @name, @repository, 'other', false + + source.cache + + refute_equal master_head, source.rev_parse + + source = Gem::Source::Git.new @name, @repository, 'nonexistent', false + + source.cache + + e = assert_raises Gem::Exception do + capture_subprocess_io {source.rev_parse} + end + + assert_equal "unable to find reference nonexistent in #{@repository}", + e.message + end + + def test_root_dir + assert_equal Gem.dir, @source.root_dir + + @source.root_dir = "#{@gemhome}2" + + assert_equal "#{@gemhome}2", @source.root_dir + end + + def test_spaceship + git = Gem::Source::Git.new 'a', 'git/a', 'master', false + remote = Gem::Source.new @gem_repo + installed = Gem::Source::Installed.new + vendor = Gem::Source::Vendor.new 'vendor/foo' + + assert_equal( 0, git. <=>(git), 'git <=> git') + + assert_equal( 1, git. <=>(remote), 'git <=> remote') + assert_equal(-1, remote. <=>(git), 'remote <=> git') + + assert_equal( 1, git. <=>(installed), 'git <=> installed') + assert_equal(-1, installed.<=>(git), 'installed <=> git') + + assert_equal(-1, git. <=>(vendor), 'git <=> vendor') + assert_equal( 1, vendor. <=>(git), 'vendor <=> git') + end + + def test_specs + source = Gem::Source::Git.new @name, @repository, 'master', true + + Dir.chdir 'git/a' do + FileUtils.mkdir 'b' + + Dir.chdir 'b' do + b = Gem::Specification.new 'b', 1 + + open 'b.gemspec', 'w' do |io| + io.write b.to_ruby + end + + system @git, 'add', 'b.gemspec' + system @git, 'commit', '--quiet', '-m', 'add b/b.gemspec' + end + + FileUtils.touch 'c.gemspec' + + system @git, 'add', 'c.gemspec' + system @git, 'commit', '--quiet', '-m', 'add c.gemspec' + end + + specs = nil + + capture_io do + specs = source.specs + end + + assert_equal %w[a-1 b-1], specs.map { |spec| spec.full_name } + + a_spec = specs.shift + + base_dir = File.dirname File.dirname source.install_dir + + assert_equal source.install_dir, a_spec.full_gem_path + assert_equal File.join(source.install_dir, 'a.gemspec'), a_spec.loaded_from + assert_equal base_dir, a_spec.base_dir + + extension_dir = + File.join Gem.dir, 'bundler', 'extensions', + Gem::Platform.local.to_s, Gem.extension_api_version, + "a-#{source.dir_shortref}" + + assert_equal extension_dir, a_spec.extension_dir + + b_spec = specs.shift + + assert_equal File.join(source.install_dir, 'b'), b_spec.full_gem_path + assert_equal File.join(source.install_dir, 'b', 'b.gemspec'), + b_spec.loaded_from + assert_equal base_dir, b_spec.base_dir + + assert_equal extension_dir, b_spec.extension_dir + end + + def test_specs_local + source = Gem::Source::Git.new @name, @repository, 'master', true + source.remote = false + + capture_io do + assert_empty source.specs + end + end + + def test_uri + assert_equal URI(@repository), @source.uri + end + + def test_uri_hash + assert_equal @hash, @source.uri_hash + + source = + Gem::Source::Git.new 'a', 'http://git@example/repo.git', 'master', false + + assert_equal '291c4caac7feba8bb64c297987028acb3dde6cfe', + source.uri_hash + + source = + Gem::Source::Git.new 'a', 'HTTP://git@EXAMPLE/repo.git', 'master', false + + assert_equal '291c4caac7feba8bb64c297987028acb3dde6cfe', + source.uri_hash + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_source_installed.rb b/jni/ruby/test/rubygems/test_gem_source_installed.rb new file mode 100644 index 0000000..9eaddf7 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_source_installed.rb @@ -0,0 +1,36 @@ +require 'rubygems/test_case' +require 'rubygems/source' + +class TestGemSourceInstalled < Gem::TestCase + + def test_spaceship + a1 = quick_gem 'a', '1' + util_build_gem a1 + + remote = Gem::Source.new @gem_repo + specific = Gem::Source::SpecificFile.new a1.cache_file + installed = Gem::Source::Installed.new + local = Gem::Source::Local.new + git = Gem::Source::Git.new 'a', 'a', 'master' + vendor = Gem::Source::Vendor.new 'a' + + assert_equal( 0, installed.<=>(installed), 'installed <=> installed') + + assert_equal(-1, remote. <=>(installed), 'remote <=> installed') + assert_equal( 1, installed.<=>(remote), 'installed <=> remote') + + assert_equal( 1, installed.<=>(local), 'installed <=> local') + assert_equal(-1, local. <=>(installed), 'local <=> installed') + + assert_equal(-1, specific. <=>(installed), 'specific <=> installed') + assert_equal( 1, installed.<=>(specific), 'installed <=> specific') + + assert_equal( 1, git. <=>(installed), 'git <=> installed') + assert_equal(-1, installed.<=>(git), 'installed <=> git') + + assert_equal( 1, vendor. <=>(installed), 'vendor <=> installed') + assert_equal(-1, installed.<=>(vendor), 'installed <=> vendor') + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_source_list.rb b/jni/ruby/test/rubygems/test_gem_source_list.rb new file mode 100644 index 0000000..43db204 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_source_list.rb @@ -0,0 +1,111 @@ +require 'rubygems/source_list' +require 'rubygems/test_case' + +class TestGemSourceList < Gem::TestCase + def setup + super + + @uri = "http://example" + @source = Gem::Source.new(@uri) + + @sl = Gem::SourceList.new + @sl << @source + end + + def test_self_from + sl = Gem::SourceList.from [@uri] + + assert_equal [Gem::Source.new(@uri)], sl.sources + end + + def test_Enumerable + assert_includes Gem::SourceList.ancestors, Enumerable + end + + def test_append + sl = Gem::SourceList.new + source = (sl << @uri) + + assert_kind_of Gem::Source, source + + assert_kind_of URI, source.uri + assert_equal source.uri.to_s, @uri + + assert_equal [source], sl.sources + end + + def test_clear + sl = Gem::SourceList.new + + sl << 'http://source.example' + + sl.clear + + assert_empty sl + end + + def test_replace + sl = Gem::SourceList.new + sl.replace [@uri] + + assert_equal [@source], sl.sources + end + + def test_each + @sl.each do |x| + assert_equal @uri, x + end + end + + def test_each_source + @sl.each_source do |x| + assert_equal @source, x + end + end + + def test_empty? + sl = Gem::SourceList.new + + assert_empty sl + + sl << 'http://source.example' + + refute_empty sl + end + + def test_equal_to_another_list + sl2 = Gem::SourceList.new + sl2 << Gem::Source.new(@uri) + + assert @sl == sl2, "lists not equal" + end + + def test_equal_to_array + assert @sl == [@uri], "lists not equal" + end + + def test_to_a + assert_equal @sl.to_a, [@uri] + end + + def test_include_eh + assert @sl.include?(@uri), "string comparison not working" + assert @sl.include?(URI.parse(@uri)), "uri comparison not working" + end + + def test_include_matches_a_source + assert @sl.include?(@source), "source comparison not working" + assert @sl.include?(Gem::Source.new(@uri)), "source comparison not working" + end + + def test_delete + @sl.delete @uri + assert_equal @sl.sources, [] + end + + def test_delete_a_source + @sl.delete Gem::Source.new(@uri) + assert_equal @sl.sources, [] + end + +end diff --git a/jni/ruby/test/rubygems/test_gem_source_local.rb b/jni/ruby/test/rubygems/test_gem_source_local.rb new file mode 100644 index 0000000..19e1c4b --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_source_local.rb @@ -0,0 +1,106 @@ +require 'rubygems/test_case' +require 'rubygems/source' + +require 'fileutils' + +class TestGemSourceLocal < Gem::TestCase + def setup + super + + @sl = Gem::Source::Local.new + + @a, @a_gem = util_gem "a", '1' + @ap, @ap_gem = util_gem "a", '2.a' + @b, @b_gem = util_gem "b", '1' + + FileUtils.mv @a_gem, @tempdir + FileUtils.mv @ap_gem, @tempdir + FileUtils.mv @b_gem, @tempdir + end + + def test_load_specs_released + assert_equal [@a.name_tuple, @b.name_tuple].sort, + @sl.load_specs(:released).sort + end + + def test_load_specs_prerelease + assert_equal [@ap.name_tuple], @sl.load_specs(:prerelease) + end + + def test_load_specs_latest + a2, a2_gem = util_gem "a", "2" + + FileUtils.mv a2_gem, @tempdir + + assert_equal [a2.name_tuple, @b.name_tuple].sort, + @sl.load_specs(:latest).sort + end + + def test_find_gem + assert_equal "a-1", @sl.find_gem("a").full_name + end + + def test_find_gem_highest_version + _, a2_gem = util_gem "a", "2" + FileUtils.mv a2_gem, @tempdir + + assert_equal "a-2", @sl.find_gem("a").full_name + end + + def test_find_gem_specific_version + _, a2_gem = util_gem "a", "2" + FileUtils.mv a2_gem, @tempdir + + req = Gem::Requirement.create("= 1") + + assert_equal "a-1", @sl.find_gem("a", req).full_name + end + + def test_find_gem_prerelease + req = Gem::Requirement.create(">= 0") + assert_equal "a-2.a", @sl.find_gem("a", req, true).full_name + end + + def test_fetch_spec + s = @sl.fetch_spec @a.name_tuple + assert_equal s, @a + end + + def test_inspect + assert_equal '#<Gem::Source::Local specs: "NOT LOADED">', @sl.inspect + + @sl.load_specs :released + + inner = [@a, @ap, @b].map { |t| t.name_tuple }.inspect + + assert_equal "#<Gem::Source::Local specs: #{inner}>", @sl.inspect + end + + def test_download + path = @sl.download @a + + assert_equal File.expand_path(@a.file_name), path + end + + def test_spaceship + a1 = quick_gem 'a', '1' + util_build_gem a1 + + remote = Gem::Source.new @gem_repo + specific = Gem::Source::SpecificFile.new a1.cache_file + installed = Gem::Source::Installed.new + local = Gem::Source::Local.new + + assert_equal( 0, local. <=>(local), 'local <=> local') + + assert_equal(-1, remote. <=>(local), 'remote <=> local') + assert_equal( 1, local. <=>(remote), 'local <=> remote') + + assert_equal( 1, installed.<=>(local), 'installed <=> local') + assert_equal(-1, local. <=>(installed), 'local <=> installed') + + assert_equal(-1, specific. <=>(local), 'specific <=> local') + assert_equal( 1, local. <=>(specific), 'local <=> specific') + end + +end diff --git a/jni/ruby/test/rubygems/test_gem_source_lock.rb b/jni/ruby/test/rubygems/test_gem_source_lock.rb new file mode 100644 index 0000000..23f063d --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_source_lock.rb @@ -0,0 +1,114 @@ +require 'rubygems/test_case' + +class TestGemSourceLock < Gem::TestCase + + def test_fetch_spec + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + end + + name_tuple = Gem::NameTuple.new 'a', v(1), 'ruby' + + remote = Gem::Source.new @gem_repo + lock = Gem::Source::Lock.new remote + + spec = lock.fetch_spec name_tuple + + assert_equal 'a-1', spec.full_name + end + + def test_equals2 + git = Gem::Source::Git.new 'a', 'git/a', 'master', false + g_lock = Gem::Source::Lock.new git + + installed = Gem::Source::Installed.new + i_lock = Gem::Source::Lock.new installed + + assert_equal g_lock, g_lock + refute_equal g_lock, i_lock + refute_equal g_lock, Object.new + end + + def test_spaceship + git = Gem::Source::Git.new 'a', 'git/a', 'master', false + g_lock = Gem::Source::Lock.new git + + installed = Gem::Source::Installed.new + i_lock = Gem::Source::Lock.new installed + + vendor = Gem::Source::Vendor.new 'vendor/a' + v_lock = Gem::Source::Lock.new vendor + + assert_equal( 0, g_lock.<=>(g_lock), 'g_lock <=> g_lock') + assert_equal( 0, i_lock.<=>(i_lock), 'i_lock <=> i_lock') + assert_equal( 0, v_lock.<=>(v_lock), 'v_lock <=> v_lock') + + assert_equal( 1, g_lock.<=>(i_lock), 'g_lock <=> i_lock') + assert_equal(-1, i_lock.<=>(g_lock), 'i_lock <=> g_lock') + + assert_equal(-1, g_lock.<=>(v_lock), 'g_lock <=> v_lock') + assert_equal( 1, v_lock.<=>(g_lock), 'v_lock <=> g_lock') + + assert_equal(-1, i_lock.<=>(v_lock), 'i_lock <=> v_lock') + assert_equal( 1, v_lock.<=>(i_lock), 'i_lock <=> v_lock') + end + + def test_spaceship_git + git = Gem::Source::Git.new 'a', 'git/a', 'master', false + lock = Gem::Source::Lock.new git + + assert_equal( 1, lock.<=>(git), 'lock <=> git') + assert_equal(-1, git .<=>(lock), 'git <=> lock') + end + + def test_spaceship_installed + installed = Gem::Source::Installed.new + lock = Gem::Source::Lock.new installed + + assert_equal( 1, lock. <=>(installed), 'lock <=> installed') + assert_equal(-1, installed.<=>(lock), 'installed <=> lock') + end + + def test_spaceship_local + local = Gem::Source::Local.new + lock = Gem::Source::Lock.new local # nonsense + + assert_equal( 1, lock. <=>(local), 'lock <=> local') + assert_equal(-1, local.<=>(lock), 'local <=> lock') + end + + def test_spaceship_remote + remote = Gem::Source.new @gem_repo + lock = Gem::Source::Lock.new remote + + assert_equal( 1, lock. <=>(remote), 'lock <=> remote') + assert_equal(-1, remote.<=>(lock), 'remote <=> lock') + end + + def test_spaceship_specific_file + _, gem = util_gem 'a', 1 + + specific = Gem::Source::SpecificFile.new gem + lock = Gem::Source::Lock.new specific # nonsense + + assert_equal( 1, lock .<=>(specific), 'lock <=> specific') + assert_equal(-1, specific.<=>(lock), 'specific <=> lock') + end + + def test_spaceship_vendor + vendor = Gem::Source::Vendor.new 'vendor/a' + lock = Gem::Source::Lock.new vendor + + assert_equal( 1, lock. <=>(vendor), 'lock <=> vendor') + assert_equal(-1, vendor.<=>(lock), 'vendor <=> lock') + end + + def test_uri + remote = Gem::Source.new @gem_repo + lock = Gem::Source::Lock.new remote + + assert_equal URI(@gem_repo), lock.uri + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_source_specific_file.rb b/jni/ruby/test/rubygems/test_gem_source_specific_file.rb new file mode 100644 index 0000000..12ef7f5 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_source_specific_file.rb @@ -0,0 +1,75 @@ +require 'rubygems/test_case' +require 'rubygems/source' + +class TestGemSourceSpecificFile < Gem::TestCase + def setup + super + + @a, @a_gem = util_gem "a", '1' + @sf = Gem::Source::SpecificFile.new(@a_gem) + end + + def test_path + assert_equal @a_gem, @sf.path + end + + def test_spec + assert_equal @a, @sf.spec + end + + def test_load_specs + assert_equal [@a.name_tuple], @sf.load_specs + end + + def test_fetch_spec + assert_equal @a, @sf.fetch_spec(@a.name_tuple) + end + + def test_fetch_spec_fails_on_unknown_name + assert_raises Gem::Exception do + @sf.fetch_spec(nil) + end + end + + def test_download + assert_equal @a_gem, @sf.download(@a) + end + + def test_spaceship + a1 = quick_gem 'a', '1' + util_build_gem a1 + + remote = Gem::Source.new @gem_repo + specific = Gem::Source::SpecificFile.new a1.cache_file + installed = Gem::Source::Installed.new + local = Gem::Source::Local.new + + assert_equal( 0, specific. <=>(specific), 'specific <=> specific') + + assert_equal(-1, remote. <=>(specific), 'remote <=> specific') + assert_equal( 1, specific. <=>(remote), 'specific <=> remote') + + assert_equal(-1, specific. <=>(local), 'specific <=> local') + assert_equal( 1, local. <=>(specific), 'local <=> specific') + + assert_equal(-1, specific. <=>(installed), 'specific <=> installed') + assert_equal( 1, installed.<=>(specific), 'installed <=> specific') + + a2 = quick_gem 'a', '2' + util_build_gem a2 + + b1 = quick_gem 'b', '1' + util_build_gem b1 + + a1_source = specific + a2_source = Gem::Source::SpecificFile.new a2.cache_file + b1_source = Gem::Source::SpecificFile.new b1.cache_file + + assert_nil a1_source.<=>(b1_source), 'a1_source <=> b1_source' + + assert_equal(-1, a1_source.<=>(a2_source), 'a1_source <=> a2_source') + assert_equal( 0, a1_source.<=>(a1_source), 'a1_source <=> a1_source') + assert_equal( 1, a2_source.<=>(a1_source), 'a2_source <=> a1_source') + end + +end diff --git a/jni/ruby/test/rubygems/test_gem_source_vendor.rb b/jni/ruby/test/rubygems/test_gem_source_vendor.rb new file mode 100644 index 0000000..1d9ae35 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_source_vendor.rb @@ -0,0 +1,31 @@ +require 'rubygems/test_case' +require 'rubygems/source' + +class TestGemSourceVendor < Gem::TestCase + + def test_initialize + source = Gem::Source::Vendor.new 'vendor/foo' + + assert_equal 'vendor/foo', source.uri + end + + def test_spaceship + vendor = Gem::Source::Vendor.new 'vendor/foo' + remote = Gem::Source.new @gem_repo + git = Gem::Source::Git.new 'a', 'a', 'master' + installed = Gem::Source::Installed.new + + assert_equal( 0, vendor. <=>(vendor), 'vendor <=> vendor') + + assert_equal( 1, vendor. <=>(remote), 'vendor <=> remote') + assert_equal(-1, remote. <=>(vendor), 'remote <=> vendor') + + assert_equal( 1, vendor. <=>(git), 'vendor <=> git') + assert_equal(-1, git. <=>(vendor), 'git <=> vendor') + + assert_equal( 1, vendor. <=>(installed), 'vendor <=> installed') + assert_equal(-1, installed.<=>(vendor), 'installed <=> vendor') + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_spec_fetcher.rb b/jni/ruby/test/rubygems/test_gem_spec_fetcher.rb new file mode 100644 index 0000000..6ee1a52 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_spec_fetcher.rb @@ -0,0 +1,310 @@ +require 'rubygems/test_case' +require 'rubygems/spec_fetcher' + +class TestGemSpecFetcher < Gem::TestCase + + def tuple(*args) + Gem::NameTuple.new(*args) + end + + def setup + super + + @uri = URI.parse @gem_repo + @source = Gem::Source.new(@uri) + + @sf = Gem::SpecFetcher.new + end + + def test_initialize + fetcher = Gem::SpecFetcher.new + + assert_same Gem.sources, fetcher.sources + end + + def test_initialize_source + alternate = 'http://alternate.example' + fetcher = Gem::SpecFetcher.new alternate + + refute_same Gem.sources, fetcher.sources + + assert_equal alternate, fetcher.sources + end + + def test_initialize_nonexistent_home_dir + FileUtils.rmdir Gem.user_home + + assert Gem::SpecFetcher.new + end + + def test_initialize_unwritable_home_dir + skip 'chmod not supported' if Gem.win_platform? + + FileUtils.chmod 0000, Gem.user_home + + begin + assert Gem::SpecFetcher.new + ensure + FileUtils.chmod 0755, Gem.user_home + end + end + + def test_spec_for_dependency_all + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.spec 'a', '2.a' + fetcher.spec 'a', 2 + fetcher.spec 'a', '3.a' + end + + dep = Gem::Dependency.new 'a', ">= 1" + + specs_and_sources, _ = @sf.spec_for_dependency dep + + spec_names = specs_and_sources.map do |spec, source_uri| + [spec.full_name, source_uri] + end + + expected = [['a-1', @source], ['a-2', @source]] + + assert_equal expected, spec_names + + assert_same specs_and_sources.first.last, specs_and_sources.last.last + end + + def test_spec_for_dependency_latest + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.spec 'a', 2 + fetcher.spec 'a', '3.a' + end + + dep = Gem::Dependency.new 'a' + specs_and_sources, _ = @sf.spec_for_dependency dep + + spec_names = specs_and_sources.map do |spec, source_uri| + [spec.full_name, source_uri] + end + + assert_equal [['a-2', Gem::Source.new(@gem_repo)]], + spec_names + end + + def test_spec_for_dependency_prerelease + spec_fetcher do |fetcher| + fetcher.spec 'a', '1.a' + fetcher.spec 'a', 1 + end + + specs_and_sources, _ = @sf.spec_for_dependency dep('a', '1.a') + + spec_names = specs_and_sources.map do |spec, source_uri| + [spec.full_name, source_uri] + end + + assert_equal [['a-1.a', Gem::Source.new(@gem_repo)]], spec_names + end + + def test_spec_for_dependency_platform + util_set_arch 'i386-linux' + + spec_fetcher do |fetcher| + fetcher.legacy_platform + end + + dep = Gem::Dependency.new 'pl', 1 + specs_and_sources, _ = @sf.spec_for_dependency dep + + spec_names = specs_and_sources.map do |spec, source_uri| + [spec.full_name, source_uri] + end + + assert_equal [['pl-1-x86-linux', Gem::Source.new(@gem_repo)]], + spec_names + end + + def test_spec_for_dependency_mismatched_platform + util_set_arch 'hrpa-989' + + spec_fetcher do |fetcher| + fetcher.legacy_platform + end + + dep = Gem::Dependency.new 'pl', 1 + specs_and_sources, errors = @sf.spec_for_dependency dep + + assert_equal 0, specs_and_sources.size + assert_equal 1, errors.size + pmm = errors.first + + assert_equal "i386-linux", pmm.platforms.first + assert_equal "Found pl (1), but was for platform i386-linux", pmm.wordy + end + + def test_spec_for_dependency_bad_fetch_spec + src = Gem::Source.new(@gem_repo) + def src.fetch_spec(name) + raise Gem::RemoteFetcher::FetchError.new("bad news from the internet", @uri) + end + + Gem.sources.replace [src] + + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.spec 'a', '2.a' + fetcher.spec 'a', 2 + fetcher.spec 'a', '3.a' + end + + dep = Gem::Dependency.new 'a', ">= 1" + + specs_and_sources, errors = @sf.spec_for_dependency dep + + assert_equal [], specs_and_sources + sfp = errors.first + + assert_kind_of Gem::SourceFetchProblem, sfp + assert_equal src, sfp.source + assert_equal "bad news from the internet (#{@gem_repo})", sfp.error.message + end + + def test_available_specs_latest + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.spec 'a', 2 + fetcher.spec 'a', '3.a' + fetcher.legacy_platform + end + + specs, _ = @sf.available_specs(:latest) + + assert_equal [@source], specs.keys + + expected = Gem::NameTuple.from_list \ + [['a', v(2), Gem::Platform::RUBY], + ['pl', v(1), 'i386-linux']] + + assert_equal expected, specs[@source] + end + + def test_available_specs_released + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.legacy_platform + end + + specs, _ = @sf.available_specs(:released) + + assert_equal [@source], specs.keys + + expected = Gem::NameTuple.from_list \ + [['a', v(1), Gem::Platform::RUBY], + ['pl', v(1), 'i386-linux']] + + assert_equal expected, specs[@source] + end + + def test_available_specs_complete + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.spec 'a', '2.a' + fetcher.spec 'b', 2 + fetcher.legacy_platform + end + + specs, _ = @sf.available_specs(:complete) + + assert_equal [@source], specs.keys + + expected = Gem::NameTuple.from_list \ + [['a', v(1), Gem::Platform::RUBY], + ['a', v('2.a'), Gem::Platform::RUBY], + ['b', v(2), Gem::Platform::RUBY], + ['pl', v(1), 'i386-linux']] + + assert_equal expected, specs[@source] + end + + def test_available_specs_complete_handles_no_prerelease + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.spec 'a', '2.a' + fetcher.spec 'b', 2 + fetcher.legacy_platform + end + + v = Gem.marshal_version + @fetcher.data.delete "#{@gem_repo}prerelease_specs.#{v}.gz" + + specs, _ = @sf.available_specs(:complete) + + assert_equal [@source], specs.keys + + expected = Gem::NameTuple.from_list \ + [['a', v(1), Gem::Platform::RUBY], + ['b', v(2), Gem::Platform::RUBY], + ['pl', v(1), 'i386-linux']] + + assert_equal expected, specs[@source] + end + + def test_available_specs_cache + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + end + + specs, _ = @sf.available_specs(:latest) + + refute specs[@source].empty? + + @fetcher.data["#{@gem_repo}/latest_specs.#{Gem.marshal_version}.gz"] = nil + + cached_specs, _ = @sf.available_specs(:latest) + + assert_equal specs, cached_specs + end + + def test_available_specs_cache_released + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.spec 'a', '2.a' + fetcher.spec 'b', 2 + fetcher.legacy_platform + end + + specs, _ = @sf.available_specs(:released) + + refute specs[@source].empty? + + @fetcher.data["#{@gem_repo}/specs.#{Gem.marshal_version}.gz"] = nil + + cached_specs, _ = @sf.available_specs(:released) + + assert_equal specs, cached_specs + end + + def test_available_specs_prerelease + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 + fetcher.spec 'a', '2.a' + end + + specs, _ = @sf.available_specs(:prerelease) + + expected = Gem::NameTuple.from_list \ + [['a', v('2.a'), Gem::Platform::RUBY]] + + assert_equal expected, specs[@source] + end + + def test_available_specs_with_bad_source + Gem.sources.replace ["http://not-there.nothing"] + + specs, errors = @sf.available_specs(:latest) + + assert_equal({}, specs) + assert_kind_of Gem::SourceFetchProblem, errors.first + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_specification.rb b/jni/ruby/test/rubygems/test_gem_specification.rb new file mode 100644 index 0000000..3cadc55 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_specification.rb @@ -0,0 +1,3138 @@ +require 'rubygems/test_case' +require 'pathname' +require 'stringio' +require 'rubygems/ext' +require 'rubygems/specification' + +class TestGemSpecification < Gem::TestCase + + LEGACY_YAML_SPEC = <<-EOF +--- !ruby/object:Gem::Specification +rubygems_version: "1.0" +name: keyedlist +version: !ruby/object:Gem::Version + version: 0.4.0 +date: 2004-03-28 15:37:49.828000 +02:00 +platform: +summary: A Hash which automatically computes keys. +require_paths: + - lib +files: + - lib/keyedlist.rb +autorequire: keyedlist +author: Florian Gross +email: flgr@ccan.de +has_rdoc: true + EOF + + LEGACY_RUBY_SPEC = <<-EOF +Gem::Specification.new do |s| + s.name = %q{keyedlist} + s.version = %q{0.4.0} + s.has_rdoc = true + s.summary = %q{A Hash which automatically computes keys.} + s.files = [%q{lib/keyedlist.rb}] + s.require_paths = [%q{lib}] + s.autorequire = %q{keyedlist} + s.author = %q{Florian Gross} + s.email = %q{flgr@ccan.de} +end + EOF + + def make_spec_c1 + @c1 = util_spec 'a', '1' do |s| + s.executable = 'exec' + s.extensions << 'ext/a/extconf.rb' + s.test_file = 'test/suite.rb' + s.requirements << 'A working computer' + s.rubyforge_project = 'example' + s.license = 'MIT' + + s.add_dependency 'rake', '> 0.4' + s.add_dependency 'jabber4r', '> 0.0.0' + s.add_dependency 'pqa', ['> 0.4', '<= 0.6'] + + s.mark_version + s.files = %w[lib/code.rb] + end + end + + def ext_spec + @ext = util_spec 'ext', '1' do |s| + s.executable = 'exec' + s.test_file = 'test/suite.rb' + s.extensions = %w[ext/extconf.rb] + s.license = 'MIT' + + s.mark_version + s.files = %w[lib/code.rb] + s.installed_by_version = v('2.2') + end + end + + def setup + super + + @a1 = util_spec 'a', '1' do |s| + s.executable = 'exec' + s.test_file = 'test/suite.rb' + s.requirements << 'A working computer' + s.rubyforge_project = 'example' + s.license = 'MIT' + + s.mark_version + s.files = %w[lib/code.rb] + end + + @a2 = util_spec 'a', '2' do |s| + s.files = %w[lib/code.rb] + end + + @a3 = util_spec 'a', '3' do |s| + s.metadata['allowed_push_host'] = "https://privategemserver.com" + end + + @current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION + + load 'rubygems/syck_hack.rb' + end + + def test_self_activate + foo = util_spec 'foo', '1' + + assert_activate %w[foo-1], foo + end + + def test_self_activate_ambiguous_direct + save_loaded_features do + a1 = new_spec "a", "1", "b" => "> 0" + b1 = new_spec("b", "1", { "c" => ">= 1" }, "lib/d.rb") + b2 = new_spec("b", "2", { "c" => ">= 2" }, "lib/d.rb") + c1 = new_spec "c", "1" + c2 = new_spec "c", "2" + + Gem::Specification.reset + install_specs a1, b1, b2, c1, c2 + + a1.activate + assert_equal %w(a-1), loaded_spec_names + assert_equal ["b (> 0)"], unresolved_names + + require "d" + + assert_equal %w(a-1 b-2 c-2), loaded_spec_names + assert_equal [], unresolved_names + end + end + + def test_self_activate_ambiguous_indirect + 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", nil, "lib/d.rb" + c2 = new_spec "c", "2", nil, "lib/d.rb" + + install_specs a1, b1, b2, c1, c2 + + a1.activate + assert_equal %w(a-1), loaded_spec_names + assert_equal ["b (> 0)"], unresolved_names + + require "d" + + assert_equal %w(a-1 b-2 c-2), loaded_spec_names + assert_equal [], unresolved_names + end + end + + def test_self_activate_ambiguous_indirect_conflict + save_loaded_features do + a1 = new_spec "a", "1", "b" => "> 0" + a2 = new_spec "a", "2", "b" => "> 0" + b1 = new_spec "b", "1", "c" => ">= 1" + b2 = new_spec "b", "2", "c" => ">= 2" + c1 = new_spec "c", "1", nil, "lib/d.rb" + c2 = new_spec("c", "2", { "a" => "1" }, "lib/d.rb") # conflicts with a-2 + + install_specs a1, a2, b1, b2, c1, c2 + + a2.activate + assert_equal %w(a-2), loaded_spec_names + assert_equal ["b (> 0)"], unresolved_names + + require "d" + + assert_equal %w(a-2 b-1 c-1), loaded_spec_names + assert_equal [], unresolved_names + end + end + + def test_self_activate_ambiguous_unrelated + 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" + d1 = new_spec "d", "1", nil, "lib/d.rb" + + install_specs a1, b1, b2, c1, c2, d1 + + a1.activate + assert_equal %w(a-1), loaded_spec_names + assert_equal ["b (> 0)"], unresolved_names + + require "d" + + assert_equal %w(a-1 d-1), loaded_spec_names + assert_equal ["b (> 0)"], unresolved_names + end + end + + ## + # [A] depends on + # [C] = 1.0 depends on + # [B] = 2.0 + # [B] ~> 1.0 (satisfied by 1.0) + + def test_self_activate_checks_dependencies + a, _ = util_spec 'a', '1.0' + a.add_dependency 'c', '= 1.0' + a.add_dependency 'b', '~> 1.0' + + util_spec 'b', '1.0' + util_spec 'b', '2.0' + c, _ = util_spec 'c', '1.0', 'b' => '= 2.0' + + e = assert_raises Gem::LoadError do + assert_activate nil, a, c, "b" + end + + expected = "can't satisfy 'b (~> 1.0)', already activated 'b-2.0'" + assert_equal expected, e.message + end + + ## + # [A] depends on + # [B] ~> 1.0 (satisfied by 1.0) + # [C] = 1.0 depends on + # [B] = 2.0 + + def test_self_activate_divergent + a, _ = util_spec 'a', '1.0', 'b' => '~> 1.0', 'c' => '= 1.0' + util_spec 'b', '1.0' + util_spec 'b', '2.0' + c, _ = util_spec 'c', '1.0', 'b' => '= 2.0' + + e = assert_raises Gem::ConflictError do + assert_activate nil, a, c, "b" + end + + assert_match(/Unable to activate c-1.0,/, e.message) + assert_match(/because b-1.0 conflicts with b .= 2.0/, e.message) + end + + ## + # DOC + + def test_self_activate_old_required + e1, = util_spec 'e', '1', 'd' => '= 1' + @d1 = util_spec 'd', '1' + @d2 = util_spec 'd', '2' + + assert_activate %w[d-1 e-1], e1, "d" + end + + ## + # DOC + + def test_self_activate_platform_alternate + @x1_m = util_spec 'x', '1' do |s| + s.platform = Gem::Platform.new %w[cpu my_platform 1] + end + + @x1_o = util_spec 'x', '1' do |s| + s.platform = Gem::Platform.new %w[cpu other_platform 1] + end + + @w1 = util_spec 'w', '1', 'x' => nil + + util_set_arch 'cpu-my_platform1' + + assert_activate %w[x-1-cpu-my_platform-1 w-1], @w1, @x1_m + end + + ## + # DOC + + def test_self_activate_platform_bump + @y1 = util_spec 'y', '1' + + @y1_1_p = util_spec 'y', '1.1' do |s| + s.platform = Gem::Platform.new %w[cpu my_platform 1] + end + + @z1 = util_spec 'z', '1', 'y' => nil + + assert_activate %w[y-1 z-1], @z1, @y1 + end + + ## + # [C] depends on + # [A] = 1.a + # [B] = 1.0 depends on + # [A] >= 0 (satisfied by 1.a) + + def test_self_activate_prerelease + @c1_pre = util_spec 'c', '1.a', "a" => "1.a", "b" => "1" + @a1_pre = util_spec 'a', '1.a' + @b1 = util_spec 'b', '1' do |s| + s.add_dependency 'a' + s.add_development_dependency 'aa' + end + + assert_activate %w[a-1.a b-1 c-1.a], @c1_pre, @a1_pre, @b1 + end + + def test_self_activate_via_require + a1 = new_spec "a", "1", "b" => "= 1" + b1 = new_spec "b", "1", nil, "lib/b/c.rb" + b2 = new_spec "b", "2", nil, "lib/b/c.rb" + + install_specs a1, b1, b2 + + a1.activate + save_loaded_features do + require "b/c" + end + + assert_equal %w(a-1 b-1), loaded_spec_names + end + + def test_self_activate_via_require_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" + b2 = new_spec "b", "2", { "c" => ">= 2" }, "lib/b.rb" # this + c1 = new_spec "c", "1" + c2 = new_spec "c", "2" # this + 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 + + require "b" + + e = assert_raises Gem::LoadError do + require "d" + end + + assert_equal "unable to find a version of 'd' to activate", e.message + + assert_equal %w(a-1 b-2 c-2), loaded_spec_names + assert_equal ["d (> 0)"], unresolved_names + end + end + + def test_self_activate_deep_unambiguous + a1 = new_spec "a", "1", "b" => "= 1" + 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 b-1 c-1), loaded_spec_names + end + + def test_self_activate_loaded + foo = util_spec 'foo', '1' + + assert foo.activate + refute foo.activate + end + + ## + # [A] depends on + # [B] >= 1.0 (satisfied by 2.0) + # [C] depends on nothing + + def test_self_activate_unrelated + a = util_spec 'a', '1.0', 'b' => '>= 1.0' + util_spec 'b', '1.0' + c = util_spec 'c', '1.0' + + assert_activate %w[b-1.0 c-1.0 a-1.0], a, c, "b" + end + + ## + # [A] depends on + # [B] >= 1.0 (satisfied by 2.0) + # [C] = 1.0 depends on + # [B] ~> 1.0 + # + # and should resolve using b-1.0 + # TODO: move these to specification + + def test_self_activate_over + a = util_spec 'a', '1.0', 'b' => '>= 1.0', 'c' => '= 1.0' + util_spec 'b', '1.0' + util_spec 'b', '1.1' + util_spec 'b', '2.0' + util_spec 'c', '1.0', 'b' => '~> 1.0' + + a.activate + + assert_equal %w[a-1.0 c-1.0], loaded_spec_names + assert_equal ["b (>= 1.0, ~> 1.0)"], unresolved_names + end + + ## + # [A] depends on + # [B] ~> 1.0 (satisfied by 1.1) + # [C] = 1.0 depends on + # [B] = 1.0 + # + # and should resolve using b-1.0 + # + # TODO: this is not under, but over... under would require depth + # first resolve through a dependency that is later pruned. + + def test_self_activate_under + a, _ = util_spec 'a', '1.0', 'b' => '~> 1.0', 'c' => '= 1.0' + util_spec 'b', '1.0' + util_spec 'b', '1.1' + c, _ = util_spec 'c', '1.0', 'b' => '= 1.0' + + assert_activate %w[b-1.0 c-1.0 a-1.0], a, c, "b" + end + + ## + # [A1] depends on + # [B] > 0 (satisfied by 2.0) + # [B1] depends on + # [C] > 0 (satisfied by 1.0) + # [B2] depends on nothing! + # [C1] depends on nothing + + def test_self_activate_dropped + a1, = util_spec 'a', '1', 'b' => nil + util_spec 'b', '1', 'c' => nil + util_spec 'b', '2' + util_spec 'c', '1' + + assert_activate %w[b-2 a-1], a1, "b" + end + + ## + # [A] depends on + # [B] >= 1.0 (satisfied by 1.1) depends on + # [Z] + # [C] >= 1.0 depends on + # [B] = 1.0 + # + # and should backtrack to resolve using b-1.0, pruning Z from the + # resolve. + + def test_self_activate_raggi_the_edgecase_generator + a, _ = util_spec 'a', '1.0', 'b' => '>= 1.0', 'c' => '>= 1.0' + util_spec 'b', '1.0' + util_spec 'b', '1.1', 'z' => '>= 1.0' + c, _ = util_spec 'c', '1.0', 'b' => '= 1.0' + + assert_activate %w[b-1.0 c-1.0 a-1.0], a, c, "b" + end + + def test_self_activate_conflict + util_spec 'b', '1.0' + util_spec 'b', '2.0' + + gem "b", "= 1.0" + + assert_raises Gem::LoadError do + gem "b", "= 2.0" + end + end + + def test_self_all_equals + a = new_spec "foo", "1", nil, "lib/foo.rb" + + Gem::Specification.all = [a] + + assert_equal a, Gem::Specification.find_inactive_by_path('foo') + end + + def test_self_attribute_names + expected_value = %w[ + authors + autorequire + bindir + cert_chain + date + dependencies + description + email + executables + extensions + extra_rdoc_files + files + homepage + licenses + metadata + name + platform + post_install_message + rdoc_options + require_paths + required_ruby_version + required_rubygems_version + requirements + rubyforge_project + rubygems_version + signing_key + specification_version + summary + test_files + version + ] + + actual_value = Gem::Specification.attribute_names.map { |a| a.to_s }.sort + + assert_equal expected_value, actual_value + end + + def test_self__load_future + spec = Gem::Specification.new + spec.name = 'a' + spec.version = '1' + spec.specification_version = @current_version + 1 + + new_spec = Marshal.load Marshal.dump(spec) + + assert_equal 'a', new_spec.name + assert_equal Gem::Version.new(1), new_spec.version + assert_equal @current_version, new_spec.specification_version + end + + def test_self_from_yaml + @a1.instance_variable_set :@specification_version, nil + + spec = Gem::Specification.from_yaml @a1.to_yaml + + assert_equal Gem::Specification::NONEXISTENT_SPECIFICATION_VERSION, + spec.specification_version + end + + def test_self_from_yaml_syck_date_bug + # This is equivalent to (and totally valid) psych 1.0 output and + # causes parse errors on syck. + yaml = @a1.to_yaml + yaml.sub!(/^date:.*/, "date: 2011-04-26 00:00:00.000000000Z") + + new_spec = with_syck do + Gem::Specification.from_yaml yaml + end + + assert_kind_of Time, @a1.date + assert_kind_of Time, new_spec.date + end + + def test_self_from_yaml_syck_default_key_bug + # This is equivalent to (and totally valid) psych 1.0 output and + # causes parse errors on syck. + yaml = <<-YAML +--- !ruby/object:Gem::Specification +name: posix-spawn +version: !ruby/object:Gem::Version + version: 0.3.6 + prerelease: +dependencies: +- !ruby/object:Gem::Dependency + name: rake-compiler + requirement: &70243867725240 !ruby/object:Gem::Requirement + none: false + requirements: + - - = + - !ruby/object:Gem::Version + version: 0.7.6 + type: :development + prerelease: false + version_requirements: *70243867725240 +platform: ruby +files: [] +test_files: [] +bindir: + YAML + + new_spec = with_syck do + Gem::Specification.from_yaml yaml + end + + op = new_spec.dependencies.first.requirement.requirements.first.first + refute_kind_of YAML::Syck::DefaultKey, op + + refute_match %r%DefaultKey%, new_spec.to_ruby + end + + def test_self_from_yaml_cleans_up_defaultkey + yaml = <<-YAML +--- !ruby/object:Gem::Specification +name: posix-spawn +version: !ruby/object:Gem::Version + version: 0.3.6 + prerelease: +dependencies: +- !ruby/object:Gem::Dependency + name: rake-compiler + requirement: &70243867725240 !ruby/object:Gem::Requirement + none: false + requirements: + - - !ruby/object:YAML::Syck::DefaultKey {} + + - !ruby/object:Gem::Version + version: 0.7.6 + type: :development + prerelease: false + version_requirements: *70243867725240 +platform: ruby +files: [] +test_files: [] +bindir: + YAML + + new_spec = Gem::Specification.from_yaml yaml + + op = new_spec.dependencies.first.requirement.requirements.first.first + refute_kind_of YAML::Syck::DefaultKey, op + + refute_match %r%DefaultKey%, new_spec.to_ruby + end + + def test_self_from_yaml_cleans_up_defaultkey_from_newer_192 + yaml = <<-YAML +--- !ruby/object:Gem::Specification +name: posix-spawn +version: !ruby/object:Gem::Version + version: 0.3.6 + prerelease: +dependencies: +- !ruby/object:Gem::Dependency + name: rake-compiler + requirement: &70243867725240 !ruby/object:Gem::Requirement + none: false + requirements: + - - !ruby/object:Syck::DefaultKey {} + + - !ruby/object:Gem::Version + version: 0.7.6 + type: :development + prerelease: false + version_requirements: *70243867725240 +platform: ruby +files: [] +test_files: [] +bindir: + YAML + + new_spec = Gem::Specification.from_yaml yaml + + op = new_spec.dependencies.first.requirement.requirements.first.first + refute_kind_of YAML::Syck::DefaultKey, op + + refute_match %r%DefaultKey%, new_spec.to_ruby + end + + def test_self_from_yaml_cleans_up_Date_objects + yaml = <<-YAML +--- !ruby/object:Gem::Specification +rubygems_version: 0.8.1 +specification_version: 1 +name: diff-lcs +version: !ruby/object:Gem::Version + version: 1.1.2 +date: 2004-10-20 +summary: Provides a list of changes that represent the difference between two sequenced collections. +require_paths: + - lib +author: Austin Ziegler +email: diff-lcs@halostatue.ca +homepage: http://rubyforge.org/projects/ruwiki/ +rubyforge_project: ruwiki +description: "Test" +bindir: bin +has_rdoc: true +required_ruby_version: !ruby/object:Gem::Version::Requirement + requirements: + - + - ">=" + - !ruby/object:Gem::Version + version: 1.8.1 + version: +platform: ruby +files: + - tests/00test.rb +rdoc_options: + - "--title" + - "Diff::LCS -- A Diff Algorithm" + - "--main" + - README + - "--line-numbers" +extra_rdoc_files: + - README + - ChangeLog + - Install +executables: + - ldiff + - htmldiff +extensions: [] +requirements: [] +dependencies: [] + YAML + + new_spec = Gem::Specification.from_yaml yaml + + assert_kind_of Time, new_spec.date + end + + def test_self_load + full_path = @a2.spec_file + write_file full_path do |io| + io.write @a2.to_ruby_for_cache + end + + spec = Gem::Specification.load full_path + + @a2.files.clear + + assert_equal @a2, spec + end + + def test_self_load_relative + open 'a-2.gemspec', 'w' do |io| + io.write @a2.to_ruby_for_cache + end + + spec = Gem::Specification.load 'a-2.gemspec' + + @a2.files.clear + + assert_equal @a2, spec + + assert_equal File.join(@tempdir, 'a-2.gemspec'), spec.loaded_from + end + + def test_self_load_tainted + full_path = @a2.spec_file + write_file full_path do |io| + io.write @a2.to_ruby_for_cache + end + + full_path.taint + loader = Thread.new { $SAFE = 1; Gem::Specification.load full_path } + spec = loader.value + + @a2.files.clear + + assert_equal @a2, spec + end + + def test_self_load_escape_curly + @a2.name = 'a};raise "improper escaping";%q{' + + full_path = @a2.spec_file + write_file full_path do |io| + io.write @a2.to_ruby_for_cache + end + + spec = Gem::Specification.load full_path + + @a2.files.clear + + assert_equal @a2, spec + end + + def test_self_load_escape_interpolation + @a2.name = 'a#{raise %<improper escaping>}' + + full_path = @a2.spec_file + write_file full_path do |io| + io.write @a2.to_ruby_for_cache + end + + spec = Gem::Specification.load full_path + + @a2.files.clear + + assert_equal @a2, spec + end + + def test_self_load_escape_quote + @a2.name = 'a";raise "improper escaping";"' + + full_path = @a2.spec_file + write_file full_path do |io| + io.write @a2.to_ruby_for_cache + end + + spec = Gem::Specification.load full_path + + @a2.files.clear + + assert_equal @a2, spec + end + + if defined?(Encoding) + def test_self_load_utf8_with_ascii_encoding + int_enc = Encoding.default_internal + silence_warnings { Encoding.default_internal = 'US-ASCII' } + + spec2 = @a2.dup + bin = "\u5678" + spec2.authors = [bin] + full_path = spec2.spec_file + write_file full_path do |io| + io.write spec2.to_ruby_for_cache.force_encoding('BINARY').sub("\\u{5678}", bin.force_encoding('BINARY')) + end + + spec = Gem::Specification.load full_path + + spec2.files.clear + + assert_equal spec2, spec + ensure + silence_warnings { Encoding.default_internal = int_enc } + end + end + + def test_self_load_legacy_ruby + spec = Gem::Deprecate.skip_during do + eval LEGACY_RUBY_SPEC + end + assert_equal 'keyedlist', spec.name + assert_equal '0.4.0', spec.version.to_s + assert_equal Gem::Specification::TODAY, spec.date + assert spec.required_ruby_version.satisfied_by?(Gem::Version.new('1')) + assert_equal false, spec.has_unit_tests? + end + + def test_self_normalize_yaml_input_with_183_yaml + input = "!ruby/object:Gem::Specification " + assert_equal "--- #{input}", Gem::Specification.normalize_yaml_input(input) + end + + def test_self_normalize_yaml_input_with_non_183_yaml + input = "--- !ruby/object:Gem::Specification " + assert_equal input, Gem::Specification.normalize_yaml_input(input) + end + + def test_self_normalize_yaml_input_with_183_io + input = "!ruby/object:Gem::Specification " + assert_equal "--- #{input}", + Gem::Specification.normalize_yaml_input(StringIO.new(input)) + end + + def test_self_normalize_yaml_input_with_non_183_io + input = "--- !ruby/object:Gem::Specification " + assert_equal input, + Gem::Specification.normalize_yaml_input(StringIO.new(input)) + end + + def test_self_normalize_yaml_input_with_192_yaml + input = "--- !ruby/object:Gem::Specification \nblah: !!null \n" + expected = "--- !ruby/object:Gem::Specification \nblah: \n" + + assert_equal expected, Gem::Specification.normalize_yaml_input(input) + end + + def test_self_outdated + spec_fetcher do |fetcher| + fetcher.spec 'a', 4 + + fetcher.clear + + fetcher.spec 'a', 3 + end + + assert_equal %w[a], Gem::Specification.outdated + end + + def test_self_outdated_and_latest_remotes + specs = spec_fetcher do |fetcher| + fetcher.spec 'a', 4 + fetcher.spec 'b', 3 + + fetcher.clear + + fetcher.spec 'a', '3.a' + fetcher.spec 'b', 2 + end + + expected = [ + [specs['a-3.a'], v(4)], + [specs['b-2'], v(3)], + ] + + assert_equal expected, Gem::Specification.outdated_and_latest_version.to_a + end + + def test_self_remove_spec + assert_includes Gem::Specification.all_names, 'a-1' + assert_includes Gem::Specification.stubs.map { |s| s.full_name }, 'a-1' + + Gem::Specification.remove_spec @a1 + + refute_includes Gem::Specification.all_names, 'a-1' + refute_includes Gem::Specification.stubs.map { |s| s.full_name }, 'a-1' + end + + def test_self_remove_spec_removed + open @a1.spec_file, 'w' do |io| + io.write @a1.to_ruby + end + + Gem::Specification.reset + + FileUtils.rm @a1.spec_file # bug #698 + + Gem::Specification.remove_spec @a1 + + refute_includes Gem::Specification.all_names, 'a-1' + refute_includes Gem::Specification.stubs.map { |s| s.full_name }, 'a-1' + end + + DATA_PATH = File.expand_path "../data", __FILE__ + + def test_handles_private_null_type + path = File.join DATA_PATH, "null-type.gemspec.rz" + + data = Marshal.load Gem.inflate(Gem.read_binary(path)) + + assert_equal nil, data.rubyforge_project + end + + def test_emits_zulu_timestamps_properly + t = Time.utc(2012, 3, 12) + @a2.date = t + + yaml = with_psych { @a2.to_yaml } + + assert_match %r!date: 2012-03-12 00:00:00\.000000000 Z!, yaml + end if RUBY_VERSION =~ /1\.9\.2/ + + def test_initialize + spec = Gem::Specification.new do |s| + s.name = "blah" + s.version = "1.3.5" + end + + assert_equal "blah", spec.name + assert_equal "1.3.5", spec.version.to_s + assert_equal Gem::Platform::RUBY, spec.platform + assert_equal nil, spec.summary + assert_equal [], spec.files + + assert_equal [], spec.test_files + assert_equal [], spec.rdoc_options + assert_equal [], spec.extra_rdoc_files + assert_equal [], spec.executables + assert_equal [], spec.extensions + assert_equal [], spec.requirements + assert_equal [], spec.dependencies + assert_equal 'bin', spec.bindir + assert_equal '>= 0', spec.required_ruby_version.to_s + assert_equal '>= 0', spec.required_rubygems_version.to_s + end + + def test_initialize_future + version = Gem::Specification::CURRENT_SPECIFICATION_VERSION + 1 + spec = Gem::Specification.new do |s| + s.name = "blah" + s.version = "1.3.5" + + s.specification_version = version + + s.new_unknown_attribute = "a value" + end + + assert_equal "blah", spec.name + assert_equal "1.3.5", spec.version.to_s + end + + def test_initialize_copy + spec = Gem::Specification.new do |s| + s.name = "blah" + s.version = "1.3.5" + s.summary = 'summary' + s.description = 'description' + s.authors = 'author a', 'author b' + s.licenses = 'BSD' + s.files = 'lib/file.rb' + s.test_files = 'test/file.rb' + s.rdoc_options = '--foo' + s.extra_rdoc_files = 'README.txt' + s.executables = 'exec' + s.extensions = 'ext/extconf.rb' + s.requirements = 'requirement' + s.add_dependency 'some_gem' + end + + new_spec = spec.dup + + assert_equal "blah", spec.name + assert_same spec.name, new_spec.name + + assert_equal "1.3.5", spec.version.to_s + assert_same spec.version, new_spec.version + + assert_equal Gem::Platform::RUBY, spec.platform + assert_same spec.platform, new_spec.platform + + assert_equal 'summary', spec.summary + assert_same spec.summary, new_spec.summary + + assert_equal %w[README.txt bin/exec ext/extconf.rb lib/file.rb + test/file.rb].sort, + spec.files + refute_same spec.files, new_spec.files, 'files' + + assert_equal %w[test/file.rb], spec.test_files + refute_same spec.test_files, new_spec.test_files, 'test_files' + + assert_equal %w[--foo], spec.rdoc_options + refute_same spec.rdoc_options, new_spec.rdoc_options, 'rdoc_options' + + assert_equal %w[README.txt], spec.extra_rdoc_files + refute_same spec.extra_rdoc_files, new_spec.extra_rdoc_files, + 'extra_rdoc_files' + + assert_equal %w[exec], spec.executables + refute_same spec.executables, new_spec.executables, 'executables' + + assert_equal %w[ext/extconf.rb], spec.extensions + refute_same spec.extensions, new_spec.extensions, 'extensions' + + assert_equal %w[requirement], spec.requirements + refute_same spec.requirements, new_spec.requirements, 'requirements' + + assert_equal [Gem::Dependency.new('some_gem', Gem::Requirement.default)], + spec.dependencies + refute_same spec.dependencies, new_spec.dependencies, 'dependencies' + + assert_equal 'bin', spec.bindir + assert_same spec.bindir, new_spec.bindir + + assert_equal '>= 0', spec.required_ruby_version.to_s + assert_same spec.required_ruby_version, new_spec.required_ruby_version + + assert_equal '>= 0', spec.required_rubygems_version.to_s + assert_same spec.required_rubygems_version, + new_spec.required_rubygems_version + end + + def test_initialize_copy_broken + spec = Gem::Specification.new do |s| + s.name = 'a' + s.version = '1' + end + + spec.instance_variable_set :@licenses, :blah + spec.loaded_from = '/path/to/file' + + e = assert_raises Gem::FormatException do + spec.dup + end + + assert_equal 'a-1 has an invalid value for @licenses', e.message + assert_equal '/path/to/file', e.file_path + end + + def test__dump + @a2.platform = Gem::Platform.local + @a2.instance_variable_set :@original_platform, 'old_platform' + + data = Marshal.dump @a2 + + same_spec = Marshal.load data + + assert_equal 'old_platform', same_spec.original_platform + end + + def test_activate + @a2.activate + + assert @a2.activated? + end + + def test_add_dependency_with_type + gem = util_spec "awesome", "1.0" do |awesome| + awesome.add_dependency true + awesome.add_dependency :gem_name + end + + assert_equal %w[true gem_name], gem.dependencies.map { |dep| dep.name } + end + + def test_add_dependency_with_type_explicit + gem = util_spec "awesome", "1.0" do |awesome| + awesome.add_development_dependency "monkey" + end + + monkey = gem.dependencies.detect { |d| d.name == "monkey" } + assert_equal(:development, monkey.type) + end + + def test_author + assert_equal 'A User', @a1.author + end + + def test_authors + assert_equal ['A User'], @a1.authors + end + + def test_bindir_equals + @a1.bindir = 'apps' + + assert_equal 'apps', @a1.bindir + end + + def test_bindir_equals_nil + @a2.bindir = nil + @a2.executable = 'app' + + assert_equal nil, @a2.bindir + assert_equal %w[app lib/code.rb].sort, @a2.files + end + + def test_extensions_equals_nil + @a2.instance_variable_set(:@extensions, nil) + assert_equal nil, @a2.instance_variable_get(:@extensions) + assert_equal %w[lib/code.rb], @a2.files + end + + def test_test_files_equals_nil + @a2.instance_variable_set(:@test_files, nil) + assert_equal nil, @a2.instance_variable_get(:@test_files) + assert_equal %w[lib/code.rb], @a2.files + end + + def test_executables_equals_nil + @a2.instance_variable_set(:@executables, nil) + assert_equal nil, @a2.instance_variable_get(:@executables) + assert_equal %w[lib/code.rb], @a2.files + end + + def test_extra_rdoc_files_equals_nil + @a2.instance_variable_set(:@extra_rdoc_files, nil) + assert_equal nil, @a2.instance_variable_get(:@extra_rdoc_files) + assert_equal %w[lib/code.rb], @a2.files + end + + def test_build_args + ext_spec + + assert_empty @ext.build_args + + open @ext.build_info_file, 'w' do |io| + io.puts + end + + assert_empty @ext.build_args + + open @ext.build_info_file, 'w' do |io| + io.puts '--with-foo-dir=wherever' + end + + assert_equal %w[--with-foo-dir=wherever], @ext.build_args + end + + def test_build_extensions + ext_spec + + refute_path_exists @ext.extension_dir, 'sanity check' + refute_empty @ext.extensions, 'sanity check' + + extconf_rb = File.join @ext.gem_dir, @ext.extensions.first + FileUtils.mkdir_p File.dirname extconf_rb + + open extconf_rb, 'w' do |f| + f.write <<-'RUBY' + open 'Makefile', 'w' do |f| + f.puts "clean:\n\techo clean" + f.puts "default:\n\techo built" + f.puts "install:\n\techo installed" + end + RUBY + end + + @ext.build_extensions + + assert_path_exists @ext.extension_dir + end + + def test_build_extensions_built + ext_spec + + refute_empty @ext.extensions, 'sanity check' + + gem_build_complete = + File.join @ext.extension_dir, 'gem.build_complete' + + FileUtils.mkdir_p @ext.extension_dir + FileUtils.touch gem_build_complete + + @ext.build_extensions + + gem_make_out = File.join @ext.extension_dir, 'gem_make.out' + refute_path_exists gem_make_out + end + + def test_build_extensions_default_gem + spec = new_default_spec 'default', 1 + spec.extensions << 'extconf.rb' + + extconf_rb = File.join spec.gem_dir, spec.extensions.first + FileUtils.mkdir_p File.dirname extconf_rb + + open extconf_rb, 'w' do |f| + f.write <<-'RUBY' + open 'Makefile', 'w' do |f| + f.puts "default:\n\techo built" + f.puts "install:\n\techo installed" + end + RUBY + end + + spec.build_extensions + + refute_path_exists spec.extension_dir + end + + def test_build_extensions_error + ext_spec + + refute_empty @ext.extensions, 'sanity check' + + assert_raises Gem::Ext::BuildError do + @ext.build_extensions + end + end + + def test_build_extensions_extensions_dir_unwritable + skip 'chmod not supported' if Gem.win_platform? + + ext_spec + + refute_empty @ext.extensions, 'sanity check' + + extconf_rb = File.join @ext.gem_dir, @ext.extensions.first + FileUtils.mkdir_p File.dirname extconf_rb + + open extconf_rb, 'w' do |f| + f.write <<-'RUBY' + open 'Makefile', 'w' do |f| + f.puts "clean:\n\techo clean" + f.puts "default:\n\techo built" + f.puts "install:\n\techo installed" + end + RUBY + end + + FileUtils.mkdir_p File.join @ext.base_dir, 'extensions' + FileUtils.chmod 0555, @ext.base_dir + FileUtils.chmod 0555, File.join(@ext.base_dir, 'extensions') + + @ext.build_extensions + refute_path_exists @ext.extension_dir + ensure + unless ($DEBUG or win_platform?) then + FileUtils.chmod 0755, File.join(@ext.base_dir, 'extensions') + FileUtils.chmod 0755, @ext.base_dir + end + end + + def test_build_extensions_no_extensions_dir_unwritable + skip 'chmod not supported' if Gem.win_platform? + + ext_spec + + refute_empty @ext.extensions, 'sanity check' + + extconf_rb = File.join @ext.gem_dir, @ext.extensions.first + FileUtils.mkdir_p File.dirname extconf_rb + + open extconf_rb, 'w' do |f| + f.write <<-'RUBY' + open 'Makefile', 'w' do |f| + f.puts "clean:\n\techo clean" + f.puts "default:\n\techo built" + f.puts "install:\n\techo installed" + end + RUBY + end + + FileUtils.rm_r File.join @gemhome, 'extensions' + FileUtils.chmod 0555, @gemhome + + @ext.build_extensions + + gem_make_out = File.join @ext.extension_dir, 'gem_make.out' + refute_path_exists gem_make_out + ensure + FileUtils.chmod 0755, @gemhome + end + + def test_build_extensions_none + refute_path_exists @a1.extension_dir, 'sanity check' + assert_empty @a1.extensions, 'sanity check' + + @a1.build_extensions + + refute_path_exists @a1.extension_dir + end + + def test_build_extensions_old + ext_spec + + refute_empty @ext.extensions, 'sanity check' + + @ext.installed_by_version = v(0) + + @ext.build_extensions + + gem_make_out = File.join @ext.extension_dir, 'gem_make.out' + refute_path_exists gem_make_out + end + + def test_build_extensions_preview + ext_spec + + extconf_rb = File.join @ext.gem_dir, @ext.extensions.first + FileUtils.mkdir_p File.dirname extconf_rb + + open extconf_rb, 'w' do |f| + f.write <<-'RUBY' + open 'Makefile', 'w' do |f| + f.puts "clean:\n\techo clean" + f.puts "default:\n\techo built" + f.puts "install:\n\techo installed" + end + RUBY + end + + refute_empty @ext.extensions, 'sanity check' + + @ext.installed_by_version = v('2.2.0.preview.2') + + @ext.build_extensions + + gem_make_out = File.join @ext.extension_dir, 'gem_make.out' + assert_path_exists gem_make_out + end + + def test_contains_requirable_file_eh + code_rb = File.join @a1.gem_dir, 'lib', 'code.rb' + FileUtils.mkdir_p File.dirname code_rb + FileUtils.touch code_rb + + assert @a1.contains_requirable_file? 'code' + end + + def test_contains_requirable_file_eh_extension + ext_spec + + _, err = capture_io do + refute @ext.contains_requirable_file? 'nonexistent' + end + + expected = "Ignoring ext-1 because its extensions are not built. " + + "Try: gem pristine ext --version 1\n" + + assert_equal expected, err + end + + def test_date + assert_equal Gem::Specification::TODAY, @a1.date + end + + def test_date_equals_date + @a1.date = Date.new(2003, 9, 17) + assert_equal Time.utc(2003, 9, 17, 0,0,0), @a1.date + end + + def test_date_equals_string + @a1.date = '2003-09-17' + assert_equal Time.utc(2003, 9, 17, 0,0,0), @a1.date + end + + def test_date_equals_string_bad + assert_raises Gem::InvalidSpecificationException do + @a1.date = '9/11/2003' + end + end + + def test_date_equals_time + @a1.date = Time.local(2003, 9, 17, 0,0,0) + assert_equal Time.utc(2003, 9, 17, 0,0,0), @a1.date + end + + def test_date_equals_time_local + @a1.date = Time.local(2003, 9, 17, 19,50,0) # may not pass in utc >= +4 + assert_equal Time.utc(2003, 9, 17, 0,0,0), @a1.date + end + + def test_date_equals_time_utc + @a1.date = Time.utc(2003, 9, 17, 19,50,0) + assert_equal Time.utc(2003, 9, 17, 0,0,0), @a1.date + end + + def test_date_tolerates_hour_sec_zulu + @a1.date = "2012-01-12 11:22:33.4444444 Z" + assert_equal Time.utc(2012,01,12,0,0,0), @a1.date + end + + def test_date_tolerates_hour_sec_and_timezone + @a1.date = "2012-01-12 11:22:33.4444444 +02:33" + assert_equal Time.utc(2012,01,12,0,0,0), @a1.date + end + + def test_dependencies + util_setup_deps + assert_equal [@bonobo, @monkey], @gem.dependencies + end + + def test_dependent_gems + util_setup_deps + + assert_empty @gem.dependent_gems + + bonobo = util_spec 'bonobo' + + expected = [ + [@gem, @bonobo, [bonobo]], + ] + + assert_equal expected, bonobo.dependent_gems + end + + def test_doc_dir + assert_equal File.join(@gemhome, 'doc', 'a-1'), @a1.doc_dir + end + + def test_doc_dir_type + assert_equal File.join(@gemhome, 'doc', 'a-1', 'ri'), @a1.doc_dir('ri') + end + + def test_runtime_dependencies + util_setup_deps + assert_equal [@bonobo], @gem.runtime_dependencies + end + + def test_development_dependencies + util_setup_deps + assert_equal [@monkey], @gem.development_dependencies + end + + def test_description + assert_equal 'This is a test description', @a1.description + end + + def test_eql_eh + g1 = new_spec 'gem', 1 + g2 = new_spec 'gem', 1 + + assert_equal g1, g2 + assert_equal g1.hash, g2.hash + assert_equal true, g1.eql?(g2) + end + + def test_eql_eh_extensions + spec = @a1.dup + spec.extensions = 'xx' + + refute_operator @a1, :eql?, spec + refute_operator spec, :eql?, @a1 + end + + def test_executables + @a1.executable = 'app' + assert_equal %w[app], @a1.executables + end + + def test_executable_equals + @a2.executable = 'app' + assert_equal 'app', @a2.executable + assert_equal %w[bin/app lib/code.rb].sort, @a2.files + end + + def test_extensions + assert_equal ['ext/extconf.rb'], ext_spec.extensions + end + + def test_extension_dir + enable_shared, RbConfig::CONFIG['ENABLE_SHARED'] = + RbConfig::CONFIG['ENABLE_SHARED'], 'no' + + ext_spec + + refute_empty @ext.extensions + + expected = + File.join(@ext.base_dir, 'extensions', Gem::Platform.local.to_s, + "#{Gem.ruby_api_version}-static", @ext.full_name) + + assert_equal expected, @ext.extension_dir + ensure + RbConfig::CONFIG['ENABLE_SHARED'] = enable_shared + end + + def test_extension_dir_override + enable_shared, RbConfig::CONFIG['ENABLE_SHARED'] = + RbConfig::CONFIG['ENABLE_SHARED'], 'no' + + class << Gem + alias orig_default_ext_dir_for default_ext_dir_for + + def Gem.default_ext_dir_for(base_dir) + 'elsewhere' + end + end + + ext_spec + + refute_empty @ext.extensions + + expected = File.join @tempdir, 'elsewhere', @ext.full_name + + assert_equal expected, @ext.extension_dir + ensure + RbConfig::CONFIG['ENABLE_SHARED'] = enable_shared + + class << Gem + remove_method :default_ext_dir_for + + alias default_ext_dir_for orig_default_ext_dir_for + end + end + + def test_files + @a1.files = %w(files bin/common) + @a1.test_files = %w(test_files bin/common) + @a1.executables = %w(executables common) + @a1.extra_rdoc_files = %w(extra_rdoc_files bin/common) + @a1.extensions = %w(extensions bin/common) + + expected = %w[ + bin/common + bin/executables + extensions + extra_rdoc_files + files + test_files + ] + assert_equal expected, @a1.files + end + + def test_files_append + @a1.files = %w(files bin/common) + @a1.test_files = %w(test_files bin/common) + @a1.executables = %w(executables common) + @a1.extra_rdoc_files = %w(extra_rdoc_files bin/common) + @a1.extensions = %w(extensions bin/common) + + expected = %w[ + bin/common + bin/executables + extensions + extra_rdoc_files + files + test_files + ] + assert_equal expected, @a1.files + + @a1.files << "generated_file.c" + + expected << "generated_file.c" + expected.sort! + + assert_equal expected, @a1.files + end + + def test_files_duplicate + @a2.files = %w[a b c d b] + @a2.extra_rdoc_files = %w[x y z x] + @a2.normalize + + assert_equal %w[a b c d x y z], @a2.files + assert_equal %w[x y z], @a2.extra_rdoc_files + end + + def test_files_extra_rdoc_files + @a2.files = %w[a b c d] + @a2.extra_rdoc_files = %w[x y z] + @a2.normalize + assert_equal %w[a b c d x y z], @a2.files + end + + def test_files_non_array + @a1.files = "F" + @a1.test_files = "TF" + @a1.executables = "X" + @a1.extra_rdoc_files = "ERF" + @a1.extensions = "E" + + assert_equal %w[E ERF F TF bin/X], @a1.files + end + + def test_files_non_array_pathological + @a1.instance_variable_set :@files, "F" + @a1.instance_variable_set :@test_files, "TF" + @a1.instance_variable_set :@extra_rdoc_files, "ERF" + @a1.instance_variable_set :@extensions, "E" + @a1.instance_variable_set :@executables, "X" + + assert_equal %w[E ERF F TF bin/X], @a1.files + assert_kind_of Integer, @a1.hash + end + + def test_for_cache + @a2.add_runtime_dependency 'b', '1' + @a2.dependencies.first.instance_variable_set :@type, nil + @a2.required_rubygems_version = Gem::Requirement.new '> 0' + @a2.test_files = %w[test/test_b.rb] + + refute_empty @a2.files + refute_empty @a2.test_files + + spec = @a2.for_cache + + assert_empty spec.files + assert_empty spec.test_files + + refute_empty @a2.files + refute_empty @a2.test_files + end + + def test_full_gem_path + assert_equal File.join(@gemhome, 'gems', @a1.full_name), @a1.full_gem_path + + @a1.original_platform = 'mswin32' + + assert_equal File.join(@gemhome, 'gems', @a1.original_name), + @a1.full_gem_path + end + + def test_full_gem_path_double_slash + gemhome = @gemhome.to_s.sub(/\w\//, '\&/') + @a1.loaded_from = File.join gemhome, "specifications", @a1.spec_name + + expected = File.join @gemhome, "gems", @a1.full_name + assert_equal expected, @a1.full_gem_path + end + + def test_full_name + assert_equal 'a-1', @a1.full_name + + @a1 = Gem::Specification.new "a", 1 + @a1.platform = Gem::Platform.new ['universal', 'darwin', nil] + assert_equal 'a-1-universal-darwin', @a1.full_name + + @a1 = Gem::Specification.new "a", 1 + @a1.instance_variable_set :@new_platform, 'mswin32' + assert_equal 'a-1-mswin32', @a1.full_name, 'legacy' + + return if win_platform? + + @a1 = Gem::Specification.new "a", 1 + @a1.platform = 'current' + assert_equal 'a-1-x86-darwin-8', @a1.full_name + end + + def test_full_name_windows + test_cases = { + 'i386-mswin32' => 'a-1-x86-mswin32-60', + 'i386-mswin32_80' => 'a-1-x86-mswin32-80', + 'i386-mingw32' => 'a-1-x86-mingw32' + } + + test_cases.each do |arch, expected| + @a1 = Gem::Specification.new "a", 1 + util_set_arch arch + @a1.platform = 'current' + assert_equal expected, @a1.full_name + end + end + + def test_gem_build_complete_path + expected = File.join @a1.extension_dir, 'gem.build_complete' + assert_equal expected, @a1.gem_build_complete_path + end + + def test_hash + assert_equal @a1.hash, @a1.hash + assert_equal @a1.hash, @a1.dup.hash + refute_equal @a1.hash, @a2.hash + end + + def test_installed_by_version + assert_equal v(0), @a1.installed_by_version + + @a1.installed_by_version = Gem.rubygems_version + + assert_equal Gem.rubygems_version, @a1.installed_by_version + end + + def test_base_dir + assert_equal @gemhome, @a1.base_dir + end + + def test_base_dir_not_loaded + @a1.instance_variable_set :@loaded_from, nil + + assert_equal Gem.dir, @a1.base_dir + end + + def test_base_dir_default + default_dir = + File.join Gem::Specification.default_specifications_dir, @a1.spec_name + + @a1.instance_variable_set :@loaded_from, default_dir + + assert_equal Gem.default_dir, @a1.base_dir + end + + def test_lib_files + @a1.files = %w[lib/foo.rb Rakefile] + + assert_equal %w[lib/foo.rb], @a1.lib_files + end + + def test_license + assert_equal 'MIT', @a1.license + end + + def test_licenses + assert_equal ['MIT'], @a1.licenses + end + + def test_name + assert_equal 'a', @a1.name + end + + def test_original_name + assert_equal 'a-1', @a1.full_name + + @a1.platform = 'i386-linux' + @a1.instance_variable_set :@original_platform, 'i386-linux' + assert_equal 'a-1-i386-linux', @a1.original_name + end + + def test_platform + assert_equal Gem::Platform::RUBY, @a1.platform + end + + def test_platform_change_reset_full_name + orig_full_name = @a1.full_name + + @a1.platform = "universal-unknown" + refute_equal orig_full_name, @a1.full_name + end + + def test_platform_change_reset_cache_file + orig_cache_file = @a1.cache_file + + @a1.platform = "universal-unknown" + refute_equal orig_cache_file, @a1.cache_file + end + + def test_platform_equals + @a1.platform = nil + assert_equal Gem::Platform::RUBY, @a1.platform + + @a1.platform = Gem::Platform::RUBY + assert_equal Gem::Platform::RUBY, @a1.platform + + test_cases = { + 'i386-mswin32' => ['x86', 'mswin32', '60'], + 'i386-mswin32_80' => ['x86', 'mswin32', '80'], + 'i386-mingw32' => ['x86', 'mingw32', nil ], + 'x86-darwin8' => ['x86', 'darwin', '8' ], + } + + test_cases.each do |arch, expected| + util_set_arch arch + @a1.platform = Gem::Platform::CURRENT + assert_equal Gem::Platform.new(expected), @a1.platform + end + end + + def test_platform_equals_current + @a1.platform = Gem::Platform::CURRENT + assert_equal Gem::Platform.local, @a1.platform + assert_equal Gem::Platform.local.to_s, @a1.original_platform + end + + def test_platform_equals_legacy + @a1.platform = 'mswin32' + assert_equal Gem::Platform.new('x86-mswin32'), @a1.platform + + @a1.platform = 'i586-linux' + assert_equal Gem::Platform.new('x86-linux'), @a1.platform + + @a1.platform = 'powerpc-darwin' + assert_equal Gem::Platform.new('ppc-darwin'), @a1.platform + end + + def test_prerelease_spec_adds_required_rubygems_version + @prerelease = util_spec('tardis', '2.2.0.a') + refute @prerelease.required_rubygems_version.satisfied_by?(Gem::Version.new('1.3.1')) + assert @prerelease.required_rubygems_version.satisfied_by?(Gem::Version.new('1.4.0')) + end + + def test_require_paths + enable_shared 'no' do + ext_spec + + @ext.require_paths = 'lib' + + assert_equal [@ext.extension_dir, 'lib'], @ext.require_paths + end + end + + def test_require_paths_default_ext_dir_for + class << Gem + send :alias_method, :orig_default_ext_dir_for, :default_ext_dir_for + end + + def Gem.default_ext_dir_for base_dir + '/foo' + end + + enable_shared 'no' do + ext_spec + + @ext.require_paths = 'lib' + + assert_equal [File.expand_path('/foo/ext-1'), 'lib'], @ext.require_paths + end + ensure + class << Gem + send :remove_method, :default_ext_dir_for + send :alias_method, :default_ext_dir_for, :orig_default_ext_dir_for + send :remove_method, :orig_default_ext_dir_for + end + end + + def test_source + assert_kind_of Gem::Source::Installed, @a1.source + end + + def test_source_paths + ext_spec + + @ext.require_paths = %w[lib ext foo] + @ext.extensions << 'bar/baz' + + expected = %w[ + lib + ext + foo + bar + ] + + assert_equal expected, @ext.source_paths + end + + def test_full_require_paths + ext_spec + + @ext.require_paths = 'lib' + + expected = [ + @ext.extension_dir, + File.join(@gemhome, 'gems', @ext.original_name, 'lib'), + ] + + assert_equal expected, @ext.full_require_paths + end + + def test_to_fullpath + ext_spec + + @ext.require_paths = 'lib' + + dir = File.join(@gemhome, 'gems', @ext.original_name, 'lib') + expected_rb = File.join(dir, 'code.rb') + FileUtils.mkdir_p dir + FileUtils.touch expected_rb + + dir = @ext.extension_dir + ext = RbConfig::CONFIG["DLEXT"] + expected_so = File.join(dir, "ext.#{ext}") + FileUtils.mkdir_p dir + FileUtils.touch expected_so + + assert_nil @ext.to_fullpath("code") + assert_nil @ext.to_fullpath("code.rb") + assert_nil @ext.to_fullpath("code.#{ext}") + + assert_nil @ext.to_fullpath("ext") + assert_nil @ext.to_fullpath("ext.rb") + assert_nil @ext.to_fullpath("ext.#{ext}") + + @ext.activate + + assert_equal expected_rb, @ext.to_fullpath("code") + assert_equal expected_rb, @ext.to_fullpath("code.rb") + assert_nil @ext.to_fullpath("code.#{ext}") + + assert_equal expected_so, @ext.to_fullpath("ext") + assert_nil @ext.to_fullpath("ext.rb") + assert_equal expected_so, @ext.to_fullpath("ext.#{ext}") + + assert_nil @ext.to_fullpath("notexist") + end + + def test_require_already_activated + save_loaded_features do + a1 = new_spec "a", "1", nil, "lib/d.rb" + + install_specs a1 # , a2, b1, b2, c1, c2 + + a1.activate + assert_equal %w(a-1), loaded_spec_names + assert_equal [], unresolved_names + + assert require "d" + + assert_equal %w(a-1), loaded_spec_names + assert_equal [], unresolved_names + end + end + + def test_require_already_activated_indirect_conflict + save_loaded_features do + a1 = new_spec "a", "1", "b" => "> 0" + a2 = new_spec "a", "2", "b" => "> 0" + b1 = new_spec "b", "1", "c" => ">= 1" + b2 = new_spec "b", "2", "c" => ">= 2" + c1 = new_spec "c", "1", nil, "lib/d.rb" + c2 = new_spec("c", "2", { "a" => "1" }, "lib/d.rb") # conflicts with a-2 + + install_specs a1, a2, b1, b2, c1, c2 + + a1.activate + c1.activate + assert_equal %w(a-1 c-1), loaded_spec_names + assert_equal ["b (> 0)"], unresolved_names + + assert require "d" + + assert_equal %w(a-1 c-1), loaded_spec_names + assert_equal ["b (> 0)"], unresolved_names + end + end + + def test_requirements + assert_equal ['A working computer'], @a1.requirements + end + + def test_allowed_push_host + assert_equal nil, @a1.metadata['allowed_push_host'] + assert_equal 'https://privategemserver.com', @a3.metadata['allowed_push_host'] + end + + def test_runtime_dependencies_legacy + make_spec_c1 + # legacy gems don't have a type + @c1.runtime_dependencies.each do |dep| + dep.instance_variable_set :@type, nil + end + + expected = %w[rake jabber4r pqa] + + assert_equal expected, @c1.runtime_dependencies.map { |d| d.name } + end + + def test_spaceship_name + s1 = new_spec 'a', '1' + s2 = new_spec 'b', '1' + + assert_equal(-1, (s1 <=> s2)) + assert_equal( 0, (s1 <=> s1)) + assert_equal( 1, (s2 <=> s1)) + end + + def test_spaceship_platform + s1 = new_spec 'a', '1' + s2 = new_spec 'a', '1' do |s| + s.platform = Gem::Platform.new 'x86-my_platform1' + end + + assert_equal( -1, (s1 <=> s2)) + assert_equal( 0, (s1 <=> s1)) + assert_equal( 1, (s2 <=> s1)) + end + + def test_spaceship_version + s1 = new_spec 'a', '1' + s2 = new_spec 'a', '2' + + assert_equal( -1, (s1 <=> s2)) + assert_equal( 0, (s1 <=> s1)) + assert_equal( 1, (s2 <=> s1)) + end + + def test_spec_file + assert_equal File.join(@gemhome, 'specifications', 'a-1.gemspec'), + @a1.spec_file + end + + def test_spec_name + assert_equal 'a-1.gemspec', @a1.spec_name + end + + def test_summary + assert_equal 'this is a summary', @a1.summary + end + + def test_test_files + @a1.test_file = 'test/suite.rb' + assert_equal ['test/suite.rb'], @a1.test_files + end + + def test_to_ruby + @a2.add_runtime_dependency 'b', '1' + @a2.dependencies.first.instance_variable_set :@type, nil + @a2.required_rubygems_version = Gem::Requirement.new '> 0' + @a2.require_paths << 'other' + + ruby_code = @a2.to_ruby + + expected = <<-SPEC +# -*- encoding: utf-8 -*- +# stub: a 2 ruby lib\0other + +Gem::Specification.new do |s| + s.name = "a" + s.version = "2" + + s.required_rubygems_version = Gem::Requirement.new(\"> 0\") if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib", "other"] + s.authors = ["A User"] + s.date = "#{Gem::Specification::TODAY.strftime "%Y-%m-%d"}" + s.description = "This is a test description" + s.email = "example@example.com" + s.files = ["lib/code.rb"] + s.homepage = "http://example.com" + s.rubygems_version = "#{Gem::VERSION}" + s.summary = "this is a summary" + + if s.respond_to? :specification_version then + s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION} + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_runtime_dependency(%q<b>, [\"= 1\"]) + else + s.add_dependency(%q<b>, [\"= 1\"]) + end + else + s.add_dependency(%q<b>, [\"= 1\"]) + end +end + SPEC + + assert_equal expected, ruby_code + + same_spec = eval ruby_code + + assert_equal @a2, same_spec + end + + def test_to_ruby_for_cache + @a2.add_runtime_dependency 'b', '1' + @a2.dependencies.first.instance_variable_set :@type, nil + @a2.required_rubygems_version = Gem::Requirement.new '> 0' + @a2.installed_by_version = Gem.rubygems_version + + # cached specs do not have spec.files populated: + ruby_code = @a2.to_ruby_for_cache + + expected = <<-SPEC +# -*- encoding: utf-8 -*- +# stub: a 2 ruby lib + +Gem::Specification.new do |s| + s.name = "a" + s.version = "2" + + s.required_rubygems_version = Gem::Requirement.new(\"> 0\") if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib"] + s.authors = ["A User"] + s.date = "#{Gem::Specification::TODAY.strftime "%Y-%m-%d"}" + s.description = "This is a test description" + s.email = "example@example.com" + s.homepage = "http://example.com" + s.rubygems_version = "#{Gem::VERSION}" + s.summary = "this is a summary" + + s.installed_by_version = "#{Gem::VERSION}" if s.respond_to? :installed_by_version + + if s.respond_to? :specification_version then + s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION} + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_runtime_dependency(%q<b>, [\"= 1\"]) + else + s.add_dependency(%q<b>, [\"= 1\"]) + end + else + s.add_dependency(%q<b>, [\"= 1\"]) + end +end + SPEC + + assert_equal expected, ruby_code + + same_spec = eval ruby_code + + # cached specs do not have spec.files populated: + @a2.files = [] + assert_equal @a2, same_spec + end + + def test_to_ruby_fancy + make_spec_c1 + + @c1.platform = Gem::Platform.local + ruby_code = @c1.to_ruby + + local = Gem::Platform.local + expected_platform = "[#{local.cpu.inspect}, #{local.os.inspect}, #{local.version.inspect}]" + stub_require_paths = + @c1.instance_variable_get(:@require_paths).join "\u0000" + extensions = @c1.extensions.join "\u0000" + + expected = <<-SPEC +# -*- encoding: utf-8 -*- +# stub: a 1 #{win_platform? ? "x86-mswin32-60" : "x86-darwin-8"} #{stub_require_paths} +# stub: #{extensions} + +Gem::Specification.new do |s| + s.name = "a" + s.version = "1" + s.platform = Gem::Platform.new(#{expected_platform}) + + s.required_rubygems_version = Gem::Requirement.new(\">= 0\") if s.respond_to? :required_rubygems_version= + s.require_paths = ["lib"] + s.authors = ["A User"] + s.date = "#{Gem::Specification::TODAY.strftime "%Y-%m-%d"}" + s.description = "This is a test description" + s.email = "example@example.com" + s.executables = ["exec"] + s.extensions = ["ext/a/extconf.rb"] + s.files = ["bin/exec", "ext/a/extconf.rb", "lib/code.rb", "test/suite.rb"] + s.homepage = "http://example.com" + s.licenses = ["MIT"] + s.requirements = ["A working computer"] + s.rubyforge_project = "example" + s.rubygems_version = "#{Gem::VERSION}" + s.summary = "this is a summary" + s.test_files = ["test/suite.rb"] + + if s.respond_to? :specification_version then + s.specification_version = 4 + + if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then + s.add_runtime_dependency(%q<rake>, [\"> 0.4\"]) + s.add_runtime_dependency(%q<jabber4r>, [\"> 0.0.0\"]) + s.add_runtime_dependency(%q<pqa>, [\"<= 0.6\", \"> 0.4\"]) + else + s.add_dependency(%q<rake>, [\"> 0.4\"]) + s.add_dependency(%q<jabber4r>, [\"> 0.0.0\"]) + s.add_dependency(%q<pqa>, [\"<= 0.6\", \"> 0.4\"]) + end + else + s.add_dependency(%q<rake>, [\"> 0.4\"]) + s.add_dependency(%q<jabber4r>, [\"> 0.0.0\"]) + s.add_dependency(%q<pqa>, [\"<= 0.6\", \"> 0.4\"]) + end +end + SPEC + + assert_equal expected, ruby_code + + same_spec = eval ruby_code + + assert_equal @c1, same_spec + end + + def test_to_ruby_legacy + gemspec1 = Gem::Deprecate.skip_during do + eval LEGACY_RUBY_SPEC + end + ruby_code = gemspec1.to_ruby + gemspec2 = eval ruby_code + + assert_equal gemspec1, gemspec2 + end + + def test_to_ruby_nested_hash + metadata = {} + metadata[metadata] = metadata + + @a2.metadata = metadata + + ruby = @a2.to_ruby + + assert_match %r%^ s\.metadata = \{ "%, ruby + end + + def test_to_ruby_platform + @a2.platform = Gem::Platform.local + @a2.instance_variable_set :@original_platform, 'old_platform' + + ruby_code = @a2.to_ruby + + same_spec = eval ruby_code + + assert_equal 'old_platform', same_spec.original_platform + end + + def test_to_yaml + yaml_str = @a1.to_yaml + + refute_match '!!null', yaml_str + + same_spec = Gem::Specification.from_yaml(yaml_str) + + assert_equal @a1, same_spec + end + + def test_to_yaml_fancy + @a1.platform = Gem::Platform.local + yaml_str = @a1.to_yaml + + same_spec = Gem::Specification.from_yaml(yaml_str) + + assert_equal Gem::Platform.local, same_spec.platform + + assert_equal @a1, same_spec + end + + def test_to_yaml_platform_empty_string + @a1.instance_variable_set :@original_platform, '' + + assert_match %r|^platform: ruby$|, @a1.to_yaml + end + + def test_to_yaml_platform_legacy + @a1.platform = 'powerpc-darwin7.9.0' + @a1.instance_variable_set :@original_platform, 'powerpc-darwin7.9.0' + + yaml_str = @a1.to_yaml + + same_spec = YAML.load yaml_str + + assert_equal Gem::Platform.new('powerpc-darwin7'), same_spec.platform + assert_equal 'powerpc-darwin7.9.0', same_spec.original_platform + end + + def test_to_yaml_platform_nil + @a1.instance_variable_set :@original_platform, nil + + assert_match %r|^platform: ruby$|, @a1.to_yaml + end + + def test_validate + util_setup_validate + + Dir.chdir @tempdir do + assert @a1.validate + end + end + + def x s; s.gsub(/xxx/, ''); end + def w; x "WARxxxNING"; end + def t; x "TOxxxDO"; end + def f; x "FxxxIXME"; end + + def test_validate_authors + util_setup_validate + + Dir.chdir @tempdir do + @a1.authors = [""] + + use_ui @ui do + @a1.validate + end + + assert_match "#{w}: no author specified\n", @ui.error, 'error' + + @a1.authors = [Object.new] + + assert_equal [], @a1.authors + + e = assert_raises Gem::InvalidSpecificationException do + @a1.validate + end + + assert_equal "authors may not be empty", e.message + + @a1.authors = ["#{f} (who is writing this software)"] + + e = assert_raises Gem::InvalidSpecificationException do + @a1.validate + end + + assert_equal %{"#{f}" or "#{t}" is not an author}, e.message + + @a1.authors = ["#{t} (who is writing this software)"] + + e = assert_raises Gem::InvalidSpecificationException do + @a1.validate + end + + assert_equal %{"#{f}" or "#{t}" is not an author}, e.message + end + end + + def test_validate_autorequire + util_setup_validate + + Dir.chdir @tempdir do + @a1.autorequire = 'code' + + use_ui @ui do + @a1.validate + end + + assert_match "#{w}: deprecated autorequire specified\n", + @ui.error, 'error' + end + end + + def test_validate_dependencies + util_setup_validate + + Dir.chdir @tempdir do + @a1.add_runtime_dependency 'b', '>= 1.0.rc1' + @a1.add_development_dependency 'c', '>= 2.0.rc2' + @a1.add_runtime_dependency 'd', '~> 1.2.3' + @a1.add_runtime_dependency 'e', '~> 1.2.3.4' + @a1.add_runtime_dependency 'g', '~> 1.2.3', '>= 1.2.3.4' + @a1.add_runtime_dependency 'h', '>= 1.2.3', '<= 2' + @a1.add_runtime_dependency 'i', '>= 1.2' + @a1.add_runtime_dependency 'j', '>= 1.2.3' + @a1.add_runtime_dependency 'k', '> 1.2' + @a1.add_runtime_dependency 'l', '> 1.2.3' + @a1.add_runtime_dependency 'm', '~> 2.1.0' + @a1.add_runtime_dependency 'n', '~> 0.1.0' + + use_ui @ui do + @a1.validate + end + + expected = <<-EXPECTED +#{w}: prerelease dependency on b (>= 1.0.rc1) is not recommended +#{w}: prerelease dependency on c (>= 2.0.rc2, development) is not recommended +#{w}: pessimistic dependency on d (~> 1.2.3) may be overly strict + if d is semantically versioned, use: + add_runtime_dependency 'd', '~> 1.2', '>= 1.2.3' +#{w}: pessimistic dependency on e (~> 1.2.3.4) may be overly strict + if e is semantically versioned, use: + add_runtime_dependency 'e', '~> 1.2', '>= 1.2.3.4' +#{w}: open-ended dependency on i (>= 1.2) is not recommended + if i is semantically versioned, use: + add_runtime_dependency 'i', '~> 1.2' +#{w}: open-ended dependency on j (>= 1.2.3) is not recommended + if j is semantically versioned, use: + add_runtime_dependency 'j', '~> 1.2', '>= 1.2.3' +#{w}: open-ended dependency on k (> 1.2) is not recommended + if k is semantically versioned, use: + add_runtime_dependency 'k', '~> 1.2', '> 1.2' +#{w}: open-ended dependency on l (> 1.2.3) is not recommended + if l is semantically versioned, use: + add_runtime_dependency 'l', '~> 1.2', '> 1.2.3' +#{w}: pessimistic dependency on m (~> 2.1.0) may be overly strict + if m is semantically versioned, use: + add_runtime_dependency 'm', '~> 2.1', '>= 2.1.0' +#{w}: See http://guides.rubygems.org/specification-reference/ for help + EXPECTED + + assert_equal expected, @ui.error, 'warning' + end + end + + def test_validate_dependencies_open_ended + util_setup_validate + + Dir.chdir @tempdir do + @a1.add_runtime_dependency 'b', '~> 1.2' + @a1.add_runtime_dependency 'b', '>= 1.2.3' + + use_ui @ui do + e = assert_raises Gem::InvalidSpecificationException do + @a1.validate + end + + expected = <<-EXPECTED +duplicate dependency on b (>= 1.2.3), (~> 1.2) use: + add_runtime_dependency 'b', '>= 1.2.3', '~> 1.2' + EXPECTED + + assert_equal expected, e.message + end + + assert_equal <<-EXPECTED, @ui.error +#{w}: See http://guides.rubygems.org/specification-reference/ for help + EXPECTED + end + end + + def test_validate_description + util_setup_validate + + Dir.chdir @tempdir do + @a1.description = '' + + use_ui @ui do + @a1.validate + end + + assert_match "#{w}: no description specified\n", @ui.error, "error" + + @ui = Gem::MockGemUi.new + @a1.summary = "this is my summary" + @a1.description = @a1.summary + + use_ui @ui do + @a1.validate + end + + assert_match "#{w}: description and summary are identical\n", + @ui.error, "error" + + @a1.description = "#{f} (describe your package)" + + e = assert_raises Gem::InvalidSpecificationException do + @a1.validate + end + + assert_equal %{"#{f}" or "#{t}" is not a description}, e.message + + @a1.description = "#{t} (describe your package)" + + e = assert_raises Gem::InvalidSpecificationException do + @a1.validate + end + + assert_equal %{"#{f}" or "#{t}" is not a description}, e.message + end + end + + def test_validate_email + util_setup_validate + + Dir.chdir @tempdir do + @a1.email = "" + + use_ui @ui do + @a1.validate + end + + assert_match "#{w}: no email specified\n", @ui.error, "error" + + @a1.email = "FIxxxXME (your e-mail)".sub(/xxx/, "") + + e = assert_raises Gem::InvalidSpecificationException do + @a1.validate + end + + assert_equal %{"#{f}" or "#{t}" is not an email}, e.message + + @a1.email = "#{t} (your e-mail)" + + e = assert_raises Gem::InvalidSpecificationException do + @a1.validate + end + + assert_equal %{"#{f}" or "#{t}" is not an email}, e.message + end + end + + def test_validate_empty + e = assert_raises Gem::InvalidSpecificationException do + Gem::Specification.new.validate + end + + assert_equal 'missing value for attribute name', e.message + end + + def test_validate_error + assert_raises Gem::InvalidSpecificationException do + use_ui @ui do + Gem::Specification.new.validate + end + end + + assert_match 'See http://guides.rubygems.org/specification-reference/ for help', @ui.error + end + + def test_validate_executables + util_setup_validate + + FileUtils.mkdir_p File.join(@tempdir, 'bin') + File.open File.join(@tempdir, 'bin', 'exec'), 'w' do end + FileUtils.mkdir_p File.join(@tempdir, 'exec') + + use_ui @ui do + Dir.chdir @tempdir do + assert @a1.validate + end + end + + assert_equal %w[exec], @a1.executables + + assert_equal '', @ui.output, 'output' + assert_match "#{w}: bin/exec is missing #! line\n", @ui.error, 'error' + end + + def test_validate_empty_require_paths + if win_platform? then + skip 'test_validate_empty_require_paths skipped on MS Windows (symlink)' + else + util_setup_validate + + @a1.require_paths = [] + e = assert_raises Gem::InvalidSpecificationException do + @a1.validate + end + + assert_equal 'specification must have at least one require_path', + e.message + end + end + + def test_validate_files + skip 'test_validate_files skipped on MS Windows (symlink)' if win_platform? + util_setup_validate + + @a1.files += ['lib', 'lib2'] + @a1.extensions << 'ext/a/extconf.rb' + + Dir.chdir @tempdir do + FileUtils.ln_s '/root/path', 'lib2' unless vc_windows? + + e = assert_raises Gem::InvalidSpecificationException do + @a1.validate + end + + assert_equal '["lib2"] are not files', e.message + end + + assert_equal %w[bin/exec ext/a/extconf.rb lib/code.rb lib2 test/suite.rb].sort, + @a1.files + end + + def test_validate_files_recursive + util_setup_validate + FileUtils.touch @a1.file_name + + @a1.files = [@a1.file_name] + + e = assert_raises Gem::InvalidSpecificationException do + @a1.validate + end + + assert_equal "#{@a1.full_name} contains itself (#{@a1.file_name}), check your files list", + e.message + end + + def test_validate_homepage + util_setup_validate + + Dir.chdir @tempdir do + @a1.homepage = nil + + use_ui @ui do + @a1.validate + end + + assert_match "#{w}: no homepage specified\n", @ui.error, 'error' + + @ui = Gem::MockGemUi.new + + @a1.homepage = '' + + use_ui @ui do + @a1.validate + end + + assert_match "#{w}: no homepage specified\n", @ui.error, 'error' + + @a1.homepage = 'over at my cool site' + + e = assert_raises Gem::InvalidSpecificationException do + @a1.validate + end + + assert_equal '"over at my cool site" is not a URI', e.message + end + end + + def test_validate_license + util_setup_validate + + use_ui @ui do + @a1.licenses.clear + @a1.validate + end + + assert_match <<-warning, @ui.error +WARNING: licenses is empty, but is recommended. Use a license abbreviation from: +http://opensource.org/licenses/alphabetical + warning + end + + def test_validate_name + util_setup_validate + + e = assert_raises Gem::InvalidSpecificationException do + @a1.name = :json + @a1.validate + end + + assert_equal 'invalid value for attribute name: ":json"', e.message + end + + def test_validate_non_nil + util_setup_validate + + Dir.chdir @tempdir do + assert @a1.validate + + Gem::Specification.non_nil_attributes.each do |name| + next if name == :files # set by #normalize + spec = @a1.dup + spec.instance_variable_set "@#{name}", nil + + e = assert_raises Gem::InvalidSpecificationException do + spec.validate + end + + assert_match %r%^#{name}%, e.message + end + end + end + + def test_validate_permissions + skip 'chmod not supported' if Gem.win_platform? + + util_setup_validate + + Dir.chdir @tempdir do + File.chmod 0640, File.join('lib', 'code.rb') + File.chmod 0640, File.join('bin', 'exec') + + use_ui @ui do + @a1.validate + end + + assert_match "#{w}: lib/code.rb is not world-readable\n", @ui.error + assert_match "#{w}: bin/exec is not world-readable\n", @ui.error + assert_match "#{w}: bin/exec is not executable\n", @ui.error + end + end + + def test_validate_platform_legacy + util_setup_validate + + Dir.chdir @tempdir do + @a1.platform = 'mswin32' + assert @a1.validate + + @a1.platform = 'i586-linux' + assert @a1.validate + + @a1.platform = 'powerpc-darwin' + assert @a1.validate + end + end + + def test_validate_rubygems_version + util_setup_validate + + @a1.rubygems_version = "3" + e = assert_raises Gem::InvalidSpecificationException do + @a1.validate + end + + assert_equal "expected RubyGems version #{Gem::VERSION}, was 3", + e.message + end + + def test_validate_specification_version + util_setup_validate + + Dir.chdir @tempdir do + @a1.specification_version = '1.0' + + e = assert_raises Gem::InvalidSpecificationException do + use_ui @ui do + @a1.validate + end + end + + err = 'specification_version must be a Fixnum (did you mean version?)' + assert_equal err, e.message + end + end + + def test_validate_summary + util_setup_validate + + Dir.chdir @tempdir do + @a1.summary = '' + + use_ui @ui do + @a1.validate + end + + assert_match "#{w}: no summary specified\n", @ui.error, 'error' + + @a1.summary = "#{f} (describe your package)" + + e = assert_raises Gem::InvalidSpecificationException do + @a1.validate + end + + assert_equal %{"#{f}" or "#{t}" is not a summary}, e.message + + @a1.summary = "#{t} (describe your package)" + + e = assert_raises Gem::InvalidSpecificationException do + @a1.validate + end + + assert_equal %{"#{f}" or "#{t}" is not a summary}, e.message + end + end + + def test_validate_warning + util_setup_validate + + use_ui @ui do + @a1.licenses.clear + @a1.validate + end + + assert_match 'See http://guides.rubygems.org/specification-reference/ for help', @ui.error + end + + def test_version + assert_equal Gem::Version.new('1'), @a1.version + end + + def test_version_change_reset_full_name + orig_full_name = @a1.full_name + + @a1.version = "2" + + refute_equal orig_full_name, @a1.full_name + end + + def test_version_change_reset_cache_file + orig_cache_file = @a1.cache_file + + @a1.version = "2" + + refute_equal orig_cache_file, @a1.cache_file + end + + def test__load_fixes_Date_objects + spec = new_spec "a", 1 + spec.instance_variable_set :@date, Date.today + + spec = Marshal.load Marshal.dump(spec) + + assert_kind_of Time, spec.date + end + + def test_load_errors_contain_filename + specfile = Tempfile.new(self.class.name.downcase) + specfile.write "raise 'boom'" + specfile.close + begin + capture_io do + Gem::Specification.load(specfile.path) + end + rescue => e + name_rexp = Regexp.new(Regexp.escape(specfile.path)) + assert e.backtrace.grep(name_rexp).any? + end + ensure + specfile.delete + end + + ## + # KEEP p-1-x86-darwin-8 + # KEEP p-1 + # KEEP c-1.2 + # KEEP a_evil-9 + # a-1 + # a-1-x86-my_platform-1 + # KEEP a-2 + # a-2-x86-other_platform-1 + # KEEP a-2-x86-my_platform-1 + # a-3.a + # KEEP a-3-x86-other_platform-1 + + def test_latest_specs + spec_fetcher do |fetcher| + fetcher.spec 'a', 1 do |s| + s.platform = Gem::Platform.new 'x86-my_platform1' + end + + fetcher.spec 'a', 2 + + fetcher.spec 'a', 2 do |s| + s.platform = Gem::Platform.new 'x86-my_platform1' + end + + fetcher.spec 'a', 2 do |s| + s.platform = Gem::Platform.new 'x86-other_platform1' + end + + fetcher.spec 'a', 3 do |s| + s.platform = Gem::Platform.new 'x86-other_platform1' + end + end + + expected = %W[ + a-2 + a-2-x86-my_platform-1 + a-3-x86-other_platform-1 + ] + + latest_specs = Gem::Specification.latest_specs.map(&:full_name).sort + + assert_equal expected, latest_specs + end + + def test_metadata_validates_ok + util_setup_validate + + Dir.chdir @tempdir do + @m1 = quick_gem 'm', '1' do |s| + s.files = %w[lib/code.rb] + s.metadata = { 'one' => "two", 'two' => "three" } + end + + use_ui @ui do + @m1.validate + end + end + end + + def test_metadata_key_type_validation_fails + util_setup_validate + + Dir.chdir @tempdir do + @m2 = quick_gem 'm', '2' do |s| + s.files = %w[lib/code.rb] + s.metadata = { 1 => "fail" } + end + + e = assert_raises Gem::InvalidSpecificationException do + @m2.validate + end + + assert_equal "metadata keys must be a String", e.message + end + end + + def test_metadata_key_size_validation_fails + util_setup_validate + + Dir.chdir @tempdir do + @m2 = quick_gem 'm', '2' do |s| + s.files = %w[lib/code.rb] + s.metadata = { ("x" * 129) => "fail" } + end + + e = assert_raises Gem::InvalidSpecificationException do + @m2.validate + end + + assert_equal "metadata key too large (129 > 128)", e.message + end + end + + def test_metadata_value_type_validation_fails + util_setup_validate + + Dir.chdir @tempdir do + @m2 = quick_gem 'm', '2' do |s| + s.files = %w[lib/code.rb] + s.metadata = { 'fail' => [] } + end + + e = assert_raises Gem::InvalidSpecificationException do + @m2.validate + end + + assert_equal "metadata values must be a String", e.message + end + end + + def test_metadata_value_size_validation_fails + util_setup_validate + + Dir.chdir @tempdir do + @m2 = quick_gem 'm', '2' do |s| + s.files = %w[lib/code.rb] + s.metadata = { 'fail' => ("x" * 1025) } + end + + e = assert_raises Gem::InvalidSpecificationException do + @m2.validate + end + + assert_equal "metadata value too large (1025 > 1024)", e.message + end + end + + def test_metadata_specs + valid_ruby_spec = <<-EOF +# -*- encoding: utf-8 -*- +# stub: m 1 ruby lib + +Gem::Specification.new do |s| + s.name = "m" + s.version = "1" + + s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= + s.metadata = { "one" => "two", "two" => "three" } if s.respond_to? :metadata= + s.require_paths = ["lib"] + s.authors = ["A User"] + s.date = "#{Gem::Specification::TODAY.strftime("%Y-%m-%d")}" + s.description = "This is a test description" + s.email = "example@example.com" + s.files = ["lib/code.rb"] + s.homepage = "http://example.com" + s.rubygems_version = "#{Gem::VERSION}" + s.summary = "this is a summary" +end + EOF + + @m1 = quick_gem 'm', '1' do |s| + s.files = %w[lib/code.rb] + s.metadata = { 'one' => "two", 'two' => "three" } + end + + assert_equal @m1.to_ruby, valid_ruby_spec + end + + def test_missing_extensions_eh + ext_spec + + assert @ext.missing_extensions? + + extconf_rb = File.join @ext.gem_dir, @ext.extensions.first + FileUtils.mkdir_p File.dirname extconf_rb + + open extconf_rb, 'w' do |f| + f.write <<-'RUBY' + open 'Makefile', 'w' do |f| + f.puts "clean:\n\techo clean" + f.puts "default:\n\techo built" + f.puts "install:\n\techo installed" + end + RUBY + end + + @ext.build_extensions + + refute @ext.missing_extensions? + end + + def test_missing_extensions_eh_default_gem + spec = new_default_spec 'default', 1 + spec.extensions << 'extconf.rb' + + refute spec.missing_extensions? + end + + def test_missing_extensions_eh_legacy + ext_spec + + @ext.installed_by_version = v '2.2.0.preview.2' + + assert @ext.missing_extensions? + + @ext.installed_by_version = v '2.2.0.preview.1' + + refute @ext.missing_extensions? + end + + def test_missing_extensions_eh_none + refute @a1.missing_extensions? + end + + def test_find_by_name + util_spec "a" + + assert Gem::Specification.find_by_name "a" + assert Gem::Specification.find_by_name "a", "1" + assert Gem::Specification.find_by_name "a", ">1" + + assert_raises Gem::LoadError do + Gem::Specification.find_by_name "monkeys" + end + end + + def test_find_by_name_prerelease + b = util_spec "b", "2.a" + + b.activate + + assert Gem::Specification.find_by_name "b" + + assert_raises Gem::LoadError do + Gem::Specification.find_by_name "b", "1" + end + + assert Gem::Specification.find_by_name "b", ">1" + end + + def test_find_by_path + a = new_spec "foo", "1", nil, "lib/foo.rb" + + install_specs a + + assert_equal a, Gem::Specification.find_by_path('foo') + a.activate + assert_equal a, Gem::Specification.find_by_path('foo') + end + + def test_find_inactive_by_path + a = new_spec "foo", "1", nil, "lib/foo.rb" + + install_specs a + + assert_equal a, Gem::Specification.find_inactive_by_path('foo') + a.activate + assert_equal nil, Gem::Specification.find_inactive_by_path('foo') + end + + def test_load_default_gem + Gem::Specification.reset + assert_equal [], Gem::Specification.map(&:full_name) + + default_gem_spec = new_default_spec("default", "2.0.0.0", + nil, "default/gem.rb") + spec_path = File.join(@default_spec_dir, default_gem_spec.spec_name) + write_file(spec_path) do |file| + file.print(default_gem_spec.to_ruby) + end + Gem::Specification.reset + assert_equal ["default-2.0.0.0"], Gem::Specification.map(&:full_name) + end + + def test_detect_bundled_gem_in_old_ruby + util_set_RUBY_VERSION '1.9.3', 551 + + spec = new_spec 'bigdecimal', '1.1.0' do |s| + s.summary = "This bigdecimal is bundled with Ruby" + end + + assert spec.bundled_gem_in_old_ruby? + ensure + util_restore_RUBY_VERSION + end + + def util_setup_deps + @gem = util_spec "awesome", "1.0" do |awesome| + awesome.add_runtime_dependency "bonobo", [] + awesome.add_development_dependency "monkey", [] + end + + @bonobo = Gem::Dependency.new("bonobo", []) + @monkey = Gem::Dependency.new("monkey", [], :development) + end + + def util_setup_validate + Dir.chdir @tempdir do + FileUtils.mkdir_p File.join("ext", "a") + FileUtils.mkdir_p "lib" + FileUtils.mkdir_p "test" + FileUtils.mkdir_p "bin" + + FileUtils.touch File.join("ext", "a", "extconf.rb") + FileUtils.touch File.join("lib", "code.rb") + FileUtils.touch File.join("test", "suite.rb") + + File.open "bin/exec", "w", 0755 do |fp| + fp.puts "#!#{Gem.ruby}" + end + end + end + + def with_syck + begin + verbose, $VERBOSE = $VERBOSE, nil + require "yaml" + old_engine = YAML::ENGINE.yamler + YAML::ENGINE.yamler = 'syck' + load 'rubygems/syck_hack.rb' + rescue NameError + # probably on 1.8, ignore + ensure + $VERBOSE = verbose + end + + yield + ensure + begin + YAML::ENGINE.yamler = old_engine + load 'rubygems/syck_hack.rb' + rescue NameError + # ignore + end + end + + def with_psych + begin + require "yaml" + old_engine = YAML::ENGINE.yamler + YAML::ENGINE.yamler = 'psych' + load 'rubygems/syck_hack.rb' + rescue NameError + # probably on 1.8, ignore + end + + yield + ensure + begin + YAML::ENGINE.yamler = old_engine + load 'rubygems/syck_hack.rb' + rescue NameError + # ignore + end + end + + def silence_warnings + old_verbose, $VERBOSE = $VERBOSE, false + yield + ensure + $VERBOSE = old_verbose + end +end diff --git a/jni/ruby/test/rubygems/test_gem_stream_ui.rb b/jni/ruby/test/rubygems/test_gem_stream_ui.rb new file mode 100644 index 0000000..f483568 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_stream_ui.rb @@ -0,0 +1,238 @@ +require 'rubygems/test_case' +require 'rubygems/user_interaction' +require 'timeout' + +class TestGemStreamUI < Gem::TestCase + + module IsTty + attr_accessor :tty + + def tty? + @tty = true unless defined? @tty + return @tty + end + + alias_method :isatty, :tty? + + def noecho + yield self + end + end + + def setup + super + + @cfg = Gem.configuration + + @in = StringIO.new + @out = StringIO.new + @err = StringIO.new + + @in.extend IsTty + @out.extend IsTty + + @sui = Gem::StreamUI.new @in, @out, @err, true + end + + def test_ask + skip 'TTY detection broken on windows' if + Gem.win_platform? unless RUBY_VERSION > '1.9.2' + + timeout(1) do + expected_answer = "Arthur, King of the Britons" + @in.string = "#{expected_answer}\n" + actual_answer = @sui.ask("What is your name?") + assert_equal expected_answer, actual_answer + end + end + + def test_ask_no_tty + skip 'TTY detection broken on windows' if + Gem.win_platform? unless RUBY_VERSION > '1.9.2' + + @in.tty = false + + timeout(0.1) do + answer = @sui.ask("what is your favorite color?") + assert_equal nil, answer + end + end + + def test_ask_for_password + skip 'Always uses $stdin on windows' if + Gem.win_platform? unless RUBY_VERSION > '1.9.2' + + timeout(1) do + expected_answer = "Arthur, King of the Britons" + @in.string = "#{expected_answer}\n" + actual_answer = @sui.ask_for_password("What is your name?") + assert_equal expected_answer, actual_answer + end + end + + def test_ask_for_password_no_tty + skip 'TTY handling is broken on windows' if + Gem.win_platform? unless RUBY_VERSION > '1.9.2' + + @in.tty = false + + timeout(0.1) do + answer = @sui.ask_for_password("what is the airspeed velocity of an unladen swallow?") + assert_equal nil, answer + end + end + + def test_ask_yes_no_no_tty_with_default + skip 'TTY handling is broken on windows' if + Gem.win_platform? unless RUBY_VERSION > '1.9.2' + + @in.tty = false + + timeout(0.1) do + answer = @sui.ask_yes_no("do coconuts migrate?", false) + assert_equal false, answer + + answer = @sui.ask_yes_no("do coconuts migrate?", true) + assert_equal true, answer + end + end + + def test_ask_yes_no_no_tty_without_default + skip 'TTY handling is broken on windows' if + Gem.win_platform? unless RUBY_VERSION > '1.9.2' + + @in.tty = false + + timeout(0.1) do + assert_raises(Gem::OperationNotSupportedError) do + @sui.ask_yes_no("do coconuts migrate?") + end + end + end + + def test_choose_from_list + @in.puts "1" + @in.rewind + + result = @sui.choose_from_list 'which one?', %w[foo bar] + + assert_equal ['foo', 0], result + assert_equal "which one?\n 1. foo\n 2. bar\n> ", @out.string + end + + def test_choose_from_list_EOF + result = @sui.choose_from_list 'which one?', %w[foo bar] + + assert_equal [nil, nil], result + assert_equal "which one?\n 1. foo\n 2. bar\n> ", @out.string + end + + def test_progress_reporter_silent_nil + @cfg.verbose = nil + reporter = @sui.progress_reporter 10, 'hi' + assert_kind_of Gem::StreamUI::SilentProgressReporter, reporter + end + + def test_progress_reporter_silent_false + @cfg.verbose = false + reporter = @sui.progress_reporter 10, 'hi' + assert_kind_of Gem::StreamUI::SilentProgressReporter, reporter + assert_equal "", @out.string + end + + def test_progress_reporter_simple + @cfg.verbose = true + reporter = @sui.progress_reporter 10, 'hi' + assert_kind_of Gem::StreamUI::SimpleProgressReporter, reporter + assert_equal "hi\n", @out.string + end + + def test_progress_reporter_verbose + @cfg.verbose = 0 + reporter = @sui.progress_reporter 10, 'hi' + assert_kind_of Gem::StreamUI::VerboseProgressReporter, reporter + assert_equal "hi\n", @out.string + end + + def test_download_reporter_silent_nil + @cfg.verbose = nil + reporter = @sui.download_reporter + reporter.fetch 'a.gem', 1024 + assert_kind_of Gem::StreamUI::SilentDownloadReporter, reporter + assert_equal "", @out.string + end + + def test_download_reporter_silent_false + @cfg.verbose = false + reporter = @sui.download_reporter + reporter.fetch 'a.gem', 1024 + assert_kind_of Gem::StreamUI::SilentDownloadReporter, reporter + assert_equal "", @out.string + end + + def test_download_reporter_anything + @cfg.verbose = 0 + reporter = @sui.download_reporter + assert_kind_of Gem::StreamUI::VerboseDownloadReporter, reporter + end + + def test_verbose_download_reporter + @cfg.verbose = true + reporter = @sui.download_reporter + reporter.fetch 'a.gem', 1024 + assert_equal "Fetching: a.gem", @out.string + end + + def test_verbose_download_reporter_progress + @cfg.verbose = true + reporter = @sui.download_reporter + reporter.fetch 'a.gem', 1024 + reporter.update 512 + assert_equal "Fetching: a.gem\rFetching: a.gem ( 50%)", @out.string + end + + def test_verbose_download_reporter_progress_once + @cfg.verbose = true + reporter = @sui.download_reporter + reporter.fetch 'a.gem', 1024 + reporter.update 510 + reporter.update 512 + assert_equal "Fetching: a.gem\rFetching: a.gem ( 50%)", @out.string + end + + def test_verbose_download_reporter_progress_complete + @cfg.verbose = true + reporter = @sui.download_reporter + reporter.fetch 'a.gem', 1024 + reporter.update 510 + reporter.done + assert_equal "Fetching: a.gem\rFetching: a.gem ( 50%)\rFetching: a.gem (100%)\n", @out.string + end + + def test_verbose_download_reporter_progress_nil_length + @cfg.verbose = true + reporter = @sui.download_reporter + reporter.fetch 'a.gem', nil + reporter.update 1024 + reporter.done + assert_equal "Fetching: a.gem\rFetching: a.gem (1024B)\rFetching: a.gem (1024B)\n", @out.string + end + + def test_verbose_download_reporter_progress_zero_length + @cfg.verbose = true + reporter = @sui.download_reporter + reporter.fetch 'a.gem', 0 + reporter.update 1024 + reporter.done + assert_equal "Fetching: a.gem\rFetching: a.gem (1024B)\rFetching: a.gem (1024B)\n", @out.string + end + + def test_verbose_download_reporter_no_tty + @out.tty = false + + @cfg.verbose = true + reporter = @sui.download_reporter + reporter.fetch 'a.gem', 1024 + assert_equal "", @out.string + end +end diff --git a/jni/ruby/test/rubygems/test_gem_stub_specification.rb b/jni/ruby/test/rubygems/test_gem_stub_specification.rb new file mode 100644 index 0000000..914b06a --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_stub_specification.rb @@ -0,0 +1,199 @@ +require "rubygems/test_case" +require "rubygems/stub_specification" + +class TestStubSpecification < Gem::TestCase + SPECIFICATIONS = File.expand_path(File.join("..", "specifications"), __FILE__) + FOO = File.join SPECIFICATIONS, "foo-0.0.1.gemspec" + BAR = File.join SPECIFICATIONS, "bar-0.0.2.gemspec" + + def setup + super + + @foo = Gem::StubSpecification.new FOO + end + + def test_initialize + assert_equal "foo", @foo.name + assert_equal Gem::Version.new("0.0.1"), @foo.version + assert_equal Gem::Platform.new("mswin32"), @foo.platform + assert_equal ["lib", "lib/f oo/ext"], @foo.require_paths + assert @foo.stubbed? + end + + def test_initialize_extension + stub = stub_with_extension + + assert_equal 'stub_e', stub.name + assert_equal v(2), stub.version + assert_equal Gem::Platform::RUBY, stub.platform + assert_equal [stub.extension_dir, 'lib'], stub.require_paths + assert_equal %w[ext/stub_e/extconf.rb], stub.extensions + end + + def test_initialize_missing_stubline + stub = Gem::StubSpecification.new(BAR) + assert_equal "bar", stub.name + assert_equal Gem::Version.new("0.0.2"), stub.version + assert_equal Gem::Platform.new("ruby"), stub.platform + assert_equal ["lib"], stub.require_paths + assert !stub.stubbed? + end + + def test_contains_requirable_file_eh + stub = stub_without_extension + code_rb = File.join stub.gem_dir, 'lib', 'code.rb' + FileUtils.mkdir_p File.dirname code_rb + FileUtils.touch code_rb + + assert stub.contains_requirable_file? 'code' + end + + def test_contains_requirable_file_eh_extension + stub_with_extension do |stub| + _, err = capture_io do + refute stub.contains_requirable_file? 'nonexistent' + end + + expected = "Ignoring stub_e-2 because its extensions are not built. " + + "Try: gem pristine stub_e --version 2\n" + + assert_equal expected, err + end + end + + def test_full_require_paths + stub = stub_with_extension + + expected = [ + stub.extension_dir, + File.join(stub.full_gem_path, 'lib'), + ] + + assert_equal expected, stub.full_require_paths + end + + def test_missing_extensions_eh + stub = stub_with_extension do |s| + extconf_rb = File.join s.gem_dir, s.extensions.first + FileUtils.mkdir_p File.dirname extconf_rb + + open extconf_rb, 'w' do |f| + f.write <<-'RUBY' + open 'Makefile', 'w' do |f| + f.puts "clean:\n\techo clean" + f.puts "default:\n\techo built" + f.puts "install:\n\techo installed" + end + RUBY + end + end + + assert stub.missing_extensions? + + stub.build_extensions + + refute stub.missing_extensions? + end + + def test_missing_extensions_eh_default_gem + spec = new_default_spec 'default', 1 + spec.extensions << 'extconf.rb' + + open spec.loaded_from, 'w' do |io| + io.write spec.to_ruby_for_cache + end + + default_spec = Gem::StubSpecification.new spec.loaded_from + + refute default_spec.missing_extensions? + end + + def test_missing_extensions_eh_none + refute @foo.missing_extensions? + end + + def test_to_spec + real_foo = util_spec @foo.name, @foo.version + real_foo.activate + + assert_equal @foo.version, Gem.loaded_specs[@foo.name].version, + 'sanity check' + + assert_same real_foo, @foo.to_spec + end + + def test_to_spec_with_other_specs_loaded_does_not_warn + real_foo = util_spec @foo.name, @foo.version + real_foo.activate + bar = Gem::StubSpecification.new BAR + refute_predicate Gem.loaded_specs, :empty? + assert bar.to_spec + end + + def test_to_spec_activated + assert @foo.to_spec.is_a?(Gem::Specification) + assert_equal "foo", @foo.to_spec.name + refute @foo.to_spec.instance_variable_defined? :@ignored + end + + def test_to_spec_missing_extensions + stub = stub_with_extension + + capture_io do + stub.contains_requirable_file? 'nonexistent' + end + + assert stub.to_spec.instance_variable_get :@ignored + end + + def stub_with_extension + spec = File.join @gemhome, 'specifications', 'stub_e-2.gemspec' + open spec, 'w' do |io| + io.write <<-STUB +# -*- encoding: utf-8 -*- +# stub: stub_e 2 ruby lib +# stub: ext/stub_e/extconf.rb + +Gem::Specification.new do |s| + s.name = 'stub_e' + s.version = Gem::Version.new '2' + s.extensions = ['ext/stub_e/extconf.rb'] + s.installed_by_version = '2.2' +end + STUB + + io.flush + + stub = Gem::StubSpecification.new io.path + + yield stub if block_given? + + return stub + end + end + + def stub_without_extension + spec = File.join @gemhome, 'specifications', 'stub-2.gemspec' + open spec, 'w' do |io| + io.write <<-STUB +# -*- encoding: utf-8 -*- +# stub: stub 2 ruby lib + +Gem::Specification.new do |s| + s.name = 'stub' + s.version = Gem::Version.new '2' +end + STUB + + io.flush + + stub = Gem::StubSpecification.new io.path + + yield stub if block_given? + + return stub + end + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_text.rb b/jni/ruby/test/rubygems/test_gem_text.rb new file mode 100644 index 0000000..e5cfc41 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_text.rb @@ -0,0 +1,74 @@ +require 'rubygems/test_case' +require "rubygems/text" + +class TestGemText < Gem::TestCase + include Gem::Text + + def test_format_text + assert_equal "text to\nwrap", format_text("text to wrap", 8) + end + + def test_format_text_indent + assert_equal " text to\n wrap", format_text("text to wrap", 8, 2) + end + + def test_format_text_none + assert_equal "text to wrap", format_text("text to wrap", 40) + end + + def test_format_text_none_indent + assert_equal " text to wrap", format_text("text to wrap", 40, 2) + end + + def test_format_text_trailing # for two spaces after . + text = <<-TEXT +This line is really, really long. So long, in fact, that it is more than eighty characters long! The purpose of this line is for testing wrapping behavior because sometimes people don't wrap their text to eighty characters. Without the wrapping, the text might not look good in the RSS feed. + TEXT + + expected = <<-EXPECTED +This line is really, really long. So long, in fact, that it is more than +eighty characters long! The purpose of this line is for testing wrapping +behavior because sometimes people don't wrap their text to eighty characters. +Without the wrapping, the text might not look good in the RSS feed. + EXPECTED + + assert_equal expected, format_text(text, 78) + end + + def test_min3 + assert_equal 1, min3(1, 1, 1) + assert_equal 1, min3(1, 1, 2) + assert_equal 1, min3(1, 2, 1) + assert_equal 1, min3(2, 1, 1) + assert_equal 1, min3(1, 2, 2) + assert_equal 1, min3(2, 1, 2) + assert_equal 1, min3(2, 2, 1) + assert_equal 1, min3(1, 2, 3) + assert_equal 1, min3(1, 3, 2) + assert_equal 1, min3(2, 1, 3) + assert_equal 1, min3(2, 3, 1) + assert_equal 1, min3(3, 1, 2) + assert_equal 1, min3(3, 2, 1) + end + + def test_levenshtein_distance_add + assert_equal 2, levenshtein_distance("zentest", "zntst") + assert_equal 2, levenshtein_distance("zntst", "zentest") + end + + def test_levenshtein_distance_empty + assert_equal 5, levenshtein_distance("abcde", "") + assert_equal 5, levenshtein_distance("", "abcde") + end + + def test_levenshtein_distance_remove + assert_equal 3, levenshtein_distance("zentest", "zentestxxx") + assert_equal 3, levenshtein_distance("zentestxxx", "zentest") + end + + def test_levenshtein_distance_replace + assert_equal 2, levenshtein_distance("zentest", "ZenTest") + assert_equal 7, levenshtein_distance("xxxxxxx", "ZenTest") + assert_equal 7, levenshtein_distance("zentest", "xxxxxxx") + end +end diff --git a/jni/ruby/test/rubygems/test_gem_uninstaller.rb b/jni/ruby/test/rubygems/test_gem_uninstaller.rb new file mode 100644 index 0000000..2a9a15d --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_uninstaller.rb @@ -0,0 +1,483 @@ +require 'rubygems/installer_test_case' +require 'rubygems/uninstaller' + +class TestGemUninstaller < Gem::InstallerTestCase + + def setup + super + common_installer_setup + + build_rake_in do + use_ui ui do + @installer.install + @spec = @installer.spec + + @user_installer.install + @user_spec = @user_installer.spec + end + end + + Gem::Specification.reset + end + + def test_initialize_expand_path + uninstaller = Gem::Uninstaller.new nil, :install_dir => '/foo//bar' + + assert_match %r|/foo/bar$|, uninstaller.instance_variable_get(:@gem_home) + end + + def test_ask_if_ok + c = util_spec 'c' + + uninstaller = Gem::Uninstaller.new nil + + ok = :junk + + ui = Gem::MockGemUi.new "\n" + + use_ui ui do + ok = uninstaller.ask_if_ok c + end + + refute ok + end + + def test_remove_all + uninstaller = Gem::Uninstaller.new nil + + ui = Gem::MockGemUi.new "y\n" + + use_ui ui do + uninstaller.remove_all [@spec] + end + + refute_path_exists @spec.gem_dir + end + + def test_remove_executables_force_keep + uninstaller = Gem::Uninstaller.new nil, :executables => false + + executable = File.join Gem.bindir(@user_spec.base_dir), 'executable' + assert File.exist?(executable), 'executable not written' + + use_ui @ui do + uninstaller.remove_executables @user_spec + end + + assert File.exist? executable + + assert_equal "Executables and scripts will remain installed.\n", @ui.output + end + + def test_remove_executables_force_remove + uninstaller = Gem::Uninstaller.new nil, :executables => true + + executable = File.join Gem.bindir(@user_spec.base_dir), 'executable' + assert File.exist?(executable), 'executable not written' + + use_ui @ui do + uninstaller.remove_executables @user_spec + end + + assert_equal "Removing executable\n", @ui.output + + refute File.exist? executable + end + + def test_remove_executables_user + uninstaller = Gem::Uninstaller.new nil, :executables => true + + use_ui @ui do + uninstaller.remove_executables @user_spec + end + + exec_path = File.join Gem.user_dir, 'bin', 'executable' + refute File.exist?(exec_path), 'exec still exists in user bin dir' + + assert_equal "Removing executable\n", @ui.output + end + + def test_remove_executables_user_format + Gem::Installer.exec_format = 'foo-%s-bar' + + uninstaller = Gem::Uninstaller.new nil, :executables => true, :format_executable => true + + use_ui @ui do + uninstaller.remove_executables @user_spec + end + + exec_path = File.join Gem.user_dir, 'bin', 'foo-executable-bar' + assert_equal false, File.exist?(exec_path), 'removed exec from bin dir' + + assert_equal "Removing foo-executable-bar\n", @ui.output + ensure + Gem::Installer.exec_format = nil + end + + def test_remove_executables_user_format_disabled + Gem::Installer.exec_format = 'foo-%s-bar' + + uninstaller = Gem::Uninstaller.new nil, :executables => true + + use_ui @ui do + uninstaller.remove_executables @user_spec + end + + exec_path = File.join Gem.user_dir, 'bin', 'executable' + refute File.exist?(exec_path), 'removed exec from bin dir' + + assert_equal "Removing executable\n", @ui.output + ensure + Gem::Installer.exec_format = nil + end + + def test_remove_not_in_home + uninstaller = Gem::Uninstaller.new nil, :install_dir => "#{@gemhome}2" + + e = assert_raises Gem::GemNotInHomeException do + use_ui ui do + uninstaller.remove @spec + end + end + + expected = + "Gem '#{@spec.full_name}' is not installed in directory #{@gemhome}2" + + assert_equal expected, e.message + + assert_path_exists @spec.gem_dir + end + + def test_path_ok_eh + uninstaller = Gem::Uninstaller.new nil + + assert_equal true, uninstaller.path_ok?(@gemhome, @spec) + end + + def test_path_ok_eh_legacy + uninstaller = Gem::Uninstaller.new nil + + @spec.loaded_from = @spec.loaded_from.gsub @spec.full_name, '\&-legacy' + @spec.platform = 'legacy' + + assert_equal true, uninstaller.path_ok?(@gemhome, @spec) + end + + def test_path_ok_eh_user + uninstaller = Gem::Uninstaller.new nil + + assert_equal true, uninstaller.path_ok?(Gem.user_dir, @user_spec) + end + + def test_uninstall + uninstaller = Gem::Uninstaller.new @spec.name, :executables => true + + gem_dir = File.join @gemhome, 'gems', @spec.full_name + + Gem.pre_uninstall do + assert File.exist?(gem_dir), 'gem_dir should exist' + end + + Gem.post_uninstall do + refute File.exist?(gem_dir), 'gem_dir should not exist' + end + + uninstaller.uninstall + + refute File.exist?(gem_dir) + + assert_same uninstaller, @pre_uninstall_hook_arg + assert_same uninstaller, @post_uninstall_hook_arg + end + + def test_uninstall_default_gem + spec = new_default_spec 'default', '2' + + install_default_gems spec + + uninstaller = Gem::Uninstaller.new spec.name, :executables => true + + e = assert_raises Gem::InstallError do + uninstaller.uninstall + end + + assert_equal 'gem "default" cannot be uninstalled ' + + 'because it is a default gem', + e.message + end + + def test_uninstall_default_gem_with_same_version + default_spec = new_default_spec 'default', '2' + install_default_gems default_spec + + spec = new_spec 'default', '2' + install_gem spec + + Gem::Specification.reset + + uninstaller = Gem::Uninstaller.new spec.name, :executables => true + + uninstaller.uninstall + + refute_path_exists spec.gem_dir + end + + def test_uninstall_extension + @spec.extensions << 'extconf.rb' + write_file File.join(@tempdir, 'extconf.rb') do |io| + io.write <<-RUBY +require 'mkmf' +create_makefile '#{@spec.name}' + RUBY + end + + @spec.files += %w[extconf.rb] + + use_ui @ui do + path = Gem::Package.build @spec + + installer = Gem::Installer.new path + installer.install + end + + assert_path_exists @spec.extension_dir, 'sanity check' + + uninstaller = Gem::Uninstaller.new @spec.name, :executables => true + uninstaller.uninstall + + refute_path_exists @spec.extension_dir + end + + def test_uninstall_nonexistent + uninstaller = Gem::Uninstaller.new 'bogus', :executables => true + + e = assert_raises Gem::InstallError do + uninstaller.uninstall + end + + assert_equal 'gem "bogus" is not installed', e.message + end + + def test_uninstall_not_ok + quick_gem 'z' do |s| + s.add_runtime_dependency @spec.name + end + + uninstaller = Gem::Uninstaller.new @spec.name + + gem_dir = File.join @gemhome, 'gems', @spec.full_name + executable = File.join @gemhome, 'bin', 'executable' + + assert File.exist?(gem_dir), 'gem_dir must exist' + assert File.exist?(executable), 'executable must exist' + + ui = Gem::MockGemUi.new "n\n" + + assert_raises Gem::DependencyRemovalException do + use_ui ui do + uninstaller.uninstall + end + end + + assert File.exist?(gem_dir), 'gem_dir must still exist' + assert File.exist?(executable), 'executable must still exist' + end + + def test_uninstall_user_install + @user_spec = Gem::Specification.find_by_name 'b' + + uninstaller = Gem::Uninstaller.new(@user_spec.name, + :executables => true, + :user_install => true) + + gem_dir = File.join @user_spec.gem_dir + + Gem.pre_uninstall do + assert_path_exists gem_dir + end + + Gem.post_uninstall do + refute_path_exists gem_dir + end + + uninstaller.uninstall + + refute_path_exists gem_dir + + assert_same uninstaller, @pre_uninstall_hook_arg + assert_same uninstaller, @post_uninstall_hook_arg + end + + def test_uninstall_wrong_repo + Gem.use_paths "#{@gemhome}2", [@gemhome] + + uninstaller = Gem::Uninstaller.new @spec.name, :executables => true + + e = assert_raises Gem::InstallError do + uninstaller.uninstall + end + + expected = <<-MESSAGE.strip +#{@spec.name} is not installed in GEM_HOME, try: +\tgem uninstall -i #{@gemhome} a + MESSAGE + + assert_equal expected, e.message + end + + def test_uninstall_selection + util_make_gems + + list = Gem::Specification.find_all_by_name 'a' + + uninstaller = Gem::Uninstaller.new 'a' + + ui = Gem::MockGemUi.new "1\ny\n" + + use_ui ui do + uninstaller.uninstall + end + + updated_list = Gem::Specification.find_all_by_name('a') + assert_equal list.length - 1, updated_list.length + + assert_match ' 1. a-1', ui.output + assert_match ' 2. a-2', ui.output + assert_match ' 3. a-3.a', ui.output + assert_match ' 4. All versions', ui.output + assert_match 'uninstalled a-1', ui.output + end + + def test_uninstall_selection_greater_than_one + util_make_gems + + list = Gem::Specification.find_all_by_name('a') + + uninstaller = Gem::Uninstaller.new('a') + + use_ui Gem::MockGemUi.new("2\ny\n") do + uninstaller.uninstall + end + + updated_list = Gem::Specification.find_all_by_name('a') + assert_equal list.length - 1, updated_list.length + end + + def test_uninstall_prompts_about_broken_deps + quick_gem 'r', '1' do |s| s.add_dependency 'q', '= 1' end + quick_gem 'q', '1' + + un = Gem::Uninstaller.new('q') + ui = Gem::MockGemUi.new("y\n") + + use_ui ui do + un.uninstall + end + + lines = ui.output.split("\n") + lines.shift + + assert_match %r!You have requested to uninstall the gem:!, lines.shift + lines.shift + lines.shift + + assert_match %r!r-1 depends on q \(= 1\)!, lines.shift + assert_match %r!Successfully uninstalled q-1!, lines.last + end + + def test_uninstall_only_lists_unsatified_deps + quick_gem 'r', '1' do |s| s.add_dependency 'q', '~> 1.0' end + quick_gem 'x', '1' do |s| s.add_dependency 'q', '= 1.0' end + quick_gem 'q', '1.0' + quick_gem 'q', '1.1' + + un = Gem::Uninstaller.new('q', :version => "1.0") + ui = Gem::MockGemUi.new("y\n") + + use_ui ui do + un.uninstall + end + + lines = ui.output.split("\n") + lines.shift + + assert_match %r!You have requested to uninstall the gem:!, lines.shift + lines.shift + lines.shift + + assert_match %r!x-1 depends on q \(= 1.0\)!, lines.shift + assert_match %r!Successfully uninstalled q-1.0!, lines.last + end + + def test_uninstall_doesnt_prompt_when_other_gem_satifies_requirement + quick_gem 'r', '1' do |s| s.add_dependency 'q', '~> 1.0' end + quick_gem 'q', '1.0' + quick_gem 'q', '1.1' + + un = Gem::Uninstaller.new('q', :version => "1.0") + ui = Gem::MockGemUi.new("y\n") + + use_ui ui do + un.uninstall + end + + lines = ui.output.split("\n") + + assert_equal "Successfully uninstalled q-1.0", lines.shift + end + + def test_uninstall_doesnt_prompt_when_removing_a_dev_dep + quick_gem 'r', '1' do |s| s.add_development_dependency 'q', '= 1.0' end + quick_gem 'q', '1.0' + + un = Gem::Uninstaller.new('q', :version => "1.0") + ui = Gem::MockGemUi.new("y\n") + + use_ui ui do + un.uninstall + end + + lines = ui.output.split("\n") + + assert_equal "Successfully uninstalled q-1.0", lines.shift + end + + def test_uninstall_doesnt_prompt_and_raises_when_abort_on_dependent_set + quick_gem 'r', '1' do |s| s.add_dependency 'q', '= 1' end + quick_gem 'q', '1' + + un = Gem::Uninstaller.new('q', :abort_on_dependent => true) + ui = Gem::MockGemUi.new("y\n") + + assert_raises Gem::DependencyRemovalException do + use_ui ui do + un.uninstall + end + end + end + + def test_uninstall_prompt_includes_dep_type + quick_gem 'r', '1' do |s| + s.add_development_dependency 'q', '= 1' + end + + quick_gem 'q', '1' + + un = Gem::Uninstaller.new('q', :check_dev => true) + ui = Gem::MockGemUi.new("y\n") + + use_ui ui do + un.uninstall + end + + lines = ui.output.split("\n") + lines.shift + + assert_match %r!You have requested to uninstall the gem:!, lines.shift + lines.shift + lines.shift + + assert_match %r!r-1 depends on q \(= 1, development\)!, lines.shift + assert_match %r!Successfully uninstalled q-1!, lines.last + end +end diff --git a/jni/ruby/test/rubygems/test_gem_unsatisfiable_dependency_error.rb b/jni/ruby/test/rubygems/test_gem_unsatisfiable_dependency_error.rb new file mode 100644 index 0000000..6418c5d --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_unsatisfiable_dependency_error.rb @@ -0,0 +1,32 @@ +require 'rubygems/test_case' + +class TestGemUnsatisfiableDependencyError < Gem::TestCase + + def setup + super + + @a_dep = dep 'a', '~> 1' + + @req = Gem::Resolver::DependencyRequest.new @a_dep, nil + + @e = Gem::UnsatisfiableDependencyError.new @req + end + + def test_errors + assert_equal [], @e.errors + + @e.errors << :a + + assert_equal [:a], @e.errors + end + + def test_name + assert_equal 'a', @e.name + end + + def test_version + assert_equal @a_dep.requirement, @e.version + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_uri_formatter.rb b/jni/ruby/test/rubygems/test_gem_uri_formatter.rb new file mode 100644 index 0000000..628b7c5 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_uri_formatter.rb @@ -0,0 +1,28 @@ +require 'rubygems/test_case' +require 'rubygems/uri_formatter' + +class TestGemUriFormatter < Gem::TestCase + + def test_normalize_uri + assert_equal 'FILE://example/', + Gem::UriFormatter.new('FILE://example/').normalize + assert_equal 'FTP://example/', + Gem::UriFormatter.new('FTP://example/').normalize + assert_equal 'HTTP://example/', + Gem::UriFormatter.new('HTTP://example/').normalize + assert_equal 'HTTPS://example/', + Gem::UriFormatter.new('HTTPS://example/').normalize + assert_equal 'http://example/', + Gem::UriFormatter.new('example/').normalize + end + + def test_escape + assert_equal 'a%40b%5Cc', Gem::UriFormatter.new('a@b\c').escape + end + + def test_unescape + assert_equal 'a@b\c', Gem::UriFormatter.new('a%40b%5Cc').unescape + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_util.rb b/jni/ruby/test/rubygems/test_gem_util.rb new file mode 100644 index 0000000..414487a --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_util.rb @@ -0,0 +1,31 @@ +require 'rubygems/test_case' +require 'rubygems/util' + +class TestGemUtil < Gem::TestCase + + def test_class_popen + assert_equal "0\n", Gem::Util.popen(Gem.ruby, '-e', 'p 0') + + assert_raises Errno::ECHILD do + Process.wait(-1) + end + end + + def test_silent_system + assert_silent do + Gem::Util.silent_system Gem.ruby, '-e', 'puts "hello"; warn "hello"' + end + end + + def test_traverse_parents + FileUtils.mkdir_p 'a/b/c' + + enum = Gem::Util.traverse_parents 'a/b/c' + + assert_equal File.join(@tempdir, 'a/b/c'), enum.next + assert_equal File.join(@tempdir, 'a/b'), enum.next + assert_equal File.join(@tempdir, 'a'), enum.next + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_validator.rb b/jni/ruby/test/rubygems/test_gem_validator.rb new file mode 100644 index 0000000..4af8b52 --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_validator.rb @@ -0,0 +1,45 @@ +require 'rubygems/test_case' +require "rubygems/simple_gem" +require 'rubygems/validator' + +class TestGemValidator < Gem::TestCase + + def setup + super + + @simple_gem = SIMPLE_GEM + @validator = Gem::Validator.new + end + + def test_alien + @spec = quick_gem 'a' do |s| + s.files = %w[lib/a.rb lib/b.rb] + end + + util_build_gem @spec + + FileUtils.rm File.join(@spec.gem_dir, 'lib/b.rb') + FileUtils.touch File.join(@spec.gem_dir, 'lib/c.rb') + + alien = @validator.alien 'a' + + expected = { + @spec.file_name => [ + Gem::Validator::ErrorData.new('lib/b.rb', 'Missing file'), + Gem::Validator::ErrorData.new('lib/c.rb', 'Extra file'), + ] + } + + assert_equal expected, alien + end + + def test_alien_default + new_default_spec 'c', 1, nil, 'lib/c.rb' + + alien = @validator.alien 'c' + + assert_empty alien + end + +end + diff --git a/jni/ruby/test/rubygems/test_gem_version.rb b/jni/ruby/test/rubygems/test_gem_version.rb new file mode 100644 index 0000000..5a65b5c --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_version.rb @@ -0,0 +1,213 @@ +require 'rubygems/test_case' +require "rubygems/version" + +class TestGemVersion < Gem::TestCase + + class V < ::Gem::Version + end + + def test_bump + assert_bumped_version_equal "5.3", "5.2.4" + end + + def test_bump_alpha + assert_bumped_version_equal "5.3", "5.2.4.a" + end + + def test_bump_alphanumeric + assert_bumped_version_equal "5.3", "5.2.4.a10" + end + + def test_bump_trailing_zeros + assert_bumped_version_equal "5.1", "5.0.0" + end + + def test_bump_one_level + assert_bumped_version_equal "6", "5" + end + + # A Gem::Version is already a Gem::Version and therefore not transformed by + # Gem::Version.create + + def test_class_create + real = Gem::Version.new(1.0) + + assert_same real, Gem::Version.create(real) + assert_nil Gem::Version.create(nil) + assert_equal v("5.1"), Gem::Version.create("5.1") + + ver = '1.1'.freeze + assert_equal v('1.1'), Gem::Version.create(ver) + end + + def test_class_new_subclass + v1 = Gem::Version.new '1' + v2 = V.new '1' + + refute_same v1, v2 + end + + def test_eql_eh + assert_version_eql "1.2", "1.2" + refute_version_eql "1.2", "1.2.0" + refute_version_eql "1.2", "1.3" + refute_version_eql "1.2.b1", "1.2.b.1" + end + + def test_equals2 + assert_version_equal "1.2", "1.2" + refute_version_equal "1.2", "1.3" + assert_version_equal "1.2.b1", "1.2.b.1" + end + + # REVISIT: consider removing as too impl-bound + def test_hash + assert_equal v("1.2").hash, v("1.2").hash + refute_equal v("1.2").hash, v("1.3").hash + refute_equal v("1.2").hash, v("1.2.0").hash + end + + def test_initialize + ["1.0", "1.0 ", " 1.0 ", "1.0\n", "\n1.0\n", "1.0".freeze].each do |good| + assert_version_equal "1.0", good + end + + assert_version_equal "1", 1 + end + + def test_initialize_bad + %W[ + junk + 1.0\n2.0 + 1..2 + 1.2\ 3.4 + ].each do |bad| + e = assert_raises ArgumentError, bad do + Gem::Version.new bad + end + + assert_equal "Malformed version number string #{bad}", e.message, bad + end + end + + def test_prerelease + assert_prerelease "1.2.0.a" + assert_prerelease "2.9.b" + assert_prerelease "22.1.50.0.d" + assert_prerelease "1.2.d.42" + + assert_prerelease '1.A' + + refute_prerelease "1.2.0" + refute_prerelease "2.9" + refute_prerelease "22.1.50.0" + end + + def test_release + assert_release_equal "1.2.0", "1.2.0.a" + assert_release_equal "1.1", "1.1.rc10" + assert_release_equal "1.9.3", "1.9.3.alpha.5" + assert_release_equal "1.9.3", "1.9.3" + end + + def test_spaceship + assert_equal( 0, v("1.0") <=> v("1.0.0")) + assert_equal( 1, v("1.0") <=> v("1.0.a")) + assert_equal( 1, v("1.8.2") <=> v("0.0.0")) + assert_equal( 1, v("1.8.2") <=> v("1.8.2.a")) + assert_equal( 1, v("1.8.2.b") <=> v("1.8.2.a")) + assert_equal(-1, v("1.8.2.a") <=> v("1.8.2")) + assert_equal( 1, v("1.8.2.a10") <=> v("1.8.2.a9")) + assert_equal( 0, v("") <=> v("0")) + + assert_nil v("1.0") <=> "whatever" + end + + def test_approximate_recommendation + assert_approximate_equal "~> 1.0", "1" + assert_approximate_equal "~> 1.0", "1.0" + assert_approximate_equal "~> 1.2", "1.2" + assert_approximate_equal "~> 1.2", "1.2.0" + assert_approximate_equal "~> 1.2", "1.2.3" + assert_approximate_equal "~> 1.2", "1.2.3.a.4" + end + + def test_to_s + assert_equal "5.2.4", v("5.2.4").to_s + end + + def test_semver + assert_less_than "1.0.0-alpha", "1.0.0-alpha.1" + assert_less_than "1.0.0-alpha.1", "1.0.0-beta.2" + assert_less_than "1.0.0-beta.2", "1.0.0-beta.11" + assert_less_than "1.0.0-beta.11", "1.0.0-rc.1" + assert_less_than "1.0.0-rc1", "1.0.0" + assert_less_than "1.0.0-1", "1" + end + + # Asserts that +version+ is a prerelease. + + def assert_prerelease version + assert v(version).prerelease?, "#{version} is a prerelease" + end + + # Assert that +expected+ is the "approximate" recommendation for +version". + + def assert_approximate_equal expected, version + assert_equal expected, v(version).approximate_recommendation + end + + # Assert that bumping the +unbumped+ version yields the +expected+. + + def assert_bumped_version_equal expected, unbumped + assert_version_equal expected, v(unbumped).bump + end + + # Assert that +release+ is the correct non-prerelease +version+. + + def assert_release_equal release, version + assert_version_equal release, v(version).release + end + + # Assert that two versions are equal. Handles strings or + # Gem::Version instances. + + def assert_version_equal expected, actual + assert_equal v(expected), v(actual) + end + + # Assert that two versions are eql?. Checks both directions. + + def assert_version_eql first, second + first, second = v(first), v(second) + assert first.eql?(second), "#{first} is eql? #{second}" + assert second.eql?(first), "#{second} is eql? #{first}" + end + + def assert_less_than left, right + l = v(left) + r = v(right) + assert l < r, "#{left} not less than #{right}" + end + + # Refute the assumption that +version+ is a prerelease. + + def refute_prerelease version + refute v(version).prerelease?, "#{version} is NOT a prerelease" + end + + # Refute the assumption that two versions are eql?. Checks both + # directions. + + def refute_version_eql first, second + first, second = v(first), v(second) + refute first.eql?(second), "#{first} is NOT eql? #{second}" + refute second.eql?(first), "#{second} is NOT eql? #{first}" + end + + # Refute the assumption that the two versions are equal?. + + def refute_version_equal unexpected, actual + refute_equal v(unexpected), v(actual) + end +end diff --git a/jni/ruby/test/rubygems/test_gem_version_option.rb b/jni/ruby/test/rubygems/test_gem_version_option.rb new file mode 100644 index 0000000..d6035ab --- /dev/null +++ b/jni/ruby/test/rubygems/test_gem_version_option.rb @@ -0,0 +1,151 @@ +require 'rubygems/test_case' +require 'rubygems/command' +require 'rubygems/version_option' + +class TestGemVersionOption < Gem::TestCase + + def setup + super + + @cmd = Gem::Command.new 'dummy', 'dummy' + @cmd.extend Gem::VersionOption + end + + def test_add_platform_option + @cmd.add_platform_option + + assert @cmd.handles?(%w[--platform x86-darwin]) + end + + def test_add_version_option + @cmd.add_version_option + + assert @cmd.handles?(%w[--version >1]) + end + + def test_enables_prerelease + @cmd.add_version_option + + @cmd.handle_options %w[mygem -v 0.2.0.a] + assert @cmd.options[:prerelease] + + @cmd.handle_options %w[mygem -v 0.2.0] + refute @cmd.options[:prerelease] + + @cmd.handle_options %w[mygem] + refute @cmd.options[:prerelease] + end + + def test_platform_option + @cmd.add_platform_option + + @cmd.handle_options %w[--platform x86-freebsd6 --platform x86-freebsd7] + + expected = [ + Gem::Platform::RUBY, + Gem::Platform.new('x86-freebsd6'), + Gem::Platform.new('x86-freebsd7'), + ] + + assert_equal expected, Gem.platforms + end + + def test_platform_option_ruby + @cmd.add_platform_option + + @cmd.handle_options %w[--platform ruby] + + expected = [ + Gem::Platform::RUBY + ] + + assert_equal expected, Gem.platforms + end + + def test_platform_option_twice + @cmd.add_platform_option + + @cmd.handle_options %w[--platform x86-freebsd6 --platform x86-freebsd-6] + + expected = [ + Gem::Platform::RUBY, + Gem::Platform.new('x86-freebsd6'), + ] + + assert_equal expected, Gem.platforms + end + + def test_version_option + @cmd.add_version_option + + @cmd.handle_options %w[--version >1] + + expected = { + :args => [], + :explicit_prerelease => false, + :prerelease => false, + :version => Gem::Requirement.new('> 1'), + } + + assert_equal expected, @cmd.options + end + + def test_version_option_compound + @cmd.add_version_option + + @cmd.handle_options ['--version', '< 1, > 0.9'] + + expected = { + :args => [], + :explicit_prerelease => false, + :prerelease => false, + :version => Gem::Requirement.new('< 1', '> 0.9'), + } + + assert_equal expected, @cmd.options + end + + def test_version_option_explicit_prerelease + @cmd.add_prerelease_option + @cmd.add_version_option + + @cmd.handle_options %w[--pre --version >1] + + expected = { + :args => [], + :explicit_prerelease => true, + :prerelease => true, + :version => Gem::Requirement.new('> 1'), + } + + assert_equal expected, @cmd.options + end + + def test_version_option_twice + @cmd.add_version_option + + @cmd.handle_options %w[--version >1.a] + + expected = { + :args => [], + :explicit_prerelease => false, + :prerelease => true, + :version => Gem::Requirement.new('> 1.a'), + } + + assert_equal expected, @cmd.options + + @cmd.handle_options %w[--version >1] + + expected = { + :args => [], + :explicit_prerelease => false, + :prerelease => false, + :version => Gem::Requirement.new('> 1'), + } + + assert_equal expected, @cmd.options + end + +end + diff --git a/jni/ruby/test/rubygems/test_kernel.rb b/jni/ruby/test/rubygems/test_kernel.rb new file mode 100644 index 0000000..ee8b248 --- /dev/null +++ b/jni/ruby/test/rubygems/test_kernel.rb @@ -0,0 +1,85 @@ +require 'rubygems/test_case' + +class TestKernel < Gem::TestCase + + def setup + super + + @old_path = $:.dup + + util_make_gems + end + + def teardown + super + + $:.replace @old_path + end + + def test_gem + assert gem('a', '= 1'), "Should load" + assert $:.any? { |p| %r{a-1/lib} =~ p } + end + + def test_gem_default + assert gem('a', '>= 0') + + assert_equal @a2, Gem.loaded_specs['a'] + end + + def test_gem_default_re_gem + assert gem('a', '=1') + + refute gem('a', '>= 0') + + assert_equal @a1, Gem.loaded_specs['a'] + end + + def test_gem_re_gem_mismatch + assert gem('a', '=1') + + assert_raises Gem::LoadError do + gem('a', '= 2') + end + + assert_equal @a1, Gem.loaded_specs['a'] + end + + def test_gem_redundant + assert gem('a', '= 1'), "Should load" + refute gem('a', '= 1'), "Should not load" + assert_equal 1, $:.select { |p| %r{a-1/lib} =~ p }.size + end + + def test_gem_overlapping + assert gem('a', '= 1'), "Should load" + refute gem('a', '>= 1'), "Should not load" + assert_equal 1, $:.select { |p| %r{a-1/lib} =~ p }.size + end + + def test_gem_prerelease + quick_gem 'd', '1.1.a' + refute gem('d', '>= 1'), 'release requirement must not load prerelease' + assert gem('d', '>= 1.a'), 'prerelease requirement may load prerelease' + end + + def test_gem_conflicting + assert gem('a', '= 1'), "Should load" + + ex = assert_raises Gem::LoadError do + gem 'a', '= 2' + end + + assert_equal "can't activate a-2, already activated a-1", ex.message + assert_match(/activated a-1/, ex.message) + assert_equal 'a', ex.name + + assert $:.any? { |p| %r{a-1/lib} =~ p } + refute $:.any? { |p| %r{a-2/lib} =~ p } + end + + def test_gem_not_adding_bin + assert gem('a', '= 1'), "Should load" + refute $:.any? { |p| %r{a-1/bin} =~ p } + end +end diff --git a/jni/ruby/test/rubygems/test_require.rb b/jni/ruby/test/rubygems/test_require.rb new file mode 100644 index 0000000..dec5285 --- /dev/null +++ b/jni/ruby/test/rubygems/test_require.rb @@ -0,0 +1,275 @@ +require 'rubygems/test_case' +require 'rubygems' + +class TestGemRequire < Gem::TestCase + class Latch + def initialize count = 1 + @count = count + @lock = Monitor.new + @cv = @lock.new_cond + end + + def release + @lock.synchronize do + @count -= 1 if @count > 0 + @cv.broadcast if @count.zero? + end + end + + def await + @lock.synchronize do + @cv.wait_while { @count > 0 } + end + end + end + + def setup + super + + assert_raises LoadError do + save_loaded_features do + require 'test_gem_require_a' + end + end + end + + def assert_require(path) + assert require(path), "'#{path}' was already required" + end + + def append_latch spec + dir = spec.gem_dir + Dir.chdir dir do + spec.files.each do |file| + File.open file, 'a' do |fp| + fp.puts "FILE_ENTERED_LATCH.release" + fp.puts "FILE_EXIT_LATCH.await" + end + end + end + end + + def test_concurrent_require + Object.const_set :FILE_ENTERED_LATCH, Latch.new(2) + Object.const_set :FILE_EXIT_LATCH, Latch.new(1) + + a1 = new_spec "a", "1", nil, "lib/a.rb" + b1 = new_spec "b", "1", nil, "lib/b.rb" + + install_specs a1, b1 + + append_latch a1 + append_latch b1 + + t1 = Thread.new { assert_require 'a' } + t2 = Thread.new { assert_require 'b' } + + # wait until both files are waiting on the exit latch + FILE_ENTERED_LATCH.await + + # now let them finish + FILE_EXIT_LATCH.release + + assert t1.join, "thread 1 should exit" + assert t2.join, "thread 2 should exit" + ensure + Object.send :remove_const, :FILE_ENTERED_LATCH + Object.send :remove_const, :FILE_EXIT_LATCH + end + + def test_require_is_not_lazy_with_exact_req + a1 = new_spec "a", "1", {"b" => "= 1"}, "lib/test_gem_require_a.rb" + b1 = new_spec "b", "1", nil, "lib/b/c.rb" + b2 = new_spec "b", "2", nil, "lib/b/c.rb" + + install_specs a1, b1, b2 + + save_loaded_features do + assert_require 'test_gem_require_a' + assert_equal %w(a-1 b-1), loaded_spec_names + assert_equal unresolved_names, [] + + assert_require "b/c" + assert_equal %w(a-1 b-1), loaded_spec_names + end + end + + def test_require_is_lazy_with_inexact_req + a1 = new_spec "a", "1", {"b" => ">= 1"}, "lib/test_gem_require_a.rb" + b1 = new_spec "b", "1", nil, "lib/b/c.rb" + b2 = new_spec "b", "2", nil, "lib/b/c.rb" + + install_specs a1, b1, b2 + + save_loaded_features do + assert_require 'test_gem_require_a' + assert_equal %w(a-1), loaded_spec_names + assert_equal unresolved_names, ["b (>= 1)"] + + assert_require "b/c" + assert_equal %w(a-1 b-2), loaded_spec_names + end + end + + def test_require_is_not_lazy_with_one_possible + a1 = new_spec "a", "1", {"b" => ">= 1"}, "lib/test_gem_require_a.rb" + b1 = new_spec "b", "1", nil, "lib/b/c.rb" + + install_specs a1, b1 + + save_loaded_features do + assert_require 'test_gem_require_a' + assert_equal %w(a-1 b-1), loaded_spec_names + assert_equal unresolved_names, [] + + assert_require "b/c" + assert_equal %w(a-1 b-1), loaded_spec_names + end + end + + def test_require_can_use_a_pathname_object + a1 = new_spec "a", "1", nil, "lib/test_gem_require_a.rb" + + install_specs a1 + + save_loaded_features do + assert_require Pathname.new 'test_gem_require_a' + assert_equal %w(a-1), loaded_spec_names + assert_equal unresolved_names, [] + end + end + + def test_activate_via_require_respects_loaded_files + require 'benchmark' # stdlib + save_loaded_features do + a1 = new_spec "a", "1", {"b" => ">= 1"}, "lib/test_gem_require_a.rb" + b1 = new_spec "b", "1", nil, "lib/benchmark.rb" + b2 = new_spec "b", "2", nil, "lib/benchmark.rb" + + install_specs a1, b1, b2 + + require 'test_gem_require_a' + assert_equal unresolved_names, ["b (>= 1)"] + + refute require('benchmark'), "benchmark should have already been loaded" + + # We detected that we should activate b-2, so we did so, but + # then original_require decided "I've already got benchmark.rb" loaded. + # This case is fine because our lazy loading is provided exactly + # the same behavior as eager loading would have. + + assert_equal %w(a-1 b-2), loaded_spec_names + end + end + + def test_already_activated_direct_conflict + save_loaded_features do + a1 = new_spec "a", "1", { "b" => "> 0" } + b1 = new_spec "b", "1", { "c" => ">= 1" }, "lib/ib.rb" + b2 = new_spec "b", "2", { "c" => ">= 2" }, "lib/ib.rb" + c1 = new_spec "c", "1", nil, "lib/d.rb" + c2 = new_spec("c", "2", nil, "lib/d.rb") + + install_specs a1, b1, b2, c1, c2 + + a1.activate + c1.activate + assert_equal %w(a-1 c-1), loaded_spec_names + assert_equal ["b (> 0)"], unresolved_names + + assert require("ib") + + assert_equal %w(a-1 b-1 c-1), loaded_spec_names + assert_equal [], unresolved_names + end + end + + def test_multiple_gems_with_the_same_path + save_loaded_features do + a1 = new_spec "a", "1", { "b" => "> 0", "x" => "> 0" } + b1 = new_spec "b", "1", { "c" => ">= 1" }, "lib/ib.rb" + b2 = new_spec "b", "2", { "c" => ">= 2" }, "lib/ib.rb" + x1 = new_spec "x", "1", nil, "lib/ib.rb" + x2 = new_spec "x", "2", nil, "lib/ib.rb" + c1 = new_spec "c", "1", nil, "lib/d.rb" + c2 = new_spec("c", "2", nil, "lib/d.rb") + + install_specs a1, b1, b2, c1, c2, x1, x2 + + a1.activate + c1.activate + assert_equal %w(a-1 c-1), loaded_spec_names + assert_equal ["b (> 0)", "x (> 0)"], unresolved_names + + e = assert_raises(Gem::LoadError) do + require("ib") + end + + assert_equal "ib found in multiple gems: b, x", e.message + end + end + + def test_unable_to_find_good_unresolved_version + save_loaded_features do + a1 = new_spec "a", "1", { "b" => "> 0" } + b1 = new_spec "b", "1", { "c" => ">= 2" }, "lib/ib.rb" + b2 = new_spec "b", "2", { "c" => ">= 3" }, "lib/ib.rb" + + c1 = new_spec "c", "1", nil, "lib/d.rb" + c2 = new_spec "c", "2", nil, "lib/d.rb" + c3 = new_spec "c", "3", nil, "lib/d.rb" + + install_specs a1, b1, b2, c1, c2, c3 + + a1.activate + c1.activate + assert_equal %w(a-1 c-1), loaded_spec_names + assert_equal ["b (> 0)"], unresolved_names + + e = assert_raises(Gem::LoadError) do + require("ib") + end + + assert_equal "unable to find a version of 'b' to activate", e.message + end + end + + def test_default_gem_only + save_loaded_features do + default_gem_spec = new_default_spec("default", "2.0.0.0", + nil, "default/gem.rb") + install_default_specs(default_gem_spec) + assert_require "default/gem" + assert_equal %w(default-2.0.0.0), loaded_spec_names + end + end + + def test_default_gem_and_normal_gem + save_loaded_features do + default_gem_spec = new_default_spec("default", "2.0.0.0", + nil, "default/gem.rb") + install_default_specs(default_gem_spec) + normal_gem_spec = new_spec("default", "3.0", nil, + "lib/default/gem.rb") + install_specs(normal_gem_spec) + assert_require "default/gem" + assert_equal %w(default-3.0), loaded_spec_names + end + end + + def loaded_spec_names + Gem.loaded_specs.values.map(&:full_name).sort + end + + def unresolved_names + Gem::Specification.unresolved_deps.values.map(&:to_s).sort + end + + def save_loaded_features + old_loaded_features = $LOADED_FEATURES.dup + yield + ensure + $LOADED_FEATURES.replace old_loaded_features + end + +end diff --git a/jni/ruby/test/rubygems/wrong_key_cert.pem b/jni/ruby/test/rubygems/wrong_key_cert.pem new file mode 100644 index 0000000..821eba7 --- /dev/null +++ b/jni/ruby/test/rubygems/wrong_key_cert.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7jCCAdagAwIBAgIBEjANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv +ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTEyMTIwODAwMDAwMFoYDzk5 +OTkxMjMxMjM1OTU5WjAqMQ8wDQYDVQQDDAZub2JvZHkxFzAVBgoJkiaJk/IsZAEZ +FgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvZQipBa1 +xH3M9OonkrUYhGZeX9UHAcJhe6jJbUr/uHXkh1Tu2ERWNnblm85upqBfjyZEnKer +7uBcwwkkvmisVgC8uBECymsBxuEIw0rfiKYEnLu0B6SiWFYz3dYPS92bBK7Vks2/ +kNyXUmLLGoZ3id2K0eK5C/AJ0j+p84OqPnVhylsjrZmXfIZrh7lkHhgCIrzPefjE +3pOloi/tz6fh2ktb0FYKQMfweT3Ba2TMeflG13PEOW80AD5w0THxDutGG0zPNCDy +DEoT7UU1a3B3RMHYuUxEk1GUEYWq9L6a6SMpZISWTSpCp0Ww1QB55PONiCCn+o6v +cIy46jI71dATAQIDAQABox0wGzAZBgNVHREEEjAQgQ5ub2JvZHlAZXhhbXBsZTAN +BgkqhkiG9w0BAQUFAAOCAQEATOGl3DvDpWn6pOAjNkZz67UYNlTANSzMaXklJmxW +pQGxy1g+CWRwExfbH7lYAOag3BB7X7h3RolLGhIpxmWriby+SFd/VJAOpCq4nz5P +6spZ4hqkXchBGzBgbK6TSyNxjITC3iquBBJWTXZMAuvRTuSlZsCe2k0uWJ8ycmge +wKhcdDLwVwCz2aMAGbwr/nZyzuIx/pkI3PWMw5Xk9PLUryaYHRSSFGm7mYQ6G7HE +7yn0ZIy7nQxrsVYOV3MMyEJNRBld+MgnGfDMf5gZIH6k4NbRNKABtiCKmvD3nk4h +3A863HaHH6wa8yKHXfyN71m/QwzaH3AbaORqKhfHl2uysQ== +-----END CERTIFICATE----- diff --git a/jni/ruby/test/rubygems/wrong_key_cert_32.pem b/jni/ruby/test/rubygems/wrong_key_cert_32.pem new file mode 100644 index 0000000..49ecb15 --- /dev/null +++ b/jni/ruby/test/rubygems/wrong_key_cert_32.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7DCCAdSgAwIBAgIBEzANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv +ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTEyMTIwODAwMDAwMFoXDTM4 +MDExOTAzMTQwN1owKjEPMA0GA1UEAwwGbm9ib2R5MRcwFQYKCZImiZPyLGQBGRYH +ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL2UIqQWtcR9 +zPTqJ5K1GIRmXl/VBwHCYXuoyW1K/7h15IdU7thEVjZ25ZvObqagX48mRJynq+7g +XMMJJL5orFYAvLgRAsprAcbhCMNK34imBJy7tAekolhWM93WD0vdmwSu1ZLNv5Dc +l1JiyxqGd4nditHiuQvwCdI/qfODqj51YcpbI62Zl3yGa4e5ZB4YAiK8z3n4xN6T +paIv7c+n4dpLW9BWCkDH8Hk9wWtkzHn5RtdzxDlvNAA+cNEx8Q7rRhtMzzQg8gxK +E+1FNWtwd0TB2LlMRJNRlBGFqvS+mukjKWSElk0qQqdFsNUAeeTzjYggp/qOr3CM +uOoyO9XQEwECAwEAAaMdMBswGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwDQYJ +KoZIhvcNAQEFBQADggEBAArsJU2zZfkHI90XNz69wSIrPMytM2Le0uFTXU4GUBix +8G4451leIwRD8fIMBlc82iE39PjsF8w4svCMqyVHzv10xEjIZq5917hbvxupKKM/ +UX6u3TWEpF9j5s+JtXT+yfyG1TyWXp+Dqlx455I9oRyUJkRe7UeqUqqiResJBTV/ +aImNyeG33MFKilQEyxz0UVZBjSy/JZlTUwAV3dqvh1tRSXfMmk2hxbkiewYIJ48f +Vu5uEnW1m866WLUIo0dz/KnGZ9aIq2XM+OhRl94MOpZ5tgA8e2R9RFDfzthbCnfU +G+cnGdtRxnyo0/+SmC7WhSpfSZ7wju9Z04zGa6VsMjI= +-----END CERTIFICATE----- |