• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

cpputest / cpputest / 10778420353

09 Sep 2024 05:42PM CUT coverage: 99.279%. Remained the same
10778420353

push

github

web-flow
Merge pull request #1811 from basvodde/master

Fixing PlatformSpecificFPuts conflict between JUnitOutputTest and TestOutput

6749 of 6798 relevant lines covered (99.28%)

18732.98 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.71
/src/CppUTest/JUnitTestOutput.cpp
1
/*
2
 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *     * Redistributions of source code must retain the above copyright
8
 *       notice, this list of conditions and the following disclaimer.
9
 *     * Redistributions in binary form must reproduce the above copyright
10
 *       notice, this list of conditions and the following disclaimer in the
11
 *       documentation and/or other materials provided with the distribution.
12
 *     * Neither the name of the <organization> nor the
13
 *       names of its contributors may be used to endorse or promote products
14
 *       derived from this software without specific prior written permission.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ''AS IS'' AND ANY
17
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
20
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 */
27

28
#include "CppUTest/TestHarness.h"
29
#include "CppUTest/JUnitTestOutput.h"
30
#include "CppUTest/TestResult.h"
31
#include "CppUTest/TestFailure.h"
32
#include "CppUTest/PlatformSpecificFunctions.h"
33

34
struct JUnitTestCaseResultNode
35
{
36
    JUnitTestCaseResultNode() :
51✔
37
        execTime_(0), failure_(NULLPTR), ignored_(false), lineNumber_ (0), checkCount_ (0), next_(NULLPTR)
51✔
38
    {
39
    }
51✔
40

41
    SimpleString name_;
42
    size_t execTime_;
43
    TestFailure* failure_;
44
    bool ignored_;
45
    SimpleString file_;
46
    size_t lineNumber_;
47
    size_t checkCount_;
48
    JUnitTestCaseResultNode* next_;
49
};
50

51
struct JUnitTestGroupResult
52
{
53
    JUnitTestGroupResult() :
33✔
54
        testCount_(0), failureCount_(0), totalCheckCount_(0), startTime_(0), groupExecTime_(0), head_(NULLPTR), tail_(NULLPTR)
33✔
55
    {
56
    }
33✔
57

58
    size_t testCount_;
59
    size_t failureCount_;
60
    size_t totalCheckCount_;
61
    size_t startTime_;
62
    size_t groupExecTime_;
63
    SimpleString group_;
64
    JUnitTestCaseResultNode* head_;
65
    JUnitTestCaseResultNode* tail_;
66
};
67

68
struct JUnitTestOutputImpl
69
{
70
    JUnitTestGroupResult results_;
71
    PlatformSpecificFile file_;
72
    SimpleString package_;
73
    SimpleString stdOutput_;
74
};
75

76
JUnitTestOutput::JUnitTestOutput() :
33✔
77
    impl_(new JUnitTestOutputImpl)
33✔
78
{
79
}
33✔
80

81
JUnitTestOutput::~JUnitTestOutput()
66✔
82
{
83
    resetTestGroupResult();
33✔
84
    delete impl_;
33✔
85
}
66✔
86

87
void JUnitTestOutput::resetTestGroupResult()
68✔
88
{
89
    impl_->results_.testCount_ = 0;
68✔
90
    impl_->results_.failureCount_ = 0;
68✔
91
    impl_->results_.group_ = "";
68✔
92
    JUnitTestCaseResultNode* cur = impl_->results_.head_;
68✔
93
    while (cur) {
119✔
94
        JUnitTestCaseResultNode* tmp = cur->next_;
51✔
95
        delete cur->failure_;
51✔
96
        delete cur;
51✔
97
        cur = tmp;
51✔
98
    }
99
    impl_->results_.head_ = NULLPTR;
68✔
100
    impl_->results_.tail_ = NULLPTR;
68✔
101
}
68✔
102

103
void JUnitTestOutput::printTestsStarted()
32✔
104
{
105
}
32✔
106

107
void JUnitTestOutput::printCurrentGroupStarted(const UtestShell& /*test*/)
35✔
108
{
109
}
35✔
110

111
void JUnitTestOutput::printCurrentTestEnded(const TestResult& result)
51✔
112
{
113
    impl_->results_.tail_->execTime_ = result.getCurrentTestTotalExecutionTime();
51✔
114
    impl_->results_.tail_->checkCount_ = result.getCheckCount();
51✔
115
}
51✔
116

