$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r74402 - in trunk/boost/test: . impl
From: gennadiy.rozental_at_[hidden]
Date: 2011-09-15 23:26:17
Author: rogeeff
Date: 2011-09-15 23:26:16 EDT (Thu, 15 Sep 2011)
New Revision: 74402
URL: http://svn.boost.org/trac/boost/changeset/74402
Log:
introduced support for "run by label" 
run by name/label now recognizes dependencies
traverse_test_tree now able traverse whole tree ignoring enable/disable status
dependencies became public property of test unit
Text files modified: 
   trunk/boost/test/framework.hpp            |     6                                         
   trunk/boost/test/impl/framework.ipp       |   285 +++++++++++++++++++++++++++++++++++++++ 
   trunk/boost/test/impl/unit_test_main.ipp  |   141 +++----------------                     
   trunk/boost/test/impl/unit_test_suite.ipp |    40 +++-                                    
   trunk/boost/test/unit_test_suite_impl.hpp |    24 ++-                                     
   5 files changed, 354 insertions(+), 142 deletions(-)
Modified: trunk/boost/test/framework.hpp
==============================================================================
--- trunk/boost/test/framework.hpp	(original)
+++ trunk/boost/test/framework.hpp	2011-09-15 23:26:16 EDT (Thu, 15 Sep 2011)
@@ -103,6 +103,12 @@
 BOOST_TEST_DECL void    exception_caught( execution_exception const& );
 BOOST_TEST_DECL void    test_unit_aborted( test_unit const& );
 
+namespace impl { // publisized to facilitate internal unit test only
+
+void    apply_filters( test_unit_id );
+
+} // namespace impl
+
 // ************************************************************************** //
 // **************                framework errors              ************** //
 // ************************************************************************** //
Modified: trunk/boost/test/impl/framework.ipp
==============================================================================
--- trunk/boost/test/impl/framework.ipp	(original)
+++ trunk/boost/test/impl/framework.ipp	2011-09-15 23:26:16 EDT (Thu, 15 Sep 2011)
@@ -28,6 +28,11 @@
 #include <boost/test/results_reporter.hpp>
 #include <boost/test/test_tools.hpp>
 
+#if !defined(__BORLANDC__) && !BOOST_WORKAROUND( BOOST_MSVC, < 1300 ) && !BOOST_WORKAROUND( __SUNPRO_CC, < 0x5100 )
+#define BOOST_TEST_SUPPORT_RUN_BY_NAME
+#include <boost/test/utils/iterator/token_iterator.hpp>
+#endif
+
 #include <boost/test/detail/unit_test_parameters.hpp>
 #include <boost/test/detail/global_typedef.hpp>
 
@@ -35,6 +40,7 @@
 
 // Boost
 #include <boost/timer.hpp>
+#include <boost/bind.hpp>
 
 // STL
 #include <map>
