Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/conversion/test.hpp @ 14

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

added boost

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