@@ -622,6 +622,50 @@ def test_export_file_html_has_line_numbers(self):
622622 # Should have line-related content
623623 self .assertIn ('line-' , content )
624624
625+ def test_export_skips_nonexistent_source (self ):
626+ """Source files that do not exist produce a placeholder."""
627+ collector = HeatmapCollector (sample_interval_usec = 100 )
628+
629+ frames = [('/no/such/file.py' , (1 , 1 , - 1 , - 1 ), 'f' , None )]
630+ collector .process_frames (frames , thread_id = 1 )
631+
632+ output_path = os .path .join (self .test_dir , 'missing_src' )
633+
634+ with captured_stdout (), captured_stderr ():
635+ collector .export (output_path )
636+
637+ html_files = [f for f in os .listdir (output_path )
638+ if f .startswith ('file_' ) and f .endswith ('.html' )]
639+ if html_files :
640+ with open (os .path .join (output_path , html_files [0 ]),
641+ 'r' , encoding = 'utf-8' ) as f :
642+ content = f .read ()
643+ self .assertIn ('Source file not available' , content )
644+
645+ def test_export_caps_oversized_source (self ):
646+ """Source files larger than the cap produce a placeholder."""
647+ collector = HeatmapCollector (sample_interval_usec = 100 )
648+
649+ big_file = os .path .join (self .test_dir , 'big.py' )
650+ with open (big_file , 'w' ) as f :
651+ f .write ('x = 1\n ' * 2_000_000 )
652+
653+ frames = [(big_file , (1 , 1 , - 1 , - 1 ), 'f' , None )]
654+ collector .process_frames (frames , thread_id = 1 )
655+
656+ output_path = os .path .join (self .test_dir , 'big_src' )
657+
658+ with captured_stdout (), captured_stderr ():
659+ collector .export (output_path )
660+
661+ html_files = [f for f in os .listdir (output_path )
662+ if f .startswith ('file_' ) and f .endswith ('.html' )]
663+ if html_files :
664+ with open (os .path .join (output_path , html_files [0 ]),
665+ 'r' , encoding = 'utf-8' ) as f :
666+ content = f .read ()
667+ self .assertIn ('Source file not available' , content )
668+
625669
626670class MockFrameInfo :
627671 """Mock FrameInfo for testing.
0 commit comments