Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dduugg authored and apainintheneck committed Mar 19, 2024
1 parent 457e989 commit 43b31dc
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 17 deletions.
2 changes: 1 addition & 1 deletion Library/Homebrew/sorbet/rbi/dsl/homebrew/cli/args.rbi

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 22 additions & 16 deletions Library/Homebrew/sorbet/tapioca/compilers/args.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@

require_relative "../../../global"

# require all the commands
["cmd", "dev-cmd"].each do |dir|
Dir[File.join(__dir__, "../../../#{dir}", "*.rb")].each { require(_1) }
end

module Tapioca
module Compilers
class Args < Tapioca::Dsl::Compiler
Expand All @@ -25,7 +20,13 @@ class Args < Tapioca::Dsl::Compiler
# rubocop:enable Style/MutableConstant

sig { override.returns(T::Enumerable[T.class_of(Homebrew::CLI::Args)]) }
def self.gather_constants = [Homebrew::CLI::Args]
def self.gather_constants
# require all the commands to ensure the _arg methods are defined
["cmd", "dev-cmd"].each do |dir|
Dir[File.join(__dir__, "../../../#{dir}", "*.rb")].each { require(_1) }
end
[Homebrew::CLI::Args]
end

sig { override.void }
def decorate
Expand All @@ -35,18 +36,29 @@ def decorate

parser = Homebrew.method(args_method_name).call
comma_array_methods = comma_arrays(parser)
args = parser.instance_variable_get(:@args)
args.instance_variable_get(:@table).each do |method_name, value|
args_table(parser).each do |method_name, value|
# some args are used in multiple commands (this is ok as long as they have the same type)
next if klass.nodes.any? { T.cast(_1, RBI::Method).name == method_name } || value == []
next if klass.nodes.any? { T.cast(_1, RBI::Method).name.to_sym == method_name }

return_type = get_return_type(method_name, value, comma_array_methods)
klass.create_method(method_name, return_type:)
klass.create_method(method_name.to_s, return_type:)
end
end
end
end

sig { params(parser: Homebrew::CLI::Parser).returns(T::Hash[Symbol, T.untyped]) }
def args_table(parser)
# we exclude non-args from the table, such as :named and :remaining
parser.instance_variable_get(:@args).instance_variable_get(:@table).except(:named, :remaining)
end

sig { params(parser: Homebrew::CLI::Parser).returns(T::Array[Symbol]) }
def comma_arrays(parser)
parser.instance_variable_get(:@non_global_processed_options)
.filter_map { |k, v| parser.option_to_name(k).to_sym if v == :comma_array }
end

sig { params(method_name: Symbol, value: T.untyped, comma_array_methods: T::Array[Symbol]).returns(String) }
def get_return_type(method_name, value, comma_array_methods)
if comma_array_methods.include?(method_name)
Expand All @@ -57,12 +69,6 @@ def get_return_type(method_name, value, comma_array_methods)
"T.nilable(String)"
end
end

sig { params(parser: Homebrew::CLI::Parser).returns(T::Array[Symbol]) }
def comma_arrays(parser)
parser.instance_variable_get(:@non_global_processed_options)
.filter_map { |k, v| parser.option_to_name(k).to_sym if v == :comma_array }
end
end
end
end
94 changes: 94 additions & 0 deletions Library/Homebrew/test/sorbet/tapioca/compilers/args_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# frozen_string_literal: true

# require 'tapioca'
require "tapioca/dsl"
require_relative "../../../../sorbet/tapioca/compilers/args"

RSpec.describe Tapioca::Compilers::Args do
let(:compiler) { described_class.new(Tapioca::Dsl::Pipeline.new(requested_constants: []), RBI::Tree.new, Homebrew) }
let(:list_parser) do
require "cmd/list"
Homebrew.list_args
end
# good testing candidate, bc it has multiple for each of switch, flag, and comma_array args:
let(:update_python_resources_parser) do
require "dev-cmd/update-python-resources"
Homebrew.update_python_resources_args
end

describe "#args_table" do
it "returns a mapping of list args to default values" do
expect(compiler.args_table(list_parser)).to eq({
"1?": false,
cask?: false,
casks?: false,
d?: false,
debug?: false,
formula?: false,
formulae?: false,
full_name?: false,
h?: false,
help?: false,
l?: false,
multiple?: false,
pinned?: false,
q?: false,
quiet?: false,
r?: false,
t?: false,
v?: false,
verbose?: false,
versions?: false,
})
end

it "rreturns a mapping of update-python-resources args to default values" do
expect(compiler.args_table(update_python_resources_parser)).to eq({
d?: false,
debug?: false,
exclude_packages: nil,
extra_packages: nil,
h?: false,
help?: false,
ignore_non_pypi_packages?: false,
install_dependencies?: false,
p?: false,
package_name: nil,
print_only?: false,
q?: false,
quiet?: false,
s?: false,
silent?: false,
v?: false,
verbose?: false,
version: nil,
})
end
end

describe "#comma_arrays" do
it "returns an empty list when there are no comma_array args" do
expect(compiler.comma_arrays(list_parser)).to eq([])
end

it "returns the comma_array args when they exist" do
expect(compiler.comma_arrays(update_python_resources_parser)).to eq([:extra_packages, :exclude_packages])
end
end

describe "#get_return_type" do
let(:comma_arrays) { compiler.comma_arrays(update_python_resources_parser) }

it "returns the correct type for switches" do
expect(compiler.get_return_type(:silent?, false, comma_arrays)).to eq("T::Boolean")
end

it "returns the correct type for flags" do
expect(compiler.get_return_type(:package_name, nil, comma_arrays)).to eq("T.nilable(String)")
end

it "returns the correct type for comma_arrays" do
expect(compiler.get_return_type(:extra_packages, nil, comma_arrays)).to eq("T.nilable(T::Array[String])")
end
end
end

0 comments on commit 43b31dc

Please sign in to comment.