#include "RDValue.h" #include "RDProps.h" #include "Invariant.h" #include #include #include #include #include #include #include #include using namespace RDKit; template void testLimits() { // check numeric limits { RDValue v(std::numeric_limits::min()); std::cerr << "min: " << std::numeric_limits::min() << " " << rdvalue_cast(v) << std::endl; CHECK_INVARIANT(rdvalue_cast(v) == std::numeric_limits::min(), "bad min"); CHECK_INVARIANT(rdvalue_cast(RDValue(v)) == std::numeric_limits::min(), "bad min"); v = std::numeric_limits::max(); CHECK_INVARIANT(rdvalue_cast(v) == std::numeric_limits::max(), "bad max"); CHECK_INVARIANT(rdvalue_cast(RDValue(v)) == std::numeric_limits::max(), "bad max"); } { RDValue v(std::numeric_limits::max()); CHECK_INVARIANT(rdvalue_cast(v) == std::numeric_limits::max(), "bad max"); RDValue vv(v); CHECK_INVARIANT(rdvalue_cast(vv) == std::numeric_limits::max(), "bad max"); v = std::numeric_limits::min(); RDValue vvv(v); CHECK_INVARIANT(rdvalue_cast(v) == std::numeric_limits::min(), "bad min"); CHECK_INVARIANT(rdvalue_cast(vvv) == std::numeric_limits::min(), "bad min"); } } void testPOD() { testLimits(); testLimits(); testLimits(); testLimits(); testLimits(); } template void testVector() { T minv = std::numeric_limits::min(); T maxv = std::numeric_limits::max(); std::vector data; data.push_back(minv); data.push_back(maxv); data.push_back(T()); RDValue v(data); CHECK_INVARIANT(rdvalue_cast >(v) == data, "bad vec"); RDValue vv; copy_rdvalue(vv,v); CHECK_INVARIANT(rdvalue_cast >(vv) == data, "bad copy constructor"); RDValue::cleanup_rdvalue(v); // desctructor... RDValue::cleanup_rdvalue(vv); } void testPODVectors() { testVector(); testVector(); testVector(); testVector(); testVector(); // stored in anys } void testStringVect() { std::vector vecs; vecs.push_back("my"); vecs.push_back("dog"); vecs.push_back("has"); vecs.push_back("fleas"); RDValue v(vecs); CHECK_INVARIANT(rdvalue_cast >(v) == vecs, "bad vect"); RDValue vc; copy_rdvalue(vc, v); CHECK_INVARIANT(rdvalue_cast >(vc) == vecs, "bad vect"); RDValue vv = vecs; RDValue vvc; copy_rdvalue(vvc, vv); CHECK_INVARIANT(rdvalue_cast >(vv) == vecs, "bad vect"); CHECK_INVARIANT(rdvalue_cast >(vvc) == vecs, "bad vect"); RDValue::cleanup_rdvalue(v); // desctructor... RDValue::cleanup_rdvalue(vc); // desctructor... RDValue::cleanup_rdvalue(vv); // desctructor... RDValue::cleanup_rdvalue(vvc); // desctructor... } void testMapsAndLists() { { typedef std::map listtype; listtype m; m["foo"] = 1; m["bar"] = 2; RDValue v(m); CHECK_INVARIANT(rdvalue_cast(v) == m, "bad map cast"); RDValue::cleanup_rdvalue(v); } { std::list m; m.push_back("foo"); m.push_back("bar"); RDValue v(m); CHECK_INVARIANT(rdvalue_cast >(v) == m, "bad map cast"); RDValue::cleanup_rdvalue(v); } } void testNaN() { // make a NaN double nan=sqrt(-1.0); RDValue v(nan); TEST_ASSERT(v.getTag() == RDTypeTag::DoubleTag); CHECK_INVARIANT(boost::math::isnan(rdvalue_cast(v)), "Oops, can't store NaNs!"); RDValue vv(2.0); TEST_ASSERT(rdvalue_is(vv)); TEST_ASSERT(vv.getTag() == RDTypeTag::DoubleTag); } template std::vector makeVec() { std::vector vec; vec.push_back((T)0); vec.push_back((T)1); vec.push_back((T)2); vec.push_back((T)3); vec.push_back((T)4); vec.push_back((T)5); return vec; } int main() { std::cerr << "-- running tests -- " << std::endl; testPOD(); testPODVectors(); testStringVect(); testNaN(); }