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;
Gigg, Martyn Anthony
committed
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;
}
/// 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;
}
}
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
{
public:
Russell Taylor
committed
void setUp()
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");
}
void tearDown()
{
delete manager;
Russell Taylor
committed
Gigg, Martyn Anthony
committed
void testConstructor()
{
PropertyManagerHelper mgr;
std::vector<Property*> props = mgr.getProperties();
TS_ASSERT( props.empty() );
}
Gigg, Martyn Anthony
committed
void testFilterByLogConvertsTimeSeriesToFilteredTimeSeries()
{
PropertyManagerHelper manager;
manager.declareProperty(createTestSeries("log1"));
manager.declareProperty(createTestSeries("log2"));
manager.declareProperty(createTestSeries("log3"));
auto filter = createTestFilter();
manager.filterByProperty(*filter);
TS_ASSERT_EQUALS(manager.propertyCount(), 3);
const std::vector<Property*> & props = manager.getProperties();
for(auto iter = props.begin(); iter != props.end(); ++iter)
{
Property *prop = *iter;
std::string msg = "Property " + prop->name() + " has not been changed to a FilteredTimeSeries";
auto filteredProp = dynamic_cast<FilteredTimeSeriesProperty<double>*>(*iter);
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);
delete filter;
}
void testCopyConstructor()
{
PropertyManagerHelper mgr1;
mgr1.declareProperty("aProp",10);
PropertyManagerHelper mgr2 = mgr1;
const std::vector<Property*>& props1 = mgr1.getProperties();
const std::vector<Property*>& props2 = mgr2.getProperties();
Janik Zikovsky
committed
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 testCopyAssignment()
{
PropertyManagerHelper mgr1;
mgr1.declareProperty("aProp",10);
PropertyManagerHelper mgr2;
mgr2 = mgr1;
const std::vector<Property*>& props1 = mgr1.getProperties();
const std::vector<Property*>& props2 = mgr2.getProperties();
Janik Zikovsky
committed
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() );
}
Gigg, Martyn Anthony
committed
void testdeclareProperty_pointer()
{
PropertyManagerHelper mgr;
Property *p = new PropertyWithValue<double>("myProp", 9.99);
TS_ASSERT_THROWS_NOTHING( mgr.declareProperty(p) );
TS_ASSERT( mgr.existsProperty(p->name()) );
// 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
// 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" );
}
Russell Taylor
committed
Gigg, Martyn Anthony
committed
void testdeclareProperty_int()
{
PropertyManagerHelper mgr;
Janik Zikovsky
committed
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
}
Gigg, Martyn Anthony
committed
void testdeclareProperty_double()
{
PropertyManagerHelper mgr;
boost::shared_ptr<BoundedValidator<double> > v = boost::make_shared<BoundedValidator<double> >(1,5);
Janik Zikovsky
committed
TS_ASSERT_THROWS_NOTHING( mgr.declareProperty("myProp", 9.99, v) );
Gigg, Martyn Anthony
committed
// 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
// still give the correct 9.99.
Janik Zikovsky
committed
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
}
Gigg, Martyn Anthony
committed
void testdeclareProperty_string()
{
PropertyManagerHelper mgr;
TS_ASSERT_THROWS_NOTHING( mgr.declareProperty("myProp", "theValue", boost::make_shared<MandatoryValidator<std::string> >(), "hello") );
Janik Zikovsky
committed
TS_ASSERT_EQUALS( mgr.getPropertyValue("myProp"), "theValue" );
Gigg, Martyn Anthony
committed
Property *p = NULL;
Janik Zikovsky
committed
TS_ASSERT_THROWS_NOTHING( p = mgr.getProperty("myProp") );
Steve Williams
committed
TS_ASSERT_EQUALS(p->documentation(),"hello");
Russell Taylor
committed
Janik Zikovsky
committed
TS_ASSERT_THROWS( mgr.declareProperty("MYPROP", "aValue"), Exception::ExistsError );
TS_ASSERT_THROWS( mgr.declareProperty("", "aValue"), std::invalid_argument );
Gigg, Martyn Anthony
committed
}
void testSetProperties()
{
PropertyManagerHelper mgr;
mgr.declareProperty("APROP", 1);
mgr.declareProperty("anotherProp", 1.0);
Janik Zikovsky
committed
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" );
}
Gigg, Martyn Anthony
committed
void testSetPropertyValue()
{
Russell Taylor
committed
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()
{
Russell Taylor
committed
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
void testSetStringProperty()
{
// Make sure we can handle std::strings as well as const char *.
TS_ASSERT_THROWS_NOTHING( manager->setProperty("yetAnotherProp","aValue") );
std::string aValue("aValue");
TS_ASSERT_THROWS_NOTHING( manager->setProperty("yetAnotherProp",aValue) );
}
Gigg, Martyn Anthony
committed
void testExistsProperty()
{
Property *p = new PropertyWithValue<int>("sjfudh",0);
Russell Taylor
committed
TS_ASSERT( ! manager->existsProperty(p->name()) );
Janik Zikovsky
committed
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
Russell Taylor
committed
TS_ASSERT( manager->existsProperty(pp->name()) );
Janik Zikovsky
committed
delete p;
Gigg, Martyn Anthony
committed
delete pp;
}
void testValidateProperties()
{
Russell Taylor
committed
TS_ASSERT( manager->validateProperties() );
Janik Zikovsky
committed
PropertyManagerHelper mgr;
mgr.declareProperty("someProp","", boost::make_shared<MandatoryValidator<std::string> >());
Janik Zikovsky
committed
TS_ASSERT( ! mgr.validateProperties() );
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
void testPropertyCount()
{
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);
}
Gigg, Martyn Anthony
committed
void testGetPropertyValue()
{
Russell Taylor
committed
TS_ASSERT( ! manager->getPropertyValue("APROP").compare("1") );
TS_ASSERT_THROWS( manager->getPropertyValue("sdfshdu"), Exception::NotFoundError );
Gigg, Martyn Anthony
committed
}
void testGetProperty()
{
Russell Taylor
committed
Property *p = manager->getProperty("APROP");
Janik Zikovsky
committed
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
Russell Taylor
committed
TS_ASSERT_THROWS( p = manager->getProperty("werhui"), Exception::NotFoundError );
Gigg, Martyn Anthony
committed
Gigg, Martyn Anthony
committed
int i(0);
Russell Taylor
committed
TS_ASSERT_THROWS_NOTHING( i = manager->getProperty("aprop") );
Gigg, Martyn Anthony
committed
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");
Janik Zikovsky
committed
TS_ASSERT( ! s.compare("1") );
Gigg, Martyn Anthony
committed
double d(0.0);
Russell Taylor
committed
TS_ASSERT_THROWS_NOTHING( d = manager->getProperty("anotherProp") );
TS_ASSERT_EQUALS( d, 1.11 );
Russell Taylor
committed
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");
Gigg, Martyn Anthony
committed
// 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
// still give the correct 9.99.
Janik Zikovsky
committed
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");
Janik Zikovsky
committed
TS_ASSERT( ! sss.compare("itsValue") );
Gigg, Martyn Anthony
committed
}
Gigg, Martyn Anthony
committed
void testGetProperties()
{
Russell Taylor
committed
std::vector<Property*> props = manager->getProperties();
Janik Zikovsky
committed
TS_ASSERT( props.size() == 3 );
Gigg, Martyn Anthony
committed
Property *p = props[0];
Janik Zikovsky
committed
TS_ASSERT( ! p->name().compare("aProp") );
TS_ASSERT( ! p->value().compare("1") );
Gigg, Martyn Anthony
committed
}
void testLongLongProperty()
{
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
void testRemoveProperty()
{
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
void testClear()
{
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
void test_asString()
{
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
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
//-----------------------------------------------------------------------------------------------------------
/** Test of adding managers together (this will be used when
* concatenating runs together).
*/
void testAdditionOperator()
{
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");
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
mgr1 += mgr2;
double d;
d = mgr1.getProperty("double");
TS_ASSERT_DELTA( d, 35.6, 1e-4);
d = mgr1.getProperty("double_only_in_mgr1");
TS_ASSERT_DELTA( d, 456.0, 1e-4);
d = mgr1.getProperty("new_double_in_mgr2");
TS_ASSERT_DELTA( d, 321.0, 1e-4);
int i;
i = mgr1.getProperty("int");
TS_ASSERT_EQUALS( i, 57);
i = mgr1.getProperty("new_int");
TS_ASSERT_EQUALS( i, 655);
}
Russell Taylor
committed
PropertyManagerHelper * manager;
Russell Taylor
committed
Gigg, Martyn Anthony
committed
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
//-------------------------------------------------------------------------------------------------
// Performance Test
//-------------------------------------------------------------------------------------------------
class PropertyManagerTestPerformance : public CxxTest::TestSuite
{
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; }
PropertyManagerTestPerformance() : m_manager(), m_filter(createTestFilter())
{
const size_t nprops = 2000;
for(size_t i = 0; i < nprops; ++i)
{
m_manager.declareProperty(createTestSeries("prop" + boost::lexical_cast<std::string>(i)));
}
}
void test_Perf_Of_Filtering_Large_Number_Of_Properties_By_Other_Property()
{
m_manager.filterByProperty(*m_filter);
}
private:
/// Test manager
PropertyManagerHelper m_manager;
/// Test filter
boost::scoped_ptr<TimeSeriesProperty<bool>> m_filter;
};