19#ifndef elxCoreMainGTestUtilities_h
20#define elxCoreMainGTestUtilities_h
26#include <itkImageBufferRange.h>
27#include <itkImageRegionRange.h>
34#include <initializer_list>
43#include <gtest/gtest.h>
48namespace CoreMainGTestUtilities
62 what() const noexcept
override
70#define ELX_GTEST_EXPECT_FALSE_AND_THROW_EXCEPTION_IF(condition) \
73 EXPECT_FALSE(true) << "Expected to be false: " #condition; \
74 throw ::elastix::CoreMainGTestUtilities::Exception("Exception thrown because " #condition); \
76 static_assert(true, "Expect a semi-colon ';' at the end of a macro call")
79template <
typename TRawPo
inter>
83 static_assert(std::is_pointer<TRawPointer>::value,
"For smart pointers, use DerefSmartPointer instead!");
87 throw Exception(
"Deref error: the pointer should not be null!");
93template <
typename TSmartPo
inter>
97 static_assert(!std::is_pointer<TSmartPointer>::value,
"For raw pointers, use Deref instead!");
101 throw Exception(
"Deref error: the (smart) pointer should not be null!");
113 if (container.empty())
115 throw Exception(
"Front error: the container should be non-empty!");
117 return container.front();
125 static_assert(std::is_same<
decltype(T::New()), itk::SmartPointer<T>>{},
126 "T::New() must return an itk::SmartPointer<T>!");
128 const auto ptr = T::New();
131 throw Exception(
"New() error: should not return null!");
137template <
typename TPixel,
unsigned int VImageDimension>
140 const itk::Index<VImageDimension> & regionIndex,
141 const itk::Size<VImageDimension> & regionSize)
143 const itk::ImageRegionRange<itk::Image<TPixel, VImageDimension>> imageRegionRange{
144 image, itk::ImageRegion<VImageDimension>{ regionIndex, regionSize }
146 std::fill(std::begin(imageRegionRange), std::end(imageRegionRange), 1);
152inline std::vector<double>
155 std::vector<double> result(strings.size());
157 std::transform(strings.cbegin(), strings.cend(), result.begin(), [](
const std::string & str) {
159 const auto result = std::stod(str, &index);
162 EXPECT_EQ(index, str.size());
171template <std::
size_t VDimension>
172itk::Offset<VDimension>
177 itk::Offset<VDimension> result;
180 for (
const double value : doubles)
182 const auto roundedValue = std::round(value);
184 EXPECT_GE(roundedValue, std::numeric_limits<itk::OffsetValueType>::min());
185 EXPECT_LE(roundedValue, std::numeric_limits<itk::OffsetValueType>::max());
187 result[i] =
static_cast<itk::OffsetValueType
>(roundedValue);
196 std::initializer_list<std::pair<std::string, std::string>> initializerList)
198 std::map<std::string, std::vector<std::string>> result;
200 for (
const auto & pair : initializerList)
202 EXPECT_TRUE(result.insert({ pair.first, { pair.second } }).second);
208template <
unsigned VImageDimension>
209std::map<std::string, std::vector<std::string>>
212 std::map<std::string, std::vector<std::string>> result =
CreateParameterMap(initializerList);
214 for (
const auto & key : {
"FixedImageDimension",
"MovingImageDimension" })
216 EXPECT_TRUE(result.insert({ key, { std::to_string(VImageDimension) } }).second);
223 std::initializer_list<std::pair<std::string, std::string>> initializerList)
225 const auto parameterObject = ParameterObject::New();
227 return parameterObject;
231inline std::vector<double>
235 EXPECT_EQ(transformParameterMaps.size(), 1);
237 if (transformParameterMaps.empty())
239 throw Exception(
"Error: GetTransformParametersFromMaps should not return an empty ParameterMap!");
242 const auto & transformParameterMap = transformParameterMaps.front();
243 const auto found = transformParameterMap.find(
"TransformParameters");
245 if (found == transformParameterMap.cend())
247 throw Exception(
"Error: GetTransformParametersFromMaps did not find TransformParameters!");
253template <
typename TFilter>
257 const auto transformParameterObject = filter.GetTransformParameterObject();
258 const auto & transformParameterMaps =
Deref(transformParameterObject).GetParameterMap();
264template <
typename TPixel,
unsigned VImageDimension>
268 const auto image = itk::Image<TPixel, VImageDimension>::New();
269 image->SetRegions(imageSize);
270 image->Allocate(
true);
276template <
typename TPixel,
unsigned VImageDimension>
280 using ImageType = itk::Image<TPixel, VImageDimension>;
281 const auto image = ImageType::New();
282 image->SetRegions(imageSize);
284 const itk::ImageBufferRange<ImageType> imageBufferRange{ *image };
285 std::iota(imageBufferRange.begin(), imageBufferRange.end(), TPixel{ 1 });
Simple exception class, to be used by unit tests.
const char * what() const noexcept override
Exception(const char *const message)
itk::SmartPointer< Self > Pointer
#define ELX_GTEST_EXPECT_FALSE_AND_THROW_EXCEPTION_IF(condition)
Expect the specified condition to be false, and throw an exception if it is true.
decltype(auto) DerefSmartPointer(const TSmartPointer &ptr)
std::vector< double > GetTransformParametersFromMaps(const std::vector< ParameterObject::ParameterMapType > &transformParameterMaps)
std::string GetNameOfTest(const testing::Test &)
std::string GetCurrentBinaryDirectoryPath()
auto CreateImageFilledWithSequenceOfNaturalNumbers(const itk::Size< VImageDimension > &imageSize)
decltype(T().front()) Front(T &container)
std::vector< double > GetTransformParametersFromFilter(TFilter &filter)
itk::SmartPointer< T > CheckNew()
std::string GetDataDirectoryPath()
std::map< std::string, std::vector< std::string > > CreateParameterMap(std::initializer_list< std::pair< std::string, std::string > > initializerList)
void FillImageRegion(itk::Image< TPixel, VImageDimension > &image, const itk::Index< VImageDimension > ®ionIndex, const itk::Size< VImageDimension > ®ionSize)
Fills the specified image region with pixel values 1.
decltype(auto) Deref(const TRawPointer ptr)
Dereferences the specified raw pointer. Throws an Exception instead, when the pointer is null.
ParameterObject::Pointer CreateParameterObject(std::initializer_list< std::pair< std::string, std::string > > initializerList)
auto CreateImage(const itk::Size< VImageDimension > &imageSize)
itk::Offset< VDimension > ConvertToOffset(const std::vector< double > &doubles)
std::vector< double > ConvertStringsToVectorOfDouble(const std::vector< std::string > &strings)