Made assertions in invalid_models_tests consistent.

This commit is contained in:
Adam Johnson 2017-07-11 10:53:22 +02:00 committed by Tim Graham
parent 169c3b3e07
commit f816ceedf1
5 changed files with 202 additions and 409 deletions

View File

@ -25,6 +25,4 @@ class BackendSpecificChecksTests(SimpleTestCase):
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
with mock.patch.object(connections['default'].validation, 'check_field', return_value=[error]): with mock.patch.object(connections['default'].validation, 'check_field', return_value=[error]):
errors = field.check() self.assertEqual(field.check(), [error])
self.assertEqual(errors, [error])

View File

@ -17,5 +17,4 @@ class CustomFieldTest(SimpleTestCase):
other_field = models.IntegerField() other_field = models.IntegerField()
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [])
self.assertEqual(errors, [])

View File

@ -38,45 +38,39 @@ class IndexTogetherTests(SimpleTestCase):
class Meta: class Meta:
index_together = 42 index_together = 42
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"'index_together' must be a list or tuple.", "'index_together' must be a list or tuple.",
obj=Model, obj=Model,
id='models.E008', id='models.E008',
), ),
] ])
self.assertEqual(errors, expected)
def test_non_list(self): def test_non_list(self):
class Model(models.Model): class Model(models.Model):
class Meta: class Meta:
index_together = 'not-a-list' index_together = 'not-a-list'
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"'index_together' must be a list or tuple.", "'index_together' must be a list or tuple.",
obj=Model, obj=Model,
id='models.E008', id='models.E008',
), ),
] ])
self.assertEqual(errors, expected)
def test_list_containing_non_iterable(self): def test_list_containing_non_iterable(self):
class Model(models.Model): class Model(models.Model):
class Meta: class Meta:
index_together = [('a', 'b'), 42] index_together = [('a', 'b'), 42]
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"All 'index_together' elements must be lists or tuples.", "All 'index_together' elements must be lists or tuples.",
obj=Model, obj=Model,
id='models.E009', id='models.E009',
), ),
] ])
self.assertEqual(errors, expected)
def test_pointing_to_missing_field(self): def test_pointing_to_missing_field(self):
class Model(models.Model): class Model(models.Model):
@ -85,15 +79,13 @@ class IndexTogetherTests(SimpleTestCase):
["missing_field"], ["missing_field"],
] ]
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"'index_together' refers to the nonexistent field 'missing_field'.", "'index_together' refers to the nonexistent field 'missing_field'.",
obj=Model, obj=Model,
id='models.E012', id='models.E012',
), ),
] ])
self.assertEqual(errors, expected)
def test_pointing_to_non_local_field(self): def test_pointing_to_non_local_field(self):
class Foo(models.Model): class Foo(models.Model):
@ -107,8 +99,7 @@ class IndexTogetherTests(SimpleTestCase):
["field2", "field1"], ["field2", "field1"],
] ]
errors = Bar.check() self.assertEqual(Bar.check(), [
expected = [
Error( Error(
"'index_together' refers to field 'field1' which is not " "'index_together' refers to field 'field1' which is not "
"local to model 'Bar'.", "local to model 'Bar'.",
@ -116,8 +107,7 @@ class IndexTogetherTests(SimpleTestCase):
obj=Bar, obj=Bar,
id='models.E016', id='models.E016',
), ),
] ])
self.assertEqual(errors, expected)
def test_pointing_to_m2m_field(self): def test_pointing_to_m2m_field(self):
class Model(models.Model): class Model(models.Model):
@ -128,16 +118,14 @@ class IndexTogetherTests(SimpleTestCase):
["m2m"], ["m2m"],
] ]
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"'index_together' refers to a ManyToManyField 'm2m', but " "'index_together' refers to a ManyToManyField 'm2m', but "
"ManyToManyFields are not permitted in 'index_together'.", "ManyToManyFields are not permitted in 'index_together'.",
obj=Model, obj=Model,
id='models.E013', id='models.E013',
), ),
] ])
self.assertEqual(errors, expected)
# unique_together tests are very similar to index_together tests. # unique_together tests are very similar to index_together tests.
@ -149,15 +137,13 @@ class UniqueTogetherTests(SimpleTestCase):
class Meta: class Meta:
unique_together = 42 unique_together = 42
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"'unique_together' must be a list or tuple.", "'unique_together' must be a list or tuple.",
obj=Model, obj=Model,
id='models.E010', id='models.E010',
), ),
] ])
self.assertEqual(errors, expected)
def test_list_containing_non_iterable(self): def test_list_containing_non_iterable(self):
class Model(models.Model): class Model(models.Model):
@ -167,30 +153,26 @@ class UniqueTogetherTests(SimpleTestCase):
class Meta: class Meta:
unique_together = [('a', 'b'), 42] unique_together = [('a', 'b'), 42]
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"All 'unique_together' elements must be lists or tuples.", "All 'unique_together' elements must be lists or tuples.",
obj=Model, obj=Model,
id='models.E011', id='models.E011',
), ),
] ])
self.assertEqual(errors, expected)
def test_non_list(self): def test_non_list(self):
class Model(models.Model): class Model(models.Model):
class Meta: class Meta:
unique_together = 'not-a-list' unique_together = 'not-a-list'
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"'unique_together' must be a list or tuple.", "'unique_together' must be a list or tuple.",
obj=Model, obj=Model,
id='models.E010', id='models.E010',
), ),
] ])
self.assertEqual(errors, expected)
def test_valid_model(self): def test_valid_model(self):
class Model(models.Model): class Model(models.Model):
@ -201,8 +183,7 @@ class UniqueTogetherTests(SimpleTestCase):
# unique_together can be a simple tuple # unique_together can be a simple tuple
unique_together = ('one', 'two') unique_together = ('one', 'two')
errors = Model.check() self.assertEqual(Model.check(), [])
self.assertEqual(errors, [])
def test_pointing_to_missing_field(self): def test_pointing_to_missing_field(self):
class Model(models.Model): class Model(models.Model):
@ -211,15 +192,13 @@ class UniqueTogetherTests(SimpleTestCase):
["missing_field"], ["missing_field"],
] ]
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"'unique_together' refers to the nonexistent field 'missing_field'.", "'unique_together' refers to the nonexistent field 'missing_field'.",
obj=Model, obj=Model,
id='models.E012', id='models.E012',
), ),
] ])
self.assertEqual(errors, expected)
def test_pointing_to_m2m(self): def test_pointing_to_m2m(self):
class Model(models.Model): class Model(models.Model):
@ -230,16 +209,14 @@ class UniqueTogetherTests(SimpleTestCase):
["m2m"], ["m2m"],
] ]
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"'unique_together' refers to a ManyToManyField 'm2m', but " "'unique_together' refers to a ManyToManyField 'm2m', but "
"ManyToManyFields are not permitted in 'unique_together'.", "ManyToManyFields are not permitted in 'unique_together'.",
obj=Model, obj=Model,
id='models.E013', id='models.E013',
), ),
] ])
self.assertEqual(errors, expected)
@isolate_apps('invalid_models_tests') @isolate_apps('invalid_models_tests')
@ -250,8 +227,7 @@ class FieldNamesTests(SimpleTestCase):
field_ = models.CharField(max_length=10) field_ = models.CharField(max_length=10)
m2m_ = models.ManyToManyField('self') m2m_ = models.ManyToManyField('self')
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
'Field names must not end with an underscore.', 'Field names must not end with an underscore.',
obj=Model._meta.get_field('field_'), obj=Model._meta.get_field('field_'),
@ -262,8 +238,7 @@ class FieldNamesTests(SimpleTestCase):
obj=Model._meta.get_field('m2m_'), obj=Model._meta.get_field('m2m_'),
id='fields.E001', id='fields.E001',
), ),
] ])
self.assertEqual(errors, expected)
max_column_name_length, column_limit_db_alias = get_max_column_name_length() max_column_name_length, column_limit_db_alias = get_max_column_name_length()
@ -373,12 +348,7 @@ class FieldNamesTests(SimpleTestCase):
long_field_name2 = 'b' * (self.max_column_name_length + 1) long_field_name2 = 'b' * (self.max_column_name_length + 1)
models.CharField(max_length=11).contribute_to_class(ModelWithLongField, long_field_name) models.CharField(max_length=11).contribute_to_class(ModelWithLongField, long_field_name)
models.CharField(max_length=11, db_column='vlmn').contribute_to_class(ModelWithLongField, long_field_name2) models.CharField(max_length=11, db_column='vlmn').contribute_to_class(ModelWithLongField, long_field_name2)
self.assertEqual(ModelWithLongField.check(), [
errors = ModelWithLongField.check()
# Error because of the field with long name added to the model
# without specifying db_column
expected = [
Error( Error(
'Autogenerated column name too long for field "%s". ' 'Autogenerated column name too long for field "%s". '
'Maximum length is "%s" for database "%s".' 'Maximum length is "%s" for database "%s".'
@ -387,37 +357,31 @@ class FieldNamesTests(SimpleTestCase):
obj=ModelWithLongField, obj=ModelWithLongField,
id='models.E018', id='models.E018',
) )
] ])
self.assertEqual(errors, expected)
def test_including_separator(self): def test_including_separator(self):
class Model(models.Model): class Model(models.Model):
some__field = models.IntegerField() some__field = models.IntegerField()
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
'Field names must not contain "__".', 'Field names must not contain "__".',
obj=Model._meta.get_field('some__field'), obj=Model._meta.get_field('some__field'),
id='fields.E002', id='fields.E002',
) )
] ])
self.assertEqual(errors, expected)
def test_pk(self): def test_pk(self):
class Model(models.Model): class Model(models.Model):
pk = models.IntegerField() pk = models.IntegerField()
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"'pk' is a reserved word that cannot be used as a field name.", "'pk' is a reserved word that cannot be used as a field name.",
obj=Model._meta.get_field('pk'), obj=Model._meta.get_field('pk'),
id='fields.E003', id='fields.E003',
) )
] ])
self.assertEqual(errors, expected)
@isolate_apps('invalid_models_tests') @isolate_apps('invalid_models_tests')
@ -430,16 +394,14 @@ class ShadowingFieldsTests(SimpleTestCase):
class Child(Parent): class Child(Parent):
child = models.CharField(max_length=100) child = models.CharField(max_length=100)
errors = Child.check() self.assertEqual(Child.check(), [
expected = [
Error( Error(
"The field 'child' clashes with the field " "The field 'child' clashes with the field "
"'child' from model 'invalid_models_tests.parent'.", "'child' from model 'invalid_models_tests.parent'.",
obj=Child._meta.get_field('child'), obj=Child._meta.get_field('child'),
id='models.E006', id='models.E006',
) )
] ])
self.assertEqual(errors, expected)
def test_multiinheritance_clash(self): def test_multiinheritance_clash(self):
class Mother(models.Model): class Mother(models.Model):
@ -453,8 +415,7 @@ class ShadowingFieldsTests(SimpleTestCase):
# both parents define these fields. # both parents define these fields.
pass pass
errors = Child.check() self.assertEqual(Child.check(), [
expected = [
Error( Error(
"The field 'id' from parent model " "The field 'id' from parent model "
"'invalid_models_tests.mother' clashes with the field 'id' " "'invalid_models_tests.mother' clashes with the field 'id' "
@ -469,8 +430,7 @@ class ShadowingFieldsTests(SimpleTestCase):
obj=Child, obj=Child,
id='models.E005', id='models.E005',
) )
] ])
self.assertEqual(errors, expected)
def test_inheritance_clash(self): def test_inheritance_clash(self):
class Parent(models.Model): class Parent(models.Model):
@ -484,16 +444,14 @@ class ShadowingFieldsTests(SimpleTestCase):
# This field clashes with parent "f_id" field. # This field clashes with parent "f_id" field.
f = models.ForeignKey(Target, models.CASCADE) f = models.ForeignKey(Target, models.CASCADE)
errors = Child.check() self.assertEqual(Child.check(), [
expected = [
Error( Error(
"The field 'f' clashes with the field 'f_id' " "The field 'f' clashes with the field 'f_id' "
"from model 'invalid_models_tests.parent'.", "from model 'invalid_models_tests.parent'.",
obj=Child._meta.get_field('f'), obj=Child._meta.get_field('f'),
id='models.E006', id='models.E006',
) )
] ])
self.assertEqual(errors, expected)
def test_multigeneration_inheritance(self): def test_multigeneration_inheritance(self):
class GrandParent(models.Model): class GrandParent(models.Model):
@ -508,16 +466,14 @@ class ShadowingFieldsTests(SimpleTestCase):
class GrandChild(Child): class GrandChild(Child):
clash = models.IntegerField() clash = models.IntegerField()
errors = GrandChild.check() self.assertEqual(GrandChild.check(), [
expected = [
Error( Error(
"The field 'clash' clashes with the field 'clash' " "The field 'clash' clashes with the field 'clash' "
"from model 'invalid_models_tests.grandparent'.", "from model 'invalid_models_tests.grandparent'.",
obj=GrandChild._meta.get_field('clash'), obj=GrandChild._meta.get_field('clash'),
id='models.E006', id='models.E006',
) )
] ])
self.assertEqual(errors, expected)
def test_id_clash(self): def test_id_clash(self):
class Target(models.Model): class Target(models.Model):
@ -527,16 +483,14 @@ class ShadowingFieldsTests(SimpleTestCase):
fk = models.ForeignKey(Target, models.CASCADE) fk = models.ForeignKey(Target, models.CASCADE)
fk_id = models.IntegerField() fk_id = models.IntegerField()
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"The field 'fk_id' clashes with the field 'fk' from model " "The field 'fk_id' clashes with the field 'fk' from model "
"'invalid_models_tests.model'.", "'invalid_models_tests.model'.",
obj=Model._meta.get_field('fk_id'), obj=Model._meta.get_field('fk_id'),
id='models.E006', id='models.E006',
) )
] ])
self.assertEqual(errors, expected)
@isolate_apps('invalid_models_tests') @isolate_apps('invalid_models_tests')
@ -548,32 +502,28 @@ class OtherModelTests(SimpleTestCase):
class Model(models.Model): class Model(models.Model):
id = invalid_id id = invalid_id
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"'id' can only be used as a field name if the field also sets " "'id' can only be used as a field name if the field also sets "
"'primary_key=True'.", "'primary_key=True'.",
obj=Model, obj=Model,
id='models.E004', id='models.E004',
), ),
] ])
self.assertEqual(errors, expected)
def test_ordering_non_iterable(self): def test_ordering_non_iterable(self):
class Model(models.Model): class Model(models.Model):
class Meta: class Meta:
ordering = "missing_field" ordering = "missing_field"
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"'ordering' must be a tuple or list " "'ordering' must be a tuple or list "
"(even if you want to order by only one field).", "(even if you want to order by only one field).",
obj=Model, obj=Model,
id='models.E014', id='models.E014',
), ),
] ])
self.assertEqual(errors, expected)
def test_just_ordering_no_errors(self): def test_just_ordering_no_errors(self):
class Model(models.Model): class Model(models.Model):
@ -608,15 +558,13 @@ class OtherModelTests(SimpleTestCase):
order_with_respect_to = 'question' order_with_respect_to = 'question'
ordering = ['order'] ordering = ['order']
errors = Answer.check() self.assertEqual(Answer.check(), [
expected = [
Error( Error(
"'ordering' and 'order_with_respect_to' cannot be used together.", "'ordering' and 'order_with_respect_to' cannot be used together.",
obj=Answer, obj=Answer,
id='models.E021', id='models.E021',
), ),
] ])
self.assertEqual(errors, expected)
def test_non_valid(self): def test_non_valid(self):
class RelationModel(models.Model): class RelationModel(models.Model):
@ -628,30 +576,26 @@ class OtherModelTests(SimpleTestCase):
class Meta: class Meta:
ordering = ['relation'] ordering = ['relation']
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"'ordering' refers to the nonexistent field 'relation'.", "'ordering' refers to the nonexistent field 'relation'.",
obj=Model, obj=Model,
id='models.E015', id='models.E015',
), ),
] ])
self.assertEqual(errors, expected)
def test_ordering_pointing_to_missing_field(self): def test_ordering_pointing_to_missing_field(self):
class Model(models.Model): class Model(models.Model):
class Meta: class Meta:
ordering = ("missing_field",) ordering = ("missing_field",)
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"'ordering' refers to the nonexistent field 'missing_field'.", "'ordering' refers to the nonexistent field 'missing_field'.",
obj=Model, obj=Model,
id='models.E015', id='models.E015',
) )
] ])
self.assertEqual(errors, expected)
def test_ordering_pointing_to_missing_foreignkey_field(self): def test_ordering_pointing_to_missing_foreignkey_field(self):
# refs #22711 # refs #22711
@ -662,15 +606,13 @@ class OtherModelTests(SimpleTestCase):
class Meta: class Meta:
ordering = ("missing_fk_field_id",) ordering = ("missing_fk_field_id",)
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"'ordering' refers to the nonexistent field 'missing_fk_field_id'.", "'ordering' refers to the nonexistent field 'missing_fk_field_id'.",
obj=Model, obj=Model,
id='models.E015', id='models.E015',
) )
] ])
self.assertEqual(errors, expected)
def test_ordering_pointing_to_existing_foreignkey_field(self): def test_ordering_pointing_to_existing_foreignkey_field(self):
# refs #22711 # refs #22711
@ -731,14 +673,12 @@ class OtherModelTests(SimpleTestCase):
class Meta: class Meta:
swappable = 'TEST_SWAPPED_MODEL_BAD_VALUE' swappable = 'TEST_SWAPPED_MODEL_BAD_VALUE'
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"'TEST_SWAPPED_MODEL_BAD_VALUE' is not of the form 'app_label.app_name'.", "'TEST_SWAPPED_MODEL_BAD_VALUE' is not of the form 'app_label.app_name'.",
id='models.E001', id='models.E001',
), ),
] ])
self.assertEqual(errors, expected)
@override_settings(TEST_SWAPPED_MODEL_BAD_MODEL='not_an_app.Target') @override_settings(TEST_SWAPPED_MODEL_BAD_MODEL='not_an_app.Target')
def test_swappable_missing_app(self): def test_swappable_missing_app(self):
@ -746,15 +686,13 @@ class OtherModelTests(SimpleTestCase):
class Meta: class Meta:
swappable = 'TEST_SWAPPED_MODEL_BAD_MODEL' swappable = 'TEST_SWAPPED_MODEL_BAD_MODEL'
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"'TEST_SWAPPED_MODEL_BAD_MODEL' references 'not_an_app.Target', " "'TEST_SWAPPED_MODEL_BAD_MODEL' references 'not_an_app.Target', "
'which has not been installed, or is abstract.', 'which has not been installed, or is abstract.',
id='models.E002', id='models.E002',
), ),
] ])
self.assertEqual(errors, expected)
def test_two_m2m_through_same_relationship(self): def test_two_m2m_through_same_relationship(self):
class Person(models.Model): class Person(models.Model):
@ -768,16 +706,14 @@ class OtherModelTests(SimpleTestCase):
person = models.ForeignKey(Person, models.CASCADE) person = models.ForeignKey(Person, models.CASCADE)
group = models.ForeignKey(Group, models.CASCADE) group = models.ForeignKey(Group, models.CASCADE)
errors = Group.check() self.assertEqual(Group.check(), [
expected = [
Error( Error(
"The model has two many-to-many relations through " "The model has two many-to-many relations through "
"the intermediate model 'invalid_models_tests.Membership'.", "the intermediate model 'invalid_models_tests.Membership'.",
obj=Group, obj=Group,
id='models.E003', id='models.E003',
) )
] ])
self.assertEqual(errors, expected)
def test_missing_parent_link(self): def test_missing_parent_link(self):
msg = 'Add parent_link=True to invalid_models_tests.ParkingLot.parent.' msg = 'Add parent_link=True to invalid_models_tests.ParkingLot.parent.'
@ -927,7 +863,7 @@ class OtherModelTests(SimpleTestCase):
post_init.connect(DummyClass(), 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) post_init.connect(DummyClass().dummy_method, sender='missing-app.Model', apps=apps)
expected = [ self.assertEqual(_check_lazy_references(apps), [
Error( Error(
"%r contains a lazy reference to auth.imaginarymodel, " "%r contains a lazy reference to auth.imaginarymodel, "
"but app 'auth' doesn't provide model 'imaginarymodel'." % dummy_function, "but app 'auth' doesn't provide model 'imaginarymodel'." % dummy_function,
@ -972,5 +908,4 @@ class OtherModelTests(SimpleTestCase):
obj='invalid_models_tests.test_models', obj='invalid_models_tests.test_models',
id='signals.E001', id='signals.E001',
), ),
] ])
self.assertEqual(_check_lazy_references(apps), expected)

