summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/iostreams/test/execute_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/iostreams/test/execute_test.cpp')
-rw-r--r--src/boost/libs/iostreams/test/execute_test.cpp660
1 files changed, 660 insertions, 0 deletions
diff --git a/src/boost/libs/iostreams/test/execute_test.cpp b/src/boost/libs/iostreams/test/execute_test.cpp
new file mode 100644
index 000000000..d477c6792
--- /dev/null
+++ b/src/boost/libs/iostreams/test/execute_test.cpp
@@ -0,0 +1,660 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.(See accompanying
+ * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
+ *
+ * See http://www.boost.org/libs/iostreams for documentation.
+ *
+ * Tests the function templates boost::iostreams::detail::execute_all and
+ * boost::iostreams::detail::execute_foreach
+ *
+ * File: libs/iostreams/test/execute_test.cpp
+ * Date: Thu Dec 06 13:21:54 MST 2007
+ * Copyright: 2007-2008 CodeRage, LLC
+ * Author: Jonathan Turkanis
+ * Contact: turkanis at coderage dot com
+ */
+
+#include <boost/iostreams/detail/execute.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+using namespace boost;
+using namespace boost::iostreams;
+using namespace boost::iostreams::detail;
+using boost::unit_test::test_suite;
+
+// Function object that sets a boolean flag and returns a value
+// specified at construction
+template<typename Result>
+class operation {
+public:
+ typedef Result result_type;
+ explicit operation(Result r, bool& executed)
+ : r_(r), executed_(executed)
+ { }
+ Result operator()() const
+ {
+ executed_ = true;
+ return r_;
+ }
+private:
+ operation& operator=(const operation&);
+ Result r_;
+ bool& executed_;
+};
+
+// Specialization for void return
+template<>
+class operation<void> {
+public:
+ typedef void result_type;
+ explicit operation(bool& executed) : executed_(executed) { }
+ void operator()() const { executed_ = true; }
+private:
+ operation& operator=(const operation&);
+ bool& executed_;
+};
+
+// Simple exception class with error code built in to type
+template<int Code>
+struct error { };
+
+// Function object that sets a boolean flag and throws an exception
+template<int Code>
+class thrower {
+public:
+ typedef void result_type;
+ explicit thrower(bool& executed) : executed_(executed) { }
+ void operator()() const
+ {
+ executed_ = true;
+ throw error<Code>();
+ }
+private:
+ thrower& operator=(const thrower&);
+ bool& executed_;
+};
+
+// Function object for use by foreach_test
+class foreach_func {
+public:
+ typedef void result_type;
+ explicit foreach_func(int& count) : count_(count) { }
+ void operator()(int x) const
+ {
+ ++count_;
+ switch (x) {
+ case 0: throw error<0>();
+ case 1: throw error<1>();
+ case 2: throw error<2>();
+ case 3: throw error<3>();
+ case 4: throw error<4>();
+ case 5: throw error<5>();
+ case 6: throw error<6>();
+ case 7: throw error<7>();
+ case 8: throw error<8>();
+ case 9: throw error<9>();
+ default:
+ break;
+ }
+ }
+private:
+ foreach_func& operator=(const foreach_func&);
+ int& count_; // Number of times operator() has been called
+};
+
+void success_test()
+{
+ // Test returning an int
+ {
+ bool executed = false;
+ BOOST_CHECK(execute_all(operation<int>(9, executed)) == 9);
+ BOOST_CHECK(executed);
+ }
+
+ // Test returning void
+ {
+ bool executed = false;
+ execute_all(operation<void>(executed));
+ BOOST_CHECK(executed);
+ }
+
+ // Test returning an int with one cleanup operation
+ {
+ bool executed = false, cleaned_up = false;
+ BOOST_CHECK(
+ execute_all(
+ operation<int>(9, executed),
+ operation<void>(cleaned_up)
+ ) == 9
+ );
+ BOOST_CHECK(executed && cleaned_up);
+ }
+
+ // Test returning void with one cleanup operation
+ {
+ bool executed = false, cleaned_up = false;
+ execute_all(
+ operation<void>(executed),
+ operation<void>(cleaned_up)
+ );
+ BOOST_CHECK(executed && cleaned_up);
+ }
+
+ // Test returning an int with two cleanup operations
+ {
+ bool executed = false, cleaned_up1 = false, cleaned_up2 = false;
+ BOOST_CHECK(
+ execute_all(
+ operation<int>(9, executed),
+ operation<void>(cleaned_up1),
+ operation<void>(cleaned_up2)
+ ) == 9
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2);
+ }
+
+ // Test returning void with two cleanup operations
+ {
+ bool executed = false, cleaned_up1 = false, cleaned_up2 = false;
+ execute_all(
+ operation<void>(executed),
+ operation<void>(cleaned_up1),
+ operation<void>(cleaned_up2)
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2);
+ }
+
+ // Test returning an int with three cleanup operations
+ {
+ bool executed = false, cleaned_up1 = false,
+ cleaned_up2 = false, cleaned_up3 = false;
+ BOOST_CHECK(
+ execute_all(
+ operation<int>(9, executed),
+ operation<void>(cleaned_up1),
+ operation<void>(cleaned_up2),
+ operation<void>(cleaned_up3)
+ ) == 9
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2 && cleaned_up3);
+ }
+
+ // Test returning void with three cleanup operations
+ {
+ bool executed = false, cleaned_up1 = false,
+ cleaned_up2 = false, cleaned_up3 = false;
+ execute_all(
+ operation<void>(executed),
+ operation<void>(cleaned_up1),
+ operation<void>(cleaned_up2),
+ operation<void>(cleaned_up3)
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2 && cleaned_up3);
+ }
+}
+
+void operation_throws_test()
+{
+ // Test primary operation throwing with no cleanup operations
+ {
+ bool executed = false;
+ BOOST_CHECK_THROW(
+ execute_all(thrower<0>(executed)),
+ error<0>
+ );
+ BOOST_CHECK(executed);
+ }
+
+ // Test primary operation throwing with one cleanup operation
+ {
+ bool executed = false, cleaned_up = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ thrower<0>(executed),
+ operation<void>(cleaned_up)
+ ),
+ error<0>
+ );
+ BOOST_CHECK(executed && cleaned_up);
+ }
+
+ // Test primary operation throwing with two cleanup operations
+ {
+ bool executed = false, cleaned_up1 = false, cleaned_up2 = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ thrower<0>(executed),
+ operation<void>(cleaned_up1),
+ operation<void>(cleaned_up2)
+ ),
+ error<0>
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2);
+ }
+
+ // Test primary operation throwing with three cleanup operations
+ {
+ bool executed = false, cleaned_up1 = false,
+ cleaned_up2 = false, cleaned_up3 = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ thrower<0>(executed),
+ operation<void>(cleaned_up1),
+ operation<void>(cleaned_up2),
+ operation<void>(cleaned_up3)
+ ),
+ error<0>
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2 && cleaned_up3);
+ }
+}
+
+void cleanup_throws_test()
+{
+ // Test single cleanup operation that throws
+ {
+ bool executed = false, cleaned_up = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ operation<void>(executed),
+ thrower<1>(cleaned_up)
+ ),
+ error<1>
+ );
+ BOOST_CHECK(executed && cleaned_up);
+ }
+
+ // Test fist of two cleanup operations throwing
+ {
+ bool executed = false, cleaned_up1 = false, cleaned_up2 = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ operation<void>(executed),
+ thrower<1>(cleaned_up1),
+ operation<void>(cleaned_up2)
+ ),
+ error<1>
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2);
+ }
+
+ // Test second of two cleanup operations throwing
+ {
+ bool executed = false, cleaned_up1 = false, cleaned_up2 = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ operation<void>(executed),
+ operation<void>(cleaned_up1),
+ thrower<2>(cleaned_up2)
+ ),
+ error<2>
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2);
+ }
+
+ // Test first of three cleanup operations throwing
+ {
+ bool executed = false, cleaned_up1 = false,
+ cleaned_up2 = false, cleaned_up3 = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ operation<void>(executed),
+ thrower<1>(cleaned_up1),
+ operation<void>(cleaned_up2),
+ operation<void>(cleaned_up3)
+ ),
+ error<1>
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2 && cleaned_up3);
+ }
+
+ // Test second of three cleanup operations throwing
+ {
+ bool executed = false, cleaned_up1 = false,
+ cleaned_up2 = false, cleaned_up3 = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ operation<void>(executed),
+ operation<void>(cleaned_up1),
+ thrower<2>(cleaned_up2),
+ operation<void>(cleaned_up3)
+ ),
+ error<2>
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2 && cleaned_up3);
+ }
+
+ // Test third of three cleanup operations throwing
+ {
+ bool executed = false, cleaned_up1 = false,
+ cleaned_up2 = false, cleaned_up3 = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ operation<void>(executed),
+ operation<void>(cleaned_up1),
+ operation<void>(cleaned_up2),
+ thrower<3>(cleaned_up3)
+ ),
+ error<3>
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2 && cleaned_up3);
+ }
+}
+
+void multiple_exceptions_test()
+{
+ // Test primary operation and cleanup operation throwing
+ {
+ bool executed = false, cleaned_up = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ thrower<0>(executed),
+ thrower<1>(cleaned_up)
+ ),
+ error<0>
+ );
+ BOOST_CHECK(executed && cleaned_up);
+ }
+
+ // Test primary operation and first of two cleanup operations throwing
+ {
+ bool executed = false, cleaned_up1 = false, cleaned_up2 = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ thrower<0>(executed),
+ thrower<1>(cleaned_up1),
+ operation<void>(cleaned_up2)
+ ),
+ error<0>
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2);
+ }
+
+ // Test primary operation and second of two cleanup operations throwing
+ {
+ bool executed = false, cleaned_up1 = false, cleaned_up2 = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ thrower<0>(executed),
+ operation<void>(cleaned_up1),
+ thrower<2>(cleaned_up2)
+ ),
+ error<0>
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2);
+ }
+
+ // Test two cleanup operations throwing
+ {
+ bool executed = false, cleaned_up1 = false, cleaned_up2 = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ operation<void>(executed),
+ thrower<1>(cleaned_up1),
+ thrower<2>(cleaned_up2)
+ ),
+ error<1>
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2);
+ }
+
+ // Test primary operation and first of three cleanup operations throwing
+ {
+ bool executed = false, cleaned_up1 = false,
+ cleaned_up2 = false, cleaned_up3 = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ thrower<0>(executed),
+ thrower<1>(cleaned_up1),
+ operation<void>(cleaned_up2),
+ operation<void>(cleaned_up3)
+ ),
+ error<0>
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2 && cleaned_up3);
+ }
+
+ // Test primary operation and second of three cleanup operations throwing
+ {
+ bool executed = false, cleaned_up1 = false,
+ cleaned_up2 = false, cleaned_up3 = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ thrower<0>(executed),
+ operation<void>(cleaned_up1),
+ thrower<2>(cleaned_up2),
+ operation<void>(cleaned_up3)
+ ),
+ error<0>
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2 && cleaned_up3);
+ }
+
+ // Test primary operation and third of three cleanup operations throwing
+ {
+ bool executed = false, cleaned_up1 = false,
+ cleaned_up2 = false, cleaned_up3 = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ thrower<0>(executed),
+ operation<void>(cleaned_up1),
+ operation<void>(cleaned_up2),
+ thrower<3>(cleaned_up3)
+ ),
+ error<0>
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2 && cleaned_up3);
+ }
+
+ // Test first and second of three cleanup operations throwing
+ {
+ bool executed = false, cleaned_up1 = false,
+ cleaned_up2 = false, cleaned_up3 = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ operation<void>(executed),
+ thrower<1>(cleaned_up1),
+ thrower<2>(cleaned_up2),
+ operation<void>(cleaned_up3)
+ ),
+ error<1>
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2 && cleaned_up3);
+ }
+
+ // Test first and third of three cleanup operations throwing
+ {
+ bool executed = false, cleaned_up1 = false,
+ cleaned_up2 = false, cleaned_up3 = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ operation<void>(executed),
+ thrower<1>(cleaned_up1),
+ operation<void>(cleaned_up2),
+ thrower<3>(cleaned_up3)
+ ),
+ error<1>
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2 && cleaned_up3);
+ }
+
+ // Test second and third of three cleanup operations throwing
+ {
+ bool executed = false, cleaned_up1 = false,
+ cleaned_up2 = false, cleaned_up3 = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ operation<void>(executed),
+ operation<void>(cleaned_up1),
+ thrower<2>(cleaned_up2),
+ thrower<3>(cleaned_up3)
+ ),
+ error<2>
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2 && cleaned_up3);
+ }
+
+ // Test three cleanup operations throwing
+ {
+ bool executed = false, cleaned_up1 = false,
+ cleaned_up2 = false, cleaned_up3 = false;
+ BOOST_CHECK_THROW(
+ execute_all(
+ operation<void>(executed),
+ thrower<1>(cleaned_up1),
+ thrower<2>(cleaned_up2),
+ thrower<3>(cleaned_up3)
+ ),
+ error<1>
+ );
+ BOOST_CHECK(executed && cleaned_up1 && cleaned_up2 && cleaned_up3);
+ }
+}
+
+#define ARRAY_SIZE(ar) (sizeof(ar) / sizeof(ar[0]))
+
+void foreach_test()
+{
+ // Test case where neither of two operations throws
+ {
+ int count = 0;
+ int seq[] = {-1, -1};
+ BOOST_CHECK_NO_THROW(
+ execute_foreach(seq, seq + ARRAY_SIZE(seq), foreach_func(count))
+ );
+ BOOST_CHECK(count == ARRAY_SIZE(seq));
+ }
+
+ // Test case where first of two operations throws
+ {
+ int count = 0;
+ int seq[] = {0, -1};
+ BOOST_CHECK_THROW(
+ execute_foreach(seq, seq + ARRAY_SIZE(seq), foreach_func(count)),
+ error<0>
+ );
+ BOOST_CHECK(count == ARRAY_SIZE(seq));
+ }
+
+ // Test case where second of two operations throws
+ {
+ int count = 0;
+ int seq[] = {-1, 1};
+ BOOST_CHECK_THROW(
+ execute_foreach(seq, seq + ARRAY_SIZE(seq), foreach_func(count)),
+ error<1>
+ );
+ BOOST_CHECK(count == ARRAY_SIZE(seq));
+ }
+
+ // Test case where both of two operations throw
+ {
+ int count = 0;
+ int seq[] = {0, 1};
+ BOOST_CHECK_THROW(
+ execute_foreach(seq, seq + ARRAY_SIZE(seq), foreach_func(count)),
+ error<0>
+ );
+ BOOST_CHECK(count == ARRAY_SIZE(seq));
+ }
+
+ // Test case where none of three operations throws
+ {
+ int count = 0;
+ int seq[] = {-1, -1, -1};
+ BOOST_CHECK_NO_THROW(
+ execute_foreach(seq, seq + ARRAY_SIZE(seq), foreach_func(count))
+ );
+ BOOST_CHECK(count == ARRAY_SIZE(seq));
+ }
+
+ // Test case where first of three operations throw
+ {
+ int count = 0;
+ int seq[] = {0, -1, -1};
+ BOOST_CHECK_THROW(
+ execute_foreach(seq, seq + ARRAY_SIZE(seq), foreach_func(count)),
+ error<0>
+ );
+ BOOST_CHECK(count == ARRAY_SIZE(seq));
+ }
+
+ // Test case where second of three operations throw
+ {
+ int count = 0;
+ int seq[] = {-1, 1, -1};
+ BOOST_CHECK_THROW(
+ execute_foreach(seq, seq + ARRAY_SIZE(seq), foreach_func(count)),
+ error<1>
+ );
+ BOOST_CHECK(count == ARRAY_SIZE(seq));
+ }
+
+ // Test case where third of three operations throw
+ {
+ int count = 0;
+ int seq[] = {-1, -1, 2};
+ BOOST_CHECK_THROW(
+ execute_foreach(seq, seq + ARRAY_SIZE(seq), foreach_func(count)),
+ error<2>
+ );
+ BOOST_CHECK(count == ARRAY_SIZE(seq));
+ }
+
+ // Test case where first and second of three operations throw
+ {
+ int count = 0;
+ int seq[] = {0, 1, -1};
+ BOOST_CHECK_THROW(
+ execute_foreach(seq, seq + ARRAY_SIZE(seq), foreach_func(count)),
+ error<0>
+ );
+ BOOST_CHECK(count == ARRAY_SIZE(seq));
+ }
+
+ // Test case where first and third of three operations throw
+ {
+ int count = 0;
+ int seq[] = {0, -1, 2};
+ BOOST_CHECK_THROW(
+ execute_foreach(seq, seq + ARRAY_SIZE(seq), foreach_func(count)),
+ error<0>
+ );
+ BOOST_CHECK(count == ARRAY_SIZE(seq));
+ }
+
+ // Test case where second and third of three operations throw
+ {
+ int count = 0;
+ int seq[] = {-1, 1, 2};
+ BOOST_CHECK_THROW(
+ execute_foreach(seq, seq + ARRAY_SIZE(seq), foreach_func(count)),
+ error<1>
+ );
+ BOOST_CHECK(count == ARRAY_SIZE(seq));
+ }
+
+ // Test case where three of three operations throw
+ {
+ int count = 0;
+ int seq[] = {0, 1, 2};
+ BOOST_CHECK_THROW(
+ execute_foreach(seq, seq + ARRAY_SIZE(seq), foreach_func(count)),
+ error<0>
+ );
+ BOOST_CHECK(count == ARRAY_SIZE(seq));
+ }
+}
+
+test_suite* init_unit_test_suite(int, char* [])
+{
+ test_suite* test = BOOST_TEST_SUITE("execute test");
+ test->add(BOOST_TEST_CASE(&success_test));
+ test->add(BOOST_TEST_CASE(&operation_throws_test));
+ test->add(BOOST_TEST_CASE(&cleanup_throws_test));
+ test->add(BOOST_TEST_CASE(&multiple_exceptions_test));
+ test->add(BOOST_TEST_CASE(&foreach_test));
+ return test;
+}