ITK 6.0.0
Insight Toolkit
 
Loading...
Searching...
No Matches
itkGTestPredicate.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright NumFOCUS
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * https://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18
19#ifndef itkGTestPredicate_h
20#define itkGTestPredicate_h
21
22
23#include "gtest/gtest.h"
24
25#include "itkNumericTraits.h"
27#include "itkMetaDataObject.h"
28#include <cmath>
29
30
35#define ITK_EXPECT_VECTOR_NEAR(val1, val2, rmsError) \
36 EXPECT_PRED_FORMAT3(itk::GTest::Predicate::VectorDoubleRMSPredFormat, val1, val2, rmsError)
37
40#define ITK_EXPECT_METADATA_VALUE(metaDict, key, knownValue) \
41 EXPECT_PRED_FORMAT3(itk::GTest::Predicate::CheckMetaDataPredFormat, metaDict, key, knownValue)
42
43
49{
50
54template <typename T>
55inline ::testing::AssertionResult
56CheckMetaDataPredFormat(const char * metaDictExpr,
57 const char * keyExpr,
58 const char * knownValueExpr,
59 itk::MetaDataDictionary & metaDict,
60 const std::string & key,
61 const T & knownValue)
62{
63 T exposedValue{};
64
65#if defined ITK_FUTURE_LEGACY_REMOVE
66 static_assert(
67 !std::is_same_v<itk::Array<char>, T>,
68 "Should not use the ambiguous 'char' stored in meta data, because it is not-cross platform consistent.");
69 static_assert(
70 !std::is_same_v<char, T>,
71 "Should not use the ambiguous 'char' stored in meta data, because it is not-cross platform consistent.");
72 if (!itk::ExposeMetaData<T>(metaDict, key, exposedValue))
73 {
74 return ::testing::AssertionFailure() << "Failure ExposeMetaData for key '" << key << "' (" << keyExpr << ") in "
75 << metaDictExpr;
76 }
77#else
78 if constexpr (std::is_same_v<itk::Array<char>, T>)
79 {
80 if (!itk::ExposeMetaData<itk::Array<char>>(metaDict, key, exposedValue))
81 {
82 if constexpr (std::is_signed_v<char>)
83 {
84 itk::Array<signed char> temp_value{};
85 if (!itk::ExposeMetaData<itk::Array<signed char>>(metaDict, key, temp_value))
86 {
87 return ::testing::AssertionFailure()
88 << "Failure ExposeMetaData '" << key << "' (" << keyExpr << ") in " << metaDictExpr;
89 }
90 exposedValue = temp_value;
91 }
92 else
93 {
94 itk::Array<unsigned char> temp_value{};
95 if (!itk::ExposeMetaData<itk::Array<unsigned char>>(metaDict, key, temp_value))
96 {
97 return ::testing::AssertionFailure()
98 << "Failure ExposeMetaData '" << key << "' (" << keyExpr << ") in " << metaDictExpr;
99 }
100 exposedValue = temp_value;
101 }
102 }
103 }
104 else if constexpr (std::is_same_v<char, T>)
105 {
106 if (!itk::ExposeMetaData<char>(metaDict, key, exposedValue))
107 {
108 if constexpr (std::is_signed_v<char>)
109 {
110 signed char temp_value{};
111 if (!itk::ExposeMetaData<signed char>(metaDict, key, temp_value))
112 {
113 return ::testing::AssertionFailure()
114 << "Failure ExposeMetaData '" << key << "' (" << keyExpr << ") in " << metaDictExpr;
115 }
116 exposedValue = static_cast<T>(temp_value);
117 }
118 else
119 {
120 unsigned char temp_value{};
121 if (!itk::ExposeMetaData<unsigned char>(metaDict, key, temp_value))
122 {
123 return ::testing::AssertionFailure()
124 << "Failure ExposeMetaData '" << key << "' (" << keyExpr << ") in " << metaDictExpr;
125 }
126 exposedValue = static_cast<T>(temp_value);
127 }
128 }
129 }
130 else if (!itk::ExposeMetaData<T>(metaDict, key, exposedValue))
131 {
132 return ::testing::AssertionFailure() << "Failure ExposeMetaData for key '" << key << "' (" << keyExpr << ") in "
133 << metaDictExpr;
134 }
135#endif
136
137 bool match = false;
138 if constexpr (std::is_floating_point_v<T>)
139 {
140 match = itk::Math::AlmostEquals(exposedValue, knownValue);
141 }
142 else
143 {
144 match = (exposedValue == knownValue);
145 }
146
147 if (match)
148 {
149 return ::testing::AssertionSuccess();
150 }
151
152 ::testing::AssertionResult failure = ::testing::AssertionFailure();
153 failure << "Incorrect meta value read in for " << keyExpr << " ('" << key << "') in " << metaDictExpr << "\n"
154 << " Actual: " << exposedValue << "\n"
155 << " Expected: " << knownValue << " (" << knownValueExpr << ")\n";
156 failure << "========================================\n";
157 std::stringstream ss;
158 metaDict.Print(ss);
159 failure << ss.str();
160 failure << "========================================";
161 return failure;
162}
163
164
171template <typename T1, typename T2>
172inline ::testing::AssertionResult
173VectorDoubleRMSPredFormat(const char * expr1,
174 const char * expr2,
175 const char * rmsErrorExpr,
176 const T1 & val1,
177 const T2 & val2,
178 double rmsError)
179{
180 const size_t val1Size = itk::NumericTraits<T1>::GetLength(val1);
181 const size_t val2Size = itk::NumericTraits<T2>::GetLength(val2);
182 if (val1Size != val2Size)
183 {
184 return ::testing::AssertionFailure() << "The size of " << expr1 << " and " << expr2 << " different, where\n"
185 << expr1 << " evaluates to " << val1 << ",\n"
186 << expr2 << " evaluates to " << val2 << '.';
187 }
188 double total = 0.0;
189 for (unsigned int i = 0; i < val1Size; ++i)
190 {
191 const double temp = (val1[i] - val2[i]);
192 total += temp * temp;
193 }
194 const double rms = std::sqrt(total / val1Size);
195 if (rms <= rmsError)
196 {
197 return ::testing::AssertionSuccess();
198 }
199
200 return ::testing::AssertionFailure() << "The RMS difference between " << expr1 << " and " << expr2 << " is " << rms
201 << ",\n which exceeds " << rmsErrorExpr << ", where\n"
202 << expr1 << " evaluates to " << val1 << ",\n"
203 << expr2 << " evaluates to " << val2 << ", and\n"
204 << rmsErrorExpr << " evaluates to " << rmsError << '.';
205}
206
207} // namespace itk::GTest::Predicate
208// end namespace GTest
209
210#endif // itkGTestPredicate_h
Array class with size defined at construction time.
Definition itkArray.h:48
Provides a mechanism for storing a collection of arbitrary data types.
virtual void Print(std::ostream &os) const
static constexpr unsigned int GetLength()
The Predicate namespace contains functions used to implement custom GTest Predicate-Formatters.
inline ::testing::AssertionResult VectorDoubleRMSPredFormat(const char *expr1, const char *expr2, const char *rmsErrorExpr, const T1 &val1, const T2 &val2, double rmsError)
inline ::testing::AssertionResult CheckMetaDataPredFormat(const char *metaDictExpr, const char *keyExpr, const char *knownValueExpr, itk::MetaDataDictionary &metaDict, const std::string &key, const T &knownValue)
bool AlmostEquals(T1 x1, T2 x2)
Provide consistent equality checks between values of potentially different scalar or complex types.
Definition itkMath.h:680
bool ExposeMetaData(const MetaDataDictionary &Dictionary, const std::string key, T &outval)