|
1 | | -import { describe, it, expect, beforeAll } from 'vitest'; |
2 | | -import * as sweph from './index'; |
3 | | -import { initializeSweph } from './utils'; |
| 1 | +import { describe, it, expect } from 'vitest'; |
| 2 | +import * as nodeSweph from './index'; |
4 | 3 |
|
5 | | -describe('@AstroFusion/sweph', () => { |
6 | | - beforeAll(async () => { |
7 | | - await initializeSweph(); |
8 | | - }); |
9 | | - it('should export all main functions', () => { |
10 | | - expect(typeof sweph.calculatePlanets).toBe('function'); |
11 | | - expect(typeof sweph.calculateLagna).toBe('function'); |
12 | | - expect(typeof sweph.calculateSunTimes).toBe('function'); |
13 | | - expect(typeof sweph.calculateMoonData).toBe('function'); |
14 | | - }); |
15 | | - |
16 | | - it('should export constants', () => { |
17 | | - expect(sweph.PLANETS).toBeDefined(); |
18 | | - expect(sweph.AYANAMSA).toBeDefined(); |
19 | | - expect(sweph.HOUSE_SYSTEMS).toBeDefined(); |
20 | | - }); |
21 | | - |
22 | | - it('should have proper constants structure', () => { |
23 | | - expect(sweph.PLANETS.SUN).toBeDefined(); |
24 | | - expect(sweph.PLANETS.MOON).toBeDefined(); |
25 | | - expect(sweph.PLANETS.SUN.name).toBe('Sun'); |
26 | | - }); |
27 | | - |
28 | | - it('should export types', () => { |
29 | | - // Type exports don't create runtime values, but we can test that the module loads |
30 | | - expect(sweph).toBeDefined(); |
31 | | - }); |
32 | | - |
33 | | - describe('Sun Calculations', () => { |
34 | | - const testLocation = { latitude: 40.7128, longitude: -74.0060, timezone: -5 }; |
35 | | - const testDate = new Date('2024-03-15T12:00:00Z'); // Spring equinox |
36 | | - |
37 | | - it('calculateSunTimes should return complete sun times data', () => { |
38 | | - const sunTimes = sweph.calculateSunTimes(testDate, testLocation); |
39 | | - |
40 | | - expect(sunTimes).toBeDefined(); |
41 | | - expect(sunTimes.sunrise).toBeInstanceOf(Date); |
42 | | - expect(sunTimes.sunset).toBeInstanceOf(Date); |
43 | | - expect(sunTimes.solarNoon).toBeInstanceOf(Date); |
44 | | - expect(typeof sunTimes.dayLength).toBe('number'); |
45 | | - expect(sunTimes.dayLength).toBeGreaterThan(0); |
46 | | - expect(sunTimes.dayLength).toBeLessThan(24); |
47 | | - |
48 | | - // Sunrise should be before solar noon, solar noon before sunset |
49 | | - expect(sunTimes.sunrise!.getTime()).toBeLessThan(sunTimes.solarNoon.getTime()); |
50 | | - expect(sunTimes.solarNoon.getTime()).toBeLessThan(sunTimes.sunset!.getTime()); |
51 | | - |
52 | | - // Civil twilight should exist |
53 | | - expect(sunTimes.civilTwilightStart).toBeDefined(); |
54 | | - expect(sunTimes.civilTwilightEnd).toBeDefined(); |
55 | | - }); |
56 | | - |
57 | | - it('calculateSolarNoon should return solar noon data', () => { |
58 | | - const solarNoon = sweph.calculateSolarNoon(testDate, testLocation); |
59 | | - |
60 | | - expect(solarNoon).toBeDefined(); |
61 | | - expect(solarNoon.time).toBeInstanceOf(Date); |
62 | | - expect(typeof solarNoon.altitude).toBe('number'); |
63 | | - expect(solarNoon.altitude).toBeGreaterThan(0); |
64 | | - expect(solarNoon.altitude).toBeLessThan(90); |
65 | | - }); |
66 | | - |
67 | | - it('calculateSunPath should return hourly sun positions', () => { |
68 | | - const sunPath = sweph.calculateSunPath(testDate, testLocation); |
69 | | - |
70 | | - expect(sunPath).toBeDefined(); |
71 | | - expect(Array.isArray(sunPath)).toBe(true); |
72 | | - expect(sunPath.length).toBe(24); // 24 hours |
73 | | - |
74 | | - sunPath.forEach((position) => { |
75 | | - expect(position).toHaveProperty('time'); |
76 | | - expect(position).toHaveProperty('azimuth'); |
77 | | - expect(position).toHaveProperty('altitude'); |
78 | | - expect(position.time).toBeInstanceOf(Date); |
79 | | - expect(typeof position.azimuth).toBe('number'); |
80 | | - expect(typeof position.altitude).toBe('number'); |
81 | | - expect(position.azimuth).toBeGreaterThanOrEqual(0); |
82 | | - expect(position.azimuth).toBeLessThanOrEqual(360); |
83 | | - expect(position.altitude).toBeGreaterThanOrEqual(-90); |
84 | | - expect(position.altitude).toBeLessThanOrEqual(90); |
85 | | - }); |
86 | | - }); |
87 | | - }); |
88 | | - |
89 | | - describe('Moon Calculations', () => { |
90 | | - const testLocation = { latitude: 27.7172, longitude: 85.324, timezone: 5.75 }; |
91 | | - const testDate = new Date(); // Use current date for moon phases test |
92 | | - |
93 | | - it('calculateMoonData should return complete moon data', () => { |
94 | | - const moonData = sweph.calculateMoonData(testDate, testLocation); |
95 | | - |
96 | | - expect(moonData).toBeDefined(); |
97 | | - expect(typeof moonData.illumination).toBe('number'); |
98 | | - expect(typeof moonData.age).toBe('number'); |
99 | | - expect(typeof moonData.phase).toBe('number'); |
100 | | - expect(typeof moonData.phaseName).toBe('string'); |
101 | | - expect(typeof moonData.distance).toBe('number'); |
102 | | - |
103 | | - expect(moonData.illumination).toBeGreaterThanOrEqual(0); |
104 | | - expect(moonData.illumination).toBeLessThanOrEqual(100); |
105 | | - expect(moonData.age).toBeGreaterThanOrEqual(0); |
106 | | - expect(moonData.age).toBeLessThanOrEqual(29.5); |
107 | | - expect(moonData.phase).toBeGreaterThanOrEqual(0); |
108 | | - expect(moonData.phase).toBeLessThanOrEqual(360); |
109 | | - expect(moonData.distance).toBeGreaterThan(360000); // km, greater than Earth-Moon distance |
110 | | - |
111 | | - // Rise/set times might be null for some locations/dates |
112 | | - if (moonData.moonrise) { |
113 | | - expect(moonData.moonrise).toBeInstanceOf(Date); |
114 | | - } |
115 | | - if (moonData.moonset) { |
116 | | - expect(moonData.moonset).toBeInstanceOf(Date); |
117 | | - } |
118 | | - if (moonData.transit) { |
119 | | - expect(moonData.transit).toBeInstanceOf(Date); |
120 | | - } |
121 | | - }); |
122 | | - |
123 | | - it('calculateMoonPhase should return phase information', () => { |
124 | | - const phase = sweph.calculateMoonPhase(testDate); |
125 | | - |
126 | | - expect(phase).toBeDefined(); |
127 | | - expect(typeof phase.phase).toBe('number'); |
128 | | - expect(typeof phase.illumination).toBe('number'); |
129 | | - expect(typeof phase.age).toBe('number'); |
130 | | - expect(typeof phase.phaseName).toBe('string'); |
131 | | - |
132 | | - expect(phase.phase).toBeGreaterThanOrEqual(0); |
133 | | - expect(phase.phase).toBeLessThanOrEqual(360); |
134 | | - expect(phase.illumination).toBeGreaterThanOrEqual(0); |
135 | | - expect(phase.illumination).toBeLessThanOrEqual(100); |
136 | | - expect(phase.age).toBeGreaterThanOrEqual(0); |
137 | | - expect(phase.age).toBeLessThanOrEqual(29.5); |
138 | | - }); |
139 | | - |
140 | | - it('calculateNextMoonPhases should return upcoming moon phases', () => { |
141 | | - const phases = sweph.calculateNextMoonPhases(testDate); |
142 | | - |
143 | | - expect(phases).toBeDefined(); |
144 | | - expect(phases.newMoon).toBeInstanceOf(Date); |
145 | | - expect(phases.firstQuarter).toBeInstanceOf(Date); |
146 | | - expect(phases.fullMoon).toBeInstanceOf(Date); |
147 | | - expect(phases.lastQuarter).toBeInstanceOf(Date); |
148 | | - |
149 | | - // All phases should be in the future |
150 | | - const now = new Date(); |
151 | | - expect(phases.newMoon.getTime()).toBeGreaterThan(now.getTime()); |
152 | | - expect(phases.firstQuarter.getTime()).toBeGreaterThan(now.getTime()); |
153 | | - expect(phases.fullMoon.getTime()).toBeGreaterThan(now.getTime()); |
154 | | - expect(phases.lastQuarter.getTime()).toBeGreaterThan(now.getTime()); |
| 4 | +describe('@af/sweph-node', () => { |
| 5 | + it('should export core functions', () => { |
| 6 | + expect(nodeSweph.calculatePlanets).toBeDefined(); |
| 7 | + expect(nodeSweph.calculateHouses).toBeDefined(); |
155 | 8 | }); |
156 | | - }); |
157 | | - |
158 | | - describe('Planet Calculations', () => { |
159 | | - const testLocation = { latitude: 28.6139, longitude: 77.2090, timezone: 5.5 }; |
160 | | - const testDate = new Date('2024-03-15T12:00:00Z'); |
161 | | - |
162 | | - it('calculatePlanets should return all 9 Vedic planets', () => { |
163 | | - const planets = sweph.calculatePlanets(testDate, { location: testLocation }); |
164 | | - |
165 | | - expect(planets).toBeDefined(); |
166 | | - expect(Array.isArray(planets)).toBe(true); |
167 | | - expect(planets.length).toBe(9); // Sun, Moon, Mars, Mercury, Jupiter, Venus, Saturn, Rahu, Ketu |
168 | | - |
169 | | - planets.forEach((planet) => { |
170 | | - expect(planet).toHaveProperty('id'); |
171 | | - expect(planet).toHaveProperty('name'); |
172 | | - expect(planet).toHaveProperty('longitude'); |
173 | | - expect(planet).toHaveProperty('latitude'); |
174 | | - expect(planet).toHaveProperty('distance'); |
175 | | - expect(planet).toHaveProperty('speed'); |
176 | | - expect(planet).toHaveProperty('rasi'); |
177 | | - expect(planet).toHaveProperty('rasiDegree'); |
178 | | - expect(planet).toHaveProperty('isRetrograde'); |
179 | | - expect(planet).toHaveProperty('totalDegree'); |
180 | | - |
181 | | - expect(typeof planet.longitude).toBe('number'); |
182 | | - expect(typeof planet.latitude).toBe('number'); |
183 | | - expect(typeof planet.distance).toBe('number'); |
184 | | - expect(typeof planet.speed).toBe('number'); |
185 | | - expect(typeof planet.rasi).toBe('number'); |
186 | | - expect(typeof planet.rasiDegree).toBe('number'); |
187 | | - expect(typeof planet.isRetrograde).toBe('boolean'); |
188 | | - expect(typeof planet.totalDegree).toBe('number'); |
189 | | - |
190 | | - expect(planet.longitude).toBeGreaterThanOrEqual(0); |
191 | | - expect(planet.longitude).toBeLessThanOrEqual(360); |
192 | | - expect(planet.rasi).toBeGreaterThanOrEqual(1); |
193 | | - expect(planet.rasi).toBeLessThanOrEqual(12); |
194 | | - expect(planet.rasiDegree).toBeGreaterThanOrEqual(0); |
195 | | - expect(planet.rasiDegree).toBeLessThanOrEqual(30); |
196 | | - }); |
197 | | - |
198 | | - // Check specific planets |
199 | | - const sun = planets.find(p => p.name === 'Sun'); |
200 | | - const moon = planets.find(p => p.name === 'Moon'); |
201 | | - const mars = planets.find(p => p.name === 'Mars'); |
202 | | - |
203 | | - expect(sun).toBeDefined(); |
204 | | - expect(moon).toBeDefined(); |
205 | | - expect(mars).toBeDefined(); |
206 | | - }); |
207 | | - |
208 | | - it('calculateSinglePlanet should return individual planet data', () => { |
209 | | - const sun = sweph.calculateSinglePlanet(sweph.PLANETS.SUN.id, testDate, { location: testLocation }); |
210 | | - |
211 | | - expect(sun).toBeDefined(); |
212 | | - expect(typeof sun!.name).toBe('string'); |
213 | | - expect(sun!.name).toBe('Sun'); |
214 | | - expect(typeof sun!.longitude).toBe('number'); |
215 | | - expect(typeof sun!.latitude).toBe('number'); |
216 | | - expect(typeof sun!.distance).toBe('number'); |
217 | | - expect(typeof sun!.speed).toBe('number'); |
218 | | - expect(sun!.longitude).toBeGreaterThanOrEqual(0); |
219 | | - expect(sun!.longitude).toBeLessThanOrEqual(360); |
220 | | - }); |
221 | | - |
222 | | - it('calculatePlanetRiseSetTimes should return rise/set/transit times', () => { |
223 | | - const sunTimes = sweph.calculatePlanetRiseSetTimes(sweph.PLANETS.SUN.id, testDate, testLocation); |
224 | | - |
225 | | - expect(sunTimes).toBeDefined(); |
226 | | - expect(typeof sunTimes.rise).toBe('object'); // Could be Date or null |
227 | | - expect(typeof sunTimes.set).toBe('object'); // Could be Date or null |
228 | | - expect(typeof sunTimes.transit).toBe('object'); // Could be Date or null |
229 | | - expect(typeof sunTimes.transitAltitude).toBe('number'); |
230 | | - expect(typeof sunTimes.transitDistance).toBe('number'); |
231 | | - |
232 | | - if (sunTimes.rise) { |
233 | | - expect(sunTimes.rise).toBeInstanceOf(Date); |
234 | | - } |
235 | | - if (sunTimes.set) { |
236 | | - expect(sunTimes.set).toBeInstanceOf(Date); |
237 | | - } |
238 | | - if (sunTimes.transit) { |
239 | | - expect(sunTimes.transit).toBeInstanceOf(Date); |
240 | | - } |
241 | | - |
242 | | - expect(sunTimes.transitAltitude).toBeGreaterThanOrEqual(0); |
243 | | - expect(sunTimes.transitAltitude).toBeLessThanOrEqual(90); |
244 | | - expect(sunTimes.transitDistance).toBeGreaterThanOrEqual(0); |
245 | | - }); |
246 | | - |
247 | | - it('calculatePlanetRiseSetTimes should work for different planets', () => { |
248 | | - const planetsToTest = [ |
249 | | - sweph.PLANETS.SUN.id, |
250 | | - sweph.PLANETS.MOON.id, |
251 | | - sweph.PLANETS.MARS.id, |
252 | | - sweph.PLANETS.VENUS.id |
253 | | - ]; |
254 | | - |
255 | | - planetsToTest.forEach((planetId) => { |
256 | | - const times = sweph.calculatePlanetRiseSetTimes(planetId, testDate, testLocation); |
257 | | - expect(times).toBeDefined(); |
258 | | - expect(typeof times.transitAltitude).toBe('number'); |
259 | | - expect(typeof times.transitDistance).toBe('number'); |
260 | | - }); |
261 | | - }); |
262 | | - }); |
263 | | - |
264 | | - describe('Integration Tests', () => { |
265 | | - const testLocation = { latitude: 40.7128, longitude: -74.0060, timezone: -5 }; |
266 | | - const testDate = new Date('2024-03-15T12:00:00Z'); // Spring equinox |
267 | | - |
268 | | - it('sun and moon calculations should be consistent', () => { |
269 | | - const sunTimes = sweph.calculateSunTimes(testDate, testLocation); |
270 | | - const moonData = sweph.calculateMoonData(testDate, testLocation); |
271 | | - |
272 | | - // Both should return valid data |
273 | | - expect(sunTimes.sunrise).toBeDefined(); |
274 | | - expect(moonData.illumination).toBeDefined(); |
275 | | - |
276 | | - // Solar day should be reasonable length (around 12 hours at equinox) |
277 | | - expect(sunTimes.dayLength).toBeGreaterThan(11); |
278 | | - expect(sunTimes.dayLength).toBeLessThan(13); |
279 | | - }); |
280 | | - |
281 | | - it('planet positions should be within valid ranges', () => { |
282 | | - const planets = sweph.calculatePlanets(testDate); |
283 | | - |
284 | | - planets.forEach((planet) => { |
285 | | - // Longitude should be 0-360 |
286 | | - expect(planet.longitude).toBeGreaterThanOrEqual(0); |
287 | | - expect(planet.longitude).toBeLessThanOrEqual(360); |
288 | | - |
289 | | - // Rasi should be 1-12 |
290 | | - expect(planet.rasi).toBeGreaterThanOrEqual(1); |
291 | | - expect(planet.rasi).toBeLessThanOrEqual(12); |
292 | 9 |
|
293 | | - // Rasi degree should be 0-30 |
294 | | - expect(planet.rasiDegree).toBeGreaterThanOrEqual(0); |
295 | | - expect(planet.rasiDegree).toBeLessThanOrEqual(30); |
296 | | - }); |
| 10 | + it('should export legacy factory functions', () => { |
| 11 | + expect(nodeSweph.createSwephCalculator).toBeDefined(); |
297 | 12 | }); |
298 | | - }); |
299 | 13 | }); |
0 commit comments