1 /***************************************************************************
2      test_template.cpp
3      --------------------------------------
4     Date                 : Sun Sep 16 12:22:23 AKDT 2007
5     Copyright            : (C) 2007 by Gary E. Sherman
6     Email                : sherman at mrcc dot com
7  ***************************************************************************
8  *                                                                         *
9  *   This program is free software; you can redistribute it and/or modify  *
10  *   it under the terms of the GNU General Public License as published by  *
11  *   the Free Software Foundation; either version 2 of the License, or     *
12  *   (at your option) any later version.                                   *
13  *                                                                         *
14  ***************************************************************************/
15 
16 #include "qgstest.h"
17 #include <QObject>
18 #include <QString>
19 #include <QStringList>
20 #include <QApplication>
21 #include <QFileInfo>
22 #include <QDir>
23 #include <QDesktopServices>
24 
25 //qgis includes...
26 #include <qgsgeometry.h>
27 #include <qgsmaplayer.h>
28 #include <qgsvectordataprovider.h>
29 #include <qgsvectorlayer.h>
30 #include <qgsvectorlayerutils.h>
31 #include "qgsfeatureiterator.h"
32 #include <qgsapplication.h>
33 #include <qgsproviderregistry.h>
34 #include <qgsproject.h>
35 #include <qgssymbol.h>
36 #include <qgssinglesymbolrenderer.h>
37 //qgis test includes
38 #include "qgsrenderchecker.h"
39 
40 class TestSignalReceiver : public QObject
41 {
42     Q_OBJECT
43 
44   public:
TestSignalReceiver()45     TestSignalReceiver()
46       : QObject( nullptr )
47       , featureBlendMode( QPainter::CompositionMode( 0 ) )
48     {}
49     bool rendererChanged =  false ;
50     QPainter::CompositionMode featureBlendMode;
51     double opacity =  1.0 ;
52   public slots:
onRendererChanged()53     void onRendererChanged()
54     {
55       rendererChanged = true;
56     }
onFeatureBlendModeChanged(const QPainter::CompositionMode blendMode)57     void onFeatureBlendModeChanged( const QPainter::CompositionMode blendMode )
58     {
59       featureBlendMode = blendMode;
60     }
onLayerOpacityChanged(double layerOpacity)61     void onLayerOpacityChanged( double layerOpacity )
62     {
63       opacity = layerOpacity;
64     }
65 };
66 
67 /**
68  * \ingroup UnitTests
69  * This is a unit test for the vector layer class.
70  */
71 class TestQgsVectorLayer : public QObject
72 {
73     Q_OBJECT
74   public:
75     TestQgsVectorLayer() = default;
76 
77   private:
78     bool mTestHasError =  false ;
79     QgsMapLayer *mpPointsLayer = nullptr;
80     QgsMapLayer *mpLinesLayer = nullptr;
81     QgsMapLayer *mpPolysLayer = nullptr;
82     QgsVectorLayer *mpNonSpatialLayer = nullptr;
83     QString mTestDataDir;
84     QString mReport;
85 
86 
87   private slots:
88 
89     void initTestCase(); // will be called before the first testfunction is executed.
90     void cleanupTestCase(); // will be called after the last testfunction was executed.
init()91     void init() {} // will be called before each testfunction is executed.
cleanup()92     void cleanup() {} // will be called after every testfunction.
93 
94     void QgsVectorLayerNonSpatialIterator();
95     void QgsVectorLayerGetValues();
96     void QgsVectorLayersetRenderer();
97     void QgsVectorLayersetFeatureBlendMode();
98     void QgsVectorLayersetLayerTransparency();
99     void uniqueValues();
100     void minimumValue();
101     void maximumValue();
102     void isSpatial();
103     void testAddTopologicalPoints();
104     void testCopyPasteFieldConfiguration();
105     void testCopyPasteFieldConfiguration_data();
106 };
107 
initTestCase()108 void TestQgsVectorLayer::initTestCase()
109 {
110   mTestHasError = false;
111   QgsApplication::init();
112   QgsApplication::initQgis();
113   QgsApplication::showSettings();
114 
115   //create some objects that will be used in all tests...
116 
117   //
118   //create a non spatial layer that will be used in all tests...
119   //
120   QString myDataDir( TEST_DATA_DIR ); //defined in CmakeLists.txt
121   mTestDataDir = myDataDir + '/';
122   QString myDbfFileName = mTestDataDir + "nonspatial.dbf";
123   QFileInfo myDbfFileInfo( myDbfFileName );
124   mpNonSpatialLayer = new QgsVectorLayer( myDbfFileInfo.filePath(),
125                                           myDbfFileInfo.completeBaseName(), QStringLiteral( "ogr" ) );
126   // Register the layer with the registry
127   QgsProject::instance()->addMapLayers(
128     QList<QgsMapLayer *>() << mpNonSpatialLayer );
129   //
130   //create a point layer that will be used in all tests...
131   //
132   QString myPointsFileName = mTestDataDir + "points.shp";
133   QFileInfo myPointFileInfo( myPointsFileName );
134   mpPointsLayer = new QgsVectorLayer( myPointFileInfo.filePath(),
135                                       myPointFileInfo.completeBaseName(), QStringLiteral( "ogr" ) );
136   // Register the layer with the registry
137   QgsProject::instance()->addMapLayers(
138     QList<QgsMapLayer *>() << mpPointsLayer );
139 
140   //
141   //create a poly layer that will be used in all tests...
142   //
143   QString myPolysFileName = mTestDataDir + "polys.shp";
144   QFileInfo myPolyFileInfo( myPolysFileName );
145   mpPolysLayer = new QgsVectorLayer( myPolyFileInfo.filePath(),
146                                      myPolyFileInfo.completeBaseName(), QStringLiteral( "ogr" ) );
147   // Register the layer with the registry
148   QgsProject::instance()->addMapLayers(
149     QList<QgsMapLayer *>() << mpPolysLayer );
150 
151 
152   //
153   // Create a line layer that will be used in all tests...
154   //
155   QString myLinesFileName = mTestDataDir + "lines.shp";
156   QFileInfo myLineFileInfo( myLinesFileName );
157   mpLinesLayer = new QgsVectorLayer( myLineFileInfo.filePath(),
158                                      myLineFileInfo.completeBaseName(), QStringLiteral( "ogr" ) );
159   // Register the layer with the registry
160   QgsProject::instance()->addMapLayers(
161     QList<QgsMapLayer *>() << mpLinesLayer );
162 
163   mReport += QLatin1String( "<h1>Vector Renderer Tests</h1>\n" );
164 }
165 
cleanupTestCase()166 void TestQgsVectorLayer::cleanupTestCase()
167 {
168   QString myReportFile = QDir::tempPath() + "/qgistest.html";
169   QFile myFile( myReportFile );
170   if ( myFile.open( QIODevice::WriteOnly | QIODevice::Append ) )
171   {
172     QTextStream myQTextStream( &myFile );
173     myQTextStream << mReport;
174     myFile.close();
175     //QDesktopServices::openUrl( "file:///" + myReportFile );
176   }
177   QgsApplication::exitQgis();
178 }
179 
QgsVectorLayerNonSpatialIterator()180 void TestQgsVectorLayer::QgsVectorLayerNonSpatialIterator()
181 {
182   QgsFeature f;
183   QgsAttributeList myList;
184   myList << 0 << 1 << 2 << 3;
185   int myCount = 0;
186   QgsFeatureIterator fit = mpNonSpatialLayer->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( myList ) );
187   while ( fit.nextFeature( f ) )
188   {
189     qDebug( "Getting non-spatial feature from layer" );
190     myCount++;
191   }
192   QVERIFY( myCount == 3 );
193 }
194 
QgsVectorLayerGetValues()195 void TestQgsVectorLayer::QgsVectorLayerGetValues()
196 {
197   QgsVectorLayer *layer = new QgsVectorLayer( QStringLiteral( "Point?field=col1:real" ), QStringLiteral( "layer" ), QStringLiteral( "memory" ) );
198   QVERIFY( layer->isValid() );
199   QgsFeature f1( layer->dataProvider()->fields(), 1 );
200   f1.setAttribute( QStringLiteral( "col1" ), 1 );
201   QgsFeature f2( layer->dataProvider()->fields(), 2 );
202   f2.setAttribute( QStringLiteral( "col1" ), 2 );
203   QgsFeature f3( layer->dataProvider()->fields(), 3 );
204   f3.setAttribute( QStringLiteral( "col1" ), 3 );
205   QgsFeature f4( layer->dataProvider()->fields(), 4 );
206   f4.setAttribute( QStringLiteral( "col1" ), QVariant() );
207   layer->dataProvider()->addFeatures( QgsFeatureList() << f1 << f2 << f3 << f4 );
208 
209   //make a selection
210   QgsFeatureIds ids;
211   ids << f2.id() << f3.id();
212   layer->selectByIds( ids );
213 
214   bool ok;
215   QList<QVariant> varList = QgsVectorLayerUtils::getValues( layer, QStringLiteral( "col1" ), ok );
216   QVERIFY( ok );
217   QCOMPARE( varList.length(), 4 );
218   std::sort( varList.begin(), varList.end() );
219   QCOMPARE( varList.at( 0 ), QVariant() );
220   QCOMPARE( varList.at( 1 ), QVariant( 1 ) );
221   QCOMPARE( varList.at( 2 ), QVariant( 2 ) );
222   QCOMPARE( varList.at( 3 ), QVariant( 3 ) );
223 
224   //check with selected features
225   varList = QgsVectorLayerUtils::getValues( layer, QStringLiteral( "col1" ), ok, true );
226   QVERIFY( ok );
227   QCOMPARE( varList.length(), 2 );
228   std::sort( varList.begin(), varList.end() );
229   QCOMPARE( varList.at( 0 ), QVariant( 2 ) );
230   QCOMPARE( varList.at( 1 ), QVariant( 3 ) );
231 
232   int nulls = 0;
233   QList<double> doubleList = QgsVectorLayerUtils::getDoubleValues( layer, QStringLiteral( "col1" ), ok, false, &nulls );
234   QVERIFY( ok );
235   QCOMPARE( doubleList.length(), 3 );
236   std::sort( doubleList.begin(), doubleList.end() );
237   QCOMPARE( doubleList.at( 0 ), 1.0 );
238   QCOMPARE( doubleList.at( 1 ), 2.0 );
239   QCOMPARE( doubleList.at( 2 ), 3.0 );
240   QCOMPARE( nulls, 1 );
241 
242   //check with selected features
243   doubleList = QgsVectorLayerUtils::getDoubleValues( layer, QStringLiteral( "col1" ), ok, true, &nulls );
244   QVERIFY( ok );
245   std::sort( doubleList.begin(), doubleList.end() );
246   QCOMPARE( doubleList.length(), 2 );
247   QCOMPARE( doubleList.at( 0 ), 2.0 );
248   QCOMPARE( doubleList.at( 1 ), 3.0 );
249   QCOMPARE( nulls, 0 );
250 
251   QList<QVariant> expVarList = QgsVectorLayerUtils::getValues( layer, QStringLiteral( "tostring(col1) || ' '" ), ok );
252   QVERIFY( ok );
253   QCOMPARE( expVarList.length(), 4 );
254   std::sort( expVarList.begin(), expVarList.end() );
255   QCOMPARE( expVarList.at( 0 ), QVariant() );
256   QCOMPARE( expVarList.at( 1 ).toString(), QString( "1 " ) );
257   QCOMPARE( expVarList.at( 2 ).toString(), QString( "2 " ) );
258   QCOMPARE( expVarList.at( 3 ).toString(), QString( "3 " ) );
259 
260   QList<double> expDoubleList = QgsVectorLayerUtils::getDoubleValues( layer, QStringLiteral( "col1 * 2" ), ok, false, &nulls );
261   QVERIFY( ok );
262   std::sort( expDoubleList.begin(), expDoubleList.end() );
263   QCOMPARE( expDoubleList.length(), 3 );
264   QCOMPARE( expDoubleList.at( 0 ), 2.0 );
265   QCOMPARE( expDoubleList.at( 1 ), 4.0 );
266   QCOMPARE( expDoubleList.at( 2 ), 6.0 );
267   QCOMPARE( nulls, 1 );
268 
269   delete layer;
270 }
271 
QgsVectorLayersetRenderer()272 void TestQgsVectorLayer::QgsVectorLayersetRenderer()
273 {
274   QgsVectorLayer *vLayer = static_cast< QgsVectorLayer * >( mpPointsLayer );
275   TestSignalReceiver receiver;
276   QObject::connect( vLayer, SIGNAL( rendererChanged() ),
277                     &receiver, SLOT( onRendererChanged() ) );
278   QgsSingleSymbolRenderer *symbolRenderer = new QgsSingleSymbolRenderer( QgsSymbol::defaultSymbol( QgsWkbTypes::PointGeometry ) );
279 
280   QCOMPARE( receiver.rendererChanged, false );
281   vLayer->setRenderer( symbolRenderer );
282   QCOMPARE( receiver.rendererChanged, true );
283   QCOMPARE( vLayer->renderer(), symbolRenderer );
284 }
285 
QgsVectorLayersetFeatureBlendMode()286 void TestQgsVectorLayer::QgsVectorLayersetFeatureBlendMode()
287 {
288   QgsVectorLayer *vLayer = static_cast< QgsVectorLayer * >( mpPointsLayer );
289   TestSignalReceiver receiver;
290   QObject::connect( vLayer, SIGNAL( featureBlendModeChanged( const QPainter::CompositionMode ) ),
291                     &receiver, SLOT( onFeatureBlendModeChanged( const QPainter::CompositionMode ) ) );
292 
293   QCOMPARE( int( receiver.featureBlendMode ), 0 );
294   vLayer->setFeatureBlendMode( QPainter::CompositionMode_Screen );
295   QCOMPARE( receiver.featureBlendMode, QPainter::CompositionMode_Screen );
296   QCOMPARE( vLayer->featureBlendMode(), QPainter::CompositionMode_Screen );
297 }
298 
QgsVectorLayersetLayerTransparency()299 void TestQgsVectorLayer::QgsVectorLayersetLayerTransparency()
300 {
301   QgsVectorLayer *vLayer = static_cast< QgsVectorLayer * >( mpPointsLayer );
302   TestSignalReceiver receiver;
303   QObject::connect( vLayer, &QgsVectorLayer::opacityChanged,
304                     &receiver, &TestSignalReceiver::onLayerOpacityChanged );
305 
306   QCOMPARE( receiver.opacity, 1.0 );
307   vLayer->setOpacity( 0.5 );
308   QCOMPARE( receiver.opacity, 0.5 );
309   QCOMPARE( vLayer->opacity(), 0.5 );
310 }
311 
uniqueValues()312 void TestQgsVectorLayer::uniqueValues()
313 {
314   QgsVectorLayer *vLayer = static_cast< QgsVectorLayer * >( mpPointsLayer );
315 
316   //test with invalid field
317   QSet<QVariant> values = vLayer->uniqueValues( 1000 );
318   QCOMPARE( values.count(), 0 );
319 }
320 
minimumValue()321 void TestQgsVectorLayer::minimumValue()
322 {
323   QgsVectorLayer *vLayer = static_cast< QgsVectorLayer * >( mpPointsLayer );
324 
325   //test with invalid field
326   QCOMPARE( vLayer->minimumValue( 1000 ), QVariant() );
327 }
328 
maximumValue()329 void TestQgsVectorLayer::maximumValue()
330 {
331   QgsVectorLayer *vLayer = static_cast< QgsVectorLayer * >( mpPointsLayer );
332 
333   //test with invalid field
334   QCOMPARE( vLayer->maximumValue( 1000 ), QVariant() );
335 }
336 
isSpatial()337 void TestQgsVectorLayer::isSpatial()
338 {
339   QVERIFY( mpPointsLayer->isSpatial() );
340   QVERIFY( mpPolysLayer->isSpatial() );
341   QVERIFY( mpLinesLayer->isSpatial() );
342   QVERIFY( !mpNonSpatialLayer->isSpatial() );
343 }
344 
testAddTopologicalPoints()345 void TestQgsVectorLayer::testAddTopologicalPoints()
346 {
347   // create a simple linestring layer
348 
349   QgsVectorLayer *layerLine = new QgsVectorLayer( QStringLiteral( "LineString?crs=EPSG:27700" ), QStringLiteral( "layer line" ), QStringLiteral( "memory" ) );
350   QVERIFY( layerLine->isValid() );
351 
352   QgsPolylineXY line1;
353   line1 << QgsPointXY( 2, 1 ) << QgsPointXY( 1, 1 ) << QgsPointXY( 1, 5 );
354   QgsFeature lineF1;
355   lineF1.setGeometry( QgsGeometry::fromPolylineXY( line1 ) );
356 
357   layerLine->startEditing();
358   layerLine->addFeature( lineF1 );
359   QgsFeatureId fidLineF1 = lineF1.id();
360   QCOMPARE( layerLine->featureCount(), ( long )1 );
361 
362   QCOMPARE( layerLine->undoStack()->index(), 1 );
363 
364   // outside of the linestring - nothing should happen
365   int result = layerLine->addTopologicalPoints( QgsPoint( 2, 2 ) );
366   QCOMPARE( result, 2 );
367 
368   QCOMPARE( layerLine->undoStack()->index(), 1 );
369   QCOMPARE( layerLine->getFeature( fidLineF1 ).geometry().asWkt(), QgsGeometry::fromWkt( "LINESTRING(2 1, 1 1, 1 5)" ).asWkt() );
370 
371   // add point at an existing vertex
372   result = layerLine->addTopologicalPoints( QgsPoint( 1, 1 ) );
373   QCOMPARE( result, 2 );
374 
375   QCOMPARE( layerLine->undoStack()->index(), 1 );
376   QCOMPARE( layerLine->getFeature( fidLineF1 ).geometry().asWkt(), QgsGeometry::fromWkt( "LINESTRING(2 1, 1 1, 1 5)" ).asWkt() );
377 
378   // add point on segment of linestring
379   result = layerLine->addTopologicalPoints( QgsPoint( 1, 2 ) );
380   QCOMPARE( result, 0 );
381 
382   QCOMPARE( layerLine->undoStack()->index(), 2 );
383   QCOMPARE( layerLine->getFeature( fidLineF1 ).geometry().asWkt(), QgsGeometry::fromWkt( "LINESTRING(2 1, 1 1, 1 2, 1 5)" ).asWkt() );
384 
385   // add points from disjoint geometry - nothing should happen
386   result = layerLine->addTopologicalPoints( QgsGeometry::fromWkt( "LINESTRING(2 0, 2 1, 2 2)" ) );
387   QCOMPARE( result, 2 );
388 
389   QCOMPARE( layerLine->undoStack()->index(), 2 );
390   QCOMPARE( layerLine->getFeature( fidLineF1 ).geometry().asWkt(), QgsGeometry::fromWkt( "LINESTRING(2 1, 1 1, 1 2, 1 5)" ).asWkt() );
391 
392   // add 2 out of 3 points from intersecting geometry
393   result = layerLine->addTopologicalPoints( QgsGeometry::fromWkt( "LINESTRING(2 0, 2 1, 2 3, 1 3, 0 3, 0 4, 1 4)" ) );
394   QCOMPARE( result, 0 );
395 
396   QCOMPARE( layerLine->undoStack()->index(), 2 );
397   QCOMPARE( layerLine->getFeature( fidLineF1 ).geometry().asWkt(), QgsGeometry::fromWkt( "LINESTRING(2 1, 1 1, 1 2, 1 3, 1 4, 1 5)" ).asWkt() );
398 
399   delete layerLine;
400 
401   // Test error results -1: layer error, 1: geometry error
402   QgsVectorLayer *nonSpatialLayer = new QgsVectorLayer( QStringLiteral( "None" ), QStringLiteral( "non spatial layer" ), QStringLiteral( "memory" ) );
403   QVERIFY( nonSpatialLayer->isValid() );
404 
405   result = nonSpatialLayer->addTopologicalPoints( QgsPoint( 2, 2 ) );
406   QCOMPARE( result, -1 );  // Non editable
407 
408   nonSpatialLayer->startEditing();
409   result = nonSpatialLayer->addTopologicalPoints( QgsPoint( 2, 2 ) );
410   QCOMPARE( result, 1 );  // Non spatial
411 
412   delete nonSpatialLayer;
413 
414   QgsVectorLayer *layerPoint = new QgsVectorLayer( QStringLiteral( "Point?crs=EPSG:27700" ), QStringLiteral( "layer point" ), QStringLiteral( "memory" ) );
415   QVERIFY( layerPoint->isValid() );
416 
417   layerPoint->startEditing();
418   result = layerPoint->addTopologicalPoints( QgsGeometry() );
419   QCOMPARE( result, 1 );  // Null geometry
420 
421   delete layerPoint;
422 
423   QgsVectorLayer *layerInvalid = new QgsVectorLayer( QStringLiteral(), QStringLiteral( "layer invalid" ), QStringLiteral( "none" ) );
424   QVERIFY( !layerInvalid->isValid() );
425 
426   result = layerInvalid->addTopologicalPoints( QgsPoint( 2, 2 ) );
427   QCOMPARE( result, -1 );  // Invalid layer
428 
429   delete layerInvalid;
430 }
431 
testCopyPasteFieldConfiguration_data()432 void TestQgsVectorLayer::testCopyPasteFieldConfiguration_data()
433 {
434   QTest::addColumn<QgsMapLayer::StyleCategories>( "categories" );
435   // QTest::addColumn<double>( "flagExpected" );
436   // QTest::addColumn<double>( "widgetExpected" );
437 
438   QTest::newRow( "forms_and_fields" ) << ( QgsMapLayer::Fields | QgsMapLayer::Forms );
439   QTest::newRow( "forms" ) << QgsMapLayer::StyleCategories( QgsMapLayer::Forms );
440   QTest::newRow( "fields" ) << QgsMapLayer::StyleCategories( QgsMapLayer::Fields );
441   QTest::newRow( "none" ) << QgsMapLayer::StyleCategories( QgsMapLayer::StyleCategories() );
442 }
443 
testCopyPasteFieldConfiguration()444 void TestQgsVectorLayer::testCopyPasteFieldConfiguration()
445 {
446   QFETCH( QgsMapLayer::StyleCategories, categories );
447 
448   QgsVectorLayer layer1( QStringLiteral( "Point?field=name:string" ), QStringLiteral( "layer1" ), QStringLiteral( "memory" ) );
449   QVERIFY( layer1.isValid() );
450   QVERIFY( layer1.editorWidgetSetup( 0 ).type().isEmpty() );
451   QCOMPARE( layer1.fieldConfigurationFlags( 0 ), QgsField::ConfigurationFlags() );
452 
453   layer1.setEditorWidgetSetup( 0, QgsEditorWidgetSetup( "ValueMap", QVariantMap() ) );
454   QCOMPARE( layer1.editorWidgetSetup( 0 ).type(), QStringLiteral( "ValueMap" ) );
455   layer1.setFieldConfigurationFlags( 0, QgsField::ConfigurationFlag::NotSearchable );
456   QCOMPARE( layer1.fieldConfigurationFlags( 0 ), QgsField::ConfigurationFlag::NotSearchable );
457 
458   // export given categories, import all
459   QString errorMsg;
460   QDomDocument doc( QStringLiteral( "qgis" ) );
461   QgsReadWriteContext context;
462   layer1.exportNamedStyle( doc, errorMsg, context, categories );
463   QVERIFY( errorMsg.isEmpty() );
464 
465   QgsVectorLayer layer2( QStringLiteral( "Point?field=name:string" ), QStringLiteral( "layer2" ), QStringLiteral( "memory" ) );
466   QVERIFY( layer2.isValid() );
467   QVERIFY( layer2.editorWidgetSetup( 0 ).type().isEmpty() );
468   QCOMPARE( layer2.fieldConfigurationFlags( 0 ), QgsField::ConfigurationFlags() );
469 
470   QVERIFY( layer2.importNamedStyle( doc, errorMsg ) );
471   QCOMPARE( layer2.editorWidgetSetup( 0 ).type(), categories.testFlag( QgsMapLayer::Forms ) ? QStringLiteral( "ValueMap" ) : QString( "" ) );
472   QCOMPARE( layer2.fieldConfigurationFlags( 0 ), categories.testFlag( QgsMapLayer::Fields ) ? QgsField::ConfigurationFlag::NotSearchable : QgsField::ConfigurationFlags() );
473 
474   // export all, import given categories
475   QDomDocument doc2( QStringLiteral( "qgis" ) );
476   layer1.exportNamedStyle( doc2, errorMsg, context );
477   QVERIFY( errorMsg.isEmpty() );
478 
479   QgsVectorLayer layer3( QStringLiteral( "Point?field=name:string" ), QStringLiteral( "layer3" ), QStringLiteral( "memory" ) );
480   QVERIFY( layer3.isValid() );
481   QVERIFY( layer3.editorWidgetSetup( 0 ).type().isEmpty() );
482   QCOMPARE( layer3.fieldConfigurationFlags( 0 ), QgsField::ConfigurationFlags() );
483 
484   QVERIFY( layer3.importNamedStyle( doc2, errorMsg, categories ) );
485   QCOMPARE( layer3.editorWidgetSetup( 0 ).type(), categories.testFlag( QgsMapLayer::Forms ) ? QStringLiteral( "ValueMap" ) : QString( "" ) );
486   QCOMPARE( layer3.fieldConfigurationFlags( 0 ), categories.testFlag( QgsMapLayer::Fields ) ? QgsField::ConfigurationFlag::NotSearchable : QgsField::ConfigurationFlags() );
487 }
488 
489 QGSTEST_MAIN( TestQgsVectorLayer )
490 #include "testqgsvectorlayer.moc"
491