Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Autodetector tests

  • Loading branch information...
commit cd809619a270ad48f1a77ee8c32bb0c7d8293f63 1 parent c7aa4b5
Andrew Godwin authored June 07, 2013
16  django/db/migrations/autodetector.py
@@ -2,7 +2,7 @@
2 2
 from django.db.migrations.migration import Migration
3 3
 
4 4
 
5  
-class AutoDetector(object):
  5
+class MigrationAutodetector(object):
6 6
     """
7 7
     Takes a pair of ProjectStates, and compares them to see what the
8 8
     first would need doing to make it match the second (the second
@@ -27,9 +27,9 @@ def changes(self):
27 27
         # We'll store migrations as lists by app names for now
28 28
         self.migrations = {}
29 29
         # Stage one: Adding models.
30  
-        added_models = set(self.to_state.keys()) - set(self.from_state.keys())
  30
+        added_models = set(self.to_state.models.keys()) - set(self.from_state.models.keys())
31 31
         for app_label, model_name in added_models:
32  
-            model_state = self.to_state[app_label, model_name]
  32
+            model_state = self.to_state.models[app_label, model_name]
33 33
             self.add_to_migration(
34 34
                 app_label,
35 35
                 operations.CreateModel(
@@ -40,9 +40,9 @@ def changes(self):
40 40
                 )
41 41
             )
42 42
         # Removing models
43  
-        removed_models = set(self.from_state.keys()) - set(self.to_state.keys())
  43
+        removed_models = set(self.from_state.models.keys()) - set(self.to_state.models.keys())
44 44
         for app_label, model_name in removed_models:
45  
-            model_state = self.from_state[app_label, model_name]
  45
+            model_state = self.from_state.models[app_label, model_name]
46 46
             self.add_to_migration(
47 47
                 app_label,
48 48
                 operations.DeleteModel(
@@ -59,11 +59,11 @@ def changes(self):
59 59
             for migration in migrations:
60 60
                 subclass = type("Migration", (Migration,), migration)
61 61
                 instance = subclass(migration['name'], app_label)
62  
-                result.append(instance)
  62
+                result.add(instance)
63 63
         return result
64 64
 
65 65
     def add_to_migration(self, app_label, operation):
66 66
         migrations = self.migrations.setdefault(app_label, [])
67 67
         if not migrations:
68  
-            migrations.append({"name": "temp-%i" % len(migrations) + 1, "operations": [], "dependencies": []})
69  
-        migrations[-1].operations.append(operation)
  68
+            migrations.append({"name": "auto_%i" % (len(migrations) + 1), "operations": [], "dependencies": []})
  69
+        migrations[-1]['operations'].append(operation)
3  django/db/migrations/migration.py
@@ -47,6 +47,9 @@ def __ne__(self, other):
47 47
     def __repr__(self):
48 48
         return "<Migration %s.%s>" % (self.app_label, self.name)
49 49
 
  50
+    def __hash__(self):
  51
+        return hash("%s.%s" % (self.app_label, self.name))
  52
+
50 53
     def mutate_state(self, project_state):
51 54
         """
52 55
         Takes a ProjectState and returns a new one with the migration's
54  tests/migrations/test_autodetector.py
... ...
@@ -0,0 +1,54 @@
  1
+# encoding: utf8
  2
+from django.test import TransactionTestCase
  3
+from django.db.migrations.autodetector import MigrationAutodetector
  4
+from django.db.migrations.state import ProjectState, ModelState
  5
+from django.db import models
  6
+
  7
+
  8
+class AutodetectorTests(TransactionTestCase):
  9
+    """
  10
+    Tests the migration autodetector.
  11
+    """
  12
+
  13
+    author_empty = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True))])
  14
+
  15
+    def make_project_state(self, model_states):
  16
+        "Shortcut to make ProjectStates from lists of predefined models"
  17
+        project_state = ProjectState()
  18
+        for model_state in model_states:
  19
+            project_state.add_model_state(model_state)
  20
+        return project_state
  21
+
  22
+    def test_new_model(self):
  23
+        "Tests autodetection of new models"
  24
+        # Make state
  25
+        before = self.make_project_state([])
  26
+        after = self.make_project_state([self.author_empty])
  27
+        autodetector = MigrationAutodetector(before, after)
  28
+        changes = autodetector.changes()
  29
+        # Right number of migrations?
  30
+        self.assertEqual(len(changes), 1)
  31
+        # Right number of actions?
  32
+        migration = changes.pop()
  33
+        self.assertEqual(len(migration.operations), 1)
  34
+        # Right action?
  35
+        action = migration.operations[0]
  36
+        self.assertEqual(action.__class__.__name__, "CreateModel")
  37
+        self.assertEqual(action.name, "Author")
  38
+
  39
+    def test_old_model(self):
  40
+        "Tests deletion of old models"
  41
+        # Make state
  42
+        before = self.make_project_state([self.author_empty])
  43
+        after = self.make_project_state([])
  44
+        autodetector = MigrationAutodetector(before, after)
  45
+        changes = autodetector.changes()
  46
+        # Right number of migrations?
  47
+        self.assertEqual(len(changes), 1)
  48
+        # Right number of actions?
  49
+        migration = changes.pop()
  50
+        self.assertEqual(len(migration.operations), 1)
  51
+        # Right action?
  52
+        action = migration.operations[0]
  53
+        self.assertEqual(action.__class__.__name__, "DeleteModel")
  54
+        self.assertEqual(action.name, "Author")

0 notes on commit cd80961

Please sign in to comment.
Something went wrong with that request. Please try again.