forked from cppcheck-opensource/cppcheck
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfixture.h
More file actions
238 lines (196 loc) · 10.6 KB
/
fixture.h
File metadata and controls
238 lines (196 loc) · 10.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
/*
* Cppcheck - A tool for static C/C++ code analysis
* Copyright (C) 2007-2023 Cppcheck team.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef fixtureH
#define fixtureH
#include "check.h"
#include "color.h"
#include "config.h"
#include "errorlogger.h"
#include "settings.h"
#include <cstddef>
#include <list>
#include <set>
#include <sstream>
#include <stdexcept>
#include <string>
class options;
class Settings;
class Tokenizer;
class TestFixture : public ErrorLogger {
private:
static std::ostringstream errmsg;
static unsigned int countTests;
static std::size_t fails_counter;
static std::size_t todos_counter;
static std::size_t succeeded_todos_counter;
bool mVerbose;
std::string mTemplateFormat;
std::string mTemplateLocation;
std::string mTestname;
protected:
std::string exename;
std::string testToRun;
bool quiet_tests;
virtual void run() = 0;
bool prepareTest(const char testname[]);
std::string getLocationStr(const char * const filename, const unsigned int linenr) const;
bool assert_(const char * const filename, const unsigned int linenr, const bool condition) const;
template<typename T, typename U>
bool assertEquals(const char* const filename, const unsigned int linenr, const T& expected, const U& actual, const std::string& msg = emptyString) const {
if (expected != actual) {
std::ostringstream expectedStr;
expectedStr << expected;
std::ostringstream actualStr;
actualStr << actual;
assertEqualsFailed(filename, linenr, expectedStr.str(), actualStr.str(), msg);
}
return expected == actual;
}
//Helper function to be called when an assertEquals assertion fails.
//Writes the appropriate failure message to errmsg and increments fails_counter
void assertEqualsFailed(const char* const filename, const unsigned int linenr, const std::string& expected, const std::string& actual, const std::string& msg) const;
bool assertEquals(const char * const filename, const unsigned int linenr, const std::string &expected, const std::string &actual, const std::string &msg = emptyString) const;
void assertEqualsWithoutLineNumbers(const char * const filename, const unsigned int linenr, const std::string &expected, const std::string &actual, const std::string &msg = emptyString) const;
bool assertEquals(const char * const filename, const unsigned int linenr, const char expected[], const std::string& actual, const std::string &msg = emptyString) const;
bool assertEquals(const char * const filename, const unsigned int linenr, const char expected[], const char actual[], const std::string &msg = emptyString) const;
bool assertEquals(const char * const filename, const unsigned int linenr, const std::string& expected, const char actual[], const std::string &msg = emptyString) const;
bool assertEquals(const char * const filename, const unsigned int linenr, const long long expected, const long long actual, const std::string &msg = emptyString) const;
void assertEqualsDouble(const char * const filename, const unsigned int linenr, const double expected, const double actual, const double tolerance, const std::string &msg = emptyString) const;
void todoAssertEquals(const char * const filename, const unsigned int linenr, const std::string &wanted,
const std::string ¤t, const std::string &actual) const;
void todoAssertEquals(const char * const filename, const unsigned int linenr, const char wanted[],
const char current[], const std::string &actual) const;
void todoAssertEquals(const char * const filename, const unsigned int linenr, const long long wanted,
const long long current, const long long actual) const;
void assertThrow(const char * const filename, const unsigned int linenr) const;
void assertThrowFail(const char * const filename, const unsigned int linenr) const;
void assertNoThrowFail(const char * const filename, const unsigned int linenr) const;
static std::string deleteLineNumber(const std::string &message);
void setVerbose(bool v) {
mVerbose = v;
}
void setTemplateFormat(const std::string &templateFormat);
void setMultiline() {
setTemplateFormat("multiline");
}
void processOptions(const options& args);
template<typename T>
static T& getCheck()
{
for (Check *check : Check::instances()) {
//cppcheck-suppress [constVariablePointer, useStlAlgorithm] - TODO: fix constVariable FP
if (T* c = dynamic_cast<T*>(check))
return *c;
}
throw std::runtime_error("instance not found");
}
template<typename T>
static void runChecks(const Tokenizer *tokenizer, const Settings *settings, ErrorLogger *errorLogger)
{
T& check = getCheck<T>();
check.runChecks(tokenizer, settings, errorLogger);
}
// TODO: bail out on redundant settings
class SettingsBuilder
{
public:
explicit SettingsBuilder(const TestFixture &fixture) : fixture(fixture) {}
SettingsBuilder(const TestFixture &fixture, Settings settings) : fixture(fixture), settings(std::move(settings)) {}
SettingsBuilder& severity(Severity::SeverityType sev) {
settings.severity.enable(sev);
return *this;
}
SettingsBuilder& certainty(Certainty cert, bool b = true) {
settings.certainty.setEnabled(cert, b);
return *this;
}
SettingsBuilder& clang() {
settings.clang = true;
return *this;
}
SettingsBuilder& checkLibrary() {
settings.checkLibrary = true;
return *this;
}
SettingsBuilder& checkUnusedTemplates() {
settings.checkUnusedTemplates = true;
return *this;
}
SettingsBuilder& debugwarnings(bool b = true) {
settings.debugwarnings = b;
return *this;
}
SettingsBuilder& c(Standards::cstd_t std) {
settings.standards.c = std;
return *this;
}
SettingsBuilder& cpp(Standards::cppstd_t std) {
settings.standards.cpp = std;
return *this;
}
SettingsBuilder& library(const char lib[]);
Settings build() {
return std::move(settings);
}
private:
const TestFixture &fixture;
Settings settings;
};
SettingsBuilder settingsBuilder() const {
return SettingsBuilder(*this);
}
SettingsBuilder settingsBuilder(Settings settings) const {
return SettingsBuilder(*this, std::move(settings));
}
public:
void reportOut(const std::string &outmsg, Color c = Color::Reset) override;
void reportErr(const ErrorMessage &msg) override;
void run(const std::string &str);
static void printHelp();
const std::string classname;
explicit TestFixture(const char * const _name);
~TestFixture() override {}
static std::size_t runTests(const options& args);
};
// TODO: fix these
// NOLINTNEXTLINE(readability-redundant-declaration)
extern std::ostringstream errout;
// NOLINTNEXTLINE(readability-redundant-declaration)
extern std::ostringstream output;
// TODO: most asserts do not actually assert i.e. do not return
#define TEST_CASE( NAME ) do { if (prepareTest(#NAME)) { setVerbose(false); NAME(); } } while (false)
#define ASSERT( CONDITION ) if (!assert_(__FILE__, __LINE__, (CONDITION))) return
#define ASSERT_LOC( CONDITION, FILE_, LINE_ ) assert_(FILE_, LINE_, (CONDITION))
#define CHECK_EQUALS( EXPECTED, ACTUAL ) assertEquals(__FILE__, __LINE__, (EXPECTED), (ACTUAL))
#define ASSERT_EQUALS( EXPECTED, ACTUAL ) if (!assertEquals(__FILE__, __LINE__, (EXPECTED), (ACTUAL))) return
#define ASSERT_EQUALS_WITHOUT_LINENUMBERS( EXPECTED, ACTUAL ) assertEqualsWithoutLineNumbers(__FILE__, __LINE__, EXPECTED, ACTUAL)
#define ASSERT_EQUALS_DOUBLE( EXPECTED, ACTUAL, TOLERANCE ) assertEqualsDouble(__FILE__, __LINE__, EXPECTED, ACTUAL, TOLERANCE)
#define ASSERT_EQUALS_MSG( EXPECTED, ACTUAL, MSG ) assertEquals(__FILE__, __LINE__, EXPECTED, ACTUAL, MSG)
#define ASSERT_THROW( CMD, EXCEPTION ) do { try { CMD; assertThrowFail(__FILE__, __LINE__); } catch (const EXCEPTION&) {} catch (...) { assertThrowFail(__FILE__, __LINE__); } } while (false)
#define ASSERT_THROW_EQUALS( CMD, EXCEPTION, EXPECTED ) do { try { CMD; assertThrowFail(__FILE__, __LINE__); } catch (const EXCEPTION&e) { assertEquals(__FILE__, __LINE__, EXPECTED, e.errorMessage); } catch (...) { assertThrowFail(__FILE__, __LINE__); } } while (false)
#define ASSERT_THROW_EQUALS_2( CMD, EXCEPTION, EXPECTED ) do { try { CMD; assertThrowFail(__FILE__, __LINE__); } catch (const EXCEPTION&e) { assertEquals(__FILE__, __LINE__, EXPECTED, e.what()); } catch (...) { assertThrowFail(__FILE__, __LINE__); } } while (false)
#define ASSERT_NO_THROW( CMD ) do { try { CMD; } catch (...) { assertNoThrowFail(__FILE__, __LINE__); } } while (false)
#define TODO_ASSERT_THROW( CMD, EXCEPTION ) do { try { CMD; } catch (const EXCEPTION&) {} catch (...) { assertThrow(__FILE__, __LINE__); } } while (false)
#define TODO_ASSERT( CONDITION ) do { const bool condition=(CONDITION); todoAssertEquals(__FILE__, __LINE__, true, false, condition); } while (false)
#define TODO_ASSERT_EQUALS( WANTED, CURRENT, ACTUAL ) todoAssertEquals(__FILE__, __LINE__, WANTED, CURRENT, ACTUAL)
#define EXPECT_EQ( EXPECTED, ACTUAL ) assertEquals(__FILE__, __LINE__, EXPECTED, ACTUAL)
#define REGISTER_TEST( CLASSNAME ) namespace { CLASSNAME instance_ ## CLASSNAME; }
#define LOAD_LIB_2_EXE( LIB, NAME, EXE ) do { if (((LIB).load((EXE), NAME).errorcode != Library::ErrorCode::OK)) throw std::runtime_error("library '" + std::string(NAME) + "' not found"); } while (false)
#define LOAD_LIB_2( LIB, NAME ) LOAD_LIB_2_EXE(LIB, NAME, exename.c_str())
#define PLATFORM( P, T ) do { std::string errstr; assertEquals(__FILE__, __LINE__, true, P.set(cppcheck::Platform::toString(T), errstr, {exename}), errstr); } while (false)
#endif // fixtureH