Converted defer_regress tests from doctests to unittests. We have always been at war with doctests.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14094 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
1fe1af93a5
commit
16089ba135
|
@ -34,115 +34,3 @@ class Leaf(models.Model):
|
|||
class ResolveThis(models.Model):
|
||||
num = models.FloatField()
|
||||
name = models.CharField(max_length=16)
|
||||
|
||||
__test__ = {"regression_tests": """
|
||||
Deferred fields should really be deferred and not accidentally use the field's
|
||||
default value just because they aren't passed to __init__.
|
||||
|
||||
>>> settings.DEBUG = True
|
||||
>>> _ = Item.objects.create(name="first", value=42)
|
||||
>>> obj = Item.objects.only("name", "other_value").get(name="first")
|
||||
|
||||
# Accessing "name" doesn't trigger a new database query. Accessing "value" or
|
||||
# "text" should.
|
||||
>>> num = len(connection.queries)
|
||||
>>> obj.name
|
||||
u"first"
|
||||
>>> obj.other_value
|
||||
0
|
||||
>>> len(connection.queries) == num
|
||||
True
|
||||
>>> obj.value
|
||||
42
|
||||
>>> len(connection.queries) == num + 1 # Effect of values lookup.
|
||||
True
|
||||
>>> obj.text
|
||||
u"xyzzy"
|
||||
>>> len(connection.queries) == num + 2 # Effect of text lookup.
|
||||
True
|
||||
>>> obj.text
|
||||
u"xyzzy"
|
||||
>>> len(connection.queries) == num + 2
|
||||
True
|
||||
|
||||
>>> settings.DEBUG = False
|
||||
|
||||
Regression test for #10695. Make sure different instances don't inadvertently
|
||||
share data in the deferred descriptor objects.
|
||||
|
||||
>>> i = Item.objects.create(name="no I'm first", value=37)
|
||||
>>> items = Item.objects.only('value').order_by('-value')
|
||||
>>> items[0].name
|
||||
u'first'
|
||||
>>> items[1].name
|
||||
u"no I'm first"
|
||||
|
||||
>>> _ = RelatedItem.objects.create(item=i)
|
||||
>>> r = RelatedItem.objects.defer('item').get()
|
||||
>>> r.item_id == i.id
|
||||
True
|
||||
>>> r.item == i
|
||||
True
|
||||
|
||||
Some further checks for select_related() and inherited model behaviour
|
||||
(regression for #10710).
|
||||
|
||||
>>> c1 = Child.objects.create(name="c1", value=42)
|
||||
>>> c2 = Child.objects.create(name="c2", value=37)
|
||||
>>> obj = Leaf.objects.create(name="l1", child=c1, second_child=c2)
|
||||
|
||||
>>> obj = Leaf.objects.only("name", "child").select_related()[0]
|
||||
>>> obj.child.name
|
||||
u'c1'
|
||||
>>> Leaf.objects.select_related().only("child__name", "second_child__name")
|
||||
[<Leaf_Deferred_name_value: l1>]
|
||||
|
||||
Models instances with deferred fields should still return the same content
|
||||
types as their non-deferred versions (bug #10738).
|
||||
>>> ctype = ContentType.objects.get_for_model
|
||||
>>> c1 = ctype(Item.objects.all()[0])
|
||||
>>> c2 = ctype(Item.objects.defer("name")[0])
|
||||
>>> c3 = ctype(Item.objects.only("name")[0])
|
||||
>>> c1 is c2 is c3
|
||||
True
|
||||
|
||||
# Regression for #10733 - only() can be used on a model with two foreign keys.
|
||||
>>> results = Leaf.objects.all().only('name', 'child', 'second_child').select_related()
|
||||
>>> results[0].child.name
|
||||
u'c1'
|
||||
>>> results[0].second_child.name
|
||||
u'c2'
|
||||
|
||||
>>> results = Leaf.objects.all().only('name', 'child', 'second_child', 'child__name', 'second_child__name').select_related()
|
||||
>>> results[0].child.name
|
||||
u'c1'
|
||||
>>> results[0].second_child.name
|
||||
u'c2'
|
||||
|
||||
# Test for #12163 - Pickling error saving session with unsaved model instances.
|
||||
>>> from django.contrib.sessions.backends.db import SessionStore
|
||||
>>> SESSION_KEY = '2b1189a188b44ad18c35e1baac6ceead'
|
||||
>>> item = Item()
|
||||
>>> item._deferred
|
||||
False
|
||||
>>> s = SessionStore(SESSION_KEY)
|
||||
>>> s.clear()
|
||||
>>> s['item'] = item
|
||||
>>> s.save()
|
||||
>>> s = SessionStore(SESSION_KEY)
|
||||
>>> s.modified = True
|
||||
>>> s.save()
|
||||
>>> i2 = s['item']
|
||||
>>> i2._deferred # Item must still be non-deferred
|
||||
False
|
||||
|
||||
# Regression for #11936 - loading.get_models should not return deferred models by default.
|
||||
>>> from django.db.models.loading import get_models
|
||||
>>> sorted(get_models(models.get_app('defer_regress')), key=lambda obj: obj._meta.object_name)
|
||||
[<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'>]
|
||||
|
||||
>>> sorted(get_models(models.get_app('defer_regress'), include_deferred=True), key=lambda obj: obj._meta.object_name)
|
||||
[<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'>]
|
||||
"""
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,162 @@
|
|||
from operator import attrgetter
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.contrib.sessions.backends.db import SessionStore
|
||||
from django.db import connection
|
||||
from django.db.models.loading import cache
|
||||
from django.test import TestCase
|
||||
from models import ResolveThis
|
||||
|
||||
from models import ResolveThis, Item, RelatedItem, Child, Leaf
|
||||
|
||||
|
||||
class DeferRegressionTest(TestCase):
|
||||
def assert_num_queries(self, n, func, *args, **kwargs):
|
||||
old_DEBUG = settings.DEBUG
|
||||
settings.DEBUG = True
|
||||
starting_queries = len(connection.queries)
|
||||
try:
|
||||
func(*args, **kwargs)
|
||||
finally:
|
||||
settings.DEBUG = old_DEBUG
|
||||
self.assertEqual(starting_queries + n, len(connection.queries))
|
||||
|
||||
|
||||
def test_basic(self):
|
||||
# Deferred fields should really be deferred and not accidentally use
|
||||
# the field's default value just because they aren't passed to __init__
|
||||
|
||||
Item.objects.create(name="first", value=42)
|
||||
obj = Item.objects.only("name", "other_value").get(name="first")
|
||||
# Accessing "name" doesn't trigger a new database query. Accessing
|
||||
# "value" or "text" should.
|
||||
def test():
|
||||
self.assertEqual(obj.name, "first")
|
||||
self.assertEqual(obj.other_value, 0)
|
||||
self.assert_num_queries(0, test)
|
||||
|
||||
def test():
|
||||
self.assertEqual(obj.value, 42)
|
||||
self.assert_num_queries(1, test)
|
||||
|
||||
def test():
|
||||
self.assertEqual(obj.text, "xyzzy")
|
||||
self.assert_num_queries(1, test)
|
||||
|
||||
def test():
|
||||
self.assertEqual(obj.text, "xyzzy")
|
||||
self.assert_num_queries(0, test)
|
||||
|
||||
# Regression test for #10695. Make sure different instances don't
|
||||
# inadvertently share data in the deferred descriptor objects.
|
||||
i = Item.objects.create(name="no I'm first", value=37)
|
||||
items = Item.objects.only("value").order_by("-value")
|
||||
self.assertEqual(items[0].name, "first")
|
||||
self.assertEqual(items[1].name, "no I'm first")
|
||||
|
||||
RelatedItem.objects.create(item=i)
|
||||
r = RelatedItem.objects.defer("item").get()
|
||||
self.assertEqual(r.item_id, i.id)
|
||||
self.assertEqual(r.item, i)
|
||||
|
||||
# Some further checks for select_related() and inherited model
|
||||
# behaviour (regression for #10710).
|
||||
c1 = Child.objects.create(name="c1", value=42)
|
||||
c2 = Child.objects.create(name="c2", value=37)
|
||||
Leaf.objects.create(name="l1", child=c1, second_child=c2)
|
||||
|
||||
obj = Leaf.objects.only("name", "child").select_related()[0]
|
||||
self.assertEqual(obj.child.name, "c1")
|
||||
|
||||
self.assertQuerysetEqual(
|
||||
Leaf.objects.select_related().only("child__name", "second_child__name"), [
|
||||
"l1",
|
||||
],
|
||||
attrgetter("name")
|
||||
)
|
||||
|
||||
# Models instances with deferred fields should still return the same
|
||||
# content types as their non-deferred versions (bug #10738).
|
||||
ctype = ContentType.objects.get_for_model
|
||||
c1 = ctype(Item.objects.all()[0])
|
||||
c2 = ctype(Item.objects.defer("name")[0])
|
||||
c3 = ctype(Item.objects.only("name")[0])
|
||||
self.assertTrue(c1 is c2 is c3)
|
||||
|
||||
# Regression for #10733 - only() can be used on a model with two
|
||||
# foreign keys.
|
||||
results = Leaf.objects.only("name", "child", "second_child").select_related()
|
||||
self.assertEqual(results[0].child.name, "c1")
|
||||
self.assertEqual(results[0].second_child.name, "c2")
|
||||
|
||||
results = Leaf.objects.only("name", "child", "second_child", "child__name", "second_child__name").select_related()
|
||||
self.assertEqual(results[0].child.name, "c1")
|
||||
self.assertEqual(results[0].second_child.name, "c2")
|
||||
|
||||
# Test for #12163 - Pickling error saving session with unsaved model
|
||||
# instances.
|
||||
SESSION_KEY = '2b1189a188b44ad18c35e1baac6ceead'
|
||||
|
||||
item = Item()
|
||||
item._deferred = False
|
||||
s = SessionStore(SESSION_KEY)
|
||||
s.clear()
|
||||
s["item"] = item
|
||||
s.save()
|
||||
|
||||
s = SessionStore(SESSION_KEY)
|
||||
s.modified = True
|
||||
s.save()
|
||||
|
||||
i2 = s["item"]
|
||||
self.assertFalse(i2._deferred)
|
||||
|
||||
# Regression for #11936 - loading.get_models should not return deferred
|
||||
# models by default.
|
||||
klasses = sorted(
|
||||
cache.get_models(cache.get_app("defer_regress")),
|
||||
key=lambda klass: klass.__name__
|
||||
)
|
||||
self.assertEqual(
|
||||
klasses, [
|
||||
Child,
|
||||
Item,
|
||||
Leaf,
|
||||
RelatedItem,
|
||||
ResolveThis,
|
||||
]
|
||||
)
|
||||
|
||||
klasses = sorted(
|
||||
map(
|
||||
attrgetter("__name__"),
|
||||
cache.get_models(
|
||||
cache.get_app("defer_regress"), include_deferred=True
|
||||
),
|
||||
)
|
||||
)
|
||||
self.assertEqual(
|
||||
klasses, [
|
||||
"Child",
|
||||
"Child_Deferred_value",
|
||||
"Item",
|
||||
"Item_Deferred_name",
|
||||
"Item_Deferred_name_other_value_text",
|
||||
"Item_Deferred_name_other_value_value",
|
||||
"Item_Deferred_other_value_text_value",
|
||||
"Item_Deferred_text_value",
|
||||
"Leaf",
|
||||
"Leaf_Deferred_child_id_second_child_id_value",
|
||||
"Leaf_Deferred_name_value",
|
||||
"Leaf_Deferred_second_child_value",
|
||||
"Leaf_Deferred_value",
|
||||
"RelatedItem",
|
||||
"RelatedItem_Deferred_",
|
||||
"RelatedItem_Deferred_item_id",
|
||||
"ResolveThis",
|
||||
]
|
||||
)
|
||||
|
||||
def test_resolve_columns(self):
|
||||
rt = ResolveThis.objects.create(num=5.0, name='Foobar')
|
||||
qs = ResolveThis.objects.defer('num')
|
||||
|
|
Loading…
Reference in New Issue