Add wxGetFileType and IsSeekable
[wxWidgets.git] / tests / archive / archivetest.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/archive/archivetest.h
3 // Purpose: Test the archive classes
4 // Author: Mike Wetherell
5 // RCS-ID: $Id$
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
19 enum 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
32 class TestOutputStream : public wxOutputStream
33 {
34 public:
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
46 private:
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
60 class TestInputStream : public wxInputStream
61 {
62 public:
63 // ctor takes the data from the output stream, which is then empty
64 TestInputStream(TestOutputStream& out) : m_data(NULL) { SetData(out); }
65 // this ctor 'dups'
66 TestInputStream(const TestInputStream& in);
67 ~TestInputStream() { delete [] m_data; }
68
69 void Rewind();
70 wxFileOffset GetLength() const { return m_size; }
71 bool IsSeekable() const { return (m_options & PipeIn) == 0; }
72 void SetData(TestOutputStream& out);
73
74 private:
75 wxFileOffset OnSysSeek(wxFileOffset pos, wxSeekMode mode);
76 wxFileOffset OnSysTell() const;
77 size_t OnSysRead(void *buffer, size_t size);
78
79 int m_options;
80 size_t m_pos;
81 size_t m_size;
82 char *m_data;
83 };
84
85
86 ///////////////////////////////////////////////////////////////////////////////
87 // wxFFile streams for piping to/from an external program
88
89 class PFileInputStream : public wxFFileInputStream
90 {
91 public:
92 PFileInputStream(const wxString& cmd);
93 ~PFileInputStream();
94 };
95
96 class PFileOutputStream : public wxFFileOutputStream
97 {
98 public:
99 PFileOutputStream(const wxString& cmd);
100 ~PFileOutputStream();
101 };
102
103
104 ///////////////////////////////////////////////////////////////////////////////
105 // A class to hold a test entry
106
107 class TestEntry
108 {
109 public:
110 TestEntry(const wxDateTime& dt, int len, const char *data);
111 ~TestEntry() { delete [] m_data; }
112
113 wxDateTime GetDateTime() const { return m_dt; }
114 wxFileOffset GetLength() const { return m_len; }
115 size_t GetSize() const { return m_len; }
116 const char *GetData() const { return m_data; }
117 wxString GetComment() const { return m_comment; }
118 bool IsText() const { return m_isText; }
119
120 void SetComment(const wxString& comment) { m_comment = comment; }
121 void SetDateTime(const wxDateTime& dt) { m_dt = dt; }
122
123 private:
124 wxDateTime m_dt;
125 size_t m_len;
126 char *m_data;
127 wxString m_comment;
128 bool m_isText;
129 };
130
131
132 ///////////////////////////////////////////////////////////////////////////////
133 // The test case
134
135 template <class ClassFactoryT>
136 class ArchiveTestCase : public CppUnit::TestCase
137 {
138 public:
139 ArchiveTestCase(std::string name,
140 int id,
141 ClassFactoryT *factory,
142 int options,
143 const wxString& archiver = wxEmptyString,
144 const wxString& unarchiver = wxEmptyString);
145
146 ~ArchiveTestCase();
147
148 protected:
149 // the classes to test
150 typedef typename ClassFactoryT::entry_type EntryT;
151 typedef typename ClassFactoryT::instream_type InputStreamT;
152 typedef typename ClassFactoryT::outstream_type OutputStreamT;
153 typedef typename ClassFactoryT::notifier_type NotifierT;
154 typedef typename ClassFactoryT::iter_type IterT;
155 typedef typename ClassFactoryT::pairiter_type PairIterT;
156
157 // the entry point for the test
158 void runTest();
159
160 // create the test data
161 void CreateTestData();
162 TestEntry& Add(const char *name, const char *data, int len = -1);
163 TestEntry& Add(const char *name, int len = 0, int value = EOF);
164
165 // 'archive up' the test data
166 void CreateArchive(wxOutputStream& out);
167 void CreateArchive(wxOutputStream& out, const wxString& archiver);
168
169 // perform various modifications on the archive
170 void ModifyArchive(wxInputStream& in, wxOutputStream& out);
171
172 // extract the archive and verify its contents
173 void ExtractArchive(wxInputStream& in);
174 void ExtractArchive(wxInputStream& in, const wxString& unarchiver);
175 void VerifyDir(wxString& path, size_t rootlen = 0);
176
177 // tests for the iterators
178 void TestIterator(wxInputStream& in);
179 void TestPairIterator(wxInputStream& in);
180 void TestSmartIterator(wxInputStream& in);
181 void TestSmartPairIterator(wxInputStream& in);
182
183 // try reading two entries at the same time
184 void ReadSimultaneous(TestInputStream& in);
185
186 // overridables
187 virtual void OnCreateArchive(OutputStreamT& WXUNUSED(arc)) { }
188 virtual void OnSetNotifier(EntryT& entry);
189
190 virtual void OnArchiveExtracted(InputStreamT& WXUNUSED(arc),
191 int WXUNUSED(expectedTotal)) { }
192
193 virtual void OnCreateEntry( OutputStreamT& WXUNUSED(arc),
194 TestEntry& WXUNUSED(testEntry),
195 EntryT *entry = NULL) { (void)entry; }
196
197 virtual void OnEntryExtracted( EntryT& WXUNUSED(entry),
198 const TestEntry& WXUNUSED(testEntry),
199 InputStreamT *arc = NULL) { (void)arc; }
200
201 typedef std::map<wxString, TestEntry*> TestEntries;
202 TestEntries m_testEntries; // test data
203 std::auto_ptr<ClassFactoryT> m_factory; // factory to make classes
204 int m_options; // test options
205 wxDateTime m_timeStamp; // timestamp to give test entries
206 int m_id; // select between the possibilites
207 wxString m_archiver; // external archiver
208 wxString m_unarchiver; // external unarchiver
209 };
210
211
212 ///////////////////////////////////////////////////////////////////////////////
213 // Base class for the archive test suites
214
215 class ArchiveTestSuite : public CppUnit::TestSuite
216 {
217 public:
218 ArchiveTestSuite(std::string name);
219
220 protected:
221 int m_id;
222
223 virtual ArchiveTestSuite *makeSuite();
224
225 virtual CppUnit::Test *makeTest(std::string descr,
226 int id,
227 int options,
228 bool genericInterface,
229 const wxString& archiver,
230 const wxString& unarchiver);
231
232 void AddArchiver(const wxString& cmd) { AddCmd(m_archivers, cmd); }
233 void AddUnArchiver(const wxString &cmd) { AddCmd(m_unarchivers, cmd); }
234 bool IsInPath(const wxString& cmd);
235
236 std::string Description(const wxString& type,
237 int options,
238 bool genericInterface = false,
239 const wxString& archiver = wxEmptyString,
240 const wxString& unarchiver = wxEmptyString);
241
242 private:
243 wxString m_name;
244 wxPathList m_path;
245 wxArrayString m_archivers;
246 wxArrayString m_unarchivers;
247
248 void AddCmd(wxArrayString& cmdlist, const wxString& cmd);
249 };