From 9694bb8cac12969300692dac5a1cf7aa4e3a46cd Mon Sep 17 00:00:00 2001 From: drbrain Date: Thu, 29 Nov 2012 06:52:18 +0000 Subject: * lib/rubygems*: Updated to RubyGems 2.0 * test/rubygems*: ditto. * common.mk (prelude): Updated for RubyGems 2.0 source rearrangement. * tool/change_maker.rb: Allow invalid UTF-8 characters in source files. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37976 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- test/rubygems/alternate_cert.pem | 9 + test/rubygems/alternate_cert_32.pem | 9 + test/rubygems/alternate_key.pem | 9 + test/rubygems/bad_rake.rb | 1 + test/rubygems/child_cert.pem | 9 + test/rubygems/child_cert_32.pem | 9 + test/rubygems/child_key.pem | 9 + test/rubygems/data/null-type.gemspec.rz | Bin 553 -> 554 bytes test/rubygems/expired_cert.pem | 9 + test/rubygems/future_cert.pem | 9 + test/rubygems/future_cert_32.pem | 9 + test/rubygems/good_rake.rb | 1 + test/rubygems/grandchild_cert.pem | 9 + test/rubygems/grandchild_cert_32.pem | 9 + test/rubygems/grandchild_key.pem | 9 + test/rubygems/invalid_issuer_cert.pem | 9 + test/rubygems/invalid_issuer_cert_32.pem | 9 + test/rubygems/invalid_key.pem | 9 + test/rubygems/invalid_signer_cert.pem | 9 + test/rubygems/invalid_signer_cert_32.pem | 9 + test/rubygems/invalidchild_cert.pem | 9 + test/rubygems/invalidchild_cert_32.pem | 9 + test/rubygems/invalidchild_key.pem | 9 + test/rubygems/plugin/exception/rubygems_plugin.rb | 2 +- .../plugin/standarderror/rubygems_plugin.rb | 2 +- test/rubygems/private_key.pem | 32 +- test/rubygems/public_cert.pem | 26 +- test/rubygems/public_cert_32.pem | 10 + test/rubygems/public_key.pem | 4 + test/rubygems/rubygems/commands/crash_command.rb | 2 +- test/rubygems/test_config.rb | 10 +- test/rubygems/test_deprecate.rb | 76 +++ test/rubygems/test_gem.rb | 366 ++++++++--- test/rubygems/test_gem_available_set.rb | 106 ++++ test/rubygems/test_gem_builder.rb | 44 -- test/rubygems/test_gem_command.rb | 10 + test/rubygems/test_gem_command_manager.rb | 64 +- test/rubygems/test_gem_commands_build_command.rb | 30 +- test/rubygems/test_gem_commands_cert_command.rb | 483 ++++++++++++-- test/rubygems/test_gem_commands_cleanup_command.rb | 19 + .../rubygems/test_gem_commands_contents_command.rb | 23 + .../test_gem_commands_dependency_command.rb | 5 + test/rubygems/test_gem_commands_fetch_command.rb | 39 +- .../test_gem_commands_generate_index_command.rb | 85 +-- test/rubygems/test_gem_commands_help_command.rb | 3 +- test/rubygems/test_gem_commands_install_command.rb | 695 +++++++++++++++++++-- test/rubygems/test_gem_commands_mirror.rb | 32 + test/rubygems/test_gem_commands_owner_command.rb | 12 +- .../rubygems/test_gem_commands_pristine_command.rb | 103 ++- test/rubygems/test_gem_commands_push_command.rb | 70 ++- test/rubygems/test_gem_commands_query_command.rb | 51 ++ test/rubygems/test_gem_commands_search_command.rb | 25 + test/rubygems/test_gem_commands_sources_command.rb | 27 +- .../test_gem_commands_specification_command.rb | 34 +- .../test_gem_commands_uninstall_command.rb | 122 +++- test/rubygems/test_gem_commands_unpack_command.rb | 6 +- test/rubygems/test_gem_commands_update_command.rb | 94 +-- test/rubygems/test_gem_commands_which_command.rb | 8 +- test/rubygems/test_gem_commands_yank_command.rb | 97 +++ test/rubygems/test_gem_config_file.rb | 87 ++- test/rubygems/test_gem_dependency.rb | 46 ++ test/rubygems/test_gem_dependency_installer.rb | 246 +++++++- test/rubygems/test_gem_dependency_list.rb | 9 - test/rubygems/test_gem_dependency_resolver.rb | 327 ++++++++++ test/rubygems/test_gem_doc_manager.rb | 32 - test/rubygems/test_gem_ext_ext_conf_builder.rb | 13 +- test/rubygems/test_gem_ext_rake_builder.rb | 26 +- test/rubygems/test_gem_format.rb | 88 --- test/rubygems/test_gem_gem_path_searcher.rb | 94 --- test/rubygems/test_gem_gem_runner.rb | 32 +- test/rubygems/test_gem_gemcutter_utilities.rb | 19 + test/rubygems/test_gem_indexer.rb | 295 ++------- test/rubygems/test_gem_install_update_options.rb | 86 ++- test/rubygems/test_gem_installer.rb | 405 ++++++------ test/rubygems/test_gem_local_remote_options.rb | 10 +- test/rubygems/test_gem_name_tuple.rb | 15 + test/rubygems/test_gem_package.rb | 547 ++++++++++++++++ test/rubygems/test_gem_package_old.rb | 37 ++ test/rubygems/test_gem_package_tar_input.rb | 129 ---- test/rubygems/test_gem_package_tar_output.rb | 101 --- test/rubygems/test_gem_package_tar_reader.rb | 32 + test/rubygems/test_gem_package_tar_writer.rb | 85 ++- test/rubygems/test_gem_path_support.rb | 34 +- test/rubygems/test_gem_platform.rb | 12 +- test/rubygems/test_gem_rdoc.rb | 245 ++++++++ test/rubygems/test_gem_remote_fetcher.rb | 73 ++- test/rubygems/test_gem_request_set.rb | 70 +++ test/rubygems/test_gem_requirement.rb | 61 +- test/rubygems/test_gem_security.rb | 232 +++++-- test/rubygems/test_gem_security_policy.rb | 376 +++++++++++ test/rubygems/test_gem_security_signer.rb | 189 ++++++ test/rubygems/test_gem_security_trust_dir.rb | 94 +++ test/rubygems/test_gem_server.rb | 67 +- test/rubygems/test_gem_source.rb | 188 ++++++ test/rubygems/test_gem_source_index.rb | 250 -------- test/rubygems/test_gem_source_list.rb | 87 +++ test/rubygems/test_gem_source_local.rb | 83 +++ test/rubygems/test_gem_source_specific_file.rb | 33 + test/rubygems/test_gem_spec_fetcher.rb | 346 +++------- test/rubygems/test_gem_specification.rb | 338 ++++++++-- test/rubygems/test_gem_uninstaller.rb | 147 ++++- test/rubygems/test_gem_validator.rb | 55 +- test/rubygems/test_gem_version.rb | 25 +- test/rubygems/test_require.rb | 193 ++++++ test/rubygems/wrong_key_cert.pem | 9 + test/rubygems/wrong_key_cert_32.pem | 9 + 106 files changed, 6736 insertions(+), 2240 deletions(-) create mode 100644 test/rubygems/alternate_cert.pem create mode 100644 test/rubygems/alternate_cert_32.pem create mode 100644 test/rubygems/alternate_key.pem create mode 100644 test/rubygems/bad_rake.rb create mode 100644 test/rubygems/child_cert.pem create mode 100644 test/rubygems/child_cert_32.pem create mode 100644 test/rubygems/child_key.pem create mode 100644 test/rubygems/expired_cert.pem create mode 100644 test/rubygems/future_cert.pem create mode 100644 test/rubygems/future_cert_32.pem create mode 100644 test/rubygems/good_rake.rb create mode 100644 test/rubygems/grandchild_cert.pem create mode 100644 test/rubygems/grandchild_cert_32.pem create mode 100644 test/rubygems/grandchild_key.pem create mode 100644 test/rubygems/invalid_issuer_cert.pem create mode 100644 test/rubygems/invalid_issuer_cert_32.pem create mode 100644 test/rubygems/invalid_key.pem create mode 100644 test/rubygems/invalid_signer_cert.pem create mode 100644 test/rubygems/invalid_signer_cert_32.pem create mode 100644 test/rubygems/invalidchild_cert.pem create mode 100644 test/rubygems/invalidchild_cert_32.pem create mode 100644 test/rubygems/invalidchild_key.pem create mode 100644 test/rubygems/public_cert_32.pem create mode 100644 test/rubygems/public_key.pem create mode 100644 test/rubygems/test_deprecate.rb create mode 100644 test/rubygems/test_gem_available_set.rb delete mode 100644 test/rubygems/test_gem_builder.rb create mode 100644 test/rubygems/test_gem_commands_mirror.rb create mode 100644 test/rubygems/test_gem_commands_search_command.rb create mode 100644 test/rubygems/test_gem_commands_yank_command.rb create mode 100644 test/rubygems/test_gem_dependency_resolver.rb delete mode 100644 test/rubygems/test_gem_doc_manager.rb delete mode 100644 test/rubygems/test_gem_format.rb delete mode 100644 test/rubygems/test_gem_gem_path_searcher.rb create mode 100644 test/rubygems/test_gem_name_tuple.rb create mode 100644 test/rubygems/test_gem_package.rb create mode 100644 test/rubygems/test_gem_package_old.rb delete mode 100644 test/rubygems/test_gem_package_tar_input.rb delete mode 100644 test/rubygems/test_gem_package_tar_output.rb create mode 100644 test/rubygems/test_gem_rdoc.rb create mode 100644 test/rubygems/test_gem_request_set.rb create mode 100644 test/rubygems/test_gem_security_policy.rb create mode 100644 test/rubygems/test_gem_security_signer.rb create mode 100644 test/rubygems/test_gem_security_trust_dir.rb create mode 100644 test/rubygems/test_gem_source.rb delete mode 100644 test/rubygems/test_gem_source_index.rb create mode 100644 test/rubygems/test_gem_source_list.rb create mode 100644 test/rubygems/test_gem_source_local.rb create mode 100644 test/rubygems/test_gem_source_specific_file.rb create mode 100644 test/rubygems/test_require.rb create mode 100644 test/rubygems/wrong_key_cert.pem create mode 100644 test/rubygems/wrong_key_cert_32.pem (limited to 'test/rubygems') diff --git a/test/rubygems/alternate_cert.pem b/test/rubygems/alternate_cert.pem new file mode 100644 index 0000000000..7596db77b2 --- /dev/null +++ b/test/rubygems/alternate_cert.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBSjCB9aADAgECAgEBMA0GCSqGSIb3DQEBBQUAMC0xEjAQBgNVBAMMCWFsdGVy +bmF0ZTEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwIBcNMTIwMTIzMjM0MzIzWhgP +OTk5OTEyMzEyMzU5NTlaMC0xEjAQBgNVBAMMCWFsdGVybmF0ZTEXMBUGCgmSJomT +8ixkARkWB2V4YW1wbGUwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA0lN/jShlFg0t ++h1L2gkdi2UXFnfLnXNh+J3Jolh4/Pd8rdzKTdnCep2nqDIRimnlEjO1+I3u7aur +Uc4b1AhX5QIDAQABMA0GCSqGSIb3DQEBBQUAA0EAidcjR8U5VFcds1Tv8bnz3Z+P +w7lmN1HOmwnQht1ZTVbqmqKzxEXgf4AkZRoIT96gPRV87HwJ5PP/pDYmv3LR8g== +-----END CERTIFICATE----- diff --git a/test/rubygems/alternate_cert_32.pem b/test/rubygems/alternate_cert_32.pem new file mode 100644 index 0000000000..a588b242b6 --- /dev/null +++ b/test/rubygems/alternate_cert_32.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBSDCB86ADAgECAgEBMA0GCSqGSIb3DQEBBQUAMC0xEjAQBgNVBAMMCWFsdGVy +bmF0ZTEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwHhcNMTIwMTEyMjMwODI5WhcN +MzgwMTE5MDMxNDA3WjAtMRIwEAYDVQQDDAlhbHRlcm5hdGUxFzAVBgoJkiaJk/Is +ZAEZFgdleGFtcGxlMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANJTf40oZRYNLfod +S9oJHYtlFxZ3y51zYfidyaJYePz3fK3cyk3Zwnqdp6gyEYpp5RIztfiN7u2rq1HO +G9QIV+UCAwEAATANBgkqhkiG9w0BAQUFAANBAH9YxSERfWdqipZbQGDmx2F8e5O2 +6zbDialEy+bD8juhzWa6nIPaoQzeSkD0lw98OXpVyE0vhnGS1rlVH3725Xw= +-----END CERTIFICATE----- diff --git a/test/rubygems/alternate_key.pem b/test/rubygems/alternate_key.pem new file mode 100644 index 0000000000..7fb6eff614 --- /dev/null +++ b/test/rubygems/alternate_key.pem @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBOgIBAAJBANJTf40oZRYNLfodS9oJHYtlFxZ3y51zYfidyaJYePz3fK3cyk3Z +wnqdp6gyEYpp5RIztfiN7u2rq1HOG9QIV+UCAwEAAQJAAM1kvSscR5tBQ6T89xX1 +0ORP1DwcwLsB8qrXbBEeVQiy4aAcfUgKbMxiSEL3iogoHnKK6VFmu4bH4v360dJl +OQIhAO97aiKxP6u+Y1oNyScF2lViu81xR4jlL/DjD8I+oBr/AiEA4NVFey13ks3U +2DTHU3qhU6y+MmYv0aCInf49hMt1gRsCIQCvSiR71EWIjkjmh6Su3Yfca/KPA9Wa +jDc1GN5WDcTfPQIgaYzWLKjAvQOyi7njZdZpTG4JcIG2q1QRLxL/cItP48cCIFvI +/R7PnPrVdF5G2QT7DZyrHjjtqnyW76zwU3MSxZMJ +-----END RSA PRIVATE KEY----- diff --git a/test/rubygems/bad_rake.rb b/test/rubygems/bad_rake.rb new file mode 100644 index 0000000000..379a4c986e --- /dev/null +++ b/test/rubygems/bad_rake.rb @@ -0,0 +1 @@ +exit 1 diff --git a/test/rubygems/child_cert.pem b/test/rubygems/child_cert.pem new file mode 100644 index 0000000000..932bda83a4 --- /dev/null +++ b/test/rubygems/child_cert.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBQzCB7qADAgECAgEBMA0GCSqGSIb3DQEBBQUAMCoxDzANBgNVBAMMBm5vYm9k +eTEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwIBcNMTIwMTEzMDAxNTE4WhgPOTk5 +OTEyMzEyMzU5NTlaMCkxDjAMBgNVBAMMBWNoaWxkMRcwFQYKCZImiZPyLGQBGRYH +ZXhhbXBsZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC93Mml1yQmsUDalFT1PH4z +z8Al8ki969L/NHUWdkG6DuM0krWiWPBkO+Moj+6NMH2TrGWyHPfYv5zQ3zn9ai+d +AgMBAAEwDQYJKoZIhvcNAQEFBQADQQCKb9V9Wl6hQNuDsn38Ceg6gCh9hXqvHrCz +/pzoFjTxZfsYCNapXp1hzb8cUijzi2YalXzUpg7zgEowLZpZD94s +-----END CERTIFICATE----- diff --git a/test/rubygems/child_cert_32.pem b/test/rubygems/child_cert_32.pem new file mode 100644 index 0000000000..b36f5729f9 --- /dev/null +++ b/test/rubygems/child_cert_32.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBQzCB7qADAgECAgEBMA0GCSqGSIb3DQEBBQUAMCoxDzANBgNVBAMMBm5vYm9k +eTEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwIBcNMTIwMTEzMDAxNTE4WhgPMjAz +ODAxMTkwMzE0MDdaMCkxDjAMBgNVBAMMBWNoaWxkMRcwFQYKCZImiZPyLGQBGRYH +ZXhhbXBsZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC93Mml1yQmsUDalFT1PH4z +z8Al8ki969L/NHUWdkG6DuM0krWiWPBkO+Moj+6NMH2TrGWyHPfYv5zQ3zn9ai+d +AgMBAAEwDQYJKoZIhvcNAQEFBQADQQB7JhifNXK4PTYVZv5NYmqyi4ze7h2sxxNl +hqjzIj+GFsf/5uFt0Oz/n8VCE/LEWVKhejiyiaLxN7nLjszW7EGq +-----END CERTIFICATE----- diff --git a/test/rubygems/child_key.pem b/test/rubygems/child_key.pem new file mode 100644 index 0000000000..a1c4613ccc --- /dev/null +++ b/test/rubygems/child_key.pem @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBOgIBAAJBAL3cyaXXJCaxQNqUVPU8fjPPwCXySL3r0v80dRZ2QboO4zSStaJY +8GQ74yiP7o0wfZOsZbIc99i/nNDfOf1qL50CAwEAAQJAEBEhF2Gvc37IiDbJQb+O +xn+sOQnZ0gik4GfmCLKVOVNn4mxJI2fJe/6qUyt5Bp0nTuY+jfx9XFIlx3A3QZY6 +mQIhAN0E92rtcTvTy5lPO+hAeUQu59q6+HzC7HJJOevPWlqrAiEA2+lvvNOyZXUD +VmlyexQ1VdNLQtqRWtQd2PBtg0W4HtcCIAU7C9v0+JwQ3B2puWI6vGP3tDcB+8WA +G3Zs8zj4dEv3AiBdSLB1UPejwfcgeKpvOytEtNSAD2cJOGFQ3OwXe0OXEQIhAJXR +I7JTU0DJF+dqpR7jr1hQSXibdEXP7MIJUSK4uLUs +-----END RSA PRIVATE KEY----- diff --git a/test/rubygems/data/null-type.gemspec.rz b/test/rubygems/data/null-type.gemspec.rz index b1d0a6d7cd..bad99289d1 100644 Binary files a/test/rubygems/data/null-type.gemspec.rz and b/test/rubygems/data/null-type.gemspec.rz differ diff --git a/test/rubygems/expired_cert.pem b/test/rubygems/expired_cert.pem new file mode 100644 index 0000000000..502b461514 --- /dev/null +++ b/test/rubygems/expired_cert.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBQjCB7aADAgECAgEBMA0GCSqGSIb3DQEBBQUAMCoxDzANBgNVBAMMBm5vYm9k +eTEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwHhcNNzAwMTAxMDAwMDAwWhcNNzAw +MTAxMDAwMDAwWjAqMQ8wDQYDVQQDDAZub2JvZHkxFzAVBgoJkiaJk/IsZAEZFgdl +eGFtcGxlMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALHKBD9e+mrCnQ7Xs2fdEhxa ++0mpObjlK7dL6hoNF190aoLwQ6xwiCAMT7WPVs4/XW81Nssq2RkHGiWGxIXnMlsC +AwEAATANBgkqhkiG9w0BAQUFAANBAE3nKONBLbE97pTsIpM6v8bzCVhtVPfS+6F7 +6WnIDuVUyN0pmVlWqRuEm8WZtrwnu1D6CGNTWwescrIEbQV6dvc= +-----END CERTIFICATE----- diff --git a/test/rubygems/future_cert.pem b/test/rubygems/future_cert.pem new file mode 100644 index 0000000000..32234bfe37 --- /dev/null +++ b/test/rubygems/future_cert.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBRjCB8aADAgECAgEBMA0GCSqGSIb3DQEBBQUAMCoxDzANBgNVBAMMBm5vYm9k +eTEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwIhgPOTk5OTEyMzEyMzU5NThaGA85 +OTk5MTIzMTIzNTk1OVowKjEPMA0GA1UEAwwGbm9ib2R5MRcwFQYKCZImiZPyLGQB +GRYHZXhhbXBsZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQCxygQ/Xvpqwp0O17Nn +3RIcWvtJqTm45Su3S+oaDRdfdGqC8EOscIggDE+1j1bOP11vNTbLKtkZBxolhsSF +5zJbAgMBAAEwDQYJKoZIhvcNAQEFBQADQQB0blKxIt6IfzaHHBgMfJwkwtEoDEey +OEtjX5oz9L0P+l/KjssEFk4fzPiVFHmx9y3KCXhapVvHcgeY7IKGHK7z +-----END CERTIFICATE----- diff --git a/test/rubygems/future_cert_32.pem b/test/rubygems/future_cert_32.pem new file mode 100644 index 0000000000..ccff23d8aa --- /dev/null +++ b/test/rubygems/future_cert_32.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBSDCB86ADAgECAgEBMA0GCSqGSIb3DQEBBQUAMC0xEjAQBgNVBAMMCWFsdGVy +bmF0ZTEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwHhcNMzgwMTE5MDMxNDA2WhcN +MzgwMTE5MDMxNDA3WjAtMRIwEAYDVQQDDAlhbHRlcm5hdGUxFzAVBgoJkiaJk/Is +ZAEZFgdleGFtcGxlMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALHKBD9e+mrCnQ7X +s2fdEhxa+0mpObjlK7dL6hoNF190aoLwQ6xwiCAMT7WPVs4/XW81Nssq2RkHGiWG +xIXnMlsCAwEAATANBgkqhkiG9w0BAQUFAANBAG7xn/s1GqtjdNA92OOwLP84N7hQ +Xa4tBtYaP84rC4LJhkYWdhTIM4YM3UpG9obxL1Xh1+92kLTN3/KpLK4EcQQ= +-----END CERTIFICATE----- diff --git a/test/rubygems/good_rake.rb b/test/rubygems/good_rake.rb new file mode 100644 index 0000000000..ca916d098d --- /dev/null +++ b/test/rubygems/good_rake.rb @@ -0,0 +1 @@ +exit 0 diff --git a/test/rubygems/grandchild_cert.pem b/test/rubygems/grandchild_cert.pem new file mode 100644 index 0000000000..d246e91544 --- /dev/null +++ b/test/rubygems/grandchild_cert.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBRzCB8qADAgECAgEBMA0GCSqGSIb3DQEBBQUAMCkxDjAMBgNVBAMMBWNoaWxk +MRcwFQYKCZImiZPyLGQBGRYHZXhhbXBsZTAgFw0xMjAxMTMwMTIxNTlaGA85OTk5 +MTIzMTIzNTk1OVowLjETMBEGA1UEAwwKZ3JhbmRjaGlsZDEXMBUGCgmSJomT8ixk +ARkWB2V4YW1wbGUwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA12r06nh9Pl7QTM2X +caPBi5uVLqyM8Bfinxc9/AJfEvvGCix/TFP0Y9E3qVxTc1WDsPdQqTZNqVjb8hi3 +W6246QIDAQABMA0GCSqGSIb3DQEBBQUAA0EAOdAYyauzQqU1x2KkMgf8U3vJZbPl +zIKWr8mN+eV+YyqQgIkX+/v8AAmOGPO+HJa2Ifs2DwcLdfsqQipkytTVxQ== +-----END CERTIFICATE----- diff --git a/test/rubygems/grandchild_cert_32.pem b/test/rubygems/grandchild_cert_32.pem new file mode 100644 index 0000000000..1a31e16fe7 --- /dev/null +++ b/test/rubygems/grandchild_cert_32.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBRzCB8qADAgECAgEBMA0GCSqGSIb3DQEBBQUAMCkxDjAMBgNVBAMMBWNoaWxk +MRcwFQYKCZImiZPyLGQBGRYHZXhhbXBsZTAgFw0xMjAxMTMwMTIxNTlaGA8yMDM4 +MDExOTAzMTQwN1owLjETMBEGA1UEAwwKZ3JhbmRjaGlsZDEXMBUGCgmSJomT8ixk +ARkWB2V4YW1wbGUwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA12r06nh9Pl7QTM2X +caPBi5uVLqyM8Bfinxc9/AJfEvvGCix/TFP0Y9E3qVxTc1WDsPdQqTZNqVjb8hi3 +W6246QIDAQABMA0GCSqGSIb3DQEBBQUAA0EAMEUY6jNegDA5hUJy7KD80MZCS83e +pPIQJyAtmOI+J1UR6C1/BHW0Ls1/Ko04R7DcHyGR46wttV7LB1TY7ya4OQ== +-----END CERTIFICATE----- diff --git a/test/rubygems/grandchild_key.pem b/test/rubygems/grandchild_key.pem new file mode 100644 index 0000000000..e462b044a9 --- /dev/null +++ b/test/rubygems/grandchild_key.pem @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBOgIBAAJBANdq9Op4fT5e0EzNl3GjwYublS6sjPAX4p8XPfwCXxL7xgosf0xT +9GPRN6lcU3NVg7D3UKk2TalY2/IYt1utuOkCAwEAAQJBAKpS7Td+8Tgha31uiTHX +Eq854ui2kfE8UXkMvXvGvDma2W40lkQKVLMJO0Y9zfJ+8E4+70nS0Eny+3feErLo +2aECIQDw9+BSwRVBaEIwGUD4wg8ganZvMBkmU+o+1jUKjbUgrQIhAOTbDeS1NyB5 +Zm2ViTKOMadvzwUZax86TZ1rwfMDIbStAiA9eB4DPjn722q29lo6mtZdAIuBxZVE +z7c7nE0fihKgaQIgfaDiV5JC2MjLuYxE7EOybj+qXRo++719rdThew1VC2ECIB5f +4Xzx62LvumYHJ7U56PHbAmSgAqEIixoDc+Bw9pE+ +-----END RSA PRIVATE KEY----- diff --git a/test/rubygems/invalid_issuer_cert.pem b/test/rubygems/invalid_issuer_cert.pem new file mode 100644 index 0000000000..19f2d02856 --- /dev/null +++ b/test/rubygems/invalid_issuer_cert.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBRTCB8KADAgECAgEBMA0GCSqGSIb3DQEBBQUAMCoxDzANBgNVBAMMBm5vYm9k +eTEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwIBcNMTIwMTEyMjM1NDQyWhgPOTk5 +OTEyMzEyMzU5NTlaMCsxEDAOBgNVBAMMB2ludmFsaWQxFzAVBgoJkiaJk/IsZAEZ +FgdleGFtcGxlMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANMWNw1TDxEdIz/4s6Km +4DUd3avjH4/0Fb63/nKWSbacKykvalYCVW3N3xnghgr1mWID1foiMdGZliQXfCll +yt0CAwEAATANBgkqhkiG9w0BAQUFAANBAIZzMKb/4YOk6pp0jSCDfb8CC2G7LVDt +b4LE1L2tbT1VQX34AjSprmdyrUXbjA3MYrE/w070Lr256dTr3fq7nWY= +-----END CERTIFICATE----- diff --git a/test/rubygems/invalid_issuer_cert_32.pem b/test/rubygems/invalid_issuer_cert_32.pem new file mode 100644 index 0000000000..9e4235ece5 --- /dev/null +++ b/test/rubygems/invalid_issuer_cert_32.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBQzCB7qADAgECAgEBMA0GCSqGSIb3DQEBBQUAMCoxDzANBgNVBAMMBm5vYm9k +eTEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwHhcNMTIwMTEyMjM1NTE2WhcNMzgw +MTE5MDMxNDA3WjArMRAwDgYDVQQDDAdpbnZhbGlkMRcwFQYKCZImiZPyLGQBGRYH +ZXhhbXBsZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDTFjcNUw8RHSM/+LOipuA1 +Hd2r4x+P9BW+t/5ylkm2nCspL2pWAlVtzd8Z4IYK9ZliA9X6IjHRmZYkF3wpZcrd +AgMBAAEwDQYJKoZIhvcNAQEFBQADQQBrExQicbjbw9QvQC9qVVzXLTZ6Zir6OJE7 +pTRsrSWWX7k5tgTUNhDb7xTr9njEAjwBDjMt5pry0MzM4MbT3Kiz +-----END CERTIFICATE----- diff --git a/test/rubygems/invalid_key.pem b/test/rubygems/invalid_key.pem new file mode 100644 index 0000000000..73b19e9113 --- /dev/null +++ b/test/rubygems/invalid_key.pem @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBOQIBAAJBANMWNw1TDxEdIz/4s6Km4DUd3avjH4/0Fb63/nKWSbacKykvalYC +VW3N3xnghgr1mWID1foiMdGZliQXfCllyt0CAwEAAQJAXL3z7hzCD+jXZfHlKt9a +vruiezTM1ziMnUDFwJ6bQGlLuS6BLNTTvKkJuSQ7v9Rj0gzCkOq9ipkb8jFgWyOt +AQIhAP9f0Pb4YCezCnWv5sEw1iT1TWbe0+72ICY+PEIY4Px9AiEA05qekUe1e/j9 +2ykXZxuFnM1wUO8yLhy6A71EasyKNeECICKfJeBlufuH3XIpH9qvOUkXbJ/2s7rg +6Wjl5Rt87futAiBTZIhBcSVQ6lwBVzxl4i7SERTGkL4R9jhI6PphrKJ7gQIgH8if +aoIHSpVKSt+Sheoi84v4CXE/MSU0uVPkqtUiV6A= +-----END RSA PRIVATE KEY----- diff --git a/test/rubygems/invalid_signer_cert.pem b/test/rubygems/invalid_signer_cert.pem new file mode 100644 index 0000000000..3df754e996 --- /dev/null +++ b/test/rubygems/invalid_signer_cert.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBRjCB8aADAgECAgEBMA0GCSqGSIb3DQEBBQUAMCsxEDAOBgNVBAMMB2ludmFs +aWQxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTEyMDExMzIyNDE1NVoYDzk5 +OTkxMjMxMjM1OTU5WjArMRAwDgYDVQQDDAdpbnZhbGlkMRcwFQYKCZImiZPyLGQB +GRYHZXhhbXBsZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDTFjcNUw8RHSM/+LOi +puA1Hd2r4x+P9BW+t/5ylkm2nCspL2pWAlVtzd8Z4IYK9ZliA9X6IjHRmZYkF3wp +ZcrdAgMBAAEwDQYJKoZIhvcNAQEFBQADQQBAT7aP57Q3HJW4EfPAl0anJPpAI8g1 +yWGhg/vUIUpBDImJ+jRJU9AuRGRPKWIRonOon+LV9sammaM4GWsU1FLb +-----END CERTIFICATE----- diff --git a/test/rubygems/invalid_signer_cert_32.pem b/test/rubygems/invalid_signer_cert_32.pem new file mode 100644 index 0000000000..74ec74a249 --- /dev/null +++ b/test/rubygems/invalid_signer_cert_32.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBRjCB8aADAgECAgEBMA0GCSqGSIb3DQEBBQUAMCsxEDAOBgNVBAMMB2ludmFs +aWQxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTEyMDExMzIyNDE1NVoYDzIw +MzgwMTE5MDMxNDA3WjArMRAwDgYDVQQDDAdpbnZhbGlkMRcwFQYKCZImiZPyLGQB +GRYHZXhhbXBsZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDTFjcNUw8RHSM/+LOi +puA1Hd2r4x+P9BW+t/5ylkm2nCspL2pWAlVtzd8Z4IYK9ZliA9X6IjHRmZYkF3wp +ZcrdAgMBAAEwDQYJKoZIhvcNAQEFBQADQQAXkBGQZ4sr9p2uFoluFFqQMQL11npB +UdhOTcM1XJ1KoyDhyRqD7gy7vxJf+9517eLABWyGMBPlDr7/CFPp/o/D +-----END CERTIFICATE----- diff --git a/test/rubygems/invalidchild_cert.pem b/test/rubygems/invalidchild_cert.pem new file mode 100644 index 0000000000..b12d33b64f --- /dev/null +++ b/test/rubygems/invalidchild_cert.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBSTCB9KADAgECAgEBMA0GCSqGSIb3DQEBBQUAMCkxDjAMBgNVBAMMBWNoaWxk +MRcwFQYKCZImiZPyLGQBGRYHZXhhbXBsZTAgFw0xMjAxMTMwMDQ0MTZaGA85OTk5 +MTIzMTIzNTk1OVowMDEVMBMGA1UEAwwMaW52YWxpZGNoaWxkMRcwFQYKCZImiZPy +LGQBGRYHZXhhbXBsZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC+tFy6eVKpSmHW +6QeZG1Egbtz2mcNywUvUZvXQVAMh/7qWyWkKbHAXeAeFw6ZhR3jC6MsEXCECwR+j +nH0hIp2pAgMBAAEwDQYJKoZIhvcNAQEFBQADQQBGWN8/w709gZtguup+xZ44pi7p +XDU05EFgnFM8hoN5DcCcFtiWCNkbN0AH5u+xXgotDMsEq+OwlJb8qAElaRjP +-----END CERTIFICATE----- diff --git a/test/rubygems/invalidchild_cert_32.pem b/test/rubygems/invalidchild_cert_32.pem new file mode 100644 index 0000000000..41ff2ce007 --- /dev/null +++ b/test/rubygems/invalidchild_cert_32.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBSTCB9KADAgECAgEBMA0GCSqGSIb3DQEBBQUAMCkxDjAMBgNVBAMMBWNoaWxk +MRcwFQYKCZImiZPyLGQBGRYHZXhhbXBsZTAgFw0xMjAxMTMwMDQ0MTZaGA8yMDM4 +MDExOTAzMTQwN1owMDEVMBMGA1UEAwwMaW52YWxpZGNoaWxkMRcwFQYKCZImiZPy +LGQBGRYHZXhhbXBsZTBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC+tFy6eVKpSmHW +6QeZG1Egbtz2mcNywUvUZvXQVAMh/7qWyWkKbHAXeAeFw6ZhR3jC6MsEXCECwR+j +nH0hIp2pAgMBAAEwDQYJKoZIhvcNAQEFBQADQQCjqL4JaoRhCAExVddloKxNajAh +VIpjw8FC7bdNhpCrf8bgOHR7UU8r42JdeJ0wR7TyV8a8pXxtd6GLPZvKaZbK +-----END CERTIFICATE----- diff --git a/test/rubygems/invalidchild_key.pem b/test/rubygems/invalidchild_key.pem new file mode 100644 index 0000000000..2908d6c3a7 --- /dev/null +++ b/test/rubygems/invalidchild_key.pem @@ -0,0 +1,9 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIBOgIBAAJBAL60XLp5UqlKYdbpB5kbUSBu3PaZw3LBS9Rm9dBUAyH/upbJaQps +cBd4B4XDpmFHeMLoywRcIQLBH6OcfSEinakCAwEAAQJAPdi0ce1Ct5Bd5pqwUiEf +0Erj8j2vuxmhBANYGPYGBhIe/W4I6JGvaeZgY8/vLHdBSqxYDa417+N1TkgnC8U0 +GQIhAPpE9Tx4AYxI6EhtS5RSv+yXjNmuGV3iNk9CwZy8WenLAiEAwxI+ejSU2qhn ++JhbUd2AhCwokzHPYLIln5NzG1FXN9sCIQC4FTLA+JBC7HmWlHXMMpWi49IhZzKX +YMWLxVF+BPipwwIgbd/u1QKc/XRx67JVbY0oAEqnKBGcT0jIrFNvOGneiJUCIB6d +vHfEsN61hepd+BWOnw6ProEhPAYnOIAl1eNwdVqI +-----END RSA PRIVATE KEY----- diff --git a/test/rubygems/plugin/exception/rubygems_plugin.rb b/test/rubygems/plugin/exception/rubygems_plugin.rb index affa72f09c..16c417e84d 100644 --- a/test/rubygems/plugin/exception/rubygems_plugin.rb +++ b/test/rubygems/plugin/exception/rubygems_plugin.rb @@ -1,2 +1,2 @@ TestGem::TEST_PLUGIN_EXCEPTION = :loaded -raise Exception.new('boom') \ No newline at end of file +raise Exception.new('boom') diff --git a/test/rubygems/plugin/standarderror/rubygems_plugin.rb b/test/rubygems/plugin/standarderror/rubygems_plugin.rb index d36849f144..4b577a6518 100644 --- a/test/rubygems/plugin/standarderror/rubygems_plugin.rb +++ b/test/rubygems/plugin/standarderror/rubygems_plugin.rb @@ -1,2 +1,2 @@ TestGem::TEST_PLUGIN_STANDARDERROR = :loaded -raise StandardError.new('boom') \ No newline at end of file +raise StandardError.new('boom') diff --git a/test/rubygems/private_key.pem b/test/rubygems/private_key.pem index 95b3dc76d8..5040da1ec2 100644 --- a/test/rubygems/private_key.pem +++ b/test/rubygems/private_key.pem @@ -1,27 +1,9 @@ -----BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAm24C6xixiAxO+i1f3L8XRMwrmLkt6BvT60mZ7g8HsklH3af7 -KNHA6vo/G6sujs2UsNO4HY8BTEneiVOXXWQlcsJ+Z5wEPlIu4zFueAmLefx+n9lE -ulNIUDoyUenKX4spoMRnX8k4lXL05ho/6JFq0JdDY2DmAaQ4vvTz5mh9kZiybtHQ -fzcpbA51uY+sjdQRCPDHyUUfh0SmWJlLYMwcBdVeCiGUPBLi+iP5x1btO4uiJK6Q -IMaV1H3SUCYtKGQKl7qwFd8k8ZBcHYOtmK61tupg3vqWQc0em6SxPj5lws8+1MVK -twBNIDx24jF4ntxBRNKMZ7FN5SHbobAgDYkPAQIDAQABAoIBAGQilgK8X/PUajVH -clEXU3hhSV0VQHwfIYKeYms6h6zXBVPKW0dLC0zXeDztJgueasMZQ67XaPCrTpGO -px/l2zJ6F1HM8/bqn4aDXDY9f/xRLYryQRMBgL8fHzgitNylHWaT4j2Vt7yg2SI9 -mxrMRNKqASJPVR+Nm3l6+n9gpjVb99wEucWplPPHI6KhXLYPZOqSwt+zaH5roz3k -UQmMs0Bs4hF1SzVl0n+KNoXHOwswVrmBWXgWvm2OhnwY2e26jfejc8toJc/ShAJ7 -C9exnrdimcgEKbd22Sum4G00CDYhcrG5LHHqkgwifcAEVctrvBZBZHGgpxlO8a8U -eF2Vr7kCgYEAykdrBlzp7Fn9xzUInBQ3NXTTYAq51lpuJdmHQmPuTSY0buoHkd9f -xbUCZ2qR9QAesrx4hI0qGLetc8IOKDoWx2rPepCCvO3Kx61o1SB5fAvBue03qVoq -HqACX3Uk24Em8zAz9xuP13ETH/wU7sUbUxRHMCre6ZDmlxn4g5l+Nl8CgYEAxLVl -22yBx0dfRr3UsHY9rxll2gIlnfnYfiJzq8wetzt/TfztRV5ILz7FyWqL5d7IoqkA -fT2V4HAasRJASnKohwJe7z5M/H2ExwkGNFvY+jefb2CoUl5WouK9AlhbqBk3zmHi -sY5GqQkAp/kHMntEin+sErJw6mkgAGdser3a9p8CgYEAqi31w++tunRnxw4+RRnY -7Pdx0k6T1NxV6TAe1ONAHNY0rM/mOHqml65W7GzDiU1lhlh8SIB/VzZJDqfHw15D -xdh94A7uf0bMILwrA4wDyTIW9Xa3Kpq57vQNqwPiU25QN69pOM+Ob+IpBfLOJafc -+kOINOUMj5Kh/aQS6Zzci58CgYEAk24dlFKEBjbRCvU2FrfYTYcsljPru7ZJc2gg -588J6m0WYf5CWy5pzbcviGFpzvSlzXv7GOLylQ+QgcxbETFUbDPzsT4xd0AgJwj1 -dIKuYgMUZOa94VZBer2TydEtiRS1heJJhKhM/1329u4nXceTvHYqIq1JAfeee48I -eAoZtaMCgYBz1FjWFQnMTD5nmyPEEZneoBPAR5+9jwOps+IYOoHtazoMFszzd0qo -JZW3Ihn9KRrVSxfFApKS/ZwjiZ+tJUk7DE/v/0l0sszefY7s8b0pL1lpeZSoL71e -QoG1WLXUiDV3BRlmyOAF1h3p12KRTLgwubN51ajECwcs3QwE+ZT8Gg== +MIIBOwIBAAJBALHKBD9e+mrCnQ7Xs2fdEhxa+0mpObjlK7dL6hoNF190aoLwQ6xw +iCAMT7WPVs4/XW81Nssq2RkHGiWGxIXnMlsCAwEAAQJAFhk4IfBaS/7Yqsmg4R4X +bDLa3TMNm6/QmT30YTyTVSfcMM3eum/5rDkKs/FmK80Q8vAch6frwG6zp65I+QrZ +cQIhANo21fpTGe4SoBTNugOqPsoXg+QeqXC2b0PccqbW6c5FAiEA0JMv/EgYL3KX +8lelPRq5VvDU+i8pnu4s283zmbap2B8CIQCQVvFXMZzXQ26sFCDUx8nct41AWZ/O +tH4Ir0sPXN0u2QIgHC9HlLfJTOAXWFAvrAoocW8p2IT3Atr8hNdXy7W7TdECIQC+ +PYFyUaQAl5s0r0Dl6SoQ6klTvOLRyX9nUg9vJnVWkg== -----END RSA PRIVATE KEY----- diff --git a/test/rubygems/public_cert.pem b/test/rubygems/public_cert.pem index 9b7c3d8e98..ce718d5e78 100644 --- a/test/rubygems/public_cert.pem +++ b/test/rubygems/public_cert.pem @@ -1,20 +1,10 @@ -----BEGIN CERTIFICATE----- -MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMRAwDgYDVQQDDAdkcmJy -YWluMRgwFgYKCZImiZPyLGQBGRYIc2VnbWVudDcxEzARBgoJkiaJk/IsZAEZFgNu -ZXQwHhcNMDcxMjIxMDIwNDE0WhcNMDgxMjIwMDIwNDE0WjBBMRAwDgYDVQQDDAdk -cmJyYWluMRgwFgYKCZImiZPyLGQBGRYIc2VnbWVudDcxEzARBgoJkiaJk/IsZAEZ -FgNuZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbbgLrGLGIDE76 -LV/cvxdEzCuYuS3oG9PrSZnuDweySUfdp/so0cDq+j8bqy6OzZSw07gdjwFMSd6J -U5ddZCVywn5nnAQ+Ui7jMW54CYt5/H6f2US6U0hQOjJR6cpfiymgxGdfyTiVcvTm -Gj/okWrQl0NjYOYBpDi+9PPmaH2RmLJu0dB/NylsDnW5j6yN1BEI8MfJRR+HRKZY -mUtgzBwF1V4KIZQ8EuL6I/nHVu07i6IkrpAgxpXUfdJQJi0oZAqXurAV3yTxkFwd -g62YrrW26mDe+pZBzR6bpLE+PmXCzz7UxUq3AE0gPHbiMXie3EFE0oxnsU3lIduh -sCANiQ8BAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW -BBS5k4Z75VSpdM0AclG2UvzFA/VW5DANBgkqhkiG9w0BAQUFAAOCAQEAHagT4lfX -kP/hDaiwGct7XPuVGbrOsKRVD59FF5kETBxEc9UQ1clKWngf8JoVuEoKD774dW19 -bU0GOVWO+J6FMmT/Cp7nuFJ79egMf/gy4gfUfQMuvfcr6DvZUPIs9P/TlK59iMYF -DIOQ3DxdF3rMzztNUCizN4taVscEsjCcgW6WkUJnGdqlu3OHWpQxZBJkBTjPCoc6 -UW6on70SFPmAy/5Cq0OJNGEWBfgD9q7rrs/X8GGwUWqXb85RXnUVi/P8Up75E0ag -14jEc90kN+C7oI/AGCBN0j6JnEtYIEJZibjjDJTSMWlUKKkj30kq7hlUC2CepJ4v -x52qPcexcYZR7w== +MIIBZDCCAQ6gAwIBAgIBATANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv +ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTEyMDEyNjIzNTYzOFoYDzk5 +OTkxMjMxMjM1OTU5WjAqMQ8wDQYDVQQDDAZub2JvZHkxFzAVBgoJkiaJk/IsZAEZ +FgdleGFtcGxlMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALHKBD9e+mrCnQ7Xs2fd +Ehxa+0mpObjlK7dL6hoNF190aoLwQ6xwiCAMT7WPVs4/XW81Nssq2RkHGiWGxIXn +MlsCAwEAAaMdMBswGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwDQYJKoZIhvcN +AQEFBQADQQAyMwxov898I7UD6WD588jgWPJjy89+iVIEvtFq/rHmTspBxP16/iom +oD36DRV5ir0n6mED+s2R2MaF1EMO2WVw -----END CERTIFICATE----- diff --git a/test/rubygems/public_cert_32.pem b/test/rubygems/public_cert_32.pem new file mode 100644 index 0000000000..1f9ce2a934 --- /dev/null +++ b/test/rubygems/public_cert_32.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBZDCCAQ6gAwIBAgIBATANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv +ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTEyMDEyNjIzNTYzOFoYDzIw +MzgwMTE5MDMxNDA3WjAqMQ8wDQYDVQQDDAZub2JvZHkxFzAVBgoJkiaJk/IsZAEZ +FgdleGFtcGxlMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALHKBD9e+mrCnQ7Xs2fd +Ehxa+0mpObjlK7dL6hoNF190aoLwQ6xwiCAMT7WPVs4/XW81Nssq2RkHGiWGxIXn +MlsCAwEAAaMdMBswGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwDQYJKoZIhvcN +AQEFBQADQQAMNCoCiTAT4+e+vVeHwdN2HXh+L4YhAm8OCkVtEwX7aJWe/JV6S6Ma +XNq1DX0kl6CENeztHU1EZx0CrMn1lyYg +-----END CERTIFICATE----- diff --git a/test/rubygems/public_key.pem b/test/rubygems/public_key.pem new file mode 100644 index 0000000000..d777cd256b --- /dev/null +++ b/test/rubygems/public_key.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALHKBD9e+mrCnQ7Xs2fdEhxa+0mpObjl +K7dL6hoNF190aoLwQ6xwiCAMT7WPVs4/XW81Nssq2RkHGiWGxIXnMlsCAwEAAQ== +-----END PUBLIC KEY----- diff --git a/test/rubygems/rubygems/commands/crash_command.rb b/test/rubygems/rubygems/commands/crash_command.rb index e77b3fcd72..624be9fd32 100644 --- a/test/rubygems/rubygems/commands/crash_command.rb +++ b/test/rubygems/rubygems/commands/crash_command.rb @@ -2,4 +2,4 @@ class Gem::Commands::CrashCommand < Gem::Command raise "crash" -end \ No newline at end of file +end diff --git a/test/rubygems/test_config.rb b/test/rubygems/test_config.rb index fae1a6ff54..7829e90dcf 100644 --- a/test/rubygems/test_config.rb +++ b/test/rubygems/test_config.rb @@ -4,12 +4,10 @@ require 'rubygems' class TestConfig < Gem::TestCase def test_datadir - _, err = capture_io do - datadir = RbConfig::CONFIG['datadir'] - assert_equal "#{datadir}/xyz", RbConfig.datadir('xyz') - end - - assert_match(/deprecate/, err) + util_make_gems + spec = Gem::Specification.find_by_name("a") + spec.activate + assert_equal "#{spec.full_gem_path}/data/a", Gem.datadir('a') end end diff --git a/test/rubygems/test_deprecate.rb b/test/rubygems/test_deprecate.rb new file mode 100644 index 0000000000..ed4e9aa5ff --- /dev/null +++ b/test/rubygems/test_deprecate.rb @@ -0,0 +1,76 @@ +require 'rubygems/test_case' +# require 'rubygems/builder' +# require 'rubygems/package' +require 'rubygems/deprecate' + +class TestDeprecate < Gem::TestCase + + def setup + super + + # Gem::Deprecate.saved_warnings.clear + @original_skip = Gem::Deprecate.skip + Gem::Deprecate.skip = false + end + + def teardown + super + + # Gem::Deprecate.saved_warnings.clear + Gem::Deprecate.skip = @original_skip + end + + def test_defaults + assert_equal false, @original_skip + end + + def test_assignment + Gem::Deprecate.skip = false + assert_equal false, Gem::Deprecate.skip + + Gem::Deprecate.skip = true + assert_equal true, Gem::Deprecate.skip + + Gem::Deprecate.skip = nil + assert([true,false].include? Gem::Deprecate.skip) + end + + def test_skip + Gem::Deprecate.skip_during do + assert_equal true, Gem::Deprecate.skip + end + + Gem::Deprecate.skip = nil + end + + class Thing + extend Gem::Deprecate + attr_accessor :message + def foo + @message = "foo" + end + def bar + @message = "bar" + end + deprecate :foo, :bar, 2099, 3 + end + + def test_deprecated_method_calls_the_old_method + capture_io do + thing = Thing.new + thing.foo + assert_equal "foo", thing.message + end + end + + def test_deprecated_method_outputs_a_warning + out, err = capture_io do + thing = Thing.new + thing.foo + end + + assert_equal "", out + assert_match(/Thing#foo is deprecated; use bar instead\./, err) + assert_match(/on or after 2099-03-01/, err) + end +end diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb index b7c7f41eb6..bbc18d42f0 100644 --- a/test/rubygems/test_gem.rb +++ b/test/rubygems/test_gem.rb @@ -1,21 +1,22 @@ require 'rubygems/test_case' require 'rubygems' -require 'rubygems/gem_openssl' 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 def setup super + ENV.delete 'RUBYGEMS_GEMDEPS' @additional = %w[a b].map { |d| File.join @tempdir, d } - @default_dir_re = if RUBY_VERSION > '1.9' then - %r|/.*?[Rr]uby.*?/[Gg]ems/[0-9.]+| - else - %r|/[Rr]uby/[Gg]ems/[0-9.]+| - end util_remove_interrupt_command end @@ -48,7 +49,7 @@ class TestGem < Gem::TestCase end def unresolved_names - Gem.unresolved_deps.values.map(&:to_s).sort + Gem::Specification.unresolved_deps.values.map(&:to_s).sort end # TODO: move these to specification @@ -60,7 +61,9 @@ class TestGem < Gem::TestCase install_specs a1, b1, b2 a1.activate - require "b/c" + save_loaded_features do + require "b/c" + end assert_equal %w(a-1 b-1), loaded_spec_names end @@ -131,6 +134,82 @@ class TestGem < Gem::TestCase end 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_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_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 + # TODO: move these to specification def test_self_activate_ambiguous_unrelated save_loaded_features do @@ -456,16 +535,6 @@ class TestGem < Gem::TestCase assert_activate %w[d-1 e-1], e1, "d" end - def test_self_available? - util_make_gems - Gem::Deprecate.skip_during do - assert(Gem.available?("a")) - assert(Gem.available?("a", "1")) - assert(Gem.available?("a", ">1")) - assert(!Gem.available?("monkeys")) - end - end - def test_self_bin_path_no_exec_name e = assert_raises ArgumentError do Gem.bin_path 'a' @@ -523,14 +592,8 @@ class TestGem < Gem::TestCase def test_self_bindir_default_dir default = Gem.default_dir - bindir = if defined?(RUBY_FRAMEWORK_VERSION) then - '/usr/bin' - else - RbConfig::CONFIG['bindir'] - end - assert_equal bindir, Gem.bindir(default) - assert_equal bindir, Gem.bindir(Pathname.new(default)) + assert_equal Gem.default_bindir, Gem.bindir(default) end def test_self_clear_paths @@ -573,10 +636,6 @@ class TestGem < Gem::TestCase assert_nil Gem.datadir('xyzzy') end - def test_self_default_dir - assert_match @default_dir_re, Gem.default_dir - end - def test_self_default_exec_format orig_RUBY_INSTALL_NAME = Gem::ConfigMap[:ruby_install_name] Gem::ConfigMap[:ruby_install_name] = 'ruby' @@ -681,19 +740,6 @@ class TestGem < Gem::TestCase end end - def test_ensure_ssl_available - orig_Gem_ssl_available = Gem.ssl_available? - - Gem.ssl_available = true - Gem.ensure_ssl_available - - Gem.ssl_available = false - e = assert_raises Gem::Exception do Gem.ensure_ssl_available end - assert_equal 'SSL is not installed on this system', e.message - ensure - Gem.ssl_available = orig_Gem_ssl_available - end - def test_self_find_files cwd = File.expand_path("test/rubygems", @@project_dir) $LOAD_PATH.unshift cwd @@ -756,7 +802,7 @@ class TestGem < Gem::TestCase Gem.instance_variable_set :@paths, nil - assert_equal [Gem.dir, *Gem.default_path].uniq, Gem.path + 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 @@ -795,10 +841,11 @@ class TestGem < Gem::TestCase ENV['GEM_PATH'] = @additional.join(File::PATH_SEPARATOR) - assert_equal [Gem.dir, *@additional], Gem.path + 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 @@ -811,7 +858,8 @@ class TestGem < Gem::TestCase assert_equal @gemhome, Gem.dir - assert_equal [Gem.dir, *@additional], Gem.path + paths = [Gem.dir] + assert_equal @additional + paths, Gem.path end def test_self_path_overlap @@ -823,7 +871,8 @@ class TestGem < Gem::TestCase assert_equal @gemhome, Gem.dir - assert_equal [Gem.dir, *@additional], Gem.path + paths = [Gem.dir] + assert_equal @additional + paths, Gem.path end def test_self_platforms @@ -933,6 +982,10 @@ class TestGem < Gem::TestCase 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 @@ -943,7 +996,7 @@ class TestGem < Gem::TestCase ENV["GEM_HOME"] = @gemhome Gem.paths = { "GEM_PATH" => path } - assert_equal [@gemhome, @userhome, other], Gem.path + assert_equal [@userhome, other, @gemhome], Gem.path end def test_self_paths_eq_nonexistent_home @@ -956,13 +1009,71 @@ class TestGem < Gem::TestCase Gem.paths = { "GEM_PATH" => other } - assert_equal [@gemhome, other], Gem.path + assert_equal [other, @gemhome], Gem.path end - def test_self_source_index - Gem::Deprecate.skip_during do - assert_kind_of Gem::SourceIndex, Gem.source_index - 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 @@ -982,19 +1093,7 @@ class TestGem < Gem::TestCase Gem.try_activate 'a_file' end - assert_match %r%Could not find b %, e.message - end - - def test_ssl_available_eh - orig_Gem_ssl_available = Gem.ssl_available? - - Gem.ssl_available = true - assert_equal true, Gem.ssl_available? - - Gem.ssl_available = false - assert_equal false, Gem.ssl_available? - ensure - Gem.ssl_available = orig_Gem_ssl_available + assert_match %r%Could not find 'b' %, e.message end def test_self_use_paths @@ -1003,7 +1102,7 @@ class TestGem < Gem::TestCase Gem.use_paths @gemhome, @additional assert_equal @gemhome, Gem.dir - assert_equal [Gem.dir, *@additional], Gem.path + assert_equal @additional + [Gem.dir], Gem.path end def test_self_user_dir @@ -1019,6 +1118,46 @@ class TestGem < Gem::TestCase 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 + 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 + 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 @@ -1105,23 +1244,6 @@ class TestGem < Gem::TestCase assert_equal :loaded, TEST_PLUGIN_EXCEPTION rescue nil end - def test_latest_load_paths - spec = quick_spec 'a', '4' do |s| - s.require_paths = ["lib"] - end - - install_gem spec - - # @exec_path = File.join spec.full_gem_path, spec.bindir, 'exec' - # @abin_path = File.join spec.full_gem_path, spec.bindir, 'abin' - # FileUtils.mkdir_p File.join(stem, "gems", "test-3") - - Gem::Deprecate.skip_during do - expected = [File.join(@gemhome, "gems", "a-4", "lib")] - assert_equal expected, Gem.latest_load_paths - end - end - def test_gem_path_ordering refute_equal Gem.dir, Gem.user_dir @@ -1202,6 +1324,84 @@ class TestGem < Gem::TestCase "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 + 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 + 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.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 with_plugin(path) test_plugin_path = File.expand_path("test/rubygems/plugin/#{path}", @@project_dir) diff --git a/test/rubygems/test_gem_available_set.rb b/test/rubygems/test_gem_available_set.rb new file mode 100644 index 0000000000..47023b2b11 --- /dev/null +++ b/test/rubygems/test_gem_available_set.rb @@ -0,0 +1,106 @@ +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_match_platform + a1, _ = util_gem 'a', '1' do |g| + g.platform = "something-weird-yep" + end + + a1c, _ = util_gem 'a', '2' do |g| + g.platform = Gem::Platform.local + end + + a2, _ = util_gem 'a', '2' + + set = Gem::AvailableSet.new + set.add a1, @source + set.add a1c, @source + set.add a2, @source + + set.match_platform! + + assert_equal [a1c, a2], set.all_specs + end + + def test_best + a1, _ = util_gem 'a', '1' + a2, _ = util_gem 'a', '2' + + set = Gem::AvailableSet.new + set.add a1, @source + set.add a2, @source + + set.pick_best! + + assert_equal [a2], set.all_specs + end + + def test_remove_installed_bang + a1, _ = util_gem 'a', '1' + + a1.activate + + set = Gem::AvailableSet.new + set.add a1, @source + + dep = Gem::Dependency.new "a", ">= 0" + + set.remove_installed! dep + + assert set.empty? + end + + def test_sorted_normal_versions + a1, _ = util_gem 'a', '1' + a2, _ = util_gem 'a', '2' + + set = Gem::AvailableSet.new + set.add a1, @source + set.add a2, @source + + g = set.sorted + + assert_equal a2, g[0].spec + assert_equal a1, g[1].spec + end + + def test_sorted_respect_pre + a1a, _ = util_gem 'a', '1.a' + a1, _ = util_gem 'a', '1' + a2a, _ = util_gem 'a', '2.a' + a2, _ = util_gem 'a', '2' + a3a, _ = util_gem 'a', '3.a' + + set = Gem::AvailableSet.new + set.add a1, @source + set.add a1a, @source + set.add a3a, @source + set.add a2a, @source + set.add a2, @source + + g = set.sorted.map { |t| t.spec } + + assert_equal [a3a, a2, a2a, a1, a1a], g + end +end diff --git a/test/rubygems/test_gem_builder.rb b/test/rubygems/test_gem_builder.rb deleted file mode 100644 index 0b4b972367..0000000000 --- a/test/rubygems/test_gem_builder.rb +++ /dev/null @@ -1,44 +0,0 @@ -require 'rubygems/test_case' -require 'rubygems/builder' -require 'rubygems/package' - -class TestGemBuilder < Gem::TestCase - - def test_build - builder = Gem::Builder.new quick_spec('a') - - use_ui @ui do - Dir.chdir @tempdir do - builder.build - end - end - - assert_match %r|Successfully built RubyGem\n Name: a|, @ui.output - end - - def test_build_validates - builder = Gem::Builder.new Gem::Specification.new - - assert_raises Gem::InvalidSpecificationException do - builder.build - end - end - - def test_build_specification_result - util_make_gems - - spec = build_gem_and_yield_spec @a1 - - assert_operator @a1, :eql?, spec - end - - def build_gem_and_yield_spec(spec) - builder = Gem::Builder.new spec - - spec = Dir.chdir @tempdir do - FileUtils.mkdir 'lib' - File.open('lib/code.rb', 'w') { |f| f << "something" } - Gem::Package.open(File.open(builder.build, 'rb')) { |x| x.metadata } - end - end -end diff --git a/test/rubygems/test_gem_command.rb b/test/rubygems/test_gem_command.rb index 037640890c..712259c6cd 100644 --- a/test/rubygems/test_gem_command.rb +++ b/test/rubygems/test_gem_command.rb @@ -109,6 +109,16 @@ class TestGemCommand < Gem::TestCase 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 diff --git a/test/rubygems/test_gem_command_manager.rb b/test/rubygems/test_gem_command_manager.rb index 6cb253d386..e201d73275 100644 --- a/test/rubygems/test_gem_command_manager.rb +++ b/test/rubygems/test_gem_command_manager.rb @@ -6,7 +6,47 @@ class TestGemCommandManager < Gem::TestCase def setup super - @command_manager = Gem::CommandManager.instance + @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 @@ -14,6 +54,8 @@ class TestGemCommandManager < Gem::TestCase $: << 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 'interrupt' @@ -54,6 +96,7 @@ class TestGemCommandManager < Gem::TestCase 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 @@ -65,7 +108,7 @@ class TestGemCommandManager < Gem::TestCase #check defaults @command_manager.process_args("install") - assert_equal true, check_options[:generate_rdoc] + 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] @@ -77,7 +120,7 @@ class TestGemCommandManager < Gem::TestCase check_options = nil @command_manager.process_args( "install --force --local --rdoc --install-dir . --version 3.0 --no-wrapper --bindir . ") - assert_equal true, check_options[:generate_rdoc] + 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] @@ -102,6 +145,7 @@ class TestGemCommandManager < Gem::TestCase end end + # HACK move to uninstall command test def test_process_args_uninstall #capture all uninstall options check_options = nil @@ -121,6 +165,7 @@ class TestGemCommandManager < Gem::TestCase 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 @@ -131,16 +176,15 @@ class TestGemCommandManager < Gem::TestCase #check defaults @command_manager.process_args("check") - assert_equal false, check_options[:verify] - assert_equal false, check_options[:alien] + assert_equal true, check_options[:alien] #check settings check_options = nil - @command_manager.process_args("check --verify foobar --alien") - assert_equal "foobar", check_options[:verify] + @command_manager.process_args("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 @@ -159,6 +203,7 @@ class TestGemCommandManager < Gem::TestCase 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 @@ -191,6 +236,7 @@ class TestGemCommandManager < Gem::TestCase 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 @@ -201,12 +247,12 @@ class TestGemCommandManager < Gem::TestCase #check defaults @command_manager.process_args("update") - assert_equal true, check_options[:generate_rdoc] + assert_includes check_options[:document], 'rdoc' #check settings check_options = nil @command_manager.process_args("update --force --rdoc --install-dir .") - assert_equal true, check_options[:generate_rdoc] + assert_includes check_options[:document], 'ri' assert_equal true, check_options[:force] assert_equal Dir.pwd, check_options[:install_dir] end diff --git a/test/rubygems/test_gem_commands_build_command.rb b/test/rubygems/test_gem_commands_build_command.rb index 5d374542ba..24ee9c8bba 100644 --- a/test/rubygems/test_gem_commands_build_command.rb +++ b/test/rubygems/test_gem_commands_build_command.rb @@ -1,6 +1,6 @@ require 'rubygems/test_case' require 'rubygems/commands/build_command' -require 'rubygems/format' +require 'rubygems/package' class TestGemCommandsBuildCommand < Gem::TestCase @@ -24,16 +24,6 @@ class TestGemCommandsBuildCommand < Gem::TestCase util_test_build_gem @gem, gemspec_file end - def test_execute_yaml - gemspec_file = File.join(@tempdir, @gem.spec_name) - - File.open gemspec_file, 'w' do |gs| - gs.write @gem.to_yaml - end - - util_test_build_gem @gem, gemspec_file - end - def test_execute_bad_spec @gem.date = "2010-11-08" @@ -72,7 +62,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase assert_equal "ERROR: Gemspec file not found: some_gem\n", @ui.error end - def util_test_build_gem(gem, gemspec_file) + def util_test_build_gem(gem, gemspec_file, check_licenses=true) @cmd.options[:args] = [gemspec_file] use_ui @ui do @@ -87,32 +77,34 @@ class TestGemCommandsBuildCommand < Gem::TestCase assert_equal " Version: 2", output.shift assert_equal " File: some_gem-2.gem", output.shift assert_equal [], output - assert_equal '', @ui.error + + if check_licenses + assert_equal "WARNING: licenses is empty\n", @ui.error + end gem_file = File.join @tempdir, File.basename(gem.cache_file) assert File.exist?(gem_file) - spec = Gem::Format.from_file_by_path(gem_file).spec + 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 - @gem.instance_variable_set :@required_rubygems_version, nil - 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_yaml + gs.write @gem.to_ruby end @cmd.options[:args] = [gemspec_file] @cmd.options[:force] = true - util_test_build_gem @gem, gemspec_file + util_test_build_gem @gem, gemspec_file, false end - end diff --git a/test/rubygems/test_gem_commands_cert_command.rb b/test/rubygems/test_gem_commands_cert_command.rb index 609fae8884..d0af46728e 100644 --- a/test/rubygems/test_gem_commands_cert_command.rb +++ b/test/rubygems/test_gem_commands_cert_command.rb @@ -8,117 +8,516 @@ 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 - @orig_security_trust_dir = Gem::Security::OPT[:trust_dir] - Gem::Security::OPT[:trust_dir] = @tempdir - @cmd = Gem::Commands::CertCommand.new - root = File.expand_path(File.dirname(__FILE__), @@project_dir) + @trust_dir = Gem::Security.trust_dir + end + + def test_certificates_matching + @trust_dir.trust_cert PUBLIC_CERT + @trust_dir.trust_cert ALTERNATE_CERT - FileUtils.cp File.join(root, 'data', 'gem-private_key.pem'), @tempdir - FileUtils.cp File.join(root, 'data', 'gem-public_cert.pem'), @tempdir + matches = @cmd.certificates_matching '' - @cert_file_name = File.join @tempdir, 'gem-public_cert.pem' - @pkey_file_name = File.join @tempdir, 'gem-private_key.pem' + # 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 teardown - Gem::Security::OPT[:trust_dir] = @orig_security_trust_dir + def test_certificates_matching_filter + @trust_dir.trust_cert PUBLIC_CERT + @trust_dir.trust_cert ALTERNATE_CERT - super + 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.send :handle_options, %W[--add #{@cert_file_name}] + @cmd.execute end - assert_equal "Added '/CN=rubygems/DC=example/DC=com'\n", @ui.output - assert_equal '', @ui.error + 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 - FileUtils.rm @cert_file_name - FileUtils.rm @pkey_file_name + @cmd.handle_options %W[--build nobody@example.com] use_ui @ui do - Dir.chdir @tempdir do - @cmd.send :handle_options, %W[--build nobody@example.com] - end + @cmd.execute end output = @ui.output.split "\n" - assert_equal 'Public Cert: gem-public_cert.pem', output.shift - assert_equal 'Private Key: gem-private_key.pem', output.shift - assert_equal 'Don\'t forget to move the key file to somewhere private...', + 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 [], output - assert_equal '', @ui.error + assert_equal "Don't forget to move the key file to somewhere private!", + output.shift + + assert_empty output + assert_empty @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_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_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 @ui.error + + assert_path_exists File.join(@tempdir, 'gem-public_cert.pem') + + private_key_file = File.join @tempdir, 'gem-private_key.pem' + assert_path_exists private_key_file - assert File.exist?(File.join(@tempdir, 'gem-private_key.pem')) - assert File.exist?(File.join(@tempdir, 'gem-public_cert.pem')) + assert_equal PRIVATE_KEY.to_pem, File.read(private_key_file) end def test_execute_certificate use_ui @ui do - @cmd.send :handle_options, %W[--certificate #{@cert_file_name}] + @cmd.handle_options %W[--certificate #{PUBLIC_CERT_FILE}] end assert_equal '', @ui.output assert_equal '', @ui.error - assert_equal File.read(@cert_file_name), - @cmd.options[:issuer_cert].to_s + 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.send :handle_options, %W[--list] + @cmd.execute end - assert_equal "/CN=rubygems/DC=example/DC=com\n", @ui.output - assert_equal '', @ui.error + 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 #{@pkey_file_name}] + @cmd.send :handle_options, %W[--private-key #{PRIVATE_KEY_FILE}] end assert_equal '', @ui.output assert_equal '', @ui.error - assert_equal File.read(@pkey_file_name), - @cmd.options[:issuer_key].to_s + assert_equal 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.send :handle_options, %W[--remove rubygems] + @cmd.execute end - assert_equal "Removed '/CN=rubygems/DC=example/DC=com'\n", @ui.output + expected = <<-EXPECTED +Removed '/CN=alternate/DC=example' +Removed '/CN=nobody/DC=example' + EXPECTED + + assert_equal expected, @ui.output assert_equal '', @ui.error - refute File.exist?(@cert_file_name) + 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.send :handle_options, %W[ - -K #{@pkey_file_name} -C #{@cert_file_name} --sign #{@cert_file_name} - ] + @cmd.execute end assert_equal '', @ui.output assert_equal '', @ui.error - # HACK this test sucks + 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 + private_key_path = File.join Gem.user_home, 'gem-private_key.pem' + Gem::Security.write PRIVATE_KEY, private_key_path + + public_cert_path = File.join Gem.user_home, '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 + private_key_path = File.join Gem.user_home, '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 + public_cert_path = File.join Gem.user_home, '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_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 diff --git a/test/rubygems/test_gem_commands_cleanup_command.rb b/test/rubygems/test_gem_commands_cleanup_command.rb index 5b94d55ceb..2357999253 100644 --- a/test/rubygems/test_gem_commands_cleanup_command.rb +++ b/test/rubygems/test_gem_commands_cleanup_command.rb @@ -85,5 +85,24 @@ class TestGemCommandsCleanupCommand < Gem::TestCase assert_path_exists @a_1.gem_dir end + def test_execute_keeps_older_versions_with_deps + @b_1 = quick_spec 'b', 1 + @b_2 = quick_spec 'b', 2 + + @c = quick_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 + end diff --git a/test/rubygems/test_gem_commands_contents_command.rb b/test/rubygems/test_gem_commands_contents_command.rb index 9995bed8d7..42e6053b21 100644 --- a/test/rubygems/test_gem_commands_contents_command.rb +++ b/test/rubygems/test_gem_commands_contents_command.rb @@ -127,6 +127,29 @@ lib/foo.rb 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 = <<-EOF +#{Gem::ConfigMap[:bindir]}/default_command +#{Gem::ConfigMap[:rubylibdir]}/default/gem.rb +#{Gem::ConfigMap[:archdir]}/default_gem.so + EOF + + assert_equal expected, @ui.output + assert_equal "", @ui.error + end + def test_handle_options refute @cmd.options[:lib_only] assert @cmd.options[:prefix] diff --git a/test/rubygems/test_gem_commands_dependency_command.rb b/test/rubygems/test_gem_commands_dependency_command.rb index 4c559e2349..a5670e7575 100644 --- a/test/rubygems/test_gem_commands_dependency_command.rb +++ b/test/rubygems/test_gem_commands_dependency_command.rb @@ -51,8 +51,13 @@ Gem b-2 Gem c-1.2 +Gem dep_x-1 + x (>= 1) + Gem pl-1-x86-linux +Gem x-1 + EOF assert_equal expected, @ui.output diff --git a/test/rubygems/test_gem_commands_fetch_command.rb b/test/rubygems/test_gem_commands_fetch_command.rb index 9017a43b80..561075aac5 100644 --- a/test/rubygems/test_gem_commands_fetch_command.rb +++ b/test/rubygems/test_gem_commands_fetch_command.rb @@ -26,8 +26,8 @@ class TestGemCommandsFetchCommand < Gem::TestCase end end - assert File.exist?(File.join(@tempdir, @a2.file_name)), - "#{@a2.full_name} not fetched" + assert_path_exists(File.join(@tempdir, @a2.file_name), + "#{@a2.full_name} not fetched") end def test_execute_prerelease @@ -49,19 +49,23 @@ class TestGemCommandsFetchCommand < Gem::TestCase end end - assert File.exist?(File.join(@tempdir, @a2_pre.file_name)), - "#{@a2_pre.full_name} not fetched" + assert_path_exists(File.join(@tempdir, @a2_pre.file_name), + "#{@a2_pre.full_name} not fetched") end - def test_execute_version - util_setup_fake_fetcher - util_setup_spec_fetcher @a1, @a2 + def test_execute_specific_prerelease + util_setup_fake_fetcher true + util_clear_gems + util_setup_spec_fetcher @a2, @a2_pre - @fetcher.data["#{@gem_repo}gems/#{@a1.file_name}"] = - File.read(@a1.cache_file) + @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = + File.read(@a2.cache_file) + @fetcher.data["#{@gem_repo}gems/#{@a2_pre.file_name}"] = + File.read(@a2_pre.cache_file) @cmd.options[:args] = [@a2.name] - @cmd.options[:version] = Gem::Requirement.new '1' + @cmd.options[:prerelease] = true + @cmd.options[:version] = "2.a" use_ui @ui do Dir.chdir @tempdir do @@ -69,16 +73,11 @@ class TestGemCommandsFetchCommand < Gem::TestCase end end - assert File.exist?(File.join(@tempdir, @a1.file_name)), - "#{@a1.full_name} not fetched" + assert_path_exists(File.join(@tempdir, @a2_pre.file_name), + "#{@a2_pre.full_name} not fetched") end - def test_execute_handles_sources_properly - repo = "http://gems.example.com" - @uri = URI.parse repo - - Gem.sources.replace [repo] - + def test_execute_version util_setup_fake_fetcher util_setup_spec_fetcher @a1, @a2 @@ -94,8 +93,8 @@ class TestGemCommandsFetchCommand < Gem::TestCase end end - assert File.exist?(File.join(@tempdir, @a1.file_name)), - "#{@a1.full_name} not fetched" + assert_path_exists(File.join(@tempdir, @a1.file_name), + "#{@a1.full_name} not fetched") end end diff --git a/test/rubygems/test_gem_commands_generate_index_command.rb b/test/rubygems/test_gem_commands_generate_index_command.rb index ee4cd8051e..2e478d9c9e 100644 --- a/test/rubygems/test_gem_commands_generate_index_command.rb +++ b/test/rubygems/test_gem_commands_generate_index_command.rb @@ -16,27 +16,9 @@ class TestGemCommandsGenerateIndexCommand < Gem::TestCase @cmd.execute end - marshal = File.join @gemhome, 'Marshal.4.8' - marshal_z = File.join @gemhome, 'Marshal.4.8.Z' + specs = File.join @gemhome, "specs.4.8.gz" - assert File.exist?(marshal), marshal - assert File.exist?(marshal_z), marshal_z - end - - def test_execute_rss_update - @cmd.options[:update] = true - @cmd.options[:rss_host] = 'example.com' - @cmd.options[:rss_gems_host] = 'gems.example.com' - - use_ui @ui do - assert_raises Gem::MockGemUi::TermError do - @cmd.execute - end - end - - assert_equal "ERROR: --update not compatible with RSS generation\n", - @ui.error - assert_empty @ui.output + assert File.exist?(specs), specs end def test_handle_options_directory @@ -58,69 +40,6 @@ class TestGemCommandsGenerateIndexCommand < Gem::TestCase assert_equal 'C:/nonexistent', @cmd.options[:directory] end - def test_handle_options_invalid - e = assert_raises OptionParser::InvalidOption do - @cmd.handle_options %w[--no-modern --no-legacy] - end - - assert_equal 'invalid option: --no-legacy no indicies will be built', - e.message - - @cmd = Gem::Commands::GenerateIndexCommand.new - e = assert_raises OptionParser::InvalidOption do - @cmd.handle_options %w[--no-legacy --no-modern] - end - - assert_equal 'invalid option: --no-modern no indicies will be built', - e.message - end - - def test_handle_options_legacy - @cmd.handle_options %w[--legacy] - - assert @cmd.options[:build_legacy] - assert @cmd.options[:build_modern], ':build_modern not set' - end - - def test_handle_options_modern - @cmd.handle_options %w[--modern] - - assert @cmd.options[:build_legacy] - assert @cmd.options[:build_modern], ':build_modern not set' - end - - def test_handle_options_no_legacy - @cmd.handle_options %w[--no-legacy] - - refute @cmd.options[:build_legacy] - assert @cmd.options[:build_modern] - end - - def test_handle_options_no_modern - @cmd.handle_options %w[--no-modern] - - assert @cmd.options[:build_legacy] - refute @cmd.options[:build_modern] - end - - def test_handle_options_rss_gems_host - @cmd.handle_options %w[--rss-gems-host gems.example.com] - - assert_equal 'gems.example.com', @cmd.options[:rss_gems_host] - end - - def test_handle_options_rss_host - @cmd.handle_options %w[--rss-host example.com] - - assert_equal 'example.com', @cmd.options[:rss_host] - end - - def test_handle_options_rss_title - @cmd.handle_options %w[--rss-title Example\ Gems] - - assert_equal 'Example Gems', @cmd.options[:rss_title] - end - def test_handle_options_update @cmd.handle_options %w[--update] diff --git a/test/rubygems/test_gem_commands_help_command.rb b/test/rubygems/test_gem_commands_help_command.rb index d626b1436a..f039857009 100644 --- a/test/rubygems/test_gem_commands_help_command.rb +++ b/test/rubygems/test_gem_commands_help_command.rb @@ -1,8 +1,9 @@ require "rubygems" require "rubygems/test_case" require "rubygems/commands/help_command" -require "rubygems/format" +require "rubygems/package" require "rubygems/command_manager" +require File.expand_path('../rubygems_plugin', __FILE__) class TestGemCommandsHelpCommand < Gem::TestCase def setup diff --git a/test/rubygems/test_gem_commands_install_command.rb b/test/rubygems/test_gem_commands_install_command.rb index 2215d4d4ab..6a3293e356 100644 --- a/test/rubygems/test_gem_commands_install_command.rb +++ b/test/rubygems/test_gem_commands_install_command.rb @@ -1,21 +1,23 @@ require 'rubygems/test_case' require 'rubygems/commands/install_command' -begin - gem "rdoc" - gem "json" -rescue Gem::LoadError - # ignore -end - class TestGemCommandsInstallCommand < Gem::TestCase def setup super @cmd = Gem::Commands::InstallCommand.new - @cmd.options[:generate_rdoc] = false - @cmd.options[:generate_ri] = false + @cmd.options[:document] = [] + + @gemdeps = "tmp_install_gemdeps" + @orig_args = Gem::Command.build_args + end + + def teardown + super + + Gem::Command.build_args = @orig_args + File.unlink @gemdeps if File.file? @gemdeps end def test_execute_exclude_prerelease @@ -36,8 +38,7 @@ class TestGemCommandsInstallCommand < Gem::TestCase assert_equal 0, e.exit_code, @ui.error end - assert_match(/Successfully installed #{@a2.full_name}$/, @ui.output) - refute_match(/Successfully installed #{@a2_pre.full_name}$/, @ui.output) + assert_equal %w[a-2], @cmd.installed_specs.map { |spec| spec.full_name } end def test_execute_explicit_version_includes_prerelease @@ -61,26 +62,7 @@ class TestGemCommandsInstallCommand < Gem::TestCase assert_equal 0, e.exit_code, @ui.error end - refute_match(/Successfully installed #{@a2.full_name}$/, @ui.output) - assert_match(/Successfully installed #{@a2_pre.full_name}$/, @ui.output) - end - - def test_execute_include_dependencies - @cmd.options[:include_dependencies] = true - @cmd.options[:args] = [] - - assert_raises Gem::CommandLineError do - use_ui @ui do - @cmd.execute - end - end - - output = @ui.output.split "\n" - assert_equal "INFO: `gem install -y` is now default and will be removed", - output.shift - assert_equal "INFO: use --ignore-dependencies to install only the gems you list", - output.shift - assert output.empty?, output.inspect + assert_equal %w[a-2.a], @cmd.installed_specs.map { |spec| spec.full_name } end def test_execute_local @@ -104,13 +86,14 @@ class TestGemCommandsInstallCommand < Gem::TestCase end end + assert_equal %w[a-2], @cmd.installed_specs.map { |spec| spec.full_name } + out = @ui.output.split "\n" - assert_equal "Successfully installed #{@a2.full_name}", out.shift assert_equal "1 gem installed", out.shift assert out.empty?, out.inspect end - def test_no_user_install + def test_execute_no_user_install skip 'skipped on MS Windows (chmod has no effect)' if win_platform? util_setup_fake_fetcher @@ -206,8 +189,8 @@ class TestGemCommandsInstallCommand < Gem::TestCase errs = @ui.error.split("\n") - assert_match(/WARNING: Error fetching data/, errs.shift) 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_with_hint @@ -234,7 +217,92 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal expected, @ui.error end - def test_execute_prerelease + def test_execute_nonexistent_with_dashes + misspelled = "non-existent_with-hint" + correctly_spelled = "nonexistent-with_hint" + + util_setup_fake_fetcher + util_setup_spec_fetcher quick_spec(correctly_spelled, '2') + + @cmd.options[:args] = [misspelled] + + use_ui @ui do + e = assert_raises Gem::SystemExitException 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 + util_setup_fake_fetcher :prerelease + util_clear_gems + util_setup_spec_fetcher @a1, @a2_pre + + @fetcher.data["#{@gem_repo}gems/#{@a1.file_name}"] = + read_binary(@a1.cache_file) + @fetcher.data["#{@gem_repo}gems/#{@a2_pre.file_name}"] = + read_binary(@a2_pre.cache_file) + + @cmd.options[:prerelease] = false + @cmd.options[:args] = [@a2_pre.name] + + use_ui @ui do + e = assert_raises Gem::SystemExitException do + @cmd.execute + end + assert_equal 0, e.exit_code, @ui.error + end + + assert_equal %w[a-1], @cmd.installed_specs.map { |spec| spec.full_name } + end + + def test_execute_prerelease_wins_over_previous_ver + util_setup_fake_fetcher :prerelease + util_clear_gems + util_setup_spec_fetcher @a1, @a2_pre + + @fetcher.data["#{@gem_repo}gems/#{@a1.file_name}"] = + read_binary(@a1.cache_file) + @fetcher.data["#{@gem_repo}gems/#{@a2_pre.file_name}"] = + read_binary(@a2_pre.cache_file) + + @cmd.options[:prerelease] = true + @cmd.options[:args] = [@a2_pre.name] + + use_ui @ui do + e = assert_raises Gem::SystemExitException do + @cmd.execute + end + assert_equal 0, e.exit_code, @ui.error + 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 util_setup_fake_fetcher :prerelease util_clear_gems util_setup_spec_fetcher @a2, @a2_pre @@ -254,14 +322,82 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal 0, e.exit_code, @ui.error end - refute_match(/Successfully installed #{@a2.full_name}$/, @ui.output) - assert_match(/Successfully installed #{@a2_pre.full_name}$/, @ui.output) + assert_equal %w[a-2], @cmd.installed_specs.map { |spec| spec.full_name } end - def test_execute_remote - @cmd.options[:generate_rdoc] = true - @cmd.options[:generate_ri] = true + def test_execute_rdoc + util_setup_fake_fetcher + + Gem.done_installing(&Gem::RDoc.method(:generation_hook)) + + @cmd.options[:document] = %w[rdoc ri] + @cmd.options[:domain] = :local + + FileUtils.mv @a2.cache_file, @tempdir + @cmd.options[:args] = [@a2.name] + + 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 + e = assert_raises Gem::SystemExitException do + @cmd.execute + end + ensure + Dir.chdir old + end + + assert_equal 0, e.exit_code + 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 + util_setup_fake_fetcher + + args = %w!--with-awesome=true --more-awesome=yes! + + Gem::Command.build_args = args + + @cmd.options[:domain] = :local + + FileUtils.mv @a2.cache_file, @tempdir + + @cmd.options[:args] = [@a2.name] + + 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 + e = assert_raises Gem::SystemExitException do + @cmd.execute + end + ensure + Dir.chdir old + end + + assert_equal 0, e.exit_code + end + + path = @a2.build_info_file + assert_path_exists path + + assert_equal args, @a2.build_args + end + + + def test_execute_remote util_setup_fake_fetcher util_setup_spec_fetcher @@ -279,16 +415,56 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal 0, e.exit_code end + assert_equal %w[a-2], @cmd.installed_specs.map { |spec| spec.full_name } + out = @ui.output.split "\n" - assert_equal "Successfully installed #{@a2.full_name}", out.shift assert_equal "1 gem installed", out.shift - assert_equal "Installing ri documentation for #{@a2.full_name}...", - out.shift - assert_equal "Installing RDoc documentation for #{@a2.full_name}...", - out.shift assert out.empty?, out.inspect end + def test_execute_remote_ignores_files + util_setup_fake_fetcher + util_setup_spec_fetcher + + @cmd.options[:domain] = :remote + + 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 + e = assert_raises Gem::SystemExitException do + @cmd.execute + end + assert_equal 0, e.exit_code + end + end + + assert_equal %w[a-1], @cmd.installed_specs.map { |spec| spec.full_name } + + out = @ui.output.split "\n" + assert_equal "1 gem installed", out.shift + assert out.empty?, out.inspect + + fin = Dir["#{gemdir}/*"] + + assert_equal [a1_gemspec], fin - start + end + def test_execute_two util_setup_fake_fetcher @cmd.options[:domain] = :local @@ -312,13 +488,33 @@ ERROR: Possible alternatives: non_existent_with_hint end end + assert_equal %w[a-2 b-2], @cmd.installed_specs.map { |spec| spec.full_name } + out = @ui.output.split "\n" - assert_equal "Successfully installed #{@a2.full_name}", out.shift - assert_equal "Successfully installed #{@b2.full_name}", out.shift assert_equal "2 gems installed", out.shift assert out.empty?, out.inspect 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 util_setup_fake_fetcher util_setup_spec_fetcher @@ -344,11 +540,414 @@ ERROR: Possible alternatives: non_existent_with_hint end end + assert_equal %w[b-2], @cmd.installed_specs.map { |spec| spec.full_name } + out = @ui.output.split "\n" assert_equal "", @ui.error - assert_equal "Successfully installed #{@b2.full_name}", out.shift assert_equal "1 gem installed", out.shift assert out.empty?, out.inspect end + + def test_parses_requirement_from_gemname + util_setup_fake_fetcher + @cmd.options[:domain] = :local + + FileUtils.mv @a2.cache_file, @tempdir + + FileUtils.mv @b2.cache_file, @tempdir + + req = "#{@a2.name}:10.0" + + @cmd.options[:args] = [req] + + e = nil + use_ui @ui do + orig_dir = Dir.pwd + begin + Dir.chdir @tempdir + e = assert_raises Gem::SystemExitException 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::SystemExitException 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 'blah' \(>= 0\)!, @ui.error + assert_match %r!Unable to download data from http://not-there\.nothing!, @ui.error + end + + def test_show_source_problems_even_on_success + util_setup_fake_fetcher + util_setup_spec_fetcher + + Gem.sources << "http://nonexistent.example" + + @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = + read_binary(@a2.cache_file) + + @cmd.options[:args] = [@a2.name] + + use_ui @ui do + e = assert_raises Gem::SystemExitException do + capture_io do + @cmd.execute + end + end + assert_equal 0, e.exit_code + end + + assert_equal %w[a-2], @cmd.installed_specs.map { |spec| spec.full_name } + + out = @ui.output.split "\n" + assert_equal "1 gem installed", out.shift + assert out.empty?, out.inspect + + e = @ui.error + + x = "WARNING: Unable to pull data from 'http://nonexistent.example': no data for http://nonexistent.example/latest_specs.4.8.gz (http://nonexistent.example/latest_specs.4.8.gz)\n" + assert_equal x, e + end + + def test_execute_installs_dependencies + r, r_gem = util_gem 'r', '1', 'q' => '= 1' + q, q_gem = util_gem 'q', '1' + + util_setup_fake_fetcher + util_setup_spec_fetcher r, q + + Gem::Specification.reset + + @fetcher.data["#{@gem_repo}gems/#{q.file_name}"] = read_binary(q_gem) + @fetcher.data["#{@gem_repo}gems/#{r.file_name}"] = read_binary(r_gem) + + @cmd.options[:args] = ["r"] + + e = nil + use_ui @ui do + e = assert_raises Gem::SystemExitException do + capture_io do + @cmd.execute + end + end + end + + out = @ui.output.split "\n" + assert_equal "2 gems installed", out.shift + assert out.empty?, out.inspect + + assert_equal %w[q-1 r-1], @cmd.installed_specs.map { |spec| spec.full_name } + + assert_equal 0, e.exit_code + end + + def test_execute_satisify_deps_of_local_from_sources + r, r_gem = util_gem 'r', '1', 'q' => '= 1' + q, q_gem = util_gem 'q', '1' + + util_setup_fake_fetcher + util_setup_spec_fetcher r, q + + Gem::Specification.reset + + @fetcher.data["#{@gem_repo}gems/#{q.file_name}"] = read_binary(q_gem) + + @cmd.options[:args] = [r_gem] + + use_ui @ui do + e = assert_raises Gem::SystemExitException do + capture_io do + @cmd.execute + end + end + assert_equal 0, e.exit_code + end + + assert_equal %w[q-1 r-1], @cmd.installed_specs.map { |spec| spec.full_name } + + out = @ui.output.split "\n" + assert_equal "2 gems installed", out.shift + assert out.empty?, out.inspect + end + + def test_execute_uses_from_a_gemdeps + util_setup_fake_fetcher + util_setup_spec_fetcher + + @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = + read_binary(@a2.cache_file) + + File.open @gemdeps, "w" do |f| + f << "gem 'a'" + end + + @cmd.options[:gemdeps] = @gemdeps + + use_ui @ui do + e = assert_raises Gem::SystemExitException do + capture_io do + @cmd.execute + end + end + assert_equal 0, e.exit_code + end + + assert_equal %w[], @cmd.installed_specs.map { |spec| spec.full_name } + + out = @ui.output.split "\n" + assert_equal "Using a (2)", out.shift + assert out.empty?, out.inspect + end + + def test_execute_installs_from_a_gemdeps + util_setup_fake_fetcher + util_setup_spec_fetcher @a2 + util_clear_gems + + @fetcher.data["#{@gem_repo}gems/#{@a2.file_name}"] = + read_binary(@a2.cache_file) + + File.open @gemdeps, "w" do |f| + f << "gem 'a'" + end + + @cmd.options[:gemdeps] = @gemdeps + + use_ui @ui do + e = assert_raises Gem::SystemExitException do + capture_io do + @cmd.execute + end + end + assert_equal 0, e.exit_code + end + + assert_equal %w[a-2], @cmd.installed_specs.map { |spec| spec.full_name } + + out = @ui.output.split "\n" + assert_equal "Installing a (2)", out.shift + assert out.empty?, out.inspect + end + + def test_execute_installs_deps_a_gemdeps + q, q_gem = util_gem 'q', '1.0' + r, r_gem = util_gem 'r', '2.0', 'q' => nil + + util_setup_fake_fetcher + util_setup_spec_fetcher q, r + util_clear_gems + + add_to_fetcher q, q_gem + add_to_fetcher r, r_gem + + File.open @gemdeps, "w" do |f| + f << "gem 'r'" + end + + @cmd.options[:gemdeps] = @gemdeps + + use_ui @ui do + e = assert_raises Gem::SystemExitException do + capture_io do + @cmd.execute + end + end + assert_equal 0, e.exit_code + end + + names = @cmd.installed_specs.map { |spec| spec.full_name } + + assert_equal %w[q-1.0 r-2.0], names + + out = @ui.output.split "\n" + assert_equal "Installing q (1.0)", out.shift + assert_equal "Installing r (2.0)", out.shift + assert out.empty?, out.inspect + end + + def test_execute_uses_deps_a_gemdeps + q, _ = util_gem 'q', '1.0' + r, r_gem = util_gem 'r', '2.0', 'q' => nil + + util_setup_fake_fetcher + util_setup_spec_fetcher q, r + util_clear_gems + + add_to_fetcher r, r_gem + + Gem::Specification.add_specs q + + File.open @gemdeps, "w" do |f| + f << "gem 'r'" + end + + @cmd.options[:gemdeps] = @gemdeps + + use_ui @ui do + e = assert_raises Gem::SystemExitException do + capture_io do + @cmd.execute + end + end + assert_equal 0, e.exit_code + end + + names = @cmd.installed_specs.map { |spec| spec.full_name } + + assert_equal %w[r-2.0], names + + out = @ui.output.split "\n" + assert_equal "Using q (1.0)", out.shift + assert_equal "Installing r (2.0)", out.shift + assert out.empty?, out.inspect + end + + def test_execute_installs_deps_a_gemdeps_into_a_path + q, q_gem = util_gem 'q', '1.0' + r, r_gem = util_gem 'r', '2.0', 'q' => nil + + util_setup_fake_fetcher + util_setup_spec_fetcher q, r + util_clear_gems + + add_to_fetcher q, q_gem + add_to_fetcher r, r_gem + + File.open @gemdeps, "w" do |f| + f << "gem 'r'" + end + + @cmd.options[:install_dir] = "gf-path" + @cmd.options[:gemdeps] = @gemdeps + + use_ui @ui do + e = assert_raises Gem::SystemExitException do + capture_io do + @cmd.execute + end + end + assert_equal 0, e.exit_code + end + + names = @cmd.installed_specs.map { |spec| spec.full_name } + + assert_equal %w[q-1.0 r-2.0], names + + out = @ui.output.split "\n" + assert_equal "Installing q (1.0)", out.shift + assert_equal "Installing r (2.0)", out.shift + assert out.empty?, out.inspect + + 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 + q, q_gem = util_gem 'q', '1.0' + r, r_gem = util_gem 'r', '2.0', 'q' => nil + + util_setup_fake_fetcher + util_setup_spec_fetcher q, r + util_clear_gems + + add_to_fetcher q, q_gem + add_to_fetcher r, r_gem + + Gem::Specification.add_specs q + + File.open @gemdeps, "w" do |f| + f << "gem 'r'" + end + + @cmd.options[:install_dir] = "gf-path" + @cmd.options[:gemdeps] = @gemdeps + + use_ui @ui do + e = assert_raises Gem::SystemExitException do + capture_io do + @cmd.execute + end + end + assert_equal 0, e.exit_code + end + + names = @cmd.installed_specs.map { |spec| spec.full_name } + + assert_equal %w[q-1.0 r-2.0], names + + out = @ui.output.split "\n" + assert_equal "Installing q (1.0)", out.shift + assert_equal "Installing r (2.0)", out.shift + assert out.empty?, out.inspect + + 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 + q, q_gem = util_gem 'q', '1.0' + r, r_gem = util_gem 'r', '2.0', 'q' => nil + + util_setup_fake_fetcher + util_setup_spec_fetcher q, r + util_clear_gems + + add_to_fetcher r, r_gem + + i = Gem::Installer.new q_gem, :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 + e = assert_raises Gem::SystemExitException do + capture_io do + @cmd.execute + end + end + assert_equal 0, e.exit_code + end + + names = @cmd.installed_specs.map { |spec| spec.full_name } + + assert_equal %w[r-2.0], names + + out = @ui.output.split "\n" + assert_equal "Using q (1.0)", out.shift + assert_equal "Installing r (2.0)", out.shift + assert out.empty?, out.inspect + end + + end diff --git a/test/rubygems/test_gem_commands_mirror.rb b/test/rubygems/test_gem_commands_mirror.rb new file mode 100644 index 0000000000..2f6fe52401 --- /dev/null +++ b/test/rubygems/test_gem_commands_mirror.rb @@ -0,0 +1,32 @@ +require 'rubygems/test_case' +require 'rubygems/commands/mirror_command' + +class TestGemCommandsMirrorCommand < Gem::TestCase + + def setup + super + + @cmd = Gem::Commands::MirrorCommand.new + + @mirror_specs = Gem::Specification.find_all_by_name('rubygems-mirror').each do |spec| + Gem::Specification.remove_spec spec + end + end + + def teardown + @mirror_specs.each do |spec| + Gem::Specification.add_spec spec + end + + super + end + + def test_execute + use_ui @ui do + @cmd.execute + end + + assert_match %r%Install the rubygems-mirror%i, @ui.error + end + +end diff --git a/test/rubygems/test_gem_commands_owner_command.rb b/test/rubygems/test_gem_commands_owner_command.rb index 65fe09e09f..dc84190e5e 100644 --- a/test/rubygems/test_gem_commands_owner_command.rb +++ b/test/rubygems/test_gem_commands_owner_command.rb @@ -80,10 +80,8 @@ EOF response = "You don't have permission to push to this gem" @fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 403, 'Forbidden'] - assert_raises Gem::MockGemUi::TermError do - use_ui @ui do - @cmd.add_owners("freewill", ["user-new1@example.com"]) - end + use_ui @ui do + @cmd.add_owners("freewill", ["user-new1@example.com"]) end assert_match response, @ui.output @@ -122,10 +120,8 @@ EOF response = "You don't have permission to push to this gem" @fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 403, 'Forbidden'] - assert_raises Gem::MockGemUi::TermError do - use_ui @ui do - @cmd.remove_owners("freewill", ["user-remove1@example.com"]) - end + use_ui @ui do + @cmd.remove_owners("freewill", ["user-remove1@example.com"]) end assert_match response, @ui.output diff --git a/test/rubygems/test_gem_commands_pristine_command.rb b/test/rubygems/test_gem_commands_pristine_command.rb index 6bf6d5a56c..778ce2ee1f 100644 --- a/test/rubygems/test_gem_commands_pristine_command.rb +++ b/test/rubygems/test_gem_commands_pristine_command.rb @@ -9,20 +9,31 @@ class TestGemCommandsPristineCommand < Gem::TestCase end def test_execute - a = quick_spec 'a' do |s| s.executables = %w[foo] end + a = quick_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' + 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 @@ -30,6 +41,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase 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" @@ -46,9 +58,11 @@ class TestGemCommandsPristineCommand < Gem::TestCase install_gem a - gem_bin = File.join @gemhome, 'gems', a.full_name, 'bin', 'foo' + 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] @@ -57,6 +71,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase end assert File.exist?(gem_bin) + assert File.exist?(gem_stub) out = @ui.output.split "\n" @@ -65,7 +80,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase assert_empty out, out.inspect end - def test_execute_no_exetension + def test_execute_no_extension a = quick_spec 'a' do |s| s.extensions << 'ext/a/extconf.rb' end ext_path = File.join @tempdir, 'ext', 'a', 'extconf.rb' @@ -90,6 +105,38 @@ class TestGemCommandsPristineCommand < Gem::TestCase assert_empty out, out.inspect end + def test_execute_with_extension_with_build_args + a = quick_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 "all:\n\techo built\n" + f.puts "install:\n\techo built\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 = quick_spec 'a' b = quick_spec 'b' @@ -195,5 +242,53 @@ class TestGemCommandsPristineCommand < Gem::TestCase assert_match %r|at least one gem name|, e.message end + def test_execute_only_executables + a = quick_spec 'a' do |s| + s.executables = %w[foo] + s.files = %w[bin/foo lib/a.rb] + end + write_file File.join(@tempdir, 'lib', 'a.rb') do |fp| + fp.puts "puts __FILE__" + end + write_file File.join(@tempdir, 'bin', 'foo') do |fp| + fp.puts "#!/usr/bin/ruby" + end + + install_gem a + + gem_lib = File.join @gemhome, 'gems', a.full_name, 'lib', 'a.rb' + gem_exec = File.join @gemhome, 'bin', 'foo' + + FileUtils.rm gem_exec + FileUtils.rm gem_lib + + @cmd.handle_options %w[--all --only-executables] + + use_ui @ui do + @cmd.execute + end + + assert File.exist? gem_exec + refute File.exist? gem_lib + end + + def test_execute_default_gem + default_gem_spec = new_default_spec("default", "2.0.0.0", + nil, "default/gem.rb") + install_default_specs(default_gem_spec) + + @cmd.options[:args] = %w[default] + + use_ui @ui do + @cmd.execute + end + + assert_equal([ + "Restoring gems to pristine condition...", + "Skipped default-2.0.0.0, it is a default gem", + ], + @ui.output.split("\n")) + assert_empty(@ui.error) + end end diff --git a/test/rubygems/test_gem_commands_push_command.rb b/test/rubygems/test_gem_commands_push_command.rb index 13a107aaf3..5ff940bf42 100644 --- a/test/rubygems/test_gem_commands_push_command.rb +++ b/test/rubygems/test_gem_commands_push_command.rb @@ -13,6 +13,9 @@ 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" @@ -23,6 +26,8 @@ class TestGemCommandsPushCommand < Gem::TestCase "ed244fbf2b1a52e012da8616c512fa47f9aa5250" @spec, @path = util_gem "freewill", "1.0.0" + @host = Gem.host + @api_key = Gem.configuration.rubygems_api_key @fetcher = Gem::FakeFetcher.new Gem::RemoteFetcher.fetcher = @fetcher @@ -35,35 +40,84 @@ class TestGemCommandsPushCommand < Gem::TestCase @cmd.send_gem(@path) end - assert_match %r{Pushing gem to #{Gem.host}...}, @ui.output + 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 Gem.configuration.rubygems_api_key, @fetcher.last_request["Authorization"] + assert_equal @api_key, @fetcher.last_request["Authorization"] assert_match @response, @ui.output 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_default @response = "Successfully registered gem: freewill (1.0.0)" - @fetcher.data["#{Gem.host}/api/v1/gems"] = [@response, 200, 'OK'] + @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK'] send_battery end def test_sending_gem_host @response = "Successfully registered gem: freewill (1.0.0)" - @fetcher.data["#{Gem.host}/api/v1/gems"] = [@response, 200, 'OK'] - @cmd.options[:host] = "#{Gem.host}" + @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK'] + @cmd.options['host'] = "#{Gem.host}" send_battery end def test_sending_gem_ENV @response = "Successfully registered gem: freewill (1.0.0)" - @fetcher.data["#{Gem.host}/api/v1/gems"] = [@response, 200, 'OK'] + @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK'] ENV["RUBYGEMS_HOST"] = "#{Gem.host}" send_battery @@ -78,7 +132,7 @@ class TestGemCommandsPushCommand < Gem::TestCase def test_sending_gem_denied response = "You don't have permission to push to this gem" - @fetcher.data["#{Gem.host}/api/v1/gems"] = [response, 403, 'Forbidden'] + @fetcher.data["#{@host}/api/v1/gems"] = [response, 403, 'Forbidden'] assert_raises Gem::MockGemUi::TermError do use_ui @ui do @@ -91,7 +145,7 @@ class TestGemCommandsPushCommand < Gem::TestCase def test_sending_gem_key @response = "Successfully registered gem: freewill (1.0.0)" - @fetcher.data["#{Gem.host}/api/v1/gems"] = [@response, 200, "OK"] + @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, "OK"] File.open Gem.configuration.credentials_path, 'a' do |f| f.write ':other: 701229f217cdf23b1344c7b4b54ca97' end diff --git a/test/rubygems/test_gem_commands_query_command.rb b/test/rubygems/test_gem_commands_query_command.rb index e718c0bcbb..8ff62b4217 100644 --- a/test/rubygems/test_gem_commands_query_command.rb +++ b/test/rubygems/test_gem_commands_query_command.rb @@ -349,5 +349,56 @@ pl (1 i386-linux) assert_equal "WARNING: prereleases are always shown locally\n", @ui.error end + def test_execute_local_details + @a1.platform = 'x86-linux' + + @a2.summary = 'This is a lot of text. ' * 4 + @a2.authors = ['Abraham Lincoln', 'Hirohito'] + @a2.homepage = 'http://a.example.com/' + @a2.rubyforge_project = 'rubygems' + @a2.platform = 'universal-darwin' + + util_clear_gems + util_setup_spec_fetcher @a1, @a2, @pl1 + + @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 + Rubyforge: http://rubyforge.org/projects/rubygems + 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_match expected, @ui.output + end + end diff --git a/test/rubygems/test_gem_commands_search_command.rb b/test/rubygems/test_gem_commands_search_command.rb new file mode 100644 index 0000000000..05e7cff892 --- /dev/null +++ b/test/rubygems/test_gem_commands_search_command.rb @@ -0,0 +1,25 @@ +require 'rubygems/test_case' +require 'rubygems/commands/search_command' + +class TestGemCommandsSearchCommand < Gem::TestCase + + def setup + super + + @cmd = Gem::Commands::SearchCommand.new + end + + def test_execute + @cmd.handle_options %w[a] + + use_ui @ui do + @cmd.execute + end + + assert_match %r%REMOTE GEMS%, @ui.output + + assert_empty @ui.error + end + +end + diff --git a/test/rubygems/test_gem_commands_sources_command.rb b/test/rubygems/test_gem_commands_sources_command.rb index 8b439025ed..6bae460c84 100644 --- a/test/rubygems/test_gem_commands_sources_command.rb +++ b/test/rubygems/test_gem_commands_sources_command.rb @@ -99,6 +99,25 @@ Error fetching http://beta-gems.example.com: assert_equal '', @ui.error end + def test_execute_add_redundant_source + @cmd.handle_options %W[--add #{@gem_repo}] + + util_setup_spec_fetcher + + 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_bad_uri @cmd.handle_options %w[--add beta-gems.example.com] @@ -125,11 +144,6 @@ beta-gems.example.com is not a URI util_setup_spec_fetcher - fetcher = Gem::SpecFetcher.fetcher - - # HACK figure out how to force directory creation via fetcher - #assert File.directory?(fetcher.dir), 'cache dir exists' - use_ui @ui do @cmd.execute end @@ -141,7 +155,8 @@ beta-gems.example.com is not a URI assert_equal expected, @ui.output assert_equal '', @ui.error - refute File.exist?(fetcher.dir), 'cache dir removed' + dir = File.join Gem.user_home, '.gem', 'specs' + refute File.exist?(dir), 'cache dir removed' end def test_execute_remove diff --git a/test/rubygems/test_gem_commands_specification_command.rb b/test/rubygems/test_gem_commands_specification_command.rb index 978c6fe194..252d0bdd55 100644 --- a/test/rubygems/test_gem_commands_specification_command.rb +++ b/test/rubygems/test_gem_commands_specification_command.rb @@ -71,7 +71,21 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase end assert_equal '', @ui.output - assert_equal "ERROR: Unknown gem 'foo'\n", @ui.error + 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 @@ -103,6 +117,24 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase assert_equal "foo", YAML.load(@ui.output) end + def test_execute_file + foo = quick_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' diff --git a/test/rubygems/test_gem_commands_uninstall_command.rb b/test/rubygems/test_gem_commands_uninstall_command.rb index 1db6146889..964ce85cc3 100644 --- a/test/rubygems/test_gem_commands_uninstall_command.rb +++ b/test/rubygems/test_gem_commands_uninstall_command.rb @@ -13,49 +13,32 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase end @cmd = Gem::Commands::UninstallCommand.new - @cmd.options[:executables] = true @executable = File.join(@gemhome, 'bin', 'executable') end - def test_execute_mulitple - @other = quick_gem 'c' - util_make_exec @other - util_build_gem @other - - @other_installer = util_installer @other, @gemhome - - ui = Gem::MockGemUi.new - util_setup_gem ui - - build_rake_in do - use_ui ui do - @other_installer.install - end - end - - @cmd.options[:args] = [@spec.name, @other.name] - - use_ui @ui do - @cmd.execute + def test_execute_dependency_order + c = quick_gem 'c' do |spec| + spec.add_dependency 'a' end - output = @ui.output.split "\n" + util_build_gem c + installer = util_installer c, @gemhome + use_ui @ui do installer.install end - assert_includes output, "Successfully uninstalled #{@spec.full_name}" - assert_includes output, "Successfully uninstalled #{@other.full_name}" - end + ui = Gem::MockGemUi.new - def test_execute_mulitple_nonexistent - @cmd.options[:args] = %w[x y] + @cmd.options[:args] = %w[a c] + @cmd.options[:executables] = true - use_ui @ui do + use_ui ui do @cmd.execute end - output = @ui.output.split "\n" + output = ui.output.split "\n" - assert_includes output, 'INFO: gem "x" is not installed' - assert_includes output, 'INFO: gem "y" is not installed' + 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 @@ -79,6 +62,7 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase open @executable, "wb+" do |f| f.puts "binary" end + @cmd.options[:executables] = true @cmd.options[:args] = [@spec.name] use_ui @ui do @cmd.execute @@ -102,6 +86,7 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase 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 @@ -123,6 +108,7 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase end end + @cmd.options[:executables] = true @cmd.options[:args] = ["pre"] use_ui @ui do @@ -133,5 +119,79 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase 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_default_gem + default_gem_spec = new_default_spec("default", "2.0.0.0", + nil, "default/gem.rb") + install_default_specs(default_gem_spec) + + ui = Gem::MockGemUi.new + + @cmd.options[:args] = %w[default] + @cmd.options[:executables] = true + + use_ui ui do + e = assert_raises Gem::InstallError do + @cmd.execute + end + assert_equal "gem \"default\" cannot be uninstalled because it is a default gem", + e.message + end + end end diff --git a/test/rubygems/test_gem_commands_unpack_command.rb b/test/rubygems/test_gem_commands_unpack_command.rb index cd8716b36b..183a7e67c0 100644 --- a/test/rubygems/test_gem_commands_unpack_command.rb +++ b/test/rubygems/test_gem_commands_unpack_command.rb @@ -191,8 +191,8 @@ class TestGemCommandsUnpackCommand < Gem::TestCase use_ui @ui do Dir.chdir @tempdir do - Gem::Builder.new(foo_spec).build - Gem::Builder.new(foo_bar_spec).build + Gem::Package.build foo_spec + Gem::Package.build foo_bar_spec end end @@ -209,7 +209,7 @@ class TestGemCommandsUnpackCommand < Gem::TestCase end end - assert File.exist?(File.join(@tempdir, foo_spec.full_name)) + assert_path_exists File.join(@tempdir, foo_spec.full_name) end def test_handle_options_metadata diff --git a/test/rubygems/test_gem_commands_update_command.rb b/test/rubygems/test_gem_commands_update_command.rb index b283d484e3..536a3d57fb 100644 --- a/test/rubygems/test_gem_commands_update_command.rb +++ b/test/rubygems/test_gem_commands_update_command.rb @@ -14,20 +14,22 @@ class TestGemCommandsUpdateCommand < Gem::TestCase @cmd = Gem::Commands::UpdateCommand.new - @cmd.options[:generate_rdoc] = false - @cmd.options[:generate_ri] = false + @cmd.options[:document] = [] - util_setup_fake_fetcher + util_setup_fake_fetcher(true) util_clear_gems - util_setup_spec_fetcher @a1, @a2 + util_setup_spec_fetcher @a1, @a2, @a3a @a1_path = @a1.cache_file @a2_path = @a2.cache_file + @a3a_path = @a3a.cache_file @fetcher.data["#{@gem_repo}gems/#{File.basename @a1_path}"] = read_binary @a1_path @fetcher.data["#{@gem_repo}gems/#{File.basename @a2_path}"] = read_binary @a2_path + @fetcher.data["#{@gem_repo}gems/#{File.basename @a3a_path}"] = + read_binary @a3a_path end def test_execute @@ -36,8 +38,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase Gem::Installer.new(@a1_path).install @cmd.options[:args] = [] - @cmd.options[:generate_rdoc] = false - @cmd.options[:generate_ri] = false use_ui @ui do @cmd.execute @@ -46,7 +46,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase out = @ui.output.split "\n" assert_equal "Updating installed gems", out.shift assert_equal "Updating #{@a2.name}", out.shift - assert_equal "Successfully installed #{@a2.full_name}", out.shift assert_equal "Gems updated: #{@a2.name}", out.shift assert_empty out end @@ -91,8 +90,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase @cmd.options[:args] = [] @cmd.options[:system] = true - @cmd.options[:generate_rdoc] = false - @cmd.options[:generate_ri] = false use_ui @ui do @cmd.execute @@ -100,7 +97,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase out = @ui.output.split "\n" assert_equal "Updating rubygems-update", out.shift - assert_equal "Successfully installed rubygems-update-9", out.shift assert_equal "Installing RubyGems 9", out.shift assert_equal "RubyGems system software updated", out.shift @@ -115,8 +111,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase @cmd.options[:args] = [] @cmd.options[:system] = true - @cmd.options[:generate_rdoc] = false - @cmd.options[:generate_ri] = false assert_raises Gem::MockGemUi::SystemExitException do use_ui @ui do @@ -138,8 +132,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase @cmd.options[:args] = [] @cmd.options[:system] = true - @cmd.options[:generate_rdoc] = false - @cmd.options[:generate_ri] = false use_ui @ui do @cmd.execute @@ -147,7 +139,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase out = @ui.output.split "\n" assert_equal "Updating rubygems-update", out.shift - assert_equal "Successfully installed rubygems-update-9", out.shift assert_equal "Installing RubyGems 9", out.shift assert_equal "RubyGems system software updated", out.shift @@ -163,8 +154,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase @cmd.options[:args] = [] @cmd.options[:system] = "8" - @cmd.options[:generate_rdoc] = false - @cmd.options[:generate_ri] = false use_ui @ui do @cmd.execute @@ -172,7 +161,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase out = @ui.output.split "\n" assert_equal "Updating rubygems-update", out.shift - assert_equal "Successfully installed rubygems-update-8", out.shift assert_equal "Installing RubyGems 8", out.shift assert_equal "RubyGems system software updated", out.shift @@ -188,8 +176,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase @cmd.options[:args] = [] @cmd.options[:system] = "9" - @cmd.options[:generate_rdoc] = false - @cmd.options[:generate_ri] = false use_ui @ui do @cmd.execute @@ -197,7 +183,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase out = @ui.output.split "\n" assert_equal "Updating rubygems-update", out.shift - assert_equal "Successfully installed rubygems-update-9", out.shift assert_equal "Installing RubyGems 9", out.shift assert_equal "RubyGems system software updated", out.shift @@ -207,8 +192,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase def test_execute_system_with_gems @cmd.options[:args] = %w[gem] @cmd.options[:system] = true - @cmd.options[:generate_rdoc] = false - @cmd.options[:generate_ri] = false assert_raises Gem::MockGemUi::TermError do use_ui @ui do @@ -270,15 +253,33 @@ class TestGemCommandsUpdateCommand < Gem::TestCase out = @ui.output.split "\n" assert_equal "Updating installed gems", out.shift assert_equal "Updating #{@a2.name}", out.shift - assert_equal "Successfully installed #{@c2.full_name}", out.shift - assert_equal "Successfully installed #{@b2.full_name}", out.shift - assert_equal "Successfully installed #{@a2.full_name}", out.shift - assert_equal "Gems updated: #{@c2.name}, #{@b2.name}, #{@a2.name}", + assert_equal "Gems updated: #{@c2.name} #{@b2.name} #{@a2.name}", out.shift assert_empty out end + def test_execute_rdoc + Gem.done_installing(&Gem::RDoc.method(:generation_hook)) + + @cmd.options[:document] = %w[rdoc ri] + + util_clear_gems + + Gem::Installer.new(@a1_path).install + + @cmd.options[:args] = [@a1.name] + + use_ui @ui do + @cmd.execute + 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_named util_clear_gems @@ -293,7 +294,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase out = @ui.output.split "\n" assert_equal "Updating installed gems", out.shift assert_equal "Updating #{@a2.name}", out.shift - assert_equal "Successfully installed #{@a2.full_name}", out.shift assert_equal "Gems updated: #{@a2.name}", out.shift assert_empty out @@ -317,6 +317,26 @@ class TestGemCommandsUpdateCommand < Gem::TestCase assert_empty out end + def test_execute_named_up_to_date_prerelease + util_clear_gems + + Gem::Installer.new(@a2_path).install + + @cmd.options[:args] = [@a2.name] + @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 #{@a3a.name}", out.shift + assert_equal "Gems updated: #{@a3a.name}", out.shift + + assert_empty out + end + def test_execute_up_to_date util_clear_gems @@ -339,11 +359,10 @@ class TestGemCommandsUpdateCommand < Gem::TestCase @cmd.handle_options %w[--system] expected = { - :generate_ri => true, - :system => true, - :force => false, - :args => [], - :generate_rdoc => true, + :args => [], + :document => %w[rdoc ri], + :force => false, + :system => true, } assert_equal expected, @cmd.options @@ -359,11 +378,10 @@ class TestGemCommandsUpdateCommand < Gem::TestCase @cmd.handle_options %w[--system 1.3.7] expected = { - :generate_ri => true, - :system => "1.3.7", - :force => false, - :args => [], - :generate_rdoc => true, + :args => [], + :document => %w[rdoc ri], + :force => false, + :system => "1.3.7", } assert_equal expected, @cmd.options diff --git a/test/rubygems/test_gem_commands_which_command.rb b/test/rubygems/test_gem_commands_which_command.rb index 4985395871..bf7be639c8 100644 --- a/test/rubygems/test_gem_commands_which_command.rb +++ b/test/rubygems/test_gem_commands_which_command.rb @@ -41,19 +41,19 @@ class TestGemCommandsWhichCommand < Gem::TestCase util_foo_bar - @cmd.handle_options %w[foo_bar missing] + @cmd.handle_options %w[foo_bar missinglib] use_ui @ui do @cmd.execute 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 missing\n%, + 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[missing] + @cmd.handle_options %w[missinglib] use_ui @ui do assert_raises Gem::MockGemUi::TermError do @@ -62,7 +62,7 @@ class TestGemCommandsWhichCommand < Gem::TestCase end assert_equal '', @ui.output - assert_match %r%Can.t find ruby library file or shared library missing\n%, + assert_match %r%Can.t find ruby library file or shared library missinglib\n%, @ui.error end diff --git a/test/rubygems/test_gem_commands_yank_command.rb b/test/rubygems/test_gem_commands_yank_command.rb new file mode 100644 index 0000000000..e627452243 --- /dev/null +++ b/test/rubygems/test_gem_commands_yank_command.rb @@ -0,0 +1,97 @@ +require 'rubygems/test_case' +require 'rubygems/commands/yank_command' + +class TestGemCommandsYankCommand < Gem::TestCase + def setup + super + + @cmd = Gem::Commands::YankCommand.new + @cmd.host = 'http://example' + + @fetcher = Gem::RemoteFetcher.fetcher + + Gem.configuration.rubygems_api_key = 'key' + Gem.configuration.api_keys[:KEY] = 'other' + end + + def test_handle_options + @cmd.handle_options %w[a --version 1.0 --platform x86-darwin -k KEY] + + assert_equal %w[a], @cmd.options[:args] + assert_equal 'KEY', @cmd.options[:key] + assert_nil @cmd.options[:platform] + assert_equal req('= 1.0'), @cmd.options[:version] + end + + def test_handle_options_missing_argument + %w[-v --version -p --platform].each do |option| + assert_raises OptionParser::MissingArgument do + @cmd.handle_options %W[a #{option}] + end + end + end + + def test_execute + yank_uri = 'http://example/api/v1/gems/yank' + @fetcher.data[yank_uri] = ['Successfully yanked', 200, 'OK'] + + @cmd.options[:args] = %w[a] + @cmd.options[:added_platform] = true + @cmd.options[:version] = req('= 1.0') + + use_ui @ui do + @cmd.execute + end + + assert_match %r%Yanking gem from http://example%, @ui.output + assert_match %r%Successfully yanked%, @ui.output + + platform = Gem.platforms[1] + body = @fetcher.last_request.body.split('&').sort + assert_equal %W[gem_name=a platform=#{platform} version=1.0], body + + assert_equal 'key', @fetcher.last_request['Authorization'] + + assert_equal [yank_uri], @fetcher.paths + end + + def test_execute_key + yank_uri = 'http://example/api/v1/gems/yank' + @fetcher.data[yank_uri] = ['Successfully yanked', 200, 'OK'] + + @cmd.options[:args] = %w[a] + @cmd.options[:version] = req('= 1.0') + @cmd.options[:key] = 'KEY' + + use_ui @ui do + @cmd.execute + end + + body = @fetcher.last_request.body.split('&').sort + assert_equal %w[gem_name=a version=1.0], body + assert_equal 'other', @fetcher.last_request['Authorization'] + end + + def test_execute_undo + unyank_uri = 'http://example/api/v1/gems/unyank' + @fetcher.data[unyank_uri] = ['Successfully unyanked', 200, 'OK'] + + @cmd.options[:args] = %w[a] + @cmd.options[:version] = req('= 1.0') + @cmd.options[:undo] = true + + use_ui @ui do + @cmd.execute + end + + assert_match %r%Unyanking gem from http://example%, @ui.output + assert_match %r%Successfully unyanked%, @ui.output + + body = @fetcher.last_request.body.split('&').sort + assert_equal %w[gem_name=a version=1.0], body + + assert_equal [unyank_uri], @fetcher.paths + end + +end + diff --git a/test/rubygems/test_gem_config_file.rb b/test/rubygems/test_gem_config_file.rb index 702ac95149..ab6f87e2fd 100644 --- a/test/rubygems/test_gem_config_file.rb +++ b/test/rubygems/test_gem_config_file.rb @@ -17,6 +17,9 @@ class TestGemConfigFile < Gem::TestCase Gem::ConfigFile::OPERATING_SYSTEM_DEFAULTS.clear Gem::ConfigFile::PLATFORM_DEFAULTS.clear + @env_gemrc = ENV['GEMRC'] + ENV['GEMRC'] = '' + util_config_file end @@ -27,6 +30,8 @@ class TestGemConfigFile < Gem::TestCase Gem::ConfigFile.send :const_set, :SYSTEM_WIDE_CONFIG_FILE, @orig_SYSTEM_WIDE_CONFIG_FILE + ENV['GEMRC'] = @env_gemrc + super end @@ -35,7 +40,6 @@ class TestGemConfigFile < Gem::TestCase assert_equal false, @cfg.backtrace assert_equal true, @cfg.update_sources - assert_equal false, @cfg.benchmark assert_equal Gem::ConfigFile::DEFAULT_BULK_THRESHOLD, @cfg.bulk_threshold assert_equal true, @cfg.verbose assert_equal [@gem_repo], Gem.sources @@ -43,7 +47,6 @@ class TestGemConfigFile < Gem::TestCase File.open @temp_conf, 'w' do |fp| fp.puts ":backtrace: true" fp.puts ":update_sources: false" - fp.puts ":benchmark: true" fp.puts ":bulk_threshold: 10" fp.puts ":verbose: false" fp.puts ":sources:" @@ -59,7 +62,6 @@ class TestGemConfigFile < Gem::TestCase util_config_file assert_equal true, @cfg.backtrace - assert_equal true, @cfg.benchmark assert_equal 10, @cfg.bulk_threshold assert_equal false, @cfg.verbose assert_equal false, @cfg.update_sources @@ -131,6 +133,37 @@ class TestGemConfigFile < Gem::TestCase 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_handle_arguments args = %w[--backtrace --bunch --of --args here] @@ -149,16 +182,6 @@ class TestGemConfigFile < Gem::TestCase assert_equal true, @cfg.backtrace end - def test_handle_arguments_benchmark - assert_equal false, @cfg.benchmark - - args = %w[--benchmark] - - @cfg.handle_arguments args - - assert_equal true, @cfg.benchmark - end - def test_handle_arguments_debug old_dollar_DEBUG = $DEBUG assert_equal false, $DEBUG @@ -174,12 +197,12 @@ class TestGemConfigFile < Gem::TestCase def test_handle_arguments_override File.open @temp_conf, 'w' do |fp| - fp.puts ":benchmark: false" + fp.puts ":backtrace: false" end - util_config_file %W[--benchmark --config-file=#{@temp_conf}] + util_config_file %W[--backtrace --config-file=#{@temp_conf}] - assert_equal true, @cfg.benchmark + assert_equal true, @cfg.backtrace end def test_handle_arguments_traceback @@ -206,7 +229,6 @@ class TestGemConfigFile < Gem::TestCase def test_write @cfg.backtrace = true - @cfg.benchmark = true @cfg.update_sources = false @cfg.bulk_threshold = 10 @cfg.verbose = false @@ -219,7 +241,6 @@ class TestGemConfigFile < Gem::TestCase # These should not be written out to the config file. assert_equal false, @cfg.backtrace, 'backtrace' - assert_equal false, @cfg.benchmark, 'benchmark' assert_equal Gem::ConfigFile::DEFAULT_BULK_THRESHOLD, @cfg.bulk_threshold, 'bulk_threshold' assert_equal true, @cfg.update_sources, 'update_sources' @@ -234,7 +255,6 @@ class TestGemConfigFile < Gem::TestCase def test_write_from_hash File.open @temp_conf, 'w' do |fp| fp.puts ":backtrace: true" - fp.puts ":benchmark: true" fp.puts ":bulk_threshold: 10" fp.puts ":update_sources: false" fp.puts ":verbose: false" @@ -246,7 +266,6 @@ class TestGemConfigFile < Gem::TestCase util_config_file @cfg.backtrace = :junk - @cfg.benchmark = :junk @cfg.update_sources = :junk @cfg.bulk_threshold = 20 @cfg.verbose = :junk @@ -259,7 +278,6 @@ class TestGemConfigFile < Gem::TestCase # These should not be written out to the config file assert_equal true, @cfg.backtrace, 'backtrace' - assert_equal true, @cfg.benchmark, 'benchmark' assert_equal 10, @cfg.bulk_threshold, 'bulk_threshold' assert_equal false, @cfg.update_sources, 'update_sources' assert_equal false, @cfg.verbose, 'verbose' @@ -295,6 +313,26 @@ class TestGemConfigFile < Gem::TestCase :other => 'a5fdbb6ba150cbb83aad2bb2fede64c'}, @cfg.api_keys) end + def test_save_credentials_file_with_strict_permissions + util_config_file + FileUtils.mkdir File.dirname(@cfg.credentials_path) + @cfg.rubygems_api_key = '701229f217cdf23b1344c7b4b54ca97' + mode = 0100600 & (~File.umask) + assert_equal mode, File.stat(@cfg.credentials_path).mode unless win_platform? + end + + def test_ignore_invalid_config_file + File.open @temp_conf, 'w' do |fp| + fp.puts "some-non-yaml-hash-string" + end + + # Avoid writing stuff to output when running tests + Gem::ConfigFile.class_eval { def warn(args); end } + + # This should not raise exception + util_config_file + end + def test_load_ssl_verify_mode_from_config File.open @temp_conf, 'w' do |fp| fp.puts ":ssl_verify_mode: 1" @@ -315,5 +353,12 @@ class TestGemConfigFile < Gem::TestCase @cfg = Gem::ConfigFile.new args end + def test_disable_default_gem_server + File.open @temp_conf, 'w' do |fp| + fp.puts ":disable_default_gem_server: true" + end + util_config_file + assert_equal(true, @cfg.disable_default_gem_server) + end end diff --git a/test/rubygems/test_gem_dependency.rb b/test/rubygems/test_gem_dependency.rb index e1ba5ffbe7..7fc4dbbebf 100644 --- a/test/rubygems/test_gem_dependency.rb +++ b/test/rubygems/test_gem_dependency.rb @@ -9,6 +9,15 @@ class TestGemDependency < Gem::TestCase 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 @@ -173,5 +182,42 @@ class TestGemDependency < Gem::TestCase assert dep('a', '= 1').specific? 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_equal "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_equal "Could not find 'b' (= 2.0) among 1 total gem(s)", e.message + end + + end diff --git a/test/rubygems/test_gem_dependency_installer.rb b/test/rubygems/test_gem_dependency_installer.rb index 03c1200b40..c021568800 100644 --- a/test/rubygems/test_gem_dependency_installer.rb +++ b/test/rubygems/test_gem_dependency_installer.rb @@ -23,6 +23,14 @@ class TestGemDependencyInstaller < Gem::TestCase 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 @@ -42,6 +50,62 @@ class TestGemDependencyInstaller < Gem::TestCase 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 = File.read(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_when_only_prerelease + p1a, gem = util_gem 'p', '1.a' + + util_setup_spec_fetcher(p1a) + util_clear_gems + + p1a_data = File.read(gem) + + @fetcher.data['http://gems.example.com/gems/p-1.a.gem'] = p1a_data + + dep = Gem::Dependency.new "p" + inst = Gem::DependencyInstaller.new + inst.install dep + + 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 = File.read(@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 @@ -69,14 +133,44 @@ class TestGemDependencyInstaller < Gem::TestCase assert_equal %w[e-1 a-1], inst.installed_gems.map { |s| s.full_name } end - def test_install_cache_dir + def test_install_ignore_satified_deps 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 + + Dir.chdir @tempdir do + i = Gem::DependencyInstaller.new :ignore_dependencies => true + i.install 'b' + end + inst = nil Dir.chdir @tempdir do + inst = Gem::DependencyInstaller.new :minimal_deps => true + inst.install 'e' + end + + assert_equal %w[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 @@ -103,7 +197,7 @@ class TestGemDependencyInstaller < Gem::TestCase Dir.chdir @tempdir do inst = Gem::DependencyInstaller.new - inst.install 'a-2' + inst.install 'a', Gem::Requirement.create("= 2") end FileUtils.rm File.join(@tempdir, a2.file_name) @@ -117,19 +211,67 @@ class TestGemDependencyInstaller < Gem::TestCase assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name } end - def test_install_dependency + # 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 + inst = nil + Dir.chdir @tempdir do + inst = Gem::DependencyInstaller.new + inst.install 'a', Gem::Requirement.create("= 2") + end + + 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 + + def test_install_dependency + util_setup_gems + + done_installing_ran = false + inst = nil + + Gem.done_installing do |installer, specs| + done_installing_ran = true + assert_equal inst, 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 @@ -152,6 +294,50 @@ class TestGemDependencyInstaller < Gem::TestCase 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 @@ -517,11 +703,12 @@ class TestGemDependencyInstaller < Gem::TestCase policy = Gem::Security::HighSecurity inst = Gem::DependencyInstaller.new :security_policy => policy - e = assert_raises Gem::Exception do + e = assert_raises Gem::Security::Exception do inst.install 'b' end - assert_equal 'Unsigned gem', e.message + 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 @@ -581,7 +768,14 @@ class TestGemDependencyInstaller < Gem::TestCase Gem::Specification.reset - assert_equal [[@b1, @gem_repo]], inst.find_gems_with_sources(dep) + 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_gems_with_sources_local @@ -590,21 +784,24 @@ class TestGemDependencyInstaller < Gem::TestCase FileUtils.mv @a1_gem, @tempdir inst = Gem::DependencyInstaller.new dep = Gem::Dependency.new 'a', '>= 0' - gems = nil + set = nil Dir.chdir @tempdir do - gems = inst.find_gems_with_sources dep + set = inst.find_gems_with_sources dep end - assert_equal 2, gems.length - remote = gems.first - assert_equal 'a-1', remote.first.full_name, 'remote spec' - assert_equal @gem_repo, remote.last, 'remote path' + gems = set.sorted - local = gems.last - assert_equal 'a-1', local.first.full_name, 'local spec' + assert_equal 2, gems.length + local = gems.first + assert_equal 'a-1', local.spec.full_name, 'local spec' assert_equal File.join(@tempdir, @a1.file_name), - local.last, 'local path' + local.source.download(local.spec), 'local path' + + remote = gems.last + 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 @@ -615,7 +812,7 @@ class TestGemDependencyInstaller < Gem::TestCase dependency = Gem::Dependency.new('a', Gem::Requirement.default) releases = - installer.find_gems_with_sources(dependency).map { |gems, *| gems } + 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' } @@ -623,9 +820,22 @@ class TestGemDependencyInstaller < Gem::TestCase dependency.prerelease = true prereleases = - installer.find_gems_with_sources(dependency).map { |gems, *| gems } + 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_equal [@a1_pre], prereleases + assert out.empty? + assert_kind_of Gem::SourceFetchProblem, installer.errors.first end def assert_resolve expected, *specs diff --git a/test/rubygems/test_gem_dependency_list.rb b/test/rubygems/test_gem_dependency_list.rb index b6d1b2f754..478481b88c 100644 --- a/test/rubygems/test_gem_dependency_list.rb +++ b/test/rubygems/test_gem_dependency_list.rb @@ -24,15 +24,6 @@ class TestGemDependencyList < Gem::TestCase @d1 = quick_spec 'd', '1' do |s| s.add_dependency 'c', '>= 1' end end - def test_self_from_source_index - util_clear_gems - install_specs @a1, @b2 - - deps = Gem::Deprecate.skip_during { Gem::DependencyList.from_source_index } - - assert_equal %w[b-2 a-1], deps.dependency_order.map { |s| s.full_name } - end - def test_active_count assert_equal 0, @deplist.send(:active_count, [], {}) assert_equal 1, @deplist.send(:active_count, [@a1], {}) diff --git a/test/rubygems/test_gem_dependency_resolver.rb b/test/rubygems/test_gem_dependency_resolver.rb new file mode 100644 index 0000000000..08d8e62f2b --- /dev/null +++ b/test/rubygems/test_gem_dependency_resolver.rb @@ -0,0 +1,327 @@ +require 'rubygems/test_case' +require 'rubygems/dependency_resolver' + +class TestGemDependencyResolver < Gem::TestCase + + def make_dep(name, *req) + Gem::Dependency.new(name, *req) + end + + def set(*specs) + StaticSet.new(specs) + end + + def assert_set(expected, actual) + exp = expected.sort_by { |s| s.full_name } + act = actual.map { |a| a.spec }.sort_by { |s| s.full_name } + + assert_equal exp, act + 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::DependencyResolver.new(deps, s) + + assert_set [a, b], res.resolve + 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::DependencyResolver.new(deps, s) + + assert_set [a, b, c], res.resolve + 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::DependencyResolver.new([ad], s) + + assert_set [a2], res.resolve + 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::DependencyResolver.new([ad, bd], s) + + assert_set [a1, b1, c1], res.resolve + 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::DependencyResolver.new([ad, bd], s) + + assert_set [a1, b1, c1], res.resolve + + cons = res.conflicts + + assert_equal 1, cons.size + con = cons.first + + assert_equal "c (= 1)", con.dependency.to_s + assert_equal "c-2", con.activated.full_name + 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::DependencyResolver.new([ad, bd], s) + + assert_set [a1, b1, c1, d4], res.resolve + + cons = res.conflicts + + assert_equal 1, cons.size + con = cons.first + + assert_equal "c (= 1)", con.dependency.to_s + assert_equal "c-2", con.activated.full_name + 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::DependencyResolver.new([ad, bd], s) + + e = assert_raises Gem::DependencyResolutionError do + r.resolve + end + + assert_equal "unable to resolve conflicting dependencies 'c (= 2)' and 'c (= 1)'", e.message + + deps = [make_dep("c", "= 2"), make_dep("c", "= 1")] + assert_equal deps, e.conflicting_dependencies + + con = e.conflict + + act = con.activated + assert_equal "c-1", act.spec.full_name + + parent = act.parent + assert_equal "a-1", parent.spec.full_name + + act = con.requester + assert_equal "b-1", act.spec.full_name + end + + def test_raises_when_a_gem_is_missing + ad = make_dep "a" + + r = Gem::DependencyResolver.new([ad], set) + + e = assert_raises Gem::UnsatisfiableDepedencyError do + r.resolve + end + + assert_equal "unable to find any gem matching dependency '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::DependencyResolver.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_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::DependencyResolver.new([ad, bd], s) + + e = assert_raises Gem::ImpossibleDependenciesError do + r.resolve + end + + assert_equal "detected 1 conflict with dependency 'c (>= 2)'", e.message + + assert_equal "c (>= 2)", e.dependency.to_s + + s, con = e.conflicts[0] + assert_equal "c-3", s.full_name + assert_equal "c (= 1)", con.dependency.to_s + assert_equal "b-1", con.requester.full_name + 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::DependencyResolver.new([ad, bd], s) + + assert_set [a1, b1, c1], r.resolve + 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::DependencyResolver.new([d1, d2], s) + + assert_set [rails, ap, rack101, lib1], r.resolve + + # check it with the deps reverse too + + r = Gem::DependencyResolver.new([d2, d1], s) + + assert_set [lib1, rack101, rails, ap], r.resolve + 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::DependencyResolver.new([d1, d2, d3], s) + + assert_raises Gem::ImpossibleDependenciesError do + r.resolve + end + 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::DependencyResolver.new([d1, d2], s) + + assert_set [merch, mail, sup1], r.resolve + 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::DependencyResolver.new([p1, p2], s) + + assert_set [b1, c1, d2], r.resolve + end +end diff --git a/test/rubygems/test_gem_doc_manager.rb b/test/rubygems/test_gem_doc_manager.rb deleted file mode 100644 index 226f69d9cf..0000000000 --- a/test/rubygems/test_gem_doc_manager.rb +++ /dev/null @@ -1,32 +0,0 @@ -require 'rubygems/test_case' -require 'rubygems/doc_manager' - -class TestGemDocManager < Gem::TestCase - - def setup - super - - @spec = quick_gem 'a', 2 - @manager = Gem::DocManager.new(@spec) - end - - def test_uninstall_doc_unwritable - path = @spec.base_dir - orig_mode = File.stat(path).mode - - # File.chmod has no effect on MS Windows directories (it needs ACL). - if win_platform? - skip("test_uninstall_doc_unwritable skipped on MS Windows") - else - FileUtils.chmod 0000, path - end - - assert_raises Gem::FilePermissionError do - @manager.uninstall_doc - end - ensure - FileUtils.chmod orig_mode, path - end - -end - diff --git a/test/rubygems/test_gem_ext_ext_conf_builder.rb b/test/rubygems/test_gem_ext_ext_conf_builder.rb index c050d82f9c..2d20fed874 100644 --- a/test/rubygems/test_gem_ext_ext_conf_builder.rb +++ b/test/rubygems/test_gem_ext_ext_conf_builder.rb @@ -1,3 +1,5 @@ +# coding: UTF-8 + require 'rubygems/test_case' require 'rubygems/ext' @@ -119,6 +121,7 @@ checking for main\(\) in .*?nonexistent/m, error.message) 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 "all:" @@ -132,14 +135,10 @@ checking for main\(\) in .*?nonexistent/m, error.message) assert_equal make_command, output[0] assert_equal "#{make_command} install", output[2] - edited_makefile = <<-EOF -RUBYARCHDIR = #{@ext}$(target_prefix) -RUBYLIBDIR = #{@ext}$(target_prefix) -all: -install: - EOF + edited_makefile = Gem.read_binary makefile_path - assert_equal edited_makefile, File.read(makefile_path) + assert_match "\nRUBYARCHDIR = #{@ext}$(target_prefix)\n", edited_makefile + assert_match "\nRUBYLIBDIR = #{@ext}$(target_prefix)\n", edited_makefile end def test_class_make_no_Makefile diff --git a/test/rubygems/test_gem_ext_rake_builder.rb b/test/rubygems/test_gem_ext_rake_builder.rb index d30664372d..c8fceb63ee 100644 --- a/test/rubygems/test_gem_ext_rake_builder.rb +++ b/test/rubygems/test_gem_ext_rake_builder.rb @@ -24,18 +24,18 @@ class TestGemExtRakeBuilder < Gem::TestCase output = [] realdir = nil # HACK /tmp vs. /private/tmp - build_rake_in do + build_rake_in do |rake| Dir.chdir @ext do realdir = Dir.pwd Gem::Ext::RakeBuilder.build 'mkrf_conf.rb', nil, @dest_path, output end - end - output = output.join "\n" + 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 + 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 @@ -44,22 +44,22 @@ class TestGemExtRakeBuilder < Gem::TestCase File.open("Rakefile","w") do |f| f.puts "task :default do abort 'fail' end" end - EO_MKRF + EO_MKRF end output = [] - error = assert_raises Gem::InstallError do - build_rake_in do + 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 - end - assert_match %r%^rake failed:%, error.message - assert_match %r%^#{Regexp.escape @@ruby} mkrf_conf\.rb%, error.message - assert_match %r%^#{Regexp.escape @@rake} RUBYARCHDIR=#{Regexp.escape @dest_path} RUBYLIBDIR=#{Regexp.escape @dest_path}%, error.message + assert_match %r%^rake failed:%, error.message + assert_match %r%^#{Regexp.escape @@ruby} mkrf_conf\.rb%, error.message + assert_match %r%^#{Regexp.escape rake} RUBYARCHDIR=#{Regexp.escape @dest_path} RUBYLIBDIR=#{Regexp.escape @dest_path}%, error.message + end end end diff --git a/test/rubygems/test_gem_format.rb b/test/rubygems/test_gem_format.rb deleted file mode 100644 index 711527bf79..0000000000 --- a/test/rubygems/test_gem_format.rb +++ /dev/null @@ -1,88 +0,0 @@ -require 'rubygems/package/tar_test_case' -require 'rubygems/simple_gem' -require 'rubygems/format' - -class TestGemFormat < Gem::Package::TarTestCase - - def setup - super - - @simple_gem = SIMPLE_GEM - end - - # HACK this test should do less - def test_class_from_file_by_path - util_make_gems - - gems = Dir[File.join(@gemhome, "cache", "*.gem")] - - names = [@a1, @a2, @a3a, @a_evil9, @b2, @c1_2, @pl1].map do |spec| - spec.original_name - end - - gems_n_names = gems.sort.zip names - - gems_n_names.each do |gemfile, name| - spec = Gem::Format.from_file_by_path(gemfile).spec - - assert_equal name, spec.original_name - end - end - - def test_class_from_file_by_path_corrupt - Tempfile.open 'corrupt' do |io| - data = Gem.gzip 'a' * 10 - io.write tar_file_header('metadata.gz', "\000x", 0644, data.length) - io.write data - io.rewind - - e = assert_raises Gem::Package::FormatError do - Gem::Format.from_file_by_path io.path - end - - sub_message = 'Gem::Package::TarInvalidError: tar is corrupt, name contains null byte' - assert_equal "corrupt gem (#{sub_message}) in #{io.path}", e.message - assert_equal io.path, e.path - end - end - - def test_class_from_file_by_path_empty - util_make_gems - - empty_gem = File.join @tempdir, 'empty.gem' - FileUtils.touch empty_gem - - assert_nil Gem::Format.from_file_by_path(empty_gem) - end - - def test_class_from_file_by_path_nonexistent - assert_raises Gem::Exception do - Gem::Format.from_file_by_path '/a/path/that/is/nonexistent' - end - end - - def test_class_from_io_garbled - e = assert_raises Gem::Package::FormatError do - # subtly bogus input - Gem::Format.from_io(StringIO.new(@simple_gem.upcase)) - end - - assert_equal 'no metadata found', e.message - - e = assert_raises Gem::Package::FormatError do - # Totally bogus input - Gem::Format.from_io(StringIO.new(@simple_gem.reverse)) - end - - assert_equal 'no metadata found', e.message - - e = assert_raises Gem::Package::FormatError do - # This was intentionally screws up YAML parsing. - Gem::Format.from_io(StringIO.new(@simple_gem.gsub(/:/, "boom"))) - end - - assert_equal 'no metadata found', e.message - end - -end - diff --git a/test/rubygems/test_gem_gem_path_searcher.rb b/test/rubygems/test_gem_gem_path_searcher.rb deleted file mode 100644 index dfabc0b885..0000000000 --- a/test/rubygems/test_gem_gem_path_searcher.rb +++ /dev/null @@ -1,94 +0,0 @@ -require 'rubygems/test_case' -require 'rubygems/gem_path_searcher' - -class Gem::GemPathSearcher - attr_accessor :gemspecs - attr_accessor :lib_dirs -end - -class TestGemGemPathSearcher < Gem::TestCase - def setup - super - - @foo1 = new_spec 'foo', '0.1', nil, "lib/foo.rb" - @foo1.require_paths << 'lib2' - path = File.join 'gems', @foo1.full_name, 'lib', 'foo.rb' - write_file(path) { |fp| fp.puts "# #{path}" } - - @foo2 = new_spec 'foo', '0.2' - @bar1 = new_spec 'bar', '0.1' - @bar2 = new_spec 'bar', '0.2' - @nrp = new_spec 'nil_require_paths', '0.1' do |s| - s.require_paths = nil - end - - util_setup_fake_fetcher - Gem::Specification.reset - util_setup_spec_fetcher @foo1, @foo2, @bar1, @bar2 - - @fetcher = Gem::FakeFetcher.new - Gem::RemoteFetcher.fetcher = @fetcher - - @gps = Gem::Deprecate.skip_during { Gem::GemPathSearcher.new } - end - - def test_find - Gem::Deprecate.skip_during do - assert_equal @foo1, @gps.find('foo') - end - end - - def test_find_all - Gem::Deprecate.skip_during do - assert_equal [@foo1], @gps.find_all('foo') - end - end - - def test_init_gemspecs - Gem::Deprecate.skip_during do - util_clear_gems - util_setup_spec_fetcher @foo1, @foo2, @bar1, @bar2 - expected = [@bar2, @bar1, @foo2, @foo1].map(&:full_name) - actual = @gps.init_gemspecs.map(&:full_name) - assert_equal expected, actual - end - end - - def test_lib_dirs_for - Gem::Deprecate.skip_during do - lib_dirs = @gps.lib_dirs_for(@foo1) - expected = File.join @gemhome, 'gems', @foo1.full_name, '{lib,lib2}' - - assert_equal expected, lib_dirs - end - end - - def test_lib_dirs_for_nil_require_paths - Gem::Deprecate.skip_during do - assert_nil @gps.lib_dirs_for(@nrp) - end - end - - def test_matching_file_eh - Gem::Deprecate.skip_during do - refute @gps.matching_file?(@foo1, 'bar') - assert @gps.matching_file?(@foo1, 'foo') - end - end - - def test_matching_files - Gem::Deprecate.skip_during do - assert_equal [], @gps.matching_files(@foo1, 'bar') - - expected = File.join @foo1.full_gem_path, 'lib', 'foo.rb' - - assert_equal [expected], @gps.matching_files(@foo1, 'foo') - end - end - - def test_matching_files_nil_require_paths - Gem::Deprecate.skip_during do - assert_empty @gps.matching_files(@nrp, 'foo') - end - end -end diff --git a/test/rubygems/test_gem_gem_runner.rb b/test/rubygems/test_gem_gem_runner.rb index 044bd8868f..6680a784c9 100644 --- a/test/rubygems/test_gem_gem_runner.rb +++ b/test/rubygems/test_gem_gem_runner.rb @@ -3,6 +3,18 @@ require 'rubygems/gem_runner' class TestGemGemRunner < Gem::TestCase + def setup + super + + @orig_args = Gem::Command.build_args + end + + def teardown + super + + Gem::Command.build_args = @orig_args + end + def test_do_configuration Gem.clear_paths @@ -25,17 +37,27 @@ class TestGemGemRunner < Gem::TestCase gr = Gem::GemRunner.new gr.send :do_configuration, %W[--config-file #{temp_conf}] - assert_equal [other_gem_home, other_gem_path], Gem.path + assert_equal [other_gem_path, other_gem_home], Gem.path assert_equal %w[--commands], Gem::Command.extra_args - assert_equal %w[--all], Gem::DocManager.configured_args end - def test_build_args__are_handled + def test_build_args_are_handled Gem.clear_paths - Gem::GemRunner.new.run(%W[help -- --build_arg1 --build_arg2]) + cls = Class.new(Gem::Command) do + def execute + end + end + + test_obj = cls.new :ba_test + + cmds = Gem::CommandManager.new + cmds.register_command :ba_test, test_obj + + runner = Gem::GemRunner.new :command_manager => cmds + runner.run(%W[ba_test -- --build_arg1 --build_arg2]) - assert_equal %w[--build_arg1 --build_arg2], Gem::Command.build_args + assert_equal %w[--build_arg1 --build_arg2], test_obj.options[:build_args] end end diff --git a/test/rubygems/test_gem_gemcutter_utilities.rb b/test/rubygems/test_gem_gemcutter_utilities.rb index db4ed19d08..8de40f2037 100644 --- a/test/rubygems/test_gem_gemcutter_utilities.rb +++ b/test/rubygems/test_gem_gemcutter_utilities.rb @@ -15,6 +15,25 @@ class TestGemGemcutterUtilities < Gem::TestCase @cmd.extend Gem::GemcutterUtilities 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 diff --git a/test/rubygems/test_gem_indexer.rb b/test/rubygems/test_gem_indexer.rb index 6002cd8925..f942ebfadd 100644 --- a/test/rubygems/test_gem_indexer.rb +++ b/test/rubygems/test_gem_indexer.rb @@ -24,22 +24,13 @@ class TestGemIndexer < Gem::TestCase @d2_0_b = quick_spec 'd', '2.0.b' util_build_gem @d2_0_b - @_tempdir = @tempdir @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, - :rss_title => 'ExampleForge gems', - :rss_host => 'example.com', - :rss_gems_host => 'gems.example.com') - end - - def teardown - @tempdir = @_tempdir - super + @indexer = Gem::Indexer.new(@tempdir) end def test_initialize @@ -48,18 +39,10 @@ class TestGemIndexer < Gem::TestCase @indexer.directory indexer = Gem::Indexer.new @tempdir - assert indexer.build_legacy assert indexer.build_modern - indexer = Gem::Indexer.new @tempdir, :build_legacy => false, - :build_modern => true - refute indexer.build_legacy + indexer = Gem::Indexer.new @tempdir, :build_modern => true assert indexer.build_modern - - indexer = Gem::Indexer.new @tempdir, :build_legacy => true, - :build_modern => false - assert indexer.build_legacy - refute indexer.build_modern end def test_build_indicies @@ -79,7 +62,9 @@ class TestGemIndexer < Gem::TestCase ["b", Gem::Version.new("2"), "ruby"], ["c", Gem::Version.new("1.2"), "ruby"], ["d", Gem::Version.new("2.0"), "ruby"], - ["pl", Gem::Version.new("1"), "i386-linux"]] + ["dep_x", Gem::Version.new("1"), "ruby"], + ["pl", Gem::Version.new("1"), "i386-linux"], + ["x", Gem::Version.new("1"), "ruby"]] assert_equal expected, specs @@ -93,7 +78,9 @@ class TestGemIndexer < Gem::TestCase ["b", Gem::Version.new("2"), "ruby"], ["c", Gem::Version.new("1.2"), "ruby"], ["d", Gem::Version.new("2.0"), "ruby"], - ["pl", Gem::Version.new("1"), "i386-linux"]] + ["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 @@ -103,9 +90,6 @@ class TestGemIndexer < Gem::TestCase @indexer.generate_index end - assert_indexed @tempdir, "Marshal.#{@marshal_version}" - assert_indexed @tempdir, "Marshal.#{@marshal_version}.Z" - quickdir = File.join @tempdir, 'quick' marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}" @@ -122,208 +106,10 @@ class TestGemIndexer < Gem::TestCase assert_indexed @tempdir, "latest_specs.#{@marshal_version}" assert_indexed @tempdir, "latest_specs.#{@marshal_version}.gz" - - expected = <<-EOF - - - - ExampleForge gems - http://example.com - Recently released gems from http://example.com - RubyGems v#{Gem::VERSION} - http://cyber.law.harvard.edu/rss/rss.html - - a-2 - -<pre>This is a test description</pre> - - example@example.com (A User) - a-2 - - #{@a2.date.rfc2822} - http://example.com - - - a-3.a - -<pre>This is a test description</pre> - - example@example.com (A User) - a-3.a - - #{@a3a.date.rfc2822} - http://example.com - - - a_evil-9 - -<pre>This is a test description</pre> - - example@example.com (A User) - a_evil-9 - - #{@a_evil9.date.rfc2822} - http://example.com - - - b-2 - -<pre>This is a test description</pre> - - example@example.com (A User) - b-2 - - #{@b2.date.rfc2822} - http://example.com - - - c-1.2 - -<pre>This is a test description</pre> - - example@example.com (A User) - c-1.2 - - #{@c1_2.date.rfc2822} - http://example.com - - - d-2.0.a - -<pre>This is a test description</pre> - - example@example.com (A User) - d-2.0.a - - #{@d2_0_a.date.rfc2822} - http://example.com - - - d-2.0.b - -<pre>This is a test description</pre> - - example@example.com (A User) - d-2.0.b - - #{@d2_0_b.date.rfc2822} - http://example.com - - - pl-1-x86-linux - -<pre>This is a test description</pre> - - example@example.com (A User) - pl-1-x86-linux - - #{@pl1.date.rfc2822} - http://example.com - - - a-1 - -<pre>This line is really, really long. So long, in fact, that it is more than -eighty characters long! The purpose of this line is for testing wrapping -behavior because sometimes people don't wrap their text to eighty characters. -Without the wrapping, the text might not look good in the RSS feed. - -Also, a list: - * An entry that's actually kind of sort - * an entry that's really long, which will probably get wrapped funny. -That's ok, somebody wasn't thinking straight when they made it more than -eighty characters.</pre> - - example@example.com (Example), example2@example.com (Example2) - a-1 - - #{@a1.date.rfc2822} - http://a.example.com - - - - EOF - - gems_rss = File.read File.join(@tempdir, 'index.rss') - - assert_equal expected, gems_rss - end - - def test_generate_index_legacy - @indexer.build_modern = false - @indexer.build_legacy = true - - use_ui @ui do - @indexer.generate_index - end - - assert_indexed @tempdir, "Marshal.#{@marshal_version}" - assert_indexed @tempdir, "Marshal.#{@marshal_version}.Z" - - 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)}" - - refute_indexed @tempdir, "specs.#{@marshal_version}" - refute_indexed @tempdir, "specs.#{@marshal_version}.gz" - - refute_indexed @tempdir, "latest_specs.#{@marshal_version}" - refute_indexed @tempdir, "latest_specs.#{@marshal_version}.gz" - end - - def test_generate_index_legacy_back_to_back - @indexer.build_modern = true - @indexer.build_legacy = true - - use_ui @ui do - @indexer.generate_index - end - - @indexer = Gem::Indexer.new @tempdir - @indexer.build_modern = false - @indexer.build_legacy = true - - use_ui @ui do - @indexer.generate_index - end - - assert_indexed @tempdir, "Marshal.#{@marshal_version}" - assert_indexed @tempdir, "Marshal.#{@marshal_version}.Z" - - quickdir = File.join @tempdir, 'quick' - marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}" - - 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_modern @indexer.build_modern = true - @indexer.build_legacy = false use_ui @ui do @indexer.generate_index @@ -369,7 +155,6 @@ eighty characters.</pre> def test_generate_index_modern_back_to_back @indexer.build_modern = true - @indexer.build_legacy = true use_ui @ui do @indexer.generate_index @@ -377,15 +162,10 @@ eighty characters.</pre> @indexer = Gem::Indexer.new @tempdir @indexer.build_modern = true - @indexer.build_legacy = false use_ui @ui do @indexer.generate_index end - - assert_indexed @tempdir, "Marshal.#{@marshal_version}" - assert_indexed @tempdir, "Marshal.#{@marshal_version}.Z" - quickdir = File.join @tempdir, 'quick' marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}" @@ -407,14 +187,13 @@ eighty characters.</pre> @indexer.generate_index end - assert_match %r%^\.\.\.\.\.\.\.\.\.\.$%, @ui.output - assert_match %r%^Generating Marshal quick index gemspecs for 10 gems$%, + 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%^Generating Marshal master index$%, @ui.output assert_match %r%^Complete$%, @ui.output assert_match %r%^Compressing indicies$%, @ui.output @@ -438,7 +217,9 @@ eighty characters.</pre> ['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 @@ -472,7 +253,9 @@ eighty characters.</pre> ['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 @@ -500,6 +283,20 @@ eighty characters.</pre> 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 = quick_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 @@ -524,30 +321,32 @@ eighty characters.</pre> FileUtils.mv @d2_1.cache_file, gems FileUtils.mv @d2_1_a.cache_file, gems - use_ui @ui do - @indexer.update_index - end + with_system_gems do + use_ui @ui do + @indexer.update_index + end - assert_indexed marshal_quickdir, "#{File.basename(@d2_1.spec_file)}.rz" + assert_indexed marshal_quickdir, "#{File.basename(@d2_1.spec_file)}.rz" - specs_index = Marshal.load Gem.read_binary(@indexer.dest_specs_index) + 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 + 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) + 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 + 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) + 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 + assert_includes pre_specs_index, @d2_1_a_tuple + refute_includes pre_specs_index, @d2_1_tuple + end end def assert_indexed(dir, name) diff --git a/test/rubygems/test_gem_install_update_options.rb b/test/rubygems/test_gem_install_update_options.rb index 473c7fee41..18d3569417 100644 --- a/test/rubygems/test_gem_install_update_options.rb +++ b/test/rubygems/test_gem_install_update_options.rb @@ -1,24 +1,104 @@ 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' + @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[-i /install_to --rdoc --ri -E -f -w -P HighSecurity - --ignore-dependencies --format-exec --include-dependencies] + args = %w[ + --document + --format-exec + --ignore-dependencies + --rdoc + --ri + -E + -P HighSecurity + -f + -i /install_to + -w + ] assert @cmd.handles?(args) 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 @cmd.handle_options %w[-P HighSecurity] diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb index 33950ad46c..23ac5b1f35 100644 --- a/test/rubygems/test_gem_installer.rb +++ b/test/rubygems/test_gem_installer.rb @@ -2,24 +2,24 @@ require 'rubygems/installer_test_case' class TestGemInstaller < Gem::InstallerTestCase - def util_setup_install - @gemhome = @installer_tmp - Gem.use_paths @installer_tmp + def setup + super - @spec = Gem::Specification.find_by_name 'a' - @user_spec = Gem::Specification.find_by_name 'b' + if __name__ =~ /^test_install(_|$)/ then + FileUtils.rm_r @spec.gem_dir + FileUtils.rm_r @user_spec.gem_dir + end - @installer.spec = @spec - @installer.gem_home = @installer_tmp - @installer.gem_dir = @spec.gem_dir - @user_installer.spec = @user_spec - @user_installer.gem_home = @installer_tmp + @config = Gem.configuration end - def test_app_script_text - util_setup_install + def teardown + super - @spec.version = 2 + Gem.configuration = @config + end + + def test_app_script_text util_make_exec @spec, '' expected = <<-EOF @@ -53,8 +53,6 @@ load Gem.bin_path('a', 'executable', version) end def test_build_extensions_none - util_setup_install - use_ui @ui do @installer.build_extensions end @@ -66,8 +64,7 @@ load Gem.bin_path('a', 'executable', version) end def test_build_extensions_extconf_bad - util_setup_install - + @installer.spec = @spec @spec.extensions << 'extconf.rb' e = assert_raises Gem::Installer::ExtensionBuildError do @@ -91,9 +88,9 @@ load Gem.bin_path('a', 'executable', version) end def test_build_extensions_unsupported - util_setup_install - - gem_make_out = File.join @gemhome, 'gems', @spec.full_name, 'gem_make.out' + @installer.spec = @spec + FileUtils.mkdir_p @spec.gem_dir + gem_make_out = File.join @spec.gem_dir, 'gem_make.out' @spec.extensions << nil e = assert_raises Gem::Installer::ExtensionBuildError do @@ -113,95 +110,148 @@ load Gem.bin_path('a', 'executable', version) FileUtils.rm_f gem_make_out end - def test_ensure_dependency - util_setup_install + def test_build_extensions_with_build_args + args = ["--aa", "--bb"] + @installer.build_args = args + @installer.spec = @spec + @spec.extensions << 'extconf.rb' - dep = Gem::Dependency.new 'a', '>= 2' - assert @installer.ensure_dependency(@spec, dep) + File.open File.join(@spec.gem_dir, "extconf.rb"), "w" do |f| + f.write <<-'RUBY' + puts "IN EXTCONF" + File.open 'extconf_args', 'w' do |f| + f.puts ARGV.inspect + end + + File.open 'Makefile', 'w' do |f| + f.puts "default:\n\techo built" + f.puts "install:\n\techo installed" + end + RUBY + end - dep = Gem::Dependency.new 'b', '> 2' - e = assert_raises Gem::InstallError do - @installer.ensure_dependency @spec, dep + use_ui @ui do + @installer.build_extensions end - assert_equal 'a requires b (> 2)', e.message + path = File.join @spec.gem_dir, "extconf_args" + + assert_equal args.inspect, File.read(path).strip end - def test_extract_files - util_setup_install + def test_check_executable_overwrite + @installer.generate_bin - format = Object.new - def format.file_entries - [[{'size' => 7, 'mode' => 0400, 'path' => 'thefile'}, 'content']] + @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 - @installer.format = format + util_make_exec + @installer.gem_dir = util_gem_dir @spec + @installer.wrappers = true + @installer.generate_bin - @installer.extract_files + installed_exec = File.join util_inst_bindir, 'executable' + assert File.exist? installed_exec - thefile_path = File.join(util_gem_dir, 'thefile') - assert_equal 'content', File.read(thefile_path) + wrapper = File.read installed_exec + assert_match %r|generated by RubyGems|, wrapper + end - unless Gem.win_platform? then - assert_equal 0400, File.stat(thefile_path).mode & 0777 + 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 - end + orig_bindir = Gem::ConfigMap[:bindir] + Gem::ConfigMap[:bindir] = Gem.bindir - def test_extract_files_bad_dest - util_setup_install + util_conflict_executable false - @installer.gem_dir = 'somedir' - @installer.format = nil - e = assert_raises ArgumentError do - @installer.extract_files - end + ui = Gem::MockGemUi.new "n\n" + use_ui ui do + e = assert_raises Gem::InstallError do + @installer.generate_bin + end - assert_equal 'format required to extract from', e.message + conflicted = File.join @gemhome, 'bin', 'executable' + assert_equal "\"executable\" from a conflicts with #{conflicted}", + e.message + end + ensure + Object.const_set :RUBY_FRAMEWORK_VERSION, orig_RUBY_FRAMEWORK_VERSION if + orig_RUBY_FRAMEWORK_VERSION + Gem::ConfigMap[:bindir] = orig_bindir end - def test_extract_files_relative - util_setup_install + def test_check_executable_overwrite_other_gem + util_conflict_executable true - format = Object.new - def format.file_entries - [[{'size' => 10, 'mode' => 0644, 'path' => '../thefile'}, '../thefile']] - end + ui = Gem::MockGemUi.new "n\n" - @installer.format = format + use_ui ui do + e = assert_raises Gem::InstallError do + @installer.generate_bin + end - e = assert_raises Gem::InstallError do - @installer.extract_files + 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 - dir = util_gem_dir - expected = "attempt to install file into \"../thefile\" under #{dir}" - assert_equal expected, e.message - assert_equal false, File.file?(File.join(@tempdir, '../thefile')), - "You may need to remove this file if you broke the test once" + @installer.generate_bin + + installed_exec = File.join util_inst_bindir, 'executable' + assert File.exist? installed_exec + + wrapper = File.read installed_exec + assert_match %r|generated by RubyGems|, wrapper end - def test_extract_files_absolute - util_setup_install + def test_check_executable_overwrite_other_non_gem + util_conflict_executable false + @installer.wrappers = true - format = Object.new - def format.file_entries - [[{'size' => 8, 'mode' => 0644, 'path' => '/thefile'}, '/thefile']] - end + @installer.generate_bin + + installed_exec = File.join util_inst_bindir, 'executable' + assert File.exist? installed_exec - @installer.format = format + wrapper = File.read installed_exec + assert_match %r|generated by RubyGems|, wrapper + end + + def test_ensure_dependency + quick_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.extract_files + @installer.ensure_dependency @spec, dep end - assert_equal 'attempt to install file into /thefile', e.message - assert_equal false, File.file?(File.join('/thefile')), - "You may need to remove this file if you broke the test once" + assert_equal 'a requires b (> 2)', e.message end - def test_generate_bin_bindir - util_setup_install + 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] @@ -227,16 +277,15 @@ load Gem.bin_path('a', 'executable', version) end def test_generate_bin_bindir_with_user_install_warning - util_setup_install - - bin_dir = Gem.win_platform? ? File.expand_path(ENV["WINDIR"]) : "/usr/bin" + 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 nil, options + inst = Gem::Installer.new '', options Gem::Installer.path_warning = false @@ -248,16 +297,14 @@ load Gem.bin_path('a', 'executable', version) end def test_generate_bin_script - util_setup_install - @installer.wrappers = true 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.exist?(installed_exec) + assert File.directory? util_inst_bindir + installed_exec = File.join util_inst_bindir, 'executable' + assert File.exist? installed_exec assert_equal mask, File.stat(installed_exec).mode unless win_platform? wrapper = File.read installed_exec @@ -265,8 +312,6 @@ load Gem.bin_path('a', 'executable', version) end def test_generate_bin_script_format - util_setup_install - @installer.format_executable = true @installer.wrappers = true util_make_exec @@ -282,8 +327,6 @@ load Gem.bin_path('a', 'executable', version) end def test_generate_bin_script_format_disabled - util_setup_install - @installer.wrappers = true util_make_exec @installer.gem_dir = util_gem_dir @@ -298,10 +341,7 @@ load Gem.bin_path('a', 'executable', version) end def test_generate_bin_script_install_dir - util_setup_install - @installer.wrappers = true - @spec.executables = %w[executable] gem_dir = File.join("#{@gemhome}2", "gems", @spec.full_name) gem_bindir = File.join gem_dir, 'bin' @@ -312,11 +352,12 @@ load Gem.bin_path('a', 'executable', version) @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_equal true, File.exist?(installed_exec) + assert File.exist? installed_exec assert_equal mask, File.stat(installed_exec).mode unless win_platform? wrapper = File.read installed_exec @@ -324,8 +365,6 @@ load Gem.bin_path('a', 'executable', version) end def test_generate_bin_script_no_execs - util_setup_install - util_execless @installer.wrappers = true @@ -335,8 +374,6 @@ load Gem.bin_path('a', 'executable', version) end def test_generate_bin_script_no_perms - util_setup_install - @installer.wrappers = true util_make_exec @@ -356,8 +393,6 @@ load Gem.bin_path('a', 'executable', version) end def test_generate_bin_script_no_shebang - util_setup_install - @installer.wrappers = true @spec.executables = %w[executable] @@ -381,8 +416,6 @@ load Gem.bin_path('a', 'executable', version) end def test_generate_bin_script_wrappers - util_setup_install - @installer.wrappers = true util_make_exec @installer.gem_dir = util_gem_dir @@ -408,8 +441,6 @@ load Gem.bin_path('a', 'executable', version) end def test_generate_bin_symlink - util_setup_install - return if win_platform? #Windows FS do not support symlinks @installer.wrappers = false @@ -425,8 +456,6 @@ load Gem.bin_path('a', 'executable', version) end def test_generate_bin_symlink_no_execs - util_setup_install - util_execless @installer.wrappers = false @@ -436,8 +465,6 @@ load Gem.bin_path('a', 'executable', version) end def test_generate_bin_symlink_no_perms - util_setup_install - @installer.wrappers = false util_make_exec @installer.gem_dir = util_gem_dir @@ -458,8 +485,6 @@ load Gem.bin_path('a', 'executable', version) end def test_generate_bin_symlink_update_newer - util_setup_install - return if win_platform? #Windows FS do not support symlinks @installer.wrappers = false @@ -480,7 +505,6 @@ load Gem.bin_path('a', 'executable', version) s.require_path = 'lib' end - @spec.version = 3 util_make_exec @installer.gem_dir = util_gem_dir @spec @installer.generate_bin @@ -491,8 +515,6 @@ load Gem.bin_path('a', 'executable', version) end def test_generate_bin_symlink_update_older - util_setup_install - return if win_platform? #Windows FS do not support symlinks @installer.wrappers = false @@ -529,8 +551,6 @@ load Gem.bin_path('a', 'executable', version) end def test_generate_bin_symlink_update_remove_wrapper - util_setup_install - return if win_platform? #Windows FS do not support symlinks @installer.wrappers = true @@ -538,8 +558,9 @@ load Gem.bin_path('a', 'executable', version) @installer.gem_dir = util_gem_dir @installer.generate_bin + installed_exec = File.join util_inst_bindir, 'executable' - assert_equal true, File.exist?(installed_exec) + assert File.exist? installed_exec @spec = Gem::Specification.new do |s| s.files = ['lib/code.rb'] @@ -549,21 +570,21 @@ load Gem.bin_path('a', 'executable', version) s.description = "desc" s.require_path = 'lib' end + util_make_exec + util_installer @spec, @gemhome @installer.wrappers = false - @spec.version = 3 - 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'), + + 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 - util_setup_install - old_win_platform = Gem.win_platform? Gem.win_platform = true @installer.wrappers = false @@ -588,8 +609,6 @@ load Gem.bin_path('a', 'executable', version) end def test_generate_bin_uses_default_shebang - util_setup_install - return if win_platform? #Windows FS do not support symlinks @installer.wrappers = true @@ -784,7 +803,7 @@ load Gem.bin_path('a', 'executable', version) File.open File.join('lib', 'other.rb'), 'w' do |f| f.puts '1' end use_ui ui do FileUtils.rm @gem - Gem::Builder.new(@spec).build + Gem::Package.build @spec end end @installer = Gem::Installer.new @gem @@ -799,27 +818,6 @@ load Gem.bin_path('a', 'executable', version) "code.rb from prior install of same gem shouldn't remain here") end - def test_install_bad_gem - gem = nil - - use_ui @ui do - Dir.chdir @tempdir do Gem::Builder.new(@spec).build end - gem = File.join @tempdir, @spec.file_name - end - - gem_data = File.open gem, 'rb' do |fp| fp.read 1024 end - File.open gem, 'wb' do |fp| fp.write gem_data end - - e = assert_raises Gem::InstallError do - use_ui @ui do - @installer = Gem::Installer.new gem - @installer.install - end - end - - assert_equal "invalid gem format for #{gem}", e.message - end - def test_install_check_dependencies @spec.add_dependency 'b', '> 5' util_setup_gem @@ -833,13 +831,15 @@ load Gem.bin_path('a', 'executable', version) def test_install_check_dependencies_install_dir gemhome2 = "#{@gemhome}2" - @spec.add_dependency 'b' + @spec.add_dependency 'd' - quick_gem 'b', 2 + quick_gem 'd', 2 FileUtils.mv @gemhome, gemhome2 - Gem::Specification.dirs = [gemhome2] # TODO: switch all dirs= to use_paths + # Don't leak any already activated gems into the installer, require + # that it work everything out on it's own. + Gem::Specification.reset util_setup_gem @@ -897,8 +897,6 @@ load Gem.bin_path('a', 'executable', version) FileUtils.rm_f File.join(Gem.dir, 'specifications') use_ui @ui do - Dir.chdir @tempdir do Gem::Builder.new(@spec).build end - @installer.install end @@ -992,7 +990,7 @@ load Gem.bin_path('a', 'executable', version) @spec.post_install_message = 'I am a shiny gem!' use_ui @ui do - path = Gem::Builder.new(@spec).build + path = Gem::Package.build @spec @installer = Gem::Installer.new path @installer.install @@ -1032,7 +1030,7 @@ load Gem.bin_path('a', 'executable', version) end def test_installation_satisfies_dependency_eh - util_setup_install + quick_spec 'a' dep = Gem::Dependency.new 'a', '>= 2' assert @installer.installation_satisfies_dependency?(dep) @@ -1042,8 +1040,6 @@ load Gem.bin_path('a', 'executable', version) end def test_shebang - util_setup_install - util_make_exec @spec, "#!/usr/bin/ruby" shebang = @installer.shebang 'executable' @@ -1052,8 +1048,6 @@ load Gem.bin_path('a', 'executable', version) end def test_shebang_arguments - util_setup_install - util_make_exec @spec, "#!/usr/bin/ruby -ws" shebang = @installer.shebang 'executable' @@ -1062,8 +1056,6 @@ load Gem.bin_path('a', 'executable', version) end def test_shebang_empty - util_setup_install - util_make_exec @spec, '' shebang = @installer.shebang 'executable' @@ -1071,8 +1063,6 @@ load Gem.bin_path('a', 'executable', version) end def test_shebang_env - util_setup_install - util_make_exec @spec, "#!/usr/bin/env ruby" shebang = @installer.shebang 'executable' @@ -1081,8 +1071,6 @@ load Gem.bin_path('a', 'executable', version) end def test_shebang_env_arguments - util_setup_install - util_make_exec @spec, "#!/usr/bin/env ruby -ws" shebang = @installer.shebang 'executable' @@ -1091,8 +1079,6 @@ load Gem.bin_path('a', 'executable', version) end def test_shebang_env_shebang - util_setup_install - util_make_exec @spec, '' @installer.env_shebang = true @@ -1105,8 +1091,6 @@ load Gem.bin_path('a', 'executable', version) end def test_shebang_nested - util_setup_install - util_make_exec @spec, "#!/opt/local/ruby/bin/ruby" shebang = @installer.shebang 'executable' @@ -1115,8 +1099,6 @@ load Gem.bin_path('a', 'executable', version) end def test_shebang_nested_arguments - util_setup_install - util_make_exec @spec, "#!/opt/local/ruby/bin/ruby -ws" shebang = @installer.shebang 'executable' @@ -1125,8 +1107,6 @@ load Gem.bin_path('a', 'executable', version) end def test_shebang_version - util_setup_install - util_make_exec @spec, "#!/usr/bin/ruby18" shebang = @installer.shebang 'executable' @@ -1135,8 +1115,6 @@ load Gem.bin_path('a', 'executable', version) end def test_shebang_version_arguments - util_setup_install - util_make_exec @spec, "#!/usr/bin/ruby18 -ws" shebang = @installer.shebang 'executable' @@ -1145,8 +1123,6 @@ load Gem.bin_path('a', 'executable', version) end def test_shebang_version_env - util_setup_install - util_make_exec @spec, "#!/usr/bin/env ruby18" shebang = @installer.shebang 'executable' @@ -1155,8 +1131,6 @@ load Gem.bin_path('a', 'executable', version) end def test_shebang_version_env_arguments - util_setup_install - util_make_exec @spec, "#!/usr/bin/env ruby18 -ws" shebang = @installer.shebang 'executable' @@ -1164,9 +1138,48 @@ load Gem.bin_path('a', 'executable', version) assert_equal "#!#{Gem.ruby} -ws", shebang end - def test_unpack - util_setup_install + 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 @@ -1178,29 +1191,21 @@ load Gem.bin_path('a', 'executable', version) end def test_write_spec - util_setup_install - - spec_dir = File.join @gemhome, 'specifications' - spec_file = File.join spec_dir, @spec.spec_name - FileUtils.rm spec_file - refute File.exist?(spec_file) + FileUtils.rm @spec.spec_file + refute File.exist?(@spec.spec_file) @installer.spec = @spec @installer.gem_home = @gemhome @installer.write_spec - assert File.exist?(spec_file) - assert_equal @spec, eval(File.read(spec_file)) + assert File.exist?(@spec.spec_file) + assert_equal @spec, eval(File.read(@spec.spec_file)) end def test_write_spec_writes_cached_spec - util_setup_install - - spec_dir = File.join @gemhome, 'specifications' - spec_file = File.join spec_dir, @spec.spec_name - FileUtils.rm spec_file - refute File.exist?(spec_file) + FileUtils.rm @spec.spec_file + refute File.exist?(@spec.spec_file) @spec.files = %w[a.rb b.rb c.rb] @@ -1212,13 +1217,11 @@ load Gem.bin_path('a', 'executable', version) # cached specs have no file manifest: @spec.files = [] - assert_equal @spec, eval(File.read(spec_file)) + assert_equal @spec, eval(File.read(@spec.spec_file)) end def test_dir - util_setup_install - - assert_match %r!/installer/gems/a-2\z!, @installer.dir + assert_match %r!/gemhome/gems/a-2$!, @installer.dir end def old_ruby_required @@ -1238,6 +1241,18 @@ load Gem.bin_path('a', 'executable', version) @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 diff --git a/test/rubygems/test_gem_local_remote_options.rb b/test/rubygems/test_gem_local_remote_options.rb index 0141a3150d..90142efb8f 100644 --- a/test/rubygems/test_gem_local_remote_options.rb +++ b/test/rubygems/test_gem_local_remote_options.rb @@ -40,6 +40,8 @@ class TestGemLocalRemoteOptions < Gem::TestCase end def test_clear_sources_option_idiot_proof + util_setup_fake_fetcher + @cmd.add_local_remote_options @cmd.handle_options %W[--clear-sources] assert_equal Gem.default_sources, Gem.sources @@ -78,10 +80,14 @@ class TestGemLocalRemoteOptions < Gem::TestCase 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}] - assert_equal [original_sources, s1.to_s, s2.to_s, "#{s3}/"].flatten, - Gem.sources + original_sources << s1.to_s + original_sources << s2.to_s + original_sources << "#{s3}/" + + assert_equal original_sources, Gem.sources end def test_update_sources_option diff --git a/test/rubygems/test_gem_name_tuple.rb b/test/rubygems/test_gem_name_tuple.rb new file mode 100644 index 0000000000..62b4801f71 --- /dev/null +++ b/test/rubygems/test_gem_name_tuple.rb @@ -0,0 +1,15 @@ +require 'rubygems/test_case' +require 'rubygems/name_tuple' + +class TestGemNameTuple < Gem::TestCase + 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 +end diff --git a/test/rubygems/test_gem_package.rb b/test/rubygems/test_gem_package.rb new file mode 100644 index 0000000000..a668f180d9 --- /dev/null +++ b/test/rubygems/test_gem_package.rb @@ -0,0 +1,547 @@ +# 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' + 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 + + reader.each_entry do |entry| + case entry.full_name + when 'checksums.yaml.gz' + Zlib::GzipReader.wrap entry do |io| + checksums = io.read + end + 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 + + data_digests = nil + util_tar do |tar| + data_digests = package.add_contents tar + end + + expected = { + 'SHA1' => { + 'metadata.gz' => metadata_sha1, + 'data.tar.gz' => data_digests['SHA1'].hexdigest, + }, + 'SHA512' => { + 'metadata.gz' => metadata_sha512, + 'data.tar.gz' => data_digests['SHA512'].hexdigest, + } + } + + assert_equal expected, YAML.load(checksums) + end + + def test_add_files + spec = Gem::Specification.new + spec.files = 'lib/code.rb' + + FileUtils.mkdir 'lib' + 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'] + + 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 + private_key_path = File.join Gem.user_home, 'gem-private_key.pem' + Gem::Security.write PRIVATE_KEY, private_key_path + + public_cert_path = File.join Gem.user_home, '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 + 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_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_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_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 = OpenSSL::Digest::SHA1.new + digest << metadata_gz + checksum = "#{digest.name}\t#{digest.hexdigest}\n" + + tar.add_file 'metadata.gz.sum', 0444 do |io| + io.write checksum + 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 + Tempfile.open 'corrupt' do |io| + data = Gem.gzip 'a' * 10 + io.write tar_file_header('metadata.gz', "\000x", 0644, data.length) + 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 + end + 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_equal 'No such file or directory - nonexistent.gem', e.message + end + + def test_verify_security_policy + 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 + 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 + + def test_spec + package = Gem::Package.new @gem + + assert_equal @spec, package.spec + 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/test/rubygems/test_gem_package_old.rb b/test/rubygems/test_gem_package_old.rb new file mode 100644 index 0000000000..20d9837a83 --- /dev/null +++ b/test/rubygems/test_gem_package_old.rb @@ -0,0 +1,37 @@ +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' + end + + def test_contents + assert_equal %w[lib/foo.rb lib/test.rb lib/test/wow.rb], @package.contents + 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_spec + assert_equal 'testing', @package.spec.name + end + +end + diff --git a/test/rubygems/test_gem_package_tar_input.rb b/test/rubygems/test_gem_package_tar_input.rb deleted file mode 100644 index ee8e53712c..0000000000 --- a/test/rubygems/test_gem_package_tar_input.rb +++ /dev/null @@ -1,129 +0,0 @@ -require 'rubygems/package/tar_test_case' -require 'rubygems/package/tar_input' - -class TestGemPackageTarInput < Gem::Package::TarTestCase - - # Sometimes the setgid bit doesn't take. Don't know if this is a problem on - # all systems, or just some. But for now, we will ignore it in the tests. - SETGID_BIT = 02000 - - def setup - super - - inner_tar = tar_file_header("bla", "", 0612, 10) - inner_tar += "0123456789" + "\0" * 502 - inner_tar += tar_file_header("foo", "", 0636, 5) - inner_tar += "01234" + "\0" * 507 - inner_tar += tar_dir_header("__dir__", "", 0600) - inner_tar += "\0" * 1024 - str = TempIO.new - - begin - os = Zlib::GzipWriter.new str - os.write inner_tar - ensure - os.finish - end - - str.rewind - - @file = File.join @tempdir, 'bla.tar' - - File.open @file, 'wb' do |f| - f.write tar_file_header("data.tar.gz", "", 0644, str.string.size) - f.write str.string - f.write "\0" * ((512 - (str.string.size % 512)) % 512 ) - - @spec = Gem::Specification.new do |spec| - spec.author = "Mauricio :)" - end - - meta = @spec.to_yaml - - f.write tar_file_header("metadata", "", 0644, meta.size) - f.write meta + "\0" * (1024 - meta.size) - f.write "\0" * 1024 - end - - @entry_names = %w{bla foo __dir__} - @entry_sizes = [10, 5, 0] - #FIXME: are these modes system dependent? - @entry_modes = [0100612, 0100636, 040600] - @entry_files = %W[#{@tempdir}/bla #{@tempdir}/foo] - @entry_contents = %w[0123456789 01234] - end - - def test_initialize_no_metadata_file - Tempfile.open 'no_meta' do |io| - io.write tar_file_header('a', '', 0644, 1) - io.write 'a' - io.rewind - - e = assert_raises Gem::Package::FormatError do - open io.path, Gem.binary_mode do |file| - Gem::Package::TarInput.open file do end - end - end - - assert_equal "no metadata found in #{io.path}", e.message - assert_equal io.path, e.path - end - end - - def test_each - open @file, 'rb' do |io| - Gem::Package::TarInput.open io do |tar_input| - count = 0 - - tar_input.each_with_index do |entry, i| - count = i - - assert_kind_of Gem::Package::TarReader::Entry, entry - assert_equal @entry_names[i], entry.header.name - assert_equal @entry_sizes[i], entry.header.size - end - - assert_equal 2, count - - assert_equal @spec, tar_input.metadata - end - end - end - - def test_extract_entry - open @file, 'rb' do |io| - Gem::Package::TarInput.open io do |tar_input| - assert_equal @spec, tar_input.metadata - - count = 0 - - tar_input.each_with_index do |entry, i| - count = i - tar_input.extract_entry @tempdir, entry - name = File.join @tempdir, entry.header.name - - if entry.directory? then - assert File.directory?(name) - else - assert File.file?(name) - assert_equal @entry_sizes[i], File.stat(name).size - #FIXME: win32? !! - end - - unless Gem.win_platform? then - assert_equal @entry_modes[i], File.stat(name).mode & (~SETGID_BIT) - end - end - - assert_equal 2, count - end - end - - @entry_files.each_with_index do |x, i| - assert File.file?(x) - assert_equal @entry_contents[i], Gem.read_binary(x) - end - end - -end - diff --git a/test/rubygems/test_gem_package_tar_output.rb b/test/rubygems/test_gem_package_tar_output.rb deleted file mode 100644 index ecf25ef107..0000000000 --- a/test/rubygems/test_gem_package_tar_output.rb +++ /dev/null @@ -1,101 +0,0 @@ -require 'rubygems/package/tar_test_case' -require 'rubygems/package/tar_output' -require 'rubygems/security' - -class TestGemPackageTarOutput < Gem::Package::TarTestCase - - def setup - super - - @file = File.join @tempdir, 'bla2.tar' - end - - def test_self_open - open @file, 'wb' do |tar_io| - Gem::Package::TarOutput.open tar_io do |tar_writer| - tar_writer.add_file_simple 'README', 0, 17 do |io| - io.write "This is a README\n" - end - - tar_writer.metadata = "This is some metadata\n" - end - end - - files = util_extract - - name, data = files.shift - assert_equal 'data.tar.gz', name - - gz = Zlib::GzipReader.new StringIO.new(data) - - Gem::Package::TarReader.new gz do |tar_reader| - tar_reader.each do |entry| - assert_equal 'README', entry.full_name - assert_equal "This is a README\n", entry.read - end - end - - gz.close - - name, data = files.shift - assert_equal 'metadata.gz', name - - gz = Zlib::GzipReader.new StringIO.new(data) - assert_equal "This is some metadata\n", gz.read - - assert_empty files - ensure - gz.close if gz - end - - if defined? OpenSSL then - def test_self_open_signed - @private_key = File.expand_path('test/rubygems/private_key.pem', @@project_dir) - @public_cert = File.expand_path('test/rubygems/public_cert.pem', @@project_dir) - - signer = Gem::Security::Signer.new @private_key, [@public_cert] - - open @file, 'wb' do |tar_io| - Gem::Package::TarOutput.open tar_io, signer do |tar_writer| - tar_writer.add_file_simple 'README', 0, 17 do |io| - io.write "This is a README\n" - end - - tar_writer.metadata = "This is some metadata\n" - end - end - - files = util_extract - - name, data = files.shift - assert_equal 'data.tar.gz', name - - name, data = files.shift - assert_equal 'metadata.gz', name - - name, data = files.shift - assert_equal 'data.tar.gz.sig', name - - name, data = files.shift - assert_equal 'metadata.gz.sig', name - - assert_empty files - end - end - - def util_extract - files = [] - - open @file, 'rb' do |io| - Gem::Package::TarReader.new io do |tar_reader| - tar_reader.each do |entry| - files << [entry.full_name, entry.read] - end - end - end - - files - end - -end - diff --git a/test/rubygems/test_gem_package_tar_reader.rb b/test/rubygems/test_gem_package_tar_reader.rb index 34e30441d8..d1af22d3be 100644 --- a/test/rubygems/test_gem_package_tar_reader.rb +++ b/test/rubygems/test_gem_package_tar_reader.rb @@ -42,5 +42,37 @@ class TestGemPackageTarReader < Gem::Package::TarTestCase end end + def test_seek + tar = tar_dir_header "foo", "bar", 0 + tar << tar_file_header("bar", "baz", 0, 0) + + 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 + end + + def test_seek_missing + tar = tar_dir_header "foo", "bar", 0 + tar << tar_file_header("bar", "baz", 0, 0) + + 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 + end + end diff --git a/test/rubygems/test_gem_package_tar_writer.rb b/test/rubygems/test_gem_package_tar_writer.rb index 88779e7079..40c6982929 100644 --- a/test/rubygems/test_gem_package_tar_writer.rb +++ b/test/rubygems/test_gem_package_tar_writer.rb @@ -1,7 +1,7 @@ require 'rubygems/package/tar_test_case' require 'rubygems/package/tar_writer' -class TestTarWriter < Gem::Package::TarTestCase +class TestGemPackageTarWriter < Gem::Package::TarTestCase def setup super @@ -26,6 +26,89 @@ class TestTarWriter < Gem::Package::TarTestCase assert_equal 1024, @io.pos end + def test_add_file_digest + digest_algorithms = OpenSSL::Digest::SHA1, OpenSSL::Digest::SHA512 + + 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), + @io.string[0, 512]) + assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512] + assert_equal 1024, @io.pos + end + + def test_add_file_digest_multiple + digest_algorithms = [OpenSSL::Digest::SHA1, OpenSSL::Digest::SHA512] + + 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), + @io.string[0, 512]) + assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512] + assert_equal 1024, @io.pos + end + + def test_add_file_signer + signer = Gem::Security::Signer.new PRIVATE_KEY, [PUBLIC_CERT] + + @tar_writer.add_file_signed 'x', 0644, signer do |io| + io.write 'a' * 10 + end + + assert_headers_equal(tar_file_header('x', '', 0644, 10), + @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), + @io.string[1024, 512]) + assert_equal "#{signature}#{"\0" * (512 - signature.length)}", + @io.string[1536, 512] + + assert_equal 2048, @io.pos + end + + def test_add_file_signer_empty + signer = Gem::Security::Signer.new nil, nil + + @tar_writer.add_file_signed 'x', 0644, signer do |io| + io.write 'a' * 10 + end + + assert_headers_equal(tar_file_header('x', '', 0644, 10), + @io.string[0, 512]) + assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512] + + digest = signer.digest_algorithm.new + digest.update 'a' * 10 + + assert_equal 1024, @io.pos + end + def test_add_file_simple @tar_writer.add_file_simple 'x', 0644, 10 do |io| io.write "a" * 10 end diff --git a/test/rubygems/test_gem_path_support.rb b/test/rubygems/test_gem_path_support.rb index 830173498f..bffc66f7dc 100644 --- a/test/rubygems/test_gem_path_support.rb +++ b/test/rubygems/test_gem_path_support.rb @@ -22,10 +22,10 @@ class TestGemPathSupport < Gem::TestCase def test_initialize_home ps = Gem::PathSupport.new "GEM_HOME" => "#{@tempdir}/foo" - expected = File.join(@tempdir, "foo") - assert_equal expected, ps.home + assert_equal File.join(@tempdir, "foo"), ps.home - assert_equal [expected, *util_path], ps.path + expected = util_path + [File.join(@tempdir, 'foo')] + assert_equal expected, ps.path end if defined?(File::ALT_SEPARATOR) and File::ALT_SEPARATOR @@ -43,9 +43,9 @@ class TestGemPathSupport < Gem::TestCase assert_equal ENV["GEM_HOME"], ps.home expected = [ - ENV["GEM_HOME"], File.join(@tempdir, 'foo'), File.join(@tempdir, 'bar'), + ENV["GEM_HOME"], ] assert_equal expected, ps.path @@ -61,32 +61,6 @@ class TestGemPathSupport < Gem::TestCase assert_equal expected, ps.path end - def test_path_equals - ps = Gem::PathSupport.new - - ps.send :path=, ['a', 'b'] - - assert_equal [@tempdir, 'a', 'b'], ps.path - end - - def test_path_equals_empty - ps = Gem::PathSupport.new - - ps.send :path=, nil - - assert_equal [@tempdir, 'something'], ps.path - end - - def test_path_equals_empty_no_GEM_PATH - ENV.delete 'GEM_PATH' - - ps = Gem::PathSupport.new - - ps.send :path=, nil - - assert_equal [@tempdir, *Gem.default_path], ps.path - end - def util_path ENV["GEM_PATH"].split(File::PATH_SEPARATOR) end diff --git a/test/rubygems/test_gem_platform.rb b/test/rubygems/test_gem_platform.rb index b6ddc0eca4..1112a013f5 100644 --- a/test/rubygems/test_gem_platform.rb +++ b/test/rubygems/test_gem_platform.rb @@ -51,6 +51,8 @@ class TestGemPlatform < Gem::TestCase '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'], @@ -67,8 +69,7 @@ class TestGemPlatform < Gem::TestCase 'x86-mswin32' => ['x86', 'mswin32', nil], 'x86-mswin32_60' => ['x86', 'mswin32', '60'], 'x86-mswin32-60' => ['x86', 'mswin32', '60'], - 'i386-netbsdelf5.1.' => ['x86', 'netbsdelf', '5'], - 'x86_64-netbsd6.99.7' => ['x86_64', 'netbsd', '6'], + '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'], @@ -76,6 +77,7 @@ class TestGemPlatform < Gem::TestCase '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| @@ -137,12 +139,6 @@ class TestGemPlatform < Gem::TestCase assert_equal '1', platform.version end - def test_empty - platform = Gem::Platform.new 'cpu-other_platform1' - assert_respond_to platform, :empty? - assert_equal false, Gem::Deprecate.skip_during { platform.empty? } - end - def test_to_s if win_platform? then assert_equal 'x86-mswin32-60', Gem::Platform.local.to_s diff --git a/test/rubygems/test_gem_rdoc.rb b/test/rubygems/test_gem_rdoc.rb new file mode 100644 index 0000000000..f75d15b117 --- /dev/null +++ b/test/rubygems/test_gem_rdoc.rb @@ -0,0 +1,245 @@ +require 'rubygems/test_case' +require 'rubygems' +require 'rubygems/rdoc' + +class TestGemRDoc < Gem::TestCase + + def setup + super + + @a = quick_spec 'a' + + @rdoc = 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_3? + Gem::Requirement.new('~> 3.0').satisfied_by? @rdoc.class.rdoc_version + end + + def rdoc_3_8_or_better? + Gem::Requirement.new('>= 3.8').satisfied_by? @rdoc.class.rdoc_version + end + + def test_initialize + assert @rdoc.generate_rdoc + assert @rdoc.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 + ] + + @rdoc.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.instance_variable_set :@rdoc, @rdoc.new_rdoc + @rdoc.instance_variable_set :@file_info, [] + + @rdoc.document 'darkfish', options, @a.doc_dir('rdoc') + + assert @rdoc.rdoc_installed? + end + + 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') + + @rdoc.generate + + assert @rdoc.rdoc_installed? + assert @rdoc.ri_installed? + + rdoc = @rdoc.instance_variable_get :@rdoc + + refute rdoc.options.hyperlink_all + end + + 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') + + @rdoc.generate + + rdoc = @rdoc.instance_variable_get :@rdoc + + assert rdoc.options.hyperlink_all + end + + 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') + + @rdoc.generate + + rdoc = @rdoc.instance_variable_get :@rdoc + + assert rdoc.options.hyperlink_all + end + + def test_generate_disabled + @rdoc.generate_rdoc = false + @rdoc.generate_ri = false + + @rdoc.generate + + refute @rdoc.rdoc_installed? + refute @rdoc.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') + + @rdoc.force = true + + @rdoc.generate + + assert_path_exists File.join(@a.doc_dir('rdoc'), 'index.html') + assert_path_exists File.join(@a.doc_dir('ri'), 'cache.ri') + end + + 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') + + @rdoc.generate + + refute_path_exists File.join(@a.doc_dir('rdoc'), 'index.html') + refute_path_exists File.join(@a.doc_dir('ri'), 'cache.ri') + end + + 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') + + @rdoc.generate_legacy + + assert @rdoc.rdoc_installed? + assert @rdoc.ri_installed? + end + + 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') + + @rdoc.legacy_rdoc '--op', @a.doc_dir('rdoc') + + assert @rdoc.rdoc_installed? + end + + def test_new_rdoc + assert_kind_of RDoc::RDoc, @rdoc.new_rdoc + end + + def test_rdoc_installed? + refute @rdoc.rdoc_installed? + + FileUtils.mkdir_p @a.doc_dir 'rdoc' + + assert @rdoc.rdoc_installed? + end + + def test_remove + FileUtils.mkdir_p @a.doc_dir 'rdoc' + FileUtils.mkdir_p @a.doc_dir 'ri' + + @rdoc.remove + + refute @rdoc.rdoc_installed? + refute @rdoc.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 + @rdoc.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 @rdoc.ri_installed? + + FileUtils.mkdir_p @a.doc_dir 'ri' + + assert @rdoc.ri_installed? + end + + def test_setup + @rdoc.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 + @rdoc.setup + end + + assert_equal @a.doc_dir, e.directory + ensure + FileUtils.chmod(0755, @a.doc_dir) if File.directory?(@a.doc_dir) + end + +end diff --git a/test/rubygems/test_gem_remote_fetcher.rb b/test/rubygems/test_gem_remote_fetcher.rb index 495c28727c..c0ee23ff5a 100644 --- a/test/rubygems/test_gem_remote_fetcher.rb +++ b/test/rubygems/test_gem_remote_fetcher.rb @@ -1,12 +1,10 @@ require 'rubygems/test_case' require 'ostruct' require 'webrick' -begin - require 'webrick/https' -rescue LoadError -end +require 'webrick/https' require 'rubygems/remote_fetcher' -require 'rubygems/format' +require 'rubygems/package' +require 'minitest/mock' # = Testing Proxy Settings # @@ -90,6 +88,8 @@ gems: ENV.delete 'HTTP_PROXY_USER' ENV.delete 'http_proxy_pass' ENV.delete 'HTTP_PROXY_PASS' + ENV.delete 'no_proxy' + ENV.delete 'NO_PROXY' base_server_uri = "http://localhost:#{SERVER_PORT}" @proxy_uri = "http://localhost:#{PROXY_PORT}" @@ -104,6 +104,7 @@ gems: # 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 @@ -176,6 +177,21 @@ gems: end end + def test_api_endpoint + uri = URI.parse "http://gems.example.com/foo" + target = MiniTest::Mock.new + target.expect :target, "http://blah.com" + + dns = MiniTest::Mock.new + dns.expect :getresource, target, [String, Object] + + fetch = Gem::RemoteFetcher.new nil, dns + assert_equal URI.parse("http://blah.com/foo"), fetch.api_endpoint(uri) + + target.verify + dns.verify + end + def util_fuck_with_fetcher data, blow = false fetcher = Gem::RemoteFetcher.fetcher fetcher.instance_variable_set :@test_data, data @@ -281,8 +297,8 @@ gems: inst = Gem::RemoteFetcher.fetcher end - assert_equal File.join(@tempdir, @a1.file_name), - inst.download(@a1, local_path) + assert_equal(File.join(@tempdir, @a1.file_name), + inst.download(@a1, local_path)) ensure FileUtils.chmod 0755, @a1.cache_dir end @@ -308,6 +324,7 @@ gems: 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| @@ -337,7 +354,7 @@ gems: cache_path = @a1.cache_file FileUtils.mv local_path, cache_path - gem = Gem::Format.from_file_by_path cache_path + gem = Gem::Package.new cache_path assert_equal cache_path, inst.download(gem.spec, cache_path) end @@ -345,7 +362,7 @@ gems: def test_download_unsupported inst = Gem::RemoteFetcher.fetcher - e = assert_raises Gem::InstallError do + e = assert_raises ArgumentError do inst.download @a1, 'ftp://gems.rubyforge.org' end @@ -627,6 +644,32 @@ gems: assert_equal "too many redirects (#{url})", e.message end + def test_normalize_uri + assert_equal 'FILE://example/', @fetcher.normalize_uri('FILE://example/') + assert_equal 'FTP://example/', @fetcher.normalize_uri('FTP://example/') + assert_equal 'HTTP://example/', @fetcher.normalize_uri('HTTP://example/') + assert_equal 'HTTPS://example/', @fetcher.normalize_uri('HTTPS://example/') + assert_equal 'http://example/', @fetcher.normalize_uri('example/') + 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 + 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 + assert_data_from_server fetcher.fetch_path(@server_uri) + end + end + def test_request uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}" util_stub_connection_for :body => :junk, :code => 200 @@ -752,7 +795,7 @@ gems: with_configured_fetcher(":ssl_ca_cert: #{temp_ca_cert}") do |fetcher| fetcher.fetch_path("https://localhost:#{ssl_server.config[:Port]}/yaml") end - end if defined?(OpenSSL::PKey) + end def test_do_not_allow_insecure_ssl_connection_by_default ssl_server = self.class.start_ssl_server @@ -761,14 +804,14 @@ gems: fetcher.fetch_path("https://localhost:#{ssl_server.config[:Port]}/yaml") end end - end if defined?(OpenSSL::PKey) + 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 if defined?(OpenSSL::PKey) + end def test_do_not_follow_insecure_redirect ssl_server = self.class.start_ssl_server @@ -778,7 +821,7 @@ gems: fetcher.fetch_path("https://localhost:#{ssl_server.config[:Port]}/insecure_redirect?to=#{@server_uri}") end end - end if defined?(OpenSSL::PKey) + end def with_configured_fetcher(config_str = nil, &block) if config_str @@ -856,7 +899,7 @@ gems: end DIR = File.expand_path(File.dirname(__FILE__)) - DH_PARAM = defined?(OpenSSL::PKey) ? OpenSSL::PKey::DH.new(128) : nil + DH_PARAM = OpenSSL::PKey::DH.new(128) def start_ssl_server(config = {}) null_logger = NilLog.new @@ -894,7 +937,7 @@ gems: end end server - end if DH_PARAM + end diff --git a/test/rubygems/test_gem_request_set.rb b/test/rubygems/test_gem_request_set.rb new file mode 100644 index 0000000000..df26784b2f --- /dev/null +++ b/test/rubygems/test_gem_request_set.rb @@ -0,0 +1,70 @@ +require 'rubygems/test_case' +require 'rubygems/request_set' + +class TestGemRequestSet < Gem::TestCase + def setup + super + + Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new + 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_resolve + a = util_spec "a", "2", "b" => ">= 2" + b = util_spec "b", "2" + + rs = Gem::RequestSet.new + rs.gem "a" + + 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 + 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_into + a, ad = util_gem "a", "1", "b" => "= 1" + b, bd = util_gem "b", "1" + + util_setup_spec_fetcher a, b + + @fetcher.data["http://gems.example.com/gems/#{a.file_name}"] = Gem.read_binary(ad) + @fetcher.data["http://gems.example.com/gems/#{b.file_name}"] = Gem.read_binary(bd) + + rs = Gem::RequestSet.new + rs.gem "a" + + rs.resolve + + installed = rs.install_into @tempdir + + assert File.exists?(File.join(@tempdir, "specifications", "a-1.gemspec")) + assert File.exists?(File.join(@tempdir, "specifications", "b-1.gemspec")) + + assert_equal %w!b-1 a-1!, installed.map { |s| s.full_name } + end +end diff --git a/test/rubygems/test_gem_requirement.rb b/test/rubygems/test_gem_requirement.rb index 0bc6ad7059..1de0f41f20 100644 --- a/test/rubygems/test_gem_requirement.rb +++ b/test/rubygems/test_gem_requirement.rb @@ -21,9 +21,19 @@ class TestGemRequirement < Gem::TestCase assert_requirement_equal "= 2", v(2) end - def test_class_available_as_gem_version_requirement - assert_same Gem::Requirement, Gem::Version::Requirement, - "Gem::Version::Requirement is aliased for old YAML compatibility." + 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_parse @@ -37,17 +47,19 @@ class TestGemRequirement < Gem::TestCase end def test_parse_bad - e = assert_raises ArgumentError do + e = assert_raises Gem::Requirement::BadRequirementError do Gem::Requirement.parse nil end assert_equal 'Illformed requirement [nil]', e.message - e = assert_raises ArgumentError do + e = assert_raises Gem::Requirement::BadRequirementError do Gem::Requirement.parse "" end assert_equal 'Illformed requirement [""]', e.message + + assert_equal Gem::Requirement::BadRequirementError.superclass, ArgumentError end def test_prerelease_eh @@ -67,28 +79,37 @@ class TestGemRequirement < Gem::TestCase def test_satisfied_by_eh_bang_equal r = req '!= 1.2' - assert_satisfied_by nil, r 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 nil, r 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 nil, r 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 @@ -98,7 +119,7 @@ class TestGemRequirement < Gem::TestCase refute_satisfied_by "1.2", r assert_satisfied_by "1.3", r - assert_raises NoMethodError do + assert_raises ArgumentError do r.satisfied_by? nil end end @@ -110,7 +131,7 @@ class TestGemRequirement < Gem::TestCase assert_satisfied_by "1.2", r assert_satisfied_by "1.3", r - assert_raises NoMethodError do + assert_raises ArgumentError do r.satisfied_by? nil end end @@ -122,7 +143,7 @@ class TestGemRequirement < Gem::TestCase assert_satisfied_by "1.2", r refute_satisfied_by "1.3", r - assert_raises NoMethodError do + assert_raises ArgumentError do r.satisfied_by? nil end end @@ -134,7 +155,7 @@ class TestGemRequirement < Gem::TestCase refute_satisfied_by "1.2", r refute_satisfied_by "1.3", r - assert_raises NoMethodError do + assert_raises ArgumentError do r.satisfied_by? nil end end @@ -146,7 +167,7 @@ class TestGemRequirement < Gem::TestCase assert_satisfied_by "1.2", r refute_satisfied_by "1.3", r - assert_raises NoMethodError do + assert_raises ArgumentError do r.satisfied_by? nil end end @@ -158,7 +179,7 @@ class TestGemRequirement < Gem::TestCase assert_satisfied_by "1.2", r assert_satisfied_by "1.3", r - assert_raises NoMethodError do + assert_raises ArgumentError do r.satisfied_by? nil end end @@ -200,12 +221,22 @@ class TestGemRequirement < Gem::TestCase def test_illformed_requirements [ ">>> 1.3.5", "> blah" ].each do |rq| - assert_raises ArgumentError, "req [#{rq}] should fail" do + 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" diff --git a/test/rubygems/test_gem_security.rb b/test/rubygems/test_gem_security.rb index 625da8ae6d..7e75548c0f 100644 --- a/test/rubygems/test_gem_security.rb +++ b/test/rubygems/test_gem_security.rb @@ -4,33 +4,35 @@ require 'rubygems/fix_openssl_warnings' if RUBY_VERSION < "1.9" 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 - Gem::Security::OPT[:trust_dir] = File.join(Gem.user_home, '.gem', 'trust') - end - def teardown - super - Gem::Security::OPT[:trust_dir] = File.join(Gem.user_home, '.gem', 'trust') + @SEC = Gem::Security end - def test_class_build_cert - name = OpenSSL::X509::Name.parse "CN=nobody/DC=example" - key = OpenSSL::PKey::RSA.new 512 - opt = { :cert_age => 60 } + def test_class_create_cert + name = PUBLIC_CERT.subject + key = PRIVATE_KEY - cert = Gem::Security.build_cert name, key, opt + 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 0, cert.serial + 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 + 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 @@ -41,60 +43,204 @@ class TestGemSecurity < Gem::TestCase key_ident = cert.extensions.find { |ext| ext.oid == 'subjectKeyIdentifier' } assert_equal 59, key_ident.value.length + assert_equal 'B0:EB:9C:A5:E5:8E:7D:94:BB:4B:3B:D6:80:CB:A5:AD:5D:12:88:90', + key_ident.value - assert_equal name.to_s, cert.issuer.to_s + assert_equal '', cert.issuer.to_s assert_equal name.to_s, cert.subject.to_s end - def test_class_build_self_signed_cert + 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' - opt = { - :cert_age => 60, - :key_size => 512, - :save_cert => false, - :save_key => false, - } + name = PUBLIC_CERT.subject + key = PRIVATE_KEY - result = Gem::Security.build_self_signed_cert email, opt + cert = @SEC.create_cert_email email, key, 60 - key = result[:key] + assert_kind_of OpenSSL::X509::Certificate, cert - assert_kind_of OpenSSL::PKey::RSA, key - # assert_equal 512, key.something_here + 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 - cert = result[:cert] + assert_equal 5, cert.extensions.length, + cert.extensions.map { |e| e.to_a.first } - assert_equal '/CN=nobody/DC=example', cert.issuer.to_s - end + constraints = cert.extensions.find { |ext| ext.oid == 'subjectAltName' } + assert_equal 'email:nobody@example', constraints.value - def test_class_sign_cert - name = OpenSSL::X509::Name.parse "CN=nobody/DC=example" - key = OpenSSL::PKey::RSA.new 512 - cert = OpenSSL::X509::Certificate.new + constraints = cert.extensions.find { |ext| ext.oid == 'basicConstraints' } + assert_equal 'CA:FALSE', constraints.value - cert.subject = name - cert.public_key = key.public_key + key_usage = cert.extensions.find { |ext| ext.oid == 'keyUsage' } + assert_equal 'Digital Signature, Key Encipherment, Data Encipherment', + key_usage.value - signed = Gem::Security.sign_cert cert, key, cert + key_ident = cert.extensions.find { |ext| ext.oid == 'subjectKeyIdentifier' } + assert_equal 59, key_ident.value.length + assert_equal 'B0:EB:9C:A5:E5:8E:7D:94:BB:4B:3B:D6:80:CB:A5:AD:5D:12:88:90', + key_ident.value + end - assert cert.verify key - assert_equal name.to_s, signed.subject.to_s + def test_class_create_key + key = @SEC.create_key 256 + + assert_kind_of OpenSSL::PKey::RSA, key end def test_class_email_to_name - munger = Gem::Security::OPT[:munge_re] - assert_equal '/CN=nobody/DC=example', - Gem::Security.email_to_name('nobody@example', munger).to_s + @SEC.email_to_name('nobody@example').to_s assert_equal '/CN=nobody/DC=example/DC=com', - Gem::Security.email_to_name('nobody@example.com', munger).to_s + @SEC.email_to_name('nobody@example.com').to_s assert_equal '/CN=no.body/DC=example', - Gem::Security.email_to_name('no.body@example', munger).to_s + @SEC.email_to_name('no.body@example').to_s assert_equal '/CN=no_body/DC=example', - Gem::Security.email_to_name('no+body@example', munger).to_s + @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 2, 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 + + assert_equal "#{ALTERNATE_CERT.subject} 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 'B0:EB:9C:A5:E5:8E:7D:94:BB:4B:3B:D6:80:CB:A5:AD:5D:12:88:90', + key_ident.value + + assert signed.verify key end -end if defined?(OpenSSL) + 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 'B0:EB:9C:A5:E5:8E:7D:94:BB:4B:3B:D6:80:CB:A5:AD:5D:12:88:90', + 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 + +end + diff --git a/test/rubygems/test_gem_security_policy.rb b/test/rubygems/test_gem_security_policy.rb new file mode 100644 index 0000000000..4b9978c430 --- /dev/null +++ b/test/rubygems/test_gem_security_policy.rb @@ -0,0 +1,376 @@ +# coding: UTF-8 + +require 'rubygems/test_case' + +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' + 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 + + @almost_no = Gem::Security::AlmostNoSecurity + @low = Gem::Security::LowSecurity + @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_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_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_key + assert @almost_no.check_key(PUBLIC_CERT, PRIVATE_KEY) + 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_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_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_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_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_verify + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + assert @almost_no.verify [PUBLIC_CERT] + end + + def test_verify_chain_signatures + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + data = digest 'hello' + digest = { 'SHA1' => { 0 => data } } + signature = { 0 => sign(data, PRIVATE_KEY) } + + assert @high.verify [PUBLIC_CERT], nil, digest, signature + end + + def test_verify_chain_key + assert @almost_no.verify [PUBLIC_CERT], PRIVATE_KEY + end + + def test_verify_signatures_chain + data = digest 'hello' + digest = { 'SHA1' => { 0 => data } } + signature = { 0 => sign(data, CHILD_KEY) } + + @spec.cert_chain = [PUBLIC_CERT, CHILD_CERT] + + assert @chain.verify_signatures @spec, digest, signature + end + + def test_verify_signatures_data + data = digest 'hello' + digest = { 'SHA1' => { 0 => data } } + signature = { 0 => sign(data) } + + @spec.cert_chain = [PUBLIC_CERT] + + @almost_no.verify_signatures @spec, digest, signature + end + + def test_verify_signatures_root + data = digest 'hello' + digest = { 'SHA1' => { 0 => data } } + signature = { 0 => sign(data, CHILD_KEY) } + + @spec.cert_chain = [PUBLIC_CERT, CHILD_CERT] + + assert @root.verify_signatures @spec, digest, signature + end + + def test_verify_signatures_signer + data = digest 'hello' + digest = { 'SHA1' => { 0 => data } } + signature = { 0 => sign(data) } + + @spec.cert_chain = [PUBLIC_CERT] + + assert @low.verify_signatures @spec, digest, signature + end + + def test_verify_signatures_trust + Gem::Security.trust_dir.trust_cert PUBLIC_CERT + + data = digest 'hello' + digest = { 'SHA1' => { 0 => data } } + signature = { 0 => sign(data, PRIVATE_KEY) } + + @spec.cert_chain = [PUBLIC_CERT] + + assert @high.verify_signatures @spec, digest, signature + 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 + @almost_no.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 + +end + diff --git a/test/rubygems/test_gem_security_signer.rb b/test/rubygems/test_gem_security_signer.rb new file mode 100644 index 0000000000..cf9ea2196d --- /dev/null +++ b/test/rubygems/test_gem_security_signer.rb @@ -0,0 +1,189 @@ +require 'rubygems/test_case' + +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 = + if 32 == (Time.at(2**32) rescue 32) then + File.expand_path 'test/rubygems/public_cert_32.pem', @current_dir + else + File.expand_path 'test/rubygems/public_cert.pem', @current_dir + end + 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 + private_key_path = File.join Gem.user_home, 'gem-private_key.pem' + Gem::Security.write PRIVATE_KEY, private_key_path + + public_cert_path = File.join Gem.user_home, '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 = File.expand_path 'test/rubygems/private_key.pem', @current_dir + + signer = Gem::Security::Signer.new key_file, nil + + assert_equal PRIVATE_KEY.to_s, signer.key.to_s + 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 +oZXzQRdq0mJpAghICQvjvlB7ZyZtE4diL5jce0Fa20PkLjOvDgpuZCs6Ppu5 +LtG89EQMMBHsAyc8NMCd4oWm6Q== + 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 Gem.user_home, :mode => 0700 + + 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] + + 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-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 Gem.user_home, :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 + diff --git a/test/rubygems/test_gem_security_trust_dir.rb b/test/rubygems/test_gem_security_trust_dir.rb new file mode 100644 index 0000000000..56c2feb44c --- /dev/null +++ b/test/rubygems/test_gem_security_trust_dir.rb @@ -0,0 +1,94 @@ +require 'rubygems/test_case' + +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 + diff --git a/test/rubygems/test_gem_server.rb b/test/rubygems/test_gem_server.rb index f11840db06..1c94144913 100644 --- a/test/rubygems/test_gem_server.rb +++ b/test/rubygems/test_gem_server.rb @@ -18,55 +18,50 @@ class TestGemServer < Gem::TestCase @res = WEBrick::HTTPResponse.new :HTTPVersion => '1.0' end - def test_spec_dirs - s = Gem::Server.new Gem.dir, process_based_port, false + 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 [File.join(Gem.dir, 'specifications')], s.spec_dirs - - s = Gem::Server.new [Gem.dir, Gem.dir], process_based_port, false + assert_equal '/doc_root/X-1/rdoc/index.html', @server.doc_root('X-1') - assert_equal [File.join(Gem.dir, 'specifications'), - File.join(Gem.dir, 'specifications')], s.spec_dirs + ensure + Gem::RDoc.instance_variable_set :@rdoc_version, orig_rdoc_version end - def test_Marshal - data = StringIO.new "GET /Marshal.#{Gem.marshal_version} HTTP/1.0\r\n\r\n" - @req.parse data + def test_doc_root_4 + orig_rdoc_version = Gem::RDoc.rdoc_version + Gem::RDoc.instance_variable_set :@rdoc_version, Gem::Version.new('4.0') - Gem::Deprecate.skip_during do - @server.Marshal @req, @res - end + assert_equal '/doc_root/X-1/', @server.doc_root('X-1') - 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'] + ensure + Gem::RDoc.instance_variable_set :@rdoc_version, orig_rdoc_version + end - Gem::Deprecate.skip_during do - si = Gem::SourceIndex.new - si.add_specs @a1, @a2 + 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') - assert_equal si, Marshal.load(@res.body) - end - end + server = Gem::Server.new Gem.dir, 0, false + assert server.have_rdoc_4_plus? - def test_Marshal_Z - data = StringIO.new "GET /Marshal.#{Gem.marshal_version}.Z HTTP/1.0\r\n\r\n" - @req.parse data + Gem::RDoc.instance_variable_set :@rdoc_version, Gem::Version.new('3.12') - Gem::Deprecate.skip_during do - @server.Marshal @req, @res - end + server = Gem::Server.new Gem.dir, 0, false + refute server.have_rdoc_4_plus? + ensure + Gem::RDoc.instance_variable_set :@rdoc_version, orig_rdoc_version + end - assert_equal 200, @res.status, @res.body - assert_match %r| \d\d:\d\d:\d\d |, @res['date'] - assert_equal 'application/x-deflate', @res['content-type'] + def test_spec_dirs + s = Gem::Server.new Gem.dir, process_based_port, false - Gem::Deprecate.skip_during do - si = Gem::SourceIndex.new - si.add_specs @a1, @a2 + assert_equal [File.join(Gem.dir, 'specifications')], s.spec_dirs - assert_equal si, Marshal.load(Gem.inflate(@res.body)) - end + 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 diff --git a/test/rubygems/test_gem_source.rb b/test/rubygems/test_gem_source.rb new file mode 100644 index 0000000000..2629f180a9 --- /dev/null +++ b/test/rubygems/test_gem_source.rb @@ -0,0 +1,188 @@ +require 'rubygems/test_case' +require 'rubygems/source' + +class TestGemSource < Gem::TestCase + + def tuple(*args) + Gem::NameTuple.new(*args) + end + + def setup + super + + util_setup_fake_fetcher + + @a_pre = new_spec 'a', '1.a' + + install_specs @a_pre + + @source = Gem::Source.new(@gem_repo) + + Gem::Specification.remove_spec @b2 + + all = Gem::Specification.map { |spec| + Gem::NameTuple.new(spec.name, spec.version, spec.original_platform) + }.sort + + @prerelease_specs, @specs = all.partition { |g| g.prerelease? } + + # TODO: couldn't all of this come from the fake spec fetcher? + @latest_specs = Gem::Specification.latest_specs.sort.map { |spec| + Gem::NameTuple.new(spec.name, spec.version, spec.original_platform) + } + + v = Gem.marshal_version + s_zip = util_gzip(Marshal.dump(Gem::NameTuple.to_basic(@specs))) + l_zip = util_gzip(Marshal.dump(Gem::NameTuple.to_basic(@latest_specs))) + p_zip = util_gzip(Marshal.dump(Gem::NameTuple.to_basic(@prerelease_specs))) + @fetcher.data["#{@gem_repo}specs.#{v}.gz"] = s_zip + @fetcher.data["#{@gem_repo}latest_specs.#{v}.gz"] = l_zip + @fetcher.data["#{@gem_repo}prerelease_specs.#{v}.gz"] = p_zip + + @released = Gem::NameTuple.from_list \ + [["a", Gem::Version.new("1"), "ruby"], + ["a", Gem::Version.new("2"), "ruby"], + ["a_evil", Gem::Version.new("9"), "ruby"], + ["c", Gem::Version.new("1.2"), "ruby"], + ['dep_x', Gem::Version.new(1), 'ruby'], + ["pl", Gem::Version.new("1"), "i386-linux"], + ['x', Gem::Version.new(1), 'ruby']] + 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 = File.join Gem.user_home, '.gem', 'specs' + cache_dir = @source.cache_dir(uri).gsub(root, '') + assert cache_dir !~ /:/, "#{cache_dir} should not contain a :" + end + + def test_fetch_spec + spec_uri = "#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}" + @fetcher.data["#{spec_uri}.rz"] = util_zip(Marshal.dump(@a1)) + + 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 + 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 + @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@pl1.original_name}.gemspec.rz"] = + util_zip(Marshal.dump(@pl1)) + + spec = @source.fetch_spec tuple('pl', Gem::Version.new(1), 'i386-linux') + + assert_equal @pl1.full_name, spec.full_name + end + + def test_fetch_spec_platform_ruby + @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}.rz"] = + util_zip(Marshal.dump(@a1)) + + spec = @source.fetch_spec tuple('a', Gem::Version.new(1), nil) + assert_equal @a1.full_name, spec.full_name + + spec = @source.fetch_spec tuple('a', Gem::Version.new(1), '') + assert_equal @a1.full_name, spec.full_name + end + + def test_load_specs + expected = @released + assert_equal expected, @source.load_specs(:released) + + cache_dir = File.join Gem.user_home, '.gem', 'specs', '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 + # 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.user_home, '.gem', 'specs', '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 + + latest_specs = @source.load_specs :latest + + assert_equal @latest_specs, latest_specs + end + + def test_load_specs_cached_empty + # 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.user_home, '.gem', 'specs', '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 + + latest_specs = @source.load_specs :latest + + assert_equal @latest_specs, latest_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 + +end + diff --git a/test/rubygems/test_gem_source_index.rb b/test/rubygems/test_gem_source_index.rb deleted file mode 100644 index b4c225ec6c..0000000000 --- a/test/rubygems/test_gem_source_index.rb +++ /dev/null @@ -1,250 +0,0 @@ -require 'rubygems/test_case' -require 'rubygems/source_index' -require 'rubygems/config_file' -require 'rubygems/deprecate' - -class TestGemSourceIndex < Gem::TestCase - def setup - super - - util_setup_fake_fetcher - - @source_index = Gem::Deprecate.skip_during { Gem.source_index } - end - - def test_find_name - Gem::Deprecate.skip_during do - assert_equal [@a1, @a2, @a3a], @source_index.find_name('a') - assert_equal [@a2], @source_index.find_name('a', '= 2') - assert_equal [], @source_index.find_name('bogusstring') - assert_equal [], @source_index.find_name('a', '= 3') - - source_index = Gem::SourceIndex.new - source_index.add_spec @a1 - source_index.add_spec @a2 - - assert_equal [@a1], source_index.find_name(@a1.name, '= 1') - - r1 = Gem::Requirement.create '= 1' - assert_equal [@a1], source_index.find_name(@a1.name, r1) - end - end - - def test_find_name_empty_cache - Gem::Deprecate.skip_during do - empty_source_index = Gem::SourceIndex.new - assert_equal [], empty_source_index.find_name("foo") - end - end - - # HACK: deprecated impl is failing tests, but I may want to port it over - def test_latest_specs - Gem::Deprecate.skip_during do - p1_ruby = quick_spec 'p', '1' - p1_platform = quick_spec 'p', '1' do |spec| - spec.platform = Gem::Platform::CURRENT - end - - a1_platform = quick_spec @a1.name, (@a1.version) do |s| - s.platform = Gem::Platform.new 'x86-my_platform1' - end - - a2_platform = quick_spec @a2.name, (@a2.version) do |s| - s.platform = Gem::Platform.new 'x86-my_platform1' - end - - a2_platform_other = quick_spec @a2.name, (@a2.version) do |s| - s.platform = Gem::Platform.new 'x86-other_platform1' - end - - a3_platform_other = quick_spec @a2.name, (@a2.version.bump) do |s| - s.platform = Gem::Platform.new 'x86-other_platform1' - end - - @source_index.add_spec p1_ruby - @source_index.add_spec p1_platform - @source_index.add_spec a1_platform - @source_index.add_spec a2_platform - @source_index.add_spec a2_platform_other - @source_index.add_spec a3_platform_other - - expected = [ - @a2.full_name, - a2_platform.full_name, - a3_platform_other.full_name, - @b2.full_name, - @c1_2.full_name, - @a_evil9.full_name, - p1_ruby.full_name, - p1_platform.full_name, - @pl1.full_name - ].sort - - latest_specs = @source_index.latest_specs.map { |s| s.full_name }.sort - - assert_equal expected, latest_specs - end - end - - def test_load_gems_in - Gem::Deprecate.skip_during do - spec_dir1 = File.join @gemhome, 'specifications' - spec_dir2 = File.join @tempdir, 'gemhome2', 'specifications' - - FileUtils.rm_r spec_dir1 - - FileUtils.mkdir_p spec_dir1 - FileUtils.mkdir_p spec_dir2 - - a1 = quick_spec 'a', '1' do |spec| spec.author = 'author 1' end - a2 = quick_spec 'a', '1' do |spec| spec.author = 'author 2' end - - path1 = File.join(spec_dir1, a1.spec_name) - path2 = File.join(spec_dir2, a2.spec_name) - - File.open path1, 'w' do |fp| - fp.write a1.to_ruby - end - - File.open path2, 'w' do |fp| - fp.write a2.to_ruby - end - - @source_index.load_gems_in File.dirname(path1), File.dirname(path2) - - assert_equal a1.author, @source_index.specification(a1.full_name).author - end - end - - # REFACTOR: move to test_gem_commands_outdated_command.rb - def test_outdated - Gem::Deprecate.skip_during do - util_setup_spec_fetcher - - assert_equal [], @source_index.outdated - - updated = quick_spec @a2.name, (@a2.version.bump) - util_setup_spec_fetcher updated - - assert_equal [updated.name], @source_index.outdated - - updated_platform = quick_spec @a2.name, (updated.version.bump) do |s| - s.platform = Gem::Platform.new 'x86-other_platform1' - end - - util_setup_spec_fetcher updated, updated_platform - - assert_equal [updated_platform.name], @source_index.outdated - end - end - - def test_prerelease_specs_kept_in_right_place - Gem::Deprecate.skip_during do - gem_a1_alpha = quick_spec 'abba', '1.a' - @source_index.add_spec gem_a1_alpha - - refute_includes @source_index.latest_specs, gem_a1_alpha - assert_includes @source_index.latest_specs(true), gem_a1_alpha - assert_empty @source_index.find_name gem_a1_alpha.full_name - assert_includes @source_index.prerelease_specs, gem_a1_alpha - end - end - - def test_refresh_bang - Gem::Deprecate.skip_during do - a1_spec = File.join @gemhome, "specifications", @a1.spec_name - - FileUtils.mv a1_spec, @tempdir - - Gem::Specification.reset - Gem.send :class_variable_set, :@@source_index, nil - source_index = Gem.source_index - - refute_includes source_index.gems.keys.sort, @a1.full_name - - FileUtils.mv File.join(@tempdir, @a1.spec_name), a1_spec - - source_index.refresh! - - assert source_index.gems.include?(@a1.full_name) - end - end - - def test_remove_spec - Gem::Deprecate.skip_during do - si = Gem.source_index - - expected = si.gems.keys.sort - - expected.delete "a-1" - @source_index.remove_spec 'a-1' - - assert_equal expected, si.gems.keys.sort - - expected.delete "a-3.a" - @source_index.remove_spec 'a-3.a' - - assert_equal expected, si.gems.keys.sort - end - end - - def test_search - Gem::Deprecate.skip_during do - requirement = Gem::Requirement.create '= 9' - with_version = Gem::Dependency.new(/^a/, requirement) - assert_equal [@a_evil9], @source_index.search(with_version) - - with_default = Gem::Dependency.new(/^a/, Gem::Requirement.default) - assert_equal [@a1, @a2, @a3a, @a_evil9], @source_index.search(with_default) - - c1_1_dep = Gem::Dependency.new 'c', '~> 1.1' - assert_equal [@c1_2], @source_index.search(c1_1_dep) - end - end - - def test_search_platform - Gem::Deprecate.skip_during do - util_set_arch 'x86-my_platform1' - - a1 = quick_spec 'a', '1' - a1_mine = quick_spec 'a', '1' do |s| - s.platform = Gem::Platform.new 'x86-my_platform1' - end - a1_other = quick_spec 'a', '1' do |s| - s.platform = Gem::Platform.new 'x86-other_platform1' - end - - si = Gem::SourceIndex.new - si.add_specs a1, a1_mine, a1_other - - dep = Gem::Dependency.new 'a', Gem::Requirement.new('1') - - gems = si.search dep, true - - assert_equal [a1, a1_mine], gems.sort - end - end - - def test_signature - Gem::Deprecate.skip_during do - sig = @source_index.gem_signature('foo-1.2.3') - assert_equal 64, sig.length - assert_match(/^[a-f0-9]{64}$/, sig) - end - end - - def test_specification - Gem::Deprecate.skip_during do - assert_equal @a1, @source_index.specification(@a1.full_name) - - assert_nil @source_index.specification("foo-1.2.4") - end - end - - def test_index_signature - Gem::Deprecate.skip_during do - sig = @source_index.index_signature - assert_match(/^[a-f0-9]{64}$/, sig) - end - end -end diff --git a/test/rubygems/test_gem_source_list.rb b/test/rubygems/test_gem_source_list.rb new file mode 100644 index 0000000000..d6e253833e --- /dev/null +++ b/test/rubygems/test_gem_source_list.rb @@ -0,0 +1,87 @@ +require 'rubygems/source_list' +require 'rubygems/test_case' + +class TestGemSourceList < Gem::TestCase + def setup + super + + @uri = "http://blah.com" + @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_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_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_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/test/rubygems/test_gem_source_local.rb b/test/rubygems/test_gem_source_local.rb new file mode 100644 index 0000000000..54ce3d51be --- /dev/null +++ b/test/rubygems/test_gem_source_local.rb @@ -0,0 +1,83 @@ +require 'rubygems/test_case' +require 'rubygems/source_local' + +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_download + path = @sl.download @a + + assert_equal File.expand_path(@a.file_name), path + end + + def test_compare + uri = URI.parse "http://gems.example/foo" + s = Gem::Source.new uri + + assert_equal(-1, (@sl <=> s)) + assert_equal 1, (s <=> @sl) + assert_equal 0, (@sl <=> @sl) + end +end diff --git a/test/rubygems/test_gem_source_specific_file.rb b/test/rubygems/test_gem_source_specific_file.rb new file mode 100644 index 0000000000..7ffcf482dc --- /dev/null +++ b/test/rubygems/test_gem_source_specific_file.rb @@ -0,0 +1,33 @@ +require 'rubygems/test_case' +require 'rubygems/source_specific_file' + +class TestGemSourceSpecificFile < Gem::TestCase + def setup + super + + @a, @a_gem = util_gem "a", '1' + @sf = Gem::Source::SpecificFile.new(@a_gem) + 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 +end diff --git a/test/rubygems/test_gem_spec_fetcher.rb b/test/rubygems/test_gem_spec_fetcher.rb index 015d2eec7d..a64a2c60cd 100644 --- a/test/rubygems/test_gem_spec_fetcher.rb +++ b/test/rubygems/test_gem_spec_fetcher.rb @@ -3,10 +3,15 @@ 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) util_setup_fake_fetcher @@ -16,108 +21,114 @@ class TestGemSpecFetcher < Gem::TestCase Gem::Specification.remove_spec @b2 - @specs = Gem::Specification.map { |spec| - [spec.name, spec.version, spec.original_platform] + all = Gem::Specification.map { |spec| + Gem::NameTuple.new(spec.name, spec.version, spec.original_platform) }.sort + @prerelease_specs, @specs = all.partition { |g| g.prerelease? } + # TODO: couldn't all of this come from the fake spec fetcher? @latest_specs = Gem::Specification.latest_specs.sort.map { |spec| - [spec.name, spec.version, spec.original_platform] + Gem::NameTuple.new(spec.name, spec.version, spec.original_platform) } - prerelease = Gem::Specification.find_all { |s| s.version.prerelease? } - @prerelease_specs = prerelease.map { |spec| - [spec.name, spec.version, spec.original_platform] - }.sort - v = Gem.marshal_version - s_zip = util_gzip(Marshal.dump(@specs)) - l_zip = util_gzip(Marshal.dump(@latest_specs)) - p_zip = util_gzip(Marshal.dump(@prerelease_specs)) + s_zip = util_gzip(Marshal.dump(Gem::NameTuple.to_basic(@specs))) + l_zip = util_gzip(Marshal.dump(Gem::NameTuple.to_basic(@latest_specs))) + p_zip = util_gzip(Marshal.dump(Gem::NameTuple.to_basic(@prerelease_specs))) @fetcher.data["#{@gem_repo}specs.#{v}.gz"] = s_zip @fetcher.data["#{@gem_repo}latest_specs.#{v}.gz"] = l_zip @fetcher.data["#{@gem_repo}prerelease_specs.#{v}.gz"] = p_zip @sf = Gem::SpecFetcher.new + + @released = Gem::NameTuple.from_list \ + [["a", Gem::Version.new("1"), "ruby"], + ["a", Gem::Version.new("2"), "ruby"], + ["a_evil", Gem::Version.new("9"), "ruby"], + ["c", Gem::Version.new("1.2"), "ruby"], + ['dep_x', Gem::Version.new(1), 'ruby'], + ["pl", Gem::Version.new("1"), "i386-linux"], + ['x', Gem::Version.new(1), 'ruby']] end - def test_fetch_all + def test_spec_for_dependency_all d = "#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}" @fetcher.data["#{d}#{@a1.spec_name}.rz"] = util_zip(Marshal.dump(@a1)) @fetcher.data["#{d}#{@a2.spec_name}.rz"] = util_zip(Marshal.dump(@a2)) @fetcher.data["#{d}#{@a_pre.spec_name}.rz"] = util_zip(Marshal.dump(@a_pre)) @fetcher.data["#{d}#{@a3a.spec_name}.rz"] = util_zip(Marshal.dump(@a3a)) - dep = Gem::Dependency.new 'a', 1 + dep = Gem::Dependency.new 'a', ">= 1" - specs_and_sources = @sf.fetch dep, true + 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 = [[@a1.full_name, @gem_repo], [@a2.full_name, @gem_repo]] + expected = [[@a1.full_name, @source], [@a2.full_name, @source]] assert_equal expected, spec_names assert_same specs_and_sources.first.last, specs_and_sources.last.last end - def test_fetch_latest + def test_spec_for_dependency_latest d = "#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}" @fetcher.data["#{d}#{@a1.spec_name}.rz"] = util_zip(Marshal.dump(@a1)) @fetcher.data["#{d}#{@a2.spec_name}.rz"] = util_zip(Marshal.dump(@a2)) @fetcher.data["#{d}#{@a_pre.spec_name}.rz"] = util_zip(Marshal.dump(@a_pre)) - dep = Gem::Dependency.new 'a', 1 - specs_and_sources = @sf.fetch dep + 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 [[@a2.full_name, @gem_repo]], spec_names + assert_equal [[@a2.full_name, Gem::Source.new(@gem_repo)]], spec_names end - def test_fetch_prerelease + def test_spec_for_dependency_prerelease d = "#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}" @fetcher.data["#{d}#{@a1.spec_name}.rz"] = util_zip(Marshal.dump(@a1)) @fetcher.data["#{d}#{@a2.spec_name}.rz"] = util_zip(Marshal.dump(@a2)) @fetcher.data["#{d}#{@a_pre.spec_name}.rz"] = util_zip(Marshal.dump(@a_pre)) - specs_and_sources = @sf.fetch dep('a', '1.a'), false, true, true + 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_pre.full_name, @gem_repo]], spec_names + assert_equal [[@a_pre.full_name, Gem::Source.new(@gem_repo)]], spec_names end - def test_fetch_platform + def test_spec_for_dependency_platform util_set_arch 'i386-linux' @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@pl1.original_name}.gemspec.rz"] = util_zip(Marshal.dump(@pl1)) dep = Gem::Dependency.new 'pl', 1 - specs_and_sources = @sf.fetch dep + 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 [[@pl1.full_name, @gem_repo]], spec_names + assert_equal [[@pl1.full_name, Gem::Source.new(@gem_repo)]], spec_names end - def test_fetch_with_errors_mismatched_platform + def test_spec_for_dependency_mismatched_platform util_set_arch 'hrpa-989' @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@pl1.original_name}.gemspec.rz"] = util_zip(Marshal.dump(@pl1)) dep = Gem::Dependency.new 'pl', 1 - specs_and_sources, errors = @sf.fetch_with_errors dep + specs_and_sources, errors = @sf.spec_for_dependency dep assert_equal 0, specs_and_sources.size assert_equal 1, errors.size @@ -125,284 +136,95 @@ class TestGemSpecFetcher < Gem::TestCase assert_equal "i386-linux", errors[0].platforms.first end - def test_fetch_spec - spec_uri = "#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}" - @fetcher.data["#{spec_uri}.rz"] = util_zip(Marshal.dump(@a1)) - - spec = @sf.fetch_spec ['a', Gem::Version.new(1), 'ruby'], @uri - assert_equal @a1.full_name, spec.full_name - - cache_dir = @sf.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 - spec_uri = "#{@gem_repo}/#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}" - @fetcher.data["#{spec_uri}.rz"] = nil - - cache_dir = @sf.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 + 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 - spec = @sf.fetch_spec ['a', Gem::Version.new(1), 'ruby'], @uri - assert_equal @a1.full_name, spec.full_name - end - - def test_fetch_spec_platform - @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@pl1.original_name}.gemspec.rz"] = - util_zip(Marshal.dump(@pl1)) - - spec = @sf.fetch_spec ['pl', Gem::Version.new(1), 'i386-linux'], @uri - - assert_equal @pl1.full_name, spec.full_name - end + Gem.sources.replace [src] - def test_fetch_spec_platform_ruby - @fetcher.data["#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}.rz"] = - util_zip(Marshal.dump(@a1)) - - spec = @sf.fetch_spec ['a', Gem::Version.new(1), nil], @uri - assert_equal @a1.full_name, spec.full_name - - spec = @sf.fetch_spec ['a', Gem::Version.new(1), ''], @uri - assert_equal @a1.full_name, spec.full_name - end - - def test_find_matching_all - dep = Gem::Dependency.new 'a', 1 - specs = @sf.find_matching dep, true - - expected = [ - [['a', Gem::Version.new(1), Gem::Platform::RUBY], @gem_repo], - [['a', Gem::Version.new(2), Gem::Platform::RUBY], @gem_repo], - ] - - assert_equal expected, specs - end - - def test_find_matching_latest - dep = Gem::Dependency.new 'a', 1 - specs = @sf.find_matching dep - - expected = [ - [['a', Gem::Version.new(2), Gem::Platform::RUBY], @gem_repo], - ] - - assert_equal expected, specs - end - - def test_find_matching_prerelease - dep = Gem::Dependency.new 'a', '1.a' - specs = @sf.find_matching dep, false, true, true - - expected = [ - [['a', Gem::Version.new('1.a'), Gem::Platform::RUBY], @gem_repo], - ] - - assert_equal expected, specs - end - - def test_find_matching_platform - util_set_arch 'i386-linux' - - dep = Gem::Dependency.new 'pl', 1 - specs = @sf.find_matching dep - - expected = [ - [['pl', Gem::Version.new(1), 'i386-linux'], @gem_repo], - ] - - assert_equal expected, specs - - util_set_arch 'i386-freebsd6' - - dep = Gem::Dependency.new 'pl', 1 - specs = @sf.find_matching dep - - assert_equal [], specs - end + d = "#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}" + @fetcher.data["#{d}#{@a1.spec_name}.rz"] = util_zip(Marshal.dump(@a1)) + @fetcher.data["#{d}#{@a2.spec_name}.rz"] = util_zip(Marshal.dump(@a2)) + @fetcher.data["#{d}#{@a_pre.spec_name}.rz"] = util_zip(Marshal.dump(@a_pre)) + @fetcher.data["#{d}#{@a3a.spec_name}.rz"] = util_zip(Marshal.dump(@a3a)) - def test_find_matching_with_errors_matched_platform - util_set_arch 'i386-linux' + dep = Gem::Dependency.new 'a', ">= 1" - dep = Gem::Dependency.new 'pl', 1 - specs, errors = @sf.find_matching_with_errors dep + specs_and_sources, errors = @sf.spec_for_dependency dep - expected = [ - [['pl', Gem::Version.new(1), 'i386-linux'], @gem_repo], - ] + assert_equal [], specs_and_sources + sfp = errors.first - assert_equal expected, specs - assert_equal 0, errors.size + 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_find_matching_with_errors_invalid_platform - util_set_arch 'hrpa-899' - - dep = Gem::Dependency.new 'pl', 1 - specs, errors = @sf.find_matching_with_errors dep - - assert_equal 0, specs.size + def test_available_specs_latest + specs, _ = @sf.available_specs(:latest) - assert_equal 1, errors.size - - assert_equal "i386-linux", errors[0].platforms.first + assert_equal [@source], specs.keys + assert_equal @latest_specs, specs[@source].sort end - def test_find_all_platforms - util_set_arch 'i386-freebsd6' + def test_available_specs_released + specs, _ = @sf.available_specs(:released) - dep = Gem::Dependency.new 'pl', 1 - specs = @sf.find_matching dep, false, false - - expected = [ - [['pl', Gem::Version.new(1), 'i386-linux'], @gem_repo], - ] + assert_equal [@source], specs.keys - assert_equal expected, specs + assert_equal @released, specs[@source].sort end - def test_list - specs = @sf.list - - assert_equal [@uri], specs.keys - assert_equal @latest_specs, specs[@uri].sort - end + def test_available_specs_complete + specs, _ = @sf.available_specs(:complete) - def test_list_all - specs = @sf.list true + assert_equal [@source], specs.keys - assert_equal [@uri], specs.keys + comp = @prerelease_specs + @released - assert_equal([["a", Gem::Version.new("1"), "ruby"], - ["a", Gem::Version.new("2"), "ruby"], - ["a_evil", Gem::Version.new("9"), "ruby"], - ["c", Gem::Version.new("1.2"), "ruby"], - ["pl", Gem::Version.new("1"), "i386-linux"]], - specs[@uri].sort) + assert_equal comp.sort, specs[@source].sort end - def test_list_cache - specs = @sf.list + def test_available_specs_cache + specs, _ = @sf.available_specs(:latest) - refute specs[@uri].empty? + refute specs[@source].empty? @fetcher.data["#{@gem_repo}/latest_specs.#{Gem.marshal_version}.gz"] = nil - cached_specs = @sf.list + cached_specs, _ = @sf.available_specs(:latest) assert_equal specs, cached_specs end - def test_list_cache_all - specs = @sf.list true + def test_available_specs_cache_released + specs, _ = @sf.available_specs(:released) - refute specs[@uri].empty? + refute specs[@source].empty? @fetcher.data["#{@gem_repo}/specs.#{Gem.marshal_version}.gz"] = nil - cached_specs = @sf.list true + cached_specs, _ = @sf.available_specs(:released) assert_equal specs, cached_specs end - def test_list_latest_all - specs = @sf.list false - - assert_equal [@latest_specs], specs.values - - specs = @sf.list true - - assert_equal([[["a", Gem::Version.new("1"), "ruby"], - ["a", Gem::Version.new("2"), "ruby"], - ["a_evil", Gem::Version.new("9"), "ruby"], - ["c", Gem::Version.new("1.2"), "ruby"], - ["pl", Gem::Version.new("1"), "i386-linux"]]], - specs.values, 'specs file not loaded') - end - - def test_list_prerelease - specs = @sf.list false, true - - assert_equal @prerelease_specs, specs[@uri].sort - end - - def test_load_specs - expected = [ - ['a', Gem::Version.new('1.a'), Gem::Platform::RUBY], - ['a', Gem::Version.new(1), Gem::Platform::RUBY], - ['a', Gem::Version.new(2), Gem::Platform::RUBY], - ['a', Gem::Version.new('3.a'), Gem::Platform::RUBY], - ['a_evil', Gem::Version.new(9), Gem::Platform::RUBY], - ['c', Gem::Version.new('1.2'), Gem::Platform::RUBY], - ['pl', Gem::Version.new(1), 'i386-linux'], - ] - - assert_equal expected, @sf.load_specs(@uri, 'specs') - - cache_dir = File.join Gem.user_home, '.gem', 'specs', '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 - @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.user_home, '.gem', 'specs', 'gems.example.com%80' + def test_available_specs_prerelease + specs, _ = @sf.available_specs(:prerelease) - 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 - - latest_specs = @sf.load_specs @uri, 'latest_specs' - - assert_equal @latest_specs, latest_specs + assert_equal @prerelease_specs, specs[@source].sort end - def test_load_specs_cached_empty - @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] = - proc do - @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] = - util_gzip(Marshal.dump(@latest_specs)) - - nil - end + def test_available_specs_with_bad_source + Gem.sources.replace ["http://not-there.nothing"] - cache_dir = File.join Gem.user_home, '.gem', 'specs', 'gems.example.com%80' + specs, errors = @sf.available_specs(:latest) - FileUtils.mkdir_p cache_dir - - cache_file = File.join cache_dir, "latest_specs.#{Gem.marshal_version}" - - open cache_file, 'wb' do |io| - io.write Marshal.dump(@latest_specs)[0, 10] - end - - latest_specs = @sf.load_specs @uri, 'latest_specs' - - assert_equal @latest_specs, latest_specs + assert_equal({}, specs) + assert_kind_of Gem::SourceFetchProblem, errors.first end - def test_cache_dir_escapes_windows_paths - uri = URI.parse("file:///C:/WINDOWS/Temp/gem_repo") - cache_dir = @sf.cache_dir(uri).gsub(@sf.dir, '') - assert cache_dir !~ /:/, "#{cache_dir} should not contain a :" - end end diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb index 1fc9769146..2e7fe689bb 100644 --- a/test/rubygems/test_gem_specification.rb +++ b/test/rubygems/test_gem_specification.rb @@ -81,6 +81,7 @@ end files homepage licenses + metadata name platform post_install_message @@ -117,7 +118,6 @@ end end def test_self_from_yaml_syck_date_bug - return unless have_syck # No meanings if no syck # This is equivalent to (and totally valid) psych 1.0 output and # causes parse errors on syck. yaml = @a1.to_yaml @@ -132,7 +132,6 @@ end end def test_self_from_yaml_syck_default_key_bug - return unless have_syck # No meanings if no syck # This is equivalent to (and totally valid) psych 1.0 output and # causes parse errors on syck. yaml = <<-YAML @@ -302,6 +301,21 @@ dependencies: [] assert_equal @a2, spec 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{' @@ -421,13 +435,15 @@ dependencies: [] end def test_emits_zulu_timestamps_properly + skip "bug only on 1.9.2" unless RUBY_VERSION =~ /1\.9\.2/ + 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/ + end def test_initialize spec = Gem::Specification.new do |s| @@ -571,10 +587,6 @@ dependencies: [] @a2.activate assert @a2.activated? - - Gem::Deprecate.skip_during do - assert @a2.loaded? - end end def test_add_dependency_with_explicit_type @@ -643,11 +655,29 @@ dependencies: [] 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_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 @@ -812,14 +842,17 @@ dependencies: [] 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 @@ -832,6 +865,7 @@ dependencies: [] } 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 @@ -844,15 +878,12 @@ dependencies: [] refute_equal @a1.hash, @a2.hash end - def test_installation_path - Gem::Deprecate.skip_during do - assert_equal @gemhome, @a1.installation_path + def test_base_dir + assert_equal @gemhome, @a1.base_dir - @a1.instance_variable_set :@loaded_from, nil - @a1.instance_variable_set :@loaded, false + @a1.instance_variable_set :@loaded_from, nil - assert_nil @a1.installation_path - end + assert_equal Gem.dir, @a1.base_dir end def test_lib_files @@ -885,6 +916,20 @@ dependencies: [] 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 @@ -978,6 +1023,11 @@ dependencies: [] 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 @@ -1118,7 +1168,7 @@ Gem::Specification.new do |s| s.test_files = ["test/suite.rb"] if s.respond_to? :specification_version then - s.specification_version = 3 + s.specification_version = 4 if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then s.add_runtime_dependency(%q, [\"> 0.4\"]) @@ -1154,6 +1204,17 @@ end 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' @@ -1210,25 +1271,6 @@ end assert_match %r|^platform: ruby$|, @a1.to_yaml end - def test_to_yaml_emits_syck_compat_yaml - if YAML.const_defined?(:ENGINE) && YAML::ENGINE.syck? - begin - yamler, YAML::ENGINE.yamler = YAML::ENGINE.yamler, 'psych' - rescue LoadError - skip 'cannot load psych' - end - end - begin - @a1.add_dependency "gx", "1.0.0" - - y = @a1.to_yaml - - refute_match %r!^\s*- - =!, y - ensure - YAML::ENGINE.yamler = yamler if yamler - end - end - def test_validate util_setup_validate @@ -1297,6 +1339,26 @@ end 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' + + 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 + EXPECTED + + assert_equal expected, @ui.error, 'warning' + end + end + def test_validate_description util_setup_validate @@ -1494,6 +1556,25 @@ 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 @@ -1572,6 +1653,22 @@ end 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 @@ -1649,8 +1746,10 @@ end a-3-x86-other_platform-1 a_evil-9 c-1.2 + dep_x-1 p-1 #{p1_curr.full_name} + x-1 ] latest_specs = Gem::Specification.latest_specs.map(&:full_name).sort @@ -1658,6 +1757,163 @@ end 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 -*- + +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.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.require_paths = ["lib"] + 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_find_by_name + util_make_gems + 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_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 util_setup_deps @gem = quick_spec "awesome", "1.0" do |awesome| awesome.add_runtime_dependency "bonobo", [] @@ -1679,7 +1935,7 @@ end FileUtils.touch File.join("lib", "code.rb") FileUtils.touch File.join("test", "suite.rb") - File.open "bin/exec", "w" do |fp| + File.open "bin/exec", "w", 0755 do |fp| fp.puts "#!#{Gem.ruby}" end end @@ -1731,16 +1987,4 @@ end ensure $VERBOSE = old_verbose end - - def have_syck - unless defined?(@@have_syck) - begin - old_verbose, $VERBOSE = $VERBOSE, nil - @@have_syck = with_syck {YAML::ENGINE.syck?} - ensure - $VERBOSE = old_verbose - end - end - @@have_syck - end end diff --git a/test/rubygems/test_gem_uninstaller.rb b/test/rubygems/test_gem_uninstaller.rb index a65b9921bb..2bb806dc01 100644 --- a/test/rubygems/test_gem_uninstaller.rb +++ b/test/rubygems/test_gem_uninstaller.rb @@ -6,19 +6,17 @@ class TestGemUninstaller < Gem::InstallerTestCase def setup super - @user_spec.executables = ["executable"] - build_rake_in do use_ui ui do @installer.install - @user_installer.install + @spec = @installer.spec - Gem.use_paths @gemhome, Gem.user_dir - - @spec = Gem::Specification.find_by_name 'a' - @user_spec = Gem::Specification.find_by_name 'b' + @user_installer.install + @user_spec = @user_installer.spec end end + + Gem::Specification.reset end def test_initialize_expand_path @@ -42,7 +40,7 @@ class TestGemUninstaller < Gem::InstallerTestCase def test_remove_executables_force_keep uninstaller = Gem::Uninstaller.new nil, :executables => false - executable = File.join Gem.user_dir, 'bin', 'executable' + executable = File.join Gem.bindir(@user_spec.base_dir), 'executable' assert File.exist?(executable), 'executable not written' use_ui @ui do @@ -57,7 +55,7 @@ class TestGemUninstaller < Gem::InstallerTestCase def test_remove_executables_force_remove uninstaller = Gem::Uninstaller.new nil, :executables => true - executable = File.join Gem.user_dir, 'bin', 'executable' + executable = File.join Gem.bindir(@user_spec.base_dir), 'executable' assert File.exist?(executable), 'executable not written' use_ui @ui do @@ -77,7 +75,7 @@ class TestGemUninstaller < Gem::InstallerTestCase end exec_path = File.join Gem.user_dir, 'bin', 'executable' - assert_equal false, File.exist?(exec_path), 'removed exec from bin dir' + refute File.exist?(exec_path), 'exec still exists in user bin dir' assert_equal "Removing executable\n", @ui.output end @@ -200,7 +198,7 @@ class TestGemUninstaller < Gem::InstallerTestCase :executables => true, :user_install => true) - gem_dir = File.join Gem.user_dir, 'gems', @user_spec.full_name + gem_dir = File.join @user_spec.gem_dir Gem.pre_uninstall do assert_path_exists gem_dir @@ -218,6 +216,23 @@ class TestGemUninstaller < Gem::InstallerTestCase 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_greater_than_one util_make_gems @@ -225,11 +240,119 @@ class TestGemUninstaller < Gem::InstallerTestCase uninstaller = Gem::Uninstaller.new('a') - use_ui Gem::MockGemUi.new("2\n") do + 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 + util_gem 'r', '1', 'q' => '= 1' + util_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 + util_gem 'r', '1', 'q' => '~> 1.0' + util_gem 'x', '1', 'q' => '= 1.0' + util_gem 'q', '1.0' + util_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 + util_gem 'r', '1', 'q' => '~> 1.0' + util_gem 'q', '1.0' + util_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 + util_gem('r', '1') do |s| + s.add_development_dependency "q", "= 1.0" + end + + util_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_prompt_includes_dep_type + util_gem 'r', '1' do |s| + s.add_development_dependency 'q', '= 1' + end + + util_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/test/rubygems/test_gem_validator.rb b/test/rubygems/test_gem_validator.rb index 58e94bfed0..ab2a9b82a7 100644 --- a/test/rubygems/test_gem_validator.rb +++ b/test/rubygems/test_gem_validator.rb @@ -11,53 +11,26 @@ class TestGemValidator < Gem::TestCase @validator = Gem::Validator.new end - def test_verify_gem_file - gem_file = File.join @tempdir, 'simple_gem.gem' - File.open gem_file, 'wb' do |fp| fp.write @simple_gem end - - assert_equal nil, @validator.verify_gem_file(gem_file) - end - - def test_verify_gem_file_empty - e = assert_raises Gem::VerificationError do - @validator.verify_gem_file '' - end - - assert_equal 'missing gem file ', e.message - end - - def test_verify_gem_file_nonexistent - file = '/nonexistent/nonexistent.gem' - e = assert_raises Gem::VerificationError do - @validator.verify_gem_file file + def test_alien + @spec = quick_gem 'a' do |s| + s.files = %w[lib/a.rb lib/b.rb] end - assert_equal "missing gem file #{file}", e.message - end - - def test_verify_gem - assert_equal nil, @validator.verify_gem(@simple_gem) - end - - def test_verify_gem_empty - e = assert_raises Gem::VerificationError do - @validator.verify_gem '' - end + util_build_gem @spec - assert_equal 'empty gem file', e.message - end + FileUtils.rm File.join(@spec.gem_dir, 'lib/b.rb') + FileUtils.touch File.join(@spec.gem_dir, 'lib/c.rb') - def test_verify_gem_invalid_checksum - e = assert_raises Gem::VerificationError do - @validator.verify_gem @simple_gem.upcase - end + alien = @validator.alien 'a' - assert_equal 'invalid checksum for gem file', e.message - end + expected = { + @spec.file_name => [ + Gem::Validator::ErrorData.new('lib/b.rb', 'Missing file'), + Gem::Validator::ErrorData.new('lib/c.rb', 'Extra file'), + ] + } - def test_verify_gem_no_sum - assert_equal nil, @validator.verify_gem('words') + assert_equal expected, alien end - end diff --git a/test/rubygems/test_gem_version.rb b/test/rubygems/test_gem_version.rb index f578063edc..4a7c223474 100644 --- a/test/rubygems/test_gem_version.rb +++ b/test/rubygems/test_gem_version.rb @@ -33,6 +33,9 @@ class TestGemVersion < Gem::TestCase assert_same fake, Gem::Version.create(fake) 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_eql_eh @@ -56,7 +59,7 @@ class TestGemVersion < Gem::TestCase end def test_initialize - ["1.0", "1.0 ", " 1.0 ", "1.0\n", "\n1.0\n"].each do |good| + ["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 @@ -106,13 +109,13 @@ class TestGemVersion < Gem::TestCase assert_nil v("1.0") <=> "whatever" end - def test_spermy_recommendation - assert_spermy_equal "~> 1.0", "1" - assert_spermy_equal "~> 1.0", "1.0" - assert_spermy_equal "~> 1.2", "1.2" - assert_spermy_equal "~> 1.2", "1.2.0" - assert_spermy_equal "~> 1.2", "1.2.3" - assert_spermy_equal "~> 1.2", "1.2.3.a.4" + 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 @@ -125,10 +128,10 @@ class TestGemVersion < Gem::TestCase assert v(version).prerelease?, "#{version} is a prerelease" end - # Assert that +expected+ is the "spermy" recommendation for +version". + # Assert that +expected+ is the "approximate" recommendation for +version". - def assert_spermy_equal expected, version - assert_equal expected, v(version).spermy_recommendation + def assert_approximate_equal expected, version + assert_equal expected, v(version).approximate_recommendation end # Assert that bumping the +unbumped+ version yields the +expected+. diff --git a/test/rubygems/test_require.rb b/test/rubygems/test_require.rb new file mode 100644 index 0000000000..9484901581 --- /dev/null +++ b/test/rubygems/test_require.rb @@ -0,0 +1,193 @@ +require 'rubygems/test_case' +require 'rubygems' + +class TestGemRequire < Gem::TestCase + def assert_require(path) + assert require(path), "'#{path}' was already required" + end + + def test_require_is_not_lazy_with_exact_req + a1 = new_spec "a", "1", {"b" => "= 1"}, "lib/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 '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/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 '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/a.rb" + b1 = new_spec "b", "1", nil, "lib/b/c.rb" + + install_specs a1, b1 + + save_loaded_features do + assert_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_activate_via_require_respects_loaded_files + save_loaded_features do + require 'benchmark' # stdlib + + a1 = new_spec "a", "1", {"b" => ">= 1"}, "lib/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 '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/test/rubygems/wrong_key_cert.pem b/test/rubygems/wrong_key_cert.pem new file mode 100644 index 0000000000..3a93569b09 --- /dev/null +++ b/test/rubygems/wrong_key_cert.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBRDCB76ADAgECAgEBMA0GCSqGSIb3DQEBBQUAMCoxDzANBgNVBAMMBm5vYm9k +eTEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwIBcNMTIwMTE0MDEzNjUxWhgPOTk5 +OTEyMzEyMzU5NTlaMCoxDzANBgNVBAMMBm5vYm9keTEXMBUGCgmSJomT8ixkARkW +B2V4YW1wbGUwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA0lN/jShlFg0t+h1L2gkd +i2UXFnfLnXNh+J3Jolh4/Pd8rdzKTdnCep2nqDIRimnlEjO1+I3u7aurUc4b1AhX +5QIDAQABMA0GCSqGSIb3DQEBBQUAA0EAoN0sTPihqOKpzU9d+iSW4Ugniqc/JZa9 +Dqzavgqcabw7OJX+xqmaqa8945Ae+b1MnkUSZpEp+93FTA0ObvozmA== +-----END CERTIFICATE----- diff --git a/test/rubygems/wrong_key_cert_32.pem b/test/rubygems/wrong_key_cert_32.pem new file mode 100644 index 0000000000..b196642202 --- /dev/null +++ b/test/rubygems/wrong_key_cert_32.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBRDCB76ADAgECAgEBMA0GCSqGSIb3DQEBBQUAMCoxDzANBgNVBAMMBm5vYm9k +eTEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwIBcNMTIwMTE0MDEzNjUxWhgPMjAz +ODAxMTkwMzE0MDdaMCoxDzANBgNVBAMMBm5vYm9keTEXMBUGCgmSJomT8ixkARkW +B2V4YW1wbGUwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA0lN/jShlFg0t+h1L2gkd +i2UXFnfLnXNh+J3Jolh4/Pd8rdzKTdnCep2nqDIRimnlEjO1+I3u7aurUc4b1AhX +5QIDAQABMA0GCSqGSIb3DQEBBQUAA0EAN6vAYZkzfXQt4qu+LsO7UGWQrwtHv2hh +tdNQd1rArKhODhtJMr1OvPsuFdG52zJpp1EC2yJAXY+k0eYDC1SIhw== +-----END CERTIFICATE----- -- cgit v1.2.3