Boost logo

Boost-Commit :

From: Frank.Birbacher_at_[hidden]
Date: 2007-08-28 19:18:41


Author: birbacher
Date: 2007-08-28 19:18:41 EDT (Tue, 28 Aug 2007)
New Revision: 39046
URL: http://svn.boost.org/trac/boost/changeset/39046

Log:
extended test for more error checking on iostreams::stream
Text files modified:
   sandbox-branches/birbacher/fix_iostreams/libs/iostreams/test/error_test.cpp | 130 ++++++++++++++++++++++++++++-----------
   1 files changed, 94 insertions(+), 36 deletions(-)

Modified: sandbox-branches/birbacher/fix_iostreams/libs/iostreams/test/error_test.cpp
==============================================================================
--- sandbox-branches/birbacher/fix_iostreams/libs/iostreams/test/error_test.cpp (original)
+++ sandbox-branches/birbacher/fix_iostreams/libs/iostreams/test/error_test.cpp 2007-08-28 19:18:41 EDT (Tue, 28 Aug 2007)
@@ -15,6 +15,22 @@
 namespace bio = boost::iostreams;
 using boost::unit_test::test_suite;
 
+/* This test unit uses a custom device to trigger errors. The device supports
+ * input, output, and seek according to the SeekableDevice concept. And each
+ * of the required functions throw a special detail::bad_xxx exception. This
+ * should trigger the iostreams::stream to set the badbit status flag.
+ * Additionally the exception can be propagated to the caller if the exception
+ * mask of the stream allows exceptions.
+ *
+ * The stream offers four different functions: read, write, seekg, and seekp.
+ * Each of them is tested with three different error reporting concepts:
+ * test by reading status flags, test by propagated exception, and test by
+ * calling std::ios_base::exceptions when badbit is already set.
+ *
+ * In each case all of the status checking functions of a stream are checked.
+ */
+
+// error device ***************************************************************
 struct error_device
 {
     typedef char char_type;
@@ -25,7 +41,6 @@
     std::streamsize read(char_type* s, std::streamsize n);
     std::streamsize write(const char_type* s, std::streamsize n);
     std::streampos seek(bio::stream_offset off, BOOST_IOS::seekdir way);
-
 };
 
 std::streamsize error_device::read(char_type*, std::streamsize)
@@ -43,57 +58,100 @@
     throw bio::detail::bad_seek();
 }
 
+// helping definitions ********************************************************
 typedef bio::stream<error_device> test_stream;
 
-void test_read()
+void check_stream_for_badbit(std::iostream& stream)
 {
- test_stream stream("foo");
- char data[10];
- try{
- stream.read(data, 10);
- BOOST_CHECK_MESSAGE(stream.fail(), "stream did not fail");
- }catch(...){
- BOOST_CHECK(false);
- }
+ BOOST_CHECK_MESSAGE(!stream.good(), "stream still good");
+ BOOST_CHECK_MESSAGE(!stream.eof(), "eofbit set but not expected");
+ BOOST_CHECK_MESSAGE(stream.bad(), "stream did not set badbit");
+ BOOST_CHECK_MESSAGE(stream.fail(), "stream did not fail");
+ BOOST_CHECK_MESSAGE(stream.operator ! (),
+ "stream does not report failure by operator !");
+ BOOST_CHECK_MESSAGE(0 == stream.operator void* (),
+ "stream does not report failure by operator void*");
 }
-void test_write()
+
+// error checking concepts ****************************************************
+template<void (*const function)(std::iostream&)>
+void wrap_nothrow()
 {
     test_stream stream("foo");
- char data[10] = {0};
- try{
- stream.write(data, 10);
- BOOST_CHECK_MESSAGE(stream.fail(), "stream did not fail");
- }catch(...){
- BOOST_CHECK(false);
- }
+ BOOST_CHECK_NO_THROW( function(stream) );
+ check_stream_for_badbit(stream);
 }
-void test_seekg()
+
+template<void (*const function)(std::iostream&)>
+void wrap_throw()
 {
+ typedef std::ios_base ios;
     test_stream stream("foo");
- try{
- stream.seekg(10);
- BOOST_CHECK_MESSAGE(stream.fail(), "stream did not fail");
- }catch(...){
- BOOST_CHECK(false);
- }
+
+ stream.exceptions(ios::failbit | ios::badbit);
+ BOOST_CHECK_THROW( function(stream), std::exception );
+
+ check_stream_for_badbit(stream);
 }
-void test_seekp()
+
+template<void (*const function)(std::iostream&)>
+void wrap_throw_delayed()
 {
+ typedef std::ios_base ios;
     test_stream stream("foo");
- try{
- stream.seekp(10);
- BOOST_CHECK_MESSAGE(stream.fail(), "stream did not fail");
- }catch(...){
- BOOST_CHECK(false);
- }
+
+ function(stream);
+ BOOST_CHECK_THROW(
+ stream.exceptions(ios::failbit | ios::badbit),
+ ios::failure
+ );
+
+ check_stream_for_badbit(stream);
+}
+
+// error raising **************************************************************
+void test_read(std::iostream& stream)
+{
+ char data[10];
+ stream.read(data, 10);
 }
 
+void test_write(std::iostream& stream)
+{
+ char data[10] = {0};
+ stream.write(data, 10);
+}
+
+void test_seekg(std::iostream& stream)
+{
+ stream.seekg(10);
+}
+
+void test_seekp(std::iostream& stream)
+{
+ stream.seekp(10);
+}
+
+// test registration function *************************************************
 test_suite* init_unit_test_suite(int, char* [])
 {
     test_suite* test = BOOST_TEST_SUITE("error test");
- test->add(BOOST_TEST_CASE(&test_read));
- test->add(BOOST_TEST_CASE(&test_write));
- test->add(BOOST_TEST_CASE(&test_seekg));
- test->add(BOOST_TEST_CASE(&test_seekp));
+
+ test->add(BOOST_TEST_CASE(&wrap_nothrow <&test_read>));
+ test->add(BOOST_TEST_CASE(&wrap_throw <&test_read>));
+ test->add(BOOST_TEST_CASE(&wrap_throw_delayed<&test_read>));
+
+ test->add(BOOST_TEST_CASE(&wrap_nothrow <&test_write>));
+ test->add(BOOST_TEST_CASE(&wrap_throw <&test_write>));
+ test->add(BOOST_TEST_CASE(&wrap_throw_delayed<&test_write>));
+
+ test->add(BOOST_TEST_CASE(&wrap_nothrow <&test_seekg>));
+ test->add(BOOST_TEST_CASE(&wrap_throw <&test_seekg>));
+ test->add(BOOST_TEST_CASE(&wrap_throw_delayed<&test_seekg>));
+
+ test->add(BOOST_TEST_CASE(&wrap_nothrow <&test_seekp>));
+ test->add(BOOST_TEST_CASE(&wrap_throw <&test_seekp>));
+ test->add(BOOST_TEST_CASE(&wrap_throw_delayed<&test_seekp>));
+
     return test;
 }


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk