Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.2.X] Converted defer_regress tests from doctests to unittests. We …

…have always been at war with doctests. Backport of [14094].

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@14095 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit ee8fc8d93af9d5dbba45dc8b0cdcc4658d71d161 1 parent b6223d3
Alex Gaynor authored October 09, 2010
112  tests/regressiontests/defer_regress/models.py
@@ -34,115 +34,3 @@ def __unicode__(self):
34 34
 class ResolveThis(models.Model):
35 35
     num = models.FloatField()
36 36
     name = models.CharField(max_length=16)
37  
-
38  
-__test__ = {"regression_tests": """
39  
-Deferred fields should really be deferred and not accidentally use the field's
40  
-default value just because they aren't passed to __init__.
41  
-
42  
->>> settings.DEBUG = True
43  
->>> _ = Item.objects.create(name="first", value=42)
44  
->>> obj = Item.objects.only("name", "other_value").get(name="first")
45  
-
46  
-# Accessing "name" doesn't trigger a new database query. Accessing "value" or
47  
-# "text" should.
48  
->>> num = len(connection.queries)
49  
->>> obj.name
50  
-u"first"
51  
->>> obj.other_value
52  
-0
53  
->>> len(connection.queries) == num
54  
-True
55  
->>> obj.value
56  
-42
57  
->>> len(connection.queries) == num + 1      # Effect of values lookup.
58  
-True
59  
->>> obj.text
60  
-u"xyzzy"
61  
->>> len(connection.queries) == num + 2      # Effect of text lookup.
62  
-True
63  
->>> obj.text
64  
-u"xyzzy"
65  
->>> len(connection.queries) == num + 2
66  
-True
67  
-
68  
->>> settings.DEBUG = False
69  
-
70  
-Regression test for #10695. Make sure different instances don't inadvertently
71  
-share data in the deferred descriptor objects.
72  
-
73  
->>> i = Item.objects.create(name="no I'm first", value=37)
74  
->>> items = Item.objects.only('value').order_by('-value')
75  
->>> items[0].name
76  
-u'first'
77  
->>> items[1].name
78  
-u"no I'm first"
79  
-
80  
->>> _ = RelatedItem.objects.create(item=i)
81  
->>> r = RelatedItem.objects.defer('item').get()
82  
->>> r.item_id == i.id
83  
-True
84  
->>> r.item == i
85  
-True
86  
-
87  
-Some further checks for select_related() and inherited model behaviour
88  
-(regression for #10710).
89  
-
90  
->>> c1 = Child.objects.create(name="c1", value=42)
91  
->>> c2 = Child.objects.create(name="c2", value=37)
92  
->>> obj = Leaf.objects.create(name="l1", child=c1, second_child=c2)
93  
-
94  
->>> obj = Leaf.objects.only("name", "child").select_related()[0]
95  
->>> obj.child.name
96  
-u'c1'
97  
->>> Leaf.objects.select_related().only("child__name", "second_child__name")
98  
-[<Leaf_Deferred_name_value: l1>]
99  
-
100  
-Models instances with deferred fields should still return the same content
101  
-types as their non-deferred versions (bug #10738).
102  
->>> ctype = ContentType.objects.get_for_model
103  
->>> c1 = ctype(Item.objects.all()[0])
104  
->>> c2 = ctype(Item.objects.defer("name")[0])
105  
->>> c3 = ctype(Item.objects.only("name")[0])
106  
->>> c1 is c2 is c3
107  
-True
108  
-
109  
-# Regression for #10733 - only() can be used on a model with two foreign keys.
110  
->>> results = Leaf.objects.all().only('name', 'child', 'second_child').select_related()
111  
->>> results[0].child.name
112  
-u'c1'
113  
->>> results[0].second_child.name
114  
-u'c2'
115  
-
116  
->>> results = Leaf.objects.all().only('name', 'child', 'second_child', 'child__name', 'second_child__name').select_related()
117  
->>> results[0].child.name
118  
-u'c1'
119  
->>> results[0].second_child.name
120  
-u'c2'
121  
-
122  
-# Test for #12163 - Pickling error saving session with unsaved model instances.
123  
->>> from django.contrib.sessions.backends.db import SessionStore
124  
->>> SESSION_KEY = '2b1189a188b44ad18c35e1baac6ceead'
125  
->>> item = Item()
126  
->>> item._deferred
127  
-False
128  
->>> s = SessionStore(SESSION_KEY)
129  
->>> s.clear()
130  
->>> s['item'] = item
131  
->>> s.save()
132  
->>> s = SessionStore(SESSION_KEY)
133  
->>> s.modified = True
134  
->>> s.save()
135  
->>> i2 = s['item']
136  
->>> i2._deferred # Item must still be non-deferred
137  
-False
138  
-
139  
-# Regression for #11936 - loading.get_models should not return deferred models by default.
140  
->>> from django.db.models.loading import get_models
141  
->>> sorted(get_models(models.get_app('defer_regress')), key=lambda obj: obj._meta.object_name)
142  
-[<class 'regressiontests.defer_regress.models.Child'>, <class 'regressiontests.defer_regress.models.Item'>, <class 'regressiontests.defer_regress.models.Leaf'>, <class 'regressiontests.defer_regress.models.RelatedItem'>, <class 'regressiontests.defer_regress.models.ResolveThis'>]
143  
-
144  
->>> sorted(get_models(models.get_app('defer_regress'), include_deferred=True), key=lambda obj: obj._meta.object_name)
145  
-[<class 'regressiontests.defer_regress.models.Child'>, <class 'regressiontests.defer_regress.models.Child_Deferred_value'>, <class 'regressiontests.defer_regress.models.Item'>, <class 'regressiontests.defer_regress.models.Item_Deferred_name'>, <class 'regressiontests.defer_regress.models.Item_Deferred_name_other_value_text'>, <class 'regressiontests.defer_regress.models.Item_Deferred_name_other_value_value'>, <class 'regressiontests.defer_regress.models.Item_Deferred_other_value_text_value'>, <class 'regressiontests.defer_regress.models.Item_Deferred_text_value'>, <class 'regressiontests.defer_regress.models.Leaf'>, <class 'regressiontests.defer_regress.models.Leaf_Deferred_child_id_second_child_id_value'>, <class 'regressiontests.defer_regress.models.Leaf_Deferred_name_value'>, <class 'regressiontests.defer_regress.models.Leaf_Deferred_second_child_value'>, <class 'regressiontests.defer_regress.models.Leaf_Deferred_value'>, <class 'regressiontests.defer_regress.models.RelatedItem'>, <class 'regressiontests.defer_regress.models.RelatedItem_Deferred_'>, <class 'regressiontests.defer_regress.models.RelatedItem_Deferred_item_id'>, <class 'regressiontests.defer_regress.models.ResolveThis'>, <class 'regressiontests.defer_regress.models.ResolveThis_Deferred_num'>]
146  
-"""
147  
-}
148  
-
157  tests/regressiontests/defer_regress/tests.py
... ...
@@ -1,7 +1,162 @@
  1
