1 /***************************************************************************
2     testqgsdoublespinbox.cpp
3      --------------------------------------
4     Date                 : June 2020
5     Copyright            : (C) 2020 Sebastien Peillet
6     Email                : sebastien dot peillet at oslandia 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 "qgsdoublevalidator.h"
20 #include <QLineEdit>
21 
22 class TestQgsDoubleValidator: public QObject
23 {
24     Q_OBJECT
25   private slots:
26     void initTestCase(); // will be called before the first testfunction is executed.
27     void cleanupTestCase(); // will be called after the last testfunction was executed.
28     void init(); // will be called before each testfunction is executed.
29     void cleanup(); // will be called after every testfunction.
30 
31     void validate();
32     void validate_data();
33     void toDouble_data();
34     void toDouble();
35 
36   private:
37 
38 };
39 
initTestCase()40 void TestQgsDoubleValidator::initTestCase()
41 {
42 
43 }
44 
cleanupTestCase()45 void TestQgsDoubleValidator::cleanupTestCase()
46 {
47 }
48 
init()49 void TestQgsDoubleValidator::init()
50 {
51 }
52 
cleanup()53 void TestQgsDoubleValidator::cleanup()
54 {
55 }
56 
validate_data()57 void TestQgsDoubleValidator::validate_data()
58 {
59   QTest::addColumn<QString>( "actualState" );
60   QTest::addColumn<int>( "expState" );
61 
62   QTest::newRow( "C decimal" ) << QString( "4cd6" ) << int( QValidator::Acceptable );
63   QTest::newRow( "locale decimal" ) << QString( "4ld6" ) << int( QValidator::Acceptable );
64   QTest::newRow( "locale decimal" ) << QString( "4444ld6" ) << int( QValidator::Acceptable );
65 
66   // QgsDoubleValidator doesn't expect group separator but it tolerates it,
67   // so the result will be QValidator::Intermediate and not QValidator::Acceptable
68   QTest::newRow( "locale group separator + locale decimal" ) << QString( "4lg444ld6" ) << int( QValidator::Intermediate );
69   QTest::newRow( "locale group separator + c decimal" ) << QString( "4lg444cd6" ) << int( QValidator::Invalid );
70   QTest::newRow( "c group separator + locale decimal" ) << QString( "4cg444ld6" ) << int( QValidator::Invalid );
71   QTest::newRow( "c group separator + c decimal" ) << QString( "4cg444cd6" ) << int( QValidator::Intermediate );
72 
73   QTest::newRow( "outside the range + local decimal" ) << QString( "3ld6" ) << int( QValidator::Intermediate );
74   QTest::newRow( "outside the range + c decimal" ) << QString( "3cd6" ) << int( QValidator::Intermediate );
75   QTest::newRow( "string" ) << QString( "string" ) << int( QValidator::Invalid );
76 
77 }
78 
toDouble_data()79 void TestQgsDoubleValidator::toDouble_data()
80 {
81   QTest::addColumn<QString>( "actualValue" );
82   QTest::addColumn<double>( "expValue" );
83 
84   QTest::newRow( "C decimal" ) << QString( "4cd6" ) << 4.6;
85   QTest::newRow( "locale decimal" ) << QString( "4ld6" ) << 4.6;
86   QTest::newRow( "locale decimal" ) << QString( "4444ld6" ) << 4444.6;
87 
88   // QgsDoubleValidator doesn't expect group separator but it tolerates it,
89   // so the result will be QValidator::Intermediate and not QValidator::Acceptable
90   QTest::newRow( "locale group separator + locale decimal" ) << QString( "4lg444ld6" ) << 4444.6;
91   QTest::newRow( "locale group separator + c decimal" ) << QString( "4lg444cd6" ) << 0.0;
92   QTest::newRow( "c group separator + locale decimal" ) << QString( "4cg444ld6" ) << 0.0;
93   QTest::newRow( "c group separator + c decimal" ) << QString( "4cg444cd6" ) << 4444.6;
94 
95   QTest::newRow( "outside the range + local decimal" ) << QString( "3ld6" ) << 3.6;
96   QTest::newRow( "outside the range + c decimal" ) << QString( "3cd6" ) << 3.6;
97   QTest::newRow( "string" ) << QString( "string" ) << 0.0;
98 
99 }
100 
validate()101 void TestQgsDoubleValidator::validate()
102 {
103   QLineEdit *lineEdit = new QLineEdit();
104   QgsDoubleValidator *validator = new QgsDoubleValidator( 4, 10000, lineEdit );
105   lineEdit->setValidator( validator );
106 
107   QFETCH( QString, actualState );
108   QFETCH( int, expState );
109   QString value;
110   int expectedValue;
111 
112   const QVector<QLocale>listLocale( {QLocale::English, QLocale::French, QLocale::German, QLocale::Italian} );
113   QLocale loc;
114   for ( int i = 0; i < listLocale.count(); ++i )
115   {
116     loc = listLocale.at( i );
117     QLocale::setDefault( loc );
118     validator->setLocale( loc );
119     value = actualState;
120     value = value.replace( "ld", QLocale().decimalPoint() )
121             .replace( "cd", QLocale( QLocale::C ).decimalPoint() )
122             .replace( "lg", QLocale().groupSeparator() )
123             .replace( "cg", QLocale( QLocale::C ).groupSeparator() );
124     expectedValue = expState;
125     // if the local group separator / decimal point is equal to the C one,
126     // expected result will be different for double with test with mixed
127     // local/C characters.
128     // Example with lg as local group separator
129     //              cg as C group separator
130     //              ld as local decimal point
131     //              cd as C decimal point
132     // for 4cg444ld6 double, if cg == lg then 4cg444ld6 == 4lg444ld6
133     //                       and validator->validate(4lg444ld6) == 1 and not 0
134     // for 4cg444ld6 double, if cd == ld then 4cg444ld6 == 4cg444cd6
135     //                       and validator->validate(4cg444cd6) == 1 and not 0
136     if ( ( QLocale( QLocale::C ).groupSeparator() == QLocale().groupSeparator() ||
137            QLocale( QLocale::C ).decimalPoint() == QLocale().decimalPoint() )
138          && value != "string" && expectedValue == 0 )
139       expectedValue = 1;
140     QCOMPARE( int( validator->validate( value ) ), expectedValue );
141   }
142 }
143 
toDouble()144 void TestQgsDoubleValidator::toDouble()
145 {
146   QFETCH( QString, actualValue );
147   QFETCH( double, expValue );
148   QString value;
149   double expectedValue;
150 
151   const QVector<QLocale>listLocale( {QLocale::English, QLocale::French, QLocale::German, QLocale::Italian} );
152   QLocale loc;
153   for ( int i = 0; i < listLocale.count(); ++i )
154   {
155     loc = listLocale.at( i );
156     QLocale::setDefault( loc );
157     value = actualValue;
158     value = value.replace( "ld", QLocale().decimalPoint() )
159             .replace( "cd", QLocale( QLocale::C ).decimalPoint() )
160             .replace( "lg", QLocale().groupSeparator() )
161             .replace( "cg", QLocale( QLocale::C ).groupSeparator() );
162     expectedValue = expValue;
163     // if the local group separator / decimal point is equal to the C one,
164     // expected result will be different for double with test with mixed
165     // local/C characters.
166     // Example with lg as local group separator
167     //              cg as C group separator
168     //              ld as local decimal point
169     //              cd as C group decimal point
170     // for 4cg444ld6 double, if cg == lg then 4cg444ld6 == 4lg444ld6
171     //                       and QgsDoubleValidator::toDouble(4lg444ld6) == 4444.6 and not 0.0
172     // for 4cg444ld6 double, if cd == ld then 4cg444ld6 == 4cg444cd6
173     //                       and QgsDoubleValidator::toDouble(4cg444cd6) == 4444.6 and not 0.0
174     if ( ( QLocale( QLocale::C ).groupSeparator() == QLocale().groupSeparator() ||
175            QLocale( QLocale::C ).decimalPoint() == QLocale().decimalPoint() )
176          && value != "string" && expectedValue == 0.0 )
177       expectedValue = 4444.6;
178 
179     QCOMPARE( QgsDoubleValidator::toDouble( value ), expectedValue );
180   }
181 
182 }
183 
184 QGSTEST_MAIN( TestQgsDoubleValidator )
185 #include "testqgsdoublevalidator.moc"
186