1. 程式人生 > >Boost中Core模組的lightweight_test用法

Boost中Core模組的lightweight_test用法

標頭檔案

boost/core/lightweight_test.hpp

作用

lightweight_test.hpp提供了大量的巨集定義,如下

#define BOOST_TEST(expression)                                                                           /*判斷 表示式 為真 */
#define BOOST_TEST_NOT(expression)                                                                  /*判斷 表示式 為假*/
#define BOOST_ERROR(message)                                                                             /*表示式為假,列印錯誤資訊*/
#define BOOST_TEST_EQ(expr1, expr2)                                                                   /*判斷 表示式1,表示式2,相等*/
#define BOOST_TEST_NE(expr1, expr2)                                                                    /*判斷 表示式1,表示式2,不相等*/
#define BOOST_TEST_CSTR_EQ(expr1, expr2)                                                       /*判斷 字串1,字串2,相等*/
#define BOOST_TEST_CSTR_NE(expr1, expr2)                                                        /*判斷 字串1,字串2,不相等*/
#define BOOST_TEST_ALL_EQ(begin1, end1, begin2, end2)                                  /* 判斷 [begin1, end1),[begin2,end2),每一個相等 */
#define BOOST_TEST_ALL_WITH(begin1, end1, begin2, end2, predicate)            /* 判斷 [begin1, end1),[begin2,end2),每一個符合 predicate */
#define BOOST_TEST_THROWS(expr, excep)                                                           /* 執行 expr,丟擲 excep 異常 */

舉例

BOOST_TEST測試

#include <boost/detail/lightweight_test.hpp>

int main()
{
    int x = 0;

    BOOST_TEST( x == 1 ); // will fail

    return boost::report_errors();
}

BOOST_ERROR測試

#include <boost/detail/lightweight_test.hpp>

int main()
{
    BOOST_ERROR( "expected failure" );

    return boost::report_errors();
}

BOOST_TEST_EQ測試

#include <boost/detail/lightweight_test.hpp>

int main()
{
    int x = 0;

    BOOST_TEST_EQ( x, 1 );

    return boost::report_errors();
}

BOOST_TEST_NE測試

#include <boost/detail/lightweight_test.hpp>

int main()
{
    int x = 0;

    BOOST_TEST_NE( x, 0 );

    return boost::report_errors();
}

BOOST_TEST_THROWS測試

#include <boost/detail/lightweight_test.hpp>

struct X
{
};

void f()
{
}

int main()
{
    BOOST_TEST_THROWS( f(), X );

    return boost::report_errors();
}

BOOST_TEST_TRAIT_TRUE測試

#include <boost/core/lightweight_test_trait.hpp>

template<class T1, class T2> struct Y1
{
    enum { value = 1 };
};

template<class T1, class T2> struct Y2
{
    enum { value = 0 };
};

struct X1
{
    typedef int type;
};

struct X2
{
    typedef int type;
};

int main()
{
    BOOST_TEST_TRAIT_TRUE(( Y2<X1::type, X2::type> ));

    return boost::report_errors();
}

BOOST_TEST_CSTR_EQ測試

#include <boost/core/lightweight_test.hpp>

int main()
{
    BOOST_TEST_CSTR_EQ("x" , "y");

    return boost::report_errors();
}

BOOST_TEST_TRAIT_TRUE測試

#include <boost/core/lightweight_test_trait.hpp>

template<class T1, class T2> struct Y1
{
    enum { value = 1 };
};

template<class T1, class T2> struct Y2
{
    enum { value = 0 };
};

struct X1
{
    typedef int type;
};

struct X2
{
    typedef int type;
};

int main()
{
    // BOOST_TEST_TRAIT_TRUE

    BOOST_TEST_TRAIT_TRUE(( Y1<X1::type, X2::type> ));

    // BOOST_TEST_TRAIT_FALSE

    BOOST_TEST_TRAIT_FALSE(( Y2<X1::type, X2::type> ));

    return boost::report_errors();
}

BOOST_TEST_ALL測試

#include <vector>
#include <boost/detail/lightweight_test.hpp>

struct X
{
};

