diff options
Diffstat (limited to 'test/rubygems')
212 files changed, 17745 insertions, 9994 deletions
diff --git a/test/rubygems/alternate_cert.pem b/test/rubygems/alternate_cert.pem index 54a34441b1..55303190f5 100644 --- a/test/rubygems/alternate_cert.pem +++ b/test/rubygems/alternate_cert.pem @@ -1,19 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDFjCCAf6gAwIBAgIBBDANBgkqhkiG9w0BAQUFADAtMRIwEAYDVQQDDAlhbHRl +MIIDFjCCAf6gAwIBAgIBBDANBgkqhkiG9w0BAQsFADAtMRIwEAYDVQQDDAlhbHRl cm5hdGUxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTEyMDEwMTAwMDAwMFoY Dzk5OTkxMjMxMjM1OTU5WjAtMRIwEAYDVQQDDAlhbHRlcm5hdGUxFzAVBgoJkiaJ k/IsZAEZFgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA -vZQipBa1xH3M9OonkrUYhGZeX9UHAcJhe6jJbUr/uHXkh1Tu2ERWNnblm85upqBf -jyZEnKer7uBcwwkkvmisVgC8uBECymsBxuEIw0rfiKYEnLu0B6SiWFYz3dYPS92b -BK7Vks2/kNyXUmLLGoZ3id2K0eK5C/AJ0j+p84OqPnVhylsjrZmXfIZrh7lkHhgC -IrzPefjE3pOloi/tz6fh2ktb0FYKQMfweT3Ba2TMeflG13PEOW80AD5w0THxDutG -G0zPNCDyDEoT7UU1a3B3RMHYuUxEk1GUEYWq9L6a6SMpZISWTSpCp0Ww1QB55PON -iCCn+o6vcIy46jI71dATAQIDAQABoz8wPTAcBgNVHREEFTATgRFhbHRlcm5hdGVA -ZXhhbXBsZTAdBgNVHQ4EFgQUyvn/FwcZnA7AkzPjmoooB4/tKgcwDQYJKoZIhvcN -AQEFBQADggEBAHilxCg0dmOn3hxPjWMf/tAvG/S25iAIZZPuWo71DSSsn/zPRWDZ -OkDNL7syJ7S2jjrWWCIyLxhj89ZI7Oyd3elOB2zd4RsDij1y9Gv0ZPqNoTp0Repk -aPtRRLEwk9j2C37Tv+qA2PnTLp8MA0DVkb1/yuSd03b2K/AZEHT8Jtf3WC3RqGSK -A1+M8CvPSSgPY7oveFFerpqAzfC4tlgyPZjSqBjZucEIlxBD2lA/3JQ8Ys8+0705 -j2jGMl5r1Y22nl0A0+cHGtPX3irtR8bcEAO+rpEfpHNF2APaYsCT7Frk1CtuAHYB -mEwqWPQKU5ZJOV4uu69Hw5Po2bfgyjKV+N8= +pebGm7NOnx+DtWG1xQsJBfTfwNlZvfzY61nlZccrhU6vx0AnYNiDZAG3J/gFQmYZ +9gJ98rzEwfLMCGq9R/TZM+lAEaLhzYZCu3X4QdhKxr1xZ/SFC+1f8KVuH4tLXORW +30DwayPhNxnrOvup4pWLiYuXUSZpV9CGMvPSUCW2odhMkBMKqaTTPjxoXJIcgacy +prkNgIq48cSvqWG/e/HrMRtkqvFbD5ta00uO1mlpajYYw1RRftEwktFo8vQgDBo9 +NT/EqoE72tffaDnLq6rQrVtw4Kr9fy775DjNAWXyiCBjnJgOQSXCGPsM/AEdFrh/ +LKQQv2M/M7WNevnEUgsEIwIDAQABoz8wPTAcBgNVHREEFTATgRFhbHRlcm5hdGVA +ZXhhbXBsZTAdBgNVHQ4EFgQUYPwS8g98+4Tq/8gcEK1iilkGXH4wDQYJKoZIhvcN +AQELBQADggEBABSKUFmTk53+yrVFT3TvX5iGgXudNdACQqcnknAg66Q8+wMA8WT1 +M2oZJIH4SWSKUGMYubpYuc53tTtMnR594LPidyNbxo8KXMYoNfEkZCk6hh0eKVdx +zPJSZ4fOQ4mKFCd7HrycOr4bxuGPTVQERYJ45vZnhvVJDIRMgshnQuivP3VBwXkQ +gKLTCh2ew2ZJgPi1dfqdNMMSw7k4OQtQVhwbAkHgwL1TUShAO9lHzxFHlQgssfR0 +f6c89eB035Vn9s21StjerTOlC9+v4hOO7QhvbsCcUs2wWiE1BWo1QqnVBCjGKyVE +fISkJd1Sn5j+Vx/NJ7EfZcOGGQMdxHC+c90= -----END CERTIFICATE----- diff --git a/test/rubygems/alternate_cert_32.pem b/test/rubygems/alternate_cert_32.pem index adeffda24a..e727189470 100644 --- a/test/rubygems/alternate_cert_32.pem +++ b/test/rubygems/alternate_cert_32.pem @@ -1,19 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDFDCCAfygAwIBAgIBBTANBgkqhkiG9w0BAQUFADAtMRIwEAYDVQQDDAlhbHRl +MIIDFDCCAfygAwIBAgIBBTANBgkqhkiG9w0BAQsFADAtMRIwEAYDVQQDDAlhbHRl cm5hdGUxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTEyMDEwMTAwMDAwMFoX DTM4MDExOTAzMTQwN1owLTESMBAGA1UEAwwJYWx0ZXJuYXRlMRcwFQYKCZImiZPy -LGQBGRYHZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL2U -IqQWtcR9zPTqJ5K1GIRmXl/VBwHCYXuoyW1K/7h15IdU7thEVjZ25ZvObqagX48m -RJynq+7gXMMJJL5orFYAvLgRAsprAcbhCMNK34imBJy7tAekolhWM93WD0vdmwSu -1ZLNv5Dcl1JiyxqGd4nditHiuQvwCdI/qfODqj51YcpbI62Zl3yGa4e5ZB4YAiK8 -z3n4xN6TpaIv7c+n4dpLW9BWCkDH8Hk9wWtkzHn5RtdzxDlvNAA+cNEx8Q7rRhtM -zzQg8gxKE+1FNWtwd0TB2LlMRJNRlBGFqvS+mukjKWSElk0qQqdFsNUAeeTzjYgg -p/qOr3CMuOoyO9XQEwECAwEAAaM/MD0wHAYDVR0RBBUwE4ERYWx0ZXJuYXRlQGV4 -YW1wbGUwHQYDVR0OBBYEFMr5/xcHGZwOwJMz45qKKAeP7SoHMA0GCSqGSIb3DQEB -BQUAA4IBAQA1Vs3lcPpqnbsdtFDgrzApZuNgtyCRbbSrshq37dem9wSI4aFjAPLx -QGgf3c+XZczK9FkR3VUHcK8yZFrCKpv9giZDvzCUOMB/HSBAzNiNbhgUC1S0THir -xFriDITPoY7mrdJlX41Ssqk6tIKZsYP63UVghy7f9wxqXJvyfJZSB9UeM+0baQVL -tGTKXmvzLw1Pc/LHTrt7jcZT9UbBsxNNy0Wk9FPPePCUUlegRjInd/sNevywzL/T -1DL0BefqF6iyWcu86Udo+eli1JDzeUsfHOL7oqJGlWhlZHRDJ1M89n5KwPg8SCx5 -TpemV2Wy0nRTzITnmggexlMibSJ0iOvC +LGQBGRYHZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKXm +xpuzTp8fg7VhtcULCQX038DZWb382OtZ5WXHK4VOr8dAJ2DYg2QBtyf4BUJmGfYC +ffK8xMHyzAhqvUf02TPpQBGi4c2GQrt1+EHYSsa9cWf0hQvtX/Clbh+LS1zkVt9A +8Gsj4TcZ6zr7qeKVi4mLl1EmaVfQhjLz0lAltqHYTJATCqmk0z48aFySHIGnMqa5 +DYCKuPHEr6lhv3vx6zEbZKrxWw+bWtNLjtZpaWo2GMNUUX7RMJLRaPL0IAwaPTU/ +xKqBO9rX32g5y6uq0K1bcOCq/X8u++Q4zQFl8oggY5yYDkElwhj7DPwBHRa4fyyk +EL9jPzO1jXr5xFILBCMCAwEAAaM/MD0wHAYDVR0RBBUwE4ERYWx0ZXJuYXRlQGV4 +YW1wbGUwHQYDVR0OBBYEFGD8EvIPfPuE6v/IHBCtYopZBlx+MA0GCSqGSIb3DQEB +CwUAA4IBAQBJeq9kniAdddOY2r9MhRYb8/rzWL1mcCgbIzkwXCTeOyVt0nWZZwAy +arEy8ofkXt1O3Bm+59+dPORnG5WJeBGVmGDHo9HxDjm4dgTramYqgtxbthmB/pu+ +QhJ5DQg59odomoRRG7dkqacd8GMdcJVYcb3OzV3Fe5v2gtvnVPZ711APtjZ7sZUR +4XBA+ok95QFeSUYo4WIOCHh16pPtZ9ium5SZ7ChVVNj5rthr+sS+rQKjEdjG510w +UOkg8rUjEvXPGjM80/DnOvzyRJvbcCWBWWHquft3wqbjTomnQtqHne2SwRFEyfpd +JLEuY9QtEUCUy7obccN39+nT9jUOyg3B -----END CERTIFICATE----- diff --git a/test/rubygems/alternate_key.pem b/test/rubygems/alternate_key.pem index 14ca734aba..ae587b3425 100644 --- a/test/rubygems/alternate_key.pem +++ b/test/rubygems/alternate_key.pem @@ -1,27 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAvZQipBa1xH3M9OonkrUYhGZeX9UHAcJhe6jJbUr/uHXkh1Tu -2ERWNnblm85upqBfjyZEnKer7uBcwwkkvmisVgC8uBECymsBxuEIw0rfiKYEnLu0 -B6SiWFYz3dYPS92bBK7Vks2/kNyXUmLLGoZ3id2K0eK5C/AJ0j+p84OqPnVhylsj -rZmXfIZrh7lkHhgCIrzPefjE3pOloi/tz6fh2ktb0FYKQMfweT3Ba2TMeflG13PE -OW80AD5w0THxDutGG0zPNCDyDEoT7UU1a3B3RMHYuUxEk1GUEYWq9L6a6SMpZISW -TSpCp0Ww1QB55PONiCCn+o6vcIy46jI71dATAQIDAQABAoIBAArXgfOoaNTH7QTE -r2awfKp1wEfywufS2ghcasiZVW6TL3Kd5NrxbYzH1/HFKIbW/SAOrDXZUPfkVOnC -iBtrmQ+CE0jjkClLXVqmW/3vNkF2XSUphu44+B/dLjItn8pS7h6icQxoP+Bk/TJ0 -+/CUaBm2Vc4TDUolfCpOAcYvbXkM3BL+N/XN2JHX52D2ljXtryrNm/sFnabUVo96 -ghWqln8TqpYTagcs/JkEQ5YxwqFuBLofz3SgzCnf8ub8WTIpYhWzWZ4yHjZSL7AS -54mkJarKWMUYcL/Qeuy1U9vxLrbC9V7cPzSkzYxPZF7XlYaJcAbItX182ufZ1uNX -3JlQS5ECgYEA+6fbg+WKy5AazEs8YokPjq1X1P01o95KUWFg+68ALowQXEYcExew -PG0BKW11WrR6Bnn41++13k8Qsrq7Tl8ynCO6ANhoWAxUksdJDAuEgQqpFuRXwa/D -d++8WlWD4XYqLwiE+h72alE/Ce/SdfPPsyBeHtXo7fih378WyZn7K9cCgYEAwNnw -zjndLtj9bxd4awHHWgQ7QpKCmtLMGlg7Teo9aODMO80G3h8NEEG6Ou6LHn88tqgH -yu0WcjJmhINAzNzmABdw+WuV4C94glwtXctQ0w4byuLOaKSh3ggWUnKf56A2KyPh -JHPe/+A1DTKAgBvU/i5Vx0kZBkUMiiEVcIOgHOcCgYBNkt6998IjIdbA5uhET4+2 -IYUTqMIiM2GhWG026CkcMBzS9OGumPzAg7F5/b3RKhT7bhnhJolfb+vrzFf0vq+x -JeouXIc9rP9dB4Vi6yH7TTf2UIkksXOFwybCid3PYEd8nBmxqF25RDY0b/LmXTPH -OdEJnFLjGGN9vz/dAVRFnQKBgQC8hE8hSO8uHG+haRANim+VTw2exhllvypFlnpi -b9gX7ae3zXQpLbFXcujZMtZLuZVf+GGlvJ10hFAyuRtfJ5CuBjwplUGtJLpotDKk -vVsE9YW1joC3SjfxE3a+oc4uXi6VfT1YpOwYtNMnU3bJxGsxDZpMdOhBeL4JSM3s -br7VgQKBgBDdJHRQOkP41Iq7CjcheTJMeXsQJt+HLHSIpEkxi8v/9bLKPbRVRo7e -8mmEr9mvjrNLVZMrQpgngRGbFzcdi9iDv+4m0OKU7BGZyWy1gtlUV77FqsL7EEl3 -gdM670c2kkrni5DdpTLpNgF6zRKK7ArZ6kSgmuEYJCGHHlpbkg3f +MIIEpQIBAAKCAQEApebGm7NOnx+DtWG1xQsJBfTfwNlZvfzY61nlZccrhU6vx0An +YNiDZAG3J/gFQmYZ9gJ98rzEwfLMCGq9R/TZM+lAEaLhzYZCu3X4QdhKxr1xZ/SF +C+1f8KVuH4tLXORW30DwayPhNxnrOvup4pWLiYuXUSZpV9CGMvPSUCW2odhMkBMK +qaTTPjxoXJIcgacyprkNgIq48cSvqWG/e/HrMRtkqvFbD5ta00uO1mlpajYYw1RR +ftEwktFo8vQgDBo9NT/EqoE72tffaDnLq6rQrVtw4Kr9fy775DjNAWXyiCBjnJgO +QSXCGPsM/AEdFrh/LKQQv2M/M7WNevnEUgsEIwIDAQABAoIBABB/S16uTPIr2xgN +WFr4xvPtrtZphrAK1bNJpDMjxCMkePxSV9gcj6xBM2ppEnTQ3GIHS2j49oPm1f08 +SAhAw9ySpElcriGW6Unk6EP78yuiKQXSXeyatUCj4riGTH83QaA/v+iXj8y/6hFa +d0FN56tM00ZBkJYn6UBl2JMZvPiI9cdRO1KhhK4+NZrKg8jdRwjJe9fxo31xefpr +jNqyx7O06hzaVfMt5jUi5qSc+/1EWJtXlvCyuJJCjpEay6ePUP5eTi/hQpwfaO82 +nIRXolwg7TPxg8rea6WQM/x6Ec3MWYUflJUdZbKDQQv1pyZR62T7WHNA1p5jHMzq +MW3kctkCgYEAxhnT8+TZG9sF/fQro0JZnKxnZXjQ9ob7vmvbyBgHf2HzrY716UkX +vLAHrykgqzZmIlWATayCryr+CzkaXu/xLrS0IMmjF//VlFjlob6OL9n40qrOW221 +ryqNNaKkMmm4c4N9D1rhsNH+vVQoeEDkHet9Pll9ilB2o3ERapMfBzcCgYEA1mO+ +iJLf7y1chmpwMWLFrK4hjPK6670K4UvDCfX6517xHtykZ05lZQ9OQLjjDsyG8Uub +H6k7KxCTV+zxLQDcUUEh/UbTb6eMhh2HAU+Bym8+lWCIdl8qPouPKz1dc+rImRwC +JE7LtxbyHXv67sPL5/7GhmdCxThXQvjH7fP1CHUCgYEArbj4pmmJ+2OXXZ1Cp2kI +LN0Dz3ijx42YNuVfV5m6+Xpst0cnX+05Y776/iCTBZIu/uz8FyGxeOu63Ry2g4rn +do4BaL9qxyETq4RJ3A2/ozcDfbtMO+F58qLeMqruU0di+enVQiHwyZ9eRaoH020U +nyhkLMlNzn3BjJMbMtrR2wECgYEAm54tSI9sUv2XQs5x/7cVi6GeIuRyP/mpsx2+ +RjWx2U52MZOxFne2a+PvRlWuIyjc7ruVrya1Fy5h9Zm8+pC8W5KurF1DzrFM9HDs +dUwUBzA2ulEm3N15GYtN8fIKKsEKuPC2sUos3wqd1j8PR08CbLTnv9mmgufBl5Bj +91p0y50CgYEAsD/KO1/BTJWVFAXoPgde4Fmt3vQyF7OYkOI0EEIGSVPydo8ebNib +cozGB1H0vhuvdrysi1Oc+uZ2pL8gpZfdYXbmD9cScXL+pP+GUmKKHTKKGAeQCWpv +2M3MZEjqOGQrqY50khXUDi77H1sAHMIBQ8yF6mdb+YU+OayRwBZmHiI= -----END RSA PRIVATE KEY----- diff --git a/test/rubygems/bad_rake.rb b/test/rubygems/bad_rake.rb index a08aa7dacc..e15a7d4156 100644 --- a/test/rubygems/bad_rake.rb +++ b/test/rubygems/bad_rake.rb @@ -1,2 +1,3 @@ # frozen_string_literal: true + exit 1 diff --git a/test/rubygems/bogussources.rb b/test/rubygems/bogussources.rb deleted file mode 100644 index 4f783c3bd2..0000000000 --- a/test/rubygems/bogussources.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true -#-- -# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. -# All rights reserved. -# See LICENSE.txt for permissions. -#++ - -require 'rubygems' -Gem.use_paths("test/mock/gems") diff --git a/test/rubygems/bundler_test_gem.rb b/test/rubygems/bundler_test_gem.rb new file mode 100644 index 0000000000..ca2980e04b --- /dev/null +++ b/test/rubygems/bundler_test_gem.rb @@ -0,0 +1,424 @@ +# frozen_string_literal: true + +require_relative "helper" + +class TestBundlerGem < Gem::TestCase + PROJECT_DIR = File.expand_path("../..", __dir__) + + def test_self_use_gemdeps + with_local_bundler_at(Gem.dir) do + with_rubygems_gemdeps("-") do + FileUtils.mkdir_p "detect/a/b" + FileUtils.mkdir_p "detect/a/Isolate" + + FileUtils.touch "detect/Isolate" + + begin + Dir.chdir "detect/a/b" + + Gem.use_gemdeps + + assert_equal add_bundler_full_name([]), loaded_spec_names + ensure + Dir.chdir @tempdir + end + end + end + end + + def test_self_find_files_with_gemfile + with_local_bundler_at(Gem.dir) do + cwd = File.expand_path("test/rubygems", PROJECT_DIR) + actual_load_path = $LOAD_PATH.unshift(cwd).dup + + discover_path = File.join "lib", "sff", "discover.rb" + + foo1, _ = %w[1 2].map do |version| + spec = quick_gem "sff", version do |s| + s.files << discover_path + end + + write_file(File.join("gems", spec.full_name, discover_path)) do |fp| + fp.puts "# #{spec.full_name}" + end + + spec + end + Gem.refresh + + write_file(File.join(Dir.pwd, "Gemfile")) do |fp| + fp.puts "source 'https://rubygems.org'" + fp.puts "gem '#{foo1.name}', '#{foo1.version}'" + end + Gem.use_gemdeps(File.join(Dir.pwd, "Gemfile")) + + expected = [ + File.expand_path("test/rubygems/sff/discover.rb", PROJECT_DIR), + File.join(foo1.full_gem_path, discover_path), + ].sort + + assert_equal expected, Gem.find_files("sff/discover").sort + assert_equal expected, Gem.find_files("sff/**.rb").sort, "[ruby-core:31730]" + assert_equal cwd, actual_load_path.shift + end + end + + def test_auto_activation_of_specific_gemdeps_file + with_local_bundler_at(Gem.dir) do + a = util_spec "a", "1", nil, "lib/a.rb" + b = util_spec "b", "1", nil, "lib/b.rb" + c = util_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 + + with_rubygems_gemdeps(path) do + Gem.use_gemdeps + + assert_equal add_bundler_full_name(%W[a-1 b-1 c-1]), loaded_spec_names + end + end + end + + def test_auto_activation_of_used_gemdeps_file + with_local_bundler_at(Gem.dir) do + a = util_spec "a", "1", nil, "lib/a.rb" + b = util_spec "b", "1", nil, "lib/b.rb" + c = util_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 + + with_rubygems_gemdeps("-") do + expected_specs = [a, b, util_spec("bundler", Bundler::VERSION), c].compact.map(&:full_name) + + Gem.use_gemdeps + + assert_equal expected_specs, loaded_spec_names + end + end + end + + def test_looks_for_gemdeps_files_automatically_from_binstubs + path = File.join(@tempdir, "gd-tmp") + + with_local_bundler_at(path) do + a = util_spec "a", "1" do |s| + s.executables = %w[foo] + s.bindir = "exe" + end + + write_file File.join(@tempdir, "exe", "foo") do |fp| + fp.puts "puts Gem.loaded_specs.values.map(&:full_name).sort" + end + + b = util_spec "b", "1", nil, "lib/b.rb" + c = util_spec "c", "1", nil, "lib/c.rb" + + install_specs a, b, c + + install_gem a, install_dir: path + install_gem b, install_dir: path + install_gem c, install_dir: path + + ENV["GEM_PATH"] = path + + with_rubygems_gemdeps("-") do + new_path = [File.join(path, "bin"), ENV["PATH"]].join(File::PATH_SEPARATOR) + new_rubyopt = "-I#{rubygems_path} -I#{bundler_path}" + + path = File.join @tempdir, "gem.deps.rb" + + File.open path, "w" do |f| + f.puts "gem 'a'" + end + out0 = with_path_and_rubyopt(new_path, new_rubyopt) do + IO.popen("foo", &:read).split(/\n/) + end + + File.open path, "a" do |f| + f.puts "gem 'b'" + f.puts "gem 'c'" + end + out = with_path_and_rubyopt(new_path, new_rubyopt) do + IO.popen("foo", &:read).split(/\n/) + end + + assert_equal ["b-1", "c-1"], out - out0 + end + end + end + + def test_looks_for_gemdeps_files_automatically_from_binstubs_in_parent_dir + path = File.join(@tempdir, "gd-tmp") + + with_local_bundler_at(path) do + pend "IO.popen has issues on JRuby when passed :chdir" if Gem.java_platform? + + a = util_spec "a", "1" do |s| + s.executables = %w[foo] + s.bindir = "exe" + end + + write_file File.join(@tempdir, "exe", "foo") do |fp| + fp.puts "puts Gem.loaded_specs.values.map(&:full_name).sort" + end + + b = util_spec "b", "1", nil, "lib/b.rb" + c = util_spec "c", "1", nil, "lib/c.rb" + + install_specs a, b, c + + install_gem a, install_dir: path + install_gem b, install_dir: path + install_gem c, install_dir: path + + ENV["GEM_PATH"] = path + + with_rubygems_gemdeps("-") do + Dir.mkdir "sub1" + + new_path = [File.join(path, "bin"), ENV["PATH"]].join(File::PATH_SEPARATOR) + new_rubyopt = "-I#{rubygems_path} -I#{bundler_path}" + + path = File.join @tempdir, "gem.deps.rb" + + File.open path, "w" do |f| + f.puts "gem 'a'" + end + out0 = with_path_and_rubyopt(new_path, new_rubyopt) do + IO.popen("foo", chdir: "sub1", &:read).split(/\n/) + end + + File.open path, "a" do |f| + f.puts "gem 'b'" + f.puts "gem 'c'" + end + out = with_path_and_rubyopt(new_path, new_rubyopt) do + IO.popen("foo", chdir: "sub1", &:read).split(/\n/) + end + + Dir.rmdir "sub1" + + assert_equal ["b-1", "c-1"], out - out0 + end + end + end + + def test_use_gemdeps + with_local_bundler_at(Gem.dir) do + gem_deps_file = "gem.deps.rb" + spec = util_spec "a", 1 + install_specs spec + + spec = Gem::Specification.find {|s| s == spec } + refute spec.activated? + + File.open gem_deps_file, "w" do |io| + io.write 'gem "a"' + end + + assert_nil Gem.gemdeps + + Gem.use_gemdeps gem_deps_file + + assert_equal add_bundler_full_name(%W[a-1]), loaded_spec_names + refute_nil Gem.gemdeps + end + end + + def test_use_gemdeps_ENV + with_local_bundler_at(Gem.dir) do + with_rubygems_gemdeps(nil) do + spec = util_spec "a", 1 + + refute spec.activated? + + File.open "gem.deps.rb", "w" do |io| + io.write 'gem "a"' + end + + Gem.use_gemdeps + + refute spec.activated? + end + end + end + + def test_use_gemdeps_argument_missing + with_local_bundler_at(Gem.dir) do + e = assert_raise ArgumentError do + Gem.use_gemdeps "gem.deps.rb" + end + + assert_equal "Unable to find gem dependencies file at gem.deps.rb", + e.message + end + end + + def test_use_gemdeps_argument_missing_match_ENV + with_local_bundler_at(Gem.dir) do + with_rubygems_gemdeps("gem.deps.rb") do + e = assert_raise ArgumentError do + Gem.use_gemdeps "gem.deps.rb" + end + + assert_equal "Unable to find gem dependencies file at gem.deps.rb", + e.message + end + end + end + + def test_use_gemdeps_automatic + with_local_bundler_at(Gem.dir) do + with_rubygems_gemdeps("-") do + spec = util_spec "a", 1 + install_specs spec + spec = Gem::Specification.find {|s| s == spec } + + refute spec.activated? + + File.open "Gemfile", "w" do |io| + io.write 'gem "a"' + end + + Gem.use_gemdeps + + assert_equal add_bundler_full_name(%W[a-1]), loaded_spec_names + end + end + end + + def test_use_gemdeps_automatic_missing + with_local_bundler_at(Gem.dir) do + with_rubygems_gemdeps("-") do + Gem.use_gemdeps + + assert true # count + end + end + end + + def test_use_gemdeps_disabled + with_local_bundler_at(Gem.dir) do + with_rubygems_gemdeps("") do + spec = util_spec "a", 1 + + refute spec.activated? + + File.open "gem.deps.rb", "w" do |io| + io.write 'gem "a"' + end + + Gem.use_gemdeps + + refute spec.activated? + end + end + end + + def test_use_gemdeps_missing_gem + with_local_bundler_at(Gem.dir) do + with_rubygems_gemdeps("x") do + File.open "x", "w" do |io| + io.write 'gem "a"' + end + + expected = <<-EXPECTED +Could not find gem 'a' in locally installed gems. +You may need to `bundle install` to install missing gems + + EXPECTED + + Gem::Deprecate.skip_during do + actual_stdout, actual_stderr = capture_output do + Gem.use_gemdeps + end + assert_empty actual_stdout + assert_equal(expected, actual_stderr) + end + end + end + end + + def test_use_gemdeps_specific + with_local_bundler_at(Gem.dir) do + with_rubygems_gemdeps("x") do + spec = util_spec "a", 1 + install_specs spec + + spec = Gem::Specification.find {|s| s == spec } + refute spec.activated? + + File.open "x", "w" do |io| + io.write 'gem "a"' + end + + Gem.use_gemdeps + + assert_equal add_bundler_full_name(%W[a-1]), loaded_spec_names + end + end + end + + private + + def add_bundler_full_name(names) + names << "bundler-#{Bundler::VERSION}" + names.sort! + names + end + + def with_path_and_rubyopt(path_value, rubyopt_value) + path = ENV["PATH"] + ENV["PATH"] = path_value + rubyopt = ENV["RUBYOPT"] + ENV["RUBYOPT"] = rubyopt_value + + yield + ensure + ENV["PATH"] = path + ENV["RUBYOPT"] = rubyopt + end + + def with_rubygems_gemdeps(value) + rubygems_gemdeps = ENV["RUBYGEMS_GEMDEPS"] + ENV["RUBYGEMS_GEMDEPS"] = value + + yield + ensure + ENV["RUBYGEMS_GEMDEPS"] = rubygems_gemdeps + end + + def with_local_bundler_at(path) + require "bundler" + + # If bundler gemspec exists, pretend it's installed + bundler_gemspec = File.expand_path("../../bundler/bundler.gemspec", __dir__) + if File.exist?(bundler_gemspec) + target_gemspec_location = "#{path}/specifications/bundler-#{Bundler::VERSION}.gemspec" + + FileUtils.mkdir_p File.dirname(target_gemspec_location) + + File.write target_gemspec_location, Gem::Specification.load(bundler_gemspec).to_ruby_for_cache + end + + yield + ensure + Bundler.reset! + end +end diff --git a/test/rubygems/child_cert.pem b/test/rubygems/child_cert.pem index 9293cfc966..26c916cf96 100644 --- a/test/rubygems/child_cert.pem +++ b/test/rubygems/child_cert.pem @@ -1,20 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDTTCCAjWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv +MIIDLDCCAhSgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTEyMDEwMTAwMDAwMFoYDzk5 OTkxMjMxMjM1OTU5WjApMQ4wDAYDVQQDDAVjaGlsZDEXMBUGCgmSJomT8ixkARkW -B2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDKf7+1q0cR -MhC/RM6Whpon/5IxuSve3CCxxdN0LcSbUisFMlf28Zj+S545SKFc6gHFcnYLZZsy -Gm4FWEd4DhNpg/kgoDPuPGwQp2DEOvKnnneB/Shj8V+6oLrjXaZFAu8Q916c5/BL -z+PlHIIsO/Q865XOK+5z1sZi0xval8QT7u4Usrcy86gevflCbpBAWkNPa/DZDqA9 -nk0vB2XDSHvhavcrYLfDrYAnFz3wiZ70LYQrmdeOqkPpaiw//Qpzqp+vtuF2br6U -iYWpN+dhdFsIxAwIE5kWZ1kk6OBJ4kHvr+Sh8Oqbf6WFBhW/lQa9wldA0xhNwhGr -1FDEfC+0g/BvAgMBAAGjfTB7MBgGA1UdEQQRMA+BDWNoaWxkQGV4YW1wbGUwHQYD -VR0OBBYEFHzVU9N7sklKBPrHElxoZ32Fg64IMB8GA1UdIwQYMBaAFF9DbvaajkUl -6SLjfTdepNU2AoUbMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgIEMA0G -CSqGSIb3DQEBBQUAA4IBAQAKRUboW7dwIHuzOp+7Nbx+ltWLUgwMkDLjjXjJE1Tv -L+NNmAx2iv0WghyoKaUBYW+SgIcenQoMfIA+K8Z6a4dUruJ0TKsUgLW8sx3wx9h8 -NwjjybsUh8mN+7EtQ5HtkLKp4F1eOqb+eTIPpCPYP8GyzUGDcFG0pdzhcHvqOKOd -sRYzkxyf/f8DE+6P01F1EPTql8pZLLirOfZjUtboUY3gZr2JQ03RzTk3dcjEr4pI -wvQV8rAkj3GE638iBEByzQb/HHN+c9fLAM7f1IDcHS49jZj1gCiuCAVlf52zUmwd -NnBgKyVrEVhf02sDgXRpoTmoRfwmcMd2cWGvDmRiijHo +B2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCHyxiIjR9Z +m3tznMc8OqAvm5h14DAUin+2eq1HzjQZ1fxkTtP4i05ieppHLTxfJrM9mH5H6sb3 +NSNtX/L7p229tM3on8UPUZRp7qDmFNTpgdRbf03ZJFDp3MTprA85wq++gc7GMI6q +QHhLuc3gshuy4iFzVfrWE0MRF/aVkEiH91iNUCZ3vZTahDG/jTafyMYnADE+26mj +fK8yCoTA6qYnYQrMPy3jcr0g3aak5+z5Gn55qIJklaAXV7vAyoNgYIq6MjXs9J0f +kedZWwJTEfAarZDo2s9wEQi7McPzv4HmNB3H6JfJsAVgaD0WtQcAVr7Ngr24lIx4 +AMY7koGayD+VAgMBAAGjXDBaMBgGA1UdEQQRMA+BDWNoaWxkQGV4YW1wbGUwHQYD +VR0OBBYEFEVZPH+Sg200JF29GN4RJ13XfpIWMA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBCwUAA4IBAQABo0B3iS7ykcIBRflUTQtd +ji60ZVsX+pseEvpFvlurdKR4vrhBu/5LImQxk3wMepEhyzXZbKBanWJjgZcfJBKA +XqWFAPu80WPunonxUpNdgKMouRBCmzmKwXojzafpZUKTZKEm7q8cbE7u1Eye8Ipv +uj41TMlIpGvJnjfGKugJh2Gu+5Sfl7P6h8nLvM5dkJW8WsRRMGc7vFEXKCvsZbth +wclhJXWciI4wsGUENTPpqxWhO2uj80/ob3rUNgIwROKeyBWXPUVKCme4AII5Cqk7 +qwQzNIRwWofBIb7TV2aICnFUHb3NHZEjMacviaMI+Nl5ND+gDAdc8YQmXrSHg1fW -----END CERTIFICATE----- diff --git a/test/rubygems/child_cert_32.pem b/test/rubygems/child_cert_32.pem index 3484803a20..4e2fcf10df 100644 --- a/test/rubygems/child_cert_32.pem +++ b/test/rubygems/child_cert_32.pem @@ -1,20 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDSzCCAjOgAwIBAgIBAzANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv +MIIDKjCCAhKgAwIBAgIBAzANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTEyMDEwMTAwMDAwMFoXDTM4 MDExOTAzMTQwN1owKTEOMAwGA1UEAwwFY2hpbGQxFzAVBgoJkiaJk/IsZAEZFgdl -eGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyn+/tatHETIQ -v0TOloaaJ/+SMbkr3twgscXTdC3Em1IrBTJX9vGY/kueOUihXOoBxXJ2C2WbMhpu -BVhHeA4TaYP5IKAz7jxsEKdgxDryp553gf0oY/FfuqC6412mRQLvEPdenOfwS8/j -5RyCLDv0POuVzivuc9bGYtMb2pfEE+7uFLK3MvOoHr35Qm6QQFpDT2vw2Q6gPZ5N -Lwdlw0h74Wr3K2C3w62AJxc98Ime9C2EK5nXjqpD6WosP/0Kc6qfr7bhdm6+lImF -qTfnYXRbCMQMCBOZFmdZJOjgSeJB76/kofDqm3+lhQYVv5UGvcJXQNMYTcIRq9RQ -xHwvtIPwbwIDAQABo30wezAYBgNVHREEETAPgQ1jaGlsZEBleGFtcGxlMB0GA1Ud -DgQWBBR81VPTe7JJSgT6xxJcaGd9hYOuCDAfBgNVHSMEGDAWgBRfQ272mo5FJeki -4303XqTVNgKFGzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwICBDANBgkq -hkiG9w0BAQUFAAOCAQEAhHnhcklUtCnLXVr4aCgdNgeuBMqT/v7cJFWGjy0s0isu -zsAHZ59caMGonykuZWwxQE2ytzMhz1fC1mRH5kfYy2h2uFHGzaexrK4n2BX0HIE+ -XFyZxDW5kwKrpmXrEeo6JVWftCoINrw3eY3iuQc3pKpLtGdir4MKByM90CcjHxzQ -RFvI9JzRY5TmY3nXdP3JNi4rNGZULEl+Hdm79LS6yrXthZQ4dqeMqJqXLggdVPf5 -5302z//0QKi+nK3UnTi5hbEOC9xUW2n5Yj2dJnSkD/aQFapobMaww8SbbOJ3IMK0 -hsI7EPoqOCw4egbv9SlvlVOQTPDqpZfSfT4Id0AnpA== +eGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh8sYiI0fWZt7 +c5zHPDqgL5uYdeAwFIp/tnqtR840GdX8ZE7T+ItOYnqaRy08XyazPZh+R+rG9zUj +bV/y+6dtvbTN6J/FD1GUae6g5hTU6YHUW39N2SRQ6dzE6awPOcKvvoHOxjCOqkB4 +S7nN4LIbsuIhc1X61hNDERf2lZBIh/dYjVAmd72U2oQxv402n8jGJwAxPtupo3yv +MgqEwOqmJ2EKzD8t43K9IN2mpOfs+Rp+eaiCZJWgF1e7wMqDYGCKujI17PSdH5Hn +WVsCUxHwGq2Q6NrPcBEIuzHD87+B5jQdx+iXybAFYGg9FrUHAFa+zYK9uJSMeADG +O5KBmsg/lQIDAQABo1wwWjAYBgNVHREEETAPgQ1jaGlsZEBleGFtcGxlMB0GA1Ud +DgQWBBRFWTx/koNtNCRdvRjeESdd136SFjAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud +DwEB/wQEAwICBDANBgkqhkiG9w0BAQsFAAOCAQEAR53288aEhg6x3zMHv0Y8ZSqB ++xPTrKzouqmHdaFBvEowIkfK6V29A2LAoIBi5DfsnkbKMGCD4mOlX3ipGoi7x2CZ +UspOfXQ93CdiG9laS4sr4f5ZUJR1sc083UT1PBwqtnajjVUPxYz9I8g2ZxxawmA/ +bybbft/l4xHDv7RUP56uzm/BoCyiUdEC9gvq+5NYS95+M7v2J/CsvV34d5xnb8cl +49zOoboN1JoZErPZ2dGnxpHvExOcQhz6CVUIEPri5eqRae+zln3RRd8RJ4gPe1FG +H2aDHUwX7NKxY5Xq2NT2vUmnhTmNzFT5HC9gjG8Zu+2dPw0tTZNxyuctSAhAgw== -----END CERTIFICATE----- diff --git a/test/rubygems/child_key.pem b/test/rubygems/child_key.pem index c56d0699c8..61fdfb628e 100644 --- a/test/rubygems/child_key.pem +++ b/test/rubygems/child_key.pem @@ -1,27 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEAyn+/tatHETIQv0TOloaaJ/+SMbkr3twgscXTdC3Em1IrBTJX -9vGY/kueOUihXOoBxXJ2C2WbMhpuBVhHeA4TaYP5IKAz7jxsEKdgxDryp553gf0o -Y/FfuqC6412mRQLvEPdenOfwS8/j5RyCLDv0POuVzivuc9bGYtMb2pfEE+7uFLK3 -MvOoHr35Qm6QQFpDT2vw2Q6gPZ5NLwdlw0h74Wr3K2C3w62AJxc98Ime9C2EK5nX -jqpD6WosP/0Kc6qfr7bhdm6+lImFqTfnYXRbCMQMCBOZFmdZJOjgSeJB76/kofDq -m3+lhQYVv5UGvcJXQNMYTcIRq9RQxHwvtIPwbwIDAQABAoIBAEJkNgerG0bRAlqj -hZQml35LtbPlwTN1OqbudFCf/NjrzL0Mb3jAZ2fghQTFAlrDQkdpKri73HFF5xKL -igsbmlO6+EAxJjWSy9998SUFKq+4LfiJduelqLw4nG2VM8Fmn9kRMY0CIm/IvjBM -84TrNz2OA/SvxKNoJG0cSAKYRao+00s+xNIu8lr6CqvXqnFO6gzbxQvJ0J0TnKVf -AezArZZI3VaPXmC8yo2U6v9r7/2txr12QnDPDk9YMwJ7OR+7qzujAPvtHy44t4en -AsTetle9AXveIBC7zpl0pp27wN8tKIdh8n+jxPfES9ecn4FjfreWiwzzZSSCitqQ -p7cQdTkCgYEA9U/y38KUjV05FO7AeeMJYmy/o3WxjcZF8lUtuCsGzogD0JbnNj7R -BF9TwlNnkeSJsPYKMG17dnoZhgY3J96mWhQbEH9CyXNdgQladE9/qH9gCCW9BXyo -z3urNc77F/44J+1OoegpWGS8Hdm7OGsESLF1wLet+5cRbVHtU2brqQMCgYEA01JK -AnATj+vACcAtr1Gu9eGE/6EqAM+H/bfQzGtqkxEmY8QihW//XWH/vOZDVZZYLUoc -9MkSUHNGwZ7ESAgoZWc1D5xxp3sT2+vV192TS+QBe3TT5AXhAGH9uL+qz7Gz4ihH -ebt4p49u5SJVY+3vv+nck/YgEiBw4PrfwSdugSUCgYB86U/XpoH0FaMKSKRTrErM -BmnytuxJL8vQIJVeMPKPWezvWtey5HuUCWJiEgwr2r5OEIqRrD3wzy2N9D5Dm/kC -5zf8x4BfidHz8apQjWaIiwuAOo8saxSeSe+dP57V0coQcqLWiJv8+ZZccNEHYl7V -ER/PmPgLoxnpm40IKeEXtwKBgCwUEAfuJMZyYD4obd8R5LK49ar0jPRaVX1gqBbb -mQFQJHfO43x93gA2fseCKC1kDMR1nxCYGE/bm7irSznTKcns+y5kbXiHvZ6z1IkQ -WLcNuhlsRv5bE5Gm3ut4X0KvSFw2FqKXrhUVYAY/YRxU9xtKxo2+WvYs+h6TdbSu -auhZAoGAThhKJW0Rf+LX1zlVaq+GXrj2rkYVSBwChMHbmmp49q6crldfLi15KbI/ -LRoUwjnQLQVNT0j090/rlNVv+pcQLqZ/pDHXQOMwrYuhbbLsda/FqTo3Qb/XnwHX -qRrjdgGk5OC3gJt8EaHHdq+ty/eF4xQ0fUPMvIj8fwowxGyextI= +MIIEowIBAAKCAQEAh8sYiI0fWZt7c5zHPDqgL5uYdeAwFIp/tnqtR840GdX8ZE7T ++ItOYnqaRy08XyazPZh+R+rG9zUjbV/y+6dtvbTN6J/FD1GUae6g5hTU6YHUW39N +2SRQ6dzE6awPOcKvvoHOxjCOqkB4S7nN4LIbsuIhc1X61hNDERf2lZBIh/dYjVAm +d72U2oQxv402n8jGJwAxPtupo3yvMgqEwOqmJ2EKzD8t43K9IN2mpOfs+Rp+eaiC +ZJWgF1e7wMqDYGCKujI17PSdH5HnWVsCUxHwGq2Q6NrPcBEIuzHD87+B5jQdx+iX +ybAFYGg9FrUHAFa+zYK9uJSMeADGO5KBmsg/lQIDAQABAoIBAA9dClPKuakK9xLr +wjvdeymfvkZZ3L66M7xa0VeOLCVfKTzVEVTtt+ra6bETXGD8kStvIRx0YtntvGof +wK85sGgV+HTw/Jvg1DyO98vIQBWCL5tBgjaGzhPDe1Dfu2JC1VzltVYFgOKgxCt3 +JGSfahRZUsUIjYZibARXVHnz9szRJFYg3lzBcVeCMWDGlPVydGaV3ttrhs4cFgPk +1TinEH80K9GfpZvkH5/4O1E2uVFetSLONRQiTs+WXpx9flEXP+mNwdrjECI6xvIP +x7pMfIo9kI9XniXXTvbGdEIeVrOL5OpW/nBCA3+EsL9S72TBVaMuiPTqUPlxA8up +v/oS2qkCgYEAu7Kj1t2M+NJtR50wQ2g3efY1qO3dQ41SCnoGEWJd/17riNV3u7Xw +FwPpnpcQAceoctK095JTtRTFGRN6FPl0VWuEsCS9lnwLzS7mQXiBg5EO7474v2Ki +JPgncJefmCbtjJwaB78l+ybk9iUkdRv80QCHqdeHA5CegbsnDGkcJSkCgYEAuTUx +Tfd3zpIEz0qhUf1D4PpgtoTj1zbXIUEFWl1SkLqklTF7k4LXZoWj7i3LraFk+jC2 +769qkLzF0CTHRFr5d00v9tCDOT5Sv2lqJw5UAmouKSuLF7XBp5tAkICkFX7Lo61v +4iS2HtpK9wzri+L2XnDD3bxcHFHsEaxuD0V6iI0CgYEAp6Nsa4pizxT53z1IDtw0 +uCwrTt5rgVrlzE+hvcMSWvPG/+ZQUwmzDotDC462EDDnhO4mDPvW4WNUign4PmVx +/pzR3JRj89SEodRieFUNr5lOMq2KAz0vvj8Y0pnJQ5Z5Ed2V7hdN79uUITeZMTM3 +AOAtSochohB3UTz7Kj1ykskCgYBPXZAHTSi2CLSu79g5fkJ8Qk73Z/MK4qFFyss0 +chFTm+ezV0URbVxIvrQE+PLzMNpIrF94Tr9nzr0l+Ny7WhDVIuqO5cOV4DMte0rV ++bneXwnw8ovkWSrnXAxK4BVwcKlrNoNfcUPp7Ll7LLozc8sHpWMJvhHqwOBcont3 +Z9qecQKBgAiiWHPgMKChKDg/JVQGEqILF67c7ZuzBMtUHmGNVn8NNr++NXZ4YIRB +/TgYNXySTgEuD7tUE6B/iO9Mp1CpJbzRtdk8oqJlgJ4rza50N07k/SGIIWl7hAr8 +No1ibENOfw7aeMKRz3udLT50TFoluykWc/m1nJEaqtSEJLkBRM5c -----END RSA PRIVATE KEY----- diff --git a/test/rubygems/data/excon-0.7.7.gemspec.rz b/test/rubygems/data/excon-0.7.7.gemspec.rz Binary files differnew file mode 100644 index 0000000000..159bd4bb1c --- /dev/null +++ b/test/rubygems/data/excon-0.7.7.gemspec.rz diff --git a/test/rubygems/data/null-type.gemspec.rz b/test/rubygems/data/null-type.gemspec.rz Binary files differdeleted file mode 100644 index bad99289d1..0000000000 --- a/test/rubygems/data/null-type.gemspec.rz +++ /dev/null diff --git a/test/rubygems/data/pry-0.4.7.gemspec.rz b/test/rubygems/data/pry-0.4.7.gemspec.rz Binary files differnew file mode 100644 index 0000000000..58fc1ed8a0 --- /dev/null +++ b/test/rubygems/data/pry-0.4.7.gemspec.rz diff --git a/test/rubygems/encrypted_private_key.pem b/test/rubygems/encrypted_private_key.pem index 868f332b7c..2d0022a6c0 100644 --- a/test/rubygems/encrypted_private_key.pem +++ b/test/rubygems/encrypted_private_key.pem @@ -1,30 +1,30 @@ -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED -DEK-Info: DES-CBC,4E38D58B5A059DB6 +DEK-Info: AES-256-CBC,4851D8D265711252BA5EAD983C957412 -IgWLfnHVnkErKkhysrUMoE0ubkRDtJXZv9KR02jGGFk/kGqWyTqPk08uzhwVNM+l -eOk0qfPykkJM3KZgqTsD6xfA1D5WqFp5mLoFXVVTn9I3acSZsqOY0FweCipwdVpI -x+9Fl+v62kIW06dOjyWLE1abed9hHiXesGGsD87/RJSywy4OBxOcrhR1fJLK4ElR -ya0UzI7rWnmZMChjaZBssfzT1DR79/dARXhon2m5EiIJDjMpc8BKGYlQy5RHCHwA -cnrhUTTvsggZbQtmLZ/yVx8FSJ273XpYR0pmwbw4j1R+zeXQRK5MroBnCfOGcYa7 -rmpERmDW3VAuxXR20SUAGdo1XOMTDe1uLbaotn6e56pXghIaYROTPS+HsuOkAZGY -OYWEkUoyog4l4n+h/C1umFfTFGvKNATLgDugONFvTw/PLbjvl+sWMy2QfqH0MlNB -DIUPxhEVCFD9oB4nfB86WDAmPp1DH9/IBet/21kbQ2eTIzakTdG3XiC+xzAQRu68 -EOCTbasFWGxlCix66gt4xWMLksEg8UhWSpjS3/HsifrKyNMB8sfUFYmZmOYMW4mf -NuEtpBL3AdHNObN8nQ75HfehukzNpbYVRsLzWrVgtxvXHVpnvoCCpCvQBMHeRZxK -6m028mhH1m6yYE/uGFiRKLrN7BKAttbUiqnGgVIg/lQQilFWwylxQ6aXqJGmNgxa -oihzWZRlXivIhhrM7VMnLoKAF/YfmWpP3zahGpBQGfObtPtm44R0ezXPdtsivnyu -CmFOPGzRNMKZtH/lwVhuIIK3AFIGDsRRP9ySN4YfjQZnTdu2sRlxBnANP9m8W9T2 -p+C4zVkDYAbsuWq2HpHwsdL8gqIiXeptsHLqkNw+ulSSLyeBCgM9fpV3RsNGjwqu -k8QLb1CYp2VX46CE8UKvOd/nyFnEsD+EAc3WangEwA41m2IaXcbs9Au7xsG9oacZ -DrxlJVNxlxO9YyP9dNOTfP0fHIiygKQQY2aU3y3oRneu7ogYES5V2mUNH7cYUWVL -CHPXAoUXJErvDQ/opW2DroA9Eqv9sST6WqBf6LXRcWU0ntfzcFUbEqgmCmB7Cbu2 -8udEn6iWilQahLyDoAShLkU7+Tk78Z1c6RuqjyY4VboZPzxrTYK8YIXzwX+jj9bG -KIIGS5eghK185+AjlwtzJ7MBdoL323YIik6uOZluhnJHLaxjxUXGa1VqDgsyqGi7 -ISRMTpVTrbR+UtoEi4ZhMjobtFUr7lGkt24VkXwBKdoyryj4RPHGdp7Tf6XDJufQ -+KKhqt8QrpOTPiMskFN2disOSF5/YZCmtT84nkhU7Hf1lkQ2kfx1zfNk0GqYYXOW -zHOAczy8gWBRetDMnhRYohDzQGWn//b+2Wr2n1RD8D9kyjMRhpFMYfQGfRcuPGjW -91k/T0XFcjcjeZPL9s+HITmrh7zg5WxbCfTEp91j3Oy1bns196SY77TE0BzUsqR2 -geJggcUMEfyvHiiCMtijmSSD9nf8tNIxLVL8Jaf1coA6e1CrlHnYAu2f/Q3GIcvU -EEEmw+cZRwsk4fffYzh5psxxGdXKBv1KcQ/CeBhZL0WJsCp2y5oxwg== +0CH43Il/Lamd5AIkeYFRdCLJUUiUAEuAlE+DDYJ+Schulv9Lp+Au00VvAH/VVdqP +jFzEJ7FIwcPac2y4SVSa8uMGdzezVhduMz3yrwWNSUPFAJCLazh4FhGMmK2kYRfx +IReEBebwr1x+e3VqoREfTuwxQqpA5Ho7dgnrzSf2UeIQrnXfDh1rIn3SCqb/xYDI +qqQ9bPlDs9iY/W24KM/ZfWOB/Dr6SQXXVDu1JS8EAxB9TK4PRMHZIBlIN+OVzju5 +v7FDysTu7g2BTH9BeHs4lWFpsUdJmrj0GjGoM9DCH/6xdPHQSWKpDptFu+06htBB +zyr2chX5RMjlPxApqtz59YJaHLNhI/nABIAJdEvAgG3CAiYHB4G+X5kQwIYryJIt +IeD8oerxNtNOVzunGL/QvYyiLB9EcDEBfPUIlriPCpTFz7r/GCLO2wX3y0u6m631 +rh/tVRPMzWTSd4HjJiBQZU/d2bVvdOKKY12b1ieai/QiaO7HjgrcVAgWLwJB8XKr +QkXIo6W4uZv+W0YVTVQ5lPfwdNY6eQ1ZWPnqIOoczAZtFbs3zdBobgoIjyQ6cEgq +fgRsIjJmLVYq39F2oDX7bLdUK5UaPgHWGbNi07cOIn0hqo6YNCw1YaQikUw4qfBb +golYKoSV73/M6IVWlTjuzP6CRDRHY80epQjA3FR9P7ToT2VgcsG+pKxoYjZxotGm +/E4PEEl+9lxNN9IXR4XuEzWSGTOiNUZ+iVOJIyNQN5tC8k6yYr08s12b9LVzvG+q +Ro/bD/3UNaDwfujoSNgwKelZPBZmSkJIUECNDXE2i4hr6WqoJu7ZhpO5f/iU5d+i +Ea0bbSne50zlYoIMIa7YG01zgI5Y+sV8BWSwwK+FaH5dORjpRUVat/yIw/Qx8VZ+ +f9RIfMnOShf5zvXIX8pF+Cayf8nPk4X8rhwrd+gL2cthHlYa58DkfKpJ4FxxRItJ +mQ01K29PuQPYBdTXN0A8jurxQgETdM2R0JrLCnDOEleshUJqdsqC69Le5Sn5ucui +ZWqxHjm+ycF4OAO99oq1T9QDyUCtIkMXPpf982KYVyzEbNw9hEr5/0CZdCaMEL4M +gecBM9rpYeWy0ndmZ/Y9rBdTT6+en2WnONKQj3nCgL8e59y9S1VG+sgQ2LwQ2nxJ +Mj2CeFi4B4D+2JdqyDKRFXfGKmzLIWW5Xw7/rrnMc7NtWZjRmUkvAOk3ILC81AmY +QPCEuqju5q9hasKfIDBnB7/eNscAvf23Aa/P3A0NBTPcTko+M+Pkpc82m4eXx1Aw +MfpfaIcfgPI4LEo+d8IfT0zcPNDuH9ACCcYa8/4q+PnKCmOsxgZ9wGpRHOQ2QfLR +qTus6c0l9zab8EWJZBnQvuacUecU64OAryP3QAWZl/NerHsKZ/i9ZIDXtDIscCHl +Yylu68l+vBZmfD455QN3iPVqSm4valJTGZnk40STtf8qLAuXdVhbyI921yGIz63n +dcRx9+wd9M3VQqmvbrri8FuavTn9/uMMpKeOeR3AIhci8EJdLxhvz2A3+w9cxIO+ +Imj0syk5TWH0c3menzkYe2cO4P8jqBsb+QRdNcA2+YSTpEsvS7Tqvogl/RWnv7r4 -----END RSA PRIVATE KEY----- diff --git a/test/rubygems/expired_cert.pem b/test/rubygems/expired_cert.pem index c76fe4c58f..12b8836607 100644 --- a/test/rubygems/expired_cert.pem +++ b/test/rubygems/expired_cert.pem @@ -1,19 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDCzCCAfOgAwIBAgIBBjANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv +MIIDCzCCAfOgAwIBAgIBBjANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTcwMDEwMTAwMDAwMFoXDTcw MDEwMTAwMDAwMFowKjEPMA0GA1UEAwwGbm9ib2R5MRcwFQYKCZImiZPyLGQBGRYH -ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdlNYcvFB6x -gpT8QcnMybVelGLUKyQL/hQPTK9J5FyqB8hEDLt2ruMwKsHU6fu/mgG+sLvHF1nq -WhZADhn6rwCfNP03025vktOZ6iJfU60vytY/f3gkiGNkP21l0hz0+Ms15f+52gk+ -sFXqwGBbDteI0x57UsHi+KAN67QuPDnthYDtwhXIA5pcdx2wH+NW8F82HEZvm1hc -pA75BDVk4vPxnpDfvPOKSYn9dWghmUtaPmqyVvs8XkDxHDfY54/D3ziPehP+zQzE -g8C07Sq/z6vLSOQ3uaYn0nBDuNE6XP3ijJ4Zvs2eJEdOMyS1H3CsnkWiePCrLtKd -w8d/F+D5bocCAwEAAaM8MDowGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwHQYD -VR0OBBYEFF9DbvaajkUl6SLjfTdepNU2AoUbMA0GCSqGSIb3DQEBBQUAA4IBAQAP -Z8vKQ1OjQCHx8MJ0gy6WN2CIjh0Uqf3fSfza3nd+K8jlJPkF7znEBZ345iCSmNwn -EPrz/OrqiId2OHW2OCJv3c9NEb7hgaTswGfdq9LmqMRVeQy57FWh2lRdjVZbquWy -IvM72hjVLqnMVisWbDxf32YghnmT37SzZKsHSXU0xUx7rVSIShnoMjLWQtIQDoqI -3isMAeKals2NNJOy0TGKJ9SspIDl/IYm9sEO1HKiuxubrdN9q+wEQdizt59sXkol -4AYga+5TN+KtsSRclAGjfKYfuRrQ85IbVsRhQIYX1ZOJtMseEhBRnIeySKV4xWsi -kXAaxX5wIyoM+S1vaKcu +ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANFC3H6Q26GO +bllXTiJBeALUbouzzxaGinwZeYYhhXKWEcfA0D8k+22w/JyndeEYc29JxwjFNwxM +/DyyQplptzbM1Q5BCcLNQaQhmpOryosjWuYWW1JUDGTG3nEg0qRCrtjwVoAU++Ko +NkQboM0wFQJxkBns0J1sr+O5Ml73YzKKtdVWWvg89osxyb4wRxkEoa9a/b9/aiK7 +WoeQhF00cRKoa/eoIN8usTjzKsYudHUtEQWibD7IxWdY3nMntGf1jyLYi40lVUbL +FFytWtlZGMVKpMVIOMMCQ+ex+ExGQaJrQF5QEqPq1L/BvXgTZkv5P6CS3YjBdVC2 +/ntfos3gMhsCAwEAAaM8MDowGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwHQYD +VR0OBBYEFLEaVAlnRWACAtfO9B1gSonf51jZMA0GCSqGSIb3DQEBCwUAA4IBAQDI +x70p19RI73Y9AEfBd0Wmk7KsZQyP55kjTAdaM37crhmClkUQRrk/Y2a0pXOhsrNI +0YO7t44fJKwMu++1dxh/bllKbuOkca6ApxTb2IfhOejx3IXXWzp+C1F9pmG9q5QW +0FDt//0SFZJIqDq9N+zFiA2z0MM1L7X/r29uUgAqkU7rsytKavHXru9EGQrrkxwh +5dM5VI+pnJgk9HYpBDPwiFVd0yFelebqdlv/nnW11tVBMTkMloVYyhei5yZbWKFk +f0Aj5g94+S107oRMyzq5e6lxQcJBhmKfOXqGaz2wue3/IHnwio9dMArayug9GLEr +ycy6PubJImhM/dboDIdO -----END CERTIFICATE----- diff --git a/test/rubygems/fake_certlib/openssl.rb b/test/rubygems/fake_certlib/openssl.rb index c7f85140a1..928672c7e5 100644 --- a/test/rubygems/fake_certlib/openssl.rb +++ b/test/rubygems/fake_certlib/openssl.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + #-- # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # All rights reserved. diff --git a/test/rubygems/future_cert.pem b/test/rubygems/future_cert.pem index 05d3f9ebe3..06e08bb4c6 100644 --- a/test/rubygems/future_cert.pem +++ b/test/rubygems/future_cert.pem @@ -1,19 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDDzCCAfegAwIBAgIBCDANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv +MIIDDzCCAfegAwIBAgIBCDANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCIYDzk5OTkxMjMxMjM1OTU5WhgP OTk5OTEyMzEyMzU5NTlaMCoxDzANBgNVBAMMBm5vYm9keTEXMBUGCgmSJomT8ixk -ARkWB2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCnZTWH -LxQesYKU/EHJzMm1XpRi1CskC/4UD0yvSeRcqgfIRAy7dq7jMCrB1On7v5oBvrC7 -xxdZ6loWQA4Z+q8AnzT9N9Nub5LTmeoiX1OtL8rWP394JIhjZD9tZdIc9PjLNeX/ -udoJPrBV6sBgWw7XiNMee1LB4vigDeu0Ljw57YWA7cIVyAOaXHcdsB/jVvBfNhxG -b5tYXKQO+QQ1ZOLz8Z6Q37zzikmJ/XVoIZlLWj5qslb7PF5A8Rw32OePw984j3oT -/s0MxIPAtO0qv8+ry0jkN7mmJ9JwQ7jROlz94oyeGb7NniRHTjMktR9wrJ5Fonjw -qy7SncPHfxfg+W6HAgMBAAGjPDA6MBkGA1UdEQQSMBCBDm5vYm9keUBleGFtcGxl -MB0GA1UdDgQWBBRfQ272mo5FJeki4303XqTVNgKFGzANBgkqhkiG9w0BAQUFAAOC -AQEAM/0YoOjHEs1zdE6oG10XKdDcYn192AYhkMaITrfJUJiVUYehmcC+fa7aV5Hp -CYasFm5SawiyHwcI92GROaM97gJy7Tjpg8zcpkXg/vUA/8ItzD0UYphs5efZ9B3R -zOfxQDasTZJgg0uCxw23Bil7Anf5/KipuiU92Cc3fjpI6jWOuezGWqSqC2KGJLM+ -S59/oLqQNR67j7WBH3lHe3qbUehpNPkSrTdcLEbvspZM2udrRN9QYUUwBxD9dMlB -eC4hADgWEh5uPZO5sM2+qUdyIRa+fDUpcbTEhLQy6NceHuCNLK230DdC2xszrtNY -yNFy3B5BHgxfZeycaC4pMED0gA== +ARkWB2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRQtx+ +kNuhjm5ZV04iQXgC1G6Ls88Whop8GXmGIYVylhHHwNA/JPttsPycp3XhGHNvSccI +xTcMTPw8skKZabc2zNUOQQnCzUGkIZqTq8qLI1rmFltSVAxkxt5xINKkQq7Y8FaA +FPviqDZEG6DNMBUCcZAZ7NCdbK/juTJe92MyirXVVlr4PPaLMcm+MEcZBKGvWv2/ +f2oiu1qHkIRdNHESqGv3qCDfLrE48yrGLnR1LREFomw+yMVnWN5zJ7Rn9Y8i2IuN +JVVGyxRcrVrZWRjFSqTFSDjDAkPnsfhMRkGia0BeUBKj6tS/wb14E2ZL+T+gkt2I +wXVQtv57X6LN4DIbAgMBAAGjPDA6MBkGA1UdEQQSMBCBDm5vYm9keUBleGFtcGxl +MB0GA1UdDgQWBBSxGlQJZ0VgAgLXzvQdYEqJ3+dY2TANBgkqhkiG9w0BAQsFAAOC +AQEAATJNbSaVk8fM1uhqQnlBiQ/0TzchHADy+WmsbIbOiUAc8c29sjpCC4x0o5Gk +Zn18+BsXUjfyF6zyY4wPABZp9SCDIxvLxP2QVmbCtY2TJeKV95c4mWEnrFcCqYZ/ +je13m5iLnAu1WqVjSbFn1KamTf25pfBd9mqgQVwrdJMGoviJC18LyKJTZs7aV+Bu +tsF9fVMIP8p1Xu0Es/hBXFRwths41seqT0dYFszhwTCBC9tt85TTixWmEXpdyrov +vLFULJg4ijn9YZeKMViC6V3zgHUl9ZnMlWdFpVZ6cf7kA/1acW1ESEZnARLQhvMF +a1gof1D2Mj5k3AtQJ2TtPXytxw== -----END CERTIFICATE----- diff --git a/test/rubygems/future_cert_32.pem b/test/rubygems/future_cert_32.pem index aa74bdffbc..c023110141 100644 --- a/test/rubygems/future_cert_32.pem +++ b/test/rubygems/future_cert_32.pem @@ -1,19 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDCzCCAfOgAwIBAgIBCTANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv +MIIDCzCCAfOgAwIBAgIBCTANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTM4MDExOTAzMTQwN1oXDTM4 MDExOTAzMTQwN1owKjEPMA0GA1UEAwwGbm9ib2R5MRcwFQYKCZImiZPyLGQBGRYH -ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdlNYcvFB6x -gpT8QcnMybVelGLUKyQL/hQPTK9J5FyqB8hEDLt2ruMwKsHU6fu/mgG+sLvHF1nq -WhZADhn6rwCfNP03025vktOZ6iJfU60vytY/f3gkiGNkP21l0hz0+Ms15f+52gk+ -sFXqwGBbDteI0x57UsHi+KAN67QuPDnthYDtwhXIA5pcdx2wH+NW8F82HEZvm1hc -pA75BDVk4vPxnpDfvPOKSYn9dWghmUtaPmqyVvs8XkDxHDfY54/D3ziPehP+zQzE -g8C07Sq/z6vLSOQ3uaYn0nBDuNE6XP3ijJ4Zvs2eJEdOMyS1H3CsnkWiePCrLtKd -w8d/F+D5bocCAwEAAaM8MDowGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwHQYD -VR0OBBYEFF9DbvaajkUl6SLjfTdepNU2AoUbMA0GCSqGSIb3DQEBBQUAA4IBAQA6 -lip2nqmXyhz1uBDAxlNAv9nN2JPicWpRIvQ4KLNwmZKnagPWfleZ4TbLqsn723w8 -lD2VqFNX/Vj1XNuEJg8pXME+qxbMgtWxGsXC0z6k2Q3rT81QTdhXJ7nqdoe2i8y1 -423Fft2L6Dcgmx2USJwZsNy53pK9smxI9NipuRtL4W34PHHpaFsC2646daxZ2F8M -No3R9C4CtSFJDrM0XZoFiAnarbqoGCJs2q0NtcdV8D5m6xGeNShWJMLNbVx4DgsT -E90gVxVqPaqm5ytAIfdPWVUsyJBoD15jDVH5AZtkBmFRNoz60KPt3HpiRPspKWCd -tVabH2JRC0wDYRwEEMKB +ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANFC3H6Q26GO +bllXTiJBeALUbouzzxaGinwZeYYhhXKWEcfA0D8k+22w/JyndeEYc29JxwjFNwxM +/DyyQplptzbM1Q5BCcLNQaQhmpOryosjWuYWW1JUDGTG3nEg0qRCrtjwVoAU++Ko +NkQboM0wFQJxkBns0J1sr+O5Ml73YzKKtdVWWvg89osxyb4wRxkEoa9a/b9/aiK7 +WoeQhF00cRKoa/eoIN8usTjzKsYudHUtEQWibD7IxWdY3nMntGf1jyLYi40lVUbL +FFytWtlZGMVKpMVIOMMCQ+ex+ExGQaJrQF5QEqPq1L/BvXgTZkv5P6CS3YjBdVC2 +/ntfos3gMhsCAwEAAaM8MDowGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwHQYD +VR0OBBYEFLEaVAlnRWACAtfO9B1gSonf51jZMA0GCSqGSIb3DQEBCwUAA4IBAQB2 +EjAxPVbDwoYehhEJEiMnMWk8GL6oo1uVwGJgCM76Yml69FVyWrre2GcSYiv+9f7K +AzE9S2uREeJuGcSV0VR0MeXoHXwQpQyBV12gCL1eQH15oxFfTi9XbVLhh5CyTKc1 +J6lYtQVpZPlLRoJN3oBq3J8PN8hWBWuhb2VIrpHXNBXAMOZ+hJM2B+EYifH6tcI5 +YK/Bw5Tes81QU4stQTLKybJzQkct02Rm7bYIM3GX/FGMMEPZE4jhnQ5btSNYVBlY +HXh6qfZVhZ8qpAy50yrlxROLa5zJSuTQ28QWh95XLzzHiHJ4Q4qZQzhcRGUQLfM3 +X6P8rtGWzXtB++CKKQIG -----END CERTIFICATE----- diff --git a/test/rubygems/good_rake.rb b/test/rubygems/good_rake.rb index 4a05ae4a13..bb0ed9fa80 100644 --- a/test/rubygems/good_rake.rb +++ b/test/rubygems/good_rake.rb @@ -1,2 +1,3 @@ # frozen_string_literal: true + exit 0 diff --git a/test/rubygems/grandchild_cert.pem b/test/rubygems/grandchild_cert.pem index dbd14bce80..c1d9887b60 100644 --- a/test/rubygems/grandchild_cert.pem +++ b/test/rubygems/grandchild_cert.pem @@ -1,20 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDNTCCAh2gAwIBAgIBDDANBgkqhkiG9w0BAQUFADApMQ4wDAYDVQQDDAVjaGls +MIIDFDCCAfygAwIBAgIBDDANBgkqhkiG9w0BAQsFADApMQ4wDAYDVQQDDAVjaGls ZDEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwIBcNMTIwMTAxMDAwMDAwWhgPOTk5 OTEyMzEyMzU5NTlaMC4xEzARBgNVBAMMCmdyYW5kY2hpbGQxFzAVBgoJkiaJk/Is -ZAEZFgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkfgy -EbzcRpXvpNA0s75R8gOVk7ENEPX5uXUElbzHbVEmHkC/NFsWZXV0vxGFfZrrnEkT -Y2kDaMMkfZX9rriRIvsZpxyqrdX87QfQTZ1ktDoytVnd+gw9A6AXB6PR7uoPymso -f/lZYJ8BWP9fIU39nogiptFqsgkpOtKSFjJfMILkcMAeBPs2B5HV5l4oLrpJ7Ns/ -0vazCXGakTByAXNKBagJWR43gh+RUQWF6Uh04VQTQ7ENGWI83088SKAPtCCcgKxr -ROHI025S7o7vEfDEqEn+gtu+4ndaLuRp+2AmF3YK8dEDiLXrrvEvG1r4+gIB/6tS -MUfkkJtBleZrDoIAgQIDAQABo2EwXzAdBgNVHREEFjAUgRJncmFuZGNoaWxkQGV4 -YW1wbGUwHQYDVR0OBBYEFAnex9R5fpiHNpHxq91rMog/PZA6MB8GA1UdIwQYMBaA -FHzVU9N7sklKBPrHElxoZ32Fg64IMA0GCSqGSIb3DQEBBQUAA4IBAQCYT10tUm9O -2xSGVmsbYv5YVrMr1Ucuq6Y+mXuTqqXuidILXZZl3LDwaYj64AhmMUqfITybGbR3 -sbWZrz2TWI2qWo+wcYDq+k0K+ys2PBavXdbjw4nVMf/9xYb2bCHK4bxxIG6rkmCw -zxYRTx+UivRf7Hw+6ZRtkHDxX/qPfMQK1PbmvK9c2VYXGN3+fRRIJqPnknN26Hv1 -gangMI7oqcaNwCvL16E/CpN8uwdJNB1LcCgjFJP7Ora+LIEJVe4eZvmuOYkYaYH2 -7u6CglItKwNjVZ5jULUfBuJqFkRiOxkVMVjChe9QvNXz/fkhW2sH05CR+TDyh4rD -ZeON5sdo9TV8 +ZAEZFgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyh7u +lK+O7leQKBQzSSvhEur49Xu4sQJllkVbrVvkv2jSo68woESgljSS8jCSX0I9IJ5T +0kHzNRpiuOpfWKZx7E4cKeqW6nmV7D/B+Iy1QnJbMzUdnxp1Y+CMCK0JrLIsFBnx +ndVmiS/S817W3coqkmZqce4e33/O0qmCChGxGJZuAVQFGYI25SiYWPbysVEjwXoW +6zO0D1m8QZLYYCeDSRpxKgItBoJK+Up+bm/nsrkFvUf4kAZNLgik5zvflM3/Mjyx +zxgY2MO07YaULOlr0vZN6Wxnq2F3jkuZY8JbEOpQSDGSgU2wJ1iFH+GLvj7LsBuR +ScjL0FJ4s1EjqjjP8QIDAQABo0AwPjAdBgNVHREEFjAUgRJncmFuZGNoaWxkQGV4 +YW1wbGUwHQYDVR0OBBYEFEuKocg9sisZIWu12gxzse+7/sHfMA0GCSqGSIb3DQEB +CwUAA4IBAQAFaz3FUNzDYt/Cb++6U1PXsucAy3pKDj8bUW7slJFleNsSooIA9A5b +axpnHst1Lt6i/bmvbi8F8q/0iq4PtsZvusmwVhJkCinEUZ9inddSJdxpWSyzOww5 +at8ragidzREd9Fx62flRr3GflzqIufkKN8TDjYrB+n45ijnSxDcwZhu7m/tmP/e2 +FxqODaIO9sVrPAU7YbXb0m3p3Em7RK22d0tqy1dHhcRIR5/yMQB4MSEvQ7ytRD2x +aHAP7A4rDbkRwG+LQ/4L57RJ1kU3InqpOEQnCgpwu3xw/6Alti9TXS7sGhXL4Aav +OLsFS/1BLSJx/DSSK58Vg6JFxFh6X2NK -----END CERTIFICATE----- diff --git a/test/rubygems/grandchild_cert_32.pem b/test/rubygems/grandchild_cert_32.pem index 5077a43452..5d1ad45cb7 100644 --- a/test/rubygems/grandchild_cert_32.pem +++ b/test/rubygems/grandchild_cert_32.pem @@ -1,20 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDMzCCAhugAwIBAgIBDTANBgkqhkiG9w0BAQUFADApMQ4wDAYDVQQDDAVjaGls +MIIDEjCCAfqgAwIBAgIBDTANBgkqhkiG9w0BAQsFADApMQ4wDAYDVQQDDAVjaGls ZDEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwHhcNMTIwMTAxMDAwMDAwWhcNMzgw MTE5MDMxNDA3WjAuMRMwEQYDVQQDDApncmFuZGNoaWxkMRcwFQYKCZImiZPyLGQB -GRYHZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJH4MhG8 -3EaV76TQNLO+UfIDlZOxDRD1+bl1BJW8x21RJh5AvzRbFmV1dL8RhX2a65xJE2Np -A2jDJH2V/a64kSL7Gaccqq3V/O0H0E2dZLQ6MrVZ3foMPQOgFwej0e7qD8prKH/5 -WWCfAVj/XyFN/Z6IIqbRarIJKTrSkhYyXzCC5HDAHgT7NgeR1eZeKC66SezbP9L2 -swlxmpEwcgFzSgWoCVkeN4IfkVEFhelIdOFUE0OxDRliPN9PPEigD7QgnICsa0Th -yNNuUu6O7xHwxKhJ/oLbvuJ3Wi7kaftgJhd2CvHRA4i1667xLxta+PoCAf+rUjFH -5JCbQZXmaw6CAIECAwEAAaNhMF8wHQYDVR0RBBYwFIESZ3JhbmRjaGlsZEBleGFt -cGxlMB0GA1UdDgQWBBQJ3sfUeX6YhzaR8avdazKIPz2QOjAfBgNVHSMEGDAWgBR8 -1VPTe7JJSgT6xxJcaGd9hYOuCDANBgkqhkiG9w0BAQUFAAOCAQEAnIlgmwVS3BGk -cT9LxE3bbQt1WGeLLxAF5ScqkNgFm3OvIxrKPX94WRa6tjWPEeJ9rl64QMKwJ8h1 -GzNbf0DUH8nMcSJLL1J5HUqdzwysQ96HNz54RuZ3ZF8w7QD4Kv3Vvh4IIsANchSj -unVYjcDVH9lSsbqTwC+bnUxYZ1Xu530fKZ440BG1ju9vLLZu5JaSOoJWRuHNOlQF -FbYj5AIjPwMNUidzoE9sUWdRzvARwecismWkPjfM0x1AmxVMs8hA5tS2QoCEvOxt -Hl3q6k7BaC8BRENkA/XRRIqgTMoTv86OOZIMFVaTiuHyU1XUxNHKv+ybAeAlP+H7 -hM/Hqka4bQ== +GRYHZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMoe7pSv +ju5XkCgUM0kr4RLq+PV7uLECZZZFW61b5L9o0qOvMKBEoJY0kvIwkl9CPSCeU9JB +8zUaYrjqX1imcexOHCnqlup5lew/wfiMtUJyWzM1HZ8adWPgjAitCayyLBQZ8Z3V +Zokv0vNe1t3KKpJmanHuHt9/ztKpggoRsRiWbgFUBRmCNuUomFj28rFRI8F6Fusz +tA9ZvEGS2GAng0kacSoCLQaCSvlKfm5v57K5Bb1H+JAGTS4IpOc735TN/zI8sc8Y +GNjDtO2GlCzpa9L2TelsZ6thd45LmWPCWxDqUEgxkoFNsCdYhR/hi74+y7AbkUnI +y9BSeLNRI6o4z/ECAwEAAaNAMD4wHQYDVR0RBBYwFIESZ3JhbmRjaGlsZEBleGFt +cGxlMB0GA1UdDgQWBBRLiqHIPbIrGSFrtdoMc7Hvu/7B3zANBgkqhkiG9w0BAQsF +AAOCAQEAFW6StPxdeONHUmWXUAKXNncP66aaHPAk+rQ84IvuyJKqR3UrrKdCbQLQ +LpL/lQZDkjGJSXdNHUhoB4MQsDJ8TQs2BdwDqOIvQLsZxTKZaXPfc1diFP+z/5f0 +9wbWezUateJwShDpp1RltCBmFCdibPZQUCpsgAsfqsgIWNpzhqy9dI/Upg3vECVc +c4g+EsEtiNXSbjd0kWUXCGBAeTMu4paBLVtt81fuffKJfnAKRhzrfFy0PoL3Kt2T +DkMr4MWfkMOyVlrSkvjPtW1oHVnxfZgqaE91J0Ht9qiHvekti3JDqxqcKaYuIgAL +w9HK9z5uQA2KrMvqn/jiuD8lBFsnuA== -----END CERTIFICATE----- diff --git a/test/rubygems/grandchild_key.pem b/test/rubygems/grandchild_key.pem index a9b9aef624..63635844b0 100644 --- a/test/rubygems/grandchild_key.pem +++ b/test/rubygems/grandchild_key.pem @@ -1,27 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIIEpgIBAAKCAQEAkfgyEbzcRpXvpNA0s75R8gOVk7ENEPX5uXUElbzHbVEmHkC/ -NFsWZXV0vxGFfZrrnEkTY2kDaMMkfZX9rriRIvsZpxyqrdX87QfQTZ1ktDoytVnd -+gw9A6AXB6PR7uoPymsof/lZYJ8BWP9fIU39nogiptFqsgkpOtKSFjJfMILkcMAe -BPs2B5HV5l4oLrpJ7Ns/0vazCXGakTByAXNKBagJWR43gh+RUQWF6Uh04VQTQ7EN -GWI83088SKAPtCCcgKxrROHI025S7o7vEfDEqEn+gtu+4ndaLuRp+2AmF3YK8dED -iLXrrvEvG1r4+gIB/6tSMUfkkJtBleZrDoIAgQIDAQABAoIBAQCFbg4+vpfQghBM -ZPI399oqUvJwziA2h9Kdn4TwZ18Y41vnvaHKdxUS63orihWvSmTjOL1bWsv+AJuj -nO8GvroU8tlxM7glLX2FImZb/GrogGaH9bz+bB995+IFXs9xCE4k5y1fRgxYUSDH -PLC13ffe6WxbdwSD9/HTTlaxqZvv1+UWxyYD0CSwopww5YdqISkVHq2UsmszK49X -hn6zzK+DT4YA04Tbv2Go9kCYLmsgrL2/dPJulDtJhX3AckbdkodSlBAmxe7XsKEO -TEzNDGgPZyZ+MXttBnLt1vk8ZrSJWcFG+E6DMbGUZ7rz6g98bUS1LI6PiqIp5BfS -sr0cGQl9AoGBAMGj7SCp1GMo8wOJpzzSGJ4PCc/fpG9NcTBqtmoUTuvMk4frkGXJ -dSS68KB0t0EGStbUFIZuylchC7RSzXs0uOZxkgaGcJT5qXXFP0Djy3/qoQMnJ2Yl -uhD6UsetPXbozK6MPs3mh9VqSDNbf2AM034nTod3I9sV471HZLwAhQk7AoGBAMD6 -Mmvy8DEa62VDTW6P1f4b6Pi6dOiZhGbNz5Xlh5jHplSMYReQGBVmr9szrV7qytGP -ZcBhEqTc53u2mEhSmRXQflRxJ7U2m8Xl3DClhxELHNGCJ9jEY52M4ZDJkvGj5v3t -pbTbE/g3zxmAaYZCOKIzYv5bSSStNpauxdomxuFzAoGBAJFohH97qEZSELJ+YrwU -VHIUfty/Zt5BvBaMe7CK0XzWIY72gHc+4Z2UV29WVeoZTIenuEX+2ii1YvGlIDI9 -s/8wF2SY/d+Q3wTV+prCtCS5TvFsLHTTLbbkEtdoqvgo9tK3881wKF5FMjSGp867 -svFPmPO2rpEtDdgrzWQzy7LTAoGBAK077Sea3qQ2VjqBQHGQDbofs/QU7f4gUgs3 -lrIpaqBsGZSssDxGzlfn5tYQfgJHI+sbn2wjuGjnJaaZM/s4qtQ6Zi3Hpq22aAAv -aIsDDUzvfN9WyA5/vi0g2xzu10q0qBgrziWcxUB+WRu7ev9bUxvIpYVQzUhvdiGu -o05CoSahAoGBAKoCGMGKkub+LnWazPkN2BAS6LblV+JIYWRI+DSGpz0UBk4Br546 -ozZq2GsLCQYWJabJ5RE9Are6rl9AvFQXMaWywOBe3TUz7SmLIxMjWpXKiX5YIFkS -tOiEEmET4ZYS87flEmldnmeDFLHHbMLOw5S0dJa4PyFRn6j9su8d8mWw +MIIEpAIBAAKCAQEAyh7ulK+O7leQKBQzSSvhEur49Xu4sQJllkVbrVvkv2jSo68w +oESgljSS8jCSX0I9IJ5T0kHzNRpiuOpfWKZx7E4cKeqW6nmV7D/B+Iy1QnJbMzUd +nxp1Y+CMCK0JrLIsFBnxndVmiS/S817W3coqkmZqce4e33/O0qmCChGxGJZuAVQF +GYI25SiYWPbysVEjwXoW6zO0D1m8QZLYYCeDSRpxKgItBoJK+Up+bm/nsrkFvUf4 +kAZNLgik5zvflM3/MjyxzxgY2MO07YaULOlr0vZN6Wxnq2F3jkuZY8JbEOpQSDGS +gU2wJ1iFH+GLvj7LsBuRScjL0FJ4s1EjqjjP8QIDAQABAoIBACI/cwQxKiojHqtX +3ufNXlYfB//Kjr05j36SsonRqhUv3Q88umPRtRc2gda1Wbv35JUwFrpoD96F4cf8 ++Jp0G5YjlxyYIinJX9i35fVoXDdN2ru2ypXgvRbnH7tBnMPNLfBbBAiPNhBVUOyJ +e6V5odSMM4mqBEOxK5mg/MaZgFVOrNf/DEI5oFSny7duEEQAuGJadJHUJOh7al0b +lByNVNAYNkdZMgvOdoAoyEzg5tvY9ykIwXUKdMwBgSlldolLYXyAjluXOVEj32m4 +p3rEV/vs+RQFTLLWXfyVyWoMIPYaK6nNaYpB8fMHnIjga8MzBgC6Hso3HqymRdg2 +Gttp4PUCgYEA2LQL72tzhUb+a0wo7dWJ4MY0ekyA7JxrqZRTWSNuqKMoAb6IxaXe +quZcpht/430szpOOz52pEwEEKUsCMuqwHiqmO2ZiZqYJpDQet466GFnhYhmAqV/x +bOaZLVbhGjiMQCD5YbpAmXjxF8SFbkqSKlSnpjxJKD2tGNX5FFWpN4UCgYEA7sXt +Xsf0XaPbISe2gYdXMO3exHplayt7C/wqjcxMePwtSwAJD+/JrFvFSiPBKT6Ajl+M +dcJIb9+WHhjk5GJI7KU4AVpf4feu5o1QnpnSAzCUlXpldYwSUS/7LZALvABm68Iy +2gHU1Aj5DYB/4nesWVhExKrMZDAICVojS5jCJH0CgYEA10SsIo9cN4ZZ0J7cfb7F +88sRcHg1DlcowFG/JmqDT/ScFnd/CNCITL8ARGZG+eZsL1333RiiT2WQC7EeoxPu +FlmJvrIriAriwwKfjPq0tOH8eeYZoKfVfbfpbFfEz7Zi5IWdFk7eQ1cYMOMhJXng +jzp/PCzhA5+ZJ3XPtDqQGb0CgYEA1AuwPuECUfqHSw1yldt0gj5s/D3aPW+SydT6 +kYziSPti2d1BLwb7Kfch4TKZgyA/mLCgE6AjJj8AmN/wviXOr2IWt5Tj29BTYeoT +s5XVHQISoiDdY6OuTK14ukDXOvF8dVi0QkkoEdmaG/SHHb67r2ilQaaQ91R0fqGv +AJ67ox0CgYBxkRfXPCnljxrJN7Fb1fS/DE1yVNWNkLiANOlUnPwzaD+jV0miCwEG +mR1PoRBG0j4sYTp9RyVCwR1RASNPStDTF/VcSllDqI45IHToKqgfeIlApmnCu291 +km1gAveM0Ayg5mLsIfIHyOlPZRL0iuewDDkwFNtwOiR87o9BurhRow== -----END RSA PRIVATE KEY----- diff --git a/test/rubygems/helper.rb b/test/rubygems/helper.rb new file mode 100644 index 0000000000..f97306717d --- /dev/null +++ b/test/rubygems/helper.rb @@ -0,0 +1,1582 @@ +# frozen_string_literal: true + +require "rubygems" + +begin + gem "test-unit", "~> 3.0" +rescue Gem::LoadError +end + +require "test/unit" + +ENV["JARS_SKIP"] = "true" if Gem.java_platform? # avoid unnecessary and noisy `jar-dependencies` post install hook + +require "fileutils" +require "pathname" +require "pp" +require "rubygems/package" +require "shellwords" +require "tmpdir" +require "rubygems/vendor/uri/lib/uri" +require "zlib" +require "benchmark" # stdlib +require_relative "mock_gem_ui" + +module Gem + ## + # Allows setting the gem path searcher. + + def self.searcher=(searcher) + @searcher = searcher + end + + ## + # Allows toggling Windows behavior. + + def self.win_platform=(val) + @@win_platform = val + end + + ## + # Allows setting path to Ruby. + + def self.ruby=(ruby) + @ruby = ruby + end + + ## + # Sets the default user interaction to a MockGemUi. + + module DefaultUserInteraction + @ui = Gem::MockGemUi.new + end +end + +require "rubygems/command" + +class Gem::Command + ## + # Allows resetting the hash of specific args per command. + + def self.specific_extra_args_hash=(value) + @specific_extra_args_hash = value + end +end + +## +# RubyGemTestCase provides a variety of methods for testing rubygems and +# gem-related behavior in a sandbox. Through RubyGemTestCase you can install +# and uninstall gems, fetch remote gems through a stub fetcher and be assured +# your normal set of gems is not affected. + +class Gem::TestCase < Test::Unit::TestCase + attr_accessor :fetcher # :nodoc: + + attr_accessor :gem_repo # :nodoc: + + attr_accessor :uri # :nodoc: + + @@tempdirs = [] + + def assert_activate(expected, *specs) + specs.each do |spec| + case spec + when String then + Gem::Specification.find_by_name(spec).activate + when Gem::Specification then + spec.activate + else + flunk spec.inspect + end + end + + loaded = Gem.loaded_specs.values.map(&:full_name) + + assert_equal expected.sort, loaded.sort if expected + end + + def assert_directory_exists(path, msg = nil) + msg = build_message(msg, "Expected path '#{path}' to be a directory") + assert_path_exist path + assert File.directory?(path), msg + end + + def refute_directory_exists(path, msg = nil) + msg = build_message(msg, "Expected path '#{path}' not to be a directory") + assert_path_not_exist path + refute File.directory?(path), msg + end + + # Originally copied from minitest/assertions.rb + def capture_subprocess_io + require "tempfile" + + captured_stdout = Tempfile.new("out") + captured_stderr = Tempfile.new("err") + + orig_stdout = $stdout.dup + orig_stderr = $stderr.dup + $stdout.reopen captured_stdout + $stderr.reopen captured_stderr + + yield + + $stdout.rewind + $stderr.rewind + + [captured_stdout.read, captured_stderr.read] + ensure + $stdout.reopen orig_stdout + $stderr.reopen orig_stderr + + orig_stdout.close + orig_stderr.close + captured_stdout.close! + captured_stderr.close! + end + + ## + # Sets the ENABLE_SHARED entry in RbConfig::CONFIG to +value+ and restores + # the original value when the block ends + + def enable_shared(value) + enable_shared = RbConfig::CONFIG["ENABLE_SHARED"] + RbConfig::CONFIG["ENABLE_SHARED"] = value + + yield + ensure + if enable_shared + RbConfig::CONFIG["ENABLE_SHARED"] = enable_shared + else + RbConfig::CONFIG.delete "ENABLE_SHARED" + end + end + + ## + # Overrides the Gem.install_extension_in_lib function and restores the + # original when the block ends + # + def extension_in_lib(value = true) # :nodoc: + Gem.stub(:install_extension_in_lib, value) { yield } + end + + ## + # Sets the vendordir entry in RbConfig::CONFIG to +value+ and restores the + # original value when the block ends + # + def vendordir(value) + vendordir = RbConfig::CONFIG["vendordir"] + + if value + RbConfig::CONFIG["vendordir"] = value + else + RbConfig::CONFIG.delete "vendordir" + end + + yield + ensure + if vendordir + RbConfig::CONFIG["vendordir"] = vendordir + else + RbConfig::CONFIG.delete "vendordir" + end + end + + ## + # Sets the bindir entry in RbConfig::CONFIG to +value+ and restores the + # original value when the block ends + # + def bindir(value) + with_clean_path_to_ruby do + bindir = RbConfig::CONFIG["bindir"] + + if value + RbConfig::CONFIG["bindir"] = value + else + RbConfig::CONFIG.delete "bindir" + end + + begin + yield + ensure + if bindir + RbConfig::CONFIG["bindir"] = bindir + else + RbConfig::CONFIG.delete "bindir" + end + end + end + end + + ## + # Sets the EXEEXT entry in RbConfig::CONFIG to +value+ and restores the + # original value when the block ends + # + def exeext(value) + exeext = RbConfig::CONFIG["EXEEXT"] + + if value + RbConfig::CONFIG["EXEEXT"] = value + else + RbConfig::CONFIG.delete "EXEEXT" + end + + yield + ensure + if exeext + RbConfig::CONFIG["EXEEXT"] = exeext + else + RbConfig::CONFIG.delete "EXEEXT" + end + end + + def scan_make_command_lines(output) + output.scan(/^#{Regexp.escape make_command}(?:[[:blank:]].*)?$/) + end + + def parse_make_command_line_targets(line) + args = line.sub(/^#{Regexp.escape make_command}/, "").shellsplit + + targets = [] + + args.each do |arg| + case arg + when /\A(\w+)=/ + else + targets << arg + end + end + + targets << "" if targets.empty? + + targets + end + + def assert_contains_make_command(target, output, msg = nil) + if output.include?("\n") + msg = build_message(msg, + format("Expected output containing make command \"%s\", but was \n\nBEGIN_OF_OUTPUT\n%sEND_OF_OUTPUT", format("%s %s", make_command, target).rstrip, output)) + else + msg = build_message(msg, + format('Expected make command "%s", but was "%s"', format("%s %s", make_command, target).rstrip, output)) + end + + assert scan_make_command_lines(output).any? {|line| + targets = parse_make_command_line_targets(line) + + if targets.include?(target) + true + else + false + end + }, msg + end + + include Gem::DefaultUserInteraction + + ## + # #setup prepares a sandboxed location to install gems. All installs are + # directed to a temporary directory. All install plugins are removed. + # + # If the +RUBY+ environment variable is set the given path is used for + # Gem::ruby. The local platform is set to <tt>i386-mswin32</tt> for Windows + # or <tt>i686-darwin8.10.1</tt> otherwise. + + def setup + @orig_hooks = {} + @orig_env = ENV.to_hash + + top_srcdir = __dir__ + "/../.." + @tmp = File.expand_path(ENV.fetch("GEM_TEST_TMPDIR", "tmp"), top_srcdir) + + FileUtils.mkdir_p(@tmp, mode: 0o700) # =rwx + @tmp = File.realpath(@tmp) + + @tempdir = Dir.mktmpdir("test_rubygems_", @tmp) + + ENV["GEM_VENDOR"] = nil + ENV["GEMRC"] = nil + ENV["XDG_CACHE_HOME"] = nil + ENV["XDG_CONFIG_HOME"] = nil + ENV["XDG_DATA_HOME"] = nil + ENV["XDG_STATE_HOME"] = nil + ENV["SOURCE_DATE_EPOCH"] = nil + ENV["BUNDLER_VERSION"] = nil + ENV["RUBYGEMS_PREVENT_UPDATE_SUGGESTION"] = "true" + + @current_dir = Dir.pwd + @fetcher = nil + + @back_ui = Gem::DefaultUserInteraction.ui + @ui = Gem::MockGemUi.new + # This needs to be a new instance since we call use_ui(@ui) when we want to + # capture output + Gem::DefaultUserInteraction.ui = Gem::MockGemUi.new + + @orig_system_wide_config_file = Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE + Gem::ConfigFile.send :remove_const, :SYSTEM_WIDE_CONFIG_FILE + Gem::ConfigFile.send :const_set, :SYSTEM_WIDE_CONFIG_FILE, + File.join(@tempdir, "system-gemrc") + + @gemhome = File.join @tempdir, "gemhome" + @userhome = File.join @tempdir, "userhome" + @statehome = File.join @tempdir, "statehome" + ENV["GEM_SPEC_CACHE"] = File.join @tempdir, "spec_cache" + + @orig_ruby = if ENV["RUBY"] + ruby = Gem.ruby + Gem.ruby = ENV["RUBY"] + ruby + end + + @git = ENV["GIT"] || "git#{RbConfig::CONFIG["EXEEXT"]}" + + Gem.ensure_gem_subdirectories @gemhome + Gem.ensure_default_gem_subdirectories @gemhome + + @orig_load_path = $LOAD_PATH.dup + $LOAD_PATH.map! do |s| + expand_path = begin + File.realpath(s) + rescue StandardError + File.expand_path(s) + end + if expand_path != s + if s.instance_variable_defined?(:@gem_prelude_index) + expand_path.instance_variable_set(:@gem_prelude_index, expand_path) + end + expand_path.freeze if s.frozen? + s = expand_path + end + s + end + + Dir.chdir @tempdir + + ENV["HOME"] = @userhome + # Remove "RUBY_CODESIGN", which is used by mkmf-generated Makefile to + # sign extension bundles on macOS, to avoid trying to find the specified key + # from the fake $HOME/Library/Keychains directory. + ENV.delete "RUBY_CODESIGN" + Gem.instance_variable_set :@config_file, nil + Gem.instance_variable_set :@user_home, nil + Gem.instance_variable_set :@config_home, nil + Gem.instance_variable_set :@data_home, nil + Gem.instance_variable_set :@state_home, @statehome + Gem.instance_variable_set :@state_file, nil + Gem.instance_variable_set :@gemdeps, nil + Gem.instance_variable_set :@env_requirements_by_name, nil + Gem.send :remove_instance_variable, :@ruby_version if + Gem.instance_variables.include? :@ruby_version + + FileUtils.mkdir_p @userhome + + ENV["GEM_PRIVATE_KEY_PASSPHRASE"] = PRIVATE_KEY_PASSPHRASE + + Gem.instance_variable_set(:@default_specifications_dir, File.join(@gemhome, "specifications", "default")) + if Gem.java_platform? + @orig_default_gem_home = RbConfig::CONFIG["default_gem_home"] + RbConfig::CONFIG["default_gem_home"] = @gemhome + else + Gem.instance_variable_set(:@default_dir, @gemhome) + end + + @orig_bindir = RbConfig::CONFIG["bindir"] + RbConfig::CONFIG["bindir"] = File.join @gemhome, "bin" + + @orig_sitelibdir = RbConfig::CONFIG["sitelibdir"] + new_sitelibdir = @orig_sitelibdir.sub(RbConfig::CONFIG["prefix"], @gemhome) + $LOAD_PATH.insert(Gem.load_path_insert_index, new_sitelibdir) + RbConfig::CONFIG["sitelibdir"] = new_sitelibdir + + @orig_mandir = RbConfig::CONFIG["mandir"] + RbConfig::CONFIG["mandir"] = File.join @gemhome, "share", "man" + + Gem::Specification.unresolved_deps.clear + Gem.use_paths(@gemhome) + + Gem.loaded_specs.clear + Gem.instance_variable_set(:@activated_gem_paths, 0) + Gem.clear_default_specs + + Gem.configuration.verbose = true + Gem.configuration.update_sources = true + + Gem::RemoteFetcher.fetcher = Gem::FakeFetcher.new + + @gem_repo = "http://gems.example.com/" + @uri = Gem::URI.parse @gem_repo + Gem.sources.replace [@gem_repo] + + Gem.searcher = nil + Gem::SpecFetcher.fetcher = nil + + @orig_arch = RbConfig::CONFIG["arch"] + + if Gem.win_platform? + util_set_arch "i386-mswin32" + else + util_set_arch "i686-darwin8.10.1" + end + + %w[post_install_hooks done_installing_hooks post_uninstall_hooks pre_uninstall_hooks pre_install_hooks pre_reset_hooks post_reset_hooks post_build_hooks].each do |name| + @orig_hooks[name] = Gem.send(name).dup + end + + @marshal_version = "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}" + @orig_loaded_features = $LOADED_FEATURES.dup + end + + ## + # #teardown restores the process to its original state and removes the + # tempdir + + def teardown + $LOAD_PATH.replace @orig_load_path if @orig_load_path + if @orig_loaded_features + if @orig_load_path + ($LOADED_FEATURES - @orig_loaded_features).each do |feat| + $LOADED_FEATURES.delete(feat) if feat.start_with?(@tmp) + end + else + $LOADED_FEATURES.replace @orig_loaded_features + end + end + + RbConfig::CONFIG["arch"] = @orig_arch + + if defined? Gem::RemoteFetcher + Gem::RemoteFetcher.fetcher = nil + end + + Dir.chdir @current_dir + + FileUtils.rm_rf @tempdir + + restore_env + + Gem::ConfigFile.send :remove_const, :SYSTEM_WIDE_CONFIG_FILE + Gem::ConfigFile.send :const_set, :SYSTEM_WIDE_CONFIG_FILE, + @orig_system_wide_config_file + + Gem.ruby = @orig_ruby if @orig_ruby + + RbConfig::CONFIG["mandir"] = @orig_mandir + RbConfig::CONFIG["sitelibdir"] = @orig_sitelibdir + RbConfig::CONFIG["bindir"] = @orig_bindir + + Gem.instance_variable_set :@default_specifications_dir, nil + if Gem.java_platform? + RbConfig::CONFIG["default_gem_home"] = @orig_default_gem_home + else + Gem.instance_variable_set :@default_dir, nil + end + + Gem::Specification.unresolved_deps.clear + Gem.refresh + + @orig_hooks.each do |name, hooks| + Gem.send(name).replace hooks + end + + @back_ui.close + + refute_directory_exists @tempdir, "may be still in use" + ghosts = @@tempdirs.filter_map do |test_name, tempdir| + test_name if File.exist?(tempdir) + end + @@tempdirs << [method_name, @tempdir] + assert_empty ghosts + end + + def credential_setup + @temp_cred = File.join(@userhome, ".gem", "credentials") + FileUtils.mkdir_p File.dirname(@temp_cred) + File.write @temp_cred, ":rubygems_api_key: 701229f217cdf23b1344c7b4b54ca97" + File.chmod 0o600, @temp_cred + end + + def credential_teardown + FileUtils.rm_rf @temp_cred + end + + def common_installer_setup + common_installer_teardown + + Gem.post_build do |installer| + @post_build_hook_arg = installer + true + end + + Gem.post_install do |installer| + @post_install_hook_arg = installer + end + + Gem.post_uninstall do |uninstaller| + @post_uninstall_hook_arg = uninstaller + end + + Gem.pre_install do |installer| + @pre_install_hook_arg = installer + true + end + + Gem.pre_uninstall do |uninstaller| + @pre_uninstall_hook_arg = uninstaller + end + end + + def common_installer_teardown + Gem.post_build_hooks.clear + Gem.post_install_hooks.clear + Gem.done_installing_hooks.clear + Gem.post_reset_hooks.clear + Gem.post_uninstall_hooks.clear + Gem.pre_install_hooks.clear + Gem.pre_reset_hooks.clear + Gem.pre_uninstall_hooks.clear + end + + def without_any_upwards_gemfiles + ENV["BUNDLE_GEMFILE"] = File.join(@tempdir, "Gemfile") + end + + ## + # A git_gem is used with a gem dependencies file. The gem created here + # has no files, just a gem specification for the given +name+ and +version+. + # + # Yields the +specification+ to the block, if given + + def git_gem(name = "a", version = 1) + have_git? + + directory = File.join "git", name + directory = File.expand_path directory + + git_spec = Gem::Specification.new name, version do |specification| + yield specification if block_given? + end + + FileUtils.mkdir_p directory + + gemspec = "#{name}.gemspec" + + File.open File.join(directory, gemspec), "w" do |io| + io.write git_spec.to_ruby + end + + head = nil + + Dir.chdir directory do + unless File.exist? ".git" + system @git, "init", "--quiet" + system @git, "config", "user.name", "RubyGems Tests" + system @git, "config", "user.email", "rubygems@example" + end + + system @git, "add", gemspec + system @git, "commit", "-a", "-m", "a non-empty commit message", "--quiet" + head = Gem::Util.popen(@git, "rev-parse", "HEAD").strip + end + + [name, git_spec.version, directory, head] + end + + ## + # Skips this test unless you have a git executable + + def have_git? + return if in_path? @git + + pend "cannot find git executable, use GIT environment variable to set" + end + + def in_path?(executable) # :nodoc: + return true if %r{\A([A-Z]:|/)}.match?(executable) && File.exist?(executable) + + ENV["PATH"].split(File::PATH_SEPARATOR).any? do |directory| + File.exist? File.join directory, executable + end + end + + ## + # Builds and installs the Gem::Specification +spec+ + + def install_gem(spec, options = {}) + require "rubygems/installer" + + gem = spec.cache_file + + unless File.exist? gem + use_ui Gem::MockGemUi.new do + Dir.chdir @tempdir do + Gem::Package.build spec + end + end + + gem = File.join(@tempdir, File.basename(gem)) + end + + Gem::Installer.at(gem, options.merge({ wrappers: true })).install + end + + ## + # Builds and installs the Gem::Specification +spec+ into the user dir + + def install_gem_user(spec) + install_gem spec, user_install: true + end + + ## + # Uninstalls the Gem::Specification +spec+ + def uninstall_gem(spec) + require "rubygems/uninstaller" + + Class.new(Gem::Uninstaller) do + def ask_if_ok(spec) + true + end + end.new(spec.name, executables: true, user_install: true).uninstall + end + + ## + # Enables pretty-print for all tests + + def mu_pp(obj) + s = String.new + s = PP.pp obj, s + s = s.force_encoding(Encoding.default_external) + s.chomp + end + + ## + # Reads a Marshal file at +path+ + + def read_cache(path) + File.open path.dup, "rb" do |io| + Marshal.load io.read + end + end + + ## + # Reads a binary file at +path+ + + def read_binary(path) + Gem.read_binary path + end + + ## + # Writes a binary file to +path+ which is relative to +@gemhome+ + + def write_file(path) + path = File.join @gemhome, path unless Pathname.new(path).absolute? + dir = File.dirname path + FileUtils.mkdir_p dir unless File.directory? dir + + File.open path, "wb" do |io| + yield io if block_given? + end + + path + end + + ## + # Load a YAML string, the psych 3 way + + def load_yaml(yaml) + if Psych.respond_to?(:unsafe_load) + Psych.unsafe_load(yaml) + else + Psych.load(yaml) + end + end + + ## + # Load a YAML file, the psych 3 way + + def load_yaml_file(file) + require "rubygems/config_file" + Gem::ConfigFile.load_with_rubygems_config_hash(File.read(file)) + end + + def all_spec_names + Gem::Specification.map(&:full_name) + end + + ## + # Creates a Gem::Specification with a minimum of extra work. +name+ and + # +version+ are the gem's name and version, platform, author, email, + # homepage, summary and description are defaulted. The specification is + # yielded for customization. + # + # The gem is added to the installed gems in +@gemhome+ and the runtime. + # + # Use this with #write_file to build an installed gem. + + def quick_gem(name, version="2") + require "rubygems/specification" + + spec = Gem::Specification.new do |s| + s.platform = Gem::Platform::RUBY + s.name = name + s.version = version + s.author = "A User" + s.email = "example@example.com" + s.homepage = "http://example.com" + s.summary = "this is a summary" + s.description = "This is a test description" + + yield(s) if block_given? + end + + written_path = write_file spec.spec_file do |io| + io.write spec.to_ruby_for_cache + end + + spec.loaded_from = written_path + + Gem::Specification.reset + + spec + end + + ## + # Builds a gem from +spec+ and places it in <tt>File.join @gemhome, + # 'cache'</tt>. Automatically creates files based on +spec.files+ + + def util_build_gem(spec) + dir = spec.gem_dir + FileUtils.mkdir_p dir + + Dir.chdir dir do + spec.files.each do |file| + next if File.exist? file + FileUtils.mkdir_p File.dirname(file) + + File.open file, "w" do |fp| + fp.puts "# #{file}" + end + end + + use_ui Gem::MockGemUi.new do + Gem::Package.build spec + end + + cache = spec.cache_file + FileUtils.mv File.basename(cache), cache + end + end + + def util_remove_gem(spec) + FileUtils.rm_rf spec.cache_file + FileUtils.rm_rf spec.spec_file + end + + ## + # Removes all installed gems from +@gemhome+. + + def util_clear_gems + FileUtils.rm_rf File.join(@gemhome, "gems") + FileUtils.mkdir File.join(@gemhome, "gems") + FileUtils.rm_rf File.join(@gemhome, "specifications") + FileUtils.mkdir File.join(@gemhome, "specifications") + Gem::Specification.reset + end + + ## + # Install the provided specs + + def install_specs(*specs) + specs.each do |spec| + Gem::Installer.for_spec(spec, force: true).install + end + + Gem.searcher = nil + end + + ## + # Installs the provided default specs including writing the spec file + + def install_default_gems(*specs) + specs.each do |spec| + installer = Gem::Installer.for_spec(spec, install_as_default: true) + installer.install + Gem.register_default_spec(spec) + 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 new_default_spec(name, version, deps = nil, *files) + spec = util_spec name, version, deps + + spec.loaded_from = File.join(@gemhome, "specifications", "default", spec.spec_name) + spec.files = files + + lib_dir = File.join(@tempdir, "default_gems", "lib") + lib_dir.instance_variable_set(:@gem_prelude_index, lib_dir) + Gem.instance_variable_set(:@default_gem_load_paths, [*Gem.send(:default_gem_load_paths), lib_dir]) + $LOAD_PATH.unshift(lib_dir) + files.each do |file| + rb_path = File.join(lib_dir, file) + FileUtils.mkdir_p(File.dirname(rb_path)) + File.open(rb_path, "w") do |rb| + rb << "# #{file}" + end + end + + spec + end + + ## + # Creates a spec with +name+, +version+. +deps+ can specify the dependency + # or a +block+ can be given for full customization of the specification. + + def util_spec(name, version = 2, deps = nil, *files) # :yields: specification + raise "deps or block, not both" if deps && block_given? + + spec = Gem::Specification.new do |s| + s.platform = Gem::Platform::RUBY + s.name = name + s.version = version + s.author = "A User" + s.email = "example@example.com" + s.homepage = "http://example.com" + s.summary = "this is a summary" + s.description = "This is a test description" + + s.files.push(*files) unless files.empty? + + yield s if block_given? + end + + if deps + deps.keys.each do |n| + spec.add_dependency n, (deps[n] || ">= 0") + end + end + + unless files.empty? + write_file spec.spec_file do |io| + io.write spec.to_ruby_for_cache + end + + util_build_gem spec + + FileUtils.rm spec.spec_file + end + + spec + end + + ## + # Creates a gem with +name+, +version+ and +deps+. The specification will + # be yielded before gem creation for customization. The gem will be placed + # in <tt>File.join @tempdir, 'gems'</tt>. The specification and .gem file + # location are returned. + + def util_gem(name, version, deps = nil, &block) + if deps + block = proc do |s| + deps.keys.each do |n| + s.add_dependency n, (deps[n] || ">= 0") + end + end + end + + spec = quick_gem(name, version, &block) + + util_build_gem spec + + cache_file = File.join @tempdir, "gems", "#{spec.original_name}.gem" + FileUtils.mkdir_p File.dirname cache_file + FileUtils.mv spec.cache_file, cache_file + FileUtils.rm spec.spec_file + + spec.loaded_from = nil + + [spec, cache_file] + end + + ## + # Gzips +data+. + + def util_gzip(data) + out = StringIO.new + + Zlib::GzipWriter.wrap out do |io| + io.write data + end + + out.string + end + + ## + # Creates several default gems which all have a lib/code.rb file. The gems + # are not installed but are available in the cache dir. + # + # +@a1+:: gem a version 1, this is the best-described gem. + # +@a2+:: gem a version 2 + # +@a3a:: gem a version 3.a + # +@a_evil9+:: gem a_evil version 9, use this to ensure similarly-named gems + # don't collide with a. + # +@b2+:: gem b version 2 + # +@c1_2+:: gem c version 1.2 + # +@pl1+:: gem pl version 1, this gem has a legacy platform of i386-linux. + # + # Additional +prerelease+ gems may also be created: + # + # +@a2_pre+:: gem a version 2.a + # TODO: nuke this and fix tests. this should speed up a lot + + def util_make_gems(prerelease = false) + @a1 = quick_gem "a", "1" do |s| + s.files = %w[lib/code.rb] + s.require_paths = %w[lib] + s.date = Gem::Specification::TODAY - 86_400 + s.homepage = "http://a.example.com" + s.email = %w[example@example.com example2@example.com] + s.authors = %w[Example Example2] + s.description = <<-DESC +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. + DESC + end + + init = proc do |s| + s.files = %w[lib/code.rb] + s.require_paths = %w[lib] + end + + @a2 = quick_gem("a", "2", &init) + @a3a = quick_gem("a", "3.a", &init) + @a_evil9 = quick_gem("a_evil", "9", &init) + @b2 = quick_gem("b", "2", &init) + @c1_2 = quick_gem("c", "1.2", &init) + @x = quick_gem("x", "1", &init) + @dep_x = quick_gem("dep_x", "1") do |s| + s.files = %w[lib/code.rb] + s.require_paths = %w[lib] + s.add_dependency "x", ">= 1" + end + + @pl1 = quick_gem "pl", "1" do |s| # l for legacy + s.files = %w[lib/code.rb] + s.require_paths = %w[lib] + s.platform = Gem::Platform.new "i386-linux" + s.instance_variable_set :@original_platform, "i386-linux" + end + + if prerelease + @a2_pre = quick_gem("a", "2.a", &init) + write_file File.join(*%W[gems #{@a2_pre.original_name} lib code.rb]) + util_build_gem @a2_pre + end + + write_file File.join(*%W[gems #{@a1.original_name} lib code.rb]) + write_file File.join(*%W[gems #{@a2.original_name} lib code.rb]) + write_file File.join(*%W[gems #{@a3a.original_name} lib code.rb]) + write_file File.join(*%W[gems #{@a_evil9.original_name} lib code.rb]) + write_file File.join(*%W[gems #{@b2.original_name} lib code.rb]) + write_file File.join(*%W[gems #{@c1_2.original_name} lib code.rb]) + write_file File.join(*%W[gems #{@pl1.original_name} lib code.rb]) + write_file File.join(*%W[gems #{@x.original_name} lib code.rb]) + write_file File.join(*%W[gems #{@dep_x.original_name} lib code.rb]) + + [@a1, @a2, @a3a, @a_evil9, @b2, @c1_2, @pl1, @x, @dep_x].each do |spec| + util_build_gem spec + end + + FileUtils.rm_r File.join(@gemhome, "gems", @pl1.original_name) + end + + ## + # Set the platform to +arch+ + + def util_set_arch(arch) + RbConfig::CONFIG["arch"] = arch + platform = Gem::Platform.new arch + + Gem.instance_variable_set :@platforms, nil + Gem::Platform.instance_variable_set :@local, nil + + yield if block_given? + + platform + end + + ## + # Add +spec+ to +@fetcher+ serving the data in the file +path+. + # +repo+ indicates which repo to make +spec+ appear to be in. + + def add_to_fetcher(spec, path=nil, repo=@gem_repo) + path ||= spec.cache_file + @fetcher.data["#{@gem_repo}gems/#{spec.file_name}"] = read_binary(path) + end + + ## + # Sets up Gem::SpecFetcher to return information from the gems in +specs+. + + def util_setup_spec_fetcher(*specs) + all_specs = Gem::Specification.to_a + specs + Gem::Specification._resort! all_specs + + spec_fetcher = Gem::SpecFetcher.fetcher + + prerelease, all = all_specs.partition {|spec| spec.version.prerelease? } + latest = Gem::Specification._latest_specs all_specs + + spec_fetcher.specs[@uri] = [] + all.each do |spec| + spec_fetcher.specs[@uri] << spec.name_tuple + end + + spec_fetcher.latest_specs[@uri] = [] + latest.each do |spec| + spec_fetcher.latest_specs[@uri] << spec.name_tuple + end + + spec_fetcher.prerelease_specs[@uri] = [] + prerelease.each do |spec| + spec_fetcher.prerelease_specs[@uri] << spec.name_tuple + end + + # HACK: for test_download_to_cache + unless Gem::RemoteFetcher === @fetcher + v = Gem.marshal_version + + specs = all.map(&:name_tuple) + s_zip = util_gzip Marshal.dump Gem::NameTuple.to_basic specs + + latest_specs = latest.map(&:name_tuple) + + l_zip = util_gzip Marshal.dump Gem::NameTuple.to_basic latest_specs + + prerelease_specs = prerelease.map(&:name_tuple) + 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 + + write_marshalled_gemspecs(*all_specs) + end + + nil # force errors + end + + def write_marshalled_gemspecs(*all_specs) + v = Gem.marshal_version + + all_specs.each do |spec| + path = "#{@gem_repo}quick/Marshal.#{v}/#{spec.original_name}.gemspec.rz" + data = Marshal.dump spec + data_deflate = Zlib::Deflate.deflate data + @fetcher.data[path] = data_deflate + end + end + + ## + # Deflates +data+ + + def util_zip(data) + Zlib::Deflate.deflate data + end + + def util_set_RUBY_VERSION(version, patchlevel, revision, description, engine = "ruby", engine_version = nil) + if Gem.instance_variables.include? :@ruby_version + Gem.send :remove_instance_variable, :@ruby_version + end + + @ruby_version = RUBY_VERSION + @ruby_patchlevel = RUBY_PATCHLEVEL + @ruby_revision = RUBY_REVISION + @ruby_description = RUBY_DESCRIPTION + @ruby_engine = RUBY_ENGINE + @ruby_engine_version = RUBY_ENGINE_VERSION + + util_clear_RUBY_VERSION + + Object.const_set :RUBY_VERSION, version + Object.const_set :RUBY_PATCHLEVEL, patchlevel + Object.const_set :RUBY_REVISION, revision + Object.const_set :RUBY_DESCRIPTION, description + Object.const_set :RUBY_ENGINE, engine + Object.const_set :RUBY_ENGINE_VERSION, engine_version + end + + def util_restore_RUBY_VERSION + util_clear_RUBY_VERSION + + Object.const_set :RUBY_VERSION, @ruby_version + Object.const_set :RUBY_PATCHLEVEL, @ruby_patchlevel + Object.const_set :RUBY_REVISION, @ruby_revision + Object.const_set :RUBY_DESCRIPTION, @ruby_description + Object.const_set :RUBY_ENGINE, @ruby_engine + Object.const_set :RUBY_ENGINE_VERSION, @ruby_engine_version + end + + def util_clear_RUBY_VERSION + Object.send :remove_const, :RUBY_VERSION + Object.send :remove_const, :RUBY_PATCHLEVEL + Object.send :remove_const, :RUBY_REVISION + Object.send :remove_const, :RUBY_DESCRIPTION + Object.send :remove_const, :RUBY_ENGINE + Object.send :remove_const, :RUBY_ENGINE_VERSION + end + + ## + # Returns whether or not we're on a version of Ruby built with VC++ (or + # Borland) versus Cygwin, Mingw, etc. + + def self.vc_windows? + RUBY_PLATFORM.match("mswin") + end + + ## + # see ::vc_windows? + + def vc_windows? + self.class.vc_windows? + end + + ## + # Is this test being run on a version of Ruby built with mingw? + + def mingw_windows? + RUBY_PLATFORM.match("mingw") + end + + ## + # Is this test being run on a ruby/ruby repository? + # + + def ruby_repo? + !ENV["GEM_COMMAND"].nil? + end + + ## + # Returns the make command for the current platform. For versions of Ruby + # built on MS Windows with VC++ or Borland it will return 'nmake'. On all + # other platforms, including Cygwin, it will return 'make'. + + def make_command + ENV["make"] || ENV["MAKE"] || (vc_windows? ? "nmake" : "make") + end + + ## + # Returns whether or not the nmake command could be found. + + def nmake_found? + system("nmake /? 1>NUL 2>&1") + end + + # In case we're building docs in a background process, this method waits for + # that process to exit (or if it's already been reaped, or never happened, + # swallows the Errno::ECHILD error). + def wait_for_child_process_to_exit + Process.wait if Process.respond_to?(:fork) + rescue Errno::ECHILD + end + + ## + # Allows the proper version of +rake+ to be used for the test. + + def build_rake_in(good=true) + gem_ruby = Gem.ruby + Gem.ruby = self.class.rubybin + env_rake = ENV["rake"] + rake = (good ? @@good_rake : @@bad_rake) + ENV["rake"] = rake + yield rake + ensure + Gem.ruby = gem_ruby + if env_rake + ENV["rake"] = env_rake + else + ENV.delete("rake") + end + end + + ## + # Finds the path to the Ruby executable + + def self.rubybin + ruby = ENV["RUBY"] + return ruby if ruby + ruby = "ruby" + rubyexe = "#{ruby}#{RbConfig::CONFIG["EXEEXT"]}" + + 3.times do + if File.exist?(ruby) && File.executable?(ruby) && !File.directory?(ruby) + return File.expand_path(ruby) + end + if File.exist?(rubyexe) && File.executable?(rubyexe) + return File.expand_path(rubyexe) + end + ruby = File.join("..", ruby) + end + + begin + Gem.ruby + rescue LoadError + "ruby" + end + end + + def ruby_with_rubygems_in_load_path + [Gem.ruby, "-I", rubygems_path] + end + + def rubygems_path + $LOAD_PATH.find {|p| p == File.dirname($LOADED_FEATURES.find {|f| f.end_with?("/rubygems.rb") }) } + end + + def bundler_path + $LOAD_PATH.find {|p| p == File.dirname($LOADED_FEATURES.find {|f| f.end_with?("/bundler.rb") }) } + end + + def with_clean_path_to_ruby + orig_ruby = Gem.ruby + + Gem.instance_variable_set :@ruby, nil + + yield + ensure + Gem.instance_variable_set :@ruby, orig_ruby + end + + def with_internal_encoding(encoding) + int_enc = Encoding.default_internal + silence_warnings { Encoding.default_internal = encoding } + + yield + ensure + silence_warnings { Encoding.default_internal = int_enc } + end + + def silence_warnings + old_verbose = $VERBOSE + $VERBOSE = false + yield + ensure + $VERBOSE = old_verbose + end + + # :nodoc: + ## + # Return the join path, with escaping backticks, dollars, and + # double-quotes. Unlike `shellescape`, equal-sign is not escaped. + + def self.escape_path(*path) + path = File.join(*path) + if %r{\A[-+:/=@,.\w]+\z}.match?(path) + path + else + "\"#{path.gsub(/[`$"]/, '\\&')}\"" + end + end + + @@good_rake = "#{rubybin} #{escape_path(__dir__, "good_rake.rb")}" + @@bad_rake = "#{rubybin} #{escape_path(__dir__, "bad_rake.rb")}" + + ## + # Construct a new Gem::Dependency. + + def dep(name, *requirements) + Gem::Dependency.new name, *requirements + end + + ## + # Constructs a Gem::Resolver::DependencyRequest from a + # Gem::Dependency +dep+, a +from_name+ and +from_version+ requesting the + # dependency and a +parent+ DependencyRequest + + def dependency_request(dep, from_name, from_version, parent = nil) + remote = Gem::Source.new @uri + + unless parent + parent_dep = dep from_name, from_version + parent = Gem::Resolver::DependencyRequest.new parent_dep, nil + end + + spec = Gem::Resolver::IndexSpecification.new \ + nil, from_name, from_version, remote, Gem::Platform::RUBY + activation = Gem::Resolver::ActivationRequest.new spec, parent + + Gem::Resolver::DependencyRequest.new dep, activation + end + + ## + # Constructs a new Gem::Requirement. + + def req(*requirements) + return requirements.first if Gem::Requirement === requirements.first + Gem::Requirement.create requirements + end + + ## + # Constructs a new Gem::Specification. + + def spec(name, version, &block) + Gem::Specification.new name, v(version), &block + end + + ## + # Creates a SpecFetcher pre-filled with the gems or specs defined in the + # block. + # + # Yields a +fetcher+ object that responds to +spec+ and +gem+. +spec+ adds + # a specification to the SpecFetcher while +gem+ adds both a specification + # and the gem data to the RemoteFetcher so the built gem can be downloaded. + # + # If only the a-3 gem is supposed to be downloaded you can save setup + # time by creating only specs for the other versions: + # + # spec_fetcher do |fetcher| + # fetcher.spec 'a', 1 + # fetcher.spec 'a', 2, 'b' => 3 # dependency on b = 3 + # fetcher.gem 'a', 3 do |spec| + # # spec is a Gem::Specification + # # ... + # end + # end + + def spec_fetcher(repository = @gem_repo) + Gem::TestCase::SpecFetcherSetup.declare self, repository do |spec_fetcher_setup| + yield spec_fetcher_setup if block_given? + end + end + + ## + # Construct a new Gem::Version. + + def v(string) + Gem::Version.create string + end + + ## + # A vendor_gem is used with a gem dependencies file. The gem created here + # has no files, just a gem specification for the given +name+ and +version+. + # + # Yields the +specification+ to the block, if given + + def vendor_gem(name = "a", version = 1, &block) + directory = File.join "vendor", name + + FileUtils.mkdir_p directory + + save_gemspec name, version, directory, &block + end + + ## + # create_gemspec creates gem specification in given +directory+ or '.' + # for the given +name+ and +version+. + # + # Yields the +specification+ to the block, if given + + def save_gemspec(name = "a", version = 1, directory = ".") + vendor_spec = Gem::Specification.new name, version do |specification| + yield specification if block_given? + end + + File.open File.join(directory, "#{name}.gemspec"), "w" do |io| + io.write vendor_spec.to_ruby + end + + [name, vendor_spec.version, directory] + end + + ## + # The StaticSet is a static set of gem specifications used for testing only. + # It is available by requiring Gem::TestCase. + + class StaticSet < Gem::Resolver::Set + ## + # A StaticSet ignores remote because it has a fixed set of gems. + + attr_accessor :remote + + ## + # Creates a new StaticSet for the given +specs+ + + def initialize(specs) + super() + + @specs = specs + + @remote = true + end + + ## + # Adds +spec+ to this set. + + def add(spec) + @specs << spec + end + + ## + # Finds +dep+ in this set. + + def find_spec(dep) + @specs.reverse_each do |s| + return s if dep.matches_spec? s + end + end + + ## + # Finds all gems matching +dep+ in this set. + + def find_all(dep) + @specs.find_all {|s| dep.match? s, @prerelease } + end + + ## + # Loads a Gem::Specification from this set which has the given +name+, + # version +ver+, +platform+. The +source+ is ignored. + + def load_spec(name, ver, platform, source) + dep = Gem::Dependency.new name, ver + spec = find_spec dep + + Gem::Specification.new spec.name, spec.version do |s| + s.platform = spec.platform + end + end + + def prefetch(reqs) # :nodoc: + end + end + + ## + # Loads certificate named +cert_name+ from <tt>test/rubygems/</tt>. + + def self.load_cert(cert_name) + cert_file = cert_path cert_name + + cert = File.read cert_file + + OpenSSL::X509::Certificate.new cert + end + + ## + # Returns the path to the certificate named +cert_name+ from + # <tt>test/rubygems/</tt>. + + def self.cert_path(cert_name) + if begin + Time.at(2**32) + rescue StandardError + 32 + end == 32 + cert_file = "#{__dir__}/#{cert_name}_cert_32.pem" + + return cert_file if File.exist? cert_file + end + + "#{__dir__}/#{cert_name}_cert.pem" + end + + ## + # Loads a private key named +key_name+ with +passphrase+ in <tt>test/rubygems/</tt> + + def self.load_key(key_name, passphrase = nil) + key_file = key_path key_name + + key = File.read key_file + + OpenSSL::PKey.read key, passphrase + end + + ## + # Returns the path to the key named +key_name+ from <tt>test/rubygems</tt> + + def self.key_path(key_name) + "#{__dir__}/#{key_name}_key.pem" + end + + # :stopdoc: + # only available in RubyGems tests + + PRIVATE_KEY_PASSPHRASE = "Foo bar" + + begin + PRIVATE_KEY = load_key "private" + PRIVATE_KEY_PATH = key_path "private" + + # ENCRYPTED_PRIVATE_KEY is PRIVATE_KEY encrypted with PRIVATE_KEY_PASSPHRASE + ENCRYPTED_PRIVATE_KEY = load_key "encrypted_private", PRIVATE_KEY_PASSPHRASE + ENCRYPTED_PRIVATE_KEY_PATH = key_path "encrypted_private" + + PUBLIC_KEY = PRIVATE_KEY.public_key + + PUBLIC_CERT = load_cert "public" + PUBLIC_CERT_PATH = cert_path "public" + rescue Errno::ENOENT + PRIVATE_KEY = nil + PUBLIC_KEY = nil + PUBLIC_CERT = nil + end if Gem::HAVE_OPENSSL + + private + + def restore_env + unless Gem.win_platform? + ENV.replace(@orig_env) + return + end + + # Fallback logic for Windows below to workaround + # https://bugs.ruby-lang.org/issues/16798. Can be dropped once all + # supported rubies include the fix for that. + + ENV.clear + + @orig_env.each {|k, v| ENV[k] = v } + end +end + +# https://github.com/seattlerb/minitest/blob/13c48a03d84a2a87855a4de0c959f96800100357/lib/minitest/mock.rb#L192 +class Object + def stub(name, val_or_callable, *block_args) + new_name = "__minitest_stub__#{name}" + + metaclass = class << self; self; end + + if respond_to?(name) && !methods.map(&:to_s).include?(name.to_s) + metaclass.send :define_method, name do |*args| + super(*args) + end + end + + metaclass.send :alias_method, new_name, name + + metaclass.send :define_method, name do |*args, &blk| + if val_or_callable.respond_to? :call + val_or_callable.call(*args, &blk) + else + blk&.call(*block_args) + val_or_callable + end + end + + metaclass.send(:ruby2_keywords, name) if metaclass.respond_to?(:ruby2_keywords, true) + + yield self + ensure + metaclass.send :undef_method, name + metaclass.send :alias_method, name, new_name + metaclass.send :undef_method, new_name + end unless method_defined?(:stub) # lib/resolv/test_dns.rb also has the same method definition +end + +require_relative "utilities" diff --git a/test/rubygems/installer_test_case.rb b/test/rubygems/installer_test_case.rb new file mode 100644 index 0000000000..abddcbe848 --- /dev/null +++ b/test/rubygems/installer_test_case.rb @@ -0,0 +1,246 @@ +# frozen_string_literal: true + +require_relative "helper" +require "rubygems/installer" + +class Gem::Installer + ## + # Available through requiring rubygems/installer_test_case + + attr_writer :bin_dir + + ## + # Available through requiring rubygems/installer_test_case + + attr_writer :build_args + + ## + # Available through requiring rubygems/installer_test_case + + attr_writer :gem_dir + + ## + # Available through requiring rubygems/installer_test_case + + attr_writer :force + + ## + # Available through requiring rubygems/installer_test_case + + attr_writer :format + + ## + # Available through requiring rubygems/installer_test_case + + attr_writer :gem_home + + ## + # Available through requiring rubygems/installer_test_case + + attr_writer :env_shebang + + ## + # Available through requiring rubygems/installer_test_case + + attr_writer :ignore_dependencies + + ## + # Available through requiring rubygems/installer_test_case + + attr_writer :format_executable + + ## + # Available through requiring rubygems/installer_test_case + + attr_writer :security_policy + + ## + # Available through requiring rubygems/installer_test_case + + attr_writer :wrappers +end + +## +# A test case for Gem::Installer. + +class Gem::InstallerTestCase < Gem::TestCase + def setup + super + + Gem::Installer.path_warning = false + end + + ## + # The path where installed executables live + + def util_inst_bindir + File.join @gemhome, "bin" + end + + ## + # Adds an executable named "executable" to +spec+ with the given +shebang+. + # + # The executable is also written to the bin dir in @tmpdir and the installed + # gem directory for +spec+. + + def util_make_exec(spec = @spec, shebang = "#!/usr/bin/ruby", bindir = "bin") + spec.executables = %w[executable] + spec.bindir = bindir + + exec_path = spec.bin_file "executable" + write_file exec_path do |io| + io.puts shebang + end + + bin_path = File.join @tempdir, "bin", "executable" + write_file bin_path do |io| + io.puts shebang + end + end + + ## + # Creates the following instance variables: + # + # @spec:: + # a spec named 'a', intended for regular installs + # + # @gem:: + # the path to a built gem from @spec + # + # And returns a Gem::Installer for the @spec that installs into @gemhome + + def setup_base_installer(force = true) + @gem = setup_base_gem + util_installer @spec, @gemhome, force + end + + ## + # Creates the following instance variables: + # + # @spec:: + # a spec named 'a', intended for regular installs + # + # And returns a gem built for the @spec + + def setup_base_gem + @spec = setup_base_spec + util_build_gem @spec + @spec.cache_file + end + + ## + # Sets up a generic specification for testing the rubygems installer + # + # And returns it + + def setup_base_spec + quick_gem "a" do |spec| + util_make_exec spec + end + end + + ## + # Creates the following instance variables: + # + # @spec:: + # a spec named 'a', intended for regular installs + # @user_spec:: + # a spec named 'b', intended for user installs + # + # @gem:: + # the path to a built gem from @spec + # @user_gem:: + # the path to a built gem from @user_spec + # + # And returns a Gem::Installer for the @user_spec that installs into Gem.user_dir + + def setup_base_user_installer + @user_spec = quick_gem "b" do |spec| + util_make_exec spec + end + + util_build_gem @user_spec + + @user_gem = @user_spec.cache_file + + Gem::Installer.at @user_gem, user_install: true + end + + ## + # Sets up the base @gem, builds it and returns an installer for it. + # + def util_setup_installer(&block) + @gem = setup_base_gem + + util_setup_gem(&block) + end + + ## + # Builds the @spec gem and returns an installer for it. The built gem + # includes: + # + # bin/executable + # lib/code.rb + # ext/a/mkrf_conf.rb + + def util_setup_gem(ui = @ui, force = true) + @spec.files << File.join("lib", "code.rb") + @spec.extensions << File.join("ext", "a", "mkrf_conf.rb") + + Dir.chdir @tempdir do + FileUtils.mkdir_p "bin" + FileUtils.mkdir_p "lib" + FileUtils.mkdir_p File.join("ext", "a") + + File.open File.join("bin", "executable"), "w" do |f| + f.puts "raise 'ran executable'" + end + + File.open File.join("lib", "code.rb"), "w" do |f| + f.puts "1" + end + + File.open File.join("ext", "a", "mkrf_conf.rb"), "w" do |f| + f << <<-EOF + File.open 'Rakefile', 'w' do |rf| rf.puts "task :default" end + EOF + end + + yield @spec if block_given? + + use_ui ui do + FileUtils.rm_f @gem + + @gem = Gem::Package.build @spec + end + end + + Gem::Installer.at @gem, force: force + end + + ## + # Creates an installer for +spec+ that will install into +gem_home+. + + def util_installer(spec, gem_home, force=true) + Gem::Installer.at(spec.cache_file, + install_dir: gem_home, + force: force) + end + + @@symlink_supported = nil + + # This is needed for Windows environment without symlink support enabled (the default + # for non admin) to be able to skip test for features using symlinks. + def symlink_supported? + if @@symlink_supported.nil? + begin + File.symlink("", "") + rescue Errno::ENOENT, Errno::EEXIST + @@symlink_supported = true + rescue NotImplementedError, SystemCallError + @@symlink_supported = false + end + end + @@symlink_supported + end +end diff --git a/test/rubygems/invalid_issuer_cert.pem b/test/rubygems/invalid_issuer_cert.pem index ea11756bb0..5cb9d22a87 100644 --- a/test/rubygems/invalid_issuer_cert.pem +++ b/test/rubygems/invalid_issuer_cert.pem @@ -1,20 +1,20 @@ -----BEGIN CERTIFICATE----- -MIIDUTCCAjmgAwIBAgIBCjANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv +MIIDMDCCAhigAwIBAgIBCjANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTEyMDEwMTAwMDAwMFoYDzk5 OTkxMjMxMjM1OTU5WjArMRAwDgYDVQQDDAdpbnZhbGlkMRcwFQYKCZImiZPyLGQB -GRYHZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM0ycOSh -SOKDGhDlPZ3+JAWwp7KB2ps/VlLhIsZl0uAHzCAGPNI1I46gmla1g7Gh429fYeJ0 -VgeRTxI/rRWNJ0HX2I9jhaJqAkiOqV5Rk6RkJv/0lU1VSu1IBjKRmV6qXiNeBWA8 -duEPNdd6zKX7UoKcYgmG3BMDuEy67AqWUgZOjc9WUnd6i+mwWciMuNqul69vMvB5 -go4c/rgtp1Y3PhLDIrheYP9s+Bza1MNp0FUFlrPnL5gzZTsP/IX2u7kF3CEhKCZX -ZPX0oZc/pbqIS2OuQ9T6ft6StSwA+9IhAyCeJ9bGyBYK78SyiSfELKyGKbk74SmR -AqjpN2PJX3o/gk8CAwEAAaN/MH0wGgYDVR0RBBMwEYEPaW52YWxpZEBleGFtcGxl -MB0GA1UdDgQWBBST34uxqPfsv8w/+cc9gEChWnnZTjAfBgNVHSMEGDAWgBRfQ272 -mo5FJeki4303XqTVNgKFGzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIC -BDANBgkqhkiG9w0BAQUFAAOCAQEAArzlvf6q7By19O1hSabH9jmnMwxJ7rZT8lr9 -G7gt18nQxgpeY6JczRmZ9wCWpoIE+ohHJ56XVUFsWilVIZ9o7+ASpZlxIErq3pzY -b8SYoOZtGzz6IpucdnaZixOvqXpQQtAsat1/Y+OLaMiyGwzT2VvDkPHsqBphU2qo -n/WwaYPTQF/yqMVM63HLm34+UwzHISChoo1ZT22S3jdWSso2KrLuRN+mfYwgGm26 -h0zRmr3SmfP8yCJhfkTcAUSR/XGLN8KOTXpjzMgsFLqTIeIbTd0e7APIh/6nBqpr -GAudXuQMlPdcYQIT8CBZJ6b36ahb+n+1oc5C9ULaeEwEZtYyLQ== +GRYHZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPEZZzId +y0m1jSbcHBwUc0MLpq/+JJdwLpGrjD35CuI7DNP0MiH+mNHblyTqMadB3font26k +QFIjDZtc1es1Zvt4mNo1lScQsvbVGRFDQK2/xdZ0O0GbK31C7IJ2Boa93F+74f7N +eD6LKn++SWCxHNCKV83RumQ6diG/WdUZQu8k9xjpRywI2u2EwNDETkbhGamj5zNj +7a8pcPyifBxzTiZ9FZvWVaCEODvdIrF4NdIteXyYEQwDRLWD/nQ9Z9wbw4KQCtA/ +UUd+rObocjveau1wLiZryumhZRwwIKZU4+aaANYTFb3tbmUKnoR9aLavKvxEnlF0 +5kHo9xcHoS5ftw8CAwEAAaNeMFwwGgYDVR0RBBMwEYEPaW52YWxpZEBleGFtcGxl +MB0GA1UdDgQWBBR17dM2zZQQPor/k6N4/JXerWXhSDAPBgNVHRMBAf8EBTADAQH/ +MA4GA1UdDwEB/wQEAwICBDANBgkqhkiG9w0BAQsFAAOCAQEALrT6pmN79vdBA80a +f8C1DnWAYNyXskmskWPVMnTtgrDGQkqz0Uqq7nBdWK75FiBjk3XAOiDonZegvho+ +NZUnotUFyTpkkn95q1qpkMwgTufamQlxsBxkDZLPiWqvZS4guSucVgZeEtEOy0R0 +AKXA1SZmhC7472z+pwXprGj86K4SX7w15LxsQ0wDP5qduKFItNo/CnBEP5w87/Eq +nxSbUN3dt7Glqt0iIp/I4mZlA4OnvtKfqTitATKOnBvHxIzvm9/6BVItjET8DRXv +2ZEVvEcnkNNRKwNbqtI3V7AzB3lf3E4nb86gFh/GLI2XRN4LlWZQ4PmyE22B8IaZ +vpqxaQ== -----END CERTIFICATE----- diff --git a/test/rubygems/invalid_issuer_cert_32.pem b/test/rubygems/invalid_issuer_cert_32.pem index bb73772735..2b71179270 100644 --- a/test/rubygems/invalid_issuer_cert_32.pem +++ b/test/rubygems/invalid_issuer_cert_32.pem @@ -1,20 +1,20 @@ -----BEGIN CERTIFICATE----- -MIIDTzCCAjegAwIBAgIBCzANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv +MIIDLjCCAhagAwIBAgIBCzANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTEyMDEwMTAwMDAwMFoXDTM4 MDExOTAzMTQwN1owKzEQMA4GA1UEAwwHaW52YWxpZDEXMBUGCgmSJomT8ixkARkW -B2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNMnDkoUji -gxoQ5T2d/iQFsKeygdqbP1ZS4SLGZdLgB8wgBjzSNSOOoJpWtYOxoeNvX2HidFYH -kU8SP60VjSdB19iPY4WiagJIjqleUZOkZCb/9JVNVUrtSAYykZleql4jXgVgPHbh -DzXXesyl+1KCnGIJhtwTA7hMuuwKllIGTo3PVlJ3eovpsFnIjLjarpevbzLweYKO -HP64LadWNz4SwyK4XmD/bPgc2tTDadBVBZaz5y+YM2U7D/yF9ru5BdwhISgmV2T1 -9KGXP6W6iEtjrkPU+n7ekrUsAPvSIQMgnifWxsgWCu/EsoknxCyshim5O+EpkQKo -6TdjyV96P4JPAgMBAAGjfzB9MBoGA1UdEQQTMBGBD2ludmFsaWRAZXhhbXBsZTAd -BgNVHQ4EFgQUk9+Lsaj37L/MP/nHPYBAoVp52U4wHwYDVR0jBBgwFoAUX0Nu9pqO -RSXpIuN9N16k1TYChRswDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAgQw -DQYJKoZIhvcNAQEFBQADggEBAMXxi62wMgtxERL3Snu9wB+qPBY0oaZn0gxcqH8x -IKbBa+ib63l3UX0vVqzHZlDYxBLTJicU3Cwr7Tm+GHPg/oMkqufxeFZPl/n4uvwY -iogyY5RMsx6C3WqdhA3x+tg04xMxDnAptRWMT4n19myPEadasLBwOqHeXtpc/v2N -XnNFlX3q8NB3AQya+Sp4fxL1fp9sCYlyJolS4dNZGOW4qC5I2GQGlduFom5oOyTB -QyWPs+McRfanWrZgmoViu5x+N7l/xRTJ7WEa9DDqZbPxjCaXrKIyteSIJgqsdqwy -0N+4pygu9VOdQNfQvI2jkxyDZI6rZ/YEr8sxhOKmzvaW0kc= +B2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDxGWcyHctJ +tY0m3BwcFHNDC6av/iSXcC6Rq4w9+QriOwzT9DIh/pjR25ck6jGnQd36J7dupEBS +Iw2bXNXrNWb7eJjaNZUnELL21RkRQ0Ctv8XWdDtBmyt9QuyCdgaGvdxfu+H+zXg+ +iyp/vklgsRzQilfN0bpkOnYhv1nVGULvJPcY6UcsCNrthMDQxE5G4Rmpo+czY+2v +KXD8onwcc04mfRWb1lWghDg73SKxeDXSLXl8mBEMA0S1g/50PWfcG8OCkArQP1FH +fqzm6HI73mrtcC4ma8rpoWUcMCCmVOPmmgDWExW97W5lCp6EfWi2ryr8RJ5RdOZB +6PcXB6EuX7cPAgMBAAGjXjBcMBoGA1UdEQQTMBGBD2ludmFsaWRAZXhhbXBsZTAd +BgNVHQ4EFgQUde3TNs2UED6K/5OjePyV3q1l4UgwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADggEBAGolEDY9meTGpP7j3Meb +pxtLX/JYPiTMqQR+FOOdGJlXg4V9syMBYUMmUj3yEPnpBFmDgDtBaH+OQcFuvf43 +mQYOQoTJD6OpC08fkPdVw56Em+cuUCXtDDYY4gc+nVRKk4+tJqkizHNAazqKkZoQ +PaHaCfXsrMGPLXxh/kbk14ESU9pL0LShh/bNn68hlAKwN2ctTSlfm81QgbNX83d1 +6kLSckj/9B1ksi6ks/eHkHWeMaiJe8H3vAU6PE6NeU3WRZY1ulSGOPleYfJA99fq +z9yks8IxwMzubJStq2sQ0n6gu3XS4Qu0sn3ih0TwRyUOSQkWa2Bf5SwUZ3/YJ25S +Wkw= -----END CERTIFICATE----- diff --git a/test/rubygems/invalid_key.pem b/test/rubygems/invalid_key.pem index 74bedabcda..bc02147403 100644 --- a/test/rubygems/invalid_key.pem +++ b/test/rubygems/invalid_key.pem @@ -1,27 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAzTJw5KFI4oMaEOU9nf4kBbCnsoHamz9WUuEixmXS4AfMIAY8 -0jUjjqCaVrWDsaHjb19h4nRWB5FPEj+tFY0nQdfYj2OFomoCSI6pXlGTpGQm//SV -TVVK7UgGMpGZXqpeI14FYDx24Q8113rMpftSgpxiCYbcEwO4TLrsCpZSBk6Nz1ZS -d3qL6bBZyIy42q6Xr28y8HmCjhz+uC2nVjc+EsMiuF5g/2z4HNrUw2nQVQWWs+cv -mDNlOw/8hfa7uQXcISEoJldk9fShlz+luohLY65D1Pp+3pK1LAD70iEDIJ4n1sbI -FgrvxLKJJ8QsrIYpuTvhKZECqOk3Y8lfej+CTwIDAQABAoIBAFo5I4pjoDh4jK2B -HmapqA0Yb6P9lLFOWBZ5B2FUxDPdOdOa6oNC+i9sTnBxv0YLeIUv20pG/My3B51u -ghxHxEsfLQlfKRMQqZBdqfrew5w0rTE9yagHKLrMQG1bt6P4JQxH+vUloN+0YGgu -hm005EKpoDGwKnPx3sdeKQs+rTI37fGLw40ZPSod2B7UkSna4/u/uXa1yFbONlqq -P4ozsDd1xoCaBJfwie2h93KneSPwyHHumlVgbFAJcQycuD5qproYbea9PppppQ+4 -17M9ccuQpS2j9rZWgk7+KqwLrYqzajmtHoQH4zkBYd0JQ4ywGKg307xDhppMZpq3 -uMqnXgECgYEA9iYB7vX91Q3HsRtUAd0aZ91lDIv9RXBP+PuK3OUrtChdtZx7Mih3 -uTgtfVEnP7bxgnPpwecnF4Ncginuu7TBtxjoztFjuFNzk/8Fz/J3i/H3oB0SdjhL -uqVa6P4hPak7FnWynZHivuuIe+eKYLvK0TCMbYaz6G81xi0Whtbm498CgYEA1Wja -PgscP/9YykCC6eRP+ixo6chGzSNJR+WRW9CJYpXEicPlaT5AI3nSZVXXSLvXIbq9 -NoExPu47pDzr9Gd02qYmFWUOolUa21W4s/x4d7lU+wJzS6ZNTFoC8woZagL2kZ5G -+we5ifbUz7eG+ahZODGMGA9BJVT3PI6zPdKtr5ECgYEAy0ORnypGBXUOrUMa+TsD -fjfGJTlI2dmoQLw/7K/Wijw3PizNUxs12p74eZ7VYXkKMKbVpwjiMDmK3/YOrbTT -rwaD4Z3p0iIftFwJCbJ5Y/hZez/mqfdNGgFIdFS/UHL6V060RAhfjTdlCqSmkcEh -9+M2Y4+z60JCzrcW/hxiqFMCgYEAj9ntwoSatkjZAPwbQq2ze18UGQH3N6/hZaVJ -JiqbcOijYnm52gcsFL25JLWIOG7lxMarZGIRX+oWKc8m/cf+7KOyaBmGk8XqJI7T -wf8c9RboQYqVTRj8YcsK0eis2NjGe8HE9tFuL6FCMgHz6bWg7k/3rwAZWaC8RwWp -rLKmgQECgYBXGjEvogVeYMgnpzjoaa99wvfp6FtbRx1jZ+FOSBoH5uCRDalD5Q16 -0UVnoPcnj0Hi7Hvvl6jTLesRW/LDra5Hqyxs4yuSBagEUFv/PvY0eYGZ5egGZgaa -PlVmxgk33xYXar8wGHLkstwqZY/OqT89cKvJqeLKMb0G2Re13oPVww== +MIIEowIBAAKCAQEA8RlnMh3LSbWNJtwcHBRzQwumr/4kl3AukauMPfkK4jsM0/Qy +If6Y0duXJOoxp0Hd+ie3bqRAUiMNm1zV6zVm+3iY2jWVJxCy9tUZEUNArb/F1nQ7 +QZsrfULsgnYGhr3cX7vh/s14Posqf75JYLEc0IpXzdG6ZDp2Ib9Z1RlC7yT3GOlH +LAja7YTA0MRORuEZqaPnM2Ptrylw/KJ8HHNOJn0Vm9ZVoIQ4O90isXg10i15fJgR +DANEtYP+dD1n3BvDgpAK0D9RR36s5uhyO95q7XAuJmvK6aFlHDAgplTj5poA1hMV +ve1uZQqehH1otq8q/ESeUXTmQej3FwehLl+3DwIDAQABAoIBAAQ1PSEES8XZESzH +nwakcBCQValGW8LNi+/cmSGEb7qxbNC5jIhzBkgfYjIcPkqc3TAeXQFlhNPfgGog +7YDh7o60Ck2WAtOVjdy+AmZ+kH9Cf271719+mFHi3E2N8XY3k8Q9+2dJlHAvA0pg +eq0L2k9kzWcuYmeZF50Q1xNfkf9U0qkb6tbx15NOGFhQMUZ/mMcbYifW/bQnU2YO +2vgxWFDItk0c82gpi/uo22gu0TjhcBp/ByKMgXV8xrLCW7Lsh1DvJ3LtigD0Zp5s +XtdXcF4KOo81VeUijDbByIQQJTxBlfmgdcyarAb7kV107wvDh55Xd8m68lZUrkj5 +tc3dRf0CgYEA+crRUXgtdeiHqN5gZRg6MF6S5yxFiAaKgeeKm/x/2xpMmoiyWhFv +tK1DLxRHEGiFuWc9IGgrWu2udEg8VE4j2EExvtFi/w3lSHxBArjeq7oCabnDk261 +lRCNzYb0HU5UZL3vBsHW8pCdnDfaOxlrT2+cDVN7LHd20DsIZROG7T0CgYEA9xdH +wSNsHqxcB44A7iNNvHxhU3Vi6QCIpzp8sfjc/fd7Ghe/MIn67gs5XPtT+DvQME0N +4hNEy2GmbHjVJQXqlf4VSWdFJ1RnKwL+4rnOiWq5sNrxmlXuTvOTRLimpjOsLKCR +G3dgKXiH7/qU9zjLljKOWgo7gqv3cPrPIL8H0jsCgYEAp99SRTpK8w7O/QJWLhrW +IGOuvoXWRNCAjUUatjI/ivRlvwVXN4i4VeiLWjx6deCI3k0vm3PmjzllIOjbAp1x +IYjO8bqumVKxYMGAv1+W5jogHQWnFpI0nnV9lz63GGrn9Lxgw13KI0JlafNvSoCO +ydfsPFh6UywGQXMq9SLmbtECgYAHWC3N09u23bCumM32Rh5dZ+UMsgSKoHVvYxGp +yJfpBJ4oHGSWcMOAp9zAosfQLRb3GJM9EQ2ObgygVMchHpfmdXL0h5lKnfujD6e7 +3YICG6YBV8CusbcvqZXLCSIK9qY7fVpS0q2NDgQcYfpjjtCeWkpY6szyCWKFfS8C +7iqxWQKBgBIwdnksccXP01svXJ0tMhiAKx1jKY/aJBPIpcSqxTFNe2WpgzynRpUg ++MKAO2Ed6Rec3TTefGRNKDPb5OUsYZUMHeNbIJ1Y1S2pORRffrE3TFWBUM0LkOTj +r4Dl5bcnDRL93Phbx7MAmjMO3TZWbQGfEgDuqk3sS1QzKMJnBLAO -----END RSA PRIVATE KEY----- diff --git a/test/rubygems/invalid_signer_cert.pem b/test/rubygems/invalid_signer_cert.pem index 7f8b5cc727..59364ee51b 100644 --- a/test/rubygems/invalid_signer_cert.pem +++ b/test/rubygems/invalid_signer_cert.pem @@ -1,19 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDEDCCAfigAwIBAgIBDjANBgkqhkiG9w0BAQUFADArMRAwDgYDVQQDDAdpbnZh +MIIDEDCCAfigAwIBAgIBDjANBgkqhkiG9w0BAQsFADArMRAwDgYDVQQDDAdpbnZh bGlkMRcwFQYKCZImiZPyLGQBGRYHZXhhbXBsZTAgFw0xMjAxMDEwMDAwMDBaGA85 OTk5MTIzMTIzNTk1OVowKzEQMA4GA1UEAwwHaW52YWxpZDEXMBUGCgmSJomT8ixk -ARkWB2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNMnDk -oUjigxoQ5T2d/iQFsKeygdqbP1ZS4SLGZdLgB8wgBjzSNSOOoJpWtYOxoeNvX2Hi -dFYHkU8SP60VjSdB19iPY4WiagJIjqleUZOkZCb/9JVNVUrtSAYykZleql4jXgVg -PHbhDzXXesyl+1KCnGIJhtwTA7hMuuwKllIGTo3PVlJ3eovpsFnIjLjarpevbzLw -eYKOHP64LadWNz4SwyK4XmD/bPgc2tTDadBVBZaz5y+YM2U7D/yF9ru5BdwhISgm -V2T19KGXP6W6iEtjrkPU+n7ekrUsAPvSIQMgnifWxsgWCu/EsoknxCyshim5O+Ep -kQKo6TdjyV96P4JPAgMBAAGjPTA7MBoGA1UdEQQTMBGBD2ludmFsaWRAZXhhbXBs -ZTAdBgNVHQ4EFgQUk9+Lsaj37L/MP/nHPYBAoVp52U4wDQYJKoZIhvcNAQEFBQAD -ggEBAGJurQiRw3Vb2LPUhoL9BHyPy8TY+ZXz7eZyzf72saiATkHTuainb9jvLTzf -9ZNYNnjxGNwR4QnDhlh8Vb8vHaYfQGGwiLhd5ZbKjkid/41Y9XmNh+oHCrmwGcS6 -vX4QmTTmPQRBZ2Ilckr+wb1fdpLYk0wW/JFMFdAzp1OO3kP23hYElqia6qeJGw4k -4fe9d56huHHptSJrlMTjHwaqXq6QRjfjF5Za1unCjxQMO2vNQC/dUYRaq/M0kwFN -6A2xHKukkgA9cyjVpFVpxhE3/iFz8OE1GZg7VVcT+Jzhhxaajubpe+ZtDN5rbln/ -NI4WP/ZM3cnxVrHG84G3AYRpkhc= +ARkWB2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDxGWcy +HctJtY0m3BwcFHNDC6av/iSXcC6Rq4w9+QriOwzT9DIh/pjR25ck6jGnQd36J7du +pEBSIw2bXNXrNWb7eJjaNZUnELL21RkRQ0Ctv8XWdDtBmyt9QuyCdgaGvdxfu+H+ +zXg+iyp/vklgsRzQilfN0bpkOnYhv1nVGULvJPcY6UcsCNrthMDQxE5G4Rmpo+cz +Y+2vKXD8onwcc04mfRWb1lWghDg73SKxeDXSLXl8mBEMA0S1g/50PWfcG8OCkArQ +P1FHfqzm6HI73mrtcC4ma8rpoWUcMCCmVOPmmgDWExW97W5lCp6EfWi2ryr8RJ5R +dOZB6PcXB6EuX7cPAgMBAAGjPTA7MBoGA1UdEQQTMBGBD2ludmFsaWRAZXhhbXBs +ZTAdBgNVHQ4EFgQUde3TNs2UED6K/5OjePyV3q1l4UgwDQYJKoZIhvcNAQELBQAD +ggEBACbQA7m+zqdAE1/GrJKcXnC/Ujr1tu6rGpe0uExTwySptgVieUGAOvzlLLrY +r2b/nGmK4bgHkeDPSVuC3F8NhgESvPTuXFSw+DU+1m+mhHxdpW30uSbbebgqV5Ea +GpckCZj1SEdsn/1SDauXCmkrs/MBuK49mYXv3jejX0Rp0STu1NxnU13yrKF0MtrL +fzZ/QF8bOZdg5DwtqMwhDPp72x58KpqAPN9GgdlsTiwOMGy4avds1g5KMGmkK8pK +6I58NEMCOuN4CxFK4oWD9xuD4j+wtHy/UYxqor4rn+UKYHfr5fWtAyRJ3gD8vMUu +C+Nl2vB8t4OVwS5FCcn0ZK18bPU= -----END CERTIFICATE----- diff --git a/test/rubygems/invalid_signer_cert_32.pem b/test/rubygems/invalid_signer_cert_32.pem index 657608e503..97feb8fd0a 100644 --- a/test/rubygems/invalid_signer_cert_32.pem +++ b/test/rubygems/invalid_signer_cert_32.pem @@ -1,19 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDDjCCAfagAwIBAgIBDzANBgkqhkiG9w0BAQUFADArMRAwDgYDVQQDDAdpbnZh +MIIDDjCCAfagAwIBAgIBDzANBgkqhkiG9w0BAQsFADArMRAwDgYDVQQDDAdpbnZh bGlkMRcwFQYKCZImiZPyLGQBGRYHZXhhbXBsZTAeFw0xMjAxMDEwMDAwMDBaFw0z ODAxMTkwMzE0MDdaMCsxEDAOBgNVBAMMB2ludmFsaWQxFzAVBgoJkiaJk/IsZAEZ -FgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzTJw5KFI -4oMaEOU9nf4kBbCnsoHamz9WUuEixmXS4AfMIAY80jUjjqCaVrWDsaHjb19h4nRW -B5FPEj+tFY0nQdfYj2OFomoCSI6pXlGTpGQm//SVTVVK7UgGMpGZXqpeI14FYDx2 -4Q8113rMpftSgpxiCYbcEwO4TLrsCpZSBk6Nz1ZSd3qL6bBZyIy42q6Xr28y8HmC -jhz+uC2nVjc+EsMiuF5g/2z4HNrUw2nQVQWWs+cvmDNlOw/8hfa7uQXcISEoJldk -9fShlz+luohLY65D1Pp+3pK1LAD70iEDIJ4n1sbIFgrvxLKJJ8QsrIYpuTvhKZEC -qOk3Y8lfej+CTwIDAQABoz0wOzAaBgNVHREEEzARgQ9pbnZhbGlkQGV4YW1wbGUw -HQYDVR0OBBYEFJPfi7Go9+y/zD/5xz2AQKFaedlOMA0GCSqGSIb3DQEBBQUAA4IB -AQA6WW6YyykIJmVFW8Og1R3d8fbFtQarDMGN+oZrCN3Eb9Twoy36Yr/h0bZgkCEe -arB+VCD1DfEii5luZowUDr/BlIjIR2cNIMFpmQ8ZLIpVWQz/BYHrbw7CHO5df3mg -HYTKlEoUMimOEWvCYnSgzKWCgSWU/jBQQ0bcUBk2HHpdT4BnLPe/7rs+TZmwd/Dz -r80sNXQ6vqTkQS+te2hqyh62r+WeaFx7aqnFjGtwiOqMmYPr80uYOy/rX26mmfwm -vyf8JlA4uTt795Krsc4Brc+BO0bOPfDDGhRs/2tvyHhOOqBbUxQeeV5ogiAZmA31 -ZrzbFysajMrWZ+1GV8QXOcBi +FgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8RlnMh3L +SbWNJtwcHBRzQwumr/4kl3AukauMPfkK4jsM0/QyIf6Y0duXJOoxp0Hd+ie3bqRA +UiMNm1zV6zVm+3iY2jWVJxCy9tUZEUNArb/F1nQ7QZsrfULsgnYGhr3cX7vh/s14 +Posqf75JYLEc0IpXzdG6ZDp2Ib9Z1RlC7yT3GOlHLAja7YTA0MRORuEZqaPnM2Pt +rylw/KJ8HHNOJn0Vm9ZVoIQ4O90isXg10i15fJgRDANEtYP+dD1n3BvDgpAK0D9R +R36s5uhyO95q7XAuJmvK6aFlHDAgplTj5poA1hMVve1uZQqehH1otq8q/ESeUXTm +Qej3FwehLl+3DwIDAQABoz0wOzAaBgNVHREEEzARgQ9pbnZhbGlkQGV4YW1wbGUw +HQYDVR0OBBYEFHXt0zbNlBA+iv+To3j8ld6tZeFIMA0GCSqGSIb3DQEBCwUAA4IB +AQBM/EjV791vKu2KQQAhd03eUXfMlvObwEj9nGtEEnSFH5i16V1m8Y5ZY7Aw+VR5 +/xJ9J2AvFG6EXclDVmkDQpo1fUVhWM/SPKD6HJWuB/eyjA30xSj+UeLmBYjdKzHt +kK+HeEaGVQaT5j8OPOW6meGriucdBWtwbhTdyZgqvwpuZwbtPpElYXwGgSijKqHI +GG6RWzeANdG/4AIChrp8CIgFfW4sbmlIZK3BAXuSvZ9A/deYqC2DAadJIoTJ9H6w +0TgYlyTidaWtCkqRBXc3qrwpc/r3wJwpgan0kJAQ2kGc5W7gYUylpoS56sFq23YX +Fmm0pRq5UZj9jKZUIwcqAoGo -----END CERTIFICATE----- diff --git a/test/rubygems/invalidchild_cert.pem b/test/rubygems/invalidchild_cert.pem index 936dc650c9..281dcce655 100644 --- a/test/rubygems/invalidchild_cert.pem +++ b/test/rubygems/invalidchild_cert.pem @@ -1,20 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDOTCCAiGgAwIBAgIBEDANBgkqhkiG9w0BAQUFADApMQ4wDAYDVQQDDAVjaGls +MIIDGDCCAgCgAwIBAgIBEDANBgkqhkiG9w0BAQsFADApMQ4wDAYDVQQDDAVjaGls ZDEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwIBcNMTIwMTAxMDAwMDAwWhgPOTk5 OTEyMzEyMzU5NTlaMDAxFTATBgNVBAMMDGludmFsaWRjaGlsZDEXMBUGCgmSJomT -8ixkARkWB2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDl -rDAlDZwmP6Zxc4sSaOdSRRXJBmbQubxmWpqU8bXrTKCkvg1l/2U6weJIS52zW6Te -Zok7Uus5jywyeNSJ/MBHb7X5ytAPQsvLu/3WFwaVfHJzimQI4vtmx9+CDgZzipYp -ett7IF18He8DPiFur1xCn8pp0qOOV8mXL/8TpUgJfmaOJosqgFqorj5niqF52IwJ -vtur/gwpq2xpCtYaCUB/dFzzefLV37kt58S6jTmZnYf4kIdFKhhyTeGmDRf/wOz+ -kK/H/aKtpsYgzI//bo+bsuWNFceIdWrdCBr63cVs4ql7VN7p2xfn9ckEfwH6wFut -QLquA/6fRkgUFF8fxUiHAgMBAAGjYzBhMB8GA1UdEQQYMBaBFGludmFsaWRjaGls -ZEBleGFtcGxlMB0GA1UdDgQWBBSwAwFqdxjicsovAzZ1ZeSAWlnKcDAfBgNVHSME -GDAWgBR81VPTe7JJSgT6xxJcaGd9hYOuCDANBgkqhkiG9w0BAQUFAAOCAQEAYxom -7nHgbfqLiMtVwx8D6LM6P3sk3p5HwoHJU0zzFVfPA0iuhhC2vWyPoHJroq6d31DG -DpPpOeVQxTYyQ6CtD6jGUpE+0MjmRoavFnvqFH5lf4OKO0dQ8xUa9fALo7fmK0v0 -ueDlgsHw3mwoVNX2Xu/+jCTuiK2KGG3J+pxr6JNA1++gQEghFFJjM8rw1/mYrDW0 -CSCyx/LeNyYbt9xzeVgo83XNO5TCfwwh8+df52I6Hj5BDFhhkP8KOai4ejq2CmZ8 -by9ylCUXc/aiz9mzX/NzIAYLuRzkmrI+lxDbUJpG/hV7MCS/TZegjD+SUSu9EI1O -RVerg89R7kQUWZyJqg== +8ixkARkWB2V4YW1wbGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDs +dqLesclj2/6HnJLw4al4swiDFBA4W0KeOS3DXOa2k5+rNfGacKOQ/AkciUnzqLiC +9D49x/YLlnlJYeSMG57C7gixhLHHDviCneQwy8TlCpuhUXnfcpmHQO+X/c+lrVB7 +wHTPjl5yZYzLFtPa8QAEtJa83E2GrUd+JEOwTRErOcBucIRP5HbeR2aD7BVP1V+F +gaUhOZb/n2e53diQF7BZurB45DTWQ2L1R/m8VldQiWoTZluWqnCGeEwtpZJXt9kU +8y5rQcxI3p8Qx4q0ilLKsE7c/sw2wzEFWoZ4BeURnjxdvPgYeOPk4K3a34pFg7lZ +u1s9XvjChJVsD8HRnbQtAgMBAAGjQjBAMB8GA1UdEQQYMBaBFGludmFsaWRjaGls +ZEBleGFtcGxlMB0GA1UdDgQWBBS3tDKiI1oVuEkKtGux8TsEy/8iuDANBgkqhkiG +9w0BAQsFAAOCAQEAQsgdq4NZBnQRk+eNbwS4go3S+m5cPPWY7kG94kpQ3aC3nwR4 +wnICb/hd+kRCB2azTTBY8PA0SkHxIXWgRFjdEpIAekm3Xtag+lCC1q7jtDTNoHw4 +KOdfeBEF621FHL5vBvJmnRMH8f4sCjVZZE8RJcaWAK7uJJXi6gzUm3xz0UnylZNr +vA+Z+cM5pFnCfxxqXUyT0MRb47O/wqH4f5SybKpOxO3+vnzpSeN++zgdMVjA/Pl0 +0SB8VKNKXGLQrvY2S3GuRoh7OD1DhRPzUTQ8gwwBAlhw2i3i5t9ib0ujw9MUO3GR +dqn4Yco98R0+wFpY8feGhr5uJNDuIC10l5LHLQ== -----END CERTIFICATE----- diff --git a/test/rubygems/invalidchild_cert_32.pem b/test/rubygems/invalidchild_cert_32.pem index 07687eb156..87885157f8 100644 --- a/test/rubygems/invalidchild_cert_32.pem +++ b/test/rubygems/invalidchild_cert_32.pem @@ -1,20 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDNzCCAh+gAwIBAgIBETANBgkqhkiG9w0BAQUFADApMQ4wDAYDVQQDDAVjaGls +MIIDFjCCAf6gAwIBAgIBETANBgkqhkiG9w0BAQsFADApMQ4wDAYDVQQDDAVjaGls ZDEXMBUGCgmSJomT8ixkARkWB2V4YW1wbGUwHhcNMTIwMTAxMDAwMDAwWhcNMzgw MTE5MDMxNDA3WjAwMRUwEwYDVQQDDAxpbnZhbGlkY2hpbGQxFzAVBgoJkiaJk/Is -ZAEZFgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5aww -JQ2cJj+mcXOLEmjnUkUVyQZm0Lm8ZlqalPG160ygpL4NZf9lOsHiSEuds1uk3maJ -O1LrOY8sMnjUifzAR2+1+crQD0LLy7v91hcGlXxyc4pkCOL7Zsffgg4Gc4qWKXrb -eyBdfB3vAz4hbq9cQp/KadKjjlfJly//E6VICX5mjiaLKoBaqK4+Z4qhediMCb7b -q/4MKatsaQrWGglAf3Rc83ny1d+5LefEuo05mZ2H+JCHRSoYck3hpg0X/8Ds/pCv -x/2irabGIMyP/26Pm7LljRXHiHVq3Qga+t3FbOKpe1Te6dsX5/XJBH8B+sBbrUC6 -rgP+n0ZIFBRfH8VIhwIDAQABo2MwYTAfBgNVHREEGDAWgRRpbnZhbGlkY2hpbGRA -ZXhhbXBsZTAdBgNVHQ4EFgQUsAMBancY4nLKLwM2dWXkgFpZynAwHwYDVR0jBBgw -FoAUfNVT03uySUoE+scSXGhnfYWDrggwDQYJKoZIhvcNAQEFBQADggEBAGK07MzH -/TJftVEgrghvEHIna0gadQUbWfrpMWxt/Vj7jsd4LvRaZEOWObMRxhtjMvMA2q3A -qKXoP1KddPkFGfAVdUsNKTKLsaMvDceZ7aN3SGEWv5IYGXtfjUEVhWj7CmpS05li -Phw9uPQVUwkkY20G2UGInRzxCYqyeW5KZIaep49KebaXCrjrV5Xy13UxgtpbmNMj -yKPvyA5u0J8TK4gQmx1Az0gujpT1KSwfMyEDrsbIqYDVMp4kF2yLlsrdmNT9Jhwj -R+M6AMhNqpLrjsklqE6TX2pCQGo+JFxCDOKQmvv5B7AhH0od46Jlwk//aIAheQQK -4rhDHEHYLCxGhrw= +ZAEZFgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7Hai +3rHJY9v+h5yS8OGpeLMIgxQQOFtCnjktw1zmtpOfqzXxmnCjkPwJHIlJ86i4gvQ+ +Pcf2C5Z5SWHkjBuewu4IsYSxxw74gp3kMMvE5QqboVF533KZh0Dvl/3Ppa1Qe8B0 +z45ecmWMyxbT2vEABLSWvNxNhq1HfiRDsE0RKznAbnCET+R23kdmg+wVT9VfhYGl +ITmW/59nud3YkBewWbqweOQ01kNi9Uf5vFZXUIlqE2ZblqpwhnhMLaWSV7fZFPMu +a0HMSN6fEMeKtIpSyrBO3P7MNsMxBVqGeAXlEZ48Xbz4GHjj5OCt2t+KRYO5Wbtb +PV74woSVbA/B0Z20LQIDAQABo0IwQDAfBgNVHREEGDAWgRRpbnZhbGlkY2hpbGRA +ZXhhbXBsZTAdBgNVHQ4EFgQUt7QyoiNaFbhJCrRrsfE7BMv/IrgwDQYJKoZIhvcN +AQELBQADggEBAFPyjOoghY6Iba9+psCWC//rwLtDfZPQ3kO9hFtd4CGvalPtR103 +Oc1Dk5pxHSWDTdeQfOb75mqWuqs4ET7IUyw8yY+bKkOOhY1ldwaJhTyP/fkElnrL +prsLSpB3AdQceS1Ob2wpMaaGIPDzJlW0LG8cQNeU3SRTTdBjX5zjG6imHKG2yuJd +76PM0tl8ooslPABlYSPSLpd1PAARqxG2ekfrxZioCLknyhBtcRsl1aMWWBiG4BH9 +xZoJvEHwpOMTxMaAFXSkyMjZAoOzAn9qP6eLbwwzeuckIrZXxYBfGcC29VOPPAN4 +IPX0IUZ7/LlzzOE5iuVS/RIBRcD+qpEzSXs= -----END CERTIFICATE----- diff --git a/test/rubygems/invalidchild_key.pem b/test/rubygems/invalidchild_key.pem index 9706c9566e..1c9997150d 100644 --- a/test/rubygems/invalidchild_key.pem +++ b/test/rubygems/invalidchild_key.pem @@ -1,27 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIIEpgIBAAKCAQEA5awwJQ2cJj+mcXOLEmjnUkUVyQZm0Lm8ZlqalPG160ygpL4N -Zf9lOsHiSEuds1uk3maJO1LrOY8sMnjUifzAR2+1+crQD0LLy7v91hcGlXxyc4pk -COL7Zsffgg4Gc4qWKXrbeyBdfB3vAz4hbq9cQp/KadKjjlfJly//E6VICX5mjiaL -KoBaqK4+Z4qhediMCb7bq/4MKatsaQrWGglAf3Rc83ny1d+5LefEuo05mZ2H+JCH -RSoYck3hpg0X/8Ds/pCvx/2irabGIMyP/26Pm7LljRXHiHVq3Qga+t3FbOKpe1Te -6dsX5/XJBH8B+sBbrUC6rgP+n0ZIFBRfH8VIhwIDAQABAoIBAQC59hllZwev0Ims -AqnwVhA2hMmG4zAMgNcS6PmQ78Ukp/7KZTfkBk6orKPTdaZSuzla+hrTdegPyuU2 -WK9+qq/lJ4ZootakBKmOZMC6wBoMn57r/nnQ2DhGmD9YxpJiqyu6mkdsAmCvRm1o -ar4XKNXC/C6gUHUto9cOG0alWYZiZ/VMe/nhPTChr2Dhd+bavO1yx7/CxB+VQMfQ -l6ihbv//3KgPJAElbaI7jfOGzX6KlwXSGf70REmZQnPGN4/n46/dLFFuA1HzcA5Z -37NU1zgN2nIrXld8rsR1mSy6EwU46sW3AkEwv6SUajCjz7PCmmWxRaQErGJjZrUq -sujNj5RBAoGBAPgdiY+6B7WvmLlCBCwI4PXjgRQ/6A1Ycgvi1LdSQzccSHddogNI -tWKa0pIrYyH7y7jB/UzstFSnsOXAf4H6Xt70VUrFPq1/dRRw1CtSLA1sFspBAD8v -aGl9R0XqWOk1t60mfgES9b4LJu46cTm7UMfyC7EbWkqHYWqf15umRgwrAoGBAOz4 -nZGqBVBW/ERDs+Imf9NcwDeuwllQ0S9ZBPHF///SQ4Rscz2Bl8GhjhTHldLNJg9k -HjP8W2BOPas66K3WM+WC3AiGrdJfs6Ju3r27X4wA0hnNc6bcoRaoSNRaqThSkgCH -l34l7yrB1gwpa5HlIfYXjHfJ7coX7WRMQK7wmVsVAoGBAJ/Y97z/DuSAgpYn7+Qm -vDfuIETZfzjJ2H/L3VtVxjQFJrKwQiZ3e1RRhoPhK/bC79bSM8yRWwSHHLKIOB2X -HfPp2eFX/i9sxBMtNaPLRtJG5s/a3LvYYR5FNdvXRPzKPNFy0Q8EFgofyS8Fu9iD -02FdkSbDBoKpgZtd61w93TcNAoGBAKtM4SKeRC8aYku6oTtW10pkHvNhmk5UVJMk -h6V6mx9D0NjWSMvqdVhcv8eXq19yOxQfLJIp16gbhwrTj8WyNVuwp/xl1xtfYQyH -lu6Sl3QuV7KdSQATN0OYrOUNEIyNa8uEOOfQ5j4DVwb9niwd9dnelgU17HYNq+a4 -FH4hoMotAoGBAJk/9+RPAdxqJsr/oVp9E4wU9ffpZ2Lr0faN7/WqBFPPhhFOMWu2 -zj8fcRaP/9Wv9g2xK/GfCKhrX8FMfq/NMkZsNx6V3W0M8Zbarp9ZvA4Sj0OvsZAO -J1NQjkvFjMCE0A29jtjY1zRmLzoC+Ds7Ola8IOKvAN8SM1X/CC6bOgGz +MIIEowIBAAKCAQEA7Hai3rHJY9v+h5yS8OGpeLMIgxQQOFtCnjktw1zmtpOfqzXx +mnCjkPwJHIlJ86i4gvQ+Pcf2C5Z5SWHkjBuewu4IsYSxxw74gp3kMMvE5QqboVF5 +33KZh0Dvl/3Ppa1Qe8B0z45ecmWMyxbT2vEABLSWvNxNhq1HfiRDsE0RKznAbnCE +T+R23kdmg+wVT9VfhYGlITmW/59nud3YkBewWbqweOQ01kNi9Uf5vFZXUIlqE2Zb +lqpwhnhMLaWSV7fZFPMua0HMSN6fEMeKtIpSyrBO3P7MNsMxBVqGeAXlEZ48Xbz4 +GHjj5OCt2t+KRYO5WbtbPV74woSVbA/B0Z20LQIDAQABAoIBAF/yuZ60NDwVWb/s +LAGbB3mm58bMPtKnUS5DlEqn6SPfXdQKhPj+SJh9dDMEkCHS7d+RPKoz96X3DkrU +8nhZgr+k95kUd1CGxha1+5BDNqcbeU/pcBLXfO2RT0b0oauf2j8EtkE8Cx3PD+Se +ZCN8U94U6u9CUyDZMd/A1kh01Qkc08mCJQ0UtPbt5iRFp9nGQaN3ZOXG6taPQVOB +M91DUUPKny74ptMrqlyRRBylTpUlSjsjo3T5LRNSVXMNubfNG2+sf1Vn/Os/3KAL +PTqc9LLNaHpR/z/oFC/wUiMdJzHB1vBFUcwHvTmahVfqwaffqLj/zJa12ztMcZ/W +efRFBb8CgYEA9c6JvqB0gR14Q6Shj7Yg6JM/dO3e8yllvGRsJm0S6IHHlblWeUEA +OeY099wD0y0oK56XvgfZyd2k+hK/FKf5/otgCyzr1i64sx+hpHE6MZ/s08VLYZvt ++N9fdk7Z5crZImo8vne+7AfBhY1UNk6QjwSUMe8U/zQ6BBGbNhKtgCcCgYEA9kTo +6xyt836PGSXFSnup3wdjlbpMlXMnvZG2V0Aw3ILdTg2iGGf37UUBzDjnZFxVRPqm +PqHJwzjd8PZesDFvaZQ1Sn4nRLKZj0aLLOGuaUOoTAP04fQkYltWR+j8w+d4JxX6 +CDNbNtf4EYRVhfNO02WCNyE4xHya7s6u4tnySYsCgYBNlRPay/AZtIB58SNhJZ37 +akZUFKQS4ZUPwi50bmbSZevlsOq/OKnmnGdJd/LpG06bfeHtA7NUyJVCrNoMnfwE +wF7fCB2jq3l2Z9xv96DjetOX/6SMOVgB/ha2U6rooX6pIxjrEQZ8nvIQwgu7XE66 +JTrVC933srdBA4GWrox+bwKBgQCRZLWuuUvpyfpp+ma0RrZPumkM6OR2B3qa7QAe +GwO97HUDtADTL+6r4mXhUGcsVWbyRpkHuTUJUPWXYZ0doNIKHzonNLuyT09hy2A3 +qzXxZ8RgvKVDEYS5nPsfkWpJrsq9KLhpRwi/JFqM3PgxESiknfV23uJI/tfpzZRq +0gm9aQKBgBuxr0xIXZpUuXwOnLIyp0qTPltXPentl71qV3tQvkqlBU+nCKnaa0ur +7PuEGuFC0jiPiBuRbcO81kq9QTPX6poEYSEFhHphuj9o5/G8MqnC9GzHqVwjc+fI +JPiixH1Dx9YWsCbnCw72lEdpnxMgk1efnzbV00tl63JgMjkyHBJz -----END RSA PRIVATE KEY----- diff --git a/test/rubygems/mock_gem_ui.rb b/test/rubygems/mock_gem_ui.rb new file mode 100644 index 0000000000..1ece78fde7 --- /dev/null +++ b/test/rubygems/mock_gem_ui.rb @@ -0,0 +1,86 @@ +# frozen_string_literal: true + +require "rubygems/user_interaction" + +## +# This Gem::StreamUI subclass records input and output to StringIO for +# retrieval during tests. + +class Gem::MockGemUi < Gem::StreamUI + ## + # Raised when you haven't provided enough input to your MockGemUi + + class InputEOFError < RuntimeError + def initialize(question) + super "Out of input for MockGemUi on #{question.inspect}" + end + end + + class TermError < RuntimeError + attr_reader :exit_code + + def initialize(exit_code) + super + @exit_code = exit_code + end + end + + class SystemExitException < RuntimeError; end + + module TTY + attr_accessor :tty + + def tty? + @tty = true unless defined?(@tty) + @tty + end + + def noecho + yield self + end + end + + def initialize(input = "") + require "stringio" + ins = StringIO.new input + outs = StringIO.new + errs = StringIO.new + + ins.extend TTY + outs.extend TTY + errs.extend TTY + + super ins, outs, errs, true + + @terminated = false + end + + def ask(question) + raise InputEOFError, question if @ins.eof? + + super + end + + def input + @ins.string + end + + def output + @outs.string + end + + def error + @errs.string + end + + def terminated? + @terminated + end + + def terminate_interaction(status=0) + @terminated = true + + raise TermError, status if status != 0 + raise SystemExitException + end +end diff --git a/test/rubygems/multifactor_auth_utilities.rb b/test/rubygems/multifactor_auth_utilities.rb new file mode 100644 index 0000000000..1133131a76 --- /dev/null +++ b/test/rubygems/multifactor_auth_utilities.rb @@ -0,0 +1,111 @@ +# frozen_string_literal: true + +## +# A MultifactorAuthFetcher is a FakeFetcher that adds paths to data for requests related to +# multi-factor authentication. +# + +require_relative "utilities" +require "json" + +class Gem::MultifactorAuthFetcher < Gem::FakeFetcher + attr_reader :host, :webauthn_url + + # GET /api/v1/webauthn_verification defaults to user does not have any security devices + def initialize(host: nil) + super() + @host = host || Gem.host + @path_token = "odow34b93t6aPCdY" + @webauthn_url = "#{@host}/webauthn_verification/#{@path_token}" + @data["#{@host}/api/v1/webauthn_verification"] = Gem::HTTPResponseFactory.create( + body: "You don't have any security devices", + code: 422, + msg: "Unprocessable Entity" + ) + end + + # given a url, return a response that requires multifactor authentication + def respond_with_require_otp(url, success_body) + response_fail = "You have enabled multifactor authentication" + + @data[url] = proc do + @call_count ||= 0 + if (@call_count += 1).odd? + Gem::HTTPResponseFactory.create(body: response_fail, code: 401, msg: "Unauthorized") + else + Gem::HTTPResponseFactory.create(body: success_body, code: 200, msg: "OK") + end + end + end + + # GET /api/v1/webauthn_verification returns a webauthn url + # GET /api/v1/webauthn_verification/:token/status.json (polling url) returns pending status + def respond_with_webauthn_url + @data["#{@host}/api/v1/webauthn_verification"] = Gem::HTTPResponseFactory.create(body: @webauthn_url, code: 200, msg: "OK") + @data["#{@host}/api/v1/webauthn_verification/#{@path_token}/status.json"] = Gem::HTTPResponseFactory.create( + body: { status: "pending", message: "Security device authentication is still pending." }.to_json, + code: 200, + msg: "OK" + ) + end + + # GET /api/v1/webauthn_verification/:token/status.json returns success status with OTP code + def respond_with_webauthn_polling(code) + @data["#{@host}/api/v1/webauthn_verification/#{@path_token}/status.json"] = Gem::HTTPResponseFactory.create( + body: { status: "success", code: code }.to_json, + code: 200, + msg: "OK" + ) + end + + # GET /api/v1/webauthn_verification/:token/status.json returns expired status + def respond_with_webauthn_polling_failure + @data["#{@host}/api/v1/webauthn_verification/#{@path_token}/status.json"] = Gem::HTTPResponseFactory.create( + body: { + status: "expired", + message: "The token in the link you used has either expired or been used already.", + }.to_json, + code: 200, + msg: "OK" + ) + end + + def webauthn_url_with_port(port) + "#{@webauthn_url}?port=#{port}" + end +end + +## +# The MockTCPServer for use in tests or to avoid real TCPServer instances to be created +# when testing code related to the WebAuthn listener. +# +# Example: +# +# server = Gem::MockTCPServer +# port = server.addr[1].to_s +# +# # this mocks waiting for a request by calling sleep +# server.accept +# +# # this mocks the server closing +# server.close + +class Gem::MockTCPServer + attr_reader :port + + def initialize(port = 5678) + @port = port + end + + def close + true + end + + def addr + ["AF_INET6", @port, "::", "::"] + end + + def accept + sleep + end +end diff --git a/test/rubygems/package/tar_test_case.rb b/test/rubygems/package/tar_test_case.rb new file mode 100644 index 0000000000..e3d812bf3f --- /dev/null +++ b/test/rubygems/package/tar_test_case.rb @@ -0,0 +1,175 @@ +# frozen_string_literal: true + +require_relative "../helper" +require "rubygems/package" + +## +# A test case for Gem::Package::Tar* classes + +class Gem::Package::TarTestCase < Gem::TestCase + def ASCIIZ(str, length) + str + "\0" * (length - str.length) + end + + def SP(s) + s + " " + end + + def SP_Z(s) + s + " \0" + end + + def Z(s) + s + "\0" + end + + def assert_headers_equal(expected, actual) + expected = expected.to_s unless String === expected + actual = actual.to_s unless String === actual + + fields = %w[ + name 100 + mode 8 + uid 8 + gid 8 + size 12 + mtime 12 + checksum 8 + typeflag 1 + linkname 100 + magic 6 + version 2 + uname 32 + gname 32 + devmajor 8 + devminor 8 + prefix 155 + ] + + offset = 0 + + until fields.empty? do + name = fields.shift + length = fields.shift.to_i + + if name == "checksum" + chksum_off = offset + offset += length + next + end + + assert_equal expected[offset, length], actual[offset, length], + "Field #{name} of the tar header differs." + + offset += length + end + + assert_equal expected[chksum_off, 8], actual[chksum_off, 8] + end + + def calc_checksum(header) + sum = header.sum(0) + SP(Z(to_oct(sum, 6))) + end + + def header(type, fname, dname, length, mode, mtime, checksum = nil, linkname = "") + checksum ||= " " * 8 + + arr = [ # struct tarfile_entry_posix + ASCIIZ(fname, 100), # char name[100]; ASCII + (Z unless filled) + Z(to_oct(mode, 7)), # char mode[8]; 0 padded, octal null + Z(to_oct(0, 7)), # char uid[8]; ditto + Z(to_oct(0, 7)), # char gid[8]; ditto + Z(to_oct(length, 11)), # char size[12]; 0 padded, octal, null + Z(to_oct(mtime, 11)), # char mtime[12]; 0 padded, octal, null + checksum, # char checksum[8]; 0 padded, octal, null, space + type, # char typeflag[1]; file: "0" dir: "5" + ASCIIZ(linkname, 100), # char linkname[100]; ASCII + (Z unless filled) + "ustar\0", # char magic[6]; "ustar\0" + "00", # char version[2]; "00" + ASCIIZ("wheel", 32), # char uname[32]; ASCIIZ + ASCIIZ("wheel", 32), # char gname[32]; ASCIIZ + Z(to_oct(0, 7)), # char devmajor[8]; 0 padded, octal, null + Z(to_oct(0, 7)), # char devminor[8]; 0 padded, octal, null + ASCIIZ(dname, 155), # char prefix[155]; ASCII + (Z unless filled) + ] + + h = arr.join + ret = ASCIIZ(h, 512) + assert_equal(512, ret.size) + ret + end + + def header_with_checksum(type, fname, dname, length, mode, mtime, linkname = "") + h = header(type, fname, dname, length, mode, mtime, nil, linkname) + checksum = calc_checksum(h) + header(type, fname, dname, length, mode, mtime, checksum, linkname) + end + + def tar_dir_header(name, prefix, mode, mtime) + header_with_checksum("5", name, prefix, 0, mode, mtime) + end + + def tar_file_header(fname, dname, mode, length, mtime) + header_with_checksum("0", fname, dname, length, mode, mtime) + end + + def tar_symlink_header(fname, dname, mode, mtime, linkname) + header_with_checksum("2", fname, dname, 0, mode, mtime, linkname) + end + + def tar_file_contents(content) + pad = (512 - (content.size % 512)) % 512 + content + "\0" * pad + end + + def to_oct(n, pad_size) + format("%0#{pad_size}o", n) + end + + def util_entry(tar) + io = tar.respond_to?(:read) ? tar : TempIO.new(tar) + + header = Gem::Package::TarHeader.from io + + Gem::Package::TarReader::Entry.open header, io + end + + def close_util_entry(entry) + entry.instance_variable_get(:@io).close! + end + + def util_dir_entry + util_entry tar_dir_header("foo", "bar", 0, Time.now) + end + + def util_symlink_entry + util_entry tar_symlink_header("foo", "bar", 0, Time.now, "link") + end + + def util_tar(&block) + tar_io = StringIO.new + Gem::Package::TarWriter.new(tar_io, &block) + tar_io.rewind + tar_io + end + + def util_tar_gz(&block) + tar_io = util_tar(&block) + StringIO.new util_gzip(tar_io.string) + end + + def util_gem_data_tar(spec = nil, &block) + data_tgz = util_tar_gz(&block) + util_tar do |tar| + if spec + tar.add_file "metadata.gz", 0o444 do |io| + io.write util_gzip(spec.to_yaml) + end + end + tar.add_file "data.tar.gz", 0o644 do |io| + io.write data_tgz.string + end + end + end +end diff --git a/test/rubygems/packages/Bluebie-legs-0.6.2.gem b/test/rubygems/packages/Bluebie-legs-0.6.2.gem Binary files differnew file mode 100644 index 0000000000..60918f3bc5 --- /dev/null +++ b/test/rubygems/packages/Bluebie-legs-0.6.2.gem diff --git a/test/rubygems/packages/ill-formatted-platform-1.0.0.10.gem b/test/rubygems/packages/ill-formatted-platform-1.0.0.10.gem Binary files differnew file mode 100644 index 0000000000..58a13535c2 --- /dev/null +++ b/test/rubygems/packages/ill-formatted-platform-1.0.0.10.gem diff --git a/test/rubygems/plugin/load/rubygems_plugin.rb b/test/rubygems/plugin/load/rubygems_plugin.rb index 7cc6bef90b..21fef10bb1 100644 --- a/test/rubygems/plugin/load/rubygems_plugin.rb +++ b/test/rubygems/plugin/load/rubygems_plugin.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + class TestGem TEST_PLUGIN_LOAD = :loaded end diff --git a/test/rubygems/plugin/exception/rubygems_plugin.rb b/test/rubygems/plugin/scripterror/rubygems_plugin.rb index 9a6f557b5c..0acd55be12 100644 --- a/test/rubygems/plugin/exception/rubygems_plugin.rb +++ b/test/rubygems/plugin/scripterror/rubygems_plugin.rb @@ -1,3 +1,4 @@ # frozen_string_literal: true + TestGem::TEST_PLUGIN_EXCEPTION = :loaded -raise Exception.new('boom') +raise ScriptError.new("boom") diff --git a/test/rubygems/plugin/standarderror/rubygems_plugin.rb b/test/rubygems/plugin/standarderror/rubygems_plugin.rb index 94cf4e8a52..58e4080f05 100644 --- a/test/rubygems/plugin/standarderror/rubygems_plugin.rb +++ b/test/rubygems/plugin/standarderror/rubygems_plugin.rb @@ -1,3 +1,4 @@ # frozen_string_literal: true + TestGem::TEST_PLUGIN_STANDARDERROR = :loaded -raise StandardError.new('boom') +raise StandardError.new("boom") diff --git a/test/rubygems/private_ec_key.pem b/test/rubygems/private_ec_key.pem new file mode 100644 index 0000000000..5d855d0dfc --- /dev/null +++ b/test/rubygems/private_ec_key.pem @@ -0,0 +1,9 @@ +-----BEGIN EC PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,4107F98A374CB8EC18F1AA4EA4B6A0DB + +BRklFxJGcz7gqQYxek8TZkt8qbPhB0FSR6nyw3SYuio/2tlT9ohs74mlK3EbG9Lt +Y4OquJbksBFmoB7fIoM4vnuIZ0Eoz2ooxn9tjhBtqJ3mVscYXwZmA3UDUWDMlviQ +Fu37OpikQv4TFA1jlmUK0LM8xmUCfUeLl0kHD17lFsz2gkO2kwg8mn/YUMOIaDOu +EnnmxbAwnZBpemQkQfpTt2mYL9gu3CcMt5gokBuGDxY= +-----END EC PRIVATE KEY----- diff --git a/test/rubygems/private_key.pem b/test/rubygems/private_key.pem index c6ed3fc24e..4e6ce13e65 100644 --- a/test/rubygems/private_key.pem +++ b/test/rubygems/private_key.pem @@ -1,27 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIIEowIBAAKCAQEAp2U1hy8UHrGClPxByczJtV6UYtQrJAv+FA9Mr0nkXKoHyEQM -u3au4zAqwdTp+7+aAb6wu8cXWepaFkAOGfqvAJ80/TfTbm+S05nqIl9TrS/K1j9/ -eCSIY2Q/bWXSHPT4yzXl/7naCT6wVerAYFsO14jTHntSweL4oA3rtC48Oe2FgO3C -FcgDmlx3HbAf41bwXzYcRm+bWFykDvkENWTi8/GekN+884pJif11aCGZS1o+arJW -+zxeQPEcN9jnj8PfOI96E/7NDMSDwLTtKr/Pq8tI5De5pifScEO40Tpc/eKMnhm+ -zZ4kR04zJLUfcKyeRaJ48Ksu0p3Dx38X4PluhwIDAQABAoIBAAx09qfJtBiYoxwN -LaQjzjrl/+re2RsEnXLGtLEysYDH0m5vyfbFXTxg4D2uZ38pgf9xPluq9CznyK5x -M9txEUbdkibp2Z0VRnrisE7Ag0yXCuQos4awSUoEMsgkVJ99B2qv5x7BqN0ZQiwS -nSBOhms5rmRNTxpIlrHqd0jgS/EPggnqVzNcM4/K8PJFthwEBKDmzOyiRByvz54Y -shzOnTjGtV2oGNgwpzmCXce1yO7dh2IdKnSnmeFwyU88GxEYnGh5MIFuTiyErP72 -k6iEUfiXy0hxk/iXmKs8UyD1lVnwTNWcZcpV8yw4a06Z6nkSnwQm0SSOVIo/w35V -jdVdUkECgYEA3GhZ70MD/Q47GFvz6BovwQvxhjFN+nIEbBfi7OTkuXprKdhVhjaR -nERPZpZjHWrcfgbFcvPY7/GJLTPN/VF1nhOsOZpzfAmCgBujRXrzlAGpU877ZNJA -QKPgzo+iv/RsQCIdrzF1gwHkqD2v1HRLaqb2+dVumiG4Qp3NXgasT2cCgYEAwm1U -uRDXgQKGODeLK8eSVpfMjD5umBVu7m4D3ZmipbN6sMBxGMAlsU40eQ7DBFH0AFft -s2D88JdjlwoOrbXYYpOc6iWD/QkygJfPpA9VQx92hv8KBd82gLHuXYMd0T0G3yZO -gPPioeRgl2TvgVCfjn6AYr3Ubt3rB5aBlSplE+ECgYEAiXhcf6rg1fkGSs8vddi/ -aDy2y+f8pvRuZa0QUIkDT9xW8qaH0Uo/z6ObknTCJRr9o209wdDtwdp4oMTq+dDQ -92N1zAfVd8vGpXiXgUKKognXPvqeOegZQzfzg2J7NBaTXfzpXtgOX0PTBkxTWsOe -NkslR/YjIedeMc6SxM6MsokCgYA3mTYyGevWe5dQOin1IgPp+UzICg5sNSzcx98Z -HpcRVWrPYqi00DW3J0sAF0WTVbA17O8PbbvHPTOAfKLH8Alp3xZvKr08vcWQWllJ -bA0Qvc2SOxptpXAbi0ZDvXvoWtA9PeITJCr56qnogTewPhLyl6A1HF3EOne8WsDB -nDb9YQKBgEyUDWhDBGXUfQN0fWy5ksqCCeHXQzvt6aEUstWvkkbnnarUfLAhBIqC -2B6omokICmWzvAfDt3UsRbb3QJUBxbbVsZVM7Vr+kY2cQ1Ma093I/2mXDoq3bV+j -LZM5+Uc7xSfiCi1hbVhGm96DXofudddo86W5mhXp3xhcQP1Fl4JZ +MIIEpAIBAAKCAQEA0ULcfpDboY5uWVdOIkF4AtRui7PPFoaKfBl5hiGFcpYRx8DQ +PyT7bbD8nKd14Rhzb0nHCMU3DEz8PLJCmWm3NszVDkEJws1BpCGak6vKiyNa5hZb +UlQMZMbecSDSpEKu2PBWgBT74qg2RBugzTAVAnGQGezQnWyv47kyXvdjMoq11VZa ++Dz2izHJvjBHGQShr1r9v39qIrtah5CEXTRxEqhr96gg3y6xOPMqxi50dS0RBaJs +PsjFZ1jecye0Z/WPItiLjSVVRssUXK1a2VkYxUqkxUg4wwJD57H4TEZBomtAXlAS +o+rUv8G9eBNmS/k/oJLdiMF1ULb+e1+izeAyGwIDAQABAoIBABS+vR8q+ysD9LqU +piFNPjmBl8fvtmr0QYxV9i8u6YzXhcG4wqxP3UEdl51sGIqNIvx4YuviqTdl9meK +AII28bvUCJcWKYKPWJ+N2UYkdLrgcWV39+use2IOOQUcDOXN2omVIe4mpmXs6RxN +ZN6SkrKgUXnQeUnx+Wno9S5m9gWPfrAMTr8iwBquo5JMFqJmAlfq1cIActU7SE6M +7LJZ8rbVGuGmZAyqJw/I5xvxts6NlTFBm2AyGq74wtbUD4OlFDtOTA57LmtRswmr +MK+JG5LIJIyc6qKQwmHU8vLstJEcVUyCJDbpjDkApd6GQ2FwXXode+S9C40DZKvi +hnaGfKECgYEA1ArI5tt3GdNR4CbY4e4yDHEuSdSkMVsRa9a7gdtrrjyNitBMbZNE +HZNqswijBCPZnXPtBxeytMUmlU7uFc7xx3QQvuBSJ6HOb9j0qtWVL+jl8R9XLogH +sE/m0yMPs2IowevJoQ95KRZIirLywZ8QgTsySEv9U4hx2CdKpn7IeRECgYEA/KR9 +WI1n6pxDbxcjWMaOdziIcgDBk7v05Qssb1OePiz+y+zfrBVqDjsvsokRLoElSAkR +TAV+/9hRgAu4cZJpP0FMdFe+sVkr1UfcDqvJdgumBL+xUNxRV/QFvuprLa6XbiQO +jUclJR6BPdXeVQPDUHuQBgnwXrJdRtMl9Fj8GGsCgYAhZKVo/e0OyyHczCFhy1Jk +dTqV8//7qdzff8y90aFuqiicUNuIciXLBplKIrURhNfTnRsZ/9hr8ZR29Rw3oQSg +pZ2xgcBOb4QER0WY1dQN3H7B726abF/Rm3O9kor5dB75EzoIvFgXaWP5O99RMMy3 +nWv4yMbXbeiH4wA1okfOEQKBgQDkaAnyrxUN5GyK2M5aCljurCufddOMrtb+5BUu +KNjduWw6DVNCjrGtYBEFRipEcvmzoI8EvctNntJAA1ijRQzl5TEr1dBPIiEg17C5 +itG+aVWU4YF7a1QXQkSXj/OJ/1hkeTC2xWVto6CQuPQixB4mey+AZifsVTFDQM4F +lRWFNQKBgQDQWRXaJgc4Jeur1/I1iMAcihN/o4Lra4baM07FdpFWrePJ4IimXHG+ +buws6BuytnQP56hqIQYLQSWCF192dcnHNbodXz48Ug6rKLSBalxH3pvThYLpkBSk +7OrfHzO4TTVaCH1mcPjzj9vmRog2tvrF/m6/8UAZQIBGDv2+cHk4rA== -----END RSA PRIVATE KEY----- diff --git a/test/rubygems/public_cert.pem b/test/rubygems/public_cert.pem index 4517de53c6..7481c26b79 100644 --- a/test/rubygems/public_cert.pem +++ b/test/rubygems/public_cert.pem @@ -1,20 +1,20 @@ -----BEGIN CERTIFICATE----- -MIIDLjCCAhagAwIBAgIBADANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv +MIIDLjCCAhagAwIBAgIBADANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTEyMDEwMTAwMDAwMFoYDzk5 OTkxMjMxMjM1OTU5WjAqMQ8wDQYDVQQDDAZub2JvZHkxFzAVBgoJkiaJk/IsZAEZ -FgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp2U1hy8U -HrGClPxByczJtV6UYtQrJAv+FA9Mr0nkXKoHyEQMu3au4zAqwdTp+7+aAb6wu8cX -WepaFkAOGfqvAJ80/TfTbm+S05nqIl9TrS/K1j9/eCSIY2Q/bWXSHPT4yzXl/7na -CT6wVerAYFsO14jTHntSweL4oA3rtC48Oe2FgO3CFcgDmlx3HbAf41bwXzYcRm+b -WFykDvkENWTi8/GekN+884pJif11aCGZS1o+arJW+zxeQPEcN9jnj8PfOI96E/7N -DMSDwLTtKr/Pq8tI5De5pifScEO40Tpc/eKMnhm+zZ4kR04zJLUfcKyeRaJ48Ksu -0p3Dx38X4PluhwIDAQABo10wWzAZBgNVHREEEjAQgQ5ub2JvZHlAZXhhbXBsZTAd -BgNVHQ4EFgQUX0Nu9pqORSXpIuN9N16k1TYChRswDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQEFBQADggEBAJasznHQK7el5CY19uRM -QZSP2moi65jbESKA5CaSOK0erWfLL7k0W69Rr4RG8CQDXmtlVLzdQlEGkvJEfMLs -GumlIGDEsLZU/3tQ8lML2fMUKipv/fsyWoe6wUHyfsywYYT4WAxyKUtY6AepwN6Y -sJ6+qDWUFziSVgDnU2bBdqzIOw+ww1NtRGE3PEam+a/VL7l/a2DYcot5cvcc8RYR -6gyBXp4fvSGasM3iQp7sWdNV04H8m8+lYBLtsfuucgLDu45uEuvKL1tRcRXvtomp -rKB5y3B5qT/bcc+3b0tbOU6s7CBIdyzIflJI7GuIbZk6lZ+V8Yem+tWt1ArL3Hqf -Myk= +FgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ULcfpDb +oY5uWVdOIkF4AtRui7PPFoaKfBl5hiGFcpYRx8DQPyT7bbD8nKd14Rhzb0nHCMU3 +DEz8PLJCmWm3NszVDkEJws1BpCGak6vKiyNa5hZbUlQMZMbecSDSpEKu2PBWgBT7 +4qg2RBugzTAVAnGQGezQnWyv47kyXvdjMoq11VZa+Dz2izHJvjBHGQShr1r9v39q +Irtah5CEXTRxEqhr96gg3y6xOPMqxi50dS0RBaJsPsjFZ1jecye0Z/WPItiLjSVV +RssUXK1a2VkYxUqkxUg4wwJD57H4TEZBomtAXlASo+rUv8G9eBNmS/k/oJLdiMF1 +ULb+e1+izeAyGwIDAQABo10wWzAZBgNVHREEEjAQgQ5ub2JvZHlAZXhhbXBsZTAd +BgNVHQ4EFgQUsRpUCWdFYAIC1870HWBKid/nWNkwDwYDVR0TAQH/BAUwAwEB/zAO +BgNVHQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADggEBAAYrbeZLQujvqrzAa6NN +QsiGLSVoF+ZcySQH+rpoqcvbd8zLKz/vH+SoMM6db4OUgD8BKaeBb8dGhzz/lE8m +YUqW/La4xvf/ffW5yze51Rtr1bPw1Tjrk92nE630Unjf0ZZO0h8shTmq/WlXiEqg +cXxfbZiPP0KZkhn4ulf+RBbKKQGrLYvaVrCZcowSjLWzcfredYxElOpcgHCrL2pl +2ZAjCySqAUpYo8HTZwgY/DeeGS3V4fZ06ZDoG20cxi7t8R+AcNbEfaTMzG3oe5qN +A8+a3Qcf5M4yiJtXRNusMKeoRwLDkYRX9u76iOI5LfKTSqnUyhrUQcSYCTFO4y/V +P48= -----END CERTIFICATE----- diff --git a/test/rubygems/public_cert_32.pem b/test/rubygems/public_cert_32.pem index 0431b8ba1a..efcf7c0ed7 100644 --- a/test/rubygems/public_cert_32.pem +++ b/test/rubygems/public_cert_32.pem @@ -1,19 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDLDCCAhSgAwIBAgIBATANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv +MIIDLDCCAhSgAwIBAgIBATANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTEyMDEwMTAwMDAwMFoXDTM4 MDExOTAzMTQwN1owKjEPMA0GA1UEAwwGbm9ib2R5MRcwFQYKCZImiZPyLGQBGRYH -ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKdlNYcvFB6x -gpT8QcnMybVelGLUKyQL/hQPTK9J5FyqB8hEDLt2ruMwKsHU6fu/mgG+sLvHF1nq -WhZADhn6rwCfNP03025vktOZ6iJfU60vytY/f3gkiGNkP21l0hz0+Ms15f+52gk+ -sFXqwGBbDteI0x57UsHi+KAN67QuPDnthYDtwhXIA5pcdx2wH+NW8F82HEZvm1hc -pA75BDVk4vPxnpDfvPOKSYn9dWghmUtaPmqyVvs8XkDxHDfY54/D3ziPehP+zQzE -g8C07Sq/z6vLSOQ3uaYn0nBDuNE6XP3ijJ4Zvs2eJEdOMyS1H3CsnkWiePCrLtKd -w8d/F+D5bocCAwEAAaNdMFswGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwHQYD -VR0OBBYEFF9DbvaajkUl6SLjfTdepNU2AoUbMA8GA1UdEwEB/wQFMAMBAf8wDgYD -VR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBBQUAA4IBAQA2+XpC520DwKfqlv5Fn2N5 -sGOgr2Kop7Id2wVWiGDnjDEoTf2Fj+nmmLPltemoCumgY/AacUBAdK1kg47x+7NR -QMq1pOXR5dZbopw1vs9isQQx2P7jKEH7AgIkqo/6XMQGE3tQtJyNIi1LTGCOKNok -Fpv8ZVS8aBmXgC0zwtlrtTxCXpkFaNB99nEqo46Fy+D7dkEXE4Oc3JjTON83sHYD -VsV3DFYzZtR9qe/gCOdgnDHYnf5vU+LGA1gX+8d4Iu/B5ZZtaAowgrsA14oJDuO3 -4g491pjaEYDFZG6mUpvf79uZaBjJdDZeyfwtJ6cN3gTv98DO4DKh/qxnbM/46LM1 +ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANFC3H6Q26GO +bllXTiJBeALUbouzzxaGinwZeYYhhXKWEcfA0D8k+22w/JyndeEYc29JxwjFNwxM +/DyyQplptzbM1Q5BCcLNQaQhmpOryosjWuYWW1JUDGTG3nEg0qRCrtjwVoAU++Ko +NkQboM0wFQJxkBns0J1sr+O5Ml73YzKKtdVWWvg89osxyb4wRxkEoa9a/b9/aiK7 +WoeQhF00cRKoa/eoIN8usTjzKsYudHUtEQWibD7IxWdY3nMntGf1jyLYi40lVUbL +FFytWtlZGMVKpMVIOMMCQ+ex+ExGQaJrQF5QEqPq1L/BvXgTZkv5P6CS3YjBdVC2 +/ntfos3gMhsCAwEAAaNdMFswGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwHQYD +VR0OBBYEFLEaVAlnRWACAtfO9B1gSonf51jZMA8GA1UdEwEB/wQFMAMBAf8wDgYD +VR0PAQH/BAQDAgIEMA0GCSqGSIb3DQEBCwUAA4IBAQBqjR8ioUTAmRjZNvRPMGXc +mx0nklEODMfG5k+X4QI2Hux/4CWuSZKh+LoIxOsqQJdm2rG1FkPr6JYQOj5HCFA7 +3gO/MoSOtqBBOY9uMnGJQUq0NrWvleO3giUhfHRzUh7utXy2u3umuwJLqF54vbuT +a1yufGSzwBO2BP7iURt9SyVrDWFmHSX976ZFWIandPXgMCJTgO6tONOC6/sABctb +YQKo2scrAiSsk+kgIMnebavL6gKgQud6xdjJzvUq3DV4s93ent9rpRzYRgnTM8Eo +UcgFbpFsWR21+gEt6UKv1rO9ZaWBf6RUVdh/sJKa/7vK/shQmnWw0A/LewxKQWV3 -----END CERTIFICATE----- diff --git a/test/rubygems/public_key.pem b/test/rubygems/public_key.pem index 7c29dcd614..c233b35e7c 100644 --- a/test/rubygems/public_key.pem +++ b/test/rubygems/public_key.pem @@ -1,9 +1,9 @@ -----BEGIN PUBLIC KEY----- -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp2U1hy8UHrGClPxByczJ -tV6UYtQrJAv+FA9Mr0nkXKoHyEQMu3au4zAqwdTp+7+aAb6wu8cXWepaFkAOGfqv -AJ80/TfTbm+S05nqIl9TrS/K1j9/eCSIY2Q/bWXSHPT4yzXl/7naCT6wVerAYFsO -14jTHntSweL4oA3rtC48Oe2FgO3CFcgDmlx3HbAf41bwXzYcRm+bWFykDvkENWTi -8/GekN+884pJif11aCGZS1o+arJW+zxeQPEcN9jnj8PfOI96E/7NDMSDwLTtKr/P -q8tI5De5pifScEO40Tpc/eKMnhm+zZ4kR04zJLUfcKyeRaJ48Ksu0p3Dx38X4Plu -hwIDAQAB +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ULcfpDboY5uWVdOIkF4 +AtRui7PPFoaKfBl5hiGFcpYRx8DQPyT7bbD8nKd14Rhzb0nHCMU3DEz8PLJCmWm3 +NszVDkEJws1BpCGak6vKiyNa5hZbUlQMZMbecSDSpEKu2PBWgBT74qg2RBugzTAV +AnGQGezQnWyv47kyXvdjMoq11VZa+Dz2izHJvjBHGQShr1r9v39qIrtah5CEXTRx +Eqhr96gg3y6xOPMqxi50dS0RBaJsPsjFZ1jecye0Z/WPItiLjSVVRssUXK1a2VkY +xUqkxUg4wwJD57H4TEZBomtAXlASo+rUv8G9eBNmS/k/oJLdiMF1ULb+e1+izeAy +GwIDAQAB -----END PUBLIC KEY----- diff --git a/test/rubygems/rubygems/commands/crash_command.rb b/test/rubygems/rubygems/commands/crash_command.rb index 9155360e76..55df274603 100644 --- a/test/rubygems/rubygems/commands/crash_command.rb +++ b/test/rubygems/rubygems/commands/crash_command.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + class Gem::Commands::CrashCommand < Gem::Command raise "crash" end diff --git a/test/rubygems/rubygems_plugin.rb b/test/rubygems/rubygems_plugin.rb index 2dc7836904..949580f904 100644 --- a/test/rubygems/rubygems_plugin.rb +++ b/test/rubygems/rubygems_plugin.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -require 'rubygems/command_manager' + +require "rubygems/command_manager" ## # This is an example of exactly what NOT to do. @@ -12,7 +13,7 @@ end class Gem::Commands::InterruptCommand < Gem::Command def initialize - super('interrupt', 'Raises an Interrupt Exception', {}) + super("interrupt", "Raises an Interrupt Exception", {}) end def execute diff --git a/test/rubygems/simple_gem.rb b/test/rubygems/simple_gem.rb index 0f2ea48198..3d30bade84 100644 --- a/test/rubygems/simple_gem.rb +++ b/test/rubygems/simple_gem.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -SIMPLE_GEM = <<-GEMDATA.freeze + +SIMPLE_GEM = <<-GEMDATA MD5SUM = "989bf34a1cbecd52e0ea66b662b3a405" if $0 == __FILE__ require 'optparse' diff --git a/test/rubygems/specifications/bar-0.0.2.gemspec b/test/rubygems/specifications/bar-0.0.2.gemspec index 37b6ea45da..1f3d0161d2 100644 --- a/test/rubygems/specifications/bar-0.0.2.gemspec +++ b/test/rubygems/specifications/bar-0.0.2.gemspec @@ -1,3 +1,5 @@ +# frozen_string_literal: true + Gem::Specification.new do |s| s.name = "bar" s.version = "0.0.2" diff --git a/test/rubygems/specifications/rubyforge-0.0.1.gemspec b/test/rubygems/specifications/rubyforge-0.0.1.gemspec index c760a42073..0421b675a0 100644 --- a/test/rubygems/specifications/rubyforge-0.0.1.gemspec +++ b/test/rubygems/specifications/rubyforge-0.0.1.gemspec @@ -1,12 +1,15 @@ +# frozen_string_literal: true + Gem::Specification.new do |s| - s.name = "rubyforge" - s.version = "0.0.1" - s.platform = "ruby" - s.require_paths = ["lib"] - s.summary = "A very bar gem" - s.authors = ["unknown"] - s.license = 'MIT' - s.homepage = 'http://example.com' - s.files = ['README.md'] - s.rubyforge_project = 'abc' + s.name = "rubyforge" + s.version = "0.0.1" + s.platform = "ruby" + s.require_paths = ["lib"] + s.summary = "A very bar gem" + s.authors = ["unknown"] + s.license = "MIT" + s.homepage = "http://example.com" + s.files = ["README.md"] + s.rubyforge_project = "abc" + s.required_ruby_version = ">= 1.9.3" end diff --git a/test/rubygems/test_bundled_ca.rb b/test/rubygems/test_bundled_ca.rb index 082bb53ba3..50e621f22b 100644 --- a/test/rubygems/test_bundled_ca.rb +++ b/test/rubygems/test_bundled_ca.rb @@ -1,20 +1,21 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'net/http' -require 'rubygems/openssl' + +require_relative "helper" +require "rubygems/vendored_net_http" +require "rubygems/openssl" unless Gem::HAVE_OPENSSL - warn 'Skipping bundled certificates tests. openssl not found.' + warn "Skipping bundled certificates tests. openssl not found." end -require 'rubygems/request' +require "rubygems/request" # = Testing Bundled CA # # The tested hosts are explained in detail here: https://github.com/rubygems/rubygems/commit/5e16a5428f973667cabfa07e94ff939e7a83ebd9 # -class TestBundledCA < Gem::TestCase +class TestGemBundledCA < Gem::TestCase def bundled_certificate_store store = OpenSSL::X509::Store.new @@ -27,34 +28,34 @@ class TestBundledCA < Gem::TestCase def assert_https(host) assert true - http = Net::HTTP.new(host, 443) + http = Gem::Net::HTTP.new(host, 443) http.use_ssl = true http.verify_mode = OpenSSL::SSL::VERIFY_PEER http.cert_store = bundled_certificate_store - http.get('/') - rescue Errno::ENOENT, Errno::ETIMEDOUT, SocketError - skip "#{host} seems offline, I can't tell whether ssl would work." + http.get("/") + rescue Errno::ENOENT, Errno::ETIMEDOUT, SocketError, Net::OpenTimeout + pend "#{host} seems offline, I can't tell whether ssl would work." rescue OpenSSL::SSL::SSLError => e # Only fail for certificate verification errors - if e.message =~ /certificate verify failed/ + if e.message.include?("certificate verify failed") flunk "#{host} is not verifiable using the included certificates. Error was: #{e.message}" end raise end def test_accessing_rubygems - assert_https('rubygems.org') + assert_https("rubygems.org") end def test_accessing_www_rubygems - assert_https('www.rubygems.org') + assert_https("www.rubygems.org") end def test_accessing_staging - assert_https('staging.rubygems.org') + assert_https("staging.rubygems.org") end def test_accessing_new_index - assert_https('index.rubygems.org') + assert_https("index.rubygems.org") end end if Gem::HAVE_OPENSSL diff --git a/test/rubygems/test_config.rb b/test/rubygems/test_config.rb index 692d8af1ab..657624d526 100644 --- a/test/rubygems/test_config.rb +++ b/test/rubygems/test_config.rb @@ -1,9 +1,10 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems' -require 'shellwords' -class TestConfig < Gem::TestCase +require_relative "helper" +require "rubygems" +require "shellwords" + +class TestGemConfig < Gem::TestCase def test_datadir util_make_gems spec = Gem::Specification.find_by_name("a") @@ -15,13 +16,13 @@ class TestConfig < Gem::TestCase path = Gem::TestCase.class_variable_get(:@@good_rake) ruby, rake = path.shellsplit assert_equal(Gem.ruby, ruby) - assert_match(/\/good_rake.rb\z/, rake) + assert_match(%r{/good_rake.rb\z}, rake) end def test_bad_rake_path_is_escaped path = Gem::TestCase.class_variable_get(:@@bad_rake) ruby, rake = path.shellsplit assert_equal(Gem.ruby, ruby) - assert_match(/\/bad_rake.rb\z/, rake) + assert_match(%r{/bad_rake.rb\z}, rake) end end diff --git a/test/rubygems/test_deprecate.rb b/test/rubygems/test_deprecate.rb index 4a14266ce3..d15de646a4 100644 --- a/test/rubygems/test_deprecate.rb +++ b/test/rubygems/test_deprecate.rb @@ -1,8 +1,9 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/deprecate' -class TestDeprecate < Gem::TestCase +require_relative "helper" +require "rubygems/deprecate" + +class TestGemDeprecate < Gem::TestCase def setup super @@ -28,7 +29,7 @@ class TestDeprecate < Gem::TestCase assert_equal true, Gem::Deprecate.skip Gem::Deprecate.skip = nil - assert([true,false].include? Gem::Deprecate.skip) + assert([true,false].include?(Gem::Deprecate.skip)) end def test_skip @@ -45,6 +46,7 @@ class TestDeprecate < Gem::TestCase def foo @message = "foo" end + def bar @message = "bar" end @@ -53,6 +55,7 @@ class TestDeprecate < Gem::TestCase def foo_arg(msg) @message = "foo" + msg end + def bar_arg(msg) @message = "bar" + msg end @@ -61,6 +64,7 @@ class TestDeprecate < Gem::TestCase def foo_kwarg(message:) @message = "foo" + message end + def bar_kwarg(message:) @message = "bar" + message end @@ -73,6 +77,7 @@ class TestDeprecate < Gem::TestCase def foo @message = "foo" end + def bar @message = "bar" end @@ -81,6 +86,7 @@ class TestDeprecate < Gem::TestCase def foo_arg(msg) @message = "foo" + msg end + def bar_arg(msg) @message = "bar" + msg end @@ -89,6 +95,7 @@ class TestDeprecate < Gem::TestCase def foo_kwarg(message:) @message = "foo" + message end + def bar_kwarg(message:) @message = "bar" + message end @@ -123,7 +130,7 @@ class TestDeprecate < Gem::TestCase end def test_rubygems_deprecate_command - require 'rubygems/command' + require "rubygems/command" foo_command = Class.new(Gem::Command) do extend Gem::Deprecate diff --git a/test/rubygems/test_exit.rb b/test/rubygems/test_exit.rb new file mode 100644 index 0000000000..396837edad --- /dev/null +++ b/test/rubygems/test_exit.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require_relative "helper" +require "rubygems" + +class TestGemExit < Gem::TestCase + def test_exit + system(*ruby_with_rubygems_in_load_path, "-e", "raise Gem::SystemExitException.new(2)") + assert_equal 2, $?.exitstatus + end + + def test_status + exc = Gem::SystemExitException.new(42) + assert_equal 42, exc.status + assert_equal 42, exc.exit_code + end +end diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb index 5192b97548..244b7749a5 100644 --- a/test/rubygems/test_gem.rb +++ b/test/rubygems/test_gem.rb @@ -1,16 +1,17 @@ # coding: US-ASCII -require 'rubygems/test_case' -require 'rubygems' -require 'rubygems/command' -require 'rubygems/installer' -require 'pathname' -require 'tmpdir' -require 'rbconfig' + +require_relative "helper" +require "rubygems" +require "rubygems/command" +require "rubygems/installer" +require "pathname" +require "tmpdir" +require "rbconfig" class TestGem < Gem::TestCase PLUGINS_LOADED = [] # rubocop:disable Style/MutableConstant - PROJECT_DIR = File.expand_path('../../..', __FILE__).tap(&Gem::UNTAINT) + PROJECT_DIR = File.expand_path("../..", __dir__) def setup super @@ -19,111 +20,104 @@ class TestGem < Gem::TestCase common_installer_setup - ENV.delete 'RUBYGEMS_GEMDEPS' @additional = %w[a b].map {|d| File.join @tempdir, d } util_remove_interrupt_command end def test_self_finish_resolve - save_loaded_features do - a1 = util_spec "a", "1", "b" => "> 0" - b1 = util_spec "b", "1", "c" => ">= 1" - b2 = util_spec "b", "2", "c" => ">= 2" - c1 = util_spec "c", "1" - c2 = util_spec "c", "2" + a1 = util_spec "a", "1", "b" => "> 0" + b1 = util_spec "b", "1", "c" => ">= 1" + b2 = util_spec "b", "2", "c" => ">= 2" + c1 = util_spec "c", "1" + c2 = util_spec "c", "2" - install_specs c1, c2, b1, b2, a1 + install_specs c1, c2, b1, b2, a1 - a1.activate + a1.activate - assert_equal %w[a-1], loaded_spec_names - assert_equal ["b (> 0)"], unresolved_names + assert_equal %w[a-1], loaded_spec_names + assert_equal ["b (> 0)"], unresolved_names - Gem.finish_resolve + Gem.finish_resolve - assert_equal %w[a-1 b-2 c-2], loaded_spec_names - assert_equal [], unresolved_names - end + assert_equal %w[a-1 b-2 c-2], loaded_spec_names + assert_equal [], unresolved_names end def test_self_finish_resolve_wtf - save_loaded_features do - a1 = util_spec "a", "1", "b" => "> 0", "d" => "> 0" # this - b1 = util_spec "b", "1", { "c" => ">= 1" }, "lib/b.rb" # this - b2 = util_spec "b", "2", { "c" => ">= 2" }, "lib/b.rb" - c1 = util_spec "c", "1" # this - c2 = util_spec "c", "2" - d1 = util_spec "d", "1", { "c" => "< 2" }, "lib/d.rb" - d2 = util_spec "d", "2", { "c" => "< 2" }, "lib/d.rb" # this + a1 = util_spec "a", "1", "b" => "> 0", "d" => "> 0" # this + b1 = util_spec "b", "1", { "c" => ">= 1" }, "lib/b.rb" # this + b2 = util_spec "b", "2", { "c" => ">= 2" }, "lib/b.rb" + c1 = util_spec "c", "1" # this + c2 = util_spec "c", "2" + d1 = util_spec "d", "1", { "c" => "< 2" }, "lib/d.rb" + d2 = util_spec "d", "2", { "c" => "< 2" }, "lib/d.rb" # this - install_specs c1, c2, b1, b2, d1, d2, a1 + install_specs c1, c2, b1, b2, d1, d2, a1 - a1.activate + a1.activate - assert_equal %w[a-1], loaded_spec_names - assert_equal ["b (> 0)", "d (> 0)"], unresolved_names + assert_equal %w[a-1], loaded_spec_names + assert_equal ["b (> 0)", "d (> 0)"], unresolved_names - Gem.finish_resolve + Gem.finish_resolve - assert_equal %w[a-1 b-1 c-1 d-2], loaded_spec_names - assert_equal [], unresolved_names - end + assert_equal %w[a-1 b-1 c-1 d-2], loaded_spec_names + assert_equal [], unresolved_names end def test_self_finish_resolve_respects_loaded_specs - save_loaded_features do - a1 = util_spec "a", "1", "b" => "> 0" - b1 = util_spec "b", "1", "c" => ">= 1" - b2 = util_spec "b", "2", "c" => ">= 2" - c1 = util_spec "c", "1" - c2 = util_spec "c", "2" + a1 = util_spec "a", "1", "b" => "> 0" + b1 = util_spec "b", "1", "c" => ">= 1" + b2 = util_spec "b", "2", "c" => ">= 2" + c1 = util_spec "c", "1" + c2 = util_spec "c", "2" - install_specs c1, c2, b1, b2, a1 + install_specs c1, c2, b1, b2, a1 - a1.activate - c1.activate + a1.activate + c1.activate - assert_equal %w[a-1 c-1], loaded_spec_names - assert_equal ["b (> 0)"], unresolved_names + assert_equal %w[a-1 c-1], loaded_spec_names + assert_equal ["b (> 0)"], unresolved_names - Gem.finish_resolve + Gem.finish_resolve - assert_equal %w[a-1 b-1 c-1], loaded_spec_names - assert_equal [], unresolved_names - end + assert_equal %w[a-1 b-1 c-1], loaded_spec_names + assert_equal [], unresolved_names end def test_self_install spec_fetcher do |f| - f.gem 'a', 1 - f.spec 'a', 2 + f.gem "a", 1 + f.spec "a", 2 end gemhome2 = "#{@gemhome}2" - installed = Gem.install 'a', '= 1', :install_dir => gemhome2 + installed = Gem.install "a", "= 1", install_dir: gemhome2 - assert_equal %w[a-1], installed.map {|spec| spec.full_name } + assert_equal %w[a-1], installed.map(&:full_name) - assert_path_exist File.join(gemhome2, 'gems', 'a-1') + assert_path_exist File.join(gemhome2, "gems", "a-1") end def test_self_install_in_rescue spec_fetcher do |f| - f.gem 'a', 1 - f.spec 'a', 2 + f.gem "a", 1 + f.spec "a", 2 end gemhome2 = "#{@gemhome}2" installed = begin - raise 'Error' + raise "Error" rescue StandardError - Gem.install 'a', '= 1', :install_dir => gemhome2 + Gem.install "a", "= 1", install_dir: gemhome2 end - assert_equal %w[a-1], installed.map {|spec| spec.full_name } + assert_equal %w[a-1], installed.map(&:full_name) end def test_self_install_permissions @@ -138,8 +132,8 @@ class TestGem < Gem::TestCase end def test_self_install_permissions_umask_077 - umask = File.umask(077) - assert_self_install_permissions + umask = File.umask(0o077) + assert_self_install_permissions(data_mode: 0o600) ensure File.umask(umask) end @@ -150,55 +144,55 @@ class TestGem < Gem::TestCase def test_self_install_permissions_with_format_executable_and_non_standard_ruby_install_name Gem::Installer.exec_format = nil - ruby_install_name 'ruby27' do + ruby_install_name "ruby27" do assert_self_install_permissions(format_executable: true) end ensure Gem::Installer.exec_format = nil end - def assert_self_install_permissions(format_executable: false) - mask = win_platform? ? 0700 : 0777 + def assert_self_install_permissions(format_executable: false, data_mode: 0o640) + mask = Gem.win_platform? ? 0o700 : 0o777 options = { - :dir_mode => 0500, - :prog_mode => win_platform? ? 0410 : 0510, - :data_mode => 0640, - :wrappers => true, - :format_executable => format_executable, + dir_mode: 0o500, + prog_mode: Gem.win_platform? ? 0o410 : 0o510, + data_mode: data_mode, + wrappers: true, + format_executable: format_executable, } Dir.chdir @tempdir do - Dir.mkdir 'bin' - Dir.mkdir 'data' + Dir.mkdir "bin" + Dir.mkdir "data" - File.write 'bin/foo', "#!/usr/bin/env ruby\n" - File.chmod 0755, 'bin/foo' + File.write "bin/foo", "#!/usr/bin/env ruby\n" + File.chmod 0o755, "bin/foo" - File.write 'data/foo.txt', "blah\n" + File.write "data/foo.txt", "blah\n" spec_fetcher do |f| - f.gem 'foo', 1 do |s| - s.executables = ['foo'] + f.gem "foo", 1 do |s| + s.executables = ["foo"] s.files = %w[bin/foo data/foo.txt] end end - Gem.install 'foo', Gem::Requirement.default, options + Gem.install "foo", Gem::Requirement.default, options end prog_mode = (options[:prog_mode] & mask).to_s(8) dir_mode = (options[:dir_mode] & mask).to_s(8) data_mode = (options[:data_mode] & mask).to_s(8) - prog_name = 'foo' - prog_name = RbConfig::CONFIG['ruby_install_name'].sub('ruby', 'foo') if options[:format_executable] + prog_name = "foo" + prog_name = RbConfig::CONFIG["ruby_install_name"].sub("ruby", "foo") if options[:format_executable] expected = { "bin/#{prog_name}" => prog_mode, - 'gems/foo-1' => dir_mode, - 'gems/foo-1/bin' => dir_mode, - 'gems/foo-1/data' => dir_mode, - 'gems/foo-1/bin/foo' => prog_mode, - 'gems/foo-1/data/foo.txt' => data_mode, + "gems/foo-1" => dir_mode, + "gems/foo-1/bin" => dir_mode, + "gems/foo-1/data" => dir_mode, + "gems/foo-1/bin/foo" => prog_mode, + "gems/foo-1/data/foo.txt" => data_mode, } # add Windows script - expected["bin/#{prog_name}.bat"] = mask.to_s(8) if win_platform? + expected["bin/#{prog_name}.bat"] = mask.to_s(8) if Gem.win_platform? result = {} Dir.chdir @gemhome do expected.each_key do |n| @@ -207,83 +201,79 @@ class TestGem < Gem::TestCase end assert_equal(expected, result) ensure - File.chmod(0755, *Dir.glob(@gemhome + '/gems/**/').map {|path| path.tap(&Gem::UNTAINT) }) + File.chmod(0o755, *Dir.glob(@gemhome + "/gems/**/")) end def test_require_missing - save_loaded_features do - assert_raise ::LoadError do - require "test_require_missing" - end + assert_raise ::LoadError do + require "test_require_missing" end end def test_require_does_not_glob - save_loaded_features do - a1 = util_spec "a", "1", nil, "lib/a1.rb" + a1 = util_spec "a", "1", nil, "lib/a1.rb" - install_specs a1 - - assert_raise ::LoadError do - require "a*" - end + install_specs a1 - assert_equal [], loaded_spec_names + assert_raise ::LoadError do + require "a*" end + + assert_equal [], loaded_spec_names end def test_self_bin_path_active - a1 = util_spec 'a', '1' do |s| - s.executables = ['exec'] + a1 = util_spec "a", "1" do |s| + s.executables = ["exec"] end - util_spec 'a', '2' do |s| - s.executables = ['exec'] + util_spec "a", "2" do |s| + s.executables = ["exec"] end a1.activate - assert_match 'a-1/bin/exec', Gem.bin_path('a', 'exec', '>= 0') + assert_match "a-1/bin/exec", Gem.bin_path("a", "exec", ">= 0") end def test_self_bin_path_picking_newest - a1 = util_spec 'a', '1' do |s| - s.executables = ['exec'] + a1 = util_spec "a", "1" do |s| + s.executables = ["exec"] end - a2 = util_spec 'a', '2' do |s| - s.executables = ['exec'] + a2 = util_spec "a", "2" do |s| + s.executables = ["exec"] end install_specs a1, a2 - assert_match 'a-2/bin/exec', Gem.bin_path('a', 'exec', '>= 0') + assert_match "a-2/bin/exec", Gem.bin_path("a", "exec", ">= 0") end def test_self_activate_bin_path_no_exec_name e = assert_raise ArgumentError do - Gem.activate_bin_path 'a' + Gem.activate_bin_path "a" end - assert_equal 'you must supply exec_name', e.message + assert_equal "you must supply exec_name", e.message end def test_activate_bin_path_resolves_eagerly - a1 = util_spec 'a', '1' do |s| - s.executables = ['exec'] - s.add_dependency 'b' + a1 = util_spec "a", "1" do |s| + s.executables = ["exec"] + s.add_dependency "b" end - b1 = util_spec 'b', '1' do |s| - s.add_dependency 'c', '2' + b1 = util_spec "b", "1" do |s| + s.add_dependency "c", "2" end - b2 = util_spec 'b', '2' do |s| - s.add_dependency 'c', '1' + b2 = util_spec "b", "2" do |s| + s.add_dependency "c", "1" end - c1 = util_spec 'c', '1' - c2 = util_spec 'c', '2' + c1 = util_spec "c", "1" + c2 = util_spec "c", "2" install_specs c1, c2, b1, b2, a1 @@ -291,27 +281,27 @@ class TestGem < Gem::TestCase # If we didn't eagerly resolve, this would activate c-2 and then the # finish_resolve would cause a conflict - gem 'c' + gem "c" Gem.finish_resolve assert_equal %w[a-1 b-2 c-1], loaded_spec_names end def test_activate_bin_path_does_not_error_if_a_gem_thats_not_finally_activated_has_orphaned_dependencies - a1 = util_spec 'a', '1' do |s| - s.executables = ['exec'] - s.add_dependency 'b' + a1 = util_spec "a", "1" do |s| + s.executables = ["exec"] + s.add_dependency "b" end - b1 = util_spec 'b', '1' do |s| - s.add_dependency 'c', '1' + b1 = util_spec "b", "1" do |s| + s.add_dependency "c", "1" end - b2 = util_spec 'b', '2' do |s| - s.add_dependency 'c', '2' + b2 = util_spec "b", "2" do |s| + s.add_dependency "c", "2" end - c2 = util_spec 'c', '2' + c2 = util_spec "c", "2" install_specs c2, b1, b2, a1 @@ -323,20 +313,20 @@ class TestGem < Gem::TestCase end def test_activate_bin_path_raises_a_meaningful_error_if_a_gem_thats_finally_activated_has_orphaned_dependencies - a1 = util_spec 'a', '1' do |s| - s.executables = ['exec'] - s.add_dependency 'b' + a1 = util_spec "a", "1" do |s| + s.executables = ["exec"] + s.add_dependency "b" end - b1 = util_spec 'b', '1' do |s| - s.add_dependency 'c', '1' + b1 = util_spec "b", "1" do |s| + s.add_dependency "c", "1" end - b2 = util_spec 'b', '2' do |s| - s.add_dependency 'c', '2' + b2 = util_spec "b", "2" do |s| + s.add_dependency "c", "2" end - c1 = util_spec 'c', '1' + c1 = util_spec "c", "1" install_specs c1, b1, b2, a1 @@ -350,8 +340,8 @@ class TestGem < Gem::TestCase end def test_activate_bin_path_in_debug_mode - a1 = util_spec 'a', '1' do |s| - s.executables = ['exec'] + a1 = util_spec "a", "1" do |s| + s.executables = ["exec"] end install_specs a1 @@ -365,54 +355,19 @@ class TestGem < Gem::TestCase assert status.success?, output end - def test_activate_bin_path_gives_proper_error_for_bundler - bundler = util_spec 'bundler', '2' do |s| - s.executables = ['bundle'] - end - - install_specs bundler - - File.open("Gemfile.lock", "w") do |f| - f.write <<-L.gsub(/ {8}/, "") - GEM - remote: https://rubygems.org/ - specs: - - PLATFORMS - ruby - - DEPENDENCIES - - BUNDLED WITH - 9999 - L - end - - File.open("Gemfile", "w") {|f| f.puts('source "https://rubygems.org"') } - - e = assert_raise Gem::GemNotFoundException do - load Gem.activate_bin_path("bundler", "bundle", ">= 0.a") - end - - assert_includes e.message, "Could not find 'bundler' (9999) required by your #{File.expand_path("Gemfile.lock")}." - assert_includes e.message, "To update to the latest version installed on your system, run `bundle update --bundler`." - assert_includes e.message, "To install the missing version, run `gem install bundler:9999`" - refute_includes e.message, "can't find gem bundler (>= 0.a) with executable bundle" - end - def test_activate_bin_path_selects_exact_bundler_version_if_present - bundler_latest = util_spec 'bundler', '2.0.1' do |s| - s.executables = ['bundle'] + bundler_latest = util_spec "bundler", "2.0.1" do |s| + s.executables = ["bundle"] end - bundler_previous = util_spec 'bundler', '2.0.0' do |s| - s.executables = ['bundle'] + bundler_previous = util_spec "bundler", "2.0.0" do |s| + s.executables = ["bundle"] end install_specs bundler_latest, bundler_previous File.open("Gemfile.lock", "w") do |f| - f.write <<-L.gsub(/ {8}/, "") + f.write <<~L GEM remote: https://rubygems.org/ specs: @@ -435,18 +390,18 @@ class TestGem < Gem::TestCase end def test_activate_bin_path_respects_underscore_selection_if_given - bundler_latest = util_spec 'bundler', '2.0.1' do |s| - s.executables = ['bundle'] + bundler_latest = util_spec "bundler", "2.0.1" do |s| + s.executables = ["bundle"] end - bundler_previous = util_spec 'bundler', '1.17.3' do |s| - s.executables = ['bundle'] + bundler_previous = util_spec "bundler", "1.17.3" do |s| + s.executables = ["bundle"] end install_specs bundler_latest, bundler_previous File.open("Gemfile.lock", "w") do |f| - f.write <<-L.gsub(/ {8}/, "") + f.write <<~L GEM remote: https://rubygems.org/ specs: @@ -470,7 +425,7 @@ class TestGem < Gem::TestCase def test_activate_bin_path_gives_proper_error_for_bundler_when_underscore_selection_given File.open("Gemfile.lock", "w") do |f| - f.write <<-L.gsub(/ {8}/, "") + f.write <<~L GEM remote: https://rubygems.org/ specs: @@ -496,58 +451,57 @@ class TestGem < Gem::TestCase def test_self_bin_path_no_exec_name e = assert_raise ArgumentError do - Gem.bin_path 'a' + Gem.bin_path "a" end - assert_equal 'you must supply exec_name', e.message + assert_equal "you must supply exec_name", e.message end def test_self_bin_path_bin_name install_specs util_exec_gem - assert_equal @abin_path, Gem.bin_path('a', 'abin') + assert_equal @abin_path, Gem.bin_path("a", "abin") end def test_self_bin_path_bin_name_version install_specs util_exec_gem - assert_equal @abin_path, Gem.bin_path('a', 'abin', '4') + assert_equal @abin_path, Gem.bin_path("a", "abin", "4") end def test_self_bin_path_nonexistent_binfile - util_spec 'a', '2' do |s| - s.executables = ['exec'] + util_spec "a", "2" do |s| + s.executables = ["exec"] end assert_raise(Gem::GemNotFoundException) do - Gem.bin_path('a', 'other', '2') + Gem.bin_path("a", "other", "2") end end def test_self_bin_path_no_bin_file - util_spec 'a', '1' + util_spec "a", "1" assert_raise(ArgumentError) do - Gem.bin_path('a', nil, '1') + Gem.bin_path("a", nil, "1") end end def test_self_bin_path_not_found assert_raise(Gem::GemNotFoundException) do - Gem.bin_path('non-existent', 'blah') + Gem.bin_path("non-existent", "blah") end end def test_self_bin_path_bin_file_gone_in_latest install_specs util_exec_gem - spec = util_spec 'a', '10' do |s| + spec = util_spec "a", "10" do |s| s.executables = [] end install_specs spec - # Should not find a-10's non-abin (bug) - assert_equal @abin_path, Gem.bin_path('a', 'abin') + assert_equal @abin_path, Gem.bin_path("a", "abin") end def test_self_bindir - assert_equal File.join(@gemhome, 'bin'), Gem.bindir - assert_equal File.join(@gemhome, 'bin'), Gem.bindir(Gem.dir) - assert_equal File.join(@gemhome, 'bin'), Gem.bindir(Pathname.new(Gem.dir)) + assert_equal File.join(@gemhome, "bin"), Gem.bindir + assert_equal File.join(@gemhome, "bin"), Gem.bindir(Gem.dir) + assert_equal File.join(@gemhome, "bin"), Gem.bindir(Pathname.new(Gem.dir)) end def test_self_bindir_default_dir @@ -576,21 +530,21 @@ class TestGem < Gem::TestCase foo = nil Dir.chdir @tempdir do - FileUtils.mkdir_p 'data' - File.open File.join('data', 'foo.txt'), 'w' do |fp| - fp.puts 'blah' + FileUtils.mkdir_p "data" + File.open File.join("data", "foo.txt"), "w" do |fp| + fp.puts "blah" end - foo = util_spec 'foo' do |s| + foo = util_spec "foo" do |s| s.files = %w[data/foo.txt] end install_gem foo end - gem 'foo' + gem "foo" - expected = File.join @gemhome, 'gems', foo.full_name, 'data', 'foo' + expected = File.join @gemhome, "gems", foo.full_name, "data", "foo" assert_equal expected, Gem::Specification.find_by_name("foo").datadir end @@ -602,25 +556,25 @@ class TestGem < Gem::TestCase end def test_self_default_exec_format - ruby_install_name 'ruby' do - assert_equal '%s', Gem.default_exec_format + ruby_install_name "ruby" do + assert_equal "%s", Gem.default_exec_format end end def test_self_default_exec_format_18 - ruby_install_name 'ruby18' do - assert_equal '%s18', Gem.default_exec_format + ruby_install_name "ruby18" do + assert_equal "%s18", Gem.default_exec_format end end def test_self_default_exec_format_jruby - ruby_install_name 'jruby' do - assert_equal 'j%s', Gem.default_exec_format + ruby_install_name "jruby" do + assert_equal "j%s", Gem.default_exec_format end end def test_default_path - vendordir(File.join(@tempdir, 'vendor')) do + vendordir(File.join(@tempdir, "vendor")) do FileUtils.rm_rf Gem.user_home expected = [Gem.default_dir] @@ -640,7 +594,7 @@ class TestGem < Gem::TestCase end def test_default_path_user_home - vendordir(File.join(@tempdir, 'vendor')) do + vendordir(File.join(@tempdir, "vendor")) do expected = [Gem.user_dir, Gem.default_dir] assert_equal expected, Gem.default_path @@ -648,7 +602,7 @@ class TestGem < Gem::TestCase end def test_default_path_vendor_dir - vendordir(File.join(@tempdir, 'vendor')) do + vendordir(File.join(@tempdir, "vendor")) do FileUtils.mkdir_p Gem.vendor_dir FileUtils.rm_rf Gem.user_home @@ -663,25 +617,6 @@ class TestGem < Gem::TestCase assert_equal %w[https://rubygems.org/], Gem.default_sources end - def test_self_use_gemdeps - rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], '-' - - FileUtils.mkdir_p 'detect/a/b' - FileUtils.mkdir_p 'detect/a/Isolate' - - FileUtils.touch 'detect/Isolate' - - begin - Dir.chdir 'detect/a/b' - - assert_equal add_bundler_full_name([]), Gem.use_gemdeps.map(&:full_name) - ensure - Dir.chdir @tempdir - end - ensure - ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps - end - def test_self_dir assert_equal @gemhome, Gem.dir end @@ -692,25 +627,25 @@ class TestGem < Gem::TestCase Gem.ensure_gem_subdirectories @gemhome - assert_path_exist File.join @gemhome, 'build_info' - assert_path_exist File.join @gemhome, 'cache' - assert_path_exist File.join @gemhome, 'doc' - assert_path_exist File.join @gemhome, 'extensions' - assert_path_exist File.join @gemhome, 'gems' - assert_path_exist File.join @gemhome, 'specifications' + assert_path_exist File.join @gemhome, "build_info" + assert_path_exist File.join @gemhome, "cache" + assert_path_exist File.join @gemhome, "doc" + assert_path_exist File.join @gemhome, "extensions" + assert_path_exist File.join @gemhome, "gems" + assert_path_exist File.join @gemhome, "specifications" end def test_self_ensure_gem_directories_permissions FileUtils.rm_r @gemhome Gem.use_paths @gemhome - Gem.ensure_gem_subdirectories @gemhome, 0750 + Gem.ensure_gem_subdirectories @gemhome, 0o750 assert_directory_exists File.join(@gemhome, "cache") - assert_equal 0750, File::Stat.new(@gemhome).mode & 0777 - assert_equal 0750, File::Stat.new(File.join(@gemhome, "cache")).mode & 0777 - end unless win_platform? + assert_equal 0o750, File::Stat.new(@gemhome).mode & 0o777 + assert_equal 0o750, File::Stat.new(File.join(@gemhome, "cache")).mode & 0o777 + end unless Gem.win_platform? def test_self_ensure_gem_directories_safe_permissions FileUtils.rm_r @gemhome @@ -720,17 +655,21 @@ class TestGem < Gem::TestCase File.umask 0 Gem.ensure_gem_subdirectories @gemhome - assert_equal 0, File::Stat.new(@gemhome).mode & 002 - assert_equal 0, File::Stat.new(File.join(@gemhome, "cache")).mode & 002 + assert_equal 0, File::Stat.new(@gemhome).mode & 0o002 + assert_equal 0, File::Stat.new(File.join(@gemhome, "cache")).mode & 0o002 ensure File.umask old_umask - end unless win_platform? + end unless Gem.win_platform? def test_self_ensure_gem_directories_missing_parents - gemdir = File.join @tempdir, 'a/b/c/gemdir' - FileUtils.rm_rf File.join(@tempdir, 'a') rescue nil - refute File.exist?(File.join(@tempdir, 'a')), - "manually remove #{File.join @tempdir, 'a'}, tests are broken" + gemdir = File.join @tempdir, "a/b/c/gemdir" + begin + FileUtils.rm_rf File.join(@tempdir, "a") + rescue StandardError + nil + end + refute File.exist?(File.join(@tempdir, "a")), + "manually remove #{File.join @tempdir, "a"}, tests are broken" Gem.use_paths gemdir Gem.ensure_gem_subdirectories gemdir @@ -738,53 +677,61 @@ class TestGem < Gem::TestCase assert_directory_exists util_cache_dir end - unless win_platform? || Process.uid.zero? # only for FS that support write protection + unless Gem.win_platform? || Process.uid.zero? # only for FS that support write protection def test_self_ensure_gem_directories_write_protected gemdir = File.join @tempdir, "egd" - FileUtils.rm_r gemdir rescue nil + begin + FileUtils.rm_r gemdir + rescue StandardError + nil + end refute File.exist?(gemdir), "manually remove #{gemdir}, tests are broken" FileUtils.mkdir_p gemdir - FileUtils.chmod 0400, gemdir + FileUtils.chmod 0o400, gemdir Gem.use_paths gemdir Gem.ensure_gem_subdirectories gemdir refute File.exist?(util_cache_dir) ensure - FileUtils.chmod 0600, gemdir + FileUtils.chmod 0o600, gemdir end def test_self_ensure_gem_directories_write_protected_parents parent = File.join(@tempdir, "egd") gemdir = "#{parent}/a/b/c" - FileUtils.rm_r parent rescue nil + begin + FileUtils.rm_r parent + rescue StandardError + nil + end refute File.exist?(parent), "manually remove #{parent}, tests are broken" FileUtils.mkdir_p parent - FileUtils.chmod 0400, parent + FileUtils.chmod 0o400, parent Gem.use_paths(gemdir) Gem.ensure_gem_subdirectories gemdir refute File.exist? File.join(gemdir, "gems") ensure - FileUtils.chmod 0600, parent + FileUtils.chmod 0o600, parent end def test_self_ensure_gem_directories_non_existent_paths - Gem.ensure_gem_subdirectories '/proc/0123456789/bogus' # should not raise - Gem.ensure_gem_subdirectories 'classpath:/bogus/x' # JRuby embed scenario + Gem.ensure_gem_subdirectories "/proc/0123456789/bogus" # should not raise + Gem.ensure_gem_subdirectories "classpath:/bogus/x" # JRuby embed scenario end end def test_self_extension_dir_shared - enable_shared 'yes' do + enable_shared "yes" do assert_equal Gem.ruby_api_version, Gem.extension_api_version end end def test_self_extension_dir_static - enable_shared 'no' do + enable_shared "no" do assert_equal "#{Gem.ruby_api_version}-static", Gem.extension_api_version end end @@ -793,14 +740,14 @@ class TestGem < Gem::TestCase cwd = File.expand_path("test/rubygems", PROJECT_DIR) $LOAD_PATH.unshift cwd - discover_path = File.join 'lib', 'sff', 'discover.rb' + discover_path = File.join "lib", "sff", "discover.rb" foo1, foo2 = %w[1 2].map do |version| - spec = quick_gem 'sff', version do |s| + spec = quick_gem "sff", version do |s| s.files << discover_path end - write_file(File.join 'gems', spec.full_name, discover_path) do |fp| + write_file(File.join("gems", spec.full_name, discover_path)) do |fp| fp.puts "# #{spec.full_name}" end @@ -810,65 +757,29 @@ class TestGem < Gem::TestCase Gem.refresh expected = [ - File.expand_path('test/rubygems/sff/discover.rb', PROJECT_DIR), + File.expand_path("test/rubygems/sff/discover.rb", PROJECT_DIR), File.join(foo2.full_gem_path, discover_path), File.join(foo1.full_gem_path, discover_path), ] - assert_equal expected, Gem.find_files('sff/discover') - assert_equal expected, Gem.find_files('sff/**.rb'), '[ruby-core:31730]' + assert_equal expected, Gem.find_files("sff/discover") + assert_equal expected, Gem.find_files("sff/**.rb"), "[ruby-core:31730]" ensure assert_equal cwd, $LOAD_PATH.shift end - def test_self_find_files_with_gemfile - cwd = File.expand_path("test/rubygems", PROJECT_DIR) - actual_load_path = $LOAD_PATH.unshift(cwd).dup - - discover_path = File.join 'lib', 'sff', 'discover.rb' - - foo1, _ = %w[1 2].map do |version| - spec = quick_gem 'sff', version do |s| - s.files << discover_path - end - - write_file(File.join 'gems', spec.full_name, discover_path) do |fp| - fp.puts "# #{spec.full_name}" - end - - spec - end - Gem.refresh - - write_file(File.join Dir.pwd, 'Gemfile') do |fp| - fp.puts "source 'https://rubygems.org'" - fp.puts "gem '#{foo1.name}', '#{foo1.version}'" - end - Gem.use_gemdeps(File.join Dir.pwd, 'Gemfile') - - expected = [ - File.expand_path('test/rubygems/sff/discover.rb', PROJECT_DIR), - File.join(foo1.full_gem_path, discover_path), - ].sort - - assert_equal expected, Gem.find_files('sff/discover').sort - assert_equal expected, Gem.find_files('sff/**.rb').sort, '[ruby-core:31730]' - ensure - assert_equal cwd, actual_load_path.shift unless Gem.java_platform? - end - def test_self_find_latest_files cwd = File.expand_path("test/rubygems", PROJECT_DIR) $LOAD_PATH.unshift cwd - discover_path = File.join 'lib', 'sff', 'discover.rb' + discover_path = File.join "lib", "sff", "discover.rb" _, foo2 = %w[1 2].map do |version| - spec = quick_gem 'sff', version do |s| + spec = quick_gem "sff", version do |s| s.files << discover_path end - write_file(File.join 'gems', spec.full_name, discover_path) do |fp| + write_file(File.join("gems", spec.full_name, discover_path)) do |fp| fp.puts "# #{spec.full_name}" end @@ -878,64 +789,103 @@ class TestGem < Gem::TestCase Gem.refresh expected = [ - File.expand_path('test/rubygems/sff/discover.rb', PROJECT_DIR), + File.expand_path("test/rubygems/sff/discover.rb", PROJECT_DIR), File.join(foo2.full_gem_path, discover_path), ] - assert_equal expected, Gem.find_latest_files('sff/discover') - assert_equal expected, Gem.find_latest_files('sff/**.rb'), '[ruby-core:31730]' + assert_equal expected, Gem.find_latest_files("sff/discover") + assert_equal expected, Gem.find_latest_files("sff/**.rb"), "[ruby-core:31730]" ensure assert_equal cwd, $LOAD_PATH.shift end def test_self_latest_spec_for gems = spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', '3.a' - fetcher.spec 'a', 2 + fetcher.spec "a", 1 + fetcher.spec "a", "3.a" + fetcher.spec "a", 2 end - spec = Gem.latest_spec_for 'a' + spec = Gem.latest_spec_for "a" - assert_equal gems['a-2'], spec + assert_equal gems["a-2"], spec + end + + def test_self_latest_spec_for_multiple_sources + uri = "https://example.sample.com/" + source = Gem::Source.new(uri) + source_list = Gem::SourceList.new + source_list << Gem::Source.new(@uri) + source_list << source + Gem.sources.replace source_list + + spec_fetcher(uri) do |fetcher| + fetcher.spec "a", 1.1 + end + + gems = spec_fetcher do |fetcher| + fetcher.spec "a", 1 + fetcher.spec "a", "3.a" + fetcher.spec "a", 2 + end + spec = Gem.latest_spec_for "a" + assert_equal gems["a-2"], spec end def test_self_latest_rubygems_version spec_fetcher do |fetcher| - fetcher.spec 'rubygems-update', '1.8.23' - fetcher.spec 'rubygems-update', '1.8.24' - fetcher.spec 'rubygems-update', '2.0.0.preview3' + fetcher.spec "rubygems-update", "1.8.23" + fetcher.spec "rubygems-update", "1.8.24" + fetcher.spec "rubygems-update", "2.0.0.preview3" end version = Gem.latest_rubygems_version - assert_equal Gem::Version.new('1.8.24'), version + assert_equal Gem::Version.new("1.8.24"), version end def test_self_latest_version_for spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', 2 - fetcher.spec 'a', '3.a' + fetcher.spec "a", 1 + fetcher.spec "a", 2 + fetcher.spec "a", "3.a" + end + + version = Gem.latest_version_for "a" + + assert_equal Gem::Version.new(2), version + end + + def test_self_latest_version_for_multiple_sources + uri = "https://example.sample.com/" + source = Gem::Source.new(uri) + source_list = Gem::SourceList.new + source_list << Gem::Source.new(@uri) + source_list << source + Gem.sources.replace source_list + + spec_fetcher(uri) do |fetcher| + fetcher.spec "a", 1.1 + end + + spec_fetcher do |fetcher| + fetcher.spec "a", 1 + fetcher.spec "a", 2 + fetcher.spec "a", "3.a" end - version = Gem.latest_version_for 'a' + version = Gem.latest_version_for "a" assert_equal Gem::Version.new(2), version end def test_self_loaded_specs - foo = util_spec 'foo' + foo = util_spec "foo" install_gem foo foo.activate - assert_equal true, Gem.loaded_specs.keys.include?('foo') - end - - def util_path - ENV.delete "GEM_HOME" - ENV.delete "GEM_PATH" + assert_equal true, Gem.loaded_specs.keys.include?("foo") end def test_self_path @@ -943,53 +893,19 @@ class TestGem < Gem::TestCase end def test_self_path_default - util_path - - if defined?(APPLE_GEM_HOME) - orig_APPLE_GEM_HOME = APPLE_GEM_HOME - Object.send :remove_const, :APPLE_GEM_HOME - end + ENV.delete "GEM_HOME" + ENV.delete "GEM_PATH" Gem.instance_variable_set :@paths, nil assert_equal [Gem.default_path, Gem.dir].flatten.uniq, Gem.path - ensure - Object.const_set :APPLE_GEM_HOME, orig_APPLE_GEM_HOME if orig_APPLE_GEM_HOME - end - - unless win_platform? - def test_self_path_APPLE_GEM_HOME - util_path - - Gem.clear_paths - apple_gem_home = File.join @tempdir, 'apple_gem_home' - - old, $-w = $-w, nil - Object.const_set :APPLE_GEM_HOME, apple_gem_home - $-w = old - - assert_includes Gem.path, apple_gem_home - ensure - Object.send :remove_const, :APPLE_GEM_HOME - end - - def test_self_path_APPLE_GEM_HOME_GEM_PATH - Gem.clear_paths - ENV['GEM_PATH'] = @gemhome - apple_gem_home = File.join @tempdir, 'apple_gem_home' - Gem.const_set :APPLE_GEM_HOME, apple_gem_home - - refute Gem.path.include?(apple_gem_home) - ensure - Gem.send :remove_const, :APPLE_GEM_HOME - end end def test_self_path_ENV_PATH path_count = Gem.path.size Gem.clear_paths - ENV['GEM_PATH'] = @additional.join(File::PATH_SEPARATOR) + ENV["GEM_PATH"] = @additional.join(File::PATH_SEPARATOR) assert_equal @additional, Gem.path[0,2] @@ -1001,10 +917,10 @@ class TestGem < Gem::TestCase def test_self_path_duplicate Gem.clear_paths util_ensure_gem_dirs - dirs = @additional + [@gemhome] + [File.join(@tempdir, 'a')] + dirs = @additional + [@gemhome] + [File.join(@tempdir, "a")] - ENV['GEM_HOME'] = @gemhome - ENV['GEM_PATH'] = dirs.join File::PATH_SEPARATOR + ENV["GEM_HOME"] = @gemhome + ENV["GEM_PATH"] = dirs.join File::PATH_SEPARATOR assert_equal @gemhome, Gem.dir @@ -1016,8 +932,8 @@ class TestGem < Gem::TestCase Gem.clear_paths util_ensure_gem_dirs - ENV['GEM_HOME'] = @gemhome - ENV['GEM_PATH'] = @additional.join(File::PATH_SEPARATOR) + ENV["GEM_HOME"] = @gemhome + ENV["GEM_PATH"] = @additional.join(File::PATH_SEPARATOR) assert_equal @gemhome, Gem.dir @@ -1034,38 +950,38 @@ class TestGem < Gem::TestCase end def test_self_prefix_libdir - orig_libdir = RbConfig::CONFIG['libdir'] - RbConfig::CONFIG['libdir'] = PROJECT_DIR + orig_libdir = RbConfig::CONFIG["libdir"] + RbConfig::CONFIG["libdir"] = PROJECT_DIR assert_nil Gem.prefix ensure - RbConfig::CONFIG['libdir'] = orig_libdir + RbConfig::CONFIG["libdir"] = orig_libdir end def test_self_prefix_sitelibdir - orig_sitelibdir = RbConfig::CONFIG['sitelibdir'] - RbConfig::CONFIG['sitelibdir'] = PROJECT_DIR + orig_sitelibdir = RbConfig::CONFIG["sitelibdir"] + RbConfig::CONFIG["sitelibdir"] = PROJECT_DIR assert_nil Gem.prefix ensure - RbConfig::CONFIG['sitelibdir'] = orig_sitelibdir + RbConfig::CONFIG["sitelibdir"] = orig_sitelibdir end def test_self_read_binary - File.open 'test', 'w' do |io| + File.open "test", "w" do |io| io.write "\xCF\x80" end - assert_equal ["\xCF", "\x80"], Gem.read_binary('test').chars.to_a + assert_equal ["\xCF", "\x80"], Gem.read_binary("test").chars.to_a - skip 'chmod not supported' if Gem.win_platform? + pend "chmod not supported" if Gem.win_platform? begin - File.chmod 0444, 'test' + File.chmod 0o444, "test" - assert_equal ["\xCF", "\x80"], Gem.read_binary('test').chars.to_a + assert_equal ["\xCF", "\x80"], Gem.read_binary("test").chars.to_a ensure - File.chmod 0644, 'test' + File.chmod 0o644, "test" end end @@ -1103,7 +1019,7 @@ class TestGem < Gem::TestCase Gem.refresh - Gem::Specification.each{|spec| assert spec.activated? if spec == s } + Gem::Specification.each {|spec| assert spec.activated? if spec == s } Gem.loaded_specs.delete(s) Gem.refresh @@ -1126,88 +1042,73 @@ class TestGem < Gem::TestCase end def test_self_ruby_api_version - orig_ruby_version, RbConfig::CONFIG['ruby_version'] = RbConfig::CONFIG['ruby_version'], '1.2.3' + orig_ruby_version = RbConfig::CONFIG["ruby_version"] + RbConfig::CONFIG["ruby_version"] = "1.2.3" Gem.instance_variable_set :@ruby_api_version, nil - assert_equal '1.2.3', Gem.ruby_api_version + assert_equal "1.2.3", Gem.ruby_api_version ensure Gem.instance_variable_set :@ruby_api_version, nil - RbConfig::CONFIG['ruby_version'] = orig_ruby_version + RbConfig::CONFIG["ruby_version"] = orig_ruby_version end def test_self_env_requirement - ENV["GEM_REQUIREMENT_FOO"] = '>= 1.2.3' - ENV["GEM_REQUIREMENT_BAR"] = '1.2.3' - ENV["GEM_REQUIREMENT_BAZ"] = 'abcd' + ENV["GEM_REQUIREMENT_FOO"] = ">= 1.2.3" + ENV["GEM_REQUIREMENT_BAR"] = "1.2.3" + ENV["GEM_REQUIREMENT_BAZ"] = "abcd" - assert_equal Gem::Requirement.create('>= 1.2.3'), Gem.env_requirement('foo') - assert_equal Gem::Requirement.create('1.2.3'), Gem.env_requirement('bAr') - assert_raise(Gem::Requirement::BadRequirementError) { Gem.env_requirement('baz') } - assert_equal Gem::Requirement.default, Gem.env_requirement('qux') - end - - def test_self_ruby_version_with_patchlevel_less_ancient_rubies - util_set_RUBY_VERSION '1.8.5' - - assert_equal Gem::Version.new('1.8.5'), Gem.ruby_version - ensure - util_restore_RUBY_VERSION - end - - def test_self_ruby_version_with_release - util_set_RUBY_VERSION '1.8.6', 287 - - assert_equal Gem::Version.new('1.8.6.287'), Gem.ruby_version - ensure - util_restore_RUBY_VERSION + assert_equal Gem::Requirement.create(">= 1.2.3"), Gem.env_requirement("foo") + assert_equal Gem::Requirement.create("1.2.3"), Gem.env_requirement("bAr") + assert_raise(Gem::Requirement::BadRequirementError) { Gem.env_requirement("baz") } + assert_equal Gem::Requirement.default, Gem.env_requirement("qux") end def test_self_ruby_version_with_non_mri_implementations - util_set_RUBY_VERSION '2.5.0', 0, 60928, 'jruby 9.2.0.0 (2.5.0) 2018-05-24 81156a8 OpenJDK 64-Bit Server VM 25.171-b11 on 1.8.0_171-8u171-b11-0ubuntu0.16.04.1-b11 [linux-x86_64]' + util_set_RUBY_VERSION "2.5.0", 0, 60_928, "jruby 9.2.0.0 (2.5.0) 2018-05-24 81156a8 OpenJDK 64-Bit Server VM 25.171-b11 on 1.8.0_171-8u171-b11-0ubuntu0.16.04.1-b11 [linux-x86_64]" - assert_equal Gem::Version.new('2.5.0'), Gem.ruby_version + assert_equal Gem::Version.new("2.5.0"), Gem.ruby_version ensure util_restore_RUBY_VERSION end def test_self_ruby_version_with_svn_prerelease - util_set_RUBY_VERSION '2.6.0', -1, 63539, 'ruby 2.6.0preview2 (2018-05-31 trunk 63539) [x86_64-linux]' + util_set_RUBY_VERSION "2.6.0", -1, 63_539, "ruby 2.6.0preview2 (2018-05-31 trunk 63539) [x86_64-linux]" - assert_equal Gem::Version.new('2.6.0.preview2'), Gem.ruby_version + assert_equal Gem::Version.new("2.6.0.preview2"), Gem.ruby_version ensure util_restore_RUBY_VERSION end def test_self_ruby_version_with_git_prerelease - util_set_RUBY_VERSION '2.7.0', -1, 'b563439274a402e33541f5695b1bfd4ac1085638', 'ruby 2.7.0preview3 (2019-11-23 master b563439274) [x86_64-linux]' + util_set_RUBY_VERSION "2.7.0", -1, "b563439274a402e33541f5695b1bfd4ac1085638", "ruby 2.7.0preview3 (2019-11-23 master b563439274) [x86_64-linux]" - assert_equal Gem::Version.new('2.7.0.preview3'), Gem.ruby_version + assert_equal Gem::Version.new("2.7.0.preview3"), Gem.ruby_version ensure util_restore_RUBY_VERSION end def test_self_ruby_version_with_non_mri_implementations_with_mri_prerelase_compatibility - util_set_RUBY_VERSION '2.6.0', -1, 63539, 'weirdjruby 9.2.0.0 (2.6.0preview2) 2018-05-24 81156a8 OpenJDK 64-Bit Server VM 25.171-b11 on 1.8.0_171-8u171-b11-0ubuntu0.16.04.1-b11 [linux-x86_64]', 'weirdjruby', '9.2.0.0' + util_set_RUBY_VERSION "2.6.0", -1, 63_539, "weirdjruby 9.2.0.0 (2.6.0preview2) 2018-05-24 81156a8 OpenJDK 64-Bit Server VM 25.171-b11 on 1.8.0_171-8u171-b11-0ubuntu0.16.04.1-b11 [linux-x86_64]", "weirdjruby", "9.2.0.0" - assert_equal Gem::Version.new('2.6.0.preview2'), Gem.ruby_version + assert_equal Gem::Version.new("2.6.0.preview2"), Gem.ruby_version ensure util_restore_RUBY_VERSION end def test_self_ruby_version_with_svn_trunk - util_set_RUBY_VERSION '1.9.2', -1, 23493, 'ruby 1.9.2dev (2009-05-20 trunk 23493) [x86_64-linux]' + util_set_RUBY_VERSION "1.9.2", -1, 23_493, "ruby 1.9.2dev (2009-05-20 trunk 23493) [x86_64-linux]" - assert_equal Gem::Version.new('1.9.2.dev'), Gem.ruby_version + assert_equal Gem::Version.new("1.9.2.dev"), Gem.ruby_version ensure util_restore_RUBY_VERSION end def test_self_ruby_version_with_git_master - util_set_RUBY_VERSION '2.7.0', -1, '5de284ec78220e75643f89b454ce999da0c1c195', 'ruby 2.7.0dev (2019-12-23T01:37:30Z master 5de284ec78) [x86_64-linux]' + util_set_RUBY_VERSION "2.7.0", -1, "5de284ec78220e75643f89b454ce999da0c1c195", "ruby 2.7.0dev (2019-12-23T01:37:30Z master 5de284ec78) [x86_64-linux]" - assert_equal Gem::Version.new('2.7.0.dev'), Gem.ruby_version + assert_equal Gem::Version.new("2.7.0.dev"), Gem.ruby_version ensure util_restore_RUBY_VERSION end @@ -1217,7 +1118,7 @@ class TestGem < Gem::TestCase end def test_self_paths_eq - other = File.join @tempdir, 'other' + other = File.join @tempdir, "other" path = [@userhome, other].join File::PATH_SEPARATOR # @@ -1230,12 +1131,12 @@ class TestGem < Gem::TestCase end def test_self_paths_eq_nonexistent_home - ENV['GEM_HOME'] = @gemhome + ENV["GEM_HOME"] = @gemhome Gem.clear_paths - other = File.join @tempdir, 'other' + other = File.join @tempdir, "other" - ENV['HOME'] = other + ENV["HOME"] = other Gem.paths = { "GEM_PATH" => other } @@ -1314,74 +1215,74 @@ class TestGem < Gem::TestCase end def test_try_activate_returns_true_for_activated_specs - b = util_spec 'b', '1.0' do |spec| - spec.files << 'lib/b.rb' + b = util_spec "b", "1.0" do |spec| + spec.files << "lib/b.rb" end install_specs b - assert Gem.try_activate('b'), 'try_activate should return true' - assert Gem.try_activate('b'), 'try_activate should still return true' + assert Gem.try_activate("b"), "try_activate should return true" + assert Gem.try_activate("b"), "try_activate should still return true" end def test_spec_order_is_consistent - b1 = util_spec 'b', '1.0' - b2 = util_spec 'b', '2.0' - b3 = util_spec 'b', '3.0' + b1 = util_spec "b", "1.0" + b2 = util_spec "b", "2.0" + b3 = util_spec "b", "3.0" install_specs b1, b2, b3 - specs1 = Gem::Specification.stubs.find_all {|s| s.name == 'b' } + specs1 = Gem::Specification.stubs.find_all {|s| s.name == "b" } Gem::Specification.reset - specs2 = Gem::Specification.stubs_for('b') + specs2 = Gem::Specification.stubs_for("b") assert_equal specs1.map(&:version), specs2.map(&:version) end def test_self_try_activate_missing_dep - b = util_spec 'b', '1.0' - a = util_spec 'a', '1.0', 'b' => '>= 1.0' + b = util_spec "b", "1.0" + a = util_spec "a", "1.0", "b" => ">= 1.0" install_specs b, a uninstall_gem b - a_file = File.join a.gem_dir, 'lib', 'a_file.rb' + a_file = File.join a.gem_dir, "lib", "a_file.rb" write_file a_file do |io| - io.puts '# a_file.rb' + io.puts "# a_file.rb" end e = assert_raise Gem::MissingSpecError do - Gem.try_activate 'a_file' + Gem.try_activate "a_file" end - assert_match %r{Could not find 'b' }, e.message - assert_match %r{at: #{a.spec_file}}, e.message + assert_include(e.message, "Could not find 'b' ") + assert_include(e.message, "at: #{a.spec_file}") end def test_self_try_activate_missing_prerelease - b = util_spec 'b', '1.0rc1' - a = util_spec 'a', '1.0rc1', 'b' => '1.0rc1' + b = util_spec "b", "1.0rc1" + a = util_spec "a", "1.0rc1", "b" => "1.0rc1" install_specs b, a uninstall_gem b - a_file = File.join a.gem_dir, 'lib', 'a_file.rb' + a_file = File.join a.gem_dir, "lib", "a_file.rb" write_file a_file do |io| - io.puts '# a_file.rb' + io.puts "# a_file.rb" end e = assert_raise Gem::MissingSpecError do - Gem.try_activate 'a_file' + Gem.try_activate "a_file" end - assert_match %r{Could not find 'b' \(= 1.0rc1\)}, e.message + assert_match(/Could not find 'b' \(= 1.0rc1\)/, e.message) end def test_self_try_activate_missing_extensions - spec = util_spec 'ext', '1' do |s| + spec = util_spec "ext", "1" do |s| s.extensions = %w[ext/extconf.rb] s.mark_version - s.installed_by_version = v('2.2') + s.installed_by_version = v("2.2") end # write the spec without install to simulate a failed install @@ -1390,55 +1291,53 @@ class TestGem < Gem::TestCase end _, err = capture_output do - refute Gem.try_activate 'nonexistent' + refute Gem.try_activate "nonexistent" end - unless Gem.java_platform? - expected = "Ignoring ext-1 because its extensions are not built. " + - "Try: gem pristine ext --version 1\n" + expected = "Ignoring ext-1 because its extensions are not built. " \ + "Try: gem pristine ext --version 1\n" - assert_equal expected, err - end + assert_equal expected, err end def test_self_use_paths_with_nils - orig_home = ENV.delete 'GEM_HOME' - orig_path = ENV.delete 'GEM_PATH' + orig_home = ENV.delete "GEM_HOME" + orig_path = ENV.delete "GEM_PATH" Gem.use_paths nil, nil assert_equal Gem.default_dir, Gem.paths.home path = (Gem.default_path + [Gem.paths.home]).uniq assert_equal path, Gem.paths.path ensure - ENV['GEM_HOME'] = orig_home - ENV['GEM_PATH'] = orig_path + ENV["GEM_HOME"] = orig_home + ENV["GEM_PATH"] = orig_path end def test_setting_paths_does_not_warn_about_unknown_keys stdout, stderr = capture_output do - Gem.paths = { 'foo' => [], - 'bar' => Object.new, - 'GEM_HOME' => Gem.paths.home, - 'GEM_PATH' => 'foo' } + Gem.paths = { "foo" => [], + "bar" => Object.new, + "GEM_HOME" => Gem.paths.home, + "GEM_PATH" => "foo" } end - assert_equal ['foo', Gem.paths.home], Gem.paths.path - assert_equal '', stderr - assert_equal '', stdout + assert_equal ["foo", Gem.paths.home], Gem.paths.path + assert_equal "", stderr + assert_equal "", stdout end def test_setting_paths_does_not_mutate_parameter_object - Gem.paths = { 'GEM_HOME' => Gem.paths.home, - 'GEM_PATH' => 'foo' }.freeze - assert_equal ['foo', Gem.paths.home], Gem.paths.path + Gem.paths = { "GEM_HOME" => Gem.paths.home, + "GEM_PATH" => "foo" } .freeze + assert_equal ["foo", Gem.paths.home], Gem.paths.path end def test_deprecated_paths= stdout, stderr = capture_output do - Gem.paths = { 'GEM_HOME' => Gem.paths.home, - 'GEM_PATH' => [Gem.paths.home, 'foo'] } + Gem.paths = { "GEM_HOME" => Gem.paths.home, + "GEM_PATH" => [Gem.paths.home, "foo"] } end - assert_equal [Gem.paths.home, 'foo'], Gem.paths.path + assert_equal [Gem.paths.home, "foo"], Gem.paths.path assert_match(/Array values in the parameter to `Gem.paths=` are deprecated.\nPlease use a String or nil/m, stderr) - assert_equal '', stdout + assert_equal "", stdout end def test_self_use_paths @@ -1451,8 +1350,8 @@ class TestGem < Gem::TestCase end def test_self_user_dir - parts = [@userhome, '.gem', Gem.ruby_engine] - parts << RbConfig::CONFIG['ruby_version'] unless RbConfig::CONFIG['ruby_version'].empty? + parts = [@userhome, ".gem", Gem.ruby_engine] + parts << RbConfig::CONFIG["ruby_version"] unless RbConfig::CONFIG["ruby_version"].empty? FileUtils.mkdir_p File.join(parts) @@ -1460,10 +1359,10 @@ class TestGem < Gem::TestCase end def test_self_user_home - if ENV['HOME'] - assert_equal ENV['HOME'], Gem.user_home + if ENV["HOME"] + assert_equal ENV["HOME"], Gem.user_home else - assert true, 'count this test' + assert true, "count this test" end end @@ -1479,67 +1378,65 @@ class TestGem < Gem::TestCase r.gem "b", "= 1" end - activated = Gem::Specification.map {|x| x.full_name } + activated = Gem::Specification.map(&: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 - a = util_spec "a", "1" - b = util_spec "b", "1", "c" => nil - c = util_spec "c", "2" - d = util_spec "d", "1", {'e' => '= 1'}, "lib/d#{$$}.rb" - e = util_spec "e", "1" - - install_specs a, c, b, e, d + a = util_spec "a", "1" + b = util_spec "b", "1", "c" => nil + c = util_spec "c", "2" + d = util_spec "d", "1", { "e" => "= 1" }, "lib/d#{$$}.rb" + e = util_spec "e", "1" - Gem.needs do |r| - r.gem "a" - r.gem "b", "= 1" + install_specs a, c, b, e, d - require "d#{$$}" - end + Gem.needs do |r| + r.gem "a" + r.gem "b", "= 1" - assert_equal %w[a-1 b-1 c-2 d-1 e-1], loaded_spec_names + require "d#{$$}" end + + assert_equal %w[a-1 b-1 c-2 d-1 e-1], loaded_spec_names end def test_self_gunzip - input = "\x1F\x8B\b\0\xED\xA3\x1AQ\0\x03\xCBH" + + input = "\x1F\x8B\b\0\xED\xA3\x1AQ\0\x03\xCBH" \ "\xCD\xC9\xC9\a\0\x86\xA6\x106\x05\0\0\0" output = Gem::Util.gunzip input - assert_equal 'hello', output + assert_equal "hello", output assert_equal Encoding::BINARY, output.encoding end def test_self_gzip - input = 'hello' + input = "hello" output = Gem::Util.gzip input zipped = StringIO.new output - assert_equal 'hello', Zlib::GzipReader.new(zipped).read + assert_equal "hello", Zlib::GzipReader.new(zipped).read assert_equal Encoding::BINARY, output.encoding end def test_self_vendor_dir - vendordir(File.join(@tempdir, 'vendor')) do + vendordir(File.join(@tempdir, "vendor")) do expected = - File.join RbConfig::CONFIG['vendordir'], 'gems', - RbConfig::CONFIG['ruby_version'] + File.join RbConfig::CONFIG["vendordir"], "gems", + RbConfig::CONFIG["ruby_version"] assert_equal expected, Gem.vendor_dir end end def test_self_vendor_dir_ENV_GEM_VENDOR - ENV['GEM_VENDOR'] = File.join @tempdir, 'vendor', 'gems' + ENV["GEM_VENDOR"] = File.join @tempdir, "vendor", "gems" - assert_equal ENV['GEM_VENDOR'], Gem.vendor_dir + assert_equal ENV["GEM_VENDOR"], Gem.vendor_dir refute Gem.vendor_dir.frozen? end @@ -1552,102 +1449,151 @@ class TestGem < Gem::TestCase def test_load_plugins plugin_path = File.join "lib", "rubygems_plugin.rb" + foo1_plugin_path = nil + foo2_plugin_path = nil Dir.chdir @tempdir do - FileUtils.mkdir_p 'lib' + FileUtils.mkdir_p "lib" File.open plugin_path, "w" do |fp| fp.puts "class TestGem; PLUGINS_LOADED << 'plugin'; end" end - foo1 = util_spec 'foo', '1' do |s| + foo1 = util_spec "foo", "1" do |s| s.files << plugin_path end + foo1_plugin_path = File.join(foo1.gem_dir, plugin_path) install_gem foo1 - foo2 = util_spec 'foo', '2' do |s| + foo2 = util_spec "foo", "2" do |s| s.files << plugin_path end + foo2_plugin_path = File.join(foo2.gem_dir, plugin_path) install_gem foo2 end Gem::Specification.reset + PLUGINS_LOADED.clear + $LOADED_FEATURES.delete(foo1_plugin_path) + $LOADED_FEATURES.delete(foo2_plugin_path) + + gem "foo" + + Gem.load_plugins + + assert_equal %w[plugin], PLUGINS_LOADED + end + + def test_load_user_installed_plugins + @orig_gem_home = ENV["GEM_HOME"] + ENV["GEM_HOME"] = @gemhome - gem 'foo' + plugin_path = File.join "lib", "rubygems_plugin.rb" + + Dir.chdir @tempdir do + FileUtils.mkdir_p "lib" + File.open plugin_path, "w" do |fp| + fp.puts "class TestGem; PLUGINS_LOADED << 'plugin'; end" + end + + foo = util_spec "foo", "1" do |s| + s.files << plugin_path + end + + install_gem_user foo + end + + Gem.paths = { "GEM_PATH" => [Gem.dir, Gem.user_dir].join(File::PATH_SEPARATOR) } + + gem "foo" Gem.load_plugins assert_equal %w[plugin], PLUGINS_LOADED + ensure + ENV["GEM_HOME"] = @orig_gem_home end def test_load_env_plugins - with_plugin('load') { Gem.load_env_plugins } - assert_equal :loaded, TEST_PLUGIN_LOAD rescue nil + with_plugin("load") { Gem.load_env_plugins } + begin + assert_equal :loaded, TEST_PLUGIN_LOAD + rescue StandardError + nil + end util_remove_interrupt_command # Should attempt to cause a StandardError - with_plugin('standarderror') { Gem.load_env_plugins } - assert_equal :loaded, TEST_PLUGIN_STANDARDERROR rescue nil + with_plugin("standarderror") { Gem.load_env_plugins } + begin + assert_equal :loaded, TEST_PLUGIN_STANDARDERROR + rescue StandardError + nil + end util_remove_interrupt_command # Should attempt to cause an Exception - with_plugin('exception') { Gem.load_env_plugins } - assert_equal :loaded, TEST_PLUGIN_EXCEPTION rescue nil + with_plugin("scripterror") { Gem.load_env_plugins } + begin + assert_equal :loaded, TEST_PLUGIN_EXCEPTION + rescue StandardError + nil + end end def test_gem_path_ordering refute_equal Gem.dir, Gem.user_dir - write_file File.join(@tempdir, 'lib', "g.rb") {|fp| fp.puts "" } - write_file File.join(@tempdir, 'lib', 'm.rb') {|fp| fp.puts "" } + write_file File.join(@tempdir, "lib", "g.rb") {|fp| fp.puts "" } + write_file File.join(@tempdir, "lib", "m.rb") {|fp| fp.puts "" } - g = util_spec 'g', '1', nil, "lib/g.rb" - m = util_spec 'm', '1', nil, "lib/m.rb" + g = util_spec "g", "1", nil, "lib/g.rb" + m = util_spec "m", "1", nil, "lib/m.rb" - install_gem g, :install_dir => Gem.dir - m0 = install_gem m, :install_dir => Gem.dir - m1 = install_gem m, :install_dir => Gem.user_dir + install_gem g, install_dir: Gem.dir + m0 = install_gem m, install_dir: Gem.dir + m1 = install_gem m, install_dir: Gem.user_dir assert_equal m0.gem_dir, File.join(Gem.dir, "gems", "m-1") assert_equal m1.gem_dir, File.join(Gem.user_dir, "gems", "m-1") tests = [ - [:dir0, [ Gem.dir, Gem.user_dir], m0], - [:dir1, [ Gem.user_dir, Gem.dir], m1], + [:dir0, [Gem.dir, Gem.user_dir], m0], + [:dir1, [Gem.user_dir, Gem.dir], m1], ] - tests.each do |_name, _paths, expected| - Gem.use_paths _paths.first, _paths + tests.each do |name, paths, expected| + Gem.use_paths paths.first, paths Gem::Specification.reset Gem.searcher = nil - assert_equal Gem::Dependency.new('m','1').to_specs, - Gem::Dependency.new('m','1').to_specs.sort + assert_equal Gem::Dependency.new("m","1").to_specs, + Gem::Dependency.new("m","1").to_specs.sort assert_equal \ [expected.gem_dir], - Gem::Dependency.new('m','1').to_specs.map(&:gem_dir).sort, - "Wrong specs for #{_name}" + Gem::Dependency.new("m","1").to_specs.map(&:gem_dir).sort, + "Wrong specs for #{name}" - spec = Gem::Dependency.new('m','1').to_spec + spec = Gem::Dependency.new("m","1").to_spec assert_equal \ - File.join(_paths.first, "gems", "m-1"), + File.join(paths.first, "gems", "m-1"), spec.gem_dir, - "Wrong spec before require for #{_name}" - refute spec.activated?, "dependency already activated for #{_name}" + "Wrong spec before require for #{name}" + refute spec.activated?, "dependency already activated for #{name}" gem "m" - spec = Gem::Dependency.new('m','1').to_spec - assert spec.activated?, "dependency not activated for #{_name}" + spec = Gem::Dependency.new("m","1").to_spec + assert spec.activated?, "dependency not activated for #{name}" assert_equal \ - File.join(_paths.first, "gems", "m-1"), + File.join(paths.first, "gems", "m-1"), spec.gem_dir, - "Wrong spec after require for #{_name}" + "Wrong spec after require for #{name}" spec.instance_variable_set :@activated, false Gem.loaded_specs.delete(spec.name) @@ -1656,152 +1602,24 @@ class TestGem < Gem::TestCase end def test_gem_path_ordering_short - write_file File.join(@tempdir, 'lib', "g.rb") {|fp| fp.puts "" } - write_file File.join(@tempdir, 'lib', 'm.rb') {|fp| fp.puts "" } + write_file File.join(@tempdir, "lib", "g.rb") {|fp| fp.puts "" } + write_file File.join(@tempdir, "lib", "m.rb") {|fp| fp.puts "" } - g = util_spec 'g', '1', nil, "lib/g.rb" - m = util_spec 'm', '1', nil, "lib/m.rb" + g = util_spec "g", "1", nil, "lib/g.rb" + m = util_spec "m", "1", nil, "lib/m.rb" - install_gem g, :install_dir => Gem.dir - install_gem m, :install_dir => Gem.dir - install_gem m, :install_dir => Gem.user_dir + install_gem g, install_dir: Gem.dir + install_gem m, install_dir: Gem.dir + install_gem m, install_dir: Gem.user_dir - Gem.use_paths Gem.dir, [ Gem.dir, Gem.user_dir] + Gem.use_paths Gem.dir, [Gem.dir, Gem.user_dir] assert_equal \ File.join(Gem.dir, "gems", "m-1"), - Gem::Dependency.new('m','1').to_spec.gem_dir, + Gem::Dependency.new("m","1").to_spec.gem_dir, "Wrong spec selected" end - def test_auto_activation_of_specific_gemdeps_file - a = util_spec "a", "1", nil, "lib/a.rb" - b = util_spec "b", "1", nil, "lib/b.rb" - c = util_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.use_gemdeps - - assert_equal add_bundler_full_name(%W[a-1 b-1 c-1]), loaded_spec_names - end - - def test_auto_activation_of_used_gemdeps_file - a = util_spec "a", "1", nil, "lib/a.rb" - b = util_spec "b", "1", nil, "lib/b.rb" - c = util_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'] = "-" - - expected_specs = [a, b, util_spec("bundler", Bundler::VERSION), c].compact - assert_equal expected_specs, Gem.use_gemdeps.sort_by {|s| s.name } - end - - BUNDLER_LIB_PATH = File.expand_path $LOAD_PATH.find {|lp| File.file?(File.join(lp, "bundler.rb")) } - BUNDLER_FULL_NAME = "bundler-#{Bundler::VERSION}".freeze - - def add_bundler_full_name(names) - names << BUNDLER_FULL_NAME - names.sort! - names - end - - def test_looks_for_gemdeps_files_automatically_on_start - skip "Requiring bundler messes things up" if Gem.java_platform? - - a = util_spec "a", "1", nil, "lib/a.rb" - b = util_spec "b", "1", nil, "lib/b.rb" - c = util_spec "c", "1", nil, "lib/c.rb" - - install_specs a, b, c - - 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'] = "-" - - path = File.join @tempdir, "gem.deps.rb" - cmd = [*ruby_with_rubygems_in_load_path, - "-I#{BUNDLER_LIB_PATH}"] - cmd << "-eputs Gem.loaded_specs.values.map(&:full_name).sort" - - File.open path, "w" do |f| - f.puts "gem 'a'" - end - out0 = IO.popen(cmd, &:read).split(/\n/) - - File.open path, "a" do |f| - f.puts "gem 'b'" - f.puts "gem 'c'" - end - out = IO.popen(cmd, &:read).split(/\n/) - - assert_equal ["b-1", "c-1"], out - out0 - end - - def test_looks_for_gemdeps_files_automatically_on_start_in_parent_dir - skip "Requiring bundler messes things up" if Gem.java_platform? - - a = util_spec "a", "1", nil, "lib/a.rb" - b = util_spec "b", "1", nil, "lib/b.rb" - c = util_spec "c", "1", nil, "lib/c.rb" - - install_specs a, b, c - - path = File.join(@tempdir, "gd-tmp") - install_gem a, :install_dir => path - install_gem b, :install_dir => path - install_gem c, :install_dir => path - - ENV['GEM_PATH'] = path - ENV['RUBYGEMS_GEMDEPS'] = "-" - - Dir.mkdir "sub1" - - path = File.join @tempdir, "gem.deps.rb" - cmd = [*ruby_with_rubygems_in_load_path, "-Csub1", - "-I#{BUNDLER_LIB_PATH}"] - cmd << "-eputs Gem.loaded_specs.values.map(&:full_name).sort" - - File.open path, "w" do |f| - f.puts "gem 'a'" - end - out0 = IO.popen(cmd, &:read).split(/\n/) - - File.open path, "a" do |f| - f.puts "gem 'b'" - f.puts "gem 'c'" - end - out = IO.popen(cmd, &:read).split(/\n/) - - Dir.rmdir "sub1" - - assert_equal ["b-1", "c-1"], out - out0 - end - def test_register_default_spec Gem.clear_default_specs @@ -1842,179 +1660,25 @@ class TestGem < Gem::TestCase assert_equal old_style, Gem.find_unresolved_default_spec("foo.rb") end - def test_use_gemdeps - gem_deps_file = 'gem.deps.rb'.tap(&Gem::UNTAINT) - spec = util_spec 'a', 1 - install_specs spec - - spec = Gem::Specification.find {|s| s == spec } - refute spec.activated? - - File.open gem_deps_file, 'w' do |io| - io.write 'gem "a"' - end - - assert_nil Gem.gemdeps - - Gem.use_gemdeps gem_deps_file - - assert_equal add_bundler_full_name(%W[a-1]), loaded_spec_names - refute_nil Gem.gemdeps - end - - def test_use_gemdeps_ENV - rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], nil - - spec = util_spec 'a', 1 - - refute spec.activated? - - File.open 'gem.deps.rb', 'w' do |io| - io.write 'gem "a"' - end - - Gem.use_gemdeps - - refute spec.activated? - ensure - ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps - end - - def test_use_gemdeps_argument_missing - e = assert_raise ArgumentError do - Gem.use_gemdeps 'gem.deps.rb' - end - - assert_equal 'Unable to find gem dependencies file at gem.deps.rb', - e.message - end - - def test_use_gemdeps_argument_missing_match_ENV - rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = - ENV['RUBYGEMS_GEMDEPS'], 'gem.deps.rb' - - e = assert_raise ArgumentError do - Gem.use_gemdeps 'gem.deps.rb' - end - - assert_equal 'Unable to find gem dependencies file at gem.deps.rb', - e.message - ensure - ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps - end - - def test_use_gemdeps_automatic - rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], '-' - - spec = util_spec 'a', 1 - install_specs spec - spec = Gem::Specification.find {|s| s == spec } - - refute spec.activated? - - File.open 'Gemfile', 'w' do |io| - io.write 'gem "a"' - end - - Gem.use_gemdeps - - assert_equal add_bundler_full_name(%W[a-1]), loaded_spec_names - ensure - ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps - end - - def test_use_gemdeps_automatic_missing - rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], '-' - - Gem.use_gemdeps - - assert true # count - ensure - ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps - end - - def test_use_gemdeps_disabled - rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], '' - - spec = util_spec 'a', 1 - - refute spec.activated? - - File.open 'gem.deps.rb', 'w' do |io| - io.write 'gem "a"' - end - - Gem.use_gemdeps - - refute spec.activated? - ensure - ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps - end - - def test_use_gemdeps_missing_gem - rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], 'x' - - File.open 'x', 'w' do |io| - io.write 'gem "a"' - end - - expected = <<-EXPECTED -Could not find gem 'a' in locally installed gems. -The source does not contain any versions of 'a' -You may need to `gem install -g` to install missing gems - - EXPECTED - - Gem::Deprecate.skip_during do - actual_stdout, actual_stderr = capture_output do - Gem.use_gemdeps - end - assert_empty actual_stdout - assert_equal(expected, actual_stderr) - end - ensure - ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps - end - - def test_use_gemdeps_specific - rubygems_gemdeps, ENV['RUBYGEMS_GEMDEPS'] = ENV['RUBYGEMS_GEMDEPS'], 'x' - - spec = util_spec 'a', 1 - install_specs spec - - spec = Gem::Specification.find {|s| s == spec } - refute spec.activated? - - File.open 'x', 'w' do |io| - io.write 'gem "a"' - end - - Gem.use_gemdeps - - assert_equal add_bundler_full_name(%W[a-1]), loaded_spec_names - ensure - ENV['RUBYGEMS_GEMDEPS'] = rubygems_gemdeps - end - def test_operating_system_defaults operating_system_defaults = Gem.operating_system_defaults - assert operating_system_defaults != nil + assert !operating_system_defaults.nil? assert operating_system_defaults.is_a? Hash end def test_platform_defaults platform_defaults = Gem.platform_defaults - assert platform_defaults != nil + assert !platform_defaults.nil? assert platform_defaults.is_a? Hash end # Ensure that `Gem.source_date_epoch` is consistent even if # $SOURCE_DATE_EPOCH has not been set. def test_default_source_date_epoch_doesnt_change - old_epoch = ENV['SOURCE_DATE_EPOCH'] - ENV['SOURCE_DATE_EPOCH'] = nil + old_epoch = ENV["SOURCE_DATE_EPOCH"] + ENV["SOURCE_DATE_EPOCH"] = nil # Unfortunately, there is no real way to test this aside from waiting # enough for `Time.now.to_i` to change -- which is a whole second. @@ -2025,21 +1689,47 @@ You may need to `gem install -g` to install missing gems b = Gem.source_date_epoch assert_equal a, b ensure - ENV['SOURCE_DATE_EPOCH'] = old_epoch + ENV["SOURCE_DATE_EPOCH"] = old_epoch + end + + def test_data_home_default + expected = File.join(@userhome, ".local", "share") + assert_equal expected, Gem.data_home end + def test_data_home_from_env + ENV["XDG_DATA_HOME"] = expected = "/test/data/home" + assert_equal expected, Gem.data_home + end + + def test_state_home_default + Gem.instance_variable_set :@state_home, nil + Gem.data_home # memoize @data_home, to demonstrate GH-6418 + expected = File.join(@userhome, ".local", "state") + assert_equal expected, Gem.state_home + end + + def test_state_home_from_env + Gem.instance_variable_set :@state_home, nil + Gem.data_home # memoize @data_home, to demonstrate GH-6418 + ENV["XDG_STATE_HOME"] = expected = "/test/state/home" + assert_equal expected, Gem.state_home + end + + private + def ruby_install_name(name) with_clean_path_to_ruby do - orig_RUBY_INSTALL_NAME = RbConfig::CONFIG['ruby_install_name'] - RbConfig::CONFIG['ruby_install_name'] = name + orig_ruby_install_name = RbConfig::CONFIG["ruby_install_name"] + RbConfig::CONFIG["ruby_install_name"] = name begin yield ensure - if orig_RUBY_INSTALL_NAME - RbConfig::CONFIG['ruby_install_name'] = orig_RUBY_INSTALL_NAME + if orig_ruby_install_name + RbConfig::CONFIG["ruby_install_name"] = orig_ruby_install_name else - RbConfig::CONFIG.delete 'ruby_install_name' + RbConfig::CONFIG.delete "ruby_install_name" end end end @@ -2057,13 +1747,8 @@ You may need to `gem install -g` to install missing gems end def redefine_method(base, method, new_result) - if RUBY_VERSION >= "2.5" - base.alias_method(method, method) - base.define_method(method) { new_result } - else - base.send(:alias_method, method, method) - base.send(:define_method, method) { new_result } - end + base.alias_method(method, method) + base.define_method(method) { new_result } end def with_plugin(path) @@ -2088,18 +1773,18 @@ You may need to `gem install -g` to install missing gems # # FIXME what does this solve precisely? -ebh # - @additional.each do |dir| + @additional.each do |_dir| Gem.ensure_gem_subdirectories @gemhome end end def util_exec_gem - spec, _ = util_spec 'a', '4' do |s| - s.executables = ['exec', 'abin'] + spec, _ = util_spec "a", "4" do |s| + s.executables = ["exec", "abin"] end - @exec_path = File.join spec.full_gem_path, spec.bindir, 'exec' - @abin_path = File.join spec.full_gem_path, spec.bindir, 'abin' + @exec_path = File.join spec.full_gem_path, spec.bindir, "exec" + @abin_path = File.join spec.full_gem_path, spec.bindir, "abin" spec end diff --git a/test/rubygems/test_gem_available_set.rb b/test/rubygems/test_gem_available_set.rb index dd2816acc6..7c24d25bcb 100644 --- a/test/rubygems/test_gem_available_set.rb +++ b/test/rubygems/test_gem_available_set.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/available_set' -require 'rubygems/security' + +require_relative "helper" +require "rubygems/available_set" +require "rubygems/security" class TestGemAvailableSet < Gem::TestCase def setup @@ -11,7 +12,7 @@ class TestGemAvailableSet < Gem::TestCase end def test_add_and_empty - a1, _ = util_gem 'a', '1' + a1, _ = util_gem "a", "1" set = Gem::AvailableSet.new assert set.empty? @@ -24,8 +25,8 @@ class TestGemAvailableSet < Gem::TestCase end def test_find_all - a1, a1_gem = util_gem 'a', 1 - a1a, a1a_gem = util_gem 'a', '1.a' + a1, a1_gem = util_gem "a", 1 + a1a, a1a_gem = util_gem "a", "1.a" a1_source = Gem::Source::SpecificFile.new a1_gem a1a_source = Gem::Source::SpecificFile.new a1a_gem @@ -34,26 +35,26 @@ class TestGemAvailableSet < Gem::TestCase set.add a1, a1_source set.add a1a, a1a_source - dep = Gem::Resolver::DependencyRequest.new dep('a'), nil + dep = Gem::Resolver::DependencyRequest.new dep("a"), nil - assert_equal %w[a-1], set.find_all(dep).map {|spec| spec.full_name } + assert_equal %w[a-1], set.find_all(dep).map(&:full_name) - dep = Gem::Resolver::DependencyRequest.new dep('a', '>= 0.a'), nil + dep = Gem::Resolver::DependencyRequest.new dep("a", ">= 0.a"), nil assert_equal %w[a-1 a-1.a], - set.find_all(dep).map {|spec| spec.full_name }.sort + set.find_all(dep).map(&:full_name).sort end def test_match_platform - a1, _ = util_gem 'a', '1' do |g| + a1, _ = util_gem "a", "1" do |g| g.platform = "something-weird-yep" end - a1c, _ = util_gem 'a', '2' do |g| + a1c, _ = util_gem "a", "2" do |g| g.platform = Gem::Platform.local end - a2, _ = util_gem 'a', '2' + a2, _ = util_gem "a", "2" set = Gem::AvailableSet.new set.add a1, @source @@ -66,8 +67,8 @@ class TestGemAvailableSet < Gem::TestCase end def test_best - a1, _ = util_gem 'a', '1' - a2, _ = util_gem 'a', '2' + a1, _ = util_gem "a", "1" + a2, _ = util_gem "a", "2" set = Gem::AvailableSet.new set.add a1, @source @@ -79,7 +80,7 @@ class TestGemAvailableSet < Gem::TestCase end def test_remove_installed_bang - a1, _ = util_spec 'a', '1' + a1, _ = util_spec "a", "1" install_specs a1 a1.activate @@ -95,8 +96,8 @@ class TestGemAvailableSet < Gem::TestCase end def test_sorted_normal_versions - a1, _ = util_gem 'a', '1' - a2, _ = util_gem 'a', '2' + a1, _ = util_gem "a", "1" + a2, _ = util_gem "a", "2" set = Gem::AvailableSet.new set.add a1, @source @@ -109,11 +110,11 @@ class TestGemAvailableSet < Gem::TestCase 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' + 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 @@ -122,7 +123,7 @@ class TestGemAvailableSet < Gem::TestCase set.add a2a, @source set.add a2, @source - g = set.sorted.map {|t| t.spec } + g = set.sorted.map(&:spec) assert_equal [a3a, a2, a2a, a1, a1a], g end diff --git a/test/rubygems/test_gem_bundler_version_finder.rb b/test/rubygems/test_gem_bundler_version_finder.rb index 4372356db8..6d88810493 100644 --- a/test/rubygems/test_gem_bundler_version_finder.rb +++ b/test/rubygems/test_gem_bundler_version_finder.rb @@ -1,19 +1,19 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" +require "rubygems/bundler_version_finder" class TestGemBundlerVersionFinder < Gem::TestCase def setup - super - @argv = ARGV.dup - @env = ENV.to_hash.clone - ENV.delete("BUNDLER_VERSION") @dollar_0 = $0 + super + + without_any_upwards_gemfiles end def teardown ARGV.replace @argv - ENV.replace @env $0 = @dollar_0 super @@ -50,36 +50,37 @@ class TestGemBundlerVersionFinder < Gem::TestCase end def test_bundler_version_with_lockfile - bvf.stub(:lockfile_contents, [nil, ""]) do + bvf.stub(:lockfile_contents, "") do assert_nil bvf.bundler_version end - bvf.stub(:lockfile_contents, [nil, "\n\nBUNDLED WITH\n 1.1.1.1\n"]) do + bvf.stub(:lockfile_contents, "\n\nBUNDLED WITH\n 1.1.1.1\n") do assert_equal v("1.1.1.1"), bvf.bundler_version end - bvf.stub(:lockfile_contents, [nil, "\n\nBUNDLED WITH\n fjdkslfjdkslfjsldk\n"]) do + bvf.stub(:lockfile_contents, "\n\nBUNDLED WITH\n fjdkslfjdkslfjsldk\n") do assert_nil bvf.bundler_version end end - def test_bundler_version_with_reason - assert_nil bvf.bundler_version_with_reason - bvf.stub(:lockfile_contents, [nil, "\n\nBUNDLED WITH\n 1.1.1.1\n"]) do - assert_equal ["1.1.1.1", "your lockfile"], bvf.bundler_version_with_reason + def test_bundler_version + assert_nil bvf.bundler_version + bvf.stub(:lockfile_contents, "\n\nBUNDLED WITH\n 1.1.1.1\n") do + assert_equal "1.1.1.1", bvf.bundler_version.to_s $0 = "bundle" ARGV.replace %w[update --bundler] - assert_nil bvf.bundler_version_with_reason + assert_nil bvf.bundler_version + ARGV.replace %w[update --bundler=1.1.1.2] - assert_equal ["1.1.1.2", "`bundle update --bundler`"], bvf.bundler_version_with_reason + assert_equal "1.1.1.2", bvf.bundler_version.to_s ENV["BUNDLER_VERSION"] = "1.1.1.3" - assert_equal ["1.1.1.3", "`$BUNDLER_VERSION`"], bvf.bundler_version_with_reason + assert_equal "1.1.1.3", bvf.bundler_version.to_s end end def test_deleted_directory - skip "Cannot perform this test on windows" if win_platform? - skip "Cannot perform this test on Solaris" if /solaris/ =~ RUBY_PLATFORM + pend "Cannot perform this test on windows" if Gem.win_platform? + pend "Cannot perform this test on Solaris" if RUBY_PLATFORM.include?("solaris") require "tmpdir" orig_dir = Dir.pwd @@ -92,57 +93,35 @@ class TestGemBundlerVersionFinder < Gem::TestCase Dir.chdir(orig_dir) end - assert_nil bvf.bundler_version_with_reason - end - - def test_compatible - assert bvf.compatible?(util_spec("foo")) - assert bvf.compatible?(util_spec("bundler", 1.1)) - - bvf.stub(:bundler_version, v("1.1.1.1")) do - assert bvf.compatible?(util_spec("foo")) - assert bvf.compatible?(util_spec("bundler", "1.1.1.1")) - assert bvf.compatible?(util_spec("bundler", "1.1.1.a")) - assert bvf.compatible?(util_spec("bundler", "1.999")) - refute bvf.compatible?(util_spec("bundler", "2.999")) - end - - bvf.stub(:bundler_version, v("2.1.1.1")) do - assert bvf.compatible?(util_spec("foo")) - assert bvf.compatible?(util_spec("bundler", "2.1.1.1")) - assert bvf.compatible?(util_spec("bundler", "2.1.1.a")) - assert bvf.compatible?(util_spec("bundler", "2.999")) - refute bvf.compatible?(util_spec("bundler", "1.999")) - refute bvf.compatible?(util_spec("bundler", "3.0.0")) - end + assert_nil bvf.bundler_version end - def test_filter + def test_prioritize versions = %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1] specs = versions.map {|v| util_spec("bundler", v) } - assert_equal %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_filter_specs(specs).map(&:version).map(&:to_s) + assert_equal %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs) bvf.stub(:bundler_version, v("2.1.1.1")) do - assert_equal %w[2 2.a 2.0 2.1.1], util_filter_specs(specs).map(&:version).map(&:to_s) + assert_equal %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs) end bvf.stub(:bundler_version, v("1.1.1.1")) do - assert_equal %w[1 1.0 1.0.1.1], util_filter_specs(specs).map(&:version).map(&:to_s) + assert_equal %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs) end bvf.stub(:bundler_version, v("1")) do - assert_equal %w[1 1.0 1.0.1.1], util_filter_specs(specs).map(&:version).map(&:to_s) + assert_equal %w[1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs) end bvf.stub(:bundler_version, v("2.a")) do - assert_equal %w[2.a 2 2.0 2.1.1], util_filter_specs(specs).map(&:version).map(&:to_s) + assert_equal %w[2.a 1 1.0 1.0.1.1 2 2.0 2.1.1 3 3.a 3.0 3.1.1], util_prioritize_specs(specs) end bvf.stub(:bundler_version, v("3")) do - assert_equal %w[3 3.a 3.0 3.1.1], util_filter_specs(specs).map(&:version).map(&:to_s) + assert_equal %w[3 1 1.0 1.0.1.1 2 2.a 2.0 2.1.1 3.a 3.0 3.1.1], util_prioritize_specs(specs) end end - def util_filter_specs(specs) + def util_prioritize_specs(specs) specs = specs.dup - bvf.filter!(specs) - specs + bvf.prioritize!(specs) + specs.map(&:version).map(&:to_s) end end diff --git a/test/rubygems/test_gem_ci_detector.rb b/test/rubygems/test_gem_ci_detector.rb new file mode 100644 index 0000000000..3caefce97d --- /dev/null +++ b/test/rubygems/test_gem_ci_detector.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +require_relative "helper" +require "rubygems" + +class TestCiDetector < Test::Unit::TestCase + def test_ci? + with_env("FOO" => "bar") { assert_equal(false, Gem::CIDetector.ci?) } + with_env("CI" => "true") { assert_equal(true, Gem::CIDetector.ci?) } + with_env("CONTINUOUS_INTEGRATION" => "1") { assert_equal(true, Gem::CIDetector.ci?) } + with_env("RUN_ID" => "0", "TASKCLUSTER_ROOT_URL" => "2") do + assert_equal(true, Gem::CIDetector.ci?) + end + end + + def test_ci_strings + with_env("FOO" => "bar") { assert_empty(Gem::CIDetector.ci_strings) } + with_env("TRAVIS" => "true") { assert_equal(["travis"], Gem::CIDetector.ci_strings) } + with_env("CI" => "true", "CIRCLECI" => "true", "GITHUB_ACTIONS" => "true") do + assert_equal(["ci", "circle", "github"], Gem::CIDetector.ci_strings) + end + with_env("CI" => "true", "CI_NAME" => "MYCI") do + assert_equal(["ci", "myci"], Gem::CIDetector.ci_strings) + end + with_env("GITHUB_ACTIONS" => "true", "CI_NAME" => "github") do + assert_equal(["github"], Gem::CIDetector.ci_strings) + end + with_env("TASKCLUSTER_ROOT_URL" => "https://foo.bar", "DSARI" => "1", "CI_NAME" => "") do + assert_equal(["dsari", "taskcluster"], Gem::CIDetector.ci_strings) + end + end + + private + + def with_env(overrides, &block) + @orig_env = ENV.to_h + ENV.replace(overrides) + begin + block.call + ensure + ENV.replace(@orig_env) + end + end +end diff --git a/test/rubygems/test_gem_command.rb b/test/rubygems/test_gem_command.rb index a99de30b33..3695f9488f 100644 --- a/test/rubygems/test_gem_command.rb +++ b/test/rubygems/test_gem_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/command' + +require_relative "helper" +require "rubygems/command" class Gem::Command public :parser @@ -15,13 +16,13 @@ class TestGemCommand < Gem::TestCase @common_options = Gem::Command.common_options.dup Gem::Command.common_options.clear Gem::Command.common_options << [ - ['-x', '--exe', 'Execute'], lambda do |*a| + ["-x", "--exe", "Execute"], lambda do |*_a| @xopt = true end ] - @cmd_name = 'doit' - @cmd = Gem::Command.new @cmd_name, 'summary' + @cmd_name = "doit" + @cmd = Gem::Command.new @cmd_name, "summary" end def teardown @@ -31,7 +32,7 @@ class TestGemCommand < Gem::TestCase def test_self_add_specific_extra_args added_args = %w[--all] - @cmd.add_option('--all') {|v,o| } + @cmd.add_option("--all") {|v,o| } Gem::Command.add_specific_extra_args @cmd_name, added_args @@ -55,7 +56,9 @@ class TestGemCommand < Gem::TestCase end def test_self_extra_args - verbose, $VERBOSE, separator = $VERBOSE, nil, $; + verbose = $VERBOSE + $VERBOSE = nil + separator = $; extra_args = Gem::Command.extra_args Gem::Command.extra_args = %w[--all] @@ -68,7 +71,6 @@ class TestGemCommand < Gem::TestCase Gem::Command.extra_args = "--awesome=true --verbose" assert_equal %w[--awesome=true --verbose], Gem::Command.extra_args - ensure Gem::Command.extra_args = extra_args $; = separator @@ -86,11 +88,11 @@ class TestGemCommand < Gem::TestCase end def test_defaults - @cmd.add_option('-h', '--help [COMMAND]', 'Get help on COMMAND') do |value, options| + @cmd.add_option("-h", "--help [COMMAND]", "Get help on COMMAND") do |value, options| options[:help] = value end - @cmd.defaults = { :help => true } + @cmd.defaults = { help: true } @cmd.when_invoked do |options| assert options[:help], "Help options should default true" @@ -100,7 +102,7 @@ class TestGemCommand < Gem::TestCase @cmd.invoke end - assert_match %r{Usage: gem doit}, @ui.output + assert_match(/Usage: gem doit/, @ui.output) end def test_invoke @@ -118,8 +120,8 @@ class TestGemCommand < Gem::TestCase use_ui @ui do @cmd.when_invoked { true } - ex = assert_raise OptionParser::InvalidOption do - @cmd.invoke('-zzz') + ex = assert_raise Gem::OptionParser::InvalidOption do + @cmd.invoke("-zzz") end assert_match(/invalid option:/, ex.message) @@ -151,12 +153,12 @@ class TestGemCommand < Gem::TestCase done = false use_ui @ui do - @cmd.add_option('-h', '--help [COMMAND]', 'Get help on COMMAND') do |value, options| + @cmd.add_option("-h", "--help [COMMAND]", "Get help on COMMAND") do |_value, options| options[:help] = true done = true end - @cmd.invoke('--help') + @cmd.invoke("--help") assert done end @@ -174,7 +176,7 @@ class TestGemCommand < Gem::TestCase end def test_invoke_with_options - @cmd.add_option('-h', '--help [COMMAND]', 'Get help on COMMAND') do |value, options| + @cmd.add_option("-h", "--help [COMMAND]", "Get help on COMMAND") do |_value, options| options[:help] = true end @@ -183,36 +185,48 @@ class TestGemCommand < Gem::TestCase end use_ui @ui do - @cmd.invoke '-h' + @cmd.invoke "-h" + end + + assert_match(/Usage: gem doit/, @ui.output) + end + + def test_add_option + assert_nothing_raised RuntimeError do + @cmd.add_option("--force", "skip validation of the spec") {|v,o| } end + end - assert_match %r{Usage: gem doit}, @ui.output + def test_add_option_with_empty + assert_raise RuntimeError, "Do not pass an empty string in opts" do + @cmd.add_option("", "skip validation of the spec") {|v,o| } + end end def test_option_recognition - @cmd.add_option('-h', '--help [COMMAND]', 'Get help on COMMAND') do |value, options| + @cmd.add_option("-h", "--help [COMMAND]", "Get help on COMMAND") do |_value, options| options[:help] = true end - @cmd.add_option('-f', '--file FILE', 'File option') do |value, options| + @cmd.add_option("-f", "--file FILE", "File option") do |_value, options| options[:help] = true end - @cmd.add_option('--silent', 'Silence RubyGems output') do |value, options| + @cmd.add_option("--silent", "Silence RubyGems output") do |_value, options| options[:silent] = true end - assert @cmd.handles?(['-x']) - assert @cmd.handles?(['-h']) - assert @cmd.handles?(['-h', 'command']) - assert @cmd.handles?(['--help', 'command']) - assert @cmd.handles?(['-f', 'filename']) - assert @cmd.handles?(['--file=filename']) - assert @cmd.handles?(['--silent']) - refute @cmd.handles?(['-z']) - refute @cmd.handles?(['-f']) - refute @cmd.handles?(['--toothpaste']) - - args = ['-h', 'command'] + assert @cmd.handles?(["-x"]) + assert @cmd.handles?(["-h"]) + assert @cmd.handles?(["-h", "command"]) + assert @cmd.handles?(["--help", "command"]) + assert @cmd.handles?(["-f", "filename"]) + assert @cmd.handles?(["--file=filename"]) + assert @cmd.handles?(["--silent"]) + refute @cmd.handles?(["-z"]) + refute @cmd.handles?(["-f"]) + refute @cmd.handles?(["--toothpaste"]) + + args = ["-h", "command"] @cmd.handles?(args) - assert_equal ['-h', 'command'], args + assert_equal ["-h", "command"], args end def test_deprecate_option @@ -220,15 +234,15 @@ class TestGemCommand < Gem::TestCase WARNING: The \"--test\" option has been deprecated and will be removed in Rubygems 3.1. EXPECTED - testCommand = Class.new(Gem::Command) do + test_command = Class.new(Gem::Command) do def initialize - super('test', 'Gem::Command instance for testing') + super("test", "Gem::Command instance for testing") - add_option('-t', '--test', 'Test command') do |value, options| + add_option("-t", "--test", "Test command") do |_value, options| options[:test] = true end - deprecate_option('--test', version: '3.1') + deprecate_option("--test", version: "3.1") end def execute @@ -236,7 +250,7 @@ WARNING: The \"--test\" option has been deprecated and will be removed in Rubyg end end - cmd = testCommand.new + cmd = test_command.new use_ui @ui do cmd.invoke("--test") @@ -249,15 +263,15 @@ WARNING: The \"--test\" option has been deprecated and will be removed in Rubyg WARNING: The \"--test\" option has been deprecated and will be removed in future versions of Rubygems. EXPECTED - testCommand = Class.new(Gem::Command) do + test_command = Class.new(Gem::Command) do def initialize - super('test', 'Gem::Command instance for testing') + super("test", "Gem::Command instance for testing") - add_option('-t', '--test', 'Test command') do |value, options| + add_option("-t", "--test", "Test command") do |_value, options| options[:test] = true end - deprecate_option('--test') + deprecate_option("--test") end def execute @@ -265,7 +279,7 @@ WARNING: The \"--test\" option has been deprecated and will be removed in futur end end - cmd = testCommand.new + cmd = test_command.new use_ui @ui do cmd.invoke("--test") @@ -278,15 +292,15 @@ WARNING: The \"--test\" option has been deprecated and will be removed in futur WARNING: The \"--test\" option has been deprecated and will be removed in Rubygems 3.1. Whether you set `--test` mode or not, this dummy app always runs in test mode. EXPECTED - testCommand = Class.new(Gem::Command) do + test_command = Class.new(Gem::Command) do def initialize - super('test', 'Gem::Command instance for testing') + super("test", "Gem::Command instance for testing") - add_option('-t', '--test', 'Test command') do |value, options| + add_option("-t", "--test", "Test command") do |_value, options| options[:test] = true end - deprecate_option('--test', version: '3.1', extra_msg: 'Whether you set `--test` mode or not, this dummy app always runs in test mode.') + deprecate_option("--test", version: "3.1", extra_msg: "Whether you set `--test` mode or not, this dummy app always runs in test mode.") end def execute @@ -294,7 +308,7 @@ WARNING: The \"--test\" option has been deprecated and will be removed in Rubyg end end - cmd = testCommand.new + cmd = test_command.new use_ui @ui do cmd.invoke("--test") @@ -307,15 +321,15 @@ WARNING: The \"--test\" option has been deprecated and will be removed in Rubyg WARNING: The \"--test\" option has been deprecated and will be removed in future versions of Rubygems. Whether you set `--test` mode or not, this dummy app always runs in test mode. EXPECTED - testCommand = Class.new(Gem::Command) do + test_command = Class.new(Gem::Command) do def initialize - super('test', 'Gem::Command instance for testing') + super("test", "Gem::Command instance for testing") - add_option('-t', '--test', 'Test command') do |value, options| + add_option("-t", "--test", "Test command") do |_value, options| options[:test] = true end - deprecate_option('--test', extra_msg: 'Whether you set `--test` mode or not, this dummy app always runs in test mode.') + deprecate_option("--test", extra_msg: "Whether you set `--test` mode or not, this dummy app always runs in test mode.") end def execute @@ -323,7 +337,7 @@ WARNING: The \"--test\" option has been deprecated and will be removed in futur end end - cmd = testCommand.new + cmd = test_command.new use_ui @ui do cmd.invoke("--test") @@ -352,11 +366,11 @@ ERROR: Could not find a valid gem 'nonexistent_with_hint' (>= 0) in any reposit def test_show_lookup_failure_suggestions_none spec_fetcher do |fetcher| - fetcher.spec 'correct', 2 + fetcher.spec "correct", 2 end use_ui @ui do - @cmd.show_lookup_failure 'other', Gem::Requirement.default, [], :remote + @cmd.show_lookup_failure "other", Gem::Requirement.default, [], :remote end expected = <<-EXPECTED diff --git a/test/rubygems/test_gem_command_manager.rb b/test/rubygems/test_gem_command_manager.rb index 16e2f4a4dd..f04ec0cafa 100644 --- a/test/rubygems/test_gem_command_manager.rb +++ b/test/rubygems/test_gem_command_manager.rb @@ -1,9 +1,10 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/command_manager' + +require_relative "helper" +require "rubygems/command_manager" class TestGemCommandManager < Gem::TestCase - PROJECT_DIR = File.expand_path('../../..', __FILE__).tap(&Gem::UNTAINT) + PROJECT_DIR = File.expand_path("../..", __dir__) def setup super @@ -12,37 +13,49 @@ class TestGemCommandManager < Gem::TestCase end def test_find_command - command = @command_manager.find_command 'install' + command = @command_manager.find_command "install" assert_kind_of Gem::Commands::InstallCommand, command - command = @command_manager.find_command 'ins' + command = @command_manager.find_command "ins" assert_kind_of Gem::Commands::InstallCommand, command end def test_find_command_ambiguous e = assert_raise Gem::CommandLineError do - @command_manager.find_command 'u' + @command_manager.find_command "u" end - assert_equal 'Ambiguous command u matches [uninstall, unpack, update]', + assert_equal "Ambiguous command u matches [uninstall, unpack, update]", e.message end def test_find_alias_command - command = @command_manager.find_command 'i' + command = @command_manager.find_command "i" assert_kind_of Gem::Commands::InstallCommand, command end + def test_find_login_alias_command + command = @command_manager.find_command "login" + + assert_kind_of Gem::Commands::SigninCommand, command + end + + def test_find_logout_alias_comamnd + command = @command_manager.find_command "logout" + + assert_kind_of Gem::Commands::SignoutCommand, command + 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' + command = @command_manager.find_command "ins" assert_kind_of ins_command, command ensure @@ -51,24 +64,30 @@ class TestGemCommandManager < Gem::TestCase def test_find_command_unknown e = assert_raise Gem::UnknownCommandError do - @command_manager.find_command 'xyz' + @command_manager.find_command "xyz" end - assert_equal 'Unknown command xyz', e.message + assert_equal "Unknown command xyz", e.message end def test_find_command_unknown_suggestions e = assert_raise Gem::UnknownCommandError do - @command_manager.find_command 'pish' + @command_manager.find_command "pish" end - message = 'Unknown command pish'.dup + message = "Unknown command pish".dup - if RUBY_VERSION >= "2.4" && defined?(DidYouMean::SPELL_CHECKERS) && defined?(DidYouMean::Correctable) + if defined?(DidYouMean::SPELL_CHECKERS) && defined?(DidYouMean::Correctable) message << "\nDid you mean? \"push\"" end - assert_equal message, e.message + if e.respond_to?(:detailed_message) + actual_message = e.detailed_message(highlight: false).sub(/\A(.*?)(?: \(.+?\))/) { $1 } + else + actual_message = e.message + end + + assert_equal message, actual_message end def test_run_interrupt @@ -82,7 +101,7 @@ class TestGemCommandManager < Gem::TestCase assert_raise Gem::MockGemUi::TermError do @command_manager.run %w[interrupt] end - assert_equal '', ui.output + assert_equal "", ui.output assert_equal "ERROR: Interrupted\n", ui.error end ensure @@ -99,7 +118,7 @@ class TestGemCommandManager < Gem::TestCase assert_raise Gem::MockGemUi::TermError do @command_manager.run %w[crash] end - assert_equal '', ui.output + assert_equal "", ui.output err = ui.error.split("\n").first assert_equal "ERROR: Loading command: crash (RuntimeError)", err end @@ -108,6 +127,46 @@ class TestGemCommandManager < Gem::TestCase @command_manager.unregister_command :crash end + def test_process_args_with_c_flag + custom_start_point = File.join @tempdir, "nice_folder" + FileUtils.mkdir_p custom_start_point + + execution_path = nil + use_ui @ui do + @command_manager[:install].when_invoked do + execution_path = Dir.pwd + true + end + @command_manager.process_args %W[-C #{custom_start_point} install net-scp-4.0.0.gem --local] + end + + assert_equal custom_start_point, execution_path + end + + def test_process_args_with_c_flag_without_path + use_ui @ui do + assert_raise Gem::MockGemUi::TermError do + @command_manager.process_args %w[-C install net-scp-4.0.0.gem --local] + end + end + + assert_match(/install isn't a directory\./i, @ui.error) + end + + def test_process_args_with_c_flag_path_not_found + custom_start_point = File.join @tempdir, "nice_folder" + FileUtils.mkdir_p custom_start_point + custom_start_point.tr!("_", "-") + + use_ui @ui do + assert_raise Gem::MockGemUi::TermError do + @command_manager.process_args %W[-C #{custom_start_point} install net-scp-4.0.0.gem --local] + end + end + + assert_match(/#{Regexp.quote(custom_start_point)} isn't a directory\./i, @ui.error) + end + def test_process_args_bad_arg use_ui @ui do assert_raise Gem::MockGemUi::TermError do @@ -118,17 +177,17 @@ class TestGemCommandManager < Gem::TestCase assert_match(/invalid option: --bad-arg/i, @ui.error) end - # HACK move to install command test + # HACK: move to install command test def test_process_args_install - #capture all install options + # capture all install options use_ui @ui do check_options = nil - @command_manager['install'].when_invoked do |options| + @command_manager["install"].when_invoked do |options| check_options = options true end - #check defaults + # check defaults @command_manager.process_args %w[install] assert_equal %w[ri], check_options[:document].sort assert_equal false, check_options[:force] @@ -138,7 +197,7 @@ class TestGemCommandManager < Gem::TestCase assert_nil check_options[:install_dir] assert_nil check_options[:bin_dir] - #check settings + # check settings check_options = nil @command_manager.process_args %w[ install --force --local --document=ri,rdoc --install-dir . @@ -148,103 +207,103 @@ class TestGemCommandManager < Gem::TestCase assert_equal true, check_options[:force] assert_equal :local, check_options[:domain] assert_equal false, check_options[:wrappers] - assert_equal Gem::Requirement.new('3.0'), check_options[:version] + assert_equal Gem::Requirement.new("3.0"), check_options[:version] assert_equal Dir.pwd, check_options[:install_dir] assert_equal Dir.pwd, check_options[:bin_dir] - #check remote domain + # check remote domain check_options = nil @command_manager.process_args %w[install --remote] assert_equal :remote, check_options[:domain] - #check both domain + # check both domain check_options = nil @command_manager.process_args %w[install --both] assert_equal :both, check_options[:domain] - #check both domain + # check both domain check_options = nil @command_manager.process_args %w[install --both] assert_equal :both, check_options[:domain] end end - # HACK move to uninstall command test + # HACK: move to uninstall command test def test_process_args_uninstall - #capture all uninstall options + # capture all uninstall options check_options = nil - @command_manager['uninstall'].when_invoked do |options| + @command_manager["uninstall"].when_invoked do |options| check_options = options true end - #check defaults + # check defaults @command_manager.process_args %w[uninstall] assert_equal Gem::Requirement.default, check_options[:version] - #check settings + # check settings check_options = nil @command_manager.process_args %w[uninstall foobar --version 3.0] assert_equal "foobar", check_options[:args].first - assert_equal Gem::Requirement.new('3.0'), check_options[:version] + assert_equal Gem::Requirement.new("3.0"), check_options[:version] end - # HACK move to check command test + # HACK: move to check command test def test_process_args_check - #capture all check options + # capture all check options check_options = nil - @command_manager['check'].when_invoked do |options| + @command_manager["check"].when_invoked do |options| check_options = options true end - #check defaults + # check defaults @command_manager.process_args %w[check] assert_equal true, check_options[:alien] - #check settings + # check settings check_options = nil @command_manager.process_args %w[check foobar --alien] assert_equal true, check_options[:alien] end - # HACK move to build command test + # HACK: move to build command test def test_process_args_build - #capture all build options + # capture all build options check_options = nil - @command_manager['build'].when_invoked do |options| + @command_manager["build"].when_invoked do |options| check_options = options true end - #check defaults + # check defaults @command_manager.process_args %w[build] - #NOTE: Currently no defaults + # NOTE: Currently no defaults - #check settings + # check settings check_options = nil @command_manager.process_args %w[build foobar.rb] - assert_equal 'foobar.rb', check_options[:args].first + assert_equal "foobar.rb", check_options[:args].first end - # HACK move to query command test + # HACK: move to query command test def test_process_args_query - #capture all query options + # capture all query options check_options = nil - @command_manager['query'].when_invoked do |options| + @command_manager["query"].when_invoked do |options| check_options = options true end - #check defaults + # check defaults Gem::Deprecate.skip_during do @command_manager.process_args %w[query] end - assert_equal(//, check_options[:name]) + assert_nil(check_options[:name]) assert_equal :local, check_options[:domain] assert_equal false, check_options[:details] - #check settings + # check settings check_options = nil Gem::Deprecate.skip_during do @command_manager.process_args %w[query --name foobar --local --details] @@ -253,14 +312,14 @@ class TestGemCommandManager < Gem::TestCase assert_equal :local, check_options[:domain] assert_equal true, check_options[:details] - #remote domain + # remote domain check_options = nil Gem::Deprecate.skip_during do @command_manager.process_args %w[query --remote] end assert_equal :remote, check_options[:domain] - #both (local/remote) domains + # both (local/remote) domains check_options = nil Gem::Deprecate.skip_during do @command_manager.process_args %w[query --both] @@ -268,29 +327,29 @@ class TestGemCommandManager < Gem::TestCase assert_equal :both, check_options[:domain] end - # HACK move to update command test + # HACK: move to update command test def test_process_args_update - #capture all update options + # capture all update options check_options = nil - @command_manager['update'].when_invoked do |options| + @command_manager["update"].when_invoked do |options| check_options = options true end - #check defaults + # check defaults @command_manager.process_args %w[update] - assert_includes check_options[:document], 'ri' + assert_includes check_options[:document], "ri" - #check settings + # check settings check_options = nil @command_manager.process_args %w[update --force --document=ri --install-dir .] - assert_includes check_options[:document], 'ri' + assert_includes check_options[:document], "ri" assert_equal true, check_options[:force] assert_equal Dir.pwd, check_options[:install_dir] end def test_deprecated_command - require 'rubygems/command' + require "rubygems/command" foo_command = Class.new(Gem::Command) do extend Gem::Deprecate @@ -309,7 +368,32 @@ class TestGemCommandManager < Gem::TestCase end assert_equal "pew pew!\n", @ui.output - assert_match(/WARNING: foo command is deprecated. It will be removed in Rubygems [0-9]+/, @ui.error) + assert_match(/WARNING: foo command is deprecated\. It will be removed in Rubygems [0-9]+/, @ui.error) + ensure + Gem::Commands.send(:remove_const, :FooCommand) + end + + def test_deprecated_command_with_version + require "rubygems/command" + foo_command = Class.new(Gem::Command) do + extend Gem::Deprecate + + rubygems_deprecate_command("9.9.9") + + def execute + say "pew pew!" + end + end + + Gem::Commands.send(:const_set, :FooCommand, foo_command) + @command_manager.register_command(:foo, foo_command.new("foo")) + + use_ui @ui do + @command_manager.process_args(%w[foo]) + end + + assert_equal "pew pew!\n", @ui.output + assert_match(/WARNING: foo command is deprecated\. It will be removed in Rubygems 9\.9\.9/, @ui.error) ensure Gem::Commands.send(:remove_const, :FooCommand) end diff --git a/test/rubygems/test_gem_commands_build_command.rb b/test/rubygems/test_gem_commands_build_command.rb index a7606aafee..d44126d204 100644 --- a/test/rubygems/test_gem_commands_build_command.rb +++ b/test/rubygems/test_gem_commands_build_command.rb @@ -1,32 +1,34 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/build_command' -require 'rubygems/package' + +require_relative "helper" +require "rubygems/commands/build_command" +require "rubygems/package" class TestGemCommandsBuildCommand < Gem::TestCase - CERT_FILE = cert_path 'public3072' - SIGNING_KEY = key_path 'private3072' + CERT_FILE = cert_path "public3072" + SIGNING_KEY = key_path "private3072" - EXPIRED_CERT_FILE = cert_path 'expired' - PRIVATE_KEY_FILE = key_path 'private' + EXPIRED_CERT_FILE = cert_path "expired" + PRIVATE_KEY_FILE = key_path "private" def setup super - readme_file = File.join(@tempdir, 'README.md') + readme_file = File.join(@tempdir, "README.md") begin umask_orig = File.umask(2) - File.open readme_file, 'w' do |f| - f.write 'My awesome gem' + File.open readme_file, "w" do |f| + f.write "My awesome gem" end ensure File.umask(umask_orig) end - @gem = util_spec 'some_gem' do |s| - s.license = 'AGPL-3.0' - s.files = ['README.md'] + @gem = util_spec "some_gem" do |s| + s.license = "AGPL-3.0-only" + s.files = ["README.md"] + s.required_ruby_version = "2.3.0" end @cmd = Gem::Commands::BuildCommand.new @@ -41,10 +43,20 @@ class TestGemCommandsBuildCommand < Gem::TestCase assert_includes Gem.platforms, Gem::Platform.local end + def test_handle_deprecated_options + use_ui @ui do + @cmd.handle_options %w[-C ./test/dir] + end + + assert_equal "WARNING: The \"-C\" option has been deprecated and will be removed in Rubygems 4.0. " \ + "-C is a global flag now. Use `gem -C PATH build GEMSPEC_FILE [options]` instead\n", + @ui.error + end + def test_options_filename gemspec_file = File.join(@tempdir, @gem.spec_name) - File.open gemspec_file, 'w' do |gs| + File.open gemspec_file, "w" do |gs| gs.write @gem.to_ruby end @@ -79,7 +91,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase def test_execute gemspec_file = File.join(@tempdir, @gem.spec_name) - File.open gemspec_file, 'w' do |gs| + File.open gemspec_file, "w" do |gs| gs.write @gem.to_ruby end @@ -91,7 +103,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase def test_execute_platform gemspec_file = File.join(@tempdir, @gem.spec_name) - File.open gemspec_file, 'w' do |gs| + File.open gemspec_file, "w" do |gs| gs.write @gem.to_ruby end @@ -110,15 +122,15 @@ class TestGemCommandsBuildCommand < Gem::TestCase def test_execute_bad_name [".", "-", "_"].each do |special_char| - gem = util_spec 'some_gem_with_bad_name' do |s| + gem = util_spec "some_gem_with_bad_name" do |s| s.name = "#{special_char}bad_gem_name" - s.license = 'AGPL-3.0' - s.files = ['README.md'] + s.license = "AGPL-3.0" + s.files = ["README.md"] end gemspec_file = File.join(@tempdir, gem.spec_name) - File.open gemspec_file, 'w' do |gs| + File.open gemspec_file, "w" do |gs| gs.write gem.to_ruby end @@ -137,7 +149,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase def test_execute_strict_without_warnings gemspec_file = File.join(@tempdir, @gem.spec_name) - File.open gemspec_file, 'w' do |gs| + File.open gemspec_file, "w" do |gs| gs.write @gem.to_ruby end @@ -165,13 +177,14 @@ class TestGemCommandsBuildCommand < Gem::TestCase end def test_execute_strict_with_warnings - bad_gem = util_spec 'some_bad_gem' do |s| - s.files = ['README.md'] + bad_gem = util_spec "some_bad_gem" do |s| + s.files = ["README.md"] + s.required_ruby_version = ">= 1.9.3" end gemspec_file = File.join(@tempdir, bad_gem.spec_name) - File.open gemspec_file, 'w' do |gs| + File.open gemspec_file, "w" do |gs| gs.write bad_gem.to_ruby end @@ -187,8 +200,9 @@ class TestGemCommandsBuildCommand < Gem::TestCase end error = @ui.error.split "\n" - assert_equal "WARNING: licenses is empty, but is recommended. Use a license identifier from", error.shift - assert_equal "http://spdx.org/licenses or 'Nonstandard' for a nonstandard license.", error.shift + assert_equal "WARNING: licenses is empty, but is recommended. Use an license identifier from", error.shift + assert_equal "https://spdx.org/licenses or 'Nonstandard' for a nonstandard license,", error.shift + assert_equal "or set it to nil if you don't want to specify a license.", error.shift assert_equal "WARNING: See https://guides.rubygems.org/specification-reference/ for help", error.shift assert_equal [], error @@ -201,7 +215,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase gemspec_file = File.join(@tempdir, @gem.spec_name) - File.open gemspec_file, 'w' do |gs| + File.open gemspec_file, "w" do |gs| gs.write @gem.to_ruby.sub(/11-08/, "11-8") end @@ -218,7 +232,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase assert_equal "", out assert_match(/invalid date format in specification/, err) - assert_equal '', @ui.output + assert_equal "", @ui.output assert_equal "ERROR: Error loading gemspec. Aborting.\n", @ui.error end @@ -230,22 +244,22 @@ class TestGemCommandsBuildCommand < Gem::TestCase end end - assert_equal '', @ui.output + assert_equal "", @ui.output assert_equal "ERROR: Couldn't find a gemspec file matching 'some_gem' in #{@tempdir}\n", @ui.error end def test_execute_outside_dir - gemspec_dir = File.join @tempdir, 'build_command_gem' + gemspec_dir = File.join @tempdir, "build_command_gem" gemspec_file = File.join gemspec_dir, @gem.spec_name - readme_file = File.join gemspec_dir, 'README.md' + readme_file = File.join gemspec_dir, "README.md" FileUtils.mkdir_p gemspec_dir - File.open readme_file, 'w' do |f| + File.open readme_file, "w" do |f| f.write "My awesome gem" end - File.open gemspec_file, 'w' do |gs| + File.open gemspec_file, "w" do |gs| gs.write @gem.to_ruby end @@ -273,17 +287,17 @@ class TestGemCommandsBuildCommand < Gem::TestCase end def test_execute_outside_dir_with_glob_argument - gemspec_dir = File.join @tempdir, 'build_command_gem' + gemspec_dir = File.join @tempdir, "build_command_gem" gemspec_file = File.join gemspec_dir, @gem.spec_name - readme_file = File.join gemspec_dir, 'README.md' + readme_file = File.join gemspec_dir, "README.md" FileUtils.mkdir_p gemspec_dir - File.open readme_file, 'w' do |f| + File.open readme_file, "w" do |f| f.write "My awesome gem" end - File.open gemspec_file, 'w' do |gs| + File.open gemspec_file, "w" do |gs| gs.write @gem.to_ruby end @@ -311,17 +325,17 @@ class TestGemCommandsBuildCommand < Gem::TestCase end def test_execute_outside_dir_no_gemspec_present - gemspec_dir = File.join @tempdir, 'build_command_gem' + gemspec_dir = File.join @tempdir, "build_command_gem" gemspec_file = File.join @tempdir, @gem.spec_name - readme_file = File.join gemspec_dir, 'README.md' + readme_file = File.join gemspec_dir, "README.md" FileUtils.mkdir_p gemspec_dir - File.open readme_file, 'w' do |f| + File.open readme_file, "w" do |f| f.write "My awesome gem" end - File.open gemspec_file, 'w' do |gs| + File.open gemspec_file, "w" do |gs| gs.write @gem.to_ruby end @@ -342,14 +356,14 @@ class TestGemCommandsBuildCommand < Gem::TestCase end def test_execute_outside_dir_without_gem_name - gemspec_dir = File.join(@tempdir, 'build_command_gem') + gemspec_dir = File.join(@tempdir, "build_command_gem") gemspec_file = File.join(gemspec_dir, @gem.spec_name) - readme_file = File.join gemspec_dir, 'README.md' + readme_file = File.join gemspec_dir, "README.md" FileUtils.mkdir_p(gemspec_dir) - File.open readme_file, 'w' do |f| + File.open readme_file, "w" do |f| f.write "My awesome gem" end @@ -383,20 +397,20 @@ class TestGemCommandsBuildCommand < Gem::TestCase end def test_execute_outside_dir_with_external_gemspec - gemspec_dir = File.join @tempdir, 'gemspec_dir' + gemspec_dir = File.join @tempdir, "gemspec_dir" gemspec_file = File.join gemspec_dir, @gem.spec_name - gemcode_dir = File.join @tempdir, 'build_command_gem' - readme_file = File.join gemcode_dir, 'README.md' + gemcode_dir = File.join @tempdir, "build_command_gem" + readme_file = File.join gemcode_dir, "README.md" FileUtils.mkdir_p gemspec_dir FileUtils.mkdir_p gemcode_dir - File.open readme_file, 'w' do |f| + File.open readme_file, "w" do |f| f.write "My awesome gem in nested directory" end - File.open gemspec_file, 'w' do |gs| + File.open gemspec_file, "w" do |gs| gs.write @gem.to_ruby end @@ -424,20 +438,20 @@ class TestGemCommandsBuildCommand < Gem::TestCase end def test_execute_outside_dir_with_external_relative_gemspec - gemspec_dir = File.join @tempdir, 'gemspec_dir' + gemspec_dir = File.join @tempdir, "gemspec_dir" gemspec_file = File.join gemspec_dir, @gem.spec_name - gemcode_dir = File.join @tempdir, 'build_command_gem' - readme_file = File.join gemcode_dir, 'README.md' + gemcode_dir = File.join @tempdir, "build_command_gem" + readme_file = File.join gemcode_dir, "README.md" FileUtils.mkdir_p gemspec_dir FileUtils.mkdir_p gemcode_dir - File.open readme_file, 'w' do |f| + File.open readme_file, "w" do |f| f.write "My awesome gem in nested directory" end - File.open gemspec_file, 'w' do |gs| + File.open gemspec_file, "w" do |gs| gs.write @gem.to_ruby end @@ -467,7 +481,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase def test_can_find_gemspecs_without_dot_gemspec gemspec_file = File.join(@tempdir, @gem.name) - File.open gemspec_file + ".gemspec", 'w' do |gs| + File.open gemspec_file + ".gemspec", "w" do |gs| gs.write @gem.to_ruby end @@ -571,7 +585,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase @gem.send :remove_instance_variable, :@rubygems_version - File.open gemspec_file, 'w' do |gs| + File.open gemspec_file, "w" do |gs| gs.write @gem.to_ruby end @@ -582,18 +596,18 @@ class TestGemCommandsBuildCommand < Gem::TestCase end def test_build_signed_gem - skip 'openssl is missing' unless Gem::HAVE_OPENSSL && !java_platform? + pend "openssl is missing" unless Gem::HAVE_OPENSSL && !Gem.java_platform? trust_dir = Gem::Security.trust_dir - spec = util_spec 'some_gem' do |s| + spec = util_spec "some_gem" do |s| s.signing_key = SIGNING_KEY s.cert_chain = [CERT_FILE] end gemspec_file = File.join(@tempdir, spec.spec_name) - File.open gemspec_file, 'w' do |gs| + File.open gemspec_file, "w" do |gs| gs.write spec.to_ruby end @@ -609,7 +623,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase end def test_build_signed_gem_with_cert_expiration_length_days - skip 'openssl is missing' unless Gem::HAVE_OPENSSL && !java_platform? + pend "openssl is missing" unless Gem::HAVE_OPENSSL && !Gem.java_platform? gem_path = File.join Gem.user_home, ".gem" Dir.mkdir gem_path @@ -622,14 +636,14 @@ class TestGemCommandsBuildCommand < Gem::TestCase tmp_private_key_file = File.join gem_path, "gem-private_key.pem" File.write(tmp_private_key_file, File.read(PRIVATE_KEY_FILE)) - spec = util_spec 'some_gem' do |s| + spec = util_spec "some_gem" do |s| s.signing_key = tmp_private_key_file s.cert_chain = [tmp_expired_cert_file] end gemspec_file = File.join(@tempdir, spec.spec_name) - File.open gemspec_file, 'w' do |gs| + File.open gemspec_file, "w" do |gs| gs.write spec.to_ruby end @@ -653,7 +667,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase end def test_build_auto_resign_cert - skip 'openssl is missing' unless Gem::HAVE_OPENSSL && !java_platform? + pend "openssl is missing" unless Gem::HAVE_OPENSSL && !Gem.java_platform? gem_path = File.join Gem.user_home, ".gem" Dir.mkdir gem_path @@ -666,14 +680,14 @@ class TestGemCommandsBuildCommand < Gem::TestCase tmp_private_key_file = File.join gem_path, "gem-private_key.pem" File.write(tmp_private_key_file, File.read(PRIVATE_KEY_FILE)) - spec = util_spec 'some_gem' do |s| + spec = util_spec "some_gem" do |s| s.signing_key = tmp_private_key_file s.cert_chain = [tmp_expired_cert_file] end gemspec_file = File.join(@tempdir, spec.spec_name) - File.open gemspec_file, 'w' do |gs| + File.open gemspec_file, "w" do |gs| gs.write spec.to_ruby end @@ -689,7 +703,7 @@ class TestGemCommandsBuildCommand < Gem::TestCase output = @ui.output.split "\n" assert_equal "INFO: Your certificate has expired, trying to re-sign it...", output.shift - assert_equal "INFO: Your cert: #{tmp_expired_cert_file } has been auto re-signed with the key: #{tmp_private_key_file}", output.shift + assert_equal "INFO: Your cert: #{tmp_expired_cert_file} has been auto re-signed with the key: #{tmp_private_key_file}", output.shift assert_match(/INFO: Your expired cert will be located at: .+\Wgem-public_cert\.pem\.expired\.[0-9]+/, output.shift) end diff --git a/test/rubygems/test_gem_commands_cert_command.rb b/test/rubygems/test_gem_commands_cert_command.rb index e8b6e506f5..c173467935 100644 --- a/test/rubygems/test_gem_commands_cert_command.rb +++ b/test/rubygems/test_gem_commands_cert_command.rb @@ -1,27 +1,29 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/cert_command' + +require_relative "helper" +require "rubygems/commands/cert_command" unless Gem::HAVE_OPENSSL - warn 'Skipping `gem cert` tests. openssl not found.' + warn "Skipping `gem cert` tests. openssl not found." end if Gem.java_platform? - warn 'Skipping `gem cert` tests on jruby.' + warn "Skipping `gem cert` tests on jruby." end class TestGemCommandsCertCommand < Gem::TestCase - ALTERNATE_CERT = load_cert 'alternate' - EXPIRED_PUBLIC_CERT = load_cert 'expired' + ALTERNATE_CERT = load_cert "alternate" + EXPIRED_PUBLIC_CERT = load_cert "expired" - ALTERNATE_KEY_FILE = key_path 'alternate' - PRIVATE_KEY_FILE = key_path 'private' - PUBLIC_KEY_FILE = key_path 'public' + ALTERNATE_KEY_FILE = key_path "alternate" + PRIVATE_KEY_FILE = key_path "private" + PRIVATE_EC_KEY_FILE = key_path "private_ec" + PUBLIC_KEY_FILE = key_path "public" - ALTERNATE_CERT_FILE = cert_path 'alternate' - CHILD_CERT_FILE = cert_path 'child' - PUBLIC_CERT_FILE = cert_path 'public' - EXPIRED_PUBLIC_CERT_FILE = cert_path 'expired' + ALTERNATE_CERT_FILE = cert_path "alternate" + CHILD_CERT_FILE = cert_path "child" + PUBLIC_CERT_FILE = cert_path "public" + EXPIRED_PUBLIC_CERT_FILE = cert_path "expired" def setup super @@ -43,9 +45,9 @@ class TestGemCommandsCertCommand < Gem::TestCase @trust_dir.trust_cert PUBLIC_CERT @trust_dir.trust_cert ALTERNATE_CERT - matches = @cmd.certificates_matching '' + matches = @cmd.certificates_matching "" - # HACK OpenSSL::X509::Certificate#== is Object#==, so do this the hard way + # 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 @@ -63,7 +65,7 @@ class TestGemCommandsCertCommand < Gem::TestCase @trust_dir.trust_cert PUBLIC_CERT @trust_dir.trust_cert ALTERNATE_CERT - matches = @cmd.certificates_matching 'alternate' + matches = @cmd.certificates_matching "alternate" match = matches.next assert_equal ALTERNATE_CERT.to_pem, match.first.to_pem @@ -90,7 +92,7 @@ class TestGemCommandsCertCommand < Gem::TestCase end def test_execute_add_twice - self.class.cert_path 'alternate' + self.class.cert_path "alternate" @cmd.handle_options %W[ --add #{PUBLIC_CERT_FILE} @@ -111,7 +113,7 @@ Added '/CN=alternate/DC=example' end def test_execute_build - passphrase = 'Foo bar' + passphrase = "Foo bar" @cmd.handle_options %W[--build nobody@example.com] @@ -127,9 +129,9 @@ Added '/CN=alternate/DC=example' output.shift assert_equal "Please repeat the passphrase for your Private Key: ", output.shift - assert_equal "Certificate: #{File.join @tempdir, 'gem-public_cert.pem'}", + assert_equal "Certificate: #{File.join @tempdir, "gem-public_cert.pem"}", output.shift - assert_equal "Private Key: #{File.join @tempdir, 'gem-private_key.pem'}", + 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!", @@ -138,12 +140,48 @@ Added '/CN=alternate/DC=example' assert_empty output assert_empty @build_ui.error - assert_path_exist File.join(@tempdir, 'gem-private_key.pem') - assert_path_exist File.join(@tempdir, 'gem-public_cert.pem') + assert_path_exist File.join(@tempdir, "gem-private_key.pem") + assert_path_exist File.join(@tempdir, "gem-public_cert.pem") + end + + def test_execute_build_key_algorithm_ec_key + passphrase = "Foo bar" + + @cmd.handle_options %W[--build nobody@example.com --key-algorithm ec] + + @build_ui = Gem::MockGemUi.new "#{passphrase}\n#{passphrase}" + + use_ui @build_ui do + @cmd.execute + end + + output = @build_ui.output.squeeze("\n").split "\n" + + assert_equal "Passphrase for your Private Key: ", + output.shift + assert_equal "Please repeat the passphrase for your Private Key: ", + output.shift + assert_equal "Certificate: #{File.join @tempdir, "gem-public_cert.pem"}", + output.shift + assert_equal "Private Key: #{File.join @tempdir, "gem-private_key.pem"}", + output.shift + + assert_equal "Don't forget to move the key file to somewhere private!", + output.shift + + assert_empty output + assert_empty @build_ui.error + + assert_path_exist File.join(@tempdir, "gem-private_key.pem") + + cert_path = File.join(@tempdir, "gem-public_cert.pem") + assert_path_exist cert_path + cert = OpenSSL::X509::Certificate.new(File.read(cert_path)) + assert cert.public_key.is_a? OpenSSL::PKey::EC end def test_execute_build_bad_email_address - passphrase = 'Foo bar' + passphrase = "Foo bar" email = "nobody@" @cmd.handle_options %W[--build #{email}] @@ -151,7 +189,6 @@ Added '/CN=alternate/DC=example' @build_ui = Gem::MockGemUi.new "#{passphrase}\n#{passphrase}" use_ui @build_ui do - e = assert_raise Gem::CommandLineError do @cmd.execute end @@ -159,13 +196,13 @@ Added '/CN=alternate/DC=example' assert_equal "Invalid email address #{email}", e.message - assert_path_not_exist File.join(@tempdir, 'gem-private_key.pem') - assert_path_not_exist File.join(@tempdir, 'gem-public_cert.pem') + assert_path_not_exist File.join(@tempdir, "gem-private_key.pem") + assert_path_not_exist File.join(@tempdir, "gem-public_cert.pem") end end def test_execute_build_expiration_days - passphrase = 'Foo bar' + passphrase = "Foo bar" @cmd.handle_options %W[ --build nobody@example.com @@ -184,9 +221,9 @@ Added '/CN=alternate/DC=example' output.shift assert_equal "Please repeat the passphrase for your Private Key: ", output.shift - assert_equal "Certificate: #{File.join @tempdir, 'gem-public_cert.pem'}", + assert_equal "Certificate: #{File.join @tempdir, "gem-public_cert.pem"}", output.shift - assert_equal "Private Key: #{File.join @tempdir, 'gem-private_key.pem'}", + 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!", @@ -195,8 +232,8 @@ Added '/CN=alternate/DC=example' assert_empty output assert_empty @build_ui.error - assert_path_exist File.join(@tempdir, 'gem-private_key.pem') - assert_path_exist File.join(@tempdir, 'gem-public_cert.pem') + assert_path_exist File.join(@tempdir, "gem-private_key.pem") + assert_path_exist File.join(@tempdir, "gem-public_cert.pem") pem = File.read("#{@tempdir}/gem-public_cert.pem") cert = OpenSSL::X509::Certificate.new(pem) @@ -206,8 +243,8 @@ Added '/CN=alternate/DC=example' end def test_execute_build_bad_passphrase_confirmation - passphrase = 'Foo bar' - passphrase_confirmation = 'Fu bar' + passphrase = "Foo bar" + passphrase_confirmation = "Fu bar" @cmd.handle_options %W[--build nobody@example.com] @@ -229,11 +266,10 @@ Added '/CN=alternate/DC=example' assert_equal "Passphrase and passphrase confirmation don't match", e.message - end - assert_path_not_exist File.join(@tempdir, 'gem-private_key.pem') - assert_path_not_exist File.join(@tempdir, 'gem-public_cert.pem') + assert_path_not_exist File.join(@tempdir, "gem-private_key.pem") + assert_path_not_exist File.join(@tempdir, "gem-public_cert.pem") end def test_execute_build_key @@ -248,14 +284,14 @@ Added '/CN=alternate/DC=example' output = @ui.output.split "\n" - assert_equal "Certificate: #{File.join @tempdir, 'gem-public_cert.pem'}", + assert_equal "Certificate: #{File.join @tempdir, "gem-public_cert.pem"}", output.shift assert_empty output assert_empty @ui.error - assert_path_exist File.join(@tempdir, 'gem-public_cert.pem') - assert_path_not_exist File.join(@tempdir, 'gem-private_key.pem') + assert_path_exist File.join(@tempdir, "gem-public_cert.pem") + assert_path_not_exist File.join(@tempdir, "gem-private_key.pem") end def test_execute_build_encrypted_key @@ -270,13 +306,35 @@ Added '/CN=alternate/DC=example' output = @ui.output.split "\n" - assert_equal "Certificate: #{File.join @tempdir, 'gem-public_cert.pem'}", + assert_equal "Certificate: #{File.join @tempdir, "gem-public_cert.pem"}", + output.shift + + assert_empty output + assert_empty @ui.error + + assert_path_exist File.join(@tempdir, "gem-public_cert.pem") + end + + def test_execute_build_ec_key + @cmd.handle_options %W[ + --build nobody@example.com + --private-key #{PRIVATE_EC_KEY_FILE} + ] + + use_ui @ui do + @cmd.execute + end + + output = @ui.output.split "\n" + + assert_equal "Certificate: #{File.join @tempdir, "gem-public_cert.pem"}", output.shift assert_empty output assert_empty @ui.error - assert_path_exist File.join(@tempdir, 'gem-public_cert.pem') + assert_path_exist File.join(@tempdir, "gem-public_cert.pem") + assert_path_not_exist File.join(@tempdir, "gem-private_key.pem") end def test_execute_certificate @@ -284,8 +342,8 @@ Added '/CN=alternate/DC=example' @cmd.handle_options %W[--certificate #{PUBLIC_CERT_FILE}] end - assert_equal '', @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.output + assert_equal "", @ui.error assert_equal PUBLIC_CERT.to_pem, @cmd.options[:issuer_cert].to_pem end @@ -324,8 +382,8 @@ Added '/CN=alternate/DC=example' @cmd.send :handle_options, %W[--private-key #{PRIVATE_KEY_FILE}] end - assert_equal '', @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.output + assert_equal "", @ui.error assert_equal PRIVATE_KEY.to_pem, @cmd.options[:key].to_pem end @@ -335,8 +393,8 @@ Added '/CN=alternate/DC=example' @cmd.send :handle_options, %W[--private-key #{ENCRYPTED_PRIVATE_KEY_PATH}] end - assert_equal '', @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.output + assert_equal "", @ui.error assert_equal ENCRYPTED_PRIVATE_KEY.to_pem, @cmd.options[:key].to_pem end @@ -355,7 +413,7 @@ Added '/CN=alternate/DC=example' end assert_equal "Removed '/CN=nobody/DC=example'\n", @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error assert_path_not_exist cert_path end @@ -382,7 +440,7 @@ Removed '/CN=nobody/DC=example' EXPECTED assert_equal expected, @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error assert_path_not_exist public_path assert_path_not_exist alternate_path @@ -410,17 +468,17 @@ Removed '/CN=alternate/DC=example' EXPECTED assert_equal expected, @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error assert_path_not_exist public_path assert_path_not_exist alternate_path end def test_execute_sign - path = File.join @tempdir, 'cert.pem' - Gem::Security.write ALTERNATE_CERT, path, 0600 + path = File.join @tempdir, "cert.pem" + Gem::Security.write ALTERNATE_CERT, path, 0o600 - assert_equal '/CN=alternate/DC=example', ALTERNATE_CERT.issuer.to_s + assert_equal "/CN=alternate/DC=example", ALTERNATE_CERT.issuer.to_s @cmd.handle_options %W[ --private-key #{PRIVATE_KEY_FILE} @@ -433,23 +491,23 @@ Removed '/CN=alternate/DC=example' @cmd.execute end - assert_equal '', @ui.output - assert_equal '', @ui.error + 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 + assert_equal "/CN=nobody/DC=example", cert.issuer.to_s - mask = 0100600 & (~File.umask) + mask = 0o100600 & (~File.umask) - assert_equal mask, File.stat(path).mode unless win_platform? + assert_equal mask, File.stat(path).mode unless Gem.win_platform? end def test_execute_sign_encrypted_key - path = File.join @tempdir, 'cert.pem' - Gem::Security.write ALTERNATE_CERT, path, 0600 + path = File.join @tempdir, "cert.pem" + Gem::Security.write ALTERNATE_CERT, path, 0o600 - assert_equal '/CN=alternate/DC=example', ALTERNATE_CERT.issuer.to_s + assert_equal "/CN=alternate/DC=example", ALTERNATE_CERT.issuer.to_s @cmd.handle_options %W[ --private-key #{ENCRYPTED_PRIVATE_KEY_PATH} @@ -462,31 +520,31 @@ Removed '/CN=alternate/DC=example' @cmd.execute end - assert_equal '', @ui.output - assert_equal '', @ui.error + 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 + assert_equal "/CN=nobody/DC=example", cert.issuer.to_s - mask = 0100600 & (~File.umask) + mask = 0o100600 & (~File.umask) - assert_equal mask, File.stat(path).mode unless win_platform? + assert_equal mask, File.stat(path).mode unless Gem.win_platform? end def test_execute_sign_default - FileUtils.mkdir_p File.join Gem.user_home, '.gem' + FileUtils.mkdir_p File.join Gem.user_home, ".gem" - private_key_path = File.join Gem.user_home, '.gem', 'gem-private_key.pem' + private_key_path = File.join Gem.user_home, ".gem", "gem-private_key.pem" Gem::Security.write PRIVATE_KEY, private_key_path - public_cert_path = File.join Gem.user_home, '.gem', 'gem-public_cert.pem' + public_cert_path = File.join Gem.user_home, ".gem", "gem-public_cert.pem" Gem::Security.write PUBLIC_CERT, public_cert_path - path = File.join @tempdir, 'cert.pem' - Gem::Security.write ALTERNATE_CERT, path, 0600 + path = File.join @tempdir, "cert.pem" + Gem::Security.write ALTERNATE_CERT, path, 0o600 - assert_equal '/CN=alternate/DC=example', ALTERNATE_CERT.issuer.to_s + assert_equal "/CN=alternate/DC=example", ALTERNATE_CERT.issuer.to_s @cmd.handle_options %W[--sign #{path}] @@ -494,31 +552,31 @@ Removed '/CN=alternate/DC=example' @cmd.execute end - assert_equal '', @ui.output - assert_equal '', @ui.error + 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 + assert_equal "/CN=nobody/DC=example", cert.issuer.to_s - mask = 0100600 & (~File.umask) + mask = 0o100600 & (~File.umask) - assert_equal mask, File.stat(path).mode unless win_platform? + assert_equal mask, File.stat(path).mode unless Gem.win_platform? end def test_execute_sign_default_encrypted_key - FileUtils.mkdir_p File.join(Gem.user_home, '.gem') + FileUtils.mkdir_p File.join(Gem.user_home, ".gem") - private_key_path = File.join Gem.user_home, '.gem', 'gem-private_key.pem' - Gem::Security.write ENCRYPTED_PRIVATE_KEY, private_key_path, 0600, PRIVATE_KEY_PASSPHRASE + private_key_path = File.join Gem.user_home, ".gem", "gem-private_key.pem" + Gem::Security.write ENCRYPTED_PRIVATE_KEY, private_key_path, 0o600, PRIVATE_KEY_PASSPHRASE - public_cert_path = File.join Gem.user_home, '.gem', 'gem-public_cert.pem' + public_cert_path = File.join Gem.user_home, ".gem", "gem-public_cert.pem" Gem::Security.write PUBLIC_CERT, public_cert_path - path = File.join @tempdir, 'cert.pem' - Gem::Security.write ALTERNATE_CERT, path, 0600 + path = File.join @tempdir, "cert.pem" + Gem::Security.write ALTERNATE_CERT, path, 0o600 - assert_equal '/CN=alternate/DC=example', ALTERNATE_CERT.issuer.to_s + assert_equal "/CN=alternate/DC=example", ALTERNATE_CERT.issuer.to_s @cmd.handle_options %W[--sign #{path}] @@ -526,28 +584,28 @@ Removed '/CN=alternate/DC=example' @cmd.execute end - assert_equal '', @ui.output - assert_equal '', @ui.error + 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 + assert_equal "/CN=nobody/DC=example", cert.issuer.to_s - mask = 0100600 & (~File.umask) + mask = 0o100600 & (~File.umask) - assert_equal mask, File.stat(path).mode unless win_platform? + assert_equal mask, File.stat(path).mode unless Gem.win_platform? end def test_execute_sign_no_cert - FileUtils.mkdir_p File.join Gem.user_home, '.gem' + FileUtils.mkdir_p File.join Gem.user_home, ".gem" - private_key_path = File.join Gem.user_home, '.gem', 'gem-private_key.pem' + private_key_path = File.join Gem.user_home, ".gem", "gem-private_key.pem" Gem::Security.write PRIVATE_KEY, private_key_path - path = File.join @tempdir, 'cert.pem' - Gem::Security.write ALTERNATE_CERT, path, 0600 + path = File.join @tempdir, "cert.pem" + Gem::Security.write ALTERNATE_CERT, path, 0o600 - assert_equal '/CN=alternate/DC=example', ALTERNATE_CERT.issuer.to_s + assert_equal "/CN=alternate/DC=example", ALTERNATE_CERT.issuer.to_s @cmd.handle_options %W[--sign #{path}] @@ -557,7 +615,7 @@ Removed '/CN=alternate/DC=example' end end - assert_equal '', @ui.output + assert_equal "", @ui.output expected = <<-EXPECTED ERROR: --certificate not specified and ~/.gem/gem-public_cert.pem does not exist @@ -567,15 +625,15 @@ ERROR: --certificate not specified and ~/.gem/gem-public_cert.pem does not exis end def test_execute_sign_no_key - FileUtils.mkdir_p File.join Gem.user_home, '.gem' + FileUtils.mkdir_p File.join Gem.user_home, ".gem" - public_cert_path = File.join Gem.user_home, '.gem', 'gem-public_cert.pem' + public_cert_path = File.join Gem.user_home, ".gem", "gem-public_cert.pem" Gem::Security.write PUBLIC_CERT, public_cert_path - path = File.join @tempdir, 'cert.pem' - Gem::Security.write ALTERNATE_CERT, path, 0600 + path = File.join @tempdir, "cert.pem" + Gem::Security.write ALTERNATE_CERT, path, 0o600 - assert_equal '/CN=alternate/DC=example', ALTERNATE_CERT.issuer.to_s + assert_equal "/CN=alternate/DC=example", ALTERNATE_CERT.issuer.to_s @cmd.handle_options %W[--sign #{path}] @@ -585,7 +643,7 @@ ERROR: --certificate not specified and ~/.gem/gem-public_cert.pem does not exis end end - assert_equal '', @ui.output + assert_equal "", @ui.output expected = <<-EXPECTED ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exist @@ -598,10 +656,10 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis gem_path = File.join Gem.user_home, ".gem" Dir.mkdir gem_path - path = File.join @tempdir, 'cert.pem' - Gem::Security.write EXPIRED_PUBLIC_CERT, path, 0600 + path = File.join @tempdir, "cert.pem" + Gem::Security.write EXPIRED_PUBLIC_CERT, path, 0o600 - assert_equal '/CN=nobody/DC=example', EXPIRED_PUBLIC_CERT.issuer.to_s + assert_equal "/CN=nobody/DC=example", EXPIRED_PUBLIC_CERT.issuer.to_s tmp_expired_cert_file = File.join(Dir.tmpdir, File.basename(EXPIRED_PUBLIC_CERT_FILE)) @cleanup << tmp_expired_cert_file @@ -619,21 +677,22 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis expected_path = File.join(gem_path, "#{File.basename(tmp_expired_cert_file)}.expired") + assert_include(@ui.output, "INFO: Your certificate #{tmp_expired_cert_file} has been re-signed\n") assert_match( - /INFO: Your certificate #{tmp_expired_cert_file} has been re-signed\nINFO: Your expired certificate will be located at: #{expected_path}\.[0-9]+/, + /INFO: Your expired certificate will be located at: #{Regexp.quote(expected_path)}\.[0-9]+/, @ui.output ) - assert_equal '', @ui.error + assert_equal "", @ui.error end def test_execute_re_sign_with_cert_expiration_length_days gem_path = File.join Gem.user_home, ".gem" Dir.mkdir gem_path - path = File.join @tempdir, 'cert.pem' - Gem::Security.write EXPIRED_PUBLIC_CERT, path, 0600 + path = File.join @tempdir, "cert.pem" + Gem::Security.write EXPIRED_PUBLIC_CERT, path, 0o600 - assert_equal '/CN=nobody/DC=example', EXPIRED_PUBLIC_CERT.issuer.to_s + assert_equal "/CN=nobody/DC=example", EXPIRED_PUBLIC_CERT.issuer.to_s tmp_expired_cert_file = File.join(Dir.tmpdir, File.basename(EXPIRED_PUBLIC_CERT_FILE)) @cleanup << tmp_expired_cert_file @@ -655,7 +714,7 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis cert_days_to_expire = (re_signed_cert.not_after - re_signed_cert.not_before).to_i / (24 * 60 * 60) assert_equal(28, cert_days_to_expire) - assert_equal '', @ui.error + assert_equal "", @ui.error end def test_handle_options @@ -674,29 +733,29 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis ] assert_equal [PUBLIC_CERT.to_pem, ALTERNATE_CERT.to_pem], - @cmd.options[:add].map {|cert| cert.to_pem } + @cmd.options[:add].map(&: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 } + @cmd.options[:build].map(&:to_s) - assert_equal ['', 'example'], @cmd.options[:list] + assert_equal ["", "example"], @cmd.options[:list] end def test_handle_options_add_bad - nonexistent = File.join @tempdir, 'nonexistent' - e = assert_raise OptionParser::InvalidArgument do + nonexistent = File.join @tempdir, "nonexistent" + e = assert_raise Gem::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' + bad = File.join @tempdir, "bad" FileUtils.touch bad - e = assert_raise OptionParser::InvalidArgument do + e = assert_raise Gem::OptionParser::InvalidArgument do @cmd.handle_options %W[--add #{bad}] end @@ -705,51 +764,51 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis end def test_handle_options_certificate - nonexistent = File.join @tempdir, 'nonexistent' - e = assert_raise OptionParser::InvalidArgument do + nonexistent = File.join @tempdir, "nonexistent" + e = assert_raise Gem::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' + bad = File.join @tempdir, "bad" FileUtils.touch bad - e = assert_raise OptionParser::InvalidArgument do + e = assert_raise Gem::OptionParser::InvalidArgument do @cmd.handle_options %W[--certificate #{bad}] end - assert_equal "invalid argument: " + + 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_raise OptionParser::InvalidArgument do + nonexistent = File.join @tempdir, "nonexistent" + e = assert_raise Gem::OptionParser::InvalidArgument do @cmd.handle_options %W[--private-key #{nonexistent}] end - assert_equal "invalid argument: " + + assert_equal "invalid argument: " \ "--private-key #{nonexistent}: does not exist", e.message - bad = File.join @tempdir, 'bad' + bad = File.join @tempdir, "bad" FileUtils.touch bad - e = assert_raise OptionParser::InvalidArgument do + e = assert_raise Gem::OptionParser::InvalidArgument do @cmd.handle_options %W[--private-key #{bad}] end - assert_equal "invalid argument: --private-key #{bad}: invalid RSA key", + assert_equal "invalid argument: --private-key #{bad}: invalid RSA, DSA, or EC key", e.message - e = assert_raise OptionParser::InvalidArgument do + e = assert_raise Gem::OptionParser::InvalidArgument do @cmd.handle_options %W[--private-key #{PUBLIC_KEY_FILE}] end - assert_equal "invalid argument: " + + assert_equal "invalid argument: " \ "--private-key #{PUBLIC_KEY_FILE}: private key not found", e.message end @@ -791,8 +850,8 @@ ERROR: --private-key not specified and ~/.gem/gem-private_key.pem does not exis end def test_handle_options_sign_nonexistent - nonexistent = File.join @tempdir, 'nonexistent' - e = assert_raise OptionParser::InvalidArgument do + nonexistent = File.join @tempdir, "nonexistent" + e = assert_raise Gem::OptionParser::InvalidArgument do @cmd.handle_options %W[ --private-key #{ALTERNATE_KEY_FILE} diff --git a/test/rubygems/test_gem_commands_check_command.rb b/test/rubygems/test_gem_commands_check_command.rb index 07eea188e3..65a3093b13 100644 --- a/test/rubygems/test_gem_commands_check_command.rb +++ b/test/rubygems/test_gem_commands_check_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/check_command' + +require_relative "helper" +require "rubygems/commands/check_command" class TestGemCommandsCheckCommand < Gem::TestCase def setup @@ -45,8 +46,8 @@ class TestGemCommandsCheckCommand < Gem::TestCase end def test_doctor - gem 'a' - b = gem 'b' + gem "a" + b = gem "b" FileUtils.rm b.spec_file diff --git a/test/rubygems/test_gem_commands_cleanup_command.rb b/test/rubygems/test_gem_commands_cleanup_command.rb index 6e21e8c68b..bcb8871b57 100644 --- a/test/rubygems/test_gem_commands_cleanup_command.rb +++ b/test/rubygems/test_gem_commands_cleanup_command.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/cleanup_command' -require 'rubygems/installer' + +require_relative "helper" +require "rubygems/commands/cleanup_command" +require "rubygems/installer" class TestGemCommandsCleanupCommand < Gem::TestCase def setup @@ -9,8 +10,8 @@ class TestGemCommandsCleanupCommand < Gem::TestCase @cmd = Gem::Commands::CleanupCommand.new - @a_1 = util_spec 'a', 1 - @a_2 = util_spec 'a', 2 + @a_1 = util_spec "a", 1 + @a_2 = util_spec "a", 2 install_gem @a_1 install_gem @a_2 @@ -66,12 +67,12 @@ class TestGemCommandsCleanupCommand < Gem::TestCase end def test_execute_all_dependencies - @b_1 = util_spec 'b', 1 do |s| - s.add_dependency 'a', '1' + @b_1 = util_spec "b", 1 do |s| + s.add_dependency "a", "1" end - @b_2 = util_spec 'b', 2 do |s| - s.add_dependency 'a', '2' + @b_2 = util_spec "b", 2 do |s| + s.add_dependency "a", "2" end install_gem @b_1 @@ -86,12 +87,12 @@ class TestGemCommandsCleanupCommand < Gem::TestCase end def test_execute_dev_dependencies - @b_1 = util_spec 'b', 1 do |s| - s.add_development_dependency 'a', '1' + @b_1 = util_spec "b", 1 do |s| + s.add_development_dependency "a", "1" end - @c_1 = util_spec 'c', 1 do |s| - s.add_development_dependency 'a', '2' + @c_1 = util_spec "c", 1 do |s| + s.add_development_dependency "a", "2" end install_gem @b_1 @@ -105,12 +106,12 @@ class TestGemCommandsCleanupCommand < Gem::TestCase end def test_execute_without_dev_dependencies - @b_1 = util_spec 'b', 1 do |s| - s.add_development_dependency 'a', '1' + @b_1 = util_spec "b", 1 do |s| + s.add_development_dependency "a", "1" end - @c_1 = util_spec 'c', 1 do |s| - s.add_development_dependency 'a', '2' + @c_1 = util_spec "c", 1 do |s| + s.add_development_dependency "a", "2" end install_gem @b_1 @@ -124,14 +125,14 @@ class TestGemCommandsCleanupCommand < Gem::TestCase end def test_execute_all - gemhome2 = File.join @tempdir, 'gemhome2' + gemhome2 = File.join @tempdir, "gemhome2" Gem.ensure_gem_subdirectories gemhome2 Gem.use_paths @gemhome, gemhome2 - @b_1 = util_spec 'b', 1 - @b_2 = util_spec 'b', 2 + @b_1 = util_spec "b", 1 + @b_2 = util_spec "b", 2 install_gem @b_1 install_gem @b_2 @@ -140,15 +141,15 @@ class TestGemCommandsCleanupCommand < Gem::TestCase @cmd.execute - assert_equal @gemhome, Gem.dir, 'GEM_HOME' - assert_equal [@gemhome, gemhome2], Gem.path.sort, 'GEM_PATH' + assert_equal @gemhome, Gem.dir, "GEM_HOME" + assert_equal [@gemhome, gemhome2], Gem.path.sort, "GEM_PATH" assert_path_not_exist @a_1.gem_dir assert_path_not_exist @b_1.gem_dir end def test_execute_all_user - @a_1_1, = util_gem 'a', '1.1' + @a_1_1, = util_gem "a", "1.1" @a_1_1 = install_gem @a_1_1 # pick up user install path Gem::Specification.dirs = [Gem.dir, Gem.user_dir] @@ -165,10 +166,10 @@ class TestGemCommandsCleanupCommand < Gem::TestCase end def test_execute_all_user_no_sudo - FileUtils.chmod 0555, @gemhome + FileUtils.chmod 0o555, @gemhome - @a_1_1, = util_gem 'a', '1.1' - @a_1_1 = install_gem @a_1_1, :user_install => true # pick up user install path + @a_1_1, = util_gem "a", "1.1" + @a_1_1 = install_gem @a_1_1, user_install: true # pick up user install path Gem::Specification.dirs = [Gem.dir, Gem.user_dir] @@ -182,8 +183,8 @@ class TestGemCommandsCleanupCommand < Gem::TestCase assert_path_exist @a_1.gem_dir assert_path_exist @a_1_1.gem_dir ensure - FileUtils.chmod 0755, @gemhome - end unless win_platform? || Process.uid.zero? + FileUtils.chmod 0o755, @gemhome + end unless Gem.win_platform? || Process.uid.zero? def test_execute_dry_run @cmd.options[:args] = %w[a] @@ -195,11 +196,11 @@ class TestGemCommandsCleanupCommand < Gem::TestCase end def test_execute_keeps_older_versions_with_deps - @b_1 = util_spec 'b', 1 - @b_2 = util_spec 'b', 2 + @b_1 = util_spec "b", 1 + @b_2 = util_spec "b", 2 - @c = util_spec 'c', 1 do |s| - s.add_dependency 'b', '1' + @c = util_spec "c", 1 do |s| + s.add_dependency "b", "1" end install_gem @b_1 @@ -216,9 +217,9 @@ class TestGemCommandsCleanupCommand < Gem::TestCase def test_execute_ignore_default_gem_verbose Gem.configuration.verbose = :really - @b_1 = util_spec 'b', 1 + @b_1 = util_spec "b", 1 @b_default = new_default_spec "b", "2" - @b_2 = util_spec 'b', 3 + @b_2 = util_spec "b", 3 install_gem @b_1 install_default_gems @b_default @@ -230,23 +231,23 @@ class TestGemCommandsCleanupCommand < Gem::TestCase @cmd.execute end - assert_match %r{^Skipped default gems: b-2}, @ui.output + assert_match(/^Skipped default gems: b-2/, @ui.output) assert_empty @ui.error end def test_execute_remove_gem_home_only - c_1, = util_gem 'c', '1' - c_2, = util_gem 'c', '2' - d_1, = util_gem 'd', '1' - d_2, = util_gem 'd', '2' - e_1, = util_gem 'e', '1' - e_2, = util_gem 'e', '2' - - c_1 = install_gem c_1, :user_install => true # pick up user install path + c_1, = util_gem "c", "1" + c_2, = util_gem "c", "2" + d_1, = util_gem "d", "1" + d_2, = util_gem "d", "2" + e_1, = util_gem "e", "1" + e_2, = util_gem "e", "2" + + c_1 = install_gem c_1, user_install: true # pick up user install path c_2 = install_gem c_2 d_1 = install_gem d_1 - d_2 = install_gem d_2, :user_install => true # pick up user install path + d_2 = install_gem d_2, user_install: true # pick up user install path e_1 = install_gem e_1 e_2 = install_gem e_2 @@ -263,14 +264,14 @@ class TestGemCommandsCleanupCommand < Gem::TestCase end def test_execute_user_install - c_1, = util_gem 'c', '1.0' - c_2, = util_gem 'c', '1.1' + c_1, = util_gem "c", "1.0" + c_2, = util_gem "c", "1.1" - d_1, = util_gem 'd', '1.0' - d_2, = util_gem 'd', '1.1' + d_1, = util_gem "d", "1.0" + d_2, = util_gem "d", "1.1" - c_1 = install_gem c_1, :user_install => true # pick up user install path - c_2 = install_gem c_2, :user_install => true # pick up user install path + c_1 = install_gem c_1, user_install: true # pick up user install path + c_2 = install_gem c_2, user_install: true # pick up user install path d_1 = install_gem d_1 d_2 = install_gem d_2 diff --git a/test/rubygems/test_gem_commands_contents_command.rb b/test/rubygems/test_gem_commands_contents_command.rb index 2b04a9c654..d8e6ba3dec 100644 --- a/test/rubygems/test_gem_commands_contents_command.rb +++ b/test/rubygems/test_gem_commands_contents_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/contents_command' + +require_relative "helper" +require "rubygems/commands/contents_command" class TestGemCommandsContentsCommand < Gem::TestCase def setup @@ -20,22 +21,22 @@ class TestGemCommandsContentsCommand < Gem::TestCase def test_execute @cmd.options[:args] = %w[foo] - gem 'foo' + gem "foo" use_ui @ui do @cmd.execute end assert_match %r{lib/foo\.rb}, @ui.output - assert_match %r{Rakefile}, @ui.output + assert_match(/Rakefile/, @ui.output) assert_equal "", @ui.error end def test_execute_all @cmd.options[:all] = true - gem 'foo' - gem 'bar' + gem "foo" + gem "bar" use_ui @ui do @cmd.execute @@ -43,7 +44,7 @@ class TestGemCommandsContentsCommand < Gem::TestCase assert_match %r{lib/foo\.rb}, @ui.output assert_match %r{lib/bar\.rb}, @ui.output - assert_match %r{Rakefile}, @ui.output + assert_match(/Rakefile/, @ui.output) assert_equal "", @ui.error end @@ -56,22 +57,22 @@ class TestGemCommandsContentsCommand < Gem::TestCase end end - assert_match %r{Unable to find gem 'foo' in default gem paths}, @ui.output - assert_match %r{Directories searched:}, @ui.output + assert_match(/Unable to find gem 'foo' in default gem paths/, @ui.output) + assert_match(/Directories searched:/, @ui.output) assert_equal "", @ui.error end def test_execute_exact_match @cmd.options[:args] = %w[foo] - gem 'foo' - gem 'bar' + gem "foo" + gem "bar" use_ui @ui do @cmd.execute end assert_match %r{lib/foo\.rb}, @ui.output - assert_match %r{Rakefile}, @ui.output + assert_match(/Rakefile/, @ui.output) assert_equal "", @ui.error end @@ -79,14 +80,14 @@ class TestGemCommandsContentsCommand < Gem::TestCase @cmd.options[:args] = %w[foo] @cmd.options[:lib_only] = true - gem 'foo' + gem "foo" use_ui @ui do @cmd.execute end assert_match %r{lib/foo\.rb}, @ui.output - refute_match %r{Rakefile}, @ui.output + refute_match(/Rakefile/, @ui.output) assert_equal "", @ui.error end @@ -106,9 +107,9 @@ class TestGemCommandsContentsCommand < Gem::TestCase def test_execute_missing_version @cmd.options[:args] = %w[foo] - @cmd.options[:version] = Gem::Requirement.new '= 2' + @cmd.options[:version] = Gem::Requirement.new "= 2" - gem 'foo', 1 + gem "foo", 1 assert_raise Gem::MockGemUi::TermError do use_ui @ui do @@ -123,7 +124,7 @@ class TestGemCommandsContentsCommand < Gem::TestCase def test_execute_missing_multiple @cmd.options[:args] = %w[foo bar] - gem 'foo' + gem "foo" use_ui @ui do @cmd.execute @@ -138,8 +139,8 @@ class TestGemCommandsContentsCommand < Gem::TestCase def test_execute_multiple @cmd.options[:args] = %w[foo bar] - gem 'foo' - gem 'bar' + gem "foo" + gem "bar" use_ui @ui do @cmd.execute @@ -147,7 +148,7 @@ class TestGemCommandsContentsCommand < Gem::TestCase assert_match %r{lib/foo\.rb}, @ui.output assert_match %r{lib/bar\.rb}, @ui.output - assert_match %r{Rakefile}, @ui.output + assert_match(/Rakefile/, @ui.output) assert_equal "", @ui.error end @@ -155,13 +156,13 @@ class TestGemCommandsContentsCommand < Gem::TestCase @cmd.options[:args] = %w[foo] @cmd.options[:show_install_dir] = true - gem 'foo' + gem "foo" use_ui @ui do @cmd.execute end - expected = File.join @gemhome, 'gems', 'foo-2' + expected = File.join @gemhome, "gems", "foo-2" assert_equal "#{expected}\n", @ui.output assert_equal "", @ui.error @@ -171,14 +172,14 @@ class TestGemCommandsContentsCommand < Gem::TestCase @cmd.options[:args] = %w[foo] @cmd.options[:show_install_dir] = true - gem 'foo', 1 - gem 'foo', 2 + gem "foo", 1 + gem "foo", 2 use_ui @ui do @cmd.execute end - expected = File.join @gemhome, 'gems', 'foo-2' + expected = File.join @gemhome, "gems", "foo-2" assert_equal "#{expected}\n", @ui.output assert_equal "", @ui.error @@ -187,16 +188,16 @@ class TestGemCommandsContentsCommand < Gem::TestCase def test_execute_show_install_dir_version @cmd.options[:args] = %w[foo] @cmd.options[:show_install_dir] = true - @cmd.options[:version] = Gem::Requirement.new '= 1' + @cmd.options[:version] = Gem::Requirement.new "= 1" - gem 'foo', 1 - gem 'foo', 2 + gem "foo", 1 + gem "foo", 2 use_ui @ui do @cmd.execute end - expected = File.join @gemhome, 'gems', 'foo-1' + expected = File.join @gemhome, "gems", "foo-1" assert_equal "#{expected}\n", @ui.output assert_equal "", @ui.error @@ -206,7 +207,7 @@ class TestGemCommandsContentsCommand < Gem::TestCase @cmd.options[:args] = %w[foo] @cmd.options[:prefix] = false - gem 'foo' + gem "foo" use_ui @ui do @cmd.execute @@ -236,10 +237,10 @@ lib/foo.rb end expected = [ - [RbConfig::CONFIG['bindir'], 'default_command'], - [RbConfig::CONFIG['rubylibdir'], 'default/gem.rb'], - [RbConfig::CONFIG['archdir'], 'default_gem.so'], - ].sort.map{|a|File.join a }.join "\n" + [RbConfig::CONFIG["bindir"], "default_command"], + [RbConfig::CONFIG["rubylibdir"], "default/gem.rb"], + [RbConfig::CONFIG["archdir"], "default_gem.so"], + ].sort.map {|a|File.join a }.join "\n" assert_equal expected, @ui.output.chomp assert_equal "", @ui.error @@ -264,7 +265,7 @@ lib/foo.rb assert @cmd.options[:lib_only] refute @cmd.options[:prefix] assert_equal %w[foo], @cmd.options[:specdirs] - assert_equal Gem::Requirement.new('0.0.2'), @cmd.options[:version] + assert_equal Gem::Requirement.new("0.0.2"), @cmd.options[:version] assert @cmd.options[:show_install_dir] end end diff --git a/test/rubygems/test_gem_commands_dependency_command.rb b/test/rubygems/test_gem_commands_dependency_command.rb index d49aa2f513..48fe2f8e8d 100644 --- a/test/rubygems/test_gem_commands_dependency_command.rb +++ b/test/rubygems/test_gem_commands_dependency_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/dependency_command' + +require_relative "helper" +require "rubygems/commands/dependency_command" class TestGemCommandsDependencyCommand < Gem::TestCase def setup @@ -11,9 +12,9 @@ class TestGemCommandsDependencyCommand < Gem::TestCase end def test_execute - quick_gem 'foo' do |gem| - gem.add_dependency 'bar', '> 1' - gem.add_dependency 'baz', '> 1' + quick_gem "foo" do |gem| + gem.add_dependency "bar", "> 1" + gem.add_dependency "baz", "> 1" end @cmd.options[:args] = %w[foo] @@ -24,16 +25,16 @@ class TestGemCommandsDependencyCommand < Gem::TestCase assert_equal "Gem foo-2\n bar (> 1)\n baz (> 1)\n\n", @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_no_args - install_specs util_spec 'x', '2' + install_specs util_spec "x", "2" spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', '2.a' - fetcher.spec 'dep_x', 1, 'x' => '>= 1' + fetcher.spec "a", 1 + fetcher.spec "a", "2.a" + fetcher.spec "dep_x", 1, "x" => ">= 1" fetcher.legacy_platform end @@ -58,7 +59,7 @@ Gem x-2 EOF assert_equal expected, @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_no_match @@ -71,14 +72,14 @@ Gem x-2 end assert_equal "No gems found matching foo (>= 0)\n", @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_pipe_format - spec = util_spec 'foo' do |gem| - gem.add_dependency 'bar', '> 1' + spec = util_spec "foo" do |gem| + gem.add_dependency "bar", "> 1" end - install_specs util_spec 'bar', 2 + install_specs util_spec "bar", 2 install_specs spec @cmd.options[:args] = %w[foo] @@ -89,15 +90,15 @@ Gem x-2 end assert_equal "bar --version '> 1'\n", @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_regexp spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', '2.a' - fetcher.spec 'a_evil', 9 - fetcher.spec 'b', 2 + fetcher.spec "a", 1 + fetcher.spec "a", "2.a" + fetcher.spec "a_evil", 9 + fetcher.spec "b", 2 end @cmd.options[:args] = %w[[ab]] @@ -118,17 +119,17 @@ Gem b-2 EOF assert_equal expected, @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_reverse # FIX: this shouldn't need to write out, but fails if you switch it - quick_gem 'foo' do |gem| - gem.add_dependency 'bar', '> 1' + quick_gem "foo" do |gem| + gem.add_dependency "bar", "> 1" end - quick_gem 'baz' do |gem| - gem.add_dependency 'foo' + quick_gem "baz" do |gem| + gem.add_dependency "foo" end @cmd.options[:args] = %w[foo] @@ -147,7 +148,7 @@ Gem foo-2 EOF assert_equal expected, @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_reverse_remote @@ -165,15 +166,15 @@ Gem foo-2 ERROR: Only reverse dependencies for local gems are supported. EOF - assert_equal '', @stub_ui.output + assert_equal "", @stub_ui.output assert_equal expected, @stub_ui.error end def test_execute_remote - install_specs util_spec 'bar', '2' + install_specs util_spec "bar", "2" spec_fetcher do |fetcher| - fetcher.spec 'foo', 2, 'bar' => '> 1' + fetcher.spec "foo", 2, "bar" => "> 1" end @cmd.options[:args] = %w[foo] @@ -184,7 +185,7 @@ ERROR: Only reverse dependencies for local gems are supported. end assert_equal "Gem foo-2\n bar (> 1)\n\n", @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_remote_version @@ -192,25 +193,25 @@ ERROR: Only reverse dependencies for local gems are supported. Gem::RemoteFetcher.fetcher = @fetcher spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', 2 + fetcher.spec "a", 1 + fetcher.spec "a", 2 end @cmd.options[:args] = %w[a] @cmd.options[:domain] = :remote - @cmd.options[:version] = req '= 1' + @cmd.options[:version] = req "= 1" use_ui @stub_ui do @cmd.execute end assert_equal "Gem a-1\n\n", @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_prerelease spec_fetcher do |fetcher| - fetcher.spec 'a', '2.a' + fetcher.spec "a", "2.a" end @cmd.options[:args] = %w[a] @@ -222,6 +223,6 @@ ERROR: Only reverse dependencies for local gems are supported. end assert_equal "Gem a-2.a\n\n", @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end end diff --git a/test/rubygems/test_gem_commands_environment_command.rb b/test/rubygems/test_gem_commands_environment_command.rb index c31ca24869..48252d84d4 100644 --- a/test/rubygems/test_gem_commands_environment_command.rb +++ b/test/rubygems/test_gem_commands_environment_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/environment_command' + +require_relative "helper" +require "rubygems/commands/environment_command" class TestGemCommandsEnvironmentCommand < Gem::TestCase def setup @@ -11,9 +12,10 @@ class TestGemCommandsEnvironmentCommand < Gem::TestCase def test_execute orig_sources = Gem.sources.dup - orig_path, ENV['PATH'] = ENV['PATH'], %w[/usr/local/bin /usr/bin /bin].join(File::PATH_SEPARATOR) + orig_path = ENV["PATH"] + ENV["PATH"] = %w[/usr/local/bin /usr/bin /bin].join(File::PATH_SEPARATOR) Gem.sources.replace %w[http://gems.example.com] - Gem.configuration['gemcutter_key'] = 'blah' + Gem.configuration["gemcutter_key"] = "blah" @cmd.send :handle_options, %w[] @@ -21,35 +23,36 @@ class TestGemCommandsEnvironmentCommand < Gem::TestCase @cmd.execute end - assert_match %r{RUBYGEMS VERSION: (\d\.)+\d}, @ui.output - assert_match %r{RUBY VERSION: \d+\.\d+\.\d+ \(.*\) \[.*\]}, @ui.output - assert_match %r{INSTALLATION DIRECTORY: #{Regexp.escape @gemhome}}, - @ui.output - assert_match %r{RUBYGEMS PREFIX: }, @ui.output - assert_match %r{RUBY EXECUTABLE:.*#{RbConfig::CONFIG['ruby_install_name']}}, - @ui.output - assert_match %r{GIT EXECUTABLE: #{@cmd.send(:git_path)}}, @ui.output - assert_match %r{SYSTEM CONFIGURATION DIRECTORY:}, @ui.output - assert_match %r{EXECUTABLE DIRECTORY:}, @ui.output - assert_match %r{RUBYGEMS PLATFORMS:}, @ui.output - assert_match %r{- #{Gem::Platform.local}}, @ui.output - assert_match %r{GEM PATHS:}, @ui.output - assert_match %r{- #{Regexp.escape @gemhome}}, @ui.output - assert_match %r{GEM CONFIGURATION:}, @ui.output - assert_match %r{"gemcutter_key" => "\*\*\*\*"}, @ui.output - assert_match %r{:verbose => }, @ui.output - assert_match %r{REMOTE SOURCES:}, @ui.output - - assert_match %r{- SHELL PATH:}, @ui.output + assert_match(/RUBYGEMS VERSION: (\d\.)+\d/, @ui.output) + assert_match(/RUBY VERSION: \d+\.\d+\.\d+ \(.*\) \[.*\]/, @ui.output) + assert_match(/INSTALLATION DIRECTORY: #{Regexp.escape @gemhome}/, + @ui.output) + assert_match(/USER INSTALLATION DIRECTORY: #{Regexp.escape Gem.user_dir}/, + @ui.output) + assert_match(/RUBYGEMS PREFIX: /, @ui.output) + assert_match(/RUBY EXECUTABLE:.*#{RbConfig::CONFIG["ruby_install_name"]}/, + @ui.output) + assert_match(/GIT EXECUTABLE: #{@cmd.send(:git_path)}/, @ui.output) + assert_match(/SYSTEM CONFIGURATION DIRECTORY:/, @ui.output) + assert_match(/EXECUTABLE DIRECTORY:/, @ui.output) + assert_match(/RUBYGEMS PLATFORMS:/, @ui.output) + assert_match(/- #{Gem::Platform.local}/, @ui.output) + assert_match(/GEM PATHS:/, @ui.output) + assert_match(/- #{Regexp.escape @gemhome}/, @ui.output) + assert_match(/GEM CONFIGURATION:/, @ui.output) + assert_match(/"gemcutter_key" => "\*\*\*\*"/, @ui.output) + assert_match(/:verbose => /, @ui.output) + assert_match(/REMOTE SOURCES:/, @ui.output) + + assert_match(/- SHELL PATH:/, @ui.output) assert_match %r{- /usr/local/bin$}, @ui.output assert_match %r{- /usr/bin$}, @ui.output assert_match %r{- /bin$}, @ui.output assert_empty @ui.error - ensure Gem.sources.replace orig_sources - ENV['PATH'] = orig_path + ENV["PATH"] = orig_path end def test_execute_gemdir @@ -60,7 +63,29 @@ class TestGemCommandsEnvironmentCommand < Gem::TestCase end assert_equal "#{@gemhome}\n", @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error + end + + def test_execute_user_gemdir + @cmd.send :handle_options, %w[user_gemdir] + + use_ui @ui do + @cmd.execute + end + + assert_equal "#{Gem.user_dir}\n", @ui.output + assert_equal "", @ui.error + end + + def test_execute_user_gemhome + @cmd.send :handle_options, %w[user_gemhome] + + use_ui @ui do + @cmd.execute + end + + assert_equal "#{Gem.user_dir}\n", @ui.output + assert_equal "", @ui.error end def test_execute_gempath @@ -71,13 +96,13 @@ class TestGemCommandsEnvironmentCommand < Gem::TestCase end assert_equal "#{@gemhome}\n", @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error end def test_execute_gempath_multiple Gem.clear_paths path = [@gemhome, "#{@gemhome}2"].join File::PATH_SEPARATOR - ENV['GEM_PATH'] = path + ENV["GEM_PATH"] = path @cmd.send :handle_options, %w[gempath] @@ -86,7 +111,7 @@ class TestGemCommandsEnvironmentCommand < Gem::TestCase end assert_equal "#{Gem.path.join File::PATH_SEPARATOR}\n", @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error end def test_execute_remotesources @@ -100,8 +125,7 @@ class TestGemCommandsEnvironmentCommand < Gem::TestCase end assert_equal "http://gems.example.com\n", @ui.output - assert_equal '', @ui.error - + assert_equal "", @ui.error ensure Gem.sources.replace orig_sources end @@ -115,8 +139,8 @@ class TestGemCommandsEnvironmentCommand < Gem::TestCase end end - assert_equal '', @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.output + assert_equal "", @ui.error end def test_execute_version @@ -127,7 +151,7 @@ class TestGemCommandsEnvironmentCommand < Gem::TestCase end assert_equal "#{Gem::VERSION}\n", @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error end def test_execute_platform @@ -138,6 +162,6 @@ class TestGemCommandsEnvironmentCommand < Gem::TestCase end assert_equal "#{Gem.platforms.join File::PATH_SEPARATOR}\n", @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error end end diff --git a/test/rubygems/test_gem_commands_exec_command.rb b/test/rubygems/test_gem_commands_exec_command.rb new file mode 100644 index 0000000000..e52fe247a2 --- /dev/null +++ b/test/rubygems/test_gem_commands_exec_command.rb @@ -0,0 +1,859 @@ +# frozen_string_literal: true + +require_relative "helper" +require "rubygems/commands/exec_command" + +class TestGemCommandsExecCommand < Gem::TestCase + def setup + @orig_args = Gem::Command.build_args + @orig_specific_extra_args = Gem::Command.specific_extra_args_hash.dup + @orig_extra_args = Gem::Command.extra_args.dup + + super + common_installer_setup + + @cmd = Gem::Commands::ExecCommand.new + + @gem_home = Gem.dir + @gem_path = Gem.path + @test_arch = RbConfig::CONFIG["arch"] + + @installed_specs = [] + Gem.post_install {|installer| @installed_specs << installer.spec } + end + + def teardown + super + + common_installer_teardown + + Gem::Command.build_args = @orig_args + Gem::Command.specific_extra_args_hash = @orig_specific_extra_args + Gem::Command.extra_args = @orig_extra_args + Gem.configuration = nil + end + + def invoke(*args) + @ui.outs.truncate(0) + @ui.outs.rewind + @ui.errs.truncate(0) + @ui.errs.rewind + @installed_specs.clear + + @cmd.invoke(*args) + ensure + Gem::Specification.unresolved_deps.clear + Gem.loaded_specs.clear + Gem.instance_variable_set(:@activated_gem_paths, 0) + Gem.clear_default_specs + Gem.use_paths(@gem_home, @gem_path) + Gem.refresh + end + + def test_error_with_no_arguments + e = assert_raise Gem::CommandLineError do + @cmd.invoke + end + assert_equal "Please specify an executable to run (e.g. gem exec COMMAND)", + e.message + end + + def test_error_with_no_executable + e = assert_raise Gem::CommandLineError do + @cmd.invoke "--verbose", "--gem", "GEM", "--version", "< 10", "--conservative" + end + assert_equal "Please specify an executable to run (e.g. gem exec COMMAND)", + e.message + end + + def test_full_option_parsing + @cmd.when_invoked do |options| + assert_equal options, { + args: ["install", "--no-color", "--help", "--verbose"], + executable: "pod", + explicit_prerelease: false, + gem_name: "cocoapods", + prerelease: false, + version: Gem::Requirement.new(["> 1", "< 1.3"]), + build_args: nil, + } + end + @cmd.invoke "--gem", "cocoapods", "-v", "> 1", "--version", "< 1.3", "--verbose", "--", "pod", "install", "--no-color", "--help", "--verbose" + end + + def test_single_arg_parsing + @cmd.when_invoked do |options| + assert_equal options, { + args: [], + executable: "rails", + gem_name: "rails", + version: Gem::Requirement.new([">= 0"]), + build_args: nil, + } + end + @cmd.invoke "rails" + end + + def test_single_arg_parsing_with_version + @cmd.when_invoked do |options| + assert_equal options, { + args: [], + executable: "rails", + gem_name: "rails", + version: Gem::Requirement.new(["= 7.1"]), + build_args: nil, + } + end + @cmd.invoke "rails:7.1" + end + + def test_gem_without_executable + spec_fetcher do |fetcher| + fetcher.gem "a", 2 + end + + util_clear_gems + + use_ui @ui do + e = assert_raise Gem::MockGemUi::TermError, @ui.error do + @cmd.invoke "a:2" + end + assert_equal 1, e.exit_code + assert_equal "ERROR: Failed to load executable `a`, are you sure the gem `a` contains it?\n", @ui.error + end + end + + def test_gem_with_executable + spec_fetcher do |fetcher| + fetcher.gem "a", 2 do |s| + s.executables = %w[a] + s.files = %w[bin/a lib/a.rb] + + write_file File.join(*%W[gems #{s.original_name} bin a]) do |f| + f << "Gem.ui.say #{s.original_name.dump}" + end + end + end + + util_clear_gems + + use_ui @ui do + @cmd.invoke "a:2" + assert_equal "a-2\n", @ui.output + end + end + + def test_gem_with_platforms + spec_fetcher do |fetcher| + fetcher.download "a", 2 do |s| + s.executables = %w[a] + s.files = %w[bin/a lib/a.rb] + + write_file File.join(*%W[gems #{s.original_name} bin a]) do |f| + f << "Gem.ui.say #{s.original_name.dump}" + end + end + + fetcher.download "a", 2 do |s| + s.executables = %w[a] + s.files = %w[bin/a lib/a.rb] + s.platform = "x86_64-darwin" + + write_file File.join(*%W[gems #{s.original_name} bin a]) do |f| + f << "Gem.ui.say #{s.original_name.dump}" + end + end + end + + use_ui @ui do + invoke "a:2" + assert_equal "a-2\n", @ui.output + end + + use_ui @ui do + util_set_arch "x86_64-darwin-18" + invoke "a:2" + assert_equal "a-2-x86_64-darwin\n", @ui.output + end + end + + def test_gem_with_platform_dependencies + spec_fetcher do |fetcher| + fetcher.download "a", 2 do |s| + s.executables = %w[a] + s.files = %w[bin/a lib/a.rb] + s.add_runtime_dependency "with_platform" + + write_file File.join(*%W[gems #{s.original_name} bin a]) do |f| + f << 'require "with_platform"' << "\n" + f << 'Gem.ui.say Gem.loaded_specs.each_value.map(&:original_name).sort.join("\n")' + end + end + + fetcher.download "with_platform", 2 do |s| + s.files = %w[lib/with_platform.rb] + s.platform = Gem::Platform.local + end + + fetcher.download "with_platform", 2 do |s| + s.files = %w[lib/with_platform.rb] + end + end + + use_ui @ui do + util_set_arch "unknown-unknown" + invoke "a" + assert_equal "a-2\nwith_platform-2\n", @ui.output + end + + use_ui @ui do + util_set_arch @test_arch + invoke "a" + assert_empty @ui.error + assert_equal "a-2\nwith_platform-2-#{Gem::Platform.local}\n", @ui.output + end + end + + def test_gem_with_platform_and_platform_dependencies + pend "extensions don't quite work on jruby" if Gem.java_platform? + pend "terminates on mswin" if vc_windows? && ruby_repo? + + spec_fetcher do |fetcher| + fetcher.download "a", 2 do |s| + s.executables = %w[a] + s.files = %w[bin/a lib/a.rb] + s.add_runtime_dependency "with_platform" + s.platform = Gem::Platform.local.to_s + + write_file File.join(*%W[gems #{s.original_name} bin a]) do |f| + f << 'require "with_platform"' << "\n" + f << 'Gem.ui.say Gem.loaded_specs.each_value.map(&:original_name).sort.join("\n")' + end + end + + fetcher.download "a", 2 do |s| + s.executables = %w[a] + s.files = %w[bin/a lib/a.rb extconf.rb] + s.add_runtime_dependency "with_platform" + + write_file File.join(*%W[gems #{s.original_name} bin a]) do |f| + f << 'require "with_platform"' << "\n" + f << 'Gem.ui.say Gem.loaded_specs.each_value.map(&:original_name).sort.join("\n")' + end + + s.extensions = %w[extconf.rb] + write_file File.join(*%W[gems #{s.original_name} extconf.rb]) do |f| + f.write <<-RUBY + gem('with_platform', '~> 2.0') + require 'with_platform' + gem 'sometimes_used' + require 'sometimes_used' + require "mkmf" + create_makefile("#{s.name}") + RUBY + end + end + + fetcher.download "with_platform", 2 do |s| + s.files = %w[lib/with_platform.rb] + s.platform = Gem::Platform.local.to_s + end + + fetcher.download "with_platform", 2 do |s| + s.files = %w[lib/with_platform.rb] + s.add_runtime_dependency "sometimes_used" + end + + fetcher.download "sometimes_used", 2 do |s| + s.files = %w[lib/sometimes_used.rb] + end + end + + use_ui @ui do + util_set_arch "unknown-unknown" + invoke "a" + assert_empty @ui.error + assert_equal "Building native extensions. This could take a while...\na-2\nsometimes_used-2\nwith_platform-2\n", @ui.output + end + + use_ui @ui do + util_set_arch @test_arch + invoke "a" + assert_empty @ui.error + assert_equal "a-2-#{Gem::Platform.local}\nwith_platform-2-#{Gem::Platform.local}\n", @ui.output + end + end + + def test_gem_with_other_executable_name + spec_fetcher do |fetcher| + fetcher.gem "a", 2 do |s| + s.executables = %w[foo] + s.files = %w[bin/foo lib/a.rb] + + write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f| + f << "Gem.ui.say #{s.original_name.dump}" + end + end + end + + util_clear_gems + + use_ui @ui do + @cmd.invoke "a:2" + assert_equal "a-2\n", @ui.output + end + end + + def test_gem_with_executable_error + spec_fetcher do |fetcher| + fetcher.gem "a", 2 do |s| + s.executables = %w[foo] + s.files = %w[bin/foo lib/a.rb] + + write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f| + f << "raise #{s.original_name.dump}" + end + end + end + + util_clear_gems + + use_ui @ui do + e = assert_raise RuntimeError do + @cmd.invoke "a:2" + end + assert_equal "a-2", e.message + assert_empty @ui.error + end + end + + def test_gem_with_multiple_executables_one_match + spec_fetcher do |fetcher| + fetcher.gem "a", 2 do |s| + s.executables = %w[foo a] + s.files = %w[bin/foo bin/a lib/a.rb] + + write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + + write_file File.join(*%W[gems #{s.original_name} bin a]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + end + + util_clear_gems + + use_ui @ui do + @cmd.invoke "a:2" + assert_equal "a-2 a\n", @ui.output + end + end + + def test_gem_with_multiple_executables_no_match + spec_fetcher do |fetcher| + fetcher.gem "a", 2 do |s| + s.executables = %w[foo bar] + s.files = %w[bin/foo bin/bar lib/a.rb] + + write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + + write_file File.join(*%W[gems #{s.original_name} bin bar]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + end + + util_clear_gems + + use_ui @ui do + @cmd.invoke "a:2" + assert_equal "a-2 foo\n", @ui.output + end + end + + def test_gem_dependency_contains_executable + spec_fetcher do |fetcher| + fetcher.gem "a", 2 do |s| + s.executables = %w[] + s.files = %w[lib/a.rb] + + s.add_dependency "b" + end + + fetcher.gem "b", 2 do |s| + s.executables = %w[a] + s.files = %w[bin/a lib/b.rb] + + write_file File.join(*%W[gems #{s.original_name} bin a]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + end + + util_clear_gems + + use_ui @ui do + @cmd.invoke "a:2" + assert_equal "b-2 a\n", @ui.output + end + end + + def test_gem_dependency_contains_other_executable + spec_fetcher do |fetcher| + fetcher.gem "a", 2 do |s| + s.executables = %w[] + s.files = %w[lib/a.rb] + + s.add_dependency "b" + end + + fetcher.gem "b", 2 do |s| + s.executables = %w[foo] + s.files = %w[bin/foo lib/b.rb] + + write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + end + + util_clear_gems + + use_ui @ui do + e = assert_raise Gem::MockGemUi::TermError do + @cmd.invoke "a:2" + end + assert_equal 1, e.exit_code + assert_equal <<~ERR, @ui.error + ERROR: Failed to load executable `a`, are you sure the gem `a` contains it? + ERR + end + end + + def test_other_gem_contains_executable + spec_fetcher do |fetcher| + fetcher.gem "a", 2 do |s| + s.executables = %w[] + s.files = %w[lib/a.rb] + end + + fetcher.gem "b", 2 do |s| + s.executables = %w[a] + s.files = %w[bin/a lib/b.rb] + + write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + end + + util_clear_gems + + use_ui @ui do + e = assert_raise Gem::MockGemUi::TermError do + @cmd.invoke "a:2" + end + assert_equal 1, e.exit_code + assert_equal <<~ERR, @ui.error + ERROR: Failed to load executable `a`, are you sure the gem `a` contains it? + ERR + end + end + + def test_missing_gem + spec_fetcher do |fetcher| + end + + use_ui @ui do + e = assert_raise Gem::MockGemUi::TermError do + @cmd.invoke "a" + end + assert_equal 2, e.exit_code + assert_equal <<~ERR, @ui.error + ERROR: Could not find a valid gem 'a' (>= 0) in any repository + ERR + end + end + + def test_version_mismatch + spec_fetcher do |fetcher| + fetcher.gem "a", 1 + end + + util_clear_gems + + use_ui @ui do + e = assert_raise Gem::MockGemUi::TermError do + @cmd.invoke "a:2" + end + assert_equal 2, e.exit_code + assert_equal <<~ERR, @ui.error + ERROR: Could not find a valid gem 'a' (= 2) in any repository + ERROR: Possible alternatives: a + ERR + end + end + + def test_pre_argument + spec_fetcher do |fetcher| + fetcher.gem "a", 1 do |s| + s.executables = %w[foo] + s.files = %w[bin/foo lib/a.rb] + + write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + fetcher.gem "a", "1.1.a" do |s| + s.executables = %w[foo] + s.files = %w[bin/foo lib/a.rb] + + write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + end + + util_clear_gems + + use_ui @ui do + @cmd.invoke "--pre", "a" + assert_equal "a-1.1.a foo\n", @ui.output + end + end + + def test_pre_version_option + spec_fetcher do |fetcher| + fetcher.download "a", 1 do |s| + s.executables = %w[foo] + s.files = %w[bin/foo lib/a.rb] + + write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + fetcher.download "a", "1.1.a" do |s| + s.executables = %w[foo] + s.files = %w[bin/foo lib/a.rb] + + write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + end + + use_ui @ui do + @cmd.invoke "-v", ">= 0.a", "a" + assert_equal "a-1.1.a foo\n", @ui.output + end + end + + def test_conservative_missing_gem + spec_fetcher do |fetcher| + fetcher.gem "a", 1 do |s| + s.executables = %w[foo] + s.files = %w[bin/foo lib/a.rb] + + write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + end + + util_clear_gems + + use_ui @ui do + e = assert_raise Gem::MockGemUi::TermError do + @cmd.invoke "--verbose", "--conservative", "a:2" + end + assert_equal 2, e.exit_code + assert_include @ui.output, "a (= 2) not available locally" + assert_equal <<~ERROR, @ui.error + ERROR: Could not find a valid gem 'a' (= 2) in any repository + ERROR: Possible alternatives: a + ERROR + end + end + + def test_conservative + spec_fetcher do |fetcher| + fetcher.download "a", 1 do |s| + s.executables = %w[foo] + s.files = %w[bin/foo lib/a.rb] + + write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + end + + use_ui @ui do + invoke "--verbose", "--conservative", "a" + assert_include @ui.output, "a (>= 0) not available locally" + assert_include @ui.output, "a-1 foo" + assert_equal %w[a-1], @installed_specs.map(&:original_name) + end + + spec_fetcher do |fetcher| + fetcher.gem "a", 1 do |s| + s.executables = %w[foo] + s.files = %w[bin/foo lib/a.rb] + + write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + + fetcher.download "a", 2 do |s| + s.executables = %w[foo] + s.files = %w[bin/foo lib/a.rb] + + write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + end + + use_ui @ui do + invoke "--verbose", "--conservative", "a" + assert_not_include @ui.output, "a (>= 0) not available locally" + assert_include @ui.output, "a-1 foo" + assert_empty @installed_specs.map(&:original_name) + end + end + + def test_uses_newest_version + spec_fetcher do |fetcher| + fetcher.download "a", 1 do |s| + s.executables = %w[foo] + s.files = %w[bin/foo lib/a.rb] + + write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + end + + use_ui @ui do + invoke "a" + assert_include @ui.output, "a-1 foo" + end + + spec_fetcher do |fetcher| + fetcher.download "a", 1 do |s| + s.executables = %w[foo] + s.files = %w[bin/foo lib/a.rb] + + write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + + fetcher.download "a", 2 do |s| + s.executables = %w[foo] + s.files = %w[bin/foo lib/a.rb] + + write_file File.join(*%W[gems #{s.original_name} bin foo]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + end + + use_ui @ui do + invoke "--verbose", "a:2" + refute_predicate @ui, :terminated? + assert_empty @ui.error + assert_include @ui.output, "a-2 foo" + assert_equal %w[a-2], @installed_specs.map(&:original_name) + end + end + + def test_uses_newest_version_of_dependency + spec_fetcher do |fetcher| + fetcher.gem "a", 1 do |s| + s.executables = %w[] + s.files = %w[lib/a.rb] + s.add_runtime_dependency "b" + end + + fetcher.gem "b", 1 do |s| + s.executables = %w[a] + s.files = %w[bin/a lib/a.rb] + + write_file File.join(*%W[gems #{s.original_name} bin a]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + + fetcher.download "b", 2 do |s| + s.executables = %w[a] + s.files = %w[bin/a lib/a.rb] + + write_file File.join(*%W[gems #{s.original_name} bin a]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + end + + use_ui @ui do + invoke "a" + assert_include @ui.output, "b-2 a" + assert_equal %w[b-2], @installed_specs.map(&:original_name) + end + end + + def test_gem_exec_gem_uninstall + spec_fetcher do |fetcher| + fetcher.download "a", 2 do |s| + s.executables = %w[a] + s.files = %w[bin/a lib/a.rb] + s.add_runtime_dependency "b" + + write_file File.join(*%W[gems #{s.original_name} bin a]) do |f| + f << "Gem.ui.say #{s.original_name.dump}" + end + end + + fetcher.download "b", 2 do |s| + s.files = %w[lib/b.rb] + end + end + + use_ui @ui do + invoke "a:2" + assert_equal "a-2\n", @ui.output + + invoke "gem", "list", "--local" + assert_includes @ui.output, "a (2)\n" + assert_includes @ui.output, "b (2)\n" + + begin + invoke "gem", "uninstall", "--verbose", "-x", "a" + rescue StandardError + nil + end + + assert_empty @ui.error + refute_includes @ui.output, "running gem exec with" + assert_includes @ui.output, "Successfully uninstalled a-2\n" + + invoke "--verbose", "gem", "uninstall", "b" + assert_includes @ui.output, "Successfully uninstalled b-2\n" + + invoke "gem", "list", "--local" + assert_empty @ui.error + assert_match(/\A\s*\** LOCAL GEMS \**\s*\z/m, @ui.output) + + invoke "gem", "env", "GEM_HOME" + assert_equal "#{@gem_home}/gem_exec\n", @ui.output + end + end + + def test_only_prerelease_available + spec_fetcher do |fetcher| + fetcher.download "a", "1.a" do |s| + s.executables = %w[a] + s.files = %w[lib/a.rb bin/a] + + write_file File.join(*%W[gems #{s.original_name} bin a]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + end + + use_ui @ui do + assert_raise Gem::MockGemUi::TermError do + invoke "a" + end + assert_equal "ERROR: Could not find a valid gem 'a' (>= 0) in any repository\n" \ + "ERROR: Possible alternatives: a\n", @ui.error + assert_empty @ui.output + assert_empty @installed_specs + end + + use_ui @ui do + invoke "a:1.a" + assert_empty @ui.error + assert_equal "a-1.a a\n", @ui.output + assert_equal %w[a-1.a], @installed_specs.map(&:full_name) + end + + FileUtils.rm_rf Gem.dir + + use_ui @ui do + invoke "--version", ">= 1.a", "a" + assert_empty @ui.error + assert_equal "a-1.a a\n", @ui.output + assert_equal %w[a-1.a], @installed_specs.map(&:full_name) + end + + FileUtils.rm_rf Gem.dir + + use_ui @ui do + invoke "--pre", "a" + assert_empty @ui.error + assert_equal "a-1.a a\n", @ui.output + assert_equal %w[a-1.a], @installed_specs.map(&:full_name) + end + end + + def test_newer_prerelease_available + spec_fetcher do |fetcher| + fetcher.download "a", "1" do |s| + s.executables = %w[a] + s.files = %w[lib/a.rb bin/a] + + write_file File.join(*%W[gems #{s.original_name} bin a]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + + fetcher.download "a", "1.1.a" do |s| + s.executables = %w[a] + s.files = %w[lib/a.rb bin/a] + + write_file File.join(*%W[gems #{s.original_name} bin a]) do |f| + f << "Gem.ui.say #{s.original_name.dump} + ' ' + File.basename(__FILE__)" + end + end + end + + use_ui @ui do + invoke "a" + assert_empty @ui.error + assert_equal "a-1 a\n", @ui.output + assert_equal %w[a-1], @installed_specs.map(&:full_name) + end + + FileUtils.rm_rf Gem.dir + + use_ui @ui do + invoke "a:1.1.a" + assert_empty @ui.error + assert_equal "a-1.1.a a\n", @ui.output + assert_equal %w[a-1.1.a], @installed_specs.map(&:full_name) + end + + FileUtils.rm_rf Gem.dir + + use_ui @ui do + invoke "--version", ">= 1.a", "a" + assert_empty @ui.error + assert_equal "a-1.1.a a\n", @ui.output + assert_equal %w[a-1.1.a], @installed_specs.map(&:full_name) + end + + FileUtils.rm_rf Gem.dir + + use_ui @ui do + invoke "--pre", "a" + assert_empty @ui.error + assert_equal "a-1.1.a a\n", @ui.output + assert_equal %w[a-1.1.a], @installed_specs.map(&:full_name) + end + end +end diff --git a/test/rubygems/test_gem_commands_fetch_command.rb b/test/rubygems/test_gem_commands_fetch_command.rb index 9a81e8898e..e8710d3cd1 100644 --- a/test/rubygems/test_gem_commands_fetch_command.rb +++ b/test/rubygems/test_gem_commands_fetch_command.rb @@ -1,8 +1,9 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/package' -require 'rubygems/security' -require 'rubygems/commands/fetch_command' + +require_relative "helper" +require "rubygems/package" +require "rubygems/security" +require "rubygems/commands/fetch_command" class TestGemCommandsFetchCommand < Gem::TestCase def setup @@ -13,10 +14,10 @@ class TestGemCommandsFetchCommand < Gem::TestCase def test_execute specs = spec_fetcher do |fetcher| - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end - assert_path_not_exist File.join(@tempdir, 'cache'), 'sanity check' + assert_path_not_exist File.join(@tempdir, "cache"), "sanity check" @cmd.options[:args] = %w[a] @@ -26,24 +27,24 @@ class TestGemCommandsFetchCommand < Gem::TestCase end end - a2 = specs['a-2'] + a2 = specs["a-2"] assert_path_exist(File.join(@tempdir, a2.file_name), "#{a2.full_name} not fetched") - assert_path_not_exist File.join(@tempdir, 'cache'), - 'gem repository directories must not be created' + assert_path_not_exist File.join(@tempdir, "cache"), + "gem repository directories must not be created" end def test_execute_latest specs = spec_fetcher do |fetcher| - fetcher.gem 'a', 1 - fetcher.gem 'a', 2 + fetcher.gem "a", 1 + fetcher.gem "a", 2 end - assert_path_not_exist File.join(@tempdir, 'cache'), 'sanity check' + assert_path_not_exist File.join(@tempdir, "cache"), "sanity check" @cmd.options[:args] = %w[a] - @cmd.options[:version] = req('>= 0.1') + @cmd.options[:version] = req(">= 0.1") use_ui @ui do Dir.chdir @tempdir do @@ -51,17 +52,17 @@ class TestGemCommandsFetchCommand < Gem::TestCase end end - a2 = specs['a-2'] + a2 = specs["a-2"] assert_path_exist(File.join(@tempdir, a2.file_name), "#{a2.full_name} not fetched") - assert_path_not_exist File.join(@tempdir, 'cache'), - 'gem repository directories must not be created' + assert_path_not_exist File.join(@tempdir, "cache"), + "gem repository directories must not be created" end def test_execute_prerelease specs = spec_fetcher do |fetcher| - fetcher.gem 'a', 2 - fetcher.gem 'a', '2.a' + fetcher.gem "a", 2 + fetcher.gem "a", "2.a" end @cmd.options[:args] = %w[a] @@ -73,16 +74,52 @@ class TestGemCommandsFetchCommand < Gem::TestCase end end - a2 = specs['a-2'] + a2 = specs["a-2"] assert_path_exist(File.join(@tempdir, a2.file_name), "#{a2.full_name} not fetched") end + def test_execute_platform + a2_spec, a2 = util_gem("a", "2") + + a2_universal_darwin_spec, a2_universal_darwin = util_gem("a", "2") do |s| + s.platform = "universal-darwin" + end + + Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new + + write_marshalled_gemspecs(a2_spec, a2_universal_darwin_spec) + + @cmd.options[:args] = %w[a] + + @fetcher.data["#{@gem_repo}latest_specs.#{Gem.marshal_version}.gz"] = util_gzip(Marshal.dump([ + Gem::NameTuple.new(a2_spec.name, a2_spec.version, a2_spec.platform), + Gem::NameTuple.new(a2_universal_darwin_spec.name, a2_universal_darwin_spec.version, a2_universal_darwin_spec.platform), + ])) + + @fetcher.data["#{@gem_repo}gems/#{a2_spec.file_name}"] = Gem.read_binary(a2) + FileUtils.cp a2, a2_spec.cache_file + + @fetcher.data["#{@gem_repo}gems/#{a2_universal_darwin_spec.file_name}"] = Gem.read_binary(a2_universal_darwin) + FileUtils.cp a2_universal_darwin, a2_universal_darwin_spec.cache_file + + util_set_arch "arm64-darwin20" do + use_ui @ui do + Dir.chdir @tempdir do + @cmd.execute + end + end + end + + assert_path_exist(File.join(@tempdir, a2_universal_darwin_spec.file_name), + "#{a2_universal_darwin_spec.full_name} not fetched") + end + def test_execute_specific_prerelease specs = spec_fetcher do |fetcher| - fetcher.gem 'a', 2 - fetcher.gem 'a', '2.a' + fetcher.gem "a", 2 + fetcher.gem "a", "2.a" end @cmd.options[:args] = %w[a] @@ -95,7 +132,7 @@ class TestGemCommandsFetchCommand < Gem::TestCase end end - a2_pre = specs['a-2.a'] + a2_pre = specs["a-2.a"] assert_path_exist(File.join(@tempdir, a2_pre.file_name), "#{a2_pre.full_name} not fetched") @@ -103,12 +140,12 @@ class TestGemCommandsFetchCommand < Gem::TestCase def test_execute_version specs = spec_fetcher do |fetcher| - fetcher.gem 'a', 1 - fetcher.gem 'a', 2 + fetcher.gem "a", 1 + fetcher.gem "a", 2 end @cmd.options[:args] = %w[a] - @cmd.options[:version] = Gem::Requirement.new '1' + @cmd.options[:version] = Gem::Requirement.new "1" use_ui @ui do Dir.chdir @tempdir do @@ -116,9 +153,106 @@ class TestGemCommandsFetchCommand < Gem::TestCase end end - a1 = specs['a-1'] + a1 = specs["a-1"] assert_path_exist(File.join(@tempdir, a1.file_name), "#{a1.full_name} not fetched") end + + def test_execute_version_specified_by_colon + specs = spec_fetcher do |fetcher| + fetcher.gem "a", 1 + end + + @cmd.options[:args] = %w[a:1] + + use_ui @ui do + Dir.chdir @tempdir do + @cmd.execute + end + end + + a1 = specs["a-1"] + + assert_path_exist(File.join(@tempdir, a1.file_name), + "#{a1.full_name} not fetched") + end + + def test_execute_two_version + @cmd.options[:args] = %w[a b] + @cmd.options[:version] = Gem::Requirement.new "1" + + use_ui @ui do + assert_raise Gem::MockGemUi::TermError, @ui.error do + @cmd.execute + end + end + + msg = "ERROR: Can't use --version with multiple gems. You can specify multiple gems with" \ + " version requirements using `gem fetch 'my_gem:1.0.0' 'my_other_gem:~>2.0.0'`" + + assert_empty @ui.output + assert_equal msg, @ui.error.chomp + end + + def test_execute_two_version_specified_by_colon + specs = spec_fetcher do |fetcher| + fetcher.gem "a", 1 + fetcher.gem "b", 1 + end + + @cmd.options[:args] = %w[a:1 b:1] + + use_ui @ui do + Dir.chdir @tempdir do + @cmd.execute + end + end + + a1 = specs["a-1"] + b1 = specs["b-1"] + + assert_path_exist(File.join(@tempdir, a1.file_name), + "#{a1.full_name} not fetched") + assert_path_exist(File.join(@tempdir, b1.file_name), + "#{b1.full_name} not fetched") + end + + def test_execute_version_nonexistent + spec_fetcher do |fetcher| + fetcher.spec "foo", 1 + end + + @cmd.options[:args] = %w[foo:2] + + use_ui @ui do + @cmd.execute + end + + expected = <<-EXPECTED +ERROR: Could not find a valid gem 'foo' (2) in any repository +ERROR: Possible alternatives: foo + EXPECTED + + assert_equal expected, @ui.error + end + + def test_execute_nonexistent_hint_disabled + spec_fetcher do |fetcher| + fetcher.spec "foo", 1 + end + + @cmd.options[:args] = %w[foo:2] + @cmd.options[:suggest_alternate] = false + + use_ui @ui do + @cmd.execute + end + + expected = <<-EXPECTED +ERROR: Could not find a valid gem 'foo' (2) in any repository + EXPECTED + + assert_equal expected, @ui.error + end end diff --git a/test/rubygems/test_gem_commands_generate_index_command.rb b/test/rubygems/test_gem_commands_generate_index_command.rb deleted file mode 100644 index fc1317a49d..0000000000 --- a/test/rubygems/test_gem_commands_generate_index_command.rb +++ /dev/null @@ -1,80 +0,0 @@ -# frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/indexer' -require 'rubygems/commands/generate_index_command' - -class TestGemCommandsGenerateIndexCommand < Gem::TestCase - def setup - super - - @cmd = Gem::Commands::GenerateIndexCommand.new - @cmd.options[:directory] = @gemhome - end - - def test_execute - use_ui @ui do - @cmd.execute - end - - specs = File.join @gemhome, "specs.4.8.gz" - - assert File.exist?(specs), specs - end - - def test_execute_no_modern - @cmd.options[:modern] = false - - use_ui @ui do - @cmd.execute - end - - specs = File.join @gemhome, "specs.4.8.gz" - - assert File.exist?(specs), specs - end - - def test_handle_options_directory - return if win_platform? - refute_equal '/nonexistent', @cmd.options[:directory] - - @cmd.handle_options %w[--directory /nonexistent] - - assert_equal '/nonexistent', @cmd.options[:directory] - end - - def test_handle_options_directory_windows - return unless win_platform? - - refute_equal '/nonexistent', @cmd.options[:directory] - - @cmd.handle_options %w[--directory C:/nonexistent] - - assert_equal 'C:/nonexistent', @cmd.options[:directory] - end - - def test_handle_options_update - @cmd.handle_options %w[--update] - - assert @cmd.options[:update] - end - - def test_handle_options_modern - use_ui @ui do - @cmd.handle_options %w[--modern] - end - - assert_equal \ - "WARNING: The \"--modern\" option has been deprecated and will be removed in Rubygems 4.0. Modern indexes (specs, latest_specs, and prerelease_specs) are always generated, so this option is not needed.\n", - @ui.error - end - - def test_handle_options_no_modern - use_ui @ui do - @cmd.handle_options %w[--no-modern] - end - - assert_equal \ - "WARNING: The \"--no-modern\" option has been deprecated and will be removed in Rubygems 4.0. The `--no-modern` option is currently ignored. Modern indexes (specs, latest_specs, and prerelease_specs) are always generated.\n", - @ui.error - end -end diff --git a/test/rubygems/test_gem_commands_help_command.rb b/test/rubygems/test_gem_commands_help_command.rb index 24cf2d2250..359da0a6d0 100644 --- a/test/rubygems/test_gem_commands_help_command.rb +++ b/test/rubygems/test_gem_commands_help_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true + require "rubygems" -require "rubygems/test_case" +require_relative "helper" require "rubygems/commands/help_command" require "rubygems/package" require "rubygems/command_manager" @@ -11,34 +12,41 @@ class TestGemCommandsHelpCommand < Gem::TestCase @cmd = Gem::Commands::HelpCommand.new - load File.expand_path('../rubygems_plugin.rb', __FILE__) unless Gem::Commands.const_defined? :InterruptCommand + load File.expand_path("rubygems_plugin.rb", __dir__) unless Gem::Commands.const_defined? :InterruptCommand end def test_gem_help_bad - util_gem 'bad' do |out, err| - assert_equal('', out) + util_gem "bad" do |out, err| + assert_equal("", out) assert_match "Unknown command bad", err end end def test_gem_help_gem_dependencies - util_gem 'gem_dependencies' do |out, err| - assert_match 'gem.deps.rb', out - assert_equal '', err + util_gem "gem_dependencies" do |out, err| + assert_match "gem.deps.rb", out + assert_equal "", err end end def test_gem_help_platforms - util_gem 'platforms' do |out, err| + util_gem "platforms" do |out, err| assert_match(/x86-freebsd/, out) - assert_equal '', err + assert_equal "", err + end + end + + def test_gem_help_build + util_gem "build" do |out, err| + assert_match(/-C PATH *Run as if gem build was started in <PATH>/, out) + assert_equal "", err end end def test_gem_help_commands mgr = Gem::CommandManager.new - util_gem 'commands' do |out, err| + util_gem "commands" do |out, err| mgr.command_names.each do |cmd| unless mgr[cmd].deprecated? assert_match(/\s+#{cmd}\s+\S+/, out) @@ -48,7 +56,7 @@ class TestGemCommandsHelpCommand < Gem::TestCase if Gem::HAVE_OPENSSL assert_empty err - refute_match %r{No command found for }, out + refute_match(/No command found for /, out) end end end @@ -56,7 +64,7 @@ class TestGemCommandsHelpCommand < Gem::TestCase def test_gem_help_commands_omits_deprecated_commands mgr = Gem::CommandManager.new - util_gem 'commands' do |out, err| + util_gem "commands" do |out, _err| deprecated_commands = mgr.command_names.select {|cmd| mgr[cmd].deprecated? } deprecated_commands.each do |cmd| refute_match(/\A\s+#{cmd}\s+\S+\z/, out) @@ -68,7 +76,7 @@ class TestGemCommandsHelpCommand < Gem::TestCase util_gem do |out, err| assert_match(/Usage:/, out) assert_match(/gem install/, out) - assert_equal '', err + assert_equal "", err end end diff --git a/test/rubygems/test_gem_commands_info_command.rb b/test/rubygems/test_gem_commands_info_command.rb index 6d67b567c7..83e4c8a896 100644 --- a/test/rubygems/test_gem_commands_info_command.rb +++ b/test/rubygems/test_gem_commands_info_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/info_command' + +require_relative "helper" +require "rubygems/commands/info_command" class TestGemCommandsInfoCommand < Gem::TestCase def setup @@ -32,12 +33,38 @@ class TestGemCommandsInfoCommand < Gem::TestCase @cmd.execute end - assert_match %r{#{@gem.name} \(#{@gem.version}\)\n}, @ui.output - assert_match %r{Authors: #{@gem.authors.join(', ')}\n}, @ui.output - assert_match %r{Homepage: #{@gem.homepage}\n}, @ui.output - assert_match %r{License: #{@gem.license}\n}, @ui.output - assert_match %r{Installed at: #{@gem.base_dir}\n}, @ui.output - assert_match %r{#{@gem.summary}\n}, @ui.output + assert_include(@ui.output, "#{@gem.name} (#{@gem.version})\n") + assert_include(@ui.output, "Authors: #{@gem.authors.join(", ")}\n") + assert_include(@ui.output, "Homepage: #{@gem.homepage}\n") + assert_include(@ui.output, "License: #{@gem.license}\n") + assert_include(@ui.output, "Installed at: #{@gem.base_dir}\n") + assert_include(@ui.output, "#{@gem.summary}\n") assert_match "", @ui.error end + + def test_execute_with_version_flag + spec_fetcher do |fetcher| + fetcher.spec "coolgem", "1.0" + fetcher.spec "coolgem", "2.0" + end + + @cmd.handle_options %w[coolgem --remote --version 1.0] + + use_ui @ui do + @cmd.execute + end + + expected = <<-EOF + +*** REMOTE GEMS *** + +coolgem (1.0) + Author: A User + Homepage: http://example.com + + this is a summary + EOF + + assert_equal expected, @ui.output + end end diff --git a/test/rubygems/test_gem_commands_install_command.rb b/test/rubygems/test_gem_commands_install_command.rb index bc6349b219..5b09512ac4 100644 --- a/test/rubygems/test_gem_commands_install_command.rb +++ b/test/rubygems/test_gem_commands_install_command.rb @@ -1,11 +1,14 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/install_command' -require 'rubygems/request_set' -require 'rubygems/rdoc' + +require_relative "helper" +require_relative "test_gem_update_suggestion" +require "rubygems/commands/install_command" +require "rubygems/request_set" +require "rubygems/rdoc" class TestGemCommandsInstallCommand < Gem::TestCase def setup + @orig_args = Gem::Command.build_args super common_installer_setup @@ -13,7 +16,6 @@ class TestGemCommandsInstallCommand < Gem::TestCase @cmd.options[:document] = [] @gemdeps = "tmp_install_gemdeps" - @orig_args = Gem::Command.build_args common_installer_setup end @@ -30,8 +32,8 @@ class TestGemCommandsInstallCommand < Gem::TestCase def test_execute_exclude_prerelease spec_fetcher do |fetcher| - fetcher.gem 'a', 2 - fetcher.gem 'a', '2.pre' + fetcher.gem "a", 2 + fetcher.gem "a", "2.pre" end @cmd.options[:args] = %w[a] @@ -42,18 +44,18 @@ class TestGemCommandsInstallCommand < Gem::TestCase end end - assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name) end def test_execute_explicit_version_includes_prerelease specs = spec_fetcher do |fetcher| - fetcher.gem 'a', 2 - fetcher.gem 'a', '2.a' + fetcher.gem "a", 2 + fetcher.gem "a", "2.a" end - a2_pre = specs['a-2.a'] + a2_pre = specs["a-2.a"] - @cmd.handle_options [a2_pre.name, '--version', a2_pre.version.to_s, + @cmd.handle_options [a2_pre.name, "--version", a2_pre.version.to_s, "--no-document"] assert @cmd.options[:prerelease] assert @cmd.options[:version].satisfied_by?(a2_pre.version) @@ -64,17 +66,17 @@ class TestGemCommandsInstallCommand < Gem::TestCase end end - assert_equal %w[a-2.a], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[a-2.a], @cmd.installed_specs.map(&:full_name) end def test_execute_local specs = spec_fetcher do |fetcher| - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end @cmd.options[:domain] = :local - FileUtils.mv specs['a-2'].cache_file, @tempdir + FileUtils.mv specs["a-2"].cache_file, @tempdir @cmd.options[:args] = %w[a] @@ -90,21 +92,21 @@ class TestGemCommandsInstallCommand < Gem::TestCase end end - assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name) assert_match "1 gem installed", @ui.output end def test_execute_local_dependency_nonexistent specs = spec_fetcher do |fetcher| - fetcher.gem 'foo', 2, 'bar' => '0.5' + fetcher.gem "foo", 2, "bar" => "0.5" end @cmd.options[:domain] = :local - FileUtils.mv specs['foo-2'].cache_file, @tempdir + FileUtils.mv specs["foo-2"].cache_file, @tempdir - @cmd.options[:args] = ['foo'] + @cmd.options[:args] = ["foo"] use_ui @ui do orig_dir = Dir.pwd @@ -128,15 +130,15 @@ ERROR: Could not find a valid gem 'bar' (= 0.5) (required by 'foo' (>= 0)) in a def test_execute_local_dependency_nonexistent_ignore_dependencies specs = spec_fetcher do |fetcher| - fetcher.gem 'foo', 2, 'bar' => '0.5' + fetcher.gem "foo", 2, "bar" => "0.5" end @cmd.options[:domain] = :local @cmd.options[:ignore_dependencies] = true - FileUtils.mv specs['foo-2'].cache_file, @tempdir + FileUtils.mv specs["foo-2"].cache_file, @tempdir - @cmd.options[:args] = ['foo'] + @cmd.options[:args] = ["foo"] use_ui @ui do orig_dir = Dir.pwd @@ -155,16 +157,16 @@ ERROR: Could not find a valid gem 'bar' (= 0.5) (required by 'foo' (>= 0)) in a def test_execute_local_transitive_prerelease specs = spec_fetcher do |fetcher| - fetcher.download 'a', 2, 'b' => "2.a", 'c' => '3' - fetcher.download 'b', '2.a' - fetcher.download 'c', '3' + fetcher.download "a", 2, "b" => "2.a", "c" => "3" + fetcher.download "b", "2.a" + fetcher.download "c", "3" end @cmd.options[:domain] = :local - FileUtils.mv specs['a-2'].cache_file, @tempdir - FileUtils.mv specs['b-2.a'].cache_file, @tempdir - FileUtils.mv specs['c-3'].cache_file, @tempdir + FileUtils.mv specs["a-2"].cache_file, @tempdir + FileUtils.mv specs["b-2.a"].cache_file, @tempdir + FileUtils.mv specs["c-3"].cache_file, @tempdir @cmd.options[:args] = %w[a] @@ -181,40 +183,35 @@ ERROR: Could not find a valid gem 'bar' (= 0.5) (required by 'foo' (>= 0)) in a end end - assert_equal %w[a-2 b-2.a c-3], @cmd.installed_specs.map {|spec| spec.full_name }.sort + assert_equal %w[a-2 b-2.a c-3], @cmd.installed_specs.map(&:full_name).sort assert_match "3 gems installed", @ui.output end def test_execute_no_user_install - skip 'skipped on MS Windows (chmod has no effect)' if win_platform? - skip 'skipped in root privilege' if Process.uid.zero? + pend "skipped on MS Windows (chmod has no effect)" if Gem.win_platform? + pend "skipped in root privilege" if Process.uid.zero? - specs = spec_fetcher do |fetcher| - fetcher.gem 'a', 2 + spec_fetcher do |fetcher| + fetcher.download "a", 2 end @cmd.options[:user_install] = false - FileUtils.mv specs['a-2'].cache_file, @tempdir - @cmd.options[:args] = %w[a] use_ui @ui do - orig_dir = Dir.pwd - begin - FileUtils.chmod 0755, @userhome - FileUtils.chmod 0555, @gemhome + FileUtils.chmod 0o755, @userhome + FileUtils.chmod 0o555, @gemhome - Dir.chdir @tempdir - assert_raise Gem::FilePermissionError do - @cmd.execute - end - ensure - Dir.chdir orig_dir - FileUtils.chmod 0755, @gemhome + assert_raise Gem::MockGemUi::SystemExitException, @ui.error do + @cmd.execute end + ensure + FileUtils.chmod 0o755, @gemhome end + + assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name).sort end def test_execute_local_missing @@ -231,7 +228,7 @@ ERROR: Could not find a valid gem 'bar' (= 0.5) (required by 'foo' (>= 0)) in a assert_equal 2, e.exit_code end - # HACK no repository was checked + # HACK: no repository was checked assert_match(/ould not find a valid gem 'no_such_gem'/, @ui.error) end @@ -250,7 +247,7 @@ ERROR: Could not find a valid gem 'bar' (= 0.5) (required by 'foo' (>= 0)) in a assert_equal 2, e.exit_code end - # HACK no repository was checked + # HACK: no repository was checked assert_match(/ould not find a valid gem 'no_such_gem'/, @ui.error) end @@ -277,12 +274,28 @@ ERROR: Could not find a valid gem 'bar' (= 0.5) (required by 'foo' (>= 0)) in a assert_match(/ould not find a valid gem 'nonexistent'/, @ui.error) end + def test_execute_nonexistent_force + spec_fetcher + + @cmd.options[:args] = %w[nonexistent] + @cmd.options[:force] = true + + use_ui @ui do + e = assert_raise Gem::MockGemUi::TermError do + @cmd.execute + end + assert_equal 2, e.exit_code + end + + assert_match(/ould not find a valid gem 'nonexistent'/, @ui.error) + end + def test_execute_dependency_nonexistent spec_fetcher do |fetcher| - fetcher.spec 'foo', 2, 'bar' => '0.5' + fetcher.spec "foo", 2, "bar" => "0.5" end - @cmd.options[:args] = ['foo'] + @cmd.options[:args] = ["foo"] use_ui @ui do e = assert_raise Gem::MockGemUi::TermError do @@ -418,25 +431,10 @@ ERROR: Possible alternatives: non_existent_with_hint 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_raise Gem::MockGemUi::TermError do - @cmd.execute - end - end - - expected = "ERROR: Use --install-dir or --user-install but not both\n" - - assert_equal expected, @ui.error - end - def test_execute_prerelease_skipped_when_no_flag_set spec_fetcher do |fetcher| - fetcher.gem 'a', 1 - fetcher.gem 'a', '3.a' + fetcher.gem "a", 1 + fetcher.gem "a", "3.a" end @cmd.options[:prerelease] = false @@ -448,13 +446,13 @@ ERROR: Possible alternatives: non_existent_with_hint end end - assert_equal %w[a-1], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[a-1], @cmd.installed_specs.map(&:full_name) end def test_execute_prerelease_wins_over_previous_ver spec_fetcher do |fetcher| - fetcher.download 'a', 1 - fetcher.download 'a', '2.a' + fetcher.download "a", 1 + fetcher.download "a", "2.a" end @cmd.options[:prerelease] = true @@ -466,13 +464,13 @@ ERROR: Possible alternatives: non_existent_with_hint end end - assert_equal %w[a-2.a], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[a-2.a], @cmd.installed_specs.map(&:full_name) end def test_execute_with_version_specified_by_colon spec_fetcher do |fetcher| - fetcher.download 'a', 1 - fetcher.download 'a', 2 + fetcher.download "a", 1 + fetcher.download "a", 2 end @cmd.options[:args] = %w[a:1] @@ -483,13 +481,13 @@ ERROR: Possible alternatives: non_existent_with_hint end end - assert_equal %w[a-1], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[a-1], @cmd.installed_specs.map(&:full_name) end def test_execute_prerelease_skipped_when_non_pre_available spec_fetcher do |fetcher| - fetcher.gem 'a', '2.pre' - fetcher.gem 'a', 2 + fetcher.gem "a", "2.pre" + fetcher.gem "a", 2 end @cmd.options[:prerelease] = true @@ -501,23 +499,23 @@ ERROR: Possible alternatives: non_existent_with_hint end end - assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name) end def test_execute_required_ruby_version - next_ruby = Gem.ruby_version.segments.map.with_index{|n, i| i == 1 ? n + 1 : n }.join(".") + next_ruby = Gem.ruby_version.segments.map.with_index {|n, i| i == 1 ? n + 1 : n }.join(".") local = Gem::Platform.local spec_fetcher do |fetcher| - fetcher.download 'a', 2 - fetcher.download 'a', 2 do |s| + fetcher.download "a", 2 + fetcher.download "a", 2 do |s| s.required_ruby_version = "< #{RUBY_VERSION}.a" s.platform = local end - fetcher.download 'a', 3 do |s| + fetcher.download "a", 3 do |s| s.required_ruby_version = ">= #{next_ruby}" end - fetcher.download 'a', 3 do |s| + fetcher.download "a", 3 do |s| s.required_ruby_version = ">= #{next_ruby}" s.platform = local end @@ -531,14 +529,14 @@ ERROR: Possible alternatives: non_existent_with_hint end end - assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name) end def test_execute_required_ruby_version_upper_bound local = Gem::Platform.local spec_fetcher do |fetcher| - fetcher.gem 'a', 2.0 - fetcher.gem 'a', 2.0 do |s| + fetcher.gem "a", 2.0 + fetcher.gem "a", 2.0 do |s| s.required_ruby_version = "< #{RUBY_VERSION}.a" s.platform = local end @@ -552,13 +550,13 @@ ERROR: Possible alternatives: non_existent_with_hint end end - assert_equal %w[a-2.0], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[a-2.0], @cmd.installed_specs.map(&:full_name) end def test_execute_required_ruby_version_specific_not_met spec_fetcher do |fetcher| - fetcher.gem 'a', '1.0' do |s| - s.required_ruby_version = '= 1.4.6' + fetcher.gem "a", "1.0" do |s| + s.required_ruby_version = "= 1.4.6" end end @@ -577,8 +575,8 @@ ERROR: Possible alternatives: non_existent_with_hint def test_execute_required_ruby_version_specific_prerelease_met spec_fetcher do |fetcher| - fetcher.gem 'a', '1.0' do |s| - s.required_ruby_version = '>= 1.4.6.preview2' + fetcher.gem "a", "1.0" do |s| + s.required_ruby_version = ">= 1.4.6.preview2" end end @@ -590,14 +588,14 @@ ERROR: Possible alternatives: non_existent_with_hint end end - assert_equal %w[a-1.0], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[a-1.0], @cmd.installed_specs.map(&:full_name) end def test_execute_required_ruby_version_specific_prerelease_not_met - next_ruby_pre = Gem.ruby_version.segments.map.with_index{|n, i| i == 1 ? n + 1 : n }.join(".") + ".a" + next_ruby_pre = Gem.ruby_version.segments.map.with_index {|n, i| i == 1 ? n + 1 : n }.join(".") + ".a" spec_fetcher do |fetcher| - fetcher.gem 'a', '1.0' do |s| + fetcher.gem "a", "1.0" do |s| s.required_ruby_version = "> #{next_ruby_pre}" end end @@ -617,8 +615,8 @@ ERROR: Possible alternatives: non_existent_with_hint def test_execute_required_rubygems_version_wrong spec_fetcher do |fetcher| - fetcher.gem 'a', '1.0' do |s| - s.required_rubygems_version = '< 0' + fetcher.gem "a", "1.0" do |s| + s.required_rubygems_version = "< 0" end end @@ -637,7 +635,7 @@ ERROR: Possible alternatives: non_existent_with_hint def test_execute_rdoc specs = spec_fetcher do |fetcher| - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end Gem.done_installing(&Gem::RDoc.method(:generation_hook)) @@ -645,7 +643,7 @@ ERROR: Possible alternatives: non_existent_with_hint @cmd.options[:document] = %w[rdoc ri] @cmd.options[:domain] = :local - a2 = specs['a-2'] + a2 = specs["a-2"] FileUtils.mv a2.cache_file, @tempdir @cmd.options[:args] = %w[a] @@ -667,22 +665,22 @@ ERROR: Possible alternatives: non_existent_with_hint wait_for_child_process_to_exit - assert_path_exist File.join(a2.doc_dir, 'ri') - assert_path_exist File.join(a2.doc_dir, 'rdoc') + assert_path_exist File.join(a2.doc_dir, "ri") + assert_path_exist File.join(a2.doc_dir, "rdoc") end def test_execute_rdoc_with_path specs = spec_fetcher do |fetcher| - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end Gem.done_installing(&Gem::RDoc.method(:generation_hook)) @cmd.options[:document] = %w[rdoc ri] @cmd.options[:domain] = :local - @cmd.options[:install_dir] = 'whatever' + @cmd.options[:install_dir] = "whatever" - a2 = specs['a-2'] + a2 = specs["a-2"] FileUtils.mv a2.cache_file, @tempdir @cmd.options[:args] = %w[a] @@ -704,19 +702,19 @@ ERROR: Possible alternatives: non_existent_with_hint wait_for_child_process_to_exit - assert_path_exist 'whatever/doc/a-2', 'documentation not installed' + assert_path_exist "whatever/doc/a-2", "documentation not installed" end def test_execute_saves_build_args specs = spec_fetcher do |fetcher| - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end args = %w[--with-awesome=true --more-awesome=yes] Gem::Command.build_args = args - a2 = specs['a-2'] + a2 = specs["a-2"] FileUtils.mv a2.cache_file, @tempdir @cmd.options[:domain] = :local @@ -746,7 +744,7 @@ ERROR: Possible alternatives: non_existent_with_hint def test_execute_remote spec_fetcher do |fetcher| - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end @cmd.options[:args] = %w[a] @@ -757,7 +755,7 @@ ERROR: Possible alternatives: non_existent_with_hint end end - assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name) assert_match "1 gem installed", @ui.output end @@ -766,7 +764,7 @@ ERROR: Possible alternatives: non_existent_with_hint FileUtils.touch("a.gem") spec_fetcher do |fetcher| - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end @cmd.options[:args] = %w[a] @@ -777,21 +775,54 @@ ERROR: Possible alternatives: non_existent_with_hint end end - assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name) assert_match "1 gem installed", @ui.output end + def test_execute_remote_truncates_existing_gemspecs + spec_fetcher do |fetcher| + fetcher.gem "a", 1 + end + + @cmd.options[:domain] = :remote + + @cmd.options[:args] = %w[a] + + use_ui @ui do + assert_raise Gem::MockGemUi::SystemExitException, @ui.error do + @cmd.execute + end + end + + assert_equal %w[a-1], @cmd.installed_specs.map(&:full_name) + assert_match "1 gem installed", @ui.output + + a1_gemspec = File.join(@gemhome, "specifications", "a-1.gemspec") + + initial_a1_gemspec_content = File.read(a1_gemspec) + modified_a1_gemspec_content = initial_a1_gemspec_content + "\n # AAAAAAA\n" + File.write(a1_gemspec, modified_a1_gemspec_content) + + use_ui @ui do + assert_raise Gem::MockGemUi::SystemExitException, @ui.error do + @cmd.execute + end + end + + assert_equal initial_a1_gemspec_content, File.read(a1_gemspec) + end + def test_execute_remote_ignores_files specs = spec_fetcher do |fetcher| - fetcher.gem 'a', 1 - fetcher.gem 'a', 2 + fetcher.gem "a", 1 + fetcher.gem "a", 2 end @cmd.options[:domain] = :remote - a1 = specs['a-1'] - a2 = specs['a-2'] + a1 = specs["a-1"] + a2 = specs["a-2"] FileUtils.mv a2.cache_file, @tempdir @@ -800,7 +831,7 @@ ERROR: Possible alternatives: non_existent_with_hint @cmd.options[:args] = [a2.name] - gemdir = File.join @gemhome, 'specifications' + gemdir = File.join @gemhome, "specifications" a2_gemspec = File.join(gemdir, "a-2.gemspec") a1_gemspec = File.join(gemdir, "a-1.gemspec") @@ -818,7 +849,7 @@ ERROR: Possible alternatives: non_existent_with_hint end end - assert_equal %w[a-1], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[a-1], @cmd.installed_specs.map(&:full_name) assert_match "1 gem installed", @ui.output @@ -829,12 +860,12 @@ ERROR: Possible alternatives: non_existent_with_hint def test_execute_two specs = spec_fetcher do |fetcher| - fetcher.gem 'a', 2 - fetcher.gem 'b', 2 + fetcher.gem "a", 2 + fetcher.gem "b", 2 end - FileUtils.mv specs['a-2'].cache_file, @tempdir - FileUtils.mv specs['b-2'].cache_file, @tempdir + FileUtils.mv specs["a-2"].cache_file, @tempdir + FileUtils.mv specs["b-2"].cache_file, @tempdir @cmd.options[:domain] = :local @@ -852,7 +883,7 @@ ERROR: Possible alternatives: non_existent_with_hint end end - assert_equal %w[a-2 b-2], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[a-2 b-2], @cmd.installed_specs.map(&:full_name) assert_match "2 gems installed", @ui.output end @@ -880,10 +911,10 @@ ERROR: Possible alternatives: non_existent_with_hint def test_execute_two_version_specified_by_colon spec_fetcher do |fetcher| - fetcher.gem 'a', 1 - fetcher.gem 'a', 2 - fetcher.gem 'b', 1 - fetcher.gem 'b', 2 + fetcher.gem "a", 1 + fetcher.gem "a", 2 + fetcher.gem "b", 1 + fetcher.gem "b", 2 end @cmd.options[:args] = %w[a:1 b:1] @@ -894,14 +925,14 @@ ERROR: Possible alternatives: non_existent_with_hint end end - assert_equal %w[a-1 b-1], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[a-1 b-1], @cmd.installed_specs.map(&:full_name) end def test_execute_conservative spec_fetcher do |fetcher| - fetcher.download 'b', 2 + fetcher.download "b", 2 - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end @cmd.options[:conservative] = true @@ -920,7 +951,7 @@ ERROR: Possible alternatives: non_existent_with_hint end end - assert_equal %w[b-2], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[b-2], @cmd.installed_specs.map(&:full_name) assert_equal "", @ui.error assert_match "1 gem installed", @ui.output @@ -932,7 +963,7 @@ ERROR: Possible alternatives: non_existent_with_hint done_installing = true end - spec = util_spec 'a', 2 + spec = util_spec "a", 2 util_build_gem spec @@ -940,44 +971,44 @@ ERROR: Possible alternatives: non_existent_with_hint @cmd.options[:ignore_dependencies] = true - @cmd.install_gem 'a', '>= 0' + @cmd.install_gem "a", ">= 0" - assert_equal %w[a-2], @cmd.installed_specs.map {|s| s.full_name } + assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name) - assert done_installing, 'documentation was not generated' + assert done_installing, "documentation was not generated" end def test_install_gem_ignore_dependencies_remote spec_fetcher do |fetcher| - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end @cmd.options[:ignore_dependencies] = true - @cmd.install_gem 'a', '>= 0' + @cmd.install_gem "a", ">= 0" - assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name) end def test_install_gem_ignore_dependencies_remote_platform_local local = Gem::Platform.local spec_fetcher do |fetcher| - fetcher.gem 'a', 3 + fetcher.gem "a", 3 - fetcher.gem 'a', 3 do |s| + fetcher.gem "a", 3 do |s| s.platform = local end end @cmd.options[:ignore_dependencies] = true - @cmd.install_gem 'a', '>= 0' + @cmd.install_gem "a", ">= 0" - assert_equal %W[a-3-#{local}], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %W[a-3-#{local}], @cmd.installed_specs.map(&:full_name) end def test_install_gem_ignore_dependencies_specific_file - spec = util_spec 'a', 2 + spec = util_spec "a", 2 util_build_gem spec @@ -987,13 +1018,13 @@ ERROR: Possible alternatives: non_existent_with_hint @cmd.install_gem File.join(@tempdir, spec.file_name), nil - assert_equal %w[a-2], @cmd.installed_specs.map {|s| s.full_name } + assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name) end def test_parses_requirement_from_gemname spec_fetcher do |fetcher| - fetcher.gem 'a', 2 - fetcher.gem 'b', 2 + fetcher.gem "a", 2 + fetcher.gem "b", 2 end @cmd.options[:domain] = :local @@ -1016,7 +1047,7 @@ ERROR: Possible alternatives: non_existent_with_hint end assert_equal 2, e.exit_code - assert_match %r{Could not find a valid gem 'a' \(= 10.0\)}, @ui.error + assert_match(/Could not find a valid gem 'a' \(= 10.0\)/, @ui.error) end def test_show_errors_on_failure @@ -1039,12 +1070,12 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal 2, e.exit_code - assert_match 'Unable to download data', @ui.error + assert_match "Unable to download data", @ui.error end def test_show_source_problems_even_on_success spec_fetcher do |fetcher| - fetcher.download 'a', 2 + fetcher.download "a", 2 end Gem.sources << "http://nonexistent.example" @@ -1057,7 +1088,7 @@ ERROR: Possible alternatives: non_existent_with_hint end end - assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name) assert_match "1 gem installed", @ui.output @@ -1067,9 +1098,34 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal x, e end + def test_redact_credentials_from_uri_on_warning + spec_fetcher do |fetcher| + fetcher.download "a", 2 + end + + Gem.sources << "http://username:SECURE_TOKEN@nonexistent.example" + + @cmd.options[:args] = %w[a] + + use_ui @ui do + assert_raise Gem::MockGemUi::SystemExitException, @ui.error do + @cmd.execute + end + end + + assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name) + + assert_match "1 gem installed", @ui.output + + e = @ui.error + + x = "WARNING: Unable to pull data from 'http://username:REDACTED@nonexistent.example': no data for http://username:REDACTED@nonexistent.example/specs.4.8.gz (http://username:REDACTED@nonexistent.example/specs.4.8.gz)\n" + assert_equal x, e + end + def test_execute_uses_from_a_gemdeps spec_fetcher do |fetcher| - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end File.open @gemdeps, "w" do |f| @@ -1084,7 +1140,7 @@ ERROR: Possible alternatives: non_existent_with_hint end end - assert_equal %w[], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[], @cmd.installed_specs.map(&:full_name) assert_match "Using a (2)", @ui.output assert File.exist?("#{@gemdeps}.lock") @@ -1092,7 +1148,7 @@ ERROR: Possible alternatives: non_existent_with_hint def test_execute_uses_from_a_gemdeps_with_no_lock spec_fetcher do |fetcher| - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end File.open @gemdeps, "w" do |f| @@ -1108,7 +1164,7 @@ ERROR: Possible alternatives: non_existent_with_hint end end - assert_equal %w[], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[], @cmd.installed_specs.map(&:full_name) assert_match "Using a (2)", @ui.output assert !File.exist?("#{@gemdeps}.lock") @@ -1116,8 +1172,8 @@ ERROR: Possible alternatives: non_existent_with_hint def test_execute_installs_from_a_gemdeps_with_conservative spec_fetcher do |fetcher| - fetcher.download 'a', 2 - fetcher.gem 'a', 1 + fetcher.download "a", 2 + fetcher.gem "a", 1 end File.open @gemdeps, "w" do |f| @@ -1133,14 +1189,14 @@ ERROR: Possible alternatives: non_existent_with_hint end end - assert_equal %w[], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[], @cmd.installed_specs.map(&:full_name) assert_match "Using a (1)", @ui.output end def test_execute_installs_from_a_gemdeps spec_fetcher do |fetcher| - fetcher.download 'a', 2 + fetcher.download "a", 2 end File.open @gemdeps, "w" do |f| @@ -1155,15 +1211,15 @@ ERROR: Possible alternatives: non_existent_with_hint end end - assert_equal %w[a-2], @cmd.installed_specs.map {|spec| spec.full_name } + assert_equal %w[a-2], @cmd.installed_specs.map(&:full_name) assert_match "Installing a (2)", @ui.output end def test_execute_installs_deps_a_gemdeps spec_fetcher do |fetcher| - fetcher.download 'q', '1.0' - fetcher.download 'r', '2.0', 'q' => nil + fetcher.download "q", "1.0" + fetcher.download "r", "2.0", "q" => nil end File.open @gemdeps, "w" do |f| @@ -1178,7 +1234,7 @@ ERROR: Possible alternatives: non_existent_with_hint end end - names = @cmd.installed_specs.map {|spec| spec.full_name } + names = @cmd.installed_specs.map(&:full_name) assert_equal %w[q-1.0 r-2.0], names @@ -1188,9 +1244,9 @@ ERROR: Possible alternatives: non_existent_with_hint def test_execute_uses_deps_a_gemdeps spec_fetcher do |fetcher| - fetcher.download 'r', '2.0', 'q' => nil + fetcher.download "r", "2.0", "q" => nil - fetcher.spec 'q', '1.0' + fetcher.spec "q", "1.0" end File.open @gemdeps, "w" do |f| @@ -1205,7 +1261,7 @@ ERROR: Possible alternatives: non_existent_with_hint end end - names = @cmd.installed_specs.map {|spec| spec.full_name } + names = @cmd.installed_specs.map(&:full_name) assert_equal %w[r-2.0], names @@ -1215,8 +1271,8 @@ ERROR: Possible alternatives: non_existent_with_hint def test_execute_installs_deps_a_gemdeps_into_a_path spec_fetcher do |fetcher| - fetcher.download 'q', '1.0' - fetcher.download 'r', '2.0', 'q' => nil + fetcher.download "q", "1.0" + fetcher.download "r", "2.0", "q" => nil end File.open @gemdeps, "w" do |f| @@ -1232,7 +1288,7 @@ ERROR: Possible alternatives: non_existent_with_hint end end - names = @cmd.installed_specs.map {|spec| spec.full_name } + names = @cmd.installed_specs.map(&:full_name) assert_equal %w[q-1.0 r-2.0], names @@ -1245,11 +1301,11 @@ ERROR: Possible alternatives: non_existent_with_hint def test_execute_with_gemdeps_path_ignores_system specs = spec_fetcher do |fetcher| - fetcher.download 'q', '1.0' - fetcher.download 'r', '2.0', 'q' => nil + fetcher.download "q", "1.0" + fetcher.download "r", "2.0", "q" => nil end - install_specs specs['q-1.0'] + install_specs specs["q-1.0"] File.open @gemdeps, "w" do |f| f << "gem 'r'" @@ -1264,7 +1320,7 @@ ERROR: Possible alternatives: non_existent_with_hint end end - names = @cmd.installed_specs.map {|spec| spec.full_name } + names = @cmd.installed_specs.map(&:full_name) assert_equal %w[q-1.0 r-2.0], names @@ -1277,11 +1333,11 @@ ERROR: Possible alternatives: non_existent_with_hint def test_execute_uses_deps_a_gemdeps_with_a_path specs = spec_fetcher do |fetcher| - fetcher.gem 'q', '1.0' - fetcher.gem 'r', '2.0', 'q' => nil + fetcher.gem "q", "1.0" + fetcher.gem "r", "2.0", "q" => nil end - i = Gem::Installer.at specs['q-1.0'].cache_file, :install_dir => "gf-path" + i = Gem::Installer.at specs["q-1.0"].cache_file, install_dir: "gf-path" i.install assert File.file?("gf-path/specifications/q-1.0.gemspec"), "not installed" @@ -1299,7 +1355,7 @@ ERROR: Possible alternatives: non_existent_with_hint end end - names = @cmd.installed_specs.map {|spec| spec.full_name } + names = @cmd.installed_specs.map(&:full_name) assert_equal %w[r-2.0], names @@ -1308,39 +1364,39 @@ ERROR: Possible alternatives: non_existent_with_hint end def test_handle_options_file - FileUtils.touch 'Gemfile' + FileUtils.touch "Gemfile" @cmd.handle_options %w[-g Gemfile] - assert_equal 'Gemfile', @cmd.options[:gemdeps] + assert_equal "Gemfile", @cmd.options[:gemdeps] - FileUtils.rm 'Gemfile' + FileUtils.rm "Gemfile" - FileUtils.touch 'gem.deps.rb' + FileUtils.touch "gem.deps.rb" @cmd.handle_options %w[--file gem.deps.rb] - assert_equal 'gem.deps.rb', @cmd.options[:gemdeps] + assert_equal "gem.deps.rb", @cmd.options[:gemdeps] - FileUtils.rm 'gem.deps.rb' + FileUtils.rm "gem.deps.rb" - FileUtils.touch 'Isolate' + FileUtils.touch "Isolate" @cmd.handle_options %w[-g] - assert_equal 'Isolate', @cmd.options[:gemdeps] + assert_equal "Isolate", @cmd.options[:gemdeps] - FileUtils.touch 'Gemfile' + FileUtils.touch "Gemfile" @cmd.handle_options %w[-g] - assert_equal 'Gemfile', @cmd.options[:gemdeps] + assert_equal "Gemfile", @cmd.options[:gemdeps] - FileUtils.touch 'gem.deps.rb' + FileUtils.touch "gem.deps.rb" @cmd.handle_options %w[-g] - assert_equal 'gem.deps.rb', @cmd.options[:gemdeps] + assert_equal "gem.deps.rb", @cmd.options[:gemdeps] end def test_handle_options_suggest @@ -1368,9 +1424,9 @@ ERROR: Possible alternatives: non_existent_with_hint def test_explain_platform_local local = Gem::Platform.local spec_fetcher do |fetcher| - fetcher.spec 'a', 2 + fetcher.spec "a", 2 - fetcher.spec 'a', 2 do |s| + fetcher.spec "a", 2 do |s| s.platform = local end end @@ -1394,9 +1450,9 @@ ERROR: Possible alternatives: non_existent_with_hint def test_explain_platform_local_ignore_dependencies local = Gem::Platform.local spec_fetcher do |fetcher| - fetcher.spec 'a', 3 + fetcher.spec "a", 3 - fetcher.spec 'a', 3 do |s| + fetcher.spec "a", 3 do |s| s.platform = local end end @@ -1421,9 +1477,9 @@ ERROR: Possible alternatives: non_existent_with_hint def test_explain_platform_ruby local = Gem::Platform.local spec_fetcher do |fetcher| - fetcher.spec 'a', 2 + fetcher.spec "a", 2 - fetcher.spec 'a', 2 do |s| + fetcher.spec "a", 2 do |s| s.platform = local end end @@ -1450,9 +1506,9 @@ ERROR: Possible alternatives: non_existent_with_hint def test_explain_platform_ruby_ignore_dependencies local = Gem::Platform.local spec_fetcher do |fetcher| - fetcher.spec 'a', 3 + fetcher.spec "a", 3 - fetcher.spec 'a', 3 do |s| + fetcher.spec "a", 3 do |s| s.platform = local end end @@ -1476,4 +1532,22 @@ ERROR: Possible alternatives: non_existent_with_hint assert_equal " a-3", out.shift assert_empty out end + + def test_suggest_update_if_enabled + TestUpdateSuggestion.with_eligible_environment(cmd: @cmd) do + spec_fetcher do |fetcher| + fetcher.gem "a", 2 + end + + @cmd.options[:args] = %w[a] + + use_ui @ui do + assert_raise Gem::MockGemUi::SystemExitException, @ui.error do + @cmd.execute + end + end + + assert_includes @ui.output, "A new release of RubyGems is available: 1.2.3 → 2.0.0!" + end + end end diff --git a/test/rubygems/test_gem_commands_list_command.rb b/test/rubygems/test_gem_commands_list_command.rb index 772a99eabd..c83dd51b67 100644 --- a/test/rubygems/test_gem_commands_list_command.rb +++ b/test/rubygems/test_gem_commands_list_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/list_command' + +require_relative "helper" +require "rubygems/commands/list_command" class TestGemCommandsListCommand < Gem::TestCase def setup @@ -9,7 +10,7 @@ class TestGemCommandsListCommand < Gem::TestCase @cmd = Gem::Commands::ListCommand.new spec_fetcher do |fetcher| - fetcher.spec 'c', 1 + fetcher.spec "c", 1 end @fetcher.data["#{@gem_repo}Marshal.#{Gem.marshal_version}"] = proc do @@ -27,6 +28,6 @@ class TestGemCommandsListCommand < Gem::TestCase end assert_equal "true\n", @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error end end diff --git a/test/rubygems/test_gem_commands_lock_command.rb b/test/rubygems/test_gem_commands_lock_command.rb index 81252e6409..6afe4f35c5 100644 --- a/test/rubygems/test_gem_commands_lock_command.rb +++ b/test/rubygems/test_gem_commands_lock_command.rb @@ -1,18 +1,19 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/lock_command' + +require_relative "helper" +require "rubygems/commands/lock_command" class TestGemCommandsLockCommand < Gem::TestCase def setup super - @a1 = quick_gem 'a', '1' - @b1 = quick_gem 'b', '1' do |s| - s.add_runtime_dependency 'a' + @a1 = quick_gem "a", "1" + @b1 = quick_gem "b", "1" do |s| + s.add_runtime_dependency "a" end - @d1 = quick_gem 'd', '1' do |s| - s.add_runtime_dependency 'z' + @d1 = quick_gem "d", "1" do |s| + s.add_runtime_dependency "z" end @cmd = Gem::Commands::LockCommand.new @@ -32,7 +33,7 @@ gem 'a', '= 1' EXPECTED assert_equal expected, @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error end def test_execute_missing_dependency @@ -49,7 +50,7 @@ gem 'd', '= 1' EXPECTED assert_equal expected, @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error end def test_execute_strict @@ -61,6 +62,6 @@ gem 'd', '= 1' end end - assert_equal 'Could not find gem c-1, try using the full name', e.message + assert_equal "Could not find gem c-1, try using the full name", e.message end end diff --git a/test/rubygems/test_gem_commands_mirror.rb b/test/rubygems/test_gem_commands_mirror.rb index 6b2b7d11bb..2256a3ab33 100644 --- a/test/rubygems/test_gem_commands_mirror.rb +++ b/test/rubygems/test_gem_commands_mirror.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/mirror_command' + +require_relative "helper" +require "rubygems/commands/mirror_command" class TestGemCommandsMirrorCommand < Gem::TestCase def setup @@ -14,6 +15,6 @@ class TestGemCommandsMirrorCommand < Gem::TestCase @cmd.execute end - assert_match %r{Install the rubygems-mirror}i, @ui.error + assert_match(/Install the rubygems-mirror/i, @ui.error) end end diff --git a/test/rubygems/test_gem_commands_open_command.rb b/test/rubygems/test_gem_commands_open_command.rb index 2c32b810cc..d9e518048c 100644 --- a/test/rubygems/test_gem_commands_open_command.rb +++ b/test/rubygems/test_gem_commands_open_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/open_command' + +require_relative "helper" +require "rubygems/commands/open_command" class TestGemCommandsOpenCommand < Gem::TestCase def setup @@ -21,20 +22,23 @@ class TestGemCommandsOpenCommand < Gem::TestCase def test_execute @cmd.options[:args] = %w[foo] - @cmd.options[:editor] = "#{Gem.ruby} -e0 --" + @cmd.options[:editor] = (ruby_with_rubygems_in_load_path + ["-e", "puts(ARGV,Dir.pwd)", "--"]).join(" ") - gem 'foo', '1.0.0' - spec = gem 'foo', '1.0.1' + gem "foo", "1.0.0" + spec = gem "foo", "1.0.1" assert_nothing_raised Gem::MockGemUi::TermError do - Dir.stub(:chdir, spec.full_gem_path) do + stdout, stderr = capture_subprocess_io do use_ui @ui do @cmd.execute end end + assert_equal [spec.full_gem_path, spec.full_gem_path], stdout.split("\n") + assert_equal "", stderr end assert_equal "", @ui.error + assert_equal "", @ui.output end def test_wrong_version @@ -49,7 +53,7 @@ class TestGemCommandsOpenCommand < Gem::TestCase end end - assert_match %r{Unable to find gem 'foo'}, @ui.output + assert_match(/Unable to find gem 'foo'/, @ui.output) assert_equal "", @ui.error end @@ -62,7 +66,7 @@ class TestGemCommandsOpenCommand < Gem::TestCase end end - assert_match %r{Unable to find gem 'foo'}, @ui.output + assert_match(/Unable to find gem 'foo'/, @ui.output) assert_equal "", @ui.error end @@ -91,7 +95,7 @@ class TestGemCommandsOpenCommand < Gem::TestCase end end - assert_match %r{'foo' is a default gem and can't be opened\.} , @ui.output + assert_match(/'foo' is a default gem and can't be opened\./, @ui.output) assert_equal "", @ui.error end end diff --git a/test/rubygems/test_gem_commands_outdated_command.rb b/test/rubygems/test_gem_commands_outdated_command.rb index c4af421f5d..3e61033af3 100644 --- a/test/rubygems/test_gem_commands_outdated_command.rb +++ b/test/rubygems/test_gem_commands_outdated_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/outdated_command' + +require_relative "helper" +require "rubygems/commands/outdated_command" class TestGemCommandsOutdatedCommand < Gem::TestCase def setup @@ -15,10 +16,10 @@ class TestGemCommandsOutdatedCommand < Gem::TestCase def test_execute spec_fetcher do |fetcher| - fetcher.download 'foo', '1.0' - fetcher.download 'foo', '2.0' - fetcher.gem 'foo', '0.1' - fetcher.gem 'foo', '0.2' + fetcher.download "foo", "1.0" + fetcher.download "foo", "2.0" + fetcher.gem "foo", "0.1" + fetcher.gem "foo", "0.2" end use_ui @ui do @@ -31,10 +32,10 @@ class TestGemCommandsOutdatedCommand < Gem::TestCase def test_execute_with_up_to_date_platform_specific_gem spec_fetcher do |fetcher| - fetcher.download 'foo', '2.0' + fetcher.download "foo", "2.0" - fetcher.gem 'foo', '1.0' - fetcher.gem 'foo', '2.0' do |s| + fetcher.gem "foo", "1.0" + fetcher.gem "foo", "2.0" do |s| s.platform = Gem::Platform.local end end diff --git a/test/rubygems/test_gem_commands_owner_command.rb b/test/rubygems/test_gem_commands_owner_command.rb index a98a48f6ea..eddd8afaf5 100644 --- a/test/rubygems/test_gem_commands_owner_command.rb +++ b/test/rubygems/test_gem_commands_owner_command.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/owner_command' + +require_relative "helper" +require_relative "multifactor_auth_utilities" +require "rubygems/commands/owner_command" class TestGemCommandsOwnerCommand < Gem::TestCase def setup @@ -10,7 +12,7 @@ class TestGemCommandsOwnerCommand < Gem::TestCase ENV["RUBYGEMS_HOST"] = nil @stub_ui = Gem::MockGemUi.new - @stub_fetcher = Gem::FakeFetcher.new + @stub_fetcher = Gem::MultifactorAuthFetcher.new Gem::RemoteFetcher.fetcher = @stub_fetcher Gem.configuration = nil Gem.configuration.rubygems_api_key = "ed244fbf2b1a52e012da8616c512fa47f9aa5250" @@ -36,24 +38,24 @@ class TestGemCommandsOwnerCommand < Gem::TestCase - id: 4 EOF - @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners.yaml"] = [response, 200, 'OK'] + @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners.yaml"] = HTTPResponseFactory.create(body: response, code: 200, msg: "OK") use_ui @stub_ui do @cmd.show_owners("freewill") end - assert_equal Net::HTTP::Get, @stub_fetcher.last_request.class + assert_equal Gem::Net::HTTP::Get, @stub_fetcher.last_request.class assert_equal Gem.configuration.rubygems_api_key, @stub_fetcher.last_request["Authorization"] - assert_match %r{Owners for gem: freewill}, @stub_ui.output - assert_match %r{- user1@example.com}, @stub_ui.output - assert_match %r{- user2@example.com}, @stub_ui.output - assert_match %r{- user3}, @stub_ui.output - assert_match %r{- 4}, @stub_ui.output + assert_match(/Owners for gem: freewill/, @stub_ui.output) + assert_match(/- user1@example.com/, @stub_ui.output) + assert_match(/- user2@example.com/, @stub_ui.output) + assert_match(/- user3/, @stub_ui.output) + assert_match(/- 4/, @stub_ui.output) end def test_show_owners_dont_load_objects - skip "testing a psych-only API" unless defined?(::Psych::DisallowedClass) + pend "testing a psych-only API" unless defined?(::Psych::DisallowedClass) response = <<EOF --- @@ -66,7 +68,7 @@ EOF - id: 4 EOF - @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners.yaml"] = [response, 200, 'OK'] + @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners.yaml"] = HTTPResponseFactory.create(body: response, code: 200, msg: "OK") assert_raise Psych::DisallowedClass do use_ui @ui do @@ -80,14 +82,14 @@ EOF host = "http://rubygems.example" ENV["RUBYGEMS_HOST"] = host - @stub_fetcher.data["#{host}/api/v1/gems/freewill/owners.yaml"] = [response, 200, 'OK'] + @stub_fetcher.data["#{host}/api/v1/gems/freewill/owners.yaml"] = HTTPResponseFactory.create(body: response, code: 200, msg: "OK") use_ui @stub_ui do @cmd.show_owners("freewill") end - assert_match %r{Owners for gem: freewill}, @stub_ui.output - assert_match %r{- user1@example.com}, @stub_ui.output + assert_match(/Owners for gem: freewill/, @stub_ui.output) + assert_match(/- user1@example.com/, @stub_ui.output) end def test_show_owners_setting_up_host @@ -95,19 +97,19 @@ EOF host = "http://rubygems.example" @cmd.host = host - @stub_fetcher.data["#{host}/api/v1/gems/freewill/owners.yaml"] = [response, 200, 'OK'] + @stub_fetcher.data["#{host}/api/v1/gems/freewill/owners.yaml"] = HTTPResponseFactory.create(body: response, code: 200, msg: "OK") use_ui @stub_ui do @cmd.show_owners("freewill") end - assert_match %r{Owners for gem: freewill}, @stub_ui.output - assert_match %r{- user1@example.com}, @stub_ui.output + assert_match(/Owners for gem: freewill/, @stub_ui.output) + assert_match(/- user1@example.com/, @stub_ui.output) end def test_show_owners_denied response = "You don't have permission to push to this gem" - @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners.yaml"] = [response, 403, 'Forbidden'] + @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners.yaml"] = HTTPResponseFactory.create(body: response, code: 403, msg: "Forbidden") assert_raise Gem::MockGemUi::TermError do use_ui @stub_ui do @@ -118,29 +120,52 @@ EOF assert_match response, @stub_ui.output end + def test_show_owners_permanent_redirect + host = "http://rubygems.example" + ENV["RUBYGEMS_HOST"] = host + path = "/api/v1/gems/freewill/owners.yaml" + redirected_uri = "https://rubygems.example#{path}" + + @stub_fetcher.data["#{host}#{path}"] = HTTPResponseFactory.create( + body: "", + code: "301", + msg: "Moved Permanently", + headers: { "location" => redirected_uri } + ) + + assert_raise Gem::MockGemUi::TermError do + use_ui @stub_ui do + @cmd.show_owners("freewill") + end + end + + response = "The request has redirected permanently to #{redirected_uri}. Please check your defined push host URL." + assert_match response, @stub_ui.output + end + def test_show_owners_key response = "- email: user1@example.com\n" - @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners.yaml"] = [response, 200, 'OK'] - File.open Gem.configuration.credentials_path, 'a' do |f| - f.write ':other: 701229f217cdf23b1344c7b4b54ca97' + @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners.yaml"] = HTTPResponseFactory.create(body: response, code: 200, msg: "OK") + File.open Gem.configuration.credentials_path, "a" do |f| + f.write ":other: 701229f217cdf23b1344c7b4b54ca97" end Gem.configuration.load_api_keys @cmd.handle_options %w[-k other] - @cmd.show_owners('freewill') + @cmd.show_owners("freewill") - assert_equal '701229f217cdf23b1344c7b4b54ca97', @stub_fetcher.last_request['Authorization'] + assert_equal "701229f217cdf23b1344c7b4b54ca97", @stub_fetcher.last_request["Authorization"] end def test_add_owners response = "Owner added successfully." - @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 200, 'OK'] + @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = HTTPResponseFactory.create(body: response, code: 200, msg: "OK") use_ui @stub_ui do @cmd.add_owners("freewill", ["user-new1@example.com"]) end - assert_equal Net::HTTP::Post, @stub_fetcher.last_request.class + assert_equal Gem::Net::HTTP::Post, @stub_fetcher.last_request.class assert_equal Gem.configuration.rubygems_api_key, @stub_fetcher.last_request["Authorization"] assert_equal "email=user-new1%40example.com", @stub_fetcher.last_request.body @@ -149,7 +174,7 @@ EOF def test_add_owners_denied response = "You don't have permission to push to this gem" - @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 403, 'Forbidden'] + @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = HTTPResponseFactory.create(body: response, code: 403, msg: "Forbidden") use_ui @stub_ui do @cmd.add_owners("freewill", ["user-new1@example.com"]) @@ -158,12 +183,33 @@ EOF assert_match response, @stub_ui.output end + def test_add_owners_permanent_redirect + host = "http://rubygems.example" + ENV["RUBYGEMS_HOST"] = host + path = "/api/v1/gems/freewill/owners" + redirected_uri = "https://rubygems.example#{path}" + + @stub_fetcher.data["#{host}#{path}"] = HTTPResponseFactory.create( + body: "", + code: "308", + msg: "Permanent Redirect", + headers: { "location" => redirected_uri } + ) + + use_ui @stub_ui do + @cmd.add_owners("freewill", ["user-new1@example.com"]) + end + + response = "The request has redirected permanently to #{redirected_uri}. Please check your defined push host URL." + assert_match response, @stub_ui.output + end + def test_add_owner_with_host_option_through_execute host = "http://rubygems.example" add_owner_response = "Owner added successfully." show_owners_response = "- email: user1@example.com\n" - @stub_fetcher.data["#{host}/api/v1/gems/freewill/owners"] = [add_owner_response, 200, 'OK'] - @stub_fetcher.data["#{host}/api/v1/gems/freewill/owners.yaml"] = [show_owners_response, 200, 'OK'] + @stub_fetcher.data["#{host}/api/v1/gems/freewill/owners"] = HTTPResponseFactory.create(body: add_owner_response, code: 200, msg: "OK") + @stub_fetcher.data["#{host}/api/v1/gems/freewill/owners.yaml"] = HTTPResponseFactory.create(body: show_owners_response, code: 200, msg: "OK") @cmd.handle_options %W[--host #{host} --add user-new1@example.com freewill] @@ -172,33 +218,33 @@ EOF end assert_match add_owner_response, @stub_ui.output - assert_match %r{Owners for gem: freewill}, @stub_ui.output - assert_match %r{- user1@example.com}, @stub_ui.output + assert_match(/Owners for gem: freewill/, @stub_ui.output) + assert_match(/- user1@example.com/, @stub_ui.output) end def test_add_owners_key response = "Owner added successfully." - @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 200, 'OK'] - File.open Gem.configuration.credentials_path, 'a' do |f| - f.write ':other: 701229f217cdf23b1344c7b4b54ca97' + @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = HTTPResponseFactory.create(body: response, code: 200, msg: "OK") + File.open Gem.configuration.credentials_path, "a" do |f| + f.write ":other: 701229f217cdf23b1344c7b4b54ca97" end Gem.configuration.load_api_keys @cmd.handle_options %w[-k other] - @cmd.add_owners('freewill', ['user-new1@example.com']) + @cmd.add_owners("freewill", ["user-new1@example.com"]) - assert_equal '701229f217cdf23b1344c7b4b54ca97', @stub_fetcher.last_request['Authorization'] + assert_equal "701229f217cdf23b1344c7b4b54ca97", @stub_fetcher.last_request["Authorization"] end def test_remove_owners response = "Owner removed successfully." - @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 200, 'OK'] + @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = HTTPResponseFactory.create(body: response, code: 200, msg: "OK") use_ui @stub_ui do @cmd.remove_owners("freewill", ["user-remove1@example.com"]) end - assert_equal Net::HTTP::Delete, @stub_fetcher.last_request.class + assert_equal Gem::Net::HTTP::Delete, @stub_fetcher.last_request.class assert_equal Gem.configuration.rubygems_api_key, @stub_fetcher.last_request["Authorization"] assert_equal "email=user-remove1%40example.com", @stub_fetcher.last_request.body @@ -207,32 +253,69 @@ EOF def test_remove_owners_denied response = "You don't have permission to push to this gem" - @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 403, 'Forbidden'] + @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = HTTPResponseFactory.create(body: response, code: 403, msg: "Forbidden") + + use_ui @stub_ui do + @cmd.remove_owners("freewill", ["user-remove1@example.com"]) + end + + assert_match response, @stub_ui.output + end + + def test_remove_owners_permanent_redirect + host = "http://rubygems.example" + ENV["RUBYGEMS_HOST"] = host + path = "/api/v1/gems/freewill/owners" + redirected_uri = "https://rubygems.example#{path}" + @stub_fetcher.data["#{host}#{path}"] = HTTPResponseFactory.create( + body: "", + code: "308", + msg: "Permanent Redirect", + headers: { "location" => redirected_uri } + ) use_ui @stub_ui do @cmd.remove_owners("freewill", ["user-remove1@example.com"]) end + response = "The request has redirected permanently to #{redirected_uri}. Please check your defined push host URL." + assert_match response, @stub_ui.output + + path = "/api/v1/gems/freewill/owners" + redirected_uri = "https://rubygems.example#{path}" + + @stub_fetcher.data["#{host}#{path}"] = HTTPResponseFactory.create( + body: "", + code: "308", + msg: "Permanent Redirect", + headers: { "location" => redirected_uri } + ) + + use_ui @stub_ui do + @cmd.add_owners("freewill", ["user-new1@example.com"]) + end + + response = "The request has redirected permanently to #{redirected_uri}. Please check your defined push host URL." assert_match response, @stub_ui.output end def test_remove_owners_key response = "Owner removed successfully." - @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 200, 'OK'] - File.open Gem.configuration.credentials_path, 'a' do |f| - f.write ':other: 701229f217cdf23b1344c7b4b54ca97' + @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = HTTPResponseFactory.create(body: response, code: 200, msg: "OK") + File.open Gem.configuration.credentials_path, "a" do |f| + f.write ":other: 701229f217cdf23b1344c7b4b54ca97" end Gem.configuration.load_api_keys @cmd.handle_options %w[-k other] - @cmd.remove_owners('freewill', ['user-remove1@example.com']) + @cmd.remove_owners("freewill", ["user-remove1@example.com"]) - assert_equal '701229f217cdf23b1344c7b4b54ca97', @stub_fetcher.last_request['Authorization'] + assert_equal "701229f217cdf23b1344c7b4b54ca97", @stub_fetcher.last_request["Authorization"] end def test_remove_owners_missing - response = 'Owner could not be found.' - @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 404, 'Not Found'] + response = "Owner could not be found." + @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = HTTPResponseFactory.create(body: response, code: 404, msg: "Not Found") use_ui @stub_ui do @cmd.remove_owners("freewill", ["missing@example"]) @@ -242,28 +325,25 @@ EOF end def test_otp_verified_success - response_fail = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry." response_success = "Owner added successfully." - - @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [ - [response_fail, 401, 'Unauthorized'], - [response_success, 200, 'OK'], - ] + @stub_fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems/freewill/owners", response_success) @otp_ui = Gem::MockGemUi.new "111111\n" use_ui @otp_ui do @cmd.add_owners("freewill", ["user-new1@example.com"]) end - assert_match 'You have enabled multi-factor authentication. Please enter OTP code.', @otp_ui.output - assert_match 'Code: ', @otp_ui.output + assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @otp_ui.output + assert_match "Code: ", @otp_ui.output assert_match response_success, @otp_ui.output - assert_equal '111111', @stub_fetcher.last_request['OTP'] + assert_equal "111111", @stub_fetcher.last_request["OTP"] end def test_otp_verified_failure response = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry." - @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [response, 401, 'Unauthorized'] + @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = HTTPResponseFactory.create(body: response, code: 401, msg: "Unauthorized") + @stub_fetcher.data["#{Gem.host}/api/v1/webauthn_verification"] = + HTTPResponseFactory.create(body: "You don't have any security devices", code: 422, msg: "Unprocessable Entity") @otp_ui = Gem::MockGemUi.new "111111\n" use_ui @otp_ui do @@ -271,9 +351,106 @@ EOF end assert_match response, @otp_ui.output - assert_match 'You have enabled multi-factor authentication. Please enter OTP code.', @otp_ui.output - assert_match 'Code: ', @otp_ui.output - assert_equal '111111', @stub_fetcher.last_request['OTP'] + assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @otp_ui.output + assert_match "Code: ", @otp_ui.output + assert_equal "111111", @stub_fetcher.last_request["OTP"] + end + + def test_with_webauthn_enabled_success + response_success = "Owner added successfully." + server = Gem::MockTCPServer.new + + @stub_fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems/freewill/owners", response_success) + @stub_fetcher.respond_with_webauthn_url + + TCPServer.stub(:new, server) do + Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:otp] = "Uvh6T57tkWuUnWYo" }) do + use_ui @stub_ui do + @cmd.add_owners("freewill", ["user-new1@example.com"]) + end + end + end + + assert_match "You have enabled multi-factor authentication. Please visit #{@stub_fetcher.webauthn_url_with_port(server.port)} " \ + "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \ + "you can re-run the gem signin command with the `--otp [your_code]` option.", @stub_ui.output + assert_match "You are verified with a security device. You may close the browser window.", @stub_ui.output + assert_equal "Uvh6T57tkWuUnWYo", @stub_fetcher.last_request["OTP"] + assert_match response_success, @stub_ui.output + end + + def test_with_webauthn_enabled_failure + response_success = "Owner added successfully." + server = Gem::MockTCPServer.new + error = Gem::WebauthnVerificationError.new("Something went wrong") + + @stub_fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems/freewill/owners", response_success) + @stub_fetcher.respond_with_webauthn_url + + TCPServer.stub(:new, server) do + Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:error] = error }) do + use_ui @stub_ui do + @cmd.add_owners("freewill", ["user-new1@example.com"]) + end + end + end + + assert_match @stub_fetcher.last_request["Authorization"], Gem.configuration.rubygems_api_key + assert_match "You have enabled multi-factor authentication. Please visit #{@stub_fetcher.webauthn_url_with_port(server.port)} " \ + "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \ + "you can re-run the gem signin command with the `--otp [your_code]` option.", @stub_ui.output + assert_match "ERROR: Security device verification failed: Something went wrong", @stub_ui.error + refute_match "You are verified with a security device. You may close the browser window.", @stub_ui.output + refute_match response_success, @stub_ui.output + end + + def test_with_webauthn_enabled_success_with_polling + response_success = "Owner added successfully." + server = Gem::MockTCPServer.new + + @stub_fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems/freewill/owners", response_success) + @stub_fetcher.respond_with_webauthn_url + @stub_fetcher.respond_with_webauthn_polling("Uvh6T57tkWuUnWYo") + + TCPServer.stub(:new, server) do + use_ui @stub_ui do + @cmd.add_owners("freewill", ["user-new1@example.com"]) + end + end + + assert_match "You have enabled multi-factor authentication. Please visit #{@stub_fetcher.webauthn_url_with_port(server.port)} " \ + "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, you can re-run the gem signin " \ + "command with the `--otp [your_code]` option.", @stub_ui.output + assert_match "You are verified with a security device. You may close the browser window.", @stub_ui.output + assert_equal "Uvh6T57tkWuUnWYo", @stub_fetcher.last_request["OTP"] + assert_match response_success, @stub_ui.output + end + + def test_with_webauthn_enabled_failure_with_polling + response_success = "Owner added successfully." + server = Gem::MockTCPServer.new + + @stub_fetcher.respond_with_require_otp( + "#{Gem.host}/api/v1/gems/freewill/owners", + response_success + ) + @stub_fetcher.respond_with_webauthn_url + @stub_fetcher.respond_with_webauthn_polling_failure + + TCPServer.stub(:new, server) do + use_ui @stub_ui do + @cmd.add_owners("freewill", ["user-new1@example.com"]) + end + end + + assert_match @stub_fetcher.last_request["Authorization"], Gem.configuration.rubygems_api_key + assert_match "You have enabled multi-factor authentication. Please visit #{@stub_fetcher.webauthn_url_with_port(server.port)} " \ + "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, you can re-run the gem signin " \ + "command with the `--otp [your_code]` option.", @stub_ui.output + assert_match "ERROR: Security device verification failed: The token in the link you used has either expired " \ + "or been used already.", @stub_ui.error + refute_match "You are verified with a security device. You may close the browser window.", @stub_ui.output + refute_match response_success, @stub_ui.output end def test_remove_owners_unathorized_api_key @@ -281,10 +458,10 @@ EOF response_success = "Owner removed successfully." @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [ - [response_forbidden, 403, 'Forbidden'], - [response_success, 200, "OK"], + HTTPResponseFactory.create(body: response_forbidden, code: 403, msg: "Forbidden"), + HTTPResponseFactory.create(body: response_success, code: 200, msg: "OK"), ] - @stub_fetcher.data["#{Gem.host}/api/v1/api_key"] = ["", 200, "OK"] + @stub_fetcher.data["#{Gem.host}/api/v1/api_key"] = HTTPResponseFactory.create(body: "", code: 200, msg: "OK") @cmd.instance_variable_set :@scope, :remove_owner @stub_ui = Gem::MockGemUi.new "some@mail.com\npass\n" @@ -294,7 +471,7 @@ EOF access_notice = "The existing key doesn't have access of remove_owner on RubyGems.org. Please sign in to update access." assert_match access_notice, @stub_ui.output - assert_match "Email:", @stub_ui.output + assert_match "Username/email:", @stub_ui.output assert_match "Password:", @stub_ui.output assert_match "Added remove_owner scope to the existing API key", @stub_ui.output assert_match response_success, @stub_ui.output @@ -305,10 +482,10 @@ EOF response_success = "Owner added successfully." @stub_fetcher.data["#{Gem.host}/api/v1/gems/freewill/owners"] = [ - [response_forbidden, 403, 'Forbidden'], - [response_success, 200, "OK"], + HTTPResponseFactory.create(body: response_forbidden, code: 403, msg: "Forbidden"), + HTTPResponseFactory.create(body: response_success, code: 200, msg: "OK"), ] - @stub_fetcher.data["#{Gem.host}/api/v1/api_key"] = ["", 200, "OK"] + @stub_fetcher.data["#{Gem.host}/api/v1/api_key"] = HTTPResponseFactory.create(body: "", code: 200, msg: "OK") @cmd.instance_variable_set :@scope, :add_owner @stub_ui = Gem::MockGemUi.new "some@mail.com\npass\n" @@ -318,7 +495,7 @@ EOF access_notice = "The existing key doesn't have access of add_owner on RubyGems.org. Please sign in to update access." assert_match access_notice, @stub_ui.output - assert_match "Email:", @stub_ui.output + assert_match "Username/email:", @stub_ui.output assert_match "Password:", @stub_ui.output assert_match "Added add_owner scope to the existing API key", @stub_ui.output assert_match response_success, @stub_ui.output diff --git a/test/rubygems/test_gem_commands_pristine_command.rb b/test/rubygems/test_gem_commands_pristine_command.rb index 118b2334fc..a17d7837c9 100644 --- a/test/rubygems/test_gem_commands_pristine_command.rb +++ b/test/rubygems/test_gem_commands_pristine_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/pristine_command' + +require_relative "helper" +require "rubygems/commands/pristine_command" class TestGemCommandsPristineCommand < Gem::TestCase def setup @@ -11,29 +12,29 @@ class TestGemCommandsPristineCommand < Gem::TestCase end def test_execute - a = util_spec 'a' do |s| + a = util_spec "a" do |s| s.executables = %w[foo] s.files = %w[bin/foo lib/a.rb] end - write_file File.join(@tempdir, 'lib', 'a.rb') do |fp| + write_file File.join(@tempdir, "lib", "a.rb") do |fp| fp.puts "puts __FILE__" end - write_file File.join(@tempdir, 'bin', 'foo') do |fp| + write_file File.join(@tempdir, "bin", "foo") do |fp| fp.puts "#!/usr/bin/ruby" end install_gem a - foo_path = File.join @gemhome, 'gems', a.full_name, 'bin', 'foo' - a_rb_path = File.join @gemhome, 'gems', a.full_name, 'lib', 'a.rb' + 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!' + io.puts "I changed it!" end write_file a_rb_path do |io| - io.puts 'I changed it!' + io.puts "I changed it!" end @cmd.options[:args] = %w[a] @@ -53,7 +54,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase end def test_execute_user_install - FileUtils.chmod 0555, @gemhome + FileUtils.chmod 0o555, @gemhome a = util_spec "a" do |s| s.executables = %w[foo] @@ -98,22 +99,22 @@ class TestGemCommandsPristineCommand < Gem::TestCase assert_equal "Restored #{a.full_name}", out.shift assert_empty out, out.inspect ensure - FileUtils.chmod(0755, @gemhome) + FileUtils.chmod(0o755, @gemhome) end def test_execute_all - a = util_spec 'a' do |s| + a = util_spec "a" do |s| s.executables = %w[foo] end - write_file File.join(@tempdir, 'bin', 'foo') do |fp| + write_file File.join(@tempdir, "bin", "foo") do |fp| fp.puts "#!/usr/bin/ruby" end install_gem a - gem_bin = File.join @gemhome, 'gems', a.full_name, 'bin', 'foo' - gem_stub = File.join @gemhome, 'bin', 'foo' + 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 @@ -135,17 +136,17 @@ class TestGemCommandsPristineCommand < Gem::TestCase end def test_execute_env_shebang - a = util_spec 'a' do |s| + a = util_spec "a" do |s| s.executables = %w[foo] s.files = %w[bin/foo] end - write_file File.join(@tempdir, 'bin', 'foo') do |fp| + write_file File.join(@tempdir, "bin", "foo") do |fp| fp.puts "#!/usr/bin/ruby" end install_gem a - gem_exec = File.join @gemhome, 'bin', 'foo' + gem_exec = File.join @gemhome, "bin", "foo" FileUtils.rm gem_exec @@ -157,19 +158,19 @@ class TestGemCommandsPristineCommand < Gem::TestCase assert_path_exist gem_exec - ruby_exec = sprintf Gem.default_exec_format, 'ruby' + ruby_exec = format Gem.default_exec_format, "ruby" - bin_env = win_platform? ? "" : %w[/usr/bin/env /bin/env].find {|f| File.executable?(f) } + " " + bin_env = Gem.win_platform? ? "" : %w[/usr/bin/env /bin/env].find {|f| File.executable?(f) } + " " - assert_match %r{\A#!\s*#{bin_env}#{ruby_exec}}, File.read(gem_exec) + assert_match(/\A#!\s*#{bin_env}#{ruby_exec}/, File.read(gem_exec)) end def test_execute_extensions_explicit - a = util_spec 'a' do |s| - s.extensions << 'ext/a/extconf.rb' + a = util_spec "a" do |s| + s.extensions << "ext/a/extconf.rb" end - ext_path = File.join @tempdir, 'ext', 'a', 'extconf.rb' + ext_path = File.join @tempdir, "ext", "a", "extconf.rb" write_file ext_path do |io| io.write <<-'RUBY' File.open "Makefile", "w" do |f| @@ -180,7 +181,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase RUBY end - b = util_spec 'b' + b = util_spec "b" install_gem a install_gem b @@ -195,19 +196,67 @@ class TestGemCommandsPristineCommand < Gem::TestCase out = @ui.output.split "\n" - assert_equal 'Restoring gems to pristine condition...', out.shift - assert_equal 'Building native extensions. This could take a while...', + assert_equal "Restoring gems to pristine condition...", out.shift + assert_equal "Building native extensions. This could take a while...", out.shift assert_equal "Restored #{a.full_name}", out.shift assert_empty out, out.inspect end + def test_execute_extensions_only_missing_extensions + a = util_spec "a" do |s| + s.extensions << "ext/a/extconf.rb" + end + + ext_path = File.join @tempdir, "ext", "a", "extconf.rb" + write_file ext_path do |io| + io.write <<-'RUBY' + File.open "Makefile", "w" do |f| + f.puts "clean:\n\techo cleaned\n" + f.puts "all:\n\techo built\n" + f.puts "install:\n\techo installed\n" + end + RUBY + end + + b = util_spec "b" do |s| + s.extensions << "ext/b/extconf.rb" + end + + ext_path = File.join @tempdir, "ext", "b", "extconf.rb" + write_file ext_path do |io| + io.write <<-'RUBY' + File.open "Makefile", "w" do |f| + f.puts "clean:\n\techo cleaned\n" + f.puts "all:\n\techo built\n" + f.puts "install:\n\techo installed\n" + end + RUBY + end + + install_gem a + install_gem b + + # Remove the extension files for b + FileUtils.rm_rf b.gem_build_complete_path + + @cmd.options[:only_missing_extensions] = true + @cmd.options[:args] = [] + + use_ui @ui do + @cmd.execute + end + + refute_includes @ui.output, "Restored #{a.full_name}" + assert_includes @ui.output, "Restored #{b.full_name}" + end + def test_execute_no_extension - a = util_spec 'a' do |s| - s.extensions << 'ext/a/extconf.rb' + a = util_spec "a" do |s| + s.extensions << "ext/a/extconf.rb" end - ext_path = File.join @tempdir, 'ext', 'a', 'extconf.rb' + ext_path = File.join @tempdir, "ext", "a", "extconf.rb" write_file ext_path do |io| io.write "# extconf.rb\nrequire 'mkmf'; create_makefile 'a'" end @@ -223,18 +272,18 @@ class TestGemCommandsPristineCommand < Gem::TestCase out = @ui.output.split "\n" - assert_equal 'Restoring gems to pristine condition...', out.shift + assert_equal "Restoring gems to pristine condition...", out.shift assert_equal "Skipped #{a.full_name}, it needs to compile an extension", out.shift assert_empty out, out.inspect end def test_execute_with_extension_with_build_args - a = util_spec 'a' do |s| - s.extensions << 'ext/a/extconf.rb' + a = util_spec "a" do |s| + s.extensions << "ext/a/extconf.rb" end - ext_path = File.join @tempdir, 'ext', 'a', 'extconf.rb' + ext_path = File.join @tempdir, "ext", "a", "extconf.rb" write_file ext_path do |io| io.write <<-'RUBY' File.open "Makefile", "w" do |f| @@ -247,7 +296,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase build_args = %w[--with-awesome=true --sweet] - install_gem a, :build_args => build_args + install_gem a, build_args: build_args @cmd.options[:args] = %w[a] @@ -257,7 +306,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase out = @ui.output.split "\n" - assert_equal 'Restoring gems to pristine condition...', out.shift + 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 @@ -265,8 +314,8 @@ class TestGemCommandsPristineCommand < Gem::TestCase end def test_execute_many - a = util_spec 'a' - b = util_spec 'b' + a = util_spec "a" + b = util_spec "b" install_gem a install_gem b @@ -286,14 +335,14 @@ class TestGemCommandsPristineCommand < Gem::TestCase end def test_skip - a = util_spec 'a' - b = util_spec 'b' + a = util_spec "a" + b = util_spec "b" install_gem a install_gem b @cmd.options[:args] = %w[a b] - @cmd.options[:skip] = 'a' + @cmd.options[:skip] = "a" use_ui @ui do @cmd.execute @@ -308,16 +357,16 @@ class TestGemCommandsPristineCommand < Gem::TestCase end def test_skip_many_gems - a = util_spec 'a' - b = util_spec 'b' - c = util_spec 'c' + a = util_spec "a" + b = util_spec "b" + c = util_spec "c" install_gem a install_gem b install_gem c @cmd.options[:args] = %w[a b c] - @cmd.options[:skip] = ['a', 'c'] + @cmd.options[:skip] = ["a", "c"] use_ui @ui do @cmd.execute @@ -333,16 +382,19 @@ class TestGemCommandsPristineCommand < Gem::TestCase end def test_execute_many_multi_repo - a = util_spec 'a' + a = util_spec "a" install_gem a Gem.clear_paths - gemhome2 = File.join @tempdir, 'gemhome2' + gemhome2 = File.join @tempdir, "gemhome2" Gem.use_paths gemhome2, [gemhome2, @gemhome] - b = util_spec 'b' + b = util_spec "b" install_gem b + assert_path_exist File.join(gemhome2, "gems", "b-2") + assert_path_not_exist File.join(@gemhome, "gems", "b-2") + @cmd.options[:args] = %w[a b] use_ui @ui do @@ -356,21 +408,21 @@ class TestGemCommandsPristineCommand < Gem::TestCase assert_equal "Restored #{b.full_name}", out.shift assert_empty out, out.inspect - assert_path_exist File.join(@gemhome, "gems", 'a-2') - assert_path_not_exist File.join(gemhome2, "gems", 'a-2') - assert_path_exist File.join(gemhome2, "gems", 'b-2') - assert_path_not_exist File.join(@gemhome, "gems", 'b-2') + assert_path_exist File.join(@gemhome, "gems", "a-2") + assert_path_not_exist File.join(gemhome2, "gems", "a-2") + assert_path_exist File.join(gemhome2, "gems", "b-2") + assert_path_not_exist File.join(@gemhome, "gems", "b-2") end def test_execute_missing_cache_gem specs = spec_fetcher do |fetcher| - fetcher.gem 'a', 1 - fetcher.gem 'a', 2 - fetcher.gem 'a', 3 - fetcher.gem 'a', '3.a' + fetcher.gem "a", 1 + fetcher.gem "a", 2 + fetcher.gem "a", 3 + fetcher.gem "a", "3.a" end - FileUtils.rm specs['a-2'].cache_file + FileUtils.rm specs["a-2"].cache_file @cmd.options[:args] = %w[a] @@ -396,22 +448,23 @@ class TestGemCommandsPristineCommand < Gem::TestCase def test_execute_missing_cache_gem_when_multi_repo specs = spec_fetcher do |fetcher| - fetcher.gem 'a', 1 - fetcher.gem 'b', 1 + fetcher.gem "a", 1 + fetcher.gem "b", 1 end - FileUtils.rm_rf File.join(@gemhome, 'gems', 'a-1') - FileUtils.rm_rf File.join(@gemhome, 'gems', 'b-1') + FileUtils.rm_rf File.join(@gemhome, "gems", "a-1") + FileUtils.rm_rf File.join(@gemhome, "gems", "b-1") install_gem specs["a-1"] - FileUtils.rm File.join(@gemhome, 'cache', 'a-1.gem') + FileUtils.rm File.join(@gemhome, "cache", "a-1.gem") Gem.clear_paths - gemhome2 = File.join(@tempdir, 'gemhome2') + gemhome2 = File.join(@tempdir, "gemhome2") Gem.use_paths gemhome2, [gemhome2, @gemhome] install_gem specs["b-1"] - FileUtils.rm File.join(gemhome2, 'cache', 'b-1.gem') + FileUtils.rm File.join(gemhome2, "cache", "b-1.gem") + Gem::Specification.reset @cmd.options[:args] = %w[a b] @@ -434,15 +487,15 @@ class TestGemCommandsPristineCommand < Gem::TestCase assert_empty out, out.inspect assert_empty @ui.error - assert_path_exist File.join(@gemhome, "cache", 'a-1.gem') - assert_path_not_exist File.join(gemhome2, "cache", 'a-2.gem') - assert_path_exist File.join(@gemhome, "gems", 'a-1') - assert_path_not_exist File.join(gemhome2, "gems", 'a-1') + assert_path_exist File.join(@gemhome, "cache", "a-1.gem") + assert_path_not_exist File.join(gemhome2, "cache", "a-2.gem") + assert_path_exist File.join(@gemhome, "gems", "a-1") + assert_path_not_exist File.join(gemhome2, "gems", "a-1") - assert_path_exist File.join(gemhome2, "cache", 'b-1.gem') - assert_path_not_exist File.join(@gemhome, "cache", 'b-2.gem') - assert_path_exist File.join(gemhome2, "gems", 'b-1') - assert_path_not_exist File.join(@gemhome, "gems", 'b-1') + assert_path_exist File.join(gemhome2, "cache", "b-1.gem") + assert_path_not_exist File.join(@gemhome, "cache", "b-2.gem") + assert_path_exist File.join(gemhome2, "gems", "b-1") + assert_path_not_exist File.join(@gemhome, "gems", "b-1") end def test_execute_no_gem @@ -454,25 +507,25 @@ class TestGemCommandsPristineCommand < Gem::TestCase end end - assert_match %r{at least one gem name}, e.message + assert_match(/at least one gem name/, e.message) end def test_execute_only_executables - a = util_spec 'a' do |s| + a = util_spec "a" do |s| s.executables = %w[foo] s.files = %w[bin/foo lib/a.rb] end - write_file File.join(@tempdir, 'lib', 'a.rb') do |fp| + write_file File.join(@tempdir, "lib", "a.rb") do |fp| fp.puts "puts __FILE__" end - write_file File.join(@tempdir, 'bin', 'foo') do |fp| + 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' + 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 @@ -488,25 +541,25 @@ class TestGemCommandsPristineCommand < Gem::TestCase end def test_execute_only_plugins - a = util_spec 'a' do |s| + a = util_spec "a" do |s| s.executables = %w[foo] s.files = %w[bin/foo lib/a.rb lib/rubygems_plugin.rb] end - write_file File.join(@tempdir, 'lib', 'a.rb') do |fp| + write_file File.join(@tempdir, "lib", "a.rb") do |fp| fp.puts "puts __FILE__" end - write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |fp| - fp.puts "puts __FILE__" + write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |fp| + fp.puts "# do nothing" end - write_file File.join(@tempdir, 'bin', 'foo') do |fp| + 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_plugin = File.join @gemhome, 'plugins', 'a_plugin.rb' - gem_exec = File.join @gemhome, 'bin', 'foo' + gem_lib = File.join @gemhome, "gems", a.full_name, "lib", "a.rb" + gem_plugin = File.join @gemhome, "plugins", "a_plugin.rb" + gem_exec = File.join @gemhome, "bin", "foo" FileUtils.rm gem_exec FileUtils.rm gem_plugin @@ -524,29 +577,29 @@ class TestGemCommandsPristineCommand < Gem::TestCase end def test_execute_bindir - a = util_spec 'a' do |s| + a = util_spec "a" do |s| s.name = "test_gem" s.executables = %w[foo] s.files = %w[bin/foo] end - write_file File.join(@tempdir, 'bin', 'foo') do |fp| + write_file File.join(@tempdir, "bin", "foo") do |fp| fp.puts "#!/usr/bin/ruby" end - write_file File.join(@tempdir, 'test_bin', 'foo') do |fp| + write_file File.join(@tempdir, "test_bin", "foo") do |fp| fp.puts "#!/usr/bin/ruby" end install_gem a - gem_exec = File.join @gemhome, 'bin', 'foo' - gem_bindir = File.join @tempdir, 'test_bin', 'foo' + gem_exec = File.join @gemhome, "bin", "foo" + gem_bindir = File.join @tempdir, "test_bin", "foo" FileUtils.rm gem_exec FileUtils.rm gem_bindir - @cmd.handle_options ["--all", "--only-executables", "--bindir", "#{gem_bindir}"] + @cmd.handle_options ["--all", "--only-executables", "--bindir", gem_bindir.to_s] use_ui @ui do @cmd.execute @@ -557,7 +610,7 @@ class TestGemCommandsPristineCommand < Gem::TestCase end def test_execute_unknown_gem_at_remote_source - install_specs util_spec 'a' + install_specs util_spec "a" @cmd.options[:args] = %w[a] @@ -596,16 +649,16 @@ class TestGemCommandsPristineCommand < Gem::TestCase end def test_execute_multi_platform - a = util_spec 'a' do |s| - s.extensions << 'ext/a/extconf.rb' + a = util_spec "a" do |s| + s.extensions << "ext/a/extconf.rb" end - b = util_spec 'b' do |s| - s.extensions << 'ext/a/extconf.rb' + b = util_spec "b" do |s| + s.extensions << "ext/a/extconf.rb" s.platform = Gem::Platform.new("java") end - ext_path = File.join @tempdir, 'ext', 'a', 'extconf.rb' + ext_path = File.join @tempdir, "ext", "a", "extconf.rb" write_file ext_path do |io| io.write <<-'RUBY' File.open "Makefile", "w" do |f| @@ -631,8 +684,8 @@ class TestGemCommandsPristineCommand < Gem::TestCase out = @ui.output.split "\n" - assert_equal 'Restoring gems to pristine condition...', out.shift - assert_equal 'Building native extensions. This could take a while...', + assert_equal "Restoring gems to pristine condition...", out.shift + assert_equal "Building native extensions. This could take a while...", out.shift assert_equal "Restored #{a.full_name}", out.shift assert_empty out, out.inspect diff --git a/test/rubygems/test_gem_commands_push_command.rb b/test/rubygems/test_gem_commands_push_command.rb index 4f0feabfa7..a7a18ff4ab 100644 --- a/test/rubygems/test_gem_commands_push_command.rb +++ b/test/rubygems/test_gem_commands_push_command.rb @@ -1,6 +1,9 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/push_command' + +require_relative "helper" +require_relative "multifactor_auth_utilities" +require "rubygems/commands/push_command" +require "rubygems/config_file" class TestGemCommandsPushCommand < Gem::TestCase def setup @@ -12,7 +15,7 @@ class TestGemCommandsPushCommand < Gem::TestCase Gem.host = Gem::DEFAULT_HOST Gem.configuration.disable_default_gem_server = false - @gems_dir = File.join @tempdir, 'gems' + @gems_dir = File.join @tempdir, "gems" @cache_dir = File.join @gemhome, "cache" FileUtils.mkdir @gems_dir @@ -21,10 +24,10 @@ class TestGemCommandsPushCommand < Gem::TestCase "ed244fbf2b1a52e012da8616c512fa47f9aa5250" @spec, @path = util_gem "freewill", "1.0.0" - @host = 'https://rubygems.example' + @host = "https://rubygems.example" @api_key = Gem.configuration.rubygems_api_key - @fetcher = Gem::FakeFetcher.new + @fetcher = Gem::MultifactorAuthFetcher.new Gem::RemoteFetcher.fetcher = @fetcher @cmd = Gem::Commands::PushCommand.new @@ -55,9 +58,9 @@ class TestGemCommandsPushCommand < Gem::TestCase @cmd.send_gem(@path) end - assert_match %r{Pushing gem to #{@host}...}, @ui.output + assert_match(/Pushing gem to #{@host}.../, @ui.output) - assert_equal Net::HTTP::Post, @fetcher.last_request.class + assert_equal Gem::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"] @@ -68,32 +71,32 @@ class TestGemCommandsPushCommand < Gem::TestCase def test_execute @response = "Successfully registered gem: freewill (1.0.0)" - @fetcher.data["#{Gem.host}/api/v1/gems"] = [@response, 200, 'OK'] + @fetcher.data["#{Gem.host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK") @cmd.options[:args] = [@path] @cmd.execute - assert_equal Net::HTTP::Post, @fetcher.last_request.class + assert_equal Gem::Net::HTTP::Post, @fetcher.last_request.class assert_equal Gem.read_binary(@path), @fetcher.last_request.body assert_equal "application/octet-stream", @fetcher.last_request["Content-Type"] end def test_execute_host - host = 'https://other.example' + host = "https://other.example" @response = "Successfully registered gem: freewill (1.0.0)" - @fetcher.data["#{host}/api/v1/gems"] = [@response, 200, 'OK'] + @fetcher.data["#{host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK") @fetcher.data["#{Gem.host}/api/v1/gems"] = - ['fail', 500, 'Internal Server Error'] + ["fail", 500, "Internal Server Error"] @cmd.options[:host] = host @cmd.options[:args] = [@path] @cmd.execute - assert_equal Net::HTTP::Post, @fetcher.last_request.class + assert_equal Gem::Net::HTTP::Post, @fetcher.last_request.class assert_equal Gem.read_binary(@path), @fetcher.last_request.body assert_equal "application/octet-stream", @fetcher.last_request["Content-Type"] @@ -101,19 +104,19 @@ class TestGemCommandsPushCommand < Gem::TestCase def test_execute_allowed_push_host @spec, @path = util_gem "freebird", "1.0.1" do |spec| - spec.metadata['allowed_push_host'] = "https://privategemserver.example" + spec.metadata["allowed_push_host"] = "https://privategemserver.example" end @response = "Successfully registered gem: freewill (1.0.0)" - @fetcher.data["#{@spec.metadata['allowed_push_host']}/api/v1/gems"] = [@response, 200, 'OK'] + @fetcher.data["#{@spec.metadata["allowed_push_host"]}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK") @fetcher.data["#{Gem.host}/api/v1/gems"] = - ['fail', 500, 'Internal Server Error'] + ["fail", 500, "Internal Server Error"] @cmd.options[:args] = [@path] @cmd.execute - assert_equal Net::HTTP::Post, @fetcher.last_request.class + assert_equal Gem::Net::HTTP::Post, @fetcher.last_request.class assert_equal Gem.read_binary(@path), @fetcher.last_request.body assert_equal "application/octet-stream", @fetcher.last_request["Content-Type"] @@ -136,7 +139,7 @@ class TestGemCommandsPushCommand < Gem::TestCase 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'] + @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK") send_battery end @@ -145,33 +148,32 @@ class TestGemCommandsPushCommand < Gem::TestCase @host = "http://privategemserver.example" @spec, @path = util_gem "freebird", "1.0.1" do |spec| - spec.metadata['default_gem_server'] = @host + spec.metadata["default_gem_server"] = @host end @api_key = "EYKEY" keys = { - :rubygems_api_key => 'KEY', + :rubygems_api_key => "KEY", @host => @api_key, } - FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path - File.open Gem.configuration.credentials_path, 'w' do |f| - f.write keys.to_yaml + File.open Gem.configuration.credentials_path, "w" do |f| + f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys) 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'] + @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK") send_battery end def test_sending_gem @response = "Successfully registered gem: freewill (1.0.0)" - @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK'] + @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK") send_battery end @@ -180,26 +182,25 @@ class TestGemCommandsPushCommand < Gem::TestCase @host = "http://privategemserver.example" @spec, @path = util_gem "freebird", "1.0.1" do |spec| - spec.metadata['allowed_push_host'] = @host + spec.metadata["allowed_push_host"] = @host end @api_key = "PRIVKEY" keys = { - :rubygems_api_key => 'KEY', + :rubygems_api_key => "KEY", @host => @api_key, } - FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path - File.open Gem.configuration.credentials_path, 'w' do |f| - f.write keys.to_yaml + File.open Gem.configuration.credentials_path, "w" do |f| + f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys) 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'] + @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK") send_battery end @@ -207,14 +208,14 @@ class TestGemCommandsPushCommand < Gem::TestCase @host = "http://privategemserver.example" @spec, @path = util_gem "freebird", "1.0.1" do |spec| - spec.metadata['allowed_push_host'] = @host + spec.metadata["allowed_push_host"] = @host end @api_key = "PRIVKEY" ENV["GEM_HOST_API_KEY"] = "PRIVKEY" @response = "Successfully registered gem: freebird (1.0.1)" - @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, 'OK'] + @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK") send_battery end @@ -223,31 +224,30 @@ class TestGemCommandsPushCommand < Gem::TestCase @host = "http://user:password@privategemserver.example" @spec, @path = util_gem "freebird", "1.0.1" do |spec| - spec.metadata['allowed_push_host'] = @sanitized_host + spec.metadata["allowed_push_host"] = @sanitized_host end @api_key = "DOESNTMATTER" keys = { - :rubygems_api_key => @api_key, + rubygems_api_key: @api_key, } - FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path - File.open Gem.configuration.credentials_path, 'w' do |f| - f.write keys.to_yaml + File.open Gem.configuration.credentials_path, "w" do |f| + f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys) 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'] + @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK") send_battery end def test_sending_gem_to_disallowed_default_host @spec, @path = util_gem "freebird", "1.0.1" do |spec| - spec.metadata['allowed_push_host'] = "https://privategemserver.example" + spec.metadata["allowed_push_host"] = "https://privategemserver.example" end response = %(ERROR: "#{@host}" is not allowed by the gemspec, which only allows "https://privategemserver.example") @@ -264,19 +264,18 @@ class TestGemCommandsPushCommand < Gem::TestCase push_host = "https://privategemserver.example" @spec, @path = util_gem "freebird", "1.0.1" do |spec| - spec.metadata['allowed_push_host'] = push_host + spec.metadata["allowed_push_host"] = push_host end @api_key = "PRIVKEY" keys = { - :rubygems_api_key => 'KEY', + :rubygems_api_key => "KEY", @host => @api_key, } - FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path - File.open Gem.configuration.credentials_path, 'w' do |f| - f.write keys.to_yaml + File.open Gem.configuration.credentials_path, "w" do |f| + f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys) end Gem.configuration.load_api_keys @@ -295,8 +294,8 @@ class TestGemCommandsPushCommand < Gem::TestCase host = "http://privategemserver.example" @spec, @path = util_gem "freebird", "1.0.1" do |spec| - spec.metadata.delete('default_gem_server') - spec.metadata['allowed_push_host'] = host + spec.metadata.delete("default_gem_server") + spec.metadata["allowed_push_host"] = host end api_key = "PRIVKEY" @@ -305,23 +304,22 @@ class TestGemCommandsPushCommand < Gem::TestCase host => api_key, } - FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path - File.open Gem.configuration.credentials_path, 'w' do |f| - f.write keys.to_yaml + File.open Gem.configuration.credentials_path, "w" do |f| + f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys) 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'] + @fetcher.data["#{host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK") # do not set @host use_ui(@ui) { @cmd.send_gem(@path) } - assert_match %r{Pushing gem to #{host}...}, @ui.output + assert_match(/Pushing gem to #{host}.../, @ui.output) - assert_equal Net::HTTP::Post, @fetcher.last_request.class + assert_equal Gem::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"] @@ -330,6 +328,27 @@ class TestGemCommandsPushCommand < Gem::TestCase assert_match @response, @ui.output end + def test_sending_gem_to_host_permanent_redirect + @host = "http://rubygems.example" + redirected_uri = "https://rubygems.example/api/v1/gems" + @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create( + body: "", + code: 308, + msg: "Permanent Redirect", + headers: { "Location" => redirected_uri } + ) + + assert_raise Gem::MockGemUi::TermError do + use_ui @ui do + @cmd.instance_variable_set :@host, @host + @cmd.send_gem(@path) + end + end + + response = "The request has redirected permanently to #{redirected_uri}. Please check your defined push host URL." + assert_match response, @ui.output + end + def test_raises_error_with_no_arguments def @cmd.sign_in(*); end assert_raise Gem::CommandLineError do @@ -339,7 +358,7 @@ class TestGemCommandsPushCommand < Gem::TestCase def test_sending_gem_denied response = "You don't have permission to push to this gem" - @fetcher.data["#{@host}/api/v1/gems"] = [response, 403, 'Forbidden'] + @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: response, code: 403, msg: "Forbidden") @cmd.instance_variable_set :@host, @host assert_raise Gem::MockGemUi::TermError do @@ -353,9 +372,9 @@ class TestGemCommandsPushCommand < Gem::TestCase def test_sending_gem_key @response = "Successfully registered gem: freewill (1.0.0)" - @fetcher.data["#{@host}/api/v1/gems"] = [@response, 200, "OK"] - File.open Gem.configuration.credentials_path, 'a' do |f| - f.write ':other: 701229f217cdf23b1344c7b4b54ca97' + @fetcher.data["#{@host}/api/v1/gems"] = HTTPResponseFactory.create(body: @response, code: 200, msg: "OK") + File.open Gem.configuration.credentials_path, "a" do |f| + f.write ":other: 701229f217cdf23b1344c7b4b54ca97" end Gem.configuration.load_api_keys @@ -368,28 +387,26 @@ class TestGemCommandsPushCommand < Gem::TestCase end def test_otp_verified_success - response_fail = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry." - response_success = 'Successfully registered gem: freewill (1.0.0)' + response_success = "Successfully registered gem: freewill (1.0.0)" - @fetcher.data["#{Gem.host}/api/v1/gems"] = [ - [response_fail, 401, 'Unauthorized'], - [response_success, 200, 'OK'], - ] + @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success) @otp_ui = Gem::MockGemUi.new "111111\n" use_ui @otp_ui do @cmd.send_gem(@path) end - assert_match 'You have enabled multi-factor authentication. Please enter OTP code.', @otp_ui.output - assert_match 'Code: ', @otp_ui.output + assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @otp_ui.output + assert_match "Code: ", @otp_ui.output assert_match response_success, @otp_ui.output - assert_equal '111111', @fetcher.last_request['OTP'] + assert_equal "111111", @fetcher.last_request["OTP"] end def test_otp_verified_failure response = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry." - @fetcher.data["#{Gem.host}/api/v1/gems"] = [response, 401, 'Unauthorized'] + @fetcher.data["#{Gem.host}/api/v1/gems"] = HTTPResponseFactory.create(body: response, code: 401, msg: "Unauthorized") + @fetcher.data["#{Gem.host}/api/v1/webauthn_verification"] = + HTTPResponseFactory.create(body: "You don't have any security devices", code: 422, msg: "Unprocessable Entity") @otp_ui = Gem::MockGemUi.new "111111\n" assert_raise Gem::MockGemUi::TermError do @@ -399,23 +416,125 @@ class TestGemCommandsPushCommand < Gem::TestCase end assert_match response, @otp_ui.output - assert_match 'You have enabled multi-factor authentication. Please enter OTP code.', @otp_ui.output - assert_match 'Code: ', @otp_ui.output - assert_equal '111111', @fetcher.last_request['OTP'] + assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @otp_ui.output + assert_match "Code: ", @otp_ui.output + assert_equal "111111", @fetcher.last_request["OTP"] + end + + def test_with_webauthn_enabled_success + response_success = "Successfully registered gem: freewill (1.0.0)" + server = Gem::MockTCPServer.new + + @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success) + @fetcher.respond_with_webauthn_url + + TCPServer.stub(:new, server) do + Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:otp] = "Uvh6T57tkWuUnWYo" }) do + use_ui @ui do + @cmd.send_gem(@path) + end + end + end + + assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \ + "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \ + "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output + assert_match "You are verified with a security device. You may close the browser window.", @ui.output + assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"] + assert_match response_success, @ui.output + end + + def test_with_webauthn_enabled_failure + response_success = "Successfully registered gem: freewill (1.0.0)" + server = Gem::MockTCPServer.new + error = Gem::WebauthnVerificationError.new("Something went wrong") + + @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success) + @fetcher.respond_with_webauthn_url + + error = assert_raise Gem::MockGemUi::TermError do + TCPServer.stub(:new, server) do + Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:error] = error }) do + use_ui @ui do + @cmd.send_gem(@path) + end + end + end + end + assert_equal 1, error.exit_code + + assert_match @fetcher.last_request["Authorization"], Gem.configuration.rubygems_api_key + assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \ + "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \ + "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output + assert_match "ERROR: Security device verification failed: Something went wrong", @ui.error + refute_match "You are verified with a security device. You may close the browser window.", @ui.output + refute_match response_success, @ui.output + end + + def test_with_webauthn_enabled_success_with_polling + response_success = "Successfully registered gem: freewill (1.0.0)" + server = Gem::MockTCPServer.new + + @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success) + @fetcher.respond_with_webauthn_url + @fetcher.respond_with_webauthn_polling("Uvh6T57tkWuUnWYo") + + TCPServer.stub(:new, server) do + use_ui @ui do + @cmd.send_gem(@path) + end + end + + assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \ + "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \ + "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output + assert_match "You are verified with a security device. You may close the browser window.", @ui.output + assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"] + assert_match response_success, @ui.output + end + + def test_with_webauthn_enabled_failure_with_polling + response_success = "Successfully registered gem: freewill (1.0.0)" + server = Gem::MockTCPServer.new + + @fetcher.respond_with_require_otp("#{Gem.host}/api/v1/gems", response_success) + @fetcher.respond_with_webauthn_url + @fetcher.respond_with_webauthn_polling_failure + + error = assert_raise Gem::MockGemUi::TermError do + TCPServer.stub(:new, server) do + use_ui @ui do + @cmd.send_gem(@path) + end + end + end + assert_equal 1, error.exit_code + + assert_match @fetcher.last_request["Authorization"], Gem.configuration.rubygems_api_key + assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \ + "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, you can re-run the gem signin " \ + "command with the `--otp [your_code]` option.", @ui.output + assert_match "ERROR: Security device verification failed: The token in the link you used has either expired " \ + "or been used already.", @ui.error + refute_match "You are verified with a security device. You may close the browser window.", @ui.output + refute_match response_success, @ui.output end def test_sending_gem_unathorized_api_key_with_mfa_enabled response_mfa_enabled = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry." response_forbidden = "The API key doesn't have access" - response_success = 'Successfully registered gem: freewill (1.0.0)' + response_success = "Successfully registered gem: freewill (1.0.0)" @fetcher.data["#{@host}/api/v1/gems"] = [ - [response_mfa_enabled, 401, 'Unauthorized'], - [response_forbidden, 403, 'Forbidden'], - [response_success, 200, "OK"], + HTTPResponseFactory.create(body: response_mfa_enabled, code: 401, msg: "Unauthorized"), + HTTPResponseFactory.create(body: response_forbidden, code: 403, msg: "Forbidden"), + HTTPResponseFactory.create(body: response_success, code: 200, msg: "OK"), ] + @fetcher.data["#{@host}/api/v1/webauthn_verification"] = + HTTPResponseFactory.create(body: "You don't have any security devices", code: 422, msg: "Unprocessable Entity") - @fetcher.data["#{@host}/api/v1/api_key"] = ["", 200, "OK"] + @fetcher.data["#{@host}/api/v1/api_key"] = HTTPResponseFactory.create(body: "", code: 200, msg: "OK") @cmd.instance_variable_set :@host, @host @cmd.instance_variable_set :@scope, :push_rubygem @@ -428,27 +547,34 @@ class TestGemCommandsPushCommand < Gem::TestCase access_notice = "The existing key doesn't have access of push_rubygem on https://rubygems.example. Please sign in to update access." assert_match mfa_notice, @ui.output assert_match access_notice, @ui.output - assert_match "Email:", @ui.output + assert_match "Username/email:", @ui.output assert_match "Password:", @ui.output assert_match "Added push_rubygem scope to the existing API key", @ui.output assert_match response_success, @ui.output - assert_equal '11111', @fetcher.last_request['OTP'] + assert_equal "11111", @fetcher.last_request["OTP"] end def test_sending_gem_with_no_local_creds Gem.configuration.rubygems_api_key = nil response_mfa_enabled = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry." - response_success = 'Successfully registered gem: freewill (1.0.0)' + response_success = "Successfully registered gem: freewill (1.0.0)" + response_profile = "mfa: disabled\n" @fetcher.data["#{@host}/api/v1/gems"] = [ - [response_success, 200, "OK"], + HTTPResponseFactory.create(body: response_success, code: 200, msg: "OK"), ] @fetcher.data["#{@host}/api/v1/api_key"] = [ - [response_mfa_enabled, 401, 'Unauthorized'], - ["", 200, "OK"], + HTTPResponseFactory.create(body: response_mfa_enabled, code: 401, msg: "Unauthorized"), + HTTPResponseFactory.create(body: "", code: 200, msg: "OK"), + ] + + @fetcher.data["#{@host}/api/v1/profile/me.yaml"] = [ + HTTPResponseFactory.create(body: response_profile, code: 200, msg: "OK"), ] + @fetcher.data["#{@host}/api/v1/webauthn_verification"] = + HTTPResponseFactory.create(body: "You don't have any security devices", code: 422, msg: "Unprocessable Entity") @cmd.instance_variable_set :@scope, :push_rubygem @cmd.options[:args] = [@path] @@ -462,11 +588,11 @@ class TestGemCommandsPushCommand < Gem::TestCase mfa_notice = "You have enabled multi-factor authentication. Please enter OTP code." assert_match mfa_notice, @ui.output assert_match "Enter your https://rubygems.example credentials.", @ui.output - assert_match "Email:", @ui.output + assert_match "Username/email:", @ui.output assert_match "Password:", @ui.output assert_match "Signed in with API key:", @ui.output assert_match response_success, @ui.output - assert_equal '11111', @fetcher.last_request['OTP'] + assert_equal "11111", @fetcher.last_request["OTP"] end private diff --git a/test/rubygems/test_gem_commands_query_command.rb b/test/rubygems/test_gem_commands_query_command.rb index cb95f185ab..8e590df124 100644 --- a/test/rubygems/test_gem_commands_query_command.rb +++ b/test/rubygems/test_gem_commands_query_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/query_command' + +require_relative "helper" +require "rubygems/commands/query_command" module TestGemCommandsQueryCommandSetup def setup @@ -22,9 +23,7 @@ class TestGemCommandsQueryCommandWithInstalledGems < Gem::TestCase include TestGemCommandsQueryCommandSetup def test_execute - spec_fetcher do |fetcher| - fetcher.legacy_platform - end + spec_fetcher(&:legacy_platform) @cmd.handle_options %w[-r] @@ -41,13 +40,11 @@ pl (1 i386-linux) EOF assert_equal expected, @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_all - spec_fetcher do |fetcher| - fetcher.legacy_platform - end + spec_fetcher(&:legacy_platform) @cmd.handle_options %w[-r --all] @@ -64,13 +61,11 @@ pl (1 i386-linux) EOF assert_equal expected, @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_all_prerelease - spec_fetcher do |fetcher| - fetcher.legacy_platform - end + spec_fetcher(&:legacy_platform) @cmd.handle_options %w[-r --all --prerelease] @@ -87,15 +82,15 @@ pl (1 i386-linux) EOF assert_equal expected, @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_details spec_fetcher do |fetcher| - fetcher.spec 'a', 2 do |s| - s.summary = 'This is a lot of text. ' * 4 - s.authors = ['Abraham Lincoln', 'Hirohito'] - s.homepage = 'http://a.example.com/' + fetcher.spec "a", 2 do |s| + s.summary = "This is a lot of text. " * 4 + s.authors = ["Abraham Lincoln", "Hirohito"] + s.homepage = "http://a.example.com/" end fetcher.legacy_platform @@ -127,13 +122,13 @@ pl (1) EOF assert_equal expected, @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_details_cleans_text spec_fetcher do |fetcher| - fetcher.spec 'a', 2 do |s| - s.summary = 'This is a lot of text. ' * 4 + fetcher.spec "a", 2 do |s| + s.summary = "This is a lot of text. " * 4 s.authors = ["Abraham Lincoln \x01", "\x02 Hirohito"] s.homepage = "http://a.example.com/\x03" end @@ -167,13 +162,13 @@ pl (1) EOF assert_equal expected, @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_details_truncates_summary spec_fetcher do |fetcher| - fetcher.spec 'a', 2 do |s| - s.summary = 'This is a lot of text. ' * 10_000 + fetcher.spec "a", 2 do |s| + s.summary = "This is a lot of text. " * 10_000 s.authors = ["Abraham Lincoln \x01", "\x02 Hirohito"] s.homepage = "http://a.example.com/\x03" end @@ -207,7 +202,7 @@ pl (1) EOF assert_equal expected, @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_installed @@ -220,7 +215,7 @@ pl (1) end assert_equal "true\n", @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_installed_inverse @@ -233,7 +228,7 @@ pl (1) end assert_equal "false\n", @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error assert_equal 1, e.exit_code end @@ -248,7 +243,7 @@ pl (1) end assert_equal "true\n", @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_installed_no_name @@ -260,7 +255,7 @@ pl (1) end end - assert_equal '', @stub_ui.output + assert_equal "", @stub_ui.output assert_equal "ERROR: You must specify a gem name\n", @stub_ui.error assert_equal 4, e.exit_code @@ -276,7 +271,7 @@ pl (1) end assert_equal "false\n", @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error assert_equal 1, e.exit_code end @@ -291,7 +286,7 @@ pl (1) end assert_equal "true\n", @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_installed_version_not_installed @@ -304,15 +299,13 @@ pl (1) end assert_equal "false\n", @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error assert_equal 1, e.exit_code end def test_execute_local - spec_fetcher do |fetcher| - fetcher.legacy_platform - end + spec_fetcher(&:legacy_platform) @cmd.options[:domain] = :local @@ -329,13 +322,11 @@ pl (1 i386-linux) EOF assert_equal expected, @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_local_notty - spec_fetcher do |fetcher| - fetcher.legacy_platform - end + spec_fetcher(&:legacy_platform) @cmd.handle_options %w[] @@ -351,13 +342,11 @@ pl (1 i386-linux) EOF assert_equal expected, @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_local_quiet - spec_fetcher do |fetcher| - fetcher.legacy_platform - end + spec_fetcher(&:legacy_platform) @cmd.options[:domain] = :local Gem.configuration.verbose = false @@ -372,13 +361,11 @@ pl (1 i386-linux) EOF assert_equal expected, @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_no_versions - spec_fetcher do |fetcher| - fetcher.legacy_platform - end + spec_fetcher(&:legacy_platform) @cmd.handle_options %w[-r --no-versions] @@ -395,13 +382,11 @@ pl EOF assert_equal expected, @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_notty - spec_fetcher do |fetcher| - fetcher.legacy_platform - end + spec_fetcher(&:legacy_platform) @cmd.handle_options %w[-r] @@ -417,7 +402,7 @@ pl (1 i386-linux) EOF assert_equal expected, @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_prerelease @@ -435,13 +420,11 @@ a (3.a) EOF assert_equal expected, @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_prerelease_local - spec_fetcher do |fetcher| - fetcher.legacy_platform - end + spec_fetcher(&:legacy_platform) @cmd.handle_options %w[-l --prerelease] @@ -461,9 +444,7 @@ pl (1 i386-linux) end def test_execute_no_prerelease_local - spec_fetcher do |fetcher| - fetcher.legacy_platform - end + spec_fetcher(&:legacy_platform) @cmd.handle_options %w[-l --no-prerelease] @@ -483,9 +464,7 @@ pl (1 i386-linux) end def test_execute_remote - spec_fetcher do |fetcher| - fetcher.legacy_platform - end + spec_fetcher(&:legacy_platform) @cmd.options[:domain] = :remote @@ -502,13 +481,11 @@ pl (1 i386-linux) EOF assert_equal expected, @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_remote_notty - spec_fetcher do |fetcher| - fetcher.legacy_platform - end + spec_fetcher(&:legacy_platform) @cmd.handle_options %w[] @@ -524,13 +501,11 @@ pl (1 i386-linux) EOF assert_equal expected, @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_remote_quiet - spec_fetcher do |fetcher| - fetcher.legacy_platform - end + spec_fetcher(&:legacy_platform) @cmd.options[:domain] = :remote Gem.configuration.verbose = false @@ -545,16 +520,16 @@ pl (1 i386-linux) EOF assert_equal expected, @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_make_entry - a_2_name = @specs['a-2'].original_name + a_2_name = @specs["a-2"].original_name @stub_fetcher.data.delete \ "#{@gem_repo}quick/Marshal.#{Gem.marshal_version}/#{a_2_name}.gemspec.rz" - a2 = @specs['a-2'] + a2 = @specs["a-2"] entry_tuples = [ [Gem::NameTuple.new(a2.name, a2.version, a2.platform), Gem.sources.first], @@ -564,14 +539,12 @@ pl (1 i386-linux) entry = @cmd.send :make_entry, entry_tuples, platforms - assert_equal 'a (2)', entry + assert_equal "a (2)", entry end # Test for multiple args handling! def test_execute_multiple_args - spec_fetcher do |fetcher| - fetcher.legacy_platform - end + spec_fetcher(&:legacy_platform) @cmd.handle_options %w[a pl] @@ -579,9 +552,9 @@ pl (1 i386-linux) @cmd.execute end - assert_match %r{^a }, @stub_ui.output - assert_match %r{^pl }, @stub_ui.output - assert_equal '', @stub_ui.error + assert_match(/^a /, @stub_ui.output) + assert_match(/^pl /, @stub_ui.output) + assert_equal "", @stub_ui.error end def test_show_gems @@ -592,8 +565,8 @@ pl (1 i386-linux) @cmd.send :show_gems, /a/i end - assert_match %r{^a }, @stub_ui.output - refute_match %r{^pl }, @stub_ui.output + assert_match(/^a /, @stub_ui.output) + refute_match(/^pl /, @stub_ui.output) assert_empty @stub_ui.error end @@ -601,9 +574,9 @@ pl (1 i386-linux) def add_gems_to_fetcher spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', 2 - fetcher.spec 'a', '3.a' + fetcher.spec "a", 1 + fetcher.spec "a", 2 + fetcher.spec "a", "3.a" end end end @@ -613,13 +586,13 @@ class TestGemCommandsQueryCommandWithoutInstalledGems < Gem::TestCase def test_execute_platform spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', 1 do |s| - s.platform = 'x86-linux' + fetcher.spec "a", 1 + fetcher.spec "a", 1 do |s| + s.platform = "x86-linux" end - fetcher.spec 'a', 2 do |s| - s.platform = 'universal-darwin' + fetcher.spec "a", 2 do |s| + s.platform = "universal-darwin" end end @@ -637,13 +610,13 @@ a (2 universal-darwin, 1 ruby x86-linux) EOF assert_equal expected, @stub_ui.output - assert_equal '', @stub_ui.error + assert_equal "", @stub_ui.error end def test_execute_show_default_gems - spec_fetcher {|fetcher| fetcher.spec 'a', 2 } + spec_fetcher {|fetcher| fetcher.spec "a", 2 } - a1 = new_default_spec 'a', 1 + a1 = new_default_spec "a", 1 install_default_gems a1 use_ui @stub_ui do @@ -661,8 +634,8 @@ EOF end def test_execute_show_default_gems_with_platform - a1 = new_default_spec 'a', 1 - a1.platform = 'java' + a1 = new_default_spec "a", 1 + a1.platform = "java" install_default_gems a1 use_ui @stub_ui do @@ -681,10 +654,10 @@ EOF def test_execute_default_details spec_fetcher do |fetcher| - fetcher.spec 'a', 2 + fetcher.spec "a", 2 end - a1 = new_default_spec 'a', 1 + a1 = new_default_spec "a", 1 install_default_gems a1 @cmd.handle_options %w[-l -d] @@ -711,15 +684,15 @@ a (2, 1) def test_execute_local_details spec_fetcher do |fetcher| - fetcher.spec 'a', 1 do |s| - s.platform = 'x86-linux' + fetcher.spec "a", 1 do |s| + s.platform = "x86-linux" end - fetcher.spec 'a', 2 do |s| - s.summary = 'This is a lot of text. ' * 4 - s.authors = ['Abraham Lincoln', 'Hirohito'] - s.homepage = 'http://a.example.com/' - s.platform = 'universal-darwin' + fetcher.spec "a", 2 do |s| + s.summary = "This is a lot of text. " * 4 + s.authors = ["Abraham Lincoln", "Hirohito"] + s.homepage = "http://a.example.com/" + s.platform = "universal-darwin" end fetcher.legacy_platform @@ -766,9 +739,9 @@ pl (1) def test_execute_exact_remote spec_fetcher do |fetcher| - fetcher.spec 'coolgem-omg', 3 - fetcher.spec 'coolgem', '4.2.1' - fetcher.spec 'wow_coolgem', 1 + fetcher.spec "coolgem-omg", 3 + fetcher.spec "coolgem", "4.2.1" + fetcher.spec "wow_coolgem", 1 end @cmd.handle_options %w[--remote --exact coolgem] @@ -789,9 +762,9 @@ coolgem (4.2.1) def test_execute_exact_local spec_fetcher do |fetcher| - fetcher.spec 'coolgem-omg', 3 - fetcher.spec 'coolgem', '4.2.1' - fetcher.spec 'wow_coolgem', 1 + fetcher.spec "coolgem-omg", 3 + fetcher.spec "coolgem", "4.2.1" + fetcher.spec "wow_coolgem", 1 end @cmd.handle_options %w[--exact coolgem] @@ -812,13 +785,13 @@ coolgem (4.2.1) def test_execute_exact_multiple spec_fetcher do |fetcher| - fetcher.spec 'coolgem-omg', 3 - fetcher.spec 'coolgem', '4.2.1' - fetcher.spec 'wow_coolgem', 1 + fetcher.spec "coolgem-omg", 3 + fetcher.spec "coolgem", "4.2.1" + fetcher.spec "wow_coolgem", 1 - fetcher.spec 'othergem-omg', 3 - fetcher.spec 'othergem', '1.2.3' - fetcher.spec 'wow_othergem', 1 + fetcher.spec "othergem-omg", 3 + fetcher.spec "othergem", "1.2.3" + fetcher.spec "wow_othergem", 1 end @cmd.handle_options %w[--exact coolgem othergem] @@ -849,9 +822,9 @@ othergem (1.2.3) def add_gems_to_fetcher spec_fetcher do |fetcher| - fetcher.download 'a', 1 - fetcher.download 'a', 2 - fetcher.download 'a', '3.a' + fetcher.download "a", 1 + fetcher.download "a", 2 + fetcher.download "a", "3.a" end end end diff --git a/test/rubygems/test_gem_commands_rebuild_command.rb b/test/rubygems/test_gem_commands_rebuild_command.rb new file mode 100644 index 0000000000..5e8c797e2d --- /dev/null +++ b/test/rubygems/test_gem_commands_rebuild_command.rb @@ -0,0 +1,145 @@ +# frozen_string_literal: true + +require_relative "helper" +require "rubygems/commands/build_command" +require "rubygems/commands/rebuild_command" +require "rubygems/package" + +class TestGemCommandsRebuildCommand < Gem::TestCase + def setup + super + + readme_file = File.join(@tempdir, "README.md") + + begin + umask_orig = File.umask(2) + File.open readme_file, "w" do |f| + f.write "My awesome gem" + end + ensure + File.umask(umask_orig) + end + + @gem_name = "rebuild_test_gem" + @gem_version = "1.0.0" + @gem = util_spec @gem_name do |s| + s.version = @gem_version + s.license = "AGPL-3.0" + s.files = ["README.md"] + end + end + + def util_test_build_gem(gem, args) + @ui = Gem::MockGemUi.new + + cmd = Gem::Commands::BuildCommand.new + + cmd.options[:args] = args + cmd.options[:build_path] = @tempdir + use_ui @ui do + cmd.execute + end + gem_file = "#{@gem_name}-#{@gem_version}.gem" + output = @ui.output.split "\n" + assert_equal " Successfully built RubyGem", output.shift + assert_equal " Name: #{@gem_name}", output.shift + assert_equal " Version: #{@gem_version}", output.shift + assert_equal " File: #{gem_file}", output.shift + assert_equal [], output + + gem_file = File.join(@tempdir, gem_file) + assert File.exist?(gem_file) + + spec = Gem::Package.new(gem_file).spec + + assert_equal @gem_name, spec.name + assert_equal "this is a summary", spec.summary + gem_file + end + + def util_test_rebuild_gem(gem, args, original_gem_file, gemspec_file, timestamp) + @ui = Gem::MockGemUi.new + + cmd = Gem::Commands::RebuildCommand.new + + cmd.options[:args] = args + cmd.options[:original_gem_file] = original_gem_file + cmd.options[:build_path] = @tempdir + cmd.options[:gemspec_file] = gemspec_file + use_ui @ui do + cmd.execute + end + gem_file = "#{@gem_name}-#{@gem_version}.gem" + output = @ui.output.split "\n" + + assert_equal " Successfully built RubyGem", output.shift + assert_equal " Name: #{@gem_name}", output.shift + assert_equal " Version: #{@gem_version}", output.shift + assert_equal " File: #{gem_file}", output.shift + assert_empty output.shift + assert_match(/^Built at: .+ \(#{timestamp}\)/, output.shift) + original_line = output.shift + original = original_line.split(" ")[-1] + assert_match(/^Original build saved to: /, original_line) + reproduced_line = output.shift + reproduced = reproduced_line.split(" ")[-1] + assert_match(/^Reproduced build saved to: /, reproduced_line) + assert_equal "Working directory: #{@tempdir}", output.shift + assert_equal "", output.shift + assert_equal "Hash comparison:", output.shift + output.shift # " #{old_hash}\t#{old_file}" + output.shift # " #{new_hash}\t#{new_file}" + assert_empty output.shift + assert_equal "SUCCESS - original and rebuild hashes matched", output.shift + assert_equal [], output + + assert File.exist?(original) + assert File.exist?(reproduced) + + old_spec = Gem::Package.new(original).spec + new_spec = Gem::Package.new(reproduced).spec + + assert_equal @gem_name, old_spec.name + assert_equal "this is a summary", old_spec.summary + + assert_equal old_spec.name, new_spec.name + assert_equal old_spec.summary, new_spec.summary + + reproduced + end + + def test_build_is_reproducible + # Back up SOURCE_DATE_EPOCH to restore later. + epoch = ENV["SOURCE_DATE_EPOCH"] + + gemspec_file = File.join(@tempdir, @gem.spec_name) + + # Initial Build + + # Set SOURCE_DATE_EPOCH to 2001-02-03 04:05:06 -0500. + ENV["SOURCE_DATE_EPOCH"] = timestamp = Time.new(2001, 2, 3, 4, 5, 6).to_i.to_s + File.write(gemspec_file, @gem.to_ruby) + gem_file = util_test_build_gem @gem, [gemspec_file] + + build_contents = File.read(gem_file) + + gem_file_dir = File.dirname(gem_file) + gem_file_name = File.basename(gem_file) + original_gem_file = File.join(gem_file_dir, "original-" + gem_file_name) + File.rename(gem_file, original_gem_file) + + # Rebuild + + # Set SOURCE_DATE_EPOCH to a different value, meaning we are + # also testing that `gem rebuild` overrides the value. + ENV["SOURCE_DATE_EPOCH"] = Time.new(2007, 8, 9, 10, 11, 12).to_s + + rebuild_gem_file = util_test_rebuild_gem(@gem, [@gem_name, @gem_version], original_gem_file, gemspec_file, timestamp) + + rebuild_contents = File.read(rebuild_gem_file) + + assert_equal build_contents, rebuild_contents + ensure + ENV["SOURCE_DATE_EPOCH"] = epoch + end +end diff --git a/test/rubygems/test_gem_commands_search_command.rb b/test/rubygems/test_gem_commands_search_command.rb index 17693e6837..47aefa0cf7 100644 --- a/test/rubygems/test_gem_commands_search_command.rb +++ b/test/rubygems/test_gem_commands_search_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/search_command' + +require_relative "helper" +require "rubygems/commands/search_command" class TestGemCommandsSearchCommand < Gem::TestCase def setup diff --git a/test/rubygems/test_gem_commands_server_command.rb b/test/rubygems/test_gem_commands_server_command.rb index 36c1feaec2..cabb7cf49d 100644 --- a/test/rubygems/test_gem_commands_server_command.rb +++ b/test/rubygems/test_gem_commands_server_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/server_command' + +require_relative "helper" +require "rubygems/commands/server_command" class TestGemCommandsServerCommand < Gem::TestCase def setup @@ -9,53 +10,11 @@ class TestGemCommandsServerCommand < Gem::TestCase @cmd = Gem::Commands::ServerCommand.new end - def test_handle_options - @cmd.send :handle_options, %w[-p 8808 --no-daemon] - - assert_equal false, @cmd.options[:daemon] - assert_equal [], @cmd.options[:gemdir] - assert_equal 8808, @cmd.options[:port] - - @cmd.send :handle_options, %w[-p 9999 -d /nonexistent --daemon] - - assert_equal true, @cmd.options[:daemon] - assert_equal [File.expand_path('/nonexistent')], @cmd.options[:gemdir] - assert_equal 9999, @cmd.options[:port] - end - - def test_handle_options_gemdir - @cmd.send :handle_options, %w[--dir a --dir b] - - assert_equal [File.expand_path('a'), File.expand_path('b')], - @cmd.options[:gemdir] - end - - def test_handle_options_port - @cmd.send :handle_options, %w[-p 0] - assert_equal 0, @cmd.options[:port] - - @cmd.send :handle_options, %w[-p 65535] - assert_equal 65535, @cmd.options[:port] - - begin - @cmd.send :handle_options, %w[-p discard] - assert_equal 9, @cmd.options[:port] - rescue OptionParser::InvalidArgument - # for container environment on GitHub Actions - end - - e = assert_raise OptionParser::InvalidArgument do - @cmd.send :handle_options, %w[-p nonexistent] - end - - assert_equal 'invalid argument: -p nonexistent: no such named service', - e.message - - e = assert_raise OptionParser::InvalidArgument do - @cmd.send :handle_options, %w[-p 65536] + def test_execute + use_ui @ui do + @cmd.execute end - assert_equal 'invalid argument: -p 65536: not a port number', - e.message + assert_match(/Install the rubygems-server/i, @ui.error) end end diff --git a/test/rubygems/test_gem_commands_setup_command.rb b/test/rubygems/test_gem_commands_setup_command.rb index e324d25562..43f695f147 100644 --- a/test/rubygems/test_gem_commands_setup_command.rb +++ b/test/rubygems/test_gem_commands_setup_command.rb @@ -1,27 +1,26 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/setup_command' +require_relative "helper" +require "rubygems/commands/setup_command" class TestGemCommandsSetupCommand < Gem::TestCase - bundler_gemspec = File.expand_path("../../../bundler/lib/bundler/version.rb", __FILE__) + bundler_gemspec = File.expand_path("../../bundler/lib/bundler/version.rb", __dir__) if File.exist?(bundler_gemspec) BUNDLER_VERS = File.read(bundler_gemspec).match(/VERSION = "(#{Gem::Version::VERSION_PATTERN})"/)[1] else - BUNDLER_VERS = "2.0.1".freeze + BUNDLER_VERS = "2.0.1" end def setup super - @install_dir = File.join @tempdir, 'install' @cmd = Gem::Commands::SetupCommand.new - @cmd.options[:prefix] = @install_dir + @cmd.options[:document] = [] filelist = %w[ - bin/gem + exe/gem lib/rubygems.rb - lib/rubygems/test_case.rb + lib/rubygems/requirement.rb lib/rubygems/ssl_certs/rubygems.org/foo.pem bundler/exe/bundle bundler/exe/bundler @@ -32,23 +31,20 @@ class TestGemCommandsSetupCommand < Gem::TestCase bundler/lib/bundler/man/gemfile.5 bundler/lib/bundler/man/gemfile.5.ronn bundler/lib/bundler/templates/.circleci/config.yml - bundler/lib/bundler/templates/.travis.yml ] create_dummy_files(filelist) - gemspec = Gem::Specification.new - gemspec.author = "Us" - gemspec.name = "bundler" - gemspec.version = BUNDLER_VERS - gemspec.bindir = "exe" - gemspec.executables = ["bundle", "bundler"] + gemspec = util_spec "bundler", BUNDLER_VERS do |s| + s.bindir = "exe" + s.executables = ["bundle", "bundler"] + end - File.open 'bundler/bundler.gemspec', 'w' do |io| + File.open "bundler/bundler.gemspec", "w" do |io| io.puts gemspec.to_ruby end - File.open(File.join(Gem.default_specifications_dir, "bundler-1.15.4.gemspec"), 'w') do |io| + File.open(File.join(Gem.default_specifications_dir, "bundler-1.15.4.gemspec"), "w") do |io| gemspec.version = "1.15.4" io.puts gemspec.to_ruby end @@ -56,31 +52,29 @@ class TestGemCommandsSetupCommand < Gem::TestCase spec_fetcher do |fetcher| fetcher.download "bundler", "1.15.4" - fetcher.gem "bundler", BUNDLER_VERS + fetcher.gem "bundler", bundler_version fetcher.gem "bundler-audit", "1.0.0" end end def test_execute_regenerate_binstubs - gem_bin_path = gem_install 'a' + gem_bin_path = gem_install "a" write_file gem_bin_path do |io| - io.puts 'I changed it!' + io.puts "I changed it!" end - @cmd.options[:document] = [] @cmd.execute - assert_match %r{\A#!}, File.read(gem_bin_path) + assert_match(/\A#!/, File.read(gem_bin_path)) end def test_execute_no_regenerate_binstubs - gem_bin_path = gem_install 'a' + gem_bin_path = gem_install "a" write_file gem_bin_path do |io| - io.puts 'I changed it!' + io.puts "I changed it!" end - @cmd.options[:document] = [] @cmd.options[:regenerate_binstubs] = false @cmd.execute @@ -88,24 +82,22 @@ class TestGemCommandsSetupCommand < Gem::TestCase end def test_execute_regenerate_plugins - gem_plugin_path = gem_install_with_plugin 'a' + gem_plugin_path = gem_install_with_plugin "a" write_file gem_plugin_path do |io| - io.puts 'I changed it!' + io.puts "I changed it!" end - @cmd.options[:document] = [] @cmd.execute - assert_match %r{\Arequire}, File.read(gem_plugin_path) + assert_match(/\Arequire/, File.read(gem_plugin_path)) end def test_execute_no_regenerate_plugins - gem_plugin_path = gem_install_with_plugin 'a' + gem_plugin_path = gem_install_with_plugin "a" write_file gem_plugin_path do |io| - io.puts 'I changed it!' + io.puts "I changed it!" end - @cmd.options[:document] = [] @cmd.options[:regenerate_plugins] = false @cmd.execute @@ -113,20 +105,17 @@ class TestGemCommandsSetupCommand < Gem::TestCase end def test_execute_regenerate_plugins_creates_plugins_dir_if_not_there - gem_plugin_path = gem_install_with_plugin 'a' + gem_plugin_path = gem_install_with_plugin "a" # Simulate gem installed with an older rubygems without a plugins layout FileUtils.rm_rf Gem.plugindir - @cmd.options[:document] = [] @cmd.execute - assert_match %r{\Arequire}, File.read(gem_plugin_path) + assert_match(/\Arequire/, File.read(gem_plugin_path)) end def test_execute_informs_about_installed_executables - @cmd.options[:document] = [] - use_ui @ui do @cmd.execute end @@ -140,53 +129,63 @@ class TestGemCommandsSetupCommand < Gem::TestCase end def test_env_shebang_flag - gem_bin_path = gem_install 'a' + gem_bin_path = gem_install "a" write_file gem_bin_path do |io| - io.puts 'I changed it!' + io.puts "I changed it!" end - @cmd.options[:document] = [] @cmd.options[:env_shebang] = true @cmd.execute - ruby_exec = sprintf Gem.default_exec_format, 'ruby' + ruby_exec = format Gem.default_exec_format, "ruby" + + bin_env = Gem.win_platform? ? "" : %w[/usr/bin/env /bin/env].find {|f| File.executable?(f) } + " " + assert_match(/\A#!\s*#{bin_env}#{ruby_exec}/, File.read(default_gem_bin_path)) + assert_match(/\A#!\s*#{bin_env}#{ruby_exec}/, File.read(default_bundle_bin_path)) + assert_match(/\A#!\s*#{bin_env}#{ruby_exec}/, File.read(default_bundler_bin_path)) + assert_match(/\A#!\s*#{bin_env}#{ruby_exec}/, File.read(gem_bin_path)) + end + + def test_destdir_flag_does_not_try_to_write_to_the_default_gem_home + FileUtils.chmod "-w", File.join(@gemhome, "plugins") - bin_env = win_platform? ? "" : %w[/usr/bin/env /bin/env].find {|f| File.executable?(f) } + " " - assert_match %r{\A#!\s*#{bin_env}#{ruby_exec}}, File.read(default_gem_bin_path) - assert_match %r{\A#!\s*#{bin_env}#{ruby_exec}}, File.read(default_bundle_bin_path) - assert_match %r{\A#!\s*#{bin_env}#{ruby_exec}}, File.read(default_bundler_bin_path) - assert_match %r{\A#!\s*#{bin_env}#{ruby_exec}}, File.read(gem_bin_path) + destdir = File.join(@tempdir, "foo") + + @cmd.options[:destdir] = destdir + @cmd.execute + + bundler_spec.executables.each do |e| + assert_path_exist prepend_destdir(destdir, File.join(@gemhome, "gems", bundler_spec.full_name, bundler_spec.bindir, e)) + end end def test_files_in - assert_equal %w[rubygems.rb rubygems/ssl_certs/rubygems.org/foo.pem rubygems/test_case.rb], - @cmd.files_in('lib').sort + assert_equal %w[rubygems.rb rubygems/requirement.rb rubygems/ssl_certs/rubygems.org/foo.pem], + @cmd.files_in("lib").sort end def test_install_lib @cmd.extend FileUtils - Dir.mktmpdir 'lib' do |dir| + Dir.mktmpdir "lib" do |dir| @cmd.install_lib dir - assert_path_exist File.join(dir, 'rubygems.rb') - assert_path_exist File.join(dir, 'rubygems/ssl_certs/rubygems.org/foo.pem') + assert_path_exist File.join(dir, "rubygems.rb") + assert_path_exist File.join(dir, "rubygems/ssl_certs/rubygems.org/foo.pem") - assert_path_exist File.join(dir, 'bundler.rb') - assert_path_exist File.join(dir, 'bundler/b.rb') + assert_path_exist File.join(dir, "bundler.rb") + assert_path_exist File.join(dir, "bundler/b.rb") - assert_path_exist File.join(dir, 'bundler/templates/.circleci/config.yml') unless RUBY_ENGINE == "truffleruby" # https://github.com/oracle/truffleruby/issues/2116 - assert_path_exist File.join(dir, 'bundler/templates/.travis.yml') + assert_path_exist File.join(dir, "bundler/templates/.circleci/config.yml") end end def test_install_default_bundler_gem @cmd.extend FileUtils - bin_dir = File.join(@gemhome, 'bin') + bin_dir = File.join(@gemhome, "bin") @cmd.install_default_bundler_gem bin_dir - bundler_spec = Gem::Specification.load("bundler/bundler.gemspec") default_spec_path = File.join(Gem.default_specifications_dir, "#{bundler_spec.full_name}.gemspec") spec = Gem::Specification.load(default_spec_path) @@ -198,72 +197,126 @@ class TestGemCommandsSetupCommand < Gem::TestCase assert_path_exist File.join bin_dir, e end - default_dir = Gem.default_specifications_dir - # expect to remove other versions of bundler gemspecs on default specification directory. - assert_path_not_exist File.join(default_dir, "bundler-1.15.4.gemspec") - assert_path_exist File.join(default_dir, "bundler-#{BUNDLER_VERS}.gemspec") + assert_path_not_exist previous_bundler_specification_path + assert_path_exist new_bundler_specification_path # expect to not remove bundler-* gemspecs. assert_path_exist File.join(Gem.dir, "specifications", "bundler-audit-1.0.0.gemspec") # expect to remove normal gem that was same version. because it's promoted default gems. - assert_path_not_exist File.join(Gem.dir, "specifications", "bundler-#{BUNDLER_VERS}.gemspec") + assert_path_not_exist File.join(Gem.dir, "specifications", "bundler-#{bundler_version}.gemspec") - assert_path_exist "#{Gem.dir}/gems/bundler-#{BUNDLER_VERS}" + assert_path_exist "#{Gem.dir}/gems/bundler-#{bundler_version}" assert_path_exist "#{Gem.dir}/gems/bundler-1.15.4" assert_path_exist "#{Gem.dir}/gems/bundler-audit-1.0.0" end + def test_install_default_bundler_gem_with_default_gems_not_installed_at_default_dir + @cmd.extend FileUtils + + gemhome2 = File.join(@tempdir, "gemhome2") + Gem.instance_variable_set(:@default_dir, gemhome2) + + FileUtils.mkdir_p gemhome2 + bin_dir = File.join(gemhome2, "bin") + + @cmd.install_default_bundler_gem bin_dir + + # expect to remove other versions of bundler gemspecs on default specification directory. + assert_path_not_exist previous_bundler_specification_path + assert_path_exist new_bundler_specification_path + end + def test_install_default_bundler_gem_with_force_flag @cmd.extend FileUtils - bin_dir = File.join(@gemhome, 'bin') - bundle_bin = File.join(bin_dir, 'bundle') + bin_dir = File.join(@gemhome, "bin") + bundle_bin = File.join(bin_dir, "bundle") write_file bundle_bin do |f| - f.puts '#!/usr/bin/ruby' - f.puts '' + f.puts "#!/usr/bin/ruby" + f.puts "" f.puts 'echo "hello"' end - bindir(bin_dir) do - @cmd.options[:force] = true - - @cmd.install_default_bundler_gem bin_dir + @cmd.options[:force] = true - bundler_spec = Gem::Specification.load("bundler/bundler.gemspec") - default_spec_path = File.join(Gem.default_specifications_dir, "#{bundler_spec.full_name}.gemspec") - spec = Gem::Specification.load(default_spec_path) + @cmd.install_default_bundler_gem bin_dir - spec.executables.each do |e| - if Gem.win_platform? - assert_path_exist File.join(bin_dir, "#{e}.bat") - end + default_spec_path = File.join(Gem.default_specifications_dir, "#{bundler_spec.full_name}.gemspec") + spec = Gem::Specification.load(default_spec_path) - assert_path_exist File.join bin_dir, e + spec.executables.each do |e| + if Gem.win_platform? + assert_path_exist File.join(bin_dir, "#{e}.bat") end + + assert_path_exist File.join bin_dir, e + end + end + + def test_install_default_bundler_gem_with_destdir_flag + @cmd.extend FileUtils + + FileUtils.chmod "-w", @gemhome + + destdir = File.join(@tempdir, "foo") + bin_dir = File.join(destdir, "bin") + + @cmd.options[:destdir] = destdir + + @cmd.install_default_bundler_gem bin_dir + + # leaves other versions of bundler gemspecs on default specification directory. + assert_path_exist previous_bundler_specification_path + assert_path_not_exist new_bundler_specification_path + + # installs the updated bundler gemspec to destdir + assert_path_not_exist prepend_destdir(destdir, previous_bundler_specification_path) + assert_path_exist prepend_destdir(destdir, new_bundler_specification_path) + + bundler_spec.executables.each do |e| + assert_path_exist prepend_destdir(destdir, File.join(@gemhome, "gems", bundler_spec.full_name, bundler_spec.bindir, e)) + end + ensure + FileUtils.chmod "+w", @gemhome + end + + def test_install_default_bundler_gem_with_destdir_and_prefix_flags + @cmd.extend FileUtils + + destdir = File.join(@tempdir, "foo") + bin_dir = File.join(destdir, "bin") + + @cmd.options[:destdir] = destdir + @cmd.options[:prefix] = "/" + + @cmd.install_default_bundler_gem bin_dir + + bundler_spec.executables.each do |e| + assert_path_exist File.join destdir, "gems", bundler_spec.full_name, bundler_spec.bindir, e end end def test_remove_old_lib_files - lib = File.join @install_dir, 'lib' - lib_rubygems = File.join lib, 'rubygems' - lib_bundler = File.join lib, 'bundler' - lib_rubygems_defaults = File.join lib_rubygems, 'defaults' - lib_bundler_templates = File.join lib_bundler, 'templates' + lib = RbConfig::CONFIG["sitelibdir"] + lib_rubygems = File.join lib, "rubygems" + lib_bundler = File.join lib, "bundler" + lib_rubygems_defaults = File.join lib_rubygems, "defaults" + lib_bundler_templates = File.join lib_bundler, "templates" - securerandom_rb = File.join lib, 'securerandom.rb' + securerandom_rb = File.join lib, "securerandom.rb" - engine_defaults_rb = File.join lib_rubygems_defaults, 'jruby.rb' - os_defaults_rb = File.join lib_rubygems_defaults, 'operating_system.rb' + engine_defaults_rb = File.join lib_rubygems_defaults, "jruby.rb" + os_defaults_rb = File.join lib_rubygems_defaults, "operating_system.rb" - old_gauntlet_rubygems_rb = File.join lib, 'gauntlet_rubygems.rb' + old_gauntlet_rubygems_rb = File.join lib, "gauntlet_rubygems.rb" - old_builder_rb = File.join lib_rubygems, 'builder.rb' - old_format_rb = File.join lib_rubygems, 'format.rb' - old_bundler_c_rb = File.join lib_bundler, 'c.rb' - old_bundler_ci = File.join lib_bundler_templates, '.lecacy_ci', 'config.yml' + old_builder_rb = File.join lib_rubygems, "builder.rb" + old_format_rb = File.join lib_rubygems, "format.rb" + old_bundler_c_rb = File.join lib_bundler, "c.rb" + old_bundler_ci = File.join lib_bundler_templates, ".lecacy_ci", "config.yml" files_that_go = [old_gauntlet_rubygems_rb, old_builder_rb, old_format_rb, old_bundler_c_rb, old_bundler_ci] files_that_stay = [securerandom_rb, engine_defaults_rb, os_defaults_rb] @@ -272,21 +325,21 @@ class TestGemCommandsSetupCommand < Gem::TestCase @cmd.remove_old_lib_files lib - files_that_go.each {|file| assert_path_not_exist(file) unless file == old_bundler_ci && RUBY_ENGINE == "truffleruby" } # https://github.com/oracle/truffleruby/issues/2116 + files_that_go.each {|file| assert_path_not_exist(file) unless file == old_bundler_ci } files_that_stay.each {|file| assert_path_exist file } end def test_remove_old_man_files - man = File.join @install_dir, 'man' + man = File.join RbConfig::CONFIG["mandir"], "man" - ruby_1 = File.join man, 'man1', 'ruby.1' - bundle_b_1 = File.join man, 'man1', 'bundle-b.1' - bundle_b_1_ronn = File.join man, 'man1', 'bundle-b.1.ronn' - bundle_b_1_txt = File.join man, 'man1', 'bundle-b.1.txt' - gemfile_5 = File.join man, 'man5', 'gemfile.5' - gemfile_5_ronn = File.join man, 'man5', 'gemfile.5.ronn' - gemfile_5_txt = File.join man, 'man5', 'gemfile.5.txt' + ruby_1 = File.join man, "man1", "ruby.1" + bundle_b_1 = File.join man, "man1", "bundle-b.1" + bundle_b_1_ronn = File.join man, "man1", "bundle-b.1.ronn" + bundle_b_1_txt = File.join man, "man1", "bundle-b.1.txt" + gemfile_5 = File.join man, "man5", "gemfile.5" + gemfile_5_ronn = File.join man, "man5", "gemfile.5.ronn" + gemfile_5_txt = File.join man, "man5", "gemfile.5.txt" files_that_go = [bundle_b_1, bundle_b_1_txt, bundle_b_1_ronn, gemfile_5, gemfile_5_txt, gemfile_5_ronn] files_that_stay = [ruby_1] @@ -304,9 +357,9 @@ class TestGemCommandsSetupCommand < Gem::TestCase @default_external = @ui.outs.external_encoding @ui.outs.set_encoding Encoding::US_ASCII - @cmd.options[:previous_version] = Gem::Version.new '2.0.2' + @cmd.options[:previous_version] = Gem::Version.new "2.0.2" - File.open 'CHANGELOG.md', 'w' do |io| + File.open "CHANGELOG.md", "w" do |io| io.puts <<-HISTORY_TXT # #{Gem::VERSION} / 2013-03-26 @@ -353,7 +406,7 @@ class TestGemCommandsSetupCommand < Gem::TestCase list.each do |file| FileUtils.mkdir_p File.dirname(file) - File.open file, 'w' do |io| + File.open file, "w" do |io| io.puts "# #{File.basename(file)}" end end @@ -364,19 +417,19 @@ class TestGemCommandsSetupCommand < Gem::TestCase s.executables = [name] s.files = %W[bin/#{name}] end - write_file File.join @tempdir, 'bin', name do |f| - f.puts '#!/usr/bin/ruby' + write_file File.join @tempdir, "bin", name do |f| + f.puts "#!/usr/bin/ruby" end install_gem gem - File.join @gemhome, 'bin', name + File.join @gemhome, "bin", name end def gem_install_with_plugin(name) gem = util_spec name do |s| s.files = %W[lib/rubygems_plugin.rb] end - write_file File.join @tempdir, 'lib', 'rubygems_plugin.rb' do |f| - f.puts "require '#{gem.plugins.first}'" + write_file File.join @tempdir, "lib", "rubygems_plugin.rb" do |f| + f.puts "# do nothing" end install_gem gem @@ -384,14 +437,34 @@ class TestGemCommandsSetupCommand < Gem::TestCase end def default_gem_bin_path - File.join @install_dir, 'bin', 'gem' + File.join RbConfig::CONFIG["bindir"], "gem" end def default_bundle_bin_path - File.join @install_dir, 'bin', 'bundle' + File.join RbConfig::CONFIG["bindir"], "bundle" end def default_bundler_bin_path - File.join @install_dir, 'bin', 'bundler' + File.join RbConfig::CONFIG["bindir"], "bundler" + end + + def previous_bundler_specification_path + File.join(Gem.default_specifications_dir, "bundler-1.15.4.gemspec") + end + + def new_bundler_specification_path + File.join(Gem.default_specifications_dir, "bundler-#{bundler_version}.gemspec") + end + + def bundler_spec + Gem::Specification.load("bundler/bundler.gemspec") + end + + def bundler_version + bundler_spec.version + end + + def prepend_destdir(destdir, path) + File.join(destdir, path.gsub(/^[a-zA-Z]:/, "")) end end unless Gem.java_platform? diff --git a/test/rubygems/test_gem_commands_signin_command.rb b/test/rubygems/test_gem_commands_signin_command.rb index f8262466b1..29e5edceb7 100644 --- a/test/rubygems/test_gem_commands_signin_command.rb +++ b/test/rubygems/test_gem_commands_signin_command.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/signin_command' -require 'rubygems/installer' + +require_relative "helper" +require "rubygems/commands/signin_command" +require "rubygems/installer" class TestGemCommandsSigninCommand < Gem::TestCase def setup @@ -23,29 +24,36 @@ class TestGemCommandsSigninCommand < Gem::TestCase def test_execute_when_not_already_signed_in sign_in_ui = util_capture { @cmd.execute } - assert_match %r{Signed in.}, sign_in_ui.output + assert_match(/Signed in./, sign_in_ui.output) + end + + def test_execute_when_not_already_signed_in_and_not_preexisting_credentials_folder + FileUtils.rm Gem.configuration.credentials_path + + sign_in_ui = util_capture { @cmd.execute } + assert_match(/Signed in./, sign_in_ui.output) end def test_execute_when_already_signed_in_with_same_host - host = 'http://some-gemcutter-compatible-host.org' + host = "http://some-gemcutter-compatible-host.org" util_capture(nil, host) { @cmd.execute } - old_credentials = YAML.load_file Gem.configuration.credentials_path + old_credentials = load_yaml_file Gem.configuration.credentials_path util_capture(nil, host) { @cmd.execute } - new_credentials = YAML.load_file Gem.configuration.credentials_path + new_credentials = load_yaml_file Gem.configuration.credentials_path assert_equal old_credentials[host], new_credentials[host] end def test_execute_when_already_signed_in_with_different_host - api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf04045xxxx' + api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf04045xxxx" util_capture(nil, nil, api_key) { @cmd.execute } - host = 'http://some-gemcutter-compatible-host.org' + host = "http://some-gemcutter-compatible-host.org" util_capture(nil, host, api_key) { @cmd.execute } - credentials = YAML.load_file Gem.configuration.credentials_path + credentials = load_yaml_file Gem.configuration.credentials_path assert_equal credentials[:rubygems_api_key], api_key @@ -53,66 +61,243 @@ class TestGemCommandsSigninCommand < Gem::TestCase end def test_execute_with_host_supplied - host = 'http://some-gemcutter-compatible-host.org' + host = "http://some-gemcutter-compatible-host.org" sign_in_ui = util_capture(nil, host) { @cmd.execute } - assert_match %r{Enter your #{host} credentials.}, sign_in_ui.output - assert_match %r{Signed in.}, sign_in_ui.output + assert_match(/Enter your #{host} credentials./, sign_in_ui.output) + assert_match(/Signed in./, sign_in_ui.output) - api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' - credentials = YAML.load_file Gem.configuration.credentials_path + api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903" + credentials = load_yaml_file Gem.configuration.credentials_path assert_equal api_key, credentials[host] end + def test_execute_with_host_permanent_redirect + host = "http://rubygems.example/" + ENV["RUBYGEMS_HOST"] = host + path = "/api/v1/api_key" + redirected_uri = "http://rubygems.example#{path}" + fetcher = Gem::FakeFetcher.new + fetcher.data["#{host}#{path}"] = HTTPResponseFactory.create( + body: "", + code: "308", + msg: "Permanent Redirect", + headers: { "location" => redirected_uri } + ) + Gem::RemoteFetcher.fetcher = fetcher + ui = Gem::MockGemUi.new("you@example.com\nsecret\n\n\n") + + assert_raise Gem::MockGemUi::TermError do + use_ui ui do + @cmd.execute + end + end + + response = "The request has redirected permanently to #{redirected_uri}. Please check your defined push host URL." + assert_match response, ui.output + end + def test_execute_with_valid_creds_set_for_default_host util_capture { @cmd.execute } - api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' - credentials = YAML.load_file Gem.configuration.credentials_path + api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903" + credentials = load_yaml_file Gem.configuration.credentials_path assert_equal api_key, credentials[:rubygems_api_key] end - def test_excute_with_key_name_and_scope - email = 'you@example.com' - password = 'secret' - api_key = '1234' + def test_execute_with_key_name_default_scope + email = "you@example.com" + password = "secret" + api_key = "1234abcd" fetcher = Gem::RemoteFetcher.fetcher - key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\ny\n\n\n\n\n\n" + key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\n" util_capture(key_name_ui, nil, api_key, fetcher) { @cmd.execute } user = ENV["USER"] || ENV["USERNAME"] assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output - assert_match "index_rubygems [y/N]", key_name_ui.output - assert_match "push_rubygem [y/N]", key_name_ui.output - assert_match "yank_rubygem [y/N]", key_name_ui.output - assert_match "add_owner [y/N]", key_name_ui.output - assert_match "remove_owner [y/N]", key_name_ui.output - assert_match "access_webhooks [y/N]", key_name_ui.output - assert_match "show_dashboard [y/N]", key_name_ui.output + assert_match "The default access scope is:", key_name_ui.output + assert_match "index_rubygems: y", key_name_ui.output + assert_match "Do you want to customise scopes? [yN]", key_name_ui.output + assert_equal "name=test-key&index_rubygems=true", fetcher.last_request.body + + credentials = load_yaml_file Gem.configuration.credentials_path + assert_equal api_key, credentials[:rubygems_api_key] + end + + def test_execute_with_key_name_and_custom_scope + email = "you@example.com" + password = "secret" + api_key = "1234abcd" + fetcher = Gem::RemoteFetcher.fetcher + + key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\ny\n\n\ny\n\n\n\n\n\n\n" + util_capture(key_name_ui, nil, api_key, fetcher) { @cmd.execute } + + user = ENV["USER"] || ENV["USERNAME"] + + assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output + assert_match "The default access scope is:", key_name_ui.output + assert_match "Do you want to customise scopes? [yN]", key_name_ui.output + assert_match "show_dashboard (exclusive scope, answering yes will not prompt for other scopes) [yN]", key_name_ui.output + assert_match "index_rubygems [yN]", key_name_ui.output + assert_match "push_rubygem [yN]", key_name_ui.output + assert_match "yank_rubygem [yN]", key_name_ui.output + assert_match "add_owner [yN]", key_name_ui.output + assert_match "remove_owner [yN]", key_name_ui.output + assert_match "access_webhooks [yN]", key_name_ui.output assert_equal "name=test-key&push_rubygem=true", fetcher.last_request.body - credentials = YAML.load_file Gem.configuration.credentials_path + credentials = load_yaml_file Gem.configuration.credentials_path + assert_equal api_key, credentials[:rubygems_api_key] + end + + def test_execute_with_key_name_and_exclusive_scope + email = "you@example.com" + password = "secret" + api_key = "1234abcd" + fetcher = Gem::RemoteFetcher.fetcher + + key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\ny\ny\n" + util_capture(key_name_ui, nil, api_key, fetcher) { @cmd.execute } + + user = ENV["USER"] || ENV["USERNAME"] + + assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output + assert_match "The default access scope is:", key_name_ui.output + assert_match "index_rubygems: y", key_name_ui.output + assert_match "Do you want to customise scopes? [yN]", key_name_ui.output + assert_match "show_dashboard (exclusive scope, answering yes will not prompt for other scopes) [yN]", key_name_ui.output + assert_equal "name=test-key&show_dashboard=true", fetcher.last_request.body + + credentials = load_yaml_file Gem.configuration.credentials_path + assert_equal api_key, credentials[:rubygems_api_key] + end + + def test_execute_with_key_name_custom_scope_and_mfa_level_of_ui_only + email = "you@example.com" + password = "secret" + api_key = "1234abcd" + fetcher = Gem::RemoteFetcher.fetcher + mfa_level = "ui_only" + + key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\ny\n\n\ny\n\n\n\n\n\n\ny" + util_capture(key_name_ui, nil, api_key, fetcher, mfa_level) { @cmd.execute } + + user = ENV["USER"] || ENV["USERNAME"] + + assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output + assert_match "The default access scope is:", key_name_ui.output + assert_match "Do you want to customise scopes? [yN]", key_name_ui.output + assert_match "show_dashboard (exclusive scope, answering yes will not prompt for other scopes) [yN]", key_name_ui.output + assert_match "index_rubygems [yN]", key_name_ui.output + assert_match "push_rubygem [yN]", key_name_ui.output + assert_match "yank_rubygem [yN]", key_name_ui.output + assert_match "add_owner [yN]", key_name_ui.output + assert_match "remove_owner [yN]", key_name_ui.output + assert_match "access_webhooks [yN]", key_name_ui.output + assert_match "Would you like to enable MFA for this key? (strongly recommended) [yn]", key_name_ui.output + assert_equal "name=test-key&push_rubygem=true&mfa=true", fetcher.last_request.body + + credentials = load_yaml_file Gem.configuration.credentials_path + assert_equal api_key, credentials[:rubygems_api_key] + end + + def test_execute_with_key_name_custom_scope_and_mfa_level_of_gem_signin + email = "you@example.com" + password = "secret" + api_key = "1234abcd" + fetcher = Gem::RemoteFetcher.fetcher + mfa_level = "ui_and_gem_signin" + + key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\ny\n\n\ny\n\n\n\n\n\n\ny" + util_capture(key_name_ui, nil, api_key, fetcher, mfa_level) { @cmd.execute } + + user = ENV["USER"] || ENV["USERNAME"] + + assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output + assert_match "The default access scope is:", key_name_ui.output + assert_match "Do you want to customise scopes? [yN]", key_name_ui.output + assert_match "show_dashboard (exclusive scope, answering yes will not prompt for other scopes) [yN]", key_name_ui.output + assert_match "index_rubygems [yN]", key_name_ui.output + assert_match "push_rubygem [yN]", key_name_ui.output + assert_match "yank_rubygem [yN]", key_name_ui.output + assert_match "add_owner [yN]", key_name_ui.output + assert_match "remove_owner [yN]", key_name_ui.output + assert_match "access_webhooks [yN]", key_name_ui.output + assert_match "Would you like to enable MFA for this key? (strongly recommended) [yn]", key_name_ui.output + assert_equal "name=test-key&push_rubygem=true&mfa=true", fetcher.last_request.body + + credentials = load_yaml_file Gem.configuration.credentials_path assert_equal api_key, credentials[:rubygems_api_key] end + def test_execute_with_warnings + email = "you@example.com" + password = "secret" + api_key = "1234abcd" + fetcher = Gem::RemoteFetcher.fetcher + mfa_level = "disabled" + warning = "/[WARNING/] For protection of your account and gems" + + key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\n\ny\n\n\n\n\n\ny" + util_capture(key_name_ui, nil, api_key, fetcher, mfa_level, warning) { @cmd.execute } + + assert_match warning, key_name_ui.output + end + + def test_execute_on_gemserver_without_profile_me_endpoint + host = "http://some-gemcutter-compatible-host.org" + + email = "you@example.com" + password = "secret" + api_key = "1234abcd" + fetcher = Gem::RemoteFetcher.fetcher + + key_name_ui = Gem::MockGemUi.new "#{email}\n#{password}\ntest-key\ny\n\n\ny\n\n\n\n\n\n\ny" + + # Set the expected response for the Web-API supplied + ENV["RUBYGEMS_HOST"] = host + data_key = "#{ENV["RUBYGEMS_HOST"]}/api/v1/api_key" + fetcher.data[data_key] = HTTPResponseFactory.create(body: api_key, code: 200, msg: "OK") + + use_ui key_name_ui do + @cmd.execute + end + + user = ENV["USER"] || ENV["USERNAME"] + + assert_match "API Key name [#{Socket.gethostname}-#{user}", key_name_ui.output + assert_match "show_dashboard (exclusive scope, answering yes will not prompt for other scopes) [yN]", key_name_ui.output + assert_match "index_rubygems [yN]", key_name_ui.output + assert_match "push_rubygem [yN]", key_name_ui.output + assert_match "yank_rubygem [yN]", key_name_ui.output + assert_match "add_owner [yN]", key_name_ui.output + assert_match "remove_owner [yN]", key_name_ui.output + assert_match "access_webhooks [yN]", key_name_ui.output + assert_equal "name=test-key&push_rubygem=true", fetcher.last_request.body + end + # Utility method to capture IO/UI within the block passed - def util_capture(ui_stub = nil, host = nil, api_key = nil, fetcher = Gem::FakeFetcher.new) - api_key ||= 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' - response = [api_key, 200, 'OK'] - email = 'you@example.com' - password = 'secret' + def util_capture(ui_stub = nil, host = nil, api_key = nil, fetcher = Gem::FakeFetcher.new, mfa_level = "disabled", warning = nil) + api_key ||= "a5fdbb6ba150cbb83aad2bb2fede64cf040453903" + response = HTTPResponseFactory.create(body: api_key, code: 200, msg: "OK") + profile_response = HTTPResponseFactory.create(body: "mfa: #{mfa_level}\nwarning: #{warning}", code: 200, msg: "OK") + email = "you@example.com" + password = "secret" # Set the expected response for the Web-API supplied - ENV['RUBYGEMS_HOST'] = host || Gem::DEFAULT_HOST - data_key = "#{ENV['RUBYGEMS_HOST']}/api/v1/api_key" + ENV["RUBYGEMS_HOST"] = host || Gem::DEFAULT_HOST + data_key = "#{ENV["RUBYGEMS_HOST"]}/api/v1/api_key" fetcher.data[data_key] = response + profile = "#{ENV["RUBYGEMS_HOST"]}/api/v1/profile/me.yaml" + fetcher.data[profile] = profile_response Gem::RemoteFetcher.fetcher = fetcher - sign_in_ui = ui_stub || Gem::MockGemUi.new("#{email}\n#{password}\n\n\n\n\n\n\n\n\n") + sign_in_ui = ui_stub || Gem::MockGemUi.new("#{email}\n#{password}\n\n\n") use_ui sign_in_ui do yield diff --git a/test/rubygems/test_gem_commands_signout_command.rb b/test/rubygems/test_gem_commands_signout_command.rb index 20389d0537..999a14080f 100644 --- a/test/rubygems/test_gem_commands_signout_command.rb +++ b/test/rubygems/test_gem_commands_signout_command.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/signout_command' -require 'rubygems/installer' +require_relative "helper" +require "rubygems/commands/signout_command" +require "rubygems/installer" class TestGemCommandsSignoutCommand < Gem::TestCase def setup @@ -12,12 +12,12 @@ class TestGemCommandsSignoutCommand < Gem::TestCase def test_execute_when_user_is_signed_in FileUtils.mkdir_p File.dirname(Gem.configuration.credentials_path) - FileUtils::touch Gem.configuration.credentials_path + FileUtils.touch Gem.configuration.credentials_path @sign_out_ui = Gem::MockGemUi.new use_ui(@sign_out_ui) { @cmd.execute } - assert_match %r{You have successfully signed out}, @sign_out_ui.output + assert_match(/You have successfully signed out/, @sign_out_ui.output) assert_equal false, File.exist?(Gem.configuration.credentials_path) end @@ -25,6 +25,6 @@ class TestGemCommandsSignoutCommand < Gem::TestCase @sign_out_ui = Gem::MockGemUi.new use_ui(@sign_out_ui) { @cmd.execute } - assert_match %r{You are not currently signed in}, @sign_out_ui.error + assert_match(/You are not currently signed in/, @sign_out_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 70d1b3611c..5e675e5c84 100644 --- a/test/rubygems/test_gem_commands_sources_command.rb +++ b/test/rubygems/test_gem_commands_sources_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/sources_command' + +require_relative "helper" +require "rubygems/commands/sources_command" class TestGemCommandsSourcesCommand < Gem::TestCase def setup @@ -20,7 +21,7 @@ class TestGemCommandsSourcesCommand < Gem::TestCase end def test_initialize_proxy - assert @cmd.handles?(['--http-proxy', 'http://proxy.example.com']) + assert @cmd.handles?(["--http-proxy", "http://proxy.example.com"]) end def test_execute @@ -37,12 +38,12 @@ class TestGemCommandsSourcesCommand < Gem::TestCase EOF assert_equal expected, @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error end def test_execute_add spec_fetcher do |fetcher| - fetcher.spec 'a', 1 + fetcher.spec "a", 1 end specs = Gem::Specification.map do |spec| @@ -70,7 +71,7 @@ class TestGemCommandsSourcesCommand < Gem::TestCase EOF assert_equal expected, @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error end def test_execute_add_allow_typo_squatting_source @@ -161,7 +162,6 @@ class TestGemCommandsSourcesCommand < Gem::TestCase ui = Gem::MockGemUi.new("n") use_ui ui do - assert_raise Gem::MockGemUi::TermError do @cmd.execute end @@ -182,7 +182,7 @@ class TestGemCommandsSourcesCommand < Gem::TestCase uri = "http://beta-gems.example.com/specs.#{@marshal_version}.gz" @fetcher.data[uri] = proc do - raise Gem::RemoteFetcher::FetchError.new('it died', uri) + raise Gem::RemoteFetcher::FetchError.new("it died", uri) end @cmd.handle_options %w[--add http://beta-gems.example.com] @@ -199,7 +199,57 @@ Error fetching http://beta-gems.example.com: EOF assert_equal expected, @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error + end + + def test_execute_add_existent_source_invalid_uri + spec_fetcher + + uri = "https://u:p@example.com/specs.#{@marshal_version}.gz" + + @cmd.handle_options %w[--add https://u:p@example.com] + @fetcher.data[uri] = proc do + raise Gem::RemoteFetcher::FetchError.new("it died", uri) + end + + use_ui @ui do + assert_raise Gem::MockGemUi::TermError do + @cmd.execute + end + end + + expected = <<-EOF +Error fetching https://u:REDACTED@example.com: +\tit died (https://u:REDACTED@example.com/specs.#{@marshal_version}.gz) + EOF + + assert_equal expected, @ui.output + assert_equal "", @ui.error + end + + def test_execute_add_existent_source_invalid_uri_with_error_by_chance_including_the_uri_password + spec_fetcher + + uri = "https://u:secret@example.com/specs.#{@marshal_version}.gz" + + @cmd.handle_options %w[--add https://u:secret@example.com] + @fetcher.data[uri] = proc do + raise Gem::RemoteFetcher::FetchError.new("it secretly died", uri) + end + + use_ui @ui do + assert_raise Gem::MockGemUi::TermError do + @cmd.execute + end + end + + expected = <<-EOF +Error fetching https://u:REDACTED@example.com: +\tit secretly died (https://u:REDACTED@example.com/specs.#{@marshal_version}.gz) + EOF + + assert_equal expected, @ui.output + assert_equal "", @ui.error end def test_execute_add_redundant_source @@ -218,7 +268,7 @@ source #{@gem_repo} already present in the cache EOF assert_equal expected, @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error end def test_execute_add_redundant_source_trailing_slash @@ -238,7 +288,7 @@ source #{@gem_repo} already present in the cache EOF assert_equal expected, @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error # Re-add pre-existing gem source (w/o slash) repo_without_slash = "http://gems.example.com" @@ -255,7 +305,7 @@ http://gems.example.com added to sources EOF assert_equal expected, @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error # Re-add original gem source (w/ slash) @cmd.handle_options %W[--add #{repo_with_slash}] @@ -272,14 +322,14 @@ source http://gems.example.com/ already present in the cache EOF assert_equal expected, @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error end def test_execute_add_http_rubygems_org - http_rubygems_org = 'http://rubygems.org/' + http_rubygems_org = "http://rubygems.org/" spec_fetcher do |fetcher| - fetcher.spec 'a', 1 + fetcher.spec "a", 1 end specs = Gem::Specification.map do |spec| @@ -344,10 +394,10 @@ source http://gems.example.com/ already present in the cache end def test_execute_add_https_rubygems_org - https_rubygems_org = 'https://rubygems.org/' + https_rubygems_org = "https://rubygems.org/" spec_fetcher do |fetcher| - fetcher.spec 'a', 1 + fetcher.spec "a", 1 end specs = Gem::Specification.map do |spec| @@ -397,7 +447,7 @@ beta-gems.example.com is not a URI EOF assert_equal expected, @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error end def test_execute_clear_all @@ -412,10 +462,10 @@ beta-gems.example.com is not a URI EOF assert_equal expected, @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error dir = Gem.spec_cache_dir - refute File.exist?(dir), 'cache dir removed' + refute File.exist?(dir), "cache dir removed" end def test_execute_list @@ -432,7 +482,7 @@ beta-gems.example.com is not a URI EOF assert_equal expected, @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error end def test_execute_remove @@ -445,7 +495,7 @@ beta-gems.example.com is not a URI expected = "#{@gem_repo} removed from sources\n" assert_equal expected, @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error end def test_execute_remove_no_network @@ -464,14 +514,14 @@ beta-gems.example.com is not a URI expected = "#{@gem_repo} removed from sources\n" assert_equal expected, @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error end def test_execute_update @cmd.handle_options %w[--update] spec_fetcher do |fetcher| - fetcher.gem 'a', 1 + fetcher.gem "a", 1 end use_ui @ui do @@ -479,6 +529,6 @@ beta-gems.example.com is not a URI end assert_equal "source cache successfully updated\n", @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error end end diff --git a/test/rubygems/test_gem_commands_specification_command.rb b/test/rubygems/test_gem_commands_specification_command.rb index 74a85e96ef..454d6ea1c6 100644 --- a/test/rubygems/test_gem_commands_specification_command.rb +++ b/test/rubygems/test_gem_commands_specification_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/specification_command' + +require_relative "helper" +require "rubygems/commands/specification_command" class TestGemCommandsSpecificationCommand < Gem::TestCase def setup @@ -10,7 +11,7 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase end def test_execute - foo = util_spec 'foo' + foo = util_spec "foo" install_specs foo @@ -20,14 +21,14 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase @cmd.execute end - assert_match %r{Gem::Specification}, @ui.output - assert_match %r{name: foo}, @ui.output - assert_equal '', @ui.error + assert_match(/Gem::Specification/, @ui.output) + assert_match(/name: foo/, @ui.output) + assert_equal "", @ui.error end def test_execute_all - install_specs util_spec 'foo', '0.0.1' - install_specs util_spec 'foo', '0.0.2' + install_specs util_spec "foo", "0.0.1" + install_specs util_spec "foo", "0.0.2" @cmd.options[:args] = %w[foo] @cmd.options[:all] = true @@ -36,16 +37,16 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase @cmd.execute end - assert_match %r{Gem::Specification}, @ui.output - assert_match %r{name: foo}, @ui.output - assert_match %r{version: 0.0.1}, @ui.output - assert_match %r{version: 0.0.2}, @ui.output - assert_equal '', @ui.error + assert_match(/Gem::Specification/, @ui.output) + assert_match(/name: foo/, @ui.output) + assert_match(/version: 0.0.1/, @ui.output) + assert_match(/version: 0.0.2/, @ui.output) + assert_equal "", @ui.error end def test_execute_all_conflicts_with_version - util_spec 'foo', '0.0.1' - util_spec 'foo', '0.0.2' + util_spec "foo", "0.0.1" + util_spec "foo", "0.0.2" @cmd.options[:args] = %w[foo] @cmd.options[:all] = true @@ -57,7 +58,7 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase end end - assert_equal '', @ui.output + assert_equal "", @ui.output assert_equal "ERROR: Specify --all or -v, not both\n", @ui.error end @@ -70,7 +71,7 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase end end - assert_equal '', @ui.output + assert_equal "", @ui.output assert_equal "ERROR: No gem matching 'foo (>= 0)' found\n", @ui.error end @@ -84,13 +85,13 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase end end - assert_equal '', @ui.output + assert_equal "", @ui.output assert_equal "ERROR: No gem matching 'foo (= 1.3.2)' found\n", @ui.error end def test_execute_exact_match - install_specs util_spec 'foo' - install_specs util_spec 'foo_bar' + install_specs util_spec "foo" + install_specs util_spec "foo_bar" @cmd.options[:args] = %w[foo] @@ -98,13 +99,13 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase @cmd.execute end - assert_match %r{Gem::Specification}, @ui.output - assert_match %r{name: foo}, @ui.output - assert_equal '', @ui.error + assert_match(/Gem::Specification/, @ui.output) + assert_match(/name: foo/, @ui.output) + assert_equal "", @ui.error end def test_execute_field - foo = util_spec 'foo', '2' + foo = util_spec "foo", "2" install_specs foo @@ -114,11 +115,11 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase @cmd.execute end - assert_equal "foo", YAML.load(@ui.output) + assert_equal "foo", load_yaml(@ui.output) end def test_execute_file - foo = util_spec 'foo' do |s| + foo = util_spec "foo" do |s| s.files = %w[lib/code.rb] end @@ -130,13 +131,13 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase @cmd.execute end - assert_match %r{Gem::Specification}, @ui.output - assert_match %r{name: foo}, @ui.output - assert_equal '', @ui.error + assert_match(/Gem::Specification/, @ui.output) + assert_match(/name: foo/, @ui.output) + assert_equal "", @ui.error end def test_execute_marshal - foo = util_spec 'foo', '2' + foo = util_spec "foo", "2" install_specs foo @@ -148,12 +149,12 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase end assert_equal foo, Marshal.load(@ui.output) - assert_equal '', @ui.error + assert_equal "", @ui.error end def test_execute_remote spec_fetcher do |fetcher| - fetcher.spec 'foo', 1 + fetcher.spec "foo", 1 end @cmd.options[:args] = %w[foo] @@ -164,13 +165,13 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase end assert_match %r{\A--- !ruby/object:Gem::Specification}, @ui.output - assert_match %r{name: foo}, @ui.output + assert_match(/name: foo/, @ui.output) end def test_execute_remote_with_version spec_fetcher do |fetcher| - fetcher.spec 'foo', "1" - fetcher.spec 'foo', "2" + fetcher.spec "foo", "1" + fetcher.spec "foo", "2" end @cmd.options[:args] = %w[foo] @@ -190,9 +191,9 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase original_platforms = Gem.platforms.dup spec_fetcher do |fetcher| - fetcher.spec 'foo', "1" - fetcher.spec 'foo', "1" do |s| - s.platform = 'x86_64-linux' + fetcher.spec "foo", "1" + fetcher.spec "foo", "1" do |s| + s.platform = "x86_64-linux" end end @@ -216,8 +217,8 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase def test_execute_remote_without_prerelease spec_fetcher do |fetcher| - fetcher.spec 'foo', '2.0.0' - fetcher.spec 'foo', '2.0.1.pre' + fetcher.spec "foo", "2.0.0" + fetcher.spec "foo", "2.0.1.pre" end @cmd.options[:args] = %w[foo] @@ -228,17 +229,17 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase end assert_match %r{\A--- !ruby/object:Gem::Specification}, @ui.output - assert_match %r{name: foo}, @ui.output + assert_match(/name: foo/, @ui.output) - spec = YAML.load @ui.output + spec = load_yaml @ui.output assert_equal Gem::Version.new("2.0.0"), spec.version end def test_execute_remote_with_prerelease spec_fetcher do |fetcher| - fetcher.spec 'foo', '2.0.0' - fetcher.spec 'foo', '2.0.1.pre' + fetcher.spec "foo", "2.0.0" + fetcher.spec "foo", "2.0.1.pre" end @cmd.options[:args] = %w[foo] @@ -250,15 +251,15 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase end assert_match %r{\A--- !ruby/object:Gem::Specification}, @ui.output - assert_match %r{name: foo}, @ui.output + assert_match(/name: foo/, @ui.output) - spec = YAML.load @ui.output + spec = load_yaml @ui.output assert_equal Gem::Version.new("2.0.1.pre"), spec.version end def test_execute_ruby - foo = util_spec 'foo' + foo = util_spec "foo" install_specs foo @@ -269,8 +270,8 @@ class TestGemCommandsSpecificationCommand < Gem::TestCase @cmd.execute end - assert_match %r{Gem::Specification.new}, @ui.output - assert_match %r{s.name = "foo"}, @ui.output - assert_equal '', @ui.error + assert_match(/Gem::Specification.new/, @ui.output) + assert_match(/s.name = "foo"/, @ui.output) + assert_equal "", @ui.error end end diff --git a/test/rubygems/test_gem_commands_stale_command.rb b/test/rubygems/test_gem_commands_stale_command.rb index 0aa7f243e2..ea7493b418 100644 --- a/test/rubygems/test_gem_commands_stale_command.rb +++ b/test/rubygems/test_gem_commands_stale_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/stale_command' + +require_relative "helper" +require "rubygems/commands/stale_command" class TestGemCommandsStaleCommand < Gem::TestCase def setup @@ -11,12 +12,12 @@ class TestGemCommandsStaleCommand < Gem::TestCase def test_execute_sorts files = %w[lib/foo_bar.rb Rakefile] - foo_bar = util_spec 'foo_bar' do |gem| + foo_bar = util_spec "foo_bar" do |gem| gem.files = files end install_specs foo_bar - bar_baz = util_spec 'bar_baz' do |gem| + bar_baz = util_spec "bar_baz" do |gem| gem.files = files end install_specs bar_baz @@ -24,11 +25,11 @@ class TestGemCommandsStaleCommand < Gem::TestCase files.each do |file| filename = File.join(bar_baz.full_gem_path, file) FileUtils.mkdir_p File.dirname filename - FileUtils.touch(filename, :mtime => Time.now) + FileUtils.touch(filename, mtime: Time.now) filename = File.join(foo_bar.full_gem_path, file) FileUtils.mkdir_p File.dirname filename - FileUtils.touch(filename, :mtime => Time.now - 86400) + FileUtils.touch(filename, mtime: Time.now - 86_400) end use_ui @stub_ui do diff --git a/test/rubygems/test_gem_commands_uninstall_command.rb b/test/rubygems/test_gem_commands_uninstall_command.rb index a1b81d73de..4daa61cb0c 100644 --- a/test/rubygems/test_gem_commands_uninstall_command.rb +++ b/test/rubygems/test_gem_commands_uninstall_command.rb @@ -1,12 +1,13 @@ # frozen_string_literal: true -require 'rubygems/installer_test_case' -require 'rubygems/commands/uninstall_command' + +require_relative "installer_test_case" +require "rubygems/commands/uninstall_command" class TestGemCommandsUninstallCommand < Gem::InstallerTestCase def setup super @cmd = Gem::Commands::UninstallCommand.new - @executable = File.join(@gemhome, 'bin', 'executable') + @executable = File.join(@gemhome, "bin", "executable") end def test_execute_all_named @@ -14,20 +15,15 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase util_make_gems - default = new_default_spec 'default', '1' + default = new_default_spec "default", "1" install_default_gems default gemhome2 = "#{@gemhome}2" - a_4, = util_gem 'a', 4 - install_gem a_4, :install_dir => gemhome2 - - Gem::Specification.dirs = [@gemhome, gemhome2] + a_4, = util_gem "a", 4 + install_gem a_4, install_dir: gemhome2 - assert_includes Gem::Specification.all_names, 'a-1' - assert_includes Gem::Specification.all_names, 'a-4' - assert_includes Gem::Specification.all_names, 'b-2' - assert_includes Gem::Specification.all_names, 'default-1' + assert_gems_presence "a-1", "a-4", "b-2", "default-1", dirs: [@gemhome, gemhome2] @cmd.options[:all] = true @cmd.options[:args] = %w[a] @@ -41,10 +37,10 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase end def test_execute_all_named_default_single - z_1 = new_default_spec 'z', '1' + z_1 = new_default_spec "z", "1" install_default_gems z_1 - assert_includes Gem::Specification.all_names, 'z-1' + assert_includes Gem::Specification.all_names, "z-1" @cmd.options[:all] = true @cmd.options[:args] = %w[z] @@ -57,18 +53,18 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase output = @ui.output.split "\n" - assert_equal 'Gem z-1 cannot be uninstalled because it is a default gem', output.shift + assert_equal "Gem z-1 cannot be uninstalled because it is a default gem", output.shift end def test_execute_all_named_default_multiple - z_1 = new_default_spec 'z', '1' + z_1 = new_default_spec "z", "1" install_default_gems z_1 - z_2, = util_gem 'z', 2 + z_2, = util_gem "z", 2 install_gem z_2 - assert_includes Gem::Specification.all_names, 'z-1' - assert_includes Gem::Specification.all_names, 'z-2' + assert_includes Gem::Specification.all_names, "z-1" + assert_includes Gem::Specification.all_names, "z-2" @cmd.options[:all] = true @cmd.options[:args] = %w[z] @@ -81,15 +77,15 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase output = @ui.output.split "\n" - assert_equal 'Gem z-1 cannot be uninstalled because it is a default gem', output.shift - assert_equal 'Successfully uninstalled z-2', output.shift + assert_equal "Gem z-1 cannot be uninstalled because it is a default gem", output.shift + assert_equal "Successfully uninstalled z-2", output.shift end def test_execute_dependency_order initial_install - c = quick_gem 'c' do |spec| - spec.add_dependency 'a' + c = quick_gem "c" do |spec| + spec.add_dependency "a" end util_build_gem c @@ -110,15 +106,15 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase output = ui.output.split "\n" - assert_equal 'Successfully uninstalled c-2', output.shift + assert_equal "Successfully uninstalled c-2", output.shift assert_equal "Removing executable", output.shift - assert_equal 'Successfully uninstalled a-2', output.shift + assert_equal "Successfully uninstalled a-2", output.shift end def test_execute_removes_executable initial_install - if win_platform? + if Gem.win_platform? assert File.exist?(@executable) else assert File.symlink?(@executable) @@ -149,12 +145,12 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase FileUtils.rm_f @executable # Wish this didn't happen in #setup - Gem::Installer.exec_format = 'foo-%s-bar' + Gem::Installer.exec_format = "foo-%s-bar" installer.format_executable = true installer.install - formatted_executable = File.join @gemhome, 'bin', 'foo-executable-bar' + formatted_executable = File.join @gemhome, "bin", "foo-executable-bar" assert_equal true, File.exist?(formatted_executable) @cmd.options[:executables] = true @@ -162,7 +158,7 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase @cmd.execute assert_equal false, File.exist?(formatted_executable) - rescue + rescue StandardError Gem::Installer.exec_format = nil end @@ -197,19 +193,19 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase util_make_gems - assert_equal 3, Gem::Specification.find_all_by_name('a').length + assert_equal 3, Gem::Specification.find_all_by_name("a").length - @cmd.options[:version] = '1' + @cmd.options[:version] = "1" @cmd.options[:force] = true - @cmd.options[:args] = ['a'] + @cmd.options[:args] = ["a"] use_ui ui do @cmd.execute end - assert_equal 2, Gem::Specification.find_all_by_name('a').length + assert_equal 2, Gem::Specification.find_all_by_name("a").length - assert File.exist? File.join(@gemhome, 'bin', 'executable') + assert File.exist? File.join(@gemhome, "bin", "executable") end def test_execute_with_version_specified_as_colon @@ -219,18 +215,38 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase util_make_gems - assert_equal 3, Gem::Specification.find_all_by_name('a').length + assert_equal 3, Gem::Specification.find_all_by_name("a").length @cmd.options[:force] = true - @cmd.options[:args] = ['a:1'] + @cmd.options[:args] = ["a:1"] use_ui ui do @cmd.execute end - assert_equal 2, Gem::Specification.find_all_by_name('a').length + assert_equal 2, Gem::Specification.find_all_by_name("a").length + + assert File.exist? File.join(@gemhome, "bin", "executable") + end + + def test_execute_with_multiple_version_specified_as_colon + initial_install + + ui = Gem::MockGemUi.new "y\n" + + util_make_gems + + assert_equal 3, Gem::Specification.find_all_by_name("a").length + + @cmd.options[:force] = true + @cmd.options[:args] = ["a:1", "a:2"] + + use_ui ui do + @cmd.execute + end - assert File.exist? File.join(@gemhome, 'bin', 'executable') + assert_equal 1, Gem::Specification.find_all_by_name("a").length + assert_equal Gem::Version.new("3.a"), Gem::Specification.find_by_name("a").version end def test_uninstall_selection @@ -238,22 +254,22 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase util_make_gems - list = Gem::Specification.find_all_by_name 'a' + list = Gem::Specification.find_all_by_name "a" - @cmd.options[:args] = ['a'] + @cmd.options[:args] = ["a"] use_ui ui do @cmd.execute end - updated_list = Gem::Specification.find_all_by_name('a') + updated_list = Gem::Specification.find_all_by_name("a") assert_equal list.length - 1, updated_list.length - assert_match ' 1. a-1', ui.output - assert_match ' 2. a-2', ui.output - assert_match ' 3. a-3.a', ui.output - assert_match ' 4. All versions', ui.output - assert_match 'uninstalled a-1', ui.output + assert_match " 1. a-1", ui.output + assert_match " 2. a-2", ui.output + assert_match " 3. a-3.a", ui.output + assert_match " 4. All versions", ui.output + assert_match "uninstalled a-1", ui.output end def test_uninstall_selection_multiple_gems @@ -261,31 +277,31 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase util_make_gems - a_list = Gem::Specification.find_all_by_name('a') - b_list = Gem::Specification.find_all_by_name('b') + a_list = Gem::Specification.find_all_by_name("a") + b_list = Gem::Specification.find_all_by_name("b") list = a_list + b_list - @cmd.options[:args] = ['a', 'b'] + @cmd.options[:args] = ["a", "b"] use_ui ui do @cmd.execute end - updated_a_list = Gem::Specification.find_all_by_name('a') - updated_b_list = Gem::Specification.find_all_by_name('b') + updated_a_list = Gem::Specification.find_all_by_name("a") + updated_b_list = Gem::Specification.find_all_by_name("b") updated_list = updated_a_list + updated_b_list assert_equal list.length - 2, updated_list.length out = ui.output.split("\n") - assert_match 'uninstalled b-2', out.shift - assert_match '', out.shift - assert_match 'Select gem to uninstall:', out.shift - assert_match ' 1. a-1', out.shift - assert_match ' 2. a-2', out.shift - assert_match ' 3. a-3.a', out.shift - assert_match ' 4. All versions', out.shift - assert_match 'uninstalled a-1', out.shift + assert_match "uninstalled b-2", out.shift + assert_match "", out.shift + assert_match "Select gem to uninstall:", out.shift + assert_match " 1. a-1", out.shift + assert_match " 2. a-2", out.shift + assert_match " 3. a-3.a", out.shift + assert_match " 4. All versions", out.shift + assert_match "uninstalled a-1", out.shift assert_empty out end @@ -294,22 +310,22 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase ui = Gem::MockGemUi.new "y\n" - a_1, = util_gem 'a', 1 + a_1, = util_gem "a", 1 install_gem a_1 - a_3a, = util_gem 'a', '3.a' + a_3a, = util_gem "a", "3.a" install_gem a_3a - assert_equal 3, Gem::Specification.find_all_by_name('a').length + assert_equal 3, Gem::Specification.find_all_by_name("a").length @cmd.options[:force] = true - @cmd.options[:args] = ['a'] + @cmd.options[:args] = ["a"] use_ui ui do @cmd.execute end - assert_empty Gem::Specification.find_all_by_name('a') + assert_empty Gem::Specification.find_all_by_name("a") assert_match "Removing executable", ui.output refute File.exist? @executable end @@ -321,36 +337,32 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase util_make_gems - assert Gem::Specification.find_all_by_name('dep_x').length > 0 - assert Gem::Specification.find_all_by_name('x').length > 0 + 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'] + @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.zero? + assert Gem::Specification.find_all_by_name("dep_x").length > 0 + assert Gem::Specification.find_all_by_name("x").length.zero? end def test_execute_all util_make_gems - default = new_default_spec 'default', '1' + default = new_default_spec "default", "1" install_default_gems default gemhome2 = "#{@gemhome}2" - a_4, = util_gem 'a', 4 + a_4, = util_gem "a", 4 install_gem a_4 - Gem::Specification.dirs = [@gemhome, gemhome2] - - assert_includes Gem::Specification.all_names, 'a-1' - assert_includes Gem::Specification.all_names, 'a-4' - assert_includes Gem::Specification.all_names, 'default-1' + assert_gems_presence "a-1", "a-4", "default-1", dirs: [@gemhome, gemhome2] @cmd.options[:all] = true @cmd.options[:args] = [] @@ -368,14 +380,12 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase gemhome2 = "#{@gemhome}2" - a_4, = util_gem 'a', 4 - install_gem a_4 , :install_dir => gemhome2 - - Gem::Specification.dirs = [@gemhome, gemhome2] + a_4, = util_gem "a", 4 + install_gem a_4, install_dir: gemhome2 - assert_includes Gem::Specification.all_names, 'a-4' + assert_gems_presence "a-4", dirs: [@gemhome, gemhome2] - @cmd.options[:args] = ['a:4'] + @cmd.options[:args] = ["a:4"] e = assert_raise Gem::InstallError do use_ui ui do @@ -386,6 +396,26 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase assert_includes e.message, "a is not installed in GEM_HOME" end + def test_execute_outside_gem_home_when_install_dir_given + gemhome2 = "#{@gemhome}2" + + a_4, = util_gem "a", 4 + install_gem a_4, install_dir: gemhome2 + + assert_gems_presence "a-4", dirs: [@gemhome, gemhome2] + + Gem::Specification.dirs = [@gemhome] + + @cmd.options[:install_dir] = gemhome2 + @cmd.options[:args] = ["a:4"] + + @cmd.execute + + Gem::Specification.dirs = [gemhome2] + + refute_includes Gem::Specification.all_names.sort, "a-4" + end + def test_handle_options @cmd.handle_options %w[] @@ -397,7 +427,7 @@ class TestGemCommandsUninstallCommand < Gem::InstallerTestCase end def test_handle_options_vendor - vendordir(File.join(@tempdir, 'vendor')) do + vendordir(File.join(@tempdir, "vendor")) do use_ui @ui do @cmd.handle_options %w[--vendor] end @@ -436,11 +466,11 @@ WARNING: Use your OS package manager to uninstall vendor gems def test_handle_options_vendor_missing vendordir(nil) do - e = assert_raise OptionParser::InvalidOption do + e = assert_raise Gem::OptionParser::InvalidOption do @cmd.handle_options %w[--vendor] end - assert_equal 'invalid option: --vendor your platform is not supported', + assert_equal "invalid option: --vendor your platform is not supported", e.message refute @cmd.options[:vendor] @@ -449,7 +479,7 @@ WARNING: Use your OS package manager to uninstall vendor gems end def test_execute_with_gem_not_installed - @cmd.options[:args] = ['d'] + @cmd.options[:args] = ["d"] use_ui ui do @cmd.execute @@ -486,7 +516,7 @@ WARNING: Use your OS package manager to uninstall vendor gems end assert_empty @ui.output - assert_match %r{Error: unable to successfully uninstall '#{@spec.name}'}, @ui.error + assert_match(/Error: unable to successfully uninstall '#{@spec.name}'/, @ui.error) end private @@ -501,4 +531,12 @@ WARNING: Use your OS package manager to uninstall vendor gems end end end + + def assert_gems_presence(*gems, dirs:) + Gem::Specification.dirs = dirs + + gems.each do |full_name| + assert_includes Gem::Specification.all_names, full_name + end + end end diff --git a/test/rubygems/test_gem_commands_unpack_command.rb b/test/rubygems/test_gem_commands_unpack_command.rb index 06bdc510aa..61cf8a611a 100644 --- a/test/rubygems/test_gem_commands_unpack_command.rb +++ b/test/rubygems/test_gem_commands_unpack_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/unpack_command' + +require_relative "helper" +require "rubygems/commands/unpack_command" class TestGemCommandsUnpackCommand < Gem::TestCase def setup @@ -15,30 +16,30 @@ class TestGemCommandsUnpackCommand < Gem::TestCase util_make_gems assert_equal( - @cmd.find_in_cache(File.basename @a1.cache_file), + @cmd.find_in_cache(File.basename(@a1.cache_file)), @a1.cache_file, - 'found a-1.gem in the cache' + "found a-1.gem in the cache" ) end def test_get_path specs = spec_fetcher do |fetcher| - fetcher.gem 'a', 1 + fetcher.gem "a", 1 end - dep = Gem::Dependency.new 'a', 1 + dep = Gem::Dependency.new "a", 1 assert_equal( @cmd.get_path(dep), - specs['a-1'].cache_file, - 'fetches a-1 and returns the cache path' + specs["a-1"].cache_file, + "fetches a-1 and returns the cache path" ) - FileUtils.rm specs['a-1'].cache_file + FileUtils.rm specs["a-1"].cache_file assert_equal( @cmd.get_path(dep), - specs['a-1'].cache_file, - 'when removed from cache, refetches a-1' + specs["a-1"].cache_file, + "when removed from cache, refetches a-1" ) end @@ -53,18 +54,18 @@ class TestGemCommandsUnpackCommand < Gem::TestCase end end - assert File.exist?(File.join(@tempdir, 'a-3.a')), 'a should be unpacked' - assert File.exist?(File.join(@tempdir, 'b-2')), 'b should be unpacked' + assert File.exist?(File.join(@tempdir, "a-3.a")), "a should be unpacked" + assert File.exist?(File.join(@tempdir, "b-2")), "b should be unpacked" end def test_execute_gem_path spec_fetcher do |fetcher| - fetcher.gem 'a', '3.a' + fetcher.gem "a", "3.a" end Gem.clear_paths - gemhome2 = File.join @tempdir, 'gemhome2' + gemhome2 = File.join @tempdir, "gemhome2" Gem.use_paths gemhome2, [gemhome2, @gemhome] @@ -76,7 +77,7 @@ class TestGemCommandsUnpackCommand < Gem::TestCase end end - assert File.exist?(File.join(@tempdir, 'a-3.a')) + assert File.exist?(File.join(@tempdir, "a-3.a")) end def test_execute_gem_path_missing @@ -84,7 +85,7 @@ class TestGemCommandsUnpackCommand < Gem::TestCase Gem.clear_paths - gemhome2 = File.join @tempdir, 'gemhome2' + gemhome2 = File.join @tempdir, "gemhome2" Gem.use_paths gemhome2, [gemhome2, @gemhome] @@ -96,13 +97,13 @@ class TestGemCommandsUnpackCommand < Gem::TestCase end end - assert_equal '', @ui.output + assert_equal "", @ui.output end def test_execute_remote spec_fetcher do |fetcher| - fetcher.download 'a', 1 - fetcher.download 'a', 2 + fetcher.download "a", 1 + fetcher.download "a", 2 end Gem.configuration.verbose = :really @@ -114,7 +115,7 @@ class TestGemCommandsUnpackCommand < Gem::TestCase end end - assert File.exist?(File.join(@tempdir, 'a-2')), 'a should be unpacked' + assert File.exist?(File.join(@tempdir, "a-2")), "a should be unpacked" end def test_execute_spec @@ -129,15 +130,15 @@ class TestGemCommandsUnpackCommand < Gem::TestCase end end - assert File.exist?(File.join(@tempdir, 'a-3.a.gemspec')) - assert File.exist?(File.join(@tempdir, 'b-2.gemspec')) + assert File.exist?(File.join(@tempdir, "a-3.a.gemspec")) + assert File.exist?(File.join(@tempdir, "b-2.gemspec")) end def test_execute_spec_target util_make_gems @cmd.options[:args] = %w[a b] - @cmd.options[:target] = 'specs' + @cmd.options[:target] = "specs" @cmd.options[:spec] = true use_ui @ui do @@ -146,16 +147,16 @@ class TestGemCommandsUnpackCommand < Gem::TestCase end end - assert File.exist?(File.join(@tempdir, 'specs/a-3.a.gemspec')) - assert File.exist?(File.join(@tempdir, 'specs/b-2.gemspec')) + assert File.exist?(File.join(@tempdir, "specs/a-3.a.gemspec")) + assert File.exist?(File.join(@tempdir, "specs/b-2.gemspec")) end def test_execute_sudo - skip 'Cannot perform this test on windows (chmod)' if win_platform? + pend "Cannot perform this test on windows (chmod)" if Gem.win_platform? util_make_gems - FileUtils.chmod 0555, @gemhome + FileUtils.chmod 0o555, @gemhome @cmd.options[:args] = %w[b] @@ -165,15 +166,15 @@ class TestGemCommandsUnpackCommand < Gem::TestCase end end - assert File.exist?(File.join(@tempdir, 'b-2')), 'b should be unpacked' + assert File.exist?(File.join(@tempdir, "b-2")), "b should be unpacked" ensure - FileUtils.chmod 0755, @gemhome + FileUtils.chmod 0o755, @gemhome end def test_execute_with_target_option util_make_gems - target = 'with_target' + target = "with_target" @cmd.options[:args] = %w[a] @cmd.options[:target] = target @@ -183,12 +184,12 @@ class TestGemCommandsUnpackCommand < Gem::TestCase end end - assert File.exist?(File.join(@tempdir, target, 'a-3.a')) + assert File.exist?(File.join(@tempdir, target, "a-3.a")) end def test_execute_exact_match - foo_spec = util_spec 'foo' - foo_bar_spec = util_spec 'foo_bar' + foo_spec = util_spec "foo" + foo_bar_spec = util_spec "foo_bar" use_ui @ui do Dir.chdir @tempdir do diff --git a/test/rubygems/test_gem_commands_update_command.rb b/test/rubygems/test_gem_commands_update_command.rb index 6693b0921b..2683840f2e 100644 --- a/test/rubygems/test_gem_commands_update_command.rb +++ b/test/rubygems/test_gem_commands_update_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/update_command' + +require_relative "helper" +require "rubygems/commands/update_command" class TestGemCommandsUpdateCommand < Gem::TestCase def setup @@ -12,20 +13,20 @@ class TestGemCommandsUpdateCommand < Gem::TestCase @cmd.options[:document] = [] @specs = spec_fetcher do |fetcher| - fetcher.download 'a', 1 - fetcher.download 'a', 2 - fetcher.download 'a', '3.a' + fetcher.download "a", 1 + fetcher.download "a", 2 + fetcher.download "a", "3.a" end - @a1_path = @specs['a-1'].cache_file - @a2_path = @specs['a-1'].cache_file - @a3a_path = @specs['a-3.a'].cache_file + @a1_path = @specs["a-1"].cache_file + @a2_path = @specs["a-1"].cache_file + @a3a_path = @specs["a-3.a"].cache_file end def test_execute spec_fetcher do |fetcher| - fetcher.download 'a', 2 - fetcher.spec 'a', 1 + fetcher.download "a", 2 + fetcher.spec "a", 1 end @cmd.options[:args] = [] @@ -43,11 +44,11 @@ class TestGemCommandsUpdateCommand < Gem::TestCase def test_execute_multiple spec_fetcher do |fetcher| - fetcher.download 'a', 2 - fetcher.download 'ab', 2 + fetcher.download "a", 2 + fetcher.download "ab", 2 - fetcher.spec 'a', 1 - fetcher.spec 'ab', 1 + fetcher.spec "a", 1 + fetcher.spec "ab", 1 end @cmd.options[:args] = %w[a] @@ -65,7 +66,7 @@ class TestGemCommandsUpdateCommand < Gem::TestCase def test_execute_system spec_fetcher do |fetcher| - fetcher.download 'rubygems-update', 9 do |s| + fetcher.download "rubygems-update", 9 do |s| s.files = %w[setup.rb] end end @@ -78,7 +79,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase end out = @ui.output.split "\n" - assert_equal "Updating rubygems-update", out.shift assert_equal "Installing RubyGems 9", out.shift assert_equal "RubyGems system software updated", out.shift @@ -87,7 +87,7 @@ class TestGemCommandsUpdateCommand < Gem::TestCase def test_execute_system_at_latest spec_fetcher do |fetcher| - fetcher.download 'rubygems-update', Gem::VERSION do |s| + fetcher.download "rubygems-update", Gem::VERSION do |s| s.files = %w[setup.rb] end end @@ -106,17 +106,133 @@ class TestGemCommandsUpdateCommand < Gem::TestCase assert_empty out end + def test_execute_system_when_latest_does_not_support_your_ruby + spec_fetcher do |fetcher| + fetcher.download "rubygems-update", 9 do |s| + s.files = %w[setup.rb] + s.required_ruby_version = "> 9" + end + end + + @cmd.options[:args] = [] + @cmd.options[:system] = true + + use_ui @ui do + @cmd.execute + end + + out = @ui.output.split "\n" + assert_empty out + + err = @ui.error.split "\n" + assert_equal "ERROR: Error installing rubygems-update:", err.shift + assert_equal "\trubygems-update-9 requires Ruby version > 9. The current ruby version is #{Gem.ruby_version}.", err.shift + assert_empty err + end + + def test_execute_system_when_latest_does_not_support_your_ruby_but_previous_one_does + spec_fetcher do |fetcher| + fetcher.download "rubygems-update", 9 do |s| + s.files = %w[setup.rb] + s.required_ruby_version = "> 9" + end + + fetcher.download "rubygems-update", 8 do |s| + s.files = %w[setup.rb] + end + end + + @cmd.options[:args] = [] + @cmd.options[:system] = true + + use_ui @ui do + @cmd.execute + end + + err = @ui.error.split "\n" + assert_empty err + + out = @ui.output.split "\n" + assert_equal "Installing RubyGems 8", out.shift + assert_equal "RubyGems system software updated", out.shift + assert_empty out + end + def test_execute_system_multiple spec_fetcher do |fetcher| - fetcher.download 'rubygems-update', 8 do |s| + fetcher.download "rubygems-update", 8 do |s| + s.files = %w[setup.rb] + end + + fetcher.download "rubygems-update", 9 do |s| + s.files = %w[setup.rb] + end + end + + @cmd.options[:args] = [] + @cmd.options[:system] = true + + use_ui @ui do + @cmd.execute + end + + out = @ui.output.split "\n" + assert_equal "Installing RubyGems 9", out.shift + assert_equal "RubyGems system software updated", out.shift + + assert_empty out + end + + def test_execute_system_update_installed + spec_fetcher do |fetcher| + fetcher.download "rubygems-update", 8 do |s| s.files = %w[setup.rb] end + end + + @cmd.options[:args] = [] + @cmd.options[:system] = true + + @cmd.execute - fetcher.download 'rubygems-update', 9 do |s| + spec_fetcher do |fetcher| + fetcher.download "rubygems-update", 9 do |s| s.files = %w[setup.rb] end end + @cmd = Gem::Commands::UpdateCommand.new + @cmd.options[:args] = [] + @cmd.options[:system] = true + + use_ui @ui do + @cmd.execute + end + + out = @ui.output.split "\n" + assert_equal "Installing RubyGems 9", out.shift + assert_equal "RubyGems system software updated", out.shift + + assert_empty out + end + + def test_execute_system_update_installed_in_non_default_gem_path + rubygems_update_spec = quick_gem "rubygems-update", 9 do |s| + write_file File.join(@tempdir, "setup.rb") + + s.files += %w[setup.rb] + end + + util_setup_spec_fetcher rubygems_update_spec + + rubygems_update_package = Gem::Package.build rubygems_update_spec + + gemhome2 = "#{@gemhome}2" + + Gem::Installer.at(rubygems_update_package, install_dir: gemhome2).install + + Gem.use_paths @gemhome, [gemhome2, @gemhome] + @cmd.options[:args] = [] @cmd.options[:system] = true @@ -125,7 +241,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase end out = @ui.output.split "\n" - assert_equal "Updating rubygems-update", out.shift assert_equal "Installing RubyGems 9", out.shift assert_equal "RubyGems system software updated", out.shift @@ -134,11 +249,11 @@ class TestGemCommandsUpdateCommand < Gem::TestCase def test_execute_system_specific spec_fetcher do |fetcher| - fetcher.download 'rubygems-update', 8 do |s| + fetcher.download "rubygems-update", 8 do |s| s.files = %w[setup.rb] end - fetcher.download 'rubygems-update', 9 do |s| + fetcher.download "rubygems-update", 9 do |s| s.files = %w[setup.rb] end end @@ -151,7 +266,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase end out = @ui.output.split "\n" - assert_equal "Updating rubygems-update", out.shift assert_equal "Installing RubyGems 8", out.shift assert_equal "RubyGems system software updated", out.shift @@ -160,7 +274,7 @@ class TestGemCommandsUpdateCommand < Gem::TestCase def test_execute_system_specific_older_than_minimum_supported_rubygems spec_fetcher do |fetcher| - fetcher.download 'rubygems-update', "2.5.1" do |s| + fetcher.download "rubygems-update", "2.5.1" do |s| s.files = %w[setup.rb] end end @@ -189,7 +303,7 @@ class TestGemCommandsUpdateCommand < Gem::TestCase def test_execute_system_specific_older_than_3_2_removes_plugins_dir spec_fetcher do |fetcher| - fetcher.download 'rubygems-update', 3.1 do |s| + fetcher.download "rubygems-update", 3.1 do |s| s.files = %w[setup.rb] end end @@ -207,7 +321,7 @@ class TestGemCommandsUpdateCommand < Gem::TestCase @cmd.options[:system] = "3.1" FileUtils.mkdir_p Gem.plugindir - write_file File.join(Gem.plugindir, 'a_plugin.rb') + write_file File.join(Gem.plugindir, "a_plugin.rb") @cmd.execute @@ -216,7 +330,7 @@ class TestGemCommandsUpdateCommand < Gem::TestCase def test_execute_system_specific_newer_than_or_equal_to_3_2_leaves_plugins_dir_alone spec_fetcher do |fetcher| - fetcher.download 'rubygems-update', "3.2.a" do |s| + fetcher.download "rubygems-update", "3.2.a" do |s| s.files = %w[setup.rb] end end @@ -234,7 +348,7 @@ class TestGemCommandsUpdateCommand < Gem::TestCase @cmd.options[:system] = "3.2.a" FileUtils.mkdir_p Gem.plugindir - plugin_file = File.join(Gem.plugindir, 'a_plugin.rb') + plugin_file = File.join(Gem.plugindir, "a_plugin.rb") write_file plugin_file @cmd.execute @@ -245,11 +359,11 @@ class TestGemCommandsUpdateCommand < Gem::TestCase def test_execute_system_specifically_to_latest_version spec_fetcher do |fetcher| - fetcher.download 'rubygems-update', 8 do |s| + fetcher.download "rubygems-update", 8 do |s| s.files = %w[setup.rb] end - fetcher.download 'rubygems-update', 9 do |s| + fetcher.download "rubygems-update", 9 do |s| s.files = %w[setup.rb] end end @@ -262,7 +376,6 @@ class TestGemCommandsUpdateCommand < Gem::TestCase end out = @ui.output.split "\n" - assert_equal "Updating rubygems-update", out.shift assert_equal "Installing RubyGems 9", out.shift assert_equal "RubyGems system software updated", out.shift @@ -310,12 +423,12 @@ class TestGemCommandsUpdateCommand < Gem::TestCase @cmd.options[:system] = true @cmd.options[:silent] = true - assert_equal true, @cmd.update_rubygems_arguments.include?('--silent') + assert_equal true, @cmd.update_rubygems_arguments.include?("--silent") end def test_execute_system_silent spec_fetcher do |fetcher| - fetcher.download 'rubygems-update', 9 do |s| + fetcher.download "rubygems-update", 9 do |s| s.files = %w[setup.rb] end end @@ -339,12 +452,12 @@ class TestGemCommandsUpdateCommand < Gem::TestCase def test_execute_dependencies spec_fetcher do |fetcher| - fetcher.download 'a', 2, 'b' => 2, 'c' => 2 - fetcher.download 'b', 2 - fetcher.download 'c', 2 + fetcher.download "a", 2, "b" => 2, "c" => 2 + fetcher.download "b", 2 + fetcher.download "c", 2 - fetcher.spec 'a', 1, 'c' => '1.2' - fetcher.spec 'c', '1.2' + fetcher.spec "a", 1, "c" => "1.2" + fetcher.spec "c", "1.2" end Gem::Specification.reset @@ -366,8 +479,8 @@ class TestGemCommandsUpdateCommand < Gem::TestCase def test_execute_rdoc spec_fetcher do |fetcher| - fetcher.download 'a', 2 - fetcher.spec 'a', 1 + fetcher.download "a", 2 + fetcher.spec "a", 1 end Gem.done_installing(&Gem::RDoc.method(:generation_hook)) @@ -382,16 +495,16 @@ class TestGemCommandsUpdateCommand < Gem::TestCase wait_for_child_process_to_exit - a2 = @specs['a-2'] + a2 = @specs["a-2"] - assert_path_exist File.join(a2.doc_dir, 'rdoc') + assert_path_exist File.join(a2.doc_dir, "rdoc") end def test_execute_named spec_fetcher do |fetcher| - fetcher.download 'a', 2 + fetcher.download "a", 2 - fetcher.spec 'a', 1 + fetcher.spec "a", 1 end @cmd.options[:args] = %w[a] @@ -410,10 +523,10 @@ class TestGemCommandsUpdateCommand < Gem::TestCase def test_execute_named_some_up_to_date spec_fetcher do |fetcher| - fetcher.download 'a', 2 - fetcher.spec 'a', 1 + fetcher.download "a", 2 + fetcher.spec "a", 1 - fetcher.spec 'b', 2 + fetcher.spec "b", 2 end @cmd.options[:args] = %w[a b] @@ -433,7 +546,7 @@ class TestGemCommandsUpdateCommand < Gem::TestCase def test_execute_named_up_to_date spec_fetcher do |fetcher| - fetcher.spec 'a', 2 + fetcher.spec "a", 2 end @cmd.options[:args] = %w[a] @@ -445,15 +558,16 @@ class TestGemCommandsUpdateCommand < Gem::TestCase out = @ui.output.split "\n" assert_equal "Updating installed gems", out.shift assert_equal "Nothing to update", out.shift + assert_equal "Gems already up-to-date: a", out.shift assert_empty out end def test_execute_named_up_to_date_prerelease spec_fetcher do |fetcher| - fetcher.download 'a', '3.a' + fetcher.download "a", "3.a" - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end @cmd.options[:args] = %w[a] @@ -473,7 +587,7 @@ class TestGemCommandsUpdateCommand < Gem::TestCase def test_execute_up_to_date spec_fetcher do |fetcher| - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end @cmd.options[:args] = [] @@ -515,73 +629,73 @@ class TestGemCommandsUpdateCommand < Gem::TestCase def test_fetch_remote_gems specs = spec_fetcher do |fetcher| - fetcher.gem 'a', 1 - fetcher.gem 'a', 2 + fetcher.gem "a", 1 + fetcher.gem "a", 2 end expected = [ - [Gem::NameTuple.new('a', v(2), Gem::Platform::RUBY), + [Gem::NameTuple.new("a", v(2), Gem::Platform::RUBY), Gem::Source.new(@gem_repo)], ] - assert_equal expected, @cmd.fetch_remote_gems(specs['a-1']) + assert_equal expected, @cmd.fetch_remote_gems(specs["a-1"]) end def test_fetch_remote_gems_error Gem.sources.replace %w[http://nonexistent.example] assert_raise Gem::RemoteFetcher::FetchError do - @cmd.fetch_remote_gems @specs['a-1'] + @cmd.fetch_remote_gems @specs["a-1"] end end def test_fetch_remote_gems_mismatch - platform = Gem::Platform.new 'x86-freebsd9' + platform = Gem::Platform.new "x86-freebsd9" specs = spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', 2 + fetcher.spec "a", 1 + fetcher.spec "a", 2 - fetcher.spec 'a', 2 do |s| + fetcher.spec "a", 2 do |s| s.platform = platform end end expected = [ - [Gem::NameTuple.new('a', v(2), Gem::Platform::RUBY), + [Gem::NameTuple.new("a", v(2), Gem::Platform::RUBY), Gem::Source.new(@gem_repo)], ] - assert_equal expected, @cmd.fetch_remote_gems(specs['a-1']) + assert_equal expected, @cmd.fetch_remote_gems(specs["a-1"]) end def test_fetch_remote_gems_prerelease specs = spec_fetcher do |fetcher| - fetcher.gem 'a', 1 - fetcher.gem 'a', 2 - fetcher.gem 'a', '3.a' + fetcher.gem "a", 1 + fetcher.gem "a", 2 + fetcher.gem "a", "3.a" end @cmd.options[:prerelease] = true expected = [ - [Gem::NameTuple.new('a', v(2), Gem::Platform::RUBY), + [Gem::NameTuple.new("a", v(2), Gem::Platform::RUBY), Gem::Source.new(@gem_repo)], - [Gem::NameTuple.new('a', v('3.a'), Gem::Platform::RUBY), + [Gem::NameTuple.new("a", v("3.a"), Gem::Platform::RUBY), Gem::Source.new(@gem_repo)], ] - assert_equal expected, @cmd.fetch_remote_gems(specs['a-1']) + assert_equal expected, @cmd.fetch_remote_gems(specs["a-1"]) end def test_handle_options_system @cmd.handle_options %w[--system] expected = { - :args => [], - :document => %w[ri], - :force => false, - :system => true, + args: [], + document: %w[ri], + force: false, + system: true, } assert_equal expected, @cmd.options @@ -597,10 +711,10 @@ class TestGemCommandsUpdateCommand < Gem::TestCase @cmd.handle_options %w[--system 1.3.7] expected = { - :args => [], - :document => %w[ri], - :force => false, - :system => "1.3.7", + args: [], + document: %w[ri], + force: false, + system: "1.3.7", } assert_equal expected, @cmd.options @@ -608,11 +722,11 @@ class TestGemCommandsUpdateCommand < Gem::TestCase def test_update_gem_prerelease spec_fetcher do |fetcher| - fetcher.spec 'a', '1.a' - fetcher.gem 'a', '1.b' + fetcher.spec "a", "1.a" + fetcher.gem "a", "1.b" end - @cmd.update_gem 'a', Gem::Requirement.new('= 1.b') + @cmd.update_gem "a", Gem::Requirement.new("= 1.b") refute_empty @cmd.updated @@ -621,15 +735,15 @@ class TestGemCommandsUpdateCommand < Gem::TestCase def test_update_gem_unresolved_dependency spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.gem 'a', 2 do |s| - s.add_dependency 'b', '>= 2' + fetcher.spec "a", 1 + fetcher.gem "a", 2 do |s| + s.add_dependency "b", ">= 2" end - fetcher.spec 'b', 1 + fetcher.spec "b", 1 end - @cmd.update_gem 'a' + @cmd.update_gem "a" assert_empty @cmd.updated end @@ -639,18 +753,18 @@ class TestGemCommandsUpdateCommand < Gem::TestCase arguments = @cmd.update_rubygems_arguments - assert_equal '--prefix', arguments.shift + assert_equal "--prefix", arguments.shift assert_equal Gem.prefix, arguments.shift - assert_equal '--no-document', arguments.shift - assert_equal '--previous-version', arguments.shift + assert_equal "--no-document", arguments.shift + assert_equal "--previous-version", arguments.shift assert_equal Gem::VERSION, arguments.shift assert_empty arguments end def test_explain spec_fetcher do |fetcher| - fetcher.download 'a', 2 - fetcher.spec 'a', 1 + fetcher.download "a", 2 + fetcher.spec "a", 1 end @cmd.options[:explain] = true @@ -670,13 +784,13 @@ class TestGemCommandsUpdateCommand < Gem::TestCase def test_explain_platform_local local = Gem::Platform.local spec_fetcher do |fetcher| - fetcher.download 'a', 2 + fetcher.download "a", 2 - fetcher.download 'a', 2 do |s| + fetcher.download "a", 2 do |s| s.platform = local end - fetcher.spec 'a', 1 + fetcher.spec "a", 1 end @cmd.options[:explain] = true @@ -696,13 +810,13 @@ class TestGemCommandsUpdateCommand < Gem::TestCase def test_explain_platform_ruby local = Gem::Platform.local spec_fetcher do |fetcher| - fetcher.download 'a', 2 + fetcher.download "a", 2 - fetcher.download 'a', 2 do |s| + fetcher.download "a", 2 do |s| s.platform = local end - fetcher.spec 'a', 1 + fetcher.spec "a", 1 end # equivalent to --platform=ruby @@ -721,4 +835,24 @@ class TestGemCommandsUpdateCommand < Gem::TestCase assert_equal " a-2", out.shift assert_empty out end + + def test_execute_named_not_installed_and_no_update + spec_fetcher do |fetcher| + fetcher.spec "a", 2 + end + + @cmd.options[:args] = %w[a b] + + use_ui @ui do + @cmd.execute + end + + out = @ui.output.split "\n" + assert_equal "Updating installed gems", out.shift + assert_equal "Nothing to update", out.shift + assert_equal "Gems already up-to-date: a", out.shift + assert_equal "Gems not currently installed: b", out.shift + + assert_empty out + end end diff --git a/test/rubygems/test_gem_commands_which_command.rb b/test/rubygems/test_gem_commands_which_command.rb index ce56f8eefc..cbd5b5ef14 100644 --- a/test/rubygems/test_gem_commands_which_command.rb +++ b/test/rubygems/test_gem_commands_which_command.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/which_command' + +require_relative "helper" +require "rubygems/commands/which_command" class TestGemCommandsWhichCommand < Gem::TestCase def setup @@ -19,7 +20,7 @@ class TestGemCommandsWhichCommand < Gem::TestCase end assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error end def test_execute_directory @@ -31,9 +32,9 @@ class TestGemCommandsWhichCommand < Gem::TestCase end end - assert_equal '', @ui.output - assert_match %r{Can.t find Ruby library file or shared library directory\n}, - @ui.error + assert_equal "", @ui.output + assert_match(/Can.t find Ruby library file or shared library directory\n/, + @ui.error) end def test_execute_one_missing @@ -50,8 +51,8 @@ class TestGemCommandsWhichCommand < Gem::TestCase end assert_equal "#{@foo_bar.full_gem_path}/lib/foo_bar.rb\n", @ui.output - assert_match %r{Can.t find Ruby library file or shared library missinglib\n}, - @ui.error + assert_match(/Can.t find Ruby library file or shared library missinglib\n/, + @ui.error) end def test_execute_missing @@ -63,14 +64,14 @@ class TestGemCommandsWhichCommand < Gem::TestCase end end - assert_equal '', @ui.output - assert_match %r{Can.t find Ruby library file or shared library missinglib\n}, - @ui.error + assert_equal "", @ui.output + assert_match(/Can.t find Ruby library file or shared library missinglib\n/, + @ui.error) end def util_foo_bar files = %w[lib/foo_bar.rb lib/directory/baz.rb Rakefile] - @foo_bar = util_spec 'foo_bar' do |gem| + @foo_bar = util_spec "foo_bar" do |gem| gem.files = files end install_specs @foo_bar diff --git a/test/rubygems/test_gem_commands_yank_command.rb b/test/rubygems/test_gem_commands_yank_command.rb index 76e935b06a..eb78e3a542 100644 --- a/test/rubygems/test_gem_commands_yank_command.rb +++ b/test/rubygems/test_gem_commands_yank_command.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/commands/yank_command' + +require_relative "helper" +require_relative "multifactor_auth_utilities" +require "rubygems/commands/yank_command" class TestGemCommandsYankCommand < Gem::TestCase def setup @@ -9,12 +11,13 @@ class TestGemCommandsYankCommand < Gem::TestCase credential_setup @cmd = Gem::Commands::YankCommand.new - @cmd.options[:host] = 'http://example' + @cmd.options[:host] = "http://example" - @fetcher = Gem::RemoteFetcher.fetcher + @fetcher = Gem::MultifactorAuthFetcher.new(host: "http://example") + Gem::RemoteFetcher.fetcher = @fetcher - Gem.configuration.rubygems_api_key = 'key' - Gem.configuration.api_keys[:KEY] = 'other' + Gem.configuration.rubygems_api_key = "key" + Gem.configuration.api_keys[:KEY] = "other" end def teardown @@ -30,109 +33,225 @@ class TestGemCommandsYankCommand < Gem::TestCase assert_equal :KEY, @cmd.options[:key] assert_equal "HOST", @cmd.options[:host] assert_nil @cmd.options[:platform] - assert_equal req('= 1.0'), @cmd.options[:version] + assert_equal req("= 1.0"), @cmd.options[:version] end def test_handle_options_missing_argument %w[-v --version -p --platform].each do |option| - assert_raise OptionParser::MissingArgument do + assert_raise Gem::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'] + yank_uri = "http://example/api/v1/gems/yank" + @fetcher.data[yank_uri] = HTTPResponseFactory.create(body: "Successfully yanked", code: 200, msg: "OK") @cmd.options[:args] = %w[a] @cmd.options[:added_platform] = true - @cmd.options[:version] = req('= 1.0') + @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 + assert_match(/Successfully yanked/, @ui.output) platform = Gem.platforms[1] - body = @fetcher.last_request.body.split('&').sort + 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 "key", @fetcher.last_request["Authorization"] assert_equal [yank_uri], @fetcher.paths end def test_execute_with_otp_success - response_fail = 'You have enabled multifactor authentication but your request doesn\'t have the correct OTP code. Please check it and retry.' - yank_uri = 'http://example/api/v1/gems/yank' + response_fail = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry." + yank_uri = "http://example/api/v1/gems/yank" @fetcher.data[yank_uri] = [ - [response_fail, 401, 'Unauthorized'], - ['Successfully yanked', 200, 'OK'], + HTTPResponseFactory.create(body: response_fail, code: 401, msg: "Unauthorized"), + HTTPResponseFactory.create(body: "Successfully yanked", code: 200, msg: "OK"), ] @cmd.options[:args] = %w[a] @cmd.options[:added_platform] = true - @cmd.options[:version] = req('= 1.0') + @cmd.options[:version] = req("= 1.0") @otp_ui = Gem::MockGemUi.new "111111\n" use_ui @otp_ui do @cmd.execute end - assert_match 'You have enabled multi-factor authentication. Please enter OTP code.', @otp_ui.output - assert_match 'Code: ', @otp_ui.output + assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @otp_ui.output + assert_match "Code: ", @otp_ui.output assert_match %r{Yanking gem from http://example}, @otp_ui.output - assert_match %r{Successfully yanked}, @otp_ui.output - assert_equal '111111', @fetcher.last_request['OTP'] + assert_match(/Successfully yanked/, @otp_ui.output) + assert_equal "111111", @fetcher.last_request["OTP"] end def test_execute_with_otp_failure - response = 'You have enabled multifactor authentication but your request doesn\'t have the correct OTP code. Please check it and retry.' - yank_uri = 'http://example/api/v1/gems/yank' - @fetcher.data[yank_uri] = [response, 401, 'Unauthorized'] + response = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry." + yank_uri = "http://example/api/v1/gems/yank" + @fetcher.data[yank_uri] = HTTPResponseFactory.create(body: response, code: 401, msg: "Unauthorized") @cmd.options[:args] = %w[a] @cmd.options[:added_platform] = true - @cmd.options[:version] = req('= 1.0') + @cmd.options[:version] = req("= 1.0") @otp_ui = Gem::MockGemUi.new "111111\n" use_ui @otp_ui do @cmd.execute end - assert_match 'You have enabled multi-factor authentication. Please enter OTP code.', @otp_ui.output + assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @otp_ui.output assert_match response, @otp_ui.output - assert_match 'Code: ', @otp_ui.output - assert_equal '111111', @fetcher.last_request['OTP'] + assert_match "Code: ", @otp_ui.output + assert_equal "111111", @fetcher.last_request["OTP"] + end + + def test_with_webauthn_enabled_success + server = Gem::MockTCPServer.new + + @fetcher.respond_with_require_otp("http://example/api/v1/gems/yank", "Successfully yanked") + @fetcher.respond_with_webauthn_url + + @cmd.options[:args] = %w[a] + @cmd.options[:added_platform] = true + @cmd.options[:version] = req("= 1.0") + + TCPServer.stub(:new, server) do + Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:otp] = "Uvh6T57tkWuUnWYo" }) do + use_ui @ui do + @cmd.execute + end + end + end + + assert_match %r{Yanking gem from http://example}, @ui.output + assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \ + "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \ + "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output + assert_match "You are verified with a security device. You may close the browser window.", @ui.output + assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"] + assert_match "Successfully yanked", @ui.output + end + + def test_with_webauthn_enabled_failure + server = Gem::MockTCPServer.new + error = Gem::WebauthnVerificationError.new("Something went wrong") + + @fetcher.respond_with_require_otp("http://example/api/v1/gems/yank", "Successfully yanked") + @fetcher.respond_with_webauthn_url + + @cmd.options[:args] = %w[a] + @cmd.options[:added_platform] = true + @cmd.options[:version] = req("= 1.0") + + error = assert_raise Gem::MockGemUi::TermError do + TCPServer.stub(:new, server) do + Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:error] = error }) do + use_ui @ui do + @cmd.execute + end + end + end + end + assert_equal 1, error.exit_code + + assert_match @fetcher.last_request["Authorization"], Gem.configuration.rubygems_api_key + assert_match %r{Yanking gem from http://example}, @ui.output + assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \ + "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \ + "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output + assert_match "ERROR: Security device verification failed: Something went wrong", @ui.error + refute_match "You are verified with a security device. You may close the browser window.", @ui.output + refute_match "Successfully yanked", @ui.output + end + + def test_with_webauthn_enabled_success_with_polling + server = Gem::MockTCPServer.new + + @fetcher.respond_with_require_otp("http://example/api/v1/gems/yank", "Successfully yanked") + @fetcher.respond_with_webauthn_url + @fetcher.respond_with_webauthn_polling("Uvh6T57tkWuUnWYo") + + @cmd.options[:args] = %w[a] + @cmd.options[:added_platform] = true + @cmd.options[:version] = req("= 1.0") + + TCPServer.stub(:new, server) do + use_ui @ui do + @cmd.execute + end + end + + assert_match %r{Yanking gem from http://example}, @ui.output + assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \ + "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \ + "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output + assert_match "You are verified with a security device. You may close the browser window.", @ui.output + assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"] + assert_match "Successfully yanked", @ui.output + end + + def test_with_webauthn_enabled_failure_with_polling + server = Gem::MockTCPServer.new + + @fetcher.respond_with_require_otp("http://example/api/v1/gems/yank", "Successfully yanked") + @fetcher.respond_with_webauthn_url + @fetcher.respond_with_webauthn_polling_failure + + @cmd.options[:args] = %w[a] + @cmd.options[:added_platform] = true + @cmd.options[:version] = req("= 1.0") + + error = assert_raise Gem::MockGemUi::TermError do + TCPServer.stub(:new, server) do + use_ui @ui do + @cmd.execute + end + end + end + assert_equal 1, error.exit_code + + assert_match @fetcher.last_request["Authorization"], Gem.configuration.rubygems_api_key + assert_match %r{Yanking gem from http://example}, @ui.output + assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \ + "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \ + "you can re-run the gem signin command with the `--otp [your_code]` option.", @ui.output + assert_match "ERROR: Security device verification failed: The token in the link you used has either expired " \ + "or been used already.", @ui.error + refute_match "You are verified with a security device. You may close the browser window.", @ui.output + refute_match "Successfully yanked", @ui.output end def test_execute_key - yank_uri = 'http://example/api/v1/gems/yank' - @fetcher.data[yank_uri] = ['Successfully yanked', 200, 'OK'] + yank_uri = "http://example/api/v1/gems/yank" + @fetcher.data[yank_uri] = HTTPResponseFactory.create(body: "Successfully yanked", code: 200, msg: "OK") @cmd.options[:args] = %w[a] - @cmd.options[:version] = req('= 1.0') + @cmd.options[:version] = req("= 1.0") @cmd.options[:key] = :KEY use_ui @ui do @cmd.execute end - body = @fetcher.last_request.body.split('&').sort + body = @fetcher.last_request.body.split("&").sort assert_equal %w[gem_name=a version=1.0], body - assert_equal 'other', @fetcher.last_request['Authorization'] + assert_equal "other", @fetcher.last_request["Authorization"] end def test_execute_host - host = 'https://other.example' + host = "https://other.example" yank_uri = "#{host}/api/v1/gems/yank" - @fetcher.data[yank_uri] = ['Successfully yanked', 200, 'OK'] + @fetcher.data[yank_uri] = HTTPResponseFactory.create(body: "Successfully yanked", code: 200, msg: "OK") @cmd.options[:args] = %w[a] - @cmd.options[:version] = req('= 1.0') + @cmd.options[:version] = req("= 1.0") @cmd.options[:host] = host use_ui @ui do @@ -140,28 +259,28 @@ class TestGemCommandsYankCommand < Gem::TestCase end assert_match %r{Yanking gem from https://other.example}, @ui.output - assert_match %r{Successfully yanked}, @ui.output + assert_match(/Successfully yanked/, @ui.output) - body = @fetcher.last_request.body.split('&').sort + body = @fetcher.last_request.body.split("&").sort assert_equal %w[gem_name=a version=1.0], body - assert_equal 'key', @fetcher.last_request['Authorization'] + assert_equal "key", @fetcher.last_request["Authorization"] assert_equal [yank_uri], @fetcher.paths end def test_yank_gem_unathorized_api_key response_forbidden = "The API key doesn't have access" - response_success = 'Successfully yanked' - host = 'http://example' + response_success = "Successfully yanked" + host = "http://example" @fetcher.data["#{host}/api/v1/gems/yank"] = [ - [response_forbidden, 403, 'Forbidden'], - [response_success, 200, "OK"], + HTTPResponseFactory.create(body: response_forbidden, code: 403, msg: "Forbidden"), + HTTPResponseFactory.create(body: response_success, code: 200, msg: "OK"), ] - @fetcher.data["#{host}/api/v1/api_key"] = ["", 200, "OK"] + @fetcher.data["#{host}/api/v1/api_key"] = HTTPResponseFactory.create(body: "", code: 200, msg: "OK") @cmd.options[:args] = %w[a] @cmd.options[:added_platform] = true - @cmd.options[:version] = req('= 1.0') + @cmd.options[:version] = req("= 1.0") @cmd.instance_variable_set :@host, host @cmd.instance_variable_set :@scope, :yank_rubygem @@ -172,7 +291,7 @@ class TestGemCommandsYankCommand < Gem::TestCase access_notice = "The existing key doesn't have access of yank_rubygem on http://example. Please sign in to update access." assert_match access_notice, @ui.output - assert_match "Email:", @ui.output + assert_match "Username/email:", @ui.output assert_match "Password:", @ui.output assert_match "Added yank_rubygem scope to the existing API key", @ui.output assert_match response_success, @ui.output diff --git a/test/rubygems/test_gem_config_file.rb b/test/rubygems/test_gem_config_file.rb index 92375c57b0..a055f248be 100644 --- a/test/rubygems/test_gem_config_file.rb +++ b/test/rubygems/test_gem_config_file.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/config_file' + +require_relative "helper" +require "rubygems/config_file" class TestGemConfigFile < Gem::TestCase def setup @@ -8,15 +9,15 @@ class TestGemConfigFile < Gem::TestCase credential_setup - @temp_conf = File.join @tempdir, '.gemrc' + @temp_conf = File.join @tempdir, ".gemrc" @cfg_args = %W[--config-file #{@temp_conf}] Gem::ConfigFile::OPERATING_SYSTEM_DEFAULTS.clear Gem::ConfigFile::PLATFORM_DEFAULTS.clear - @env_gemrc = ENV['GEMRC'] - ENV['GEMRC'] = '' + @env_gemrc = ENV["GEMRC"] + ENV["GEMRC"] = "" util_config_file end @@ -25,7 +26,7 @@ class TestGemConfigFile < Gem::TestCase Gem::ConfigFile::OPERATING_SYSTEM_DEFAULTS.clear Gem::ConfigFile::PLATFORM_DEFAULTS.clear - ENV['GEMRC'] = @env_gemrc + ENV["GEMRC"] = @env_gemrc credential_teardown @@ -35,7 +36,7 @@ class TestGemConfigFile < Gem::TestCase def test_initialize assert_equal @temp_conf, @cfg.config_file_name - assert_equal false, @cfg.backtrace + assert_equal true, @cfg.backtrace assert_equal true, @cfg.update_sources assert_equal Gem::ConfigFile::DEFAULT_BULK_THRESHOLD, @cfg.bulk_threshold assert_equal true, @cfg.verbose @@ -43,7 +44,7 @@ class TestGemConfigFile < Gem::TestCase assert_equal 365, @cfg.cert_expiration_length_days assert_equal false, @cfg.ipv4_fallback_enabled - File.open @temp_conf, 'w' do |fp| + File.open @temp_conf, "w" do |fp| fp.puts ":backtrace: true" fp.puts ":update_sources: false" fp.puts ":bulk_threshold: 10" @@ -57,6 +58,7 @@ class TestGemConfigFile < Gem::TestCase fp.puts ":ssl_verify_mode: 0" fp.puts ":ssl_ca_cert: /etc/ssl/certs" fp.puts ":cert_expiration_length_days: 28" + fp.puts ":install_extension_in_lib: true" fp.puts ":ipv4_fallback_enabled: true" end @@ -66,17 +68,18 @@ class TestGemConfigFile < Gem::TestCase assert_equal false, @cfg.verbose assert_equal false, @cfg.update_sources assert_equal %w[http://more-gems.example.com], @cfg.sources - assert_equal '--wrappers', @cfg[:install] - assert_equal(['/usr/ruby/1.8/lib/ruby/gems/1.8', '/var/ruby/1.8/gem_home'], + assert_equal "--wrappers", @cfg[:install] + assert_equal(["/usr/ruby/1.8/lib/ruby/gems/1.8", "/var/ruby/1.8/gem_home"], @cfg.path) assert_equal 0, @cfg.ssl_verify_mode - assert_equal '/etc/ssl/certs', @cfg.ssl_ca_cert + assert_equal "/etc/ssl/certs", @cfg.ssl_ca_cert assert_equal 28, @cfg.cert_expiration_length_days + assert_equal true, @cfg.install_extension_in_lib assert_equal true, @cfg.ipv4_fallback_enabled end def test_initialize_ipv4_fallback_enabled_env - ENV['IPV4_FALLBACK_ENABLED'] = 'true' + ENV["IPV4_FALLBACK_ENABLED"] = "true" util_config_file %W[--config-file #{@temp_conf}] assert_equal true, @cfg.ipv4_fallback_enabled @@ -102,37 +105,37 @@ class TestGemConfigFile < Gem::TestCase def test_initialize_operating_system_override Gem::ConfigFile::OPERATING_SYSTEM_DEFAULTS[:bulk_threshold] = 1 - Gem::ConfigFile::OPERATING_SYSTEM_DEFAULTS['install'] = '--no-env-shebang' + Gem::ConfigFile::OPERATING_SYSTEM_DEFAULTS["install"] = "--no-env-shebang" Gem::ConfigFile::PLATFORM_DEFAULTS[:bulk_threshold] = 2 util_config_file assert_equal 2, @cfg.bulk_threshold - assert_equal '--no-env-shebang', @cfg[:install] + assert_equal "--no-env-shebang", @cfg[:install] end def test_initialize_platform_override Gem::ConfigFile::PLATFORM_DEFAULTS[:bulk_threshold] = 2 - Gem::ConfigFile::PLATFORM_DEFAULTS['install'] = '--no-env-shebang' + Gem::ConfigFile::PLATFORM_DEFAULTS["install"] = "--no-env-shebang" - File.open Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE, 'w' do |fp| + File.open Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE, "w" do |fp| fp.puts ":bulk_threshold: 3" end util_config_file assert_equal 3, @cfg.bulk_threshold - assert_equal '--no-env-shebang', @cfg[:install] + assert_equal "--no-env-shebang", @cfg[:install] end def test_initialize_system_wide_override - File.open Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE, 'w' do |fp| + File.open Gem::ConfigFile::SYSTEM_WIDE_CONFIG_FILE, "w" do |fp| fp.puts ":backtrace: false" fp.puts ":bulk_threshold: 2048" end - File.open @temp_conf, 'w' do |fp| + File.open @temp_conf, "w" do |fp| fp.puts ":backtrace: true" end @@ -143,28 +146,28 @@ class TestGemConfigFile < Gem::TestCase 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' + 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' + 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' + 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' + conf3 = File.join @tempdir, "gemrc3" + File.open conf3, "w" do |fp| + fp.puts ":verbose: :loud" end ps = File::PATH_SEPARATOR - ENV['GEMRC'] = conf1 + ps + conf2 + ps + conf3 + ENV["GEMRC"] = conf1 + ps + conf2 + ps + conf3 util_config_file @@ -174,7 +177,7 @@ class TestGemConfigFile < Gem::TestCase end def test_set_config_file_name_from_environment_variable - ENV['GEMRC'] = "/tmp/.gemrc" + ENV["GEMRC"] = "/tmp/.gemrc" cfg = Gem::ConfigFile.new([]) assert_equal cfg.config_file_name, "/tmp/.gemrc" end @@ -182,24 +185,24 @@ class TestGemConfigFile < Gem::TestCase def test_api_keys assert_nil @cfg.instance_variable_get :@api_keys - temp_cred = File.join Gem.user_home, '.gem', 'credentials' + temp_cred = File.join Gem.user_home, ".gem", "credentials" FileUtils.mkdir_p File.dirname(temp_cred) - File.open temp_cred, 'w', 0600 do |fp| - fp.puts ':rubygems_api_key: 701229f217cdf23b1344c7b4b54ca97' + File.open temp_cred, "w", 0o600 do |fp| + fp.puts ":rubygems_api_key: 701229f217cdf23b1344c7b4b54ca97" end util_config_file - assert_equal({:rubygems => '701229f217cdf23b1344c7b4b54ca97'}, + assert_equal({ rubygems: "701229f217cdf23b1344c7b4b54ca97" }, @cfg.api_keys) end def test_check_credentials_permissions - skip 'chmod not supported' if win_platform? + pend "chmod not supported" if Gem.win_platform? - @cfg.rubygems_api_key = 'x' + @cfg.rubygems_api_key = "x" - File.chmod 0644, @cfg.credentials_path + File.chmod 0o644, @cfg.credentials_path use_ui @ui do assert_raise Gem::MockGemUi::TermError do @@ -239,6 +242,12 @@ if you believe they were disclosed to a third party. end def test_handle_arguments_backtrace + File.open @temp_conf, "w" do |fp| + fp.puts ":backtrace: false" + end + + util_config_file %W[--config-file=#{@temp_conf}] + assert_equal false, @cfg.backtrace args = %w[--backtrace] @@ -257,7 +266,7 @@ if you believe they were disclosed to a third party. @cfg.handle_arguments args end - assert_match 'NOTE', err + assert_match "NOTE", err assert_equal true, $DEBUG ensure @@ -265,7 +274,7 @@ if you believe they were disclosed to a third party. end def test_handle_arguments_override - File.open @temp_conf, 'w' do |fp| + File.open @temp_conf, "w" do |fp| fp.puts ":backtrace: false" end @@ -275,6 +284,12 @@ if you believe they were disclosed to a third party. end def test_handle_arguments_traceback + File.open @temp_conf, "w" do |fp| + fp.puts ":backtrace: false" + end + + util_config_file %W[--config-file=#{@temp_conf}] + assert_equal false, @cfg.backtrace args = %w[--traceback] @@ -287,8 +302,8 @@ if you believe they were disclosed to a third party. def test_handle_arguments_norc assert_equal @temp_conf, @cfg.config_file_name - File.open @temp_conf, 'w' do |fp| - fp.puts ":backtrace: true" + File.open @temp_conf, "w" do |fp| + fp.puts ":backtrace: false" fp.puts ":update_sources: false" fp.puts ":bulk_threshold: 10" fp.puts ":verbose: false" @@ -300,7 +315,7 @@ if you believe they were disclosed to a third party. util_config_file args - assert_equal false, @cfg.backtrace + assert_equal true, @cfg.backtrace assert_equal true, @cfg.update_sources assert_equal Gem::ConfigFile::DEFAULT_BULK_THRESHOLD, @cfg.bulk_threshold assert_equal true, @cfg.verbose @@ -308,25 +323,30 @@ if you believe they were disclosed to a third party. end def test_load_api_keys - temp_cred = File.join Gem.user_home, '.gem', 'credentials' + temp_cred = File.join Gem.user_home, ".gem", "credentials" FileUtils.mkdir_p File.dirname(temp_cred) - File.open temp_cred, 'w', 0600 do |fp| - fp.puts ":rubygems_api_key: 701229f217cdf23b1344c7b4b54ca97" - fp.puts ":other: a5fdbb6ba150cbb83aad2bb2fede64c" + File.open temp_cred, "w", 0o600 do |fp| + fp.puts ":rubygems_api_key: rubygems_b9ce70c306b3a2e248679fbbbd66722d408d3c8c4f00566c" + fp.puts ":other: rubygems_9636a120106ea8b81fbc792188251738665711d2ece160c5" + fp.puts "http://localhost:3000: rubygems_be293ad9dd71550a012b17d848893b41960b811ce9312b47" end util_config_file - assert_equal({:rubygems => '701229f217cdf23b1344c7b4b54ca97', - :other => 'a5fdbb6ba150cbb83aad2bb2fede64c'}, @cfg.api_keys) + assert_equal( + { :rubygems => "rubygems_b9ce70c306b3a2e248679fbbbd66722d408d3c8c4f00566c", + :other => "rubygems_9636a120106ea8b81fbc792188251738665711d2ece160c5", + "http://localhost:3000" => "rubygems_be293ad9dd71550a012b17d848893b41960b811ce9312b47" }, + @cfg.api_keys + ) end def test_load_api_keys_bad_permission - skip 'chmod not supported' if win_platform? + pend "chmod not supported" if Gem.win_platform? - @cfg.rubygems_api_key = 'x' + @cfg.rubygems_api_key = "x" - File.chmod 0644, @cfg.credentials_path + File.chmod 0o644, @cfg.credentials_path assert_raise Gem::MockGemUi::TermError do @cfg.load_api_keys @@ -346,72 +366,72 @@ if you believe they were disclosed to a third party. end def test_rubygems_api_key_equals - @cfg.rubygems_api_key = 'x' + @cfg.rubygems_api_key = "x" - assert_equal 'x', @cfg.rubygems_api_key + assert_equal "x", @cfg.rubygems_api_key expected = { - :rubygems_api_key => 'x', + rubygems_api_key: "x", } - assert_equal expected, YAML.load_file(@cfg.credentials_path) + assert_equal expected, load_yaml_file(@cfg.credentials_path) - unless win_platform? + unless Gem.win_platform? stat = File.stat @cfg.credentials_path - assert_equal 0600, stat.mode & 0600 + assert_equal 0o600, stat.mode & 0o600 end end def test_rubygems_api_key_equals_bad_permission - skip 'chmod not supported' if win_platform? + pend "chmod not supported" if Gem.win_platform? - @cfg.rubygems_api_key = 'x' + @cfg.rubygems_api_key = "x" - File.chmod 0644, @cfg.credentials_path + File.chmod 0o644, @cfg.credentials_path assert_raise Gem::MockGemUi::TermError do - @cfg.rubygems_api_key = 'y' + @cfg.rubygems_api_key = "y" end expected = { - :rubygems_api_key => 'x', + rubygems_api_key: "x", } - assert_equal expected, YAML.load_file(@cfg.credentials_path) + assert_equal expected, load_yaml_file(@cfg.credentials_path) stat = File.stat @cfg.credentials_path - assert_equal 0644, stat.mode & 0644 + assert_equal 0o644, stat.mode & 0o644 end def test_write - @cfg.backtrace = true + @cfg.backtrace = false @cfg.update_sources = false @cfg.bulk_threshold = 10 @cfg.verbose = false Gem.sources.replace %w[http://more-gems.example.com] - @cfg[:install] = '--wrappers' + @cfg[:install] = "--wrappers" @cfg.write util_config_file # These should not be written out to the config file. - assert_equal false, @cfg.backtrace, 'backtrace' + assert_equal true, @cfg.backtrace, "backtrace" assert_equal Gem::ConfigFile::DEFAULT_BULK_THRESHOLD, @cfg.bulk_threshold, - 'bulk_threshold' - assert_equal true, @cfg.update_sources, 'update_sources' - assert_equal true, @cfg.verbose, 'verbose' + "bulk_threshold" + assert_equal true, @cfg.update_sources, "update_sources" + assert_equal true, @cfg.verbose, "verbose" - assert_equal '--wrappers', @cfg[:install], 'install' + assert_equal "--wrappers", @cfg[:install], "install" # this should be written out to the config file. assert_equal %w[http://more-gems.example.com], Gem.sources end def test_write_from_hash - File.open @temp_conf, 'w' do |fp| + File.open @temp_conf, "w" do |fp| fp.puts ":backtrace: true" fp.puts ":bulk_threshold: 10" fp.puts ":update_sources: false" @@ -431,34 +451,35 @@ if you believe they were disclosed to a third party. @cfg.bulk_threshold = 20 @cfg.verbose = :junk Gem.sources.replace %w[http://even-more-gems.example.com] - @cfg[:install] = '--wrappers --no-rdoc' + @cfg[:install] = "--wrappers --no-rdoc" @cfg.write util_config_file # These should not be written out to the config file - assert_equal true, @cfg.backtrace, 'backtrace' - assert_equal 10, @cfg.bulk_threshold, 'bulk_threshold' - assert_equal false, @cfg.update_sources, 'update_sources' - assert_equal false, @cfg.verbose, 'verbose' + assert_equal true, @cfg.backtrace, "backtrace" + assert_equal 10, @cfg.bulk_threshold, "bulk_threshold" + assert_equal false, @cfg.update_sources, "update_sources" + assert_equal false, @cfg.verbose, "verbose" assert_equal 2, @cfg.ssl_verify_mode - assert_equal '/nonexistent/ca_cert.pem', @cfg.ssl_ca_cert - assert_equal '/nonexistent/client_cert.pem', @cfg.ssl_client_cert + assert_equal "/nonexistent/ca_cert.pem", @cfg.ssl_ca_cert + assert_equal "/nonexistent/client_cert.pem", @cfg.ssl_client_cert - assert_equal '--wrappers --no-rdoc', @cfg[:install], 'install' + assert_equal "--wrappers --no-rdoc", @cfg[:install], "install" assert_equal %w[http://even-more-gems.example.com], Gem.sources end def test_ignore_invalid_config_file - File.open @temp_conf, 'w' do |fp| + File.open @temp_conf, "w" do |fp| fp.puts "invalid: yaml:" end begin - verbose, $VERBOSE = $VERBOSE, nil + verbose = $VERBOSE + $VERBOSE = nil util_config_file ensure @@ -466,8 +487,18 @@ if you believe they were disclosed to a third party. end end + def test_accept_string_key + File.open @temp_conf, "w" do |fp| + fp.puts "verbose: false" + end + + util_config_file + + assert_equal false, @cfg.verbose + end + def test_load_ssl_verify_mode_from_config - File.open @temp_conf, 'w' do |fp| + File.open @temp_conf, "w" do |fp| fp.puts ":ssl_verify_mode: 1" end util_config_file @@ -475,30 +506,76 @@ if you believe they were disclosed to a third party. end def test_load_ssl_ca_cert_from_config - File.open @temp_conf, 'w' do |fp| + File.open @temp_conf, "w" do |fp| fp.puts ":ssl_ca_cert: /home/me/certs" end util_config_file - assert_equal('/home/me/certs', @cfg.ssl_ca_cert) + assert_equal("/home/me/certs", @cfg.ssl_ca_cert) end def test_load_ssl_client_cert_from_config - File.open @temp_conf, 'w' do |fp| + File.open @temp_conf, "w" do |fp| fp.puts ":ssl_client_cert: /home/me/mine.pem" end util_config_file - assert_equal('/home/me/mine.pem', @cfg.ssl_client_cert) + assert_equal("/home/me/mine.pem", @cfg.ssl_client_cert) end - def util_config_file(args = @cfg_args) - @cfg = Gem::ConfigFile.new args + def test_load_install_extension_in_lib_from_config + File.open @temp_conf, "w" do |fp| + fp.puts ":install_extension_in_lib: false" + end + util_config_file + assert_equal(false, @cfg.install_extension_in_lib) end def test_disable_default_gem_server - File.open @temp_conf, 'w' do |fp| + 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 + + def test_load_with_rubygems_config_hash + yaml = <<~YAML + --- + :foo: bar + bar: 100 + buzz: true + alpha: :bravo + charlie: "" + delta: + YAML + actual = Gem::ConfigFile.load_with_rubygems_config_hash(yaml) + + assert_equal "bar", actual[:foo] + assert_equal 100, actual["bar"] + assert_equal true, actual["buzz"] + assert_equal :bravo, actual["alpha"] + assert_equal nil, actual["charlie"] + assert_equal nil, actual["delta"] + end + + def test_dump_with_rubygems_yaml + symbol_key_hash = { foo: "bar" } + + actual = Gem::ConfigFile.dump_with_rubygems_yaml(symbol_key_hash) + + assert_equal("---\n:foo: \"bar\"\n", actual) + end + + def test_handle_comment + yaml = <<~YAML + --- + :foo: bar # buzz + YAML + + actual = Gem::ConfigFile.load_with_rubygems_config_hash(yaml) + assert_equal("bar", actual[:foo]) + end + + def util_config_file(args = @cfg_args) + @cfg = Gem::ConfigFile.new args + end end diff --git a/test/rubygems/test_gem_console_ui.rb b/test/rubygems/test_gem_console_ui.rb new file mode 100644 index 0000000000..b8a619625f --- /dev/null +++ b/test/rubygems/test_gem_console_ui.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require_relative "helper" +require "rubygems/user_interaction" + +class TestGemConsoleUI < Gem::TestCase + def test_output_can_be_captured_by_test_unit + output = capture_output do + ui = Gem::ConsoleUI.new + + ui.alert_error "test error" + ui.alert_warning "test warning" + ui.alert "test alert" + end + + assert_equal "INFO: test alert\n", output.first + assert_equal "ERROR: test error\n" + "WARNING: test warning\n", output.last + end +end diff --git a/test/rubygems/test_gem_dependency.rb b/test/rubygems/test_gem_dependency.rb index 69208d3258..2a989a5551 100644 --- a/test/rubygems/test_gem_dependency.rb +++ b/test/rubygems/test_gem_dependency.rb @@ -1,8 +1,15 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/dependency' + +require_relative "helper" +require "rubygems/dependency" class TestGemDependency < Gem::TestCase + def setup + super + + without_any_upwards_gemfiles + end + def test_initialize d = dep "pkg", "> 1.0" @@ -12,7 +19,7 @@ class TestGemDependency < Gem::TestCase def test_initialize_type_bad e = assert_raise ArgumentError do - Gem::Dependency.new 'monkey' => '1.0' + Gem::Dependency.new "monkey" => "1.0" end assert_equal 'dependency name must be a String, was {"monkey"=>"1.0"}', @@ -30,11 +37,11 @@ class TestGemDependency < Gem::TestCase end def test_initialize_prerelease - d = dep 'd', '1.a' + d = dep "d", "1.a" assert d.prerelease? - d = dep 'd', '= 1.a' + d = dep "d", "= 1.a" assert d.prerelease? end @@ -99,8 +106,13 @@ class TestGemDependency < Gem::TestCase def test_equals_tilde_object o = Object.new - def o.name ; 'a' end - def o.version ; '0' end + def o.name + "a" + end + + def o.version + "0" + end assert_match dep("a"), o end @@ -127,142 +139,142 @@ class TestGemDependency < Gem::TestCase end def test_match_eh_name_tuple - a_dep = dep 'a' + a_dep = dep "a" - a_tup = Gem::NameTuple.new 'a', 1 - b_tup = Gem::NameTuple.new 'b', 2 - c_tup = Gem::NameTuple.new 'c', '2.a' + a_tup = Gem::NameTuple.new "a", 1 + b_tup = Gem::NameTuple.new "b", 2 + c_tup = Gem::NameTuple.new "c", "2.a" assert a_dep.match? a_tup refute a_dep.match? b_tup - b_dep = dep 'b', '>= 3' + b_dep = dep "b", ">= 3" refute b_dep.match? b_tup - c_dep = dep 'c', '>= 1' + c_dep = dep "c", ">= 1" refute c_dep.match? c_tup - c_dep = dep 'c' + c_dep = dep "c" refute c_dep.match? c_tup - c_dep = dep 'c', '2.a' + c_dep = dep "c", "2.a" assert c_dep.match? c_tup end def test_match_eh_allow_prerelease - a_dep = dep 'a' + a_dep = dep "a" - a_tup = Gem::NameTuple.new 'a', 1 - b_tup = Gem::NameTuple.new 'b', 2 - c_tup = Gem::NameTuple.new 'c', '2.a' + a_tup = Gem::NameTuple.new "a", 1 + b_tup = Gem::NameTuple.new "b", 2 + c_tup = Gem::NameTuple.new "c", "2.a" assert a_dep.match? a_tup, nil, true refute a_dep.match? b_tup, nil, true - b_dep = dep 'b', '>= 3' + b_dep = dep "b", ">= 3" refute b_dep.match? b_tup, nil, true - c_dep = dep 'c', '>= 1' + c_dep = dep "c", ">= 1" assert c_dep.match? c_tup, nil, true - c_dep = dep 'c' + c_dep = dep "c" assert c_dep.match? c_tup, nil, true - c_dep = dep 'c', '2.a' + c_dep = dep "c", "2.a" assert c_dep.match? c_tup, nil, true end def test_match_eh_specification - a_dep = dep 'a' + a_dep = dep "a" - a_spec = util_spec 'a', 1 - b_spec = util_spec 'b', 2 - c_spec = util_spec 'c', '2.a' + a_spec = util_spec "a", 1 + b_spec = util_spec "b", 2 + c_spec = util_spec "c", "2.a" assert a_dep.match? a_spec refute a_dep.match? b_spec - b_dep = dep 'b', '>= 3' + b_dep = dep "b", ">= 3" refute b_dep.match? b_spec - c_dep = dep 'c', '>= 1' + c_dep = dep "c", ">= 1" refute c_dep.match? c_spec - c_dep = dep 'c' + c_dep = dep "c" refute c_dep.match? c_spec - c_dep = dep 'c', '2.a' + c_dep = dep "c", "2.a" assert c_dep.match? c_spec end def test_matches_spec_eh - spec = util_spec 'b', 2 + spec = util_spec "b", 2 - refute dep('a') .matches_spec?(spec), 'name mismatch' - assert dep('b') .matches_spec?(spec), 'name match' - refute dep('b', '= 1') .matches_spec?(spec), 'requirement mismatch' - assert dep('b', '~> 2').matches_spec?(spec), 'requirement match' + refute dep("a") .matches_spec?(spec), "name mismatch" + assert dep("b") .matches_spec?(spec), "name match" + refute dep("b", "= 1") .matches_spec?(spec), "requirement mismatch" + assert dep("b", "~> 2").matches_spec?(spec), "requirement match" end def test_matches_spec_eh_prerelease - spec = util_spec 'b', '2.1.a' + spec = util_spec "b", "2.1.a" - refute dep('a') .matches_spec?(spec), 'name mismatch' - assert dep('b') .matches_spec?(spec), 'name match' - refute dep('b', '= 1') .matches_spec?(spec), 'requirement mismatch' - assert dep('b', '~> 2') .matches_spec?(spec), 'requirement match' - assert dep('b', '~> 2.a').matches_spec?(spec), 'prerelease requirement' + refute dep("a") .matches_spec?(spec), "name mismatch" + assert dep("b") .matches_spec?(spec), "name match" + refute dep("b", "= 1") .matches_spec?(spec), "requirement mismatch" + assert dep("b", "~> 2") .matches_spec?(spec), "requirement match" + assert dep("b", "~> 2.a").matches_spec?(spec), "prerelease requirement" end def test_merge - a1 = dep 'a', '~> 1.0' - a2 = dep 'a', '= 1.0' + a1 = dep "a", "~> 1.0" + a2 = dep "a", "= 1.0" a3 = a1.merge a2 - assert_equal dep('a', '~> 1.0', '= 1.0'), a3 + assert_equal dep("a", "~> 1.0", "= 1.0"), a3 end def test_merge_default - a1 = dep 'a' - a2 = dep 'a', '1' + a1 = dep "a" + a2 = dep "a", "1" a3 = a1.merge a2 - assert_equal dep('a', '1'), a3 + assert_equal dep("a", "1"), a3 end def test_merge_name_mismatch - a = dep 'a' - b = dep 'b' + a = dep "a" + b = dep "b" e = assert_raise ArgumentError do a.merge b end - assert_equal 'a (>= 0) and b (>= 0) have different names', + assert_equal "a (>= 0) and b (>= 0) have different names", e.message end def test_merge_other_default - a1 = dep 'a', '1' - a2 = dep 'a' + a1 = dep "a", "1" + a2 = dep "a" a3 = a1.merge a2 - assert_equal dep('a', '1'), a3 + assert_equal dep("a", "1"), a3 end def test_prerelease_eh @@ -288,44 +300,44 @@ class TestGemDependency < Gem::TestCase end def test_specific - refute dep('a', '> 1').specific? + refute dep("a", "> 1").specific? - assert dep('a', '= 1').specific? + assert dep("a", "= 1").specific? end def test_to_spec - a_1 = util_spec 'a', '1' - a_2 = util_spec 'a', '2' + a_1 = util_spec "a", "1" + a_2 = util_spec "a", "2" - a_dep = dep 'a', '>= 0' + a_dep = dep "a", ">= 0" install_specs a_1, a_2 assert_equal a_2, a_dep.to_spec end def test_to_spec_prerelease - a_1 = util_spec 'a', '1' - a_1_1_a = util_spec 'a', '1.1.a' + a_1 = util_spec "a", "1" + a_1_1_a = util_spec "a", "1.1.a" - a_dep = dep 'a', '>= 0' + a_dep = dep "a", ">= 0" install_specs a_1, a_1_1_a assert_equal a_1, a_dep.to_spec - a_pre_dep = dep 'a', '>= 0' + a_pre_dep = dep "a", ">= 0" a_pre_dep.prerelease = true assert_equal a_1_1_a, a_pre_dep.to_spec end def test_to_specs_suggests_other_versions - a = util_spec 'a', '1.0' + a = util_spec "a", "1.0" install_specs a - a_file = File.join a.gem_dir, 'lib', 'a_file.rb' + a_file = File.join a.gem_dir, "lib", "a_file.rb" write_file a_file do |io| - io.puts '# a_file.rb' + io.puts "# a_file.rb" end dep = Gem::Dependency.new "a", "= 2.0" @@ -338,41 +350,39 @@ class TestGemDependency < Gem::TestCase end def test_to_specs_respects_bundler_version - b = util_spec 'bundler', '2.0.0.pre.1' - b_1 = util_spec 'bundler', '1' + b = util_spec "bundler", "2.0.0.pre.1" + b_1 = util_spec "bundler", "1" install_specs b, b_1 - b_file = File.join b.gem_dir, 'lib', 'bundler', 'setup.rb' + b_file = File.join b.gem_dir, "lib", "bundler", "setup.rb" write_file b_file do |io| - io.puts '# setup.rb' + io.puts "# setup.rb" end dep = Gem::Dependency.new "bundler", ">= 0.a" assert_equal [b, b_1], dep.to_specs - Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["3.5", "reason"]) do - e = assert_raise Gem::MissingSpecVersionError do - dep.to_specs - end + require "rubygems/bundler_version_finder" - assert_match "Could not find 'bundler' (3.5) required by reason.\nTo update to the latest version installed on your system, run `bundle update --bundler`.\nTo install the missing version, run `gem install bundler:3.5`\n", e.message + Gem::BundlerVersionFinder.stub(:bundler_version, Gem::Version.new("1")) do + assert_equal [b_1, b], dep.to_specs end - Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["2.0.0.pre.1", "reason"]) do - assert_equal [b], dep.to_specs + Gem::BundlerVersionFinder.stub(:bundler_version, Gem::Version.new("2.0.0.pre.1")) do + assert_equal [b, b_1], dep.to_specs end end def test_to_specs_indicates_total_gem_set_size - a = util_spec 'a', '1.0' + a = util_spec "a", "1.0" install_specs a - a_file = File.join a.gem_dir, 'lib', 'a_file.rb' + a_file = File.join a.gem_dir, "lib", "a_file.rb" write_file a_file do |io| - io.puts '# a_file.rb' + io.puts "# a_file.rb" end dep = Gem::Dependency.new "b", "= 2.0" @@ -384,6 +394,16 @@ class TestGemDependency < Gem::TestCase assert_match "Could not find 'b' (= 2.0) among 1 total gem(s)", e.message end + def test_to_spec_with_only_prereleases + a_2_a_1 = util_spec "a", "2.a1" + a_2_a_2 = util_spec "a", "2.a2" + install_specs a_2_a_1, a_2_a_2 + + a_dep = dep "a", ">= 1" + + assert_equal a_2_a_2, a_dep.to_spec + end + def test_identity assert_equal dep("a", "= 1").identity, :released assert_equal dep("a", "= 1.a").identity, :complete diff --git a/test/rubygems/test_gem_dependency_installer.rb b/test/rubygems/test_gem_dependency_installer.rb index 90d5d16403..8999723ba1 100644 --- a/test/rubygems/test_gem_dependency_installer.rb +++ b/test/rubygems/test_gem_dependency_installer.rb @@ -1,15 +1,16 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/dependency_installer' -require 'rubygems/security' + +require_relative "helper" +require "rubygems/dependency_installer" +require "rubygems/security" class TestGemDependencyInstaller < Gem::TestCase def setup super common_installer_setup - @gems_dir = File.join @tempdir, 'gems' - @cache_dir = File.join @gemhome, 'cache' + @gems_dir = File.join @tempdir, "gems" + @cache_dir = File.join @gemhome, "cache" FileUtils.mkdir @gems_dir @@ -25,23 +26,23 @@ class TestGemDependencyInstaller < Gem::TestCase end def util_setup_gems - @a1, @a1_gem = util_gem 'a', '1' do |s| - s.executables << 'a_bin' + @a1, @a1_gem = util_gem "a", "1" do |s| + s.executables << "a_bin" end - @a1_pre, @a1_pre_gem = util_gem 'a', '1.a' + @a1_pre, @a1_pre_gem = util_gem "a", "1.a" - @b1, @b1_gem = util_gem 'b', '1' do |s| - s.add_dependency 'a' - s.add_development_dependency 'aa' + @b1, @b1_gem = util_gem "b", "1" do |s| + s.add_dependency "a" + s.add_development_dependency "aa" end - @c1, @c1_gem = util_gem 'c', '1' do |s| - s.add_development_dependency 'b' + @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' + @d1, @d1_gem = util_gem "d", "1" do |s| + s.add_development_dependency "c" end util_setup_spec_fetcher(@a1, @a1_pre, @b1, @d1) @@ -55,7 +56,7 @@ class TestGemDependencyInstaller < Gem::TestCase Dir.chdir @tempdir do inst = Gem::DependencyInstaller.new - inst.install 'a' + inst.install "a" end assert_equal %w[a-1], Gem::Specification.map(&:full_name) @@ -65,16 +66,16 @@ class TestGemDependencyInstaller < Gem::TestCase def test_install_prerelease util_setup_gems - p1a, gem = util_gem 'a', '10.a' + p1a, gem = util_gem "a", "10.a" util_setup_spec_fetcher(p1a, @a1, @a1_pre) p1a_data = Gem.read_binary(gem) - @fetcher.data['http://gems.example.com/gems/a-10.a.gem'] = p1a_data + @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 = Gem::DependencyInstaller.new prerelease: true inst.install dep assert_equal %w[a-10.a], Gem::Specification.map(&:full_name) @@ -83,33 +84,33 @@ class TestGemDependencyInstaller < Gem::TestCase def test_install_prerelease_bug_990 spec_fetcher do |fetcher| - fetcher.gem 'a', '1.b' do |s| - s.add_dependency 'b', '~> 1.a' + fetcher.gem "a", "1.b" do |s| + s.add_dependency "b", "~> 1.a" end - fetcher.gem 'b', '1.b' do |s| - s.add_dependency 'c', '>= 1' + fetcher.gem "b", "1.b" do |s| + s.add_dependency "c", ">= 1" end - fetcher.gem 'c', '1.1.b' + fetcher.gem "c", "1.1.b" end - dep = Gem::Dependency.new 'a' + dep = Gem::Dependency.new "a" - inst = Gem::DependencyInstaller.new :prerelease => true + inst = Gem::DependencyInstaller.new prerelease: true inst.install dep assert_equal %w[a-1.b b-1.b c-1.1.b], Gem::Specification.map(&:full_name) end def test_install_when_only_prerelease - p1a, gem = util_gem 'p', '1.a' + p1a, gem = util_gem "p", "1.a" util_setup_spec_fetcher(p1a) p1a_data = Gem.read_binary(gem) - @fetcher.data['http://gems.example.com/gems/p-1.a.gem'] = p1a_data + @fetcher.data["http://gems.example.com/gems/p-1.a.gem"] = p1a_data dep = Gem::Dependency.new "p" inst = Gem::DependencyInstaller.new @@ -128,10 +129,10 @@ class TestGemDependencyInstaller < Gem::TestCase p1a_data = Gem.read_binary(@a1_gem) - @fetcher.data['http://gems.example.com/gems/a-1.gem'] = p1a_data + @fetcher.data["http://gems.example.com/gems/a-1.gem"] = p1a_data dep = Gem::Dependency.new "a" - inst = Gem::DependencyInstaller.new :prerelease => true + inst = Gem::DependencyInstaller.new prerelease: true inst.install dep assert_equal %w[a-1], Gem::Specification.map(&:full_name) @@ -141,8 +142,8 @@ class TestGemDependencyInstaller < Gem::TestCase def test_install_all_dependencies util_setup_gems - _, e1_gem = util_gem 'e', '1' do |s| - s.add_dependency 'b' + _, e1_gem = util_gem "e", "1" do |s| + s.add_dependency "b" end FileUtils.mv @a1_gem, @tempdir @@ -152,19 +153,19 @@ class TestGemDependencyInstaller < Gem::TestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new :ignore_dependencies => true - inst.install 'b' + inst = Gem::DependencyInstaller.new ignore_dependencies: true + inst.install "b" end - assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name }, - 'sanity check' + assert_equal %w[b-1], inst.installed_gems.map(&:full_name), + "sanity check" Dir.chdir @tempdir do inst = Gem::DependencyInstaller.new - inst.install 'e' + inst.install "e" end - assert_equal %w[a-1 e-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[a-1 e-1], inst.installed_gems.map(&:full_name) end def test_install_cache_dir @@ -177,11 +178,11 @@ class TestGemDependencyInstaller < Gem::TestCase inst = nil Dir.chdir dir do - inst = Gem::DependencyInstaller.new :cache_dir => @tempdir - inst.install 'b' + inst = Gem::DependencyInstaller.new cache_dir: @tempdir + inst.install "b" end - assert_equal %w[a-1 b-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name) assert File.exist? File.join(@gemhome, "cache", @a1.file_name) assert File.exist? File.join(@gemhome, "cache", @b1.file_name) @@ -190,34 +191,34 @@ class TestGemDependencyInstaller < Gem::TestCase def test_install_dependencies_satisfied util_setup_gems - a2, a2_gem = util_gem 'a', '2' + a2, a2_gem = util_gem "a", "2" - FileUtils.rm_rf File.join(@gemhome, 'gems') + 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 a2_gem, @tempdir # not in index FileUtils.mv @b1_gem, @tempdir inst = nil Dir.chdir @tempdir do inst = Gem::DependencyInstaller.new - inst.install 'a', req("= 2") + inst.install "a", req("= 2") end - assert_equal %w[a-2], inst.installed_gems.map {|s| s.full_name }, - 'sanity check' + assert_equal %w[a-2], inst.installed_gems.map(&:full_name), + "sanity check" FileUtils.rm File.join(@tempdir, a2.file_name) Dir.chdir @tempdir do inst = Gem::DependencyInstaller.new - inst.install 'b' + 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 } + assert_equal %w[b-1], inst.installed_gems.map(&:full_name) end # This asserts that if a gem's dependency is satisfied by an @@ -226,22 +227,22 @@ class TestGemDependencyInstaller < Gem::TestCase def test_install_doesnt_upgrade_installed_dependencies util_setup_gems - a2, a2_gem = util_gem 'a', '2' - a3, a3_gem = util_gem 'a', '3' + 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') + 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 a2_gem, @tempdir # not in index FileUtils.mv @b1_gem, @tempdir FileUtils.mv a3_gem, @tempdir Dir.chdir @tempdir do - Gem::DependencyInstaller.new.install 'a', req("= 2") + Gem::DependencyInstaller.new.install "a", req("= 2") end FileUtils.rm File.join(@tempdir, a2.file_name) @@ -250,11 +251,11 @@ class TestGemDependencyInstaller < Gem::TestCase Dir.chdir @tempdir do inst = Gem::DependencyInstaller.new - inst.install 'b' + 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 } + assert_equal %w[b-1], inst.installed_gems.map(&:full_name) end def test_install_dependency @@ -273,19 +274,19 @@ class TestGemDependencyInstaller < Gem::TestCase FileUtils.mv @b1_gem, @tempdir Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new(:build_docs_in_background => false) - inst.install 'b' + 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_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name) - assert done_installing_ran, 'post installs hook was not run' + assert done_installing_ran, "post installs hook was not run" end def test_install_dependency_development util_setup_gems - @aa1, @aa1_gem = util_gem 'aa', '1' + @aa1, @aa1_gem = util_gem "aa", "1" FileUtils.mv @a1_gem, @tempdir FileUtils.mv @aa1_gem, @tempdir @@ -293,17 +294,17 @@ class TestGemDependencyInstaller < Gem::TestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new(:development => true) - inst.install 'b' + inst = Gem::DependencyInstaller.new(development: true) + inst.install "b" end - assert_equal %w[a-1 aa-1 b-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[a-1 aa-1 b-1], inst.installed_gems.map(&:full_name) end def test_install_dependency_development_deep util_setup_gems - @aa1, @aa1_gem = util_gem 'aa', '1' + @aa1, @aa1_gem = util_gem "aa", "1" FileUtils.mv @a1_gem, @tempdir FileUtils.mv @aa1_gem, @tempdir @@ -313,17 +314,17 @@ class TestGemDependencyInstaller < Gem::TestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new(:development => true) - inst.install 'd' + 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 } + assert_equal %w[a-1 aa-1 b-1 c-1 d-1], inst.installed_gems.map(&:full_name) end def test_install_dependency_development_shallow util_setup_gems - @aa1, @aa1_gem = util_gem 'aa', '1' + @aa1, @aa1_gem = util_gem "aa", "1" FileUtils.mv @a1_gem, @tempdir FileUtils.mv @aa1_gem, @tempdir @@ -333,11 +334,11 @@ class TestGemDependencyInstaller < Gem::TestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new(:development => true, :dev_shallow => true) - inst.install 'd' + 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 } + assert_equal %w[c-1 d-1], inst.installed_gems.map(&:full_name) end def test_install_dependency_existing @@ -350,29 +351,29 @@ class TestGemDependencyInstaller < Gem::TestCase Dir.chdir @tempdir do inst = Gem::DependencyInstaller.new - inst.install 'b' + inst.install "b" end - assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[b-1], inst.installed_gems.map(&:full_name) end def test_install_dependency_existing_extension - extconf_rb = File.join @gemhome, 'gems', 'e-1', 'extconf.rb' + extconf_rb = File.join @gemhome, "gems", "e-1", "extconf.rb" FileUtils.mkdir_p File.dirname extconf_rb - File.open extconf_rb, 'w' do |io| + File.open extconf_rb, "w" do |io| io.write <<-EXTCONF_RB require 'mkmf' create_makefile 'e' EXTCONF_RB end - e1 = util_spec 'e', '1', nil, 'extconf.rb' do |s| - s.extensions << 'extconf.rb' + e1 = util_spec "e", "1", nil, "extconf.rb" do |s| + s.extensions << "extconf.rb" end e1_gem = e1.cache_file - _, f1_gem = util_gem 'f', '1', 'e' => nil + _, f1_gem = util_gem "f", "1", "e" => nil Gem::Installer.at(e1_gem).install FileUtils.rm_r e1.extension_dir @@ -385,20 +386,20 @@ class TestGemDependencyInstaller < Gem::TestCase Dir.chdir @tempdir begin inst = Gem::DependencyInstaller.new - inst.install 'f' + inst.install "f" ensure Dir.chdir pwd end - assert_equal %w[f-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[f-1], inst.installed_gems.map(&:full_name) assert_path_exist e1.extension_dir end def test_install_dependency_old - _, e1_gem = util_gem 'e', '1' - _, f1_gem = util_gem 'f', '1', 'e' => nil - _, f2_gem = util_gem 'f', '2' + _, e1_gem = util_gem "e", "1" + _, f1_gem = util_gem "f", "1", "e" => nil + _, f2_gem = util_gem "f", "2" FileUtils.mv e1_gem, @tempdir FileUtils.mv f1_gem, @tempdir @@ -407,10 +408,10 @@ class TestGemDependencyInstaller < Gem::TestCase Dir.chdir @tempdir do inst = Gem::DependencyInstaller.new - inst.install 'f' + inst.install "f" end - assert_equal %w[f-2], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[f-2], inst.installed_gems.map(&:full_name) end def test_install_local @@ -420,11 +421,11 @@ class TestGemDependencyInstaller < Gem::TestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new :domain => :local - inst.install 'a-1.gem' + inst = Gem::DependencyInstaller.new domain: :local + inst.install "a-1.gem" end - assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[a-1], inst.installed_gems.map(&:full_name) end def test_install_local_prerelease @@ -434,11 +435,11 @@ class TestGemDependencyInstaller < Gem::TestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new :domain => :local - inst.install 'a-1.a.gem' + inst = Gem::DependencyInstaller.new domain: :local + inst.install "a-1.a.gem" end - assert_equal %w[a-1.a], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[a-1.a], inst.installed_gems.map(&:full_name) end def test_install_local_dependency @@ -450,11 +451,11 @@ class TestGemDependencyInstaller < Gem::TestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new :domain => :local - inst.install 'b-1.gem' + inst = Gem::DependencyInstaller.new domain: :local + inst.install "b-1.gem" end - assert_equal %w[a-1 b-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name) end def test_install_local_dependency_installed @@ -466,13 +467,47 @@ class TestGemDependencyInstaller < Gem::TestCase inst = nil Dir.chdir @tempdir do - Gem::Installer.at('a-1.gem').install + Gem::Installer.at("a-1.gem").install - inst = Gem::DependencyInstaller.new :domain => :local - inst.install 'b-1.gem' + inst = Gem::DependencyInstaller.new domain: :local + inst.install "b-1.gem" end - assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[b-1], inst.installed_gems.map(&:full_name) + end + + def test_install_local_dependency_no_network_for_target_gem + a1, a1_gem = util_gem "a", "1" + _, b1_gem = util_gem "b", "1" do |s| + s.add_dependency "a" + end + + util_setup_spec_fetcher(a1) + + a1_data = Gem.read_binary(a1_gem) + @fetcher.data["http://gems.example.com/gems/a-1.gem"] = a1_data + + # compact index is available + compact_index_response = Gem::Net::HTTPResponse.new "1.1", 200, "OK" + compact_index_response.uri = Gem::URI("http://gems.example.com") + @fetcher.data["http://gems.example.com/"] = compact_index_response + + # but private local gem not present there + @fetcher.data["http://gems.example.com/info/b"] = + proc do + raise "should not happen" + end + + FileUtils.mv b1_gem, @tempdir + + inst = nil + + Dir.chdir @tempdir do + inst = Gem::DependencyInstaller.new + inst.install "b-1.gem" + end + + assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name) end def test_install_local_subdir @@ -481,22 +516,22 @@ class TestGemDependencyInstaller < Gem::TestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new :domain => :local - inst.install 'gems/a-1.gem' + inst = Gem::DependencyInstaller.new domain: :local + inst.install "gems/a-1.gem" end - assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[a-1], inst.installed_gems.map(&:full_name) end def test_install_minimal_deps util_setup_gems - _, e1_gem = util_gem 'e', '1' do |s| - s.add_dependency 'b' + _, e1_gem = util_gem "e", "1" do |s| + s.add_dependency "b" end - _, b2_gem = util_gem 'b', '2' do |s| - s.add_dependency 'a' + _, b2_gem = util_gem "b", "2" do |s| + s.add_dependency "a" end FileUtils.mv @a1_gem, @tempdir @@ -507,30 +542,30 @@ class TestGemDependencyInstaller < Gem::TestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new :ignore_dependencies => true - inst.install 'b', req('= 1') + inst = Gem::DependencyInstaller.new ignore_dependencies: true + inst.install "b", req("= 1") end - assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name }, - 'sanity check' + assert_equal %w[b-1], inst.installed_gems.map(&:full_name), + "sanity check" Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new :minimal_deps => true - inst.install 'e' + inst = Gem::DependencyInstaller.new minimal_deps: true + inst.install "e" end - assert_equal %w[a-1 e-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[a-1 e-1], inst.installed_gems.map(&:full_name) end def test_install_no_minimal_deps util_setup_gems - _, e1_gem = util_gem 'e', '1' do |s| - s.add_dependency 'b' + _, e1_gem = util_gem "e", "1" do |s| + s.add_dependency "b" end - _, b2_gem = util_gem 'b', '2' do |s| - s.add_dependency 'a' + _, b2_gem = util_gem "b", "2" do |s| + s.add_dependency "a" end FileUtils.mv @a1_gem, @tempdir @@ -541,19 +576,19 @@ class TestGemDependencyInstaller < Gem::TestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new :ignore_dependencies => true - inst.install 'b', req('= 1') + inst = Gem::DependencyInstaller.new ignore_dependencies: true + inst.install "b", req("= 1") end - assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name }, - 'sanity check' + assert_equal %w[b-1], inst.installed_gems.map(&:full_name), + "sanity check" Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new :minimal_deps => false - inst.install 'e' + inst = Gem::DependencyInstaller.new minimal_deps: false + inst.install "e" end - assert_equal %w[a-1 b-2 e-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[a-1 b-2 e-1], inst.installed_gems.map(&:full_name) end def test_install_no_document @@ -561,12 +596,12 @@ class TestGemDependencyInstaller < Gem::TestCase done_installing_called = false - Gem.done_installing do |dep_installer, specs| + Gem.done_installing do |dep_installer, _specs| done_installing_called = true assert_empty dep_installer.document end - inst = Gem::DependencyInstaller.new :domain => :local, :document => [] + inst = Gem::DependencyInstaller.new domain: :local, document: [] inst.install @a1_gem @@ -580,14 +615,14 @@ class TestGemDependencyInstaller < Gem::TestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new :env_shebang => true, :wrappers => true, :format_executable => false - inst.install 'a' + inst = Gem::DependencyInstaller.new env_shebang: true, wrappers: true, format_executable: false + inst.install "a" end env = "/\\S+/env" unless Gem.win_platform? - assert_match %r{\A#!#{env} #{RbConfig::CONFIG['ruby_install_name']}\n}, - File.read(File.join(@gemhome, 'bin', 'a_bin')) + assert_match(/\A#!#{env} #{RbConfig::CONFIG["ruby_install_name"]}\n/, + File.read(File.join(@gemhome, "bin", "a_bin"))) end def test_install_force @@ -595,15 +630,15 @@ class TestGemDependencyInstaller < Gem::TestCase FileUtils.mv @b1_gem, @tempdir si = util_setup_spec_fetcher @b1 - @fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml + @fetcher.data["http://gems.example.com/gems/yaml"] = si.to_yaml inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new :force => true - inst.install 'b' + inst = Gem::DependencyInstaller.new force: true + inst.install "b" end - assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[b-1], inst.installed_gems.map(&:full_name) end def test_install_build_args @@ -614,9 +649,8 @@ class TestGemDependencyInstaller < Gem::TestCase build_args = %w[--a --b="c"] Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new( - :build_args => build_args) - inst.install 'a' + inst = Gem::DependencyInstaller.new(build_args: build_args) + inst.install "a" end assert_equal build_args.join("\n"), File.read(inst.installed_gems.first.build_info_file).strip @@ -629,11 +663,11 @@ class TestGemDependencyInstaller < Gem::TestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new :ignore_dependencies => true - inst.install 'b' + inst = Gem::DependencyInstaller.new ignore_dependencies: true + inst.install "b" end - assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[b-1], inst.installed_gems.map(&:full_name) end def test_install_install_dir @@ -645,40 +679,40 @@ class TestGemDependencyInstaller < Gem::TestCase inst = Gem::Installer.at @a1.file_name inst.install - gemhome2 = File.join @tempdir, 'gemhome2' + gemhome2 = File.join @tempdir, "gemhome2" Dir.mkdir gemhome2 inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new :install_dir => gemhome2 - inst.install 'b' + inst = Gem::DependencyInstaller.new install_dir: gemhome2 + inst.install "b" end - assert_equal %w[a-1 b-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name) - assert File.exist?(File.join(gemhome2, 'specifications', @a1.spec_name)) - assert File.exist?(File.join(gemhome2, 'cache', @a1.file_name)) + assert File.exist?(File.join(gemhome2, "specifications", @a1.spec_name)) + assert File.exist?(File.join(gemhome2, "cache", @a1.file_name)) end def test_install_domain_both util_setup_gems a1_data = nil - File.open @a1_gem, 'rb' do |fp| + File.open @a1_gem, "rb" do |fp| a1_data = fp.read end - @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data + @fetcher.data["http://gems.example.com/gems/a-1.gem"] = a1_data FileUtils.mv @b1_gem, @tempdir inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new :domain => :both - inst.install 'b' + inst = Gem::DependencyInstaller.new domain: :both + inst.install "b" end - assert_equal %w[a-1 b-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name) a1, b1 = inst.installed_gems assert_equal a1.spec_file, a1.loaded_from @@ -698,11 +732,11 @@ class TestGemDependencyInstaller < Gem::TestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new :domain => :both - inst.install 'b' + inst = Gem::DependencyInstaller.new domain: :both + inst.install "b" end - assert_equal %w[a-1 b-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[a-1 b-1], inst.installed_gems.map(&:full_name) end def test_install_domain_local @@ -713,31 +747,31 @@ class TestGemDependencyInstaller < Gem::TestCase Dir.chdir @tempdir do e = assert_raise Gem::UnsatisfiableDependencyError do - inst = Gem::DependencyInstaller.new :domain => :local - inst.install 'b' + inst = Gem::DependencyInstaller.new domain: :local + inst.install "b" end expected = "Unable to resolve dependency: 'b (>= 0)' requires 'a (>= 0)'" assert_equal expected, e.message end - assert_equal [], inst.installed_gems.map {|s| s.full_name } + assert_equal [], inst.installed_gems.map(&:full_name) end def test_install_domain_remote util_setup_gems a1_data = nil - File.open @a1_gem, 'rb' do |fp| + File.open @a1_gem, "rb" do |fp| a1_data = fp.read end - @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data + @fetcher.data["http://gems.example.com/gems/a-1.gem"] = a1_data - inst = Gem::DependencyInstaller.new :domain => :remote - inst.install 'a' + inst = Gem::DependencyInstaller.new domain: :remote + inst.install "a" - assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[a-1], inst.installed_gems.map(&:full_name) end def test_install_dual_repository @@ -750,23 +784,23 @@ class TestGemDependencyInstaller < Gem::TestCase gemhome2 = "#{@gemhome}2" Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new :install_dir => gemhome2 - inst.install 'a' + inst = Gem::DependencyInstaller.new install_dir: gemhome2 + inst.install "a" end - assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name }, - 'sanity check' + assert_equal %w[a-1], inst.installed_gems.map(&:full_name), + "sanity check" - ENV['GEM_HOME'] = @gemhome - ENV['GEM_PATH'] = [@gemhome, gemhome2].join File::PATH_SEPARATOR + ENV["GEM_HOME"] = @gemhome + ENV["GEM_PATH"] = [@gemhome, gemhome2].join File::PATH_SEPARATOR Gem.clear_paths Dir.chdir @tempdir do inst = Gem::DependencyInstaller.new - inst.install 'b' + inst.install "b" end - assert_equal %w[b-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[b-1], inst.installed_gems.map(&:full_name) end def test_install_reinstall @@ -777,8 +811,8 @@ class TestGemDependencyInstaller < Gem::TestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new :force => true - inst.install 'a' + inst = Gem::DependencyInstaller.new force: true + inst.install "a" end assert_equal %w[a-1], Gem::Specification.map(&:full_name) @@ -789,30 +823,30 @@ class TestGemDependencyInstaller < Gem::TestCase util_setup_gems a1_data = nil - File.open @a1_gem, 'rb' do |fp| + File.open @a1_gem, "rb" do |fp| a1_data = fp.read end - @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data + @fetcher.data["http://gems.example.com/gems/a-1.gem"] = a1_data inst = Gem::DependencyInstaller.new Dir.chdir @tempdir do - inst.install 'a' + inst.install "a" end - assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[a-1], inst.installed_gems.map(&:full_name) end def test_install_remote_dep util_setup_gems a1_data = nil - File.open @a1_gem, 'rb' do |fp| + File.open @a1_gem, "rb" do |fp| a1_data = fp.read end - @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data + @fetcher.data["http://gems.example.com/gems/a-1.gem"] = a1_data inst = Gem::DependencyInstaller.new @@ -821,28 +855,28 @@ class TestGemDependencyInstaller < Gem::TestCase inst.install dep end - assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[a-1], inst.installed_gems.map(&:full_name) end def test_install_remote_platform_newer util_setup_gems - a2_o, a2_o_gem = util_gem 'a', '2' do |s| + a2_o, a2_o_gem = util_gem "a", "2" do |s| s.platform = Gem::Platform.new %w[cpu other_platform 1] end si = util_setup_spec_fetcher @a1, a2_o - @fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml + @fetcher.data["http://gems.example.com/gems/yaml"] = si.to_yaml a1_data = nil a2_o_data = nil - File.open @a1_gem, 'rb' do |fp| + File.open @a1_gem, "rb" do |fp| a1_data = fp.read end - File.open a2_o_gem, 'rb' do |fp| + File.open a2_o_gem, "rb" do |fp| a2_o_data = fp.read end @@ -851,103 +885,103 @@ class TestGemDependencyInstaller < Gem::TestCase @fetcher.data["http://gems.example.com/gems/#{a2_o.file_name}"] = a2_o_data - inst = Gem::DependencyInstaller.new :domain => :remote - inst.install 'a' + inst = Gem::DependencyInstaller.new domain: :remote + inst.install "a" - assert_equal %w[a-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[a-1], inst.installed_gems.map(&:full_name) end def test_install_platform_is_ignored_when_a_file_is_specified - _, a_gem = util_gem 'a', '1' do |s| + _, a_gem = util_gem "a", "1" do |s| s.platform = Gem::Platform.new %w[cpu other_platform 1] end - inst = Gem::DependencyInstaller.new :domain => :local + inst = Gem::DependencyInstaller.new domain: :local inst.install a_gem - assert_equal %w[a-1-cpu-other_platform-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[a-1-cpu-other_platform-1], inst.installed_gems.map(&:full_name) end - require 'rubygems/openssl' + require "rubygems/openssl" if Gem::HAVE_OPENSSL def test_install_security_policy util_setup_gems - data = File.open(@a1_gem, 'rb') {|f| f.read } - @fetcher.data['http://gems.example.com/gems/a-1.gem'] = data + data = File.open(@a1_gem, "rb", &:read) + @fetcher.data["http://gems.example.com/gems/a-1.gem"] = data - data = File.open(@b1_gem, 'rb') {|f| f.read } - @fetcher.data['http://gems.example.com/gems/b-1.gem'] = data + data = File.open(@b1_gem, "rb", &:read) + @fetcher.data["http://gems.example.com/gems/b-1.gem"] = data policy = Gem::Security::HighSecurity - inst = Gem::DependencyInstaller.new :security_policy => policy + inst = Gem::DependencyInstaller.new security_policy: policy e = assert_raise Gem::Security::Exception do - inst.install 'b' + inst.install "b" end - assert_equal 'unsigned gems are not allowed by the High Security policy', + 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 } + assert_equal %w[], inst.installed_gems.map(&:full_name) end end # Wrappers don't work on mswin - unless win_platform? + unless Gem.win_platform? def test_install_no_wrappers util_setup_gems - @fetcher.data['http://gems.example.com/gems/a-1.gem'] = read_binary(@a1_gem) + @fetcher.data["http://gems.example.com/gems/a-1.gem"] = read_binary(@a1_gem) - inst = Gem::DependencyInstaller.new :wrappers => false, :format_executable => false - inst.install 'a' + inst = Gem::DependencyInstaller.new wrappers: false, format_executable: false + inst.install "a" - refute_match(%r{This file was generated by RubyGems.}, - File.read(File.join(@gemhome, 'bin', 'a_bin'))) + refute_match(/This file was generated by RubyGems./, + File.read(File.join(@gemhome, "bin", "a_bin"))) end end def test_install_version util_setup_d - data = File.open(@d2_gem, 'rb') {|f| f.read } - @fetcher.data['http://gems.example.com/gems/d-2.gem'] = data + data = File.open(@d2_gem, "rb", &:read) + @fetcher.data["http://gems.example.com/gems/d-2.gem"] = data - data = File.open(@d1_gem, 'rb') {|f| f.read } - @fetcher.data['http://gems.example.com/gems/d-1.gem'] = data + data = File.open(@d1_gem, "rb", &:read) + @fetcher.data["http://gems.example.com/gems/d-1.gem"] = data inst = Gem::DependencyInstaller.new - inst.install 'd', '= 1' + inst.install "d", "= 1" - assert_equal %w[d-1], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[d-1], inst.installed_gems.map(&:full_name) end def test_install_version_default util_setup_d - data = File.open(@d2_gem, 'rb') {|f| f.read } - @fetcher.data['http://gems.example.com/gems/d-2.gem'] = data + data = File.open(@d2_gem, "rb", &:read) + @fetcher.data["http://gems.example.com/gems/d-2.gem"] = data - data = File.open(@d1_gem, 'rb') {|f| f.read } - @fetcher.data['http://gems.example.com/gems/d-1.gem'] = data + data = File.open(@d1_gem, "rb", &:read) + @fetcher.data["http://gems.example.com/gems/d-1.gem"] = data inst = Gem::DependencyInstaller.new - inst.install 'd' + inst.install "d" - assert_equal %w[d-2], inst.installed_gems.map {|s| s.full_name } + assert_equal %w[d-2], inst.installed_gems.map(&:full_name) end def test_install_legacy_spec_with_nil_required_ruby_version - path = File.expand_path "../data/null-required-ruby-version.gemspec.rz", __FILE__ + path = File.expand_path "data/null-required-ruby-version.gemspec.rz", __dir__ spec = Marshal.load Gem.read_binary(path) def spec.validate(*args); end util_build_gem spec - cache_file = File.join @tempdir, 'gems', "#{spec.original_name}.gem" + cache_file = File.join @tempdir, "gems", "#{spec.original_name}.gem" FileUtils.mkdir_p File.dirname cache_file FileUtils.mv spec.cache_file, cache_file @@ -955,9 +989,9 @@ class TestGemDependencyInstaller < Gem::TestCase data = Gem.read_binary(cache_file) - @fetcher.data['http://gems.example.com/gems/activesupport-1.0.0.gem'] = data + @fetcher.data["http://gems.example.com/gems/activesupport-1.0.0.gem"] = data - dep = Gem::Dependency.new 'activesupport' + dep = Gem::Dependency.new "activesupport" inst = Gem::DependencyInstaller.new inst.install dep @@ -966,13 +1000,13 @@ class TestGemDependencyInstaller < Gem::TestCase end def test_install_legacy_spec_with_nil_required_rubygems_version - path = File.expand_path "../data/null-required-rubygems-version.gemspec.rz", __FILE__ + path = File.expand_path "data/null-required-rubygems-version.gemspec.rz", __dir__ spec = Marshal.load Gem.read_binary(path) def spec.validate(*args); end util_build_gem spec - cache_file = File.join @tempdir, 'gems', "#{spec.original_name}.gem" + cache_file = File.join @tempdir, "gems", "#{spec.original_name}.gem" FileUtils.mkdir_p File.dirname cache_file FileUtils.mv spec.cache_file, cache_file @@ -980,9 +1014,9 @@ class TestGemDependencyInstaller < Gem::TestCase data = Gem.read_binary(cache_file) - @fetcher.data['http://gems.example.com/gems/activesupport-1.0.0.gem'] = data + @fetcher.data["http://gems.example.com/gems/activesupport-1.0.0.gem"] = data - dep = Gem::Dependency.new 'activesupport' + dep = Gem::Dependency.new "activesupport" inst = Gem::DependencyInstaller.new inst.install dep @@ -994,7 +1028,7 @@ class TestGemDependencyInstaller < Gem::TestCase util_setup_gems inst = Gem::DependencyInstaller.new - dep = Gem::Dependency.new 'b', '>= 0' + dep = Gem::Dependency.new "b", ">= 0" Gem::Specification.reset @@ -1015,7 +1049,7 @@ class TestGemDependencyInstaller < Gem::TestCase FileUtils.mv @a1_gem, @tempdir inst = Gem::DependencyInstaller.new - dep = Gem::Dependency.new 'a', '>= 0' + dep = Gem::Dependency.new "a", ">= 0" set = nil Dir.chdir @tempdir do @@ -1030,12 +1064,12 @@ class TestGemDependencyInstaller < Gem::TestCase remote, local = gems - assert_equal 'a-1', local.spec.full_name, 'local spec' + assert_equal "a-1", local.spec.full_name, "local spec" assert_equal File.join(@tempdir, @a1.file_name), - local.source.download(local.spec), 'local path' + local.source.download(local.spec), "local path" - assert_equal 'a-1', remote.spec.full_name, 'remote spec' - assert_equal Gem::Source.new(@gem_repo), remote.source, 'remote path' + 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 @@ -1043,7 +1077,7 @@ class TestGemDependencyInstaller < Gem::TestCase installer = Gem::DependencyInstaller.new - dependency = Gem::Dependency.new('a', Gem::Requirement.default) + dependency = Gem::Dependency.new("a", Gem::Requirement.default) set = Gem::Deprecate.skip_during do installer.find_gems_with_sources(dependency) @@ -1051,8 +1085,8 @@ class TestGemDependencyInstaller < Gem::TestCase releases = set.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' } + assert releases.any? {|s| s.name == "a" && s.version.to_s == "1" } + refute releases.any? {|s| s.name == "a" && s.version.to_s == "1.a" } dependency.prerelease = true @@ -1067,15 +1101,15 @@ class TestGemDependencyInstaller < Gem::TestCase def test_find_gems_with_sources_with_best_only_and_platform util_setup_gems - a1_x86_mingw32, = util_gem 'a', '1' do |s| - s.platform = 'x86-mingw32' + a1_x86_mingw32, = util_gem "a", "1" do |s| + s.platform = "x86-mingw32" end util_setup_spec_fetcher @a1, a1_x86_mingw32 - Gem.platforms << Gem::Platform.new('x86-mingw32') + Gem.platforms << Gem::Platform.new("x86-mingw32") installer = Gem::DependencyInstaller.new - dependency = Gem::Dependency.new('a', Gem::Requirement.default) + dependency = Gem::Dependency.new("a", Gem::Requirement.default) set = Gem::Deprecate.skip_during do installer.find_gems_with_sources(dependency, true) @@ -1091,7 +1125,7 @@ class TestGemDependencyInstaller < Gem::TestCase installer = Gem::DependencyInstaller.new - dep = Gem::Dependency.new('a') + dep = Gem::Dependency.new("a") out = Gem::Deprecate.skip_during do installer.find_gems_with_sources(dep) @@ -1108,9 +1142,9 @@ class TestGemDependencyInstaller < Gem::TestCase FileUtils.mv @b1_gem, @tempdir inst = Gem::DependencyInstaller.new - request_set = inst.resolve_dependencies 'b', req('>= 0') + request_set = inst.resolve_dependencies "b", req(">= 0") - requests = request_set.sorted_requests.map {|req| req.full_name } + requests = request_set.sorted_requests.map(&:full_name) assert_equal %w[a-1 b-1], requests end @@ -1121,10 +1155,10 @@ class TestGemDependencyInstaller < Gem::TestCase FileUtils.mv @a1_gem, @tempdir FileUtils.mv @b1_gem, @tempdir - inst = Gem::DependencyInstaller.new :ignore_dependencies => true - request_set = inst.resolve_dependencies 'b', req('>= 0') + inst = Gem::DependencyInstaller.new ignore_dependencies: true + request_set = inst.resolve_dependencies "b", req(">= 0") - requests = request_set.sorted_requests.map {|req| req.full_name } + requests = request_set.sorted_requests.map(&:full_name) assert request_set.ignore_dependencies @@ -1134,21 +1168,21 @@ class TestGemDependencyInstaller < Gem::TestCase def test_resolve_dependencies_local util_setup_gems - @a2, @a2_gem = util_gem 'a', '2' + @a2, @a2_gem = util_gem "a", "2" FileUtils.mv @a1_gem, @tempdir FileUtils.mv @a2_gem, @tempdir inst = Gem::DependencyInstaller.new - request_set = inst.resolve_dependencies 'a-1.gem', req('>= 0') + request_set = inst.resolve_dependencies "a-1.gem", req(">= 0") - requests = request_set.sorted_requests.map {|req| req.full_name } + requests = request_set.sorted_requests.map(&:full_name) assert_equal %w[a-1], requests end def util_setup_d - @d1, @d1_gem = util_gem 'd', '1' - @d2, @d2_gem = util_gem 'd', '2' + @d1, @d1_gem = util_gem "d", "1" + @d2, @d2_gem = util_gem "d", "2" util_setup_spec_fetcher(@d1, @d2) end diff --git a/test/rubygems/test_gem_dependency_list.rb b/test/rubygems/test_gem_dependency_list.rb index 097e680596..590e042315 100644 --- a/test/rubygems/test_gem_dependency_list.rb +++ b/test/rubygems/test_gem_dependency_list.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/dependency_list' + +require_relative "helper" +require "rubygems/dependency_list" class TestGemDependencyList < Gem::TestCase def setup @@ -9,26 +10,26 @@ class TestGemDependencyList < Gem::TestCase @deplist = Gem::DependencyList.new # TODO: switch to util_spec - @a1 = util_spec 'a', '1' - @a2 = util_spec 'a', '2' - @a3 = util_spec 'a', '3' + @a1 = util_spec "a", "1" + @a2 = util_spec "a", "2" + @a3 = util_spec "a", "3" - @b1 = util_spec 'b', '1' do |s| - s.add_dependency 'a', '>= 1' + @b1 = util_spec "b", "1" do |s| + s.add_dependency "a", ">= 1" end - @b2 = util_spec 'b', '2' do |s| - s.add_dependency 'a', '>= 1' + @b2 = util_spec "b", "2" do |s| + s.add_dependency "a", ">= 1" end - @c1 = util_spec 'c', '1' do |s| - s.add_dependency 'b', '>= 1' + @c1 = util_spec "c", "1" do |s| + s.add_dependency "b", ">= 1" end - @c2 = util_spec 'c', '2' + @c2 = util_spec "c", "2" - @d1 = util_spec 'd', '1' do |s| - s.add_dependency 'c', '>= 1' + @d1 = util_spec "d", "1" do |s| + s.add_dependency "c", ">= 1" end end @@ -52,55 +53,55 @@ class TestGemDependencyList < Gem::TestCase order = @deplist.dependency_order - assert_equal %w[d-1 c-1 b-1 a-1], order.map {|s| s.full_name } + assert_equal %w[d-1 c-1 b-1 a-1], order.map(&:full_name) end def test_dependency_order_circle - @a1.add_dependency 'c', '>= 1' + @a1.add_dependency "c", ">= 1" @deplist.add @a1, @b1, @c1 order = @deplist.dependency_order - assert_equal %w[b-1 c-1 a-1], order.map {|s| s.full_name } + assert_equal %w[b-1 c-1 a-1], order.map(&:full_name) end def test_dependency_order_development - e1 = util_spec 'e', '1' - f1 = util_spec 'f', '1' - g1 = util_spec 'g', '1' + e1 = util_spec "e", "1" + f1 = util_spec "f", "1" + g1 = util_spec "g", "1" - @a1.add_dependency 'e' - @a1.add_dependency 'f' - @a1.add_dependency 'g' - g1.add_development_dependency 'a' + @a1.add_dependency "e" + @a1.add_dependency "f" + @a1.add_dependency "g" + g1.add_development_dependency "a" deplist = Gem::DependencyList.new true deplist.add @a1, e1, f1, g1 order = deplist.dependency_order - assert_equal %w[g-1 a-1 f-1 e-1], order.map {|s| s.full_name }, - 'development on' + assert_equal %w[g-1 a-1 f-1 e-1], order.map(&:full_name), + "development on" deplist2 = Gem::DependencyList.new deplist2.add @a1, e1, f1, g1 order = deplist2.dependency_order - assert_equal %w[a-1 g-1 f-1 e-1], order.map {|s| s.full_name }, - 'development off' + assert_equal %w[a-1 g-1 f-1 e-1], order.map(&:full_name), + "development off" end def test_dependency_order_diamond util_diamond - e1 = util_spec 'e', '1' + e1 = util_spec "e", "1" @deplist.add e1 - @a1.add_dependency 'e', '>= 1' + @a1.add_dependency "e", ">= 1" order = @deplist.dependency_order - assert_equal %w[d-1 c-2 b-1 a-2 e-1], order.map {|s| s.full_name }, - 'deps of trimmed specs not included' + assert_equal %w[d-1 c-2 b-1 a-2 e-1], order.map(&:full_name), + "deps of trimmed specs not included" end def test_dependency_order_no_dependencies @@ -108,7 +109,7 @@ class TestGemDependencyList < Gem::TestCase order = @deplist.dependency_order - assert_equal %w[c-2 a-1], order.map {|s| s.full_name } + assert_equal %w[c-2 a-1], order.map(&:full_name) end def test_find_name @@ -121,15 +122,15 @@ class TestGemDependencyList < Gem::TestCase end def test_ok_eh - assert @deplist.ok?, 'no dependencies' + assert @deplist.ok?, "no dependencies" @deplist.add @b2 - refute @deplist.ok?, 'unsatisfied dependency' + refute @deplist.ok?, "unsatisfied dependency" @deplist.add @a1 - assert @deplist.ok?, 'satisfied dependency' + assert @deplist.ok?, "satisfied dependency" end def test_why_not_ok_eh @@ -147,13 +148,13 @@ class TestGemDependencyList < Gem::TestCase end def test_why_not_ok_eh_old_dependency - a = util_spec 'a', '1', - 'b' => '~> 1.0' + a = util_spec "a", "1", + "b" => "~> 1.0" - b0 = util_spec 'b', '1.0', - 'd' => '>= 0' + b0 = util_spec "b", "1.0", + "d" => ">= 0" - b1 = util_spec 'b', '1.1' + b1 = util_spec "b", "1.1" util_clear_gems @@ -165,25 +166,25 @@ class TestGemDependencyList < Gem::TestCase end def test_ok_eh_mismatch - a1 = util_spec 'a', '1' - a2 = util_spec 'a', '2' + a1 = util_spec "a", "1" + a2 = util_spec "a", "2" - b = util_spec 'b', '1' do |s| - s.add_dependency 'a', '= 1' + b = util_spec "b", "1" do |s| + s.add_dependency "a", "= 1" end - c = util_spec 'c', '1' do |s| - s.add_dependency 'a', '= 2' + c = util_spec "c", "1" do |s| + s.add_dependency "a", "= 2" end - d = util_spec 'd', '1' do |s| - s.add_dependency 'b' - s.add_dependency 'c' + d = util_spec "d", "1" do |s| + s.add_dependency "b" + s.add_dependency "c" end @deplist.add a1, a2, b, c, d - assert @deplist.ok?, 'this will break on require' + assert @deplist.ok?, "this will break on require" end def test_ok_eh_redundant @@ -256,8 +257,8 @@ class TestGemDependencyList < Gem::TestCase # d1 -> b1 -> a1 # d1 -> c2 -> a2 def util_diamond - @c2.add_dependency 'a', '>= 2' - @d1.add_dependency 'b' + @c2.add_dependency "a", ">= 2" + @d1.add_dependency "b" @deplist.add @a1, @a2, @b1, @c2, @d1 end diff --git a/test/rubygems/test_gem_dependency_resolution_error.rb b/test/rubygems/test_gem_dependency_resolution_error.rb index 5321f7031c..98a6b6b8fd 100644 --- a/test/rubygems/test_gem_dependency_resolution_error.rb +++ b/test/rubygems/test_gem_dependency_resolution_error.rb @@ -1,26 +1,25 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" class TestGemDependencyResolutionError < Gem::TestCase def setup super - @DR = Gem::Resolver - - @spec = util_spec 'a', 2 + @spec = util_spec "a", 2 - @a1_req = @DR::DependencyRequest.new dep('a', '= 1'), nil - @a2_req = @DR::DependencyRequest.new dep('a', '= 2'), nil + @a1_req = Gem::Resolver::DependencyRequest.new dep("a", "= 1"), nil + @a2_req = Gem::Resolver::DependencyRequest.new dep("a", "= 2"), nil - @activated = @DR::ActivationRequest.new @spec, @a2_req + @activated = Gem::Resolver::ActivationRequest.new @spec, @a2_req - @conflict = @DR::Conflict.new @a1_req, @activated + @conflict = Gem::Resolver::Conflict.new @a1_req, @activated @error = Gem::DependencyResolutionError.new @conflict end def test_message - assert_match %r{^conflicting dependencies a \(= 1\) and a \(= 2\)$}, - @error.message + assert_match(/^conflicting dependencies a \(= 1\) and a \(= 2\)$/, + @error.message) end end diff --git a/test/rubygems/test_gem_doctor.rb b/test/rubygems/test_gem_doctor.rb index 4514d17f9f..1bcdc39022 100644 --- a/test/rubygems/test_gem_doctor.rb +++ b/test/rubygems/test_gem_doctor.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/doctor' + +require_relative "helper" +require "rubygems/doctor" class TestGemDoctor < Gem::TestCase def gem(name) @@ -15,20 +16,20 @@ class TestGemDoctor < Gem::TestCase end def test_doctor - a = gem 'a' - b = gem 'b' - c = gem 'c' + a = gem "a" + b = gem "b" + c = gem "c" Gem.use_paths @userhome, @gemhome FileUtils.rm b.spec_file - File.open c.spec_file, 'w' do |io| - io.write 'this will raise an exception when evaluated.' + File.open c.spec_file, "w" do |io| + io.write "this will raise an exception when evaluated." end - assert_path_exist File.join(a.gem_dir, 'Rakefile') - assert_path_exist File.join(a.gem_dir, 'lib', 'a.rb') + assert_path_exist File.join(a.gem_dir, "Rakefile") + assert_path_exist File.join(a.gem_dir, "lib", "a.rb") assert_path_exist b.gem_dir assert_path_not_exist b.spec_file @@ -44,8 +45,8 @@ class TestGemDoctor < Gem::TestCase end end - assert_path_exist File.join(a.gem_dir, 'Rakefile') - assert_path_exist File.join(a.gem_dir, 'lib', 'a.rb') + assert_path_exist File.join(a.gem_dir, "Rakefile") + assert_path_exist File.join(a.gem_dir, "lib", "a.rb") assert_path_not_exist b.gem_dir assert_path_not_exist b.spec_file @@ -68,20 +69,20 @@ Removed directory gems/c-2 end def test_doctor_dry_run - a = gem 'a' - b = gem 'b' - c = gem 'c' + a = gem "a" + b = gem "b" + c = gem "c" Gem.use_paths @userhome, @gemhome FileUtils.rm b.spec_file - File.open c.spec_file, 'w' do |io| - io.write 'this will raise an exception when evaluated.' + File.open c.spec_file, "w" do |io| + io.write "this will raise an exception when evaluated." end - assert_path_exist File.join(a.gem_dir, 'Rakefile') - assert_path_exist File.join(a.gem_dir, 'lib', 'a.rb') + assert_path_exist File.join(a.gem_dir, "Rakefile") + assert_path_exist File.join(a.gem_dir, "lib", "a.rb") assert_path_exist b.gem_dir assert_path_not_exist b.spec_file @@ -97,8 +98,8 @@ Removed directory gems/c-2 end end - assert_path_exist File.join(a.gem_dir, 'Rakefile') - assert_path_exist File.join(a.gem_dir, 'lib', 'a.rb') + assert_path_exist File.join(a.gem_dir, "Rakefile") + assert_path_exist File.join(a.gem_dir, "lib", "a.rb") assert_path_exist b.gem_dir assert_path_not_exist b.spec_file @@ -121,7 +122,7 @@ Extra directory gems/c-2 end def test_doctor_non_gem_home - other_dir = File.join @tempdir, 'other', 'dir' + other_dir = File.join @tempdir, "other", "dir" FileUtils.mkdir_p other_dir @@ -147,13 +148,13 @@ This directory does not appear to be a RubyGems repository, skipping def test_doctor_child_missing doctor = Gem::Doctor.new @gemhome - doctor.doctor_child 'missing', '' + doctor.doctor_child "missing", "" assert true # count end def test_doctor_badly_named_plugins - gem 'a' + gem "a" Gem.use_paths @gemhome.to_s @@ -183,12 +184,12 @@ Removed file plugins/a_badly_named_file.rb def test_gem_repository_eh doctor = Gem::Doctor.new @gemhome - refute doctor.gem_repository?, 'no gems installed' + refute doctor.gem_repository?, "no gems installed" - install_specs util_spec 'a' + install_specs util_spec "a" doctor = Gem::Doctor.new @gemhome - assert doctor.gem_repository?, 'gems installed' + assert doctor.gem_repository?, "gems installed" end end diff --git a/test/rubygems/test_gem_ext_builder.rb b/test/rubygems/test_gem_ext_builder.rb index 08c45b17d9..d5812da2aa 100644 --- a/test/rubygems/test_gem_ext_builder.rb +++ b/test/rubygems/test_gem_ext_builder.rb @@ -1,38 +1,37 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/ext' -require 'rubygems/installer' + +require_relative "helper" +require "rubygems/ext" +require "rubygems/installer" class TestGemExtBuilder < Gem::TestCase def setup + @orig_destdir = ENV["DESTDIR"] + @orig_make = ENV["make"] super - @ext = File.join @tempdir, 'ext' - @dest_path = File.join @tempdir, 'prefix' + @ext = File.join @tempdir, "ext" + @dest_path = File.join @tempdir, "prefix" FileUtils.mkdir_p @ext FileUtils.mkdir_p @dest_path - @orig_DESTDIR = ENV['DESTDIR'] - @orig_make = ENV['make'] - - @spec = util_spec 'a' + @spec = util_spec "a" - @builder = Gem::Ext::Builder.new @spec, '' + @builder = Gem::Ext::Builder.new @spec, "" end def teardown - ENV['DESTDIR'] = @orig_DESTDIR - ENV['make'] = @orig_make - super + ENV["DESTDIR"] = @orig_destdir + ENV["make"] = @orig_make end def test_class_make - ENV['DESTDIR'] = 'destination' + ENV["DESTDIR"] = "destination" results = [] - File.open File.join(@ext, 'Makefile'), 'w' do |io| + File.open File.join(@ext, "Makefile"), "w" do |io| io.puts <<-MAKEFILE all: \t@#{Gem.ruby} -e "puts %Q{all: \#{ENV['DESTDIR']}}" @@ -49,22 +48,22 @@ install: results = results.join("\n").b - assert_match %r{DESTDIR\\=#{ENV['DESTDIR']} clean$}, results - assert_match %r{DESTDIR\\=#{ENV['DESTDIR']}$}, results - assert_match %r{DESTDIR\\=#{ENV['DESTDIR']} install$}, results + assert_match(/DESTDIR\\=#{ENV["DESTDIR"]} clean$/, results) + assert_match(/DESTDIR\\=#{ENV["DESTDIR"]}$/, results) + assert_match(/DESTDIR\\=#{ENV["DESTDIR"]} install$/, results) - if /nmake/ !~ results - assert_match %r{^clean: destination$}, results - assert_match %r{^all: destination$}, results - assert_match %r{^install: destination$}, results + unless results.include?("nmake") + assert_match(/^clean: destination$/, results) + assert_match(/^all: destination$/, results) + assert_match(/^install: destination$/, results) end end def test_class_make_no_clean - ENV['DESTDIR'] = 'destination' + ENV["DESTDIR"] = "destination" results = [] - File.open File.join(@ext, 'Makefile'), 'w' do |io| + File.open File.join(@ext, "Makefile"), "w" do |io| io.puts <<-MAKEFILE all: \t@#{Gem.ruby} -e "puts %Q{all: \#{ENV['DESTDIR']}}" @@ -78,15 +77,17 @@ install: results = results.join("\n").b - assert_match %r{DESTDIR\\=#{ENV['DESTDIR']} clean$}, results - assert_match %r{DESTDIR\\=#{ENV['DESTDIR']}$}, results - assert_match %r{DESTDIR\\=#{ENV['DESTDIR']} install$}, results + assert_match(/DESTDIR\\=#{ENV["DESTDIR"]} clean$/, results) + assert_match(/DESTDIR\\=#{ENV["DESTDIR"]}$/, results) + assert_match(/DESTDIR\\=#{ENV["DESTDIR"]} install$/, results) end def test_custom_make_with_options - ENV['make'] = 'make V=1' + pend "native windows platform only provides nmake" if vc_windows? + + ENV["make"] = "make V=1" results = [] - File.open File.join(@ext, 'Makefile'), 'w' do |io| + File.open File.join(@ext, "Makefile"), "w" do |io| io.puts <<-MAKEFILE all: \t@#{Gem.ruby} -e "puts 'all: OK'" @@ -100,109 +101,104 @@ install: end Gem::Ext::Builder.make @dest_path, results, @ext results = results.join("\n").b - assert_match %r{clean: OK}, results - assert_match %r{all: OK}, results - assert_match %r{install: OK}, results + assert_match(/clean: OK/, results) + assert_match(/all: OK/, results) + assert_match(/install: OK/, results) end def test_build_extensions - skip if /mswin/ =~ RUBY_PLATFORM && ENV.key?('GITHUB_ACTIONS') # not working from the beginning - @spec.extensions << 'ext/extconf.rb' + pend "terminates on mswin" if vc_windows? && ruby_repo? - ext_dir = File.join @spec.gem_dir, 'ext' + extension_in_lib do + @spec.extensions << "ext/extconf.rb" - FileUtils.mkdir_p ext_dir + ext_dir = File.join @spec.gem_dir, "ext" - extconf_rb = File.join ext_dir, 'extconf.rb' + FileUtils.mkdir_p ext_dir - File.open extconf_rb, 'w' do |f| - f.write <<-'RUBY' - require 'mkmf' + extconf_rb = File.join ext_dir, "extconf.rb" - create_makefile 'a' - RUBY - end + File.open extconf_rb, "w" do |f| + f.write <<-'RUBY' + require 'mkmf' + + create_makefile 'a' + RUBY + end - ext_lib_dir = File.join ext_dir, 'lib' - FileUtils.mkdir ext_lib_dir - FileUtils.touch File.join ext_lib_dir, 'a.rb' - FileUtils.mkdir File.join ext_lib_dir, 'a' - FileUtils.touch File.join ext_lib_dir, 'a', 'b.rb' + ext_lib_dir = File.join ext_dir, "lib" + FileUtils.mkdir ext_lib_dir + FileUtils.touch File.join ext_lib_dir, "a.rb" + FileUtils.mkdir File.join ext_lib_dir, "a" + FileUtils.touch File.join ext_lib_dir, "a", "b.rb" - use_ui @ui do - @builder.build_extensions - end + use_ui @ui do + @builder.build_extensions + end - assert_path_exist @spec.extension_dir - assert_path_exist @spec.gem_build_complete_path - assert_path_exist File.join @spec.extension_dir, 'gem_make.out' - assert_path_exist File.join @spec.extension_dir, 'a.rb' - assert_path_exist File.join @spec.gem_dir, 'lib', 'a.rb' - assert_path_exist File.join @spec.gem_dir, 'lib', 'a', 'b.rb' + assert_path_exist @spec.extension_dir + assert_path_exist @spec.gem_build_complete_path + assert_path_exist File.join @spec.extension_dir, "gem_make.out" + assert_path_exist File.join @spec.extension_dir, "a.rb" + assert_path_exist File.join @spec.gem_dir, "lib", "a.rb" + assert_path_exist File.join @spec.gem_dir, "lib", "a", "b.rb" + end end def test_build_extensions_with_gemhome_with_space - skip if /mswin/ =~ RUBY_PLATFORM && ENV.key?('GITHUB_ACTIONS') # not working from the beginning - new_gemhome = File.join @tempdir, 'gem home' + pend "terminates on mswin" if vc_windows? && ruby_repo? + new_gemhome = File.join @tempdir, "gem home" File.rename(@gemhome, new_gemhome) @gemhome = new_gemhome Gem.use_paths(@gemhome) - @spec = util_spec 'a' - @builder = Gem::Ext::Builder.new @spec, '' + @spec = util_spec "a" + @builder = Gem::Ext::Builder.new @spec, "" test_build_extensions end def test_build_extensions_install_ext_only - class << Gem - alias orig_install_extension_in_lib install_extension_in_lib + pend "terminates on mswin" if vc_windows? && ruby_repo? - remove_method :install_extension_in_lib + extension_in_lib(false) do + @orig_install_extension_in_lib = Gem.configuration.install_extension_in_lib + Gem.configuration.install_extension_in_lib = false - def Gem.install_extension_in_lib - false - end - end - skip if /mswin/ =~ RUBY_PLATFORM && ENV.key?('GITHUB_ACTIONS') # not working from the beginning + @spec.extensions << "ext/extconf.rb" - @spec.extensions << 'ext/extconf.rb' + ext_dir = File.join @spec.gem_dir, "ext" - ext_dir = File.join @spec.gem_dir, 'ext' + FileUtils.mkdir_p ext_dir - FileUtils.mkdir_p ext_dir + extconf_rb = File.join ext_dir, "extconf.rb" - extconf_rb = File.join ext_dir, 'extconf.rb' + File.open extconf_rb, "w" do |f| + f.write <<-'RUBY' + require 'mkmf' - File.open extconf_rb, 'w' do |f| - f.write <<-'RUBY' - require 'mkmf' + create_makefile 'a' + RUBY + end - create_makefile 'a' - RUBY - end + ext_lib_dir = File.join ext_dir, "lib" + FileUtils.mkdir ext_lib_dir + FileUtils.touch File.join ext_lib_dir, "a.rb" + FileUtils.mkdir File.join ext_lib_dir, "a" + FileUtils.touch File.join ext_lib_dir, "a", "b.rb" - ext_lib_dir = File.join ext_dir, 'lib' - FileUtils.mkdir ext_lib_dir - FileUtils.touch File.join ext_lib_dir, 'a.rb' - FileUtils.mkdir File.join ext_lib_dir, 'a' - FileUtils.touch File.join ext_lib_dir, 'a', 'b.rb' + use_ui @ui do + @builder.build_extensions + end - use_ui @ui do - @builder.build_extensions + assert_path_exist @spec.extension_dir + assert_path_exist @spec.gem_build_complete_path + assert_path_exist File.join @spec.extension_dir, "gem_make.out" + assert_path_exist File.join @spec.extension_dir, "a.rb" + assert_path_not_exist File.join @spec.gem_dir, "lib", "a.rb" + assert_path_not_exist File.join @spec.gem_dir, "lib", "a", "b.rb" end - - assert_path_exist @spec.extension_dir - assert_path_exist @spec.gem_build_complete_path - assert_path_exist File.join @spec.extension_dir, 'gem_make.out' - assert_path_exist File.join @spec.extension_dir, 'a.rb' - assert_path_not_exist File.join @spec.gem_dir, 'lib', 'a.rb' - assert_path_not_exist File.join @spec.gem_dir, 'lib', 'a', 'b.rb' ensure - class << Gem - remove_method :install_extension_in_lib - - alias install_extension_in_lib orig_install_extension_in_lib - end + Gem.configuration.install_extension_in_lib = @orig_install_extension_in_lib end def test_build_extensions_none @@ -210,10 +206,10 @@ install: @builder.build_extensions end - assert_equal '', @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.output + assert_equal "", @ui.error - assert_path_not_exist File.join @spec.extension_dir, 'gem_make.out' + assert_path_not_exist File.join @spec.extension_dir, "gem_make.out" end def test_build_extensions_rebuild_failure @@ -234,7 +230,7 @@ install: def test_build_extensions_extconf_bad cwd = Dir.pwd - @spec.extensions << 'extconf.rb' + @spec.extensions << "extconf.rb" FileUtils.mkdir_p @spec.gem_dir @@ -246,13 +242,13 @@ install: assert_match(/\AERROR: Failed to build gem native extension.$/, e.message) assert_equal "Building native extensions. This could take a while...\n", @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error - gem_make_out = File.join @spec.extension_dir, 'gem_make.out' + gem_make_out = File.join @spec.extension_dir, "gem_make.out" cmd_make_out = File.read(gem_make_out) assert_match %r{#{Regexp.escape Gem.ruby} .* extconf\.rb}, cmd_make_out - assert_match %r{: No such file}, cmd_make_out + assert_match(/: No such file/, cmd_make_out) assert_path_not_exist @spec.gem_build_complete_path @@ -261,7 +257,7 @@ install: def test_build_extensions_unsupported FileUtils.mkdir_p @spec.gem_dir - gem_make_out = File.join @spec.extension_dir, 'gem_make.out' + gem_make_out = File.join @spec.extension_dir, "gem_make.out" @spec.extensions << nil e = assert_raise Gem::Ext::BuildError do @@ -272,7 +268,7 @@ install: assert_match(/^\s*No builder for extension ''$/, e.message) assert_equal "Building native extensions. This could take a while...\n", @ui.output - assert_equal '', @ui.error + assert_equal "", @ui.error assert_equal "No builder for extension ''\n", File.read(gem_make_out) @@ -284,14 +280,14 @@ install: def test_build_extensions_with_build_args args = ["--aa", "--bb"] @builder.build_args = args - @spec.extensions << 'extconf.rb' + @spec.extensions << "extconf.rb" FileUtils.mkdir_p @spec.gem_dir File.open File.join(@spec.gem_dir, "extconf.rb"), "w" do |f| f.write <<-'RUBY' puts "IN EXTCONF" - extconf_args = File.join File.dirname(__FILE__), 'extconf_args' + extconf_args = File.join __dir__, 'extconf_args' File.open extconf_args, 'w' do |f| f.puts ARGV.inspect end @@ -315,14 +311,14 @@ install: end def test_initialize - build_info_dir = File.join @gemhome, 'build_info' + build_info_dir = File.join @gemhome, "build_info" FileUtils.mkdir_p build_info_dir build_info_file = File.join build_info_dir, "#{@spec.full_name}.info" - File.open build_info_file, 'w' do |io| - io.puts '--with-foo-dir=/nonexistent' + File.open build_info_file, "w" do |io| + io.puts "--with-foo-dir=/nonexistent" end builder = Gem::Ext::Builder.new @spec diff --git a/test/rubygems/test_gem_ext_cargo_builder.rb b/test/rubygems/test_gem_ext_cargo_builder.rb new file mode 100644 index 0000000000..5faf3e2480 --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder.rb @@ -0,0 +1,171 @@ +# frozen_string_literal: true + +require_relative "helper" +require "rubygems/ext" +require "open3" + +class TestGemExtCargoBuilder < Gem::TestCase + def setup + super + + @rust_envs = { + "CARGO_HOME" => ENV.fetch("CARGO_HOME", File.join(@orig_env["HOME"], ".cargo")), + "RUSTUP_HOME" => ENV.fetch("RUSTUP_HOME", File.join(@orig_env["HOME"], ".rustup")), + } + end + + def setup_rust_gem(name) + @ext = File.join(@tempdir, "ext") + @dest_path = File.join(@tempdir, "prefix") + @fixture_dir = Pathname.new(File.expand_path("test_gem_ext_cargo_builder/#{name}/", __dir__)) + + FileUtils.mkdir_p @dest_path + FileUtils.cp_r(@fixture_dir.to_s, @ext) + end + + def test_build_cdylib + skip_unsupported_platforms! + setup_rust_gem "rust_ruby_example" + + output = [] + + Dir.chdir @ext do + ENV.update(@rust_envs) + builder = Gem::Ext::CargoBuilder.new + builder.build "Cargo.toml", @dest_path, output + end + + output = output.join "\n" + bundle = File.join(@dest_path, "rust_ruby_example.#{RbConfig::CONFIG["DLEXT"]}") + + assert_match(/Finished/, output) + assert_match(/release/, output) + assert_ffi_handle bundle, "Init_rust_ruby_example" + rescue StandardError => e + pp output if output + + raise(e) + end + + def test_rubygems_cfg_passed_to_rustc + skip_unsupported_platforms! + setup_rust_gem "rust_ruby_example" + version_slug = Gem::VERSION.tr(".", "_") + output = [] + + replace_in_rust_file("src/lib.rs", "rubygems_x_x_x", "rubygems_#{version_slug}") + + Dir.chdir @ext do + ENV.update(@rust_envs) + builder = Gem::Ext::CargoBuilder.new + builder.build "Cargo.toml", @dest_path, output + end + + output = output.join "\n" + bundle = File.join(@dest_path, "rust_ruby_example.#{RbConfig::CONFIG["DLEXT"]}") + + assert_ffi_handle bundle, "hello_from_rubygems" + assert_ffi_handle bundle, "hello_from_rubygems_version" + refute_ffi_handle bundle, "should_never_exist" + rescue StandardError => e + pp output if output + + raise(e) + end + + def test_build_fail + skip_unsupported_platforms! + setup_rust_gem "rust_ruby_example" + + FileUtils.rm(File.join(@ext, "src/lib.rs")) + + error = assert_raise(Gem::InstallError) do + Dir.chdir @ext do + ENV.update(@rust_envs) + builder = Gem::Ext::CargoBuilder.new + builder.build "Cargo.toml", @dest_path, [] + end + end + + assert_match(/cargo\s.*\sfailed/, error.message) + end + + def test_full_integration + skip_unsupported_platforms! + setup_rust_gem "rust_ruby_example" + + require "open3" + + Dir.chdir @ext do + require "tmpdir" + + env_for_subprocess = @rust_envs.merge("GEM_HOME" => Gem.paths.home) + gem = [env_for_subprocess, *ruby_with_rubygems_in_load_path, File.expand_path("../../exe/gem", __dir__)] + + Dir.mktmpdir("rust_ruby_example") do |dir| + built_gem = File.expand_path(File.join(dir, "rust_ruby_example.gem")) + Open3.capture2e(*gem, "build", "rust_ruby_example.gemspec", "--output", built_gem) + Open3.capture2e(*gem, "install", "--verbose", "--local", built_gem, *ARGV) + + stdout_and_stderr_str, status = Open3.capture2e(env_for_subprocess, *ruby_with_rubygems_in_load_path, "-rrust_ruby_example", "-e", "puts 'Result: ' + RustRubyExample.reverse('hello world')") + assert status.success?, stdout_and_stderr_str + assert_match "Result: #{"hello world".reverse}", stdout_and_stderr_str + end + end + end + + def test_custom_name + skip_unsupported_platforms! + setup_rust_gem "custom_name" + + Dir.chdir @ext do + require "tmpdir" + + env_for_subprocess = @rust_envs.merge("GEM_HOME" => Gem.paths.home) + gem = [env_for_subprocess, *ruby_with_rubygems_in_load_path, File.expand_path("../../exe/gem", __dir__)] + + Dir.mktmpdir("custom_name") do |dir| + built_gem = File.expand_path(File.join(dir, "custom_name.gem")) + Open3.capture2e(*gem, "build", "custom_name.gemspec", "--output", built_gem) + Open3.capture2e(*gem, "install", "--verbose", "--local", built_gem, *ARGV) + end + + stdout_and_stderr_str, status = Open3.capture2e(env_for_subprocess, *ruby_with_rubygems_in_load_path, "-rcustom_name", "-e", "puts 'Result: ' + CustomName.say_hello") + + assert status.success?, stdout_and_stderr_str + assert_match "Result: Hello world!", stdout_and_stderr_str + end + end + + private + + def skip_unsupported_platforms! + pend "jruby not supported" if Gem.java_platform? + pend "truffleruby not supported (yet)" if RUBY_ENGINE == "truffleruby" + system(@rust_envs, "cargo", "-V", out: IO::NULL, err: [:child, :out]) + pend "cargo not present" unless $?.success? + pend "ruby.h is not provided by ruby repo" if ruby_repo? + pend "rust toolchain of mingw is broken" if mingw_windows? + end + + def assert_ffi_handle(bundle, name) + require "fiddle" + dylib_handle = Fiddle.dlopen bundle + assert_nothing_raised { dylib_handle[name] } + ensure + dylib_handle&.close + end + + def refute_ffi_handle(bundle, name) + require "fiddle" + dylib_handle = Fiddle.dlopen bundle + assert_raise { dylib_handle[name] } + ensure + dylib_handle&.close + end + + def replace_in_rust_file(name, from, to) + content = @fixture_dir.join(name).read.gsub(from, to) + File.write(File.join(@ext, name), content) + end +end diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/.gitignore b/test/rubygems/test_gem_ext_cargo_builder/custom_name/.gitignore new file mode 100644 index 0000000000..2f7896d1d1 --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec b/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec new file mode 100644 index 0000000000..5f130527dd --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +Gem::Specification.new do |s| + s.name = "custom_name" + s.version = "0.1.0" + s.summary = "A Rust extension for Ruby" + s.extensions = ["ext/custom_name_lib/Cargo.toml"] + s.authors = ["Ian Ker-Seymer"] + s.files = ["lib/custom_name.rb", "ext/custom_name_lib/Cargo.toml", "ext/custom_name_lib/Cargo.lock", "ext/custom_name_lib/src/lib.rs"] +end diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.lock b/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.lock new file mode 100644 index 0000000000..abd1e0ae33 --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.lock @@ -0,0 +1,249 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + +[[package]] +name = "bindgen" +version = "0.69.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ffcebc3849946a7170a05992aac39da343a90676ab392c51a4280981d6379c2" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", +] + +[[package]] +name = "bitflags" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clang-sys" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "custom-name-ext" +version = "0.1.0" +dependencies = [ + "rb-sys", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.138" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rb-sys" +version = "0.9.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d30bcad206b51f2f66121190ca678dce1fdf3a2eae0ac5d838d1818b19bdf5" +dependencies = [ + "rb-sys-build", +] + +[[package]] +name = "rb-sys-build" +version = "0.9.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbd92f281615f3c2dcb9dcb0f0576624752afbf9a7f99173b37c4b55b62dd8a" +dependencies = [ + "bindgen", + "lazy_static", + "proc-macro2", + "quote", + "regex", + "shell-words", + "syn", +] + +[[package]] +name = "regex" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "syn" +version = "2.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.toml b/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.toml new file mode 100644 index 0000000000..ad3e7f9b76 --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "custom-name-ext" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +rb-sys = "0.9.97" diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/src/lib.rs b/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/src/lib.rs new file mode 100644 index 0000000000..28ba3be564 --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/src/lib.rs @@ -0,0 +1,27 @@ +extern crate rb_sys; + +use rb_sys::{rb_define_module, rb_define_module_function, rb_utf8_str_new, VALUE}; +use std::ffi::CString; + +#[no_mangle] +unsafe extern "C" fn say_hello(_klass: VALUE) -> VALUE { + let cstr = CString::new("Hello world!").unwrap(); + + rb_utf8_str_new(cstr.as_ptr(), 12) +} + +#[allow(non_snake_case)] +#[no_mangle] +pub extern "C" fn Init_custom_name_ext() { + let name = CString::new("CustomName").unwrap(); + let function_name = CString::new("say_hello").unwrap(); + // bindgen does not properly detect the arity of the ruby callback function, so we have to transmute + let callback = unsafe { + std::mem::transmute::<unsafe extern "C" fn(VALUE) -> VALUE, unsafe extern "C" fn() -> VALUE>( + say_hello, + ) + }; + let klass = unsafe { rb_define_module(name.as_ptr()) }; + + unsafe { rb_define_module_function(klass, function_name.as_ptr(), Some(callback), 0) } +} diff --git a/test/rubygems/test_gem_ext_cargo_builder/custom_name/lib/custom_name.rb b/test/rubygems/test_gem_ext_cargo_builder/custom_name/lib/custom_name.rb new file mode 100644 index 0000000000..9f8d190baf --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/custom_name/lib/custom_name.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true + +require "custom_name_lib/custom_name_ext" diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/.gitignore b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/.gitignore new file mode 100644 index 0000000000..2f7896d1d1 --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock new file mode 100644 index 0000000000..1d174f569e --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock @@ -0,0 +1,249 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + +[[package]] +name = "bindgen" +version = "0.69.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ffcebc3849946a7170a05992aac39da343a90676ab392c51a4280981d6379c2" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", +] + +[[package]] +name = "bitflags" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clang-sys" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa2e27ae6ab525c3d369ded447057bca5438d86dc3a68f6faafb8269ba82ebf3" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.138" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rb-sys" +version = "0.9.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d30bcad206b51f2f66121190ca678dce1fdf3a2eae0ac5d838d1818b19bdf5" +dependencies = [ + "rb-sys-build", +] + +[[package]] +name = "rb-sys-build" +version = "0.9.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbd92f281615f3c2dcb9dcb0f0576624752afbf9a7f99173b37c4b55b62dd8a" +dependencies = [ + "bindgen", + "lazy_static", + "proc-macro2", + "quote", + "regex", + "shell-words", + "syn", +] + +[[package]] +name = "regex" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" + +[[package]] +name = "rust_ruby_example" +version = "0.1.0" +dependencies = [ + "rb-sys", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "syn" +version = "2.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml new file mode 100644 index 0000000000..60cf49ce03 --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "rust_ruby_example" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +rb-sys = "0.9.97" diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec new file mode 100644 index 0000000000..d3f8b11a8b --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +Gem::Specification.new do |s| + s.name = "rust_ruby_example" + s.version = "0.1.0" + s.summary = "A Rust extension for Ruby" + s.extensions = ["Cargo.toml"] + s.authors = ["Ian Ker-Seymer"] + s.files = ["Cargo.toml", "Cargo.lock", "src/lib.rs"] +end diff --git a/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs new file mode 100644 index 0000000000..0626f04e0f --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs @@ -0,0 +1,51 @@ +extern crate rb_sys; + +use rb_sys::{ + rb_define_module, rb_define_module_function, rb_string_value_cstr, rb_utf8_str_new, VALUE, +}; +use std::ffi::{CStr, CString}; +use std::os::raw::{c_char, c_long}; + +#[inline] +unsafe fn cstr_to_string(str: *const c_char) -> String { + CStr::from_ptr(str).to_string_lossy().into_owned() +} + +#[no_mangle] +unsafe extern "C" fn pub_reverse(_klass: VALUE, mut input: VALUE) -> VALUE { + let ruby_string = cstr_to_string(rb_string_value_cstr(&mut input)); + let reversed = ruby_string.to_string().chars().rev().collect::<String>(); + let reversed_cstring = CString::new(reversed).unwrap(); + let size = ruby_string.len() as c_long; + + rb_utf8_str_new(reversed_cstring.as_ptr(), size) +} + +#[cfg(rubygems)] +#[no_mangle] +pub extern "C" fn hello_from_rubygems() {} + +#[cfg(rubygems_0_0_0)] +#[no_mangle] +pub extern "C" fn should_never_exist() {} + +#[cfg(rubygems_x_x_x)] +#[no_mangle] +pub extern "C" fn hello_from_rubygems_version() {} + +#[allow(non_snake_case)] +#[no_mangle] +pub extern "C" fn Init_rust_ruby_example() { + let name = CString::new("RustRubyExample").unwrap(); + let function_name = CString::new("reverse").unwrap(); + // bindgen does not properly detect the arity of the ruby callback function, so we have to transmute + let callback = unsafe { + std::mem::transmute::< + unsafe extern "C" fn(VALUE, VALUE) -> VALUE, + unsafe extern "C" fn() -> VALUE, + >(pub_reverse) + }; + let klass = unsafe { rb_define_module(name.as_ptr()) }; + + unsafe { rb_define_module_function(klass, function_name.as_ptr(), Some(callback), 1) } +} diff --git a/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb b/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb new file mode 100644 index 0000000000..a3fef50d54 --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require_relative "helper" +require "rubygems/ext" +require "rubygems/ext/cargo_builder/link_flag_converter" + +class TestGemExtCargoBuilderLinkFlagConverter < Gem::TestCase + CASES = { + test_search_path_basic: ["-L/usr/local/lib", ["-L", "native=/usr/local/lib"]], + test_search_path_space: ["-L /usr/local/lib", ["-L", "native=/usr/local/lib"]], + test_search_path_space_in_path: ["-L/usr/local/my\ lib", ["-L", "native=/usr/local/my\ lib"]], + test_simple_lib: ["-lfoo", ["-l", "foo"]], + test_lib_with_nonascii: ["-lws2_32", ["-l", "ws2_32"]], + test_simple_lib_space: ["-l foo", ["-l", "foo"]], + test_verbose_lib_space: ["--library=foo", ["-l", "foo"]], + test_libstatic_with_colon: ["-l:libssp.a", ["-C", "link-args=-l:libssp.a"]], + test_libstatic_with_colon_space: ["-l :libssp.a", ["-C", "link-args=-l :libssp.a"]], + test_unconventional_lib_with_colon: ["-l:ssp.a", ["-C", "link-args=-l:ssp.a"]], + test_dylib_with_colon_space: ["-l :libssp.dylib", ["-C", "link-args=-l :libssp.dylib"]], + test_so_with_colon_space: ["-l :libssp.so", ["-C", "link-args=-l :libssp.so"]], + test_dll_with_colon_space: ["-l :libssp.dll", ["-C", "link-args=-l :libssp.dll"]], + test_framework: ["-F/some/path", ["-l", "framework=/some/path"]], + test_framework_space: ["-F /some/path", ["-l", "framework=/some/path"]], + test_non_lib_dash_l: ["test_rubygems_20220413-976-lemgf9/prefix", ["-C", "link-args=test_rubygems_20220413-976-lemgf9/prefix"]], + }.freeze + + CASES.each do |test_name, (arg, expected)| + raise "duplicate test name" if instance_methods.include?(test_name) + + define_method(test_name) do + assert_equal(expected, Gem::Ext::CargoBuilder::LinkFlagConverter.convert(arg)) + end + end +end diff --git a/test/rubygems/test_gem_ext_cargo_builder_unit.rb b/test/rubygems/test_gem_ext_cargo_builder_unit.rb new file mode 100644 index 0000000000..89495b84ff --- /dev/null +++ b/test/rubygems/test_gem_ext_cargo_builder_unit.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require_relative "helper" +require "rubygems/ext" + +class TestGemExtCargoBuilderUnit < Gem::TestCase + def test_cargo_command_passes_args + skip_unsupported_platforms! + builder = Gem::Ext::CargoBuilder.new + command = builder.cargo_command(Dir.pwd, @tempdir, ["--all-features"]) + + assert_includes command, "--all-features" + end + + def test_cargo_command_locks_in_release_profile + skip_unsupported_platforms! + builder = Gem::Ext::CargoBuilder.new + builder.profile = :release + command = builder.cargo_command(Dir.pwd, @tempdir) + + assert_includes command, "--locked" + end + + def test_cargo_command_passes_respects_cargo_env_var + skip_unsupported_platforms! + old_cargo = ENV["CARGO"] + ENV["CARGO"] = "mycargo" + builder = Gem::Ext::CargoBuilder.new + command = builder.cargo_command(Dir.pwd, @tempdir) + + assert_includes command, "mycargo" + ensure + ENV["CARGO"] = old_cargo + end + + def test_build_env_includes_rbconfig + skip_unsupported_platforms! + builder = Gem::Ext::CargoBuilder.new + env = builder.build_env + + assert_equal env.fetch("RBCONFIG_RUBY_SO_NAME"), RbConfig::CONFIG["RUBY_SO_NAME"] + end + + def test_cargo_command_passes_respects_cargo_build_target + skip_unsupported_platforms! + old_cargo = ENV["CARGO_BUILD_TARGET"] + ENV["CARGO_BUILD_TARGET"] = "x86_64-unknown-linux-gnu" + builder = Gem::Ext::CargoBuilder.new + command = builder.cargo_command(Dir.pwd, @tempdir, ["--locked"]) + + assert_includes command, "--target" + assert_includes command, "x86_64-unknown-linux-gnu" + ensure + ENV["CARGO_BUILD_TARGET"] = old_cargo + end + + def skip_unsupported_platforms! + pend "jruby not supported" if Gem.java_platform? + end +end diff --git a/test/rubygems/test_gem_ext_cmake_builder.rb b/test/rubygems/test_gem_ext_cmake_builder.rb index b51c5a6e08..5f886af05f 100644 --- a/test/rubygems/test_gem_ext_cmake_builder.rb +++ b/test/rubygems/test_gem_ext_cmake_builder.rb @@ -1,30 +1,33 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/ext' + +require_relative "helper" +require "rubygems/ext" class TestGemExtCmakeBuilder < Gem::TestCase def setup super # Details: https://github.com/rubygems/rubygems/issues/1270#issuecomment-177368340 - skip "CmakeBuilder doesn't work on Windows." if Gem.win_platform? + pend "CmakeBuilder doesn't work on Windows." if Gem.win_platform? + + require "open3" begin - _, status = Open3.capture2e('cmake') - skip 'cmake not present' unless status.success? + _, status = Open3.capture2e("cmake") + pend "cmake not present" unless status.success? rescue Errno::ENOENT - skip 'cmake not present' + pend "cmake not present" end - @ext = File.join @tempdir, 'ext' - @dest_path = File.join @tempdir, 'prefix' + @ext = File.join @tempdir, "ext" + @dest_path = File.join @tempdir, "prefix" FileUtils.mkdir_p @ext FileUtils.mkdir_p @dest_path end def test_self_build - File.open File.join(@ext, 'CMakeLists.txt'), 'w' do |cmakelists| + File.open File.join(@ext, "CMakeLists.txt"), "w" do |cmakelists| cmakelists.write <<-EO_CMAKE cmake_minimum_required(VERSION 2.6) project(self_build NONE) @@ -32,7 +35,7 @@ install (FILES test.txt DESTINATION bin) EO_CMAKE end - FileUtils.touch File.join(@ext, 'test.txt') + FileUtils.touch File.join(@ext, "test.txt") output = [] @@ -40,11 +43,11 @@ install (FILES test.txt DESTINATION bin) output = output.join "\n" - assert_match %r{^cmake \. -DCMAKE_INSTALL_PREFIX\\=#{Regexp.escape @dest_path}}, output - assert_match %r{#{Regexp.escape @ext}}, output - assert_contains_make_command '', output - assert_contains_make_command 'install', output - assert_match %r{test\.txt}, output + assert_match(/^cmake \. -DCMAKE_INSTALL_PREFIX\\=#{Regexp.escape @dest_path}/, output) + assert_match(/#{Regexp.escape @ext}/, output) + assert_contains_make_command "", output + assert_contains_make_command "install", output + assert_match(/test\.txt/, output) end def test_self_build_fail @@ -56,16 +59,16 @@ install (FILES test.txt DESTINATION bin) output = output.join "\n" - shell_error_msg = %r{(CMake Error: .*)} + shell_error_msg = /(CMake Error: .*)/ - assert_match 'cmake failed', error.message + assert_match "cmake failed", error.message - assert_match %r{^cmake . -DCMAKE_INSTALL_PREFIX\\=#{Regexp.escape @dest_path}}, output - assert_match %r{#{shell_error_msg}}, output + assert_match(/^cmake . -DCMAKE_INSTALL_PREFIX\\=#{Regexp.escape @dest_path}/, output) + assert_match(/#{shell_error_msg}/, output) end def test_self_build_has_makefile - File.open File.join(@ext, 'Makefile'), 'w' do |makefile| + File.open File.join(@ext, "Makefile"), "w" do |makefile| makefile.puts "all:\n\t@echo ok\ninstall:\n\t@echo ok" end @@ -75,7 +78,7 @@ install (FILES test.txt DESTINATION bin) output = output.join "\n" - assert_contains_make_command '', output - assert_contains_make_command 'install', output + assert_contains_make_command "", output + assert_contains_make_command "install", output end end diff --git a/test/rubygems/test_gem_ext_configure_builder.rb b/test/rubygems/test_gem_ext_configure_builder.rb index 87260bcfa2..6a2f9883f0 100644 --- a/test/rubygems/test_gem_ext_configure_builder.rb +++ b/test/rubygems/test_gem_ext_configure_builder.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/ext' + +require_relative "helper" +require "rubygems/ext" class TestGemExtConfigureBuilder < Gem::TestCase def setup @@ -9,8 +10,8 @@ class TestGemExtConfigureBuilder < Gem::TestCase @makefile_body = "clean:\n\t@echo ok\nall:\n\t@echo ok\ninstall:\n\t@echo ok" - @ext = File.join @tempdir, 'ext' - @dest_path = File.join @tempdir, 'prefix' + @ext = File.join @tempdir, "ext" + @dest_path = File.join @tempdir, "prefix" FileUtils.mkdir_p @ext FileUtils.mkdir_p @dest_path @@ -19,7 +20,7 @@ class TestGemExtConfigureBuilder < Gem::TestCase def test_self_build pend("test_self_build skipped on MS Windows (VC++)") if vc_windows? - File.open File.join(@ext, './configure'), 'w' do |configure| + File.open File.join(@ext, "./configure"), "w" do |configure| configure.puts "#!/bin/sh\necho \"#{@makefile_body}\" > Makefile" end @@ -31,13 +32,13 @@ class TestGemExtConfigureBuilder < Gem::TestCase assert_equal "sh ./configure --prefix\\=#{@dest_path}", output.shift assert_equal "", output.shift assert_match(/^current directory:/, output.shift) - assert_contains_make_command 'clean', output.shift + assert_contains_make_command "clean", output.shift assert_match(/^ok$/m, output.shift) assert_match(/^current directory:/, output.shift) - assert_contains_make_command '', output.shift + assert_contains_make_command "", output.shift assert_match(/^ok$/m, output.shift) assert_match(/^current directory:/, output.shift) - assert_contains_make_command 'install', output.shift + assert_contains_make_command "install", output.shift assert_match(/^ok$/m, output.shift) end @@ -52,11 +53,11 @@ class TestGemExtConfigureBuilder < Gem::TestCase shell_error_msg = %r{(\./configure: .*)|((?:[Cc]an't|cannot) open '?\./configure'?(?:: No such file or directory)?)} sh_prefix_configure = "sh ./configure --prefix\\=" - assert_match 'configure failed', error.message + assert_match "configure failed", error.message assert_match(/^current directory:/, output.shift) assert_equal "#{sh_prefix_configure}#{@dest_path}", output.shift - assert_match %r{#{shell_error_msg}}, output.shift + assert_match(/#{shell_error_msg}/, output.shift) assert_equal true, output.empty? end @@ -65,15 +66,15 @@ class TestGemExtConfigureBuilder < Gem::TestCase pend("test_self_build_has_makefile skipped - nmake not found") end - File.open File.join(@ext, 'Makefile'), 'w' do |makefile| + File.open File.join(@ext, "Makefile"), "w" do |makefile| makefile.puts @makefile_body end output = [] Gem::Ext::ConfigureBuilder.build nil, @dest_path, output, [], nil, @ext - assert_contains_make_command 'clean', output[1] - assert_contains_make_command '', output[4] - assert_contains_make_command 'install', output[7] + assert_contains_make_command "clean", output[1] + assert_contains_make_command "", output[4] + assert_contains_make_command "install", output[7] 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 3b1d1c6777..218c6f3d5e 100644 --- a/test/rubygems/test_gem_ext_ext_conf_builder.rb +++ b/test/rubygems/test_gem_ext_ext_conf_builder.rb @@ -1,21 +1,21 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/ext' +require_relative "helper" +require "rubygems/ext" class TestGemExtExtConfBuilder < Gem::TestCase def setup super - @ext = File.join @tempdir, 'ext' - @dest_path = File.join @tempdir, 'prefix' + @ext = File.join @tempdir, "ext" + @dest_path = File.join @tempdir, "prefix" FileUtils.mkdir_p @ext FileUtils.mkdir_p @dest_path end def test_class_build - if java_platform? + if Gem.java_platform? pend("failing on jruby") end @@ -23,72 +23,76 @@ class TestGemExtExtConfBuilder < Gem::TestCase pend("test_class_build skipped - nmake not found") end - File.open File.join(@ext, 'extconf.rb'), 'w' do |extconf| + File.open File.join(@ext, "extconf.rb"), "w" do |extconf| extconf.puts "require 'mkmf'\ncreate_makefile 'foo'" end output = [] - result = Gem::Ext::ExtConfBuilder.build 'extconf.rb', @dest_path, output, [], nil, @ext + result = Gem::Ext::ExtConfBuilder.build "extconf.rb", @dest_path, output, [], nil, @ext assert_same result, output assert_match(/^current directory:/, output[0]) - assert_match(/^#{Gem.ruby}.* extconf.rb/, output[1]) + assert_match(/^#{Regexp.quote(Gem.ruby)}.* extconf.rb/, output[1]) assert_equal "creating Makefile\n", output[2] assert_match(/^current directory:/, output[3]) - assert_contains_make_command 'clean', output[4] - assert_contains_make_command '', output[7] - assert_contains_make_command 'install', output[10] - assert_empty Dir.glob(File.join(@ext, 'siteconf*.rb')) + assert_contains_make_command "clean", output[4] + assert_contains_make_command "", output[7] + assert_contains_make_command "install", output[10] + assert_empty Dir.glob(File.join(@ext, "siteconf*.rb")) + assert_empty Dir.glob(File.join(@ext, ".gem.*")) end def test_class_build_rbconfig_make_prog - if java_platform? + if Gem.java_platform? pend("failing on jruby") end configure_args do - - File.open File.join(@ext, 'extconf.rb'), 'w' do |extconf| + File.open File.join(@ext, "extconf.rb"), "w" do |extconf| extconf.puts "require 'mkmf'\ncreate_makefile 'foo'" end output = [] - Gem::Ext::ExtConfBuilder.build 'extconf.rb', @dest_path, output, [], nil, @ext + Gem::Ext::ExtConfBuilder.build "extconf.rb", @dest_path, output, [], nil, @ext assert_equal "creating Makefile\n", output[2] - assert_contains_make_command 'clean', output[4] - assert_contains_make_command '', output[7] - assert_contains_make_command 'install', output[10] + assert_contains_make_command "clean", output[4] + assert_contains_make_command "", output[7] + assert_contains_make_command "install", output[10] end end def test_class_build_env_make - env_make = ENV.delete 'MAKE' - ENV['MAKE'] = 'anothermake' + env_make = ENV.delete "make" + ENV["make"] = nil + + env_large_make = ENV.delete "MAKE" + ENV["MAKE"] = "anothermake" - if java_platform? + if Gem.java_platform? pend("failing on jruby") end - configure_args '' do - File.open File.join(@ext, 'extconf.rb'), 'w' do |extconf| + configure_args "" do + File.open File.join(@ext, "extconf.rb"), "w" do |extconf| extconf.puts "require 'mkmf'\ncreate_makefile 'foo'" end output = [] assert_raise Gem::InstallError do - Gem::Ext::ExtConfBuilder.build 'extconf.rb', @dest_path, output, [], nil, @ext + Gem::Ext::ExtConfBuilder.build "extconf.rb", @dest_path, output, [], nil, @ext end assert_equal "creating Makefile\n", output[2] - assert_contains_make_command 'clean', output[4] + assert_contains_make_command "clean", output[4] end ensure - ENV['MAKE'] = env_make + ENV["MAKE"] = env_large_make + ENV["make"] = env_make end def test_class_build_extconf_fail @@ -96,7 +100,7 @@ class TestGemExtExtConfBuilder < Gem::TestCase pend("test_class_build_extconf_fail skipped - nmake not found") end - File.open File.join(@ext, 'extconf.rb'), 'w' do |extconf| + File.open File.join(@ext, "extconf.rb"), "w" do |extconf| extconf.puts "require 'mkmf'" extconf.puts "have_library 'nonexistent' or abort 'need libnonexistent'" extconf.puts "create_makefile 'foo'" @@ -105,16 +109,16 @@ class TestGemExtExtConfBuilder < Gem::TestCase output = [] error = assert_raise Gem::InstallError do - Gem::Ext::ExtConfBuilder.build 'extconf.rb', @dest_path, output, [], nil, @ext + Gem::Ext::ExtConfBuilder.build "extconf.rb", @dest_path, output, [], nil, @ext end - assert_equal 'extconf failed, exit code 1', error.message + assert_equal "extconf failed, exit code 1", error.message - assert_match(/^#{Gem.ruby}.* extconf.rb/, output[1]) - assert_match(File.join(@dest_path, 'mkmf.log'), output[4]) + assert_match(/^#{Regexp.quote(Gem.ruby)}.* extconf.rb/, output[1]) + assert_match(File.join(@dest_path, "mkmf.log"), output[4]) assert_includes(output, "To see why this extension failed to compile, please check the mkmf.log which can be found here:\n") - assert_path_exist File.join @dest_path, 'mkmf.log' + assert_path_exist File.join @dest_path, "mkmf.log" end def test_class_build_extconf_success_without_warning @@ -122,7 +126,7 @@ class TestGemExtExtConfBuilder < Gem::TestCase pend("test_class_build_extconf_fail skipped - nmake not found") end - File.open File.join(@ext, 'extconf.rb'), 'w' do |extconf| + File.open File.join(@ext, "extconf.rb"), "w" do |extconf| extconf.puts "require 'mkmf'" extconf.puts "File.open('mkmf.log', 'w'){|f| f.write('a')}" extconf.puts "create_makefile 'foo'" @@ -130,11 +134,11 @@ class TestGemExtExtConfBuilder < Gem::TestCase output = [] - Gem::Ext::ExtConfBuilder.build 'extconf.rb', @dest_path, output, [], nil, @ext + Gem::Ext::ExtConfBuilder.build "extconf.rb", @dest_path, output, [], nil, @ext refute_includes(output, "To see why this extension failed to compile, please check the mkmf.log which can be found here:\n") - assert_path_exist File.join @dest_path, 'mkmf.log' + assert_path_exist File.join @dest_path, "mkmf.log" end def test_class_build_unconventional @@ -142,7 +146,7 @@ class TestGemExtExtConfBuilder < Gem::TestCase pend("test_class_build skipped - nmake not found") end - File.open File.join(@ext, 'extconf.rb'), 'w' do |extconf| + File.open File.join(@ext, "extconf.rb"), "w" do |extconf| extconf.puts <<-'EXTCONF' include RbConfig @@ -170,12 +174,12 @@ end output = [] - Gem::Ext::ExtConfBuilder.build 'extconf.rb', @dest_path, output, [], nil, @ext + Gem::Ext::ExtConfBuilder.build "extconf.rb", @dest_path, output, [], nil, @ext - assert_contains_make_command 'clean', output[4] - assert_contains_make_command '', output[7] - assert_contains_make_command 'install', output[10] - assert_empty Dir.glob(File.join(@ext, 'siteconf*.rb')) + assert_contains_make_command "clean", output[4] + assert_contains_make_command "", output[7] + assert_contains_make_command "install", output[10] + assert_empty Dir.glob(File.join(@ext, "siteconf*.rb")) end def test_class_make @@ -184,8 +188,8 @@ end end output = [] - makefile_path = File.join(@ext, 'Makefile') - File.open makefile_path, 'w' do |makefile| + 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)" @@ -196,30 +200,29 @@ end Gem::Ext::ExtConfBuilder.make @ext, output, @ext - assert_contains_make_command 'clean', output[1] - assert_contains_make_command '', output[4] - assert_contains_make_command 'install', output[7] + assert_contains_make_command "clean", output[1] + assert_contains_make_command "", output[4] + assert_contains_make_command "install", output[7] end def test_class_make_no_Makefile error = assert_raise Gem::InstallError do - Gem::Ext::ExtConfBuilder.make @ext, ['output'], @ext + Gem::Ext::ExtConfBuilder.make @ext, ["output"], @ext end - assert_equal 'Makefile not found', error.message + assert_equal "Makefile not found", error.message end def configure_args(args = nil) - configure_args = RbConfig::CONFIG['configure_args'] - RbConfig::CONFIG['configure_args'] = args if args + configure_args = RbConfig::CONFIG["configure_args"] + RbConfig::CONFIG["configure_args"] = args if args yield - ensure if configure_args - RbConfig::CONFIG['configure_args'] = configure_args + RbConfig::CONFIG["configure_args"] = configure_args else - RbConfig::CONFIG.delete 'configure_args' + RbConfig::CONFIG.delete "configure_args" end end end diff --git a/test/rubygems/test_gem_ext_rake_builder.rb b/test/rubygems/test_gem_ext_rake_builder.rb index 833f57615d..bd72c1aa08 100644 --- a/test/rubygems/test_gem_ext_rake_builder.rb +++ b/test/rubygems/test_gem_ext_rake_builder.rb @@ -1,30 +1,31 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/ext' + +require_relative "helper" +require "rubygems/ext" class TestGemExtRakeBuilder < Gem::TestCase def setup super - @ext = File.join @tempdir, 'ext' - @dest_path = File.join @tempdir, 'prefix' + @ext = File.join @tempdir, "ext" + @dest_path = File.join @tempdir, "prefix" FileUtils.mkdir_p @ext FileUtils.mkdir_p @dest_path end def test_class_build - create_temp_mkrf_file('task :default') + create_temp_mkrf_file("task :default") output = [] build_rake_in do |rake| - Gem::Ext::RakeBuilder.build 'mkrf_conf.rb', @dest_path, output, [], nil, @ext + Gem::Ext::RakeBuilder.build "mkrf_conf.rb", @dest_path, output, [], nil, @ext output = output.join "\n" - refute_match %r{^rake failed:}, output - assert_match %r{^#{Regexp.escape Gem.ruby} mkrf_conf\.rb}, output - assert_match %r{^#{Regexp.escape rake} RUBYARCHDIR\\=#{Regexp.escape @dest_path} RUBYLIBDIR\\=#{Regexp.escape @dest_path}}, output + refute_match(/^rake failed:/, output) + assert_match(/^#{Regexp.escape Gem.ruby} mkrf_conf\.rb/, output) + assert_match(/^#{Regexp.escape rake} RUBYARCHDIR\\=#{Regexp.escape @dest_path} RUBYLIBDIR\\=#{Regexp.escape @dest_path}/, output) end end @@ -32,44 +33,46 @@ class TestGemExtRakeBuilder < Gem::TestCase # # It should not fail with a non-empty args list either def test_class_build_with_args - create_temp_mkrf_file('task :default') + create_temp_mkrf_file("task :default") output = [] build_rake_in do |rake| - non_empty_args_list = [''] - Gem::Ext::RakeBuilder.build 'mkrf_conf.rb', @dest_path, output, non_empty_args_list, nil, @ext + non_empty_args_list = [""] + Gem::Ext::RakeBuilder.build "mkrf_conf.rb", @dest_path, output, non_empty_args_list, nil, @ext output = output.join "\n" - refute_match %r{^rake failed:}, output - assert_match %r{^#{Regexp.escape Gem.ruby} mkrf_conf\.rb}, output - assert_match %r{^#{Regexp.escape rake} RUBYARCHDIR\\=#{Regexp.escape @dest_path} RUBYLIBDIR\\=#{Regexp.escape @dest_path}}, output + refute_match(/^rake failed:/, output) + assert_match(/^#{Regexp.escape Gem.ruby} mkrf_conf\.rb/, output) + assert_match(/^#{Regexp.escape rake} RUBYARCHDIR\\=#{Regexp.escape @dest_path} RUBYLIBDIR\\=#{Regexp.escape @dest_path}/, output) end end def test_class_no_openssl_override - create_temp_mkrf_file('task :default') + pend "openssl is missing" unless Gem::HAVE_OPENSSL + + create_temp_mkrf_file("task :default") - rake = util_spec 'rake' do |s| + rake = util_spec "rake" do |s| s.executables = %w[rake] s.files = %w[bin/rake] end output = [] - write_file File.join(@tempdir, 'bin', 'rake') do |fp| + write_file File.join(@tempdir, "bin", "rake") do |fp| fp.puts "#!/usr/bin/ruby" fp.puts "require 'openssl'; puts OpenSSL" end install_gem rake - Gem::Ext::RakeBuilder.build 'mkrf_conf.rb', @dest_path, output, [''], nil, @ext + Gem::Ext::RakeBuilder.build "mkrf_conf.rb", @dest_path, output, [""], nil, @ext output = output.join "\n" assert_match "OpenSSL", output - assert_match %r{^#{Regexp.escape Gem.ruby} mkrf_conf\.rb}, output + assert_match(/^#{Regexp.escape Gem.ruby} mkrf_conf\.rb/, output) end def test_class_build_no_mkrf_passes_args @@ -80,8 +83,8 @@ class TestGemExtRakeBuilder < Gem::TestCase output = output.join "\n" - refute_match %r{^rake failed:}, output - assert_match %r{^#{Regexp.escape rake} RUBYARCHDIR\\=#{Regexp.escape @dest_path} RUBYLIBDIR\\=#{Regexp.escape @dest_path} test1 test2}, output + refute_match(/^rake failed:/, output) + assert_match(/^#{Regexp.escape rake} RUBYARCHDIR\\=#{Regexp.escape @dest_path} RUBYLIBDIR\\=#{Regexp.escape @dest_path} test1 test2/, output) end end @@ -89,17 +92,17 @@ class TestGemExtRakeBuilder < Gem::TestCase create_temp_mkrf_file("task :default do abort 'fail' end") output = [] - build_rake_in(false) do |rake| + build_rake_in(false) do |_rake| error = assert_raise Gem::InstallError do Gem::Ext::RakeBuilder.build "mkrf_conf.rb", @dest_path, output, [], nil, @ext end - assert_match %r{^rake failed}, error.message + assert_match(/^rake failed/, error.message) end end def create_temp_mkrf_file(rakefile_content) - File.open File.join(@ext, 'mkrf_conf.rb'), 'w' do |mkrf_conf| + File.open File.join(@ext, "mkrf_conf.rb"), "w" do |mkrf_conf| mkrf_conf.puts <<-EO_MKRF File.open("Rakefile","w") do |f| f.puts "#{rakefile_content}" diff --git a/test/rubygems/test_gem_gem_runner.rb b/test/rubygems/test_gem_gem_runner.rb index 8df11ecebc..c05e74c991 100644 --- a/test/rubygems/test_gem_gem_runner.rb +++ b/test/rubygems/test_gem_gem_runner.rb @@ -1,20 +1,26 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" class TestGemGemRunner < Gem::TestCase def setup - super - - require 'rubygems/command' + require "rubygems/command" @orig_args = Gem::Command.build_args @orig_specific_extra_args = Gem::Command.specific_extra_args_hash.dup @orig_extra_args = Gem::Command.extra_args.dup - require 'rubygems/gem_runner' + super + + @orig_gem_home = ENV["GEM_HOME"] + ENV["GEM_HOME"] = @gemhome + + require "rubygems/gem_runner" @runner = Gem::GemRunner.new end def teardown + ENV["GEM_HOME"] = @orig_gem_home + super Gem::Command.build_args = @orig_args @@ -25,15 +31,15 @@ class TestGemGemRunner < Gem::TestCase def test_do_configuration Gem.clear_paths - temp_conf = File.join @tempdir, '.gemrc' + temp_conf = File.join @tempdir, ".gemrc" - other_gem_path = File.join @tempdir, 'other_gem_path' - other_gem_home = File.join @tempdir, 'other_gem_home' + other_gem_path = File.join @tempdir, "other_gem_path" + other_gem_home = File.join @tempdir, "other_gem_home" Gem.ensure_gem_subdirectories other_gem_path Gem.ensure_gem_subdirectories other_gem_home - File.open temp_conf, 'w' do |fp| + File.open temp_conf, "w" do |fp| fp.puts "gem: --commands" fp.puts "gemhome: #{other_gem_home}" fp.puts "gempath:" diff --git a/test/rubygems/test_gem_gemcutter_utilities.rb b/test/rubygems/test_gem_gemcutter_utilities.rb index c673c6271f..a3236e6276 100644 --- a/test/rubygems/test_gem_gemcutter_utilities.rb +++ b/test/rubygems/test_gem_gemcutter_utilities.rb @@ -1,27 +1,33 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems' -require 'rubygems/command' -require 'rubygems/gemcutter_utilities' + +require_relative "helper" +require_relative "multifactor_auth_utilities" +require "rubygems" +require "rubygems/command" +require "rubygems/gemcutter_utilities" +require "rubygems/config_file" class TestGemGemcutterUtilities < Gem::TestCase def setup super credential_setup + @fetcher = SignInFetcher.new # below needed for random testing, class property Gem.configuration.disable_default_gem_server = nil - ENV['RUBYGEMS_HOST'] = nil + ENV["RUBYGEMS_HOST"] = nil + ENV["GEM_HOST_OTP_CODE"] = nil Gem.configuration.rubygems_api_key = nil - @cmd = Gem::Command.new '', 'summary' + @cmd = Gem::Command.new "", "summary" @cmd.extend Gem::GemcutterUtilities end def teardown - ENV['RUBYGEMS_HOST'] = nil + ENV["RUBYGEMS_HOST"] = nil + ENV["GEM_HOST_OTP_CODE"] = nil Gem.configuration.rubygems_api_key = nil credential_teardown @@ -31,42 +37,38 @@ class TestGemGemcutterUtilities < Gem::TestCase def test_alternate_key_alternate_host keys = { - :rubygems_api_key => 'KEY', + :rubygems_api_key => "KEY", "http://rubygems.engineyard.com" => "EYKEY", } - FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path - - File.open Gem.configuration.credentials_path, 'w' do |f| - f.write keys.to_yaml + File.open Gem.configuration.credentials_path, "w" do |f| + f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys) end ENV["RUBYGEMS_HOST"] = "http://rubygems.engineyard.com" Gem.configuration.load_api_keys - assert_equal 'EYKEY', @cmd.api_key + 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 + keys = { rubygems_api_key: "KEY" } - File.open Gem.configuration.credentials_path, 'w' do |f| - f.write keys.to_yaml + File.open Gem.configuration.credentials_path, "w" do |f| + f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys) end Gem.configuration.load_api_keys - assert_equal 'KEY', @cmd.api_key + assert_equal "KEY", @cmd.api_key end def test_api_key_override - keys = { :rubygems_api_key => 'KEY', :other => 'OTHER' } - FileUtils.mkdir_p File.dirname Gem.configuration.credentials_path + keys = { rubygems_api_key: "KEY", other: "OTHER" } - File.open Gem.configuration.credentials_path, 'w' do |f| - f.write keys.to_yaml + File.open Gem.configuration.credentials_path, "w" do |f| + f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys) end Gem.configuration.load_api_keys @@ -74,166 +76,237 @@ class TestGemGemcutterUtilities < Gem::TestCase @cmd.add_key_option @cmd.handle_options %w[--key other] - assert_equal 'OTHER', @cmd.api_key + assert_equal "OTHER", @cmd.api_key end def test_host - assert_equal 'https://rubygems.org', @cmd.host + assert_equal "https://rubygems.org", @cmd.host end def test_host_RUBYGEMS_HOST - ENV['RUBYGEMS_HOST'] = 'https://other.example' + ENV["RUBYGEMS_HOST"] = "https://other.example" - assert_equal 'https://other.example', @cmd.host + assert_equal "https://other.example", @cmd.host end def test_host_RUBYGEMS_HOST_empty - ENV['RUBYGEMS_HOST'] = '' + ENV["RUBYGEMS_HOST"] = "" - assert_equal 'https://rubygems.org', @cmd.host + assert_equal "https://rubygems.org", @cmd.host end def test_sign_in - api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' - util_sign_in [api_key, 200, 'OK'] + util_sign_in - assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output + assert_match(/Enter your RubyGems.org credentials./, @sign_in_ui.output) assert @fetcher.last_request["authorization"] - assert_match %r{Signed in.}, @sign_in_ui.output + assert_match(/Signed in./, @sign_in_ui.output) - credentials = YAML.load_file Gem.configuration.credentials_path - assert_equal api_key, credentials[:rubygems_api_key] + credentials = load_yaml_file Gem.configuration.credentials_path + assert_equal @fetcher.api_key, credentials[:rubygems_api_key] end def test_sign_in_with_host - api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' - - util_sign_in [api_key, 200, 'OK'], 'http://example.com', ['http://example.com'] + @fetcher = SignInFetcher.new(host: "http://example.com") + util_sign_in assert_match "Enter your http://example.com credentials.", @sign_in_ui.output assert @fetcher.last_request["authorization"] - assert_match %r{Signed in.}, @sign_in_ui.output + assert_match(/Signed in./, @sign_in_ui.output) - credentials = YAML.load_file Gem.configuration.credentials_path - assert_equal api_key, credentials['http://example.com'] + credentials = load_yaml_file Gem.configuration.credentials_path + assert_equal @fetcher.api_key, credentials["http://example.com"] end def test_sign_in_with_host_nil - api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' - - util_sign_in [api_key, 200, 'OK'], nil, [nil] + @fetcher = SignInFetcher.new(host: nil) + util_sign_in(args: [nil]) assert_match "Enter your RubyGems.org credentials.", @sign_in_ui.output assert @fetcher.last_request["authorization"] - assert_match %r{Signed in.}, @sign_in_ui.output + assert_match(/Signed in./, @sign_in_ui.output) - credentials = YAML.load_file Gem.configuration.credentials_path - assert_equal api_key, credentials[:rubygems_api_key] + credentials = load_yaml_file Gem.configuration.credentials_path + assert_equal @fetcher.api_key, credentials[:rubygems_api_key] end def test_sign_in_with_host_ENV - api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' - util_sign_in [api_key, 200, 'OK'], 'http://example.com' + @fetcher = SignInFetcher.new(host: "http://example.com") + util_sign_in assert_match "Enter your http://example.com credentials.", @sign_in_ui.output assert @fetcher.last_request["authorization"] - assert_match %r{Signed in.}, @sign_in_ui.output + assert_match(/Signed in./, @sign_in_ui.output) - credentials = YAML.load_file Gem.configuration.credentials_path - assert_equal api_key, credentials['http://example.com'] + credentials = load_yaml_file Gem.configuration.credentials_path + assert_equal @fetcher.api_key, credentials["http://example.com"] end def test_sign_in_skips_with_existing_credentials - api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' - Gem.configuration.rubygems_api_key = api_key + Gem.configuration.rubygems_api_key = @fetcher.api_key - util_sign_in [api_key, 200, 'OK'] + util_sign_in assert_equal "", @sign_in_ui.output end def test_sign_in_skips_with_key_override - api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' - Gem.configuration.api_keys[:KEY] = 'other' + Gem.configuration.api_keys[:KEY] = "other" @cmd.options[:key] = :KEY - util_sign_in [api_key, 200, 'OK'] + util_sign_in assert_equal "", @sign_in_ui.output end def test_sign_in_with_other_credentials_doesnt_overwrite_other_keys - api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' - other_api_key = 'f46dbb18bb6a9c97cdc61b5b85c186a17403cdcbf' + other_api_key = "f46dbb18bb6a9c97cdc61b5b85c186a17403cdcbf" + + config = Hash[:other_api_key, other_api_key] - FileUtils.mkdir_p File.dirname(Gem.configuration.credentials_path) - File.open Gem.configuration.credentials_path, 'w' do |f| - f.write Hash[:other_api_key, other_api_key].to_yaml + File.open Gem.configuration.credentials_path, "w" do |f| + f.write Gem::ConfigFile.dump_with_rubygems_yaml(config) end - util_sign_in [api_key, 200, 'OK'] + util_sign_in - assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output - assert_match %r{Signed in.}, @sign_in_ui.output + assert_match(/Enter your RubyGems.org credentials./, @sign_in_ui.output) + assert_match(/Signed in./, @sign_in_ui.output) - credentials = YAML.load_file Gem.configuration.credentials_path - assert_equal api_key, credentials[:rubygems_api_key] + credentials = load_yaml_file Gem.configuration.credentials_path + assert_equal @fetcher.api_key, credentials[:rubygems_api_key] assert_equal other_api_key, credentials[:other_api_key] end def test_sign_in_with_bad_credentials + @fetcher.respond_with_forbidden_api_key_response assert_raise Gem::MockGemUi::TermError do - util_sign_in ['Access Denied.', 403, 'Forbidden'] + util_sign_in end - assert_match %r{Enter your RubyGems.org credentials.}, @sign_in_ui.output - assert_match %r{Access Denied.}, @sign_in_ui.output + assert_match(/Enter your RubyGems.org credentials./, @sign_in_ui.output) + assert_match(/Access Denied./, @sign_in_ui.output) + end + + def test_signin_with_env_otp_code + ENV["GEM_HOST_OTP_CODE"] = "111111" + + util_sign_in + + assert_match "Signed in with API key:", @sign_in_ui.output + assert_equal "111111", @fetcher.last_request["OTP"] end def test_sign_in_with_correct_otp_code - api_key = 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903' - response_fail = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry." - - util_sign_in(proc do - @call_count ||= 0 - (@call_count += 1).odd? ? [response_fail, 401, 'Unauthorized'] : [api_key, 200, 'OK'] - end, nil, [], "111111\n") - - assert_match 'You have enabled multi-factor authentication. Please enter OTP code.', @sign_in_ui.output - assert_match 'Code: ', @sign_in_ui.output - assert_match 'Signed in with API key:', @sign_in_ui.output - assert_equal '111111', @fetcher.last_request['OTP'] + @fetcher.respond_with_require_otp + util_sign_in(extra_input: "111111\n") + + assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @sign_in_ui.output + assert_match "Code: ", @sign_in_ui.output + assert_match "Signed in with API key:", @sign_in_ui.output + assert_equal "111111", @fetcher.last_request["OTP"] end def test_sign_in_with_incorrect_otp_code response = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry." + @fetcher.respond_with_unauthorized_api_key_response assert_raise Gem::MockGemUi::TermError do - util_sign_in [response, 401, 'Unauthorized'], nil, [], "111111\n" + util_sign_in(extra_input: "111111\n") end - assert_match 'You have enabled multi-factor authentication. Please enter OTP code.', @sign_in_ui.output - assert_match 'Code: ', @sign_in_ui.output + assert_match "You have enabled multi-factor authentication. Please enter OTP code.", @sign_in_ui.output + assert_match "Code: ", @sign_in_ui.output assert_match response, @sign_in_ui.output - assert_equal '111111', @fetcher.last_request['OTP'] + assert_equal "111111", @fetcher.last_request["OTP"] end - def util_sign_in(response, host = nil, args = [], extra_input = '') - email = 'you@example.com' - password = 'secret' + def test_sign_in_with_webauthn_enabled + server = Gem::MockTCPServer.new - if host - ENV['RUBYGEMS_HOST'] = host - else - host = Gem.host + @fetcher.respond_with_require_otp + @fetcher.respond_with_webauthn_url + TCPServer.stub(:new, server) do + Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:otp] = "Uvh6T57tkWuUnWYo" }) do + util_sign_in + end end - @fetcher = Gem::FakeFetcher.new - @fetcher.data["#{host}/api/v1/api_key"] = response + assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \ + "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \ + "you can re-run the gem signin command with the `--otp [your_code]` option.", @sign_in_ui.output + assert_match "You are verified with a security device. You may close the browser window.", @sign_in_ui.output + assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"] + end + + def test_sign_in_with_webauthn_enabled_with_error + server = Gem::MockTCPServer.new + error = Gem::WebauthnVerificationError.new("Something went wrong") + + @fetcher.respond_with_require_otp + @fetcher.respond_with_webauthn_url + error = assert_raise Gem::MockGemUi::TermError do + TCPServer.stub(:new, server) do + Gem::GemcutterUtilities::WebauthnListener.stub(:listener_thread, Thread.new { Thread.current[:error] = error }) do + util_sign_in + end + end + end + assert_equal 1, error.exit_code + + assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \ + "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \ + "you can re-run the gem signin command with the `--otp [your_code]` option.", @sign_in_ui.output + assert_match "ERROR: Security device verification failed: Something went wrong", @sign_in_ui.error + refute_match "You are verified with a security device. You may close the browser window.", @sign_in_ui.output + refute_match "Signed in with API key:", @sign_in_ui.output + end + + def test_sign_in_with_webauthn_enabled_with_polling + server = Gem::MockTCPServer.new + @fetcher.respond_with_require_otp + @fetcher.respond_with_webauthn_url + @fetcher.respond_with_webauthn_polling("Uvh6T57tkWuUnWYo") + + TCPServer.stub(:new, server) do + util_sign_in + end + + assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \ + "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \ + "you can re-run the gem signin command with the `--otp [your_code]` option.", @sign_in_ui.output + assert_match "You are verified with a security device. You may close the browser window.", @sign_in_ui.output + assert_equal "Uvh6T57tkWuUnWYo", @fetcher.last_request["OTP"] + end + + def test_sign_in_with_webauthn_enabled_with_polling_failure + server = Gem::MockTCPServer.new + @fetcher.respond_with_require_otp + @fetcher.respond_with_webauthn_url + @fetcher.respond_with_webauthn_polling_failure + + assert_raise Gem::MockGemUi::TermError do + TCPServer.stub(:new, server) do + util_sign_in + end + end + + assert_match "You have enabled multi-factor authentication. Please visit #{@fetcher.webauthn_url_with_port(server.port)} " \ + "to authenticate via security device. If you can't verify using WebAuthn but have OTP enabled, " \ + "you can re-run the gem signin command with the `--otp [your_code]` option.", @sign_in_ui.output + assert_match "ERROR: Security device verification failed: " \ + "The token in the link you used has either expired or been used already.", @sign_in_ui.error + end + + def util_sign_in(args: [], extra_input: "") + email = "you@example.com" + password = "secret" + + ENV["RUBYGEMS_HOST"] = @fetcher.host Gem::RemoteFetcher.fetcher = @fetcher - @sign_in_ui = Gem::MockGemUi.new("#{email}\n#{password}\n\n\n\n\n\n\n\n\n" + extra_input) + @sign_in_ui = Gem::MockGemUi.new("#{email}\n#{password}\n\n\n" + extra_input) use_ui @sign_in_ui do if args.length > 0 @@ -245,14 +318,13 @@ class TestGemGemcutterUtilities < Gem::TestCase end def test_verify_api_key - keys = {:other => 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903'} - FileUtils.mkdir_p File.dirname(Gem.configuration.credentials_path) - File.open Gem.configuration.credentials_path, 'w' do |f| - f.write keys.to_yaml + keys = { other: "a5fdbb6ba150cbb83aad2bb2fede64cf040453903" } + File.open Gem.configuration.credentials_path, "w" do |f| + f.write Gem::ConfigFile.dump_with_rubygems_yaml(keys) end Gem.configuration.load_api_keys - assert_equal 'a5fdbb6ba150cbb83aad2bb2fede64cf040453903', + assert_equal "a5fdbb6ba150cbb83aad2bb2fede64cf040453903", @cmd.verify_api_key(:other) end @@ -261,4 +333,29 @@ class TestGemGemcutterUtilities < Gem::TestCase @cmd.verify_api_key :missing end end + + class SignInFetcher < Gem::MultifactorAuthFetcher + attr_reader :api_key + + def initialize(host: nil) + super(host: host) + @api_key = "a5fdbb6ba150cbb83aad2bb2fede64cf040453903" + @data["#{@host}/api/v1/api_key"] = Gem::HTTPResponseFactory.create(body: @api_key, code: 200, msg: "OK") + @data["#{@host}/api/v1/profile/me.yaml"] = Gem::HTTPResponseFactory.create(body: "mfa: disabled\n", code: 200, msg: "OK") + end + + def respond_with_require_otp + super("#{host}/api/v1/api_key", @api_key) + end + + def respond_with_forbidden_api_key_response + @data["#{host}/api/v1/api_key"] = Gem::HTTPResponseFactory.create(body: "Access Denied.", code: 403, msg: "Forbidden") + end + + def respond_with_unauthorized_api_key_response + response = "You have enabled multifactor authentication but your request doesn't have the correct OTP code. Please check it and retry." + + @data["#{host}/api/v1/api_key"] = Gem::HTTPResponseFactory.create(body: response, code: 401, msg: "Unauthorized") + end + end end diff --git a/test/rubygems/test_gem_impossible_dependencies_error.rb b/test/rubygems/test_gem_impossible_dependencies_error.rb index e4fe6ef77c..94c0290ea1 100644 --- a/test/rubygems/test_gem_impossible_dependencies_error.rb +++ b/test/rubygems/test_gem_impossible_dependencies_error.rb @@ -1,9 +1,10 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" class TestGemImpossibleDependenciesError < Gem::TestCase def test_message_conflict - request = dependency_request dep('net-ssh', '>= 2.0.13'), 'rye', '0.9.8' + request = dependency_request dep("net-ssh", ">= 2.0.13"), "rye", "0.9.8" conflicts = [] @@ -11,9 +12,9 @@ class TestGemImpossibleDependenciesError < Gem::TestCase # requested-by entries, but they are suitable for testing the message. # See #485 to construct a correct conflict. net_ssh_2_2_2 = - dependency_request dep('net-ssh', '>= 2.6.5'), 'net-ssh', '2.2.2', request + dependency_request dep("net-ssh", ">= 2.6.5"), "net-ssh", "2.2.2", request net_ssh_2_6_5 = - dependency_request dep('net-ssh', '~> 2.2.2'), 'net-ssh', '2.6.5', request + dependency_request dep("net-ssh", "~> 2.2.2"), "net-ssh", "2.6.5", request conflict1 = Gem::Resolver::Conflict.new \ net_ssh_2_6_5, net_ssh_2_6_5.requester diff --git a/test/rubygems/test_gem_indexer.rb b/test/rubygems/test_gem_indexer.rb deleted file mode 100644 index adc83dd8fb..0000000000 --- a/test/rubygems/test_gem_indexer.rb +++ /dev/null @@ -1,357 +0,0 @@ -# frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/indexer' - -class TestGemIndexer < Gem::TestCase - def setup - super - - util_make_gems - - @d2_0 = util_spec 'd', '2.0' do |s| - s.date = Gem::Specification::TODAY - 86400 * 3 - end - util_build_gem @d2_0 - - @d2_0_a = util_spec 'd', '2.0.a' - util_build_gem @d2_0_a - - @d2_0_b = util_spec 'd', '2.0.b' - util_build_gem @d2_0_b - - @default = new_default_spec 'default', 2 - install_default_gems @default - - @indexerdir = File.join(@tempdir, 'indexer') - - gems = File.join(@indexerdir, 'gems') - FileUtils.mkdir_p gems - FileUtils.mv Dir[File.join(@gemhome, "cache", '*.gem')], gems - - @indexer = Gem::Indexer.new(@indexerdir) - end - - def test_initialize - assert_equal @indexerdir, @indexer.dest_directory - assert_match %r{#{Dir.mktmpdir('gem_generate_index').match(/.*-/)}}, @indexer.directory - - indexer = Gem::Indexer.new @indexerdir - assert indexer.build_modern - - indexer = Gem::Indexer.new @indexerdir, :build_modern => true - assert indexer.build_modern - end - - def test_build_indices - @indexer.make_temp_directories - - use_ui @ui do - @indexer.build_indices - end - - specs_path = File.join @indexer.directory, "specs.#{@marshal_version}" - specs_dump = Gem.read_binary specs_path - specs = Marshal.load specs_dump - - expected = [["a", Gem::Version.new("1"), "ruby"], - ["a", Gem::Version.new("2"), "ruby"], - ["a_evil", Gem::Version.new("9"), "ruby"], - ["b", Gem::Version.new("2"), "ruby"], - ["c", Gem::Version.new("1.2"), "ruby"], - ["d", Gem::Version.new("2.0"), "ruby"], - ["dep_x", Gem::Version.new("1"), "ruby"], - ["pl", Gem::Version.new("1"), "i386-linux"], - ["x", Gem::Version.new("1"), "ruby"]] - - assert_equal expected, specs - - latest_specs_path = File.join(@indexer.directory, - "latest_specs.#{@marshal_version}") - latest_specs_dump = Gem.read_binary latest_specs_path - latest_specs = Marshal.load latest_specs_dump - - expected = [["a", Gem::Version.new("2"), "ruby"], - ["a_evil", Gem::Version.new("9"), "ruby"], - ["b", Gem::Version.new("2"), "ruby"], - ["c", Gem::Version.new("1.2"), "ruby"], - ["d", Gem::Version.new("2.0"), "ruby"], - ["dep_x", Gem::Version.new("1"), "ruby"], - ["pl", Gem::Version.new("1"), "i386-linux"], - ["x", Gem::Version.new("1"), "ruby"]] - - assert_equal expected, latest_specs, 'latest_specs' - end - - def test_generate_index - use_ui @ui do - @indexer.generate_index - end - - quickdir = File.join @indexerdir, 'quick' - marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}" - - assert_directory_exists quickdir - assert_directory_exists marshal_quickdir - - assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz" - assert_indexed marshal_quickdir, "#{File.basename(@a2.spec_file)}.rz" - - refute_indexed marshal_quickdir, File.basename(@c1_2.spec_file) - - assert_indexed @indexerdir, "specs.#{@marshal_version}" - assert_indexed @indexerdir, "specs.#{@marshal_version}.gz" - - assert_indexed @indexerdir, "latest_specs.#{@marshal_version}" - assert_indexed @indexerdir, "latest_specs.#{@marshal_version}.gz" - end - - def test_generate_index_modern - @indexer.build_modern = true - - use_ui @ui do - @indexer.generate_index - end - - refute_indexed @indexerdir, 'yaml' - refute_indexed @indexerdir, 'yaml.Z' - refute_indexed @indexerdir, "Marshal.#{@marshal_version}" - refute_indexed @indexerdir, "Marshal.#{@marshal_version}.Z" - - quickdir = File.join @indexerdir, 'quick' - marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}" - - assert_directory_exists quickdir, 'quickdir should be directory' - assert_directory_exists marshal_quickdir - - refute_indexed quickdir, "index" - refute_indexed quickdir, "index.rz" - - refute_indexed quickdir, "latest_index" - refute_indexed quickdir, "latest_index.rz" - - refute_indexed quickdir, "#{File.basename(@a1.spec_file)}.rz" - refute_indexed quickdir, "#{File.basename(@a2.spec_file)}.rz" - refute_indexed quickdir, "#{File.basename(@b2.spec_file)}.rz" - refute_indexed quickdir, "#{File.basename(@c1_2.spec_file)}.rz" - - refute_indexed quickdir, "#{@pl1.original_name}.gemspec.rz" - refute_indexed quickdir, "#{File.basename(@pl1.spec_file)}.rz" - - assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz" - assert_indexed marshal_quickdir, "#{File.basename(@a2.spec_file)}.rz" - - refute_indexed quickdir, "#{File.basename(@c1_2.spec_file)}" - refute_indexed marshal_quickdir, "#{File.basename(@c1_2.spec_file)}" - - assert_indexed @indexerdir, "specs.#{@marshal_version}" - assert_indexed @indexerdir, "specs.#{@marshal_version}.gz" - - assert_indexed @indexerdir, "latest_specs.#{@marshal_version}" - assert_indexed @indexerdir, "latest_specs.#{@marshal_version}.gz" - end - - def test_generate_index_modern_back_to_back - @indexer.build_modern = true - - use_ui @ui do - @indexer.generate_index - end - - @indexer = Gem::Indexer.new @indexerdir - @indexer.build_modern = true - - use_ui @ui do - @indexer.generate_index - end - quickdir = File.join @indexerdir, 'quick' - marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}" - - assert_directory_exists quickdir - assert_directory_exists marshal_quickdir - - assert_indexed marshal_quickdir, "#{File.basename(@a1.spec_file)}.rz" - assert_indexed marshal_quickdir, "#{File.basename(@a2.spec_file)}.rz" - - assert_indexed @indexerdir, "specs.#{@marshal_version}" - assert_indexed @indexerdir, "specs.#{@marshal_version}.gz" - - assert_indexed @indexerdir, "latest_specs.#{@marshal_version}" - assert_indexed @indexerdir, "latest_specs.#{@marshal_version}.gz" - end - - def test_generate_index_ui - use_ui @ui do - @indexer.generate_index - end - - assert_match %r{^\.\.\.\.\.\.\.\.\.\.\.\.$}, @ui.output - assert_match %r{^Generating Marshal quick index gemspecs for 12 gems$}, - @ui.output - assert_match %r{^Complete$}, @ui.output - assert_match %r{^Generating specs index$}, @ui.output - assert_match %r{^Generating latest specs index$}, @ui.output - assert_match %r{^Generating prerelease specs index$}, @ui.output - assert_match %r{^Complete$}, @ui.output - assert_match %r{^Compressing indices$}, @ui.output - - assert_equal '', @ui.error - end - - def test_generate_index_specs - use_ui @ui do - @indexer.generate_index - end - - specs_path = File.join @indexerdir, "specs.#{@marshal_version}" - - specs_dump = Gem.read_binary specs_path - specs = Marshal.load specs_dump - - expected = [ - ['a', Gem::Version.new(1), 'ruby'], - ['a', Gem::Version.new(2), 'ruby'], - ['a_evil', Gem::Version.new(9), 'ruby'], - ['b', Gem::Version.new(2), 'ruby'], - ['c', Gem::Version.new('1.2'), 'ruby'], - ['d', Gem::Version.new('2.0'), 'ruby'], - ['dep_x', Gem::Version.new(1), 'ruby'], - ['pl', Gem::Version.new(1), 'i386-linux'], - ['x', Gem::Version.new(1), 'ruby'], - ] - - assert_equal expected, specs - - assert_same specs[0].first, specs[1].first, - 'identical names not identical' - - assert_same specs[0][1], specs[-1][1], - 'identical versions not identical' - - assert_same specs[0].last, specs[1].last, - 'identical platforms not identical' - - refute_same specs[1][1], specs[5][1], - 'different versions not different' - end - - def test_generate_index_latest_specs - use_ui @ui do - @indexer.generate_index - end - - latest_specs_path = File.join @indexerdir, "latest_specs.#{@marshal_version}" - - latest_specs_dump = Gem.read_binary latest_specs_path - latest_specs = Marshal.load latest_specs_dump - - expected = [ - ['a', Gem::Version.new(2), 'ruby'], - ['a_evil', Gem::Version.new(9), 'ruby'], - ['b', Gem::Version.new(2), 'ruby'], - ['c', Gem::Version.new('1.2'), 'ruby'], - ['d', Gem::Version.new('2.0'), 'ruby'], - ['dep_x', Gem::Version.new(1), 'ruby'], - ['pl', Gem::Version.new(1), 'i386-linux'], - ['x', Gem::Version.new(1), 'ruby'], - ] - - assert_equal expected, latest_specs - - assert_same latest_specs[0][1], latest_specs[2][1], - 'identical versions not identical' - - assert_same latest_specs[0].last, latest_specs[1].last, - 'identical platforms not identical' - end - - def test_generate_index_prerelease_specs - use_ui @ui do - @indexer.generate_index - end - - prerelease_specs_path = File.join @indexerdir, "prerelease_specs.#{@marshal_version}" - - prerelease_specs_dump = Gem.read_binary prerelease_specs_path - prerelease_specs = Marshal.load prerelease_specs_dump - - assert_equal [['a', Gem::Version.new('3.a'), 'ruby'], - ['d', Gem::Version.new('2.0.a'), 'ruby'], - ['d', Gem::Version.new('2.0.b'), 'ruby']], - prerelease_specs - end - - ## - # Emulate the starting state of Gem::Specification in a live environment, - # where it will carry the list of system gems - def with_system_gems - Gem::Specification.reset - - sys_gem = util_spec 'systemgem', '1.0' - util_build_gem sys_gem - install_default_gems sys_gem - yield - util_remove_gem sys_gem - end - - def test_update_index - use_ui @ui do - @indexer.generate_index - end - - quickdir = File.join @indexerdir, 'quick' - marshal_quickdir = File.join quickdir, "Marshal.#{@marshal_version}" - - assert_directory_exists quickdir - assert_directory_exists marshal_quickdir - - @d2_1 = util_spec 'd', '2.1' - util_build_gem @d2_1 - @d2_1_tuple = [@d2_1.name, @d2_1.version, @d2_1.original_platform] - - @d2_1_a = util_spec 'd', '2.2.a' - util_build_gem @d2_1_a - @d2_1_a_tuple = [@d2_1_a.name, @d2_1_a.version, @d2_1_a.original_platform] - - gems = File.join @indexerdir, 'gems' - - FileUtils.mv @d2_1.cache_file, gems - FileUtils.mv @d2_1_a.cache_file, gems - - with_system_gems do - use_ui @ui do - @indexer.update_index - end - - assert_indexed marshal_quickdir, "#{File.basename(@d2_1.spec_file)}.rz" - - specs_index = Marshal.load Gem.read_binary(@indexer.dest_specs_index) - - assert_includes specs_index, @d2_1_tuple - refute_includes specs_index, @d2_1_a_tuple - - latest_specs_index = Marshal.load \ - Gem.read_binary(@indexer.dest_latest_specs_index) - - assert_includes latest_specs_index, @d2_1_tuple - assert_includes latest_specs_index, - [@d2_0.name, @d2_0.version, @d2_0.original_platform] - refute_includes latest_specs_index, @d2_1_a_tuple - - pre_specs_index = Marshal.load \ - Gem.read_binary(@indexer.dest_prerelease_specs_index) - - assert_includes pre_specs_index, @d2_1_a_tuple - refute_includes pre_specs_index, @d2_1_tuple - end - end - - def assert_indexed(dir, name) - file = File.join dir, name - assert File.exist?(file), "#{file} does not exist" - end - - def refute_indexed(dir, name) - file = File.join dir, name - refute File.exist?(file), "#{file} exists" - end -end diff --git a/test/rubygems/test_gem_install_update_options.rb b/test/rubygems/test_gem_install_update_options.rb index 92832eaf32..8fd5d9c543 100644 --- a/test/rubygems/test_gem_install_update_options.rb +++ b/test/rubygems/test_gem_install_update_options.rb @@ -1,14 +1,15 @@ # frozen_string_literal: true -require 'rubygems/installer_test_case' -require 'rubygems/install_update_options' -require 'rubygems/command' -require 'rubygems/dependency_installer' + +require_relative "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 @@ -38,7 +39,7 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase def test_build_root @cmd.handle_options %w[--build-root build_root] - assert_equal File.expand_path('build_root'), @cmd.options[:build_root] + assert_equal File.expand_path("build_root"), @cmd.options[:build_root] end def test_doc @@ -92,7 +93,7 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase end def test_security_policy - skip 'openssl is missing' unless Gem::HAVE_OPENSSL + pend "openssl is missing" unless Gem::HAVE_OPENSSL @cmd.handle_options %w[-P HighSecurity] @@ -100,18 +101,18 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase end def test_security_policy_unknown - skip 'openssl is missing' unless Gem::HAVE_OPENSSL + pend "openssl is missing" unless Gem::HAVE_OPENSSL @cmd.add_install_update_options - e = assert_raise OptionParser::InvalidArgument do + e = assert_raise Gem::OptionParser::InvalidArgument do @cmd.handle_options %w[-P UnknownSecurity] end assert_includes e.message, "UnknownSecurity" end def test_user_install_enabled - @spec = quick_gem 'a' do |spec| + @spec = quick_gem "a" do |spec| util_make_exec spec end @@ -124,42 +125,39 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase @installer = Gem::Installer.at @gem, @cmd.options @installer.install - assert_path_exist File.join(Gem.user_dir, 'gems') - assert_path_exist File.join(Gem.user_dir, 'gems', @spec.full_name) + assert_path_exist File.join(Gem.user_dir, "gems") + assert_path_exist File.join(Gem.user_dir, "gems", @spec.full_name) end def test_user_install_disabled_read_only - @spec = quick_gem 'a' do |spec| + pend "skipped on MS Windows (chmod has no effect)" if Gem.win_platform? + pend "skipped in root privilege" if Process.uid.zero? + + @spec = quick_gem "a" do |spec| util_make_exec spec end util_build_gem @spec @gem = @spec.cache_file - if win_platform? - pend('test_user_install_disabled_read_only test skipped on MS Windows') - elsif Process.uid.zero? - pend('test_user_install_disabled_read_only test skipped in root privilege') - else - @cmd.handle_options %w[--no-user-install] + @cmd.handle_options %w[--no-user-install] - refute @cmd.options[:user_install] + refute @cmd.options[:user_install] - FileUtils.chmod 0755, @userhome - FileUtils.chmod 0000, @gemhome + FileUtils.chmod 0o755, @userhome + FileUtils.chmod 0o000, @gemhome - Gem.use_paths @gemhome, @userhome + Gem.use_paths @gemhome, @userhome - assert_raise(Gem::FilePermissionError) do - Gem::Installer.at(@gem, @cmd.options).install - end + assert_raise(Gem::FilePermissionError) do + Gem::Installer.at(@gem, @cmd.options).install end ensure - FileUtils.chmod 0755, @gemhome + FileUtils.chmod 0o755, @gemhome end def test_vendor - vendordir(File.join(@tempdir, 'vendor')) do + vendordir(File.join(@tempdir, "vendor")) do @cmd.handle_options %w[--vendor] assert @cmd.options[:vendor] @@ -169,11 +167,11 @@ class TestGemInstallUpdateOptions < Gem::InstallerTestCase def test_vendor_missing vendordir(nil) do - e = assert_raise OptionParser::InvalidOption do + e = assert_raise Gem::OptionParser::InvalidOption do @cmd.handle_options %w[--vendor] end - assert_equal 'invalid option: --vendor your platform is not supported', + assert_equal "invalid option: --vendor your platform is not supported", e.message refute @cmd.options[:vendor] diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb index 1180e3a609..61609a26c9 100644 --- a/test/rubygems/test_gem_installer.rb +++ b/test/rubygems/test_gem_installer.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -require 'rubygems/installer_test_case' + +require_relative "installer_test_case" class TestGemInstaller < Gem::InstallerTestCase def setup @@ -18,11 +19,12 @@ class TestGemInstaller < Gem::InstallerTestCase end def test_app_script_text - installer = setup_base_installer + load_relative "no" do + installer = setup_base_installer - util_make_exec @spec, '' + util_make_exec @spec, "" - expected = <<-EOF + expected = <<-EOF #!#{Gem.ruby} # # This file was generated by RubyGems. @@ -33,6 +35,8 @@ class TestGemInstaller < Gem::InstallerTestCase require 'rubygems' +Gem.use_gemdeps + version = \">= 0.a\" str = ARGV.first @@ -50,10 +54,11 @@ else gem "a", version load Gem.bin_path("a", "executable", version) end - EOF + EOF - wrapper = installer.app_script_text 'executable' - assert_equal expected, wrapper + wrapper = installer.app_script_text "executable" + assert_equal expected, wrapper + end end def test_check_executable_overwrite @@ -62,12 +67,12 @@ end installer.generate_bin @spec = Gem::Specification.new do |s| - s.files = ['lib/code.rb'] + s.files = ["lib/code.rb"] s.name = "a" s.version = "3" s.summary = "summary" s.description = "desc" - s.require_path = 'lib' + s.require_path = "lib" end util_make_exec @@ -75,11 +80,11 @@ end installer.wrappers = true installer.generate_bin - installed_exec = File.join util_inst_bindir, 'executable' + installed_exec = File.join util_inst_bindir, "executable" assert_path_exist installed_exec wrapper = File.read installed_exec - assert_match %r{generated by RubyGems}, wrapper + assert_match(/generated by RubyGems/, wrapper) end def test_check_executable_overwrite_default_bin_dir @@ -94,9 +99,9 @@ end installer.generate_bin end - conflicted = File.join @gemhome, 'bin', 'executable' - assert_match %r{\A"executable" from a conflicts with (?:#{Regexp.quote(conflicted)}|installed executable from conflict)\z}, - e.message + conflicted = File.join @gemhome, "bin", "executable" + assert_match(/\A"executable" from a conflicts with (?:#{Regexp.quote(conflicted)}|installed executable from conflict)\z/, + e.message) end end end @@ -107,15 +112,15 @@ end installer.generate_bin @spec = Gem::Specification.new do |s| - s.files = ['lib/code.rb'] + s.files = ["lib/code.rb"] s.name = "a" s.version = "3" s.summary = "summary" s.description = "desc" - s.require_path = 'lib' + s.require_path = "lib" end - File.open File.join(util_inst_bindir, 'executable'), 'w' do |io| + File.open File.join(util_inst_bindir, "executable"), "w" do |io| io.write <<-EXEC #!/usr/local/bin/ruby # @@ -126,18 +131,18 @@ gem 'other', version end util_make_exec - Gem::Installer.exec_format = 'foo-%s-bar' + Gem::Installer.exec_format = "foo-%s-bar" installer.gem_dir = @spec.gem_dir installer.wrappers = true installer.format_executable = true installer.generate_bin # should not raise - installed_exec = File.join util_inst_bindir, 'foo-executable-bar' + installed_exec = File.join util_inst_bindir, "foo-executable-bar" assert_path_exist installed_exec wrapper = File.read installed_exec - assert_match %r{generated by RubyGems}, wrapper + assert_match(/generated by RubyGems/, wrapper) ensure Gem::Installer.exec_format = nil end @@ -168,11 +173,11 @@ gem 'other', version installer.generate_bin - installed_exec = File.join util_inst_bindir, 'executable' + installed_exec = File.join util_inst_bindir, "executable" assert_path_exist installed_exec wrapper = File.read installed_exec - assert_match %r{generated by RubyGems}, wrapper + assert_match(/generated by RubyGems/, wrapper) end def test_check_executable_overwrite_other_non_gem @@ -183,11 +188,11 @@ gem 'other', version installer.generate_bin - installed_exec = File.join util_inst_bindir, 'executable' + installed_exec = File.join util_inst_bindir, "executable" assert_path_exist installed_exec wrapper = File.read installed_exec - assert_match %r{generated by RubyGems}, wrapper + assert_match(/generated by RubyGems/, wrapper) end unless Gem.win_platform? def test_check_that_user_bin_dir_is_in_path @@ -199,8 +204,8 @@ gem 'other', version bin_dir = bin_dir.downcase end - orig_PATH, ENV['PATH'] = - ENV['PATH'], [ENV['PATH'], bin_dir].join(File::PATH_SEPARATOR) + orig_path = ENV["PATH"] + ENV["PATH"] = [ENV["PATH"], bin_dir].join(File::PATH_SEPARATOR) use_ui @ui do installer.check_that_user_bin_dir_is_in_path @@ -208,9 +213,9 @@ gem 'other', version assert_empty @ui.error - return unless win_platform? + return unless Gem.win_platform? - ENV['PATH'] = [orig_PATH, bin_dir.tr(File::SEPARATOR, File::ALT_SEPARATOR)].join(File::PATH_SEPARATOR) + ENV["PATH"] = [orig_path, bin_dir.tr(File::SEPARATOR, File::ALT_SEPARATOR)].join(File::PATH_SEPARATOR) use_ui @ui do installer.check_that_user_bin_dir_is_in_path @@ -218,17 +223,17 @@ gem 'other', version assert_empty @ui.error ensure - ENV['PATH'] = orig_PATH + ENV["PATH"] = orig_path end def test_check_that_user_bin_dir_is_in_path_tilde - skip "Tilde is PATH is not supported under MS Windows" if win_platform? + pend "Tilde is PATH is not supported under MS Windows" if Gem.win_platform? - orig_PATH, ENV['PATH'] = - ENV['PATH'], [ENV['PATH'], '~/bin'].join(File::PATH_SEPARATOR) + orig_path = ENV["PATH"] + ENV["PATH"] = [ENV["PATH"], "~/bin"].join(File::PATH_SEPARATOR) installer = setup_base_installer - installer.bin_dir.replace File.join @userhome, 'bin' + installer.bin_dir.replace File.join @userhome, "bin" use_ui @ui do installer.check_that_user_bin_dir_is_in_path @@ -236,7 +241,7 @@ gem 'other', version assert_empty @ui.error ensure - ENV['PATH'] = orig_PATH unless win_platform? + ENV["PATH"] = orig_path unless Gem.win_platform? end def test_check_that_user_bin_dir_is_in_path_not_in_path @@ -258,22 +263,22 @@ gem 'other', version def test_ensure_dependency installer = setup_base_installer - util_spec 'a' + util_spec "a" - dep = Gem::Dependency.new 'a', '>= 2' + dep = Gem::Dependency.new "a", ">= 2" assert installer.ensure_dependency(@spec, dep) - dep = Gem::Dependency.new 'b', '> 2' + dep = Gem::Dependency.new "b", "> 2" e = assert_raise Gem::InstallError do installer.ensure_dependency @spec, dep end - assert_equal 'a requires b (> 2)', e.message + assert_equal "a requires b (> 2)", e.message end def test_ensure_loadable_spec - a, a_gem = util_gem 'a', 2 do |s| - s.add_dependency 'garbage ~> 5' + a, a_gem = util_gem "a", 2 do |s| + s.add_dependency "garbage ~> 5" end installer = Gem::Installer.at a_gem @@ -282,19 +287,19 @@ gem 'other', version installer.ensure_loadable_spec end - assert_equal "The specification for #{a.full_name} is corrupt " + + assert_equal "The specification for #{a.full_name} is corrupt " \ "(SyntaxError)", e.message end def test_ensure_loadable_spec_security_policy - skip 'openssl is missing' unless Gem::HAVE_OPENSSL + pend "openssl is missing" unless Gem::HAVE_OPENSSL - _, a_gem = util_gem 'a', 2 do |s| - s.add_dependency 'garbage ~> 5' + _, a_gem = util_gem "a", 2 do |s| + s.add_dependency "garbage ~> 5" end policy = Gem::Security::HighSecurity - installer = Gem::Installer.at a_gem, :security_policy => policy + installer = Gem::Installer.at a_gem, security_policy: policy assert_raise Gem::Security::Exception do installer.ensure_loadable_spec @@ -306,7 +311,7 @@ gem 'other', version installer.extract_files - assert_path_exist File.join @spec.gem_dir, 'bin/executable' + assert_path_exist File.join @spec.gem_dir, "bin/executable" end def test_generate_bin_bindir @@ -315,12 +320,12 @@ gem 'other', version installer.wrappers = true @spec.executables = %w[executable] - @spec.bindir = 'bin' + @spec.bindir = "bin" - exec_file = installer.formatted_program_filename 'executable' + exec_file = installer.formatted_program_filename "executable" exec_path = File.join @spec.gem_dir, exec_file - File.open exec_path, 'w' do |f| - f.puts '#!/usr/bin/ruby' + File.open exec_path, "w" do |f| + f.puts "#!/usr/bin/ruby" end installer.gem_dir = @spec.gem_dir @@ -328,27 +333,30 @@ gem 'other', version installer.generate_bin assert_directory_exists util_inst_bindir - installed_exec = File.join(util_inst_bindir, 'executable') + installed_exec = File.join(util_inst_bindir, "executable") assert_path_exist installed_exec - assert_equal mask, File.stat(installed_exec).mode unless win_platform? + assert_equal mask, File.stat(installed_exec).mode unless Gem.win_platform? wrapper = File.read installed_exec - assert_match %r{generated by RubyGems}, wrapper + assert_match(/generated by RubyGems/, wrapper) end def test_generate_bin_bindir_with_user_install_warning - bin_dir = Gem.win_platform? ? File.expand_path(ENV["WINDIR"]).upcase : - "/usr/bin" + bin_dir = if Gem.win_platform? + File.expand_path(ENV["WINDIR"]).upcase + else + "/usr/bin" + end old_path = ENV["PATH"] ENV["PATH"] = [ENV["PATH"], bin_dir].compact.join(File::PATH_SEPARATOR) options = { - :bin_dir => bin_dir, - :install_dir => "/non/existent", + bin_dir: bin_dir, + install_dir: "/non/existent", } - inst = Gem::Installer.at '', options + inst = Gem::Installer.at "", options Gem::Installer.path_warning = false @@ -357,7 +365,6 @@ gem 'other', version end assert_equal "", @ui.error - ensure ENV["PATH"] = old_path end @@ -371,12 +378,12 @@ gem 'other', version installer.generate_bin assert_directory_exists util_inst_bindir - installed_exec = File.join util_inst_bindir, 'executable' + installed_exec = File.join util_inst_bindir, "executable" assert_path_exist installed_exec - assert_equal mask, File.stat(installed_exec).mode unless win_platform? + assert_equal mask, File.stat(installed_exec).mode unless Gem.win_platform? wrapper = File.read installed_exec - assert_match %r{generated by RubyGems}, wrapper + assert_match(/generated by RubyGems/, wrapper) end def test_generate_bin_script_format @@ -387,10 +394,10 @@ gem 'other', version util_make_exec installer.gem_dir = @spec.gem_dir - Gem::Installer.exec_format = 'foo-%s-bar' + Gem::Installer.exec_format = "foo-%s-bar" installer.generate_bin assert_directory_exists util_inst_bindir - installed_exec = File.join util_inst_bindir, 'foo-executable-bar' + installed_exec = File.join util_inst_bindir, "foo-executable-bar" assert_path_exist installed_exec ensure Gem::Installer.exec_format = nil @@ -403,10 +410,10 @@ gem 'other', version util_make_exec installer.gem_dir = @spec.gem_dir - Gem::Installer.exec_format = 'foo-%s-bar' + Gem::Installer.exec_format = "foo-%s-bar" installer.generate_bin assert_directory_exists util_inst_bindir - installed_exec = File.join util_inst_bindir, 'executable' + installed_exec = File.join util_inst_bindir, "executable" assert_path_exist installed_exec ensure Gem::Installer.exec_format = nil @@ -418,24 +425,24 @@ gem 'other', version installer.wrappers = true gem_dir = File.join("#{@gemhome}2", "gems", @spec.full_name) - gem_bindir = File.join gem_dir, 'bin' + gem_bindir = File.join gem_dir, "bin" FileUtils.mkdir_p gem_bindir - File.open File.join(gem_bindir, 'executable'), 'w' do |f| + File.open File.join(gem_bindir, "executable"), "w" do |f| f.puts "#!/bin/ruby" end installer.gem_home = "#{@gemhome}2" installer.gem_dir = gem_dir - installer.bin_dir = File.join "#{@gemhome}2", 'bin' + installer.bin_dir = File.join "#{@gemhome}2", "bin" installer.generate_bin - installed_exec = File.join("#{@gemhome}2", "bin", 'executable') + installed_exec = File.join("#{@gemhome}2", "bin", "executable") assert_path_exist installed_exec - assert_equal mask, File.stat(installed_exec).mode unless win_platform? + assert_equal mask, File.stat(installed_exec).mode unless Gem.win_platform? wrapper = File.read installed_exec - assert_match %r{generated by RubyGems}, wrapper + assert_match(/generated by RubyGems/, wrapper) end def test_generate_bin_script_no_execs @@ -446,7 +453,7 @@ gem 'other', version installer.wrappers = true installer.generate_bin - assert_path_not_exist util_inst_bindir, 'bin dir was created when not needed' + assert_path_not_exist util_inst_bindir, "bin dir was created when not needed" end def test_generate_bin_script_no_perms @@ -457,19 +464,19 @@ gem 'other', version Dir.mkdir util_inst_bindir - if win_platform? - pend('test_generate_bin_script_no_perms skipped on MS Windows') + if Gem.win_platform? + pend("test_generate_bin_script_no_perms skipped on MS Windows") elsif Process.uid.zero? - pend('test_generate_bin_script_no_perms skipped in root privilege') + pend("test_generate_bin_script_no_perms skipped in root privilege") else - FileUtils.chmod 0000, util_inst_bindir + FileUtils.chmod 0o000, util_inst_bindir assert_raise Gem::FilePermissionError do installer.generate_bin end end ensure - FileUtils.chmod 0755, util_inst_bindir unless ($DEBUG or win_platform?) + FileUtils.chmod 0o755, util_inst_bindir unless $DEBUG || Gem.win_platform? end def test_generate_bin_script_no_shebang @@ -478,23 +485,23 @@ gem 'other', version installer.wrappers = true @spec.executables = %w[executable] - gem_dir = File.join @gemhome, 'gems', @spec.full_name - gem_bindir = File.join gem_dir, 'bin' + gem_dir = File.join @gemhome, "gems", @spec.full_name + gem_bindir = File.join gem_dir, "bin" FileUtils.mkdir_p gem_bindir - File.open File.join(gem_bindir, 'executable'), 'w' do |f| + File.open File.join(gem_bindir, "executable"), "w" do |f| f.puts "blah blah blah" end installer.generate_bin - installed_exec = File.join @gemhome, 'bin', 'executable' + installed_exec = File.join @gemhome, "bin", "executable" assert_path_exist installed_exec - assert_equal mask, File.stat(installed_exec).mode unless win_platform? + assert_equal mask, File.stat(installed_exec).mode unless Gem.win_platform? wrapper = File.read installed_exec - assert_match %r{generated by RubyGems}, wrapper - # HACK some gems don't have #! in their executables, restore 2008/06 - #assert_no_match %r|generated by RubyGems|, wrapper + assert_match(/generated by RubyGems/, wrapper) + # HACK: some gems don't have #! in their executables, restore 2008/06 + # assert_no_match %r|generated by RubyGems|, wrapper end def test_generate_bin_script_wrappers @@ -503,9 +510,9 @@ gem 'other', version installer.wrappers = true util_make_exec installer.gem_dir = @spec.gem_dir - installed_exec = File.join(util_inst_bindir, 'executable') + installed_exec = File.join(util_inst_bindir, "executable") - real_exec = File.join @spec.gem_dir, 'bin', 'executable' + real_exec = File.join @spec.gem_dir, "bin", "executable" # fake --no-wrappers for previous install unless Gem.win_platform? @@ -516,16 +523,16 @@ gem 'other', version installer.generate_bin assert_directory_exists util_inst_bindir assert_path_exist installed_exec - assert_equal mask, File.stat(installed_exec).mode unless win_platform? + assert_equal mask, File.stat(installed_exec).mode unless Gem.win_platform? - assert_match %r{generated by RubyGems}, File.read(installed_exec) + assert_match(/generated by RubyGems/, File.read(installed_exec)) - refute_match %r{generated by RubyGems}, File.read(real_exec), - 'real executable overwritten' + refute_match(/generated by RubyGems/, File.read(real_exec), + "real executable overwritten") end def test_generate_bin_symlink - skip "Symlinks not supported or not enabled" unless symlink_supported? + pend "Symlinks not supported or not enabled" unless symlink_supported? installer = setup_base_installer @@ -535,9 +542,9 @@ gem 'other', version installer.generate_bin assert_directory_exists util_inst_bindir - installed_exec = File.join util_inst_bindir, 'executable' + installed_exec = File.join util_inst_bindir, "executable" assert_equal true, File.symlink?(installed_exec) - assert_equal(File.join(@spec.gem_dir, 'bin', 'executable'), + assert_equal(File.join(@spec.gem_dir, "bin", "executable"), File.readlink(installed_exec)) end @@ -561,23 +568,23 @@ gem 'other', version Dir.mkdir util_inst_bindir - if win_platform? - pend('test_generate_bin_symlink_no_perms skipped on MS Windows') + if Gem.win_platform? + pend("test_generate_bin_symlink_no_perms skipped on MS Windows") elsif Process.uid.zero? - pend('test_user_install_disabled_read_only test skipped in root privilege') + pend("test_user_install_disabled_read_only test skipped in root privilege") else - FileUtils.chmod 0000, util_inst_bindir + FileUtils.chmod 0o000, util_inst_bindir assert_raise Gem::FilePermissionError do installer.generate_bin end end ensure - FileUtils.chmod 0755, util_inst_bindir unless ($DEBUG or win_platform?) + FileUtils.chmod 0o755, util_inst_bindir unless $DEBUG || Gem.win_platform? end def test_generate_bin_symlink_update_newer - skip "Symlinks not supported or not enabled" unless symlink_supported? + pend "Symlinks not supported or not enabled" unless symlink_supported? installer = setup_base_installer @@ -586,30 +593,30 @@ gem 'other', version installer.gem_dir = @spec.gem_dir installer.generate_bin - installed_exec = File.join(util_inst_bindir, 'executable') - assert_equal(File.join(@spec.gem_dir, 'bin', 'executable'), + installed_exec = File.join(util_inst_bindir, "executable") + assert_equal(File.join(@spec.gem_dir, "bin", "executable"), File.readlink(installed_exec)) @spec = Gem::Specification.new do |s| - s.files = ['lib/code.rb'] + s.files = ["lib/code.rb"] s.name = "a" s.version = "3" s.summary = "summary" s.description = "desc" - s.require_path = 'lib' + s.require_path = "lib" end util_make_exec installer.gem_dir = @spec.gem_dir installer.generate_bin - installed_exec = File.join(util_inst_bindir, 'executable') - assert_equal(@spec.bin_file('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_update_older - skip "Symlinks not supported or not enabled" unless symlink_supported? + pend "Symlinks not supported or not enabled" unless symlink_supported? installer = setup_base_installer @@ -618,17 +625,17 @@ gem 'other', version installer.gem_dir = @spec.gem_dir installer.generate_bin - installed_exec = File.join(util_inst_bindir, 'executable') - assert_equal(File.join(@spec.gem_dir, 'bin', 'executable'), + installed_exec = File.join(util_inst_bindir, "executable") + assert_equal(File.join(@spec.gem_dir, "bin", "executable"), File.readlink(installed_exec)) spec = Gem::Specification.new do |s| - s.files = ['lib/code.rb'] + s.files = ["lib/code.rb"] s.name = "a" s.version = "1" s.summary = "summary" s.description = "desc" - s.require_path = 'lib' + s.require_path = "lib" end util_make_exec @@ -639,15 +646,15 @@ gem 'other', version installer.generate_bin - installed_exec = File.join util_inst_bindir, 'executable' - expected = File.join @spec.gem_dir, 'bin', 'executable' + installed_exec = File.join util_inst_bindir, "executable" + expected = File.join @spec.gem_dir, "bin", "executable" assert_equal(expected, File.readlink(installed_exec), "Ensure symlink not moved") end def test_generate_bin_symlink_update_remove_wrapper - skip "Symlinks not supported or not enabled" unless symlink_supported? + pend "Symlinks not supported or not enabled" unless symlink_supported? installer = setup_base_installer @@ -657,16 +664,16 @@ gem 'other', version installer.generate_bin - installed_exec = File.join util_inst_bindir, 'executable' + installed_exec = File.join util_inst_bindir, "executable" assert_path_exist installed_exec @spec = Gem::Specification.new do |s| - s.files = ['lib/code.rb'] + s.files = ["lib/code.rb"] s.name = "a" s.version = "3" s.summary = "summary" s.description = "desc" - s.require_path = 'lib' + s.require_path = "lib" end util_make_exec @@ -676,8 +683,8 @@ gem 'other', version installer.generate_bin - installed_exec = File.join util_inst_bindir, 'executable' - assert_equal(@spec.bin_file('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 @@ -687,7 +694,7 @@ gem 'other', version Gem.win_platform = true old_alt_separator = File::ALT_SEPARATOR File.__send__(:remove_const, :ALT_SEPARATOR) - File.const_set(:ALT_SEPARATOR, '\\') + File.const_set(:ALT_SEPARATOR, "\\") installer = setup_base_installer @@ -700,7 +707,7 @@ gem 'other', version end assert_directory_exists util_inst_bindir - installed_exec = File.join(util_inst_bindir, 'executable') + installed_exec = File.join(util_inst_bindir, "executable") assert_path_exist installed_exec if symlink_supported? @@ -720,19 +727,21 @@ gem 'other', version end def test_generate_bin_uses_default_shebang - skip "Symlinks not supported or not enabled" unless symlink_supported? + pend "Symlinks not supported or not enabled" unless symlink_supported? - installer = setup_base_installer + load_relative "no" do + installer = setup_base_installer - installer.wrappers = true - util_make_exec + installer.wrappers = true + util_make_exec - installer.generate_bin + installer.generate_bin - default_shebang = Gem.ruby - shebang_line = File.open("#{@gemhome}/bin/executable") {|f| f.readlines.first } - assert_match(/\A#!/, shebang_line) - assert_match(/#{default_shebang}/, shebang_line) + default_shebang = Gem.ruby + shebang_line = File.open("#{@gemhome}/bin/executable", &:gets) + assert_match(/\A#!/, shebang_line) + assert_include(shebang_line, default_shebang) + end end def test_generate_bin_with_dangling_symlink @@ -740,9 +749,8 @@ gem 'other', version installer = Gem::Installer.at( gem_with_dangling_symlink, - :install_dir => @gem_home, - :user_install => false, - :force => true + user_install: false, + force: true ) build_rake_in do @@ -751,14 +759,17 @@ gem 'other', version end end - assert_match %r{bin/ascii_binder` is dangling symlink pointing to `bin/asciibinder`}, @ui.error + errors = @ui.error.split("\n") + assert_equal "WARNING: ascii_binder-0.1.10.1 ships with a dangling symlink named bin/ascii_binder pointing to missing bin/asciibinder file. Ignoring", errors.shift + assert_empty errors + assert_empty @ui.output end def test_generate_plugins installer = util_setup_installer do |spec| - write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io| - io.write "puts __FILE__" + write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io| + io.write "# do nothing" end spec.files += %w[lib/rubygems_plugin.rb] @@ -768,18 +779,18 @@ gem 'other', version installer.install end - plugin_path = File.join Gem.plugindir, 'a_plugin.rb' + plugin_path = File.join Gem.plugindir, "a_plugin.rb" FileUtils.rm plugin_path installer.generate_plugins - assert File.exist?(plugin_path), 'plugin not written' + assert File.exist?(plugin_path), "plugin not written" end def test_generate_plugins_with_install_dir - spec = quick_gem 'a' do |s| - write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io| + spec = quick_gem "a" do |s| + write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io| io.write "puts __FILE__" end @@ -788,17 +799,17 @@ gem 'other', version util_build_gem spec - plugin_path = File.join "#{@gemhome}2", 'plugins', 'a_plugin.rb' + plugin_path = File.join "#{@gemhome}2", "plugins", "a_plugin.rb" installer = util_installer spec, "#{@gemhome}2" assert_equal spec, installer.install - assert File.exist?(plugin_path), 'plugin not written to install_dir' + assert File.exist?(plugin_path), "plugin not written to install_dir" end def test_generate_plugins_with_user_install - spec = quick_gem 'a' do |s| - write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io| + spec = quick_gem "a" do |s| + write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io| io.write "puts __FILE__" end @@ -807,20 +818,20 @@ gem 'other', version util_build_gem spec - File.chmod(0555, Gem.plugindir) - system_path = File.join(Gem.plugindir, 'a_plugin.rb') - user_path = File.join(Gem.plugindir(Gem.user_dir), 'a_plugin.rb') - installer = util_installer spec, Gem.dir, :user + File.chmod(0o555, Gem.plugindir) + system_path = File.join(Gem.plugindir, "a_plugin.rb") + user_path = File.join(Gem.plugindir(Gem.user_dir), "a_plugin.rb") + installer = Gem::Installer.at spec.cache_file, user_install: true, force: true assert_equal spec, installer.install - assert !File.exist?(system_path), 'plugin incorrectly written to system plugins_dir' - assert File.exist?(user_path), 'plugin not written to user plugins_dir' + assert !File.exist?(system_path), "plugin incorrectly written to system plugins_dir" + assert File.exist?(user_path), "plugin not written to user plugins_dir" end def test_generate_plugins_with_build_root - spec = quick_gem 'a' do |s| - write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io| + spec = quick_gem "a" do |s| + write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io| io.write "puts __FILE__" end @@ -829,78 +840,126 @@ gem 'other', version util_build_gem spec - File.chmod(0555, Gem.plugindir) - system_path = File.join(Gem.plugindir, 'a_plugin.rb') + File.chmod(0o555, Gem.plugindir) + system_path = File.join(Gem.plugindir, "a_plugin.rb") - build_root = File.join(@tempdir, 'build_root') - build_root_path = File.join(build_root, Gem.plugindir.gsub(/^[a-zA-Z]:/, ''), 'a_plugin.rb') + build_root = File.join(@tempdir, "build_root") + build_root_path = File.join(build_root, Gem.plugindir.gsub(/^[a-zA-Z]:/, ""), "a_plugin.rb") - installer = Gem::Installer.at spec.cache_file, :build_root => build_root + installer = Gem::Installer.at spec.cache_file, build_root: build_root assert_equal spec, installer.install - assert !File.exist?(system_path), 'plugin written incorrect written to system plugins_dir' - assert File.exist?(build_root_path), 'plugin not written to build_root' + assert !File.exist?(system_path), "plugin written incorrect written to system plugins_dir" + assert File.exist?(build_root_path), "plugin not written to build_root" refute_includes File.read(build_root_path), build_root end + class << self + attr_accessor :plugin_loaded + attr_accessor :post_install_is_called + end + + def test_use_plugin_immediately + self.class.plugin_loaded = false + self.class.post_install_is_called = false + spec_version = nil + plugin_path = nil + installer = util_setup_installer do |spec| + spec_version = spec.version + plugin_path = File.join("lib", "rubygems_plugin.rb") + write_file File.join(@tempdir, plugin_path) do |io| + io.write <<-PLUGIN +#{self.class}.plugin_loaded = true +Gem.post_install do + #{self.class}.post_install_is_called = true +end + PLUGIN + end + spec.files += [plugin_path] + plugin_path = File.join(spec.gem_dir, plugin_path) + end + build_rake_in do + installer.install + end + assert self.class.plugin_loaded, "plugin is not loaded" + assert self.class.post_install_is_called, + "post install hook registered by plugin is not called" + + self.class.plugin_loaded = false + $LOADED_FEATURES.delete(plugin_path) + installer_new = util_setup_installer do |spec_new| + spec_new.version = spec_version.version.succ + plugin_path = File.join("lib", "rubygems_plugin.rb") + write_file File.join(@tempdir, plugin_path) do |io| + io.write "#{self.class}.plugin_loaded = true" + end + spec_new.files += [plugin_path] + end + build_rake_in do + installer_new.install + end + assert !self.class.plugin_loaded, + "plugin is loaded even when old version is already loaded" + end + def test_keeps_plugins_up_to_date # NOTE: version a-2 is already installed by setup hooks - write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io| - io.write "puts __FILE__" + write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io| + io.write "# do nothing" end build_rake_in do util_setup_installer do |spec| - spec.version = '1' + spec.version = "1" spec.files += %w[lib/rubygems_plugin.rb] end.install - plugin_path = File.join Gem.plugindir, 'a_plugin.rb' - refute File.exist?(plugin_path), 'old version installed while newer version without plugin also installed, but plugin written' + plugin_path = File.join Gem.plugindir, "a_plugin.rb" + refute File.exist?(plugin_path), "old version installed while newer version without plugin also installed, but plugin written" util_setup_installer do |spec| - spec.version = '2' + spec.version = "2" spec.files += %w[lib/rubygems_plugin.rb] end.install - plugin_path = File.join Gem.plugindir, 'a_plugin.rb' - assert File.exist?(plugin_path), 'latest version reinstalled, but plugin not written' - assert_match %r{\Arequire.*a-2/lib/rubygems_plugin\.rb}, File.read(plugin_path), 'written plugin has incorrect content' + plugin_path = File.join Gem.plugindir, "a_plugin.rb" + assert File.exist?(plugin_path), "latest version reinstalled, but plugin not written" + assert_match %r{\Arequire.*a-2/lib/rubygems_plugin\.rb}, File.read(plugin_path), "written plugin has incorrect content" util_setup_installer do |spec| - spec.version = '3' + spec.version = "3" spec.files += %w[lib/rubygems_plugin.rb] end.install - plugin_path = File.join Gem.plugindir, 'a_plugin.rb' - assert File.exist?(plugin_path), 'latest version installed, but plugin removed' - assert_match %r{\Arequire.*a-3/lib/rubygems_plugin\.rb}, File.read(plugin_path), 'written plugin has incorrect content' + plugin_path = File.join Gem.plugindir, "a_plugin.rb" + assert File.exist?(plugin_path), "latest version installed, but plugin removed" + assert_match %r{\Arequire.*a-3/lib/rubygems_plugin\.rb}, File.read(plugin_path), "written plugin has incorrect content" util_setup_installer do |spec| - spec.version = '4' + spec.version = "4" end.install - refute File.exist?(plugin_path), 'new version installed without a plugin while older version with a plugin installed, but plugin not removed' + refute File.exist?(plugin_path), "new version installed without a plugin while older version with a plugin installed, but plugin not removed" end end def test_generates_plugins_dir_under_install_dir_if_not_there Gem.use_paths "#{@gemhome}2" # Set GEM_HOME to an uninitialized repo - @spec = util_spec 'a' + @spec = util_spec "a" path = Gem::Package.build @spec - installer = Gem::Installer.at path, :install_dir => "#{@gemhome}3" + installer = Gem::Installer.at path, install_dir: "#{@gemhome}3" assert_equal @spec, installer.install end def test_initialize - spec = util_spec 'a' do |s| - s.platform = Gem::Platform.new 'mswin32' + spec = util_spec "a" do |s| + s.platform = Gem::Platform.new "mswin32" end gem = File.join @tempdir, spec.file_name @@ -911,16 +970,16 @@ gem 'other', version installer = Gem::Installer.at gem - assert_equal File.join(@gemhome, 'gems', spec.full_name), installer.gem_dir - assert_equal File.join(@gemhome, 'bin'), installer.bin_dir + assert_equal File.join(@gemhome, "gems", spec.full_name), installer.gem_dir + assert_equal File.join(@gemhome, "bin"), installer.bin_dir end def test_initialize_user_install @gem = setup_base_gem - installer = Gem::Installer.at @gem, :user_install => true + installer = Gem::Installer.at @gem, user_install: true - assert_equal File.join(Gem.user_dir, 'gems', @spec.full_name), + assert_equal File.join(Gem.user_dir, "gems", @spec.full_name), installer.gem_dir assert_equal Gem.bindir(Gem.user_dir), installer.bin_dir end @@ -929,39 +988,49 @@ gem 'other', version @gem = setup_base_gem installer = - Gem::Installer.at @gem, :user_install => true, :bin_dir => @tempdir + Gem::Installer.at @gem, user_install: true, bin_dir: @tempdir - assert_equal File.join(Gem.user_dir, 'gems', @spec.full_name), + assert_equal File.join(Gem.user_dir, "gems", @spec.full_name), installer.gem_dir assert_equal @tempdir, installer.bin_dir end + def test_install_dir_takes_precedence_to_user_install + gemhome2 = "#{@gemhome}2" + + @gem = setup_base_gem + + installer = + Gem::Installer.at @gem, install_dir: gemhome2, user_install: true + installer.install + + assert_path_exist File.join(gemhome2, "gems", @spec.full_name) + assert_path_not_exist File.join(Gem.user_dir, "gems", @spec.full_name) + end + def test_install installer = util_setup_installer - gemdir = File.join @gemhome, 'gems', @spec.full_name - cache_file = File.join @gemhome, 'cache', @spec.file_name - stub_exe = File.join @gemhome, 'bin', 'executable' - rakefile = File.join gemdir, 'ext', 'a', 'Rakefile' - spec_file = File.join @gemhome, 'specifications', @spec.spec_name + gemdir = File.join @gemhome, "gems", @spec.full_name + cache_file = File.join @gemhome, "cache", @spec.file_name + stub_exe = File.join @gemhome, "bin", "executable" + rakefile = File.join gemdir, "ext", "a", "Rakefile" + spec_file = File.join @gemhome, "specifications", @spec.spec_name Gem.pre_install do - assert_path_not_exist cache_file, 'cache file must not exist yet' - assert_path_not_exist spec_file, 'spec file must not exist yet' + assert_path_not_exist cache_file, "cache file must not exist yet" true end Gem.post_build do - assert_path_exist gemdir, 'gem install dir must exist' - assert_path_exist rakefile, 'gem executable must exist' - assert_path_not_exist stub_exe, 'gem executable must not exist' - assert_path_not_exist spec_file, 'spec file must not exist yet' + assert_path_exist gemdir, "gem install dir must exist" + assert_path_exist rakefile, "gem executable must exist" + assert_path_not_exist stub_exe, "gem executable must not exist" true end Gem.post_install do - assert_path_exist cache_file, 'cache file must exist' - assert_path_exist spec_file, 'spec file must exist' + assert_path_exist cache_file, "cache file must exist" end @newspec = nil @@ -973,15 +1042,15 @@ gem 'other', version assert_equal @spec, @newspec assert_path_exist gemdir - assert_path_exist stub_exe, 'gem executable must exist' + assert_path_exist stub_exe, "gem executable must exist" - exe = File.join gemdir, 'bin', 'executable' + exe = File.join gemdir, "bin", "executable" assert_path_exist exe - exe_mode = File.stat(exe).mode & 0111 - assert_equal 0111, exe_mode, "0%o" % exe_mode unless win_platform? + exe_mode = File.stat(exe).mode & 0o111 + assert_equal 0o111, exe_mode, format("0%o", exe_mode) unless Gem.win_platform? - assert_path_exist File.join gemdir, 'lib', 'code.rb' + assert_path_exist File.join gemdir, "lib", "code.rb" assert_path_exist rakefile @@ -998,7 +1067,7 @@ gem 'other', version installer.wrappers = true - gemdir = File.join @gemhome, 'gems', @spec.full_name + gemdir = File.join @gemhome, "gems", @spec.full_name @newspec = nil build_rake_in do @@ -1007,7 +1076,7 @@ gem 'other', version end end - exe = File.join gemdir, 'bin', 'executable' + exe = File.join gemdir, "bin", "executable" e = assert_raise RuntimeError do instance_eval File.read(exe) @@ -1020,11 +1089,11 @@ gem 'other', version @gem = setup_base_gem # build old version that has a bin file - installer = util_setup_gem do |spec| - File.open File.join('bin', 'executable'), 'w' do |f| + installer = util_setup_gem do |_spec| + File.open File.join("bin", "executable"), "w" do |f| f.puts "require 'code'" end - File.open File.join('lib', 'code.rb'), 'w' do |f| + File.open File.join("lib", "code.rb"), "w" do |f| f.puts 'raise "I have an executable"' end end @@ -1036,15 +1105,15 @@ gem 'other', version end end - old_bin_file = File.join installer.bin_dir, 'executable' + old_bin_file = File.join installer.bin_dir, "executable" # build new version that doesn't have a bin file installer = util_setup_gem do |spec| - FileUtils.rm File.join('bin', 'executable') - spec.files.delete File.join('bin', 'executable') - spec.executables.delete 'executable' + FileUtils.rm File.join("bin", "executable") + spec.files.delete File.join("bin", "executable") + spec.executables.delete "executable" spec.version = @spec.version.bump - File.open File.join('lib', 'code.rb'), 'w' do |f| + File.open File.join("lib", "code.rb"), "w" do |f| f.puts 'raise "I do not have an executable"' end end @@ -1061,7 +1130,7 @@ gem 'other', version # We expect the bin stub to activate the version that actually contains # the binstub. - assert_match('I have an executable', e.message) + assert_match("I have an executable", e.message) end def test_install_creates_binstub_that_understand_version @@ -1076,7 +1145,7 @@ gem 'other', version end end - exe = File.join @gemhome, 'bin', 'executable' + exe = File.join @gemhome, "bin", "executable" ARGV.unshift "_3.0_" @@ -1094,17 +1163,17 @@ gem 'other', version end def test_install_creates_binstub_that_prefers_user_installed_gem_to_default - default_spec = new_default_spec('default', '2', nil, 'exe/executable') - default_spec.executables = 'executable' + default_spec = new_default_spec("default", "2", nil, "exe/executable") + default_spec.executables = "executable" install_default_gems default_spec - exe = File.join @gemhome, 'bin', 'executable' + exe = File.join @gemhome, "bin", "executable" assert_path_exist exe, "default gem's executable not installed" installer = util_setup_installer do |spec| - spec.name = 'default' - spec.version = '2' + spec.name = "default" + spec.version = "2" end util_clear_gems @@ -1137,7 +1206,7 @@ gem 'other', version end end - exe = File.join @gemhome, 'bin', 'executable' + exe = File.join @gemhome, "bin", "executable" extra_arg = "\xE4pfel".dup.force_encoding("UTF-8") ARGV.unshift extra_arg @@ -1164,16 +1233,16 @@ gem 'other', version end end - gemdir = File.join(@gemhome, 'gems', @spec.full_name) - assert_path_exist File.join gemdir, 'lib', 'code.rb' + gemdir = File.join(@gemhome, "gems", @spec.full_name) + assert_path_exist File.join gemdir, "lib", "code.rb" installer = util_setup_installer # Morph spec to have lib/other.rb instead of code.rb and recreate - @spec.files = File.join('lib', 'other.rb') + @spec.files = File.join("lib", "other.rb") Dir.chdir @tempdir do - File.open File.join('lib', 'other.rb'), 'w' do |f| - f.puts '1' + File.open File.join("lib", "other.rb"), "w" do |f| + f.puts "1" end use_ui ui do @@ -1181,62 +1250,84 @@ gem 'other', version Gem::Package.build @spec end end - installer = Gem::Installer.at @gem, :force => true + installer = Gem::Installer.at @gem, force: true build_rake_in do use_ui @ui do assert_equal @spec, installer.install end end - assert_path_exist File.join gemdir, 'lib', 'other.rb' - assert_path_not_exist File.join gemdir, 'lib', 'code.rb', + assert_path_exist File.join gemdir, "lib", "other.rb" + assert_path_not_exist File.join gemdir, "lib", "code.rb", "code.rb from prior install of same gem shouldn't remain here" end def test_install_force - _, missing_dep_gem = util_gem 'missing_dep', '1' do |s| - s.add_dependency 'doesnt_exist', '1' + _, missing_dep_gem = util_gem "missing_dep", "1" do |s| + s.add_dependency "doesnt_exist", "1" end use_ui @ui do - installer = Gem::Installer.at missing_dep_gem, :force => true + installer = Gem::Installer.at missing_dep_gem, force: true installer.install end - gem_dir = File.join(@gemhome, 'gems', 'missing_dep-1') + gem_dir = File.join(@gemhome, "gems", "missing_dep-1") assert_path_exist gem_dir end def test_install_build_root - build_root = File.join(@tempdir, 'build_root') + build_root = File.join(@tempdir, "build_root") @gem = setup_base_gem - installer = Gem::Installer.at @gem, :build_root => build_root + installer = Gem::Installer.at @gem, build_root: build_root assert_equal @spec, installer.install end + def test_install_build_root_when_gem_home_not_writable_does_not_fallback_to_user_install_inside_build_root + build_root = File.join(@tempdir, "build_root") + + orig_gem_home = ENV.delete("GEM_HOME") + + @gem = setup_base_gem + + FileUtils.chmod "-w", @gemhome + + installer = Gem::Installer.at @gem, build_root: build_root + + assert_equal @spec, installer.install + + build_root_path = File.join(build_root, @gemhome.gsub(/^[a-zA-Z]:/, "")) + assert File.exist?(build_root_path), "gem not written to build_root" + ensure + FileUtils.chmod "+w", @gemhome + ENV["GEM_HOME"] = orig_gem_home + end + def test_install_missing_dirs installer = setup_base_installer - FileUtils.rm_f File.join(Gem.dir, 'cache') - FileUtils.rm_f File.join(Gem.dir, 'doc') - FileUtils.rm_f File.join(Gem.dir, 'specifications') + FileUtils.rm_rf File.join(Gem.dir, "doc") + FileUtils.rm_rf File.join(Gem.dir, "specifications") use_ui @ui do installer.install end - assert_directory_exists File.join(Gem.dir, 'cache') - assert_directory_exists File.join(Gem.dir, 'doc') - assert_directory_exists File.join(Gem.dir, 'specifications') + assert_directory_exists File.join(Gem.dir, "doc") + assert_directory_exists File.join(Gem.dir, "specifications") - assert_path_exist File.join @gemhome, 'cache', @spec.file_name - assert_path_exist File.join @gemhome, 'specifications', @spec.spec_name + assert_path_exist File.join @gemhome, "cache", @spec.file_name + assert_path_exist File.join @gemhome, "specifications", @spec.spec_name end def test_install_post_build_false - installer = setup_base_installer + @spec = util_spec "a" + + util_build_gem @spec + + installer = util_installer @spec, @gemhome Gem.post_build do false @@ -1252,10 +1343,10 @@ gem 'other', version assert_equal "post-build hook at #{location} failed for a-2", e.message end - spec_file = File.join @gemhome, 'specifications', @spec.spec_name + spec_file = File.join @gemhome, "specifications", @spec.spec_name assert_path_not_exist spec_file - gem_dir = File.join @gemhome, 'gems', @spec.full_name + gem_dir = File.join @gemhome, "gems", @spec.full_name assert_path_not_exist gem_dir end @@ -1270,15 +1361,19 @@ gem 'other', version installer.install end - spec_file = File.join @gemhome, 'specifications', @spec.spec_name + spec_file = File.join @gemhome, "specifications", @spec.spec_name assert_path_exist spec_file - gem_dir = File.join @gemhome, 'gems', @spec.full_name + gem_dir = File.join @gemhome, "gems", @spec.full_name assert_path_exist gem_dir end def test_install_pre_install_false - installer = setup_base_installer + @spec = util_spec "a" + + util_build_gem @spec + + installer = util_installer @spec, @gemhome Gem.pre_install do false @@ -1294,7 +1389,7 @@ gem 'other', version assert_equal "pre-install hook at #{location} failed for a-2", e.message end - spec_file = File.join @gemhome, 'specifications', @spec.spec_name + spec_file = File.join @gemhome, "specifications", @spec.spec_name assert_path_not_exist spec_file end @@ -1309,13 +1404,13 @@ gem 'other', version installer.install end - spec_file = File.join @gemhome, 'specifications', @spec.spec_name + spec_file = File.join @gemhome, "specifications", @spec.spec_name assert_path_exist spec_file end def test_install_with_message @spec = setup_base_spec - @spec.post_install_message = 'I am a shiny gem!' + @spec.post_install_message = "I am a shiny gem!" use_ui @ui do path = Gem::Package.build @spec @@ -1324,21 +1419,21 @@ gem 'other', version installer.install end - assert_match %r{I am a shiny gem!}, @ui.output + assert_match(/I am a shiny gem!/, @ui.output) end def test_install_with_skipped_message @spec = setup_base_spec - @spec.post_install_message = 'I am a shiny gem!' + @spec.post_install_message = "I am a shiny gem!" use_ui @ui do path = Gem::Package.build @spec - installer = Gem::Installer.at path, :post_install_message => false + installer = Gem::Installer.at path, post_install_message: false installer.install end - refute_match %r{I am a shiny gem!}, @ui.output + refute_match(/I am a shiny gem!/, @ui.output) end def test_install_extension_dir @@ -1358,11 +1453,11 @@ gem 'other', version use_ui @ui do path = Gem::Package.build @spec - installer = Gem::Installer.at path, :install_dir => gemhome2 + installer = Gem::Installer.at path, install_dir: gemhome2 installer.install end - expected_makefile = File.join gemhome2, 'gems', @spec.full_name, 'Makefile' + expected_makefile = File.join gemhome2, "gems", @spec.full_name, "Makefile" assert_path_exist expected_makefile end @@ -1397,7 +1492,7 @@ gem 'other', version # reinstall the gem, this is also the same as pristine use_ui @ui do - installer = Gem::Installer.at path, :force => true + installer = Gem::Installer.at path, force: true installer.install end @@ -1423,19 +1518,19 @@ gem 'other', version use_ui @ui do path = Gem::Package.build @spec - installer = Gem::Installer.at path, :user_install => true + installer = Gem::Installer.at path, user_install: true installer.install end - expected_makefile = File.join Gem.user_dir, 'gems', @spec.full_name, 'Makefile' + expected_makefile = File.join Gem.user_dir, "gems", @spec.full_name, "Makefile" assert_path_exist expected_makefile assert_path_exist expected_extension_dir - assert_path_not_exist File.join expected_extension_dir, 'gem_make.out' + assert_path_not_exist File.join expected_extension_dir, "gem_make.out" end def test_find_lib_file_after_install - skip "extensions don't quite work on jruby" if Gem.java_platform? + pend "extensions don't quite work on jruby" if Gem.java_platform? @spec = setup_base_spec @spec.extensions << "extconf.rb" @@ -1461,7 +1556,7 @@ gem 'other', version end Dir.mkdir File.join(@tempdir, "lib") - write_file File.join(@tempdir, 'lib', "b.rb") do |io| + write_file File.join(@tempdir, "lib", "b.rb") do |io| io.write "# b.rb" end @@ -1475,14 +1570,14 @@ gem 'other', version end expected = File.join @spec.full_require_paths.find {|path| - File.exist? File.join path, 'b.rb' - }, 'b.rb' - assert_equal expected, @spec.matches_for_glob('b.rb').first + File.exist? File.join path, "b.rb" + }, "b.rb" + assert_equal expected, @spec.matches_for_glob("b.rb").first end def test_install_extension_and_script - skip "Makefile creation crashes on jruby" if Gem.java_platform? - skip if /mswin/ =~ RUBY_PLATFORM && ENV.key?('GITHUB_ACTIONS') # not working from the beginning + pend "Makefile creation crashes on jruby" if Gem.java_platform? + pend "terminates on mswin" if vc_windows? && ruby_repo? @spec = setup_base_spec @spec.extensions << "extconf.rb" @@ -1523,7 +1618,7 @@ gem 'other', version end def test_install_extension_flat - skip "extensions don't quite work on jruby" if Gem.java_platform? + pend "extensions don't quite work on jruby" if Gem.java_platform? begin @spec = setup_base_spec @@ -1548,7 +1643,7 @@ gem 'other', version write_file File.join(@tempdir, file) end - so = File.join(@spec.gem_dir, "#{@spec.name}.#{RbConfig::CONFIG["DLEXT"]}") + so = File.join(@spec.extension_dir, "#{@spec.name}.#{RbConfig::CONFIG["DLEXT"]}") assert_path_not_exist so use_ui @ui do path = Gem::Package.build @spec @@ -1557,31 +1652,53 @@ gem 'other', version installer.install end assert_path_exist so - rescue - puts '-' * 78 - puts File.read File.join(@gemhome, 'gems', 'a-2', 'Makefile') - puts '-' * 78 + end + end - path = File.join(@gemhome, 'gems', 'a-2', 'gem_make.out') + def test_install_extension_clean_intermediate_files + pend "extensions don't quite work on jruby" if Gem.java_platform? + @spec = setup_base_spec + @spec.require_paths = ["."] + @spec.extensions << "extconf.rb" - if File.exist?(path) - puts File.read(path) - puts '-' * 78 - end + File.write File.join(@tempdir, "extconf.rb"), <<-RUBY + require "mkmf" + CONFIG['CC'] = '$(TOUCH) $@ ||' + CONFIG['LDSHARED'] = '$(TOUCH) $@ ||' + $ruby = '#{Gem.ruby}' + create_makefile("#{@spec.name}") + RUBY - raise + # empty depend file for no auto dependencies + @spec.files += %W[depend #{@spec.name}.c].each do |file| + write_file File.join(@tempdir, file) end + + shared_object = "#{@spec.name}.#{RbConfig::CONFIG["DLEXT"]}" + extension_file = File.join @spec.extension_dir, shared_object + intermediate_file = File.join @spec.gem_dir, shared_object + + assert_path_not_exist extension_file, "no before installing" + use_ui @ui do + path = Gem::Package.build @spec + + installer = Gem::Installer.at path + installer.install + end + + assert_path_exist extension_file, "installed" + assert_path_not_exist intermediate_file end def test_installation_satisfies_dependency_eh installer = setup_base_installer - util_spec 'a' + util_spec "a" - dep = Gem::Dependency.new 'a', '>= 2' + dep = Gem::Dependency.new "a", ">= 2" assert installer.installation_satisfies_dependency?(dep) - dep = Gem::Dependency.new 'a', '> 2' + dep = Gem::Dependency.new "a", "> 2" refute installer.installation_satisfies_dependency?(dep) end @@ -1590,15 +1707,15 @@ gem 'other', version installer.options[:development] = true installer.options[:dev_shallow] = true - util_spec 'a' + util_spec "a" - dep = Gem::Dependency.new 'a', :development + dep = Gem::Dependency.new "a", :development assert installer.installation_satisfies_dependency?(dep) end def test_pre_install_checks_dependencies installer = setup_base_installer - @spec.add_dependency 'b', '> 5' + @spec.add_dependency "b", "> 5" installer = util_setup_gem installer.force = false @@ -1611,7 +1728,7 @@ gem 'other', version def test_pre_install_checks_dependencies_ignore installer = util_setup_installer - @spec.add_dependency 'b', '> 5' + @spec.add_dependency "b", "> 5" installer.ignore_dependencies = true build_rake_in do @@ -1625,22 +1742,22 @@ gem 'other', version gemhome2 = "#{@gemhome}2" @gem = setup_base_gem - @spec.add_dependency 'd' + @spec.add_dependency "d" - quick_gem 'd', 2 + quick_gem "d", 2 gem = File.join @gemhome, @spec.file_name FileUtils.mv @gemhome, gemhome2 FileUtils.mkdir @gemhome - FileUtils.mv File.join(gemhome2, 'cache', @spec.file_name), gem + FileUtils.mv File.join(gemhome2, "cache", @spec.file_name), gem # Don't leak any already activated gems into the installer, require # that it work everything out on it's own. Gem::Specification.reset - installer = Gem::Installer.at gem, :install_dir => gemhome2 + installer = Gem::Installer.at gem, install_dir: gemhome2 build_rake_in do use_ui @ui do @@ -1650,35 +1767,37 @@ gem 'other', version end def test_pre_install_checks_malicious_name - spec = util_spec '../malicious', '1' + spec = util_spec "../malicious", "1" def spec.full_name # so the spec is buildable "malicious-1" end + def spec.validate(packaging, strict); end util_build_gem spec - gem = File.join(@gemhome, 'cache', spec.file_name) + gem = File.join(@gemhome, "cache", spec.file_name) use_ui @ui do installer = Gem::Installer.at gem e = assert_raise Gem::InstallError do installer.pre_install_checks end - assert_equal '#<Gem::Specification name=../malicious version=1> has an invalid name', e.message + assert_equal "#<Gem::Specification name=../malicious version=1> has an invalid name", e.message end end def test_pre_install_checks_malicious_name_before_eval - spec = util_spec "malicious\n::Object.const_set(:FROM_EVAL, true)#", '1' + spec = util_spec "malicious\n::Object.const_set(:FROM_EVAL, true)#", "1" def spec.full_name # so the spec is buildable "malicious-1" end + def spec.validate(*args); end util_build_gem spec - gem = File.join(@gemhome, 'cache', spec.file_name) + gem = File.join(@gemhome, "cache", spec.file_name) use_ui @ui do installer = Gem::Installer.at gem @@ -1691,16 +1810,17 @@ gem 'other', version end def test_pre_install_checks_malicious_require_paths_before_eval - spec = util_spec "malicious", '1' + spec = util_spec "malicious", "1" def spec.full_name # so the spec is buildable "malicious-1" end + def spec.validate(*args); end spec.require_paths = ["malicious\n``"] util_build_gem spec - gem = File.join(@gemhome, 'cache', spec.file_name) + gem = File.join(@gemhome, "cache", spec.file_name) use_ui @ui do installer = Gem::Installer.at gem @@ -1712,18 +1832,19 @@ gem 'other', version end def test_pre_install_checks_malicious_extensions_before_eval - skip "mswin environment disallow to create file contained the carriage return code." if Gem.win_platform? + pend "mswin environment disallow to create file contained the carriage return code." if Gem.win_platform? - spec = util_spec "malicious", '1' + spec = util_spec "malicious", "1" def spec.full_name # so the spec is buildable "malicious-1" end + def spec.validate(*args); end spec.extensions = ["malicious\n``"] util_build_gem spec - gem = File.join(@gemhome, 'cache', spec.file_name) + gem = File.join(@gemhome, "cache", spec.file_name) use_ui @ui do installer = Gem::Installer.at gem @@ -1735,16 +1856,17 @@ gem 'other', version end def test_pre_install_checks_malicious_specification_version_before_eval - spec = util_spec "malicious", '1' + spec = util_spec "malicious", "1" def spec.full_name # so the spec is buildable "malicious-1" end + def spec.validate(*args); end spec.specification_version = "malicious\n``" util_build_gem spec - gem = File.join(@gemhome, 'cache', spec.file_name) + gem = File.join(@gemhome, "cache", spec.file_name) use_ui @ui do installer = Gem::Installer.at gem @@ -1756,16 +1878,17 @@ gem 'other', version end def test_pre_install_checks_malicious_dependencies_before_eval - spec = util_spec "malicious", '1' + spec = util_spec "malicious", "1" def spec.full_name # so the spec is buildable "malicious-1" end + def spec.validate(*args); end - spec.add_dependency "b\nfoo", '> 5' + spec.add_dependency "b\nfoo", "> 5" util_build_gem spec - gem = File.join(@gemhome, 'cache', spec.file_name) + gem = File.join(@gemhome, "cache", spec.file_name) use_ui @ui do installer = Gem::Installer.at gem @@ -1777,32 +1900,54 @@ gem 'other', version end end + def test_pre_install_checks_malicious_platform_before_eval + gem_with_ill_formated_platform = File.expand_path("packages/ill-formatted-platform-1.0.0.10.gem", __dir__) + + installer = Gem::Installer.at( + gem_with_ill_formated_platform, + install_dir: @gemhome, + user_install: false, + force: true + ) + + use_ui @ui do + e = assert_raise Gem::InstallError do + installer.pre_install_checks + end + + assert_equal "x86-mswin32\n system('id > /tmp/nyangawa')# is an invalid platform", e.message + assert_empty @ui.output + end + end + def test_shebang - installer = setup_base_installer + load_relative "no" do + installer = setup_base_installer - util_make_exec @spec, "#!/usr/bin/ruby" + util_make_exec @spec, "#!/usr/bin/ruby" - shebang = installer.shebang 'executable' + shebang = installer.shebang "executable" - assert_equal "#!#{Gem.ruby}", shebang + assert_equal "#!#{Gem.ruby}", shebang + end end def test_process_options installer = setup_base_installer assert_nil installer.build_root - assert_equal File.join(@gemhome, 'bin'), installer.bin_dir + assert_equal File.join(@gemhome, "bin"), installer.bin_dir assert_equal @gemhome, installer.gem_home end def test_process_options_build_root - build_root = File.join @tempdir, 'build_root' - bin_dir = File.join(build_root, @gemhome.gsub(/^[a-zA-Z]:/, ''), 'bin') - gem_home = File.join(build_root, @gemhome.gsub(/^[a-zA-Z]:/, '')) - plugins_dir = File.join(build_root, @gemhome.gsub(/^[a-zA-Z]:/, ''), 'plugins') + build_root = File.join @tempdir, "build_root" + bin_dir = File.join(build_root, @gemhome.gsub(/^[a-zA-Z]:/, ""), "bin") + gem_home = File.join(build_root, @gemhome.gsub(/^[a-zA-Z]:/, "")) + plugins_dir = File.join(build_root, @gemhome.gsub(/^[a-zA-Z]:/, ""), "plugins") @gem = setup_base_gem - installer = use_ui(@ui) { Gem::Installer.at @gem, :build_root => build_root } + installer = use_ui(@ui) { Gem::Installer.at @gem, build_root: build_root } assert_equal build_root, installer.build_root assert_equal bin_dir, installer.bin_dir @@ -1817,136 +1962,273 @@ gem 'other', version assert_equal " Plugins dir: #{plugins_dir}", errors.shift end + def test_process_options_fallback_to_user_install_when_gem_home_not_writable + if Process.uid.zero? + pend("skipped in root privilege") + return + end + + orig_gem_home = ENV.delete("GEM_HOME") + + @gem = setup_base_gem + + FileUtils.chmod 0o000, @gemhome + + installer = use_ui(@ui) { Gem::Installer.at @gem } + + assert_equal Gem.user_dir, installer.gem_home + assert_equal "Defaulting to user installation because default installation directory (#{@gemhome}) is not writable.", @ui.output.strip + ensure + FileUtils.chmod 0o755, @gemhome + ENV["GEM_HOME"] = orig_gem_home + end + + def test_process_options_does_not_fallback_to_user_install_when_gem_home_not_writable_and_no_user_install + if Process.uid.zero? + pend("skipped in root privilege") + return + end + + orig_gem_home = ENV.delete("GEM_HOME") + + @gem = setup_base_gem + + FileUtils.chmod 0o000, @gemhome + + installer = use_ui(@ui) { Gem::Installer.at @gem, user_install: false } + + assert_equal @gemhome, installer.gem_home + assert_empty @ui.output.strip + ensure + FileUtils.chmod 0o755, @gemhome + ENV["GEM_HOME"] = orig_gem_home + end + def test_shebang_arguments - installer = setup_base_installer + load_relative "no" do + installer = setup_base_installer - util_make_exec @spec, "#!/usr/bin/ruby -ws" + util_make_exec @spec, "#!/usr/bin/ruby -ws" - shebang = installer.shebang 'executable' + shebang = installer.shebang "executable" - assert_equal "#!#{Gem.ruby} -ws", shebang + assert_equal "#!#{Gem.ruby} -ws", shebang + end + end + + def test_shebang_arguments_with_load_relative + load_relative "yes" do + installer = setup_base_installer + + util_make_exec @spec, "#!/usr/bin/ruby -ws" + + shebang = installer.shebang "executable" + + shebang_lines = shebang.split "\n" + + assert_equal "#!/bin/sh", shebang_lines.shift + assert_includes shebang_lines, "#!#{Gem.ruby} -ws" + end end def test_shebang_empty - installer = setup_base_installer + load_relative "no" do + installer = setup_base_installer - util_make_exec @spec, '' + util_make_exec @spec, "" - shebang = installer.shebang 'executable' - assert_equal "#!#{Gem.ruby}", shebang + shebang = installer.shebang "executable" + assert_equal "#!#{Gem.ruby}", shebang + end end def test_shebang_env - installer = setup_base_installer + load_relative "no" do + installer = setup_base_installer - util_make_exec @spec, "#!/usr/bin/env ruby" + util_make_exec @spec, "#!/usr/bin/env ruby" - shebang = installer.shebang 'executable' + shebang = installer.shebang "executable" - assert_equal "#!#{Gem.ruby}", shebang + assert_equal "#!#{Gem.ruby}", shebang + end end def test_shebang_env_arguments - installer = setup_base_installer + load_relative "no" do + installer = setup_base_installer + + util_make_exec @spec, "#!/usr/bin/env ruby -ws" + + shebang = installer.shebang "executable" - util_make_exec @spec, "#!/usr/bin/env ruby -ws" + assert_equal "#!#{Gem.ruby} -ws", shebang + end + end + + def test_shebang_env_arguments_with_load_relative + load_relative "yes" do + installer = setup_base_installer + + util_make_exec @spec, "#!/usr/bin/env ruby -ws" - shebang = installer.shebang 'executable' + shebang = installer.shebang "executable" - assert_equal "#!#{Gem.ruby} -ws", shebang + shebang_lines = shebang.split "\n" + + assert_equal "#!/bin/sh", shebang_lines.shift + assert_includes shebang_lines, "#!#{Gem.ruby} -ws" + end end def test_shebang_env_shebang installer = setup_base_installer - util_make_exec @spec, '' + util_make_exec @spec, "" installer.env_shebang = true - shebang = installer.shebang 'executable' + shebang = installer.shebang "executable" bin_env = get_bin_env - assert_equal("#!#{bin_env} #{RbConfig::CONFIG['ruby_install_name']}", + assert_equal("#!#{bin_env} #{RbConfig::CONFIG["ruby_install_name"]}", shebang) end def test_shebang_nested - installer = setup_base_installer + load_relative "no" do + installer = setup_base_installer - util_make_exec @spec, "#!/opt/local/ruby/bin/ruby" + util_make_exec @spec, "#!/opt/local/ruby/bin/ruby" - shebang = installer.shebang 'executable' + shebang = installer.shebang "executable" - assert_equal "#!#{Gem.ruby}", shebang + assert_equal "#!#{Gem.ruby}", shebang + end end def test_shebang_nested_arguments - installer = setup_base_installer + load_relative "no" do + installer = setup_base_installer + + util_make_exec @spec, "#!/opt/local/ruby/bin/ruby -ws" + + shebang = installer.shebang "executable" + + assert_equal "#!#{Gem.ruby} -ws", shebang + end + end + + def test_shebang_nested_arguments_with_load_relative + load_relative "yes" do + installer = setup_base_installer - util_make_exec @spec, "#!/opt/local/ruby/bin/ruby -ws" + util_make_exec @spec, "#!/opt/local/ruby/bin/ruby -ws" - shebang = installer.shebang 'executable' + shebang = installer.shebang "executable" - assert_equal "#!#{Gem.ruby} -ws", shebang + shebang_lines = shebang.split "\n" + + assert_equal "#!/bin/sh", shebang_lines.shift + assert_includes shebang_lines, "#!#{Gem.ruby} -ws" + end end def test_shebang_version - installer = setup_base_installer + load_relative "no" do + installer = setup_base_installer - util_make_exec @spec, "#!/usr/bin/ruby18" + util_make_exec @spec, "#!/usr/bin/ruby18" - shebang = installer.shebang 'executable' + shebang = installer.shebang "executable" - assert_equal "#!#{Gem.ruby}", shebang + assert_equal "#!#{Gem.ruby}", shebang + end end def test_shebang_version_arguments - installer = setup_base_installer + load_relative "no" do + installer = setup_base_installer - util_make_exec @spec, "#!/usr/bin/ruby18 -ws" + util_make_exec @spec, "#!/usr/bin/ruby18 -ws" - shebang = installer.shebang 'executable' + shebang = installer.shebang "executable" - assert_equal "#!#{Gem.ruby} -ws", shebang + assert_equal "#!#{Gem.ruby} -ws", shebang + end + end + + def test_shebang_version_arguments_with_load_relative + load_relative "yes" do + installer = setup_base_installer + + util_make_exec @spec, "#!/usr/bin/ruby18 -ws" + + shebang = installer.shebang "executable" + + shebang_lines = shebang.split "\n" + + assert_equal "#!/bin/sh", shebang_lines.shift + assert_includes shebang_lines, "#!#{Gem.ruby} -ws" + end end def test_shebang_version_env - installer = setup_base_installer + load_relative "no" do + installer = setup_base_installer - util_make_exec @spec, "#!/usr/bin/env ruby18" + util_make_exec @spec, "#!/usr/bin/env ruby18" - shebang = installer.shebang 'executable' + shebang = installer.shebang "executable" - assert_equal "#!#{Gem.ruby}", shebang + assert_equal "#!#{Gem.ruby}", shebang + end end def test_shebang_version_env_arguments - installer = setup_base_installer + load_relative "no" do + installer = setup_base_installer - util_make_exec @spec, "#!/usr/bin/env ruby18 -ws" + util_make_exec @spec, "#!/usr/bin/env ruby18 -ws" - shebang = installer.shebang 'executable' + shebang = installer.shebang "executable" - assert_equal "#!#{Gem.ruby} -ws", shebang + assert_equal "#!#{Gem.ruby} -ws", shebang + end + end + + def test_shebang_version_env_arguments_with_load_relative + load_relative "yes" do + installer = setup_base_installer + + util_make_exec @spec, "#!/usr/bin/env ruby18 -ws" + + shebang = installer.shebang "executable" + + shebang_lines = shebang.split "\n" + + assert_equal "#!/bin/sh", shebang_lines.shift + assert_includes shebang_lines, "#!#{Gem.ruby} -ws" + end end def test_shebang_custom installer = setup_base_installer conf = Gem::ConfigFile.new [] - conf[:custom_shebang] = 'test' + conf[:custom_shebang] = "test" Gem.configuration = conf util_make_exec @spec, "#!/usr/bin/ruby" - shebang = installer.shebang 'executable' + shebang = installer.shebang "executable" assert_equal "#!test", shebang end def get_bin_env - if win_platform? + if Gem.win_platform? "" else %w[/usr/bin/env /bin/env].find {|f| File.executable?(f) } @@ -1958,13 +2240,13 @@ gem 'other', version bin_env = get_bin_env conf = Gem::ConfigFile.new [] - conf[:custom_shebang] = '1 $env 2 $ruby 3 $exec 4 $name' + 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' + shebang = installer.shebang "executable" assert_equal "#!1 #{bin_env} 2 #{Gem.ruby} 3 executable 4 a", shebang end @@ -1974,13 +2256,13 @@ gem 'other', version bin_env = get_bin_env conf = Gem::ConfigFile.new [] - conf[:custom_shebang] = '1 $env 2 $ruby 3 $exec' + conf[:custom_shebang] = "1 $env 2 $ruby 3 $exec" Gem.configuration = conf util_make_exec @spec, "#!/usr/bin/ruby -ws" - shebang = installer.shebang 'executable' + shebang = installer.shebang "executable" assert_equal "#!1 #{bin_env} 2 #{Gem.ruby} -ws 3 executable", shebang end @@ -1988,14 +2270,14 @@ gem 'other', version def test_unpack installer = util_setup_installer - dest = File.join @gemhome, 'gems', @spec.full_name + dest = File.join @gemhome, "gems", @spec.full_name Gem::Deprecate.skip_during do installer.unpack dest end - assert_path_exist File.join dest, 'lib', 'code.rb' - assert_path_exist File.join dest, 'bin', 'executable' + assert_path_exist File.join dest, "lib", "code.rb" + assert_path_exist File.join dest, "bin", "executable" end def test_write_build_info_file @@ -2028,7 +2310,7 @@ gem 'other', version def test_write_build_info_file_install_dir @gem = setup_base_gem - installer = Gem::Installer.at @gem, :install_dir => "#{@gemhome}2" + installer = Gem::Installer.at @gem, install_dir: "#{@gemhome}2" installer.build_args = %w[ --with-libyaml-dir /usr/local/Cellar/libyaml/0.1.4 @@ -2038,12 +2320,12 @@ gem 'other', version assert_path_not_exist @spec.build_info_file assert_path_exist \ - File.join("#{@gemhome}2", 'build_info', "#{@spec.full_name}.info") + File.join("#{@gemhome}2", "build_info", "#{@spec.full_name}.info") end def test_write_cache_file @gem = setup_base_gem - cache_file = File.join @gemhome, 'cache', @spec.file_name + cache_file = File.join @gemhome, "cache", @spec.file_name gem = File.join @gemhome, @spec.file_name FileUtils.mv cache_file, gem @@ -2094,6 +2376,37 @@ gem 'other', version assert_equal @spec, eval(File.read(@spec.spec_file)) end + def test_leaves_no_empty_cached_spec_when_no_more_disk_space + @spec = setup_base_spec + FileUtils.rm @spec.spec_file + assert_path_not_exist @spec.spec_file + + @spec.files = %w[a.rb b.rb c.rb] + + installer = Gem::Installer.for_spec @spec + installer.gem_home = @gemhome + + File.class_eval do + alias_method :original_write, :write + + def write(data) + raise Errno::ENOSPC + end + end + + assert_raise Errno::ENOSPC do + installer.write_spec + end + + assert_path_not_exist @spec.spec_file + ensure + File.class_eval do + remove_method :write + alias_method :write, :original_write + remove_method :original_write + end + end + def test_dir installer = setup_base_installer @@ -2101,8 +2414,8 @@ gem 'other', version end def test_default_gem_loaded_from - spec = util_spec 'a' - installer = Gem::Installer.for_spec spec, :install_as_default => true + spec = util_spec "a" + installer = Gem::Installer.for_spec spec, install_as_default: true installer.install assert_predicate spec, :default_gem? end @@ -2110,7 +2423,7 @@ gem 'other', version def test_default_gem_without_wrappers installer = setup_base_installer - FileUtils.rm_f File.join(Gem.dir, 'specifications') + FileUtils.rm_rf File.join(Gem.default_dir, "specifications") installer.wrappers = false installer.options[:install_as_default] = true @@ -2120,29 +2433,29 @@ gem 'other', version installer.install end - assert_directory_exists File.join(@spec.gem_dir, 'bin') - installed_exec = File.join @spec.gem_dir, 'bin', 'executable' + assert_directory_exists File.join(@spec.gem_dir, "bin") + installed_exec = File.join @spec.gem_dir, "bin", "executable" assert_path_exist installed_exec - assert_directory_exists File.join(Gem.default_dir, 'specifications') - assert_directory_exists File.join(Gem.default_dir, 'specifications', 'default') + assert_directory_exists File.join(Gem.default_dir, "specifications") + assert_directory_exists File.join(Gem.default_dir, "specifications", "default") - default_spec = eval File.read File.join(Gem.default_dir, 'specifications', 'default', 'a-2.gemspec') + default_spec = eval File.read File.join(Gem.default_dir, "specifications", "default", "a-2.gemspec") assert_equal Gem::Version.new("2"), default_spec.version - assert_equal ['bin/executable'], default_spec.files + assert_equal ["bin/executable"], default_spec.files assert_directory_exists util_inst_bindir - installed_exec = File.join util_inst_bindir, 'executable' + installed_exec = File.join util_inst_bindir, "executable" assert_path_exist installed_exec wrapper = File.read installed_exec if symlink_supported? - refute_match %r{generated by RubyGems}, wrapper + refute_match(/generated by RubyGems/, wrapper) else # when symlink not supported, it warns and fallbacks back to installing wrapper - assert_match %r{Unable to use symlinks, installing wrapper}, @ui.error - assert_match %r{generated by RubyGems}, wrapper + assert_match(/Unable to use symlinks, installing wrapper/, @ui.error) + assert_match(/generated by RubyGems/, wrapper) end end @@ -2159,16 +2472,16 @@ gem 'other', version assert_directory_exists util_inst_bindir - installed_exec = File.join util_inst_bindir, 'executable' + installed_exec = File.join util_inst_bindir, "executable" assert_path_exist installed_exec wrapper = File.read installed_exec - assert_match %r{generated by RubyGems}, wrapper + assert_match(/generated by RubyGems/, wrapper) end def test_default_gem_with_exe_as_bindir - @spec = quick_gem 'c' do |spec| - util_make_exec spec, '#!/usr/bin/ruby', 'exe' + @spec = quick_gem "c" do |spec| + util_make_exec spec, "#!/usr/bin/ruby", "exe" end util_build_gem @spec @@ -2184,16 +2497,16 @@ gem 'other', version installer.install end - assert_directory_exists File.join(@spec.gem_dir, 'exe') - installed_exec = File.join @spec.gem_dir, 'exe', 'executable' + assert_directory_exists File.join(@spec.gem_dir, "exe") + installed_exec = File.join @spec.gem_dir, "exe", "executable" assert_path_exist installed_exec - assert_directory_exists File.join(Gem.default_dir, 'specifications') - assert_directory_exists File.join(Gem.default_dir, 'specifications', 'default') + assert_directory_exists File.join(Gem.default_dir, "specifications") + assert_directory_exists File.join(Gem.default_dir, "specifications", "default") - default_spec = eval File.read File.join(Gem.default_dir, 'specifications', 'default', 'c-2.gemspec') + default_spec = eval File.read File.join(Gem.default_dir, "specifications", "default", "c-2.gemspec") assert_equal Gem::Version.new("2"), default_spec.version - assert_equal ['exe/executable'], default_spec.files + assert_equal ["exe/executable"], default_spec.files end def test_default_gem_to_specific_install_dir @@ -2205,17 +2518,17 @@ gem 'other', version installer.install end - assert_directory_exists File.join("#{@gemhome}2", 'specifications') - assert_directory_exists File.join("#{@gemhome}2", 'specifications', 'default') + assert_directory_exists File.join("#{@gemhome}2", "specifications") + assert_directory_exists File.join("#{@gemhome}2", "specifications", "default") - default_spec = eval File.read File.join("#{@gemhome}2", 'specifications', 'default', 'a-2.gemspec') + default_spec = eval File.read File.join("#{@gemhome}2", "specifications", "default", "a-2.gemspec") assert_equal Gem::Version.new("2"), default_spec.version - assert_equal ['bin/executable'], default_spec.files + assert_equal ["bin/executable"], default_spec.files end def test_package_attribute - gem = quick_gem 'c' do |spec| - util_make_exec spec, '#!/usr/bin/ruby', 'exe' + gem = quick_gem "c" do |spec| + util_make_exec spec, "#!/usr/bin/ruby", "exe" end installer = util_installer(gem, @gemhome) @@ -2224,8 +2537,8 @@ gem 'other', version end def test_gem_attribute - gem = quick_gem 'c' do |spec| - util_make_exec spec, '#!/usr/bin/ruby', 'exe' + gem = quick_gem "c" do |spec| + util_make_exec spec, "#!/usr/bin/ruby", "exe" end installer = util_installer(gem, @gemhome) @@ -2233,15 +2546,17 @@ gem 'other', version assert_kind_of(String, installer.gem) end + private + def util_execless - @spec = util_spec 'z' + @spec = util_spec "z" util_build_gem @spec util_installer @spec, @gemhome end def util_conflict_executable(wrappers) - conflict = quick_gem 'conflict' do |spec| + conflict = quick_gem "conflict" do |spec| util_make_exec spec end @@ -2253,6 +2568,15 @@ gem 'other', version end def mask - 0100755 + 0o100755 + end + + def load_relative(value) + orig_libruby_relative = RbConfig::CONFIG["LIBRUBY_RELATIVE"] + RbConfig::CONFIG["LIBRUBY_RELATIVE"] = value + + yield + ensure + RbConfig::CONFIG["LIBRUBY_RELATIVE"] = orig_libruby_relative end end diff --git a/test/rubygems/test_gem_local_remote_options.rb b/test/rubygems/test_gem_local_remote_options.rb index 2373bbde1f..cea9cde82b 100644 --- a/test/rubygems/test_gem_local_remote_options.rb +++ b/test/rubygems/test_gem_local_remote_options.rb @@ -1,13 +1,14 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/local_remote_options' -require 'rubygems/command' + +require_relative "helper" +require "rubygems/local_remote_options" +require "rubygems/command" class TestGemLocalRemoteOptions < Gem::TestCase def setup super - @cmd = Gem::Command.new 'dummy', 'dummy' + @cmd = Gem::Command.new "dummy", "dummy" @cmd.extend Gem::LocalRemoteOptions end @@ -33,7 +34,7 @@ class TestGemLocalRemoteOptions < Gem::TestCase def test_clear_sources_option @cmd.add_local_remote_options - s = URI.parse "http://only-gems.example.com/" + s = Gem::URI.parse "http://only-gems.example.com/" @cmd.handle_options %W[--clear-sources --source #{s}] assert_equal [s.to_s], Gem.sources @@ -75,10 +76,10 @@ class TestGemLocalRemoteOptions < Gem::TestCase def test_source_option @cmd.add_source_option - s1 = URI.parse 'http://more-gems.example.com/' - s2 = URI.parse 'http://even-more-gems.example.com/' - s3 = URI.parse 'http://other-gems.example.com/some_subdir' - s4 = URI.parse 'http://more-gems.example.com/' # Intentional duplicate + s1 = Gem::URI.parse "http://more-gems.example.com/" + s2 = Gem::URI.parse "http://even-more-gems.example.com/" + s3 = Gem::URI.parse "http://other-gems.example.com/some_subdir" + s4 = Gem::URI.parse "http://more-gems.example.com/" # Intentional duplicate original_sources = Gem.sources.dup @@ -96,7 +97,7 @@ class TestGemLocalRemoteOptions < Gem::TestCase original_sources = Gem.sources.dup - source = URI.parse 'http://more-gems.example.com/' + source = Gem::URI.parse "http://more-gems.example.com/" @cmd.handle_options %W[-s #{source}] original_sources << source @@ -121,7 +122,7 @@ class TestGemLocalRemoteOptions < Gem::TestCase def test_source_option_bad @cmd.add_source_option - s1 = 'htp://more-gems.example.com' + s1 = "htp://more-gems.example.com" assert_raise ArgumentError do @cmd.handle_options %W[--source #{s1}] diff --git a/test/rubygems/test_gem_name_tuple.rb b/test/rubygems/test_gem_name_tuple.rb index 92cfe6c1d2..bdb8181ce8 100644 --- a/test/rubygems/test_gem_name_tuple.rb +++ b/test/rubygems/test_gem_name_tuple.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/name_tuple' + +require_relative "helper" +require "rubygems/name_tuple" class TestGemNameTuple < Gem::TestCase def test_full_name @@ -18,14 +19,31 @@ class TestGemNameTuple < Gem::TestCase end def test_platform_normalization - n = Gem::NameTuple.new "a", Gem::Version.new(0), "ruby" - assert_equal "ruby", n.platform - - n = Gem::NameTuple.new "a", Gem::Version.new(0), nil - assert_equal "ruby", n.platform - - n = Gem::NameTuple.new "a", Gem::Version.new(0), "" - assert_equal "ruby", n.platform + a = Gem::NameTuple.new "a", Gem::Version.new(0), "ruby" + b = Gem::NameTuple.new "a", Gem::Version.new(0), Gem::Platform::RUBY + assert_equal a, b + assert_equal a.hash, b.hash + + a = Gem::NameTuple.new "a", Gem::Version.new(0), nil + b = Gem::NameTuple.new "a", Gem::Version.new(0), Gem::Platform.new("ruby") + assert_equal a, b + assert_equal a.hash, b.hash + + a = Gem::NameTuple.new "a", Gem::Version.new(0), "" + b = Gem::NameTuple.new "a", Gem::Version.new(0), Gem::Platform.new("ruby") + assert_equal a, b + assert_equal a.hash, b.hash + + a = Gem::NameTuple.new "a", Gem::Version.new(0), "universal-darwin-23" + b = Gem::NameTuple.new "a", Gem::Version.new(0), Gem::Platform.new("universal-darwin-23") + assert_equal a, b + assert_equal a.hash, b.hash + + # Gem::Platform does normalization so that these are equal (note the missing dash before 21) + a = Gem::NameTuple.new "a", Gem::Version.new(0), "universal-darwin-21" + b = Gem::NameTuple.new "a", Gem::Version.new(0), Gem::Platform.new("universal-darwin21") + assert_equal a, b + assert_equal a.hash, b.hash end def test_spec_name @@ -34,8 +52,8 @@ class TestGemNameTuple < Gem::TestCase end def test_spaceship - a = Gem::NameTuple.new 'a', Gem::Version.new(0), Gem::Platform::RUBY - a_p = Gem::NameTuple.new 'a', Gem::Version.new(0), Gem::Platform.local + a = Gem::NameTuple.new "a", Gem::Version.new(0), Gem::Platform::RUBY + a_p = Gem::NameTuple.new "a", Gem::Version.new(0), Gem::Platform.local assert_equal 1, a_p.<=>(a) end diff --git a/test/rubygems/test_gem_package.rb b/test/rubygems/test_gem_package.rb index 8f2f50c578..2065864107 100644 --- a/test/rubygems/test_gem_package.rb +++ b/test/rubygems/test_gem_package.rb @@ -1,14 +1,14 @@ # frozen_string_literal: true -require 'rubygems/package/tar_test_case' -require 'digest' +require_relative "package/tar_test_case" +require "rubygems/openssl" class TestGemPackage < Gem::Package::TarTestCase def setup super - @spec = quick_gem 'a' do |s| - s.description = 'π' + @spec = quick_gem "a" do |s| + s.description = "π" s.files = %w[lib/code.rb] end @@ -16,19 +16,19 @@ class TestGemPackage < Gem::Package::TarTestCase @gem = @spec.cache_file - @destination = File.join @tempdir, 'extract' + @destination = File.join @tempdir, "extract" FileUtils.mkdir_p @destination end def test_class_new_old_format - skip "jruby can't require the simple_gem file" if Gem.java_platform? + pend "jruby can't require the simple_gem file" if Gem.java_platform? require_relative "simple_gem" - File.open 'old_format.gem', 'wb' do |io| + File.open "old_format.gem", "wb" do |io| io.write SIMPLE_GEM end - package = Gem::Package.new 'old_format.gem' + package = Gem::Package.new "old_format.gem" assert package.spec end @@ -36,17 +36,17 @@ class TestGemPackage < Gem::Package::TarTestCase 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 = 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' + spec.rubygems_version = Gem::Version.new "0" - FileUtils.mkdir 'lib' + FileUtils.mkdir "lib" - File.open 'lib/code.rb', 'w' do |io| - io.write '# lib/code.rb' + File.open "lib/code.rb", "w" do |io| + io.write "# lib/code.rb" end package = Gem::Package.new spec.file_name @@ -69,11 +69,11 @@ class TestGemPackage < Gem::Package::TarTestCase reader.each_entry do |entry| case entry.full_name - when 'checksums.yaml.gz' then + when "checksums.yaml.gz" then Zlib::GzipReader.wrap entry do |io| checksums = io.read end - when 'data.tar.gz' then + when "data.tar.gz" then tar = entry.read end end @@ -84,33 +84,33 @@ class TestGemPackage < Gem::Package::TarTestCase io.write spec.to_yaml end - metadata_sha256 = Digest::SHA256.hexdigest s.string - metadata_sha512 = Digest::SHA512.hexdigest s.string + metadata_sha256 = OpenSSL::Digest::SHA256.hexdigest s.string + metadata_sha512 = OpenSSL::Digest::SHA512.hexdigest s.string expected = { - 'SHA512' => { - 'metadata.gz' => metadata_sha512, - 'data.tar.gz' => Digest::SHA512.hexdigest(tar), + "SHA512" => { + "metadata.gz" => metadata_sha512, + "data.tar.gz" => OpenSSL::Digest::SHA512.hexdigest(tar), }, - 'SHA256' => { - 'metadata.gz' => metadata_sha256, - 'data.tar.gz' => Digest::SHA256.hexdigest(tar), + "SHA256" => { + "metadata.gz" => metadata_sha256, + "data.tar.gz" => OpenSSL::Digest::SHA256.hexdigest(tar), }, } - assert_equal expected, YAML.load(checksums) + assert_equal expected, load_yaml(checksums) end def test_build_time_uses_source_date_epoch epoch = ENV["SOURCE_DATE_EPOCH"] ENV["SOURCE_DATE_EPOCH"] = "123456789" - spec = Gem::Specification.new 'build', '1' - spec.summary = 'build' - spec.authors = 'build' - spec.files = ['lib/code.rb'] + 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' + spec.rubygems_version = Gem::Version.new "0" package = Gem::Package.new spec.file_name @@ -123,11 +123,11 @@ class TestGemPackage < Gem::Package::TarTestCase epoch = ENV["SOURCE_DATE_EPOCH"] ENV["SOURCE_DATE_EPOCH"] = nil - spec = Gem::Specification.new 'build', '1' - spec.summary = 'build' - spec.authors = 'build' - spec.files = ['lib/code.rb'] - spec.rubygems_version = Gem::Version.new '0' + spec = Gem::Specification.new "build", "1" + spec.summary = "build" + spec.authors = "build" + spec.files = ["lib/code.rb"] + spec.rubygems_version = Gem::Version.new "0" package = Gem::Package.new spec.file_name @@ -144,17 +144,17 @@ class TestGemPackage < Gem::Package::TarTestCase spec = Gem::Specification.new spec.files = %w[lib/code.rb lib/empty] - FileUtils.mkdir_p 'lib/empty' + FileUtils.mkdir_p "lib/empty" - File.open 'lib/code.rb', 'w' do |io| - io.write '# lib/code.rb' + File.open "lib/code.rb", "w" do |io| + io.write "# lib/code.rb" end - File.open 'lib/extra.rb', 'w' do |io| - io.write '# lib/extra.rb' + File.open "lib/extra.rb", "w" do |io| + io.write "# lib/extra.rb" end - package = Gem::Package.new 'bogus.gem' + package = Gem::Package.new "bogus.gem" package.spec = spec tar = util_tar do |tar_io| @@ -178,25 +178,25 @@ class TestGemPackage < Gem::Package::TarTestCase spec = Gem::Specification.new spec.files = %w[lib/code.rb lib/code_sym.rb lib/code_sym2.rb] - FileUtils.mkdir_p 'lib' + FileUtils.mkdir_p "lib" - File.open 'lib/code.rb', 'w' do |io| - io.write '# lib/code.rb' + File.open "lib/code.rb", "w" do |io| + io.write "# lib/code.rb" end # NOTE: 'code.rb' is correct, because it's relative to lib/code_sym.rb begin - File.symlink('code.rb', 'lib/code_sym.rb') - File.symlink('../lib/code.rb', 'lib/code_sym2.rb') + File.symlink("code.rb", "lib/code_sym.rb") + File.symlink("../lib/code.rb", "lib/code_sym2.rb") rescue Errno::EACCES => e - if win_platform? - skip "symlink - must be admin with no UAC on Windows" + if Gem.win_platform? + pend "symlink - must be admin with no UAC on Windows" else raise e end end - package = Gem::Package.new 'bogus.gem' + package = Gem::Package.new "bogus.gem" package.spec = spec tar = util_tar do |tar_io| @@ -205,7 +205,8 @@ class TestGemPackage < Gem::Package::TarTestCase tar.rewind - files, symlinks = [], [] + files = [] + symlinks = [] Gem::Package::TarReader.new tar do |tar_io| tar_io.each_entry do |entry| @@ -218,20 +219,20 @@ class TestGemPackage < Gem::Package::TarTestCase end assert_equal %w[lib/code.rb], files - assert_equal [{'lib/code_sym.rb' => 'code.rb'}, {'lib/code_sym2.rb' => '../lib/code.rb'}], symlinks + assert_equal [{ "lib/code_sym.rb" => "code.rb" }, { "lib/code_sym2.rb" => "../lib/code.rb" }], symlinks end def test_build - spec = Gem::Specification.new 'build', '1' - spec.summary = 'build' - spec.authors = 'build' - spec.files = ['lib/code.rb'] + spec = Gem::Specification.new "build", "1" + spec.summary = "build" + spec.authors = "build" + spec.files = ["lib/code.rb"] spec.rubygems_version = :junk - FileUtils.mkdir 'lib' + FileUtils.mkdir "lib" - File.open 'lib/code.rb', 'w' do |io| - io.write '# lib/code.rb' + File.open "lib/code.rb", "w" do |io| + io.write "# lib/code.rb" end package = Gem::Package.new spec.file_name @@ -252,25 +253,25 @@ class TestGemPackage < Gem::Package::TarTestCase end def test_build_auto_signed - skip 'openssl is missing' unless Gem::HAVE_OPENSSL + pend "openssl is missing" unless Gem::HAVE_OPENSSL - FileUtils.mkdir_p File.join(Gem.user_home, '.gem') + FileUtils.mkdir_p File.join(Gem.user_home, ".gem") - private_key_path = File.join Gem.user_home, '.gem', 'gem-private_key.pem' + private_key_path = File.join Gem.user_home, ".gem", "gem-private_key.pem" Gem::Security.write PRIVATE_KEY, private_key_path - public_cert_path = File.join Gem.user_home, '.gem', 'gem-public_cert.pem' + public_cert_path = File.join Gem.user_home, ".gem", "gem-public_cert.pem" FileUtils.cp PUBLIC_CERT_PATH, public_cert_path - spec = Gem::Specification.new 'build', '1' - spec.summary = 'build' - spec.authors = 'build' - spec.files = ['lib/code.rb'] + spec = Gem::Specification.new "build", "1" + spec.summary = "build" + spec.authors = "build" + spec.files = ["lib/code.rb"] - FileUtils.mkdir 'lib' + FileUtils.mkdir "lib" - File.open 'lib/code.rb', 'w' do |io| - io.write '# lib/code.rb' + File.open "lib/code.rb", "w" do |io| + io.write "# lib/code.rb" end package = Gem::Package.new spec.file_name @@ -286,8 +287,8 @@ class TestGemPackage < Gem::Package::TarTestCase 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 + assert_equal %w[metadata.gz metadata.gz.sig + data.tar.gz data.tar.gz.sig checksums.yaml.gz checksums.yaml.gz.sig], reader.files @@ -295,25 +296,25 @@ class TestGemPackage < Gem::Package::TarTestCase end def test_build_auto_signed_encrypted_key - skip 'openssl is missing' unless Gem::HAVE_OPENSSL + pend "openssl is missing" unless Gem::HAVE_OPENSSL - FileUtils.mkdir_p File.join(Gem.user_home, '.gem') + FileUtils.mkdir_p File.join(Gem.user_home, ".gem") - private_key_path = File.join Gem.user_home, '.gem', 'gem-private_key.pem' + private_key_path = File.join Gem.user_home, ".gem", "gem-private_key.pem" FileUtils.cp ENCRYPTED_PRIVATE_KEY_PATH, private_key_path - public_cert_path = File.join Gem.user_home, '.gem', 'gem-public_cert.pem' + public_cert_path = File.join Gem.user_home, ".gem", "gem-public_cert.pem" Gem::Security.write PUBLIC_CERT, public_cert_path - spec = Gem::Specification.new 'build', '1' - spec.summary = 'build' - spec.authors = 'build' - spec.files = ['lib/code.rb'] + spec = Gem::Specification.new "build", "1" + spec.summary = "build" + spec.authors = "build" + spec.files = ["lib/code.rb"] - FileUtils.mkdir 'lib' + FileUtils.mkdir "lib" - File.open 'lib/code.rb', 'w' do |io| - io.write '# lib/code.rb' + File.open "lib/code.rb", "w" do |io| + io.write "# lib/code.rb" end package = Gem::Package.new spec.file_name @@ -329,8 +330,8 @@ class TestGemPackage < Gem::Package::TarTestCase 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 + assert_equal %w[metadata.gz metadata.gz.sig + data.tar.gz data.tar.gz.sig checksums.yaml.gz checksums.yaml.gz.sig], reader.files @@ -338,7 +339,7 @@ class TestGemPackage < Gem::Package::TarTestCase end def test_build_invalid - spec = Gem::Specification.new 'build', '1' + spec = Gem::Specification.new "build", "1" package = Gem::Package.new spec.file_name package.spec = spec @@ -347,11 +348,11 @@ class TestGemPackage < Gem::Package::TarTestCase package.build end - assert_equal 'missing value for attribute summary', e.message + assert_equal "missing value for attribute summary", e.message end def test_build_invalid_arguments - spec = Gem::Specification.new 'build', '1' + spec = Gem::Specification.new "build", "1" package = Gem::Package.new spec.file_name package.spec = spec @@ -364,19 +365,19 @@ class TestGemPackage < Gem::Package::TarTestCase end def test_build_signed - skip 'openssl is missing' unless Gem::HAVE_OPENSSL + pend "openssl is missing" unless Gem::HAVE_OPENSSL - spec = Gem::Specification.new 'build', '1' - spec.summary = 'build' - spec.authors = 'build' - spec.files = ['lib/code.rb'] + 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' + FileUtils.mkdir "lib" - File.open 'lib/code.rb', 'w' do |io| - io.write '# lib/code.rb' + File.open "lib/code.rb", "w" do |io| + io.write "# lib/code.rb" end package = Gem::Package.new spec.file_name @@ -392,8 +393,8 @@ class TestGemPackage < Gem::Package::TarTestCase assert_equal spec, reader.spec - assert_equal %w[metadata.gz metadata.gz.sig - data.tar.gz data.tar.gz.sig + assert_equal %w[metadata.gz metadata.gz.sig + data.tar.gz data.tar.gz.sig checksums.yaml.gz checksums.yaml.gz.sig], reader.files @@ -401,19 +402,19 @@ class TestGemPackage < Gem::Package::TarTestCase end def test_build_signed_encrypted_key - skip 'openssl is missing' unless Gem::HAVE_OPENSSL + pend "openssl is missing" unless Gem::HAVE_OPENSSL - spec = Gem::Specification.new 'build', '1' - spec.summary = 'build' - spec.authors = 'build' - spec.files = ['lib/code.rb'] + spec = Gem::Specification.new "build", "1" + spec.summary = "build" + spec.authors = "build" + spec.files = ["lib/code.rb"] spec.cert_chain = [PUBLIC_CERT.to_pem] spec.signing_key = ENCRYPTED_PRIVATE_KEY - FileUtils.mkdir 'lib' + FileUtils.mkdir "lib" - File.open 'lib/code.rb', 'w' do |io| - io.write '# lib/code.rb' + File.open "lib/code.rb", "w" do |io| + io.write "# lib/code.rb" end package = Gem::Package.new spec.file_name @@ -429,8 +430,8 @@ class TestGemPackage < Gem::Package::TarTestCase assert_equal spec, reader.spec - assert_equal %w[metadata.gz metadata.gz.sig - data.tar.gz data.tar.gz.sig + assert_equal %w[metadata.gz metadata.gz.sig + data.tar.gz data.tar.gz.sig checksums.yaml.gz checksums.yaml.gz.sig], reader.files @@ -441,11 +442,11 @@ class TestGemPackage < Gem::Package::TarTestCase data_tgz = util_tar_gz {} gem = util_tar do |tar| - tar.add_file 'data.tar.gz', 0644 do |io| + tar.add_file "data.tar.gz", 0o644 do |io| io.write data_tgz.string end - tar.add_file 'metadata.gz', 0644 do |io| + tar.add_file "metadata.gz", 0o644 do |io| Zlib::GzipWriter.wrap io do |gzio| gzio.write @spec.to_yaml end @@ -475,47 +476,62 @@ class TestGemPackage < Gem::Package::TarTestCase package.extract_files @destination - extracted = File.join @destination, 'lib/code.rb' + extracted = File.join @destination, "lib/code.rb" assert_path_exist extracted - mask = 0100666 & (~File.umask) + mask = 0o100666 & (~File.umask) assert_equal mask.to_s(8), File.stat(extracted).mode.to_s(8) unless - win_platform? + Gem.win_platform? end def test_extract_files_empty data_tgz = util_tar_gz {} gem = util_tar do |tar| - tar.add_file 'data.tar.gz', 0644 do |io| + tar.add_file "data.tar.gz", 0o644 do |io| io.write data_tgz.string end - tar.add_file 'metadata.gz', 0644 do |io| + tar.add_file "metadata.gz", 0o644 do |io| Zlib::GzipWriter.wrap io do |gzio| gzio.write @spec.to_yaml end end end - File.open 'empty.gem', 'wb' do |io| + File.open "empty.gem", "wb" do |io| io.write gem.string end - package = Gem::Package.new 'empty.gem' + package = Gem::Package.new "empty.gem" package.extract_files @destination assert_path_exist @destination end + def test_extract_file_permissions + pend "chmod not supported" if Gem.win_platform? + + gem_with_long_permissions = File.expand_path("packages/Bluebie-legs-0.6.2.gem", __dir__) + + package = Gem::Package.new gem_with_long_permissions + + package.extract_files @destination + + filepath = File.join @destination, "README.rdoc" + assert_path_exist filepath + + assert_equal 0o104444, File.stat(filepath).mode + 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' + tar.add_file "/absolute.rb", 0o644 do |io| + io.write "hi" end end @@ -523,69 +539,118 @@ class TestGemPackage < Gem::Package::TarTestCase package.extract_tar_gz tgz_io, @destination end - assert_equal("installing into parent path /absolute.rb of " + + assert_equal("installing into parent path /absolute.rb of " \ "#{@destination} is not allowed", e.message) end def test_extract_tar_gz_symlink_relative_path package = Gem::Package.new @gem + package.verify tgz_io = util_tar_gz do |tar| - tar.add_file 'relative.rb', 0644 do |io| - io.write 'hi' + tar.add_file "relative.rb", 0o644 do |io| + io.write "hi" end - tar.mkdir 'lib', 0755 - tar.add_symlink 'lib/foo.rb', '../relative.rb', 0644 + tar.mkdir "lib", 0o755 + tar.add_symlink "lib/foo.rb", "../relative.rb", 0o644 end begin package.extract_tar_gz tgz_io, @destination rescue Errno::EACCES => e - if win_platform? - skip "symlink - must be admin with no UAC on Windows" + if Gem.win_platform? + pend "symlink - must be admin with no UAC on Windows" else raise e end end - extracted = File.join @destination, 'lib/foo.rb' + extracted = File.join @destination, "lib/foo.rb" assert_path_exist extracted - assert_equal '../relative.rb', + assert_equal "../relative.rb", File.readlink(extracted) - assert_equal 'hi', + assert_equal "hi", File.read(extracted) end + def test_extract_symlink_into_symlink_dir + package = Gem::Package.new @gem + tgz_io = util_tar_gz do |tar| + tar.mkdir "lib", 0o755 + tar.add_symlink "lib/link", "./inside.rb", 0o644 + tar.add_file "lib/inside.rb", 0o644 do |io| + io.write "hi" + end + end + + destination_subdir = File.join @destination, "subdir" + FileUtils.mkdir_p destination_subdir + + destination_linkdir = File.join @destination, "linkdir" + File.symlink(destination_subdir, destination_linkdir) + + package.extract_tar_gz tgz_io, destination_linkdir + + extracted = File.join destination_subdir, "lib/link" + assert_path_exist extracted + assert_equal "./inside.rb", + File.readlink(extracted) + assert_equal "hi", + File.read(extracted) + end + + def test_extract_tar_gz_symlink_broken_relative_path + package = Gem::Package.new @gem + package.verify + + tgz_io = util_tar_gz do |tar| + tar.mkdir "lib", 0o755 + tar.add_symlink "lib/foo.rb", "../broken.rb", 0o644 + end + + ui = Gem::MockGemUi.new + + use_ui ui do + package.extract_tar_gz tgz_io, @destination + end + + assert_equal "WARNING: a-2 ships with a dangling symlink named lib/foo.rb pointing to missing ../broken.rb file. Ignoring\n", ui.error + + extracted = File.join @destination, "lib/foo.rb" + assert_path_not_exist extracted + end + def test_extract_symlink_parent package = Gem::Package.new @gem tgz_io = util_tar_gz do |tar| - tar.mkdir 'lib', 0755 - tar.add_symlink 'lib/link', '../..', 0644 - tar.add_file 'lib/link/outside.txt', 0644 do |io| - io.write 'hi' + tar.mkdir "lib", 0o755 + tar.add_symlink "lib/link", "../..", 0o644 + tar.add_file "lib/link/outside.txt", 0o644 do |io| + io.write "hi" end end # Extract into a subdirectory of @destination; if this test fails it writes # a file outside destination_subdir, but we want the file to remain inside # @destination so it will be cleaned up. - destination_subdir = File.join @destination, 'subdir' + destination_subdir = File.join @destination, "subdir" FileUtils.mkdir_p destination_subdir - e = assert_raise(Gem::Package::PathError, Errno::EACCES) do + expected_exceptions = Gem.win_platform? ? [Gem::Package::SymlinkError, Errno::EACCES] : [Gem::Package::SymlinkError] + + e = assert_raise(*expected_exceptions) do package.extract_tar_gz tgz_io, destination_subdir end - if Gem::Package::PathError === e - assert_equal("installing into parent path lib/link/outside.txt of " + - "#{destination_subdir} is not allowed", e.message) - elsif win_platform? - skip "symlink - must be admin with no UAC on Windows" - else - raise e - end + pend "symlink - must be admin with no UAC on Windows" if Errno::EACCES === e + + assert_equal("installing symlink 'lib/link' pointing to parent path #{@destination} of " \ + "#{destination_subdir} is not allowed", e.message) + + assert_path_not_exist File.join(@destination, "outside.txt") + assert_path_not_exist File.join(destination_subdir, "lib/link") end def test_extract_symlink_parent_doesnt_delete_user_dir @@ -594,53 +659,53 @@ class TestGemPackage < Gem::Package::TarTestCase # Extract into a subdirectory of @destination; if this test fails it writes # a file outside destination_subdir, but we want the file to remain inside # @destination so it will be cleaned up. - destination_subdir = File.join @destination, 'subdir' + destination_subdir = File.join @destination, "subdir" FileUtils.mkdir_p destination_subdir - destination_user_dir = File.join @destination, 'user' - destination_user_subdir = File.join destination_user_dir, 'dir' + destination_user_dir = File.join @destination, "user" + destination_user_subdir = File.join destination_user_dir, "dir" FileUtils.mkdir_p destination_user_subdir - skip "TMPDIR seems too long to add it as symlink into tar" if destination_user_dir.size > 90 + pend "TMPDIR seems too long to add it as symlink into tar" if destination_user_dir.size > 90 tgz_io = util_tar_gz do |tar| - tar.add_symlink 'link', destination_user_dir, 16877 - tar.add_symlink 'link/dir', '.', 16877 + tar.add_symlink "link", destination_user_dir, 16_877 + tar.add_symlink "link/dir", ".", 16_877 end - e = assert_raise(Gem::Package::PathError, Errno::EACCES) do + expected_exceptions = Gem.win_platform? ? [Gem::Package::SymlinkError, Errno::EACCES] : [Gem::Package::SymlinkError] + + e = assert_raise(*expected_exceptions) do package.extract_tar_gz tgz_io, destination_subdir end - assert_path_exist destination_user_subdir + pend "symlink - must be admin with no UAC on Windows" if Errno::EACCES === e - if Gem::Package::PathError === e - assert_equal("installing into parent path #{destination_user_subdir} of " + - "#{destination_subdir} is not allowed", e.message) - elsif win_platform? - skip "symlink - must be admin with no UAC on Windows" - else - raise e - end + assert_equal("installing symlink 'link' pointing to parent path #{destination_user_dir} of " \ + "#{destination_subdir} is not allowed", e.message) + + assert_path_exist destination_user_subdir + assert_path_not_exist File.join(destination_subdir, "link/dir") + assert_path_not_exist File.join(destination_subdir, "link") end def test_extract_tar_gz_directory package = Gem::Package.new @gem tgz_io = util_tar_gz do |tar| - tar.mkdir 'lib', 0755 - tar.add_file 'lib/foo.rb', 0644 do |io| - io.write 'hi' + tar.mkdir "lib", 0o755 + tar.add_file "lib/foo.rb", 0o644 do |io| + io.write "hi" end - tar.mkdir 'lib/foo', 0755 + tar.mkdir "lib/foo", 0o755 end package.extract_tar_gz tgz_io, @destination - extracted = File.join @destination, 'lib/foo.rb' + extracted = File.join @destination, "lib/foo.rb" assert_path_exist extracted - extracted = File.join @destination, 'lib/foo' + extracted = File.join @destination, "lib/foo" assert_path_exist extracted end @@ -648,14 +713,14 @@ class TestGemPackage < Gem::Package::TarTestCase package = Gem::Package.new @gem tgz_io = util_tar_gz do |tar| - tar.add_file './dot_slash.rb', 0644 do |io| - io.write 'hi' + tar.add_file "./dot_slash.rb", 0o644 do |io| + io.write "hi" end end package.extract_tar_gz tgz_io, @destination - extracted = File.join @destination, 'dot_slash.rb' + extracted = File.join @destination, "dot_slash.rb" assert_path_exist extracted end @@ -663,14 +728,14 @@ class TestGemPackage < Gem::Package::TarTestCase package = Gem::Package.new @gem tgz_io = util_tar_gz do |tar| - tar.add_file '.dot_file.rb', 0644 do |io| - io.write 'hi' + tar.add_file ".dot_file.rb", 0o644 do |io| + io.write "hi" end end package.extract_tar_gz tgz_io, @destination - extracted = File.join @destination, '.dot_file.rb' + extracted = File.join @destination, ".dot_file.rb" assert_path_exist extracted end @@ -679,14 +744,14 @@ class TestGemPackage < Gem::Package::TarTestCase package = Gem::Package.new @gem tgz_io = util_tar_gz do |tar| - tar.add_file 'foo/file.rb', 0644 do |io| - io.write 'hi' + tar.add_file "foo/file.rb", 0o644 do |io| + io.write "hi" end end package.extract_tar_gz tgz_io, @destination.upcase - extracted = File.join @destination, 'foo/file.rb' + extracted = File.join @destination, "foo/file.rb" assert_path_exist extracted end end @@ -694,66 +759,60 @@ class TestGemPackage < Gem::Package::TarTestCase def test_install_location package = Gem::Package.new @gem - file = 'file.rb'.dup - file.taint if RUBY_VERSION < '2.7' + file = "file.rb".dup destination = package.install_location file, @destination - assert_equal File.join(@destination, 'file.rb'), destination - refute destination.tainted? if RUBY_VERSION < '2.7' + assert_equal File.join(@destination, "file.rb"), destination end def test_install_location_absolute package = Gem::Package.new @gem e = assert_raise Gem::Package::PathError do - package.install_location '/absolute.rb', @destination + package.install_location "/absolute.rb", @destination end - assert_equal("installing into parent path /absolute.rb of " + + assert_equal("installing into parent path /absolute.rb of " \ "#{@destination} is not allowed", e.message) end def test_install_location_dots package = Gem::Package.new @gem - file = 'file.rb' + file = "file.rb" - destination = File.join @destination, 'foo', '..', 'bar' + destination = File.join @destination, "foo", "..", "bar" - FileUtils.mkdir_p File.join @destination, 'foo' + FileUtils.mkdir_p File.join @destination, "foo" FileUtils.mkdir_p File.expand_path destination destination = package.install_location file, destination # this test only fails on ruby missing File.realpath - assert_equal File.join(@destination, 'bar', 'file.rb'), destination + assert_equal File.join(@destination, "bar", "file.rb"), destination end def test_install_location_extra_slash package = Gem::Package.new @gem - file = 'foo//file.rb'.dup - file.taint if RUBY_VERSION < '2.7' - - destination = @destination.sub '/', '//' + file = "foo//file.rb".dup - destination = package.install_location file, destination + destination = package.install_location file, @destination - assert_equal File.join(@destination, 'foo', 'file.rb'), destination - refute destination.tainted? if RUBY_VERSION < '2.7' + assert_equal File.join(@destination, "foo", "file.rb"), destination end def test_install_location_relative package = Gem::Package.new @gem e = assert_raise Gem::Package::PathError do - package.install_location '../relative.rb', @destination + package.install_location "../relative.rb", @destination end parent = File.expand_path File.join @destination, "../relative.rb" - assert_equal("installing into parent path #{parent} of " + + assert_equal("installing into parent path #{parent} of " \ "#{@destination} is not allowed", e.message) end @@ -768,15 +827,17 @@ class TestGemPackage < Gem::Package::TarTestCase parent = File.expand_path File.join @destination, filename - assert_equal("installing into parent path #{parent} of " + + assert_equal("installing into parent path #{parent} of " \ "#{@destination} is not allowed", e.message) end def test_load_spec entry = StringIO.new Gem::Util.gzip @spec.to_yaml - def entry.full_name() 'metadata.gz' end + def entry.full_name + "metadata.gz" + end - package = Gem::Package.new 'nonexistent.gem' + package = Gem::Package.new "nonexistent.gem" spec = package.load_spec entry @@ -795,8 +856,8 @@ class TestGemPackage < Gem::Package::TarTestCase 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' + tar.add_file "lib/code.rb", 0o444 do |io| + io.write "# lib/code.rb" end end @@ -805,45 +866,45 @@ class TestGemPackage < Gem::Package::TarTestCase gem = util_tar do |tar| metadata_gz = Gem::Util.gzip @spec.to_yaml - tar.add_file 'metadata.gz', 0444 do |io| + tar.add_file "metadata.gz", 0o444 do |io| io.write metadata_gz end - tar.add_file 'data.tar.gz', 0444 do |io| + tar.add_file "data.tar.gz", 0o444 do |io| io.write data_tgz end bogus_checksums = { - 'SHA1' => { - 'data.tar.gz' => 'bogus', - 'metadata.gz' => 'bogus', + "SHA1" => { + "data.tar.gz" => "bogus", + "metadata.gz" => "bogus", }, } - tar.add_file 'checksums.yaml.gz', 0444 do |io| + tar.add_file "checksums.yaml.gz", 0o444 do |io| Zlib::GzipWriter.wrap io do |gz_io| - gz_io.write YAML.dump bogus_checksums + gz_io.write Psych.dump bogus_checksums end end end - File.open 'mismatch.gem', 'wb' do |io| + File.open "mismatch.gem", "wb" do |io| io.write gem.string end - package = Gem::Package.new 'mismatch.gem' + package = Gem::Package.new "mismatch.gem" e = assert_raise Gem::Package::FormatError do package.verify end - assert_equal 'SHA1 checksum mismatch for data.tar.gz in mismatch.gem', + 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' + tar.add_file "lib/code.rb", 0o444 do |io| + io.write "# lib/code.rb" end end @@ -852,45 +913,45 @@ class TestGemPackage < Gem::Package::TarTestCase gem = util_tar do |tar| metadata_gz = Gem::Util.gzip @spec.to_yaml - tar.add_file 'metadata.gz', 0444 do |io| + tar.add_file "metadata.gz", 0o444 do |io| io.write metadata_gz end - digest = Digest::SHA1.new + digest = OpenSSL::Digest::SHA1.new digest << metadata_gz checksums = { - 'SHA1' => { - 'metadata.gz' => digest.hexdigest, + "SHA1" => { + "metadata.gz" => digest.hexdigest, }, } - tar.add_file 'checksums.yaml.gz', 0444 do |io| + tar.add_file "checksums.yaml.gz", 0o444 do |io| Zlib::GzipWriter.wrap io do |gz_io| - gz_io.write YAML.dump checksums + gz_io.write Psych.dump checksums end end - tar.add_file 'data.tar.gz', 0444 do |io| + tar.add_file "data.tar.gz", 0o444 do |io| io.write data_tgz end end - File.open 'data_checksum_missing.gem', 'wb' do |io| + File.open "data_checksum_missing.gem", "wb" do |io| io.write gem.string end - package = Gem::Package.new 'data_checksum_missing.gem' + package = Gem::Package.new "data_checksum_missing.gem" assert package.verify end def test_verify_corrupt - skip "jruby strips the null byte and does not think it's corrupt" if Gem.java_platform? - tf = Tempfile.open 'corrupt' do |io| - data = Gem::Util.gzip 'a' * 10 + pend "jruby strips the null byte and does not think it's corrupt" if Gem.java_platform? + tf = Tempfile.open "corrupt" do |io| + data = Gem::Util.gzip "a" * 10 io.write \ - tar_file_header('metadata.gz', "\000x", 0644, data.length, Time.now) + tar_file_header("metadata.gz", "\000x", 0o644, data.length, Time.now) io.write data io.rewind @@ -907,43 +968,132 @@ class TestGemPackage < Gem::Package::TarTestCase tf.close! end + def test_verify_corrupt_tar_metadata_entry + gem = tar_file_header("metadata.gz", "", 0, 999, Time.now) + + File.open "corrupt.gem", "wb" do |io| + io.write gem + end + + package = Gem::Package.new "corrupt.gem" + + e = nil + out_err = capture_output do + e = assert_raise Gem::Package::FormatError do + package.verify + end + end + + assert_match(/(EOFError|end of file reached) in corrupt.gem/i, e.message) + assert_equal(["", "Exception while verifying corrupt.gem\n"], out_err) + end + + def test_verify_corrupt_tar_checksums_entry + gem = tar_file_header("checksums.yaml.gz", "", 0, 100, Time.now) + + File.open "corrupt.gem", "wb" do |io| + io.write gem + end + + package = Gem::Package.new "corrupt.gem" + + e = assert_raise Gem::Package::FormatError do + package.verify + end + + assert_equal "not in gzip format in corrupt.gem", e.message + end + + def test_verify_corrupt_tar_data_entry + gem = tar_file_header("data.tar.gz", "", 0, 100, Time.now) + + File.open "corrupt.gem", "wb" do |io| + io.write gem + end + + package = Gem::Package.new "corrupt.gem" + + e = nil + out_err = capture_output do + e = assert_raise Gem::Package::FormatError do + package.verify + end + end + + assert_match(/(EOFError|end of file reached) in corrupt.gem/i, e.message) + assert_equal(["", "Exception while verifying corrupt.gem\n"], out_err) + end + + def test_corrupt_data_tar_gz + data_tgz = util_gzip tar_file_header("lib/code.rb", "", 0, 100, Time.now) + metadata_gz = util_gzip @spec.to_yaml + + gem = util_tar do |tar| + tar.add_file "data.tar.gz", 0o444 do |io| + io.write data_tgz + end + + tar.add_file "metadata.gz", 0o644 do |io| + io.write metadata_gz + end + end + + File.open "corrupt.gem", "wb" do |io| + io.write gem.string + end + + package = Gem::Package.new "corrupt.gem" + + e = assert_raise Gem::Package::FormatError do + package.contents + end + + assert_match(/(EOFError|end of file reached) in corrupt.gem/i, e.message) + + e = assert_raise Gem::Package::FormatError do + package.extract_files @destination + end + + assert_match(/(EOFError|end of file reached) in corrupt.gem/i, e.message) + end + def test_verify_empty - FileUtils.touch 'empty.gem' + FileUtils.touch "empty.gem" - package = Gem::Package.new 'empty.gem' + package = Gem::Package.new "empty.gem" e = assert_raise Gem::Package::FormatError do package.verify end - assert_equal 'package metadata is missing in empty.gem', e.message + assert_equal "package metadata is missing in empty.gem", e.message end def test_verify_nonexistent - package = Gem::Package.new 'nonexistent.gem' + package = Gem::Package.new "nonexistent.gem" e = assert_raise Gem::Package::FormatError do package.verify end - assert_match %r{^No such file or directory}, e.message - assert_match %r{nonexistent.gem$}, e.message + assert_match(/^No such file or directory/, e.message) + assert_match(/nonexistent.gem$/, e.message) end def test_verify_duplicate_file - FileUtils.mkdir_p 'lib' - FileUtils.touch 'lib/code.rb' + FileUtils.mkdir_p "lib" + FileUtils.touch "lib/code.rb" build = Gem::Package.new @gem build.spec = @spec build.setup_signer - File.open @gem, 'wb' do |gem_io| + File.open @gem, "wb" do |gem_io| Gem::Package::TarWriter.new gem_io do |gem| build.add_metadata gem build.add_contents gem - gem.add_file_simple 'a.sig', 0444, 0 - gem.add_file_simple 'a.sig', 0444, 0 + gem.add_file_simple "a.sig", 0o444, 0 + gem.add_file_simple "a.sig", 0o444, 0 end end @@ -957,7 +1107,7 @@ class TestGemPackage < Gem::Package::TarTestCase end def test_verify_security_policy - skip 'openssl is missing' unless Gem::HAVE_OPENSSL + pend "openssl is missing" unless Gem::HAVE_OPENSSL package = Gem::Package.new @gem package.security_policy = Gem::Security::HighSecurity @@ -966,21 +1116,21 @@ class TestGemPackage < Gem::Package::TarTestCase package.verify end - assert_equal 'unsigned gems are not allowed by the High Security policy', + assert_equal "unsigned gems are not allowed by the High Security policy", e.message - refute package.instance_variable_get(:@spec), '@spec must not be loaded' - assert_empty package.instance_variable_get(:@files), '@files must empty' + refute package.instance_variable_get(:@spec), "@spec must not be loaded" + assert_empty package.instance_variable_get(:@files), "@files must empty" end def test_verify_security_policy_low_security - skip 'openssl is missing' unless Gem::HAVE_OPENSSL + pend "openssl is missing" unless Gem::HAVE_OPENSSL @spec.cert_chain = [PUBLIC_CERT.to_pem] @spec.signing_key = PRIVATE_KEY - FileUtils.mkdir_p 'lib' - FileUtils.touch 'lib/code.rb' + FileUtils.mkdir_p "lib" + FileUtils.touch "lib/code.rb" build = Gem::Package.new @gem build.spec = @spec @@ -994,7 +1144,7 @@ class TestGemPackage < Gem::Package::TarTestCase end def test_verify_security_policy_checksum_missing - skip 'openssl is missing' unless Gem::HAVE_OPENSSL + pend "openssl is missing" unless Gem::HAVE_OPENSSL @spec.cert_chain = [PUBLIC_CERT.to_pem] @spec.signing_key = PRIVATE_KEY @@ -1003,23 +1153,34 @@ class TestGemPackage < Gem::Package::TarTestCase build.spec = @spec build.setup_signer - FileUtils.mkdir 'lib' - FileUtils.touch 'lib/code.rb' + FileUtils.mkdir "lib" + FileUtils.touch "lib/code.rb" - File.open @gem, 'wb' do |gem_io| + File.open @gem, "wb" do |gem_io| Gem::Package::TarWriter.new gem_io do |gem| build.add_metadata gem build.add_contents gem # write bogus data.tar.gz to foil signature - bogus_data = Gem::Util.gzip 'hello' + bogus_data = Gem::Util.gzip "hello" fake_signer = Class.new do - def digest_name; 'SHA512'; end - def digest_algorithm; Digest(:SHA512).new; end - def key; 'key'; end - def sign(*); 'fake_sig'; end + def digest_name + "SHA512" + end + + def digest_algorithm + OpenSSL::Digest(:SHA512).new + end + + def key + "key" + end + + def sign(*) + "fake_sig" + end end - gem.add_file_signed 'data2.tar.gz', 0444, fake_signer.new do |io| + gem.add_file_signed "data2.tar.gz", 0o444, fake_signer.new do |io| io.write bogus_data end @@ -1036,24 +1197,24 @@ class TestGemPackage < Gem::Package::TarTestCase package.verify end - assert_equal 'invalid signature', e.message + assert_equal "invalid signature", e.message - refute package.instance_variable_get(:@spec), '@spec must not be loaded' - assert_empty package.instance_variable_get(:@files), '@files must empty' + refute package.instance_variable_get(:@spec), "@spec must not be loaded" + assert_empty package.instance_variable_get(:@files), "@files must empty" end def test_verify_truncate - File.open 'bad.gem', 'wb' do |io| + File.open "bad.gem", "wb" do |io| io.write File.read(@gem, 1024) # don't care about newlines end - package = Gem::Package.new 'bad.gem' + package = Gem::Package.new "bad.gem" e = assert_raise Gem::Package::FormatError do package.verify end - assert_equal 'package content (data.tar.gz) is missing in bad.gem', + assert_equal "package content (data.tar.gz) is missing in bad.gem", e.message end @@ -1061,7 +1222,9 @@ class TestGemPackage < Gem::Package::TarTestCase def test_verify_entry entry = Object.new - def entry.full_name() raise ArgumentError, 'whatever' end + def entry.full_name + raise ArgumentError, "whatever" + end package = Gem::Package.new @gem @@ -1088,11 +1251,15 @@ class TestGemPackage < Gem::Package::TarTestCase $good_name = vm entry = Object.new - def entry.full_name() $good_name end + def entry.full_name + $good_name + end package = Gem::Package.new(@gem) package.instance_variable_set(:@files, []) - def package.load_spec(entry) $spec_loaded = true end + def package.load_spec(entry) + $spec_loaded = true + end package.verify_entry(entry) @@ -1105,11 +1272,15 @@ class TestGemPackage < Gem::Package::TarTestCase $bad_name = vm entry = Object.new - def entry.full_name() $bad_name end + def entry.full_name + $bad_name + end package = Gem::Package.new(@gem) package.instance_variable_set(:@files, []) - def package.load_spec(entry) $spec_loaded = true end + def package.load_spec(entry) + $spec_loaded = true + end package.verify_entry(entry) @@ -1145,28 +1316,10 @@ class TestGemPackage < Gem::Package::TarTestCase end end - def util_tar - tar_io = StringIO.new - - Gem::Package::TarWriter.new tar_io do |tar| - yield tar - end - - tar_io.rewind - - tar_io - end - - def util_tar_gz(&block) - tar_io = util_tar(&block) - - tgz_io = StringIO.new - - # can't wrap TarWriter because it seeks - Zlib::GzipWriter.wrap tgz_io do |io| - io.write tar_io.string - end + def test_contents_from_io + io = StringIO.new Gem.read_binary @gem + package = Gem::Package.new io - StringIO.new tgz_io.string + assert_equal %w[lib/code.rb], package.contents end end diff --git a/test/rubygems/test_gem_package_old.rb b/test/rubygems/test_gem_package_old.rb index fbeb4dd0c0..7582dbedd4 100644 --- a/test/rubygems/test_gem_package_old.rb +++ b/test/rubygems/test_gem_package_old.rb @@ -1,19 +1,20 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" unless Gem.java_platform? # jruby can't require the simple_gem file - require 'rubygems/simple_gem' + require "rubygems/simple_gem" class TestGemPackageOld < Gem::TestCase def setup super - File.open 'old_format.gem', 'wb' do |io| + File.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' + @package = Gem::Package::Old.new "old_format.gem" + @destination = File.join @tempdir, "extract" FileUtils.mkdir_p @destination end @@ -23,7 +24,7 @@ unless Gem.java_platform? # jruby can't require the simple_gem file end def test_contents_security_policy - skip 'openssl is missing' unless Gem::HAVE_OPENSSL + pend "openssl is missing" unless Gem::HAVE_OPENSSL @package.security_policy = Gem::Security::AlmostNoSecurity @@ -35,16 +36,16 @@ unless Gem.java_platform? # jruby can't require the simple_gem file def test_extract_files @package.extract_files @destination - extracted = File.join @destination, 'lib/foo.rb' + extracted = File.join @destination, "lib/foo.rb" assert_path_exist extracted - mask = 0100644 & (~File.umask) + mask = 0o100644 & (~File.umask) - assert_equal mask, File.stat(extracted).mode unless win_platform? + assert_equal mask, File.stat(extracted).mode unless Gem.win_platform? end def test_extract_files_security_policy - skip 'openssl is missing' unless Gem::HAVE_OPENSSL + pend "openssl is missing" unless Gem::HAVE_OPENSSL @package.security_policy = Gem::Security::AlmostNoSecurity @@ -54,11 +55,11 @@ unless Gem.java_platform? # jruby can't require the simple_gem file end def test_spec - assert_equal 'testing', @package.spec.name + assert_equal "testing", @package.spec.name end def test_spec_security_policy - skip 'openssl is missing' unless Gem::HAVE_OPENSSL + pend "openssl is missing" unless Gem::HAVE_OPENSSL @package.security_policy = Gem::Security::AlmostNoSecurity @@ -68,7 +69,7 @@ unless Gem.java_platform? # jruby can't require the simple_gem file end def test_verify - skip 'openssl is missing' unless Gem::HAVE_OPENSSL + pend "openssl is missing" unless Gem::HAVE_OPENSSL assert @package.verify @@ -82,8 +83,8 @@ unless Gem.java_platform? # jruby can't require the simple_gem file @package.verify end - assert_equal 'old format gems do not contain signatures ' + - 'and cannot be verified', + assert_equal "old format gems do not contain signatures " \ + "and cannot be verified", e.message end end diff --git a/test/rubygems/test_gem_package_tar_header.rb b/test/rubygems/test_gem_package_tar_header.rb index 9f321e0a77..4469750f9a 100644 --- a/test/rubygems/test_gem_package_tar_header.rb +++ b/test/rubygems/test_gem_package_tar_header.rb @@ -1,25 +1,26 @@ # frozen_string_literal: true -require 'rubygems/package/tar_test_case' -require 'rubygems/package' + +require_relative "package/tar_test_case" +require "rubygems/package" class TestGemPackageTarHeader < Gem::Package::TarTestCase def setup super header = { - :name => 'x', - :mode => 0644, - :uid => 1000, - :gid => 10000, - :size => 100, - :mtime => 12345, - :typeflag => '0', - :linkname => 'link', - :uname => 'user', - :gname => 'group', - :devmajor => 1, - :devminor => 2, - :prefix => 'y', + name: "x", + mode: 0o644, + uid: 1000, + gid: 10_000, + size: 100, + mtime: 12_345, + typeflag: "0", + linkname: "link", + uname: "user", + gname: "group", + devmajor: 1, + devminor: 2, + prefix: "y", } @tar_header = Gem::Package::TarHeader.new header @@ -36,64 +37,64 @@ class TestGemPackageTarHeader < Gem::Package::TarTestCase end def test_initialize - assert_equal '', @tar_header.checksum, 'checksum' - assert_equal 1, @tar_header.devmajor, 'devmajor' - assert_equal 2, @tar_header.devminor, 'devminor' - assert_equal 10000, @tar_header.gid, 'gid' - assert_equal 'group', @tar_header.gname, 'gname' - assert_equal 'link', @tar_header.linkname, 'linkname' - assert_equal 'ustar', @tar_header.magic, 'magic' - assert_equal 0644, @tar_header.mode, 'mode' - assert_equal 12345, @tar_header.mtime, 'mtime' - assert_equal 'x', @tar_header.name, 'name' - assert_equal 'y', @tar_header.prefix, 'prefix' - assert_equal 100, @tar_header.size, 'size' - assert_equal '0', @tar_header.typeflag, 'typeflag' - assert_equal 1000, @tar_header.uid, 'uid' - assert_equal 'user', @tar_header.uname, 'uname' - assert_equal '00', @tar_header.version, 'version' - - refute_empty @tar_header, 'empty' + assert_equal "", @tar_header.checksum, "checksum" + assert_equal 1, @tar_header.devmajor, "devmajor" + assert_equal 2, @tar_header.devminor, "devminor" + assert_equal 10_000, @tar_header.gid, "gid" + assert_equal "group", @tar_header.gname, "gname" + assert_equal "link", @tar_header.linkname, "linkname" + assert_equal "ustar", @tar_header.magic, "magic" + assert_equal 0o644, @tar_header.mode, "mode" + assert_equal 12_345, @tar_header.mtime, "mtime" + assert_equal "x", @tar_header.name, "name" + assert_equal "y", @tar_header.prefix, "prefix" + assert_equal 100, @tar_header.size, "size" + assert_equal "0", @tar_header.typeflag, "typeflag" + assert_equal 1000, @tar_header.uid, "uid" + assert_equal "user", @tar_header.uname, "uname" + assert_equal "00", @tar_header.version, "version" + + refute_empty @tar_header, "empty" end def test_initialize_bad assert_raise ArgumentError do - Gem::Package::TarHeader.new :name => '', :size => '', :mode => '' + Gem::Package::TarHeader.new name: "", size: "", mode: "" end assert_raise ArgumentError do - Gem::Package::TarHeader.new :name => '', :size => '', :prefix => '' + Gem::Package::TarHeader.new name: "", size: "", prefix: "" end assert_raise ArgumentError do - Gem::Package::TarHeader.new :name => '', :prefix => '', :mode => '' + Gem::Package::TarHeader.new name: "", prefix: "", mode: "" end assert_raise ArgumentError do - Gem::Package::TarHeader.new :prefix => '', :size => '', :mode => '' + Gem::Package::TarHeader.new prefix: "", size: "", mode: "" end end def test_initialize_typeflag header = { - :mode => '', - :name => '', - :prefix => '', - :size => '', - :typeflag => '', + mode: "", + name: "", + prefix: "", + size: "", + typeflag: "", } tar_header = Gem::Package::TarHeader.new header - assert_equal '0', tar_header.typeflag + assert_equal "0", tar_header.typeflag end def test_empty_eh refute_empty @tar_header - @tar_header = Gem::Package::TarHeader.new :name => 'x', :prefix => '', - :mode => 0, :size => 0, - :empty => true + @tar_header = Gem::Package::TarHeader.new name: "x", prefix: "", + mode: 0, size: 0, + empty: true assert_empty @tar_header end @@ -135,11 +136,11 @@ group\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 end def test_update_checksum - assert_equal '', @tar_header.checksum + assert_equal "", @tar_header.checksum @tar_header.update_checksum - assert_equal '012467', @tar_header.checksum + assert_equal "012467", @tar_header.checksum end def test_from_bad_octal @@ -159,13 +160,14 @@ group\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 assert_raise ArgumentError do Gem::Package::TarHeader.from io end + ensure io.close! end end def test_big_uid_gid stream = StringIO.new( - <<-EOF.dup.force_encoding('binary').split("\n").join + <<-EOF.dup.force_encoding("binary").split("\n").join GeoIP2-City_20190528/ \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 @@ -194,19 +196,19 @@ tjmather\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 tar_header = Gem::Package::TarHeader.from stream - assert_equal 1991400094, tar_header.uid - assert_equal 1991400094, tar_header.gid + assert_equal 1_991_400_094, tar_header.uid + assert_equal 1_991_400_094, tar_header.gid - assert_equal 'GeoIP2-City_20190528/', tar_header.name - assert_equal 0755, tar_header.mode + assert_equal "GeoIP2-City_20190528/", tar_header.name + assert_equal 0o755, tar_header.mode assert_equal 0, tar_header.size - assert_equal 1559064640, tar_header.mtime + assert_equal 1_559_064_640, tar_header.mtime assert_equal 6932, tar_header.checksum end def test_spaces_in_headers stream = StringIO.new( - <<-EOF.dup.force_encoding('binary').split("\n").join + <<-EOF.dup.force_encoding("binary").split("\n").join Access_Points_09202018.csv \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 diff --git a/test/rubygems/test_gem_package_tar_reader.rb b/test/rubygems/test_gem_package_tar_reader.rb index 05b3ac56a6..b2f7cc2d5c 100644 --- a/test/rubygems/test_gem_package_tar_reader.rb +++ b/test/rubygems/test_gem_package_tar_reader.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/package/tar_test_case' -require 'rubygems/package' + +require_relative "package/tar_test_case" +require "rubygems/package" class TestGemPackageTarReader < Gem::Package::TarTestCase def test_each_entry @@ -24,12 +25,27 @@ class TestGemPackageTarReader < Gem::Package::TarTestCase io.close! end + def test_each_with_not_a_tar + text = "Hello, world!!?\n" * 256 # 4 KiB + io = TempIO.new text + + Gem::Package::TarReader.new io do |tar| + assert_raise Gem::Package::TarInvalidError do + tar.each do + flunk "TarInvalidError was expected to occur, but an entry was found" + end + end + end + ensure + io.close! + end + def test_rewind - content = ('a'..'z').to_a.join(" ") + content = ("a".."z").to_a.join(" ") str = - tar_file_header("lib/foo", "", 010644, content.size, Time.now) + - content + "\0" * (512 - content.size) + tar_file_header("lib/foo", "", 0o10644, content.size, Time.now) + + content + "\0" * (512 - content.size) str << "\0" * 1024 io = TempIO.new(str) @@ -56,12 +72,14 @@ class TestGemPackageTarReader < Gem::Package::TarTestCase io = TempIO.new tar Gem::Package::TarReader.new io do |tar_reader| - tar_reader.seek 'baz/bar' do |entry| + retval = tar_reader.seek "baz/bar" do |entry| assert_kind_of Gem::Package::TarReader::Entry, entry - assert_equal 'baz/bar', entry.full_name + assert_equal "baz/bar", entry.full_name + entry.read end + assert_equal "", retval assert_equal 0, io.pos end ensure @@ -75,8 +93,8 @@ class TestGemPackageTarReader < Gem::Package::TarTestCase 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' + tar_reader.seek "nonexistent" do |_entry| + flunk "entry missing but entry-found block was run" end assert_equal 0, io.pos @@ -84,4 +102,49 @@ class TestGemPackageTarReader < Gem::Package::TarTestCase ensure io.close! end + + def test_read_in_gem_data + gem_tar = util_gem_data_tar do |tar| + tar.add_file "lib/code.rb", 0o444 do |io| + io.write "# lib/code.rb" + end + end + + count = 0 + Gem::Package::TarReader.new(gem_tar).each do |entry| + next unless entry.full_name == "data.tar.gz" + + Zlib::GzipReader.wrap entry do |gzio| + Gem::Package::TarReader.new(gzio).each do |contents_entry| + assert_equal "# lib/code.rb", contents_entry.read + count += 1 + end + end + end + + assert_equal 1, count, "should have found one file" + end + + def test_seek_in_gem_data + gem_tar = util_gem_data_tar do |tar| + tar.add_file "lib/code.rb", 0o444 do |io| + io.write "# lib/code.rb" + end + tar.add_file "lib/foo.rb", 0o444 do |io| + io.write "# lib/foo.rb" + end + end + + count = 0 + Gem::Package::TarReader.new(gem_tar).seek("data.tar.gz") do |entry| + Zlib::GzipReader.wrap entry do |gzio| + Gem::Package::TarReader.new(gzio).seek("lib/foo.rb") do |contents_entry| + assert_equal "# lib/foo.rb", contents_entry.read + count += 1 + end + end + end + + assert_equal 1, count, "should have found one file" + end end diff --git a/test/rubygems/test_gem_package_tar_reader_entry.rb b/test/rubygems/test_gem_package_tar_reader_entry.rb index 031de06e09..67ab7922b5 100644 --- a/test/rubygems/test_gem_package_tar_reader_entry.rb +++ b/test/rubygems/test_gem_package_tar_reader_entry.rb @@ -1,17 +1,17 @@ # frozen_string_literal: true -require 'rubygems/package/tar_test_case' -require 'rubygems/package' + +require_relative "package/tar_test_case" +require "rubygems/package" class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase def setup super - @contents = ('a'..'z').to_a.join * 100 + @contents = ("a".."z").to_a.join * 100 @tar = String.new @tar << tar_file_header("lib/foo", "", 0, @contents.size, Time.now) - @tar << @contents - @tar << "\0" * (512 - (@tar.size % 512)) + @tar << tar_file_contents(@contents) @entry = util_entry @tar end @@ -21,8 +21,39 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase super end - def close_util_entry(entry) - entry.instance_variable_get(:@io).close! + def test_open + io = TempIO.new @tar + header = Gem::Package::TarHeader.from io + retval = Gem::Package::TarReader::Entry.open header, io, &:getc + assert_equal "a", retval + assert_equal @tar.size, io.pos, "should have read to end of entry" + ensure + io&.close! + end + + def test_open_closes_entry + io = TempIO.new @tar + header = Gem::Package::TarHeader.from io + entry = nil + Gem::Package::TarReader::Entry.open header, io do |e| + entry = e + end + assert entry.closed? + assert_raise(IOError) { entry.getc } + ensure + io&.close! + end + + def test_open_returns_entry + io = TempIO.new @tar + header = Gem::Package::TarHeader.from io + entry = Gem::Package::TarReader::Entry.open header, io + refute entry.closed? + assert_equal "a", entry.getc + assert_nil entry.close + assert entry.closed? + ensure + io&.close! end def test_bytes_read @@ -43,19 +74,19 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase assert @entry.bytes_read e = assert_raise(IOError) { @entry.eof? } - assert_equal 'closed Gem::Package::TarReader::Entry', e.message + assert_equal "closed Gem::Package::TarReader::Entry", e.message e = assert_raise(IOError) { @entry.getc } - assert_equal 'closed Gem::Package::TarReader::Entry', e.message + assert_equal "closed Gem::Package::TarReader::Entry", e.message e = assert_raise(IOError) { @entry.pos } - assert_equal 'closed Gem::Package::TarReader::Entry', e.message + assert_equal "closed Gem::Package::TarReader::Entry", e.message e = assert_raise(IOError) { @entry.read } - assert_equal 'closed Gem::Package::TarReader::Entry', e.message + assert_equal "closed Gem::Package::TarReader::Entry", e.message e = assert_raise(IOError) { @entry.rewind } - assert_equal 'closed Gem::Package::TarReader::Entry', e.message + assert_equal "closed Gem::Package::TarReader::Entry", e.message end def test_closed_eh @@ -71,22 +102,22 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase end def test_full_name - assert_equal 'lib/foo', @entry.full_name + assert_equal "lib/foo", @entry.full_name end def test_full_name_null - skip "jruby strips the null byte and does not think it's corrupt" if Gem.java_platform? + pend "jruby strips the null byte and does not think it's corrupt" if Gem.java_platform? @entry.header.prefix << "\000" e = assert_raise Gem::Package::TarInvalidError do @entry.full_name end - assert_equal 'tar is corrupt, name contains null byte', e.message + assert_equal "tar is corrupt, name contains null byte", e.message end def test_getc - assert_equal ?a, @entry.getc + assert_equal "a", @entry.getc end def test_directory_eh @@ -125,6 +156,18 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase assert_equal @contents, @entry.read end + def test_consecutive_read + expected = StringIO.new(@contents) + assert_equal expected.read, @entry.read + assert_equal expected.read, @entry.read + end + + def test_consecutive_read_bytes_past_eof + expected = StringIO.new(@contents) + assert_equal expected.read, @entry.read + assert_equal expected.read(1), @entry.read(1) + end + def test_read_big assert_equal @contents, @entry.read(@contents.size * 2) end @@ -133,13 +176,64 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase assert_equal @contents[0...100], @entry.read(100) end + def test_read_remaining + @entry.read(100) + assert_equal @contents[100..-1], @entry.read + end + def test_readpartial + assert_equal @contents[0...100], @entry.readpartial(100) + end + + def test_readpartial_to_eof + assert_equal @contents, @entry.readpartial(4096) + assert @entry.eof? + end + + def test_read_partial_buffer + buffer = "".b + @entry.readpartial(100, buffer) + assert_equal @contents[0...100], buffer + end + + def test_readpartial_past_eof + @entry.readpartial(@contents.size) + assert @entry.eof? assert_raise(EOFError) do - @entry.read(@contents.size) @entry.readpartial(1) end end + def test_read_corrupted_tar + corrupt_tar = String.new + corrupt_tar << tar_file_header("lib/foo", "", 0, 100, Time.now) + corrupt_tar << tar_file_contents("") + corrupt_entry = util_entry corrupt_tar + + assert_equal "", corrupt_entry.read(0) + assert_equal "", corrupt_entry.read, "IO.read without len should return empty string (even though it's at an unpexpected EOF)" + + corrupt_entry.rewind + + assert_nil corrupt_entry.read(100), "IO.read with len should return nil as per IO.read docs" + ensure + close_util_entry(corrupt_entry) if corrupt_entry + end + + def test_readpartial_corrupted_tar + corrupt_tar = String.new + corrupt_tar << tar_file_header("lib/foo", "", 0, 100, Time.now) + corrupt_tar << tar_file_contents("") + + corrupt_entry = util_entry corrupt_tar + + assert_raise EOFError do + corrupt_entry.readpartial(100) + end + ensure + close_util_entry(corrupt_entry) if corrupt_entry + end + def test_rewind char = @entry.getc @@ -149,4 +243,116 @@ class TestGemPackageTarReaderEntry < Gem::Package::TarTestCase assert_equal char, @entry.getc end + + def test_seek + @entry.seek(50) + assert_equal 50, @entry.pos + assert_equal @contents[50..-1], @entry.read, "read remaining after seek" + @entry.seek(-50, IO::SEEK_CUR) + assert_equal @contents.size - 50, @entry.pos + assert_equal @contents[-50..-1], @entry.read, "read after stepping back 50 from the end" + @entry.seek(0, IO::SEEK_SET) + assert_equal 0, @entry.pos + assert_equal @contents, @entry.read, "read from beginning" + @entry.seek(-10, IO::SEEK_END) + assert_equal @contents.size - 10, @entry.pos + assert_equal @contents[-10..-1], @entry.read, "read from end" + end + + def test_read_zero + expected = StringIO.new("") + assert_equal expected.read(0), @entry.read(0) + end + + def test_readpartial_zero + expected = StringIO.new("") + assert_equal expected.readpartial(0), @entry.readpartial(0) + end + + def test_zero_byte_file_read + zero_entry = util_entry(tar_file_header("foo", "", 0, 0, Time.now)) + expected = StringIO.new("") + assert_equal expected.read, zero_entry.read + ensure + close_util_entry(zero_entry) if zero_entry + end + + def test_zero_byte_file_readpartial + zero_entry = util_entry(tar_file_header("foo", "", 0, 0, Time.now)) + expected = StringIO.new("") + assert_equal expected.readpartial(0), zero_entry.readpartial(0) + ensure + close_util_entry(zero_entry) if zero_entry + end + + def test_read_from_gzip_io + tgz = util_gzip(@tar) + + Zlib::GzipReader.wrap StringIO.new(tgz) do |gzio| + entry = util_entry(gzio) + assert_equal @contents, entry.read + entry.rewind + assert_equal @contents, entry.read, "second read after rewind should read same contents" + end + end + + def test_read_from_gzip_io_with_non_zero_offset + contents2 = ("0".."9").to_a.join * 100 + @tar << tar_file_header("lib/bar", "", 0, contents2.size, Time.now) + @tar << tar_file_contents(contents2) + + tgz = util_gzip(@tar) + + Zlib::GzipReader.wrap StringIO.new(tgz) do |gzio| + util_entry(gzio).close # skip the first entry so io.pos is not 0, preventing easy rewind + entry = util_entry(gzio) + + assert_equal contents2, entry.read + entry.rewind + assert_equal contents2, entry.read, "second read after rewind should read same contents" + end + end + + def test_seek_in_gzip_io_with_non_zero_offset + contents2 = ("0".."9").to_a.join * 100 + @tar << tar_file_header("lib/bar", "", 0, contents2.size, Time.now) + @tar << tar_file_contents(contents2) + + tgz = util_gzip(@tar) + + Zlib::GzipReader.wrap StringIO.new(tgz) do |gzio| + util_entry(gzio).close # skip the first entry so io.pos is not 0 + entry = util_entry(gzio) + + entry.seek(50) + assert_equal 50, entry.pos + assert_equal contents2[50..-1], entry.read, "read remaining after seek" + entry.seek(-50, IO::SEEK_CUR) + assert_equal contents2.size - 50, entry.pos + assert_equal contents2[-50..-1], entry.read, "read after stepping back 50 from the end" + entry.seek(0, IO::SEEK_SET) + assert_equal 0, entry.pos + assert_equal contents2, entry.read, "read from beginning" + entry.seek(-10, IO::SEEK_END) + assert_equal contents2.size - 10, entry.pos + assert_equal contents2[-10..-1], entry.read, "read from end" + assert_equal contents2.size, entry.pos + end + end + + def test_seek_in_gzip_io_corrupted + @tar << tar_file_header("lib/bar", "", 0, 100, Time.now) + @tar << tar_file_contents("") + + tgz = util_gzip(@tar) + + Zlib::GzipReader.wrap StringIO.new(tgz) do |gzio| + util_entry(gzio).close # skip the first entry so io.pos is not 0 + entry = util_entry(gzio) + + assert_raise EOFError do + entry.seek(50) + end + end + end end diff --git a/test/rubygems/test_gem_package_tar_writer.rb b/test/rubygems/test_gem_package_tar_writer.rb index 925f018b2d..751ceaca81 100644 --- a/test/rubygems/test_gem_package_tar_writer.rb +++ b/test/rubygems/test_gem_package_tar_writer.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/package/tar_test_case' -require 'rubygems/package/tar_writer' + +require_relative "package/tar_test_case" +require "rubygems/package/tar_writer" class TestGemPackageTarWriter < Gem::Package::TarTestCase def setup @@ -11,7 +12,7 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase # is not set. Gem.instance_variable_set(:'@default_source_date_epoch', nil) - @data = 'abcde12345' + @data = "abcde12345" @io = TempIO.new @tar_writer = Gem::Package::TarWriter.new @io @epoch = ENV["SOURCE_DATE_EPOCH"] @@ -27,153 +28,173 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase end def test_add_file - @tar_writer.add_file 'x', 0644 do |f| - f.write 'a' * 10 - end + Time.stub :now, Time.at(1_458_518_157) do + @tar_writer.add_file "x", 0o644 do |f| + f.write "a" * 10 + end - assert_headers_equal(tar_file_header('x', '', 0644, 10, Time.now), + assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.now), @io.string[0, 512]) + end assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512] assert_equal 1024, @io.pos end def test_add_file_source_date_epoch ENV["SOURCE_DATE_EPOCH"] = "123456789" - @tar_writer.mkdir 'foo', 0644 + Time.stub :now, Time.at(1_458_518_157) do + @tar_writer.mkdir "foo", 0o644 - assert_headers_equal tar_dir_header('foo', '', 0644, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc), - @io.string[0, 512] + assert_headers_equal tar_dir_header("foo", "", 0o644, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc), + @io.string[0, 512] + end end def test_add_symlink - @tar_writer.add_symlink 'x', 'y', 0644 + Time.stub :now, Time.at(1_458_518_157) do + @tar_writer.add_symlink "x", "y", 0o644 - assert_headers_equal(tar_symlink_header('x', '', 0644, Time.now, 'y'), + assert_headers_equal(tar_symlink_header("x", "", 0o644, Time.now, "y"), @io.string[0, 512]) + end assert_equal 512, @io.pos end def test_add_symlink_source_date_epoch ENV["SOURCE_DATE_EPOCH"] = "123456789" - @tar_writer.add_symlink 'x', 'y', 0644 + Time.stub :now, Time.at(1_458_518_157) do + @tar_writer.add_symlink "x", "y", 0o644 - assert_headers_equal(tar_symlink_header('x', '', 0644, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc, 'y'), + assert_headers_equal(tar_symlink_header("x", "", 0o644, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc, "y"), @io.string[0, 512]) + end end def test_add_file_digest - digest_algorithms = Digest::SHA1.new, Digest::SHA512.new + digest_algorithms = OpenSSL::Digest::SHA1.new, OpenSSL::Digest::SHA512.new - digests = @tar_writer.add_file_digest 'x', 0644, digest_algorithms do |io| - io.write 'a' * 10 - end + Time.stub :now, Time.at(1_458_518_157) do + digests = @tar_writer.add_file_digest "x", 0o644, 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_equal "3495ff69d34671d1e15b33a63c1379fdedd3a32a", + digests["SHA1"].hexdigest + assert_equal "4714870aff6c97ca09d135834fdb58a6389a50c1" \ + "1fef8ec4afef466fb60a23ac6b7a9c92658f14df" \ + "4993d6b40a4e4d8424196afc347e97640d68de61" \ + "e1cf14b0", + digests["SHA512"].hexdigest - assert_headers_equal(tar_file_header('x', '', 0644, 10, Time.now), + assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.now), @io.string[0, 512]) - + end assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512] assert_equal 1024, @io.pos end def test_add_file_digest_multiple - digest_algorithms = [Digest::SHA1.new, Digest::SHA512.new] - - digests = @tar_writer.add_file_digest 'x', 0644, digest_algorithms do |io| - io.write 'a' * 10 - end + digest_algorithms = [OpenSSL::Digest::SHA1.new, OpenSSL::Digest::SHA512.new] - assert_equal '3495ff69d34671d1e15b33a63c1379fdedd3a32a', - digests['SHA1'].hexdigest - assert_equal '4714870aff6c97ca09d135834fdb58a6389a50c1' \ - '1fef8ec4afef466fb60a23ac6b7a9c92658f14df' \ - '4993d6b40a4e4d8424196afc347e97640d68de61' \ - 'e1cf14b0', - digests['SHA512'].hexdigest + Time.stub :now, Time.at(1_458_518_157) do + digests = @tar_writer.add_file_digest "x", 0o644, digest_algorithms do |io| + io.write "a" * 10 + end - assert_headers_equal(tar_file_header('x', '', 0644, 10, Time.now), - @io.string[0, 512]) + assert_equal "3495ff69d34671d1e15b33a63c1379fdedd3a32a", + digests["SHA1"].hexdigest + assert_equal "4714870aff6c97ca09d135834fdb58a6389a50c1" \ + "1fef8ec4afef466fb60a23ac6b7a9c92658f14df" \ + "4993d6b40a4e4d8424196afc347e97640d68de61" \ + "e1cf14b0", + digests["SHA512"].hexdigest + assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.now), + @io.string[0, 512]) + end assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512] assert_equal 1024, @io.pos end def test_add_file_signer - skip 'openssl is missing' unless Gem::HAVE_OPENSSL + pend "openssl is missing" unless Gem::HAVE_OPENSSL signer = Gem::Security::Signer.new PRIVATE_KEY, [PUBLIC_CERT] - @tar_writer.add_file_signed 'x', 0644, signer do |io| - io.write 'a' * 10 - end + Time.stub :now, Time.at(1_458_518_157) do + @tar_writer.add_file_signed "x", 0o644, signer do |io| + io.write "a" * 10 + end - assert_headers_equal(tar_file_header('x', '', 0644, 10, Time.now), - @io.string[0, 512]) + assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.now), + @io.string[0, 512]) - assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512] + assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512] - digest = signer.digest_algorithm.new - digest.update 'a' * 10 + digest = signer.digest_algorithm.new + digest.update "a" * 10 - signature = signer.sign digest.digest + signature = signer.sign digest.digest - assert_headers_equal(tar_file_header('x.sig', '', 0444, signature.length, - Time.now), - @io.string[1024, 512]) - assert_equal "#{signature}#{"\0" * (512 - signature.length)}", - @io.string[1536, 512] + assert_headers_equal(tar_file_header("x.sig", "", 0o444, signature.length, + Time.now), + @io.string[1024, 512]) + assert_equal "#{signature}#{"\0" * (512 - signature.length)}", + @io.string[1536, 512] - assert_equal 2048, @io.pos + assert_equal 2048, @io.pos + end 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 + Time.stub :now, Time.at(1_458_518_157) do + @tar_writer.add_file_signed "x", 0o644, signer do |io| + io.write "a" * 10 + end - assert_headers_equal(tar_file_header('x', '', 0644, 10, Time.now), - @io.string[0, 512]) + assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.now), + @io.string[0, 512]) + end assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512] assert_equal 1024, @io.pos end def test_add_file_simple - @tar_writer.add_file_simple 'x', 0644, 10 do |io| - io.write "a" * 10 - end + Time.stub :now, Time.at(1_458_518_157) do + @tar_writer.add_file_simple "x", 0o644, 10 do |io| + io.write "a" * 10 + end - assert_headers_equal(tar_file_header('x', '', 0644, 10, Time.now), - @io.string[0, 512]) + assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.now), + @io.string[0, 512]) - assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512] - assert_equal 1024, @io.pos + assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512] + assert_equal 1024, @io.pos + end end def test_add_file_simple_source_date_epoch ENV["SOURCE_DATE_EPOCH"] = "123456789" - @tar_writer.add_file_simple 'x', 0644, 10 do |io| - io.write "a" * 10 - end + Time.stub :now, Time.at(1_458_518_157) do + @tar_writer.add_file_simple "x", 0o644, 10 do |io| + io.write "a" * 10 + end - assert_headers_equal(tar_file_header('x', '', 0644, 10, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc), - @io.string[0, 512]) + assert_headers_equal(tar_file_header("x", "", 0o644, 10, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc), + @io.string[0, 512]) + end end def test_add_file_simple_padding - @tar_writer.add_file_simple 'x', 0, 100 + Time.stub :now, Time.at(1_458_518_157) do + @tar_writer.add_file_simple "x", 0, 100 - assert_headers_equal tar_file_header('x', '', 0, 100, Time.now), - @io.string[0, 512] + assert_headers_equal tar_file_header("x", "", 0, 100, Time.now), + @io.string[0, 512] + end assert_equal "\0" * 512, @io.string[512, 512] end @@ -202,75 +223,79 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase e = assert_raise IOError do @tar_writer.close end - assert_equal 'closed Gem::Package::TarWriter', e.message + assert_equal "closed Gem::Package::TarWriter", e.message e = assert_raise IOError do @tar_writer.flush end - assert_equal 'closed Gem::Package::TarWriter', e.message + assert_equal "closed Gem::Package::TarWriter", e.message e = assert_raise IOError do - @tar_writer.add_file 'x', 0 + @tar_writer.add_file "x", 0 end - assert_equal 'closed Gem::Package::TarWriter', e.message + assert_equal "closed Gem::Package::TarWriter", e.message e = assert_raise IOError do - @tar_writer.add_file_simple 'x', 0, 0 + @tar_writer.add_file_simple "x", 0, 0 end - assert_equal 'closed Gem::Package::TarWriter', e.message + assert_equal "closed Gem::Package::TarWriter", e.message e = assert_raise IOError do - @tar_writer.mkdir 'x', 0 + @tar_writer.mkdir "x", 0 end - assert_equal 'closed Gem::Package::TarWriter', e.message + assert_equal "closed Gem::Package::TarWriter", e.message end def test_mkdir - @tar_writer.mkdir 'foo', 0644 + Time.stub :now, Time.at(1_458_518_157) do + @tar_writer.mkdir "foo", 0o644 - assert_headers_equal tar_dir_header('foo', '', 0644, Time.now), - @io.string[0, 512] + assert_headers_equal tar_dir_header("foo", "", 0o644, Time.now), + @io.string[0, 512] - assert_equal 512, @io.pos + assert_equal 512, @io.pos + end end def test_mkdir_source_date_epoch ENV["SOURCE_DATE_EPOCH"] = "123456789" - @tar_writer.mkdir 'foo', 0644 + Time.stub :now, Time.at(1_458_518_157) do + @tar_writer.mkdir "foo", 0o644 - assert_headers_equal tar_dir_header('foo', '', 0644, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc), - @io.string[0, 512] + assert_headers_equal tar_dir_header("foo", "", 0o644, Time.at(ENV["SOURCE_DATE_EPOCH"].to_i).utc), + @io.string[0, 512] + end end def test_split_name - assert_equal ['b' * 100, 'a' * 155], - @tar_writer.split_name("#{'a' * 155}/#{'b' * 100}") + assert_equal ["b" * 100, "a" * 155], + @tar_writer.split_name("#{"a" * 155}/#{"b" * 100}") - assert_equal ["#{'qwer/' * 19}bla", 'a' * 151], - @tar_writer.split_name("#{'a' * 151}/#{'qwer/' * 19}bla") + assert_equal ["#{"qwer/" * 19}bla", "a" * 151], + @tar_writer.split_name("#{"a" * 151}/#{"qwer/" * 19}bla") names = [ - ([''] + ['123456789'] * 9 + ['1234567890']).join('/'), # 101 bytes (several pieces) - (['123456789'] * 9 + ['1234567890'] + ['']).join('/'), # 101 bytes (several pieces) - '/' * 99, - '/' * 100, - '/' * 101, - '/' * 102, + ([""] + ["123456789"] * 9 + ["1234567890"]).join("/"), # 101 bytes (several pieces) + (["123456789"] * 9 + ["1234567890"] + [""]).join("/"), # 101 bytes (several pieces) + "/" * 99, + "/" * 100, + "/" * 101, + "/" * 102, ] names.each do |name| newname, prefix = @tar_writer.split_name(name) - assert(!(newname.empty?), "split_name() returned empty name") + assert(!newname.empty?, "split_name() returned empty name") assert(newname.bytesize <= 100, "split_name() returned name longer than 100 bytes: '#{newname}' for '#{name}'") assert(prefix.bytesize <= 155, "split_name() returned prefix longer than 155 bytes: '#{prefix}' for '#{name}'") - newname = [prefix, newname].join('/') unless prefix.empty? + newname = [prefix, newname].join("/") unless prefix.empty? assert_equal name, newname end end def test_split_name_too_long_name - name = File.join 'a', 'b' * 100 - assert_equal ['b' * 100, 'a'], @tar_writer.split_name(name) + name = File.join "a", "b" * 100 + assert_equal ["b" * 100, "a"], @tar_writer.split_name(name) - name = File.join 'a', 'b' * 101 + name = File.join "a", "b" * 101 exception = assert_raise Gem::Package::TooLongFileName do @tar_writer.split_name name end @@ -278,7 +303,7 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase # note, GNU tar 1.28 is unable to handle this case too, # tested with "tar --format=ustar -cPf /tmp/foo.tartar -- /aaaaaa....a" - name = '/' + 'a' * 100 + name = "/" + "a" * 100 exception = assert_raise Gem::Package::TooLongFileName do @tar_writer.split_name name end @@ -286,10 +311,10 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase end def test_split_name_too_long_prefix - name = File.join 'a' * 155, 'b' - assert_equal ['b', 'a' * 155], @tar_writer.split_name(name) + name = File.join "a" * 155, "b" + assert_equal ["b", "a" * 155], @tar_writer.split_name(name) - name = File.join 'a' * 156, 'b' + name = File.join "a" * 156, "b" exception = assert_raise Gem::Package::TooLongFileName do @tar_writer.split_name name end @@ -297,7 +322,7 @@ class TestGemPackageTarWriter < Gem::Package::TarTestCase end def test_split_name_too_long_total - name = 'a' * 257 + name = "a" * 257 exception = assert_raise Gem::Package::TooLongFileName do @tar_writer.split_name name end diff --git a/test/rubygems/test_gem_package_task.rb b/test/rubygems/test_gem_package_task.rb index 6f217061d2..6f322ad61e 100644 --- a/test/rubygems/test_gem_package_task.rb +++ b/test/rubygems/test_gem_package_task.rb @@ -1,15 +1,12 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems' + +require_relative "helper" +require "rubygems" begin - require 'rubygems/package_task' + require "rubygems/package_task" rescue LoadError => e - raise unless e.path == 'rake/packagetask' -end - -unless defined?(Rake::PackageTask) - warn 'Skipping Gem::PackageTask tests. rake not found.' + raise unless e.path == "rake/packagetask" end class TestGemPackageTask < Gem::TestCase @@ -23,7 +20,7 @@ class TestGemPackageTask < Gem::TestCase g.authors = %w[author] g.files = %w[x] - g.summary = 'summary' + g.summary = "summary" end Rake.application = Rake::Application.new @@ -35,12 +32,12 @@ class TestGemPackageTask < Gem::TestCase assert_equal %w[x y], pkg.package_files Dir.chdir @tempdir do - FileUtils.touch 'x' - FileUtils.touch 'y' + FileUtils.touch "x" + FileUtils.touch "y" - Rake.application['package'].invoke + Rake.application["package"].invoke - assert_path_exist 'pkg/pkgr-1.2.3.gem' + assert_path_exist "pkg/pkgr-1.2.3.gem" end ensure RakeFileUtils.verbose_flag = original_rake_fileutils_verbosity @@ -53,7 +50,7 @@ class TestGemPackageTask < Gem::TestCase g.authors = %w[author] g.files = %w[x] - g.summary = 'summary' + g.summary = "summary" end _, err = capture_output do @@ -66,10 +63,10 @@ class TestGemPackageTask < Gem::TestCase assert_equal %w[x y], pkg.package_files Dir.chdir @tempdir do - FileUtils.touch 'x' - FileUtils.touch 'y' + FileUtils.touch "x" + FileUtils.touch "y" - Rake.application['package'].invoke + Rake.application["package"].invoke end end @@ -104,14 +101,14 @@ class TestGemPackageTask < Gem::TestCase def test_package_dir_path gem = Gem::Specification.new do |g| - g.name = 'nokogiri' - g.version = '1.5.0' - g.platform = 'java' + g.name = "nokogiri" + g.version = "1.5.0" + g.platform = "java" end pkg = Gem::PackageTask.new gem pkg.define - assert_equal 'pkg/nokogiri-1.5.0-java', pkg.package_dir_path + assert_equal "pkg/nokogiri-1.5.0-java", pkg.package_dir_path end end if defined?(Rake::PackageTask) diff --git a/test/rubygems/test_gem_path_support.rb b/test/rubygems/test_gem_path_support.rb index f24041a2d8..8720bcf858 100644 --- a/test/rubygems/test_gem_path_support.rb +++ b/test/rubygems/test_gem_path_support.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems' -require 'fileutils' + +require_relative "helper" +require "rubygems" +require "fileutils" class TestGemPathSupport < Gem::TestCase def setup @@ -16,7 +17,7 @@ class TestGemPathSupport < Gem::TestCase assert_equal ENV["GEM_HOME"], ps.home - expected = util_path + expected = ENV["GEM_PATH"].split(File::PATH_SEPARATOR) assert_equal expected, ps.path, "defaults to GEM_PATH" end @@ -25,7 +26,7 @@ class TestGemPathSupport < Gem::TestCase assert_equal File.join(@tempdir, "foo"), ps.home - expected = util_path + [File.join(@tempdir, 'foo')] + expected = ENV["GEM_PATH"].split(File::PATH_SEPARATOR) + [File.join(@tempdir, "foo")] assert_equal expected, ps.path end @@ -45,8 +46,8 @@ class TestGemPathSupport < Gem::TestCase assert_equal ENV["GEM_HOME"], ps.home expected = [ - File.join(@tempdir, 'foo'), - File.join(@tempdir, 'bar'), + File.join(@tempdir, "foo"), + File.join(@tempdir, "bar"), ENV["GEM_HOME"], ] @@ -65,8 +66,8 @@ class TestGemPathSupport < Gem::TestCase assert_equal ENV["GEM_HOME"], ps.home expected = [ - File.join(@tempdir, 'foo'), - File.join(@tempdir, 'bar'), + File.join(@tempdir, "foo"), + File.join(@tempdir, "bar"), ] + Gem.default_path << ENV["GEM_HOME"] assert_equal expected, ps.path @@ -83,8 +84,8 @@ class TestGemPathSupport < Gem::TestCase assert_equal ENV["GEM_HOME"], ps.home expected = [ - File.join(@tempdir, 'foo'), - File.join(@tempdir, 'bar'), + File.join(@tempdir, "foo"), + File.join(@tempdir, "bar"), ] + Gem.default_path << ENV["GEM_HOME"] assert_equal expected, ps.path @@ -97,27 +98,23 @@ class TestGemPathSupport < Gem::TestCase assert_equal File.join(@tempdir, "foo"), ps.home - expected = [File.join(@tempdir, 'foo'), File.join(@tempdir, 'bar')] + expected = [File.join(@tempdir, "foo"), File.join(@tempdir, "bar")] assert_equal expected, ps.path end end - def util_path - ENV["GEM_PATH"].split(File::PATH_SEPARATOR) - end - def test_initialize_spec ENV["GEM_SPEC_CACHE"] = nil ps = Gem::PathSupport.new ENV assert_equal Gem.default_spec_cache_dir, ps.spec_cache_dir - ENV["GEM_SPEC_CACHE"] = 'bar' + ENV["GEM_SPEC_CACHE"] = "bar" ps = Gem::PathSupport.new ENV assert_equal ENV["GEM_SPEC_CACHE"], ps.spec_cache_dir - ENV["GEM_SPEC_CACHE"] = File.join @tempdir, 'spec_cache' + ENV["GEM_SPEC_CACHE"] = File.join @tempdir, "spec_cache" ps = Gem::PathSupport.new "GEM_SPEC_CACHE" => "foo" assert_equal "foo", ps.spec_cache_dir @@ -130,7 +127,7 @@ class TestGemPathSupport < Gem::TestCase begin File.symlink(dir, symlink) rescue NotImplementedError, SystemCallError - skip 'symlinks not supported' + pend "symlinks not supported" end not_existing = "#{@tempdir}/does_not_exist" path = "#{symlink}#{File::PATH_SEPARATOR}#{not_existing}" diff --git a/test/rubygems/test_gem_platform.rb b/test/rubygems/test_gem_platform.rb index 84754402ad..e4bf882317 100644 --- a/test/rubygems/test_gem_platform.rb +++ b/test/rubygems/test_gem_platform.rb @@ -1,47 +1,48 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/platform' -require 'rbconfig' + +require_relative "helper" +require "rubygems/platform" +require "rbconfig" class TestGemPlatform < Gem::TestCase def test_self_local - util_set_arch 'i686-darwin8.10.1' + util_set_arch "i686-darwin8.10.1" assert_equal Gem::Platform.new(%w[x86 darwin 8]), Gem::Platform.local end def test_self_match Gem::Deprecate.skip_during do - assert Gem::Platform.match(nil), 'nil == ruby' - assert Gem::Platform.match(Gem::Platform.local), 'exact match' - assert Gem::Platform.match(Gem::Platform.local.to_s), '=~ match' - assert Gem::Platform.match(Gem::Platform::RUBY), 'ruby' + assert Gem::Platform.match(nil), "nil == ruby" + assert Gem::Platform.match(Gem::Platform.local), "exact match" + assert Gem::Platform.match(Gem::Platform.local.to_s), "=~ match" + assert Gem::Platform.match(Gem::Platform::RUBY), "ruby" end end def test_self_match_gem? - assert Gem::Platform.match_gem?(nil, 'json'), 'nil == ruby' - assert Gem::Platform.match_gem?(Gem::Platform.local, 'json'), 'exact match' - assert Gem::Platform.match_gem?(Gem::Platform.local.to_s, 'json'), '=~ match' - assert Gem::Platform.match_gem?(Gem::Platform::RUBY, 'json'), 'ruby' + assert Gem::Platform.match_gem?(nil, "json"), "nil == ruby" + assert Gem::Platform.match_gem?(Gem::Platform.local, "json"), "exact match" + assert Gem::Platform.match_gem?(Gem::Platform.local.to_s, "json"), "=~ match" + assert Gem::Platform.match_gem?(Gem::Platform::RUBY, "json"), "ruby" end def test_self_match_spec? - make_spec = -> platform do - util_spec 'mygem-for-platform-match_spec', '1' do |s| + make_spec = ->(platform) do + util_spec "mygem-for-platform-match_spec", "1" do |s| s.platform = platform end end - assert Gem::Platform.match_spec?(make_spec.call(nil)), 'nil == ruby' - assert Gem::Platform.match_spec?(make_spec.call(Gem::Platform.local)), 'exact match' - assert Gem::Platform.match_spec?(make_spec.call(Gem::Platform.local.to_s)), '=~ match' - assert Gem::Platform.match_spec?(make_spec.call(Gem::Platform::RUBY)), 'ruby' + assert Gem::Platform.match_spec?(make_spec.call(nil)), "nil == ruby" + assert Gem::Platform.match_spec?(make_spec.call(Gem::Platform.local)), "exact match" + assert Gem::Platform.match_spec?(make_spec.call(Gem::Platform.local.to_s)), "=~ match" + assert Gem::Platform.match_spec?(make_spec.call(Gem::Platform::RUBY)), "ruby" end def test_self_match_spec_with_match_gem_override - make_spec = -> name, platform do - util_spec name, '1' do |s| + make_spec = ->(name, platform) do + util_spec name, "1" do |s| s.platform = platform end end @@ -50,7 +51,7 @@ class TestGemPlatform < Gem::TestCase alias_method :original_match_gem?, :match_gem? def match_gem?(platform, gem_name) # e.g., sassc and libv8 are such gems, their native extensions do not use the Ruby C API - if gem_name == 'gem-with-ruby-impl-independent-precompiled-ext' + if gem_name == "gem-with-ruby-impl-independent-precompiled-ext" match_platforms?(platform, [Gem::Platform::RUBY, Gem::Platform.local]) else match_platforms?(platform, Gem.platforms) @@ -61,16 +62,16 @@ class TestGemPlatform < Gem::TestCase platforms = Gem.platforms Gem.platforms = [Gem::Platform::RUBY] begin - assert_equal true, Gem::Platform.match_spec?(make_spec.call('mygem', Gem::Platform::RUBY)) - assert_equal false, Gem::Platform.match_spec?(make_spec.call('mygem', Gem::Platform.local)) + assert_equal true, Gem::Platform.match_spec?(make_spec.call("mygem", Gem::Platform::RUBY)) + assert_equal false, Gem::Platform.match_spec?(make_spec.call("mygem", Gem::Platform.local)) - name = 'gem-with-ruby-impl-independent-precompiled-ext' + name = "gem-with-ruby-impl-independent-precompiled-ext" assert_equal true, Gem::Platform.match_spec?(make_spec.call(name, Gem::Platform.local)) ensure Gem.platforms = platforms class << Gem::Platform remove_method :match_gem? - alias_method :match_gem?, :original_match_gem? # rubocop:disable Lint/DuplicateMethods + alias_method :match_gem?, :original_match_gem? remove_method :original_match_gem? end end @@ -80,134 +81,141 @@ class TestGemPlatform < Gem::TestCase assert_equal Gem::Platform.local, Gem::Platform.new(Gem::Platform::CURRENT) assert_equal Gem::Platform::RUBY, Gem::Platform.new(Gem::Platform::RUBY) assert_equal Gem::Platform::RUBY, Gem::Platform.new(nil) - assert_equal Gem::Platform::RUBY, Gem::Platform.new('') + assert_equal Gem::Platform::RUBY, Gem::Platform.new("") end def test_initialize test_cases = { - 'amd64-freebsd6' => ['amd64', 'freebsd', '6'], - 'hppa2.0w-hpux11.31' => ['hppa2.0w', 'hpux', '11'], - 'java' => [nil, 'java', nil], - 'jruby' => [nil, 'java', nil], - 'universal-dotnet' => ['universal', 'dotnet', nil], - 'universal-dotnet2.0' => ['universal', 'dotnet', '2.0'], - 'universal-dotnet4.0' => ['universal', 'dotnet', '4.0'], - 'powerpc-aix5.3.0.0' => ['powerpc', 'aix', '5'], - 'powerpc-darwin7' => ['powerpc', 'darwin', '7'], - 'powerpc-darwin8' => ['powerpc', 'darwin', '8'], - 'powerpc-linux' => ['powerpc', 'linux', nil], - 'powerpc64-linux' => ['powerpc64', 'linux', nil], - 'sparc-solaris2.10' => ['sparc', 'solaris', '2.10'], - 'sparc-solaris2.8' => ['sparc', 'solaris', '2.8'], - 'sparc-solaris2.9' => ['sparc', 'solaris', '2.9'], - 'universal-darwin8' => ['universal', 'darwin', '8'], - 'universal-darwin9' => ['universal', 'darwin', '9'], - 'universal-macruby' => ['universal', 'macruby', nil], - 'i386-cygwin' => ['x86', 'cygwin', nil], - 'i686-darwin' => ['x86', 'darwin', nil], - 'i686-darwin8.4.1' => ['x86', 'darwin', '8'], - 'i386-freebsd4.11' => ['x86', 'freebsd', '4'], - 'i386-freebsd5' => ['x86', 'freebsd', '5'], - 'i386-freebsd6' => ['x86', 'freebsd', '6'], - 'i386-freebsd7' => ['x86', 'freebsd', '7'], - 'i386-freebsd' => ['x86', 'freebsd', nil], - 'universal-freebsd' => ['universal', 'freebsd', nil], - 'i386-java1.5' => ['x86', 'java', '1.5'], - 'x86-java1.6' => ['x86', 'java', '1.6'], - 'i386-java1.6' => ['x86', 'java', '1.6'], - 'i686-linux' => ['x86', 'linux', nil], - 'i586-linux' => ['x86', 'linux', nil], - 'i486-linux' => ['x86', 'linux', nil], - 'i386-linux' => ['x86', 'linux', nil], - 'i586-linux-gnu' => ['x86', 'linux', nil], - 'i386-linux-gnu' => ['x86', 'linux', nil], - 'i386-mingw32' => ['x86', 'mingw32', nil], - 'i386-mswin32' => ['x86', 'mswin32', nil], - 'i386-mswin32_80' => ['x86', 'mswin32', '80'], - 'i386-mswin32-80' => ['x86', 'mswin32', '80'], - 'x86-mswin32' => ['x86', 'mswin32', nil], - 'x86-mswin32_60' => ['x86', 'mswin32', '60'], - 'x86-mswin32-60' => ['x86', 'mswin32', '60'], - 'i386-netbsdelf' => ['x86', 'netbsdelf', nil], - 'i386-openbsd4.0' => ['x86', 'openbsd', '4.0'], - 'i386-solaris2.10' => ['x86', 'solaris', '2.10'], - 'i386-solaris2.8' => ['x86', 'solaris', '2.8'], - 'mswin32' => ['x86', 'mswin32', nil], - 'x86_64-linux' => ['x86_64', 'linux', nil], - 'x86_64-linux-musl' => ['x86_64', 'linux', 'musl'], - '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], + "amd64-freebsd6" => ["amd64", "freebsd", "6"], + "java" => [nil, "java", nil], + "jruby" => [nil, "java", nil], + "universal-dotnet" => ["universal", "dotnet", nil], + "universal-dotnet2.0" => ["universal", "dotnet", "2.0"], + "universal-dotnet4.0" => ["universal", "dotnet", "4.0"], + "powerpc-aix5.3.0.0" => ["powerpc", "aix", "5"], + "powerpc-darwin7" => ["powerpc", "darwin", "7"], + "powerpc-darwin8" => ["powerpc", "darwin", "8"], + "powerpc-linux" => ["powerpc", "linux", nil], + "powerpc64-linux" => ["powerpc64", "linux", nil], + "sparc-solaris2.10" => ["sparc", "solaris", "2.10"], + "sparc-solaris2.8" => ["sparc", "solaris", "2.8"], + "sparc-solaris2.9" => ["sparc", "solaris", "2.9"], + "universal-darwin8" => ["universal", "darwin", "8"], + "universal-darwin9" => ["universal", "darwin", "9"], + "universal-macruby" => ["universal", "macruby", nil], + "i386-cygwin" => ["x86", "cygwin", nil], + "i686-darwin" => ["x86", "darwin", nil], + "i686-darwin8.4.1" => ["x86", "darwin", "8"], + "i386-freebsd4.11" => ["x86", "freebsd", "4"], + "i386-freebsd5" => ["x86", "freebsd", "5"], + "i386-freebsd6" => ["x86", "freebsd", "6"], + "i386-freebsd7" => ["x86", "freebsd", "7"], + "i386-freebsd" => ["x86", "freebsd", nil], + "universal-freebsd" => ["universal", "freebsd", nil], + "i386-java1.5" => ["x86", "java", "1.5"], + "x86-java1.6" => ["x86", "java", "1.6"], + "i386-java1.6" => ["x86", "java", "1.6"], + "i686-linux" => ["x86", "linux", nil], + "i586-linux" => ["x86", "linux", nil], + "i486-linux" => ["x86", "linux", nil], + "i386-linux" => ["x86", "linux", nil], + "i586-linux-gnu" => ["x86", "linux", "gnu"], + "i386-linux-gnu" => ["x86", "linux", "gnu"], + "i386-mingw32" => ["x86", "mingw32", nil], + "x64-mingw-ucrt" => ["x64", "mingw", "ucrt"], + "i386-mswin32" => ["x86", "mswin32", nil], + "i386-mswin32_80" => ["x86", "mswin32", "80"], + "i386-mswin32-80" => ["x86", "mswin32", "80"], + "x86-mswin32" => ["x86", "mswin32", nil], + "x86-mswin32_60" => ["x86", "mswin32", "60"], + "x86-mswin32-60" => ["x86", "mswin32", "60"], + "i386-netbsdelf" => ["x86", "netbsdelf", nil], + "i386-openbsd4.0" => ["x86", "openbsd", "4.0"], + "i386-solaris2.10" => ["x86", "solaris", "2.10"], + "i386-solaris2.8" => ["x86", "solaris", "2.8"], + "mswin32" => ["x86", "mswin32", nil], + "x86_64-linux" => ["x86_64", "linux", nil], + "x86_64-linux-gnu" => ["x86_64", "linux", "gnu"], + "x86_64-linux-musl" => ["x86_64", "linux", "musl"], + "x86_64-linux-uclibc" => ["x86_64", "linux", "uclibc"], + "arm-linux-eabi" => ["arm", "linux", "eabi"], + "arm-linux-gnueabi" => ["arm", "linux", "gnueabi"], + "arm-linux-musleabi" => ["arm", "linux", "musleabi"], + "arm-linux-uclibceabi" => ["arm", "linux", "uclibceabi"], + "x86_64-openbsd3.9" => ["x86_64", "openbsd", "3.9"], + "x86_64-openbsd4.0" => ["x86_64", "openbsd", "4.0"], + "x86_64-openbsd" => ["x86_64", "openbsd", nil], } test_cases.each do |arch, expected| platform = Gem::Platform.new arch assert_equal expected, platform.to_a, arch.inspect + assert_equal expected, Gem::Platform.new(platform.to_s).to_a, arch.inspect end end def test_initialize_command_line - expected = ['x86', 'mswin32', nil] + expected = ["x86", "mswin32", nil] - platform = Gem::Platform.new 'i386-mswin32' + platform = Gem::Platform.new "i386-mswin32" - assert_equal expected, platform.to_a, 'i386-mswin32' + assert_equal expected, platform.to_a, "i386-mswin32" - expected = ['x86', 'mswin32', '80'] + expected = ["x86", "mswin32", "80"] - platform = Gem::Platform.new 'i386-mswin32-80' + platform = Gem::Platform.new "i386-mswin32-80" - assert_equal expected, platform.to_a, 'i386-mswin32-80' + assert_equal expected, platform.to_a, "i386-mswin32-80" - expected = ['x86', 'solaris', '2.10'] + expected = ["x86", "solaris", "2.10"] - platform = Gem::Platform.new 'i386-solaris-2.10' + platform = Gem::Platform.new "i386-solaris-2.10" - assert_equal expected, platform.to_a, 'i386-solaris-2.10' + assert_equal expected, platform.to_a, "i386-solaris-2.10" end def test_initialize_mswin32_vc6 - orig_RUBY_SO_NAME = RbConfig::CONFIG['RUBY_SO_NAME'] - RbConfig::CONFIG['RUBY_SO_NAME'] = 'msvcrt-ruby18' + orig_ruby_so_name = RbConfig::CONFIG["RUBY_SO_NAME"] + RbConfig::CONFIG["RUBY_SO_NAME"] = "msvcrt-ruby18" - expected = ['x86', 'mswin32', nil] + expected = ["x86", "mswin32", nil] - platform = Gem::Platform.new 'i386-mswin32' + platform = Gem::Platform.new "i386-mswin32" - assert_equal expected, platform.to_a, 'i386-mswin32 VC6' + assert_equal expected, platform.to_a, "i386-mswin32 VC6" ensure - if orig_RUBY_SO_NAME - RbConfig::CONFIG['RUBY_SO_NAME'] = orig_RUBY_SO_NAME + if orig_ruby_so_name + RbConfig::CONFIG["RUBY_SO_NAME"] = orig_ruby_so_name else - RbConfig::CONFIG.delete 'RUBY_SO_NAME' + RbConfig::CONFIG.delete "RUBY_SO_NAME" end end def test_initialize_platform - platform = Gem::Platform.new 'cpu-my_platform1' + platform = Gem::Platform.new "cpu-my_platform1" - assert_equal 'cpu', platform.cpu - assert_equal 'my_platform', platform.os - assert_equal '1', platform.version + assert_equal "cpu", platform.cpu + assert_equal "my_platform", platform.os + assert_equal "1", platform.version end def test_initialize_test - platform = Gem::Platform.new 'cpu-my_platform1' - assert_equal 'cpu', platform.cpu - assert_equal 'my_platform', platform.os - assert_equal '1', platform.version - - platform = Gem::Platform.new 'cpu-other_platform1' - assert_equal 'cpu', platform.cpu - assert_equal 'other_platform', platform.os - assert_equal '1', platform.version + platform = Gem::Platform.new "cpu-my_platform1" + assert_equal "cpu", platform.cpu + assert_equal "my_platform", platform.os + assert_equal "1", platform.version + + platform = Gem::Platform.new "cpu-other_platform1" + assert_equal "cpu", platform.cpu + assert_equal "other_platform", platform.os + assert_equal "1", platform.version end def test_to_s - if win_platform? - assert_equal 'x86-mswin32-60', Gem::Platform.local.to_s + if Gem.win_platform? + assert_equal "x86-mswin32-60", Gem::Platform.local.to_s else - assert_equal 'x86-darwin-8', Gem::Platform.local.to_s + assert_equal "x86-darwin-8", Gem::Platform.local.to_s end end @@ -224,136 +232,244 @@ class TestGemPlatform < Gem::TestCase my = Gem::Platform.new %w[cpu my_platform 1] other = Gem::Platform.new %w[cpu other_platform 1] - assert(my === my) + assert(my === my) # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands refute(other === my) refute(my === other) end def test_equals3_cpu - ppc_darwin8 = Gem::Platform.new 'powerpc-darwin8.0' - uni_darwin8 = Gem::Platform.new 'universal-darwin8.0' - x86_darwin8 = Gem::Platform.new 'i686-darwin8.0' - - util_set_arch 'powerpc-darwin8' - assert((ppc_darwin8 === Gem::Platform.local), 'powerpc =~ universal') - assert((uni_darwin8 === Gem::Platform.local), 'powerpc =~ universal') - refute((x86_darwin8 === Gem::Platform.local), 'powerpc =~ universal') - - util_set_arch 'i686-darwin8' - refute((ppc_darwin8 === Gem::Platform.local), 'powerpc =~ universal') - assert((uni_darwin8 === Gem::Platform.local), 'x86 =~ universal') - assert((x86_darwin8 === Gem::Platform.local), 'powerpc =~ universal') - - util_set_arch 'universal-darwin8' - assert((ppc_darwin8 === Gem::Platform.local), 'universal =~ ppc') - assert((uni_darwin8 === Gem::Platform.local), 'universal =~ universal') - assert((x86_darwin8 === Gem::Platform.local), 'universal =~ x86') + ppc_darwin8 = Gem::Platform.new "powerpc-darwin8.0" + uni_darwin8 = Gem::Platform.new "universal-darwin8.0" + x86_darwin8 = Gem::Platform.new "i686-darwin8.0" + + util_set_arch "powerpc-darwin8" + assert((ppc_darwin8 === Gem::Platform.local), "powerpc =~ universal") + assert((uni_darwin8 === Gem::Platform.local), "powerpc =~ universal") + refute((x86_darwin8 === Gem::Platform.local), "powerpc =~ universal") + + util_set_arch "i686-darwin8" + refute((ppc_darwin8 === Gem::Platform.local), "powerpc =~ universal") + assert((uni_darwin8 === Gem::Platform.local), "x86 =~ universal") + assert((x86_darwin8 === Gem::Platform.local), "powerpc =~ universal") + + util_set_arch "universal-darwin8" + assert((ppc_darwin8 === Gem::Platform.local), "universal =~ ppc") + assert((uni_darwin8 === Gem::Platform.local), "universal =~ universal") + assert((x86_darwin8 === Gem::Platform.local), "universal =~ x86") end def test_nil_cpu_arch_is_treated_as_universal - with_nil_arch = Gem::Platform.new [nil, 'mingw32'] - with_uni_arch = Gem::Platform.new ['universal', 'mingw32'] - with_x86_arch = Gem::Platform.new ['x86', 'mingw32'] - - assert((with_nil_arch === with_uni_arch), 'nil =~ universal') - assert((with_uni_arch === with_nil_arch), 'universal =~ nil') - assert((with_nil_arch === with_x86_arch), 'nil =~ x86') - assert((with_x86_arch === with_nil_arch), 'x86 =~ nil') + with_nil_arch = Gem::Platform.new [nil, "mingw32"] + with_uni_arch = Gem::Platform.new ["universal", "mingw32"] + with_x86_arch = Gem::Platform.new ["x86", "mingw32"] + + assert((with_nil_arch === with_uni_arch), "nil =~ universal") + assert((with_uni_arch === with_nil_arch), "universal =~ nil") + assert((with_nil_arch === with_x86_arch), "nil =~ x86") + assert((with_x86_arch === with_nil_arch), "x86 =~ nil") + end + + def test_nil_version_is_treated_as_any_version + x86_darwin_8 = Gem::Platform.new "i686-darwin8.0" + x86_darwin_nil = Gem::Platform.new "i686-darwin" + + assert((x86_darwin_8 === x86_darwin_nil), "8.0 =~ nil") + assert((x86_darwin_nil === x86_darwin_8), "nil =~ 8.0") + end + + def test_nil_version_is_stricter_for_linux_os + x86_linux = Gem::Platform.new "i686-linux" + x86_linux_gnu = Gem::Platform.new "i686-linux-gnu" + x86_linux_musl = Gem::Platform.new "i686-linux-musl" + x86_linux_uclibc = Gem::Platform.new "i686-linux-uclibc" + + # a naked linux runtime is implicit gnu, as it represents the common glibc-linked runtime + assert(x86_linux === x86_linux_gnu, "linux =~ linux-gnu") + assert(x86_linux_gnu === x86_linux, "linux-gnu =~ linux") + + # musl and explicit gnu should differ + refute(x86_linux_gnu === x86_linux_musl, "linux-gnu =~ linux-musl") + refute(x86_linux_musl === x86_linux_gnu, "linux-musl =~ linux-gnu") + + # explicit libc differ + refute(x86_linux_uclibc === x86_linux_musl, "linux-uclibc =~ linux-musl") + refute(x86_linux_musl === x86_linux_uclibc, "linux-musl =~ linux-uclibc") + + # musl host runtime accepts libc-generic or statically linked gems... + assert(x86_linux === x86_linux_musl, "linux =~ linux-musl") + # ...but implicit gnu runtime generally does not accept musl-specific gems + refute(x86_linux_musl === x86_linux, "linux-musl =~ linux") + + # other libc are not glibc compatible + refute(x86_linux === x86_linux_uclibc, "linux =~ linux-uclibc") + refute(x86_linux_uclibc === x86_linux, "linux-uclibc =~ linux") + end + + def test_eabi_version_is_stricter_for_linux_os + arm_linux_eabi = Gem::Platform.new "arm-linux-eabi" + arm_linux_gnueabi = Gem::Platform.new "arm-linux-gnueabi" + arm_linux_musleabi = Gem::Platform.new "arm-linux-musleabi" + arm_linux_uclibceabi = Gem::Platform.new "arm-linux-uclibceabi" + + # a naked linux runtime is implicit gnu, as it represents the common glibc-linked runtime + assert(arm_linux_eabi === arm_linux_gnueabi, "linux-eabi =~ linux-gnueabi") + assert(arm_linux_gnueabi === arm_linux_eabi, "linux-gnueabi =~ linux-eabi") + + # musl and explicit gnu should differ + refute(arm_linux_gnueabi === arm_linux_musleabi, "linux-gnueabi =~ linux-musleabi") + refute(arm_linux_musleabi === arm_linux_gnueabi, "linux-musleabi =~ linux-gnueabi") + + # explicit libc differ + refute(arm_linux_uclibceabi === arm_linux_musleabi, "linux-uclibceabi =~ linux-musleabi") + refute(arm_linux_musleabi === arm_linux_uclibceabi, "linux-musleabi =~ linux-uclibceabi") + + # musl host runtime accepts libc-generic or statically linked gems... + assert(arm_linux_eabi === arm_linux_musleabi, "linux-eabi =~ linux-musleabi") + # ...but implicit gnu runtime generally does not accept musl-specific gems + refute(arm_linux_musleabi === arm_linux_eabi, "linux-musleabi =~ linux-eabi") + + # other libc are not glibc compatible + refute(arm_linux_eabi === arm_linux_uclibceabi, "linux-eabi =~ linux-uclibceabi") + refute(arm_linux_uclibceabi === arm_linux_eabi, "linux-uclibceabi =~ linux-eabi") + end + + def test_eabi_and_nil_version_combination_strictness + arm_linux = Gem::Platform.new "arm-linux" + arm_linux_eabi = Gem::Platform.new "arm-linux-eabi" + arm_linux_eabihf = Gem::Platform.new "arm-linux-eabihf" + arm_linux_gnueabi = Gem::Platform.new "arm-linux-gnueabi" + arm_linux_gnueabihf = Gem::Platform.new "arm-linux-gnueabihf" + arm_linux_musleabi = Gem::Platform.new "arm-linux-musleabi" + arm_linux_musleabihf = Gem::Platform.new "arm-linux-musleabihf" + arm_linux_uclibceabi = Gem::Platform.new "arm-linux-uclibceabi" + arm_linux_uclibceabihf = Gem::Platform.new "arm-linux-uclibceabihf" + + # generic arm host runtime with eabi modifier accepts generic arm gems + assert(arm_linux === arm_linux_eabi, "arm-linux =~ arm-linux-eabi") + assert(arm_linux === arm_linux_eabihf, "arm-linux =~ arm-linux-eabihf") + + # explicit gnu arm host runtime with eabi modifier accepts generic arm gems + assert(arm_linux === arm_linux_gnueabi, "arm-linux =~ arm-linux-gnueabi") + assert(arm_linux === arm_linux_gnueabihf, "arm-linux =~ arm-linux-gnueabihf") + + # musl arm host runtime accepts libc-generic or statically linked gems... + assert(arm_linux === arm_linux_musleabi, "arm-linux =~ arm-linux-musleabi") + assert(arm_linux === arm_linux_musleabihf, "arm-linux =~ arm-linux-musleabihf") + + # other libc arm hosts are not glibc compatible + refute(arm_linux === arm_linux_uclibceabi, "arm-linux =~ arm-linux-uclibceabi") + refute(arm_linux === arm_linux_uclibceabihf, "arm-linux =~ arm-linux-uclibceabihf") end def test_equals3_cpu_arm - arm = Gem::Platform.new 'arm-linux' - armv5 = Gem::Platform.new 'armv5-linux' - armv7 = Gem::Platform.new 'armv7-linux' - - util_set_arch 'armv5-linux' - assert((arm === Gem::Platform.local), 'arm === armv5') - assert((armv5 === Gem::Platform.local), 'armv5 === armv5') - refute((armv7 === Gem::Platform.local), 'armv7 === armv5') - refute((Gem::Platform.local === arm), 'armv5 === arm') - - util_set_arch 'armv7-linux' - assert((arm === Gem::Platform.local), 'arm === armv7') - refute((armv5 === Gem::Platform.local), 'armv5 === armv7') - assert((armv7 === Gem::Platform.local), 'armv7 === armv7') - refute((Gem::Platform.local === arm), 'armv7 === arm') + arm = Gem::Platform.new "arm-linux" + armv5 = Gem::Platform.new "armv5-linux" + armv7 = Gem::Platform.new "armv7-linux" + + util_set_arch "armv5-linux" + assert((arm === Gem::Platform.local), "arm === armv5") + assert((armv5 === Gem::Platform.local), "armv5 === armv5") + refute((armv7 === Gem::Platform.local), "armv7 === armv5") + refute((Gem::Platform.local === arm), "armv5 === arm") + + util_set_arch "armv7-linux" + assert((arm === Gem::Platform.local), "arm === armv7") + refute((armv5 === Gem::Platform.local), "armv5 === armv7") + assert((armv7 === Gem::Platform.local), "armv7 === armv7") + refute((Gem::Platform.local === arm), "armv7 === arm") + end + + def test_equals3_universal_mingw + uni_mingw = Gem::Platform.new "universal-mingw" + mingw32 = Gem::Platform.new "x64-mingw32" + mingw_ucrt = Gem::Platform.new "x64-mingw-ucrt" + + util_set_arch "x64-mingw32" + assert((uni_mingw === Gem::Platform.local), "uni_mingw === mingw32") + assert((mingw32 === Gem::Platform.local), "mingw32 === mingw32") + refute((mingw_ucrt === Gem::Platform.local), "mingw32 === mingw_ucrt") + + util_set_arch "x64-mingw-ucrt" + assert((uni_mingw === Gem::Platform.local), "uni_mingw === mingw32") + assert((mingw_ucrt === Gem::Platform.local), "mingw_ucrt === mingw_ucrt") + refute((mingw32 === Gem::Platform.local), "mingw32 === mingw_ucrt") end def test_equals3_version - util_set_arch 'i686-darwin8' + util_set_arch "i686-darwin8" - x86_darwin = Gem::Platform.new ['x86', 'darwin', nil] - x86_darwin7 = Gem::Platform.new ['x86', 'darwin', '7'] - x86_darwin8 = Gem::Platform.new ['x86', 'darwin', '8'] - x86_darwin9 = Gem::Platform.new ['x86', 'darwin', '9'] + x86_darwin = Gem::Platform.new ["x86", "darwin", nil] + x86_darwin7 = Gem::Platform.new ["x86", "darwin", "7"] + x86_darwin8 = Gem::Platform.new ["x86", "darwin", "8"] + x86_darwin9 = Gem::Platform.new ["x86", "darwin", "9"] - assert((x86_darwin === Gem::Platform.local), 'x86_darwin === x86_darwin8') - assert((x86_darwin8 === Gem::Platform.local), 'x86_darwin8 === x86_darwin8') + assert((x86_darwin === Gem::Platform.local), "x86_darwin === x86_darwin8") + assert((x86_darwin8 === Gem::Platform.local), "x86_darwin8 === x86_darwin8") - refute((x86_darwin7 === Gem::Platform.local), 'x86_darwin7 === x86_darwin8') - refute((x86_darwin9 === Gem::Platform.local), 'x86_darwin9 === x86_darwin8') + refute((x86_darwin7 === Gem::Platform.local), "x86_darwin7 === x86_darwin8") + refute((x86_darwin9 === Gem::Platform.local), "x86_darwin9 === x86_darwin8") end def test_equals_tilde - util_set_arch 'i386-mswin32' + util_set_arch "i386-mswin32" - assert_local_match 'mswin32' - assert_local_match 'i386-mswin32' + assert_local_match "mswin32" + assert_local_match "i386-mswin32" # oddballs - assert_local_match 'i386-mswin32-mq5.3' - assert_local_match 'i386-mswin32-mq6' - refute_local_match 'win32-1.8.2-VC7' - refute_local_match 'win32-1.8.4-VC6' - refute_local_match 'win32-source' - refute_local_match 'windows' - - util_set_arch 'i686-linux' - assert_local_match 'i486-linux' - assert_local_match 'i586-linux' - assert_local_match 'i686-linux' - - util_set_arch 'i686-darwin8' - assert_local_match 'i686-darwin8.4.1' - assert_local_match 'i686-darwin8.8.2' - - util_set_arch 'java' - assert_local_match 'java' - assert_local_match 'jruby' - - util_set_arch 'universal-dotnet2.0' - assert_local_match 'universal-dotnet' - assert_local_match 'universal-dotnet-2.0' - refute_local_match 'universal-dotnet-4.0' - assert_local_match 'dotnet' - assert_local_match 'dotnet-2.0' - refute_local_match 'dotnet-4.0' - - util_set_arch 'universal-dotnet4.0' - assert_local_match 'universal-dotnet' - refute_local_match 'universal-dotnet-2.0' - assert_local_match 'universal-dotnet-4.0' - assert_local_match 'dotnet' - refute_local_match 'dotnet-2.0' - assert_local_match 'dotnet-4.0' - - util_set_arch 'universal-macruby-1.0' - assert_local_match 'universal-macruby' - assert_local_match 'macruby' - refute_local_match 'universal-macruby-0.10' - assert_local_match 'universal-macruby-1.0' - - util_set_arch 'powerpc-darwin' - assert_local_match 'powerpc-darwin' - - util_set_arch 'powerpc-darwin7' - assert_local_match 'powerpc-darwin7.9.0' - - util_set_arch 'powerpc-darwin8' - assert_local_match 'powerpc-darwin8.10.0' - - util_set_arch 'sparc-solaris2.8' - assert_local_match 'sparc-solaris2.8-mq5.3' + assert_local_match "i386-mswin32-mq5.3" + assert_local_match "i386-mswin32-mq6" + refute_local_match "win32-1.8.2-VC7" + refute_local_match "win32-1.8.4-VC6" + refute_local_match "win32-source" + refute_local_match "windows" + + util_set_arch "i686-linux" + assert_local_match "i486-linux" + assert_local_match "i586-linux" + assert_local_match "i686-linux" + + util_set_arch "i686-darwin8" + assert_local_match "i686-darwin8.4.1" + assert_local_match "i686-darwin8.8.2" + + util_set_arch "java" + assert_local_match "java" + assert_local_match "jruby" + + util_set_arch "universal-dotnet2.0" + assert_local_match "universal-dotnet" + assert_local_match "universal-dotnet-2.0" + refute_local_match "universal-dotnet-4.0" + assert_local_match "dotnet" + assert_local_match "dotnet-2.0" + refute_local_match "dotnet-4.0" + + util_set_arch "universal-dotnet4.0" + assert_local_match "universal-dotnet" + refute_local_match "universal-dotnet-2.0" + assert_local_match "universal-dotnet-4.0" + assert_local_match "dotnet" + refute_local_match "dotnet-2.0" + assert_local_match "dotnet-4.0" + + util_set_arch "universal-macruby-1.0" + assert_local_match "universal-macruby" + assert_local_match "macruby" + refute_local_match "universal-macruby-0.10" + assert_local_match "universal-macruby-1.0" + + util_set_arch "powerpc-darwin" + assert_local_match "powerpc-darwin" + + util_set_arch "powerpc-darwin7" + assert_local_match "powerpc-darwin7.9.0" + + util_set_arch "powerpc-darwin8" + assert_local_match "powerpc-darwin8.10.0" + + util_set_arch "sparc-solaris2.8" + assert_local_match "sparc-solaris2.8-mq5.3" end def test_inspect @@ -364,6 +480,15 @@ class TestGemPlatform < Gem::TestCase assert_equal 1, result.scan(/@version=/).size end + def test_gem_platform_match_with_string_argument + util_set_arch "x86_64-linux-musl" + + Gem::Deprecate.skip_during do + assert(Gem::Platform.match(Gem::Platform.new("x86_64-linux")), "should match Gem::Platform") + assert(Gem::Platform.match("x86_64-linux"), "should match String platform") + end + end + def assert_local_match(name) assert_match Gem::Platform.local, name end diff --git a/test/rubygems/test_gem_rdoc.rb b/test/rubygems/test_gem_rdoc.rb index d33e61a010..f9b1df6cd5 100644 --- a/test/rubygems/test_gem_rdoc.rb +++ b/test/rubygems/test_gem_rdoc.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true -require 'rubygems' -require 'rubygems/test_case' -require 'rubygems/rdoc' + +require "rubygems" +require_relative "helper" +require "rubygems/rdoc" class TestGemRDoc < Gem::TestCase Gem::RDoc.load_rdoc @@ -9,13 +10,13 @@ class TestGemRDoc < Gem::TestCase def setup super - @a = util_spec 'a' do |s| + @a = util_spec "a" do |s| s.rdoc_options = %w[--main MyTitle] s.extra_rdoc_files = %w[README] end - write_file File.join(@tempdir, 'lib', 'a.rb') - write_file File.join(@tempdir, 'README') + write_file File.join(@tempdir, "lib", "a.rb") + write_file File.join(@tempdir, "README") install_gem @a @@ -24,7 +25,7 @@ class TestGemRDoc < Gem::TestCase begin Gem::RDoc.load_rdoc rescue Gem::DocumentError => e - skip e.message + pend e.message end Gem.configuration[:rdoc] = nil @@ -70,14 +71,14 @@ class TestGemRDoc < Gem::TestCase def test_rdoc_installed? refute @hook.rdoc_installed? - FileUtils.mkdir_p @a.doc_dir 'rdoc' + FileUtils.mkdir_p @a.doc_dir "rdoc" assert @hook.rdoc_installed? end def test_remove - FileUtils.mkdir_p @a.doc_dir 'rdoc' - FileUtils.mkdir_p @a.doc_dir 'ri' + FileUtils.mkdir_p @a.doc_dir "rdoc" + FileUtils.mkdir_p @a.doc_dir "ri" @hook.remove @@ -88,8 +89,8 @@ class TestGemRDoc < Gem::TestCase end def test_remove_unwritable - skip 'chmod not supported' if Gem.win_platform? - skip 'skipped in root privilege' if Process.uid.zero? + pend "chmod not supported" if Gem.win_platform? + pend "skipped in root privilege" if Process.uid.zero? FileUtils.mkdir_p @a.base_dir FileUtils.chmod 0, @a.base_dir @@ -99,13 +100,13 @@ class TestGemRDoc < Gem::TestCase assert_equal @a.base_dir, e.directory ensure - FileUtils.chmod(0755, @a.base_dir) if File.directory?(@a.base_dir) + FileUtils.chmod(0o755, @a.base_dir) if File.directory?(@a.base_dir) end def test_ri_installed? refute @hook.ri_installed? - FileUtils.mkdir_p @a.doc_dir 'ri' + FileUtils.mkdir_p @a.doc_dir "ri" assert @hook.ri_installed? end @@ -117,8 +118,8 @@ class TestGemRDoc < Gem::TestCase end def test_setup_unwritable - skip 'chmod not supported' if Gem.win_platform? - skip 'skipped in root privilege' if Process.uid.zero? + pend "chmod not supported" if Gem.win_platform? + pend "skipped in root privilege" if Process.uid.zero? FileUtils.mkdir_p @a.doc_dir FileUtils.chmod 0, @a.doc_dir @@ -129,7 +130,7 @@ class TestGemRDoc < Gem::TestCase assert_equal @a.doc_dir, e.directory ensure if File.exist? @a.doc_dir - FileUtils.chmod 0755, @a.doc_dir + FileUtils.chmod 0o755, @a.doc_dir FileUtils.rm_r @a.doc_dir end end diff --git a/test/rubygems/test_gem_remote_fetcher.rb b/test/rubygems/test_gem_remote_fetcher.rb index 81ec688fca..e71b2f5ff6 100644 --- a/test/rubygems/test_gem_remote_fetcher.rb +++ b/test/rubygems/test_gem_remote_fetcher.rb @@ -1,15 +1,16 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'webrick' -require 'webrick/https' if Gem::HAVE_OPENSSL +require_relative "helper" + +require "webrick" +require "webrick/https" if Gem::HAVE_OPENSSL unless Gem::HAVE_OPENSSL - warn 'Skipping Gem::RemoteFetcher tests. openssl not found.' + warn "Skipping Gem::RemoteFetcher tests. openssl not found." end -require 'rubygems/remote_fetcher' -require 'rubygems/package' +require "rubygems/remote_fetcher" +require "rubygems/package" # = Testing Proxy Settings # @@ -28,7 +29,7 @@ require 'rubygems/package' class TestGemRemoteFetcher < Gem::TestCase include Gem::DefaultUserInteraction - SERVER_DATA = <<-EOY.freeze + SERVER_DATA = <<-EOY --- !ruby/object:Gem::Cache gems: rake-0.4.11: !ruby/object:Gem::Specification @@ -69,7 +70,7 @@ gems: dependencies: [] EOY - PROXY_DATA = SERVER_DATA.gsub(/0.4.11/, '0.4.2') + PROXY_DATA = SERVER_DATA.gsub(/0.4.11/, "0.4.2") # Generated via: # x = OpenSSL::PKey::DH.new(2048) # wait a while... @@ -104,11 +105,11 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== @cache_dir = File.join @gemhome, "cache" # TODO: why does the remote fetcher need it written to disk? - @a1, @a1_gem = util_gem 'a', '1' do |s| - s.executables << 'a_bin' + @a1, @a1_gem = util_gem "a", "1" do |s| + s.executables << "a_bin" end - @a1.loaded_from = File.join(@gemhome, 'specifications', @a1.full_name) + @a1.loaded_from = File.join(@gemhome, "specifications", @a1.full_name) Gem::RemoteFetcher.fetcher = nil @stub_ui = Gem::MockGemUi.new @@ -130,7 +131,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== end def test_self_fetcher_with_proxy - proxy_uri = 'http://proxy.example.com' + proxy_uri = "http://proxy.example.com" Gem.configuration[:http_proxy] = proxy_uri Gem::RemoteFetcher.fetcher = nil @@ -149,39 +150,54 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== @fetcher.fetch_path("gems.example.com/yaml", nil, true) end - assert_equal 'uri scheme is invalid: nil', e.message + assert_equal "uri scheme is invalid: nil", e.message end def test_no_proxy use_ui @stub_ui do assert_data_from_server @fetcher.fetch_path(@server_uri) response = @fetcher.fetch_path(@server_uri, nil, true) - assert_equal SERVER_DATA.size, response['content-length'].to_i + assert_equal SERVER_DATA.size, response["content-length"].to_i end end def test_cache_update_path - uri = URI 'http://example/file' - path = File.join @tempdir, 'file' + uri = Gem::URI "http://example/file" + path = File.join @tempdir, "file" - fetcher = util_fuck_with_fetcher 'hello' + fetcher = util_fuck_with_fetcher "hello" data = fetcher.cache_update_path uri, path - assert_equal 'hello', data + assert_equal "hello", data + + assert_equal "hello", File.read(path) + end + + def test_cache_update_path_with_utf8_internal_encoding + with_internal_encoding("UTF-8") do + uri = Gem::URI "http://example/file" + path = File.join @tempdir, "file" + data = String.new("\xC8").force_encoding(Encoding::BINARY) - assert_equal 'hello', File.read(path) + fetcher = util_fuck_with_fetcher data + + written_data = fetcher.cache_update_path uri, path + + assert_equal data, written_data + assert_equal data, File.binread(path) + end end def test_cache_update_path_no_update - uri = URI 'http://example/file' - path = File.join @tempdir, 'file' + uri = Gem::URI "http://example/file" + path = File.join @tempdir, "file" - fetcher = util_fuck_with_fetcher 'hello' + fetcher = util_fuck_with_fetcher "hello" data = fetcher.cache_update_path uri, path, false - assert_equal 'hello', data + assert_equal "hello", data assert_path_not_exist path end @@ -190,12 +206,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== fetcher = Gem::RemoteFetcher.fetcher fetcher.instance_variable_set :@test_data, data - unless blow - def fetcher.fetch_path(arg, *rest) - @test_arg = arg - @test_data - end - else + if blow def fetcher.fetch_path(arg, *rest) # OMG I'm such an ass class << self; remove_method :fetch_path; end @@ -204,7 +215,12 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== @test_data end - raise Gem::RemoteFetcher::FetchError.new("haha!", '') + raise Gem::RemoteFetcher::FetchError.new("haha!", "") + end + else + def fetcher.fetch_path(arg, *rest) + @test_arg = arg + @test_data end end @@ -213,14 +229,14 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_download a1_data = nil - File.open @a1_gem, 'rb' do |fp| + File.open @a1_gem, "rb" do |fp| a1_data = fp.read end fetcher = util_fuck_with_fetcher a1_data a1_cache_gem = @a1.cache_file - assert_equal a1_cache_gem, fetcher.download(@a1, 'http://gems.example.com') + assert_equal a1_cache_gem, fetcher.download(@a1, "http://gems.example.com") assert_equal("http://gems.example.com/gems/a-1.gem", fetcher.instance_variable_get(:@test_arg).to_s) assert File.exist?(a1_cache_gem) @@ -228,29 +244,59 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_download_with_auth a1_data = nil - File.open @a1_gem, 'rb' do |fp| + File.open @a1_gem, "rb" do |fp| a1_data = fp.read end fetcher = util_fuck_with_fetcher a1_data a1_cache_gem = @a1.cache_file - assert_equal a1_cache_gem, fetcher.download(@a1, 'http://user:password@gems.example.com') + assert_equal a1_cache_gem, fetcher.download(@a1, "http://user:password@gems.example.com") assert_equal("http://user:password@gems.example.com/gems/a-1.gem", fetcher.instance_variable_get(:@test_arg).to_s) assert File.exist?(a1_cache_gem) end + def test_download_with_token + a1_data = nil + File.open @a1_gem, "rb" do |fp| + a1_data = fp.read + end + + fetcher = util_fuck_with_fetcher a1_data + + a1_cache_gem = @a1.cache_file + assert_equal a1_cache_gem, fetcher.download(@a1, "http://token@gems.example.com") + assert_equal("http://token@gems.example.com/gems/a-1.gem", + fetcher.instance_variable_get(:@test_arg).to_s) + assert File.exist?(a1_cache_gem) + end + + def test_download_with_x_oauth_basic + a1_data = nil + File.open @a1_gem, "rb" do |fp| + a1_data = fp.read + end + + fetcher = util_fuck_with_fetcher a1_data + + a1_cache_gem = @a1.cache_file + assert_equal a1_cache_gem, fetcher.download(@a1, "http://token:x-oauth-basic@gems.example.com") + assert_equal("http://token:x-oauth-basic@gems.example.com/gems/a-1.gem", + fetcher.instance_variable_get(:@test_arg).to_s) + assert File.exist?(a1_cache_gem) + end + def test_download_with_encoded_auth a1_data = nil - File.open @a1_gem, 'rb' do |fp| + File.open @a1_gem, "rb" do |fp| a1_data = fp.read end fetcher = util_fuck_with_fetcher a1_data a1_cache_gem = @a1.cache_file - assert_equal a1_cache_gem, fetcher.download(@a1, 'http://user:%25pas%25sword@gems.example.com') + assert_equal a1_cache_gem, fetcher.download(@a1, "http://user:%25pas%25sword@gems.example.com") assert_equal("http://user:%25pas%25sword@gems.example.com/gems/a-1.gem", fetcher.instance_variable_get(:@test_arg).to_s) assert File.exist?(a1_cache_gem) @@ -261,10 +307,11 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== inst = Gem::RemoteFetcher.fetcher - assert_equal @a1.cache_file, inst.download(@a1, 'http://gems.example.com') + assert_equal @a1.cache_file, inst.download(@a1, "http://gems.example.com") end def test_download_local + omit "doesn't work if tempdir has +" if @tempdir.include?("+") FileUtils.mv @a1_gem, @tempdir local_path = File.join @tempdir, @a1.file_name inst = nil @@ -277,7 +324,8 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== end def test_download_local_space - space_path = File.join @tempdir, 'space path' + omit "doesn't work if tempdir has +" if @tempdir.include?("+") + space_path = File.join @tempdir, "space path" FileUtils.mkdir space_path FileUtils.mv @a1_gem, space_path local_path = File.join space_path, @a1.file_name @@ -291,17 +339,15 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== end def test_download_install_dir - a1_data = File.open @a1_gem, 'rb' do |fp| - fp.read - end + a1_data = File.open @a1_gem, "rb", &:read fetcher = util_fuck_with_fetcher a1_data - install_dir = File.join @tempdir, 'more_gems' + install_dir = File.join @tempdir, "more_gems" a1_cache_gem = File.join install_dir, "cache", @a1.file_name FileUtils.mkdir_p(File.dirname(a1_cache_gem)) - actual = fetcher.download(@a1, 'http://gems.example.com', install_dir) + actual = fetcher.download(@a1, "http://gems.example.com", install_dir) assert_equal a1_cache_gem, actual assert_equal("http://gems.example.com/gems/a-1.gem", @@ -310,14 +356,19 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== assert File.exist?(a1_cache_gem) end - unless win_platform? || Process.uid.zero? # File.chmod doesn't work + unless Gem.win_platform? || Process.uid.zero? # File.chmod doesn't work def test_download_local_read_only + omit "doesn't work if tempdir has +" if @tempdir.include?("+") FileUtils.mv @a1_gem, @tempdir local_path = File.join @tempdir, @a1.file_name inst = nil - FileUtils.chmod 0555, @a1.cache_dir - FileUtils.mkdir_p File.join(Gem.user_dir, "cache") rescue nil - FileUtils.chmod 0555, File.join(Gem.user_dir, "cache") + FileUtils.chmod 0o555, @a1.cache_dir + begin + FileUtils.mkdir_p File.join(Gem.user_dir, "cache") + rescue StandardError + nil + end + FileUtils.chmod 0o555, File.join(Gem.user_dir, "cache") Dir.chdir @tempdir do inst = Gem::RemoteFetcher.fetcher @@ -326,35 +377,37 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== assert_equal(File.join(@tempdir, @a1.file_name), inst.download(@a1, local_path)) ensure - FileUtils.chmod 0755, File.join(Gem.user_dir, "cache") - FileUtils.chmod 0755, @a1.cache_dir + if local_path + FileUtils.chmod 0o755, File.join(Gem.user_dir, "cache") + FileUtils.chmod 0o755, @a1.cache_dir + end end def test_download_read_only - FileUtils.chmod 0555, @a1.cache_dir - FileUtils.chmod 0555, @gemhome + FileUtils.chmod 0o555, @a1.cache_dir + FileUtils.chmod 0o555, @gemhome fetcher = util_fuck_with_fetcher File.read(@a1_gem) - fetcher.download(@a1, 'http://gems.example.com') + fetcher.download(@a1, "http://gems.example.com") a1_cache_gem = File.join Gem.user_dir, "cache", @a1.file_name assert File.exist? a1_cache_gem ensure - FileUtils.chmod 0755, @gemhome - FileUtils.chmod 0755, @a1.cache_dir + FileUtils.chmod 0o755, @gemhome + FileUtils.chmod 0o755, @a1.cache_dir end end def test_download_platform_legacy - original_platform = 'old-platform' + original_platform = "old-platform" - e1, e1_gem = util_gem 'e', '1' do |s| + e1, e1_gem = util_gem "e", "1" do |s| s.platform = Gem::Platform::CURRENT s.instance_variable_set :@original_platform, original_platform end - e1.loaded_from = File.join(@gemhome, 'specifications', e1.full_name) + e1.loaded_from = File.join(@gemhome, "specifications", e1.full_name) e1_data = nil - File.open e1_gem, 'rb' do |fp| + File.open e1_gem, "rb" do |fp| e1_data = fp.read end @@ -362,7 +415,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== e1_cache_gem = e1.cache_file - assert_equal e1_cache_gem, fetcher.download(e1, 'http://gems.example.com') + assert_equal e1_cache_gem, fetcher.download(e1, "http://gems.example.com") assert_equal("http://gems.example.com/gems/#{e1.original_name}.gem", fetcher.instance_variable_get(:@test_arg).to_s) @@ -370,6 +423,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== end def test_download_same_file + omit "doesn't work if tempdir has +" if @tempdir.include?("+") FileUtils.mv @a1_gem, @tempdir local_path = File.join @tempdir, @a1.file_name inst = nil @@ -390,14 +444,14 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== inst = Gem::RemoteFetcher.fetcher e = assert_raise ArgumentError do - inst.download @a1, 'ftp://gems.rubyforge.org' + inst.download @a1, "ftp://gems.rubyforge.org" end - assert_equal 'unsupported URI scheme ftp', e.message + assert_equal "unsupported URI scheme ftp", e.message end def test_download_to_cache - @a2, @a2_gem = util_gem 'a', '2' + @a2, @a2_gem = util_gem "a", "2" util_setup_spec_fetcher @a1, @a2 @fetcher.instance_variable_set :@a1, @a1 @@ -413,7 +467,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== end end - gem = Gem::RemoteFetcher.fetcher.download_to_cache dep 'a' + gem = Gem::RemoteFetcher.fetcher.download_to_cache dep "a" assert_equal @a2.file_name, File.basename(gem) end @@ -423,10 +477,10 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== @fetcher = fetcher def fetcher.fetch_http(uri, mtime, head = nil) - Gem::Util.gzip 'foo' + Gem::Util.gzip "foo" end - assert_equal 'foo', fetcher.fetch_path(@uri + 'foo.gz') + assert_equal "foo", fetcher.fetch_path(@uri + "foo.gz") end def test_fetch_path_gzip_unmodified @@ -437,7 +491,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== nil end - assert_nil fetcher.fetch_path(@uri + 'foo.gz', Time.at(0)) + assert_nil fetcher.fetch_path(@uri + "foo.gz", Time.at(0)) end def test_fetch_path_io_error @@ -448,7 +502,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== raise EOFError end - url = 'http://example.com/uri' + url = "http://example.com/uri" e = assert_raise Gem::RemoteFetcher::FetchError do fetcher.fetch_path url @@ -466,7 +520,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== raise SocketError end - url = 'http://example.com/uri' + url = "http://example.com/uri" e = assert_raise Gem::RemoteFetcher::FetchError do fetcher.fetch_path url @@ -481,17 +535,17 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== @fetcher = fetcher def fetcher.fetch_http(uri, mtime = nil, head = nil) - raise Errno::ECONNREFUSED, 'connect(2)' + raise Errno::ECONNREFUSED, "connect(2)" end - url = 'http://example.com/uri' + url = "http://example.com/uri" e = assert_raise Gem::RemoteFetcher::FetchError do fetcher.fetch_path url end - assert_match %r{ECONNREFUSED:.*connect\(2\) \(#{Regexp.escape url}\)\z}, - e.message + assert_match(/ECONNREFUSED:.*connect\(2\) \(#{Regexp.escape url}\)\z/, + e.message) assert_equal url, e.uri end @@ -500,17 +554,17 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== @fetcher = fetcher def fetcher.fetch_http(uri, mtime = nil, head = nil) - raise Timeout::Error, 'timed out' + raise Gem::Timeout::Error, "timed out" end - url = 'http://example.com/uri' + url = "http://example.com/uri" e = assert_raise Gem::RemoteFetcher::FetchError do fetcher.fetch_path url end - assert_match %r{Timeout::Error: timed out \(#{Regexp.escape url}\)\z}, - e.message + assert_match(/Gem::Timeout::Error: timed out \(#{Regexp.escape url}\)\z/, + e.message) assert_equal url, e.uri end @@ -519,17 +573,17 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== @fetcher = fetcher def fetcher.fetch_http(uri, mtime = nil, head = nil) - raise SocketError, 'getaddrinfo: nodename nor servname provided' + raise SocketError, "getaddrinfo: nodename nor servname provided" end - url = 'http://example.com/uri' + url = "http://example.com/uri" e = assert_raise Gem::RemoteFetcher::FetchError do fetcher.fetch_path url end - assert_match %r{SocketError: getaddrinfo: nodename nor servname provided \(#{Regexp.escape url}\)\z}, - e.message + assert_match(/SocketError: getaddrinfo: nodename nor servname provided \(#{Regexp.escape url}\)\z/, + e.message) assert_equal url, e.uri end @@ -541,7 +595,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== raise OpenSSL::SSL::SSLError end - url = 'http://example.com/uri' + url = "http://example.com/uri" e = assert_raise Gem::RemoteFetcher::FetchError do fetcher.fetch_path url @@ -559,12 +613,12 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== nil end - assert_nil fetcher.fetch_path(URI.parse(@gem_repo), Time.at(0)) + assert_nil fetcher.fetch_path(Gem::URI.parse(@gem_repo), Time.at(0)) end def test_implicit_no_proxy use_ui @stub_ui do - ENV['http_proxy'] = 'http://fakeurl:12345' + ENV["http_proxy"] = "http://fakeurl:12345" fetcher = Gem::RemoteFetcher.new :no_proxy @fetcher = fetcher assert_data_from_server fetcher.fetch_path(@server_uri) @@ -573,7 +627,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_implicit_proxy use_ui @stub_ui do - ENV['http_proxy'] = @proxy_uri + ENV["http_proxy"] = @proxy_uri fetcher = Gem::RemoteFetcher.new nil @fetcher = fetcher assert_data_from_proxy fetcher.fetch_path(@server_uri) @@ -582,7 +636,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_implicit_upper_case_proxy use_ui @stub_ui do - ENV['HTTP_PROXY'] = @proxy_uri + ENV["HTTP_PROXY"] = @proxy_uri fetcher = Gem::RemoteFetcher.new nil @fetcher = fetcher assert_data_from_proxy fetcher.fetch_path(@server_uri) @@ -600,41 +654,42 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_fetch_http fetcher = Gem::RemoteFetcher.new nil @fetcher = fetcher - url = 'http://gems.example.com/redirect' + url = "http://gems.example.com/redirect" def fetcher.request(uri, request_class, last_modified = nil) - url = 'http://gems.example.com/redirect' - unless defined? @requested - @requested = true - res = Net::HTTPMovedPermanently.new nil, 301, nil - res.add_field 'Location', url - res + url = "http://gems.example.com/redirect" + if defined? @requested + res = Gem::Net::HTTPOK.new nil, 200, nil + def res.body + "real_path" + end else - res = Net::HTTPOK.new nil, 200, nil - def res.body() 'real_path' end - res + @requested = true + res = Gem::Net::HTTPMovedPermanently.new nil, 301, nil + res.add_field "Location", url end + res end - data = fetcher.fetch_http URI.parse(url) + data = fetcher.fetch_http Gem::URI.parse(url) - assert_equal 'real_path', data + assert_equal "real_path", data end def test_fetch_http_redirects fetcher = Gem::RemoteFetcher.new nil @fetcher = fetcher - url = 'http://gems.example.com/redirect' + url = "http://gems.example.com/redirect" def fetcher.request(uri, request_class, last_modified = nil) - url = 'http://gems.example.com/redirect' - res = Net::HTTPMovedPermanently.new nil, 301, nil - res.add_field 'Location', url + url = "http://gems.example.com/redirect" + res = Gem::Net::HTTPMovedPermanently.new nil, 301, nil + res.add_field "Location", url res end e = assert_raise Gem::RemoteFetcher::FetchError do - fetcher.fetch_http URI.parse(url) + fetcher.fetch_http Gem::URI.parse(url) end assert_equal "too many redirects (#{url})", e.message @@ -643,15 +698,15 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_fetch_http_redirects_without_location fetcher = Gem::RemoteFetcher.new nil @fetcher = fetcher - url = 'http://gems.example.com/redirect' + url = "http://gems.example.com/redirect" def fetcher.request(uri, request_class, last_modified = nil) - res = Net::HTTPMovedPermanently.new nil, 301, nil + res = Gem::Net::HTTPMovedPermanently.new nil, 301, nil res end e = assert_raise Gem::RemoteFetcher::FetchError do - fetcher.fetch_http URI.parse(url) + fetcher.fetch_http Gem::URI.parse(url) end assert_equal "redirecting but no redirect location was given (#{url})", e.message @@ -659,13 +714,13 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_fetch_http_with_additional_headers ENV["http_proxy"] = @proxy_uri - ENV["no_proxy"] = URI::parse(@server_uri).host - fetcher = Gem::RemoteFetcher.new nil, nil, {"X-Captain" => "murphy"} + ENV["no_proxy"] = Gem::URI.parse(@server_uri).host + fetcher = Gem::RemoteFetcher.new nil, nil, { "X-Captain" => "murphy" } @fetcher = fetcher assert_equal "murphy", fetcher.fetch_path(@server_uri) end - def assert_fetch_s3(url, signature, token=nil, region='us-east-1', instance_profile_json=nil) + def assert_fetch_s3(url, signature, token=nil, region="us-east-1", instance_profile_json=nil) fetcher = Gem::RemoteFetcher.new nil @fetcher = fetcher $fetched_uri = nil @@ -673,13 +728,15 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def fetcher.request(uri, request_class, last_modified = nil) $fetched_uri = uri - res = Net::HTTPOK.new nil, 200, nil - def res.body() 'success' end + res = Gem::Net::HTTPOK.new nil, 200, nil + def res.body + "success" + end res end def fetcher.s3_uri_signer(uri) - require 'json' + require "json" s3_uri_signer = Gem::S3URISigner.new(uri) def s3_uri_signer.ec2_metadata_credentials_json JSON.parse($instance_profile) @@ -690,21 +747,21 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== s3_uri_signer end - data = fetcher.fetch_s3 URI.parse(url) + data = fetcher.fetch_s3 Gem::URI.parse(url) assert_equal "https://my-bucket.s3.#{region}.amazonaws.com/gems/specs.4.8.gz?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=testuser%2F20190624%2F#{region}%2Fs3%2Faws4_request&X-Amz-Date=20190624T050641Z&X-Amz-Expires=86400#{token ? "&X-Amz-Security-Token=" + token : ""}&X-Amz-SignedHeaders=host&X-Amz-Signature=#{signature}", $fetched_uri.to_s - assert_equal 'success', data + assert_equal "success", data ensure $fetched_uri = nil end def test_fetch_s3_config_creds Gem.configuration[:s3_source] = { - 'my-bucket' => {:id => 'testuser', :secret => 'testpass'}, + "my-bucket" => { id: "testuser", secret: "testpass" }, } - url = 's3://my-bucket/gems/specs.4.8.gz' - Time.stub :now, Time.at(1561353581) do - assert_fetch_s3 url, '20f974027db2f3cd6193565327a7c73457a138efb1a63ea248d185ce6827d41b' + url = "s3://my-bucket/gems/specs.4.8.gz" + Time.stub :now, Time.at(1_561_353_581) do + assert_fetch_s3 url, "20f974027db2f3cd6193565327a7c73457a138efb1a63ea248d185ce6827d41b" end ensure Gem.configuration[:s3_source] = nil @@ -712,11 +769,11 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_fetch_s3_config_creds_with_region Gem.configuration[:s3_source] = { - 'my-bucket' => {:id => 'testuser', :secret => 'testpass', :region => 'us-west-2'}, + "my-bucket" => { id: "testuser", secret: "testpass", region: "us-west-2" }, } - url = 's3://my-bucket/gems/specs.4.8.gz' - Time.stub :now, Time.at(1561353581) do - assert_fetch_s3 url, '4afc3010757f1fd143e769f1d1dabd406476a4fc7c120e9884fd02acbb8f26c9', nil, 'us-west-2' + url = "s3://my-bucket/gems/specs.4.8.gz" + Time.stub :now, Time.at(1_561_353_581) do + assert_fetch_s3 url, "4afc3010757f1fd143e769f1d1dabd406476a4fc7c120e9884fd02acbb8f26c9", nil, "us-west-2" end ensure Gem.configuration[:s3_source] = nil @@ -724,79 +781,79 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_fetch_s3_config_creds_with_token Gem.configuration[:s3_source] = { - 'my-bucket' => {:id => 'testuser', :secret => 'testpass', :security_token => 'testtoken'}, + "my-bucket" => { id: "testuser", secret: "testpass", security_token: "testtoken" }, } - url = 's3://my-bucket/gems/specs.4.8.gz' - Time.stub :now, Time.at(1561353581) do - assert_fetch_s3 url, '935160a427ef97e7630f799232b8f208c4a4e49aad07d0540572a2ad5fe9f93c', 'testtoken' + url = "s3://my-bucket/gems/specs.4.8.gz" + Time.stub :now, Time.at(1_561_353_581) do + assert_fetch_s3 url, "935160a427ef97e7630f799232b8f208c4a4e49aad07d0540572a2ad5fe9f93c", "testtoken" end ensure Gem.configuration[:s3_source] = nil end def test_fetch_s3_env_creds - ENV['AWS_ACCESS_KEY_ID'] = 'testuser' - ENV['AWS_SECRET_ACCESS_KEY'] = 'testpass' - ENV['AWS_SESSION_TOKEN'] = nil + ENV["AWS_ACCESS_KEY_ID"] = "testuser" + ENV["AWS_SECRET_ACCESS_KEY"] = "testpass" + ENV["AWS_SESSION_TOKEN"] = nil Gem.configuration[:s3_source] = { - 'my-bucket' => {:provider => 'env'}, + "my-bucket" => { provider: "env" }, } - url = 's3://my-bucket/gems/specs.4.8.gz' - Time.stub :now, Time.at(1561353581) do - assert_fetch_s3 url, '20f974027db2f3cd6193565327a7c73457a138efb1a63ea248d185ce6827d41b' + url = "s3://my-bucket/gems/specs.4.8.gz" + Time.stub :now, Time.at(1_561_353_581) do + assert_fetch_s3 url, "20f974027db2f3cd6193565327a7c73457a138efb1a63ea248d185ce6827d41b" end ensure - ENV.each_key {|key| ENV.delete(key) if key.start_with?('AWS') } + ENV.each_key {|key| ENV.delete(key) if key.start_with?("AWS") } Gem.configuration[:s3_source] = nil end def test_fetch_s3_env_creds_with_region - ENV['AWS_ACCESS_KEY_ID'] = 'testuser' - ENV['AWS_SECRET_ACCESS_KEY'] = 'testpass' - ENV['AWS_SESSION_TOKEN'] = nil + ENV["AWS_ACCESS_KEY_ID"] = "testuser" + ENV["AWS_SECRET_ACCESS_KEY"] = "testpass" + ENV["AWS_SESSION_TOKEN"] = nil Gem.configuration[:s3_source] = { - 'my-bucket' => {:provider => 'env', :region => 'us-west-2'}, + "my-bucket" => { provider: "env", region: "us-west-2" }, } - url = 's3://my-bucket/gems/specs.4.8.gz' - Time.stub :now, Time.at(1561353581) do - assert_fetch_s3 url, '4afc3010757f1fd143e769f1d1dabd406476a4fc7c120e9884fd02acbb8f26c9', nil, 'us-west-2' + url = "s3://my-bucket/gems/specs.4.8.gz" + Time.stub :now, Time.at(1_561_353_581) do + assert_fetch_s3 url, "4afc3010757f1fd143e769f1d1dabd406476a4fc7c120e9884fd02acbb8f26c9", nil, "us-west-2" end ensure - ENV.each_key {|key| ENV.delete(key) if key.start_with?('AWS') } + ENV.each_key {|key| ENV.delete(key) if key.start_with?("AWS") } Gem.configuration[:s3_source] = nil end def test_fetch_s3_env_creds_with_token - ENV['AWS_ACCESS_KEY_ID'] = 'testuser' - ENV['AWS_SECRET_ACCESS_KEY'] = 'testpass' - ENV['AWS_SESSION_TOKEN'] = 'testtoken' + ENV["AWS_ACCESS_KEY_ID"] = "testuser" + ENV["AWS_SECRET_ACCESS_KEY"] = "testpass" + ENV["AWS_SESSION_TOKEN"] = "testtoken" Gem.configuration[:s3_source] = { - 'my-bucket' => {:provider => 'env'}, + "my-bucket" => { provider: "env" }, } - url = 's3://my-bucket/gems/specs.4.8.gz' - Time.stub :now, Time.at(1561353581) do - assert_fetch_s3 url, '935160a427ef97e7630f799232b8f208c4a4e49aad07d0540572a2ad5fe9f93c', 'testtoken' + url = "s3://my-bucket/gems/specs.4.8.gz" + Time.stub :now, Time.at(1_561_353_581) do + assert_fetch_s3 url, "935160a427ef97e7630f799232b8f208c4a4e49aad07d0540572a2ad5fe9f93c", "testtoken" end ensure - ENV.each_key {|key| ENV.delete(key) if key.start_with?('AWS') } + ENV.each_key {|key| ENV.delete(key) if key.start_with?("AWS") } Gem.configuration[:s3_source] = nil end def test_fetch_s3_url_creds - url = 's3://testuser:testpass@my-bucket/gems/specs.4.8.gz' - Time.stub :now, Time.at(1561353581) do - assert_fetch_s3 url, '20f974027db2f3cd6193565327a7c73457a138efb1a63ea248d185ce6827d41b' + url = "s3://testuser:testpass@my-bucket/gems/specs.4.8.gz" + Time.stub :now, Time.at(1_561_353_581) do + assert_fetch_s3 url, "20f974027db2f3cd6193565327a7c73457a138efb1a63ea248d185ce6827d41b" end end def test_fetch_s3_instance_profile_creds Gem.configuration[:s3_source] = { - 'my-bucket' => {:provider => 'instance_profile'}, + "my-bucket" => { provider: "instance_profile" }, } - url = 's3://my-bucket/gems/specs.4.8.gz' - Time.stub :now, Time.at(1561353581) do - assert_fetch_s3 url, '20f974027db2f3cd6193565327a7c73457a138efb1a63ea248d185ce6827d41b', nil, 'us-east-1', + url = "s3://my-bucket/gems/specs.4.8.gz" + Time.stub :now, Time.at(1_561_353_581) do + assert_fetch_s3 url, "20f974027db2f3cd6193565327a7c73457a138efb1a63ea248d185ce6827d41b", nil, "us-east-1", '{"AccessKeyId": "testuser", "SecretAccessKey": "testpass"}' end ensure @@ -805,12 +862,12 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_fetch_s3_instance_profile_creds_with_region Gem.configuration[:s3_source] = { - 'my-bucket' => {:provider => 'instance_profile', :region => 'us-west-2'}, + "my-bucket" => { provider: "instance_profile", region: "us-west-2" }, } - url = 's3://my-bucket/gems/specs.4.8.gz' - Time.stub :now, Time.at(1561353581) do - assert_fetch_s3 url, '4afc3010757f1fd143e769f1d1dabd406476a4fc7c120e9884fd02acbb8f26c9', nil, 'us-west-2', + url = "s3://my-bucket/gems/specs.4.8.gz" + Time.stub :now, Time.at(1_561_353_581) do + assert_fetch_s3 url, "4afc3010757f1fd143e769f1d1dabd406476a4fc7c120e9884fd02acbb8f26c9", nil, "us-west-2", '{"AccessKeyId": "testuser", "SecretAccessKey": "testpass"}' end ensure @@ -819,12 +876,12 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_fetch_s3_instance_profile_creds_with_token Gem.configuration[:s3_source] = { - 'my-bucket' => {:provider => 'instance_profile'}, + "my-bucket" => { provider: "instance_profile" }, } - url = 's3://my-bucket/gems/specs.4.8.gz' - Time.stub :now, Time.at(1561353581) do - assert_fetch_s3 url, '935160a427ef97e7630f799232b8f208c4a4e49aad07d0540572a2ad5fe9f93c', 'testtoken', 'us-east-1', + url = "s3://my-bucket/gems/specs.4.8.gz" + Time.stub :now, Time.at(1_561_353_581) do + assert_fetch_s3 url, "935160a427ef97e7630f799232b8f208c4a4e49aad07d0540572a2ad5fe9f93c", "testtoken", "us-east-1", '{"AccessKeyId": "testuser", "SecretAccessKey": "testpass", "Token": "testtoken"}' end ensure @@ -836,42 +893,42 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== @fetcher = fetcher e = assert_raise Gem::RemoteFetcher::FetchError do - fetcher.fetch_s3 URI.parse(url) + fetcher.fetch_s3 Gem::URI.parse(url) end assert_match expected_message, e.message end def test_fetch_s3_no_source_key - url = 's3://my-bucket/gems/specs.4.8.gz' - refute_fetch_s3 url, 'no s3_source key exists in .gemrc' + url = "s3://my-bucket/gems/specs.4.8.gz" + refute_fetch_s3 url, "no s3_source key exists in .gemrc" end def test_fetch_s3_no_host Gem.configuration[:s3_source] = { - 'my-bucket' => {:id => 'testuser', :secret => 'testpass'}, + "my-bucket" => { id: "testuser", secret: "testpass" }, } - url = 's3://other-bucket/gems/specs.4.8.gz' - refute_fetch_s3 url, 'no key for host other-bucket in s3_source in .gemrc' + url = "s3://other-bucket/gems/specs.4.8.gz" + refute_fetch_s3 url, "no key for host other-bucket in s3_source in .gemrc" ensure Gem.configuration[:s3_source] = nil end def test_fetch_s3_no_id - Gem.configuration[:s3_source] = { 'my-bucket' => {:secret => 'testpass'} } + Gem.configuration[:s3_source] = { "my-bucket" => { secret: "testpass" } } - url = 's3://my-bucket/gems/specs.4.8.gz' - refute_fetch_s3 url, 's3_source for my-bucket missing id or secret' + url = "s3://my-bucket/gems/specs.4.8.gz" + refute_fetch_s3 url, "s3_source for my-bucket missing id or secret" ensure Gem.configuration[:s3_source] = nil end def test_fetch_s3_no_secret - Gem.configuration[:s3_source] = { 'my-bucket' => {:id => 'testuser'} } + Gem.configuration[:s3_source] = { "my-bucket" => { id: "testuser" } } - url = 's3://my-bucket/gems/specs.4.8.gz' - refute_fetch_s3 url, 's3_source for my-bucket missing id or secret' + url = "s3://my-bucket/gems/specs.4.8.gz" + refute_fetch_s3 url, "s3_source for my-bucket missing id or secret" ensure Gem.configuration[:s3_source] = nil end @@ -879,7 +936,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_observe_no_proxy_env_single_host use_ui @stub_ui do ENV["http_proxy"] = @proxy_uri - ENV["no_proxy"] = URI::parse(@server_uri).host + ENV["no_proxy"] = Gem::URI.parse(@server_uri).host fetcher = Gem::RemoteFetcher.new nil @fetcher = fetcher assert_data_from_server fetcher.fetch_path(@server_uri) @@ -889,7 +946,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_observe_no_proxy_env_list use_ui @stub_ui do ENV["http_proxy"] = @proxy_uri - ENV["no_proxy"] = "fakeurl.com, #{URI::parse(@server_uri).host}" + ENV["no_proxy"] = "fakeurl.com, #{Gem::URI.parse(@server_uri).host}" fetcher = Gem::RemoteFetcher.new nil @fetcher = fetcher assert_data_from_server fetcher.fetch_path(@server_uri) @@ -901,8 +958,8 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== @fetcher = fetcher assert_throws :block_called do - fetcher.request URI('http://example'), Net::HTTP::Get do |req| - assert_kind_of Net::HTTPGenericRequest, req + fetcher.request Gem::URI("http://example"), Gem::Net::HTTP::Get do |req| + assert_kind_of Gem::Net::HTTPGenericRequest, req throw :block_called end end @@ -919,38 +976,40 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_ssl_connection ssl_server = start_ssl_server - temp_ca_cert = File.join(__dir__, 'ca_cert.pem') + temp_ca_cert = File.join(__dir__, "ca_cert.pem") with_configured_fetcher(":ssl_ca_cert: #{temp_ca_cert}") do |fetcher| fetcher.fetch_path("https://localhost:#{ssl_server.config[:Port]}/yaml") end end def test_ssl_client_cert_auth_connection - ssl_server = start_ssl_server({ - :SSLVerifyClient => - OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT}) + ssl_server = start_ssl_server( + { SSLVerifyClient: OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT } + ) - temp_ca_cert = File.join(__dir__, 'ca_cert.pem') - temp_client_cert = File.join(__dir__, 'client.pem') + temp_ca_cert = File.join(__dir__, "ca_cert.pem") + temp_client_cert = File.join(__dir__, "client.pem") with_configured_fetcher( - ":ssl_ca_cert: #{temp_ca_cert}\n" + - ":ssl_client_cert: #{temp_client_cert}\n") do |fetcher| + ":ssl_ca_cert: #{temp_ca_cert}\n" \ + ":ssl_client_cert: #{temp_client_cert}\n" + ) do |fetcher| fetcher.fetch_path("https://localhost:#{ssl_server.config[:Port]}/yaml") end end def test_do_not_allow_invalid_client_cert_auth_connection - ssl_server = start_ssl_server({ - :SSLVerifyClient => - OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT}) + ssl_server = start_ssl_server( + { SSLVerifyClient: OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT } + ) - temp_ca_cert = File.join(__dir__, 'ca_cert.pem') - temp_client_cert = File.join(__dir__, 'invalid_client.pem') + temp_ca_cert = File.join(__dir__, "ca_cert.pem") + temp_client_cert = File.join(__dir__, "invalid_client.pem") with_configured_fetcher( - ":ssl_ca_cert: #{temp_ca_cert}\n" + - ":ssl_client_cert: #{temp_client_cert}\n") do |fetcher| + ":ssl_ca_cert: #{temp_ca_cert}\n" \ + ":ssl_client_cert: #{temp_client_cert}\n" + ) do |fetcher| assert_raise Gem::RemoteFetcher::FetchError do fetcher.fetch_path("https://localhost:#{ssl_server.config[:Port]}/yaml") end @@ -975,7 +1034,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def test_do_not_follow_insecure_redirect ssl_server = start_ssl_server - temp_ca_cert = File.join(__dir__, 'ca_cert.pem') + temp_ca_cert = File.join(__dir__, "ca_cert.pem") expected_error_message = "redirecting to non-https resource: #{@server_uri} (https://localhost:#{ssl_server.config[:Port]}/insecure_redirect?to=#{@server_uri})" @@ -1001,8 +1060,8 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def with_configured_fetcher(config_str = nil, &block) if config_str - temp_conf = File.join @tempdir, '.gemrc' - File.open temp_conf, 'w' do |fp| + temp_conf = File.join @tempdir, ".gemrc" + File.open temp_conf, "w" do |fp| fp.puts config_str end Gem.configuration = Gem::ConfigFile.new %W[--config-file #{temp_conf}] @@ -1035,7 +1094,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== end class NilLog < WEBrick::Log - def log(level, data) #Do nothing + def log(level, data) # Do nothing end end @@ -1070,8 +1129,7 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== @ssl_server_thread.kill.join @ssl_server_thread = nil end - utils = WEBrick::Utils # TimeoutHandler is since 1.9 - utils::TimeoutHandler.terminate if defined?(utils::TimeoutHandler.terminate) + WEBrick::Utils::TimeoutHandler.terminate end def normal_server_port @@ -1083,36 +1141,34 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== end def start_ssl_server(config = {}) - skip "starting this test server fails randomly on jruby" if Gem.java_platform? + pend "starting this test server fails randomly on jruby" if Gem.java_platform? null_logger = NilLog.new server = WEBrick::HTTPServer.new({ - :Port => 0, - :Logger => null_logger, - :AccessLog => [], - :SSLEnable => true, - :SSLCACertificateFile => File.join(__dir__, 'ca_cert.pem'), - :SSLCertificate => cert('ssl_cert.pem'), - :SSLPrivateKey => key('ssl_key.pem'), - :SSLVerifyClient => nil, - :SSLCertName => nil, + Port: 0, + Logger: null_logger, + AccessLog: [], + SSLEnable: true, + SSLCACertificateFile: File.join(__dir__, "ca_cert.pem"), + SSLCertificate: cert("ssl_cert.pem"), + SSLPrivateKey: key("ssl_key.pem"), + SSLVerifyClient: nil, + SSLCertName: nil, }.merge(config)) - server.mount_proc("/yaml") do |req, res| + server.mount_proc("/yaml") do |_req, res| res.body = "--- true\n" end server.mount_proc("/insecure_redirect") do |req, res| - res.set_redirect(WEBrick::HTTPStatus::MovedPermanently, req.query['to']) + res.set_redirect(WEBrick::HTTPStatus::MovedPermanently, req.query["to"]) end server.ssl_context.tmp_dh_callback = proc { TEST_KEY_DH2048 } t = Thread.new do - begin - server.start - rescue Exception => ex - puts "ERROR during server thread: #{ex.message}" - raise - ensure - server.shutdown - end + server.start + rescue StandardError => ex + puts "ERROR during server thread: #{ex.message}" + raise + ensure + server.shutdown end while server.status != :Running sleep 0.1 @@ -1129,43 +1185,41 @@ PeIQQkFng2VVot/WAQbv3ePqWq07g1BBcwIBAg== def start_server(data) null_logger = NilLog.new s = WEBrick::HTTPServer.new( - :Port => 0, - :DocumentRoot => nil, - :Logger => null_logger, - :AccessLog => null_logger + Port: 0, + DocumentRoot: nil, + Logger: null_logger, + AccessLog: null_logger ) - s.mount_proc("/kill") {|req, res| s.shutdown } + s.mount_proc("/kill") {|_req, _res| s.shutdown } s.mount_proc("/yaml") do |req, res| if req["X-Captain"] res.body = req["X-Captain"] elsif @enable_yaml res.body = data - res['Content-Type'] = 'text/plain' - res['content-length'] = data.size + res["Content-Type"] = "text/plain" + res["content-length"] = data.size else res.status = "404" res.body = "<h1>NOT FOUND</h1>" - res['Content-Type'] = 'text/html' + res["Content-Type"] = "text/html" end end - s.mount_proc("/yaml.Z") do |req, res| + s.mount_proc("/yaml.Z") do |_req, res| if @enable_zip res.body = Zlib::Deflate.deflate(data) - res['Content-Type'] = 'text/plain' + res["Content-Type"] = "text/plain" else res.status = "404" res.body = "<h1>NOT FOUND</h1>" - res['Content-Type'] = 'text/html' + res["Content-Type"] = "text/html" end end th = Thread.new do - begin - s.start - rescue Exception => ex - abort "ERROR during server thread: #{ex.message}" - ensure - s.shutdown - end + s.start + rescue StandardError => ex + abort "ERROR during server thread: #{ex.message}" + ensure + s.shutdown end th[:server] = s th diff --git a/test/rubygems/test_gem_request.rb b/test/rubygems/test_gem_request.rb index 47e5f97074..5e9b264dac 100644 --- a/test/rubygems/test_gem_request.rb +++ b/test/rubygems/test_gem_request.rb @@ -1,25 +1,31 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/request' -require 'ostruct' -require 'base64' + +require_relative "helper" +require "rubygems/request" +require "ostruct" unless Gem::HAVE_OPENSSL - warn 'Skipping Gem::Request tests. openssl not found.' + warn "Skipping Gem::Request tests. openssl not found." end class TestGemRequest < Gem::TestCase - CA_CERT_FILE = cert_path 'ca' - CHILD_CERT = load_cert 'child' - EXPIRED_CERT = load_cert 'expired' - PUBLIC_CERT = load_cert 'public' - PUBLIC_CERT_FILE = cert_path 'public' - SSL_CERT = load_cert 'ssl' + CA_CERT_FILE = cert_path "ca" + CHILD_CERT = load_cert "child" + EXPIRED_CERT = load_cert "expired" + PUBLIC_CERT = load_cert "public" + PUBLIC_CERT_FILE = cert_path "public" + SSL_CERT = load_cert "ssl" def make_request(uri, request_class, last_modified, proxy) Gem::Request.create_with_proxy uri, request_class, last_modified, proxy end + # This method is same code as Base64.encode64 + # We should not use Base64.encode64 because we need to avoid gem activation. + def base64_encode64(bin) + [bin].pack("m") + end + def setup @proxies = %w[http_proxy https_proxy HTTP_PROXY http_proxy_user HTTP_PROXY_USER http_proxy_pass HTTP_PROXY_PASS no_proxy NO_PROXY] @old_proxies = @proxies.map {|k| ENV[k] } @@ -28,7 +34,7 @@ class TestGemRequest < Gem::TestCase super @proxy_uri = "http://localhost:1234" - @uri = URI('http://example') + @uri = Gem::URI("http://example") @request = make_request @uri, nil, nil, nil end @@ -40,7 +46,7 @@ class TestGemRequest < Gem::TestCase end def test_initialize_proxy - proxy_uri = 'http://proxy.example.com' + proxy_uri = "http://proxy.example.com" request = make_request @uri, nil, nil, proxy_uri @@ -48,41 +54,41 @@ class TestGemRequest < Gem::TestCase end def test_initialize_proxy_URI - proxy_uri = 'http://proxy.example.com' + proxy_uri = "http://proxy.example.com" - request = make_request @uri, nil, nil, URI(proxy_uri) + request = make_request @uri, nil, nil, Gem::URI(proxy_uri) assert_equal proxy_uri, request.proxy_uri.to_s end def test_initialize_proxy_ENV - ENV['http_proxy'] = @proxy_uri - ENV['http_proxy_user'] = 'foo' - ENV['http_proxy_pass'] = 'bar' + ENV["http_proxy"] = @proxy_uri + ENV["http_proxy_user"] = "foo" + ENV["http_proxy_pass"] = "bar" request = make_request @uri, nil, nil, nil proxy = request.proxy_uri - assert_equal 'foo', proxy.user - assert_equal 'bar', proxy.password + assert_equal "foo", proxy.user + assert_equal "bar", proxy.password end def test_initialize_proxy_ENV_https - ENV['https_proxy'] = @proxy_uri + ENV["https_proxy"] = @proxy_uri - request = make_request URI('https://example'), nil, nil, nil + request = make_request Gem::URI("https://example"), nil, nil, nil proxy = request.proxy_uri - assert_equal URI(@proxy_uri), proxy + assert_equal Gem::URI(@proxy_uri), proxy end def test_proxy_ENV - ENV['http_proxy'] = "http://proxy" - ENV['https_proxy'] = "" + ENV["http_proxy"] = "http://proxy" + ENV["https_proxy"] = "" - request = make_request URI('https://example'), nil, nil, nil + request = make_request Gem::URI("https://example"), nil, nil, nil proxy = request.proxy_uri @@ -90,13 +96,13 @@ class TestGemRequest < Gem::TestCase end def test_configure_connection_for_https - connection = Net::HTTP.new 'localhost', 443 + connection = Gem::Net::HTTP.new "localhost", 443 request = Class.new(Gem::Request) do def self.get_cert_files [TestGemRequest::PUBLIC_CERT_FILE] end - end.create_with_proxy URI('https://example'), nil, nil, nil + end.create_with_proxy Gem::URI("https://example"), nil, nil, nil Gem::Request.configure_connection_for_https connection, request.cert_files @@ -106,16 +112,16 @@ class TestGemRequest < Gem::TestCase end def test_configure_connection_for_https_ssl_ca_cert - ssl_ca_cert, Gem.configuration.ssl_ca_cert = - Gem.configuration.ssl_ca_cert, CA_CERT_FILE + ssl_ca_cert = Gem.configuration.ssl_ca_cert + Gem.configuration.ssl_ca_cert = CA_CERT_FILE - connection = Net::HTTP.new 'localhost', 443 + connection = Gem::Net::HTTP.new "localhost", 443 request = Class.new(Gem::Request) do def self.get_cert_files [TestGemRequest::PUBLIC_CERT_FILE] end - end.create_with_proxy URI('https://example'), nil, nil, nil + end.create_with_proxy Gem::URI("https://example"), nil, nil, nil Gem::Request.configure_connection_for_https connection, request.cert_files @@ -128,66 +134,66 @@ class TestGemRequest < Gem::TestCase end def test_get_proxy_from_env_fallback - ENV['http_proxy'] = @proxy_uri + ENV["http_proxy"] = @proxy_uri request = make_request @uri, nil, nil, nil proxy = request.proxy_uri - assert_equal URI(@proxy_uri), proxy + assert_equal Gem::URI(@proxy_uri), proxy end def test_get_proxy_from_env_https - ENV['https_proxy'] = @proxy_uri - uri = URI('https://example') + ENV["https_proxy"] = @proxy_uri + uri = Gem::URI("https://example") request = make_request uri, nil, nil, nil proxy = request.proxy_uri - assert_equal URI(@proxy_uri), proxy + assert_equal Gem::URI(@proxy_uri), proxy end def test_get_proxy_from_env_domain - ENV['http_proxy'] = @proxy_uri - ENV['http_proxy_user'] = 'foo\user' - ENV['http_proxy_pass'] = 'my bar' + ENV["http_proxy"] = @proxy_uri + ENV["http_proxy_user"] = 'foo\user' + ENV["http_proxy_pass"] = "my bar" request = make_request @uri, nil, nil, nil proxy = request.proxy_uri assert_equal 'foo\user', Gem::UriFormatter.new(proxy.user).unescape - assert_equal 'my bar', Gem::UriFormatter.new(proxy.password).unescape + assert_equal "my bar", Gem::UriFormatter.new(proxy.password).unescape end def test_get_proxy_from_env_escape - ENV['http_proxy'] = @proxy_uri - ENV['http_proxy_user'] = 'foo@user' - ENV['http_proxy_pass'] = 'my@bar' + ENV["http_proxy"] = @proxy_uri + ENV["http_proxy_user"] = "foo@user" + ENV["http_proxy_pass"] = "my@bar" request = make_request @uri, nil, nil, nil proxy = request.proxy_uri - assert_equal 'foo%40user', proxy.user - assert_equal 'my%40bar', proxy.password + assert_equal "foo%40user", proxy.user + assert_equal "my%40bar", proxy.password end def test_get_proxy_from_env_normalize - ENV['HTTP_PROXY'] = 'fakeurl:12345' + ENV["HTTP_PROXY"] = "fakeurl:12345" request = make_request @uri, nil, nil, nil - assert_equal 'http://fakeurl:12345', request.proxy_uri.to_s + assert_equal "http://fakeurl:12345", request.proxy_uri.to_s end def test_get_proxy_from_env_empty - ENV['HTTP_PROXY'] = '' - ENV.delete 'http_proxy' + ENV["HTTP_PROXY"] = "" + ENV.delete "http_proxy" request = make_request @uri, nil, nil, nil assert_nil request.proxy_uri end def test_fetch - uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}" - response = util_stub_net_http(:body => :junk, :code => 200) do - @request = make_request(uri, Net::HTTP::Get, nil, nil) + uri = Gem::Uri.new(Gem::URI.parse("#{@gem_repo}/specs.#{Gem.marshal_version}")) + response = util_stub_net_http(body: :junk, code: 200) do + @request = make_request(uri, Gem::Net::HTTP::Get, nil, nil) @request.fetch end @@ -197,54 +203,80 @@ class TestGemRequest < Gem::TestCase end def test_fetch_basic_auth - uri = URI.parse "https://user:pass@example.rubygems/specs.#{Gem.marshal_version}" - conn = util_stub_net_http(:body => :junk, :code => 200) do |c| - @request = make_request(uri, Net::HTTP::Get, nil, nil) - @request.fetch + Gem.configuration.verbose = :really + uri = Gem::Uri.new(Gem::URI.parse("https://user:pass@example.rubygems/specs.#{Gem.marshal_version}")) + conn = util_stub_net_http(body: :junk, code: 200) do |c| + use_ui @ui do + @request = make_request(uri, Gem::Net::HTTP::Get, nil, nil) + @request.fetch + end c end - auth_header = conn.payload['Authorization'] - assert_equal "Basic #{Base64.encode64('user:pass')}".strip, auth_header + auth_header = conn.payload["Authorization"] + assert_equal "Basic #{base64_encode64("user:pass")}".strip, auth_header + assert_includes @ui.output, "GET https://user:REDACTED@example.rubygems/specs.#{Gem.marshal_version}" end def test_fetch_basic_auth_encoded - uri = URI.parse "https://user:%7BDEScede%7Dpass@example.rubygems/specs.#{Gem.marshal_version}" - conn = util_stub_net_http(:body => :junk, :code => 200) do |c| - @request = make_request(uri, Net::HTTP::Get, nil, nil) - @request.fetch + Gem.configuration.verbose = :really + uri = Gem::Uri.new(Gem::URI.parse("https://user:%7BDEScede%7Dpass@example.rubygems/specs.#{Gem.marshal_version}")) + + conn = util_stub_net_http(body: :junk, code: 200) do |c| + use_ui @ui do + @request = make_request(uri, Gem::Net::HTTP::Get, nil, nil) + @request.fetch + end c end - auth_header = conn.payload['Authorization'] - assert_equal "Basic #{Base64.encode64('user:{DEScede}pass')}".strip, auth_header + auth_header = conn.payload["Authorization"] + assert_equal "Basic #{base64_encode64("user:{DEScede}pass")}".strip, auth_header + assert_includes @ui.output, "GET https://user:REDACTED@example.rubygems/specs.#{Gem.marshal_version}" + end + + def test_fetch_basic_oauth_encoded + Gem.configuration.verbose = :really + uri = Gem::Uri.new(Gem::URI.parse("https://%7BDEScede%7Dpass:x-oauth-basic@example.rubygems/specs.#{Gem.marshal_version}")) + + conn = util_stub_net_http(body: :junk, code: 200) do |c| + use_ui @ui do + @request = make_request(uri, Gem::Net::HTTP::Get, nil, nil) + @request.fetch + end + c + end + + auth_header = conn.payload["Authorization"] + assert_equal "Basic #{base64_encode64("{DEScede}pass:x-oauth-basic")}".strip, auth_header + assert_includes @ui.output, "GET https://REDACTED:x-oauth-basic@example.rubygems/specs.#{Gem.marshal_version}" end def test_fetch_head - uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}" - response = util_stub_net_http(:body => '', :code => 200) do |conn| - @request = make_request(uri, Net::HTTP::Get, nil, nil) + uri = Gem::Uri.new(Gem::URI.parse("#{@gem_repo}/specs.#{Gem.marshal_version}")) + response = util_stub_net_http(body: "", code: 200) do |_conn| + @request = make_request(uri, Gem::Net::HTTP::Get, nil, nil) @request.fetch end assert_equal 200, response.code - assert_equal '', response.body + assert_equal "", response.body end def test_fetch_unmodified - uri = URI.parse "#{@gem_repo}/specs.#{Gem.marshal_version}" + uri = Gem::Uri.new(Gem::URI.parse("#{@gem_repo}/specs.#{Gem.marshal_version}")) t = Time.utc(2013, 1, 2, 3, 4, 5) - conn, response = util_stub_net_http(:body => '', :code => 304) do |c| - @request = make_request(uri, Net::HTTP::Get, t, nil) + conn, response = util_stub_net_http(body: "", code: 304) do |c| + @request = make_request(uri, Gem::Net::HTTP::Get, t, nil) [c, @request.fetch] end assert_equal 304, response.code - assert_equal '', response.body + assert_equal "", response.body - modified_header = conn.payload['if-modified-since'] + modified_header = conn.payload["if-modified-since"] - assert_equal 'Wed, 02 Jan 2013 03:04:05 GMT', modified_header + assert_equal "Wed, 02 Jan 2013 03:04:05 GMT", modified_header end def test_user_agent @@ -254,18 +286,18 @@ class TestGemRequest < Gem::TestCase assert_match %r{RubyGems/#{Regexp.escape Gem::VERSION}}, ua assert_match %r{ #{Regexp.escape Gem::Platform.local.to_s} }, ua assert_match %r{Ruby/#{Regexp.escape RUBY_VERSION}}, ua - assert_match %r{\(#{Regexp.escape RUBY_RELEASE_DATE} }, ua + assert_match(/\(#{Regexp.escape RUBY_RELEASE_DATE} /, ua) end def test_user_agent_engine util_save_version Object.send :remove_const, :RUBY_ENGINE - Object.send :const_set, :RUBY_ENGINE, 'vroom' + Object.send :const_set, :RUBY_ENGINE, "vroom" ua = make_request(@uri, nil, nil, nil).user_agent - assert_match %r{\) vroom}, ua + assert_match(/\) vroom/, ua) ensure util_restore_version end @@ -274,11 +306,11 @@ class TestGemRequest < Gem::TestCase util_save_version Object.send :remove_const, :RUBY_ENGINE - Object.send :const_set, :RUBY_ENGINE, 'ruby' + Object.send :const_set, :RUBY_ENGINE, "ruby" ua = make_request(@uri, nil, nil, nil).user_agent - assert_match %r{\)}, ua + assert_match(/\)/, ua) ensure util_restore_version end @@ -301,7 +333,7 @@ class TestGemRequest < Gem::TestCase Object.send :remove_const, :RUBY_PATCHLEVEL Object.send :const_set, :RUBY_PATCHLEVEL, -1 - Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION) + Object.send :remove_const, :RUBY_REVISION Object.send :const_set, :RUBY_REVISION, 6 ua = make_request(@uri, nil, nil, nil).user_agent @@ -312,46 +344,38 @@ class TestGemRequest < Gem::TestCase util_restore_version end - def test_user_agent_revision_missing - util_save_version - - Object.send :remove_const, :RUBY_PATCHLEVEL - Object.send :const_set, :RUBY_PATCHLEVEL, -1 - Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION) + def test_verify_certificate + pend if Gem.java_platform? - ua = make_request(@uri, nil, nil, nil).user_agent + error_number = OpenSSL::X509::V_ERR_OUT_OF_MEM - assert_match %r{\(#{Regexp.escape RUBY_RELEASE_DATE}\)}, ua - ensure - util_restore_version - end - - def test_verify_certificate - skip if Gem.java_platform? store = OpenSSL::X509::Store.new context = OpenSSL::X509::StoreContext.new store - context.error = OpenSSL::X509::V_ERR_OUT_OF_MEM + context.error = error_number use_ui @ui do Gem::Request.verify_certificate context end - assert_equal "ERROR: SSL verification error at depth 0: out of memory (17)\n", + assert_equal "ERROR: SSL verification error at depth 0: out of memory (#{error_number})\n", @ui.error end def test_verify_certificate_extra_message - skip if Gem.java_platform? + pend if Gem.java_platform? + + error_number = OpenSSL::X509::V_ERR_INVALID_CA + store = OpenSSL::X509::Store.new context = OpenSSL::X509::StoreContext.new store - context.error = OpenSSL::X509::V_ERR_INVALID_CA + context.error = error_number use_ui @ui do Gem::Request.verify_certificate context end expected = <<-ERROR -ERROR: SSL verification error at depth 0: invalid CA certificate (24) +ERROR: SSL verification error at depth 0: invalid CA certificate (#{error_number}) ERROR: Certificate is an invalid CA certificate ERROR @@ -460,21 +484,19 @@ ERROR: Certificate is an invalid CA certificate def util_restore_version Object.send :remove_const, :RUBY_ENGINE - Object.send :const_set, :RUBY_ENGINE, @orig_RUBY_ENGINE if - defined?(@orig_RUBY_ENGINE) + Object.send :const_set, :RUBY_ENGINE, @orig_ruby_engine Object.send :remove_const, :RUBY_PATCHLEVEL - Object.send :const_set, :RUBY_PATCHLEVEL, @orig_RUBY_PATCHLEVEL + Object.send :const_set, :RUBY_PATCHLEVEL, @orig_ruby_patchlevel - Object.send :remove_const, :RUBY_REVISION if defined?(RUBY_REVISION) - Object.send :const_set, :RUBY_REVISION, @orig_RUBY_REVISION if - defined?(@orig_RUBY_REVISION) + Object.send :remove_const, :RUBY_REVISION + Object.send :const_set, :RUBY_REVISION, @orig_ruby_revision end def util_save_version - @orig_RUBY_ENGINE = RUBY_ENGINE - @orig_RUBY_PATCHLEVEL = RUBY_PATCHLEVEL - @orig_RUBY_REVISION = RUBY_REVISION if defined? RUBY_REVISION + @orig_ruby_engine = RUBY_ENGINE + @orig_ruby_patchlevel = RUBY_PATCHLEVEL + @orig_ruby_revision = RUBY_REVISION end def util_stub_net_http(hash) @@ -489,7 +511,10 @@ ERROR: Certificate is an invalid CA certificate class Conn attr_accessor :payload - def new(*args); self; end + def new(*args) + self + end + def use_ssl=(bool); end def verify_callback=(setting); end def verify_mode=(setting); end diff --git a/test/rubygems/test_gem_request_connection_pools.rb b/test/rubygems/test_gem_request_connection_pools.rb index a6ab002396..966447bff6 100644 --- a/test/rubygems/test_gem_request_connection_pools.rb +++ b/test/rubygems/test_gem_request_connection_pools.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/request' -require 'timeout' + +require_relative "helper" +require "rubygems/request" +require "rubygems/vendored_timeout" class TestGemRequestConnectionPool < Gem::TestCase class FakeHttp @@ -17,7 +18,7 @@ class TestGemRequestConnectionPool < Gem::TestCase @old_client = Gem::Request::ConnectionPools.client Gem::Request::ConnectionPools.client = FakeHttp - @proxy = URI 'http://proxy.example' + @proxy = Gem::URI "http://proxy.example" end def teardown @@ -32,9 +33,9 @@ class TestGemRequestConnectionPool < Gem::TestCase ems.example ] - no_proxy = pools.send :no_proxy?, 'rubygems.example', env_no_proxy + no_proxy = pools.send :no_proxy?, "rubygems.example", env_no_proxy - refute no_proxy, 'mismatch' + refute no_proxy, "mismatch" end def test_to_proxy_empty_string @@ -42,13 +43,13 @@ class TestGemRequestConnectionPool < Gem::TestCase env_no_proxy = [""] - no_proxy = pools.send :no_proxy?, 'ems.example', env_no_proxy + no_proxy = pools.send :no_proxy?, "ems.example", env_no_proxy - refute no_proxy, 'mismatch' + refute no_proxy, "mismatch" end def test_checkout_same_connection - uri = URI.parse('http://example/some_endpoint') + uri = Gem::URI.parse("http://example/some_endpoint") pools = Gem::Request::ConnectionPools.new nil, [] pool = pools.pool_for uri @@ -66,13 +67,13 @@ class TestGemRequestConnectionPool < Gem::TestCase 2.no-proxy.example ] - no_proxy = pools.send :no_proxy?, '2.no-proxy.example', env_no_proxy + no_proxy = pools.send :no_proxy?, "2.no-proxy.example", env_no_proxy - assert no_proxy, 'match' + assert no_proxy, "match" - no_proxy = pools.send :no_proxy?, 'proxy.example', env_no_proxy + no_proxy = pools.send :no_proxy?, "proxy.example", env_no_proxy - refute no_proxy, 'mismatch' + refute no_proxy, "mismatch" end def test_to_proxy_eh_wildcard @@ -82,31 +83,31 @@ class TestGemRequestConnectionPool < Gem::TestCase .no-proxy.example ] - no_proxy = pools.send :no_proxy?, '2.no-proxy.example', env_no_proxy + no_proxy = pools.send :no_proxy?, "2.no-proxy.example", env_no_proxy - assert no_proxy, 'wildcard matching subdomain' + assert no_proxy, "wildcard matching subdomain" - no_proxy = pools.send :no_proxy?, 'no-proxy.example', env_no_proxy + no_proxy = pools.send :no_proxy?, "no-proxy.example", env_no_proxy - assert no_proxy, 'wildcard matching dotless domain' + assert no_proxy, "wildcard matching dotless domain" - no_proxy = pools.send :no_proxy?, 'proxy.example', env_no_proxy + no_proxy = pools.send :no_proxy?, "proxy.example", env_no_proxy - refute no_proxy, 'wildcard mismatch' + refute no_proxy, "wildcard mismatch" end def test_net_http_args pools = Gem::Request::ConnectionPools.new nil, [] - net_http_args = pools.send :net_http_args, URI('http://example'), nil + net_http_args = pools.send :net_http_args, Gem::URI("http://example"), nil - assert_equal ['example', 80], net_http_args + assert_equal ["example", 80], net_http_args end def test_net_http_args_ipv6 pools = Gem::Request::ConnectionPools.new nil, [] - net_http_args = pools.send :net_http_args, URI('http://[::1]'), nil + net_http_args = pools.send :net_http_args, Gem::URI("http://[::1]"), nil assert_equal ["::1", 80], net_http_args end @@ -114,34 +115,34 @@ class TestGemRequestConnectionPool < Gem::TestCase def test_net_http_args_proxy pools = Gem::Request::ConnectionPools.new nil, [] - net_http_args = pools.send :net_http_args, URI('http://example'), @proxy + net_http_args = pools.send :net_http_args, Gem::URI("http://example"), @proxy - assert_equal ['example', 80, 'proxy.example', 80, nil, nil], net_http_args + assert_equal ["example", 80, "proxy.example", 80, nil, nil], net_http_args end def test_net_http_args_no_proxy - orig_no_proxy, ENV['no_proxy'] = ENV['no_proxy'], 'example' + orig_no_proxy = ENV["no_proxy"] + ENV["no_proxy"] = "example" pools = Gem::Request::ConnectionPools.new nil, [] - net_http_args = pools.send :net_http_args, URI('http://example'), @proxy - - assert_equal ['example', 80, nil, nil], net_http_args + net_http_args = pools.send :net_http_args, Gem::URI("http://example"), @proxy + assert_equal ["example", 80, nil, nil], net_http_args ensure - ENV['no_proxy'] = orig_no_proxy + ENV["no_proxy"] = orig_no_proxy end def test_thread_waits_for_connection - uri = URI.parse('http://example/some_endpoint') + uri = Gem::URI.parse("http://example/some_endpoint") pools = Gem::Request::ConnectionPools.new nil, [] pool = pools.pool_for uri pool.checkout Thread.new do - assert_raise(Timeout::Error) do - Timeout.timeout(1) do + assert_raise(Gem::Timeout::Error) do + Gem::Timeout.timeout(1) do pool.checkout end end diff --git a/test/rubygems/test_gem_request_set.rb b/test/rubygems/test_gem_request_set.rb index 404e9b61aa..9aa244892c 100644 --- a/test/rubygems/test_gem_request_set.rb +++ b/test/rubygems/test_gem_request_set.rb @@ -1,14 +1,13 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/request_set' + +require_relative "helper" +require "rubygems/request_set" class TestGemRequestSet < Gem::TestCase def setup super Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new - - @DR = Gem::Resolver end def test_gem @@ -23,49 +22,49 @@ class TestGemRequestSet < Gem::TestCase def test_gem_duplicate rs = Gem::RequestSet.new - rs.gem 'a', '1' - rs.gem 'a', '2' + rs.gem "a", "1" + rs.gem "a", "2" - assert_equal [dep('a', '= 1', '= 2')], rs.dependencies + assert_equal [dep("a", "= 1", "= 2")], rs.dependencies end def test_import rs = Gem::RequestSet.new - rs.gem 'a' + rs.gem "a" - rs.import [dep('b')] + rs.import [dep("b")] - assert_equal [dep('a'), dep('b')], rs.dependencies + assert_equal [dep("a"), dep("b")], rs.dependencies end def test_install_from_gemdeps spec_fetcher do |fetcher| - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end done_installing_ran = false - Gem.done_installing do |installer, specs| + Gem.done_installing do |_installer, _specs| done_installing_ran = true end rs = Gem::RequestSet.new installed = [] - File.open 'gem.deps.rb', 'w' do |io| + File.open "gem.deps.rb", "w" do |io| io.puts 'gem "a"' io.flush - result = rs.install_from_gemdeps :gemdeps => io.path do |req, installer| + result = rs.install_from_gemdeps gemdeps: io.path do |req, _installer| installed << req.full_name end assert_kind_of Array, result # what is supposed to be in here? end - assert_includes installed, 'a-2' - assert_path_exist File.join @gemhome, 'gems', 'a-2' - assert_path_exist 'gem.deps.rb.lock' + assert_includes installed, "a-2" + assert_path_exist File.join @gemhome, "gems", "a-2" + assert_path_exist "gem.deps.rb.lock" assert rs.remote refute done_installing_ran @@ -73,12 +72,12 @@ class TestGemRequestSet < Gem::TestCase def test_install_from_gemdeps_explain spec_fetcher do |fetcher| - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end rs = Gem::RequestSet.new - File.open 'gem.deps.rb', 'w' do |io| + File.open "gem.deps.rb", "w" do |io| io.puts 'gem "a"' io.flush @@ -88,7 +87,7 @@ Gems to install: EXPECTED actual, _ = capture_output do - rs.install_from_gemdeps :gemdeps => io.path, :explain => true + rs.install_from_gemdeps gemdeps: io.path, explain: true end assert_equal(expected, actual) end @@ -96,45 +95,45 @@ Gems to install: def test_install_from_gemdeps_install_dir spec_fetcher do |fetcher| - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end util_clear_gems - assert_path_not_exist File.join Gem.dir, 'gems', 'a-2' + assert_path_not_exist File.join Gem.dir, "gems", "a-2" rs = Gem::RequestSet.new installed = [] - File.open 'gem.deps.rb', 'w' do |io| + File.open "gem.deps.rb", "w" do |io| io.puts 'gem "a"' end options = { - :gemdeps => 'gem.deps.rb', - :install_dir => "#{@gemhome}2", + gemdeps: "gem.deps.rb", + install_dir: "#{@gemhome}2", } - rs.install_from_gemdeps options do |req, installer| + rs.install_from_gemdeps options do |req, _installer| installed << req.full_name end - assert_includes installed, 'a-2' - assert_path_not_exist File.join Gem.dir, 'gems', 'a-2' + assert_includes installed, "a-2" + assert_path_not_exist File.join Gem.dir, "gems", "a-2" end def test_install_from_gemdeps_local spec_fetcher do |fetcher| - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end rs = Gem::RequestSet.new - File.open 'gem.deps.rb', 'w' do |io| + File.open "gem.deps.rb", "w" do |io| io.puts 'gem "a"' io.flush assert_raise Gem::UnsatisfiableDependencyError do - rs.install_from_gemdeps :gemdeps => io.path, :domain => :local + rs.install_from_gemdeps gemdeps: io.path, domain: :local end end @@ -143,15 +142,15 @@ Gems to install: def test_install_from_gemdeps_lockfile spec_fetcher do |fetcher| - fetcher.download 'a', 1 - fetcher.download 'a', 2 - fetcher.download 'b', 1, 'a' => '>= 0' + fetcher.download "a", 1 + fetcher.download "a", 2 + fetcher.download "b", 1, "a" => ">= 0" end rs = Gem::RequestSet.new installed = [] - File.open 'gem.deps.rb.lock', 'w' do |io| + File.open "gem.deps.rb.lock", "w" do |io| io.puts <<-LOCKFILE GEM remote: #{@gem_repo} @@ -168,19 +167,19 @@ DEPENDENCIES LOCKFILE end - File.open 'gem.deps.rb', 'w' do |io| + File.open "gem.deps.rb", "w" do |io| io.puts 'gem "b"' end - rs.install_from_gemdeps :gemdeps => 'gem.deps.rb' do |req, installer| + rs.install_from_gemdeps gemdeps: "gem.deps.rb" do |req, _installer| installed << req.full_name end - assert_includes installed, 'b-1' - assert_includes installed, 'a-1' + assert_includes installed, "b-1" + assert_includes installed, "a-1" - assert_path_exist File.join @gemhome, 'specifications', 'a-1.gemspec' - assert_path_exist File.join @gemhome, 'specifications', 'b-1.gemspec' + assert_path_exist File.join @gemhome, "specifications", "a-1.gemspec" + assert_path_exist File.join @gemhome, "specifications", "b-1.gemspec" end def test_install_from_gemdeps_complex_dependencies @@ -197,7 +196,7 @@ DEPENDENCIES rs = Gem::RequestSet.new installed = [] - File.open 'Gemfile.lock', 'w' do |io| + File.open "Gemfile.lock", "w" do |io| io.puts <<-LOCKFILE GEM remote: #{@gem_repo} @@ -212,7 +211,7 @@ DEPENDENCIES LOCKFILE end - File.open 'testo.gemspec', 'w' do |io| + File.open "testo.gemspec", "w" do |io| io.puts <<-LOCKFILE Gem::Specification.new do |spec| spec.name = 'testo' @@ -222,28 +221,28 @@ end LOCKFILE end - File.open 'Gemfile', 'w' do |io| + File.open "Gemfile", "w" do |io| io.puts("gemspec") end - rs.install_from_gemdeps :gemdeps => 'Gemfile' do |req, installer| + rs.install_from_gemdeps gemdeps: "Gemfile" do |req, _installer| installed << req.full_name end - assert_includes installed, 'z-1.0.3' + assert_includes installed, "z-1.0.3" - assert_path_exist File.join @gemhome, 'specifications', 'z-1.0.3.gemspec' + assert_path_exist File.join @gemhome, "specifications", "z-1.0.3.gemspec" end def test_install_from_gemdeps_version_mismatch spec_fetcher do |fetcher| - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end rs = Gem::RequestSet.new installed = [] - File.open 'gem.deps.rb', 'w' do |io| + File.open "gem.deps.rb", "w" do |io| io.puts <<-GEM_DEPS gem "a" ruby "0" @@ -251,18 +250,18 @@ ruby "0" io.flush - rs.install_from_gemdeps :gemdeps => io.path do |req, installer| + rs.install_from_gemdeps gemdeps: io.path do |req, _installer| installed << req.full_name end end - assert_includes installed, 'a-2' + assert_includes installed, "a-2" end def test_load_gemdeps rs = Gem::RequestSet.new - tf = Tempfile.open 'gem.deps.rb' do |io| + tf = Tempfile.open "gem.deps.rb" do |io| io.puts 'gem "a"' io.flush @@ -273,7 +272,7 @@ ruby "0" end tf.close! - assert_equal [dep('a')], rs.dependencies + assert_equal [dep("a")], rs.dependencies assert rs.git_set assert rs.vendor_set @@ -282,7 +281,7 @@ ruby "0" def test_load_gemdeps_installing rs = Gem::RequestSet.new - tf = Tempfile.open 'gem.deps.rb' do |io| + tf = Tempfile.open "gem.deps.rb" do |io| io.puts 'ruby "0"' io.puts 'gem "a"' io.flush @@ -294,13 +293,13 @@ ruby "0" end tf.close! - assert_equal [dep('a')], rs.dependencies + assert_equal [dep("a")], rs.dependencies end def test_load_gemdeps_without_groups rs = Gem::RequestSet.new - tf = Tempfile.open 'gem.deps.rb' do |io| + tf = Tempfile.open "gem.deps.rb" do |io| io.puts 'gem "a", :group => :test' io.flush @@ -324,7 +323,7 @@ ruby "0" res = rs.resolve StaticSet.new([a, b]) assert_equal 2, res.size - names = res.map {|s| s.full_name }.sort + names = res.map(&:full_name).sort assert_equal ["a-2", "b-2"], names @@ -332,28 +331,28 @@ ruby "0" end def test_bug_bug_990 - a = util_spec 'a', '1.b', 'b' => '~> 1.a' - b = util_spec 'b', '1.b', 'c' => '>= 1' - c = util_spec 'c', '1.1.b' + a = util_spec "a", "1.b", "b" => "~> 1.a" + b = util_spec "b", "1.b", "c" => ">= 1" + c = util_spec "c", "1.1.b" rs = Gem::RequestSet.new - rs.gem 'a' + rs.gem "a" rs.prerelease = true res = rs.resolve StaticSet.new([a, b, c]) assert_equal 3, res.size - names = res.map {|s| s.full_name }.sort + names = res.map(&:full_name).sort assert_equal %w[a-1.b b-1.b c-1.1.b], names end def test_resolve_development - a = util_spec 'a', 1 + a = util_spec "a", 1 spec = Gem::Resolver::SpecSpecification.new nil, a rs = Gem::RequestSet.new - rs.gem 'a' + rs.gem "a" rs.development = true res = rs.resolve StaticSet.new [spec] @@ -364,22 +363,22 @@ ruby "0" end def test_resolve_development_shallow - a = util_spec 'a', 1 do |s| - s.add_development_dependency 'b' + a = util_spec "a", 1 do |s| + s.add_development_dependency "b" end - b = util_spec 'b', 1 do |s| - s.add_development_dependency 'c' + b = util_spec "b", 1 do |s| + s.add_development_dependency "c" end - c = util_spec 'c', 1 + c = util_spec "c", 1 a_spec = Gem::Resolver::SpecSpecification.new nil, a b_spec = Gem::Resolver::SpecSpecification.new nil, b c_spec = Gem::Resolver::SpecSpecification.new nil, c rs = Gem::RequestSet.new - rs.gem 'a' + rs.gem "a" rs.development = true rs.development_shallow = true @@ -395,7 +394,7 @@ ruby "0" rs = Gem::RequestSet.new - tf = Tempfile.open 'gem.deps.rb' do |io| + tf = Tempfile.open "gem.deps.rb" do |io| io.puts <<-GEMS_DEPS_RB gem "#{name}", :git => "#{repository}" GEMS_DEPS_RB @@ -410,12 +409,12 @@ ruby "0" res = rs.resolve assert_equal 1, res.size - names = res.map {|s| s.full_name }.sort + names = res.map(&:full_name).sort assert_equal %w[a-1], names - assert_equal [@DR::BestSet, @DR::GitSet, @DR::VendorSet, @DR::SourceSet], - rs.sets.map {|set| set.class } + assert_equal [Gem::Resolver::BestSet, Gem::Resolver::GitSet, Gem::Resolver::VendorSet, Gem::Resolver::SourceSet], + rs.sets.map(&:class) end def test_resolve_ignore_dependencies @@ -429,18 +428,18 @@ ruby "0" res = rs.resolve StaticSet.new([a, b]) assert_equal 1, res.size - names = res.map {|s| s.full_name }.sort + names = res.map(&:full_name).sort assert_equal %w[a-2], names end def test_resolve_incompatible - a1 = util_spec 'a', 1 - a2 = util_spec 'a', 2 + a1 = util_spec "a", 1 + a2 = util_spec "a", 2 rs = Gem::RequestSet.new - rs.gem 'a', '= 1' - rs.gem 'a', '= 2' + rs.gem "a", "= 1" + rs.gem "a", "= 2" set = StaticSet.new [a1, a2] @@ -450,15 +449,15 @@ ruby "0" end def test_resolve_vendor - a_name, _, a_directory = vendor_gem 'a', 1 do |s| - s.add_dependency 'b', '~> 2.0' + a_name, _, a_directory = vendor_gem "a", 1 do |s| + s.add_dependency "b", "~> 2.0" end - b_name, _, b_directory = vendor_gem 'b', 2 + b_name, _, b_directory = vendor_gem "b", 2 rs = Gem::RequestSet.new - tf = Tempfile.open 'gem.deps.rb' do |io| + tf = Tempfile.open "gem.deps.rb" do |io| io.puts <<-GEMS_DEPS_RB gem "#{a_name}", :path => "#{a_directory}" gem "#{b_name}", :path => "#{b_directory}" @@ -474,12 +473,12 @@ ruby "0" res = rs.resolve assert_equal 2, res.size - names = res.map {|s| s.full_name }.sort + names = res.map(&:full_name).sort assert_equal ["a-1", "b-2"], names - assert_equal [@DR::BestSet, @DR::GitSet, @DR::VendorSet, @DR::SourceSet], - rs.sets.map {|set| set.class } + assert_equal [Gem::Resolver::BestSet, Gem::Resolver::GitSet, Gem::Resolver::VendorSet, Gem::Resolver::SourceSet], + rs.sets.map(&:class) end def test_sorted_requests @@ -492,7 +491,7 @@ ruby "0" rs.resolve StaticSet.new([a, b, c]) - names = rs.sorted_requests.map {|s| s.full_name } + names = rs.sorted_requests.map(&:full_name) assert_equal %w[c-2 b-2 a-2], names end @@ -509,7 +508,7 @@ ruby "0" end rs = Gem::RequestSet.new - rs.gem 'a' + rs.gem "a" rs.resolve @@ -521,14 +520,14 @@ ruby "0" installers << installer end - assert_equal %w[b-1 a-1], reqs.map {|req| req.full_name } + assert_equal %w[b-1 a-1], reqs.map(&:full_name) assert_equal %w[b-1 a-1], installers.map {|installer| installer.spec.full_name } - assert_path_exist File.join @gemhome, 'specifications', 'a-1.gemspec' - assert_path_exist File.join @gemhome, 'specifications', 'b-1.gemspec' + assert_path_exist File.join @gemhome, "specifications", "a-1.gemspec" + assert_path_exist File.join @gemhome, "specifications", "b-1.gemspec" - assert_equal %w[b-1 a-1], installed.map {|s| s.full_name } + assert_equal %w[b-1 a-1], installed.map(&:full_name) assert done_installing_ran end @@ -545,60 +544,60 @@ ruby "0" rs.resolve installed = rs.install_into @tempdir do - assert_equal @tempdir, ENV['GEM_HOME'] + assert_equal @tempdir, ENV["GEM_HOME"] end - assert_path_exist File.join @tempdir, 'specifications', 'a-1.gemspec' - assert_path_exist File.join @tempdir, 'specifications', 'b-1.gemspec' + assert_path_exist File.join @tempdir, "specifications", "a-1.gemspec" + assert_path_exist File.join @tempdir, "specifications", "b-1.gemspec" - assert_equal %w[b-1 a-1], installed.map {|s| s.full_name } + assert_equal %w[b-1 a-1], installed.map(&:full_name) end def test_install_into_development_shallow spec_fetcher do |fetcher| - fetcher.gem 'a', '1' do |s| - s.add_development_dependency 'b', '= 1' + fetcher.gem "a", "1" do |s| + s.add_development_dependency "b", "= 1" end - fetcher.gem 'b', '1' do |s| - s.add_development_dependency 'c', '= 1' + fetcher.gem "b", "1" do |s| + s.add_development_dependency "c", "= 1" end - fetcher.spec 'c', '1' + fetcher.spec "c", "1" end rs = Gem::RequestSet.new rs.development = true rs.development_shallow = true - rs.gem 'a' + rs.gem "a" rs.resolve options = { - :development => true, - :development_shallow => true, + development: true, + development_shallow: true, } installed = rs.install_into @tempdir, true, options do - assert_equal @tempdir, ENV['GEM_HOME'] + assert_equal @tempdir, ENV["GEM_HOME"] end - assert_equal %w[a-1 b-1], installed.map {|s| s.full_name }.sort + assert_equal %w[a-1 b-1], installed.map(&:full_name).sort end def test_sorted_requests_development_shallow - a = util_spec 'a', 1 do |s| - s.add_development_dependency 'b' + a = util_spec "a", 1 do |s| + s.add_development_dependency "b" end - b = util_spec 'b', 1 do |s| - s.add_development_dependency 'c' + b = util_spec "b", 1 do |s| + s.add_development_dependency "c" end - c = util_spec 'c', 1 + c = util_spec "c", 1 rs = Gem::RequestSet.new - rs.gem 'a' + rs.gem "a" rs.development = true rs.development_shallow = true @@ -608,22 +607,22 @@ ruby "0" rs.resolve StaticSet.new [a_spec, b_spec, c_spec] - assert_equal %w[b-1 a-1], rs.sorted_requests.map {|req| req.full_name } + assert_equal %w[b-1 a-1], rs.sorted_requests.map(&:full_name) end def test_tsort_each_child_development - a = util_spec 'a', 1 do |s| - s.add_development_dependency 'b' + a = util_spec "a", 1 do |s| + s.add_development_dependency "b" end - b = util_spec 'b', 1 do |s| - s.add_development_dependency 'c' + b = util_spec "b", 1 do |s| + s.add_development_dependency "c" end - c = util_spec 'c', 1 + c = util_spec "c", 1 rs = Gem::RequestSet.new - rs.gem 'a' + rs.gem "a" rs.development = true rs.development_shallow = true @@ -637,22 +636,22 @@ ruby "0" deps = rs.enum_for(:tsort_each_child, a_req).to_a - assert_equal %w[b], deps.map {|dep| dep.name } + assert_equal %w[b], deps.map(&:name) end def test_tsort_each_child_development_shallow - a = util_spec 'a', 1 do |s| - s.add_development_dependency 'b' + a = util_spec "a", 1 do |s| + s.add_development_dependency "b" end - b = util_spec 'b', 1 do |s| - s.add_development_dependency 'c' + b = util_spec "b", 1 do |s| + s.add_development_dependency "c" end - c = util_spec 'c', 1 + c = util_spec "c", 1 rs = Gem::RequestSet.new - rs.gem 'a' + rs.gem "a" rs.development = true rs.development_shallow = true diff --git a/test/rubygems/test_gem_request_set_gem_dependency_api.rb b/test/rubygems/test_gem_request_set_gem_dependency_api.rb index 5891882119..af32005a16 100644 --- a/test/rubygems/test_gem_request_set_gem_dependency_api.rb +++ b/test/rubygems/test_gem_request_set_gem_dependency_api.rb @@ -1,19 +1,18 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/request_set' + +require_relative "helper" +require "rubygems/request_set" class TestGemRequestSetGemDependencyAPI < Gem::TestCase def setup super - @GDA = Gem::RequestSet::GemDependencyAPI - @set = Gem::RequestSet.new @git_set = Gem::Resolver::GitSet.new @vendor_set = Gem::Resolver::VendorSet.new - @gda = @GDA.new @set, 'gem.deps.rb' + @gda = Gem::RequestSet::GemDependencyAPI.new @set, "gem.deps.rb" @gda.instance_variable_set :@git_set, @git_set @gda.instance_variable_set :@vendor_set, @vendor_set end @@ -44,45 +43,45 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase end def test_gempspec_with_multiple_runtime_deps - save_gemspec 'foo', '1.0' do |s| - s.add_runtime_dependency 'bar', '>= 1.6.0', '< 1.6.4' + save_gemspec "foo", "1.0" do |s| + s.add_runtime_dependency "bar", ">= 1.6.0", "< 1.6.4" end @gda.gemspec - assert_equal %w[ foo bar ].sort, @set.dependencies.map(&:name).sort - bar = @set.dependencies.find {|d| d.name == 'bar' } - assert_equal [["<", Gem::Version.create('1.6.4')], - [">=", Gem::Version.create('1.6.0')]], bar.requirement.requirements.sort + assert_equal %w[foo bar].sort, @set.dependencies.map(&:name).sort + bar = @set.dependencies.find {|d| d.name == "bar" } + assert_equal [["<", Gem::Version.create("1.6.4")], + [">=", Gem::Version.create("1.6.0")]], bar.requirement.requirements.sort end def test_gemspec_without_group - @gda.send :add_dependencies, [:development], [dep('a', '= 1')] + @gda.send :add_dependencies, [:development], [dep("a", "= 1")] - assert_equal [dep('a', '= 1')], @set.dependencies + assert_equal [dep("a", "= 1")], @set.dependencies @gda.without_groups << :development - @gda.send :add_dependencies, [:development], [dep('b', '= 2')] + @gda.send :add_dependencies, [:development], [dep("b", "= 2")] - assert_equal [dep('a', '= 1')], @set.dependencies + assert_equal [dep("a", "= 1")], @set.dependencies end def test_gem - @gda.gem 'a' + @gda.gem "a" - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies - assert_equal %w[a], @gda.requires['a'] + assert_equal %w[a], @gda.requires["a"] - expected = { 'a' => Gem::Requirement.default } + expected = { "a" => Gem::Requirement.default } assert_equal expected, @gda.dependencies end def test_gem_duplicate - @gda.gem 'a' + @gda.gem "a" _, err = capture_output do - @gda.gem 'a' + @gda.gem "a" end expected = "Gem dependencies file gem.deps.rb requires a more than once." @@ -91,147 +90,147 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase end def test_gem_git - @gda.gem 'a', :git => 'git/a' + @gda.gem "a", git: "git/a" - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies - assert_equal %w[git/a master], @git_set.repositories['a'] + assert_equal ["git/a", nil], @git_set.repositories["a"] - expected = { 'a' => Gem::Requirement.create('!') } + expected = { "a" => Gem::Requirement.create("!") } assert_equal expected, @gda.dependencies end def test_gem_bitbucket - @gda.gem 'a', :bitbucket => 'example/repository' + @gda.gem "a", bitbucket: "example/repository" - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies - assert_equal %w[https://example@bitbucket.org/example/repository.git master], - @git_set.repositories['a'] + assert_equal ["https://example@bitbucket.org/example/repository.git", nil], + @git_set.repositories["a"] - expected = { 'a' => Gem::Requirement.create('!') } + expected = { "a" => Gem::Requirement.create("!") } assert_equal expected, @gda.dependencies end def test_gem_bitbucket_expand_path - @gda.gem 'a', :bitbucket => 'example' + @gda.gem "a", bitbucket: "example" - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies - assert_equal %w[https://example@bitbucket.org/example/example.git master], - @git_set.repositories['a'] + assert_equal ["https://example@bitbucket.org/example/example.git", nil], + @git_set.repositories["a"] - expected = { 'a' => Gem::Requirement.create('!') } + expected = { "a" => Gem::Requirement.create("!") } assert_equal expected, @gda.dependencies end def test_gem_git_branch _, err = capture_output do - @gda.gem 'a', :git => 'git/a', :branch => 'other', :tag => 'v1' + @gda.gem "a", git: "git/a", branch: "other", tag: "v1" end expected = "Gem dependencies file gem.deps.rb includes git reference for both ref/branch and tag but only ref/branch is used." assert_match expected, err - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies - assert_equal %w[git/a other], @git_set.repositories['a'] + assert_equal %w[git/a other], @git_set.repositories["a"] end def test_gem_git_gist - @gda.gem 'a', :gist => 'a' + @gda.gem "a", gist: "a" - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies - assert_equal %w[https://gist.github.com/a.git master], - @git_set.repositories['a'] + assert_equal ["https://gist.github.com/a.git", nil], + @git_set.repositories["a"] end def test_gem_git_ref _, err = capture_output do - @gda.gem 'a', :git => 'git/a', :ref => 'abcd123', :branch => 'other' + @gda.gem "a", git: "git/a", ref: "abcd123", branch: "other" end expected = "Gem dependencies file gem.deps.rb includes git reference for both ref and branch but only ref is used." assert_match expected, err - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies - assert_equal %w[git/a abcd123], @git_set.repositories['a'] + assert_equal %w[git/a abcd123], @git_set.repositories["a"] end def test_gem_git_submodules - @gda.gem 'a', :git => 'git/a', :submodules => true + @gda.gem "a", git: "git/a", submodules: true - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies - assert_equal %w[git/a master], @git_set.repositories['a'] + assert_equal ["git/a", nil], @git_set.repositories["a"] assert_equal %w[git/a], @git_set.need_submodules.keys end def test_gem_git_tag - @gda.gem 'a', :git => 'git/a', :tag => 'v1' + @gda.gem "a", git: "git/a", tag: "v1" - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies - assert_equal %w[git/a v1], @git_set.repositories['a'] + assert_equal %w[git/a v1], @git_set.repositories["a"] end def test_gem_github - @gda.gem 'a', :github => 'example/repository' + @gda.gem "a", github: "example/repository" - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies - assert_equal %w[git://github.com/example/repository.git master], - @git_set.repositories['a'] + assert_equal ["https://github.com/example/repository.git", nil], + @git_set.repositories["a"] - expected = { 'a' => Gem::Requirement.create('!') } + expected = { "a" => Gem::Requirement.create("!") } assert_equal expected, @gda.dependencies end def test_gem_github_expand_path - @gda.gem 'a', :github => 'example' + @gda.gem "a", github: "example" - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies - assert_equal %w[git://github.com/example/example.git master], - @git_set.repositories['a'] + assert_equal ["https://github.com/example/example.git", nil], + @git_set.repositories["a"] - expected = { 'a' => Gem::Requirement.create('!') } + expected = { "a" => Gem::Requirement.create("!") } assert_equal expected, @gda.dependencies end def test_gem_group - @gda.gem 'a', :group => :test + @gda.gem "a", group: :test - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies end def test_gem_group_without @gda.without_groups << :test - @gda.gem 'a', :group => :test + @gda.gem "a", group: :test assert_empty @set.dependencies - expected = { 'a' => Gem::Requirement.default } + expected = { "a" => Gem::Requirement.default } assert_equal expected, @gda.dependencies end def test_gem_groups - @gda.gem 'a', :groups => [:test, :development] + @gda.gem "a", groups: [:test, :development] - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies end def test_gem_path name, version, directory = vendor_gem - @gda.gem name, :path => directory + @gda.gem name, path: directory assert_equal [dep(name)], @set.dependencies @@ -239,16 +238,17 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase assert_equal "#{name}-#{version}", loaded.full_name - expected = { name => Gem::Requirement.create('!') } + expected = { name => Gem::Requirement.create("!") } assert_equal expected, @gda.dependencies end def test_gem_platforms - win_platform, Gem.win_platform = Gem.win_platform?, false + win_platform = Gem.win_platform? + Gem.win_platform = false - with_engine_version 'ruby', '2.0.0' do - @gda.gem 'a', :platforms => :ruby + with_engine_version "ruby", "2.0.0" do + @gda.gem "a", platforms: :ruby refute_empty @set.dependencies end @@ -257,46 +257,47 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase end def test_gem_platforms_bundler_ruby - win_platform, Gem.win_platform = Gem.win_platform?, false + win_platform = Gem.win_platform? + Gem.win_platform = false - with_engine_version 'ruby', '2.0.0' do + with_engine_version "ruby", "2.0.0" do set = Gem::RequestSet.new - gda = @GDA.new set, 'gem.deps.rb' - gda.gem 'a', :platforms => :ruby + gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb" + gda.gem "a", platforms: :ruby refute_empty set.dependencies end - with_engine_version 'rbx', '2.0.0' do + with_engine_version "rbx", "2.0.0" do set = Gem::RequestSet.new - gda = @GDA.new set, 'gem.deps.rb' - gda.gem 'a', :platforms => :ruby + gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb" + gda.gem "a", platforms: :ruby refute_empty set.dependencies end - with_engine_version 'truffleruby', '2.0.0' do + with_engine_version "truffleruby", "2.0.0" do set = Gem::RequestSet.new - gda = @GDA.new set, 'gem.deps.rb' - gda.gem 'a', :platforms => :ruby + gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb" + gda.gem "a", platforms: :ruby refute_empty set.dependencies end - with_engine_version 'jruby', '1.7.6' do + with_engine_version "jruby", "1.7.6" do set = Gem::RequestSet.new - gda = @GDA.new set, 'gem.deps.rb' - gda.gem 'a', :platforms => :ruby + gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb" + gda.gem "a", platforms: :ruby assert_empty set.dependencies end Gem.win_platform = true - with_engine_version 'ruby', '2.0.0' do + with_engine_version "ruby", "2.0.0" do set = Gem::RequestSet.new - gda = @GDA.new set, 'gem.deps.rb' - gda.gem 'a', :platforms => :ruby + gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb" + gda.gem "a", platforms: :ruby assert_empty set.dependencies end @@ -305,32 +306,33 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase end def test_gem_platforms_engine - with_engine_version 'jruby', '1.7.6' do - @gda.gem 'a', :platforms => :mri + with_engine_version "jruby", "1.7.6" do + @gda.gem "a", platforms: :mri assert_empty @set.dependencies end - with_engine_version 'truffleruby', '1.2.3' do - @gda.gem 'a', :platforms => :mri + with_engine_version "truffleruby", "1.2.3" do + @gda.gem "a", platforms: :mri assert_empty @set.dependencies end end def test_gem_platforms_maglev - win_platform, Gem.win_platform = Gem.win_platform?, false + win_platform = Gem.win_platform? + Gem.win_platform = false - with_engine_version 'maglev', '1.0.0' do + with_engine_version "maglev", "1.0.0" do set = Gem::RequestSet.new - gda = @GDA.new set, 'gem.deps.rb' - gda.gem 'a', :platforms => :ruby + gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb" + gda.gem "a", platforms: :ruby refute_empty set.dependencies set = Gem::RequestSet.new - gda = @GDA.new set, 'gem.deps.rb' - gda.gem 'a', :platforms => :maglev + gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb" + gda.gem "a", platforms: :maglev refute_empty set.dependencies end @@ -339,39 +341,40 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase end def test_gem_platforms_truffleruby - with_engine_version 'truffleruby', '1.0.0' do + with_engine_version "truffleruby", "1.0.0" do set = Gem::RequestSet.new - gda = @GDA.new set, 'gem.deps.rb' - gda.gem 'a', :platforms => :truffleruby + gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb" + gda.gem "a", platforms: :truffleruby refute_empty set.dependencies set = Gem::RequestSet.new - gda = @GDA.new set, 'gem.deps.rb' - gda.gem 'a', :platforms => :maglev + gda = Gem::RequestSet::GemDependencyAPI.new set, "gem.deps.rb" + gda.gem "a", platforms: :maglev assert_empty set.dependencies end end def test_gem_platforms_multiple - win_platform, Gem.win_platform = Gem.win_platform?, false + win_platform = Gem.win_platform? + Gem.win_platform = false - with_engine_version 'ruby', '2.0.0' do - @gda.gem 'a', :platforms => [:mswin, :jruby] + with_engine_version "ruby", "2.0.0" do + @gda.gem "a", platforms: [:mswin, :jruby] assert_empty @set.dependencies end - ensure Gem.win_platform = win_platform end def test_gem_platforms_platform - win_platform, Gem.win_platform = Gem.win_platform?, false + win_platform = Gem.win_platform? + Gem.win_platform = false - with_engine_version 'ruby', '2.0.0' do - @gda.gem 'a', :platforms => :jruby, :platform => :ruby + with_engine_version "ruby", "2.0.0" do + @gda.gem "a", platforms: :jruby, platform: :ruby refute_empty @set.dependencies end @@ -380,8 +383,8 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase end def test_gem_platforms_version - with_engine_version 'ruby', '2.0.0' do - @gda.gem 'a', :platforms => :ruby_18 + with_engine_version "ruby", "2.0.0" do + @gda.gem "a", platforms: :ruby_18 assert_empty @set.dependencies end @@ -389,26 +392,26 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase def test_gem_platforms_unknown e = assert_raise ArgumentError do - @gda.gem 'a', :platforms => :unknown + @gda.gem "a", platforms: :unknown end - assert_equal 'unknown platform :unknown', e.message + assert_equal "unknown platform :unknown", e.message end def test_gem_requires - @gda.gem 'a', :require => %w[b c] - @gda.gem 'd', :require => 'e' + @gda.gem "a", require: %w[b c] + @gda.gem "d", require: "e" - assert_equal [dep('a'), dep('d')], @set.dependencies + assert_equal [dep("a"), dep("d")], @set.dependencies - assert_equal %w[b c], @gda.requires['a'] - assert_equal %w[e], @gda.requires['d'] + assert_equal %w[b c], @gda.requires["a"] + assert_equal %w[e], @gda.requires["d"] end def test_gem_requires_false - @gda.gem 'a', :require => false + @gda.gem "a", require: false - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies assert_empty @gda.requires end @@ -416,55 +419,55 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase def test_gem_requires_without_group @gda.without_groups << :test - @gda.gem 'a', :group => :test + @gda.gem "a", group: :test assert_empty @set.dependencies - assert_empty @gda.requires['a'] + assert_empty @gda.requires["a"] end def test_gem_requirement - @gda.gem 'a', '~> 1.0' + @gda.gem "a", "~> 1.0" - assert_equal [dep('a', '~> 1.0')], @set.dependencies + assert_equal [dep("a", "~> 1.0")], @set.dependencies - expected = { 'a' => Gem::Requirement.create(['~> 1.0']) } + expected = { "a" => Gem::Requirement.create(["~> 1.0"]) } assert_equal expected, @gda.dependencies end def test_gem_requirements - @gda.gem 'b', '~> 1.0', '>= 1.0.2' + @gda.gem "b", "~> 1.0", ">= 1.0.2" - assert_equal [dep('b', '~> 1.0', '>= 1.0.2')], @set.dependencies + assert_equal [dep("b", "~> 1.0", ">= 1.0.2")], @set.dependencies - expected = { 'b' => Gem::Requirement.create(['~> 1.0', '>= 1.0.2']) } + expected = { "b" => Gem::Requirement.create(["~> 1.0", ">= 1.0.2"]) } assert_equal expected, @gda.dependencies end def test_gem_requirements_options - @gda.gem 'c', :git => 'https://example/c.git' + @gda.gem "c", git: "https://example/c.git" - assert_equal [dep('c')], @set.dependencies + assert_equal [dep("c")], @set.dependencies end def test_gem_source_mismatch name, _, directory = vendor_gem - gda = @GDA.new @set, nil + gda = Gem::RequestSet::GemDependencyAPI.new @set, nil gda.gem name e = assert_raise ArgumentError do - gda.gem name, :path => directory + gda.gem name, path: directory end assert_equal "duplicate source path: #{directory} for gem #{name}", e.message - gda = @GDA.new @set, nil + gda = Gem::RequestSet::GemDependencyAPI.new @set, nil gda.instance_variable_set :@vendor_set, @vendor_set - gda.gem name, :path => directory + gda.gem name, path: directory e = assert_raise ArgumentError do gda.gem name @@ -475,47 +478,47 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase end def test_gem_deps_file - assert_equal 'gem.deps.rb', @gda.gem_deps_file + assert_equal "gem.deps.rb", @gda.gem_deps_file - gda = @GDA.new @set, 'foo/Gemfile' + gda = Gem::RequestSet::GemDependencyAPI.new @set, "foo/Gemfile" - assert_equal 'Gemfile', gda.gem_deps_file + assert_equal "Gemfile", gda.gem_deps_file end def test_gem_group_method groups = [] @gda.group :a do - groups = @gda.send :gem_group, 'a', :group => :b, :groups => [:c, :d] + groups = @gda.send :gem_group, "a", group: :b, groups: [:c, :d] end - assert_equal [:a, :b, :c, :d], groups.sort_by {|group| group.to_s } + assert_equal [:a, :b, :c, :d], groups.sort_by(&:to_s) end def test_gemspec - save_gemspec 'a', 1 do |s| - s.add_dependency 'b', 2 - s.add_development_dependency 'c', 3 + save_gemspec "a", 1 do |s| + s.add_dependency "b", 2 + s.add_development_dependency "c", 3 end @gda.gemspec - assert_equal [dep('a', '= 1'), dep('b', '= 2'), dep('c', '=3')], + assert_equal [dep("a", "= 1"), dep("b", "= 2"), dep("c", "=3")], @set.dependencies - assert_equal %w[a], @gda.requires['a'] + assert_equal %w[a], @gda.requires["a"] expected = { - 'a' => Gem::Requirement.create('!'), - 'b' => req('= 2'), - 'c' => req('= 3'), + "a" => Gem::Requirement.create("!"), + "b" => req("= 2"), + "c" => req("= 3"), } assert_equal expected, @gda.dependencies end def test_gemspec_bad - FileUtils.touch 'a.gemspec' + FileUtils.touch "a.gemspec" e = assert_raise ArgumentError do capture_output do @@ -523,31 +526,31 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase end end - assert_equal 'invalid gemspec ./a.gemspec', e.message + assert_equal "invalid gemspec ./a.gemspec", e.message end def test_gemspec_development_group - save_gemspec 'a', 1 do |s| - s.add_dependency 'b', 2 - s.add_development_dependency 'c', 3 + save_gemspec "a", 1 do |s| + s.add_dependency "b", 2 + s.add_development_dependency "c", 3 end @gda.without_groups << :other - @gda.gemspec :development_group => :other + @gda.gemspec development_group: :other - assert_equal [dep('a', '= 1'), dep('b', '= 2')], @set.dependencies + assert_equal [dep("a", "= 1"), dep("b", "= 2")], @set.dependencies - assert_equal %w[a], @gda.requires['a'] + assert_equal %w[a], @gda.requires["a"] end def test_gemspec_multiple - save_gemspec 'a', 1 do |s| - s.add_dependency 'b', 2 + save_gemspec "a", 1 do |s| + s.add_dependency "b", 2 end - save_gemspec 'b', 2 do |s| - s.add_dependency 'c', 3 + save_gemspec "b", 2 do |s| + s.add_dependency "c", 3 end e = assert_raise ArgumentError do @@ -558,27 +561,27 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase end def test_gemspec_name - save_gemspec 'a', 1 do |s| - s.add_dependency 'b', 2 + save_gemspec "a", 1 do |s| + s.add_dependency "b", 2 end - save_gemspec 'b', 2 do |s| - s.add_dependency 'c', 3 + save_gemspec "b", 2 do |s| + s.add_dependency "c", 3 end - @gda.gemspec :name => 'b' + @gda.gemspec name: "b" - assert_equal [dep('b', '= 2'), dep('c', '= 3')], @set.dependencies + assert_equal [dep("b", "= 2"), dep("c", "= 3")], @set.dependencies end def test_gemspec_named - save_gemspec 'a', 1 do |s| - s.add_dependency 'b', 2 + save_gemspec "a", 1 do |s| + s.add_dependency "b", 2 end @gda.gemspec - assert_equal [dep('a', '= 1'), dep('b', '= 2')], @set.dependencies + assert_equal [dep("a", "= 1"), dep("b", "= 2")], @set.dependencies end def test_gemspec_none @@ -590,27 +593,27 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase end def test_gemspec_path - FileUtils.mkdir 'other' + FileUtils.mkdir "other" - save_gemspec 'a', 1, 'other' do |s| - s.add_dependency 'b', 2 + save_gemspec "a", 1, "other" do |s| + s.add_dependency "b", 2 end - @gda.gemspec :path => 'other' + @gda.gemspec path: "other" - assert_equal [dep('a', '= 1'), dep('b', '= 2')], @set.dependencies + assert_equal [dep("a", "= 1"), dep("b", "= 2")], @set.dependencies end def test_git - @gda.git 'git://example/repo.git' do - @gda.gem 'a' - @gda.gem 'b' + @gda.git "git://example/repo.git" do + @gda.gem "a" + @gda.gem "b" end - assert_equal [dep('a'), dep('b')], @set.dependencies + assert_equal [dep("a"), dep("b")], @set.dependencies - assert_equal %w[git://example/repo.git master], @git_set.repositories['a'] - assert_equal %w[git://example/repo.git master], @git_set.repositories['b'] + assert_equal ["git://example/repo.git", nil], @git_set.repositories["a"] + assert_equal ["git://example/repo.git", nil], @git_set.repositories["b"] end def test_git_source @@ -618,21 +621,21 @@ class TestGemRequestSetGemDependencyAPI < Gem::TestCase "git://example/#{repo_name}.git" end - @gda.gem 'a', :example => 'repo' + @gda.gem "a", example: "repo" - assert_equal %w[git://example/repo.git master], @git_set.repositories['a'] + assert_equal ["git://example/repo.git", nil], @git_set.repositories["a"] end def test_group @gda.group :test do - @gda.gem 'a' + @gda.gem "a" end - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies end def test_load - tf = Tempfile.open 'gem.deps.rb' do |io| + tf = Tempfile.open "gem.deps.rb" do |io| io.write <<-GEM_DEPS gem 'a' @@ -642,31 +645,31 @@ end GEM_DEPS io.flush - gda = @GDA.new @set, io.path + gda = Gem::RequestSet::GemDependencyAPI.new @set, io.path assert_equal gda, gda.load - assert_equal [dep('a'), dep('b')], @set.dependencies + assert_equal [dep("a"), dep("b")], @set.dependencies io end tf.close! end def test_pin_gem_source - gda = @GDA.new @set, nil + gda = Gem::RequestSet::GemDependencyAPI.new @set, nil - gda.send :pin_gem_source, 'a' - gda.send :pin_gem_source, 'a' + gda.send :pin_gem_source, "a" + gda.send :pin_gem_source, "a" e = assert_raise ArgumentError do - gda.send :pin_gem_source, 'a', :path, 'vendor/a' + gda.send :pin_gem_source, "a", :path, "vendor/a" end assert_equal "duplicate source path: vendor/a for gem a", e.message e = assert_raise ArgumentError do - gda.send :pin_gem_source, 'a', :git, 'git://example/repo.git' + gda.send :pin_gem_source, "a", :git, "git://example/repo.git" end assert_equal "duplicate source git: git://example/repo.git for gem a", @@ -674,19 +677,19 @@ end end def test_platform_mswin - if win_platform? - util_set_arch 'x86-mswin32-60' do + if Gem.win_platform? + util_set_arch "x86-mswin32-60" do @gda.platform :mswin do - @gda.gem 'a' + @gda.gem "a" end - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies refute_empty @set.dependencies end else - util_set_arch 'i686-darwin8.10.1' do + util_set_arch "i686-darwin8.10.1" do @gda.platform :mswin do - @gda.gem 'a' + @gda.gem "a" end assert_empty @set.dependencies @@ -695,23 +698,24 @@ end end def test_platform_multiple - win_platform, Gem.win_platform = Gem.win_platform?, false + win_platform = Gem.win_platform? + Gem.win_platform = false - gda = @GDA.new @set, nil + gda = Gem::RequestSet::GemDependencyAPI.new @set, nil - with_engine_version 'ruby', '1.8.7' do + with_engine_version "ruby", "1.8.7" do gda.platform :mri_19, :mri_20 do - gda.gem 'a' + gda.gem "a" end end assert_empty @set.dependencies - gda = @GDA.new @set, nil + gda = Gem::RequestSet::GemDependencyAPI.new @set, nil - with_engine_version 'ruby', '2.0.0' do + with_engine_version "ruby", "2.0.0" do gda.platform :mri_19, :mri_20 do - gda.gem 'a' + gda.gem "a" end end @@ -721,31 +725,32 @@ end end def test_platform_ruby - win_platform, Gem.win_platform = Gem.win_platform?, false + win_platform = Gem.win_platform? + Gem.win_platform = false @gda.platform :ruby do - @gda.gem 'a' + @gda.gem "a" end - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies ensure Gem.win_platform = win_platform end def test_platforms - unless win_platform? - util_set_arch 'i686-darwin8.10.1' do + unless Gem.win_platform? + util_set_arch "i686-darwin8.10.1" do @gda.platforms :ruby do - @gda.gem 'a' + @gda.gem "a" end - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies @gda.platforms :mswin do - @gda.gem 'b' + @gda.gem "b" end - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies end end end @@ -755,53 +760,51 @@ end end def test_ruby_engine - with_engine_version 'jruby', '1.7.6' do + with_engine_version "jruby", "1.7.6" do assert @gda.ruby RUBY_VERSION, - :engine => 'jruby', :engine_version => '1.7.6' - + engine: "jruby", engine_version: "1.7.6" end - with_engine_version 'truffleruby', '1.0.0-rc11' do + with_engine_version "truffleruby", "1.0.0-rc11" do assert @gda.ruby RUBY_VERSION, - :engine => 'truffleruby', :engine_version => '1.0.0-rc11' - + engine: "truffleruby", engine_version: "1.0.0-rc11" end end def test_ruby_engine_mismatch_engine - with_engine_version 'ruby', '2.0.0' do + with_engine_version "ruby", "2.0.0" do e = assert_raise Gem::RubyVersionMismatch do - @gda.ruby RUBY_VERSION, :engine => 'jruby', :engine_version => '1.7.4' + @gda.ruby RUBY_VERSION, engine: "jruby", engine_version: "1.7.4" end - assert_equal 'Your Ruby engine is ruby, but your gem.deps.rb requires jruby', + assert_equal "Your Ruby engine is ruby, but your gem.deps.rb requires jruby", e.message end end def test_ruby_engine_mismatch_version - with_engine_version 'jruby', '1.7.6' do + with_engine_version "jruby", "1.7.6" do e = assert_raise Gem::RubyVersionMismatch do - @gda.ruby RUBY_VERSION, :engine => 'jruby', :engine_version => '1.7.4' + @gda.ruby RUBY_VERSION, engine: "jruby", engine_version: "1.7.4" end - assert_equal 'Your Ruby engine version is jruby 1.7.6, but your gem.deps.rb requires jruby 1.7.4', + assert_equal "Your Ruby engine version is jruby 1.7.6, but your gem.deps.rb requires jruby 1.7.4", e.message end end def test_ruby_engine_no_engine_version e = assert_raise ArgumentError do - @gda.ruby RUBY_VERSION, :engine => 'jruby' + @gda.ruby RUBY_VERSION, engine: "jruby" end - assert_equal 'You must specify engine_version along with the Ruby engine', + assert_equal "You must specify engine_version along with the Ruby engine", e.message end def test_ruby_mismatch e = assert_raise Gem::RubyVersionMismatch do - @gda.ruby '1.8.0' + @gda.ruby "1.8.0" end assert_equal "Your Ruby version is #{RUBY_VERSION}, but your gem.deps.rb requires 1.8.0", e.message @@ -810,19 +813,19 @@ end def test_ruby_mismatch_installing @gda.installing = true - assert @gda.ruby '1.8.0' + assert @gda.ruby "1.8.0" end def test_source sources = Gem.sources - @gda.source 'http://first.example' + @gda.source "http://first.example" assert_equal %w[http://first.example], Gem.sources assert_same sources, Gem.sources - @gda.source 'http://second.example' + @gda.source "http://second.example" assert_equal %w[http://first.example http://second.example], Gem.sources end @@ -832,9 +835,9 @@ end engine = Gem.ruby_engine engine_version = RUBY_ENGINE_VERSION - with_engine_version 'other', '1.2.3' do - assert_equal 'other', Gem.ruby_engine - assert_equal '1.2.3', RUBY_ENGINE_VERSION + with_engine_version "other", "1.2.3" do + assert_equal "other", Gem.ruby_engine + assert_equal "1.2.3", RUBY_ENGINE_VERSION assert_equal version, RUBY_VERSION end diff --git a/test/rubygems/test_gem_request_set_lockfile.rb b/test/rubygems/test_gem_request_set_lockfile.rb index 2ad743c5a1..83f5002508 100644 --- a/test/rubygems/test_gem_request_set_lockfile.rb +++ b/test/rubygems/test_gem_request_set_lockfile.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/request_set' -require 'rubygems/request_set/lockfile' + +require_relative "helper" +require "rubygems/request_set" +require "rubygems/request_set/lockfile" class TestGemRequestSetLockfile < Gem::TestCase def setup @@ -9,7 +10,7 @@ class TestGemRequestSetLockfile < Gem::TestCase Gem::RemoteFetcher.fetcher = @fetcher = Gem::FakeFetcher.new - util_set_arch 'i686-darwin8.10.1' + util_set_arch "i686-darwin8.10.1" @set = Gem::RequestSet.new @@ -19,7 +20,7 @@ class TestGemRequestSetLockfile < Gem::TestCase @set.instance_variable_set :@git_set, @git_set @set.instance_variable_set :@vendor_set, @vendor_set - @gem_deps_file = 'gem.deps.rb' + @gem_deps_file = "gem.deps.rb" end def lockfile @@ -29,19 +30,19 @@ class TestGemRequestSetLockfile < Gem::TestCase def write_lockfile(lockfile) @lock_file = File.expand_path "#{@gem_deps_file}.lock" - File.open @lock_file, 'w' do |io| + File.open @lock_file, "w" do |io| io.write lockfile end end def test_add_DEPENDENCIES spec_fetcher do |fetcher| - fetcher.spec 'a', 2 do |s| - s.add_development_dependency 'b' + fetcher.spec "a", 2 do |s| + s.add_development_dependency "b" end end - @set.gem 'a' + @set.gem "a" @set.resolve out = [] @@ -49,8 +50,8 @@ class TestGemRequestSetLockfile < Gem::TestCase lockfile.add_DEPENDENCIES out expected = [ - 'DEPENDENCIES', - ' a', + "DEPENDENCIES", + " a", nil, ] @@ -59,14 +60,14 @@ class TestGemRequestSetLockfile < Gem::TestCase def test_add_DEPENDENCIES_from_gem_deps spec_fetcher do |fetcher| - fetcher.spec 'a', 2 do |s| - s.add_development_dependency 'b' + fetcher.spec "a", 2 do |s| + s.add_development_dependency "b" end end - dependencies = { 'a' => Gem::Requirement.new('~> 2.0') } + dependencies = { "a" => Gem::Requirement.new("~> 2.0") } - @set.gem 'a' + @set.gem "a" @set.resolve @lockfile = Gem::RequestSet::Lockfile.new @set, @gem_deps_file, dependencies @@ -76,8 +77,8 @@ class TestGemRequestSetLockfile < Gem::TestCase @lockfile.add_DEPENDENCIES out expected = [ - 'DEPENDENCIES', - ' a (~> 2.0)', + "DEPENDENCIES", + " a (~> 2.0)", nil, ] @@ -86,18 +87,18 @@ class TestGemRequestSetLockfile < Gem::TestCase def test_add_GEM spec_fetcher do |fetcher| - fetcher.spec 'a', 2 do |s| - s.add_dependency 'b' - s.add_development_dependency 'c' + fetcher.spec "a", 2 do |s| + s.add_dependency "b" + s.add_development_dependency "c" end - fetcher.spec 'b', 2 + fetcher.spec "b", 2 - fetcher.spec 'bundler', 1 + fetcher.spec "bundler", 1 end - @set.gem 'a' - @set.gem 'bundler' + @set.gem "a" + @set.gem "bundler" @set.resolve out = [] @@ -105,12 +106,12 @@ class TestGemRequestSetLockfile < Gem::TestCase lockfile.add_GEM out, lockfile.spec_groups expected = [ - 'GEM', - ' remote: http://gems.example.com/', - ' specs:', - ' a (2)', - ' b', - ' b (2)', + "GEM", + " remote: http://gems.example.com/", + " specs:", + " a (2)", + " b", + " b (2)", nil, ] @@ -119,16 +120,16 @@ class TestGemRequestSetLockfile < Gem::TestCase def test_add_PLATFORMS spec_fetcher do |fetcher| - fetcher.spec 'a', 2 do |s| - s.add_dependency 'b' + fetcher.spec "a", 2 do |s| + s.add_dependency "b" end - fetcher.spec 'b', 2 do |s| + fetcher.spec "b", 2 do |s| s.platform = Gem::Platform::CURRENT end end - @set.gem 'a' + @set.gem "a" @set.resolve out = [] @@ -136,9 +137,9 @@ class TestGemRequestSetLockfile < Gem::TestCase lockfile.add_PLATFORMS out expected = [ - 'PLATFORMS', - ' ruby', - ' x86-darwin-8', + "PLATFORMS", + " ruby", + " x86-darwin-8", nil, ] @@ -146,21 +147,21 @@ class TestGemRequestSetLockfile < Gem::TestCase end def test_relative_path_from - path = lockfile.relative_path_from '/foo', '/foo/bar' + path = lockfile.relative_path_from "/foo", "/foo/bar" - assert_equal File.expand_path('/foo'), path + assert_equal File.expand_path("/foo"), path - path = lockfile.relative_path_from '/foo', '/foo' + path = lockfile.relative_path_from "/foo", "/foo" - assert_equal '.', path + assert_equal ".", path end def test_to_s_gem spec_fetcher do |fetcher| - fetcher.spec 'a', 2 + fetcher.spec "a", 2 end - @set.gem 'a' + @set.gem "a" expected = <<-LOCKFILE GEM @@ -180,12 +181,12 @@ DEPENDENCIES def test_to_s_gem_dependency spec_fetcher do |fetcher| - fetcher.spec 'a', 2, 'c' => '>= 0', 'b' => '>= 0' - fetcher.spec 'b', 2 - fetcher.spec 'c', 2 + fetcher.spec "a", 2, "c" => ">= 0", "b" => ">= 0" + fetcher.spec "b", 2 + fetcher.spec "c", 2 end - @set.gem 'a' + @set.gem "a" expected = <<-LOCKFILE GEM @@ -211,12 +212,12 @@ DEPENDENCIES def test_to_s_gem_dependency_non_default spec_fetcher do |fetcher| - fetcher.spec 'a', 2, 'b' => '>= 1' - fetcher.spec 'b', 2 + fetcher.spec "a", 2, "b" => ">= 1" + fetcher.spec "b", 2 end - @set.gem 'b' - @set.gem 'a' + @set.gem "b" + @set.gem "a" expected = <<-LOCKFILE GEM @@ -239,11 +240,11 @@ DEPENDENCIES def test_to_s_gem_dependency_requirement spec_fetcher do |fetcher| - fetcher.spec 'a', 2, 'b' => '>= 0' - fetcher.spec 'b', 2 + fetcher.spec "a", 2, "b" => ">= 0" + fetcher.spec "b", 2 end - @set.gem 'a', '>= 1' + @set.gem "a", ">= 1" expected = <<-LOCKFILE GEM @@ -269,7 +270,7 @@ DEPENDENCIES @vendor_set.add_vendor_gem name, directory - @set.gem 'a' + @set.gem "a" expected = <<-LOCKFILE PATH @@ -292,7 +293,7 @@ DEPENDENCIES @vendor_set.add_vendor_gem name, File.expand_path(directory) - @set.gem 'a' + @set.gem "a" expected = <<-LOCKFILE PATH @@ -312,12 +313,12 @@ DEPENDENCIES def test_to_s_gem_platform spec_fetcher do |fetcher| - fetcher.spec 'a', 2 do |spec| + fetcher.spec "a", 2 do |spec| spec.platform = Gem::Platform.local end end - @set.gem 'a' + @set.gem "a" expected = <<-LOCKFILE GEM @@ -337,17 +338,17 @@ DEPENDENCIES def test_to_s_gem_source spec_fetcher do |fetcher| - fetcher.download 'a', 2 + fetcher.download "a", 2 end - spec_fetcher 'http://other.example/' do |fetcher| - fetcher.download 'b', 2 + spec_fetcher "http://other.example/" do |fetcher| + fetcher.download "b", 2 end - Gem.sources << 'http://other.example/' + Gem.sources << "http://other.example/" - @set.gem 'a' - @set.gem 'b' + @set.gem "a" + @set.gem "b" expected = <<-LOCKFILE GEM @@ -377,43 +378,43 @@ DEPENDENCIES head = nil Dir.chdir repository do - FileUtils.mkdir 'b' + FileUtils.mkdir "b" - Dir.chdir 'b' do - b = Gem::Specification.new 'b', 1 do |s| - s.add_dependency 'a', '~> 1.0' - s.add_dependency 'c', '~> 1.0' + Dir.chdir "b" do + b = Gem::Specification.new "b", 1 do |s| + s.add_dependency "a", "~> 1.0" + s.add_dependency "c", "~> 1.0" end - File.open 'b.gemspec', 'w' do |io| + File.open "b.gemspec", "w" do |io| io.write b.to_ruby end - system @git, 'add', 'b.gemspec' - system @git, 'commit', '--quiet', '-m', 'add b/b.gemspec' + system @git, "add", "b.gemspec" + system @git, "commit", "--quiet", "-m", "add b/b.gemspec" end - FileUtils.mkdir 'c' + FileUtils.mkdir "c" - Dir.chdir 'c' do - c = Gem::Specification.new 'c', 1 + Dir.chdir "c" do + c = Gem::Specification.new "c", 1 - File.open 'c.gemspec', 'w' do |io| + File.open "c.gemspec", "w" do |io| io.write c.to_ruby end - system @git, 'add', 'c.gemspec' - system @git, 'commit', '--quiet', '-m', 'add c/c.gemspec' + system @git, "add", "c.gemspec" + system @git, "commit", "--quiet", "-m", "add c/c.gemspec" end head = `#{@git} rev-parse HEAD`.strip end - @git_set.add_git_gem 'a', repository, 'HEAD', true - @git_set.add_git_gem 'b', repository, 'HEAD', true - @git_set.add_git_gem 'c', repository, 'HEAD', true + @git_set.add_git_gem "a", repository, "HEAD", true + @git_set.add_git_gem "b", repository, "HEAD", true + @git_set.add_git_gem "c", repository, "HEAD", true - @set.gem 'b' + @set.gem "b" expected = <<-LOCKFILE GIT @@ -449,12 +450,12 @@ DEPENDENCIES end def test_write_error - @set.gem 'nonexistent' + @set.gem "nonexistent" gem_deps_lock_file = "#{@gem_deps_file}.lock" - File.open gem_deps_lock_file, 'w' do |io| - io.write 'hello' + File.open gem_deps_lock_file, "w" do |io| + io.write "hello" end assert_raise Gem::UnsatisfiableDependencyError do @@ -463,6 +464,6 @@ DEPENDENCIES assert_path_exist gem_deps_lock_file - assert_equal 'hello', File.read(gem_deps_lock_file) + assert_equal "hello", File.read(gem_deps_lock_file) end end diff --git a/test/rubygems/test_gem_request_set_lockfile_parser.rb b/test/rubygems/test_gem_request_set_lockfile_parser.rb index 2954df70d8..253a59b243 100644 --- a/test/rubygems/test_gem_request_set_lockfile_parser.rb +++ b/test/rubygems/test_gem_request_set_lockfile_parser.rb @@ -1,14 +1,15 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/request_set' -require 'rubygems/request_set/lockfile' -require 'rubygems/request_set/lockfile/tokenizer' -require 'rubygems/request_set/lockfile/parser' + +require_relative "helper" +require "rubygems/request_set" +require "rubygems/request_set/lockfile" +require "rubygems/request_set/lockfile/tokenizer" +require "rubygems/request_set/lockfile/parser" class TestGemRequestSetLockfileParser < Gem::TestCase def setup super - @gem_deps_file = 'gem.deps.rb' + @gem_deps_file = "gem.deps.rb" @lock_file = File.expand_path "#{@gem_deps_file}.lock" @set = Gem::RequestSet.new end @@ -53,7 +54,7 @@ class TestGemRequestSetLockfileParser < Gem::TestCase parser = tokenizer.make_parser nil, nil e = assert_raise Gem::RequestSet::Lockfile::ParseError do - parser.get :text, 'y' + parser.get :text, "y" end expected = @@ -83,7 +84,7 @@ DEPENDENCIES platforms = [] parse_lockfile @set, platforms - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies assert_equal [Gem::Platform::RUBY], platforms @@ -91,9 +92,9 @@ DEPENDENCIES Gem::Resolver::LockSet === set end - assert lockfile_set, 'could not find a LockSet' + assert lockfile_set, "could not find a LockSet" - assert_equal %w[a-2], lockfile_set.specs.map {|tuple| tuple.full_name } + assert_equal %w[a-2], lockfile_set.specs.map(&:full_name) end def test_parse_dependencies @@ -113,7 +114,7 @@ DEPENDENCIES platforms = [] parse_lockfile @set, platforms - assert_equal [dep('a', '>= 1', '<= 2')], @set.dependencies + assert_equal [dep("a", ">= 1", "<= 2")], @set.dependencies assert_equal [Gem::Platform::RUBY], platforms @@ -121,9 +122,9 @@ DEPENDENCIES Gem::Resolver::LockSet === set end - assert lockfile_set, 'could not find a LockSet' + assert lockfile_set, "could not find a LockSet" - assert_equal %w[a-2], lockfile_set.specs.map {|tuple| tuple.full_name } + assert_equal %w[a-2], lockfile_set.specs.map(&:full_name) end def test_parse_DEPENDENCIES_git @@ -159,8 +160,8 @@ DEPENDENCIES parse_lockfile @set, [] expected = [ - dep('i18n-active_record', '= 0.0.2'), - dep('rails-footnotes', '= 3.7.9'), + dep("i18n-active_record", "= 0.0.2"), + dep("rails-footnotes", "= 3.7.9"), ] assert_equal expected, @set.dependencies @@ -188,7 +189,7 @@ DEPENDENCIES parse_lockfile @set, [] expected = [ - dep('jwt', '= 1.1'), + dep("jwt", "= 1.1"), ] assert_equal expected, @set.dependencies @@ -209,15 +210,15 @@ DEPENDENCIES parse_lockfile @set, [] - assert_equal [dep('a', '>= 0')], @set.dependencies + assert_equal [dep("a", ">= 0")], @set.dependencies lockfile_set = @set.sets.find do |set| Gem::Resolver::LockSet === set end - assert lockfile_set, 'found a LockSet' + assert lockfile_set, "found a LockSet" - assert_equal %w[a-2], lockfile_set.specs.map {|s| s.full_name } + assert_equal %w[a-2], lockfile_set.specs.map(&:full_name) end def test_parse_GEM_remote_multiple @@ -237,27 +238,27 @@ DEPENDENCIES parse_lockfile @set, [] - assert_equal [dep('a', '>= 0')], @set.dependencies + assert_equal [dep("a", ">= 0")], @set.dependencies lockfile_set = @set.sets.find do |set| Gem::Resolver::LockSet === set end - assert lockfile_set, 'found a LockSet' + assert lockfile_set, "found a LockSet" - assert_equal %w[a-2], lockfile_set.specs.map {|s| s.full_name } + assert_equal %w[a-2], lockfile_set.specs.map(&:full_name) assert_equal %w[https://gems.example/ https://other.example/], - lockfile_set.specs.flat_map {|s| s.sources.map{|src| src.uri.to_s } } + lockfile_set.specs.flat_map {|s| s.sources.map {|src| src.uri.to_s } } end def test_parse_GIT - @set.instance_variable_set :@install_dir, 'install_dir' + @set.instance_variable_set :@install_dir, "install_dir" write_lockfile <<-LOCKFILE GIT remote: git://example/a.git - revision: master + revision: abranch specs: a (2) b (>= 3) @@ -269,31 +270,31 @@ DEPENDENCIES parse_lockfile @set, [] - assert_equal [dep('a', '= 2')], @set.dependencies + assert_equal [dep("a", "= 2")], @set.dependencies lockfile_set = @set.sets.find do |set| Gem::Resolver::LockSet === set end - refute lockfile_set, 'fount a LockSet' + refute lockfile_set, "found a LockSet" git_set = @set.sets.find do |set| Gem::Resolver::GitSet === set end - assert git_set, 'could not find a GitSet' + assert git_set, "could not find a GitSet" - assert_equal %w[a-2], git_set.specs.values.map {|s| s.full_name } + assert_equal %w[a-2], git_set.specs.values.map(&:full_name) - assert_equal [dep('b', '>= 3'), dep('c')], + assert_equal [dep("b", ">= 3"), dep("c")], git_set.specs.values.first.dependencies expected = { - 'a' => %w[git://example/a.git master], + "a" => %w[git://example/a.git abranch], } assert_equal expected, git_set.repositories - assert_equal 'install_dir', git_set.root_dir + assert_equal "install_dir", git_set.root_dir end def test_parse_GIT_branch @@ -312,22 +313,22 @@ DEPENDENCIES parse_lockfile @set, [] - assert_equal [dep('a', '= 2')], @set.dependencies + assert_equal [dep("a", "= 2")], @set.dependencies lockfile_set = @set.sets.find do |set| Gem::Resolver::LockSet === set end - refute lockfile_set, 'fount a LockSet' + refute lockfile_set, "found a LockSet" git_set = @set.sets.find do |set| Gem::Resolver::GitSet === set end - assert git_set, 'could not find a GitSet' + assert git_set, "could not find a GitSet" expected = { - 'a' => %w[git://example/a.git 1234abc], + "a" => %w[git://example/a.git 1234abc], } assert_equal expected, git_set.repositories @@ -349,22 +350,22 @@ DEPENDENCIES parse_lockfile @set, [] - assert_equal [dep('a', '= 2')], @set.dependencies + assert_equal [dep("a", "= 2")], @set.dependencies lockfile_set = @set.sets.find do |set| Gem::Resolver::LockSet === set end - refute lockfile_set, 'fount a LockSet' + refute lockfile_set, "found a LockSet" git_set = @set.sets.find do |set| Gem::Resolver::GitSet === set end - assert git_set, 'could not find a GitSet' + assert git_set, "could not find a GitSet" expected = { - 'a' => %w[git://example/a.git 1234abc], + "a" => %w[git://example/a.git 1234abc], } assert_equal expected, git_set.repositories @@ -386,22 +387,22 @@ DEPENDENCIES parse_lockfile @set, [] - assert_equal [dep('a', '= 2')], @set.dependencies + assert_equal [dep("a", "= 2")], @set.dependencies lockfile_set = @set.sets.find do |set| Gem::Resolver::LockSet === set end - refute lockfile_set, 'fount a LockSet' + refute lockfile_set, "found a LockSet" git_set = @set.sets.find do |set| Gem::Resolver::GitSet === set end - assert git_set, 'could not find a GitSet' + assert git_set, "could not find a GitSet" expected = { - 'a' => %w[git://example/a.git 1234abc], + "a" => %w[git://example/a.git 1234abc], } assert_equal expected, git_set.repositories @@ -423,45 +424,45 @@ DEPENDENCIES parse_lockfile @set, [] - assert_equal [dep('a', '= 1')], @set.dependencies + assert_equal [dep("a", "= 1")], @set.dependencies lockfile_set = @set.sets.find do |set| Gem::Resolver::LockSet === set end - refute lockfile_set, 'found a LockSet' + refute lockfile_set, "found a LockSet" vendor_set = @set.sets.find do |set| Gem::Resolver::VendorSet === set end - assert vendor_set, 'could not find a VendorSet' + assert vendor_set, "could not find a VendorSet" - assert_equal %w[a-1], vendor_set.specs.values.map {|s| s.full_name } + assert_equal %w[a-1], vendor_set.specs.values.map(&:full_name) - spec = vendor_set.load_spec 'a', nil, nil, nil + spec = vendor_set.load_spec "a", nil, nil, nil - assert_equal [dep('b', '= 2')], spec.dependencies + assert_equal [dep("b", "= 2")], spec.dependencies end def test_parse_dependency - write_lockfile ' 1)' + write_lockfile " 1)" tokenizer = Gem::RequestSet::Lockfile::Tokenizer.from_file @lock_file parser = tokenizer.make_parser nil, nil - parsed = parser.parse_dependency 'a', '=' + parsed = parser.parse_dependency "a", "=" - assert_equal dep('a', '= 1'), parsed + assert_equal dep("a", "= 1"), parsed - write_lockfile ')' + write_lockfile ")" tokenizer = Gem::RequestSet::Lockfile::Tokenizer.from_file @lock_file parser = tokenizer.make_parser nil, nil - parsed = parser.parse_dependency 'a', '2' + parsed = parser.parse_dependency "a", "2" - assert_equal dep('a', '= 2'), parsed + assert_equal dep("a", "= 2"), parsed end def test_parse_gem_specs_dependency @@ -486,7 +487,7 @@ DEPENDENCIES platforms = [] parse_lockfile @set, platforms - assert_equal [dep('a')], @set.dependencies + assert_equal [dep("a")], @set.dependencies assert_equal [Gem::Platform::RUBY], platforms @@ -494,24 +495,24 @@ DEPENDENCIES Gem::Resolver::LockSet === set end - assert lockfile_set, 'could not find a LockSet' + assert lockfile_set, "could not find a LockSet" - assert_equal %w[a-2 b-3], lockfile_set.specs.map {|tuple| tuple.full_name } + assert_equal %w[a-2 b-3], lockfile_set.specs.map(&:full_name) expected = [ Gem::Platform::RUBY, - Gem::Platform.new('x86_64-linux'), + Gem::Platform.new("x86_64-linux"), ] - assert_equal expected, lockfile_set.specs.map {|tuple| tuple.platform } + assert_equal expected, lockfile_set.specs.map(&:platform) spec = lockfile_set.specs.first expected = [ - dep('b', '= 3'), - dep('c', '~> 4'), - dep('d'), - dep('e', '~> 5.0', '>= 5.0.1'), + dep("b", "= 3"), + dep("c", "~> 4"), + dep("d"), + dep("e", "~> 5.0", ">= 5.0.1"), ] assert_equal expected, spec.dependencies @@ -530,7 +531,7 @@ DEPENDENCIES end def write_lockfile(lockfile) - File.open @lock_file, 'w' do |io| + File.open @lock_file, "w" do |io| io.write lockfile end end diff --git a/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb b/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb index a81ecac7b7..dce8c9ada5 100644 --- a/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb +++ b/test/rubygems/test_gem_request_set_lockfile_tokenizer.rb @@ -1,15 +1,16 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/request_set' -require 'rubygems/request_set/lockfile' -require 'rubygems/request_set/lockfile/tokenizer' -require 'rubygems/request_set/lockfile/parser' + +require_relative "helper" +require "rubygems/request_set" +require "rubygems/request_set/lockfile" +require "rubygems/request_set/lockfile/tokenizer" +require "rubygems/request_set/lockfile/parser" class TestGemRequestSetLockfileTokenizer < Gem::TestCase def setup super - @gem_deps_file = 'gem.deps.rb' + @gem_deps_file = "gem.deps.rb" @lock_file = File.expand_path "#{@gem_deps_file}.lock" end @@ -34,10 +35,10 @@ class TestGemRequestSetLockfileTokenizer < Gem::TestCase end def test_token_pos - tokenizer = Gem::RequestSet::Lockfile::Tokenizer.new '' + tokenizer = Gem::RequestSet::Lockfile::Tokenizer.new "" assert_equal [5, 0], tokenizer.token_pos(5) - tokenizer = Gem::RequestSet::Lockfile::Tokenizer.new '', nil, 1, 2 + tokenizer = Gem::RequestSet::Lockfile::Tokenizer.new "", nil, 1, 2 assert_equal [3, 1], tokenizer.token_pos(5) end @@ -63,74 +64,74 @@ DEPENDENCIES LOCKFILE expected = [ - [:section, 'GEM', 0, 0], + [:section, "GEM", 0, 0], [:newline, nil, 3, 0], - [:entry, 'remote', 2, 1], + [:entry, "remote", 2, 1], [:text, @gem_repo, 10, 1], [:newline, nil, 34, 1], - [:entry, 'specs', 2, 2], + [:entry, "specs", 2, 2], [:newline, nil, 8, 2], - [:text, 'a', 4, 3], + [:text, "a", 4, 3], [:l_paren, nil, 6, 3], - [:text, '2', 7, 3], + [:text, "2", 7, 3], [:r_paren, nil, 8, 3], [:newline, nil, 9, 3], - [:text, 'b', 6, 4], + [:text, "b", 6, 4], [:l_paren, nil, 8, 4], - [:requirement, '=', 9, 4], - [:text, '2', 11, 4], + [:requirement, "=", 9, 4], + [:text, "2", 11, 4], [:r_paren, nil, 12, 4], [:newline, nil, 13, 4], - [:text, 'c', 6, 5], + [:text, "c", 6, 5], [:l_paren, nil, 8, 5], - [:requirement, '!=', 9, 5], - [:text, '3', 12, 5], + [:requirement, "!=", 9, 5], + [:text, "3", 12, 5], [:r_paren, nil, 13, 5], [:newline, nil, 14, 5], - [:text, 'd', 6, 6], + [:text, "d", 6, 6], [:l_paren, nil, 8, 6], - [:requirement, '>', 9, 6], - [:text, '4', 11, 6], + [:requirement, ">", 9, 6], + [:text, "4", 11, 6], [:r_paren, nil, 12, 6], [:newline, nil, 13, 6], - [:text, 'e', 6, 7], + [:text, "e", 6, 7], [:l_paren, nil, 8, 7], - [:requirement, '<', 9, 7], - [:text, '5', 11, 7], + [:requirement, "<", 9, 7], + [:text, "5", 11, 7], [:r_paren, nil, 12, 7], [:newline, nil, 13, 7], - [:text, 'f', 6, 8], + [:text, "f", 6, 8], [:l_paren, nil, 8, 8], - [:requirement, '>=', 9, 8], - [:text, '6', 12, 8], + [:requirement, ">=", 9, 8], + [:text, "6", 12, 8], [:r_paren, nil, 13, 8], [:newline, nil, 14, 8], - [:text, 'g', 6, 9], + [:text, "g", 6, 9], [:l_paren, nil, 8, 9], - [:requirement, '<=', 9, 9], - [:text, '7', 12, 9], + [:requirement, "<=", 9, 9], + [:text, "7", 12, 9], [:r_paren, nil, 13, 9], [:newline, nil, 14, 9], - [:text, 'h', 6, 10], + [:text, "h", 6, 10], [:l_paren, nil, 8, 10], - [:requirement, '~>', 9, 10], - [:text, '8', 12, 10], + [:requirement, "~>", 9, 10], + [:text, "8", 12, 10], [:r_paren, nil, 13, 10], [:newline, nil, 14, 10], [:newline, nil, 0, 11], - [:section, 'PLATFORMS', 0, 12], + [:section, "PLATFORMS", 0, 12], [:newline, nil, 9, 12], [:text, Gem::Platform::RUBY, 2, 13], @@ -138,10 +139,10 @@ DEPENDENCIES [:newline, nil, 0, 14], - [:section, 'DEPENDENCIES', 0, 15], + [:section, "DEPENDENCIES", 0, 15], [:newline, nil, 12, 15], - [:text, 'a', 2, 16], + [:text, "a", 2, 16], [:newline, nil, 3, 16], ] @@ -163,27 +164,27 @@ DEPENDENCIES LOCKFILE expected = [ - [:section, 'GEM', 0, 0], + [:section, "GEM", 0, 0], [:newline, nil, 3, 0], - [:entry, 'remote', 2, 1], + [:entry, "remote", 2, 1], [:text, @gem_repo, 10, 1], [:newline, nil, 34, 1], - [:entry, 'specs', 2, 2], + [:entry, "specs", 2, 2], [:newline, nil, 8, 2], - [:text, 'Ab', 4, 3], + [:text, "Ab", 4, 3], [:l_paren, nil, 7, 3], - [:text, '2', 8, 3], + [:text, "2", 8, 3], [:r_paren, nil, 9, 3], [:newline, nil, 10, 3], [:newline, nil, 0, 4], - [:section, 'PLATFORMS', 0, 5], + [:section, "PLATFORMS", 0, 5], [:newline, nil, 9, 5], [:text, Gem::Platform::RUBY, 2, 6], [:newline, nil, 6, 6], [:newline, nil, 0, 7], - [:section, 'DEPENDENCIES', 0, 8], + [:section, "DEPENDENCIES", 0, 8], [:newline, nil, 12, 8], - [:text, 'Ab', 2, 9], + [:text, "Ab", 2, 9], [:newline, nil, 4, 9], ] @@ -191,7 +192,7 @@ DEPENDENCIES end def test_tokenize_conflict_markers - write_lockfile '<<<<<<<' + write_lockfile "<<<<<<<" e = assert_raise Gem::RequestSet::Lockfile::ParseError do tokenize_lockfile @@ -200,7 +201,7 @@ DEPENDENCIES assert_equal "your #{@lock_file} contains merge conflict markers (at line 0 column 0)", e.message - write_lockfile '|||||||' + write_lockfile "|||||||" e = assert_raise Gem::RequestSet::Lockfile::ParseError do tokenize_lockfile @@ -209,7 +210,7 @@ DEPENDENCIES assert_equal "your #{@lock_file} contains merge conflict markers (at line 0 column 0)", e.message - write_lockfile '=======' + write_lockfile "=======" e = assert_raise Gem::RequestSet::Lockfile::ParseError do tokenize_lockfile @@ -218,7 +219,7 @@ DEPENDENCIES assert_equal "your #{@lock_file} contains merge conflict markers (at line 0 column 0)", e.message - write_lockfile '>>>>>>>' + write_lockfile ">>>>>>>" e = assert_raise Gem::RequestSet::Lockfile::ParseError do tokenize_lockfile @@ -235,10 +236,10 @@ DEPENDENCIES LOCKFILE expected = [ - [:section, 'DEPENDENCIES', 0, 0], + [:section, "DEPENDENCIES", 0, 0], [:newline, nil, 12, 0], - [:text, 'a', 2, 1], + [:text, "a", 2, 1], [:bang, nil, 3, 1], [:newline, nil, 4, 1], ] @@ -256,29 +257,29 @@ GEM LOCKFILE expected = [ - [:section, 'GEM', 0, 0], + [:section, "GEM", 0, 0], [:newline, nil, 3, 0], - [:entry, 'remote', 2, 1], + [:entry, "remote", 2, 1], [:text, @gem_repo, 10, 1], [:newline, nil, 34, 1], - [:entry, 'specs', 2, 2], + [:entry, "specs", 2, 2], [:newline, nil, 8, 2], - [:text, 'a', 4, 3], + [:text, "a", 4, 3], [:l_paren, nil, 6, 3], - [:text, '2', 7, 3], + [:text, "2", 7, 3], [:r_paren, nil, 8, 3], [:newline, nil, 9, 3], - [:text, 'b', 6, 4], + [:text, "b", 6, 4], [:l_paren, nil, 8, 4], - [:requirement, '~>', 9, 4], - [:text, '3.0', 12, 4], + [:requirement, "~>", 9, 4], + [:text, "3.0", 12, 4], [:comma, nil, 15, 4], - [:requirement, '>=', 17, 4], - [:text, '3.0.1', 20, 4], + [:requirement, ">=", 17, 4], + [:text, "3.0.1", 20, 4], [:r_paren, nil, 25, 4], [:newline, nil, 26, 4], ] @@ -295,7 +296,7 @@ GEM end def write_lockfile(lockfile) - File.open @lock_file, 'w' do |io| + File.open @lock_file, "w" do |io| io.write lockfile end end diff --git a/test/rubygems/test_gem_requirement.rb b/test/rubygems/test_gem_requirement.rb index c4f05342bd..de0d11ec00 100644 --- a/test/rubygems/test_gem_requirement.rb +++ b/test/rubygems/test_gem_requirement.rb @@ -1,14 +1,23 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" require "rubygems/requirement" class TestGemRequirement < Gem::TestCase def test_concat - r = req '>= 1' + r = req ">= 1" - r.concat ['< 2'] + r.concat ["< 2"] - assert_equal [['>=', v(1)], ['<', v(2)]], r.requirements + assert_equal [[">=", v(1)], ["<", v(2)]], r.requirements + end + + def test_initialize_copy + r = req("= 1.2") + r2 = r.dup + + assert_equal r.requirements, r2.requirements + refute_same r.requirements, r2.requirements end def test_equals2 @@ -60,42 +69,42 @@ class TestGemRequirement < Gem::TestCase end def test_for_lockfile - assert_equal ' (~> 1.0)', req('~> 1.0').for_lockfile + assert_equal " (~> 1.0)", req("~> 1.0").for_lockfile - assert_equal ' (~> 1.0, >= 1.0.1)', req('>= 1.0.1', '~> 1.0').for_lockfile + assert_equal " (~> 1.0, >= 1.0.1)", req(">= 1.0.1", "~> 1.0").for_lockfile - duped = req '= 1.0' - duped.requirements << ['=', v('1.0')] + duped = req "= 1.0" + duped.requirements << ["=", v("1.0")] - assert_equal ' (= 1.0)', duped.for_lockfile + assert_equal " (= 1.0)", duped.for_lockfile assert_nil Gem::Requirement.default.for_lockfile end def test_parse - assert_equal ['=', Gem::Version.new(1)], Gem::Requirement.parse(' 1') - assert_equal ['=', Gem::Version.new(1)], Gem::Requirement.parse('= 1') - assert_equal ['>', Gem::Version.new(1)], Gem::Requirement.parse('> 1') - assert_equal ['=', Gem::Version.new(1)], Gem::Requirement.parse("=\n1") - assert_equal ['=', Gem::Version.new(1)], Gem::Requirement.parse('1.0') + assert_equal ["=", Gem::Version.new(1)], Gem::Requirement.parse(" 1") + assert_equal ["=", Gem::Version.new(1)], Gem::Requirement.parse("= 1") + assert_equal [">", Gem::Version.new(1)], Gem::Requirement.parse("> 1") + assert_equal ["=", Gem::Version.new(1)], Gem::Requirement.parse("=\n1") + assert_equal ["=", Gem::Version.new(1)], Gem::Requirement.parse("1.0") - assert_equal ['=', Gem::Version.new(2)], - Gem::Requirement.parse(Gem::Version.new('2')) + assert_equal ["=", Gem::Version.new(2)], + Gem::Requirement.parse(Gem::Version.new("2")) end - if RUBY_VERSION >= '2.5' && !(Gem.java_platform? && ENV["JRUBY_OPTS"] =~ /--debug/) + unless Gem.java_platform? && ENV["JRUBY_OPTS"].to_s.include?("--debug") def test_parse_deduplication - assert_same '~>', Gem::Requirement.parse('~> 1').first + assert_same "~>", Gem::Requirement.parse("~> 1").first end end def test_parse_bad [ nil, - '', - '! 1', - '= junk', - '1..2', + "", + "! 1", + "= junk", + "1..2", ].each do |bad| e = assert_raise Gem::Requirement::BadRequirementError do Gem::Requirement.parse bad @@ -108,28 +117,30 @@ class TestGemRequirement < Gem::TestCase end def test_prerelease_eh - r = req '= 1' + r = req "= 1" refute r.prerelease? - r = req '= 1.a' + r = req "= 1.a" assert r.prerelease? - r = req '> 1.a', '< 2' + r = req "> 1.a", "< 2" assert r.prerelease? end def test_satisfied_by_eh_bang_equal - r = req '!= 1.2' + r = req "!= 1.2" assert_satisfied_by "1.1", r refute_satisfied_by "1.2", r assert_satisfied_by "1.3", r assert_raise ArgumentError do - assert_satisfied_by nil, r + Gem::Deprecate.skip_during do + assert_satisfied_by nil, r + end end end @@ -141,7 +152,9 @@ class TestGemRequirement < Gem::TestCase refute_satisfied_by "1.3", r assert_raise ArgumentError do - assert_satisfied_by nil, r + Gem::Deprecate.skip_during do + assert_satisfied_by nil, r + end end end @@ -153,7 +166,9 @@ class TestGemRequirement < Gem::TestCase refute_satisfied_by "1.3", r assert_raise ArgumentError do - assert_satisfied_by nil, r + Gem::Deprecate.skip_during do + assert_satisfied_by nil, r + end end end @@ -280,7 +295,7 @@ class TestGemRequirement < Gem::TestCase end def test_illformed_requirements - [ ">>> 1.3.5", "> blah" ].each do |rq| + [">>> 1.3.5", "> blah"].each do |rq| assert_raise Gem::Requirement::BadRequirementError, "req [#{rq}] should fail" do Gem::Requirement.new rq end @@ -362,16 +377,16 @@ class TestGemRequirement < Gem::TestCase end def test_specific - refute req('> 1') .specific? - refute req('>= 1').specific? + refute req("> 1") .specific? + refute req(">= 1").specific? - assert req('!= 1').specific? - assert req('< 1') .specific? - assert req('<= 1').specific? - assert req('= 1') .specific? - assert req('~> 1').specific? + assert req("!= 1").specific? + assert req("< 1") .specific? + assert req("<= 1").specific? + assert req("= 1") .specific? + assert req("~> 1").specific? - assert req('> 1', '> 2').specific? # GIGO + assert req("> 1", "> 2").specific? # GIGO end def test_bad @@ -392,12 +407,12 @@ class TestGemRequirement < Gem::TestCase end def test_hash_with_multiple_versions - r1 = req('1.0', '2.0') - r2 = req('2.0', '1.0') + r1 = req("1.0", "2.0") + r2 = req("2.0", "1.0") assert_equal r1.hash, r2.hash - r1 = req('1.0', '2.0').tap {|r| r.concat(['3.0']) } - r2 = req('3.0', '1.0').tap {|r| r.concat(['2.0']) } + r1 = req("1.0", "2.0").tap {|r| r.concat(["3.0"]) } + r2 = req("3.0", "1.0").tap {|r| r.concat(["2.0"]) } assert_equal r1.hash, r2.hash end @@ -422,6 +437,40 @@ class TestGemRequirement < Gem::TestCase assert_requirement_hash_equal "1", "1.0.0" end + class Exploit < RuntimeError + end + + def self.exploit(arg) + raise Exploit, "arg = #{arg}" + end + + def test_marshal_load_attack + wa = Gem::Net::WriteAdapter.allocate + wa.instance_variable_set(:@socket, self.class) + wa.instance_variable_set(:@method_id, :exploit) + request_set = Gem::RequestSet.allocate + request_set.instance_variable_set(:@git_set, "id") + request_set.instance_variable_set(:@sets, wa) + wa = Gem::Net::WriteAdapter.allocate + wa.instance_variable_set(:@socket, request_set) + wa.instance_variable_set(:@method_id, :resolve) + ent = Gem::Package::TarReader::Entry.allocate + ent.instance_variable_set(:@read, 0) + ent.instance_variable_set(:@header, "aaa") + io = Gem::Net::BufferedIO.allocate + io.instance_variable_set(:@io, ent) + io.instance_variable_set(:@debug_output, wa) + reader = Gem::Package::TarReader.allocate + reader.instance_variable_set(:@io, io) + requirement = Gem::Requirement.allocate + requirement.instance_variable_set(:@requirements, reader) + m = [Gem::SpecFetcher, Gem::Installer, requirement] + e = assert_raise(TypeError) do + Marshal.load(Marshal.dump(m)) + end + assert_equal(e.message, "wrong @requirements") + end + # Assert that two requirements are equal. Handles Gem::Requirements, # strings, arrays, numbers, and versions. diff --git a/test/rubygems/test_gem_resolver.rb b/test/rubygems/test_gem_resolver.rb index fbf9438122..b7dadda708 100644 --- a/test/rubygems/test_gem_resolver.rb +++ b/test/rubygems/test_gem_resolver.rb @@ -1,19 +1,14 @@ # frozen_string_literal: true -require 'rubygems/test_case' -class TestGemResolver < Gem::TestCase - def setup - super - - @DR = Gem::Resolver - end +require_relative "helper" +class TestGemResolver < Gem::TestCase def make_dep(name, *req) Gem::Dependency.new(name, *req) end def set(*specs) - source = Gem::Source.new URI @gem_repo + source = Gem::Source.new Gem::URI @gem_repo specs = specs.map do |spec| Gem::Resolver::SpecSpecification.new nil, spec, source @@ -25,10 +20,10 @@ class TestGemResolver < Gem::TestCase def assert_resolves_to(expected, resolver) actual = resolver.resolve - exp = expected.sort_by {|s| s.full_name } - act = actual.map {|a| a.spec.spec }.sort_by {|s| s.full_name } + exp = expected.sort_by(&:full_name) + act = actual.map {|a| a.spec.spec }.sort_by(&:full_name) - msg = "Set of gems was not the same: #{exp.map {|x| x.full_name }.inspect} != #{act.map {|x| x.full_name }.inspect}" + msg = "Set of gems was not the same: #{exp.map(&:full_name).inspect} != #{act.map(&:full_name).inspect}" assert_equal exp, act, msg rescue Gem::DependencyResolutionError => e @@ -36,18 +31,18 @@ class TestGemResolver < Gem::TestCase end def test_self_compose_sets_best_set - best_set = @DR::BestSet.new + best_set = Gem::Resolver::BestSet.new - composed = @DR.compose_sets best_set + composed = Gem::Resolver.compose_sets best_set assert_equal best_set, composed end def test_self_compose_sets_multiple - index_set = @DR::IndexSet.new - vendor_set = @DR::VendorSet.new + index_set = Gem::Resolver::IndexSet.new + vendor_set = Gem::Resolver::VendorSet.new - composed = @DR.compose_sets index_set, vendor_set + composed = Gem::Resolver.compose_sets index_set, vendor_set assert_kind_of Gem::Resolver::ComposedSet, composed @@ -55,14 +50,14 @@ class TestGemResolver < Gem::TestCase end def test_self_compose_sets_nest - index_set = @DR::IndexSet.new - vendor_set = @DR::VendorSet.new + index_set = Gem::Resolver::IndexSet.new + vendor_set = Gem::Resolver::VendorSet.new - inner = @DR.compose_sets index_set, vendor_set + inner = Gem::Resolver.compose_sets index_set, vendor_set - current_set = @DR::CurrentSet.new + current_set = Gem::Resolver::CurrentSet.new - composed = @DR.compose_sets inner, current_set + composed = Gem::Resolver.compose_sets inner, current_set assert_kind_of Gem::Resolver::ComposedSet, composed @@ -70,31 +65,31 @@ class TestGemResolver < Gem::TestCase end def test_self_compose_sets_nil - index_set = @DR::IndexSet.new + index_set = Gem::Resolver::IndexSet.new - composed = @DR.compose_sets index_set, nil + composed = Gem::Resolver.compose_sets index_set, nil assert_same index_set, composed e = assert_raise ArgumentError do - @DR.compose_sets nil + Gem::Resolver.compose_sets nil end - assert_equal 'one set in the composition must be non-nil', e.message + assert_equal "one set in the composition must be non-nil", e.message end def test_self_compose_sets_single - index_set = @DR::IndexSet.new + index_set = Gem::Resolver::IndexSet.new - composed = @DR.compose_sets index_set + composed = Gem::Resolver.compose_sets index_set assert_same index_set, composed end def test_requests - a1 = util_spec 'a', 1, 'b' => 2 + a1 = util_spec "a", 1, "b" => 2 - r1 = Gem::Resolver::DependencyRequest.new dep('a', '= 1'), nil + r1 = Gem::Resolver::DependencyRequest.new dep("a", "= 1"), nil act = Gem::Resolver::ActivationRequest.new a1, r1 @@ -104,18 +99,18 @@ class TestGemResolver < Gem::TestCase res.requests a1, act, reqs - assert_equal ['b (= 2)'], reqs.map {|req| req.to_s } + assert_equal ["b (= 2)"], reqs.map(&:to_s) end def test_requests_development - a1 = util_spec 'a', 1, 'b' => 2 + a1 = util_spec "a", 1, "b" => 2 spec = Gem::Resolver::SpecSpecification.new nil, a1 def spec.fetch_development_dependencies @called = true end - r1 = Gem::Resolver::DependencyRequest.new dep('a', '= 1'), nil + r1 = Gem::Resolver::DependencyRequest.new dep("a", "= 1"), nil act = Gem::Resolver::ActivationRequest.new spec, r1 @@ -126,15 +121,15 @@ class TestGemResolver < Gem::TestCase res.requests spec, act, reqs - assert_equal ['b (= 2)'], reqs.map {|req| req.to_s } + assert_equal ["b (= 2)"], reqs.map(&:to_s) assert spec.instance_variable_defined? :@called end def test_requests_ignore_dependencies - a1 = util_spec 'a', 1, 'b' => 2 + a1 = util_spec "a", 1, "b" => 2 - r1 = Gem::Resolver::DependencyRequest.new dep('a', '= 1'), nil + r1 = Gem::Resolver::DependencyRequest.new dep("a", "= 1"), nil act = Gem::Resolver::ActivationRequest.new a1, r1 @@ -149,37 +144,37 @@ class TestGemResolver < Gem::TestCase end def test_resolve_conservative - a1_spec = util_spec 'a', 1 + a1_spec = util_spec "a", 1 - a2_spec = util_spec 'a', 2 do |s| - s.add_dependency 'b', 2 - s.add_dependency 'c' + a2_spec = util_spec "a", 2 do |s| + s.add_dependency "b", 2 + s.add_dependency "c" end - b1_spec = util_spec 'b', 1 - b2_spec = util_spec 'b', 2 + b1_spec = util_spec "b", 1 + b2_spec = util_spec "b", 2 - c1_spec = util_spec 'c', 1 do |s| - s.add_dependency 'd', 2 + c1_spec = util_spec "c", 1 do |s| + s.add_dependency "d", 2 end - c2_spec = util_spec 'c', 2 do |s| - s.add_dependency 'd', 2 + c2_spec = util_spec "c", 2 do |s| + s.add_dependency "d", 2 end - d1_spec = util_spec 'd', 1 do |s| - s.add_dependency 'e' + d1_spec = util_spec "d", 1 do |s| + s.add_dependency "e" end - d2_spec = util_spec 'd', 2 do |s| - s.add_dependency 'e' + d2_spec = util_spec "d", 2 do |s| + s.add_dependency "e" end - e1_spec = util_spec 'e', 1 - e2_spec = util_spec 'e', 2 + e1_spec = util_spec "e", 1 + e2_spec = util_spec "e", 2 - a_dep = make_dep 'a', '= 2' - e_dep = make_dep 'e' + a_dep = make_dep "a", "= 2" + e_dep = make_dep "e" # When requesting to install: # a-2, e @@ -191,7 +186,7 @@ class TestGemResolver < Gem::TestCase # With the following gems already installed: # a-1, b-1, c-1, e-1 - res.skip_gems = {'a' => [a1_spec], 'b' => [b1_spec], 'c' => [c1_spec], 'e' => [e1_spec]} + res.skip_gems = { "a" => [a1_spec], "b" => [b1_spec], "c" => [c1_spec], "e" => [e1_spec] } # Make sure the following gems end up getting used/installed/upgraded: # a-2 (upgraded) @@ -203,17 +198,17 @@ class TestGemResolver < Gem::TestCase end def test_resolve_development - a_spec = util_spec 'a', 1 do |s| - s.add_development_dependency 'b' + a_spec = util_spec "a", 1 do |s| + s.add_development_dependency "b" end - b_spec = util_spec 'b', 1 do - |s| s.add_development_dependency 'c' + b_spec = util_spec "b", 1 do |s| + s.add_development_dependency "c" end - c_spec = util_spec 'c', 1 + c_spec = util_spec "c", 1 - a_dep = make_dep 'a', '= 1' + a_dep = make_dep "a", "= 1" deps = [a_dep] @@ -227,24 +222,24 @@ class TestGemResolver < Gem::TestCase end def test_resolve_development_shallow - a_spec = util_spec 'a', 1 do |s| - s.add_development_dependency 'b' - s.add_runtime_dependency 'd' + a_spec = util_spec "a", 1 do |s| + s.add_development_dependency "b" + s.add_runtime_dependency "d" end - b_spec = util_spec 'b', 1 do |s| - s.add_development_dependency 'c' + b_spec = util_spec "b", 1 do |s| + s.add_development_dependency "c" end - c_spec = util_spec 'c', 1 + c_spec = util_spec "c", 1 - d_spec = util_spec 'd', 1 do |s| - s.add_development_dependency 'e' + d_spec = util_spec "d", 1 do |s| + s.add_development_dependency "e" end - e_spec = util_spec 'e', 1 + e_spec = util_spec "e", 1 - a_dep = make_dep 'a', '= 1' + a_dep = make_dep "a", "= 1" deps = [a_dep] @@ -262,19 +257,19 @@ class TestGemResolver < Gem::TestCase @fetcher = Gem::FakeFetcher.new Gem::RemoteFetcher.fetcher = @fetcher - a_dep = make_dep 'a', '= 1' + a_dep = make_dep "a", "= 1" res = Gem::Resolver.new [a_dep], Gem::Resolver::IndexSet.new - e = assert_raise Gem::UnsatisfiableDepedencyError do + e = assert_raise Gem::UnsatisfiableDependencyError do res.resolve end refute_empty e.errors end - def test_no_overlap_specificly - a = util_spec "a", '1' + def test_no_overlap_specifically + a = util_spec "a", "1" b = util_spec "b", "1" ad = make_dep "a", "= 1" @@ -290,7 +285,7 @@ class TestGemResolver < Gem::TestCase end def test_pulls_in_dependencies - a = util_spec "a", '1' + a = util_spec "a", "1" b = util_spec "b", "1", "c" => "= 1" c = util_spec "c", "1" @@ -307,8 +302,8 @@ class TestGemResolver < Gem::TestCase end def test_picks_highest_version - a1 = util_spec "a", '1' - a2 = util_spec "a", '2' + a1 = util_spec "a", "1" + a2 = util_spec "a", "2" s = set(a1, a2) @@ -321,17 +316,16 @@ class TestGemResolver < Gem::TestCase def test_picks_best_platform is = Gem::Resolver::IndexSpecification - unknown = Gem::Platform.new 'unknown' - a2_p1 = a3_p2 = nil + unknown = Gem::Platform.new "unknown" spec_fetcher do |fetcher| - fetcher.spec 'a', 2 + fetcher.spec "a", 2 - a2_p1 = fetcher.spec 'a', 2 do |s| + fetcher.spec "a", 2 do |s| s.platform = Gem::Platform.local end - a3_p2 = fetcher.spec 'a', 3 do |s| + fetcher.spec "a", 3 do |s| s.platform = unknown end end @@ -342,9 +336,9 @@ class TestGemResolver < Gem::TestCase s = set - a2 = is.new s, 'a', v2, source, Gem::Platform::RUBY - a2_p1 = is.new s, 'a', v2, source, Gem::Platform.local.to_s - a3_p2 = is.new s, 'a', v3, source, unknown + a2 = is.new s, "a", v2, source, Gem::Platform::RUBY + a2_p1 = is.new s, "a", v2, source, Gem::Platform.local.to_s + a3_p2 = is.new s, "a", v3, source, unknown s.add a3_p2 s.add a2_p1 @@ -357,6 +351,74 @@ class TestGemResolver < Gem::TestCase assert_resolves_to [a2_p1.spec], res end + def test_does_not_pick_musl_variants_on_non_musl_linux + util_set_arch "aarch64-linux" do + is = Gem::Resolver::IndexSpecification + + linux_musl = Gem::Platform.new("aarch64-linux-musl") + + spec_fetcher do |fetcher| + fetcher.spec "libv8-node", "15.14.0.1" do |s| + s.platform = Gem::Platform.local + end + + fetcher.spec "libv8-node", "15.14.0.1" do |s| + s.platform = linux_musl + end + end + + v15 = v("15.14.0.1") + source = Gem::Source.new @gem_repo + + s = set + + v15_linux = is.new s, "libv8-node", v15, source, Gem::Platform.local.to_s + v15_linux_musl = is.new s, "libv8-node", v15, source, linux_musl.to_s + + s.add v15_linux + s.add v15_linux_musl + + ad = make_dep "libv8-node", "= 15.14.0.1" + + res = Gem::Resolver.new([ad], s) + + assert_resolves_to [v15_linux.spec], res + end + end + + def test_pick_generic_linux_variants_on_musl_linux + util_set_arch "aarch64-linux-musl" do + is = Gem::Resolver::IndexSpecification + + linux = Gem::Platform.new("aarch64-linux") + + spec_fetcher do |fetcher| + fetcher.spec "libv8-node", "15.14.0.1" do |s| + s.platform = linux + end + + fetcher.spec "libv8-node", "15.14.0.1" + end + + v15 = v("15.14.0.1") + source = Gem::Source.new @gem_repo + + s = set + + v15_ruby = is.new s, "libv8-node", v15, source, Gem::Platform::RUBY + v15_linux = is.new s, "libv8-node", v15, source, linux.to_s + + s.add v15_linux + s.add v15_ruby + + ad = make_dep "libv8-node", "= 15.14.0.1" + + res = Gem::Resolver.new([ad], s) + + assert_resolves_to [v15_linux.spec], res + end + end + def test_only_returns_spec_once a1 = util_spec "a", "1", "c" => "= 1" b1 = util_spec "b", "1", "c" => "= 1" @@ -469,7 +531,7 @@ class TestGemResolver < Gem::TestCase r = Gem::Resolver.new([ad], set) - e = assert_raise Gem::UnsatisfiableDepedencyError do + e = assert_raise Gem::UnsatisfiableDependencyError do r.resolve end @@ -486,7 +548,7 @@ class TestGemResolver < Gem::TestCase r = Gem::Resolver.new([ad], set(a1)) - e = assert_raise Gem::UnsatisfiableDepedencyError do + e = assert_raise Gem::UnsatisfiableDependencyError do r.resolve end @@ -499,7 +561,7 @@ class TestGemResolver < Gem::TestCase r = Gem::Resolver.new([ad], set(a1)) - e = assert_raise Gem::UnsatisfiableDepedencyError do + e = assert_raise Gem::UnsatisfiableDependencyError do r.resolve end @@ -509,14 +571,14 @@ class TestGemResolver < Gem::TestCase def test_raises_and_reports_an_implicit_request_properly a1 = util_spec "a", "1" do |s| - s.add_runtime_dependency 'b', '= 2' + s.add_runtime_dependency "b", "= 2" end ad = make_dep "a", "= 1" r = Gem::Resolver.new([ad], set(a1)) - e = assert_raise Gem::UnsatisfiableDepedencyError do + e = assert_raise Gem::UnsatisfiableDependencyError do r.resolve end @@ -546,14 +608,14 @@ class TestGemResolver < Gem::TestCase dependency = e.conflict.dependency assert_includes %w[a b], dependency.name - assert_equal req('>= 0'), dependency.requirement + assert_equal req(">= 0"), dependency.requirement activated = e.conflict.activated - assert_equal 'c-1', activated.full_name + assert_equal "c-1", activated.full_name - assert_equal dep('c', '= 1'), activated.request.dependency + assert_equal dep("c", "= 1"), activated.request.dependency - assert_equal [dep('c', '>= 2'), dep('c', '= 1')], + assert_equal [dep("c", ">= 2"), dep("c", "= 1")], e.conflict.conflicting_dependencies end @@ -617,15 +679,15 @@ class TestGemResolver < Gem::TestCase end def test_resolve_conflict - a1 = util_spec 'a', 1 - a2 = util_spec 'a', 2 + a1 = util_spec "a", 1 + a2 = util_spec "a", 2 - b2 = util_spec 'b', 2, 'a' => '~> 2.0' + b2 = util_spec "b", 2, "a" => "~> 2.0" s = set a1, a2, b2 - a_dep = dep 'a', '~> 1.0' - b_dep = dep 'b' + a_dep = dep "a", "~> 1.0" + b_dep = dep "b" r = Gem::Resolver.new [a_dep, b_dep], s @@ -635,18 +697,18 @@ class TestGemResolver < Gem::TestCase end def test_resolve_bug_699 - a1 = util_spec 'a', '1', 'b' => '= 2', - 'c' => '~> 1.0.3' + a1 = util_spec "a", "1", "b" => "= 2", + "c" => "~> 1.0.3" - b1 = util_spec 'b', '2', 'c' => '~> 1.0' + b1 = util_spec "b", "2", "c" => "~> 1.0" - c1 = util_spec 'c', '1.0.9' - c2 = util_spec 'c', '1.1.0' - c3 = util_spec 'c', '1.2.0' + c1 = util_spec "c", "1.0.9" + c2 = util_spec "c", "1.1.0" + c3 = util_spec "c", "1.2.0" s = set a1, b1, c1, c2, c3 - a_dep = dep 'a', '= 1' + a_dep = dep "a", "= 1" r = Gem::Resolver.new [a_dep], s @@ -654,16 +716,16 @@ class TestGemResolver < Gem::TestCase end def test_resolve_rollback - a1 = util_spec 'a', 1 - a2 = util_spec 'a', 2 + a1 = util_spec "a", 1 + a2 = util_spec "a", 2 - b1 = util_spec 'b', 1, 'a' => '~> 1.0' - b2 = util_spec 'b', 2, 'a' => '~> 2.0' + b1 = util_spec "b", 1, "a" => "~> 1.0" + b2 = util_spec "b", 2, "a" => "~> 2.0" s = set a1, a2, b1, b2 - a_dep = dep 'a', '~> 1.0' - b_dep = dep 'b' + a_dep = dep "a", "~> 1.0" + b_dep = dep "b" r = Gem::Resolver.new [a_dep, b_dep], s @@ -711,42 +773,42 @@ class TestGemResolver < Gem::TestCase end def test_sorts_by_source_then_version - sourceA = Gem::Source.new 'http://example.com/a' - sourceB = Gem::Source.new 'http://example.com/b' - sourceC = Gem::Source.new 'http://example.com/c' + source_a = Gem::Source.new "http://example.com/a" + source_b = Gem::Source.new "http://example.com/b" + source_c = Gem::Source.new "http://example.com/c" - spec_A_1 = util_spec 'some-dep', '0.0.1' - spec_A_2 = util_spec 'some-dep', '1.0.0' - spec_B_1 = util_spec 'some-dep', '0.0.1' - spec_B_2 = util_spec 'some-dep', '0.0.2' - spec_C_1 = util_spec 'some-dep', '0.1.0' + spec_a_1 = util_spec "some-dep", "0.0.1" + spec_a_2 = util_spec "some-dep", "1.0.0" + spec_b_1 = util_spec "some-dep", "0.0.1" + spec_b_2 = util_spec "some-dep", "0.0.2" + spec_c_1 = util_spec "some-dep", "0.1.0" set = StaticSet.new [ - Gem::Resolver::SpecSpecification.new(nil, spec_B_1, sourceB), - Gem::Resolver::SpecSpecification.new(nil, spec_B_2, sourceB), - Gem::Resolver::SpecSpecification.new(nil, spec_C_1, sourceC), - Gem::Resolver::SpecSpecification.new(nil, spec_A_2, sourceA), - Gem::Resolver::SpecSpecification.new(nil, spec_A_1, sourceA), + Gem::Resolver::SpecSpecification.new(nil, spec_b_1, source_b), + Gem::Resolver::SpecSpecification.new(nil, spec_b_2, source_b), + Gem::Resolver::SpecSpecification.new(nil, spec_c_1, source_c), + Gem::Resolver::SpecSpecification.new(nil, spec_a_2, source_a), + Gem::Resolver::SpecSpecification.new(nil, spec_a_1, source_a), ] - dependency = make_dep 'some-dep', '> 0' + dependency = make_dep "some-dep", "> 0" resolver = Gem::Resolver.new [dependency], set - assert_resolves_to [spec_B_2], resolver + assert_resolves_to [spec_b_2], resolver end def test_select_local_platforms r = Gem::Resolver.new nil, nil - a1 = util_spec 'a', 1 + a1 = util_spec "a", 1 - a1_p1 = util_spec 'a', 1 do |s| + a1_p1 = util_spec "a", 1 do |s| s.platform = Gem::Platform.local end - a1_p2 = util_spec 'a', 1 do |s| - s.platform = 'unknown' + a1_p2 = util_spec "a", 1 do |s| + s.platform = "unknown" end selected = r.select_local_platforms [a1, a1_p1, a1_p2] @@ -755,18 +817,18 @@ class TestGemResolver < Gem::TestCase end def test_search_for_local_platform_partial_string_match - a1 = util_spec 'a', 1 + a1 = util_spec "a", 1 - a1_p1 = util_spec 'a', 1 do |s| + a1_p1 = util_spec "a", 1 do |s| s.platform = Gem::Platform.local.os end - a1_p2 = util_spec 'a', 1 do |s| - s.platform = 'unknown' + a1_p2 = util_spec "a", 1 do |s| + s.platform = "unknown" end s = set(a1_p1, a1_p2, a1) - d = [make_dep('a')] + d = [make_dep("a")] r = Gem::Resolver.new(d, s) assert_resolves_to [a1_p1], r @@ -781,7 +843,7 @@ class TestGemResolver < Gem::TestCase r = Gem::Resolver.new([ad], set(a1)) - e = assert_raise Gem::UnsatisfiableDepedencyError do + e = assert_raise Gem::UnsatisfiableDependencyError do r.resolve end diff --git a/test/rubygems/test_gem_resolver_activation_request.rb b/test/rubygems/test_gem_resolver_activation_request.rb index f973c5956d..53875b72cb 100644 --- a/test/rubygems/test_gem_resolver_activation_request.rb +++ b/test/rubygems/test_gem_resolver_activation_request.rb @@ -1,41 +1,40 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" class TestGemResolverActivationRequest < Gem::TestCase def setup super - @DR = Gem::Resolver - - @dep = @DR::DependencyRequest.new dep('a', '>= 0'), nil + @dep = Gem::Resolver::DependencyRequest.new dep("a", ">= 0"), nil source = Gem::Source::Local.new platform = Gem::Platform::RUBY - @a3 = @DR::IndexSpecification.new nil, 'a', v(3), source, platform + @a3 = Gem::Resolver::IndexSpecification.new nil, "a", v(3), source, platform - @req = @DR::ActivationRequest.new @a3, @dep + @req = Gem::Resolver::ActivationRequest.new @a3, @dep end def test_development_eh refute @req.development? - dep_req = @DR::DependencyRequest.new dep('a', '>= 0', :development), nil + dep_req = Gem::Resolver::DependencyRequest.new dep("a", ">= 0", :development), nil - act_req = @DR::ActivationRequest.new @a3, dep_req + act_req = Gem::Resolver::ActivationRequest.new @a3, dep_req assert act_req.development? end def test_inspect - assert_match 'a-3', @req.inspect - assert_match 'from a (>= 0)', @req.inspect + assert_match "a-3", @req.inspect + assert_match "from a (>= 0)", @req.inspect end def test_installed_eh v_spec = Gem::Resolver::VendorSpecification.new nil, @a3 - @req = @DR::ActivationRequest.new v_spec, @dep + @req = Gem::Resolver::ActivationRequest.new v_spec, @dep assert @req.installed? end diff --git a/test/rubygems/test_gem_resolver_api_set.rb b/test/rubygems/test_gem_resolver_api_set.rb index aa17ec6f3a..5781cf37d2 100644 --- a/test/rubygems/test_gem_resolver_api_set.rb +++ b/test/rubygems/test_gem_resolver_api_set.rb @@ -1,55 +1,55 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" class TestGemResolverAPISet < Gem::TestCase def setup super - @DR = Gem::Resolver - @dep_uri = URI "#{@gem_repo}info/" + @dep_uri = Gem::URI "#{@gem_repo}info/" end def test_initialize - set = @DR::APISet.new + set = Gem::Resolver::APISet.new - assert_equal URI('https://index.rubygems.org/info/'), set.dep_uri - assert_equal URI('https://index.rubygems.org/'), set.uri - assert_equal Gem::Source.new(URI('https://index.rubygems.org')), set.source + assert_equal Gem::URI("https://index.rubygems.org/info/"), set.dep_uri + assert_equal Gem::URI("https://index.rubygems.org/"), set.uri + assert_equal Gem::Source.new(Gem::URI("https://index.rubygems.org")), set.source end def test_initialize_deeper_uri - set = @DR::APISet.new 'https://rubygemsserver.com/mygems/info' + set = Gem::Resolver::APISet.new "https://rubygemsserver.com/mygems/info" - assert_equal URI('https://rubygemsserver.com/mygems/info'), set.dep_uri - assert_equal URI('https://rubygemsserver.com/'), set.uri - assert_equal Gem::Source.new(URI('https://rubygemsserver.com/')), set.source + assert_equal Gem::URI("https://rubygemsserver.com/mygems/info"), set.dep_uri + assert_equal Gem::URI("https://rubygemsserver.com/"), set.uri + assert_equal Gem::Source.new(Gem::URI("https://rubygemsserver.com/")), set.source end def test_initialize_uri - set = @DR::APISet.new @dep_uri + set = Gem::Resolver::APISet.new @dep_uri - assert_equal URI("#{@gem_repo}info/"), set.dep_uri - assert_equal URI("#{@gem_repo}"), set.uri + assert_equal Gem::URI("#{@gem_repo}info/"), set.dep_uri + assert_equal Gem::URI(@gem_repo.to_s), set.uri end def test_find_all spec_fetcher data = [ - { :name => 'a', - :number => '1', - :platform => 'ruby', - :dependencies => [] }, + { name: "a", + number: "1", + platform: "ruby", + dependencies: [] }, ] @fetcher.data["#{@dep_uri}a"] = "---\n1 " - set = @DR::APISet.new @dep_uri + set = Gem::Resolver::APISet.new @dep_uri - a_dep = @DR::DependencyRequest.new dep('a'), nil + a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil expected = [ - @DR::APISpecification.new(set, data.first), + Gem::Resolver::APISpecification.new(set, data.first), ] assert_equal expected, set.find_all(a_dep) @@ -59,26 +59,26 @@ class TestGemResolverAPISet < Gem::TestCase spec_fetcher data = [ - { :name => 'a', - :number => '1', - :platform => 'ruby', - :dependencies => [] }, - { :name => 'a', - :number => '2.a', - :platform => 'ruby', - :dependencies => [] }, + { name: "a", + number: "1", + platform: "ruby", + dependencies: [] }, + { name: "a", + number: "2.a", + platform: "ruby", + dependencies: [] }, ] @fetcher.data["#{@dep_uri}a"] = "---\n1\n2.a" - set = @DR::APISet.new @dep_uri + set = Gem::Resolver::APISet.new @dep_uri set.prerelease = true - a_dep = @DR::DependencyRequest.new dep('a'), nil + a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil expected = [ - @DR::APISpecification.new(set, data.first), - @DR::APISpecification.new(set, data.last), + Gem::Resolver::APISpecification.new(set, data.first), + Gem::Resolver::APISpecification.new(set, data.last), ] assert_equal expected, set.find_all(a_dep) @@ -88,22 +88,22 @@ class TestGemResolverAPISet < Gem::TestCase spec_fetcher data = [ - { :name => 'a', - :number => '1', - :platform => 'ruby', - :dependencies => [] }, + { name: "a", + number: "1", + platform: "ruby", + dependencies: [] }, ] @fetcher.data["#{@dep_uri}a"] = "---\n1 " - set = @DR::APISet.new @dep_uri + set = Gem::Resolver::APISet.new @dep_uri - a_dep = @DR::DependencyRequest.new dep('a'), nil + a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil set.prefetch [a_dep] expected = [ - @DR::APISpecification.new(set, data.first), + Gem::Resolver::APISpecification.new(set, data.first), ] assert_equal expected, set.find_all(a_dep) @@ -112,10 +112,10 @@ class TestGemResolverAPISet < Gem::TestCase end def test_find_all_local - set = @DR::APISet.new @dep_uri + set = Gem::Resolver::APISet.new @dep_uri set.remote = false - a_dep = @DR::DependencyRequest.new dep('a'), nil + a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil assert_empty set.find_all(a_dep) end @@ -125,9 +125,9 @@ class TestGemResolverAPISet < Gem::TestCase @fetcher.data["#{@dep_uri}a"] = "---" - set = @DR::APISet.new @dep_uri + set = Gem::Resolver::APISet.new @dep_uri - a_dep = @DR::DependencyRequest.new dep('a'), nil + a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil assert_empty set.find_all(a_dep) @@ -142,14 +142,14 @@ class TestGemResolverAPISet < Gem::TestCase @fetcher.data["#{@dep_uri}a"] = "---\n1 \n" @fetcher.data["#{@dep_uri}b"] = "---" - set = @DR::APISet.new @dep_uri + set = Gem::Resolver::APISet.new @dep_uri - a_dep = @DR::DependencyRequest.new dep('a'), nil - b_dep = @DR::DependencyRequest.new dep('b'), nil + a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil + b_dep = Gem::Resolver::DependencyRequest.new dep("b"), nil set.prefetch [a_dep, b_dep] - assert_equal %w[a-1], set.find_all(a_dep).map {|s| s.full_name } + assert_equal %w[a-1], set.find_all(a_dep).map(&:full_name) assert_empty set.find_all(b_dep) end @@ -158,10 +158,10 @@ class TestGemResolverAPISet < Gem::TestCase @fetcher.data["#{@dep_uri}a"] = "---\n1 \n" - set = @DR::APISet.new @dep_uri + set = Gem::Resolver::APISet.new @dep_uri - a_dep = @DR::DependencyRequest.new dep('a'), nil - b_dep = @DR::DependencyRequest.new dep('b'), nil + a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil + b_dep = Gem::Resolver::DependencyRequest.new dep("b"), nil set.prefetch [a_dep] @@ -177,10 +177,10 @@ class TestGemResolverAPISet < Gem::TestCase @fetcher.data["#{@dep_uri}a"] = "---\n1 \n" @fetcher.data["#{@dep_uri}b"] = "---" - set = @DR::APISet.new @dep_uri + set = Gem::Resolver::APISet.new @dep_uri - a_dep = @DR::DependencyRequest.new dep('a'), nil - b_dep = @DR::DependencyRequest.new dep('b'), nil + a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil + b_dep = Gem::Resolver::DependencyRequest.new dep("b"), nil set.prefetch [a_dep, b_dep] @@ -196,11 +196,11 @@ class TestGemResolverAPISet < Gem::TestCase @fetcher.data["#{@dep_uri}a"] = "---\n1 \n" @fetcher.data["#{@dep_uri}b"] = "---" - set = @DR::APISet.new @dep_uri + set = Gem::Resolver::APISet.new @dep_uri set.remote = false - a_dep = @DR::DependencyRequest.new dep('a'), nil - b_dep = @DR::DependencyRequest.new dep('b'), nil + a_dep = Gem::Resolver::DependencyRequest.new dep("a"), nil + b_dep = Gem::Resolver::DependencyRequest.new dep("b"), nil set.prefetch [a_dep, b_dep] diff --git a/test/rubygems/test_gem_resolver_api_specification.rb b/test/rubygems/test_gem_resolver_api_specification.rb index e9ba4ae481..2119d73478 100644 --- a/test/rubygems/test_gem_resolver_api_specification.rb +++ b/test/rubygems/test_gem_resolver_api_specification.rb @@ -1,28 +1,29 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" class TestGemResolverAPISpecification < Gem::TestCase def test_initialize set = Gem::Resolver::APISet.new data = { - :name => 'rails', - :number => '3.0.3', - :platform => Gem::Platform.local.to_s, - :dependencies => [ - ['bundler', '~> 1.0'], - ['railties', '= 3.0.3'], + name: "rails", + number: "3.0.3", + platform: Gem::Platform.local.to_s, + dependencies: [ + ["bundler", "~> 1.0"], + ["railties", "= 3.0.3"], ], } spec = Gem::Resolver::APISpecification.new set, data - assert_equal 'rails', spec.name - assert_equal Gem::Version.new('3.0.3'), spec.version + assert_equal "rails", spec.name + assert_equal Gem::Version.new("3.0.3"), spec.version assert_equal Gem::Platform.local, spec.platform expected = [ - Gem::Dependency.new('bundler', '~> 1.0'), - Gem::Dependency.new('railties', '= 3.0.3'), + Gem::Dependency.new("bundler", "~> 1.0"), + Gem::Dependency.new("railties", "= 3.0.3"), ] assert_equal expected, spec.dependencies @@ -30,26 +31,26 @@ class TestGemResolverAPISpecification < Gem::TestCase def test_fetch_development_dependencies specs = spec_fetcher do |fetcher| - fetcher.spec 'rails', '3.0.3' do |s| - s.add_runtime_dependency 'bundler', '~> 1.0' - s.add_runtime_dependency 'railties', '= 3.0.3' - s.add_development_dependency 'a', '= 1' + fetcher.spec "rails", "3.0.3" do |s| + s.add_runtime_dependency "bundler", "~> 1.0" + s.add_runtime_dependency "railties", "= 3.0.3" + s.add_development_dependency "a", "= 1" end end - rails = specs['rails-3.0.3'] + rails = specs["rails-3.0.3"] - repo = @gem_repo + 'info' + repo = @gem_repo + "info" set = Gem::Resolver::APISet.new repo data = { - :name => 'rails', - :number => '3.0.3', - :platform => 'ruby', - :dependencies => [ - ['bundler', '~> 1.0'], - ['railties', '= 3.0.3'], + name: "rails", + number: "3.0.3", + platform: "ruby", + dependencies: [ + ["bundler", "~> 1.0"], + ["railties", "= 3.0.3"], ], } @@ -60,9 +61,9 @@ class TestGemResolverAPISpecification < Gem::TestCase spec.fetch_development_dependencies expected = [ - Gem::Dependency.new('bundler', '~> 1.0'), - Gem::Dependency.new('railties', '= 3.0.3'), - Gem::Dependency.new('a', '= 1', :development), + Gem::Dependency.new("bundler", "~> 1.0"), + Gem::Dependency.new("railties", "= 3.0.3"), + Gem::Dependency.new("a", "= 1", :development), ] assert_equal expected, spec.dependencies @@ -71,10 +72,10 @@ class TestGemResolverAPISpecification < Gem::TestCase def test_installable_platform_eh set = Gem::Resolver::APISet.new data = { - :name => 'a', - :number => '1', - :platform => 'ruby', - :dependencies => [], + name: "a", + number: "1", + platform: "ruby", + dependencies: [], } a_spec = Gem::Resolver::APISpecification.new set, data @@ -82,10 +83,10 @@ class TestGemResolverAPISpecification < Gem::TestCase assert a_spec.installable_platform? data = { - :name => 'b', - :number => '1', - :platform => 'cpu-other_platform-1', - :dependencies => [], + name: "b", + number: "1", + platform: "cpu-other_platform-1", + dependencies: [], } b_spec = Gem::Resolver::APISpecification.new set, data @@ -93,10 +94,10 @@ class TestGemResolverAPISpecification < Gem::TestCase refute b_spec.installable_platform? data = { - :name => 'c', - :number => '1', - :platform => Gem::Platform.local.to_s, - :dependencies => [], + name: "c", + number: "1", + platform: Gem::Platform.local.to_s, + dependencies: [], } c_spec = Gem::Resolver::APISpecification.new set, data @@ -107,10 +108,10 @@ class TestGemResolverAPISpecification < Gem::TestCase def test_source set = Gem::Resolver::APISet.new data = { - :name => 'a', - :number => '1', - :platform => 'ruby', - :dependencies => [], + name: "a", + number: "1", + platform: "ruby", + dependencies: [], } api_spec = Gem::Resolver::APISpecification.new set, data @@ -120,16 +121,16 @@ class TestGemResolverAPISpecification < Gem::TestCase def test_spec spec_fetcher do |fetcher| - fetcher.spec 'a', 1 + fetcher.spec "a", 1 end - dep_uri = URI(@gem_repo) + 'info' + dep_uri = Gem::URI(@gem_repo) + "info" set = Gem::Resolver::APISet.new dep_uri data = { - :name => 'a', - :number => '1', - :platform => 'ruby', - :dependencies => [], + name: "a", + number: "1", + platform: "ruby", + dependencies: [], } api_spec = Gem::Resolver::APISpecification.new set, data @@ -137,23 +138,23 @@ class TestGemResolverAPISpecification < Gem::TestCase spec = api_spec.spec assert_kind_of Gem::Specification, spec - assert_equal 'a-1', spec.full_name + assert_equal "a-1", spec.full_name end def test_spec_jruby_platform spec_fetcher do |fetcher| - fetcher.gem 'j', 1 do |spec| - spec.platform = 'jruby' + fetcher.gem "j", 1 do |spec| + spec.platform = "jruby" end end - dep_uri = URI(@gem_repo) + 'info' + dep_uri = Gem::URI(@gem_repo) + "info" set = Gem::Resolver::APISet.new dep_uri data = { - :name => 'j', - :number => '1', - :platform => 'jruby', - :dependencies => [], + name: "j", + number: "1", + platform: "jruby", + dependencies: [], } api_spec = Gem::Resolver::APISpecification.new set, data @@ -161,6 +162,6 @@ class TestGemResolverAPISpecification < Gem::TestCase spec = api_spec.spec assert_kind_of Gem::Specification, spec - assert_equal 'j-1-java', spec.full_name + assert_equal "j-1-java", spec.full_name end end diff --git a/test/rubygems/test_gem_resolver_best_set.rb b/test/rubygems/test_gem_resolver_best_set.rb index df6b438763..8a750cdf8f 100644 --- a/test/rubygems/test_gem_resolver_best_set.rb +++ b/test/rubygems/test_gem_resolver_best_set.rb @@ -1,70 +1,65 @@ # frozen_string_literal: true -require 'rubygems/test_case' -class TestGemResolverBestSet < Gem::TestCase - def setup - super - - @DR = Gem::Resolver - end +require_relative "helper" +class TestGemResolverBestSet < Gem::TestCase def test_initialize - set = @DR::BestSet.new + set = Gem::Resolver::BestSet.new assert_empty set.sets end def test_find_all_index spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', 2 - fetcher.spec 'b', 1 + fetcher.spec "a", 1 + fetcher.spec "a", 2 + fetcher.spec "b", 1 end - set = @DR::BestSet.new + set = Gem::Resolver::BestSet.new - dependency = dep 'a', '~> 1' + dependency = dep "a", "~> 1" - req = @DR::DependencyRequest.new dependency, nil + req = Gem::Resolver::DependencyRequest.new dependency, nil found = set.find_all req - assert_equal %w[a-1], found.map {|s| s.full_name } + assert_equal %w[a-1], found.map(&:full_name) end def test_find_all_fallback spec_fetcher do |fetcher| - fetcher.spec 'a', 1 + fetcher.spec "a", 1 end - set = @DR::BestSet.new + set = Gem::Resolver::BestSet.new - api_uri = URI(@gem_repo) + api_uri = Gem::URI(@gem_repo) set.sets << Gem::Resolver::APISet.new(api_uri) - dependency = dep 'a', '~> 1' + dependency = dep "a", "~> 1" - req = @DR::DependencyRequest.new dependency, nil + req = Gem::Resolver::DependencyRequest.new dependency, nil found = set.find_all req - assert_equal %w[a-1], found.map {|s| s.full_name } + assert_equal %w[a-1], found.map(&:full_name) end def test_find_all_local spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', 2 - fetcher.spec 'b', 1 + fetcher.spec "a", 1 + fetcher.spec "a", 2 + fetcher.spec "b", 1 end - set = @DR::BestSet.new + set = Gem::Resolver::BestSet.new set.remote = false - dependency = dep 'a', '~> 1' + dependency = dep "a", "~> 1" - req = @DR::DependencyRequest.new dependency, nil + req = Gem::Resolver::DependencyRequest.new dependency, nil found = set.find_all req @@ -73,10 +68,10 @@ class TestGemResolverBestSet < Gem::TestCase def test_prefetch spec_fetcher do |fetcher| - fetcher.spec 'a', 1 + fetcher.spec "a", 1 end - set = @DR::BestSet.new + set = Gem::Resolver::BestSet.new set.prefetch [] @@ -85,10 +80,10 @@ class TestGemResolverBestSet < Gem::TestCase def test_prefetch_local spec_fetcher do |fetcher| - fetcher.spec 'a', 1 + fetcher.spec "a", 1 end - set = @DR::BestSet.new + set = Gem::Resolver::BestSet.new set.remote = false set.prefetch [] @@ -97,16 +92,16 @@ class TestGemResolverBestSet < Gem::TestCase end def test_replace_failed_api_set - set = @DR::BestSet.new + set = Gem::Resolver::BestSet.new - api_uri = URI(@gem_repo) + './info/' + api_uri = Gem::URI(@gem_repo) + "./info/" api_set = Gem::Resolver::APISet.new api_uri set.sets << api_set - error_uri = api_uri + 'a' + error_uri = api_uri + "a" - error = Gem::RemoteFetcher::FetchError.new 'bogus', error_uri + error = Gem::RemoteFetcher::FetchError.new "bogus", error_uri set.replace_failed_api_set error @@ -118,13 +113,13 @@ class TestGemResolverBestSet < Gem::TestCase end def test_replace_failed_api_set_no_api_set - set = @DR::BestSet.new + set = Gem::Resolver::BestSet.new index_set = Gem::Resolver::IndexSet.new Gem::Source.new @gem_repo set.sets << index_set - error = Gem::RemoteFetcher::FetchError.new 'bogus', @gem_repo + error = Gem::RemoteFetcher::FetchError.new "bogus", @gem_repo e = assert_raise Gem::RemoteFetcher::FetchError do set.replace_failed_api_set error @@ -134,18 +129,18 @@ class TestGemResolverBestSet < Gem::TestCase end def test_replace_failed_api_set_uri_with_credentials - set = @DR::BestSet.new + set = Gem::Resolver::BestSet.new - api_uri = URI(@gem_repo) + './info/' - api_uri.user = 'user' - api_uri.password = 'pass' + api_uri = Gem::URI(@gem_repo) + "./info/" + api_uri.user = "user" + api_uri.password = "pass" api_set = Gem::Resolver::APISet.new api_uri set.sets << api_set - error_uri = api_uri + 'a' + error_uri = api_uri + "a" - error = Gem::RemoteFetcher::FetchError.new 'bogus', error_uri + error = Gem::RemoteFetcher::FetchError.new "bogus", error_uri set.replace_failed_api_set error diff --git a/test/rubygems/test_gem_resolver_composed_set.rb b/test/rubygems/test_gem_resolver_composed_set.rb index 7c8ae004a3..5a53000ec7 100644 --- a/test/rubygems/test_gem_resolver_composed_set.rb +++ b/test/rubygems/test_gem_resolver_composed_set.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" class TestGemResolverComposedSet < Gem::TestCase def test_errors diff --git a/test/rubygems/test_gem_resolver_conflict.rb b/test/rubygems/test_gem_resolver_conflict.rb index ff5fe9bae3..5696ff266d 100644 --- a/test/rubygems/test_gem_resolver_conflict.rb +++ b/test/rubygems/test_gem_resolver_conflict.rb @@ -1,16 +1,17 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" class TestGemResolverConflict < Gem::TestCase def test_explanation root = - dependency_request dep('net-ssh', '>= 2.0.13'), 'rye', '0.9.8' + dependency_request dep("net-ssh", ">= 2.0.13"), "rye", "0.9.8" child = - dependency_request dep('net-ssh', '>= 2.6.5'), 'net-ssh', '2.2.2', root + dependency_request dep("net-ssh", ">= 2.6.5"), "net-ssh", "2.2.2", root - dep = Gem::Resolver::DependencyRequest.new dep('net-ssh', '>= 2.0.13'), nil + dep = Gem::Resolver::DependencyRequest.new dep("net-ssh", ">= 2.0.13"), nil - spec = util_spec 'net-ssh', '2.2.2' + spec = util_spec "net-ssh", "2.2.2" active = Gem::Resolver::ActivationRequest.new spec, dep @@ -35,16 +36,14 @@ class TestGemResolverConflict < Gem::TestCase end def test_explanation_user_request - @DR = Gem::Resolver - - spec = util_spec 'a', 2 + spec = util_spec "a", 2 - a1_req = @DR::DependencyRequest.new dep('a', '= 1'), nil - a2_req = @DR::DependencyRequest.new dep('a', '= 2'), nil + a1_req = Gem::Resolver::DependencyRequest.new dep("a", "= 1"), nil + a2_req = Gem::Resolver::DependencyRequest.new dep("a", "= 2"), nil - activated = @DR::ActivationRequest.new spec, a2_req + activated = Gem::Resolver::ActivationRequest.new spec, a2_req - conflict = @DR::Conflict.new a1_req, activated + conflict = Gem::Resolver::Conflict.new a1_req, activated expected = <<-EXPECTED Activated a-2 @@ -63,17 +62,17 @@ class TestGemResolverConflict < Gem::TestCase def test_request_path root = - dependency_request dep('net-ssh', '>= 2.0.13'), 'rye', '0.9.8' + dependency_request dep("net-ssh", ">= 2.0.13"), "rye", "0.9.8" child = - dependency_request dep('other', '>= 1.0'), 'net-ssh', '2.2.2', root + dependency_request dep("other", ">= 1.0"), "net-ssh", "2.2.2", root conflict = Gem::Resolver::Conflict.new nil, nil expected = [ - 'net-ssh (>= 2.0.13), 2.2.2 activated', - 'rye (= 0.9.8), 0.9.8 activated', + "net-ssh (>= 2.0.13), 2.2.2 activated", + "rye (= 0.9.8), 0.9.8 activated", ] assert_equal expected, conflict.request_path(child.requester) diff --git a/test/rubygems/test_gem_resolver_dependency_request.rb b/test/rubygems/test_gem_resolver_dependency_request.rb index a8ddc8362b..3e14771da8 100644 --- a/test/rubygems/test_gem_resolver_dependency_request.rb +++ b/test/rubygems/test_gem_resolver_dependency_request.rb @@ -1,81 +1,76 @@ # frozen_string_literal: true -require 'rubygems/test_case' -class TestGemResolverDependencyRequest < Gem::TestCase - def setup - super - - @DR = Gem::Resolver::DependencyRequest - end +require_relative "helper" +class TestGemResolverDependencyRequest < Gem::TestCase def test_development_eh - a_dep = dep 'a', '>= 1' + a_dep = dep "a", ">= 1" - a_dep_req = @DR.new a_dep, nil + a_dep_req = Gem::Resolver::DependencyRequest.new a_dep, nil refute a_dep_req.development? - b_dep = dep 'b', '>= 1', :development + b_dep = dep "b", ">= 1", :development - b_dep_req = @DR.new b_dep, nil + b_dep_req = Gem::Resolver::DependencyRequest.new b_dep, nil assert b_dep_req.development? end def test_match_eh - spec = util_spec 'a', 1 - dependency = dep 'a', '>= 1' + spec = util_spec "a", 1 + dependency = dep "a", ">= 1" - dr = @DR.new dependency, nil + dr = Gem::Resolver::DependencyRequest.new dependency, nil assert dr.match? spec end def test_match_eh_prerelease - spec = util_spec 'a', '1.a' + spec = util_spec "a", "1.a" - a_dep = dep 'a', '>= 1' - a_dr = @DR.new a_dep, nil + a_dep = dep "a", ">= 1" + a_dr = Gem::Resolver::DependencyRequest.new a_dep, nil refute a_dr.match? spec - a_pre_dep = dep 'a', '>= 1.a' - a_pre_dr = @DR.new a_pre_dep, nil + a_pre_dep = dep "a", ">= 1.a" + a_pre_dr = Gem::Resolver::DependencyRequest.new a_pre_dep, nil assert a_pre_dr.match? spec end def test_match_eh_prerelease_allow_prerelease - spec = util_spec 'a', '2.a' + spec = util_spec "a", "2.a" - a_dep = dep 'a', '>= 1' - a_dr = @DR.new a_dep, nil + a_dep = dep "a", ">= 1" + a_dr = Gem::Resolver::DependencyRequest.new a_dep, nil assert a_dr.match? spec, true end def test_matches_spec_eh - spec = util_spec 'a', 1 - dependency = dep 'a', '>= 1' + spec = util_spec "a", 1 + dependency = dep "a", ">= 1" - dr = @DR.new dependency, nil + dr = Gem::Resolver::DependencyRequest.new dependency, nil assert dr.matches_spec? spec end def test_matches_spec_eh_prerelease - spec = util_spec 'a', '1.a' + spec = util_spec "a", "1.a" - dependency = dep 'a', '>= 0' - dr = @DR.new dependency, nil + dependency = dep "a", ">= 0" + dr = Gem::Resolver::DependencyRequest.new dependency, nil assert dr.matches_spec? spec end def test_requirement - dependency = dep 'a', '>= 1' + dependency = dep "a", ">= 1" - dr = @DR.new dependency, nil + dr = Gem::Resolver::DependencyRequest.new dependency, nil assert_equal dependency, dr.dependency end diff --git a/test/rubygems/test_gem_resolver_git_set.rb b/test/rubygems/test_gem_resolver_git_set.rb index 7b0efa0680..90749d712c 100644 --- a/test/rubygems/test_gem_resolver_git_set.rb +++ b/test/rubygems/test_gem_resolver_git_set.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" class TestGemResolverGitSet < Gem::TestCase def setup @@ -13,9 +14,9 @@ class TestGemResolverGitSet < Gem::TestCase def test_add_git_gem name, version, repository, = git_gem - @set.add_git_gem name, repository, 'master', false + @set.add_git_gem name, repository, nil, false - dependency = dep 'a' + dependency = dep "a" specs = @set.find_all dependency @@ -27,9 +28,9 @@ class TestGemResolverGitSet < Gem::TestCase def test_add_git_gem_submodules name, _, repository, = git_gem - @set.add_git_gem name, repository, 'master', true + @set.add_git_gem name, repository, nil, true - dependency = dep 'a' + dependency = dep "a" refute_empty @set.find_all dependency @@ -41,7 +42,7 @@ class TestGemResolverGitSet < Gem::TestCase @set.add_git_spec name, version, repository, revision, true - dependency = dep 'a' + dependency = dep "a" specs = @set.find_all dependency @@ -57,9 +58,9 @@ class TestGemResolverGitSet < Gem::TestCase def test_find_all name, _, repository, = git_gem - @set.add_git_gem name, repository, 'master', false + @set.add_git_gem name, repository, nil, false - dependency = dep 'a', '~> 1.0' + dependency = dep "a", "~> 1.0" req = Gem::Resolver::DependencyRequest.new dependency, nil @reqs.add req @@ -67,16 +68,16 @@ class TestGemResolverGitSet < Gem::TestCase found = @set.find_all dependency - assert_equal [@set.specs['a']], found + assert_equal [@set.specs["a"]], found end def test_find_all_local name, _, repository, = git_gem - @set.add_git_gem name, repository, 'master', false + @set.add_git_gem name, repository, nil, false @set.remote = false - dependency = dep 'a', '~> 1.0' + dependency = dep "a", "~> 1.0" req = Gem::Resolver::DependencyRequest.new dependency, nil @reqs.add req @@ -86,11 +87,11 @@ class TestGemResolverGitSet < Gem::TestCase end def test_find_all_prerelease - name, _, repository, = git_gem 'a', '1.a' + name, _, repository, = git_gem "a", "1.a" - @set.add_git_gem name, repository, 'master', false + @set.add_git_gem name, repository, nil, false - dependency = dep 'a', '>= 0' + dependency = dep "a", ">= 0" req = Gem::Resolver::DependencyRequest.new dependency, nil @reqs.add req @@ -100,7 +101,7 @@ class TestGemResolverGitSet < Gem::TestCase assert_empty found - dependency = dep 'a', '>= 0.a' + dependency = dep "a", ">= 0.a" req = Gem::Resolver::DependencyRequest.new dependency, nil @reqs.add req @@ -122,7 +123,7 @@ class TestGemResolverGitSet < Gem::TestCase def test_prefetch name, _, repository, = git_gem - @set.add_git_gem name, repository, 'master', false + @set.add_git_gem name, repository, nil, false dependency = dep name req = Gem::Resolver::DependencyRequest.new dependency, nil @@ -136,7 +137,7 @@ class TestGemResolverGitSet < Gem::TestCase def test_prefetch_cache name, _, repository, = git_gem - @set.add_git_gem name, repository, 'master', false + @set.add_git_gem name, repository, nil, false dependency = dep name req = Gem::Resolver::DependencyRequest.new dependency, nil @@ -154,21 +155,21 @@ class TestGemResolverGitSet < Gem::TestCase def test_prefetch_filter name, _, repository, = git_gem - @set.add_git_gem name, repository, 'master', false + @set.add_git_gem name, repository, nil, false - dependency = dep 'b' + dependency = dep "b" req = Gem::Resolver::DependencyRequest.new dependency, nil @reqs.add req @set.prefetch @reqs - refute_empty @set.specs, 'the git source does not filter' + refute_empty @set.specs, "the git source does not filter" end def test_prefetch_root_dir name, _, repository, = git_gem - @set.add_git_gem name, repository, 'master', false + @set.add_git_gem name, repository, nil, false dependency = dep name req = Gem::Resolver::DependencyRequest.new dependency, nil diff --git a/test/rubygems/test_gem_resolver_git_specification.rb b/test/rubygems/test_gem_resolver_git_specification.rb index 88729c4d20..621333d3bf 100644 --- a/test/rubygems/test_gem_resolver_git_specification.rb +++ b/test/rubygems/test_gem_resolver_git_specification.rb @@ -1,13 +1,14 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/installer' + +require_relative "helper" +require "rubygems/installer" class TestGemResolverGitSpecification < Gem::TestCase def setup super @set = Gem::Resolver::GitSet.new - @spec = Gem::Specification.new 'a', 1 + @spec = Gem::Specification.new "a", 1 end def test_equals2 @@ -15,7 +16,7 @@ class TestGemResolverGitSpecification < Gem::TestCase assert_equal g_spec_a, g_spec_a - spec_b = Gem::Specification.new 'b', 1 + spec_b = Gem::Specification.new "b", 1 g_spec_b = Gem::Resolver::GitSpecification.new @set, spec_b refute_equal g_spec_a, g_spec_b @@ -28,17 +29,18 @@ class TestGemResolverGitSpecification < Gem::TestCase i_set = Gem::Resolver::IndexSet.new source = Gem::Source.new @gem_repo i_spec = Gem::Resolver::IndexSpecification.new( - i_set, 'a', v(1), source, Gem::Platform::RUBY) + i_set, "a", v(1), source, Gem::Platform::RUBY + ) refute_equal g_spec_a, i_spec end def test_add_dependency - git_gem 'a', 1 + git_gem "a", 1 git_spec = Gem::Resolver::GitSpecification.new @set, @spec - b_dep = dep 'b' + b_dep = dep "b" git_spec.add_dependency b_dep @@ -46,7 +48,7 @@ class TestGemResolverGitSpecification < Gem::TestCase end def test_install - git_gem 'a', 1 + git_gem "a", 1 git_spec = Gem::Resolver::GitSpecification.new @set, @spec @@ -62,29 +64,29 @@ class TestGemResolverGitSpecification < Gem::TestCase # functional test for Gem::Ext::Builder def test_install_extension - skip if Gem.java_platform? - skip if /mswin/ =~ RUBY_PLATFORM && ENV.key?('GITHUB_ACTIONS') # not working from the beginning - name, _, repository, = git_gem 'a', 1 do |s| - s.extensions << 'ext/extconf.rb' + pend if Gem.java_platform? + pend "terminates on mswin" if vc_windows? && ruby_repo? + name, _, repository, = git_gem "a", 1 do |s| + s.extensions << "ext/extconf.rb" end - Dir.chdir 'git/a' do - FileUtils.mkdir_p 'ext/lib' + Dir.chdir "git/a" do + FileUtils.mkdir_p "ext/lib" - File.open 'ext/extconf.rb', 'w' do |io| + File.open "ext/extconf.rb", "w" do |io| io.puts 'require "mkmf"' io.puts 'create_makefile "a"' end - FileUtils.touch 'ext/lib/b.rb' + FileUtils.touch "ext/lib/b.rb" - system @git, 'add', 'ext/extconf.rb' - system @git, 'add', 'ext/lib/b.rb' + system @git, "add", "ext/extconf.rb" + system @git, "add", "ext/lib/b.rb" - system @git, 'commit', '--quiet', '-m', 'Add extension files' + system @git, "commit", "--quiet", "-m", "Add extension files" end - source = Gem::Source::Git.new name, repository, 'master', true + source = Gem::Source::Git.new name, repository, nil, true spec = source.specs.first @@ -92,11 +94,11 @@ class TestGemResolverGitSpecification < Gem::TestCase git_spec.install({}) - assert_path_exist File.join git_spec.spec.extension_dir, 'b.rb' + assert_path_exist File.join git_spec.spec.extension_dir, "b.rb" end def test_install_installed - git_gem 'a', 1 + git_gem "a", 1 git_spec = Gem::Resolver::GitSpecification.new @set, @spec diff --git a/test/rubygems/test_gem_resolver_index_set.rb b/test/rubygems/test_gem_resolver_index_set.rb index 2de766f60a..8ff1acbf1e 100644 --- a/test/rubygems/test_gem_resolver_index_set.rb +++ b/test/rubygems/test_gem_resolver_index_set.rb @@ -1,15 +1,10 @@ # frozen_string_literal: true -require 'rubygems/test_case' -class TestGemResolverIndexSet < Gem::TestCase - def setup - super - - @DR = Gem::Resolver - end +require_relative "helper" +class TestGemResolverIndexSet < Gem::TestCase def test_initialize - set = @DR::IndexSet.new + set = Gem::Resolver::IndexSet.new fetcher = set.instance_variable_get :@f @@ -17,7 +12,7 @@ class TestGemResolverIndexSet < Gem::TestCase end def test_initialize_source - set = @DR::IndexSet.new 'http://alternate.example' + set = Gem::Resolver::IndexSet.new "http://alternate.example" fetcher = set.instance_variable_get :@f @@ -28,49 +23,49 @@ class TestGemResolverIndexSet < Gem::TestCase def test_find_all spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', 2 - fetcher.spec 'b', 1 + fetcher.spec "a", 1 + fetcher.spec "a", 2 + fetcher.spec "b", 1 end - set = @DR::IndexSet.new + set = Gem::Resolver::IndexSet.new - dependency = dep 'a', '~> 1' + dependency = dep "a", "~> 1" - req = @DR::DependencyRequest.new dependency, nil + req = Gem::Resolver::DependencyRequest.new dependency, nil found = set.find_all req - assert_equal %w[a-1], found.map {|s| s.full_name } + assert_equal %w[a-1], found.map(&:full_name) end def test_find_all_local spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', 2 - fetcher.spec 'b', 1 + fetcher.spec "a", 1 + fetcher.spec "a", 2 + fetcher.spec "b", 1 end - set = @DR::IndexSet.new + set = Gem::Resolver::IndexSet.new set.remote = false - dependency = dep 'a', '~> 1' + dependency = dep "a", "~> 1" - req = @DR::DependencyRequest.new dependency, nil + req = Gem::Resolver::DependencyRequest.new dependency, nil assert_empty set.find_all req end def test_find_all_prerelease spec_fetcher do |fetcher| - fetcher.spec 'a', '1.a' + fetcher.spec "a", "1.a" end - set = @DR::IndexSet.new + set = Gem::Resolver::IndexSet.new - dependency = dep 'a' + dependency = dep "a" - req = @DR::DependencyRequest.new dependency, nil + req = Gem::Resolver::DependencyRequest.new dependency, nil found = set.find_all req @@ -78,10 +73,10 @@ class TestGemResolverIndexSet < Gem::TestCase dependency.prerelease = true - req = @DR::DependencyRequest.new dependency, nil + req = Gem::Resolver::DependencyRequest.new dependency, nil found = set.find_all req - assert_equal %w[a-1.a], found.map {|s| s.full_name } + assert_equal %w[a-1.a], found.map(&:full_name) end end diff --git a/test/rubygems/test_gem_resolver_index_specification.rb b/test/rubygems/test_gem_resolver_index_specification.rb index 382f95c004..ed9475f0cf 100644 --- a/test/rubygems/test_gem_resolver_index_specification.rb +++ b/test/rubygems/test_gem_resolver_index_specification.rb @@ -1,17 +1,19 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/available_set' + +require_relative "helper" +require "rubygems/available_set" class TestGemResolverIndexSpecification < Gem::TestCase def test_initialize set = Gem::Resolver::IndexSet.new source = Gem::Source.new @gem_repo - version = Gem::Version.new '3.0.3' + version = Gem::Version.new "3.0.3" spec = Gem::Resolver::IndexSpecification.new( - set, 'rails', version, source, Gem::Platform::RUBY) + set, "rails", version, source, Gem::Platform::RUBY + ) - assert_equal 'rails', spec.name + assert_equal "rails", spec.name assert_equal version, spec.version assert_equal Gem::Platform::RUBY, spec.platform @@ -21,24 +23,26 @@ class TestGemResolverIndexSpecification < Gem::TestCase def test_initialize_platform set = Gem::Resolver::IndexSet.new source = Gem::Source::Local.new - version = Gem::Version.new '3.0.3' + version = Gem::Version.new "3.0.3" spec = Gem::Resolver::IndexSpecification.new( - set, 'rails', version, source, Gem::Platform.local) + set, "rails", version, source, Gem::Platform.local + ) - assert_equal Gem::Platform.local.to_s, spec.platform + assert_equal Gem::Platform.local, spec.platform end def test_install spec_fetcher do |fetcher| - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end set = Gem::Resolver::IndexSet.new source = Gem::Source.new @gem_repo spec = Gem::Resolver::IndexSpecification.new( - set, 'a', v(2), source, Gem::Platform::RUBY) + set, "a", v(2), source, Gem::Platform::RUBY + ) called = false @@ -46,15 +50,15 @@ class TestGemResolverIndexSpecification < Gem::TestCase called = installer end - assert_path_exist File.join @gemhome, 'specifications', 'a-2.gemspec' + assert_path_exist File.join @gemhome, "specifications", "a-2.gemspec" assert_kind_of Gem::Installer, called end def test_spec specs = spec_fetcher do |fetcher| - fetcher.spec 'a', 2 - fetcher.spec 'a', 2 do |s| + fetcher.spec "a", 2 + fetcher.spec "a", 2 do |s| s.platform = Gem::Platform.local end end @@ -64,7 +68,7 @@ class TestGemResolverIndexSpecification < Gem::TestCase set = Gem::Resolver::IndexSet.new i_spec = Gem::Resolver::IndexSpecification.new \ - set, 'a', version, source, Gem::Platform.local + set, "a", version, source, Gem::Platform.local spec = i_spec.spec @@ -72,7 +76,7 @@ class TestGemResolverIndexSpecification < Gem::TestCase end def test_spec_local - a_2_p = util_spec 'a', 2 do |s| + a_2_p = util_spec "a", 2 do |s| s.platform = Gem::Platform.local end @@ -83,7 +87,7 @@ class TestGemResolverIndexSpecification < Gem::TestCase set.always_install << a_2_p i_spec = Gem::Resolver::IndexSpecification.new \ - set, 'a', v(2), source, Gem::Platform.local + set, "a", v(2), source, Gem::Platform.local spec = i_spec.spec diff --git a/test/rubygems/test_gem_resolver_installed_specification.rb b/test/rubygems/test_gem_resolver_installed_specification.rb index b102f98d00..5b10273b13 100644 --- a/test/rubygems/test_gem_resolver_installed_specification.rb +++ b/test/rubygems/test_gem_resolver_installed_specification.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" class TestGemResolverInstalledSpecification < Gem::TestCase def setup @@ -9,17 +10,17 @@ class TestGemResolverInstalledSpecification < Gem::TestCase end def test_initialize - source_spec = util_spec 'a' + source_spec = util_spec "a" spec = Gem::Resolver::InstalledSpecification.new @set, source_spec - assert_equal 'a', spec.name + assert_equal "a", spec.name assert_equal Gem::Version.new(2), spec.version assert_equal Gem::Platform::RUBY, spec.platform end def test_install - a = util_spec 'a' + a = util_spec "a" spec = Gem::Resolver::InstalledSpecification.new @set, a @@ -33,7 +34,7 @@ class TestGemResolverInstalledSpecification < Gem::TestCase end def test_installable_platform_eh - b, b_gem = util_gem 'a', 1 do |s| + b, b_gem = util_gem "a", 1 do |s| s.platform = Gem::Platform.new %w[cpu other_platform 1] end diff --git a/test/rubygems/test_gem_resolver_installer_set.rb b/test/rubygems/test_gem_resolver_installer_set.rb index d45a527d2f..202fe9d653 100644 --- a/test/rubygems/test_gem_resolver_installer_set.rb +++ b/test/rubygems/test_gem_resolver_installer_set.rb @@ -1,26 +1,27 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" class TestGemResolverInstallerSet < Gem::TestCase def test_add_always_install spec_fetcher do |fetcher| - fetcher.download 'a', 1 - fetcher.download 'a', 2 + fetcher.download "a", 1 + fetcher.download "a", 2 end - util_gem 'a', 1 + util_gem "a", 1 set = Gem::Resolver::InstallerSet.new :both - set.add_always_install dep('a') + set.add_always_install dep("a") - assert_equal %w[a-2], set.always_install.map {|s| s.full_name } + assert_equal %w[a-2], set.always_install.map(&:full_name) e = assert_raise Gem::UnsatisfiableDependencyError do - set.add_always_install dep('b') + set.add_always_install dep("b") end - assert_equal dep('b'), e.dependency.dependency + assert_equal dep("b"), e.dependency.dependency end def test_add_always_install_errors @@ -30,7 +31,7 @@ class TestGemResolverInstallerSet < Gem::TestCase set = Gem::Resolver::InstallerSet.new :both e = assert_raise Gem::UnsatisfiableDependencyError do - set.add_always_install dep 'a' + set.add_always_install dep "a" end refute_empty e.errors @@ -38,46 +39,96 @@ class TestGemResolverInstallerSet < Gem::TestCase def test_add_always_install_platform spec_fetcher do |fetcher| - fetcher.download 'a', 1 - fetcher.download 'a', 2 do |s| - s.platform = Gem::Platform.new 'x86-freebsd-9' + fetcher.download "a", 1 + fetcher.download "a", 2 do |s| + s.platform = Gem::Platform.new "x86-freebsd-9" end end set = Gem::Resolver::InstallerSet.new :both - set.add_always_install dep('a') + set.add_always_install dep("a") + + assert_equal %w[a-1], set.always_install.map(&:full_name) + end + + def test_add_always_install_platform_if_gem_platforms_modified_by_platform_flag + freebsd = Gem::Platform.new "x86-freebsd-9" + + spec_fetcher do |fetcher| + fetcher.download "a", 1 + fetcher.download "a", 1 do |s| + s.platform = freebsd + end + end + + # equivalent to --platform=x86-freebsd-9 + Gem.platforms << freebsd + set = Gem::Resolver::InstallerSet.new :both + + set.add_always_install dep("a") + + assert_equal %w[a-1-x86-freebsd-9], set.always_install.map(&:full_name) + end + + def test_add_always_install_index_spec_platform + _, a_1_local_gem = util_gem "a", 1 do |s| + s.platform = Gem::Platform.local + end + + FileUtils.mv a_1_local_gem, @tempdir + + set = Gem::Resolver::InstallerSet.new :both + set.add_always_install dep("a") - assert_equal %w[a-1], set.always_install.map {|s| s.full_name } + assert_equal [Gem::Platform.local], set.always_install.map(&:platform) end def test_add_always_install_prerelease spec_fetcher do |fetcher| - fetcher.gem 'a', 1 - fetcher.gem 'a', '3.a' + fetcher.gem "a", 1 + fetcher.gem "a", "3.a" end set = Gem::Resolver::InstallerSet.new :both - set.add_always_install dep('a') + set.add_always_install dep("a") - assert_equal %w[a-1], set.always_install.map {|s| s.full_name } + assert_equal %w[a-1], set.always_install.map(&:full_name) + end + + def test_add_always_install_prerelease_github_problem + spec_fetcher do |fetcher| + fetcher.gem "a", 1 + end + + # Github has an issue in which it will generate a misleading prerelease output in its RubyGems server API and + # returns a 0 version for the gem while it doesn't exist. + @fetcher.data["#{@gem_repo}prerelease_specs.#{Gem.marshal_version}.gz"] = util_gzip(Marshal.dump([ + Gem::NameTuple.new("a", Gem::Version.new(0), "ruby"), + ])) + + set = Gem::Resolver::InstallerSet.new :both + + set.add_always_install dep("a") + + assert_equal %w[a-1], set.always_install.map(&:full_name) end def test_add_always_install_prerelease_only spec_fetcher do |fetcher| - fetcher.gem 'a', '3.a' + fetcher.gem "a", "3.a" end set = Gem::Resolver::InstallerSet.new :both assert_raise Gem::UnsatisfiableDependencyError do - set.add_always_install dep('a') + set.add_always_install dep("a") end end def test_add_local - a_1, a_1_gem = util_gem 'a', 1 + a_1, a_1_gem = util_gem "a", 1 a_1_source = Gem::Source::SpecificFile.new a_1_gem @@ -90,9 +141,9 @@ class TestGemResolverInstallerSet < Gem::TestCase FileUtils.rm a_1_gem util_clear_gems - req = Gem::Resolver::DependencyRequest.new dep('a'), nil + req = Gem::Resolver::DependencyRequest.new dep("a"), nil - assert_equal %w[a-1], set.find_all(req).map {|spec| spec.full_name } + assert_equal %w[a-1], set.find_all(req).map(&:full_name) end def test_consider_local_eh @@ -128,7 +179,7 @@ class TestGemResolverInstallerSet < Gem::TestCase set.instance_variable_get(:@errors) << :a - req = Gem::Resolver::DependencyRequest.new dep('a'), nil + req = Gem::Resolver::DependencyRequest.new dep("a"), nil set.find_all req @@ -137,42 +188,54 @@ class TestGemResolverInstallerSet < Gem::TestCase def test_find_all_always_install spec_fetcher do |fetcher| - fetcher.download 'a', 2 + fetcher.download "a", 2 end - util_gem 'a', 1 + util_gem "a", 1 set = Gem::Resolver::InstallerSet.new :both - set.add_always_install dep 'a' + set.add_always_install dep "a" - req = Gem::Resolver::DependencyRequest.new dep('a'), nil + req = Gem::Resolver::DependencyRequest.new dep("a"), nil - assert_equal %w[a-2], set.find_all(req).map {|spec| spec.full_name } + assert_equal %w[a-2], set.find_all(req).map(&:full_name) end def test_find_all_prerelease spec_fetcher do |fetcher| - fetcher.download 'a', '1' - fetcher.download 'a', '1.a' + fetcher.download "a", "1" + fetcher.download "a", "1.a" end set = Gem::Resolver::InstallerSet.new :both - req = Gem::Resolver::DependencyRequest.new dep('a'), nil + req = Gem::Resolver::DependencyRequest.new dep("a"), nil - assert_equal %w[a-1], set.find_all(req).map {|spec| spec.full_name } + assert_equal %w[a-1], set.find_all(req).map(&:full_name) - req = Gem::Resolver::DependencyRequest.new dep('a', '>= 0.a'), nil + req = Gem::Resolver::DependencyRequest.new dep("a", ">= 0.a"), nil assert_equal %w[a-1 a-1.a], - set.find_all(req).map {|spec| spec.full_name }.sort + set.find_all(req).map(&:full_name).sort + end + + def test_find_all_prerelease_dependencies_with_add_local + activesupport_7_1_0_alpha = util_spec "activesupport", "7.1.0.alpha" + + install_gem activesupport_7_1_0_alpha + + set = Gem::Resolver::InstallerSet.new :both + + req = Gem::Resolver::DependencyRequest.new dep("activesupport", ">= 4.2.0"), nil + + assert_equal %w[activesupport-7.1.0.alpha], set.find_all(req).map(&:full_name) end def test_load_spec specs = spec_fetcher do |fetcher| - fetcher.spec 'a', 2 - fetcher.spec 'a', 2 do |s| + fetcher.spec "a", 2 + fetcher.spec "a", 2 do |s| s.platform = Gem::Platform.local end end @@ -182,7 +245,7 @@ class TestGemResolverInstallerSet < Gem::TestCase set = Gem::Resolver::InstallerSet.new :remote - spec = set.load_spec 'a', version, Gem::Platform.local, source + spec = set.load_spec "a", version, Gem::Platform.local, source assert_equal specs["a-2-#{Gem::Platform.local}"].full_name, spec.full_name end @@ -192,7 +255,7 @@ class TestGemResolverInstallerSet < Gem::TestCase def (set.remote_set).prefetch(_) raise "called" end - assert_raise(RuntimeError){ set.prefetch(nil) } + assert_raise(RuntimeError) { set.prefetch(nil) } set = Gem::Resolver::InstallerSet.new :local def (set.remote_set).prefetch(_) diff --git a/test/rubygems/test_gem_resolver_local_specification.rb b/test/rubygems/test_gem_resolver_local_specification.rb index 67b8f34cc1..cefd761520 100644 --- a/test/rubygems/test_gem_resolver_local_specification.rb +++ b/test/rubygems/test_gem_resolver_local_specification.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/available_set' + +require_relative "helper" +require "rubygems/available_set" class TestGemResolverLocalSpecification < Gem::TestCase def setup @@ -11,12 +12,12 @@ class TestGemResolverLocalSpecification < Gem::TestCase def test_install specs = spec_fetcher do |fetcher| - fetcher.gem 'a', 2 + fetcher.gem "a", 2 end - source = Gem::Source::SpecificFile.new 'gems/a-2.gem' + source = Gem::Source::SpecificFile.new "gems/a-2.gem" - spec = Gem::Resolver::LocalSpecification.new @set, specs['a-2'], source + spec = Gem::Resolver::LocalSpecification.new @set, specs["a-2"], source called = false @@ -24,13 +25,13 @@ class TestGemResolverLocalSpecification < Gem::TestCase called = installer end - assert_path_exist File.join @gemhome, 'specifications', 'a-2.gemspec' + assert_path_exist File.join @gemhome, "specifications", "a-2.gemspec" assert_kind_of Gem::Installer, called end def test_installable_platform_eh - b, b_gem = util_gem 'a', 1 do |s| + b, b_gem = util_gem "a", 1 do |s| s.platform = Gem::Platform.new %w[cpu other_platform 1] end diff --git a/test/rubygems/test_gem_resolver_lock_set.rb b/test/rubygems/test_gem_resolver_lock_set.rb index cb03e0b5f8..ebb64ef583 100644 --- a/test/rubygems/test_gem_resolver_lock_set.rb +++ b/test/rubygems/test_gem_resolver_lock_set.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" class TestGemResolverLockSet < Gem::TestCase def setup @@ -12,47 +13,47 @@ class TestGemResolverLockSet < Gem::TestCase end def test_add - specs = @set.add 'a', '2', Gem::Platform::RUBY + specs = @set.add "a", "2", Gem::Platform::RUBY spec = specs.first - assert_equal %w[a-2], @set.specs.map {|t| t.full_name } + assert_equal %w[a-2], @set.specs.map(&:full_name) assert_kind_of Gem::Resolver::LockSpecification, spec assert_equal @set, spec.set - assert_equal 'a', spec.name + assert_equal "a", spec.name assert_equal v(2), spec.version assert_equal Gem::Platform::RUBY, spec.platform assert_equal @lock_source, spec.source end def test_find_all - @set.add 'a', '1.a', Gem::Platform::RUBY - @set.add 'a', '2', Gem::Platform::RUBY - @set.add 'b', '2', Gem::Platform::RUBY + @set.add "a", "1.a", Gem::Platform::RUBY + @set.add "a", "2", Gem::Platform::RUBY + @set.add "b", "2", Gem::Platform::RUBY - found = @set.find_all dep 'a' + found = @set.find_all dep "a" - assert_equal %w[a-2], found.map {|s| s.full_name } + assert_equal %w[a-2], found.map(&:full_name) - found = @set.find_all dep 'a', '>= 0.a' + found = @set.find_all dep "a", ">= 0.a" - assert_equal %w[a-1.a a-2], found.map {|s| s.full_name } + assert_equal %w[a-1.a a-2], found.map(&:full_name) end def test_load_spec spec_fetcher do |fetcher| - fetcher.spec 'a', 2 + fetcher.spec "a", 2 end version = v(2) - @set.add 'a', version, Gem::Platform::RUBY + @set.add "a", version, Gem::Platform::RUBY - loaded = @set.load_spec 'a', version, Gem::Platform::RUBY, nil + loaded = @set.load_spec "a", version, Gem::Platform::RUBY, nil assert_kind_of Gem::Specification, loaded - assert_equal 'a-2', loaded.full_name + assert_equal "a-2", loaded.full_name end def test_prefetch diff --git a/test/rubygems/test_gem_resolver_lock_specification.rb b/test/rubygems/test_gem_resolver_lock_specification.rb index 07654a9164..402f5d1509 100644 --- a/test/rubygems/test_gem_resolver_lock_specification.rb +++ b/test/rubygems/test_gem_resolver_lock_specification.rb @@ -1,22 +1,21 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/installer' -require 'rubygems/resolver' + +require_relative "helper" +require "rubygems/installer" +require "rubygems/resolver" class TestGemResolverLockSpecification < Gem::TestCase def setup super - @LS = Gem::Resolver::LockSpecification - @source = Gem::Source.new @gem_repo @set = Gem::Resolver::LockSet.new [@source] end def test_initialize - spec = @LS.new @set, 'a', v(2), [@source], Gem::Platform::RUBY + spec = Gem::Resolver::LockSpecification.new @set, "a", v(2), [@source], Gem::Platform::RUBY - assert_equal 'a', spec.name + assert_equal "a", spec.name assert_equal v(2), spec.version assert_equal Gem::Platform::RUBY, spec.platform @@ -24,9 +23,9 @@ class TestGemResolverLockSpecification < Gem::TestCase end def test_add_dependency - l_spec = @LS.new @set, 'a', v(2), [@source], Gem::Platform::RUBY + l_spec = Gem::Resolver::LockSpecification.new @set, "a", v(2), [@source], Gem::Platform::RUBY - b_dep = dep('b', '>= 0') + b_dep = dep("b", ">= 0") l_spec.add_dependency b_dep @@ -35,10 +34,10 @@ class TestGemResolverLockSpecification < Gem::TestCase def test_install spec_fetcher do |fetcher| - fetcher.download 'a', 2 + fetcher.download "a", 2 end - spec = @LS.new @set, 'a', v(2), [@source], Gem::Platform::RUBY + spec = Gem::Resolver::LockSpecification.new @set, "a", v(2), [@source], Gem::Platform::RUBY called = false @@ -50,9 +49,9 @@ class TestGemResolverLockSpecification < Gem::TestCase end def test_install_installed - spec = @LS.new @set, 'a', v(2), [@source], Gem::Platform::RUBY + spec = Gem::Resolver::LockSpecification.new @set, "a", v(2), [@source], Gem::Platform::RUBY - FileUtils.touch File.join(@gemhome, 'specifications', spec.spec.spec_name) + FileUtils.touch File.join(@gemhome, "specifications", spec.spec.spec_name) called = false @@ -66,17 +65,17 @@ class TestGemResolverLockSpecification < Gem::TestCase def test_spec version = v(2) - l_spec = @LS.new @set, 'a', version, [@source], Gem::Platform::RUBY + l_spec = Gem::Resolver::LockSpecification.new @set, "a", version, [@source], Gem::Platform::RUBY - b_dep = dep 'b', '>= 0' - c_dep = dep 'c', '~> 1' + b_dep = dep "b", ">= 0" + c_dep = dep "c", "~> 1" l_spec.add_dependency b_dep l_spec.add_dependency c_dep spec = l_spec.spec - assert_equal 'a', spec.name + assert_equal "a", spec.name assert_equal version, spec.version assert_equal Gem::Platform::RUBY, spec.platform @@ -84,13 +83,13 @@ class TestGemResolverLockSpecification < Gem::TestCase end def test_spec_loaded - real_spec = util_spec 'a', 2 + real_spec = util_spec "a", 2 install_specs real_spec real_spec.activate version = v(2) - l_spec = @LS.new @set, 'a', version, [@source], Gem::Platform::RUBY + l_spec = Gem::Resolver::LockSpecification.new @set, "a", version, [@source], Gem::Platform::RUBY assert_same real_spec, l_spec.spec end diff --git a/test/rubygems/test_gem_resolver_requirement_list.rb b/test/rubygems/test_gem_resolver_requirement_list.rb index af8a77ef4b..20251805fc 100644 --- a/test/rubygems/test_gem_resolver_requirement_list.rb +++ b/test/rubygems/test_gem_resolver_requirement_list.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" class TestGemResolverRequirementList < Gem::TestCase def setup diff --git a/test/rubygems/test_gem_resolver_specification.rb b/test/rubygems/test_gem_resolver_specification.rb index 8b50bf91bd..e2bbce0c0c 100644 --- a/test/rubygems/test_gem_resolver_specification.rb +++ b/test/rubygems/test_gem_resolver_specification.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" class TestGemResolverSpecification < Gem::TestCase class TestSpec < Gem::Resolver::Specification @@ -16,31 +17,31 @@ class TestGemResolverSpecification < Gem::TestCase def test_install gemhome = "#{@gemhome}2" spec_fetcher do |fetcher| - fetcher.gem 'a', 1 + fetcher.gem "a", 1 end - a = util_spec 'a', 1 + a = util_spec "a", 1 a_spec = TestSpec.new a a_spec.source = Gem::Source.new @gem_repo - a_spec.install :install_dir => gemhome + a_spec.install install_dir: gemhome - assert_path_exist File.join gemhome, 'gems', a.full_name + assert_path_exist File.join gemhome, "gems", a.full_name - expected = File.join gemhome, 'specifications', a.spec_name + expected = File.join gemhome, "specifications", a.spec_name assert_equal expected, a_spec.spec.loaded_from end def test_installable_platform_eh - a = util_spec 'a', 1 + a = util_spec "a", 1 a_spec = TestSpec.new a assert a_spec.installable_platform? - b = util_spec 'a', 1 do |s| + b = util_spec "a", 1 do |s| s.platform = Gem::Platform.new %w[cpu other_platform 1] end @@ -50,7 +51,7 @@ class TestGemResolverSpecification < Gem::TestCase end def test_source - a = util_spec 'a', 1 + a = util_spec "a", 1 source = Gem::Source.new @gem_repo diff --git a/test/rubygems/test_gem_resolver_vendor_set.rb b/test/rubygems/test_gem_resolver_vendor_set.rb index 19cc7383c6..25a3c5fc7b 100644 --- a/test/rubygems/test_gem_resolver_vendor_set.rb +++ b/test/rubygems/test_gem_resolver_vendor_set.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" class TestGemResolverVendorSet < Gem::TestCase def setup @@ -40,7 +41,7 @@ class TestGemResolverVendorSet < Gem::TestCase @set.add_vendor_gem name, directory - dependency = dep 'a', '~> 1' + dependency = dep "a", "~> 1" req = Gem::Resolver::DependencyRequest.new dependency, nil @@ -58,15 +59,15 @@ class TestGemResolverVendorSet < Gem::TestCase end def test_find_all_prerelease - name, _, directory = vendor_gem 'a', '1.a' + name, _, directory = vendor_gem "a", "1.a" @set.add_vendor_gem name, directory - req = Gem::Resolver::DependencyRequest.new dep('a'), nil + req = Gem::Resolver::DependencyRequest.new dep("a"), nil assert_empty @set.find_all req - req = Gem::Resolver::DependencyRequest.new dep('a', '>= 0.a'), nil + req = Gem::Resolver::DependencyRequest.new dep("a", ">= 0.a"), nil refute_empty @set.find_all req end @@ -75,7 +76,7 @@ class TestGemResolverVendorSet < Gem::TestCase error = Object.const_defined?(:KeyError) ? KeyError : IndexError assert_raise error do - @set.load_spec 'b', v(1), Gem::Platform::RUBY, nil + @set.load_spec "b", v(1), Gem::Platform::RUBY, nil end end end diff --git a/test/rubygems/test_gem_resolver_vendor_specification.rb b/test/rubygems/test_gem_resolver_vendor_specification.rb index dbf0c58e0b..3525a6c14c 100644 --- a/test/rubygems/test_gem_resolver_vendor_specification.rb +++ b/test/rubygems/test_gem_resolver_vendor_specification.rb @@ -1,12 +1,13 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" class TestGemResolverVendorSpecification < Gem::TestCase def setup super @set = Gem::Resolver::VendorSet.new - @spec = Gem::Specification.new 'a', 1 + @spec = Gem::Specification.new "a", 1 end def test_equals2 @@ -14,7 +15,7 @@ class TestGemResolverVendorSpecification < Gem::TestCase assert_equal v_spec_a, v_spec_a - spec_b = Gem::Specification.new 'b', 1 + spec_b = Gem::Specification.new "b", 1 v_spec_b = Gem::Resolver::VendorSpecification.new @set, spec_b refute_equal v_spec_a, v_spec_b @@ -27,24 +28,25 @@ class TestGemResolverVendorSpecification < Gem::TestCase i_set = Gem::Resolver::IndexSet.new source = Gem::Source.new @gem_repo i_spec = Gem::Resolver::IndexSpecification.new( - i_set, 'a', v(1), source, Gem::Platform::RUBY) + i_set, "a", v(1), source, Gem::Platform::RUBY + ) refute_equal v_spec_a, i_spec end def test_dependencies - @spec.add_dependency 'b' - @spec.add_dependency 'c' + @spec.add_dependency "b" + @spec.add_dependency "c" v_spec = Gem::Resolver::VendorSpecification.new @set, @spec - assert_equal [dep('b'), dep('c')], v_spec.dependencies + assert_equal [dep("b"), dep("c")], v_spec.dependencies end def test_full_name v_spec = Gem::Resolver::VendorSpecification.new @set, @spec - assert_equal 'a-1', v_spec.full_name + assert_equal "a-1", v_spec.full_name end def test_install @@ -62,7 +64,7 @@ class TestGemResolverVendorSpecification < Gem::TestCase def test_name v_spec = Gem::Resolver::VendorSpecification.new @set, @spec - assert_equal 'a', v_spec.name + assert_equal "a", v_spec.name end def test_platform @@ -72,7 +74,7 @@ class TestGemResolverVendorSpecification < Gem::TestCase end def test_version - spec = Gem::Specification.new 'a', 1 + spec = Gem::Specification.new "a", 1 v_spec = Gem::Resolver::VendorSpecification.new @set, spec diff --git a/test/rubygems/test_gem_safe_marshal.rb b/test/rubygems/test_gem_safe_marshal.rb new file mode 100644 index 0000000000..ebb000a9ef --- /dev/null +++ b/test/rubygems/test_gem_safe_marshal.rb @@ -0,0 +1,404 @@ +# frozen_string_literal: true + +require_relative "helper" + +require "date" +require "rubygems/safe_marshal" + +class TestGemSafeMarshal < Gem::TestCase + define_method("test_safe_load_marshal Date #<Date: 1994-12-09 ((2449696j,0s,0n),+0s,2299161j)>") { assert_safe_load_marshal "\x04\bU:\tDate[\vi\x00i\x03 a%i\x00i\x00i\x00f\f2299161" } + define_method("test_safe_load_marshal Float 0.0") { assert_safe_load_marshal "\x04\bf\x060" } + define_method("test_safe_load_marshal Float -0.0") { assert_safe_load_marshal "\x04\bf\a-0" } + define_method("test_safe_load_marshal Float Infinity") { assert_safe_load_marshal "\x04\bf\binf" } + define_method("test_safe_load_marshal Float -Infinity") { assert_safe_load_marshal "\x04\bf\t-inf" } + define_method("test_safe_load_marshal Float NaN") { assert_safe_load_marshal "\x04\bf\bnan", equality: false } + define_method("test_safe_load_marshal Float 1.1") { assert_safe_load_marshal "\x04\bf\b1.1" } + define_method("test_safe_load_marshal Float -1.1") { assert_safe_load_marshal "\x04\bf\t-1.1" } + define_method("test_safe_load_marshal Float 30000000.0") { assert_safe_load_marshal "\x04\bf\b3e7" } + define_method("test_safe_load_marshal Float -30000000.0") { assert_safe_load_marshal "\x04\bf\t-3e7" } + define_method("test_safe_load_marshal Gem::Version #<Gem::Version \"1.abc\">") { assert_safe_load_marshal "\x04\bU:\x11Gem::Version[\x06I\"\n1.abc\x06:\x06ET" } + define_method("test_safe_load_marshal Hash {} default value") { assert_safe_load_marshal "\x04\b}\x00[\x00", additional_methods: [:default] } + define_method("test_safe_load_marshal Hash {}") { assert_safe_load_marshal "\x04\b{\x00" } + define_method("test_safe_load_marshal Array {}") { assert_safe_load_marshal "\x04\b[\x00" } + define_method("test_safe_load_marshal Hash {:runtime=>:development}") { assert_safe_load_marshal "\x04\bI{\x06:\fruntime:\x10development\x06:\n@type[\x00", permitted_ivars: { "Hash" => %w[@type] } } + define_method("test_safe_load_marshal Integer -1") { assert_safe_load_marshal "\x04\bi\xFA" } + define_method("test_safe_load_marshal Integer -1048575") { assert_safe_load_marshal "\x04\bi\xFD\x01\x00\xF0" } + define_method("test_safe_load_marshal Integer -122") { assert_safe_load_marshal "\x04\bi\x81" } + define_method("test_safe_load_marshal Integer -123") { assert_safe_load_marshal "\x04\bi\x80" } + define_method("test_safe_load_marshal Integer -124") { assert_safe_load_marshal "\x04\bi\xFF\x84" } + define_method("test_safe_load_marshal Integer -127") { assert_safe_load_marshal "\x04\bi\xFF\x81" } + define_method("test_safe_load_marshal Integer -128") { assert_safe_load_marshal "\x04\bi\xFF\x80" } + define_method("test_safe_load_marshal Integer -2") { assert_safe_load_marshal "\x04\bi\xF9" } + define_method("test_safe_load_marshal Integer -255") { assert_safe_load_marshal "\x04\bi\xFF\x01" } + define_method("test_safe_load_marshal Integer -256") { assert_safe_load_marshal "\x04\bi\xFF\x00" } + define_method("test_safe_load_marshal Integer -257") { assert_safe_load_marshal "\x04\bi\xFE\xFF\xFE" } + define_method("test_safe_load_marshal Integer -268435455") { assert_safe_load_marshal "\x04\bi\xFC\x01\x00\x00\xF0" } + define_method("test_safe_load_marshal Integer -268435456") { assert_safe_load_marshal "\x04\bi\xFC\x00\x00\x00\xF0" } + define_method("test_safe_load_marshal Integer -3") { assert_safe_load_marshal "\x04\bi\xF8" } + define_method("test_safe_load_marshal Integer -4") { assert_safe_load_marshal "\x04\bi\xF7" } + define_method("test_safe_load_marshal Integer -4294967295") { assert_safe_load_marshal "\x04\bl-\a\xFF\xFF\xFF\xFF" } + define_method("test_safe_load_marshal Integer -4294967296") { assert_safe_load_marshal "\x04\bl-\b\x00\x00\x00\x00\x01\x00" } + define_method("test_safe_load_marshal Integer -5") { assert_safe_load_marshal "\x04\bi\xF6" } + define_method("test_safe_load_marshal Integer -6") { assert_safe_load_marshal "\x04\bi\xF5" } + define_method("test_safe_load_marshal Integer -65535") { assert_safe_load_marshal "\x04\bi\xFE\x01\x00" } + define_method("test_safe_load_marshal Integer -65536") { assert_safe_load_marshal "\x04\bi\xFE\x00\x00" } + define_method("test_safe_load_marshal Integer -9223372036854775807") { assert_safe_load_marshal "\x04\bl-\t\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F" } + define_method("test_safe_load_marshal Integer -9223372036854775808") { assert_safe_load_marshal "\x04\bl-\t\x00\x00\x00\x00\x00\x00\x00\x80" } + define_method("test_safe_load_marshal Integer 0") { assert_safe_load_marshal "\x04\bi\x00" } + define_method("test_safe_load_marshal Integer 1") { assert_safe_load_marshal "\x04\bi\x06" } + define_method("test_safe_load_marshal Integer 1048574") { assert_safe_load_marshal "\x04\bi\x03\xFE\xFF\x0F" } + define_method("test_safe_load_marshal Integer 1048575") { assert_safe_load_marshal "\x04\bi\x03\xFF\xFF\x0F" } + define_method("test_safe_load_marshal Integer 1048576") { assert_safe_load_marshal "\x04\bi\x03\x00\x00\x10" } + define_method("test_safe_load_marshal Integer 121") { assert_safe_load_marshal "\x04\bi~" } + define_method("test_safe_load_marshal Integer 122") { assert_safe_load_marshal "\x04\bi\x7F" } + define_method("test_safe_load_marshal Integer 123") { assert_safe_load_marshal "\x04\bi\x01{" } + define_method("test_safe_load_marshal Integer 124") { assert_safe_load_marshal "\x04\bi\x01|" } + define_method("test_safe_load_marshal Integer 125") { assert_safe_load_marshal "\x04\bi\x01}" } + define_method("test_safe_load_marshal Integer 126") { assert_safe_load_marshal "\x04\bi\x01~" } + define_method("test_safe_load_marshal Integer 127") { assert_safe_load_marshal "\x04\bi\x01\x7F" } + define_method("test_safe_load_marshal Integer 128") { assert_safe_load_marshal "\x04\bi\x01\x80" } + define_method("test_safe_load_marshal Integer 129") { assert_safe_load_marshal "\x04\bi\x01\x81" } + define_method("test_safe_load_marshal Integer 2") { assert_safe_load_marshal "\x04\bi\a" } + define_method("test_safe_load_marshal Integer 254") { assert_safe_load_marshal "\x04\bi\x01\xFE" } + define_method("test_safe_load_marshal Integer 255") { assert_safe_load_marshal "\x04\bi\x01\xFF" } + define_method("test_safe_load_marshal Integer 256") { assert_safe_load_marshal "\x04\bi\x02\x00\x01" } + define_method("test_safe_load_marshal Integer 257") { assert_safe_load_marshal "\x04\bi\x02\x01\x01" } + define_method("test_safe_load_marshal Integer 258") { assert_safe_load_marshal "\x04\bi\x02\x02\x01" } + define_method("test_safe_load_marshal Integer 268435454") { assert_safe_load_marshal "\x04\bi\x04\xFE\xFF\xFF\x0F" } + define_method("test_safe_load_marshal Integer 268435455") { assert_safe_load_marshal "\x04\bi\x04\xFF\xFF\xFF\x0F" } + define_method("test_safe_load_marshal Integer 268435456") { assert_safe_load_marshal "\x04\bi\x04\x00\x00\x00\x10" } + define_method("test_safe_load_marshal Integer 268435457") { assert_safe_load_marshal "\x04\bi\x04\x01\x00\x00\x10" } + define_method("test_safe_load_marshal Integer 3") { assert_safe_load_marshal "\x04\bi\b" } + define_method("test_safe_load_marshal Integer 4") { assert_safe_load_marshal "\x04\bi\t" } + define_method("test_safe_load_marshal Integer 4294967294") { assert_safe_load_marshal "\x04\bl+\a\xFE\xFF\xFF\xFF" } + define_method("test_safe_load_marshal Integer 4294967295") { assert_safe_load_marshal "\x04\bl+\a\xFF\xFF\xFF\xFF" } + define_method("test_safe_load_marshal Integer 4294967296") { assert_safe_load_marshal "\x04\bl+\b\x00\x00\x00\x00\x01\x00" } + define_method("test_safe_load_marshal Integer 4294967297") { assert_safe_load_marshal "\x04\bl+\b\x01\x00\x00\x00\x01\x00" } + define_method("test_safe_load_marshal Integer 5") { assert_safe_load_marshal "\x04\bi\n" } + define_method("test_safe_load_marshal Integer 6") { assert_safe_load_marshal "\x04\bi\v" } + define_method("test_safe_load_marshal Integer 65534") { assert_safe_load_marshal "\x04\bi\x02\xFE\xFF" } + define_method("test_safe_load_marshal Integer 65535") { assert_safe_load_marshal "\x04\bi\x02\xFF\xFF" } + define_method("test_safe_load_marshal Integer 65536") { assert_safe_load_marshal "\x04\bi\x03\x00\x00\x01" } + define_method("test_safe_load_marshal Integer 65537") { assert_safe_load_marshal "\x04\bi\x03\x01\x00\x01" } + define_method("test_safe_load_marshal Integer 7") { assert_safe_load_marshal "\x04\bi\f" } + define_method("test_safe_load_marshal Integer 9223372036854775806") { assert_safe_load_marshal "\x04\bl+\t\xFE\xFF\xFF\xFF\xFF\xFF\xFF\x7F" } + define_method("test_safe_load_marshal Integer 9223372036854775807") { assert_safe_load_marshal "\x04\bl+\t\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F" } + define_method("test_safe_load_marshal Integer 9223372036854775808") { assert_safe_load_marshal "\x04\bl+\t\x00\x00\x00\x00\x00\x00\x00\x80" } + define_method("test_safe_load_marshal Integer 9223372036854775809") { assert_safe_load_marshal "\x04\bl+\t\x01\x00\x00\x00\x00\x00\x00\x80" } + define_method("test_safe_load_marshal Rational (1/3)") { assert_safe_load_marshal "\x04\bU:\rRational[\ai\x06i\b" } + define_method("test_safe_load_marshal Array [[...]]") { assert_safe_load_marshal "\x04\b[\x06@\x00" } + define_method("test_safe_load_marshal String \"hello\" ivar") { assert_safe_load_marshal "\x04\bI\"\nhello\a:\x06ET:\n@type@\x00", additional_methods: [:instance_variables], permitted_ivars: { "String" => %w[@type E] } } + define_method("test_safe_load_marshal Array [\"hello\", [\"hello\"], \"hello\", [\"hello\"]]") { assert_safe_load_marshal "\x04\b[\tI\"\nhello\x06:\x06ET[\x06@\x06@\x06@\a" } + define_method("test_safe_load_marshal Array [\"hello\", \"hello\"]") { assert_safe_load_marshal "\x04\b[\aI\"\nhello\x06:\x06ET@\x06" } + define_method("test_safe_load_marshal Array [:development, :development]") { assert_safe_load_marshal "\x04\b[\a:\x10development;\x00" } + define_method("test_safe_load_marshal String \"abc\" ascii") { assert_safe_load_marshal "\x04\bI\"\babc\x06:\x06EF", additional_methods: [:encoding] } + define_method("test_safe_load_marshal Array [\"abc\", \"abc\"] ascii") { assert_safe_load_marshal "\x04\b[\aI\"\babc\x06:\x06EF@\x06", additional_methods: [->(x) { x.map(&:encoding) }] } + define_method("test_safe_load_marshal String \"abc\" utf8") { assert_safe_load_marshal "\x04\bI\"\babc\x06:\x06ET", additional_methods: [:encoding] } + define_method("test_safe_load_marshal Array [\"abc\", \"abc\"] utf8") { assert_safe_load_marshal "\x04\b[\aI\"\babc\x06:\x06ET@\x06", additional_methods: [->(x) { x.map(&:encoding) }] } + define_method("test_safe_load_marshal String \"abc\" Windows-1256") { assert_safe_load_marshal "\x04\bI\"\babc\x06:\rencoding\"\x11Windows-1256", additional_methods: [:encoding] } + define_method("test_safe_load_marshal Array [\"abc\", \"abc\"] Windows-1256") { assert_safe_load_marshal "\x04\b[\aI\"\babc\x06:\rencoding\"\x11Windows-1256@\x06", additional_methods: [->(x) { x.map(&:encoding) }] } + define_method("test_safe_load_marshal String \"abc\" binary") { assert_safe_load_marshal "\x04\b\"\babc", additional_methods: [:encoding] } + define_method("test_safe_load_marshal Array [\"abc\", \"abc\"] binary") { assert_safe_load_marshal "\x04\b[\a\"\babc@\x06", additional_methods: [->(x) { x.map(&:encoding) }] } + define_method("test_safe_load_marshal String \"\\x61\\x62\\x63\" utf32") { assert_safe_load_marshal "\x04\bI\"\babc\x06:\rencoding\"\vUTF-32", additional_methods: [:encoding] } + define_method("test_safe_load_marshal Array [\"\\x61\\x62\\x63\", \"\\x61\\x62\\x63\"] utf32") { assert_safe_load_marshal "\x04\b[\aI\"\babc\x06:\rencoding\"\vUTF-32@\x06", additional_methods: [->(x) { x.map(&:encoding) }] } + define_method("test_safe_load_marshal String \"abc\" ivar") { assert_safe_load_marshal "\x04\bI\"\babc\a:\x06ET:\n@typeI\"\ttype\x06;\x00T", permitted_ivars: { "String" => %w[@type E] } } + define_method("test_safe_load_marshal String \"\"") { assert_safe_load_marshal "\x04\bI\"\babc\x06:\x06ET" } + define_method("test_safe_load_marshal Time 2000-12-31 20:07:59 -1152") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x00\x00\xB0\xEF\a:\voffseti\xFE Y:\tzone0", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] } + define_method("test_safe_load_marshal Time 2000-12-31 23:59:59 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x00\x00\xB0\xEF\a:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] } + define_method("test_safe_load_marshal Time 2000-12-31 23:59:59 2254051613498933/2251799813685248000000000 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x00\x00\xB0\xEF\n:\rnano_numl+\t5^\xBAI\f\x02\b\x00:\rnano_denl+\t\x00\x00\x00\x00\x00\x00\b\x00:\rsubmicro\"\a\x00\x10:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] } + define_method("test_safe_load_marshal Time 2000-12-31 23:59:59 2476979795053773/2251799813685248000 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80L\x04\xB0\xEF\t:\rnano_numi\x025\f:\rnano_denl+\b\x00\x00\x00\x00\x00 :\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] } + define_method("test_safe_load_marshal Time 2000-12-31 23:59:59 2476979795053773/2251799813685248000000 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x01\x00\xB0\xEF\n:\rnano_numl+\t\x19\x00\x00\x00\x00\x00d\x00:\rnano_denl+\t\x00\x00\x00\x00\x00\x00\x01\x00:\rsubmicro\"\x06\x10:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] } + define_method("test_safe_load_marshal Time 2000-12-31 23:59:59 2476979795053773/2251799813685248000000000 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x00\x00\xB0\xEF\n:\rnano_numl+\t\xCD\xCC\xCC\xCC\xCC\xCC\b\x00:\rnano_denl+\t\x00\x00\x00\x00\x00\x00\b\x00:\rsubmicro\"\a\x00\x10:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] } + define_method("test_safe_load_marshal Time 2000-12-31 23:59:59 450364466336677/450359962737049600000000 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x00\x00\xB0\xEF\n:\rnano_numl+\t9b->\x05\x00\b\x00:\rnano_denl+\t\x00\x00\x00\x00\x00\x00\b\x00:\rsubmicro\"\a\x00\x10:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] } + define_method("test_safe_load_marshal Time 2000-12-31 23:59:59 4548635623644201/4503599627370496000 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\xF2\x03\xB0\xEF\t:\rnano_numi\x02q\x02:\rnano_denl+\b\x00\x00\x00\x00\x00@:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] } + define_method("test_safe_load_marshal Time 2000-12-31 23:59:59 4548635623644201/4503599627370496000000 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x01\x00\xB0\xEF\n:\rnano_numl+\t\x05\x00\x00\x00\x00\x00\x14\x00:\rnano_denl+\t\x00\x00\x00\x00\x00\x00\x02\x00:\rsubmicro\"\x06\x01:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] } + define_method("test_safe_load_marshal Time 2000-12-31 23:59:59 4548635623644201/4503599627370496000000000 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x00\x00\xB0\xEF\n:\rnano_numl+\t)\\\x8F\xC2\xF5(\x10\x00:\rnano_denl+\t\x00\x00\x00\x00\x00\x00\x10\x00:\rsubmicro\"\a\x00\x10:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] } + define_method("test_safe_load_marshal Time 2000-12-31 23:59:59.000000001 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x00\x00\xB0\xEF\n:\rnano_numi\x06:\rnano_deni\x06:\rsubmicro\"\a\x00\x10:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] } + define_method("test_safe_load_marshal Time 2000-12-31 23:59:59.000001 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x01\x00\xB0\xEF\a:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] } + define_method("test_safe_load_marshal Time 2000-12-31 23:59:59.001 -0800") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\xE8\x03\xB0\xEF\a:\voffseti\xFE\x80\x8F:\tzoneI\"\bPST\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] } + define_method("test_safe_load_marshal Time 2001-01-01 07:59:59 +0000") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x00\x00\xB0\xEF\a:\voffseti\x00:\tzone0", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] } + define_method("test_safe_load_marshal Time 2001-01-01 07:59:59 UTC") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\xC0\x00\x00\xB0\xEF\x06:\tzoneI\"\bUTC\x06:\x06EF", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] } + define_method("test_safe_load_marshal Time 2001-01-01 11:59:59 +0400") { assert_safe_load_marshal "\x04\bIu:\tTime\r'@\x19\x80\x00\x00\xB0\xEF\a:\voffseti\x02@8:\tzone0", additional_methods: [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] } + define_method("test_safe_load_marshal Time 2023-08-24 10:10:39.09565 -0700") { assert_safe_load_marshal "\x04\bIu:\tTime\r\x11\xDF\x1E\x80\xA2uq*\a:\voffseti\xFE\x90\x9D:\tzoneI\"\bPDT\x06:\x06EF" } + define_method("test_safe_load_marshal Time 2023-08-24 10:10:39.098453 -0700") { assert_safe_load_marshal "\x04\bIu:\tTime\r\x11\xDF\x1E\x80\x95\x80q*\b:\n@typeI\"\fruntime\x06:\x06ET:\voffseti\xFE\x90\x9D:\tzoneI\"\bPDT\x06;\aF", permitted_ivars: { "Time" => %w[@type offset zone], "String" => %w[E @debug_created_info] }, marshal_dump_equality: true } + + def test_repeated_symbol + assert_safe_load_as [:development, :development] + end + + def test_length_one_symbols + with_const(Gem::SafeMarshal, :PERMITTED_SYMBOLS, %w[E A b 0] << "") do + assert_safe_load_as [:A, :E, :E, :A, "".to_sym, "".to_sym], additional_methods: [:instance_variables] + end + end + + def test_repeated_string + s = "hello" + a = [s] + assert_safe_load_as [s, a, s, a] + assert_safe_load_as [s, s] + end + + def test_recursive_string + s = String.new("hello") + s.instance_variable_set(:@type, s) + with_const(Gem::SafeMarshal, :PERMITTED_IVARS, { "String" => %w[@type E] }) do + assert_safe_load_as s, additional_methods: [:instance_variables] + end + end + + def test_recursive_array + a = [] + a << a + assert_safe_load_as a + end + + def test_time_loads + assert_safe_load_as Time.new + end + + def test_string_with_encoding + [ + String.new("abc", encoding: "US-ASCII"), + String.new("abc", encoding: "UTF-8"), + String.new("abc", encoding: "Windows-1256"), + String.new("abc", encoding: Encoding::BINARY), + String.new("abc", encoding: "UTF-32"), + + String.new("", encoding: "US-ASCII"), + String.new("", encoding: "UTF-8"), + String.new("", encoding: "Windows-1256"), + String.new("", encoding: Encoding::BINARY), + String.new("", encoding: "UTF-32"), + ].each do |s| + assert_safe_load_as s, additional_methods: [:encoding] + assert_safe_load_as [s, s], additional_methods: [->(a) { a.map(&:encoding) }] + end + end + + def test_string_with_ivar + str = String.new("abc") + str.instance_variable_set :@type, "type" + with_const(Gem::SafeMarshal, :PERMITTED_IVARS, { "String" => %w[@type E @debug_created_info] }) do + assert_safe_load_as str + end + end + + def test_time_with_ivar + pend "Marshal.load of Time with ivars is broken on jruby, see https://github.com/jruby/jruby/issues/7902" if RUBY_ENGINE == "jruby" + + with_const(Gem::SafeMarshal, :PERMITTED_IVARS, { "Time" => %w[@type offset zone nano_num nano_den submicro], "String" => %w[E @debug_created_info] }) do + assert_safe_load_as Time.new.tap {|t| t.instance_variable_set :@type, "runtime" }, marshal_dump_equality: true + end + end + + secs = Time.new(2000, 12, 31, 23, 59, 59).to_i + [ + Time.at(secs), + Time.at(secs, in: "+04:00"), + Time.at(secs, in: "-11:52"), + Time.at(secs, in: "+00:00"), + Time.at(secs, in: "-00:00"), + Time.at(secs, 1, :millisecond), + Time.at(secs, 1.1, :millisecond), + Time.at(secs, 1.01, :millisecond), + Time.at(secs, 1, :microsecond), + Time.at(secs, 1.1, :microsecond), + Time.at(secs, 1.01, :microsecond), + Time.at(secs, 1, :nanosecond), + Time.at(secs, 1.1, :nanosecond), + Time.at(secs, 1.01, :nanosecond), + Time.at(secs, 1.001, :nanosecond), + Time.at(secs, 1.00001, :nanosecond), + Time.at(secs, 1.00001, :nanosecond), + Time.at(secs, in: "UTC"), + Time.at(secs, in: "Z"), + ].each_with_index do |t, i| + define_method("test_time_#{i} #{t.inspect}") do + additional_methods = [:ctime, :to_f, :to_r, :to_i, :zone, :subsec, :instance_variables, :dst?, :to_a] + assert_safe_load_as t, additional_methods: additional_methods + end + end + + def test_floats + [0.0, Float::INFINITY, Float::NAN, 1.1, 3e7].each do |f| + assert_safe_load_as f + assert_safe_load_as(-f) + end + end + + def test_hash_with_ivar + h = { runtime: :development } + h.instance_variable_set :@type, [] + with_const(Gem::SafeMarshal, :PERMITTED_IVARS, { "Hash" => %w[@type] }) do + assert_safe_load_as(h) + end + end + + def test_hash_with_default_value + assert_safe_load_as Hash.new([]) + end + + def test_hash_with_compare_by_identity + with_const(Gem::SafeMarshal, :PERMITTED_CLASSES, %w[Hash]) do + assert_safe_load_as Hash.new.compare_by_identity.tap {|h| + h[+"a"] = 1 + h[+"a"] = 2 }, additional_methods: [:compare_by_identity?], equality: false + assert_safe_load_as Hash.new.compare_by_identity, additional_methods: [:compare_by_identity?] + assert_safe_load_as Hash.new(0).compare_by_identity.tap {|h| + h[+"a"] = 1 + h[+"a"] = 2 }, additional_methods: [:compare_by_identity?, :default], equality: false + end + end + + class StringSubclass < ::String + end + + def test_string_subclass + with_const(Gem::SafeMarshal, :PERMITTED_CLASSES, [StringSubclass.name]) do + with_const(Gem::SafeMarshal, :PERMITTED_IVARS, { StringSubclass.name => %w[E] }) do + e = assert_raise(Gem::SafeMarshal::Visitors::ToRuby::UnsupportedError) do + Gem::SafeMarshal.safe_load Marshal.dump StringSubclass.new("abc") + end + assert_equal "Unsupported user class #{StringSubclass.name} in marshal stream @ root.object", e.message + end + end + end + + class ArraySubclass < ::Array + end + + def test_array_subclass + with_const(Gem::SafeMarshal, :PERMITTED_CLASSES, [ArraySubclass.name]) do + e = assert_raise(Gem::SafeMarshal::Visitors::ToRuby::UnsupportedError) do + Gem::SafeMarshal.safe_load(Marshal.dump(ArraySubclass.new << "abc")) + end + assert_equal "Unsupported user class #{ArraySubclass.name} in marshal stream @ root", e.message + end + end + + def test_frozen_object + assert_safe_load_as Gem::Version.new("1.abc").freeze + end + + def test_date + assert_safe_load_as Date.new(1994, 12, 9) + end + + def test_rational + assert_safe_load_as Rational(1, 3) + end + + [ + 0, 1, 2, 3, 4, 5, 6, 122, 123, 124, 127, 128, 255, 256, 257, + 2**16, 2**16 - 1, 2**20 - 1, + 2**28, 2**28 - 1, + 2**32, 2**32 - 1, + 2**63, 2**63 - 1 + ]. + each do |i| + define_method("test_int_ #{i}") do + assert_safe_load_as i + assert_safe_load_as(-i) + assert_safe_load_as(i + 1) + assert_safe_load_as(i - 1) + end + end + + def test_gem_spec_disallowed_symbol + e = assert_raise(Gem::SafeMarshal::Visitors::ToRuby::UnpermittedSymbolError) do + spec = Gem::Specification.new do |s| + s.name = "hi" + s.version = "1.2.3" + + s.dependencies << Gem::Dependency.new("rspec", Gem::Requirement.new([">= 1.2.3"]), :runtime).tap {|d| d.instance_variable_set(:@name, :rspec) } + end + Gem::SafeMarshal.safe_load(Marshal.dump(spec)) + end + + assert_equal e.message, "Attempting to load unpermitted symbol \"rspec\" @ root.[9].[0].@name" + end + + def test_gem_spec_disallowed_ivar + e = assert_raise(Gem::SafeMarshal::Visitors::ToRuby::UnpermittedIvarError) do + spec = Gem::Specification.new do |s| + s.name = "hi" + s.version = "1.2.3" + + s.metadata.instance_variable_set(:@foobar, "rspec") + end + Gem::SafeMarshal.safe_load(Marshal.dump(spec)) + end + + assert_equal e.message, "Attempting to set unpermitted ivar \"@foobar\" on object of class Hash @ root.[18].ivar_0" + end + + def test_unexpected_eof + e = assert_raise(Gem::SafeMarshal::Reader::EOFError) do + Gem::SafeMarshal.safe_load("\x04\x08") + end + assert_equal e.message, "Unexpected EOF" + + e = assert_raise(Gem::SafeMarshal::Reader::EOFError) do + Gem::SafeMarshal.safe_load("\x04\x08[") + end + assert_equal e.message, "Unexpected EOF" + + e = assert_raise(Gem::SafeMarshal::Reader::EOFError) do + Gem::SafeMarshal.safe_load("\x04\x08[\x06") + end + assert_equal e.message, "Unexpected EOF" + end + + def assert_safe_load_marshal(dumped, additional_methods: [], permitted_ivars: nil, equality: true, marshal_dump_equality: true) + loaded = Marshal.load(dumped) + safe_loaded = + if permitted_ivars + with_const(Gem::SafeMarshal, :PERMITTED_IVARS, permitted_ivars) do + Gem::SafeMarshal.safe_load(dumped) + end + else + Gem::SafeMarshal.safe_load(dumped) + end + + # NaN != NaN, for example + if equality + assert_equal loaded, safe_loaded, "should equal what Marshal.load returns" + end + + assert_equal loaded.to_s, safe_loaded.to_s, "should have equal to_s" + assert_equal loaded.inspect, safe_loaded.inspect, "should have equal inspect" + additional_methods.each do |m| + if m.is_a?(Proc) + call = m + else + call = ->(obj) { obj.__send__(m) } + end + + assert_equal call[loaded], call[safe_loaded], "should have equal #{m}" + end + if marshal_dump_equality + assert_equal Marshal.dump(loaded).dump, Marshal.dump(safe_loaded).dump, "should Marshal.dump the same" + end + end + + def assert_safe_load_as(x, **kwargs) + dumped = Marshal.dump(x) + equality = x == x # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands + assert_safe_load_marshal(dumped, equality: equality, **kwargs) + end + + def with_const(mod, name, new_value, &block) + orig = mod.const_get(name) + mod.send :remove_const, name + mod.const_set name, new_value + + begin + yield + ensure + mod.send :remove_const, name + mod.const_set name, orig + mod.send :private_constant, name + end + end +end diff --git a/test/rubygems/test_gem_safe_yaml.rb b/test/rubygems/test_gem_safe_yaml.rb new file mode 100644 index 0000000000..02df9f97da --- /dev/null +++ b/test/rubygems/test_gem_safe_yaml.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require_relative "helper" + +Gem.load_yaml + +class TestGemSafeYAML < Gem::TestCase + def test_aliases_enabled_by_default + assert_predicate Gem::SafeYAML, :aliases_enabled? + assert_equal({ "a" => "a", "b" => "a" }, Gem::SafeYAML.safe_load("a: &a a\nb: *a\n")) + end + + def test_aliases_disabled + aliases_enabled = Gem::SafeYAML.aliases_enabled? + Gem::SafeYAML.aliases_enabled = false + refute_predicate Gem::SafeYAML, :aliases_enabled? + expected_error = defined?(Psych::AliasesNotEnabled) ? Psych::AliasesNotEnabled : Psych::BadAlias + assert_raise expected_error do + Gem::SafeYAML.safe_load("a: &a\nb: *a\n") + end + ensure + Gem::SafeYAML.aliases_enabled = aliases_enabled + end +end diff --git a/test/rubygems/test_gem_security.rb b/test/rubygems/test_gem_security.rb index 0badb96763..82449a8626 100644 --- a/test/rubygems/test_gem_security.rb +++ b/test/rubygems/test_gem_security.rb @@ -1,33 +1,29 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/security' + +require_relative "helper" +require "rubygems/security" unless Gem::HAVE_OPENSSL - warn 'Skipping Gem::Security tests. openssl not found.' + warn "Skipping Gem::Security tests. openssl not found." end if Gem.java_platform? - warn 'Skipping Gem::Security tests on jruby.' + warn "Skipping Gem::Security tests on jruby." end class TestGemSecurity < Gem::TestCase - CHILD_KEY = load_key 'child' - - ALTERNATE_CERT = load_cert 'child' - CHILD_CERT = load_cert 'child' - EXPIRED_CERT = load_cert 'expired' + CHILD_KEY = load_key "child" + EC_KEY = load_key "private_ec", "Foo bar" - def setup - super - - @SEC = Gem::Security - end + ALTERNATE_CERT = load_cert "child" + CHILD_CERT = load_cert "child" + EXPIRED_CERT = load_cert "expired" def test_class_create_cert name = PUBLIC_CERT.subject key = PRIVATE_KEY - cert = @SEC.create_cert name, key, 60, Gem::Security::EXTENSIONS, 5 + cert = Gem::Security.create_cert name, key, 60, Gem::Security::EXTENSIONS, 5 assert_kind_of OpenSSL::X509::Certificate, cert @@ -41,37 +37,37 @@ class TestGemSecurity < Gem::TestCase 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 + constraints = cert.extensions.find {|ext| ext.oid == "basicConstraints" } + assert_equal "CA:FALSE", constraints.value - key_usage = cert.extensions.find {|ext| ext.oid == 'keyUsage' } - assert_equal 'Digital Signature, Key Encipherment, Data Encipherment', + key_usage = cert.extensions.find {|ext| ext.oid == "keyUsage" } + assert_equal "Digital Signature, Key Encipherment, Data Encipherment", key_usage.value - key_ident = cert.extensions.find {|ext| ext.oid == 'subjectKeyIdentifier' } + key_ident = cert.extensions.find {|ext| ext.oid == "subjectKeyIdentifier" } assert_equal 59, key_ident.value.length - assert_equal '5F:43:6E:F6:9A:8E:45:25:E9:22:E3:7D:37:5E:A4:D5:36:02:85:1B', + assert_equal "B1:1A:54:09:67:45:60:02:02:D7:CE:F4:1D:60:4A:89:DF:E7:58:D9", key_ident.value - assert_equal '', cert.issuer.to_s + assert_equal "", cert.issuer.to_s assert_equal name.to_s, cert.subject.to_s end def test_class_create_cert_self_signed subject = PUBLIC_CERT.subject - cert = @SEC.create_cert_self_signed subject, PRIVATE_KEY, 60 + cert = Gem::Security.create_cert_self_signed subject, PRIVATE_KEY, 60 - assert_equal '/CN=nobody/DC=example', cert.issuer.to_s + assert_equal "/CN=nobody/DC=example", cert.issuer.to_s assert_equal "sha256WithRSAEncryption", cert.signature_algorithm end def test_class_create_cert_email - email = 'nobody@example' + email = "nobody@example" name = PUBLIC_CERT.subject key = PRIVATE_KEY - cert = @SEC.create_cert_email email, key, 60 + cert = Gem::Security.create_cert_email email, key, 60 assert_kind_of OpenSSL::X509::Certificate, cert @@ -86,44 +82,71 @@ class TestGemSecurity < Gem::TestCase assert_equal 5, cert.extensions.length, cert.extensions.map {|e| e.to_a.first } - constraints = cert.extensions.find {|ext| ext.oid == 'subjectAltName' } - assert_equal 'email:nobody@example', constraints.value + constraints = cert.extensions.find {|ext| ext.oid == "subjectAltName" } + assert_equal "email:nobody@example", constraints.value - constraints = cert.extensions.find {|ext| ext.oid == 'basicConstraints' } - assert_equal 'CA:FALSE', constraints.value + constraints = cert.extensions.find {|ext| ext.oid == "basicConstraints" } + assert_equal "CA:FALSE", constraints.value - key_usage = cert.extensions.find {|ext| ext.oid == 'keyUsage' } - assert_equal 'Digital Signature, Key Encipherment, Data Encipherment', + key_usage = cert.extensions.find {|ext| ext.oid == "keyUsage" } + assert_equal "Digital Signature, Key Encipherment, Data Encipherment", key_usage.value - key_ident = cert.extensions.find {|ext| ext.oid == 'subjectKeyIdentifier' } + key_ident = cert.extensions.find {|ext| ext.oid == "subjectKeyIdentifier" } assert_equal 59, key_ident.value.length - assert_equal '5F:43:6E:F6:9A:8E:45:25:E9:22:E3:7D:37:5E:A4:D5:36:02:85:1B', + assert_equal "B1:1A:54:09:67:45:60:02:02:D7:CE:F4:1D:60:4A:89:DF:E7:58:D9", key_ident.value end def test_class_create_key - key = @SEC.create_key 1024 + key = Gem::Security.create_key "rsa" assert_kind_of OpenSSL::PKey::RSA, key end + def test_class_create_key_downcases + key = Gem::Security.create_key "DSA" + + assert_kind_of OpenSSL::PKey::DSA, key + end + + def test_class_create_key_raises_unknown_algorithm + e = assert_raise Gem::Security::Exception do + Gem::Security.create_key "NOT_RSA" + end + + assert_equal "NOT_RSA algorithm not found. RSA, DSA, and EC algorithms are supported.", + e.message + end + + def test_class_get_public_key_rsa + pkey_pem = PRIVATE_KEY.public_key.to_pem + + assert_equal pkey_pem, Gem::Security.get_public_key(PRIVATE_KEY).to_pem + end + + def test_class_get_public_key_ec + pkey = Gem::Security.get_public_key(EC_KEY) + + assert_respond_to pkey, :to_pem + end + def test_class_email_to_name - assert_equal '/CN=nobody/DC=example', - @SEC.email_to_name('nobody@example').to_s + assert_equal "/CN=nobody/DC=example", + Gem::Security.email_to_name("nobody@example").to_s - assert_equal '/CN=nobody/DC=example/DC=com', - @SEC.email_to_name('nobody@example.com').to_s + assert_equal "/CN=nobody/DC=example/DC=com", + Gem::Security.email_to_name("nobody@example.com").to_s - assert_equal '/CN=no.body/DC=example', - @SEC.email_to_name('no.body@example').to_s + assert_equal "/CN=no.body/DC=example", + Gem::Security.email_to_name("no.body@example").to_s - assert_equal '/CN=no_body/DC=example', - @SEC.email_to_name('no+body@example').to_s + assert_equal "/CN=no_body/DC=example", + Gem::Security.email_to_name("no+body@example").to_s end def test_class_re_sign - assert_equal "sha1WithRSAEncryption", EXPIRED_CERT.signature_algorithm + assert_equal "sha256WithRSAEncryption", EXPIRED_CERT.signature_algorithm re_signed = Gem::Security.re_sign EXPIRED_CERT, PRIVATE_KEY, 60 assert_in_delta Time.now, re_signed.not_before, 10 @@ -140,10 +163,10 @@ class TestGemSecurity < Gem::TestCase end child_alt_name = CHILD_CERT.extensions.find do |extension| - extension.oid == 'subjectAltName' + extension.oid == "subjectAltName" end - assert_equal "#{child_alt_name.value} is not self-signed, contact " + + assert_equal "#{child_alt_name.value} is not self-signed, contact " \ "#{ALTERNATE_CERT.issuer} to obtain a valid certificate", e.message end @@ -154,21 +177,21 @@ class TestGemSecurity < Gem::TestCase end assert_equal "incorrect signing key for re-signing " + - "#{ALTERNATE_CERT.subject}", + ALTERNATE_CERT.subject.to_s, e.message end def test_class_reset - trust_dir = @SEC.trust_dir + trust_dir = Gem::Security.trust_dir - @SEC.reset + Gem::Security.reset - refute_equal trust_dir, @SEC.trust_dir + refute_equal trust_dir, Gem::Security.trust_dir end def test_class_sign issuer = PUBLIC_CERT.subject - signee = OpenSSL::X509::Name.parse "/CN=signee/DC=example" + signee = OpenSSL::X509::Name.new([["CN", "signee"], ["DC", "example"]]) key = PRIVATE_KEY cert = OpenSSL::X509::Certificate.new @@ -177,7 +200,7 @@ class TestGemSecurity < Gem::TestCase cert.subject = signee cert.public_key = key.public_key - signed = @SEC.sign cert, key, PUBLIC_CERT, 60 + signed = Gem::Security.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 @@ -189,20 +212,20 @@ class TestGemSecurity < Gem::TestCase 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 == "issuerAltName" } + assert_equal "email:nobody@example", constraints.value, "issuerAltName" - constraints = signed.extensions.find {|ext| ext.oid == 'basicConstraints' } - assert_equal 'CA:FALSE', constraints.value + 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 = 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' } + signed.extensions.find {|ext| ext.oid == "subjectKeyIdentifier" } assert_equal 59, key_ident.value.length - assert_equal '5F:43:6E:F6:9A:8E:45:25:E9:22:E3:7D:37:5E:A4:D5:36:02:85:1B', + assert_equal "B1:1A:54:09:67:45:60:02:02:D7:CE:F4:1D:60:4A:89:DF:E7:58:D9", key_ident.value assert signed.verify key @@ -212,9 +235,9 @@ class TestGemSecurity < Gem::TestCase issuer = PUBLIC_CERT.subject signee = OpenSSL::X509::Name.parse "/CN=signee/DC=example" - cert = @SEC.create_cert_email 'signee@example', PRIVATE_KEY + cert = Gem::Security.create_cert_email "signee@example", PRIVATE_KEY - signed = @SEC.sign cert, PRIVATE_KEY, PUBLIC_CERT, 60 + signed = Gem::Security.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 @@ -228,42 +251,42 @@ class TestGemSecurity < Gem::TestCase 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 == "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 == "subjectAltName" } + assert_equal "email:signee@example", constraints.value, "subjectAltName" - constraints = signed.extensions.find {|ext| ext.oid == 'basicConstraints' } - assert_equal 'CA:FALSE', constraints.value + 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 = 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' } + signed.extensions.find {|ext| ext.oid == "subjectKeyIdentifier" } assert_equal 59, key_ident.value.length - assert_equal '5F:43:6E:F6:9A:8E:45:25:E9:22:E3:7D:37:5E:A4:D5:36:02:85:1B', + assert_equal "B1:1A:54:09:67:45:60:02:02:D7:CE:F4:1D:60:4A:89:DF:E7:58:D9", key_ident.value assert signed.verify PUBLIC_KEY end def test_class_trust_dir - trust_dir = @SEC.trust_dir + trust_dir = Gem::Security.trust_dir - expected = File.join Gem.user_home, '.gem/trust' + expected = File.join Gem.user_home, ".gem/trust" assert_equal expected, trust_dir.dir end def test_class_write - key = @SEC.create_key 1024 + key = Gem::Security.create_key "rsa" - path = File.join @tempdir, 'test-private_key.pem' + path = File.join @tempdir, "test-private_key.pem" - @SEC.write key, path + Gem::Security.write key, path assert_path_exist path @@ -273,13 +296,13 @@ class TestGemSecurity < Gem::TestCase end def test_class_write_encrypted - key = @SEC.create_key 1024 + key = Gem::Security.create_key "rsa" - path = File.join @tempdir, 'test-private_encrypted_key.pem' + path = File.join @tempdir, "test-private_encrypted_key.pem" - passphrase = 'It should be long.' + passphrase = "It should be long." - @SEC.write key, path, 0600, passphrase + Gem::Security.write key, path, 0o600, passphrase assert_path_exist path @@ -289,15 +312,15 @@ class TestGemSecurity < Gem::TestCase end def test_class_write_encrypted_cipher - key = @SEC.create_key 1024 + key = Gem::Security.create_key "rsa" - path = File.join @tempdir, 'test-private_encrypted__with_non_default_cipher_key.pem' + path = File.join @tempdir, "test-private_encrypted__with_non_default_cipher_key.pem" - passphrase = 'It should be long.' + passphrase = "It should be long." - cipher = OpenSSL::Cipher.new 'AES-192-CBC' + cipher = OpenSSL::Cipher.new "AES-192-CBC" - @SEC.write key, path, 0600, passphrase, cipher + Gem::Security.write key, path, 0o600, passphrase, cipher assert_path_exist path diff --git a/test/rubygems/test_gem_security_policy.rb b/test/rubygems/test_gem_security_policy.rb index a85791c918..2f4fb1ce28 100644 --- a/test/rubygems/test_gem_security_policy.rb +++ b/test/rubygems/test_gem_security_policy.rb @@ -1,39 +1,39 @@ # frozen_string_literal: true -require 'rubygems/test_case' +require_relative "helper" unless Gem::HAVE_OPENSSL - warn 'Skipping Gem::Security::Policy tests. openssl not found.' + warn "Skipping Gem::Security::Policy tests. openssl not found." end class TestGemSecurityPolicy < Gem::TestCase - ALTERNATE_KEY = load_key 'alternate' - INVALID_KEY = load_key 'invalid' - CHILD_KEY = load_key 'child' - GRANDCHILD_KEY = load_key 'grandchild' - INVALIDCHILD_KEY = load_key 'invalidchild' - - ALTERNATE_CERT = load_cert 'alternate' - CA_CERT = load_cert 'ca' - CHILD_CERT = load_cert 'child' - EXPIRED_CERT = load_cert 'expired' - FUTURE_CERT = load_cert 'future' - GRANDCHILD_CERT = load_cert 'grandchild' - INVALIDCHILD_CERT = load_cert 'invalidchild' - INVALID_ISSUER_CERT = load_cert 'invalid_issuer' - INVALID_SIGNER_CERT = load_cert 'invalid_signer' - WRONG_KEY_CERT = load_cert 'wrong_key' + ALTERNATE_KEY = load_key "alternate" + INVALID_KEY = load_key "invalid" + CHILD_KEY = load_key "child" + GRANDCHILD_KEY = load_key "grandchild" + INVALIDCHILD_KEY = load_key "invalidchild" + + ALTERNATE_CERT = load_cert "alternate" + CA_CERT = load_cert "ca" + CHILD_CERT = load_cert "child" + EXPIRED_CERT = load_cert "expired" + FUTURE_CERT = load_cert "future" + GRANDCHILD_CERT = load_cert "grandchild" + INVALIDCHILD_CERT = load_cert "invalidchild" + INVALID_ISSUER_CERT = load_cert "invalid_issuer" + INVALID_SIGNER_CERT = load_cert "invalid_signer" + WRONG_KEY_CERT = load_cert "wrong_key" def setup super - @spec = quick_gem 'a' do |s| - s.description = 'π' + @spec = quick_gem "a" do |s| + s.description = "π" s.files = %w[lib/code.rb] end @digest = OpenSSL::Digest.new Gem::Security::DIGEST_NAME - @trust_dir = Gem::Security.trust_dir.dir # HACK use the object + @trust_dir = Gem::Security.trust_dir.dir # HACK: use the object @no = Gem::Security::NoSecurity @almost_no = Gem::Security::AlmostNoSecurity @@ -42,28 +42,28 @@ class TestGemSecurityPolicy < Gem::TestCase @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 + "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 + "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' + data = digest "hello" signature = sign data @@ -71,17 +71,17 @@ class TestGemSecurityPolicy < Gem::TestCase end def test_check_data_invalid - data = digest 'hello' + data = digest "hello" signature = sign data - invalid = digest 'hello!' + invalid = digest "hello!" e = assert_raise Gem::Security::Exception do @almost_no.check_data PUBLIC_KEY, @digest, signature, invalid end - assert_equal 'invalid signature', e.message + assert_equal "invalid signature", e.message end def test_check_chain @@ -95,7 +95,7 @@ class TestGemSecurityPolicy < Gem::TestCase @chain.check_chain [], Time.now end - assert_equal 'empty signing chain', e.message + assert_equal "empty signing chain", e.message end def test_check_chain_invalid @@ -105,8 +105,8 @@ class TestGemSecurityPolicy < Gem::TestCase @chain.check_chain chain, Time.now end - assert_equal "invalid signing chain: " + - "certificate #{INVALIDCHILD_CERT.subject} " + + assert_equal "invalid signing chain: " \ + "certificate #{INVALIDCHILD_CERT.subject} " \ "was not issued by #{CHILD_CERT.subject}", e.message end @@ -115,7 +115,7 @@ class TestGemSecurityPolicy < Gem::TestCase @chain.check_chain nil, Time.now end - assert_equal 'missing signing chain', e.message + assert_equal "missing signing chain", e.message end def test_check_cert @@ -127,7 +127,7 @@ class TestGemSecurityPolicy < Gem::TestCase @low.check_cert EXPIRED_CERT, nil, Time.now end - assert_equal "certificate #{EXPIRED_CERT.subject} " + + assert_equal "certificate #{EXPIRED_CERT.subject} " \ "not valid after #{EXPIRED_CERT.not_after}", e.message end @@ -137,7 +137,7 @@ class TestGemSecurityPolicy < Gem::TestCase @low.check_cert FUTURE_CERT, nil, Time.now end - assert_equal "certificate #{FUTURE_CERT.subject} " + + assert_equal "certificate #{FUTURE_CERT.subject} " \ "not valid before #{FUTURE_CERT.not_before}", e.message end @@ -147,7 +147,7 @@ class TestGemSecurityPolicy < Gem::TestCase @low.check_cert INVALID_ISSUER_CERT, PUBLIC_CERT, Time.now end - assert_equal "certificate #{INVALID_ISSUER_CERT.subject} " + + assert_equal "certificate #{INVALID_ISSUER_CERT.subject} " \ "was not issued by #{PUBLIC_CERT.subject}", e.message end @@ -161,7 +161,7 @@ class TestGemSecurityPolicy < Gem::TestCase @high.check_cert(nil, nil, Time.now) end - assert_equal 'missing signing certificate', e.message + assert_equal "missing signing certificate", e.message end def test_check_key @@ -175,7 +175,7 @@ class TestGemSecurityPolicy < Gem::TestCase @high.check_key(nil, nil) end - assert_equal 'missing key or signature', e.message + assert_equal "missing key or signature", e.message end def test_check_key_wrong_key @@ -183,7 +183,7 @@ class TestGemSecurityPolicy < Gem::TestCase @almost_no.check_key(PUBLIC_CERT, ALTERNATE_KEY) end - assert_equal "certificate #{PUBLIC_CERT.subject} " + + assert_equal "certificate #{PUBLIC_CERT.subject} " \ "does not match the signing key", e.message end @@ -198,7 +198,7 @@ class TestGemSecurityPolicy < Gem::TestCase @chain.check_root [], Time.now end - assert_equal 'missing root certificate', e.message + assert_equal "missing root certificate", e.message end def test_check_root_invalid_signer @@ -208,7 +208,7 @@ class TestGemSecurityPolicy < Gem::TestCase @chain.check_root chain, Time.now end - assert_equal "certificate #{INVALID_SIGNER_CERT.subject} " + + assert_equal "certificate #{INVALID_SIGNER_CERT.subject} " \ "was not issued by #{INVALID_SIGNER_CERT.issuer}", e.message end @@ -220,7 +220,7 @@ class TestGemSecurityPolicy < Gem::TestCase @chain.check_root chain, Time.now end - assert_equal "root certificate #{INVALID_ISSUER_CERT.subject} " + + assert_equal "root certificate #{INVALID_ISSUER_CERT.subject} " \ "is not self-signed (issuer #{INVALID_ISSUER_CERT.issuer})", e.message end @@ -230,7 +230,7 @@ class TestGemSecurityPolicy < Gem::TestCase @chain.check_root nil, Time.now end - assert_equal 'missing signing chain', e.message + assert_equal "missing signing chain", e.message end def test_check_trust @@ -250,7 +250,7 @@ class TestGemSecurityPolicy < Gem::TestCase @chain.check_trust [], @digest, @trust_dir end - assert_equal 'missing root certificate', e.message + assert_equal "missing root certificate", e.message end def test_check_trust_mismatch @@ -260,7 +260,7 @@ class TestGemSecurityPolicy < Gem::TestCase @high.check_trust [WRONG_KEY_CERT], @digest, @trust_dir end - assert_equal "trusted root certificate #{PUBLIC_CERT.subject} checksum " + + assert_equal "trusted root certificate #{PUBLIC_CERT.subject} checksum " \ "does not match signing root certificate checksum", e.message end @@ -269,7 +269,7 @@ class TestGemSecurityPolicy < Gem::TestCase @chain.check_trust nil, @digest, @trust_dir end - assert_equal 'missing signing chain', e.message + assert_equal "missing signing chain", e.message end def test_check_trust_no_trust @@ -285,13 +285,13 @@ class TestGemSecurityPolicy < Gem::TestCase @high.check_trust [PUBLIC_CERT, CHILD_CERT], @digest, @trust_dir end - assert_equal "root cert #{PUBLIC_CERT.subject} is not trusted " + + assert_equal "root cert #{PUBLIC_CERT.subject} is not trusted " \ "(root of signing cert #{CHILD_CERT.subject})", e.message end def test_subject - assert_equal 'email:nobody@example', @no.subject(PUBLIC_CERT) - assert_equal '/C=JP/ST=Tokyo/O=RubyGemsTest/CN=CA', @no.subject(CA_CERT) + assert_equal "email:nobody@example", @no.subject(PUBLIC_CERT) + assert_equal "/C=JP/ST=Tokyo/O=RubyGemsTest/CN=CA", @no.subject(CA_CERT) end def test_verify @@ -319,7 +319,7 @@ class TestGemSecurityPolicy < Gem::TestCase @almost_no.verify [PUBLIC_CERT], nil, {}, signatures end - assert_equal 'no digests provided (probable bug)', e.message + assert_equal "no digests provided (probable bug)", e.message end def test_verify_no_digests_no_security @@ -331,7 +331,7 @@ class TestGemSecurityPolicy < Gem::TestCase @no.verify [PUBLIC_CERT], nil, {}, signatures end - assert_equal 'missing digest for 0', e.message + assert_equal "missing digest for 0", e.message end def test_verify_no_signatures @@ -340,7 +340,7 @@ class TestGemSecurityPolicy < Gem::TestCase digests, = dummy_signatures use_ui @ui do - @no.verify [PUBLIC_CERT], nil, digests, {}, 'some_gem' + @no.verify [PUBLIC_CERT], nil, digests, {}, "some_gem" end assert_match "WARNING: some_gem is not signed\n", @ui.error @@ -354,7 +354,7 @@ class TestGemSecurityPolicy < Gem::TestCase Gem::Security.trust_dir.trust_cert PUBLIC_CERT use_ui @ui do - @no.verify [PUBLIC_CERT], nil, {}, {}, 'some_gem' + @no.verify [PUBLIC_CERT], nil, {}, {}, "some_gem" end assert_empty @ui.output @@ -366,7 +366,7 @@ class TestGemSecurityPolicy < Gem::TestCase digests, signatures = dummy_signatures - data = digest 'goodbye' + data = digest "goodbye" signatures[1] = PRIVATE_KEY.sign @digest.new, data.digest @@ -374,14 +374,14 @@ class TestGemSecurityPolicy < Gem::TestCase @almost_no.verify [PUBLIC_CERT], nil, digests, signatures end - assert_equal 'missing digest for 1', e.message + assert_equal "missing digest for 1", e.message end def test_verify_no_trust digests, signatures = dummy_signatures use_ui @ui do - @low.verify [PUBLIC_CERT], nil, digests, signatures, 'some_gem' + @low.verify [PUBLIC_CERT], nil, digests, signatures, "some_gem" end assert_equal "WARNING: email:nobody@example is not trusted for some_gem\n", @@ -395,18 +395,18 @@ class TestGemSecurityPolicy < Gem::TestCase def test_verify_wrong_digest_type Gem::Security.trust_dir.trust_cert PUBLIC_CERT - data = OpenSSL::Digest.new('SHA512') - data << 'hello' + data = OpenSSL::Digest.new("SHA512") + data << "hello" - digests = { 'SHA512' => { 0 => data } } - signature = PRIVATE_KEY.sign 'sha512', data.digest + digests = { "SHA512" => { 0 => data } } + signature = PRIVATE_KEY.sign "sha512", data.digest signatures = { 0 => signature } e = assert_raise Gem::Security::Exception do @almost_no.verify [PUBLIC_CERT], nil, digests, signatures end - assert_equal 'no digests provided (probable bug)', e.message + assert_equal "no digests provided (probable bug)", e.message end def test_verify_signatures_chain @@ -448,17 +448,19 @@ class TestGemSecurityPolicy < Gem::TestCase metadata_gz = Gem::Util.gzip @spec.to_yaml - package = Gem::Package.new 'nonexistent.gem' + package = Gem::Package.new "nonexistent.gem" package.checksums[Gem::Security::DIGEST_NAME] = {} s = StringIO.new metadata_gz - def s.full_name() 'metadata.gz' end + def s.full_name + "metadata.gz" + end digests = package.digest s - metadata_gz_digest = digests[Gem::Security::DIGEST_NAME]['metadata.gz'] + metadata_gz_digest = digests[Gem::Security::DIGEST_NAME]["metadata.gz"] signatures = {} - signatures['metadata.gz'] = + signatures["metadata.gz"] = PRIVATE_KEY.sign @digest.new, metadata_gz_digest.digest assert @high.verify_signatures @spec, digests, signatures @@ -471,26 +473,28 @@ class TestGemSecurityPolicy < Gem::TestCase metadata_gz = Gem::Util.gzip @spec.to_yaml - package = Gem::Package.new 'nonexistent.gem' + package = Gem::Package.new "nonexistent.gem" package.checksums[Gem::Security::DIGEST_NAME] = {} s = StringIO.new metadata_gz - def s.full_name() 'metadata.gz' end + def s.full_name + "metadata.gz" + end digests = package.digest s - digests[Gem::Security::DIGEST_NAME]['data.tar.gz'] = @digest.hexdigest 'hello' + digests[Gem::Security::DIGEST_NAME]["data.tar.gz"] = @digest.hexdigest "hello" - metadata_gz_digest = digests[Gem::Security::DIGEST_NAME]['metadata.gz'] + metadata_gz_digest = digests[Gem::Security::DIGEST_NAME]["metadata.gz"] signatures = {} - signatures['metadata.gz'] = + signatures["metadata.gz"] = PRIVATE_KEY.sign @digest.new, metadata_gz_digest.digest e = assert_raise Gem::Security::Exception do @high.verify_signatures @spec, digests, signatures end - assert_equal 'missing signature for data.tar.gz', e.message + assert_equal "missing signature for data.tar.gz", e.message end def test_verify_signatures_none @@ -500,14 +504,16 @@ class TestGemSecurityPolicy < Gem::TestCase metadata_gz = Gem::Util.gzip @spec.to_yaml - package = Gem::Package.new 'nonexistent.gem' + package = Gem::Package.new "nonexistent.gem" package.checksums[Gem::Security::DIGEST_NAME] = {} s = StringIO.new metadata_gz - def s.full_name() 'metadata.gz' end + def s.full_name + "metadata.gz" + end digests = package.digest s - digests[Gem::Security::DIGEST_NAME]['data.tar.gz'] = @digest.hexdigest 'hello' + digests[Gem::Security::DIGEST_NAME]["data.tar.gz"] = @digest.hexdigest "hello" assert_raise Gem::Security::Exception do @high.verify_signatures @spec, digests, {} @@ -525,11 +531,11 @@ class TestGemSecurityPolicy < Gem::TestCase end def dummy_signatures(key = PRIVATE_KEY) - data = digest 'hello' + data = digest "hello" digests = { Gem::Security::DIGEST_NAME => { 0 => data } } signatures = { 0 => sign(data, key) } - return digests, signatures + [digests, signatures] end end if Gem::HAVE_OPENSSL diff --git a/test/rubygems/test_gem_security_signer.rb b/test/rubygems/test_gem_security_signer.rb index 699ebea43f..f4799cbd46 100644 --- a/test/rubygems/test_gem_security_signer.rb +++ b/test/rubygems/test_gem_security_signer.rb @@ -1,18 +1,19 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" unless Gem::HAVE_OPENSSL - warn 'Skipping Gem::Security::Signer tests. openssl not found.' + warn "Skipping Gem::Security::Signer tests. openssl not found." end class TestGemSecuritySigner < Gem::TestCase - ALTERNATE_KEY = load_key 'alternate' - CHILD_KEY = load_key 'child' - GRANDCHILD_KEY = load_key 'grandchild' + 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' + CHILD_CERT = load_cert "child" + GRANDCHILD_CERT = load_cert "grandchild" + EXPIRED_CERT = load_cert "expired" def setup super @@ -36,36 +37,36 @@ class TestGemSecuritySigner < Gem::TestCase 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 } + assert_equal [PUBLIC_CERT, CHILD_CERT].map(&:to_pem), + signer.cert_chain.map(&:to_pem) end def test_initialize_cert_chain_invalid assert_raise OpenSSL::X509::CertificateError do - Gem::Security::Signer.new nil, ['garbage'] + 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 } + assert_equal [PUBLIC_CERT].map(&:to_pem), + signer.cert_chain.map(&:to_pem) end def test_initialize_default - FileUtils.mkdir_p File.join(Gem.user_home, '.gem') + FileUtils.mkdir_p File.join(Gem.user_home, ".gem") - private_key_path = File.join Gem.user_home, '.gem', 'gem-private_key.pem' + private_key_path = File.join Gem.user_home, ".gem", "gem-private_key.pem" Gem::Security.write PRIVATE_KEY, private_key_path - public_cert_path = File.join Gem.user_home, '.gem', 'gem-public_cert.pem' + public_cert_path = File.join Gem.user_home, ".gem", "gem-public_cert.pem" Gem::Security.write PUBLIC_CERT, public_cert_path signer = Gem::Security::Signer.new nil, nil assert_equal PRIVATE_KEY.to_pem, signer.key.to_pem - assert_equal [PUBLIC_CERT.to_pem], signer.cert_chain.map {|c| c.to_pem } + assert_equal [PUBLIC_CERT.to_pem], signer.cert_chain.map(&:to_pem) end def test_initialize_key_path @@ -87,7 +88,7 @@ class TestGemSecuritySigner < Gem::TestCase def test_extract_name signer = Gem::Security::Signer.new nil, nil - assert_equal 'child@example', signer.extract_name(CHILD_CERT) + assert_equal "child@example", signer.extract_name(CHILD_CERT) end def test_load_cert_chain @@ -99,7 +100,7 @@ class TestGemSecuritySigner < Gem::TestCase signer.load_cert_chain assert_equal [PUBLIC_CERT.to_pem, CHILD_CERT.to_pem], - signer.cert_chain.map {|c| c.to_pem } + signer.cert_chain.map(&:to_pem) end def test_load_cert_chain_broken @@ -111,49 +112,49 @@ class TestGemSecuritySigner < Gem::TestCase signer.load_cert_chain assert_equal [CHILD_CERT.to_pem, GRANDCHILD_CERT.to_pem], - signer.cert_chain.map {|c| c.to_pem } + signer.cert_chain.map(&:to_pem) end def test_sign signer = Gem::Security::Signer.new PRIVATE_KEY, [PUBLIC_CERT] - signature = signer.sign 'hello' + signature = signer.sign "hello" expected = <<-EXPECTED -cHze2sEfRysoUMCfGVAx/7o8jxj5liJJ2ptNxe2jf3l+EZvyjdqpXo9Ndzxx -6xLp2rxLG4K2//ip4aCH5Sh7hnia+F5u6iuLBETPlklPrmw5dnuKZxolz+vM -0O1aOZsQHcVzQoESTGjkms3KZk+gn3lg0sSBbAV5/LyDYoHCEjxlcA5D+Olb -rDmRyBMOnMS+q489OZ5Hr6B2YJJ3QbUwIZNhUeNmOxIBEYTrrKkZ92qkxbRN -qhlqFP4jR6zXFeyBCOr0KpTiWBNuxBFXDsxmhGyt2BOIjD6qmKn7RSIfYg/U -toqvglr0kdbknSRRjBVLK6tsgr07aLT9gNP7mTW2PA== +FmrCYxEXW3dgYYNMxPdS16VrdXT+d5nyXTVlRm64ZHSgMxMAaPtQJsVYv73m +DWHTzNnLhhINSpgBMLh5a4atM52yxVdkPUTgqIH+LeIPBXn8xaP5JLmfDcmI +tBpc/9DhS3v9iKCX40igAArFu7Gg3swbgQ61SP+U22LvG5nDQZQz3sudtsw3 +qKPykFVaYjrRwzvBdSdJ1PwlAsanSwcwS/GKPtmE/ykZ6X5XOx7wvCDL/zGy +B8khkB8hDKC6moCzebmUxCBmTmXD0Wjzon+bf4MOriVE3a0ySGRvpr1mKR2+ +9EaVo7pDJLEM487+xg1CAZHRhwshd6II00XEzG/jBQ== EXPECTED - assert_equal expected, [signature].pack('m') + assert_equal expected, [signature].pack("m") end def test_sign_expired signer = Gem::Security::Signer.new PRIVATE_KEY, [EXPIRED_CERT] e = assert_raise Gem::Security::Exception do - signer.sign 'hello' + signer.sign "hello" end assert_match "certificate /CN=nobody/DC=example not valid after 1970-01-01 00:00:00 UTC", e.message end def test_sign_expired_auto_update - skip if Gem.java_platform? - FileUtils.mkdir_p File.join(Gem.user_home, '.gem'), :mode => 0700 + pend if Gem.java_platform? + FileUtils.mkdir_p File.join(Gem.user_home, ".gem"), mode: 0o700 - private_key_path = File.join(Gem.user_home, '.gem', 'gem-private_key.pem') + private_key_path = File.join(Gem.user_home, ".gem", "gem-private_key.pem") Gem::Security.write PRIVATE_KEY, private_key_path - cert_path = File.join Gem.user_home, '.gem', 'gem-public_cert.pem' + cert_path = File.join Gem.user_home, ".gem", "gem-public_cert.pem" Gem::Security.write EXPIRED_CERT, cert_path signer = Gem::Security::Signer.new PRIVATE_KEY, [EXPIRED_CERT] - signer.sign 'hello' + signer.sign "hello" cert = OpenSSL::X509::Certificate.new File.read cert_path @@ -163,14 +164,14 @@ toqvglr0kdbknSRRjBVLK6tsgr07aLT9gNP7mTW2PA== expiry = EXPIRED_CERT.not_after.strftime "%Y%m%d%H%M%S" expired_path = - File.join Gem.user_home, '.gem', "gem-public_cert.pem.expired.#{expiry}" + File.join Gem.user_home, ".gem", "gem-public_cert.pem.expired.#{expiry}" assert_path_exist expired_path assert_equal EXPIRED_CERT.to_pem, File.read(expired_path) end def test_sign_expired_auto_update_exists - FileUtils.mkdir_p File.join(Gem.user_home, '.gem'), :mode => 0700 + FileUtils.mkdir_p File.join(Gem.user_home, ".gem"), mode: 0o700 expiry = EXPIRED_CERT.not_after.strftime "%Y%m%d%H%M%S" expired_path = @@ -178,16 +179,16 @@ toqvglr0kdbknSRRjBVLK6tsgr07aLT9gNP7mTW2PA== Gem::Security.write EXPIRED_CERT, expired_path - private_key_path = File.join(Gem.user_home, 'gem-private_key.pem') + 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' + 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_raise Gem::Security::Exception do - signer.sign 'hello' + signer.sign "hello" end assert_match %r{certificate /CN=nobody/DC=example not valid}, e.message @@ -196,14 +197,14 @@ toqvglr0kdbknSRRjBVLK6tsgr07aLT9gNP7mTW2PA== def test_sign_no_key signer = Gem::Security::Signer.new nil, nil - assert_nil signer.sign 'stuff' + assert_nil signer.sign "stuff" end def test_sign_wrong_key signer = Gem::Security::Signer.new ALTERNATE_KEY, [PUBLIC_CERT] assert_raise Gem::Security::Exception do - signer.sign 'hello' + signer.sign "hello" end end @@ -211,7 +212,7 @@ toqvglr0kdbknSRRjBVLK6tsgr07aLT9gNP7mTW2PA== signer = Gem::Security::Signer.new ALTERNATE_KEY, [] assert_raise Gem::Security::Exception do - signer.sign 'hello' + signer.sign "hello" end end end if Gem::HAVE_OPENSSL diff --git a/test/rubygems/test_gem_security_trust_dir.rb b/test/rubygems/test_gem_security_trust_dir.rb index 6dc0997eaf..cfde8e9d48 100644 --- a/test/rubygems/test_gem_security_trust_dir.rb +++ b/test/rubygems/test_gem_security_trust_dir.rb @@ -1,17 +1,18 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" unless Gem::HAVE_OPENSSL - warn 'Skipping Gem::Security::TrustDir tests. openssl not found.' + warn "Skipping Gem::Security::TrustDir tests. openssl not found." end class TestGemSecurityTrustDir < Gem::TestCase - CHILD_CERT = load_cert 'child' + CHILD_CERT = load_cert "child" def setup super - @dest_dir = File.join @tempdir, 'trust' + @dest_dir = File.join @tempdir, "trust" @trust_dir = Gem::Security::TrustDir.new @dest_dir end @@ -55,9 +56,9 @@ class TestGemSecurityTrustDir < Gem::TestCase assert_path_exist trusted - mask = 0100600 & (~File.umask) + mask = 0o100600 & (~File.umask) - assert_equal mask, File.stat(trusted).mode unless win_platform? + assert_equal mask, File.stat(trusted).mode unless Gem.win_platform? assert_equal PUBLIC_CERT.to_pem, File.read(trusted) end @@ -69,10 +70,10 @@ class TestGemSecurityTrustDir < Gem::TestCase assert_path_exist @dest_dir - mask = 040700 & (~File.umask) - mask |= 0200000 if /aix/ =~ RUBY_PLATFORM + mask = 0o040700 & (~File.umask) + mask |= 0o200000 if RUBY_PLATFORM.include?("aix") - assert_equal mask, File.stat(@dest_dir).mode unless win_platform? + assert_equal mask, File.stat(@dest_dir).mode unless Gem.win_platform? end def test_verify_file @@ -86,13 +87,13 @@ class TestGemSecurityTrustDir < Gem::TestCase end def test_verify_wrong_permissions - FileUtils.mkdir_p @dest_dir, :mode => 0777 + FileUtils.mkdir_p @dest_dir, mode: 0o777 @trust_dir.verify - mask = 040700 & (~File.umask) - mask |= 0200000 if /aix/ =~ RUBY_PLATFORM + mask = 0o40700 & (~File.umask) + mask |= 0o200000 if RUBY_PLATFORM.include?("aix") - assert_equal mask, File.stat(@dest_dir).mode unless win_platform? + assert_equal mask, File.stat(@dest_dir).mode unless Gem.win_platform? end end if Gem::HAVE_OPENSSL diff --git a/test/rubygems/test_gem_server.rb b/test/rubygems/test_gem_server.rb deleted file mode 100644 index aeb7fa2ab9..0000000000 --- a/test/rubygems/test_gem_server.rb +++ /dev/null @@ -1,608 +0,0 @@ -# frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/server' -require 'stringio' - -class Gem::Server - attr_reader :server -end - -class TestGemServer < Gem::TestCase - def process_based_port - 0 - end - - def setup - super - - @a1 = quick_gem 'a', '1' - @a2 = quick_gem 'a', '2' - @a3_p = quick_gem 'a', '3.a' - - @server = Gem::Server.new Gem.dir, process_based_port, false - @req = WEBrick::HTTPRequest.new :Logger => nil - @res = WEBrick::HTTPResponse.new :HTTPVersion => '1.0' - end - - def test_doc_root_3 - orig_rdoc_version = Gem::RDoc.rdoc_version - Gem::RDoc.instance_variable_set :@rdoc_version, Gem::Version.new('3.12') - - assert_equal '/doc_root/X-1/rdoc/index.html', @server.doc_root('X-1') - - ensure - Gem::RDoc.instance_variable_set :@rdoc_version, orig_rdoc_version - end - - def test_doc_root_4 - orig_rdoc_version = Gem::RDoc.rdoc_version - Gem::RDoc.instance_variable_set :@rdoc_version, Gem::Version.new('4.0') - - assert_equal '/doc_root/X-1/', @server.doc_root('X-1') - - ensure - Gem::RDoc.instance_variable_set :@rdoc_version, orig_rdoc_version - end - - def test_have_rdoc_4_plus_eh - orig_rdoc_version = Gem::RDoc.rdoc_version - Gem::RDoc.instance_variable_set(:@rdoc_version, Gem::Version.new('4.0')) - - server = Gem::Server.new Gem.dir, 0, false - assert server.have_rdoc_4_plus? - - Gem::RDoc.instance_variable_set :@rdoc_version, Gem::Version.new('3.12') - - server = Gem::Server.new Gem.dir, 0, false - refute server.have_rdoc_4_plus? - - Gem::RDoc.instance_variable_set(:@rdoc_version, - Gem::Version.new('4.0.0.preview2')) - - server = Gem::Server.new Gem.dir, 0, false - assert server.have_rdoc_4_plus? - ensure - Gem::RDoc.instance_variable_set :@rdoc_version, orig_rdoc_version - end - - def test_spec_dirs - s = Gem::Server.new Gem.dir, process_based_port, false - - assert_equal [File.join(Gem.dir, 'specifications')], s.spec_dirs - - s = Gem::Server.new [Gem.dir, Gem.dir], process_based_port, false - - assert_equal [File.join(Gem.dir, 'specifications'), - File.join(Gem.dir, 'specifications')], s.spec_dirs - end - - def test_latest_specs - data = StringIO.new "GET /latest_specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n" - @req.parse data - - Gem::Deprecate.skip_during do - @server.latest_specs @req, @res - end - - assert_equal 200, @res.status, @res.body - assert_match %r{ \d\d:\d\d:\d\d }, @res['date'] - assert_equal 'application/octet-stream', @res['content-type'] - assert_equal [['a', Gem::Version.new(2), Gem::Platform::RUBY]], - Marshal.load(@res.body) - end - - def test_latest_specs_gemdirs - data = StringIO.new "GET /latest_specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n" - dir = "#{@gemhome}2" - - spec = util_spec 'z', 9 - - specs_dir = File.join dir, 'specifications' - FileUtils.mkdir_p specs_dir - - File.open File.join(specs_dir, spec.spec_name), 'w' do |io| - io.write spec.to_ruby - end - - server = Gem::Server.new dir, process_based_port, false - - @req.parse data - - server.latest_specs @req, @res - - assert_equal 200, @res.status - - assert_equal [['z', v(9), Gem::Platform::RUBY]], Marshal.load(@res.body) - end - - def test_latest_specs_gz - data = StringIO.new "GET /latest_specs.#{Gem.marshal_version}.gz HTTP/1.0\r\n\r\n" - @req.parse data - - Gem::Deprecate.skip_during do - @server.latest_specs @req, @res - end - - assert_equal 200, @res.status, @res.body - assert_match %r{ \d\d:\d\d:\d\d }, @res['date'] - assert_equal 'application/x-gzip', @res['content-type'] - assert_equal [['a', Gem::Version.new(2), Gem::Platform::RUBY]], - Marshal.load(Gem::Util.gunzip(@res.body)) - end - - def test_listen - util_listen - - capture_output do - @server.listen - end - - assert_equal 1, @server.server.listeners.length - end - - def test_listen_addresses - util_listen - - capture_output do - @server.listen %w[a b] - end - - assert_equal 2, @server.server.listeners.length - end - - def test_prerelease_specs - data = StringIO.new "GET /prerelease_specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n" - @req.parse data - - Gem::Deprecate.skip_during do - @server.prerelease_specs @req, @res - end - - assert_equal 200, @res.status, @res.body - assert_match %r{ \d\d:\d\d:\d\d }, @res['date'] - assert_equal 'application/octet-stream', @res['content-type'] - assert_equal [['a', v('3.a'), Gem::Platform::RUBY]], - Marshal.load(@res.body) - end - - def test_prerelease_specs_gz - data = StringIO.new "GET /prerelease_specs.#{Gem.marshal_version}.gz HTTP/1.0\r\n\r\n" - @req.parse data - - Gem::Deprecate.skip_during do - @server.prerelease_specs @req, @res - end - - assert_equal 200, @res.status, @res.body - assert_match %r{ \d\d:\d\d:\d\d }, @res['date'] - assert_equal 'application/x-gzip', @res['content-type'] - assert_equal [['a', v('3.a'), Gem::Platform::RUBY]], - Marshal.load(Gem::Util.gunzip(@res.body)) - end - - def test_quick_gemdirs - data = StringIO.new "GET /quick/Marshal.4.8/z-9.gemspec.rz HTTP/1.0\r\n\r\n" - dir = "#{@gemhome}2" - - server = Gem::Server.new dir, process_based_port, false - - @req.parse data - - server.quick @req, @res - - assert_equal 404, @res.status - - spec = util_spec 'z', 9 - - specs_dir = File.join dir, 'specifications' - - FileUtils.mkdir_p specs_dir - - File.open File.join(specs_dir, spec.spec_name), 'w' do |io| - io.write spec.to_ruby - end - - data.rewind - - req = WEBrick::HTTPRequest.new :Logger => nil - res = WEBrick::HTTPResponse.new :HTTPVersion => '1.0' - req.parse data - - server.quick req, res - - assert_equal 200, res.status - end - - def test_quick_missing - data = StringIO.new "GET /quick/Marshal.4.8/z-9.gemspec.rz HTTP/1.0\r\n\r\n" - @req.parse data - - @server.quick @req, @res - - assert_equal 404, @res.status, @res.body - assert_match %r{ \d\d:\d\d:\d\d }, @res['date'] - assert_equal 'text/plain', @res['content-type'] - assert_equal 'No gems found matching "z-9"', @res.body - assert_equal 404, @res.status - end - - def test_quick_marshal_a_1_gemspec_rz - data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-1.gemspec.rz HTTP/1.0\r\n\r\n" - @req.parse data - - @server.quick @req, @res - - assert_equal 200, @res.status, @res.body - assert @res['date'] - assert_equal 'application/x-deflate', @res['content-type'] - - spec = Marshal.load Gem::Util.inflate(@res.body) - assert_equal 'a', spec.name - assert_equal Gem::Version.new(1), spec.version - end - - def test_quick_marshal_a_1_mswin32_gemspec_rz - quick_gem 'a', '1' do |s| - s.platform = Gem::Platform.local - end - - data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-1-#{Gem::Platform.local}.gemspec.rz HTTP/1.0\r\n\r\n" - @req.parse data - - @server.quick @req, @res - - assert_equal 200, @res.status, @res.body - assert @res['date'] - assert_equal 'application/x-deflate', @res['content-type'] - - spec = Marshal.load Gem::Util.inflate(@res.body) - assert_equal 'a', spec.name - assert_equal Gem::Version.new(1), spec.version - assert_equal Gem::Platform.local, spec.platform - end - - def test_quick_marshal_a_3_a_gemspec_rz - data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-3.a.gemspec.rz HTTP/1.0\r\n\r\n" - @req.parse data - - @server.quick @req, @res - - assert_equal 200, @res.status, @res.body - assert @res['date'] - assert_equal 'application/x-deflate', @res['content-type'] - - spec = Marshal.load Gem::Util.inflate(@res.body) - assert_equal 'a', spec.name - assert_equal v('3.a'), spec.version - end - - def test_quick_marshal_a_b_3_a_gemspec_rz - quick_gem 'a-b', '3.a' - - data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-b-3.a.gemspec.rz HTTP/1.0\r\n\r\n" - @req.parse data - - @server.quick @req, @res - - assert_equal 200, @res.status, @res.body - assert @res['date'] - assert_equal 'application/x-deflate', @res['content-type'] - - spec = Marshal.load Gem::Util.inflate(@res.body) - assert_equal 'a-b', spec.name - assert_equal v('3.a'), spec.version - end - - def test_quick_marshal_a_b_1_3_a_gemspec_rz - quick_gem 'a-b-1', '3.a' - - data = StringIO.new "GET /quick/Marshal.#{Gem.marshal_version}/a-b-1-3.a.gemspec.rz HTTP/1.0\r\n\r\n" - @req.parse data - - @server.quick @req, @res - - assert_equal 200, @res.status, @res.body - assert @res['date'] - assert_equal 'application/x-deflate', @res['content-type'] - - spec = Marshal.load Gem::Util.inflate(@res.body) - assert_equal 'a-b-1', spec.name - assert_equal v('3.a'), spec.version - end - - def test_rdoc - data = StringIO.new "GET /rdoc?q=a HTTP/1.0\r\n\r\n" - @req.parse data - - @server.rdoc @req, @res - - assert_equal 200, @res.status, @res.body - assert_match %r{No documentation found}, @res.body - assert_equal 'text/html', @res['content-type'] - end - - def test_root - data = StringIO.new "GET / HTTP/1.0\r\n\r\n" - @req.parse data - - @server.root @req, @res - - assert_equal 200, @res.status, @res.body - assert_match %r{ \d\d:\d\d:\d\d }, @res['date'] - assert_equal 'text/html', @res['content-type'] - end - - def test_root_gemdirs - data = StringIO.new "GET / HTTP/1.0\r\n\r\n" - dir = "#{@gemhome}2" - - spec = util_spec 'z', 9 - - specs_dir = File.join dir, 'specifications' - FileUtils.mkdir_p specs_dir - - File.open File.join(specs_dir, spec.spec_name), 'w' do |io| - io.write spec.to_ruby - end - - server = Gem::Server.new dir, process_based_port, false - - @req.parse data - - server.root @req, @res - - assert_equal 200, @res.status - assert_match 'z 9', @res.body - end - - def test_xss_homepage_fix_289313 - data = StringIO.new "GET / HTTP/1.0\r\n\r\n" - dir = "#{@gemhome}2" - - spec = util_spec 'xsshomepagegem', 1 - spec.homepage = "javascript:confirm(document.domain)" - - specs_dir = File.join dir, 'specifications' - FileUtils.mkdir_p specs_dir - - File.open File.join(specs_dir, spec.spec_name), 'w' do |io| - io.write spec.to_ruby - end - - server = Gem::Server.new dir, process_based_port, false - - @req.parse data - - server.root @req, @res - - assert_equal 200, @res.status - assert_match 'xsshomepagegem 1', @res.body - - # This verifies that the homepage for this spec is not displayed and is set to ".", because it's not a - # valid HTTP/HTTPS URL and could be unsafe in an HTML context. We would prefer to throw an exception here, - # but spec.homepage is currently free form and not currently required to be a URL, this behavior may be - # validated in future versions of Gem::Specification. - # - # There are two variant we're checking here, one where rdoc is not present, and one where rdoc is present in the same regex: - # - # Variant #1 - rdoc not installed - # - # <b>xsshomepagegem 1</b> - # - # - # <span title="rdoc not installed">[rdoc]</span> - # - # - # - # <a href="." title=".">[www]</a> - # - # Variant #2 - rdoc installed - # - # <b>xsshomepagegem 1</b> - # - # - # <a href="\/doc_root\/xsshomepagegem-1\/">\[rdoc\]<\/a> - # - # - # - # <a href="." title=".">[www]</a> - regex_match = /xsshomepagegem 1<\/b>\s+(<span title="rdoc not installed">\[rdoc\]<\/span>|<a href="\/doc_root\/xsshomepagegem-1\/">\[rdoc\]<\/a>)\s+<a href="\." title="\.">\[www\]<\/a>/ - assert_match regex_match, @res.body - end - - def test_invalid_homepage - data = StringIO.new "GET / HTTP/1.0\r\n\r\n" - dir = "#{@gemhome}2" - - spec = util_spec 'invalidhomepagegem', 1 - spec.homepage = "notavalidhomepageurl" - - specs_dir = File.join dir, 'specifications' - FileUtils.mkdir_p specs_dir - - File.open File.join(specs_dir, spec.spec_name), 'w' do |io| - io.write spec.to_ruby - end - - server = Gem::Server.new dir, process_based_port, false - - @req.parse data - - server.root @req, @res - - assert_equal 200, @res.status - assert_match 'invalidhomepagegem 1', @res.body - - # This verifies that the homepage for this spec is not displayed and is set to ".", because it's not a - # valid HTTP/HTTPS URL and could be unsafe in an HTML context. We would prefer to throw an exception here, - # but spec.homepage is currently free form and not currently required to be a URL, this behavior may be - # validated in future versions of Gem::Specification. - # - # There are two variant we're checking here, one where rdoc is not present, and one where rdoc is present in the same regex: - # - # Variant #1 - rdoc not installed - # - # <b>invalidhomepagegem 1</b> - # - # - # <span title="rdoc not installed">[rdoc]</span> - # - # - # - # <a href="." title=".">[www]</a> - # - # Variant #2 - rdoc installed - # - # <b>invalidhomepagegem 1</b> - # - # - # <a href="\/doc_root\/invalidhomepagegem-1\/">\[rdoc\]<\/a> - # - # - # - # <a href="." title=".">[www]</a> - regex_match = /invalidhomepagegem 1<\/b>\s+(<span title="rdoc not installed">\[rdoc\]<\/span>|<a href="\/doc_root\/invalidhomepagegem-1\/">\[rdoc\]<\/a>)\s+<a href="\." title="\.">\[www\]<\/a>/ - assert_match regex_match, @res.body - end - - def test_valid_homepage_http - data = StringIO.new "GET / HTTP/1.0\r\n\r\n" - dir = "#{@gemhome}2" - - spec = util_spec 'validhomepagegemhttp', 1 - spec.homepage = "http://rubygems.org" - - specs_dir = File.join dir, 'specifications' - FileUtils.mkdir_p specs_dir - - File.open File.join(specs_dir, spec.spec_name), 'w' do |io| - io.write spec.to_ruby - end - - server = Gem::Server.new dir, process_based_port, false - - @req.parse data - - server.root @req, @res - - assert_equal 200, @res.status - assert_match 'validhomepagegemhttp 1', @res.body - - regex_match = /validhomepagegemhttp 1<\/b>\s+(<span title="rdoc not installed">\[rdoc\]<\/span>|<a href="\/doc_root\/validhomepagegemhttp-1\/">\[rdoc\]<\/a>)\s+<a href="http:\/\/rubygems\.org" title="http:\/\/rubygems\.org">\[www\]<\/a>/ - assert_match regex_match, @res.body - end - - def test_valid_homepage_https - data = StringIO.new "GET / HTTP/1.0\r\n\r\n" - dir = "#{@gemhome}2" - - spec = util_spec 'validhomepagegemhttps', 1 - spec.homepage = "https://rubygems.org" - - specs_dir = File.join dir, 'specifications' - FileUtils.mkdir_p specs_dir - - File.open File.join(specs_dir, spec.spec_name), 'w' do |io| - io.write spec.to_ruby - end - - server = Gem::Server.new dir, process_based_port, false - - @req.parse data - - server.root @req, @res - - assert_equal 200, @res.status - assert_match 'validhomepagegemhttps 1', @res.body - - regex_match = /validhomepagegemhttps 1<\/b>\s+(<span title="rdoc not installed">\[rdoc\]<\/span>|<a href="\/doc_root\/validhomepagegemhttps-1\/">\[rdoc\]<\/a>)\s+<a href="https:\/\/rubygems\.org" title="https:\/\/rubygems\.org">\[www\]<\/a>/ - assert_match regex_match, @res.body - end - - def test_specs - data = StringIO.new "GET /specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n" - @req.parse data - - @server.specs @req, @res - - assert_equal 200, @res.status, @res.body - assert_match %r{ \d\d:\d\d:\d\d }, @res['date'] - assert_equal 'application/octet-stream', @res['content-type'] - - assert_equal [['a', Gem::Version.new(1), Gem::Platform::RUBY], - ['a', Gem::Version.new(2), Gem::Platform::RUBY], - ['a', v('3.a'), Gem::Platform::RUBY]], - Marshal.load(@res.body) - end - - def test_specs_gemdirs - data = StringIO.new "GET /specs.#{Gem.marshal_version} HTTP/1.0\r\n\r\n" - dir = "#{@gemhome}2" - - spec = util_spec 'z', 9 - - specs_dir = File.join dir, 'specifications' - FileUtils.mkdir_p specs_dir - - File.open File.join(specs_dir, spec.spec_name), 'w' do |io| - io.write spec.to_ruby - end - - server = Gem::Server.new dir, process_based_port, false - - @req.parse data - - server.specs @req, @res - - assert_equal 200, @res.status - - assert_equal [['z', v(9), Gem::Platform::RUBY]], Marshal.load(@res.body) - end - - def test_specs_gz - data = StringIO.new "GET /specs.#{Gem.marshal_version}.gz HTTP/1.0\r\n\r\n" - @req.parse data - - @server.specs @req, @res - - assert_equal 200, @res.status, @res.body - assert_match %r{ \d\d:\d\d:\d\d }, @res['date'] - assert_equal 'application/x-gzip', @res['content-type'] - - assert_equal [['a', Gem::Version.new(1), Gem::Platform::RUBY], - ['a', Gem::Version.new(2), Gem::Platform::RUBY], - ['a', v('3.a'), Gem::Platform::RUBY]], - Marshal.load(Gem::Util.gunzip(@res.body)) - end - - def test_uri_encode - url_safe = @server.uri_encode 'http://rubyonrails.org/">malicious_content</a>' - assert_equal url_safe, 'http://rubyonrails.org/%22%3Emalicious_content%3C/a%3E' - end - - # Regression test for issue #1793: incorrect URL encoding. - # Checking that no URLs have had '://' incorrectly encoded - def test_regression_1793 - data = StringIO.new "GET / HTTP/1.0\r\n\r\n" - @req.parse data - - @server.root @req, @res - - refute_match %r{%3A%2F%2F}, @res.body - end - - def util_listen - webrick = Object.new - webrick.instance_variable_set :@listeners, [] - def webrick.listeners() @listeners end - def webrick.listen(host, port) - socket = Object.new - socket.instance_variable_set :@host, host - socket.instance_variable_set :@port, port - def socket.addr() [nil, @port, @host] end - @listeners << socket - end - - @server.instance_variable_set :@server, webrick - end -end diff --git a/test/rubygems/test_gem_silent_ui.rb b/test/rubygems/test_gem_silent_ui.rb index 0d46ab592a..001a73eb51 100644 --- a/test/rubygems/test_gem_silent_ui.rb +++ b/test/rubygems/test_gem_silent_ui.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/user_interaction' -require 'timeout' + +require_relative "helper" +require "rubygems/user_interaction" class TestGemSilentUI < Gem::TestCase def setup @@ -18,28 +18,28 @@ class TestGemSilentUI < Gem::TestCase value = nil out, err = capture_output do use_ui @sui do - value = @sui.ask 'Problem?' + value = @sui.ask "Problem?" end end - assert_empty out, 'No output' - assert_empty err, 'No output' + assert_empty out, "No output" + assert_empty err, "No output" - assert_nil value, 'No value' + assert_nil value, "No value" end def test_ask_for_password value = nil out, err = capture_output do use_ui @sui do - value = @sui.ask_for_password 'Problem?' + value = @sui.ask_for_password "Problem?" end end - assert_empty out, 'No output' - assert_empty err, 'No output' + assert_empty out, "No output" + assert_empty err, "No output" - assert_nil value, 'No value' + assert_nil value, "No value" end def test_ask_yes_no @@ -47,70 +47,76 @@ class TestGemSilentUI < Gem::TestCase out, err = capture_output do use_ui @sui do assert_raise(Gem::OperationNotSupportedError) do - @sui.ask_yes_no 'Problem?' + @sui.ask_yes_no "Problem?" end end end - assert_empty out, 'No output' - assert_empty err, 'No output' + assert_empty out, "No output" + assert_empty err, "No output" out, err = capture_output do use_ui @sui do - value = @sui.ask_yes_no 'Problem?', true + value = @sui.ask_yes_no "Problem?", true end end - assert_empty out, 'No output' - assert_empty err, 'No output' + assert_empty out, "No output" + assert_empty err, "No output" - assert value, 'Value is true' + assert value, "Value is true" out, err = capture_output do use_ui @sui do - value = @sui.ask_yes_no 'Problem?', false + value = @sui.ask_yes_no "Problem?", false end end - assert_empty out, 'No output' - assert_empty err, 'No output' + assert_empty out, "No output" + assert_empty err, "No output" - assert_equal value, false, 'Value is false' + assert_equal value, false, "Value is false" end def test_choose_from_list value = nil out, err = capture_output do use_ui @sui do - value = @sui.choose_from_list 'Problem?', %w[yes no] + value = @sui.choose_from_list "Problem?", %w[yes no] end end - assert_empty out, 'No output' - assert_empty err, 'No output' + assert_empty out, "No output" + assert_empty err, "No output" - assert_equal [nil, nil], value, 'Value is nil!' + assert_equal [nil, nil], value, "Value is nil!" end def test_progress_reporter out, err = capture_output do use_ui @sui do - @sui.progress_reporter 10, 'hi' + @sui.progress_reporter 10, "hi" end end - assert_empty out, 'No output' - assert_empty err, 'No output' + assert_empty out, "No output" + assert_empty err, "No output" end def test_download_reporter out, err = capture_output do use_ui @sui do - @sui.download_reporter.fetch 'a.gem', 1024 + @sui.download_reporter.fetch "a.gem", 1024 end end - assert_empty out, 'No output' - assert_empty err, 'No output' + assert_empty out, "No output" + assert_empty err, "No output" + end + + def test_new_without_dev_null + File.stub(:open, ->(path, _mode) { raise Errno::ENOTCAPABLE if path == IO::NULL }) do + Gem::SilentUI.new + end end end diff --git a/test/rubygems/test_gem_source.rb b/test/rubygems/test_gem_source.rb index f7b288ae11..6baa203dcb 100644 --- a/test/rubygems/test_gem_source.rb +++ b/test/rubygems/test_gem_source.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/source' -require 'rubygems/indexer' + +require_relative "helper" +require "rubygems/source" class TestGemSource < Gem::TestCase def tuple(*args) @@ -12,39 +12,39 @@ class TestGemSource < Gem::TestCase super @specs = spec_fetcher do |fetcher| - fetcher.spec 'a', '1.a' - fetcher.gem 'a', 1 - fetcher.spec 'a', 2 - fetcher.spec 'b', 2 + fetcher.spec "a", "1.a" + fetcher.gem "a", 1 + fetcher.spec "a", 2 + fetcher.spec "b", 2 end @source = Gem::Source.new(@gem_repo) end def test_initialize_invalid_uri - assert_raise URI::InvalidURIError do - Gem::Source.new 'git@example:a.git' + assert_raise Gem::URI::InvalidURIError do + Gem::Source.new "git@example:a.git" end end def test_initialize_git - repository = 'git@example:a.git' + repository = "git@example:a.git" - source = Gem::Source::Git.new 'a', repository, 'master', false + source = Gem::Source::Git.new "a", repository, nil, false assert_equal repository, source.uri end def test_cache_dir_escapes_windows_paths - uri = URI.parse("file:///C:/WINDOWS/Temp/gem_repo") + uri = Gem::URI.parse("file:///C:/WINDOWS/Temp/gem_repo") root = Gem.spec_cache_dir - cache_dir = @source.cache_dir(uri).gsub(root, '') - assert cache_dir !~ /:/, "#{cache_dir} should not contain a :" + cache_dir = @source.cache_dir(uri).gsub(root, "") + assert !cache_dir.include?(":"), "#{cache_dir} should not contain a :" end def test_dependency_resolver_set_bundler_api - response = Net::HTTPResponse.new '1.1', 200, 'OK' - response.uri = URI('http://example') + response = Gem::Net::HTTPResponse.new "1.1", 200, "OK" + response.uri = Gem::URI("http://example") @fetcher.data[@gem_repo] = response @@ -54,7 +54,9 @@ class TestGemSource < Gem::TestCase end def test_dependency_resolver_set_file_uri - Gem::Indexer.new(@tempdir).generate_index + empty_dump = Gem::Util.gzip("\x04\x08[\x05".b) + File.binwrite(File.join(@tempdir, "prerelease_specs.4.8.gz"), empty_dump) + File.binwrite(File.join(@tempdir, "specs.4.8.gz"), empty_dump) source = Gem::Source.new "file://#{@tempdir}/" @@ -70,14 +72,14 @@ class TestGemSource < Gem::TestCase end def test_fetch_spec - a1 = @specs['a-1'] + a1 = @specs["a-1"] spec_uri = "#{@gem_repo}#{Gem::MARSHAL_SPEC_DIR}#{a1.spec_name}" - spec = @source.fetch_spec tuple('a', Gem::Version.new(1), 'ruby') + 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_dir = @source.cache_dir Gem::URI.parse(spec_uri) cache_file = File.join cache_dir, a1.spec_name @@ -85,47 +87,45 @@ class TestGemSource < Gem::TestCase end def test_fetch_spec_cached - a1 = @specs['a-1'] + a1 = @specs["a-1"] spec_uri = "#{@gem_repo}/#{Gem::MARSHAL_SPEC_DIR}#{a1.spec_name}" @fetcher.data["#{spec_uri}.rz"] = nil - cache_dir = @source.cache_dir URI.parse(spec_uri) + cache_dir = @source.cache_dir Gem::URI.parse(spec_uri) FileUtils.mkdir_p cache_dir cache_file = File.join cache_dir, a1.spec_name - File.open cache_file, 'wb' do |io| + File.open cache_file, "wb" do |io| Marshal.dump a1, io end - spec = @source.fetch_spec tuple('a', Gem::Version.new(1), 'ruby') + spec = @source.fetch_spec tuple("a", Gem::Version.new(1), "ruby") assert_equal a1.full_name, spec.full_name end def test_fetch_spec_platform - specs = spec_fetcher do |fetcher| - fetcher.legacy_platform - end + specs = spec_fetcher(&:legacy_platform) - spec = @source.fetch_spec tuple('pl', Gem::Version.new(1), 'i386-linux') + spec = @source.fetch_spec tuple("pl", Gem::Version.new(1), "i386-linux") - assert_equal specs['pl-1-x86-linux'].full_name, spec.full_name + assert_equal specs["pl-1-x86-linux"].full_name, spec.full_name end def test_fetch_spec_platform_ruby - spec = @source.fetch_spec tuple('a', Gem::Version.new(1), nil) - assert_equal @specs['a-1'].full_name, spec.full_name + spec = @source.fetch_spec tuple("a", Gem::Version.new(1), nil) + assert_equal @specs["a-1"].full_name, spec.full_name - spec = @source.fetch_spec tuple('a', Gem::Version.new(1), '') - assert_equal @specs['a-1'].full_name, spec.full_name + spec = @source.fetch_spec tuple("a", Gem::Version.new(1), "") + assert_equal @specs["a-1"].full_name, spec.full_name end def test_load_specs - released = @source.load_specs(:released).map {|spec| spec.full_name } + released = @source.load_specs(:released).map(&:full_name) assert_equal %W[a-2 a-1 b-2], released - cache_dir = File.join Gem.spec_cache_dir, 'gems.example.com%80' + cache_dir = File.join Gem.spec_cache_dir, "gems.example.com%80" assert File.exist?(cache_dir), "#{cache_dir} does not exist" cache_file = File.join cache_dir, "specs.#{Gem.marshal_version}" @@ -136,19 +136,19 @@ class TestGemSource < Gem::TestCase latest_specs = @source.load_specs :latest # Make sure the cached version is actually different: - latest_specs << Gem::NameTuple.new('cached', Gem::Version.new('1.0.0'), 'ruby') + 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 + " " * Marshal.dump(latest_specs).length - cache_dir = File.join Gem.spec_cache_dir, 'gems.example.com%80' + cache_dir = File.join Gem.spec_cache_dir, "gems.example.com%80" FileUtils.mkdir_p cache_dir cache_file = File.join cache_dir, "latest_specs.#{Gem.marshal_version}" - File.open cache_file, 'wb' do |io| + File.open cache_file, "wb" do |io| Marshal.dump latest_specs, io end @@ -161,18 +161,18 @@ class TestGemSource < Gem::TestCase latest_specs = @source.load_specs :latest # Make sure the cached version is actually different: - latest_specs << Gem::NameTuple.new('fixed', Gem::Version.new('1.0.0'), 'ruby') + 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)) + util_gzip(Marshal.dump(latest_specs)) - cache_dir = File.join Gem.spec_cache_dir, 'gems.example.com%80' + cache_dir = File.join Gem.spec_cache_dir, "gems.example.com%80" FileUtils.mkdir_p cache_dir cache_file = File.join cache_dir, "latest_specs.#{Gem.marshal_version}" - File.open cache_file, 'wb' do |io| + File.open cache_file, "wb" do |io| # Setup invalid data in the cache: io.write Marshal.dump(latest_specs)[0, 10] end @@ -192,34 +192,34 @@ class TestGemSource < Gem::TestCase def test_spaceship remote = @source - specific = Gem::Source::SpecificFile.new @specs['a-1'].cache_file + specific = Gem::Source::SpecificFile.new @specs["a-1"].cache_file installed = Gem::Source::Installed.new local = Gem::Source::Local.new - assert_equal(0, remote.<=>(remote), 'remote <=> remote') + assert_equal(0, remote.<=>(remote), "remote <=> remote") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands - assert_equal(-1, remote.<=>(specific), 'remote <=> specific') - assert_equal(1, specific.<=>(remote), 'specific <=> remote') + assert_equal(-1, remote.<=>(specific), "remote <=> specific") + assert_equal(1, specific.<=>(remote), "specific <=> remote") - assert_equal(-1, remote.<=>(local), 'remote <=> local') - assert_equal(1, local.<=>(remote), 'local <=> remote') + assert_equal(-1, remote.<=>(local), "remote <=> local") + assert_equal(1, local.<=>(remote), "local <=> remote") - assert_equal(-1, remote.<=>(installed), 'remote <=> installed') - assert_equal(1, installed.<=>(remote), 'installed <=> remote') + assert_equal(-1, remote.<=>(installed), "remote <=> installed") + assert_equal(1, installed.<=>(remote), "installed <=> remote") no_uri = @source.dup no_uri.instance_variable_set :@uri, nil - assert_equal(-1, remote.<=>(no_uri), 'remote <=> no_uri') + assert_equal(-1, remote.<=>(no_uri), "remote <=> no_uri") end def test_spaceship_order_is_preserved_when_uri_differs - sourceA = Gem::Source.new "http://example.com/a" - sourceB = Gem::Source.new "http://example.com/b" + source_a = Gem::Source.new "http://example.com/a" + source_b = Gem::Source.new "http://example.com/b" - assert_equal(0, sourceA.<=>(sourceA), 'sourceA <=> sourceA') - assert_equal(1, sourceA.<=>(sourceB), 'sourceA <=> sourceB') - assert_equal(1, sourceB.<=>(sourceA), 'sourceB <=> sourceA') + assert_equal(0, source_a.<=>(source_a), "source_a <=> source_a") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands + assert_equal(1, source_a.<=>(source_b), "source_a <=> source_b") + assert_equal(1, source_b.<=>(source_a), "source_b <=> source_a") end def test_update_cache_eh diff --git a/test/rubygems/test_gem_source_fetch_problem.rb b/test/rubygems/test_gem_source_fetch_problem.rb index 87b190a12c..6d8ef360ae 100644 --- a/test/rubygems/test_gem_source_fetch_problem.rb +++ b/test/rubygems/test_gem_source_fetch_problem.rb @@ -1,10 +1,11 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" class TestGemSourceFetchProblem < Gem::TestCase def test_exception source = Gem::Source.new @gem_repo - error = RuntimeError.new 'test' + error = RuntimeError.new "test" sf = Gem::SourceFetchProblem.new source, error @@ -12,15 +13,25 @@ class TestGemSourceFetchProblem < Gem::TestCase raise sf end - assert_equal 'test', e.message + assert_equal "test", e.message end def test_password_redacted - source = Gem::Source.new 'https://username:secret@gemsource.com' - error = RuntimeError.new 'test' + source = Gem::Source.new "https://username:secret@gemsource.com" + error = RuntimeError.new "test" + + sf = Gem::SourceFetchProblem.new source, error + + refute_match sf.wordy, "secret" + end + + def test_source_password_no_redacted + source = Gem::Source.new "https://username:secret@gemsource.com" + error = RuntimeError.new "test" sf = Gem::SourceFetchProblem.new source, error + sf.wordy - refute_match sf.wordy, 'secret' + assert_match "secret", source.uri.to_s end end diff --git a/test/rubygems/test_gem_source_git.rb b/test/rubygems/test_gem_source_git.rb index 749859b024..20e750a0d4 100644 --- a/test/rubygems/test_gem_source_git.rb +++ b/test/rubygems/test_gem_source_git.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/source' + +require_relative "helper" +require "rubygems/source" class TestGemSourceGit < Gem::TestCase def setup @@ -8,38 +9,39 @@ class TestGemSourceGit < Gem::TestCase @name, @version, @repository, @head = git_gem - @hash = Digest::SHA1.hexdigest @repository + @hash = OpenSSL::Digest::SHA1.hexdigest @repository - @source = Gem::Source::Git.new @name, @repository, 'master', false + @source = Gem::Source::Git.new @name, @repository, nil, false end def test_base_dir - assert_equal File.join(Gem.dir, 'bundler'), @source.base_dir + assert_equal File.join(Gem.dir, "bundler"), @source.base_dir @source.root_dir = "#{@gemhome}2" - assert_equal File.join("#{@gemhome}2", 'bundler'), @source.base_dir + assert_equal File.join("#{@gemhome}2", "bundler"), @source.base_dir end def test_checkout @source.checkout - assert_path_exist File.join @source.install_dir, 'a.gemspec' + assert_path_exist File.join @source.install_dir, "a.gemspec" end - def test_checkout_master + def test_checkout_default Dir.chdir @repository do - system @git, 'checkout', '-q', '-b', 'other' - system @git, 'mv', 'a.gemspec', 'b.gemspec' - system @git, 'commit', '-q', '-a', '-m', 'rename gemspec' - system @git, 'checkout', '-q', 'master' + default_branch = Gem::Util.popen(@git, "branch", "--show-current").strip + system @git, "checkout", "-q", "-b", "other" + system @git, "mv", "a.gemspec", "b.gemspec" + system @git, "commit", "-q", "-a", "-m", "rename gemspec" + system @git, "checkout", "-q", default_branch end - @source = Gem::Source::Git.new @name, @repository, 'other', false + @source = Gem::Source::Git.new @name, @repository, "other", false @source.checkout - assert_path_exist File.join @source.install_dir, 'b.gemspec' + assert_path_exist File.join @source.install_dir, "b.gemspec" end def test_checkout_local @@ -47,9 +49,9 @@ class TestGemSourceGit < Gem::TestCase @source.checkout - install_dir = File.join Gem.dir, 'bundler', 'gems', "a-#{@head[0..11]}" + install_dir = File.join Gem.dir, "bundler", "gems", "a-#{@head[0..11]}" - assert_path_not_exist File.join install_dir, 'a.gemspec' + assert_path_not_exist File.join install_dir, "a.gemspec" end def test_checkout_local_cached @@ -59,25 +61,31 @@ class TestGemSourceGit < Gem::TestCase @source.checkout - assert_path_exist File.join @source.install_dir, 'a.gemspec' + assert_path_exist File.join @source.install_dir, "a.gemspec" end def test_checkout_submodules - source = Gem::Source::Git.new @name, @repository, 'master', true + # We need to allow to checkout submodules with file:// protocol + # CVE-2022-39253 + # https://lore.kernel.org/lkml/xmqq4jw1uku5.fsf@gitster.g/ + system(@git, *%W[config --global protocol.file.allow always]) + + source = Gem::Source::Git.new @name, @repository, nil, true - git_gem 'b' + git_gem "b" - Dir.chdir 'git/a' do - output, status = Open3.capture2e(@git, 'submodule', '--quiet', 'add', File.expand_path('../b'), 'b') + Dir.chdir "git/a" do + require "open3" + output, status = Open3.capture2e(@git, "submodule", "--quiet", "add", File.expand_path("../b"), "b") assert status.success?, output - system @git, 'commit', '--quiet', '-m', 'add submodule b' + system @git, "commit", "--quiet", "-m", "add submodule b" end source.checkout - assert_path_exist File.join source.install_dir, 'a.gemspec' - assert_path_exist File.join source.install_dir, 'b/b.gemspec' + assert_path_exist File.join source.install_dir, "a.gemspec" + assert_path_exist File.join source.install_dir, "b/b.gemspec" end def test_cache @@ -86,7 +94,7 @@ class TestGemSourceGit < Gem::TestCase assert_path_exist @source.repo_cache_dir Dir.chdir @source.repo_cache_dir do - assert_equal @head, Gem::Util.popen(@git, 'rev-parse', 'master').strip + assert_equal @head, Gem::Util.popen(@git, "rev-parse", "HEAD").strip end end @@ -114,17 +122,17 @@ class TestGemSourceGit < Gem::TestCase assert_equal @source, @source.dup source = - Gem::Source::Git.new @source.name, @source.repository, 'other', false + Gem::Source::Git.new @source.name, @source.repository, "other", false refute_equal @source, source source = - Gem::Source::Git.new @source.name, 'repo/other', @source.reference, false + Gem::Source::Git.new @source.name, "repo/other", @source.reference, false refute_equal @source, source source = - Gem::Source::Git.new 'b', @source.repository, @source.reference, false + Gem::Source::Git.new "b", @source.repository, @source.reference, false refute_equal @source, source @@ -138,7 +146,7 @@ class TestGemSourceGit < Gem::TestCase def test_install_dir @source.cache - expected = File.join Gem.dir, 'bundler', 'gems', "a-#{@head[0..11]}" + expected = File.join Gem.dir, "bundler", "gems", "a-#{@head[0..11]}" assert_equal expected, @source.install_dir end @@ -151,14 +159,14 @@ class TestGemSourceGit < Gem::TestCase def test_repo_cache_dir expected = - File.join Gem.dir, 'cache', 'bundler', 'git', "a-#{@hash}" + File.join Gem.dir, "cache", "bundler", "git", "a-#{@hash}" assert_equal expected, @source.repo_cache_dir @source.root_dir = "#{@gemhome}2" expected = - File.join "#{@gemhome}2", 'cache', 'bundler', 'git', "a-#{@hash}" + File.join "#{@gemhome}2", "cache", "bundler", "git", "a-#{@hash}" assert_equal expected, @source.repo_cache_dir end @@ -169,20 +177,20 @@ class TestGemSourceGit < Gem::TestCase assert_equal @head, @source.rev_parse Dir.chdir @repository do - system @git, 'checkout', '--quiet', '-b', 'other' + system @git, "checkout", "--quiet", "-b", "other" end - master_head = @head + default_head = @head - git_gem 'a', 2 + git_gem "a", 2 - source = Gem::Source::Git.new @name, @repository, 'other', false + source = Gem::Source::Git.new @name, @repository, "other", false source.cache - refute_equal master_head, source.rev_parse + refute_equal default_head, source.rev_parse - source = Gem::Source::Git.new @name, @repository, 'nonexistent', false + source = Gem::Source::Git.new @name, @repository, "nonexistent", false source.cache @@ -203,38 +211,38 @@ class TestGemSourceGit < Gem::TestCase end def test_spaceship - git = Gem::Source::Git.new 'a', 'git/a', 'master', false + git = Gem::Source::Git.new "a", "git/a", nil, false remote = Gem::Source.new @gem_repo installed = Gem::Source::Installed.new - vendor = Gem::Source::Vendor.new 'vendor/foo' + vendor = Gem::Source::Vendor.new "vendor/foo" - assert_equal(0, git.<=>(git), 'git <=> git') + assert_equal(0, git.<=>(git), "git <=> git") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands - assert_equal(1, git.<=>(remote), 'git <=> remote') - assert_equal(-1, remote.<=>(git), 'remote <=> git') + assert_equal(1, git.<=>(remote), "git <=> remote") + assert_equal(-1, remote.<=>(git), "remote <=> git") - assert_equal(1, git.<=>(installed), 'git <=> installed') - assert_equal(-1, installed.<=>(git), 'installed <=> git') + assert_equal(1, git.<=>(installed), "git <=> installed") + assert_equal(-1, installed.<=>(git), "installed <=> git") - assert_equal(-1, git.<=>(vendor), 'git <=> vendor') - assert_equal(1, vendor.<=>(git), 'vendor <=> git') + assert_equal(-1, git.<=>(vendor), "git <=> vendor") + assert_equal(1, vendor.<=>(git), "vendor <=> git") end def test_specs - source = Gem::Source::Git.new @name, @repository, 'master', true + source = Gem::Source::Git.new @name, @repository, nil, true - Dir.chdir 'git/a' do - FileUtils.mkdir 'b' + Dir.chdir "git/a" do + FileUtils.mkdir "b" - Dir.chdir 'b' do - b = Gem::Specification.new 'b', 1 + Dir.chdir "b" do + b = Gem::Specification.new "b", 1 - File.open 'b.gemspec', 'w' do |io| + File.open "b.gemspec", "w" do |io| io.write b.to_ruby end - system @git, 'add', 'b.gemspec' - system @git, 'commit', '--quiet', '-m', 'add b/b.gemspec' + system @git, "add", "b.gemspec" + system @git, "commit", "--quiet", "-m", "add b/b.gemspec" end end @@ -244,18 +252,18 @@ class TestGemSourceGit < Gem::TestCase specs = source.specs end - assert_equal %w[a-1 b-1], specs.map {|spec| spec.full_name } + assert_equal %w[a-1 b-1], specs.map(&:full_name) a_spec = specs.shift base_dir = File.dirname File.dirname source.install_dir assert_equal source.install_dir, a_spec.full_gem_path - assert_equal File.join(source.install_dir, 'a.gemspec'), a_spec.loaded_from + assert_equal File.join(source.install_dir, "a.gemspec"), a_spec.loaded_from assert_equal base_dir, a_spec.base_dir extension_dir = - File.join Gem.dir, 'bundler', 'extensions', + File.join Gem.dir, "bundler", "extensions", Gem::Platform.local.to_s, Gem.extension_api_version, "a-#{source.dir_shortref}" @@ -263,8 +271,8 @@ class TestGemSourceGit < Gem::TestCase b_spec = specs.shift - assert_equal File.join(source.install_dir, 'b'), b_spec.full_gem_path - assert_equal File.join(source.install_dir, 'b', 'b.gemspec'), + assert_equal File.join(source.install_dir, "b"), b_spec.full_gem_path + assert_equal File.join(source.install_dir, "b", "b.gemspec"), b_spec.loaded_from assert_equal base_dir, b_spec.base_dir @@ -272,7 +280,7 @@ class TestGemSourceGit < Gem::TestCase end def test_specs_local - source = Gem::Source::Git.new @name, @repository, 'master', true + source = Gem::Source::Git.new @name, @repository, nil, true source.remote = false capture_output do @@ -281,22 +289,22 @@ class TestGemSourceGit < Gem::TestCase end def test_uri - assert_equal URI(@repository), @source.uri + assert_equal Gem::URI(@repository), @source.uri end def test_uri_hash assert_equal @hash, @source.uri_hash source = - Gem::Source::Git.new 'a', 'http://git@example/repo.git', 'master', false + Gem::Source::Git.new "a", "http://git@example/repo.git", nil, false - assert_equal '291c4caac7feba8bb64c297987028acb3dde6cfe', + assert_equal "291c4caac7feba8bb64c297987028acb3dde6cfe", source.uri_hash source = - Gem::Source::Git.new 'a', 'HTTP://git@EXAMPLE/repo.git', 'master', false + Gem::Source::Git.new "a", "HTTP://git@EXAMPLE/repo.git", nil, false - assert_equal '291c4caac7feba8bb64c297987028acb3dde6cfe', + assert_equal "291c4caac7feba8bb64c297987028acb3dde6cfe", source.uri_hash end end diff --git a/test/rubygems/test_gem_source_installed.rb b/test/rubygems/test_gem_source_installed.rb index 93aa4eb039..0d6171b0e5 100644 --- a/test/rubygems/test_gem_source_installed.rb +++ b/test/rubygems/test_gem_source_installed.rb @@ -1,34 +1,35 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/source' + +require_relative "helper" +require "rubygems/source" class TestGemSourceInstalled < Gem::TestCase def test_spaceship - a1 = quick_gem 'a', '1' + a1 = quick_gem "a", "1" util_build_gem a1 remote = Gem::Source.new @gem_repo specific = Gem::Source::SpecificFile.new a1.cache_file installed = Gem::Source::Installed.new local = Gem::Source::Local.new - git = Gem::Source::Git.new 'a', 'a', 'master' - vendor = Gem::Source::Vendor.new 'a' + git = Gem::Source::Git.new "a", "a", nil + vendor = Gem::Source::Vendor.new "a" - assert_equal(0, installed.<=>(installed), 'installed <=> installed') + assert_equal(0, installed.<=>(installed), "installed <=> installed") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands - assert_equal(-1, remote.<=>(installed), 'remote <=> installed') - assert_equal(1, installed.<=>(remote), 'installed <=> remote') + assert_equal(-1, remote.<=>(installed), "remote <=> installed") + assert_equal(1, installed.<=>(remote), "installed <=> remote") - assert_equal(1, installed.<=>(local), 'installed <=> local') - assert_equal(-1, local.<=>(installed), 'local <=> installed') + assert_equal(1, installed.<=>(local), "installed <=> local") + assert_equal(-1, local.<=>(installed), "local <=> installed") - assert_equal(-1, specific.<=>(installed), 'specific <=> installed') - assert_equal(1, installed.<=>(specific), 'installed <=> specific') + assert_equal(-1, specific.<=>(installed), "specific <=> installed") + assert_equal(1, installed.<=>(specific), "installed <=> specific") - assert_equal(1, git. <=>(installed), 'git <=> installed') - assert_equal(-1, installed.<=>(git), 'installed <=> git') + assert_equal(1, git. <=>(installed), "git <=> installed") + assert_equal(-1, installed.<=>(git), "installed <=> git") - assert_equal(1, vendor.<=>(installed), 'vendor <=> installed') - assert_equal(-1, installed.<=>(vendor), 'installed <=> vendor') + assert_equal(1, vendor.<=>(installed), "vendor <=> installed") + assert_equal(-1, installed.<=>(vendor), "installed <=> vendor") end end diff --git a/test/rubygems/test_gem_source_list.rb b/test/rubygems/test_gem_source_list.rb index 7c60af3ff8..64353f8f90 100644 --- a/test/rubygems/test_gem_source_list.rb +++ b/test/rubygems/test_gem_source_list.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true -require 'rubygems' -require 'rubygems/source_list' -require 'rubygems/test_case' + +require "rubygems" +require "rubygems/source_list" +require_relative "helper" class TestGemSourceList < Gem::TestCase def setup @@ -36,7 +37,7 @@ class TestGemSourceList < Gem::TestCase assert_kind_of Gem::Source, source - assert_kind_of URI, source.uri + assert_kind_of Gem::URI, source.uri assert_equal source.uri.to_s, @uri assert_equal [source], sl.sources @@ -45,7 +46,7 @@ class TestGemSourceList < Gem::TestCase def test_clear sl = Gem::SourceList.new - sl << 'http://source.example' + sl << "http://source.example" sl.clear @@ -76,7 +77,7 @@ class TestGemSourceList < Gem::TestCase assert_empty sl - sl << 'http://source.example' + sl << "http://source.example" refute_empty sl end @@ -98,7 +99,7 @@ class TestGemSourceList < Gem::TestCase def test_include_eh assert @sl.include?(@uri), "string comparison not working" - assert @sl.include?(URI.parse(@uri)), "uri comparison not working" + assert @sl.include?(Gem::URI.parse(@uri)), "uri comparison not working" end def test_include_matches_a_source diff --git a/test/rubygems/test_gem_source_local.rb b/test/rubygems/test_gem_source_local.rb index 7417f8d111..c15e0e07c0 100644 --- a/test/rubygems/test_gem_source_local.rb +++ b/test/rubygems/test_gem_source_local.rb @@ -1,8 +1,9 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/source' -require 'fileutils' +require_relative "helper" +require "rubygems/source" + +require "fileutils" class TestGemSourceLocal < Gem::TestCase def setup @@ -10,9 +11,9 @@ class TestGemSourceLocal < Gem::TestCase @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' + @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 @@ -72,7 +73,7 @@ class TestGemSourceLocal < Gem::TestCase @sl.load_specs :released - inner = [@a, @ap, @b].map {|t| t.name_tuple }.inspect + inner = [@a, @ap, @b].map(&:name_tuple).inspect assert_equal "#<Gem::Source::Local specs: #{inner}>", @sl.inspect end @@ -84,7 +85,7 @@ class TestGemSourceLocal < Gem::TestCase end def test_spaceship - a1 = quick_gem 'a', '1' + a1 = quick_gem "a", "1" util_build_gem a1 remote = Gem::Source.new @gem_repo @@ -92,15 +93,15 @@ class TestGemSourceLocal < Gem::TestCase installed = Gem::Source::Installed.new local = Gem::Source::Local.new - assert_equal(0, local.<=>(local), 'local <=> local') + assert_equal(0, local.<=>(local), "local <=> local") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands - assert_equal(-1, remote.<=>(local), 'remote <=> local') - assert_equal(1, local.<=>(remote), 'local <=> remote') + assert_equal(-1, remote.<=>(local), "remote <=> local") + assert_equal(1, local.<=>(remote), "local <=> remote") - assert_equal(1, installed.<=>(local), 'installed <=> local') - assert_equal(-1, local.<=>(installed), 'local <=> installed') + assert_equal(1, installed.<=>(local), "installed <=> local") + assert_equal(-1, local.<=>(installed), "local <=> installed") - assert_equal(-1, specific.<=>(local), 'specific <=> local') - assert_equal(1, local.<=>(specific), 'local <=> specific') + assert_equal(-1, specific.<=>(local), "specific <=> local") + assert_equal(1, local.<=>(specific), "local <=> specific") end end diff --git a/test/rubygems/test_gem_source_lock.rb b/test/rubygems/test_gem_source_lock.rb index 8c55926d94..91ffee68f2 100644 --- a/test/rubygems/test_gem_source_lock.rb +++ b/test/rubygems/test_gem_source_lock.rb @@ -1,24 +1,25 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" class TestGemSourceLock < Gem::TestCase def test_fetch_spec spec_fetcher do |fetcher| - fetcher.spec 'a', 1 + fetcher.spec "a", 1 end - name_tuple = Gem::NameTuple.new 'a', v(1), 'ruby' + name_tuple = Gem::NameTuple.new "a", v(1), "ruby" remote = Gem::Source.new @gem_repo lock = Gem::Source::Lock.new remote spec = lock.fetch_spec name_tuple - assert_equal 'a-1', spec.full_name + assert_equal "a-1", spec.full_name end def test_equals2 - git = Gem::Source::Git.new 'a', 'git/a', 'master', false + git = Gem::Source::Git.new "a", "git/a", nil, false g_lock = Gem::Source::Lock.new git installed = Gem::Source::Installed.new @@ -30,83 +31,85 @@ class TestGemSourceLock < Gem::TestCase end def test_spaceship - git = Gem::Source::Git.new 'a', 'git/a', 'master', false + git = Gem::Source::Git.new "a", "git/a", nil, false g_lock = Gem::Source::Lock.new git installed = Gem::Source::Installed.new i_lock = Gem::Source::Lock.new installed - vendor = Gem::Source::Vendor.new 'vendor/a' + vendor = Gem::Source::Vendor.new "vendor/a" v_lock = Gem::Source::Lock.new vendor - assert_equal(0, g_lock.<=>(g_lock), 'g_lock <=> g_lock') - assert_equal(0, i_lock.<=>(i_lock), 'i_lock <=> i_lock') - assert_equal(0, v_lock.<=>(v_lock), 'v_lock <=> v_lock') + # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands + assert_equal(0, g_lock.<=>(g_lock), "g_lock <=> g_lock") + assert_equal(0, i_lock.<=>(i_lock), "i_lock <=> i_lock") + assert_equal(0, v_lock.<=>(v_lock), "v_lock <=> v_lock") + # rubocop:enable Lint/BinaryOperatorWithIdenticalOperands - assert_equal(1, g_lock.<=>(i_lock), 'g_lock <=> i_lock') - assert_equal(-1, i_lock.<=>(g_lock), 'i_lock <=> g_lock') + assert_equal(1, g_lock.<=>(i_lock), "g_lock <=> i_lock") + assert_equal(-1, i_lock.<=>(g_lock), "i_lock <=> g_lock") - assert_equal(-1, g_lock.<=>(v_lock), 'g_lock <=> v_lock') - assert_equal(1, v_lock.<=>(g_lock), 'v_lock <=> g_lock') + assert_equal(-1, g_lock.<=>(v_lock), "g_lock <=> v_lock") + assert_equal(1, v_lock.<=>(g_lock), "v_lock <=> g_lock") - assert_equal(-1, i_lock.<=>(v_lock), 'i_lock <=> v_lock') - assert_equal(1, v_lock.<=>(i_lock), 'i_lock <=> v_lock') + assert_equal(-1, i_lock.<=>(v_lock), "i_lock <=> v_lock") + assert_equal(1, v_lock.<=>(i_lock), "i_lock <=> v_lock") end def test_spaceship_git - git = Gem::Source::Git.new 'a', 'git/a', 'master', false + git = Gem::Source::Git.new "a", "git/a", nil, false lock = Gem::Source::Lock.new git - assert_equal(1, lock.<=>(git), 'lock <=> git') - assert_equal(-1, git.<=>(lock), 'git <=> lock') + assert_equal(1, lock.<=>(git), "lock <=> git") + assert_equal(-1, git.<=>(lock), "git <=> lock") end def test_spaceship_installed installed = Gem::Source::Installed.new lock = Gem::Source::Lock.new installed - assert_equal(1, lock.<=>(installed), 'lock <=> installed') - assert_equal(-1, installed.<=>(lock), 'installed <=> lock') + assert_equal(1, lock.<=>(installed), "lock <=> installed") + assert_equal(-1, installed.<=>(lock), "installed <=> lock") end def test_spaceship_local local = Gem::Source::Local.new lock = Gem::Source::Lock.new local # nonsense - assert_equal(1, lock.<=>(local), 'lock <=> local') - assert_equal(-1, local.<=>(lock), 'local <=> lock') + assert_equal(1, lock.<=>(local), "lock <=> local") + assert_equal(-1, local.<=>(lock), "local <=> lock") end def test_spaceship_remote remote = Gem::Source.new @gem_repo lock = Gem::Source::Lock.new remote - assert_equal(1, lock.<=>(remote), 'lock <=> remote') - assert_equal(-1, remote.<=>(lock), 'remote <=> lock') + assert_equal(1, lock.<=>(remote), "lock <=> remote") + assert_equal(-1, remote.<=>(lock), "remote <=> lock") end def test_spaceship_specific_file - _, gem = util_gem 'a', 1 + _, gem = util_gem "a", 1 specific = Gem::Source::SpecificFile.new gem lock = Gem::Source::Lock.new specific # nonsense - assert_equal(1, lock.<=>(specific), 'lock <=> specific') - assert_equal(-1, specific.<=>(lock), 'specific <=> lock') + assert_equal(1, lock.<=>(specific), "lock <=> specific") + assert_equal(-1, specific.<=>(lock), "specific <=> lock") end def test_spaceship_vendor - vendor = Gem::Source::Vendor.new 'vendor/a' + vendor = Gem::Source::Vendor.new "vendor/a" lock = Gem::Source::Lock.new vendor - assert_equal(1, lock.<=>(vendor), 'lock <=> vendor') - assert_equal(-1, vendor.<=>(lock), 'vendor <=> lock') + assert_equal(1, lock.<=>(vendor), "lock <=> vendor") + assert_equal(-1, vendor.<=>(lock), "vendor <=> lock") end def test_uri remote = Gem::Source.new @gem_repo lock = Gem::Source::Lock.new remote - assert_equal URI(@gem_repo), lock.uri + assert_equal Gem::URI(@gem_repo), lock.uri end end diff --git a/test/rubygems/test_gem_source_specific_file.rb b/test/rubygems/test_gem_source_specific_file.rb index f6d6aa51d5..3bc1901ee1 100644 --- a/test/rubygems/test_gem_source_specific_file.rb +++ b/test/rubygems/test_gem_source_specific_file.rb @@ -1,12 +1,13 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/source' + +require_relative "helper" +require "rubygems/source" class TestGemSourceSpecificFile < Gem::TestCase def setup super - @a, @a_gem = util_gem "a", '1' + @a, @a_gem = util_gem "a", "1" @sf = Gem::Source::SpecificFile.new(@a_gem) end @@ -37,7 +38,7 @@ class TestGemSourceSpecificFile < Gem::TestCase end def test_spaceship - a1 = quick_gem 'a', '1' + a1 = quick_gem "a", "1" util_build_gem a1 remote = Gem::Source.new @gem_repo @@ -45,31 +46,31 @@ class TestGemSourceSpecificFile < Gem::TestCase installed = Gem::Source::Installed.new local = Gem::Source::Local.new - assert_equal(0, specific.<=>(specific), 'specific <=> specific') + assert_equal(0, specific.<=>(specific), "specific <=> specific") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands - assert_equal(-1, remote.<=>(specific), 'remote <=> specific') - assert_equal(1, specific.<=>(remote), 'specific <=> remote') + assert_equal(-1, remote.<=>(specific), "remote <=> specific") + assert_equal(1, specific.<=>(remote), "specific <=> remote") - assert_equal(-1, specific.<=>(local), 'specific <=> local') - assert_equal(1, local. <=>(specific), 'local <=> specific') + assert_equal(-1, specific.<=>(local), "specific <=> local") + assert_equal(1, local. <=>(specific), "local <=> specific") - assert_equal(-1, specific. <=>(installed), 'specific <=> installed') - assert_equal(1, installed.<=>(specific), 'installed <=> specific') + assert_equal(-1, specific. <=>(installed), "specific <=> installed") + assert_equal(1, installed.<=>(specific), "installed <=> specific") - a2 = quick_gem 'a', '2' + a2 = quick_gem "a", "2" util_build_gem a2 - b1 = quick_gem 'b', '1' + b1 = quick_gem "b", "1" util_build_gem b1 a1_source = specific a2_source = Gem::Source::SpecificFile.new a2.cache_file b1_source = Gem::Source::SpecificFile.new b1.cache_file - assert_nil a1_source.<=>(b1_source), 'a1_source <=> b1_source' + assert_nil a1_source.<=>(b1_source), "a1_source <=> b1_source" - assert_equal(-1, a1_source.<=>(a2_source), 'a1_source <=> a2_source') - assert_equal(0, a1_source.<=>(a1_source), 'a1_source <=> a1_source') - assert_equal(1, a2_source.<=>(a1_source), 'a2_source <=> a1_source') + assert_equal(-1, a1_source.<=>(a2_source), "a1_source <=> a2_source") + assert_equal(0, a1_source.<=>(a1_source), "a1_source <=> a1_source") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands + assert_equal(1, a2_source.<=>(a1_source), "a2_source <=> a1_source") end end diff --git a/test/rubygems/test_gem_source_subpath_problem.rb b/test/rubygems/test_gem_source_subpath_problem.rb index b2289ea625..a451a81a25 100644 --- a/test/rubygems/test_gem_source_subpath_problem.rb +++ b/test/rubygems/test_gem_source_subpath_problem.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/source' + +require_relative "helper" +require "rubygems/source" class TestGemSourceSubpathProblem < Gem::TestCase def tuple(*args) @@ -20,8 +21,8 @@ class TestGemSourceSubpathProblem < Gem::TestCase end def test_dependency_resolver_set - response = Net::HTTPResponse.new '1.1', 200, 'OK' - response.uri = URI('http://example') + response = Gem::Net::HTTPResponse.new "1.1", 200, "OK" + response.uri = Gem::URI("http://example") @fetcher.data["#{@gem_repo}/"] = response @@ -33,17 +34,17 @@ class TestGemSourceSubpathProblem < Gem::TestCase def test_fetch_spec @fetcher.data["#{@gem_repo}/#{Gem::MARSHAL_SPEC_DIR}#{@a1.spec_name}.rz"] = Zlib::Deflate.deflate(Marshal.dump(@a1)) - spec = @source.fetch_spec tuple('a', Gem::Version.new(1), 'ruby') + spec = @source.fetch_spec tuple("a", Gem::Version.new(1), "ruby") assert_equal @a1.full_name, spec.full_name end def test_load_specs @fetcher.data["#{@gem_repo}/latest_specs.#{Gem.marshal_version}.gz"] = util_gzip(Marshal.dump([ - Gem::NameTuple.new(@a1.name, @a1.version, 'ruby'), - Gem::NameTuple.new(@b2.name, @b2.version, 'ruby'), + Gem::NameTuple.new(@a1.name, @a1.version, "ruby"), + Gem::NameTuple.new(@b2.name, @b2.version, "ruby"), ])) - released = @source.load_specs(:latest).map {|spec| spec.full_name } + released = @source.load_specs(:latest).map(&:full_name) assert_equal %W[a-1 b-2], released end end diff --git a/test/rubygems/test_gem_source_vendor.rb b/test/rubygems/test_gem_source_vendor.rb index 18a3f47f45..2543871439 100644 --- a/test/rubygems/test_gem_source_vendor.rb +++ b/test/rubygems/test_gem_source_vendor.rb @@ -1,29 +1,30 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/source' + +require_relative "helper" +require "rubygems/source" class TestGemSourceVendor < Gem::TestCase def test_initialize - source = Gem::Source::Vendor.new 'vendor/foo' + source = Gem::Source::Vendor.new "vendor/foo" - assert_equal 'vendor/foo', source.uri + assert_equal "vendor/foo", source.uri end def test_spaceship - vendor = Gem::Source::Vendor.new 'vendor/foo' + vendor = Gem::Source::Vendor.new "vendor/foo" remote = Gem::Source.new @gem_repo - git = Gem::Source::Git.new 'a', 'a', 'master' + git = Gem::Source::Git.new "a", "a", nil installed = Gem::Source::Installed.new - assert_equal(0, vendor.<=>(vendor), 'vendor <=> vendor') + assert_equal(0, vendor.<=>(vendor), "vendor <=> vendor") # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands - assert_equal(1, vendor.<=>(remote), 'vendor <=> remote') - assert_equal(-1, remote.<=>(vendor), 'remote <=> vendor') + assert_equal(1, vendor.<=>(remote), "vendor <=> remote") + assert_equal(-1, remote.<=>(vendor), "remote <=> vendor") - assert_equal(1, vendor.<=>(git), 'vendor <=> git') - assert_equal(-1, git.<=>(vendor), 'git <=> vendor') + assert_equal(1, vendor.<=>(git), "vendor <=> git") + assert_equal(-1, git.<=>(vendor), "git <=> vendor") - assert_equal(1, vendor.<=>(installed), 'vendor <=> installed') - assert_equal(-1, installed.<=>(vendor), 'installed <=> vendor') + assert_equal(1, vendor.<=>(installed), "vendor <=> installed") + assert_equal(-1, installed.<=>(vendor), "installed <=> vendor") end end diff --git a/test/rubygems/test_gem_spec_fetcher.rb b/test/rubygems/test_gem_spec_fetcher.rb index 9c756aacf3..cb4a4f7204 100644 --- a/test/rubygems/test_gem_spec_fetcher.rb +++ b/test/rubygems/test_gem_spec_fetcher.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/spec_fetcher' + +require_relative "helper" +require "rubygems/spec_fetcher" class TestGemSpecFetcher < Gem::TestCase def tuple(*args) @@ -10,7 +11,7 @@ class TestGemSpecFetcher < Gem::TestCase def setup super - @uri = URI.parse @gem_repo + @uri = Gem::URI.parse @gem_repo @source = Gem::Source.new(@uri) @sf = Gem::SpecFetcher.new @@ -23,7 +24,7 @@ class TestGemSpecFetcher < Gem::TestCase end def test_initialize_source - alternate = 'http://alternate.example' + alternate = "http://alternate.example" fetcher = Gem::SpecFetcher.new alternate refute_same Gem.sources, fetcher.sources @@ -38,26 +39,26 @@ class TestGemSpecFetcher < Gem::TestCase end def test_initialize_unwritable_home_dir - skip 'chmod not supported' if Gem.win_platform? + pend "chmod not supported" if Gem.win_platform? - FileUtils.chmod 0000, Gem.user_home + FileUtils.chmod 0o000, Gem.user_home begin assert Gem::SpecFetcher.new ensure - FileUtils.chmod 0755, Gem.user_home + FileUtils.chmod 0o755, Gem.user_home end end def test_spec_for_dependency_all spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', '2.a' - fetcher.spec 'a', 2 - fetcher.spec 'a', '3.a' + fetcher.spec "a", 1 + fetcher.spec "a", "2.a" + fetcher.spec "a", 2 + fetcher.spec "a", "3.a" end - dep = Gem::Dependency.new 'a', ">= 1" + dep = Gem::Dependency.new "a", ">= 1" specs_and_sources, _ = @sf.spec_for_dependency dep @@ -65,7 +66,7 @@ class TestGemSpecFetcher < Gem::TestCase [spec.full_name, source_uri] end - expected = [['a-1', @source], ['a-2', @source]] + expected = [["a-1", @source], ["a-2", @source]] assert_equal expected, spec_names @@ -74,63 +75,59 @@ class TestGemSpecFetcher < Gem::TestCase def test_spec_for_dependency_latest spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', 2 - fetcher.spec 'a', '3.a' + fetcher.spec "a", 1 + fetcher.spec "a", 2 + fetcher.spec "a", "3.a" end - dep = Gem::Dependency.new 'a' + dep = Gem::Dependency.new "a" specs_and_sources, _ = @sf.spec_for_dependency dep spec_names = specs_and_sources.map do |spec, source_uri| [spec.full_name, source_uri] end - assert_equal [['a-2', Gem::Source.new(@gem_repo)]], + assert_equal [["a-2", Gem::Source.new(@gem_repo)]], spec_names end def test_spec_for_dependency_prerelease spec_fetcher do |fetcher| - fetcher.spec 'a', '1.a' - fetcher.spec 'a', 1 + fetcher.spec "a", "1.a" + fetcher.spec "a", 1 end - specs_and_sources, _ = @sf.spec_for_dependency dep('a', '1.a') + specs_and_sources, _ = @sf.spec_for_dependency dep("a", "1.a") spec_names = specs_and_sources.map do |spec, source_uri| [spec.full_name, source_uri] end - assert_equal [['a-1.a', Gem::Source.new(@gem_repo)]], spec_names + assert_equal [["a-1.a", Gem::Source.new(@gem_repo)]], spec_names end def test_spec_for_dependency_platform - util_set_arch 'i386-linux' + util_set_arch "i386-linux" - spec_fetcher do |fetcher| - fetcher.legacy_platform - end + spec_fetcher(&:legacy_platform) - dep = Gem::Dependency.new 'pl', 1 + dep = Gem::Dependency.new "pl", 1 specs_and_sources, _ = @sf.spec_for_dependency dep spec_names = specs_and_sources.map do |spec, source_uri| [spec.full_name, source_uri] end - assert_equal [['pl-1-x86-linux', Gem::Source.new(@gem_repo)]], + assert_equal [["pl-1-x86-linux", Gem::Source.new(@gem_repo)]], spec_names end def test_spec_for_dependency_mismatched_platform - util_set_arch 'hrpa-989' + util_set_arch "hrpa-989" - spec_fetcher do |fetcher| - fetcher.legacy_platform - end + spec_fetcher(&:legacy_platform) - dep = Gem::Dependency.new 'pl', 1 + dep = Gem::Dependency.new "pl", 1 specs_and_sources, errors = @sf.spec_for_dependency dep assert_equal 0, specs_and_sources.size @@ -150,13 +147,13 @@ class TestGemSpecFetcher < Gem::TestCase Gem.sources.replace [src] spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', '2.a' - fetcher.spec 'a', 2 - fetcher.spec 'a', '3.a' + fetcher.spec "a", 1 + fetcher.spec "a", "2.a" + fetcher.spec "a", 2 + fetcher.spec "a", "3.a" end - dep = Gem::Dependency.new 'a', ">= 1" + dep = Gem::Dependency.new "a", ">= 1" specs_and_sources, errors = @sf.spec_for_dependency dep @@ -170,38 +167,38 @@ class TestGemSpecFetcher < Gem::TestCase def test_suggest_gems_from_name_latest spec_fetcher do|fetcher| - fetcher.spec 'example', 1 - fetcher.spec 'other-example', 1 - fetcher.spec 'examp', 1 + fetcher.spec "example", 1 + fetcher.spec "other-example", 1 + fetcher.spec "examp", 1 end - suggestions = @sf.suggest_gems_from_name('examplw', :latest, 1) - assert_equal ['example'], suggestions + suggestions = @sf.suggest_gems_from_name("examplw", :latest, 1) + assert_equal ["example"], suggestions - suggestions = @sf.suggest_gems_from_name('other') - assert_equal ['other-example'], suggestions + suggestions = @sf.suggest_gems_from_name("other") + assert_equal ["other-example"], suggestions - suggestions = @sf.suggest_gems_from_name('exam') - assert suggestions.any? { ['examp'] } - assert suggestions.any? { ['example'] } - assert suggestions.any? { ['other-example'] } + suggestions = @sf.suggest_gems_from_name("exam") + assert suggestions.any? { ["examp"] } + assert suggestions.any? { ["example"] } + assert suggestions.any? { ["other-example"] } end def test_suggest_gems_from_name_prerelease spec_fetcher do|fetcher| - fetcher.spec 'example', '1.a' - fetcher.spec 'other-example', 1 + fetcher.spec "example", "1.a" + fetcher.spec "other-example", 1 end - suggestions = @sf.suggest_gems_from_name('examplw') - assert_equal ['example'], suggestions + suggestions = @sf.suggest_gems_from_name("examplw") + assert_equal ["example"], suggestions end def test_available_specs_latest spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', 2 - fetcher.spec 'a', '3.a' + fetcher.spec "a", 1 + fetcher.spec "a", 2 + fetcher.spec "a", "3.a" fetcher.legacy_platform end @@ -210,15 +207,15 @@ class TestGemSpecFetcher < Gem::TestCase assert_equal [@source], specs.keys expected = Gem::NameTuple.from_list \ - [['a', v(2), Gem::Platform::RUBY], - ['pl', v(1), 'i386-linux']] + [["a", v(2), Gem::Platform::RUBY], + ["pl", v(1), "i386-linux"]] assert_equal expected, specs[@source] end def test_available_specs_released spec_fetcher do |fetcher| - fetcher.spec 'a', 1 + fetcher.spec "a", 1 fetcher.legacy_platform end @@ -227,17 +224,17 @@ class TestGemSpecFetcher < Gem::TestCase assert_equal [@source], specs.keys expected = Gem::NameTuple.from_list \ - [['a', v(1), Gem::Platform::RUBY], - ['pl', v(1), 'i386-linux']] + [["a", v(1), Gem::Platform::RUBY], + ["pl", v(1), "i386-linux"]] assert_equal expected, specs[@source] end def test_available_specs_complete spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', '2.a' - fetcher.spec 'b', 2 + fetcher.spec "a", 1 + fetcher.spec "a", "2.a" + fetcher.spec "b", 2 fetcher.legacy_platform end @@ -246,19 +243,19 @@ class TestGemSpecFetcher < Gem::TestCase assert_equal [@source], specs.keys expected = Gem::NameTuple.from_list \ - [['a', v(1), Gem::Platform::RUBY], - ['a', v('2.a'), Gem::Platform::RUBY], - ['b', v(2), Gem::Platform::RUBY], - ['pl', v(1), 'i386-linux']] + [["a", v(1), Gem::Platform::RUBY], + ["a", v("2.a"), Gem::Platform::RUBY], + ["b", v(2), Gem::Platform::RUBY], + ["pl", v(1), "i386-linux"]] assert_equal expected, specs[@source] end def test_available_specs_complete_handles_no_prerelease spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', '2.a' - fetcher.spec 'b', 2 + fetcher.spec "a", 1 + fetcher.spec "a", "2.a" + fetcher.spec "b", 2 fetcher.legacy_platform end @@ -270,16 +267,16 @@ class TestGemSpecFetcher < Gem::TestCase assert_equal [@source], specs.keys expected = Gem::NameTuple.from_list \ - [['a', v(1), Gem::Platform::RUBY], - ['b', v(2), Gem::Platform::RUBY], - ['pl', v(1), 'i386-linux']] + [["a", v(1), Gem::Platform::RUBY], + ["b", v(2), Gem::Platform::RUBY], + ["pl", v(1), "i386-linux"]] assert_equal expected, specs[@source] end def test_available_specs_cache spec_fetcher do |fetcher| - fetcher.spec 'a', 1 + fetcher.spec "a", 1 end specs, _ = @sf.available_specs(:latest) @@ -295,9 +292,9 @@ class TestGemSpecFetcher < Gem::TestCase def test_available_specs_cache_released spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', '2.a' - fetcher.spec 'b', 2 + fetcher.spec "a", 1 + fetcher.spec "a", "2.a" + fetcher.spec "b", 2 fetcher.legacy_platform end @@ -314,14 +311,14 @@ class TestGemSpecFetcher < Gem::TestCase def test_available_specs_prerelease spec_fetcher do |fetcher| - fetcher.spec 'a', 1 - fetcher.spec 'a', '2.a' + fetcher.spec "a", 1 + fetcher.spec "a", "2.a" end specs, _ = @sf.available_specs(:prerelease) expected = Gem::NameTuple.from_list \ - [['a', v('2.a'), Gem::Platform::RUBY]] + [["a", v("2.a"), Gem::Platform::RUBY]] assert_equal expected, specs[@source] end diff --git a/test/rubygems/test_gem_specification.rb b/test/rubygems/test_gem_specification.rb index d014eaea36..9e05649f7c 100644 --- a/test/rubygems/test_gem_specification.rb +++ b/test/rubygems/test_gem_specification.rb @@ -1,16 +1,17 @@ # frozen_string_literal: true -require 'benchmark' -require 'rubygems/test_case' -require 'date' -require 'pathname' -require 'stringio' -require 'rubygems/ext' -require 'rubygems/specification' -require 'rubygems/installer' -require 'rubygems/platform' + +require "benchmark" +require_relative "helper" +require "date" +require "pathname" +require "stringio" +require "rubygems/ext" +require "rubygems/specification" +require "rubygems/installer" +require "rubygems/platform" class TestGemSpecification < Gem::TestCase - LEGACY_YAML_SPEC = <<-EOF.freeze + LEGACY_YAML_SPEC = <<-EOF --- !ruby/object:Gem::Specification rubygems_version: "1.0" name: keyedlist @@ -29,7 +30,7 @@ email: flgr@ccan.de has_rdoc: true EOF - LEGACY_RUBY_SPEC = <<-EOF.freeze + LEGACY_RUBY_SPEC = <<-EOF Gem::Specification.new do |s| s.name = %q{keyedlist} s.version = %q{0.4.0} @@ -44,16 +45,16 @@ end EOF def make_spec_c1 - @c1 = util_spec 'a', '1' do |s| - s.executable = 'exec' - s.extensions << 'ext/a/extconf.rb' - s.test_file = 'test/suite.rb' - s.requirements << 'A working computer' - s.license = 'MIT' + @c1 = util_spec "a", "1" do |s| + s.executable = "exec" + s.extensions << "ext/a/extconf.rb" + s.test_file = "test/suite.rb" + s.requirements << "A working computer" + s.license = "MIT" - s.add_dependency 'rake', '> 0.4' - s.add_dependency 'jabber4r', '> 0.0.0' - s.add_dependency 'pqa', ['> 0.4', '<= 0.6'] + s.add_dependency "rake", "> 0.4" + s.add_dependency "jabber4r", "> 0.0.0" + s.add_dependency "pqa", ["> 0.4", "<= 0.6"] s.mark_version s.files = %w[lib/code.rb] @@ -61,16 +62,16 @@ end end def ext_spec(platform: Gem::Platform::RUBY) - @ext = util_spec 'ext', '1' do |s| - s.executable = 'exec' - s.test_file = 'test/suite.rb' + @ext = util_spec "ext", "1" do |s| + s.executable = "exec" + s.test_file = "test/suite.rb" s.extensions = %w[ext/extconf.rb] - s.license = 'MIT' + s.license = "MIT" s.platform = platform s.mark_version s.files = %w[lib/code.rb] - s.installed_by_version = v('2.2') + s.installed_by_version = v("2.2") end end @@ -88,306 +89,282 @@ end # is not set. Gem.instance_variable_set(:'@default_source_date_epoch', nil) - @a1 = util_spec 'a', '1' do |s| - s.executable = 'exec' - s.test_file = 'test/suite.rb' - s.requirements << 'A working computer' - s.license = 'MIT' + @a1 = util_spec "a", "1" do |s| + s.required_ruby_version = ">= 2.3.0" + s.executable = "exec" + s.test_file = "test/suite.rb" + s.requirements << "A working computer" + s.license = "MIT" s.mark_version s.files = %w[lib/code.rb] end - @a2 = util_spec 'a', '2' do |s| + @a2 = util_spec "a", "2" do |s| s.files = %w[lib/code.rb] end - @a3 = util_spec 'a', '3' do |s| - s.metadata['allowed_push_host'] = "https://privategemserver.com" + @a3 = util_spec "a", "3" do |s| + s.metadata["allowed_push_host"] = "https://privategemserver.com" end @current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION - - load 'rubygems/syck_hack.rb' end def test_self_find_active_stub_by_path - spec = util_spec('a', '1', nil, 'lib/foo.rb') + spec = util_spec("a", "1", nil, "lib/foo.rb") spec.activated = true # There used to be a bug (introduced in a9c1aaf) when Gem::Specification # objects are present in the @stubs collection. This test verifies that # this scenario works correctly. Gem::Specification.all = [spec] - assert_equal spec, Gem::Specification.find_active_stub_by_path('foo') + assert_equal spec, Gem::Specification.find_active_stub_by_path("foo") end def test_self_activate - foo = util_spec 'foo', '1' + foo = util_spec "foo", "1" assert_activate %w[foo-1], foo end def test_self_activate_ambiguous_direct - save_loaded_features do - a1 = util_spec "a", "1", "b" => "> 0" - b1 = util_spec("b", "1", { "c" => ">= 1" }, "lib/d#{$$}.rb") - b2 = util_spec("b", "2", { "c" => ">= 2" }, "lib/d#{$$}.rb") - c1 = util_spec "c", "1" - c2 = util_spec "c", "2" + a1 = util_spec "a", "1", "b" => "> 0" + b1 = util_spec("b", "1", { "c" => ">= 1" }, "lib/d#{$$}.rb") + b2 = util_spec("b", "2", { "c" => ">= 2" }, "lib/d#{$$}.rb") + c1 = util_spec "c", "1" + c2 = util_spec "c", "2" - Gem::Specification.reset - install_specs c1, c2, b1, b2, a1 + Gem::Specification.reset + install_specs c1, c2, b1, b2, a1 - a1.activate - assert_equal %w[a-1], loaded_spec_names - assert_equal ["b (> 0)"], unresolved_names + a1.activate + assert_equal %w[a-1], loaded_spec_names + assert_equal ["b (> 0)"], unresolved_names - require "d#{$$}" + require "d#{$$}" - assert_equal %w[a-1 b-2 c-2], loaded_spec_names - assert_equal [], unresolved_names - end + assert_equal %w[a-1 b-2 c-2], loaded_spec_names + assert_equal [], unresolved_names end def test_find_in_unresolved_tree_is_not_exponentiental - save_loaded_features do - num_of_pkg = 7 - num_of_version_per_pkg = 3 - packages = (0..num_of_pkg).map do |pkgi| - (0..num_of_version_per_pkg).map do |pkg_version| - deps = Hash[((pkgi + 1)..num_of_pkg).map do |deppkgi| - ["pkg#{deppkgi}", ">= 0"] - end] - util_spec "pkg#{pkgi}", pkg_version.to_s, deps - end + pend "currently slower in CI on TruffleRuby" if RUBY_ENGINE == "truffleruby" + num_of_pkg = 7 + num_of_version_per_pkg = 3 + packages = (0..num_of_pkg).map do |pkgi| + (0..num_of_version_per_pkg).map do |pkg_version| + deps = Hash[((pkgi + 1)..num_of_pkg).map do |deppkgi| + ["pkg#{deppkgi}", ">= 0"] + end] + util_spec "pkg#{pkgi}", pkg_version.to_s, deps end - base = util_spec "pkg_base", "1", {"pkg0" => ">= 0"} + end + base = util_spec "pkg_base", "1", { "pkg0" => ">= 0" } - Gem::Specification.reset - install_specs(*packages.flatten.reverse) - install_specs base - base.activate + Gem::Specification.reset + install_specs(*packages.flatten.reverse) + install_specs base + base.activate - tms = Benchmark.measure do - assert_raise(LoadError) { require 'no_such_file_foo' } - end - assert_operator tms.total, :<=, 10 + tms = Benchmark.measure do + assert_raise(LoadError) { require "no_such_file_foo" } end + assert_operator tms.total, :<=, 10 end def test_self_activate_ambiguous_indirect - save_loaded_features do - a1 = util_spec "a", "1", "b" => "> 0" - b1 = util_spec "b", "1", "c" => ">= 1" - b2 = util_spec "b", "2", "c" => ">= 2" - c1 = util_spec "c", "1", nil, "lib/d#{$$}.rb" - c2 = util_spec "c", "2", nil, "lib/d#{$$}.rb" + a1 = util_spec "a", "1", "b" => "> 0" + b1 = util_spec "b", "1", "c" => ">= 1" + b2 = util_spec "b", "2", "c" => ">= 2" + c1 = util_spec "c", "1", nil, "lib/d#{$$}.rb" + c2 = util_spec "c", "2", nil, "lib/d#{$$}.rb" - install_specs c1, c2, b1, b2, a1 + install_specs c1, c2, b1, b2, a1 - a1.activate - assert_equal %w[a-1], loaded_spec_names - assert_equal ["b (> 0)"], unresolved_names + a1.activate + assert_equal %w[a-1], loaded_spec_names + assert_equal ["b (> 0)"], unresolved_names - require "d#{$$}" + require "d#{$$}" - assert_equal %w[a-1 b-2 c-2], loaded_spec_names - assert_equal [], unresolved_names - end + assert_equal %w[a-1 b-2 c-2], loaded_spec_names + assert_equal [], unresolved_names end def test_self_activate_ambiguous_indirect_conflict - save_loaded_features do - a1 = util_spec "a", "1", "b" => "> 0" - a2 = util_spec "a", "2", "b" => "> 0" - b1 = util_spec "b", "1", "c" => ">= 1" - b2 = util_spec "b", "2", "c" => ">= 2" - c1 = util_spec "c", "1", nil, "lib/d#{$$}.rb" - c2 = util_spec("c", "2", { "a" => "1" }, "lib/d#{$$}.rb") # conflicts with a-2 + a1 = util_spec "a", "1", "b" => "> 0" + a2 = util_spec "a", "2", "b" => "> 0" + b1 = util_spec "b", "1", "c" => ">= 1" + b2 = util_spec "b", "2", "c" => ">= 2" + c1 = util_spec "c", "1", nil, "lib/d#{$$}.rb" + c2 = util_spec("c", "2", { "a" => "1" }, "lib/d#{$$}.rb") # conflicts with a-2 - install_specs c1, b1, a1, a2, c2, b2 + install_specs c1, b1, a1, a2, c2, b2 - a2.activate - assert_equal %w[a-2], loaded_spec_names - assert_equal ["b (> 0)"], unresolved_names + a2.activate + assert_equal %w[a-2], loaded_spec_names + assert_equal ["b (> 0)"], unresolved_names - require "d#{$$}" + require "d#{$$}" - assert_equal %w[a-2 b-1 c-1], loaded_spec_names - assert_equal [], unresolved_names - end + assert_equal %w[a-2 b-1 c-1], loaded_spec_names + assert_equal [], unresolved_names end def test_self_activate_ambiguous_unrelated - save_loaded_features do - a1 = util_spec "a", "1", "b" => "> 0" - b1 = util_spec "b", "1", "c" => ">= 1" - b2 = util_spec "b", "2", "c" => ">= 2" - c1 = util_spec "c", "1" - c2 = util_spec "c", "2" - d1 = util_spec "d", "1", nil, "lib/d#{$$}.rb" + a1 = util_spec "a", "1", "b" => "> 0" + b1 = util_spec "b", "1", "c" => ">= 1" + b2 = util_spec "b", "2", "c" => ">= 2" + c1 = util_spec "c", "1" + c2 = util_spec "c", "2" + d1 = util_spec "d", "1", nil, "lib/d#{$$}.rb" - install_specs d1, c1, c2, b1, b2, a1 + install_specs d1, c1, c2, b1, b2, a1 - a1.activate - assert_equal %w[a-1], loaded_spec_names - assert_equal ["b (> 0)"], unresolved_names + a1.activate + assert_equal %w[a-1], loaded_spec_names + assert_equal ["b (> 0)"], unresolved_names - require "d#{$$}" + require "d#{$$}" - assert_equal %w[a-1 d-1], loaded_spec_names - assert_equal ["b (> 0)"], unresolved_names - end + assert_equal %w[a-1 d-1], loaded_spec_names + assert_equal ["b (> 0)"], unresolved_names end def test_require_should_prefer_latest_gem_level1 - save_loaded_features do - a1 = util_spec "a", "1", "b" => "> 0" - b1 = util_spec "b", "1", "c" => ">= 0" # unresolved - b2 = util_spec "b", "2", "c" => ">= 0" - c1 = util_spec "c", "1", nil, "lib/c#{$$}.rb" # 1st level - c2 = util_spec "c", "2", nil, "lib/c#{$$}.rb" + a1 = util_spec "a", "1", "b" => "> 0" + b1 = util_spec "b", "1", "c" => ">= 0" # unresolved + b2 = util_spec "b", "2", "c" => ">= 0" + c1 = util_spec "c", "1", nil, "lib/c#{$$}.rb" # 1st level + c2 = util_spec "c", "2", nil, "lib/c#{$$}.rb" - install_specs c1, c2, b1, b2, a1 + install_specs c1, c2, b1, b2, a1 - a1.activate + a1.activate - require "c#{$$}" + require "c#{$$}" - assert_equal %w[a-1 b-2 c-2], loaded_spec_names - end + assert_equal %w[a-1 b-2 c-2], loaded_spec_names end def test_require_should_prefer_latest_gem_level2 - save_loaded_features do - a1 = util_spec "a", "1", "b" => "> 0" - b1 = util_spec "b", "1", "c" => ">= 0" # unresolved - b2 = util_spec "b", "2", "c" => ">= 0" - c1 = util_spec "c", "1", "d" => ">= 0" # 1st level - c2 = util_spec "c", "2", "d" => ">= 0" - d1 = util_spec "d", "1", nil, "lib/d#{$$}.rb" # 2nd level - d2 = util_spec "d", "2", nil, "lib/d#{$$}.rb" + a1 = util_spec "a", "1", "b" => "> 0" + b1 = util_spec "b", "1", "c" => ">= 0" # unresolved + b2 = util_spec "b", "2", "c" => ">= 0" + c1 = util_spec "c", "1", "d" => ">= 0" # 1st level + c2 = util_spec "c", "2", "d" => ">= 0" + d1 = util_spec "d", "1", nil, "lib/d#{$$}.rb" # 2nd level + d2 = util_spec "d", "2", nil, "lib/d#{$$}.rb" - install_specs d1, d2, c1, c2, b1, b2, a1 + install_specs d1, d2, c1, c2, b1, b2, a1 - a1.activate + a1.activate - require "d#{$$}" + require "d#{$$}" - assert_equal %w[a-1 b-2 c-2 d-2], loaded_spec_names - end + assert_equal %w[a-1 b-2 c-2 d-2], loaded_spec_names end def test_require_finds_in_2nd_level_indirect - save_loaded_features do - a1 = util_spec "a", "1", "b" => "> 0" - b1 = util_spec "b", "1", "c" => ">= 0" # unresolved - b2 = util_spec "b", "2", "c" => ">= 0" - c1 = util_spec "c", "1", "d" => "<= 2" # 1st level - c2 = util_spec "c", "2", "d" => "<= 2" - d1 = util_spec "d", "1", nil, "lib/d#{$$}.rb" # 2nd level - d2 = util_spec "d", "2", nil, "lib/d#{$$}.rb" - d3 = util_spec "d", "3", nil, "lib/d#{$$}.rb" + a1 = util_spec "a", "1", "b" => "> 0" + b1 = util_spec "b", "1", "c" => ">= 0" # unresolved + b2 = util_spec "b", "2", "c" => ">= 0" + c1 = util_spec "c", "1", "d" => "<= 2" # 1st level + c2 = util_spec "c", "2", "d" => "<= 2" + d1 = util_spec "d", "1", nil, "lib/d#{$$}.rb" # 2nd level + d2 = util_spec "d", "2", nil, "lib/d#{$$}.rb" + d3 = util_spec "d", "3", nil, "lib/d#{$$}.rb" - install_specs d1, d2, d3, c1, c2, b1, b2, a1 + install_specs d1, d2, d3, c1, c2, b1, b2, a1 - a1.activate + a1.activate - require "d#{$$}" + require "d#{$$}" - assert_equal %w[a-1 b-2 c-2 d-2], loaded_spec_names - end + assert_equal %w[a-1 b-2 c-2 d-2], loaded_spec_names end def test_require_should_prefer_reachable_gems - save_loaded_features do - a1 = util_spec "a", "1", "b" => "> 0" - b1 = util_spec "b", "1", "c" => ">= 0" # unresolved - b2 = util_spec "b", "2", "c" => ">= 0" - c1 = util_spec "c", "1", "d" => "<= 2" # 1st level - c2 = util_spec "c", "2", "d" => "<= 2" - d1 = util_spec "d", "1", nil, "lib/d#{$$}.rb" # 2nd level - d2 = util_spec "d", "2", nil, "lib/d#{$$}.rb" - d3 = util_spec "d", "3", nil, "lib/d#{$$}.rb" - e = util_spec "anti_d", "1", nil, "lib/d#{$$}.rb" + a1 = util_spec "a", "1", "b" => "> 0" + b1 = util_spec "b", "1", "c" => ">= 0" # unresolved + b2 = util_spec "b", "2", "c" => ">= 0" + c1 = util_spec "c", "1", "d" => "<= 2" # 1st level + c2 = util_spec "c", "2", "d" => "<= 2" + d1 = util_spec "d", "1", nil, "lib/d#{$$}.rb" # 2nd level + d2 = util_spec "d", "2", nil, "lib/d#{$$}.rb" + d3 = util_spec "d", "3", nil, "lib/d#{$$}.rb" + e = util_spec "anti_d", "1", nil, "lib/d#{$$}.rb" + + install_specs d1, d2, d3, e, c1, c2, b1, b2, a1 - install_specs d1, d2, d3, e, c1, c2, b1, b2, a1 - - a1.activate + a1.activate - require "d#{$$}" + require "d#{$$}" - assert_equal %w[a-1 b-2 c-2 d-2], loaded_spec_names - end + assert_equal %w[a-1 b-2 c-2 d-2], loaded_spec_names end def test_require_should_not_conflict - save_loaded_features do - base = util_spec "0", "1", "A" => ">= 1" - a1 = util_spec "A", "1", {"c" => ">= 2", "b" => "> 0"}, "lib/a.rb" - a2 = util_spec "A", "2", {"c" => ">= 2", "b" => "> 0"}, "lib/a.rb" - b1 = util_spec "b", "1", {"c" => "= 1"}, "lib/d#{$$}.rb" - b2 = util_spec "b", "2", {"c" => "= 2"}, "lib/d#{$$}.rb" - c1 = util_spec "c", "1", {}, "lib/c.rb" - c2 = util_spec "c", "2", {}, "lib/c.rb" - c3 = util_spec "c", "3", {}, "lib/c.rb" - - install_specs c1, c2, c3, b1, b2, a1, a2, base - - base.activate - assert_equal %w[0-1], loaded_spec_names - assert_equal ["A (>= 1)"], unresolved_names + base = util_spec "0", "1", "A" => ">= 1" + a1 = util_spec "A", "1", { "c" => ">= 2", "b" => "> 0" }, "lib/a.rb" + a2 = util_spec "A", "2", { "c" => ">= 2", "b" => "> 0" }, "lib/a.rb" + b1 = util_spec "b", "1", { "c" => "= 1" }, "lib/d#{$$}.rb" + b2 = util_spec "b", "2", { "c" => "= 2" }, "lib/d#{$$}.rb" + c1 = util_spec "c", "1", {}, "lib/c.rb" + c2 = util_spec "c", "2", {}, "lib/c.rb" + c3 = util_spec "c", "3", {}, "lib/c.rb" - require "d#{$$}" + install_specs c1, c2, c3, b1, b2, a1, a2, base - assert_equal %w[0-1 A-2 b-2 c-2], loaded_spec_names - assert_equal [], unresolved_names - end + base.activate + assert_equal %w[0-1], loaded_spec_names + assert_equal ["A (>= 1)"], unresolved_names + + require "d#{$$}" + + assert_equal %w[0-1 A-2 b-2 c-2], loaded_spec_names + assert_equal [], unresolved_names end def test_inner_clonflict_in_indirect_gems - save_loaded_features do - a1 = util_spec "a", "1", "b" => "> 0" - b1 = util_spec "b", "1", "c" => ">= 1" # unresolved - b2 = util_spec "b", "2", "c" => ">= 1", "d" => "< 3" - c1 = util_spec "c", "1", "d" => "<= 2" # 1st level - c2 = util_spec "c", "2", "d" => "<= 2" - c3 = util_spec "c", "3", "d" => "<= 3" - d1 = util_spec "d", "1", nil, "lib/d#{$$}.rb" # 2nd level - d2 = util_spec "d", "2", nil, "lib/d#{$$}.rb" - d3 = util_spec "d", "3", nil, "lib/d#{$$}.rb" - - install_specs d1, d2, d3, c1, c2, c3, b1, b2, a1 + a1 = util_spec "a", "1", "b" => "> 0" + b1 = util_spec "b", "1", "c" => ">= 1" # unresolved + b2 = util_spec "b", "2", "c" => ">= 1", "d" => "< 3" + c1 = util_spec "c", "1", "d" => "<= 2" # 1st level + c2 = util_spec "c", "2", "d" => "<= 2" + c3 = util_spec "c", "3", "d" => "<= 3" + d1 = util_spec "d", "1", nil, "lib/d#{$$}.rb" # 2nd level + d2 = util_spec "d", "2", nil, "lib/d#{$$}.rb" + d3 = util_spec "d", "3", nil, "lib/d#{$$}.rb" + + install_specs d1, d2, d3, c1, c2, c3, b1, b2, a1 - a1.activate + a1.activate - require "d#{$$}" + require "d#{$$}" - assert_includes [%w[a-1 b-2 c-3 d-2],%w[a-1 b-2 d-2]], loaded_spec_names - end + assert_includes [%w[a-1 b-2 c-3 d-2],%w[a-1 b-2 d-2]], loaded_spec_names end def test_inner_clonflict_in_indirect_gems_reversed - save_loaded_features do - a1 = util_spec "a", "1", "b" => "> 0" - b1 = util_spec "b", "1", "xc" => ">= 1" # unresolved - b2 = util_spec "b", "2", "xc" => ">= 1", "d" => "< 3" - c1 = util_spec "xc", "1", "d" => "<= 3" # 1st level - c2 = util_spec "xc", "2", "d" => "<= 2" - c3 = util_spec "xc", "3", "d" => "<= 3" - d1 = util_spec "d", "1", nil, "lib/d#{$$}.rb" # 2nd level - d2 = util_spec "d", "2", nil, "lib/d#{$$}.rb" - d3 = util_spec "d", "3", nil, "lib/d#{$$}.rb" - - install_specs d1, d2, d3, c1, c2, c3, b1, b2, a1 + a1 = util_spec "a", "1", "b" => "> 0" + b1 = util_spec "b", "1", "xc" => ">= 1" # unresolved + b2 = util_spec "b", "2", "xc" => ">= 1", "d" => "< 3" + c1 = util_spec "xc", "1", "d" => "<= 3" # 1st level + c2 = util_spec "xc", "2", "d" => "<= 2" + c3 = util_spec "xc", "3", "d" => "<= 3" + d1 = util_spec "d", "1", nil, "lib/d#{$$}.rb" # 2nd level + d2 = util_spec "d", "2", nil, "lib/d#{$$}.rb" + d3 = util_spec "d", "3", nil, "lib/d#{$$}.rb" + + install_specs d1, d2, d3, c1, c2, c3, b1, b2, a1 - a1.activate + a1.activate - require "d#{$$}" + require "d#{$$}" - assert_includes [%w[a-1 b-2 d-2 xc-3], %w[a-1 b-2 d-2]], loaded_spec_names - end + assert_includes [%w[a-1 b-2 d-2 xc-3], %w[a-1 b-2 d-2]], loaded_spec_names end ## @@ -397,13 +374,13 @@ end # [B] ~> 1.0 (satisfied by 1.0) def test_self_activate_checks_dependencies - a = util_spec 'a', '1.0' - a.add_dependency 'c', '= 1.0' - a.add_dependency 'b', '~> 1.0' + a = util_spec "a", "1.0" + a.add_dependency "c", "= 1.0" + a.add_dependency "b", "~> 1.0" - b1 = util_spec 'b', '1.0' - b2 = util_spec 'b', '2.0' - c = util_spec 'c', '1.0', 'b' => '= 2.0' + b1 = util_spec "b", "1.0" + b2 = util_spec "b", "2.0" + c = util_spec "c", "1.0", "b" => "= 2.0" install_specs b1, b2, c, a e = assert_raise Gem::LoadError do @@ -421,10 +398,10 @@ end # [B] = 2.0 def test_self_activate_divergent - a = util_spec 'a', '1.0', 'b' => '~> 1.0', 'c' => '= 1.0' - b1 = util_spec 'b', '1.0' - b2 = util_spec 'b', '2.0' - c = util_spec 'c', '1.0', 'b' => '= 2.0' + a = util_spec "a", "1.0", "b" => "~> 1.0", "c" => "= 1.0" + b1 = util_spec "b", "1.0" + b2 = util_spec "b", "2.0" + c = util_spec "c", "1.0", "b" => "= 2.0" install_specs b1, b2, c, a @@ -440,9 +417,9 @@ end # DOC def test_self_activate_old_required - e1, = util_spec 'e', '1', 'd' => '= 1' - @d1 = util_spec 'd', '1' - @d2 = util_spec 'd', '2' + e1, = util_spec "e", "1", "d" => "= 1" + @d1 = util_spec "d", "1" + @d2 = util_spec "d", "2" install_specs @d1, @d2, e1 @@ -453,17 +430,17 @@ end # DOC def test_self_activate_platform_alternate - @x1_m = util_spec 'x', '1' do |s| + @x1_m = util_spec "x", "1" do |s| s.platform = Gem::Platform.new %w[cpu my_platform 1] end - @x1_o = util_spec 'x', '1' do |s| + @x1_o = util_spec "x", "1" do |s| s.platform = Gem::Platform.new %w[cpu other_platform 1] end - @w1 = util_spec 'w', '1', 'x' => nil + @w1 = util_spec "w", "1", "x" => nil - util_set_arch 'cpu-my_platform1' + util_set_arch "cpu-my_platform1" install_specs @x1_m, @x1_o, @w1 assert_activate %w[x-1-cpu-my_platform-1 w-1], @w1, @x1_m @@ -473,13 +450,13 @@ end # DOC def test_self_activate_platform_bump - @y1 = util_spec 'y', '1' + @y1 = util_spec "y", "1" - @y1_1_p = util_spec 'y', '1.1' do |s| + @y1_1_p = util_spec "y", "1.1" do |s| s.platform = Gem::Platform.new %w[cpu my_platform 1] end - @z1 = util_spec 'z', '1', 'y' => nil + @z1 = util_spec "z", "1", "y" => nil install_specs @y1, @y1_1_p, @z1 assert_activate %w[y-1 z-1], @z1, @y1 @@ -492,11 +469,11 @@ end # [A] >= 0 (satisfied by 1.a) def test_self_activate_prerelease - @c1_pre = util_spec 'c', '1.a', "a" => "1.a", "b" => "1" - @a1_pre = util_spec 'a', '1.a' - @b1 = util_spec 'b', '1' do |s| - s.add_dependency 'a' - s.add_development_dependency 'aa' + @c1_pre = util_spec "c", "1.a", "a" => "1.a", "b" => "1" + @a1_pre = util_spec "a", "1.a" + @b1 = util_spec "b", "1" do |s| + s.add_dependency "a" + s.add_development_dependency "aa" end install_specs @a1_pre, @b1, @c1_pre @@ -511,41 +488,37 @@ end install_specs b1, b2, a1 a1.activate - save_loaded_features do - require "b/c" - end + require "b/c" assert_equal %w[a-1 b-1], loaded_spec_names end def test_self_activate_via_require_wtf - save_loaded_features do - a1 = util_spec "a", "1", "b" => "> 0", "d" => "> 0" # this - b1 = util_spec "b", "1", { "c" => ">= 1" }, "lib/b#{$$}.rb" - b2 = util_spec "b", "2", { "c" => ">= 2" }, "lib/b#{$$}.rb" # this - c1 = util_spec "c", "1" - c2 = util_spec "c", "2" # this - d1 = util_spec "d", "1", { "c" => "< 2" }, "lib/d#{$$}.rb" - d2 = util_spec "d", "2", { "c" => "< 2" }, "lib/d#{$$}.rb" # this + a1 = util_spec "a", "1", "b" => "> 0", "d" => "> 0" # this + b1 = util_spec "b", "1", { "c" => ">= 1" }, "lib/b#{$$}.rb" + b2 = util_spec "b", "2", { "c" => ">= 2" }, "lib/b#{$$}.rb" # this + c1 = util_spec "c", "1" + c2 = util_spec "c", "2" # this + d1 = util_spec "d", "1", { "c" => "< 2" }, "lib/d#{$$}.rb" + d2 = util_spec "d", "2", { "c" => "< 2" }, "lib/d#{$$}.rb" # this - install_specs c1, c2, b1, b2, d1, d2, a1 + install_specs c1, c2, b1, b2, d1, d2, a1 - a1.activate + a1.activate - assert_equal %w[a-1], loaded_spec_names - assert_equal ["b (> 0)", "d (> 0)"], unresolved_names + assert_equal %w[a-1], loaded_spec_names + assert_equal ["b (> 0)", "d (> 0)"], unresolved_names - require "b#{$$}" + require "b#{$$}" - e = assert_raise Gem::LoadError do - require "d#{$$}" - end + e = assert_raise Gem::LoadError do + require "d#{$$}" + end - assert_equal "unable to find a version of 'd' to activate", e.message + 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 + assert_equal %w[a-1 b-2 c-2], loaded_spec_names + assert_equal ["d (> 0)"], unresolved_names end def test_self_activate_deep_unambiguous @@ -562,7 +535,7 @@ end end def test_self_activate_loaded - foo = util_spec 'foo', '1' + foo = util_spec "foo", "1" assert foo.activate refute foo.activate @@ -574,9 +547,9 @@ end # [C] depends on nothing def test_self_activate_unrelated - a = util_spec 'a', '1.0', 'b' => '>= 1.0' - b = util_spec 'b', '1.0' - c = util_spec 'c', '1.0' + a = util_spec "a", "1.0", "b" => ">= 1.0" + b = util_spec "b", "1.0" + c = util_spec "c", "1.0" install_specs b, c, a assert_activate %w[b-1.0 c-1.0 a-1.0], a, c, "b" @@ -592,11 +565,11 @@ end # TODO: move these to specification def test_self_activate_over - a = util_spec 'a', '1.0', 'b' => '>= 1.0', 'c' => '= 1.0' - install_specs util_spec 'b', '1.0' - install_specs util_spec 'b', '1.1' - install_specs util_spec 'b', '2.0' - install_specs util_spec 'c', '1.0', 'b' => '~> 1.0' + a = util_spec "a", "1.0", "b" => ">= 1.0", "c" => "= 1.0" + install_specs util_spec "b", "1.0" + install_specs util_spec "b", "1.1" + install_specs util_spec "b", "2.0" + install_specs util_spec "c", "1.0", "b" => "~> 1.0" install_specs a a.activate @@ -617,10 +590,10 @@ end # first resolve through a dependency that is later pruned. def test_self_activate_under - a = util_spec 'a', '1.0', 'b' => '~> 1.0', 'c' => '= 1.0' - b1 = util_spec 'b', '1.0' - b1_1 = util_spec 'b', '1.1' - c = util_spec 'c', '1.0', 'b' => '= 1.0' + a = util_spec "a", "1.0", "b" => "~> 1.0", "c" => "= 1.0" + b1 = util_spec "b", "1.0" + b1_1 = util_spec "b", "1.1" + c = util_spec "c", "1.0", "b" => "= 1.0" install_specs b1, b1_1, c, a @@ -636,10 +609,10 @@ end # [C1] depends on nothing def test_self_activate_dropped - a1 = util_spec 'a', '1', 'b' => nil - b1 = util_spec 'b', '1', 'c' => nil - b2 = util_spec 'b', '2' - c1 = util_spec 'c', '1' + a1 = util_spec "a", "1", "b" => nil + b1 = util_spec "b", "1", "c" => nil + b2 = util_spec "b", "2" + c1 = util_spec "c", "1" install_specs c1, b1, b2, a1 assert_activate %w[b-2 a-1], a1, "b" @@ -656,11 +629,11 @@ end # resolve. def test_self_activate_raggi_the_edgecase_generator - a = util_spec 'a', '1.0', 'b' => '>= 1.0', 'c' => '>= 1.0' - b1 = util_spec 'b', '1.0' - b1_0 = util_spec 'b', '1.1', 'z' => '>= 1.0' - c = util_spec 'c', '1.0', 'b' => '= 1.0' - z = util_spec 'z', '1' + a = util_spec "a", "1.0", "b" => ">= 1.0", "c" => ">= 1.0" + b1 = util_spec "b", "1.0" + b1_0 = util_spec "b", "1.1", "z" => ">= 1.0" + c = util_spec "c", "1.0", "b" => "= 1.0" + z = util_spec "z", "1" install_specs z, b1, b1_0, c, z @@ -668,8 +641,8 @@ end end def test_self_activate_conflict - install_specs util_spec 'b', '1.0' - install_specs util_spec 'b', '2.0' + install_specs util_spec "b", "1.0" + install_specs util_spec "b", "2.0" gem "b", "= 1.0" @@ -684,7 +657,7 @@ end install_specs a Gem::Specification.all = [a] - assert_equal a, Gem::Specification.find_inactive_by_path('foo') + assert_equal a, Gem::Specification.find_inactive_by_path("foo") end def test_self_attribute_names @@ -720,20 +693,20 @@ end version ] - actual_value = Gem::Specification.attribute_names.map {|a| a.to_s }.sort + actual_value = Gem::Specification.attribute_names.map(&:to_s).sort assert_equal expected_value, actual_value end def test_self__load_future spec = Gem::Specification.new - spec.name = 'a' - spec.version = '1' + spec.name = "a" + spec.version = "1" spec.specification_version = @current_version + 1 load_spec = Marshal.load Marshal.dump(spec) - assert_equal 'a', load_spec.name + assert_equal "a", load_spec.name assert_equal Gem::Version.new(1), load_spec.version assert_equal @current_version, load_spec.specification_version end @@ -747,125 +720,6 @@ end spec.specification_version end - def test_self_from_yaml_syck_date_bug - # This is equivalent to (and totally valid) psych 1.0 output and - # causes parse errors on syck. - yaml = @a1.to_yaml - yaml.sub!(/^date:.*/, "date: 2011-04-26 00:00:00.000000000Z") - - spec = with_syck do - Gem::Specification.from_yaml yaml - end - - assert_kind_of Time, @a1.date - assert_kind_of Time, spec.date - end - - def test_self_from_yaml_syck_default_key_bug - # This is equivalent to (and totally valid) psych 1.0 output and - # causes parse errors on syck. - yaml = <<-YAML ---- !ruby/object:Gem::Specification -name: posix-spawn -version: !ruby/object:Gem::Version - version: 0.3.6 - prerelease: -dependencies: -- !ruby/object:Gem::Dependency - name: rake-compiler - requirement: &70243867725240 !ruby/object:Gem::Requirement - none: false - requirements: - - - = - - !ruby/object:Gem::Version - version: 0.7.6 - type: :development - prerelease: false - version_requirements: *70243867725240 -platform: ruby -files: [] -test_files: [] -bindir: - YAML - - spec = with_syck do - Gem::Specification.from_yaml yaml - end - - op = spec.dependencies.first.requirement.requirements.first.first - refute_kind_of YAML::Syck::DefaultKey, op - - refute_match %r{DefaultKey}, spec.to_ruby - end - - def test_self_from_yaml_cleans_up_defaultkey - yaml = <<-YAML ---- !ruby/object:Gem::Specification -name: posix-spawn -version: !ruby/object:Gem::Version - version: 0.3.6 - prerelease: -dependencies: -- !ruby/object:Gem::Dependency - name: rake-compiler - requirement: &70243867725240 !ruby/object:Gem::Requirement - none: false - requirements: - - - !ruby/object:YAML::Syck::DefaultKey {} - - - !ruby/object:Gem::Version - version: 0.7.6 - type: :development - prerelease: false - version_requirements: *70243867725240 -platform: ruby -files: [] -test_files: [] -bindir: - YAML - - spec = Gem::Specification.from_yaml yaml - - op = spec.dependencies.first.requirement.requirements.first.first - refute_kind_of YAML::Syck::DefaultKey, op - - refute_match %r{DefaultKey}, spec.to_ruby - end - - def test_self_from_yaml_cleans_up_defaultkey_from_newer_192 - yaml = <<-YAML ---- !ruby/object:Gem::Specification -name: posix-spawn -version: !ruby/object:Gem::Version - version: 0.3.6 - prerelease: -dependencies: -- !ruby/object:Gem::Dependency - name: rake-compiler - requirement: &70243867725240 !ruby/object:Gem::Requirement - none: false - requirements: - - - !ruby/object:Syck::DefaultKey {} - - - !ruby/object:Gem::Version - version: 0.7.6 - type: :development - prerelease: false - version_requirements: *70243867725240 -platform: ruby -files: [] -test_files: [] -bindir: - YAML - - spec = Gem::Specification.from_yaml yaml - - op = spec.dependencies.first.requirement.requirements.first.first - refute_kind_of YAML::Syck::DefaultKey, op - - refute_match %r{DefaultKey}, spec.to_ruby - end - def test_self_from_yaml_cleans_up_Date_objects yaml = <<-YAML --- !ruby/object:Gem::Specification @@ -931,37 +785,17 @@ dependencies: [] end def test_self_load_relative - File.open 'a-2.gemspec', 'w' do |io| + File.open "a-2.gemspec", "w" do |io| io.write @a2.to_ruby_for_cache end - spec = Gem::Specification.load 'a-2.gemspec' + spec = Gem::Specification.load "a-2.gemspec" @a2.files.clear assert_equal @a2, spec - assert_equal File.join(@tempdir, 'a-2.gemspec'), spec.loaded_from - end - - if RUBY_ENGINE == 'ruby' and RUBY_VERSION < '2.7' - 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 - - ensure - $SAFE = 0 - end + assert_equal File.join(@tempdir, "a-2.gemspec"), spec.loaded_from end def test_self_load_escape_curly @@ -973,7 +807,7 @@ dependencies: [] io.write @a2.to_ruby_for_cache end rescue Errno::EINVAL - skip "cannot create '#{full_path}' on this platform" + pend "cannot create '#{full_path}' on this platform" end spec = Gem::Specification.load full_path @@ -992,7 +826,7 @@ dependencies: [] io.write @a2.to_ruby_for_cache end rescue Errno::EINVAL - skip "cannot create '#{full_path}' on this platform" + pend "cannot create '#{full_path}' on this platform" end spec = Gem::Specification.load full_path @@ -1011,7 +845,7 @@ dependencies: [] io.write @a2.to_ruby_for_cache end rescue Errno::EINVAL - skip "cannot create '#{full_path}' on this platform" + pend "cannot create '#{full_path}' on this platform" end spec = Gem::Specification.load full_path @@ -1022,34 +856,31 @@ dependencies: [] end def test_self_load_utf8_with_ascii_encoding - int_enc = Encoding.default_internal - silence_warnings { Encoding.default_internal = 'US-ASCII' } - - spec2 = @a2.dup - bin = "\u5678".dup - spec2.authors = [bin] - full_path = spec2.spec_file - write_file full_path do |io| - io.write spec2.to_ruby_for_cache.force_encoding('BINARY').sub("\\u{5678}", bin.force_encoding('BINARY')) - end + with_internal_encoding("US-ASCII") do + spec2 = @a2.dup + bin = "\u5678".dup + spec2.authors = [bin] + full_path = spec2.spec_file + write_file full_path do |io| + io.write spec2.to_ruby_for_cache.force_encoding("BINARY").sub("\\u{5678}", bin.force_encoding("BINARY")) + end - spec = Gem::Specification.load full_path + spec = Gem::Specification.load full_path - spec2.files.clear + spec2.files.clear - assert_equal spec2, spec - ensure - silence_warnings { Encoding.default_internal = int_enc } + assert_equal spec2, spec + end end def test_self_load_legacy_ruby spec = Gem::Deprecate.skip_during do eval LEGACY_RUBY_SPEC end - assert_equal 'keyedlist', spec.name - assert_equal '0.4.0', spec.version.to_s + assert_equal "keyedlist", spec.name + assert_equal "0.4.0", spec.version.to_s assert_kind_of Time, spec.date - assert spec.required_ruby_version.satisfied_by?(Gem::Version.new('1')) + assert spec.required_ruby_version.satisfied_by?(Gem::Version.new("1")) assert_equal false, spec.has_unit_tests? end @@ -1084,26 +915,26 @@ dependencies: [] def test_self_outdated spec_fetcher do |fetcher| - fetcher.download 'a', 4 + fetcher.download "a", 4 - fetcher.spec 'a', 3 + fetcher.spec "a", 3 end assert_equal %w[a], Gem::Specification.outdated end def test_self_outdated_and_latest_remotes - specs = spec_fetcher do |fetcher| - fetcher.download 'a', 4 - fetcher.download 'b', 3 + spec_fetcher do |fetcher| + fetcher.download "a", 4 + fetcher.download "b", 3 - fetcher.spec 'a', '3.a' - fetcher.spec 'b', 2 + fetcher.spec "a", "3.a" + fetcher.spec "b", 2 end expected = [ - [specs['a-3.a'], v(4)], - [specs['b-2'], v(3)], + [Gem::Specification.stubs.find {|s| s.full_name == "a-3.a" }, v(4)], + [Gem::Specification.stubs.find {|s| s.full_name == "b-2" }, v(3)], ] assert_equal expected, Gem::Specification.outdated_and_latest_version.to_a @@ -1112,18 +943,18 @@ dependencies: [] def test_self_remove_spec install_specs @a1 - assert_includes Gem::Specification.all_names, 'a-1' - assert_includes Gem::Specification.stubs.map {|s| s.full_name }, 'a-1' + assert_includes Gem::Specification.all_names, "a-1" + assert_includes Gem::Specification.stubs.map(&:full_name), "a-1" uninstall_gem @a1 Gem::Specification.reset - refute_includes Gem::Specification.all_names, 'a-1' - refute_includes Gem::Specification.stubs.map {|s| s.full_name }, 'a-1' + refute_includes Gem::Specification.all_names, "a-1" + refute_includes Gem::Specification.stubs.map(&:full_name), "a-1" end def test_self_remove_spec_removed - File.open @a1.spec_file, 'w' do |io| + File.open @a1.spec_file, "w" do |io| io.write @a1.to_ruby end @@ -1133,40 +964,40 @@ dependencies: [] Gem::Specification.reset - refute_includes Gem::Specification.all_names, 'a-1' - refute_includes Gem::Specification.stubs.map {|s| s.full_name }, 'a-1' + refute_includes Gem::Specification.all_names, "a-1" + refute_includes Gem::Specification.stubs.map(&:full_name), "a-1" end def test_self_stubs_for_lazy_loading Gem.loaded_specs.clear Gem::Specification.class_variable_set(:@@stubs, nil) - dir_standard_specs = File.join Gem.dir, 'specifications' + dir_standard_specs = File.join Gem.dir, "specifications" - save_gemspec('a-1', '1', dir_standard_specs){|s| s.name = 'a' } - save_gemspec('b-1', '1', dir_standard_specs){|s| s.name = 'b' } + save_gemspec("a-1", "1", dir_standard_specs) {|s| s.name = "a" } + save_gemspec("b-1", "1", dir_standard_specs) {|s| s.name = "b" } - assert_equal ['a-1'], Gem::Specification.stubs_for('a').map {|s| s.full_name } + assert_equal ["a-1"], Gem::Specification.stubs_for("a").map(&:full_name) assert_equal 1, Gem::Specification.class_variable_get(:@@stubs_by_name).length - assert_equal ['b-1'], Gem::Specification.stubs_for('b').map {|s| s.full_name } + assert_equal ["b-1"], Gem::Specification.stubs_for("b").map(&:full_name) assert_equal 2, Gem::Specification.class_variable_get(:@@stubs_by_name).length assert_equal( - Gem::Specification.stubs_for('a').map {|s| s.object_id }, - Gem::Specification.stubs_for('a').map {|s| s.object_id } + Gem::Specification.stubs_for("a").map(&:object_id), + Gem::Specification.stubs_for("a").map(&:object_id) ) - Gem.loaded_specs.delete 'a' - Gem.loaded_specs.delete 'b' + Gem.loaded_specs.delete "a" + Gem.loaded_specs.delete "b" Gem::Specification.class_variable_set(:@@stubs, nil) end def test_self_stubs_for_no_lazy_loading_after_all_specs_setup - Gem::Specification.all = [util_spec('a', '1')] + Gem::Specification.all = [util_spec("a", "1")] - save_gemspec('b-1', '1', File.join(Gem.dir, 'specifications')){|s| s.name = 'b' } + save_gemspec("b-1", "1", File.join(Gem.dir, "specifications")) {|s| s.name = "b" } - assert_equal [], Gem::Specification.stubs_for('b').map {|s| s.full_name } + assert_equal [], Gem::Specification.stubs_for("b").map(&:full_name) end def test_self_stubs_for_mult_platforms @@ -1176,30 +1007,30 @@ dependencies: [] orig_platform = Gem.platforms.dup # create user spec - user_spec_dir = File.join Gem.user_dir, 'specifications' + user_spec_dir = File.join Gem.user_dir, "specifications" FileUtils.mkdir_p(user_spec_dir) unless Dir.exist? user_spec_dir # dirs doesn't include user ? Gem::Specification.dirs << user_spec_dir - gem = 'mingw' - v = '1.1.1' - platforms = ['x86-mingw32', 'x64-mingw32'] + gem = "mingw" + v = "1.1.1" + platforms = ["x86-mingw32", "x64-mingw32"] - #create specs + # create specs platforms.each do |plat| spec = Gem::Specification.new(gem, v) {|s| s.platform = plat } - File.open File.join(user_spec_dir, "#{gem}-#{v}-#{plat}.gemspec"), 'w' do |io| + File.open File.join(user_spec_dir, "#{gem}-#{v}-#{plat}.gemspec"), "w" do |io| io.write spec.to_ruby end end platforms.each do |plat| cur_plat = Gem::Platform.new plat - Gem.platforms = ['ruby', cur_plat] + Gem.platforms = ["ruby", cur_plat] Gem::Specification.class_variable_set :@@stubs, nil Gem::Specification.stubs if plat == platforms.last # test loading via stubs - t = Gem::Specification.stubs_for 'mingw' + t = Gem::Specification.stubs_for "mingw" assert_equal 1, t.length assert_equal cur_plat, t.first.platform @@ -1209,21 +1040,56 @@ dependencies: [] end def test_self_stubs_returns_only_specified_named_specs - dir_standard_specs = File.join Gem.dir, 'specifications' + dir_standard_specs = File.join Gem.dir, "specifications" - save_gemspec('a-1', '1', dir_standard_specs){|s| s.name = 'a' } - save_gemspec('a-2', '2', dir_standard_specs){|s| s.name = 'a' } - save_gemspec('a-a', '3', dir_standard_specs){|s| s.name = 'a-a' } + save_gemspec("a-1", "1", dir_standard_specs) {|s| s.name = "a" } + save_gemspec("a-2", "2", dir_standard_specs) {|s| s.name = "a" } + save_gemspec("a-a", "3", dir_standard_specs) {|s| s.name = "a-a" } - assert_equal ['a-1', 'a-2'], Gem::Specification.stubs_for('a').map(&:full_name).sort + assert_equal ["a-1", "a-2"], Gem::Specification.stubs_for("a").map(&:full_name).sort end def test_handles_private_null_type - path = File.expand_path "../data/null-type.gemspec.rz", __FILE__ + yaml_defined = Object.const_defined?("YAML") + + path = File.expand_path "data/pry-0.4.7.gemspec.rz", __dir__ data = Marshal.load Gem::Util.inflate(Gem.read_binary(path)) - assert_nil data.signing_key + assert_instance_of Gem::Specification, data + + assert_equal(yaml_defined, Object.const_defined?("YAML")) + end + + def test_handles_dependencies_with_syck_requirements_bug + yaml_defined = Object.const_defined?("YAML") + + path = File.expand_path "data/excon-0.7.7.gemspec.rz", __dir__ + + data = Marshal.load Gem::Util.inflate(Gem.read_binary(path)) + + assert_instance_of Gem::Specification, data + + assert_equal(yaml_defined, Object.const_defined?("YAML")) + end + + def test_handles_dependencies_with_other_syck_requirements_argument_error + yaml_defined = Object.const_defined?("YAML") + + data = Marshal.dump(Gem::Specification.new do |s| + v = Gem::Version.allocate + v.instance_variable_set :@version, "YAML::Syck::DefaultKey" + s.instance_variable_set :@version, v + end) + + assert_raise(ArgumentError) { Marshal.load(data) } + out, err = capture_output do + assert_raise(ArgumentError) { Marshal.load(data) } + end + assert_empty out + assert_empty err + + assert_equal(yaml_defined, Object.const_defined?("YAML")) end def test_initialize @@ -1245,9 +1111,9 @@ dependencies: [] assert_equal [], spec.extensions assert_equal [], spec.requirements assert_equal [], spec.dependencies - assert_equal 'bin', spec.bindir - assert_equal '>= 0', spec.required_ruby_version.to_s - assert_equal '>= 0', spec.required_rubygems_version.to_s + assert_equal "bin", spec.bindir + assert_equal ">= 0", spec.required_ruby_version.to_s + assert_equal ">= 0", spec.required_rubygems_version.to_s end def test_initialize_future @@ -1269,18 +1135,18 @@ dependencies: [] spec = Gem::Specification.new do |s| s.name = "blah" s.version = "1.3.5" - s.summary = 'summary' - s.description = 'description' - s.authors = 'author a', 'author b' - s.licenses = 'BSD-2-Clause' - s.files = 'lib/file.rb' - s.test_files = 'test/file.rb' - s.rdoc_options = '--foo' - s.extra_rdoc_files = 'README.txt' - s.executables = 'exec' - s.extensions = 'ext/extconf.rb' - s.requirements = 'requirement' - s.add_dependency 'some_gem' + s.summary = "summary" + s.description = "description" + s.authors = "author a", "author b" + s.licenses = "BSD-2-Clause" + s.files = "lib/file.rb" + s.test_files = "test/file.rb" + s.rdoc_options = "--foo" + s.extra_rdoc_files = "README.txt" + s.executables = "exec" + s.extensions = "ext/extconf.rb" + s.requirements = "requirement" + s.add_dependency "some_gem" end dup_spec = spec.dup @@ -1294,84 +1160,96 @@ dependencies: [] assert_equal Gem::Platform::RUBY, spec.platform assert_same spec.platform, dup_spec.platform - assert_equal 'summary', spec.summary + assert_equal "summary", spec.summary assert_same spec.summary, dup_spec.summary assert_equal %w[README.txt bin/exec ext/extconf.rb lib/file.rb test/file.rb].sort, spec.files - refute_same spec.files, dup_spec.files, 'files' + refute_same spec.files, dup_spec.files, "files" assert_equal %w[test/file.rb], spec.test_files - refute_same spec.test_files, dup_spec.test_files, 'test_files' + refute_same spec.test_files, dup_spec.test_files, "test_files" assert_equal %w[--foo], spec.rdoc_options - refute_same spec.rdoc_options, dup_spec.rdoc_options, 'rdoc_options' + refute_same spec.rdoc_options, dup_spec.rdoc_options, "rdoc_options" assert_equal %w[README.txt], spec.extra_rdoc_files refute_same spec.extra_rdoc_files, dup_spec.extra_rdoc_files, - 'extra_rdoc_files' + "extra_rdoc_files" assert_equal %w[exec], spec.executables - refute_same spec.executables, dup_spec.executables, 'executables' + refute_same spec.executables, dup_spec.executables, "executables" assert_equal %w[ext/extconf.rb], spec.extensions - refute_same spec.extensions, dup_spec.extensions, 'extensions' + refute_same spec.extensions, dup_spec.extensions, "extensions" assert_equal %w[requirement], spec.requirements - refute_same spec.requirements, dup_spec.requirements, 'requirements' + refute_same spec.requirements, dup_spec.requirements, "requirements" - assert_equal [Gem::Dependency.new('some_gem', Gem::Requirement.default)], + assert_equal [Gem::Dependency.new("some_gem", Gem::Requirement.default)], spec.dependencies - refute_same spec.dependencies, dup_spec.dependencies, 'dependencies' + refute_same spec.dependencies, dup_spec.dependencies, "dependencies" - assert_equal 'bin', spec.bindir + assert_equal "bin", spec.bindir assert_same spec.bindir, dup_spec.bindir - assert_equal '>= 0', spec.required_ruby_version.to_s - assert_same spec.required_ruby_version, dup_spec.required_ruby_version + assert_equal ">= 0", spec.required_ruby_version.to_s + assert_equal spec.required_ruby_version, dup_spec.required_ruby_version + refute_same spec.required_ruby_version, dup_spec.required_ruby_version - assert_equal '>= 0', spec.required_rubygems_version.to_s - assert_same spec.required_rubygems_version, + assert_equal ">= 0", spec.required_rubygems_version.to_s + assert_equal spec.required_rubygems_version, + dup_spec.required_rubygems_version + refute_same spec.required_rubygems_version, dup_spec.required_rubygems_version end def test_initialize_copy_broken spec = Gem::Specification.new do |s| - s.name = 'a' - s.version = '1' + s.name = "a" + s.version = "1" end - spec.instance_variable_set :@licenses, (class << (Object.new);self;end) - spec.loaded_from = '/path/to/file' + spec.instance_variable_set :@licenses, (class << Object.new;self;end) + spec.loaded_from = "/path/to/file" e = assert_raise Gem::FormatException do spec.dup end - assert_equal 'a-1 has an invalid value for @licenses', e.message - assert_equal '/path/to/file', e.file_path + assert_equal "a-1 has an invalid value for @licenses", e.message + assert_equal "/path/to/file", e.file_path end def test_initialize_prerelease_version_before_name spec = Gem::Specification.new do |s| - s.version = '1.0.0.dev' - s.name = 'a' + s.version = "1.0.0.dev" + s.name = "a" end assert_equal "a", spec.name assert_equal "1.0.0.dev", spec.version.to_s end + def test_initialize_nil_version + expected = "nil versions are discouraged and will be deprecated in Rubygems 4\n" + actual_stdout, actual_stderr = capture_output do + Gem::Specification.new.version = nil + end + assert_empty actual_stdout + assert_equal(expected, actual_stderr) + end + def test__dump @a2.platform = Gem::Platform.local - @a2.instance_variable_set :@original_platform, 'old_platform' + @a2.instance_variable_set :@original_platform, "old_platform" data = Marshal.dump @a2 same_spec = Marshal.load data - assert_equal 'old_platform', same_spec.original_platform + assert_equal "old_platform", same_spec.original_platform end def test_activate @@ -1386,11 +1264,11 @@ dependencies: [] awesome.add_dependency :gem_name end - assert_equal %w[true gem_name], gem.dependencies.map {|dep| dep.name } + assert_equal %w[true gem_name], gem.dependencies.map(&:name) end def test_add_dependency_from_existing_dependency - dep = Gem::Dependency.new("existing_dep", Gem::Requirement.new('> 1'), :runtime) + dep = Gem::Dependency.new("existing_dep", Gem::Requirement.new("> 1"), :runtime) spec = Gem::Specification.new {|s| s.add_dependency dep } assert_equal dep, spec.dependencies.first end @@ -1405,22 +1283,22 @@ dependencies: [] end def test_author - assert_equal 'A User', @a1.author + assert_equal "A User", @a1.author end def test_authors - assert_equal ['A User'], @a1.authors + assert_equal ["A User"], @a1.authors end def test_bindir_equals - @a1.bindir = 'apps' + @a1.bindir = "apps" - assert_equal 'apps', @a1.bindir + assert_equal "apps", @a1.bindir end def test_bindir_equals_nil @a2.bindir = nil - @a2.executable = 'app' + @a2.executable = "app" assert_nil @a2.bindir assert_equal %w[app lib/code.rb].sort, @a2.files @@ -1451,35 +1329,33 @@ dependencies: [] end def test_build_args - skip "extensions don't quite work on jruby" if Gem.java_platform? + pend "extensions don't quite work on jruby" if Gem.java_platform? ext_spec assert_empty @ext.build_args - File.open @ext.build_info_file, 'w' do |io| - io.puts - end + File.open @ext.build_info_file, "w", &:puts assert_empty @ext.build_args - File.open @ext.build_info_file, 'w' do |io| - io.puts '--with-foo-dir=wherever' + File.open @ext.build_info_file, "w" do |io| + io.puts "--with-foo-dir=wherever" end assert_equal %w[--with-foo-dir=wherever], @ext.build_args end def test_build_extensions - skip "extensions don't quite work on jruby" if Gem.java_platform? + pend "extensions don't quite work on jruby" if Gem.java_platform? ext_spec - assert_path_not_exist @ext.extension_dir, 'sanity check' - refute_empty @ext.extensions, 'sanity check' + assert_path_not_exist @ext.extension_dir, "sanity check" + refute_empty @ext.extensions, "sanity check" extconf_rb = File.join @ext.gem_dir, @ext.extensions.first FileUtils.mkdir_p File.dirname extconf_rb - File.open extconf_rb, 'w' do |f| + File.open extconf_rb, "w" do |f| f.write <<-'RUBY' File.open 'Makefile', 'w' do |f| f.puts "clean:\n\techo clean" @@ -1495,42 +1371,42 @@ dependencies: [] end def test_default_spec_stub_is_marked_default - default = new_default_spec 'default', 2 + default = new_default_spec "default", 2 install_default_gems default - stub = Gem::Specification.stubs.find {|s| s.name == 'default' } + stub = Gem::Specification.stubs.find {|s| s.name == "default" } assert_predicate stub, :default_gem? - stub = Gem::Specification.find_all_by_name('default').first + stub = Gem::Specification.find_all_by_name("default").first assert_predicate stub, :default_gem? end def test_build_extensions_built - skip "extensions don't quite work on jruby" if Gem.java_platform? + pend "extensions don't quite work on jruby" if Gem.java_platform? ext_spec - refute_empty @ext.extensions, 'sanity check' + refute_empty @ext.extensions, "sanity check" gem_build_complete = - File.join @ext.extension_dir, 'gem.build_complete' + File.join @ext.extension_dir, "gem.build_complete" FileUtils.mkdir_p @ext.extension_dir FileUtils.touch gem_build_complete @ext.build_extensions - gem_make_out = File.join @ext.extension_dir, 'gem_make.out' + gem_make_out = File.join @ext.extension_dir, "gem_make.out" assert_path_not_exist gem_make_out end def test_build_extensions_default_gem - spec = new_default_spec 'default', 1 - spec.extensions << 'extconf.rb' + spec = new_default_spec "default", 1 + spec.extensions << "extconf.rb" extconf_rb = File.join spec.gem_dir, spec.extensions.first FileUtils.mkdir_p File.dirname extconf_rb - File.open extconf_rb, 'w' do |f| + File.open extconf_rb, "w" do |f| f.write <<-'RUBY' File.open 'Makefile', 'w' do |f| f.puts "default:\n\techo built" @@ -1545,10 +1421,10 @@ dependencies: [] end def test_build_extensions_error - skip "extensions don't quite work on jruby" if Gem.java_platform? + pend "extensions don't quite work on jruby" if Gem.java_platform? ext_spec - refute_empty @ext.extensions, 'sanity check' + refute_empty @ext.extensions, "sanity check" assert_raise Gem::Ext::BuildError do @ext.build_extensions @@ -1556,18 +1432,18 @@ dependencies: [] end def test_build_extensions_extensions_dir_unwritable - skip 'chmod not supported' if Gem.win_platform? - skip 'skipped in root privilege' if Process.uid.zero? + pend "chmod not supported" if Gem.win_platform? + pend "skipped in root privilege" if Process.uid.zero? - skip "extensions don't quite work on jruby" if Gem.java_platform? + pend "extensions don't quite work on jruby" if Gem.java_platform? ext_spec - refute_empty @ext.extensions, 'sanity check' + refute_empty @ext.extensions, "sanity check" extconf_rb = File.join @ext.gem_dir, @ext.extensions.first FileUtils.mkdir_p File.dirname extconf_rb - File.open extconf_rb, 'w' do |f| + File.open extconf_rb, "w" do |f| f.write <<-'RUBY' File.open 'Makefile', 'w' do |f| f.puts "clean:\n\techo clean" @@ -1577,30 +1453,30 @@ dependencies: [] RUBY end - FileUtils.mkdir_p File.join @ext.base_dir, 'extensions' - FileUtils.chmod 0555, @ext.base_dir - FileUtils.chmod 0555, File.join(@ext.base_dir, 'extensions') + FileUtils.mkdir_p File.join @ext.base_dir, "extensions" + FileUtils.chmod 0o555, @ext.base_dir + FileUtils.chmod 0o555, File.join(@ext.base_dir, "extensions") @ext.build_extensions assert_path_not_exist @ext.extension_dir ensure - unless ($DEBUG or win_platform? or Process.uid.zero? or Gem.java_platform?) - FileUtils.chmod 0755, File.join(@ext.base_dir, 'extensions') - FileUtils.chmod 0755, @ext.base_dir + unless $DEBUG || Gem.win_platform? || Process.uid.zero? || Gem.java_platform? + FileUtils.chmod 0o755, File.join(@ext.base_dir, "extensions") + FileUtils.chmod 0o755, @ext.base_dir end end def test_build_extensions_no_extensions_dir_unwritable - skip 'chmod not supported' if Gem.win_platform? - skip "extensions don't quite work on jruby" if Gem.java_platform? + pend "chmod not supported" if Gem.win_platform? + pend "extensions don't quite work on jruby" if Gem.java_platform? ext_spec - refute_empty @ext.extensions, 'sanity check' + refute_empty @ext.extensions, "sanity check" extconf_rb = File.join @ext.gem_dir, @ext.extensions.first FileUtils.mkdir_p File.dirname extconf_rb - File.open extconf_rb, 'w' do |f| + File.open extconf_rb, "w" do |f| f.write <<-'RUBY' File.open 'Makefile', 'w' do |f| f.puts "clean:\n\techo clean" @@ -1610,20 +1486,20 @@ dependencies: [] RUBY end - FileUtils.rm_r File.join @gemhome, 'extensions' - FileUtils.chmod 0555, @gemhome + FileUtils.rm_r File.join @gemhome, "extensions" + FileUtils.chmod 0o555, @gemhome @ext.build_extensions - gem_make_out = File.join @ext.extension_dir, 'gem_make.out' + gem_make_out = File.join @ext.extension_dir, "gem_make.out" assert_path_not_exist gem_make_out ensure - FileUtils.chmod 0755, @gemhome + FileUtils.chmod 0o755, @gemhome end def test_build_extensions_none - assert_path_not_exist @a1.extension_dir, 'sanity check' - assert_empty @a1.extensions, 'sanity check' + assert_path_not_exist @a1.extension_dir, "sanity check" + assert_empty @a1.extensions, "sanity check" @a1.build_extensions @@ -1631,13 +1507,13 @@ dependencies: [] end def test_build_extensions_preview - skip "extensions don't quite work on jruby" if Gem.java_platform? + pend "extensions don't quite work on jruby" if Gem.java_platform? ext_spec extconf_rb = File.join @ext.gem_dir, @ext.extensions.first FileUtils.mkdir_p File.dirname extconf_rb - File.open extconf_rb, 'w' do |f| + File.open extconf_rb, "w" do |f| f.write <<-'RUBY' File.open 'Makefile', 'w' do |f| f.puts "clean:\n\techo clean" @@ -1647,33 +1523,33 @@ dependencies: [] RUBY end - refute_empty @ext.extensions, 'sanity check' + refute_empty @ext.extensions, "sanity check" - @ext.installed_by_version = v('2.2.0.preview.2') + @ext.installed_by_version = v("2.2.0.preview.2") @ext.build_extensions - gem_make_out = File.join @ext.extension_dir, 'gem_make.out' + gem_make_out = File.join @ext.extension_dir, "gem_make.out" assert_path_exist gem_make_out end def test_contains_requirable_file_eh - code_rb = File.join @a1.gem_dir, 'lib', 'code.rb' + code_rb = File.join @a1.gem_dir, "lib", "code.rb" FileUtils.mkdir_p File.dirname code_rb FileUtils.touch code_rb - assert @a1.contains_requirable_file? 'code' + assert @a1.contains_requirable_file? "code" end def test_contains_requirable_file_eh_extension - skip "extensions don't quite work on jruby" if Gem.java_platform? + pend "extensions don't quite work on jruby" if Gem.java_platform? ext_spec _, err = capture_output do - refute @ext.contains_requirable_file? 'nonexistent' + refute @ext.contains_requirable_file? "nonexistent" end - expected = "Ignoring ext-1 because its extensions are not built. " + + expected = "Ignoring ext-1 because its extensions are not built. " \ "Try: gem pristine ext --version 1\n" assert_equal expected, err @@ -1683,12 +1559,23 @@ dependencies: [] ext_spec(platform: Gem::Platform.new("java")) _, err = capture_output do - refute @ext.contains_requirable_file? 'nonexistent' + refute @ext.contains_requirable_file? "nonexistent" end assert_empty err end + def test_contains_requirable_file_extension_soext + ext_spec + dlext = RbConfig::CONFIG["DLEXT"] + @ext.files += ["lib/ext.#{dlext}"] + + FileUtils.mkdir_p @ext.extension_dir + FileUtils.touch File.join(@ext.extension_dir, "ext.#{dlext}") + FileUtils.touch File.join(@ext.extension_dir, "gem.build_complete") + assert @ext.contains_requirable_file? "ext.so" + end + def test_date assert_date @a1.date end @@ -1699,13 +1586,13 @@ dependencies: [] end def test_date_equals_string - @a1.date = '2003-09-17' + @a1.date = "2003-09-17" assert_equal Time.utc(2003, 9, 17, 0,0,0), @a1.date end def test_date_equals_string_bad assert_raise Gem::InvalidSpecificationException do - @a1.date = '9/11/2003' + @a1.date = "9/11/2003" end end @@ -1726,12 +1613,12 @@ dependencies: [] 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 + assert_equal Time.utc(2012,1,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 + assert_equal Time.utc(2012,1,12,0,0,0), @a1.date end def test_date_use_env_source_date_epoch @@ -1752,7 +1639,7 @@ dependencies: [] assert_empty @gem.dependent_gems - bonobo = util_spec 'bonobo', 1 + bonobo = util_spec "bonobo", 1 install_gem bonobo install_gem @gem @@ -1764,11 +1651,11 @@ dependencies: [] end def test_doc_dir - assert_equal File.join(@gemhome, 'doc', 'a-1'), @a1.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') + assert_equal File.join(@gemhome, "doc", "a-1", "ri"), @a1.doc_dir("ri") end def test_runtime_dependencies @@ -1782,12 +1669,12 @@ dependencies: [] end def test_description - assert_equal 'This is a test description', @a1.description + assert_equal "This is a test description", @a1.description end def test_eql_eh - g1 = util_spec 'gem', 1 - g2 = util_spec 'gem', 1 + g1 = util_spec "gem", 1 + g2 = util_spec "gem", 1 assert_equal g1, g2 assert_equal g1.hash, g2.hash @@ -1796,55 +1683,55 @@ dependencies: [] def test_eql_eh_extensions spec = @a1.dup - spec.extensions = 'xx' + spec.extensions = "xx" refute_operator @a1, :eql?, spec refute_operator spec, :eql?, @a1 end def test_executables - @a1.executable = 'app' + @a1.executable = "app" assert_equal %w[app], @a1.executables end def test_executable_equals - @a2.executable = 'app' - assert_equal 'app', @a2.executable + @a2.executable = "app" + assert_equal "app", @a2.executable assert_equal %w[bin/app lib/code.rb].sort, @a2.files end def test_extensions - assert_equal ['ext/extconf.rb'], ext_spec.extensions + assert_equal ["ext/extconf.rb"], ext_spec.extensions end def test_extension_dir - enable_shared, RbConfig::CONFIG['ENABLE_SHARED'] = - RbConfig::CONFIG['ENABLE_SHARED'], 'no' + enable_shared = RbConfig::CONFIG["ENABLE_SHARED"] + RbConfig::CONFIG["ENABLE_SHARED"] = "no" ext_spec refute_empty @ext.extensions expected = - File.join(@ext.base_dir, 'extensions', Gem::Platform.local.to_s, + File.join(@ext.base_dir, "extensions", Gem::Platform.local.to_s, "#{Gem.ruby_api_version}-static", @ext.full_name) assert_equal expected, @ext.extension_dir ensure - RbConfig::CONFIG['ENABLE_SHARED'] = enable_shared + RbConfig::CONFIG["ENABLE_SHARED"] = enable_shared end def test_extension_dir_override - enable_shared, RbConfig::CONFIG['ENABLE_SHARED'] = - RbConfig::CONFIG['ENABLE_SHARED'], 'no' + enable_shared = RbConfig::CONFIG["ENABLE_SHARED"] + RbConfig::CONFIG["ENABLE_SHARED"] = "no" class << Gem - alias orig_default_ext_dir_for default_ext_dir_for + alias_method :orig_default_ext_dir_for, :default_ext_dir_for remove_method :default_ext_dir_for def Gem.default_ext_dir_for(base_dir) - 'elsewhere' + "elsewhere" end end @@ -1852,16 +1739,16 @@ dependencies: [] refute_empty @ext.extensions - expected = File.join @tempdir, 'elsewhere', @ext.full_name + expected = File.join @tempdir, "elsewhere", @ext.full_name assert_equal expected, @ext.extension_dir ensure - RbConfig::CONFIG['ENABLE_SHARED'] = enable_shared + RbConfig::CONFIG["ENABLE_SHARED"] = enable_shared class << Gem remove_method :default_ext_dir_for - alias default_ext_dir_for orig_default_ext_dir_for + alias_method :default_ext_dir_for, :orig_default_ext_dir_for end end @@ -1946,9 +1833,9 @@ dependencies: [] end def test_for_cache - @a2.add_runtime_dependency 'b', '1' + @a2.add_runtime_dependency "b", "1" @a2.dependencies.first.instance_variable_set :@type, nil - @a2.required_rubygems_version = Gem::Requirement.new '> 0' + @a2.required_rubygems_version = Gem::Requirement.new "> 0" @a2.test_files = %w[test/test_b.rb] refute_empty @a2.files @@ -1964,16 +1851,16 @@ dependencies: [] end def test_full_gem_path - assert_equal File.join(@gemhome, 'gems', @a1.full_name), @a1.full_gem_path + assert_equal File.join(@gemhome, "gems", @a1.full_name), @a1.full_gem_path - @a1.original_platform = 'mswin32' + @a1.original_platform = "mswin32" - assert_equal File.join(@gemhome, 'gems', @a1.original_name), + assert_equal File.join(@gemhome, "gems", @a1.original_name), @a1.full_gem_path end def test_full_gem_path_double_slash - gemhome = @gemhome.to_s.sub(/\w\//, '\&/') + gemhome = @gemhome.to_s.sub(%r{\w/}, '\&/') @a1.loaded_from = File.join gemhome, "specifications", @a1.spec_name expected = File.join @gemhome, "gems", @a1.full_name @@ -1981,40 +1868,40 @@ dependencies: [] end def test_full_name - assert_equal 'a-1', @a1.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.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' + @a1.instance_variable_set :@new_platform, "mswin32" + assert_equal "a-1-mswin32", @a1.full_name, "legacy" - return if win_platform? + return if Gem.win_platform? @a1 = Gem::Specification.new "a", 1 - @a1.platform = 'current' - assert_equal 'a-1-x86-darwin-8', @a1.full_name + @a1.platform = "current" + assert_equal "a-1-x86-darwin-8", @a1.full_name end def test_full_name_windows test_cases = { - 'i386-mswin32' => 'a-1-x86-mswin32-60', - 'i386-mswin32_80' => 'a-1-x86-mswin32-80', - 'i386-mingw32' => 'a-1-x86-mingw32', + "i386-mswin32" => "a-1-x86-mswin32-60", + "i386-mswin32_80" => "a-1-x86-mswin32-80", + "i386-mingw32" => "a-1-x86-mingw32", } test_cases.each do |arch, expected| @a1 = Gem::Specification.new "a", 1 util_set_arch arch - @a1.platform = 'current' + @a1.platform = "current" assert_equal expected, @a1.full_name end end def test_gem_build_complete_path - expected = File.join @a1.extension_dir, 'gem.build_complete' + expected = File.join @a1.extension_dir, "gem.build_complete" assert_equal expected, @a1.gem_build_complete_path end @@ -2058,23 +1945,23 @@ dependencies: [] end def test_license - assert_equal 'MIT', @a1.license + assert_equal "MIT", @a1.license end def test_licenses - assert_equal ['MIT'], @a1.licenses + assert_equal ["MIT"], @a1.licenses end def test_name - assert_equal 'a', @a1.name + assert_equal "a", @a1.name end def test_original_name - assert_equal 'a-1', @a1.full_name + assert_equal "a-1", @a1.full_name - @a1.platform = 'i386-linux' - @a1.instance_variable_set :@original_platform, 'i386-linux' - assert_equal 'a-1-i386-linux', @a1.original_name + @a1.platform = "i386-linux" + @a1.instance_variable_set :@original_platform, "i386-linux" + assert_equal "a-1-i386-linux", @a1.original_name end def test_platform @@ -2103,10 +1990,10 @@ dependencies: [] assert_equal Gem::Platform::RUBY, @a1.platform test_cases = { - 'i386-mswin32' => ['x86', 'mswin32', '60'], - 'i386-mswin32_80' => ['x86', 'mswin32', '80'], - 'i386-mingw32' => ['x86', 'mingw32', nil ], - 'x86-darwin8' => ['x86', 'darwin', '8' ], + "i386-mswin32" => ["x86", "mswin32", "60"], + "i386-mswin32_80" => ["x86", "mswin32", "80"], + "i386-mingw32" => ["x86", "mingw32", nil], + "x86-darwin8" => ["x86", "darwin", "8"], } test_cases.each do |arch, expected| @@ -2123,29 +2010,23 @@ dependencies: [] end def test_platform_equals_legacy - @a1.platform = 'mswin32' - assert_equal Gem::Platform.new('x86-mswin32'), @a1.platform + @a1.platform = "mswin32" + assert_equal Gem::Platform.new("x86-mswin32"), @a1.platform - @a1.platform = 'i586-linux' - assert_equal Gem::Platform.new('x86-linux'), @a1.platform + @a1.platform = "i586-linux" + assert_equal Gem::Platform.new("x86-linux"), @a1.platform - @a1.platform = 'powerpc-darwin' - assert_equal Gem::Platform.new('ppc-darwin'), @a1.platform - end - - def test_prerelease_spec_adds_required_rubygems_version - @prerelease = util_spec('tardis', '2.2.0.a') - refute @prerelease.required_rubygems_version.satisfied_by?(Gem::Version.new('1.3.1')) - assert @prerelease.required_rubygems_version.satisfied_by?(Gem::Version.new('1.4.0')) + @a1.platform = "powerpc-darwin" + assert_equal Gem::Platform.new("ppc-darwin"), @a1.platform end def test_require_paths - enable_shared 'no' do + enable_shared "no" do ext_spec - @ext.require_paths = 'lib' + @ext.require_paths = "lib" - assert_equal [@ext.extension_dir, 'lib'], @ext.require_paths + assert_equal [@ext.extension_dir, "lib"], @ext.require_paths end end @@ -2157,15 +2038,15 @@ dependencies: [] end def Gem.default_ext_dir_for(base_dir) - '/foo' + "/foo" end - enable_shared 'no' do + enable_shared "no" do ext_spec - @ext.require_paths = 'lib' + @ext.require_paths = "lib" - assert_equal [File.expand_path('/foo/ext-1'), 'lib'], @ext.require_paths + assert_equal [File.expand_path("/foo/ext-1"), "lib"], @ext.require_paths end ensure class << Gem @@ -2183,7 +2064,7 @@ dependencies: [] ext_spec @ext.require_paths = %w[lib ext foo] - @ext.extensions << 'bar/baz' + @ext.extensions << "bar/baz" expected = %w[ lib @@ -2198,10 +2079,10 @@ dependencies: [] def test_full_require_paths ext_spec - @ext.require_paths = 'lib' + @ext.require_paths = "lib" expected = [ - File.join(@gemhome, 'gems', @ext.original_name, 'lib'), + File.join(@gemhome, "gems", @ext.original_name, "lib"), @ext.extension_dir, ] @@ -2211,10 +2092,10 @@ dependencies: [] def test_to_fullpath ext_spec - @ext.require_paths = 'lib' + @ext.require_paths = "lib" - dir = File.join(@gemhome, 'gems', @ext.original_name, 'lib') - expected_rb = File.join(dir, 'code.rb') + dir = File.join(@gemhome, "gems", @ext.original_name, "lib") + expected_rb = File.join(dir, "code.rb") FileUtils.mkdir_p dir FileUtils.touch expected_rb @@ -2248,10 +2129,10 @@ dependencies: [] def test_fullpath_return_rb_extension_file_when_exist_the_same_name_file ext_spec - @ext.require_paths = 'lib' + @ext.require_paths = "lib" - dir = File.join(@gemhome, 'gems', @ext.original_name, 'lib') - expected_rb = File.join(dir, 'code.rb') + dir = File.join(@gemhome, "gems", @ext.original_name, "lib") + expected_rb = File.join(dir, "code.rb") FileUtils.mkdir_p dir FileUtils.touch expected_rb @@ -2267,52 +2148,48 @@ dependencies: [] end def test_require_already_activated - save_loaded_features do - a1 = util_spec "a", "1", nil, "lib/d#{$$}.rb" + a1 = util_spec "a", "1", nil, "lib/d#{$$}.rb" - install_specs a1 # , a2, b1, b2, c1, c2 + install_specs a1 # , a2, b1, b2, c1, c2 - a1.activate - assert_equal %w[a-1], loaded_spec_names - assert_equal [], unresolved_names + a1.activate + assert_equal %w[a-1], loaded_spec_names + assert_equal [], unresolved_names - assert require "d#{$$}" + assert require "d#{$$}" - assert_equal %w[a-1], loaded_spec_names - assert_equal [], unresolved_names - end + assert_equal %w[a-1], loaded_spec_names + assert_equal [], unresolved_names end def test_require_already_activated_indirect_conflict - save_loaded_features do - a1 = util_spec "a", "1", "b" => "> 0" - a2 = util_spec "a", "2", "b" => "> 0" - b1 = util_spec "b", "1", "c" => ">= 1" - b2 = util_spec "b", "2", "c" => ">= 2" - c1 = util_spec "c", "1", nil, "lib/d#{$$}.rb" - c2 = util_spec("c", "2", { "a" => "1" }, "lib/d#{$$}.rb") # conflicts with a-2 + a1 = util_spec "a", "1", "b" => "> 0" + a2 = util_spec "a", "2", "b" => "> 0" + b1 = util_spec "b", "1", "c" => ">= 1" + b2 = util_spec "b", "2", "c" => ">= 2" + c1 = util_spec "c", "1", nil, "lib/d#{$$}.rb" + c2 = util_spec("c", "2", { "a" => "1" }, "lib/d#{$$}.rb") # conflicts with a-2 - install_specs c1, b1, a1, a2, c2, b2 + install_specs c1, b1, a1, a2, c2, b2 - a1.activate - c1.activate - assert_equal %w[a-1 c-1], loaded_spec_names - assert_equal ["b (> 0)"], unresolved_names + a1.activate + c1.activate + assert_equal %w[a-1 c-1], loaded_spec_names + assert_equal ["b (> 0)"], unresolved_names - assert require "d#{$$}" + assert require "d#{$$}" - assert_equal %w[a-1 c-1], loaded_spec_names - assert_equal ["b (> 0)"], unresolved_names - end + assert_equal %w[a-1 c-1], loaded_spec_names + assert_equal ["b (> 0)"], unresolved_names end def test_requirements - assert_equal ['A working computer'], @a1.requirements + assert_equal ["A working computer"], @a1.requirements end def test_allowed_push_host - assert_nil @a1.metadata['allowed_push_host'] - assert_equal 'https://privategemserver.com', @a3.metadata['allowed_push_host'] + assert_nil @a1.metadata["allowed_push_host"] + assert_equal "https://privategemserver.com", @a3.metadata["allowed_push_host"] end def test_runtime_dependencies_legacy @@ -2324,58 +2201,58 @@ dependencies: [] expected = %w[rake jabber4r pqa] - assert_equal expected, @c1.runtime_dependencies.map {|d| d.name } + assert_equal expected, @c1.runtime_dependencies.map(&:name) end def test_spaceship_name - s1 = util_spec 'a', '1' - s2 = util_spec 'b', '1' + s1 = util_spec "a", "1" + s2 = util_spec "b", "1" assert_equal(-1, (s1 <=> s2)) - assert_equal(0, (s1 <=> s1)) + assert_equal(0, (s1 <=> s1)) # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands assert_equal(1, (s2 <=> s1)) end def test_spaceship_platform - s1 = util_spec 'a', '1' - s2 = util_spec 'a', '1' do |s| - s.platform = Gem::Platform.new 'x86-my_platform1' + s1 = util_spec "a", "1" + s2 = util_spec "a", "1" do |s| + s.platform = Gem::Platform.new "x86-my_platform1" end assert_equal(-1, (s1 <=> s2)) - assert_equal(0, (s1 <=> s1)) + assert_equal(0, (s1 <=> s1)) # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands assert_equal(1, (s2 <=> s1)) end def test_spaceship_version - s1 = util_spec 'a', '1' - s2 = util_spec 'a', '2' + s1 = util_spec "a", "1" + s2 = util_spec "a", "2" assert_equal(-1, (s1 <=> s2)) - assert_equal(0, (s1 <=> s1)) + assert_equal(0, (s1 <=> s1)) # rubocop:disable Lint/BinaryOperatorWithIdenticalOperands assert_equal(1, (s2 <=> s1)) end def test_spec_file - assert_equal File.join(@gemhome, 'specifications', 'a-1.gemspec'), + 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 + assert_equal "a-1.gemspec", @a1.spec_name end def test_summary - assert_equal 'this is a summary', @a1.summary + assert_equal "this is a summary", @a1.summary end def test_test_files - @a1.test_file = 'test/suite.rb' - assert_equal ['test/suite.rb'], @a1.test_files + @a1.test_file = "test/suite.rb" + assert_equal ["test/suite.rb"], @a1.test_files end def test_runtime_predicate_true - @a2.add_runtime_dependency 'b', '1' + @a2.add_runtime_dependency "b", "1" assert_predicate @a2.dependencies.first, :runtime? @a2.dependencies.first.instance_variable_set :@type, nil @@ -2383,15 +2260,15 @@ dependencies: [] end def test_runtime_predicate_false - @a2.add_development_dependency 'b', '1' + @a2.add_development_dependency "b", "1" refute_predicate @a2.dependencies.first, :runtime? end def test_to_ruby - @a2.add_runtime_dependency 'b', '1' + @a2.add_runtime_dependency "b", "1" @a2.dependencies.first.instance_variable_set :@type, nil - @a2.required_rubygems_version = Gem::Requirement.new '> 0' - @a2.require_paths << 'other' + @a2.required_rubygems_version = Gem::Requirement.new "> 0" + @a2.require_paths << "other" ruby_code = @a2.to_ruby @@ -2401,7 +2278,7 @@ dependencies: [] Gem::Specification.new do |s| s.name = "a".freeze - s.version = "2" + s.version = "2".freeze s.required_rubygems_version = Gem::Requirement.new(\"> 0\".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze, "other".freeze] @@ -2414,15 +2291,9 @@ Gem::Specification.new do |s| s.rubygems_version = "#{Gem::VERSION}".freeze s.summary = "this is a summary".freeze - if s.respond_to? :specification_version then - s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION} - end + s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION} - if s.respond_to? :add_runtime_dependency then - s.add_runtime_dependency(%q<b>.freeze, [\"= 1\"]) - else - s.add_dependency(%q<b>.freeze, [\"= 1\"]) - end + s.add_runtime_dependency(%q<b>.freeze, [\"= 1\".freeze]) end SPEC @@ -2434,8 +2305,8 @@ end end def test_to_ruby_with_rsa_key - require 'rubygems/openssl' - skip 'openssl is missing' unless defined?(OpenSSL::PKey::RSA) + require "rubygems/openssl" + pend "openssl is missing" unless defined?(OpenSSL::PKey::RSA) rsa_key = OpenSSL::PKey::RSA.new(2048) @a2.signing_key = rsa_key @@ -2447,7 +2318,7 @@ end Gem::Specification.new do |s| s.name = "a".freeze - s.version = "2" + s.version = "2".freeze s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] @@ -2466,9 +2337,9 @@ end end def test_to_ruby_for_cache - @a2.add_runtime_dependency 'b', '1' + @a2.add_runtime_dependency "b", "1" @a2.dependencies.first.instance_variable_set :@type, nil - @a2.required_rubygems_version = Gem::Requirement.new '> 0' + @a2.required_rubygems_version = Gem::Requirement.new "> 0" @a2.installed_by_version = Gem.rubygems_version # cached specs do not have spec.files populated: @@ -2480,7 +2351,7 @@ end Gem::Specification.new do |s| s.name = "a".freeze - s.version = "2" + s.version = "2".freeze s.required_rubygems_version = Gem::Requirement.new(\"> 0\".freeze) if s.respond_to? :required_rubygems_version= s.require_paths = ["lib".freeze] @@ -2492,17 +2363,11 @@ Gem::Specification.new do |s| s.rubygems_version = "#{Gem::VERSION}".freeze s.summary = "this is a summary".freeze - s.installed_by_version = "#{Gem::VERSION}" if s.respond_to? :installed_by_version + s.installed_by_version = "#{Gem::VERSION}".freeze if s.respond_to? :installed_by_version - if s.respond_to? :specification_version then - s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION} - end + s.specification_version = #{Gem::Specification::CURRENT_SPECIFICATION_VERSION} - if s.respond_to? :add_runtime_dependency then - s.add_runtime_dependency(%q<b>.freeze, [\"= 1\"]) - else - s.add_dependency(%q<b>.freeze, [\"= 1\"]) - end + s.add_runtime_dependency(%q<b>.freeze, ["= 1".freeze]) end SPEC @@ -2522,19 +2387,19 @@ end ruby_code = @c1.to_ruby local = Gem::Platform.local - expected_platform = "[#{local.cpu.inspect}, #{local.os.inspect}, #{local.version.inspect}]" + expected_platform = "[#{local.cpu.inspect}.freeze, #{local.os.inspect}.freeze, #{local.version.inspect}.freeze]" stub_require_paths = @c1.instance_variable_get(:@require_paths).join "\u0000" extensions = @c1.extensions.join "\u0000" expected = <<-SPEC # -*- encoding: utf-8 -*- -# stub: a 1 #{win_platform? ? "x86-mswin32-60" : "x86-darwin-8"} #{stub_require_paths} +# stub: a 1 #{Gem.win_platform? ? "x86-mswin32-60" : "x86-darwin-8"} #{stub_require_paths} # stub: #{extensions} Gem::Specification.new do |s| s.name = "a".freeze - s.version = "1" + s.version = "1".freeze s.platform = Gem::Platform.new(#{expected_platform}) s.required_rubygems_version = Gem::Requirement.new(\">= 0\".freeze) if s.respond_to? :required_rubygems_version= @@ -2553,19 +2418,11 @@ Gem::Specification.new do |s| s.summary = "this is a summary".freeze s.test_files = ["test/suite.rb".freeze] - if s.respond_to? :specification_version then - s.specification_version = 4 - end + s.specification_version = 4 - if s.respond_to? :add_runtime_dependency then - s.add_runtime_dependency(%q<rake>.freeze, [\"> 0.4\"]) - s.add_runtime_dependency(%q<jabber4r>.freeze, [\"> 0.0.0\"]) - s.add_runtime_dependency(%q<pqa>.freeze, [\"> 0.4\", \"<= 0.6\"]) - else - s.add_dependency(%q<rake>.freeze, [\"> 0.4\"]) - s.add_dependency(%q<jabber4r>.freeze, [\"> 0.0.0\"]) - s.add_dependency(%q<pqa>.freeze, [\"> 0.4\", \"<= 0.6\"]) - end + s.add_runtime_dependency(%q<rake>.freeze, [\"> 0.4\".freeze]) + s.add_runtime_dependency(%q<jabber4r>.freeze, [\"> 0.0.0\".freeze]) + s.add_runtime_dependency(%q<pqa>.freeze, [\"> 0.4\".freeze, \"<= 0.6\".freeze]) end SPEC @@ -2577,11 +2434,11 @@ end end def test_to_ruby_keeps_requirements_as_originally_specified - spec = util_spec 'a', '1' do |s| - s.add_dependency 'b', ['~> 1.0', '>= 1.0.0'] + spec = util_spec "a", "1" do |s| + s.add_dependency "b", ["~> 1.0", ">= 1.0.0"] end - assert_includes spec.to_ruby, '"~> 1.0", ">= 1.0.0"' + assert_includes spec.to_ruby, '"~> 1.0".freeze, ">= 1.0.0".freeze' end def test_to_ruby_legacy @@ -2596,30 +2453,30 @@ end def test_to_ruby_nested_hash metadata = {} - metadata[metadata] = metadata + metadata[:metadata] = {} @a2.metadata = metadata ruby = @a2.to_ruby - assert_match %r%^ s\.metadata = \{ "%, ruby + assert_match(/^ s\.metadata = \{ "/, ruby) end def test_to_ruby_platform @a2.platform = Gem::Platform.local - @a2.instance_variable_set :@original_platform, 'old_platform' + @a2.instance_variable_set :@original_platform, "old_platform" ruby_code = @a2.to_ruby same_spec = eval ruby_code - assert_equal 'old_platform', same_spec.original_platform + assert_equal "old_platform", same_spec.original_platform end def test_to_yaml yaml_str = @a1.to_yaml - refute_match %r{!!null}, yaml_str + refute_match(/!!null/, yaml_str) same_spec = Gem::Specification.from_yaml(yaml_str) @@ -2638,27 +2495,47 @@ end end def test_to_yaml_platform_empty_string - @a1.instance_variable_set :@original_platform, '' + @a1.instance_variable_set :@original_platform, "" - assert_match %r{^platform: ruby$}, @a1.to_yaml + assert_match(/^platform: ruby$/, @a1.to_yaml) end def test_to_yaml_platform_legacy - @a1.platform = 'powerpc-darwin7.9.0' - @a1.instance_variable_set :@original_platform, 'powerpc-darwin7.9.0' + @a1.platform = "powerpc-darwin7.9.0" + @a1.instance_variable_set :@original_platform, "powerpc-darwin7.9.0" yaml_str = @a1.to_yaml - same_spec = YAML.load yaml_str + same_spec = load_yaml yaml_str - assert_equal Gem::Platform.new('powerpc-darwin7'), same_spec.platform - assert_equal 'powerpc-darwin7.9.0', same_spec.original_platform + assert_equal Gem::Platform.new("powerpc-darwin7"), same_spec.platform + assert_equal "powerpc-darwin7.9.0", same_spec.original_platform end def test_to_yaml_platform_nil @a1.instance_variable_set :@original_platform, nil - assert_match %r{^platform: ruby$}, @a1.to_yaml + assert_match(/^platform: ruby$/, @a1.to_yaml) + end + + def test_to_yaml_no_autorequire + yaml_str = @a1.to_yaml + + refute_match(/^autorequire:/, yaml_str) + end + + def test_to_yaml_no_signing_key + @a1.signing_key = nil + yaml_str = @a1.to_yaml + + refute_match(/^signing_key:/, yaml_str) + end + + def test_to_yaml_no_post_install_message + @a1.post_install_message = nil + yaml_str = @a1.to_yaml + + refute_match(/^post_install_message:/, yaml_str) end def test_validate @@ -2669,10 +2546,21 @@ end end end - def x(s); s.gsub(/xxx/, ''); end - def w; x "WARxxxNING"; end - def t; x "TOxxxDO"; end - def f; x "FxxxIXME"; end + def x(s) + s.gsub(/xxx/, "") + end + + def w + x "WARxxxNING" + end + + def t + x "TOxxxDO" + end + + def f + x "FxxxIXME" + end def test_validate_authors util_setup_validate @@ -2684,7 +2572,7 @@ end @a1.validate end - assert_match "#{w}: no author specified\n", @ui.error, 'error' + assert_match "#{w}: no author specified\n", @ui.error, "error" @a1.authors = [Object.new] @@ -2718,14 +2606,14 @@ end util_setup_validate Dir.chdir @tempdir do - @a1.autorequire = 'code' + @a1.autorequire = "code" use_ui @ui do @a1.validate end assert_match "#{w}: deprecated autorequire specified\n", - @ui.error, 'error' + @ui.error, "error" end end @@ -2733,19 +2621,19 @@ end util_setup_validate Dir.chdir @tempdir do - @a1.add_runtime_dependency 'b', '>= 1.0.rc1' - @a1.add_development_dependency 'c', '>= 2.0.rc2' - @a1.add_runtime_dependency 'd', '~> 1.2.3' - @a1.add_runtime_dependency 'e', '~> 1.2.3.4' - @a1.add_runtime_dependency 'g', '~> 1.2.3', '>= 1.2.3.4' - @a1.add_runtime_dependency 'h', '>= 1.2.3', '<= 2' - @a1.add_runtime_dependency 'i', '>= 1.2' - @a1.add_runtime_dependency 'j', '>= 1.2.3' - @a1.add_runtime_dependency 'k', '> 1.2' - @a1.add_runtime_dependency 'l', '> 1.2.3' - @a1.add_runtime_dependency 'm', '~> 2.1.0' - @a1.add_runtime_dependency 'n', '~> 0.1.0' - @a1.add_runtime_dependency 'o' + @a1.add_runtime_dependency "b", ">= 1.0.rc1" + @a1.add_development_dependency "c", ">= 2.0.rc2" + @a1.add_runtime_dependency "d", "~> 1.2.3" + @a1.add_runtime_dependency "e", "~> 1.2.3.4" + @a1.add_runtime_dependency "g", "~> 1.2.3", ">= 1.2.3.4" + @a1.add_runtime_dependency "h", ">= 1.2.3", "<= 2" + @a1.add_runtime_dependency "i", ">= 1.2" + @a1.add_runtime_dependency "j", ">= 1.2.3" + @a1.add_runtime_dependency "k", "> 1.2" + @a1.add_runtime_dependency "l", "> 1.2.3" + @a1.add_runtime_dependency "m", "~> 2.1.0" + @a1.add_runtime_dependency "n", "~> 0.1.0" + @a1.add_runtime_dependency "o" use_ui @ui do @a1.validate @@ -2756,22 +2644,22 @@ end #{w}: prerelease dependency on c (>= 2.0.rc2, development) is not recommended #{w}: open-ended dependency on i (>= 1.2) is not recommended if i is semantically versioned, use: - add_runtime_dependency 'i', '~> 1.2' + add_runtime_dependency "i", "~> 1.2" #{w}: open-ended dependency on j (>= 1.2.3) is not recommended if j is semantically versioned, use: - add_runtime_dependency 'j', '~> 1.2', '>= 1.2.3' + add_runtime_dependency "j", "~> 1.2", ">= 1.2.3" #{w}: open-ended dependency on k (> 1.2) is not recommended if k is semantically versioned, use: - add_runtime_dependency 'k', '~> 1.2', '> 1.2' + add_runtime_dependency "k", "~> 1.2", "> 1.2" #{w}: open-ended dependency on l (> 1.2.3) is not recommended if l is semantically versioned, use: - add_runtime_dependency 'l', '~> 1.2', '> 1.2.3' + add_runtime_dependency "l", "~> 1.2", "> 1.2.3" #{w}: open-ended dependency on o (>= 0) is not recommended - use a bounded requirement, such as '~> x.y' + use a bounded requirement, such as "~> x.y" #{w}: See https://guides.rubygems.org/specification-reference/ for help EXPECTED - assert_equal expected, @ui.error, 'warning' + assert_equal expected, @ui.error, "warning" end end @@ -2779,10 +2667,10 @@ end util_setup_validate Dir.chdir @tempdir do - @a1.add_runtime_dependency 'b', '~> 1.2' - @a1.add_runtime_dependency 'b', '>= 1.2.3' - @a1.add_development_dependency 'c', '~> 1.2' - @a1.add_development_dependency 'c', '>= 1.2.3' + @a1.add_runtime_dependency "b", "~> 1.2" + @a1.add_runtime_dependency "b", ">= 1.2.3" + @a1.add_development_dependency "c", "~> 1.2" + @a1.add_development_dependency "c", ">= 1.2.3" use_ui @ui do e = assert_raise Gem::InvalidSpecificationException do @@ -2791,9 +2679,9 @@ end expected = <<-EXPECTED duplicate dependency on b (>= 1.2.3), (~> 1.2) use: - add_runtime_dependency 'b', '>= 1.2.3', '~> 1.2' + add_runtime_dependency "b", ">= 1.2.3", "~> 1.2" duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use: - add_development_dependency 'c', '>= 1.2.3', '~> 1.2' + add_development_dependency "c", ">= 1.2.3", "~> 1.2" EXPECTED assert_equal expected, e.message @@ -2809,14 +2697,61 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use: util_setup_validate Dir.chdir @tempdir do - @a1.add_runtime_dependency 'b', '~> 1.2' - @a1.add_development_dependency 'b', '= 1.2.3' + @a1.add_runtime_dependency "b", "~> 1.2" + @a1.add_development_dependency "b", "= 1.2.3" + + use_ui @ui do + @a1.validate + end + + assert_equal "", @ui.error, "warning" + end + end + + def test_validate_no_required_ruby_versions + util_setup_validate + + Dir.chdir @tempdir do + use_ui @ui do + @a1.required_ruby_version = nil # reset + @a1.validate + end + + assert_equal <<-EXPECTED, @ui.error +#{w}: make sure you specify the oldest ruby version constraint (like \">= 3.0\") that you want your gem to support by setting the `required_ruby_version` gemspec attribute +#{w}: See https://guides.rubygems.org/specification-reference/ for help + EXPECTED + end + end + + def test_validate_open_required_ruby_versions + util_setup_validate + + Dir.chdir @tempdir do + @a1.required_ruby_version = ">= 0" + + use_ui @ui do + @a1.validate + end + + assert_equal <<-EXPECTED, @ui.error +#{w}: make sure you specify the oldest ruby version constraint (like \">= 3.0\") that you want your gem to support by setting the `required_ruby_version` gemspec attribute +#{w}: See https://guides.rubygems.org/specification-reference/ for help + EXPECTED + end + end + + def test_validate_valid_required_ruby_versions + util_setup_validate + + Dir.chdir @tempdir do + @a1.required_ruby_version = ">= 2.3.0" use_ui @ui do @a1.validate end - assert_equal '', @ui.error, 'warning' + assert_equal "", @ui.error, "warning" end end @@ -2824,14 +2759,31 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use: util_setup_validate Dir.chdir @tempdir do - @a1.version = '1.0.0.beta.1' - @a1.add_runtime_dependency 'b', '~> 1.2.0.beta.1' + @a1.version = "1.0.0.beta.1" + @a1.add_runtime_dependency "b", "~> 1.2.0.beta.1" + + use_ui @ui do + @a1.validate + end + + assert_equal "", @ui.error, "warning" + end + end + + def test_validate_self_referencing_dependencies + util_setup_validate + + Dir.chdir @tempdir do + @a1.add_runtime_dependency @a1.name, "1" use_ui @ui do @a1.validate end - assert_equal '', @ui.error, 'warning' + assert_equal <<-EXPECTED, @ui.error +#{w}: Self referencing dependency is unnecessary and strongly discouraged. +#{w}: See https://guides.rubygems.org/specification-reference/ for help + EXPECTED end end @@ -2839,14 +2791,14 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use: util_setup_validate Dir.chdir @tempdir do - @a1.extensions = ['Rakefile'] - File.write File.join(@tempdir, 'Rakefile'), '' + @a1.extensions = ["Rakefile"] + File.write File.join(@tempdir, "Rakefile"), "" use_ui @ui do @a1.validate end - assert_match(/add rake as a dependency/, @ui.error) + assert_match(/add rake as a runtime dependency/, @ui.error) end end @@ -2854,15 +2806,48 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use: util_setup_validate Dir.chdir @tempdir do - @a1.extensions = ['Rakefile'] - @a1.add_runtime_dependency 'rake' - File.write File.join(@tempdir, 'Rakefile'), '' + @a1.extensions = ["Rakefile"] + @a1.add_runtime_dependency "rake" + File.write File.join(@tempdir, "Rakefile"), "" use_ui @ui do @a1.validate end - refute_match(/add rake as a dependency/, @ui.error) + refute_match(/add rake as a runtime dependency/, @ui.error) + end + end + + def test_validate_rust_extension_have_missing_cargo_toml_error + util_setup_validate + + Dir.chdir @tempdir do + @a1.extensions = ["Cargo.toml"] + File.write File.join(@tempdir, "Cargo.toml"), "" + + e = assert_raise Gem::InvalidSpecificationException do + use_ui @ui do + @a1.validate + end + end + + assert_match(/but Cargo.lock is not part of the gem files/, e.message) + end + end + + def test_validate_rust_extension_have_no_missing_cargo_toml_error + util_setup_validate + + Dir.chdir @tempdir do + @a1.extensions = ["Cargo.toml"] + @a1.files << "Cargo.toml" + @a1.files << "Cargo.lock" + File.write File.join(@tempdir, "Cargo.toml"), "" + File.write File.join(@tempdir, "Cargo.lock"), "" + + use_ui @ui do + @a1.validate + end end end @@ -2870,7 +2855,7 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use: util_setup_validate Dir.chdir @tempdir do - @a1.description = '' + @a1.description = "" use_ui @ui do @a1.validate @@ -2902,6 +2887,34 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use: end assert_equal %("#{f}" or "#{t}" is not a description), e.message + + # Adding #{f} anywhere after the start of the description should be fine. + @a1.description = "(some description) #{f}" + + assert_nothing_raised do + @a1.validate + end + + # Adding #{t} anywhere after the start of the description should be fine. + @a1.description = "(some description) #{t}" + + assert_nothing_raised do + @a1.validate + end + + # Adding #{f} at the start of the second or later line should be fine. + @a1.description = "(some description)\n#{f}" + + assert_nothing_raised do + @a1.validate + end + + # Adding #{t} at the start of the second or later line should be fine. + @a1.description = "(some description)\n#{t}" + + assert_nothing_raised do + @a1.validate + end end end @@ -2932,7 +2945,7 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use: Gem::Specification.new.validate end - assert_equal 'missing value for attribute name', e.message + assert_equal "missing value for attribute name", e.message end def test_validate_error @@ -2942,15 +2955,15 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use: end end - assert_match 'See https://guides.rubygems.org/specification-reference/ for help', @ui.error + assert_match "See https://guides.rubygems.org/specification-reference/ for help", @ui.error end def test_validate_executables util_setup_validate - FileUtils.mkdir_p File.join(@tempdir, 'bin') - File.write File.join(@tempdir, 'bin', 'exec'), '' - FileUtils.mkdir_p File.join(@tempdir, 'exec') + FileUtils.mkdir_p File.join(@tempdir, "bin") + File.write File.join(@tempdir, "bin", "exec"), "" + FileUtils.mkdir_p File.join(@tempdir, "exec") use_ui @ui do Dir.chdir @tempdir do @@ -2960,13 +2973,13 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use: assert_equal %w[exec], @a1.executables - assert_equal '', @ui.output, 'output' - assert_match "#{w}: bin/exec is missing #! line\n", @ui.error, 'error' + assert_equal "", @ui.output, "output" + assert_match "#{w}: bin/exec is missing #! line\n", @ui.error, "error" end def test_validate_empty_require_paths - if win_platform? - skip 'test_validate_empty_require_paths skipped on MS Windows (symlink)' + if Gem.win_platform? + pend "test_validate_empty_require_paths skipped on MS Windows (symlink)" else util_setup_validate @@ -2975,26 +2988,26 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use: @a1.validate end - assert_equal 'specification must have at least one require_path', + assert_equal "specification must have at least one require_path", e.message end end def test_validate_files - skip 'test_validate_files skipped on MS Windows (symlink)' if win_platform? + pend "test_validate_files skipped on MS Windows (symlink)" if Gem.win_platform? util_setup_validate - @a1.files += ['lib', 'lib2'] - @a1.extensions << 'ext/a/extconf.rb' + @a1.files += ["lib", "lib2"] + @a1.extensions << "ext/a/extconf.rb" Dir.chdir @tempdir do - FileUtils.ln_s 'lib/code.rb', 'lib2' unless vc_windows? + FileUtils.ln_s "lib/code.rb", "lib2" unless vc_windows? use_ui @ui do @a1.validate end - assert_match 'WARNING: lib2 is a symlink, which is not supported on all platforms', @ui.error + assert_match "WARNING: lib2 is a symlink, which is not supported on all platforms", @ui.error end assert_equal %w[bin/exec ext/a/extconf.rb lib/code.rb lib2 test/suite.rb].sort, @@ -3010,7 +3023,7 @@ duplicate dependency on c (>= 1.2.3, development), (~> 1.2) use: { b: Gem::Dependency.new("x","1") } end - specification.define_singleton_method(:find_all_by_name) do |dep_name| + specification.define_singleton_method(:find_all_by_name) do |_dep_name| [] end @@ -3037,7 +3050,7 @@ Please report a bug if this causes problems. { b: Gem::Dependency.new("x","1") } end - specification.define_singleton_method(:find_all_by_name) do |dep_name| + specification.define_singleton_method(:find_all_by_name) do |_dep_name| [ specification.new {|s| s.name = "z", s.version = Gem::Version.new("1") }, specification.new {|s| s.name = "z", s.version = Gem::Version.new("2") }, @@ -3072,7 +3085,7 @@ Please report a bug if this causes problems. def set_orig(cls) s_cls = cls.singleton_class - s_cls.send :alias_method, :orig_unresolved_deps , :unresolved_deps + s_cls.send :alias_method, :orig_unresolved_deps, :unresolved_deps s_cls.send :alias_method, :orig_find_all_by_name, :find_all_by_name end @@ -3100,19 +3113,19 @@ Please report a bug if this causes problems. @a1.validate end - assert_match "#{w}: no homepage specified\n", @ui.error, 'error' + assert_match "#{w}: no homepage specified\n", @ui.error, "error" @ui = Gem::MockGemUi.new - @a1.homepage = '' + @a1.homepage = "" use_ui @ui do @a1.validate end - assert_match "#{w}: no homepage specified\n", @ui.error, 'error' + assert_match "#{w}: no homepage specified\n", @ui.error, "error" - @a1.homepage = 'over at my cool site' + @a1.homepage = "over at my cool site" e = assert_raise Gem::InvalidSpecificationException do @a1.validate @@ -3120,7 +3133,7 @@ Please report a bug if this causes problems. assert_equal '"over at my cool site" is not a valid HTTP URI', e.message - @a1.homepage = 'ftp://rubygems.org' + @a1.homepage = "ftp://rubygems.org" e = assert_raise Gem::InvalidSpecificationException do @a1.validate @@ -3128,12 +3141,11 @@ Please report a bug if this causes problems. assert_equal '"ftp://rubygems.org" is not a valid HTTP URI', e.message - @a1.homepage = 'https://rubygems.org/' + @a1.homepage = "https://rubygems.org/" assert_equal true, @a1.validate - @a1.homepage = 'https://rubygems.org' + @a1.homepage = "https://rubygems.org" assert_equal true, @a1.validate - end end @@ -3146,11 +3158,23 @@ Please report a bug if this causes problems. end assert_match <<-WARNING, @ui.error -WARNING: licenses is empty, but is recommended. Use a license identifier from -http://spdx.org/licenses or 'Nonstandard' for a nonstandard license. +WARNING: licenses is empty, but is recommended. Use an license identifier from +https://spdx.org/licenses or 'Nonstandard' for a nonstandard license, +or set it to nil if you don't want to specify a license. WARNING end + def test_validate_nil_license + util_setup_validate + + use_ui @ui do + @a1.license = nil + @a1.validate + end + + assert_empty @ui.error + end + def test_validate_license_in_a_non_packaging_context util_setup_validate @@ -3170,7 +3194,7 @@ http://spdx.org/licenses or 'Nonstandard' for a nonstandard license. util_setup_validate use_ui @ui do - @a1.rubyforge_project = 'invalid-attribute' + @a1.rubyforge_project = "invalid-attribute" @a1.validate end @@ -3181,32 +3205,48 @@ http://spdx.org/licenses or 'Nonstandard' for a nonstandard license. util_setup_validate use_ui @ui do - @a1.licenses = ['BSD'] + @a1.licenses = ["BSD"] @a1.validate end assert_match <<-WARNING, @ui.error -WARNING: license value 'BSD' is invalid. Use a license identifier from -http://spdx.org/licenses or 'Nonstandard' for a nonstandard license. +WARNING: License identifier 'BSD' is invalid. Use an identifier from +https://spdx.org/licenses or 'Nonstandard' for a nonstandard license, +or set it to nil if you don't want to specify a license. WARNING end - def test_validate_license_values_plus + def test_validate_license_ref util_setup_validate use_ui @ui do - @a1.licenses = ['GPL-2.0+'] + @a1.licenses = ["LicenseRef-LICENSE.md"] @a1.validate end assert_empty @ui.error end + def test_validate_deprecated_license_values_plus + util_setup_validate + + use_ui @ui do + @a1.licenses = ["GPL-2.0+"] + @a1.validate + end + + assert_match <<-WARNING, @ui.error +WARNING: License identifier 'GPL-2.0+' is deprecated. Use an identifier from +https://spdx.org/licenses or 'Nonstandard' for a nonstandard license, +or set it to nil if you don't want to specify a license. + WARNING + end + def test_validate_license_values_or_later util_setup_validate use_ui @ui do - @a1.licenses = ['GPL-2.0-or-later'] + @a1.licenses = ["GPL-2.0-or-later"] @a1.validate end @@ -3217,7 +3257,7 @@ http://spdx.org/licenses or 'Nonstandard' for a nonstandard license. util_setup_validate use_ui @ui do - @a1.licenses = ['GPL-2.0+ WITH Autoconf-exception-2.0'] + @a1.licenses = ["GPL-2.0-or-later WITH Autoconf-exception-2.0"] @a1.validate end @@ -3228,17 +3268,19 @@ http://spdx.org/licenses or 'Nonstandard' for a nonstandard license. util_setup_validate use_ui @ui do - @a1.licenses = ['GPL-2.0+ FOO', 'GPL-2.0 FOO'] + @a1.licenses = ["GPL-2.0+ FOO", "GPL-2.0 FOO"] @a1.validate end assert_match <<-WARNING, @ui.error -WARNING: license value 'GPL-2.0+ FOO' is invalid. Use a license identifier from -http://spdx.org/licenses or 'Nonstandard' for a nonstandard license. +WARNING: License identifier 'GPL-2.0+ FOO' is invalid. Use an identifier from +https://spdx.org/licenses or 'Nonstandard' for a nonstandard license, +or set it to nil if you don't want to specify a license. WARNING assert_match <<-WARNING, @ui.error -WARNING: license value 'GPL-2.0 FOO' is invalid. Use a license identifier from -http://spdx.org/licenses or 'Nonstandard' for a nonstandard license. +WARNING: License identifier 'GPL-2.0+ FOO' is invalid. Use an identifier from +https://spdx.org/licenses or 'Nonstandard' for a nonstandard license, +or set it to nil if you don't want to specify a license. WARNING end @@ -3246,13 +3288,29 @@ http://spdx.org/licenses or 'Nonstandard' for a nonstandard license. util_setup_validate use_ui @ui do - @a1.licenses = ['GPL-2.0+ WITH Autocofn-exception-2.0'] + @a1.licenses = ["GPL-2.0-only WITH Autocofn-exception-2.0"] + @a1.validate + end + + assert_match <<-WARNING, @ui.error +WARNING: License identifier 'GPL-2.0-only WITH Autocofn-exception-2.0' is invalid. Use an identifier from +https://spdx.org/licenses or 'Nonstandard' for a nonstandard license, +or set it to nil if you don't want to specify a license. + WARNING + end + + def test_validate_license_with_deprecated_exception + util_setup_validate + + use_ui @ui do + @a1.licenses = ["GPL-2.0-only WITH Nokia-Qt-exception-1.1"] @a1.validate end assert_match <<-WARNING, @ui.error -WARNING: license value 'GPL-2.0+ WITH Autocofn-exception-2.0' is invalid. Use a license identifier from -http://spdx.org/licenses or 'Nonstandard' for a nonstandard license. +WARNING: Exception identifier at 'GPL-2.0-only WITH Nokia-Qt-exception-1.1' is deprecated. Use an identifier from +https://spdx.org/licenses or 'Nonstandard' for a nonstandard license, +or set it to nil if you don't want to specify a license. WARNING end @@ -3260,13 +3318,14 @@ http://spdx.org/licenses or 'Nonstandard' for a nonstandard license. util_setup_validate use_ui @ui do - @a1.licenses = ['ruby'] + @a1.licenses = ["ruby"] @a1.validate end assert_match <<-WARNING, @ui.error -WARNING: license value 'ruby' is invalid. Use a license identifier from -http://spdx.org/licenses or 'Nonstandard' for a nonstandard license. +WARNING: License identifier 'ruby' is invalid. Use an identifier from +https://spdx.org/licenses or 'Nonstandard' for a nonstandard license, +or set it to nil if you don't want to specify a license. Did you mean 'Ruby'? WARNING end @@ -3364,19 +3423,19 @@ Did you mean 'Ruby'? spec.validate end - assert_match %r{^#{name}}, e.message + assert_match(/^#{name}/, e.message) end end end def test_validate_permissions - skip 'chmod not supported' if Gem.win_platform? + pend "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') + File.chmod 0o640, File.join("lib", "code.rb") + File.chmod 0o640, File.join("bin", "exec") use_ui @ui do @a1.validate @@ -3389,12 +3448,12 @@ Did you mean 'Ruby'? end def test_validate_permissions_of_missing_file_non_packaging - skip 'chmod not supported' if Gem.win_platform? + pend "chmod not supported" if Gem.win_platform? util_setup_validate Dir.chdir @tempdir do - File.delete File.join('lib', 'code.rb') + File.delete File.join("lib", "code.rb") use_ui @ui do assert @a1.validate(false) @@ -3406,13 +3465,13 @@ Did you mean 'Ruby'? util_setup_validate Dir.chdir @tempdir do - @a1.platform = 'mswin32' + @a1.platform = "mswin32" assert @a1.validate - @a1.platform = 'i586-linux' + @a1.platform = "i586-linux" assert @a1.validate - @a1.platform = 'powerpc-darwin' + @a1.platform = "powerpc-darwin" assert @a1.validate end end @@ -3433,7 +3492,7 @@ Did you mean 'Ruby'? util_setup_validate Dir.chdir @tempdir do - @a1.specification_version = '1.0' + @a1.specification_version = "1.0" e = assert_raise Gem::InvalidSpecificationException do use_ui @ui do @@ -3441,7 +3500,7 @@ Did you mean 'Ruby'? end end - err = 'specification_version must be an Integer (did you mean version?)' + err = "specification_version must be an Integer (did you mean version?)" assert_equal err, e.message end end @@ -3450,13 +3509,13 @@ Did you mean 'Ruby'? util_setup_validate Dir.chdir @tempdir do - @a1.summary = '' + @a1.summary = "" use_ui @ui do @a1.validate end - assert_match "#{w}: no summary specified\n", @ui.error, 'error' + assert_match "#{w}: no summary specified\n", @ui.error, "error" @a1.summary = "#{f} (describe your package)" @@ -3484,11 +3543,11 @@ Did you mean 'Ruby'? @a1.validate end - assert_match 'See https://guides.rubygems.org/specification-reference/ for help', @ui.error + assert_match "See https://guides.rubygems.org/specification-reference/ for help", @ui.error end def test_version - assert_equal Gem::Version.new('1'), @a1.version + assert_equal Gem::Version.new("1"), @a1.version end def test_version_change_reset_full_name @@ -3524,7 +3583,7 @@ Did you mean 'Ruby'? capture_output do Gem::Specification.load(specfile.path) end - rescue => e + rescue StandardError => e name_rexp = Regexp.new(Regexp.escape(specfile.path)) assert e.backtrace.grep(name_rexp).any? end @@ -3534,22 +3593,22 @@ Did you mean 'Ruby'? def test_latest_specs spec_fetcher do |fetcher| - fetcher.spec 'a', 1 do |s| - s.platform = Gem::Platform.new 'x86-my_platform1' + fetcher.spec "a", 1 do |s| + s.platform = Gem::Platform.new "x86-my_platform1" end - fetcher.spec 'a', 2 + fetcher.spec "a", 2 - fetcher.spec 'a', 2 do |s| - s.platform = Gem::Platform.new 'x86-my_platform1' + fetcher.spec "a", 2 do |s| + s.platform = Gem::Platform.new "x86-my_platform1" end - fetcher.spec 'a', 2 do |s| - s.platform = Gem::Platform.new 'x86-other_platform1' + fetcher.spec "a", 2 do |s| + s.platform = Gem::Platform.new "x86-other_platform1" end - fetcher.spec 'a', 3 do |s| - s.platform = Gem::Platform.new 'x86-other_platform1' + fetcher.spec "a", 3 do |s| + s.platform = Gem::Platform.new "x86-other_platform1" end end @@ -3566,13 +3625,13 @@ Did you mean 'Ruby'? util_setup_validate Dir.chdir @tempdir do - @m1 = quick_gem 'm', '1' do |s| + @m1 = quick_gem "m", "1" do |s| s.files = %w[lib/code.rb] s.metadata = { - "one" => "two", - "home" => "three", + "one" => "two", + "home" => "three", "homepage_uri" => "https://example.com/user/repo", - "funding_uri" => "https://example.com/donate", + "funding_uri" => "https://example.com/donate", } end @@ -3586,7 +3645,7 @@ Did you mean 'Ruby'? util_setup_validate Dir.chdir @tempdir do - @m2 = quick_gem 'm', '2' do |s| + @m2 = quick_gem "m", "2" do |s| s.files = %w[lib/code.rb] s.metadata = { 1 => "fail" } end @@ -3603,7 +3662,7 @@ Did you mean 'Ruby'? util_setup_validate Dir.chdir @tempdir do - @m2 = quick_gem 'm', '2' do |s| + @m2 = quick_gem "m", "2" do |s| s.files = %w[lib/code.rb] s.metadata = { ("x" * 129) => "fail" } end @@ -3612,7 +3671,7 @@ Did you mean 'Ruby'? @m2.validate end - assert_equal "metadata key too large (129 > 128)", e.message + assert_equal "metadata key is too large (129 > 128)", e.message end end @@ -3620,16 +3679,16 @@ Did you mean 'Ruby'? util_setup_validate Dir.chdir @tempdir do - @m2 = quick_gem 'm', '2' do |s| + @m2 = quick_gem "m", "2" do |s| s.files = %w[lib/code.rb] - s.metadata = { 'fail' => [] } + s.metadata = { "fail" => [] } end e = assert_raise Gem::InvalidSpecificationException do @m2.validate end - assert_equal "metadata values must be a String", e.message + assert_equal "metadata['fail'] value must be a String", e.message end end @@ -3637,16 +3696,16 @@ Did you mean 'Ruby'? util_setup_validate Dir.chdir @tempdir do - @m2 = quick_gem 'm', '2' do |s| + @m2 = quick_gem "m", "2" do |s| s.files = %w[lib/code.rb] - s.metadata = { 'fail' => ("x" * 1025) } + s.metadata = { "fail" => ("x" * 1025) } end e = assert_raise Gem::InvalidSpecificationException do @m2.validate end - assert_equal "metadata value too large (1025 > 1024)", e.message + assert_equal "metadata['fail'] value is too large (1025 > 1024)", e.message end end @@ -3654,9 +3713,9 @@ Did you mean 'Ruby'? util_setup_validate Dir.chdir @tempdir do - @m2 = quick_gem 'm', '2' do |s| + @m2 = quick_gem "m", "2" do |s| s.files = %w[lib/code.rb] - s.metadata = { 'homepage_uri' => 'http:/example.com' } + s.metadata = { "homepage_uri" => "http:/example.com" } end e = assert_raise Gem::InvalidSpecificationException do @@ -3667,10 +3726,43 @@ Did you mean 'Ruby'? end end + def test_metadata_link_validation_warns_for_duplicates + util_setup_validate + + Dir.chdir @tempdir do + @m2 = quick_gem "m", "2" do |s| + s.required_ruby_version = ">= 2.3.0" + s.files = %w[lib/code.rb] + s.licenses = "BSD-2-Clause" + s.metadata = { + "source_code_uri" => "http://example.com", + "homepage_uri" => "http://example.com", + "changelog_uri" => "http://example.com/changelog", + } + end + + use_ui @ui do + @m2.validate + end + + expected = <<~EXPECTED + #{w}: You have specified the uri: + http://example.com + for all of the following keys: + homepage_uri + source_code_uri + Only the first one will be shown on rubygems.org + #{w}: See https://guides.rubygems.org/specification-reference/ for help + EXPECTED + + assert_equal expected, @ui.error, "warning" + end + end + def test_metadata_specs - @m1 = quick_gem 'm', '1' do |s| + @m1 = quick_gem "m", "1" do |s| s.files = %w[lib/code.rb] - s.metadata = { 'one' => "two", 'two' => "three" } + s.metadata = { "one" => "two", "two" => "three" } end valid_ruby_spec = <<-EOF @@ -3679,7 +3771,7 @@ Did you mean 'Ruby'? Gem::Specification.new do |s| s.name = "m".freeze - s.version = "1" + s.version = "1".freeze s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version= s.metadata = { "one" => "two", "two" => "three" } if s.respond_to? :metadata= @@ -3699,7 +3791,7 @@ end end def test_missing_extensions_eh - skip "extensions don't quite work on jruby" if Gem.java_platform? + pend "extensions don't quite work on jruby" if Gem.java_platform? ext_spec assert @ext.missing_extensions? @@ -3707,7 +3799,7 @@ end extconf_rb = File.join @ext.gem_dir, @ext.extensions.first FileUtils.mkdir_p File.dirname extconf_rb - File.open extconf_rb, 'w' do |f| + File.open extconf_rb, "w" do |f| f.write <<-'RUBY' File.open 'Makefile', 'w' do |f| f.puts "clean:\n\techo clean" @@ -3723,8 +3815,8 @@ end end def test_missing_extensions_eh_default_gem - spec = new_default_spec 'default', 1 - spec.extensions << 'extconf.rb' + spec = new_default_spec "default", 1 + spec.extensions << "extconf.rb" refute spec.missing_extensions? end @@ -3734,7 +3826,7 @@ end end def test_find_all_by_full_name - pl = Gem::Platform.new 'i386-linux' + pl = Gem::Platform.new "i386-linux" a1 = util_spec "a", "1" a1_pre = util_spec "a", "1.0.0.pre.1" @@ -3778,6 +3870,13 @@ end assert Gem::Specification.find_by_name "q" end + def test_find_by_name_with_only_prereleases_with_requirements + q = util_spec "q", "2.a" + install_specs q + + assert Gem::Specification.find_by_name "q", ">= 1" + end + def test_find_by_name_prerelease b = util_spec "b", "2.a" @@ -3785,6 +3884,8 @@ end install_specs b + Gem::Specification.reset + assert Gem::Specification.find_by_name "b" assert_raise Gem::MissingSpecVersionError do @@ -3794,14 +3895,31 @@ end assert Gem::Specification.find_by_name "b", ">1" end + def test_find_by_full_name + pl = Gem::Platform.new "x86_64-linux" + + a = util_spec "a", "1" + install_specs a + + a_pl = util_spec("a", "1") {|s| s.platform = pl } + install_specs a_pl + + assert_equal a, Gem::Specification.find_by_full_name("a-1") + assert_equal a_pl, Gem::Specification.find_by_full_name("a-1-x86_64-linux") + + assert_nil Gem::Specification.find_by_full_name("a-2") + assert_nil Gem::Specification.find_by_full_name("b-1") + assert_nil Gem::Specification.find_by_full_name("a-1-arm64-linux") + end + def test_find_by_path a = util_spec "foo", "1", nil, "lib/foo.rb" install_specs a - assert_equal a, Gem::Specification.find_by_path('foo') + assert_equal a, Gem::Specification.find_by_path("foo") a.activate - assert_equal a, Gem::Specification.find_by_path('foo') + assert_equal a, Gem::Specification.find_by_path("foo") end def test_find_inactive_by_path @@ -3809,9 +3927,9 @@ end install_specs a - assert_equal a, Gem::Specification.find_inactive_by_path('foo') + assert_equal a, Gem::Specification.find_inactive_by_path("foo") a.activate - assert_nil Gem::Specification.find_inactive_by_path('foo') + assert_nil Gem::Specification.find_inactive_by_path("foo") end def test_load_default_gem @@ -3851,7 +3969,7 @@ end FileUtils.touch File.join("lib", "code.rb") FileUtils.touch File.join("test", "suite.rb") - File.open "bin/exec", "w", 0755 do |fp| + File.open "bin/exec", "w", 0o755 do |fp| fp.puts "#!#{Gem.ruby}" end ensure @@ -3859,54 +3977,4 @@ end end end end - - def with_syck - begin - verbose, $VERBOSE = $VERBOSE, nil - require "yaml" - old_engine = YAML::ENGINE.yamler - YAML::ENGINE.yamler = 'syck' - load 'rubygems/syck_hack.rb' - rescue NameError - # probably on 1.8, ignore - ensure - $VERBOSE = verbose - end - - yield - ensure - begin - YAML::ENGINE.yamler = old_engine - load 'rubygems/syck_hack.rb' - rescue NameError - # ignore - end - end - - def with_psych - begin - require "yaml" - old_engine = YAML::ENGINE.yamler - YAML::ENGINE.yamler = 'psych' - load 'rubygems/syck_hack.rb' - rescue NameError - # probably on 1.8, ignore - end - - yield - ensure - begin - YAML::ENGINE.yamler = old_engine - load 'rubygems/syck_hack.rb' - rescue NameError - # ignore - end - end - - def silence_warnings - old_verbose, $VERBOSE = $VERBOSE, false - yield - ensure - $VERBOSE = old_verbose - end end diff --git a/test/rubygems/test_gem_stream_ui.rb b/test/rubygems/test_gem_stream_ui.rb index 9148ad1385..b1fcb3bc26 100644 --- a/test/rubygems/test_gem_stream_ui.rb +++ b/test/rubygems/test_gem_stream_ui.rb @@ -1,19 +1,20 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/user_interaction' -require 'timeout' + +require_relative "helper" +require "rubygems/user_interaction" +require "rubygems/vendored_timeout" class TestGemStreamUI < Gem::TestCase - # increase timeout with MJIT for --jit-wait testing - mjit_enabled = defined?(RubyVM::JIT) ? RubyVM::JIT.enabled? : defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? - SHORT_TIMEOUT = (RUBY_ENGINE == "ruby" && !mjit_enabled) ? 0.1 : 1.0 + # increase timeout with RJIT for --jit-wait testing + rjit_enabled = defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? + SHORT_TIMEOUT = RUBY_ENGINE == "ruby" && !rjit_enabled ? 0.1 : 1.0 module IsTty attr_accessor :tty def tty? @tty = true unless defined? @tty - return @tty + @tty end alias_method :isatty, :tty? @@ -39,7 +40,7 @@ class TestGemStreamUI < Gem::TestCase end def test_ask - Timeout.timeout(5) do + Gem::Timeout.timeout(5) do expected_answer = "Arthur, King of the Britons" @in.string = "#{expected_answer}\n" actual_answer = @sui.ask("What is your name?") @@ -50,14 +51,14 @@ class TestGemStreamUI < Gem::TestCase def test_ask_no_tty @in.tty = false - Timeout.timeout(SHORT_TIMEOUT) do + Gem::Timeout.timeout(SHORT_TIMEOUT) do answer = @sui.ask("what is your favorite color?") assert_nil answer end end def test_ask_for_password - Timeout.timeout(5) do + Gem::Timeout.timeout(5) do expected_answer = "Arthur, King of the Britons" @in.string = "#{expected_answer}\n" actual_answer = @sui.ask_for_password("What is your name?") @@ -68,7 +69,7 @@ class TestGemStreamUI < Gem::TestCase def test_ask_for_password_no_tty @in.tty = false - Timeout.timeout(SHORT_TIMEOUT) do + Gem::Timeout.timeout(SHORT_TIMEOUT) do answer = @sui.ask_for_password("what is the airspeed velocity of an unladen swallow?") assert_nil answer end @@ -77,7 +78,7 @@ class TestGemStreamUI < Gem::TestCase def test_ask_yes_no_no_tty_with_default @in.tty = false - Timeout.timeout(SHORT_TIMEOUT) do + Gem::Timeout.timeout(SHORT_TIMEOUT) do answer = @sui.ask_yes_no("do coconuts migrate?", false) assert_equal false, answer @@ -89,7 +90,7 @@ class TestGemStreamUI < Gem::TestCase def test_ask_yes_no_no_tty_without_default @in.tty = false - Timeout.timeout(SHORT_TIMEOUT) do + Gem::Timeout.timeout(SHORT_TIMEOUT) do assert_raise(Gem::OperationNotSupportedError) do @sui.ask_yes_no("do coconuts migrate?") end @@ -100,14 +101,44 @@ class TestGemStreamUI < Gem::TestCase @in.puts "1" @in.rewind - result = @sui.choose_from_list 'which one?', %w[foo bar] + result = @sui.choose_from_list "which one?", %w[foo bar] - assert_equal ['foo', 0], result + assert_equal ["foo", 0], result assert_equal "which one?\n 1. foo\n 2. bar\n> ", @out.string end def test_choose_from_list_EOF - result = @sui.choose_from_list 'which one?', %w[foo bar] + result = @sui.choose_from_list "which one?", %w[foo bar] + + assert_equal [nil, nil], result + assert_equal "which one?\n 1. foo\n 2. bar\n> ", @out.string + end + + def test_choose_from_list_0 + @in.puts "0" + @in.rewind + + result = @sui.choose_from_list "which one?", %w[foo bar] + + assert_equal [nil, nil], result + assert_equal "which one?\n 1. foo\n 2. bar\n> ", @out.string + end + + def test_choose_from_list_over + @in.puts "3" + @in.rewind + + result = @sui.choose_from_list "which one?", %w[foo bar] + + assert_equal [nil, nil], result + assert_equal "which one?\n 1. foo\n 2. bar\n> ", @out.string + end + + def test_choose_from_list_negative + @in.puts "-1" + @in.rewind + + result = @sui.choose_from_list "which one?", %w[foo bar] assert_equal [nil, nil], result assert_equal "which one?\n 1. foo\n 2. bar\n> ", @out.string @@ -115,27 +146,27 @@ class TestGemStreamUI < Gem::TestCase def test_progress_reporter_silent_nil @cfg.verbose = nil - reporter = @sui.progress_reporter 10, 'hi' + reporter = @sui.progress_reporter 10, "hi" assert_kind_of Gem::StreamUI::SilentProgressReporter, reporter end def test_progress_reporter_silent_false @cfg.verbose = false - reporter = @sui.progress_reporter 10, 'hi' + reporter = @sui.progress_reporter 10, "hi" assert_kind_of Gem::StreamUI::SilentProgressReporter, reporter assert_equal "", @out.string end def test_progress_reporter_simple @cfg.verbose = true - reporter = @sui.progress_reporter 10, 'hi' + reporter = @sui.progress_reporter 10, "hi" assert_kind_of Gem::StreamUI::SimpleProgressReporter, reporter assert_equal "hi\n", @out.string end def test_progress_reporter_verbose @cfg.verbose = 0 - reporter = @sui.progress_reporter 10, 'hi' + reporter = @sui.progress_reporter 10, "hi" assert_kind_of Gem::StreamUI::VerboseProgressReporter, reporter assert_equal "hi\n", @out.string end @@ -143,7 +174,7 @@ class TestGemStreamUI < Gem::TestCase def test_download_reporter_silent_nil @cfg.verbose = nil reporter = @sui.download_reporter - reporter.fetch 'a.gem', 1024 + reporter.fetch "a.gem", 1024 assert_kind_of Gem::StreamUI::SilentDownloadReporter, reporter assert_equal "", @out.string end @@ -151,7 +182,7 @@ class TestGemStreamUI < Gem::TestCase def test_download_reporter_silent_false @cfg.verbose = false reporter = @sui.download_reporter - reporter.fetch 'a.gem', 1024 + reporter.fetch "a.gem", 1024 assert_kind_of Gem::StreamUI::SilentDownloadReporter, reporter assert_equal "", @out.string end @@ -165,14 +196,14 @@ class TestGemStreamUI < Gem::TestCase def test_threaded_download_reporter @cfg.verbose = true reporter = @sui.download_reporter - reporter.fetch 'a.gem', 1024 + reporter.fetch "a.gem", 1024 assert_equal "Fetching a.gem\n", @out.string end def test_verbose_download_reporter_progress @cfg.verbose = true reporter = @sui.download_reporter - reporter.fetch 'a.gem', 1024 + reporter.fetch "a.gem", 1024 reporter.update 512 assert_equal "Fetching a.gem\n", @out.string end @@ -180,7 +211,7 @@ class TestGemStreamUI < Gem::TestCase def test_verbose_download_reporter_progress_once @cfg.verbose = true reporter = @sui.download_reporter - reporter.fetch 'a.gem', 1024 + reporter.fetch "a.gem", 1024 reporter.update 510 reporter.update 512 assert_equal "Fetching a.gem\n", @out.string @@ -189,7 +220,7 @@ class TestGemStreamUI < Gem::TestCase def test_verbose_download_reporter_progress_complete @cfg.verbose = true reporter = @sui.download_reporter - reporter.fetch 'a.gem', 1024 + reporter.fetch "a.gem", 1024 reporter.update 510 reporter.done assert_equal "Fetching a.gem\n", @out.string @@ -198,7 +229,7 @@ class TestGemStreamUI < Gem::TestCase def test_verbose_download_reporter_progress_nil_length @cfg.verbose = true reporter = @sui.download_reporter - reporter.fetch 'a.gem', nil + reporter.fetch "a.gem", nil reporter.update 1024 reporter.done assert_equal "Fetching a.gem\n", @out.string @@ -207,7 +238,7 @@ class TestGemStreamUI < Gem::TestCase def test_verbose_download_reporter_progress_zero_length @cfg.verbose = true reporter = @sui.download_reporter - reporter.fetch 'a.gem', 0 + reporter.fetch "a.gem", 0 reporter.update 1024 reporter.done assert_equal "Fetching a.gem\n", @out.string @@ -218,7 +249,7 @@ class TestGemStreamUI < Gem::TestCase @cfg.verbose = true reporter = @sui.download_reporter - reporter.fetch 'a.gem', 1024 + reporter.fetch "a.gem", 1024 assert_equal "", @out.string end end diff --git a/test/rubygems/test_gem_stub_specification.rb b/test/rubygems/test_gem_stub_specification.rb index ff74fd19ca..fe30a78c0b 100644 --- a/test/rubygems/test_gem_stub_specification.rb +++ b/test/rubygems/test_gem_stub_specification.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -require "rubygems/test_case" + +require_relative "helper" require "rubygems/stub_specification" class TestStubSpecification < Gem::TestCase @@ -10,7 +11,7 @@ class TestStubSpecification < Gem::TestCase super @base_dir = __dir__ - @gems_dir = File.join __dir__, 'gem' + @gems_dir = File.join __dir__, "gem" @foo = Gem::StubSpecification.gemspec_stub FOO, @base_dir, @gems_dir end @@ -25,24 +26,24 @@ class TestStubSpecification < Gem::TestCase def test_initialize_extension stub = stub_with_extension - assert_equal 'stub_e', stub.name + assert_equal "stub_e", stub.name assert_equal v(2), stub.version assert_equal Gem::Platform::RUBY, stub.platform - assert_equal [stub.extension_dir, 'lib'], stub.require_paths + assert_equal [stub.extension_dir, "lib"], stub.require_paths assert_equal %w[ext/stub_e/extconf.rb], stub.extensions end def test_initialize_version stub = stub_with_version - assert_equal 'stub_v', stub.name + assert_equal "stub_v", stub.name assert_equal v(2), stub.version end def test_initialize_with_empty_version stub = stub_without_version - assert_equal 'stub_v', stub.name + assert_equal "stub_v", stub.name assert_equal v(0), stub.version end @@ -57,21 +58,21 @@ class TestStubSpecification < Gem::TestCase def test_contains_requirable_file_eh stub = stub_without_extension - code_rb = File.join stub.gem_dir, 'lib', 'code.rb' + code_rb = File.join stub.gem_dir, "lib", "code.rb" FileUtils.mkdir_p File.dirname code_rb FileUtils.touch code_rb - assert stub.contains_requirable_file? 'code' + assert stub.contains_requirable_file? "code" end def test_contains_requirable_file_eh_extension - skip "I guess making the stub match the running platform should work" if Gem.java_platform? + pend "I guess making the stub match the running platform should work" if Gem.java_platform? stub_with_extension do |stub| _, err = capture_output do - refute stub.contains_requirable_file? 'nonexistent' + refute stub.contains_requirable_file? "nonexistent" end - expected = "Ignoring stub_e-2 because its extensions are not built. " + + expected = "Ignoring stub_e-2 because its extensions are not built. " \ "Try: gem pristine stub_e --version 2\n" assert_equal expected, err @@ -82,7 +83,7 @@ class TestStubSpecification < Gem::TestCase stub = stub_with_extension expected = [ - File.join(stub.full_gem_path, 'lib'), + File.join(stub.full_gem_path, "lib"), stub.extension_dir, ] @@ -92,42 +93,42 @@ class TestStubSpecification < Gem::TestCase def test_lib_dirs_glob stub = stub_without_extension - assert_equal File.join(stub.full_gem_path, 'lib'), stub.lib_dirs_glob + assert_equal File.join(stub.full_gem_path, "lib"), stub.lib_dirs_glob end def test_lib_dirs_glob_with_extension stub = stub_with_extension - assert_equal File.join(stub.full_gem_path, 'lib'), stub.lib_dirs_glob + assert_equal File.join(stub.full_gem_path, "lib"), stub.lib_dirs_glob end def test_matches_for_glob stub = stub_without_extension - code_rb = File.join stub.gem_dir, 'lib', 'code.rb' + code_rb = File.join stub.gem_dir, "lib", "code.rb" FileUtils.mkdir_p File.dirname code_rb FileUtils.touch code_rb - assert_equal code_rb, stub.matches_for_glob('code*').first + assert_equal code_rb, stub.matches_for_glob("code*").first end def test_matches_for_glob_with_bundler_inline stub = stub_with_extension - code_rb = File.join stub.gem_dir, 'lib', 'code.rb' + code_rb = File.join stub.gem_dir, "lib", "code.rb" FileUtils.mkdir_p File.dirname code_rb FileUtils.touch code_rb stub.stub(:raw_require_paths, nil) do - assert_equal code_rb, stub.matches_for_glob('code*').first + assert_equal code_rb, stub.matches_for_glob("code*").first end end def test_missing_extensions_eh - skip "I guess making the stub match the running platform should work" if Gem.java_platform? + pend "I guess making the stub match the running platform should work" if Gem.java_platform? stub = stub_with_extension do |s| extconf_rb = File.join s.gem_dir, s.extensions.first FileUtils.mkdir_p File.dirname extconf_rb - File.open extconf_rb, 'w' do |f| + File.open extconf_rb, "w" do |f| f.write <<-'RUBY' File.open 'Makefile', 'w' do |f| f.puts "clean:\n\techo clean" @@ -146,10 +147,10 @@ class TestStubSpecification < Gem::TestCase end def test_missing_extensions_eh_default_gem - spec = new_default_spec 'default', 1 - spec.extensions << 'extconf.rb' + spec = new_default_spec "default", 1 + spec.extensions << "extconf.rb" - File.open spec.loaded_from, 'w' do |io| + File.open spec.loaded_from, "w" do |io| io.write spec.to_ruby_for_cache end @@ -167,7 +168,7 @@ class TestStubSpecification < Gem::TestCase real_foo.activate assert_equal @foo.version, Gem.loaded_specs[@foo.name].version, - 'sanity check' + "sanity check" assert_same real_foo, @foo.to_spec end @@ -180,25 +181,9 @@ class TestStubSpecification < Gem::TestCase assert bar.to_spec end - def test_to_spec_activated - assert @foo.to_spec.is_a?(Gem::Specification) - assert_equal "foo", @foo.to_spec.name - refute @foo.to_spec.instance_variable_get :@ignored - end - - def test_to_spec_missing_extensions - stub = stub_with_extension - - capture_output do - stub.contains_requirable_file? 'nonexistent' - end - - assert stub.to_spec.instance_variable_get :@ignored - end - def stub_with_version - spec = File.join @gemhome, 'specifications', 'stub_e-2.gemspec' - File.open spec, 'w' do |io| + spec = File.join @gemhome, "specifications", "stub_e-2.gemspec" + File.open spec, "w" do |io| io.write <<-STUB # -*- encoding: utf-8 -*- # stub: stub_v 2 ruby lib @@ -211,7 +196,7 @@ end io.flush - stub = Gem::StubSpecification.gemspec_stub io.path, @gemhome, File.join(@gemhome, 'gems') + stub = Gem::StubSpecification.gemspec_stub io.path, @gemhome, File.join(@gemhome, "gems") yield stub if block_given? @@ -220,8 +205,8 @@ end end def stub_without_version - spec = File.join @gemhome, 'specifications', 'stub-2.gemspec' - File.open spec, 'w' do |io| + spec = File.join @gemhome, "specifications", "stub-2.gemspec" + File.open spec, "w" do |io| io.write <<-STUB # -*- encoding: utf-8 -*- # stub: stub_v ruby lib @@ -234,7 +219,7 @@ end io.flush - stub = Gem::StubSpecification.gemspec_stub io.path, @gemhome, File.join(@gemhome, 'gems') + stub = Gem::StubSpecification.gemspec_stub io.path, @gemhome, File.join(@gemhome, "gems") yield stub if block_given? @@ -243,8 +228,8 @@ end end def stub_with_extension - spec = File.join @gemhome, 'specifications', 'stub_e-2.gemspec' - File.open spec, 'w' do |io| + spec = File.join @gemhome, "specifications", "stub_e-2.gemspec" + File.open spec, "w" do |io| io.write <<-STUB # -*- encoding: utf-8 -*- # stub: stub_e 2 ruby lib @@ -260,7 +245,7 @@ end io.flush - stub = Gem::StubSpecification.gemspec_stub io.path, @gemhome, File.join(@gemhome, 'gems') + stub = Gem::StubSpecification.gemspec_stub io.path, @gemhome, File.join(@gemhome, "gems") yield stub if block_given? @@ -269,8 +254,8 @@ end end def stub_without_extension - spec = File.join @gemhome, 'specifications', 'stub-2.gemspec' - File.open spec, 'w' do |io| + spec = File.join @gemhome, "specifications", "stub-2.gemspec" + File.open spec, "w" do |io| io.write <<-STUB # -*- encoding: utf-8 -*- # stub: stub 2 ruby lib @@ -283,7 +268,7 @@ end io.flush - stub = Gem::StubSpecification.gemspec_stub io.path, @gemhome, File.join(@gemhome, 'gems') + stub = Gem::StubSpecification.gemspec_stub io.path, @gemhome, File.join(@gemhome, "gems") yield stub if block_given? diff --git a/test/rubygems/test_gem_text.rb b/test/rubygems/test_gem_text.rb index d9f024f1e6..8e99610946 100644 --- a/test/rubygems/test_gem_text.rb +++ b/test/rubygems/test_gem_text.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" require "rubygems/text" class TestGemText < Gem::TestCase diff --git a/test/rubygems/test_gem_uninstaller.rb b/test/rubygems/test_gem_uninstaller.rb index 657addf6d9..9e0c1aa3d8 100644 --- a/test/rubygems/test_gem_uninstaller.rb +++ b/test/rubygems/test_gem_uninstaller.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/installer_test_case' -require 'rubygems/uninstaller' + +require_relative "installer_test_case" +require "rubygems/uninstaller" class TestGemUninstaller < Gem::InstallerTestCase def setup @@ -23,14 +24,14 @@ class TestGemUninstaller < Gem::InstallerTestCase end def test_initialize_expand_path - FileUtils.mkdir_p 'foo/bar' - uninstaller = Gem::Uninstaller.new nil, :install_dir => 'foo//bar' + FileUtils.mkdir_p "foo/bar" + uninstaller = Gem::Uninstaller.new nil, install_dir: "foo//bar" assert_match %r{foo/bar$}, uninstaller.instance_variable_get(:@gem_home) end def test_ask_if_ok - c = util_spec 'c' + c = util_spec "c" uninstaller = Gem::Uninstaller.new nil @@ -58,10 +59,10 @@ class TestGemUninstaller < Gem::InstallerTestCase end def test_remove_executables_force_keep - uninstaller = Gem::Uninstaller.new nil, :executables => false + uninstaller = Gem::Uninstaller.new nil, executables: false - executable = File.join Gem.bindir(@user_spec.base_dir), 'executable' - assert File.exist?(executable), 'executable not written' + executable = File.join Gem.bindir(@user_spec.base_dir), "executable" + assert File.exist?(executable), "executable not written" use_ui @ui do uninstaller.remove_executables @user_spec @@ -73,10 +74,10 @@ class TestGemUninstaller < Gem::InstallerTestCase end def test_remove_executables_force_remove - uninstaller = Gem::Uninstaller.new nil, :executables => true + uninstaller = Gem::Uninstaller.new nil, executables: true - executable = File.join Gem.bindir(@user_spec.base_dir), 'executable' - assert File.exist?(executable), 'executable not written' + executable = File.join Gem.bindir(@user_spec.base_dir), "executable" + assert File.exist?(executable), "executable not written" use_ui @ui do uninstaller.remove_executables @user_spec @@ -88,29 +89,29 @@ class TestGemUninstaller < Gem::InstallerTestCase end def test_remove_executables_user - uninstaller = Gem::Uninstaller.new nil, :executables => true + uninstaller = Gem::Uninstaller.new nil, executables: true use_ui @ui do uninstaller.remove_executables @user_spec end - exec_path = File.join Gem.user_dir, 'bin', 'executable' - refute File.exist?(exec_path), 'exec still exists in user bin dir' + exec_path = File.join Gem.user_dir, "bin", "executable" + refute File.exist?(exec_path), "exec still exists in user bin dir" assert_equal "Removing executable\n", @ui.output end def test_remove_executables_user_format - Gem::Installer.exec_format = 'foo-%s-bar' + Gem::Installer.exec_format = "foo-%s-bar" - uninstaller = Gem::Uninstaller.new nil, :executables => true, :format_executable => true + uninstaller = Gem::Uninstaller.new nil, executables: true, format_executable: true use_ui @ui do uninstaller.remove_executables @user_spec end - exec_path = File.join Gem.user_dir, 'bin', 'foo-executable-bar' - assert_equal false, File.exist?(exec_path), 'removed exec from bin dir' + exec_path = File.join Gem.user_dir, "bin", "foo-executable-bar" + assert_equal false, File.exist?(exec_path), "removed exec from bin dir" assert_equal "Removing foo-executable-bar\n", @ui.output ensure @@ -118,16 +119,16 @@ class TestGemUninstaller < Gem::InstallerTestCase end def test_remove_executables_user_format_disabled - Gem::Installer.exec_format = 'foo-%s-bar' + Gem::Installer.exec_format = "foo-%s-bar" - uninstaller = Gem::Uninstaller.new nil, :executables => true + uninstaller = Gem::Uninstaller.new nil, executables: true use_ui @ui do uninstaller.remove_executables @user_spec end - exec_path = File.join Gem.user_dir, 'bin', 'executable' - refute File.exist?(exec_path), 'removed exec from bin dir' + exec_path = File.join Gem.user_dir, "bin", "executable" + refute File.exist?(exec_path), "removed exec from bin dir" assert_equal "Removing executable\n", @ui.output ensure @@ -136,7 +137,7 @@ class TestGemUninstaller < Gem::InstallerTestCase def test_remove_not_in_home Dir.mkdir "#{@gemhome}2" - uninstaller = Gem::Uninstaller.new nil, :install_dir => "#{@gemhome}2" + uninstaller = Gem::Uninstaller.new nil, install_dir: "#{@gemhome}2" e = assert_raise Gem::GemNotInHomeException do use_ui ui do @@ -153,14 +154,14 @@ class TestGemUninstaller < Gem::InstallerTestCase end def test_remove_symlinked_gem_home - skip "Symlinks not supported or not enabled" unless symlink_supported? + pend "Symlinks not supported or not enabled" unless symlink_supported? Dir.mktmpdir("gem_home") do |dir| symlinked_gem_home = "#{dir}/#{File.basename(@gemhome)}" FileUtils.ln_s(@gemhome, dir) - uninstaller = Gem::Uninstaller.new nil, :install_dir => symlinked_gem_home + uninstaller = Gem::Uninstaller.new nil, install_dir: symlinked_gem_home use_ui ui do uninstaller.remove @spec @@ -171,56 +172,56 @@ class TestGemUninstaller < Gem::InstallerTestCase end def test_remove_plugins - write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io| - io.write "puts __FILE__" + write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io| + io.write "# do nothing" end @spec.files += %w[lib/rubygems_plugin.rb] - Gem::Installer.at(Gem::Package.build(@spec), :force => true).install + Gem::Installer.at(Gem::Package.build(@spec), force: true).install - plugin_path = File.join Gem.plugindir, 'a_plugin.rb' - assert File.exist?(plugin_path), 'plugin not written' + plugin_path = File.join Gem.plugindir, "a_plugin.rb" + assert File.exist?(plugin_path), "plugin not written" Gem::Uninstaller.new(nil).remove_plugins @spec - refute File.exist?(plugin_path), 'plugin not removed' + refute File.exist?(plugin_path), "plugin not removed" end def test_remove_plugins_with_install_dir - write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io| - io.write "puts __FILE__" + write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io| + io.write "# do nothing" end @spec.files += %w[lib/rubygems_plugin.rb] - Gem::Installer.at(Gem::Package.build(@spec), :force => true).install + Gem::Installer.at(Gem::Package.build(@spec), force: true).install - plugin_path = File.join Gem.plugindir, 'a_plugin.rb' - assert File.exist?(plugin_path), 'plugin not written' + plugin_path = File.join Gem.plugindir, "a_plugin.rb" + assert File.exist?(plugin_path), "plugin not written" Dir.mkdir "#{@gemhome}2" - Gem::Uninstaller.new(nil, :install_dir => "#{@gemhome}2").remove_plugins @spec + Gem::Uninstaller.new(nil, install_dir: "#{@gemhome}2").remove_plugins @spec - assert File.exist?(plugin_path), 'plugin unintentionally removed' + assert File.exist?(plugin_path), "plugin unintentionally removed" end def test_regenerate_plugins_for - write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io| - io.write "puts __FILE__" + write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io| + io.write "# do nothing" end @spec.files += %w[lib/rubygems_plugin.rb] - Gem::Installer.at(Gem::Package.build(@spec), :force => true).install + Gem::Installer.at(Gem::Package.build(@spec), force: true).install - plugin_path = File.join Gem.plugindir, 'a_plugin.rb' - assert File.exist?(plugin_path), 'plugin not written' + plugin_path = File.join Gem.plugindir, "a_plugin.rb" + assert File.exist?(plugin_path), "plugin not written" FileUtils.rm plugin_path Gem::Uninstaller.new(nil).regenerate_plugins_for @spec, Gem.plugindir - assert File.exist?(plugin_path), 'plugin not regenerated' + assert File.exist?(plugin_path), "plugin not regenerated" end def test_path_ok_eh @@ -234,7 +235,7 @@ class TestGemUninstaller < Gem::InstallerTestCase @spec.loaded_from = @spec.loaded_from.gsub @spec.full_name, '\&-legacy' @spec.internal_init # blow out cache. but why did ^^ depend on cache? - @spec.platform = 'legacy' + @spec.platform = "legacy" assert_equal true, uninstaller.path_ok?(@gemhome, @spec) end @@ -246,18 +247,18 @@ class TestGemUninstaller < Gem::InstallerTestCase end def test_uninstall - uninstaller = Gem::Uninstaller.new @spec.name, :executables => true + uninstaller = Gem::Uninstaller.new @spec.name, executables: true - gem_dir = File.join @gemhome, 'gems', @spec.full_name + gem_dir = File.join @gemhome, "gems", @spec.full_name Gem.pre_uninstall do - sleep(0.1) if win_platform? - assert File.exist?(gem_dir), 'gem_dir should exist' + sleep(0.1) if Gem.win_platform? + assert File.exist?(gem_dir), "gem_dir should exist" end Gem.post_uninstall do - sleep(0.1) if win_platform? - refute File.exist?(gem_dir), 'gem_dir should not exist' + sleep(0.1) if Gem.win_platform? + refute File.exist?(gem_dir), "gem_dir should not exist" end uninstaller.uninstall @@ -269,11 +270,11 @@ class TestGemUninstaller < Gem::InstallerTestCase end def test_uninstall_default_gem - spec = new_default_spec 'default', '2' + spec = new_default_spec "default", "2" install_default_gems spec - uninstaller = Gem::Uninstaller.new spec.name, :executables => true + uninstaller = Gem::Uninstaller.new spec.name, executables: true use_ui @ui do uninstaller.uninstall @@ -281,28 +282,35 @@ class TestGemUninstaller < Gem::InstallerTestCase lines = @ui.output.split("\n") - assert_equal 'Gem default-2 cannot be uninstalled because it is a default gem', lines.shift + assert_equal "Gem default-2 cannot be uninstalled because it is a default gem", lines.shift end def test_uninstall_default_gem_with_same_version - default_spec = new_default_spec 'default', '2' + default_spec = new_default_spec "default", "2" install_default_gems default_spec - spec = util_spec 'default', '2' + spec = util_spec "default", "2" install_gem spec Gem::Specification.reset - uninstaller = Gem::Uninstaller.new spec.name, :executables => true - - uninstaller.uninstall + uninstaller = Gem::Uninstaller.new spec.name, executables: true + ui = Gem::MockGemUi.new "1\ny\n" + use_ui ui do + uninstaller.uninstall + end + expected = "Successfully uninstalled default-2\n" \ + "There was both a regular copy and a default copy of default-2. The " \ + "regular copy was successfully uninstalled, but the default copy " \ + "was left around because default gems can't be removed.\n" + assert_equal expected, ui.output assert_path_not_exist spec.gem_dir end def test_uninstall_extension - @spec.extensions << 'extconf.rb' - write_file File.join(@tempdir, 'extconf.rb') do |io| + @spec.extensions << "extconf.rb" + write_file File.join(@tempdir, "extconf.rb") do |io| io.write <<-RUBY require 'mkmf' create_makefile '#{@spec.name}' @@ -314,20 +322,20 @@ create_makefile '#{@spec.name}' use_ui @ui do path = Gem::Package.build @spec - installer = Gem::Installer.at path, :force => true + installer = Gem::Installer.at path, force: true installer.install end - assert_path_exist @spec.extension_dir, 'sanity check' + assert_path_exist @spec.extension_dir, "sanity check" - uninstaller = Gem::Uninstaller.new @spec.name, :executables => true + uninstaller = Gem::Uninstaller.new @spec.name, executables: true uninstaller.uninstall assert_path_not_exist @spec.extension_dir end def test_uninstall_nonexistent - uninstaller = Gem::Uninstaller.new 'bogus', :executables => true + uninstaller = Gem::Uninstaller.new "bogus", executables: true e = assert_raise Gem::InstallError do uninstaller.uninstall @@ -337,17 +345,17 @@ create_makefile '#{@spec.name}' end def test_uninstall_not_ok - quick_gem 'z' do |s| + quick_gem "z" do |s| s.add_runtime_dependency @spec.name end uninstaller = Gem::Uninstaller.new @spec.name - gem_dir = File.join @gemhome, 'gems', @spec.full_name - executable = File.join @gemhome, 'bin', 'executable' + gem_dir = File.join @gemhome, "gems", @spec.full_name + executable = File.join @gemhome, "bin", "executable" - assert File.exist?(gem_dir), 'gem_dir must exist' - assert File.exist?(executable), 'executable must exist' + assert File.exist?(gem_dir), "gem_dir must exist" + assert File.exist?(executable), "executable must exist" ui = Gem::MockGemUi.new "n\n" @@ -357,16 +365,16 @@ create_makefile '#{@spec.name}' end end - assert File.exist?(gem_dir), 'gem_dir must still exist' - assert File.exist?(executable), 'executable must still exist' + assert File.exist?(gem_dir), "gem_dir must still exist" + assert File.exist?(executable), "executable must still exist" end def test_uninstall_user_install - @user_spec = Gem::Specification.find_by_name 'b' + @user_spec = Gem::Specification.find_by_name "b" uninstaller = Gem::Uninstaller.new(@user_spec.name, - :executables => true, - :user_install => true) + executables: true, + user_install: true) gem_dir = File.join @user_spec.gem_dir @@ -390,7 +398,7 @@ create_makefile '#{@spec.name}' Dir.mkdir "#{@gemhome}2" Gem.use_paths "#{@gemhome}2", [@gemhome] - uninstaller = Gem::Uninstaller.new @spec.name, :executables => true + uninstaller = Gem::Uninstaller.new @spec.name, executables: true e = assert_raise Gem::InstallError do uninstaller.uninstall @@ -407,9 +415,9 @@ create_makefile '#{@spec.name}' def test_uninstall_selection util_make_gems - list = Gem::Specification.find_all_by_name 'a' + list = Gem::Specification.find_all_by_name "a" - uninstaller = Gem::Uninstaller.new 'a' + uninstaller = Gem::Uninstaller.new "a" ui = Gem::MockGemUi.new "1\ny\n" @@ -417,39 +425,39 @@ create_makefile '#{@spec.name}' uninstaller.uninstall end - updated_list = Gem::Specification.find_all_by_name('a') + updated_list = Gem::Specification.find_all_by_name("a") assert_equal list.length - 1, updated_list.length - assert_match ' 1. a-1', ui.output - assert_match ' 2. a-2', ui.output - assert_match ' 3. a-3.a', ui.output - assert_match ' 4. All versions', ui.output - assert_match 'uninstalled a-1', ui.output + assert_match " 1. a-1", ui.output + assert_match " 2. a-2", ui.output + assert_match " 3. a-3.a", ui.output + assert_match " 4. All versions", ui.output + assert_match "uninstalled a-1", ui.output end def test_uninstall_selection_greater_than_one util_make_gems - list = Gem::Specification.find_all_by_name('a') + list = Gem::Specification.find_all_by_name("a") - uninstaller = Gem::Uninstaller.new('a') + uninstaller = Gem::Uninstaller.new("a") use_ui Gem::MockGemUi.new("2\ny\n") do uninstaller.uninstall end - updated_list = Gem::Specification.find_all_by_name('a') + updated_list = Gem::Specification.find_all_by_name("a") assert_equal list.length - 1, updated_list.length end def test_uninstall_prompts_about_broken_deps - quick_gem 'r', '1' do |s| - s.add_dependency 'q', '= 1' + quick_gem "r", "1" do |s| + s.add_dependency "q", "= 1" end - quick_gem 'q', '1' + quick_gem "q", "1" - un = Gem::Uninstaller.new('q') + un = Gem::Uninstaller.new("q") ui = Gem::MockGemUi.new("y\n") use_ui ui do @@ -459,27 +467,27 @@ create_makefile '#{@spec.name}' lines = ui.output.split("\n") lines.shift - assert_match %r{You have requested to uninstall the gem:}, lines.shift + assert_match(/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 + assert_match(/r-1 depends on q \(= 1\)/, lines.shift) + assert_match(/Successfully uninstalled q-1/, lines.last) end def test_uninstall_only_lists_unsatisfied_deps - quick_gem 'r', '1' do |s| - s.add_dependency 'q', '~> 1.0' + quick_gem "r", "1" do |s| + s.add_dependency "q", "~> 1.0" end - quick_gem 'x', '1' do |s| - s.add_dependency 'q', '= 1.0' + quick_gem "x", "1" do |s| + s.add_dependency "q", "= 1.0" end - quick_gem 'q', '1.0' - quick_gem 'q', '1.1' + quick_gem "q", "1.0" + quick_gem "q", "1.1" - un = Gem::Uninstaller.new('q', :version => "1.0") + un = Gem::Uninstaller.new("q", version: "1.0") ui = Gem::MockGemUi.new("y\n") use_ui ui do @@ -489,23 +497,23 @@ create_makefile '#{@spec.name}' lines = ui.output.split("\n") lines.shift - assert_match %r{You have requested to uninstall the gem:}, lines.shift + assert_match(/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 + assert_match(/x-1 depends on q \(= 1.0\)/, lines.shift) + assert_match(/Successfully uninstalled q-1.0/, lines.last) end def test_uninstall_doesnt_prompt_when_other_gem_satisfies_requirement - quick_gem 'r', '1' do |s| - s.add_dependency 'q', '~> 1.0' + quick_gem "r", "1" do |s| + s.add_dependency "q", "~> 1.0" end - quick_gem 'q', '1.0' - quick_gem 'q', '1.1' + quick_gem "q", "1.0" + quick_gem "q", "1.1" - un = Gem::Uninstaller.new('q', :version => "1.0") + un = Gem::Uninstaller.new("q", version: "1.0") ui = Gem::MockGemUi.new("y\n") use_ui ui do @@ -518,13 +526,13 @@ create_makefile '#{@spec.name}' end def test_uninstall_doesnt_prompt_when_removing_a_dev_dep - quick_gem 'r', '1' do |s| - s.add_development_dependency 'q', '= 1.0' + quick_gem "r", "1" do |s| + s.add_development_dependency "q", "= 1.0" end - quick_gem 'q', '1.0' + quick_gem "q", "1.0" - un = Gem::Uninstaller.new('q', :version => "1.0") + un = Gem::Uninstaller.new("q", version: "1.0") ui = Gem::MockGemUi.new("y\n") use_ui ui do @@ -537,13 +545,13 @@ create_makefile '#{@spec.name}' end def test_uninstall_doesnt_prompt_and_raises_when_abort_on_dependent_set - quick_gem 'r', '1' do |s| - s.add_dependency 'q', '= 1' + quick_gem "r", "1" do |s| + s.add_dependency "q", "= 1" end - quick_gem 'q', '1' + quick_gem "q", "1" - un = Gem::Uninstaller.new('q', :abort_on_dependent => true) + un = Gem::Uninstaller.new("q", abort_on_dependent: true) ui = Gem::MockGemUi.new("y\n") assert_raise Gem::DependencyRemovalException do @@ -554,13 +562,13 @@ create_makefile '#{@spec.name}' end def test_uninstall_prompt_includes_dep_type - quick_gem 'r', '1' do |s| - s.add_development_dependency 'q', '= 1' + quick_gem "r", "1" do |s| + s.add_development_dependency "q", "= 1" end - quick_gem 'q', '1' + quick_gem "q", "1" - un = Gem::Uninstaller.new('q', :check_dev => true) + un = Gem::Uninstaller.new("q", check_dev: true) ui = Gem::MockGemUi.new("y\n") use_ui ui do @@ -570,26 +578,26 @@ create_makefile '#{@spec.name}' lines = ui.output.split("\n") lines.shift - assert_match %r{You have requested to uninstall the gem:}, lines.shift + assert_match(/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 + assert_match(/r-1 depends on q \(= 1, development\)/, lines.shift) + assert_match(/Successfully uninstalled q-1/, lines.last) end def test_uninstall_prompt_only_lists_the_dependents_that_prevented_uninstallation - quick_gem 'r', '1' do |s| - s.add_development_dependency 'q', '= 1' + quick_gem "r", "1" do |s| + s.add_development_dependency "q", "= 1" end - quick_gem 's', '1' do |s| - s.add_dependency 'q', '= 1' + quick_gem "s", "1" do |s| + s.add_dependency "q", "= 1" end - quick_gem 'q', '1' + quick_gem "q", "1" - un = Gem::Uninstaller.new('q', :check_dev => false) + un = Gem::Uninstaller.new("q", check_dev: false) ui = Gem::MockGemUi.new("y\n") use_ui ui do @@ -599,16 +607,16 @@ create_makefile '#{@spec.name}' lines = ui.output.split("\n") lines.shift - assert_match %r{You have requested to uninstall the gem:}, lines.shift + assert_match(/You have requested to uninstall the gem:/, lines.shift) lines.shift lines.shift - assert_match %r{s-1 depends on q \(= 1\)}, lines.shift - assert_match %r{Successfully uninstalled q-1}, lines.last + assert_match(/s-1 depends on q \(= 1\)/, lines.shift) + assert_match(/Successfully uninstalled q-1/, lines.last) end def test_uninstall_no_permission - uninstaller = Gem::Uninstaller.new @spec.name, :executables => true + uninstaller = Gem::Uninstaller.new @spec.name, executables: true stub_rm_r = lambda do |*args| _path = args.shift @@ -626,42 +634,42 @@ create_makefile '#{@spec.name}' end def test_uninstall_keeps_plugins_up_to_date - write_file File.join(@tempdir, 'lib', 'rubygems_plugin.rb') do |io| - io.write "puts __FILE__" + write_file File.join(@tempdir, "lib", "rubygems_plugin.rb") do |io| + io.write "# do nothing" end - plugin_path = File.join Gem.plugindir, 'a_plugin.rb' + plugin_path = File.join Gem.plugindir, "a_plugin.rb" - @spec.version = '1' - Gem::Installer.at(Gem::Package.build(@spec), :force => true).install + @spec.version = "1" + Gem::Installer.at(Gem::Package.build(@spec), force: true).install - refute File.exist?(plugin_path), 'version without plugin installed, but plugin written' + refute File.exist?(plugin_path), "version without plugin installed, but plugin written" @spec.files += %w[lib/rubygems_plugin.rb] - @spec.version = '2' - Gem::Installer.at(Gem::Package.build(@spec), :force => true).install + @spec.version = "2" + Gem::Installer.at(Gem::Package.build(@spec), force: true).install - assert File.exist?(plugin_path), 'version with plugin installed, but plugin not written' - assert_match %r{\Arequire.*a-2/lib/rubygems_plugin\.rb}, File.read(plugin_path), 'written plugin has incorrect content' + assert File.exist?(plugin_path), "version with plugin installed, but plugin not written" + assert_match %r{\Arequire.*a-2/lib/rubygems_plugin\.rb}, File.read(plugin_path), "written plugin has incorrect content" - @spec.version = '3' - Gem::Installer.at(Gem::Package.build(@spec), :force => true).install + @spec.version = "3" + Gem::Installer.at(Gem::Package.build(@spec), force: true).install - assert File.exist?(plugin_path), 'version with plugin installed, but plugin removed' - assert_match %r{\Arequire.*a-3/lib/rubygems_plugin\.rb}, File.read(plugin_path), 'old version installed, but plugin updated' + assert File.exist?(plugin_path), "version with plugin installed, but plugin removed" + assert_match %r{\Arequire.*a-3/lib/rubygems_plugin\.rb}, File.read(plugin_path), "old version installed, but plugin updated" - Gem::Uninstaller.new('a', :version => '1', :executables => true).uninstall + Gem::Uninstaller.new("a", version: "1", executables: true).uninstall - assert File.exist?(plugin_path), 'plugin removed when old version uninstalled' - assert_match %r{\Arequire.*a-3/lib/rubygems_plugin\.rb}, File.read(plugin_path), 'old version uninstalled, but plugin updated' + assert File.exist?(plugin_path), "plugin removed when old version uninstalled" + assert_match %r{\Arequire.*a-3/lib/rubygems_plugin\.rb}, File.read(plugin_path), "old version uninstalled, but plugin updated" - Gem::Uninstaller.new('a', version: '3', :executables => true).uninstall + Gem::Uninstaller.new("a", version: "3", executables: true).uninstall - assert File.exist?(plugin_path), 'plugin removed when old version uninstalled and another version with plugin still present' - assert_match %r{\Arequire.*a-2/lib/rubygems_plugin\.rb}, File.read(plugin_path), 'latest version uninstalled, but plugin not updated to previous version' + assert File.exist?(plugin_path), "plugin removed when old version uninstalled and another version with plugin still present" + assert_match %r{\Arequire.*a-2/lib/rubygems_plugin\.rb}, File.read(plugin_path), "latest version uninstalled, but plugin not updated to previous version" - Gem::Uninstaller.new('a', version: '2', :executables => true).uninstall + Gem::Uninstaller.new("a", version: "2", executables: true).uninstall - refute File.exist?(plugin_path), 'last version uninstalled, but plugin still present' + refute File.exist?(plugin_path), "last version uninstalled, but plugin still present" end end diff --git a/test/rubygems/test_gem_unsatisfiable_dependency_error.rb b/test/rubygems/test_gem_unsatisfiable_dependency_error.rb index 7950efb2a9..5202010dac 100644 --- a/test/rubygems/test_gem_unsatisfiable_dependency_error.rb +++ b/test/rubygems/test_gem_unsatisfiable_dependency_error.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" class TestGemUnsatisfiableDependencyError < Gem::TestCase def setup super - @a_dep = dep 'a', '~> 1' + @a_dep = dep "a", "~> 1" @req = Gem::Resolver::DependencyRequest.new @a_dep, nil @@ -21,7 +22,7 @@ class TestGemUnsatisfiableDependencyError < Gem::TestCase end def test_name - assert_equal 'a', @e.name + assert_equal "a", @e.name end def test_version diff --git a/test/rubygems/test_gem_update_suggestion.rb b/test/rubygems/test_gem_update_suggestion.rb new file mode 100644 index 0000000000..8cb8ee57ff --- /dev/null +++ b/test/rubygems/test_gem_update_suggestion.rb @@ -0,0 +1,209 @@ +# frozen_string_literal: true + +require_relative "helper" +require "rubygems/command" +require "rubygems/update_suggestion" + +class TestUpdateSuggestion < Gem::TestCase + def setup + super + + @cmd = Gem::Command.new "dummy", "dummy" + @cmd.extend Gem::UpdateSuggestion + @start_time = 1_000_000 + @minute = 60 * 60 + @week = 7 * 24 * @minute + end + + def with_eligible_environment(**params) + self.class.with_eligible_environment(**params) do + yield + end + end + + def self.with_eligible_environment( + tty: true, + rubygems_version: Gem::Version.new("1.2.3"), + latest_rubygems_version: Gem::Version.new("2.0.0"), + ci: false, + reset_last_update_check: true, + cmd: + ) + original_config = Gem.configuration[:prevent_update_suggestion] + Gem.configuration[:prevent_update_suggestion] = nil + original_env = ENV["RUBYGEMS_PREVENT_UPDATE_SUGGESTION"] + ENV["RUBYGEMS_PREVENT_UPDATE_SUGGESTION"] = nil + original_disable = Gem.disable_system_update_message + Gem.disable_system_update_message = nil + Gem.configuration.last_update_check = 0 if reset_last_update_check + + Gem.ui.stub :tty?, tty do + Gem.stub :rubygems_version, rubygems_version do + Gem.stub :latest_rubygems_version, latest_rubygems_version do + Gem::CIDetector.stub :ci?, ci do + yield + end + end + end + end + ensure + Gem.configuration[:prevent_update_suggestion] = original_config + ENV["RUBYGEMS_PREVENT_UPDATE_SUGGESTION"] = original_env + Gem.disable_system_update_message = original_disable + end + + def test_update_suggestion + Gem.stub :rubygems_version, Gem::Version.new("1.2.3") do + Gem.stub :latest_rubygems_version, Gem::Version.new("2.0.0") do + assert_equal @cmd.update_suggestion, <<~SUGGESTION + + A new release of RubyGems is available: 1.2.3 → 2.0.0! + Run `gem update --system 2.0.0` to update your installation. + + SUGGESTION + end + end + end + + def test_eligible_for_update + with_eligible_environment(cmd: @cmd) do + Time.stub :now, 123_456_789 do + assert_predicate @cmd, :eligible_for_update? + assert_equal 123_456_789, Gem.configuration.last_update_check + + # test last check is written to config file + assert_include File.read(Gem.configuration.state_file_name), "123456789" + end + end + end + + def test_eligible_for_update_is_not_annoying_when_new_version_is_released + current_version = Gem::Version.new("1.2.0") + latest_version = current_version + + # checking for first time, it is not eligible since new version + # is not released yet and stored + with_eligible_environment(cmd: @cmd, rubygems_version: current_version, latest_rubygems_version: latest_version) do + Time.stub :now, @start_time do + refute_predicate @cmd, :eligible_for_update? + assert_equal @start_time, Gem.configuration.last_update_check + end + end + + # checking next week, it is not eligible since new version + # is not released yet and timestamp is stored + with_eligible_environment( + cmd: @cmd, + rubygems_version: current_version, + latest_rubygems_version: latest_version, + reset_last_update_check: false + ) do + Time.stub :now, @start_time + @week do + refute_predicate @cmd, :eligible_for_update? + assert_equal @start_time + @week, Gem.configuration.last_update_check + end + end + + # pretend new version is released + latest_version = Gem::Version.new("1.3.0") + + # checking later same next week, it is not eligible even new version + # is released and timestamp is not stored + with_eligible_environment( + cmd: @cmd, + rubygems_version: current_version, + latest_rubygems_version: latest_version, + reset_last_update_check: false + ) do + Time.stub :now, @start_time + @week + @minute do + refute_predicate @cmd, :eligible_for_update? + assert_equal @start_time + @week, Gem.configuration.last_update_check + end + end + end + + def test_eligible_for_update_is_not_annoying_when_not_upgraded + with_eligible_environment(cmd: @cmd) do + # checking for first time, it is eligible and stored + Time.stub :now, @start_time do + assert_predicate @cmd, :eligible_for_update? + assert_equal @start_time, Gem.configuration.last_update_check + end + + # checking minute later is not eligible and not stored + Time.stub :now, @start_time + @minute do + refute_predicate @cmd, :eligible_for_update? + assert_equal @start_time, Gem.configuration.last_update_check + end + + # checking week later is eligible again and stored + Time.stub :now, @start_time + @week do + assert_predicate @cmd, :eligible_for_update? + assert_equal @start_time + @week, Gem.configuration.last_update_check + end + end + end + + def test_eligible_for_update_prevent_config + with_eligible_environment(cmd: @cmd) do + original_config = Gem.configuration[:prevent_update_suggestion] + Gem.configuration[:prevent_update_suggestion] = true + refute_predicate @cmd, :eligible_for_update? + ensure + Gem.configuration[:prevent_update_suggestion] = original_config + end + end + + def test_eligible_for_update_prevent_env + with_eligible_environment(cmd: @cmd) do + original_env = ENV["RUBYGEMS_PREVENT_UPDATE_SUGGESTION"] + ENV["RUBYGEMS_PREVENT_UPDATE_SUGGESTION"] = "yes" + refute_predicate @cmd, :eligible_for_update? + ensure + ENV["RUBYGEMS_PREVENT_UPDATE_SUGGESTION"] = original_env + end + end + + def test_eligible_for_update_non_tty + with_eligible_environment(tty: false, cmd: @cmd) do + refute_predicate @cmd, :eligible_for_update? + end + end + + def test_eligible_for_update_for_prerelease + with_eligible_environment(rubygems_version: Gem::Version.new("1.0.0-rc1"), cmd: @cmd) do + refute_predicate @cmd, :eligible_for_update? + end + end + + def test_eligible_for_update_disabled_update + with_eligible_environment(cmd: @cmd) do + original_disable = Gem.disable_system_update_message + Gem.disable_system_update_message = "disabled" + refute_predicate @cmd, :eligible_for_update? + ensure + Gem.disable_system_update_message = original_disable + end + end + + def test_eligible_for_update_on_ci + with_eligible_environment(ci: true, cmd: @cmd) do + refute_predicate @cmd, :eligible_for_update? + end + end + + def test_eligible_for_update_unwrittable_config + with_eligible_environment(cmd: @cmd) do + Gem.configuration.stub :state_file_writable?, false do + refute_predicate @cmd, :eligible_for_update? + end + end + end + + def test_eligible_for_update_notification_delay + with_eligible_environment(cmd: @cmd) do + Gem.configuration.last_update_check = Time.now.to_i + refute_predicate @cmd, :eligible_for_update? + end + end +end diff --git a/test/rubygems/test_gem_uri.rb b/test/rubygems/test_gem_uri.rb new file mode 100644 index 0000000000..1253ebc6de --- /dev/null +++ b/test/rubygems/test_gem_uri.rb @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +require_relative "helper" +require "rubygems/uri" + +class TestUri < Gem::TestCase + def test_to_s_not_string + assert_equal "not_a_uri", Gem::Uri.new(:not_a_uri).to_s + end + + def test_to_s_invalid_uri + assert_equal "https://www.example.com:80index", Gem::Uri.new("https://www.example.com:80index").to_s + end + + def test_redacted_with_user_pass + assert_equal "https://user:REDACTED@example.com", Gem::Uri.new("https://user:pass@example.com").redacted.to_s + end + + def test_redacted_with_token + assert_equal "https://REDACTED@example.com", Gem::Uri.new("https://token@example.com").redacted.to_s + end + + def test_redacted_with_user_x_oauth_basic + assert_equal "https://REDACTED:x-oauth-basic@example.com", Gem::Uri.new("https://token:x-oauth-basic@example.com").redacted.to_s + end + + def test_redacted_without_credential + assert_equal "https://www.example.com", Gem::Uri.new("https://www.example.com").redacted.to_s + end + + def test_redacted_with_invalid_uri + assert_equal "https://www.example.com:80index", Gem::Uri.new("https://www.example.com:80index").redacted.to_s + end + + def test_redacted_does_not_modify_uri + url = "https://user:password@example.com" + uri = Gem::Uri.new(url) + assert_equal "https://user:REDACTED@example.com", uri.redacted.to_s + assert_equal url, uri.to_s + end +end diff --git a/test/rubygems/test_gem_uri_formatter.rb b/test/rubygems/test_gem_uri_formatter.rb index debc7739cb..5ab4730d62 100644 --- a/test/rubygems/test_gem_uri_formatter.rb +++ b/test/rubygems/test_gem_uri_formatter.rb @@ -1,26 +1,27 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/uri_formatter' + +require_relative "helper" +require "rubygems/uri_formatter" class TestGemUriFormatter < Gem::TestCase def test_normalize_uri - assert_equal 'FILE://example/', - Gem::UriFormatter.new('FILE://example/').normalize - assert_equal 'FTP://example/', - Gem::UriFormatter.new('FTP://example/').normalize - assert_equal 'HTTP://example/', - Gem::UriFormatter.new('HTTP://example/').normalize - assert_equal 'HTTPS://example/', - Gem::UriFormatter.new('HTTPS://example/').normalize - assert_equal 'http://example/', - Gem::UriFormatter.new('example/').normalize + assert_equal "FILE://example/", + Gem::UriFormatter.new("FILE://example/").normalize + assert_equal "FTP://example/", + Gem::UriFormatter.new("FTP://example/").normalize + assert_equal "HTTP://example/", + Gem::UriFormatter.new("HTTP://example/").normalize + assert_equal "HTTPS://example/", + Gem::UriFormatter.new("HTTPS://example/").normalize + assert_equal "http://example/", + Gem::UriFormatter.new("example/").normalize end def test_escape - assert_equal 'a%40b%5Cc', Gem::UriFormatter.new('a@b\c').escape + assert_equal "a%40b%5Cc", Gem::UriFormatter.new('a@b\c').escape end def test_unescape - assert_equal 'a@b\c', Gem::UriFormatter.new('a%40b%5Cc').unescape + assert_equal 'a@b\c', Gem::UriFormatter.new("a%40b%5Cc").unescape end end diff --git a/test/rubygems/test_gem_util.rb b/test/rubygems/test_gem_util.rb index 222adcb06f..608210a903 100644 --- a/test/rubygems/test_gem_util.rb +++ b/test/rubygems/test_gem_util.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/util' + +require_relative "helper" +require "rubygems/util" class TestGemUtil < Gem::TestCase def test_class_popen - skip "popen with a block does not behave well on jruby" if Gem.java_platform? - assert_equal "0\n", Gem::Util.popen(*ruby_with_rubygems_in_load_path, '-e', 'p 0') + pend "popen with a block does not behave well on jruby" if Gem.java_platform? + assert_equal "0\n", Gem::Util.popen(*ruby_with_rubygems_in_load_path, "-e", "p 0") assert_raise Errno::ECHILD do Process.wait(-1) @@ -13,10 +14,10 @@ class TestGemUtil < Gem::TestCase end def test_silent_system - skip if Gem.java_platform? + pend if Gem.java_platform? Gem::Deprecate.skip_during do out, err = capture_output do - Gem::Util.silent_system(*ruby_with_rubygems_in_load_path, '-e', 'puts "hello"; warn "hello"') + Gem::Util.silent_system(*ruby_with_rubygems_in_load_path, "-e", 'puts "hello"; warn "hello"') end assert_empty out assert_empty err @@ -24,59 +25,51 @@ class TestGemUtil < Gem::TestCase end def test_traverse_parents - FileUtils.mkdir_p 'a/b/c' + FileUtils.mkdir_p "a/b/c" - enum = Gem::Util.traverse_parents 'a/b/c' + enum = Gem::Util.traverse_parents "a/b/c" - assert_equal File.join(@tempdir, 'a/b/c'), enum.next - assert_equal File.join(@tempdir, 'a/b'), enum.next - assert_equal File.join(@tempdir, 'a'), enum.next + assert_equal File.join(@tempdir, "a/b/c"), enum.next + assert_equal File.join(@tempdir, "a/b"), enum.next + assert_equal File.join(@tempdir, "a"), enum.next loop { break if enum.next.nil? } # exhaust the enumerator end def test_traverse_parents_does_not_crash_on_permissions_error - skip 'skipped on MS Windows (chmod has no effect)' if win_platform? || java_platform? + pend "skipped on MS Windows (chmod has no effect)" if Gem.win_platform? || Gem.java_platform? - FileUtils.mkdir_p 'd/e/f' + FileUtils.mkdir_p "d/e/f" # remove 'execute' permission from "e" directory and make it # impossible to cd into it and its children - FileUtils.chmod(0666, 'd/e') + FileUtils.chmod(0o666, "d/e") - skip 'skipped in root privilege' if Process.uid.zero? + pend "skipped in root privilege" if Process.uid.zero? - paths = Gem::Util.traverse_parents('d/e/f').to_a + paths = Gem::Util.traverse_parents("d/e/f").to_a - assert_equal File.join(@tempdir, 'd'), paths[0] + assert_equal File.join(@tempdir, "d"), paths[0] assert_equal @tempdir, paths[1] assert_equal File.realpath("..", @tempdir), paths[2] assert_equal File.realpath("../..", @tempdir), paths[3] ensure # restore default permissions, allow the directory to be removed - FileUtils.chmod(0775, 'd/e') unless win_platform? || java_platform? - end - - def test_linked_list_find - list = [1,2,3,4,5].inject(Gem::List.new(0)) do |m,o| - Gem::List.new o, m - end - assert_equal 5, list.find {|x| x == 5 } - assert_equal 4, list.find {|x| x == 4 } + FileUtils.chmod(0o775, "d/e") unless Gem.win_platform? || Gem.java_platform? end def test_glob_files_in_dir - FileUtils.mkdir_p 'g' - FileUtils.touch File.join('g', 'h.rb') - FileUtils.touch File.join('g', 'i.rb') + FileUtils.mkdir_p "g" + FileUtils.touch File.join("g", "h.rb") + FileUtils.touch File.join("g", "i.rb") expected_paths = [ - File.join(@tempdir, 'g/h.rb'), - File.join(@tempdir, 'g/i.rb'), + File.join(@tempdir, "g/h.rb"), + File.join(@tempdir, "g/i.rb"), ] - files_with_absolute_base = Gem::Util.glob_files_in_dir('*.rb', File.join(@tempdir, 'g')) + files_with_absolute_base = Gem::Util.glob_files_in_dir("*.rb", File.join(@tempdir, "g")) assert_equal expected_paths.sort, files_with_absolute_base.sort - files_with_relative_base = Gem::Util.glob_files_in_dir('*.rb', 'g') + files_with_relative_base = Gem::Util.glob_files_in_dir("*.rb", "g") assert_equal expected_paths.sort, files_with_relative_base.sort end diff --git a/test/rubygems/test_gem_validator.rb b/test/rubygems/test_gem_validator.rb index 5158543fa9..80109ab8ba 100644 --- a/test/rubygems/test_gem_validator.rb +++ b/test/rubygems/test_gem_validator.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require "rubygems/test_case" +require_relative "helper" require "rubygems/validator" class TestGemValidator < Gem::TestCase @@ -11,21 +11,21 @@ class TestGemValidator < Gem::TestCase end def test_alien - @spec = quick_gem 'a' do |s| + @spec = quick_gem "a" do |s| s.files = %w[lib/a.rb lib/b.rb] end util_build_gem @spec - FileUtils.rm File.join(@spec.gem_dir, 'lib/b.rb') - FileUtils.touch File.join(@spec.gem_dir, 'lib/c.rb') + FileUtils.rm File.join(@spec.gem_dir, "lib/b.rb") + FileUtils.touch File.join(@spec.gem_dir, "lib/c.rb") - alien = @validator.alien 'a' + alien = @validator.alien "a" expected = { @spec.file_name => [ - Gem::Validator::ErrorData.new('lib/b.rb', 'Missing file'), - Gem::Validator::ErrorData.new('lib/c.rb', 'Extra file'), + Gem::Validator::ErrorData.new("lib/b.rb", "Missing file"), + Gem::Validator::ErrorData.new("lib/c.rb", "Extra file"), ], } @@ -33,9 +33,9 @@ class TestGemValidator < Gem::TestCase end def test_alien_default - new_default_spec 'c', 1, nil, 'lib/c.rb' + new_default_spec "c", 1, nil, "lib/c.rb" - alien = @validator.alien 'c' + alien = @validator.alien "c" assert_empty alien end diff --git a/test/rubygems/test_gem_version.rb b/test/rubygems/test_gem_version.rb index 91325c2214..cf771bc5a1 100644 --- a/test/rubygems/test_gem_version.rb +++ b/test/rubygems/test_gem_version.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true -require 'rubygems/test_case' + +require_relative "helper" require "rubygems/version" class TestGemVersion < Gem::TestCase @@ -32,12 +33,19 @@ class TestGemVersion < Gem::TestCase def test_class_create real = Gem::Version.new(1.0) - assert_same real, Gem::Version.create(real) - assert_nil Gem::Version.create(nil) + assert_same real, Gem::Version.create(real) + + expected = "nil versions are discouraged and will be deprecated in Rubygems 4\n" + actual_stdout, actual_stderr = capture_output do + assert_nil Gem::Version.create(nil) + end + assert_empty actual_stdout + assert_equal(expected, actual_stderr) + assert_equal v("5.1"), Gem::Version.create("5.1") - ver = '1.1'.freeze - assert_equal v('1.1'), Gem::Version.create(ver) + ver = "1.1" + assert_equal v("1.1"), Gem::Version.create(ver) end def test_class_correct @@ -53,8 +61,8 @@ class TestGemVersion < Gem::TestCase end def test_class_new_subclass - v1 = Gem::Version.new '1' - v2 = V.new '1' + v1 = Gem::Version.new "1" + v2 = V.new "1" refute_same v1, v2 end @@ -81,7 +89,7 @@ class TestGemVersion < Gem::TestCase end def test_initialize - ["1.0", "1.0 ", " 1.0 ", "1.0\n", "\n1.0\n", "1.0".freeze].each do |good| + ["1.0", "1.0 ", " 1.0 ", "1.0\n", "\n1.0\n", "1.0"].each do |good| assert_version_equal "1.0", good end @@ -120,10 +128,10 @@ class TestGemVersion < Gem::TestCase assert_prerelease "22.1.50.0.d" assert_prerelease "1.2.d.42" - assert_prerelease '1.A' + assert_prerelease "1.A" - assert_prerelease '1-1' - assert_prerelease '1-a' + assert_prerelease "1-1" + assert_prerelease "1-a" refute_prerelease "1.2.0" refute_prerelease "2.9" @@ -154,6 +162,10 @@ class TestGemVersion < Gem::TestCase assert_equal(-1, v("5.a") <=> v("5.0.0.rc2")) assert_equal(1, v("5.x") <=> v("5.0.0.rc2")) + assert_equal(0, v("1.9.3") <=> "1.9.3") + assert_equal(1, v("1.9.3") <=> "1.9.2.99") + assert_equal(-1, v("1.9.3") <=> "1.9.3.1") + assert_nil v("1.0") <=> "whatever" end @@ -195,7 +207,7 @@ class TestGemVersion < Gem::TestCase # modifying the segments of a version should not affect the segments of the cached version object def test_segments - v('9.8.7').segments[2] += 1 + v("9.8.7").segments[2] += 1 refute_version_equal "9.8.8", "9.8.7" assert_equal [9,8,7], v("9.8.7").segments @@ -208,10 +220,10 @@ class TestGemVersion < Gem::TestCase end def test_frozen_version - v = v('1.freeze.test').freeze - assert_less_than v, v('1') - assert_version_equal v('1'), v.release - assert_version_equal v('2'), v.bump + v = v("1.freeze.test").freeze + assert_less_than v, v("1") + assert_version_equal v("1"), v.release + assert_version_equal v("2"), v.bump end # Asserts that +version+ is a prerelease. @@ -257,7 +269,8 @@ class TestGemVersion < Gem::TestCase # Assert that two versions are eql?. Checks both directions. def assert_version_eql(first, second) - first, second = v(first), v(second) + first = v(first) + second = v(second) assert first.eql?(second), "#{first} is eql? #{second}" assert second.eql?(first), "#{second} is eql? #{first}" end @@ -278,7 +291,8 @@ class TestGemVersion < Gem::TestCase # directions. def refute_version_eql(first, second) - first, second = v(first), v(second) + first = v(first) + second = v(second) refute first.eql?(second), "#{first} is NOT eql? #{second}" refute second.eql?(first), "#{second} is NOT eql? #{first}" end diff --git a/test/rubygems/test_gem_version_option.rb b/test/rubygems/test_gem_version_option.rb index 49a8513dbe..8b6e14fc42 100644 --- a/test/rubygems/test_gem_version_option.rb +++ b/test/rubygems/test_gem_version_option.rb @@ -1,13 +1,14 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems/command' -require 'rubygems/version_option' + +require_relative "helper" +require "rubygems/command" +require "rubygems/version_option" class TestGemVersionOption < Gem::TestCase def setup super - @cmd = Gem::Command.new 'dummy', 'dummy' + @cmd = Gem::Command.new "dummy", "dummy" @cmd.extend Gem::VersionOption end @@ -43,8 +44,8 @@ class TestGemVersionOption < Gem::TestCase expected = [ Gem::Platform::RUBY, - Gem::Platform.new('x86-freebsd6'), - Gem::Platform.new('x86-freebsd7'), + Gem::Platform.new("x86-freebsd6"), + Gem::Platform.new("x86-freebsd7"), ] assert_equal expected, Gem.platforms @@ -69,7 +70,7 @@ class TestGemVersionOption < Gem::TestCase expected = [ Gem::Platform::RUBY, - Gem::Platform.new('x86-freebsd6'), + Gem::Platform.new("x86-freebsd6"), ] assert_equal expected, Gem.platforms @@ -81,10 +82,10 @@ class TestGemVersionOption < Gem::TestCase @cmd.handle_options %w[--version >1] expected = { - :args => [], - :explicit_prerelease => false, - :prerelease => false, - :version => Gem::Requirement.new('> 1'), + args: [], + explicit_prerelease: false, + prerelease: false, + version: Gem::Requirement.new("> 1"), } assert_equal expected, @cmd.options @@ -93,13 +94,13 @@ class TestGemVersionOption < Gem::TestCase def test_version_option_compound @cmd.add_version_option - @cmd.handle_options ['--version', '< 1, > 0.9'] + @cmd.handle_options ["--version", "< 1, > 0.9"] expected = { - :args => [], - :explicit_prerelease => false, - :prerelease => false, - :version => Gem::Requirement.new('< 1', '> 0.9'), + args: [], + explicit_prerelease: false, + prerelease: false, + version: Gem::Requirement.new("< 1", "> 0.9"), } assert_equal expected, @cmd.options @@ -108,13 +109,13 @@ class TestGemVersionOption < Gem::TestCase def test_multiple_version_operator_option_compound @cmd.add_version_option - @cmd.handle_options ['--version', '< 1', '--version', '> 0.9'] + @cmd.handle_options ["--version", "< 1", "--version", "> 0.9"] expected = { - :args => [], - :explicit_prerelease => false, - :prerelease => false, - :version => Gem::Requirement.new('< 1', '> 0.9'), + args: [], + explicit_prerelease: false, + prerelease: false, + version: Gem::Requirement.new("< 1", "> 0.9"), } assert_equal expected, @cmd.options @@ -127,10 +128,10 @@ class TestGemVersionOption < Gem::TestCase @cmd.handle_options %w[--pre --version >1] expected = { - :args => [], - :explicit_prerelease => true, - :prerelease => true, - :version => Gem::Requirement.new('> 1'), + args: [], + explicit_prerelease: true, + prerelease: true, + version: Gem::Requirement.new("> 1"), } assert_equal expected, @cmd.options @@ -142,10 +143,10 @@ class TestGemVersionOption < Gem::TestCase @cmd.handle_options %w[--version >1.a] expected = { - :args => [], - :explicit_prerelease => false, - :prerelease => true, - :version => Gem::Requirement.new('> 1.a'), + args: [], + explicit_prerelease: false, + prerelease: true, + version: Gem::Requirement.new("> 1.a"), } assert_equal expected, @cmd.options @@ -153,10 +154,10 @@ class TestGemVersionOption < Gem::TestCase @cmd.handle_options %w[--version >1] expected = { - :args => [], - :explicit_prerelease => false, - :prerelease => false, - :version => Gem::Requirement.new('> 1'), + args: [], + explicit_prerelease: false, + prerelease: false, + version: Gem::Requirement.new("> 1"), } assert_equal expected, @cmd.options diff --git a/test/rubygems/test_kernel.rb b/test/rubygems/test_kernel.rb index c427203b35..d862b26fe9 100644 --- a/test/rubygems/test_kernel.rb +++ b/test/rubygems/test_kernel.rb @@ -1,93 +1,98 @@ # frozen_string_literal: true -require 'rubygems/test_case' -class TestKernel < Gem::TestCase +require_relative "helper" + +class TestGemKernel < Gem::TestCase def setup super - @old_path = $:.dup - util_make_gems - end - def teardown - super - - $:.replace @old_path + without_any_upwards_gemfiles end def test_gem - assert gem('a', '= 1'), "Should load" - assert $:.any? {|p| %r{a-1/lib} =~ p } + assert gem("a", "= 1"), "Should load" + assert $:.any? {|p| p.include?("a-1/lib") } end def test_gem_default - assert gem('a', '>= 0') + assert gem("a", ">= 0") - assert_equal @a2, Gem.loaded_specs['a'] + assert_equal @a2, Gem.loaded_specs["a"] end def test_gem_default_re_gem - assert gem('a', '=1') + assert gem("a", "=1") - refute gem('a', '>= 0') + refute gem("a", ">= 0") - assert_equal @a1, Gem.loaded_specs['a'] + assert_equal @a1, Gem.loaded_specs["a"] end def test_gem_re_gem_mismatch - assert gem('a', '=1') + assert gem("a", "=1") assert_raise Gem::LoadError do - gem('a', '= 2') + gem("a", "= 2") end - assert_equal @a1, Gem.loaded_specs['a'] + assert_equal @a1, Gem.loaded_specs["a"] end def test_gem_redundant - assert gem('a', '= 1'), "Should load" - refute gem('a', '= 1'), "Should not load" - assert_equal 1, $:.select {|p| %r{a-1/lib} =~ p }.size + assert gem("a", "= 1"), "Should load" + refute gem("a", "= 1"), "Should not load" + assert_equal 1, $:.count {|p| p.include?("a-1/lib") } end def test_gem_overlapping - assert gem('a', '= 1'), "Should load" - refute gem('a', '>= 1'), "Should not load" - assert_equal 1, $:.select {|p| %r{a-1/lib} =~ p }.size + assert gem("a", "= 1"), "Should load" + refute gem("a", ">= 1"), "Should not load" + assert_equal 1, $:.count {|p| p.include?("a-1/lib") } + end + + def test_gem_prerelease_is_the_only_available + quick_gem "d", "1.1.a" + + assert gem("d", ">= 1"), "release requirement may load prerelease when sole option" + assert $:.one? {|p| p.include?("/d-1.1.a/lib") } end - def test_gem_prerelease - quick_gem 'd', '1.1.a' - refute gem('d', '>= 1'), 'release requirement must not load prerelease' - assert gem('d', '>= 1.a'), 'prerelease requirement may load prerelease' + def test_release_favored_over_prerelease + quick_gem "d", "1.1.a" + quick_gem "d", "1.2" + gem("d", ">= 1") + + refute $:.any? {|p| p.include?("/d-1.1.a/lib") } + assert $:.one? {|p| p.include?("/d-1.2/lib") } end def test_gem_env_req - ENV["GEM_REQUIREMENT_A"] = '~> 2.0' - assert_raise(Gem::MissingSpecVersionError) { gem('a', '= 1') } - assert gem('a', '> 1') - assert_equal @a2, Gem.loaded_specs['a'] + ENV["GEM_REQUIREMENT_A"] = "~> 2.0" + assert_raise(Gem::MissingSpecVersionError) { gem("a", "= 1") } + assert gem("a", "> 1") + assert_equal @a2, Gem.loaded_specs["a"] end def test_gem_conflicting - assert gem('a', '= 1'), "Should load" + assert gem("a", "= 1"), "Should load" ex = assert_raise Gem::LoadError do - gem 'a', '= 2' + gem "a", "= 2" end assert_equal "can't activate a-2, already activated a-1", ex.message assert_match(/activated a-1/, ex.message) - assert_equal 'a', ex.name + assert_equal "a", ex.name - assert $:.any? {|p| %r{a-1/lib} =~ p } - refute $:.any? {|p| %r{a-2/lib} =~ p } + assert $:.any? {|p| p.include?("a-1/lib") } + refute $:.any? {|p| p.include?("a-2/lib") } end def test_gem_not_adding_bin - assert gem('a', '= 1'), "Should load" - refute $:.any? {|p| %r{a-1/bin} =~ p } + assert gem("a", "= 1"), "Should load" + refute $:.any? {|p| p.include?("a-1/bin") } end def test_gem_failing_inside_require_doesnt_cause_double_exceptions @@ -108,32 +113,22 @@ class TestKernel < Gem::TestCase end def test_gem_bundler - quick_gem 'bundler', '1' - quick_gem 'bundler', '2.a' + quick_gem "bundler", "1" + quick_gem "bundler", "2.a" - assert gem('bundler') - assert $:.any? {|p| %r{bundler-1/lib} =~ p } - end - - def test_gem_bundler_missing_bundler_version - Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["55", "reason"]) do - quick_gem 'bundler', '1' - quick_gem 'bundler', '2.a' - - e = assert_raise Gem::MissingSpecVersionError do - gem('bundler') - end - assert_match "Could not find 'bundler' (55) required by reason.", e.message - end + assert gem("bundler") + assert $:.any? {|p| p.include?("bundler-1/lib") } end def test_gem_bundler_inferred_bundler_version - Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["1", "reason"]) do - quick_gem 'bundler', '1' - quick_gem 'bundler', '2.a' + require "rubygems/bundler_version_finder" + + Gem::BundlerVersionFinder.stub(:bundler_version, Gem::Version.new("1")) do + quick_gem "bundler", "1" + quick_gem "bundler", "2.a" - assert gem('bundler', '>= 0.a') - assert $:.any? {|p| %r{bundler-1/lib} =~ p } + assert gem("bundler", ">= 0.a") + assert $:.any? {|p| p.include?("bundler-1/lib") } end end end diff --git a/test/rubygems/test_project_sanity.rb b/test/rubygems/test_project_sanity.rb index 831a2c00aa..7a7b779b08 100644 --- a/test/rubygems/test_project_sanity.rb +++ b/test/rubygems/test_project_sanity.rb @@ -1,20 +1,49 @@ # frozen_string_literal: true -require "rubygems/test_case" +require_relative "helper" require "open3" -class TestProjectSanity < Gem::TestCase +class TestGemProjectSanity < Gem::TestCase + def setup + end + + def teardown + end + def test_manifest_is_up_to_date - skip unless File.exist?(File.expand_path("../../../Rakefile", __FILE__)) + pend unless File.exist?("#{root}/Rakefile") _, status = Open3.capture2e("rake check_manifest") - assert status.success?, "Expected Manifest.txt to be up to date, but it's not. Run `rake update_manifest` to sync it." + unless status.success? + original_contents = File.read("#{root}/Manifest.txt") + + # Update the manifest to see if it fixes the problem + Open3.capture2e("rake update_manifest") + + out, status = Open3.capture2e("rake check_manifest") + + # If `rake update_manifest` fixed the problem, that was the original + # issue, otherwise it was an unknown error, so print the error output + if status.success? + File.write("#{root}/Manifest.txt", original_contents) + + raise "Expected Manifest.txt to be up to date, but it's not. Run `rake update_manifest` to sync it." + else + raise "There was an error running `rake check_manifest`: #{out}" + end + end end def test_require_rubygems_package - err, status = Open3.capture2e(*ruby_with_rubygems_in_load_path, "--disable-gems", "-e", "'require \"rubygems/package\"'") + err, status = Open3.capture2e(*ruby_with_rubygems_in_load_path, "--disable-gems", "-e", "require \"rubygems/package\"") assert status.success?, err end + + private + + def root + File.expand_path("../..", __dir__) + end end diff --git a/test/rubygems/test_remote_fetch_error.rb b/test/rubygems/test_remote_fetch_error.rb index a1c25bcdda..5d9028ede7 100644 --- a/test/rubygems/test_remote_fetch_error.rb +++ b/test/rubygems/test_remote_fetch_error.rb @@ -1,19 +1,20 @@ # frozen_string_literal: true -require 'rubygems/test_case' -class TestRemoteFetchError < Gem::TestCase +require_relative "helper" + +class TestGemRemoteFetchError < Gem::TestCase def test_password_redacted - error = Gem::RemoteFetcher::FetchError.new('There was an error fetching', 'https://user:secret@gemsource.org') - refute_match %r{secret}, error.to_s + error = Gem::RemoteFetcher::FetchError.new("There was an error fetching", "https://user:secret@gemsource.org") + refute_match(/secret/, error.to_s) end def test_invalid_url - error = Gem::RemoteFetcher::FetchError.new('There was an error fetching', 'https://::gemsource.org') - assert_equal error.to_s, 'There was an error fetching (https://::gemsource.org)' + error = Gem::RemoteFetcher::FetchError.new("There was an error fetching", "https://::gemsource.org") + assert_equal error.to_s, "There was an error fetching (https://::gemsource.org)" end def test_to_s - error = Gem::RemoteFetcher::FetchError.new('There was an error fetching', 'https://gemsource.org') - assert_equal error.to_s, 'There was an error fetching (https://gemsource.org)' + error = Gem::RemoteFetcher::FetchError.new("There was an error fetching", "https://gemsource.org") + assert_equal error.to_s, "There was an error fetching (https://gemsource.org)" end end diff --git a/test/rubygems/test_require.rb b/test/rubygems/test_require.rb index f04d5187df..30a4a477f9 100644 --- a/test/rubygems/test_require.rb +++ b/test/rubygems/test_require.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true -require 'rubygems/test_case' -require 'rubygems' + +require_relative "helper" +require "rubygems" class TestGemRequire < Gem::TestCase class Latch @@ -24,16 +25,6 @@ class TestGemRequire < Gem::TestCase end end - def setup - super - - @old_loaded_features = $LOADED_FEATURES.dup - assert_raise LoadError do - require 'test_gem_require_a' - end - $LOADED_FEATURES.replace @old_loaded_features - end - def assert_require(path) assert require(path), "'#{path}' was already required" end @@ -45,26 +36,26 @@ class TestGemRequire < Gem::TestCase def test_respect_loaded_features_caching_like_standard_require dir = Dir.mktmpdir("test_require", @tempdir) - lp1 = File.join dir, 'foo1' - foo1 = File.join lp1, 'foo.rb' + lp1 = File.join dir, "foo1" + foo1 = File.join lp1, "foo.rb" FileUtils.mkdir_p lp1 - File.open(foo1, 'w') {|f| f.write "class Object; HELLO = 'foo1' end" } + File.open(foo1, "w") {|f| f.write "class Object; HELLO = 'foo1' end" } lp = $LOAD_PATH.dup $LOAD_PATH.unshift lp1 - assert_require 'foo' + assert_require "foo" assert_equal "foo1", ::Object::HELLO - lp2 = File.join dir, 'foo2' - foo2 = File.join lp2, 'foo.rb' + lp2 = File.join dir, "foo2" + foo2 = File.join lp2, "foo.rb" FileUtils.mkdir_p lp2 - File.open(foo2, 'w') {|f| f.write "class Object; HELLO = 'foo2' end" } + File.open(foo2, "w") {|f| f.write "class Object; HELLO = 'foo2' end" } $LOAD_PATH.unshift lp2 - refute_require 'foo' + refute_require "foo" assert_equal "foo1", ::Object::HELLO ensure $LOAD_PATH.replace lp @@ -73,96 +64,82 @@ class TestGemRequire < Gem::TestCase # Providing -I on the commandline should always beat gems def test_dash_i_beats_gems - a1 = util_spec "a", "1", {"b" => "= 1"}, "lib/test_gem_require_a.rb" - b1 = util_spec "b", "1", {"c" => "> 0"}, "lib/b/c.rb" + a1 = util_spec "a", "1", { "b" => "= 1" }, "lib/test_gem_require_a.rb" + b1 = util_spec "b", "1", { "c" => "> 0" }, "lib/b/c.rb" c1 = util_spec "c", "1", nil, "lib/c/c.rb" c2 = util_spec "c", "2", nil, "lib/c/c.rb" install_specs c1, c2, b1, a1 dir = Dir.mktmpdir("test_require", @tempdir) - dash_i_arg = File.join dir, 'lib' + dash_i_arg = File.join dir, "lib" - c_rb = File.join dash_i_arg, 'b', 'c.rb' + c_rb = File.join dash_i_arg, "b", "c.rb" FileUtils.mkdir_p File.dirname c_rb - File.open(c_rb, 'w') {|f| f.write "class Object; HELLO = 'world' end" } - - lp = $LOAD_PATH.dup + File.open(c_rb, "w") {|f| f.write "class Object; HELLO = 'world' end" } # Pretend to provide a commandline argument that overrides a file in gem b $LOAD_PATH.unshift dash_i_arg - assert_require 'test_gem_require_a' - assert_require 'b/c' # this should be required from -I + assert_require "test_gem_require_a" + assert_require "b/c" # this should be required from -I assert_equal "world", ::Object::HELLO assert_equal %w[a-1 b-1], loaded_spec_names ensure - $LOAD_PATH.replace lp Object.send :remove_const, :HELLO if Object.const_defined? :HELLO end def create_sync_thread Thread.new do - begin - yield - ensure - FILE_ENTERED_LATCH.release - FILE_EXIT_LATCH.await - end + yield + ensure + FILE_ENTERED_LATCH.release + FILE_EXIT_LATCH.await end end # Providing -I on the commandline should always beat gems def test_dash_i_beats_default_gems - a1 = new_default_spec "a", "1", {"b" => "= 1"}, "test_gem_require_a.rb" - b1 = new_default_spec "b", "1", {"c" => "> 0"}, "b/c.rb" + a1 = new_default_spec "a", "1", { "b" => "= 1" }, "test_gem_require_a.rb" + b1 = new_default_spec "b", "1", { "c" => "> 0" }, "b/c.rb" c1 = new_default_spec "c", "1", nil, "c/c.rb" c2 = new_default_spec "c", "2", nil, "c/c.rb" install_default_gems c1, c2, b1, a1 dir = Dir.mktmpdir("test_require", @tempdir) - dash_i_arg = File.join dir, 'lib' + dash_i_arg = File.join dir, "lib" - c_rb = File.join dash_i_arg, 'c', 'c.rb' + c_rb = File.join dash_i_arg, "c", "c.rb" FileUtils.mkdir_p File.dirname c_rb - File.open(c_rb, 'w') {|f| f.write "class Object; HELLO = 'world' end" } - - assert_require 'test_gem_require_a' + File.open(c_rb, "w") {|f| f.write "class Object; HELLO = 'world' end" } - lp = $LOAD_PATH.dup + assert_require "test_gem_require_a" # Pretend to provide a commandline argument that overrides a file in gem b $LOAD_PATH.unshift dash_i_arg - assert_require 'b/c' - assert_require 'c/c' # this should be required from -I + assert_require "b/c" + assert_require "c/c" # this should be required from -I assert_equal "world", ::Object::HELLO assert_equal %w[a-1 b-1], loaded_spec_names ensure - $LOAD_PATH.replace lp Object.send :remove_const, :HELLO if Object.const_defined? :HELLO end def test_dash_i_respects_default_library_extension_priority - skip "extensions don't quite work on jruby" if Gem.java_platform? - skip "not installed yet" unless RbConfig::TOPDIR + pend "extensions don't quite work on jruby" if Gem.java_platform? + pend "not installed yet" unless RbConfig::TOPDIR - dash_i_ext_arg = util_install_extension_file('a') - dash_i_lib_arg = util_install_ruby_file('a') + dash_i_ext_arg = util_install_extension_file("a") + dash_i_lib_arg = util_install_ruby_file("a") - lp = $LOAD_PATH.dup - - begin - $LOAD_PATH.unshift dash_i_lib_arg - $LOAD_PATH.unshift dash_i_ext_arg - assert_require 'a' - assert_match(/a\.rb$/, $LOADED_FEATURES.last) - ensure - $LOAD_PATH.replace lp - end + $LOAD_PATH.unshift dash_i_lib_arg + $LOAD_PATH.unshift dash_i_ext_arg + assert_require "a" + assert_match(/a\.rb$/, $LOADED_FEATURES.last) end def test_concurrent_require @@ -174,8 +151,8 @@ class TestGemRequire < Gem::TestCase install_specs a1, b1 - t1 = create_sync_thread{ assert_require "a#{$$}" } - t2 = create_sync_thread{ assert_require "b#{$$}" } + t1 = create_sync_thread { assert_require "a#{$$}" } + t2 = create_sync_thread { assert_require "b#{$$}" } # wait until both files are waiting on the exit latch FILE_ENTERED_LATCH.await @@ -191,13 +168,13 @@ class TestGemRequire < Gem::TestCase end def test_require_is_not_lazy_with_exact_req - a1 = util_spec "a", "1", {"b" => "= 1"}, "lib/test_gem_require_a.rb" + a1 = util_spec "a", "1", { "b" => "= 1" }, "lib/test_gem_require_a.rb" b1 = util_spec "b", "1", nil, "lib/b/c.rb" b2 = util_spec "b", "2", nil, "lib/b/c.rb" install_specs b1, b2, a1 - assert_require 'test_gem_require_a' + assert_require "test_gem_require_a" assert_equal %w[a-1 b-1], loaded_spec_names assert_equal unresolved_names, [] @@ -206,13 +183,13 @@ class TestGemRequire < Gem::TestCase end def test_require_is_lazy_with_inexact_req - a1 = util_spec "a", "1", {"b" => ">= 1"}, "lib/test_gem_require_a.rb" + a1 = util_spec "a", "1", { "b" => ">= 1" }, "lib/test_gem_require_a.rb" b1 = util_spec "b", "1", nil, "lib/b/c.rb" b2 = util_spec "b", "2", nil, "lib/b/c.rb" install_specs b1, b2, a1 - assert_require 'test_gem_require_a' + assert_require "test_gem_require_a" assert_equal %w[a-1], loaded_spec_names assert_equal unresolved_names, ["b (>= 1)"] @@ -221,12 +198,12 @@ class TestGemRequire < Gem::TestCase end def test_require_is_not_lazy_with_one_possible - a1 = util_spec "a", "1", {"b" => ">= 1"}, "lib/test_gem_require_a.rb" + a1 = util_spec "a", "1", { "b" => ">= 1" }, "lib/test_gem_require_a.rb" b1 = util_spec "b", "1", nil, "lib/b/c.rb" install_specs b1, a1 - assert_require 'test_gem_require_a' + assert_require "test_gem_require_a" assert_equal %w[a-1 b-1], loaded_spec_names assert_equal unresolved_names, [] @@ -239,20 +216,20 @@ class TestGemRequire < Gem::TestCase install_specs a1 - assert_require Pathname.new 'test_gem_require_a' + assert_require Pathname.new "test_gem_require_a" assert_equal %w[a-1], loaded_spec_names assert_equal unresolved_names, [] end def test_activate_via_require_respects_loaded_files - skip "Not sure what's going on. If another spec creates a 'a' gem before + pend "Not sure what's going on. If another spec creates a 'a' gem before this test, somehow require will load the benchmark in b, and ignore that the stdlib one is already in $LOADED_FEATURES?. Reproducible by running the - spaceship_specific_file test before this one" if java_platform? + spaceship_specific_file test before this one" if Gem.java_platform? - skip "not installed yet" unless RbConfig::TOPDIR + pend "not installed yet" unless RbConfig::TOPDIR - lib_dir = File.expand_path("../../lib", File.dirname(__FILE__)) + lib_dir = File.expand_path("../lib", __dir__) rubylibdir = File.realdirpath(RbConfig::CONFIG["rubylibdir"]) if rubylibdir == lib_dir # testing in the ruby repository where RubyGems' lib/ == stdlib lib/ @@ -263,20 +240,20 @@ class TestGemRequire < Gem::TestCase load_path_changed = true end - require 'benchmark' # the stdlib + require "benchmark" # the stdlib - a1 = util_spec "a", "1", {"b" => ">= 1"}, "lib/test_gem_require_a.rb" + a1 = util_spec "a", "1", { "b" => ">= 1" }, "lib/test_gem_require_a.rb" b1 = util_spec "b", "1", nil, "lib/benchmark.rb" b2 = util_spec "b", "2", nil, "lib/benchmark.rb" install_specs b1, b2, a1 # Activates a-1, but not b-1 and b-2 - assert_require 'test_gem_require_a' + assert_require "test_gem_require_a" assert_equal %w[a-1], loaded_spec_names - assert $LOAD_PATH.include? a1.load_paths[0] - refute $LOAD_PATH.include? b1.load_paths[0] - refute $LOAD_PATH.include? b2.load_paths[0] + assert $LOAD_PATH.include? a1.full_require_paths[0] + refute $LOAD_PATH.include? b1.full_require_paths[0] + refute $LOAD_PATH.include? b2.full_require_paths[0] assert_equal unresolved_names, ["b (>= 1)"] @@ -285,15 +262,15 @@ class TestGemRequire < Gem::TestCase # though b-2 is earlier in $LOAD_PATH it already loaded a benchmark.rb file # and that still exists in $LOAD_PATH (further down), # and as a result #gem_original_require returns false. - refute require('benchmark'), "the benchmark stdlib should be recognized as already loaded" + refute require("benchmark"), "the benchmark stdlib should be recognized as already loaded" - assert_includes $LOAD_PATH, b2.load_paths[0] + assert_includes $LOAD_PATH, b2.full_require_paths[0] assert_includes $LOAD_PATH, rubylibdir message = proc { "this test relies on the b-2 gem lib/ to be before stdlib to make sense\n" + - $LOAD_PATH.pretty_inspect + $LOAD_PATH.pretty_inspect } - assert_operator $LOAD_PATH.index(b2.load_paths[0]), :<, $LOAD_PATH.index(rubylibdir), message + assert_operator $LOAD_PATH.index(b2.full_require_paths[0]), :<, $LOAD_PATH.index(rubylibdir), message # We detected that we should activate b-2, so we did so, but # then #gem_original_require decided "I've already got some benchmark.rb" loaded. @@ -318,7 +295,7 @@ class TestGemRequire < Gem::TestCase install_specs a2 - refute_require 'a' + refute_require "a" assert_equal %w[a-1], loaded_spec_names end @@ -400,18 +377,18 @@ class TestGemRequire < Gem::TestCase # Load default ruby gems fresh as if we've just started a ruby script. Gem::Specification.reset - require 'rubygems' + require "rubygems" Gem::Specification.stubs # Remove an old default gem version directly from disk as if someone ran # gem cleanup. - FileUtils.rm_rf(File.join @gemhome, "#{b1.full_name}") - FileUtils.rm_rf(File.join @gemhome, "specifications", "default", "#{b1.full_name}.gemspec") + FileUtils.rm_rf(File.join(@gemhome, b1.full_name.to_s)) + FileUtils.rm_rf(File.join(@gemhome, "specifications", "default", "#{b1.full_name}.gemspec")) # Require gems that have not been removed. - assert_require 'a/b' + assert_require "a/b" assert_equal %w[a-1.0], loaded_spec_names - assert_require 'b/d' + assert_require "b/d" assert_equal %w[a-1.0 b-2.0], loaded_spec_names end @@ -447,7 +424,7 @@ class TestGemRequire < Gem::TestCase times_called = 0 - Kernel.stub(:gem, ->(name, requirement) { times_called += 1 }) do + Kernel.stub(:gem, ->(_name, _requirement) { times_called += 1 }) do refute_require "default/gem" end @@ -466,8 +443,7 @@ class TestGemRequire < Gem::TestCase end def test_realworld_default_gem - testing_ruby_repo = !ENV["GEM_COMMAND"].nil? - skip "this test can't work under ruby-core setup" if testing_ruby_repo || java_platform? + omit "this test can't work under ruby-core setup" if ruby_repo? cmd = <<-RUBY $stderr = $stdout @@ -480,8 +456,7 @@ class TestGemRequire < Gem::TestCase end def test_realworld_upgraded_default_gem - testing_ruby_repo = !ENV["GEM_COMMAND"].nil? - skip "this test can't work under ruby-core setup" if testing_ruby_repo + omit "this test can't work under ruby-core setup" if ruby_repo? newer_json = util_spec("json", "999.99.9", nil, ["lib/json.rb"]) install_gem newer_json @@ -495,12 +470,12 @@ class TestGemRequire < Gem::TestCase RUBY File.write(path, code) - output = Gem::Util.popen({ 'GEM_HOME' => @gemhome }, *ruby_with_rubygems_in_load_path, path).strip - assert $?.success? + output = Gem::Util.popen({ "GEM_HOME" => @gemhome }, *ruby_with_rubygems_in_load_path, path).strip refute_empty output assert_equal "999.99.9", output.lines[0].chomp # Make sure only files from the newer json gem are loaded, and no files from the default json gem assert_equal ["#{@gemhome}/gems/json-999.99.9/lib/json.rb"], output.lines.grep(%r{/gems/json-}).map(&:chomp) + assert $?.success? end def test_default_gem_and_normal_gem @@ -514,6 +489,17 @@ class TestGemRequire < Gem::TestCase assert_equal %w[default-3.0], loaded_spec_names end + def test_normal_gem_does_not_shadow_default_gem + default_gem_spec = new_default_spec("foo", "2.0", nil, "foo.rb") + install_default_gems(default_gem_spec) + + normal_gem_spec = util_spec("fake-foo", "3.0", nil, "lib/foo.rb") + install_specs(normal_gem_spec) + + assert_require "foo" + assert_equal %w[foo-2.0], loaded_spec_names + end + def test_normal_gems_with_overridden_load_error_message normal_gem_spec = util_spec("normal", "3.0", nil, "lib/normal/gem.rb") @@ -554,6 +540,65 @@ class TestGemRequire < Gem::TestCase assert_equal %w[default-3.0.0.rc2], loaded_spec_names end + def test_default_gem_with_unresolved_gems_depending_on_it + my_http_old = util_spec "my-http", "0.1.1", nil, "lib/my/http.rb" + install_gem my_http_old + + my_http_default = new_default_spec "my-http", "0.3.0", nil, "my/http.rb" + install_default_gems my_http_default + + faraday_1 = util_spec "faraday", "1", { "my-http" => ">= 0" } + install_gem faraday_1 + + faraday_2 = util_spec "faraday", "2", { "my-http" => ">= 0" } + install_gem faraday_2 + + chef = util_spec "chef", "1", { "faraday" => [">= 1", "< 3"] }, "lib/chef.rb" + install_gem chef + + assert_require "chef" + assert_require "my/http" + end + + def test_default_gem_required_circulary_with_unresolved_gems_depending_on_it + my_http_old = util_spec "my-http", "0.1.1", nil, "lib/my/http.rb" + install_gem my_http_old + + my_http_default = new_default_spec "my-http", "0.3.0", nil, "my/http.rb" + my_http_default_path = File.join(@tempdir, "default_gems", "lib", "my/http.rb") + install_default_gems my_http_default + File.write(my_http_default_path, 'require "my/http"') + + faraday_1 = util_spec "faraday", "1", { "my-http" => ">= 0" } + install_gem faraday_1 + + faraday_2 = util_spec "faraday", "2", { "my-http" => ">= 0" } + install_gem faraday_2 + + chef = util_spec "chef", "1", { "faraday" => [">= 1", "< 3"] }, "lib/chef.rb" + install_gem chef + + assert_require "chef" + + out, err = capture_output do + assert_require "my/http" + end + + assert_empty out + + circular_require_warning = false + + err_lines = err.split("\n").reject do |line| + if line.include?("circular require") + circular_require_warning = true + elsif circular_require_warning # ignore backtrace lines for circular require warning + circular_require_warning = line.start_with?(/[\s]/) + end + end + + assert_empty err_lines + end + def loaded_spec_names Gem.loaded_specs.values.map(&:full_name).sort end @@ -565,19 +610,21 @@ class TestGemRequire < Gem::TestCase def test_try_activate_error_unlocks_require_monitor silence_warnings do class << ::Gem - alias old_try_activate try_activate - def try_activate(*); raise 'raised from try_activate'; end + alias_method :old_try_activate, :try_activate + def try_activate(*) + raise "raised from try_activate" + end end end - require 'does_not_exist_for_try_activate_test' + require "does_not_exist_for_try_activate_test" rescue RuntimeError => e assert_match(/raised from try_activate/, e.message) assert Kernel::RUBYGEMS_ACTIVATION_MONITOR.try_enter, "require monitor was not unlocked when try_activate raised" ensure silence_warnings do class << ::Gem - alias try_activate old_try_activate + alias_method :try_activate, :old_try_activate end end Kernel::RUBYGEMS_ACTIVATION_MONITOR.exit @@ -609,126 +656,106 @@ class TestGemRequire < Gem::TestCase end def test_require_bundler - b1 = util_spec('bundler', '1', nil, "lib/bundler/setup.rb") - b2a = util_spec('bundler', '2.a', nil, "lib/bundler/setup.rb") + b1 = util_spec("bundler", "1", nil, "lib/bundler/setup.rb") + b2a = util_spec("bundler", "2.a", nil, "lib/bundler/setup.rb") install_specs b1, b2a require "rubygems/bundler_version_finder" $:.clear - assert_require 'bundler/setup' + assert_require "bundler/setup" assert_equal %w[bundler-2.a], loaded_spec_names assert_empty unresolved_names end - def test_require_bundler_missing_bundler_version - Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["55", "reason"]) do - b1 = util_spec('bundler', '1.999999999', nil, "lib/bundler/setup.rb") - b2a = util_spec('bundler', '2.a', nil, "lib/bundler/setup.rb") - install_specs b1, b2a - - e = assert_raise Gem::MissingSpecVersionError do - gem('bundler') - end - assert_match "Could not find 'bundler' (55) required by reason.", e.message - end - end - - def test_require_bundler_with_bundler_version - Gem::BundlerVersionFinder.stub(:bundler_version_with_reason, ["1", "reason"]) do - b1 = util_spec('bundler', '1.999999999', nil, "lib/bundler/setup.rb") - b2 = util_spec('bundler', '2', nil, "lib/bundler/setup.rb") - install_specs b1, b2 - - $:.clear - assert_require 'bundler/setup' - assert_equal %w[bundler-1.999999999], loaded_spec_names - end - end - - # uplevel is 2.5+ only - if RUBY_VERSION >= "2.5" - ["", "Kernel."].each do |prefix| - define_method "test_no_kernel_require_in_#{prefix.tr(".", "_")}warn_with_uplevel" do - Dir.mktmpdir("warn_test") do |dir| - File.write(dir + "/sub.rb", "#{prefix}warn 'uplevel', 'test', uplevel: 1\n") - File.write(dir + "/main.rb", "require 'sub'\n") - _, err = capture_subprocess_io do - system(*ruby_with_rubygems_in_load_path, "-w", "--disable=gems", "-C", dir, "-I", dir, "main.rb") - end - assert_match(/main\.rb:1: warning: uplevel\ntest\n$/, err) - _, err = capture_subprocess_io do - system(*ruby_with_rubygems_in_load_path, "-w", "--enable=gems", "-C", dir, "-I", dir, "main.rb") - end - assert_match(/main\.rb:1: warning: uplevel\ntest\n$/, err) + ["", "Kernel."].each do |prefix| + define_method "test_no_kernel_require_in_#{prefix.tr(".", "_")}warn_with_uplevel" do + Dir.mktmpdir("warn_test") do |dir| + File.write(dir + "/sub.rb", "#{prefix}warn 'uplevel', 'test', uplevel: 1\n") + File.write(dir + "/main.rb", "require 'sub'\n") + _, err = capture_subprocess_io do + system(*ruby_with_rubygems_in_load_path, "-w", "--disable=gems", "-C", dir, "-I", dir, "main.rb") end - end - - define_method "test_no_other_behavioral_changes_with_#{prefix.tr(".", "_")}warn" do - Dir.mktmpdir("warn_test") do |dir| - File.write(dir + "/main.rb", "#{prefix}warn({x:1}, {y:2}, [])\n") - _, err = capture_subprocess_io do - system(*ruby_with_rubygems_in_load_path, "-w", "--disable=gems", "-C", dir, "main.rb") - end - assert_match(/{:x=>1}\n{:y=>2}\n$/, err) - _, err = capture_subprocess_io do - system(*ruby_with_rubygems_in_load_path, "-w", "--enable=gems", "-C", dir, "main.rb") - end - assert_match(/{:x=>1}\n{:y=>2}\n$/, err) + assert_match(/main\.rb:1: warning: uplevel\ntest\n$/, err) + _, err = capture_subprocess_io do + system(*ruby_with_rubygems_in_load_path, "-w", "--enable=gems", "-C", dir, "-I", dir, "main.rb") end + assert_match(/main\.rb:1: warning: uplevel\ntest\n$/, err) end end - def test_no_crash_when_overriding_warn_with_warning_module - skip "https://github.com/oracle/truffleruby/issues/2109" if RUBY_ENGINE == "truffleruby" - + define_method "test_no_other_behavioral_changes_with_#{prefix.tr(".", "_")}warn" do Dir.mktmpdir("warn_test") do |dir| - File.write(dir + "/main.rb", "module Warning; def warn(str); super; end; end; warn 'Foo Bar'") + File.write(dir + "/main.rb", "#{prefix}warn({x:1}, {y:2}, [])\n") _, err = capture_subprocess_io do system(*ruby_with_rubygems_in_load_path, "-w", "--disable=gems", "-C", dir, "main.rb") end - assert_match(/Foo Bar\n$/, err) + assert_match(/{:x=>1}\n{:y=>2}\n$/, err) _, err = capture_subprocess_io do system(*ruby_with_rubygems_in_load_path, "-w", "--enable=gems", "-C", dir, "main.rb") end - assert_match(/Foo Bar\n$/, err) + assert_match(/{:x=>1}\n{:y=>2}\n$/, err) end end + end - def test_expected_backtrace_location_when_inheriting_from_basic_object_and_including_kernel - Dir.mktmpdir("warn_test") do |dir| - File.write(dir + "/main.rb", "\nrequire 'sub'\n") - File.write(dir + "/sub.rb", <<-'RUBY') - require 'rubygems' - class C < BasicObject - include ::Kernel - def deprecated - warn "This is a deprecated method", uplevel: 2 - end - end - C.new.deprecated - RUBY + def test_no_crash_when_overriding_warn_with_warning_module + Dir.mktmpdir("warn_test") do |dir| + File.write(dir + "/main.rb", "module Warning; def warn(str); super; end; end; warn 'Foo Bar'") + _, err = capture_subprocess_io do + system(*ruby_with_rubygems_in_load_path, "-w", "--disable=gems", "-C", dir, "main.rb") + end + assert_match(/Foo Bar\n$/, err) + _, err = capture_subprocess_io do + system(*ruby_with_rubygems_in_load_path, "-w", "--enable=gems", "-C", dir, "main.rb") + end + assert_match(/Foo Bar\n$/, err) + end + end - _, err = capture_subprocess_io do - system(*ruby_with_rubygems_in_load_path, "-w", "--disable=gems", "-C", dir, "-I", dir, "main.rb") - end - assert_match(/main\.rb:2: warning: This is a deprecated method$/, err) - _, err = capture_subprocess_io do - system(*ruby_with_rubygems_in_load_path, "-w", "--enable=gems", "-C", dir, "-I", dir, "main.rb") + def test_expected_backtrace_location_when_inheriting_from_basic_object_and_including_kernel + Dir.mktmpdir("warn_test") do |dir| + File.write(dir + "/main.rb", "\nrequire 'sub'\n") + File.write(dir + "/sub.rb", <<-'RUBY') + require 'rubygems' + class C < BasicObject + include ::Kernel + def deprecated + warn "This is a deprecated method", uplevel: 2 + end end - assert_match(/main\.rb:2: warning: This is a deprecated method$/, err) + C.new.deprecated + RUBY + + _, err = capture_subprocess_io do + system(*ruby_with_rubygems_in_load_path, "-w", "--disable=gems", "-C", dir, "-I", dir, "main.rb") end + assert_match(/main\.rb:2: warning: This is a deprecated method$/, err) + _, err = capture_subprocess_io do + system(*ruby_with_rubygems_in_load_path, "-w", "--enable=gems", "-C", dir, "-I", dir, "main.rb") + end + assert_match(/main\.rb:2: warning: This is a deprecated method$/, err) end end - private + def test_require_does_not_crash_when_utilizing_bundler_version_finder + a1 = util_spec "a", "1.1", { "bundler" => ">= 0" } + a2 = util_spec "a", "1.2", { "bundler" => ">= 0" } + b1 = util_spec "bundler", "2.3.7" + b2 = util_spec "bundler", "2.3.24" + c = util_spec "c", "1", { "a" => [">= 1.1", "< 99.0"] }, "lib/test_gem_require_c.rb" - def silence_warnings - old_verbose, $VERBOSE = $VERBOSE, false - yield - ensure - $VERBOSE = old_verbose + install_specs a1, a2, b1, b2, c + + cmd = <<-RUBY + require "test_gem_require_c" + require "json" + RUBY + out = Gem::Util.popen({ "GEM_HOME" => @gemhome }, *ruby_with_rubygems_in_load_path, "-e", cmd) + assert_predicate $?, :success?, "Require failed due to #{out}" end + private + def util_install_extension_file(name) spec = quick_gem name util_build_gem spec @@ -752,13 +779,13 @@ class TestGemRequire < Gem::TestCase spec.files += ["extconf.rb", "depend", "#{name}.c"] - so = File.join(spec.gem_dir, "#{name}.#{RbConfig::CONFIG["DLEXT"]}") - assert_path_not_exist so + extension_file = File.join(spec.extension_dir, "#{name}.#{RbConfig::CONFIG["DLEXT"]}") + assert_path_not_exist extension_file path = Gem::Package.build spec installer = Gem::Installer.at path installer.install - assert_path_exist so + assert_path_exist extension_file spec.gem_dir end @@ -770,7 +797,7 @@ class TestGemRequire < Gem::TestCase a_rb = File.join dash_i_lib_arg, "#{name}.rb" FileUtils.mkdir_p File.dirname a_rb - File.open(a_rb, 'w') {|f| f.write "# #{name}.rb" } + File.open(a_rb, "w") {|f| f.write "# #{name}.rb" } dash_i_lib_arg end diff --git a/test/rubygems/test_rubygems.rb b/test/rubygems/test_rubygems.rb new file mode 100644 index 0000000000..ec195b65cd --- /dev/null +++ b/test/rubygems/test_rubygems.rb @@ -0,0 +1,76 @@ +# frozen_string_literal: true + +require_relative "helper" + +class GemTest < Gem::TestCase + def test_rubygems_normal_behaviour + _ = Gem::Util.popen(*ruby_with_rubygems_in_load_path, "-e", "'require \"rubygems\"'", { err: [:child, :out] }).strip + assert $?.success? + end + + def test_operating_system_other_exceptions + pend "does not apply to truffleruby" if RUBY_ENGINE == "truffleruby" + + path = util_install_operating_system_rb <<-RUBY + intentionally_not_implemented_method + RUBY + + output = Gem::Util.popen(*ruby_with_rubygems_and_fake_operating_system_in_load_path(path), "-e", "'require \"rubygems\"'", { err: [:child, :out] }).strip + assert !$?.success? + assert_match(/undefined local variable or method [`']intentionally_not_implemented_method'/, output) + assert_includes output, "Loading the #{operating_system_rb_at(path)} file caused an error. " \ + "This file is owned by your OS, not by rubygems upstream. " \ + "Please find out which OS package this file belongs to and follow the guidelines from your OS to report " \ + "the problem and ask for help." + end + + def test_operating_system_customizing_default_dir + pend "does not apply to truffleruby" if RUBY_ENGINE == "truffleruby" + pend "loads a custom defaults/jruby file that gets in the middle" if RUBY_ENGINE == "jruby" + + # On a non existing default dir, there should be no gems + + path = util_install_operating_system_rb <<-RUBY + module Gem + def self.default_dir + File.expand_path("foo") + end + end + RUBY + + output = Gem::Util.popen( + *ruby_with_rubygems_and_fake_operating_system_in_load_path(path), + "-e", + "require \"rubygems\"; puts Gem::Specification.stubs.map(&:full_name)", + { err: [:child, :out] } + ).strip + begin + assert_empty output + rescue Test::Unit::AssertionFailedError + pend "Temporary pending custom default_dir test" + end + end + + private + + def util_install_operating_system_rb(content) + dir_lib = Dir.mktmpdir("test_operating_system_lib", @tempdir) + dir_lib_arg = File.join dir_lib, "lib" + + operating_system_rb = operating_system_rb_at(dir_lib_arg) + + FileUtils.mkdir_p File.dirname(operating_system_rb) + + File.open(operating_system_rb, "w") {|f| f.write content } + + dir_lib_arg + end + + def operating_system_rb_at(dir) + File.join dir, "rubygems", "defaults", "operating_system.rb" + end + + def ruby_with_rubygems_and_fake_operating_system_in_load_path(operating_system_path) + [Gem.ruby, "-I", operating_system_path, "-I", $LOAD_PATH.find {|p| p == File.dirname($LOADED_FEATURES.find {|f| f.end_with?("/rubygems.rb") }) }] + end +end diff --git a/test/rubygems/test_webauthn_listener.rb b/test/rubygems/test_webauthn_listener.rb new file mode 100644 index 0000000000..08edabceb2 --- /dev/null +++ b/test/rubygems/test_webauthn_listener.rb @@ -0,0 +1,143 @@ +# frozen_string_literal: true + +require_relative "helper" +require "rubygems/gemcutter_utilities/webauthn_listener" +require "rubygems/gemcutter_utilities" + +class WebauthnListenerTest < Gem::TestCase + def setup + super + @server = TCPServer.new 0 + @port = @server.addr[1].to_s + end + + def teardown + @thread.kill.join if @thread + @server&.close + super + end + + def test_listener_thread_retreives_otp_code + thread = Gem::GemcutterUtilities::WebauthnListener.listener_thread(Gem.host, @server) + Gem::MockBrowser.get Gem::URI("http://localhost:#{@port}?code=xyz") + + thread.join + assert_equal "xyz", thread[:otp] + end + + def test_listener_thread_sets_error + thread = Gem::GemcutterUtilities::WebauthnListener.listener_thread(Gem.host, @server) + Gem::MockBrowser.post Gem::URI("http://localhost:#{@port}?code=xyz") + + thread.join + assert_equal "Security device verification failed: Invalid HTTP method POST received.", thread[:error].message + end + + def test_wait_for_otp_code_get_follows_options + wait_for_otp_code + assert Gem::MockBrowser.options(Gem::URI("http://localhost:#{@port}?code=xyz")).is_a? Gem::Net::HTTPNoContent + assert Gem::MockBrowser.get(Gem::URI("http://localhost:#{@port}?code=xyz")).is_a? Gem::Net::HTTPOK + end + + def test_wait_for_otp_code_options_request + wait_for_otp_code + response = Gem::MockBrowser.options Gem::URI("http://localhost:#{@port}?code=xyz") + + assert response.is_a? Gem::Net::HTTPNoContent + assert_equal Gem.host, response["access-control-allow-origin"] + assert_equal "POST", response["access-control-allow-methods"] + assert_equal "Content-Type, Authorization, x-csrf-token", response["access-control-allow-headers"] + assert_equal "close", response["Connection"] + end + + def test_wait_for_otp_code_get_request + wait_for_otp_code + response = Gem::MockBrowser.get Gem::URI("http://localhost:#{@port}?code=xyz") + + assert response.is_a? Gem::Net::HTTPOK + assert_equal "text/plain; charset=utf-8", response["Content-Type"] + assert_equal "7", response["Content-Length"] + assert_equal Gem.host, response["access-control-allow-origin"] + assert_equal "POST", response["access-control-allow-methods"] + assert_equal "Content-Type, Authorization, x-csrf-token", response["access-control-allow-headers"] + assert_equal "close", response["Connection"] + assert_equal "success", response.body + + @thread.join + assert_equal "xyz", @thread[:otp] + end + + def test_wait_for_otp_code_invalid_post_req_method + wait_for_otp_code_expect_error_with_message("Security device verification failed: Invalid HTTP method POST received.") + response = Gem::MockBrowser.post Gem::URI("http://localhost:#{@port}?code=xyz") + + assert response + assert response.is_a? Gem::Net::HTTPMethodNotAllowed + assert_equal "GET, OPTIONS", response["allow"] + assert_equal "close", response["Connection"] + + @thread.join + assert_nil @thread[:otp] + end + + def test_wait_for_otp_code_incorrect_path + wait_for_otp_code_expect_error_with_message("Security device verification failed: Page at /path not found.") + response = Gem::MockBrowser.post Gem::URI("http://localhost:#{@port}/path?code=xyz") + + assert response.is_a? Gem::Net::HTTPNotFound + assert_equal "close", response["Connection"] + + @thread.join + assert_nil @thread[:otp] + end + + def test_wait_for_otp_code_no_params_response + wait_for_otp_code_expect_error_with_message("Security device verification failed: Did not receive OTP from https://rubygems.org.") + response = Gem::MockBrowser.get Gem::URI("http://localhost:#{@port}") + + assert response.is_a? Gem::Net::HTTPBadRequest + assert_equal "text/plain; charset=utf-8", response["Content-Type"] + assert_equal "22", response["Content-Length"] + assert_equal "close", response["Connection"] + assert_equal "missing code parameter", response.body + + @thread.join + assert_nil @thread[:otp] + end + + def test_wait_for_otp_code_incorrect_params + wait_for_otp_code_expect_error_with_message("Security device verification failed: Did not receive OTP from https://rubygems.org.") + response = Gem::MockBrowser.get Gem::URI("http://localhost:#{@port}?param=xyz") + + assert response.is_a? Gem::Net::HTTPBadRequest + assert_equal "text/plain; charset=utf-8", response["Content-Type"] + assert_equal "22", response["Content-Length"] + assert_equal "close", response["Connection"] + assert_equal "missing code parameter", response.body + + @thread.join + assert_nil @thread[:otp] + end + + private + + def wait_for_otp_code + @thread = Thread.new do + Thread.current[:otp] = Gem::GemcutterUtilities::WebauthnListener.new(Gem.host).wait_for_otp_code(@server) + end + @thread.abort_on_exception = true + @thread.report_on_exception = false + end + + def wait_for_otp_code_expect_error_with_message(message) + @thread = Thread.new do + error = assert_raise Gem::WebauthnVerificationError do + Thread.current[:otp] = Gem::GemcutterUtilities::WebauthnListener.new(Gem.host).wait_for_otp_code(@server) + end + + assert_equal message, error.message + end + @thread.abort_on_exception = true + @thread.report_on_exception = false + end +end diff --git a/test/rubygems/test_webauthn_listener_response.rb b/test/rubygems/test_webauthn_listener_response.rb new file mode 100644 index 0000000000..377e5bfe5a --- /dev/null +++ b/test/rubygems/test_webauthn_listener_response.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true + +require_relative "helper" +require "rubygems/gemcutter_utilities/webauthn_listener/response" + +class WebauthnListenerResponseTest < Gem::TestCase + def setup + super + @host = "rubygems.example" + end + + def test_ok_response_to_s + to_s = Gem::GemcutterUtilities::WebauthnListener::OkResponse.new(@host).to_s + + expected_to_s = <<~RESPONSE + HTTP/1.1 200 OK\r + connection: close\r + access-control-allow-origin: rubygems.example\r + access-control-allow-methods: POST\r + access-control-allow-headers: Content-Type, Authorization, x-csrf-token\r + content-type: text/plain; charset=utf-8\r + content-length: 7\r + \r + success + RESPONSE + + assert_equal expected_to_s, to_s + end + + def test_no_to_s_response_to_s + to_s = Gem::GemcutterUtilities::WebauthnListener::NoContentResponse.new(@host).to_s + + expected_to_s = <<~RESPONSE + HTTP/1.1 204 No Content\r + connection: close\r + access-control-allow-origin: rubygems.example\r + access-control-allow-methods: POST\r + access-control-allow-headers: Content-Type, Authorization, x-csrf-token\r + \r + RESPONSE + + assert_equal expected_to_s, to_s + end + + def test_method_not_allowed_response_to_s + to_s = Gem::GemcutterUtilities::WebauthnListener::MethodNotAllowedResponse.new(@host).to_s + + expected_to_s = <<~RESPONSE + HTTP/1.1 405 Method Not Allowed\r + connection: close\r + access-control-allow-origin: rubygems.example\r + access-control-allow-methods: POST\r + access-control-allow-headers: Content-Type, Authorization, x-csrf-token\r + allow: GET, OPTIONS\r + \r + RESPONSE + + assert_equal expected_to_s, to_s + end + + def test_method_not_found_response_to_s + to_s = Gem::GemcutterUtilities::WebauthnListener::NotFoundResponse.new(@host).to_s + + expected_to_s = <<~RESPONSE + HTTP/1.1 404 Not Found\r + connection: close\r + access-control-allow-origin: rubygems.example\r + access-control-allow-methods: POST\r + access-control-allow-headers: Content-Type, Authorization, x-csrf-token\r + \r + RESPONSE + + assert_equal expected_to_s, to_s + end + + def test_bad_request_response_to_s + to_s = Gem::GemcutterUtilities::WebauthnListener::BadRequestResponse.new(@host).to_s + + expected_to_s = <<~RESPONSE + HTTP/1.1 400 Bad Request\r + connection: close\r + access-control-allow-origin: rubygems.example\r + access-control-allow-methods: POST\r + access-control-allow-headers: Content-Type, Authorization, x-csrf-token\r + content-type: text/plain; charset=utf-8\r + content-length: 22\r + \r + missing code parameter + RESPONSE + + assert_equal expected_to_s, to_s + end +end diff --git a/test/rubygems/test_webauthn_poller.rb b/test/rubygems/test_webauthn_poller.rb new file mode 100644 index 0000000000..23290d8ea1 --- /dev/null +++ b/test/rubygems/test_webauthn_poller.rb @@ -0,0 +1,124 @@ +# frozen_string_literal: true + +require_relative "helper" +require "rubygems/gemcutter_utilities/webauthn_poller" +require "rubygems/gemcutter_utilities" + +class WebauthnPollerTest < Gem::TestCase + def setup + super + + @host = Gem.host + @webauthn_url = "#{@host}/api/v1/webauthn_verification/odow34b93t6aPCdY" + @fetcher = Gem::FakeFetcher.new + Gem::RemoteFetcher.fetcher = @fetcher + @credentials = { + email: "email@example.com", + password: "password", + } + end + + def test_poll_thread_success + @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create( + body: "{\"status\":\"success\",\"code\":\"Uvh6T57tkWuUnWYo\"}", + code: 200, + msg: "OK" + ) + + thread = Gem::GemcutterUtilities::WebauthnPoller.poll_thread({}, @host, @webauthn_url, @credentials) + thread.join + + assert_equal thread[:otp], "Uvh6T57tkWuUnWYo" + end + + def test_poll_thread_webauthn_verification_error + @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create( + body: "HTTP Basic: Access denied.", + code: 401, + msg: "Unauthorized" + ) + + thread = Gem::GemcutterUtilities::WebauthnPoller.poll_thread({}, @host, @webauthn_url, @credentials) + thread.join + + assert_equal thread[:error].message, "Security device verification failed: Unauthorized" + end + + def test_poll_thread_timeout_error + raise_error = ->(*_args) { raise Gem::Timeout::Error, "execution expired" } + Gem::Timeout.stub(:timeout, raise_error) do + thread = Gem::GemcutterUtilities::WebauthnPoller.poll_thread({}, @host, @webauthn_url, @credentials) + thread.join + assert_equal thread[:error].message, "execution expired" + end + end + + def test_poll_for_otp_success + @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create( + body: "{\"status\":\"success\",\"code\":\"Uvh6T57tkWuUnWYo\"}", + code: 200, + msg: "OK" + ) + + otp = Gem::GemcutterUtilities::WebauthnPoller.new({}, @host).poll_for_otp(@webauthn_url, @credentials) + + assert_equal otp, "Uvh6T57tkWuUnWYo" + end + + def test_poll_for_otp_pending_sleeps + @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create( + body: "{\"status\":\"pending\",\"message\":\"Security device authentication is still pending.\"}", + code: 200, + msg: "OK" + ) + + assert_raise Gem::Timeout::Error do + Gem::Timeout.timeout(0.1) do + Gem::GemcutterUtilities::WebauthnPoller.new({}, @host).poll_for_otp(@webauthn_url, @credentials) + end + end + end + + def test_poll_for_otp_not_http_success + @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create( + body: "HTTP Basic: Access denied.", + code: 401, + msg: "Unauthorized" + ) + + error = assert_raise Gem::WebauthnVerificationError do + Gem::GemcutterUtilities::WebauthnPoller.new({}, @host).poll_for_otp(@webauthn_url, @credentials) + end + + assert_equal error.message, "Security device verification failed: Unauthorized" + end + + def test_poll_for_otp_invalid_format + @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create( + body: "{}", + code: 200, + msg: "OK" + ) + + error = assert_raise Gem::WebauthnVerificationError do + Gem::GemcutterUtilities::WebauthnPoller.new({}, @host).poll_for_otp(@webauthn_url, @credentials) + end + + assert_equal error.message, "Security device verification failed: Invalid response from server" + end + + def test_poll_for_otp_invalid_status + @fetcher.data["#{@webauthn_url}/status.json"] = Gem::HTTPResponseFactory.create( + body: "{\"status\":\"expired\",\"message\":\"The token in the link you used has either expired or been used already.\"}", + code: 200, + msg: "OK" + ) + + error = assert_raise Gem::WebauthnVerificationError do + Gem::GemcutterUtilities::WebauthnPoller.new({}, @host).poll_for_otp(@webauthn_url, @credentials) + end + + assert_equal error.message, + "Security device verification failed: The token in the link you used has either expired or been used already." + end +end diff --git a/test/rubygems/utilities.rb b/test/rubygems/utilities.rb new file mode 100644 index 0000000000..357379f88d --- /dev/null +++ b/test/rubygems/utilities.rb @@ -0,0 +1,436 @@ +# frozen_string_literal: true + +require "tempfile" +require "rubygems" +require "rubygems/remote_fetcher" + +## +# A fake Gem::RemoteFetcher for use in tests or to avoid real live HTTP +# requests when testing code that uses RubyGems. +# +# Example: +# +# @fetcher = Gem::FakeFetcher.new +# @fetcher.data['http://gems.example.com/yaml'] = source_index.to_yaml +# Gem::RemoteFetcher.fetcher = @fetcher +# +# use nested array if multiple response is needed +# +# @fetcher.data['http://gems.example.com/sequence'] = [['Success', 200, 'OK'], ['Failed', 401, 'Unauthorized']] +# +# @fetcher.fetch_path('http://gems.example.com/sequence') # => ['Success', 200, 'OK'] +# @fetcher.fetch_path('http://gems.example.com/sequence') # => ['Failed', 401, 'Unauthorized'] +# +# # invoke RubyGems code +# +# paths = @fetcher.paths +# assert_equal 'http://gems.example.com/yaml', paths.shift +# assert paths.empty?, paths.join(', ') +# +# See RubyGems' tests for more examples of FakeFetcher. + +class Gem::FakeFetcher + attr_reader :data + attr_reader :last_request + attr_accessor :paths + + def initialize + @data = {} + @paths = [] + end + + def find_data(path) + return Gem.read_binary path.path if Gem::URI === path && path.scheme == "file" + + if Gem::URI === path && "Gem::URI::#{path.scheme.upcase}" != path.class.name + raise ArgumentError, + "mismatch for scheme #{path.scheme} and class #{path.class}" + end + + path = path.to_s + @paths << path + raise ArgumentError, "need full Gem::URI" unless path.start_with?("https://", "http://") + + unless @data.key? path + raise Gem::RemoteFetcher::FetchError.new("no data for #{path}", path) + end + + if @data[path].is_a?(Array) + @data[path].shift + else + @data[path] + end + end + + def create_response(uri) + data = find_data(uri) + response = data.respond_to?(:call) ? data.call : data + raise TypeError, "#{response.class} is not a type of Gem::Net::HTTPResponse" unless response.is_a?(Gem::Net::HTTPResponse) + + response + end + + def fetch_path(path, mtime = nil, head = false) + data = find_data(path) + + if data.respond_to?(:call) + data.call + else + if path.to_s.end_with?(".gz") && !data.nil? && !data.empty? + data = Gem::Util.gunzip data + end + data + end + end + + def cache_update_path(uri, path = nil, update = true) + if data = fetch_path(uri) + File.open(path, "wb") {|io| io.write data } if path && update + data + else + Gem.read_binary(path) if path + end + end + + # Thanks, FakeWeb! + def open_uri_or_path(path) + find_data(path) + + create_response(uri) + end + + def request(uri, request_class, last_modified = nil) + @last_request = request_class.new uri.request_uri + yield @last_request if block_given? + + create_response(uri) + end + + def pretty_print(q) # :nodoc: + q.group 2, "[FakeFetcher", "]" do + q.breakable + q.text "URIs:" + + q.breakable + q.pp @data.keys + end + end + + def fetch_size(path) + path = path.to_s + @paths << path + + raise ArgumentError, "need full URI" unless %r{^http://}.match?(path) + + unless @data.key? path + raise Gem::RemoteFetcher::FetchError.new("no data for #{path}", path) + end + + data = @data[path] + + data.respond_to?(:call) ? data.call : data.length + end + + def download(spec, source_uri, install_dir = Gem.dir) + name = File.basename spec.cache_file + path = if Dir.pwd == install_dir # see fetch_command + install_dir + else + File.join install_dir, "cache" + end + + path = File.join path, name + + if /^http/.match?(source_uri) + File.open(path, "wb") do |f| + f.write fetch_path(File.join(source_uri, "gems", name)) + end + else + FileUtils.cp source_uri, path + end + + path + end + + def download_to_cache(dependency) + found, _ = Gem::SpecFetcher.fetcher.spec_for_dependency dependency + + return if found.empty? + + spec, source = found.first + + download spec, source.uri.to_s + end +end + +## +# The HTTPResponseFactory allows easy creation of Gem::Net::HTTPResponse instances in RubyGems tests: +# +# Example: +# +# Gem::HTTPResponseFactory.create( +# body: "", +# code: 301, +# msg: "Moved Permanently", +# headers: { "location" => "http://example.com" } +# ) +# + +class Gem::HTTPResponseFactory + def self.create(body:, code:, msg:, headers: {}) + response = Gem::Net::HTTPResponse.send(:response_class, code.to_s).new("1.0", code.to_s, msg) + response.instance_variable_set(:@body, body) + response.instance_variable_set(:@read, true) + headers.each {|name, value| response[name] = value } + + response + end +end + +## +# A Gem::MockBrowser is used in tests to mock a browser in that it can +# send HTTP requests to the defined URI. +# +# Example: +# +# # Sends a get request to http://localhost:5678 +# Gem::MockBrowser.get Gem::URI("http://localhost:5678") +# +# See RubyGems' tests for more examples of MockBrowser. +# + +class Gem::MockBrowser + def self.options(uri) + options = Gem::Net::HTTP::Options.new(uri) + Gem::Net::HTTP.start(uri.hostname, uri.port) do |http| + http.request(options) + end + end + + def self.get(uri) + get = Gem::Net::HTTP::Get.new(uri) + Gem::Net::HTTP.start(uri.hostname, uri.port) do |http| + http.request(get) + end + end + + def self.post(uri, content_type: "application/x-www-form-urlencoded") + headers = { "content-type" => content_type } if content_type + post = Gem::Net::HTTP::Post.new(uri, headers) + Gem::Net::HTTP.start(uri.hostname, uri.port) do |http| + http.request(post) + end + end +end + +# :stopdoc: +class Gem::RemoteFetcher + def self.fetcher=(fetcher) + @fetcher = fetcher + end +end +# :startdoc: + +## +# The SpecFetcherSetup allows easy setup of a remote source in RubyGems tests: +# +# spec_fetcher do |f| +# f.gem 'a', 1 +# f.spec 'a', 2 +# f.gem 'b', 1' 'a' => '~> 1.0' +# end +# +# The above declaration creates two gems, a-1 and b-1, with a dependency from +# b to a. The declaration creates an additional spec a-2, but no gem for it +# (so it cannot be installed). +# +# After the gems are created they are removed from Gem.dir. + +class Gem::TestCase::SpecFetcherSetup + ## + # Executes a SpecFetcher setup block. Yields an instance then creates the + # gems and specifications defined in the instance. + + def self.declare(test, repository) + setup = new test, repository + + yield setup + + setup.execute + end + + def initialize(test, repository) # :nodoc: + @test = test + @repository = repository + + @gems = {} + @downloaded = [] + @installed = [] + @operations = [] + end + + ## + # Returns a Hash of created Specification full names and the corresponding + # Specification. + + def created_specs + created = {} + + @gems.keys.each do |spec| + created[spec.full_name] = spec + end + + created + end + + ## + # Creates any defined gems or specifications + + def execute # :nodoc: + execute_operations + + setup_fetcher + + created_specs + end + + def execute_operations # :nodoc: + @operations.each do |operation, *arguments| + block = arguments.pop + case operation + when :gem then + spec, gem = @test.util_gem(*arguments, &block) + + write_spec spec + + @gems[spec] = gem + @installed << spec + when :download then + spec, gem = @test.util_gem(*arguments, &block) + + @gems[spec] = gem + @downloaded << spec + when :spec then + spec = @test.util_spec(*arguments, &block) + + write_spec spec + + @gems[spec] = nil + @installed << spec + end + end + end + + ## + # Creates a gem with +name+, +version+ and +deps+. The created gem can be + # downloaded and installed. + # + # The specification will be yielded before gem creation for customization, + # but only the block or the dependencies may be set, not both. + + def gem(name, version, dependencies = nil, &block) + @operations << [:gem, name, version, dependencies, block] + end + + ## + # Creates a gem with +name+, +version+ and +deps+. The created gem is + # downloaded in to the cache directory but is not installed + # + # The specification will be yielded before gem creation for customization, + # but only the block or the dependencies may be set, not both. + + def download(name, version, dependencies = nil, &block) + @operations << [:download, name, version, dependencies, block] + end + + ## + # Creates a legacy platform spec with the name 'pl' and version 1 + + def legacy_platform + spec "pl", 1 do |s| + s.platform = Gem::Platform.new "i386-linux" + s.instance_variable_set :@original_platform, "i386-linux" + end + end + + def setup_fetcher # :nodoc: + require "zlib" + require "socket" + require "rubygems/remote_fetcher" + + unless @test.fetcher + @test.fetcher = Gem::FakeFetcher.new + Gem::RemoteFetcher.fetcher = @test.fetcher + end + + Gem::Specification.reset + + begin + gem_repo = @test.gem_repo + @test.gem_repo = @repository + @test.uri = Gem::URI @repository + + @test.util_setup_spec_fetcher(*@downloaded) + ensure + @test.gem_repo = gem_repo + @test.uri = Gem::URI gem_repo + end + + @gems.each do |spec, gem| + next unless gem + + @test.fetcher.data["#{@repository}gems/#{spec.file_name}"] = + Gem.read_binary(gem) + + FileUtils.cp gem, spec.cache_file + end + end + + ## + # Creates a spec with +name+, +version+ and +deps+. The created gem can be + # downloaded and installed. + # + # The specification will be yielded before creation for customization, + # but only the block or the dependencies may be set, not both. + + def spec(name, version, dependencies = nil, &block) + @operations << [:spec, name, version, dependencies, block] + end + + def write_spec(spec) # :nodoc: + File.open spec.spec_file, "w" do |io| + io.write spec.to_ruby_for_cache + end + end +end + +## +# A StringIO duck-typed class that uses Tempfile instead of String as the +# backing store. +# +# This class was added to flush out problems in Rubinius' IO implementation. + +class Gem::TempIO < Tempfile + ## + # Creates a new TempIO that will be initialized to contain +string+. + + def initialize(string = "") + super "TempIO" + binmode + write string + rewind + end + + ## + # The content of the TempIO as a String. + + def string + flush + Gem.read_binary path + end +end + +class Gem::TestCase + TempIO = Gem::TempIO + HTTPResponseFactory = Gem::HTTPResponseFactory +end diff --git a/test/rubygems/wrong_key_cert.pem b/test/rubygems/wrong_key_cert.pem index 23396d7c81..2f2cffbc61 100644 --- a/test/rubygems/wrong_key_cert.pem +++ b/test/rubygems/wrong_key_cert.pem @@ -1,19 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDDTCCAfWgAwIBAgIBEjANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv +MIIDDTCCAfWgAwIBAgIBEjANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMCAXDTEyMDEwMTAwMDAwMFoYDzk5 OTkxMjMxMjM1OTU5WjAqMQ8wDQYDVQQDDAZub2JvZHkxFzAVBgoJkiaJk/IsZAEZ -FgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvZQipBa1 -xH3M9OonkrUYhGZeX9UHAcJhe6jJbUr/uHXkh1Tu2ERWNnblm85upqBfjyZEnKer -7uBcwwkkvmisVgC8uBECymsBxuEIw0rfiKYEnLu0B6SiWFYz3dYPS92bBK7Vks2/ -kNyXUmLLGoZ3id2K0eK5C/AJ0j+p84OqPnVhylsjrZmXfIZrh7lkHhgCIrzPefjE -3pOloi/tz6fh2ktb0FYKQMfweT3Ba2TMeflG13PEOW80AD5w0THxDutGG0zPNCDy -DEoT7UU1a3B3RMHYuUxEk1GUEYWq9L6a6SMpZISWTSpCp0Ww1QB55PONiCCn+o6v -cIy46jI71dATAQIDAQABozwwOjAZBgNVHREEEjAQgQ5ub2JvZHlAZXhhbXBsZTAd -BgNVHQ4EFgQUyvn/FwcZnA7AkzPjmoooB4/tKgcwDQYJKoZIhvcNAQEFBQADggEB -ABswixv3veo8S0Omyhbch3t19xAd/I4ZAx/lq6a/Ubl+X33hRbZQ7ulXja6Y5ZCs -iIkezGcpc182e7hZdHuEGGnJ1fJwxz3rbFWvs+MrtRSaCC73HbbxF1x0mQY6Kc7W -PahB2v+Dx5n3dIN6ah5p+STUHmzhKGr3bsQswtSHrFn74wt6mBu/hyCz+t6UaQ7b -rpRpzDFO1q3tZB8MeIHg57Lk2bu0LtfaHdkGDghNa3t7oZfV5A6pruiTy/EdQvFL -ZJpvDgHCyUsDmukMMjz6U4ts+nx7kZ9JoIH9K2lMJo3SGw4iZ8rB+HTfsbUdRfBj -UlyNcLqCW+FPlUHgHgNugFA= +FgdleGFtcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApebGm7NO +nx+DtWG1xQsJBfTfwNlZvfzY61nlZccrhU6vx0AnYNiDZAG3J/gFQmYZ9gJ98rzE +wfLMCGq9R/TZM+lAEaLhzYZCu3X4QdhKxr1xZ/SFC+1f8KVuH4tLXORW30DwayPh +NxnrOvup4pWLiYuXUSZpV9CGMvPSUCW2odhMkBMKqaTTPjxoXJIcgacyprkNgIq4 +8cSvqWG/e/HrMRtkqvFbD5ta00uO1mlpajYYw1RRftEwktFo8vQgDBo9NT/EqoE7 +2tffaDnLq6rQrVtw4Kr9fy775DjNAWXyiCBjnJgOQSXCGPsM/AEdFrh/LKQQv2M/ +M7WNevnEUgsEIwIDAQABozwwOjAZBgNVHREEEjAQgQ5ub2JvZHlAZXhhbXBsZTAd +BgNVHQ4EFgQUYPwS8g98+4Tq/8gcEK1iilkGXH4wDQYJKoZIhvcNAQELBQADggEB +AJacpAT2GQQn5Rmb/LYaPhguWFHEdjHBO6rU0p7tE8QJW5pwMgim0mFtQlbuXE2L +mbHrYCyRgVyaPV9gNiFg1sLzQMmmG4Afg1N4cpdg8zLZFZho+eyYGRkH+EtrAN0Q +l8l603zovMXj8q8Q1eeurxkDHA6mDgwwMGiBQgAiPixQVOjvL+5M5PkwNw/kVzjA +0EXumGQkeZ1jUAkVjp7uWbyoVatamUcpYvo51NQQQeuqwzdo2oDYLa27axWxaqj2 +m4TKsz2WnnrSnrpq3NnflXfWcOrnXI3odNlhQoPmtZQVt6P8pNbGrx4XD/WTGkGw +i/6jlkwwjK7A7dSepfnTI4Y= -----END CERTIFICATE----- diff --git a/test/rubygems/wrong_key_cert_32.pem b/test/rubygems/wrong_key_cert_32.pem index 7a3bb9f714..aca829ab44 100644 --- a/test/rubygems/wrong_key_cert_32.pem +++ b/test/rubygems/wrong_key_cert_32.pem @@ -1,19 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDCzCCAfOgAwIBAgIBEzANBgkqhkiG9w0BAQUFADAqMQ8wDQYDVQQDDAZub2Jv +MIIDCzCCAfOgAwIBAgIBEzANBgkqhkiG9w0BAQsFADAqMQ8wDQYDVQQDDAZub2Jv ZHkxFzAVBgoJkiaJk/IsZAEZFgdleGFtcGxlMB4XDTEyMDEwMTAwMDAwMFoXDTM4 MDExOTAzMTQwN1owKjEPMA0GA1UEAwwGbm9ib2R5MRcwFQYKCZImiZPyLGQBGRYH -ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL2UIqQWtcR9 -zPTqJ5K1GIRmXl/VBwHCYXuoyW1K/7h15IdU7thEVjZ25ZvObqagX48mRJynq+7g -XMMJJL5orFYAvLgRAsprAcbhCMNK34imBJy7tAekolhWM93WD0vdmwSu1ZLNv5Dc -l1JiyxqGd4nditHiuQvwCdI/qfODqj51YcpbI62Zl3yGa4e5ZB4YAiK8z3n4xN6T -paIv7c+n4dpLW9BWCkDH8Hk9wWtkzHn5RtdzxDlvNAA+cNEx8Q7rRhtMzzQg8gxK -E+1FNWtwd0TB2LlMRJNRlBGFqvS+mukjKWSElk0qQqdFsNUAeeTzjYggp/qOr3CM -uOoyO9XQEwECAwEAAaM8MDowGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwHQYD -VR0OBBYEFMr5/xcHGZwOwJMz45qKKAeP7SoHMA0GCSqGSIb3DQEBBQUAA4IBAQCU -VkESWkNeiJ1L3MfkMl2ybP2QPWP5nlhz+NOqwOCJSmEXF86Dq2XTY/GgSu1iPp4s -pPm1RSpnjujtiV7gjCziNif/XqAxeSjU2deApvq4mknyk958N0IS8c86dUXms1DQ -Rncmb3pxxvzP1d6Is35Uwoc5KqheJWR3aDwE8ejaFfO8pq/ncUDB25bc7OyslHMJ -7Ah+2YlFjvHYuPvN8bP44UMYyAPZCCJnjIPn7m7giyQiIo6SA9aiLQ8F7+NN3SU4 -7I9ED0F7RTDxNYISr1sLZ7aNtnXkTAnZclwKohuGfZD3OGAOshLZZXIB2pIRr/Kj -6zxTef39tli6orheYQXp +ZXhhbXBsZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKXmxpuzTp8f +g7VhtcULCQX038DZWb382OtZ5WXHK4VOr8dAJ2DYg2QBtyf4BUJmGfYCffK8xMHy +zAhqvUf02TPpQBGi4c2GQrt1+EHYSsa9cWf0hQvtX/Clbh+LS1zkVt9A8Gsj4TcZ +6zr7qeKVi4mLl1EmaVfQhjLz0lAltqHYTJATCqmk0z48aFySHIGnMqa5DYCKuPHE +r6lhv3vx6zEbZKrxWw+bWtNLjtZpaWo2GMNUUX7RMJLRaPL0IAwaPTU/xKqBO9rX +32g5y6uq0K1bcOCq/X8u++Q4zQFl8oggY5yYDkElwhj7DPwBHRa4fyykEL9jPzO1 +jXr5xFILBCMCAwEAAaM8MDowGQYDVR0RBBIwEIEObm9ib2R5QGV4YW1wbGUwHQYD +VR0OBBYEFGD8EvIPfPuE6v/IHBCtYopZBlx+MA0GCSqGSIb3DQEBCwUAA4IBAQBE +lq/rPaPT+5uui42u4BTFayrQU9EFik9xPG6WJw+IJ/5CprECj6h90FC+GaMNeu2Z +R0l+iEfgx4xBM4DERiRVLZIlHbZzuPp0YRYH9gyJot/+0piaAcnUEvjz2Z8axoFq +lE3/q4s6Yw8xdqwxvc5kiwymv2nEm4+v5w6Pb3K/fP/QQLvDUBWrBUMHPgdYXYk2 +zvc58BBwgGDSpFRO0tw+lnqMTM1y+fbpfuvP9TY1m4y13nuw/g7KxVxYolAWVQs3 +TptnJqqzEwdFa2S9BidUIlDRRY8cuhY6R3DM6THNLjR3c1oyf04nhT3sd/ilAJdD +YjnEtcLlkjxZyLLoWjn2 -----END CERTIFICATE----- |