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