@@ -323,231 +323,20 @@ def test_iter_notifications_survives_overflow(
323323 assert first .kind .name == "SESSIONS_CHANGED"
324324
325325
326- class SetClientFlagsCase (t .NamedTuple ):
327- """Fixture for refresh-client flag construction."""
328-
329- test_id : str
330- kwargs : dict [str , t .Any ]
331- expected_flags : set [str ]
332- expect_run : bool
333-
334-
335- @pytest .mark .parametrize (
336- "case" ,
337- [
338- SetClientFlagsCase (
339- test_id = "enable_no_output_with_pause" ,
340- kwargs = {"no_output" : True , "pause_after" : 1 },
341- expected_flags = {"no-output" , "pause-after=1" },
342- expect_run = True ,
343- ),
344- SetClientFlagsCase (
345- test_id = "disable_no_output_clear_pause" ,
346- kwargs = {"no_output" : False , "pause_after" : 0 },
347- expected_flags = {"!no-output" , "!pause-after" },
348- expect_run = True ,
349- ),
350- SetClientFlagsCase (
351- test_id = "wait_exit_and_read_only" ,
352- kwargs = {"wait_exit" : True , "read_only" : True },
353- expected_flags = {"wait-exit" , "read-only" },
354- expect_run = True ,
355- ),
356- SetClientFlagsCase (
357- test_id = "clear_wait_exit" ,
358- kwargs = {"wait_exit" : False },
359- expected_flags = {"!wait-exit" },
360- expect_run = True ,
361- ),
362- SetClientFlagsCase (
363- test_id = "toggle_misc_flags" ,
364- kwargs = {"ignore_size" : True , "active_pane" : False },
365- expected_flags = {"ignore-size" , "!active-pane" },
366- expect_run = True ,
367- ),
368- SetClientFlagsCase (
369- test_id = "noop_when_no_flags" ,
370- kwargs = {},
371- expected_flags = set (),
372- expect_run = False ,
373- ),
374- ],
375- ids = lambda c : c .test_id ,
376- )
377- def test_set_client_flags_builds_refresh_client (case : SetClientFlagsCase ) -> None :
378- """set_client_flags should call refresh-client with correct flag string."""
379- engine = ControlModeEngine (start_threads = False )
380- calls : list [tuple [str , tuple [str , ...], tuple [str , ...]]] = []
381-
382- class DummyCmd :
383- stdout : t .ClassVar [list [str ]] = []
384- stderr : t .ClassVar [list [str ]] = []
385- returncode : t .ClassVar [int ] = 0
386-
387- def fake_run (
388- cmd : str ,
389- cmd_args : t .Sequence [str | int ] | None = None ,
390- server_args : t .Sequence [str | int ] | None = None ,
391- timeout : float | None = None ,
392- ) -> DummyCmd :
393- cmd_args_tuple = tuple (str (a ) for a in (cmd_args or ()))
394- server_args_tuple = tuple (str (a ) for a in (server_args or ()))
395- calls .append ((cmd , cmd_args_tuple , server_args_tuple ))
396- return DummyCmd ()
397-
398- engine .run = fake_run # type: ignore[assignment]
399-
400- engine .set_client_flags (** case .kwargs )
401-
402- if not case .expect_run :
403- assert calls == []
404- return
405-
406- assert len (calls ) == 1
407- cmd , cmd_args , server_args = calls [0 ]
408- assert cmd == "refresh-client"
409- assert cmd_args and cmd_args [0 ] == "-f"
410- flags_str = cmd_args [1 ] if len (cmd_args ) > 1 else ""
411- for flag in case .expected_flags :
412- assert flag in flags_str
413- assert server_args == ()
414-
415-
416326def test_set_client_flags_rejects_negative_pause () -> None :
417327 """pause_after must be non-negative."""
418328 engine = ControlModeEngine (start_threads = False )
419329 with pytest .raises (ValueError ):
420330 engine .set_client_flags (pause_after = - 1 )
421331
422332
423- class PaneFlowCase (t .NamedTuple ):
424- """Fixture for refresh-client -A flow control."""
425-
426- test_id : str
427- pane_id : str | int
428- state : str
429- expected_arg : str
430-
431-
432- @pytest .mark .parametrize (
433- "case" ,
434- [
435- PaneFlowCase (
436- test_id = "resume_default" ,
437- pane_id = "%1" ,
438- state = "continue" ,
439- expected_arg = "%1:continue" ,
440- ),
441- PaneFlowCase (
442- test_id = "pause_pane" ,
443- pane_id = 3 ,
444- state = "pause" ,
445- expected_arg = "3:pause" ,
446- ),
447- ],
448- ids = lambda c : c .test_id ,
449- )
450- def test_set_pane_flow_builds_refresh_client (case : PaneFlowCase ) -> None :
451- """set_pane_flow should build refresh-client -A args."""
452- engine = ControlModeEngine (start_threads = False )
453- calls : list [tuple [str , tuple [str , ...], tuple [str , ...]]] = []
454-
455- class DummyCmd :
456- stdout : t .ClassVar [list [str ]] = []
457- stderr : t .ClassVar [list [str ]] = []
458- returncode : t .ClassVar [int ] = 0
459-
460- def fake_run (
461- cmd : str ,
462- cmd_args : t .Sequence [str | int ] | None = None ,
463- server_args : t .Sequence [str | int ] | None = None ,
464- timeout : float | None = None ,
465- ) -> DummyCmd :
466- cmd_args_tuple = tuple (str (a ) for a in (cmd_args or ()))
467- server_args_tuple = tuple (str (a ) for a in (server_args or ()))
468- calls .append ((cmd , cmd_args_tuple , server_args_tuple ))
469- return DummyCmd ()
470-
471- engine .run = fake_run # type: ignore[assignment]
472-
473- engine .set_pane_flow (case .pane_id , state = case .state )
474-
475- assert calls
476- cmd , cmd_args , server_args = calls [0 ]
477- assert cmd == "refresh-client"
478- assert cmd_args == ("-A" , case .expected_arg )
479- assert server_args == ()
480-
481-
482333def test_set_pane_flow_validates_state () -> None :
483334 """Invalid flow state should raise."""
484335 engine = ControlModeEngine (start_threads = False )
485336 with pytest .raises (ValueError ):
486337 engine .set_pane_flow ("%1" , state = "bad" )
487338
488339
489- class SubscribeCase (t .NamedTuple ):
490- """Fixture for refresh-client -B subscription arguments."""
491-
492- test_id : str
493- name : str
494- what : str | None
495- format : str | None
496- expected_args : tuple [str , ...]
497-
498-
499- @pytest .mark .parametrize (
500- "case" ,
501- [
502- SubscribeCase (
503- test_id = "add_subscription" ,
504- name = "focus" ,
505- what = "%1" ,
506- format = "#{pane_active}" ,
507- expected_args = ("-B" , "focus:%1:#{pane_active}" ),
508- ),
509- SubscribeCase (
510- test_id = "remove_subscription" ,
511- name = "focus" ,
512- what = None ,
513- format = None ,
514- expected_args = ("-B" , "focus" ),
515- ),
516- ],
517- ids = lambda c : c .test_id ,
518- )
519- def test_subscribe_builds_refresh_client (case : SubscribeCase ) -> None :
520- """Subscribe should wrap refresh-client -B calls."""
521- engine = ControlModeEngine (start_threads = False )
522- calls : list [tuple [str , tuple [str , ...], tuple [str , ...]]] = []
523-
524- class DummyCmd :
525- stdout : t .ClassVar [list [str ]] = []
526- stderr : t .ClassVar [list [str ]] = []
527- returncode : t .ClassVar [int ] = 0
528-
529- def fake_run (
530- cmd : str ,
531- cmd_args : t .Sequence [str | int ] | None = None ,
532- server_args : t .Sequence [str | int ] | None = None ,
533- timeout : float | None = None ,
534- ) -> DummyCmd :
535- cmd_args_tuple = tuple (str (a ) for a in (cmd_args or ()))
536- server_args_tuple = tuple (str (a ) for a in (server_args or ()))
537- calls .append ((cmd , cmd_args_tuple , server_args_tuple ))
538- return DummyCmd ()
539-
540- engine .run = fake_run # type: ignore[assignment]
541-
542- engine .subscribe (case .name , what = case .what , fmt = case .format )
543-
544- assert calls
545- cmd , cmd_args , server_args = calls [0 ]
546- assert cmd == "refresh-client"
547- assert cmd_args == case .expected_args
548- assert server_args == ()
549-
550-
551340class ScriptedStdin :
552341 """Fake stdin that can optionally raise BrokenPipeError on write."""
553342
0 commit comments