BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
itemutils.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/itemutils.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 "google_test.h"
17 #include "mvvm/model/itemutils.h"
19 #include "mvvm/model/sessionitem.h"
21 #include "mvvm/model/taginfo.h"
23 #include <memory>
24 
25 using namespace ModelView;
26 
27 class ItemUtilsTest : public ::testing::Test {
28 };
29 
30 //! Simple iteration over item and its children
31 
32 TEST_F(ItemUtilsTest, iterateItem)
33 {
34  std::vector<const SessionItem*> visited_items;
35 
36  auto fun = [&](const SessionItem* item) { visited_items.push_back(item); };
37 
38  // iteration over nullptr
39  Utils::iterate(nullptr, fun);
40  EXPECT_TRUE(visited_items.empty());
41 
42  // iteration over lonely parent
43  std::unique_ptr<SessionItem> parent(new SessionItem);
44  parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true);
45 
46  std::vector<const SessionItem*> expected = {parent.get()};
47  Utils::iterate(parent.get(), fun);
48  EXPECT_EQ(visited_items, expected);
49 
50  // adding children
51  auto child1 = new SessionItem;
52  auto child2 = new SessionItem;
53  parent->insertItem(child1, TagRow::append());
54  parent->insertItem(child2, TagRow::append());
55 
56  visited_items.clear();
57  Utils::iterate(parent.get(), fun);
58 
59  expected = {parent.get(), child1, child2};
60  EXPECT_EQ(visited_items, expected);
61 }
62 
63 //! Conditional iteration over item and its children.
64 
65 TEST_F(ItemUtilsTest, iterateIfItem)
66 {
67  std::vector<const SessionItem*> visited_items;
68 
69  // function which will not let iterate over children
70  std::function<bool(const SessionItem*)> fun = [&](const SessionItem* item) {
71  visited_items.push_back(item);
72  return false;
73  };
74 
75  // iteration over lonely parent
76  std::unique_ptr<SessionItem> parent(new SessionItem);
77  parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true);
78 
79  auto child1 = new SessionItem;
80  auto child2 = new SessionItem;
81  parent->insertItem(child1, TagRow::append());
82  parent->insertItem(child2, TagRow::append());
83 
84  std::vector<const SessionItem*> expected = {parent.get()};
85  Utils::iterate_if(parent.get(), fun);
86  EXPECT_EQ(visited_items, expected);
87 }
88 
89 //! Iteration over root item of the model.
90 
91 TEST_F(ItemUtilsTest, iterateModel)
92 {
93  SessionModel model;
94 
95  // building model
96  auto parent1 = model.insertItem<SessionItem>();
97  auto parent2 = model.insertItem<SessionItem>();
98  parent1->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true);
99  parent2->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true);
100  auto child1 = model.insertItem<SessionItem>(parent1);
101  auto child2 = model.insertItem<SessionItem>(parent1);
102 
103  std::vector<const SessionItem*> visited_items;
104  auto fun = [&](const SessionItem* item) { visited_items.push_back(item); };
105 
106  // iteration
107  Utils::iterate(model.rootItem(), fun);
108 
109  std::vector<const SessionItem*> expected = {model.rootItem(), parent1, child1, child2, parent2};
110  EXPECT_EQ(visited_items, expected);
111 }
112 
113 //! Copy number of child in parents tree.
114 
115 TEST_F(ItemUtilsTest, itemCopyNumber)
116 {
117  SessionModel model;
118 
119  auto parent = model.insertItem<SessionItem>();
120  parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true);
121 
122  auto child1 = model.insertItem<SessionItem>(parent);
123  auto child2 = model.insertItem<SessionItem>(parent);
124  auto child3 = model.insertItem<PropertyItem>(parent);
125 
126  EXPECT_EQ(Utils::CopyNumber(child1), 0);
127  EXPECT_EQ(Utils::CopyNumber(child2), 1);
128  EXPECT_EQ(Utils::CopyNumber(child3), -1);
129 }
130 
131 //! Checks method ::HasTag.
132 
134 {
135  SessionItem item;
136  item.registerTag(TagInfo::universalTag("default_tag"), /*set_as_default*/ true);
137 
138  EXPECT_TRUE(Utils::HasTag(item, "default_tag"));
139  EXPECT_FALSE(Utils::HasTag(item, "nonexisting_tag"));
140 }
141 
142 //! Checks method ::IsSinglePropertyTag.
143 
145 {
146  SessionItem item;
147  item.registerTag(TagInfo::universalTag("default_tag"), /*set_as_default*/ true);
149 
150  EXPECT_FALSE(Utils::IsSinglePropertyTag(item, "default_tag"));
151  EXPECT_TRUE(Utils::IsSinglePropertyTag(item, "property_tag"));
152 }
153 
154 //! Checks method ::RegisteredTags.
155 
157 {
158  SessionItem item;
159  EXPECT_TRUE(Utils::RegisteredTags(item).empty());
160 
161  item.registerTag(TagInfo::universalTag("default_tag"), /*set_as_default*/ true);
163 
164  EXPECT_EQ(Utils::RegisteredTags(item),
165  std::vector<std::string>({"default_tag", "property_tag"}));
166 }
167 
168 //! Checks method ::RegisteredUniversalTags.
169 
171 {
172  SessionItem item;
173  EXPECT_TRUE(Utils::RegisteredUniversalTags(item).empty());
174 
175  item.registerTag(TagInfo::universalTag("default_tag"), /*set_as_default*/ true);
177 
178  EXPECT_EQ(Utils::RegisteredUniversalTags(item), std::vector<std::string>({"default_tag"}));
179 }
180 
181 //! Check access to top level and property items.
182 
184 {
185  SessionModel model;
186 
187  auto parent = model.insertItem<SessionItem>();
188  parent->registerTag(TagInfo::universalTag("default_tag"), /*set_as_default*/ true);
189  parent->registerTag(TagInfo::propertyTag("property_tag", Constants::PropertyType));
190 
191  auto child1 = model.insertItem<SessionItem>(parent, "default_tag");
192  model.insertItem<PropertyItem>(parent, "property_tag");
193  auto child3 = model.insertItem<SessionItem>(parent, "default_tag");
194 
195  EXPECT_EQ(Utils::TopLevelItems(*model.rootItem()), std::vector<SessionItem*>({parent}));
196  EXPECT_EQ(Utils::TopLevelItems(*child1), std::vector<SessionItem*>({}));
197  EXPECT_EQ(Utils::TopLevelItems(*parent), std::vector<SessionItem*>({child1, child3}));
198 }
199 
200 //! Check access to top level and property items.
201 
203 {
204  SessionModel model;
205 
206  auto parent = model.insertItem<SessionItem>();
207  parent->registerTag(TagInfo::universalTag("default_tag"), /*set_as_default*/ true);
208  parent->registerTag(TagInfo::propertyTag("property_tag", Constants::PropertyType));
209 
210  auto child1 = model.insertItem<SessionItem>(parent, "default_tag");
211  auto child2 = model.insertItem<PropertyItem>(parent, "property_tag");
212  model.insertItem<SessionItem>(parent, "default_tag");
213 
214  EXPECT_EQ(Utils::SinglePropertyItems(*model.rootItem()), std::vector<SessionItem*>({}));
215  EXPECT_EQ(Utils::SinglePropertyItems(*child1), std::vector<SessionItem*>({}));
216  EXPECT_EQ(Utils::SinglePropertyItems(*parent), std::vector<SessionItem*>({child2}));
217 }
218 
219 //! Looking for next item.
220 
222 {
223  SessionModel model;
224 
225  auto parent = model.insertItem<SessionItem>();
226  parent->registerTag(TagInfo::universalTag("default_tag"), /*set_as_default*/ true);
227  parent->registerTag(TagInfo::propertyTag("property_tag", Constants::PropertyType));
228 
229  auto property = model.insertItem<PropertyItem>(parent, "property_tag");
230  auto child0 = model.insertItem<SessionItem>(parent, "default_tag");
231  auto child1 = model.insertItem<SessionItem>(parent, "default_tag");
232  auto child2 = model.insertItem<SessionItem>(parent, "default_tag");
233 
234  EXPECT_EQ(Utils::FindNextSibling(child0), child1);
235  EXPECT_EQ(Utils::FindNextSibling(child1), child2);
236  EXPECT_EQ(Utils::FindNextSibling(child2), nullptr);
237  EXPECT_EQ(Utils::FindNextSibling(property), nullptr);
238  EXPECT_EQ(Utils::FindNextSibling(parent), nullptr);
239 }
240 
241 //! Looking for previous item.
242 
244 {
245  SessionModel model;
246 
247  auto parent = model.insertItem<SessionItem>();
248  parent->registerTag(TagInfo::universalTag("default_tag"), /*set_as_default*/ true);
249  parent->registerTag(TagInfo::propertyTag("property_tag", Constants::PropertyType));
250 
251  auto property = model.insertItem<PropertyItem>(parent, "property_tag");
252  auto child0 = model.insertItem<SessionItem>(parent, "default_tag");
253  auto child1 = model.insertItem<SessionItem>(parent, "default_tag");
254  auto child2 = model.insertItem<SessionItem>(parent, "default_tag");
255 
256  EXPECT_EQ(Utils::FindPreviousSibling(child0), nullptr);
257  EXPECT_EQ(Utils::FindPreviousSibling(child1), child0);
258  EXPECT_EQ(Utils::FindPreviousSibling(child2), child1);
259  EXPECT_EQ(Utils::FindPreviousSibling(property), nullptr);
260  EXPECT_EQ(Utils::FindPreviousSibling(parent), nullptr);
261 }
262 
263 //! Looking for previous item.
264 
266 {
267  SessionModel model;
268 
269  auto parent = model.insertItem<SessionItem>();
270  parent->registerTag(TagInfo::universalTag("default_tag"), /*set_as_default*/ true);
271  parent->registerTag(TagInfo::propertyTag("property_tag", Constants::PropertyType));
272 
273  auto property = model.insertItem<PropertyItem>(parent, "property_tag");
274  auto child0 = model.insertItem<SessionItem>(parent, "default_tag");
275  auto child1 = model.insertItem<SessionItem>(parent, "default_tag");
276  auto child2 = model.insertItem<SessionItem>(parent, "default_tag");
277 
278  EXPECT_EQ(Utils::FindNextItemToSelect(child0), child1);
279  EXPECT_EQ(Utils::FindNextItemToSelect(child1), child2);
280  EXPECT_EQ(Utils::FindNextItemToSelect(child2), child1);
281  EXPECT_EQ(Utils::FindNextItemToSelect(property), parent);
282  EXPECT_EQ(Utils::FindNextItemToSelect(parent), model.rootItem());
283 }
284 
285 //! Looking for previous item.
286 
288 {
289  SessionModel model;
290  EXPECT_FALSE(Utils::IsItemAncestor(model.rootItem(), model.rootItem()));
291 
292  // rootItem in ancestor of vectorItem, but not vice versa
293  auto vector_item = model.insertItem<VectorItem>();
294  EXPECT_TRUE(Utils::IsItemAncestor(vector_item, model.rootItem()));
295  EXPECT_FALSE(Utils::IsItemAncestor(model.rootItem(), vector_item));
296 
297  auto x_item = vector_item->getItem(VectorItem::P_X);
298 
299  EXPECT_TRUE(Utils::IsItemAncestor(x_item, model.rootItem()));
300  EXPECT_TRUE(Utils::IsItemAncestor(x_item, vector_item));
301  EXPECT_FALSE(Utils::IsItemAncestor(model.rootItem(), x_item));
302  EXPECT_FALSE(Utils::IsItemAncestor(vector_item, x_item));
303 
304  auto y_item = vector_item->getItem(VectorItem::P_Y);
305  EXPECT_FALSE(Utils::IsItemAncestor(x_item, y_item));
306 }
307 
309 {
310  SessionModel model;
311  auto item0 = model.insertItem<SessionItem>(model.rootItem());
312  auto item1 = model.insertItem<SessionItem>(model.rootItem());
313  auto item2 = model.insertItem<SessionItem>(model.rootItem());
314  std::vector<SessionItem*> data = {nullptr, item0, item1, item2, item0, item2, nullptr};
315  std::vector<SessionItem*> expected = {item0, item1, item2};
316  EXPECT_EQ(Utils::UniqueItems(data), expected);
317 }
318 
320 {
321  SessionModel model;
322  auto item0 = model.insertItem<SessionItem>(model.rootItem());
323  auto item1 = model.insertItem<PropertyItem>(model.rootItem());
324  auto item2 = model.insertItem<VectorItem>(model.rootItem());
325  std::vector<SessionItem*> data = {nullptr, item0, item1, item2, item0, item1, item2, nullptr};
326 
327  EXPECT_EQ(Utils::CastedItems<PropertyItem>(data), std::vector<PropertyItem*>({item1, item1}));
328 }
Item to carry concrete editable entity (e.g.
Definition: propertyitem.h:27
The main object representing an editable/displayable/serializable entity.
Definition: sessionitem.h:38
void registerTag(const TagInfo &tagInfo, bool set_as_default=false)
Registers tag to hold items under given name.
bool insertItem(SessionItem *item, const TagRow &tagrow)
Insert item into given tag under the given row.
Main class to hold hierarchy of SessionItem objects.
Definition: sessionmodel.h:37
SessionItem * rootItem() const
Returns root item of the model.
T * insertItem(SessionItem *parent=nullptr, const TagRow &tagrow={})
Inserts item into given parent under given tagrow.
Definition: sessionmodel.h:104
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
static TagRow append(const std::string &tag_name={})
Returns TagRow corresponding to the append to tag_name.
Definition: tagrow.cpp:36
Vector item with three x,y,z property items.
Definition: vectoritem.h:24
static const std::string P_X
Definition: vectoritem.h:26
static const std::string P_Y
Definition: vectoritem.h:27
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
TEST_F(ItemUtilsTest, iterateItem)
Simple iteration over item and its children.
const model_type PropertyType
Definition: mvvm_types.h:59
MVVM_MODEL_EXPORT int CopyNumber(const SessionItem *item)
Returns copy number of given item in it's parent hierarchy.
Definition: itemutils.cpp:49
MVVM_MODEL_EXPORT SessionItem * FindNextSibling(SessionItem *item)
Returns next sibling with same tag.
Definition: itemutils.cpp:131
MVVM_MODEL_EXPORT SessionItem * FindNextItemToSelect(SessionItem *item)
Finds next item to select Method is used in the context of next item selection after given item was d...
Definition: itemutils.cpp:149
MVVM_MODEL_EXPORT std::vector< SessionItem * > SinglePropertyItems(const SessionItem &item)
Returns vector of children representing property items.
Definition: itemutils.cpp:122
MVVM_MODEL_EXPORT void iterate(SessionItem *item, const std::function< void(SessionItem *)> &fun)
Iterates through item and all its children.
Definition: itemutils.cpp:24
MVVM_MODEL_EXPORT std::vector< SessionItem * > UniqueItems(const std::vector< SessionItem * > &items)
Returns vector with duplicates and 'nullptr' filtered out.
Definition: itemutils.cpp:170
MVVM_MODEL_EXPORT void iterate_if(const SessionItem *item, const std::function< bool(const SessionItem *)> &fun)
Iterates through all model indices and calls user function.
Definition: itemutils.cpp:35
MVVM_MODEL_EXPORT std::vector< SessionItem * > TopLevelItems(const SessionItem &item)
Returns vector of children representing top level items.
Definition: itemutils.cpp:113
MVVM_MODEL_EXPORT std::vector< std::string > RegisteredUniversalTags(const SessionItem &item)
Returns vector of strings containing all registered universal tags of the given item.
Definition: itemutils.cpp:104
MVVM_MODEL_EXPORT bool HasTag(const SessionItem &item, const std::string &tag)
Returns true if given item has registered tag.
Definition: itemutils.cpp:86
MVVM_MODEL_EXPORT std::vector< std::string > RegisteredTags(const SessionItem &item)
Returns vector of strings containing all registered tags of the given item.
Definition: itemutils.cpp:96
std::vector< T * > CastedItems(const std::vector< SessionItem * > &items)
Returns vector of items casted to given type.
Definition: itemutils.h:90
MVVM_MODEL_EXPORT bool IsItemAncestor(const SessionItem *item, const SessionItem *candidate)
Returns true if 'candidate' is one of ancestor of given item.
Definition: itemutils.cpp:156
MVVM_MODEL_EXPORT SessionItem * FindPreviousSibling(SessionItem *item)
Returns previous sibling with same tag.
Definition: itemutils.cpp:140
MVVM_MODEL_EXPORT bool IsSinglePropertyTag(const SessionItem &item, const std::string &tag)
Returns true if given item has registered tag, and it belongs to single property.
Definition: itemutils.cpp:91
materialitems.h Collection of materials to populate MaterialModel.
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?