#ifndef BOOST_TEST_FILTER_HPP_ #define BOOST_TEST_FILTER_HPP_ #include #include #include #include namespace boost { namespace unit_test { namespace detail { inline size_t test_case_size( const boost::unit_test::test_suite& ts ) { boost::unit_test::test_case_counter counter; boost::unit_test::traverse_test_tree( ts, counter ); return counter.m_count; } class filter_visitor : public boost::unit_test::test_tree_visitor { public: filter_visitor( const boost::regex& regex ) : regex_( regex ) , root_( 0 ) {} boost::unit_test::test_suite* get_suite() const { return root_; } private: // test_tree_visitor void visit( boost::unit_test::test_case const& tc ) { if( is_passed( tc ) ) suites_.back()->add ( const_cast( &tc ) , tc.p_expected_failures.get() , tc.p_timeout.get() ); } bool test_suite_start( boost::unit_test::test_suite const& ts ) { suites_.push_back( new boost::unit_test::test_suite( ts.p_name.get() ) ); return true; } void test_suite_finish( boost::unit_test::test_suite const& ts ) { boost::unit_test::test_suite* suite = suites_.back(); suites_.pop_back(); if( suites_.empty() ) root_ = suite; else if( test_case_size( *suite ) > 0 ) suites_.back()->add( suite, ts.p_expected_failures, ts.p_timeout ); } private: static std::string make_name( const std::string& begin, const boost::unit_test::test_unit* tu ) { std::string next( tu->p_name.get() ); return begin.empty() ? next : begin + "/" + next; } std::string get_cur_suite_name() const { return std::accumulate( suites_.begin(), suites_.end(), std::string(), &filter_visitor::make_name ); } std::string get_unit_name( const boost::unit_test::test_unit& tu ) const { return make_name( get_cur_suite_name(), &tu ); } bool is_passed( const boost::unit_test::test_unit& tu ) const { return boost::regex_match( get_unit_name( tu ), regex_ ); } private: const boost::regex& regex_; std::vector suites_; boost::unit_test::test_suite* root_; }; inline boost::regex get_regex_from_args( int argc, char* argv[] ) { for( int i = 1; i < argc; ++i ) { const std::string key( "--filter=" ); if( std::string( argv[i], key.size() ) == key ) return boost::regex( std::string( ".*" ) + ( argv[i] + key.size() ) + ".*" ); } return boost::regex(); } inline boost::unit_test::test_suite* filter( boost::unit_test::test_suite* src, int& argc, char* argv[] ) { boost::regex regex( detail::get_regex_from_args( argc, argv ) ); if( src == NULL || regex.empty() ) return src; detail::filter_visitor visitor( regex ); boost::unit_test::traverse_test_tree( *src, visitor ); return visitor.get_suite(); } }}} // namespace boost, unit_test, detail #endif // #ifndef BOOST_TEST_FILTER_HPP_