7
from south import migration
8
from south.tests import Monkeypatcher
10
# Add the tests directory so fakeapp is on sys.path
11
test_root = os.path.dirname(__file__)
12
sys.path.append(test_root)
15
class TestMigrationLogic(Monkeypatcher):
18
Tests if the various logic functions in migration actually work.
21
def test_get_app_name(self):
24
migration.get_app_name(self.create_fake_app("southtest.migrations")),
28
migration.get_app_name(self.create_fake_app("foo.bar.baz.migrations")),
32
def test_get_migrated_apps(self):
34
P1 = __import__("fakeapp.migrations", {}, {}, [''])
38
list(migration.get_migrated_apps()),
42
def test_get_app(self):
44
P1 = __import__("fakeapp.migrations", {}, {}, [''])
46
self.assertEqual(P1, migration.get_app("fakeapp"))
47
self.assertEqual(P1, migration.get_app(self.create_fake_app("fakeapp.models")))
50
def test_get_app_fullname(self):
53
migration.get_app_fullname(self.create_fake_app("southtest.migrations")),
57
migration.get_app_fullname(self.create_fake_app("foo.bar.baz.migrations")),
61
def test_get_migration_names(self):
63
app = self.create_test_app()
66
["0001_spam", "0002_eggs", "0003_alter_spam"],
67
migration.get_migration_names(app),
71
def test_get_migration_classes(self):
73
app = self.create_test_app()
75
# Can't use vanilla import, modules beginning with numbers aren't in grammar
76
M1 = __import__("fakeapp.migrations.0001_spam", {}, {}, ['Migration']).Migration
77
M2 = __import__("fakeapp.migrations.0002_eggs", {}, {}, ['Migration']).Migration
78
M3 = __import__("fakeapp.migrations.0003_alter_spam", {}, {}, ['Migration']).Migration
82
list(migration.get_migration_classes(app)),
86
def test_get_migration(self):
88
app = self.create_test_app()
90
# Can't use vanilla import, modules beginning with numbers aren't in grammar
91
M1 = __import__("fakeapp.migrations.0001_spam", {}, {}, ['Migration']).Migration
92
M2 = __import__("fakeapp.migrations.0002_eggs", {}, {}, ['Migration']).Migration
94
self.assertEqual(M1, migration.get_migration(app, "0001_spam"))
95
self.assertEqual(M2, migration.get_migration(app, "0002_eggs"))
97
# Temporarily redirect sys.stdout during this, it whinges.
98
stdout, sys.stdout = sys.stdout, StringIO.StringIO()
100
self.assertRaises((ImportError, ValueError), migration.get_migration, app, "0001_jam")
105
def test_all_migrations(self):
107
app = migration.get_app("fakeapp")
111
"0001_spam": migration.get_migration(app, "0001_spam"),
112
"0002_eggs": migration.get_migration(app, "0002_eggs"),
113
"0003_alter_spam": migration.get_migration(app, "0003_alter_spam"),
115
migration.all_migrations(),
119
def assertListEqual(self, list1, list2):
124
return self.assertEqual(list1, list2)
127
def test_apply_migrations(self):
129
app = migration.get_app("fakeapp")
131
# We should start with no migrations
132
self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
134
# Apply them normally
135
migration.migrate_app(app, target_name=None, resolve_mode=None, fake=False, silent=True)
137
# We should finish with all migrations
138
self.assertListEqual(
140
(u"fakeapp", u"0001_spam"),
141
(u"fakeapp", u"0002_eggs"),
142
(u"fakeapp", u"0003_alter_spam"),
144
migration.MigrationHistory.objects.values_list("app_name", "migration"),
147
# Now roll them backwards
148
migration.migrate_app(app, target_name="zero", resolve_mode=None, fake=False, silent=True)
151
self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
154
def test_migration_merge_forwards(self):
156
app = migration.get_app("fakeapp")
158
# We should start with no migrations
159
self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
161
# Insert one in the wrong order
162
migration.MigrationHistory.objects.create(
163
app_name = "fakeapp",
164
migration = "0002_eggs",
165
applied = datetime.datetime.now(),
169
self.assertListEqual(
171
(u"fakeapp", u"0002_eggs"),
173
migration.MigrationHistory.objects.values_list("app_name", "migration"),
176
# Apply them normally
178
migration.migrate_app(app, target_name=None, resolve_mode=None, fake=False, silent=True)
182
# Nothing should have changed (no merge mode!)
183
self.assertListEqual(
185
(u"fakeapp", u"0002_eggs"),
187
migration.MigrationHistory.objects.values_list("app_name", "migration"),
191
migration.migrate_app(app, target_name=None, resolve_mode="merge", fake=False, silent=True)
193
# We should finish with all migrations
194
self.assertListEqual(
196
(u"fakeapp", u"0001_spam"),
197
(u"fakeapp", u"0002_eggs"),
198
(u"fakeapp", u"0003_alter_spam"),
200
migration.MigrationHistory.objects.values_list("app_name", "migration"),
203
# Now roll them backwards
204
migration.migrate_app(app, target_name="0002", resolve_mode=None, fake=False, silent=True)
205
migration.migrate_app(app, target_name="0001", resolve_mode=None, fake=True, silent=True)
206
migration.migrate_app(app, target_name="zero", resolve_mode=None, fake=False, silent=True)
209
self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
211
def test_alter_column_null(self):
213
from django.db import connection, transaction
214
# the DBAPI introspection module fails on postgres NULLs.
215
cursor = connection.cursor()
217
cursor.execute("INSERT INTO southtest_spam (id, weight, expires, name) VALUES (100, 10.1, now(), NULL);")
219
transaction.rollback()
222
cursor.execute("DELETE FROM southtest_spam")
226
app = migration.get_app("fakeapp")
227
self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
229
# by default name is NOT NULL
230
migration.migrate_app(app, target_name="0002", resolve_mode=None, fake=False, silent=True)
231
self.failIf(null_ok())
233
# after 0003, it should be NULL
234
migration.migrate_app(app, target_name="0003", resolve_mode=None, fake=False, silent=True)
235
self.assert_(null_ok())
237
# make sure it is NOT NULL again
238
migration.migrate_app(app, target_name="0002", resolve_mode=None, fake=False, silent=True)
239
self.failIf(null_ok(), 'name not null after migration')
241
# finish with no migrations, otherwise other tests fail...
242
migration.migrate_app(app, target_name="zero", resolve_mode=None, fake=False, silent=True)
243
self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
b'\\ No newline at end of file'