root/lang/objective-cplusplus/i3/trunk/src/mil/include/quicktest/quicktest.h @ 34940

Revision 34940, 10.3 kB (checked in by saturday06, 4 years ago)

pass

  • Property svn:executable set to *
Line 
1/************************************************************************
2* QuickTest                                                             *
3* http://quicktest.sourceforge.net                                      *
4* Copyright (C) 2005-2008                                               *
5* Tyler Streeter (http://www.tylerstreeter.net)                         *
6*                                                                       *
7* This library is free software; you can redistribute it and/or         *
8* modify it under the terms of EITHER:                                  *
9*   (1) The GNU Lesser General Public License as published by the Free  *
10*       Software Foundation; either version 2.1 of the License, or (at  *
11*       your option) any later version. The text of the GNU Lesser      *
12*       General Public License is included with this library in the     *
13*       file license-LGPL.txt.                                          *
14*   (2) The BSD-style license that is included with this library in     *
15*       the file license-BSD.txt.                                       *
16*                                                                       *
17* This library is distributed in the hope that it will be useful,       *
18* but WITHOUT ANY WARRANTY; without even the implied warranty of        *
19* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
20* license-LGPL.txt and license-BSD.txt for more details.                *
21************************************************************************/
22
23// Please visit the project website (http://quicktest.sourceforge.net)
24// for usage instructions.
25
26// Credits:
27// Thanks to Noel Llopis for his helpful comparison of various C++ unit
28// testing frameworks and ideas for an ideal simple testing framework:
29// http://www.gamesfromwithin.com/articles/0412/000061.html  Thanks to
30// Michael Feathers for developing CppUnitLite.  Many of the macros in
31// Quicktest were modeled after those in CppUnitLite.
32
33#ifndef QUICK_TEST_H
34#define QUICK_TEST_H
35
36#include <string>
37#include <sstream>
38#include <vector>
39#include <iostream>
40
41// -----------------------------------------------------------------------
42// Design Notes
43// -----------------------------------------------------------------------
44// * Each test automatically registers itself by accessing the TestManager
45// singleton.
46//
47// * There are no formal fixtures.  Fixtures are simply user-defined
48// objects.  setup and teardown occur in the user-defined object's
49// constructor and destructor.  Tests that need fixtures should staticly
50// allocate one of these objects at the beginning of the test.  This method
51// is flexible and conceptually simple.
52
53namespace quicktest {
54typedef std::vector<std::string> TestResult;
55
56class Test {
57public:
58    Test(const std::string& testName) {
59        mTestName = testName;
60    }
61
62    virtual void run(TestResult& result) = 0;
63
64public:
65    void recordFailure(TestResult& result, const std::string& file,
66                       unsigned long int line, const std::string& message) {
67        // If the full filename is too long, only use the last part.
68        std::string fileStr = file;
69        size_t maxLength = 40;
70        size_t fileLength = file.size();
71        if (fileLength > maxLength) {
72            // Get the last maxLength characters - 3 (leave room for
73            // three ellipses at the beginning).
74            fileStr = "...";
75            fileStr += file.substr(fileLength - maxLength + 3,
76                                   fileLength - 1);
77        }
78
79        std::ostringstream oss;
80        oss << fileStr << "(" << line << "): '" << mTestName
81        << "' FAILED: " << message;
82                std::cout << oss.str() << std::endl << std::flush;
83        result.push_back(oss.str());
84    }
85
86protected:
87    /// The unique name of this test.
88    std::string mTestName;
89};
90
91class TestManager {
92public:
93    ///
94    static Test* currentTest;
95    static TestResult* currentResult;
96    ///
97
98    static TestManager& instance() {
99        static TestManager self;
100        return self;
101    }
102
103    void addTest(Test* test) {
104        mTests.push_back(test);
105    }
106
107    void setOutputStream(std::ostream* stream) {
108        mOutputStream = stream;
109    }
110
111    std::ostream* getOutputStream() {
112        return mOutputStream;
113    }
114
115    void runTests() {
116        unsigned int numFailures = 0;
117
118        *getOutputStream()
119        << "[-------------- RUNNING UNIT TESTS --------------]"
120        << std::endl;
121
122        std::vector<Test*>::iterator iter;
123        for (iter = mTests.begin(); iter != mTests.end(); ++iter) {
124            currentTest = *iter;
125            currentResult = &mResult;
126            (*iter)->run(mResult);
127
128            bool testFailed = false;
129
130            size_t size = mResult.size();
131            for (size_t i = 0; i < size; ++i) {
132                //*getOutputStream() << mResult.at(i) << std::endl;
133                testFailed = true;
134            }
135            mResult.clear();
136
137            if (testFailed) {
138                ++numFailures;
139            }
140        }
141
142        *getOutputStream() << "Results: " << (unsigned int)mTests.size()
143        - numFailures << " succeeded, " << numFailures << " failed"
144        << std::endl;
145
146        *getOutputStream()
147        << "[-------------- UNIT TESTS FINISHED -------------]"
148        << std::endl;
149
150        if (numFailures == 0) {
151            std::cerr << std::endl << "*** No errors detected" << std::endl;
152        }
153    }
154
155private:
156    TestManager() {
157        currentTest = NULL;
158        currentResult = NULL;
159        mOutputStream = &std::cout;
160    }
161
162    ~TestManager() {
163    }
164
165    /// List of pointers to Tests.  All tests are staticly allocated,
166    /// so we don't need to destroy them manually.
167    std::vector<Test*> mTests;
168
169    std::ostream* mOutputStream;
170
171    TestResult mResult;
172};
173}
174
175/// Macro to define a single test without using a fixture.
176#define QT_TEST(testName)\
177        class testName##Test : public quicktest::Test\
178        {\
179        public:\
180                testName##Test()\
181                : Test(#testName)\
182                {\
183                        quicktest::TestManager::instance().addTest(this);\
184                }\
185                void run(quicktest::TestResult& result);\
186        }testName##Instance;\
187        void testName##Test::run(quicktest::TestResult& result)
188
189/// Macro that runs all tests.
190#define QT_RUN_TESTS quicktest::TestManager::instance().runTests()
191
192/// Macro that sets the output stream to use.
193#define QT_SET_OUTPUT(stream)\
194        quicktest::TestManager::instance().setOutputStream(stream)
195
196/// Checks whether the given condition is true.
197#define QT_CHECK(condition)\
198        {\
199                if (!(condition))\
200                {\
201                        quicktest::TestManager::currentTest->recordFailure(*quicktest::TestManager::currentResult, __FILE__, __LINE__, #condition);\
202                }\
203        }
204
205/// Checks whether the first parameter is equal to the second.
206#define QT_CHECK_EQUAL(value1, value2)\
207        {\
208                if ((value1) != (value2))\
209                {\
210                        std::ostringstream oss;\
211                        oss << "value1 (" << (value1) << ") should equal "\
212                                << "value2 (" << (value2) << ")";\
213                        quicktest::TestManager::currentTest->recordFailure(*quicktest::TestManager::currentResult, __FILE__, __LINE__, oss.str());\
214                }\
215        }
216
217/// Checks whether the first parameter is not equal to the second.
218#define QT_CHECK_NOT_EQUAL(value1, value2)\
219        {\
220                if ((value1) == (value2))\
221                {\
222                        std::ostringstream oss;\
223                        oss << "value1 (" << (value1) << ") should not equal "\
224                                << "value2 (" << (value2) << ")";\
225                        quicktest::TestManager::currentTest->recordFailure(*quicktest::TestManager::currentResult, __FILE__, __LINE__, oss.str());\
226                }\
227        }
228
229/// Checks whether the first parameter is within the given tolerance from
230/// the second parameter.  This is useful for comparing floating point
231/// values.
232#define QT_CHECK_CLOSE(value1, value2, tolerance)\
233        {\
234                double tempValue1 = (double)(value1);\
235                double tempValue2 = (double)(value2);\
236                if (fabs((tempValue1)-(tempValue2)) > tolerance)\
237                {\
238                        std::ostringstream oss;\
239                        oss << "value1 (" << (value1) << ") should be close to "\
240                                << "value2 (" << (value2) << ")";\
241                        quicktest::TestManager::currentTest->recordFailure(*quicktest::TestManager::currentResult, __FILE__, __LINE__, oss.str());\
242                }\
243        }
244
245/// Checks whether the first parameter is less than the second.
246#define QT_CHECK_LESS(value1, value2)\
247        {\
248                if ((value1) >= (value2))\
249                {\
250                        std::ostringstream oss;\
251                        oss << "value1 (" << (value1) << ") should be less than "\
252                                << "value2 (" << (value2) << ")";\
253                        quicktest::TestManager::currentTest->recordFailure(*quicktest::TestManager::currentResult, __FILE__, __LINE__, oss.str());\
254                }\
255        }
256
257/// Checks whether the first parameter is less than or equal to the second.
258#define QT_CHECK_LESS_OR_EQUAL(value1, value2)\
259        {\
260                if ((value1) > (value2))\
261                {\
262                        std::ostringstream oss;\
263                        oss << "value1 (" << (value1) << ") should be less than or "\
264                                << "equal to " << "value2 (" << (value2) << ")";\
265                        quicktest::TestManager::currentTest->recordFailure(*quicktest::TestManager::currentResult, __FILE__, __LINE__, oss.str());\
266                }\
267        }
268
269/// Checks whether the first parameter is greater than the second.
270#define QT_CHECK_GREATER(value1, value2)\
271        {\
272                if ((value1) <= (value2))\
273                {\
274                        std::ostringstream oss;\
275                        oss << "value1 (" << (value1) << ") should be greater than "\
276                                << "value2 (" << (value2) << ")";\
277                        quicktest::TestManager::currentTest->recordFailure(*quicktest::TestManager::currentResult, __FILE__, __LINE__, oss.str());\
278                }\
279        }
280
281/// Checks whether the first parameter is greater than or equal to the
282/// second.
283#define QT_CHECK_GREATER_OR_EQUAL(value1, value2)\
284        {\
285                if ((value1) < (value2))\
286                {\
287                        std::ostringstream oss;\
288                        oss << "value1 (" << (value1) << ") should be greater than or "\
289                                << "equal to " << "value2 (" << (value2) << ")";\
290                        quicktest::TestManager::currentTest->recordFailure(*quicktest::TestManager::currentResult, __FILE__, __LINE__, oss.str());\
291                }\
292        }
293
294/// Fails unconditionally and prints the given message.
295#define QT_FAIL(message)\
296        {\
297                quicktest::TestManager::currentTest->recordFailure(*quicktest::TestManager::currentResult, __FILE__, __LINE__, (message));\
298        }\
299 
300/// Prints the given message.
301#define QT_PRINT(message)\
302        {\
303                *(quicktest::TestManager::instance().getOutputStream()) << (message)\
304                        << std::flush;\
305        }\
306 
307#endif
Note: See TracBrowser for help on using the browser.