From e09d2de9063cf6a709441c2d21c1e6d42a62b770 Mon Sep 17 00:00:00 2001 From: Paul McMillan Date: Wed, 23 Jun 2010 10:08:19 +0000 Subject: [PATCH] [soc2010/test-refactor] Converted files modeltest to unittest. Removed unused custom field on Storage model (the same functionality is tested by random). Sadly these tests aren't threadsafe because the Storage model's temp_storage can't be changed for each testcase. git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2010/test-refactor@13392 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- tests/modeltests/files/models.py | 134 +------------------------------ tests/modeltests/files/tests.py | 126 +++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+), 131 deletions(-) create mode 100644 tests/modeltests/files/tests.py diff --git a/tests/modeltests/files/models.py b/tests/modeltests/files/models.py index 67c27b54b5..cbd5301536 100644 --- a/tests/modeltests/files/models.py +++ b/tests/modeltests/files/models.py @@ -8,147 +8,19 @@ and where files should be stored. import random import tempfile from django.db import models -from django.core.files.base import ContentFile + from django.core.files.storage import FileSystemStorage temp_storage_location = tempfile.mkdtemp() temp_storage = FileSystemStorage(location=temp_storage_location) -# Write out a file to be used as default content -temp_storage.save('tests/default.txt', ContentFile('default content')) - class Storage(models.Model): - def custom_upload_to(self, filename): - return 'foo' - def random_upload_to(self, filename): # This returns a different result each time, # to make sure it only gets called once. return '%s/%s' % (random.randint(100, 999), filename) normal = models.FileField(storage=temp_storage, upload_to='tests') - custom = models.FileField(storage=temp_storage, upload_to=custom_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') - -__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 - ->>> 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 - ->>> 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 - ->>> 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 - - -# 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 - - -# 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] -[, , ] ->>> for o in objs: -... o.delete() - -# Default values allow an object to access a single file. - ->>> obj3 = Storage.objects.create() ->>> obj3.default - ->>> 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 - - -# 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) -"""} + default = models.FileField(storage=temp_storage, upload_to='tests', + default='tests/default.txt') diff --git a/tests/modeltests/files/tests.py b/tests/modeltests/files/tests.py new file mode 100644 index 0000000000..3ee6608068 --- /dev/null +++ b/tests/modeltests/files/tests.py @@ -0,0 +1,126 @@ +import random +import shutil +import os + +from django.test import TestCase +from django.core.files.uploadedfile import SimpleUploadedFile +from django.core.files.base import ContentFile +from django.core.cache import cache + +from models import Storage, temp_storage, temp_storage_location + +def make_obj(): + obj = Storage() + obj.normal.save('django_test.txt', ContentFile('content')) + return obj + +class CustomFileStorageTestCase(TestCase): + def setUp(self): + #recreate our temp dir if necessary + if not os.path.exists(temp_storage_location): + os.mkdir(temp_storage_location) + # Write out a file to be used as default content + temp_storage.save('tests/default.txt', ContentFile('default content')) + + def tearDown(self): + #remove the temp dir after each test + shutil.rmtree(temp_storage_location) + + def test_access_from_class(self): + # Attempting to access a FileField from the class raises a + # descriptive error + self.assertRaises(AttributeError, + getattr, + Storage, 'normal') + + def test_object_without_file(self): + # An object without a file has limited functionality. + obj = Storage() + self.assertEqual(repr(obj.normal), '') + self.assertRaises(ValueError, + getattr, + obj.normal, 'size') + + def test_basic_saved_file(self): + # Saving a file enables full functionality. + obj = Storage() + obj.normal.save('django_test.txt', ContentFile('content')) + self.assertEqual(repr(obj.normal), '') + self.assertEqual(obj.normal.size, 7) + self.assertEqual(obj.normal.read(), 'content') + + + def test_attribute_assignment(self): + # File objects can be assigned to FileField attributes, but + # shouldn't get committed until the model it's attached to is + # saved. + obj = Storage() + obj.normal = SimpleUploadedFile('assignment.txt', 'content') + dirs, files = temp_storage.listdir('tests') + self.assertEqual(len(dirs), 0) + self.assertEqual(files, ['default.txt']) + obj.save() + dirs, files = temp_storage.listdir('tests') + files.sort() + self.assertEqual(files, ['assignment.txt', 'default.txt']) + + def test_file_read(self): + # Files can be read in a little at a time, if necessary. + obj = make_obj() + obj.normal.open() + self.assertEqual(obj.normal.read(3), 'con') + self.assertEqual(obj.normal.read(), 'tent') + self.assertEqual('-'.join(obj.normal.chunks(chunk_size=2)), + 'co-nt-en-t') + + def test_file_duplicate_name(self): + # Save another file with the same name. + obj = make_obj() + obj2 = Storage() + obj2.normal.save('django_test.txt', ContentFile('more content')) + self.assertEqual(repr(obj2.normal), + "") + self.assertEqual(obj2.normal.size, 12) + + def test_object_pickling(self): + # Push the objects into the cache to make sure they pickle properly + obj = make_obj() + cache.set('obj', obj) + self.assertEqual(repr(cache.get('obj').normal), + "") + + def test_delete(self): + # Deleting an object deletes the file it uses, if there are no + # other objects still using that file. + obj = make_obj() + obj.delete() + obj.normal.save('django_test.txt', ContentFile('more content')) + self.assertEqual(repr(obj.normal), + "") + + def test_duplicate_file_name_differentiation(self): + # 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(repr([o.normal for o in objs]), + "[, , ]") + + def test_default_values(self): + # Default values allow an object to access a single file. + obj = Storage.objects.create() + self.assertEqual(repr(obj.default), "") + self.assertEqual(obj.default.read(), 'default content') + + # But it shouldn't be deleted, even if there are no more + # objects using it. + obj.delete() + obj = Storage() + self.assertEqual(obj.default.read(), 'default content') + + def test_directory_determined_once(self): + # Verify the fix for #5655, making sure the directory is only + # determined once. + obj = Storage() + obj.random.save('random_file', ContentFile('random content')) + self.assertEqual(obj.random.read(), 'random content')