File indexing completed on 2024-04-28 15:11:57
0001 /* 0002 SPDX-FileCopyrightText: 2016 Jasem Mutlaq <mutlaqja@ikarustech.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "testdms.h" 0008 0009 #include "auxiliary/dms.h" 0010 0011 #include <QTest> 0012 0013 TestDMS::TestDMS() : QObject() 0014 { 0015 } 0016 0017 void TestDMS::defaultCtor() 0018 { 0019 /* 0020 * Test 1: Check Default Constructor 0021 */ 0022 0023 // Check default empty constructor 0024 dms d; 0025 QVERIFY(std::isnan(d.Degrees())); 0026 } 0027 0028 void TestDMS::explicitSexigesimalCtor() 0029 { 0030 /* 0031 * Test 2: Checks Sexigesimal Ctor 0032 */ 0033 0034 // HH:MM:SS 0035 // 14:55:20 0036 0037 dms d(14, 55, 20); 0038 0039 QVERIFY(d.degree() == 14); 0040 QVERIFY(d.arcmin() == 55); 0041 QVERIFY(d.arcsec() == 20); 0042 QVERIFY(qFuzzyCompare(d.Degrees(), (14.0 + 55.0 / 60.0 + 20.0 / 3600.0))); 0043 } 0044 0045 void TestDMS::angleCtor() 0046 { 0047 /* 0048 * Test 3: Checks Angle Ctor 0049 */ 0050 0051 // Angle = -112.56 Degrees ---> HMS (16:29:45) 0052 0053 double angle = -112.56; 0054 0055 dms d(angle); 0056 0057 QVERIFY(d.degree() == (int)angle); 0058 0059 QVERIFY(qFuzzyCompare(d.Hours(), (angle + 360) / 15.0)); 0060 QVERIFY(d.hour() == 16); 0061 QVERIFY(d.minute() == 29); 0062 QVERIFY(d.second() == 45); 0063 } 0064 0065 void TestDMS::stringCtor() 0066 { 0067 QString hms("14:55:20"); 0068 0069 // From Degree 0070 dms d(hms); 0071 0072 QVERIFY(d.degree() == 14); 0073 QVERIFY(d.arcmin() == 55); 0074 QVERIFY(d.arcsec() == 20); 0075 QVERIFY(qFuzzyCompare(d.Degrees(), (14.0 + 55.0 / 60.0 + 20.0 / 3600.0))); 0076 0077 // From Hours 0078 dms h(hms, false); 0079 QVERIFY(qFuzzyCompare(h.Degrees(), d.Degrees() * 15.0)); 0080 QVERIFY(qFuzzyCompare(h.Hours(), d.Degrees())); 0081 } 0082 0083 void TestDMS::testReduceToRange() 0084 { 0085 double base = 67.8; 0086 double a = 360.0 * 11. + base; 0087 double b = -360.0 * 12. + base; 0088 0089 dms d; 0090 d.setD(a); 0091 d.reduceToRange(dms::ZERO_TO_2PI); 0092 QVERIFY(fabs(d.Degrees() - base) < 1e-9); 0093 0094 d.setD(b); 0095 d.reduceToRange(dms::ZERO_TO_2PI); 0096 QVERIFY(fabs(d.Degrees() - base) < 1e-9); 0097 0098 d.setD(360.0); 0099 d.reduceToRange(dms::ZERO_TO_2PI); 0100 QVERIFY(fabs(d.Degrees() - 0.) < 1e-9); 0101 0102 double c = 180.0 * 13. + base; 0103 double e = 180.0 * 14. + base; 0104 double f = -180.0 * 15. + base; 0105 double g = -180.0 * 16. + base; 0106 0107 d.setD(c); 0108 d.reduceToRange(dms::MINUSPI_TO_PI); 0109 QVERIFY(fabs(d.Degrees() - (base - 180.0)) < 1e-9); 0110 0111 d.setD(e); 0112 d.reduceToRange(dms::MINUSPI_TO_PI); 0113 QVERIFY(fabs(d.Degrees() - base) < 1e-9); 0114 0115 d.setD(f); 0116 d.reduceToRange(dms::MINUSPI_TO_PI); 0117 QVERIFY(fabs(d.Degrees() - (base - 180.0)) < 1e-9); 0118 0119 d.setD(g); 0120 d.reduceToRange(dms::MINUSPI_TO_PI); 0121 QVERIFY(fabs(d.Degrees() - base) < 1e-9); 0122 } 0123 0124 void TestDMS::testSubstraction() 0125 { 0126 // Diff 359 and 1 0127 dms sub = dms(359) - dms(1); 0128 QVERIFY(sub.Degrees() == 358.); 0129 0130 // The reverse is -358 0131 sub = dms(1) - dms(359); 0132 QVERIFY(sub.Degrees() == -358.); 0133 0134 // Diff 100 and 300 0135 sub = dms(100) - dms(300); 0136 QVERIFY(sub.Degrees() == -200.0); 0137 0138 // Diff 310 and 110 should be 200 0139 sub = dms(310) - dms(110); 0140 QVERIFY(sub.Degrees() == 200.0); 0141 0142 // Diff 170 and 130 should be 40 0143 sub = dms(170) - dms(130); 0144 QVERIFY(sub.Degrees() == 40.0); 0145 0146 // Reverse is -40 0147 sub = dms(130) - dms(170); 0148 QVERIFY(sub.Degrees() == -40.0); 0149 } 0150 0151 void TestDMS::testDeltaAngle() 0152 { 0153 // Diff 359 and 1 should be 2 (shortest path normalized) 0154 dms sub = dms(359).deltaAngle(dms(1)); 0155 QVERIFY(sub.Degrees() == 2.); 0156 0157 // Diff 1 to 350 is -11 0158 sub = dms(1).deltaAngle(dms(350)); 0159 QVERIFY(sub.Degrees() == -11.); 0160 0161 // Diff 310 and 110 should be 160 0162 sub = dms(310).deltaAngle(dms(110)); 0163 QVERIFY(sub.Degrees() == 160.0); 0164 0165 // Diff 100 and 300 should be -160 (NOT -200) since 160 is the shorest path CCW 0166 sub = dms(100).deltaAngle(dms(300)); 0167 QVERIFY(sub.Degrees() == -160.0); 0168 } 0169 0170 void TestDMS::testUnitTransition() 0171 { 0172 // check for rounding/truncating errors around unit transition 0173 // in DMS and HMS angle representation strings 0174 dms sp; 0175 sp.setD(10.0 - 1.0E-14); 0176 QVERIFY(sp.degree() == 9); 0177 QVERIFY(sp.arcmin() == 59); 0178 QVERIFY(sp.arcsec() == 59); 0179 QVERIFY(sp.marcsec() == 999); 0180 0181 sp.setH(10.0 - 1.0E-14); 0182 QVERIFY(sp.hour() == 9); 0183 QVERIFY(sp.minute() == 59); 0184 QVERIFY(sp.second() == 59); 0185 QVERIFY(sp.msecond() == 999); 0186 0187 sp.setD(10.0); 0188 QVERIFY(sp.degree() == 10); 0189 QVERIFY(sp.arcmin() == 0); 0190 QVERIFY(sp.arcsec() == 0); 0191 QVERIFY(sp.marcsec() == 0); 0192 0193 sp.setH(10.0); 0194 QVERIFY(sp.hour() == 10); 0195 QVERIFY(sp.minute() == 0); 0196 QVERIFY(sp.second() == 0); 0197 QVERIFY(sp.msecond() == 0); 0198 0199 sp.setD(10.0 + 1.0E-14); 0200 QVERIFY(sp.degree() == 10); 0201 QVERIFY(sp.arcmin() == 0); 0202 QVERIFY(sp.arcsec() == 0); 0203 QVERIFY(sp.marcsec() == 0); 0204 0205 sp.setH(10.0 + 1.0E-14); 0206 QVERIFY(sp.hour() == 10); 0207 QVERIFY(sp.minute() == 0); 0208 QVERIFY(sp.second() == 0); 0209 QVERIFY(sp.msecond() == 0); 0210 } 0211 0212 void TestDMS::testPrecisionTransition() 0213 { 0214 // check for transitions in DMS and HMS angle representation strings 0215 // with respect to DMS and HMS precision around angle units 0216 dms sp; 0217 double half_precision_DMS = 1.0 / 7200.0; 0218 double half_precision_HMS = 15.0 / 7200.0; 0219 double epsilon = 0.000000001; 0220 0221 QLocale::setDefault(QLocale::c()); 0222 0223 // toDMSString 0224 0225 bool forceSign = false; 0226 bool machineReadable = false; 0227 bool highPrecision = false; 0228 0229 sp.setD(10.0 + half_precision_DMS + epsilon); 0230 QCOMPARE(sp.toDMSString( 0231 forceSign, machineReadable, highPrecision), QString(" 10° 00' 01\"")); 0232 sp.setD(10.0 + half_precision_DMS - epsilon); 0233 QCOMPARE(sp.toDMSString( 0234 forceSign, machineReadable, highPrecision), QString(" 10° 00' 00\"")); 0235 sp.setD(10.0 - half_precision_DMS + epsilon); 0236 QCOMPARE(sp.toDMSString( 0237 forceSign, machineReadable, highPrecision), QString(" 10° 00' 00\"")); 0238 sp.setD(10.0 - half_precision_DMS - epsilon); 0239 QCOMPARE(sp.toDMSString( 0240 forceSign, machineReadable, highPrecision), QString(" 09° 59' 59\"")); 0241 0242 sp.setD(-10.0 + half_precision_DMS + epsilon); 0243 QCOMPARE(sp.toDMSString( 0244 forceSign, machineReadable, highPrecision), QString("-09° 59' 59\"")); 0245 sp.setD(-10.0 + half_precision_DMS - epsilon); 0246 QCOMPARE(sp.toDMSString( 0247 forceSign, machineReadable, highPrecision), QString("-10° 00' 00\"")); 0248 sp.setD(-10.0 - half_precision_DMS + epsilon); 0249 QCOMPARE(sp.toDMSString( 0250 forceSign, machineReadable, highPrecision), QString("-10° 00' 00\"")); 0251 sp.setD(-10.0 - half_precision_DMS - epsilon); 0252 QCOMPARE(sp.toDMSString( 0253 forceSign, machineReadable, highPrecision), QString("-10° 00' 01\"")); 0254 0255 machineReadable = true; 0256 0257 for (int i=0; i < 2; i++) 0258 { 0259 sp.setD(10.0 + half_precision_DMS + epsilon); 0260 QCOMPARE(sp.toDMSString( 0261 forceSign, machineReadable, highPrecision), QString(" 10:00:01")); 0262 sp.setD(10.0 + half_precision_DMS - epsilon); 0263 QCOMPARE(sp.toDMSString( 0264 forceSign, machineReadable, highPrecision), QString(" 10:00:00")); 0265 sp.setD(10.0 - half_precision_DMS + epsilon); 0266 QCOMPARE(sp.toDMSString( 0267 forceSign, machineReadable, highPrecision), QString(" 10:00:00")); 0268 sp.setD(10.0 - half_precision_DMS - epsilon); 0269 QCOMPARE(sp.toDMSString( 0270 forceSign, machineReadable, highPrecision), QString(" 09:59:59")); 0271 0272 sp.setD(-10.0 + half_precision_DMS + epsilon); 0273 QCOMPARE(sp.toDMSString( 0274 forceSign, machineReadable, highPrecision), QString("-09:59:59")); 0275 sp.setD(-10.0 + half_precision_DMS - epsilon); 0276 QCOMPARE(sp.toDMSString( 0277 forceSign, machineReadable, highPrecision), QString("-10:00:00")); 0278 sp.setD(-10.0 - half_precision_DMS + epsilon); 0279 QCOMPARE(sp.toDMSString( 0280 forceSign, machineReadable, highPrecision), QString("-10:00:00")); 0281 sp.setD(-10.0 - half_precision_DMS - epsilon); 0282 QCOMPARE(sp.toDMSString( 0283 forceSign, machineReadable, highPrecision), QString("-10:00:01")); 0284 0285 highPrecision = true; 0286 } 0287 0288 machineReadable = false; 0289 0290 sp.setD(10.0 + half_precision_DMS + epsilon); 0291 QCOMPARE(sp.toDMSString( 0292 forceSign, machineReadable, highPrecision), QString(" 10° 00' 0.50\"")); 0293 sp.setD(10.0 + half_precision_DMS - epsilon); 0294 QCOMPARE(sp.toDMSString( 0295 forceSign, machineReadable, highPrecision), QString(" 10° 00' 0.50\"")); 0296 sp.setD(10.0 - half_precision_DMS + epsilon); 0297 QCOMPARE(sp.toDMSString( 0298 forceSign, machineReadable, highPrecision), QString(" 09° 59' 59.50\"")); 0299 sp.setD(10.0 - half_precision_DMS - epsilon); 0300 QCOMPARE(sp.toDMSString( 0301 forceSign, machineReadable, highPrecision), QString(" 09° 59' 59.50\"")); 0302 0303 sp.setD(-10.0 + half_precision_DMS + epsilon); 0304 QCOMPARE(sp.toDMSString( 0305 forceSign, machineReadable, highPrecision), QString("-09° 59' 59.50\"")); 0306 sp.setD(-10.0 + half_precision_DMS - epsilon); 0307 QCOMPARE(sp.toDMSString( 0308 forceSign, machineReadable, highPrecision), QString("-09° 59' 59.50\"")); 0309 sp.setD(-10.0 - half_precision_DMS + epsilon); 0310 QCOMPARE(sp.toDMSString( 0311 forceSign, machineReadable, highPrecision), QString("-10° 00' 0.50\"")); 0312 sp.setD(-10.0 - half_precision_DMS - epsilon); 0313 QCOMPARE(sp.toDMSString( 0314 forceSign, machineReadable, highPrecision), QString("-10° 00' 0.50\"")); 0315 0316 // toHMSString 0317 0318 highPrecision = false; 0319 0320 sp.setD(10.0 * 15.0 + half_precision_HMS + epsilon); 0321 QCOMPARE(sp.toHMSString( 0322 machineReadable, highPrecision),QString("10h 00m 01s")); 0323 sp.setD(10.0 * 15.0 + half_precision_HMS - epsilon); 0324 QCOMPARE(sp.toHMSString( 0325 machineReadable, highPrecision),QString("10h 00m 00s")); 0326 sp.setD(10.0 * 15.0 - half_precision_HMS + epsilon); 0327 QCOMPARE(sp.toHMSString( 0328 machineReadable, highPrecision),QString("10h 00m 00s")); 0329 sp.setD(10.0 * 15.0 - half_precision_HMS - epsilon); 0330 QCOMPARE(sp.toHMSString( 0331 machineReadable, highPrecision),QString("09h 59m 59s")); 0332 0333 sp.setD(-10.0 * 15.0 + half_precision_HMS + epsilon); 0334 QCOMPARE(sp.toHMSString( 0335 machineReadable, highPrecision),QString("14h 00m 01s")); 0336 sp.setD(-10.0 * 15.0 + half_precision_HMS - epsilon); 0337 QCOMPARE(sp.toHMSString( 0338 machineReadable, highPrecision),QString("14h 00m 00s")); 0339 sp.setD(-10.0 * 15.0 - half_precision_HMS + epsilon); 0340 QCOMPARE(sp.toHMSString( 0341 machineReadable, highPrecision),QString("14h 00m 00s")); 0342 sp.setD(-10.0 * 15.0 - half_precision_HMS - epsilon); 0343 QCOMPARE(sp.toHMSString( 0344 machineReadable, highPrecision),QString("13h 59m 59s")); 0345 0346 machineReadable = true; 0347 0348 for (int i=0; i < 2; i++) 0349 { 0350 sp.setD(10.0 * 15.0 + half_precision_HMS + epsilon); 0351 QCOMPARE(sp.toHMSString( 0352 machineReadable, highPrecision), QString("10:00:01")); 0353 sp.setD(10.0 * 15.0 + half_precision_HMS - epsilon); 0354 QCOMPARE(sp.toHMSString( 0355 machineReadable, highPrecision), QString("10:00:00")); 0356 sp.setD(10.0 * 15.0 - half_precision_HMS + epsilon); 0357 QCOMPARE(sp.toHMSString( 0358 machineReadable, highPrecision), QString("10:00:00")); 0359 sp.setD(10.0 * 15.0 - half_precision_HMS - epsilon); 0360 QCOMPARE(sp.toHMSString( 0361 machineReadable, highPrecision), QString("09:59:59")); 0362 0363 sp.setD(-10.0 * 15.0 + half_precision_HMS + epsilon); 0364 QCOMPARE(sp.toHMSString( 0365 machineReadable, highPrecision), QString("14:00:01")); 0366 sp.setD(-10.0 * 15.0 + half_precision_HMS - epsilon); 0367 QCOMPARE(sp.toHMSString( 0368 machineReadable, highPrecision), QString("14:00:00")); 0369 sp.setD(-10.0 * 15.0 - half_precision_HMS + epsilon); 0370 QCOMPARE(sp.toHMSString( 0371 machineReadable, highPrecision), QString("14:00:00")); 0372 sp.setD(-10.0 * 15.0 - half_precision_HMS - epsilon); 0373 QCOMPARE(sp.toHMSString( 0374 machineReadable, highPrecision), QString("13:59:59")); 0375 0376 highPrecision = true; 0377 } 0378 0379 machineReadable = false; 0380 0381 sp.setD(10.0 * 15.0 + half_precision_HMS + epsilon); 0382 QCOMPARE(sp.toHMSString( 0383 machineReadable, highPrecision),QString("10h 00m 0.50s")); 0384 sp.setD(10.0 * 15.0 + half_precision_HMS - epsilon); 0385 QCOMPARE(sp.toHMSString( 0386 machineReadable, highPrecision),QString("10h 00m 0.50s")); 0387 sp.setD(10.0 * 15.0 - half_precision_HMS + epsilon); 0388 QCOMPARE(sp.toHMSString( 0389 machineReadable, highPrecision),QString("09h 59m 59.50s")); 0390 sp.setD(10.0 * 15.0 - half_precision_HMS - epsilon); 0391 QCOMPARE(sp.toHMSString( 0392 machineReadable, highPrecision),QString("09h 59m 59.50s")); 0393 0394 sp.setD(-10.0 * 15.0 + half_precision_HMS + epsilon); 0395 QCOMPARE(sp.toHMSString( 0396 machineReadable, highPrecision),QString("14h 00m 0.50s")); 0397 sp.setD(-10.0 * 15.0 + half_precision_HMS - epsilon); 0398 QCOMPARE(sp.toHMSString( 0399 machineReadable, highPrecision),QString("14h 00m 0.50s")); 0400 sp.setD(-10.0 * 15.0 - half_precision_HMS + epsilon); 0401 QCOMPARE(sp.toHMSString( 0402 machineReadable, highPrecision),QString("13h 59m 59.50s")); 0403 sp.setD(-10.0 * 15.0 - half_precision_HMS - epsilon); 0404 QCOMPARE(sp.toHMSString( 0405 machineReadable, highPrecision),QString("13h 59m 59.50s")); 0406 0407 QLocale::setDefault(QLocale::system()); 0408 } 0409 0410 QTEST_GUILESS_MAIN(TestDMS)