diff options
Diffstat (limited to 'src/boost/libs/iostreams/test/execute_test.cpp')
-rw-r--r-- | src/boost/libs/iostreams/test/execute_test.cpp | 660 |
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; +} |