Skip to content

Commit e09d2de

Browse files
committed
[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
1 parent c8624d4 commit e09d2de

File tree

2 files changed

+129
-131
lines changed

2 files changed

+129
-131
lines changed

tests/modeltests/files/models.py

Lines changed: 3 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -8,147 +8,19 @@
88
import random
99
import tempfile
1010
from django.db import models
11-
from django.core.files.base import ContentFile
11+
1212
from django.core.files.storage import FileSystemStorage
1313

1414
temp_storage_location = tempfile.mkdtemp()
1515
temp_storage = FileSystemStorage(location=temp_storage_location)
1616

17-
# Write out a file to be used as default content
18-
temp_storage.save('tests/default.txt', ContentFile('default content'))
19-
2017
class Storage(models.Model):
21-
def custom_upload_to(self, filename):
22-
return 'foo'
23-
2418
def random_upload_to(self, filename):
2519
# This returns a different result each time,
2620
# to make sure it only gets called once.
2721
return '%s/%s' % (random.randint(100, 999), filename)
2822

2923
normal = models.FileField(storage=temp_storage, upload_to='tests')
30-
custom = models.FileField(storage=temp_storage, upload_to=custom_upload_to)
3124
random = models.FileField(storage=temp_storage, upload_to=random_upload_to)
32-
default = models.FileField(storage=temp_storage, upload_to='tests', default='tests/default.txt')
33-
34-
__test__ = {'API_TESTS':"""
35-
# Attempting to access a FileField from the class raises a descriptive error
36-
>>> Storage.normal
37-
Traceback (most recent call last):
38-
...
39-
AttributeError: The 'normal' attribute can only be accessed from Storage instances.
40-
41-
# An object without a file has limited functionality.
42-
43-
>>> obj1 = Storage()
44-
>>> obj1.normal
45-
<FieldFile: None>
46-
>>> obj1.normal.size
47-
Traceback (most recent call last):
48-
...
49-
ValueError: The 'normal' attribute has no file associated with it.
50-
51-
# Saving a file enables full functionality.
52-
53-
>>> obj1.normal.save('django_test.txt', ContentFile('content'))
54-
>>> obj1.normal
55-
<FieldFile: tests/django_test.txt>
56-
>>> obj1.normal.size
57-
7
58-
>>> obj1.normal.read()
59-
'content'
60-
61-
# File objects can be assigned to FileField attributes, but shouldn't get
62-
# committed until the model it's attached to is saved.
63-
64-
>>> from django.core.files.uploadedfile import SimpleUploadedFile
65-
>>> obj1.normal = SimpleUploadedFile('assignment.txt', 'content')
66-
>>> dirs, files = temp_storage.listdir('tests')
67-
>>> dirs
68-
[]
69-
>>> files.sort()
70-
>>> files == ['default.txt', 'django_test.txt']
71-
True
72-
73-
>>> obj1.save()
74-
>>> dirs, files = temp_storage.listdir('tests')
75-
>>> files.sort()
76-
>>> files == ['assignment.txt', 'default.txt', 'django_test.txt']
77-
True
78-
79-
# Files can be read in a little at a time, if necessary.
80-
81-
>>> obj1.normal.open()
82-
>>> obj1.normal.read(3)
83-
'con'
84-
>>> obj1.normal.read()
85-
'tent'
86-
>>> '-'.join(obj1.normal.chunks(chunk_size=2))
87-
'co-nt-en-t'
88-
89-
# Save another file with the same name.
90-
91-
>>> obj2 = Storage()
92-
>>> obj2.normal.save('django_test.txt', ContentFile('more content'))
93-
>>> obj2.normal
94-
<FieldFile: tests/django_test_1.txt>
95-
>>> obj2.normal.size
96-
12
97-
98-
# Push the objects into the cache to make sure they pickle properly
99-
100-
>>> from django.core.cache import cache
101-
>>> cache.set('obj1', obj1)
102-
>>> cache.set('obj2', obj2)
103-
>>> cache.get('obj2').normal
104-
<FieldFile: tests/django_test_1.txt>
105-
106-
# Deleting an object deletes the file it uses, if there are no other objects
107-
# still using that file.
108-
109-
>>> obj2.delete()
110-
>>> obj2.normal.save('django_test.txt', ContentFile('more content'))
111-
>>> obj2.normal
112-
<FieldFile: tests/django_test_1.txt>
113-
114-
# Multiple files with the same name get _N appended to them.
115-
116-
>>> objs = [Storage() for i in range(3)]
117-
>>> for o in objs:
118-
... o.normal.save('multiple_files.txt', ContentFile('Same Content'))
119-
>>> [o.normal for o in objs]
120-
[<FieldFile: tests/multiple_files.txt>, <FieldFile: tests/multiple_files_1.txt>, <FieldFile: tests/multiple_files_2.txt>]
121-
>>> for o in objs:
122-
... o.delete()
123-
124-
# Default values allow an object to access a single file.
125-
126-
>>> obj3 = Storage.objects.create()
127-
>>> obj3.default
128-
<FieldFile: tests/default.txt>
129-
>>> obj3.default.read()
130-
'default content'
131-
132-
# But it shouldn't be deleted, even if there are no more objects using it.
133-
134-
>>> obj3.delete()
135-
>>> obj3 = Storage()
136-
>>> obj3.default.read()
137-
'default content'
138-
139-
# Verify the fix for #5655, making sure the directory is only determined once.
140-
141-
>>> obj4 = Storage()
142-
>>> obj4.random.save('random_file', ContentFile('random content'))
143-
>>> obj4.random
144-
<FieldFile: .../random_file>
145-
146-
# Clean up the temporary files and dir.
147-
>>> obj1.normal.delete()
148-
>>> obj2.normal.delete()
149-
>>> obj3.default.delete()
150-
>>> obj4.random.delete()
151-
152-
>>> import shutil
153-
>>> shutil.rmtree(temp_storage_location)
154-
"""}
25+
default = models.FileField(storage=temp_storage, upload_to='tests',
26+
default='tests/default.txt')

tests/modeltests/files/tests.py

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import random
2+
import shutil
3+
import os
4+
5+
from django.test import TestCase
6+
from django.core.files.uploadedfile import SimpleUploadedFile
7+
from django.core.files.base import ContentFile
8+
from django.core.cache import cache
9+
10+
from models import Storage, temp_storage, temp_storage_location
11+
12+
def make_obj():
13+
obj = Storage()
14+
obj.normal.save('django_test.txt', ContentFile('content'))
15+
return obj
16+
17+
class CustomFileStorageTestCase(TestCase):
18+
def setUp(self):
19+
#recreate our temp dir if necessary
20+
if not os.path.exists(temp_storage_location):
21+
os.mkdir(temp_storage_location)
22+
# Write out a file to be used as default content
23+
temp_storage.save('tests/default.txt', ContentFile('default content'))
24+
25+
def tearDown(self):
26+
#remove the temp dir after each test
27+
shutil.rmtree(temp_storage_location)
28+
29+
def test_access_from_class(self):
30+
# Attempting to access a FileField from the class raises a
31+
# descriptive error
32+
self.assertRaises(AttributeError,
33+
getattr,
34+
Storage, 'normal')
35+
36+
def test_object_without_file(self):
37+
# An object without a file has limited functionality.
38+
obj = Storage()
39+
self.assertEqual(repr(obj.normal), '<FieldFile: None>')
40+
self.assertRaises(ValueError,
41+
getattr,
42+
obj.normal, 'size')
43+
44+
def test_basic_saved_file(self):
45+
# Saving a file enables full functionality.
46+
obj = Storage()
47+
obj.normal.save('django_test.txt', ContentFile('content'))
48+
self.assertEqual(repr(obj.normal), '<FieldFile: tests/django_test.txt>')
49+
self.assertEqual(obj.normal.size, 7)
50+
self.assertEqual(obj.normal.read(), 'content')
51+
52+
53+
def test_attribute_assignment(self):
54+
# File objects can be assigned to FileField attributes, but
55+
# shouldn't get committed until the model it's attached to is
56+
# saved.
57+
obj = Storage()
58+
obj.normal = SimpleUploadedFile('assignment.txt', 'content')
59+
dirs, files = temp_storage.listdir('tests')
60+
self.assertEqual(len(dirs), 0)
61+
self.assertEqual(files, ['default.txt'])
62+
obj.save()
63+
dirs, files = temp_storage.listdir('tests')
64+
files.sort()
65+
self.assertEqual(files, ['assignment.txt', 'default.txt'])
66+
67+
def test_file_read(self):
68+
# Files can be read in a little at a time, if necessary.
69+
obj = make_obj()
70+
obj.normal.open()
71+
self.assertEqual(obj.normal.read(3), 'con')
72+
self.assertEqual(obj.normal.read(), 'tent')
73+
self.assertEqual('-'.join(obj.normal.chunks(chunk_size=2)),
74+
'co-nt-en-t')
75+
76+
def test_file_duplicate_name(self):
77+
# Save another file with the same name.
78+
obj = make_obj()
79+
obj2 = Storage()
80+
obj2.normal.save('django_test.txt', ContentFile('more content'))
81+
self.assertEqual(repr(obj2.normal),
82+
"<FieldFile: tests/django_test_1.txt>")
83+
self.assertEqual(obj2.normal.size, 12)
84+
85+
def test_object_pickling(self):
86+
# Push the objects into the cache to make sure they pickle properly
87+
obj = make_obj()
88+
cache.set('obj', obj)
89+
self.assertEqual(repr(cache.get('obj').normal),
90+
"<FieldFile: tests/django_test.txt>")
91+
92+
def test_delete(self):
93+
# Deleting an object deletes the file it uses, if there are no
94+
# other objects still using that file.
95+
obj = make_obj()
96+
obj.delete()
97+
obj.normal.save('django_test.txt', ContentFile('more content'))
98+
self.assertEqual(repr(obj.normal),
99+
"<FieldFile: tests/django_test.txt>")
100+
101+
def test_duplicate_file_name_differentiation(self):
102+
# Multiple files with the same name get _N appended to them.
103+
objs = [Storage() for i in range(3)]
104+
for o in objs:
105+
o.normal.save('multiple_files.txt', ContentFile('Same Content'))
106+
self.assertEqual(repr([o.normal for o in objs]),
107+
"[<FieldFile: tests/multiple_files.txt>, <FieldFile: tests/multiple_files_1.txt>, <FieldFile: tests/multiple_files_2.txt>]")
108+
109+
def test_default_values(self):
110+
# Default values allow an object to access a single file.
111+
obj = Storage.objects.create()
112+
self.assertEqual(repr(obj.default), "<FieldFile: tests/default.txt>")
113+
self.assertEqual(obj.default.read(), 'default content')
114+
115+
# But it shouldn't be deleted, even if there are no more
116+
# objects using it.
117+
obj.delete()
118+
obj = Storage()
119+
self.assertEqual(obj.default.read(), 'default content')
120+
121+
def test_directory_determined_once(self):
122+
# Verify the fix for #5655, making sure the directory is only
123+
# determined once.
124+
obj = Storage()
125+
obj.random.save('random_file', ContentFile('random content'))
126+
self.assertEqual(obj.random.read(), 'random content')

0 commit comments

Comments
 (0)