1 /***************************************************************************
2                          testqgscategorizedrendererwidget.cpp
3                          ---------------------------
4     begin                : January 2019
5     copyright            : (C) 2019 by Nyall Dawson
6     email                : nyall dot dawson at gmail dot com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include "qgstest.h"
19 
20 #include "qgscategorizedsymbolrenderer.h"
21 #include "qgscategorizedsymbolrendererwidget.h"
22 #include "qgsapplication.h"
23 #include "qgsvectorlayer.h"
24 #include "qgsfeature.h"
25 #include "qgsvectordataprovider.h"
26 #include "qgssymbol.h"
27 
28 #include <memory>
29 
30 class TestQgsCategorizedRendererWidget : public QObject
31 {
32     Q_OBJECT
33   private slots:
34     void initTestCase();// will be called before the first testfunction is executed.
35     void cleanupTestCase();// will be called after the last testfunction was executed.
36     void init();// will be called before each testfunction is executed.
37     void cleanup();// will be called after every testfunction.
38     void testAddMissingCategories();
39     void merge();
40     void model();
41 
42 };
43 
initTestCase()44 void TestQgsCategorizedRendererWidget::initTestCase()
45 {
46   QgsApplication::init();
47   QgsApplication::initQgis();
48 }
49 
cleanupTestCase()50 void TestQgsCategorizedRendererWidget::cleanupTestCase()
51 {
52   QgsApplication::exitQgis();
53 }
54 
init()55 void TestQgsCategorizedRendererWidget::init()
56 {
57 }
58 
cleanup()59 void TestQgsCategorizedRendererWidget::cleanup()
60 {
61 }
62 
testAddMissingCategories()63 void TestQgsCategorizedRendererWidget::testAddMissingCategories()
64 {
65   std::unique_ptr< QgsVectorLayer > vl = std::make_unique< QgsVectorLayer >( "Point?crs=EPSG:4326&field=idx:integer&field=name:string", QString(), QStringLiteral( "memory" ) );
66   QVERIFY( vl->isValid() );
67 
68   QgsFeature f;
69   f.setAttributes( QgsAttributes() << 1 << "a" );
70   QVERIFY( vl->dataProvider()->addFeature( f ) );
71   f.setAttributes( QgsAttributes() << 2 << "b" );
72   vl->dataProvider()->addFeature( f );
73   f.setAttributes( QgsAttributes() << 3 << "c" );
74   vl->dataProvider()->addFeature( f );
75   f.setAttributes( QgsAttributes() << 4 << "d" );
76   vl->dataProvider()->addFeature( f );
77 
78   QgsCategorizedSymbolRenderer *renderer = new QgsCategorizedSymbolRenderer( QStringLiteral( "name" ) );
79   vl->setRenderer( renderer );
80 
81   std::unique_ptr< QgsCategorizedSymbolRendererWidget > widget = std::make_unique< QgsCategorizedSymbolRendererWidget >( vl.get(), nullptr, renderer );
82   QVERIFY( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().isEmpty() );
83 
84   widget->addCategories();
85   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().count(), 5 );
86   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 0 ).value().toString(), QStringLiteral( "a" ) );
87   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 1 ).value().toString(), QStringLiteral( "b" ) );
88   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 2 ).value().toString(), QStringLiteral( "c" ) );
89   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 3 ).value().toString(), QStringLiteral( "d" ) );
90   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 4 ).value().toString(), QString() );
91 
92   // add a new value
93   f.setAttributes( QgsAttributes() << 4 << "e" );
94   vl->dataProvider()->addFeature( f );
95 
96   widget->addCategories();
97   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().count(), 6 );
98   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 5 ).value().toString(), QStringLiteral( "e" ) );
99 
100   // test with a value list category
101   widget.reset();
102   renderer = new QgsCategorizedSymbolRenderer( QStringLiteral( "name" ) );
103   renderer->addCategory( QgsRendererCategory( QStringLiteral( "b" ), QgsSymbol::defaultSymbol( QgsWkbTypes::PointGeometry ), QString() ) );
104   renderer->addCategory( QgsRendererCategory( QVariantList() << QStringLiteral( "a" ) << QStringLiteral( "c" ), QgsSymbol::defaultSymbol( QgsWkbTypes::PointGeometry ), QString() ) );
105 
106   vl->setRenderer( renderer );
107 
108   widget = std::make_unique< QgsCategorizedSymbolRendererWidget >( vl.get(), nullptr, renderer );
109   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().count(), 2 );
110 
111   // values inside list categories should not be re-added
112   widget->addCategories();
113   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().count(), 5 );
114   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 0 ).value().toString(), QStringLiteral( "b" ) );
115   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 1 ).value().toList().at( 0 ).toString(), QStringLiteral( "a" ) );
116   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 1 ).value().toList().at( 1 ).toString(), QStringLiteral( "c" ) );
117   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 2 ).value().toString(), QStringLiteral( "d" ) );
118   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 3 ).value().toString(), QStringLiteral( "e" ) );
119   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 4 ).value().toString(), QString() );
120 }
121 
merge()122 void TestQgsCategorizedRendererWidget::merge()
123 {
124   // test merging categories
125 
126   std::unique_ptr< QgsVectorLayer > vl = std::make_unique< QgsVectorLayer >( "Point?crs=EPSG:4326&field=idx:integer&field=name:string", QString(), QStringLiteral( "memory" ) );
127   QVERIFY( vl->isValid() );
128 
129   QgsFeature f;
130   f.setAttributes( QgsAttributes() << 1 << "a" );
131   QVERIFY( vl->dataProvider()->addFeature( f ) );
132   f.setAttributes( QgsAttributes() << 2 << "b" );
133   vl->dataProvider()->addFeature( f );
134   f.setAttributes( QgsAttributes() << 3 << "c" );
135   vl->dataProvider()->addFeature( f );
136   f.setAttributes( QgsAttributes() << 4 << "d" );
137   vl->dataProvider()->addFeature( f );
138   f.setAttributes( QgsAttributes() << 5 << "e" );
139   vl->dataProvider()->addFeature( f );
140 
141   QgsCategorizedSymbolRenderer *renderer = new QgsCategorizedSymbolRenderer( QStringLiteral( "name" ) );
142   vl->setRenderer( renderer );
143 
144   std::unique_ptr< QgsCategorizedSymbolRendererWidget > widget = std::make_unique< QgsCategorizedSymbolRendererWidget >( vl.get(), nullptr, renderer );
145   widget->addCategories();
146   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().count(), 6 );
147   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 0 ).value().toString(), QStringLiteral( "a" ) );
148   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 1 ).value().toString(), QStringLiteral( "b" ) );
149   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 2 ).value().toString(), QStringLiteral( "c" ) );
150   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 3 ).value().toString(), QStringLiteral( "d" ) );
151   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 4 ).value().toString(), QStringLiteral( "e" ) );
152   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 5 ).value().toString(), QString() );
153 
154   // no selection, should have no effect
155   widget->mergeSelectedCategories();
156   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().count(), 6 );
157 
158   widget->viewCategories->selectionModel()->select( widget->viewCategories->model()->index( 1, 0 ), QItemSelectionModel::Select | QItemSelectionModel::Rows );
159   // one selection, should have no effect
160   widget->mergeSelectedCategories();
161   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().count(), 6 );
162 
163   widget->viewCategories->selectionModel()->select( widget->viewCategories->model()->index( 3, 0 ), QItemSelectionModel::Select | QItemSelectionModel::Rows );
164   widget->viewCategories->selectionModel()->select( widget->viewCategories->model()->index( 4, 0 ), QItemSelectionModel::Select | QItemSelectionModel::Rows );
165   widget->mergeSelectedCategories();
166   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().count(), 4 );
167 
168   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 0 ).value().toString(), QStringLiteral( "a" ) );
169   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 1 ).value().toList().at( 0 ).toString(), QStringLiteral( "b" ) );
170   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 1 ).value().toList().at( 1 ).toString(), QStringLiteral( "d" ) );
171   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 1 ).value().toList().at( 2 ).toString(), QStringLiteral( "e" ) );
172   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 2 ).value().toString(), QStringLiteral( "c" ) );
173   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 3 ).value().toString(), QString() );
174 
175   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 0 ).label(), QStringLiteral( "a" ) );
176   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 1 ).label(), QStringLiteral( "b,d,e" ) );
177   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 2 ).label(), QStringLiteral( "c" ) );
178   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 3 ).label(), QString() );
179 
180   // selection should always "merge into" first selected item
181   widget->viewCategories->selectionModel()->select( widget->viewCategories->model()->index( 2, 0 ), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
182   widget->viewCategories->selectionModel()->select( widget->viewCategories->model()->index( 0, 0 ), QItemSelectionModel::Select | QItemSelectionModel::Rows );
183   widget->mergeSelectedCategories();
184   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().count(), 3 );
185 
186   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 0 ).value().toList().at( 0 ).toString(), QStringLiteral( "b" ) );
187   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 0 ).value().toList().at( 1 ).toString(), QStringLiteral( "d" ) );
188   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 0 ).value().toList().at( 2 ).toString(), QStringLiteral( "e" ) );
189   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 1 ).value().toList().at( 0 ).toString(), QStringLiteral( "c" ) );
190   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 1 ).value().toList().at( 1 ).toString(), QStringLiteral( "a" ) );
191   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 2 ).value().toString(), QString() );
192 
193   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 0 ).label(), QStringLiteral( "b,d,e" ) );
194   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 1 ).label(), QStringLiteral( "c,a" ) );
195   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 2 ).label(), QString() );
196 
197   // merging categories which are already lists
198   widget->viewCategories->selectionModel()->select( widget->viewCategories->model()->index( 0, 0 ), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
199   widget->viewCategories->selectionModel()->select( widget->viewCategories->model()->index( 1, 0 ), QItemSelectionModel::Select | QItemSelectionModel::Rows );
200   //"" entry should be ignored
201   widget->viewCategories->selectionModel()->select( widget->viewCategories->model()->index( 2, 0 ), QItemSelectionModel::Select | QItemSelectionModel::Rows );
202   widget->mergeSelectedCategories();
203 
204   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().count(), 2 );
205 
206   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 0 ).value().toList().at( 0 ).toString(), QStringLiteral( "b" ) );
207   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 0 ).value().toList().at( 1 ).toString(), QStringLiteral( "d" ) );
208   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 0 ).value().toList().at( 2 ).toString(), QStringLiteral( "e" ) );
209   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 0 ).value().toList().at( 3 ).toString(), QStringLiteral( "c" ) );
210   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 0 ).value().toList().at( 4 ).toString(), QStringLiteral( "a" ) );
211   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 1 ).value().toString(), QString() );
212 
213   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 0 ).label(), QStringLiteral( "b,d,e,c,a" ) );
214   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 1 ).label(), QString() );
215 
216   widget->viewCategories->selectionModel()->clearSelection();
217   // unmerge
218   widget->unmergeSelectedCategories();
219   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().count(), 2 );
220   // not a list
221   widget->viewCategories->selectionModel()->select( widget->viewCategories->model()->index( 1, 0 ), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
222   widget->unmergeSelectedCategories();
223   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().count(), 2 );
224   // list
225   widget->viewCategories->selectionModel()->select( widget->viewCategories->model()->index( 0, 0 ), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
226   widget->unmergeSelectedCategories();
227 
228   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().count(), 6 );
229   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 0 ).value().toString(), QStringLiteral( "b" ) );
230   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 1 ).value().toString(), QString() );
231   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 2 ).value().toString(), QStringLiteral( "d" ) );
232   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 3 ).value().toString(), QStringLiteral( "e" ) );
233   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 4 ).value().toString(), QStringLiteral( "c" ) );
234   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 5 ).value().toString(), QStringLiteral( "a" ) );
235   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 0 ).label(), QStringLiteral( "b" ) );
236   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 1 ).label(), QString() );
237   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 2 ).label(), QStringLiteral( "d" ) );
238   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 3 ).label(), QStringLiteral( "e" ) );
239   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 4 ).label(), QStringLiteral( "c" ) );
240   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 5 ).label(), QStringLiteral( "a" ) );
241 
242   widget->viewCategories->selectionModel()->select( widget->viewCategories->model()->index( 2, 0 ), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
243   widget->viewCategories->selectionModel()->select( widget->viewCategories->model()->index( 3, 0 ), QItemSelectionModel::Select | QItemSelectionModel::Rows );
244   widget->mergeSelectedCategories();
245   widget->viewCategories->selectionModel()->select( widget->viewCategories->model()->index( 3, 0 ), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
246   widget->viewCategories->selectionModel()->select( widget->viewCategories->model()->index( 4, 0 ), QItemSelectionModel::Select | QItemSelectionModel::Rows );
247   widget->mergeSelectedCategories();
248   widget->viewCategories->selectionModel()->select( widget->viewCategories->model()->index( 0, 0 ), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
249   widget->viewCategories->selectionModel()->select( widget->viewCategories->model()->index( 1, 0 ), QItemSelectionModel::Select | QItemSelectionModel::Rows );
250   widget->viewCategories->selectionModel()->select( widget->viewCategories->model()->index( 2, 0 ), QItemSelectionModel::Select | QItemSelectionModel::Rows );
251   widget->viewCategories->selectionModel()->select( widget->viewCategories->model()->index( 3, 0 ), QItemSelectionModel::Select | QItemSelectionModel::Rows );
252   widget->unmergeSelectedCategories();
253   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().count(), 6 );
254   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 0 ).value().toString(), QStringLiteral( "b" ) );
255   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 1 ).value().toString(), QString() );
256   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 2 ).value().toString(), QStringLiteral( "d" ) );
257   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 3 ).value().toString(), QStringLiteral( "c" ) );
258   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 4 ).value().toString(), QStringLiteral( "e" ) );
259   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 5 ).value().toString(), QStringLiteral( "a" ) );
260   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 0 ).label(), QStringLiteral( "b" ) );
261   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 1 ).label(), QString() );
262   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 2 ).label(), QStringLiteral( "d" ) );
263   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 3 ).label(), QStringLiteral( "c" ) );
264   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 4 ).label(), QStringLiteral( "e" ) );
265   QCOMPARE( static_cast< QgsCategorizedSymbolRenderer * >( widget->renderer() )->categories().at( 5 ).label(), QStringLiteral( "a" ) );
266 }
267 
model()268 void TestQgsCategorizedRendererWidget::model()
269 {
270   std::unique_ptr< QgsVectorLayer > vl = std::make_unique< QgsVectorLayer >( "Point?crs=EPSG:4326&field=idx:integer&field=name:string", QString(), QStringLiteral( "memory" ) );
271   QVERIFY( vl->isValid() );
272 
273   QgsFeature f;
274   f.setAttributes( QgsAttributes() << 1 << "a" );
275   QVERIFY( vl->dataProvider()->addFeature( f ) );
276   f.setAttributes( QgsAttributes() << 2 << "b" );
277   vl->dataProvider()->addFeature( f );
278   f.setAttributes( QgsAttributes() << 3 << "c" );
279   vl->dataProvider()->addFeature( f );
280   f.setAttributes( QgsAttributes() << 4 << "d" );
281   vl->dataProvider()->addFeature( f );
282   f.setAttributes( QgsAttributes() << 5 << "e" );
283   vl->dataProvider()->addFeature( f );
284 
285   QgsCategorizedSymbolRenderer *renderer = new QgsCategorizedSymbolRenderer( QStringLiteral( "name" ) );
286   renderer = new QgsCategorizedSymbolRenderer( QStringLiteral( "name" ) );
287   renderer->addCategory( QgsRendererCategory( QStringLiteral( "b" ), QgsSymbol::defaultSymbol( QgsWkbTypes::PointGeometry ), QStringLiteral( "aa" ) ) );
288   renderer->addCategory( QgsRendererCategory( QVariantList() << QStringLiteral( "a" ) << QStringLiteral( "c" ), QgsSymbol::defaultSymbol( QgsWkbTypes::PointGeometry ), QStringLiteral( "list" ) ) );
289   renderer->addCategory( QgsRendererCategory( QStringLiteral( "d" ), QgsSymbol::defaultSymbol( QgsWkbTypes::PointGeometry ), QStringLiteral( "dd" ), false ) );
290 
291   vl->setRenderer( renderer );
292 
293   std::unique_ptr< QgsCategorizedSymbolRendererWidget > widget = std::make_unique< QgsCategorizedSymbolRendererWidget >( vl.get(), nullptr, renderer );
294   QgsCategorizedSymbolRendererModel *model = widget->mModel;
295   QCOMPARE( model->rowCount(), 3 );
296   QCOMPARE( model->data( model->index( 0, 1 ), Qt::DisplayRole ).toString(), QStringLiteral( "b" ) );
297   QCOMPARE( model->data( model->index( 1, 1 ), Qt::DisplayRole ).toString(), QStringLiteral( "a;c" ) );
298   QCOMPARE( model->data( model->index( 2, 1 ), Qt::DisplayRole ).toString(), QStringLiteral( "d" ) );
299   QCOMPARE( model->data( model->index( 0, 2 ), Qt::DisplayRole ).toString(), QStringLiteral( "aa" ) );
300   QCOMPARE( model->data( model->index( 1, 2 ), Qt::DisplayRole ).toString(), QStringLiteral( "list" ) );
301   QCOMPARE( model->data( model->index( 2, 2 ), Qt::DisplayRole ).toString(), QStringLiteral( "dd" ) );
302 
303   QCOMPARE( model->data( model->index( 0, 0 ), Qt::CheckStateRole ).toInt(), static_cast< int >( Qt::Checked ) );
304   QCOMPARE( model->data( model->index( 1, 0 ), Qt::CheckStateRole ).toInt(), static_cast< int >( Qt::Checked ) );
305   QCOMPARE( model->data( model->index( 2, 0 ), Qt::CheckStateRole ).toInt(), static_cast< int >( Qt::Unchecked ) );
306 }
307 
308 QGSTEST_MAIN( TestQgsCategorizedRendererWidget )
309 #include "testqgscategorizedrendererwidget.moc"
310