1 from dmigrations
.tests
.common
import *
2 from dmigrations
.migration_state
import MigrationState
3 from dmigrations
.migration_db
import MigrationDb
6 CREATE TABLE `dmigrations` (
7 `id` int(11) NOT NULL auto_increment,
8 `migration` VARCHAR(255) NOT NULL,
10 ) ENGINE=InnoDB DEFAULT CHARSET=utf8
13 class MigrationStateTest(TestCase
):
15 from django
.db
import connection
16 self
.cursor
= connection
.cursor()
18 try: self
.cursor
.execute("DROP TABLE dmigrations")
21 def test_table_present_methods(self
):
24 self
.assert_equal(False, si
.migration_table_present())
26 self
.cursor
.execute(create_new
)
28 self
.assert_equal(True, si
.migration_table_present())
30 def test_init_on_fresh_db_creates_new_table(self
):
33 self
.assert_equal(False, si
.migration_table_present())
37 self
.assert_equal(True, si
.migration_table_present())
39 def test_init_on_initialized_db_does_nothing(self
):
40 self
.cursor
.execute(create_new
)
44 self
.assert_equal(True, si
.migration_table_present())
48 self
.assert_equal(True, si
.migration_table_present())
50 def test_applying_and_unapplying(self
):
51 def assert_applied(f
, b
, h
):
52 self
.assert_equal([f
, b
, h
], [si
.is_applied('001_foo'), si
.is_applied('002_bar'), si
.is_applied('005_hello')])
55 self
.cursor
.execute(create_new
)
57 assert_applied(False, False, False)
59 si
.mark_as_applied('001_foo')
60 assert_applied(True, False, False)
62 si
.mark_as_applied('005_hello')
63 assert_applied(True, False, True)
65 si
.mark_as_applied('005_hello')
66 assert_applied(True, False, True)
68 si
.mark_as_unapplied('002_bar')
69 assert_applied(True, False, True)
71 si
.mark_as_unapplied('005_hello')
72 assert_applied(True, False, False)
74 si
.mark_as_applied('002_bar')
75 assert_applied(True, True, False)
77 def assert_plans(self
, si
, *plans
):
79 query
, expected_plan
, plans
= plans
[0], plans
[1], plans
[2:]
81 if isinstance(expected_plan
, type(Exception)) and issubclass(expected_plan
, Exception):
82 self
.assert_raises(expected_plan
, lambda: si
.plan(*query
))
84 actual_plan
= si
.plan(*query
)
85 self
.assert_equal(expected_plan
, actual_plan
, u
"Plan for %s expected to be %s but was %s" % (query
, expected_plan
, actual_plan
))
88 db
= MigrationDb(migrations
= ['001_foo', '002_bar', '005_omg', '005_hello'])
89 si
= MigrationState(migration_db
=db
)
94 ['apply', '1'], [('001_foo', 'up')],
95 ['apply', '001_foo'], [('001_foo', 'up')],
96 ['apply', '1', '2'], [('001_foo', 'up'), ('002_bar', 'up')],
97 ['unapply', '001_foo'], [],
98 ['unapply', '1', '2'], [],
100 ['all'], [('001_foo', 'up'), ('002_bar', 'up'), ('005_hello', 'up'), ('005_omg', 'up')],
101 ['up'], [('001_foo', 'up')],
104 ['to', '1'], [('001_foo', 'up')],
105 ['to', '2'], [('001_foo', 'up'), ('002_bar', 'up')],
106 ['upto', '2'], [('001_foo', 'up'), ('002_bar', 'up')],
107 ['upto', '002_bar'], [('001_foo', 'up'), ('002_bar', 'up')],
108 ['upto', '4'], [('001_foo', 'up'), ('002_bar', 'up')],
109 ['upto', '004_foo'], NoSuchMigrationError
,
110 ['upto', '5'], AmbiguousMigrationNameError
,
111 ['upto', '005_hello'], [('001_foo', 'up'), ('002_bar', 'up'), ('005_hello', 'up')],
112 ['upto', '005_omg'], [('001_foo', 'up'), ('002_bar', 'up'), ('005_hello', 'up'), ('005_omg', 'up')],
117 si
.mark_as_applied('002_bar')
119 self
.assert_plans(si
,
120 ['apply', '1'], [('001_foo', 'up')],
121 ['apply', '001_foo'], [('001_foo', 'up')],
122 ['apply', '1', '2'], [('001_foo', 'up')],
123 ['unapply', '001_foo'], [],
124 ['unapply', '1', '2'], [('002_bar', 'down')],
126 ['all'], [('001_foo', 'up'), ('005_hello', 'up'), ('005_omg', 'up')],
127 ['up'], [('001_foo', 'up')],
128 ['down'], [('002_bar', 'down')],
130 ['to', '1'], [('002_bar', 'down'), ('001_foo', 'up')],
131 ['to', '2'], [('001_foo', 'up')],
132 ['upto', '2'], [('001_foo', 'up')],
133 ['upto', '002_bar'], [('001_foo', 'up')],
134 ['upto', '4'], [('001_foo', 'up')],
135 ['upto', '004_foo'], NoSuchMigrationError
,
136 ['upto', '5'], AmbiguousMigrationNameError
,
137 ['upto', '005_hello'], [('001_foo', 'up'), ('005_hello', 'up')],
138 ['upto', '005_omg'], [('001_foo', 'up'), ('005_hello', 'up'), ('005_omg', 'up')],
139 ['downto', '1'], [('002_bar', 'down')],
143 si
.mark_as_applied('001_foo')
145 self
.assert_plans(si
,
147 ['apply', '001_foo'], [],
148 ['apply', '1', '2'], [],
149 ['unapply', '001_foo'], [('001_foo', 'down')],
150 ['unapply', '1', '2'], [('001_foo', 'down'), ('002_bar', 'down')],
152 ['all'], [('005_hello', 'up'), ('005_omg', 'up')],
153 ['up'], [('005_hello', 'up')],
154 ['down'], [('002_bar', 'down')],
156 ['to', '1'], [('002_bar', 'down')],
159 ['upto', '002_bar'], [],
161 ['upto', '004_foo'], NoSuchMigrationError
,
162 ['upto', '5'], AmbiguousMigrationNameError
,
163 ['upto', '005_hello'], [('005_hello', 'up')],
164 ['upto', '005_omg'], [('005_hello', 'up'), ('005_omg', 'up')],
165 ['downto', '1'], [('002_bar', 'down')],
169 si
.mark_as_unapplied('002_bar')
171 self
.assert_plans(si
,
173 ['apply', '001_foo'], [],
174 ['apply', '1', '2'], [('002_bar', 'up')],
175 ['unapply', '001_foo'], [('001_foo', 'down')],
176 ['unapply', '1', '2'], [('001_foo', 'down')],
178 ['all'], [('002_bar', 'up'), ('005_hello', 'up'), ('005_omg', 'up')],
179 ['up'], [('002_bar', 'up')],
180 ['down'], [('001_foo', 'down')],
183 ['to', '2'], [('002_bar', 'up')],
184 ['upto', '2'], [('002_bar', 'up')],
185 ['upto', '002_bar'], [('002_bar', 'up')],
186 ['upto', '4'], [('002_bar', 'up')],
187 ['upto', '004_foo'], NoSuchMigrationError
,
188 ['upto', '5'], AmbiguousMigrationNameError
,
189 ['upto', '005_hello'], [('002_bar', 'up'), ('005_hello', 'up')],
190 ['upto', '005_omg'], [('002_bar', 'up'), ('005_hello', 'up'), ('005_omg', 'up')],
195 si
.mark_as_applied('002_bar')
196 si
.mark_as_applied('005_hello')
197 si
.mark_as_applied('005_omg')
199 self
.assert_plans(si
,
201 ['apply', '001_foo'], [],
202 ['apply', '1', '2'], [],
203 ['unapply', '001_foo'], [('001_foo', 'down')],
204 ['unapply', '1', '2'], [('001_foo', 'down'), ('002_bar', 'down')],
208 ['down'], [('005_omg', 'down')],
210 ['to', '1'], [('005_omg', 'down'), ('005_hello', 'down'), ('002_bar', 'down')],
211 ['to', '2'], [('005_omg', 'down'), ('005_hello', 'down')],
213 ['upto', '002_bar'], [],
215 ['upto', '004_foo'], NoSuchMigrationError
,
216 ['upto', '5'], AmbiguousMigrationNameError
,
217 ['upto', '005_hello'], [],
218 ['upto', '005_omg'], [],
219 ['downto', '1'], [('005_omg', 'down'), ('005_hello', 'down'), ('002_bar', 'down')],
220 ['downto', '2'], [('005_omg', 'down'), ('005_hello', 'down')],
223 def test_plan_with_dev(self
):
224 # NOTE: si.mark_as_applied modifies global state, not si (MigrationState) object.
225 # There is only one meaningful MigrationState object per database,
226 # so it's an almost-singleton unless we support multiple databases at the same time.
227 # This makes testing quite ugly.
228 db
= MigrationDb(migrations
= ['001_foo', '002_DEV_bar', '005_omg', '006_DEV_hello'])
230 si
= MigrationState(migration_db
=db
)
232 self
.assert_plans(si
,
233 ['up'], [('001_foo', 'up')],
234 ['upto', '5'], [('001_foo', 'up'), ('005_omg', 'up')],
235 ['upto', '6'], [('001_foo', 'up'), ('005_omg', 'up')],
236 ['all'], [('001_foo', 'up'), ('005_omg', 'up')],
239 si
= MigrationState(migration_db
=db
, dev
=True)
241 self
.assert_plans(si
,
242 ['up'], [('001_foo', 'up')],
243 ['upto', '5'], [('001_foo', 'up'), ('002_DEV_bar', 'up'), ('005_omg', 'up')],
244 ['upto', '6'], [('001_foo', 'up'), ('002_DEV_bar', 'up'), ('005_omg', 'up'), ('006_DEV_hello', 'up')],
245 ['all'], [('001_foo', 'up'), ('002_DEV_bar', 'up'), ('005_omg', 'up'), ('006_DEV_hello', 'up')],
248 si
.mark_as_applied('001_foo')
250 si
= MigrationState(migration_db
=db
)
252 self
.assert_plans(si
,
253 ['up'], [('005_omg', 'up')],
254 ['upto', '5'], [('005_omg', 'up')],
255 ['upto', '6'], [('005_omg', 'up')],
256 ['all'], [('005_omg', 'up')],
259 si
= MigrationState(migration_db
=db
, dev
=True)
261 self
.assert_plans(si
,
262 ['up'], [('002_DEV_bar', 'up')],
263 ['upto', '5'], [('002_DEV_bar', 'up'), ('005_omg', 'up')],
264 ['upto', '6'], [('002_DEV_bar', 'up'), ('005_omg', 'up'), ('006_DEV_hello', 'up')],
265 ['all'], [('002_DEV_bar', 'up'), ('005_omg', 'up'), ('006_DEV_hello', 'up')],
268 si
.mark_as_applied('002_DEV_bar')
270 si
= MigrationState(migration_db
=db
)
272 self
.assert_plans(si
,
273 ['up'], [('005_omg', 'up')],
274 ['upto', '5'], [('005_omg', 'up')],
275 ['upto', '6'], [('005_omg', 'up')],
276 ['all'], [('005_omg', 'up')],
277 ['down'], [('001_foo', 'down')], # Is it better to always assume --dev on down ?
280 si
= MigrationState(migration_db
=db
, dev
=True)
282 self
.assert_plans(si
,
283 ['up'], [('005_omg', 'up')],
284 ['upto', '5'], [('005_omg', 'up')],
285 ['upto', '6'], [('005_omg', 'up'), ('006_DEV_hello', 'up')],
286 ['all'], [('005_omg', 'up'), ('006_DEV_hello', 'up')],
287 ['down'], [('002_DEV_bar', 'down')],
290 def test_all_migrations_applied(self
):
291 db
= MigrationDb(migrations
= ['001_foo', '002_DEV_bar', '005_omg', '006_DEV_hello'])
292 si
= MigrationState(migration_db
=db
)
295 si
.mark_as_applied('005_omg')
296 si
.mark_as_applied('001_foo')
297 si
.mark_as_applied('009_bogus')
299 self
.assert_equal(['001_foo', '005_omg', '009_bogus'], si
.all_migrations_applied())