Skip to content

Commit 76e1c77

Browse files
increase coverage
1 parent 3f29a2d commit 76e1c77

File tree

5 files changed

+116
-20
lines changed

5 files changed

+116
-20
lines changed

temporalio/lib/temporalio/worker/activity_executor/fiber.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def initialize_activity(defn)
2323
end
2424

2525
# @see ActivityExecutor.initialize_activity
26-
def execute_activity(_defn, &)
26+
def execute_activity(defn, &) # rubocop:disable Lint/UnusedMethodArgument
2727
::Fiber.schedule(&)
2828
end
2929

temporalio/lib/temporalio/worker/activity_executor/thread_pool.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def initialize(thread_pool = Worker::ThreadPool.default) # rubocop:disable Lint/
2020
end
2121

2222
# @see ActivityExecutor.execute_activity
23-
def execute_activity(_defn, &)
23+
def execute_activity(defn, &) # rubocop:disable Lint/UnusedMethodArgument
2424
@thread_pool.execute(&)
2525
end
2626

temporalio/test/support/sig_applicator.rb

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ def register_summary_hook!
142142
def raise_instrumentation_errors!(errors)
143143
return if errors.empty?
144144

145-
summary = +"SigApplicator: #{errors.size} methods could not be instrumented:\n"
145+
summary = "SigApplicator: #{errors.size} methods could not be instrumented:\n"
146146
errors.each { |error| summary << " #{error}\n" }
147147
raise summary.chomp
148148
end
@@ -169,7 +169,7 @@ def apply_scope(node, errors)
169169
case child
170170
when RBI::Method
171171
target = child.is_singleton ? klass.singleton_class : klass
172-
result = apply_method_sig(target, class_name, child, errors)
172+
result = apply_method_sig(target, class_name, child, errors, sig_eval_scope: klass)
173173
if result == :skipped
174174
skipped += 1
175175
elsif result
@@ -179,7 +179,14 @@ def apply_scope(node, errors)
179179
child.nodes.each do |scn|
180180
next unless scn.is_a?(RBI::Method)
181181

182-
result = apply_method_sig(klass.singleton_class, class_name, scn, errors, class_method: true)
182+
result = apply_method_sig(
183+
klass.singleton_class,
184+
class_name,
185+
scn,
186+
errors,
187+
class_method: true,
188+
sig_eval_scope: klass
189+
)
183190
if result == :skipped
184191
skipped += 1
185192
elsif result
@@ -191,11 +198,12 @@ def apply_scope(node, errors)
191198
[applied, skipped]
192199
end
193200

194-
def apply_method_sig(target, class_name, method_node, errors, class_method: false)
201+
def apply_method_sig(target, class_name, method_node, errors, class_method: false, sig_eval_scope: target)
195202
return false if method_node.sigs.empty?
196203

197204
method_name = method_node.name.to_sym
198-
separator = class_method || method_node.is_singleton ? '.' : '#'
205+
singleton_method = class_method || method_node.is_singleton
206+
separator = singleton_method ? '.' : '#'
199207
full_name = "#{class_name}#{separator}#{method_name}"
200208

