archivetest.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Name: tests/archive/archivetest.h
  3. // Purpose: Test the archive classes
  4. // Author: Mike Wetherell
  5. // Copyright: (c) 2004 Mike Wetherell
  6. // Licence: wxWindows licence
  7. ///////////////////////////////////////////////////////////////////////////////
  8. #ifndef WX_ARCHIVETEST_INCLUDED
  9. #define WX_ARCHIVETEST_INCLUDED 1
  10. #define WX_TEST_ARCHIVE_ITERATOR
  11. #include "wx/archive.h"
  12. #include "wx/wfstream.h"
  13. ///////////////////////////////////////////////////////////////////////////////
  14. // Bit flags for options for the tests
  15. enum Options
  16. {
  17. PipeIn = 0x01, // input streams are non-seekable
  18. PipeOut = 0x02, // output streams are non-seekable
  19. Stub = 0x04, // the archive should be appended to a stub
  20. AllOptions = 0x07
  21. };
  22. ///////////////////////////////////////////////////////////////////////////////
  23. // TestOutputStream and TestInputStream are memory streams which can be
  24. // seekable or non-seekable.
  25. class TestOutputStream : public wxOutputStream
  26. {
  27. public:
  28. TestOutputStream(int options);
  29. ~TestOutputStream() { delete [] m_data; }
  30. int GetOptions() const { return m_options; }
  31. wxFileOffset GetLength() const { return m_size; }
  32. bool IsSeekable() const { return (m_options & PipeOut) == 0; }
  33. // gives away the data, this stream is then empty, and can be reused
  34. void GetData(char*& data, size_t& size);
  35. private:
  36. void Init();
  37. wxFileOffset OnSysSeek(wxFileOffset pos, wxSeekMode mode);
  38. wxFileOffset OnSysTell() const;
  39. size_t OnSysWrite(const void *buffer, size_t size);
  40. int m_options;
  41. size_t m_pos;
  42. size_t m_capacity;
  43. size_t m_size;
  44. char *m_data;
  45. };
  46. class TestInputStream : public wxInputStream
  47. {
  48. public:
  49. // various streams have implemented eof differently, so check the archive
  50. // stream works with all the possibilities (bit flags that can be ORed)
  51. enum EofTypes {
  52. AtLast = 0x01, // eof before an attempt to read past the last byte
  53. WithError = 0x02 // give an error instead of eof
  54. };
  55. // ctor takes the data from the output stream, which is then empty
  56. TestInputStream(TestOutputStream& out, int eoftype)
  57. : m_data(NULL), m_eoftype(eoftype) { SetData(out); }
  58. // this ctor 'dups'
  59. TestInputStream(const TestInputStream& in);
  60. ~TestInputStream() { delete [] m_data; }
  61. void Rewind();
  62. wxFileOffset GetLength() const { return m_size; }
  63. bool IsSeekable() const { return (m_options & PipeIn) == 0; }
  64. void SetData(TestOutputStream& out);
  65. void Chop(size_t size) { m_size = size; }
  66. char& operator [](size_t pos) { return m_data[pos]; }
  67. private:
  68. wxFileOffset OnSysSeek(wxFileOffset pos, wxSeekMode mode);
  69. wxFileOffset OnSysTell() const;
  70. size_t OnSysRead(void *buffer, size_t size);
  71. int m_options;
  72. size_t m_pos;
  73. size_t m_size;
  74. char *m_data;
  75. int m_eoftype;
  76. };
  77. ///////////////////////////////////////////////////////////////////////////////
  78. // wxFFile streams for piping to/from an external program
  79. class PFileInputStream : public wxFFileInputStream
  80. {
  81. public:
  82. PFileInputStream(const wxString& cmd);
  83. ~PFileInputStream();
  84. };
  85. class PFileOutputStream : public wxFFileOutputStream
  86. {
  87. public:
  88. PFileOutputStream(const wxString& cmd);
  89. ~PFileOutputStream();
  90. };
  91. ///////////////////////////////////////////////////////////////////////////////
  92. // A class to hold a test entry
  93. class TestEntry
  94. {
  95. public:
  96. TestEntry(const wxDateTime& dt, int len, const char *data);
  97. ~TestEntry() { delete [] m_data; }
  98. wxDateTime GetDateTime() const { return m_dt; }
  99. wxFileOffset GetLength() const { return m_len; }
  100. size_t GetSize() const { return m_len; }
  101. const char *GetData() const { return m_data; }
  102. wxString GetComment() const { return m_comment; }
  103. bool IsText() const { return m_isText; }
  104. void SetComment(const wxString& comment) { m_comment = comment; }
  105. void SetDateTime(const wxDateTime& dt) { m_dt = dt; }
  106. private:
  107. wxDateTime m_dt;
  108. size_t m_len;
  109. char *m_data;
  110. wxString m_comment;
  111. bool m_isText;
  112. };
  113. ///////////////////////////////////////////////////////////////////////////////
  114. // The test case
  115. template <class ClassFactoryT>
  116. class ArchiveTestCase : public CppUnit::TestCase
  117. {
  118. public:
  119. ArchiveTestCase(std::string name,
  120. ClassFactoryT *factory,
  121. int options,
  122. const wxString& archiver = wxEmptyString,
  123. const wxString& unarchiver = wxEmptyString);
  124. ~ArchiveTestCase();
  125. protected:
  126. // the classes to test
  127. typedef typename ClassFactoryT::entry_type EntryT;
  128. typedef typename ClassFactoryT::instream_type InputStreamT;
  129. typedef typename ClassFactoryT::outstream_type OutputStreamT;
  130. typedef typename ClassFactoryT::notifier_type NotifierT;
  131. typedef typename ClassFactoryT::iter_type IterT;
  132. typedef typename ClassFactoryT::pairiter_type PairIterT;
  133. // the entry point for the test
  134. void runTest();
  135. // create the test data
  136. void CreateTestData();
  137. TestEntry& Add(const char *name, const char *data, int len = -1);
  138. TestEntry& Add(const char *name, int len = 0, int value = EOF);
  139. // 'archive up' the test data
  140. void CreateArchive(wxOutputStream& out);
  141. void CreateArchive(wxOutputStream& out, const wxString& archiver);
  142. // perform various modifications on the archive
  143. void ModifyArchive(wxInputStream& in, wxOutputStream& out);
  144. // extract the archive and verify its contents
  145. void ExtractArchive(wxInputStream& in);
  146. void ExtractArchive(wxInputStream& in, const wxString& unarchiver);
  147. void VerifyDir(wxString& path, size_t rootlen = 0);
  148. // tests for the iterators
  149. void TestIterator(wxInputStream& in);
  150. void TestPairIterator(wxInputStream& in);
  151. void TestSmartIterator(wxInputStream& in);
  152. void TestSmartPairIterator(wxInputStream& in);
  153. // try reading two entries at the same time
  154. void ReadSimultaneous(TestInputStream& in);
  155. // overridables
  156. virtual void OnCreateArchive(OutputStreamT& WXUNUSED(arc)) { }
  157. virtual void OnSetNotifier(EntryT& entry);
  158. virtual void OnArchiveExtracted(InputStreamT& WXUNUSED(arc),
  159. int WXUNUSED(expectedTotal)) { }
  160. virtual void OnCreateEntry( OutputStreamT& WXUNUSED(arc),
  161. TestEntry& WXUNUSED(testEntry),
  162. EntryT *entry = NULL) { (void)entry; }
  163. virtual void OnEntryExtracted( EntryT& WXUNUSED(entry),
  164. const TestEntry& WXUNUSED(testEntry),
  165. InputStreamT *arc = NULL) { (void)arc; }
  166. typedef std::map<wxString, TestEntry*> TestEntries;
  167. TestEntries m_testEntries; // test data
  168. std::auto_ptr<ClassFactoryT> m_factory; // factory to make classes
  169. int m_options; // test options
  170. wxDateTime m_timeStamp; // timestamp to give test entries
  171. int m_id; // select between the possibilites
  172. wxString m_archiver; // external archiver
  173. wxString m_unarchiver; // external unarchiver
  174. };
  175. ///////////////////////////////////////////////////////////////////////////////
  176. // Make ids
  177. class TestId
  178. {
  179. public:
  180. // make a new id and return it as a string
  181. static std::string MakeId();
  182. // get the current id
  183. static int GetId() { return m_seed; }
  184. private:
  185. // seed for generating the ids
  186. static int m_seed;
  187. };
  188. ///////////////////////////////////////////////////////////////////////////////
  189. // Base class for the archive test suites
  190. class ArchiveTestSuite : public CppUnit::TestSuite
  191. {
  192. public:
  193. ArchiveTestSuite(std::string name);
  194. protected:
  195. virtual ArchiveTestSuite *makeSuite();
  196. virtual CppUnit::Test *makeTest(std::string descr,
  197. int options,
  198. bool genericInterface,
  199. const wxString& archiver,
  200. const wxString& unarchiver);
  201. void AddArchiver(const wxString& cmd) { AddCmd(m_archivers, cmd); }
  202. void AddUnArchiver(const wxString &cmd) { AddCmd(m_unarchivers, cmd); }
  203. bool IsInPath(const wxString& cmd);
  204. std::string Description(const wxString& type,
  205. int options,
  206. bool genericInterface = false,
  207. const wxString& archiver = wxEmptyString,
  208. const wxString& unarchiver = wxEmptyString);
  209. private:
  210. wxString m_name;
  211. wxPathList m_path;
  212. wxArrayString m_archivers;
  213. wxArrayString m_unarchivers;
  214. void AddCmd(wxArrayString& cmdlist, const wxString& cmd);
  215. };
  216. #endif