/* * Software License Agreement (BSD License) * * Point Cloud Library (PCL) - www.pointclouds.org * Copyright (c) 2010-2012, Willow Garage, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the copyright holder(s) nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * $Id$ */ #pragma once #include /** \file pcl_tests.h * Helper macros for testing equality of various data fields in PCL points */ namespace pcl { /** test_macros.h provide helper macros for testing vectors, matrices etc. * We took some liberty with upcasing names to make them look like googletest * macros names so that reader is not confused. * * This file also provides a family of googletest-style macros for asserting * equality or nearness of xyz, normal, and rgba fields. * * \author Nizar Sallem, Sergey Alexandrov */ namespace test { template void EXPECT_EQ_VECTORS (const V1& v1, const V2& v2) { SCOPED_TRACE("EXPECT_EQ_VECTORS failed"); EXPECT_EQ (v1.size (), v2.size ()); std::size_t length = v1.size (); for (std::size_t i = 0; i < length; ++i) EXPECT_EQ (v1[i], v2[i]); } template void EXPECT_NEAR_VECTORS (const V1& v1, const V2& v2, const Scalar& epsilon) { SCOPED_TRACE("EXPECT_NEAR_VECTORS failed"); EXPECT_EQ (v1.size (), v2.size ()); std::size_t length = v1.size (); for (std::size_t i = 0; i < length; ++i) EXPECT_NEAR (v1[i], v2[i], epsilon); } namespace internal { template ::testing::AssertionResult XYZEQ (const char* expr1, const char* expr2, const Point1T& p1, const Point2T& p2) { if ((p1).getVector3fMap ().cwiseEqual ((p2).getVector3fMap ()).all ()) return ::testing::AssertionSuccess (); return ::testing::AssertionFailure () << "Value of: " << expr2 << ".getVector3fMap ()" << std::endl << " Actual: " << p2.getVector3fMap ().transpose () << std::endl << "Expected: " << expr1 << ".getVector3fMap ()" << std::endl << "Which is: " << p1.getVector3fMap ().transpose (); } template ::testing::AssertionResult XYZNear (const char* expr1, const char* expr2, const char* abs_error_expr, const Point1T& p1, const Point2T& p2, double abs_error) { const Eigen::Vector3f diff = ((p1).getVector3fMap () - (p2).getVector3fMap ()).cwiseAbs (); if ((diff.array () < abs_error).all ()) return ::testing::AssertionSuccess (); return ::testing::AssertionFailure () << "Some of the element-wise differences exceed " << abs_error_expr << " (which evaluates to " << abs_error << ")" << std::endl << "Difference: " << diff.transpose () << std::endl << " Value of: " << expr2 << ".getVector3fMap ()" << std::endl << " Actual: " << p2.getVector3fMap ().transpose () << std::endl << " Expected: " << expr1 << ".getVector3fMap ()" << std::endl << " Which is: " << p1.getVector3fMap ().transpose (); } template ::testing::AssertionResult NormalEQ (const char* expr1, const char* expr2, const Point1T& p1, const Point2T& p2) { if ((p1).getNormalVector3fMap ().cwiseEqual ((p2).getNormalVector3fMap ()).all ()) return ::testing::AssertionSuccess (); return ::testing::AssertionFailure () << "Value of: " << expr2 << ".getNormalVector3fMap ()" << std::endl << " Actual: " << p2.getNormalVector3fMap ().transpose () << std::endl << "Expected: " << expr1 << ".getNormalVector3fMap ()" << std::endl << "Which is: " << p1.getNormalVector3fMap ().transpose (); } template ::testing::AssertionResult NormalNear (const char* expr1, const char* expr2, const char* abs_error_expr, const Point1T& p1, const Point2T& p2, double abs_error) { const Eigen::Vector3f diff = ((p1).getNormalVector3fMap () - (p2).getNormalVector3fMap ()).cwiseAbs (); if ((diff.array () < abs_error).all ()) return ::testing::AssertionSuccess (); return ::testing::AssertionFailure () << "Some of the element-wise differences exceed " << abs_error_expr << " (which evaluates to " << abs_error << ")" << std::endl << "Difference: " << diff.transpose () << std::endl << " Value of: " << expr2 << ".getNormalVector3fMap ()" << std::endl << " Actual: " << p2.getNormalVector3fMap ().transpose () << std::endl << " Expected: " << expr1 << ".getNormalVector3fMap ()" << std::endl << " Which is: " << p1.getNormalVector3fMap ().transpose (); } template ::testing::AssertionResult RGBEQ (const char* expr1, const char* expr2, const Point1T& p1, const Point2T& p2) { if ((p1).getRGBVector3i ().cwiseEqual ((p2).getRGBVector3i ()).all ()) return ::testing::AssertionSuccess (); return ::testing::AssertionFailure () << "Value of: " << expr2 << ".getRGBVector3i ()" << std::endl << " Actual: " << p2.getRGBVector3i ().transpose () << std::endl << "Expected: " << expr1 << ".getRGBVector3i ()" << std::endl << "Which is: " << p1.getRGBVector3i ().transpose (); } template ::testing::AssertionResult RGBAEQ (const char* expr1, const char* expr2, const Point1T& p1, const Point2T& p2) { if ((p1).getRGBAVector4i ().cwiseEqual ((p2).getRGBAVector4i ()).all ()) return ::testing::AssertionSuccess (); return ::testing::AssertionFailure () << "Value of: " << expr2 << ".getRGBAVector4i ()" << std::endl << " Actual: " << p2.getRGBAVector4i ().transpose () << std::endl << "Expected: " << expr1 << ".getRGBAVector4i ()" << std::endl << "Which is: " << p1.getRGBAVector4i ().transpose (); } template ::testing::AssertionResult MetaDataEQ (const char* expr1, const char* expr2, const PointCloud1T& p1, const PointCloud2T& p2) { if (!(p1.header == p2.header)) return ::testing::AssertionFailure () << "Headers are different"; if (p1.width != p2.width) return ::testing::AssertionFailure () << "Value of: " << expr2 << ".width" << std::endl << " Actual: " << p2.width << std::endl << "Expected: " << expr1 << ".width" << std::endl << "Which is: " << p1.width << std::endl; if (p1.height != p2.height) return ::testing::AssertionFailure () << "Value of: " << expr2 << ".height" << std::endl << " Actual: " << p2.height << std::endl << "Expected: " << expr1 << ".height" << std::endl << "Which is: " << p1.height << std::endl; if (p1.is_dense != p2.is_dense) return ::testing::AssertionFailure () << "Value of: " << expr2 << ".is_dense" << std::endl << " Actual: " << p2.is_dense << std::endl << "Expected: " << expr1 << ".is_dense" << std::endl << "Which is: " << p1.is_dense << std::endl; if (p1.sensor_origin_ != p2.sensor_origin_) return ::testing::AssertionFailure () << "Sensor origins are different"; if (p1.sensor_orientation_.coeffs () != p2.sensor_orientation_.coeffs ()) return ::testing::AssertionFailure () << "Sensor orientations are different"; return ::testing::AssertionSuccess (); } template ::testing::AssertionResult VectorContainsAll(const char* expr1, const char* expr2, const std::vector& elements, const std::vector& v) { for(const V& item : elements) { if(std::find(v.cbegin(), v.cend(), item)==v.cend()) { std::ostringstream vec_rep; std::copy(v.cbegin(), v.cend()-1, std::ostream_iterator(vec_rep, ", ")); vec_rep<(elements_rep, ", ")); elements_rep << elements.back(); return ::testing::AssertionFailure () << "Actual : " << expr2 << std::endl << "contains : " << vec_rep.str() << std::endl << "Target set : " << expr1 << std::endl << "contains : " << elements_rep.str() << std::endl; } } return ::testing::AssertionSuccess (); } template ::testing::AssertionResult VectorDoesNotContain(const char* expr1, const char* expr2, const std::vector& elements, const std::vector& v) { for(const V& item : elements) { if(std::find(v.cbegin(), v.cend(), item)!=v.cend()) { std::ostringstream vec_rep; std::copy(v.cbegin(), v.cend()-1, std::ostream_iterator(vec_rep, ", ")); vec_rep<(elements_rep, ", ")); elements_rep << elements.back(); return ::testing::AssertionFailure () << "Actual : " << expr2 << std::endl << "contains : " << vec_rep.str() << std::endl << "Forbidden set: " << expr1 << std::endl << "contains : " << elements_rep.str() << std::endl; } } return ::testing::AssertionSuccess (); } } } } /// Expect that each of x, y, and z fields are equal in /// two points. #define EXPECT_XYZ_EQ(expected, actual) \ EXPECT_PRED_FORMAT2(::pcl::test::internal::XYZEQ, \ (expected), (actual)) /// Assert that each of x, y, and z fields are equal in /// two points. #define ASSERT_XYZ_EQ(expected, actual) \ ASSERT_PRED_FORMAT2(::pcl::test::internal::XYZEQ, \ (expected), (actual)) /// Expect that differences between x, y, and z fields in /// two points are each within abs_error. #define EXPECT_XYZ_NEAR(expected, actual, abs_error) \ EXPECT_PRED_FORMAT3(::pcl::test::internal::XYZNear, \ (expected), (actual), abs_error) /// Assert that differences between x, y, and z fields in /// two points are each within abs_error. #define ASSERT_XYZ_NEAR(expected, actual, abs_error) \ ASSERT_PRED_FORMAT3(::pcl::test::internal::XYZNear, \ (expected), (actual), abs_error) /// Expect that each of normal_x, normal_y, and normal_z /// fields are equal in two points. #define EXPECT_NORMAL_EQ(expected, actual) \ EXPECT_PRED_FORMAT2(::pcl::test::internal::NormalEQ, \ (expected), (actual)) /// Assert that each of normal_x, normal_y, and normal_z /// fields are equal in two points. #define ASSERT_NORMAL_EQ(expected, actual) \ ASSERT_PRED_FORMAT2(::pcl::test::internal::NormalEQ, \ (expected), (actual)) /// Expect that differences between normal_x, normal_y, /// and normal_z fields in two points are each within /// abs_error. #define EXPECT_NORMAL_NEAR(expected, actual, abs_error) \ EXPECT_PRED_FORMAT3(::pcl::test::internal::NormalNear, \ (expected), (actual), abs_error) /// Assert that differences between normal_x, normal_y, /// and normal_z fields in two points are each within /// abs_error. #define ASSERT_NORMAL_NEAR(expected, actual, abs_error) \ ASSERT_PRED_FORMAT3(::pcl::test::internal::NormalNear, \ (expected), (actual), abs_error) /// Expect that each of r, g, and b fields are equal in /// two points. #define EXPECT_RGB_EQ(expected, actual) \ EXPECT_PRED_FORMAT2(::pcl::test::internal::RGBEQ, \ (expected), (actual)) /// Assert that each of r, g, and b fields are equal in /// two points. #define ASSERT_RGB_EQ(expected, actual) \ ASSERT_PRED_FORMAT2(::pcl::test::internal::RGBEQ, \ (expected), (actual)) /// Expect that each of r, g, b, and a fields are equal /// in two points. #define EXPECT_RGBA_EQ(expected, actual) \ EXPECT_PRED_FORMAT2(::pcl::test::internal::RGBAEQ, \ (expected), (actual)) /// Assert that each of r, g, b, and a fields are equal /// in two points. #define ASSERT_RGBA_EQ(expected, actual) \ ASSERT_PRED_FORMAT2(::pcl::test::internal::RGBAEQ, \ (expected), (actual)) /// Assert that the metadata (header, width, height, /// is_dense, sensor origin and orientation) are equal /// in two point clouds. #define ASSERT_METADATA_EQ(expected, actual) \ ASSERT_PRED_FORMAT2(::pcl::test::internal::MetaDataEQ, \ expected, actual) /// Expect that the metadata (header, width, height, /// is_dense, sensor origin and orientation) are equal /// in two point clouds. #define EXPECT_METADATA_EQ(expected, actual) \ EXPECT_PRED_FORMAT2(::pcl::test::internal::MetaDataEQ, \ expected, actual) /// Expect that the vector contains all elements /// from the expected vector. #define EXPECT_VECTOR_CONTAINS_ALL(expected, actual) \ EXPECT_PRED_FORMAT2(::pcl::test::internal::VectorContainsAll, \ expected, actual) /// Expect that the vector does not contain any element /// from the expected vector. #define EXPECT_VECTOR_DOES_NOT_CONTAIN(expected, actual) \ EXPECT_PRED_FORMAT2(::pcl::test::internal::VectorDoesNotContain, \ expected, actual) /// Assert that the vector contains all elements /// from the expected vector. #define ASSERT_VECTOR_CONTAINS_ALL(expected, actual) \ ASSERT_PRED_FORMAT2(::pcl::test::internal::VectorContainsAll, \ expected, actual) /// Assert that the vector does not contain any element /// from the expected vector. #define ASSERT_VECTOR_DOES_NOT_CONTAIN(expected, actual) \ ASSERT_PRED_FORMAT2(::pcl::test::internal::VectorDoesNotContain, \ expected, actual)