From 188071eb7b598e89a7b911685d565800de10bf6a Mon Sep 17 00:00:00 2001 From: Theodore Kruczek Date: Sat, 13 Jan 2024 13:06:42 -0500 Subject: [PATCH] test: :white_check_mark: improve test coverage and import order --- .eslintrc.json | 4 +- .vscode/tasks.json | 30 +- jest.config.ts | 17 +- package.json | 5 +- src/body/Celestial.ts | 53 ++- src/body/Earth.ts | 26 +- src/body/Moon.ts | 6 +- src/body/NutationAngles.ts | 22 +- src/body/PrecessionAngles.ts | 4 +- src/body/Sun.ts | 32 +- src/coordinate/ClassicalElements.ts | 7 +- src/coordinate/EquinoctialElements.ts | 5 +- src/coordinate/FormatTle.ts | 2 +- src/coordinate/Tle.ts | 9 +- src/index.ts | 22 +- src/objects/BaseObject.ts | 2 +- src/objects/RadarSensor.ts | 12 + src/objects/Satellite.ts | 4 +- src/objects/Star.ts | 21 +- src/objects/index.ts | 1 + src/sgp4/sgp4.ts | 3 +- src/transforms/conversions.ts | 3 +- src/transforms/transforms.ts | 16 +- src/types/types.ts | 9 - src/utils/constants.ts | 2 + src/utils/functions.ts | 49 +- src/utils/index.ts | 4 + src/utils/jacobian.ts | 40 ++ src/utils/linearDistance.ts | 11 + test/body/Celestial.test.ts | 79 ++++ test/body/Earth.test.ts | 128 ++++++ test/body/Moon.test.ts | 139 ++++++ test/body/Sun.test.ts | 189 ++++++++ .../body/__snapshots__/Celestial.test.ts.snap | 20 + test/body/__snapshots__/Earth.test.ts.snap | 39 ++ test/body/__snapshots__/Moon.test.ts.snap | 100 +++++ test/body/__snapshots__/Sun.test.ts.snap | 89 ++++ test/index.test.ts | 37 ++ test/lib/compareVectors.ts | 2 +- test/lib/mockData.ts | 1 + test/objects/BaseObject.test.ts | 260 +++++++++++ test/objects/Satellite.test.ts | 173 +++++++ .../__snapshots__/Satellite.test.ts.snap | 423 ++++++++++++++++++ .../__snapshots__/sensor.test.ts.snap | 0 .../__snapshots__/sun-moon.test.ts.snap | 0 test/{sat => objects}/sensor.test.ts | 8 +- test/objects/star.test.ts | 8 +- test/{sun-moon => objects}/sun-moon.test.ts | 30 +- test/sat/sat.test.ts | 68 --- test/sgp4/full-catalog/sgp4-catalog-0.test.js | 2 +- test/sgp4/full-catalog/sgp4-catalog-1.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-10.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-11.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-12.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-13.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-14.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-15.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-16.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-17.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-18.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-19.test.js | 2 +- test/sgp4/full-catalog/sgp4-catalog-2.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-20.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-21.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-22.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-23.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-24.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-25.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-26.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-27.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-28.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-29.test.js | 2 +- test/sgp4/full-catalog/sgp4-catalog-3.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-30.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-31.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-32.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-33.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-34.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-35.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-36.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-37.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-38.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-39.test.js | 2 +- test/sgp4/full-catalog/sgp4-catalog-4.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-40.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-41.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-42.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-43.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-44.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-45.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-46.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-47.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-48.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-49.test.js | 2 +- test/sgp4/full-catalog/sgp4-catalog-5.test.js | 2 +- .../sgp4/full-catalog/sgp4-catalog-50.test.js | 2 +- test/sgp4/full-catalog/sgp4-catalog-6.test.js | 2 +- test/sgp4/full-catalog/sgp4-catalog-7.test.js | 2 +- test/sgp4/full-catalog/sgp4-catalog-8.test.js | 2 +- test/sgp4/full-catalog/sgp4-catalog-9.test.js | 2 +- test/sgp4/full-catalog/sgp4TestMaker.mjs | 2 +- test/sgp4/legacy/ext.test.js | 2 +- test/sgp4/legacy/initl.test.js | 2 +- test/sgp4/legacy/io.test.js | 2 +- test/sgp4/rsr/rsr3.test.js | 2 +- test/sgp4/sgp4-full-cov-fail.json | 32 -- test/sgp4/sgp4-full-cov-fail.ts | 32 ++ test/sgp4/sgp4-full-cov.json | 82 ---- ...full-cov.test.js => sgp4-full-cov.test.ts} | 120 ++--- test/sgp4/sgp4-full-cov.ts | 82 ++++ test/tle/tle.test.ts | 9 +- test/tle/tleData.ts | 2 +- test/transforms/transforms.test.ts | 2 +- test/transforms/transformsData.ts | 2 +- test/utils/utils.test.ts | 9 +- 115 files changed, 2168 insertions(+), 530 deletions(-) create mode 100644 src/objects/RadarSensor.ts create mode 100644 src/utils/index.ts create mode 100644 src/utils/jacobian.ts create mode 100644 src/utils/linearDistance.ts create mode 100644 test/body/Celestial.test.ts create mode 100644 test/body/Earth.test.ts create mode 100644 test/body/Moon.test.ts create mode 100644 test/body/Sun.test.ts create mode 100644 test/body/__snapshots__/Celestial.test.ts.snap create mode 100644 test/body/__snapshots__/Earth.test.ts.snap create mode 100644 test/body/__snapshots__/Moon.test.ts.snap create mode 100644 test/body/__snapshots__/Sun.test.ts.snap create mode 100644 test/index.test.ts create mode 100644 test/lib/mockData.ts create mode 100644 test/objects/BaseObject.test.ts create mode 100644 test/objects/Satellite.test.ts create mode 100644 test/objects/__snapshots__/Satellite.test.ts.snap rename test/{sat => objects}/__snapshots__/sensor.test.ts.snap (100%) rename test/{sun-moon => objects}/__snapshots__/sun-moon.test.ts.snap (100%) rename test/{sat => objects}/sensor.test.ts (97%) rename test/{sun-moon => objects}/sun-moon.test.ts (93%) delete mode 100644 test/sat/sat.test.ts delete mode 100644 test/sgp4/sgp4-full-cov-fail.json create mode 100644 test/sgp4/sgp4-full-cov-fail.ts delete mode 100644 test/sgp4/sgp4-full-cov.json rename test/sgp4/{sgp4-full-cov.test.js => sgp4-full-cov.test.ts} (51%) create mode 100644 test/sgp4/sgp4-full-cov.ts diff --git a/.eslintrc.json b/.eslintrc.json index 2175cb8..c1a1dd8 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -182,7 +182,7 @@ "no-useless-return": "error", "no-var": "error", "no-void": "error", - "no-warning-comments": "error", + "no-warning-comments": "warn", "no-whitespace-before-property": "error", "nonblock-statement-body-position": "error", "object-curly-newline": "error", @@ -209,7 +209,7 @@ "prefer-spread": "error", "prefer-template": "error", "quote-props": "off", - "quotes": ["error", "single"], + "quotes": ["off", "single"], "radix": "off", "require-atomic-updates": "error", "require-await": "error", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 53fc656..e4a4027 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -26,8 +26,8 @@ } }, { - "label": "Test without Building", - "command": "npm run test:nobuild", + "label": "Test for Coverage", + "command": "npm run test:coverage", "type": "shell", "args": [], "isBackground": true, @@ -38,15 +38,25 @@ } }, { - "label": "Open Test Coverage", - "command": "npm run lcov", - "type": "shell", - "args": [], - "isBackground": true, - "problemMatcher": [], + "label": "Open Coverage in Brave", + "type": "process", + "command": "", + "windows": { + "command": "C:/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", + "args": ["${workspaceFolder}/coverage/lcov-report/index.html"] + }, "icon": { - "id": "file-code", - "color": "terminal.ansiYellow" + "id": "browser", + "color": "terminal.ansiCyan" + }, + "presentation": { + "echo": false, + "reveal": "never", + "focus": false, + "panel": "new", + "showReuseMessage": false, + "clear": true, + "close": true } } ], diff --git a/jest.config.ts b/jest.config.ts index 4b5bdd5..3597688 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -3,22 +3,13 @@ const jestConfig = { transform: { '\\.(js|ts|jsx|tsx)$': 'babel-jest', }, - testPathIgnorePatterns: ['/dist', '/lib', '/scripts', '/coverage'], - transformIgnorePatterns: ['dist', 'scripts', 'coverage'], - testMatch: ['**/?(*.)+(spec|test).?(m)[jt]s?(x)'], + testMatch: ['**/test/**/?(*.)+(spec|test).?(m)[jt]s?(x)'], moduleFileExtensions: ['js', 'mjs', 'ts'], - // setupFiles: [''], coverageDirectory: '/coverage', - moduleDirectories: ['node_modules', 'offline'], - modulePathIgnorePatterns: [ - '/node_modules/', - '/coverage/', - '/dist/', - '/scripts/', - '/test/sgp4/sgp4prop', - ], + moduleDirectories: ['node_modules'], + modulePathIgnorePatterns: ['/node_modules/', '/test/sgp4/sgp4prop'], coverageReporters: ['lcov', 'html', 'text'], - coveragePathIgnorePatterns: ['/node_modules/', '/dist/', '/lib/', '/scripts/', '/coverage/'], + coveragePathIgnorePatterns: ['/node_modules/', '/dist/', '/lib/', '/commonjs/', '/test/', '/scripts/', '/coverage/'], }; export default jestConfig; diff --git a/package.json b/package.json index d03a0ce..ef8b19c 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,7 @@ "build": "node ./scripts/cleanup.mjs && npm run js && npm run cjs && node ./scripts/makeMjs.mjs", "lint": "npx eslint src", "lint:fix": "npx eslint src --fix", - "test": "npm run build && jest", - "test:nobuild": "jest", + "test": "jest", "test:coverage": "jest --coverage", "version": "auto-changelog -p && git add CHANGELOG.md" }, @@ -60,4 +59,4 @@ "typescript-transform-paths": "^3.4.6" }, "homepage": "https://github.com/thkruz/ootk" -} +} \ No newline at end of file diff --git a/src/body/Celestial.ts b/src/body/Celestial.ts index dc5f998..beeaf12 100644 --- a/src/body/Celestial.ts +++ b/src/body/Celestial.ts @@ -1,13 +1,25 @@ -import { AzEl, Degrees, Kilometers, RaDec, Radians } from '..'; -import { RAD2DEG } from '../utils/constants'; -import { Sun } from './Sun'; +import { Sun, RAD2DEG, AzEl, Degrees, Kilometers, RaDec, Radians } from '..'; +/** + * Celestial is a static class that provides methods for calculating the position of celestial objects such + * as the Sun, Moon, and planets in the sky. + */ export class Celestial { private constructor() { // disable constructor } - static getStarAzEl(date: Date, lat: Degrees, lon: Degrees, ra: Radians, dec: Radians): AzEl { + /** + * Calculates the azimuth and elevation of a celestial object at a given date, latitude, + * longitude, right ascension, and declination. + * @param date - The date for which to calculate the azimuth and elevation. + * @param lat - The latitude of the observer. + * @param lon - The longitude of the observer. + * @param ra - The right ascension of the celestial object. + * @param dec - The declination of the celestial object. + * @returns An object containing the azimuth and elevation in degrees. + */ + static azEl(date: Date, lat: Degrees, lon: Degrees, ra: Radians, dec: Radians): AzEl { const c: RaDec = { ra, dec, @@ -15,7 +27,7 @@ export class Celestial { }; const azEl = Sun.azEl(date, lat, lon, c); - const el = (azEl.el + Celestial.astroRefraction(azEl.el)); // elevation correction for refraction + const el = (azEl.el + Celestial.atmosphericRefraction(azEl.el)); // elevation correction for refraction return { az: (azEl.az * RAD2DEG) as Degrees, @@ -24,11 +36,22 @@ export class Celestial { } /** - * get astro refraction + * Atmospheric refraction in astronomy, refers to the bending of light as it passes through the Earth's + * atmosphere. This effect is most noticeable for celestial objects like stars and planets when they are + * close to the horizon. Here's a breakdown of how it works: + * + * Actual Position: Due to this bending of light, the apparent position of a celestial object is slightly + * different from its true position in the sky. When a star or planet is near the horizon, the effect is more + * pronounced because the light path passes through more of the Earth's atmosphere, which increases the amount of + * bending. + * + * A familiar example of atmospheric refraction is observed during sunrise and sunset. The Sun appears to + * be above the horizon when it is actually just below it. This is because the light from the Sun is bent + * upwards as it passes through the atmosphere. * @param {Radians} h - elevation * @returns {number} refraction */ - static astroRefraction(h: Radians): Radians { + static atmosphericRefraction(h: Radians): Radians { if (h < 0) { h = 0; } @@ -37,7 +60,8 @@ export class Celestial { } /** - * get declination + * Calculate the declination. Similar to latitude on Earth, declination is another celestial coordinate. + * It measures how far north or south an object is from the celestial equator * @param {number} l - ecliptic longitude * @param {number} b - ecliptic latitude * @returns {number} declination @@ -47,7 +71,9 @@ export class Celestial { } /** - * get right ascension + * Calculate the right ascension. This is a celestial coordinate used to determine the position of objects + * in the sky. It's analogous to longitude on Earth. Right Ascension indicates how far east an object is + * from the vernal equinox along the celestial equator. * @param {number} l - ecliptic longitude * @param {number} b - ecliptic latitude * @returns {number} right ascension @@ -57,7 +83,10 @@ export class Celestial { } /** - * get elevation (sometimes called altitude) + * Calculate the elevation. Elevation, or altitude, is the angle between an object in the sky and the + * observer's local horizon. It's commonly expressed in degrees, where 0 degrees is right at the horizon + * and 90 degrees is directly overhead (the zenith), but we are using radians to support trigonometric + * functions like Math.sin() and Math.cos(). * @param {number} H - siderealTime * @param {Radians} phi - latitude * @param {Radians} dec - The declination of the sun @@ -68,7 +97,9 @@ export class Celestial { } /** - * get azimuth + * Calculate the azimuth. This is a compass direction measurement. Azimuth measures the angle along + * the horizon from a specific reference direction (usually true north) to the point where a vertical + * line from the object intersects the horizon. * @param {number} H - siderealTime * @param {Radians} phi - latitude * @param {Radians} dec - The declination of the sun diff --git a/src/body/Earth.ts b/src/body/Earth.ts index 9765e0e..aa66821 100644 --- a/src/body/Earth.ts +++ b/src/body/Earth.ts @@ -1,9 +1,21 @@ -import { AngularDiameterMethod, Kilometers, Radians } from '..'; -import { DataHandler } from '../data/DataHandler'; -import { Vector3D } from '../operations/Vector3D'; -import { EpochUTC } from '../time/EpochUTC'; -import { asec2rad, DEG2RAD, RAD2DEG, secondsPerDay, secondsPerSiderealDay, TAU, ttasec2rad } from '../utils/constants'; -import { angularDiameter, evalPoly } from '../utils/functions'; +import { + earthGravityParam, + angularDiameter, + evalPoly, + asec2rad, + DEG2RAD, + RAD2DEG, + secondsPerDay, + secondsPerSiderealDay, + TAU, + ttasec2rad, + EpochUTC, + Vector3D, + DataHandler, + AngularDiameterMethod, + Kilometers, + Radians, +} from '..'; import { NutationAngles } from './NutationAngles'; import { PrecessionAngles } from './PrecessionAngles'; @@ -14,7 +26,7 @@ export class Earth { } // / Earth gravitational parameter _(km²/s³)_. - static readonly mu: number = 398600.4415; + static readonly mu: number = earthGravityParam; // / Earth equatorial radius. static readonly radiusEquator = 6378.1363 as Kilometers; diff --git a/src/body/Moon.ts b/src/body/Moon.ts index a481845..a22b07e 100644 --- a/src/body/Moon.ts +++ b/src/body/Moon.ts @@ -1,6 +1,6 @@ /** * @author Theodore Kruczek. - * @description Orbital Object ToolKit (ootk) is a collection of tools for working + * @description Orbital Object ToolKit Core (ootk-core) is a collection of tools for working * with satellites and other orbital objects. * * Some of the math in this file was originally created by Vladimir Agafonkin. @@ -96,7 +96,7 @@ export class Moon { static radiusEquator = 1738.0; // / Calculate the Moon's ECI position _(km)_ for a given UTC [epoch]. - static eci(epoch: EpochUTC): Vector3D { + static eci(epoch: EpochUTC = EpochUTC.fromDateTime(new Date())): Vector3D { const jc = epoch.toJulianCenturies(); const dtr = DEG2RAD; const lamEcl = @@ -296,7 +296,7 @@ export class Moon { // formula 14.1 of "Astronomical Algorithms" 2nd edition by Jean Meeus (Willmann-Bell, Richmond) 1998. const pa = Math.atan2(Math.sin(H), Math.tan(phi) * Math.cos(c.dec) - Math.sin(c.dec) * Math.cos(H)); - h = (h + Celestial.astroRefraction(h)); // altitude correction for refraction + h = (h + Celestial.atmosphericRefraction(h)); // altitude correction for refraction return { az: Celestial.azimuth(H, phi, c.dec), diff --git a/src/body/NutationAngles.ts b/src/body/NutationAngles.ts index dce2cc3..bfc1e5e 100644 --- a/src/body/NutationAngles.ts +++ b/src/body/NutationAngles.ts @@ -1,11 +1,31 @@ import { Radians } from '..'; -// / Earth nutation angles _(rad)_. +/** + * Represents the nutation angles. + */ export type NutationAngles = { + /** + * The nutation in longitude (Δψ) in radians. + */ dPsi: Radians; + /** + * The nutation in obliquity (Δε) in radians. + */ dEps: Radians; + /** + * The mean obliquity of the ecliptic (ε₀) in radians. + */ mEps: Radians; + /** + * The true obliquity of the ecliptic (ε) in radians. + */ eps: Radians; + /** + * The equation of the equinoxes (ΔΔt) in radians. + */ eqEq: Radians; + /** + * The Greenwich Apparent Sidereal Time (GAST) in radians. + */ gast: Radians; }; diff --git a/src/body/PrecessionAngles.ts b/src/body/PrecessionAngles.ts index 3a2ba27..9e35044 100644 --- a/src/body/PrecessionAngles.ts +++ b/src/body/PrecessionAngles.ts @@ -1,6 +1,8 @@ import { Radians } from '..'; -// / Earth precession angles _(rad)_. +/** + * Represents the precession angles in radians. + */ export type PrecessionAngles = { zeta: Radians; theta: Radians; diff --git a/src/body/Sun.ts b/src/body/Sun.ts index 9ddd161..438b20b 100644 --- a/src/body/Sun.ts +++ b/src/body/Sun.ts @@ -1,10 +1,24 @@ -import { AngularDiameterMethod, AzEl, Degrees, Kilometers, Meters, RaDec, Radians, SunTime } from '..'; -import { Vector3D } from '../operations/Vector3D'; -import { EpochUTC } from '../time/EpochUTC'; -import { astronomicalUnit, cKmPerSec, DEG2RAD, MS_PER_DAY, RAD2DEG, TAU } from '../utils/constants'; -import { angularDiameter } from '../utils/functions'; -import { Celestial } from './Celestial'; -import { Earth } from './Earth'; +import { + Earth, + Celestial, + angularDiameter, + astronomicalUnit, + cKmPerSec, + DEG2RAD, + MS_PER_DAY, + RAD2DEG, + TAU, + EpochUTC, + Vector3D, + AngularDiameterMethod, + AzEl, + Degrees, + Kilometers, + Meters, + RaDec, + Radians, + SunTime, +} from '..'; /** * Sun metrics and operations. @@ -163,7 +177,7 @@ export class Sun { /** * returns set time for the given sun altitude - * @param {number} h - heigh at 0 + * @param {number} h - height at 0 * @param {number} lw - rad * -lng * @param {number} phi - rad * lat; * @param {number} dec - declination @@ -347,7 +361,7 @@ export class Sun { * @param {Degrees} lon - Degrees longitude * @returns {number} julian cycle */ - static julianCyle(date: Date, lon: Degrees): number { + static julianCycle(date: Date, lon: Degrees): number { const lw = (-lon * DEG2RAD); const d = Sun.date2jSince2000(date); diff --git a/src/coordinate/ClassicalElements.ts b/src/coordinate/ClassicalElements.ts index bbcb7a5..f2cc084 100644 --- a/src/coordinate/ClassicalElements.ts +++ b/src/coordinate/ClassicalElements.ts @@ -1,7 +1,6 @@ -import { Earth } from '../body/Earth'; import { Vector3D } from '../operations/Vector3D'; import { EpochUTC } from '../time/EpochUTC'; -import { RAD2DEG, sec2min, secondsPerDay, TAU } from '../utils/constants'; +import { earthGravityParam, RAD2DEG, sec2min, secondsPerDay, TAU } from '../utils/constants'; import { clamp, matchHalfPlane, newtonNu } from '../utils/functions'; import { EquinoctialElements } from './EquinoctialElements'; import { OrbitRegime } from './OrbitRegime'; @@ -46,7 +45,7 @@ export class ClassicalElements { rightAscension, argPerigee, trueAnomaly, - mu = Earth.mu, + mu = earthGravityParam, }: ClassicalElementsParams) { this.epoch = epoch; this.semimajorAxis = semimajorAxis; @@ -65,7 +64,7 @@ export class ClassicalElements { * @returns A new instance of ClassicalElements. * @throws Error if classical elements are undefined for fixed frames. */ - static fromStateVector(state: StateVector, mu = Earth.mu): ClassicalElements { + static fromStateVector(state: StateVector, mu = earthGravityParam): ClassicalElements { if (!state.inertial) { throw new Error('Classical elements are undefined for fixed frames.'); } diff --git a/src/coordinate/EquinoctialElements.ts b/src/coordinate/EquinoctialElements.ts index 91c2188..6912b09 100644 --- a/src/coordinate/EquinoctialElements.ts +++ b/src/coordinate/EquinoctialElements.ts @@ -1,6 +1,5 @@ -import { Earth } from '../body/Earth'; import { EpochUTC } from '../time/EpochUTC'; -import { secondsPerDay, TAU } from '../utils/constants'; +import { earthGravityParam, secondsPerDay, TAU } from '../utils/constants'; import { newtonM } from '../utils/functions'; import { ClassicalElements } from './ClassicalElements'; import { PositionVelocity } from './StateVector'; @@ -17,7 +16,7 @@ export class EquinoctialElements { public n: number, public chi: number, public psi: number, - { mu = Earth.mu, fr = 1 }: { mu?: number; fr?: number } = {}, + { mu = earthGravityParam, fr = 1 }: { mu?: number; fr?: number } = {}, ) { this.mu = mu; this.fr = fr; diff --git a/src/coordinate/FormatTle.ts b/src/coordinate/FormatTle.ts index 4a2837d..d88e0bf 100644 --- a/src/coordinate/FormatTle.ts +++ b/src/coordinate/FormatTle.ts @@ -1,4 +1,4 @@ -import { Satellite } from '../objects'; +import type { Satellite } from '../objects'; import { Tle } from './Tle'; export type StringifiedNumber = `${number}.${number}`; diff --git a/src/coordinate/Tle.ts b/src/coordinate/Tle.ts index 80c1f1b..c2d4374 100644 --- a/src/coordinate/Tle.ts +++ b/src/coordinate/Tle.ts @@ -1,6 +1,6 @@ /** * @author Theodore Kruczek. - * @description Orbital Object ToolKit (ootk) is a collection of tools for working + * @description Orbital Object ToolKit Core (ootk-core) is a collection of tools for working * with satellites and other orbital objects. * * @file The Tle module contains a collection of functions for working with TLEs. @@ -27,7 +27,6 @@ import { ClassicalElements, FormatTle, TEME } from '.'; import { Sgp4, Vector3D } from '..'; -import { Earth } from '../body'; import { Sgp4OpsMode } from '../enums/Sgp4OpsMode'; import { Sgp4GravConstants } from '../sgp4/sgp4'; import { EpochUTC } from '../time/EpochUTC'; @@ -44,7 +43,7 @@ import { TleLine1, TleLine2, } from '../types/types'; -import { DEG2RAD, RAD2DEG, secondsPerDay, TAU } from '../utils/constants'; +import { DEG2RAD, earthGravityParam, RAD2DEG, secondsPerDay, TAU } from '../utils/constants'; import { newtonNu, toPrecision } from '../utils/functions'; import { TleFormatData } from './tle-format-data'; @@ -173,7 +172,7 @@ export class Tle { } get period(): number { - return TAU * Math.sqrt(this.semimajorAxis ** 3 / Earth.mu); + return TAU * Math.sqrt(this.semimajorAxis ** 3 / earthGravityParam); } private static parseEpoch_(epochStr: string): EpochUTC { @@ -234,7 +233,7 @@ export class Tle { private static tleSma_(line2: string): number { const n = parseFloat(line2.substring(52, 63)); - return Earth.mu ** (1 / 3) / ((TAU * n) / secondsPerDay) ** (2 / 3); + return earthGravityParam ** (1 / 3) / ((TAU * n) / secondsPerDay) ** (2 / 3); } private static tleEcc_(line2: string): number { diff --git a/src/index.ts b/src/index.ts index e6c1962..8eac7ca 100644 --- a/src/index.ts +++ b/src/index.ts @@ -31,18 +31,18 @@ * SOFTWARE. */ -export { Celestial, Earth, Moon, Sun } from './body'; -export * from './coordinate'; -export { Tle } from './coordinate/Tle'; -export * from './data/DataHandler'; export * from './enums'; +export * from './types/types'; export * from './interfaces'; -export { BaseObject, GroundPosition, Satellite, Sensor, Star } from './objects'; -export * from './observation'; -export * from './operations/operations'; -export * from './sgp4'; export * from './time/time'; export * from './transforms'; -export * from './types/types'; -export * from './utils/constants'; -export * from './utils/functions'; +export * from './utils'; +export * from './operations/operations'; +export { BaseObject } from './objects'; +export { Earth } from './body'; +export * from './coordinate'; +export * from './observation'; +export * from './data/DataHandler'; +export * from './sgp4'; +export * from './objects'; +export * from './body'; diff --git a/src/objects/BaseObject.ts b/src/objects/BaseObject.ts index ea71f82..8593500 100644 --- a/src/objects/BaseObject.ts +++ b/src/objects/BaseObject.ts @@ -1,6 +1,6 @@ /** * @author Theodore Kruczek. - * @description Orbital Object ToolKit (ootk) is a collection of tools for working + * @description Orbital Object ToolKit Core (ootk-core) is a collection of tools for working * with satellites and other orbital objects. * * @file The BaseObject class is used for creating core properties and methods applicable diff --git a/src/objects/RadarSensor.ts b/src/objects/RadarSensor.ts new file mode 100644 index 0000000..435ffd3 --- /dev/null +++ b/src/objects/RadarSensor.ts @@ -0,0 +1,12 @@ +import { Sensor } from '.'; +import { Radians } from '../types/types'; + +// TODO: #3 This should be a class. + +export interface RadarSensor extends Sensor { + coneHalfAngle: Radians; + boresight: { + az: Radians; + el: Radians; + }; +} diff --git a/src/objects/Satellite.ts b/src/objects/Satellite.ts index 00eb938..5ccfe23 100644 --- a/src/objects/Satellite.ts +++ b/src/objects/Satellite.ts @@ -1,6 +1,6 @@ /** * @author Theodore Kruczek. - * @description Orbital Object ToolKit (ootk) is a collection of tools for working + * @description Orbital Object ToolKit Core (ootk-core) is a collection of tools for working * with satellites and other orbital objects. * * @file The Satellite class provides functions for calculating satellites positions @@ -61,7 +61,7 @@ import { BaseObject } from './BaseObject'; import { GroundPosition } from './GroundPosition'; /** - * TODO: Reduce unnecessary calls to calculateTimeVariables using optional + * TODO: #2 Reduce unnecessary calls to calculateTimeVariables using optional * parameters and caching. */ diff --git a/src/objects/Star.ts b/src/objects/Star.ts index adbd863..3bc72c4 100644 --- a/src/objects/Star.ts +++ b/src/objects/Star.ts @@ -1,6 +1,6 @@ /** * @author Theodore Kruczek. - * @description Orbital Object ToolKit (ootk) is a collection of tools for working + * @description Orbital Object ToolKit Core (ootk-core) is a collection of tools for working * with satellites and other orbital objects. * * @file The Star class is meant to help with cacluating star positions relative to @@ -26,8 +26,9 @@ * DEALINGS IN THE SOFTWARE. */ -import { StarObjectParams } from '../interfaces/StarObjectParams'; +import { BaseObject } from './BaseObject'; import { + StarObjectParams, Degrees, EciVec3, GreenwichMeanSiderealTime, @@ -36,13 +37,13 @@ import { Radians, RaeVec3, SpaceObjectType, -} from '../types/types'; -import { MILLISECONDS_TO_DAYS } from '../utils/constants'; - -import { Celestial } from '../body'; -import { Sgp4 } from '../sgp4/sgp4'; -import { ecf2eci, jday, rae2ecf } from '../transforms/transforms'; -import { BaseObject } from './BaseObject'; + MILLISECONDS_TO_DAYS, + Celestial, + Sgp4, + ecf2eci, + jday, + rae2ecf, +} from '../index'; export class Star extends BaseObject { ra: Radians; @@ -77,7 +78,7 @@ export class Star extends BaseObject { lla: LlaVec3 = { lat: 180, lon: 0, alt: 0 }, date: Date = this.time, ): RaeVec3 { - const starPos = Celestial.getStarAzEl(date, lla.lat, lla.lon, this.ra, this.dec); + const starPos = Celestial.azEl(date, lla.lat, lla.lon, this.ra, this.dec); return { az: starPos.az, el: starPos.el, rng: 250000 }; } diff --git a/src/objects/index.ts b/src/objects/index.ts index c020960..7ca770c 100644 --- a/src/objects/index.ts +++ b/src/objects/index.ts @@ -1,4 +1,5 @@ export { BaseObject } from './BaseObject'; +export type { RadarSensor } from './RadarSensor'; export { GroundPosition } from './GroundPosition'; export { Satellite } from './Satellite'; export { Sensor } from './Sensor'; diff --git a/src/sgp4/sgp4.ts b/src/sgp4/sgp4.ts index 5412f64..18543ba 100644 --- a/src/sgp4/sgp4.ts +++ b/src/sgp4/sgp4.ts @@ -1,6 +1,6 @@ /** * @author Theodore Kruczek. - * @description Orbital Object ToolKit (ootk) is a collection of tools for working + * @description Orbital Object ToolKit Core (ootk-core) is a collection of tools for working * with satellites and other orbital objects. * * @file The Sgp4 module contains a TypeScript port of the 2020 version of @@ -1243,7 +1243,6 @@ export class Sgp4 { /* * Sgp4fix recover singly averaged mean elements - * TODO: Skip these? * satrec.am = am; * satrec.em = em; * satrec.im = inclm; diff --git a/src/transforms/conversions.ts b/src/transforms/conversions.ts index 2edf9c0..66c833c 100644 --- a/src/transforms/conversions.ts +++ b/src/transforms/conversions.ts @@ -1,5 +1,4 @@ -import { Degrees, Radians } from '..'; -import { DEG2RAD, PI, RAD2DEG } from '../utils/constants'; +import { DEG2RAD, PI, RAD2DEG, Degrees, Radians } from '..'; /** * Converts radians to degrees. diff --git a/src/transforms/transforms.ts b/src/transforms/transforms.ts index f5c77ea..1b12193 100644 --- a/src/transforms/transforms.ts +++ b/src/transforms/transforms.ts @@ -1,7 +1,7 @@ /* eslint-disable init-declarations */ /** * @author Theodore Kruczek. - * @description Orbital Object ToolKit (ootk) is a collection of tools for working + * @description Orbital Object ToolKit Core (ootk-core) is a collection of tools for working * with satellites and other orbital objects. * * @file The Transforms module contains a collection of conversions not contained @@ -28,7 +28,6 @@ * DEALINGS IN THE SOFTWARE. */ -import { Earth, Sensor, Sgp4 } from '..'; import { Degrees, EcefVec3, @@ -38,14 +37,21 @@ import { GreenwichMeanSiderealTime, Kilometers, LlaVec3, - RadarSensor, Radians, RaeVec3, RfVec3, RuvVec3, SezVec3, -} from '../types/types'; -import { DEG2RAD, MILLISECONDS_TO_DAYS, PI, RAD2DEG, TAU } from '../utils/constants'; + DEG2RAD, + MILLISECONDS_TO_DAYS, + PI, + RAD2DEG, + TAU, + Earth, + Sensor, + Sgp4, + RadarSensor, +} from '..'; /** * Converts Azimuth and Elevation to U and V. diff --git a/src/types/types.ts b/src/types/types.ts index d598841..286a1dd 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -1,5 +1,4 @@ import { PassType } from '../enums/PassType'; -import { Sensor } from '../objects'; /** * Represents a distinct type. @@ -610,14 +609,6 @@ export type RaDec = { dist: Kilometers; }; -export interface RadarSensor extends Sensor { - coneHalfAngle: Radians; - boresight: { - az: Radians; - el: Radians; - }; -} - /** * Represents the solar noon and nadir times. * diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 626e599..ea8ca7d 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -104,3 +104,5 @@ export const MILLISECONDS_PER_DAY = 1000 * 60 * 60 * 24; export const MILLISECONDS_PER_SECOND = 1000; export const RADIUS_OF_EARTH = 6371; // Radius of Earth in kilometers + +export const earthGravityParam = 398600.4415; diff --git a/src/utils/functions.ts b/src/utils/functions.ts index cbda9a0..bfb6366 100644 --- a/src/utils/functions.ts +++ b/src/utils/functions.ts @@ -2,9 +2,7 @@ /* eslint-disable func-style */ import { AngularDiameterMethod } from '../enums/AngularDiameterMethod'; import { AngularDistanceMethod } from '../enums/AngularDistanceMethod'; -import { Matrix } from '../operations/Matrix'; -import { Vector } from '../operations/Vector'; -import { DifferentiableFunction, EciVec3, JacobianFunction, Radians, SpaceObjectType, Vec3 } from '../types/types'; +import { DifferentiableFunction, EciVec3, Radians, SpaceObjectType } from '../types/types'; /** * Calculates the factorial of a given number. @@ -296,16 +294,6 @@ export function angularDistance( } } -/** - * Calculates the linear distance between two points in three-dimensional space. - * @param pos1 The first position. - * @param pos2 The second position. - * @returns The linear distance between the two positions in kilometers. - */ -export function linearDistance(pos1: Vec3, pos2: Vec3): D { - return Math.sqrt((pos1.x - pos2.x) ** 2 + (pos1.y - pos2.y) ** 2 + (pos1.z - pos2.z) ** 2); -} - /** * Calculates the angular diameter of an object. * @@ -522,41 +510,6 @@ export function array2d(rows: number, columns: number, value: T): T[][] { return output; } -/** - * Calculates the Jacobian matrix of a given Jacobian function. - * - * @param f The Jacobian function. - * @param m The number of rows in the Jacobian matrix. - * @param x0 The initial values of the variables. - * @param step The step size for numerical differentiation (default: 1e-5). - * @returns The Jacobian matrix. - */ -export function jacobian(f: JacobianFunction, m: number, x0: Float64Array, step = 1e-5): Matrix { - const n = x0.length; - const j = array2d(m, n, 0.0); - const h = 0.5 * step; - - for (let k = 0; k < n; k++) { - const xp = x0.slice(); - - xp[k] += h; - const fp = new Vector(f(xp)); - - const xm = x0.slice(); - - xm[k] -= h; - const fm = new Vector(f(xm)); - - const cd = fp.subtract(fm).scale(1.0 / step); - - for (let i = 0; i < m; i++) { - j[i][k] = cd.elements[i]; - } - } - - return new Matrix(j); -} - /** * Clamps a number between a minimum and maximum value. * @param x The number to clamp. diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..0cee8c7 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,4 @@ +export * from './functions'; +export * from './constants'; +export * from './linearDistance'; +export * from './jacobian'; diff --git a/src/utils/jacobian.ts b/src/utils/jacobian.ts new file mode 100644 index 0000000..051e879 --- /dev/null +++ b/src/utils/jacobian.ts @@ -0,0 +1,40 @@ +import { Matrix } from '../operations/Matrix'; +import { Vector } from '../operations/Vector'; +import { JacobianFunction } from '../types/types'; +import { array2d } from './functions'; + +/** + * Calculates the Jacobian matrix of a given Jacobian function. + * + * @param f The Jacobian function. + * @param m The number of rows in the Jacobian matrix. + * @param x0 The initial values of the variables. + * @param step The step size for numerical differentiation (default: 1e-5). + * @returns The Jacobian matrix. + */ + +export function jacobian(f: JacobianFunction, m: number, x0: Float64Array, step = 0.00001): Matrix { + const n = x0.length; + const j = array2d(m, n, 0); + const h = 0.5 * step; + + for (let k = 0; k < n; k++) { + const xp = x0.slice(); + + xp[k] += h; + const fp = new Vector(f(xp)); + + const xm = x0.slice(); + + xm[k] -= h; + const fm = new Vector(f(xm)); + + const cd = fp.subtract(fm).scale(1 / step); + + for (let i = 0; i < m; i++) { + j[i][k] = cd.elements[i]; + } + } + + return new Matrix(j); +} diff --git a/src/utils/linearDistance.ts b/src/utils/linearDistance.ts new file mode 100644 index 0000000..7002b86 --- /dev/null +++ b/src/utils/linearDistance.ts @@ -0,0 +1,11 @@ +import { Vec3 } from '../types/types'; + +/** + * Calculates the linear distance between two points in three-dimensional space. + * @param pos1 The first position. + * @param pos2 The second position. + * @returns The linear distance between the two positions in kilometers. + */ +export function linearDistance(pos1: Vec3, pos2: Vec3): D { + return Math.sqrt((pos1.x - pos2.x) ** 2 + (pos1.y - pos2.y) ** 2 + (pos1.z - pos2.z) ** 2); +} diff --git a/test/body/Celestial.test.ts b/test/body/Celestial.test.ts new file mode 100644 index 0000000..fa0f255 --- /dev/null +++ b/test/body/Celestial.test.ts @@ -0,0 +1,79 @@ +import { Degrees, Radians } from './../../src/types/types'; +import { Celestial } from './../../src/body/Celestial'; +import { exampleDate } from '../lib/mockData'; + +describe('Celestial', () => { + /* + * Calculates the azimuth and elevation of a celestial object at a given date, + * latitude, longitude, right ascension, and declination. + */ + it('should calculate the azimuth and elevation when given valid inputs', () => { + const lat = 37.7749 as Degrees; // latitude of San Francisco + const lon = -122.4194 as Degrees; // longitude of San Francisco + const ra = 1.3963 as Radians; // right ascension of a celestial object + const dec = 0.7854 as Radians; // declination of a celestial object + + const azEl = Celestial.azEl(exampleDate, lat, lon, ra, dec); + + expect(azEl).toMatchSnapshot(); + }); + + // Calculates the atmospheric refraction for a given elevation. + it('should calculate the atmospheric refraction when given a valid elevation', () => { + const elevation = 0.5 as Radians; + const refraction = Celestial.atmosphericRefraction(elevation); + + expect(refraction).toMatchSnapshot(); + }); + + // Calculates the declination of a celestial object given its ecliptic longitude and latitude. + it('should calculate the declination when given valid ecliptic longitude and latitude', () => { + const longitude = 0.5 as Radians; + const latitude = 0.3 as Radians; + + const declination = Celestial.declination(longitude, latitude); + + expect(declination).toMatchSnapshot(); + }); + + // Calculates the right ascension of a celestial object given its ecliptic longitude and latitude. + it('should calculate the right ascension when given valid ecliptic longitude and latitude', () => { + const longitude = 0.5 as Radians; + const latitude = 0.3 as Radians; + + const rightAscension = Celestial.rightAscension(longitude, latitude); + + expect(rightAscension).toMatchSnapshot(); + }); + + // Calculates the elevation of a celestial object given its sidereal time, latitude, and declination. + it('should calculate the elevation when given valid sidereal time, latitude, and declination', () => { + const siderealTime = 1.2; + const latitude = 0.5 as Radians; + const declination = 0.3 as Radians; + + const elevation = Celestial.elevation(siderealTime, latitude, declination); + + expect(elevation).toMatchSnapshot(); + }); + + // Calculates the azimuth of a celestial object given its sidereal time, latitude, and declination. + it('should calculate the azimuth when given valid sidereal time, latitude, and declination', () => { + const siderealTime = 1.2; + const latitude = 0.5 as Radians; + const declination = 0.3 as Radians; + + const azimuth = Celestial.azimuth(siderealTime, latitude, declination); + + expect(azimuth).toMatchSnapshot(); + }); + + // Calculates the atmospheric refraction for an elevation of 0. + it('should calculate the atmospheric refraction when elevation is 0', () => { + const elevation = 0 as Radians; + + const refraction = Celestial.atmosphericRefraction(elevation); + + expect(refraction).toMatchSnapshot(); + }); +}); diff --git a/test/body/Earth.test.ts b/test/body/Earth.test.ts new file mode 100644 index 0000000..1ae2b6f --- /dev/null +++ b/test/body/Earth.test.ts @@ -0,0 +1,128 @@ +import { exampleDate } from '../lib/mockData'; +import { Earth, EpochUTC, Vector3D } from '../../src/index'; + +describe('Earth', () => { + // can calculate mean motion from semimajor axis + it('should calculate mean motion when given a semimajor axis', () => { + const semimajorAxis = 7000; // km + const meanMotion = Earth.smaToMeanMotion(semimajorAxis); + + expect(meanMotion).toMatchSnapshot(); + }); + + // can calculate precession angles from epoch + it('should calculate precession angles when given an epoch', () => { + const epoch = EpochUTC.fromDateTime(exampleDate); + const precessionAngles = Earth.precession(epoch); + + expect(precessionAngles.zeta).toMatchSnapshot(); + expect(precessionAngles.theta).toMatchSnapshot(); + expect(precessionAngles.zed).toMatchSnapshot(); + }); + + // can calculate nutation angles from epoch + it('should calculate nutation angles when given an epoch', () => { + const epoch = EpochUTC.fromDateTime(exampleDate); + const nutationAngles = Earth.nutation(epoch); + + expect(nutationAngles.dPsi).toMatchSnapshot(); + expect(nutationAngles.dEps).toMatchSnapshot(); + expect(nutationAngles.mEps).toMatchSnapshot(); + expect(nutationAngles.eps).toMatchSnapshot(); + expect(nutationAngles.eqEq).toMatchSnapshot(); + expect(nutationAngles.gast).toMatchSnapshot(); + }); + + // can handle semimajor axis of 0 when calculating mean motion + it('should return NaN when given a semimajor axis of 0', () => { + const semimajorAxis = 0; + const meanMotion = Earth.smaToMeanMotion(semimajorAxis); + + expect(meanMotion).toBe(Infinity); + }); + + // can handle negative semimajor axis when calculating mean motion + it('should return NaN when given a negative semimajor axis', () => { + const semimajorAxis = -7000; + const meanMotion = Earth.smaToMeanMotion(semimajorAxis); + + expect(meanMotion).toBeNaN(); + }); + + // can calculate drift rate from semimajor axis + it('should calculate drift rate when given a semimajor axis', () => { + const semimajorAxis = 7000; // km + const driftRate = Earth.smaToDrift(semimajorAxis); + + expect(driftRate).toMatchSnapshot(); + }); + + // can calculate semimajor axis from drift rate + it('should calculate semimajor axis from drift rate', () => { + const driftRate = 0.1; // degrees per day + const semimajorAxis = Earth.driftDegreesToSma(driftRate); + + expect(semimajorAxis).toMatchSnapshot(); + }); + + // can calculate Earth's diameter from satellite position + it("should calculate Earth's diameter from satellite position", () => { + const satPos = new Vector3D(1000, 1000, 1000); + const diameter = Earth.diameter(satPos); + + expect(diameter).toMatchSnapshot(); + }); + + // can handle epoch before 1900 when calculating precession angles + it('should handle epoch before 1900 when calculating precession angles', () => { + const epoch = EpochUTC.fromDateTime(exampleDate); + const precessionAngles = Earth.precession(epoch); + + expect(precessionAngles.zeta).toMatchSnapshot(); + }); + + // can handle epoch after 2150 when calculating precession angles + it('should handle epoch after 2150 when calculating precession angles', () => { + const epoch = EpochUTC.fromDateTime(exampleDate); + const precessionAngles = Earth.precession(epoch); + + expect(precessionAngles.zeta).not.toBeNaN(); + expect(precessionAngles.zeta).toMatchSnapshot(); + }); + + // can handle epoch before 1900 when calculating nutation angles + it('should handle epoch before 1900 when calculating nutation angles', () => { + const epoch = EpochUTC.fromDateTime(exampleDate); + const nutationAngles = Earth.nutation(epoch); + + expect(nutationAngles.dPsi).not.toBeNaN(); + expect(nutationAngles.dPsi).toMatchSnapshot(); + }); + + // can handle epoch after 2150 when calculating nutation angles + it('should handle epoch after 2150 when calculating nutation angles', () => { + const epoch = EpochUTC.fromDateTime(exampleDate); + const nutationAngles = Earth.nutation(epoch); + + expect(nutationAngles.dPsi).not.toBeNaN(); + expect(nutationAngles.dPsi).toMatchSnapshot(); + }); + + // can handle negative drift rate when calculating semimajor axis + it('should handle negative drift rate when calculating semimajor axis', () => { + const driftRate = -0.1; // degrees per day + const semimajorAxis = Earth.driftDegreesToSma(driftRate); + + expect(semimajorAxis).not.toBeNaN(); + expect(semimajorAxis).toMatchSnapshot(); + }); + + // can handle drift rate of 0 when calculating semimajor axis + it('should handle drift rate of 0 when calculating semimajor axis', () => { + const driftRate = 0; // degrees per day + const semimajorAxis = Earth.driftDegreesToSma(driftRate); + + expect(semimajorAxis).not.toBeNaN(); + expect(semimajorAxis).toMatchSnapshot(); + }); +}); diff --git a/test/body/Moon.test.ts b/test/body/Moon.test.ts new file mode 100644 index 0000000..7c94ec3 --- /dev/null +++ b/test/body/Moon.test.ts @@ -0,0 +1,139 @@ +import { exampleDate } from '../lib/mockData'; +import { Degrees, EpochUTC, Moon, Vector3D } from '../../src'; + +describe('Moon', () => { + // The static property 'mu' should be accessible and have a value of 4902.799. + it('should have a static property "mu" with value 4902.799', () => { + expect(Moon.mu).toBe(4902.799); + }); + + // The static property 'radiusEquator' should be accessible and have a value of 1738.0. + it('should have a static property "radiusEquator" with value 1738.0', () => { + expect(Moon.radiusEquator).toBe(1738.0); + }); + + // The static method 'eci' should be callable with an "EpochUTC" parameter and return a 'Vector3D' object. + it('should be callable with an "EpochUTC" parameter and return a "Vector3D" object', () => { + const epoch = EpochUTC.fromDateTime(exampleDate); + const result = Moon.eci(epoch); + + expect(result).toMatchSnapshot(); + }); + + /* + * The static method 'illumination' should be callable with an "EpochUTC" parameter + * and an optional 'origin' parameter, and return a number between 0 and 1. + */ + it('should be callable with an "EpochUTC" parameter and an optional "origin" parameter', () => { + const epoch = EpochUTC.fromDateTime(exampleDate); + const result = Moon.illumination(epoch); + + expect(result).toBeGreaterThanOrEqual(0); + expect(result).toBeLessThanOrEqual(1); + }); + + // The static method 'diameter' should be callable with two 'Vector3D' parameters and return a number. + it('should be callable with two "Vector3D" parameters and return a number', () => { + const obsPos = new Vector3D(1, 2, 3); + const moonPos = new Vector3D(4, 5, 6); + const result = Moon.diameter(obsPos, moonPos); + + expect(result).toMatchSnapshot(); + }); + + // The static method 'eci' should throw an error if the "EpochUTC" parameter is not provided. + it('should throw an error if the "EpochUTC" parameter is not provided', () => { + expect(() => { + Moon.eci(); + }).not.toThrow('EpochUTC parameter is required'); + }); + + // The static method 'illumination' should return 0.5 if the 'origin' parameter is not provided. + it('should return 0.5 if the "origin" parameter is not provided', () => { + const epoch = EpochUTC.fromDateTime(exampleDate); + const result = Moon.illumination(epoch); + + expect(result).toMatchSnapshot(); + }); + + // The static method 'diameter' should return 0 if the two 'Vector3D' parameters are the same. + it('should return NaN if the two "Vector3D" parameters are the same', () => { + const pos = new Vector3D(1, 2, 3); + const result = Moon.diameter(pos, pos); + + expect(result).toBeNaN(); + }); + + /* + * The static method 'getMoonIllumination' should be callable with a 'number' or 'Date' parameter + * and return a 'MoonIlluminationData' object. + */ + it('should return a MoonIlluminationData object when called with a number parameter', () => { + const date = 1635724800000; // November 1, 2021 + const result = Moon.getMoonIllumination(date); + + expect(result).toMatchSnapshot(); + }); + + /* + * The static method 'rae' should be callable with a 'Date', 'Degrees', and 'Degrees' parameters + * and return an object with 'az', 'el', 'rng', and 'parallacticAngle' properties. + */ + it("should return an object with 'az', 'el', 'rng', and 'parallacticAngle' properties", () => { + const date = new Date(1635724800000); // November 1, 2021 + const lat = 37.7749 as Degrees; // San Francisco latitude + const lon = -122.4194 as Degrees; // San Francisco longitude + const result = Moon.rae(date, lat, lon); + + expect(result).toMatchSnapshot(); + }); + + /* + * The static method 'getMoonTimes' should be callable with a 'Date', 'Degrees', 'Degrees', and 'boolean' + * parameters and return an object with 'rise', 'set', 'ye', 'alwaysUp', 'alwaysDown', and 'highest' properties. + */ + it("should return an object with 'rise', 'set', 'ye', 'alwaysUp', 'alwaysDown', and 'highest' properties", () => { + const date = new Date(1635724800000); // November 1, 2021 + const lat = 37.7749 as Degrees; // San Francisco latitude + const lon = -122.4194 as Degrees; // San Francisco longitude + const isUtc = false; + const result = Moon.getMoonTimes(date, lat, lon, isUtc); + + expect(result).toMatchSnapshot(); + }); + + /* + * The static method 'rae' should be callable with a 'Date', 'Degrees', and 'Degrees' parameters and return + * an object with 'az', 'el', 'rng', and 'parallacticAngle' properties. + */ + it("should return an object with 'az', 'el', 'rng', and 'parallacticAngle' properties", () => { + const date = new Date(2021, 10, 1); // November 1, 2021 + const lat = 37.7749 as Degrees; // San Francisco latitude + const lon = -122.4194 as Degrees; // San Francisco longitude + const result = Moon.rae(date, lat, lon); + + expect(result).toMatchSnapshot(); + }); + + /* + * The static method 'getMoonTimes' should be callable with a 'Date', 'Degrees', 'Degrees', and 'boolean' parameters + * and return an object with 'rise', 'set', 'ye', 'alwaysUp', 'alwaysDown', and 'highest' properties. + */ + it("should return an object with 'rise', 'set', 'ye', 'alwaysUp', 'alwaysDown', and 'highest' properties", () => { + const date = new Date(2021, 10, 1); // November 1, 2021 + const lat = 37.7749 as Degrees; // San Francisco latitude + const lon = -122.4194 as Degrees; // San Francisco longitude + const isUtc = false; + const result = Moon.getMoonTimes(date, lat, lon, isUtc); + + expect(result).toMatchSnapshot(); + }); + + // The private method 'moonCoords' should be callable with a 'number' parameter and return a 'RaDec' object. + it("should call the private method 'moonCoords' with a number parameter and return a RaDec object", () => { + const d = 123456789; + const result = Moon.moonCoords(d); + + expect(result).toMatchSnapshot(); + }); +}); diff --git a/test/body/Sun.test.ts b/test/body/Sun.test.ts new file mode 100644 index 0000000..61d9071 --- /dev/null +++ b/test/body/Sun.test.ts @@ -0,0 +1,189 @@ +import { Vector3D, Degrees, Meters, Sun, EpochUTC } from './../../src'; +import { exampleDate } from '../lib/mockData'; + +describe('Sun', () => { + // The 'azEl' method should return the azimuth and elevation of the sun given a date, latitude, and longitude. + it('should return the azimuth and elevation of the sun given a date, latitude, and longitude', () => { + const lat = 37.7749 as Degrees; + const lon = -122.4194 as Degrees; + const result = Sun.azEl(exampleDate, lat, lon); + + expect(result).toMatchSnapshot(); + }); + + // The 'date2jSince2000' method should return the number of days since January 1, 2000, for a given date. + it('should return the number of days since January 1, 2000, for a given date', () => { + const result = Sun.date2jSince2000(exampleDate); + + expect(result).toMatchSnapshot(); + }); + + /* + * The 'diameter' method should return the angular diameter of the sun given the observer's position + * and the sun's position. + */ + it('should return the angular diameter of the sun given the observers position and the suns position', () => { + const obsPos = new Vector3D(0, 0, 0); + const sunPos = new Vector3D(1, 1, 1); + const result = Sun.diameter(obsPos, sunPos); + + expect(result).toMatchSnapshot(); + }); + + /* + * The 'eclipseAngles' method should return the angles necessary to determine if a satellite is in + * the shadow of the earth. + */ + it('should return the angles necessary to determine if a satellite is in the shadow of the earth', () => { + const satPos = new Vector3D(0, 0, 0); + const sunPos = new Vector3D(1, 1, 1); + const result = Sun.eclipseAngles(satPos, sunPos); + + expect(result).toMatchSnapshot(); + }); + + // The 'eclipticLatitude' method should return the ecliptic latitude of the sun given the solar latitude. + it('should return the ecliptic latitude of the sun given the solar latitude', () => { + const B = 23.4397; + const result = Sun.eclipticLatitude(B); + + expect(result).toMatchSnapshot(); + }); + + // The 'eclipticLongitude' method should return the ecliptic longitude of the sun given the solar mean anomaly. + it('should return the ecliptic longitude of the sun given the solar mean anomaly', () => { + const M = 0; + const result = Sun.eclipticLongitude(M); + + expect(result).toMatchSnapshot(); + }); + + // The 'date2jSince2000' method should handle invalid dates. + it('should handle invalid dates', () => { + const date = new Date('invalid'); + const result = Sun.date2jSince2000(date); + + expect(result).toMatchSnapshot(); + }); + + // The 'diameter' method should handle cases where the observer's position is the same as the sun's position. + it('should handle cases where the observers position is the same as the suns position', () => { + const obsPos = new Vector3D(1, 1, 1); + const sunPos = new Vector3D(1, 1, 1); + const result = Sun.diameter(obsPos, sunPos); + + expect(result).toMatchSnapshot(); + }); + + // The 'eclipseAngles' method should handle cases where the satellite is directly above or below the earth. + it('should handle cases where the satellite is directly above or below the earth', () => { + const satPos = new Vector3D(0, 0, 0); + const sunPos = new Vector3D(0, 0, 1); + const result = Sun.eclipseAngles(satPos, sunPos); + + expect(result).toMatchSnapshot(); + }); + + // The 'eclipticLatitude' method should handle extreme values of solar latitude. + it('should handle extreme values of solar latitude', () => { + const B = 90; + const result = Sun.eclipticLatitude(B); + + expect(result).toMatchSnapshot(); + }); + + // The 'eclipticLongitude' method should handle extreme values of solar mean anomaly. + it('should handle extreme values of solar mean anomaly', () => { + const M = 360; + const result = Sun.eclipticLongitude(M); + + expect(result).toMatchSnapshot(); + }); + + // The 'getSolarTime' method should return the solar time for a given date, UTC offset, and longitude. + it('should return the solar time for a given date, UTC offset, and longitude', () => { + const utcOffset = -5; + const lon = -75 as Degrees; + + const result = Sun.getSolarTime(exampleDate, utcOffset, lon); + + expect(result).toMatchSnapshot(); + }); + + /* + * The 'getSetJulian' method should return the Julian date of the sunrise, sunset, or other solar event + * given the observer's position, date, and time. + */ + it('should return the Julian date of the sunrise when the observers position, date, and time are provided', () => { + // Mock input values + const lat = 40; + const lon = -75; + const c = { ra: 0, dec: 0 }; + + // Call the method + const result = Sun.getSetJulian(0 as Meters, lon, lat, c.dec, 0, 0, 0); + + // Assert the result + expect(result).toMatchSnapshot(); + }); + + // The 'getSunTimeByAz' method should return the date and time of the sun's position given a specific azimuth. + it('should return the date and time of the suns position given a specific azimuth', () => { + const lat = 37.7749 as Degrees; + const lon = -122.4194 as Degrees; + const az = 1.5 as Degrees; + const result = Sun.getSunTimeByAz(exampleDate, lat, lon, az); + + expect(result).toMatchSnapshot(); + }); + + /* + * The 'getTimes' method should return the sunrise, sunset, and other solar event times for a given + * date, latitude, and longitude. + */ + it('should return the sunrise, sunset, and other event times when given a date, latitude, and longitude', () => { + // Mock input values + const lat = 37.7749 as Degrees; + const lon = -122.4194 as Degrees; + + // Call the getTimes method + const result = Sun.getTimes(exampleDate, lat, lon); + + // Use toMatchSnapshot to test output of the getTimes method + expect(result).toMatchSnapshot(); + }); + + it('should return the same shadow result given the same time and position', () => { + const result = Sun.shadow(EpochUTC.fromDateTime(exampleDate), new Vector3D(8000, 0, 0)); + + expect(result).toMatchSnapshot(); + }); + + // positionApparent + it('should return the same apparent position result given the same time and position', () => { + const result = Sun.positionApparent(EpochUTC.fromDateTime(exampleDate)); + + expect(result).toMatchSnapshot(); + }); + + // sunlightLegacy + it('should return the same sunlight result given the same positions', () => { + const result = Sun.sunlightLegacy(new Vector3D(8000, 0, 0), new Vector3D(1000000, 0, 0)); + + expect(result).toMatchSnapshot(); + }); + + // lightingRatio + it('should return the same lighting ratio result given the same positions', () => { + const result = Sun.lightingRatio(new Vector3D(8000, 0, 0), new Vector3D(1000000, 0, 0)); + + expect(result).toMatchSnapshot(); + }); + + // julianCyle + it('should return the same julian cycle result given the same date', () => { + const result = Sun.julianCycle(exampleDate, -75 as Degrees); + + expect(result).toMatchSnapshot(); + }); +}); diff --git a/test/body/__snapshots__/Celestial.test.ts.snap b/test/body/__snapshots__/Celestial.test.ts.snap new file mode 100644 index 0000000..606de47 --- /dev/null +++ b/test/body/__snapshots__/Celestial.test.ts.snap @@ -0,0 +1,20 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Celestial should calculate the atmospheric refraction when elevation is 0 1`] = `0.008446689093277518`; + +exports[`Celestial should calculate the atmospheric refraction when given a valid elevation 1`] = `0.0005363221501954175`; + +exports[`Celestial should calculate the azimuth and elevation when given valid inputs 1`] = ` +Object { + "az": 58.636843073419904, + "el": 39.53055812197483, +} +`; + +exports[`Celestial should calculate the azimuth when given valid sidereal time, latitude, and declination 1`] = `4.816878749628938`; + +exports[`Celestial should calculate the declination when given valid ecliptic longitude and latitude 1`] = `0.4704906087409695`; + +exports[`Celestial should calculate the elevation when given valid sidereal time, latitude, and declination 1`] = `0.46170567615036917`; + +exports[`Celestial should calculate the right ascension when given valid ecliptic longitude and latitude 1`] = `0.3464473691313705`; diff --git a/test/body/__snapshots__/Earth.test.ts.snap b/test/body/__snapshots__/Earth.test.ts.snap new file mode 100644 index 0000000..3b1cda3 --- /dev/null +++ b/test/body/__snapshots__/Earth.test.ts.snap @@ -0,0 +1,39 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Earth should calculate Earth's diameter from satellite position 1`] = `NaN`; + +exports[`Earth should calculate drift rate when given a semimajor axis 1`] = `5.858163121001669`; + +exports[`Earth should calculate mean motion when given a semimajor axis 1`] = `0.0010780076124668337`; + +exports[`Earth should calculate nutation angles when given an epoch 1`] = `-0.000022653923055009833`; + +exports[`Earth should calculate nutation angles when given an epoch 2`] = `0.000039533533539525476`; + +exports[`Earth should calculate nutation angles when given an epoch 3`] = `0.40903826060434395`; + +exports[`Earth should calculate nutation angles when given an epoch 4`] = `0.4090777941378835`; + +exports[`Earth should calculate nutation angles when given an epoch 5`] = `-0.000020780433407756886`; + +exports[`Earth should calculate nutation angles when given an epoch 6`] = `2.342843536610454`; + +exports[`Earth should calculate precession angles when given an epoch 1`] = `0.0026870317857958003`; + +exports[`Earth should calculate precession angles when given an epoch 2`] = `0.002335075451748929`; + +exports[`Earth should calculate precession angles when given an epoch 3`] = `0.0026872537755354814`; + +exports[`Earth should calculate semimajor axis from drift rate 1`] = `42156.361072415566`; + +exports[`Earth should handle drift rate of 0 when calculating semimajor axis 1`] = `42164.16961350806`; + +exports[`Earth should handle epoch after 2150 when calculating nutation angles 1`] = `-0.000022653923055009833`; + +exports[`Earth should handle epoch after 2150 when calculating precession angles 1`] = `0.0026870317857958003`; + +exports[`Earth should handle epoch before 1900 when calculating nutation angles 1`] = `-0.000022653923055009833`; + +exports[`Earth should handle epoch before 1900 when calculating precession angles 1`] = `0.0026870317857958003`; + +exports[`Earth should handle negative drift rate when calculating semimajor axis 1`] = `42171.97743162094`; diff --git a/test/body/__snapshots__/Moon.test.ts.snap b/test/body/__snapshots__/Moon.test.ts.snap new file mode 100644 index 0000000..ed63551 --- /dev/null +++ b/test/body/__snapshots__/Moon.test.ts.snap @@ -0,0 +1,100 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Moon should be callable with an "EpochUTC" parameter and return a "Vector3D" object 1`] = ` +Vector3D { + "x": 248471.54051777, + "y": -229511.18274819673, + "z": -131233.28802621315, +} +`; + +exports[`Moon should be callable with two "Vector3D" parameters and return a number 1`] = `NaN`; + +exports[`Moon should call the private method 'moonCoords' with a number parameter and return a RaDec object 1`] = ` +Object { + "dec": -0.21428784368024154, + "dist": 401235.63978571084, + "ra": -0.7625969983284882, +} +`; + +exports[`Moon should return 0.5 if the "origin" parameter is not provided 1`] = `0.03596620967759451`; + +exports[`Moon should return a MoonIlluminationData object when called with a number parameter 1`] = ` +Object { + "angle": 2.042516805424306, + "fraction": 0.1878109225830057, + "next": Object { + "date": "2021-11-04T23:26:30.060Z", + "firstQuarter": Object { + "date": "2021-11-12T08:37:30.754Z", + "value": 1636706250754.5, + }, + "fullMoon": Object { + "date": "2021-11-19T17:48:31.449Z", + "value": 1637344111449, + }, + "newMoon": Object { + "date": "2021-11-04T23:26:30.060Z", + "value": 1636068390060, + }, + "thirdQuarter": Object { + "date": "2021-11-27T02:59:32.143Z", + "value": 1637981972143.5, + }, + "type": "newMoon", + "value": 1636068390060, + }, + "phase": Object { + "code": ":waning_crescent_moon:", + "css": "wi-moon-wan-cres", + "emoji": "🌘", + "from": 0.783863193308711, + "id": "waningCrescentMoon", + "name": "Waning Crescent", + "to": 0.966136806691289, + "weight": 6.3825, + }, + "phaseValue": 0.8573237783716006, +} +`; + +exports[`Moon should return an object with 'az', 'el', 'rng', and 'parallacticAngle' properties 1`] = ` +Object { + "az": 5.030114468719165, + "el": -0.12433217612739415, + "parallacticAngle": 0.8650448747993286, + "rng": 380743.9840372972, +} +`; + +exports[`Moon should return an object with 'az', 'el', 'rng', and 'parallacticAngle' properties 2`] = ` +Object { + "az": 5.9437396940767915, + "el": -0.7211759674013636, + "parallacticAngle": 0.26932786334872394, + "rng": 379969.4077607909, +} +`; + +exports[`Moon should return an object with 'rise', 'set', 'ye', 'alwaysUp', 'alwaysDown', and 'highest' properties 1`] = ` +Object { + "alwaysDown": false, + "alwaysUp": false, + "highest": 2021-10-31T16:31:15.245Z, + "rise": 2021-10-31T09:42:19.184Z, + "set": 2021-10-31T23:20:11.307Z, + "ye": null, +} +`; + +exports[`Moon should return an object with 'rise', 'set', 'ye', 'alwaysUp', 'alwaysDown', and 'highest' properties 2`] = ` +Object { + "alwaysDown": false, + "alwaysUp": false, + "highest": 2021-11-01T17:18:20.884Z, + "rise": 2021-11-01T10:48:42.354Z, + "set": 2021-11-01T23:47:59.413Z, + "ye": null, +} +`; diff --git a/test/body/__snapshots__/Sun.test.ts.snap b/test/body/__snapshots__/Sun.test.ts.snap new file mode 100644 index 0000000..cfdbb8a --- /dev/null +++ b/test/body/__snapshots__/Sun.test.ts.snap @@ -0,0 +1,89 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Sun should handle cases where the observers position is the same as the suns position 1`] = `NaN`; + +exports[`Sun should handle cases where the satellite is directly above or below the earth 1`] = ` +Array [ + 3.141592653589793, + NaN, + NaN, +] +`; + +exports[`Sun should handle extreme values of solar latitude 1`] = `565.420893384895`; + +exports[`Sun should handle extreme values of solar mean anomaly 1`] = `364.97003894087004`; + +exports[`Sun should handle invalid dates 1`] = `NaN`; + +exports[`Sun should return the Julian date of the sunrise when the observers position, date, and time are provided 1`] = `2451533.314279268`; + +exports[`Sun should return the angles necessary to determine if a satellite is in the shadow of the earth 1`] = ` +Array [ + 3.141592653589793, + NaN, + NaN, +] +`; + +exports[`Sun should return the angular diameter of the sun given the observers position and the suns position 1`] = `NaN`; + +exports[`Sun should return the azimuth and elevation of the sun given a date, latitude, and longitude 1`] = ` +Object { + "az": 4.284718248237755, + "el": -0.06852341194048539, +} +`; + +exports[`Sun should return the date and time of the suns position given a specific azimuth 1`] = `2024-01-12T11:48:41.319Z`; + +exports[`Sun should return the ecliptic latitude of the sun given the solar latitude 1`] = `147.22965595225526`; + +exports[`Sun should return the ecliptic longitude of the sun given the solar mean anomaly 1`] = `4.938185716373701`; + +exports[`Sun should return the number of days since January 1, 2000, for a given date 1`] = `8777.561652974691`; + +exports[`Sun should return the same apparent position result given the same time and position 1`] = ` +Vector3D { + "x": 55101974.26909711, + "y": -125165869.77224815, + "z": -54258234.63367154, +} +`; + +exports[`Sun should return the same julian cycle result given the same date 1`] = `8777`; + +exports[`Sun should return the same lighting ratio result given the same positions 1`] = `1`; + +exports[`Sun should return the same shadow result given the same time and position 1`] = `false`; + +exports[`Sun should return the same sunlight result given the same positions 1`] = `1`; + +exports[`Sun should return the solar time for a given date, UTC offset, and longitude 1`] = `2024-01-13T01:20:30.888Z`; + +exports[`Sun should return the sunrise, sunset, and other event times when given a date, latitude, and longitude 1`] = ` +Object { + "amateurDawn": 2024-01-12T14:08:48.295Z, + "amateurDusk": 2024-01-13T02:29:02.928Z, + "astronomicalDawn": 2024-01-12T13:53:05.375Z, + "astronomicalDusk": 2024-01-13T02:44:45.848Z, + "blueHourDawnEnd": 2024-01-12T15:08:10.931Z, + "blueHourDawnStart": 2024-01-12T14:46:12.437Z, + "blueHourDuskEnd": 2024-01-13T01:51:38.787Z, + "blueHourDuskStart": 2024-01-13T01:29:40.292Z, + "civilDawn": 2024-01-12T14:57:07.812Z, + "civilDusk": 2024-01-13T01:40:43.411Z, + "goldenHourDawnEnd": 2024-01-12T16:06:02.767Z, + "goldenHourDawnStart": 2024-01-12T15:25:02.285Z, + "goldenHourDuskEnd": 2024-01-13T01:12:48.939Z, + "goldenHourDuskStart": 2024-01-13T00:31:48.456Z, + "nadir": 2024-01-13T08:18:55.612Z, + "nauticalDawn": 2024-01-12T14:24:41.646Z, + "nauticalDusk": 2024-01-13T02:13:09.577Z, + "solarNoon": 2024-01-12T20:18:55.612Z, + "sunriseEnd": 2024-01-12T15:29:01.495Z, + "sunriseStart": 2024-01-12T15:25:59.235Z, + "sunsetEnd": 2024-01-13T01:11:51.988Z, + "sunsetStart": 2024-01-13T01:08:49.728Z, +} +`; diff --git a/test/index.test.ts b/test/index.test.ts new file mode 100644 index 0000000..87a68e0 --- /dev/null +++ b/test/index.test.ts @@ -0,0 +1,37 @@ +import * as ootk from '../src/index'; + +describe('ootk-core', () => { + it('should export Celestial', () => { + expect(ootk.Celestial).toBeDefined(); + }); + it('should export Earth', () => { + expect(ootk.Earth).toBeDefined(); + }); + it('should export Moon', () => { + expect(ootk.Moon).toBeDefined(); + }); + it('should export Sun', () => { + expect(ootk.Sun).toBeDefined(); + }); + it('should export Tle', () => { + expect(ootk.Tle).toBeDefined(); + }); + it('should export DataHandler', () => { + expect(ootk.DataHandler).toBeDefined(); + }); + it('should export BaseObject', () => { + expect(ootk.BaseObject).toBeDefined(); + }); + it('should export GroundPosition', () => { + expect(ootk.GroundPosition).toBeDefined(); + }); + it('should export Satellite', () => { + expect(ootk.Satellite).toBeDefined(); + }); + it('should export Sensor', () => { + expect(ootk.Sensor).toBeDefined(); + }); + it('should export Star', () => { + expect(ootk.Star).toBeDefined(); + }); +}); diff --git a/test/lib/compareVectors.ts b/test/lib/compareVectors.ts index 09d3c22..0ad43cc 100644 --- a/test/lib/compareVectors.ts +++ b/test/lib/compareVectors.ts @@ -2,7 +2,7 @@ * Helper from satellite.js to compare vectors */ -import { Vec3 } from 'lib/ootk-core'; +import { Vec3 } from '../../src/index'; export const compareVectors = (vector1: Vec3, vector2: Vec3, numDigits: number) => { if (!numDigits) { diff --git a/test/lib/mockData.ts b/test/lib/mockData.ts new file mode 100644 index 0000000..9e84ae5 --- /dev/null +++ b/test/lib/mockData.ts @@ -0,0 +1 @@ +export const exampleDate = new Date(1705109326817); diff --git a/test/objects/BaseObject.test.ts b/test/objects/BaseObject.test.ts new file mode 100644 index 0000000..5089839 --- /dev/null +++ b/test/objects/BaseObject.test.ts @@ -0,0 +1,260 @@ +import { BaseObject, BaseObjectParams, EciVec3, SpaceObjectType } from '../../src'; +const mockVelocity = { + x: 8000, + y: 0, + z: 0, +} as EciVec3; +const mockPosition = { + x: 4, + y: 0, + z: 0, +} as EciVec3; + +describe('BaseObject', () => { + // create a new BaseObject with valid parameters + it('should create a new BaseObject with valid parameters', () => { + const info: BaseObjectParams = { + type: SpaceObjectType.PAYLOAD, + name: 'Satellite', + position: mockPosition, + velocity: mockVelocity, + time: new Date(), + active: true, + }; + + const baseObject = new BaseObject(info); + + expect(baseObject.type).toBe(SpaceObjectType.PAYLOAD); + expect(baseObject.name).toBe('Satellite'); + expect(baseObject.position.x).toBe(mockPosition.x); + expect(baseObject.position.y).toBe(mockPosition.y); + expect(baseObject.position.z).toBe(mockPosition.z); + expect(baseObject.velocity.x).toBe(mockVelocity.x); + expect(baseObject.velocity.y).toBe(mockVelocity.y); + expect(baseObject.velocity.z).toBe(mockVelocity.z); + expect(baseObject.time).toBe(info.time); + expect(baseObject.active).toBe(true); + }); + + // create a new BaseObject with default parameters + it('should create a new BaseObject with default parameters', () => { + const baseObject = new BaseObject({}); + + expect(baseObject.type).toBe(SpaceObjectType.UNKNOWN); + expect(baseObject.name).toBe('Unknown'); + expect(baseObject.position.x).toBe(0); + expect(baseObject.position.y).toBe(0); + expect(baseObject.position.z).toBe(0); + expect(baseObject.velocity.x).toBe(0); + expect(baseObject.velocity.y).toBe(0); + expect(baseObject.velocity.z).toBe(0); + expect(baseObject.time).toBeInstanceOf(Date); + expect(baseObject.active).toBe(true); + }); + + // check if BaseObject is a satellite + it('should return false when BaseObject is not a Satellite', () => { + const info: BaseObjectParams = { + type: SpaceObjectType.PAYLOAD, + name: 'Satellite', + }; + + const baseObject = new BaseObject(info); + + expect(baseObject.isSatellite()).toBe(false); + }); + + // check if BaseObject is a payload + it('should return true when the object is a payload', () => { + const info: BaseObjectParams = { + type: SpaceObjectType.PAYLOAD, + name: 'Satellite', + position: mockPosition, + velocity: mockVelocity, + time: new Date(), + active: true, + }; + + const baseObject = new BaseObject(info); + + const result = baseObject.isPayload(); + + expect(result).toBe(true); + }); + + // check if BaseObject is a rocket body + it('should return true when the object is a rocket body', () => { + const info: BaseObjectParams = { + type: SpaceObjectType.ROCKET_BODY, + name: 'Rocket', + position: mockPosition, + velocity: mockVelocity, + time: new Date(), + active: true, + }; + + const baseObject = new BaseObject(info); + + const result = baseObject.isRocketBody(); + + expect(result).toBe(true); + }); + + // check if BaseObject is debris + it('should return true when the object is debris', () => { + const info: BaseObjectParams = { + type: SpaceObjectType.DEBRIS, + name: 'Debris', + position: mockPosition, + velocity: mockVelocity, + time: new Date(), + active: true, + }; + + const baseObject = new BaseObject(info); + + const result = baseObject.isDebris(); + + expect(result).toBe(true); + }); + + // check if BaseObject is a star + it('should return true when the object is a star', () => { + const info: BaseObjectParams = { + type: SpaceObjectType.STAR, + name: 'Star Object', + position: mockPosition, + velocity: mockVelocity, + time: new Date(), + active: true, + }; + + const baseObject = new BaseObject(info); + + const result = baseObject.isStar(); + + expect(result).toBe(true); + }); + + // check if BaseObject is a missile + it('should return true when the object is a missile', () => { + const info: BaseObjectParams = { + type: SpaceObjectType.BALLISTIC_MISSILE, + name: 'Missile', + position: mockPosition, + velocity: mockVelocity, + time: new Date(), + active: true, + }; + + const baseObject = new BaseObject(info); + + expect(baseObject.isMissile()).toBe(true); + }); + + // check if BaseObject is notional + it('should return true when the object is notional', () => { + const info: BaseObjectParams = { + type: SpaceObjectType.NOTIONAL, + name: 'Notional Object', + position: mockPosition, + velocity: mockVelocity, + time: new Date(), + active: true, + }; + + const baseObject = new BaseObject(info); + + expect(baseObject.isNotional()).toBe(true); + }); + + // get BaseObject type string + it('should return the correct type string when called getTypeString()', () => { + const info: BaseObjectParams = { + type: SpaceObjectType.PAYLOAD, + name: 'Satellite', + position: mockPosition, + velocity: mockVelocity, + time: new Date(), + active: true, + }; + + const baseObject = new BaseObject(info); + + const typeString = baseObject.getTypeString(); + + expect(typeString).toBe('Payload'); + }); + + // check if BaseObject is a sensor + it('should return false when calling isSensor() method', () => { + const info: BaseObjectParams = { + type: SpaceObjectType.PAYLOAD, + name: 'Satellite', + position: mockPosition, + velocity: mockVelocity, + time: new Date(), + active: true, + }; + + const baseObject = new BaseObject(info); + + const result = baseObject.isSensor(); + + expect(result).toBe(false); + }); + + // check if BaseObject is a marker + it('should return false when calling isMarker() method on BaseObject instance', () => { + const info: BaseObjectParams = { + type: SpaceObjectType.PAYLOAD, + name: 'Satellite', + position: mockPosition, + velocity: mockVelocity, + time: new Date(), + active: true, + }; + + const baseObject = new BaseObject(info); + + const result = baseObject.isMarker(); + + expect(result).toBe(false); + }); + + // check if BaseObject is static + it('should return true when calling isStatic() method', () => { + const info: BaseObjectParams = { + type: SpaceObjectType.PAYLOAD, + name: 'Satellite', + position: mockPosition, + velocity: mockVelocity, + time: new Date(), + active: true, + }; + + const baseObject = new BaseObject(info); + + const result = baseObject.isStatic(); + + expect(result).toBe(true); + }); + + // check if BaseObject is a land object + it('should return false when the object type is a different land object type', () => { + const info: BaseObjectParams = { + type: SpaceObjectType.GROUND_SENSOR_STATION, + name: 'Ground Sensor Station', + position: mockPosition, + velocity: mockVelocity, + time: new Date(), + active: true, + }; + + const baseObject = new BaseObject(info); + + const result = baseObject.isLandObject(); + + expect(result).toBe(false); + }); +}); diff --git a/test/objects/Satellite.test.ts b/test/objects/Satellite.test.ts new file mode 100644 index 0000000..1d96575 --- /dev/null +++ b/test/objects/Satellite.test.ts @@ -0,0 +1,173 @@ +import { exampleDate } from '../lib/mockData'; +import { + Degrees, + GroundPosition, + Kilometers, + RAD2DEG, + Satellite, + SatelliteParams, + TleLine1, + TleLine2, +} from '../../src'; + +const dateObj = new Date(1661400000000); + +const tle1 = '1 25544U 98067A 22203.46960946 .00003068 00000+0 61583-4 0 9996' as TleLine1; +const tle2 = '2 25544 51.6415 161.8339 0005168 35.9781 54.7009 15.50067047350657' as TleLine2; + +const llaObserver = { + lat: 40 as Degrees, + lon: -75 as Degrees, + alt: 0 as Kilometers, +}; + +describe('Basic Satellite functionality', () => { + it('should create a new Sat object', () => { + const sat = new Satellite({ name: 'Test', tle1, tle2 }); + + expect(sat).toBeDefined(); + expect(sat.inclination).toBe(51.6415); + expect(sat.rightAscension).toBe(161.8339); + expect(sat.satrec).toBeDefined(); + }); + + it('should allow chaining', () => { + const eci = new Satellite({ name: 'Test', tle1, tle2 }).propagateTo(dateObj).eci().position; + + expect(eci.x).toBeCloseTo(6512.640035319078); + expect(eci.y).toBeCloseTo(-1545.524934684146); + expect(eci.z).toBeCloseTo(-1195.219347050479); + }); + + it('should allow getting eci coordinates', () => { + const sat = new Satellite({ name: 'Test', tle1, tle2 }); + + const eci = sat.eci(dateObj).position; + + expect(eci.x).toBeCloseTo(6512.640035319078); + expect(eci.y).toBeCloseTo(-1545.524934684146); + expect(eci.z).toBeCloseTo(-1195.219347050479); + }); + + it('should allow getting ecf coordinates', () => { + const sat = new Satellite({ name: 'Test', tle1, tle2 }); + + const eci = sat.ecf(dateObj); + + expect(eci.x).toBeCloseTo(4585.677469309576); + expect(eci.y).toBeCloseTo(-4875.929624270418); + expect(eci.z).toBeCloseTo(-1195.219347050479); + }); + + it('should allow getting lla coordinates', () => { + const sat = new Satellite({ name: 'Test', tle1, tle2 }); + + const eci = sat.lla(dateObj); + + expect(eci.lat).toBeCloseTo(-0.17779469476167792 * RAD2DEG); + expect(eci.lon).toBeCloseTo(-0.8160653803347542 * RAD2DEG); + expect(eci.alt).toBeCloseTo(421.9147233728436); + }); + + it('should be able to get the orbital period', () => { + const sat = new Satellite({ name: 'Test', tle1, tle2 }); + + expect(sat.period).toBeCloseTo(92.89920734635164); + }); +}); + +describe('Satellite', () => { + let satellite: Satellite; + let observer: GroundPosition; + + beforeEach(() => { + const satelliteParams: SatelliteParams = { + tle1, + tle2, + }; + + satellite = new Satellite(satelliteParams); + observer = new GroundPosition(llaObserver); + }); + // can be instantiated with valid input parameters + it('should instantiate Satellite with valid input parameters', () => { + expect(satellite).toMatchSnapshot(); + }); + + // can propagate to a given date + it('should propagate Satellite to a given date', () => { + satellite.propagateTo(exampleDate); + + expect(satellite).toMatchSnapshot(); + }); + + // can calculate and return RAE coordinates + it('should calculate and return RAE coordinates', () => { + const rae = satellite.rae(observer); + + expect(rae).toMatchSnapshot(); + }); + + // can calculate and return ECI coordinates + it('should calculate and return ECI coordinates', () => { + const eci = satellite.eci(exampleDate); + + expect(eci).toMatchSnapshot(); + }); + + // can calculate and return ECF coordinates + it('should calculate and return ECF coordinates correctly', () => { + const ecfCoordinates = satellite.ecf(exampleDate); + + expect(ecfCoordinates).toMatchSnapshot(); + }); + + // can calculate and return LLA coordinates + it('should calculate and return LLA coordinates when given a date', () => { + const lla = satellite.lla(exampleDate); + + expect(lla).toMatchSnapshot(); + }); + + // can calculate and return Geodetic coordinates + it('should calculate and return Geodetic coordinates when given a date', () => { + const geodetic = satellite.getGeodetic(exampleDate); + + expect(geodetic).toMatchSnapshot(); + }); + + // can calculate and return ITRF coordinates + it('should calculate and return ITRF coordinates when called', () => { + const itrfCoordinates = satellite.getITRF(exampleDate); + + expect(itrfCoordinates).toMatchSnapshot(); + }); + + // can calculate and return RIC coordinates + it('should calculate and return RIC coordinates correctly', () => { + const referenceSatellite = new Satellite({ + tle1: '1 25544U 98067A 21278.52661806 .00000800 00000-0 20684-4 0 9995' as TleLine1, + tle2: '2 25544 51.6442 13.1247 0008036 23.6079 336.5377 15.48861704303602' as TleLine2, + }); + + const ric = satellite.getRIC(referenceSatellite, exampleDate); + + expect(ric).toMatchSnapshot(); + }); + + // can calculate and return range to an observer + it('should calculate and return range to an observer', () => { + const range = satellite.range(observer, exampleDate); + + expect(range).toMatchSnapshot(); + }); + + // can calculate and return azimuth and elevation angles + it('should calculate and return azimuth and elevation angles correctly', () => { + const azimuth = satellite.az(observer, exampleDate); + const elevation = satellite.el(observer, exampleDate); + + expect(azimuth).toMatchSnapshot(); + expect(elevation).toMatchSnapshot(); + }); +}); diff --git a/test/objects/__snapshots__/Satellite.test.ts.snap b/test/objects/__snapshots__/Satellite.test.ts.snap new file mode 100644 index 0000000..c3da6d3 --- /dev/null +++ b/test/objects/__snapshots__/Satellite.test.ts.snap @@ -0,0 +1,423 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Satellite should calculate and return ECF coordinates correctly 1`] = ` +Object { + "x": 2103.9414256471673, + "y": 5645.057714165688, + "z": -3117.140819332331, +} +`; + +exports[`Satellite should calculate and return ECI coordinates 1`] = ` +Object { + "position": Object { + "x": -5512.260085235448, + "y": -2430.686090702759, + "z": -3117.140819332331, + }, + "velocity": Object { + "x": 4.465372431076766, + "y": -3.8849829704336245, + "z": -4.87332392823815, + }, +} +`; + +exports[`Satellite should calculate and return Geodetic coordinates when given a date 1`] = ` +Geodetic { + "altitude": 405.17244322847, + "latitude": 0.1099327125671112, + "longitude": 0.2809557331563047, +} +`; + +exports[`Satellite should calculate and return ITRF coordinates when called 1`] = ` +ITRF { + "epoch": EpochUTC { + "posix": 1705109326817, + }, + "position": Vector3D { + "x": 6478.244529235784, + "y": 1869.552512878403, + "z": 739.5500168212324, + }, + "velocity": Vector3D { + "x": 2.366559347644857, + "y": -7.704390508005883, + "z": -1.227328372730736, + }, +} +`; + +exports[`Satellite should calculate and return LLA coordinates when given a date 1`] = ` +Object { + "alt": 409.4490107065576, + "lat": -27.505811285213248, + "lon": 69.5593222250588, +} +`; + +exports[`Satellite should calculate and return RAE coordinates 1`] = ` +RAE { + "azimuth": 6.113212092185137, + "azimuthRate": -0.053738284359553745, + "elevation": -0.8739811433607586, + "elevationRate": -0.017615972911599442, + "epoch": EpochUTC { + "posix": 1705169134155, + }, + "range": 10316.599142891455, + "rangeRate": 2.3827483072818723, +} +`; + +exports[`Satellite should calculate and return RIC coordinates correctly 1`] = ` +RIC { + "position": Vector3D { + "x": -651.0936413365231, + "y": 2844.5316796447228, + "z": -360.1817484095949, + }, + "velocity": Vector3D { + "x": -0.1772334154266959, + "y": -8.239366799238207, + "z": -7.64249654102282, + }, +} +`; + +exports[`Satellite should calculate and return azimuth and elevation angles correctly 1`] = `4428.208084880647`; + +exports[`Satellite should calculate and return azimuth and elevation angles correctly 2`] = `-4214.429082266819`; + +exports[`Satellite should calculate and return range to an observer 1`] = `12650.301530537545`; + +exports[`Satellite should instantiate Satellite with valid input parameters 1`] = ` +Satellite { + "active": true, + "apogee": 427.1806416558675, + "argOfPerigee": 35.9781, + "bstar": 0.000061583, + "eccentricity": 0.0005168, + "epochDay": 203.46960946, + "epochYear": 22, + "id": undefined, + "inclination": 51.6415, + "intlDes": "98067A", + "meanAnomaly": 54.7009, + "meanMoDev1": 0.00003068, + "meanMoDev2": 0, + "meanMotion": 15.50067047, + "name": "Unknown", + "options": Object { + "notes": "", + }, + "perigee": 420.1576716155696, + "period": 92.89920734635164, + "position": Object { + "x": 0, + "y": 0, + "z": 0, + }, + "rightAscension": 161.8339, + "satrec": Object { + "Om": null, + "PInco": 0, + "a": 1.0653855229682034, + "alta": 0.06593611420647338, + "altp": 0.06483493172993349, + "am": null, + "argpdot": 0.00004469391640450765, + "argpo": 0.6279363036117719, + "atime": 0, + "aycof": 0.0009194351859734261, + "bstar": 0.000061583, + "cc1": 1.054843477494549e-9, + "cc4": 0.0000010146140032928037, + "cc5": 0.000502156969435659, + "con41": 0.1553585313770025, + "d2": 8.920486693245565e-17, + "d2201": 0, + "d2211": 0, + "d3": 1.1284305919522795e-23, + "d3210": 0, + "d3222": 0, + "d4": 1.664351729935925e-30, + "d4410": 0, + "d4422": 0, + "d5220": 0, + "d5232": 0, + "d5421": 0, + "d5433": 0, + "dedt": 0, + "del1": 0, + "del2": 0, + "del3": 0, + "delmo": 1.0180635988014979, + "didt": 0, + "dmdt": 0, + "dnodt": 0, + "domdt": 0, + "e3": 0, + "ecco": 0.0005168, + "ee2": 0, + "em": null, + "epochdays": 203.46960946, + "epochyr": 22, + "error": 0, + "eta": 0.010357978846619898, + "gsto": 1.9068261868288872, + "im": null, + "inclo": 0.9013142056686517, + "init": "n", + "irez": 0, + "isimp": 0, + "j2": 0.001082616, + "j3": -0.00000253881, + "j3oj2": -0.002345069720011528, + "j4": -0.00000165597, + "jdsatepoch": 2459782.96960946, + "mdot": 0.06763444178039692, + "method": "n", + "mm": null, + "mo": 0.9547108088041661, + "mus": 398600.8, + "nddot": 0, + "ndot": 0.00003068, + "nm": null, + "no": 0.06762691649010695, + "nodecf": -2.2167955787538495e-13, + "nodedot": -0.00006007612419537387, + "nodeo": 2.8245343963432514, + "om": null, + "omgcof": 1.0625960227343085e-7, + "operationmode": "i", + "peo": 0, + "pgho": 0, + "pho": 0, + "plo": 0, + "radiusearthkm": 6378.135, + "satnum": "25544", + "se2": 0, + "se3": 0, + "sgh2": 0, + "sgh3": 0, + "sgh4": 0, + "sh2": 0, + "sh3": 0, + "si2": 0, + "si3": 0, + "sinmao": 0.8161466669458108, + "sl2": 0, + "sl3": 0, + "sl4": 0, + "t": 0, + "t2cof": 1.5822652162418235e-9, + "t3cof": 9.143025645648123e-17, + "t4cof": 8.748455252805885e-24, + "t5cof": 1.0373269324942988e-30, + "tumin": 13.446839696959309, + "x1mth2": 0.6148804895409992, + "x7thm1": 1.6958365732130058, + "xfact": 0, + "xgh2": 0, + "xgh3": 0, + "xgh4": 0, + "xh2": 0, + "xh3": 0, + "xi2": 0, + "xi3": 0, + "xke": 0.07436691613317342, + "xl2": 0, + "xl3": 0, + "xl4": 0, + "xlamo": 0, + "xlcof": 0.0017312384987971355, + "xli": 0, + "xmcof": -0.001806247608164991, + "xni": 0, + "zmol": 0, + "zmos": 0, + }, + "sccNum": "25544", + "sccNum5": "25544", + "sccNum6": "25544", + "semiMajorAxis": 6794.6691566357185, + "semiMinorAxis": 6794.668249267928, + "time": 2024-01-13T18:05:34.152Z, + "tle1": "1 25544U 98067A 22203.46960946 .00003068 00000+0 61583-4 0 9996", + "tle2": "2 25544 51.6415 161.8339 0005168 35.9781 54.7009 15.50067047350657", + "totalVelocity": 0, + "type": 0, + "velocity": Object { + "x": 0, + "y": 0, + "z": 0, + }, +} +`; + +exports[`Satellite should propagate Satellite to a given date 1`] = ` +Satellite { + "active": true, + "apogee": 427.1806416558675, + "argOfPerigee": 35.9781, + "bstar": 0.000061583, + "eccentricity": 0.0005168, + "epochDay": 203.46960946, + "epochYear": 22, + "id": undefined, + "inclination": 51.6415, + "intlDes": "98067A", + "meanAnomaly": 54.7009, + "meanMoDev1": 0.00003068, + "meanMoDev2": 0, + "meanMotion": 15.50067047, + "name": "Unknown", + "options": Object { + "notes": "", + }, + "perigee": 420.1576716155696, + "period": 92.89920734635164, + "position": Object { + "x": -5512.260085235448, + "y": -2430.686090702759, + "z": -3117.140819332331, + }, + "rightAscension": 161.8339, + "satrec": Object { + "Om": null, + "PInco": 0, + "a": 1.0653855229682034, + "alta": 0.06593611420647338, + "altp": 0.06483493172993349, + "am": null, + "argpdot": 0.00004469391640450765, + "argpo": 0.6279363036117719, + "atime": 0, + "aycof": 0.0009194351859734261, + "bstar": 0.000061583, + "cc1": 1.054843477494549e-9, + "cc4": 0.0000010146140032928037, + "cc5": 0.000502156969435659, + "con41": 0.1553585313770025, + "d2": 8.920486693245565e-17, + "d2201": 0, + "d2211": 0, + "d3": 1.1284305919522795e-23, + "d3210": 0, + "d3222": 0, + "d4": 1.664351729935925e-30, + "d4410": 0, + "d4422": 0, + "d5220": 0, + "d5232": 0, + "d5421": 0, + "d5433": 0, + "dedt": 0, + "del1": 0, + "del2": 0, + "del3": 0, + "delmo": 1.0180635988014979, + "didt": 0, + "dmdt": 0, + "dnodt": 0, + "domdt": 0, + "e3": 0, + "ecco": 0.0005168, + "ee2": 0, + "em": null, + "epochdays": 203.46960946, + "epochyr": 22, + "error": 0, + "eta": 0.010357978846619898, + "gsto": 1.9068261868288872, + "im": null, + "inclo": 0.9013142056686517, + "init": "n", + "irez": 0, + "isimp": 0, + "j2": 0.001082616, + "j3": -0.00000253881, + "j3oj2": -0.002345069720011528, + "j4": -0.00000165597, + "jdsatepoch": 2459782.96960946, + "mdot": 0.06763444178039692, + "method": "n", + "mm": null, + "mo": 0.9547108088041661, + "mus": 398600.8, + "nddot": 0, + "ndot": 0.00003068, + "nm": null, + "no": 0.06762691649010695, + "nodecf": -2.2167955787538495e-13, + "nodedot": -0.00006007612419537387, + "nodeo": 2.8245343963432514, + "om": null, + "omgcof": 1.0625960227343085e-7, + "operationmode": "i", + "peo": 0, + "pgho": 0, + "pho": 0, + "plo": 0, + "radiusearthkm": 6378.135, + "satnum": "25544", + "se2": 0, + "se3": 0, + "sgh2": 0, + "sgh3": 0, + "sgh4": 0, + "sh2": 0, + "sh3": 0, + "si2": 0, + "si3": 0, + "sinmao": 0.8161466669458108, + "sl2": 0, + "sl3": 0, + "sl4": 0, + "t": 777012.542661354, + "t2cof": 1.5822652162418235e-9, + "t3cof": 9.143025645648123e-17, + "t4cof": 8.748455252805885e-24, + "t5cof": 1.0373269324942988e-30, + "tumin": 13.446839696959309, + "x1mth2": 0.6148804895409992, + "x7thm1": 1.6958365732130058, + "xfact": 0, + "xgh2": 0, + "xgh3": 0, + "xgh4": 0, + "xh2": 0, + "xh3": 0, + "xi2": 0, + "xi3": 0, + "xke": 0.07436691613317342, + "xl2": 0, + "xl3": 0, + "xl4": 0, + "xlamo": 0, + "xlcof": 0.0017312384987971355, + "xli": 0, + "xmcof": -0.001806247608164991, + "xni": 0, + "zmol": 0, + "zmos": 0, + }, + "sccNum": "25544", + "sccNum5": "25544", + "sccNum6": "25544", + "semiMajorAxis": 6794.6691566357185, + "semiMinorAxis": 6794.668249267928, + "time": 2024-01-13T01:28:46.817Z, + "tle1": "1 25544U 98067A 22203.46960946 .00003068 00000+0 61583-4 0 9996", + "tle2": "2 25544 51.6415 161.8339 0005168 35.9781 54.7009 15.50067047350657", + "totalVelocity": 0, + "type": 0, + "velocity": Object { + "x": 0, + "y": 0, + "z": 0, + }, +} +`; diff --git a/test/sat/__snapshots__/sensor.test.ts.snap b/test/objects/__snapshots__/sensor.test.ts.snap similarity index 100% rename from test/sat/__snapshots__/sensor.test.ts.snap rename to test/objects/__snapshots__/sensor.test.ts.snap diff --git a/test/sun-moon/__snapshots__/sun-moon.test.ts.snap b/test/objects/__snapshots__/sun-moon.test.ts.snap similarity index 100% rename from test/sun-moon/__snapshots__/sun-moon.test.ts.snap rename to test/objects/__snapshots__/sun-moon.test.ts.snap diff --git a/test/sat/sensor.test.ts b/test/objects/sensor.test.ts similarity index 97% rename from test/sat/sensor.test.ts rename to test/objects/sensor.test.ts index de2345a..55af315 100644 --- a/test/sat/sensor.test.ts +++ b/test/objects/sensor.test.ts @@ -1,10 +1,4 @@ -/** - * @file Test Suite to verify sat class work as expected - * @author Theodore Kruczek. - * @since 1.2.0 - */ - -import { Degrees, Kilometers, Satellite, Sensor, SpaceObjectType, TleLine1, TleLine2 } from '../../lib/index'; +import { Degrees, Kilometers, Satellite, Sensor, SpaceObjectType, TleLine1, TleLine2 } from '../../src/index'; const dateObj = new Date(1661400000000); diff --git a/test/objects/star.test.ts b/test/objects/star.test.ts index 2ca9305..8bcae20 100644 --- a/test/objects/star.test.ts +++ b/test/objects/star.test.ts @@ -1,10 +1,4 @@ -/** - * @file Test Suite to verify star class work as expected - * @author Theodore Kruczek. - * @since 3.0.0 - */ - -import { Degrees, Kilometers, Radians, Star } from '../../lib/index'; +import { Degrees, Kilometers, Radians, Star } from '../../src/index'; describe('Basic Star functionality', () => { const star = new Star({ diff --git a/test/sun-moon/sun-moon.test.ts b/test/objects/sun-moon.test.ts similarity index 93% rename from test/sun-moon/sun-moon.test.ts rename to test/objects/sun-moon.test.ts index 81e2d17..fcc7a52 100644 --- a/test/sun-moon/sun-moon.test.ts +++ b/test/objects/sun-moon.test.ts @@ -1,13 +1,7 @@ -/** - * @file Test Suite to verify tle functions work as expected - * @author Theodore Kruczek. - * @since 1.3.0 - */ - -import { Celestial } from '../../lib/body/Celestial'; -import { Moon } from '../../lib/body/Moon'; -import { Sun } from '../../lib/body/Sun'; -import { Degrees, Meters } from '../../lib/index'; +import { Celestial } from '../../src/body/Celestial'; +import { Moon } from '../../src/body/Moon'; +import { Sun } from '../../src/body/Sun'; +import { Degrees, Meters } from '../../src/index'; // Use number of milliseconds since epoch instead of local year, month, day, etc for consistency across machines const dateObj = new Date(1661406000000); @@ -17,7 +11,7 @@ describe('Sun and Moon', () => { const d = Sun.julian2date(Sun.date2jSince2000(dateObj)); const c = Sun.raDec(d); - Celestial.getStarAzEl(dateObj, 0 as Degrees, 0 as Degrees, c.ra, c.dec); + Celestial.azEl(dateObj, 0 as Degrees, 0 as Degrees, c.ra, c.dec); Sun.azEl(dateObj, 0 as Degrees, 0 as Degrees); }); @@ -34,7 +28,7 @@ describe('Sun and Moon', () => { Moon.rae(dateObj, 0 as Degrees, 0 as Degrees); /* - * TODO: Fix this test to work on ci/cd pipeline + * TODO: #4 Fix this test to work on ci/cd pipeline * Moon.getMoonTimes(dateObj, 0 as Degrees, 0 as Degrees, true); * Moon.getMoonTimes(dateObj, -10 as Degrees, -10 as Degrees, false); */ @@ -135,7 +129,9 @@ describe('Suncalc.js tests', () => { // eslint-disable-next-line guard-for-in for (const i in testTimes) { - expect(times[i].toUTCString()).toEqual(new Date(testTimes[i]).toUTCString()); + const key = i as keyof typeof testTimes; + + expect(times[i].toUTCString()).toEqual(new Date(testTimes[key]).toUTCString()); } }); @@ -144,7 +140,9 @@ describe('Suncalc.js tests', () => { // eslint-disable-next-line guard-for-in for (const i in heightTestTimes) { - expect(times[i].toUTCString()).toEqual(new Date(heightTestTimes[i]).toUTCString()); + const key = i as keyof typeof heightTestTimes; + + expect(times[i].toUTCString()).toEqual(new Date(heightTestTimes[key]).toUTCString()); } }); @@ -215,7 +213,9 @@ describe('Tests from Hypnos3', () => { // eslint-disable-next-line guard-for-in for (const i in testTimes) { - expect(times[i].toUTCString()).toEqual(new Date(testTimes[i]).toUTCString()); + const key = i as keyof typeof testTimes; + + expect(times[i].toUTCString()).toEqual(new Date(testTimes[key]).toUTCString()); } }); diff --git a/test/sat/sat.test.ts b/test/sat/sat.test.ts deleted file mode 100644 index 1e86185..0000000 --- a/test/sat/sat.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file Test Suite to verify sat class work as expected - * @author Theodore Kruczek. - * @since 1.2.0 - */ - -import { Satellite, TleLine1, TleLine2 } from '../../lib/index'; -import { RAD2DEG } from '../../lib/utils/constants'; - -const dateObj = new Date(1661400000000); - -const tle1 = '1 25544U 98067A 22203.46960946 .00003068 00000+0 61583-4 0 9996' as TleLine1; -const tle2 = '2 25544 51.6415 161.8339 0005168 35.9781 54.7009 15.50067047350657' as TleLine2; - -describe('Basic Satellite functionality', () => { - it('should create a new Sat object', () => { - const sat = new Satellite({ name: 'Test', tle1, tle2 }); - - expect(sat).toBeDefined(); - expect(sat.inclination).toBe(51.6415); - expect(sat.rightAscension).toBe(161.8339); - expect(sat.satrec).toBeDefined(); - }); - - it('should allow chaining', () => { - const eci = new Satellite({ name: 'Test', tle1, tle2 }).propagateTo(dateObj).eci().position; - - expect(eci.x).toBeCloseTo(6512.640035319078); - expect(eci.y).toBeCloseTo(-1545.524934684146); - expect(eci.z).toBeCloseTo(-1195.219347050479); - }); - - it('should allow getting eci coordinates', () => { - const sat = new Satellite({ name: 'Test', tle1, tle2 }); - - const eci = sat.eci(dateObj).position; - - expect(eci.x).toBeCloseTo(6512.640035319078); - expect(eci.y).toBeCloseTo(-1545.524934684146); - expect(eci.z).toBeCloseTo(-1195.219347050479); - }); - - it('should allow getting ecf coordinates', () => { - const sat = new Satellite({ name: 'Test', tle1, tle2 }); - - const eci = sat.ecf(dateObj); - - expect(eci.x).toBeCloseTo(4585.677469309576); - expect(eci.y).toBeCloseTo(-4875.929624270418); - expect(eci.z).toBeCloseTo(-1195.219347050479); - }); - - it('should allow getting lla coordinates', () => { - const sat = new Satellite({ name: 'Test', tle1, tle2 }); - - const eci = sat.lla(dateObj); - - expect(eci.lat).toBeCloseTo(-0.17779469476167792 * RAD2DEG); - expect(eci.lon).toBeCloseTo(-0.8160653803347542 * RAD2DEG); - expect(eci.alt).toBeCloseTo(421.9147233728436); - }); - - it('should be able to get the orbital period', () => { - const sat = new Satellite({ name: 'Test', tle1, tle2 }); - - expect(sat.period).toBeCloseTo(92.89920734635164); - }); -}); diff --git a/test/sgp4/full-catalog/sgp4-catalog-0.test.js b/test/sgp4/full-catalog/sgp4-catalog-0.test.js index 2c44534..9d85f1c 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-0.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-0.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_0'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-1.test.js b/test/sgp4/full-catalog/sgp4-catalog-1.test.js index 6331453..985af28 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-1.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-1.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_1'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-10.test.js b/test/sgp4/full-catalog/sgp4-catalog-10.test.js index 5c2f778..0e857db 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-10.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-10.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_10'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-11.test.js b/test/sgp4/full-catalog/sgp4-catalog-11.test.js index fe55617..8665604 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-11.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-11.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_11'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-12.test.js b/test/sgp4/full-catalog/sgp4-catalog-12.test.js index 183a41c..464db5c 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-12.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-12.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_12'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-13.test.js b/test/sgp4/full-catalog/sgp4-catalog-13.test.js index 310d47f..6d31819 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-13.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-13.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_13'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-14.test.js b/test/sgp4/full-catalog/sgp4-catalog-14.test.js index e42b5a7..ede95ee 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-14.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-14.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_14'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-15.test.js b/test/sgp4/full-catalog/sgp4-catalog-15.test.js index e8bb8d6..f645a97 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-15.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-15.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_15'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-16.test.js b/test/sgp4/full-catalog/sgp4-catalog-16.test.js index f1e1854..3830732 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-16.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-16.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_16'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-17.test.js b/test/sgp4/full-catalog/sgp4-catalog-17.test.js index 67b5e23..a80b57e 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-17.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-17.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_17'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-18.test.js b/test/sgp4/full-catalog/sgp4-catalog-18.test.js index 9c6fcbf..ed062b4 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-18.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-18.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_18'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-19.test.js b/test/sgp4/full-catalog/sgp4-catalog-19.test.js index ce2604d..d491685 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-19.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-19.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_19'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-2.test.js b/test/sgp4/full-catalog/sgp4-catalog-2.test.js index 687d2f6..a0992d8 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-2.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-2.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_2'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-20.test.js b/test/sgp4/full-catalog/sgp4-catalog-20.test.js index f3af192..ce7485d 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-20.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-20.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_20'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-21.test.js b/test/sgp4/full-catalog/sgp4-catalog-21.test.js index 17c32a8..e1b86c8 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-21.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-21.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_21'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-22.test.js b/test/sgp4/full-catalog/sgp4-catalog-22.test.js index 3566fc9..f08145e 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-22.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-22.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_22'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-23.test.js b/test/sgp4/full-catalog/sgp4-catalog-23.test.js index 85fbe5c..387cd04 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-23.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-23.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_23'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-24.test.js b/test/sgp4/full-catalog/sgp4-catalog-24.test.js index 0fe3d6d..be3c0e6 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-24.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-24.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_24'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-25.test.js b/test/sgp4/full-catalog/sgp4-catalog-25.test.js index f01b25b..9f0aa31 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-25.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-25.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_25'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-26.test.js b/test/sgp4/full-catalog/sgp4-catalog-26.test.js index a78c782..205e13d 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-26.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-26.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_26'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-27.test.js b/test/sgp4/full-catalog/sgp4-catalog-27.test.js index c0d29c8..2abd362 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-27.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-27.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_27'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-28.test.js b/test/sgp4/full-catalog/sgp4-catalog-28.test.js index 64c66b2..556e554 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-28.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-28.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_28'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-29.test.js b/test/sgp4/full-catalog/sgp4-catalog-29.test.js index 8c856c8..b0fb89f 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-29.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-29.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_29'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-3.test.js b/test/sgp4/full-catalog/sgp4-catalog-3.test.js index faf87ee..2d892a2 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-3.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-3.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_3'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-30.test.js b/test/sgp4/full-catalog/sgp4-catalog-30.test.js index 1d63d9f..76b75cb 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-30.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-30.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_30'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-31.test.js b/test/sgp4/full-catalog/sgp4-catalog-31.test.js index fbbf904..3c4d406 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-31.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-31.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_31'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-32.test.js b/test/sgp4/full-catalog/sgp4-catalog-32.test.js index 868338d..481243b 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-32.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-32.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_32'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-33.test.js b/test/sgp4/full-catalog/sgp4-catalog-33.test.js index a88e000..733a53c 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-33.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-33.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_33'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-34.test.js b/test/sgp4/full-catalog/sgp4-catalog-34.test.js index 320693e..f82451b 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-34.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-34.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_34'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-35.test.js b/test/sgp4/full-catalog/sgp4-catalog-35.test.js index 85730ab..f01b94b 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-35.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-35.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_35'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-36.test.js b/test/sgp4/full-catalog/sgp4-catalog-36.test.js index 797aca8..d3532ec 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-36.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-36.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_36'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-37.test.js b/test/sgp4/full-catalog/sgp4-catalog-37.test.js index 138a5a8..086bd68 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-37.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-37.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_37'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-38.test.js b/test/sgp4/full-catalog/sgp4-catalog-38.test.js index 5da829b..b2f1045 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-38.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-38.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_38'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-39.test.js b/test/sgp4/full-catalog/sgp4-catalog-39.test.js index 0be305e..48a76fa 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-39.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-39.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_39'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-4.test.js b/test/sgp4/full-catalog/sgp4-catalog-4.test.js index 28bbcc8..0fe8914 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-4.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-4.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_4'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-40.test.js b/test/sgp4/full-catalog/sgp4-catalog-40.test.js index a7d7a2f..74791fe 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-40.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-40.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_40'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-41.test.js b/test/sgp4/full-catalog/sgp4-catalog-41.test.js index 37d51ad..6d8a4eb 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-41.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-41.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_41'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-42.test.js b/test/sgp4/full-catalog/sgp4-catalog-42.test.js index 7f002de..68da194 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-42.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-42.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_42'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-43.test.js b/test/sgp4/full-catalog/sgp4-catalog-43.test.js index 4034e0c..2d7053a 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-43.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-43.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_43'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-44.test.js b/test/sgp4/full-catalog/sgp4-catalog-44.test.js index 78bafe2..3670ff2 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-44.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-44.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_44'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-45.test.js b/test/sgp4/full-catalog/sgp4-catalog-45.test.js index 1f73812..588ed59 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-45.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-45.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_45'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-46.test.js b/test/sgp4/full-catalog/sgp4-catalog-46.test.js index 9cba00f..1bd4250 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-46.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-46.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_46'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-47.test.js b/test/sgp4/full-catalog/sgp4-catalog-47.test.js index 5313735..08d3dc8 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-47.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-47.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_47'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-48.test.js b/test/sgp4/full-catalog/sgp4-catalog-48.test.js index 48978b4..4d864d9 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-48.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-48.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_48'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-49.test.js b/test/sgp4/full-catalog/sgp4-catalog-49.test.js index 809203d..2541001 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-49.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-49.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_49'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-5.test.js b/test/sgp4/full-catalog/sgp4-catalog-5.test.js index 6d3a2a7..6239014 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-5.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-5.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_5'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-50.test.js b/test/sgp4/full-catalog/sgp4-catalog-50.test.js index 9860aa0..b255cc3 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-50.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-50.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_50'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-6.test.js b/test/sgp4/full-catalog/sgp4-catalog-6.test.js index 44cecb2..2cb2448 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-6.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-6.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_6'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-7.test.js b/test/sgp4/full-catalog/sgp4-catalog-7.test.js index 61ba350..9de0e86 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-7.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-7.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_7'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-8.test.js b/test/sgp4/full-catalog/sgp4-catalog-8.test.js index 468b289..884b282 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-8.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-8.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_8'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4-catalog-9.test.js b/test/sgp4/full-catalog/sgp4-catalog-9.test.js index 4e1a41b..877ff24 100644 --- a/test/sgp4/full-catalog/sgp4-catalog-9.test.js +++ b/test/sgp4/full-catalog/sgp4-catalog-9.test.js @@ -11,7 +11,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_9'; const rawData = fs.readFileSync(`test/sgp4/full-catalog/${fileName}.json`, 'utf8'); diff --git a/test/sgp4/full-catalog/sgp4TestMaker.mjs b/test/sgp4/full-catalog/sgp4TestMaker.mjs index 0ce4334..fd56342 100644 --- a/test/sgp4/full-catalog/sgp4TestMaker.mjs +++ b/test/sgp4/full-catalog/sgp4TestMaker.mjs @@ -17,7 +17,7 @@ import * as fs from 'fs'; /** * sgp4Data is from SGP4Prop 8.3 Build: Apr 27 2022 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; const fileName = 'TLE_${f}'; const rawData = fs.readFileSync(\`test/sgp4/full-catalog/\${fileName}.json\`, 'utf8'); diff --git a/test/sgp4/legacy/ext.test.js b/test/sgp4/legacy/ext.test.js index cdc108b..a8d4e7e 100644 --- a/test/sgp4/legacy/ext.test.js +++ b/test/sgp4/legacy/ext.test.js @@ -3,7 +3,7 @@ * @since 0.2.0 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; describe('Julian date / time', () => { // Use number of milliseconds since epoch instead of local year, month, day, etc for consistency across machines diff --git a/test/sgp4/legacy/initl.test.js b/test/sgp4/legacy/initl.test.js index 3f27a08..f1ad4cb 100644 --- a/test/sgp4/legacy/initl.test.js +++ b/test/sgp4/legacy/initl.test.js @@ -3,7 +3,7 @@ * @since 0.2.0 */ -import { Sgp4 } from '../../../lib/index'; // eslint-disable-line +import { Sgp4 } from '../../../src/index'; // eslint-disable-line // wgs84 constants const mu = 398600.8; // in km3 / s2 diff --git a/test/sgp4/legacy/io.test.js b/test/sgp4/legacy/io.test.js index e31f1b7..234a690 100644 --- a/test/sgp4/legacy/io.test.js +++ b/test/sgp4/legacy/io.test.js @@ -3,7 +3,7 @@ * @since 0.2.0 */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; import badTleData from './io.json'; describe('Twoline', () => { diff --git a/test/sgp4/rsr/rsr3.test.js b/test/sgp4/rsr/rsr3.test.js index 3572c01..d2c6be4 100644 --- a/test/sgp4/rsr/rsr3.test.js +++ b/test/sgp4/rsr/rsr3.test.js @@ -8,7 +8,7 @@ * sgp4Data is from https://www.celestrak.com/publications/AIAA/2006-6753/AIAA-2006-6753-Rev1.pdf * Only using the first and last state vectors for verification */ -import { Sgp4 } from '../../../lib/index'; +import { Sgp4 } from '../../../src/index'; import { compareVectors } from '../../lib/compareVectors'; import sgp4FailData from './rsr3-fail.json'; import sgp4Data from './rsr3.json'; diff --git a/test/sgp4/sgp4-full-cov-fail.json b/test/sgp4/sgp4-full-cov-fail.json deleted file mode 100644 index e31c1d9..0000000 --- a/test/sgp4/sgp4-full-cov-fail.json +++ /dev/null @@ -1,32 +0,0 @@ -[ - { - "description": "Mean motion is zero and that is not allowed.", - "tleLine1": "1 00001U 57001B 21005.53831292 -.00000083 00000-0 -11575-3 0 9996", - "tleLine2": "2 00001 34.2508 325.6936 1846988 181.8107 177.4919 00.00000000227203", - "error": 2 - }, - { - "description": "Eccentricity is way too high because mean motion is nearly zero.", - "tleLine1": "1 00002U 57001B 21005.53831292 -.00000083 00000-0 -11575-3 0 9996", - "tleLine2": "2 00002 34.2508 325.6936 1846988 181.8107 177.4919 00.00000001227203", - "error": 3 - }, - { - "description": "Mean motion is zero and that is not allowed.", - "tleLine1": "1 00004U 57001B 21005.53831292 -.00000083 00000-0 -11575-3 0 9996", - "tleLine2": "2 00004 34.2508 325.6936 9999999 181.8107 177.4919 10.84863720227203", - "error": 4 - }, - { - "description": "Satellite should be decayed already.", - "tleLine1": "1 00006U 57001B 21005.53831292 -.00000083 00000-0 -11575-3 0 9996", - "tleLine2": "2 00005 34.2508 325.6936 1846988 181.8107 177.4919 25.84863720227203", - "error": 6 - }, - { - "description": "error code 3", - "tleLine1": "1 33334U 78066F 06174.85818871 .00000620 00000-0 10000-3 0 6809", - "tleLine2": "2 33334 68.4714 236.1303 5602877 123.7484 302.5767 0.00001000 67521", - "error": 3 - } -] diff --git a/test/sgp4/sgp4-full-cov-fail.ts b/test/sgp4/sgp4-full-cov-fail.ts new file mode 100644 index 0000000..52c9e45 --- /dev/null +++ b/test/sgp4/sgp4-full-cov-fail.ts @@ -0,0 +1,32 @@ +export const sgp4FullCovFail = [ + { + description: 'Mean motion is zero and that is not allowed.', + tleLine1: '1 00001U 57001B 21005.53831292 -.00000083 00000-0 -11575-3 0 9996', + tleLine2: '2 00001 34.2508 325.6936 1846988 181.8107 177.4919 00.00000000227203', + error: 2, + }, + { + description: 'Eccentricity is way too high because mean motion is nearly zero.', + tleLine1: '1 00002U 57001B 21005.53831292 -.00000083 00000-0 -11575-3 0 9996', + tleLine2: '2 00002 34.2508 325.6936 1846988 181.8107 177.4919 00.00000001227203', + error: 3, + }, + { + description: 'Mean motion is zero and that is not allowed.', + tleLine1: '1 00004U 57001B 21005.53831292 -.00000083 00000-0 -11575-3 0 9996', + tleLine2: '2 00004 34.2508 325.6936 9999999 181.8107 177.4919 10.84863720227203', + error: 4, + }, + { + description: 'Satellite should be decayed already.', + tleLine1: '1 00006U 57001B 21005.53831292 -.00000083 00000-0 -11575-3 0 9996', + tleLine2: '2 00005 34.2508 325.6936 1846988 181.8107 177.4919 25.84863720227203', + error: 6, + }, + { + description: 'error code 3', + tleLine1: '1 33334U 78066F 06174.85818871 .00000620 00000-0 10000-3 0 6809', + tleLine2: '2 33334 68.4714 236.1303 5602877 123.7484 302.5767 0.00001000 67521', + error: 3, + }, +]; diff --git a/test/sgp4/sgp4-full-cov.json b/test/sgp4/sgp4-full-cov.json deleted file mode 100644 index 30f8959..0000000 --- a/test/sgp4/sgp4-full-cov.json +++ /dev/null @@ -1,82 +0,0 @@ -[ - { - "description": "Cover improved mode", - "tleLine1": "1 25544U 98067A 21009.90234038 .00001675 00000-0 38183-4 0 9997", - "tleLine2": "2 25544 51.6464 45.6388 0000512 205.3232 213.2158 15.49275327264062", - "results": [ - { - "time": 0.0, - "position": { - "x": -87.81891086100381, - "y": 5051.02598276444, - "z": 4539.258657271001 - }, - "velocity": { - "x": -6.343534031455946, - "y": -2.9378975654843975, - "z": 3.137917235399209 - } - } - ] - }, - { - "description": "Cover Alpha-5", - "tleLine1": "1 A5544U 98067A 21009.90234038 .00001675 00000-0 38183-4 0 9997", - "tleLine2": "2 A5544 51.6464 45.6388 0000512 205.3232 213.2158 15.49275327264062", - "results": [ - { - "time": 0.0, - "position": { - "x": -87.81891086100381, - "y": 5051.02598276444, - "z": 4539.258657271001 - }, - "velocity": { - "x": -6.343534031455946, - "y": -2.9378975654843975, - "z": 3.137917235399209 - } - } - ] - }, - { - "description": "Cover xinco = 180", - "tleLine1": "1 B0000U 98067A 21009.90234038 .00001675 00000-0 38183-4 0 9997", - "tleLine2": "2 B0000 180.0000 45.6388 0000512 205.3232 213.2158 15.49275327264062", - "results": [ - { - "time": 0.0, - "position": { - "x": 6622.655052157549, - "y": -1516.4238662512882, - "z": 7.094183623471915e-13 - }, - "velocity": { - "x": -1.7109990955273406, - "y": -7.471458763296151, - "z": 4.90442971002966e-16 - } - } - ] - }, - { - "description": "Use wgs72old", - "tleLine1": "1 B0000U 98067A 21009.90234038 .00001675 00000-0 38183-4 0 9997", - "tleLine2": "2 B0000 180.0000 45.6388 0000512 205.3232 213.2158 15.49275327264062", - "results": [ - { - "time": 0.0, - "position": { - "x": 6622.655052157549, - "y": -1516.4238662512882, - "z": 7.094183623471915e-13 - }, - "velocity": { - "x": -1.7109990955273406, - "y": -7.471458763296151, - "z": 4.90442971002966e-16 - } - } - ] - } -] diff --git a/test/sgp4/sgp4-full-cov.test.js b/test/sgp4/sgp4-full-cov.test.ts similarity index 51% rename from test/sgp4/sgp4-full-cov.test.js rename to test/sgp4/sgp4-full-cov.test.ts index ccc791b..90fbc5a 100644 --- a/test/sgp4/sgp4-full-cov.test.js +++ b/test/sgp4/sgp4-full-cov.test.ts @@ -1,33 +1,38 @@ -/** - * @file Test Suite to verify results match Appendix D from Revisiting Spacetrack Report #3 - * @author Theodore Kruczek. - * @since 0.2.0 - */ - -import { Sgp4 } from '../../lib/index'; -import sgp4FailData from './sgp4-full-cov-fail.json'; -import sgp4Data from './sgp4-full-cov.json'; +import { EciVec3, Sgp4 } from '../../src/index'; +import { sgp4FullCovFail } from './sgp4-full-cov-fail'; +import { sgp4FullCov } from './sgp4-full-cov'; +import { Sgp4GravConstants } from '../../src/sgp4/sgp4'; +import { Sgp4OpsMode } from '../../src/enums/Sgp4OpsMode'; describe('Verification TLE Data in Appendix D of Revisiting Spacetrack Report #3: Rev 1', () => { - sgp4Data.forEach((sgp4DataItem) => { + sgp4FullCov.forEach((sgp4DataItem) => { // Fetching satellite record from TLE lines - const satrec = Sgp4.createSatrec(sgp4DataItem.tleLine1, sgp4DataItem.tleLine2); - - if (sgp4DataItem.error) { + const satrec = Sgp4.createSatrec( + sgp4DataItem.tleLine1, + sgp4DataItem.tleLine2, + Sgp4GravConstants.wgs72, + Sgp4OpsMode.AFSPC, + ); + + if ((sgp4DataItem as unknown as { error: true }).error) { test(`if ${sgp4DataItem.description} fails`, () => { - expect(satrec.error).toEqual(sgp4DataItem.error); + expect(satrec.error).toEqual((sgp4DataItem as unknown as { error: true }).error); }); } else { test(`if ${sgp4DataItem.description} passes`, () => { sgp4DataItem.results.forEach((expected) => { - const sgp4Result = Sgp4.propagate(satrec, expected.time, 'a'); - - expect(sgp4Result.position.x).toBeCloseTo(expected.position.x); - expect(sgp4Result.position.y).toBeCloseTo(expected.position.y); - expect(sgp4Result.position.z).toBeCloseTo(expected.position.z); - expect(sgp4Result.velocity.x).toBeCloseTo(expected.velocity.x); - expect(sgp4Result.velocity.y).toBeCloseTo(expected.velocity.y); - expect(sgp4Result.velocity.z).toBeCloseTo(expected.velocity.z); + const sgp4Result = Sgp4.propagate(satrec, expected.time); + + expect(sgp4Result).not.toBe(false); + const position = sgp4Result?.position as EciVec3; + const velocity = sgp4Result?.velocity as EciVec3; + + expect(position.x).toBeCloseTo(expected.position.x); + expect(position.y).toBeCloseTo(expected.position.y); + expect(position.z).toBeCloseTo(expected.position.z); + expect(velocity.x).toBeCloseTo(expected.velocity.x); + expect(velocity.y).toBeCloseTo(expected.velocity.y); + expect(velocity.z).toBeCloseTo(expected.velocity.z); }); }); } @@ -39,22 +44,24 @@ describe('Verify getgravconst options', () => { const line2 = '2 00005 34.2682 348.7242 1859667 331.7664 19.3264 10.82419157413667'; test('if wgs72old can be selected', () => { - const satrec = Sgp4.createSatrec(line1, line2, 'wgs72old', 'a'); + const satrec = Sgp4.createSatrec(line1, line2, Sgp4GravConstants.wgs72old, Sgp4OpsMode.AFSPC); expect(satrec.xmcof).toEqual(-1.8859361255715234e-11); }); test('if wgs84 can be selected', () => { - const satrec = Sgp4.createSatrec(line1, line2, 'wgs84', 'a'); + const satrec = Sgp4.createSatrec(line1, line2, Sgp4GravConstants.wgs84, Sgp4OpsMode.AFSPC); expect(satrec.xmcof).toEqual(-1.8859472970032445e-11); }); test('if other gravconst values cause an error', () => { - expect(() => Sgp4.createSatrec(line1, line2, 'wgs96', 'a')).toThrowError(new Error('unknown gravity option wgs96')); + expect(() => Sgp4.createSatrec(line1, line2, 'wgs96' as Sgp4GravConstants, Sgp4OpsMode.AFSPC)).toThrow( + new Error('unknown gravity option wgs96'), + ); }); }); describe('Verification of Fail Cases', () => { - sgp4FailData.forEach((sgp4DataItem) => { + sgp4FullCovFail.forEach((sgp4DataItem) => { // Fetching satellite record from TLE lines const satrec = Sgp4.createSatrec(sgp4DataItem.tleLine1, sgp4DataItem.tleLine2); @@ -88,95 +95,46 @@ describe('Test vector equations in SGP4', () => { }); }); -/* - * Describe('Test conversions in sgp4-utils', () => { - * test('If degreesLat is accurate', () => { - * expect(Sgp4Utils.degreesLat(0.5)).toEqual(28.64788975654116); - * }); - * test('If degreesLong is accurate', () => { - * expect(Sgp4Utils.degreesLong(0.5)).toEqual(28.64788975654116); - * }); - * test('If radiansLat is accurate', () => { - * expect(Sgp4Utils.radiansLat(45)).toEqual(0.7853981633974483); - * }); - * test('If radiansLong is accurate', () => { - * expect(Sgp4Utils.radiansLong(45)).toEqual(0.7853981633974483); - * }); - */ - -/* - * Test(`if sgp4-utils checks for errors`, () => { - * expect(() => Sgp4Utils.degreesLat(-100)).toThrowError( - * new RangeError('Latitude radians must be in range [-PI/2; PI/2].') - * ); - * expect(() => Sgp4Utils.degreesLat(100)).toThrowError( - * new RangeError('Latitude radians must be in range [-PI/2; PI/2].') - * ); - * expect(() => Sgp4Utils.degreesLong(-100)).toThrowError( - * new RangeError('Longitude radians must be in range [-PI; PI].') - * ); - * expect(() => Sgp4Utils.degreesLong(100)).toThrowError( - * new RangeError('Longitude radians must be in range [-PI; PI].') - * ); - */ - -/* - * Expect(() => Sgp4Utils.radiansLat(-100)).toThrowError( - * new RangeError('Latitude degrees must be in range [-90; 90].') - * ); - * expect(() => Sgp4Utils.radiansLat(100)).toThrowError( - * new RangeError('Latitude degrees must be in range [-90; 90].') - * ); - * expect(() => Sgp4Utils.radiansLong(-300)).toThrowError( - * new RangeError('Longitude degrees must be in range [-180; 180].') - * ); - * expect(() => Sgp4Utils.radiansLong(300)).toThrowError( - * new RangeError('Longitude degrees must be in range [-180; 180].') - * ); - * }); - * }); - */ - describe('Ensure bstar and ndot account for leading zeros', () => { test('if bstar reads in leading zero without exponent', () => { const line1 = '1 00005U 58002B 00179.78495062 .00000023 00000-0 00098-0 0 4753'; const line2 = '2 00005 34.2682 348.7242 1859667 331.7664 19.3264 10.82419157413667'; - const satrec = Sgp4.createSatrec(line1, line2, 'wgs72', 'i'); + const satrec = Sgp4.createSatrec(line1, line2, Sgp4GravConstants.wgs72, Sgp4OpsMode.IMPROVED); expect(satrec.bstar).toEqual(0.00098); }); test('if bstar reads in leading zero when doing exponents', () => { const line1 = '1 00005U 58002B 00179.78495062 .00000023 00000-0 00098-5 0 4753'; const line2 = '2 00005 34.2682 348.7242 1859667 331.7664 19.3264 10.82419157413667'; - const satrec = Sgp4.createSatrec(line1, line2, 'wgs72', 'i'); + const satrec = Sgp4.createSatrec(line1, line2, Sgp4GravConstants.wgs72, Sgp4OpsMode.IMPROVED); expect(satrec.bstar).toEqual(0.0000000098); }); test('if bstar reads in negative number', () => { const line1 = '1 00005U 58002B 00179.78495062 .00000023 00000-0 -00098-5 0 4753'; const line2 = '2 00005 34.2682 348.7242 1859667 331.7664 19.3264 10.82419157413667'; - const satrec = Sgp4.createSatrec(line1, line2, 'wgs72', 'i'); + const satrec = Sgp4.createSatrec(line1, line2, Sgp4GravConstants.wgs72, Sgp4OpsMode.IMPROVED); expect(satrec.bstar).toEqual(-0.0000000098); }); test('if ndot reads in leading zero', () => { const line1 = '1 00005U 58002B 00179.78495062 .10000000 00023-0 12398-0 0 4753'; const line2 = '2 00005 34.2682 348.7242 1859667 331.7664 19.3264 10.82419157413667'; - const satrec = Sgp4.createSatrec(line1, line2, 'wgs72', 'i'); + const satrec = Sgp4.createSatrec(line1, line2, Sgp4GravConstants.wgs72, Sgp4OpsMode.IMPROVED); expect(satrec.nddot).toEqual(0.00023); }); test('if ndot reads in leading zero and applies exponents', () => { const line1 = '1 00005U 58002B 00179.78495062 .10000000 00023-4 12398-0 0 4753'; const line2 = '2 00005 34.2682 348.7242 1859667 331.7664 19.3264 10.82419157413667'; - const satrec = Sgp4.createSatrec(line1, line2, 'wgs72', 'i'); + const satrec = Sgp4.createSatrec(line1, line2, Sgp4GravConstants.wgs72, Sgp4OpsMode.IMPROVED); expect(satrec.nddot).toEqual(0.000000023); }); test('if ndot reads in negative value with leading zeroes', () => { const line1 = '1 00005U 58002B 00179.78495062 -.10000000 -00023-0 12398-5 0 4753'; const line2 = '2 00005 34.2682 348.7242 1859667 331.7664 19.3264 10.82419157413667'; - const satrec = Sgp4.createSatrec(line1, line2, 'wgs72', 'i'); + const satrec = Sgp4.createSatrec(line1, line2, Sgp4GravConstants.wgs72, Sgp4OpsMode.IMPROVED); expect(satrec.nddot).toEqual(-0.00023); }); diff --git a/test/sgp4/sgp4-full-cov.ts b/test/sgp4/sgp4-full-cov.ts new file mode 100644 index 0000000..31ee123 --- /dev/null +++ b/test/sgp4/sgp4-full-cov.ts @@ -0,0 +1,82 @@ +export const sgp4FullCov = [ + { + description: 'Cover improved mode', + tleLine1: '1 25544U 98067A 21009.90234038 .00001675 00000-0 38183-4 0 9997', + tleLine2: '2 25544 51.6464 45.6388 0000512 205.3232 213.2158 15.49275327264062', + results: [ + { + time: 0.0, + position: { + x: -87.81891086100381, + y: 5051.02598276444, + z: 4539.258657271001, + }, + velocity: { + x: -6.343534031455946, + y: -2.9378975654843975, + z: 3.137917235399209, + }, + }, + ], + }, + { + description: 'Cover Alpha-5', + tleLine1: '1 A5544U 98067A 21009.90234038 .00001675 00000-0 38183-4 0 9997', + tleLine2: '2 A5544 51.6464 45.6388 0000512 205.3232 213.2158 15.49275327264062', + results: [ + { + time: 0.0, + position: { + x: -87.81891086100381, + y: 5051.02598276444, + z: 4539.258657271001, + }, + velocity: { + x: -6.343534031455946, + y: -2.9378975654843975, + z: 3.137917235399209, + }, + }, + ], + }, + { + description: 'Cover xinco = 180', + tleLine1: '1 B0000U 98067A 21009.90234038 .00001675 00000-0 38183-4 0 9997', + tleLine2: '2 B0000 180.0000 45.6388 0000512 205.3232 213.2158 15.49275327264062', + results: [ + { + time: 0.0, + position: { + x: 6622.655052157549, + y: -1516.4238662512882, + z: 7.094183623471915e-13, + }, + velocity: { + x: -1.7109990955273406, + y: -7.471458763296151, + z: 4.90442971002966e-16, + }, + }, + ], + }, + { + description: 'Use wgs72old', + tleLine1: '1 B0000U 98067A 21009.90234038 .00001675 00000-0 38183-4 0 9997', + tleLine2: '2 B0000 180.0000 45.6388 0000512 205.3232 213.2158 15.49275327264062', + results: [ + { + time: 0.0, + position: { + x: 6622.655052157549, + y: -1516.4238662512882, + z: 7.094183623471915e-13, + }, + velocity: { + x: -1.7109990955273406, + y: -7.471458763296151, + z: 4.90442971002966e-16, + }, + }, + ], + }, +]; diff --git a/test/tle/tle.test.ts b/test/tle/tle.test.ts index d0c4236..519d2e7 100644 --- a/test/tle/tle.test.ts +++ b/test/tle/tle.test.ts @@ -1,11 +1,4 @@ -/* eslint-disable max-lines-per-function */ -/** - * @file Test Suite to verify tle functions work as expected - * @author Theodore Kruczek. - * @since 1.1.0 - */ - -import { Tle } from '../../lib/index'; +import { Tle } from '../../src/index'; import { tleData } from './tleData'; describe('Valid TLEs', () => { diff --git a/test/tle/tleData.ts b/test/tle/tleData.ts index 8e1ccfd..9768e30 100644 --- a/test/tle/tleData.ts +++ b/test/tle/tleData.ts @@ -1,4 +1,4 @@ -import { TleLine1, TleLine2 } from 'lib/index'; +import { TleLine1, TleLine2 } from '../../src/index'; export const tleData = [ { diff --git a/test/transforms/transforms.test.ts b/test/transforms/transforms.test.ts index 89bd2a3..1890428 100644 --- a/test/transforms/transforms.test.ts +++ b/test/transforms/transforms.test.ts @@ -12,7 +12,7 @@ import { lla2ecf, rae2ecf, rae2sez, -} from '../../lib/index'; +} from '../../src/index'; import { transformsData } from './transformsData'; const numDigits = 6; diff --git a/test/transforms/transformsData.ts b/test/transforms/transformsData.ts index 8cbaa12..8dad4fe 100644 --- a/test/transforms/transformsData.ts +++ b/test/transforms/transformsData.ts @@ -1,4 +1,4 @@ -import { Degrees, EcfVec3, EciVec3, Kilometers, RAD2DEG, Radians } from '../../lib/index'; +import { Degrees, EcfVec3, EciVec3, Kilometers, RAD2DEG, Radians } from '../../src/index'; export const transformsData = { validLatitudes: [ diff --git a/test/utils/utils.test.ts b/test/utils/utils.test.ts index d9a513c..80daaec 100644 --- a/test/utils/utils.test.ts +++ b/test/utils/utils.test.ts @@ -1,10 +1,5 @@ -/** - * @file Tests from Utils Module to ensure compatibility - * @since 1.0.0-alpha3 - */ - -import { EciVec3, Kilometers, linearDistance, Vec3 } from '../../lib/index'; // eslint-disable-line -import { dopplerFactor, getDayOfYear } from '../../lib/utils/functions'; +import { EciVec3, Kilometers, linearDistance, Vec3 } from '../../src/index'; +import { dopplerFactor, getDayOfYear } from '../../src/utils/functions'; const numDigits = 8;