]> git.saurik.com Git - wxWidgets.git/blob - tests/archive/ziptest.cpp
fixing m_axe access indices
[wxWidgets.git] / tests / archive / ziptest.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/archive/ziptest.cpp
3 // Purpose: Test the zip classes
4 // Author: Mike Wetherell
5 // RCS-ID: $Id$
6 // Copyright: (c) 2004 Mike Wetherell
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
9
10 #include "testprec.h"
11
12 #ifdef __BORLANDC__
13 # pragma hdrstop
14 #endif
15
16 #ifndef WX_PRECOMP
17 # include "wx/wx.h"
18 #endif
19
20 #if wxUSE_STREAMS && wxUSE_ZIPSTREAM
21
22 #include "archivetest.h"
23 #include "wx/zipstrm.h"
24
25 using std::string;
26 using std::auto_ptr;
27
28
29 ///////////////////////////////////////////////////////////////////////////////
30 // ArchiveTestCase<wxZipClassFactory> could be used directly, but instead this
31 // derived class is used so that zip specific features can be tested.
32
33 class ZipTestCase : public ArchiveTestCase<wxZipClassFactory>
34 {
35 public:
36 ZipTestCase(string name,
37 int options,
38 const wxString& archiver = wxEmptyString,
39 const wxString& unarchiver = wxEmptyString)
40 :
41 ArchiveTestCase<wxZipClassFactory>(name, new wxZipClassFactory,
42 options, archiver, unarchiver),
43 m_count(0)
44 { }
45
46 protected:
47 void OnCreateArchive(wxZipOutputStream& zip);
48
49 void OnArchiveExtracted(wxZipInputStream& zip, int expectedTotal);
50
51 void OnCreateEntry(wxZipOutputStream& zip,
52 TestEntry& testEntry,
53 wxZipEntry *entry);
54
55 void OnEntryExtracted(wxZipEntry& entry,
56 const TestEntry& testEntry,
57 wxZipInputStream *arc);
58
59 void OnSetNotifier(EntryT& entry);
60
61 int m_count;
62 wxString m_comment;
63 };
64
65 void ZipTestCase::OnCreateArchive(wxZipOutputStream& zip)
66 {
67 m_comment << wxT("Comment for test ") << m_id;
68 zip.SetComment(m_comment);
69 }
70
71 void ZipTestCase::OnArchiveExtracted(wxZipInputStream& zip, int expectedTotal)
72 {
73 CPPUNIT_ASSERT(zip.GetComment() == m_comment);
74 CPPUNIT_ASSERT(zip.GetTotalEntries() == expectedTotal);
75 }
76
77 void ZipTestCase::OnCreateEntry(wxZipOutputStream& zip,
78 TestEntry& testEntry,
79 wxZipEntry *entry)
80 {
81 zip.SetLevel((m_id + m_count) % 10);
82
83 if (entry) {
84 switch ((m_id + m_count) % 5) {
85 case 0:
86 {
87 wxString comment = wxT("Comment for ") + entry->GetName();
88 entry->SetComment(comment);
89 // lowercase the expected result, and the notifier should do
90 // the same for the zip entries when ModifyArchive() runs
91 testEntry.SetComment(comment.Lower());
92 break;
93 }
94 case 2:
95 entry->SetMethod(wxZIP_METHOD_STORE);
96 break;
97 case 4:
98 entry->SetMethod(wxZIP_METHOD_DEFLATE);
99 break;
100 }
101 entry->SetIsText(testEntry.IsText());
102 }
103
104 m_count++;
105 }
106
107 void ZipTestCase::OnEntryExtracted(wxZipEntry& entry,
108 const TestEntry& testEntry,
109 wxZipInputStream *arc)
110 {
111 // provide some context for the error message so that we know which
112 // iteration of the loop we were on
113 wxString name = wxT(" '") + entry.GetName() + wxT("'");
114 string error_entry(name.mb_str());
115 string error_context(" failed for entry" + error_entry);
116
117 CPPUNIT_ASSERT_MESSAGE("GetComment" + error_context,
118 entry.GetComment() == testEntry.GetComment());
119
120 // for seekable streams, GetNextEntry() doesn't read the local header so
121 // call OpenEntry() to do it
122 if (arc && (m_options & PipeIn) == 0 && entry.IsDir())
123 arc->OpenEntry(entry);
124
125 CPPUNIT_ASSERT_MESSAGE("IsText" + error_context,
126 entry.IsText() == testEntry.IsText());
127
128 CPPUNIT_ASSERT_MESSAGE("Extra/LocalExtra mismatch for entry" + error_entry,
129 (entry.GetExtraLen() != 0 && entry.GetLocalExtraLen() != 0) ||
130 (entry.GetExtraLen() == 0 && entry.GetLocalExtraLen() == 0));
131 }
132
133 // check the notifier mechanism by using it to fold the entry comments to
134 // lowercase
135 //
136 class ZipNotifier : public wxZipNotifier
137 {
138 public:
139 void OnEntryUpdated(wxZipEntry& entry);
140 };
141
142 void ZipNotifier::OnEntryUpdated(wxZipEntry& entry)
143 {
144 entry.SetComment(entry.GetComment().Lower());
145 }
146
147 void ZipTestCase::OnSetNotifier(EntryT& entry)
148 {
149 static ZipNotifier notifier;
150 entry.SetNotifier(notifier);
151 }
152
153
154 ///////////////////////////////////////////////////////////////////////////////
155 // 'zip - -' produces local headers without the size field set. This is a
156 // case not covered by all the other tests, so this class tests it as a
157 // special case
158
159 class ZipPipeTestCase : public CppUnit::TestCase
160 {
161 public:
162 ZipPipeTestCase(string name, int options) :
163 CppUnit::TestCase(TestId::MakeId() + name),
164 m_options(options),
165 m_id(TestId::GetId())
166 { }
167
168 protected:
169 void runTest();
170 int m_options;
171 int m_id;
172 };
173
174 void ZipPipeTestCase::runTest()
175 {
176 TestOutputStream out(m_options);
177
178 wxString testdata = wxT("test data to pipe through zip");
179 wxString cmd = wxT("echo ") + testdata + wxT(" | zip -q - -");
180
181 {
182 PFileInputStream in(cmd);
183 if (in.IsOk())
184 out.Write(in);
185 }
186
187 TestInputStream in(out, m_id % ((m_options & PipeIn) ? 4 : 3));
188 wxZipInputStream zip(in);
189
190 auto_ptr<wxZipEntry> entry(zip.GetNextEntry());
191 CPPUNIT_ASSERT(entry.get() != NULL);
192
193 if ((m_options & PipeIn) == 0)
194 CPPUNIT_ASSERT(entry->GetSize() != wxInvalidOffset);
195
196 char buf[64];
197 size_t len = zip.Read(buf, sizeof(buf) - 1).LastRead();
198
199 while (len > 0 && buf[len - 1] <= 32)
200 --len;
201 buf[len] = 0;
202
203 CPPUNIT_ASSERT(zip.Eof());
204 CPPUNIT_ASSERT(wxString(buf, *wxConvCurrent) == testdata);
205 }
206
207
208 ///////////////////////////////////////////////////////////////////////////////
209 // Zip suite
210
211 class ziptest : public ArchiveTestSuite
212 {
213 public:
214 ziptest();
215 static CppUnit::Test *suite() { return (new ziptest)->makeSuite(); }
216
217 protected:
218 ArchiveTestSuite *makeSuite();
219
220 CppUnit::Test *makeTest(string descr, int options,
221 bool genericInterface, const wxString& archiver,
222 const wxString& unarchiver);
223 };
224
225 ziptest::ziptest()
226 : ArchiveTestSuite("zip")
227 {
228 AddArchiver(wxT("zip -qr %s *"));
229 AddUnArchiver(wxT("unzip -q %s"));
230 }
231
232 ArchiveTestSuite *ziptest::makeSuite()
233 {
234 ArchiveTestSuite::makeSuite();
235
236 #if !defined WXARC_NO_POPEN && !defined __WXMSW__
237 // If have popen then can check the piped output of 'zip - -'.
238 // The gnuwin32 build of infozip does work for this, e.g.:
239 // C:\>echo test data to pipe through zip | zip -q > foo.zip
240 // doesn't produce a valid zip, so disabled for now.
241 if (IsInPath(wxT("zip")))
242 for (int options = 0; options <= PipeIn; options += PipeIn) {
243 string name = Description(wxT("ZipPipeTestCase"), options,
244 false, wxT(""), wxT("zip -q - -"));
245 addTest(new ZipPipeTestCase(name, options));
246 }
247 #endif
248
249 return this;
250 }
251
252 CppUnit::Test *ziptest::makeTest(
253 string descr,
254 int options,
255 bool genericInterface,
256 const wxString& archiver,
257 const wxString& unarchiver)
258 {
259 // unzip doesn't support piping in the zip
260 if ((options & PipeIn) && !unarchiver.empty())
261 return NULL;
262
263 if (genericInterface)
264 {
265 return new ArchiveTestCase<wxArchiveClassFactory>(
266 descr, new wxZipClassFactory,
267 options, archiver, unarchiver);
268 }
269
270 return new ZipTestCase(descr, options, archiver, unarchiver);
271 }
272
273 CPPUNIT_TEST_SUITE_REGISTRATION(ziptest);
274 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(ziptest, "archive");
275 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(ziptest, "archive/zip");
276
277 #endif // wxUSE_STREAMS && wxUSE_ZIPSTREAM