brew/Library/Homebrew/test/installed_dependents_spec.rb
2022-11-09 14:45:43 +00:00

205 lines
6.2 KiB
Ruby

# typed: false
# frozen_string_literal: true
require "installed_dependents"
describe InstalledDependents do
include FileUtils
def stub_formula(name, version = "1.0", &block)
f = formula(name) do
url "#{name}-#{version}"
instance_eval(&block) if block
end
stub_formula_loader f
stub_formula_loader f, "homebrew/core/#{f}"
f
end
def setup_test_keg(name, version, &block)
stub_formula("gcc")
stub_formula("glibc")
stub_formula(name, version, &block)
path = HOMEBREW_CELLAR/name/version
(path/"bin").mkpath
%w[hiworld helloworld goodbye_cruel_world].each do |file|
touch path/"bin"/file
end
Keg.new(path)
end
let!(:keg) { setup_test_keg("foo", "1.0") }
let!(:keg_only_keg) do
setup_test_keg("foo-keg-only", "1.0") do
keg_only "a good reason"
end
end
describe "::find_some_installed_dependents" do
def setup_test_keg(name, version, &block)
keg = super
Tab.create(keg.to_formula, DevelopmentTools.default_compiler, :libcxx).write
keg
end
before do
keg.link
keg_only_keg.optlink
end
def alter_tab(keg)
tab = Tab.for_keg(keg)
yield tab
tab.write
end
# 1.1.6 is the earliest version of Homebrew that generates correct runtime
# dependency lists in {Tab}s.
def tab_dependencies(keg, deps, homebrew_version: "1.1.6")
alter_tab(keg) do |tab|
tab.homebrew_version = homebrew_version
tab.tabfile = keg/Tab::FILENAME
tab.runtime_dependencies = deps
end
end
def unreliable_tab_dependencies(keg, deps)
# 1.1.5 is (hopefully!) the last version of Homebrew that generates
# incorrect runtime dependency lists in {Tab}s.
tab_dependencies(keg, deps, homebrew_version: "1.1.5")
end
specify "a dependency with no Tap in Tab" do
tap_dep = setup_test_keg("baz", "1.0")
dependent = setup_test_keg("bar", "1.0") do
depends_on "foo"
depends_on "baz"
end
# allow tap_dep to be linked too
FileUtils.rm_r tap_dep/"bin"
tap_dep.link
alter_tab(keg) { |t| t.source["tap"] = nil }
tab_dependencies dependent, nil
result = described_class.find_some_installed_dependents([keg, tap_dep])
expect(result).to eq([[keg, tap_dep], ["bar"]])
end
specify "no dependencies anywhere" do
dependent = setup_test_keg("bar", "1.0")
tab_dependencies dependent, nil
expect(described_class.find_some_installed_dependents([keg])).to be_nil
end
specify "missing Formula dependency" do
dependent = setup_test_keg("bar", "1.0") do
depends_on "foo"
end
tab_dependencies dependent, nil
expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar"]])
end
specify "uninstalling dependent and dependency" do
dependent = setup_test_keg("bar", "1.0") do
depends_on "foo"
end
tab_dependencies dependent, nil
expect(described_class.find_some_installed_dependents([keg, dependent])).to be_nil
end
specify "renamed dependency" do
dependent = setup_test_keg("bar", "1.0") do
depends_on "foo"
end
tab_dependencies dependent, nil
stub_formula_loader Formula["foo"], "homebrew/core/foo-old"
renamed_path = HOMEBREW_CELLAR/"foo-old"
(HOMEBREW_CELLAR/"foo").rename(renamed_path)
renamed_keg = Keg.new(renamed_path/keg.version.to_s)
result = described_class.find_some_installed_dependents([renamed_keg])
expect(result).to eq([[renamed_keg], ["bar"]])
end
specify "empty dependencies in Tab" do
dependent = setup_test_keg("bar", "1.0")
tab_dependencies dependent, []
expect(described_class.find_some_installed_dependents([keg])).to be_nil
end
specify "same name but different version in Tab" do
dependent = setup_test_keg("bar", "1.0")
tab_dependencies dependent, [{ "full_name" => keg.name, "version" => "1.1" }]
expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar"]])
end
specify "different name and same version in Tab" do
stub_formula("baz")
dependent = setup_test_keg("bar", "1.0")
tab_dependencies dependent, [{ "full_name" => "baz", "version" => keg.version.to_s }]
expect(described_class.find_some_installed_dependents([keg])).to be_nil
end
specify "same name and version in Tab" do
dependent = setup_test_keg("bar", "1.0")
tab_dependencies dependent, [{ "full_name" => keg.name, "version" => keg.version.to_s }]
expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar"]])
end
specify "fallback for old versions" do
dependent = setup_test_keg("bar", "1.0") do
depends_on "foo"
end
unreliable_tab_dependencies dependent, [{ "full_name" => "baz", "version" => "1.0" }]
expect(described_class.find_some_installed_dependents([keg])).to eq([[keg], ["bar"]])
end
specify "non-opt-linked" do
keg.remove_opt_record
dependent = setup_test_keg("bar", "1.0")
tab_dependencies dependent, [{ "full_name" => keg.name, "version" => keg.version.to_s }]
expect(described_class.find_some_installed_dependents([keg])).to be_nil
end
specify "keg-only" do
dependent = setup_test_keg("bar", "1.0")
tab_dependencies dependent, [{ "full_name" => keg_only_keg.name, "version" => "1.1" }] # different version
expect(described_class.find_some_installed_dependents([keg_only_keg])).to eq([[keg_only_keg], ["bar"]])
end
def stub_cask_name(name, version, dependency)
c = Cask::CaskLoader.load(+<<-RUBY)
cask "#{name}" do
version "#{version}"
url "c-1"
depends_on formula: "#{dependency}"
end
RUBY
stub_cask_loader c
c
end
def setup_test_cask(name, version, dependency)
c = stub_cask_name(name, version, dependency)
Cask::Caskroom.path.join(name, c.version).mkpath
c
end
specify "identify dependent casks" do
setup_test_cask("qux", "1.0.0", "foo")
dependents = described_class.find_some_installed_dependents([keg]).last
expect(dependents.include?("qux")).to be(true)
end
end
end