Files
rdkit/Code/RDGeneral/testRDValue.cpp
Brian Kelley ada0ef5e75 Fix to serialize binary strings (#2264)
* Fix to serialize binary strings

* Use stringstream instead of files for pickle tests
2019-02-13 18:10:47 +01:00

248 lines
6.6 KiB
C++

#include <RDGeneral/test.h>
#include "RDValue.h"
#include "RDProps.h"
#include "Invariant.h"
#include "StreamOps.h"
#include <limits>
#include <vector>
#include <list>
#include <map>
#include <string>
#include <iostream>
#include <fstream>
#include <boost/math/special_functions/fpclassify.hpp>
using namespace RDKit;
template<class T>
void testLimits() {
BOOST_LOG(rdErrorLog) << "Test limits" << std::endl;
// check numeric limits
{
RDValue v(std::numeric_limits<T>::min());
std::cerr << "min: " << std::numeric_limits<T>::min() << " " << rdvalue_cast<T>(v) <<
std::endl;
CHECK_INVARIANT(rdvalue_cast<T>(v) == std::numeric_limits<T>::min(), "bad min");
CHECK_INVARIANT(rdvalue_cast<T>(RDValue(v)) == std::numeric_limits<T>::min(), "bad min");
v = std::numeric_limits<T>::max();
CHECK_INVARIANT(rdvalue_cast<T>(v) == std::numeric_limits<T>::max(), "bad max");
CHECK_INVARIANT(rdvalue_cast<T>(RDValue(v)) == std::numeric_limits<T>::max(), "bad max");
}
{
RDValue v(std::numeric_limits<T>::max());
CHECK_INVARIANT(rdvalue_cast<T>(v) == std::numeric_limits<T>::max(), "bad max");
RDValue vv(v);
CHECK_INVARIANT(rdvalue_cast<T>(vv) == std::numeric_limits<T>::max(), "bad max");
v = std::numeric_limits<T>::min();
RDValue vvv(v);
CHECK_INVARIANT(rdvalue_cast<T>(v) == std::numeric_limits<T>::min(), "bad min");
CHECK_INVARIANT(rdvalue_cast<T>(vvv) == std::numeric_limits<T>::min(), "bad min");
}
BOOST_LOG(rdErrorLog) << "..done" << std::endl;
}
void testPOD() {
BOOST_LOG(rdErrorLog) << "Test POD" << std::endl;
testLimits<int>();
testLimits<unsigned int>();
testLimits<double>();
testLimits<float>();
testLimits<bool>();
BOOST_LOG(rdErrorLog) << "..done" << std::endl;
}
template<class T>
void testVector() {
T minv = std::numeric_limits<T>::min();
T maxv = std::numeric_limits<T>::max();
std::vector<T> data;
data.push_back(minv);
data.push_back(maxv);
data.push_back(T());
RDValue v(data);
CHECK_INVARIANT(rdvalue_cast<std::vector<T> >(v) == data, "bad vec");
RDValue vv; copy_rdvalue(vv,v);
CHECK_INVARIANT(rdvalue_cast<std::vector<T> >(vv) == data, "bad copy constructor");
RDValue::cleanup_rdvalue(v); // desctructor...
RDValue::cleanup_rdvalue(vv);
}
void testPODVectors() {
BOOST_LOG(rdErrorLog) << "Test String Vect" << std::endl;
testVector<int>();
testVector<unsigned int>();
testVector<double>();
testVector<float>();
testVector<long double>(); // stored in anys
BOOST_LOG(rdErrorLog) << "..done" << std::endl;
}
void testStringVect() {
BOOST_LOG(rdErrorLog) << "Test String Vect" << std::endl;
std::vector<std::string> vecs;
vecs.push_back("my");
vecs.push_back("dog");
vecs.push_back("has");
vecs.push_back("fleas");
RDValue v(vecs);
CHECK_INVARIANT(rdvalue_cast<std::vector<std::string> >(v) == vecs, "bad vect");
RDValue vc; copy_rdvalue(vc, v);
CHECK_INVARIANT(rdvalue_cast<std::vector<std::string> >(vc) == vecs, "bad vect");
RDValue vv = vecs;
RDValue vvc; copy_rdvalue(vvc, vv);
CHECK_INVARIANT(rdvalue_cast<std::vector<std::string> >(vv) == vecs, "bad vect");
CHECK_INVARIANT(rdvalue_cast<std::vector<std::string> >(vvc) == vecs, "bad vect");
RDValue::cleanup_rdvalue(v); // desctructor...
RDValue::cleanup_rdvalue(vc); // desctructor...
RDValue::cleanup_rdvalue(vv); // desctructor...
RDValue::cleanup_rdvalue(vvc); // desctructor...
BOOST_LOG(rdErrorLog) << "..done" << std::endl;
}
void testMapsAndLists() {
BOOST_LOG(rdErrorLog) << "Test Maps And Lists" << std::endl;
{
typedef std::map<std::string, int> listtype;
listtype m;
m["foo"] = 1;
m["bar"] = 2;
RDValue v(m);
CHECK_INVARIANT(rdvalue_cast<listtype>(v) == m, "bad map cast");
RDValue::cleanup_rdvalue(v);
}
{
std::list<std::string> m;
m.push_back("foo");
m.push_back("bar");
RDValue v(m);
CHECK_INVARIANT(rdvalue_cast<std::list<std::string> >(v) == m, "bad map cast");
RDValue::cleanup_rdvalue(v);
}
BOOST_LOG(rdErrorLog) << "..done" << std::endl;
}
void testNaN() {
// make a NaN
BOOST_LOG(rdErrorLog) << "Test NaN" << std::endl;
double nan=sqrt(-1.0);
RDValue v(nan);
TEST_ASSERT(v.getTag() == RDTypeTag::DoubleTag);
CHECK_INVARIANT(boost::math::isnan(rdvalue_cast<double>(v)), "Oops, can't store NaNs!");
RDValue vv(2.0);
TEST_ASSERT(rdvalue_is<double>(vv));
TEST_ASSERT(vv.getTag() == RDTypeTag::DoubleTag);
BOOST_LOG(rdErrorLog) << "..done" << std::endl;
}
template<class T>
std::vector<T> makeVec() {
std::vector<T> 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;
}
template<class T>
void testProp(T val) {
std::stringstream ss;
{
RDProps p;
p.setProp<T>("foo", val);
TEST_ASSERT(streamWriteProps(ss, p));
}
{
RDProps p2;
streamReadProps(ss, p2);
TEST_ASSERT(p2.getProp<T>("foo") == val);
}
};
void testPropertyPickler() {
BOOST_LOG(rdErrorLog) << "Test Property Pickler" << std::endl;
std::cerr << "== int" << std::endl;
testProp<int>(1234);
std::cerr << "== double" << std::endl;
testProp<double>(1234.);
std::cerr << "== float" << std::endl;
testProp<float>(1234.0f);
std::cerr << "== unsigned int" << std::endl;
testProp<unsigned int>(1234u);
std::cerr << "== bool" << std::endl;
testProp<bool>(true);
std::cerr << "== std::string" << std::endl;
testProp<std::string>(std::string("the quick brown fox jumps over the lazy dog"));
testProp(0);
testProp(0.);
testProp(0.0f);
testProp(0u);
testProp(false);
/*
testProp(makeVec<int>());
testProp(makeVec<int>());
testProp(makeVec<int>());
testProp(makeVec<unsigned int>());
{
std::vector<std::string> v;
v.push_back("a");
v.push_back("b");
v.push_back("c");
v.push_back("d");
v.push_back("e");
testProp(v);
}
*/
BOOST_LOG(rdErrorLog) << "..done" << std::endl;
}
void testPickleBinaryString() {
BOOST_LOG(rdErrorLog) << "Pickle Binary String" << std::endl;
char buf[10];
for(int i=0;i<10;++i) {
buf[i] = (char)i;
}
std::string str(buf, 10);
std::stringstream ss;
{
RDProps p;
p.setProp<std::string>("foo", str);
TEST_ASSERT(streamWriteProps(ss, p));
}
{
RDProps p2;
streamReadProps(ss, p2);
TEST_ASSERT(p2.getProp<std::string>("foo") == str);
}
BOOST_LOG(rdErrorLog) << "..done" << std::endl;
}
int main() {
std::cerr << "-- running tests -- " << std::endl;
testPOD();
testPODVectors();
testStringVect();
testNaN();
testPropertyPickler();
testPickleBinaryString();
}