1 /***************************************************************************
2     testqgseditorwidgetregistry.cpp
3     ---------------------
4     begin                : July 2016
5     copyright            : (C) 2016 by Patrick Valsecchi
6     email                : patrick.valsecchi at camptocamp.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 #include "qgstest.h"
16 
17 #include "qgseditorwidgetregistry.h"
18 #include "qgseditorwidgetautoconf.h"
19 #include "qgsproject.h"
20 #include "qgsrelationmanager.h"
21 #include "qgsgui.h"
22 
23 class TestQgsEditorWidgetRegistry: public QObject
24 {
25     Q_OBJECT
26 
27     class DummyPlugin: public QgsEditorWidgetAutoConfPlugin
28     {
29       public:
editorWidgetSetup(const QgsVectorLayer * vl,const QString & fieldName,int & score) const30         QgsEditorWidgetSetup editorWidgetSetup( const QgsVectorLayer *vl, const QString &fieldName, int &score ) const override
31         {
32           Q_UNUSED( vl )
33           if ( fieldName == QLatin1String( "special" ) )
34           {
35             score = 100;
36             return QgsEditorWidgetSetup( QStringLiteral( "Special" ), QVariantMap() );
37           }
38           score = 0;
39           return QgsEditorWidgetSetup();
40         }
41     };
42 
43 
44   private slots:
initTestCase()45     void initTestCase()
46     {
47       QgsApplication::init();
48       QgsApplication::initQgis();
49       QgsGui::editorWidgetRegistry()->initEditors();
50       QgsGui::editorWidgetRegistry()->registerAutoConfPlugin( new DummyPlugin() );
51     }
52 
cleanupTestCase()53     void cleanupTestCase()
54     {
55       QgsApplication::exitQgis();
56     }
57 
stringType()58     void stringType()
59     {
60       checkSimple( QStringLiteral( "string" ), QStringLiteral( "TextEdit" ) );
61     }
62 
datetimeType()63     void datetimeType()
64     {
65       checkSimple( QStringLiteral( "datetime" ), QStringLiteral( "DateTime" ) );
66     }
67 
integerType()68     void integerType()
69     {
70       checkSimple( QStringLiteral( "integer" ), QStringLiteral( "Range" ) );
71     }
72 
longLongType()73     void longLongType()
74     {
75       checkSimple( QStringLiteral( "int8" ), QStringLiteral( "TextEdit" ) ); // no current widget supports 64 bit integers => default to TextEdit
76     }
77 
doubleType()78     void doubleType()
79     {
80       checkSimple( QStringLiteral( "double" ), QStringLiteral( "TextEdit" ) );
81     }
82 
arrayType()83     void arrayType()
84     {
85       checkSimple( QStringLiteral( "double[]" ), QStringLiteral( "List" ) );
86       checkSimple( QStringLiteral( "int[]" ), QStringLiteral( "List" ) );
87       checkSimple( QStringLiteral( "string[]" ), QStringLiteral( "List" ) );
88     }
89 
binaryType()90     void binaryType()
91     {
92       checkSimple( QStringLiteral( "binary" ), QStringLiteral( "Binary" ) );
93     }
94 
configuredType()95     void configuredType()
96     {
97       QgsVectorLayer vl( QStringLiteral( "LineString?crs=epsg:3111&field=pk:int&field=col1:string" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) );
98 
99       QVariantMap config;
100       config[QStringLiteral( "a" )] = QVariant( 12 );
101       config[QStringLiteral( "b" )] = QVariant( "bar" );
102 
103       vl.setEditorWidgetSetup( 1, QgsEditorWidgetSetup( QStringLiteral( "FooEdit" ), config ) );
104 
105       const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( &vl, QStringLiteral( "col1" ) );
106       QCOMPARE( setup.type(), QString( "FooEdit" ) );
107       QCOMPARE( setup.config(), config );
108     }
109 
wrongFieldName()110     void wrongFieldName()
111     {
112       const QgsVectorLayer vl( QStringLiteral( "LineString?crs=epsg:3111&field=pk:int&field=col1:string" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) );
113       const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( &vl, QStringLiteral( "col2" ) );
114       // an unknown fields leads to a default setup with a TextEdit
115       QCOMPARE( setup.type(), QString( "TextEdit" ) );
116       QCOMPARE( setup.config().count(), 0 );
117     }
118 
referencedLayers()119     void referencedLayers()
120     {
121       //build two layers
122       QgsVectorLayer vl1( QStringLiteral( "LineString?crs=epsg:3111&field=pk:int&field=name:string&field=fk:int" ), QStringLiteral( "vl1" ), QStringLiteral( "memory" ) );
123       QgsVectorLayer vl2( QStringLiteral( "LineString?crs=epsg:3111&field=pk:int&field=col1:string" ), QStringLiteral( "vl2" ), QStringLiteral( "memory" ) );
124       QgsProject::instance()->addMapLayer( &vl1, false, false );
125       QgsProject::instance()->addMapLayer( &vl2, false, false );
126 
127       //create a relation between them
128       QgsRelation relation;
129       relation.setId( QStringLiteral( "vl1->vl2" ) );
130       relation.setName( QStringLiteral( "vl1->vl2" ) );
131       relation.setReferencingLayer( vl1.id() );
132       relation.setReferencedLayer( vl2.id() );
133       relation.addFieldPair( QStringLiteral( "fk" ), QStringLiteral( "pk" ) );
134       QVERIFY( relation.isValid() );
135       QgsProject::instance()->relationManager()->addRelation( relation );
136 
137       //check the guessed editor widget type for vl1.fk is RelationReference
138       const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( &vl1, QStringLiteral( "fk" ) );
139       QCOMPARE( setup.type(), QString( "RelationReference" ) );
140       QCOMPARE( setup.config(), QVariantMap() );
141     }
142 
typeFromPlugin()143     void typeFromPlugin()
144     {
145       const QgsVectorLayer vl( QStringLiteral( "LineString?crs=epsg:3111&field=pk:int&field=special:string" ), QStringLiteral( "vl" ), QStringLiteral( "memory" ) );
146       const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( &vl, QStringLiteral( "special" ) );
147       QCOMPARE( setup.type(), QString( "Special" ) );
148     }
149 
150   private:
151 
checkSimple(const QString & dataType,const QString & widgetType)152     static void checkSimple( const QString &dataType, const QString &widgetType )
153     {
154       const QgsVectorLayer vl( "LineString?crs=epsg:3111&field=pk:int&field=col1:" + dataType, QStringLiteral( "vl" ), QStringLiteral( "memory" ) );
155       const QgsEditorWidgetSetup setup = QgsGui::editorWidgetRegistry()->findBest( &vl, QStringLiteral( "col1" ) );
156       QCOMPARE( setup.type(), widgetType );
157       QCOMPARE( setup.config().count(), 0 );
158     }
159 };
160 
161 QGSTEST_MAIN( TestQgsEditorWidgetRegistry )
162 #include "testqgseditorwidgetregistry.moc"
163