Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/any/test.hpp @ 12

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

added boost

File size: 7.4 KB
Line 
1// what:  simple unit test framework
2// who:   developed by Kevlin Henney
3// when:  November 2000
4// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.91
5
6#ifndef TEST_INCLUDED
7#define TEST_INCLUDED
8
9#include <boost/config.hpp>
10#include <exception>
11#include <iostream>
12#ifdef BOOST_NO_STRINGSTREAM
13#include <strstream> // for out-of-the-box g++ pre-2.95.3
14#else
15#include <sstream>
16#endif
17#include <string>
18
19namespace any_tests // test tuple comprises name and nullary function (object)
20{
21    template<typename string_type, typename function_type>
22    struct test
23    {
24        string_type   name;
25        function_type action;
26
27        static test make(string_type name, function_type action)
28        {
29            test result; // MSVC aggreggate initializer bugs
30            result.name   = name;
31            result.action = action;
32            return result;
33        }
34    };
35}
36
37namespace any_tests // failure exception used to indicate checked test failures
38{
39    class failure : public std::exception
40    {
41    public: // struction (default cases are OK)
42
43        failure(const std::string & why) throw()
44          : reason(why)
45        {
46        }
47
48              ~failure() throw() {}
49
50    public: // usage
51
52        virtual const char * what() const throw()
53        {
54            return reason.c_str();
55        }
56
57    private: // representation
58
59        std::string reason;
60
61    };
62}
63
64namespace any_tests // not_implemented exception used to mark unimplemented tests
65{
66    class not_implemented : public std::exception
67    {
68    public: // usage (default ctor and dtor are OK)
69
70        virtual const char * what() const throw()
71        {
72            return "not implemented";
73        }
74
75    };
76}
77
78namespace any_tests // test utilities
79{
80    inline void check(bool condition, const std::string & description)
81    {
82        if(!condition)
83        {
84            throw failure(description);
85        }
86    }
87
88    inline void check_true(bool value, const std::string & description)
89    {
90        check(value, "expected true: " + description);
91    }
92
93    inline void check_false(bool value, const std::string & description)
94    {
95        check(!value, "expected false: " + description);
96    }
97
98    template<typename lhs_type, typename rhs_type>
99    void check_equal(
100        const lhs_type & lhs, const rhs_type & rhs,
101        const std::string & description)
102    {
103        check(lhs == rhs, "expected equal values: " + description);
104    }
105
106    template<typename lhs_type, typename rhs_type>
107    void check_unequal(
108        const lhs_type & lhs, const rhs_type & rhs,
109        const std::string & description)
110    {
111        check(lhs != rhs, "expected unequal values: " + description);
112    }
113
114    inline void check_null(const void * ptr, const std::string & description)
115    {
116        check(!ptr, "expected null pointer: " + description);
117    }
118
119    inline void check_non_null(const void * ptr, const std::string & description)
120    {
121        check(ptr, "expected non-null pointer: " + description);
122    }
123}
124
125#define TEST_CHECK_THROW(expression, exception, description) \
126    try \
127    { \
128        expression; \
129        throw ::any_tests::failure(description); \
130    } \
131    catch(exception &) \
132    { \
133    }
134
135namespace any_tests // memory tracking (enabled if test new and delete linked in)
136{
137    class allocations
138    {
139    public: // singleton access
140
141        static allocations & instance()
142        {
143            static allocations singleton;
144            return singleton;
145        }
146
147    public: // logging
148
149        void clear()
150        {
151            alloc_count = dealloc_count = 0;
152        }
153
154        void allocation()
155        {
156            ++alloc_count;
157        }
158
159        void deallocation()
160        {
161            ++dealloc_count;
162        }
163
164    public: // reporting
165
166        unsigned long allocated() const
167        {
168            return alloc_count;
169        }
170
171        unsigned long deallocated() const
172        {
173            return dealloc_count;
174        }
175
176        bool balanced() const
177        {
178            return alloc_count == dealloc_count;
179        }
180
181    private: // structors (default dtor is fine)
182   
183        allocations()
184          : alloc_count(0), dealloc_count(0)
185        {
186        }
187
188    private: // prevention
189
190        allocations(const allocations &);
191        allocations & operator=(const allocations &);
192
193    private: // state
194
195        unsigned long alloc_count, dealloc_count;
196
197    };
198}
199
200namespace any_tests // tester is the driver class for a sequence of tests
201{
202    template<typename test_iterator>
203    class tester
204    {
205    public: // structors (default destructor is OK)
206
207        tester(test_iterator first_test, test_iterator after_last_test)
208          : begin(first_test), end(after_last_test)
209        {
210        }
211
212    public: // usage
213
214        bool operator()(); // returns true if all tests passed
215
216    private: // representation
217
218        test_iterator begin, end;
219
220    private: // prevention
221
222        tester(const tester &);
223        tester &operator=(const tester &);
224
225    };
226   
227#if defined(__GNUC__) && defined(__SGI_STL_PORT) && (__GNUC__ < 3)
228    // function scope using declarations don't work:
229    using namespace std;
230#endif
231
232    template<typename test_iterator>
233    bool tester<test_iterator>::operator()()
234    {
235        using namespace std;
236
237        unsigned long passed = 0, failed = 0, unimplemented = 0;
238
239        for(test_iterator current = begin; current != end; ++current)
240        {
241            cerr << "[" << current->name << "] " << flush;
242            string result = "passed"; // optimistic
243
244            try
245            {
246                allocations::instance().clear();
247                current->action();
248
249                if(!allocations::instance().balanced())
250                {
251                    unsigned long allocated   = allocations::instance().allocated();
252                    unsigned long deallocated = allocations::instance().deallocated();
253#ifdef BOOST_NO_STRINGSTREAM
254                    ostrstream report;
255#else
256                    ostringstream report;
257#endif
258                    report << "new/delete ("
259                           << allocated << " allocated, "
260                           << deallocated << " deallocated)"
261                           << ends;
262                    const string text = report.str();
263#ifdef BOOST_NO_STRINGSTREAM
264                    report.freeze(false);
265#endif
266                    throw failure(text);
267                }
268
269                ++passed;
270            }
271            catch(const failure & caught)
272            {
273                (result = "failed: ") += caught.what();
274                ++failed;
275            }
276            catch(const not_implemented &)
277            {
278                result = "not implemented";
279                ++unimplemented;
280            }
281            catch(const exception & caught)
282            {
283                (result = "exception: ") += caught.what();
284                ++failed;
285            }
286            catch(...)
287            {
288                result = "failed with unknown exception";
289                ++failed;
290            }
291
292            cerr << result << endl;
293        }
294
295        cerr << (passed + failed) << " tests: "
296             << passed << " passed, "
297             << failed << " failed";
298
299        if(unimplemented)
300        {
301            cerr << " (" << unimplemented << " not implemented)";
302        }
303
304        cerr << endl;
305
306        return failed == 0;
307    }
308}
309
310#endif
311
312// Copyright Kevlin Henney, 2000. All rights reserved.
313//
314// Distributed under the Boost Software License, Version 1.0. (See
315// accompanying file LICENSE_1_0.txt or copy at
316// http://www.boost.org/LICENSE_1_0.txt)
Note: See TracBrowser for help on using the repository browser.