Skip to content

Commit

Permalink
Update Method
Browse files Browse the repository at this point in the history
  • Loading branch information
sampersand committed Jul 26, 2024
1 parent 34f9880 commit 4577dfb
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 55 deletions.
21 changes: 14 additions & 7 deletions core/method.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,16 @@
# %w[2017-03-01 2017-03-02].collect(&Date.method(:parse))
# #=> [#<Date: 2017-03-01 ((2457814j,0s,0n),+0s,2299161j)>, #<Date: 2017-03-02 ((2457815j,0s,0n),+0s,2299161j)>]
#
class Method < Object
class Method
type param_types = Array[[:req | :opt | :rest | :keyreq | :key | :keyrest | :block, Symbol] | [:rest | :keyrest | :nokey]]

def ==: (untyped other) -> bool
alias eql? ==
def hash: () -> Integer
def dup: () -> instance
def inspect: () -> String
alias to_s inspect

# <!--
# rdoc-file=proc.c
# - meth.to_proc -> proc
Expand All @@ -44,7 +51,7 @@ class Method < Object
# m.call(3) #=> 15
# m.call(20) #=> 32
#
def call: (*untyped args) -> untyped
def call: (?) -> untyped

# <!--
# rdoc-file=proc.c
Expand All @@ -62,7 +69,7 @@ class Method < Object
# g = proc {|x| x + x }
# p (f << g).call(2) #=> 16
#
def <<: (Proc g) -> Proc
def <<: (Proc::_Callable g) -> Proc

# <!-- rdoc-file=proc.c -->
# Invokes the *meth* with the specified arguments, returning the method's return
Expand Down Expand Up @@ -90,7 +97,7 @@ class Method < Object
# g = proc {|x| x + x }
# p (f >> g).call(2) #=> 8
#
def >>: (Proc g) -> Proc
def >>: (Proc::_Callable g) -> Proc

# <!-- rdoc-file=proc.c -->
# Invokes the *meth* with the specified arguments, returning the method's return
Expand Down Expand Up @@ -161,7 +168,7 @@ class Method < Object
# m.call # => "bar"
# n = m.clone.call # => "bar"
#
def clone: () -> Method
def clone: () -> instance

# <!--
# rdoc-file=proc.c
Expand Down Expand Up @@ -194,7 +201,7 @@ class Method < Object
# proc3 = proc2.call(:y, :z) #=> #<Proc>
# proc3.call(:a) #=> [:x, :y, :z, :a]
#
def curry: (?Integer arity) -> Proc
def curry: (?int? arity) -> Proc

# <!--
# rdoc-file=proc.c
Expand Down Expand Up @@ -273,7 +280,7 @@ class Method < Object
# Returns the Ruby source filename and line number containing this method or nil
# if this method was not defined in Ruby (i.e. native).
#
def source_location: () -> [ String, Integer ]?
def source_location: () -> [String, Integer]?

# <!--
# rdoc-file=proc.c
Expand Down
2 changes: 1 addition & 1 deletion lib/rbs/test/type_check.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def method_call(method_name, method_type, call, errors:)
# Block is given, but not yielded
end
else
if call.block_given
if call.block_given && !method_type.type.is_a?(Types::UntypedFunction)
errors << Errors::UnexpectedBlockError.new(klass: self_class, method_name: method_name, method_type: method_type)
end
end
Expand Down
186 changes: 139 additions & 47 deletions test/stdlib/Method_test.rb
Original file line number Diff line number Diff line change
@@ -1,89 +1,181 @@
require_relative "test_helper"
require_relative 'test_helper'

class MethodTest < StdlibTest
target Method
class MethodInstanceTest < Test::Unit::TestCase
include TestHelper

class Foo
def foo
end
testing '::Method'

def foo_with_args(*, **)
end
def self.takes_anything(*, **, &b)
:hello
end

def foo_with_many_args(x, y=42, *other, k_x:, k_y: 42, **k_other, &b)
end
METHOD = singleton_method(:takes_anything)

def foo_with_arg_and_rest(x, *)
def test_op_eq(method: :==)
with_untyped.and METHOD do |untyped|
assert_send_type '(untyped) -> bool',
METHOD, method, untyped
end
end

class Bar < Foo
def foo
end
def test_eql?
test_op_eq(method: :eql?)
end

def test_to_proc
Foo.new.method(:foo).to_proc
def test_hash
assert_send_type '() -> Integer',
METHOD, :hash
end

def test_call
Foo.new.method(:foo).call
Foo.new.method(:foo_with_args).call(1)
end
def test_dup
omit_if RUBY_VERSION < '3.4'

