| # Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html |
| # For details: https://github.com/pylint-dev/astroid/blob/main/LICENSE |
| # Copyright (c) https://github.com/pylint-dev/astroid/blob/main/CONTRIBUTORS.txt |
| import os |
| import tempfile |
| import unittest |
| |
| from astroid import modutils |
| |
| |
| class TestModUtilsRelativePath(unittest.TestCase): |
| |
| def setUp(self): |
| self.cwd = os.getcwd() |
| |
| def _run_relative_path_test(self, target, base, expected): |
| if not (target and base): |
| result = None |
| else: |
| base_dir = os.path.join(self.cwd, base) |
| target_path = os.path.join(self.cwd, target) |
| result = modutils._get_relative_base_path(target_path, base_dir) |
| self.assertEqual(result, expected) |
| |
| def test_similar_prefixes_no_match(self): |
| |
| cases = [ |
| ("something", "some", None), |
| ("some-thing", "some", None), |
| ("some2", "some", None), |
| ("somedir", "some", None), |
| ("some_thing", "some", None), |
| ("some.dir", "some", None), |
| ] |
| for target, base, expected in cases: |
| with self.subTest(target=target, base=base): |
| self._run_relative_path_test(target, base, expected) |
| |
| def test_valid_subdirectories(self): |
| |
| cases = [ |
| ("some/sub", "some", ["sub"]), |
| ("some/foo/bar", "some", ["foo", "bar"]), |
| ("some/foo-bar", "some", ["foo-bar"]), |
| ("some/foo/bar-ext", "some/foo", ["bar-ext"]), |
| ("something/sub", "something", ["sub"]), |
| ] |
| for target, base, expected in cases: |
| with self.subTest(target=target, base=base): |
| self._run_relative_path_test(target, base, expected) |
| |
| def test_path_format_variations(self): |
| |
| cases = [ |
| ("some", "some", []), |
| ("some/", "some", []), |
| ("../some", "some", None), |
| ] |
| |
| if os.path.isabs("/abs/path"): |
| cases.append(("/abs/path/some", "/abs/path", ["some"])) |
| |
| for target, base, expected in cases: |
| with self.subTest(target=target, base=base): |
| self._run_relative_path_test(target, base, expected) |
| |
| def test_case_sensitivity(self): |
| |
| cases = [ |
| ("Some/sub", "some", None if os.path.sep == "/" else ["sub"]), |
| ("some/Sub", "some", ["Sub"]), |
| ] |
| for target, base, expected in cases: |
| with self.subTest(target=target, base=base): |
| self._run_relative_path_test(target, base, expected) |
| |
| def test_special_path_components(self): |
| |
| cases = [ |
| ("some/.hidden", "some", [".hidden"]), |
| ("some/with space", "some", ["with space"]), |
| ("some/unicode_ø", "some", ["unicode_ø"]), |
| ] |
| for target, base, expected in cases: |
| with self.subTest(target=target, base=base): |
| self._run_relative_path_test(target, base, expected) |
| |
| def test_nonexistent_paths(self): |
| |
| cases = [("nonexistent", "some", None), ("some/sub", "nonexistent", None)] |
| for target, base, expected in cases: |
| with self.subTest(target=target, base=base): |
| self._run_relative_path_test(target, base, expected) |
| |
| def test_empty_paths(self): |
| |
| cases = [("", "some", None), ("some", "", None), ("", "", None)] |
| for target, base, expected in cases: |
| with self.subTest(target=target, base=base): |
| self._run_relative_path_test(target, base, expected) |
| |
| def test_symlink_resolution(self): |
| with tempfile.TemporaryDirectory() as tmpdir: |
| base_dir = os.path.join(tmpdir, "some") |
| os.makedirs(base_dir, exist_ok=True) |
| |
| real_file = os.path.join(base_dir, "real.py") |
| with open(real_file, "w", encoding="utf-8") as f: |
| f.write("# dummy content") |
| |
| symlink_path = os.path.join(tmpdir, "symlink.py") |
| os.symlink(real_file, symlink_path) |
| |
| result = modutils._get_relative_base_path(symlink_path, base_dir) |
| self.assertEqual(result, ["real"]) |
| |
| |
| if __name__ == "__main__": |
| unittest.main() |