Migrate the files doctests. Thanks to Alex Gaynor.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@13781 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Russell Keith-Magee 2010-09-12 20:03:55 +00:00
parent e2e1802e48
commit a45c687ecf
2 changed files with 102 additions and 122 deletions

View File

@ -7,10 +7,12 @@ and where files should be stored.
import random import random
import tempfile import tempfile
from django.db import models from django.db import models
from django.core.files.base import ContentFile from django.core.files.base import ContentFile
from django.core.files.storage import FileSystemStorage from django.core.files.storage import FileSystemStorage
temp_storage_location = tempfile.mkdtemp() temp_storage_location = tempfile.mkdtemp()
temp_storage = FileSystemStorage(location=temp_storage_location) temp_storage = FileSystemStorage(location=temp_storage_location)
@ -30,125 +32,3 @@ class Storage(models.Model):
custom = models.FileField(storage=temp_storage, upload_to=custom_upload_to) custom = models.FileField(storage=temp_storage, upload_to=custom_upload_to)
random = models.FileField(storage=temp_storage, upload_to=random_upload_to) random = models.FileField(storage=temp_storage, upload_to=random_upload_to)
default = models.FileField(storage=temp_storage, upload_to='tests', default='tests/default.txt') default = models.FileField(storage=temp_storage, upload_to='tests', default='tests/default.txt')
__test__ = {'API_TESTS':"""
# Attempting to access a FileField from the class raises a descriptive error
>>> Storage.normal
Traceback (most recent call last):
...
AttributeError: The 'normal' attribute can only be accessed from Storage instances.
# An object without a file has limited functionality.
>>> obj1 = Storage()
>>> obj1.normal
<FieldFile: None>
>>> obj1.normal.size
Traceback (most recent call last):
...
ValueError: The 'normal' attribute has no file associated with it.
# Saving a file enables full functionality.
>>> obj1.normal.save('django_test.txt', ContentFile('content'))
>>> obj1.normal
<FieldFile: tests/django_test.txt>
>>> obj1.normal.size
7
>>> obj1.normal.read()
'content'
# File objects can be assigned to FileField attributes, but shouldn't get
# committed until the model it's attached to is saved.
>>> from django.core.files.uploadedfile import SimpleUploadedFile
>>> obj1.normal = SimpleUploadedFile('assignment.txt', 'content')
>>> dirs, files = temp_storage.listdir('tests')
>>> dirs
[]
>>> files.sort()
>>> files == ['default.txt', 'django_test.txt']
True
>>> obj1.save()
>>> dirs, files = temp_storage.listdir('tests')
>>> files.sort()
>>> files == ['assignment.txt', 'default.txt', 'django_test.txt']
True
# Files can be read in a little at a time, if necessary.
>>> obj1.normal.open()
>>> obj1.normal.read(3)
'con'
>>> obj1.normal.read()
'tent'
>>> '-'.join(obj1.normal.chunks(chunk_size=2))
'co-nt-en-t'
# Save another file with the same name.
>>> obj2 = Storage()
>>> obj2.normal.save('django_test.txt', ContentFile('more content'))
>>> obj2.normal
<FieldFile: tests/django_test_1.txt>
>>> obj2.normal.size
12
# Push the objects into the cache to make sure they pickle properly
>>> from django.core.cache import cache
>>> cache.set('obj1', obj1)
>>> cache.set('obj2', obj2)
>>> cache.get('obj2').normal
<FieldFile: tests/django_test_1.txt>
# Deleting an object deletes the file it uses, if there are no other objects
# still using that file.
>>> obj2.delete()
>>> obj2.normal.save('django_test.txt', ContentFile('more content'))
>>> obj2.normal
<FieldFile: tests/django_test_1.txt>
# Multiple files with the same name get _N appended to them.
>>> objs = [Storage() for i in range(3)]
>>> for o in objs:
... o.normal.save('multiple_files.txt', ContentFile('Same Content'))
>>> [o.normal for o in objs]
[<FieldFile: tests/multiple_files.txt>, <FieldFile: tests/multiple_files_1.txt>, <FieldFile: tests/multiple_files_2.txt>]
>>> for o in objs:
... o.delete()
# Default values allow an object to access a single file.
>>> obj3 = Storage.objects.create()
>>> obj3.default
<FieldFile: tests/default.txt>
>>> obj3.default.read()
'default content'
# But it shouldn't be deleted, even if there are no more objects using it.
>>> obj3.delete()
>>> obj3 = Storage()
>>> obj3.default.read()
'default content'
# Verify the fix for #5655, making sure the directory is only determined once.
>>> obj4 = Storage()
>>> obj4.random.save('random_file', ContentFile('random content'))
>>> obj4.random
<FieldFile: .../random_file>
# Clean up the temporary files and dir.
>>> obj1.normal.delete()
>>> obj2.normal.delete()
>>> obj3.default.delete()
>>> obj4.random.delete()
>>> import shutil
>>> shutil.rmtree(temp_storage_location)
"""}

