347 lines
10 KiB
C++
347 lines
10 KiB
C++
// (C) Copyright Gennadiy Rozental 2005-2008.
|
|
// 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/test for the library home page.
|
|
//
|
|
// File : $RCSfile$
|
|
//
|
|
// Version : $Revision: 54633 $
|
|
//
|
|
// Description : privides core implementation for Unit Test Framework.
|
|
// Extensions can be provided in separate files
|
|
// ***************************************************************************
|
|
|
|
#ifndef BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
|
|
#define BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
|
|
|
|
// Boost.Test
|
|
#include <boost/detail/workaround.hpp>
|
|
#include <boost/test/unit_test_suite_impl.hpp>
|
|
#include <boost/test/framework.hpp>
|
|
#include <boost/test/utils/foreach.hpp>
|
|
#include <boost/test/results_collector.hpp>
|
|
#include <boost/test/detail/unit_test_parameters.hpp>
|
|
|
|
// Boost
|
|
#include <boost/timer.hpp>
|
|
|
|
// STL
|
|
#include <algorithm>
|
|
#include <vector>
|
|
|
|
#include <boost/test/detail/suppress_warnings.hpp>
|
|
|
|
#if BOOST_WORKAROUND(__BORLANDC__, < 0x600) && \
|
|
BOOST_WORKAROUND(_STLPORT_VERSION, <= 0x450) \
|
|
/**/
|
|
using std::rand; // rand is in std and random_shuffle is in _STL
|
|
#endif
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
namespace boost {
|
|
|
|
namespace unit_test {
|
|
|
|
// ************************************************************************** //
|
|
// ************** test_unit ************** //
|
|
// ************************************************************************** //
|
|
|
|
test_unit::test_unit( const_string name, test_unit_type t )
|
|
: p_type( t )
|
|
, p_type_name( t == tut_case ? "case" : "suite" )
|
|
, p_id( INV_TEST_UNIT_ID )
|
|
, p_name( std::string( name.begin(), name.size() ) )
|
|
, p_enabled( true )
|
|
{
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
test_unit::~test_unit()
|
|
{
|
|
framework::deregister_test_unit( this );
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
void
|
|
test_unit::depends_on( test_unit* tu )
|
|
{
|
|
m_dependencies.push_back( tu->p_id );
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
bool
|
|
test_unit::check_dependencies() const
|
|
{
|
|
BOOST_TEST_FOREACH( test_unit_id, tu_id, m_dependencies ) {
|
|
if( !unit_test::results_collector.results( tu_id ).passed() )
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
void
|
|
test_unit::increase_exp_fail( unsigned num )
|
|
{
|
|
p_expected_failures.value += num;
|
|
|
|
if( p_parent_id != 0 )
|
|
framework::get<test_suite>( p_parent_id ).increase_exp_fail( num );
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
// ************************************************************************** //
|
|
// ************** test_case ************** //
|
|
// ************************************************************************** //
|
|
|
|
test_case::test_case( const_string name, callback0<> const& test_func )
|
|
: test_unit( name, static_cast<test_unit_type>(type) )
|
|
, m_test_func( test_func )
|
|
{
|
|
// !! weirdest MSVC BUG; try to remove this statement; looks like it eats first token of next statement
|
|
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
|
0;
|
|
#endif
|
|
framework::register_test_unit( this );
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
// ************************************************************************** //
|
|
// ************** test_suite ************** //
|
|
// ************************************************************************** //
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
test_suite::test_suite( const_string name )
|
|
: test_unit( name, static_cast<test_unit_type>(type) )
|
|
{
|
|
framework::register_test_unit( this );
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
void
|
|
test_suite::add( test_unit* tu, counter_t expected_failures, unsigned timeout )
|
|
{
|
|
if( timeout != 0 )
|
|
tu->p_timeout.value = timeout;
|
|
|
|
m_members.push_back( tu->p_id );
|
|
tu->p_parent_id.value = p_id;
|
|
|
|
if( tu->p_expected_failures )
|
|
increase_exp_fail( tu->p_expected_failures );
|
|
|
|
if( expected_failures )
|
|
tu->increase_exp_fail( expected_failures );
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
void
|
|
test_suite::add( test_unit_generator const& gen, unsigned timeout )
|
|
{
|
|
test_unit* tu;
|
|
while((tu = gen.next(), tu))
|
|
add( tu, 0, timeout );
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
void
|
|
test_suite::remove( test_unit_id id )
|
|
{
|
|
std::vector<test_unit_id>::iterator it = std::find( m_members.begin(), m_members.end(), id );
|
|
|
|
if( it != m_members.end() )
|
|
m_members.erase( it );
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
test_unit_id
|
|
test_suite::get( const_string tu_name ) const
|
|
{
|
|
BOOST_TEST_FOREACH( test_unit_id, id, m_members ) {
|
|
if( tu_name == framework::get( id, ut_detail::test_id_2_unit_type( id ) ).p_name.get() )
|
|
return id;
|
|
}
|
|
|
|
return INV_TEST_UNIT_ID;
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
// ************************************************************************** //
|
|
// ************** traverse_test_tree ************** //
|
|
// ************************************************************************** //
|
|
|
|
void
|
|
traverse_test_tree( test_case const& tc, test_tree_visitor& V )
|
|
{
|
|
if( tc.p_enabled )
|
|
V.visit( tc );
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
void
|
|
traverse_test_tree( test_suite const& suite, test_tree_visitor& V )
|
|
{
|
|
if( !suite.p_enabled || !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 );
|
|
}
|
|
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 );
|
|
}
|
|
|
|
} catch( test_being_aborted const& ) {
|
|
V.test_suite_finish( suite );
|
|
framework::test_unit_aborted( suite );
|
|
|
|
throw;
|
|
}
|
|
|
|
V.test_suite_finish( suite );
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
void
|
|
traverse_test_tree( test_unit_id id, test_tree_visitor& V )
|
|
{
|
|
if( ut_detail::test_id_2_unit_type( id ) == tut_case )
|
|
traverse_test_tree( framework::get<test_case>( id ), V );
|
|
else
|
|
traverse_test_tree( framework::get<test_suite>( id ), V );
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
// ************************************************************************** //
|
|
// ************** test_case_counter ************** //
|
|
// ************************************************************************** //
|
|
|
|
void
|
|
test_case_counter::visit( test_case const& tc )
|
|
{
|
|
if( tc.p_enabled )
|
|
++p_count.value;
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
// ************************************************************************** //
|
|
// ************** object generators ************** //
|
|
// ************************************************************************** //
|
|
|
|
namespace ut_detail {
|
|
|
|
std::string
|
|
normalize_test_case_name( const_string name )
|
|
{
|
|
return ( name[0] == '&'
|
|
? std::string( name.begin()+1, name.size()-1 )
|
|
: std::string( name.begin(), name.size() ) );
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
// ************************************************************************** //
|
|
// ************** auto_test_unit_registrar ************** //
|
|
// ************************************************************************** //
|
|
|
|
auto_test_unit_registrar::auto_test_unit_registrar( test_case* tc, counter_t exp_fail )
|
|
{
|
|
curr_ts_store().back()->add( tc, exp_fail );
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
auto_test_unit_registrar::auto_test_unit_registrar( const_string ts_name )
|
|
{
|
|
test_unit_id id = curr_ts_store().back()->get( ts_name );
|
|
|
|
test_suite* ts;
|
|
|
|
if( id != INV_TEST_UNIT_ID ) {
|
|
ts = &framework::get<test_suite>( id ); // !! test for invalid tu type
|
|
BOOST_ASSERT( ts->p_parent_id == curr_ts_store().back()->p_id );
|
|
}
|
|
else {
|
|
ts = new test_suite( ts_name );
|
|
curr_ts_store().back()->add( ts );
|
|
}
|
|
|
|
curr_ts_store().push_back( ts );
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
auto_test_unit_registrar::auto_test_unit_registrar( test_unit_generator const& tc_gen )
|
|
{
|
|
curr_ts_store().back()->add( tc_gen );
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
auto_test_unit_registrar::auto_test_unit_registrar( int )
|
|
{
|
|
if( curr_ts_store().size() == 0 )
|
|
return; // report error?
|
|
|
|
curr_ts_store().pop_back();
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
std::list<test_suite*>&
|
|
auto_test_unit_registrar::curr_ts_store()
|
|
{
|
|
static std::list<test_suite*> inst( 1, &framework::master_test_suite() );
|
|
return inst;
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
} // namespace ut_detail
|
|
|
|
// ************************************************************************** //
|
|
// ************** global_fixture ************** //
|
|
// ************************************************************************** //
|
|
|
|
global_fixture::global_fixture()
|
|
{
|
|
framework::register_observer( *this );
|
|
}
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
} // namespace unit_test
|
|
|
|
} // namespace boost
|
|
|
|
//____________________________________________________________________________//
|
|
|
|
#include <boost/test/detail/enable_warnings.hpp>
|
|
|
|
#endif // BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
|