1 /* *****************************************************************
2 MESQUITE -- The Mesh Quality Improvement Toolkit
3
4 Copyright 2006 Lawrence Livermore National Laboratory. Under
5 the terms of Contract B545069 with the University of Wisconsin --
6 Madison, Lawrence Livermore National Laboratory retains certain
7 rights in this software.
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
13
14 This library 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.
18
19 You should have received a copy of the GNU Lesser General Public License
20 (lgpl.txt) along with this library; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
23 (2006) kraftche@cae.wisc.edu
24
25 ***************************************************************** */
26
27
28 /** \file UnitUtil.hpp
29 * \brief Utility functions for use in unit tests
30 * \author Jason Kraftcheck
31 */
32
33 #ifndef MSQ_UNIT_UTIL_HPP
34 #define MSQ_UNIT_UTIL_HPP
35
36 #include "Mesquite.hpp"
37 #include "Vector3D.hpp"
38 #include "Matrix3D.hpp"
39 #include "MsqMatrix.hpp"
40 #include "MsqError.hpp"
41
42 #include <string>
43 #include <stdio.h>
44
45 #include "cppunit/extensions/HelperMacros.h"
46
47 #define ASSERT_MESSAGE( MSG, COND ) \
48 CPPUNIT_NS::Asserter::failIf( !(COND), (MSG), CPPUNIT_SOURCELINE() )
49
50 /** Assert that MBMesquite API has not flagged an error */
51 #define ASSERT_NO_ERROR( A ) \
52 ASSERT_MESSAGE( (A).error_message(), ! MSQ_CHKERR( (A) ) )
53
54 /**\brief compare two vectors (Vector3D)
55 *
56 * Ensure that the test result Vector3D \a v2 is within \a eps of the
57 * expected vector \a v1 .
58 */
59 #define CPPUNIT_ASSERT_VECTORS_EQUAL( v1, v2, eps ) \
60 ASSERT_MESSAGE( utest_vect_message((v1),(v2)), \
61 utest_vect_equal((v1),(v2),(eps)) )
62
63 /**\brief compare two matrices (Matrix3D)
64 *
65 * Ensure that the test result Matrix3D \a m2 is within \a eps of the
66 * expected matrix \a m1
67 */
68 #define CPPUNIT_ASSERT_MATRICES_EQUAL( m1, m2, eps ) \
69 ASSERT_MESSAGE( utest_mat_message((m1),(m2)), \
70 utest_mat_equal((m1),(m2),(eps)) )
71
72
73 /** compare matrix (MsqMatrix) with the identity matrix */
74 #define ASSERT_IDENTITY_MATRIX( M ) \
75 ASSERT_MESSAGE( ident_check_msg(M), ident_check(M) )
76
77 /** compare two matrices (MsqMatrix) */
78 #define ASSERT_MATRICES_EQUAL( A, B, E ) \
79 ASSERT_MESSAGE( mat_equal_check_msg( A, B), mat_equal_check(A,B,E) )
80
81 /** compare two matrices (MsqMatrix) */
82 #define ASSERT_MATRICES_DIFFERENT( A, B, E ) \
83 ASSERT_MESSAGE( mat_not_equal_check_msg(A, B), !mat_equal_check(A,B,E) )
84
85 /** compare two arrays of values */
86 #define ASSERT_ARRAYS_EQUAL( A, B, LEN ) \
87 CPPUNIT_NS::Asserter::failIf( !(arrays_equal((A),(B),(LEN))), arrays_not_equal_msg((A),(LEN),(B),(LEN)), CPPUNIT_SOURCELINE() )
88
89 #define ASSERT_STD_VECTORS_EQUAL( A, B ) \
90 CPPUNIT_NS::Asserter::failIf( ((A) != (B)), arrays_not_equal_msg(&(A)[0],(A).size(),&(B)[0],(B).size()), CPPUNIT_SOURCELINE() )
91
92
93 /** make string representation of cartesian vector */
utest_vect_str(const MBMesquite::Vector3D & v)94 inline std::string utest_vect_str( const MBMesquite::Vector3D& v )
95 {
96 char buffer[128];
97 sprintf(buffer, "[%f, %f, %f]", v[0], v[1], v[2]);
98 return buffer;
99 }
100
101 /** make string representation of 3x3 matrix */
utest_mat_str(const MBMesquite::Matrix3D & m)102 inline std::string utest_mat_str( const MBMesquite::Matrix3D& m )
103 {
104 char buffer[256];
105 sprintf(buffer, "[%f, %f, %f] [%f, %f, %f] [%f, %f, %f]",
106 m[0][0], m[0][1], m[0][2],
107 m[1][0], m[1][1], m[1][2],
108 m[2][0], m[2][1], m[2][2] );
109 return buffer;
110 }
111
112 /** make string representation of 3x3 symetric matrix */
utest_mat_str(const MBMesquite::SymMatrix3D & m)113 inline std::string utest_mat_str( const MBMesquite::SymMatrix3D& m )
114 {
115 char buffer[256];
116 sprintf(buffer, "[%f, %f, %f] [%f, %f, %f] [%f, %f, %f]",
117 m(0,0), m(0,1), m(0,2),
118 m(1,0), m(1,1), m(1,2),
119 m(2,0), m(2,1), m(2,2) );
120 return buffer;
121 }
122
123 /** make error message for failed vector copmarison */
utest_vect_message(const MBMesquite::Vector3D & v1,const MBMesquite::Vector3D & v2)124 inline CppUnit::Message utest_vect_message( const MBMesquite::Vector3D& v1,
125 const MBMesquite::Vector3D& v2 )
126 {
127 CppUnit::Message m( "equality assertion failed" );
128 m.addDetail( std::string("Expected: ") + utest_vect_str(v1) );
129 m.addDetail( std::string("Actual : ") + utest_vect_str(v2) );
130 return m;
131 }
132
133 /** make error message for failed matrix copmarison */
utest_mat_message(const MBMesquite::Matrix3D & m1,const MBMesquite::Matrix3D & m2)134 inline CppUnit::Message utest_mat_message( const MBMesquite::Matrix3D& m1,
135 const MBMesquite::Matrix3D& m2 )
136 {
137 CppUnit::Message m( "equality assertion failed" );
138 m.addDetail( std::string("Expected: ") + utest_mat_str(m1) );
139 m.addDetail( std::string("Actual : ") + utest_mat_str(m2) );
140 return m;
141 }
142
143 /** make error message for failed symmetric matrix copmarison */
utest_mat_message(const MBMesquite::SymMatrix3D & m1,const MBMesquite::SymMatrix3D & m2)144 inline CppUnit::Message utest_mat_message( const MBMesquite::SymMatrix3D& m1,
145 const MBMesquite::SymMatrix3D& m2 )
146 {
147 CppUnit::Message m( "equality assertion failed" );
148 m.addDetail( std::string("Expected: ") + utest_mat_str(m1) );
149 m.addDetail( std::string("Actual : ") + utest_mat_str(m2) );
150 return m;
151 }
152
153 /** compare vectors */
utest_vect_equal(const MBMesquite::Vector3D & v1,const MBMesquite::Vector3D & v2,double eps)154 inline bool utest_vect_equal( const MBMesquite::Vector3D& v1, const MBMesquite::Vector3D& v2, double eps )
155 {
156 return (fabs(v1[0] - v2[0]) < eps) &&
157 (fabs(v1[1] - v2[1]) < eps) &&
158 (fabs(v1[2] - v2[2]) < eps);
159 }
160
161 /** compare matrices */
utest_mat_equal(const MBMesquite::Matrix3D & m1,const MBMesquite::Matrix3D & m2,double eps)162 inline bool utest_mat_equal( const MBMesquite::Matrix3D& m1, const MBMesquite::Matrix3D& m2, double eps )
163 {
164 return (fabs(m1[0][0] - m2[0][0]) < eps) &&
165 (fabs(m1[0][1] - m2[0][1]) < eps) &&
166 (fabs(m1[0][2] - m2[0][2]) < eps) &&
167 (fabs(m1[1][0] - m2[1][0]) < eps) &&
168 (fabs(m1[1][1] - m2[1][1]) < eps) &&
169 (fabs(m1[1][2] - m2[1][2]) < eps) &&
170 (fabs(m1[2][0] - m2[2][0]) < eps) &&
171 (fabs(m1[2][1] - m2[2][1]) < eps) &&
172 (fabs(m1[2][2] - m2[2][2]) < eps);
173 }
174
175 /** compare matrices */
utest_mat_equal(const MBMesquite::SymMatrix3D & m1,const MBMesquite::SymMatrix3D & m2,double eps)176 inline bool utest_mat_equal( const MBMesquite::SymMatrix3D& m1, const MBMesquite::SymMatrix3D& m2, double eps )
177 {
178 return (fabs(m1(0,0) - m2(0,0)) < eps) &&
179 (fabs(m1(0,1) - m2(0,1)) < eps) &&
180 (fabs(m1(0,2) - m2(0,2)) < eps) &&
181 (fabs(m1(1,1) - m2(1,1)) < eps) &&
182 (fabs(m1(1,2) - m2(1,2)) < eps) &&
183 (fabs(m1(2,2) - m2(2,2)) < eps);
184 }
185
186 template <unsigned R, unsigned C>
msq_mat_str(const MBMesquite::MsqMatrix<R,C> & m)187 inline std::string msq_mat_str( const MBMesquite::MsqMatrix<R,C>& m )
188 {
189 std::ostringstream os;
190 for (unsigned i = 0; i < R; ++i) {
191 os << "[" << m(i,0);
192 for (unsigned j = 1; j < C; ++j)
193 os << ", " << m(i,j);
194 os << "]";
195 }
196 return os.str();
197 }
198
199 template <unsigned R, unsigned C>
ident_check_msg(const MBMesquite::MsqMatrix<R,C> & m)200 inline CppUnit::Message ident_check_msg( const MBMesquite::MsqMatrix<R,C>& m )
201 {
202 CppUnit::Message mes( "Identity Assertion Failed" );
203 mes.addDetail( std::string("Actual: ") + msq_mat_str(m) );
204 return mes;
205 }
206
207 template <unsigned R, unsigned C>
ident_check(const MBMesquite::MsqMatrix<R,C> & m)208 inline bool ident_check( const MBMesquite::MsqMatrix<R,C>& m )
209 {
210 for (unsigned i = 0; i < R; ++i)
211 for (unsigned j = 0; j < C; ++j)
212 if (i == j && fabs(m(i,j) - 1.0) > 1e-6)
213 return false;
214 else if (i != j && fabs(m(i,j)) > 1e-6)
215 return false;
216 return true;
217 }
218
219 template <unsigned R, unsigned C>
mat_equal_check_msg(const MBMesquite::MsqMatrix<R,C> & A,const MBMesquite::MsqMatrix<R,C> & B)220 inline CppUnit::Message mat_equal_check_msg( const MBMesquite::MsqMatrix<R,C>& A,
221 const MBMesquite::MsqMatrix<R,C>& B )
222 {
223 CppUnit::Message mes( "Matrix Equality Assertion Failed" );
224 mes.addDetail( std::string( "Expected: ") + msq_mat_str(A) );
225 mes.addDetail( std::string( "Actual: ") + msq_mat_str(B) );
226 return mes;
227 }
228
229 template <unsigned R, unsigned C>
mat_not_equal_check_msg(const MBMesquite::MsqMatrix<R,C> & A,const MBMesquite::MsqMatrix<R,C> & B)230 inline CppUnit::Message mat_not_equal_check_msg( const MBMesquite::MsqMatrix<R,C>& A,
231 const MBMesquite::MsqMatrix<R,C>& B )
232 {
233 CppUnit::Message mes( "Matrix Inequality Assertion Failed" );
234 mes.addDetail( std::string( "Expected: ") + msq_mat_str(A) );
235 mes.addDetail( std::string( "Actual: ") + msq_mat_str(B) );
236 return mes;
237 }
238
239 template <unsigned R, unsigned C>
mat_equal_check(const MBMesquite::MsqMatrix<R,C> & A,const MBMesquite::MsqMatrix<R,C> & B,double eps)240 inline bool mat_equal_check( const MBMesquite::MsqMatrix<R,C>& A,
241 const MBMesquite::MsqMatrix<R,C>& B,
242 double eps )
243 {
244 for (unsigned i = 0; i < R; ++i)
245 for (unsigned j = 0; j < C; ++j)
246 if (fabs(A(i,j)-B(i,j)) > eps)
247 return false;
248 return true;
249 }
250
251 template <typename T1, typename T2>
arrays_equal(const T1 * A,const T2 * B,size_t len)252 inline bool arrays_equal( const T1* A, const T2* B, size_t len )
253 {
254 for (size_t i = 0; i < len; ++i)
255 if (A[i] != B[i])
256 return false;
257 return true;
258 }
259
260 template <typename T1, typename T2>
arrays_not_equal_msg(const T1 * A,size_t A_len,const T2 * B,size_t B_len)261 inline CppUnit::Message arrays_not_equal_msg( const T1* A, size_t A_len,
262 const T2* B, size_t B_len )
263 {
264 CppUnit::Message mes( "Equality Assertion Failed for Arrays" );
265
266 std::ostringstream strA;
267 if (A_len == 0)
268 strA << "(empty)";
269 else {
270 strA << '[' << A[0];
271 for (size_t i = 1; i < A_len; ++i)
272 strA << ',' << A[i];
273 strA << ']';
274 }
275 mes.addDetail( std::string( "Expected: ") + strA.str() );
276
277 std::ostringstream strB;
278 if (B_len == 0)
279 strB << "(empty)";
280 else {
281 strB << '[' << B[0];
282 for (size_t i = 1; i < B_len; ++i)
283 strB << ',' << B[i];
284 strB << ']';
285 }
286 mes.addDetail( std::string( "Actual: ") + strB.str() );
287
288 return mes;
289 }
290
291 #endif
292