ziptest.cpp 7.6 KB

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