forgot to add header file
[wxWidgets.git] / tests / streams / bstream.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: tests/streams/bstream.h
3 // Purpose: Template class for testing base stream functions.
4 // Author: Hans Van Leemputten
5 // RCS-ID: $Id$
6 // Copyright: (c) 2004 Hans Van Leemputten
7 // Licence: wxWidgets licence
8 ///////////////////////////////////////////////////////////////////////////////
9
10 #ifndef _WX_TESTBSTREAM_H__
11 #define _WX_TESTBSTREAM_H__
12
13 #include "wx/cppunit.h"
14 using namespace CppUnit;
15
16 ///////////////////////////////////////////////////////////////////////////////
17 // Some macros preventing use from typing too much ;-)
18 //
19
20 #define STREAM_TEST_NAME "Streams"
21 #define STREAM_REGISTER_SUB_SUITE(Name) \
22 extern Test* Get##Name##Suite(); \
23 suite->addTest(Get##Name##Suite())
24 #define STREAM_IMPLEMENT_SUB_REGISTRATION_ROUTINE(Name) \
25 Test* Get##Name##Suite() { return Name::suite(); }
26 #define STREAM_TEST_SUBSUITE_NAMED_REGISTRATION(Name) \
27 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( Name, STREAM_TEST_NAME "." #Name ); \
28 STREAM_IMPLEMENT_SUB_REGISTRATION_ROUTINE( Name )
29
30
31 ///////////////////////////////////////////////////////////////////////////////
32 // Template class that implements a test for all base stream functions.
33 //
34
35 template <class TStreamIn, class TStreamOut> class BaseStreamTestCase : public TestCase
36 {
37 protected:
38 typedef BaseStreamTestCase<TStreamIn, TStreamOut> StreamTestCase;
39
40 class CleanupHelper
41 {
42 public:
43 CleanupHelper(StreamTestCase *value)
44 :m_pCleanup(value)
45 {}
46 ~CleanupHelper()
47 {
48 m_pCleanup->DeleteInStream();
49 m_pCleanup->DeleteOutStream();
50 }
51 private:
52 StreamTestCase *m_pCleanup;
53 };
54 friend class CleanupHelper;
55
56 public:
57 BaseStreamTestCase()
58 :m_bSimpleTellITest(false),
59 m_bSimpleTellOTest(false),
60 m_pCurrentIn(NULL),
61 m_pCurrentOut(NULL)
62 { /* Nothing extra */ }
63 virtual ~BaseStreamTestCase()
64 {
65 // Prevent mem leaks!
66 delete m_pCurrentIn;
67 delete m_pCurrentOut;
68 }
69
70 protected:
71 /*
72 * Input stream tests.
73 */
74
75 // Just try to perform a GetSize() on the input stream.
76 void Input_GetSize()
77 {
78 CleanupHelper cleanup(this);
79 const TStreamIn &stream_in = CreateInStream();
80 CPPUNIT_ASSERT(!stream_in.Eof());
81
82 // Size should be greater then zero.
83 // Note: streams not supporting this should register this test
84 // with CPPUNIT_TEST_FAIL instead of CPPUNIT_TEST.
85 CPPUNIT_ASSERT(stream_in.GetSize() != 0);
86 }
87
88 // Just try to perform a GetC() on the input stream.
89 void Input_GetC()
90 {
91 CleanupHelper cleanup(this);
92 TStreamIn &stream_in = CreateInStream();
93 CPPUNIT_ASSERT(!stream_in.Eof());
94
95 // If no exception occurs the test is successful.
96 (void)stream_in.GetC();
97 }
98
99 // Just try to perform a Read() on the input stream.
100 void Input_Read()
101 {
102 CleanupHelper cleanup(this);
103 TStreamIn &stream_in = CreateInStream();
104 CPPUNIT_ASSERT(!stream_in.Eof());
105
106 // Note: the input stream should at least be of min size +10!
107
108 char buf[10];
109 (void)stream_in.Read(buf, 10);
110
111 CPPUNIT_ASSERT(!stream_in.Eof());
112 CPPUNIT_ASSERT(stream_in.IsOk());
113
114 // Test the stream version aswell.
115 TStreamOut &stream_out = CreateOutStream();
116 (void)stream_in.Read(stream_out);
117
118 // The output stream should have read the input stream till the end.
119 CPPUNIT_ASSERT(stream_in.Eof());
120 }
121
122 // Test and see what happens to the EOF when we
123 // read after EOF was encountered.
124 void Input_Eof()
125 {
126 CleanupHelper cleanup(this);
127 TStreamIn &stream_in = CreateInStream();
128 CPPUNIT_ASSERT(!stream_in.Eof());
129 // Double check to see if Eof it self doesn't changes the Eof status.
130 CPPUNIT_ASSERT(!stream_in.Eof());
131
132 // Travel to the end of the stream.
133 while(!stream_in.Eof())
134 {
135 // Double check to see if normal Eof works.
136 CPPUNIT_ASSERT_MESSAGE("Eof() doesn't return true when IsOk returns false!", stream_in.IsOk());
137 // Read, we move one byte along.
138 (void)stream_in.GetC();
139 }
140
141 // Ok we found the end, lets see if we can go past it.
142 for (size_t i = 0; i < 100; i++)
143 (void)stream_in.GetC();
144
145 // Check for EOF correctness.
146 CPPUNIT_ASSERT_MESSAGE("EOF is wrong when we read past EOF!", stream_in.Eof());
147 }
148
149 // Just try to perform a LastRead() on the input stream.
150 void Input_LastRead()
151 {
152 CleanupHelper cleanup(this);
153 TStreamIn &stream_in = CreateInStream();
154 CPPUNIT_ASSERT(!stream_in.Eof());
155
156 char buf[5];
157 (void)stream_in.Read(buf, 5);
158 CPPUNIT_ASSERT(stream_in.LastRead() == 5);
159 (void)stream_in.GetC();
160 CPPUNIT_ASSERT(stream_in.LastRead() == 1);
161 }
162
163 // Just try to perform a SeekI() on the input stream.
164 void Input_SeekI()
165 {
166 CleanupHelper cleanup(this);
167 TStreamIn &stream_in = CreateInStream();
168 CPPUNIT_ASSERT(!stream_in.Eof());
169
170 // Try to Seek in the stream...
171 // Note: streams not supporting this should register this test
172 // with CPPUNIT_TEST_FAIL instead of CPPUNIT_TEST.
173 CPPUNIT_ASSERT(stream_in.SeekI(2, wxFromStart) == 2);
174 CPPUNIT_ASSERT(stream_in.SeekI(2, wxFromCurrent) == 4);
175 // Not sure the following line is correct, so test it differently.
176 //CPPUNIT_ASSERT(stream_in.SeekI(-2, wxFromEnd) == (off_t)stream_in.GetSize()-2);
177 CPPUNIT_ASSERT(stream_in.SeekI(-2, wxFromEnd) != wxInvalidOffset);
178 // Go beyond the stream size.
179 CPPUNIT_ASSERT(stream_in.SeekI(10, wxFromCurrent) == wxInvalidOffset);
180 }
181
182 // Just try to perform a TellI() on the input stream.
183 void Input_TellI()
184 {
185 CleanupHelper cleanup(this);
186 TStreamIn &stream_in = CreateInStream();
187 CPPUNIT_ASSERT(!stream_in.Eof());
188
189 // Try to Get the location in the stream...
190 CPPUNIT_ASSERT(stream_in.TellI() == 0);
191 (void)stream_in.GetC();
192 CPPUNIT_ASSERT(stream_in.TellI() == 1);
193 if (!m_bSimpleTellITest)
194 {
195 off_t pos = stream_in.SeekI(5, wxFromStart);
196 CPPUNIT_ASSERT(stream_in.TellI() == pos);
197 (void)stream_in.GetC();
198 CPPUNIT_ASSERT(stream_in.TellI() == 6);
199 pos = stream_in.SeekI(2, wxFromCurrent);
200 CPPUNIT_ASSERT(stream_in.TellI() == pos);
201 pos = stream_in.SeekI(5, wxFromStart);
202 CPPUNIT_ASSERT(stream_in.TellI() == pos);
203 }
204 }
205
206 // Just try to perform a Peek() on the input stream.
207 void Input_Peek()
208 {
209 CleanupHelper cleanup(this);
210 TStreamIn &stream_in = CreateInStream();
211
212 // Test the full stream
213 while(!stream_in.Eof())
214 {
215 if (!stream_in.IsOk())
216 break;
217
218 char peekChar = stream_in.Peek();
219 char getChar = stream_in.GetC();
220 CPPUNIT_ASSERT(peekChar == getChar);
221 }
222 }
223
224 // Just try to perform a Ungetch() on the input stream.
225 void Input_Ungetch()
226 {
227 CleanupHelper cleanup(this);
228 TStreamIn &stream_in = CreateInStream();
229 CPPUNIT_ASSERT(!stream_in.Eof());
230
231 const char *ungetstr = "test";
232 size_t ungetsize = stream_in.Ungetch(ungetstr, strlen(ungetstr) + 1);
233 if (ungetsize != 0)
234 {
235 CPPUNIT_ASSERT(ungetsize == strlen(ungetstr) + 1);
236 char buf[10];
237 (void)stream_in.Read(buf, ungetsize);
238 CPPUNIT_ASSERT(strcmp(buf, ungetstr) == 0);
239 }
240
241 if (stream_in.Ungetch('a'))
242 {
243 CPPUNIT_ASSERT(stream_in.GetC() == 'a');
244 }
245 }
246
247 /*
248 * Output stream tests.
249 */
250
251 // Just try to perform a PutC() on the output stream.
252 void Output_PutC()
253 {
254 CleanupHelper cleanup(this);
255 TStreamOut &stream_out = CreateOutStream();
256
257 char *buf = "Some text";
258 off_t i;
259 off_t len = (off_t) strlen(buf);
260 for (i = 0; i < len; i++)
261 stream_out.PutC(buf[i]);
262
263 CPPUNIT_ASSERT(i == stream_out.TellO());
264 }
265
266 // Just try to perform a Write() on the output stream.
267 void Output_Write()
268 {
269 CleanupHelper cleanup(this);
270 TStreamOut &stream_out = CreateOutStream();
271
272 // Do the buffer version.
273 char *buf = "Some text";
274 off_t len = (off_t) strlen(buf);
275 (void)stream_out.Write(buf, len);
276 CPPUNIT_ASSERT(stream_out.TellO() == len);
277
278 // Do the Stream version.
279 TStreamIn &stream_in = CreateInStream();
280 (void)stream_out.Write(stream_in);
281 CPPUNIT_ASSERT(stream_out.TellO() > len);
282 }
283
284 // Just try to perform a LastWrite() on the output stream.
285 void Output_LastWrite()
286 {
287 CleanupHelper cleanup(this);
288 TStreamOut &stream_out = CreateOutStream();
289
290 char *buf = "12345";
291 (void)stream_out.Write(buf, 5);
292 CPPUNIT_ASSERT(stream_out.LastWrite() == 5);
293 (void)stream_out.PutC('1');
294 CPPUNIT_ASSERT(stream_out.LastWrite() == 1);
295 }
296
297 // Just try to perform a SeekO() on the output stream.
298 void Output_SeekO()
299 {
300 CleanupHelper cleanup(this);
301 TStreamOut &stream_out = CreateOutStream();
302
303 // First put some data in the stream, so it is not empty.
304 char *buf = "1234567890";
305 (void)stream_out.Write(buf, 10);
306
307 // Try to Seek in the stream...
308 // Note: streams not supporting this should register this test
309 // with CPPUNIT_TEST_FAIL instead of CPPUNIT_TEST.
310 CPPUNIT_ASSERT(stream_out.SeekO(2, wxFromStart) == 2);
311 CPPUNIT_ASSERT(stream_out.SeekO(2, wxFromCurrent) == 4);
312 // Not sure the following line is correct, so test it differently.
313 //CPPUNIT_ASSERT(stream_out.SeekO(-2, wxFromEnd) == (off_t)stream_in.GetSize()-2);
314 CPPUNIT_ASSERT(stream_out.SeekO(-2, wxFromEnd) != wxInvalidOffset);
315 // Go beyond the stream size.
316 CPPUNIT_ASSERT(stream_out.SeekO(10, wxFromCurrent) == wxInvalidOffset);
317 }
318
319 // Just try to perform a TellO() on the output stream.
320 void Output_TellO()
321 {
322 CleanupHelper cleanup(this);
323 TStreamOut &stream_out = CreateOutStream();
324
325 // Try to Get the location in the stream...
326 CPPUNIT_ASSERT(stream_out.TellO() == 0);
327 (void)stream_out.PutC('1');
328 CPPUNIT_ASSERT(stream_out.TellO() == 1);
329 if (!m_bSimpleTellOTest)
330 {
331 // First put some extra data in the stream, so it's not empty.
332 char *buf = "1234567890";
333 (void)stream_out.Write(buf, 10);
334
335 off_t pos = stream_out.SeekO(5, wxFromStart);
336 CPPUNIT_ASSERT(stream_out.TellO() == pos);
337 (void)stream_out.PutC('1');
338 CPPUNIT_ASSERT(stream_out.TellO() == 6);
339 pos = stream_out.SeekO(2, wxFromCurrent);
340 CPPUNIT_ASSERT(stream_out.TellO() == pos);
341 pos = stream_out.SeekO(5, wxFromStart);
342 CPPUNIT_ASSERT(stream_out.TellO() == pos);
343 }
344 }
345
346 protected:
347 // Some tests can be configured... here you can find the config settings
348 bool m_bSimpleTellITest; // if true, no SeekI will be used by the TellI test.
349 // Default false.
350 bool m_bSimpleTellOTest; // if true, no SeekO will be used by the TellI test.
351 // Default false.
352
353 protected:
354 TStreamIn &CreateInStream()
355 {
356 if (m_pCurrentIn)
357 {
358 wxFAIL_MSG(_T("Error in test case, the previouse input stream needs to be delete first!"));
359 }
360
361 m_pCurrentIn = DoCreateInStream();
362 wxASSERT(m_pCurrentIn != NULL);
363 return *m_pCurrentIn;
364 }
365 TStreamOut &CreateOutStream()
366 {
367 if (m_pCurrentOut)
368 {
369 wxFAIL_MSG(_T("Error in test case, the previouse output stream needs to be delete first!"));
370 }
371
372 m_pCurrentOut = DoCreateOutStream();
373 wxASSERT(m_pCurrentOut != NULL);
374 return *m_pCurrentOut;
375 }
376
377 void DeleteInStream()
378 {
379 if (m_pCurrentIn == NULL)
380 return;
381 delete m_pCurrentIn;
382 m_pCurrentIn = NULL;
383 // Incase something extra needs to be done.
384 DoDeleteInStream();
385 }
386 void DeleteOutStream()
387 {
388 if (m_pCurrentOut == NULL)
389 return;
390 delete m_pCurrentOut;
391 m_pCurrentOut = NULL;
392 // Incase something extra needs to be done.
393 DoDeleteOutStream();
394 }
395
396 protected:
397 // Items that need to be implemented by a derived class!
398 virtual TStreamIn *DoCreateInStream() = 0;
399 virtual TStreamOut *DoCreateOutStream() = 0;
400 virtual void DoDeleteInStream() { /* Depends on the base class */ }
401 virtual void DoDeleteOutStream() { /* Depends on the base class */ }
402
403 private:
404 TStreamIn *m_pCurrentIn;
405 TStreamOut *m_pCurrentOut;
406 };
407
408 #endif
409
410