summaryrefslogtreecommitdiff
path: root/tests/regressiontests
diff options
context:
space:
mode:
authorBrian Rosner <brosner@gmail.com>2008-06-10 04:03:09 +0000
committerBrian Rosner <brosner@gmail.com>2008-06-10 04:03:09 +0000
commit4530a408c40647c195f27f81da1315e98e956f96 (patch)
treeed8290751a7e284b9f030f4da97b422067ca9c95 /tests/regressiontests
parent3b92ced51856e740cd6fb3d3e5bb8ea932bd276e (diff)
newforms-admin: Merged from trunk up to [7602].
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@7604 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'tests/regressiontests')
-rw-r--r--tests/regressiontests/fixtures_regress/fixtures/bad_fixture1.unkn1
-rw-r--r--tests/regressiontests/fixtures_regress/fixtures/bad_fixture2.xml7
-rw-r--r--tests/regressiontests/fixtures_regress/models.py23
-rw-r--r--tests/regressiontests/model_inheritance_regress/__init__.py0
-rw-r--r--tests/regressiontests/model_inheritance_regress/models.py120
-rw-r--r--tests/regressiontests/null_fk/__init__.py0
-rw-r--r--tests/regressiontests/null_fk/models.py55
-rw-r--r--tests/regressiontests/serializers_regress/models.py20
-rw-r--r--tests/regressiontests/serializers_regress/tests.py48
9 files changed, 267 insertions, 7 deletions
diff --git a/tests/regressiontests/fixtures_regress/fixtures/bad_fixture1.unkn b/tests/regressiontests/fixtures_regress/fixtures/bad_fixture1.unkn
new file mode 100644
index 0000000000..a8b0a0c56c
--- /dev/null
+++ b/tests/regressiontests/fixtures_regress/fixtures/bad_fixture1.unkn
@@ -0,0 +1 @@
+This data shouldn't load, as it's of an unknown file format. \ No newline at end of file
diff --git a/tests/regressiontests/fixtures_regress/fixtures/bad_fixture2.xml b/tests/regressiontests/fixtures_regress/fixtures/bad_fixture2.xml
new file mode 100644
index 0000000000..87b809fbc6
--- /dev/null
+++ b/tests/regressiontests/fixtures_regress/fixtures/bad_fixture2.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<django-objcts version="1.0">
+ <objct pk="2" model="fixtures.article">
+ <field type="CharField" name="headline">Poker on TV is great!</field>
+ <field type="DateTimeField" name="pub_date">2006-06-16 11:00:00</field>
+ </objct>
+</django-objcts> \ No newline at end of file
diff --git a/tests/regressiontests/fixtures_regress/models.py b/tests/regressiontests/fixtures_regress/models.py
index 144debe05a..59fc167d50 100644
--- a/tests/regressiontests/fixtures_regress/models.py
+++ b/tests/regressiontests/fixtures_regress/models.py
@@ -71,4 +71,27 @@ __test__ = {'API_TESTS':"""
>>> Absolute.load_count
1
+###############################################
+# Test for ticket #4371 -- fixture loading fails silently in testcases
+# Validate that error conditions are caught correctly
+
+# redirect stderr for the next few tests...
+>>> import sys
+>>> savestderr = sys.stderr
+>>> sys.stderr = sys.stdout
+
+# Loading data of an unknown format should fail
+>>> management.call_command('loaddata', 'bad_fixture1.unkn', verbosity=0)
+Problem installing fixture 'bad_fixture1': unkn is not a known serialization format.
+
+# Loading a fixture file with invalid data using explicit filename
+>>> management.call_command('loaddata', 'bad_fixture2.xml', verbosity=0)
+No fixture data found for 'bad_fixture2'. (File format may be invalid.)
+
+# Loading a fixture file with invalid data without file extension
+>>> management.call_command('loaddata', 'bad_fixture2', verbosity=0)
+No fixture data found for 'bad_fixture2'. (File format may be invalid.)
+
+>>> sys.stderr = savestderr
+
"""}
diff --git a/tests/regressiontests/model_inheritance_regress/__init__.py b/tests/regressiontests/model_inheritance_regress/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/regressiontests/model_inheritance_regress/__init__.py
diff --git a/tests/regressiontests/model_inheritance_regress/models.py b/tests/regressiontests/model_inheritance_regress/models.py
new file mode 100644
index 0000000000..8801715a0c
--- /dev/null
+++ b/tests/regressiontests/model_inheritance_regress/models.py
@@ -0,0 +1,120 @@
+"""
+Regression tests for Model inheritance behaviour.
+"""
+
+from django.db import models
+
+class Place(models.Model):
+ name = models.CharField(max_length=50)
+ address = models.CharField(max_length=80)
+
+ class Meta:
+ ordering = ('name',)
+
+ def __unicode__(self):
+ return u"%s the place" % self.name
+
+class Restaurant(Place):
+ serves_hot_dogs = models.BooleanField()
+ serves_pizza = models.BooleanField()
+
+ def __unicode__(self):
+ return u"%s the restaurant" % self.name
+
+class ItalianRestaurant(Restaurant):
+ serves_gnocchi = models.BooleanField()
+
+ def __unicode__(self):
+ return u"%s the italian restaurant" % self.name
+
+class ParkingLot(Place):
+ # An explicit link to the parent (we can control the attribute name).
+ parent = models.OneToOneField(Place, primary_key=True, parent_link=True)
+ capacity = models.IntegerField()
+
+ def __unicode__(self):
+ return u"%s the parking lot" % self.name
+
+__test__ = {'API_TESTS':"""
+# Regression for #7350, #7202
+# Check that when you create a Parent object with a specific reference to an existent
+# child instance, saving the Parent doesn't duplicate the child.
+# This behaviour is only activated during a raw save - it is mostly relevant to
+# deserialization, but any sort of CORBA style 'narrow()' API would require a
+# similar approach.
+
+# Create a child-parent-grandparent chain
+>>> place1 = Place(name="Guido's House of Pasta", address='944 W. Fullerton')
+>>> place1.save_base(raw=True)
+>>> restaurant = Restaurant(place_ptr=place1, serves_hot_dogs=True, serves_pizza=False)
+>>> restaurant.save_base(raw=True)
+>>> italian_restaurant = ItalianRestaurant(restaurant_ptr=restaurant, serves_gnocchi=True)
+>>> italian_restaurant.save_base(raw=True)
+
+# Create a child-parent chain with an explicit parent link
+>>> place2 = Place(name='Main St', address='111 Main St')
+>>> place2.save_base(raw=True)
+>>> park = ParkingLot(parent=place2, capacity=100)
+>>> park.save_base(raw=True)
+
+# Check that no extra parent objects have been created.
+>>> Place.objects.all()
+[<Place: Guido's House of Pasta the place>, <Place: Main St the place>]
+
+>>> dicts = Restaurant.objects.values('name','serves_hot_dogs')
+>>> [sorted(d.items()) for d in dicts]
+[[('name', u"Guido's House of Pasta"), ('serves_hot_dogs', True)]]
+
+>>> dicts = ItalianRestaurant.objects.values('name','serves_hot_dogs','serves_gnocchi')
+>>> [sorted(d.items()) for d in dicts]
+[[('name', u"Guido's House of Pasta"), ('serves_gnocchi', True), ('serves_hot_dogs', True)]]
+
+>>> dicts = ParkingLot.objects.values('name','capacity')
+>>> [sorted(d.items()) for d in dicts]
+[[('capacity', 100), ('name', u'Main St')]]
+
+# You can also update objects when using a raw save.
+>>> place1.name = "Guido's All New House of Pasta"
+>>> place1.save_base(raw=True)
+
+>>> restaurant.serves_hot_dogs = False
+>>> restaurant.save_base(raw=True)
+
+>>> italian_restaurant.serves_gnocchi = False
+>>> italian_restaurant.save_base(raw=True)
+
+>>> place2.name='Derelict lot'
+>>> place2.save_base(raw=True)
+
+>>> park.capacity = 50
+>>> park.save_base(raw=True)
+
+# No extra parent objects after an update, either.
+>>> Place.objects.all()
+[<Place: Derelict lot the place>, <Place: Guido's All New House of Pasta the place>]
+
+>>> dicts = Restaurant.objects.values('name','serves_hot_dogs')
+>>> [sorted(d.items()) for d in dicts]
+[[('name', u"Guido's All New House of Pasta"), ('serves_hot_dogs', False)]]
+
+>>> dicts = ItalianRestaurant.objects.values('name','serves_hot_dogs','serves_gnocchi')
+>>> [sorted(d.items()) for d in dicts]
+[[('name', u"Guido's All New House of Pasta"), ('serves_gnocchi', False), ('serves_hot_dogs', False)]]
+
+>>> dicts = ParkingLot.objects.values('name','capacity')
+>>> [sorted(d.items()) for d in dicts]
+[[('capacity', 50), ('name', u'Derelict lot')]]
+
+# If you try to raw_save a parent attribute onto a child object,
+# the attribute will be ignored.
+
+>>> italian_restaurant.name = "Lorenzo's Pasta Hut"
+>>> italian_restaurant.save_base(raw=True)
+
+# Note that the name has not changed
+# - name is an attribute of Place, not ItalianRestaurant
+>>> dicts = ItalianRestaurant.objects.values('name','serves_hot_dogs','serves_gnocchi')
+>>> [sorted(d.items()) for d in dicts]
+[[('name', u"Guido's All New House of Pasta"), ('serves_gnocchi', False), ('serves_hot_dogs', False)]]
+
+"""}
diff --git a/tests/regressiontests/null_fk/__init__.py b/tests/regressiontests/null_fk/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/tests/regressiontests/null_fk/__init__.py
diff --git a/tests/regressiontests/null_fk/models.py b/tests/regressiontests/null_fk/models.py
new file mode 100644
index 0000000000..1bc266c033
--- /dev/null
+++ b/tests/regressiontests/null_fk/models.py
@@ -0,0 +1,55 @@
+"""
+Regression tests for proper working of ForeignKey(null=True). Tests these bugs:
+
+ * #7369: FK non-null after null relationship on select_related() generates an invalid query
+
+"""
+
+from django.db import models
+
+class SystemInfo(models.Model):
+ system_name = models.CharField(max_length=32)
+
+class Forum(models.Model):
+ system_info = models.ForeignKey(SystemInfo)
+ forum_name = models.CharField(max_length=32)
+
+class Post(models.Model):
+ forum = models.ForeignKey(Forum, null=True)
+ title = models.CharField(max_length=32)
+
+ def __unicode__(self):
+ return self.title
+
+class Comment(models.Model):
+ post = models.ForeignKey(Post, null=True)
+ comment_text = models.CharField(max_length=250)
+
+ def __unicode__(self):
+ return self.comment_text
+
+__test__ = {'API_TESTS':"""
+
+>>> s = SystemInfo.objects.create(system_name='First forum')
+>>> f = Forum.objects.create(system_info=s, forum_name='First forum')
+>>> p = Post.objects.create(forum=f, title='First Post')
+>>> c1 = Comment.objects.create(post=p, comment_text='My first comment')
+>>> c2 = Comment.objects.create(comment_text='My second comment')
+
+# Starting from comment, make sure that a .select_related(...) with a specified
+# set of fields will properly LEFT JOIN multiple levels of NULLs (and the things
+# that come after the NULLs, or else data that should exist won't).
+>>> c = Comment.objects.select_related().get(id=1)
+>>> c.post
+<Post: First Post>
+>>> c = Comment.objects.select_related().get(id=2)
+>>> print c.post
+None
+
+>>> comments = Comment.objects.select_related('post__forum__system_info').all()
+>>> [(c.id, c.post.id) for c in comments]
+[(1, 1), (2, None)]
+>>> [(c.comment_text, c.post.title) for c in comments]
+[(u'My first comment', u'First Post'), (u'My second comment', None)]
+
+"""}
diff --git a/tests/regressiontests/serializers_regress/models.py b/tests/regressiontests/serializers_regress/models.py
index 593e61ecc7..7d3f9d3b1d 100644
--- a/tests/regressiontests/serializers_regress/models.py
+++ b/tests/regressiontests/serializers_regress/models.py
@@ -223,3 +223,23 @@ class ModifyingSaveData(models.Model):
"A save method that modifies the data in the object"
self.data = 666
super(ModifyingSaveData, self).save(raw)
+
+# Tests for serialization of models using inheritance.
+# Regression for #7202, #7350
+class AbstractBaseModel(models.Model):
+ parent_data = models.IntegerField()
+ class Meta:
+ abstract = True
+
+class InheritAbstractModel(AbstractBaseModel):
+ child_data = models.IntegerField()
+
+class BaseModel(models.Model):
+ parent_data = models.IntegerField()
+
+class InheritBaseModel(BaseModel):
+ child_data = models.IntegerField()
+
+class ExplicitInheritBaseModel(BaseModel):
+ parent = models.OneToOneField(BaseModel)
+ child_data = models.IntegerField()
diff --git a/tests/regressiontests/serializers_regress/tests.py b/tests/regressiontests/serializers_regress/tests.py
index db34f8cf77..9bc5eec1eb 100644
--- a/tests/regressiontests/serializers_regress/tests.py
+++ b/tests/regressiontests/serializers_regress/tests.py
@@ -32,7 +32,7 @@ def data_create(pk, klass, data):
instance = klass(id=pk)
instance.data = data
models.Model.save_base(instance, raw=True)
- return instance
+ return [instance]
def generic_create(pk, klass, data):
instance = klass(id=pk)
@@ -40,32 +40,45 @@ def generic_create(pk, klass, data):
models.Model.save_base(instance, raw=True)
for tag in data[1:]:
instance.tags.create(data=tag)
- return instance
+ return [instance]
def fk_create(pk, klass, data):
instance = klass(id=pk)
setattr(instance, 'data_id', data)
models.Model.save_base(instance, raw=True)
- return instance
+ return [instance]
def m2m_create(pk, klass, data):
instance = klass(id=pk)
models.Model.save_base(instance, raw=True)
instance.data = data
- return instance
+ return [instance]
def o2o_create(pk, klass, data):
instance = klass()
instance.data_id = data
models.Model.save_base(instance, raw=True)
- return instance
+ return [instance]
def pk_create(pk, klass, data):
instance = klass()
instance.data = data
models.Model.save_base(instance, raw=True)
- return instance
+ return [instance]
+def inherited_create(pk, klass, data):
+ instance = klass(id=pk,**data)
+ # This isn't a raw save because:
+ # 1) we're testing inheritance, not field behaviour, so none
+ # of the field values need to be protected.
+ # 2) saving the child class and having the parent created
+ # automatically is easier than manually creating both.
+ models.Model.save(instance)
+ created = [instance]
+ for klass,field in instance._meta.parents.items():
+ created.append(klass.objects.get(id=pk))
+ return created
+
# A set of functions that can be used to compare
# test data objects of various kinds
def data_compare(testcase, pk, klass, data):
@@ -94,6 +107,11 @@ def pk_compare(testcase, pk, klass, data):
instance = klass.objects.get(data=data)
testcase.assertEqual(data, instance.data)
+def inherited_compare(testcase, pk, klass, data):
+ instance = klass.objects.get(id=pk)
+ for key,value in data.items():
+ testcase.assertEqual(value, getattr(instance,key))
+
# Define some data types. Each data type is
# actually a pair of functions; one to create
# and one to compare objects of that type
@@ -103,6 +121,7 @@ fk_obj = (fk_create, fk_compare)
m2m_obj = (m2m_create, m2m_compare)
o2o_obj = (o2o_create, o2o_compare)
pk_obj = (pk_create, pk_compare)
+inherited_obj = (inherited_create, inherited_compare)
test_data = [
# Format: (data type, PK value, Model Class, data)
@@ -255,6 +274,10 @@ The end."""),
(data_obj, 800, AutoNowDateTimeData, datetime.datetime(2006,6,16,10,42,37)),
(data_obj, 810, ModifyingSaveData, 42),
+
+ (inherited_obj, 900, InheritAbstractModel, {'child_data':37,'parent_data':42}),
+ (inherited_obj, 910, ExplicitInheritBaseModel, {'child_data':37,'parent_data':42}),
+ (inherited_obj, 920, InheritBaseModel, {'child_data':37,'parent_data':42}),
]
# Because Oracle treats the empty string as NULL, Oracle is expected to fail
@@ -277,13 +300,19 @@ def serializerTest(format, self):
# Create all the objects defined in the test data
objects = []
+ instance_count = {}
transaction.enter_transaction_management()
transaction.managed(True)
for (func, pk, klass, datum) in test_data:
- objects.append(func[0](pk, klass, datum))
+ objects.extend(func[0](pk, klass, datum))
+ instance_count[klass] = 0
transaction.commit()
transaction.leave_transaction_management()
+ # Get a count of the number of objects created for each class
+ for klass in instance_count:
+ instance_count[klass] = klass.objects.count()
+
# Add the generic tagged objects to the object list
objects.extend(Tag.objects.all())
@@ -304,6 +333,11 @@ def serializerTest(format, self):
for (func, pk, klass, datum) in test_data:
func[1](self, pk, klass, datum)
+ # Assert that the number of objects deserialized is the
+ # same as the number that was serialized.
+ for klass, count in instance_count.items():
+ self.assertEquals(count, klass.objects.count())
+
def fieldsTest(format, self):
# Clear the database first
management.call_command('flush', verbosity=0, interactive=False)