@@ -459,4 +459,78 @@ def test_timeout_in_trap_handler
459459 trap ( signal , original_handler )
460460 end
461461 end
462+
463+ # Tests for fiber scheduler delegation (added for fiber-scheduler-compatibility)
464+ if Fiber . respond_to? ( :current_scheduler )
465+ # Stubs Fiber.current_scheduler for the duration of the block, then restores it.
466+ def with_mock_scheduler ( mock )
467+ original = Fiber . method ( :current_scheduler )
468+ Fiber . define_singleton_method ( :current_scheduler ) { mock }
469+ begin
470+ yield
471+ ensure
472+ Fiber . define_singleton_method ( :current_scheduler , original )
473+ end
474+ end
475+
476+ def test_fiber_scheduler_delegates_to_timeout_after
477+ received = nil
478+ mock = Object . new
479+ mock . define_singleton_method ( :timeout_after ) do |sec , exc , msg , &blk |
480+ received = [ sec , exc , msg ]
481+ blk . call ( sec )
482+ end
483+
484+ with_mock_scheduler ( mock ) do
485+ assert_equal :ok , Timeout . timeout ( 5 ) { :ok }
486+ end
487+
488+ assert_equal 5 , received [ 0 ]
489+ assert_instance_of Timeout ::ExitException , received [ 1 ] , "scheduler should receive an ExitException instance when no klass given"
490+ assert_equal "execution expired" , received [ 2 ]
491+ end
492+
493+ def test_fiber_scheduler_delegates_to_timeout_after_with_custom_exception
494+ custom_error = Class . new ( StandardError )
495+ received = nil
496+ mock = Object . new
497+ mock . define_singleton_method ( :timeout_after ) do |sec , exc , msg , &blk |
498+ received = [ sec , exc , msg ]
499+ blk . call ( sec )
500+ end
501+
502+ with_mock_scheduler ( mock ) do
503+ assert_equal :ok , Timeout . timeout ( 5 , custom_error , "custom message" ) { :ok }
504+ end
505+
506+ assert_equal [ 5 , custom_error , "custom message" ] , received
507+ end
508+
509+ def test_fiber_scheduler_timeout_raises_timeout_error
510+ mock = Object . new
511+ mock . define_singleton_method ( :timeout_after ) do |sec , exc , msg , &blk |
512+ raise exc # simulate timeout firing
513+ end
514+
515+ with_mock_scheduler ( mock ) do
516+ assert_raise ( Timeout ::Error ) do
517+ Timeout . timeout ( 5 ) { :should_not_reach }
518+ end
519+ end
520+ end
521+
522+ def test_fiber_scheduler_timeout_raises_custom_error
523+ custom_error = Class . new ( StandardError )
524+ mock = Object . new
525+ mock . define_singleton_method ( :timeout_after ) do |sec , exc , msg , &blk |
526+ raise exc , msg
527+ end
528+
529+ with_mock_scheduler ( mock ) do
530+ assert_raise_with_message ( custom_error , "custom message" ) do
531+ Timeout . timeout ( 5 , custom_error , "custom message" ) { :should_not_reach }
532+ end
533+ end
534+ end
535+ end
462536end
0 commit comments