123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660 |
- /*
- * 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;
- }
|