@@ -237,6 +237,11 @@ def test_self_import(self):
237237 # Verify it's usable in the second block
238238 assert "let value := utilFunc(10)" in result
239239
240+ # IMPORTANT: When importing from self (different assembly block in same file),
241+ # the imported function SHOULD have coverage exclusion markers
242+ assert "function exclude_coverage_start_utilFunc() {}" in result
243+ assert "function exclude_coverage_stop_utilFunc() {}" in result
244+
240245 def test_self_import_multiple (self ):
241246 """Test importing multiple functions from a different assembly block in the same file."""
242247 test_dir = self .test_files_dir / "self_import"
@@ -254,6 +259,13 @@ def test_self_import_multiple(self):
254259 assert "let doubled := helper(5)" in result
255260 assert "let increased := anotherHelper(doubled)" in result
256261
262+ # IMPORTANT: When importing from self (different assembly block in same file),
263+ # the imported functions SHOULD have coverage exclusion markers
264+ assert "function exclude_coverage_start_helper() {}" in result
265+ assert "function exclude_coverage_stop_helper() {}" in result
266+ assert "function exclude_coverage_start_anotherHelper() {}" in result
267+ assert "function exclude_coverage_stop_anotherHelper() {}" in result
268+
257269 def test_circular_with_external_import (self ):
258270 """Test that C can import from a circular group A-B."""
259271 test_dir = self .test_files_dir / "circular_regular"
@@ -602,17 +614,90 @@ def test_slither_comments_preserved(self):
602614 # Should have slither-disable-next-line before simpleFunction
603615 assert "// slither-disable-next-line write-after-write" in result
604616
617+ # Verify coverage exclusion markers are added
618+ assert "function exclude_coverage_start_complexFunction() {}" in result
619+ assert "function exclude_coverage_stop_complexFunction() {}" in result
620+ assert "function exclude_coverage_start_simpleFunction() {}" in result
621+ assert "function exclude_coverage_stop_simpleFunction() {}" in result
622+
605623 # Verify the ordering is correct (disable-start comes before the function)
606624 start_idx = result .find ("// slither-disable-start cyclomatic-complexity" )
625+ cov_start_idx = result .find ("function exclude_coverage_start_complexFunction" )
607626 func_idx = result .find ("function complexFunction" )
627+ cov_stop_idx = result .find ("function exclude_coverage_stop_complexFunction" )
608628 end_idx = result .find ("// slither-disable-end cyclomatic-complexity" )
609629 assert (
610- start_idx < func_idx < end_idx
611- ), "Slither comments should wrap the function"
630+ start_idx < cov_start_idx < func_idx < cov_stop_idx < end_idx
631+ ), "Slither comments and coverage markers should properly wrap the function"
612632
613633 # Verify no duplicate disable-end comments
614634 assert result .count ("// slither-disable-end cyclomatic-complexity" ) == 1
615635
636+ def test_coverage_exclusion_for_external_imports (self ):
637+ """Test that functions imported from external files get coverage exclusion markers."""
638+ test_dir = self .test_files_dir / "basic_import"
639+ target_file = test_dir / "main.presl"
640+
641+ preprocessor = YulPreprocessor (root_dir = test_dir )
642+ result = preprocessor .process_file (target_file )
643+
644+ # Verify the imported function has coverage exclusion markers
645+ assert "function exclude_coverage_start_add5() {}" in result
646+ assert "function exclude_coverage_stop_add5() {}" in result
647+
648+ # Verify the markers wrap the function
649+ start_idx = result .find ("function exclude_coverage_start_add5" )
650+ func_idx = result .find ("function add5(x) -> result" )
651+ stop_idx = result .find ("function exclude_coverage_stop_add5" )
652+ assert (
653+ start_idx < func_idx < stop_idx
654+ ), "Coverage markers should wrap the imported function"
655+
656+ def test_coverage_exclusion_circular_dependencies (self ):
657+ """Test that functions in their own file are NOT coverage-excluded in circular dependencies."""
658+ test_dir = self .test_files_dir / "circular_regular"
659+ file_a = test_dir / "a.presl"
660+ file_b = test_dir / "b.presl"
661+
662+ preprocessor = YulPreprocessor (root_dir = test_dir )
663+ result_a = preprocessor .process_file (file_a )
664+ result_b = preprocessor .process_file (file_b )
665+
666+ # In a.post.sol, funcA is defined locally so it should NOT have coverage exclusion
667+ # but funcB is imported so it SHOULD have coverage exclusion
668+
669+ # funcB imported into a.post.sol should have coverage exclusion
670+ assert "function exclude_coverage_start_funcB() {}" in result_a
671+ assert "function exclude_coverage_stop_funcB() {}" in result_a
672+
673+ # funcA imported into b.post.sol should have coverage exclusion
674+ assert "function exclude_coverage_start_funcA() {}" in result_b
675+ assert "function exclude_coverage_stop_funcA() {}" in result_b
676+
677+ # IMPORTANT: funcA in a.post.sol should NOT have coverage exclusion
678+ # because it's defined in a.presl (the source file for a.post.sol)
679+ assert "function exclude_coverage_start_funcA() {}" not in result_a
680+ assert "function exclude_coverage_stop_funcA() {}" not in result_a
681+
682+ # Similarly, funcB in b.post.sol should NOT have coverage exclusion
683+ # because it's defined in b.presl (the source file for b.post.sol)
684+ assert "function exclude_coverage_start_funcB() {}" not in result_b
685+ assert "function exclude_coverage_stop_funcB() {}" not in result_b
686+
687+ def test_coverage_exclusion_with_dependencies (self ):
688+ """Test that transitive dependencies also get coverage exclusion markers."""
689+ test_dir = self .test_files_dir / "multiple_imports"
690+ target_file = test_dir / "calculator.presl"
691+
692+ preprocessor = YulPreprocessor (root_dir = test_dir )
693+ result = preprocessor .process_file (target_file )
694+
695+ # Both imported functions should have coverage exclusion markers
696+ assert "function exclude_coverage_start_multiply() {}" in result
697+ assert "function exclude_coverage_stop_multiply() {}" in result
698+ assert "function exclude_coverage_start_divide() {}" in result
699+ assert "function exclude_coverage_stop_divide() {}" in result
700+
616701
617702if __name__ == "__main__" :
618703 pytest .main ([__file__ , "-v" ])
0 commit comments