1from south.tests import unittest 2 3from south.creator.changes import AutoChanges, InitialChanges 4from south.migration.base import Migrations 5from south.tests import Monkeypatcher 6from south.creator import freezer 7from south.orm import FakeORM 8from south.v2 import SchemaMigration 9 10try: 11 from django.utils.six.moves import reload_module 12except ImportError: 13 # Older django, no python3 support 14 reload_module = reload 15 16class TestComparison(unittest.TestCase): 17 18 """ 19 Tests the comparison methods of startmigration. 20 """ 21 22 def test_no_change(self): 23 "Test with a completely unchanged definition." 24 25 self.assertEqual( 26 AutoChanges.different_attributes( 27 ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['southdemo.Lizard']"}), 28 ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['southdemo.Lizard']"}), 29 ), 30 False, 31 ) 32 33 self.assertEqual( 34 AutoChanges.different_attributes( 35 ('django.db.models.fields.related.ForeignKey', ['ohhai', 'there'], {'to': "somewhere", "from": "there"}), 36 ('django.db.models.fields.related.ForeignKey', ['ohhai', 'there'], {"from": "there", 'to': "somewhere"}), 37 ), 38 False, 39 ) 40 41 42 def test_pos_change(self): 43 "Test with a changed positional argument." 44 45 self.assertEqual( 46 AutoChanges.different_attributes( 47 ('django.db.models.fields.CharField', ['hi'], {'to': "foo"}), 48 ('django.db.models.fields.CharField', [], {'to': "foo"}), 49 ), 50 True, 51 ) 52 53 self.assertEqual( 54 AutoChanges.different_attributes( 55 ('django.db.models.fields.CharField', [], {'to': "foo"}), 56 ('django.db.models.fields.CharField', ['bye'], {'to': "foo"}), 57 ), 58 True, 59 ) 60 61 self.assertEqual( 62 AutoChanges.different_attributes( 63 ('django.db.models.fields.CharField', ['pi'], {'to': "foo"}), 64 ('django.db.models.fields.CharField', ['pi'], {'to': "foo"}), 65 ), 66 False, 67 ) 68 69 self.assertEqual( 70 AutoChanges.different_attributes( 71 ('django.db.models.fields.CharField', ['pisdadad'], {'to': "foo"}), 72 ('django.db.models.fields.CharField', ['pi'], {'to': "foo"}), 73 ), 74 True, 75 ) 76 77 self.assertEqual( 78 AutoChanges.different_attributes( 79 ('django.db.models.fields.CharField', ['hi'], {}), 80 ('django.db.models.fields.CharField', [], {}), 81 ), 82 True, 83 ) 84 85 self.assertEqual( 86 AutoChanges.different_attributes( 87 ('django.db.models.fields.CharField', [], {}), 88 ('django.db.models.fields.CharField', ['bye'], {}), 89 ), 90 True, 91 ) 92 93 self.assertEqual( 94 AutoChanges.different_attributes( 95 ('django.db.models.fields.CharField', ['pi'], {}), 96 ('django.db.models.fields.CharField', ['pi'], {}), 97 ), 98 False, 99 ) 100 101 self.assertEqual( 102 AutoChanges.different_attributes( 103 ('django.db.models.fields.CharField', ['pi'], {}), 104 ('django.db.models.fields.CharField', ['45fdfdf'], {}), 105 ), 106 True, 107 ) 108 109 110 def test_kwd_change(self): 111 "Test a changed keyword argument" 112 113 self.assertEqual( 114 AutoChanges.different_attributes( 115 ('django.db.models.fields.CharField', ['pi'], {'to': "foo"}), 116 ('django.db.models.fields.CharField', ['pi'], {'to': "blue"}), 117 ), 118 True, 119 ) 120 121 self.assertEqual( 122 AutoChanges.different_attributes( 123 ('django.db.models.fields.CharField', [], {'to': "foo"}), 124 ('django.db.models.fields.CharField', [], {'to': "blue"}), 125 ), 126 True, 127 ) 128 129 self.assertEqual( 130 AutoChanges.different_attributes( 131 ('django.db.models.fields.CharField', ['b'], {'to': "foo"}), 132 ('django.db.models.fields.CharField', ['b'], {'to': "blue"}), 133 ), 134 True, 135 ) 136 137 self.assertEqual( 138 AutoChanges.different_attributes( 139 ('django.db.models.fields.CharField', [], {'to': "foo"}), 140 ('django.db.models.fields.CharField', [], {}), 141 ), 142 True, 143 ) 144 145 self.assertEqual( 146 AutoChanges.different_attributes( 147 ('django.db.models.fields.CharField', ['a'], {'to': "foo"}), 148 ('django.db.models.fields.CharField', ['a'], {}), 149 ), 150 True, 151 ) 152 153 self.assertEqual( 154 AutoChanges.different_attributes( 155 ('django.db.models.fields.CharField', [], {}), 156 ('django.db.models.fields.CharField', [], {'to': "foo"}), 157 ), 158 True, 159 ) 160 161 self.assertEqual( 162 AutoChanges.different_attributes( 163 ('django.db.models.fields.CharField', ['a'], {}), 164 ('django.db.models.fields.CharField', ['a'], {'to': "foo"}), 165 ), 166 True, 167 ) 168 169 170 171 def test_backcompat_nochange(self): 172 "Test that the backwards-compatable comparison is working" 173 174 self.assertEqual( 175 AutoChanges.different_attributes( 176 ('models.CharField', [], {}), 177 ('django.db.models.fields.CharField', [], {}), 178 ), 179 False, 180 ) 181 182 self.assertEqual( 183 AutoChanges.different_attributes( 184 ('models.CharField', ['ack'], {}), 185 ('django.db.models.fields.CharField', ['ack'], {}), 186 ), 187 False, 188 ) 189 190 self.assertEqual( 191 AutoChanges.different_attributes( 192 ('models.CharField', [], {'to':'b'}), 193 ('django.db.models.fields.CharField', [], {'to':'b'}), 194 ), 195 False, 196 ) 197 198 self.assertEqual( 199 AutoChanges.different_attributes( 200 ('models.CharField', ['hah'], {'to':'you'}), 201 ('django.db.models.fields.CharField', ['hah'], {'to':'you'}), 202 ), 203 False, 204 ) 205 206 self.assertEqual( 207 AutoChanges.different_attributes( 208 ('models.CharField', ['hah'], {'to':'you'}), 209 ('django.db.models.fields.CharField', ['hah'], {'to':'heh'}), 210 ), 211 True, 212 ) 213 214 self.assertEqual( 215 AutoChanges.different_attributes( 216 ('models.CharField', ['hah'], {}), 217 ('django.db.models.fields.CharField', [], {'to':"orm['appname.hah']"}), 218 ), 219 False, 220 ) 221 222 self.assertEqual( 223 AutoChanges.different_attributes( 224 ('models.CharField', ['hah'], {}), 225 ('django.db.models.fields.CharField', [], {'to':'hah'}), 226 ), 227 True, 228 ) 229 230 self.assertEqual( 231 AutoChanges.different_attributes( 232 ('models.CharField', ['hah'], {}), 233 ('django.db.models.fields.CharField', [], {'to':'rrr'}), 234 ), 235 True, 236 ) 237 238 self.assertEqual( 239 AutoChanges.different_attributes( 240 ('models.CharField', ['hah'], {}), 241 ('django.db.models.fields.IntField', [], {'to':'hah'}), 242 ), 243 True, 244 ) 245 246class TestNonManagedIgnored(Monkeypatcher): 247 248 installed_apps = ["non_managed"] 249 250 full_defs = { 251 'non_managed.legacy': { 252 'Meta': {'object_name': 'Legacy', 'db_table': "'legacy_table'", 'managed': 'False'}, 253 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 254 'name': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True'}), 255 'size': ('django.db.models.fields.IntegerField', [], {}) 256 } 257 } 258 259 def test_not_added_init(self): 260 261 migrations = Migrations("non_managed") 262 changes = InitialChanges(migrations) 263 change_list = changes.get_changes() 264 if list(change_list): 265 self.fail("Initial migration creates table for non-managed model") 266 267 def test_not_added_auto(self): 268 269 empty_defs = { } 270 class EmptyMigration(SchemaMigration): 271 "Serves as fake previous migration" 272 273 def forwards(self, orm): 274 pass 275 276 def backwards(self, orm): 277 pass 278 279 models = empty_defs 280 281 complete_apps = ['non_managed'] 282 283 migrations = Migrations("non_managed") 284 empty_orm = FakeORM(EmptyMigration, "non_managed") 285 changes = AutoChanges( 286 migrations = migrations, 287 old_defs = empty_defs, 288 old_orm = empty_orm, 289 new_defs = self.full_defs, 290 ) 291 change_list = changes.get_changes() 292 if list(change_list): 293 self.fail("Auto migration creates table for non-managed model") 294 295 def test_not_deleted_auto(self): 296 297 empty_defs = { } 298 old_defs = freezer.freeze_apps(["non_managed"]) 299 class InitialMigration(SchemaMigration): 300 "Serves as fake previous migration" 301 302 def forwards(self, orm): 303 pass 304 305 def backwards(self, orm): 306 pass 307 308 models = self.full_defs 309 310 complete_apps = ['non_managed'] 311 312 migrations = Migrations("non_managed") 313 initial_orm = FakeORM(InitialMigration, "non_managed") 314 changes = AutoChanges( 315 migrations = migrations, 316 old_defs = self.full_defs, 317 old_orm = initial_orm, 318 new_defs = empty_defs, 319 ) 320 change_list = changes.get_changes() 321 if list(change_list): 322 self.fail("Auto migration deletes table for non-managed model") 323 324 def test_not_modified_auto(self): 325 326 fake_defs = { 327 'non_managed.legacy': { 328 'Meta': {'object_name': 'Legacy', 'db_table': "'legacy_table'", 'managed': 'False'}, 329 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), 330 'name': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True'}), 331 #'size': ('django.db.models.fields.IntegerField', [], {}) # The "change" is the addition of this field 332 } 333 } 334 class InitialMigration(SchemaMigration): 335 "Serves as fake previous migration" 336 337 def forwards(self, orm): 338 pass 339 340 def backwards(self, orm): 341 pass 342 343 models = fake_defs 344 345 complete_apps = ['non_managed'] 346 347 from non_managed import models as dummy_import_to_force_loading_models # TODO: Does needing this indicate a bug in MokeyPatcher? 348 reload_module(dummy_import_to_force_loading_models) # really force... 349 350 migrations = Migrations("non_managed") 351 initial_orm = FakeORM(InitialMigration, "non_managed") 352 changes = AutoChanges( 353 migrations = migrations, 354 old_defs = fake_defs, 355 old_orm = initial_orm, 356 new_defs = self.full_defs 357 ) 358 change_list = changes.get_changes() 359 if list(change_list): 360 self.fail("Auto migration changes table for non-managed model") 361