mirror of
https://github.com/django-components/django-components.git
synced 2025-08-31 11:17:21 +00:00
chore: Push dev to master to release v0.110 (#767)
* feat: skeleton of dependency manager backend (#688) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * refactor: selectolax update and tests cleanup (#702) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * refactor: move release notes to own file (#704) * chore: merge changes from master (#705) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Yassin Rakha <yaso2go@gmail.com> Co-authored-by: Emil Stenström <emil@emilstenstrom.se> fix for nested slots (#698) (#699) * refactor: remove joint {% component_dependencies %} tag (#706) Co-authored-by: Emil Stenström <emil@emilstenstrom.se> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * refactor: split up utils file and move utils to util dir (#707) * docs: Move docs inside src/ to allow imports in python scripts (#708) * refactor: Docs prep 1 (#715) * refactor: Document template tags (#716) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * refactor: pass slot fills in template via slots param (#719) * chore: Merge master to dev (#729) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Yassin Rakha <yaso2go@gmail.com> Co-authored-by: Emil Stenström <emil@emilstenstrom.se> Co-authored-by: Tom Larsen <larsent@gmail.com> fix for nested slots (#698) (#699) * fix: Do not raise error if multiple slots with same name are flagged as default (#727) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * refactor: tag formatter - allow fwd slash in end tag (#730) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * refactor: Use lowercase names for registry settings (#731) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * docs: add docstrings (#732) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * feat: define settings as a data class for type hints, intellisense, and docs (#733) * refactor: fix reload-on-change logic, expose autodiscover's dirs-getting logic, rename settings (#734) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * docs: document settings (#743) * docs: document settings * refactor: fix linter errors * feat: passthrough slots and more (#758) * feat: passthrough slots and more * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * refactor: remove ComponentSlotContext.slots * refactor: update comment * docs: update changelog * refactor: update docstrings * refactor: document and test-cover more changes * refactor: revert fill without name * docs: update README --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> * fix: apostrophes in tags (#765) * refactor: fix merge error - duplicate code --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Emil Stenström <emil@emilstenstrom.se>
This commit is contained in:
parent
9f891453d5
commit
5fd45ab424
97 changed files with 8727 additions and 3011 deletions
338
tests/test_loader.py
Normal file
338
tests/test_loader.py
Normal file
|
@ -0,0 +1,338 @@
|
|||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from django.conf import settings
|
||||
from django.test import override_settings
|
||||
|
||||
from django_components.util.loader import _filepath_to_python_module, get_component_dirs, get_component_files
|
||||
|
||||
from .django_test_setup import setup_test_config
|
||||
from .testutils import BaseTestCase
|
||||
|
||||
setup_test_config({"autodiscover": False})
|
||||
|
||||
|
||||
class ComponentDirsTest(BaseTestCase):
|
||||
@override_settings(
|
||||
BASE_DIR=Path(__file__).parent.resolve(),
|
||||
)
|
||||
def test_get_dirs__base_dir(self):
|
||||
dirs = sorted(get_component_dirs())
|
||||
|
||||
apps_dirs = [dirs[0], dirs[2]]
|
||||
own_dirs = [dirs[1], *dirs[3:]]
|
||||
|
||||
self.assertEqual(
|
||||
own_dirs,
|
||||
[
|
||||
# Top-level /components dir
|
||||
Path(__file__).parent.resolve()
|
||||
/ "components",
|
||||
],
|
||||
)
|
||||
|
||||
# Apps with a `components` dir
|
||||
self.assertEqual(len(apps_dirs), 2)
|
||||
self.assertRegex(str(apps_dirs[0]), re.compile(r"\/django_components\/components$"))
|
||||
self.assertRegex(str(apps_dirs[1]), re.compile(r"\/tests\/test_app\/components$"))
|
||||
|
||||
@override_settings(
|
||||
BASE_DIR=Path(__file__).parent.resolve() / "test_structures" / "test_structure_1", # noqa
|
||||
)
|
||||
def test_get_dirs__base_dir__complex(self):
|
||||
dirs = sorted(get_component_dirs())
|
||||
|
||||
apps_dirs = dirs[:2]
|
||||
own_dirs = dirs[2:]
|
||||
|
||||
# Apps with a `components` dir
|
||||
self.assertEqual(len(apps_dirs), 2)
|
||||
self.assertRegex(str(apps_dirs[0]), re.compile(r"\/django_components\/components$"))
|
||||
self.assertRegex(str(apps_dirs[1]), re.compile(r"\/tests\/test_app\/components$"))
|
||||
|
||||
expected = [
|
||||
Path(__file__).parent.resolve() / "test_structures" / "test_structure_1" / "components",
|
||||
]
|
||||
self.assertEqual(own_dirs, expected)
|
||||
|
||||
@override_settings(
|
||||
BASE_DIR=Path(__file__).parent.resolve(),
|
||||
STATICFILES_DIRS=[
|
||||
Path(__file__).parent.resolve() / "components",
|
||||
("with_alias", Path(__file__).parent.resolve() / "components"),
|
||||
("too_many", Path(__file__).parent.resolve() / "components", Path(__file__).parent.resolve()),
|
||||
("with_not_str_alias", 3),
|
||||
], # noqa
|
||||
)
|
||||
@patch("django_components.util.loader.logger.warning")
|
||||
def test_get_dirs__components_dirs(self, mock_warning: MagicMock):
|
||||
mock_warning.reset_mock()
|
||||
dirs = sorted(get_component_dirs())
|
||||
|
||||
apps_dirs = [dirs[0], dirs[2]]
|
||||
own_dirs = [dirs[1], *dirs[3:]]
|
||||
|
||||
# Apps with a `components` dir
|
||||
self.assertEqual(len(apps_dirs), 2)
|
||||
self.assertRegex(str(apps_dirs[0]), re.compile(r"\/django_components\/components$"))
|
||||
self.assertRegex(str(apps_dirs[1]), re.compile(r"\/tests\/test_app\/components$"))
|
||||
|
||||
self.assertEqual(
|
||||
own_dirs,
|
||||
[
|
||||
# Top-level /components dir
|
||||
Path(__file__).parent.resolve()
|
||||
/ "components",
|
||||
],
|
||||
)
|
||||
|
||||
warn_inputs = [warn.args[0] for warn in mock_warning.call_args_list]
|
||||
assert "Got <class 'int'> : 3" in warn_inputs[0]
|
||||
|
||||
@override_settings(
|
||||
BASE_DIR=Path(__file__).parent.resolve(),
|
||||
COMPONENTS={
|
||||
"dirs": [],
|
||||
},
|
||||
)
|
||||
def test_get_dirs__components_dirs__empty(self):
|
||||
dirs = sorted(get_component_dirs())
|
||||
|
||||
apps_dirs = dirs
|
||||
|
||||
# Apps with a `components` dir
|
||||
self.assertEqual(len(apps_dirs), 2)
|
||||
self.assertRegex(str(apps_dirs[0]), re.compile(r"\/django_components\/components$"))
|
||||
self.assertRegex(str(apps_dirs[1]), re.compile(r"\/tests\/test_app\/components$"))
|
||||
|
||||
@override_settings(
|
||||
BASE_DIR=Path(__file__).parent.resolve(),
|
||||
COMPONENTS={
|
||||
"dirs": ["components"],
|
||||
},
|
||||
)
|
||||
def test_get_dirs__componenents_dirs__raises_on_relative_path_1(self):
|
||||
with self.assertRaisesMessage(ValueError, "COMPONENTS.dirs must contain absolute paths"):
|
||||
get_component_dirs()
|
||||
|
||||
@override_settings(
|
||||
BASE_DIR=Path(__file__).parent.resolve(),
|
||||
COMPONENTS={
|
||||
"dirs": [("with_alias", "components")],
|
||||
},
|
||||
)
|
||||
def test_get_dirs__component_dirs__raises_on_relative_path_2(self):
|
||||
with self.assertRaisesMessage(ValueError, "COMPONENTS.dirs must contain absolute paths"):
|
||||
get_component_dirs()
|
||||
|
||||
@override_settings(
|
||||
BASE_DIR=Path(__file__).parent.resolve(),
|
||||
COMPONENTS={
|
||||
"app_dirs": ["custom_comps_dir"],
|
||||
},
|
||||
)
|
||||
def test_get_dirs__app_dirs(self):
|
||||
dirs = sorted(get_component_dirs())
|
||||
|
||||
apps_dirs = dirs[1:]
|
||||
own_dirs = dirs[:1]
|
||||
|
||||
# Apps with a `components` dir
|
||||
self.assertEqual(len(apps_dirs), 1)
|
||||
self.assertRegex(str(apps_dirs[0]), re.compile(r"\/tests\/test_app\/custom_comps_dir$"))
|
||||
|
||||
self.assertEqual(
|
||||
own_dirs,
|
||||
[
|
||||
# Top-level /components dir
|
||||
Path(__file__).parent.resolve()
|
||||
/ "components",
|
||||
],
|
||||
)
|
||||
|
||||
@override_settings(
|
||||
BASE_DIR=Path(__file__).parent.resolve(),
|
||||
COMPONENTS={
|
||||
"app_dirs": [],
|
||||
},
|
||||
)
|
||||
def test_get_dirs__app_dirs_empty(self):
|
||||
dirs = sorted(get_component_dirs())
|
||||
|
||||
own_dirs = dirs
|
||||
|
||||
self.assertEqual(
|
||||
own_dirs,
|
||||
[
|
||||
# Top-level /components dir
|
||||
Path(__file__).parent.resolve()
|
||||
/ "components",
|
||||
],
|
||||
)
|
||||
|
||||
@override_settings(
|
||||
BASE_DIR=Path(__file__).parent.resolve(),
|
||||
COMPONENTS={
|
||||
"app_dirs": ["this_dir_does_not_exist"],
|
||||
},
|
||||
)
|
||||
def test_get_dirs__app_dirs_not_found(self):
|
||||
dirs = sorted(get_component_dirs())
|
||||
|
||||
own_dirs = dirs
|
||||
|
||||
self.assertEqual(
|
||||
own_dirs,
|
||||
[
|
||||
# Top-level /components dir
|
||||
Path(__file__).parent.resolve()
|
||||
/ "components",
|
||||
],
|
||||
)
|
||||
|
||||
@override_settings(
|
||||
BASE_DIR=Path(__file__).parent.resolve(),
|
||||
INSTALLED_APPS=("django_components", "tests.test_app_nested.app"),
|
||||
)
|
||||
def test_get_dirs__nested_apps(self):
|
||||
dirs = sorted(get_component_dirs())
|
||||
|
||||
apps_dirs = [dirs[0], *dirs[2:]]
|
||||
own_dirs = [dirs[1]]
|
||||
|
||||
# Apps with a `components` dir
|
||||
self.assertEqual(len(apps_dirs), 2)
|
||||
self.assertRegex(str(apps_dirs[0]), re.compile(r"\/django_components\/components$"))
|
||||
self.assertRegex(str(apps_dirs[1]), re.compile(r"\/tests\/test_app_nested\/app\/components$"))
|
||||
|
||||
self.assertEqual(
|
||||
own_dirs,
|
||||
[
|
||||
# Top-level /components dir
|
||||
Path(__file__).parent.resolve()
|
||||
/ "components",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
class ComponentFilesTest(BaseTestCase):
|
||||
@override_settings(
|
||||
BASE_DIR=Path(__file__).parent.resolve(),
|
||||
)
|
||||
def test_get_files__py(self):
|
||||
files = sorted(get_component_files(".py"))
|
||||
|
||||
dot_paths = [f.dot_path for f in files]
|
||||
file_paths = [str(f.filepath) for f in files]
|
||||
|
||||
self.assertEqual(
|
||||
dot_paths,
|
||||
[
|
||||
"components",
|
||||
"components.multi_file.multi_file",
|
||||
"components.relative_file.relative_file",
|
||||
"components.relative_file_pathobj.relative_file_pathobj",
|
||||
"components.single_file",
|
||||
"components.staticfiles.staticfiles",
|
||||
"components.urls",
|
||||
"django_components.components",
|
||||
"django_components.components.dynamic",
|
||||
"tests.test_app.components.app_lvl_comp.app_lvl_comp",
|
||||
],
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
[
|
||||
file_paths[0].endswith("tests/components/__init__.py"),
|
||||
file_paths[1].endswith("tests/components/multi_file/multi_file.py"),
|
||||
file_paths[2].endswith("tests/components/relative_file/relative_file.py"),
|
||||
file_paths[3].endswith("tests/components/relative_file_pathobj/relative_file_pathobj.py"),
|
||||
file_paths[4].endswith("tests/components/single_file.py"),
|
||||
file_paths[5].endswith("tests/components/staticfiles/staticfiles.py"),
|
||||
file_paths[6].endswith("tests/components/urls.py"),
|
||||
file_paths[7].endswith("django_components/components/__init__.py"),
|
||||
file_paths[8].endswith("django_components/components/dynamic.py"),
|
||||
file_paths[9].endswith("tests/test_app/components/app_lvl_comp/app_lvl_comp.py"),
|
||||
],
|
||||
[True for _ in range(len(file_paths))],
|
||||
)
|
||||
|
||||
@override_settings(
|
||||
BASE_DIR=Path(__file__).parent.resolve(),
|
||||
)
|
||||
def test_get_files__js(self):
|
||||
files = sorted(get_component_files(".js"))
|
||||
|
||||
dot_paths = [f.dot_path for f in files]
|
||||
file_paths = [str(f.filepath) for f in files]
|
||||
|
||||
print(file_paths)
|
||||
|
||||
self.assertEqual(
|
||||
dot_paths,
|
||||
[
|
||||
"components.relative_file.relative_file",
|
||||
"components.relative_file_pathobj.relative_file_pathobj",
|
||||
"components.staticfiles.staticfiles",
|
||||
"tests.test_app.components.app_lvl_comp.app_lvl_comp",
|
||||
],
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
[
|
||||
file_paths[0].endswith("tests/components/relative_file/relative_file.js"),
|
||||
file_paths[1].endswith("tests/components/relative_file_pathobj/relative_file_pathobj.js"),
|
||||
file_paths[2].endswith("tests/components/staticfiles/staticfiles.js"),
|
||||
file_paths[3].endswith("tests/test_app/components/app_lvl_comp/app_lvl_comp.js"),
|
||||
],
|
||||
[True for _ in range(len(file_paths))],
|
||||
)
|
||||
|
||||
|
||||
class TestFilepathToPythonModule(BaseTestCase):
|
||||
def test_prepares_path(self):
|
||||
base_path = str(settings.BASE_DIR)
|
||||
|
||||
the_path = os.path.join(base_path, "tests.py")
|
||||
self.assertEqual(
|
||||
_filepath_to_python_module(the_path, base_path, None),
|
||||
"tests",
|
||||
)
|
||||
|
||||
the_path = os.path.join(base_path, "tests/components/relative_file/relative_file.py")
|
||||
self.assertEqual(
|
||||
_filepath_to_python_module(the_path, base_path, None),
|
||||
"tests.components.relative_file.relative_file",
|
||||
)
|
||||
|
||||
def test_handles_nonlinux_paths(self):
|
||||
base_path = str(settings.BASE_DIR).replace("/", "//")
|
||||
|
||||
with patch("os.path.sep", new="//"):
|
||||
the_path = os.path.join(base_path, "tests.py")
|
||||
self.assertEqual(
|
||||
_filepath_to_python_module(the_path, base_path, None),
|
||||
"tests",
|
||||
)
|
||||
|
||||
the_path = os.path.join(base_path, "tests//components//relative_file//relative_file.py")
|
||||
self.assertEqual(
|
||||
_filepath_to_python_module(the_path, base_path, None),
|
||||
"tests.components.relative_file.relative_file",
|
||||
)
|
||||
|
||||
base_path = str(settings.BASE_DIR).replace("//", "\\")
|
||||
with patch("os.path.sep", new="\\"):
|
||||
the_path = os.path.join(base_path, "tests.py")
|
||||
self.assertEqual(
|
||||
_filepath_to_python_module(the_path, base_path, None),
|
||||
"tests",
|
||||
)
|
||||
|
||||
the_path = os.path.join(base_path, "tests\\components\\relative_file\\relative_file.py")
|
||||
self.assertEqual(
|
||||
_filepath_to_python_module(the_path, base_path, None),
|
||||
"tests.components.relative_file.relative_file",
|
||||
)
|
Loading…
Add table
Add a link
Reference in a new issue