@@ -55,7 +61,7 @@
 namespace unit_test {
 
 // ************************************************************************** //
-// **************            test_start calls wrapper          ************** //
+// **************           test_start calls wrapper           ************** //
 // ************************************************************************** //
 
 namespace ut_detail {
@@ -102,7 +108,198 @@
     init_unit_test_func m_init_func;
 };
 
-}
+// ************************************************************************** //
+// **************                  tu_enabler                  ************** //
+// ************************************************************************** //
+
+struct tu_enabler : public test_tree_visitor {
+    explicit        tu_enabler( bool on_off ) : m_on_off( on_off ) {}
+private:
+    virtual void    visit( test_case const& tc )                { tc.p_enabled.value = m_on_off; }
+    virtual bool    test_suite_start( test_suite const& ts )    { ts.p_enabled.value = m_on_off; return true; }
+
+    // Data members
+    bool            m_on_off;
+};
+
+// ************************************************************************** //
+// **************                  name_filter                 ************** //
+// ************************************************************************** //
+
+typedef std::list<std::pair<test_unit_id,bool> > tu_enable_list;
+
+class name_filter : public test_tree_visitor {
+    struct component {
+        component( const_string name ) // has to be implicit
+        {
+            if( name == "*" )
+                m_kind  = SFK_ALL;
+            else if( first_char( name ) == '*' && last_char( name ) == '*' ) {
+                m_kind  = SFK_SUBSTR;
+                m_name  = name.substr( 1, name.size()-1 );
+            }
+            else if( first_char( name ) == '*' ) {
+                m_kind  = SFK_TRAILING;
+                m_name  = name.substr( 1 );
+            }
+            else if( last_char( name ) == '*' ) {
+                m_kind  = SFK_LEADING;
+                m_name  = name.substr( 0, name.size()-1 );
+            }
+            else {
+                m_kind  = SFK_MATCH;
+                m_name  = name;
+            }
+        };
+
+        bool            pass( test_unit const& tu ) const
+        {
+            const_string name( tu.p_name );
+    
+            switch( m_kind ) {
+            default:
+            case SFK_ALL:
+                return true;
+            case SFK_LEADING:
+                return name.substr( 0, m_name.size() ) == m_name;
+            case SFK_TRAILING:
+                return name.size() >= m_name.size() && name.substr( name.size() - m_name.size() ) == m_name;
+            case SFK_SUBSTR:
+                return name.find( m_name ) != const_string::npos;
+            case SFK_MATCH:
+                return m_name == tu.p_name.get();
+            }
+        }
+        enum kind { SFK_ALL, SFK_LEADING, SFK_TRAILING, SFK_SUBSTR, SFK_MATCH };
+
+        kind            m_kind;
+        const_string    m_name;
+    };
+
+public:
+    // Constructor
+    name_filter( tu_enable_list& tu_to_enable, const_string tc_to_run ) : m_tu_to_enable( tu_to_enable ), m_depth( 0 )
+    {
+#ifdef BOOST_TEST_SUPPORT_RUN_BY_NAME
+        string_token_iterator tit( tc_to_run, (dropped_delimeters = "/", kept_delimeters = dt_none) );
+
+        while( tit != string_token_iterator() ) {
+            m_components.push_back( std::vector<component>( string_token_iterator( *tit, (dropped_delimeters = ",", kept_delimeters = dt_none)  ), 
+                                                            string_token_iterator() ) );
+
+            ++tit;           
+        }
+#endif
+    }
+
+private:
+    bool            filter_unit( test_unit const& tu )
+    {
+        // skip master test suite
+        if( m_depth == 0 )
+            return true;
+
+        // corresponding name filters are at level m_depth-1
+        std::vector<component> const& filters = m_components[m_depth-1];
+
+        // look for match
+        return std::find_if( filters.begin(), filters.end(), bind( &component::pass, _1, boost::ref(tu) ) ) != filters.end();
+    }
+
+    // test_tree_visitor interface
+    virtual void    visit( test_case const& tc )
+    {
+        if( filter_unit( tc ) )
+            m_tu_to_enable.push_back( std::make_pair( tc.p_id, false ) ); // found a test case; add it to enable list without children
+    }
+    virtual bool    test_suite_start( test_suite const& ts )
+    {
+        if( filter_unit( ts ) ) {
+            if( m_depth < m_components.size() ) {
+                ++m_depth;
+                return true;
+            }
+
+            m_tu_to_enable.push_back( std::make_pair( ts.p_id, true ) ); // found a test suite; add it to enable list with children and stop recursion
+        }
+
+        return false;
+    }
+
+    // Data members
+    typedef std::vector<std::vector<component> > components_per_level;
+
+    components_per_level    m_components;
+    tu_enable_list&         m_tu_to_enable;
+    unsigned                m_depth;
+};
+
+// ************************************************************************** //
+// **************                 label_filter                 ************** //
+// ************************************************************************** //
+
+class label_filter : public test_tree_visitor {
+public:
+    label_filter( tu_enable_list& tu_to_enable, const_string label )
+    : m_tu_to_enable( tu_to_enable )
+    , m_label( label )
+    {}
+
+private:
+    bool            filter_unit( test_unit const& tu )
+    {
+        return tu.has_label( m_label );
+    }
+
+    // test_tree_visitor interface
+    virtual void    visit( test_case const& tc )
+    {
+        if( filter_unit( tc ) )
+            m_tu_to_enable.push_back( std::make_pair( tc.p_id, false ) ); // found a test case; add it to enable list without children
+    }
+    virtual bool    test_suite_start( test_suite const& ts )
+    {
+        if( filter_unit( ts ) ) {
+            m_tu_to_enable.push_back( std::make_pair( ts.p_id, true ) ); // found a test suite; add it to enable list with children and stop recursion
+            return false;
+        }
+
+        return true;
+    }
+
+    // Data members
+    const_string    m_label;
+    tu_enable_list& m_tu_to_enable;
+};
+
+// ************************************************************************** //
+// **************                 tu_collector                 ************** //
+// ************************************************************************** //
+
+class tu_collector : public test_tree_visitor {
+public:
+    explicit        tu_collector( tu_enable_list& tu_to_enable ) : m_tu_to_enable( tu_to_enable ) {}
+
+private:
+    // test_tree_visitor interface
+    virtual void    visit( test_case const& tc )
+    {
+        if( !tc.p_enabled )
+            m_tu_to_enable.push_back( std::make_pair( tc.p_id, false ) );
+    }
+    virtual bool    test_suite_start( test_suite const& ts )
+    {
+        if( !ts.p_enabled )
+            m_tu_to_enable.push_back( std::make_pair( ts.p_id, false ) );
+
+        return true;
+    }
+
+    // Data members
+    tu_enable_list& m_tu_to_enable;
+};
+
+} // namespace ut_detail
 
 // ************************************************************************** //
 // **************                   framework                  ************** //