View File

@ -15,9 +15,7 @@ class AutoFieldTests(SimpleTestCase):
id = models.AutoField(primary_key=True) id = models.AutoField(primary_key=True)
field = Model._meta.get_field('id') field = Model._meta.get_field('id')
errors = field.check() self.assertEqual(field.check(), [])
expected = []
self.assertEqual(errors, expected)
def test_primary_key(self): def test_primary_key(self):
# primary_key must be True. Refs #12467. # primary_key must be True. Refs #12467.
@ -30,15 +28,13 @@ class AutoFieldTests(SimpleTestCase):
another = models.IntegerField(primary_key=True) another = models.IntegerField(primary_key=True)
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
'AutoFields must set primary_key=True.', 'AutoFields must set primary_key=True.',
obj=field, obj=field,
id='fields.E100', id='fields.E100',
), ),
] ])
self.assertEqual(errors, expected)
@isolate_apps('invalid_models_tests') @isolate_apps('invalid_models_tests')
@ -49,16 +45,14 @@ class BooleanFieldTests(SimpleTestCase):
field = models.BooleanField(null=True) field = models.BooleanField(null=True)
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
'BooleanFields do not accept null values.', 'BooleanFields do not accept null values.',
hint='Use a NullBooleanField instead.', hint='Use a NullBooleanField instead.',
obj=field, obj=field,
id='fields.E110', id='fields.E110',
), ),
] ])
self.assertEqual(errors, expected)
@isolate_apps('invalid_models_tests') @isolate_apps('invalid_models_tests')
@ -75,99 +69,85 @@ class CharFieldTests(TestCase):
db_index=True) db_index=True)
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [])
expected = []
self.assertEqual(errors, expected)
def test_missing_max_length(self): def test_missing_max_length(self):
class Model(models.Model): class Model(models.Model):
field = models.CharField() field = models.CharField()
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
"CharFields must define a 'max_length' attribute.", "CharFields must define a 'max_length' attribute.",
obj=field, obj=field,
id='fields.E120', id='fields.E120',
), ),
] ])
self.assertEqual(errors, expected)
def test_negative_max_length(self): def test_negative_max_length(self):
class Model(models.Model): class Model(models.Model):
field = models.CharField(max_length=-1) field = models.CharField(max_length=-1)
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
"'max_length' must be a positive integer.", "'max_length' must be a positive integer.",
obj=field, obj=field,
id='fields.E121', id='fields.E121',
), ),
] ])
self.assertEqual(errors, expected)
def test_bad_max_length_value(self): def test_bad_max_length_value(self):
class Model(models.Model): class Model(models.Model):
field = models.CharField(max_length="bad") field = models.CharField(max_length="bad")
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
"'max_length' must be a positive integer.", "'max_length' must be a positive integer.",
obj=field, obj=field,
id='fields.E121', id='fields.E121',
), ),
] ])
self.assertEqual(errors, expected)
def test_str_max_length_value(self): def test_str_max_length_value(self):
class Model(models.Model): class Model(models.Model):
field = models.CharField(max_length='20') field = models.CharField(max_length='20')
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
"'max_length' must be a positive integer.", "'max_length' must be a positive integer.",
obj=field, obj=field,
id='fields.E121', id='fields.E121',
), ),
] ])
self.assertEqual(errors, expected)
def test_str_max_length_type(self): def test_str_max_length_type(self):
class Model(models.Model): class Model(models.Model):
field = models.CharField(max_length=True) field = models.CharField(max_length=True)
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
"'max_length' must be a positive integer.", "'max_length' must be a positive integer.",
obj=field, obj=field,
id='fields.E121' id='fields.E121'
), ),
] ])
self.assertEqual(errors, expected)
def test_non_iterable_choices(self): def test_non_iterable_choices(self):
class Model(models.Model): class Model(models.Model):
field = models.CharField(max_length=10, choices='bad') field = models.CharField(max_length=10, choices='bad')
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
"'choices' must be an iterable (e.g., a list or tuple).", "'choices' must be an iterable (e.g., a list or tuple).",
obj=field, obj=field,
id='fields.E004', id='fields.E004',
), ),
] ])
self.assertEqual(errors, expected)
def test_iterable_of_iterable_choices(self): def test_iterable_of_iterable_choices(self):
class ThingItem: class ThingItem:
@ -195,30 +175,26 @@ class CharFieldTests(TestCase):
field = models.CharField(max_length=10, choices=[(1, 2, 3), (1, 2, 3)]) field = models.CharField(max_length=10, choices=[(1, 2, 3), (1, 2, 3)])
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
"'choices' must be an iterable containing (actual value, human readable name) tuples.", "'choices' must be an iterable containing (actual value, human readable name) tuples.",
obj=field, obj=field,
id='fields.E005', id='fields.E005',
), ),
] ])
self.assertEqual(errors, expected)
def test_bad_db_index_value(self): def test_bad_db_index_value(self):
class Model(models.Model): class Model(models.Model):
field = models.CharField(max_length=10, db_index='bad') field = models.CharField(max_length=10, db_index='bad')
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
"'db_index' must be None, True or False.", "'db_index' must be None, True or False.",
obj=field, obj=field,
id='fields.E006', id='fields.E006',
), ),
] ])
self.assertEqual(errors, expected)
def test_bad_validators(self): def test_bad_validators(self):
class Model(models.Model): class Model(models.Model):
@ -247,19 +223,18 @@ class CharFieldTests(TestCase):
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
validator = DatabaseValidation(connection=connection) validator = DatabaseValidation(connection=connection)
errors = validator.check_field(field) self.assertEqual(validator.check_field(field), [
expected = [
Error( Error(
'MySQL does not allow unique CharFields to have a max_length > 255.', 'MySQL does not allow unique CharFields to have a max_length > 255.',
obj=field, obj=field,
id='mysql.E001', id='mysql.E001',
) )
] ])
self.assertEqual(errors, expected)
@isolate_apps('invalid_models_tests') @isolate_apps('invalid_models_tests')
class DateFieldTests(TestCase): class DateFieldTests(TestCase):
maxDiff = None
def test_auto_now_and_auto_now_add_raise_error(self): def test_auto_now_and_auto_now_add_raise_error(self):
class Model(models.Model): class Model(models.Model):
@ -294,7 +269,7 @@ class DateFieldTests(TestCase):
errors = field_dt.check() errors = field_dt.check()
errors.extend(field_d.check()) errors.extend(field_d.check())
errors.extend(field_now.check()) # doesn't raise a warning errors.extend(field_now.check()) # doesn't raise a warning
expected = [ self.assertEqual(errors, [
DjangoWarning( DjangoWarning(
'Fixed default value provided.', 'Fixed default value provided.',
hint='It seems you set a fixed date / time / datetime ' hint='It seems you set a fixed date / time / datetime '
@ -313,11 +288,7 @@ class DateFieldTests(TestCase):
obj=field_d, obj=field_d,
id='fields.W161', id='fields.W161',
) )
] ])
maxDiff = self.maxDiff
self.maxDiff = None
self.assertEqual(errors, expected)
self.maxDiff = maxDiff
@override_settings(USE_TZ=True) @override_settings(USE_TZ=True)
def test_fix_default_value_tz(self): def test_fix_default_value_tz(self):
@ -326,6 +297,7 @@ class DateFieldTests(TestCase):
@isolate_apps('invalid_models_tests') @isolate_apps('invalid_models_tests')
class DateTimeFieldTests(TestCase): class DateTimeFieldTests(TestCase):
maxDiff = None
def test_fix_default_value(self): def test_fix_default_value(self):
class Model(models.Model): class Model(models.Model):
@ -339,7 +311,7 @@ class DateTimeFieldTests(TestCase):
errors = field_dt.check() errors = field_dt.check()
errors.extend(field_d.check()) errors.extend(field_d.check())
errors.extend(field_now.check()) # doesn't raise a warning errors.extend(field_now.check()) # doesn't raise a warning
expected = [ self.assertEqual(errors, [
DjangoWarning( DjangoWarning(
'Fixed default value provided.', 'Fixed default value provided.',
hint='It seems you set a fixed date / time / datetime ' hint='It seems you set a fixed date / time / datetime '
@ -358,11 +330,7 @@ class DateTimeFieldTests(TestCase):
obj=field_d, obj=field_d,
id='fields.W161', id='fields.W161',
) )
] ])
maxDiff = self.maxDiff
self.maxDiff = None
self.assertEqual(errors, expected)
self.maxDiff = maxDiff
@override_settings(USE_TZ=True) @override_settings(USE_TZ=True)
def test_fix_default_value_tz(self): def test_fix_default_value_tz(self):
@ -377,8 +345,7 @@ class DecimalFieldTests(SimpleTestCase):
field = models.DecimalField() field = models.DecimalField()
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
"DecimalFields must define a 'decimal_places' attribute.", "DecimalFields must define a 'decimal_places' attribute.",
obj=field, obj=field,
@ -389,16 +356,14 @@ class DecimalFieldTests(SimpleTestCase):
obj=field, obj=field,
id='fields.E132', id='fields.E132',
), ),
] ])
self.assertEqual(errors, expected)
def test_negative_max_digits_and_decimal_places(self): def test_negative_max_digits_and_decimal_places(self):
class Model(models.Model): class Model(models.Model):
field = models.DecimalField(max_digits=-1, decimal_places=-1) field = models.DecimalField(max_digits=-1, decimal_places=-1)
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
"'decimal_places' must be a non-negative integer.", "'decimal_places' must be a non-negative integer.",
obj=field, obj=field,
@ -409,16 +374,14 @@ class DecimalFieldTests(SimpleTestCase):
obj=field, obj=field,
id='fields.E133', id='fields.E133',
), ),
] ])
self.assertEqual(errors, expected)
def test_bad_values_of_max_digits_and_decimal_places(self): def test_bad_values_of_max_digits_and_decimal_places(self):
class Model(models.Model): class Model(models.Model):
field = models.DecimalField(max_digits="bad", decimal_places="bad") field = models.DecimalField(max_digits="bad", decimal_places="bad")
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
"'decimal_places' must be a non-negative integer.", "'decimal_places' must be a non-negative integer.",
obj=field, obj=field,
@ -429,32 +392,27 @@ class DecimalFieldTests(SimpleTestCase):
obj=field, obj=field,
id='fields.E133', id='fields.E133',
), ),
] ])
self.assertEqual(errors, expected)
def test_decimal_places_greater_than_max_digits(self): def test_decimal_places_greater_than_max_digits(self):
class Model(models.Model): class Model(models.Model):
field = models.DecimalField(max_digits=9, decimal_places=10) field = models.DecimalField(max_digits=9, decimal_places=10)
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
"'max_digits' must be greater or equal to 'decimal_places'.", "'max_digits' must be greater or equal to 'decimal_places'.",
obj=field, obj=field,
id='fields.E134', id='fields.E134',
), ),
] ])
self.assertEqual(errors, expected)
def test_valid_field(self): def test_valid_field(self):
class Model(models.Model): class Model(models.Model):
field = models.DecimalField(max_digits=10, decimal_places=10) field = models.DecimalField(max_digits=10, decimal_places=10)
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [])
expected = []
self.assertEqual(errors, expected)
@isolate_apps('invalid_models_tests') @isolate_apps('invalid_models_tests')
@ -471,24 +429,20 @@ class FileFieldTests(SimpleTestCase):
field = models.FileField(upload_to='somewhere') field = models.FileField(upload_to='somewhere')
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [])
expected = []
self.assertEqual(errors, expected)
def test_primary_key(self): def test_primary_key(self):
class Model(models.Model): class Model(models.Model):
field = models.FileField(primary_key=False, upload_to='somewhere') field = models.FileField(primary_key=False, upload_to='somewhere')
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
"'primary_key' is not a valid argument for a FileField.", "'primary_key' is not a valid argument for a FileField.",
obj=field, obj=field,
id='fields.E201', id='fields.E201',
) )
] ])
self.assertEqual(errors, expected)
def test_upload_to_starts_with_slash(self): def test_upload_to_starts_with_slash(self):
class Model(models.Model): class Model(models.Model):
@ -524,15 +478,13 @@ class FilePathFieldTests(SimpleTestCase):
field = models.FilePathField(allow_files=False, allow_folders=False) field = models.FilePathField(allow_files=False, allow_folders=False)
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
"FilePathFields must have either 'allow_files' or 'allow_folders' set to True.", "FilePathFields must have either 'allow_files' or 'allow_folders' set to True.",
obj=field, obj=field,
id='fields.E140', id='fields.E140',
), ),
] ])
self.assertEqual(errors, expected)
@isolate_apps('invalid_models_tests') @isolate_apps('invalid_models_tests')
@ -543,16 +495,14 @@ class GenericIPAddressFieldTests(SimpleTestCase):
field = models.GenericIPAddressField(null=False, blank=True) field = models.GenericIPAddressField(null=False, blank=True)
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
('GenericIPAddressFields cannot have blank=True if null=False, ' ('GenericIPAddressFields cannot have blank=True if null=False, '
'as blank values are stored as nulls.'), 'as blank values are stored as nulls.'),
obj=field, obj=field,
id='fields.E150', id='fields.E150',
), ),
] ])
self.assertEqual(errors, expected)
@isolate_apps('invalid_models_tests') @isolate_apps('invalid_models_tests')
@ -590,21 +540,20 @@ class IntegerFieldTests(SimpleTestCase):
class Model(models.Model): class Model(models.Model):
value = models.IntegerField(max_length=2) value = models.IntegerField(max_length=2)
value = Model._meta.get_field('value') field = Model._meta.get_field('value')
errors = Model.check() self.assertEqual(field.check(), [
expected = [
DjangoWarning( DjangoWarning(
"'max_length' is ignored when used with IntegerField", "'max_length' is ignored when used with IntegerField",
hint="Remove 'max_length' from field", hint="Remove 'max_length' from field",
obj=value, obj=field,
id='fields.W122', id='fields.W122',
) )
] ])
self.assertEqual(errors, expected)
@isolate_apps('invalid_models_tests') @isolate_apps('invalid_models_tests')
class TimeFieldTests(TestCase): class TimeFieldTests(TestCase):
maxDiff = None
def test_fix_default_value(self): def test_fix_default_value(self):
class Model(models.Model): class Model(models.Model):
@ -618,7 +567,7 @@ class TimeFieldTests(TestCase):
errors = field_dt.check() errors = field_dt.check()
errors.extend(field_t.check()) errors.extend(field_t.check())
errors.extend(field_now.check()) # doesn't raise a warning errors.extend(field_now.check()) # doesn't raise a warning
expected = [ self.assertEqual(errors, [
DjangoWarning( DjangoWarning(
'Fixed default value provided.', 'Fixed default value provided.',
hint='It seems you set a fixed date / time / datetime ' hint='It seems you set a fixed date / time / datetime '
@ -637,11 +586,7 @@ class TimeFieldTests(TestCase):
obj=field_t, obj=field_t,
id='fields.W161', id='fields.W161',
) )
] ])
maxDiff = self.maxDiff
self.maxDiff = None
self.assertEqual(errors, expected)
self.maxDiff = maxDiff
@override_settings(USE_TZ=True) @override_settings(USE_TZ=True)
def test_fix_default_value_tz(self): def test_fix_default_value_tz(self):

