Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/test/example/unit_test_example5.cpp @ 20

Last change on this file since 20 was 12, checked in by landauf, 17 years ago

added boost

File size: 5.7 KB
Line 
1//  (C) Copyright Gennadiy Rozental 2001-2005.
2//  Distributed under the Boost Software License, Version 1.0.
3//  (See accompanying file LICENSE_1_0.txt or copy at
4//  http://www.boost.org/LICENSE_1_0.txt)
5
6//  See http://www.boost.org/libs/test for the library home page.
7
8// Boost.Test
9#include <boost/test/unit_test.hpp>
10#include <boost/test/floating_point_comparison.hpp>
11#include <boost/test/parameterized_test.hpp>
12using boost::unit_test::test_suite;
13
14// BOOST
15#include <boost/functional.hpp>
16#include <boost/static_assert.hpp>
17#include <boost/mem_fn.hpp>
18#include <boost/bind.hpp>
19
20// STL
21#include <string>
22#include <stdexcept>
23#include <algorithm>
24#include <functional>
25#include <iostream>
26#include <memory>
27#include <list>
28
29//____________________________________________________________________________//
30
31template<int n>
32struct pow10 {
33    BOOST_STATIC_CONSTANT( unsigned long, value = 10*pow10<n-1>::value );
34};
35
36template<>
37struct pow10<0> {
38    BOOST_STATIC_CONSTANT( unsigned long, value = 1 );
39};
40
41//____________________________________________________________________________//
42
43template<int AlphabetSize>
44class hash_function {
45public:
46    BOOST_STATIC_ASSERT( AlphabetSize <= 5 );
47
48    explicit        hash_function( std::string const& alphabet )
49    : m_alphabet( alphabet )
50    {
51        if( m_alphabet.size() != AlphabetSize )
52            throw std::runtime_error( "Wrong alphabet size" );
53
54        std::sort( m_alphabet.begin(), m_alphabet.end() );
55
56        if( std::adjacent_find( m_alphabet.begin(), m_alphabet.end() ) != m_alphabet.end() )
57            throw std::logic_error( "Duplicate characters in alphabet" );
58    }
59
60    unsigned long   operator()( std::string const& arg )
61    {
62        m_result = 0;
63
64        if( arg.length() > 8 )
65            throw std::runtime_error( "Wrong argument size" );
66
67        std::string::const_iterator it = std::find_if( arg.begin(), arg.end(), 
68                                                       std::bind1st( boost::mem_fun( &hash_function::helper_ ), this ) );
69
70        if( it != arg.end() )
71            throw std::out_of_range( std::string( "Invalid character " ) + *it );
72
73        return m_result;
74    }
75
76private:
77    bool            helper_( char c )
78    {       
79        std::string::const_iterator it = std::find( m_alphabet.begin(), m_alphabet.end(), c );
80       
81        if( it == m_alphabet.end() )
82            return true;
83
84        m_result += pow10_( it - m_alphabet.begin() );
85
86        return false;
87    }
88
89    unsigned long   pow10_( int i ) {
90        switch( i ) {
91        case 0: return pow10<0>::value;
92        case 1: return pow10<1>::value;
93        case 2: return pow10<2>::value;
94        case 3: return pow10<3>::value;
95        case 4: return pow10<4>::value;
96        default: return 0;
97        }
98    }
99
100    // Data members
101    std::string     m_alphabet;
102    unsigned long   m_result;
103};
104
105//____________________________________________________________________________//
106
107struct hash_function_test_data {
108    std::string     orig_string;
109    unsigned long   exp_value;
110
111    friend std::istream& operator>>( std::istream& istr, hash_function_test_data& test_data )
112    {
113        std::istream& tmp = istr >> test_data.orig_string;
114        return  !tmp ? tmp : istr >> test_data.exp_value;
115    }
116};
117
118//____________________________________________________________________________//
119
120class hash_function_tester {
121public:
122    explicit        hash_function_tester( std::string const& alphabet )
123    : m_function_under_test( alphabet ) {}
124
125    void            test( hash_function_test_data const& test_data )
126    {
127        if( test_data.exp_value == (unsigned long)-1 )
128            BOOST_CHECK_THROW( m_function_under_test( test_data.orig_string ), std::runtime_error )
129        else if( test_data.exp_value == (unsigned long)-2 )
130            BOOST_CHECK_THROW( m_function_under_test( test_data.orig_string ), std::out_of_range )
131        else {
132            BOOST_MESSAGE( "Testing: " << test_data.orig_string );
133            BOOST_CHECK_EQUAL( m_function_under_test( test_data.orig_string ), test_data.exp_value );
134        }
135    }
136
137private:
138    hash_function<4> m_function_under_test;
139};
140
141//____________________________________________________________________________//
142
143struct massive_hash_function_test : test_suite {
144    massive_hash_function_test() {
145        std::string alphabet;
146        std::cout << "Enter alphabet (4 characters without delimeters)\n";
147        std::cin >> alphabet;
148
149        boost::shared_ptr<hash_function_tester> instance( new hash_function_tester( alphabet ) );
150
151        std::cout << "\nEnter test data in a format [string] [value] to check correct calculation\n";
152        std::cout << "Enter test data in a format [string] -1 to check long string validation\n";
153        std::cout << "Enter test data in a format [string] -2 to check invalid argument string validation\n";
154
155        std::list<hash_function_test_data> test_data_store;
156
157        while( !std::cin.eof() ) {
158            hash_function_test_data test_data;
159           
160            if( !(std::cin >> test_data) )
161                break;
162
163            test_data_store.push_back( test_data );
164        }
165
166        add( BOOST_PARAM_CLASS_TEST_CASE( &hash_function_tester::test, instance, test_data_store.begin(), test_data_store.end() ) );
167    }
168};
169
170//____________________________________________________________________________//
171
172test_suite*
173init_unit_test_suite( int argc, char * argv[] ) {
174    test_suite* test( BOOST_TEST_SUITE( "Unit test example 5" ) );
175 
176    try  {
177        test->add( new massive_hash_function_test );
178    } catch( std::logic_error const& ex ) {
179        std::cout << "Test suite fail to create instance of hash function: " << ex.what() << std::endl;
180
181        return (test_suite*)0;
182    }
183
184    return test; 
185}
186
187//____________________________________________________________________________//
188
189// EOF
Note: See TracBrowser for help on using the repository browser.