def test_lshift
f = Foo.new.method(:foo_with_args)
g = proc { }
f << g
assert_send_type '() -> Method',
METHOD, :dup
end

def test_triple_equal
f = Foo.new.method(:foo_with_args)
f === 1
def test_inspect(method: :inspect)
assert_send_type '() -> String',
METHOD, method
end

def test_rshift
f = Foo.new.method(:foo_with_args)
g = proc { }
f >> g
def test_to_s
test_inspect(method: :to_s)
end

def test_to_proc
assert_send_type '() -> Proc',
METHOD, :to_proc
end

def test_square_bracket
Foo.new.method(:foo_with_args)[1]
def test_call(method: :call)
assert_send_type '(?) -> untyped',
METHOD, method, :takes_anything, 1, 2i, foo: :three do end
end

def test_op_lsh
callable = BlankSlate.new
def callable.call(*, **, &b) = 1r

with proc{}, lambda{}, method(:p), callable do |other|
assert_send_type '(Proc::_Callable) -> Proc',
METHOD, :<<, other
end
end

def test_op_eqq
test_call(method: :===)
end

def test_op_rsh
callable = BlankSlate.new
def callable.call(*, **, &b) = 1r

with proc{}, lambda{}, method(:p), callable do |other|
assert_send_type '(Proc::_Callable) -> Proc',
METHOD, :>>, other
end
end

def test_op_aref
test_call(method: :[])
end

def test_arity
Foo.new.method(:foo_with_args).arity
arities = BlankSlate.new.__with_object_methods(:method)
def arities.no_args = nil
def arities.any_amount(*) = nil
def arities.all(*, **, &x) = nil

assert_send_type '() -> Integer',
arities.method(:no_args), :arity
assert_send_type '() -> Integer',
arities.method(:any_amount), :arity
assert_send_type '() -> Integer',
arities.method(:all), :arity
end

def test_clone
Foo.new.method(:foo_with_args).clone
assert_send_type '() -> Method',
METHOD, :clone
end

def test_curry
f = Foo.new.method(:foo)
f.curry
f.curry(0)
assert_send_type '() -> Proc',
METHOD, :curry

with_int.and_nil do |arity|
assert_send_type '(int?) -> Proc',
METHOD, :curry, arity
end
end

def test_name
assert_send_type '() -> Symbol',
METHOD, :name
end

def test_original_name
Foo.new.method(:foo).original_name
assert_send_type '() -> Symbol',
METHOD, :original_name
end

def test_owner
assert_send_type '() -> (Class | Module)',
METHOD, :owner
end

def test_parameters
Foo.new.method(:foo).parameters
Foo.new.method(:foo_with_args).parameters
Foo.new.method(:foo_with_many_args).parameters
Foo.new.method(:foo_with_arg_and_rest).parameters
params = BlankSlate.new.__with_object_methods(:method)
def params.leading_optional(a=3, b=4, c, d: 3) end
def params.all_params(a, b=3, *c, d: 1, e:, **f, &g) end
def params.only_ddd(...) end
def params.tailing_ddd(a, ...) end
def params.no_kwargs(**nil) end
def params.shorthand(*, **, &x) end

assert_send_type '() -> ::Method::param_types',
params.method(:leading_optional), :parameters
assert_send_type '() -> ::Method::param_types',
params.method(:all_params), :parameters
assert_send_type '() -> ::Method::param_types',
params.method(:only_ddd), :parameters
assert_send_type '() -> ::Method::param_types',
params.method(:tailing_ddd), :parameters
assert_send_type '() -> ::Method::param_types',
params.method(:no_kwargs), :parameters
assert_send_type '() -> ::Method::param_types',
params.method(:shorthand), :parameters
end

def test_receiver
assert_send_type '() -> untyped',
METHOD, :receiver
end

def test_source_location
Foo.new.method(:foo).source_location
method(:puts).source_location
assert_send_type '() -> [String, Integer]',
METHOD, :source_location
assert_send_type '() -> nil',
method(:__id__), :source_location
end

def test_super_method
Foo.new.method(:foo).super_method
Bar.new.method(:foo).super_method
has_super = Object.new
def has_super.display = nil

no_super = BlankSlate.new.__with_object_methods(:method)
def no_super.has_no_super_method = nil

assert_send_type '() -> Method',
has_super.method(:display), :super_method

assert_send_type '() -> nil',
no_super.method(:has_no_super_method), :super_method
end

def test_unbind
assert_send_type '() -> UnboundMethod',
METHOD, :unbind
end
end

0 comments on commit 4577dfb

Please sign in to comment.