ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/dclient/testsuite/json/jsontest.h
Revision: 1.1
Committed: Sun Oct 17 08:15:15 2010 UTC (13 years, 9 months ago) by sf-pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Log Message:
initial import

File Contents

# User Rev Content
1 sf-pippijn 1.1 #ifndef JSONTEST_H_INCLUDED
2     #define JSONTEST_H_INCLUDED
3    
4     #include <deque>
5     #include <stdio.h>
6     #include <string>
7    
8     /*
9     * //////////////////////////////////////////////////////////////////
10     * //////////////////////////////////////////////////////////////////
11     * Mini Unit Testing framework
12     * //////////////////////////////////////////////////////////////////
13     * //////////////////////////////////////////////////////////////////
14     */
15    
16    
17    
18     /** \brief Unit testing framework.
19     * \warning: all assertions are non-aborting, test case execution will continue
20     * even if an assertion namespace.
21     * This constraint is for portability: the framework needs to compile
22     * on Visual Studio 6 and must not require exception usage.
23     */
24     namespace JsonTest
25     {
26     struct Failure
27     {
28     const char *file_;
29     std::string expr_;
30     std::string message_;
31     unsigned int line_;
32     unsigned int nestingLevel_;
33     };
34    
35    
36     /*
37     * / Context used to create the assertion callstack on failure.
38     * / Must be a POD to allow inline initialisation without stepping
39     * / into the debugger.
40     */
41     struct PredicateContext
42     {
43     typedef size_t Id;
44     Id id_;
45     const char *file_;
46     size_t line_;
47     const char *expr_;
48     PredicateContext *next_;
49     /*
50     * / Related Failure, set when the PredicateContext is converted
51     * / into a Failure.
52     */
53     Failure *failure_;
54     };
55    
56     class TestResult
57     {
58     public:
59     TestResult ();
60    
61     /*
62     * / \internal Implementation detail for assertion macros
63     * / Not encapsulated to prevent step into when debugging failed assertions
64     * / Incremented by one on assertion predicate entry, decreased by one
65     * / by addPredicateContext().
66     */
67     PredicateContext::Id predicateId_;
68    
69     /* / \internal Implementation detail for predicate macros */
70     PredicateContext *predicateStackTail_;
71    
72     void setTestName (const std::string &name);
73    
74     /* / Adds an assertion failure. */
75     TestResult &addFailure (const char *file, unsigned int line, const char *expr = 0);
76    
77     /*
78     * / Removes the last PredicateContext added to the predicate stack
79     * / chained list.
80     * / Next messages will be targed at the PredicateContext that was removed.
81     */
82     TestResult &popPredicateContext ();
83    
84     bool failed () const;
85    
86     void printFailure (bool printTestName) const;
87    
88     TestResult &operator << (bool value);
89     TestResult &operator << (int value);
90     TestResult &operator << (unsigned int value);
91     TestResult &operator << (double value);
92     TestResult &operator << (const char *value);
93     TestResult &operator << (const std::string &value);
94    
95     private:
96     TestResult &addToLastFailure (const std::string &message);
97     unsigned int getAssertionNestingLevel () const;
98     /* / Adds a failure or a predicate context */
99     void addFailureInfo (const char *file, unsigned int line, const char *expr, unsigned int nestingLevel);
100     static std::string indentText (const std::string &text, const std::string &indent);
101    
102     typedef std::deque<Failure> Failures;
103     Failures failures_;
104     std::string name_;
105     PredicateContext rootPredicateNode_;
106     PredicateContext::Id lastUsedPredicateId_;
107     /* / Failure which is the target of the messages added using operator << */
108     Failure *messageTarget_;
109     };
110    
111    
112     class TestCase
113     {
114     public:
115     TestCase ();
116    
117     virtual
118     ~TestCase ();
119    
120     void run (TestResult &result);
121    
122     virtual const char *testName () const = 0;
123    
124     protected:
125     TestResult *result_;
126    
127     private:
128     virtual void runTestCase () = 0;
129     };
130    
131     /* / Function pointer type for TestCase factory */
132     typedef TestCase *(*TestCaseFactory)();
133    
134     class Runner
135     {
136     public:
137     Runner ();
138    
139     /* / Adds a test to the suite */
140     Runner &add (TestCaseFactory factory);
141    
142     /*
143     * / Runs test as specified on the command-line
144     * / If no command-line arguments are provided, run all tests.
145     * / If --list-tests is provided, then print the list of all test cases
146     * / If --test <testname> is provided, then run test testname.
147     */
148     int runCommandLine (int argc, const char *argv[]) const;
149    
150     /* / Runs all the test cases */
151     bool runAllTest (bool printSummary) const;
152    
153     /* / Returns the number of test case in the suite */
154     unsigned int testCount () const;
155    
156     /* / Returns the name of the test case at the specified index */
157     std::string testNameAt (unsigned int index) const;
158    
159     /* / Runs the test case at the specified index using the specified TestResult */
160     void runTestAt (unsigned int index, TestResult &result) const;
161    
162     static void printUsage (const char *appName);
163    
164     private:
165     /* prevents copy construction and assignment */
166     Runner (const Runner &other);
167     Runner &operator = (const Runner &other);
168    
169     private:
170     void listTests () const;
171     bool testIndex (const std::string &testName, unsigned int &index) const;
172     static void preventDialogOnCrash ();
173    
174     private:
175     typedef std::deque<TestCaseFactory> Factories;
176     Factories tests_;
177     };
178    
179     template<typename T>
180     TestResult &
181     checkEqual (TestResult &result, const T &expected, const T &actual, const char *file, unsigned int line, const char *expr)
182     {
183     if (expected != actual)
184     {
185     result.addFailure (file, line, expr);
186     result << "Expected: " << expected << "\n";
187     result << "Actual : " << actual;
188     }
189     return result;
190     }
191    
192     TestResult &checkStringEqual (TestResult &result, const std::string &expected, const std::string &actual, const char *file, unsigned int line, const char *expr);
193     } /* namespace JsonTest */
194    
195    
196     /*
197     * / \brief Asserts that the given expression is true.
198     * / JSONTEST_ASSERT( x == y ) << "x=" << x << ", y=" << y;
199     * / JSONTEST_ASSERT( x == y );
200     */
201     #define JSONTEST_ASSERT(expr) \
202     if (condition) \
203     { \
204     } \
205     else \
206     result_->addFailure (__FILE__, __LINE__, # expr)
207    
208     /*
209     * / \brief Asserts that the given predicate is true.
210     * / The predicate may do other assertions and be a member function of the fixture.
211     */
212     #define JSONTEST_ASSERT_PRED(expr) \
213     { \
214     JsonTest::PredicateContext _minitest_Context = { \
215     result_->predicateId_, __FILE__, __LINE__, # expr }; \
216     result_->predicateStackTail_->next_ = &_minitest_Context; \
217     result_->predicateId_ += 1; \
218     result_->predicateStackTail_ = &_minitest_Context; \
219     (expr); \
220     result_->popPredicateContext (); \
221     } \
222     *result_
223    
224     /* / \brief Asserts that two values are equals. */
225     #define JSONTEST_ASSERT_EQUAL(expected, actual) \
226     JsonTest::checkEqual (*result_, expected, actual, \
227     __FILE__, __LINE__, \
228     # expected " == " # actual)
229    
230     /* / \brief Asserts that two values are equals. */
231     #define JSONTEST_ASSERT_STRING_EQUAL(expected, actual) \
232     JsonTest::checkStringEqual (*result_, \
233     std::string (expected), std::string (actual), \
234     # expected " == " # actual)
235    
236     /* / \brief Begin a fixture test case. */
237     #define JSONTEST_FIXTURE(FixtureType, name) \
238     class Test ## FixtureType ## name \
239     : public FixtureType \
240     { \
241     public: \
242     static JsonTest::TestCase *factory () \
243     { \
244     return new Test ## FixtureType ## name (); \
245     } \
246     public: \
247     /* overidden from TestCase */ \
248     virtual const char *testName () const \
249     { \
250     return # FixtureType "/" # name; \
251     } \
252     virtual void runTestCase (); \
253     }; \
254     \
255     void Test ## FixtureType ## name::runTestCase ()
256    
257     #define JSONTEST_FIXTURE_FACTORY(FixtureType, name) \
258     & Test ## FixtureType ## name::factory
259    
260     #define JSONTEST_REGISTER_FIXTURE(runner, FixtureType, name) \
261     (runner).add (JSONTEST_FIXTURE_FACTORY (FixtureType, name))
262    
263     #endif /* ifndef JSONTEST_H_INCLUDED */