Newer
Older
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2007 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source
// & Institut Laue - Langevin
// SPDX - License - Identifier: GPL - 3.0 +
#ifndef PROPERTYWITHVALUEJSONDECODERTEST_H
#define PROPERTYWITHVALUEJSONDECODERTEST_H
#include <cxxtest/TestSuite.h>
#include <jsoncpp/json/value.h>
#include "MantidKernel/ArrayProperty.h"
#include "MantidKernel/PropertyManager.h"
#include "MantidKernel/PropertyManagerProperty.h"
#include "MantidKernel/PropertyWithValueJSONDecoder.h"
class PropertyWithValueJSONDecoderTest : public CxxTest::TestSuite {
public:
static PropertyWithValueJSONDecoderTest *createSuite() {
return new PropertyWithValueJSONDecoderTest;
}
static void destroySuite(PropertyWithValueJSONDecoderTest *suite) {
return delete suite;
}
void testDecodeSingleJSONIntAsProperty() {
doSingleValueObjecteDecodeTest("IntProperty", 10);
}
void testDecodeSingleJSONDoubleAsProperty() {
doSingleValueObjecteDecodeTest("DoubleProperty", 10.5);
}
void testDecodeSingleJSONStringAsProperty() {
doSingleValueObjecteDecodeTest("StringProperty", std::string("My value"));
}
void testDecodeSingleJSONBoolAsProperty() {
doSingleValueObjecteDecodeTest("BoolProperty", false);
void testDecodeArrayValueAsArrayProperty() {
const auto propName{"ArrayProperty"};
const std::vector<double> propValue{1.0, 2.0, 3.0};
Json::Value arrayItem(Json::arrayValue);
for (const auto &elem : propValue)
arrayItem.append(elem);
Json::Value root;
root[propName] = arrayItem;
using Mantid::Kernel::ArrayProperty;
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
auto typedProperty =
doBasicDecodeTest<ArrayProperty<double>>(propName, root);
}
void testDecodeSingleObjectValuePropertyManagerProperty() {
const auto propName{"SinglePropertyManager"}, intKey("k1"), realKey("k2");
const int intValue(1);
const double realValue(5.3);
Json::Value dict(Json::objectValue);
dict[intKey] = intValue;
dict[realKey] = realValue;
Json::Value root;
root[propName] = dict;
using Mantid::Kernel::PropertyManagerProperty;
auto typedProperty =
doBasicDecodeTest<PropertyManagerProperty>(propName, root);
using Mantid::Kernel::PropertyManager_sptr;
PropertyManager_sptr propMgr{(*typedProperty)()};
TS_ASSERT_EQUALS(intValue, static_cast<int>(propMgr->getProperty(intKey)));
TS_ASSERT_EQUALS(realValue,
static_cast<double>(propMgr->getProperty(realKey)));
}
void testDecodeNestedObjectValuesAsNestedPropertyManagerProperty() {
const auto propName{"NestedPropertyManager"}, outerIntKey("k1"),
innerIntKey("ik1"), outerRealKey("k2"), innerRealKey("ik2"),
outerDictKey("ik3");
const int outerIntValue(1), innerIntValue(10);
const double outerRealValue(5.3), innerRealValue(15.3);
Json::Value innerDict(Json::objectValue);
innerDict[innerIntKey] = innerIntValue;
innerDict[innerRealKey] = innerRealValue;
Json::Value outerDict(Json::objectValue);
outerDict[outerIntKey] = outerIntValue;
outerDict[outerRealKey] = outerRealValue;
outerDict[outerDictKey] = innerDict;
Json::Value root;
root[propName] = outerDict;
using Mantid::Kernel::PropertyManagerProperty;
auto typedProperty =
doBasicDecodeTest<PropertyManagerProperty>(propName, root);
using Mantid::Kernel::PropertyManager_sptr;
PropertyManager_sptr propMgr{(*typedProperty)()};
TS_ASSERT_EQUALS(outerIntValue,
static_cast<int>(propMgr->getProperty(outerIntKey)));
TS_ASSERT_EQUALS(outerRealValue,
static_cast<double>(propMgr->getProperty(outerRealKey)));
// ----------------------- Failure tests -----------------------
void testDecodeThrowsWithEmptyValue() {
using Mantid::Kernel::decode;
Json::Value root;
TSM_ASSERT_THROWS("Expected decode to throw for empty value", decode(root),
std::invalid_argument);
}
void testDecodeThrowsWithGreaterThanOneMember() {
using Mantid::Kernel::decode;
Json::Value root;
root["one"] = 1;
root["two"] = 2;
TSM_ASSERT_THROWS("Expected decode to throw with more than 1 member",
decode(root), std::invalid_argument);
}
void testDecodeThrowsWithNonObjectValue() {
using Mantid::Kernel::decode;
TSM_ASSERT_THROWS("Expected decode to throw with non-object type",
decode(Json::Value(10)), std::invalid_argument);
}
void testDecodeEmptyArrayValueThrows() {
Json::Value root;
root["EmptyArray"] = Json::Value(Json::arrayValue);
using Mantid::Kernel::decode;
TSM_ASSERT_THROWS("Expected an empty json array to throw", decode(root),
std::invalid_argument);
}
void testDecodeHeterogenousArrayValueThrows() {
Json::Value mixedArray(Json::arrayValue);
mixedArray.append(1);
mixedArray.append(true);
mixedArray.append("hello");
Json::Value root;
root["MixedArray"] = mixedArray;
using Mantid::Kernel::decode;
TSM_ASSERT_THROWS("Expected an empty json array to throw", decode(root),
std::invalid_argument);
}
private:
template <typename ValueType>
void doSingleValueObjecteDecodeTest(const std::string &propName,
const ValueType &propValue) {
Json::Value root;
root[propName] = propValue;
using Mantid::Kernel::PropertyWithValue;
auto typedProperty =
doBasicDecodeTest<PropertyWithValue<ValueType>>(propName, root);
TS_ASSERT_EQUALS(propValue, (*typedProperty)());
}
template <typename PropertyType>
std::unique_ptr<PropertyType>
doBasicDecodeTest(const std::string &propName, const Json::Value &jsonValue) {
using Mantid::Kernel::decode;
auto property = decode(jsonValue);
TSM_ASSERT("Decode failed to create a Property. ", property);
auto typedProperty = std::unique_ptr<PropertyType>{
dynamic_cast<PropertyType *>(property.release())};
TSM_ASSERT("Property has unexpected type ", typedProperty);
TS_ASSERT_EQUALS(propName, typedProperty->name());
return typedProperty;
}
};
#endif // PROPERTYWITHVALUEJSONDECODERTEST_H