]>
git.saurik.com Git - wxWidgets.git/blob - 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
6 // Copyright: (c) 2004 Hans Van Leemputten
7 // Licence: wxWidgets licence
8 ///////////////////////////////////////////////////////////////////////////////
10 #ifndef _WX_TESTBSTREAM_H__
11 #define _WX_TESTBSTREAM_H__
13 #include "wx/cppunit.h"
15 ///////////////////////////////////////////////////////////////////////////////
16 // Some macros preventing us from typing too much ;-)
19 #define STREAM_TEST_NAME "Streams"
20 #define COMPOSE_TEST_NAME(Name) \
21 STREAM_TEST_NAME "." #Name
22 #define STREAM_REGISTER_SUB_SUITE(Name) \
23 extern CppUnit::Test* Get##Name##Suite(); \
24 suite->addTest(Get##Name##Suite())
25 #define STREAM_IMPLEMENT_SUB_REGISTRATION_ROUTINE(Name) \
26 CppUnit::Test* Get##Name##Suite() { return Name::suite(); }
27 #define STREAM_TEST_SUBSUITE_NAMED_REGISTRATION(Name) \
28 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( Name, COMPOSE_TEST_NAME(Name) ); \
29 STREAM_IMPLEMENT_SUB_REGISTRATION_ROUTINE( Name )
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
34 WX_CPPUNIT_ALLOW_EQUALS_TO_INT(wxFileOffset
)
37 ///////////////////////////////////////////////////////////////////////////////
38 // Template class that implements a test for all base stream functions.
41 template <class TStreamIn
, class TStreamOut
> class BaseStreamTestCase
: public CppUnit::TestCase
44 typedef BaseStreamTestCase
<TStreamIn
, TStreamOut
> StreamTestCase
;
49 CleanupHelper(StreamTestCase
*value
)
54 m_pCleanup
->DeleteInStream();
55 m_pCleanup
->DeleteOutStream();
58 StreamTestCase
*m_pCleanup
;
60 friend class CleanupHelper
;
64 :m_bSimpleTellITest(false),
65 m_bSimpleTellOTest(false),
66 m_bSeekInvalidBeyondEnd(true),
67 m_bEofAtLastRead(true),
70 { /* Nothing extra */ }
71 virtual ~BaseStreamTestCase()
83 // Just try to perform a GetSize() on the input stream.
86 CleanupHelper
cleanup(this);
87 const TStreamIn
&stream_in
= CreateInStream();
88 CPPUNIT_ASSERT(!stream_in
.Eof());
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);
96 // Just try to perform a GetC() on the input stream.
99 CleanupHelper
cleanup(this);
100 TStreamIn
&stream_in
= CreateInStream();
101 CPPUNIT_ASSERT(!stream_in
.Eof());
103 // If no exception occurs the test is successful.
104 (void)stream_in
.GetC();
107 // Just try to perform a Read() on the input stream.
110 CleanupHelper
cleanup(this);
111 TStreamIn
&stream_in
= CreateInStream();
112 CPPUNIT_ASSERT(!stream_in
.Eof());
114 // Note: the input stream should at least be of min size +10!
117 (void)stream_in
.Read(buf
, 10);
119 CPPUNIT_ASSERT(!stream_in
.Eof());
120 CPPUNIT_ASSERT(stream_in
.IsOk());
122 // Test the stream version aswell.
123 TStreamOut
&stream_out
= CreateOutStream();
124 (void)stream_in
.Read(stream_out
);
126 // The output stream should have read the input stream till the end.
127 CPPUNIT_ASSERT(stream_in
.Eof());
130 // Test and see what happens to the EOF when we
131 // read after EOF was encountered.
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());
140 // Travel to the end of the stream.
141 while(!stream_in
.Eof())
143 CPPUNIT_ASSERT_MESSAGE( "unexpected non-EOF stream error",
146 // Read, we move one byte along.
147 (void)stream_in
.GetC();
149 // EOF behaviour is different in streams, disabled (for now?)
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()));
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()));
160 // Check EOF stream state.
161 CPPUNIT_ASSERT_MESSAGE("EOF is not EOF?", stream_in
.Eof());
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();
167 // Check for EOF correctness.
168 CPPUNIT_ASSERT_MESSAGE("EOF is wrong when we read past EOF!", stream_in
.Eof());
169 CPPUNIT_ASSERT_MESSAGE("Last error is not EOF while stream_in.Eof() is true", stream_in
.GetLastError() == wxSTREAM_EOF
);
172 // Just try to perform a LastRead() on the input stream.
173 void Input_LastRead()
175 CleanupHelper
cleanup(this);
176 TStreamIn
&stream_in
= CreateInStream();
177 CPPUNIT_ASSERT(!stream_in
.Eof());
180 (void)stream_in
.Read(buf
, 5);
181 CPPUNIT_ASSERT_EQUAL(5, stream_in
.LastRead());
182 (void)stream_in
.GetC();
183 CPPUNIT_ASSERT_EQUAL(1, stream_in
.LastRead());
188 CleanupHelper
cleanup(this);
189 TStreamIn
&stream_in
= CreateInStream();
191 CPPUNIT_ASSERT( stream_in
.CanRead() );
193 // read the entire contents
194 (void)stream_in
.Read(CreateOutStream());
196 CPPUNIT_ASSERT( !stream_in
.CanRead() );
199 // Just try to perform a SeekI() on the input stream.
202 CleanupHelper
cleanup(this);
203 TStreamIn
&stream_in
= CreateInStream();
205 CPPUNIT_ASSERT( stream_in
.IsSeekable() );
206 CPPUNIT_ASSERT(!stream_in
.Eof());
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.
211 CPPUNIT_ASSERT_EQUAL(2, stream_in
.SeekI(2, wxFromStart
));
212 CPPUNIT_ASSERT_EQUAL(4, stream_in
.SeekI(2, wxFromCurrent
));
213 // Not sure the following line is correct, so test it differently.
214 //CPPUNIT_ASSERT_EQUAL(stream_in.GetSize()-2, stream_in.SeekI(-2, wxFromEnd));
215 CPPUNIT_ASSERT(stream_in
.SeekI(-2, wxFromEnd
) != wxInvalidOffset
);
216 // Go beyond the stream size.
217 CPPUNIT_ASSERT((stream_in
.SeekI(10, wxFromCurrent
) == wxInvalidOffset
) == m_bSeekInvalidBeyondEnd
);
220 // Just try to perform a TellI() on the input stream.
223 CleanupHelper
cleanup(this);
224 TStreamIn
&stream_in
= CreateInStream();
226 // this test shouldn't be used at all if the stream isn't seekable
227 CPPUNIT_ASSERT( stream_in
.IsSeekable() );
229 CPPUNIT_ASSERT(!stream_in
.Eof());
231 // Try to Get the location in the stream...
232 CPPUNIT_ASSERT_EQUAL(0, stream_in
.TellI());
233 (void)stream_in
.GetC();
234 CPPUNIT_ASSERT_EQUAL(1, stream_in
.TellI());
235 if (!m_bSimpleTellITest
)
237 wxFileOffset pos
= stream_in
.SeekI(5, wxFromStart
);
238 CPPUNIT_ASSERT_EQUAL(pos
, stream_in
.TellI());
239 (void)stream_in
.GetC();
240 CPPUNIT_ASSERT_EQUAL(6, stream_in
.TellI());
241 pos
= stream_in
.SeekI(2, wxFromCurrent
);
242 CPPUNIT_ASSERT_EQUAL(pos
, stream_in
.TellI());
243 pos
= stream_in
.SeekI(5, wxFromStart
);
244 CPPUNIT_ASSERT_EQUAL(pos
, stream_in
.TellI());
248 // Just try to perform a Peek() on the input stream.
251 CleanupHelper
cleanup(this);
252 TStreamIn
&stream_in
= CreateInStream();
254 // Test the full stream
255 while (stream_in
.IsOk())
257 char peekChar
= stream_in
.Peek();
258 char getChar
= stream_in
.GetC();
259 if (stream_in
.LastRead() == 1)
260 CPPUNIT_ASSERT_EQUAL(getChar
, peekChar
);
264 // Just try to perform a Ungetch() on the input stream.
267 CleanupHelper
cleanup(this);
268 TStreamIn
&stream_in
= CreateInStream();
269 CPPUNIT_ASSERT(!stream_in
.Eof());
271 const char *ungetstr
= "test";
272 size_t ungetsize
= stream_in
.Ungetch(ungetstr
, strlen(ungetstr
) + 1);
275 CPPUNIT_ASSERT_EQUAL(strlen(ungetstr
) + 1, ungetsize
);
277 (void)stream_in
.Read(buf
, ungetsize
);
278 CPPUNIT_ASSERT(strcmp(buf
, ungetstr
) == 0);
281 if (stream_in
.Ungetch('a'))
283 CPPUNIT_ASSERT_EQUAL(int('a'), stream_in
.GetC());
288 * Output stream tests.
291 // Just try to perform a PutC() on the output stream.
294 CleanupHelper
cleanup(this);
295 TStreamOut
&stream_out
= CreateOutStream();
297 const char *buf
= "Some text";
298 const wxFileOffset len
= strlen(buf
);
299 for ( int i
= 0; i
< len
; i
++ )
300 stream_out
.PutC(buf
[i
]);
302 if ( stream_out
.IsSeekable() )
303 CPPUNIT_ASSERT_EQUAL(len
, stream_out
.TellO());
306 // Just try to perform a Write() on the output stream.
309 CleanupHelper
cleanup(this);
310 TStreamOut
&stream_out
= CreateOutStream();
312 // Do the buffer version.
313 const char *buf
= "Some text";
314 const wxFileOffset len
= strlen(buf
);
315 (void)stream_out
.Write(buf
, len
);
316 if ( stream_out
.IsSeekable() )
317 CPPUNIT_ASSERT_EQUAL( len
, stream_out
.TellO() );
319 // Do the Stream version.
320 TStreamIn
&stream_in
= CreateInStream();
321 (void)stream_out
.Write(stream_in
);
323 if ( stream_out
.IsSeekable() )
324 CPPUNIT_ASSERT(stream_out
.TellO() > len
);
327 // Just try to perform a LastWrite() on the output stream.
328 void Output_LastWrite()
330 CleanupHelper
cleanup(this);
331 TStreamOut
&stream_out
= CreateOutStream();
333 const char *buf
= "12345";
334 (void)stream_out
.Write(buf
, 5);
335 CPPUNIT_ASSERT_EQUAL(5, stream_out
.LastWrite());
336 (void)stream_out
.PutC('1');
337 CPPUNIT_ASSERT_EQUAL(1, stream_out
.LastWrite());
340 // Just try to perform a SeekO() on the output stream.
343 CleanupHelper
cleanup(this);
344 TStreamOut
&stream_out
= CreateOutStream();
346 CPPUNIT_ASSERT( stream_out
.IsSeekable() );
348 // First put some data in the stream, so it is not empty.
349 const char *buf
= "1234567890";
350 (void)stream_out
.Write(buf
, 10);
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.
355 CPPUNIT_ASSERT_EQUAL(2, stream_out
.SeekO(2, wxFromStart
));
356 CPPUNIT_ASSERT_EQUAL(4, stream_out
.SeekO(2, wxFromCurrent
));
357 // Not sure the following line is correct, so test it differently.
358 //CPPUNIT_ASSERT_EQUAL(stream_in.GetSize()-2, stream_out.SeekO(-2, wxFromEnd));
359 CPPUNIT_ASSERT(stream_out
.SeekO(-2, wxFromEnd
) != wxInvalidOffset
);
360 // Go beyond the stream size.
361 CPPUNIT_ASSERT((stream_out
.SeekO(10, wxFromCurrent
) == wxInvalidOffset
) == m_bSeekInvalidBeyondEnd
);
364 // Just try to perform a TellO() on the output stream.
367 CleanupHelper
cleanup(this);
368 TStreamOut
&stream_out
= CreateOutStream();
370 // If this test is used, the stream must be seekable
371 CPPUNIT_ASSERT( stream_out
.IsSeekable() );
373 // Try to Get the location in the stream...
374 CPPUNIT_ASSERT_EQUAL(0, stream_out
.TellO());
375 (void)stream_out
.PutC('1');
376 CPPUNIT_ASSERT_EQUAL(1, stream_out
.TellO());
377 if (!m_bSimpleTellOTest
)
379 // First put some extra data in the stream, so it's not empty.
380 const char *buf
= "1234567890";
381 (void)stream_out
.Write(buf
, 10);
383 wxFileOffset pos
= stream_out
.SeekO(5, wxFromStart
);
384 CPPUNIT_ASSERT_EQUAL(pos
, stream_out
.TellO());
385 (void)stream_out
.PutC('1');
386 CPPUNIT_ASSERT_EQUAL(6, stream_out
.TellO());
387 pos
= stream_out
.SeekO(2, wxFromCurrent
);
388 CPPUNIT_ASSERT_EQUAL(pos
, stream_out
.TellO());
389 pos
= stream_out
.SeekO(5, wxFromStart
);
390 CPPUNIT_ASSERT_EQUAL(pos
, stream_out
.TellO());
395 // Some tests can be configured... here you can find the config settings
396 bool m_bSimpleTellITest
; // if true, no SeekI will be used by the TellI test.
398 bool m_bSimpleTellOTest
; // if true, no SeekO will be used by the TellI test.
400 bool m_bSeekInvalidBeyondEnd
; // if true a SeekI|O beyond the end of the stream should return wxInvalidOffset
402 bool m_bEofAtLastRead
; // Does EOF occure at the moment the last byte is read or when read past the last byte.
405 TStreamIn
&CreateInStream()
409 wxFAIL_MSG(_T("Error in test case, the previouse input stream needs to be delete first!"));
412 m_pCurrentIn
= DoCreateInStream();
413 wxASSERT(m_pCurrentIn
!= NULL
);
414 return *m_pCurrentIn
;
416 TStreamOut
&CreateOutStream()
420 wxFAIL_MSG(_T("Error in test case, the previouse output stream needs to be delete first!"));
423 m_pCurrentOut
= DoCreateOutStream();
424 wxASSERT(m_pCurrentOut
!= NULL
);
425 return *m_pCurrentOut
;
428 void DeleteInStream()
430 if (m_pCurrentIn
== NULL
)
434 // Incase something extra needs to be done.
437 void DeleteOutStream()
439 if (m_pCurrentOut
== NULL
)
442 CPPUNIT_ASSERT(m_pCurrentOut
->Close());
444 delete m_pCurrentOut
;
445 m_pCurrentOut
= NULL
;
446 // Incase something extra needs to be done.
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 */ }
458 TStreamIn
*m_pCurrentIn
;
459 TStreamOut
*m_pCurrentOut
;