Fix failing tests

This commit is contained in:
Matthias Kuhn 2016-12-05 15:43:15 +01:00
parent c4a0c470fd
commit 930ce545a8
17 changed files with 293 additions and 205 deletions

View File

@ -28,4 +28,9 @@ class QgsValueRelationSearchWidgetWrapper : QgsSearchWidgetWrapper
QWidget* createWidget( QWidget* parent );
void initWidget( QWidget* editor );
protected slots:
void onValueChanged();
void setExpression( QString exp );
};

View File

@ -5,6 +5,7 @@ ADD_SUBDIRECTORY(gui)
ADD_SUBDIRECTORY(auth)
ADD_SUBDIRECTORY(providers)
ADD_SUBDIRECTORY(crssync)
ADD_SUBDIRECTORY(test)
IF (WITH_DESKTOP)
ADD_SUBDIRECTORY(app)

View File

@ -47,47 +47,50 @@ QString QgsValueRelationFieldKit::representValue( QgsVectorLayer* layer, int fie
Q_UNUSED( layer )
Q_UNUSED( fieldIndex )
QHash<QString, QString> vrCache;
QgsValueRelationFieldKit::ValueRelationCache vrCache;
if ( cache.isValid() )
{
vrCache = cache.value<QHash<QString, QString>>();
vrCache = cache.value<QgsValueRelationFieldKit::ValueRelationCache>();
}
else
{
vrCache = createCache( layer, fieldIndex, config ).value<QHash<QString, QString>>();
vrCache = QgsValueRelationFieldKit::createCache( config );
}
if ( config.value( QStringLiteral( "AllowMulti" ) ).toBool() )
if ( config.value( "AllowMulti" ).toBool() )
{
QStringList keyList = value.toString().remove( QChar( '{' ) ).remove( QChar( '}' ) ).split( ',' );
QStringList valueList;
Q_FOREACH ( const QString& key, keyList )
Q_FOREACH ( const QgsValueRelationFieldKit::ValueRelationItem& item, vrCache )
{
auto val = vrCache.constFind( key );
if ( val != vrCache.constEnd() )
valueList << val.value();
else
valueList << QStringLiteral( "(%1)" ).arg( key );
if ( keyList.contains( item.key.toString() ) )
{
valueList << item.value;
}
}
return valueList.join( QStringLiteral( ", " ) ).prepend( '{' ).append( '}' );
return valueList.join( ", " ).prepend( '{' ).append( '}' );
}
else
{
if ( value.isNull() )
{
QSettings settings;
return settings.value( QStringLiteral( "qgis/nullValue" ), "NULL" ).toString();
return settings.value( "qgis/nullValue", "NULL" ).toString();
}
auto val = vrCache.constFind( value.toString() );
if ( val != vrCache.constEnd() )
return val.value();
Q_FOREACH ( const QgsValueRelationFieldKit::ValueRelationItem& item, vrCache )
{
if ( item.key == value )
{
return item.value;
}
}
}
return QStringLiteral( "(%1)" ).arg( value.toString() );
return QString( "(%1)" ).arg( value.toString() );
}
QVariant QgsValueRelationFieldKit::sortValue( QgsVectorLayer* layer, int fieldIndex, const QVariantMap& config, const QVariant& cache, const QVariant& value ) const

View File

@ -116,12 +116,13 @@ QVariant QgsConfigurationMap::fromXmlHelper( const QDomElement& element ) const
else if ( type == QLatin1String( "Map" ) )
{
QVariantMap map;
QDomNodeList options = element.elementsByTagName( QStringLiteral( "Option" ) );
QDomNodeList options = element.childNodes();
for ( int i = 0; i < options.count(); ++i )
{
QDomElement elem = options.at( i ).toElement();
map.insert( elem.attribute( QStringLiteral( "name" ) ), fromXmlHelper( elem ) );
if ( elem.tagName() == QLatin1String( "Option" ) )
map.insert( elem.attribute( QStringLiteral( "name" ) ), fromXmlHelper( elem ) );
}
return map;
}

