@@ -403,3 +403,71 @@ def test_get_stream_id_from_track_id(self):
403403
404404 stream_id = state .get_stream_id_from_track_id ("track3" )
405405 assert stream_id is None
406+
407+ def test_map_with_bound_method (self ):
408+ """Test that map works with bound methods."""
409+ state = ParticipantsState ()
410+
411+ class Handler :
412+ def __init__ (self ):
413+ self .results = []
414+
415+ def on_participants (self , participants ):
416+ self .results .append (len (participants ))
417+
418+ handler_obj = Handler ()
419+
420+ # Subscribe with a bound method
421+ _subscription = state .map (handler_obj .on_participants )
422+
423+ # Should be called immediately
424+ assert handler_obj .results == [0 ]
425+
426+ # Add a participant
427+ p1 = models_pb2 .Participant ()
428+ p1 .user_id = "user1"
429+ p1 .track_lookup_prefix = "prefix1"
430+ state ._add_participant (p1 )
431+
432+ # Handler should be called
433+ assert handler_obj .results == [0 , 1 ]
434+
435+ # Add another participant
436+ p2 = models_pb2 .Participant ()
437+ p2 .user_id = "user2"
438+ p2 .track_lookup_prefix = "prefix2"
439+ state ._add_participant (p2 )
440+
441+ # Handler should be called again
442+ assert handler_obj .results == [0 , 1 , 2 ]
443+
444+ def test_weak_reference_cleanup_with_bound_method (self ):
445+ """Test that bound method handlers are cleaned up when object is garbage collected."""
446+ state = ParticipantsState ()
447+
448+ class Handler :
449+ def __init__ (self ):
450+ self .results = []
451+
452+ def on_participants (self , participants ):
453+ self .results .append (len (participants ))
454+
455+ handler_obj = Handler ()
456+ _subscription = state .map (handler_obj .on_participants )
457+
458+ assert handler_obj .results == [0 ]
459+ assert len (state ._map_handlers ) == 1
460+
461+ # Delete the handler object and subscription, force garbage collection
462+ del handler_obj
463+ del _subscription
464+ gc .collect ()
465+
466+ # Handler should be cleaned up
467+ p1 = models_pb2 .Participant ()
468+ p1 .user_id = "user1"
469+ p1 .track_lookup_prefix = "prefix1"
470+ state ._add_participant (p1 )
471+
472+ # No handlers should remain
473+ assert len (state ._map_handlers ) == 0
0 commit comments