1.3.49
 
Loading...
Searching...
No Matches
Test_utilities.h
1#pragma once
2// =================================================================================
3// Suite 1: Core Utilities and Data Types
4//
5// Tests for fundamental data structures (vectors, colors, date/time),
6// coordinate systems, and their associated operations.
7// =================================================================================
8TEST_CASE("Vector and Color Types (helios_vector_types.h)") {
9 // This test case contains the full, unaltered "helios_vector_types coverage" test.
10 SUBCASE("int2") {
11 int2 v0(1, 2);
12 int2 v1(3, 4);
13 DOCTEST_CHECK(v0.x == 1);
14 DOCTEST_CHECK(v0.y == 2);
15
16 // Constructors
17 int2 v_vec_c(std::vector<int>{1, 2});
18 DOCTEST_CHECK(v_vec_c == v0);
19 DOCTEST_CHECK_THROWS(int2({1}));
20 int arr[2] = {1, 2};
21 int2 v_arr_c(arr);
22 DOCTEST_CHECK(v_arr_c == v0);
23
24 // Operators
25 DOCTEST_CHECK(v0 + v1 == int2(4, 6));
26 v0 += v1;
27 DOCTEST_CHECK(v0 == int2(4, 6));
28 DOCTEST_CHECK(v1 - v0 == int2(-1, -2));
29 v0 -= v1;
30 DOCTEST_CHECK(v0 == int2(1, 2));
31 DOCTEST_CHECK(v0 != v1);
32 DOCTEST_CHECK(-v0 == int2(-1, -2));
33
34 // make_int2
35 int arr2[2] = {5, 6};
36 DOCTEST_CHECK(make_int2(arr2) == int2(5, 6));
37
38 // Stream operator
39 std::stringstream ss;
40 ss << v0;
41 DOCTEST_CHECK(ss.str() == "helios::int2<1, 2>");
42 }
43
44 SUBCASE("int3") {
45 int3 v0(1, 2, 3);
46 int3 v1(4, 5, 6);
47 DOCTEST_CHECK(v0.x == 1);
48
49 // Constructors
50 int3 v_vec_c(std::vector<int>{1, 2, 3});
51 DOCTEST_CHECK(v_vec_c == v0);
52 DOCTEST_CHECK_THROWS(int3({1}));
53 int arr[3] = {1, 2, 3};
54 int3 v_arr_c(arr);
55 DOCTEST_CHECK(v_arr_c == v0);
56
57 // Operators
58 DOCTEST_CHECK(v0 + v1 == int3(5, 7, 9));
59 v0 += v1;
60 DOCTEST_CHECK(v0 == int3(5, 7, 9));
61 DOCTEST_CHECK(v1 - v0 == int3(-1, -2, -3));
62 v0 -= v1;
63 DOCTEST_CHECK(v0 == int3(1, 2, 3));
64 DOCTEST_CHECK(v0 != v1);
65 DOCTEST_CHECK(-v0 == int3(-1, -2, -3));
66
67 // make_int3
68 DOCTEST_CHECK(make_int3(1, 2, 3) == v0);
69 int arr2[3] = {1, 2, 3};
70 DOCTEST_CHECK(make_int3(arr2) == v0);
71
72 // Stream operator
73 std::stringstream ss;
74 ss << v0;
75 DOCTEST_CHECK(ss.str() == "helios::int3<1, 2, 3>");
76 }
77
78 SUBCASE("int4") {
79 int4 v0(1, 2, 3, 4);
80 int4 v1(5, 6, 7, 8);
81 DOCTEST_CHECK(v0.w == 4);
82
83 // Constructors
84 int4 v_def_c;
85 DOCTEST_CHECK(v_def_c.x == 0);
86 int4 v_vec_c(std::vector<int>{1, 2, 3, 4});
87 DOCTEST_CHECK(v_vec_c == v0);
88 DOCTEST_CHECK_THROWS(int4({1}));
89 int arr[4] = {1, 2, 3, 4};
90 int4 v_arr_c(arr);
91 DOCTEST_CHECK(v_arr_c == v0);
92
93 // Operators
94 DOCTEST_CHECK(v0 + v1 == int4(6, 8, 10, 12));
95 v0 += v1;
96 DOCTEST_CHECK(v0 == int4(6, 8, 10, 12));
97 DOCTEST_CHECK(v1 - v0 == int4(-1, -2, -3, -4));
98 v0 -= v1;
99 DOCTEST_CHECK(v0 == int4(1, 2, 3, 4));
100 DOCTEST_CHECK(v0 != v1);
101 DOCTEST_CHECK(-v0 == int4(-1, -2, -3, -4));
102
103 // make_int4
104 DOCTEST_CHECK(make_int4(1, 2, 3, 4) == v0);
105 int arr2[4] = {1, 2, 3, 4};
106 DOCTEST_CHECK(make_int4(arr2) == v0);
107
108 // Stream operator
109 std::stringstream ss;
110 ss << v0;
111 DOCTEST_CHECK(ss.str() == "helios::int4<1, 2, 3, 4>");
112 }
113
114 SUBCASE("uint2") {
115 uint2 v0(1, 2);
116 uint2 v1(3, 4);
117 DOCTEST_CHECK(v0.x == 1);
118
119 // Constructors
120 uint2 v_def_c;
121 DOCTEST_CHECK(v_def_c.x == 0);
122 uint2 v_vec_c(std::vector<uint>{1, 2});
123 DOCTEST_CHECK(v_vec_c == v0);
124 DOCTEST_CHECK_THROWS(uint2({1}));
125 unsigned int arr[2] = {1, 2};
126 uint2 v_arr_c(arr);
127 DOCTEST_CHECK(v_arr_c == v0);
128
129 // Operators
130 DOCTEST_CHECK(v0 + v1 == uint2(4, 6));
131 v0 += v1;
132 DOCTEST_CHECK(v0 == uint2(4, 6));
133 DOCTEST_CHECK(v0 - v1 == uint2(1, 2));
134 v0 -= v1;
135 DOCTEST_CHECK(v0 == uint2(1, 2));
136 DOCTEST_CHECK(v0 != v1);
137 DOCTEST_CHECK(-v0 == uint2((unsigned int) -1, (unsigned int) -2));
138
139 // make_uint2
140 DOCTEST_CHECK(make_uint2(1, 2) == v0);
141 unsigned int arr2[2] = {1, 2};
142 DOCTEST_CHECK(make_uint2(arr2) == v0);
143
144 // Stream operator
145 std::stringstream ss;
146 ss << v0;
147 DOCTEST_CHECK(ss.str() == "helios::uint2<1, 2>");
148 }
149
150 SUBCASE("uint3") {
151 uint3 v0(1, 2, 3);
152 uint3 v1(4, 5, 6);
153 DOCTEST_CHECK(v0.x == 1);
154
155 // Constructors
156 uint3 v_def_c;
157 DOCTEST_CHECK(v_def_c.x == 0);
158 uint3 v_vec_c(std::vector<uint>{1, 2, 3});
159 DOCTEST_CHECK(v_vec_c == v0);
160 DOCTEST_CHECK_THROWS(uint3({1}));
161 unsigned int arr[3] = {1, 2, 3};
162 uint3 v_arr_c(arr);
163 DOCTEST_CHECK(v_arr_c == v0);
164
165 // Operators
166 DOCTEST_CHECK(v0 + v1 == uint3(5, 7, 9));
167 v0 += v1;
168 DOCTEST_CHECK(v0 == uint3(5, 7, 9));
169 DOCTEST_CHECK(v0 - v1 == uint3(1, 2, 3));
170 v0 -= v1;
171 DOCTEST_CHECK(v0 == uint3(1, 2, 3));
172 DOCTEST_CHECK(v0 != v1);
173 DOCTEST_CHECK(-v0 == uint3((unsigned int) -1, (unsigned int) -2, (unsigned int) -3));
174
175 // make_uint3
176 DOCTEST_CHECK(make_uint3(1, 2, 3) == v0);
177 unsigned int arr2[3] = {1, 2, 3};
178 DOCTEST_CHECK(make_uint3(arr2) == v0);
179
180 // Stream operator
181 std::stringstream ss;
182 ss << v0;
183 DOCTEST_CHECK(ss.str() == "helios::uint3<1, 2, 3>");
184 }
185
186 SUBCASE("uint4") {
187 uint4 v0(1, 2, 3, 4);
188 uint4 v1(5, 6, 7, 8);
189 DOCTEST_CHECK(v0.w == 4);
190
191 // Constructors
192 uint4 v_def_c;
193 DOCTEST_CHECK(v_def_c.x == 0);
194 uint4 v_vec_c(std::vector<uint>{1, 2, 3, 4});
195 DOCTEST_CHECK(v_vec_c == v0);
196 DOCTEST_CHECK_THROWS(uint4({1}));
197 unsigned int arr[4] = {1, 2, 3, 4};
198 uint4 v_arr_c(arr);
199 DOCTEST_CHECK(v_arr_c == v0);
200
201 // Operators
202 DOCTEST_CHECK(v0 + v1 == uint4(6, 8, 10, 12));
203 v0 += v1;
204 DOCTEST_CHECK(v0 == uint4(6, 8, 10, 12));
205 DOCTEST_CHECK(v0 - v1 == uint4(1, 2, 3, 4));
206 v0 -= v1;
207 DOCTEST_CHECK(v0 == uint4(1, 2, 3, 4));
208 DOCTEST_CHECK(v0 != v1);
209 DOCTEST_CHECK(-v0 == uint4((unsigned int) -1, (unsigned int) -2, (unsigned int) -3, (unsigned int) -4));
210
211 // make_uint4
212 DOCTEST_CHECK(make_uint4(1, 2, 3, 4) == v0);
213 unsigned int arr2[4] = {1, 2, 3, 4};
214 DOCTEST_CHECK(make_uint4(arr2) == v0);
215
216 // Stream operator
217 std::stringstream ss;
218 ss << v0;
219 DOCTEST_CHECK(ss.str() == "helios::uint4<1, 2, 3, 4>");
220 }
221
222 SUBCASE("vec2") {
223 vec2 v0(1.f, 2.f);
224 vec2 v1(3.f, 4.f);
225
226 // Constructors
227 DOCTEST_CHECK_THROWS(vec2({1.f}));
228 float arr[] = {1.f, 2.f};
229 vec2 v_arr_c(arr);
230 DOCTEST_CHECK(v_arr_c == v0);
231
232 // Methods
233 DOCTEST_CHECK(vec2(3.f, 4.f).magnitude() == doctest::Approx(5.f));
234 DOCTEST_CHECK(normalize(vec2(3.f, 4.f)) == vec2(0.6f, 0.8f));
235 vec2 v_norm = vec2(3.f, 4.f);
236 v_norm.normalize();
237 DOCTEST_CHECK(v_norm == vec2(0.6f, 0.8f));
238 vec2 zero_vec(0.f, 0.f);
239 zero_vec.normalize();
240 DOCTEST_CHECK(zero_vec == vec2(0.f, 0.f));
241
242
243 // Operators
244 DOCTEST_CHECK(v0 * v1 == doctest::Approx(11.f));
245 v0 += v1;
246 DOCTEST_CHECK(v0 == vec2(4.f, 6.f));
247 v0 -= v1;
248 DOCTEST_CHECK(v0 == vec2(1.f, 2.f));
249 v0 *= 2.f;
250 DOCTEST_CHECK(v0 == vec2(2.f, 4.f));
251 v0 /= 2.f;
252 DOCTEST_CHECK(v0 == vec2(1.f, 2.f));
253 DOCTEST_CHECK(v0 + 1.f == vec2(2.f, 3.f));
254 DOCTEST_CHECK(1.f + v0 == vec2(2.f, 3.f));
255 DOCTEST_CHECK(v0 - 1.f == vec2(0.f, 1.f));
256 DOCTEST_CHECK(1.f - v0 == vec2(0.f, -1.f));
257 DOCTEST_CHECK(v0 * 2.f == vec2(2.f, 4.f));
258 DOCTEST_CHECK(v0 / 2.f == vec2(0.5f, 1.f));
259 DOCTEST_CHECK(v0 / 0.f == vec2(std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity()));
260 DOCTEST_CHECK(v0 != v1);
261 DOCTEST_CHECK(-v0 == vec2(-1.f, -2.f));
262
263 // Stream operator
264 std::stringstream ss;
265 ss << v0;
266 DOCTEST_CHECK(ss.str() == "helios::vec2<1, 2>");
267 }
268
269 SUBCASE("vec3") {
270 vec3 v0(1.f, 2.f, 3.f);
271 vec3 v1(4.f, 5.f, 6.f);
272
273 // Constructors
274 DOCTEST_CHECK_THROWS(vec3({1.f}));
275 float arr[] = {1.f, 2.f, 3.f};
276 vec3 v_arr_c(arr);
277 DOCTEST_CHECK(v_arr_c == v0);
278
279 // Methods
280 vec3 zero_vec(0.f, 0.f, 0.f);
281 zero_vec.normalize();
282 DOCTEST_CHECK(zero_vec == vec3(0.f, 0.f, 0.f));
283
284 // Operators
285 v0 += v1;
286 DOCTEST_CHECK(v0 == vec3(5.f, 7.f, 9.f));
287 v0 -= v1;
288 DOCTEST_CHECK(v0 == vec3(1.f, 2.f, 3.f));
289 v0 *= 2.f;
290 DOCTEST_CHECK(v0 == vec3(2.f, 4.f, 6.f));
291 v0 /= 2.f;
292 DOCTEST_CHECK(v0 == vec3(1.f, 2.f, 3.f));
293 DOCTEST_CHECK(v0 + 1.f == vec3(2.f, 3.f, 4.f));
294 DOCTEST_CHECK(1.f + v0 == vec3(2.f, 3.f, 4.f));
295 DOCTEST_CHECK(v0 - 1.f == vec3(0.f, 1.f, 2.f));
296 DOCTEST_CHECK(1.f - v0 == vec3(0.f, -1.f, -2.f));
297 DOCTEST_CHECK(v0 * 2.f == vec3(2.f, 4.f, 6.f));
298 DOCTEST_CHECK(v0 != v1);
299
300 // make_vec3
301 float arr2[] = {1.f, 2.f, 3.f};
302 DOCTEST_CHECK(make_vec3(arr2) == v0);
303
304 // Stream operator
305 std::stringstream ss;
306 ss << v0;
307 DOCTEST_CHECK(ss.str() == "helios::vec3<1, 2, 3>");
308 }
309
310 SUBCASE("vec4") {
311 vec4 v0(1.f, 2.f, 3.f, 4.f);
312 vec4 v1(5.f, 6.f, 7.f, 8.f);
313
314 // Constructors
315 vec4 v_def_c;
316 DOCTEST_CHECK(v_def_c.x == 0.f);
317 DOCTEST_CHECK_THROWS(vec4({1.f}));
318 float arr[] = {1.f, 2.f, 3.f, 4.f};
319 vec4 v_arr_c(arr);
320 DOCTEST_CHECK(v_arr_c == v0);
321
322 // Methods
323 DOCTEST_CHECK(vec4(1, 2, 3, 4).magnitude() == doctest::Approx(sqrt(30.f)));
324 vec4 v_norm(1, 2, 3, 4);
325 v_norm.normalize();
326 float mag = sqrt(30.f);
327 DOCTEST_CHECK(v_norm.x == doctest::Approx(1.f / mag));
328 vec4 zero_vec;
329 zero_vec.normalize();
330 DOCTEST_CHECK(zero_vec == vec4(0, 0, 0, 0));
331 DOCTEST_CHECK(normalize(vec4(1, 2, 3, 4)) == v_norm);
332
333 // Operators
334 DOCTEST_CHECK(v0 * v1 == doctest::Approx(70.f));
335 DOCTEST_CHECK(v0 + v1 == vec4(6.f, 8.f, 10.f, 12.f));
336 v0 += v1;
337 DOCTEST_CHECK(v0 == vec4(6.f, 8.f, 10.f, 12.f));
338 DOCTEST_CHECK(v0 - v1 == vec4(1.f, 2.f, 3.f, 4.f));
339 v0 -= v1;
340 DOCTEST_CHECK(v0 == vec4(1.f, 2.f, 3.f, 4.f));
341 v0 *= 2.f;
342 DOCTEST_CHECK(v0 == vec4(2.f, 4.f, 6.f, 8.f));
343 v0 /= 2.f;
344 DOCTEST_CHECK(v0 == vec4(1.f, 2.f, 3.f, 4.f));
345 DOCTEST_CHECK(v0 + 1.f == vec4(2.f, 3.f, 4.f, 5.f));
346 DOCTEST_CHECK(1.f + v0 == vec4(2.f, 3.f, 4.f, 5.f));
347 DOCTEST_CHECK(v0 - 1.f == vec4(0.f, 1.f, 2.f, 3.f));
348 DOCTEST_CHECK(1.f - v0 == vec4(0.f, -1.f, -2.f, -3.f));
349 DOCTEST_CHECK(v0 * 2.f == vec4(2.f, 4.f, 6.f, 8.f));
350 DOCTEST_CHECK(2.f * v0 == vec4(2.f, 4.f, 6.f, 8.f));
351 DOCTEST_CHECK(v0 / 2.f == vec4(0.5f, 1.f, 1.5f, 2.f));
352 DOCTEST_CHECK(v0 / 0.f == vec4(std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity()));
353 DOCTEST_CHECK(v0 != v1);
354 DOCTEST_CHECK(-v0 == vec4(-1.f, -2.f, -3.f, -4.f));
355
356 // make_vec4
357 DOCTEST_CHECK(make_vec4(1.f, 2.f, 3.f, 4.f) == v0);
358 float arr2[] = {1.f, 2.f, 3.f, 4.f};
359 DOCTEST_CHECK(make_vec4(arr2) == v0);
360
361 // Stream operator
362 std::stringstream ss;
363 ss << v0;
364 DOCTEST_CHECK(ss.str() == "helios::vec4<1, 2, 3, 4>");
365 }
366
367 SUBCASE("RGBcolor") {
368 RGBcolor c0(0.1f, 0.2f, 0.3f);
369 RGBcolor c1(0.4f, 0.5f, 0.6f);
370
371 // Constructors
372 float arr[] = {0.1f, 0.2f, 0.3f};
373 RGBcolor c_arr_c(arr);
374 DOCTEST_CHECK(c_arr_c == c0);
375 std::vector<float> vec = {0.1f, 0.2f, 0.3f};
376 RGBcolor c_vec_c(vec);
377 DOCTEST_CHECK(c_vec_c == c0);
378 DOCTEST_CHECK_THROWS(RGBcolor({0.1f}));
379 vec3 v(0.1f, 0.2f, 0.3f);
380 RGBcolor c_v3_c(v);
381 DOCTEST_CHECK(c_v3_c == c0);
382
383 // Methods
384 c0.scale(2.f);
385 DOCTEST_CHECK(c0.r == doctest::Approx(0.2f));
386 DOCTEST_CHECK_THROWS(c0.scale(-1.f));
387
388 // Operators
389 c0 = RGBcolor(0.1f, 0.2f, 0.3f);
390 DOCTEST_CHECK(c0 + c1 == RGBcolor(0.5f, 0.7f, 0.9f));
391 DOCTEST_CHECK(c1 - c0 == RGBcolor(0.3f, 0.3f, 0.3f));
392 DOCTEST_CHECK(c0 != c1);
393
394 // Stream operator
395 std::stringstream ss;
396 ss << c0;
397 DOCTEST_CHECK(ss.str() == "helios::RGBcolor<0.1, 0.2, 0.3>");
398 }
399
400 SUBCASE("RGBAcolor") {
401 RGBAcolor c0(0.1f, 0.2f, 0.3f, 0.4f);
402 RGBAcolor c1(0.5f, 0.6f, 0.7f, 0.8f);
403
404 // Constructors
405 float arr[] = {0.1f, 0.2f, 0.3f, 0.4f};
406 RGBAcolor c_arr_c(arr);
407 DOCTEST_CHECK(c_arr_c == c0);
408 std::vector<float> vec = {0.1f, 0.2f, 0.3f, 0.4f};
409 RGBAcolor c_vec_c(vec);
410 DOCTEST_CHECK(c_vec_c == c0);
411 DOCTEST_CHECK_THROWS(RGBAcolor({0.1f}));
412
413 // Methods
414 c0.scale(2.f);
415 DOCTEST_CHECK(c0.r == doctest::Approx(0.2f));
416 DOCTEST_CHECK_THROWS(c0.scale(-1.f));
417
418 // Operators
419 c0 = RGBAcolor(0.1f, 0.2f, 0.3f, 0.4f);
420 DOCTEST_CHECK(c0 + c1 == RGBAcolor(0.6f, 0.8f, 1.0f, 1.0f));
421 DOCTEST_CHECK(c1 - c0 == RGBAcolor(0.4f, 0.4f, 0.4f, 0.4f));
422 DOCTEST_CHECK(c0 != c1);
423
424 // Stream operator
425 std::stringstream ss;
426 ss << c0;
427 DOCTEST_CHECK(ss.str() == "helios::RGBAcolor<0.1, 0.2, 0.3, 0.4>");
428 }
429}
430
431TEST_CASE("Date and Time Logic") {
432 SUBCASE("Date struct and helpers") {
433 Date d(10, 1, 2000);
434 // Constructors
435 DOCTEST_CHECK_THROWS(Date(32, 1, 2000));
436 DOCTEST_CHECK_THROWS(Date(1, 13, 2000));
437 DOCTEST_CHECK_THROWS(Date(1, 1, 999));
438
439 // Operators
440 DOCTEST_CHECK(d == Date(10, 1, 2000));
441 DOCTEST_CHECK(d != Date(11, 1, 2000));
442
443 // make_Date
444 DOCTEST_CHECK_THROWS(make_Date(32, 1, 2000));
445 DOCTEST_CHECK_THROWS(make_Date(1, 13, 2000));
446 DOCTEST_CHECK_THROWS(make_Date(1, 1, 999));
447 DOCTEST_CHECK_THROWS(make_Date(0, 2000));
448 DOCTEST_CHECK_THROWS(make_Date(367, 2000));
449 DOCTEST_CHECK_THROWS(make_Date(1, 999));
450 DOCTEST_CHECK(make_Date(10, 2000) == d);
451
452 // Julian2Calendar
453 DOCTEST_CHECK_THROWS(Julian2Calendar(0, 2000));
454 DOCTEST_CHECK_THROWS(Julian2Calendar(367, 2000));
455 DOCTEST_CHECK(Julian2Calendar(366, 2000).day == 31);
456 DOCTEST_CHECK(Julian2Calendar(366, 2000).month == 12);
457
458 // Calendar2Julian
459 DOCTEST_CHECK(Calendar2Julian(d) == 10);
460 DOCTEST_CHECK(Calendar2Julian(Date(31, 12, 2001)) == 365);
461
462 // Stream operator
463 std::stringstream ss;
464 ss << d;
465 DOCTEST_CHECK(ss.str() == "2000-01-10");
466 }
467
468 SUBCASE("Date::JulianDay edge cases") {
469 Date d1(1, 1, 2021);
470 int jd1 = d1.JulianDay();
471 DOCTEST_CHECK(jd1 == 1);
472 Date d2(31, 12, 2021);
473 int jd2 = d2.JulianDay();
474 DOCTEST_CHECK(jd2 == 365);
475 Date d3(29, 2, 2020);
476 int jd3 = d3.JulianDay();
477 DOCTEST_CHECK(jd3 == 60);
478 }
479
480 SUBCASE("JulianDay and CalendarDay") {
481 int jd1 = JulianDay(1, 1, 2021);
482 DOCTEST_CHECK(jd1 == 1);
483 int jd2 = JulianDay(31, 12, 2021);
484 DOCTEST_CHECK(jd2 == 365);
485 int jd3 = JulianDay(29, 2, 2020);
486 DOCTEST_CHECK(jd3 == 60);
487
488 Date d = CalendarDay(60, 2020);
489 DOCTEST_CHECK(d.day == 29);
490 DOCTEST_CHECK(d.month == 2);
491 DOCTEST_CHECK(d.year == 2020);
492
493 capture_cerr cerr_buffer;
494 DOCTEST_CHECK_THROWS(d = CalendarDay(366, 2021));
495 DOCTEST_CHECK_THROWS(d = CalendarDay(0, 2021));
496 DOCTEST_CHECK_THROWS(jd1 = JulianDay(32, 1, 2021));
497 DOCTEST_CHECK_THROWS(jd2 = JulianDay(1, 13, 2021));
498 }
499
500 SUBCASE("Time struct and helpers") {
501 Time t(1, 2, 3);
502 // Constructors
503 DOCTEST_CHECK_THROWS(Time(24, 1));
504 DOCTEST_CHECK_THROWS(Time(1, 60));
505 DOCTEST_CHECK_THROWS(Time(1, 1, 60));
506 DOCTEST_CHECK_THROWS(Time(1, 60, 1));
507 DOCTEST_CHECK_THROWS(Time(24, 1, 1));
508
509 // Operators
510 DOCTEST_CHECK(t == Time(1, 2, 3));
511 DOCTEST_CHECK(t != Time(1, 2, 4));
512
513 // make_Time
514 DOCTEST_CHECK(make_Time(1, 2) == Time(1, 2, 0));
515 DOCTEST_CHECK_THROWS(make_Time(24, 1));
516 DOCTEST_CHECK_THROWS(make_Time(1, 60));
517 DOCTEST_CHECK_THROWS(make_Time(1, 1, 60));
518 DOCTEST_CHECK_THROWS(make_Time(1, 60, 1));
519 DOCTEST_CHECK_THROWS(make_Time(24, 1, 1));
520
521 // Stream operator
522 std::stringstream ss;
523 ss << t;
524 DOCTEST_CHECK(ss.str() == "1:02:03");
525 }
526
527 SUBCASE("Location struct") {
528 Location l(1.f, 2.f, 3.f);
529
530 // Operators
531 DOCTEST_CHECK(l == Location(1.f, 2.f, 3.f));
532 DOCTEST_CHECK(l != Location(1.f, 2.f, 4.f));
533
534 // Stream operator
535 std::stringstream ss;
536 ss << l;
537 DOCTEST_CHECK(ss.str() == "<1,2,3>");
538 }
539
540 SUBCASE("Julian day conversion") {
541 int year = 2000;
542 Date d = Julian2Calendar(10, year);
543 DOCTEST_CHECK(d.year == year);
544 DOCTEST_CHECK(d.month == 1);
545 DOCTEST_CHECK(d.day == 10);
546 d = Julian2Calendar(230, year);
547 DOCTEST_CHECK(d.month == 8);
548 DOCTEST_CHECK(d.day == 17);
549 year = 2001;
550 d = Julian2Calendar(230, year);
551 DOCTEST_CHECK(d.month == 8);
552 DOCTEST_CHECK(d.day == 18);
553 }
554
555 SUBCASE("Date methods") {
556 SUBCASE("incrementDay") {
557 Date d(31, 12, 2020);
558 d.incrementDay();
559 DOCTEST_CHECK(d.day == 1);
560 DOCTEST_CHECK(d.month == 1);
561 DOCTEST_CHECK(d.year == 2021);
562
563 Date d2(28, 2, 2021);
564 d2.incrementDay();
565 DOCTEST_CHECK(d2.day == 1);
566 DOCTEST_CHECK(d2.month == 3);
567 DOCTEST_CHECK(d2.year == 2021);
568
569 Date d3(28, 2, 2020);
570 d3.incrementDay();
571 DOCTEST_CHECK(d3.day == 29);
572 DOCTEST_CHECK(d3.month == 2);
573 DOCTEST_CHECK(d3.year == 2020);
574 }
575 SUBCASE("isLeapYear") {
576 Date d1(1, 1, 2020);
577 DOCTEST_CHECK(d1.isLeapYear());
578 Date d2(1, 1, 2021);
579 DOCTEST_CHECK(!d2.isLeapYear());
580 Date d3(1, 1, 2000);
581 DOCTEST_CHECK(d3.isLeapYear());
582 Date d4(1, 1, 2100);
583 DOCTEST_CHECK(!d4.isLeapYear());
584 }
585 }
586}
587
588TEST_CASE("Coordinate System Conversions") {
589 SUBCASE("Spherical coordinate struct and conversions") {
590 SphericalCoord sc(1.f, 0.5f, 1.5f);
591
592 // Constructors
593#ifdef HELIOS_DEBUG
594 DOCTEST_CHECK_THROWS(make_SphericalCoord(-1.f, 0.f, 0.f));
595#endif
596
597 // Operators
598 DOCTEST_CHECK(sc == SphericalCoord(1.f, 0.5f, 1.5f));
599
600 // Methods
601 vec3 cart = sphere2cart(sc);
602 DOCTEST_CHECK(cart.x == doctest::Approx(1.f * cos(0.5f) * sin(1.5f)));
603 DOCTEST_CHECK(cart.y == doctest::Approx(1.f * cos(0.5f) * cos(1.5f)));
604 DOCTEST_CHECK(cart.z == doctest::Approx(1.f * sin(0.5f)));
605
606 // Stream operator
607 std::stringstream ss;
608 ss << sc;
609 DOCTEST_CHECK(ss.str() == "helios::SphericalCoord<1, 0.5, 1.5>");
610 }
611 SUBCASE("Cartesian to Spherical and back") {
612 SphericalCoord sph = make_SphericalCoord(1.f, 0.25 * PI_F, 1.5 * PI_F);
613 vec3 cart = sphere2cart(sph);
614 SphericalCoord sph2 = cart2sphere(cart);
615 DOCTEST_CHECK(sph.radius == doctest::Approx(sph2.radius).epsilon(errtol));
616 DOCTEST_CHECK(sph.elevation == doctest::Approx(sph2.elevation).epsilon(errtol));
617 DOCTEST_CHECK(sph.zenith == doctest::Approx(sph2.zenith).epsilon(errtol));
618 DOCTEST_CHECK(sph.azimuth == doctest::Approx(sph2.azimuth).epsilon(errtol));
619 }
620 SUBCASE("cart2sphere and sphere2cart") {
621 vec3 p1(1, 1, 1);
622 SphericalCoord s1 = cart2sphere(p1);
623 vec3 p2 = sphere2cart(s1);
624 DOCTEST_CHECK(p2.x == doctest::Approx(p1.x));
625 DOCTEST_CHECK(p2.y == doctest::Approx(p1.y));
626 DOCTEST_CHECK(p2.z == doctest::Approx(p1.z));
627
628 vec3 p_pole(0, 0, 5);
629 SphericalCoord s_pole = cart2sphere(p_pole);
630 DOCTEST_CHECK(s_pole.radius == doctest::Approx(5.f));
631 DOCTEST_CHECK(s_pole.elevation == doctest::Approx(PI_F / 2.f));
632 }
633}