| import os |
| from pathlib import Path |
| from unittest.mock import MagicMock, patch |
| |
| from isort import exceptions, hooks |
| |
| |
| def test_git_hook(src_dir): |
| """Simple smoke level testing of git hooks""" |
| |
| # Ensure correct subprocess command is called |
| with patch("subprocess.run", MagicMock()) as run_mock: |
| hooks.git_hook() |
| assert run_mock.called_once() |
| assert run_mock.call_args[0][0] == [ |
| "git", |
| "diff-index", |
| "--cached", |
| "--name-only", |
| "--diff-filter=ACMRTUXB", |
| "HEAD", |
| ] |
| |
| hooks.git_hook(lazy=True) |
| assert run_mock.called_once() |
| assert run_mock.call_args[0][0] == [ |
| "git", |
| "diff-index", |
| "--name-only", |
| "--diff-filter=ACMRTUXB", |
| "HEAD", |
| ] |
| |
| # Test that non python files aren't processed |
| with patch( |
| "isort.hooks.get_lines", |
| MagicMock(return_value=["README.md", "setup.cfg", "LICDENSE", "mkdocs.yml", "test"]), |
| ): |
| with patch("subprocess.run", MagicMock()) as run_mock: |
| hooks.git_hook(modify=True) |
| run_mock.assert_not_called() |
| |
| mock_main_py = MagicMock(return_value=[os.path.join(src_dir, "main.py")]) |
| |
| mock_imperfect = MagicMock() |
| mock_imperfect.return_value.stdout = b"import b\nimport a" |
| |
| # Test with incorrectly sorted file returned from git |
| with patch("isort.hooks.get_lines", mock_main_py): |
| with patch("subprocess.run", mock_imperfect): |
| with patch("isort.api.sort_file", MagicMock(return_value=False)) as api_mock: |
| hooks.git_hook(modify=True) |
| api_mock.assert_called_once() |
| assert api_mock.call_args[0][0] == mock_main_py.return_value[0] |
| |
| # Test with sorted file returned from git and modify=False |
| with patch("isort.hooks.get_lines", mock_main_py): |
| with patch("subprocess.run", mock_imperfect): |
| with patch("isort.api.sort_file", MagicMock(return_value=False)) as api_mock: |
| hooks.git_hook(modify=False) |
| api_mock.assert_not_called() |
| |
| # Test with skipped file returned from git |
| with patch( |
| "isort.hooks.get_lines", MagicMock(return_value=[os.path.join(src_dir, "main.py")]) |
| ) as run_mock: |
| |
| class FakeProcessResponse(object): |
| stdout = b"# isort: skip-file\nimport b\nimport a\n" |
| |
| with patch("subprocess.run", MagicMock(return_value=FakeProcessResponse())) as run_mock: |
| with patch("isort.api", MagicMock(side_effect=exceptions.FileSkipped("", ""))): |
| hooks.git_hook(modify=True) |
| |
| |
| def test_git_hook_uses_the_configuration_file_specified_in_settings_path(tmp_path: Path) -> None: |
| subdirectory_path = tmp_path / "subdirectory" |
| configuration_file_path = subdirectory_path / ".isort.cfg" |
| |
| # Inserting the modified file in the parent directory of the configuration file ensures that it |
| # will not be found by the normal search routine |
| modified_file_path = configuration_file_path.parent.parent / "somefile.py" |
| |
| # This section will be used to check that the configuration file was indeed loaded |
| section = "testsection" |
| |
| os.mkdir(subdirectory_path) |
| with open(configuration_file_path, "w") as fd: |
| fd.write("[isort]\n") |
| fd.write(f"sections={section}") |
| |
| with open(modified_file_path, "w") as fd: |
| pass |
| |
| files_modified = [str(modified_file_path.absolute())] |
| with patch("isort.hooks.get_lines", MagicMock(return_value=files_modified)): |
| with patch("isort.hooks.get_output", MagicMock(return_value="")): |
| with patch("isort.api.check_code_string", MagicMock()) as run_mock: |
| hooks.git_hook(settings_file=str(configuration_file_path)) |
| |
| assert run_mock.call_args[1]["config"].sections == (section,) |