#define BOOST_TEST_DYN_LINK #define BOOST_TEST_MAIN // in only one cpp file #include #include "core/small_obj.hpp" #include "core/tristate_obj.hpp" #include "third_party/bitops.hpp" using namespace sophiar; BOOST_AUTO_TEST_CASE(test_small_obj) { struct test_obj : public small_obj { explicit test_obj(int &_p) : probe(_p) { probe = 1; } ~test_obj() { probe = 2; } int &probe; }; int my_probe = 0; { auto obj = test_obj::new_instance(my_probe); BOOST_TEST(my_probe == 1); } BOOST_TEST(my_probe == 2); my_probe = 0; { test_obj::pointer obj_2; { auto obj = test_obj::new_instance(my_probe); obj_2 = obj; BOOST_TEST(my_probe == 1); BOOST_TEST(obj_2->ref_count == 2); } BOOST_TEST(my_probe == 1); BOOST_TEST(obj_2->ref_count == 1); } BOOST_TEST(my_probe == 2); } BOOST_AUTO_TEST_CASE(test_tristate_obj) { struct test_type : public tristate_obj { bool on_init() { probe = std::setbit(probe, 0); return true; }; bool on_start() { probe = std::setbit(probe, 1); return true; }; void on_stop() { probe = std::setbit(probe, 2); }; void on_reset() { probe = std::setbit(probe, 3); }; explicit test_type(int &_p) : probe(_p) {} int &probe; }; int probe = 0; test_type test_obj(probe); BOOST_TEST(test_obj.state == ST_INITIAL); test_obj.init(); BOOST_TEST(test_obj.state == ST_PENDING); BOOST_TEST(std::testbit(probe, 0)); test_obj.start(); BOOST_TEST(test_obj.state == ST_RUNNING); BOOST_TEST(std::testbit(probe, 1)); test_obj.stop(); BOOST_TEST(test_obj.state == ST_PENDING); BOOST_TEST(std::testbit(probe, 2)); test_obj.reset(); BOOST_TEST(test_obj.state == ST_INITIAL); BOOST_TEST(std::testbit(probe, 3)); probe = 0; test_obj.init(); test_obj.start(); test_obj.reset(); BOOST_TEST(test_obj.state == ST_INITIAL); BOOST_TEST(std::popcount(probe) == 4); struct test_type_2 : public tristate_obj { void after_init() { probe = std::setbit(probe, 0); } void after_start() { probe = std::setbit(probe, 1); } void after_stop() { probe = std::setbit(probe, 2); } void after_reset() { probe = std::setbit(probe, 3); } explicit test_type_2(int &_p) : probe(_p) {} int &probe; }; probe = 0; test_type_2 obj_2(probe); obj_2.init(); BOOST_TEST(std::testbit(probe, 0)); obj_2.start(); BOOST_TEST(std::testbit(probe, 1)); obj_2.stop(); BOOST_TEST(std::testbit(probe, 2)); obj_2.reset(); BOOST_TEST(std::testbit(probe, 3)); struct test_type_3 : public tristate_obj { void after_state_change(state_type old_state) { switch (old_state) { case ST_INITIAL: probe = std::setbit(probe, 0); break; case ST_PENDING: probe = std::setbit(probe, 1); break; case ST_RUNNING: probe = std::setbit(probe, 2); break; default: return; } } explicit test_type_3(int &_p) : probe(_p) {} int &probe; }; probe = 0; test_type_3 obj_3(probe); obj_3.init(); BOOST_TEST(std::testbit(probe, 0)); obj_3.start(); BOOST_TEST(std::testbit(probe, 1)); obj_3.stop(); BOOST_TEST(std::testbit(probe, 2)); probe = 0; obj_3.reset(); BOOST_TEST(std::testbit(probe, 1)); struct test_type_4 : public tristate_obj { auto on_init() { return boost::indeterminate; } auto on_start() { return boost::indeterminate; } void _init_finished(bool flag) { init_finished(flag); } void _start_finished(bool flag) { start_finished(flag); } void after_init() { probe = std::setbit(probe, 0); } void after_start() { probe = std::setbit(probe, 1); } explicit test_type_4(int &_p) : probe(_p) {} int &probe; }; probe = 0; test_type_4 obj_4(probe); obj_4.init(); BOOST_TEST(obj_4.state == ST_INITIALIZING); BOOST_TEST(!std::testbit(probe, 0)); obj_4._init_finished(false); BOOST_TEST(obj_4.state == ST_INITIAL); BOOST_TEST(!std::testbit(probe, 0)); obj_4.init(); obj_4._init_finished(true); BOOST_TEST(obj_4.state == ST_PENDING); BOOST_TEST(std::testbit(probe, 0)); obj_4.start(); BOOST_TEST(obj_4.state == ST_STARING); BOOST_TEST(!std::testbit(probe, 1)); obj_4._start_finished(false); BOOST_TEST(obj_4.state == ST_PENDING); BOOST_TEST(!std::testbit(probe, 1)); obj_4.start(); obj_4._start_finished(true); BOOST_TEST(obj_4.state == ST_RUNNING); BOOST_TEST(std::testbit(probe, 1)); }