ProteoWizard
unit.hpp
Go to the documentation of this file.
1//
2// $Id$
3//
4//
5// Original author: Darren Kessner <darren@proteowizard.org>
6//
7// Copyright 2006 Louis Warschaw Prostate Cancer Center
8// Cedars Sinai Medical Center, Los Angeles, California 90048
9//
10// Licensed under the Apache License, Version 2.0 (the "License");
11// you may not use this file except in compliance with the License.
12// You may obtain a copy of the License at
13//
14// http://www.apache.org/licenses/LICENSE-2.0
15//
16// Unless required by applicable law or agreed to in writing, software
17// distributed under the License is distributed on an "AS IS" BASIS,
18// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19// See the License for the specific language governing permissions and
20// limitations under the License.
21//
22
23
24#ifndef _UNIT_HPP_
25#define _UNIT_HPP_
26
27
28#include "Exception.hpp"
29#include "DateTime.hpp"
30#include "Filesystem.hpp"
32#include <string>
33#include <sstream>
34#include <cmath>
35#include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
36
37
38namespace pwiz {
39namespace util {
40
41
42//
43// These are assertion macros for unit testing. They throw a runtime_error
44// exception on failure, instead of calling abort(), allowing the application
45// to recover and return an appropriate error value to the shell.
46//
47// unit_assert(x): asserts x is true
48// unit_assert_equal(x, y, epsilon): asserts x==y, within epsilon
49// unit_assert_matrices_equal(A, B, epsilon): asserts A==B, within epsilon
50//
51
52
53inline std::string unit_assert_message(const char* filename, int line, const char* expression)
54{
55 std::ostringstream oss;
56 oss << "[" << filename << ":" << line << "] Assertion failed: " << expression;
57 return oss.str();
58}
59
60inline std::string unit_assert_equal_message(const char* filename, int line, const std::string& x, const std::string& y, const char* expression)
61{
62 std::ostringstream oss;
63 oss << "[" << filename << ":" << line << "] Assertion failed: expected \"" << x << "\" but got \"" << y << "\" (" << expression << ")";
64 return oss.str();
65}
66
67inline std::string unit_assert_numeric_equal_message(const char* filename, int line, double x, double y, double epsilon)
68{
69 std::ostringstream oss;
70 oss.precision(10);
71 oss << "[" << filename << ":" << line << "] Assertion failed: |" << x << " - " << y << "| < " << epsilon;
72 return oss.str();
73}
74
75inline std::string unit_assert_exception_message(const char* filename, int line, const char* expression, const std::string& exception)
76{
77 std::ostringstream oss;
78 oss << "[" << filename << ":" << line << "] Assertion \"" << expression << "\" failed to throw " << exception;
79 return oss.str();
80}
81
82inline std::string quote_string(const string& str) {return "\"" + str + "\"";}
83
84
85#define unit_assert(x) \
86 (!(x) ? throw std::runtime_error(unit_assert_message(__FILE__, __LINE__, #x)) : 0)
87
88#define unit_assert_to_stream(x, os) \
89 ((os) << (!(x) ? unit_assert_message(__FILE__, __LINE__, #x) + "\n" : ""))
90
91
92#define unit_assert_operator_equal(expected, actual) \
93 (!((expected) == (actual)) ? throw std::runtime_error(unit_assert_equal_message(__FILE__, __LINE__, lexical_cast<string>(expected), lexical_cast<string>(actual), #actual)) : 0)
94
95#define unit_assert_operator_equal_to_stream(expected, actual, os) \
96 ((os) << (!((expected) == (actual)) ? unit_assert_equal_message(__FILE__, __LINE__, lexical_cast<string>(expected), lexical_cast<string>(actual), #actual) + "\n" : ""))
97
98
99#define unit_assert_equal(x, y, epsilon) \
100 (!(fabs((x)-(y)) <= (epsilon)) ? throw std::runtime_error(unit_assert_numeric_equal_message(__FILE__, __LINE__, (x), (y), (epsilon))) : 0)
101
102#define unit_assert_equal_to_stream(x, y, epsilon, os) \
103 ((os) << (!(fabs((x)-(y)) <= (epsilon)) ? unit_assert_numeric_equal_message(__FILE__, __LINE__, (x), (y), (epsilon)) + "\n" : ""))
104
105
106#define unit_assert_throws(x, exception) \
107 { \
108 bool threw = false; \
109 try { (x); } \
110 catch (exception&) \
111 { \
112 threw = true; \
113 } \
114 if (!threw) \
115 throw std::runtime_error(unit_assert_exception_message(__FILE__, __LINE__, #x, #exception)); \
116 }
117
118
119#define unit_assert_throws_what(x, exception, whatStr) \
120 { \
121 bool threw = false; \
122 try { (x); } \
123 catch (exception& e) \
124 { \
125 if (e.what() == std::string(whatStr)) \
126 threw = true; \
127 else \
128 throw std::runtime_error(unit_assert_exception_message(__FILE__, __LINE__, #x, std::string(#exception)+" "+quote_string(whatStr)+"\nBut a different exception was thrown: ")+quote_string(e.what())); \
129 } \
130 if (!threw) \
131 throw std::runtime_error(unit_assert_exception_message(__FILE__, __LINE__, #x, std::string(#exception)+" "+quote_string(whatStr))); \
132 }
133
134
135#define unit_assert_matrices_equal(A, B, epsilon) \
136 unit_assert(boost::numeric::ublas::norm_frobenius((A)-(B)) < (epsilon))
137
138
139#define unit_assert_vectors_equal(A, B, epsilon) \
140 unit_assert(boost::numeric::ublas::norm_2((A)-(B)) < (epsilon))
141
142
143// the following macros are used by the ProteoWizard tests to report test status and duration to TeamCity
144
145inline std::string escape_teamcity_string(const std::string& str)
146{
147 string result = str;
148 bal::replace_all(result, "'", "|'");
149 bal::replace_all(result, "\n", "|n");
150 bal::replace_all(result, "\r", "|r");
151 bal::replace_all(result, "|", "||");
152 bal::replace_all(result, "[", "|[");
153 bal::replace_all(result, "]", "|]");
154 return result;
155}
156
157#define TEST_PROLOG_EX(argc, argv, suffix) \
158 bnw::args args(argc, argv); \
159 std::locale global_loc = std::locale(); \
160 std::locale loc(global_loc, new boost::filesystem::detail::utf8_codecvt_facet); \
161 bfs::path::imbue(loc); \
162 bfs::path testName = bfs::change_extension(bfs::basename(argv[0]), (suffix)); \
163 string teamcityTestName = pwiz::util::escape_teamcity_string(testName.string()); \
164 bpt::ptime testStartTime; \
165 vector<string> testArgs(argv, argv+argc); \
166 bool teamcityTestDecoration = find(testArgs.begin(), testArgs.end(), "--teamcity-test-decoration") != testArgs.end(); \
167 if (teamcityTestDecoration) \
168 { \
169 testStartTime = bpt::microsec_clock::local_time(); \
170 cout << "##teamcity[testStarted name='" << teamcityTestName << "']" << endl; \
171 } \
172 int testExitStatus = 0;
173
174
175#define TEST_PROLOG(argc, argv) TEST_PROLOG_EX(argc, argv, "")
176
177#define TEST_FAILED(x) \
178 if (teamcityTestDecoration) \
179 cout << "##teamcity[testFailed name='" << teamcityTestName << "' message='" << pwiz::util::escape_teamcity_string((x)) << "']\n"; \
180 cerr << (x) << endl; \
181 testExitStatus = 1;
182
183#define TEST_EPILOG \
184 if (teamcityTestDecoration) \
185 cout << "##teamcity[testFinished name='" << teamcityTestName << \
186 "' duration='" << round((bpt::microsec_clock::local_time() - testStartTime).total_microseconds() / 1000.0) << "']" << endl; \
187 return testExitStatus;
188
189
190} // namespace util
191} // namespace pwiz
192
193
194// without PWIZ_DOCTEST defined, disable doctest macros; when it is defined, doctest will be configured with main()
195#if !defined(PWIZ_DOCTEST) && !defined(PWIZ_DOCTEST_NO_MAIN)
196#ifndef __cplusplus_cli
197#define DOCTEST_CONFIG_DISABLE
198#include "libraries/doctest.h"
199#endif
200#else
201#define DOCTEST_CONFIG_IMPLEMENT
202#include "libraries/doctest.h"
203
204#ifndef PWIZ_DOCTEST_NO_MAIN
205int main(int argc, char* argv[])
206{
207 TEST_PROLOG(argc, argv)
208
209 try
210 {
211 doctest::Context context;
212 testExitStatus = context.run();
213 }
214 catch (exception& e)
215 {
216 TEST_FAILED(e.what())
217 }
218 catch (...)
219 {
220 TEST_FAILED("Caught unknown exception.")
221 }
222
224}
225#endif
226
227namespace std
228{
229 template <typename T>
230 vector<doctest::Approx> operator~(const vector<T>& lhs)
231 {
232 vector<doctest::Approx> result(lhs.size(), doctest::Approx(0));
233 for (size_t i = 0; i < lhs.size(); ++i)
234 result[i] = doctest::Approx(lhs[i]);
235 return result;
236 }
237
238 inline ostream& operator<< (ostream& o, const doctest::Approx& rhs)
239 {
240 o << rhs.toString();
241 return o;
242 }
243
244 template <typename T>
245 bool operator==(const vector<T>& lhs, const vector<doctest::Approx>& rhs)
246 {
247 if (doctest::isRunningInTest())
248 REQUIRE(lhs.size() == rhs.size());
249 else if (lhs.size() != rhs.size())
250 return false;
251
252 for (size_t i = 0; i < lhs.size(); ++i)
253 if (lhs[i] != rhs[i]) return false;
254 return true;
255 }
256
257 template <typename T>
258 bool operator==(const vector<doctest::Approx>& rhs, const vector<T>& lhs)
259 {
260 return lhs == rhs;
261 }
262}
263#endif
264
265
266#endif // _UNIT_HPP_
267
int main(int argc, char *argv[])
KernelTraitsBase< Kernel >::space_type::abscissa_type x
KernelTraitsBase< Kernel >::space_type::ordinate_type y
const double epsilon
Definition DiffTest.cpp:41
PWIZ_API_DECL bool operator==(const TruncatedLorentzianParameters &t, const TruncatedLorentzianParameters &u)
std::string unit_assert_message(const char *filename, int line, const char *expression)
Definition unit.hpp:53
std::string unit_assert_exception_message(const char *filename, int line, const char *expression, const std::string &exception)
Definition unit.hpp:75
std::string unit_assert_numeric_equal_message(const char *filename, int line, double x, double y, double epsilon)
Definition unit.hpp:67
std::string escape_teamcity_string(const std::string &str)
Definition unit.hpp:145
std::string unit_assert_equal_message(const char *filename, int line, const std::string &x, const std::string &y, const char *expression)
Definition unit.hpp:60
std::string quote_string(const string &str)
Definition unit.hpp:82
STL namespace.
ostream & operator<<(ostream &os, SpectrumListCache::CacheType &cache)
#define TEST_EPILOG
Definition unit.hpp:183
#define TEST_FAILED(x)
Definition unit.hpp:177
#define TEST_PROLOG(argc, argv)
Definition unit.hpp:175