diff --git a/bundler/lib/dependabot/bundler/file_parser.rb b/bundler/lib/dependabot/bundler/file_parser.rb index 19f3d50893..69648afa44 100644 --- a/bundler/lib/dependabot/bundler/file_parser.rb +++ b/bundler/lib/dependabot/bundler/file_parser.rb @@ -50,7 +50,11 @@ def ecosystem sig { returns(Ecosystem::VersionManager) } def package_manager - @package_manager ||= PackageManager.new(bundler_raw_version, package_manager_requirement) + @package_manager ||= PackageManager.new( + detected_version: bundler_version, + raw_version: bundler_raw_version, + requirement: package_manager_requirement + ) end def package_manager_requirement @@ -355,7 +359,9 @@ def imported_ruby_files def bundler_raw_version return bundler_raw_version if defined?(@bundler_raw_version) - package_manager = PackageManager.new(bundler_version) + package_manager = PackageManager.new( + detected_version: bundler_version + ) # If the selected version is unsupported, an unsupported error will be raised, # so there’s no need to attempt retrieving the raw version. diff --git a/bundler/lib/dependabot/bundler/package_manager.rb b/bundler/lib/dependabot/bundler/package_manager.rb index 8385d6e4db..147b49c928 100644 --- a/bundler/lib/dependabot/bundler/package_manager.rb +++ b/bundler/lib/dependabot/bundler/package_manager.rb @@ -25,14 +25,16 @@ class PackageManager < Dependabot::Ecosystem::VersionManager sig do params( - raw_version: String, + detected_version: String, + raw_version: T.nilable(String), requirement: T.nilable(Requirement) ).void end - def initialize(raw_version, requirement = nil) + def initialize(detected_version:, raw_version: nil, requirement: nil) super( name: PACKAGE_MANAGER, - version: Version.new(raw_version), + detected_version: Version.new(detected_version), + version: raw_version ? Version.new(raw_version) : nil, deprecated_versions: DEPRECATED_BUNDLER_VERSIONS, supported_versions: SUPPORTED_BUNDLER_VERSIONS, requirement: requirement, diff --git a/bundler/spec/dependabot/bundler/package_manager_spec.rb b/bundler/spec/dependabot/bundler/package_manager_spec.rb index 10bd4ddd1e..35c52fe551 100644 --- a/bundler/spec/dependabot/bundler/package_manager_spec.rb +++ b/bundler/spec/dependabot/bundler/package_manager_spec.rb @@ -6,52 +6,41 @@ require "spec_helper" RSpec.describe Dependabot::Bundler::PackageManager do - let(:package_manager) { described_class.new(version, requirement) } + let(:package_manager) do + described_class.new( + detected_version: detected_version, + raw_version: raw_version, + requirement: requirement + ) + end let(:requirement) { nil } describe "#initialize" do - context "when version is a String" do - let(:version) { "2" } - - it "sets the version correctly" do - expect(package_manager.version).to eq(Dependabot::Bundler::Version.new(version)) - end - - it "sets the name correctly" do - expect(package_manager.name).to eq(Dependabot::Bundler::PACKAGE_MANAGER) - end - - it "sets the deprecated_versions correctly" do - expect(package_manager.deprecated_versions).to eq(Dependabot::Bundler::DEPRECATED_BUNDLER_VERSIONS) - end - - it "sets the supported_versions correctly" do - expect(package_manager.supported_versions).to eq(Dependabot::Bundler::SUPPORTED_BUNDLER_VERSIONS) - end - end + context "when versions are set" do + let(:detected_version) { "2" } + let(:raw_version) { "2.0.1" } - context "when version is a Dependabot::Bundler::Version" do - let(:version) { "2" } - - it "sets the version correctly" do - expect(package_manager.version).to eq(version) + it "sets detected and raw versions correctly" do + expect(package_manager.detected_version).to eq(Dependabot::Bundler::Version.new(detected_version)) + expect(package_manager.version).to eq(Dependabot::Bundler::Version.new(raw_version)) end it "sets the name correctly" do expect(package_manager.name).to eq(Dependabot::Bundler::PACKAGE_MANAGER) end - it "sets the deprecated_versions correctly" do + it "sets deprecated_versions correctly" do expect(package_manager.deprecated_versions).to eq(Dependabot::Bundler::DEPRECATED_BUNDLER_VERSIONS) end - it "sets the supported_versions correctly" do + it "sets supported_versions correctly" do expect(package_manager.supported_versions).to eq(Dependabot::Bundler::SUPPORTED_BUNDLER_VERSIONS) end end context "when a requirement is provided" do - let(:version) { "2.1" } + let(:detected_version) { "2.1" } + let(:raw_version) { "2.1.3" } let(:requirement) { Dependabot::Bundler::Requirement.new(">= 1.12.0, ~> 2.3.0") } it "sets the requirement correctly" do @@ -66,101 +55,111 @@ expect(package_manager.requirement.max_version).to eq(Dependabot::Version.new("2.4.0")) end end + end - context "when a single minimum constraint is provided" do - let(:version) { "2.1" } - let(:requirement) { Dependabot::Bundler::Requirement.new(">= 1.5") } - - it "sets the requirement correctly" do - expect(package_manager.requirement.to_s).to eq(">= 1.5") - end - - it "calculates the correct min_version" do - expect(package_manager.requirement.min_version).to eq(Dependabot::Version.new("1.5")) - end + describe "#deprecated?" do + context "when detected_version is deprecated but raw_version is not" do + let(:detected_version) { "1" } + let(:raw_version) { "2.0.1" } - it "returns nil for max_version" do - expect(package_manager.requirement.max_version).to be_nil + it "returns false because no deprecated versions exist" do + allow(package_manager).to receive(:unsupported?).and_return(false) + expect(package_manager.deprecated?).to be false end end - context "when multiple maximum constraints are provided" do - let(:version) { "2.1" } - let(:requirement) { Dependabot::Bundler::Requirement.new("<= 2.5, < 3.0") } + context "when detected_version and raw_version are both deprecated" do + let(:detected_version) { "1" } + let(:raw_version) { "1.0.3" } - it "sets the requirement correctly" do - expect(package_manager.requirement.to_s).to eq("<= 2.5, < 3.0") - end - - it "calculates the correct max_version" do - expect(package_manager.requirement.max_version).to eq(Dependabot::Version.new("2.5")) - end - - it "returns nil for min_version" do - expect(package_manager.requirement.min_version).to be_nil + it "returns false because no deprecated versions exist" do + allow(package_manager).to receive(:unsupported?).and_return(false) + expect(package_manager.deprecated?).to be false end end - end - - describe "SUPPORTED_BUNDLER_VERSIONS" do - it "is in ascending order" do - expect(Dependabot::Bundler::SUPPORTED_BUNDLER_VERSIONS) - .to eq(Dependabot::Bundler::SUPPORTED_BUNDLER_VERSIONS.sort) - end - end - describe "#deprecated?" do - context "when version is deprecated but not unsupported" do - let(:version) { "1" } + context "when detected_version is unsupported" do + let(:detected_version) { "0.9" } + let(:raw_version) { "1.0.4" } - it "returns true" do - allow(package_manager).to receive_messages(deprecated?: true) - expect(package_manager.deprecated?).to be true + it "returns false, as unsupported takes precedence" do + expect(package_manager.deprecated?).to be false end end - context "when version is unsupported" do - let(:version) { "0.9" } + context "when raw_version is nil" do + let(:detected_version) { "1" } + let(:raw_version) { nil } - it "returns false, as unsupported takes precedence" do + it "returns false because no deprecated versions exist" do + allow(package_manager).to receive(:unsupported?).and_return(false) expect(package_manager.deprecated?).to be false end end end describe "#unsupported?" do - context "when version is supported" do - let(:version) { "2" } + context "when detected_version is supported" do + let(:detected_version) { "2" } + let(:raw_version) { "2.1.3" } it "returns false" do expect(package_manager.unsupported?).to be false end end - context "when version is not supported" do - let(:version) { "0.9" } + context "when detected_version is unsupported" do + let(:detected_version) { "0.9" } + let(:raw_version) { "0.9.2" } it "returns true" do expect(package_manager.unsupported?).to be true end end + + context "when raw_version is nil" do + let(:detected_version) { "0.9" } + let(:raw_version) { nil } + + it "returns true based on detected_version" do + expect(package_manager.unsupported?).to be true + end + end end describe "#raise_if_unsupported!" do - context "when version is unsupported" do - let(:version) { "0.9" } + context "when detected_version is unsupported" do + let(:detected_version) { "0.9" } + let(:raw_version) { "0.9.2" } it "raises a ToolVersionNotSupported error" do expect { package_manager.raise_if_unsupported! }.to raise_error(Dependabot::ToolVersionNotSupported) end end - context "when version is supported" do - let(:version) { "2.1" } + context "when detected_version is supported" do + let(:detected_version) { "2.1" } + let(:raw_version) { "2.1.4" } it "does not raise an error" do expect { package_manager.raise_if_unsupported! }.not_to raise_error end end + + context "when raw_version is nil but detected_version is unsupported" do + let(:detected_version) { "0.9" } + let(:raw_version) { nil } + + it "raises a ToolVersionNotSupported error" do + expect { package_manager.raise_if_unsupported! }.to raise_error(Dependabot::ToolVersionNotSupported) + end + end + end + + describe "SUPPORTED_BUNDLER_VERSIONS" do + it "is in ascending order" do + expect(Dependabot::Bundler::SUPPORTED_BUNDLER_VERSIONS) + .to eq(Dependabot::Bundler::SUPPORTED_BUNDLER_VERSIONS.sort) + end end end diff --git a/common/spec/dependabot/ecosystem_spec.rb b/common/spec/dependabot/ecosystem_spec.rb index 224ff0377a..794a3ae996 100644 --- a/common/spec/dependabot/ecosystem_spec.rb +++ b/common/spec/dependabot/ecosystem_spec.rb @@ -5,122 +5,226 @@ require "dependabot/ecosystem" require "dependabot/requirement" -# Define an anonymous subclass of Dependabot::Requirement for testing purposes -TestRequirement = Class.new(Dependabot::Requirement) - RSpec.describe Dependabot::Ecosystem do - let(:supported_versions) { [Dependabot::Version.new("1"), Dependabot::Version.new("2")] } - let(:deprecated_versions) { [Dependabot::Version.new("1")] } - let(:requirement) { TestRequirement.new(">= 1.0") } + let(:package_manager_supported_versions) { [Dependabot::Version.new("1"), Dependabot::Version.new("2")] } + let(:package_manager_deprecated_versions) { [Dependabot::Version.new("1")] } + let(:package_manager_requirement) { TestRequirement.new(">= 1.0") } + let(:package_manager_detected_version) { "1.0" } + let(:package_manager_raw_version) { "1.0.1" } - let(:package_manager_detected_version) { "1.0.0" } - let(:package_manager_raw_version) { "1.0.0" } - let(:language_detected_version) { "3.0.0" } - let(:language_raw_version) { "3.0.0" } + let(:language_supported_versions) { [Dependabot::Version.new("3.0"), Dependabot::Version.new("3.1")] } + let(:language_deprecated_versions) { [Dependabot::Version.new("3.0")] } + let(:language_requirement) { TestRequirement.new(">= 3.0") } + let(:language_detected_version) { "3.0" } + let(:language_raw_version) { "3.0.2" } let(:package_manager) do Class.new(Dependabot::Ecosystem::VersionManager) do def initialize(detected_version, raw_version, deprecated_versions, supported_versions, requirement) super( - name: "bundler", # name - detected_version: Dependabot::Version.new(detected_version), # version - version: Dependabot::Version.new(raw_version), # version - deprecated_versions: deprecated_versions, # deprecated_versions - supported_versions: supported_versions, # supported_versions - requirement: requirement # requirement + name: "bundler", + detected_version: Dependabot::Version.new(detected_version), + version: raw_version.nil? ? nil : Dependabot::Version.new(raw_version), + deprecated_versions: deprecated_versions, + supported_versions: supported_versions, + requirement: requirement ) end end.new( package_manager_detected_version, package_manager_raw_version, - deprecated_versions, - supported_versions, - requirement + package_manager_deprecated_versions, + package_manager_supported_versions, + package_manager_requirement ) end let(:language) do Class.new(Dependabot::Ecosystem::VersionManager) do - def initialize(detected_version, raw_version) + def initialize(detected_version, raw_version, deprecated_versions, supported_versions, requirement) super( - name: "ruby", # name - detected_version: Dependabot::Version.new(detected_version), # version - version: Dependabot::Version.new(raw_version), # version - deprecated_versions: [], # deprecated_versions - supported_versions: [], # supported_versions + name: "ruby", + detected_version: Dependabot::Version.new(detected_version), + version: raw_version.nil? ? nil : Dependabot::Version.new(raw_version), + deprecated_versions: deprecated_versions, + supported_versions: supported_versions, + requirement: requirement ) end - end.new(language_detected_version, language_raw_version) + end.new( + language_detected_version, + language_raw_version, + language_deprecated_versions, + language_supported_versions, + language_requirement + ) end describe "#initialize" do - it "sets the correct attributes" do + it "sets the correct attributes for package manager and language" do ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) expect(ecosystem.name).to eq("bundler") + expect(ecosystem.package_manager.name).to eq("bundler") + expect(ecosystem.package_manager.detected_version.to_s).to eq("1.0") + expect(ecosystem.package_manager.version.to_s).to eq("1.0.1") + expect(ecosystem.language.name).to eq("ruby") + expect(ecosystem.language.detected_version.to_s).to eq("3.0") + expect(ecosystem.language.version.to_s).to eq("3.0.2") + end + end + + describe "#name" do + it "returns the correct name for the package manager and language" do + ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) + expect(ecosystem.package_manager.name).to eq("bundler") expect(ecosystem.language.name).to eq("ruby") end end + describe "#version checks" do + it "returns the correct string representation of version and raw version" do + expect(package_manager.version.to_s).to eq("1.0.1") + expect(language.version.to_s).to eq("3.0.2") + end + end + describe "#deprecated?" do - context "when the package manager version is deprecated" do - let(:package_manager_detected_version) { "1" } - let(:package_manager_raw_version) { "1" } + context "when detected version is deprecated" do + let(:package_manager_detected_version) { "1.0" } - it "returns true" do - ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) - expect(ecosystem.deprecated?).to be true + context "with raw version not deprecated" do + let(:package_manager_raw_version) { "2.0.1" } + + it "returns true" do + ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) + expect(ecosystem.deprecated?).to be true + end + end + + context "with raw version deprecated" do + let(:package_manager_raw_version) { "1.0.1" } + + it "returns true" do + ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) + expect(ecosystem.deprecated?).to be true + end + end + + context "with raw version nil" do + let(:package_manager_raw_version) { nil } + + it "returns true" do + ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) + expect(ecosystem.deprecated?).to be true + end end end - context "when the package manager version is not deprecated" do - let(:package_manager_detected_version) { "2.0.0" } - let(:package_manager_raw_version) { "2.0.0" } + context "when detected version is not deprecated" do + let(:package_manager_detected_version) { "2.0" } - it "returns false" do - ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) - expect(ecosystem.deprecated?).to be false + context "with raw version not deprecated" do + let(:package_manager_raw_version) { "2.0.1" } + + it "returns false" do + ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) + expect(ecosystem.deprecated?).to be false + end + end + + context "with raw version deprecated" do + let(:package_manager_raw_version) { "1.0.1" } + + it "returns false" do + ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) + expect(ecosystem.deprecated?).to be false + end + end + + context "with raw version nil" do + let(:package_manager_raw_version) { nil } + + it "returns false" do + ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) + expect(ecosystem.deprecated?).to be false + end end end end describe "#unsupported?" do - context "when the package manager version is unsupported" do - let(:package_manager_detected_version) { "0.8.0" } - let(:package_manager_raw_version) { "0.8.0" } + context "when detected version is unsupported" do + let(:package_manager_detected_version) { "0.8" } - it "returns true" do - ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) - expect(ecosystem.unsupported?).to be true + context "with raw version not unsupported" do + let(:package_manager_raw_version) { "2.0.1" } + + it "returns true" do + ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) + expect(ecosystem.unsupported?).to be true + end + end + + context "with raw version nil" do + let(:package_manager_raw_version) { nil } + + it "returns true" do + ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) + expect(ecosystem.unsupported?).to be true + end end end - context "when the package manager version is supported" do - let(:package_manager_detected_version) { "2.0.0" } - let(:package_manager_raw_version) { "2.0.0" } + context "when detected version is supported" do + let(:package_manager_detected_version) { "2.0" } - it "returns false" do - ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) - expect(ecosystem.unsupported?).to be false + context "with raw version not unsupported" do + let(:package_manager_raw_version) { "2.0.1" } + + it "returns false" do + ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) + expect(ecosystem.unsupported?).to be false + end + end + + context "with raw version nil" do + let(:package_manager_raw_version) { nil } + + it "returns false" do + ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) + expect(ecosystem.unsupported?).to be false + end end end end describe "#raise_if_unsupported!" do - context "when the package manager version is unsupported" do - let(:package_manager_detected_version) { "0.8.0" } - let(:package_manager_raw_version) { "0.8.0" } + context "when detected version is unsupported" do + let(:package_manager_detected_version) { "0.8" } - it "raises a ToolVersionNotSupported error" do - ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) - expect { ecosystem.raise_if_unsupported! }.to raise_error(Dependabot::ToolVersionNotSupported) + context "with raw version not nil" do + let(:package_manager_raw_version) { "2.0.1" } + + it "raises a ToolVersionNotSupported error" do + ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) + expect { ecosystem.raise_if_unsupported! }.to raise_error(Dependabot::ToolVersionNotSupported) + end + end + + context "with raw version nil" do + let(:package_manager_raw_version) { nil } + + it "raises a ToolVersionNotSupported error" do + ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) + expect { ecosystem.raise_if_unsupported! }.to raise_error(Dependabot::ToolVersionNotSupported) + end end end - context "when the package manager version is supported" do - let(:package_manager_detected_version) { "2.0.0" } - let(:package_manager_raw_version) { "2.0.0" } + context "when detected version is supported" do + let(:package_manager_detected_version) { "2.0" } it "does not raise an error" do ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) @@ -133,16 +237,19 @@ def initialize(detected_version, raw_version) context "when a requirement is provided" do it "sets the requirement correctly" do ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) - expect(ecosystem.package_manager.requirement).to eq(requirement) + expect(ecosystem.package_manager.requirement).to eq(package_manager_requirement) + expect(ecosystem.language.requirement).to eq(language_requirement) end end context "when no requirement is provided" do - let(:requirement) { nil } + let(:package_manager_requirement) { nil } + let(:language_requirement) { nil } it "returns nil for the requirement" do ecosystem = described_class.new(name: "bundler", package_manager: package_manager, language: language) expect(ecosystem.package_manager.requirement).to be_nil + expect(ecosystem.language.requirement).to be_nil end end end diff --git a/common/spec/dependabot/notices_spec.rb b/common/spec/dependabot/notices_spec.rb index 817a4c1873..988f39fa8c 100644 --- a/common/spec/dependabot/notices_spec.rb +++ b/common/spec/dependabot/notices_spec.rb @@ -15,28 +15,46 @@ def initialize(name:, detected_version:, raw_version:, deprecated_versions: [], super( name: name, detected_version: Dependabot::Version.new(detected_version), - version: Dependabot::Version.new(raw_version), + version: raw_version.nil? ? nil : Dependabot::Version.new(raw_version), deprecated_versions: deprecated_versions, supported_versions: supported_versions - ) + ) end attr_reader :support_later_versions sig { override.returns(T::Boolean) } def unsupported? - # Determine if the version is unsupported. + return false unless version + version < supported_versions.first end sig { override.returns(T::Boolean) } def support_later_versions? - # Determine if the Bundler version is unsupported. support_later_versions end end RSpec.describe Dependabot::Notice do + let(:detected_version) { Dependabot::Version.new("1") } + let(:raw_version) { Dependabot::Version.new("1.0.1") } + let(:deprecated_versions) { [Dependabot::Version.new("1")] } + let(:supported_versions) { [Dependabot::Version.new("2"), Dependabot::Version.new("3")] } + let(:support_later_versions) { false } + let(:version_manager_type) { :package_manager } + + let(:version_manager) do + StubVersionManager.new( + name: "bundler", + detected_version: detected_version, + raw_version: raw_version, + deprecated_versions: deprecated_versions, + supported_versions: supported_versions, + support_later_versions: support_later_versions + ) + end + describe ".generate_supported_versions_description" do subject(:generate_supported_versions_description) do described_class.generate_supported_versions_description(supported_versions, support_later_versions) @@ -44,139 +62,119 @@ def support_later_versions? context "when supported_versions has one version" do let(:supported_versions) { [Dependabot::Version.new("2")] } - let(:support_later_versions) { false } - it "returns the correct description" do - expect(generate_supported_versions_description) - .to eq("Please upgrade to version `v2`.") + context "with support_later_versions as false" do + let(:support_later_versions) { false } + + it "returns the correct description" do + expect(generate_supported_versions_description).to eq("Please upgrade to version `v2`.") + end end - end - context "when supported_versions has one version and later versions are supported" do - let(:supported_versions) { [Dependabot::Version.new("2")] } - let(:support_later_versions) { true } + context "with support_later_versions as true" do + let(:support_later_versions) { true } - it "returns the correct description" do - expect(generate_supported_versions_description) - .to eq("Please upgrade to version `v2`, or later.") + it "returns the correct description with later versions supported" do + expect(generate_supported_versions_description).to eq("Please upgrade to version `v2`, or later.") + end end end context "when supported_versions has multiple versions" do - let(:supported_versions) do - [Dependabot::Version.new("2"), Dependabot::Version.new("3"), - Dependabot::Version.new("4")] - end - let(:support_later_versions) { false } + let(:supported_versions) { [Dependabot::Version.new("2"), Dependabot::Version.new("3")] } - it "returns the correct description" do - expect(generate_supported_versions_description) - .to eq("Please upgrade to one of the following versions: `v2`, `v3`, or `v4`.") - end - end + context "with support_later_versions as false" do + let(:support_later_versions) { false } - context "when supported_versions has multiple versions and later versions are supported" do - let(:supported_versions) do - [Dependabot::Version.new("2"), Dependabot::Version.new("3"), - Dependabot::Version.new("4")] - end - let(:support_later_versions) { true } - - it "returns the correct description" do - expect(generate_supported_versions_description) - .to eq("Please upgrade to one of the following versions: `v2`, `v3`, `v4`, or later.") + it "returns the correct description without later versions supported" do + expect(generate_supported_versions_description) + .to eq("Please upgrade to one of the following versions: `v2`, or `v3`.") + end end - end - context "when supported_versions is nil" do - let(:supported_versions) { nil } - let(:support_later_versions) { false } + context "with support_later_versions as true" do + let(:support_later_versions) { true } - it "returns empty string" do - expect(generate_supported_versions_description).to eq("Please upgrade your package manager version") + it "returns the correct description with later versions supported" do + expect(generate_supported_versions_description) + .to eq("Please upgrade to one of the following versions: `v2`, `v3`, or later.") + end end end context "when supported_versions is empty" do let(:supported_versions) { [] } - let(:support_later_versions) { false } - it "returns the correct description" do + it "returns a generic upgrade message" do expect(generate_supported_versions_description).to eq("Please upgrade your package manager version") end - - context "when the entity being deprecated is the language" do - subject(:generate_supported_versions_description) do - described_class.generate_supported_versions_description( - supported_versions, support_later_versions, :language - ) - end - - it "returns the correct description" do - expect(generate_supported_versions_description).to eq("Please upgrade your language version") - end - end end end describe ".generate_deprecation_notice" do - subject(:package_manager_deprecation_notice) do - described_class.generate_deprecation_notice(package_manager) + subject(:deprecation_notice) do + described_class.generate_deprecation_notice(version_manager, version_manager_type) end - let(:package_manager) do - StubVersionManager.new( - name: "bundler", - detected_version: Dependabot::Version.new("1"), - raw_version: Dependabot::Version.new("1"), - deprecated_versions: [Dependabot::Version.new("1")], - supported_versions: [Dependabot::Version.new("2"), Dependabot::Version.new("3")] - ) - end + context "when detected_version is deprecated" do + let(:detected_version) { Dependabot::Version.new("1") } + let(:deprecated_versions) { [Dependabot::Version.new("1")] } + + context "with raw_version not deprecated" do + let(:raw_version) { Dependabot::Version.new("2.0.1") } + + it "returns a deprecation notice using detected_version" do + expect(deprecation_notice.to_hash) + .to eq({ + mode: "WARN", + type: "bundler_deprecated_warn", + package_manager_name: "bundler", + title: "Package manager deprecation notice", + description: "Dependabot will stop supporting `bundler v1`!" \ + "\n\nPlease upgrade to one of the following versions: `v2`, or `v3`.\n", + show_in_pr: true, + show_alert: true + }) + end + end - it "returns the correct deprecation notice" do - allow(package_manager).to receive(:unsupported?).and_return(false) - expect(package_manager_deprecation_notice.to_hash) - .to eq({ - mode: "WARN", - type: "bundler_deprecated_warn", - package_manager_name: "bundler", - title: "Package manager deprecation notice", - description: "Dependabot will stop supporting `bundler v1`!" \ - "\n\nPlease upgrade to one of the following versions: `v2`, or `v3`.\n", - show_in_pr: true, - show_alert: true - }) + context "with raw_version nil" do + let(:raw_version) { nil } + + it "returns a deprecation notice using detected_version" do + expect(deprecation_notice.to_hash) + .to eq({ + mode: "WARN", + type: "bundler_deprecated_warn", + package_manager_name: "bundler", + title: "Package manager deprecation notice", + description: "Dependabot will stop supporting `bundler v1`!" \ + "\n\nPlease upgrade to one of the following versions: `v2`, or `v3`.\n", + show_in_pr: true, + show_alert: true + }) + end + end end - context "when generating a notice for a deprecated language" do - subject(:deprecation_notice) do - described_class.generate_deprecation_notice(language_manager, :language) - end + context "when detected_version is not deprecated" do + let(:detected_version) { Dependabot::Version.new("2") } + let(:deprecated_versions) { [Dependabot::Version.new("1")] } - let(:language_manager) do - StubVersionManager.new( - name: "python", - detected_version: Dependabot::Version.new("3.8"), - raw_version: Dependabot::Version.new("3.8"), - deprecated_versions: [Dependabot::Version.new("3.8")], - supported_versions: [Dependabot::Version.new("3.9")] - ) + context "with raw_version nil" do + let(:raw_version) { nil } + + it "does not return a notice" do + expect(deprecation_notice).to be_nil + end end - it "returns the correct deprecation notice" do - allow(language_manager).to receive(:unsupported?).and_return(false) - expect(deprecation_notice.to_hash) - .to eq({ - mode: "WARN", - type: "python_deprecated_warn", - package_manager_name: "python", - title: "Language deprecation notice", - description: "Dependabot will stop supporting `python v3.8`!" \ - "\n\nPlease upgrade to version `v3.9`.\n", - show_in_pr: true, - show_alert: true - }) + context "with raw_version different from detected_version" do + let(:raw_version) { Dependabot::Version.new("1.0.1") } + + it "does not return a notice" do + expect(deprecation_notice).to be_nil + end end end end diff --git a/common/spec/dependabot/requirement_spec.rb b/common/spec/dependabot/requirement_spec.rb index dc292950a1..6e38c9d8c8 100644 --- a/common/spec/dependabot/requirement_spec.rb +++ b/common/spec/dependabot/requirement_spec.rb @@ -5,15 +5,6 @@ require "dependabot/requirement" require "dependabot/version" -# Define an anonymous subclass of Dependabot::Requirement for testing purposes -TestRequirement = Class.new(Dependabot::Requirement) do - # Initialize with comma-separated requirement constraints - def initialize(constraint_string) - requirements = constraint_string.split(",").map(&:strip) - super(requirements) - end -end - RSpec.describe Dependabot::Requirement do subject(:requirement) { TestRequirement.new(constraint_string) } diff --git a/common/spec/spec_helper.rb b/common/spec/spec_helper.rb index f376821476..41c3058670 100644 --- a/common/spec/spec_helper.rb +++ b/common/spec/spec_helper.rb @@ -202,3 +202,12 @@ def command_fixture(name) File.expand_path(path) end + +# Define an anonymous subclass of Dependabot::Requirement for testing purposes +TestRequirement = Class.new(Dependabot::Requirement) do + # Initialize with comma-separated requirement constraints + def initialize(constraint_string) + requirements = constraint_string.split(",").map(&:strip) + super(requirements) + end +end diff --git a/updater/spec/dependabot/notices_helpers_spec.rb b/updater/spec/dependabot/notices_helpers_spec.rb index 05d85e251f..e2c62ffc82 100644 --- a/updater/spec/dependabot/notices_helpers_spec.rb +++ b/updater/spec/dependabot/notices_helpers_spec.rb @@ -7,6 +7,35 @@ require "dependabot/notices" require "dependabot/notices_helpers" +# A stub package manager for testing purposes. +class StubVersionManager < Dependabot::Ecosystem::VersionManager + def initialize(name:, detected_version:, raw_version:, deprecated_versions: [], supported_versions: [], + support_later_versions: false) + @support_later_versions = support_later_versions + super( + name: name, + detected_version: Dependabot::Version.new(detected_version), + version: raw_version.nil? ? nil : Dependabot::Version.new(raw_version), + deprecated_versions: deprecated_versions, + supported_versions: supported_versions + ) + end + + attr_reader :support_later_versions + + sig { override.returns(T::Boolean) } + def unsupported? + return false unless version + + version < supported_versions.first + end + + sig { override.returns(T::Boolean) } + def support_later_versions? + support_later_versions + end +end + RSpec.describe Dependabot::NoticesHelpers do let(:dummy_class) do Class.new do @@ -21,102 +50,116 @@ def initialize end let(:dummy_instance) { dummy_class.new } - - let(:package_manager) do - Class.new(Dependabot::Ecosystem::VersionManager) do - def initialize - detected_version = "1" - raw_version = "1" - super( - name: "bundler", # name - detected_version: Dependabot::Version.new(detected_version), # detected_version - version: Dependabot::Version.new(raw_version), # version - deprecated_versions: [Dependabot::Version.new("1")], # deprecated_versions - supported_versions: [Dependabot::Version.new("2"), Dependabot::Version.new("3")] # supported_versions - ) - end - end.new + let(:detected_version) { Dependabot::Version.new("1") } + let(:raw_version) { Dependabot::Version.new("1.0.1") } + let(:deprecated_versions) { [Dependabot::Version.new("1")] } + let(:supported_versions) { [Dependabot::Version.new("2"), Dependabot::Version.new("3")] } + let(:version_manager_type) { :package_manager } + + let(:version_manager) do + StubVersionManager.new( + name: "bundler", + detected_version: detected_version, + raw_version: raw_version, + deprecated_versions: deprecated_versions, + supported_versions: supported_versions + ) end before do - allow(package_manager).to receive(:unsupported?).and_return(false) + allow(version_manager).to receive(:unsupported?).and_return(false) end describe "#add_deprecation_notice" do - context "when package manager is provided and is deprecated" do - it "adds a deprecation notice to the notices array" do - expect do - dummy_instance.add_deprecation_notice(notices: dummy_instance.notices, version_manager: package_manager) - end - .to change { dummy_instance.notices.size }.by(1) + context "when version manager is provided" do + context "when version manager is deprecated" do + let(:detected_version) { Dependabot::Version.new("1") } + let(:deprecated_versions) { [Dependabot::Version.new("1")] } + + it "adds a deprecation notice to the notices array" do + expect do + dummy_instance.add_deprecation_notice( + notices: dummy_instance.notices, + version_manager: version_manager + ) + end.to change { dummy_instance.notices.size }.by(1) - notice = dummy_instance.notices.first - expect(notice.mode).to eq("WARN") - expect(notice.type).to eq("bundler_deprecated_warn") - expect(notice.package_manager_name).to eq("bundler") - end + notice = dummy_instance.notices.first + expect(notice.mode).to eq("WARN") + expect(notice.type).to eq("bundler_deprecated_warn") + expect(notice.package_manager_name).to eq("bundler") + end - it "logs deprecation notices line by line" do - allow(Dependabot.logger).to receive(:warn) + it "logs deprecation notices line by line" do + allow(Dependabot.logger).to receive(:warn) - dummy_instance.add_deprecation_notice(notices: dummy_instance.notices, version_manager: package_manager) + dummy_instance.add_deprecation_notice( + notices: dummy_instance.notices, + version_manager: version_manager + ) - notice = dummy_instance.notices.first - notice.description.each_line do |line| - line = line.strip - next if line.empty? + notice = dummy_instance.notices.first + notice.description.each_line do |line| + line = line.strip + next if line.empty? - puts "except lines: ##{line}#" - expect(Dependabot.logger).to have_received(:warn).with(line).once + expect(Dependabot.logger).to have_received(:warn).with(line).once + end end end - end - context "when package manager is not provided" do - it "does not add a deprecation notice to the notices array" do - expect { dummy_instance.add_deprecation_notice(notices: dummy_instance.notices, version_manager: nil) } - .not_to(change { dummy_instance.notices.size }) + context "when version manager is not deprecated" do + let(:detected_version) { Dependabot::Version.new("2") } + let(:deprecated_versions) { [Dependabot::Version.new("1")] } + + it "does not add a deprecation notice to the notices array" do + expect do + dummy_instance.add_deprecation_notice( + notices: dummy_instance.notices, + version_manager: version_manager + ) + end.not_to(change { dummy_instance.notices.size }) + end end - end - context "when package manager is not deprecated" do - let(:package_manager) do - Class.new(Dependabot::Ecosystem::VersionManager) do - def initialize - detected_version = "2" - raw_version = "2" - super( - name: "bundler", # name - detected_version: Dependabot::Version.new(detected_version), - version: Dependabot::Version.new(raw_version), # version - deprecated_versions: [Dependabot::Version.new("1")], # deprecated_versions - supported_versions: [Dependabot::Version.new("2"), Dependabot::Version.new("3")] # supported_versions + context "when raw_version is nil" do + let(:raw_version) { nil } + let(:detected_version) { Dependabot::Version.new("1") } + + it "adds a deprecation notice using detected_version" do + expect do + dummy_instance.add_deprecation_notice( + notices: dummy_instance.notices, + version_manager: version_manager ) - end - end.new + end.to change { dummy_instance.notices.size }.by(1) + + notice = dummy_instance.notices.first + expect(notice.description).to include("Dependabot will stop supporting `bundler v1`!") + end end + end + context "when version manager is not provided" do it "does not add a deprecation notice to the notices array" do expect do - dummy_instance.add_deprecation_notice(notices: dummy_instance.notices, version_manager: package_manager) - end - .not_to(change { dummy_instance.notices.size }) + dummy_instance.add_deprecation_notice( + notices: dummy_instance.notices, + version_manager: nil + ) + end.not_to(change { dummy_instance.notices.size }) end end - context "when the language version is deprecated" do + context "when language version is deprecated" do let(:language_manager) do - Class.new(Dependabot::Ecosystem::VersionManager) do - def initialize - super( - name: "python", # name - detected_version: Dependabot::Version.new("3.8"), # version - version: Dependabot::Version.new("3.8"), # version - deprecated_versions: [Dependabot::Version.new("3.8")], # deprecated_versions - supported_versions: [Dependabot::Version.new("3.9"), Dependabot::Version.new("3.10")] # supported_versions - ) - end - end.new + StubVersionManager.new( + name: "python", + detected_version: Dependabot::Version.new("3.8"), + raw_version: Dependabot::Version.new("3.8"), + deprecated_versions: [Dependabot::Version.new("3.8")], + supported_versions: [Dependabot::Version.new("3.9"), Dependabot::Version.new("3.10")] + ) end before do @@ -125,16 +168,14 @@ def initialize it "adds a deprecation notice to the notices array" do expect do - dummy_instance - .add_deprecation_notice( - notices: dummy_instance.notices, - version_manager: language_manager, - version_manager_type: :language - ) + dummy_instance.add_deprecation_notice( + notices: dummy_instance.notices, + version_manager: language_manager, + version_manager_type: :language + ) end.to change { dummy_instance.notices.size }.by(1) notice = dummy_instance.notices.first - expect(notice.mode).to eq("WARN") expect(notice.type).to eq("python_deprecated_warn") expect(notice.package_manager_name).to eq("python")