+from operator import attrgetter
  2
+
  3
+from django.conf import settings
  4
+from django.contrib.contenttypes.models import ContentType
  5
+from django.contrib.sessions.backends.db import SessionStore
  6
+from django.db import connection
  7
+from django.db.models.loading import cache
1 8
 from django.test import TestCase
2  
-from models import ResolveThis
  9
+
  10
+from models import ResolveThis, Item, RelatedItem, Child, Leaf
  11
+
3 12
 
4 13
 class DeferRegressionTest(TestCase):
  14
+    def assert_num_queries(self, n, func, *args, **kwargs):
  15
+        old_DEBUG = settings.DEBUG
  16
+        settings.DEBUG = True
  17
+        starting_queries = len(connection.queries)
  18
+        try:
  19
+            func(*args, **kwargs)
  20
+        finally:
  21
+            settings.DEBUG = old_DEBUG
  22
+        self.assertEqual(starting_queries + n, len(connection.queries))
  23
+
  24
+
  25
+    def test_basic(self):
  26
+        # Deferred fields should really be deferred and not accidentally use
  27
+        # the field's default value just because they aren't passed to __init__
  28
+
  29
+        Item.objects.create(name="first", value=42)
  30
+        obj = Item.objects.only("name", "other_value").get(name="first")
  31
+        # Accessing "name" doesn't trigger a new database query. Accessing
  32
+        # "value" or "text" should.
  33
+        def test():
  34
+            self.assertEqual(obj.name, "first")
  35
+            self.assertEqual(obj.other_value, 0)
  36
+        self.assert_num_queries(0, test)
  37
+
  38
+        def test():
  39
+            self.assertEqual(obj.value, 42)
  40
+        self.assert_num_queries(1, test)
  41
+
  42
+        def test():
  43
+            self.assertEqual(obj.text, "xyzzy")
  44
+        self.assert_num_queries(1, test)
  45
+
  46
+        def test():
  47
+            self.assertEqual(obj.text, "xyzzy")
  48
+        self.assert_num_queries(0, test)
  49
+
  50
+        # Regression test for #10695. Make sure different instances don't
  51
+        # inadvertently share data in the deferred descriptor objects.
  52
+        i = Item.objects.create(name="no I'm first", value=37)
  53
+        items = Item.objects.only("value").order_by("-value")
  54
