~ubuntu-branches/ubuntu/lucid/python-django-south/lucid

« back to all changes in this revision

Viewing changes to south/tests/logic.py

  • Committer: Bazaar Package Importer
  • Author(s): David Watson
  • Date: 2009-05-02 09:56:35 UTC
  • Revision ID: james.westby@ubuntu.com-20090502095635-xy3077zb72r8enzy
Tags: upstream-0.5
ImportĀ upstreamĀ versionĀ 0.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import unittest
 
2
import datetime
 
3
import sys
 
4
import os
 
5
import StringIO
 
6
 
 
7
from south import migration
 
8
from south.tests import Monkeypatcher
 
9
 
 
10
# Add the tests directory so fakeapp is on sys.path
 
11
test_root = os.path.dirname(__file__)
 
12
sys.path.append(test_root)
 
13
 
 
14
 
 
15
class TestMigrationLogic(Monkeypatcher):
 
16
 
 
17
    """
 
18
    Tests if the various logic functions in migration actually work.
 
19
    """
 
20
    
 
21
    def test_get_app_name(self):
 
22
        self.assertEqual(
 
23
            "southtest",
 
24
            migration.get_app_name(self.create_fake_app("southtest.migrations")),
 
25
        )
 
26
        self.assertEqual(
 
27
            "baz",
 
28
            migration.get_app_name(self.create_fake_app("foo.bar.baz.migrations")),
 
29
        )
 
30
    
 
31
    
 
32
    def test_get_migrated_apps(self):
 
33
        
 
34
        P1 = __import__("fakeapp.migrations", {}, {}, [''])
 
35
        
 
36
        self.assertEqual(
 
37
            [P1],
 
38
            list(migration.get_migrated_apps()),
 
39
        )
 
40
    
 
41
    
 
42
    def test_get_app(self):
 
43
        
 
44
        P1 = __import__("fakeapp.migrations", {}, {}, [''])
 
45
        
 
46
        self.assertEqual(P1, migration.get_app("fakeapp"))
 
47
        self.assertEqual(P1, migration.get_app(self.create_fake_app("fakeapp.models")))
 
48
    
 
49
    
 
50
    def test_get_app_fullname(self):
 
51
        self.assertEqual(
 
52
            "southtest",
 
53
            migration.get_app_fullname(self.create_fake_app("southtest.migrations")),
 
54
        )
 
55
        self.assertEqual(
 
56
            "foo.bar.baz",
 
57
            migration.get_app_fullname(self.create_fake_app("foo.bar.baz.migrations")),
 
58
        )
 
59
    
 
60
    
 
61
    def test_get_migration_names(self):
 
62
        
 
63
        app = self.create_test_app()
 
64
        
 
65
        self.assertEqual(
 
66
            ["0001_spam", "0002_eggs", "0003_alter_spam"],
 
67
            migration.get_migration_names(app),
 
68
        )
 
69
    
 
70
    
 
71
    def test_get_migration_classes(self):
 
72
        
 
73
        app = self.create_test_app()
 
74
        
 
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
 
79
        
 
80
        self.assertEqual(
 
81
            [M1, M2, M3],
 
82
            list(migration.get_migration_classes(app)),
 
83
        )
 
84
    
 
85
    
 
86
    def test_get_migration(self):
 
87
        
 
88
        app = self.create_test_app()
 
89
        
 
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
 
93
        
 
94
        self.assertEqual(M1, migration.get_migration(app, "0001_spam"))
 
95
        self.assertEqual(M2, migration.get_migration(app, "0002_eggs"))
 
96
        
 
97
        # Temporarily redirect sys.stdout during this, it whinges.
 
98
        stdout, sys.stdout = sys.stdout, StringIO.StringIO()
 
99
        try:
 
100
            self.assertRaises((ImportError, ValueError), migration.get_migration, app, "0001_jam")
 
101
        finally:
 
102
            sys.stdout = stdout
 
103
    
 
104
    
 
105
    def test_all_migrations(self):
 
106
        
 
107
        app = migration.get_app("fakeapp")
 