View File

@ -0,0 +1,100 @@
import shutil
from django.core.cache import cache
from django.core.files.base import ContentFile
from django.core.files.uploadedfile import SimpleUploadedFile
from django.test import TestCase
from models import Storage, temp_storage, temp_storage_location
class FileTests(TestCase):
def tearDown(self):
shutil.rmtree(temp_storage_location)
def test_files(self):
# Attempting to access a FileField from the class raises a descriptive
# error
self.assertRaises(AttributeError, lambda: Storage.normal)
# An object without a file has limited functionality.
obj1 = Storage()
self.assertEqual(obj1.normal.name, "")
self.assertRaises(ValueError, lambda: obj1.normal.size)
# Saving a file enables full functionality.
obj1.normal.save("django_test.txt", ContentFile("content"))
self.assertEqual(obj1.normal.name, "tests/django_test.txt")
self.assertEqual(obj1.normal.size, 7)
self.assertEqual(obj1.normal.read(), "content")
# File objects can be assigned to FileField attributes, but shouldn't
# get committed until the model it's attached to is saved.
obj1.normal = SimpleUploadedFile("assignment.txt", "content")
dirs, files = temp_storage.listdir("tests")
self.assertEqual(dirs, [])
self.assertEqual(sorted(files), ["default.txt", "django_test.txt"])
obj1.save()
dirs, files = temp_storage.listdir("tests")
self.assertEqual(
sorted(files), ["assignment.txt", "default.txt", "django_test.txt"]
)
# Files can be read in a little at a time, if necessary.
obj1.normal.open()
self.assertEqual(obj1.normal.read(3), "con")
self.assertEqual(obj1.normal.read(), "tent")
self.assertEqual(list(obj1.normal.chunks(chunk_size=2)), ["co", "nt", "en", "t"])
# Save another file with the same name.
obj2 = Storage()
obj2.normal.save("django_test.txt", ContentFile("more content"))
self.assertEqual(obj2.normal.name, "tests/django_test_1.txt")
self.assertEqual(obj2.normal.size, 12)
# Push the objects into the cache to make sure they pickle properly
cache.set("obj1", obj1)
cache.set("obj2", obj2)
self.assertEqual(cache.get("obj2").normal.name, "tests/django_test_1.txt")
# Deleting an object deletes the file it uses, if there are no other
# objects still using that file.
obj2.delete()
obj2.normal.save("django_test.txt", ContentFile("more content"))
self.assertEqual(obj2.normal.name, "tests/django_test_1.txt")
# Multiple files with the same name get _N appended to them.
objs = [Storage() for i in range(3)]
for o in objs:
o.normal.save("multiple_files.txt", ContentFile("Same Content"))
self.assertEqual(
[o.normal.name for o in objs],
["tests/multiple_files.txt", "tests/multiple_files_1.txt", "tests/multiple_files_2.txt"]
)
for o in objs:
o.delete()
# Default values allow an object to access a single file.
obj3 = Storage.objects.create()
self.assertEqual(obj3.default.name, "tests/default.txt")
self.assertEqual(obj3.default.read(), "default content")
# But it shouldn't be deleted, even if there are no more objects using
# it.
obj3.delete()
obj3 = Storage()
self.assertEqual(obj3.default.read(), "default content")
# Verify the fix for #5655, making sure the directory is only
# determined once.
obj4 = Storage()
obj4.random.save("random_file", ContentFile("random content"))
self.assertTrue(obj4.random.name.endswith("/random_file"))
# Clean up the temporary files and dir.
obj1.normal.delete()
obj2.normal.delete()
obj3.default.delete()
obj4.random.delete()