diff options
| author | Tim Graham <timograham@gmail.com> | 2016-08-16 14:23:30 -0400 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2016-08-16 15:22:58 -0400 |
| commit | 02c276623db6deb62312ab60f530f845a5932b5d (patch) | |
| tree | 8854a63b29482dc5ec444888f3d7198114d749e7 /tests/invalid_models_tests | |
| parent | 8fb53c50ce1c759c740960c9e1cef3cef39cabc5 (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.py | 75 | ||||
| -rw-r--r-- | tests/invalid_models_tests/test_ordinary_fields.py | 21 | ||||
| -rw-r--r-- | tests/invalid_models_tests/test_relative_fields.py | 15 |
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): |
