mirror of
https://github.com/Homebrew/brew.git
synced 2026-08-12 22:29:27 +04:00
sorbet: Use T.bind in formula blocks in tests
- Don't duplicate all of `formula.rbi` in the `rspec.rbi` shim because it's a terrible pattern. - I also noticed a supposedly typechecked file `test/test_bot/formulae_spec.rb` that was definitely cheating through the use of `T.bind(self, T.untyped)` and `T.unsafe`. So, follow the same `T.bind(self, T.class_of(Formula))` pattern in test files to make sure we're getting proper type checking in `formula` blocks.
This commit is contained in:
@@ -44,14 +44,6 @@ class RSpec::Core::ExampleGroup
|
||||
# These methods are mixed into specs via
|
||||
# `config.include(Test::Helper::{Formula,Cask})` in `test/spec_helper.rb`;
|
||||
# declare them here so Sorbet can resolve them in typed spec files.
|
||||
sig {
|
||||
params(
|
||||
name: String, path: T.nilable(Pathname), spec: Symbol, alias_path: T.nilable(Pathname),
|
||||
tap: T.nilable(Tap), block: T.nilable(T.proc.bind(Formula).void)
|
||||
).returns(::Formula)
|
||||
}
|
||||
def formula(name = T.unsafe(nil), path: nil, spec: :stable, alias_path: nil, tap: nil, &block); end
|
||||
|
||||
sig { params(formula: ::Formula, ref: T.nilable(String), call_original: T::Boolean).void }
|
||||
def stub_formula_loader(formula, ref = formula.full_name, call_original: false); end
|
||||
|
||||
@@ -132,25 +124,6 @@ class RSpec::Core::ExampleGroup
|
||||
|
||||
sig { params(name: String).returns(Pathname) }
|
||||
def fixture(name); end
|
||||
|
||||
# `formula(...) { ... }` helper blocks can be inferred as example group
|
||||
# contexts in typed specs; declare Formula DSL methods to satisfy static
|
||||
# analysis.
|
||||
sig { params(val: String, specs: T::Hash[Symbol, T.anything]).returns(String) }
|
||||
def url(val = "", specs = {}); end
|
||||
end
|
||||
|
||||
# `formula(...) { ... }` helper blocks can be inferred as this helper module in
|
||||
# typed specs; declare Formula DSL methods to satisfy static analysis.
|
||||
module Test::Helper::Formula
|
||||
sig { params(val: String, specs: T::Hash[Symbol, T.anything]).returns(String) }
|
||||
def url(val = "", specs = {}); end
|
||||
end
|
||||
|
||||
# Some helper blocks are inferred as Formula instances or class contexts.
|
||||
class Formula
|
||||
sig { params(val: String, specs: T::Hash[Symbol, T.anything]).returns(String) }
|
||||
def url(val = "", specs = {}); end
|
||||
end
|
||||
|
||||
# The rspec-mocks RBI defines `ExpectHost#expect(target)` with a required
|
||||
|
||||
@@ -53,6 +53,7 @@ RSpec.describe Bottle::Filename do
|
||||
|
||||
let(:f) do
|
||||
formula do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "https://brew.sh/foo.tar.gz"
|
||||
version "1.0"
|
||||
end
|
||||
|
||||
@@ -180,7 +180,10 @@ RSpec.describe Homebrew::Bundle::MacAppStore do
|
||||
|
||||
describe "installing" do
|
||||
before do
|
||||
stub_formula_loader formula("mas") { url "mas-1.0" }
|
||||
stub_formula_loader formula("mas") {
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "mas-1.0"
|
||||
}
|
||||
end
|
||||
|
||||
describe ".installed_app_ids" do
|
||||
|
||||
@@ -34,7 +34,10 @@ RSpec.describe Homebrew::Bundle::Skipper do
|
||||
it "returns true" do
|
||||
allow(Hardware::CPU).to receive(:arm?).and_return(true)
|
||||
allow(Homebrew).to receive(:default_prefix?).and_return(true)
|
||||
stub_formula_loader formula("mysql") { url "mysql-1.0" }
|
||||
stub_formula_loader formula("mysql") {
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "mysql-1.0"
|
||||
}
|
||||
|
||||
expect(skipper.skip?(entry)).to be true
|
||||
end
|
||||
|
||||
@@ -7,12 +7,14 @@ RSpec.describe Homebrew::CLI::NamedArgs do
|
||||
let(:klass) { Homebrew::CLI::NamedArgs }
|
||||
let(:foo) do
|
||||
formula "foo" do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "https://brew.sh"
|
||||
version "1.0"
|
||||
end
|
||||
end
|
||||
let(:bar) do
|
||||
formula "bar" do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "https://brew.sh"
|
||||
version "1.0"
|
||||
end
|
||||
@@ -92,6 +94,7 @@ RSpec.describe Homebrew::CLI::NamedArgs do
|
||||
context "when a non-core formula and a core cask are present" do
|
||||
let(:non_core_formula) do
|
||||
formula "foo", tap: Tap.fetch("some/tap") do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "https://brew.sh"
|
||||
version "1.0"
|
||||
end
|
||||
|
||||
@@ -19,7 +19,10 @@ RSpec.describe Homebrew::Cmd::Bundle::CheckSubcommand, :no_api do
|
||||
before do
|
||||
Homebrew::Bundle::Checker.reset!
|
||||
allow_any_instance_of(IO).to receive(:puts)
|
||||
stub_formula_loader formula("mas") { url "mas-1.0" }
|
||||
stub_formula_loader formula("mas") {
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "mas-1.0"
|
||||
}
|
||||
end
|
||||
|
||||
context "when dependencies are satisfied" do
|
||||
@@ -85,7 +88,10 @@ RSpec.describe Homebrew::Cmd::Bundle::CheckSubcommand, :no_api do
|
||||
before do
|
||||
allow(Homebrew::Bundle::Cask).to receive(:casks).and_return([])
|
||||
allow(Homebrew::Bundle::Brew).to receive_messages(upgradable_formulae: [], installed_formulae: ["abc"])
|
||||
stub_formula_loader formula("abc") { url "abc-1.0" }
|
||||
stub_formula_loader formula("abc") {
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "abc-1.0"
|
||||
}
|
||||
end
|
||||
|
||||
it "raises an error" do
|
||||
|
||||
@@ -101,7 +101,10 @@ RSpec.describe Homebrew::Cmd::Bundle::DumpSubcommand do
|
||||
|
||||
before do
|
||||
ENV["HOMEBREW_BUNDLE_FILE"] = ""
|
||||
stub_formula_loader formula("mas") { url "mas-1.0" }
|
||||
stub_formula_loader formula("mas") {
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "mas-1.0"
|
||||
}
|
||||
allow_any_instance_of(Pathname).to receive(:exist?).and_return(true)
|
||||
allow(Homebrew::Bundle).to receive(:cask_installed?).and_return(true)
|
||||
allow(Cask::Caskroom).to receive(:casks).and_return([])
|
||||
|
||||
@@ -7,6 +7,7 @@ require "cmd/shared_examples/args_parse"
|
||||
RSpec.describe Homebrew::Cmd::Home do
|
||||
let(:testballhome) do
|
||||
formula("testballhome") do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
homepage "https://brew.sh/testballhome"
|
||||
url "https://brew.sh/testballhome-1.0"
|
||||
end
|
||||
|
||||
@@ -13,9 +13,11 @@ RSpec.describe Homebrew::Cmd::InstallCmd do
|
||||
|
||||
it "prints a formula dry-run plan when asking" do
|
||||
added = formula("added") do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "https://brew.sh/added-1.0.tar.gz"
|
||||
end
|
||||
changed = formula("changed") do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "https://brew.sh/changed-2.0.tar.gz"
|
||||
end
|
||||
added_installer = FormulaInstaller.new(added)
|
||||
@@ -39,6 +41,7 @@ RSpec.describe Homebrew::Cmd::InstallCmd do
|
||||
|
||||
it "skips ask input when asking for only requested formulae" do
|
||||
formula = formula("testball") do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "https://brew.sh/testball-0.1.tar.gz"
|
||||
end
|
||||
formula_installer = FormulaInstaller.new(formula)
|
||||
@@ -60,9 +63,11 @@ RSpec.describe Homebrew::Cmd::InstallCmd do
|
||||
|
||||
it "uses the requested action when asking for formulae with dependencies" do
|
||||
formula = formula("changed") do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "https://brew.sh/changed-2.0.tar.gz"
|
||||
end
|
||||
dependency = formula("dependency") do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "https://brew.sh/dependency-1.0.tar.gz"
|
||||
end
|
||||
formula_installer = FormulaInstaller.new(formula)
|
||||
@@ -261,7 +266,10 @@ RSpec.describe Homebrew::Cmd::InstallCmd do
|
||||
it "prints an ask mode environment hint when installing formulae" do
|
||||
cmd = klass.new(["testball"])
|
||||
download_queue = instance_double(Homebrew::DownloadQueue, fetch: nil, shutdown: nil)
|
||||
formula = formula("testball") { url "https://brew.sh/testball-0.1.tar.gz" }
|
||||
formula = formula("testball") do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "https://brew.sh/testball-0.1.tar.gz"
|
||||
end
|
||||
formula_installer = FormulaInstaller.new(formula)
|
||||
dependants = Homebrew::Upgrade::Dependents.new(upgradeable: [], pinned: [], skipped: [])
|
||||
|
||||
@@ -386,7 +394,10 @@ RSpec.describe Homebrew::Cmd::InstallCmd do
|
||||
it "prints a shared fetch heading and correct upgrade count", :cask do
|
||||
cmd = klass.new(["codex"])
|
||||
download_queue = instance_double(Homebrew::DownloadQueue, fetch: nil, shutdown: nil)
|
||||
formula = formula("testball_bottle") { url "https://brew.sh/testball_bottle-0.1.tar.gz" }
|
||||
formula = formula("testball_bottle") do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "https://brew.sh/testball_bottle-0.1.tar.gz"
|
||||
end
|
||||
formula_installer = instance_double(FormulaInstaller, formula:)
|
||||
cask = Cask::CaskLoader.load(cask_path("local-caffeine"))
|
||||
installer = instance_double(Cask::Installer, enqueue_downloads: nil, source_download_requires_pre_fetch?: false)
|
||||
|
||||
@@ -46,7 +46,10 @@ RSpec.describe Homebrew::Cmd::Reinstall do
|
||||
|
||||
it "asks for casks before shared prefetch when reinstalling formulae and casks" do
|
||||
cmd = klass.new(["--ask", "testball", "local-caffeine"])
|
||||
formula = formula("testball") { url "https://brew.sh/testball-0.1.tar.gz" }
|
||||
formula = formula("testball") do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "https://brew.sh/testball-0.1.tar.gz"
|
||||
end
|
||||
formula_installer = FormulaInstaller.new(formula)
|
||||
dependants = Homebrew::Upgrade::Dependents.new(upgradeable: [], pinned: [], skipped: [])
|
||||
cask = Cask::CaskLoader.load(cask_path("local-caffeine"))
|
||||
|
||||
@@ -40,6 +40,7 @@ RSpec.describe DescriptionCacheStore do
|
||||
describe "#update_from_formula_names!" do
|
||||
it "sets the formulae descriptions" do
|
||||
f = formula do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "url-1"
|
||||
desc "desc"
|
||||
end
|
||||
|
||||
@@ -11,6 +11,7 @@ RSpec.describe Homebrew::DevCmd::Bump do
|
||||
let(:klass) { Homebrew::DevCmd::Bump }
|
||||
let(:f_basic) do
|
||||
formula("basic_formula") do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
desc "Basic formula"
|
||||
url "https://brew.sh/test-1.2.3.tgz"
|
||||
end
|
||||
|
||||
@@ -8,6 +8,7 @@ RSpec.describe Language::Java do
|
||||
|
||||
let(:f) do
|
||||
formula("openjdk") do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "openjdk"
|
||||
version "15.0.1"
|
||||
end
|
||||
|
||||
@@ -15,6 +15,7 @@ RSpec.describe Language::Node do
|
||||
|
||||
it "calls prepend_path when node formula exists only during the first call" do
|
||||
node = formula "node" do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "node-test-v1.0"
|
||||
end
|
||||
stub_formula_loader(node)
|
||||
|
||||
@@ -8,7 +8,12 @@ RSpec.describe Messages do
|
||||
let(:klass) { Messages }
|
||||
|
||||
let(:messages) { klass.new }
|
||||
let(:test_formula) { formula("foo") { url("https://brew.sh/foo-0.1.tgz") } }
|
||||
let(:test_formula) do
|
||||
formula("foo") do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url("https://brew.sh/foo-0.1.tgz")
|
||||
end
|
||||
end
|
||||
let(:elapsed_time) { 1.1 }
|
||||
|
||||
describe "#record_caveats" do
|
||||
@@ -56,7 +61,12 @@ RSpec.describe Messages do
|
||||
end
|
||||
|
||||
context "when package_count is greater than one and caveats are present" do
|
||||
let(:test_formula2) { formula("bar") { url("https://brew.sh/bar-0.1.tgz") } }
|
||||
let(:test_formula2) do
|
||||
formula("bar") do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url("https://brew.sh/bar-0.1.tgz")
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
messages.record_caveats(test_formula.name, "Zsh completions were installed")
|
||||
|
||||
@@ -184,7 +184,10 @@ RSpec.describe Resource do
|
||||
end
|
||||
|
||||
it "sets its owner to be the patches' owner" do
|
||||
resource.patch(:p1) { url "file:///my.patch" }
|
||||
resource.patch(:p1) do
|
||||
T.bind(self, Resource::Patch)
|
||||
url "file:///my.patch"
|
||||
end
|
||||
resource.owner = owner
|
||||
resource.patches.each do |p|
|
||||
expect(p.resource.owner).to eq(owner)
|
||||
|
||||
@@ -13,7 +13,7 @@ module Test
|
||||
sig {
|
||||
params(
|
||||
name: String, path: T.nilable(Pathname), spec: Symbol, alias_path: T.nilable(Pathname),
|
||||
tap: T.nilable(Tap), block: T.nilable(T.proc.bind(Formula).void)
|
||||
tap: T.nilable(Tap), block: T.nilable(T.proc.bind(::Formula).void)
|
||||
).returns(::Formula)
|
||||
}
|
||||
def formula(name = "formula_name", path: nil, spec: :stable, alias_path: nil, tap: nil, &block)
|
||||
@@ -23,6 +23,7 @@ module Test
|
||||
|
||||
# Use a stubbed {Formulary::FormulaLoader} to make a given formula be found
|
||||
# when loading from {Formulary} with `ref`.
|
||||
sig { params(formula: ::Formula, ref: T.nilable(T.any(String, Pathname)), call_original: T::Boolean).void }
|
||||
def stub_formula_loader(formula, ref = formula.full_name, call_original: false)
|
||||
allow(Formulary).to receive(:loader_for).and_call_original if call_original
|
||||
|
||||
|
||||
@@ -32,20 +32,26 @@ RSpec.describe Homebrew::TestBot::Formulae do
|
||||
|
||||
describe "#annotate_added_dependencies" do
|
||||
it "writes a warning annotation for the new recursive dependency impact" do
|
||||
T.bind(self, T.untyped)
|
||||
|
||||
formula = formula("foo") do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "foo-1.0"
|
||||
depends_on "existing"
|
||||
depends_on "bar"
|
||||
end
|
||||
existing = formula("existing") { url "existing-1.0" }
|
||||
existing = formula("existing") do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "existing-1.0"
|
||||
end
|
||||
bar = formula("bar") do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "bar-1.0"
|
||||
depends_on "existing"
|
||||
depends_on "baz"
|
||||
end
|
||||
baz = formula("baz") { url "baz-1.0" }
|
||||
baz = formula("baz") do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "baz-1.0"
|
||||
end
|
||||
|
||||
[existing, bar, baz].each { |f| stub_formula_loader f }
|
||||
[[bar, 1_000_000], [baz, 500_000]].each do |f, size|
|
||||
@@ -127,8 +133,8 @@ RSpec.describe Homebrew::TestBot::Formulae do
|
||||
it "restores bottled config with InstallRenamed handling" do
|
||||
Dir.mktmpdir do |tmpdir|
|
||||
formula_class = Class.new(Formula)
|
||||
T.unsafe(formula_class).url "foo-2.0"
|
||||
T.unsafe(formula_class).version "2.0"
|
||||
formula_class.url "foo-2.0"
|
||||
formula_class.version "2.0"
|
||||
f = formula_class.new("test-bot-config", Formulary.core_path("test-bot-config"), :stable)
|
||||
config_file = HOMEBREW_PREFIX/"etc/test-bot-config.conf"
|
||||
default_config_file = Pathname.new("#{config_file}.default")
|
||||
|
||||
@@ -48,8 +48,13 @@ RSpec.describe Utils::Analytics do
|
||||
end
|
||||
|
||||
describe "::report_package_event" do
|
||||
let(:f) { formula { url "foo-1.0" } }
|
||||
let(:package_name) { f.name }
|
||||
let(:f) do
|
||||
formula do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "foo-1.0"
|
||||
end
|
||||
end
|
||||
let(:package_name) { f.name }
|
||||
let(:tap_name) { f.tap.name }
|
||||
let(:on_request) { false }
|
||||
let(:options) { "--HEAD" }
|
||||
@@ -92,7 +97,12 @@ RSpec.describe Utils::Analytics do
|
||||
end
|
||||
|
||||
describe "::report_influx" do
|
||||
let(:f) { formula { url "foo-1.0" } }
|
||||
let(:f) do
|
||||
formula do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "foo-1.0"
|
||||
end
|
||||
end
|
||||
let(:package) { f.name }
|
||||
let(:tap_name) { f.tap.name }
|
||||
let(:on_request) { false }
|
||||
@@ -110,7 +120,12 @@ RSpec.describe Utils::Analytics do
|
||||
describe "::report_build_error" do
|
||||
context "when tap is installed" do
|
||||
let(:err) { BuildError.new(f, "badprg", %w[arg1 arg2], {}) }
|
||||
let(:f) { formula { url "foo-1.0" } }
|
||||
let(:f) do
|
||||
formula do
|
||||
T.bind(self, T.class_of(Formula))
|
||||
url "foo-1.0"
|
||||
end
|
||||
end
|
||||
|
||||
it "reports event if BuildError raised for a formula with a public remote repository" do
|
||||
allow_any_instance_of(Tap).to receive(:custom_remote?).and_return(false)
|
||||
|
||||
Reference in New Issue
Block a user