108
        
 
109
        self.assertEqual(
 
110
            {app: {
 
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"),
 
114
            }},
 
115
            migration.all_migrations(),
 
116
        )
 
117
    
 
118
    
 
119
    def assertListEqual(self, list1, list2):
 
120
        list1 = list(list1)
 
121
        list2 = list(list2)
 
122
        list1.sort()
 
123
        list2.sort()
 
124
        return self.assertEqual(list1, list2)
 
125
    
 
126
    
 
127
    def test_apply_migrations(self):
 
128
        
 
129
        app = migration.get_app("fakeapp")
 
130
        
 
131
        # We should start with no migrations
 
132
        self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
 
133
        
 
134
        # Apply them normally
 
135
        migration.migrate_app(app, target_name=None, resolve_mode=None, fake=False, silent=True)
 
136
        
 
137
        # We should finish with all migrations
 
138
        self.assertListEqual(
 
139
            (
 
140
                (u"fakeapp", u"0001_spam"),
 
141
                (u"fakeapp", u"0002_eggs"),
 
142
                (u"fakeapp", u"0003_alter_spam"),
 
143
            ),
 
144
            migration.MigrationHistory.objects.values_list("app_name", "migration"),
 
145
        )
 
146
        
 
147
        # Now roll them backwards
 
148
        migration.migrate_app(app, target_name="zero", resolve_mode=None, fake=False, silent=True)
 
149
        
 
150
        # Finish with none
 
151
        self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
 
152
    
 
153
    
 
154
    def test_migration_merge_forwards(self):
 
155
        
 
156
        app = migration.get_app("fakeapp")
 
157
        
 
158
        # We should start with no migrations
 
159
        self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
 
160
        
 
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(),
 
166
        )
 
167
        
 
168
        # Did it go in?
 
169
        self.assertListEqual(
 
170
            (
 
171
                (u"fakeapp", u"0002_eggs"),
 
172
            ),
 
173
            migration.MigrationHistory.objects.values_list("app_name", "migration"),
 
174
        )
 
175
        
 
176
        # Apply them normally
 
177
        try:
 
178
            migration.migrate_app(app, target_name=None, resolve_mode=None, fake=False, silent=True)
 
179
        except SystemExit:
 
180
            pass
 
181
        
 
182
        # Nothing should have changed (no merge mode!)
 
183
        self.assertListEqual(
 
184
            (
 
185
                (u"fakeapp", u"0002_eggs"),
 
186
            ),
 
187
            migration.MigrationHistory.objects.values_list("app_name", "migration"),
 
188
        )
 
189
        
 
190
        # Apply with merge
 
191
        migration.migrate_app(app, target_name=None, resolve_mode="merge", fake=False, silent=True)
 
192
        
 
193
        # We should finish with all migrations
 
194
        self.assertListEqual(
 
195
            (
 
196
                (u"fakeapp", u"0001_spam"),
 
197
                (u"fakeapp", u"0002_eggs"),
 
198
                (u"fakeapp", u"0003_alter_spam"),
 
199
            ),
 
200
            migration.MigrationHistory.objects.values_list("app_name", "migration"),
 
201
        )
 
202
        
 
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)
 
207
        
 
208
        # Finish with none
 
209
        self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
 
210
    
 
211
    def test_alter_column_null(self):
 
212
        def null_ok():
 
213
            from django.db import connection, transaction
 
214
            # the DBAPI introspection module fails on postgres NULLs.
 
215
            cursor = connection.cursor()
 
216
            try:
 
217
                cursor.execute("INSERT INTO southtest_spam (id, weight, expires, name) VALUES (100, 10.1, now(), NULL);")
 
218
            except:
 
219
                transaction.rollback()
 
220
                return False
 
221
            else:
 
222
                cursor.execute("DELETE FROM southtest_spam")
 
223
                transaction.commit()
 
224
                return True
 
225
        
 
226
        app = migration.get_app("fakeapp")
 
227
        self.assertEqual(list(migration.MigrationHistory.objects.all()), [])
 
228
        
 
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())
 
232
        
 
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())
 
236
 
 
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')
 
240
        
 
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'