summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorAndrew Godwin <andrew@aeracode.org>2013-11-06 13:47:58 +0000
committerAndrew Godwin <andrew@aeracode.org>2013-11-06 13:47:58 +0000
commit106b019dc9b48aa749947e406e5445feb045e8a2 (patch)
tree0251a5a2c969e73575c58cc3c029bdd6e2cf9847 /tests
parent8265323c9169e95e9e765aa976b0e8065f0bd484 (diff)
Massive migration optimiser improvements + RenameModel opn
Diffstat (limited to 'tests')
-rw-r--r--tests/migrations/test_operations.py24
-rw-r--r--tests/migrations/test_optimizer.py195
2 files changed, 218 insertions, 1 deletions
diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py
index 9121755000..fb38605030 100644
--- a/tests/migrations/test_operations.py
+++ b/tests/migrations/test_operations.py
@@ -100,6 +100,30 @@ class OperationTests(MigrationTestBase):
operation.database_backwards("test_dlmo", editor, new_state, project_state)
self.assertTableExists("test_dlmo_pony")
+ def test_rename_model(self):
+ """
+ Tests the RenameModel operation.
+ """
+ project_state = self.set_up_test_model("test_rnmo")
+ # 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)
+ # Test the database alteration
+ self.assertTableExists("test_rnmo_pony")
+ self.assertTableNotExists("test_rnmo_horse")
+ 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")
+ # 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.assertTableNotExists("test_rnmo_horse")
+
def test_add_field(self):
"""
Tests the AddField operation.
diff --git a/tests/migrations/test_optimizer.py b/tests/migrations/test_optimizer.py
index 7a481c905c..8ba42db467 100644
--- a/tests/migrations/test_optimizer.py
+++ b/tests/migrations/test_optimizer.py
@@ -1,4 +1,5 @@
# encoding: utf8
+import operator
from django.test import TestCase
from django.db.migrations.optimizer import MigrationOptimizer
from django.db import migrations
@@ -64,7 +65,7 @@ class OptimizerTests(TestCase):
self.assertOptimizesTo(
[migrations.DeleteModel("Foo")],
[migrations.DeleteModel("Foo")],
- exact=1,
+ exact = 1,
)
def test_create_delete_model(self):
@@ -79,6 +80,34 @@ class OptimizerTests(TestCase):
[],
)
+ def test_create_rename_model(self):
+ """
+ CreateModel should absorb RenameModels.
+ """
+ self.assertOptimizesTo(
+ [
+ migrations.CreateModel("Foo", [("name", models.CharField(max_length=255))]),
+ migrations.RenameModel("Foo", "Bar"),
+ ],
+ [
+ migrations.CreateModel("Bar", [("name", models.CharField(max_length=255))]),
+ ],
+ )
+
+ def test_rename_model_self(self):
+ """
+ RenameModels should absorb themselves.
+ """
+ self.assertOptimizesTo(
+ [
+ migrations.RenameModel("Foo", "Baa"),
+ migrations.RenameModel("Baa", "Bar"),
+ ],
+ [
+ migrations.RenameModel("Foo", "Bar"),
+ ],
+ )
+
def test_create_alter_delete_model(self):
"""
CreateModel, AlterModelTable, AlterUniqueTogether, and DeleteModel should collapse into nothing.
@@ -154,3 +183,167 @@ class OptimizerTests(TestCase):
migrations.DeleteModel("Foo"),
],
)
+
+ def test_create_model_add_field(self):
+ """
+ AddField should optimize into CreateModel.
+ """
+ self.assertOptimizesTo(
+ [
+ migrations.CreateModel("Foo", [("name", models.CharField(max_length=255))]),
+ migrations.AddField("Foo", "age", models.IntegerField()),
+ ],
+ [
+ migrations.CreateModel("Foo", [
+ ("name", models.CharField(max_length=255)),
+ ("age", models.IntegerField()),
+ ]),
+ ],
+ )
+
+ def test_create_model_alter_field(self):
+ """
+ AlterField should optimize into CreateModel.
+ """
+ self.assertOptimizesTo(
+ [
+ migrations.CreateModel("Foo", [("name", models.CharField(max_length=255))]),
+ migrations.AlterField("Foo", "name", models.IntegerField()),
+ ],
+ [
+ migrations.CreateModel("Foo", [
+ ("name", models.IntegerField()),
+ ]),
+ ],
+ )
+
+ def test_create_model_rename_field(self):
+ """
+ RenameField should optimize into CreateModel.
+ """
+ self.assertOptimizesTo(
+ [
+ migrations.CreateModel("Foo", [("name", models.CharField(max_length=255))]),
+ migrations.RenameField("Foo", "name", "title"),
+ ],
+ [
+ migrations.CreateModel("Foo", [
+ ("title", models.CharField(max_length=255)),
+ ]),
+ ],
+ )
+
+ def test_add_field_rename_field(self):
+ """
+ RenameField should optimize into AddField
+ """
+ self.assertOptimizesTo(
+ [
+ migrations.AddField("Foo", "name", models.CharField(max_length=255)),
+ migrations.RenameField("Foo", "name", "title"),
+ ],
+ [
+ migrations.AddField("Foo", "title", models.CharField(max_length=255)),
+ ],
+ )
+
+ def test_alter_field_rename_field(self):
+ """
+ RenameField should optimize to the other side of AlterField,
+ and into itself.
+ """
+ self.assertOptimizesTo(
+ [
+ migrations.AlterField("Foo", "name", models.CharField(max_length=255)),
+ migrations.RenameField("Foo", "name", "title"),
+ migrations.RenameField("Foo", "title", "nom"),
+ ],
+ [
+ migrations.RenameField("Foo", "name", "nom"),
+ migrations.AlterField("Foo", "nom", models.CharField(max_length=255)),
+ ],
+ )
+
+ def test_create_model_remove_field(self):
+ """
+ RemoveField should optimize into CreateModel.
+ """
+ self.assertOptimizesTo(
+ [
+ migrations.CreateModel("Foo", [
+ ("name", models.CharField(max_length=255)),
+ ("age", models.IntegerField()),
+ ]),
+ migrations.RemoveField("Foo", "age"),
+ ],
+ [
+ migrations.CreateModel("Foo", [
+ ("name", models.CharField(max_length=255)),
+ ]),
+ ],
+ )
+
+ def test_add_field_alter_field(self):
+ """
+ AlterField should optimize into AddField.
+ """
+ self.assertOptimizesTo(
+ [
+ migrations.AddField("Foo", "age", models.IntegerField()),
+ migrations.AlterField("Foo", "age", models.FloatField(default=2.4)),
+ ],
+ [
+ migrations.AddField("Foo", "age", models.FloatField(default=2.4)),
+ ],
+ )
+
+ def test_add_field_delete_field(self):
+ """
+ RemoveField should cancel AddField
+ """
+ self.assertOptimizesTo(
+ [
+ migrations.AddField("Foo", "age", models.IntegerField()),
+ migrations.RemoveField("Foo", "age"),
+ ],
+ [],
+ )
+
+ def test_alter_field_delete_field(self):
+ """
+ RemoveField should absorb AlterField
+ """
+ self.assertOptimizesTo(
+ [
+ migrations.AlterField("Foo", "age", models.IntegerField()),
+ migrations.RemoveField("Foo", "age"),
+ ],
+ [
+ migrations.RemoveField("Foo", "age"),
+ ],
+ )
+
+ def test_optimize_through_fields(self):
+ """
+ Checks that field-level through checking is working.
+ This should manage to collapse model Foo to nonexistence,
+ and model Bar to a single IntegerField called "width".
+ """
+ self.assertOptimizesTo(
+ [
+ migrations.CreateModel("Foo", [("name", models.CharField(max_length=255))]),
+ migrations.CreateModel("Bar", [("size", models.IntegerField())]),
+ migrations.AddField("Foo", "age", models.IntegerField()),
+ migrations.AddField("Bar", "width", models.IntegerField()),
+ migrations.AlterField("Foo", "age", models.IntegerField()),
+ migrations.RenameField("Bar", "size", "dimensions"),
+ migrations.RemoveField("Foo", "age"),
+ migrations.RenameModel("Foo", "Phou"),
+ migrations.RemoveField("Bar", "dimensions"),
+ migrations.RenameModel("Phou", "Fou"),
+ migrations.DeleteModel("Fou"),
+ ],
+ [
+ migrations.CreateModel("Bar", [("width", models.IntegerField())]),
+ ],
+ )