summaryrefslogtreecommitdiff
path: root/spec/bundler/bundler
diff options
context:
space:
mode:
Diffstat (limited to 'spec/bundler/bundler')
-rw-r--r--spec/bundler/bundler/compact_index_client/parser_spec.rb259
-rw-r--r--spec/bundler/bundler/compact_index_client/updater_spec.rb18
-rw-r--r--spec/bundler/bundler/fetcher/compact_index_spec.rb11
-rw-r--r--spec/bundler/bundler/installer/gem_installer_spec.rb6
-rw-r--r--spec/bundler/bundler/settings_spec.rb14
-rw-r--r--spec/bundler/bundler/source/git/git_proxy_spec.rb14
6 files changed, 292 insertions, 30 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..45a08fd9ff
--- /dev/null
+++ b/spec/bundler/bundler/compact_index_client/parser_spec.rb
@@ -0,0 +1,259 @@
+# 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.dup }
+ created_at: 2024-05-01T00:00:04Z
+ ---
+ 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.dup }
+ ---
+ 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 true when versions has only one gem" do
+ compact_index.versions = +"a 1.0.0 aaa1\n"
+ expect(parser).to be_available
+ end
+
+ it "returns true when versions has a gem and a header" do
+ compact_index.versions = +"---\na 1.0.0 aaa1\n"
+ expect(parser).to be_available
+ end
+
+ it "returns true when versions has a gem and a header with header data" do
+ compact_index.versions = +"created_at: 2024-05-01T00:00:04Z\n---\na 1.0.0 aaa1\n"
+ expect(parser).to be_available
+ end
+
+ it "returns false when versions has only the header" do
+ compact_index.versions = +"---\n"
+ expect(parser).not_to be_available
+ end
+
+ it "returns false when versions has only the header with header data" do
+ compact_index.versions = +"created_at: 2024-05-01T00:00:04Z\n---\n"
+ expect(parser).not_to be_available
+ end
+
+ it "returns false when versions index is not available" do
+ compact_index.versions = nil
+ expect(parser).not_to be_available
+ end
+
+ it "returns false when versions is empty" do
+ compact_index.versions = +""
+ expect(parser).not_to be_available
+ end
+
+ it "returns false when versions ends improperly without a newline" do
+ compact_index.versions = "a 1.0.0 aaa1"
+ 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..aa536673d9 100644
--- a/spec/bundler/bundler/fetcher/compact_index_spec.rb
+++ b/spec/bundler/bundler/fetcher/compact_index_spec.rb
@@ -4,14 +4,18 @@
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) }
+ let(:compact_index_client) { double(:compact_index_client, available?: true, info: [["lskdjf", "1", nil, [], []]]) }
before do
+ allow(response).to receive(:is_a?).with(Gem::Net::HTTPNotModified).and_return(true)
allow(compact_index).to receive(:log_specs) {}
+ allow(compact_index).to receive(:compact_index_client).and_return(compact_index_client)
end
describe "#specs_for_names" do
@@ -32,11 +36,6 @@ RSpec.describe Bundler::Fetcher::CompactIndex do
end
describe "#available?" do
- before do
- allow(compact_index).to receive(:compact_index_client).
- and_return(double(:compact_index_client, update_and_parse_checksums!: true))
- end
-
it "returns true" do
expect(compact_index).to be_available
end
diff --git a/spec/bundler/bundler/installer/gem_installer_spec.rb b/spec/bundler/bundler/installer/gem_installer_spec.rb
index 4b6a07f344..ea506c36c8 100644
--- a/spec/bundler/bundler/installer/gem_installer_spec.rb
+++ b/spec/bundler/bundler/installer/gem_installer_spec.rb
@@ -14,7 +14,7 @@ RSpec.describe Bundler::GemInstaller do
it "invokes install method with empty build_args" do
allow(spec_source).to receive(:install).with(
spec,
- { force: false, ensure_builtin_gems_cached: false, build_args: [], previous_spec: nil }
+ { force: false, build_args: [], previous_spec: nil }
)
subject.install_from_spec
end
@@ -28,7 +28,7 @@ RSpec.describe Bundler::GemInstaller do
allow(Bundler.settings).to receive(:[]).with("build.dummy").and_return("--with-dummy-config=dummy")
expect(spec_source).to receive(:install).with(
spec,
- { force: false, ensure_builtin_gems_cached: false, build_args: ["--with-dummy-config=dummy"], previous_spec: nil }
+ { force: false, build_args: ["--with-dummy-config=dummy"], previous_spec: nil }
)
subject.install_from_spec
end
@@ -42,7 +42,7 @@ RSpec.describe Bundler::GemInstaller do
allow(Bundler.settings).to receive(:[]).with("build.dummy").and_return("--with-dummy-config=dummy --with-another-dummy-config")
expect(spec_source).to receive(:install).with(
spec,
- { force: false, ensure_builtin_gems_cached: false, build_args: ["--with-dummy-config=dummy", "--with-another-dummy-config"], previous_spec: nil }
+ { force: false, build_args: ["--with-dummy-config=dummy", "--with-another-dummy-config"], previous_spec: nil }
)
subject.install_from_spec
end
diff --git a/spec/bundler/bundler/settings_spec.rb b/spec/bundler/bundler/settings_spec.rb
index 634e0faf91..768372c608 100644
--- a/spec/bundler/bundler/settings_spec.rb
+++ b/spec/bundler/bundler/settings_spec.rb
@@ -6,12 +6,18 @@ RSpec.describe Bundler::Settings do
subject(:settings) { described_class.new(bundled_app) }
describe "#set_local" do
- context "when the local config file is not found" do
+ context "root is nil" do
subject(:settings) { described_class.new(nil) }
- it "raises a GemfileNotFound error with explanation" do
- expect { subject.set_local("foo", "bar") }.
- to raise_error(Bundler::GemfileNotFound, "Could not locate Gemfile")
+ before do
+ allow(Pathname).to receive(:new).and_call_original
+ allow(Pathname).to receive(:new).with(".bundle").and_return home(".bundle")
+ end
+
+ it "works" do
+ subject.set_local("foo", "bar")
+
+ expect(subject["foo"]).to eq("bar")
end
end
end
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