117
void JUnitTestOutput::printTestsEnded(const TestResult& /*result*/)
32✔
118
{
119
}
32✔
120

121
void JUnitTestOutput::printCurrentGroupEnded(const TestResult& result)
35✔
122
{
123
    impl_->results_.groupExecTime_ = result.getCurrentGroupTotalExecutionTime();
35✔
124
    writeTestGroupToFile();
35✔
125
    resetTestGroupResult();
35✔
126
}
35✔
127

128
void JUnitTestOutput::printCurrentTestStarted(const UtestShell& test)
51✔
129
{
130
    impl_->results_.testCount_++;
51✔
131
    impl_->results_.group_ = test.getGroup();
51✔
132
    impl_->results_.startTime_ = (size_t) GetPlatformSpecificTimeInMillis();
51✔
133

134
    if (impl_->results_.tail_ == NULLPTR) {
51✔
135
        impl_->results_.head_ = impl_->results_.tail_
35✔
136
                = new JUnitTestCaseResultNode;
35✔
137
    }
138
    else {
139
        impl_->results_.tail_->next_ = new JUnitTestCaseResultNode;
16✔
140
        impl_->results_.tail_ = impl_->results_.tail_->next_;
16✔
141
    }
142
    impl_->results_.tail_->name_ = test.getName();
51✔
143
    impl_->results_.tail_->file_ = test.getFile();
51✔
144
    impl_->results_.tail_->lineNumber_ = test.getLineNumber();
51✔
145
    if (!test.willRun()) {
51✔
146
        impl_->results_.tail_->ignored_ = true;
1✔
147
    }
148
}
51✔
149

150
SimpleString JUnitTestOutput::createFileName(const SimpleString& group)
36✔
151
{
152
    SimpleString fileName = "cpputest_";
36✔
153
    if (!impl_->package_.isEmpty()) {
36✔
154
        fileName += impl_->package_;
6✔
155
        fileName += "_";
6✔
156
    }
157
    fileName += group;
36✔
158
    return encodeFileName(fileName) + ".xml";
108✔
159
}
36✔
160

161
SimpleString JUnitTestOutput::encodeFileName(const SimpleString& fileName)
36✔
162
{
163
    // special character list based on: https://en.wikipedia.org/wiki/Filename
164
    static const char* const forbiddenCharacters = "/\\?%*:|\"<>";
165

166
    SimpleString result = fileName;
36✔
167
    for (const char* sym = forbiddenCharacters; *sym; ++sym) {
396✔
168
        result.replace(*sym, '_');
360✔
169
    }
170
    return result;
36✔
171
}
×
172

173
void JUnitTestOutput::setPackageName(const SimpleString& package)
6✔
174
{
175
    if (impl_ != NULLPTR) {
6✔
176
        impl_->package_ = package;
6✔
177
    }
178
}
6✔
179

