|
@@ -1,128 +1,105 @@
|
|
|
-from copy import copy, deepcopy
|
|
|
-
|
|
|
-from django.core.checks import Warning
|
|
|
-from django.core.checks.templates import (
|
|
|
- E001,
|
|
|
- E002,
|
|
|
- W003,
|
|
|
- check_for_template_tags_with_the_same_name,
|
|
|
- check_setting_app_dirs_loaders,
|
|
|
- check_string_if_invalid_is_string,
|
|
|
-)
|
|
|
+from copy import deepcopy
|
|
|
+from itertools import chain
|
|
|
+
|
|
|
+from django.core.checks import Error, Warning
|
|
|
+from django.core.checks.templates import check_templates
|
|
|
+from django.template import engines
|
|
|
+from django.template.backends.base import BaseEngine
|
|
|
from django.test import SimpleTestCase
|
|
|
from django.test.utils import override_settings
|
|
|
|
|
|
|
|
|
-class CheckTemplateSettingsAppDirsTest(SimpleTestCase):
|
|
|
- TEMPLATES_APP_DIRS_AND_LOADERS = [
|
|
|
- {
|
|
|
- "BACKEND": "django.template.backends.django.DjangoTemplates",
|
|
|
- "APP_DIRS": True,
|
|
|
- "OPTIONS": {
|
|
|
- "loaders": ["django.template.loaders.filesystem.Loader"],
|
|
|
- },
|
|
|
- },
|
|
|
- ]
|
|
|
+class ErrorEngine(BaseEngine):
|
|
|
+ def __init__(self, params):
|
|
|
+ params.pop("OPTIONS")
|
|
|
+ super().__init__(params)
|
|
|
|
|
|
- @override_settings(TEMPLATES=TEMPLATES_APP_DIRS_AND_LOADERS)
|
|
|
- def test_app_dirs_and_loaders(self):
|
|
|
- """
|
|
|
- Error if template loaders are specified and APP_DIRS is True.
|
|
|
- """
|
|
|
- self.assertEqual(check_setting_app_dirs_loaders(None), [E001])
|
|
|
+ def check(self, **kwargs):
|
|
|
+ return [Error("Example")]
|
|
|
|
|
|
- def test_app_dirs_removed(self):
|
|
|
- TEMPLATES = deepcopy(self.TEMPLATES_APP_DIRS_AND_LOADERS)
|
|
|
- del TEMPLATES[0]["APP_DIRS"]
|
|
|
- with self.settings(TEMPLATES=TEMPLATES):
|
|
|
- self.assertEqual(check_setting_app_dirs_loaders(None), [])
|
|
|
|
|
|
- def test_loaders_removed(self):
|
|
|
- TEMPLATES = deepcopy(self.TEMPLATES_APP_DIRS_AND_LOADERS)
|
|
|
- del TEMPLATES[0]["OPTIONS"]["loaders"]
|
|
|
- with self.settings(TEMPLATES=TEMPLATES):
|
|
|
- self.assertEqual(check_setting_app_dirs_loaders(None), [])
|
|
|
+class CheckTemplatesTests(SimpleTestCase):
|
|
|
+ @override_settings(
|
|
|
+ TEMPLATES=[
|
|
|
+ {"BACKEND": f"{__name__}.{ErrorEngine.__qualname__}", "NAME": "backend_1"},
|
|
|
+ {"BACKEND": f"{__name__}.{ErrorEngine.__qualname__}", "NAME": "backend_2"},
|
|
|
+ ]
|
|
|
+ )
|
|
|
+ def test_errors_aggregated(self):
|
|
|
+ errors = check_templates(None)
|
|
|
+ self.assertEqual(errors, [Error("Example")] * 2)
|
|
|
|
|
|
|
|
|
class CheckTemplateStringIfInvalidTest(SimpleTestCase):
|
|
|
TEMPLATES_STRING_IF_INVALID = [
|
|
|
{
|
|
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
|
|
+ "NAME": "backend_1",
|
|
|
"OPTIONS": {
|
|
|
"string_if_invalid": False,
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
|
|
+ "NAME": "backend_2",
|
|
|
"OPTIONS": {
|
|
|
"string_if_invalid": 42,
|
|
|
},
|
|
|
},
|
|
|
]
|
|
|
|
|
|
- @classmethod
|
|
|
- def setUpClass(cls):
|
|
|
- super().setUpClass()
|
|
|
- cls.error1 = copy(E002)
|
|
|
- cls.error2 = copy(E002)
|
|
|
- string_if_invalid1 = cls.TEMPLATES_STRING_IF_INVALID[0]["OPTIONS"][
|
|
|
- "string_if_invalid"
|
|
|
- ]
|
|
|
- string_if_invalid2 = cls.TEMPLATES_STRING_IF_INVALID[1]["OPTIONS"][
|
|
|
- "string_if_invalid"
|
|
|
- ]
|
|
|
- cls.error1.msg = cls.error1.msg.format(
|
|
|
- string_if_invalid1, type(string_if_invalid1).__name__
|
|
|
+ def _get_error_for_engine(self, engine):
|
|
|
+ value = engine.engine.string_if_invalid
|
|
|
+ return Error(
|
|
|
+ "'string_if_invalid' in TEMPLATES OPTIONS must be a string but got: %r "
|
|
|
+ "(%s)." % (value, type(value)),
|
|
|
+ obj=engine,
|
|
|
+ id="templates.E002",
|
|
|
)
|
|
|
- cls.error2.msg = cls.error2.msg.format(
|
|
|
- string_if_invalid2, type(string_if_invalid2).__name__
|
|
|
+
|
|
|
+ def _check_engines(self, engines):
|
|
|
+ return list(
|
|
|
+ chain.from_iterable(e._check_string_if_invalid_is_string() for e in engines)
|
|
|
)
|
|
|
|
|
|
@override_settings(TEMPLATES=TEMPLATES_STRING_IF_INVALID)
|
|
|
def test_string_if_invalid_not_string(self):
|
|
|
- self.assertEqual(
|
|
|
- check_string_if_invalid_is_string(None), [self.error1, self.error2]
|
|
|
- )
|
|
|
+ _engines = engines.all()
|
|
|
+ errors = [
|
|
|
+ self._get_error_for_engine(_engines[0]),
|
|
|
+ self._get_error_for_engine(_engines[1]),
|
|
|
+ ]
|
|
|
+ self.assertEqual(self._check_engines(_engines), errors)
|
|
|
|
|
|
def test_string_if_invalid_first_is_string(self):
|
|
|
TEMPLATES = deepcopy(self.TEMPLATES_STRING_IF_INVALID)
|
|
|
TEMPLATES[0]["OPTIONS"]["string_if_invalid"] = "test"
|
|
|
with self.settings(TEMPLATES=TEMPLATES):
|
|
|
- self.assertEqual(check_string_if_invalid_is_string(None), [self.error2])
|
|
|
+ _engines = engines.all()
|
|
|
+ errors = [self._get_error_for_engine(_engines[1])]
|
|
|
+ self.assertEqual(self._check_engines(_engines), errors)
|
|
|
|
|
|
def test_string_if_invalid_both_are_strings(self):
|
|
|
TEMPLATES = deepcopy(self.TEMPLATES_STRING_IF_INVALID)
|
|
|
TEMPLATES[0]["OPTIONS"]["string_if_invalid"] = "test"
|
|
|
TEMPLATES[1]["OPTIONS"]["string_if_invalid"] = "test"
|
|
|
with self.settings(TEMPLATES=TEMPLATES):
|
|
|
- self.assertEqual(check_string_if_invalid_is_string(None), [])
|
|
|
+ self.assertEqual(self._check_engines(engines.all()), [])
|
|
|
|
|
|
def test_string_if_invalid_not_specified(self):
|
|
|
TEMPLATES = deepcopy(self.TEMPLATES_STRING_IF_INVALID)
|
|
|
del TEMPLATES[1]["OPTIONS"]["string_if_invalid"]
|
|
|
with self.settings(TEMPLATES=TEMPLATES):
|
|
|
- self.assertEqual(check_string_if_invalid_is_string(None), [self.error1])
|
|
|
+ _engines = engines.all()
|
|
|
+ errors = [self._get_error_for_engine(_engines[0])]
|
|
|
+ self.assertEqual(self._check_engines(_engines), errors)
|
|
|
|
|
|
|
|
|
class CheckTemplateTagLibrariesWithSameName(SimpleTestCase):
|
|
|
- @classmethod
|
|
|
- def setUpClass(cls):
|
|
|
- super().setUpClass()
|
|
|
- cls.warning_same_tags = Warning(
|
|
|
- W003.msg.format(
|
|
|
- "'same_tags'",
|
|
|
- "'check_framework.template_test_apps.same_tags_app_1."
|
|
|
- "templatetags.same_tags', "
|
|
|
- "'check_framework.template_test_apps.same_tags_app_2."
|
|
|
- "templatetags.same_tags'",
|
|
|
- ),
|
|
|
- id=W003.id,
|
|
|
- )
|
|
|
-
|
|
|
- @staticmethod
|
|
|
- def get_settings(module_name, module_path):
|
|
|
+ def get_settings(self, module_name, module_path, name="django"):
|
|
|
return {
|
|
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
|
|
+ "NAME": name,
|
|
|
"OPTIONS": {
|
|
|
"libraries": {
|
|
|
module_name: f"check_framework.template_test_apps.{module_path}",
|
|
@@ -130,6 +107,20 @@ class CheckTemplateTagLibrariesWithSameName(SimpleTestCase):
|
|
|
},
|
|
|
}
|
|
|
|
|
|
+ def _get_error_for_engine(self, engine, modules):
|
|
|
+ return Warning(
|
|
|
+ f"'same_tags' is used for multiple template tag modules: {modules}",
|
|
|
+ obj=engine,
|
|
|
+ id="templates.W003",
|
|
|
+ )
|
|
|
+
|
|
|
+ def _check_engines(self, engines):
|
|
|
+ return list(
|
|
|
+ chain.from_iterable(
|
|
|
+ e._check_for_template_tags_with_the_same_name() for e in engines
|
|
|
+ )
|
|
|
+ )
|
|
|
+
|
|
|
@override_settings(
|
|
|
INSTALLED_APPS=[
|
|
|
"check_framework.template_test_apps.same_tags_app_1",
|
|
@@ -137,26 +128,32 @@ class CheckTemplateTagLibrariesWithSameName(SimpleTestCase):
|
|
|
]
|
|
|
)
|
|
|
def test_template_tags_with_same_name(self):
|
|
|
- self.assertEqual(
|
|
|
- check_for_template_tags_with_the_same_name(None),
|
|
|
- [self.warning_same_tags],
|
|
|
+ _engines = engines.all()
|
|
|
+ modules = (
|
|
|
+ "'check_framework.template_test_apps.same_tags_app_1.templatetags"
|
|
|
+ ".same_tags', 'check_framework.template_test_apps.same_tags_app_2"
|
|
|
+ ".templatetags.same_tags'"
|
|
|
)
|
|
|
+ errors = [self._get_error_for_engine(_engines[0], modules)]
|
|
|
+ self.assertEqual(self._check_engines(_engines), errors)
|
|
|
|
|
|
- def test_template_tags_with_same_library_name(self):
|
|
|
+ def test_template_tags_for_separate_backends(self):
|
|
|
+ # The "libraries" names are the same, but the backends are different.
|
|
|
with self.settings(
|
|
|
TEMPLATES=[
|
|
|
self.get_settings(
|
|
|
- "same_tags", "same_tags_app_1.templatetags.same_tags"
|
|
|
+ "same_tags",
|
|
|
+ "same_tags_app_1.templatetags.same_tags",
|
|
|
+ name="backend_1",
|
|
|
),
|
|
|
self.get_settings(
|
|
|
- "same_tags", "same_tags_app_2.templatetags.same_tags"
|
|
|
+ "same_tags",
|
|
|
+ "same_tags_app_2.templatetags.same_tags",
|
|
|
+ name="backend_2",
|
|
|
),
|
|
|
]
|
|
|
):
|
|
|
- self.assertEqual(
|
|
|
- check_for_template_tags_with_the_same_name(None),
|
|
|
- [self.warning_same_tags],
|
|
|
- )
|
|
|
+ self.assertEqual(self._check_engines(engines.all()), [])
|
|
|
|
|
|
@override_settings(
|
|
|
INSTALLED_APPS=["check_framework.template_test_apps.same_tags_app_1"]
|
|
@@ -169,48 +166,44 @@ class CheckTemplateTagLibrariesWithSameName(SimpleTestCase):
|
|
|
),
|
|
|
]
|
|
|
):
|
|
|
- self.assertEqual(check_for_template_tags_with_the_same_name(None), [])
|
|
|
+ self.assertEqual(self._check_engines(engines.all()), [])
|
|
|
|
|
|
@override_settings(
|
|
|
INSTALLED_APPS=["check_framework.template_test_apps.same_tags_app_1"]
|
|
|
)
|
|
|
def test_template_tags_with_same_library_name_and_module_name(self):
|
|
|
+ modules = (
|
|
|
+ "'check_framework.template_test_apps.different_tags_app.templatetags"
|
|
|
+ ".different_tags', 'check_framework.template_test_apps.same_tags_app_1"
|
|
|
+ ".templatetags.same_tags'"
|
|
|
+ )
|
|
|
with self.settings(
|
|
|
TEMPLATES=[
|
|
|
self.get_settings(
|
|
|
- "same_tags",
|
|
|
- "different_tags_app.templatetags.different_tags",
|
|
|
+ "same_tags", "different_tags_app.templatetags.different_tags"
|
|
|
),
|
|
|
]
|
|
|
):
|
|
|
- self.assertEqual(
|
|
|
- check_for_template_tags_with_the_same_name(None),
|
|
|
- [
|
|
|
- Warning(
|
|
|
- W003.msg.format(
|
|
|
- "'same_tags'",
|
|
|
- "'check_framework.template_test_apps.different_tags_app."
|
|
|
- "templatetags.different_tags', "
|
|
|
- "'check_framework.template_test_apps.same_tags_app_1."
|
|
|
- "templatetags.same_tags'",
|
|
|
- ),
|
|
|
- id=W003.id,
|
|
|
- )
|
|
|
- ],
|
|
|
- )
|
|
|
+ _engines = engines.all()
|
|
|
+ errors = [self._get_error_for_engine(_engines[0], modules)]
|
|
|
+ self.assertEqual(self._check_engines(_engines), errors)
|
|
|
|
|
|
def test_template_tags_with_different_library_name(self):
|
|
|
with self.settings(
|
|
|
TEMPLATES=[
|
|
|
self.get_settings(
|
|
|
- "same_tags", "same_tags_app_1.templatetags.same_tags"
|
|
|
+ "same_tags",
|
|
|
+ "same_tags_app_1.templatetags.same_tags",
|
|
|
+ name="backend_1",
|
|
|
),
|
|
|
self.get_settings(
|
|
|
- "not_same_tags", "same_tags_app_2.templatetags.same_tags"
|
|
|
+ "not_same_tags",
|
|
|
+ "same_tags_app_2.templatetags.same_tags",
|
|
|
+ name="backend_2",
|
|
|
),
|
|
|
]
|
|
|
):
|
|
|
- self.assertEqual(check_for_template_tags_with_the_same_name(None), [])
|
|
|
+ self.assertEqual(self._check_engines(engines.all()), [])
|
|
|
|
|
|
@override_settings(
|
|
|
INSTALLED_APPS=[
|
|
@@ -219,4 +212,4 @@ class CheckTemplateTagLibrariesWithSameName(SimpleTestCase):
|
|
|
]
|
|
|
)
|
|
|
def test_template_tags_with_different_name(self):
|
|
|
- self.assertEqual(check_for_template_tags_with_the_same_name(None), [])
|
|
|
+ self.assertEqual(self._check_engines(engines.all()), [])
|