summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorAndrew Godwin <andrew@aeracode.org>2014-06-07 18:17:31 -0700
committerAndrew Godwin <andrew@aeracode.org>2014-06-07 18:18:18 -0700
commitb568bdf8da30fe5940a31add9f3a2b8029ecb04d (patch)
tree3a967585f311e72c9bc9fb265a736dc7771e0dff /tests
parent83fe38ae30fe6053f378c4adfc4387f2e8bd030c (diff)
[1.7.x] Fixed #22750, #22248: Model renaming now also alters field FKs
Diffstat (limited to 'tests')
-rw-r--r--tests/migrations/test_autodetector.py33
-rw-r--r--tests/migrations/test_base.py14
-rw-r--r--tests/migrations/test_operations.py58
3 files changed, 36 insertions, 69 deletions
diff --git a/tests/migrations/test_autodetector.py b/tests/migrations/test_autodetector.py
index 629acbd610..6d163873ad 100644
--- a/tests/migrations/test_autodetector.py
+++ b/tests/migrations/test_autodetector.py
@@ -75,9 +75,7 @@ class AutodetectorTests(TestCase):
return output
def assertNumberMigrations(self, changes, app_label, number):
- if not changes.get(app_label, None):
- self.fail("No migrations found for %s\n%s" % (app_label, self.repr_changes(changes)))
- if len(changes[app_label]) != number:
+ if len(changes.get(app_label, [])) != number:
self.fail("Incorrect number of migrations (%s) for %s (expected %s)\n%s" % (
len(changes[app_label]),
app_label,
@@ -283,7 +281,7 @@ class AutodetectorTests(TestCase):
changes = autodetector._detect_changes()
# Right number of migrations for model rename?
- self.assertEqual(len(changes['testapp']), 1)
+ self.assertNumberMigrations(changes, 'testapp', 1)
# Right number of actions?
migration = changes['testapp'][0]
self.assertEqual(len(migration.operations), 1)
@@ -292,17 +290,9 @@ class AutodetectorTests(TestCase):
self.assertEqual(action.__class__.__name__, "RenameModel")
self.assertEqual(action.old_name, "Author")
self.assertEqual(action.new_name, "Writer")
-
- # Right number of migrations for related field rename?
- self.assertEqual(len(changes['otherapp']), 1)
- # Right number of actions?
- migration = changes['otherapp'][0]
- self.assertEqual(len(migration.operations), 1)
- # Right action?
- action = migration.operations[0]
- self.assertEqual(action.__class__.__name__, "AlterField")
- self.assertEqual(action.name, "author")
- self.assertEqual(action.field.rel.to, "testapp.Writer")
+ # Now that RenameModel handles related fields too, there should be
+ # no AlterField for the related field.
+ self.assertNumberMigrations(changes, 'otherapp', 0)
def test_rename_model_with_renamed_rel_field(self):
"""
@@ -314,9 +304,8 @@ class AutodetectorTests(TestCase):
after = self.make_project_state([self.author_renamed_with_book, self.book_with_field_and_author_renamed])
autodetector = MigrationAutodetector(before, after, MigrationQuestioner({"ask_rename_model": True, "ask_rename": True}))
changes = autodetector._detect_changes()
-
# Right number of migrations for model rename?
- self.assertEqual(len(changes['testapp']), 1)
+ self.assertNumberMigrations(changes, 'testapp', 1)
# Right number of actions?
migration = changes['testapp'][0]
self.assertEqual(len(migration.operations), 1)
@@ -325,21 +314,17 @@ class AutodetectorTests(TestCase):
self.assertEqual(action.__class__.__name__, "RenameModel")
self.assertEqual(action.old_name, "Author")
self.assertEqual(action.new_name, "Writer")
-
# Right number of migrations for related field rename?
- self.assertEqual(len(changes['otherapp']), 1)
+ # Alter is already taken care of.
+ self.assertNumberMigrations(changes, 'otherapp', 1)
# Right number of actions?
migration = changes['otherapp'][0]
- self.assertEqual(len(migration.operations), 2)
+ self.assertEqual(len(migration.operations), 1)
# Right actions?
action = migration.operations[0]
self.assertEqual(action.__class__.__name__, "RenameField")
self.assertEqual(action.old_name, "author")
self.assertEqual(action.new_name, "writer")
- action = migration.operations[1]
- self.assertEqual(action.__class__.__name__, "AlterField")
- self.assertEqual(action.name, "writer")
- self.assertEqual(action.field.rel.to, "testapp.Writer")
def test_fk_dependency(self):
"Tests that having a ForeignKey automatically adds a dependency"
diff --git a/tests/migrations/test_base.py b/tests/migrations/test_base.py
index 2dba30b2aa..839929d087 100644
--- a/tests/migrations/test_base.py
+++ b/tests/migrations/test_base.py
@@ -46,3 +46,17 @@ class MigrationTestBase(TransactionTestCase):
def assertIndexNotExists(self, table, columns):
return self.assertIndexExists(table, columns, False)
+
+ def assertFKExists(self, table, columns, to, value=True):
+ with connection.cursor() as cursor:
+ self.assertEqual(
+ value,
+ any(
+ c["foreign_key"] == to
+ for c in connection.introspection.get_constraints(cursor, table).values()
+ if c['columns'] == list(columns)
+ ),
+ )
+
+ def assertFKNotExists(self, table, columns, to, value=True):
+ return self.assertFKExists(table, columns, to, False)
diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py
index 19d19e81b5..472d7b003e 100644
--- a/tests/migrations/test_operations.py
+++ b/tests/migrations/test_operations.py
@@ -245,68 +245,36 @@ class OperationTests(MigrationTestBase):
"""
Tests the RenameModel operation.
"""
- project_state = self.set_up_test_model("test_rnmo")
+ project_state = self.set_up_test_model("test_rnmo", related_model=True)
# Test the state alteration
operation = migrations.RenameModel("Pony", "Horse")
new_state = project_state.clone()
operation.state_forwards("test_rnmo", new_state)
self.assertNotIn(("test_rnmo", "pony"), new_state.models)
self.assertIn(("test_rnmo", "horse"), new_state.models)
+ # Remember, RenameModel also repoints all incoming FKs and M2Ms
+ self.assertEqual("test_rnmo.Horse", new_state.models["test_rnmo", "rider"].fields[1][1].rel.to)
# Test the database alteration
self.assertTableExists("test_rnmo_pony")
self.assertTableNotExists("test_rnmo_horse")
+ if connection.features.supports_foreign_keys:
+ self.assertFKExists("test_rnmo_rider", ["pony_id"], ("test_rnmo_pony", "id"))
+ self.assertFKNotExists("test_rnmo_rider", ["pony_id"], ("test_rnmo_horse", "id"))
with connection.schema_editor() as editor:
operation.database_forwards("test_rnmo", editor, project_state, new_state)
self.assertTableNotExists("test_rnmo_pony")
self.assertTableExists("test_rnmo_horse")
+ if connection.features.supports_foreign_keys:
+ self.assertFKNotExists("test_rnmo_rider", ["pony_id"], ("test_rnmo_pony", "id"))
+ self.assertFKExists("test_rnmo_rider", ["pony_id"], ("test_rnmo_horse", "id"))
# And test reversal
with connection.schema_editor() as editor:
operation.database_backwards("test_rnmo", editor, new_state, project_state)
- self.assertTableExists("test_dlmo_pony")
+ self.assertTableExists("test_rnmo_pony")
self.assertTableNotExists("test_rnmo_horse")
-
- # See #22248 - this will fail until that's fixed.
- #
- # def test_rename_model_with_related(self):
- # """
- # Tests the real-world combo of a RenameModel operation with AlterField
- # for a related field.
- # """
- # project_state = self.set_up_test_model(
- # "test_rnmowr", related_model=True)
- # # Test the state alterations
- # model_operation = migrations.RenameModel("Pony", "Horse")
- # new_state = project_state.clone()
- # model_operation.state_forwards("test_rnmowr", new_state)
- # self.assertNotIn(("test_rnmowr", "pony"), new_state.models)
- # self.assertIn(("test_rnmowr", "horse"), new_state.models)
-
- # self.assertEqual(
- # "Pony",
- # project_state.render().get_model("test_rnmowr", "rider")
- # ._meta.get_field_by_name("pony")[0].rel.to._meta.object_name)
- # field_operation = migrations.AlterField(
- # "Rider", "pony", models.ForeignKey("Horse"))
- # field_operation.state_forwards("test_rnmowr", new_state)
- # self.assertEqual(
- # "Horse",
- # new_state.render().get_model("test_rnmowr", "rider")
- # ._meta.get_field_by_name("pony")[0].rel.to._meta.object_name)
-
- # # Test the database alterations
- # self.assertTableExists("test_rnmowr_pony")
- # self.assertTableNotExists("test_rnmowr_horse")
- # with connection.schema_editor() as editor:
- # model_operation.database_forwards("test_rnmowr", editor, project_state, new_state)
- # field_operation.database_forwards("test_rnmowr", editor, project_state, new_state)
- # self.assertTableNotExists("test_rnmowr_pony")
- # self.assertTableExists("test_rnmowr_horse")
- # # And test reversal
- # with connection.schema_editor() as editor:
- # field_operation.database_backwards("test_rnmowr", editor, new_state, project_state)
- # model_operation.database_backwards("test_rnmowr", editor, new_state, project_state)
- # self.assertTableExists("test_rnmowr_pony")
- # self.assertTableNotExists("test_rnmowr_horse")
+ if connection.features.supports_foreign_keys:
+ self.assertFKExists("test_rnmo_rider", ["pony_id"], ("test_rnmo_pony", "id"))
+ self.assertFKNotExists("test_rnmo_rider", ["pony_id"], ("test_rnmo_horse", "id"))
def test_add_field(self):
"""