CppEphem
test_CEAngle.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * test_CEAngle.cpp: CppEphem *
3  * ----------------------------------------------------------------------- *
4  * Copyright © 2019 JCardenzana *
5  * ----------------------------------------------------------------------- *
6  * *
7  * This program is free software: you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation, either version 3 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This program is distributed in the hope that it will be useful, *
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15  * GNU General Public License for more details. *
16  * *
17  * You should have received a copy of the GNU General Public License *
18  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
19  * *
20  ***************************************************************************/
21 
22 #include <iostream>
23 
24 #include "test_CEAngle.h"
25 #include "CEException.h"
26 #include "CENamespace.h"
27 
28 
29 /**********************************************************************/
33  CETestSuite()
34 {
35  // Let's use 45 degrees for the tests, or PI/2
36  base_ = CEAngle(M_PI_2);
37 }
38 
39 
40 /**********************************************************************/
44 {}
45 
46 
47 /**********************************************************************/
53 {
54  std::cout << "\nTesting CEAngle:\n";
55 
56  // Run each of the tests
58  test_setangle();
59  test_retrieve();
60 
61  return pass();
62 }
63 
64 
65 /**********************************************************************/
71 {
72  // Default constructor
73  CEAngle test1;
74  test_double(test1.Rad(), 0.0, __func__, __LINE__);
75 
76  // Copy constructor (CEAngle)
77  CEAngle test2(base_);
78  test_double(test2.Rad(), base_.Rad(), __func__, __LINE__);
79 
80  // Copy-assignment operator (CEAngle)
81  CEAngle test3 = base_;
82  test_double(test3.Rad(), base_.Rad(), __func__, __LINE__);
83 
84  // Copy-assignment operator (double)
85  double angle_test = M_PI;
86  CEAngle test4;
87  test4 = angle_test;
88  test_double(test4, angle_test, __func__, __LINE__);
89 
90  // Copy-assignment operator (CEAngle)
91  CEAngle test5;
92  test5 = base_;
93  test_double(test5, base_, __func__, __LINE__);
94 
95  return pass();
96 }
97 
98 
99 /**********************************************************************/
105 {
106  // Construct the test angle
107  CEAngle test_ang;
108  // Test radians
109  double angle_rad = M_PI_2; // PI/2 radians or 90 degrees
110  test_ang.SetAngle(angle_rad, CEAngleType::RADIANS);
111  test_double(test_ang, angle_rad, __func__, __LINE__);
112 
113  // Test degrees
114  double angle_deg = 180.0;
115  std::string angle_deg_str = "180.0";
116  test_ang.SetAngle(angle_deg, CEAngleType::DEGREES);
117  test_double(test_ang, M_PI, __func__, __LINE__);
118  test_ang.SetAngle(angle_deg_str.c_str(), CEAngleType::DEGREES);
119 
120  // HMS values to be tested
121  std::string angle_hms_str1 = "3:0:0";
122  std::string angle_hms_str2 = "6 0 0";
123  std::string angle_hms_str3 = "9.0.0";
124  test_ang.SetAngle(angle_hms_str1.c_str(), CEAngleType::HMS);
125  test_double(test_ang, M_PI_2/2.0, __func__, __LINE__);
126  test_ang.SetAngle(angle_hms_str2.c_str(), CEAngleType::HMS);
127  test_double(test_ang, M_PI_2, __func__, __LINE__);
128  test_ang.SetAngle(angle_hms_str3.c_str(), CEAngleType::HMS, '.');
129  test_double(test_ang, 1.5 * M_PI_2, __func__, __LINE__);
130 
131  // DMS values to be tested
132  std::string angle_dms_str1 = "45:0:0";
133  test_ang.SetAngle(angle_dms_str1.c_str(), CEAngleType::DMS);
134  test_double(test_ang, M_PI_2/2.0, __func__, __LINE__);
135 
136  // Try to set the angle by passing the wrong delimiter
137  try {
138  test_ang.SetAngle(angle_hms_str1.c_str(), CEAngleType::HMS, ' ');
139  test(false, __func__, __LINE__);
140  } catch (CEException::invalid_delimiter& e) {
141  test(true, __func__, __LINE__);
142  }
143 
144  // Try to set angle as a double, but with the wrong CEAngleType
145  try {
146  test_ang.SetAngle(123.456, CEAngleType::HMS);
147  test(false, __func__, __LINE__);
148  } catch (CEException::invalid_value& e) {
149  test(true, __func__, __LINE__);
150  }
151 
152  // Try to set the angle from a vector<double> with wrong CEAngleType
153  try {
154  test_ang.SetAngle({123,45,6, 0.789}, CEAngleType::DEGREES);
155  test(false, __func__, __LINE__);
156  } catch (CEException::invalid_value& e) {
157  test(true, __func__, __LINE__);
158  }
159 
160  return pass();
161 }
162 
163 
164 
165 /**********************************************************************/
171 {
172  double angle = M_PI;
173 
174  // Test getting from...
175  // ... degrees
176  test_double(CEAngle::Deg(180), angle, __func__, __LINE__);
177  // ... radians
178  test_double(CEAngle::Rad(angle), angle, __func__, __LINE__);
179  // ... Hms (version 1)
180  test_double(CEAngle::Hms("12:00:00"), angle, __func__, __LINE__);
181  test_double(CEAngle::Hms("12 00 00"), angle, __func__, __LINE__);
182  test_double(CEAngle::Hms("12.00.00", '.'), angle, __func__, __LINE__);
183  // ... HMS (version 2)
184  test_double(CEAngle::Hms({12.0, 0.0, 0.0, 0.0}), angle, __func__, __LINE__);
185  // ... Dms (version 1)
186  test_double(CEAngle::Dms("180:00:00"), angle, __func__, __LINE__);
187  test_double(CEAngle::Dms("180 00 00"), angle, __func__, __LINE__);
188  test_double(CEAngle::Dms("180'00'00", '\''), angle, __func__, __LINE__);
189  // ... DMS (version 2)
190  test_double(CEAngle::Dms({180, 0, 0, 0.0}), angle, __func__, __LINE__);
191 
192  // Now test some of the other ways in which to get back the angle using
193  // a particular format. For this, we will use 315.25 degrees
194  double test_deg = 315.25;
195  CEAngle test_ang(test_deg * DD2R);
196 
197  // Deg
198  test_double(test_ang.Deg(), test_deg, __func__, __LINE__);
199 
200  // Rad
201  test_double(test_ang.Rad(), test_deg*DD2R, __func__, __LINE__);
202 
203  // HMS as string
204  std::string hms_str = test_ang.HmsStr('\'');
205  hms_str = std::string(hms_str.begin(), hms_str.begin()+11);
206  test_string(hms_str, "21'01'00.00", __func__, __LINE__);
207 
208  // HMS as vector<double>
209  test_vect(test_ang.HmsVect(), {21, 1, 0, 0}, __func__, __LINE__);
210 
211  // DMS as string
212  std::string dms_str = test_ang.DmsStr('"');
213  dms_str = std::string(dms_str.begin(), dms_str.begin()+12);
214  test_string(dms_str, "315\"15\"00.00", __func__, __LINE__);
215 
216  // DMS as vector<double>
217  test_vect(test_ang.DmsVect(), {315, 15, 0, 0}, __func__, __LINE__);
218 
219  // Can the angle be retrieved directly as a double?
220  test_double(test_ang, test_deg*DD2R, __func__, __LINE__);
221  const CEAngle test_ang2(test_ang);
222  // Test 'const' version
223  test_double(test_ang2, test_deg*DD2R, __func__, __LINE__);
224 
225 
226  // Test exceptions
227  CEAngle test_ang3;
228 
229  // Incorrect hour
230  try {
231  test_ang3.SetAngle({25, 2, 3.3}, CEAngleType::HMS);
232  test(false, "HMS bad hours exception", __func__, __LINE__);
233  } catch (CEException::invalid_value& e) {
234  test(true, "HMS bad hours exception", __func__, __LINE__);
235  }
236  // Incorrect minutes
237  try {
238  test_ang3.SetAngle({1, -2, 3.3}, CEAngleType::HMS);
239  test(false, "HMS bad minutes exception", __func__, __LINE__);
240  } catch (CEException::invalid_value& e) {
241  test(true, "HMS bad minutes exception", __func__, __LINE__);
242  }
243  // Incorrect seconds
244  try {
245  test_ang3.SetAngle({1, 2, -3.3}, CEAngleType::HMS);
246  test(false, "HMS bad seconds exception", __func__, __LINE__);
247  } catch (CEException::invalid_value& e) {
248  test(true, "HMS bad seconds exception", __func__, __LINE__);
249  }
250 
251  // Incorrect degrees
252  try {
253  test_ang3.SetAngle({370, 2, 3.3}, CEAngleType::DMS);
254  test(false, "DMS bad degrees exception", __func__, __LINE__);
255  } catch (CEException::invalid_value& e) {
256  test(true, "DMS bad degrees exception", __func__, __LINE__);
257  }
258  // Incorrect minutes
259  try {
260  test_ang3.SetAngle({1, -2, 3.3}, CEAngleType::DMS);
261  test(false, "DMS bad arcmins exception", __func__, __LINE__);
262  } catch (CEException::invalid_value& e) {
263  test(true, "DMS bad arcmins exception", __func__, __LINE__);
264  }
265  // Incorrect seconds
266  try {
267  test_ang3.SetAngle({1, 2, -3.3}, CEAngleType::DMS);
268  test(false, "DMS bad arcsecs exception", __func__, __LINE__);
269  } catch (CEException::invalid_value& e) {
270  test(true, "DMS bad arcsecs exception", __func__, __LINE__);
271  }
272 
273  return pass();
274 }
275 
276 
277 /**********************************************************************/
280 int main(int argc, char** argv)
281 {
282  test_CEAngle tester;
283  return (!tester.runtests());
284 }
CEAngle::Dms
static CEAngle Dms(const char *angle_str, const char &delim=0)
Return double constructed from a string representing degrees, minutes, seconds.
Definition: CEAngle.cpp:234
test_CEAngle::test_construct
bool test_construct(void)
Test the various constructor methods.
Definition: test_CEAngle.cpp:70
CENamespace.h
CEAngle::DmsStr
std::string DmsStr(const char &delim=':') const
Return string representing the angle in DD:MM:SS.
Definition: CEAngle.cpp:270
CEAngle::DmsVect
std::vector< double > DmsVect(void) const
Return vector of doubles representing the {degrees, arcmin, arcsec, arcsec-fraction}.
Definition: CEAngle.cpp:291
test_CEAngle.h
test_CEAngle::test_retrieve
bool test_retrieve(void)
Test getting the angle from multiple methods.
Definition: test_CEAngle.cpp:170
CEAngle::HmsVect
std::vector< double > HmsVect(void) const
Return vector of doubles representing the {hours, min, sec, sec-fraction}.
Definition: CEAngle.cpp:199
test_CEAngle::runtests
bool runtests()
Run tests.
Definition: test_CEAngle.cpp:52
CEException.h
CEAngle
Definition: CEAngle.h:38
CEAngle::Rad
double Rad(void) const
Return angle in radians as a double.
Definition: CEAngle.cpp:351
CEAngle::SetAngle
void SetAngle(const double &angle, const CEAngleType &angle_type=CEAngleType::RADIANS)
Set the angle from a double.
Definition: CEAngle.cpp:369
test_CEAngle::base_
CEAngle base_
Definition: test_CEAngle.h:60
CEAngle::Rad
static CEAngle Rad(const double &angle)
Return angle constructed from a radians angle.
Definition: CEAngle.cpp:340
CEException::invalid_delimiter
Definition: CEException.h:80
CEAngleType::DEGREES
test_CEAngle::~test_CEAngle
virtual ~test_CEAngle()
Destructor.
Definition: test_CEAngle.cpp:43
CEAngleType::RADIANS
test_CEAngle::test_setangle
bool test_setangle(void)
Test setting the angle from multiple methods representing 45 degrees.
Definition: test_CEAngle.cpp:104
CEException::invalid_value
Definition: CEException.h:73
CEAngle::Deg
double Deg(void) const
Return angle in degrees as a double.
Definition: CEAngle.cpp:328
CEAngle::Hms
static CEAngle Hms(const char *angle_str, const char &delim=0)
Return angle constructed from a string representing hours, minutes, seconds.
Definition: CEAngle.cpp:142
main
int main(int argc, char **argv)
Main method that actually runs the tests.
Definition: test_CEAngle.cpp:280
test_CEAngle::test_CEAngle
test_CEAngle()
Default constructor.
Definition: test_CEAngle.cpp:32
CEAngleType::DMS
test_CEAngle
Definition: test_CEAngle.h:27
CEAngle::Deg
static CEAngle Deg(const double &angle)
Return angle (radians) constructed from a degree angle.
Definition: CEAngle.cpp:317
CEAngleType::HMS
CEAngle::HmsStr
std::string HmsStr(const char &delim=':') const
Return string representing the angle in HH:MM:SS.
Definition: CEAngle.cpp:178