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