276 lines
11 KiB
C++
276 lines
11 KiB
C++
|
// (C) Copyright Gennadiy Rozental 2001.
|
||
|
// 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
|
||
|
/// Defines @ref boost::unit_test::test_unit "test_unit", @ref boost::unit_test::test_case "test_case",
|
||
|
/// @ref boost::unit_test::test_suite "test_suite" and @ref boost::unit_test::master_test_suite_t "master_test_suite_t"
|
||
|
// ***************************************************************************
|
||
|
|
||
|
#ifndef BOOST_TEST_TREE_TEST_UNIT_HPP_100211GER
|
||
|
#define BOOST_TEST_TREE_TEST_UNIT_HPP_100211GER
|
||
|
|
||
|
// Boost.Test
|
||
|
#include <boost/test/detail/config.hpp>
|
||
|
#include <boost/test/detail/global_typedef.hpp>
|
||
|
#include <boost/test/detail/fwd_decl.hpp>
|
||
|
|
||
|
#include <boost/test/tree/decorator.hpp>
|
||
|
#include <boost/test/tree/fixture.hpp>
|
||
|
|
||
|
#include <boost/test/tools/assertion_result.hpp>
|
||
|
|
||
|
#include <boost/test/utils/class_properties.hpp>
|
||
|
|
||
|
// Boost
|
||
|
#include <boost/function/function0.hpp>
|
||
|
#include <boost/function/function1.hpp>
|
||
|
|
||
|
// STL
|
||
|
#include <vector>
|
||
|
#include <string>
|
||
|
#include <map>
|
||
|
|
||
|
#include <boost/test/detail/suppress_warnings.hpp>
|
||
|
|
||
|
//____________________________________________________________________________//
|
||
|
|
||
|
namespace boost {
|
||
|
namespace unit_test {
|
||
|
|
||
|
namespace framework {
|
||
|
class state;
|
||
|
}
|
||
|
|
||
|
// ************************************************************************** //
|
||
|
// ************** test_unit ************** //
|
||
|
// ************************************************************************** //
|
||
|
|
||
|
typedef std::vector<test_unit_id> test_unit_id_list;
|
||
|
|
||
|
class BOOST_TEST_DECL test_unit {
|
||
|
public:
|
||
|
enum { type = TUT_ANY };
|
||
|
enum run_status { RS_DISABLED, RS_ENABLED, RS_INHERIT, RS_INVALID };
|
||
|
|
||
|
typedef std::vector<test_unit_id> id_list;
|
||
|
typedef std::vector<test_unit_fixture_ptr> fixture_list_t;
|
||
|
typedef BOOST_READONLY_PROPERTY(test_unit_id,(framework::state)) 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;
|
||
|
typedef std::vector<decorator::base_ptr> decor_list_t;
|
||
|
typedef BOOST_READONLY_PROPERTY(std::vector<std::string>,(test_unit)) label_list_t;
|
||
|
|
||
|
typedef boost::function<test_tools::assertion_result (test_unit_id)> precondition_t;
|
||
|
typedef BOOST_READONLY_PROPERTY(std::vector<precondition_t>,(test_unit)) precond_list_t;
|
||
|
|
||
|
// preconditions management
|
||
|
void depends_on( test_unit* tu );
|
||
|
void add_precondition( precondition_t const& );
|
||
|
test_tools::assertion_result check_preconditions() const;
|
||
|
|
||
|
// labels management
|
||
|
void add_label( const_string l );
|
||
|
bool has_label( const_string l ) const;
|
||
|
|
||
|
// helper access methods
|
||
|
void increase_exp_fail( counter_t num );
|
||
|
bool is_enabled() const { return p_run_status == RS_ENABLED; }
|
||
|
std::string full_name() const;
|
||
|
|
||
|
// Public r/o properties
|
||
|
test_unit_type const p_type; ///< type for this test unit
|
||
|
const_string const p_type_name; ///< "case"/"suite"/"module"
|
||
|
const_string const p_file_name;
|
||
|
std::size_t const p_line_num;
|
||
|
id_t p_id; ///< unique id for this test unit
|
||
|
parent_id_t p_parent_id; ///< parent test suite id
|
||
|
label_list_t p_labels; ///< list of labels associated with this test unit
|
||
|
|
||
|
id_list_t p_dependencies; ///< list of test units this one depends on
|
||
|
precond_list_t p_preconditions; ///< user supplied preconditions for this test unit;
|
||
|
|
||
|
// Public r/w properties
|
||
|
readwrite_property<std::string> p_name; ///< name for this test unit
|
||
|
readwrite_property<std::string> p_description; ///< description for this test unit
|
||
|
readwrite_property<unsigned> p_timeout; ///< timeout for the test unit execution in seconds
|
||
|
readwrite_property<counter_t> p_expected_failures; ///< number of expected failures in this test unit
|
||
|
|
||
|
readwrite_property<run_status> p_default_status; ///< run status obtained by this unit during setup phase
|
||
|
readwrite_property<run_status> p_run_status; ///< run status assigned to this unit before execution phase after applying all filters
|
||
|
|
||
|
readwrite_property<counter_t> p_sibling_rank; ///< rank of this test unit amoung siblings of the same parent
|
||
|
|
||
|
readwrite_property<decor_list_t> p_decorators; ///< automatically assigned decorators; execution is delayed till framework::finalize_setup_phase function
|
||
|
readwrite_property<fixture_list_t> p_fixtures; ///< fixtures associated with this test unit
|
||
|
|
||
|
protected:
|
||
|
~test_unit();
|
||
|
// Constructor
|
||
|
test_unit( const_string tu_name, const_string tc_file, std::size_t tc_line, test_unit_type t );
|
||
|
// Master test suite constructor
|
||
|
explicit test_unit( const_string module_name );
|
||
|
|
||
|
private:
|
||
|
};
|
||
|
|
||
|
// ************************************************************************** //
|
||
|
// ************** test_unit_generator ************** //
|
||
|
// ************************************************************************** //
|
||
|
|
||
|
class BOOST_TEST_DECL test_unit_generator {
|
||
|
public:
|
||
|
virtual test_unit* next() const = 0;
|
||
|
|
||
|
protected:
|
||
|
BOOST_TEST_PROTECTED_VIRTUAL ~test_unit_generator() {}
|
||
|
};
|
||
|
|
||
|
// ************************************************************************** //
|
||
|
// ************** test_case ************** //
|
||
|
// ************************************************************************** //
|
||
|
|
||
|
class BOOST_TEST_DECL test_case : public test_unit {
|
||
|
public:
|
||
|
enum { type = TUT_CASE };
|
||
|
|
||
|
// Constructor
|
||
|
test_case( const_string tc_name, boost::function<void ()> const& test_func );
|
||
|
test_case( const_string tc_name, const_string tc_file, std::size_t tc_line, boost::function<void ()> const& test_func );
|
||
|
|
||
|
// Public property
|
||
|
typedef BOOST_READONLY_PROPERTY(boost::function<void ()>,(test_case)) test_func;
|
||
|
|
||
|
test_func p_test_func;
|
||
|
|
||
|
private:
|
||
|
friend class framework::state;
|
||
|
~test_case() {}
|
||
|
};
|
||
|
|
||
|
// ************************************************************************** //
|
||
|
// ************** test_suite ************** //
|
||
|
// ************************************************************************** //
|
||
|
|
||
|
//! Class representing test suites
|
||
|
class BOOST_TEST_DECL test_suite : public test_unit {
|
||
|
public:
|
||
|
enum { type = TUT_SUITE };
|
||
|
|
||
|
// Constructor
|
||
|
explicit test_suite( const_string ts_name, const_string ts_file, std::size_t ts_line );
|
||
|
|
||
|
// test unit list management
|
||
|
|
||
|
/*!@brief Adds a test unit to a test suite.
|
||
|
*
|
||
|
* It is possible to specify the timeout and the expected failures.
|
||
|
*/
|
||
|
void add( test_unit* tu, counter_t expected_failures = 0, unsigned timeout = 0 );
|
||
|
|
||
|
/// @overload
|
||
|
void add( test_unit_generator const& gen, unsigned timeout = 0 );
|
||
|
|
||
|
/// @overload
|
||
|
void add( test_unit_generator const& gen, decorator::collector& decorators );
|
||
|
|
||
|
//! Removes a test from the test suite.
|
||
|
void remove( test_unit_id id );
|
||
|
|
||
|
|
||
|
// access methods
|
||
|
test_unit_id get( const_string tu_name ) const;
|
||
|
std::size_t size() const { return m_children.size(); }
|
||
|
|
||
|
protected:
|
||
|
// Master test suite constructor
|
||
|
explicit test_suite( const_string module_name );
|
||
|
|
||
|
friend BOOST_TEST_DECL
|
||
|
void traverse_test_tree( test_suite const&, test_tree_visitor&, bool );
|
||
|
friend class framework::state;
|
||
|
virtual ~test_suite() {}
|
||
|
|
||
|
typedef std::multimap<counter_t,test_unit_id> children_per_rank;
|
||
|
// Data members
|
||
|
|
||
|
test_unit_id_list m_children;
|
||
|
children_per_rank m_ranked_children; ///< maps child sibling rank to list of children with that rank
|
||
|
};
|
||
|
|
||
|
// ************************************************************************** //
|
||
|
// ************** master_test_suite ************** //
|
||
|
// ************************************************************************** //
|
||
|
|
||
|
class BOOST_TEST_DECL master_test_suite_t : public test_suite {
|
||
|
public:
|
||
|
master_test_suite_t();
|
||
|
|
||
|
// Data members
|
||
|
int argc;
|
||
|
char** argv;
|
||
|
};
|
||
|
|
||
|
// ************************************************************************** //
|
||
|
// ************** user_tc_method_invoker ************** //
|
||
|
// ************************************************************************** //
|
||
|
|
||
|
namespace ut_detail {
|
||
|
|
||
|
BOOST_TEST_DECL std::string normalize_test_case_name( const_string tu_name );
|
||
|
|
||
|
//____________________________________________________________________________//
|
||
|
|
||
|
template<typename InstanceType,typename UserTestCase>
|
||
|
struct user_tc_method_invoker {
|
||
|
typedef void (UserTestCase::*TestMethod )();
|
||
|
|
||
|
user_tc_method_invoker( shared_ptr<InstanceType> inst, TestMethod test_method )
|
||
|
: m_inst( inst ), m_test_method( test_method ) {}
|
||
|
|
||
|
void operator()() { ((*m_inst).*m_test_method)(); }
|
||
|
|
||
|
shared_ptr<InstanceType> m_inst;
|
||
|
TestMethod m_test_method;
|
||
|
};
|
||
|
|
||
|
} // namespace ut_detail
|
||
|
|
||
|
// ************************************************************************** //
|
||
|
// ************** make_test_case ************** //
|
||
|
// ************************************************************************** //
|
||
|
|
||
|
inline test_case*
|
||
|
make_test_case( boost::function<void ()> const& test_func, const_string tc_name, const_string tc_file, std::size_t tc_line )
|
||
|
{
|
||
|
return new test_case( ut_detail::normalize_test_case_name( tc_name ), tc_file, tc_line, test_func );
|
||
|
}
|
||
|
|
||
|
//____________________________________________________________________________//
|
||
|
|
||
|
template<typename UserTestCase, typename InstanceType>
|
||
|
inline test_case*
|
||
|
make_test_case( void (UserTestCase::* test_method )(),
|
||
|
const_string tc_name,
|
||
|
const_string tc_file,
|
||
|
std::size_t tc_line,
|
||
|
boost::shared_ptr<InstanceType> user_test_case )
|
||
|
{
|
||
|
return new test_case( ut_detail::normalize_test_case_name( tc_name ),
|
||
|
tc_file,
|
||
|
tc_line,
|
||
|
ut_detail::user_tc_method_invoker<InstanceType,UserTestCase>( user_test_case, test_method ) );
|
||
|
}
|
||
|
|
||
|
//____________________________________________________________________________//
|
||
|
|
||
|
} // namespace unit_test
|
||
|
} // namespace boost
|
||
|
|
||
|
#include <boost/test/detail/enable_warnings.hpp>
|
||
|
|
||
|
#endif // BOOST_TEST_TREE_TEST_UNIT_HPP_100211GER
|