summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/bundler/bundler/compact_index_client/parser_spec.rb221
-rw-r--r--spec/bundler/bundler/compact_index_client/updater_spec.rb18
-rw-r--r--spec/bundler/bundler/fetcher/compact_index_spec.rb6
-rw-r--r--spec/bundler/bundler/source/git/git_proxy_spec.rb14
-rw-r--r--spec/bundler/commands/cache_spec.rb60
-rw-r--r--spec/bundler/commands/exec_spec.rb4
-rw-r--r--spec/bundler/commands/install_spec.rb52
-rw-r--r--spec/bundler/commands/lock_spec.rb128
-rw-r--r--spec/bundler/commands/newgem_spec.rb131
-rw-r--r--spec/bundler/commands/post_bundle_message_spec.rb2
-rw-r--r--spec/bundler/commands/update_spec.rb46
-rw-r--r--spec/bundler/install/gemfile/git_spec.rb2
-rw-r--r--spec/bundler/install/gemfile/sources_spec.rb4
-rw-r--r--spec/bundler/install/gemfile/specific_platform_spec.rb6
-rw-r--r--spec/bundler/install/gems/flex_spec.rb2
-rw-r--r--spec/bundler/install/gems/resolving_spec.rb4
-rw-r--r--spec/bundler/install/yanked_spec.rb6
-rw-r--r--spec/bundler/other/major_deprecation_spec.rb7
-rw-r--r--spec/bundler/runtime/require_spec.rb24
-rw-r--r--spec/bundler/runtime/setup_spec.rb12
-rw-r--r--spec/bundler/support/builders.rb1
-rw-r--r--spec/bundler/support/helpers.rb16
-rw-r--r--spec/prism.mspec26
-rw-r--r--spec/ruby/core/binding/dup_spec.rb17
-rw-r--r--spec/ruby/core/binding/irb_spec.rb2
-rw-r--r--spec/ruby/core/enumerator/next_values_spec.rb8
-rw-r--r--spec/ruby/core/enumerator/peek_values_spec.rb8
-rw-r--r--spec/ruby/core/io/pread_spec.rb9
-rw-r--r--spec/ruby/core/io/read_spec.rb15
-rw-r--r--spec/ruby/core/io/readpartial_spec.rb3
-rw-r--r--spec/ruby/core/io/sysread_spec.rb9
-rw-r--r--spec/ruby/core/module/include_spec.rb28
-rw-r--r--spec/ruby/core/module/prepend_spec.rb48
-rw-r--r--spec/ruby/core/string/index_spec.rb11
-rw-r--r--spec/ruby/core/warning/element_reference_spec.rb4
-rw-r--r--spec/ruby/core/warning/performance_warning_spec.rb28
-rw-r--r--spec/ruby/language/break_spec.rb19
-rw-r--r--spec/ruby/language/case_spec.rb39
-rw-r--r--spec/ruby/language/execution_spec.rb4
-rw-r--r--spec/ruby/language/hash_spec.rb32
-rw-r--r--spec/ruby/language/keyword_arguments_spec.rb28
-rw-r--r--spec/ruby/language/regexp/back-references_spec.rb9
-rw-r--r--spec/ruby/language/retry_spec.rb5
-rw-r--r--spec/ruby/language/yield_spec.rb12
-rw-r--r--spec/ruby/library/date/time/to_date_spec.rb (renamed from spec/ruby/library/time/to_date_spec.rb)2
-rw-r--r--spec/ruby/library/datetime/time/to_datetime_spec.rb (renamed from spec/ruby/library/time/to_datetime_spec.rb)2
-rw-r--r--spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb16
-rw-r--r--spec/ruby/library/socket/basicsocket/recv_spec.rb22
-rw-r--r--spec/ruby/library/socket/socket/recvfrom_nonblock_spec.rb21
-rw-r--r--spec/ruby/library/socket/udpsocket/recvfrom_nonblock_spec.rb9
-rw-r--r--spec/ruby/library/socket/unixsocket/recvfrom_spec.rb23
-rw-r--r--spec/ruby/library/stringio/shared/read.rb20
-rw-r--r--spec/ruby/optional/capi/class_spec.rb12
-rw-r--r--spec/ruby/optional/capi/ext/class_spec.c5
-rw-r--r--spec/ruby/optional/capi/ext/gc_spec.c10
-rw-r--r--spec/ruby/optional/capi/ext/io_spec.c8
-rw-r--r--spec/ruby/optional/capi/ext/object_spec.c16
-rw-r--r--spec/ruby/optional/capi/gc_spec.rb4
-rw-r--r--spec/ruby/shared/kernel/at_exit.rb6
59 files changed, 1145 insertions, 161 deletions
diff --git a/spec/bundler/bundler/compact_index_client/parser_spec.rb b/spec/bundler/bundler/compact_index_client/parser_spec.rb
new file mode 100644
index 0000000000..1d1d41a5a8
--- /dev/null
+++ b/spec/bundler/bundler/compact_index_client/parser_spec.rb
@@ -0,0 +1,221 @@
+# frozen_string_literal: true
+
+require "bundler/compact_index_client"
+require "bundler/compact_index_client/parser"
+
+TestCompactIndexClient = Struct.new(:names, :versions, :info_data) do
+ # Requiring the checksum to match the input data helps ensure
+ # that we are parsing the correct checksum from the versions file
+ def info(name, checksum)
+ info_data.dig(name, checksum)
+ end
+
+ def set_info_data(name, value)
+ info_data[name] = value
+ end
+end
+
+RSpec.describe Bundler::CompactIndexClient::Parser do
+ subject(:parser) { described_class.new(compact_index) }
+
+ let(:compact_index) { TestCompactIndexClient.new(names, versions, info_data) }
+ let(:names) { "a\nb\nc\n" }
+ let(:versions) { <<~VERSIONS }
+ a 1.0.0,1.0.1,1.1.0 aaa111
+ b 2.0.0,2.0.0-java bbb222
+ c 3.0.0,3.0.3,3.3.3 ccc333
+ c -3.0.3 ccc333yanked
+ VERSIONS
+ let(:info_data) do
+ {
+ "a" => { "aaa111" => a_info },
+ "b" => { "bbb222" => b_info },
+ "c" => { "ccc333yanked" => c_info },
+ }
+ end
+ let(:a_info) { <<~INFO }
+ 1.0.0 |checksum:aaa1,ruby:>= 3.0.0,rubygems:>= 3.2.3
+ 1.0.1 |checksum:aaa2,ruby:>= 3.0.0,rubygems:>= 3.2.3
+ 1.1.0 |checksum:aaa3,ruby:>= 3.0.0,rubygems:>= 3.2.3
+ INFO
+ let(:b_info) { <<~INFO }
+ 2.0.0 a:~> 1.0&<= 3.0|checksum:bbb1
+ 2.0.0-java a:~> 1.0&<= 3.0|checksum:bbb2
+ INFO
+ let(:c_info) { <<~INFO }
+ 3.0.0 a:= 1.0.0,b:~> 2.0|checksum:ccc1,ruby:>= 2.7.0,rubygems:>= 3.0.0
+ 3.3.3 a:>= 1.1.0,b:~> 2.0|checksum:ccc3,ruby:>= 3.0.0,rubygems:>= 3.2.3
+ INFO
+
+ describe "#available?" do
+ it "returns true versions are available" do
+ expect(parser).to be_available
+ end
+
+ it "returns false when versions are not available" do
+ compact_index.versions = nil
+ expect(parser).not_to be_available
+ end
+ end
+
+ describe "#names" do
+ it "returns the names" do
+ expect(parser.names).to eq(%w[a b c])
+ end
+
+ it "returns an empty array when names is empty" do
+ compact_index.names = ""
+ expect(parser.names).to eq([])
+ end
+
+ it "returns an empty array when names is not readable" do
+ compact_index.names = nil
+ expect(parser.names).to eq([])
+ end
+ end
+
+ describe "#versions" do
+ it "returns the versions" do
+ expect(parser.versions).to eq(
+ "a" => [
+ ["a", "1.0.0"],
+ ["a", "1.0.1"],
+ ["a", "1.1.0"],
+ ],
+ "b" => [
+ ["b", "2.0.0"],
+ ["b", "2.0.0", "java"],
+ ],
+ "c" => [
+ ["c", "3.0.0"],
+ ["c", "3.3.3"],
+ ],
+ )
+ end
+
+ it "returns an empty hash when versions is empty" do
+ compact_index.versions = ""
+ expect(parser.versions).to eq({})
+ end
+
+ it "returns an empty hash when versions is not readable" do
+ compact_index.versions = nil
+ expect(parser.versions).to eq({})
+ end
+ end
+
+ describe "#info" do
+ it "returns the info for example gem 'a' which has no deps" do
+ expect(parser.info("a")).to eq(
+ [
+ [
+ "a",
+ "1.0.0",
+ nil,
+ [],
+ [
+ ["checksum", ["aaa1"]],
+ ["ruby", [">= 3.0.0"]],
+ ["rubygems", [">= 3.2.3"]],
+ ],
+ ],
+ [
+ "a",
+ "1.0.1",
+ nil,
+ [],
+ [
+ ["checksum", ["aaa2"]],
+ ["ruby", [">= 3.0.0"]],
+ ["rubygems", [">= 3.2.3"]],
+ ],
+ ],
+ [
+ "a",
+ "1.1.0",
+ nil,
+ [],
+ [
+ ["checksum", ["aaa3"]],
+ ["ruby", [">= 3.0.0"]],
+ ["rubygems", [">= 3.2.3"]],
+ ],
+ ],
+ ]
+ )
+ end
+
+ it "returns the info for example gem 'b' which has platform and compound deps" do
+ expect(parser.info("b")).to eq(
+ [
+ [
+ "b",
+ "2.0.0",
+ nil,
+ [
+ ["a", ["~> 1.0", "<= 3.0"]],
+ ],
+ [
+ ["checksum", ["bbb1"]],
+ ],
+ ],
+ [
+ "b",
+ "2.0.0",
+ "java",
+ [
+ ["a", ["~> 1.0", "<= 3.0"]],
+ ],
+ [
+ ["checksum", ["bbb2"]],
+ ],
+ ],
+ ]
+ )
+ end
+
+ it "returns the info for example gem 'c' which has deps and yanked version (requires use of correct info checksum)" do
+ expect(parser.info("c")).to eq(
+ [
+ [
+ "c",
+ "3.0.0",
+ nil,
+ [
+ ["a", ["= 1.0.0"]],
+ ["b", ["~> 2.0"]],
+ ],
+ [
+ ["checksum", ["ccc1"]],
+ ["ruby", [">= 2.7.0"]],
+ ["rubygems", [">= 3.0.0"]],
+ ],
+ ],
+ [
+ "c",
+ "3.3.3",
+ nil,
+ [
+ ["a", [">= 1.1.0"]],
+ ["b", ["~> 2.0"]],
+ ],
+ [
+ ["checksum", ["ccc3"]],
+ ["ruby", [">= 3.0.0"]],
+ ["rubygems", [">= 3.2.3"]],
+ ],
+ ],
+ ]
+ )
+ end
+
+ it "returns an empty array when the info is empty" do
+ compact_index.set_info_data("a", {})
+ expect(parser.info("a")).to eq([])
+ end
+
+ it "returns an empty array when the info is not readable" do
+ expect(parser.info("d")).to eq([])
+ end
+ end
+end
diff --git a/spec/bundler/bundler/compact_index_client/updater_spec.rb b/spec/bundler/bundler/compact_index_client/updater_spec.rb
index 6eed88ca9e..87a73d993f 100644
--- a/spec/bundler/bundler/compact_index_client/updater_spec.rb
+++ b/spec/bundler/bundler/compact_index_client/updater_spec.rb
@@ -119,23 +119,7 @@ RSpec.describe Bundler::CompactIndexClient::Updater do
context "without an etag file" do
let(:headers) do
- {
- "Range" => "bytes=2-",
- # This MD5 feature should be deleted after sufficient time has passed since release.
- # From then on, requests that still don't have a saved etag will be made without this header.
- "If-None-Match" => %("#{Digest::MD5.hexdigest(local_body)}"),
- }
- end
-
- it "saves only the etag_path if generated etag matches" do
- expect(fetcher).to receive(:call).once.with(remote_path, headers).and_return(response)
- allow(response).to receive(:is_a?).with(Gem::Net::HTTPPartialContent) { false }
- allow(response).to receive(:is_a?).with(Gem::Net::HTTPNotModified) { true }
-
- updater.update(remote_path, local_path, etag_path)
-
- expect(local_path.read).to eq("abc")
- expect(%("#{etag_path.read}")).to eq(headers["If-None-Match"])
+ { "Range" => "bytes=2-" }
end
it "appends the file" do
diff --git a/spec/bundler/bundler/fetcher/compact_index_spec.rb b/spec/bundler/bundler/fetcher/compact_index_spec.rb
index a988171f34..a7bb61a900 100644
--- a/spec/bundler/bundler/fetcher/compact_index_spec.rb
+++ b/spec/bundler/bundler/fetcher/compact_index_spec.rb
@@ -4,13 +4,15 @@
require "bundler/compact_index_client"
RSpec.describe Bundler::Fetcher::CompactIndex do
- let(:downloader) { double(:downloader) }
+ let(:response) { double(:response) }
+ let(:downloader) { double(:downloader, fetch: response) }
let(:display_uri) { Gem::URI("http://sampleuri.com") }
let(:remote) { double(:remote, cache_slug: "lsjdf", uri: display_uri) }
let(:gem_remote_fetcher) { nil }
let(:compact_index) { described_class.new(downloader, remote, display_uri, gem_remote_fetcher) }
before do
+ allow(response).to receive(:is_a?).with(Gem::Net::HTTPNotModified).and_return(true)
allow(compact_index).to receive(:log_specs) {}
end
@@ -34,7 +36,7 @@ RSpec.describe Bundler::Fetcher::CompactIndex do
describe "#available?" do
before do
allow(compact_index).to receive(:compact_index_client).
- and_return(double(:compact_index_client, update_and_parse_checksums!: true))
+ and_return(double(:compact_index_client, available?: true))
end
it "returns true" do
diff --git a/spec/bundler/bundler/source/git/git_proxy_spec.rb b/spec/bundler/bundler/source/git/git_proxy_spec.rb
index 1450316d59..f7c883eed4 100644
--- a/spec/bundler/bundler/source/git/git_proxy_spec.rb
+++ b/spec/bundler/bundler/source/git/git_proxy_spec.rb
@@ -197,4 +197,18 @@ RSpec.describe Bundler::Source::Git::GitProxy do
expect(Pathname.new(bundled_app("canary"))).not_to exist
end
+
+ context "URI is HTTP" do
+ let(:uri) { "http://github.com/rubygems/rubygems.git" }
+ let(:without_depth_arguments) { ["clone", "--bare", "--no-hardlinks", "--quiet", "--no-tags", "--single-branch"] }
+ let(:fail_clone_result) { double(Process::Status, success?: false) }
+
+ it "retries without --depth when git url is http and fails" do
+ allow(git_proxy).to receive(:git_local).with("--version").and_return("git version 2.14.0")
+ allow(git_proxy).to receive(:capture).with([*base_clone_args, "--", uri, path.to_s], nil).and_return(["", "dumb http transport does not support shallow capabilities", fail_clone_result])
+ expect(git_proxy).to receive(:capture).with([*without_depth_arguments, "--", uri, path.to_s], nil).and_return(["", "", clone_result])
+
+ subject.checkout
+ end
+ end
end
diff --git a/spec/bundler/commands/cache_spec.rb b/spec/bundler/commands/cache_spec.rb
index 70e2c84961..37d8b3ac1a 100644
--- a/spec/bundler/commands/cache_spec.rb
+++ b/spec/bundler/commands/cache_spec.rb
@@ -386,6 +386,66 @@ RSpec.describe "bundle install with gem sources" do
expect(the_bundle).to include_gems "rack 1.0.0"
end
+ it "uses cached gems for secondary sources when cache_all_platforms configured" do
+ build_repo4 do
+ build_gem "foo", "1.0.0" do |s|
+ s.platform = "x86_64-linux"
+ end
+
+ build_gem "foo", "1.0.0" do |s|
+ s.platform = "arm64-darwin"
+ end
+ end
+
+ gemfile <<~G
+ source "https://gems.repo2"
+
+ source "https://gems.repo4" do
+ gem "foo"
+ end
+ G
+
+ lockfile <<~L
+ GEM
+ remote: https://gems.repo2/
+ specs:
+
+ GEM
+ remote: https://gems.repo4/
+ specs:
+ foo (1.0.0-x86_64-linux)
+ foo (1.0.0-arm64-darwin)
+
+ PLATFORMS
+ arm64-darwin
+ ruby
+ x86_64-linux
+
+ DEPENDENCIES
+ foo
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ simulate_platform "x86_64-linux" do
+ bundle "config set cache_all_platforms true"
+ bundle "config set path vendor/bundle"
+ bundle :cache, artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+
+ build_repo4 do
+ # simulate removal of all remote gems
+ end
+
+ # delete compact index cache
+ FileUtils.rm_rf home(".bundle/cache/compact_index")
+
+ bundle "install", artifice: "compact_index", env: { "BUNDLER_SPEC_GEM_REPO" => gem_repo4.to_s }
+
+ expect(the_bundle).to include_gems "foo 1.0.0 x86_64-linux"
+ end
+ end
+
it "does not reinstall already-installed gems" do
install_gemfile <<-G
source "#{file_uri_for(gem_repo1)}"
diff --git a/spec/bundler/commands/exec_spec.rb b/spec/bundler/commands/exec_spec.rb
index d59b690d2f..9f5f12739a 100644
--- a/spec/bundler/commands/exec_spec.rb
+++ b/spec/bundler/commands/exec_spec.rb
@@ -885,7 +885,7 @@ RSpec.describe "bundle exec" do
let(:exit_code) { Bundler::GemNotFound.new.status_code }
let(:expected) { "" }
let(:expected_err) { <<-EOS.strip }
-Could not find gem 'rack (= 2)' in cached gems or installed locally.
+Could not find gem 'rack (= 2)' in locally installed gems.
The source contains the following gems matching 'rack':
* rack-0.9.1
@@ -915,7 +915,7 @@ Run `bundle install` to install missing gems.
let(:exit_code) { Bundler::GemNotFound.new.status_code }
let(:expected) { "" }
let(:expected_err) { <<-EOS.strip }
-Could not find gem 'rack (= 2)' in cached gems or installed locally.
+Could not find gem 'rack (= 2)' in locally installed gems.
The source contains the following gems matching 'rack':
* rack-1.0.0
diff --git a/spec/bundler/commands/install_spec.rb b/spec/bundler/commands/install_spec.rb
index f0c9aaea8e..edc5887d7b 100644
--- a/spec/bundler/commands/install_spec.rb
+++ b/spec/bundler/commands/install_spec.rb
@@ -1024,6 +1024,29 @@ RSpec.describe "bundle install with gem sources" do
end
end
+ describe "when gemspecs are unreadable", :permissions do
+ let(:gemspec_path) { vendored_gems("specifications/rack-1.0.0.gemspec") }
+
+ before do
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo1)}"
+ gem 'rack'
+ G
+ bundle "config path vendor/bundle"
+ bundle :install
+ expect(out).to include("Bundle complete!")
+ expect(err).to be_empty
+
+ FileUtils.chmod("-r", gemspec_path)
+ end
+
+ it "shows a good error" do
+ bundle :install, raise_on_error: false
+ expect(err).to include(gemspec_path.to_s)
+ expect(err).to include("grant read permissions")
+ end
+ end
+
context "after installing with --standalone" do
before do
install_gemfile <<-G
@@ -1384,4 +1407,33 @@ RSpec.describe "bundle install with gem sources" do
expect(bundled_app(".bundle/config")).not_to exist
end
end
+
+ context "when bundler installation is corrupt" do
+ before do
+ system_gems "bundler-9.99.8"
+
+ replace_version_file("9.99.9", dir: system_gem_path("gems/bundler-9.99.8"))
+ end
+
+ it "shows a proper error" do
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo1)}/
+ specs:
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+
+ BUNDLED WITH
+ 9.99.8
+ L
+
+ install_gemfile "source \"#{file_uri_for(gem_repo1)}\"", env: { "BUNDLER_VERSION" => "9.99.8" }, raise_on_error: false
+
+ expect(err).not_to include("ERROR REPORT TEMPLATE")
+ expect(err).to include("The running version of Bundler (9.99.9) does not match the version of the specification installed for it (9.99.8)")
+ end
+ end
end
diff --git a/spec/bundler/commands/lock_spec.rb b/spec/bundler/commands/lock_spec.rb
index f6793d393b..b0d6fa9134 100644
--- a/spec/bundler/commands/lock_spec.rb
+++ b/spec/bundler/commands/lock_spec.rb
@@ -138,7 +138,7 @@ RSpec.describe "bundle lock" do
it "does not fetch remote specs when using the --local option" do
bundle "lock --update --local", raise_on_error: false
- expect(err).to match(/cached gems or installed locally/)
+ expect(err).to match(/locally installed gems/)
end
it "does not fetch remote checksums with --local" do
@@ -252,6 +252,128 @@ RSpec.describe "bundle lock" do
expect(read_lockfile).to eq(remove_checksums_from_lockfile(@lockfile, "(2.3.2)", "(#{rake_version})"))
end
+ it "updates specific gems using --update, even if that requires unlocking other top level gems" do
+ build_repo4 do
+ build_gem "prism", "0.15.1"
+ build_gem "prism", "0.24.0"
+
+ build_gem "ruby-lsp", "0.12.0" do |s|
+ s.add_dependency "prism", "< 0.24.0"
+ end
+
+ build_gem "ruby-lsp", "0.16.1" do |s|
+ s.add_dependency "prism", ">= 0.24.0"
+ end
+
+ build_gem "tapioca", "0.11.10" do |s|
+ s.add_dependency "prism", "< 0.24.0"
+ end
+
+ build_gem "tapioca", "0.13.1" do |s|
+ s.add_dependency "prism", ">= 0.24.0"
+ end
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "tapioca"
+ gem "ruby-lsp"
+ G
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}
+ specs:
+ prism (0.15.1)
+ ruby-lsp (0.12.0)
+ prism (< 0.24.0)
+ tapioca (0.11.10)
+ prism (< 0.24.0)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ ruby-lsp
+ tapioca
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "lock --update tapioca --verbose"
+
+ expect(lockfile).to include("tapioca (0.13.1)")
+ end
+
+ it "updates specific gems using --update, even if that requires unlocking other top level gems, but only as few as possible" do
+ build_repo4 do
+ build_gem "prism", "0.15.1"
+ build_gem "prism", "0.24.0"
+
+ build_gem "ruby-lsp", "0.12.0" do |s|
+ s.add_dependency "prism", "< 0.24.0"
+ end
+
+ build_gem "ruby-lsp", "0.16.1" do |s|
+ s.add_dependency "prism", ">= 0.24.0"
+ end
+
+ build_gem "tapioca", "0.11.10" do |s|
+ s.add_dependency "prism", "< 0.24.0"
+ end
+
+ build_gem "tapioca", "0.13.1" do |s|
+ s.add_dependency "prism", ">= 0.24.0"
+ end
+
+ build_gem "other-prism-dependent", "1.0.0" do |s|
+ s.add_dependency "prism", ">= 0.15.1"
+ end
+
+ build_gem "other-prism-dependent", "1.1.0" do |s|
+ s.add_dependency "prism", ">= 0.15.1"
+ end
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+
+ gem "tapioca"
+ gem "ruby-lsp"
+ gem "other-prism-dependent"
+ G
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}
+ specs:
+ other-prism-dependent (1.0.0)
+ prism (>= 0.15.1)
+ prism (0.15.1)
+ ruby-lsp (0.12.0)
+ prism (< 0.24.0)
+ tapioca (0.11.10)
+ prism (< 0.24.0)
+
+ PLATFORMS
+ #{lockfile_platforms}
+
+ DEPENDENCIES
+ ruby-lsp
+ tapioca
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+
+ bundle "lock --update tapioca"
+
+ expect(lockfile).to include("tapioca (0.13.1)")
+ expect(lockfile).to include("other-prism-dependent (1.0.0)")
+ end
+
it "preserves unknown checksum algorithms" do
lockfile @lockfile.gsub(/(sha256=[a-f0-9]+)$/, "constant=true,\\1,xyz=123")
@@ -1227,7 +1349,7 @@ RSpec.describe "bundle lock" do
Because rails >= 7.0.4 depends on railties = 7.0.4
and rails < 7.0.4 depends on railties = 7.0.3.1,
railties = 7.0.3.1 OR = 7.0.4 is required.
- So, because railties = 7.0.3.1 OR = 7.0.4 could not be found in rubygems repository #{file_uri_for(gem_repo4)}/, cached gems or installed locally,
+ So, because railties = 7.0.3.1 OR = 7.0.4 could not be found in rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally,
version solving has failed.
ERR
end
@@ -1338,7 +1460,7 @@ RSpec.describe "bundle lock" do
Thus, rails >= 7.0.2.3, < 7.0.4 cannot be used.
And because rails >= 7.0.4 depends on activemodel = 7.0.4,
rails >= 7.0.2.3 requires activemodel = 7.0.4.
- So, because activemodel = 7.0.4 could not be found in rubygems repository #{file_uri_for(gem_repo4)}/, cached gems or installed locally
+ So, because activemodel = 7.0.4 could not be found in rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally
and Gemfile depends on rails >= 7.0.2.3,
version solving has failed.
ERR
diff --git a/spec/bundler/commands/newgem_spec.rb b/spec/bundler/commands/newgem_spec.rb
index 199340b131..53d0f9d6eb 100644
--- a/spec/bundler/commands/newgem_spec.rb
+++ b/spec/bundler/commands/newgem_spec.rb
@@ -36,22 +36,25 @@ RSpec.describe "bundle gem" do
sys_exec("git config --global user.name 'Bundler User'")
sys_exec("git config --global user.email user@example.com")
sys_exec("git config --global github.user bundleuser")
+
+ global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__LINTER" => "false",
+ "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__CHANGELOG" => "false"
end
describe "git repo initialization" do
- it "generates a gem skeleton with a .git folder", :readline do
+ it "generates a gem skeleton with a .git folder" do
bundle "gem #{gem_name}"
gem_skeleton_assertions
expect(bundled_app("#{gem_name}/.git")).to exist
end
- it "generates a gem skeleton with a .git folder when passing --git", :readline do
+ it "generates a gem skeleton with a .git folder when passing --git" do
bundle "gem #{gem_name} --git"
gem_skeleton_assertions
expect(bundled_app("#{gem_name}/.git")).to exist
end
- it "generates a gem skeleton without a .git folder when passing --no-git", :readline do
+ it "generates a gem skeleton without a .git folder when passing --no-git" do
bundle "gem #{gem_name} --no-git"
gem_skeleton_assertions
expect(bundled_app("#{gem_name}/.git")).not_to exist
@@ -62,7 +65,9 @@ RSpec.describe "bundle gem" do
Dir.mkdir(bundled_app("path with spaces"))
end
- it "properly initializes git repo", :readline do
+ it "properly initializes git repo" do
+ skip "path with spaces needs special handling on Windows" if Gem.win_platform?
+
bundle "gem #{gem_name}", dir: bundled_app("path with spaces")
expect(bundled_app("path with spaces/#{gem_name}/.git")).to exist
end
@@ -131,7 +136,7 @@ RSpec.describe "bundle gem" do
before do
bundle "gem #{gem_name} --changelog"
end
- it "generates a gem skeleton with a CHANGELOG", :readline do
+ it "generates a gem skeleton with a CHANGELOG" do
gem_skeleton_assertions
expect(bundled_app("#{gem_name}/CHANGELOG.md")).to exist
end
@@ -141,7 +146,7 @@ RSpec.describe "bundle gem" do
before do
bundle "gem #{gem_name} --no-changelog"
end
- it "generates a gem skeleton without a CHANGELOG", :readline do
+ it "generates a gem skeleton without a CHANGELOG" do
gem_skeleton_assertions
expect(bundled_app("#{gem_name}/CHANGELOG.md")).to_not exist
end
@@ -150,6 +155,7 @@ RSpec.describe "bundle gem" do
shared_examples_for "--rubocop flag" do
context "is deprecated", bundler: "< 3" do
before do
+ global_config "BUNDLE_GEM__LINTER" => nil
bundle "gem #{gem_name} --rubocop"
end
@@ -303,49 +309,49 @@ RSpec.describe "bundle gem" do
end
end
- it "has no rubocop offenses when using --linter=rubocop flag", :readline do
+ it "has no rubocop offenses when using --linter=rubocop flag" do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
bundle "gem #{gem_name} --linter=rubocop"
bundle_exec_rubocop
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext=c and --linter=rubocop flag", :readline do
+ it "has no rubocop offenses when using --ext=c and --linter=rubocop flag" do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
bundle "gem #{gem_name} --ext=c --linter=rubocop"
bundle_exec_rubocop
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext=c, --test=minitest, and --linter=rubocop flag", :readline do
+ it "has no rubocop offenses when using --ext=c, --test=minitest, and --linter=rubocop flag" do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
bundle "gem #{gem_name} --ext=c --test=minitest --linter=rubocop"
bundle_exec_rubocop
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext=c, --test=rspec, and --linter=rubocop flag", :readline do
+ it "has no rubocop offenses when using --ext=c, --test=rspec, and --linter=rubocop flag" do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
bundle "gem #{gem_name} --ext=c --test=rspec --linter=rubocop"
bundle_exec_rubocop
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext=c, --test=test-unit, and --linter=rubocop flag", :readline do
+ it "has no rubocop offenses when using --ext=c, --test=test-unit, and --linter=rubocop flag" do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
bundle "gem #{gem_name} --ext=c --test=test-unit --linter=rubocop"
bundle_exec_rubocop
expect(last_command).to be_success
end
- it "has no standard offenses when using --linter=standard flag", :readline do
+ it "has no standard offenses when using --linter=standard flag" do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
bundle "gem #{gem_name} --linter=standard"
bundle_exec_standardrb
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext=rust and --linter=rubocop flag", :readline do
+ it "has no rubocop offenses when using --ext=rust and --linter=rubocop flag" do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
skip "RubyGems incompatible with Rust builder" if ::Gem::Version.new("3.3.11") > ::Gem.rubygems_version
@@ -354,7 +360,7 @@ RSpec.describe "bundle gem" do
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext=rust, --test=minitest, and --linter=rubocop flag", :readline do
+ it "has no rubocop offenses when using --ext=rust, --test=minitest, and --linter=rubocop flag" do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
skip "RubyGems incompatible with Rust builder" if ::Gem::Version.new("3.3.11") > ::Gem.rubygems_version
@@ -363,7 +369,7 @@ RSpec.describe "bundle gem" do
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext=rust, --test=rspec, and --linter=rubocop flag", :readline do
+ it "has no rubocop offenses when using --ext=rust, --test=rspec, and --linter=rubocop flag" do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
skip "RubyGems incompatible with Rust builder" if ::Gem::Version.new("3.3.11") > ::Gem.rubygems_version
@@ -372,7 +378,7 @@ RSpec.describe "bundle gem" do
expect(last_command).to be_success
end
- it "has no rubocop offenses when using --ext=rust, --test=test-unit, and --linter=rubocop flag", :readline do
+ it "has no rubocop offenses when using --ext=rust, --test=test-unit, and --linter=rubocop flag" do
skip "ruby_core has an 'ast.rb' file that gets in the middle and breaks this spec" if ruby_core?
skip "RubyGems incompatible with Rust builder" if ::Gem::Version.new("3.3.11") > ::Gem.rubygems_version
@@ -399,7 +405,7 @@ RSpec.describe "bundle gem" do
end
end
- context "README.md", :readline do
+ context "README.md" do
context "git config github.user present" do
before do
bundle "gem #{gem_name}"
@@ -424,12 +430,12 @@ RSpec.describe "bundle gem" do
end
end
- it "creates a new git repository", :readline do
+ it "creates a new git repository" do
bundle "gem #{gem_name}"
expect(bundled_app("#{gem_name}/.git")).to exist
end
- context "when git is not available", :readline do
+ context "when git is not available" do
# This spec cannot have `git` available in the test env
before do
load_paths = [lib_dir, spec_dir]
@@ -451,7 +457,7 @@ RSpec.describe "bundle gem" do
end
end
- it "generates a valid gemspec", :readline, :ruby_repo do
+ it "generates a valid gemspec", :ruby_repo do
bundle "gem newgem --bin"
prepare_gemspec(bundled_app("newgem", "newgem.gemspec"))
@@ -464,7 +470,7 @@ RSpec.describe "bundle gem" do
expect(last_command.stdboth).not_to include("ERROR")
end
- context "gem naming with relative paths", :readline do
+ context "gem naming with relative paths" do
it "resolves ." do
create_temporary_dir("tmp")
@@ -557,8 +563,12 @@ RSpec.describe "bundle gem" do
expect(bundled_app("#{gem_name}/bin/setup")).to exist
expect(bundled_app("#{gem_name}/bin/console")).to exist
- expect(bundled_app("#{gem_name}/bin/setup")).to be_executable
- expect(bundled_app("#{gem_name}/bin/console")).to be_executable
+
+ unless Gem.win_platform?
+ expect(bundled_app("#{gem_name}/bin/setup")).to be_executable
+ expect(bundled_app("#{gem_name}/bin/console")).to be_executable
+ end
+
expect(bundled_app("#{gem_name}/bin/setup").read).to start_with("#!")
expect(bundled_app("#{gem_name}/bin/console").read).to start_with("#!")
end
@@ -870,7 +880,7 @@ RSpec.describe "bundle gem" do
end
end
- context "gem.test set to rspec and --test with no arguments", :hint_text do
+ context "gem.test set to rspec and --test with no arguments" do
before do
bundle "config set gem.test rspec"
bundle "gem #{gem_name} --test"
@@ -887,10 +897,12 @@ RSpec.describe "bundle gem" do
end
end
- context "gem.test setting set to false and --test with no arguments", :hint_text do
+ context "gem.test setting set to false and --test with no arguments", :readline do
before do
bundle "config set gem.test false"
- bundle "gem #{gem_name} --test"
+ bundle "gem #{gem_name} --test" do |input, _, _|
+ input.puts
+ end
end
it "asks to generate test files" do
@@ -904,9 +916,12 @@ RSpec.describe "bundle gem" do
it_behaves_like "test framework is absent"
end
- context "gem.test setting not set and --test with no arguments", :hint_text do
+ context "gem.test setting not set and --test with no arguments", :readline do
before do
- bundle "gem #{gem_name} --test"
+ global_config "BUNDLE_GEM__TEST" => nil
+ bundle "gem #{gem_name} --test" do |input, _, _|
+ input.puts
+ end
end
it "asks to generate test files" do
@@ -1009,7 +1024,7 @@ RSpec.describe "bundle gem" do
end
end
- context "gem.ci set to github and --ci with no arguments", :hint_text do
+ context "gem.ci set to github and --ci with no arguments" do
before do
bundle "config set gem.ci github"
bundle "gem #{gem_name} --ci"
@@ -1024,10 +1039,12 @@ RSpec.describe "bundle gem" do
end
end
- context "gem.ci setting set to false and --ci with no arguments", :hint_text do
+ context "gem.ci setting set to false and --ci with no arguments", :readline do
before do
bundle "config set gem.ci false"
- bundle "gem #{gem_name} --ci"
+ bundle "gem #{gem_name} --ci" do |input, _, _|
+ input.puts "github"
+ end
end
it "asks to setup CI" do
@@ -1039,9 +1056,12 @@ RSpec.describe "bundle gem" do
end
end
- context "gem.ci setting not set and --ci with no arguments", :hint_text do
+ context "gem.ci setting not set and --ci with no arguments", :readline do
before do
- bundle "gem #{gem_name} --ci"
+ global_config "BUNDLE_GEM__CI" => nil
+ bundle "gem #{gem_name} --ci" do |input, _, _|
+ input.puts "github"
+ end
end
it "asks to setup CI" do
@@ -1111,6 +1131,7 @@ RSpec.describe "bundle gem" do
context "gem.rubocop setting set to true", bundler: "< 3" do
before do
+ global_config "BUNDLE_GEM__LINTER" => nil
bundle "config set gem.rubocop true"
bundle "gem #{gem_name}"
end
@@ -1130,7 +1151,7 @@ RSpec.describe "bundle gem" do
end
end
- context "gem.linter set to rubocop and --linter with no arguments", :hint_text do
+ context "gem.linter set to rubocop and --linter with no arguments" do
before do
bundle "config set gem.linter rubocop"
bundle "gem #{gem_name} --linter"
@@ -1145,10 +1166,12 @@ RSpec.describe "bundle gem" do
end
end
- context "gem.linter setting set to false and --linter with no arguments", :hint_text do
+ context "gem.linter setting set to false and --linter with no arguments", :readline do
before do
bundle "config set gem.linter false"
- bundle "gem #{gem_name} --linter"
+ bundle "gem #{gem_name} --linter" do |input, _, _|
+ input.puts "rubocop"
+ end
end
it "asks to setup a linter" do
@@ -1160,9 +1183,12 @@ RSpec.describe "bundle gem" do
end
end
- context "gem.linter setting not set and --linter with no arguments", :hint_text do
+ context "gem.linter setting not set and --linter with no arguments", :readline do
before do
- bundle "gem #{gem_name} --linter"
+ global_config "BUNDLE_GEM__LINTER" => nil
+ bundle "gem #{gem_name} --linter" do |input, _, _|
+ input.puts "rubocop"
+ end
end
it "asks to setup a linter" do
@@ -1185,7 +1211,7 @@ RSpec.describe "bundle gem" do
end
end
- context "testing --mit and --coc options against bundle config settings", :readline do
+ context "testing --mit and --coc options against bundle config settings" do
let(:gem_name) { "test-gem" }
let(:require_path) { "test/gem" }
@@ -1288,7 +1314,7 @@ RSpec.describe "bundle gem" do
end
end
- context "testing --github-username option against git and bundle config settings", :readline do
+ context "testing --github-username option against git and bundle config settings" do
context "without git config set" do
before do
sys_exec("git config --global --unset github.user")
@@ -1325,7 +1351,7 @@ RSpec.describe "bundle gem" do
end
end
- context "testing github_username bundle config against git config settings", :readline do
+ context "testing github_username bundle config against git config settings" do
context "without git config set" do
before do
sys_exec("git config --global --unset github.user")
@@ -1339,7 +1365,7 @@ RSpec.describe "bundle gem" do
end
end
- context "gem naming with underscore", :readline do
+ context "gem naming with underscore" do
let(:gem_name) { "test_gem" }
let(:require_path) { "test_gem" }
@@ -1485,7 +1511,7 @@ RSpec.describe "bundle gem" do
end
end
- context "gem naming with dashed", :readline do
+ context "gem naming with dashed" do
let(:gem_name) { "test-gem" }
let(:require_path) { "test/gem" }
@@ -1506,7 +1532,7 @@ RSpec.describe "bundle gem" do
end
describe "uncommon gem names" do
- it "can deal with two dashes", :readline do
+ it "can deal with two dashes" do
bundle "gem a--a"
expect(bundled_app("a--a/a--a.gemspec")).to exist
@@ -1536,7 +1562,7 @@ Usage: "bundle gem NAME [OPTIONS]"
end
end
- describe "#ensure_safe_gem_name", :readline do
+ describe "#ensure_safe_gem_name" do
before do
bundle "gem #{subject}", raise_on_error: false
end
@@ -1564,7 +1590,7 @@ Usage: "bundle gem NAME [OPTIONS]"
context "on first run", :readline do
it "asks about test framework" do
- global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__COC" => "false"
+ global_config "BUNDLE_GEM__TEST" => nil
bundle "gem foobar" do |input, _, _|
input.puts "rspec"
@@ -1587,7 +1613,7 @@ Usage: "bundle gem NAME [OPTIONS]"
end
it "asks about CI service" do
- global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__LINTER" => "false"
+ global_config "BUNDLE_GEM__CI" => nil
bundle "gem foobar" do |input, _, _|
input.puts "github"
@@ -1597,7 +1623,7 @@ Usage: "bundle gem NAME [OPTIONS]"
end
it "asks about MIT license" do
- global_config "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false"
+ global_config "BUNDLE_GEM__MIT" => nil
bundle "config list"
@@ -1609,7 +1635,7 @@ Usage: "bundle gem NAME [OPTIONS]"
end
it "asks about CoC" do
- global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false"
+ global_config "BUNDLE_GEM__COC" => nil
bundle "gem foobar" do |input, _, _|
input.puts "yes"
@@ -1619,8 +1645,7 @@ Usage: "bundle gem NAME [OPTIONS]"
end
it "asks about CHANGELOG" do
- global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__LINTER" => "false",
- "BUNDLE_GEM__COC" => "false"
+ global_config "BUNDLE_GEM__CHANGELOG" => nil
bundle "gem foobar" do |input, _, _|
input.puts "yes"
@@ -1630,7 +1655,7 @@ Usage: "bundle gem NAME [OPTIONS]"
end
end
- context "on conflicts with a previously created file", :readline do
+ context "on conflicts with a previously created file" do
it "should fail gracefully" do
FileUtils.touch(bundled_app("conflict-foobar"))
bundle "gem conflict-foobar", raise_on_error: false
@@ -1639,7 +1664,7 @@ Usage: "bundle gem NAME [OPTIONS]"
end
end
- context "on conflicts with a previously created directory", :readline do
+ context "on conflicts with a previously created directory" do
it "should succeed" do
FileUtils.mkdir_p(bundled_app("conflict-foobar/Gemfile"))
bundle "gem conflict-foobar"
diff --git a/spec/bundler/commands/post_bundle_message_spec.rb b/spec/bundler/commands/post_bundle_message_spec.rb
index 07fd5a79e9..3c7fd3486d 100644
--- a/spec/bundler/commands/post_bundle_message_spec.rb
+++ b/spec/bundler/commands/post_bundle_message_spec.rb
@@ -120,7 +120,7 @@ RSpec.describe "post bundle message" do
gem "not-a-gem", :group => :development
G
expect(err).to include <<-EOS.strip
-Could not find gem 'not-a-gem' in rubygems repository #{file_uri_for(gem_repo1)}/, cached gems or installed locally.
+Could not find gem 'not-a-gem' in rubygems repository #{file_uri_for(gem_repo1)}/ or installed locally.
EOS
end
diff --git a/spec/bundler/commands/update_spec.rb b/spec/bundler/commands/update_spec.rb
index cfb86ebb54..8565e27ebf 100644
--- a/spec/bundler/commands/update_spec.rb
+++ b/spec/bundler/commands/update_spec.rb
@@ -1954,6 +1954,52 @@ RSpec.describe "bundle update conservative" do
end
end
+ context "when Gemfile dependencies have changed" do
+ before do
+ build_repo4 do
+ build_gem "nokogiri", "1.16.4" do |s|
+ s.platform = "arm64-darwin"
+ end
+
+ build_gem "nokogiri", "1.16.4" do |s|
+ s.platform = "x86_64-linux"
+ end
+
+ build_gem "prism", "0.25.0"
+ end
+
+ gemfile <<~G
+ source "#{file_uri_for(gem_repo4)}"
+ gem "nokogiri", ">=1.16.4"
+ gem "prism", ">=0.25.0"
+ G
+
+ lockfile <<~L
+ GEM
+ remote: #{file_uri_for(gem_repo4)}/
+ specs:
+ nokogiri (1.16.4-arm64-darwin)
+ nokogiri (1.16.4-x86_64-linux)
+
+ PLATFORMS
+ arm64-darwin
+ x86_64-linux
+
+ DEPENDENCIES
+ nokogiri (>= 1.16.4)
+
+ BUNDLED WITH
+ #{Bundler::VERSION}
+ L
+ end
+
+ it "still works" do
+ simulate_platform "arm64-darwin-23" do
+ bundle "update"
+ end
+ end
+ end
+
context "error handling" do
before do
gemfile "source \"#{file_uri_for(gem_repo1)}\""
diff --git a/spec/bundler/install/gemfile/git_spec.rb b/spec/bundler/install/gemfile/git_spec.rb
index 45ee7b44d1..24cf30eadb 100644
--- a/spec/bundler/install/gemfile/git_spec.rb
+++ b/spec/bundler/install/gemfile/git_spec.rb
@@ -929,7 +929,7 @@ RSpec.describe "bundle install with git sources" do
gem "has_submodule"
end
G
- expect(err).to match(%r{submodule >= 0 could not be found in rubygems repository #{file_uri_for(gem_repo1)}/, cached gems or installed locally})
+ expect(err).to match(%r{submodule >= 0 could not be found in rubygems repository #{file_uri_for(gem_repo1)}/ or installed locally})
expect(the_bundle).not_to include_gems "has_submodule 1.0"
end
diff --git a/spec/bundler/install/gemfile/sources_spec.rb b/spec/bundler/install/gemfile/sources_spec.rb
index a5ba76f4d9..daee8a2744 100644
--- a/spec/bundler/install/gemfile/sources_spec.rb
+++ b/spec/bundler/install/gemfile/sources_spec.rb
@@ -520,7 +520,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
it "fails" do
bundle :install, artifice: "compact_index", raise_on_error: false
- expect(err).to include("Could not find gem 'private_gem_1' in rubygems repository https://gem.repo2/, cached gems or installed locally.")
+ expect(err).to include("Could not find gem 'private_gem_1' in rubygems repository https://gem.repo2/ or installed locally.")
end
end
@@ -611,7 +611,7 @@ RSpec.describe "bundle install with gems on multiple sources" do
Could not find compatible versions
Because every version of depends_on_rack depends on rack >= 0
- and rack >= 0 could not be found in rubygems repository https://gem.repo2/, cached gems or installed locally,
+ and rack >= 0 could not be found in rubygems repository https://gem.repo2/ or installed locally,
depends_on_rack cannot be used.
So, because Gemfile depends on depends_on_rack >= 0,
version solving has failed.
diff --git a/spec/bundler/install/gemfile/specific_platform_spec.rb b/spec/bundler/install/gemfile/specific_platform_spec.rb
index 5f1b034bfc..1a33053dc6 100644
--- a/spec/bundler/install/gemfile/specific_platform_spec.rb
+++ b/spec/bundler/install/gemfile/specific_platform_spec.rb
@@ -395,7 +395,7 @@ RSpec.describe "bundle install with specific platforms" do
G
error_message = <<~ERROR.strip
- Could not find gem 'sorbet-static (= 0.5.6433)' with platform 'arm64-darwin-21' in rubygems repository #{file_uri_for(gem_repo4)}/, cached gems or installed locally.
+ Could not find gem 'sorbet-static (= 0.5.6433)' with platform 'arm64-darwin-21' in rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally.
The source contains the following gems matching 'sorbet-static (= 0.5.6433)':
* sorbet-static-0.5.6433-universal-darwin-20
@@ -434,7 +434,7 @@ RSpec.describe "bundle install with specific platforms" do
Could not find compatible versions
Because every version of sorbet depends on sorbet-static = 0.5.6433
- and sorbet-static = 0.5.6433 could not be found in rubygems repository #{file_uri_for(gem_repo4)}/, cached gems or installed locally for any resolution platforms (arm64-darwin-21),
+ and sorbet-static = 0.5.6433 could not be found in rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally for any resolution platforms (arm64-darwin-21),
sorbet cannot be used.
So, because Gemfile depends on sorbet = 0.5.6433,
version solving has failed.
@@ -473,7 +473,7 @@ RSpec.describe "bundle install with specific platforms" do
bundle "lock", raise_on_error: false, env: { "BUNDLE_FORCE_RUBY_PLATFORM" => "true" }
expect(err).to include <<~ERROR.rstrip
- Could not find gem 'sorbet-static (= 0.5.9889)' with platform 'ruby' in rubygems repository #{file_uri_for(gem_repo4)}/, cached gems or installed locally.
+ Could not find gem 'sorbet-static (= 0.5.9889)' with platform 'ruby' in rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally.
The source contains the following gems matching 'sorbet-static (= 0.5.9889)':
* sorbet-static-0.5.9889-#{Gem::Platform.local}
diff --git a/spec/bundler/install/gems/flex_spec.rb b/spec/bundler/install/gems/flex_spec.rb
index 8ef3984975..5e0c88fc95 100644
--- a/spec/bundler/install/gems/flex_spec.rb
+++ b/spec/bundler/install/gems/flex_spec.rb
@@ -197,7 +197,7 @@ RSpec.describe "bundle flex_install" do
Could not find compatible versions
Because rack-obama >= 2.0 depends on rack = 1.2
- and rack = 1.2 could not be found in rubygems repository #{file_uri_for(gem_repo2)}/, cached gems or installed locally,
+ and rack = 1.2 could not be found in rubygems repository #{file_uri_for(gem_repo2)}/ or installed locally,
rack-obama >= 2.0 cannot be used.
So, because Gemfile depends on rack-obama = 2.0,
version solving has failed.
diff --git a/spec/bundler/install/gems/resolving_spec.rb b/spec/bundler/install/gems/resolving_spec.rb
index c5f9c4a3d3..b54674898d 100644
--- a/spec/bundler/install/gems/resolving_spec.rb
+++ b/spec/bundler/install/gems/resolving_spec.rb
@@ -434,7 +434,7 @@ RSpec.describe "bundle install with install-time dependencies" do
end
nice_error = <<~E.strip
- Could not find gems matching 'sorbet-static (= 0.5.10554)' valid for all resolution platforms (arm64-darwin-21, aarch64-linux) in rubygems repository #{file_uri_for(gem_repo4)}/, cached gems or installed locally.
+ Could not find gems matching 'sorbet-static (= 0.5.10554)' valid for all resolution platforms (arm64-darwin-21, aarch64-linux) in rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally.
The source contains the following gems matching 'sorbet-static (= 0.5.10554)':
* sorbet-static-0.5.10554-universal-darwin-21
@@ -490,7 +490,7 @@ RSpec.describe "bundle install with install-time dependencies" do
it "raises a proper error" do
nice_error = <<~E.strip
- Could not find gems matching 'sorbet-static' valid for all resolution platforms (arm-linux, x86_64-linux) in rubygems repository #{file_uri_for(gem_repo4)}/, cached gems or installed locally.
+ Could not find gems matching 'sorbet-static' valid for all resolution platforms (arm-linux, x86_64-linux) in rubygems repository #{file_uri_for(gem_repo4)}/ or installed locally.
The source contains the following gems matching 'sorbet-static':
* sorbet-static-0.5.10696-x86_64-linux
diff --git a/spec/bundler/install/yanked_spec.rb b/spec/bundler/install/yanked_spec.rb
index 7408c24327..5aeabd2f23 100644
--- a/spec/bundler/install/yanked_spec.rb
+++ b/spec/bundler/install/yanked_spec.rb
@@ -188,7 +188,7 @@ RSpec.context "when using gem before installing" do
bundle :list, raise_on_error: false
- expect(err).to include("Could not find rack-0.9.1 in cached gems or installed locally")
+ expect(err).to include("Could not find rack-0.9.1 in locally installed gems")
expect(err).to_not include("Your bundle is locked to rack (0.9.1) from")
expect(err).to_not include("If you haven't changed sources, that means the author of rack (0.9.1) has removed it.")
expect(err).to_not include("You'll need to update your bundle to a different version of rack (0.9.1) that hasn't been removed in order to install.")
@@ -197,7 +197,7 @@ RSpec.context "when using gem before installing" do
lockfile lockfile.gsub(/PLATFORMS\n #{lockfile_platforms}/m, "PLATFORMS\n #{lockfile_platforms("ruby")}")
bundle :list, raise_on_error: false
- expect(err).to include("Could not find rack-0.9.1 in cached gems or installed locally")
+ expect(err).to include("Could not find rack-0.9.1 in locally installed gems")
end
it "does not suggest the author has yanked the gem when using more than one gem, but shows all gems that couldn't be found in the source" do
@@ -224,7 +224,7 @@ RSpec.context "when using gem before installing" do
bundle :list, raise_on_error: false
- expect(err).to include("Could not find rack-0.9.1, rack_middleware-1.0 in cached gems or installed locally")
+ expect(err).to include("Could not find rack-0.9.1, rack_middleware-1.0 in locally installed gems")
expect(err).to include("Install missing gems with `bundle install`.")
expect(err).to_not include("Your bundle is locked to rack (0.9.1) from")
expect(err).to_not include("If you haven't changed sources, that means the author of rack (0.9.1) has removed it.")
diff --git a/spec/bundler/other/major_deprecation_spec.rb b/spec/bundler/other/major_deprecation_spec.rb
index 939b68a0bb..e7577d38b4 100644
--- a/spec/bundler/other/major_deprecation_spec.rb
+++ b/spec/bundler/other/major_deprecation_spec.rb
@@ -618,7 +618,12 @@ RSpec.describe "major deprecations" do
pending "fails with a helpful message", bundler: "3"
end
- describe "deprecating rubocop", :readline do
+ describe "deprecating rubocop" do
+ before do
+ global_config "BUNDLE_GEM__MIT" => "false", "BUNDLE_GEM__TEST" => "false", "BUNDLE_GEM__COC" => "false",
+ "BUNDLE_GEM__CI" => "false", "BUNDLE_GEM__CHANGELOG" => "false"
+ end
+
context "bundle gem --rubocop" do
before do
bundle "gem my_new_gem --rubocop", raise_on_error: false
diff --git a/spec/bundler/runtime/require_spec.rb b/spec/bundler/runtime/require_spec.rb
index 76271a5593..e630e902c9 100644
--- a/spec/bundler/runtime/require_spec.rb
+++ b/spec/bundler/runtime/require_spec.rb
@@ -430,6 +430,30 @@ RSpec.describe "Bundler.require" do
expect(out).to eq("WIN")
end
+
+ it "does not extract gemspecs from application cache packages" do
+ gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ bundle :cache
+
+ path = cached_gem("rack-1.0.0")
+
+ run <<-R
+ File.open("#{path}", "w") do |f|
+ f.write "broken package"
+ end
+ R
+
+ run <<-R
+ Bundler.require
+ puts "WIN"
+ R
+
+ expect(out).to eq("WIN")
+ end
end
RSpec.describe "Bundler.require with platform specific dependencies" do
diff --git a/spec/bundler/runtime/setup_spec.rb b/spec/bundler/runtime/setup_spec.rb
index 0344d24223..8b8988063c 100644
--- a/spec/bundler/runtime/setup_spec.rb
+++ b/spec/bundler/runtime/setup_spec.rb
@@ -767,6 +767,18 @@ end
expect(err).to be_empty
end
+ it "can require rubygems without warnings, when using a local cache" do
+ install_gemfile <<-G
+ source "#{file_uri_for(gem_repo1)}"
+ gem "rack"
+ G
+
+ bundle "package"
+ bundle %(exec ruby -w -e "require 'rubygems'")
+
+ expect(err).to be_empty
+ end
+
context "when the user has `MANPATH` set", :man do
before { ENV["MANPATH"] = "/foo#{File::PATH_SEPARATOR}" }
diff --git a/spec/bundler/support/builders.rb b/spec/bundler/support/builders.rb
index ab2dafb0b9..8f646b9358 100644
--- a/spec/bundler/support/builders.rb
+++ b/spec/bundler/support/builders.rb
@@ -518,7 +518,6 @@ module Spec
if options[:rubygems_version]
@spec.rubygems_version = options[:rubygems_version]
- def @spec.mark_version; end
def @spec.validate(*); end
end
diff --git a/spec/bundler/support/helpers.rb b/spec/bundler/support/helpers.rb
index 1ad9cc78ca..dbb8b8152b 100644
--- a/spec/bundler/support/helpers.rb
+++ b/spec/bundler/support/helpers.rb
@@ -226,12 +226,20 @@ module Spec
end
def config(config = nil, path = bundled_app(".bundle/config"))
- return Psych.load_file(path) unless config
+ current = File.exist?(path) ? Psych.load_file(path) : {}
+ return current unless config
+
+ current = {} if current.empty?
+
FileUtils.mkdir_p(File.dirname(path))
- File.open(path, "w") do |f|
- f.puts config.to_yaml
+
+ new_config = current.merge(config).compact
+
+ File.open(path, "w+") do |f|
+ f.puts new_config.to_yaml
end
- config
+
+ new_config
end
def global_config(config = nil)
diff --git a/spec/prism.mspec b/spec/prism.mspec
deleted file mode 100644
index c13b58b1cd..0000000000
--- a/spec/prism.mspec
+++ /dev/null
@@ -1,26 +0,0 @@
-# frozen_string_literal: true
-
-# This is turned off because when we run with --parser=prism we explicitly turn
-# off experimental warnings to make sure the output is consistent.
-MSpec.register(:exclude, "Warning.[] returns default values for categories :deprecated and :experimental")
-
-## Language
-MSpec.register(:exclude, "Hash literal raises a SyntaxError at parse time when Symbol key with invalid bytes")
-MSpec.register(:exclude, "Hash literal raises a SyntaxError at parse time when Symbol key with invalid bytes and 'key: value' syntax used")
-MSpec.register(:exclude, "Regexps with encoding modifiers supports /e (EUC encoding) with interpolation")
-MSpec.register(:exclude, "Regexps with encoding modifiers supports /e (EUC encoding) with interpolation /o")
-MSpec.register(:exclude, "Regexps with encoding modifiers preserves EUC-JP as /e encoding through interpolation")
-MSpec.register(:exclude, "Regexps with encoding modifiers supports /s (Windows_31J encoding) with interpolation")
-MSpec.register(:exclude, "Regexps with encoding modifiers supports /s (Windows_31J encoding) with interpolation and /o")
-MSpec.register(:exclude, "Regexps with encoding modifiers preserves Windows-31J as /s encoding through interpolation")
-MSpec.register(:exclude, "Regexps with encoding modifiers supports /u (UTF8 encoding) with interpolation")
-MSpec.register(:exclude, "Regexps with encoding modifiers supports /u (UTF8 encoding) with interpolation and /o")
-MSpec.register(:exclude, "Regexps with encoding modifiers preserves UTF-8 as /u encoding through interpolation")
-MSpec.register(:exclude, "A Symbol literal raises an SyntaxError at parse time when Symbol with invalid bytes")
-
-## Core
-MSpec.register(:exclude, "TracePoint#path equals \"(eval at __FILE__:__LINE__)\" inside an eval for :end event")
-
-## Library
-MSpec.register(:exclude, "Coverage.result returns the correct results when eval coverage is disabled")
-MSpec.register(:exclude, "Socket.gethostbyaddr using an IPv6 address with an explicit address family raises SocketError when the address is not supported by the family")
diff --git a/spec/ruby/core/binding/dup_spec.rb b/spec/ruby/core/binding/dup_spec.rb
index 55fac6e333..4eff66bd9a 100644
--- a/spec/ruby/core/binding/dup_spec.rb
+++ b/spec/ruby/core/binding/dup_spec.rb
@@ -10,4 +10,21 @@ describe "Binding#dup" do
bind.frozen?.should == true
bind.dup.frozen?.should == false
end
+
+ it "retains original binding variables but the list is distinct" do
+ bind1 = binding
+ eval "a = 1", bind1
+
+ bind2 = bind1.dup
+ eval("a = 2", bind2)
+ eval("a", bind1).should == 2
+ eval("a", bind2).should == 2
+
+ eval("b = 2", bind2)
+ -> { eval("b", bind1) }.should raise_error(NameError)
+ eval("b", bind2).should == 2
+
+ bind1.local_variables.sort.should == [:a, :bind1, :bind2]
+ bind2.local_variables.sort.should == [:a, :b, :bind1, :bind2]
+ end
end
diff --git a/spec/ruby/core/binding/irb_spec.rb b/spec/ruby/core/binding/irb_spec.rb
index 25521f0dd7..2607c7ef33 100644
--- a/spec/ruby/core/binding/irb_spec.rb
+++ b/spec/ruby/core/binding/irb_spec.rb
@@ -10,7 +10,7 @@ describe "Binding#irb" do
IO.popen([envs, *ruby_exe, irb_fixture, chdir: dir], "r+") do |pipe|
pipe.puts "a ** 2"
pipe.puts "exit"
- pipe.readlines.map(&:chomp)
+ pipe.readlines.map(&:chomp).reject(&:empty?)
end
end
diff --git a/spec/ruby/core/enumerator/next_values_spec.rb b/spec/ruby/core/enumerator/next_values_spec.rb
index 201b5d323f..2202700c58 100644
--- a/spec/ruby/core/enumerator/next_values_spec.rb
+++ b/spec/ruby/core/enumerator/next_values_spec.rb
@@ -11,6 +11,7 @@ describe "Enumerator#next_values" do
yield :e1, :e2, :e3
yield nil
yield
+ yield [:f1, :f2]
end
@e = o.to_enum
@@ -48,8 +49,13 @@ describe "Enumerator#next_values" do
@e.next_values.should == []
end
- it "raises StopIteration if called on a finished enumerator" do
+ it "returns an array of array if yield is called with an array" do
7.times { @e.next }
+ @e.next_values.should == [[:f1, :f2]]
+ end
+
+ it "raises StopIteration if called on a finished enumerator" do
+ 8.times { @e.next }
-> { @e.next_values }.should raise_error(StopIteration)
end
end
diff --git a/spec/ruby/core/enumerator/peek_values_spec.rb b/spec/ruby/core/enumerator/peek_values_spec.rb
index 7865546515..8b84fc8afc 100644
--- a/spec/ruby/core/enumerator/peek_values_spec.rb
+++ b/spec/ruby/core/enumerator/peek_values_spec.rb
@@ -11,6 +11,7 @@ describe "Enumerator#peek_values" do
yield :e1, :e2, :e3
yield nil
yield
+ yield [:f1, :f2]
end
@e = o.to_enum
@@ -50,8 +51,13 @@ describe "Enumerator#peek_values" do
@e.peek_values.should == []
end
- it "raises StopIteration if called on a finished enumerator" do
+ it "returns an array of array if yield is called with an array" do
7.times { @e.next }
+ @e.peek_values.should == [[:f1, :f2]]
+ end
+
+ it "raises StopIteration if called on a finished enumerator" do
+ 8.times { @e.next }
-> { @e.peek_values }.should raise_error(StopIteration)
end
end
diff --git a/spec/ruby/core/io/pread_spec.rb b/spec/ruby/core/io/pread_spec.rb
index 28afc80e5c..6d93b432c2 100644
--- a/spec/ruby/core/io/pread_spec.rb
+++ b/spec/ruby/core/io/pread_spec.rb
@@ -22,7 +22,7 @@ guard -> { platform_is_not :windows or ruby_version_is "3.3" } do
it "accepts a length, an offset, and an output buffer" do
buffer = +"foo"
- @file.pread(3, 4, buffer)
+ @file.pread(3, 4, buffer).should.equal?(buffer)
buffer.should == "567"
end
@@ -38,6 +38,13 @@ guard -> { platform_is_not :windows or ruby_version_is "3.3" } do
buffer.should == "12345"
end
+ it "preserves the encoding of the given buffer" do
+ buffer = ''.encode(Encoding::ISO_8859_1)
+ @file.pread(10, 0, buffer)
+
+ buffer.encoding.should == Encoding::ISO_8859_1
+ end
+
it "does not advance the file pointer" do
@file.pread(4, 0).should == "1234"
@file.read.should == "1234567890"
diff --git a/spec/ruby/core/io/read_spec.rb b/spec/ruby/core/io/read_spec.rb
index eb3652e692..8741d9f017 100644
--- a/spec/ruby/core/io/read_spec.rb
+++ b/spec/ruby/core/io/read_spec.rb
@@ -376,6 +376,21 @@ describe "IO#read" do
buf.should == @contents[0..4]
end
+ it "preserves the encoding of the given buffer" do
+ buffer = ''.encode(Encoding::ISO_8859_1)
+ @io.read(10, buffer)
+
+ buffer.encoding.should == Encoding::ISO_8859_1
+ end
+
+ # https://bugs.ruby-lang.org/issues/20416
+ it "does not preserve the encoding of the given buffer when max length is not provided" do
+ buffer = ''.encode(Encoding::ISO_8859_1)
+ @io.read(nil, buffer)
+
+ buffer.encoding.should_not == Encoding::ISO_8859_1
+ end
+
it "returns the given buffer" do
buf = +""
diff --git a/spec/ruby/core/io/readpartial_spec.rb b/spec/ruby/core/io/readpartial_spec.rb
index 0060beb545..0852f20b2d 100644
--- a/spec/ruby/core/io/readpartial_spec.rb
+++ b/spec/ruby/core/io/readpartial_spec.rb
@@ -62,7 +62,7 @@ describe "IO#readpartial" do
buffer = +"existing content"
@wr.write("hello world")
@wr.close
- @rd.readpartial(11, buffer)
+ @rd.readpartial(11, buffer).should.equal?(buffer)
buffer.should == "hello world"
end
@@ -106,6 +106,7 @@ describe "IO#readpartial" do
@wr.write("abc")
@wr.close
@rd.readpartial(10, buffer)
+
buffer.encoding.should == Encoding::ISO_8859_1
end
end
diff --git a/spec/ruby/core/io/sysread_spec.rb b/spec/ruby/core/io/sysread_spec.rb
index 003bb9eb94..8851214283 100644
--- a/spec/ruby/core/io/sysread_spec.rb
+++ b/spec/ruby/core/io/sysread_spec.rb
@@ -97,7 +97,7 @@ describe "IO#sysread on a file" do
it "discards the existing buffer content upon successful read" do
buffer = +"existing content"
- @file.sysread(11, buffer)
+ @file.sysread(11, buffer).should.equal?(buffer)
buffer.should == "01234567890"
end
@@ -107,6 +107,13 @@ describe "IO#sysread on a file" do
-> { @file.sysread(1, buffer) }.should raise_error(EOFError)
buffer.should be_empty
end
+
+ it "preserves the encoding of the given buffer" do
+ buffer = ''.encode(Encoding::ISO_8859_1)
+ string = @file.sysread(10, buffer)
+
+ buffer.encoding.should == Encoding::ISO_8859_1
+ end
end
describe "IO#sysread" do
diff --git a/spec/ruby/core/module/include_spec.rb b/spec/ruby/core/module/include_spec.rb
index c073bc31ca..78f6b41031 100644
--- a/spec/ruby/core/module/include_spec.rb
+++ b/spec/ruby/core/module/include_spec.rb
@@ -47,6 +47,34 @@ describe "Module#include" do
-> { ModuleSpecs::SubclassSpec.include(ModuleSpecs::Subclass.new) }.should_not raise_error(TypeError)
end
+ ruby_version_is ""..."3.2" do
+ it "raises ArgumentError when the argument is a refinement" do
+ refinement = nil
+
+ Module.new do
+ refine String do
+ refinement = self
+ end
+ end
+
+ -> { ModuleSpecs::Basic.include(refinement) }.should raise_error(ArgumentError, "refinement module is not allowed")
+ end
+ end
+
+ ruby_version_is "3.2" do
+ it "raises a TypeError when the argument is a refinement" do
+ refinement = nil
+
+ Module.new do
+ refine String do
+ refinement = self
+ end
+ end
+
+ -> { ModuleSpecs::Basic.include(refinement) }.should raise_error(TypeError, "Cannot include refinement")
+ end
+ end
+
it "imports constants to modules and classes" do
ModuleSpecs::A.constants.should include(:CONSTANT_A)
ModuleSpecs::B.constants.should include(:CONSTANT_A, :CONSTANT_B)
diff --git a/spec/ruby/core/module/prepend_spec.rb b/spec/ruby/core/module/prepend_spec.rb
index c90fa9700e..b40d12f0de 100644
--- a/spec/ruby/core/module/prepend_spec.rb
+++ b/spec/ruby/core/module/prepend_spec.rb
@@ -75,6 +75,26 @@ describe "Module#prepend" do
foo.call.should == 'm'
end
+ it "updates the optimized method when a prepended module is updated" do
+ out = ruby_exe(<<~RUBY)
+ module M; end
+ class Integer
+ prepend M
+ end
+ l = -> { 1 + 2 }
+ p l.call
+ M.module_eval do
+ def +(o)
+ $called = true
+ super(o)
+ end
+ end
+ p l.call
+ p $called
+ RUBY
+ out.should == "3\n3\ntrue\n"
+ end
+
it "updates the method when there is a base included method and the prepended module overrides it" do
base_module = Module.new do
def foo
@@ -415,6 +435,34 @@ describe "Module#prepend" do
-> { ModuleSpecs::SubclassSpec.prepend(ModuleSpecs::Subclass.new) }.should_not raise_error(TypeError)
end
+ ruby_version_is ""..."3.2" do
+ it "raises ArgumentError when the argument is a refinement" do
+ refinement = nil
+
+ Module.new do
+ refine String do
+ refinement = self
+ end
+ end
+
+ -> { ModuleSpecs::Basic.prepend(refinement) }.should raise_error(ArgumentError, "refinement module is not allowed")
+ end
+ end
+
+ ruby_version_is "3.2" do
+ it "raises a TypeError when the argument is a refinement" do
+ refinement = nil
+
+ Module.new do
+ refine String do
+ refinement = self
+ end
+ end
+
+ -> { ModuleSpecs::Basic.prepend(refinement) }.should raise_error(TypeError, "Cannot prepend refinement")
+ end
+ end
+
it "imports constants" do
m1 = Module.new
m1::MY_CONSTANT = 1
diff --git a/spec/ruby/core/string/index_spec.rb b/spec/ruby/core/string/index_spec.rb
index be79708045..835263a2cd 100644
--- a/spec/ruby/core/string/index_spec.rb
+++ b/spec/ruby/core/string/index_spec.rb
@@ -231,6 +231,17 @@ describe "String#index with Regexp" do
$~.should == nil
end
+ ruby_bug "#20421", ""..."3.3" do
+ it "always clear $~" do
+ "a".index(/a/)
+ $~.should_not == nil
+
+ string = "blablabla"
+ string.index(/bla/, string.length + 1)
+ $~.should == nil
+ end
+ end
+
it "starts the search at the given offset" do
"blablabla".index(/.{0}/, 5).should == 5
"blablabla".index(/.{1}/, 5).should == 5
diff --git a/spec/ruby/core/warning/element_reference_spec.rb b/spec/ruby/core/warning/element_reference_spec.rb
index 8cb4018c20..c0ed37ef13 100644
--- a/spec/ruby/core/warning/element_reference_spec.rb
+++ b/spec/ruby/core/warning/element_reference_spec.rb
@@ -2,6 +2,10 @@ require_relative '../../spec_helper'
describe "Warning.[]" do
it "returns default values for categories :deprecated and :experimental" do
+ # If any warning options were set on the Ruby that will be executed, then
+ # it's possible this test will fail. In this case we will skip this test.
+ skip if ruby_exe.any? { |opt| opt.start_with?("-W") }
+
ruby_exe('p [Warning[:deprecated], Warning[:experimental]]').chomp.should == "[false, true]"
ruby_exe('p [Warning[:deprecated], Warning[:experimental]]', options: "-w").chomp.should == "[true, true]"
end
diff --git a/spec/ruby/core/warning/performance_warning_spec.rb b/spec/ruby/core/warning/performance_warning_spec.rb
new file mode 100644
index 0000000000..ab0badcd3d
--- /dev/null
+++ b/spec/ruby/core/warning/performance_warning_spec.rb
@@ -0,0 +1,28 @@
+require_relative '../../spec_helper'
+
+
+describe "Performance warnings" do
+ guard -> { ruby_version_is("3.4") || RUBY_ENGINE == "truffleruby" } do
+ # Optimising Integer, Float or Symbol methods is kind of implementation detail
+ # but multiple implementations do so. So it seems reasonable to have a test case
+ # for at least one such common method.
+ # See https://bugs.ruby-lang.org/issues/20429
+ context "when redefined optimised methods" do
+ it "emits performance warning for redefining Integer#+" do
+ code = <<~CODE
+ Warning[:performance] = true
+
+ class Integer
+ ORIG_METHOD = instance_method(:+)
+
+ def +(...)
+ ORIG_METHOD.bind(self).call(...)
+ end
+ end
+ CODE
+
+ ruby_exe(code, args: "2>&1").should.include?("warning: Redefining 'Integer#+' disables interpreter and JIT optimizations")
+ end
+ end
+ end
+end
diff --git a/spec/ruby/language/break_spec.rb b/spec/ruby/language/break_spec.rb
index e725e77e80..7e5b6fb328 100644
--- a/spec/ruby/language/break_spec.rb
+++ b/spec/ruby/language/break_spec.rb
@@ -252,6 +252,25 @@ describe "Break inside a while loop" do
end
end
+describe "The break statement in a method" do
+ it "is invalid and raises a SyntaxError" do
+ -> {
+ eval("def m; break; end")
+ }.should raise_error(SyntaxError)
+ end
+end
+
+describe "The break statement in a module literal" do
+ it "is invalid and raises a SyntaxError" do
+ code = <<~RUBY
+ module BreakSpecs:ModuleWithBreak
+ break
+ end
+ RUBY
+
+ -> { eval(code) }.should raise_error(SyntaxError)
+ end
+end
# TODO: Rewrite all the specs from here to the end of the file in the style
# above.
diff --git a/spec/ruby/language/case_spec.rb b/spec/ruby/language/case_spec.rb
index 3262f09dd5..d289eca037 100644
--- a/spec/ruby/language/case_spec.rb
+++ b/spec/ruby/language/case_spec.rb
@@ -416,17 +416,34 @@ describe "The 'case'-construct" do
self.test(true).should == true
end
- it "warns if there are identical when clauses" do
- -> {
- eval <<~RUBY
- case 1
- when 2
- :foo
- when 2
- :bar
- end
- RUBY
- }.should complain(/warning: duplicated .when' clause with line \d+ is ignored/, verbose: true)
+ ruby_version_is ""..."3.4" do
+ it "warns if there are identical when clauses" do
+ -> {
+ eval <<~RUBY
+ case 1
+ when 2
+ :foo
+ when 2
+ :bar
+ end
+ RUBY
+ }.should complain(/warning: duplicated .when' clause with line \d+ is ignored/, verbose: true)
+ end
+ end
+
+ ruby_version_is "3.4" do
+ it "warns if there are identical when clauses" do
+ -> {
+ eval <<~RUBY
+ case 1
+ when 2
+ :foo
+ when 2
+ :bar
+ end
+ RUBY
+ }.should complain(/warning: 'when' clause on line \d+ duplicates 'when' clause on line \d+ and is ignored/, verbose: true)
+ end
end
end
diff --git a/spec/ruby/language/execution_spec.rb b/spec/ruby/language/execution_spec.rb
index ef1de38899..51bcde62e8 100644
--- a/spec/ruby/language/execution_spec.rb
+++ b/spec/ruby/language/execution_spec.rb
@@ -38,7 +38,7 @@ describe "``" do
2.times do
runner.instance_exec do
- `test #{:command}`
+ `test #{:command}` # rubocop:disable Lint/LiteralInInterpolation
end
end
@@ -84,7 +84,7 @@ describe "%x" do
2.times do
runner.instance_exec do
- %x{test #{:command}}
+ %x{test #{:command}} # rubocop:disable Lint/LiteralInInterpolation
end
end
diff --git a/spec/ruby/language/hash_spec.rb b/spec/ruby/language/hash_spec.rb
index a7631fb0d6..068ac0f39c 100644
--- a/spec/ruby/language/hash_spec.rb
+++ b/spec/ruby/language/hash_spec.rb
@@ -86,6 +86,30 @@ describe "Hash literal" do
-> { eval("{:a ==> 1}") }.should raise_error(SyntaxError)
end
+ it "recognizes '!' at the end of the key" do
+ eval("{:a! =>1}").should == {:"a!" => 1}
+ eval("{:a! => 1}").should == {:"a!" => 1}
+
+ eval("{a!:1}").should == {:"a!" => 1}
+ eval("{a!: 1}").should == {:"a!" => 1}
+ end
+
+ it "raises a SyntaxError if there is no space between `!` and `=>`" do
+ -> { eval("{:a!=> 1}") }.should raise_error(SyntaxError)
+ end
+
+ it "recognizes '?' at the end of the key" do
+ eval("{:a? =>1}").should == {:"a?" => 1}
+ eval("{:a? => 1}").should == {:"a?" => 1}
+
+ eval("{a?:1}").should == {:"a?" => 1}
+ eval("{a?: 1}").should == {:"a?" => 1}
+ end
+
+ it "raises a SyntaxError if there is no space between `?` and `=>`" do
+ -> { eval("{:a?=> 1}") }.should raise_error(SyntaxError)
+ end
+
it "constructs a new hash with the given elements" do
{foo: 123}.should == {foo: 123}
h = {rbx: :cool, specs: 'fail_sometimes'}
@@ -271,6 +295,14 @@ describe "The ** operator" do
a.new.foo(1).should == {bar: "baz", val: 1}
end
+
+ it "raises a SyntaxError when the hash key ends with `!`" do
+ -> { eval("{a!:}") }.should raise_error(SyntaxError, /identifier a! is not valid to get/)
+ end
+
+ it "raises a SyntaxError when the hash key ends with `?`" do
+ -> { eval("{a?:}") }.should raise_error(SyntaxError, /identifier a\? is not valid to get/)
+ end
end
end
end
diff --git a/spec/ruby/language/keyword_arguments_spec.rb b/spec/ruby/language/keyword_arguments_spec.rb
index ffb5b1fab0..8668799d26 100644
--- a/spec/ruby/language/keyword_arguments_spec.rb
+++ b/spec/ruby/language/keyword_arguments_spec.rb
@@ -395,4 +395,32 @@ describe "Keyword arguments" do
end
end
end
+
+ context "in define_method(name, &proc)" do
+ # This tests that a free-standing proc used in define_method and converted to ruby2_keywords adopts that logic.
+ # See jruby/jruby#8119 for a case where aggressive JIT optimization broke later ruby2_keywords changes.
+ it "works with ruby2_keywords" do
+ m = Class.new do
+ def bar(a, foo: nil)
+ [a, foo]
+ end
+
+ # define_method and ruby2_keywords using send to avoid peephole optimizations
+ def self.setup
+ pr = make_proc
+ send :define_method, :foo, &pr
+ send :ruby2_keywords, :foo
+ end
+
+ # create proc in isolated method to force jit compilation on some implementations
+ def self.make_proc
+ proc { |a, *args| bar(a, *args) }
+ end
+ end
+
+ m.setup
+
+ m.new.foo(1, foo:2).should == [1, 2]
+ end
+ end
end
diff --git a/spec/ruby/language/regexp/back-references_spec.rb b/spec/ruby/language/regexp/back-references_spec.rb
index 26750c20c5..627c8daace 100644
--- a/spec/ruby/language/regexp/back-references_spec.rb
+++ b/spec/ruby/language/regexp/back-references_spec.rb
@@ -22,6 +22,15 @@ describe "Regexps with back-references" do
$10.should == "0"
end
+ it "returns nil for numbered variable with too large index" do
+ -> {
+ eval(<<~CODE).should == nil
+ "a" =~ /(.)/
+ eval('$4294967296')
+ CODE
+ }.should complain(/warning: ('|`)\$4294967296' is too big for a number variable, always nil/)
+ end
+
it "will not clobber capture variables across threads" do
cap1, cap2, cap3 = nil
"foo" =~ /(o+)/
diff --git a/spec/ruby/language/retry_spec.rb b/spec/ruby/language/retry_spec.rb
index ee5377946f..669d5f0ff5 100644
--- a/spec/ruby/language/retry_spec.rb
+++ b/spec/ruby/language/retry_spec.rb
@@ -31,8 +31,11 @@ describe "The retry statement" do
results.should == [1, 2, 3, 1, 2, 4, 5, 6, 4, 5]
end
- it "raises a SyntaxError when used outside of a begin statement" do
+ it "raises a SyntaxError when used outside of a rescue statement" do
-> { eval 'retry' }.should raise_error(SyntaxError)
+ -> { eval 'begin; retry; end' }.should raise_error(SyntaxError)
+ -> { eval 'def m; retry; end' }.should raise_error(SyntaxError)
+ -> { eval 'module RetrySpecs; retry; end' }.should raise_error(SyntaxError)
end
end
diff --git a/spec/ruby/language/yield_spec.rb b/spec/ruby/language/yield_spec.rb
index 5283517636..e125cf8e73 100644
--- a/spec/ruby/language/yield_spec.rb
+++ b/spec/ruby/language/yield_spec.rb
@@ -206,3 +206,15 @@ describe "Using yield in non-lambda block" do
-> { eval(code) }.should raise_error(SyntaxError, /Invalid yield/)
end
end
+
+describe "Using yield in a module literal" do
+ it 'raises a SyntaxError' do
+ code = <<~RUBY
+ module YieldSpecs::ModuleWithYield
+ yield
+ end
+ RUBY
+
+ -> { eval(code) }.should raise_error(SyntaxError, /Invalid yield/)
+ end
+end
diff --git a/spec/ruby/library/time/to_date_spec.rb b/spec/ruby/library/date/time/to_date_spec.rb
index baeafe0847..f9132da289 100644
--- a/spec/ruby/library/time/to_date_spec.rb
+++ b/spec/ruby/library/date/time/to_date_spec.rb
@@ -1,5 +1,5 @@
-require_relative '../../spec_helper'
+require_relative '../../../spec_helper'
require 'time'
describe "Time#to_date" do
diff --git a/spec/ruby/library/time/to_datetime_spec.rb b/spec/ruby/library/datetime/time/to_datetime_spec.rb
index 9c44f38e5c..1125dbe851 100644
--- a/spec/ruby/library/time/to_datetime_spec.rb
+++ b/spec/ruby/library/datetime/time/to_datetime_spec.rb
@@ -1,4 +1,4 @@
-require_relative '../../spec_helper'
+require_relative '../../../spec_helper'
require 'time'
require 'date'
date_version = defined?(Date::VERSION) ? Date::VERSION : '3.1.0'
diff --git a/spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb b/spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb
index 17c846054d..df42c116fb 100644
--- a/spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb
+++ b/spec/ruby/library/socket/basicsocket/recv_nonblock_spec.rb
@@ -52,9 +52,19 @@ describe "Socket::BasicSocket#recv_nonblock" do
@s2.send("data", 0, @s1.getsockname)
IO.select([@s1], nil, nil, 2)
- buf = +"foo"
- @s1.recv_nonblock(5, 0, buf)
- buf.should == "data"
+ buffer = +"foo"
+ @s1.recv_nonblock(5, 0, buffer).should.equal?(buffer)
+ buffer.should == "data"
+ end
+
+ it "preserves the encoding of the given buffer" do
+ @s1.bind(Socket.pack_sockaddr_in(0, ip_address))
+ @s2.send("data", 0, @s1.getsockname)
+ IO.select([@s1], nil, nil, 2)
+
+ buffer = ''.encode(Encoding::ISO_8859_1)
+ @s1.recv_nonblock(5, 0, buffer)
+ buffer.encoding.should == Encoding::ISO_8859_1
end
it "does not block if there's no data available" do
diff --git a/spec/ruby/library/socket/basicsocket/recv_spec.rb b/spec/ruby/library/socket/basicsocket/recv_spec.rb
index 9fe8c52f9a..e82a357d3d 100644
--- a/spec/ruby/library/socket/basicsocket/recv_spec.rb
+++ b/spec/ruby/library/socket/basicsocket/recv_spec.rb
@@ -100,13 +100,29 @@ describe "BasicSocket#recv" do
socket.write("data")
client = @server.accept
- buf = +"foo"
+ buffer = +"foo"
begin
- client.recv(4, 0, buf)
+ client.recv(4, 0, buffer).should.equal?(buffer)
ensure
client.close
end
- buf.should == "data"
+ buffer.should == "data"
+
+ socket.close
+ end
+
+ it "preserves the encoding of the given buffer" do
+ socket = TCPSocket.new('127.0.0.1', @port)
+ socket.write("data")
+
+ client = @server.accept
+ buffer = ''.encode(Encoding::ISO_8859_1)
+ begin
+ client.recv(4, 0, buffer)
+ ensure
+ client.close
+ end
+ buffer.encoding.should == Encoding::ISO_8859_1
socket.close
end
diff --git a/spec/ruby/library/socket/socket/recvfrom_nonblock_spec.rb b/spec/ruby/library/socket/socket/recvfrom_nonblock_spec.rb
index 94f58ac49f..5596f91bb8 100644
--- a/spec/ruby/library/socket/socket/recvfrom_nonblock_spec.rb
+++ b/spec/ruby/library/socket/socket/recvfrom_nonblock_spec.rb
@@ -52,6 +52,27 @@ describe 'Socket#recvfrom_nonblock' do
end
end
+ it "allows an output buffer as third argument" do
+ @client.write('hello')
+
+ IO.select([@server])
+ buffer = +''
+ message, = @server.recvfrom_nonblock(5, 0, buffer)
+
+ message.should.equal?(buffer)
+ buffer.should == 'hello'
+ end
+
+ it "preserves the encoding of the given buffer" do
+ @client.write('hello')
+
+ IO.select([@server])
+ buffer = ''.encode(Encoding::ISO_8859_1)
+ @server.recvfrom_nonblock(5, 0, buffer)
+
+ buffer.encoding.should == Encoding::ISO_8859_1
+ end
+
describe 'the returned data' do
it 'is the same as the sent data' do
5.times do
diff --git a/spec/ruby/library/socket/udpsocket/recvfrom_nonblock_spec.rb b/spec/ruby/library/socket/udpsocket/recvfrom_nonblock_spec.rb
index 650a061221..b804099589 100644
--- a/spec/ruby/library/socket/udpsocket/recvfrom_nonblock_spec.rb
+++ b/spec/ruby/library/socket/udpsocket/recvfrom_nonblock_spec.rb
@@ -58,6 +58,15 @@ describe 'UDPSocket#recvfrom_nonblock' do
buffer.should == 'h'
end
+ it "preserves the encoding of the given buffer" do
+ buffer = ''.encode(Encoding::ISO_8859_1)
+ IO.select([@server])
+ message, = @server.recvfrom_nonblock(1, 0, buffer)
+
+ message.should.equal?(buffer)
+ buffer.encoding.should == Encoding::ISO_8859_1
+ end
+
describe 'the returned Array' do
before do
IO.select([@server])
diff --git a/spec/ruby/library/socket/unixsocket/recvfrom_spec.rb b/spec/ruby/library/socket/unixsocket/recvfrom_spec.rb
index fedf74bb2f..d849fdc302 100644
--- a/spec/ruby/library/socket/unixsocket/recvfrom_spec.rb
+++ b/spec/ruby/library/socket/unixsocket/recvfrom_spec.rb
@@ -31,6 +31,29 @@ with_feature :unix_socket do
sock.close
end
+ it "allows an output buffer as third argument" do
+ buffer = +''
+
+ @client.send("foobar", 0)
+ sock = @server.accept
+ message, = sock.recvfrom(6, 0, buffer)
+ sock.close
+
+ message.should.equal?(buffer)
+ buffer.should == "foobar"
+ end
+
+ it "preserves the encoding of the given buffer" do
+ buffer = ''.encode(Encoding::ISO_8859_1)
+
+ @client.send("foobar", 0)
+ sock = @server.accept
+ sock.recvfrom(6, 0, buffer)
+ sock.close
+
+ buffer.encoding.should == Encoding::ISO_8859_1
+ end
+
it "uses different message options" do
@client.send("foobar", Socket::MSG_PEEK)
sock = @server.accept
diff --git a/spec/ruby/library/stringio/shared/read.rb b/spec/ruby/library/stringio/shared/read.rb
index e3840786d9..8ef6ec2734 100644
--- a/spec/ruby/library/stringio/shared/read.rb
+++ b/spec/ruby/library/stringio/shared/read.rb
@@ -11,10 +11,28 @@ describe :stringio_read, shared: true do
end
it "reads length bytes and writes them to the buffer String" do
- @io.send(@method, 7, buffer = +"")
+ @io.send(@method, 7, buffer = +"").should.equal?(buffer)
buffer.should == "example"
end
+ ruby_version_is ""..."3.4" do
+ it "does not preserve the encoding of the given buffer" do
+ buffer = ''.encode(Encoding::ISO_8859_1)
+ @io.send(@method, 7, buffer)
+
+ buffer.encoding.should_not == Encoding::ISO_8859_1
+ end
+ end
+
+ ruby_version_is "3.4" do
+ it "preserves the encoding of the given buffer" do
+ buffer = ''.encode(Encoding::ISO_8859_1)
+ @io.send(@method, 7, buffer)
+
+ buffer.encoding.should == Encoding::ISO_8859_1
+ end
+ end
+
it "tries to convert the passed buffer Object to a String using #to_str" do
obj = mock("to_str")
obj.should_receive(:to_str).and_return(buffer = +"")
diff --git a/spec/ruby/optional/capi/class_spec.rb b/spec/ruby/optional/capi/class_spec.rb
index d0a9913570..a231245ebe 100644
--- a/spec/ruby/optional/capi/class_spec.rb
+++ b/spec/ruby/optional/capi/class_spec.rb
@@ -487,4 +487,16 @@ describe "C-API Class function" do
@s.rb_class_real(0).should == 0
end
end
+
+ describe "rb_class_get_superclass" do
+ it "returns parent class for a provided class" do
+ a = Class.new
+ @s.rb_class_get_superclass(Class.new(a)).should == a
+ end
+
+ it "returns false when there is no parent class" do
+ @s.rb_class_get_superclass(BasicObject).should == false
+ @s.rb_class_get_superclass(Module.new).should == false
+ end
+ end
end
diff --git a/spec/ruby/optional/capi/ext/class_spec.c b/spec/ruby/optional/capi/ext/class_spec.c
index f376534924..c13f02ecf2 100644
--- a/spec/ruby/optional/capi/ext/class_spec.c
+++ b/spec/ruby/optional/capi/ext/class_spec.c
@@ -79,6 +79,10 @@ static VALUE class_spec_rb_class_real(VALUE self, VALUE object) {
}
}
+static VALUE class_spec_rb_class_get_superclass(VALUE self, VALUE klass) {
+ return rb_class_get_superclass(klass);
+}
+
static VALUE class_spec_rb_class_superclass(VALUE self, VALUE klass) {
return rb_class_superclass(klass);
}
@@ -160,6 +164,7 @@ void Init_class_spec(void) {
rb_define_method(cls, "rb_class_new_instance_kw", class_spec_rb_class_new_instance_kw, 2);
#endif
rb_define_method(cls, "rb_class_real", class_spec_rb_class_real, 1);
+ rb_define_method(cls, "rb_class_get_superclass", class_spec_rb_class_get_superclass, 1);
rb_define_method(cls, "rb_class_superclass", class_spec_rb_class_superclass, 1);
rb_define_method(cls, "rb_cvar_defined", class_spec_cvar_defined, 2);
rb_define_method(cls, "rb_cvar_get", class_spec_cvar_get, 2);
diff --git a/spec/ruby/optional/capi/ext/gc_spec.c b/spec/ruby/optional/capi/ext/gc_spec.c
index 1392bc6ee6..2637ad27ac 100644
--- a/spec/ruby/optional/capi/ext/gc_spec.c
+++ b/spec/ruby/optional/capi/ext/gc_spec.c
@@ -16,6 +16,8 @@ VALUE registered_after_rb_global_variable_bignum;
VALUE registered_after_rb_global_variable_float;
VALUE rb_gc_register_address_outside_init;
+VALUE rb_gc_register_mark_object_not_referenced_float;
+
static VALUE registered_tagged_address(VALUE self) {
return registered_tagged_value;
}
@@ -90,6 +92,10 @@ static VALUE gc_spec_rb_gc_register_mark_object(VALUE self, VALUE obj) {
return Qnil;
}
+static VALUE gc_spec_rb_gc_register_mark_object_not_referenced_float(VALUE self) {
+ return rb_gc_register_mark_object_not_referenced_float;
+}
+
void Init_gc_spec(void) {
VALUE cls = rb_define_class("CApiGCSpecs", rb_cObject);
@@ -115,6 +121,9 @@ void Init_gc_spec(void) {
registered_after_rb_global_variable_float = DBL2NUM(6.28);
rb_global_variable(&registered_after_rb_global_variable_float);
+ rb_gc_register_mark_object_not_referenced_float = DBL2NUM(1.61);
+ rb_gc_register_mark_object(rb_gc_register_mark_object_not_referenced_float);
+
rb_define_method(cls, "registered_tagged_address", registered_tagged_address, 0);
rb_define_method(cls, "registered_reference_address", registered_reference_address, 0);
rb_define_method(cls, "registered_before_rb_gc_register_address", get_registered_before_rb_gc_register_address, 0);
@@ -131,6 +140,7 @@ void Init_gc_spec(void) {
rb_define_method(cls, "rb_gc", gc_spec_rb_gc, 0);
rb_define_method(cls, "rb_gc_adjust_memory_usage", gc_spec_rb_gc_adjust_memory_usage, 1);
rb_define_method(cls, "rb_gc_register_mark_object", gc_spec_rb_gc_register_mark_object, 1);
+ rb_define_method(cls, "rb_gc_register_mark_object_not_referenced_float", gc_spec_rb_gc_register_mark_object_not_referenced_float, 0);
rb_define_method(cls, "rb_gc_latest_gc_info", gc_spec_rb_gc_latest_gc_info, 1);
}
diff --git a/spec/ruby/optional/capi/ext/io_spec.c b/spec/ruby/optional/capi/ext/io_spec.c
index bcd3940e34..1a73331386 100644
--- a/spec/ruby/optional/capi/ext/io_spec.c
+++ b/spec/ruby/optional/capi/ext/io_spec.c
@@ -157,7 +157,7 @@ VALUE io_spec_rb_io_wait_readable(VALUE self, VALUE io, VALUE read_p) {
return ret ? Qtrue : Qfalse;
#else
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
#endif
}
@@ -174,6 +174,10 @@ VALUE io_spec_rb_io_maybe_wait_writable(VALUE self, VALUE error, VALUE io, VALUE
#endif
#ifdef RUBY_VERSION_IS_3_1
+#ifdef SET_NON_BLOCKING_FAILS_ALWAYS
+NORETURN(VALUE io_spec_rb_io_maybe_wait_readable(VALUE self, VALUE error, VALUE io, VALUE timeout, VALUE read_p));
+#endif
+
VALUE io_spec_rb_io_maybe_wait_readable(VALUE self, VALUE error, VALUE io, VALUE timeout, VALUE read_p) {
int fd = io_spec_get_fd(io);
#ifndef SET_NON_BLOCKING_FAILS_ALWAYS
@@ -209,7 +213,7 @@ VALUE io_spec_rb_io_maybe_wait_readable(VALUE self, VALUE error, VALUE io, VALUE
return INT2NUM(ret);
#else
- UNREACHABLE;
+ UNREACHABLE_RETURN(Qnil);
#endif
}
#endif
diff --git a/spec/ruby/optional/capi/ext/object_spec.c b/spec/ruby/optional/capi/ext/object_spec.c
index 8aa98cc5ce..aa60662e1e 100644
--- a/spec/ruby/optional/capi/ext/object_spec.c
+++ b/spec/ruby/optional/capi/ext/object_spec.c
@@ -390,22 +390,22 @@ static VALUE speced_allocator(VALUE klass) {
return instance;
}
-static VALUE define_alloc_func(VALUE self, VALUE klass) {
+static VALUE object_spec_rb_define_alloc_func(VALUE self, VALUE klass) {
rb_define_alloc_func(klass, speced_allocator);
return Qnil;
}
-static VALUE undef_alloc_func(VALUE self, VALUE klass) {
+static VALUE object_spec_rb_undef_alloc_func(VALUE self, VALUE klass) {
rb_undef_alloc_func(klass);
return Qnil;
}
-static VALUE speced_allocator_p(VALUE self, VALUE klass) {
+static VALUE object_spec_speced_allocator_p(VALUE self, VALUE klass) {
rb_alloc_func_t allocator = rb_get_alloc_func(klass);
return (allocator == speced_allocator) ? Qtrue : Qfalse;
}
-static VALUE custom_alloc_func_p(VALUE self, VALUE klass) {
+static VALUE object_spec_custom_alloc_func_p(VALUE self, VALUE klass) {
rb_alloc_func_t allocator = rb_get_alloc_func(klass);
return allocator ? Qtrue : Qfalse;
}
@@ -485,10 +485,10 @@ void Init_object_spec(void) {
rb_define_method(cls, "rb_ivar_defined", object_spec_rb_ivar_defined, 2);
rb_define_method(cls, "rb_copy_generic_ivar", object_spec_rb_copy_generic_ivar, 2);
rb_define_method(cls, "rb_free_generic_ivar", object_spec_rb_free_generic_ivar, 1);
- rb_define_method(cls, "rb_define_alloc_func", define_alloc_func, 1);
- rb_define_method(cls, "rb_undef_alloc_func", undef_alloc_func, 1);
- rb_define_method(cls, "speced_allocator?", speced_allocator_p, 1);
- rb_define_method(cls, "custom_alloc_func?", custom_alloc_func_p, 1);
+ rb_define_method(cls, "rb_define_alloc_func", object_spec_rb_define_alloc_func, 1);
+ rb_define_method(cls, "rb_undef_alloc_func", object_spec_rb_undef_alloc_func, 1);
+ rb_define_method(cls, "speced_allocator?", object_spec_speced_allocator_p, 1);
+ rb_define_method(cls, "custom_alloc_func?", object_spec_custom_alloc_func_p, 1);
rb_define_method(cls, "not_implemented_method", rb_f_notimplement, -1);
rb_define_method(cls, "rb_ivar_foreach", object_spec_rb_ivar_foreach, 1);
}
diff --git a/spec/ruby/optional/capi/gc_spec.rb b/spec/ruby/optional/capi/gc_spec.rb
index aaced56483..d9661328ab 100644
--- a/spec/ruby/optional/capi/gc_spec.rb
+++ b/spec/ruby/optional/capi/gc_spec.rb
@@ -108,6 +108,10 @@ describe "CApiGCSpecs" do
it "can be called with an object" do
@f.rb_gc_register_mark_object(Object.new).should be_nil
end
+
+ it "keeps the value alive even if the value is not referenced by any Ruby object" do
+ @f.rb_gc_register_mark_object_not_referenced_float.should == 1.61
+ end
end
describe "rb_gc_latest_gc_info" do
diff --git a/spec/ruby/shared/kernel/at_exit.rb b/spec/ruby/shared/kernel/at_exit.rb
index 16d41cb01c..29db79bb39 100644
--- a/spec/ruby/shared/kernel/at_exit.rb
+++ b/spec/ruby/shared/kernel/at_exit.rb
@@ -30,6 +30,12 @@ describe :kernel_at_exit, shared: true do
result.lines.should.include?("The exception matches: true (message=foo)\n")
end
+ it "gives access to an exception raised in a previous handler" do
+ code = "#{@method} { print '$!.message = ' + $!.message }; #{@method} { raise 'foo' }"
+ result = ruby_exe(code, args: "2>&1", exit_status: 1)
+ result.lines.should.include?("$!.message = foo")
+ end
+
it "both exceptions in a handler and in the main script are printed" do
code = "#{@method} { raise 'at_exit_error' }; raise 'main_script_error'"
result = ruby_exe(code, args: "2>&1", exit_status: 1)