OpenClovis Logo

clTestApi.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2002-2012 OpenClovis Solutions Inc. All Rights Reserved.
3  *
4  * This file is available under a commercial license from the
5  * copyright holder or the GNU General Public License Version 2.0.
6  *
7  * The source code for this program is not published or otherwise
8  * divested of its trade secrets, irrespective of what has been
9  * deposited with the U.S. Copyright office.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * General Public License for more details.
15  *
16  * For more information, see the file COPYING provided with this
17  * material.
18  */
19 #ifndef _CL_TEST_H_
20 #define _CL_TEST_H_
21 
22 #include <stdio.h>
23 #include "clDebugApi.h"
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
41 /* See clTest.c for documentation on these global variables */
42 extern int clTestLogLevel;
43 extern int clTestOn;
44 extern int clTestPrintIndent;
45 
46 enum
47 {
48  ClTestCaseMaxNameLen = 512,
49  ClTestMaxNameLen = 512
50 };
51 
52 typedef enum /* A bit field that turns on/off types of printout */
53 {
54  CL_TEST_PRINT_ALL = 0xffffff,
55  CL_TEST_PRINT_TEST_OK = 1,
56  CL_TEST_PRINT_TEST_FAILED = 2,
57 } ClTestVerbosity;
58 
59 extern ClTestVerbosity clTestVerbosity;
60 
61 /* Not part of the public API */
62 
63 typedef struct
64 {
65  unsigned int passed;
66  unsigned int failed;
67  unsigned int malfunction;
68  unsigned int malfPops;
69  char name[ClTestCaseMaxNameLen];
70 } ClTestCaseData;
71 
72 /* Not part of the public API */
73 extern void clPushTestCase(const ClTestCaseData* tcd);
74 extern void clPopTestCase(ClTestCaseData* tcd);
75 extern int clTestGroupFinalizeImpl();
76 extern void clTestPrintImpl(const char* file, int line, const char* fn, const char* c);
77 extern void clTestImpl(const char* file, int line, const char* function, const char * id, const char * error, int ok);
78 
79 extern ClTestCaseData clCurTc;
80 
81 
82 /* All strings are printf formatted and in () */
83 #define this_error_indicates_missing_parens_around_string(...) __VA_ARGS__
84 
85 #define clTestStripParens(...) __VA_ARGS__
86 
87 
88 #ifndef CL_NO_TEST
89 
111 #define clTestGroupInitialize(name) clTestPrint(name)
112 
127 #define clTestGroupFinalize() clTestGroupFinalizeImpl()
128 
149 #define clTestGroupMalfunction(reason, predicate, execOnFailure) \
150 do { \
151  if (!(predicate)) { \
152  clTestPrint(reason); \
153  clTestPrint(("Test Malfunction.")); \
154  (void) clTestGroupFinalize(); \
155  execOnFailure; \
156  } \
157 } while(0)
158 
176 #define clTestCase(name, test) \
177 do { \
178  clTestCaseStart(name); \
179  clCurTc.malfPops = 0; \
180  test; \
181  clTestCaseEnd((" ")); \
182 } while (0)
183 
184 
199 #define clTestCaseStart(testname) \
200 do { \
201  clTestPrintIndent+=2; \
202  clPushTestCase(&clCurTc); \
203  clCurTc.passed=0; \
204  clCurTc.failed=0; \
205  clCurTc.malfunction=0; \
206  clCurTc.malfPops = 1; \
207  snprintf(clCurTc.name, ClTestCaseMaxNameLen, \
208  this_error_indicates_missing_parens_around_string testname); \
209  clTestPrint(("Test case started [%s]:\n", clCurTc.name)); \
210 } while(0)
211 
221 #define clTestCaseNumErrors() clCurTc.failed
222 
232 #define clTestCaseNumMalfunctions() clCurTc.malfunction
233 
243 #define clTestCaseNumPasses() clCurTc.passed
244 
260 #define clTestCaseEnd(synopsis) \
261 do { \
262  clTestPrint(("Test case completed [%s]. " \
263  "Subcases: [%d] passed, [%d] failed, [%d] malfunction.\n" \
264  "Synopsis:\n", \
265  clCurTc.name, clCurTc.passed, \
266  clCurTc.failed, clCurTc.malfunction)); \
267  clTestPrint(synopsis); \
268  clTestPrintIndent-=2; \
269  int malf=clCurTc.malfunction; \
270  int fail = clCurTc.failed; \
271  clPopTestCase(&clCurTc); \
272  if (fail) \
273  clCurTc.failed++; \
274  else if (malf) \
275  clCurTc.malfunction++; \
276  else \
277  clCurTc.passed++; \
278 } while(0)
279 
296 // Will call TestCaseEnd, but you have to "return" or break, whatever
297 #define clTestCaseMalfunction(reason, predicate, execOnFailure) \
298 do { \
299  if (!(predicate)) { \
300  clTestPrint(("Test case malfunction [%s]. " \
301  "Subtests: [%d] Passed, [%d] Failed.\n" \
302  "Malfunction reason:\n", \
303  clCurTc.name, clCurTc.passed, clCurTc.failed)); \
304  clTestPrint(reason); \
305  if (clCurTc.malfPops) clPopTestCase(&clCurTc); \
306  clCurTc.malfunction++; \
307  execOnFailure; \
308  } \
309 } while(0)
310 
330 #define clTest(string, predicate, errorPrintf)\
331 do{ \
332  char __id[ClTestMaxNameLen]; \
333  char __error[ClTestMaxNameLen]=""; \
334  int __ok = predicate; \
335  snprintf(__id, ClTestMaxNameLen, \
336  this_error_indicates_missing_parens_around_string string); \
337  if (!__ok) \
338  snprintf(__error, ClTestMaxNameLen, \
339  this_error_indicates_missing_parens_around_string errorPrintf); \
340  clTestImpl(__FILE__, __LINE__, __FUNCTION__, __id, __error, __ok); \
341 } while(0)
342 
343 // do { clTestPrint(string); { int result = (predicate); if (result) { clCurTc.passed++; clTestPrint((": Ok\n")); } else { clCurTc.failed++; clTestPrint((": %s:%d: Test (" #predicate ") failed. ", __FILE__, __LINE__)); clTestPrint(errorPrintf); clTestPrint(("\n")); } } } while(0)
344 
365 #define clTestExecOnFailure(string, predicate, errorPrintf, execOnFailure) \
366 do { \
367  clTestPrint(string); \
368  { \
369  int result = (predicate); \
370  if (result) { \
371  clCurTc.passed++; \
372  clTestPrint((": Ok\n")); \
373  } else { \
374  clCurTc.failed++; \
375  clTestPrint((": %s:%d: Test (" #predicate ") failed. ", \
376  __FILE__, __LINE__)); \
377  clTestPrint(errorPrintf); \
378  clTestPrint(("\n")); \
379  execOnFailure; \
380  } \
381  } \
382 } while(0)
383 
402 #define clTestFailed(__string) clTestFailedAt(__FILE__, __LINE__,__string)
403 
413 #define clTestFailedAt(__file, __line, __string) \
414 do { \
415  clCurTc.failed++; \
416  clTestPrint((": %s:%d: Test failed. ", __file, __line)); \
417  clTestPrint(__string); \
418  clTestPrint(("\n")); \
419 } while(0)
420 
441 #define clTestSuccess(__string) clTestSuccessAt(__FILE__, __LINE__, __string)
442 
452 #define clTestSuccessAt(__file, __line, __string) \
453 { \
454  clCurTc.passed++; \
455  clTestPrintAt(__file,__line, __FUNCTION__, __string); \
456  clTestPrintAt(__file,__line, __FUNCTION__, (": Ok\n")); \
457 } while (0)
458 
459 
460 
474 #define clTestPrint(x) clTestPrintAt(__FILE__, __LINE__, __FUNCTION__, x)
475 
485 #define clTestPrintAt(__file, __line, __function, x) \
486 do { \
487  char __tempstr[2048]; \
488  snprintf(__tempstr,2048, \
489  this_error_indicates_missing_parens_around_string x); \
490  clTestPrintImpl(__file, __line, __function,__tempstr); \
491  CL_DEBUG_PRINT(clTestLogLevel, x); \
492 } while(0)
493 
494 #else
495 
496 /* Make all macros a noop if CL_NO_TEST is defined */
497 #define clTestGroupInitialize(name) do{ } while(0)
498 #define clTestGroupFinalize() do{ } while(0)
499 #define clTestGroupMalfunction(reason, predicate, execOnFailure) do{ } while(0)
500 #define clTestCase(name, test) do{ } while(0)
501 #define clTestCaseStart(testname) do{ } while(0)
502 #define clTestCaseNumErrors() 0
503 #define clTestCaseNumMalfunctions() 0
504 #define clTestCaseNumPasses() 0
505 #define clTestCaseEnd(synopsis) do{ } while(0)
506 #define clTestCaseMalfunction(reason, predicate, execOnFailure) do{ } while(0)
507 #define clTest(string, predicate, errorPrintf) do{ } while(0)
508 #define clTestExecOnFailure(string, predicate, errorPrintf, execOnFailure) do{ } while(0)
509 #define clTestFailed(string) do{ } while(0)
510 #define clTestSuccess(string) do{ } while(0)
511 #define clTestPrint(x) do{ } while(0)
512 
513 #define clTestPrintAt(__file, __line, __function, x) do{ } while(0)
514 #define clTestSuccessAt(__file, __line, __string) do{ } while(0)
515 #define clTestFailedAt(__file, __line, __string) do{ } while(0)
516 #endif
517 
518 #ifdef __cplusplus
519 }
520 #endif
521 
525 #endif

Generated on Tue Jan 10 10:29:15 PST 2012 for OpenClovis SDK using Doxygen