BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
viewmodelutils.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/testviewmodel/viewmodelutils.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"
16 #include "mvvm/model/mvvm_types.h"
17 #include "mvvm/model/sessionitem.h"
23 #include <QColor>
24 #include <QModelIndexList>
25 #include <QStandardItemModel>
26 
27 namespace {
28 QList<QStandardItem*> get_items(std::vector<int> data)
29 {
30  QList<QStandardItem*> result;
31 
32  for (auto x : data)
33  result.append(new QStandardItem(QString::number(x)));
34 
35  return result;
36 }
37 } // namespace
38 
39 using namespace ModelView;
40 
41 class ViewModelUtilsTest : public ::testing::Test {
42 public:
44 };
45 
47 
49 {
50  QStandardItemModel model;
51 
52  model.setColumnCount(2);
53  QStandardItem* parentItem = model.invisibleRootItem();
54 
55  auto row1 = get_items({1, 2});
56  parentItem->appendRow(row1);
57  row1.at(0)->appendRow(get_items({3, 4}));
58 
59  auto row2 = get_items({10, 20});
60  parentItem->appendRow(row2);
61 
62  std::vector<int> expected = {1, 2, 3, 4, 10, 20};
63  std::vector<int> result;
64 
65  Utils::iterate_model(&model, QModelIndex(), [&](const QModelIndex& index) {
66  auto item = model.itemFromIndex(index);
67  result.push_back(item->data(Qt::EditRole).value<int>());
68  });
69 
70  EXPECT_EQ(result, expected);
71 }
72 
73 //! Translation of item role to Qt roles.
74 
76 {
77  // DATA role of SessionItem should be translated to two Qt roles (edit and display)
79  QVector<int> expected = {Qt::DisplayRole, Qt::EditRole};
80  EXPECT_EQ(roles, expected);
81 
82  // APPEARANCE roles of SessionItem on Qt site means color
84 #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
85  expected = {Qt::ForegroundRole};
86 #else
87  expected = {Qt::TextColorRole};
88 #endif
89  EXPECT_EQ(roles, expected);
90 
91  // tooltip role
93  expected = {Qt::ToolTipRole};
94  EXPECT_EQ(roles, expected);
95 }
96 
97 //! Testing color role of item.
98 
99 TEST_F(ViewModelUtilsTest, itemTextColorRole)
100 {
101  SessionItem item("Something");
102 
103  // no color defined for item by default
104  auto variant = Utils::TextColorRole(item);
105  EXPECT_FALSE(variant.isValid());
106 
107  item.setEnabled(false);
108  variant = Utils::TextColorRole(item);
109  EXPECT_EQ(variant.value<QColor>(), QColor(Qt::gray));
110 }
111 
112 //! Testing check state role of item.
113 
114 TEST_F(ViewModelUtilsTest, itemCheckStateRole)
115 {
116  SessionItem item("Something");
117 
118  // no color defined for item by default
119  auto variant = Utils::CheckStateRole(item);
120  EXPECT_FALSE(variant.isValid());
121 
122  item.setData(QVariant::fromValue(true));
123  EXPECT_EQ(Utils::CheckStateRole(item).value<int>(), Qt::Checked);
124 
125  item.setData(QVariant::fromValue(false));
126  EXPECT_EQ(Utils::CheckStateRole(item).value<int>(), Qt::Unchecked);
127 }
128 
129 //! Testing decoration role of the item.
130 
131 TEST_F(ViewModelUtilsTest, itemDecorationRole)
132 {
133  SessionItem item("Something");
134 
135  // no color defined for item by default
136  auto variant = Utils::DecorationRole(item);
137  EXPECT_FALSE(variant.isValid());
138 
139  QColor expected(Qt::green);
140  item.setData(expected);
141  EXPECT_EQ(Utils::DecorationRole(item).value<QColor>(), expected);
142 }
143 
144 //! Testing tooltip role of the item.
145 
146 TEST_F(ViewModelUtilsTest, itemToolTipRole)
147 {
148  SessionItem item("Something");
149 
150  auto variant = Utils::ToolTipRole(item);
151  EXPECT_FALSE(variant.isValid());
152 
153  item.setToolTip("abc");
154  EXPECT_EQ(Utils::ToolTipRole(item).toString(), QString("abc"));
155 }
156 
157 //! Check ItemsFromIndex in PropertyTableViewModel context.
158 //! ViewItem with its three property x, y, z forms one row. All corresponding
159 //! indices of (x,y,z) should give us pointers to VectorItem's properties.
160 
161 TEST_F(ViewModelUtilsTest, itemsFromIndex)
162 {
163  // creating VectorItem and viewModel to see it as a table
164  SessionModel model;
165  auto parent = model.insertItem<VectorItem>();
166  PropertyTableViewModel viewModel(&model);
167 
168  // it's a table with one row and x,y,z columns
169  EXPECT_EQ(viewModel.rowCount(), 1);
170  EXPECT_EQ(viewModel.columnCount(), 3);
171 
172  // empty index list doesn't lead to SessionItem's
173  QModelIndexList index_list;
174  EXPECT_EQ(Utils::ItemsFromIndex(index_list).size(), 0);
175 
176  // index list populated with column of properties
177  index_list.push_back(viewModel.index(0, 0));
178  index_list.push_back(viewModel.index(0, 1));
179  index_list.push_back(viewModel.index(0, 2));
180 
181  std::vector<SessionItem*> expected = {parent->getItem(VectorItem::P_X),
182  parent->getItem(VectorItem::P_Y),
183  parent->getItem(VectorItem::P_Z)};
184  EXPECT_EQ(Utils::ItemsFromIndex(index_list), expected);
185  EXPECT_EQ(Utils::UniqueItemsFromIndex(index_list), expected);
186 }
187 
188 //! Check UniqueItemsFromIndex for artificially constructed viewmodel.
189 
191 {
192  SessionItem item1;
193  item1.setData(42, ItemDataRole::DATA);
194  SessionItem item2;
195  item2.setData(42, ItemDataRole::DATA);
196 
197  ViewModelBase viewmodel;
198  std::vector<std::unique_ptr<ViewItem>> items;
199  items.emplace_back(std::make_unique<ViewLabelItem>(&item1));
200  items.emplace_back(std::make_unique<ViewLabelItem>(&item2));
201  items.emplace_back(std::make_unique<ViewDataItem>(&item1));
202  items.emplace_back(std::make_unique<ViewDataItem>(&item2));
203  viewmodel.insertRow(viewmodel.rootItem(), 0, std::move(items));
204 
205  QModelIndexList index_list = {viewmodel.index(0, 0), viewmodel.index(0, 1),
206  viewmodel.index(0, 2), viewmodel.index(0, 3)};
207 
208  EXPECT_EQ(Utils::ItemsFromIndex(index_list),
209  std::vector<SessionItem*>({&item1, &item2, &item1, &item2}));
210  EXPECT_EQ(Utils::UniqueItemsFromIndex(index_list), std::vector<SessionItem*>({&item1, &item2}));
211 }
212 
213 //! Check ParentItemsFromIndex in PropertyTableViewModel context.
214 //! ViewItem with its three property x, y, z forms one row. All corresponding
215 //! indices of (x,y,z) should give us pointer to VectorItem.
216 
217 TEST_F(ViewModelUtilsTest, parentItemsFromIndex)
218 {
219  // creating VectorItem and viewModel to see it as a table
220  SessionModel model;
221  auto parent = model.insertItem<VectorItem>();
222  PropertyTableViewModel viewModel(&model);
223 
224  // it's a table with one row and x,y,z columns
225  EXPECT_EQ(viewModel.rowCount(), 1);
226  EXPECT_EQ(viewModel.columnCount(), 3);
227 
228  // empty index list doesn't lead to SessionItem's
229  QModelIndexList index_list;
230  EXPECT_EQ(Utils::ParentItemsFromIndex(index_list).size(), 0);
231 
232  std::vector<SessionItem*> expected = {parent};
233 
234  // one cell in a list should give us pointer to original VectorItem
235  index_list.push_back(viewModel.index(0, 1));
236  EXPECT_EQ(Utils::ParentItemsFromIndex(index_list), expected);
237 
238  index_list.clear();
239  index_list.push_back(viewModel.index(0, 1));
240  EXPECT_EQ(Utils::ParentItemsFromIndex(index_list), expected);
241 
242  index_list.clear();
243  index_list.push_back(viewModel.index(0, 2));
244  EXPECT_EQ(Utils::ParentItemsFromIndex(index_list), expected);
245 
246  // tthree cells (x, y, z) in a list should give us pointer to original VectorItem
247  index_list.clear();
248  index_list.push_back(viewModel.index(0, 0));
249  index_list.push_back(viewModel.index(0, 1));
250  index_list.push_back(viewModel.index(0, 2));
251  EXPECT_EQ(Utils::ParentItemsFromIndex(index_list), expected);
252 }
View model to show content of SessionModel in Qt widgets: all item properties as a table row.
The main object representing an editable/displayable/serializable entity.
Definition: sessionitem.h:38
SessionItem * setEnabled(bool value)
Sets enabled flag to given value (fluent interface).
SessionItem * setToolTip(const std::string &tooltip)
Sets item tooltip (fluent interface).
bool setData(const T &value, int role=ItemDataRole::DATA, bool direct=false)
Sets data for a given role.
Definition: sessionitem.h:141
Main class to hold hierarchy of SessionItem objects.
Definition: sessionmodel.h:37
T * insertItem(SessionItem *parent=nullptr, const TagRow &tagrow={})
Inserts item into given parent under given tagrow.
Definition: sessionmodel.h:104
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_Z
Definition: vectoritem.h:28
static const std::string P_Y
Definition: vectoritem.h:27
Base class for all view models to show content of SessionModel in Qt views.
Definition: viewmodelbase.h:31
ViewItem * rootItem() const
Returns a pointer to invisible root item.
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
void insertRow(ViewItem *parent, int row, std::vector< std::unique_ptr< ViewItem >> items)
Insert a row of items at index 'row' to given parent.
Defines class CLASS?
Defines class CLASS?
void iterate(const QModelIndex &index, const QAbstractItemModel *model, const std::function< void(const QModelIndex &)> &fun)
Iterates through all model indices and calls user function.
Definition: ModelUtils.cpp:33
const int TOOLTIP
tooltip for item's data
Definition: mvvm_types.h:34
const int DATA
main data role
Definition: mvvm_types.h:30
const int APPEARANCE
appearance flag
Definition: mvvm_types.h:32
MVVM_VIEWMODEL_EXPORT QVariant TextColorRole(const SessionItem &item)
Returns text color for given item.
MVVM_VIEWMODEL_EXPORT QVariant DecorationRole(const SessionItem &item)
Returns decoration role for given item.
MVVM_VIEWMODEL_EXPORT QVariant ToolTipRole(const SessionItem &item)
Returns tooltip role for given item.
MVVM_VIEWMODEL_EXPORT QVector< int > ItemRoleToQtRole(int role)
Returns vector of Qt roles corresponding to given ItemDataRole.
MVVM_VIEWMODEL_EXPORT std::vector< SessionItem * > ItemsFromIndex(const QModelIndexList &index_list)
Returns vector of underlying SessionItem's for given index list.
MVVM_VIEWMODEL_EXPORT void iterate_model(const QAbstractItemModel *model, const QModelIndex &parent, const std::function< void(const QModelIndex &child)> &fun)
Iterates through QAbstractItem model.
MVVM_VIEWMODEL_EXPORT QVariant CheckStateRole(const SessionItem &item)
Returns check state role of given item.
MVVM_VIEWMODEL_EXPORT std::vector< SessionItem * > UniqueItemsFromIndex(const QModelIndexList &index_list)
Returns vector of underlying SessionItem's for given index list. Removes repetitions.
MVVM_VIEWMODEL_EXPORT std::vector< SessionItem * > ParentItemsFromIndex(const QModelIndexList &index_list)
Returns vector of parent items from given index list.
materialitems.h Collection of materials to populate MaterialModel.
std::string toString(PyObject *obj)
Converts PyObject into string, if possible, or throws exception.
Definition: PyUtils.cpp:24
QVariant ToolTipRole(const SessionItem &item, int ncol=0)
Returns tooltip for given item.
QVariant ForegroundRole(const SessionItem &item)
Returns text color for given item.
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
TEST_F(ViewModelUtilsTest, iterate)