BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
toyitemsshapegroup.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/testintegration/toyitemsshapegroup.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"
20 #include "toyitems.h"
21 #include "toymodel.h"
22 #include <QSignalSpy>
23 
24 using namespace ModelView;
25 
26 //! Tests of toy ShapeGroup in the context of model and viewmodel.
27 
28 class ToyItemsShapeGroupTest : public ::testing::Test {
29 public:
31 };
32 
34 
35 //! Toy multilayer as produced bo toy SampleModel.
36 
38 {
40 
41  EXPECT_EQ(item.currentIndex(), 1);
42  ASSERT_TRUE(item.currentItem() != nullptr);
43  EXPECT_TRUE(item.data<QVariant>().isValid());
44  EXPECT_EQ(item.currentType(), item.currentItem()->modelType());
46  ASSERT_EQ(item.children().size(), 3);
47 
48  // parent child relationship
49  EXPECT_EQ(item.children().at(0)->parent(), &item);
50  EXPECT_EQ(item.children().at(1)->parent(), &item);
51  EXPECT_EQ(item.children().at(2)->parent(), &item);
52 
53  // expected value in combo
54  ComboProperty combo = item.data<ComboProperty>();
55  EXPECT_EQ(combo.currentIndex(), 1);
56  EXPECT_EQ(combo.values(),
57  std::vector<std::string>({"Cylinder", "Full sphere", "Anysotropical pyramid"}));
58 }
59 
61 {
64 
65  EXPECT_EQ(item.currentIndex(), 0);
66  ASSERT_TRUE(item.currentItem() != nullptr);
67  EXPECT_EQ(item.currentType(), item.currentItem()->modelType());
69  EXPECT_TRUE(item.data<QVariant>().isValid());
70  EXPECT_EQ(item.children().size(), 3);
71 
72  // expected value in combo
73  ComboProperty combo = item.data<ComboProperty>();
74  EXPECT_EQ(combo.currentIndex(), 0);
75  EXPECT_EQ(combo.values(),
76  std::vector<std::string>({"Cylinder", "Full sphere", "Anysotropical pyramid"}));
77 }
78 
79 TEST_F(ToyItemsShapeGroupTest, currentItemNoConst)
80 {
83  EXPECT_EQ(item.currentItem()->property<double>(ToyItems::SphereItem::P_RADIUS), 42.0);
84 }
85 
87 {
89  auto item = model.insertItem<ToyItems::ShapeGroupItem>();
90  ASSERT_TRUE(item != nullptr);
91 
92  EXPECT_EQ(item->currentIndex(), 1);
93  ASSERT_TRUE(item->currentItem() != nullptr);
94  EXPECT_TRUE(item->data<QVariant>().isValid());
95  EXPECT_EQ(item->currentType(), item->currentItem()->modelType());
96  EXPECT_EQ(item->children().size(), 3);
97 
98  // parent child relationship
99  EXPECT_EQ(item->children().at(0)->parent(), item);
100  EXPECT_EQ(item->children().at(1)->parent(), item);
101  EXPECT_EQ(item->children().at(2)->parent(), item);
102 
103  // model relationship
104  EXPECT_EQ(item->children().at(0)->model(), &model);
105  EXPECT_EQ(item->children().at(1)->model(), &model);
106  EXPECT_EQ(item->children().at(2)->model(), &model);
107 }
108 
109 TEST_F(ToyItemsShapeGroupTest, setDataInModelContext)
110 {
111  ToyItems::SampleModel model;
112  auto item = model.insertItem<ToyItems::ShapeGroupItem>();
113  ASSERT_TRUE(item != nullptr);
114 
115  // initial status
116  EXPECT_EQ(item->currentIndex(), 1);
117  EXPECT_EQ(item->currentType(), ToyItems::Constants::SphereItemType);
118  ComboProperty combo = model.data(item, ItemDataRole::DATA).value<ComboProperty>();
119  EXPECT_EQ(combo.currentIndex(), 1);
120 
121  // setting through combo
122  combo.setCurrentIndex(0);
123  model.setData(item, QVariant::fromValue(combo), ItemDataRole::DATA);
124 
125  EXPECT_EQ(item->currentIndex(), 0);
126  EXPECT_EQ(item->currentType(), ToyItems::Constants::CylinderItemType);
127 }
128 
129 //! ViewLabelItem and ViewDataItem from ShapeItem.
130 
131 TEST_F(ToyItemsShapeGroupTest, viewItemsFromShapeGroup)
132 {
133  ToyItems::SampleModel model;
134 
135  auto groupItem = model.insertItem<ToyItems::ShapeGroupItem>();
136 
137  ViewLabelItem labelItem(groupItem);
138  EXPECT_EQ(labelItem.data(Qt::DisplayRole).toString().toStdString(),
140 
141  ViewDataItem dataItem(groupItem);
142  EXPECT_EQ(dataItem.data(Qt::DisplayRole).value<ComboProperty>().currentIndex(), 1);
143 }
144 
145 //! ShapeGroup item in DefaultViewModel.
146 
147 TEST_F(ToyItemsShapeGroupTest, inDefaultViewModelContext)
148 {
149  ToyItems::SampleModel model;
150  auto groupItem = model.insertItem<ToyItems::ShapeGroupItem>();
151 
152  // constructing viewModel from sample model
153  DefaultViewModel viewModel(&model);
154 
155  // root item should have one child, item looking at our groupItem
156  EXPECT_EQ(viewModel.rowCount(), 1);
157  EXPECT_EQ(viewModel.columnCount(), 2);
158 
159  // accessing to viewItem representing groupItem
160  QModelIndex groupIndex = viewModel.index(0, 0);
161  EXPECT_EQ(viewModel.sessionItemFromIndex(groupIndex), groupItem);
162  EXPECT_EQ(viewModel.columnCount(groupIndex), 2);
163  EXPECT_EQ(viewModel.rowCount(groupIndex), 3); // Cylinder, Sphere, Anysopyramid
164 
165  // setting up signal spy
166  QSignalSpy spyRemove(&viewModel, &DefaultViewModel::rowsRemoved);
167  QSignalSpy spyInsert(&viewModel, &DefaultViewModel::rowsInserted);
168  QSignalSpy spyData(&viewModel, &DefaultViewModel::dataChanged);
169 
170  // changing the data
171  ComboProperty combo = model.data(groupItem, ItemDataRole::DATA).value<ComboProperty>();
172  combo.setCurrentIndex(0);
173  model.setData(groupItem, QVariant::fromValue(combo), ItemDataRole::DATA);
174 
175  // expectances
176  EXPECT_EQ(spyRemove.count(), 0);
177  EXPECT_EQ(spyInsert.count(), 0);
178  EXPECT_EQ(spyData.count(), 1);
179 
180  // what signal reports
181  QList<QVariant> arguments = spyData.takeFirst();
182  QModelIndex dataIndex = viewModel.index(0, 1);
183  EXPECT_EQ(arguments.size(), 3); // QModelIndex left, QModelIndex right, QVector<int> roles
184  EXPECT_EQ(arguments.at(0).value<QModelIndex>(), dataIndex);
185  EXPECT_EQ(arguments.at(1).value<QModelIndex>(), dataIndex);
186  QVector<int> expectedRoles = {Qt::DisplayRole, Qt::EditRole};
187  EXPECT_EQ(arguments.at(2).value<QVector<int>>(), expectedRoles);
188 
189  // same layout
190  groupIndex = viewModel.index(0, 0);
191  EXPECT_EQ(viewModel.sessionItemFromIndex(groupIndex), groupItem);
192  EXPECT_EQ(viewModel.columnCount(groupIndex), 2);
193  EXPECT_EQ(viewModel.rowCount(groupIndex), 3); // Cylinder, Sphere, Anysopyramid
194 }
195 
196 //! ShapeGroup item in PropertyViewModel.
197 
198 TEST_F(ToyItemsShapeGroupTest, inPropertyViewModelContext)
199 {
200  ToyItems::SampleModel model;
201  auto parent = model.insertItem<SessionItem>();
202  parent->registerTag(
204 
205  auto groupItem = model.insertItem<ToyItems::ShapeGroupItem>(parent, "property_tag");
206  ASSERT_TRUE(groupItem != nullptr);
207 
208  // constructing viewModel from sample model
209  PropertyViewModel viewModel(&model);
210  viewModel.setRootSessionItem(parent);
211 
212  // root item should have one child, item looking at our groupItem
213  EXPECT_EQ(viewModel.rowCount(), 1);
214  EXPECT_EQ(viewModel.columnCount(), 2);
215 
216  // accessing to viewItem representing groupItem
217  QModelIndex groupIndex = viewModel.index(0, 0);
218  EXPECT_EQ(viewModel.sessionItemFromIndex(groupIndex), groupItem);
219 
220  // There is only one row under groupItem, representing radius of Sphere
221  EXPECT_EQ(viewModel.columnCount(groupIndex), 2);
222  EXPECT_EQ(viewModel.rowCount(groupIndex), 1); // Radius of sphere
223 
224  // ViewLabelItem and ViewDataItem should look at propertyItem corresponding to sphere
225  {
226  QModelIndex radiusLabelIndex = viewModel.index(0, 0, groupIndex);
227  QModelIndex radiusValueIndex = viewModel.index(0, 1, groupIndex);
228  auto radiusLabelItem =
229  dynamic_cast<ViewLabelItem*>(viewModel.itemFromIndex(radiusLabelIndex));
230  ASSERT_TRUE(radiusLabelItem != nullptr);
231  auto radiusPropertyItem = groupItem->currentItem()->getItem(ToyItems::SphereItem::P_RADIUS);
232  EXPECT_EQ(radiusLabelItem->item(), radiusPropertyItem);
233  auto radiusValueItem =
234  dynamic_cast<ViewDataItem*>(viewModel.itemFromIndex(radiusValueIndex));
235  ASSERT_TRUE(radiusValueItem != nullptr);
236  EXPECT_EQ(radiusValueItem->item(), radiusPropertyItem);
237  }
238 
239  // setting up signal spy
240  QSignalSpy spyRemove(&viewModel, &DefaultViewModel::rowsRemoved);
241  QSignalSpy spyInsert(&viewModel, &DefaultViewModel::rowsInserted);
242  QSignalSpy spyData(&viewModel, &DefaultViewModel::dataChanged);
243 
244  // changing the data (now GroupItem's current item changed from Sphere to Cylinder
245  ComboProperty combo = model.data(groupItem, ItemDataRole::DATA).value<ComboProperty>();
246  combo.setCurrentIndex(0);
247  model.setData(groupItem, QVariant::fromValue(combo), ItemDataRole::DATA);
248 
249  EXPECT_EQ(viewModel.columnCount(groupIndex), 2);
250  EXPECT_EQ(viewModel.rowCount(groupIndex), 2); // Radius and Height of cylinder
251 
252  // Checking ViewLabelItem and ViewDataItem corresponding to Cylinder's radius
253  {
254  QModelIndex radiusLabelIndex = viewModel.index(0, 0, groupIndex);
255  QModelIndex radiusValueIndex = viewModel.index(0, 1, groupIndex);
256  auto radiusLabelItem =
257  dynamic_cast<ViewLabelItem*>(viewModel.itemFromIndex(radiusLabelIndex));
258  ASSERT_TRUE(radiusLabelItem != nullptr);
259  auto radiusPropertyItem =
260  groupItem->currentItem()->getItem(ToyItems::CylinderItem::P_RADIUS);
261  EXPECT_EQ(radiusLabelItem->item(), radiusPropertyItem);
262  auto radiusValueItem =
263  dynamic_cast<ViewDataItem*>(viewModel.itemFromIndex(radiusValueIndex));
264  ASSERT_TRUE(radiusValueItem != nullptr);
265  EXPECT_EQ(radiusValueItem->item(), radiusPropertyItem);
266  }
267 
268  // Checking ViewLabelItem and ViewDataItem corresponding to Cylinder's height
269  {
270  QModelIndex heightLabelIndex = viewModel.index(1, 0, groupIndex);
271  QModelIndex heightValueIndex = viewModel.index(1, 1, groupIndex);
272  auto heightLabelItem =
273  dynamic_cast<ViewLabelItem*>(viewModel.itemFromIndex(heightLabelIndex));
274  ASSERT_TRUE(heightLabelItem != nullptr);
275  auto heightPropertyItem =
276  groupItem->currentItem()->getItem(ToyItems::CylinderItem::P_HEIGHT);
277  EXPECT_EQ(heightLabelItem->item(), heightPropertyItem);
278  auto heightValueItem =
279  dynamic_cast<ViewDataItem*>(viewModel.itemFromIndex(heightValueIndex));
280  ASSERT_TRUE(heightPropertyItem != nullptr);
281  EXPECT_EQ(heightValueItem->item(), heightPropertyItem);
282  }
283 
284  // expectances
285  EXPECT_EQ(spyRemove.count(), 1);
286  EXPECT_EQ(spyInsert.count(), 2);
287  EXPECT_EQ(spyData.count(), 1);
288 }
Custom property to define list of string values with multiple selections.
Definition: comboproperty.h:27
std::vector< std::string > values() const
void setCurrentIndex(int index)
View model to show content of SessionModel in Qt widgets: two column tree with label/data.
const SessionItem * currentItem() const
Returns currently selected item.
Definition: groupitem.cpp:41
void setCurrentType(const std::string &model_type)
Sets item corresponding to given model type.
Definition: groupitem.cpp:58
std::string currentType() const
Definition: groupitem.cpp:51
int currentIndex() const
Definition: groupitem.cpp:34
View model to show content of SessionModel in Qt widgets.
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.
T data(int role=ItemDataRole::DATA) const
Returns data of given type T for given role.
Definition: sessionitem.h:148
std::vector< SessionItem * > children() const
Returns vector of children formed from all chidlren from all tags.
T property(const std::string &tag) const
Returns data stored in property item.
Definition: sessionitem.h:181
model_type modelType() const
Returns item's model type.
Definition: sessionitem.cpp:80
void setProperty(const std::string &tag, const T &value)
Sets value to property item.
Definition: sessionitem.h:190
bool setData(SessionItem *item, const Variant &value, int role)
Sets the data for given item.
T * insertItem(SessionItem *parent=nullptr, const TagRow &tagrow={})
Inserts item into given parent under given tagrow.
Definition: sessionmodel.h:104
Variant data(SessionItem *item, int role) const
Returns the data for given item and role.
static TagInfo propertyTag(std::string name, std::string model_type)
Constructs tag intended for single property.
Definition: taginfo.cpp:40
Represents data role of SessionItem in any cell of Qt's trees and tables.
QVariant data(int role) const override
Returns the data for given role according to Qt::ItemDataRole namespace definitions.
Represents display name of SessionItem in any cell of Qt's trees and tables.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
int rowCount(const QModelIndex &parent=QModelIndex()) const override
int columnCount(const QModelIndex &parent=QModelIndex()) const override
ViewItem * itemFromIndex(const QModelIndex &index) const
Returns a pointer to the RefViewItem associated with the given index.
void setRootSessionItem(SessionItem *item)
Definition: viewmodel.cpp:52
SessionItem * sessionItemFromIndex(const QModelIndex &index) const
Definition: viewmodel.cpp:59
Tests of toy ShapeGroup in the context of model and viewmodel.
static const std::string P_HEIGHT
Definition: toyitems.h:91
static const std::string P_RADIUS
Definition: toyitems.h:90
Represents a group item holding a collection of shapes.
Definition: toyitems.h:119
static const std::string P_RADIUS
Definition: toyitems.h:100
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
const int DATA
main data role
Definition: mvvm_types.h:30
materialitems.h Collection of materials to populate MaterialModel.
const ModelView::model_type SphereItemType
Definition: toyitems.h:36
const ModelView::model_type CylinderItemType
Definition: toyitems.h:35
const ModelView::model_type ShapeGroupItemType
Definition: toyitems.h:39
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
TEST_F(ToyItemsShapeGroupTest, initialState)
Toy multilayer as produced bo toy SampleModel.
Defines class CLASS?