+        self.assertEqual(items[0].name, "first")
  55
+        self.assertEqual(items[1].name, "no I'm first")
  56
+
  57
+        RelatedItem.objects.create(item=i)
  58
+        r = RelatedItem.objects.defer("item").get()
  59
+        self.assertEqual(r.item_id, i.id)
  60
+        self.assertEqual(r.item, i)
  61
+
  62
+        # Some further checks for select_related() and inherited model
  63
+        # behaviour (regression for #10710).
  64
+        c1 = Child.objects.create(name="c1", value=42)
  65
+        c2 = Child.objects.create(name="c2", value=37)
  66
+        Leaf.objects.create(name="l1", child=c1, second_child=c2)
  67
+
  68
+        obj = Leaf.objects.only("name", "child").select_related()[0]
  69
+        self.assertEqual(obj.child.name, "c1")
  70
+
  71
+        self.assertQuerysetEqual(
  72
+            Leaf.objects.select_related().only("child__name", "second_child__name"), [
  73
+                "l1",
  74
+            ],
  75
+            attrgetter("name")
  76
+        )
  77
+
  78
+        # Models instances with deferred fields should still return the same
  79
+        # content types as their non-deferred versions (bug #10738).
  80
+        ctype = ContentType.objects.get_for_model
  81
+        c1 = ctype(Item.objects.all()[0])
  82
+        c2 = ctype(Item.objects.defer("name")[0])
  83
+        c3 = ctype(Item.objects.only("name")[0])
  84
+        self.assertTrue(c1 is c2 is c3)
  85
+
  86
+        # Regression for #10733 - only() can be used on a model with two
  87
+        # foreign keys.
  88
+        results = Leaf.objects.only("name", "child", "second_child").select_related()
  89
+        self.assertEqual(results[0].child.name, "c1")
  90
+        self.assertEqual(results[0].second_child.name, "c2")
  91
+
  92
+        results = Leaf.objects.only("name", "child", "second_child", "child__name", "second_child__name").select_related()
  93
+        self.assertEqual(results[0].child.name, "c1")
  94
+        self.assertEqual(results[0].second_child.name, "c2")
  95
+
  96
+        # Test for #12163 - Pickling error saving session with unsaved model
  97
+        # instances.
  98
+        SESSION_KEY = '2b1189a188b44ad18c35e1baac6ceead'
  99
+
  100
+        item = Item()
  101
+        item._deferred = False
  102
+        s = SessionStore(SESSION_KEY)
  103
+        s.clear()
  104
+        s["item"] = item
  105
+        s.save()
  106
+
  107
+        s = SessionStore(SESSION_KEY)
  108
+        s.modified = True
  109
+        s.save()
  110
+
  111
+        i2 = s["item"]
  112
+        self.assertFalse(i2._deferred)
  113
+
  114
+        # Regression for #11936 - loading.get_models should not return deferred
  115
+        # models by default.
  116
+        klasses = sorted(
  117
+            cache.get_models(cache.get_app("defer_regress")),
  118
+            key=lambda klass: klass.__name__
  119
+        )
  120
+        self.assertEqual(
  121
+            klasses, [
  122
+                Child,
  123
+                Item,
  124
+                Leaf,
  125
+                RelatedItem,
  126
+                ResolveThis,
  127
+            ]
  128
+        )
  129
+
  130
+        klasses = sorted(
  131
+            map(
  132
+                attrgetter("__name__"),
  133
+                cache.get_models(
  134
+                    cache.get_app("defer_regress"), include_deferred=True
  135
+                ),
  136
+            )
  137
+        )
  138
+        self.assertEqual(
  139
+            klasses, [
  140
+                "Child",
  141
+                "Child_Deferred_value",
  142
+                "Item",
  143
+                "Item_Deferred_name",
  144
+                "Item_Deferred_name_other_value_text",
  145
+                "Item_Deferred_name_other_value_value",
  146
+                "Item_Deferred_other_value_text_value",
  147
+                "Item_Deferred_text_value",
  148
+                "Leaf",
  149
+                "Leaf_Deferred_child_id_second_child_id_value",
  150
+                "Leaf_Deferred_name_value",
  151
+                "Leaf_Deferred_second_child_value",
  152
+                "Leaf_Deferred_value",
  153
+                "RelatedItem",
  154
+                "RelatedItem_Deferred_",
  155
+                "RelatedItem_Deferred_item_id",
  156
+                "ResolveThis",
  157
+            ]
  158
+        )
  159
+
5 160
     def test_resolve_columns(self):
6 161
         rt = ResolveThis.objects.create(num=5.0, name='Foobar')
7 162
         qs = ResolveThis.objects.defer('num')

0 notes on commit ee8fc8d

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