View File

@ -33,7 +33,7 @@ class QgsVectorLayer;
*
* This is an abstract base class and will always need to be subclassed.
*
* @Note added in QGIS 3.0
* @note added in QGIS 3.0
*/
class CORE_EXPORT QgsFieldKit
{

View File

@ -52,7 +52,7 @@ class GUI_EXPORT QgsValueRelationSearchWidgetWrapper : public QgsSearchWidgetWra
QWidget* createWidget( QWidget* parent ) override;
void initWidget( QWidget* editor ) override;
private slots:
protected slots:
//! Called when current value of search widget changes
void onValueChanged();

7
src/test/CMakeLists.txt Normal file
View File

@ -0,0 +1,7 @@
# for installing headers
SET(QGIS_TEST_HDRS
qgstest.h
)
INSTALL(FILES ${QGIS_TEST_HDRS} DESTINATION ${QGIS_INCLUDE_DIR})

35
src/test/qgstest.h Normal file
View File

@ -0,0 +1,35 @@
/***************************************************************************
qgstest - %{Cpp:License:ClassName}
---------------------
begin : 5.12.2016
copyright : (C) 2016 by Matthias Kuhn
email : matthias@opengis.ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSTEST_H
#define QGSTEST_H
#define QGSTEST_MAIN(TestObject) \
QT_BEGIN_NAMESPACE \
QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS \
QT_END_NAMESPACE \
int main(int argc, char *argv[]) \
{ \
QgsApplication app(argc, argv, false); \
app.setAttribute(Qt::AA_Use96Dpi, true); \
QTEST_DISABLE_KEYPAD_NAVIGATION \
QTEST_ADD_GPU_BLACKLIST_SUPPORT \
TestObject tc; \
QTEST_SET_MAIN_SOURCE_PATH \
return QTest::qExec(&tc, argc, argv); \
}
#endif // QGSTEST_H

View File

@ -10,6 +10,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/core/raster
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/core/symbology-ng
${CMAKE_CURRENT_BINARY_DIR}/../../../src/ui
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/ui
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/gui
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/gui/editorwidgets
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/gui/editorwidgets/core
@ -19,7 +20,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/python
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/app
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/app/pluginmanager
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/ui
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/test
)
INCLUDE_DIRECTORIES(SYSTEM
${QT_INCLUDE_DIR}

View File

@ -25,6 +25,8 @@
#include "qgsmapcanvas.h"
#include "qgsunittypes.h"
#include "qgstest.h"
/** \ingroup UnitTests
* This is a unit test for the attribute table dialog
*/
@ -167,5 +169,5 @@ void TestQgsAttributeTable::testFieldCalculationArea()
QVERIFY( qgsDoubleNear( f.attribute( "col1" ).toDouble(), expected, 0.001 ) );
}
QTEST_MAIN( TestQgsAttributeTable )
QGSTEST_MAIN( TestQgsAttributeTable )
#include "testqgsattributetable.moc"

View File

@ -19,6 +19,7 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/core/geometry
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/core/raster
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/core/symbology-ng
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/test
)
INCLUDE_DIRECTORIES(SYSTEM
${QT_INCLUDE_DIR}

View File

@ -27,6 +27,8 @@
#include <qgsmapcanvas.h>
#include <qgsfeature.h>
#include "qgstest.h"
class TestQgsDualView : public QObject
{
Q_OBJECT
@ -67,6 +69,7 @@ void TestQgsDualView::initTestCase()
QgsApplication::init();
QgsApplication::initQgis();
QgsApplication::showSettings();
QgsEditorWidgetRegistry::initEditors();
// Setup a map canvas with a vector layer loaded...
@ -267,9 +270,5 @@ void TestQgsDualView::testAttributeFormSharedValueScanning()
QVERIFY( mixedValueFields.isEmpty() );
}
QTEST_MAIN( TestQgsDualView )
QGSTEST_MAIN( TestQgsDualView )
#include "testqgsdualview.moc"

View File

@ -45,6 +45,7 @@ ADD_PYTHON_TEST(PyQgsEditWidgets test_qgseditwidgets.py)
ADD_PYTHON_TEST(PyQgsExpression test_qgsexpression.py)
ADD_PYTHON_TEST(PyQgsExpressionLineEdit test_qgsexpressionlineedit.py)
ADD_PYTHON_TEST(PyQgsFeature test_qgsfeature.py)
ADD_PYTHON_TEST(PyQgsFieldKitsTest test_qgsfieldkits.py)
ADD_PYTHON_TEST(PyQgsProject test_qgsproject.py)
ADD_PYTHON_TEST(PyQgsFeatureIterator test_qgsfeatureiterator.py)
ADD_PYTHON_TEST(PyQgsField test_qgsfield.py)

View File

@ -52,7 +52,7 @@ class TestQgsConfigurationMap(unittest.TestCase):
prop2 = QgsConfigurationMap()
prop2.fromXml(element)
self.assertEquals(prop2.get(), my_properties)
self.assertEquals(my_properties, prop2.get())
def test_string(self):
"""
@ -69,7 +69,7 @@ class TestQgsConfigurationMap(unittest.TestCase):
prop2 = QgsConfigurationMap()
prop2.fromXml(element)
self.assertEquals(prop2.get(), my_properties)
self.assertEquals(my_properties, prop2.get())
def test_double(self):
"""
@ -86,7 +86,7 @@ class TestQgsConfigurationMap(unittest.TestCase):
prop2 = QgsConfigurationMap()
prop2.fromXml(element)
self.assertEquals(prop2.get(), my_properties)
self.assertEquals(my_properties, prop2.get())
def test_boolean(self):
"""
@ -105,7 +105,7 @@ class TestQgsConfigurationMap(unittest.TestCase):
prop2 = QgsConfigurationMap()
prop2.fromXml(element)
self.assertEquals(prop2.get(), my_properties)
self.assertEquals(my_properties, prop2.get())
def test_complex(self):
"""
@ -124,7 +124,7 @@ class TestQgsConfigurationMap(unittest.TestCase):
prop2 = QgsConfigurationMap()
prop2.fromXml(element)
self.assertEquals(prop2.get(), my_properties)
self.assertEquals(my_properties, prop2.get())
if __name__ == '__main__':

View File

@ -95,40 +95,6 @@ class TestQgsTextEditWidget(unittest.TestCase):
QgsProject.instance().removeAllMapLayers()
def test_ValueMap_representValue(self):
layer = QgsVectorLayer("none?field=number1:integer&field=number2:double&field=text1:string&field=number3:integer&field=number4:double&field=text2:string",
"layer", "memory")
assert layer.isValid()
QgsProject.instance().addMapLayer(layer)
f = QgsFeature()
f.setAttributes([2, 2.5, 'NULL', None, None, None])
assert layer.dataProvider().addFeatures([f])
reg = QgsEditorWidgetRegistry.instance()
factory = reg.factory("ValueMap")
self.assertIsNotNone(factory)
# Tests with different value types occurring in the value map
config = {'two': '2', 'twoandhalf': '2.5', 'NULL text': 'NULL',
'nothing': self.VALUEMAP_NULL_TEXT}
self.assertEqual(factory.representValue(layer, 0, config, None, 2), 'two')
self.assertEqual(factory.representValue(layer, 1, config, None, 2.5), 'twoandhalf')
self.assertEqual(factory.representValue(layer, 2, config, None, 'NULL'), 'NULL text')
# Tests with null values of different types, if value map contains null
self.assertEqual(factory.representValue(layer, 3, config, None, None), 'nothing')
self.assertEqual(factory.representValue(layer, 4, config, None, None), 'nothing')
self.assertEqual(factory.representValue(layer, 5, config, None, None), 'nothing')
# Tests with fallback display for different value types
config = {}
self.assertEqual(factory.representValue(layer, 0, config, None, 2), '(2)')
self.assertEqual(factory.representValue(layer, 1, config, None, 2.5), '(2.50000)')
self.assertEqual(factory.representValue(layer, 2, config, None, 'NULL'), '(NULL)')
# Tests with fallback display for null in different types of fields
self.assertEqual(factory.representValue(layer, 3, config, None, None), '(NULL)')
self.assertEqual(factory.representValue(layer, 4, config, None, None), '(NULL)')
self.assertEqual(factory.representValue(layer, 5, config, None, None), '(NULL)')
QgsProject.instance().removeAllMapLayers()
def test_ValueMap_set_get(self):
layer = QgsVectorLayer("none?field=number:integer", "layer", "memory")
assert layer.isValid()
@ -136,8 +102,8 @@ class TestQgsTextEditWidget(unittest.TestCase):
reg = QgsEditorWidgetRegistry.instance()
configWdg = reg.createConfigWidget('ValueMap', layer, 0, None)
config = {'two': '2', 'twoandhalf': '2.5', 'NULL text': 'NULL',
'nothing': self.VALUEMAP_NULL_TEXT}
config = {'map': {'two': '2', 'twoandhalf': '2.5', 'NULL text': 'NULL',
'nothing': self.VALUEMAP_NULL_TEXT}}
# Set a configuration containing values and NULL and check if it
# is returned intact.
@ -145,140 +111,4 @@ class TestQgsTextEditWidget(unittest.TestCase):
self.assertEqual(configWdg.config(), config)
QgsProject.instance().removeAllMapLayers()
def test_ValueRelation_representValue(self):
first_layer = QgsVectorLayer("none?field=foreign_key:integer",
"first_layer", "memory")
assert first_layer.isValid()
second_layer = QgsVectorLayer("none?field=pkid:integer&field=decoded:string",
"second_layer", "memory")
assert second_layer.isValid()
QgsProject.instance().addMapLayer(second_layer)
f = QgsFeature()
f.setAttributes([123])
assert first_layer.dataProvider().addFeatures([f])
f = QgsFeature()
f.setAttributes([123, 'decoded_val'])
assert second_layer.dataProvider().addFeatures([f])
reg = QgsEditorWidgetRegistry.instance()
factory = reg.factory("ValueRelation")
self.assertIsNotNone(factory)
# Everything valid
config = {'Layer': second_layer.id(), 'Key': 'pkid', 'Value': 'decoded'}
self.assertEqual(factory.representValue(first_layer, 0, config, None, '123'), 'decoded_val')
# Code not find match in foreign layer
config = {'Layer': second_layer.id(), 'Key': 'pkid', 'Value': 'decoded'}
self.assertEqual(factory.representValue(first_layer, 0, config, None, '456'), '(456)')
# Missing Layer
config = {'Key': 'pkid', 'Value': 'decoded'}
self.assertEqual(factory.representValue(first_layer, 0, config, None, '456'), '(456)')
# Invalid Layer
config = {'Layer': 'invalid', 'Key': 'pkid', 'Value': 'decoded'}
self.assertEqual(factory.representValue(first_layer, 0, config, None, '456'), '(456)')
# Invalid Key
config = {'Layer': second_layer.id(), 'Key': 'invalid', 'Value': 'decoded'}
self.assertEqual(factory.representValue(first_layer, 0, config, None, '456'), '(456)')
# Invalid Value
config = {'Layer': second_layer.id(), 'Key': 'pkid', 'Value': 'invalid'}
self.assertEqual(factory.representValue(first_layer, 0, config, None, '456'), '(456)')
QgsProject.instance().removeMapLayer(second_layer.id())
def test_RelationReference_representValue(self):
first_layer = QgsVectorLayer("none?field=foreign_key:integer",
"first_layer", "memory")
assert first_layer.isValid()
second_layer = QgsVectorLayer("none?field=pkid:integer&field=decoded:string",
"second_layer", "memory")
assert second_layer.isValid()
QgsProject.instance().addMapLayers([first_layer, second_layer])
f = QgsFeature()
f.setAttributes([123])
assert first_layer.dataProvider().addFeatures([f])
f = QgsFeature()
f.setAttributes([123, 'decoded_val'])
assert second_layer.dataProvider().addFeatures([f])
relMgr = QgsProject.instance().relationManager()
reg = QgsEditorWidgetRegistry.instance()
factory = reg.factory("RelationReference")
self.assertIsNotNone(factory)
rel = QgsRelation()
rel.setRelationId('rel1')
rel.setRelationName('Relation Number One')
rel.setReferencingLayer(first_layer.id())
rel.setReferencedLayer(second_layer.id())
rel.addFieldPair('foreign_key', 'pkid')
assert(rel.isValid())
relMgr.addRelation(rel)
# Everything valid
config = {'Relation': rel.id()}
second_layer.setDisplayExpression('decoded')
self.assertEqual(factory.representValue(first_layer, 0, config, None, '123'), 'decoded_val')
# Code not find match in foreign layer
config = {'Relation': rel.id()}
second_layer.setDisplayExpression('decoded')
self.assertEqual(factory.representValue(first_layer, 0, config, None, '456'), '456')
# Invalid relation id
config = {'Relation': 'invalid'}
second_layer.setDisplayExpression('decoded')
self.assertEqual(factory.representValue(first_layer, 0, config, None, '123'), '123')
# No display expression
config = {'Relation': rel.id()}
second_layer.setDisplayExpression(None)
self.assertEqual(factory.representValue(first_layer, 0, config, None, '123'), '123')
# Invalid display expression
config = {'Relation': rel.id()}
second_layer.setDisplayExpression('invalid +')
self.assertEqual(factory.representValue(first_layer, 0, config, None, '123'), '123')
# Missing relation
config = {}
second_layer.setDisplayExpression('decoded')
self.assertEqual(factory.representValue(first_layer, 0, config, None, '123'), '123')
# Inconsistent layer provided to representValue()
config = {'Relation': rel.id()}
second_layer.setDisplayExpression('decoded')
self.assertEqual(factory.representValue(second_layer, 0, config, None, '123'), '123')
# Inconsistent idx provided to representValue()
config = {'Relation': rel.id()}
second_layer.setDisplayExpression('decoded')
self.assertEqual(factory.representValue(first_layer, 1, config, None, '123'), '123')
# Invalid relation
rel = QgsRelation()
rel.setRelationId('rel2')
rel.setRelationName('Relation Number Two')
rel.setReferencingLayer(first_layer.id())
rel.addFieldPair('foreign_key', 'pkid')
self.assertFalse(rel.isValid())
relMgr.addRelation(rel)
config = {'Relation': rel.id()}
second_layer.setDisplayExpression('decoded')
self.assertEqual(factory.representValue(first_layer, 0, config, None, '123'), '123')
QgsProject.instance().removeAllMapLayers()
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,202 @@
# -*- coding: utf-8 -*-
"""QGIS Unit tests for field kits.
.. note:: This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
"""
__author__ = 'Matthias Kuhn'
__date__ = '05/12/2016'
__copyright__ = 'Copyright 2016, The QGIS Project'
# This will get replaced with a git SHA1 when you do a git archive
__revision__ = '$Format:%H$'
import qgis # NOQA
from qgis.core import (QgsMapLayerRegistry, QgsFeature, QgsGeometry, QgsPoint,
QgsProject, QgsRelation, QgsVectorLayer, NULL, QgsField,
QgsValueMapFieldKit, QgsValueRelationFieldKit,
QgsRelationReferenceFieldKit)
from qgis.testing import start_app, unittest
from qgis.PyQt.QtCore import QVariant
from qgis.PyQt.QtWidgets import QTextEdit
start_app()
class TestQgsValueMapFieldKit(unittest.TestCase):
VALUEMAP_NULL_TEXT = "{2839923C-8B7D-419E-B84B-CA2FE9B80EC7}"
def test_representValue(self):
layer = QgsVectorLayer("none?field=number1:integer&field=number2:double&field=text1:string&field=number3:integer&field=number4:double&field=text2:string",
"layer", "memory")
self.assertTrue(layer.isValid())
QgsMapLayerRegistry.instance().addMapLayer(layer)
f = QgsFeature()
f.setAttributes([2, 2.5, 'NULL', None, None, None])
layer.dataProvider().addFeatures([f])
fieldKit = QgsValueMapFieldKit()
# Tests with different value types occurring in the value map
config = {'map': {'two': '2', 'twoandhalf': '2.5', 'NULL text': 'NULL',
'nothing': self.VALUEMAP_NULL_TEXT}}
self.assertEqual(fieldKit.representValue(layer, 0, config, None, 2), 'two')
self.assertEqual(fieldKit.representValue(layer, 1, config, None, 2.5), 'twoandhalf')
self.assertEqual(fieldKit.representValue(layer, 2, config, None, 'NULL'), 'NULL text')
# Tests with null values of different types, if value map contains null
self.assertEqual(fieldKit.representValue(layer, 3, config, None, None), 'nothing')
self.assertEqual(fieldKit.representValue(layer, 4, config, None, None), 'nothing')
self.assertEqual(fieldKit.representValue(layer, 5, config, None, None), 'nothing')
# Tests with fallback display for different value types
config = {}
self.assertEqual(fieldKit.representValue(layer, 0, config, None, 2), '(2)')
self.assertEqual(fieldKit.representValue(layer, 1, config, None, 2.5), '(2.50000)')
self.assertEqual(fieldKit.representValue(layer, 2, config, None, 'NULL'), '(NULL)')
# Tests with fallback display for null in different types of fields
self.assertEqual(fieldKit.representValue(layer, 3, config, None, None), '(NULL)')
self.assertEqual(fieldKit.representValue(layer, 4, config, None, None), '(NULL)')
self.assertEqual(fieldKit.representValue(layer, 5, config, None, None), '(NULL)')
QgsMapLayerRegistry.instance().removeAllMapLayers()
class TestQgsValueRelationFieldKit(unittest.TestCase):
def test_representValue(self):
first_layer = QgsVectorLayer("none?field=foreign_key:integer",
"first_layer", "memory")
self.assertTrue(first_layer.isValid())
second_layer = QgsVectorLayer("none?field=pkid:integer&field=decoded:string",
"second_layer", "memory")
self.assertTrue(second_layer.isValid())
QgsMapLayerRegistry.instance().addMapLayer(second_layer)
f = QgsFeature()
f.setAttributes([123])
first_layer.dataProvider().addFeatures([f])
f = QgsFeature()
f.setAttributes([123, 'decoded_val'])
second_layer.dataProvider().addFeatures([f])
fieldKit = QgsValueRelationFieldKit()
# Everything valid
config = {'Layer': second_layer.id(), 'Key': 'pkid', 'Value': 'decoded'}
self.assertEqual(fieldKit.representValue(first_layer, 0, config, None, '123'), 'decoded_val')
# Code not find match in foreign layer
config = {'Layer': second_layer.id(), 'Key': 'pkid', 'Value': 'decoded'}
self.assertEqual(fieldKit.representValue(first_layer, 0, config, None, '456'), '(456)')
# Missing Layer
config = {'Key': 'pkid', 'Value': 'decoded'}
self.assertEqual(fieldKit.representValue(first_layer, 0, config, None, '456'), '(456)')
# Invalid Layer
config = {'Layer': 'invalid', 'Key': 'pkid', 'Value': 'decoded'}
self.assertEqual(fieldKit.representValue(first_layer, 0, config, None, '456'), '(456)')
# Invalid Key
config = {'Layer': second_layer.id(), 'Key': 'invalid', 'Value': 'decoded'}
self.assertEqual(fieldKit.representValue(first_layer, 0, config, None, '456'), '(456)')
# Invalid Value
config = {'Layer': second_layer.id(), 'Key': 'pkid', 'Value': 'invalid'}
self.assertEqual(fieldKit.representValue(first_layer, 0, config, None, '456'), '(456)')
QgsMapLayerRegistry.instance().removeMapLayer(second_layer.id())
class TestQgsRelationReferenceFieldKit(unittest.TestCase):
def test_representValue(self):
first_layer = QgsVectorLayer("none?field=foreign_key:integer",
"first_layer", "memory")
self.assertTrue(first_layer.isValid())
second_layer = QgsVectorLayer("none?field=pkid:integer&field=decoded:string",
"second_layer", "memory")
self.assertTrue(second_layer.isValid())
QgsMapLayerRegistry.instance().addMapLayers([first_layer, second_layer])
f = QgsFeature()
f.setAttributes([123])
first_layer.dataProvider().addFeatures([f])
f = QgsFeature()
f.setAttributes([123, 'decoded_val'])
second_layer.dataProvider().addFeatures([f])
relMgr = QgsProject.instance().relationManager()
fieldKit = QgsRelationReferenceFieldKit()
rel = QgsRelation()
rel.setRelationId('rel1')
rel.setRelationName('Relation Number One')
rel.setReferencingLayer(first_layer.id())
rel.setReferencedLayer(second_layer.id())
rel.addFieldPair('foreign_key', 'pkid')
self.assertTrue(rel.isValid())
relMgr.addRelation(rel)
# Everything valid
config = {'Relation': rel.id()}
second_layer.setDisplayExpression('decoded')
self.assertEqual(fieldKit.representValue(first_layer, 0, config, None, '123'), 'decoded_val')
# Code not find match in foreign layer
config = {'Relation': rel.id()}
second_layer.setDisplayExpression('decoded')
self.assertEqual(fieldKit.representValue(first_layer, 0, config, None, '456'), '456')
# Invalid relation id
config = {'Relation': 'invalid'}
second_layer.setDisplayExpression('decoded')
self.assertEqual(fieldKit.representValue(first_layer, 0, config, None, '123'), '123')
# No display expression
config = {'Relation': rel.id()}
second_layer.setDisplayExpression(None)
self.assertEqual(fieldKit.representValue(first_layer, 0, config, None, '123'), '123')
# Invalid display expression
config = {'Relation': rel.id()}
second_layer.setDisplayExpression('invalid +')
self.assertEqual(fieldKit.representValue(first_layer, 0, config, None, '123'), '123')
# Missing relation
config = {}
second_layer.setDisplayExpression('decoded')
self.assertEqual(fieldKit.representValue(first_layer, 0, config, None, '123'), '123')
# Inconsistent layer provided to representValue()
config = {'Relation': rel.id()}
second_layer.setDisplayExpression('decoded')
self.assertEqual(fieldKit.representValue(second_layer, 0, config, None, '123'), '123')
# Inconsistent idx provided to representValue()
config = {'Relation': rel.id()}
second_layer.setDisplayExpression('decoded')
self.assertEqual(fieldKit.representValue(first_layer, 1, config, None, '123'), '123')
# Invalid relation
rel = QgsRelation()
rel.setRelationId('rel2')
rel.setRelationName('Relation Number Two')
rel.setReferencingLayer(first_layer.id())
rel.addFieldPair('foreign_key', 'pkid')
self.assertFalse(rel.isValid())
relMgr.addRelation(rel)
config = {'Relation': rel.id()}
second_layer.setDisplayExpression('decoded')
self.assertEqual(fieldKit.representValue(first_layer, 0, config, None, '123'), '123')
QgsMapLayerRegistry.instance().removeAllMapLayers()
if __name__ == '__main__':
unittest.main()

View File

@ -457,7 +457,7 @@ CREATE TABLE qgis_test.widget_styles(
);
INSERT INTO qgis_editor_widget_styles VALUES
('qgis_test', 'widget_styles', 'fld1', 'FooEdit', '<config><option key="param1" value="value1"/><option key="param2" value="2"/></config>');
('qgis_test', 'widget_styles', 'fld1', 'FooEdit', '<config type="Map"><Option name="param1" value="value1" type="String"/><Option name="param2" value="2" type="String"/></config>');
-----------------------------