test_merge_models.cpp
Go to the documentation of this file.
3 
4 #include <QStandardItemModel>
5 #include <gtest/gtest.h>
6 
7 using namespace moveit_rviz_plugin::utils;
8 
9 void createStandardItems(QStandardItem* parent, int rows, int columns, int depth, int d_rows = 0) {
10  if (depth <= 0 || rows <= 0 || columns <= 0)
11  return;
12 
13  for (int row = 0; row < rows; ++row) {
14  QList<QStandardItem*> items;
15  for (int column = 0; column < columns; ++column)
16  items << new QStandardItem(QString("%2: %0, %1").arg(row).arg(column).arg(depth));
17  parent->appendRow(items);
18  createStandardItems(items.first(), rows + d_rows, columns, depth - 1, d_rows);
19  }
20 }
21 
22 QStandardItemModel* createStandardModel(QObject* parent, int rows, int columns, int depth, int d_rows = 0) {
23  QStandardItemModel* model = new QStandardItemModel(parent);
24  createStandardItems(model->invisibleRootItem(), rows, columns, depth, d_rows);
25  return model;
26 }
27 
28 // tell gtest how to print QVariant
29 ::std::ostream& operator<<(::std::ostream& os, const QVariant& value) {
30  return os << value.toString().toStdString();
31 }
32 
33 // compare structure and content of proxy and source model
34 void checkEquality(const QAbstractItemModel* proxy_model, const QModelIndex& proxy_parent,
35  const QAbstractItemModel* source_model, const QModelIndex& source_parent) {
36  ASSERT_EQ(proxy_model->rowCount(proxy_parent), source_model->rowCount(source_parent));
37  ASSERT_EQ(proxy_model->columnCount(proxy_parent), source_model->columnCount(source_parent));
38 
39  for (int r = proxy_model->rowCount(proxy_parent) - 1; r >= 0; --r) {
40  for (int c = proxy_model->columnCount(proxy_parent) - 1; c >= 0; --c) {
41  QModelIndex proxy_child = proxy_model->index(r, c, proxy_parent);
42  QModelIndex source_child = source_model->index(r, c, source_parent);
43 
44  // validate equality of data
45  if (proxy_child.isValid() && source_child.isValid()) {
46  EXPECT_EQ(proxy_model->data(proxy_child), source_model->data(source_child));
47  EXPECT_EQ(proxy_child.row(), source_child.row());
48  EXPECT_EQ(proxy_child.column(), source_child.column());
49  EXPECT_EQ(proxy_child.internalPointer(), source_child.internalPointer());
50  }
51 
52  // recursively check children
53  checkEquality(proxy_model, proxy_child, source_model, source_child);
54  }
55  }
56 }
57 
58 template <class T>
59 void modifySourceModel(QAbstractItemModel* src, T* proxy, const QModelIndex& src_index) {
60  bool called = false;
61  const char* new_value = "foo";
62 
63  auto con =
64  proxy->connect(proxy, &T::dataChanged,
65  [&called, &src_index, new_value](const QModelIndex& topLeft, const QModelIndex& bottomRight) {
66  EXPECT_EQ(topLeft.row(), src_index.row());
67  EXPECT_EQ(topLeft.column(), src_index.column());
68 
69  EXPECT_EQ(bottomRight.row(), src_index.row());
70  EXPECT_EQ(bottomRight.column(), src_index.column());
71 
72  EXPECT_STREQ(topLeft.data().toString().toLatin1().data(), new_value);
73  called = true;
74  });
75 
76  EXPECT_TRUE(src->setData(src_index, new_value));
77 
78  proxy->disconnect(con);
79  EXPECT_TRUE(called);
80 }
81 
82 TEST(TreeMergeModel, basics) {
84 
85  EXPECT_EQ(tree.parent(QModelIndex()), QModelIndex());
86  EXPECT_EQ(tree.rowCount(), 0);
87  EXPECT_EQ(tree.columnCount(), 0);
88 
89  QAbstractItemModel* m = createStandardModel(&tree, 2, 3, 2);
90  tree.insertModel("M1", m);
91  EXPECT_FALSE(tree.insertModel("M1", m)); // a model may only inserted once
92 
93  EXPECT_EQ(tree.rowCount(), 1);
94  EXPECT_EQ(tree.columnCount(), 3);
95  EXPECT_TRUE(tree.index(0, 0).flags() & Qt::ItemIsSelectable);
96  EXPECT_FALSE(tree.index(0, 1).flags() & Qt::ItemIsSelectable);
97  EXPECT_FALSE(tree.index(1, 0).isValid());
98 
99  QModelIndex idx = tree.index(0, 0);
100  ASSERT_TRUE(idx.isValid());
101  EXPECT_EQ(idx.row(), 0);
102  EXPECT_EQ(idx.column(), 0);
103  EXPECT_EQ(idx.model(), &tree);
104  EXPECT_EQ(idx.internalPointer(), &tree);
105 
106  EXPECT_FALSE(idx.parent().isValid());
107  EXPECT_STREQ(idx.data().toString().toUtf8().data(), "M1");
108 
109  checkEquality(&tree, idx, m, QModelIndex());
110 
111  // add second model
112  m = createStandardModel(&tree, 3, 3, 2);
113  tree.insertModel("M2", m);
114 
115  // modify underlying model before accessing anything else
116  modifySourceModel(m, &tree, m->index(1, 1));
117  modifySourceModel(m, &tree, m->index(0, 2, m->index(1, 0)));
118 
119  EXPECT_EQ(tree.rowCount(), 2);
120  EXPECT_EQ(tree.columnCount(), 3);
121 
122  idx = tree.index(1, 0);
123  ASSERT_TRUE(idx.isValid());
124  EXPECT_EQ(idx.row(), 1);
125  EXPECT_EQ(idx.column(), 0);
126  EXPECT_EQ(idx.model(), &tree);
127  EXPECT_EQ(idx.internalPointer(), &tree);
128 
129  EXPECT_FALSE(idx.parent().isValid());
130  EXPECT_STREQ(idx.data().toString().toUtf8().data(), "M2");
131 
132  checkEquality(&tree, idx, m, QModelIndex());
133 
134  // remove middle, top-level row of second model
135  EXPECT_EQ(tree.rowCount(idx), 3);
136  m->removeRows(1, 1);
137  EXPECT_EQ(tree.rowCount(), 2);
138  EXPECT_EQ(tree.rowCount(idx), 2);
139 
140  // remove first model
141  ASSERT_TRUE(tree.removeModel(0));
142  EXPECT_EQ(tree.rowCount(), 1);
143  checkEquality(&tree, tree.index(0, 0), m, QModelIndex());
144 
145  // remove model by pointer
146  EXPECT_FALSE(tree.removeModel(nullptr));
147  ASSERT_TRUE(tree.removeModel(m));
148  EXPECT_EQ(tree.rowCount(), 0);
149 }
150 
151 TEST(FlatMergeModel, basics) {
152  FlatMergeProxyModel flat;
153 
154  EXPECT_EQ(flat.parent(QModelIndex()), QModelIndex());
155  EXPECT_EQ(flat.rowCount(), 0);
156  EXPECT_EQ(flat.columnCount(), 0);
157 
158  QAbstractItemModel* m1 = createStandardModel(&flat, 2, 3, 2);
159  flat.insertModel(m1);
160  EXPECT_FALSE(flat.insertModel(m1)); // a model may only be inserted once
161 
162  // modify underlying model before accessing anything else
163  modifySourceModel(m1, &flat, m1->index(1, 1));
164  modifySourceModel(m1, &flat, m1->index(0, 2, m1->index(1, 0)));
165 
166  EXPECT_EQ(flat.rowCount(), 2);
167  EXPECT_EQ(flat.columnCount(), 3);
168 
169  QModelIndex idx = flat.index(0, 0);
170  ASSERT_TRUE(idx.isValid());
171  EXPECT_EQ(idx.row(), 0);
172  EXPECT_EQ(idx.column(), 0);
173  EXPECT_EQ(idx.model(), &flat);
174 
175  EXPECT_FALSE(idx.parent().isValid());
176 
177  checkEquality(&flat, QModelIndex(), m1, QModelIndex());
178 
179  // add second model
180  QAbstractItemModel* m2 = createStandardModel(&flat, 3, 3, 1);
181  flat.insertModel(m2);
182 
183  EXPECT_EQ(flat.rowCount(), 2 + 3);
184  EXPECT_EQ(flat.columnCount(), 3);
185  EXPECT_EQ(flat.index(2, 0).data(), m2->index(0, 0).data());
186 
187  EXPECT_EQ(flat.getModel(flat.index(1, 1)), std::make_pair(m1, m1->index(1, 1)));
188  EXPECT_EQ(flat.getModel(flat.index(2, 2)), std::make_pair(m2, m2->index(0, 2)));
189 }
190 
191 class FlatMergeModelRemove : public ::testing::Test
192 {
193 protected:
195  void SetUp() override {
196  flat.insertModel(createStandardModel(&flat, 1, 3, 2));
197  flat.insertModel(createStandardModel(&flat, 2, 3, 2));
198  flat.insertModel(createStandardModel(&flat, 3, 3, 2));
199  }
200 };
201 
203  ASSERT_EQ(flat.rowCount(), 1 + 2 + 3);
204  EXPECT_TRUE(flat.removeRows(0, 1));
205  EXPECT_EQ(flat.rowCount(), 2 + 3);
206 }
207 
209  ASSERT_EQ(flat.rowCount(), 1 + 2 + 3);
210  EXPECT_TRUE(flat.removeRows(0, 2));
211  EXPECT_EQ(flat.rowCount(), 1 + 3);
212 }
213 
215  ASSERT_EQ(flat.rowCount(), 1 + 2 + 3);
216  EXPECT_TRUE(flat.removeRows(0, 3));
217  EXPECT_EQ(flat.rowCount(), 3);
218 }
219 
221  ASSERT_EQ(flat.rowCount(), 1 + 2 + 3);
222  EXPECT_TRUE(flat.removeRows(2, 2));
223  EXPECT_EQ(flat.rowCount(), 1 + 1 + 2);
224 }
checkEquality
void checkEquality(const QAbstractItemModel *proxy_model, const QModelIndex &proxy_parent, const QAbstractItemModel *source_model, const QModelIndex &source_parent)
Definition: test_merge_models.cpp:34
TEST_F
TEST_F(FlatMergeModelRemove, remove1)
Definition: test_merge_models.cpp:202
flat_merge_proxy_model.h
r
r
rows
int rows
operator<<
::std::ostream & operator<<(::std::ostream &os, const QVariant &value)
Definition: test_merge_models.cpp:29
modifySourceModel
void modifySourceModel(QAbstractItemModel *src, T *proxy, const QModelIndex &src_index)
Definition: test_merge_models.cpp:59
TEST
TEST(TreeMergeModel, basics)
Definition: test_merge_models.cpp:82
EXPECT_TRUE
#define EXPECT_TRUE(args)
tree
tree
c
c
createStandardModel
QStandardItemModel * createStandardModel(QObject *parent, int rows, int columns, int depth, int d_rows=0)
Definition: test_merge_models.cpp:22
moveit_rviz_plugin::utils::FlatMergeProxyModel::columnCount
int columnCount(const QModelIndex &parent=QModelIndex()) const override
Definition: flat_merge_proxy_model.cpp:325
moveit_rviz_plugin::utils::FlatMergeProxyModel
Definition: flat_merge_proxy_model.h:116
moveit_rviz_plugin::utils::FlatMergeProxyModel::index
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Definition: flat_merge_proxy_model.cpp:337
value
float value
moveit_rviz_plugin::utils::FlatMergeProxyModel::parent
QModelIndex parent(const QModelIndex &index) const override
Definition: flat_merge_proxy_model.cpp:362
FlatMergeModelRemove::flat
FlatMergeProxyModel flat
Definition: test_merge_models.cpp:194
FlatMergeModelRemove
Definition: test_merge_models.cpp:191
moveit_rviz_plugin::utils::TreeMergeProxyModel
Definition: tree_merge_proxy_model.h:115
moveit_rviz_plugin::utils::FlatMergeProxyModel::rowCount
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Definition: flat_merge_proxy_model.cpp:313
moveit_rviz_plugin::utils::FlatMergeProxyModel::insertModel
bool insertModel(QAbstractItemModel *model, int pos=-1)
insert a new sub model, pos is relative to modelCount()
Definition: flat_merge_proxy_model.cpp:470
tree_merge_proxy_model.h
m
m
moveit_rviz_plugin::utils::FlatMergeProxyModel::getModel
std::pair< QAbstractItemModel *, QModelIndex > getModel(const QModelIndex &index) const
retrieve model corresponding to given index
Definition: flat_merge_proxy_model.cpp:516
FlatMergeModelRemove::SetUp
void SetUp() override
Definition: test_merge_models.cpp:195
createStandardItems
void createStandardItems(QStandardItem *parent, int rows, int columns, int depth, int d_rows=0)
Definition: test_merge_models.cpp:9
os
bool const Stage std::ostream & os
moveit_rviz_plugin::utils
Definition: flat_merge_proxy_model.cpp:74
EXPECT_EQ
#define EXPECT_EQ(a, b)
EXPECT_FALSE
#define EXPECT_FALSE(args)


visualization
Author(s): Robert Haschke
autogenerated on Thu Feb 27 2025 03:39:51