1/*
2 * Copyright (c) 2003, 2004
3 * Zdenek Nemec
4 *
5 * This material is provided "as is", with absolutely no warranty expressed
6 * or implied. Any use is at your own risk.
7 *
8 * Permission to use or copy this software for any purpose is hereby granted
9 * without fee, provided the above notices are retained on all copies.
10 * Permission to modify the code and to distribute modified code is granted,
11 * provided the above notices are retained, and a notice that the code was
12 * modified is included with the above copyright notice.
13 *
14 */
15
16/* $Id$ */
17
18#ifndef _CPPUNITMINIFILEREPORTERINTERFACE_H_
19#define _CPPUNITMINIFILEREPORTERINTERFACE_H_
20
21#include <stdio.h>
22
23#include "cppunit_timer.h"
24
25//
26// CppUnit mini file(stream) reporter
27//
28class FileReporter : public CPPUNIT_NS::Reporter {
29private:
30  FileReporter(const FileReporter&);
31  FileReporter& operator=(const FileReporter&);
32public:
33  // reporting to stderr
34  explicit FileReporter(bool doMonitor = false):
35      m_numErrors(0), m_numIgnored(0), m_numExplicit(0), m_numTests(0), _myStream(false),
36      m_failed(false), m_doMonitor(doMonitor)
37  { _file = stderr; }
38
39  // reporting to the file with the given name
40  explicit FileReporter(const char* file, bool doMonitor = false):
41      m_numErrors(0), m_numIgnored(0), m_numExplicit(0), m_numTests(0), _myStream(true),
42      m_failed(false), m_doMonitor(doMonitor)
43  {
44#ifndef _STLP_USE_SAFE_STRING_FUNCTIONS
45    _file = fopen(file, "w");
46#else
47    fopen_s(&_file, file, "w");
48#endif
49  }
50
51  // reporting to the given file
52  explicit FileReporter(FILE* stream, bool doMonitor = false):
53      m_numErrors(0), m_numIgnored(0), m_numExplicit(0), m_numTests(0), _myStream(false),
54      m_failed(false), m_doMonitor(doMonitor)
55  { _file = stream; }
56
57  virtual ~FileReporter() {
58    if (_myStream)
59      fclose(_file);
60    else
61      fflush(_file);
62  }
63
64  virtual void error(const char *in_macroName, const char *in_macro, const char *in_file, int in_line) {
65    // Error might be called several times between 2 progress calls, we shouldn't however consider
66    // that a test failed twice so we simply keep the info that test failed, number of failed tests
67    // is computed later in end method.
68    m_failed = true;
69    fprintf(_file, "\n\n%s(%d) : %s(%s);", in_file, in_line, in_macroName, in_macro);
70  }
71
72  virtual void message( const char *msg )
73  { fprintf(_file, "\n\t%s", msg ); }
74
75  virtual void progress(const char *in_className, const char *in_shortTestName, bool ignored, bool explicitTest) {
76    if (m_doMonitor) {
77      m_globalTimer.restart();
78      m_testTimer.start();
79    }
80    ++m_numTests;
81    m_failed = false;
82    if (ignored)
83      ++m_numIgnored;
84    fprintf(_file, "%s::%s", in_className, in_shortTestName);
85    if (ignored) {
86      const char *ignoredReason;
87      if (explicitTest) {
88        ++m_numExplicit;
89        ignoredReason = " EXPLICIT";
90      }
91      else
92        ignoredReason = " IGNORED";
93
94      fprintf(_file, "%s", ignoredReason);
95    }
96  }
97
98  virtual void end() {
99    if (m_doMonitor) {
100      m_globalTimer.stop();
101      m_testTimer.stop();
102      fprintf(_file, " %f msec", m_testTimer.elapsedMilliseconds());
103    }
104    if (m_failed) {
105      ++m_numErrors;
106    }
107    fprintf(_file, "\n");
108  }
109
110  virtual void printSummary() {
111    if (m_numErrors > 0) {
112      fprintf(_file, "\nThere were errors! %d of %d tests", m_numErrors, m_numTests);
113    }
114    else {
115      fprintf(_file, "\nOK %d tests", m_numTests);
116    }
117
118    if (m_numIgnored > 0) {
119      fprintf(_file, ", %d ignored", m_numIgnored);
120    }
121
122    if (m_numExplicit > 0) {
123      fprintf(_file, " (%d explicit)", m_numExplicit);
124    }
125
126    if (m_doMonitor) {
127      fprintf(_file, " %f msec", m_globalTimer.elapsedMilliseconds());
128    }
129
130    fprintf(_file, "\n\n");
131  }
132private:
133  int m_numErrors;
134  int m_numIgnored;
135  int m_numExplicit;
136  int m_numTests;
137  // flag whether we own '_file' and are thus responsible for releasing it in the destructor
138  bool  _myStream;
139  bool m_failed;
140  bool m_doMonitor;
141  Timer m_globalTimer, m_testTimer;
142  FILE* _file;
143};
144
145#endif /*_CPPUNITMINIFILEREPORTERINTERFACE_H_*/
146