File indexing completed on 2024-04-28 03:45:18
0001 /* 0002 SPDX-FileCopyrightText: 2016 Akarsh Simha <akarsh.simha@kdemail.net> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "testcachingdms.h" 0008 0009 #include "auxiliary/cachingdms.h" 0010 0011 #include <QTest> 0012 0013 #include <ctime> 0014 #include <cstdlib> 0015 #include <cstdint> 0016 0017 TestCachingDms::TestCachingDms() : QObject() 0018 { 0019 } 0020 0021 void TestCachingDms::defaultCtor() 0022 { 0023 /* 0024 * Test 1: Check Default Constructor 0025 */ 0026 0027 // Check default empty constructor 0028 CachingDms d; 0029 QVERIFY(std::isnan(d.Degrees())); 0030 QVERIFY(std::isnan(d.sin())); 0031 QVERIFY(std::isnan(d.cos())); 0032 } 0033 0034 void TestCachingDms::explicitSexigesimalCtor() 0035 { 0036 /* 0037 * Test 2: Checks Sexigesimal Ctor 0038 */ 0039 0040 // DD:MM:SS 0041 // 14:55:20 0042 0043 CachingDms d(14, 55, 20); 0044 0045 QVERIFY(d.degree() == 14); 0046 QVERIFY(d.arcmin() == 55); 0047 QVERIFY(d.arcsec() == 20); 0048 QVERIFY(qFuzzyCompare(d.Degrees(), (14.0 + 55.0 / 60.0 + 20.0 / 3600.0))); 0049 QVERIFY(fabs(d.sin() - .25750758368074941632) < 1e-9); 0050 QVERIFY(fabs(d.cos() - .96627627744186177805) < 1e-9); 0051 } 0052 0053 void TestCachingDms::angleCtor() 0054 { 0055 /* 0056 * Test 3: Checks Angle Ctor 0057 */ 0058 0059 // Angle = -112.56 Degrees ---> HMS (16:29:45) 0060 0061 double angle = -112.56; 0062 0063 CachingDms d(angle); 0064 0065 QVERIFY(d.degree() == (int)angle); 0066 0067 QVERIFY(qFuzzyCompare(d.Hours(), (angle + 360) / 15.0)); 0068 QVERIFY(d.hour() == 16); 0069 QVERIFY(d.minute() == 29); 0070 QVERIFY(d.second() == 45); 0071 QVERIFY(fabs(d.sin() + 0.92347828085768229015) < 1e-9); 0072 QVERIFY(fabs(d.cos() + 0.38365070674265630377) < 1e-9); 0073 } 0074 0075 void TestCachingDms::stringCtor() 0076 { 0077 QString hms("14:55:20"); 0078 0079 // From Degree 0080 CachingDms d(hms); 0081 0082 QVERIFY(d.degree() == 14); 0083 QVERIFY(d.arcmin() == 55); 0084 QVERIFY(d.arcsec() == 20); 0085 QVERIFY(qFuzzyCompare(d.Degrees(), (14.0 + 55.0 / 60.0 + 20.0 / 3600.0))); 0086 QVERIFY(fabs(d.sin() - .25750758368074941632) < 1e-9); 0087 QVERIFY(fabs(d.cos() - .96627627744186177805) < 1e-9); 0088 0089 // From Hours 0090 CachingDms h(hms, false); 0091 QVERIFY(qFuzzyCompare(h.Degrees(), d.Degrees() * 15.0)); 0092 QVERIFY(qFuzzyCompare(h.Hours(), d.Degrees())); 0093 } 0094 0095 void TestCachingDms::setUsing_asin() 0096 { 0097 // Test case in first quadrant: 56.3 degrees 0098 CachingDms d; 0099 d.setUsing_asin(.83195412213048254606); 0100 QVERIFY(fabs(d.Degrees() - 56.3) < 1e-7); 0101 QVERIFY(fabs(d.cos() - .55484442744799927555) < 1e-9); 0102 0103 // Test case in fourth quadrant: -56.3 degrees 0104 d.setUsing_asin(-.83195412213048254606); 0105 QVERIFY(fabs(d.Degrees() + 56.3) < 1e-7); 0106 QVERIFY(fabs(d.cos() - .55484442744799927555) < 1e-9); 0107 } 0108 0109 void TestCachingDms::setUsing_acos() 0110 { 0111 CachingDms d; 0112 0113 // Test case in first quadrant: 56.3 degrees 0114 d.setUsing_acos(.55484442744799927555); 0115 QVERIFY(fabs(d.Degrees() - 56.3) < 1e-7); 0116 QVERIFY(fabs(d.sin() - .83195412213048254606) < 1e-9); 0117 0118 // Test case in second quadrant: 123.7 degrees 0119 d.setUsing_acos(-0.55484442744799927555); 0120 QVERIFY(fabs(d.Degrees() - 123.7) < 1e-7); 0121 QVERIFY(fabs(d.sin() - .83195412213048254606) < 1e-9); 0122 } 0123 0124 void TestCachingDms::setUsing_atan2() 0125 { 0126 // Test case in first quadrant: 56.3 degrees 0127 CachingDms d; 0128 d.setUsing_atan2(2.73701935509448143467, 1.82536500102022632674); 0129 QVERIFY(fabs(d.Degrees() - 56.3) < 1e-7); 0130 QVERIFY(fabs(d.sin() - .83195412213048254606) < 1e-9); 0131 QVERIFY(fabs(d.cos() - .55484442744799927555) < 1e-9); 0132 0133 // Test case in third quadrant: -123.7 degrees 0134 d.setUsing_atan2(-2.73701935509448143467, -1.82536500102022632674); 0135 QVERIFY(fabs(d.Degrees() + 123.7) < 1e-7); 0136 QVERIFY(fabs(d.sin() + .83195412213048254606) < 1e-9); 0137 QVERIFY(fabs(d.cos() + .55484442744799927555) < 1e-9); 0138 0139 // Test case in second quadrant: 123.7 degrees 0140 d.setUsing_atan2(2.73701935509448143467, -1.82536500102022632674); 0141 QVERIFY(fabs(d.Degrees() - 123.7) < 1e-7); 0142 QVERIFY(fabs(d.sin() - .83195412213048254606) < 1e-9); 0143 QVERIFY(fabs(d.cos() + .55484442744799927555) < 1e-9); 0144 0145 // Test case in fourth quadrant: -56.3 degrees 0146 d.setUsing_atan2(-2.73701935509448143467, +1.82536500102022632674); 0147 QVERIFY(fabs(d.Degrees() + 56.3) < 1e-7); 0148 QVERIFY(fabs(d.sin() + .83195412213048254606) < 1e-9); 0149 QVERIFY(fabs(d.cos() - .55484442744799927555) < 1e-9); 0150 0151 // Edge case test: angle = 0 0152 d.setUsing_atan2(0., 1.33); 0153 QVERIFY(fabs(d.Degrees() - 0.) < 1e-7); 0154 QVERIFY(fabs(d.sin() - 0.) < 1e-9); 0155 QVERIFY(fabs(d.cos() - 1.) < 1e-9); 0156 0157 // Edge case test: angle = 90 degrees 0158 d.setUsing_atan2(10.12, 0.); 0159 QVERIFY(fabs(d.Degrees() - 90.) < 1e-7); 0160 QVERIFY(fabs(d.sin() - 1.) < 1e-9); 0161 QVERIFY(fabs(d.cos() - 0.) < 1e-9); 0162 0163 // Edge case test: angle = -90 degrees 0164 d.setUsing_atan2(-3.1415, 0.); 0165 QVERIFY(fabs(d.Degrees() + 90.) < 1e-7); 0166 QVERIFY(fabs(d.sin() + 1.) < 1e-9); 0167 QVERIFY(fabs(d.cos() - 0.) < 1e-9); 0168 0169 // Edge case test: angle = 180 degrees 0170 d.setUsing_atan2(0., -724.); 0171 QVERIFY(fabs(d.Degrees() - 180.) < 1e-7); 0172 QVERIFY(fabs(d.sin() - 0.) < 1e-9); 0173 QVERIFY(fabs(d.cos() + 1.) < 1e-9); 0174 } 0175 0176 void TestCachingDms::unaryMinusOperator() 0177 { 0178 CachingDms d(56.3); 0179 qDebug() << (-d).Degrees(); 0180 QVERIFY(qFuzzyCompare((-d).Degrees(), -56.3)); 0181 QVERIFY(qFuzzyCompare((-d).cos(), d.cos())); 0182 QVERIFY(qFuzzyCompare((-d).sin(), -d.sin())); 0183 } 0184 0185 void TestCachingDms::additionOperator() 0186 { 0187 const double a = 123.7; 0188 const double b = 89.5; 0189 CachingDms d1(a); 0190 CachingDms d2(b); 0191 CachingDms ds = d1 + d2; 0192 const double sinapb = std::sin((a + b) * dms::DegToRad); 0193 const double cosapb = std::cos((a + b) * dms::DegToRad); 0194 QVERIFY(fabs(ds.sin() - sinapb) < 1e-9); 0195 QVERIFY(fabs(ds.cos() - cosapb) < 1e-9); 0196 0197 const double c = -34.7; 0198 const double d = 233.6; 0199 CachingDms d3(c); 0200 CachingDms d4(d); 0201 CachingDms ds2 = d3 + d4; 0202 const double sincpd = std::sin((c + d) * dms::DegToRad); 0203 const double coscpd = std::cos((c + d) * dms::DegToRad); 0204 QVERIFY(fabs(ds2.sin() - sincpd) < 1e-9); 0205 QVERIFY(fabs(ds2.cos() - coscpd) < 1e-9); 0206 } 0207 0208 void TestCachingDms::subtractionOperator() 0209 { 0210 const double a = 123.7; 0211 const double b = 89.5; 0212 CachingDms d1(a); 0213 CachingDms d2(b); 0214 CachingDms ds = d1 - d2; 0215 const double sinamb = std::sin((a - b) * dms::DegToRad); 0216 const double cosamb = std::cos((a - b) * dms::DegToRad); 0217 QVERIFY(fabs(ds.sin() - sinamb) < 1e-9); 0218 QVERIFY(fabs(ds.cos() - cosamb) < 1e-9); 0219 0220 const double c = -34.7; 0221 const double d = 233.6; 0222 CachingDms d3(c); 0223 CachingDms d4(d); 0224 CachingDms ds2 = d3 - d4; 0225 const double sincmd = std::sin((c - d) * dms::DegToRad); 0226 const double coscmd = std::cos((c - d) * dms::DegToRad); 0227 QVERIFY(fabs(ds2.sin() - sincmd) < 1e-9); 0228 QVERIFY(fabs(ds2.cos() - coscmd) < 1e-9); 0229 } 0230 0231 void TestCachingDms::testFailsafeUseOfBaseClassPtr() 0232 { 0233 typedef union angle { 0234 double x; 0235 int64_t y; 0236 } angle; 0237 const int testCases = 5000; 0238 std::srand(std::time(nullptr)); 0239 for (int k = 0; k < testCases; ++k) 0240 { 0241 angle a { 0 }; 0242 CachingDms _a; 0243 dms __a; 0244 a.y = std::rand(); 0245 _a.setD(a.x); 0246 __a.setD(a.x); 0247 dms *d; 0248 if (std::rand() % 10 > 5) 0249 d = &_a; 0250 else 0251 d = &__a; 0252 angle b; 0253 b.y = std::rand(); 0254 switch (std::rand() % 7) 0255 { 0256 case 0: 0257 d->setD(b.x); 0258 break; 0259 case 1: 0260 d->setH(b.x / 15.); 0261 break; 0262 case 2: 0263 { 0264 dms x(b.x); 0265 d->setD(x.degree(), x.arcmin(), x.arcsec(), x.marcsec()); 0266 break; 0267 } 0268 case 3: 0269 { 0270 dms x(b.x); 0271 d->setFromString(x.toDMSString()); 0272 break; 0273 } 0274 case 4: 0275 { 0276 dms x(b.x); 0277 d->setFromString(x.toHMSString(), false); 0278 break; 0279 } 0280 case 5: 0281 { 0282 dms x(b.x); 0283 dms y(0.0); 0284 *d = x + y; 0285 break; 0286 } 0287 case 6: 0288 default: 0289 d->setRadians(b.x * dms::DegToRad); 0290 break; 0291 } 0292 QVERIFY(fabs(d->sin() - sin(b.x * dms::DegToRad)) < 1e-12); 0293 QVERIFY(fabs(d->cos() - cos(b.x * dms::DegToRad)) < 1e-12); 0294 } 0295 } 0296 0297 QTEST_GUILESS_MAIN(TestCachingDms)