201209
return :skipped if SKIP_METHODS.include?(full_name)
@@ -214,10 +222,11 @@ def apply_method_sig(target, class_name, method_node, errors, class_method: fals
214222
method_node.sigs.each do |sig|
215223
# RBI::Sig#string serializes back to valid T::Sig DSL source
216224
sig_source = sig.string
217-
# Anonymous block params (def foo(&)) need `"&":` instead of `block:`
218-
sig_source = rewrite_block_param(sig_source) if has_anon_block
225+
# Anonymous block params (def foo(&)) need `"&":` instead of the RBI
226+
# block parameter name.
227+
sig_source = rewrite_block_param(sig_source, method_node, sig) if has_anon_block
219228
begin
220-
target.class_eval(sig_source)
229+
apply_sig_source(sig_eval_scope, target, sig_source, singleton_method)
221230
target.send(:define_method, method_name, original)
222231

223232
# Force eager sig validation so mismatches are caught now rather than
@@ -240,10 +249,28 @@ def anonymous_block?(method)
240249
block_param && (block_param[1].nil? || block_param[1] == :&)
241250
end
242251

243-
# Rewrites `block: <type>` to `"&": <type>` in a sig source string
244-
# so sorbet-runtime matches the anonymous block parameter.
245-
def rewrite_block_param(sig_source)
246-
sig_source.sub(/\bblock:\s/, '"&": ')
252+
def apply_sig_source(sig_eval_scope, target, sig_source, singleton_method)
253+
if singleton_method
254+
sig_eval_scope.class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
255+
class << self
256+
#{sig_source} # #{sig_source}
257+
end
258+
RUBY
259+
else
260+
target.class_eval(sig_source)
261+
end
262+
end
263+
264+
# Rewrites the RBI block parameter name to `"&": <type>` so
265+
# sorbet-runtime matches the anonymous block parameter.
266+
def rewrite_block_param(sig_source, method_node, sig)
267+
block_param_name =
268+
method_node.params.find { |param| param.is_a?(RBI::BlockParam) }&.name ||
269+
sig.params.find { |param| param.type&.include?('T.proc') }&.name
270+
271+
return sig_source unless block_param_name
272+
273+
sig_source.sub(/\b#{Regexp.escape(block_param_name)}:\s/, '"&": ')
247274
end
248275

249276
# Determines whether a method should be skipped for sig application based

temporalio/test/support/sig_applicator_test.rb

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,18 @@ def foo(&blk); end # rubocop:disable Naming/BlockForwarding
5353
# --- Anonymous block sig rewriting ---
5454

5555
def test_rewrite_block_param
56-
input = 'sig { params(name: String, block: T.proc.void).void }'
56+
input = 'sig { params(name: String, blk: T.proc.void).void }'
5757
expected = 'sig { params(name: String, "&": T.proc.void).void }'
58-
assert_equal expected, rewrite_block_param(input)
58+
method_node = parse_method(
59+
'class X; sig { params(name: String, blk: T.proc.void).void }; def foo(name, &blk); end; end'
60+
)
61+
assert_equal expected, rewrite_block_param(input, method_node, method_node.sigs.first)
5962
end
6063

6164
def test_rewrite_block_param_no_block
6265
input = 'sig { params(name: String).void }'
63-
assert_equal input, rewrite_block_param(input)
66+
method_node = parse_method('class X; sig { params(name: String).void }; def foo(name); end; end')
67+
assert_equal input, rewrite_block_param(input, method_node, method_node.sigs.first)
6468
end
6569

6670
# --- Setter / unnamed param skips ---
@@ -150,10 +154,61 @@ def self.foo(value); end
150154
assert_includes error.message, 'Support::SigApplicatorApplyAllTest.foo:'
151155
ensure
152156
parser.send(:define_method, :parse_file, original_parse_file)
153-
Support.send(:remove_const, :SigApplicatorApplyAllTest) if Support.const_defined?(:SigApplicatorApplyAllTest, false)
157+
if Support.const_defined?(:SigApplicatorApplyAllTest, false)
158+
Support.send(:remove_const, :SigApplicatorApplyAllTest)
159+
end
154160
Object.send(:remove_const, :ZZZSigApplicatorTest) if Object.const_defined?(:ZZZSigApplicatorTest)
155161
end
156162

163+
def test_apply_method_sig_supports_anonymous_block_with_named_rbi_block
164+
klass = Class.new do
165+
extend T::Sig
166+
167+
def foo(&); end
168+
end
169+
method_node = parse_method(
170+
'class X; sig { params(blk: T.proc.void).void }; def foo(&blk); end; end'
171+
)
172+
errors = []
173+
174+
assert apply_method_sig(klass, 'X', method_node, errors, sig_eval_scope: klass)
175+
assert_empty errors
176+
end
177+
178+
def test_apply_method_sig_resolves_singleton_sig_constants_in_class_namespace
179+
klass = Class.new do
180+
extend T::Sig
181+
182+
class << self
183+
extend T::Sig
184+
end
185+
186+
def self.foo(value); end
187+
end
188+
klass.const_set(:Inner, Data.define(:value))
189+
Support.const_set(:SigApplicatorSingletonScopeTest, klass)
190+
method_node = parse_method(<<~RBI)
191+
class Support::SigApplicatorSingletonScopeTest
192+
sig { params(value: Inner).void }
193+
def self.foo(value); end
194+
end
195+
RBI
196+
errors = []
197+
198+
assert apply_method_sig(
199+
klass.singleton_class,
200+
'Support::SigApplicatorSingletonScopeTest',
201+
method_node,
202+
errors,
203+
sig_eval_scope: klass
204+
)
205+
assert_empty errors
206+
ensure
207+
if Support.const_defined?(:SigApplicatorSingletonScopeTest, false)
208+
Support.send(:remove_const, :SigApplicatorSingletonScopeTest)
209+
end
210+
end
211+
157212
private
158213

159214
def parse_method(source)
@@ -166,8 +221,19 @@ def skip_method?(original, method_node, method_name)
166221
SigApplicator.send(:skip_method?, original, method_node, method_name)
167222
end
168223

169-
def rewrite_block_param(sig_source)
170-
SigApplicator.send(:rewrite_block_param, sig_source)
224+
def rewrite_block_param(sig_source, method_node, sig)
225+
SigApplicator.send(:rewrite_block_param, sig_source, method_node, sig)
226+
end
227+
228+
def apply_method_sig(target, class_name, method_node, errors, sig_eval_scope:)
229+
SigApplicator.send(
230+
:apply_method_sig,
231+
target,
232+
class_name,
233+
method_node,
234+
errors,
235+
sig_eval_scope:
236+
)
171237
end
172238
end
173239
end

temporalio/test/test.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@
1717

1818
if ENV['TEMPORAL_SORBET_RUNTIME_CHECK']
1919
# Load modules that are lazy-loaded so their types can be instrumented
20+
require 'temporalio/common_enums'
2021
require 'temporalio/contrib/open_telemetry'
2122
require 'temporalio/converters/payload_codec'
2223
require 'temporalio/env_config'
2324
require 'temporalio/simple_plugin'
25+
require 'temporalio/worker/interceptor'
2426
require 'temporalio/worker/workflow_replayer'
27+
require 'temporalio/workflow'
2528

2629
require 'support/sig_applicator'
2730
SigApplicator.apply_all!

0 commit comments

Comments
 (0)