fix git support for v1.5.3 (or higher) by setting "--work-tree"
[translate_toolkit.git] / storage / test_zipfile.py
blob856e5c392936b18b23948b4420de1595a4a656df
1 #!/usr/bin/env python
2 import zlib # implied prerequisite
3 import zipfile, os, StringIO, tempfile
4 from test.test_support import TestFailed
5 from py import test
6 from translate.misc import zipfileext
8 BrokenStringIO = StringIO.StringIO
9 class FixedStringIO(BrokenStringIO):
10 def truncate(self, size=None):
11 BrokenStringIO.truncate(self, size)
12 self.len = len(self.buf)
14 StringIO.StringIO = FixedStringIO
16 # these tests won't all pass on zipfile module in Python 2.4
17 # there are extensions in zipfileext to add the delete method etc
18 # to test the underlying zipfile module, uncomment the following line:
19 zipfile.ZipFile = zipfileext.ZipFileExt
21 class TestZipFiles:
22 def setup_method(self, method):
23 self.srcname = "%s-%s%stmp" % (self.__class__.__name__, method.__name__, os.extsep)
24 self.zipname = "%s-%s%szip" % (self.__class__.__name__, method.__name__, os.extsep)
26 def teardown_method(self, method):
27 # Remove temporary files
28 if os.path.isfile(self.srcname):
29 os.unlink(self.srcname)
30 if os.path.isfile(self.zipname):
31 os.unlink(self.zipname)
33 def zipTest(self, f, compression, srccontents):
34 zip = zipfile.ZipFile(f, "w", compression) # Create the ZIP archive
35 zip.write(self.srcname, "another"+os.extsep+"name")
36 zip.write(self.srcname, self.srcname)
37 zip.close()
39 zip = zipfile.ZipFile(f, "r", compression) # Read the ZIP archive
40 readData2 = zip.read(self.srcname)
41 readData1 = zip.read("another"+os.extsep+"name")
42 zip.close()
44 if readData1 != srccontents or readData2 != srccontents:
45 raise TestFailed("Written data doesn't equal read data.")
47 def deleteTest(self, f, compression, srccontents):
48 zip = zipfile.ZipFile(f, "w", compression) # Create the ZIP archive
49 othername = "another"+os.extsep+"name"
50 finalname = "adifferent"+os.extsep+"name"
51 leftname, deletenames = othername, [self.srcname, finalname]
52 zip.write(self.srcname, self.srcname)
53 zip.write(self.srcname, othername)
54 zip.write(self.srcname, finalname)
55 zip.close()
57 zip = zipfile.ZipFile(f, "a", compression) # Modify the ZIP archive
58 try:
59 for deletename in deletenames:
60 zip.delete(deletename)
61 finally:
62 zip.close()
64 zip = zipfile.ZipFile(f, "r", compression) # Read the ZIP archive
65 try:
66 testfailed = zip.testzip()
67 readData = zip.read(leftname)
68 finally:
69 zip.close()
71 assert not testfailed
72 assert readData == srccontents
74 def test_create_zip(self):
75 fp = open(self.srcname, "wb") # Make a source file with some lines
76 for i in range(0, 1000):
77 fp.write("Test of zipfile line %d.\n" % i)
78 fp.close()
80 fp = open(self.srcname, "rb")
81 writtenData = fp.read()
82 fp.close()
84 for file in (self.zipname, tempfile.TemporaryFile(), StringIO.StringIO()):
85 self.zipTest(file, zipfile.ZIP_STORED, writtenData)
87 for file in (self.zipname, tempfile.TemporaryFile(), StringIO.StringIO()):
88 self.zipTest(file, zipfile.ZIP_DEFLATED, writtenData)
90 def test_delete_member(self):
91 fp = open(self.srcname, "wb") # Make a source file with some lines
92 for i in range(0, 1000):
93 fp.write("Test of zipfile line %d.\n" % i)
94 fp.close()
96 fp = open(self.srcname, "rb")
97 writtenData = fp.read()
98 fp.close()
100 self.deleteTest(self.zipname, zipfile.ZIP_STORED, writtenData)
101 self.deleteTest(tempfile.TemporaryFile(), zipfile.ZIP_STORED, writtenData)
102 self.deleteTest(StringIO.StringIO(), zipfile.ZIP_STORED, writtenData)
104 self.deleteTest(self.zipname, zipfile.ZIP_DEFLATED, writtenData)
105 self.deleteTest(tempfile.TemporaryFile(), zipfile.ZIP_DEFLATED, writtenData)
106 self.deleteTest(StringIO.StringIO(), zipfile.ZIP_DEFLATED, writtenData)
108 def test_handles_error(self):
109 """This test checks that the ZipFile constructor closes the file object"""
110 """it opens if there's an error in the file. If it doesn't, the traceback"""
111 """holds a reference to the ZipFile object and, indirectly, the file object."""
112 """On Windows, this causes the os.unlink() call to fail because the"""
113 """underlying file is still open. This is SF bug #412214."""
114 fp = open(self.srcname, "w")
115 fp.write("this is not a legal zip file\n")
116 fp.close()
117 assert test.raises(zipfile.BadZipfile, zipfile.ZipFile, self.srcname)
118 os.unlink(self.srcname)
120 def test_finalize(self):
121 """make sure we don't raise an AttributeError when a partially-constructed"""
122 """ZipFile instance is finalized; this tests for regression on SF tracker"""
123 """bug #403871."""
124 assert test.raises(IOError, zipfile.ZipFile, self.srcname)
125 # The bug we're testing for caused an AttributeError to be raised
126 # when a ZipFile instance was created for a file that did not
127 # exist; the .fp member was not initialized but was needed by the
128 # __del__() method. Since the AttributeError is in the __del__(),
129 # it is ignored, but the user should be sufficiently annoyed by
130 # the message on the output that regression will be noticed
131 # quickly.
133 def test_fail_read_closed(self):
134 # Verify that testzip() doesn't swallow inappropriate exceptions.
135 data = StringIO.StringIO()
136 zipf = zipfile.ZipFile(data, mode="w")
137 zipf.writestr("foo.txt", "O, for a Muse of Fire!")
138 zipf.close()
139 zipf = zipfile.ZipFile(data, mode="r")
140 zipf.close()
141 # This is correct; calling .read on a closed ZipFile should throw
142 # a RuntimeError, and so should calling .testzip. An earlier
143 # version of .testzip would swallow this exception (and any other)
144 # and report that the first file in the archive was corrupt.
145 assert test.raises(RuntimeError, zipf.testzip)
146 del data, zipf