Skip to content

Commit

Permalink
test: ✅ add more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
thkruz committed Jan 15, 2024
1 parent 60c39de commit b804ded
Show file tree
Hide file tree
Showing 24 changed files with 1,024 additions and 47 deletions.
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
"no-extra-label": "error",
"no-extra-parens": "off",
"no-floating-decimal": "error",
"no-implicit-coercion": "error",
"no-implicit-coercion": "off",
"no-implicit-globals": "error",
"no-implied-eval": "error",
"no-inline-comments": "off",
Expand Down
11 changes: 6 additions & 5 deletions src/observation/RAE.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ import { angularDistance } from '../utils/functions';

// / Range, azimuth, and elevation.
export class RAE {
// / Create a new [Razel] object.
constructor(
public epoch: EpochUTC,
public range: Kilometers,
Expand Down Expand Up @@ -88,7 +87,7 @@ export class RAE {
* @param site The observer [site] vector.
* @returns A new [Razel] object.
*/
static fromStateVectors(state: J2000, site: J2000): RAE {
static fromStateVector(state: J2000, site: J2000): RAE {
const stateEcef = state.toITRF();
const siteEcef = site.toITRF();
const po2 = halfPi;
Expand Down Expand Up @@ -199,9 +198,11 @@ export class RAE {
* @returns A [J2000] state vector.
*/
toStateVector(site: J2000): J2000 {
if (!this.rangeRate || !this.elevationRate || !this.azimuthRate) {
throw new Error('Cannot create state, required values are undefined.');
}
// If the rates are not defined then assume stationary
this.rangeRate ??= 0;
this.elevationRate ??= 0;
this.azimuthRate ??= 0;

const ecef = site.toITRF();
const geo = ecef.toGeodetic();
const po2 = halfPi;
Expand Down
49 changes: 25 additions & 24 deletions src/observation/RadecGeocentric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
*/

/* eslint-disable no-undefined */
import { Degrees, Kilometers, Radians } from 'src/main';
import { J2000 } from '../coordinate/J2000';
import { AngularDistanceMethod } from '../enums/AngularDistanceMethod';
import { Vector3D } from '../operations/Vector3D';
Expand All @@ -35,11 +36,11 @@ export class RadecGeocentric {
// / Create a new [RadecGeocentric] object.
constructor(
public epoch: EpochUTC,
public rightAscension: number,
public declination: number,
public range?: number,
public rightAscensionRate?: number,
public declinationRate?: number,
public rightAscension: Radians,
public declination: Radians,
public range?: Kilometers,
public rightAscensionRate?: Radians,
public declinationRate?: Radians,
public rangeRate?: number,
) {
// Nothing to do here.
Expand All @@ -49,33 +50,33 @@ export class RadecGeocentric {
* Create a new [RadecGeocentric] object, using degrees for the
* angular values.
* @param epoch UTC epoch.
* @param rightAscensionDegrees Right-ascension _(°)_.
* @param declinationDegrees Declination _(°)_.
* @param range Range _(km)_.
* @param rightAscensionRateDegrees Right-ascension rate _(°/s)_.
* @param declinationRateDegrees Declination rate _(°/s)_.
* @param rangeRate Range rate _(km/s)_.
* @param rightAscensionDegrees Right-ascension
* @param declinationDegrees Declination
* @param range Range
* @param rightAscensionRateDegrees Right-ascension rate (°/s).
* @param declinationRateDegrees Declination rate (°/s).
* @param rangeRate Range rate (km/s).
* @returns A new [RadecGeocentric] object.
*/
static fromDegrees(
epoch: EpochUTC,
rightAscensionDegrees: number,
declinationDegrees: number,
range?: number,
rightAscensionRateDegrees?: number,
declinationRateDegrees?: number,
rightAscensionDegrees: Degrees,
declinationDegrees: Degrees,
range?: Kilometers,
rightAscensionRateDegrees?: Degrees,
declinationRateDegrees?: Degrees,
rangeRate?: number,
): RadecGeocentric {
const rightAscensionRate = rightAscensionRateDegrees && rightAscensionRateDegrees * DEG2RAD;
const declinationRate = declinationRateDegrees && declinationRateDegrees * DEG2RAD;

return new RadecGeocentric(
epoch,
rightAscensionDegrees * DEG2RAD,
declinationDegrees * DEG2RAD,
rightAscensionDegrees * DEG2RAD as Radians,
declinationDegrees * DEG2RAD as Radians,
range,
rightAscensionRate,
declinationRate,
rightAscensionRate as Radians,
declinationRate as Radians,
rangeRate,
);
}
Expand Down Expand Up @@ -104,11 +105,11 @@ export class RadecGeocentric {

return new RadecGeocentric(
state.epoch,
rightAscension % TAU,
declination,
rightAscension % TAU as Radians,
declination as Radians,
rMag,
rightAscensionRate,
declinationRate,
rightAscensionRate as Radians,
declinationRate as Radians,
rangeRate,
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/observation/RadecTopocentric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export class RadecTopocentric {
* @param site Site vector.
* @returns A new [RadecTopocentric] object.
*/
static fromStateVectors(state: J2000, site: J2000): RadecTopocentric {
static fromStateVector(state: J2000, site: J2000): RadecTopocentric {
const p = state.position.subtract(site.position);
const pI = p.x;
const pJ = p.y;
Expand Down
5 changes: 0 additions & 5 deletions src/time/Comparable.ts

This file was deleted.

12 changes: 4 additions & 8 deletions src/time/Epoch.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Seconds } from 'src/main';
import { secondsPerDay } from '../utils/constants';
import { Comparable } from './Comparable';

// / Base class for [Epoch] data.
export class Epoch implements Comparable {
export class Epoch {
/*
* Create a new [Epoch] object given the number of seconds elapsed since the
* [posix] epoch _(`1970-01-01T00:00:00.000`)_ in the [Epoch] time scale.
Expand All @@ -23,8 +23,8 @@ export class Epoch implements Comparable {
}

// / Return the difference _(s)_ between this and another [epoch]/
difference(epoch: Epoch): number {
return this.posix - epoch.posix;
difference(epoch: Epoch): Seconds {
return this.posix - epoch.posix as Seconds;
}

// / Check if this has the same timestamp as the provided [epoch].
Expand Down Expand Up @@ -83,10 +83,6 @@ export class Epoch implements Comparable {
return (this.toJulianDate() - 2451545) / 36525;
}

compareTo(other: Epoch): number {
return this.posix - other.posix;
}

// / Check if this is later than the [other] epoch.
operatorGreaterThan(other: Epoch): boolean {
return this.posix > other.posix;
Expand Down
3 changes: 2 additions & 1 deletion src/time/EpochGPS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export class EpochGPS {
* of [seconds] into the [week].
* @param week Number of weeks since the GPS reference epoch.
* @param seconds Number of seconds into the week.
* @param reference Reference epoch.
* @param reference Reference should always be EpochUTC.fromDateTimeString('1980-01-06T00:00:00.000Z').
*/
constructor(public week: number, public seconds: number, reference: EpochUTC) {
if (week < 0) {
Expand All @@ -18,6 +18,7 @@ export class EpochGPS {
throw new Error('GPS seconds must be within a week.');
}

// TODO: #9 Set EpochGPS.reference statically without circular dependency.

Check warning on line 21 in src/time/EpochGPS.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected 'todo' comment: 'TODO: #9 Set EpochGPS.reference...'
EpochGPS.reference = reference;
}

Expand Down
5 changes: 3 additions & 2 deletions src/time/EpochUTC.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,14 @@ export class EpochUTC extends Epoch {
}

toGPS(): EpochGPS {
const referenceTime = EpochUTC.fromDateTimeString('1980-01-06T00:00:00.000Z');
const ls = DataHandler.getInstance().getLeapSeconds(this.toJulianDate());
const delta = this.roll(ls - EpochGPS.offset).difference(EpochGPS.reference);
const delta = this.roll(ls - EpochGPS.offset).difference(referenceTime);
const week = delta / secondsPerWeek;
const weekFloor = Math.floor(week);
const seconds = (week - weekFloor) * secondsPerWeek;

return new EpochGPS(weekFloor, seconds, EpochUTC.fromDateTimeString('1980-01-06T00:00:00.000Z'));
return new EpochGPS(weekFloor, seconds, referenceTime);
}

gmstAngle(): number {
Expand Down
1 change: 1 addition & 0 deletions src/time/TimeStamped.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { EpochUTC } from './EpochUTC';

/**
* Time stamped value container.
* TODO: #10 Is TimeStamped class needed?
*/
export class TimeStamped<T> {
/**
Expand Down
134 changes: 134 additions & 0 deletions test/observation/RAE.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import {
AngularDistanceMethod,
DEG2RAD,
Degrees,
EpochUTC,
J2000,
Kilometers,
RAE,
Radians,
Vector3D,
} from '../../src/main';

describe('RAE', () => {
let exampleDate: Date;
let rae: RAE;

beforeEach(() => {
exampleDate = new Date(1705109326817);
rae = new RAE(
EpochUTC.fromDateTime(exampleDate),
1000 as Kilometers,
10 * DEG2RAD as Radians,
20 * DEG2RAD as Radians,
);
});

it('should be constructable', () => {
expect(rae).toMatchSnapshot();
});

it('should be constructable from degrees', () => {
const raeDeg = RAE.fromDegrees(
EpochUTC.fromDateTime(exampleDate),
1000 as Kilometers,
10 as Degrees,
20 as Degrees,
);

expect(raeDeg).toMatchSnapshot();
expect(raeDeg).toMatchObject(rae);
});

// azimuthDegrees
it('should return the azimuth in degrees', () => {
expect(rae.azimuthDegrees).toMatchSnapshot();
});

// elevationDegrees
it('should return the elevation in degrees', () => {
expect(rae.elevationDegrees).toMatchSnapshot();
});

// azimuthRateDegrees
it('should return the azimuth rate in degrees', () => {
expect(rae.azimuthRateDegrees).toMatchSnapshot();
});

// elevationRateDegrees
it('should return the elevation rate in degrees', () => {
expect(rae.elevationRateDegrees).toMatchSnapshot();
});

// toString
it('should return a string representation', () => {
expect(rae.toString()).toMatchSnapshot();
});

// fromStateVector
it('should return a RAE object from a state vector', () => {
const state = new J2000(
EpochUTC.fromDateTime(exampleDate),
new Vector3D<Kilometers>(7000 as Kilometers, 7000 as Kilometers, 8000 as Kilometers),
new Vector3D<Kilometers>(0 as Kilometers, 0 as Kilometers, 0 as Kilometers),
);
const site = new J2000(
EpochUTC.fromDateTime(exampleDate),
new Vector3D<Kilometers>(6000 as Kilometers, 7000 as Kilometers, 8000 as Kilometers),
new Vector3D<Kilometers>(0 as Kilometers, 0 as Kilometers, 0 as Kilometers),
);

const rae = RAE.fromStateVector(state, site);

expect(rae).toMatchSnapshot();
});

// toStateVector
it('should return a state vector', () => {
const site = new J2000(
EpochUTC.fromDateTime(exampleDate),
new Vector3D<Kilometers>(6000 as Kilometers, 7000 as Kilometers, 8000 as Kilometers),
new Vector3D<Kilometers>(0 as Kilometers, 0 as Kilometers, 0 as Kilometers),
);

expect(rae.toStateVector(site)).toMatchSnapshot();
});

// position
it('should return the position vector', () => {
const site = new J2000(
EpochUTC.fromDateTime(exampleDate),
new Vector3D<Kilometers>(6000 as Kilometers, 7000 as Kilometers, 8000 as Kilometers),
new Vector3D<Kilometers>(0 as Kilometers, 0 as Kilometers, 0 as Kilometers),
);

expect(rae.position(site)).toMatchSnapshot();
});

// angle
it('should return the angle', () => {
const rae2 = new RAE(
EpochUTC.fromDateTime(exampleDate),
1000 as Kilometers,
15 * DEG2RAD as Radians,
25 * DEG2RAD as Radians,
);

expect(rae.angle(rae2)).toMatchSnapshot();
expect(rae.angle(rae2, AngularDistanceMethod.Haversine)).toMatchSnapshot();
expect(rae.angle(rae2, AngularDistanceMethod.Haversine))
.not.toEqual(rae.angle(rae2, AngularDistanceMethod.Cosine));
});

// angleDegrees
it('should return the angle in degrees', () => {
const rae2 = new RAE(
EpochUTC.fromDateTime(exampleDate),
1000 as Kilometers,
15 * DEG2RAD as Radians,
25 * DEG2RAD as Radians,
);

expect(rae.angleDegrees(rae2)).toMatchSnapshot();
});
});
Loading

0 comments on commit b804ded

Please sign in to comment.