1 /*
2 SPDX-FileCopyrightText: 2016 Akarsh Simha <akarsh.simha@kdemail.net>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "testcachingdms.h"
8
9 #include "auxiliary/cachingdms.h"
10
11 #include <QtTest>
12
13 #include <ctime>
14 #include <cstdlib>
15 #include <cstdint>
16
TestCachingDms()17 TestCachingDms::TestCachingDms() : QObject()
18 {
19 }
20
defaultCtor()21 void TestCachingDms::defaultCtor()
22 {
23 /*
24 * Test 1: Check Default Constructor
25 */
26
27 // Check default empty constructor
28 CachingDms d;
29 QVERIFY(std::isnan(d.Degrees()));
30 QVERIFY(std::isnan(d.sin()));
31 QVERIFY(std::isnan(d.cos()));
32 }
33
explicitSexigesimalCtor()34 void TestCachingDms::explicitSexigesimalCtor()
35 {
36 /*
37 * Test 2: Checks Sexigesimal Ctor
38 */
39
40 // DD:MM:SS
41 // 14:55:20
42
43 CachingDms d(14, 55, 20);
44
45 QVERIFY(d.degree() == 14);
46 QVERIFY(d.arcmin() == 55);
47 QVERIFY(d.arcsec() == 20);
48 QVERIFY(qFuzzyCompare(d.Degrees(), (14.0 + 55.0 / 60.0 + 20.0 / 3600.0)));
49 QVERIFY(fabs(d.sin() - .25750758368074941632) < 1e-9);
50 QVERIFY(fabs(d.cos() - .96627627744186177805) < 1e-9);
51 }
52
angleCtor()53 void TestCachingDms::angleCtor()
54 {
55 /*
56 * Test 3: Checks Angle Ctor
57 */
58
59 // Angle = -112.56 Degrees ---> HMS (16:29:45)
60
61 double angle = -112.56;
62
63 CachingDms d(angle);
64
65 QVERIFY(d.degree() == (int)angle);
66
67 QVERIFY(qFuzzyCompare(d.Hours(), (angle + 360) / 15.0));
68 QVERIFY(d.hour() == 16);
69 QVERIFY(d.minute() == 29);
70 QVERIFY(d.second() == 45);
71 QVERIFY(fabs(d.sin() + 0.92347828085768229015) < 1e-9);
72 QVERIFY(fabs(d.cos() + 0.38365070674265630377) < 1e-9);
73 }
74
stringCtor()75 void TestCachingDms::stringCtor()
76 {
77 QString hms("14:55:20");
78
79 // From Degree
80 CachingDms d(hms);
81
82 QVERIFY(d.degree() == 14);
83 QVERIFY(d.arcmin() == 55);
84 QVERIFY(d.arcsec() == 20);
85 QVERIFY(qFuzzyCompare(d.Degrees(), (14.0 + 55.0 / 60.0 + 20.0 / 3600.0)));
86 QVERIFY(fabs(d.sin() - .25750758368074941632) < 1e-9);
87 QVERIFY(fabs(d.cos() - .96627627744186177805) < 1e-9);
88
89 // From Hours
90 CachingDms h(hms, false);
91 QVERIFY(qFuzzyCompare(h.Degrees(), d.Degrees() * 15.0));
92 QVERIFY(qFuzzyCompare(h.Hours(), d.Degrees()));
93 }
94
setUsing_asin()95 void TestCachingDms::setUsing_asin()
96 {
97 // Test case in first quadrant: 56.3 degrees
98 CachingDms d;
99 d.setUsing_asin(.83195412213048254606);
100 QVERIFY(fabs(d.Degrees() - 56.3) < 1e-7);
101 QVERIFY(fabs(d.cos() - .55484442744799927555) < 1e-9);
102
103 // Test case in fourth quadrant: -56.3 degrees
104 d.setUsing_asin(-.83195412213048254606);
105 QVERIFY(fabs(d.Degrees() + 56.3) < 1e-7);
106 QVERIFY(fabs(d.cos() - .55484442744799927555) < 1e-9);
107 }
108
setUsing_acos()109 void TestCachingDms::setUsing_acos()
110 {
111 CachingDms d;
112
113 // Test case in first quadrant: 56.3 degrees
114 d.setUsing_acos(.55484442744799927555);
115 QVERIFY(fabs(d.Degrees() - 56.3) < 1e-7);
116 QVERIFY(fabs(d.sin() - .83195412213048254606) < 1e-9);
117
118 // Test case in second quadrant: 123.7 degrees
119 d.setUsing_acos(-0.55484442744799927555);
120 QVERIFY(fabs(d.Degrees() - 123.7) < 1e-7);
121 QVERIFY(fabs(d.sin() - .83195412213048254606) < 1e-9);
122 }
123
setUsing_atan2()124 void TestCachingDms::setUsing_atan2()
125 {
126 // Test case in first quadrant: 56.3 degrees
127 CachingDms d;
128 d.setUsing_atan2(2.73701935509448143467, 1.82536500102022632674);
129 QVERIFY(fabs(d.Degrees() - 56.3) < 1e-7);
130 QVERIFY(fabs(d.sin() - .83195412213048254606) < 1e-9);
131 QVERIFY(fabs(d.cos() - .55484442744799927555) < 1e-9);
132
133 // Test case in third quadrant: -123.7 degrees
134 d.setUsing_atan2(-2.73701935509448143467, -1.82536500102022632674);
135 QVERIFY(fabs(d.Degrees() + 123.7) < 1e-7);
136 QVERIFY(fabs(d.sin() + .83195412213048254606) < 1e-9);
137 QVERIFY(fabs(d.cos() + .55484442744799927555) < 1e-9);
138
139 // Test case in second quadrant: 123.7 degrees
140 d.setUsing_atan2(2.73701935509448143467, -1.82536500102022632674);
141 QVERIFY(fabs(d.Degrees() - 123.7) < 1e-7);
142 QVERIFY(fabs(d.sin() - .83195412213048254606) < 1e-9);
143 QVERIFY(fabs(d.cos() + .55484442744799927555) < 1e-9);
144
145 // Test case in fourth quadrant: -56.3 degrees
146 d.setUsing_atan2(-2.73701935509448143467, +1.82536500102022632674);
147 QVERIFY(fabs(d.Degrees() + 56.3) < 1e-7);
148 QVERIFY(fabs(d.sin() + .83195412213048254606) < 1e-9);
149 QVERIFY(fabs(d.cos() - .55484442744799927555) < 1e-9);
150
151 // Edge case test: angle = 0
152 d.setUsing_atan2(0., 1.33);
153 QVERIFY(fabs(d.Degrees() - 0.) < 1e-7);
154 QVERIFY(fabs(d.sin() - 0.) < 1e-9);
155 QVERIFY(fabs(d.cos() - 1.) < 1e-9);
156
157 // Edge case test: angle = 90 degrees
158 d.setUsing_atan2(10.12, 0.);
159 QVERIFY(fabs(d.Degrees() - 90.) < 1e-7);
160 QVERIFY(fabs(d.sin() - 1.) < 1e-9);
161 QVERIFY(fabs(d.cos() - 0.) < 1e-9);
162
163 // Edge case test: angle = -90 degrees
164 d.setUsing_atan2(-3.1415, 0.);
165 QVERIFY(fabs(d.Degrees() + 90.) < 1e-7);
166 QVERIFY(fabs(d.sin() + 1.) < 1e-9);
167 QVERIFY(fabs(d.cos() - 0.) < 1e-9);
168
169 // Edge case test: angle = 180 degrees
170 d.setUsing_atan2(0., -724.);
171 QVERIFY(fabs(d.Degrees() - 180.) < 1e-7);
172 QVERIFY(fabs(d.sin() - 0.) < 1e-9);
173 QVERIFY(fabs(d.cos() + 1.) < 1e-9);
174 }
175
unaryMinusOperator()176 void TestCachingDms::unaryMinusOperator()
177 {
178 CachingDms d(56.3);
179 qDebug() << (-d).Degrees();
180 QVERIFY(qFuzzyCompare((-d).Degrees(), -56.3));
181 QVERIFY(qFuzzyCompare((-d).cos(), d.cos()));
182 QVERIFY(qFuzzyCompare((-d).sin(), -d.sin()));
183 }
184
additionOperator()185 void TestCachingDms::additionOperator()
186 {
187 const double a = 123.7;
188 const double b = 89.5;
189 CachingDms d1(a);
190 CachingDms d2(b);
191 CachingDms ds = d1 + d2;
192 const double sinapb = std::sin((a + b) * dms::DegToRad);
193 const double cosapb = std::cos((a + b) * dms::DegToRad);
194 QVERIFY(fabs(ds.sin() - sinapb) < 1e-9);
195 QVERIFY(fabs(ds.cos() - cosapb) < 1e-9);
196
197 const double c = -34.7;
198 const double d = 233.6;
199 CachingDms d3(c);
200 CachingDms d4(d);
201 CachingDms ds2 = d3 + d4;
202 const double sincpd = std::sin((c + d) * dms::DegToRad);
203 const double coscpd = std::cos((c + d) * dms::DegToRad);
204 QVERIFY(fabs(ds2.sin() - sincpd) < 1e-9);
205 QVERIFY(fabs(ds2.cos() - coscpd) < 1e-9);
206 }
207
subtractionOperator()208 void TestCachingDms::subtractionOperator()
209 {
210 const double a = 123.7;
211 const double b = 89.5;
212 CachingDms d1(a);
213 CachingDms d2(b);
214 CachingDms ds = d1 - d2;
215 const double sinamb = std::sin((a - b) * dms::DegToRad);
216 const double cosamb = std::cos((a - b) * dms::DegToRad);
217 QVERIFY(fabs(ds.sin() - sinamb) < 1e-9);
218 QVERIFY(fabs(ds.cos() - cosamb) < 1e-9);
219
220 const double c = -34.7;
221 const double d = 233.6;
222 CachingDms d3(c);
223 CachingDms d4(d);
224 CachingDms ds2 = d3 - d4;
225 const double sincmd = std::sin((c - d) * dms::DegToRad);
226 const double coscmd = std::cos((c - d) * dms::DegToRad);
227 QVERIFY(fabs(ds2.sin() - sincmd) < 1e-9);
228 QVERIFY(fabs(ds2.cos() - coscmd) < 1e-9);
229 }
230
testFailsafeUseOfBaseClassPtr()231 void TestCachingDms::testFailsafeUseOfBaseClassPtr()
232 {
233 typedef union angle {
234 double x;
235 int64_t y;
236 } angle;
237 const int testCases = 5000;
238 std::srand(std::time(nullptr));
239 for (int k = 0; k < testCases; ++k)
240 {
241 angle a { 0 };
242 CachingDms _a;
243 dms __a;
244 a.y = std::rand();
245 _a.setD(a.x);
246 __a.setD(a.x);
247 dms *d;
248 if (std::rand() % 10 > 5)
249 d = &_a;
250 else
251 d = &__a;
252 angle b;
253 b.y = std::rand();
254 switch (std::rand() % 7)
255 {
256 case 0:
257 d->setD(b.x);
258 break;
259 case 1:
260 d->setH(b.x / 15.);
261 break;
262 case 2:
263 {
264 dms x(b.x);
265 d->setD(x.degree(), x.arcmin(), x.arcsec(), x.marcsec());
266 break;
267 }
268 case 3:
269 {
270 dms x(b.x);
271 d->setFromString(x.toDMSString());
272 break;
273 }
274 case 4:
275 {
276 dms x(b.x);
277 d->setFromString(x.toHMSString(), false);
278 break;
279 }
280 case 5:
281 {
282 dms x(b.x);
283 dms y(0.0);
284 *d = x + y;
285 break;
286 }
287 case 6:
288 default:
289 d->setRadians(b.x * dms::DegToRad);
290 break;
291 }
292 QVERIFY(fabs(d->sin() - sin(b.x * dms::DegToRad)) < 1e-12);
293 QVERIFY(fabs(d->cos() - cos(b.x * dms::DegToRad)) < 1e-12);
294 }
295 }
296
297 QTEST_GUILESS_MAIN(TestCachingDms)
298