@@ -155,7 +352,6 @@
         BOOST_TEST_FOREACH( test_observer*, to, m_observers )
             to->test_unit_start( tc );
 
-      
         // execute the test case body
         boost::timer tc_timer;
         test_unit_id bkup = m_curr_test_case;
@@ -225,7 +421,7 @@
 
         std::string descr;
         int         frame_id;
-        bool        is_sticky;    
+        bool        is_sticky;
     };
     typedef std::vector<context_frame> context_data;
 
@@ -299,11 +495,90 @@
         throw setup_error( ex.what() );
     }
 
+    impl::apply_filters( master_test_suite().p_id );
+
     s_frk_impl().m_is_initialized = true;
 }
 
 //____________________________________________________________________________//
 
+namespace impl {
+void
+apply_filters( test_unit_id tu_id )
+{
+    if( runtime_config::test_to_run().empty() ) {
+        ut_detail::tu_enabler enable( true );
+
+        traverse_test_tree( tu_id, enable );
+    }
+    else {
+        // 10. first disable all tu
+        ut_detail::tu_enabler disable( false );
+        traverse_test_tree( tu_id, disable );
+
+        // 20. collect tu to enable based on filters
+        ut_detail::tu_enable_list tu_to_enable;
+
+        BOOST_TEST_FOREACH( std::string const&, filter, runtime_config::test_to_run() ) {
+            if( filter.empty() )
+                continue;
+
+            if( filter[0] == '@' ) {
+                ut_detail::label_filter lf( tu_to_enable, const_string(filter).trim_left(1) );
+                traverse_test_tree( tu_id, lf, true );
+            }
+            else {
+                ut_detail::name_filter nf( tu_to_enable, filter );
+                traverse_test_tree( tu_id, nf, true );
+            }
+        }
+
+        // 30. enable all tu collected along with their parents, dependencies and children where necessary
+        while( !tu_to_enable.empty() ) {
+            std::pair<test_unit_id,bool>    data = tu_to_enable.front();
+            test_unit const&                tu   = framework::get( data.first, tut_any );
+
+            tu_to_enable.pop_front();
+
+            if( tu.p_enabled ) 
+                continue;
+
+            // 31. enable tu
+            tu.p_enabled.value = true;
+
+            // 32. master test suite - we are done
+            if( tu.p_id == tu_id )
+                continue;
+
+            // 33. add parent to the list (without children)
+            if( !framework::get( tu.p_parent_id, tut_any ).p_enabled )
+                tu_to_enable.push_back( std::make_pair( tu.p_parent_id, false ) );
+
+            // 34. add dependencies to the list (with children)
+            BOOST_TEST_FOREACH( test_unit_id, dep_id, tu.p_dependencies.get() ) {
+                test_unit const& dep = framework::get( dep_id, tut_any );
+
+                if( !dep.p_enabled ) {
+                    BOOST_TEST_MESSAGE( "Including test " << dep.p_type_name << ' ' << dep.p_name << 
+                                        " as a dependacy of test " << tu.p_type_name << ' ' << tu.p_name );
+
+                    tu_to_enable.push_back( std::make_pair( dep_id, true ) );
+                }
+            }
+
+            // 35. add all children to the list recursively
+            if( data.second && tu.p_type == tut_suite ) {
+                ut_detail::tu_collector collect( tu_to_enable );
+                traverse_test_tree( tu.p_id, collect, true );
+            }
+        }
+    }
+}
+
+} // namespace impl
+
+//____________________________________________________________________________//
+
 bool
 is_initialized()
 {
@@ -498,7 +773,7 @@
     test_case_counter tcc;
     traverse_test_tree( id, tcc );
 
-    BOOST_TEST_SETUP_ASSERT( tcc.p_count != 0 , runtime_config::test_to_run().is_empty() 
+    BOOST_TEST_SETUP_ASSERT( tcc.p_count != 0 , runtime_config::test_to_run().empty() 
         ? BOOST_TEST_L( "test tree is empty" ) 
         : BOOST_TEST_L( "no test cases matching filter" ) );
 
Modified: trunk/boost/test/impl/unit_test_main.ipp
==============================================================================
--- trunk/boost/test/impl/unit_test_main.ipp	(original)
+++ trunk/boost/test/impl/unit_test_main.ipp	2011-09-15 23:26:16 EDT (Thu, 15 Sep 2011)
@@ -23,18 +23,13 @@
 
 #include <boost/test/detail/unit_test_parameters.hpp>
 
-#if !defined(__BORLANDC__) && !BOOST_WORKAROUND( BOOST_MSVC, < 1300 ) && !BOOST_WORKAROUND( __SUNPRO_CC, < 0x5100 )
-#define BOOST_TEST_SUPPORT_RUN_BY_NAME
-#include <boost/test/utils/iterator/token_iterator.hpp>
-#endif
-
 // Boost
 #include <boost/cstdlib.hpp>
-#include <boost/bind.hpp>
 
 // STL
 #include <stdexcept>
 #include <iostream>
+#include <iomanip>
 
 #include <boost/test/detail/suppress_warnings.hpp>
 
@@ -44,128 +39,38 @@
 
 namespace unit_test {
 
+namespace ut_detail {
+
 // ************************************************************************** //
-// **************                 test_case_filter             ************** //
+// **************                test_tree_reporter            ************** //
 // ************************************************************************** //
 
-class test_case_filter : public test_tree_visitor {
-public:
-    struct single_filter {
-        single_filter( const_string in )
-        {
-            if( in == "*" )
-                m_kind  = SFK_ALL;
-            else if( first_char( in ) == '*' && last_char( in ) == '*' ) {
-                m_kind  = SFK_SUBSTR;
-                m_value = in.substr( 1, in.size()-1 );
-            }
-            else if( first_char( in ) == '*' ) {
-                m_kind  = SFK_TRAILING;
-                m_value = in.substr( 1 );
-            }
-            else if( last_char( in ) == '*' ) {
-                m_kind  = SFK_LEADING;
-                m_value = in.substr( 0, in.size()-1 );
-            }
-            else {
-                m_kind  = SFK_MATCH;
-                m_value = in;
-            }
-        };
-
-        bool            pass( test_unit const& tu ) const
-        {
-            const_string name( tu.p_name );
-    
-            switch( m_kind ) {
-            default:
-            case SFK_ALL:
-                return true;
-
-            case SFK_LEADING:
-                return name.substr( 0, m_value.size() ) == m_value;
-
-            case SFK_TRAILING:
-                return name.size() >= m_value.size() && name.substr( name.size() - m_value.size() ) == m_value;
-
-            case SFK_SUBSTR:
-                return name.find( m_value ) != const_string::npos;
-
-            case SFK_MATCH:
-                return m_value == tu.p_name.get();
-            }
-        }
-        enum kind { SFK_ALL, SFK_LEADING, SFK_TRAILING, SFK_SUBSTR, SFK_MATCH };
+struct test_tree_reporter : test_tree_visitor {
+    test_tree_reporter() : m_indent( -4 ) {} // skip master test suite
 
-        kind            m_kind;
-        const_string    m_value;
-    };
-    // Constructor
-#ifndef BOOST_TEST_SUPPORT_RUN_BY_NAME
-    explicit        test_case_filter( const_string ) : m_depth( 0 ) {}
-#else
-    explicit        test_case_filter( const_string tc_to_run ) 
-    : m_depth( 0 )
+private:
+    virtual void    visit( test_case const& tc )
     {
-        string_token_iterator tit( tc_to_run, (dropped_delimeters = "/", kept_delimeters = dt_none) );
-
-        while( tit != string_token_iterator() ) {
-            m_filters.push_back( 
-                std::vector<single_filter>( string_token_iterator( *tit, (dropped_delimeters = ",", kept_delimeters = dt_none)  ), 
-                                            string_token_iterator() ) );
-
-            ++tit;           
-        }
+        results_reporter::get_stream() << std::setw( m_indent ) << "" << tc.p_name << "\n";
     }
-#endif
-    
-    void            filter_unit( test_unit const& tu )
+    virtual bool    test_suite_start( test_suite const& ts )
     {
-        if( (++m_depth - 1) > m_filters.size() ) {
-            tu.p_enabled.value = true;
-            return;
-        }
-
-        if( m_depth == 1 )
-            return;
-
-        std::vector<single_filter> const& filters = m_filters[m_depth-2];
-
-        tu.p_enabled.value =
-            std::find_if( filters.begin(), filters.end(), bind( &single_filter::pass, _1, boost::ref(tu) ) ) != filters.end();
+        if( m_indent >= 0 )
+            results_reporter::get_stream() << std::setw( m_indent ) << "" << ts.p_name << "\n";
+        m_indent += 4;
+        return true;
     }
-
-    // test tree visitor interface
-    virtual void    visit( test_case const& tc )
+    virtual void    test_suite_finish( test_suite const& )
     {
-        if( m_depth < m_filters.size() ) {
-            tc.p_enabled.value = false;
-            return;
-        }
-
-        filter_unit( tc );
-
-        --m_depth;
+        m_indent -= 4;
     }
 
-    virtual bool    test_suite_start( test_suite const& ts )
-    { 
-        filter_unit( ts );
-
-        if( !ts.p_enabled )
-            --m_depth;
-
-        return ts.p_enabled;
-    }
-
-    virtual void    test_suite_finish( test_suite const& )  { --m_depth; }
-
-private:
     // Data members
-    std::vector<std::vector<single_filter> >    m_filters;
-    unsigned                                    m_depth;
+    int             m_indent;
 };
 
+} // namespace ut_detail
+
 // ************************************************************************** //
 // **************                  unit_test_main              ************** //
 // ************************************************************************** //
@@ -176,10 +81,12 @@
     try {
         framework::init( init_func, argc, argv );
 
-        if( !runtime_config::test_to_run().is_empty() ) {
-            test_case_filter filter( runtime_config::test_to_run() );
+        if( runtime_config::list_content() ) {
+            ut_detail::test_tree_reporter content_reporter;
+
+            traverse_test_tree( framework::master_test_suite().p_id, content_reporter );
 
-            traverse_test_tree( framework::master_test_suite().p_id, filter );
+            return boost::exit_success;
         }
 
         framework::run();
Modified: trunk/boost/test/impl/unit_test_suite.ipp
==============================================================================
--- trunk/boost/test/impl/unit_test_suite.ipp	(original)
+++ trunk/boost/test/impl/unit_test_suite.ipp	2011-09-15 23:26:16 EDT (Thu, 15 Sep 2011)
@@ -70,7 +70,7 @@
 void
 test_unit::depends_on( test_unit* tu )
 {
-    m_dependencies.push_back( tu->p_id );
+    p_dependencies.value.push_back( tu->p_id );
 }
 
 //____________________________________________________________________________//
@@ -78,7 +78,7 @@
 bool
 test_unit::check_dependencies() const
 {
-    BOOST_TEST_FOREACH( test_unit_id, tu_id, m_dependencies ) {
+    BOOST_TEST_FOREACH( test_unit_id, tu_id, p_dependencies.get() ) {
         if( !unit_test::results_collector.results( tu_id ).passed() )
             return false;
     }
@@ -99,6 +99,22 @@
 
 //____________________________________________________________________________//
 
+void
+test_unit::add_label( const_string l )
+{
+    m_labels.push_back( std::string( l.begin(), l.end() ) );
+}
+
+//____________________________________________________________________________//
+
+bool
+test_unit::has_label( const_string l ) const
+{
+    return std::find( m_labels.begin(), m_labels.end(), l ) != m_labels.end();
+}
+
+//____________________________________________________________________________//
+
 // ************************************************************************** //
 // **************                   test_case                  ************** //
 // ************************************************************************** //
@@ -187,30 +203,30 @@
 // ************************************************************************** //
 
 void
-traverse_test_tree( test_case const& tc, test_tree_visitor& V )
+traverse_test_tree( test_case const& tc, test_tree_visitor& V, bool ignore_status )
 {
-    if( tc.p_enabled )
-    V.visit( tc );
+    if( tc.p_enabled || ignore_status )
+        V.visit( tc );
 }
 
 //____________________________________________________________________________//
 
 void
-traverse_test_tree( test_suite const& suite, test_tree_visitor& V )
+traverse_test_tree( test_suite const& suite, test_tree_visitor& V, bool ignore_status )
 {
-    if( !suite.p_enabled || !V.test_suite_start( suite ) )
+    if( (!suite.p_enabled && !ignore_status) || !V.test_suite_start( suite ) )
         return;
 
     try {
         if( runtime_config::random_seed() == 0 ) {
             BOOST_TEST_FOREACH( test_unit_id, id, suite.m_members )
-                traverse_test_tree( id, V );
+                traverse_test_tree( id, V, ignore_status );
         }
         else {
             std::vector<test_unit_id> members( suite.m_members );
             std::random_shuffle( members.begin(), members.end() );
             BOOST_TEST_FOREACH( test_unit_id, id, members )
-                traverse_test_tree( id, V );
+                traverse_test_tree( id, V, ignore_status );
         }
         
     } catch( test_being_aborted const& ) {
@@ -226,12 +242,12 @@
 //____________________________________________________________________________//
 
 void
-traverse_test_tree( test_unit_id id, test_tree_visitor& V )
+traverse_test_tree( test_unit_id id, test_tree_visitor& V, bool ignore_status )
 {
     if( ut_detail::test_id_2_unit_type( id ) == tut_case )
-        traverse_test_tree( framework::get<test_case>( id ), V );
+        traverse_test_tree( framework::get<test_case>( id ), V, ignore_status );
     else
-        traverse_test_tree( framework::get<test_suite>( id ), V );
+        traverse_test_tree( framework::get<test_suite>( id ), V, ignore_status );
 }
 
 //____________________________________________________________________________//
Modified: trunk/boost/test/unit_test_suite_impl.hpp
==============================================================================
--- trunk/boost/test/unit_test_suite_impl.hpp	(original)
+++ trunk/boost/test/unit_test_suite_impl.hpp	2011-09-15 23:26:16 EDT (Thu, 15 Sep 2011)
@@ -52,6 +52,7 @@
 class BOOST_TEST_DECL test_unit {
 public:
     enum { type = tut_any };
+    typedef std::list<test_unit_id> id_list;
 
     // Constructor
     test_unit( const_string tu_name, test_unit_type t );
@@ -60,13 +61,20 @@
     void    depends_on( test_unit* tu );
     bool    check_dependencies() const;
 
+    // labels management
+    void    add_label( const_string l );
+    bool    has_label( const_string l ) const;
+
     // Public r/o properties
     typedef BOOST_READONLY_PROPERTY(test_unit_id,(framework_impl))  id_t;
     typedef BOOST_READONLY_PROPERTY(test_unit_id,(test_suite))      parent_id_t;
+    typedef BOOST_READONLY_PROPERTY(id_list,(test_unit))            id_list_t;
+
     readonly_property<test_unit_type>   p_type;                 // type for this test unit
     readonly_property<const_string>     p_type_name;            // "case"/"suite"
     id_t                                p_id;                   // unique id for this test unit
     parent_id_t                         p_parent_id;            // parent test suite id
+    id_list_t                           p_dependencies;         // list of test units this one depends on
 
     // Public r/w properties
     readwrite_property<std::string>     p_name;                 // name for this test unit
@@ -81,7 +89,7 @@
 
 private:
     // Data members
-    std::list<test_unit_id>             m_dependencies;
+    std::list<std::string>              m_labels;
 };
 
 // ************************************************************************** //
@@ -141,7 +149,7 @@
 
 protected:
     friend BOOST_TEST_DECL 
-    void        traverse_test_tree( test_suite const&, test_tree_visitor& );
+    void        traverse_test_tree( test_suite const&, test_tree_visitor&, bool );
     friend class framework_impl;
     virtual     ~test_suite() {}
 
@@ -185,19 +193,19 @@
 // **************               traverse_test_tree             ************** //
 // ************************************************************************** //
 
-BOOST_TEST_DECL void    traverse_test_tree( test_case const&, test_tree_visitor& );
-BOOST_TEST_DECL void    traverse_test_tree( test_suite const&, test_tree_visitor& );
-BOOST_TEST_DECL void    traverse_test_tree( test_unit_id     , test_tree_visitor& );
+BOOST_TEST_DECL void    traverse_test_tree( test_case const&, test_tree_visitor&, bool ignore_status = false );
+BOOST_TEST_DECL void    traverse_test_tree( test_suite const&, test_tree_visitor&, bool ignore_status = false );
+BOOST_TEST_DECL void    traverse_test_tree( test_unit_id     , test_tree_visitor&, bool ignore_status = false );
 
 //____________________________________________________________________________//
 
 inline void
-traverse_test_tree( test_unit const& tu, test_tree_visitor& V )
+traverse_test_tree( test_unit const& tu, test_tree_visitor& V, bool ignore_status = false )
 {
     if( tu.p_type == tut_case )
-        traverse_test_tree( static_cast<test_case const&>( tu ), V );
+        traverse_test_tree( static_cast<test_case const&>( tu ), V, ignore_status );
     else
-        traverse_test_tree( static_cast<test_suite const&>( tu ), V );
+        traverse_test_tree( static_cast<test_suite const&>( tu ), V, ignore_status );
 }
 
 //____________________________________________________________________________//