summaryrefslogtreecommitdiff
path: root/tests/invalid_models_tests
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2016-08-16 14:23:30 -0400
committerTim Graham <timograham@gmail.com>2016-08-16 15:22:58 -0400
commit02c276623db6deb62312ab60f530f845a5932b5d (patch)
tree8854a63b29482dc5ec444888f3d7198114d749e7 /tests/invalid_models_tests
parent8fb53c50ce1c759c740960c9e1cef3cef39cabc5 (diff)
Moved model_validation tests to invalid_models_tests.
Diffstat (limited to 'tests/invalid_models_tests')
-rw-r--r--tests/invalid_models_tests/test_models.py75
-rw-r--r--tests/invalid_models_tests/test_ordinary_fields.py21
-rw-r--r--tests/invalid_models_tests/test_relative_fields.py15
3 files changed, 111 insertions, 0 deletions
diff --git a/tests/invalid_models_tests/test_models.py b/tests/invalid_models_tests/test_models.py
index fa63b9e8a7..b37fca9922 100644
--- a/tests/invalid_models_tests/test_models.py
+++ b/tests/invalid_models_tests/test_models.py
@@ -6,7 +6,9 @@ import warnings
from django.conf import settings
from django.core.checks import Error
+from django.core.checks.model_checks import _check_lazy_references
from django.db import connections, models
+from django.db.models.signals import post_init
from django.test import SimpleTestCase
from django.test.utils import isolate_apps, override_settings
@@ -827,3 +829,76 @@ class OtherModelTests(SimpleTestCase):
id='fields.E340',
)
])
+
+ @isolate_apps('django.contrib.auth', kwarg_name='apps')
+ def test_lazy_reference_checks(self, apps):
+ class DummyModel(models.Model):
+ author = models.ForeignKey('Author', models.CASCADE)
+
+ class Meta:
+ app_label = 'invalid_models_tests'
+
+ class DummyClass(object):
+ def __call__(self, **kwargs):
+ pass
+
+ def dummy_method(self):
+ pass
+
+ def dummy_function(*args, **kwargs):
+ pass
+
+ apps.lazy_model_operation(dummy_function, ('auth', 'imaginarymodel'))
+ apps.lazy_model_operation(dummy_function, ('fanciful_app', 'imaginarymodel'))
+
+ post_init.connect(dummy_function, sender='missing-app.Model', apps=apps)
+ post_init.connect(DummyClass(), sender='missing-app.Model', apps=apps)
+ post_init.connect(DummyClass().dummy_method, sender='missing-app.Model', apps=apps)
+
+ expected = [
+ Error(
+ "%r contains a lazy reference to auth.imaginarymodel, "
+ "but app 'auth' doesn't provide model 'imaginarymodel'." % dummy_function,
+ obj=dummy_function,
+ id='models.E022',
+ ),
+ Error(
+ "%r contains a lazy reference to fanciful_app.imaginarymodel, "
+ "but app 'fanciful_app' isn't installed." % dummy_function,
+ obj=dummy_function,
+ id='models.E022',
+ ),
+ Error(
+ "An instance of class 'DummyClass' was connected to "
+ "the 'post_init' signal with a lazy reference to the sender "
+ "'missing-app.model', but app 'missing-app' isn't installed.",
+ hint=None,
+ obj='invalid_models_tests.test_models',
+ id='signals.E001',
+ ),
+ Error(
+ "Bound method 'DummyClass.dummy_method' was connected to the "
+ "'post_init' signal with a lazy reference to the sender "
+ "'missing-app.model', but app 'missing-app' isn't installed.",
+ hint=None,
+ obj='invalid_models_tests.test_models',
+ id='signals.E001',
+ ),
+ Error(
+ "The field invalid_models_tests.DummyModel.author was declared "
+ "with a lazy reference to 'invalid_models_tests.author', but app "
+ "'invalid_models_tests' isn't installed.",
+ hint=None,
+ obj=DummyModel.author.field,
+ id='fields.E307',
+ ),
+ Error(
+ "The function 'dummy_function' was connected to the 'post_init' "
+ "signal with a lazy reference to the sender "
+ "'missing-app.model', but app 'missing-app' isn't installed.",
+ hint=None,
+ obj='invalid_models_tests.test_models',
+ id='signals.E001',
+ ),
+ ]
+ self.assertEqual(_check_lazy_references(apps), expected)
diff --git a/tests/invalid_models_tests/test_ordinary_fields.py b/tests/invalid_models_tests/test_ordinary_fields.py
index 0dff216cb6..2f16e83d18 100644
--- a/tests/invalid_models_tests/test_ordinary_fields.py
+++ b/tests/invalid_models_tests/test_ordinary_fields.py
@@ -157,6 +157,27 @@ class CharFieldTests(TestCase):
]
self.assertEqual(errors, expected)
+ def test_iterable_of_iterable_choices(self):
+ class ThingItem(object):
+ def __init__(self, value, display):
+ self.value = value
+ self.display = display
+
+ def __iter__(self):
+ return (x for x in [self.value, self.display])
+
+ def __len__(self):
+ return 2
+
+ class Things(object):
+ def __iter__(self):
+ return (x for x in [ThingItem(1, 2), ThingItem(3, 4)])
+
+ class ThingWithIterableChoices(models.Model):
+ thing = models.CharField(max_length=100, blank=True, choices=Things())
+
+ self.assertEqual(ThingWithIterableChoices._meta.get_field('thing').check(), [])
+
def test_choices_containing_non_pairs(self):
class Model(models.Model):
field = models.CharField(max_length=10, choices=[(1, 2, 3), (1, 2, 3)])
diff --git a/tests/invalid_models_tests/test_relative_fields.py b/tests/invalid_models_tests/test_relative_fields.py
index 01941fc58c..6756302bf1 100644
--- a/tests/invalid_models_tests/test_relative_fields.py
+++ b/tests/invalid_models_tests/test_relative_fields.py
@@ -995,6 +995,21 @@ class AccessorClashTests(SimpleTestCase):
]
self.assertEqual(errors, expected)
+ def test_no_clash_for_hidden_related_name(self):
+ class Stub(models.Model):
+ pass
+
+ class ManyToManyRel(models.Model):
+ thing1 = models.ManyToManyField(Stub, related_name='+')
+ thing2 = models.ManyToManyField(Stub, related_name='+')
+
+ class FKRel(models.Model):
+ thing1 = models.ForeignKey(Stub, models.CASCADE, related_name='+')
+ thing2 = models.ForeignKey(Stub, models.CASCADE, related_name='+')
+
+ self.assertEqual(ManyToManyRel.check(), [])
+ self.assertEqual(FKRel.check(), [])
+
@isolate_apps('invalid_models_tests')
class ReverseQueryNameClashTests(SimpleTestCase):