|
5 | 5 | import os |
6 | 6 | import shutil |
7 | 7 | import subprocess |
8 | | -from unittest.mock import MagicMock, patch |
| 8 | +from unittest.mock import patch |
9 | 9 |
|
| 10 | +import bigfoot |
10 | 11 | import pytest |
11 | 12 |
|
12 | 13 | from headerkit.backends.libclang import ( |
@@ -728,59 +729,84 @@ def test_c_and_cxx_cached_separately(self): |
728 | 729 |
|
729 | 730 | def test_clang_not_found_returns_empty(self): |
730 | 731 | """When clang is not on PATH, returns empty list.""" |
| 732 | + import sys |
| 733 | + |
731 | 734 | import headerkit.backends.libclang as mod |
732 | 735 |
|
| 736 | + null_file = "NUL" if sys.platform == "win32" else "/dev/null" |
733 | 737 | mod._system_include_cache_c = None |
734 | | - with patch("headerkit.backends.libclang.subprocess.run", side_effect=FileNotFoundError): |
| 738 | + bigfoot.subprocess_mock.mock_run( |
| 739 | + ["clang", "-v", "-x", "c", "-E", null_file], |
| 740 | + raises=FileNotFoundError(), |
| 741 | + ) |
| 742 | + with bigfoot.sandbox(): |
735 | 743 | result = get_system_include_dirs() |
736 | | - assert result == [] |
| 744 | + assert result == [] |
| 745 | + bigfoot.assert_interaction(bigfoot.subprocess_mock.run, command=["clang", "-v", "-x", "c", "-E", null_file]) |
737 | 746 |
|
738 | 747 | def test_clang_timeout_returns_empty(self): |
739 | 748 | """When clang times out, returns empty list.""" |
| 749 | + import sys |
| 750 | + |
740 | 751 | import headerkit.backends.libclang as mod |
741 | 752 |
|
| 753 | + null_file = "NUL" if sys.platform == "win32" else "/dev/null" |
742 | 754 | mod._system_include_cache_c = None |
743 | | - with patch( |
744 | | - "headerkit.backends.libclang.subprocess.run", |
745 | | - side_effect=subprocess.TimeoutExpired(cmd="clang", timeout=10), |
746 | | - ): |
| 755 | + bigfoot.subprocess_mock.mock_run( |
| 756 | + ["clang", "-v", "-x", "c", "-E", null_file], |
| 757 | + raises=subprocess.TimeoutExpired(cmd="clang", timeout=10), |
| 758 | + ) |
| 759 | + with bigfoot.sandbox(): |
747 | 760 | result = get_system_include_dirs() |
748 | | - assert result == [] |
| 761 | + assert result == [] |
| 762 | + bigfoot.assert_interaction(bigfoot.subprocess_mock.run, command=["clang", "-v", "-x", "c", "-E", null_file]) |
749 | 763 |
|
750 | 764 | def test_parses_include_search_paths(self): |
751 | 765 | """Parses clang -v output to extract include search paths.""" |
| 766 | + import sys |
| 767 | + |
752 | 768 | import headerkit.backends.libclang as mod |
753 | 769 |
|
| 770 | + null_file = "NUL" if sys.platform == "win32" else "/dev/null" |
754 | 771 | mod._system_include_cache_c = None |
755 | | - mock_result = MagicMock() |
756 | | - mock_result.stderr = ( |
757 | | - "clang version 18.0.0\n" |
758 | | - "#include <...> search starts here:\n" |
759 | | - " /usr/lib/clang/18/include\n" |
760 | | - " /usr/include\n" |
761 | | - "End of search list.\n" |
| 772 | + bigfoot.subprocess_mock.mock_run( |
| 773 | + ["clang", "-v", "-x", "c", "-E", null_file], |
| 774 | + returncode=0, |
| 775 | + stderr=( |
| 776 | + "clang version 18.0.0\n" |
| 777 | + "#include <...> search starts here:\n" |
| 778 | + " /usr/lib/clang/18/include\n" |
| 779 | + " /usr/include\n" |
| 780 | + "End of search list.\n" |
| 781 | + ), |
762 | 782 | ) |
763 | | - with patch("headerkit.backends.libclang.subprocess.run", return_value=mock_result): |
| 783 | + with bigfoot.sandbox(): |
764 | 784 | result = get_system_include_dirs() |
765 | | - assert "-isystem/usr/lib/clang/18/include" in result |
766 | | - assert "-isystem/usr/include" in result |
| 785 | + assert result == ["-isystem/usr/lib/clang/18/include", "-isystem/usr/include"] |
| 786 | + bigfoot.assert_interaction(bigfoot.subprocess_mock.run, command=["clang", "-v", "-x", "c", "-E", null_file]) |
767 | 787 |
|
768 | 788 | def test_skips_framework_directories(self): |
769 | 789 | """Framework directories are excluded from the result.""" |
| 790 | + import sys |
| 791 | + |
770 | 792 | import headerkit.backends.libclang as mod |
771 | 793 |
|
| 794 | + null_file = "NUL" if sys.platform == "win32" else "/dev/null" |
772 | 795 | mod._system_include_cache_c = None |
773 | | - mock_result = MagicMock() |
774 | | - mock_result.stderr = ( |
775 | | - "#include <...> search starts here:\n" |
776 | | - " /usr/include\n" |
777 | | - " /System/Library/Frameworks (framework directory)\n" |
778 | | - "End of search list.\n" |
| 796 | + bigfoot.subprocess_mock.mock_run( |
| 797 | + ["clang", "-v", "-x", "c", "-E", null_file], |
| 798 | + returncode=0, |
| 799 | + stderr=( |
| 800 | + "#include <...> search starts here:\n" |
| 801 | + " /usr/include\n" |
| 802 | + " /System/Library/Frameworks (framework directory)\n" |
| 803 | + "End of search list.\n" |
| 804 | + ), |
779 | 805 | ) |
780 | | - with patch("headerkit.backends.libclang.subprocess.run", return_value=mock_result): |
| 806 | + with bigfoot.sandbox(): |
781 | 807 | result = get_system_include_dirs() |
782 | | - assert "-isystem/usr/include" in result |
783 | | - assert len(result) == 1 # framework dir excluded |
| 808 | + assert result == ["-isystem/usr/include"] |
| 809 | + bigfoot.assert_interaction(bigfoot.subprocess_mock.run, command=["clang", "-v", "-x", "c", "-E", null_file]) |
784 | 810 |
|
785 | 811 |
|
786 | 812 | @libclang |
|
0 commit comments