Newer
Older
#ifndef PROPERTYMANAGERTEST_H_
#define PROPERTYMANAGERTEST_H_
#include <cxxtest/TestSuite.h>
#include "MantidKernel/PropertyManager.h"
#include "MantidKernel/BoundedValidator.h"
#include "MantidKernel/MandatoryValidator.h"
Gigg, Martyn Anthony
committed
#include "MantidKernel/TimeSeriesProperty.h"
#include "MantidKernel/FilteredTimeSeriesProperty.h"
#include <boost/scoped_ptr.hpp>
using namespace Mantid::Kernel;
namespace {
/// Create the test source property
Mantid::Kernel::TimeSeriesProperty<double> *
createTestSeries(const std::string &name) {
auto source = new Mantid::Kernel::TimeSeriesProperty<double>(name);
source->addValue("2007-11-30T16:17:00", 1);
source->addValue("2007-11-30T16:17:10", 2);
source->addValue("2007-11-30T16:17:20", 3);
source->addValue("2007-11-30T16:17:30", 4);
source->addValue("2007-11-30T16:17:40", 5);
return source;
}
Gigg, Martyn Anthony
committed
/// Create test filter
Mantid::Kernel::TimeSeriesProperty<bool> *createTestFilter() {
auto filter = new Mantid::Kernel::TimeSeriesProperty<bool>("filter");
filter->addValue("2007-11-30T16:16:50", false);
filter->addValue("2007-11-30T16:17:25", true);
filter->addValue("2007-11-30T16:17:39", false);
return filter;
}
Gigg, Martyn Anthony
committed
}
class PropertyManagerHelper : public PropertyManager {
public:
PropertyManagerHelper() : PropertyManager() {}
Russell Taylor
committed
using PropertyManager::declareProperty;
using PropertyManager::setProperty;
Steve Williams
committed
using PropertyManager::getPointerToProperty;
class PropertyManagerTest : public CxxTest::TestSuite {
Russell Taylor
committed
manager = new PropertyManagerHelper;
Property *p = new PropertyWithValue<int>("aProp", 1);
Russell Taylor
committed
manager->declareProperty(p);
manager->declareProperty("anotherProp", 1.11);
manager->declareProperty("yetAnotherProp", "itsValue");
Russell Taylor
committed
}
void tearDown() { delete manager; }
Russell Taylor
committed
Gigg, Martyn Anthony
committed
PropertyManagerHelper mgr;
std::vector<Property *> props = mgr.getProperties();
TS_ASSERT(props.empty());
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
void testFilterByLogConvertsTimeSeriesToFilteredTimeSeries() {
Gigg, Martyn Anthony
committed
PropertyManagerHelper manager;
manager.declareProperty(createTestSeries("log1"));
manager.declareProperty(createTestSeries("log2"));
manager.declareProperty(createTestSeries("log3"));
Gigg, Martyn Anthony
committed
auto filter = createTestFilter();
manager.filterByProperty(*filter);
Gigg, Martyn Anthony
committed
TS_ASSERT_EQUALS(manager.propertyCount(), 3);
const std::vector<Property *> &props = manager.getProperties();
for (auto iter = props.begin(); iter != props.end(); ++iter) {
Gigg, Martyn Anthony
committed
Property *prop = *iter;
std::string msg = "Property " + prop->name() +
" has not been changed to a FilteredTimeSeries";
auto filteredProp =
dynamic_cast<FilteredTimeSeriesProperty<double> *>(*iter);
Gigg, Martyn Anthony
committed
TSM_ASSERT(msg, filteredProp);
}
// Also check the single getter
Property *log2 = manager.getProperty("log2");
auto filteredProp =
dynamic_cast<FilteredTimeSeriesProperty<double> *>(log2);
TSM_ASSERT("getProperty has not returned a FilteredProperty as expected",
filteredProp);
Gigg, Martyn Anthony
committed
delete filter;
}
PropertyManagerHelper mgr1;
mgr1.declareProperty("aProp", 10);
PropertyManagerHelper mgr2 = mgr1;
const std::vector<Property *> &props1 = mgr1.getProperties();
const std::vector<Property *> &props2 = mgr2.getProperties();
TS_ASSERT_EQUALS(props1.size(), props2.size());
TS_ASSERT_DIFFERS(&props1[0], &props2[0]);
TS_ASSERT_EQUALS(props1[0]->name(), props2[0]->name());
TS_ASSERT_EQUALS(props1[0]->value(), props2[0]->value());
}
PropertyManagerHelper mgr1;
mgr1.declareProperty("aProp", 10);
PropertyManagerHelper mgr2;
mgr2 = mgr1;
const std::vector<Property *> &props1 = mgr1.getProperties();
const std::vector<Property *> &props2 = mgr2.getProperties();
TS_ASSERT_EQUALS(props1.size(), props2.size());
TS_ASSERT_DIFFERS(&props1[0], &props2[0]);
TS_ASSERT_EQUALS(props1[0]->name(), props2[0]->name());
TS_ASSERT_EQUALS(props1[0]->value(), props2[0]->value());
}
void testdeclareProperty_pointer() {
Gigg, Martyn Anthony
committed
PropertyManagerHelper mgr;
Property *p = new PropertyWithValue<double>("myProp", 9.99);
TS_ASSERT_THROWS_NOTHING(mgr.declareProperty(p));
TS_ASSERT(mgr.existsProperty(p->name()));
Gigg, Martyn Anthony
committed
// Confirm that the first 4 characters of the string are the same
// Note that some versions of boost::lexical_cast > 1.34 give a string such
// as
// 9.9900000000000002 rather than 9.99. Converting back to a double however
// does
Gigg, Martyn Anthony
committed
// still give the correct 9.99.
TS_ASSERT_EQUALS(mgr.getPropertyValue("myProp").substr(0, 4),
std::string("9.99"));
TS_ASSERT_THROWS(mgr.declareProperty(p), Exception::ExistsError);
TS_ASSERT_THROWS(mgr.declareProperty(new PropertyWithValue<int>("", 0)),
std::invalid_argument);
mgr.declareProperty(new PropertyWithValue<int>("GoodIntProp", 1),
"Test doc");
TS_ASSERT_EQUALS(mgr.getPointerToProperty("GoodIntProp")->documentation(),
"Test doc");
Gigg, Martyn Anthony
committed
}
Russell Taylor
committed
void testdeclareProperty_int() {
Gigg, Martyn Anthony
committed
PropertyManagerHelper mgr;
TS_ASSERT_THROWS_NOTHING(mgr.declareProperty("myProp", 1));
TS_ASSERT(!mgr.getPropertyValue("myProp").compare("1"));
TS_ASSERT_THROWS(mgr.declareProperty("MYPROP", 5), Exception::ExistsError);
TS_ASSERT_THROWS(mgr.declareProperty("", 5), std::invalid_argument);
Gigg, Martyn Anthony
committed
}
void testdeclareProperty_double() {
PropertyManagerHelper mgr;
boost::shared_ptr<BoundedValidator<double>> v =
boost::make_shared<BoundedValidator<double>>(1, 5);
TS_ASSERT_THROWS_NOTHING(mgr.declareProperty("myProp", 9.99, v));
// Note that some versions of boost::lexical_cast > 1.34 give a string such
// as
// 9.9900000000000002 rather than 9.99. Converting back to a double however
// does
Gigg, Martyn Anthony
committed
// still give the correct 9.99.
TS_ASSERT_EQUALS(mgr.getPropertyValue("myProp").substr(0, 4),
std::string("9.99"));
TS_ASSERT_THROWS_NOTHING(
mgr.declareProperty("withDoc", 4.4, v->clone(), "Test doc doub"));
TS_ASSERT_EQUALS(mgr.getPointerToProperty("withDoc")->documentation(),
"Test doc doub");
TS_ASSERT_THROWS(mgr.declareProperty("MYPROP", 5.5),
Exception::ExistsError);
TS_ASSERT_THROWS(mgr.declareProperty("", 5.5), std::invalid_argument);
Gigg, Martyn Anthony
committed
}
void testdeclareProperty_string() {
PropertyManagerHelper mgr;
TS_ASSERT_THROWS_NOTHING(mgr.declareProperty(
"myProp", "theValue",
boost::make_shared<MandatoryValidator<std::string>>(), "hello"));
TS_ASSERT_EQUALS(mgr.getPropertyValue("myProp"), "theValue");
Gigg, Martyn Anthony
committed
Property *p = NULL;
TS_ASSERT_THROWS_NOTHING(p = mgr.getProperty("myProp"));
TS_ASSERT_EQUALS(p->documentation(), "hello");
Russell Taylor
committed
TS_ASSERT_THROWS(mgr.declareProperty("MYPROP", "aValue"),
Exception::ExistsError);
TS_ASSERT_THROWS(mgr.declareProperty("", "aValue"), std::invalid_argument);
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
PropertyManagerHelper mgr;
mgr.declareProperty("APROP", 1);
mgr.declareProperty("anotherProp", 1.0);
TS_ASSERT_THROWS_NOTHING(mgr.setProperties("APROP=15;anotherProp=1.3"));
TS_ASSERT(!mgr.getPropertyValue("APROP").compare("15"));
TS_ASSERT(!mgr.getPropertyValue("anotherProp").compare("1.3"));
Gigg, Martyn Anthony
committed
}
void testSetProperties_complicatedValueString() {
PropertyManagerHelper mgr;
mgr.declareProperty("APROP", "1");
mgr.declareProperty("anotherProp", "1");
TS_ASSERT_THROWS_NOTHING(
mgr.setProperties("APROP=equation=12+3;anotherProp=1.3,2.5"));
TS_ASSERT_EQUALS(mgr.getPropertyValue("APROP"), "equation=12+3");
TS_ASSERT_EQUALS(mgr.getPropertyValue("anotherProp"), "1.3,2.5");
void testSetPropertyValue() {
manager->setPropertyValue("APROP", "10");
TS_ASSERT(!manager->getPropertyValue("aProp").compare("10"));
manager->setPropertyValue("aProp", "1");
TS_ASSERT_THROWS(manager->setPropertyValue("fhfjsdf", "0"),
Exception::NotFoundError);
Gigg, Martyn Anthony
committed
}
void testSetProperty() {
TS_ASSERT_THROWS_NOTHING(manager->setProperty("AProp", 5));
TS_ASSERT_THROWS(manager->setProperty("wefhui", 5),
Exception::NotFoundError);
TS_ASSERT_THROWS(manager->setProperty("APROP", 5.55),
std::invalid_argument);
TS_ASSERT_THROWS(manager->setProperty("APROP", "value"),
std::invalid_argument);
TS_ASSERT_THROWS_NOTHING(manager->setProperty("AProp", 1));
Gigg, Martyn Anthony
committed
}
Russell Taylor
committed
// Make sure we can handle std::strings as well as const char *.
TS_ASSERT_THROWS_NOTHING(manager->setProperty("yetAnotherProp", "aValue"));
TS_ASSERT_THROWS_NOTHING(manager->setProperty("yetAnotherProp", aValue));
void testExistsProperty() {
Property *p = new PropertyWithValue<int>("sjfudh", 0);
TS_ASSERT(!manager->existsProperty(p->name()));
Property *pp = new PropertyWithValue<double>("APROP", 9.99);
// Note that although the name of the property is the same, the type is
// different - yet it passes
TS_ASSERT(manager->existsProperty(pp->name()));
Janik Zikovsky
committed
delete p;
Gigg, Martyn Anthony
committed
delete pp;
}
void testValidateProperties() {
TS_ASSERT(manager->validateProperties());
Janik Zikovsky
committed
PropertyManagerHelper mgr;
mgr.declareProperty("someProp", "",
boost::make_shared<MandatoryValidator<std::string>>());
TS_ASSERT(!mgr.validateProperties());
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
PropertyManagerHelper mgr;
TS_ASSERT_EQUALS(mgr.propertyCount(), 0);
const std::string name("TestProperty");
mgr.declareProperty(name, 10.0);
TS_ASSERT_EQUALS(mgr.propertyCount(), 1);
mgr.removeProperty(name);
TS_ASSERT_EQUALS(mgr.propertyCount(), 0);
}
void testGetPropertyValue() {
TS_ASSERT(!manager->getPropertyValue("APROP").compare("1"));
TS_ASSERT_THROWS(manager->getPropertyValue("sdfshdu"),
Exception::NotFoundError);
Gigg, Martyn Anthony
committed
}
Russell Taylor
committed
Property *p = manager->getProperty("APROP");
TS_ASSERT(p);
TS_ASSERT(!p->name().compare("aProp"));
TS_ASSERT(!p->value().compare("1"));
TS_ASSERT(!p->documentation().compare(""));
TS_ASSERT(typeid(int) == *p->type_info());
Gigg, Martyn Anthony
committed
TS_ASSERT_THROWS(p = manager->getProperty("werhui"),
Exception::NotFoundError);
Gigg, Martyn Anthony
committed
Gigg, Martyn Anthony
committed
int i(0);
TS_ASSERT_THROWS_NOTHING(i = manager->getProperty("aprop"));
TS_ASSERT_EQUALS(i, 1);
Gigg, Martyn Anthony
committed
double dd(0.0);
TS_ASSERT_THROWS(dd = manager->getProperty("aprop"), std::runtime_error);
TS_ASSERT_EQUALS(dd, 0.0); // If dd is bot used you get a compiler warning
Russell Taylor
committed
std::string s = manager->getProperty("aprop");
Gigg, Martyn Anthony
committed
double d(0.0);
TS_ASSERT_THROWS_NOTHING(d = manager->getProperty("anotherProp"));
TS_ASSERT_EQUALS(d, 1.11);
TS_ASSERT_THROWS(ii = manager->getProperty("anotherprop"),
std::runtime_error);
TS_ASSERT_EQUALS(ii, 0); // Compiler warning if ii is not used
Russell Taylor
committed
std::string ss = manager->getProperty("anotherprop");
// Note that some versions of boost::lexical_cast > 1.34 give a string such
// as
// 9.9900000000000002 rather than 9.99. Converting back to a double however
// does
Gigg, Martyn Anthony
committed
// still give the correct 9.99.
TS_ASSERT_EQUALS(ss.substr(0, 4), std::string("1.11"));
Russell Taylor
committed
// This works, but CANNOT at present declare the string on a separate line
// and then assign
// (as I did for the int & double above)
Russell Taylor
committed
std::string sss = manager->getProperty("yetanotherprop");
TS_ASSERT(!sss.compare("itsValue"));
Gigg, Martyn Anthony
committed
}
void testGetProperties() {
std::vector<Property *> props = manager->getProperties();
TS_ASSERT(props.size() == 3);
Gigg, Martyn Anthony
committed
Property *p = props[0];
TS_ASSERT(!p->name().compare("aProp"));
TS_ASSERT(!p->value().compare("1"));
Gigg, Martyn Anthony
committed
}
PropertyManagerHelper mgr;
TS_ASSERT_THROWS_NOTHING(
mgr.declareProperty("llprop", static_cast<int64_t>(0)));
TS_ASSERT_THROWS_NOTHING(
mgr.setProperty("llprop", static_cast<int64_t>(52147900000)));
TS_ASSERT_EQUALS(mgr.getPropertyValue("llprop"), "52147900000");
TS_ASSERT_THROWS_NOTHING(
mgr.setPropertyValue("llprop", "1234567890123456789"));
Gigg, Martyn Anthony
committed
int64_t retrieved(0);
TS_ASSERT_THROWS_NOTHING(retrieved = mgr.getProperty("llprop"));
TS_ASSERT_EQUALS(retrieved, static_cast<int64_t>(1234567890123456789));
}
Gigg, Martyn Anthony
committed
PropertyManagerHelper mgr;
const std::string name("TestProperty");
TS_ASSERT_THROWS_NOTHING(mgr.declareProperty(name, 10.0));
TS_ASSERT_THROWS_NOTHING(mgr.removeProperty(name));
TS_ASSERT_EQUALS(mgr.getProperties().size(), 0);
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
PropertyManagerHelper mgr;
const std::string name("TestProperty");
TS_ASSERT_THROWS_NOTHING(mgr.declareProperty(name + "1", 10.0));
TS_ASSERT_THROWS_NOTHING(mgr.declareProperty(name + "2", 15.0));
TS_ASSERT_THROWS_NOTHING(mgr.declareProperty(name + "3", 14.0));
TS_ASSERT_EQUALS(mgr.propertyCount(), 3);
TS_ASSERT_THROWS_NOTHING(mgr.clear());
TS_ASSERT_EQUALS(mgr.propertyCount(), 0);
Gigg, Martyn Anthony
committed
PropertyManagerHelper mgr;
TS_ASSERT_THROWS_NOTHING(mgr.declareProperty("Prop1", 10));
TS_ASSERT_THROWS_NOTHING(mgr.declareProperty("Prop2", 15));
TSM_ASSERT_EQUALS("Empty string when all are default", mgr.asString(), "");
TSM_ASSERT_EQUALS("Show the default", mgr.asString(true),
"Prop1=10,Prop2=15");
TSM_ASSERT_EQUALS("Different separator", mgr.asString(true, ';'),
"Prop1=10;Prop2=15");
mgr.setProperty("Prop1", 123);
mgr.setProperty("Prop2", 456);
TSM_ASSERT_EQUALS("Change the values", mgr.asString(false, ';'),
"Prop1=123;Prop2=456");
Gigg, Martyn Anthony
committed
}
Janik Zikovsky
committed
//-----------------------------------------------------------------------------------------------------------
/** Test of adding managers together (this will be used when
* concatenating runs together).
*/
Janik Zikovsky
committed
PropertyManager mgr1;
Property *p;
p = new PropertyWithValue<double>("double", 12.0);
mgr1.declareProperty(p, "docs");
p = new PropertyWithValue<int>("int", 23);
mgr1.declareProperty(p, "docs");
p = new PropertyWithValue<double>("double_only_in_mgr1", 456.0);
mgr1.declareProperty(p, "docs");
Janik Zikovsky
committed
PropertyManager mgr2;
p = new PropertyWithValue<double>("double", 23.6);
mgr2.declareProperty(p, "docs");
p = new PropertyWithValue<int>("int", 34);
mgr2.declareProperty(p, "docs");
p = new PropertyWithValue<double>("new_double_in_mgr2", 321.0);
mgr2.declareProperty(p, "docs");
p = new PropertyWithValue<int>("new_int", 655);
mgr2.declareProperty(p, "docs");
// Add em together
Janik Zikovsky
committed
mgr1 += mgr2;
double d;
d = mgr1.getProperty("double");
Janik Zikovsky
committed
d = mgr1.getProperty("double_only_in_mgr1");
TS_ASSERT_DELTA(d, 456.0, 1e-4);
Janik Zikovsky
committed
d = mgr1.getProperty("new_double_in_mgr2");
TS_ASSERT_DELTA(d, 321.0, 1e-4);
Janik Zikovsky
committed
int i;
i = mgr1.getProperty("int");
Janik Zikovsky
committed
i = mgr1.getProperty("new_int");
Janik Zikovsky
committed
}
Gigg, Martyn Anthony
committed
//-------------------------------------------------------------------------------------------------
// Performance Test
//-------------------------------------------------------------------------------------------------
class PropertyManagerTestPerformance : public CxxTest::TestSuite {
Gigg, Martyn Anthony
committed
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static PropertyManagerTestPerformance *createSuite() {
return new PropertyManagerTestPerformance();
}
static void destroySuite(PropertyManagerTestPerformance *suite) {
delete suite;
}
Gigg, Martyn Anthony
committed
PropertyManagerTestPerformance() : m_manager(), m_filter(createTestFilter()) {
Gigg, Martyn Anthony
committed
const size_t nprops = 2000;
for (size_t i = 0; i < nprops; ++i) {
m_manager.declareProperty(
createTestSeries("prop" + boost::lexical_cast<std::string>(i)));
Gigg, Martyn Anthony
committed
}
}
void test_Perf_Of_Filtering_Large_Number_Of_Properties_By_Other_Property() {
Gigg, Martyn Anthony
committed
m_manager.filterByProperty(*m_filter);
}
private:
/// Test manager
PropertyManagerHelper m_manager;
/// Test filter
boost::scoped_ptr<TimeSeriesProperty<bool>> m_filter;
};