localBadiDate.test.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. import { BadiDate, badiDateSettings, LocalBadiDate } from '../src/localBadiDate';
  2. import { BadiDate as BadiDateOrig } from '../src/badiDate';
  3. import { clockLocationFromPolygons } from '../src/clockLocations';
  4. import * as luxon from 'luxon';
  5. import { clockMap } from './testData';
  6. import { BadiDateSettings } from '../src/types';
  7. const timesString = localBadiDate => (
  8. `${localBadiDate.start.toFormat('HH:mm:ss')}|${
  9. localBadiDate.sunrise.toFormat('HH:mm:ss')}|${
  10. localBadiDate.solarNoon.toFormat('HH:mm:ss')}|${
  11. localBadiDate.end.toFormat('HH:mm:ss')}`);
  12. const bahjiLat = 32.943;
  13. const bahjiLng = 35.092;
  14. describe('API', () => {
  15. expect(BadiDateOrig).toEqual(BadiDate);
  16. });
  17. describe('timestamps for start, sunrise, solar noon, and sunrise', () => {
  18. const badiDate = new LocalBadiDate({ year: 172, month: 1, day: 1 }, bahjiLat, bahjiLng, 'Asia/Jerusalem');
  19. it('should have the correct timestamp for start', () => {
  20. expect(badiDate.start.toISO()).toEqual('2015-03-20T17:51:00.000+02:00');
  21. });
  22. it('should have the correct timestamp for sunrise', () => {
  23. expect(badiDate.sunrise.toISO()).toEqual('2015-03-21T05:43:00.000+02:00');
  24. });
  25. it('should have the correct timestamp for solar noon', () => {
  26. expect(badiDate.solarNoon.toISO()).toEqual('2015-03-21T11:47:00.000+02:00');
  27. });
  28. it('should have the correct timestamp for end', () => {
  29. expect(badiDate.end.toISO()).toEqual('2015-03-21T17:52:00.000+02:00');
  30. });
  31. });
  32. describe('Getters', () => {
  33. it('should return values from geographic getters', () => {
  34. const badiDate = new LocalBadiDate({ year: 172, month: 1, day: 1 }, bahjiLat, bahjiLng, 'Asia/Jerusalem');
  35. expect(badiDate.latitude).toEqual(bahjiLat);
  36. expect(badiDate.longitude).toEqual(bahjiLng);
  37. expect(badiDate.timezoneId).toEqual('Asia/Jerusalem');
  38. });
  39. it('should return appropriate relative `LocalBadiDate` instances', () => {
  40. const badiDate1 = new LocalBadiDate({ year: 172, month: 1, day: 1 }, bahjiLat, bahjiLng, 'Asia/Jerusalem');
  41. expect(badiDate1.nextMonth.badiDate.month).toEqual(2);
  42. expect(badiDate1.nextMonth.badiDate.day).toEqual(1);
  43. expect(badiDate1.previousMonth.badiDate.month).toEqual(19);
  44. expect(badiDate1.previousMonth.badiDate.day).toEqual(1);
  45. expect(badiDate1.nextDay.badiDate.month).toEqual(1);
  46. expect(badiDate1.nextDay.badiDate.day).toEqual(2);
  47. expect(badiDate1.previousDay.badiDate.month).toEqual(19);
  48. expect(badiDate1.previousDay.badiDate.day).toEqual(19);
  49. const badiDate2 = new LocalBadiDate({ year: 172, month: 9, day: 5 }, bahjiLat, bahjiLng, 'Asia/Jerusalem');
  50. expect(badiDate2.nextMonth.badiDate.month).toEqual(10);
  51. expect(badiDate2.nextMonth.badiDate.day).toEqual(1);
  52. expect(badiDate2.previousMonth.badiDate.month).toEqual(8);
  53. expect(badiDate2.previousMonth.badiDate.day).toEqual(1);
  54. expect(badiDate2.nextDay.badiDate.month).toEqual(9);
  55. expect(badiDate2.nextDay.badiDate.day).toEqual(6);
  56. expect(badiDate2.previousDay.badiDate.month).toEqual(9);
  57. expect(badiDate2.previousDay.badiDate.day).toEqual(4);
  58. const badiDate3 = new LocalBadiDate({ year: 172, month: 19, day: 19 }, bahjiLat, bahjiLng, 'Asia/Jerusalem');
  59. expect(badiDate3.nextMonth.badiDate.month).toEqual(1);
  60. expect(badiDate3.nextMonth.badiDate.day).toEqual(1);
  61. expect(badiDate3.previousMonth.badiDate.month).toEqual(20);
  62. expect(badiDate3.previousMonth.badiDate.day).toEqual(1);
  63. expect(badiDate3.nextDay.badiDate.month).toEqual(1);
  64. expect(badiDate3.nextDay.badiDate.day).toEqual(1);
  65. expect(badiDate3.previousDay.badiDate.month).toEqual(19);
  66. expect(badiDate3.previousDay.badiDate.day).toEqual(18);
  67. const badiDate4 = new LocalBadiDate({ year: 172, month: 19, day: 1 }, bahjiLat, bahjiLng, 'Asia/Jerusalem');
  68. expect(badiDate4.nextMonth.badiDate.month).toEqual(1);
  69. expect(badiDate4.nextMonth.badiDate.day).toEqual(1);
  70. expect(badiDate4.previousMonth.badiDate.month).toEqual(20);
  71. expect(badiDate4.previousMonth.badiDate.day).toEqual(1);
  72. expect(badiDate4.nextDay.badiDate.month).toEqual(19);
  73. expect(badiDate4.nextDay.badiDate.day).toEqual(2);
  74. expect(badiDate4.previousDay.badiDate.month).toEqual(20);
  75. expect(badiDate4.previousDay.badiDate.day).toEqual(4);
  76. const badiDate5 = new LocalBadiDate({ year: 178, month: 19, day: 1 }, bahjiLat, bahjiLng, 'Asia/Jerusalem');
  77. expect(badiDate5.nextMonth.badiDate.month).toEqual(1);
  78. expect(badiDate5.nextMonth.badiDate.day).toEqual(1);
  79. expect(badiDate5.previousMonth.badiDate.month).toEqual(20);
  80. expect(badiDate5.previousMonth.badiDate.day).toEqual(1);
  81. expect(badiDate5.nextDay.badiDate.month).toEqual(19);
  82. expect(badiDate5.nextDay.badiDate.day).toEqual(2);
  83. expect(badiDate5.previousDay.badiDate.month).toEqual(20);
  84. expect(badiDate5.previousDay.badiDate.day).toEqual(5);
  85. const badiDate6 = new LocalBadiDate({ year: 172, month: 20, day: 4 }, bahjiLat, bahjiLng, 'Asia/Jerusalem');
  86. expect(badiDate6.nextMonth.badiDate.month).toEqual(19);
  87. expect(badiDate6.nextMonth.badiDate.day).toEqual(1);
  88. expect(badiDate6.previousMonth.badiDate.month).toEqual(18);
  89. expect(badiDate6.previousMonth.badiDate.day).toEqual(1);
  90. expect(badiDate6.nextDay.badiDate.month).toEqual(19);
  91. expect(badiDate6.nextDay.badiDate.day).toEqual(1);
  92. expect(badiDate6.previousDay.badiDate.month).toEqual(20);
  93. expect(badiDate6.previousDay.badiDate.day).toEqual(3);
  94. const badiDate7 = new LocalBadiDate({ year: 172, month: 18, day: 1 }, bahjiLat, bahjiLng, 'Asia/Jerusalem');
  95. expect(badiDate7.nextMonth.badiDate.month).toEqual(20);
  96. expect(badiDate7.nextMonth.badiDate.day).toEqual(1);
  97. expect(badiDate7.previousMonth.badiDate.month).toEqual(17);
  98. expect(badiDate7.previousMonth.badiDate.day).toEqual(1);
  99. expect(badiDate7.nextDay.badiDate.month).toEqual(18);
  100. expect(badiDate7.nextDay.badiDate.day).toEqual(2);
  101. expect(badiDate7.previousDay.badiDate.month).toEqual(17);
  102. expect(badiDate7.previousDay.badiDate.day).toEqual(19);
  103. });
  104. });
  105. it('should use the following day as input for the BadiDate if the input datetime is after sunset', () => {
  106. const badiDate1 = new LocalBadiDate(luxon.DateTime.fromISO('2015-03-21T12:00:00', { zone: 'Asia/Jerusalem' }),
  107. bahjiLat, bahjiLng, 'Asia/Jerusalem');
  108. const badiDate2 = new LocalBadiDate(luxon.DateTime.fromISO('2015-03-21T20:00:00', { zone: 'Asia/Jerusalem' }),
  109. bahjiLat, bahjiLng, 'Asia/Jerusalem');
  110. expect(badiDate1.badiDate.gregorianDate.day).toEqual(21);
  111. expect(badiDate2.badiDate.gregorianDate.day).toEqual(22);
  112. });
  113. describe('the BadiDate settings', () => {
  114. const settingsData = [
  115. {
  116. settings: { defaultLanguage: 'en', underlineFormat: 'css' },
  117. expectedOutput: 'Ma<span style="text-decoration:underline">sh</span>íyyat (Will)',
  118. }, {
  119. settings: { defaultLanguage: 'es', underlineFormat: 'css' },
  120. expectedOutput: 'Ma<span style="text-decoration:underline">sh</span>íyyat (Voluntad)',
  121. }, {
  122. settings: { defaultLanguage: 'en', underlineFormat: 'diacritic' },
  123. expectedOutput: 'Mas̲h̲íyyat (Will)',
  124. }, {
  125. settings: { defaultLanguage: 'es', underlineFormat: 'diacritic' },
  126. expectedOutput: 'Mas̲h̲íyyat (Voluntad)',
  127. },
  128. ];
  129. const badiDate = new LocalBadiDate({ year: 172, month: 11, day: 1 }, bahjiLat, bahjiLng, 'Asia/Jerusalem');
  130. settingsData.forEach(({ settings, expectedOutput }) => {
  131. it('should pass on the settings to the BadiDate class', () => {
  132. badiDateSettings(settings as BadiDateSettings);
  133. expect(badiDate.badiDate.format('MM+')).toEqual(expectedOutput);
  134. });
  135. });
  136. });
  137. describe('the useClockLocationSettings', () => {
  138. afterAll(() => {
  139. badiDateSettings({ useClockLocations: true });
  140. });
  141. const clockLocationDates = [
  142. {
  143. date: { year: 172, month: 1, day: 1 },
  144. latitude: 65.0,
  145. longitude: -150.0,
  146. timezone: 'America/Anchorage',
  147. fixedTimes: '19:00:00|07:00:00|13:00:00|19:00:00',
  148. solarTimes: '20:16:00|07:57:00|14:07:00|20:19:00',
  149. clockLocation: 'USA',
  150. }, {
  151. date: { year: 172, month: 1, day: 1 },
  152. latitude: 62.0,
  153. longitude: -120.0,
  154. timezone: 'America/Edmonton',
  155. fixedTimes: '18:00:00|06:30:00|12:00:00|18:00:00',
  156. solarTimes: '20:15:00|07:58:00|14:07:00|20:18:00',
  157. clockLocation: 'Canada',
  158. }, {
  159. date: { year: 172, month: 1, day: 1 },
  160. latitude: 65.0,
  161. longitude: -19.0,
  162. timezone: 'Atlantic/Reykjavik',
  163. fixedTimes: '18:00:00|06:00:00|13:00:00|18:00:00',
  164. solarTimes: '19:31:00|07:14:00|13:23:00|19:34:00',
  165. clockLocation: 'Iceland',
  166. }, {
  167. date: { year: 172, month: 1, day: 1 },
  168. latitude: 60.0,
  169. longitude: 10.0,
  170. timezone: 'Europe/Oslo',
  171. fixedTimes: '18:00:00|06:00:00|12:00:00|18:00:00',
  172. solarTimes: '18:34:00|06:20:00|12:27:00|18:36:00',
  173. clockLocation: 'Norway',
  174. }, {
  175. date: { year: 172, month: 1, day: 1 },
  176. latitude: 65.0,
  177. longitude: 17.0,
  178. timezone: 'Europe/Stockholm',
  179. fixedTimes: '18:00:00|06:00:00|12:00:00|18:00:00',
  180. solarTimes: '18:07:00|05:51:00|11:59:00|18:10:00',
  181. clockLocation: 'Sweden',
  182. }, {
  183. date: { year: 172, month: 1, day: 1 },
  184. latitude: 65.0,
  185. longitude: 28.0,
  186. timezone: 'Europe/Helsinki',
  187. fixedTimes: '18:00:00|06:00:00|12:00:00|18:00:00',
  188. solarTimes: '18:23:00|06:07:00|12:15:00|18:26:00',
  189. clockLocation: 'Finland',
  190. }, {
  191. date: { year: 172, month: 19, day: 19 },
  192. latitude: 65.0,
  193. longitude: 28.0,
  194. timezone: 'Europe/Helsinki',
  195. fixedTimes: '18:19:00|06:11:00|12:16:00|18:22:00',
  196. solarTimes: '18:19:00|06:11:00|12:16:00|18:22:00',
  197. clockLocation: 'Finland',
  198. },
  199. ];
  200. clockLocationDates.forEach(({ date, latitude, longitude, timezone, fixedTimes, clockLocation }) => {
  201. it('should output the appropriate time for areas where fixed times are used', () => {
  202. const badiDate = new LocalBadiDate(date, latitude, longitude, timezone);
  203. expect(timesString(badiDate)).toEqual(fixedTimes);
  204. expect(badiDate.clockLocation).toEqual(clockLocation);
  205. });
  206. });
  207. clockLocationDates.forEach(({ date, latitude, longitude, timezone, solarTimes }) => {
  208. it('should not output fixed times if useClockLocations if false', () => {
  209. badiDateSettings({ useClockLocations: false });
  210. const badiDate = new LocalBadiDate(date, latitude, longitude, timezone);
  211. expect(timesString(badiDate)).toEqual(solarTimes);
  212. expect(badiDate.clockLocation).toBeUndefined();
  213. });
  214. });
  215. describe('should determine the correct region for the given coordinates', () => {
  216. beforeEach(() => {
  217. badiDateSettings({ useClockLocations: true });
  218. });
  219. const valueMapping = [undefined, 'USA', 'Canada', 'Iceland', 'Norway', 'Sweden', 'Finland'];
  220. for (let i = 0; i < 40; i++) {
  221. const lat = 90 - i;
  222. for (let j = 0; j < 360; j++) {
  223. const lng = -180 + j;
  224. it(`latitude: ${lat}, longitude: ${lng}`, () => {
  225. expect(clockLocationFromPolygons(lat, lng)).toEqual(valueMapping[clockMap[i][j]]);
  226. });
  227. }
  228. }
  229. });
  230. });
  231. describe('the Holy Day commemoration times', () => {
  232. const holyDayDates = [
  233. { date: { year: 172, holyDayNumber: 1 }, commemorationTime: undefined },
  234. { date: { year: 172, holyDayNumber: 2 }, commemorationTime: '16:00:00' },
  235. { date: { year: 172, holyDayNumber: 3 }, commemorationTime: undefined },
  236. { date: { year: 172, holyDayNumber: 4 }, commemorationTime: undefined },
  237. { date: { year: 172, holyDayNumber: 5 }, commemorationTime: '21:48:00' },
  238. { date: { year: 172, holyDayNumber: 6 }, commemorationTime: '04:00:00' },
  239. { date: { year: 172, holyDayNumber: 7 }, commemorationTime: '12:45:00' },
  240. { date: { year: 172, holyDayNumber: 8 }, commemorationTime: undefined },
  241. { date: { year: 172, holyDayNumber: 9 }, commemorationTime: undefined },
  242. { date: { year: 172, holyDayNumber: 10 }, commemorationTime: undefined },
  243. { date: { year: 172, holyDayNumber: 11 }, commemorationTime: '01:00:00' },
  244. ];
  245. holyDayDates.forEach(({ date, commemorationTime }) => {
  246. it('should show the correct comemmoration time where appropriate', () => {
  247. const badiDate = new LocalBadiDate(date, bahjiLat, bahjiLng, 'Asia/Jerusalem');
  248. expect(badiDate.holyDayCommemoration?.toFormat?.('HH:mm:ss')).toEqual(commemorationTime);
  249. });
  250. });
  251. const southernHemisphereCommemorationTimes = [
  252. { date: { year: 172, holyDayNumber: 2 }, commemorationTime: '15:00:00' },
  253. { date: { year: 172, holyDayNumber: 6 }, commemorationTime: '03:00:00' },
  254. { date: { year: 172, holyDayNumber: 11 }, commemorationTime: '02:00:00' },
  255. ];
  256. southernHemisphereCommemorationTimes.forEach(({ date, commemorationTime }) => {
  257. it('should show the correct commemoration time in the southern hemisphere with DST', () => {
  258. const badiDate = new LocalBadiDate(date, 33.8, 151.2, 'Australia/Sydney');
  259. expect(badiDate.holyDayCommemoration.toFormat?.('HH:mm:ss')).toEqual(commemorationTime);
  260. });
  261. });
  262. });