boost/test/tree/decorator.hpp
// (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 : $RCSfile$
//
// Version : $Revision: 62016 $
//
// Description : defines decorators to be using with auto registered test units
// ***************************************************************************
#ifndef BOOST_TEST_TREE_DECORATOR_HPP_091911GER
#define BOOST_TEST_TREE_DECORATOR_HPP_091911GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/tree/fixture.hpp>
#include <boost/test/tools/assertion_result.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
// Boost
#include <boost/shared_ptr.hpp>
#include <boost/function/function0.hpp>
#include <boost/function/function1.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
// STL
#include <vector>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
class test_unit;
namespace decorator {
// ************************************************************************** //
// ************** decorator::collector_t ************** //
// ************************************************************************** //
class base;
typedef boost::shared_ptr<base> base_ptr;
class BOOST_TEST_DECL collector_t {
public:
collector_t& operator*( base const& d );
void store_in( test_unit& tu );
void reset();
void stack();
std::vector<base_ptr> get_lazy_decorators() const;
// singleton pattern without ctor
BOOST_TEST_SINGLETON_CONS_NO_CTOR( collector_t )
private:
// Class invariant: minimal size is 1.
collector_t() : m_tu_decorators_stack(1) {}
// Data members
std::vector< std::vector<base_ptr> > m_tu_decorators_stack;
};
// ************************************************************************** //
// ************** decorator::base ************** //
// ************************************************************************** //
class BOOST_TEST_DECL base {
public:
// composition interface
virtual collector_t& operator*() const;
// application interface
virtual void apply( test_unit& tu ) = 0;
// deep cloning interface
virtual base_ptr clone() const = 0;
protected:
virtual ~base() {}
};
// ************************************************************************** //
// ************** decorator::stack_decorator ************** //
// ************************************************************************** //
//!@ A decorator that creates a new stack in the collector
//!
//! This decorator may be used in places where the currently accumulated decorators
//! in the collector should be applied to lower levels of the hierarchy rather
//! than the current one. This is for instance for dataset test cases, where the
//! macro does not let the user specify decorators for the underlying generated tests
//! (but rather on the main generator function), applying the stack_decorator at the
//! parent level lets us consume the decorator at the underlying test cases level.
class BOOST_TEST_DECL stack_decorator : public decorator::base {
public:
explicit stack_decorator() {}
virtual collector_t& operator*() const;
private:
// decorator::base interface
virtual void apply( test_unit& tu );
virtual base_ptr clone() const { return base_ptr(new stack_decorator()); }
};
// ************************************************************************** //
// ************** decorator::label ************** //
// ************************************************************************** //
class BOOST_TEST_DECL label : public decorator::base {
public:
explicit label( const_string l ) : m_label( l ) {}
private:
// decorator::base interface
virtual void apply( test_unit& tu );
virtual base_ptr clone() const { return base_ptr(new label( m_label )); }
// Data members
const_string m_label;
};
// ************************************************************************** //
// ************** decorator::expected_failures ************** //
// ************************************************************************** //
class BOOST_TEST_DECL expected_failures : public decorator::base {
public:
explicit expected_failures( counter_t ef ) : m_exp_fail( ef ) {}
private:
// decorator::base interface
virtual void apply( test_unit& tu );
virtual base_ptr clone() const { return base_ptr(new expected_failures( m_exp_fail )); }
// Data members
counter_t m_exp_fail;
};
// ************************************************************************** //
// ************** decorator::timeout ************** //
// ************************************************************************** //
class BOOST_TEST_DECL timeout : public decorator::base {
public:
explicit timeout( unsigned t ) : m_timeout( t ) {}
private:
// decorator::base interface
virtual void apply( test_unit& tu );
virtual base_ptr clone() const { return base_ptr(new timeout( m_timeout )); }
// Data members
unsigned m_timeout;
};
// ************************************************************************** //
// ************** decorator::description ************** //
// ************************************************************************** //
class BOOST_TEST_DECL description : public decorator::base {
public:
explicit description( const_string descr ) : m_description( descr ) {}
private:
// decorator::base interface
virtual void apply( test_unit& tu );
virtual base_ptr clone() const { return base_ptr(new description( m_description )); }
// Data members
const_string m_description;
};
// ************************************************************************** //
// ************** decorator::depends_on ************** //
// ************************************************************************** //
class BOOST_TEST_DECL depends_on : public decorator::base {
public:
explicit depends_on( const_string dependency ) : m_dependency( dependency ) {}
private:
// decorator::base interface
virtual void apply( test_unit& tu );
virtual base_ptr clone() const { return base_ptr(new depends_on( m_dependency )); }
// Data members
const_string m_dependency;
};
// ************************************************************************** //
// ************** decorator::enable_if/enabled/disabled ************** //
// ************************************************************************** //
class BOOST_TEST_DECL enable_if_impl : public decorator::base {
protected:
void apply_impl( test_unit& tu, bool condition );
};
template<bool condition>
class enable_if : public enable_if_impl {
private:
// decorator::base interface
virtual void apply( test_unit& tu ) { this->apply_impl( tu, condition ); }
virtual base_ptr clone() const { return base_ptr(new enable_if<condition>()); }
};
typedef enable_if<true> enabled;
typedef enable_if<false> disabled;
// ************************************************************************** //
// ************** decorator::fixture ************** //
// ************************************************************************** //
class BOOST_TEST_DECL fixture_t : public decorator::base {
public:
// Constructor
explicit fixture_t( test_unit_fixture_ptr impl ) : m_impl( impl ) {}
private:
// decorator::base interface
virtual void apply( test_unit& tu );
virtual base_ptr clone() const { return base_ptr(new fixture_t( m_impl )); }
// Data members
test_unit_fixture_ptr m_impl;
};
//____________________________________________________________________________//
template<typename F>
inline fixture_t
fixture()
{
return fixture_t( test_unit_fixture_ptr( new unit_test::class_based_fixture<F>() ) );
}
//____________________________________________________________________________//
template<typename F, typename Arg>
inline fixture_t
fixture( Arg const& arg )
{
return fixture_t( test_unit_fixture_ptr( new unit_test::class_based_fixture<F,Arg>( arg ) ) );
}
//____________________________________________________________________________//
inline fixture_t
fixture( boost::function<void()> const& setup, boost::function<void()> const& teardown = boost::function<void()>() )
{
return fixture_t( test_unit_fixture_ptr( new unit_test::function_based_fixture( setup, teardown ) ) );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** decorator::depends_on ************** //
// ************************************************************************** //
class BOOST_TEST_DECL precondition : public decorator::base {
public:
typedef boost::function<test_tools::assertion_result (test_unit_id)> predicate_t;
explicit precondition( predicate_t p ) : m_precondition( p ) {}
private:
// decorator::base interface
virtual void apply( test_unit& tu );
virtual base_ptr clone() const { return base_ptr(new precondition( m_precondition )); }
// Data members
predicate_t m_precondition;
};
} // namespace decorator
using decorator::label;
using decorator::expected_failures;
using decorator::timeout;
using decorator::description;
using decorator::depends_on;
using decorator::enable_if;
using decorator::enabled;
using decorator::disabled;
using decorator::fixture;
using decorator::precondition;
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TREE_DECORATOR_HPP_091911GER