BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
jsonitemcontainerconverter.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/jsonitemcontainerconverter.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"
17 #include "mvvm/model/mvvm_types.h"
25 #include "test_utils.h"
26 #include <QJsonArray>
27 #include <QJsonDocument>
28 #include <QJsonObject>
29 
30 using namespace ModelView;
31 
32 //! Checks JsonItemContainerConverter class and its ability to convert SessionItemContainer
33 //! to json and back. Full testing is not possible since JsonItemContainerConverter
34 //! requires machinery provided by JsonItemConverter. Simplifed item/json creation is used.
35 
37 public:
39  : FolderBasedTest("test_JsonItemContainerConverterTest")
40  , m_itemdata_converter(std::make_unique<JsonItemDataConverter>())
41  {
42  }
43 
44  std::unique_ptr<JsonItemContainerConverter> createConverter() const
45  {
46  //! Simplified method to convert SessionItem to JSON object.
47  auto to_json = [this](const SessionItem& item) {
48  QJsonObject result;
49  result[JsonItemFormatAssistant::modelKey] = QString::fromStdString(item.modelType());
51  m_itemdata_converter->to_json(*item.itemData());
52  result[JsonItemFormatAssistant::itemTagsKey] = QJsonObject();
53  return result;
54  };
55 
56  //! Simplified method to create SessionItem from JSON object
57  auto create_item = [this](const QJsonObject& json) {
58  auto result = std::make_unique<SessionItem>();
59  m_itemdata_converter->from_json(json[JsonItemFormatAssistant::itemDataKey].toArray(),
60  *result->itemData());
61  return result;
62  };
63 
64  //! Simplified method to update SessionItem from JSON object
65  auto update_item = [this](const QJsonObject& json, SessionItem* item) {
66  m_itemdata_converter->from_json(json[JsonItemFormatAssistant::itemDataKey].toArray(),
67  *item->itemData());
68  };
69 
70  ConverterCallbacks callbacks{to_json, create_item, update_item};
71  return std::make_unique<JsonItemContainerConverter>(callbacks);
72  }
73 
75 
76  std::unique_ptr<JsonItemDataConverter> m_itemdata_converter;
77 };
78 
80 
81 //! SessionItemContainer (with single property item) to json object.
82 
83 TEST_F(JsonItemContainerConverterTest, propertyContainerToJson)
84 {
85  // creating container
87  SessionItemContainer container(tag);
88 
89  // inserting single property item
90  auto item = new PropertyItem;
91  item->setData(42);
92  EXPECT_TRUE(container.insertItem(item, 0));
93 
94  // converting top JSON and checking that it is valid JSON object
95  auto converter = createConverter();
96  auto json = converter->to_json(container);
97 
98  JsonItemFormatAssistant assistant;
99  EXPECT_TRUE(assistant.isSessionItemContainer(json));
100 }
101 
102 //! SessionItemContainer (with single property item) to json object and back.
103 
104 TEST_F(JsonItemContainerConverterTest, propertyContainerToJsonAndBack)
105 {
106  // creating container
108  SessionItemContainer container(tag);
109 
110  // inserting single property item
111  auto item = new PropertyItem;
112  item->setData(42);
113  EXPECT_TRUE(container.insertItem(item, 0));
114 
115  // converting top JSON
116  auto converter = createConverter();
117  auto json = converter->to_json(container);
118 
119  // creating second container with same layout, and updating it from JSON
120  SessionItemContainer container2(tag);
121  auto item2 = new PropertyItem;
122  item2->setData(43);
123  EXPECT_TRUE(container2.insertItem(item2, 0));
124  converter->from_json(json, container2);
125 
126  // Checking that item in container2 has been reused, and get same properties as item.
127  EXPECT_EQ(container2.itemAt(0), item2);
128  EXPECT_EQ(item->displayName(), item2->displayName());
129  EXPECT_EQ(item->identifier(), item2->identifier());
130  EXPECT_EQ(42, item2->data<int>());
131 }
132 
133 //! SessionItemContainer (with single property item) to json file and back.
134 
135 TEST_F(JsonItemContainerConverterTest, propertyContainerToFileAndBack)
136 {
137  // creating container
139  SessionItemContainer container(tag);
140 
141  // inserting single property item
142  auto item = new PropertyItem;
143  item->setData(42);
144  EXPECT_TRUE(container.insertItem(item, 0));
145 
146  // converting top JSON and checking that it is valid JSON object
147  auto converter = createConverter();
148  auto json = converter->to_json(container);
149 
150  // saving object to file
151  auto fileName = TestUtils::TestFileName(testDir(), "propertyContainerToFileAndBack.json");
152  TestUtils::SaveJson(json, fileName);
153 
154  // loading from file
155  auto document = TestUtils::LoadJson(fileName);
156 
157  // creating second container with same layout, and updating it from JSON
158  SessionItemContainer container2(tag);
159  auto item2 = new PropertyItem;
160  item2->setData(43);
161  EXPECT_TRUE(container2.insertItem(item2, 0));
162  converter->from_json(document.object(), container2);
163 
164  // Checking that item in container2 has been reused, and get same properties as item.
165  EXPECT_EQ(container2.itemAt(0), item2);
166  EXPECT_EQ(item->displayName(), item2->displayName());
167  EXPECT_EQ(item->identifier(), item2->identifier());
168  EXPECT_EQ(42, item2->data<int>());
169 }
170 
171 //! SessionItemContainer (with universal tag and several items) to json object and back.
172 
173 TEST_F(JsonItemContainerConverterTest, universalContainerToJsonAndBack)
174 {
175  // creating container
176  TagInfo tag = TagInfo::universalTag("items");
177  SessionItemContainer container(tag);
178 
179  // inserting single property item
180  const int n_max_items = 3;
181  for (int i = 0; i < n_max_items; ++i) {
182  auto item = new PropertyItem;
183  item->setData(i + 42);
184  EXPECT_TRUE(container.insertItem(item, 0));
185  }
186 
187  // converting top JSON
188  auto converter = createConverter();
189  auto json = converter->to_json(container);
190 
191  // creating second container with same layout, but without items
192  SessionItemContainer container2(tag);
193  converter->from_json(json, container2);
194 
195  // Checking that container2 got same content as container
196  EXPECT_EQ(container2.itemCount(), n_max_items);
197  for (int i = 0; i < n_max_items; ++i) {
198  EXPECT_EQ(container.itemAt(i)->identifier(), container2.itemAt(i)->identifier());
199  EXPECT_EQ(container.itemAt(i)->data<int>(), container2.itemAt(i)->data<int>());
200  }
201 }
Convenience class which creates a directory on disk for test content.
Checks JsonItemContainerConverter class and its ability to convert SessionItemContainer to json and b...
std::unique_ptr< JsonItemContainerConverter > createConverter() const
std::unique_ptr< JsonItemDataConverter > m_itemdata_converter
Default converter of SessionItemData to/from json object.
Utility class to determine, whether given JSON object can represent various parts of SessionModel.
bool isSessionItemContainer(const QJsonObject &json) const
Returns true if given json object represents SessionItemContainer.
Item to carry concrete editable entity (e.g.
Definition: propertyitem.h:27
Holds collection of SessionItem objects related to the same tag.
bool insertItem(SessionItem *item, int index)
Inserts item in a vector of children at given index, returns true in the case of success.
int itemCount() const
Returns number of items in given tag.
SessionItem * itemAt(int index) const
Returns item at given index. Returns nullptr if index is invalid.
The main object representing an editable/displayable/serializable entity.
Definition: sessionitem.h:38
std::string identifier() const
Returns unique identifier.
Definition: sessionitem.cpp:87
bool setData(const T &value, int role=ItemDataRole::DATA, bool direct=false)
Sets data for a given role.
Definition: sessionitem.h:141
T data(int role=ItemDataRole::DATA) const
Returns data of given type T for given role.
Definition: sessionitem.h:148
Holds info about single tag for SessionItem.
Definition: taginfo.h:28
static TagInfo universalTag(std::string name, std::vector< std::string > modelTypes={})
Constructs universal tag intended for unlimited amount of various items.
Definition: taginfo.cpp:34
static TagInfo propertyTag(std::string name, std::string model_type)
Constructs tag intended for single property.
Definition: taginfo.cpp:40
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
TEST_F(JsonItemContainerConverterTest, propertyContainerToJson)
SessionItemContainer (with single property item) to json object.
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
const model_type PropertyType
Definition: mvvm_types.h:59
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
std::unique_ptr< IUnitConverter > createConverter(const ISimulation &simulation)
Definition: filesystem.h:81
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Provides necessary callbacks to convert SessionItem to JSON and back.
Defines class CLASS?