Add tests

This commit is contained in:
Douglas Eichelberger 2024-03-13 21:55:59 -07:00
parent 5888cd8607
commit 68cce23e15
3 changed files with 117 additions and 17 deletions

View File

@ -539,7 +539,7 @@ class Homebrew::CLI::Args
sig { returns(T::Boolean) }
def online?; end
sig { returns(T.nilable(String)) }
sig { returns(T.nilable(T::Array[String])) }
def only; end
sig { returns(T.nilable(T::Array[String])) }

View File

@ -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
@ -25,7 +20,13 @@ module Tapioca
# 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
@ -35,18 +36,29 @@ module Tapioca
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)
@ -57,12 +69,6 @@ module Tapioca
"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

View File

@ -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