Autodetector tests

This commit is contained in:
Andrew Godwin 2013-06-07 15:49:48 +01:00
parent c7aa4b5338
commit cd809619a2
3 changed files with 65 additions and 8 deletions

View File

@ -2,7 +2,7 @@ from django.db.migrations import operations
from django.db.migrations.migration import Migration from django.db.migrations.migration import Migration
class AutoDetector(object): class MigrationAutodetector(object):
""" """
Takes a pair of ProjectStates, and compares them to see what the Takes a pair of ProjectStates, and compares them to see what the
first would need doing to make it match the second (the second first would need doing to make it match the second (the second
@ -27,9 +27,9 @@ class AutoDetector(object):
# We'll store migrations as lists by app names for now # We'll store migrations as lists by app names for now
self.migrations = {} self.migrations = {}
# Stage one: Adding models. # Stage one: Adding models.
added_models = set(self.to_state.keys()) - set(self.from_state.keys()) added_models = set(self.to_state.models.keys()) - set(self.from_state.models.keys())
for app_label, model_name in added_models: for app_label, model_name in added_models:
model_state = self.to_state[app_label, model_name] model_state = self.to_state.models[app_label, model_name]
self.add_to_migration( self.add_to_migration(
app_label, app_label,
operations.CreateModel( operations.CreateModel(
@ -40,9 +40,9 @@ class AutoDetector(object):
) )
) )
# Removing models # Removing models
removed_models = set(self.from_state.keys()) - set(self.to_state.keys()) removed_models = set(self.from_state.models.keys()) - set(self.to_state.models.keys())
for app_label, model_name in removed_models: for app_label, model_name in removed_models:
model_state = self.from_state[app_label, model_name] model_state = self.from_state.models[app_label, model_name]
self.add_to_migration( self.add_to_migration(
app_label, app_label,
operations.DeleteModel( operations.DeleteModel(
@ -59,11 +59,11 @@ class AutoDetector(object):
for migration in migrations: for migration in migrations:
subclass = type("Migration", (Migration,), migration) subclass = type("Migration", (Migration,), migration)
instance = subclass(migration['name'], app_label) instance = subclass(migration['name'], app_label)
result.append(instance) result.add(instance)
return result return result
def add_to_migration(self, app_label, operation): def add_to_migration(self, app_label, operation):
migrations = self.migrations.setdefault(app_label, []) migrations = self.migrations.setdefault(app_label, [])
if not migrations: if not migrations:
migrations.append({"name": "temp-%i" % len(migrations) + 1, "operations": [], "dependencies": []}) migrations.append({"name": "auto_%i" % (len(migrations) + 1), "operations": [], "dependencies": []})
migrations[-1].operations.append(operation) migrations[-1]['operations'].append(operation)

View File

@ -47,6 +47,9 @@ class Migration(object):
def __repr__(self): def __repr__(self):
return "<Migration %s.%s>" % (self.app_label, self.name) return "<Migration %s.%s>" % (self.app_label, self.name)
def __hash__(self):
return hash("%s.%s" % (self.app_label, self.name))
def mutate_state(self, project_state): def mutate_state(self, project_state):
""" """
Takes a ProjectState and returns a new one with the migration's Takes a ProjectState and returns a new one with the migration's

View File

@ -0,0 +1,54 @@
# encoding: utf8
from django.test import TransactionTestCase
from django.db.migrations.autodetector import MigrationAutodetector
from django.db.migrations.state import ProjectState, ModelState
from django.db import models
class AutodetectorTests(TransactionTestCase):
"""
Tests the migration autodetector.
"""
author_empty = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True))])
def make_project_state(self, model_states):
"Shortcut to make ProjectStates from lists of predefined models"
project_state = ProjectState()
for model_state in model_states:
project_state.add_model_state(model_state)
return project_state
def test_new_model(self):
"Tests autodetection of new models"
# Make state
before = self.make_project_state([])
after = self.make_project_state([self.author_empty])
autodetector = MigrationAutodetector(before, after)
changes = autodetector.changes()
# Right number of migrations?
self.assertEqual(len(changes), 1)
# Right number of actions?
migration = changes.pop()
self.assertEqual(len(migration.operations), 1)
# Right action?
action = migration.operations[0]
self.assertEqual(action.__class__.__name__, "CreateModel")
self.assertEqual(action.name, "Author")
def test_old_model(self):
"Tests deletion of old models"
# Make state
before = self.make_project_state([self.author_empty])
after = self.make_project_state([])
autodetector = MigrationAutodetector(before, after)
changes = autodetector.changes()
# Right number of migrations?
self.assertEqual(len(changes), 1)
# Right number of actions?
migration = changes.pop()
self.assertEqual(len(migration.operations), 1)
# Right action?
action = migration.operations[0]
self.assertEqual(action.__class__.__name__, "DeleteModel")
self.assertEqual(action.name, "Author")