-
Edward Brown authoredEdward Brown authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ArrayPropertyTest.h 13.18 KiB
#ifndef ARRAYPROPERTYTEST_H_
#define ARRAYPROPERTYTEST_H_
#include <cxxtest/TestSuite.h>
#include "MantidKernel/ArrayProperty.h"
using namespace Mantid::Kernel;
class ArrayPropertyTest : public CxxTest::TestSuite {
public:
void setUp() override {
iProp = new ArrayProperty<int>("intProp");
dProp = new ArrayProperty<double>("doubleProp");
sProp = new ArrayProperty<std::string>("stringProp");
}
void tearDown() override {
delete iProp;
delete dProp;
delete sProp;
}
void testConstructor() {
TS_ASSERT(!iProp->name().compare("intProp"))
TS_ASSERT(!iProp->documentation().compare(""))
TS_ASSERT(typeid(std::vector<int>) == *iProp->type_info())
TS_ASSERT(iProp->isDefault())
TS_ASSERT(iProp->operator()().empty());
TS_ASSERT(!dProp->name().compare("doubleProp"))
TS_ASSERT(!dProp->documentation().compare(""))
TS_ASSERT(typeid(std::vector<double>) == *dProp->type_info())
TS_ASSERT(dProp->isDefault())
TS_ASSERT(dProp->operator()().empty())
TS_ASSERT(!sProp->name().compare("stringProp"))
TS_ASSERT(!sProp->documentation().compare(""))
TS_ASSERT(typeid(std::vector<std::string>) == *sProp->type_info())
TS_ASSERT(sProp->isDefault())
TS_ASSERT(sProp->operator()().empty())
std::vector<int> i(5, 2);
ArrayProperty<int> ip("ip", i);
TS_ASSERT_EQUALS(ip.operator()().size(), 5)
TS_ASSERT_EQUALS(ip.operator()()[3], 2)
std::vector<double> d(4, 6.66);
ArrayProperty<double> dp("dp", d);
TS_ASSERT_EQUALS(dp.operator()().size(), 4)
TS_ASSERT_EQUALS(dp.operator()()[1], 6.66)
std::vector<std::string> s(3, "yyy");
ArrayProperty<std::string> sp("sp", s);
TS_ASSERT_EQUALS(sp.operator()().size(), 3)
TS_ASSERT(!sp.operator()()[2].compare("yyy"))
}
void testSize() {
TS_ASSERT_EQUALS(0, iProp->size());
TS_ASSERT_EQUALS(0, dProp->size());
TS_ASSERT_EQUALS(0, sProp->size());
// Make something bigger and test that.
Property *a = new ArrayProperty<int>("int_property", "1, 2, 3");
TS_ASSERT_EQUALS(3, a->size());
delete a;
// Test vector of vector.
// Make it 10 elements long, but
// should only be the size of the
// parent vector that is counted.
std::vector<std::vector<int>> input{{10}};
Property *b = new ArrayProperty<std::vector<int>>("vec_property", input);
TS_ASSERT_EQUALS(1, b->size());
delete b;
}
void testConstructorByString() {
const std::string &i_stringValue = "1,2,3";
ArrayProperty<int> i("i", i_stringValue);
TS_ASSERT_EQUALS(i.operator()()[0], 1);
TS_ASSERT_EQUALS(i.operator()()[1], 2);
TS_ASSERT_EQUALS(i.operator()()[2], 3);
TS_ASSERT_EQUALS(i.getDefault(), "1,2,3");
TS_ASSERT(i.isDefault());
ArrayProperty<int> i2("i", "-1-1");
TS_ASSERT_EQUALS(i2.operator()()[0], -1);
TS_ASSERT_EQUALS(i2.operator()()[1], 0);
TS_ASSERT_EQUALS(i2.operator()()[2], 1);
ArrayProperty<int> i4("i", "-1:1");
TS_ASSERT_EQUALS(i4.operator()()[0], -1);
TS_ASSERT_EQUALS(i4.operator()()[1], 0);
TS_ASSERT_EQUALS(i4.operator()()[2], 1);
ArrayProperty<int> i5("i", "-3--1");
TS_ASSERT_EQUALS(i5.operator()()[0], -3);
TS_ASSERT_EQUALS(i5.operator()()[1], -2);
TS_ASSERT_EQUALS(i5.operator()()[2], -1);
ArrayProperty<int> i7("i", "-3:-1");
TS_ASSERT_EQUALS(i7.operator()()[0], -3);
TS_ASSERT_EQUALS(i7.operator()()[1], -2);
TS_ASSERT_EQUALS(i7.operator()()[2], -1);
ArrayProperty<unsigned int> i3("i", "0:2,5");
TS_ASSERT_EQUALS(i3.operator()()[0], 0);
TS_ASSERT_EQUALS(i3.operator()()[1], 1);
TS_ASSERT_EQUALS(i3.operator()()[2], 2);
TS_ASSERT_EQUALS(i3.operator()()[3], 5);
ArrayProperty<unsigned int> i6("i", "5,0-2,5");
TS_ASSERT_EQUALS(i6.operator()()[0], 5);
TS_ASSERT_EQUALS(i6.operator()()[1], 0);
TS_ASSERT_EQUALS(i6.operator()()[2], 1);
TS_ASSERT_EQUALS(i6.operator()()[3], 2);
TS_ASSERT_EQUALS(i6.operator()()[4], 5);
ArrayProperty<double> d("d", "7.77,8.88,9.99");
TS_ASSERT_EQUALS(d.operator()()[0], 7.77)
TS_ASSERT_EQUALS(d.operator()()[1], 8.88)
TS_ASSERT_EQUALS(d.operator()()[2], 9.99)
ArrayProperty<double> d2("d", "-0.15,0.0,0.15");
TS_ASSERT_EQUALS(d2.operator()()[0], -0.15)
TS_ASSERT_EQUALS(d2.operator()()[1], 0.0)
TS_ASSERT_EQUALS(d2.operator()()[2], 0.15)
// Now we change the values that are set in the indices of d2
// by using a string
d2.setValue("0.3,0.1,-0.2");
TS_ASSERT_EQUALS(d2.operator()()[0], 0.3)
TS_ASSERT_EQUALS(d2.operator()()[1], 0.1)
TS_ASSERT_EQUALS(d2.operator()()[2], -0.2)
TS_ASSERT_EQUALS(d2.value(), "0.3,0.1,-0.2");
TS_ASSERT(!d2.isDefault());
ArrayProperty<std::string> s("d", "a,b,c");
TS_ASSERT(!s.operator()()[0].compare("a"))
TS_ASSERT(!s.operator()()[1].compare("b"))
TS_ASSERT(!s.operator()()[2].compare("c"))
TS_ASSERT_THROWS(ArrayProperty<int> ii("ii", "aa,bb"), std::bad_cast)
TS_ASSERT_THROWS(ArrayProperty<int> ii("ii", "5.5,6.6"), std::bad_cast)
TS_ASSERT_THROWS(ArrayProperty<double> dd("dd", "aa,bb"), std::bad_cast)
}
void testConstructorByString_long() {
ArrayProperty<long> prop("long", "0:2,5");
TS_ASSERT_EQUALS(prop.operator()()[0], 0);
TS_ASSERT_EQUALS(prop.operator()()[1], 1);
TS_ASSERT_EQUALS(prop.operator()()[2], 2);
TS_ASSERT_EQUALS(prop.operator()()[3], 5);
}
void testCopyConstructor() {
ArrayProperty<int> i = *iProp;
TS_ASSERT(!i.name().compare("intProp"))
TS_ASSERT(!i.documentation().compare(""))
TS_ASSERT(typeid(std::vector<int>) == *i.type_info())
TS_ASSERT(i.isDefault())
TS_ASSERT(i.operator()().empty())
ArrayProperty<double> d = *dProp;
TS_ASSERT(!d.name().compare("doubleProp"))
TS_ASSERT(!d.documentation().compare(""))
TS_ASSERT(typeid(std::vector<double>) == *d.type_info())
TS_ASSERT(d.isDefault())
TS_ASSERT(d.operator()().empty())
ArrayProperty<std::string> s = *sProp;
TS_ASSERT(!s.name().compare("stringProp"))
TS_ASSERT(!s.documentation().compare(""))
TS_ASSERT(typeid(std::vector<std::string>) == *s.type_info())
TS_ASSERT(s.isDefault())
TS_ASSERT(s.operator()().empty())
}
void testValue() {
std::vector<int> i(3, 3);
ArrayProperty<int> ip("ip", i);
TS_ASSERT(!ip.value().compare("3,3,3"))
std::vector<double> d(4, 1.23);
ArrayProperty<double> dp("dp", d);
TS_ASSERT(!dp.value().compare("1.23,1.23,1.23,1.23"))
std::vector<std::string> s(2, "yyy");
ArrayProperty<std::string> sp("sp", s);
TS_ASSERT(!sp.value().compare("yyy,yyy"))
}
void testSetValueAndIsDefault() {
std::string couldnt = "Could not set property ",
cant = ". Can not convert \"";
TS_ASSERT_EQUALS(iProp->setValue("1.1,2,2"), couldnt + iProp->name() +
cant + "1.1,2,2\" to " +
iProp->type())
TS_ASSERT(iProp->operator()().empty())
TS_ASSERT(iProp->isDefault())
TS_ASSERT_EQUALS(iProp->setValue("aaa,bbb"), couldnt + iProp->name() +
cant + "aaa,bbb\" to " +
iProp->type())
TS_ASSERT(iProp->operator()().empty())
TS_ASSERT(iProp->isDefault())
TS_ASSERT_EQUALS(iProp->setValue("1,2,3,4"), "")
TS_ASSERT_EQUALS(iProp->operator()().size(), 4)
for (std::size_t i = 0; i < 4; ++i) {
TS_ASSERT_EQUALS(iProp->operator()()[i], i + 1)
}
TS_ASSERT(!iProp->isDefault())
TS_ASSERT_EQUALS(iProp->setValue(""), "")
TS_ASSERT(iProp->operator()().empty())
TS_ASSERT(iProp->isDefault())
TS_ASSERT_EQUALS(dProp->setValue("aaa,bbb"), couldnt + dProp->name() +
cant + "aaa,bbb\" to " +
dProp->type())
TS_ASSERT(dProp->operator()().empty())
TS_ASSERT(dProp->isDefault())
TS_ASSERT_EQUALS(dProp->setValue("1,2"), "")
TS_ASSERT_EQUALS(dProp->operator()()[1], 2)
TS_ASSERT(!dProp->isDefault())
TS_ASSERT_EQUALS(dProp->setValue("1.11,2.22,3.33,4.44"), "")
TS_ASSERT_EQUALS(dProp->operator()()[0], 1.11)
TS_ASSERT(!dProp->isDefault())
TS_ASSERT_EQUALS(dProp->setValue(""), "")
TS_ASSERT(dProp->operator()().empty())
TS_ASSERT(dProp->isDefault())
TS_ASSERT_EQUALS(sProp->setValue("This,is,a,test"), "")
TS_ASSERT_EQUALS(sProp->operator()()[2], "a")
TS_ASSERT(!sProp->isDefault())
TS_ASSERT_EQUALS(sProp->setValue(""), "")
TS_ASSERT(sProp->operator()().empty())
TS_ASSERT(sProp->isDefault())
}
void testAssignmentOperator() {
ArrayProperty<int> i("i");
TS_ASSERT(i.isDefault())
std::vector<int> ii(3, 4);
i = ii;
TS_ASSERT_EQUALS(i.operator()(), ii);
TS_ASSERT_EQUALS(i.operator()()[1], 4)
TS_ASSERT(!i.isDefault())
ArrayProperty<double> d("d");
TS_ASSERT(d.isDefault())
std::vector<double> dd(5, 9.99);
d = dd;
TS_ASSERT_EQUALS(d.operator()(), dd);
TS_ASSERT_EQUALS(d.operator()()[3], 9.99)
TS_ASSERT(!d.isDefault())
ArrayProperty<std::string> s("s");
TS_ASSERT(s.isDefault())
std::vector<std::string> ss(2, "zzz");
s = ss;
TS_ASSERT_EQUALS(s.operator()(), ss)
TS_ASSERT_EQUALS(s.operator()()[0], "zzz")
TS_ASSERT(!s.isDefault())
}
void testOperatorBrackets() {
TS_ASSERT(iProp->operator()().empty())
TS_ASSERT(dProp->operator()().empty())
TS_ASSERT(sProp->operator()().empty())
}
void testOperatorNothing() {
std::vector<int> i = *iProp;
TS_ASSERT(i.empty())
std::vector<double> d(3, 8.8);
*dProp = d;
std::vector<double> dd = *dProp;
for (std::size_t i = 0; i < 3; ++i) {
TS_ASSERT_EQUALS(dProp->operator()()[i], 8.8)
}
std::vector<std::string> s = *sProp;
TS_ASSERT(s.empty())
}
void testCasting() {
TS_ASSERT_DIFFERS(
dynamic_cast<PropertyWithValue<std::vector<int>> *>(iProp),
static_cast<PropertyWithValue<std::vector<int>> *>(nullptr))
TS_ASSERT_DIFFERS(
dynamic_cast<PropertyWithValue<std::vector<double>> *>(dProp),
static_cast<PropertyWithValue<std::vector<double>> *>(nullptr))
TS_ASSERT_DIFFERS(
dynamic_cast<PropertyWithValue<std::vector<std::string>> *>(sProp),
static_cast<PropertyWithValue<std::vector<std::string>> *>(nullptr))
TS_ASSERT_DIFFERS(dynamic_cast<Property *>(iProp),
static_cast<Property *>(nullptr))
TS_ASSERT_DIFFERS(dynamic_cast<Property *>(dProp),
static_cast<Property *>(nullptr))
TS_ASSERT_DIFFERS(dynamic_cast<Property *>(sProp),
static_cast<Property *>(nullptr))
}
void testPrettyPrinting() {
const std::vector<std::string> inputList{
"1,2,3", "-1,0,1", "356,366,367,368,370,371,372,375", "7,6,5,6,7,8,10",
"1-9998, 9999, 2000, 20002-29999"};
const std::vector<std::string> resultList{
"1-3", "-1-1", "356,366-368,370-372,375", "7,6,5-8,10",
"1-9999,2000,20002-29999"};
TSM_ASSERT("Test Failed for vectors of int",
listShorteningwithType<int>(inputList, resultList));
TSM_ASSERT("Test Failed for vectors of long",
listShorteningwithType<long>(inputList, resultList));
// explicit test for in32_t with matches det_id_t and spec_id_t
TSM_ASSERT("Test Failed for vectors of int32_t",
listShorteningwithType<int32_t>(inputList, resultList));
// unsigned types
const std::vector<std::string> inputListUnsigned{
"1,2,3", "356,366,367,368,370,371,372,375", "7,6,5,6,7,8,10",
"1-9998, 9999, 2000, 20002-29999"};
const std::vector<std::string> resultListUnsigned{
"1-3", "356,366-368,370-372,375", "7,6,5-8,10",
"1-9999,2000,20002-29999"};
TSM_ASSERT("Test Failed for vectors of unsigned int",
listShorteningwithType<unsigned int>(inputListUnsigned,
resultListUnsigned));
TSM_ASSERT(
"Test Failed for vectors of size_t",
listShorteningwithType<size_t>(inputListUnsigned, resultListUnsigned));
// check shortening does not happen for floating point types
const std::vector<std::string> inputListFloat{
"1.0,2.0,3.0", "1.0,1.5,2.0,3.0", "-1,0,1",
};
const std::vector<std::string> resultListFloat{
"1,2,3", "1,1.5,2,3", "-1,0,1",
};
TSM_ASSERT("Test Failed for vectors of float",
listShorteningwithType<float>(inputListFloat, resultListFloat));
TSM_ASSERT("Test Failed for vectors of double",
listShorteningwithType<double>(inputListFloat, resultListFloat));
}
template <typename T>
bool listShorteningwithType(const std::vector<std::string> &inputList,
const std::vector<std::string> &resultList) {
bool success = true;
for (size_t i = 0; i < inputList.size(); i++) {
ArrayProperty<T> listProperty("i", inputList[i]);
std::string response = listProperty.valueAsPrettyStr(0, true);
TS_ASSERT_EQUALS(response, resultList[i]);
if (response != resultList[i]) {
success = false;
}
}
return success;
}
private:
ArrayProperty<int> *iProp;
ArrayProperty<double> *dProp;
ArrayProperty<std::string> *sProp;
};
#endif /*ARRAYPROPERTYTEST_H_*/