#if !defined( BOOST_NO_EXCEPTIONS )
# define LWT_THROW( x ) throw x
#else
# define LWT_THROW( x ) ((void)(x))
#endif

void f( bool x )
{
    if( x )
    {
        LWT_THROW( X() );
    }
    else
    {
        LWT_THROW( 5 );
    }
}

int main()
{
    int x = 0;

    // BOOST_TEST

    BOOST_TEST( x == 0 );
    BOOST_TEST( ++x == 1 );
    BOOST_TEST( x++ == 1 );
    BOOST_TEST( x == 2? true: false );
    BOOST_TEST( x == 2? &x: 0 );
    
    // BOOST_TEST_NOT
    
    BOOST_TEST_NOT( x == 1 );
    BOOST_TEST_NOT( ++x == 2 );
    BOOST_TEST_NOT( x++ == 2 );
    BOOST_TEST_NOT( --x == 2 );
    BOOST_TEST_NOT( x-- == 2 );
    BOOST_TEST_NOT( x == 2? false: true );
    BOOST_TEST_NOT( x == 2? 0: &x );

    // BOOST_TEST_EQ

    BOOST_TEST_EQ( x, 2 );
    BOOST_TEST_EQ( ++x, 3 );
    BOOST_TEST_EQ( x++, 3 );

    int y = 4;

    BOOST_TEST_EQ( ++x, ++y );
    BOOST_TEST_EQ( x++, y++ );
    BOOST_TEST_CSTR_EQ("xabc"+1, "yabc"+1); // equal cstrings, different addresses
    BOOST_TEST_EQ( &y, &y );

    // BOOST_TEST_NE

    BOOST_TEST_NE( ++x, y );
    BOOST_TEST_NE( &x, &y );
    BOOST_TEST_NE("xabc"+1, "yabc"+1); // equal cstrings, different addresses
    BOOST_TEST_CSTR_NE("x", "y");

    // BOOST_TEST_ALL_EQ
    {
        std::vector<int> xarray;
        xarray.push_back(1);
        xarray.push_back(2);
        std::vector<int> yarray(xarray);
        BOOST_TEST_ALL_EQ(xarray.begin(), xarray.end(), yarray.begin(), yarray.end());
    }

    // BOOST_TEST_THROWS

    BOOST_TEST_THROWS( throw X(), X );
    BOOST_TEST_THROWS( throw 1, int );

    BOOST_TEST_THROWS( f(true), X );
    BOOST_TEST_THROWS( f(false), int );

    return boost::report_errors();
}

BOOST_TEST_ALL_EQ測試

#include <vector>
#include <set>
#include <boost/core/lightweight_test.hpp>

