]> git.saurik.com Git - wxWidgets.git/blame - tests/streams/bstream.h
first round of debug/release merge: introduce wxDEBUG_LEVEL, for now defined as 1...
[wxWidgets.git] / tests / streams / bstream.h
CommitLineData
e3f810a2
VS
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"
e3f810a2
VS
14
15///////////////////////////////////////////////////////////////////////////////
08776b09 16// Some macros preventing us from typing too much ;-)
e3f810a2
VS
17//
18
19#define STREAM_TEST_NAME "Streams"
08776b09
VS
20#define COMPOSE_TEST_NAME(Name) \
21 STREAM_TEST_NAME "." #Name
e3f810a2 22#define STREAM_REGISTER_SUB_SUITE(Name) \
3e5f6c1c 23 extern CppUnit::Test* Get##Name##Suite(); \
e3f810a2
VS
24 suite->addTest(Get##Name##Suite())
25#define STREAM_IMPLEMENT_SUB_REGISTRATION_ROUTINE(Name) \
3e5f6c1c 26 CppUnit::Test* Get##Name##Suite() { return Name::suite(); }
e3f810a2 27#define STREAM_TEST_SUBSUITE_NAMED_REGISTRATION(Name) \
08776b09 28 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( Name, COMPOSE_TEST_NAME(Name) ); \
e3f810a2
VS
29 STREAM_IMPLEMENT_SUB_REGISTRATION_ROUTINE( Name )
30
68888eea
VZ
31// under 64 bit platforms wxFileOffset is the same as long and we already have
32// WX_CPPUNIT_ALLOW_EQUALS_TO_INT(long) in wx/cppunit.h
33#if SIZEOF_LONG != 8
b2eabfe8 34WX_CPPUNIT_ALLOW_EQUALS_TO_INT(wxFileOffset)
68888eea 35#endif
b2eabfe8 36
e3f810a2
VS
37///////////////////////////////////////////////////////////////////////////////
38// Template class that implements a test for all base stream functions.
39//
40
3e5f6c1c 41template <class TStreamIn, class TStreamOut> class BaseStreamTestCase : public CppUnit::TestCase
e3f810a2
VS
42{
43protected:
44 typedef BaseStreamTestCase<TStreamIn, TStreamOut> StreamTestCase;
45
46 class CleanupHelper
47 {
48 public:
49 CleanupHelper(StreamTestCase *value)
50 :m_pCleanup(value)
51 {}
52 ~CleanupHelper()
2d76b6d8 53 {
e3f810a2
VS
54 m_pCleanup->DeleteInStream();
55 m_pCleanup->DeleteOutStream();
56 }
57 private:
58 StreamTestCase *m_pCleanup;
59 };
60 friend class CleanupHelper;
61
62public:
63 BaseStreamTestCase()
64 :m_bSimpleTellITest(false),
65 m_bSimpleTellOTest(false),
08776b09 66 m_bSeekInvalidBeyondEnd(true),
7735998c 67 m_bEofAtLastRead(true),
e3f810a2
VS
68 m_pCurrentIn(NULL),
69 m_pCurrentOut(NULL)
70 { /* Nothing extra */ }
71 virtual ~BaseStreamTestCase()
72 {
73 // Prevent mem leaks!
74 delete m_pCurrentIn;
75 delete m_pCurrentOut;
2d76b6d8 76 }
e3f810a2
VS
77
78protected:
79 /*
80 * Input stream tests.
81 */
82
83 // Just try to perform a GetSize() on the input stream.
84 void Input_GetSize()
85 {
86 CleanupHelper cleanup(this);
87 const TStreamIn &stream_in = CreateInStream();
88 CPPUNIT_ASSERT(!stream_in.Eof());
89
90 // Size should be greater then zero.
91 // Note: streams not supporting this should register this test
92 // with CPPUNIT_TEST_FAIL instead of CPPUNIT_TEST.
93 CPPUNIT_ASSERT(stream_in.GetSize() != 0);
94 }
95
96 // Just try to perform a GetC() on the input stream.
97 void Input_GetC()
98 {
99 CleanupHelper cleanup(this);
100 TStreamIn &stream_in = CreateInStream();
101 CPPUNIT_ASSERT(!stream_in.Eof());
102
103 // If no exception occurs the test is successful.
104 (void)stream_in.GetC();
105 }
106
107 // Just try to perform a Read() on the input stream.
108 void Input_Read()
109 {
110 CleanupHelper cleanup(this);
111 TStreamIn &stream_in = CreateInStream();
112 CPPUNIT_ASSERT(!stream_in.Eof());
113
114 // Note: the input stream should at least be of min size +10!
115
2d76b6d8 116 char buf[10];
e3f810a2
VS
117 (void)stream_in.Read(buf, 10);
118
119 CPPUNIT_ASSERT(!stream_in.Eof());
120 CPPUNIT_ASSERT(stream_in.IsOk());
121
122 // Test the stream version aswell.
123 TStreamOut &stream_out = CreateOutStream();
124 (void)stream_in.Read(stream_out);
125
126 // The output stream should have read the input stream till the end.
127 CPPUNIT_ASSERT(stream_in.Eof());
128 }
129
2d76b6d8 130 // Test and see what happens to the EOF when we
e3f810a2
VS
131 // read after EOF was encountered.
132 void Input_Eof()
133 {
134 CleanupHelper cleanup(this);
135 TStreamIn &stream_in = CreateInStream();
136 CPPUNIT_ASSERT(!stream_in.Eof());
137 // Double check to see if Eof it self doesn't changes the Eof status.
138 CPPUNIT_ASSERT(!stream_in.Eof());
139
140 // Travel to the end of the stream.
141 while(!stream_in.Eof())
142 {
bf451723
VZ
143 CPPUNIT_ASSERT_MESSAGE( "unexpected non-EOF stream error",
144 stream_in.IsOk() );
145
e3f810a2
VS
146 // Read, we move one byte along.
147 (void)stream_in.GetC();
7735998c
VS
148#if 0
149 // EOF behaviour is different in streams, disabled (for now?)
150
151 if (m_bEofAtLastRead)
152 // EOF should only occure after the last successful get.
153 CPPUNIT_ASSERT_MESSAGE("Eof is detected too late.", !(stream_in.LastRead() != 1 && stream_in.Eof()));
154 else
155 // EOF should only occure after a failed get.
156 CPPUNIT_ASSERT_MESSAGE("Eof is detected too soon.", !(stream_in.LastRead() == 1 && stream_in.Eof()));
157#endif
e3f810a2
VS
158 }
159
7735998c 160 // Check EOF stream state.
2d76b6d8 161 CPPUNIT_ASSERT_MESSAGE("EOF is not EOF?", stream_in.Eof());
7735998c 162
e3f810a2
VS
163 // Ok we found the end, lets see if we can go past it.
164 for (size_t i = 0; i < 100; i++)
165 (void)stream_in.GetC();
166
167 // Check for EOF correctness.
168 CPPUNIT_ASSERT_MESSAGE("EOF is wrong when we read past EOF!", stream_in.Eof());
7735998c 169 CPPUNIT_ASSERT_MESSAGE("Last error is not EOF while stream_in.Eof() is true", stream_in.GetLastError() == wxSTREAM_EOF);
e3f810a2
VS
170 }
171
172 // Just try to perform a LastRead() on the input stream.
173 void Input_LastRead()
174 {
175 CleanupHelper cleanup(this);
176 TStreamIn &stream_in = CreateInStream();
177 CPPUNIT_ASSERT(!stream_in.Eof());
178
179 char buf[5];
180 (void)stream_in.Read(buf, 5);
91bde3ec 181 CPPUNIT_ASSERT_EQUAL(5, stream_in.LastRead());
e3f810a2 182 (void)stream_in.GetC();
91bde3ec 183 CPPUNIT_ASSERT_EQUAL(1, stream_in.LastRead());
e3f810a2
VS
184 }
185
2d76b6d8
VZ
186 void Input_CanRead()
187 {
188 CleanupHelper cleanup(this);
189 TStreamIn &stream_in = CreateInStream();
190
191 CPPUNIT_ASSERT( stream_in.CanRead() );
192
193 // read the entire contents
194 (void)stream_in.Read(CreateOutStream());
195
196 CPPUNIT_ASSERT( !stream_in.CanRead() );
197 }
198
e3f810a2
VS
199 // Just try to perform a SeekI() on the input stream.
200 void Input_SeekI()
201 {
202 CleanupHelper cleanup(this);
203 TStreamIn &stream_in = CreateInStream();
8bd966d3
VZ
204
205 CPPUNIT_ASSERT( stream_in.IsSeekable() );
e3f810a2
VS
206 CPPUNIT_ASSERT(!stream_in.Eof());
207
208 // Try to Seek in the stream...
209 // Note: streams not supporting this should register this test
210 // with CPPUNIT_TEST_FAIL instead of CPPUNIT_TEST.
a54b285e
VZ
211 CPPUNIT_ASSERT_EQUAL(2, stream_in.SeekI(2, wxFromStart));
212 CPPUNIT_ASSERT_EQUAL(4, stream_in.SeekI(2, wxFromCurrent));
e3f810a2 213 // Not sure the following line is correct, so test it differently.
91bde3ec 214 //CPPUNIT_ASSERT_EQUAL(stream_in.GetSize()-2, stream_in.SeekI(-2, wxFromEnd));
e3f810a2
VS
215 CPPUNIT_ASSERT(stream_in.SeekI(-2, wxFromEnd) != wxInvalidOffset);
216 // Go beyond the stream size.
08776b09 217 CPPUNIT_ASSERT((stream_in.SeekI(10, wxFromCurrent) == wxInvalidOffset) == m_bSeekInvalidBeyondEnd);
e3f810a2
VS
218 }
219
220 // Just try to perform a TellI() on the input stream.
221 void Input_TellI()
222 {
223 CleanupHelper cleanup(this);
224 TStreamIn &stream_in = CreateInStream();
8bd966d3
VZ
225
226 // this test shouldn't be used at all if the stream isn't seekable
227 CPPUNIT_ASSERT( stream_in.IsSeekable() );
228
e3f810a2
VS
229 CPPUNIT_ASSERT(!stream_in.Eof());
230
231 // Try to Get the location in the stream...
91bde3ec 232 CPPUNIT_ASSERT_EQUAL(0, stream_in.TellI());
e3f810a2 233 (void)stream_in.GetC();
91bde3ec 234 CPPUNIT_ASSERT_EQUAL(1, stream_in.TellI());
e3f810a2
VS
235 if (!m_bSimpleTellITest)
236 {
30984dea 237 wxFileOffset pos = stream_in.SeekI(5, wxFromStart);
91bde3ec 238 CPPUNIT_ASSERT_EQUAL(pos, stream_in.TellI());
e3f810a2 239 (void)stream_in.GetC();
91bde3ec 240 CPPUNIT_ASSERT_EQUAL(6, stream_in.TellI());
e3f810a2 241 pos = stream_in.SeekI(2, wxFromCurrent);
91bde3ec 242 CPPUNIT_ASSERT_EQUAL(pos, stream_in.TellI());
e3f810a2 243 pos = stream_in.SeekI(5, wxFromStart);
91bde3ec 244 CPPUNIT_ASSERT_EQUAL(pos, stream_in.TellI());
e3f810a2
VS
245 }
246 }
2d76b6d8 247
e3f810a2
VS
248 // Just try to perform a Peek() on the input stream.
249 void Input_Peek()
250 {
251 CleanupHelper cleanup(this);
252 TStreamIn &stream_in = CreateInStream();
253
254 // Test the full stream
08776b09 255 while (stream_in.IsOk())
e3f810a2 256 {
e3f810a2
VS
257 char peekChar = stream_in.Peek();
258 char getChar = stream_in.GetC();
08776b09 259 if (stream_in.LastRead() == 1)
91bde3ec 260 CPPUNIT_ASSERT_EQUAL(getChar, peekChar);
e3f810a2
VS
261 }
262 }
263
264 // Just try to perform a Ungetch() on the input stream.
265 void Input_Ungetch()
266 {
267 CleanupHelper cleanup(this);
268 TStreamIn &stream_in = CreateInStream();
269 CPPUNIT_ASSERT(!stream_in.Eof());
2d76b6d8 270
e3f810a2
VS
271 const char *ungetstr = "test";
272 size_t ungetsize = stream_in.Ungetch(ungetstr, strlen(ungetstr) + 1);
273 if (ungetsize != 0)
274 {
91bde3ec 275 CPPUNIT_ASSERT_EQUAL(strlen(ungetstr) + 1, ungetsize);
e3f810a2
VS
276 char buf[10];
277 (void)stream_in.Read(buf, ungetsize);
278 CPPUNIT_ASSERT(strcmp(buf, ungetstr) == 0);
279 }
280
281 if (stream_in.Ungetch('a'))
282 {
a54b285e 283 CPPUNIT_ASSERT_EQUAL(int('a'), stream_in.GetC());
e3f810a2
VS
284 }
285 }
286
287 /*
288 * Output stream tests.
289 */
290
291 // Just try to perform a PutC() on the output stream.
292 void Output_PutC()
293 {
294 CleanupHelper cleanup(this);
295 TStreamOut &stream_out = CreateOutStream();
296
8bd966d3
VZ
297 const char *buf = "Some text";
298 const wxFileOffset len = strlen(buf);
299 for ( int i = 0; i < len; i++ )
e3f810a2
VS
300 stream_out.PutC(buf[i]);
301
8bd966d3
VZ
302 if ( stream_out.IsSeekable() )
303 CPPUNIT_ASSERT_EQUAL(len, stream_out.TellO());
e3f810a2
VS
304 }
305
306 // Just try to perform a Write() on the output stream.
307 void Output_Write()
308 {
309 CleanupHelper cleanup(this);
310 TStreamOut &stream_out = CreateOutStream();
311
312 // Do the buffer version.
8bd966d3
VZ
313 const char *buf = "Some text";
314 const wxFileOffset len = strlen(buf);
e3f810a2 315 (void)stream_out.Write(buf, len);
8bd966d3
VZ
316 if ( stream_out.IsSeekable() )
317 CPPUNIT_ASSERT_EQUAL( len, stream_out.TellO() );
e3f810a2
VS
318
319 // Do the Stream version.
320 TStreamIn &stream_in = CreateInStream();
321 (void)stream_out.Write(stream_in);
8bd966d3
VZ
322
323 if ( stream_out.IsSeekable() )
324 CPPUNIT_ASSERT(stream_out.TellO() > len);
e3f810a2
VS
325 }
326
327 // Just try to perform a LastWrite() on the output stream.
328 void Output_LastWrite()
329 {
330 CleanupHelper cleanup(this);
331 TStreamOut &stream_out = CreateOutStream();
332
8bd966d3 333 const char *buf = "12345";
e3f810a2 334 (void)stream_out.Write(buf, 5);
91bde3ec 335 CPPUNIT_ASSERT_EQUAL(5, stream_out.LastWrite());
e3f810a2 336 (void)stream_out.PutC('1');
91bde3ec 337 CPPUNIT_ASSERT_EQUAL(1, stream_out.LastWrite());
e3f810a2
VS
338 }
339
340 // Just try to perform a SeekO() on the output stream.
341 void Output_SeekO()
342 {
343 CleanupHelper cleanup(this);
344 TStreamOut &stream_out = CreateOutStream();
2d76b6d8 345
8bd966d3
VZ
346 CPPUNIT_ASSERT( stream_out.IsSeekable() );
347
e3f810a2 348 // First put some data in the stream, so it is not empty.
8bd966d3 349 const char *buf = "1234567890";
e3f810a2
VS
350 (void)stream_out.Write(buf, 10);
351
352 // Try to Seek in the stream...
353 // Note: streams not supporting this should register this test
354 // with CPPUNIT_TEST_FAIL instead of CPPUNIT_TEST.
91bde3ec
VZ
355 CPPUNIT_ASSERT_EQUAL(2, stream_out.SeekO(2, wxFromStart));
356 CPPUNIT_ASSERT_EQUAL(4, stream_out.SeekO(2, wxFromCurrent));
e3f810a2 357 // Not sure the following line is correct, so test it differently.
91bde3ec 358 //CPPUNIT_ASSERT_EQUAL(stream_in.GetSize()-2, stream_out.SeekO(-2, wxFromEnd));
e3f810a2
VS
359 CPPUNIT_ASSERT(stream_out.SeekO(-2, wxFromEnd) != wxInvalidOffset);
360 // Go beyond the stream size.
08776b09 361 CPPUNIT_ASSERT((stream_out.SeekO(10, wxFromCurrent) == wxInvalidOffset) == m_bSeekInvalidBeyondEnd);
e3f810a2
VS
362 }
363
364 // Just try to perform a TellO() on the output stream.
365 void Output_TellO()
366 {
367 CleanupHelper cleanup(this);
368 TStreamOut &stream_out = CreateOutStream();
369
8bd966d3
VZ
370 // If this test is used, the stream must be seekable
371 CPPUNIT_ASSERT( stream_out.IsSeekable() );
372
e3f810a2 373 // Try to Get the location in the stream...
91bde3ec 374 CPPUNIT_ASSERT_EQUAL(0, stream_out.TellO());
e3f810a2 375 (void)stream_out.PutC('1');
91bde3ec 376 CPPUNIT_ASSERT_EQUAL(1, stream_out.TellO());
e3f810a2
VS
377 if (!m_bSimpleTellOTest)
378 {
379 // First put some extra data in the stream, so it's not empty.
8bd966d3 380 const char *buf = "1234567890";
e3f810a2 381 (void)stream_out.Write(buf, 10);
2d76b6d8 382
9540df9c 383 wxFileOffset pos = stream_out.SeekO(5, wxFromStart);
91bde3ec 384 CPPUNIT_ASSERT_EQUAL(pos, stream_out.TellO());
e3f810a2 385 (void)stream_out.PutC('1');
91bde3ec 386 CPPUNIT_ASSERT_EQUAL(6, stream_out.TellO());
e3f810a2 387 pos = stream_out.SeekO(2, wxFromCurrent);
91bde3ec 388 CPPUNIT_ASSERT_EQUAL(pos, stream_out.TellO());
e3f810a2 389 pos = stream_out.SeekO(5, wxFromStart);
91bde3ec 390 CPPUNIT_ASSERT_EQUAL(pos, stream_out.TellO());
e3f810a2
VS
391 }
392 }
393
394protected:
395 // Some tests can be configured... here you can find the config settings
2d76b6d8 396 bool m_bSimpleTellITest; // if true, no SeekI will be used by the TellI test.
e3f810a2 397 // Default false.
2d76b6d8 398 bool m_bSimpleTellOTest; // if true, no SeekO will be used by the TellI test.
e3f810a2 399 // Default false.
08776b09
VS
400 bool m_bSeekInvalidBeyondEnd; // if true a SeekI|O beyond the end of the stream should return wxInvalidOffset
401 // Default true.
7735998c
VS
402 bool m_bEofAtLastRead; // Does EOF occure at the moment the last byte is read or when read past the last byte.
403 // Default true.
e3f810a2
VS
404protected:
405 TStreamIn &CreateInStream()
2d76b6d8 406 {
e3f810a2
VS
407 if (m_pCurrentIn)
408 {
409 wxFAIL_MSG(_T("Error in test case, the previouse input stream needs to be delete first!"));
410 }
411
412 m_pCurrentIn = DoCreateInStream();
413 wxASSERT(m_pCurrentIn != NULL);
414 return *m_pCurrentIn;
415 }
416 TStreamOut &CreateOutStream()
2d76b6d8 417 {
e3f810a2
VS
418 if (m_pCurrentOut)
419 {
420 wxFAIL_MSG(_T("Error in test case, the previouse output stream needs to be delete first!"));
421 }
422
423 m_pCurrentOut = DoCreateOutStream();
424 wxASSERT(m_pCurrentOut != NULL);
425 return *m_pCurrentOut;
426 }
2d76b6d8 427
e3f810a2
VS
428 void DeleteInStream()
429 {
430 if (m_pCurrentIn == NULL)
431 return;
432 delete m_pCurrentIn;
433 m_pCurrentIn = NULL;
434 // Incase something extra needs to be done.
435 DoDeleteInStream();
436 }
437 void DeleteOutStream()
2d76b6d8 438 {
e3f810a2
VS
439 if (m_pCurrentOut == NULL)
440 return;
2d76b6d8 441
8f0ff178 442 CPPUNIT_ASSERT(m_pCurrentOut->Close());
2d76b6d8 443
e3f810a2
VS
444 delete m_pCurrentOut;
445 m_pCurrentOut = NULL;
446 // Incase something extra needs to be done.
447 DoDeleteOutStream();
448 }
449
450protected:
451 // Items that need to be implemented by a derived class!
452 virtual TStreamIn *DoCreateInStream() = 0;
453 virtual TStreamOut *DoCreateOutStream() = 0;
454 virtual void DoDeleteInStream() { /* Depends on the base class */ }
455 virtual void DoDeleteOutStream() { /* Depends on the base class */ }
456
457private:
458 TStreamIn *m_pCurrentIn;
459 TStreamOut *m_pCurrentOut;
460};
461
462#endif
463
464