1 /***************************************************************************
2 testqgsrangewidget.cpp
3 ---------------------------
4 begin : Jan 2018
5 copyright : (C) 2018 by Alessandro Pasotti
6 email : elpaso at itopen dot it
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 "qgsrangewidgetwrapper.h"
21 #include "qgsrangeconfigdlg.h"
22 #include "qgsdoublespinbox.h"
23 #include "qgsspinbox.h"
24 #include "qgsapplication.h"
25 #include "qgslogger.h"
26 #include "qgsvectorlayer.h"
27 #include "qgsdataprovider.h"
28 #include "qgsfilterlineedit.h"
29
30 #include <QLineEdit>
31 #include <QObject>
32 #include <QtTest/QSignalSpy>
33
34 #include <memory>
35
36 #define SPECIAL_TEXT_WHEN_EMPTY QString( QChar( 0x2063 ) )
37
38 /**
39 * @ingroup UnitTests
40 * This is a unit test for the range widget
41 *
42 * \see QgsRangeWidgetWrapper
43 */
44 class TestQgsRangeWidgetWrapper : public QObject
45 {
46 Q_OBJECT
47 private slots:
48 void initTestCase();// will be called before the first testfunction is executed.
49 void cleanupTestCase();// will be called after the last testfunction was executed.
50 void init();// will be called before each testfunction is executed.
51 void cleanup();// will be called after every testfunction.
52 void test_setDoubleRange();
53 void test_setDoubleSmallerRange();
54 void test_setDoubleLimits();
55 void test_nulls();
56 void test_negativeIntegers(); // see GH issue #32149
57 void test_focus();
58 void testLongLong();
59
60 private:
61 std::unique_ptr<QgsRangeWidgetWrapper> widget0; // For field 0
62 std::unique_ptr<QgsRangeWidgetWrapper> widget1; // For field 1
63 std::unique_ptr<QgsRangeWidgetWrapper> widget2; // For field 2
64 std::unique_ptr<QgsRangeWidgetWrapper> widget3; // For field 3
65 std::unique_ptr<QgsVectorLayer> vl;
66 };
67
initTestCase()68 void TestQgsRangeWidgetWrapper::initTestCase()
69 {
70 // Set up the QgsSettings environment
71 QCoreApplication::setOrganizationName( QStringLiteral( "QGIS" ) );
72 QCoreApplication::setOrganizationDomain( QStringLiteral( "qgis.org" ) );
73 QCoreApplication::setApplicationName( QStringLiteral( "QGIS-TEST-RANGE-WIDGET" ) );
74
75 QgsApplication::init();
76 QgsApplication::initQgis();
77 }
78
cleanupTestCase()79 void TestQgsRangeWidgetWrapper::cleanupTestCase()
80 {
81 QgsApplication::exitQgis();
82 }
83
init()84 void TestQgsRangeWidgetWrapper::init()
85 {
86 vl = std::make_unique<QgsVectorLayer>( QStringLiteral( "Point?crs=epsg:4326" ),
87 QStringLiteral( "myvl" ),
88 QLatin1String( "memory" ) );
89
90 // add fields
91 QList<QgsField> fields;
92 fields.append( QgsField( "id", QVariant::Int ) );
93 // precision = 9
94 QgsField dfield( "number", QVariant::Double );
95 dfield.setPrecision( 9 );
96 fields.append( dfield );
97 // default precision = 0
98 const QgsField dfield2( "number_def", QVariant::Double );
99 fields.append( dfield2 );
100 // simple int
101 fields.append( QgsField( "simplenumber", QVariant::Int ) );
102 fields.append( QgsField( "longlong", QVariant::LongLong ) );
103 vl->dataProvider()->addAttributes( fields );
104 vl->updateFields();
105 QVERIFY( vl.get() );
106 QVERIFY( vl->isValid() );
107 // Add feature 1:1:123.123456789:123.123456789:NULL:POINT( 1 1 )
108 QgsFeature feat1( vl->fields(), 1 );
109 feat1.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POINT( 1 1 )" ) ) );
110 feat1.setAttribute( QStringLiteral( "id" ), 1 );
111 feat1.setAttribute( QStringLiteral( "number" ), 123.123456789 );
112 feat1.setAttribute( QStringLiteral( "number_def" ), 123.123456789 );
113 vl->dataProvider()->addFeature( feat1 );
114 // Add feature 2:2:NULL:NULL:NULL:POINT( 2 2 )
115 QgsFeature feat2( vl->fields(), 2 );
116 feat2.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POINT( 2 2 )" ) ) );
117 feat2.setAttribute( QStringLiteral( "id" ), 2 );
118 vl->dataProvider()->addFeature( feat2 );
119 // Add feature 3:3:-123.123456789:-123.123456789:NULL:POINT( 3 3 )
120 QgsFeature feat3( vl->fields(), 3 );
121 feat3.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "POINT( 3 3 )" ) ) );
122 feat3.setAttribute( QStringLiteral( "number" ), -123.123456789 );
123 feat3.setAttribute( QStringLiteral( "number_def" ), -123.123456789 );
124 feat3.setAttribute( QStringLiteral( "id" ), 3 );
125 vl->dataProvider()->addFeature( feat3 );
126 // Verify feat 1 was added
127 QCOMPARE( vl->featureCount( ), ( long )3 );
128 const QgsFeature _feat1( vl->getFeature( 1 ) );
129 QCOMPARE( _feat1, feat1 );
130 widget0 = std::make_unique<QgsRangeWidgetWrapper>( vl.get(), 0, nullptr, nullptr );
131 widget1 = std::make_unique<QgsRangeWidgetWrapper>( vl.get(), 1, nullptr, nullptr );
132 widget2 = std::make_unique<QgsRangeWidgetWrapper>( vl.get(), 2, nullptr, nullptr );
133 widget3 = std::make_unique<QgsRangeWidgetWrapper>( vl.get(), 3, nullptr, nullptr );
134 QVERIFY( widget1.get() );
135 }
136
cleanup()137 void TestQgsRangeWidgetWrapper::cleanup()
138 {
139 }
140
test_setDoubleRange()141 void TestQgsRangeWidgetWrapper::test_setDoubleRange()
142 {
143 // Test setting scale range with doubles and NULL values, default range
144 // See https://github.com/qgis/QGIS/issues/25773
145 // QGIS 3 Vector Layer Fields Garbled when Clicking the Toggle Editing Icon
146
147 QgsDoubleSpinBox *editor = qobject_cast<QgsDoubleSpinBox *>( widget1->createWidget( nullptr ) );
148 QVERIFY( editor );
149 widget1->initWidget( editor );
150 QgsDoubleSpinBox *editor2 = qobject_cast<QgsDoubleSpinBox *>( widget2->createWidget( nullptr ) );
151 QVERIFY( editor2 );
152 widget2->initWidget( editor2 );
153
154 const QgsFeature feat( vl->getFeature( 1 ) );
155 QVERIFY( feat.isValid() );
156 QCOMPARE( feat.attribute( 1 ).toDouble(), 123.123456789 );
157 widget1->setFeature( vl->getFeature( 1 ) );
158 widget2->setFeature( vl->getFeature( 1 ) );
159 QCOMPARE( vl->fields().at( 1 ).precision(), 9 );
160 // Default is 0 !!! for double, really ?
161 QCOMPARE( vl->fields().at( 2 ).precision(), 0 );
162 QCOMPARE( editor->decimals(), vl->fields().at( 1 ).precision() );
163 QCOMPARE( editor->decimals(), 9 );
164 QCOMPARE( editor2->decimals(), vl->fields().at( 2 ).precision() );
165 QCOMPARE( editor->valueFromText( feat.attribute( 1 ).toString() ), 123.123456789 );
166 QCOMPARE( feat.attribute( 1 ).toString(), QStringLiteral( "123.123456789" ) );
167 QCOMPARE( editor2->valueFromText( feat.attribute( 1 ).toString() ), 123.123456789 );
168 QCOMPARE( editor->value( ), 123.123456789 );
169 QCOMPARE( editor2->value( ), 123.0 );
170 QCOMPARE( editor->minimum( ), std::numeric_limits<double>::lowest() );
171 QCOMPARE( editor2->minimum( ), std::numeric_limits<double>::lowest() );
172 QCOMPARE( editor->maximum( ), std::numeric_limits<double>::max() );
173 QCOMPARE( editor2->maximum( ), std::numeric_limits<double>::max() );
174
175 widget1->setFeature( vl->getFeature( 2 ) );
176 widget2->setFeature( vl->getFeature( 2 ) );
177 QCOMPARE( editor->value( ), editor->minimum() );
178 QCOMPARE( editor2->value( ), editor->minimum() );
179
180 widget1->setFeature( vl->getFeature( 3 ) );
181 widget2->setFeature( vl->getFeature( 3 ) );
182 QCOMPARE( editor->value( ), -123.123456789 );
183 QCOMPARE( editor2->value( ), -123.0 );
184 }
185
test_setDoubleSmallerRange()186 void TestQgsRangeWidgetWrapper::test_setDoubleSmallerRange()
187 {
188 // Same test but we set a smaller validity range for the widget
189 QVariantMap cfg;
190 cfg.insert( QStringLiteral( "Min" ), -100.0 );
191 cfg.insert( QStringLiteral( "Max" ), 100.0 );
192 cfg.insert( QStringLiteral( "Step" ), 1 );
193 widget1->setConfig( cfg );
194 QgsDoubleSpinBox *editor = qobject_cast<QgsDoubleSpinBox *>( widget1->createWidget( nullptr ) );
195 QVERIFY( editor );
196 widget1->initWidget( editor );
197
198 widget2->setConfig( cfg );
199 QgsDoubleSpinBox *editor2 = qobject_cast<QgsDoubleSpinBox *>( widget2->createWidget( nullptr ) );
200 QVERIFY( editor2 );
201 widget2->initWidget( editor2 );
202
203 const QgsFeature feat( vl->getFeature( 1 ) );
204 QVERIFY( feat.isValid() );
205 QCOMPARE( feat.attribute( 1 ).toDouble(), 123.123456789 );
206 widget1->setFeature( vl->getFeature( 1 ) );
207 widget2->setFeature( vl->getFeature( 1 ) );
208
209 QCOMPARE( vl->fields().at( 1 ).precision(), 9 );
210 // Default is 0 !!! for double, really ?
211 QCOMPARE( vl->fields().at( 2 ).precision(), 0 );
212 QCOMPARE( editor->decimals(), vl->fields().at( 1 ).precision() );
213 QCOMPARE( editor2->decimals(), vl->fields().at( 2 ).precision() );
214 // value was changed to the maximum (not NULL) accepted value
215 QCOMPARE( editor->value( ), 100.0 );
216 // value was changed to the maximum (not NULL) accepted value
217 QCOMPARE( editor2->value( ), 100.0 );
218 // minimum was lowered by the precision (10e-9)
219 QCOMPARE( editor->minimum( ), -100.000000001 );
220 // minimum was lowered by step (1)
221 QCOMPARE( editor2->minimum( ), ( double ) - 101 );
222 QCOMPARE( editor->maximum( ), ( double )100 );
223 QCOMPARE( editor2->maximum( ), ( double )100 );
224
225 // NULL, NULL
226 widget1->setFeature( vl->getFeature( 2 ) );
227 widget2->setFeature( vl->getFeature( 2 ) );
228 QCOMPARE( editor->value( ), editor->minimum() );
229 QCOMPARE( editor2->value( ), editor2->minimum() );
230
231 // negative, negative
232 widget1->setFeature( vl->getFeature( 3 ) );
233 widget2->setFeature( vl->getFeature( 3 ) );
234 // value was changed to the minimum
235 QCOMPARE( editor->value( ), editor->minimum() );
236 QCOMPARE( editor2->value( ), editor2->minimum() );
237
238 }
239
test_setDoubleLimits()240 void TestQgsRangeWidgetWrapper::test_setDoubleLimits()
241 {
242 // Same test but check double numeric limits
243 QVariantMap cfg;
244 cfg.insert( QStringLiteral( "Min" ), std::numeric_limits<double>::lowest() );
245 cfg.insert( QStringLiteral( "Max" ), std::numeric_limits<double>::max() );
246 cfg.insert( QStringLiteral( "Step" ), 1 );
247 widget1->setConfig( cfg );
248 QgsDoubleSpinBox *editor = qobject_cast<QgsDoubleSpinBox *>( widget1->createWidget( nullptr ) );
249 QVERIFY( editor );
250 widget1->initWidget( editor );
251
252 widget2->setConfig( cfg );
253 QgsDoubleSpinBox *editor2 = qobject_cast<QgsDoubleSpinBox *>( widget2->createWidget( nullptr ) );
254 QVERIFY( editor2 );
255 widget2->initWidget( editor2 );
256
257 QCOMPARE( editor->minimum( ), std::numeric_limits<double>::lowest() );
258 QCOMPARE( editor2->minimum( ), std::numeric_limits<double>::lowest() );
259 QCOMPARE( editor->maximum( ), std::numeric_limits<double>::max() );
260 QCOMPARE( editor2->maximum( ), std::numeric_limits<double>::max() );
261
262 const QgsFeature feat( vl->getFeature( 1 ) );
263 QVERIFY( feat.isValid() );
264 QCOMPARE( feat.attribute( 1 ).toDouble(), 123.123456789 );
265 widget1->setFeature( vl->getFeature( 1 ) );
266 widget2->setFeature( vl->getFeature( 1 ) );
267
268 QCOMPARE( vl->fields().at( 1 ).precision(), 9 );
269 // Default is 0 !!! for double, really ?
270 QCOMPARE( vl->fields().at( 2 ).precision(), 0 );
271 QCOMPARE( editor->decimals(), vl->fields().at( 1 ).precision() );
272 QCOMPARE( editor2->decimals(), vl->fields().at( 2 ).precision() );
273 QCOMPARE( editor->value( ), 123.123456789 );
274 QCOMPARE( editor2->value( ), 123.0 );
275
276 // NULL, NULL
277 widget1->setFeature( vl->getFeature( 2 ) );
278 widget2->setFeature( vl->getFeature( 2 ) );
279 QCOMPARE( editor->value( ), editor->minimum() );
280 QCOMPARE( editor2->value( ), editor2->minimum() );
281
282 // negative, negative
283 widget1->setFeature( vl->getFeature( 3 ) );
284 widget2->setFeature( vl->getFeature( 3 ) );
285 // value was changed to the minimum
286 QCOMPARE( editor->value( ), -123.123456789 );
287 QCOMPARE( editor2->value( ), -123.0 );
288
289 }
290
test_nulls()291 void TestQgsRangeWidgetWrapper::test_nulls()
292 {
293 QgsApplication::setNullRepresentation( QString( "" ) );
294
295 QVariantMap cfg;
296 cfg.insert( QStringLiteral( "Min" ), 100.00 );
297 cfg.insert( QStringLiteral( "Max" ), 200.00 );
298 cfg.insert( QStringLiteral( "Step" ), 1 );
299 cfg.insert( QStringLiteral( "Precision" ), 0 );
300 widget1->setConfig( cfg );
301 QgsDoubleSpinBox *editor1 = qobject_cast<QgsDoubleSpinBox *>( widget1->createWidget( nullptr ) );
302 QVERIFY( editor1 );
303 widget1->initWidget( editor1 );
304 // Out of range
305 widget1->setFeature( vl->getFeature( 3 ) );
306 QCOMPARE( editor1->value( ), editor1->minimum() );
307 QCOMPARE( widget1->value( ), QVariant( QVariant::Double ) );
308 widget1->setFeature( QgsFeature( vl->fields() ) );
309 // Null
310 QCOMPARE( editor1->value( ), editor1->minimum() );
311 QCOMPARE( widget1->value( ), QVariant( QVariant::Double ) );
312 QCOMPARE( editor1->mLineEdit->text(), SPECIAL_TEXT_WHEN_EMPTY );
313 editor1->mLineEdit->setText( QString( "151%1" ).arg( SPECIAL_TEXT_WHEN_EMPTY ) );
314 QCOMPARE( widget1->value( ).toInt(), 151 );
315 editor1->mLineEdit->setText( QString( SPECIAL_TEXT_WHEN_EMPTY ).append( QStringLiteral( "161" ) ) );
316 QCOMPARE( widget1->value( ).toInt(), 161 );
317
318
319 QgsSpinBox *editor0 = qobject_cast<QgsSpinBox *>( widget0->createWidget( nullptr ) );
320 QVERIFY( editor0 );
321 widget0->setConfig( cfg );
322 widget0->initWidget( editor0 );
323 // Out of range
324 widget0->setFeature( vl->getFeature( 3 ) );
325 QCOMPARE( editor0->value( ), editor0->minimum() );
326 QCOMPARE( widget0->value( ), QVariant( QVariant::Int ) );
327 widget0->setFeature( QgsFeature( vl->fields() ) );
328 // Null
329 QCOMPARE( editor0->value( ), editor0->minimum() );
330 QCOMPARE( widget0->value( ), QVariant( QVariant::Int ) );
331 QCOMPARE( editor0->mLineEdit->text(), SPECIAL_TEXT_WHEN_EMPTY );
332
333 editor0->mLineEdit->setText( QString( "150%1" ).arg( SPECIAL_TEXT_WHEN_EMPTY ) );
334 QCOMPARE( widget0->value( ).toInt(), 150 );
335 editor0->mLineEdit->setText( QString( SPECIAL_TEXT_WHEN_EMPTY ).append( QStringLiteral( "160" ) ) );
336 QCOMPARE( widget0->value( ).toInt(), 160 );
337
338 }
339
test_negativeIntegers()340 void TestQgsRangeWidgetWrapper::test_negativeIntegers()
341 {
342 QgsApplication::setNullRepresentation( QString( "" ) );
343
344 QVariantMap cfg;
345 widget3->setConfig( cfg );
346
347 QgsSpinBox *editor3 = qobject_cast<QgsSpinBox *>( widget3->createWidget( nullptr ) );
348 QVERIFY( editor3 );
349 widget3->initWidget( editor3 );
350
351 QgsFeature feature { vl->getFeature( 3 ) };
352 feature.setAttribute( 3, -12345 );
353
354 widget3->setFeature( feature );
355 QCOMPARE( widget3->value( ).toInt(), -12345 );
356
357 cfg.insert( QStringLiteral( "Min" ), 10 );
358 widget3->setConfig( cfg );
359 widget3->initWidget( editor3 );
360 widget3->setFeature( feature );
361 QVERIFY( widget3->value().isNull() );
362 QCOMPARE( widget3->value( ).toInt(), 0 );
363
364 cfg.clear();
365 cfg.insert( QStringLiteral( "Min" ), -12346 );
366 widget3->setConfig( cfg );
367 widget3->initWidget( editor3 );
368 widget3->setFeature( feature );
369 QCOMPARE( widget3->value( ).toInt(), -12345 );
370
371 }
372
test_focus()373 void TestQgsRangeWidgetWrapper::test_focus()
374 {
375 QgsApplication::setNullRepresentation( QString( "nope" ) );
376
377 QWidget *w = new QWidget(); //required for focus events
378 QApplication::setActiveWindow( w );
379
380 QVariantMap cfg;
381 cfg.insert( QStringLiteral( "AllowNull" ), true );
382
383 //QgsDoubleSpinBox
384 widget1->setConfig( cfg );
385 QgsDoubleSpinBox *editor1 = qobject_cast<QgsDoubleSpinBox *>( widget1->createWidget( w ) );
386 QVERIFY( editor1 );
387 widget1->initWidget( editor1 );
388 widget1->setValue( QVariant( QVariant::Double ) );
389
390 //QgsDoubleSpinBox
391 widget2->setConfig( cfg );
392 QgsDoubleSpinBox *editor2 = qobject_cast<QgsDoubleSpinBox *>( widget2->createWidget( w ) );
393 QVERIFY( editor2 );
394 widget2->initWidget( editor2 );
395 widget2->setValue( QVariant( QVariant::Double ) );
396
397 //QgsSpinBox
398 widget3->setConfig( cfg );
399 QgsSpinBox *editor3 = qobject_cast<QgsSpinBox *>( widget3->createWidget( w ) );
400 QVERIFY( editor3 );
401 widget3->initWidget( editor3 );
402 widget3->setValue( QVariant( QVariant::Int ) );
403
404 QVERIFY( widget1->value().isNull() );
405 QVERIFY( widget2->value().isNull() );
406 QVERIFY( widget3->value().isNull() );
407 QVERIFY( !editor1->mLineEdit->hasFocus() );
408 QVERIFY( !editor2->mLineEdit->hasFocus() );
409 QVERIFY( !editor3->mLineEdit->hasFocus() );
410 QCOMPARE( editor1->mLineEdit->text(), QStringLiteral( "nope" ) );
411 QCOMPARE( editor2->mLineEdit->text(), QStringLiteral( "nope" ) );
412 QCOMPARE( editor3->mLineEdit->text(), QStringLiteral( "nope" ) );
413
414 editor1->mLineEdit->setFocus();
415 QVERIFY( widget1->value().isNull() );
416 QVERIFY( widget2->value().isNull() );
417 QVERIFY( widget3->value().isNull() );
418 QVERIFY( editor1->mLineEdit->hasFocus() );
419 QVERIFY( !editor2->mLineEdit->hasFocus() );
420 QVERIFY( !editor3->mLineEdit->hasFocus() );
421 QCOMPARE( editor1->mLineEdit->text(), QString() );
422 QCOMPARE( editor2->mLineEdit->text(), QStringLiteral( "nope" ) );
423 QCOMPARE( editor3->mLineEdit->text(), QStringLiteral( "nope" ) );
424
425 editor2->mLineEdit->setFocus();
426 QVERIFY( widget1->value().isNull() );
427 QVERIFY( widget2->value().isNull() );
428 QVERIFY( widget3->value().isNull() );
429 QVERIFY( !editor1->mLineEdit->hasFocus() );
430 QVERIFY( editor2->mLineEdit->hasFocus() );
431 QVERIFY( !editor3->mLineEdit->hasFocus() );
432 QCOMPARE( editor1->mLineEdit->text(), QStringLiteral( "nope" ) );
433 QCOMPARE( editor2->mLineEdit->text(), QString() );
434 QCOMPARE( editor3->mLineEdit->text(), QStringLiteral( "nope" ) );
435
436 editor3->mLineEdit->setFocus();
437 QVERIFY( widget1->value().isNull() );
438 QVERIFY( widget2->value().isNull() );
439 QVERIFY( widget3->value().isNull() );
440 QVERIFY( !editor1->mLineEdit->hasFocus() );
441 QVERIFY( !editor2->mLineEdit->hasFocus() );
442 QVERIFY( editor3->mLineEdit->hasFocus() );
443 QCOMPARE( editor1->mLineEdit->text(), QStringLiteral( "nope" ) );
444 QCOMPARE( editor2->mLineEdit->text(), QStringLiteral( "nope" ) );
445 QCOMPARE( editor3->mLineEdit->text(), QStringLiteral( "" ) );
446
447 editor1->mLineEdit->setFocus();
448 editor1->mLineEdit->setText( QString( "151.000000000" ) );
449 QVERIFY( !widget1->value().isNull() );
450 QVERIFY( widget2->value().isNull() );
451 QVERIFY( widget3->value().isNull() );
452 QVERIFY( editor1->mLineEdit->hasFocus() );
453 QVERIFY( !editor2->mLineEdit->hasFocus() );
454 QVERIFY( !editor3->mLineEdit->hasFocus() );
455 QCOMPARE( editor1->mLineEdit->text(), QStringLiteral( "151.000000000" ) );
456 QCOMPARE( editor2->mLineEdit->text(), QStringLiteral( "nope" ) );
457 QCOMPARE( editor3->mLineEdit->text(), QStringLiteral( "nope" ) );
458
459 editor2->mLineEdit->setFocus();
460 QVERIFY( widget0->value().isNull() );
461 QVERIFY( !widget1->value().isNull() );
462 QVERIFY( widget2->value().isNull() );
463 QVERIFY( !editor1->mLineEdit->hasFocus() );
464 QVERIFY( editor2->mLineEdit->hasFocus() );
465 QVERIFY( !editor3->mLineEdit->hasFocus() );
466 QCOMPARE( editor1->mLineEdit->text(), QStringLiteral( "151.000000000" ) );
467 QCOMPARE( editor2->mLineEdit->text(), QString() );
468 QCOMPARE( editor3->mLineEdit->text(), QStringLiteral( "nope" ) );
469
470 }
471
testLongLong()472 void TestQgsRangeWidgetWrapper::testLongLong()
473 {
474 // test range widget with a long long field type
475 std::unique_ptr< QgsRangeWidgetWrapper >wrapper = std::make_unique<QgsRangeWidgetWrapper>( vl.get(), 4, nullptr, nullptr );
476
477 // should use a double spin box, as a integer spin box does not have sufficient range
478 QgsDoubleSpinBox *editor = qobject_cast<QgsDoubleSpinBox *>( wrapper->createWidget( nullptr ) );
479 QVERIFY( editor );
480 wrapper->initWidget( editor );
481 // no decimals, it's for long long value editing!
482 QCOMPARE( editor->decimals(), 0 );
483 QCOMPARE( editor->minimum( ), std::numeric_limits<double>::lowest() );
484 QCOMPARE( editor->maximum( ), std::numeric_limits<double>::max() );
485
486 wrapper->setValue( 1234567890123LL );
487
488 // double spin box value should be lossless
489 QCOMPARE( editor->value(), 1234567890123.0 );
490
491 // wrapper value must be a long long type, not double
492 QCOMPARE( wrapper->value(), 1234567890123LL );
493 }
494
495 QGSTEST_MAIN( TestQgsRangeWidgetWrapper )
496 #include "testqgsrangewidgetwrapper.moc"
497