BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
jsonvariantconverter.test.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // qt-mvvm: Model-view-view-model framework for large GUI applications
4 //
5 //! @file mvvm/tests/testmodel/jsonvariantconverter.test.cpp
6 //! @brief Implements class CLASS?
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2020
11 //! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
15 #include "folderbasedtest.h"
16 #include "google_test.h"
22 #include "mvvm/utils/reallimits.h"
23 #include "test_utils.h"
24 #include <QColor>
25 #include <QJsonArray>
26 #include <QJsonDocument>
27 #include <QJsonObject>
28 #include <vector>
29 
30 using namespace ModelView;
31 
32 //! Test convertion of QVariant from/to QJsonObject.
33 
35 public:
36  JsonVariantConverterTest() : FolderBasedTest("test_JsonVariant") {}
38 
39  static QVariant ToJsonAndBack(const QVariant& variant)
40  {
41  JsonVariantConverter converter;
42  auto json = converter.get_json(variant);
43  return converter.get_variant(json);
44  }
45 };
46 
48 
49 //! Invalid QVariant conversion.
50 
52 {
53  JsonVariantConverter converter;
54 
55  QVariant variant;
56 
57  // from variant to json object
58  auto object = converter.get_json(variant);
59  EXPECT_TRUE(converter.isVariant(object));
60 
61  // from json object to variant
62  QVariant reco_variant = converter.get_variant(object);
63  EXPECT_FALSE(reco_variant.isValid());
64  EXPECT_EQ(variant, reco_variant);
65 }
66 
67 //! Bool QVariant conversion.
68 
70 {
71  JsonVariantConverter converter;
72 
73  const bool value(true);
74  QVariant variant(value);
75 
76  // from variant to json object
77  auto object = converter.get_json(variant);
78  EXPECT_TRUE(converter.isVariant(object));
79 
80  // from json object to variant
81  QVariant reco_variant = converter.get_variant(object);
82  EXPECT_TRUE(Utils::IsBoolVariant(reco_variant));
83  EXPECT_EQ(reco_variant.value<bool>(), value);
84  EXPECT_EQ(reco_variant.typeName(), Constants::bool_type_name);
85  EXPECT_EQ(variant, reco_variant);
86 
87  EXPECT_EQ(ToJsonAndBack(true).value<bool>(), true);
88  EXPECT_EQ(ToJsonAndBack(false).value<bool>(), false);
89 }
90 
91 //! Int QVariant conversion.
92 
94 {
95  JsonVariantConverter converter;
96 
97  const int value(42);
98  QVariant variant(value);
99 
100  // from variant to json object
101  auto object = converter.get_json(variant);
102  EXPECT_TRUE(converter.isVariant(object));
103 
104  // from json object to variant
105  QVariant reco_variant = converter.get_variant(object);
106  EXPECT_TRUE(Utils::IsIntVariant(reco_variant));
107  EXPECT_EQ(reco_variant.value<int>(), value);
108  EXPECT_EQ(reco_variant.typeName(), Constants::int_type_name);
109  EXPECT_EQ(variant, reco_variant);
110 }
111 
112 //! QVariant(std::string) conversion.
113 
115 {
116  JsonVariantConverter converter;
117 
118  const std::string value("abc");
119  QVariant variant = QVariant::fromValue(value);
120 
121  // from variant to json object
122  auto object = converter.get_json(variant);
123  EXPECT_TRUE(converter.isVariant(object));
124 
125  // from json object to variant
126  QVariant reco_variant = converter.get_variant(object);
127  EXPECT_TRUE(Utils::IsStdStringVariant(reco_variant));
128  EXPECT_EQ(reco_variant.typeName(), Constants::string_type_name);
129  EXPECT_EQ(reco_variant.value<std::string>(), value);
130 
131  EXPECT_EQ(variant, reco_variant);
132 }
133 
134 //! QVariant(double) conversion.
135 
137 {
138  JsonVariantConverter converter;
139 
140  double value(43.2);
141  QVariant variant = QVariant::fromValue(value);
142  EXPECT_EQ(variant.typeName(), Constants::double_type_name);
143 
144  // from variant to json object
145  auto object = converter.get_json(variant);
146  EXPECT_TRUE(converter.isVariant(object));
147 
148  // from json object to variant
149  QVariant reco_variant = converter.get_variant(object);
150  EXPECT_TRUE(Utils::IsDoubleVariant(reco_variant));
151  EXPECT_EQ(reco_variant.value<double>(), value);
152  EXPECT_EQ(variant, reco_variant);
153 
154  // more numbers
155  value = 1e-03;
156  EXPECT_DOUBLE_EQ(ToJsonAndBack(value).value<double>(), value);
157  value = 0.99e-7;
158  EXPECT_DOUBLE_EQ(ToJsonAndBack(value).value<double>(), value);
159  value = 3.14159265359;
160  EXPECT_DOUBLE_EQ(ToJsonAndBack(value).value<double>(), value);
161 }
162 
163 //! QVariant(double) conversion. Special value 43.0 which Qt likes to cast to int based variant.
164 
165 TEST_F(JsonVariantConverterTest, doubleVariantWhichLooksAsInt)
166 {
167  JsonVariantConverter converter;
168 
169  double value(43.0); // special value which Qt like to cast to int-based variant
170  QVariant variant = QVariant::fromValue(value);
171  EXPECT_EQ(variant.typeName(), Constants::double_type_name);
172  EXPECT_TRUE(Utils::IsDoubleVariant(variant));
173 
174  // from variant to json object
175  auto object = converter.get_json(variant);
176  EXPECT_TRUE(converter.isVariant(object));
177 
178  // from json object to variant
179  QVariant reco_variant = converter.get_variant(object);
180  EXPECT_TRUE(Utils::IsDoubleVariant(reco_variant));
181  EXPECT_EQ(reco_variant.value<double>(), value);
182  EXPECT_EQ(variant, reco_variant);
183 }
184 
185 //! QVariant(std::vector<double>) conversion.
186 
187 TEST_F(JsonVariantConverterTest, vectorOfDoubleVariant)
188 {
189  JsonVariantConverter converter;
190 
191  const std::vector<double> value = {42.0, 43.0, 44.0};
192  QVariant variant = QVariant::fromValue(value);
193 
194  // from variant to json object
195  auto object = converter.get_json(variant);
196  EXPECT_TRUE(converter.isVariant(object));
197 
198  // from json object to variant
199  QVariant reco_variant = converter.get_variant(object);
200  EXPECT_TRUE(Utils::IsDoubleVectorVariant(reco_variant));
201  EXPECT_EQ(reco_variant.value<std::vector<double>>(), value);
202  EXPECT_EQ(variant, reco_variant);
203 }
204 
205 //! QVariant(ComboProperty) conversion.
206 
207 TEST_F(JsonVariantConverterTest, comboPropertyVariant)
208 {
209  JsonVariantConverter converter;
210 
211  ComboProperty value = ComboProperty::createFrom(std::vector<std::string>({"a1", "a2", "a3"}));
212  value.setSelected("a1", false);
213  value.setSelected("a2", true);
214  value.setSelected("a3", true);
215 
216  QVariant variant = QVariant::fromValue(value);
217 
218  // from variant to json object
219  auto object = converter.get_json(variant);
220  EXPECT_TRUE(converter.isVariant(object));
221 
222  // from json object to variant
223  QVariant reco_variant = converter.get_variant(object);
224  EXPECT_TRUE(Utils::IsComboVariant(reco_variant));
225  EXPECT_EQ(reco_variant.value<ComboProperty>(), value);
226  EXPECT_EQ(variant, reco_variant);
227 }
228 
229 //! QVariant(QColor) conversion.
230 
232 {
233  JsonVariantConverter converter;
234 
235  const QColor value(Qt::red);
236  QVariant variant = QVariant::fromValue(value);
237 
238  // from variant to json object
239  auto object = converter.get_json(variant);
240  EXPECT_TRUE(converter.isVariant(object));
241 
242  // from json object to variant
243  QVariant reco_variant = converter.get_variant(object);
244  EXPECT_TRUE(Utils::IsColorVariant(reco_variant));
245  EXPECT_EQ(reco_variant.value<QColor>(), value);
246  EXPECT_EQ(variant, reco_variant);
247 }
248 
249 //! QVariant(ExternalProperty) conversion.
250 
252 {
253  JsonVariantConverter converter;
254 
255  const ExternalProperty value("abc", QColor(Qt::green), "123");
256  QVariant variant = QVariant::fromValue(value);
257 
258  // from variant to json object
259  auto object = converter.get_json(variant);
260  EXPECT_TRUE(converter.isVariant(object));
261 
262  // from json object to variant
263  QVariant reco_variant = converter.get_variant(object);
264  EXPECT_TRUE(Utils::IsExtPropertyVariant(reco_variant));
265  EXPECT_EQ(reco_variant.value<ExternalProperty>(), value);
266  EXPECT_EQ(variant, reco_variant);
267 }
268 
269 //! QVariant(RealLimits) convertion.
270 
271 TEST_F(JsonVariantConverterTest, realLimitsVariant)
272 {
273  JsonVariantConverter converter;
274 
275  RealLimits value = RealLimits::limited(1.0, 2.0);
276  QVariant variant = QVariant::fromValue(value);
277 
278  // from variant to json object
279  auto object = converter.get_json(variant);
280  EXPECT_TRUE(converter.isVariant(object));
281 
282  // from json object to variant
283  QVariant reco_variant = converter.get_variant(object);
284  EXPECT_TRUE(Utils::IsRealLimitsVariant(reco_variant));
285  EXPECT_EQ(reco_variant.value<RealLimits>(), value);
286  EXPECT_EQ(variant, reco_variant);
287 
288  // more values
289  value = RealLimits::positive();
290  EXPECT_EQ(ToJsonAndBack(QVariant::fromValue(value)).value<RealLimits>(), value);
291  value = RealLimits::nonnegative();
292  EXPECT_EQ(ToJsonAndBack(QVariant::fromValue(value)).value<RealLimits>(), value);
293  value = RealLimits::limited(0.123, 0.124);
294  EXPECT_EQ(ToJsonAndBack(QVariant::fromValue(value)).value<RealLimits>(), value);
295 }
296 
297 //! Writing variants to file and reading them back.
298 
300 {
301  const std::string string_value("abc");
302  const std::vector<double> vector_value = {42.1, 42.2, 42.3};
303  ComboProperty combo = ComboProperty::createFrom({"a 1", "a 2", "a/3"});
304  combo.setSelected("a 1", false);
305  combo.setSelected("a 2", true);
306  combo.setSelected("a/3", true);
307  QColor color(Qt::red);
308  ExternalProperty extprop("abc", QColor(Qt::green), "1-2-3");
309 
310  std::vector<QVariant> variants = {QVariant(),
311  QVariant(true),
312  QVariant(42),
313  QVariant(42.3),
314  QVariant(43.0),
315  QVariant(43.1),
316  QVariant(0.99e-7),
317  QVariant(3.14159265359),
318  QVariant::fromValue(string_value),
319  QVariant::fromValue(vector_value),
320  QVariant::fromValue(combo),
321  QVariant::fromValue(color),
322  QVariant::fromValue(extprop),
323  QVariant::fromValue(RealLimits::positive()),
324  QVariant::fromValue(RealLimits::limited(1.12, 2.32))};
325 
326  // preparing array of json objects
327  JsonVariantConverter converter;
328  QJsonArray json_array;
329  for (auto var : variants)
330  json_array.append(converter.get_json(var));
331 
332  // writing to file
333  auto fileName = TestUtils::TestFileName(testDir(), "variants.json");
334  TestUtils::SaveJson(json_array, fileName);
335 
336  // reading variants from file
337  auto document = TestUtils::LoadJson(fileName);
338  std::vector<QVariant> reco_variants;
339  for (const auto x : document.array())
340  reco_variants.push_back(converter.get_variant(x.toObject()));
341 
342  // comparing initial and reconstructed variants
343  EXPECT_EQ(variants, reco_variants);
344 }
Convenience class which creates a directory on disk for test content.
Test convertion of QVariant from/to QJsonObject.
static QVariant ToJsonAndBack(const QVariant &variant)
Custom property to define list of string values with multiple selections.
Definition: comboproperty.h:27
void setSelected(int index, bool value=true)
Sets given index selection flag.
static ComboProperty createFrom(const std::vector< std::string > &values, const std::string &current_value={})
Property to carry text, color and identifier.
Default converter between supported variants and json objects.
QJsonObject get_json(const Variant &variant) override
bool isVariant(const QJsonObject &object) const
Returns true if given json object represents variant.
Variant get_variant(const QJsonObject &object) override
Limits for double.
Definition: reallimits.h:25
static RealLimits positive()
Creates an object which can have only positive values (>0., zero is not included)
Definition: reallimits.cpp:46
static RealLimits nonnegative()
Creates an object which can have only positive values with 0. included.
Definition: reallimits.cpp:51
static RealLimits limited(double left_bound_value, double right_bound_value)
Creates an object bounded from the left and right.
Definition: reallimits.cpp:61
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
TEST_F(JsonVariantConverterTest, invalidVariant)
Invalid QVariant conversion.
const std::string string_type_name
const std::string bool_type_name
const std::string double_type_name
const std::string int_type_name
MVVM_MODEL_EXPORT bool IsIntVariant(const Variant &variant)
Returns true in the case of double value based variant.
MVVM_MODEL_EXPORT bool IsColorVariant(const Variant &variant)
Returns true in the case of QColor based variant.
MVVM_MODEL_EXPORT bool IsDoubleVariant(const Variant &variant)
Returns true in the case of double value based variant.
MVVM_MODEL_EXPORT bool IsStdStringVariant(const Variant &variant)
Returns true in the case of double value based variant.
MVVM_MODEL_EXPORT bool IsBoolVariant(const Variant &variant)
Returns true in the case of double value based variant.
MVVM_MODEL_EXPORT bool IsExtPropertyVariant(const Variant &variant)
Returns true in the case of ExternalProperty based variant.
MVVM_MODEL_EXPORT bool IsComboVariant(const Variant &variant)
Returns true in the case of double value based variant.
MVVM_MODEL_EXPORT bool IsDoubleVectorVariant(const Variant &variant)
Returns true in the case of variant based on std::vector<double>.
MVVM_MODEL_EXPORT bool IsRealLimitsVariant(const Variant &variant)
Returns true in the case of RealLimits based variant.
materialitems.h Collection of materials to populate MaterialModel.
std::string TestFileName(const std::string &test_sub_dir, const std::string &file_name)
Returns full path to the file in test directory.
Definition: test_utils.cpp:52
void SaveJson(const QJsonObject &object, const std::string &fileName)
Definition: test_utils.cpp:58
QJsonDocument LoadJson(const std::string &fileName)
Definition: test_utils.cpp:81
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?