6 from south import migration
8 # Add the tests directory so fakeapp is on sys.path
9 test_root = os.path.dirname(__file__)
10 sys.path.append(test_root)
13 class TestMigrationLogic(unittest.TestCase):
16 Tests if the various logic functions in migration actually work.
19 def create_fake_app(self, name):
29 def create_test_app(self):
35 fake.__name__ = "fakeapp.migrations"
36 fake.__file__ = os.path.join(test_root, "fakeapp", "migrations", "__init__.py")
40 def monkeypatch(self):
41 """Swaps out various Django calls for fake ones for our own nefarious purposes."""
46 from django.db import models
47 from django.conf import settings
48 models.get_apps_old, models.get_apps = models.get_apps, new_get_apps
49 settings.INSTALLED_APPS, settings.OLD_INSTALLED_APPS = (
51 settings.INSTALLED_APPS,
57 def unmonkeypatch(self):
58 """Undoes what monkeypatch did."""
60 from django.db import models
61 from django.conf import settings
62 models.get_apps = models.get_apps_old
63 settings.INSTALLED_APPS = settings.OLD_INSTALLED_APPS
65 tearDown = unmonkeypatch
68 def redo_app_cache(self):
69 from django.db.models.loading import AppCache
75 def test_get_app_name(self):
78 migration.get_app_name(self.create_fake_app("southtest.migrations")),
82 migration.get_app_name(self.create_fake_app("foo.bar.baz.migrations")),
86 def test_get_migrated_apps(self):
88 P1 = __import__("fakeapp.migrations", {}, {}, [''])
92 list(migration.get_migrated_apps()),
96 def test_get_app(self):
98 P1 = __import__("fakeapp.migrations", {}, {}, [''])
100 self.assertEqual(P1, migration.get_app("fakeapp"))
101 self.assertEqual(P1, migration.get_app(self.create_fake_app("fakeapp.models")))
104 def test_get_app_fullname(self):
107 migration.get_app_fullname(self.create_fake_app("southtest.migrations")),
111 migration.get_app_fullname(self.create_fake_app("foo.bar.baz.migrations")),
115 def test_get_migration_names(self):
117 app = self.create_test_app()
120 ["0001_spam", "0002_eggs"],
121 migration.get_migration_names(app),
125 def test_get_migration_classes(self):
127 app = self.create_test_app()
129 # Can't use vanilla import, modules beginning with numbers aren't in grammar
130 M1 = __import__("fakeapp.migrations.0001_spam", {}, {}, ['Migration']).Migration
131 M2 = __import__("fakeapp.migrations.0002_eggs", {}, {}, ['Migration']).Migration
135 list(migration.get_migration_classes(app)),
139 def test_get_migration(self):
141 app = self.create_test_app()
143 # Can't use vanilla import, modules beginning with numbers aren't in grammar
144 M1 = __import__("fakeapp.migrations.0001_spam", {}, {}, ['Migration']).Migration
145 M2 = __import__("fakeapp.migrations.0002_eggs", {}, {}, ['Migration']).Migration
147 self.assertEqual(M1, migration.get_migration(app, "0001_spam"))
148 self.assertEqual(M2, migration.get_migration(app, "0002_eggs"))
150 self.assertRaises(ValueError, migration.get_migration, app, "0001_jam")
153 def test_all_migrations(self):
155 app = migration.get_app("fakeapp")
159 "0001_spam": migration.get_migration(app, "0001_spam"),
160 "0002_eggs": migration.get_migration(app, "0002_eggs"),
162 migration.all_migrations(),
166 def assertListEqual(self, list1, list2):
171 return self.assertEqual(list1, list2)
174 def test_apply_migrations(self):
176 app = migration.get_app("fakeapp")
178 # We should start with no migrations
179 self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
181 # Apply them normally
182 migration.migrate_app(app, target_name=None, resolve_mode=None, fake=False, silent=True)
184 # We should finish with all migrations
185 self.assertListEqual(
187 (u"fakeapp", u"0001_spam"),
188 (u"fakeapp", u"0002_eggs"),
190 migration.MigrationHistory.objects.values_list("app_name", "migration"),
193 # Now roll them backwards
194 migration.migrate_app(app, target_name="zero", resolve_mode=None, fake=False, silent=True)
197 self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
200 def test_migration_merge_forwards(self):
202 app = migration.get_app("fakeapp")
204 # We should start with no migrations
205 self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
207 # Insert one in the wrong order
208 migration.MigrationHistory.objects.create(
209 app_name = "fakeapp",
210 migration = "0002_eggs",
211 applied = datetime.datetime.now(),
215 self.assertListEqual(
217 (u"fakeapp", u"0002_eggs"),
219 migration.MigrationHistory.objects.values_list("app_name", "migration"),
222 # Apply them normally
224 migration.migrate_app(app, target_name=None, resolve_mode=None, fake=False, silent=True)
228 # Nothing should have changed (no merge mode!)
229 self.assertListEqual(
231 (u"fakeapp", u"0002_eggs"),
233 migration.MigrationHistory.objects.values_list("app_name", "migration"),
237 migration.migrate_app(app, target_name=None, resolve_mode="merge", fake=False, silent=True)
239 # We should finish with all migrations
240 self.assertListEqual(
242 (u"fakeapp", u"0001_spam"),
243 (u"fakeapp", u"0002_eggs"),
245 migration.MigrationHistory.objects.values_list("app_name", "migration"),
248 # Now roll them backwards
249 migration.migrate_app(app, target_name="0001", resolve_mode=None, fake=True, silent=True)
250 migration.migrate_app(app, target_name="zero", resolve_mode=None, fake=False, silent=True)
253 self.assertEqual(list(migration.MigrationHistory.objects.all()), [])