180
void JUnitTestOutput::writeXmlHeader()
35✔
181
{
182
    writeToFile("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
35✔
183
}
35✔
184

185
void JUnitTestOutput::writeTestSuiteSummary()
35✔
186
{
187
    SimpleString
188
            buf =
189
                    StringFromFormat(
190
                            "<testsuite errors=\"0\" failures=\"%d\" hostname=\"localhost\" name=\"%s\" tests=\"%d\" time=\"%d.%03d\" timestamp=\"%s\">\n",
191
                            (int)impl_->results_.failureCount_,
35✔
192
                            impl_->results_.group_.asCharString(),
35✔
193
                            (int) impl_->results_.testCount_,
35✔
194
                            (int) (impl_->results_.groupExecTime_ / 1000), (int) (impl_->results_.groupExecTime_ % 1000),
35✔
195
                            GetPlatformSpecificTimeString());
35✔
196
    writeToFile(buf.asCharString());
35✔
197
}
35✔
198

199
void JUnitTestOutput::writeProperties()
35✔
200
{
201
    writeToFile("<properties>\n");
35✔
202
    writeToFile("</properties>\n");
35✔
203
}
35✔
204

205
SimpleString JUnitTestOutput::encodeXmlText(const SimpleString& textbody)
47✔
206
{
207
    SimpleString buf = textbody.asCharString();
47✔
208
    buf.replace("&", "&amp;");
47✔
209
    buf.replace("\"", "&quot;");
47✔
210
    buf.replace("<", "&lt;");
47✔
211
    buf.replace(">", "&gt;");
47✔
212
    buf.replace("\r", "&#13;");
47✔
213
    buf.replace("\n", "&#10;");
47✔
214
    return buf;
47✔
215
}
×
216

217
void JUnitTestOutput::writeTestCases()
35✔
218
{
219
    JUnitTestCaseResultNode* cur = impl_->results_.head_;
35✔
220

221
    while (cur) {
86✔
222
        SimpleString buf = StringFromFormat(
223
                "<testcase classname=\"%s%s%s\" name=\"%s\" assertions=\"%d\" time=\"%d.%03d\" file=\"%s\" line=\"%d\">\n",
224
                impl_->package_.asCharString(),
51✔
225
                impl_->package_.isEmpty() ? "" : ".",
102✔
226
                impl_->results_.group_.asCharString(),
51✔
227
                cur->name_.asCharString(),
228
                (int) (cur->checkCount_ - impl_->results_.totalCheckCount_),
51✔
229
                (int) (cur->execTime_ / 1000), (int)(cur->execTime_ % 1000),
51✔
230
                cur->file_.asCharString(),
231
                (int) cur->lineNumber_);
51✔
232
        writeToFile(buf.asCharString());
51✔
233

234
        impl_->results_.totalCheckCount_ = cur->checkCount_;
51✔
235

236
        if (cur->failure_) {
51✔
237
            writeFailure(cur);
12✔
238
        }
239
        else if (cur->ignored_) {
39✔
240
            writeToFile("<skipped />\n");
1✔
241
        }
242
        writeToFile("</testcase>\n");
51✔
243
        cur = cur->next_;
51✔
244
    }
51✔
245
}
35✔
246

247
void JUnitTestOutput::writeFailure(JUnitTestCaseResultNode* node)
12✔
248
{
249
    SimpleString buf = StringFromFormat(
250
            "<failure message=\"%s:%d: %s\" type=\"AssertionFailedError\">\n",
251
            node->failure_->getFileName().asCharString(),
12✔
252
            (int) node->failure_->getFailureLineNumber(),
24✔
253
            encodeXmlText(node->failure_->getMessage()).asCharString());
24✔
254
    writeToFile(buf.asCharString());
12✔
255
    writeToFile("</failure>\n");
12✔
256
}
12✔
257

258

259
void JUnitTestOutput::writeFileEnding()
35✔
260
{
261
    writeToFile("<system-out>");
35✔
262
    writeToFile(encodeXmlText(impl_->stdOutput_));
35✔
263
    writeToFile("</system-out>\n");
35✔
264
    writeToFile("<system-err></system-err>\n");
35✔
265
    writeToFile("</testsuite>\n");
35✔
266
}
35✔
267

268
void JUnitTestOutput::writeTestGroupToFile()
35✔
269
{
270
    openFileForWrite(createFileName(impl_->results_.group_));
35✔
271
    writeXmlHeader();
35✔
272
    writeTestSuiteSummary();
35✔
273
    writeProperties();
35✔
274
    writeTestCases();
35✔
275
    writeFileEnding();
35✔
276
    closeFile();
35✔
277
}
35✔
278

279
// LCOV_EXCL_START
280

281
void JUnitTestOutput::printBuffer(const char*)
282
{
283
}
284

285
void JUnitTestOutput::print(const char *output)
286
{
287
    impl_->stdOutput_ += output;
288
}
289

290
void JUnitTestOutput::print(long)
291
{
292
}
293

294
void JUnitTestOutput::print(size_t)
295
{
296
}
297

298
void JUnitTestOutput::flush()
299
{
300
}
301

302
// LCOV_EXCL_STOP
303

304
void JUnitTestOutput::printFailure(const TestFailure& failure)
12✔
305
{
306
    if (impl_->results_.tail_->failure_ == NULLPTR) {
12✔
307
        impl_->results_.failureCount_++;
12✔
308
        impl_->results_.tail_->failure_ = new TestFailure(failure);
12✔
309
    }
310
}
12✔
311

312
void JUnitTestOutput::openFileForWrite(const SimpleString& fileName)
35✔
313
{
314
    impl_->file_ = PlatformSpecificFOpen(fileName.asCharString(), "w");
35✔
315
}
35✔
316

317
void JUnitTestOutput::writeToFile(const SimpleString& buffer)
442✔
318
{
319
    PlatformSpecificFPuts(buffer.asCharString(), impl_->file_);
442✔
320
}
442✔
321

322
void JUnitTestOutput::closeFile()
35✔
323
{
324
    PlatformSpecificFClose(impl_->file_);
35✔
325
}
35✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc