1 /*************************************************************************** 2 testqgslistwidget.cpp 3 -------------------------------------- 4 Date : 08 09 2016 5 Copyright : (C) 2016 Patrick Valsecchi 6 Email : patrick dot valsecchi at camptocamp 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 17 #include "qgstest.h" 18 19 #include <editorwidgets/qgslistwidgetfactory.h> 20 #include <qgslistwidget.h> 21 #include <editorwidgets/core/qgseditorwidgetwrapper.h> 22 #include <qgsapplication.h> 23 #include <qgsvectorlayer.h> 24 #include <editorwidgets/qgslistwidgetwrapper.h> 25 #include <QSignalSpy> 26 27 class TestQgsListWidget : public QObject 28 { 29 Q_OBJECT 30 private: 31 QString dbConn; 32 private slots: initTestCase()33 void initTestCase() // will be called before the first testfunction is executed. 34 { 35 QgsApplication::init(); 36 QgsApplication::initQgis(); 37 dbConn = getenv( "QGIS_PGTEST_DB" ); 38 if ( dbConn.isEmpty() ) 39 { 40 dbConn = "service=\"qgis_test\""; 41 } 42 } 43 cleanupTestCase()44 void cleanupTestCase() // will be called after the last testfunction was executed. 45 { 46 // delete new features in db from postgres test 47 QgsVectorLayer *vl_array_int = new QgsVectorLayer( QStringLiteral( "%1 sslmode=disable key=\"pk\" table=\"qgis_test\".\"array_tbl\" sql=" ).arg( dbConn ), QStringLiteral( "json" ), QStringLiteral( "postgres" ) ); 48 vl_array_int->startEditing( ); 49 const QgsFeatureIds delete_ids = QSet<QgsFeatureId>() << Q_INT64_C( 997 ) << Q_INT64_C( 998 ) << Q_INT64_C( 999 ); 50 vl_array_int->deleteFeatures( delete_ids ); 51 vl_array_int->commitChanges( false ); 52 QgsVectorLayer *vl_array_str = new QgsVectorLayer( QStringLiteral( "%1 sslmode=disable key=\"pk\" table=\"qgis_test\".\"string_array\" sql=" ).arg( dbConn ), QStringLiteral( "json" ), QStringLiteral( "postgres" ) ); 53 vl_array_str->startEditing( ); 54 vl_array_str->deleteFeatures( delete_ids ); 55 vl_array_str->commitChanges( false ); 56 QgsApplication::exitQgis(); 57 } 58 testStringUpdate()59 void testStringUpdate() 60 { 61 const QgsListWidgetFactory factory( QStringLiteral( "testList" ) ); 62 QgsVectorLayer vl( QStringLiteral( "Point?field=fld:string[]" ), QStringLiteral( "test" ), QStringLiteral( "memory" ) ); 63 QgsEditorWidgetWrapper *wrapper = factory.create( &vl, 0, nullptr, nullptr ); 64 QVERIFY( wrapper ); 65 const QSignalSpy spy( wrapper, SIGNAL( valueChanged( const QVariant & ) ) ); 66 67 QgsListWidget *widget = qobject_cast< QgsListWidget * >( wrapper->widget() ); 68 QVERIFY( widget ); 69 70 QStringList initial; 71 initial << QStringLiteral( "one" ) << QStringLiteral( "two" ); 72 wrapper->setValues( initial, QVariantList() ); 73 74 const QVariant value = wrapper->value(); 75 QCOMPARE( int( value.type() ), int( QVariant::StringList ) ); 76 QCOMPARE( value.toStringList(), initial ); 77 QCOMPARE( spy.count(), 0 ); 78 79 QAbstractItemModel *model = widget->tableView->model(); 80 model->setData( model->index( 0, 0 ), "hello" ); 81 QCOMPARE( spy.count(), 1 ); 82 QVERIFY( widget->valid() ); 83 84 QStringList expected = initial; 85 expected[0] = QStringLiteral( "hello" ); 86 const QVariant eventValue = spy.at( 0 ).at( 0 ).value<QVariant>(); 87 QCOMPARE( int( eventValue.type() ), int( QVariant::StringList ) ); 88 QCOMPARE( eventValue.toStringList(), expected ); 89 QCOMPARE( wrapper->value().toStringList(), expected ); 90 QCOMPARE( spy.count(), 1 ); 91 QVERIFY( widget->valid() ); 92 } 93 testIntUpdate()94 void testIntUpdate() 95 { 96 const QgsListWidgetFactory factory( QStringLiteral( "testList" ) ); 97 QgsVectorLayer vl( QStringLiteral( "Point?field=fld:int[]" ), QStringLiteral( "test" ), QStringLiteral( "memory" ) ); 98 QgsEditorWidgetWrapper *wrapper = factory.create( &vl, 0, nullptr, nullptr ); 99 QVERIFY( wrapper ); 100 QSignalSpy spy( wrapper, SIGNAL( valueChanged( const QVariant & ) ) ); 101 102 QgsListWidget *widget = qobject_cast< QgsListWidget * >( wrapper->widget() ); 103 QVERIFY( widget ); 104 105 QVariantList initial; 106 initial << 1 << -2; 107 wrapper->setValues( initial, QVariantList() ); 108 109 const QVariant value = wrapper->value(); 110 QCOMPARE( int( value.type() ), int( QVariant::List ) ); 111 QCOMPARE( value.toList(), initial ); 112 QCOMPARE( spy.count(), 0 ); 113 114 QAbstractItemModel *model = widget->tableView->model(); 115 model->setData( model->index( 0, 0 ), 3 ); 116 QCOMPARE( spy.count(), 1 ); 117 118 QVariantList expected = initial; 119 expected[0] = 3; 120 QCOMPARE( spy.count(), 1 ); 121 QVariant eventValue = spy.at( 0 ).at( 0 ).value<QVariant>(); 122 QCOMPARE( int( eventValue.type() ), int( QVariant::List ) ); 123 QCOMPARE( eventValue.toList(), expected ); 124 QCOMPARE( wrapper->value().toList(), expected ); 125 QVERIFY( widget->valid() ); 126 127 model->setData( model->index( 0, 0 ), "a" ); 128 expected = initial; 129 expected.removeAt( 0 ); 130 QVERIFY( !widget->valid() ); 131 QCOMPARE( wrapper->value().toList(), expected ); 132 133 spy.clear(); 134 model->setData( model->index( 0, 0 ), 56 ); 135 expected = initial; 136 expected[0] = 56; 137 QCOMPARE( spy.count(), 1 ); 138 eventValue = spy.at( 0 ).at( 0 ).value<QVariant>(); 139 QCOMPARE( eventValue.toList(), expected ); 140 QCOMPARE( wrapper->value().toList(), expected ); 141 QVERIFY( widget->valid() ); 142 } 143 testPostgres()144 void testPostgres() 145 { 146 //create pg layers 147 QgsVectorLayer *vl_array_int = new QgsVectorLayer( QStringLiteral( "%1 sslmode=disable key=\"pk\" table=\"qgis_test\".\"array_tbl\" sql=" ).arg( dbConn ), QStringLiteral( "json" ), QStringLiteral( "postgres" ) ); 148 QVERIFY( vl_array_int->isValid( ) ); 149 150 QgsListWidgetWrapper w_array_int( vl_array_int, vl_array_int->fields().indexOf( QLatin1String( "location" ) ), nullptr, nullptr ); 151 QgsListWidget *widget = qobject_cast< QgsListWidget * >( w_array_int.widget( ) ); 152 153 vl_array_int->startEditing( ); 154 QVariantList newList; 155 newList.append( QStringLiteral( "100" ) ); 156 widget->setList( QList<QVariant>() << 100 ); 157 QVERIFY( w_array_int.value( ).isValid( ) ); 158 QCOMPARE( widget->list( ), QList<QVariant>( ) << 100 ); 159 // save value and check it is saved properly in postges 160 QgsFeature new_rec_997 {vl_array_int->fields(), 997}; 161 new_rec_997.setAttribute( 0, QVariant( 997 ) ); 162 vl_array_int->addFeature( new_rec_997, QgsFeatureSink::RollBackOnErrors ); 163 vl_array_int->commitChanges( false ); 164 bool success = vl_array_int->changeAttributeValue( 997, 1, w_array_int.value(), QVariant(), false ); 165 QVERIFY( success ); 166 success = vl_array_int->commitChanges( false ); 167 QVERIFY( success ); 168 169 w_array_int.setFeature( vl_array_int->getFeature( 997 ) ); 170 QCOMPARE( widget->list( ), QList<QVariant>( ) << 100 ); 171 172 // alter two values at a time which triggered old bug (#38784) 173 widget->setList( QList<QVariant>() << 4 << 5 << 6 ); 174 QgsFeature new_rec_998 {vl_array_int->fields(), 998}; 175 new_rec_998.setAttribute( 0, QVariant( 998 ) ); 176 new_rec_998.setAttribute( 1, w_array_int.value() ); 177 vl_array_int->addFeature( new_rec_998, QgsFeatureSink::RollBackOnErrors ); 178 179 widget->setList( QList<QVariant>() << 10 << 11 << 12 ); 180 QgsFeature new_rec_999 {vl_array_int->fields(), 999}; 181 new_rec_999.setAttribute( 0, QVariant( 999 ) ); 182 new_rec_999.setAttribute( 1, w_array_int.value() ); 183 vl_array_int->addFeature( new_rec_999, QgsFeatureSink::RollBackOnErrors ); 184 vl_array_int->commitChanges( false ); 185 186 w_array_int.setFeature( vl_array_int->getFeature( 998 ) ); 187 QCOMPARE( widget->list( ), QList<QVariant>( ) << 4 << 5 << 6 ); 188 189 w_array_int.setFeature( vl_array_int->getFeature( 999 ) ); 190 QCOMPARE( widget->list( ), QList<QVariant>() << 10 << 11 << 12 ); 191 192 // do similar for array of strings 193 QgsVectorLayer *vl_array_str = new QgsVectorLayer( QStringLiteral( "%1 sslmode=disable key=\"pk\" table=\"qgis_test\".\"string_array\" sql=" ).arg( dbConn ), QStringLiteral( "json" ), QStringLiteral( "postgres" ) ); 194 QVERIFY( vl_array_str->isValid() ); 195 196 QgsListWidgetWrapper w_array_str( vl_array_str, vl_array_str->fields().indexOf( QLatin1String( "value" ) ), nullptr, nullptr ); 197 widget = qobject_cast< QgsListWidget * >( w_array_str.widget( ) ); 198 vl_array_str->startEditing( ); 199 QVariantList newListStr; 200 201 // test quotes 202 newListStr.append( QStringLiteral( "10\"0" ) ); 203 widget->setList( newListStr ); 204 QVERIFY( w_array_str.value().isValid() ); 205 QCOMPARE( widget->list( ), QList<QVariant>( ) << QStringLiteral( "10\"0" ) ); 206 // save value and check it is saved properly in postges 207 QgsFeature new_rec_997_str {vl_array_str->fields(), 997}; 208 new_rec_997_str.setAttribute( 0, QVariant( 997 ) ); 209 vl_array_str->addFeature( new_rec_997_str, QgsFeatureSink::RollBackOnErrors ); 210 vl_array_str->commitChanges( false ); 211 success = vl_array_str->changeAttributeValue( 997, 1, w_array_str.value(), QVariant(), false ); 212 QVERIFY( success ); 213 success = vl_array_str->commitChanges( false ); 214 QVERIFY( success ); 215 216 w_array_str.setFeature( vl_array_str->getFeature( 997 ) ); 217 QCOMPARE( widget->list( ), QList<QVariant>( ) << QStringLiteral( "10\"0" ) ); 218 219 // alter two values at a time which triggered old bug (#38784) 220 widget->setList( QList<QVariant>() << QStringLiteral( "four" ) << QStringLiteral( "five" ) << QStringLiteral( "six" ) ); 221 QgsFeature new_rec_998_str {vl_array_str->fields(), 998}; 222 new_rec_998_str.setAttribute( 0, QVariant( 998 ) ); 223 new_rec_998_str.setAttribute( 1, w_array_str.value() ); 224 vl_array_str->addFeature( new_rec_998_str, QgsFeatureSink::RollBackOnErrors ); 225 226 widget->setList( QList<QVariant>() << QStringLiteral( "ten" ) << QStringLiteral( "eleven" ) << QStringLiteral( "twelve" ) ); 227 QgsFeature new_rec_999_str {vl_array_str->fields(), 999}; 228 new_rec_999_str.setAttribute( 0, QVariant( 999 ) ); 229 new_rec_999_str.setAttribute( 1, w_array_str.value() ); 230 vl_array_str->addFeature( new_rec_999_str, QgsFeatureSink::RollBackOnErrors ); 231 vl_array_str->commitChanges( false ); 232 233 w_array_str.setFeature( vl_array_str->getFeature( 998 ) ); 234 QCOMPARE( widget->list( ), QList<QVariant>() << QStringLiteral( "four" ) << QStringLiteral( "five" ) << QStringLiteral( "six" ) ); 235 236 w_array_str.setFeature( vl_array_str->getFeature( 999 ) ); 237 QCOMPARE( widget->list( ), QList<QVariant>() << QStringLiteral( "ten" ) << QStringLiteral( "eleven" ) << QStringLiteral( "twelve" ) ); 238 } 239 }; 240 241 QGSTEST_MAIN( TestQgsListWidget ) 242 #include "testqgslistwidget.moc" 243