gtsam  4.1.0
gtsam
TestableAssertions.h
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------------
2 
3  * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4  * Atlanta, Georgia 30332-0415
5  * All Rights Reserved
6  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7 
8  * See LICENSE for the license information
9 
10  * -------------------------------------------------------------------------- */
11 
18 #pragma once
19 
20 #include <gtsam/base/Testable.h>
21 #include <gtsam/global_includes.h>
22 
23 #include <boost/optional.hpp>
24 #include <map>
25 #include <iostream>
26 #include <sstream>
27 #include <vector>
28 
29 namespace gtsam {
30 
34 inline bool assert_equal(const Key& expected, const Key& actual, double tol = 0.0) {
35  if(expected != actual) {
36  std::cout << "Not equal:\nexpected: " << expected << "\nactual: " << actual << std::endl;
37  return false;
38  }
39  return true;
40 }
41 
49 template<class V>
50 bool assert_equal(const boost::optional<V>& expected,
51  const boost::optional<V>& actual, double tol = 1e-9) {
52  if (!expected && actual) {
53  std::cout << "expected is boost::none, while actual is not" << std::endl;
54  return false;
55  }
56  if (expected && !actual) {
57  std::cout << "actual is boost::none, while expected is not" << std::endl;
58  return false;
59  }
60  if (!expected && !actual)
61  return true;
62  return assert_equal(*expected, *actual, tol);
63 }
64 
65 template<class V>
66 bool assert_equal(const V& expected, const boost::optional<V>& actual, double tol = 1e-9) {
67  if (!actual) {
68  std::cout << "actual is boost::none" << std::endl;
69  return false;
70  }
71  return assert_equal(expected, *actual, tol);
72 }
73 
74 template<class V>
75 bool assert_equal(const V& expected, const boost::optional<const V&>& actual, double tol = 1e-9) {
76  if (!actual) {
77  std::cout << "actual is boost::none" << std::endl;
78  return false;
79  }
80  return assert_equal(expected, *actual, tol);
81 }
82 
87 template<class V>
88 bool assert_equal(const std::vector<V>& expected, const std::vector<V>& actual, double tol = 1e-9) {
89  bool match = true;
90  if (expected.size() != actual.size())
91  match = false;
92  if(match) {
93  size_t i = 0;
94  for(const V& a: expected) {
95  if (!assert_equal(a, actual[i++], tol)) {
96  match = false;
97  break;
98  }
99  }
100  }
101  if(!match) {
102  std::cout << "expected: " << std::endl;
103  for(const V& a: expected) { std::cout << a << " "; }
104  std::cout << "\nactual: " << std::endl;
105  for(const V& a: actual) { std::cout << a << " "; }
106  std::cout << std::endl;
107  return false;
108  }
109  return true;
110 }
111 
116 template<class V1, class V2>
117 bool assert_container_equal(const std::map<V1,V2>& expected, const std::map<V1,V2>& actual, double tol = 1e-9) {
118  typedef typename std::map<V1,V2> Map;
119  bool match = true;
120  if (expected.size() != actual.size())
121  match = false;
122  typename Map::const_iterator
123  itExp = expected.begin(),
124  itAct = actual.begin();
125  if(match) {
126  for (; itExp!=expected.end() && itAct!=actual.end(); ++itExp, ++itAct) {
127  if (!assert_equal(itExp->first, itAct->first, tol) ||
128  !assert_equal(itExp->second, itAct->second, tol)) {
129  match = false;
130  break;
131  }
132  }
133  }
134  if(!match) {
135  std::cout << "expected: " << std::endl;
136  for(const typename Map::value_type& a: expected) {
137  a.first.print("key");
138  a.second.print(" value");
139  }
140  std::cout << "\nactual: " << std::endl;
141  for(const typename Map::value_type& a: actual) {
142  a.first.print("key");
143  a.second.print(" value");
144  }
145  std::cout << std::endl;
146  return false;
147  }
148  return true;
149 }
150 
154 template<class V2>
155 bool assert_container_equal(const std::map<size_t,V2>& expected, const std::map<size_t,V2>& actual, double tol = 1e-9) {
156  typedef typename std::map<size_t,V2> Map;
157  bool match = true;
158  if (expected.size() != actual.size())
159  match = false;
160  typename Map::const_iterator
161  itExp = expected.begin(),
162  itAct = actual.begin();
163  if(match) {
164  for (; itExp!=expected.end() && itAct!=actual.end(); ++itExp, ++itAct) {
165  if (itExp->first != itAct->first ||
166  !assert_equal(itExp->second, itAct->second, tol)) {
167  match = false;
168  break;
169  }
170  }
171  }
172  if(!match) {
173  std::cout << "expected: " << std::endl;
174  for(const typename Map::value_type& a: expected) {
175  std::cout << "Key: " << a.first << std::endl;
176  a.second.print(" value");
177  }
178  std::cout << "\nactual: " << std::endl;
179  for(const typename Map::value_type& a: actual) {
180  std::cout << "Key: " << a.first << std::endl;
181  a.second.print(" value");
182  }
183  std::cout << std::endl;
184  return false;
185  }
186  return true;
187 }
188 
192 template<class V1, class V2>
193 bool assert_container_equal(const std::vector<std::pair<V1,V2> >& expected,
194  const std::vector<std::pair<V1,V2> >& actual, double tol = 1e-9) {
195  typedef typename std::vector<std::pair<V1,V2> > VectorPair;
196  bool match = true;
197  if (expected.size() != actual.size())
198  match = false;
199  typename VectorPair::const_iterator
200  itExp = expected.begin(),
201  itAct = actual.begin();
202  if(match) {
203  for (; itExp!=expected.end() && itAct!=actual.end(); ++itExp, ++itAct) {
204  if (!assert_equal(itExp->first, itAct->first, tol) ||
205  !assert_equal(itExp->second, itAct->second, tol)) {
206  match = false;
207  break;
208  }
209  }
210  }
211  if(!match) {
212  std::cout << "expected: " << std::endl;
213  for(const typename VectorPair::value_type& a: expected) {
214  a.first.print( " first ");
215  a.second.print(" second");
216  }
217  std::cout << "\nactual: " << std::endl;
218  for(const typename VectorPair::value_type& a: actual) {
219  a.first.print( " first ");
220  a.second.print(" second");
221  }
222  std::cout << std::endl;
223  return false;
224  }
225  return true;
226 }
227 
228 
232 template<class V>
233 bool assert_container_equal(const V& expected, const V& actual, double tol = 1e-9) {
234  bool match = true;
235  typename V::const_iterator
236  itExp = expected.begin(),
237  itAct = actual.begin();
238  if(match) {
239  for (; itExp!=expected.end() && itAct!=actual.end(); ++itExp, ++itAct) {
240  if (!assert_equal(*itExp, *itAct, tol)) {
241  match = false;
242  break;
243  }
244  }
245  if(itExp != expected.end() || itAct != actual.end())
246  match = false;
247  }
248  if(!match) {
249  std::cout << "expected: " << std::endl;
250  for(const typename V::value_type& a: expected) { a.print(" "); }
251  std::cout << "\nactual: " << std::endl;
252  for(const typename V::value_type& a: actual) { a.print(" "); }
253  std::cout << std::endl;
254  return false;
255  }
256  return true;
257 }
258 
263 template<class V2>
264 bool assert_container_equality(const std::map<size_t,V2>& expected, const std::map<size_t,V2>& actual) {
265  typedef typename std::map<size_t,V2> Map;
266  bool match = true;
267  if (expected.size() != actual.size())
268  match = false;
269  typename Map::const_iterator
270  itExp = expected.begin(),
271  itAct = actual.begin();
272  if(match) {
273  for (; itExp!=expected.end() && itAct!=actual.end(); ++itExp, ++itAct) {
274  if (itExp->first != itAct->first || itExp->second != itAct->second) {
275  match = false;
276  break;
277  }
278  }
279  }
280  if(!match) {
281  std::cout << "expected: " << std::endl;
282  for(const typename Map::value_type& a: expected) {
283  std::cout << "Key: " << a.first << std::endl;
284  std::cout << "Value: " << a.second << std::endl;
285  }
286  std::cout << "\nactual: " << std::endl;
287  for(const typename Map::value_type& a: actual) {
288  std::cout << "Key: " << a.first << std::endl;
289  std::cout << "Value: " << a.second << std::endl;
290  }
291  std::cout << std::endl;
292  return false;
293  }
294  return true;
295 }
296 
297 
301 template<class V>
302 bool assert_container_equality(const V& expected, const V& actual) {
303  bool match = true;
304  if (expected.size() != actual.size())
305  match = false;
306  typename V::const_iterator
307  itExp = expected.begin(),
308  itAct = actual.begin();
309  if(match) {
310  for (; itExp!=expected.end() && itAct!=actual.end(); ++itExp, ++itAct) {
311  if (*itExp != *itAct) {
312  match = false;
313  break;
314  }
315  }
316  }
317  if(!match) {
318  std::cout << "expected: " << std::endl;
319  for(const typename V::value_type& a: expected) { std::cout << a << " "; }
320  std::cout << "\nactual: " << std::endl;
321  for(const typename V::value_type& a: actual) { std::cout << a << " "; }
322  std::cout << std::endl;
323  return false;
324  }
325  return true;
326 }
327 
331 inline bool assert_equal(const std::string& expected, const std::string& actual) {
332  if (expected == actual)
333  return true;
334  printf("Not equal:\n");
335  std::cout << "expected: [" << expected << "]\n";
336  std::cout << "actual: [" << actual << "]" << std::endl;
337  return false;
338 }
339 
343 template<class V>
344 bool assert_inequal(const V& expected, const V& actual, double tol = 1e-9) {
345  if (!actual.equals(expected, tol))
346  return true;
347  printf("Erroneously equal:\n");
348  expected.print("expected");
349  actual.print("actual");
350  return false;
351 }
352 
356 template<class V>
357 bool assert_stdout_equal(const std::string& expected, const V& actual) {
358  // Redirect output to buffer so we can compare
359  std::stringstream buffer;
360  // Save the original output stream so we can reset later
361  std::streambuf* old = std::cout.rdbuf(buffer.rdbuf());
362 
363  // We test against actual std::cout for faithful reproduction
364  std::cout << actual;
365 
366  // Get output string and reset stdout
367  std::string actual_ = buffer.str();
368  std::cout.rdbuf(old);
369 
370  return assert_equal(expected, actual_);
371 }
372 
376 template<class V>
377 bool assert_print_equal(const std::string& expected, const V& actual) {
378  // Redirect output to buffer so we can compare
379  std::stringstream buffer;
380  // Save the original output stream so we can reset later
381  std::streambuf* old = std::cout.rdbuf(buffer.rdbuf());
382 
383  // We test against actual std::cout for faithful reproduction
384  actual.print();
385 
386  // Get output string and reset stdout
387  std::string actual_ = buffer.str();
388  std::cout.rdbuf(old);
389 
390  return assert_equal(expected, actual_);
391 }
392 
393 } // \namespace gtsam
Testable.h
Concept check for values that can be used in unit tests.
gtsam::Key
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:61
gtsam::assert_print_equal
bool assert_print_equal(const std::string &expected, const V &actual)
Capture print function output and compare against string.
Definition: TestableAssertions.h:377
gtsam
Global functions in a separate testing namespace.
Definition: chartTesting.h:28
global_includes.h
Included from all GTSAM files.
gtsam::assert_inequal
bool assert_inequal(const Matrix &A, const Matrix &B, double tol)
inequals with an tolerance, prints out message if within tolerance
Definition: Matrix.cpp:62
gtsam::assert_container_equal
bool assert_container_equal(const std::map< V1, V2 > &expected, const std::map< V1, V2 > &actual, double tol=1e-9)
Function for comparing maps of testable->testable TODO: replace with more generalized version.
Definition: TestableAssertions.h:117
gtsam::assert_container_equality
bool assert_container_equality(const std::map< size_t, V2 > &expected, const std::map< size_t, V2 > &actual)
Function for comparing maps of size_t->testable Types are assumed to have operator ==.
Definition: TestableAssertions.h:264
gtsam::assert_equal
bool assert_equal(const Matrix &expected, const Matrix &actual, double tol)
equals with an tolerance, prints out message if unequal
Definition: Matrix.cpp:42
gtsam::assert_stdout_equal
bool assert_stdout_equal(const std::string &expected, const V &actual)
Capture std out via cout stream and compare against string.
Definition: TestableAssertions.h:357