int main()
{
    int test_cases = 0;

    // Array

    {
        int x[] = { 1 };
        int y[] = { 1, 2 };
        BOOST_TEST_ALL_EQ( x, x + sizeof(x)/sizeof(x[0]), y, y + sizeof(y)/sizeof(y[0]) );
        ++test_cases;
    }

    {
        int x[] = { 1, 2 };
        int y[] = { 1 };
        BOOST_TEST_ALL_EQ( x, x + sizeof(x)/sizeof(x[0]), y, y + sizeof(y)/sizeof(y[0]) );
        ++test_cases;
    }

    {
        int x[] = { 2 };
        int y[] = { 1, 2 };
        BOOST_TEST_ALL_EQ( x, x + sizeof(x)/sizeof(x[0]), y, y + sizeof(y)/sizeof(y[0]) );
        ++test_cases;
    }

    {
        int x[] = { 1, 2, 3, 4 };
        int y[] = { 1, 3, 2, 4 };
        BOOST_TEST_ALL_EQ( x, x + sizeof(x)/sizeof(x[0]), y, y + sizeof(y)/sizeof(y[0]) );
        ++test_cases;
    }

    // Vector

    {
        std::vector<int> x, y;
        x.push_back( 1 );
        BOOST_TEST_ALL_EQ( x.begin(), x.end(), y.begin(), y.end() );
        ++test_cases;
    }

    {
        std::vector<int> x, y;
        y.push_back( 1 );
        BOOST_TEST_ALL_EQ( x.begin(), x.end(), y.begin(), y.end() );
        ++test_cases;
    }

    {
        std::vector<int> x, y;
        x.push_back( 1 ); x.push_back( 2 ); x.push_back( 3 ); x.push_back( 4 );
        y.push_back( 1 ); y.push_back( 3 ); y.push_back( 2 ); y.push_back( 4 );
        BOOST_TEST_ALL_EQ( x.begin(), x.end(), y.begin(), y.end() );
        ++test_cases;
    }

    {
        std::vector<float> x, y;
        x.push_back( 1.0f ); x.push_back( 2.0f ); x.push_back( 3.0f ); x.push_back( 4.0f );
        y.push_back( 4.0f ); y.push_back( 2.0f ); y.push_back( 3.0f ); y.push_back( 1.0f );
        BOOST_TEST_ALL_EQ( x.begin(), x.end(), y.begin(), y.end() );
        ++test_cases;
    }

    {
        std::vector<int> x, y;
        x.push_back( 1 ); x.push_back( 2 ); x.push_back( 3 );
        y.push_back( 1 ); y.push_back( 3 ); y.push_back( 2 ); y.push_back( 4 );
        BOOST_TEST_ALL_EQ( x.begin(), x.end(), y.begin(), y.end() );
        ++test_cases;
    }

    {
        std::vector<int> x, y;
        x.push_back( 1 ); x.push_back( 2 ); x.push_back( 3 ); x.push_back( 4 );
        y.push_back( 1 ); y.push_back( 3 ); y.push_back( 2 );;
        BOOST_TEST_ALL_EQ( x.begin(), x.end(), y.begin(), y.end() );
        ++test_cases;
    }

    // Set

    {
        std::set<int> x, y;
        x.insert(1);
        y.insert(1); y.insert(3);
        BOOST_TEST_ALL_EQ( x.begin(), x.end(), y.begin(), y.end() );
        ++test_cases;
    }

    {
        std::set<int> x, y;
        x.insert(1); x.insert(2);
        y.insert(1);
        BOOST_TEST_ALL_EQ( x.begin(), x.end(), y.begin(), y.end() );
        ++test_cases;
    }

    {
        std::set<int> x, y;
        x.insert(1); x.insert(2);
        y.insert(1); y.insert(3);
        BOOST_TEST_ALL_EQ( x.begin(), x.end(), y.begin(), y.end() );
        ++test_cases;
    }

    boost::report_errors();

    return boost::detail::test_errors() != test_cases;
}

test_all_with_test測試

#include <cmath>
#include <functional>
#include <vector>
#include <boost/core/lightweight_test.hpp>

void test_vector()
{
    {
        std::vector<int> x, y;
        x.push_back( 1 ); x.push_back( 2 ); x.push_back( 3 ); x.push_back( 4 );
        y.push_back( 1 ); y.push_back( 2 ); y.push_back( 3 ); y.push_back( 4 );
        BOOST_TEST_ALL_WITH( x.begin(), x.end(), y.begin(), y.end(), std::equal_to<int>() );
    }

    {
        std::vector<int> x, y;
        x.push_back( 1 ); x.push_back( 2 ); x.push_back( 3 ); x.push_back( 4 );
        y.push_back( 2 ); y.push_back( 3 ); y.push_back( 4 ); y.push_back( 5 );
        BOOST_TEST_ALL_WITH( x.begin(), x.end(), y.begin(), y.end(), std::not_equal_to<int>() );
    }

    {
        std::vector<int> x, y;
        x.push_back( 1 ); x.push_back( 2 ); x.push_back( 3 ); x.push_back( 4 );
        y.push_back( 2 ); y.push_back( 3 ); y.push_back( 4 ); y.push_back( 5 );
        BOOST_TEST_ALL_WITH( x.begin(), x.end(), y.begin(), y.end(), std::less<int>() );
    }
}

template <typename T>
struct with_tolerance
{
    with_tolerance(T tolerance) : tolerance(tolerance) {}
    bool operator()(T lhs, T rhs)
    {
        return (std::abs(lhs - rhs) <= tolerance);
    }

private:
    T tolerance;
};