View File

@ -17,8 +17,7 @@ class RelativeFieldTests(SimpleTestCase):
field = models.ForeignKey(Target, models.CASCADE, related_name='+') field = models.ForeignKey(Target, models.CASCADE, related_name='+')
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [])
self.assertEqual(errors, [])
def test_foreign_key_to_missing_model(self): def test_foreign_key_to_missing_model(self):
# Model names are resolved when a model is being created, so we cannot # Model names are resolved when a model is being created, so we cannot
@ -28,16 +27,14 @@ class RelativeFieldTests(SimpleTestCase):
foreign_key = models.ForeignKey('Rel1', models.CASCADE) foreign_key = models.ForeignKey('Rel1', models.CASCADE)
field = Model._meta.get_field('foreign_key') field = Model._meta.get_field('foreign_key')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
"Field defines a relation with model 'Rel1', " "Field defines a relation with model 'Rel1', "
"which is either not installed, or is abstract.", "which is either not installed, or is abstract.",
obj=field, obj=field,
id='fields.E300', id='fields.E300',
), ),
] ])
self.assertEqual(errors, expected)
@isolate_apps('invalid_models_tests') @isolate_apps('invalid_models_tests')
def test_foreign_key_to_isolate_apps_model(self): def test_foreign_key_to_isolate_apps_model(self):
@ -59,16 +56,14 @@ class RelativeFieldTests(SimpleTestCase):
m2m = models.ManyToManyField("Rel2") m2m = models.ManyToManyField("Rel2")
field = Model._meta.get_field('m2m') field = Model._meta.get_field('m2m')
errors = field.check(from_model=Model) self.assertEqual(field.check(from_model=Model), [
expected = [
Error( Error(
"Field defines a relation with model 'Rel2', " "Field defines a relation with model 'Rel2', "
"which is either not installed, or is abstract.", "which is either not installed, or is abstract.",
obj=field, obj=field,
id='fields.E300', id='fields.E300',
), ),
] ])
self.assertEqual(errors, expected)
@isolate_apps('invalid_models_tests') @isolate_apps('invalid_models_tests')
def test_many_to_many_to_isolate_apps_model(self): def test_many_to_many_to_isolate_apps_model(self):
@ -112,10 +107,8 @@ class RelativeFieldTests(SimpleTestCase):
model = models.ForeignKey('Model', models.CASCADE) model = models.ForeignKey('Model', models.CASCADE)
modelm2m = models.ForeignKey('ModelM2M', models.CASCADE) modelm2m = models.ForeignKey('ModelM2M', models.CASCADE)
errors = ModelM2M.check()
field = ModelM2M._meta.get_field('m2m') field = ModelM2M._meta.get_field('m2m')
self.assertEqual(ModelM2M.check(), [
expected = [
DjangoWarning( DjangoWarning(
'null has no effect on ManyToManyField.', 'null has no effect on ManyToManyField.',
obj=field, obj=field,
@ -132,9 +125,7 @@ class RelativeFieldTests(SimpleTestCase):
obj=field, obj=field,
id='fields.W343', id='fields.W343',
), ),
] ])
self.assertEqual(errors, expected)
def test_ambiguous_relationship_model(self): def test_ambiguous_relationship_model(self):
@ -151,8 +142,7 @@ class RelativeFieldTests(SimpleTestCase):
second_model = models.ForeignKey(Group, models.CASCADE) second_model = models.ForeignKey(Group, models.CASCADE)
field = Group._meta.get_field('field') field = Group._meta.get_field('field')
errors = field.check(from_model=Group) self.assertEqual(field.check(from_model=Group), [
expected = [
Error( Error(
"The model is used as an intermediate model by " "The model is used as an intermediate model by "
"'invalid_models_tests.Group.field', but it has more than one " "'invalid_models_tests.Group.field', but it has more than one "
@ -166,8 +156,7 @@ class RelativeFieldTests(SimpleTestCase):
obj=field, obj=field,
id='fields.E335', id='fields.E335',
), ),
] ])
self.assertEqual(errors, expected)
def test_relationship_model_with_foreign_key_to_wrong_model(self): def test_relationship_model_with_foreign_key_to_wrong_model(self):
class WrongModel(models.Model): class WrongModel(models.Model):
@ -185,8 +174,7 @@ class RelativeFieldTests(SimpleTestCase):
# The last foreign key should point to Group model. # The last foreign key should point to Group model.
field = Group._meta.get_field('members') field = Group._meta.get_field('members')
errors = field.check(from_model=Group) self.assertEqual(field.check(from_model=Group), [
expected = [
Error( Error(
"The model is used as an intermediate model by " "The model is used as an intermediate model by "
"'invalid_models_tests.Group.members', but it does not " "'invalid_models_tests.Group.members', but it does not "
@ -194,8 +182,7 @@ class RelativeFieldTests(SimpleTestCase):
obj=InvalidRelationship, obj=InvalidRelationship,
id='fields.E336', id='fields.E336',
), ),
] ])
self.assertEqual(errors, expected)
def test_relationship_model_missing_foreign_key(self): def test_relationship_model_missing_foreign_key(self):
class Person(models.Model): class Person(models.Model):
@ -209,8 +196,7 @@ class RelativeFieldTests(SimpleTestCase):
# No foreign key to Person # No foreign key to Person
field = Group._meta.get_field('members') field = Group._meta.get_field('members')
errors = field.check(from_model=Group) self.assertEqual(field.check(from_model=Group), [
expected = [
Error( Error(
"The model is used as an intermediate model by " "The model is used as an intermediate model by "
"'invalid_models_tests.Group.members', but it does not have " "'invalid_models_tests.Group.members', but it does not have "
@ -218,8 +204,7 @@ class RelativeFieldTests(SimpleTestCase):
obj=InvalidRelationship, obj=InvalidRelationship,
id='fields.E336', id='fields.E336',
), ),
] ])
self.assertEqual(errors, expected)
def test_missing_relationship_model(self): def test_missing_relationship_model(self):
class Person(models.Model): class Person(models.Model):
@ -229,16 +214,14 @@ class RelativeFieldTests(SimpleTestCase):
members = models.ManyToManyField('Person', through="MissingM2MModel") members = models.ManyToManyField('Person', through="MissingM2MModel")
field = Group._meta.get_field('members') field = Group._meta.get_field('members')
errors = field.check(from_model=Group) self.assertEqual(field.check(from_model=Group), [
expected = [
Error( Error(
"Field specifies a many-to-many relation through model " "Field specifies a many-to-many relation through model "
"'MissingM2MModel', which has not been installed.", "'MissingM2MModel', which has not been installed.",
obj=field, obj=field,
id='fields.E331', id='fields.E331',
), ),
] ])
self.assertEqual(errors, expected)
def test_missing_relationship_model_on_model_check(self): def test_missing_relationship_model_on_model_check(self):
class Person(models.Model): class Person(models.Model):
@ -285,15 +268,13 @@ class RelativeFieldTests(SimpleTestCase):
second = models.ForeignKey(Person, models.CASCADE, related_name="rel_to_set") second = models.ForeignKey(Person, models.CASCADE, related_name="rel_to_set")
field = Person._meta.get_field('friends') field = Person._meta.get_field('friends')
errors = field.check(from_model=Person) self.assertEqual(field.check(from_model=Person), [
expected = [
Error( Error(
'Many-to-many fields with intermediate tables must not be symmetrical.', 'Many-to-many fields with intermediate tables must not be symmetrical.',
obj=field, obj=field,
id='fields.E332', id='fields.E332',
), ),
] ])
self.assertEqual(errors, expected)
def test_too_many_foreign_keys_in_self_referential_model(self): def test_too_many_foreign_keys_in_self_referential_model(self):
class Person(models.Model): class Person(models.Model):
@ -305,8 +286,7 @@ class RelativeFieldTests(SimpleTestCase):
third = models.ForeignKey(Person, models.CASCADE, related_name="too_many_by_far") third = models.ForeignKey(Person, models.CASCADE, related_name="too_many_by_far")
field = Person._meta.get_field('friends') field = Person._meta.get_field('friends')
errors = field.check(from_model=Person) self.assertEqual(field.check(from_model=Person), [
expected = [
Error( Error(
"The model is used as an intermediate model by " "The model is used as an intermediate model by "
"'invalid_models_tests.Person.friends', but it has more than two " "'invalid_models_tests.Person.friends', but it has more than two "
@ -317,8 +297,7 @@ class RelativeFieldTests(SimpleTestCase):
obj=InvalidRelationship, obj=InvalidRelationship,
id='fields.E333', id='fields.E333',
), ),
] ])
self.assertEqual(errors, expected)
def test_symmetric_self_reference_with_intermediate_table(self): def test_symmetric_self_reference_with_intermediate_table(self):
class Person(models.Model): class Person(models.Model):
@ -330,15 +309,13 @@ class RelativeFieldTests(SimpleTestCase):
second = models.ForeignKey(Person, models.CASCADE, related_name="rel_to_set") second = models.ForeignKey(Person, models.CASCADE, related_name="rel_to_set")
field = Person._meta.get_field('friends') field = Person._meta.get_field('friends')
errors = field.check(from_model=Person) self.assertEqual(field.check(from_model=Person), [
expected = [
Error( Error(
'Many-to-many fields with intermediate tables must not be symmetrical.', 'Many-to-many fields with intermediate tables must not be symmetrical.',
obj=field, obj=field,
id='fields.E332', id='fields.E332',
), ),
] ])
self.assertEqual(errors, expected)
def test_symmetric_self_reference_with_intermediate_table_and_through_fields(self): def test_symmetric_self_reference_with_intermediate_table_and_through_fields(self):
""" """
@ -360,15 +337,13 @@ class RelativeFieldTests(SimpleTestCase):
referee = models.ForeignKey(Person, models.CASCADE, related_name="referred") referee = models.ForeignKey(Person, models.CASCADE, related_name="referred")
field = Person._meta.get_field('friends') field = Person._meta.get_field('friends')
errors = field.check(from_model=Person) self.assertEqual(field.check(from_model=Person), [
expected = [
Error( Error(
'Many-to-many fields with intermediate tables must not be symmetrical.', 'Many-to-many fields with intermediate tables must not be symmetrical.',
obj=field, obj=field,
id='fields.E332', id='fields.E332',
), ),
] ])
self.assertEqual(errors, expected)
def test_foreign_key_to_abstract_model(self): def test_foreign_key_to_abstract_model(self):
class AbstractModel(models.Model): class AbstractModel(models.Model):
@ -390,8 +365,7 @@ class RelativeFieldTests(SimpleTestCase):
) )
for field in fields: for field in fields:
expected_error.obj = field expected_error.obj = field
errors = field.check() self.assertEqual(field.check(), [expected_error])
self.assertEqual(errors, [expected_error])
def test_m2m_to_abstract_model(self): def test_m2m_to_abstract_model(self):
class AbstractModel(models.Model): class AbstractModel(models.Model):
@ -413,8 +387,7 @@ class RelativeFieldTests(SimpleTestCase):
) )
for field in fields: for field in fields:
expected_error.obj = field expected_error.obj = field
errors = field.check(from_model=Model) self.assertEqual(field.check(from_model=Model), [expected_error])
self.assertEqual(errors, [expected_error])
def test_unique_m2m(self): def test_unique_m2m(self):
class Person(models.Model): class Person(models.Model):
@ -424,15 +397,13 @@ class RelativeFieldTests(SimpleTestCase):
members = models.ManyToManyField('Person', unique=True) members = models.ManyToManyField('Person', unique=True)
field = Group._meta.get_field('members') field = Group._meta.get_field('members')
errors = field.check(from_model=Group) self.assertEqual(field.check(from_model=Group), [
expected = [
Error( Error(
'ManyToManyFields cannot be unique.', 'ManyToManyFields cannot be unique.',
obj=field, obj=field,
id='fields.E330', id='fields.E330',
), ),
] ])
self.assertEqual(errors, expected)
def test_foreign_key_to_non_unique_field(self): def test_foreign_key_to_non_unique_field(self):
class Target(models.Model): class Target(models.Model):
@ -442,15 +413,13 @@ class RelativeFieldTests(SimpleTestCase):
foreign_key = models.ForeignKey('Target', models.CASCADE, to_field='bad') foreign_key = models.ForeignKey('Target', models.CASCADE, to_field='bad')
field = Model._meta.get_field('foreign_key') field = Model._meta.get_field('foreign_key')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
"'Target.bad' must set unique=True because it is referenced by a foreign key.", "'Target.bad' must set unique=True because it is referenced by a foreign key.",
obj=field, obj=field,
id='fields.E311', id='fields.E311',
), ),
] ])
self.assertEqual(errors, expected)
def test_foreign_key_to_non_unique_field_under_explicit_model(self): def test_foreign_key_to_non_unique_field_under_explicit_model(self):
class Target(models.Model): class Target(models.Model):
@ -460,15 +429,13 @@ class RelativeFieldTests(SimpleTestCase):
field = models.ForeignKey(Target, models.CASCADE, to_field='bad') field = models.ForeignKey(Target, models.CASCADE, to_field='bad')
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
"'Target.bad' must set unique=True because it is referenced by a foreign key.", "'Target.bad' must set unique=True because it is referenced by a foreign key.",
obj=field, obj=field,
id='fields.E311', id='fields.E311',
), ),
] ])
self.assertEqual(errors, expected)
def test_foreign_object_to_non_unique_fields(self): def test_foreign_object_to_non_unique_fields(self):
class Person(models.Model): class Person(models.Model):
@ -488,8 +455,7 @@ class RelativeFieldTests(SimpleTestCase):
) )
field = MMembership._meta.get_field('person') field = MMembership._meta.get_field('person')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
"No subset of the fields 'country_id', 'city_id' on model 'Person' is unique.", "No subset of the fields 'country_id', 'city_id' on model 'Person' is unique.",
hint=( hint=(
@ -499,8 +465,7 @@ class RelativeFieldTests(SimpleTestCase):
obj=field, obj=field,
id='fields.E310', id='fields.E310',
) )
] ])
self.assertEqual(errors, expected)
def test_on_delete_set_null_on_non_nullable_field(self): def test_on_delete_set_null_on_non_nullable_field(self):
class Person(models.Model): class Person(models.Model):
@ -510,16 +475,14 @@ class RelativeFieldTests(SimpleTestCase):
foreign_key = models.ForeignKey('Person', models.SET_NULL) foreign_key = models.ForeignKey('Person', models.SET_NULL)
field = Model._meta.get_field('foreign_key') field = Model._meta.get_field('foreign_key')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
'Field specifies on_delete=SET_NULL, but cannot be null.', 'Field specifies on_delete=SET_NULL, but cannot be null.',
hint='Set null=True argument on the field, or change the on_delete rule.', hint='Set null=True argument on the field, or change the on_delete rule.',
obj=field, obj=field,
id='fields.E320', id='fields.E320',
), ),
] ])
self.assertEqual(errors, expected)
def test_on_delete_set_default_without_default_value(self): def test_on_delete_set_default_without_default_value(self):
class Person(models.Model): class Person(models.Model):
@ -529,16 +492,14 @@ class RelativeFieldTests(SimpleTestCase):
foreign_key = models.ForeignKey('Person', models.SET_DEFAULT) foreign_key = models.ForeignKey('Person', models.SET_DEFAULT)
field = Model._meta.get_field('foreign_key') field = Model._meta.get_field('foreign_key')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
'Field specifies on_delete=SET_DEFAULT, but has no default value.', 'Field specifies on_delete=SET_DEFAULT, but has no default value.',
hint='Set a default value, or change the on_delete rule.', hint='Set a default value, or change the on_delete rule.',
obj=field, obj=field,
id='fields.E321', id='fields.E321',
), ),
] ])
self.assertEqual(errors, expected)
@skipIfDBFeature('interprets_empty_strings_as_nulls') @skipIfDBFeature('interprets_empty_strings_as_nulls')
def test_nullable_primary_key(self): def test_nullable_primary_key(self):
@ -546,16 +507,14 @@ class RelativeFieldTests(SimpleTestCase):
field = models.IntegerField(primary_key=True, null=True) field = models.IntegerField(primary_key=True, null=True)
field = Model._meta.get_field('field') field = Model._meta.get_field('field')
errors = field.check() self.assertEqual(field.check(), [
expected = [
Error( Error(
'Primary keys must not have null=True.', 'Primary keys must not have null=True.',
hint='Set null=False on the field, or remove primary_key=True argument.', hint='Set null=False on the field, or remove primary_key=True argument.',
obj=field, obj=field,
id='fields.E007', id='fields.E007',
), ),
] ])
self.assertEqual(errors, expected)
def test_not_swapped_model(self): def test_not_swapped_model(self):
class SwappableModel(models.Model): class SwappableModel(models.Model):
@ -635,8 +594,7 @@ class RelativeFieldTests(SimpleTestCase):
for field in fields: for field in fields:
expected_error.obj = field expected_error.obj = field
errors = field.check(from_model=Model) self.assertEqual(field.check(from_model=Model), [expected_error])
self.assertEqual(errors, [expected_error])
def test_related_field_has_invalid_related_name(self): def test_related_field_has_invalid_related_name(self):
digit = 0 digit = 0
@ -667,8 +625,7 @@ class RelativeFieldTests(SimpleTestCase):
}) })
field = Child._meta.get_field('parent') field = Child._meta.get_field('parent')
errors = Child.check() self.assertEqual(Child.check(), [
expected = [
Error( Error(
"The name '%s' is invalid related_name for field Child%s.parent" "The name '%s' is invalid related_name for field Child%s.parent"
% (invalid_related_name, invalid_related_name), % (invalid_related_name, invalid_related_name),
@ -676,8 +633,7 @@ class RelativeFieldTests(SimpleTestCase):
obj=field, obj=field,
id='fields.E306', id='fields.E306',
), ),
] ])
self.assertEqual(errors, expected)
def test_related_field_has_valid_related_name(self): def test_related_field_has_valid_related_name(self):
lowercase = 'a' lowercase = 'a'
@ -704,9 +660,7 @@ class RelativeFieldTests(SimpleTestCase):
'parent': models.ForeignKey('Parent', models.CASCADE, related_name=related_name), 'parent': models.ForeignKey('Parent', models.CASCADE, related_name=related_name),
'__module__': Parent.__module__, '__module__': Parent.__module__,
}) })
self.assertEqual(Child.check(), [])
errors = Child.check()
self.assertFalse(errors)
def test_to_fields_exist(self): def test_to_fields_exist(self):
class Parent(models.Model): class Parent(models.Model):
@ -723,7 +677,7 @@ class RelativeFieldTests(SimpleTestCase):
) )
field = Child._meta.get_field('parent') field = Child._meta.get_field('parent')
expected = [ self.assertEqual(field.check(), [
Error( Error(
"The to_field 'a' doesn't exist on the related model 'invalid_models_tests.Parent'.", "The to_field 'a' doesn't exist on the related model 'invalid_models_tests.Parent'.",
obj=field, obj=field,
@ -734,8 +688,7 @@ class RelativeFieldTests(SimpleTestCase):
obj=field, obj=field,
id='fields.E312', id='fields.E312',
), ),
] ])
self.assertEqual(field.check(), expected)
def test_to_fields_not_checked_if_related_model_doesnt_exist(self): def test_to_fields_not_checked_if_related_model_doesnt_exist(self):
class Child(models.Model): class Child(models.Model):
@ -828,8 +781,7 @@ class AccessorClashTests(SimpleTestCase):
class Model(models.Model): class Model(models.Model):
rel = relative rel = relative
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"Reverse accessor for 'Model.rel' clashes with field name 'Target.model_set'.", "Reverse accessor for 'Model.rel' clashes with field name 'Target.model_set'.",
hint=("Rename field 'Target.model_set', or add/change " hint=("Rename field 'Target.model_set', or add/change "
@ -838,8 +790,7 @@ class AccessorClashTests(SimpleTestCase):
obj=Model._meta.get_field('rel'), obj=Model._meta.get_field('rel'),
id='fields.E302', id='fields.E302',
), ),
] ])
self.assertEqual(errors, expected)
def test_clash_between_accessors(self): def test_clash_between_accessors(self):
class Target(models.Model): class Target(models.Model):
@ -849,8 +800,7 @@ class AccessorClashTests(SimpleTestCase):
foreign = models.ForeignKey(Target, models.CASCADE) foreign = models.ForeignKey(Target, models.CASCADE)
m2m = models.ManyToManyField(Target) m2m = models.ManyToManyField(Target)
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"Reverse accessor for 'Model.foreign' clashes with reverse accessor for 'Model.m2m'.", "Reverse accessor for 'Model.foreign' clashes with reverse accessor for 'Model.m2m'.",
hint=( hint=(
@ -869,8 +819,7 @@ class AccessorClashTests(SimpleTestCase):
obj=Model._meta.get_field('m2m'), obj=Model._meta.get_field('m2m'),
id='fields.E304', id='fields.E304',
), ),
] ])
self.assertEqual(errors, expected)
def test_m2m_to_m2m_with_inheritance(self): def test_m2m_to_m2m_with_inheritance(self):
""" Ref #22047. """ """ Ref #22047. """
@ -887,8 +836,7 @@ class AccessorClashTests(SimpleTestCase):
class Child(Parent): class Child(Parent):
pass pass
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"Reverse accessor for 'Model.children' clashes with field name 'Child.m2m_clash'.", "Reverse accessor for 'Model.children' clashes with field name 'Child.m2m_clash'.",
hint=( hint=(
@ -898,8 +846,7 @@ class AccessorClashTests(SimpleTestCase):
obj=Model._meta.get_field('children'), obj=Model._meta.get_field('children'),
id='fields.E302', id='fields.E302',
) )
] ])
self.assertEqual(errors, expected)
def test_no_clash_for_hidden_related_name(self): def test_no_clash_for_hidden_related_name(self):
class Stub(models.Model): class Stub(models.Model):
@ -960,8 +907,7 @@ class ReverseQueryNameClashTests(SimpleTestCase):
class Model(models.Model): class Model(models.Model):
rel = relative rel = relative
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"Reverse query name for 'Model.rel' clashes with field name 'Target.model'.", "Reverse query name for 'Model.rel' clashes with field name 'Target.model'.",
hint=( hint=(
@ -971,8 +917,7 @@ class ReverseQueryNameClashTests(SimpleTestCase):
obj=Model._meta.get_field('rel'), obj=Model._meta.get_field('rel'),
id='fields.E303', id='fields.E303',
), ),
] ])
self.assertEqual(errors, expected)
@isolate_apps('invalid_models_tests') @isolate_apps('invalid_models_tests')
@ -1018,8 +963,7 @@ class ExplicitRelatedNameClashTests(SimpleTestCase):
class Model(models.Model): class Model(models.Model):
rel = relative rel = relative
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"Reverse accessor for 'Model.rel' clashes with field name 'Target.clash'.", "Reverse accessor for 'Model.rel' clashes with field name 'Target.clash'.",
hint=( hint=(
@ -1038,8 +982,7 @@ class ExplicitRelatedNameClashTests(SimpleTestCase):
obj=Model._meta.get_field('rel'), obj=Model._meta.get_field('rel'),
id='fields.E303', id='fields.E303',
), ),
] ])
self.assertEqual(errors, expected)
@isolate_apps('invalid_models_tests') @isolate_apps('invalid_models_tests')
@ -1126,8 +1069,7 @@ class ExplicitRelatedQueryNameClashTests(SimpleTestCase):
class Model(models.Model): class Model(models.Model):
rel = relative rel = relative
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"Reverse query name for 'Model.rel' clashes with field name 'Target.clash'.", "Reverse query name for 'Model.rel' clashes with field name 'Target.clash'.",
hint=( hint=(
@ -1137,8 +1079,7 @@ class ExplicitRelatedQueryNameClashTests(SimpleTestCase):
obj=Model._meta.get_field('rel'), obj=Model._meta.get_field('rel'),
id='fields.E303', id='fields.E303',
), ),
] ])
self.assertEqual(errors, expected)
@isolate_apps('invalid_models_tests') @isolate_apps('invalid_models_tests')
@ -1149,8 +1090,7 @@ class SelfReferentialM2MClashTests(SimpleTestCase):
first_m2m = models.ManyToManyField('self', symmetrical=False) first_m2m = models.ManyToManyField('self', symmetrical=False)
second_m2m = models.ManyToManyField('self', symmetrical=False) second_m2m = models.ManyToManyField('self', symmetrical=False)
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"Reverse accessor for 'Model.first_m2m' clashes with reverse accessor for 'Model.second_m2m'.", "Reverse accessor for 'Model.first_m2m' clashes with reverse accessor for 'Model.second_m2m'.",
hint=( hint=(
@ -1169,15 +1109,13 @@ class SelfReferentialM2MClashTests(SimpleTestCase):
obj=Model._meta.get_field('second_m2m'), obj=Model._meta.get_field('second_m2m'),
id='fields.E304', id='fields.E304',
), ),
] ])
self.assertEqual(errors, expected)
def test_accessor_clash(self): def test_accessor_clash(self):
class Model(models.Model): class Model(models.Model):
model_set = models.ManyToManyField("self", symmetrical=False) model_set = models.ManyToManyField("self", symmetrical=False)
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"Reverse accessor for 'Model.model_set' clashes with field name 'Model.model_set'.", "Reverse accessor for 'Model.model_set' clashes with field name 'Model.model_set'.",
hint=( hint=(
@ -1187,15 +1125,13 @@ class SelfReferentialM2MClashTests(SimpleTestCase):
obj=Model._meta.get_field('model_set'), obj=Model._meta.get_field('model_set'),
id='fields.E302', id='fields.E302',
), ),
] ])
self.assertEqual(errors, expected)
def test_reverse_query_name_clash(self): def test_reverse_query_name_clash(self):
class Model(models.Model): class Model(models.Model):
model = models.ManyToManyField("self", symmetrical=False) model = models.ManyToManyField("self", symmetrical=False)
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"Reverse query name for 'Model.model' clashes with field name 'Model.model'.", "Reverse query name for 'Model.model' clashes with field name 'Model.model'.",
hint=( hint=(
@ -1205,16 +1141,14 @@ class SelfReferentialM2MClashTests(SimpleTestCase):
obj=Model._meta.get_field('model'), obj=Model._meta.get_field('model'),
id='fields.E303', id='fields.E303',
), ),
] ])
self.assertEqual(errors, expected)
def test_clash_under_explicit_related_name(self): def test_clash_under_explicit_related_name(self):
class Model(models.Model): class Model(models.Model):
clash = models.IntegerField() clash = models.IntegerField()
m2m = models.ManyToManyField("self", symmetrical=False, related_name='clash') m2m = models.ManyToManyField("self", symmetrical=False, related_name='clash')
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"Reverse accessor for 'Model.m2m' clashes with field name 'Model.clash'.", "Reverse accessor for 'Model.m2m' clashes with field name 'Model.clash'.",
hint=( hint=(
@ -1233,16 +1167,14 @@ class SelfReferentialM2MClashTests(SimpleTestCase):
obj=Model._meta.get_field('m2m'), obj=Model._meta.get_field('m2m'),
id='fields.E303', id='fields.E303',
), ),
] ])
self.assertEqual(errors, expected)
def test_valid_model(self): def test_valid_model(self):
class Model(models.Model): class Model(models.Model):
first = models.ManyToManyField("self", symmetrical=False, related_name='first_accessor') first = models.ManyToManyField("self", symmetrical=False, related_name='first_accessor')
second = models.ManyToManyField("self", symmetrical=False, related_name='second_accessor') second = models.ManyToManyField("self", symmetrical=False, related_name='second_accessor')
errors = Model.check() self.assertEqual(Model.check(), [])
self.assertEqual(errors, [])
@isolate_apps('invalid_models_tests') @isolate_apps('invalid_models_tests')
@ -1252,8 +1184,7 @@ class SelfReferentialFKClashTests(SimpleTestCase):
class Model(models.Model): class Model(models.Model):
model_set = models.ForeignKey("Model", models.CASCADE) model_set = models.ForeignKey("Model", models.CASCADE)
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"Reverse accessor for 'Model.model_set' clashes with field name 'Model.model_set'.", "Reverse accessor for 'Model.model_set' clashes with field name 'Model.model_set'.",
hint=( hint=(
@ -1264,15 +1195,13 @@ class SelfReferentialFKClashTests(SimpleTestCase):
obj=Model._meta.get_field('model_set'), obj=Model._meta.get_field('model_set'),
id='fields.E302', id='fields.E302',
), ),
] ])
self.assertEqual(errors, expected)
def test_reverse_query_name_clash(self): def test_reverse_query_name_clash(self):
class Model(models.Model): class Model(models.Model):
model = models.ForeignKey("Model", models.CASCADE) model = models.ForeignKey("Model", models.CASCADE)
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"Reverse query name for 'Model.model' clashes with field name 'Model.model'.", "Reverse query name for 'Model.model' clashes with field name 'Model.model'.",
hint=( hint=(
@ -1282,16 +1211,14 @@ class SelfReferentialFKClashTests(SimpleTestCase):
obj=Model._meta.get_field('model'), obj=Model._meta.get_field('model'),
id='fields.E303', id='fields.E303',
), ),
] ])
self.assertEqual(errors, expected)
def test_clash_under_explicit_related_name(self): def test_clash_under_explicit_related_name(self):
class Model(models.Model): class Model(models.Model):
clash = models.CharField(max_length=10) clash = models.CharField(max_length=10)
foreign = models.ForeignKey("Model", models.CASCADE, related_name='clash') foreign = models.ForeignKey("Model", models.CASCADE, related_name='clash')
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"Reverse accessor for 'Model.foreign' clashes with field name 'Model.clash'.", "Reverse accessor for 'Model.foreign' clashes with field name 'Model.clash'.",
hint=( hint=(
@ -1310,8 +1237,7 @@ class SelfReferentialFKClashTests(SimpleTestCase):
obj=Model._meta.get_field('foreign'), obj=Model._meta.get_field('foreign'),
id='fields.E303', id='fields.E303',
), ),
] ])
self.assertEqual(errors, expected)
@isolate_apps('invalid_models_tests') @isolate_apps('invalid_models_tests')
@ -1336,8 +1262,7 @@ class ComplexClashTests(SimpleTestCase):
m2m_1 = models.ManyToManyField(Target, related_name='id') m2m_1 = models.ManyToManyField(Target, related_name='id')
m2m_2 = models.ManyToManyField(Target, related_name='src_safe') m2m_2 = models.ManyToManyField(Target, related_name='src_safe')
errors = Model.check() self.assertEqual(Model.check(), [
expected = [
Error( Error(
"Reverse accessor for 'Model.foreign_1' clashes with field name 'Target.id'.", "Reverse accessor for 'Model.foreign_1' clashes with field name 'Target.id'.",
hint=("Rename field 'Target.id', or add/change a related_name " hint=("Rename field 'Target.id', or add/change a related_name "
@ -1425,8 +1350,7 @@ class ComplexClashTests(SimpleTestCase):
obj=Model._meta.get_field('m2m_2'), obj=Model._meta.get_field('m2m_2'),
id='fields.E305', id='fields.E305',
), ),
] ])
self.assertEqual(errors, expected)
@isolate_apps('invalid_models_tests') @isolate_apps('invalid_models_tests')
@ -1459,8 +1383,7 @@ class M2mThroughFieldsTests(SimpleTestCase):
inviter = models.ForeignKey(Fan, models.CASCADE, related_name='+') inviter = models.ForeignKey(Fan, models.CASCADE, related_name='+')
field = Event._meta.get_field('invitees') field = Event._meta.get_field('invitees')
errors = field.check(from_model=Event) self.assertEqual(field.check(from_model=Event), [
expected = [
Error( Error(
"'Invitation.invitee' is not a foreign key to 'Event'.", "'Invitation.invitee' is not a foreign key to 'Event'.",
hint="Did you mean one of the following foreign keys to 'Event': event?", hint="Did you mean one of the following foreign keys to 'Event': event?",
@ -1473,8 +1396,7 @@ class M2mThroughFieldsTests(SimpleTestCase):
obj=field, obj=field,
id='fields.E339', id='fields.E339',
), ),
] ])
self.assertEqual(expected, errors)
def test_invalid_field(self): def test_invalid_field(self):
""" """
@ -1497,8 +1419,7 @@ class M2mThroughFieldsTests(SimpleTestCase):
inviter = models.ForeignKey(Fan, models.CASCADE, related_name='+') inviter = models.ForeignKey(Fan, models.CASCADE, related_name='+')
field = Event._meta.get_field('invitees') field = Event._meta.get_field('invitees')
errors = field.check(from_model=Event) self.assertEqual(field.check(from_model=Event), [
expected = [
Error( Error(
"The intermediary model 'invalid_models_tests.Invitation' has no field 'invalid_field_1'.", "The intermediary model 'invalid_models_tests.Invitation' has no field 'invalid_field_1'.",
hint="Did you mean one of the following foreign keys to 'Event': event?", hint="Did you mean one of the following foreign keys to 'Event': event?",
@ -1511,8 +1432,7 @@ class M2mThroughFieldsTests(SimpleTestCase):
obj=field, obj=field,
id='fields.E338', id='fields.E338',
), ),
] ])
self.assertEqual(expected, errors)
def test_explicit_field_names(self): def test_explicit_field_names(self):
""" """
@ -1531,16 +1451,16 @@ class M2mThroughFieldsTests(SimpleTestCase):
inviter = models.ForeignKey(Fan, models.CASCADE, related_name='+') inviter = models.ForeignKey(Fan, models.CASCADE, related_name='+')
field = Event._meta.get_field('invitees') field = Event._meta.get_field('invitees')
errors = field.check(from_model=Event) self.assertEqual(field.check(from_model=Event), [
expected = [
Error( Error(
"Field specifies 'through_fields' but does not provide the names " "Field specifies 'through_fields' but does not provide the names "
"of the two link fields that should be used for the relation " "of the two link fields that should be used for the relation "
"through model 'invalid_models_tests.Invitation'.", "through model 'invalid_models_tests.Invitation'.",
hint="Make sure you specify 'through_fields' as through_fields=('field1', 'field2')", hint="Make sure you specify 'through_fields' as through_fields=('field1', 'field2')",
obj=field, obj=field,
id='fields.E337')] id='fields.E337',
self.assertEqual(expected, errors) ),
])
def test_superset_foreign_object(self): def test_superset_foreign_object(self):
class Parent(models.Model): class Parent(models.Model):
@ -1564,8 +1484,7 @@ class M2mThroughFieldsTests(SimpleTestCase):
) )
field = Child._meta.get_field('parent') field = Child._meta.get_field('parent')
errors = field.check(from_model=Child) self.assertEqual(field.check(from_model=Child), [
expected = [
Error( Error(
"No subset of the fields 'a', 'b' on model 'Parent' is unique.", "No subset of the fields 'a', 'b' on model 'Parent' is unique.",
hint=( hint=(
@ -1575,8 +1494,7 @@ class M2mThroughFieldsTests(SimpleTestCase):
obj=field, obj=field,
id='fields.E310', id='fields.E310',
), ),
] ])
self.assertEqual(expected, errors)
def test_intersection_foreign_object(self): def test_intersection_foreign_object(self):
class Parent(models.Model): class Parent(models.Model):
@ -1602,8 +1520,7 @@ class M2mThroughFieldsTests(SimpleTestCase):
) )
field = Child._meta.get_field('parent') field = Child._meta.get_field('parent')
errors = field.check(from_model=Child) self.assertEqual(field.check(from_model=Child), [
expected = [
Error( Error(
"No subset of the fields 'a', 'b', 'd' on model 'Parent' is unique.", "No subset of the fields 'a', 'b', 'd' on model 'Parent' is unique.",
hint=( hint=(
@ -1613,5 +1530,4 @@ class M2mThroughFieldsTests(SimpleTestCase):
obj=field, obj=field,
id='fields.E310', id='fields.E310',
), ),
] ])
self.assertEqual(expected, errors)