diff options
| author | Jacob Walls <jacobtylerwalls@gmail.com> | 2024-11-29 07:04:48 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-29 09:04:48 -0300 |
| commit | 58cc91275a68bb42780cf0e663dad9ecf49039de (patch) | |
| tree | e60317923d4f2faf61238f46528ed180a5134651 /tests/user_commands | |
| parent | 978aae4334fa71ba78a3e94408f0f3aebde8d07c (diff) | |
Fixed #35308 -- Handled OSError when launching code formatters.
Co-authored-by: Natalia <124304+nessita@users.noreply.github.com>
Diffstat (limited to 'tests/user_commands')
| -rw-r--r-- | tests/user_commands/test_files/black | 1 | ||||
| -rw-r--r-- | tests/user_commands/tests.py | 25 | ||||
| -rw-r--r-- | tests/user_commands/utils.py | 23 |
3 files changed, 49 insertions, 0 deletions
diff --git a/tests/user_commands/test_files/black b/tests/user_commands/test_files/black new file mode 100644 index 0000000000..d95ebc8c1e --- /dev/null +++ b/tests/user_commands/test_files/black @@ -0,0 +1 @@ +# This file is not executable, to simulate a broken `black` install. diff --git a/tests/user_commands/tests.py b/tests/user_commands/tests.py index 2a1e904f3b..2add272c10 100644 --- a/tests/user_commands/tests.py +++ b/tests/user_commands/tests.py @@ -1,6 +1,8 @@ import os +import sys from argparse import ArgumentDefaultsHelpFormatter from io import StringIO +from pathlib import Path from unittest import mock from admin_scripts.tests import AdminScriptTestCase @@ -15,6 +17,7 @@ from django.core.management.utils import ( is_ignored_path, normalize_path_patterns, popen_wrapper, + run_formatters, ) from django.db import connection from django.test import SimpleTestCase, override_settings @@ -22,6 +25,7 @@ from django.test.utils import captured_stderr, extend_sys_path from django.utils import translation from .management.commands import dance +from .utils import AssertFormatterFailureCaughtContext # A minimal set of apps to avoid system checks running on all apps. @@ -535,3 +539,24 @@ class UtilsTests(SimpleTestCase): def test_normalize_path_patterns_truncates_wildcard_base(self): expected = [os.path.normcase(p) for p in ["foo/bar", "bar/*/"]] self.assertEqual(normalize_path_patterns(["foo/bar/*", "bar/*/"]), expected) + + def test_run_formatters_handles_oserror_for_black_path(self): + cases = [ + (FileNotFoundError, "nonexistent"), + ( + OSError if sys.platform == "win32" else PermissionError, + str(Path(__file__).parent / "test_files" / "black"), + ), + ] + for exception, location in cases: + with ( + self.subTest(exception.__qualname__), + AssertFormatterFailureCaughtContext( + self, shutil_which_result=location + ) as ctx, + ): + run_formatters([], stderr=ctx.stderr) + parsed_error = ctx.stderr.getvalue() + self.assertIn(exception.__qualname__, parsed_error) + if sys.platform != "win32": + self.assertIn(location, parsed_error) diff --git a/tests/user_commands/utils.py b/tests/user_commands/utils.py new file mode 100644 index 0000000000..84f6bdbc5c --- /dev/null +++ b/tests/user_commands/utils.py @@ -0,0 +1,23 @@ +from io import StringIO +from unittest import mock + + +class AssertFormatterFailureCaughtContext: + + def __init__(self, test, shutil_which_result="nonexistent"): + self.stdout = StringIO() + self.stderr = StringIO() + self.test = test + self.shutil_which_result = shutil_which_result + + def __enter__(self): + self.mocker = mock.patch( + "django.core.management.utils.shutil.which", + return_value=self.shutil_which_result, + ) + self.mocker.start() + return self + + def __exit__(self, exc_type, exc_value, traceback): + self.mocker.stop() + self.test.assertIn("Formatters failed to launch", self.stderr.getvalue()) |