void test_tolerance_predicate()
{
    {
        std::vector<double> x, y;
        x.push_back( 1.0 ); x.push_back( 2.0 ); x.push_back( 3.0 ); x.push_back( 4.0 );
        y.push_back( 1.0 ); y.push_back( 2.0 ); y.push_back( 3.0 ); y.push_back( 4.0 );
        BOOST_TEST_ALL_WITH( x.begin(), x.end(), y.begin(), y.end(), with_tolerance<double>(1e-5) );
    }

    {
        std::vector<double> x, y;
        x.push_back( 1.0 ); x.push_back( 1.0 );
        y.push_back( 1.0 - 1e-6 ); y.push_back( 1.0 + 1e-6 );
        BOOST_TEST_ALL_WITH( x.begin(), x.end(), y.begin(), y.end(), with_tolerance<double>(1e-5) );
    }
}

int main()
{
    test_vector();
    test_tolerance_predicate();

    return boost::report_errors();
}

BOOST_TEST_ALL_WITH fail測試

#include <cmath>
#include <functional>
#include <vector>
#include <boost/core/lightweight_test.hpp>

int fail_vector()
{
    int test_cases = 0;

    {
        std::vector<int> x, y;
        x.push_back( 1 );
        BOOST_TEST_ALL_WITH( x.begin(), x.end(), y.begin(), y.end(), std::equal_to<int>() );
        ++test_cases;
    }

    {
        std::vector<int> x, y;
        y.push_back( 1 );
        BOOST_TEST_ALL_WITH( x.begin(), x.end(), y.begin(), y.end(), std::equal_to<int>() );
        ++test_cases;
    }

    {
        std::vector<int> x, y;
        x.push_back( 1 ); x.push_back( 2 ); x.push_back( 3 ); x.push_back( 4 );
        y.push_back( 1 ); y.push_back( 2 ); y.push_back( 3 );
        BOOST_TEST_ALL_WITH( x.begin(), x.end(), y.begin(), y.end(), std::equal_to<int>() );
        ++test_cases;
    }

    {
        std::vector<int> x, y;
        x.push_back( 1 ); x.push_back( 2 ); x.push_back( 3 );
        y.push_back( 1 ); y.push_back( 2 ); y.push_back( 3 ); y.push_back( 4 );
        BOOST_TEST_ALL_WITH( x.begin(), x.end(), y.begin(), y.end(), std::equal_to<int>() );
        ++test_cases;
    }

    {
        std::vector<int> x, y;
        x.push_back( 1 ); x.push_back( 2 ); x.push_back( 3 ); x.push_back( 4 );
        y.push_back( 1 ); y.push_back( 3 ); y.push_back( 2 ); y.push_back( 4 );
        BOOST_TEST_ALL_WITH( x.begin(), x.end(), y.begin(), y.end(), std::equal_to<int>() );
        ++test_cases;
    }

    {
        std::vector<int> x, y;
        x.push_back( 1 ); x.push_back( 2 ); x.push_back( 3 ); x.push_back( 4 );
        y.push_back( 1 ); y.push_back( 3 ); y.push_back( 2 ); y.push_back( 4 );
        BOOST_TEST_ALL_WITH( x.begin(), x.end(), y.begin(), y.end(), std::less<int>() );
        ++test_cases;
    }

    return test_cases;
}

template <typename T>
struct with_tolerance
{
    with_tolerance(T tolerance) : tolerance(tolerance) {}
    bool operator()(T lhs, T rhs)
    {
        return (std::abs(lhs - rhs) <= tolerance);
    }

private:
    T tolerance;
};

int fail_tolerance_predicate()
{
    int test_cases = 0;

    {
        std::vector<double> x, y;
        x.push_back( 1.0 ); x.push_back( 1.0 );
        y.push_back( 1.0 - 1e-4 ); y.push_back( 1.0 + 1e-4 );
        BOOST_TEST_ALL_WITH( x.begin(), x.end(), y.begin(), y.end(), with_tolerance<double>(1e-5) );
        ++test_cases;
    }

    return test_cases;
}

int main()
{
    int test_cases = 0;

    test_cases += fail_vector();
    test_cases += fail_tolerance_predicate();

    boost::report_errors();

    return boost::detail::test_errors() != test_cases;
}

原始碼

原始碼太複雜,省略。。。