@@ -22,6 +22,44 @@ async def empty_docket(docket: Docket, aiolib: str):
2222 await docket .cancel ("initial" )
2323
2424
25+ class RecordingConsole :
26+ def __init__ (self ) -> None :
27+ self .calls : list [tuple [tuple [object , ...], dict [str , object ]]] = []
28+
29+ def print (self , * args : object , ** kwargs : object ) -> None :
30+ self .calls .append ((args , kwargs ))
31+
32+
33+ def _stub_snapshot_docket (
34+ monkeypatch : MonkeyPatch ,
35+ snapshot_obj : DocketSnapshot ,
36+ registered : list [str ],
37+ ) -> None :
38+ class FakeDocket :
39+ def __init__ (self , name : str , url : str ) -> None :
40+ self .name = name
41+ self .url = url
42+
43+ async def __aenter__ (self ) -> "FakeDocket" :
44+ return self
45+
46+ async def __aexit__ (
47+ self ,
48+ exc_type : type [BaseException ] | None ,
49+ exc : BaseException | None ,
50+ tb : TracebackType | None ,
51+ ) -> bool :
52+ return False
53+
54+ def register_collection (self , task_path : str ) -> None :
55+ registered .append (task_path )
56+
57+ async def snapshot (self ) -> DocketSnapshot :
58+ return snapshot_obj
59+
60+ monkeypatch .setattr ("docket.cli.Docket" , FakeDocket )
61+
62+
2563async def test_snapshot_empty_docket (docket : Docket , runner : CliRunner ):
2664 """Should show an empty snapshot when no tasks are scheduled"""
2765 result = await asyncio .get_running_loop ().run_in_executor (
@@ -294,37 +332,7 @@ def test_snapshot_cli_renders_stats_without_backend(monkeypatch: MonkeyPatch):
294332 )
295333
296334 registered : list [str ] = []
297-
298- class FakeDocket :
299- def __init__ (self , name : str , url : str ) -> None :
300- self .name = name
301- self .url = url
302-
303- async def __aenter__ (self ) -> "FakeDocket" :
304- return self
305-
306- async def __aexit__ (
307- self ,
308- exc_type : type [BaseException ] | None ,
309- exc : BaseException | None ,
310- tb : TracebackType | None ,
311- ) -> bool :
312- return False
313-
314- def register_collection (self , task_path : str ) -> None :
315- registered .append (task_path )
316-
317- async def snapshot (self ) -> DocketSnapshot :
318- return snapshot_obj
319-
320- monkeypatch .setattr ("docket.cli.Docket" , FakeDocket )
321-
322- class RecordingConsole :
323- def __init__ (self ) -> None :
324- self .calls : list [tuple [tuple [object , ...], dict [str , object ]]] = []
325-
326- def print (self , * args : object , ** kwargs : object ) -> None :
327- self .calls .append ((args , kwargs ))
335+ _stub_snapshot_docket (monkeypatch , snapshot_obj , registered )
328336
329337 recorder = RecordingConsole ()
330338 monkeypatch .setattr ("docket.cli.Console" , lambda : recorder )
@@ -343,6 +351,61 @@ def print(self, *args: object, **kwargs: object) -> None:
343351 )
344352
345353
354+ def test_snapshot_cli_without_stats_skips_table (monkeypatch : MonkeyPatch ):
355+ """Calling snapshot CLI without --stats should omit the second table."""
356+ now = datetime (2023 , 1 , 1 , 12 , 0 , tzinfo = timezone .utc )
357+ snapshot_obj = DocketSnapshot (
358+ taken = now ,
359+ total_tasks = 0 ,
360+ future = [],
361+ running = [],
362+ workers = [
363+ WorkerInfo (
364+ name = "worker-1" ,
365+ last_seen = now ,
366+ tasks = set (),
367+ )
368+ ],
369+ )
370+
371+ registered : list [str ] = []
372+ _stub_snapshot_docket (monkeypatch , snapshot_obj , registered )
373+
374+ recorder = RecordingConsole ()
375+ monkeypatch .setattr ("docket.cli.Console" , lambda : recorder )
376+
377+ snapshot_command ()
378+
379+ assert registered == ["docket.tasks:standard_tasks" ]
380+ tables = [args [0 ] for args , _ in recorder .calls if args ]
381+ # Only the summary table should be printed.
382+ assert len ([t for t in tables if isinstance (t , Table )]) == 1
383+
384+
385+ def test_snapshot_cli_stats_with_no_tasks (monkeypatch : MonkeyPatch ):
386+ """When stats are requested but no tasks exist, the stats table should be skipped."""
387+ now = datetime (2023 , 1 , 1 , 12 , 0 , tzinfo = timezone .utc )
388+ snapshot_obj = DocketSnapshot (
389+ taken = now ,
390+ total_tasks = 0 ,
391+ future = [],
392+ running = [],
393+ workers = [],
394+ )
395+
396+ registered : list [str ] = []
397+ _stub_snapshot_docket (monkeypatch , snapshot_obj , registered )
398+
399+ recorder = RecordingConsole ()
400+ monkeypatch .setattr ("docket.cli.Console" , lambda : recorder )
401+
402+ snapshot_command (stats = True )
403+
404+ tables = [args [0 ] for args , _ in recorder .calls if args ]
405+ # Only the summary table should be printed since task_stats is empty.
406+ assert len ([t for t in tables if isinstance (t , Table )]) == 1
407+
408+
346409async def test_snapshot_with_stats_shows_timestamp_columns (
347410 docket : Docket , runner : CliRunner
348411):
0 commit comments