1 #ifndef __BLENDER_TESTING_H__
2 #define __BLENDER_TESTING_H__
3 
4 #include <vector>
5 
6 #include "gflags/gflags.h"
7 #include "glog/logging.h"
8 #include "gtest/gtest.h"
9 
10 namespace blender::tests {
11 
12 /* These strings are passed on the CLI with the --test-asset-dir and --test-release-dir arguments.
13  * The arguments are added automatically when invoking tests via `ctest`. */
14 const std::string &flags_test_asset_dir();   /* ../lib/tests in the SVN directory. */
15 const std::string &flags_test_release_dir(); /* bin/{blender version} in the build directory. */
16 
17 }  // namespace blender::tests
18 
19 #define EXPECT_V3_NEAR(a, b, eps) \
20   { \
21     EXPECT_NEAR(a[0], b[0], eps); \
22     EXPECT_NEAR(a[1], b[1], eps); \
23     EXPECT_NEAR(a[2], b[2], eps); \
24   } \
25   (void)0
26 
27 #define EXPECT_V4_NEAR(a, b, eps) \
28   { \
29     EXPECT_NEAR(a[0], b[0], eps); \
30     EXPECT_NEAR(a[1], b[1], eps); \
31     EXPECT_NEAR(a[2], b[2], eps); \
32     EXPECT_NEAR(a[3], b[3], eps); \
33   } \
34   (void)0
35 
36 #define EXPECT_M3_NEAR(a, b, eps) \
37   do { \
38     EXPECT_V3_NEAR(a[0], b[0], eps); \
39     EXPECT_V3_NEAR(a[1], b[1], eps); \
40     EXPECT_V3_NEAR(a[2], b[2], eps); \
41   } while (false);
42 
43 #define EXPECT_M4_NEAR(a, b, eps) \
44   do { \
45     EXPECT_V3_NEAR(a[0], b[0], eps); \
46     EXPECT_V3_NEAR(a[1], b[1], eps); \
47     EXPECT_V3_NEAR(a[2], b[2], eps); \
48     EXPECT_V4_NEAR(a[3], b[3], eps); \
49   } while (false);
50 
51 #define EXPECT_MATRIX_NEAR(a, b, tolerance) \
52   do { \
53     bool dims_match = (a.rows() == b.rows()) && (a.cols() == b.cols()); \
54     EXPECT_EQ(a.rows(), b.rows()) << "Matrix rows don't match."; \
55     EXPECT_EQ(a.cols(), b.cols()) << "Matrix cols don't match."; \
56     if (dims_match) { \
57       for (int r = 0; r < a.rows(); ++r) { \
58         for (int c = 0; c < a.cols(); ++c) { \
59           EXPECT_NEAR(a(r, c), b(r, c), tolerance) << "r=" << r << ", c=" << c << "."; \
60         } \
61       } \
62     } \
63   } while (false);
64 
65 #define EXPECT_MATRIX_NEAR_ZERO(a, tolerance) \
66   do { \
67     for (int r = 0; r < a.rows(); ++r) { \
68       for (int c = 0; c < a.cols(); ++c) { \
69         EXPECT_NEAR(0.0, a(r, c), tolerance) << "r=" << r << ", c=" << c << "."; \
70       } \
71     } \
72   } while (false);
73 
74 #define EXPECT_MATRIX_EQ(a, b) \
75   do { \
76     bool dims_match = (a.rows() == b.rows()) && (a.cols() == b.cols()); \
77     EXPECT_EQ(a.rows(), b.rows()) << "Matrix rows don't match."; \
78     EXPECT_EQ(a.cols(), b.cols()) << "Matrix cols don't match."; \
79     if (dims_match) { \
80       for (int r = 0; r < a.rows(); ++r) { \
81         for (int c = 0; c < a.cols(); ++c) { \
82           EXPECT_EQ(a(r, c), b(r, c)) << "r=" << r << ", c=" << c << "."; \
83         } \
84       } \
85     } \
86   } while (false);
87 
88 // Check that sin(angle(a, b)) < tolerance.
89 #define EXPECT_MATRIX_PROP(a, b, tolerance) \
90   do { \
91     bool dims_match = (a.rows() == b.rows()) && (a.cols() == b.cols()); \
92     EXPECT_EQ(a.rows(), b.rows()) << "Matrix rows don't match."; \
93     EXPECT_EQ(a.cols(), b.cols()) << "Matrix cols don't match."; \
94     if (dims_match) { \
95       double c = CosinusBetweenMatrices(a, b); \
96       if (c * c < 1) { \
97         double s = sqrt(1 - c * c); \
98         EXPECT_NEAR(0, s, tolerance); \
99       } \
100     } \
101   } while (false);
102 
103 #ifdef LIBMV_NUMERIC_NUMERIC_H
CosinusBetweenMatrices(const TMat & a,const TMat & b)104 template<class TMat> double CosinusBetweenMatrices(const TMat &a, const TMat &b)
105 {
106   return (a.array() * b.array()).sum() / libmv::FrobeniusNorm(a) / libmv::FrobeniusNorm(b);
107 }
108 #endif
109 
110 template<typename T>
EXPECT_EQ_VECTOR(const std::vector<T> & expected,const std::vector<T> & actual)111 inline void EXPECT_EQ_VECTOR(const std::vector<T> &expected, const std::vector<T> &actual)
112 {
113   EXPECT_EQ(expected.size(), actual.size());
114   if (expected.size() == actual.size()) {
115     for (size_t i = 0; i < expected.size(); ++i) {
116       EXPECT_EQ(expected[i], actual[i]) << "Element mismatch at index " << i;
117     }
118   }
119 }
120 
121 template<typename T>
EXPECT_EQ_ARRAY(const T * expected,const T * actual,const size_t N)122 inline void EXPECT_EQ_ARRAY(const T *expected, const T *actual, const size_t N)
123 {
124   for (size_t i = 0; i < N; ++i) {
125     EXPECT_EQ(expected[i], actual[i]) << "Element mismatch at index " << i;
126   }
127 }
128 
129 template<typename T>
EXPECT_EQ_ARRAY_ND(const T * expected,const T * actual,const size_t N,const size_t D)130 inline void EXPECT_EQ_ARRAY_ND(const T *expected, const T *actual, const size_t N, const size_t D)
131 {
132   for (size_t i = 0; i < N; ++i) {
133     for (size_t j = 0; j < D; ++j) {
134       EXPECT_EQ(expected[i][j], actual[i][j])
135           << "Element mismatch at index " << i << ", component index " << j;
136     }
137   }
138 }
139 
140 #endif  // __BLENDER_TESTING_H__
141