A library that computes the ephemerides.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

173 lines
5.3 KiB

  1. #!/usr/bin/env python3
  2. # Kosmorrolib - The Library To Compute Your Ephemerides
  3. # Copyright (C) 2021 Jérôme Deuchnord <jerome@deuchnord.fr>
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU Affero General Public License as
  7. # published by the Free Software Foundation, either version 3 of the
  8. # License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU Affero General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU Affero General Public License
  16. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. import unittest
  18. from datetime import date, datetime
  19. from parameterized import parameterized
  20. from kosmorrolib import events
  21. from kosmorrolib.model import Event, ASTERS
  22. from kosmorrolib.enum import EventType
  23. from kosmorrolib.exceptions import OutOfRangeDateError
  24. EXPECTED_EVENTS = [
  25. (date(2020, 2, 7), []),
  26. (
  27. date(2020, 10, 13),
  28. [Event(EventType.OPPOSITION, [ASTERS[4]], datetime(2020, 10, 13, 23, 25))],
  29. ),
  30. (
  31. date(2022, 12, 8),
  32. [
  33. Event(
  34. EventType.CONJUNCTION,
  35. [ASTERS[1], ASTERS[4]],
  36. datetime(2022, 12, 8, 4, 18),
  37. ),
  38. Event(EventType.OPPOSITION, [ASTERS[4]], datetime(2022, 12, 8, 5, 41)),
  39. ],
  40. ),
  41. (
  42. date(2025, 1, 16),
  43. [Event(EventType.OPPOSITION, [ASTERS[4]], datetime(2025, 1, 16, 2, 38))],
  44. ),
  45. (
  46. date(2027, 2, 19),
  47. [
  48. Event(EventType.MOON_PERIGEE, [ASTERS[1]], datetime(2027, 2, 19, 7, 38)),
  49. Event(EventType.OPPOSITION, [ASTERS[4]], datetime(2027, 2, 19, 15, 50)),
  50. ],
  51. ),
  52. (
  53. date(2020, 1, 2),
  54. [
  55. Event(EventType.MOON_APOGEE, [ASTERS[1]], datetime(2020, 1, 2, 1, 32)),
  56. Event(
  57. EventType.CONJUNCTION,
  58. [ASTERS[2], ASTERS[5]],
  59. datetime(2020, 1, 2, 16, 41),
  60. ),
  61. ],
  62. ),
  63. (
  64. date(2020, 1, 12),
  65. [
  66. Event(
  67. EventType.CONJUNCTION,
  68. [ASTERS[2], ASTERS[6]],
  69. datetime(2020, 1, 12, 9, 51),
  70. ),
  71. Event(
  72. EventType.CONJUNCTION,
  73. [ASTERS[2], ASTERS[9]],
  74. datetime(2020, 1, 12, 10, 13),
  75. ),
  76. Event(
  77. EventType.CONJUNCTION,
  78. [ASTERS[6], ASTERS[9]],
  79. datetime(2020, 1, 12, 16, 57),
  80. ),
  81. ],
  82. ),
  83. (
  84. date(2020, 2, 10),
  85. [
  86. Event(
  87. EventType.MAXIMAL_ELONGATION,
  88. [ASTERS[2]],
  89. datetime(2020, 2, 10, 13, 46),
  90. details={"deg": 18.2},
  91. ),
  92. Event(EventType.MOON_PERIGEE, [ASTERS[1]], datetime(2020, 2, 10, 20, 34)),
  93. ],
  94. ),
  95. (
  96. date(2020, 3, 24),
  97. [
  98. Event(
  99. EventType.MAXIMAL_ELONGATION,
  100. [ASTERS[2]],
  101. datetime(2020, 3, 24, 1, 56),
  102. details={"deg": 27.8},
  103. ),
  104. Event(EventType.MOON_APOGEE, [ASTERS[1]], datetime(2020, 3, 24, 15, 39)),
  105. Event(
  106. EventType.MAXIMAL_ELONGATION,
  107. [ASTERS[3]],
  108. datetime(2020, 3, 24, 21, 58),
  109. details={"deg": 46.1},
  110. ),
  111. ],
  112. ),
  113. (
  114. date(2005, 6, 16),
  115. [
  116. Event(
  117. EventType.OCCULTATION,
  118. [ASTERS[1], ASTERS[5]],
  119. datetime(2005, 6, 16, 6, 31),
  120. )
  121. ],
  122. ),
  123. (
  124. date(2020, 4, 7),
  125. [Event(EventType.MOON_PERIGEE, [ASTERS[1]], datetime(2020, 4, 7, 18, 14))],
  126. ),
  127. (
  128. date(2020, 1, 29),
  129. [Event(EventType.MOON_APOGEE, [ASTERS[1]], datetime(2020, 1, 29, 21, 32))],
  130. ),
  131. ]
  132. class EventTestCase(unittest.TestCase):
  133. def setUp(self) -> None:
  134. self.maxDiff = None
  135. @parameterized.expand(EXPECTED_EVENTS)
  136. def test_search_events(self, d: date, expected_events: [Event]):
  137. actual_events = events.get_events(d)
  138. self.assertEqual(
  139. len(expected_events),
  140. len(actual_events),
  141. "Expected %d elements, got %d for date %s.\n%s"
  142. % (len(expected_events), len(actual_events), d.isoformat(), actual_events),
  143. )
  144. for i, expected_event in enumerate(expected_events):
  145. actual_event = actual_events[i]
  146. # Remove unnecessary precision (seconds and microseconds)
  147. actual_event.start_time = datetime(
  148. actual_event.start_time.year,
  149. actual_event.start_time.month,
  150. actual_event.start_time.day,
  151. actual_event.start_time.hour,
  152. actual_event.start_time.minute,
  153. )
  154. self.assertEqual(expected_event.__dict__, actual_event.__dict__)
  155. def test_get_events_raises_exception_on_out_of_date_range(self):
  156. with self.assertRaises(OutOfRangeDateError):
  157. events.get_events(date(1789, 5, 5))
  158. if __name__ == "__main__":
  159. unittest.main()