2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2013, by the GROMACS development team, led by
5 * David van der Spoel, Berk Hess, Erik Lindahl, and including many
6 * others, as listed in the AUTHORS file in the top-level source
7 * directory and at http://www.gromacs.org.
9 * GROMACS is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1
12 * of the License, or (at your option) any later version.
14 * GROMACS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with GROMACS; if not, see
21 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * If you want to redistribute modifications to GROMACS, please
25 * consider that scientific software is very special. Version
26 * control is crucial - bugs must be traceable. We will be happy to
27 * consider code for inclusion in the official distribution, but
28 * derived work must not be called official GROMACS. Details are found
29 * in the README & COPYING files - if they are missing, get the
30 * official version at http://www.gromacs.org.
32 * To help us fund GROMACS development, we humbly ask that you cite
33 * the research papers on the package. Check out http://www.gromacs.org.
35 /*! \libinternal \file
37 * Extra assertions for unit tests.
39 * This file provides assert macros to replace (ASSERT|EXPECT)(_NO)?_THROW
40 * from Google Test. They behave otherwise the same as the Google Test ones,
41 * but also print details of any unexpected exceptions. This makes it much
42 * easier to see at one glance what went wrong.
44 * This file also provides extra floating-point assertions.
48 * The implementation is somewhat ugly, and accesses some Google Test
49 * internals. Could be nice to clean it up a bit.
52 * \author Teemu Murtola <teemu.murtola@gmail.com>
54 * \ingroup module_testutils
56 #ifndef GMX_TESTUTILS_TESTASSERTS_H
57 #define GMX_TESTUTILS_TESTASSERTS_H
59 #include <gtest/gtest.h>
61 #include "gromacs/legacyheaders/maths.h"
63 #include "gromacs/utility/exceptions.h"
73 * Internal implementation macro for exception assertations.
75 * \param statement Statements to execute.
76 * \param expected_exception Exception type that \p statement should throw.
77 * \param fail Function/macro to call on failure.
79 * The implementation is copied and adjusted from
80 * include/gtest/internal/gtest-internal.h in Google Test 1.6.0.
82 #define GMX_TEST_THROW_(statement, expected_exception, fail) \
83 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
84 if (::testing::AssertionResult gmx_ar = ::testing::AssertionSuccess()) { \
85 bool gmx_caught_expected = false; \
87 GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
89 catch (expected_exception const &) { \
90 gmx_caught_expected = true; \
92 catch (std::exception const &ex) { \
93 gmx_ar << "Expected: " #statement " throws an exception of type " \
94 << #expected_exception ".\n Actual: it throws a different type.\n" \
95 << "Exception details:\n" << ::gmx::formatExceptionMessageToString(ex); \
96 goto GTEST_CONCAT_TOKEN_(gmx_label_testthrow_, __LINE__); \
99 gmx_ar << "Expected: " #statement " throws an exception of type " \
100 << #expected_exception ".\n Actual: it throws a different type."; \
101 goto GTEST_CONCAT_TOKEN_(gmx_label_testthrow_, __LINE__); \
103 if (!gmx_caught_expected) { \
104 gmx_ar << "Expected: " #statement " throws an exception of type " \
105 << #expected_exception ".\n Actual: it throws nothing."; \
106 goto GTEST_CONCAT_TOKEN_(gmx_label_testthrow_, __LINE__); \
109 GTEST_CONCAT_TOKEN_(gmx_label_testthrow_, __LINE__) : \
110 fail(gmx_ar.message())
114 * Internal implementation macro for exception assertations.
116 * \param statement Statements to execute.
117 * \param fail Function/macro to call on failure.
119 * The implementation is copied and adjusted from
120 * include/gtest/internal/gtest-internal.h in Google Test 1.6.0.
122 #define GMX_TEST_NO_THROW_(statement, fail) \
123 GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
124 if (::testing::AssertionResult gmx_ar = ::testing::AssertionSuccess()) { \
126 GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
128 catch (std::exception const &ex) { \
129 gmx_ar << "Expected: " #statement " doesn't throw an exception.\n" \
130 << " Actual: it throws.\n" \
131 << "Exception details:\n" << ::gmx::formatExceptionMessageToString(ex); \
132 goto GTEST_CONCAT_TOKEN_(gmx_label_testnothrow_, __LINE__); \
135 gmx_ar << "Expected: " #statement " doesn't throw an exception.\n" \
136 << " Actual: it throws."; \
137 goto GTEST_CONCAT_TOKEN_(gmx_label_testnothrow_, __LINE__); \
140 GTEST_CONCAT_TOKEN_(gmx_label_testnothrow_, __LINE__) : \
141 fail(gmx_ar.message())
145 * Asserts that a statement throws a given exception.
147 * See Google Test documentation on EXPECT_THROW.
148 * This macro works the same, but additionally prints details of unexpected
151 #define EXPECT_THROW_GMX(statement, expected_exception) \
152 GMX_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_)
154 * Asserts that a statement does not throw.
156 * See Google Test documentation on EXPECT_NO_THROW.
157 * This macro works the same, but additionally prints details of unexpected
160 #define EXPECT_NO_THROW_GMX(statement) \
161 GMX_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_)
163 * Asserts that a statement throws a given exception.
165 * See Google Test documentation on ASSERT_THROW.
166 * This macro works the same, but additionally prints details of unexpected
169 #define ASSERT_THROW_GMX(statement, expected_exception) \
170 GMX_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_)
172 * Asserts that a statement does not throw.
174 * See Google Test documentation on ASSERT_NO_THROW.
175 * This macro works the same, but additionally prints details of unexpected
178 #define ASSERT_NO_THROW_GMX(statement) \
179 GMX_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_)
181 /*! \cond internal */
183 * Assertion predicate formatter for comparing two floating-point values.
185 static ::testing::AssertionResult assertWithinRelativeTolerance(
186 const char *expr1, const char *expr2, const char * /*exprTolerance*/,
187 real val1, real val2, real relativeTolerance)
189 if (gmx_within_tol(val1, val2, relativeTolerance))
191 return ::testing::AssertionSuccess();
193 return ::testing::AssertionFailure()
194 << "Value of: " << expr2 << " not within tolerance of " << relativeTolerance << "\n"
195 << " Actual: " << val2 << "\n"
196 << "Expected: " << expr1 << "\n"
197 << "Which is: " << val1;
202 * Asserts that two floating-point values are within the given relative error.
204 * This assert works as EXPECT_NEAR from Google Test, except that it uses a
205 * relative instead of a absolute tolerance.
206 * See gmx_within_tol() for definition of the tolerance.
208 #define EXPECT_NEAR_REL(val1, val2, rel_error) \
209 EXPECT_PRED_FORMAT3(::gmx::test::assertWithinRelativeTolerance, val1, val2, rel_error)
211 * Asserts that two floating-point values are within the given relative error.
213 * This assert works as ASSERT_NEAR from Google Test, except that it uses a
214 * relative instead of a absolute tolerance.
215 * See gmx_within_tol() for definition of the tolerance.
217 #define ASSERT_NEAR_REL(val1, val2, rel_error) \
218 ASSERT_PRED_FORMAT3(::gmx::test::assertWithinRelativeTolerance, val1, val2, rel_error)