From 4dab5d0c1a6393c82dbabb9e76ffea0ec982b4ff Mon Sep 17 00:00:00 2001 From: qntm Date: Sat, 20 Jul 2024 02:06:21 +0100 Subject: [PATCH] Adjust Second constructor --- src/munge.js | 10 +- src/rat.js | 2 +- src/second.js | 18 +- test/converter.spec.js | 25 +-- test/exact.spec.js | 57 +++--- test/munge.spec.js | 452 ++++++++++++++++++++--------------------- test/second.spec.js | 55 ++--- test/segment.spec.js | 6 +- 8 files changed, 306 insertions(+), 319 deletions(-) diff --git a/src/munge.js b/src/munge.js index 80176b0..de13cb7 100644 --- a/src/munge.js +++ b/src/munge.js @@ -34,7 +34,7 @@ export const MODELS = { } const NOV = 10 -const secondsPerDay = new Second(86_400n, 1n) +const secondsPerDay = new Second(new Rat(86_400n, 1n)) const mjdEpoch = { unix: Second.fromMillis(Date.UTC(1858, NOV, 17)) } @@ -63,20 +63,20 @@ export const munge = (data, model) => { // Convert from a floating point number to a precise ratio // Offsets are given in TAI seconds to seven decimal places, e.g. `1.422_818_0`. // So we have to do some rounding - offsetAtRoot.atomic = new Second( + offsetAtRoot.atomic = new Second(new Rat( BigInt(Math.round(offsetAtRoot.atomicFloat * 10_000_000)), BigInt(10_000_000) - ) + )) root.unix = mjdEpoch.unix.plusS(secondsPerDay.timesR(new Rat(BigInt(root.mjds)))) // Convert from a floating point number to a precise ratio // Drift rates are given in TAI seconds to seven decimal places, e.g. `0.001_123_2` // So we have to do some rounding - driftRate.atomicPerUnixDay = new Second( + driftRate.atomicPerUnixDay = new Second(new Rat( BigInt(Math.round(driftRate.atomicPerUnixDayFloat * 10_000_000)), BigInt(10_000_000) - ) + )) driftRate.atomicPerUnix = driftRate.atomicPerUnixDay.divideS(secondsPerDay) const slope = {} diff --git a/src/rat.js b/src/rat.js index b561742..0df865d 100644 --- a/src/rat.js +++ b/src/rat.js @@ -17,7 +17,7 @@ export class Rat { const g2 = (de < 0) === (g < 0) ? g : -g this.nu = nu / g2 // sign of `this.nu` is the sign of the represented rational - this.de = de / g2 // non-negative + this.de = de / g2 // positive } plus (other) { diff --git a/src/second.js b/src/second.js index 8c17fe3..49e2e3d 100644 --- a/src/second.js +++ b/src/second.js @@ -1,28 +1,24 @@ import { Rat } from './rat.js' export class Second { - constructor (nu, de) { - this.rat = new Rat(nu, de) + constructor (rat) { + this.rat = rat } plusS (other) { - const sum = this.rat.plus(other.rat) - return new Second(sum.nu, sum.de) + return new Second(this.rat.plus(other.rat)) } minusS (other) { - const difference = this.rat.minus(other.rat) - return new Second(difference.nu, difference.de) + return new Second(this.rat.minus(other.rat)) } timesR (other) { - const product = this.rat.times(other) - return new Second(product.nu, product.de) + return new Second(this.rat.times(other)) } divideR (other) { - const quotient = this.rat.divide(other) - return new Second(quotient.nu, quotient.de) + return new Second(this.rat.divide(other)) } divideS (other) { @@ -51,7 +47,7 @@ Second.fromMillis = millis => { throw Error(`Not an integer: ${millis}`) } - return new Second(BigInt(millis), 1_000n) + return new Second(new Rat(BigInt(millis), 1_000n)) } Second.END_OF_TIME = Symbol('end of time') diff --git a/test/converter.spec.js b/test/converter.spec.js index d035878..a9dfac8 100644 --- a/test/converter.spec.js +++ b/test/converter.spec.js @@ -3,6 +3,7 @@ import { describe, it } from 'mocha' import { Converter } from '../src/converter.js' import { MODELS } from '../src/munge.js' import { Range } from '../src/range.js' +import { Rat } from '../src/rat.js' import { Second } from '../src/second.js' const JAN = 0 @@ -267,7 +268,7 @@ describe('Converter', () => { ]) assert.deepStrictEqual(converter.unixToAtomic(Second.fromMillis(Date.UTC(1979, DEC, 31, 12, 0, 0, 1))), [ - new Range(Second.fromMillis(Date.UTC(1979, DEC, 31, 12, 0, 0, 1)).plusS(new Second(1n, 86_400_000n))) + new Range(Second.fromMillis(Date.UTC(1979, DEC, 31, 12, 0, 0, 1)).plusS(new Second(new Rat(1n, 86_400_000n)))) ]) // SMEAR MIDPOINT @@ -279,7 +280,7 @@ describe('Converter', () => { // SMEAR ENDS, ATOMIC IS A FULL SECOND AHEAD (actually Unix is a full second behind) assert.deepStrictEqual(converter.unixToAtomic(Second.fromMillis(Date.UTC(1980, JAN, 1, 11, 59, 59, 999))), [ - new Range(Second.fromMillis(Date.UTC(1980, JAN, 1, 11, 59, 59, 999)).plusS(new Second(86_399_999n, 86_400_000n))) + new Range(Second.fromMillis(Date.UTC(1980, JAN, 1, 11, 59, 59, 999)).plusS(new Second(new Rat(86_399_999n, 86_400_000n)))) ]) assert.deepStrictEqual(converter.unixToAtomic(Second.fromMillis(Date.UTC(1980, JAN, 1, 12, 0, 0, 0))), [ @@ -301,7 +302,7 @@ describe('Converter', () => { assert.deepStrictEqual(converter.atomicToUnix(Second.fromMillis(Date.UTC(1979, DEC, 31, 12, 0, 0, 0))), Second.fromMillis(Date.UTC(1979, DEC, 31, 12, 0, 0, 0))) assert.deepStrictEqual(converter.atomicToUnix(Second.fromMillis(Date.UTC(1979, DEC, 31, 12, 0, 0, 1))), - Second.fromMillis(Date.UTC(1979, DEC, 31, 12, 0, 0, 1)).minusS(new Second(1n, 86_401_000n))) + Second.fromMillis(Date.UTC(1979, DEC, 31, 12, 0, 0, 1)).minusS(new Second(new Rat(1n, 86_401_000n)))) // SMEAR MIDPOINT assert.deepStrictEqual(converter.atomicToUnix(Second.fromMillis(Date.UTC(1980, JAN, 1, 0, 0, 0, 500))), @@ -309,7 +310,7 @@ describe('Converter', () => { // SMEAR ENDS, UNIX HAS DROPPED A FULL SECOND BEHIND assert.deepStrictEqual(converter.atomicToUnix(Second.fromMillis(Date.UTC(1980, JAN, 1, 12, 0, 0, 999))), - Second.fromMillis(Date.UTC(1980, JAN, 1, 12, 0, 0, 999)).minusS(new Second(86_400_999n, 86_401_000n))) + Second.fromMillis(Date.UTC(1980, JAN, 1, 12, 0, 0, 999)).minusS(new Second(new Rat(86_400_999n, 86_401_000n)))) assert.deepStrictEqual(converter.atomicToUnix(Second.fromMillis(Date.UTC(1980, JAN, 1, 12, 0, 1, 0))), Second.fromMillis(Date.UTC(1980, JAN, 1, 12, 0, 0, 0))) assert.deepStrictEqual(converter.atomicToUnix(Second.fromMillis(Date.UTC(1980, JAN, 1, 12, 0, 1, 1))), @@ -482,7 +483,7 @@ describe('Converter', () => { ]) assert.deepStrictEqual(converter.unixToAtomic(Second.fromMillis(Date.UTC(1979, DEC, 31, 12, 0, 0, 1))), [ - new Range(Second.fromMillis(Date.UTC(1979, DEC, 31, 12, 0, 0, 1)).minusS(new Second(1n, 86_400_000n))) + new Range(Second.fromMillis(Date.UTC(1979, DEC, 31, 12, 0, 0, 1)).minusS(new Second(new Rat(1n, 86_400_000n)))) ]) // SMEAR MIDPOINT @@ -494,7 +495,7 @@ describe('Converter', () => { // SMEAR ENDS, ATOMIC IS A FULL SECOND BEHIND (actually Unix is a full second ahead) assert.deepStrictEqual(converter.unixToAtomic(Second.fromMillis(Date.UTC(1980, JAN, 1, 11, 59, 59, 999))), [ - new Range(Second.fromMillis(Date.UTC(1980, JAN, 1, 11, 59, 59, 999)).minusS(new Second(86_399_999n, 86_400_000n))) + new Range(Second.fromMillis(Date.UTC(1980, JAN, 1, 11, 59, 59, 999)).minusS(new Second(new Rat(86_399_999n, 86_400_000n)))) ]) assert.deepStrictEqual(converter.unixToAtomic(Second.fromMillis(Date.UTC(1980, JAN, 1, 12, 0, 0, 0))), [ @@ -516,7 +517,7 @@ describe('Converter', () => { assert.deepStrictEqual(converter.atomicToUnix(Second.fromMillis(Date.UTC(1979, DEC, 31, 12, 0, 0, 0))), Second.fromMillis(Date.UTC(1979, DEC, 31, 12, 0, 0, 0))) assert.deepStrictEqual(converter.atomicToUnix(Second.fromMillis(Date.UTC(1979, DEC, 31, 12, 0, 0, 1))), - Second.fromMillis(Date.UTC(1979, DEC, 31, 12, 0, 0, 1)).plusS(new Second(1n, 86_399_000n))) + Second.fromMillis(Date.UTC(1979, DEC, 31, 12, 0, 0, 1)).plusS(new Second(new Rat(1n, 86_399_000n)))) // SMEAR MIDPOINT assert.deepStrictEqual(converter.atomicToUnix(Second.fromMillis(Date.UTC(1979, DEC, 31, 23, 59, 59, 500))), @@ -524,7 +525,7 @@ describe('Converter', () => { // SMEAR ENDS, UNIX HAS RUN A FULL SECOND FASTER THAN ATOMIC assert.deepStrictEqual(converter.atomicToUnix(Second.fromMillis(Date.UTC(1980, JAN, 1, 11, 59, 58, 999))), - Second.fromMillis(Date.UTC(1980, JAN, 1, 11, 59, 58, 999)).plusS(new Second(86_398_999n, 86_399_000n))) + Second.fromMillis(Date.UTC(1980, JAN, 1, 11, 59, 58, 999)).plusS(new Second(new Rat(86_398_999n, 86_399_000n)))) assert.deepStrictEqual(converter.atomicToUnix(Second.fromMillis(Date.UTC(1980, JAN, 1, 11, 59, 59, 0))), Second.fromMillis(Date.UTC(1980, JAN, 1, 12, 0, 0, 0))) assert.deepStrictEqual(converter.atomicToUnix(Second.fromMillis(Date.UTC(1980, JAN, 1, 11, 59, 59, 1))), @@ -543,9 +544,9 @@ describe('Converter', () => { assert.deepStrictEqual(converter.unixToAtomic(Second.fromMillis(1)), [ - new Range(new Second(900n, 1_000_000n)) + new Range(new Second(new Rat(900n, 1_000_000n))) ]) - assert.deepStrictEqual(converter.atomicToUnix(new Second(900n, 1_000_000n)), + assert.deepStrictEqual(converter.atomicToUnix(new Second(new Rat(900n, 1_000_000n))), Second.fromMillis(1)) }) @@ -558,9 +559,9 @@ describe('Converter', () => { assert.deepStrictEqual(converter.unixToAtomic(Second.fromMillis(-1)), [ - new Range(new Second(-900n, 1_000_000n)) + new Range(new Second(new Rat(-900n, 1_000_000n))) ]) - assert.deepStrictEqual(converter.atomicToUnix(new Second(-900n, 1_000_000n)), + assert.deepStrictEqual(converter.atomicToUnix(new Second(new Rat(-900n, 1_000_000n))), Second.fromMillis(-1)) }) }) diff --git a/test/exact.spec.js b/test/exact.spec.js index 0b06c64..504cb65 100644 --- a/test/exact.spec.js +++ b/test/exact.spec.js @@ -2,6 +2,7 @@ import assert from 'node:assert' import { describe, it } from 'mocha' import { TaiConverter, Second, MODELS, UNIX_START, UNIX_END } from '../src/exact.js' import { Range } from '../src/range.js' +import { Rat } from '../src/rat.js' const JAN = 0 const FEB = 1 @@ -48,51 +49,51 @@ describe('TaiConverter', () => { // 00:00:01.422_818 is in range, but rounds down to 00:00:01.422 which is not assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(1961, JAN, 1, 0, 0, 0, 0))), [ - new Range(Second.fromMillis(Date.UTC(1961, JAN, 1, 0, 0, 1, 422)).plusS(new Second(818_000_000n, 1_000_000_000_000n))) + new Range(Second.fromMillis(Date.UTC(1961, JAN, 1, 0, 0, 1, 422)).plusS(new Second(new Rat(818_000_000n, 1_000_000_000_000n)))) ]) }) it('advances 15 TAI picoseconds per Unix millisecond', () => { assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(1961, JAN, 1, 0, 0, 0, 1))), [ - new Range(Second.fromMillis(Date.UTC(1961, JAN, 1, 0, 0, 1, 423)).plusS(new Second(818_000_015n, 1_000_000_000_000n))) + new Range(Second.fromMillis(Date.UTC(1961, JAN, 1, 0, 0, 1, 423)).plusS(new Second(new Rat(818_000_015n, 1_000_000_000_000n)))) ]) assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(1961, JAN, 1, 0, 0, 0, 2))), [ - new Range(Second.fromMillis(Date.UTC(1961, JAN, 1, 0, 0, 1, 424)).plusS(new Second(818_000_030n, 1_000_000_000_000n))) + new Range(Second.fromMillis(Date.UTC(1961, JAN, 1, 0, 0, 1, 424)).plusS(new Second(new Rat(818_000_030n, 1_000_000_000_000n)))) ]) assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(1961, JAN, 1, 0, 0, 0, 3))), [ - new Range(Second.fromMillis(Date.UTC(1961, JAN, 1, 0, 0, 1, 425)).plusS(new Second(818_000_045n, 1_000_000_000_000n))) + new Range(Second.fromMillis(Date.UTC(1961, JAN, 1, 0, 0, 1, 425)).plusS(new Second(new Rat(818_000_045n, 1_000_000_000_000n)))) ]) }) it('advances 0.001_296 TAI seconds per Unix day', () => { assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(1961, JAN, 2, 0, 0, 0, 0))), [ - new Range(Second.fromMillis(Date.UTC(1961, JAN, 2, 0, 0, 1, 424)).plusS(new Second(114n, 1_000_000n))) + new Range(Second.fromMillis(Date.UTC(1961, JAN, 2, 0, 0, 1, 424)).plusS(new Second(new Rat(114n, 1_000_000n)))) ]) }) it('makes certain TAI millisecond counts inaccessible', () => { assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(-283_984_666_668)), [ - new Range(new Second(-283_984_665_245_000_000_020n, 1_000_000_000_000n)) + new Range(new Second(new Rat(-283_984_665_245_000_000_020n, 1_000_000_000_000n))) ]) assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(-283_984_666_667)), [ - new Range(new Second(-283_984_665_244_000_000_005n, 1_000_000_000_000n)) + new Range(new Second(new Rat(-283_984_665_244_000_000_005n, 1_000_000_000_000n))) ]) // it's not possible to get a result of -283_984_665_244_XXX_XXX_XXXn assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(-283_984_666_666)), [ - new Range(new Second(-283_984_665_242_999_999_990n, 1_000_000_000_000n)) + new Range(new Second(new Rat(-283_984_665_242_999_999_990n, 1_000_000_000_000n))) ]) assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(-283_984_666_665)), [ - new Range(new Second(-283_984_665_241_999_999_975n, 1_000_000_000_000n)) + new Range(new Second(new Rat(-283_984_665_241_999_999_975n, 1_000_000_000_000n))) ]) }) }) @@ -103,7 +104,7 @@ describe('TaiConverter', () => { NaN) // Actual start of TAI: 1961-01-01 00:00:01.422_818 - assert.deepStrictEqual(taiConverter.atomicToUnix(Second.fromMillis(Date.UTC(1961, JAN, 1, 0, 0, 1, 422)).plusS(new Second(818n, 1_000_000n))), + assert.deepStrictEqual(taiConverter.atomicToUnix(Second.fromMillis(Date.UTC(1961, JAN, 1, 0, 0, 1, 422)).plusS(new Second(new Rat(818n, 1_000_000n)))), Second.fromMillis(Date.UTC(1961, JAN, 1, 0, 0, 0, 0))) }) @@ -143,7 +144,7 @@ describe('TaiConverter', () => { // Fun fact! There is about 105 leap milliseconds here! assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(1972, JAN, 1, 0, 0, 0, 0))), [ - new Range(Second.fromMillis(Date.UTC(1972, JAN, 1, 0, 0, 9, 892)).plusS(new Second(242n, 1_000_000n))), + new Range(Second.fromMillis(Date.UTC(1972, JAN, 1, 0, 0, 9, 892)).plusS(new Second(new Rat(242n, 1_000_000n)))), new Range(Second.fromMillis(Date.UTC(1972, JAN, 1, 0, 0, 10, 0))) ]) }) @@ -188,15 +189,15 @@ describe('TaiConverter', () => { // TAI picosecond count rounds to -252_460_798_155 which is not in range assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(1961, DEC, 31, 23, 59, 59, 999))), [ - new Range(new Second(-252_460_798_155_142_000_015n, 1_000_000_000_000n)) + new Range(new Second(new Rat(-252_460_798_155_142_000_015n, 1_000_000_000_000n))) ]) assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(1962, JAN, 1, 0, 0, 0, 0))), [ - new Range(new Second(-252_460_798_154_142_000_000n, 1_000_000_000_000n)) + new Range(new Second(new Rat(-252_460_798_154_142_000_000n, 1_000_000_000_000n))) ]) assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(1962, JAN, 1, 0, 0, 0, 1))), [ - new Range(new Second(-252_460_798_153_141_999_987n, 1_000_000_000_000n)) + new Range(new Second(new Rat(-252_460_798_153_141_999_987n, 1_000_000_000_000n))) ]) }) @@ -205,8 +206,8 @@ describe('TaiConverter', () => { // The period between 1965-09-01 00:00:00 and 00:00:00.100 UTC happened twice! assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(1965, SEP, 1, 0, 0, 0, 50))), [ - new Range(new Second(-136_771_195_894_941_999_250n, 1_000_000_000_000n)), - new Range(new Second(-136_771_195_794_941_999_250n, 1_000_000_000_000n)) + new Range(new Second(new Rat(-136_771_195_894_941_999_250n, 1_000_000_000_000n))), + new Range(new Second(new Rat(-136_771_195_794_941_999_250n, 1_000_000_000_000n))) ]) }) @@ -216,11 +217,11 @@ describe('TaiConverter', () => { // Which means that 23:59:59.950 UTC *does* actually exist... assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(1961, JUL, 31, 23, 59, 59, 949))), [ - new Range(new Second(-265_679_998_353_430_000_765n, 1_000_000_000_000n)) + new Range(new Second(new Rat(-265_679_998_353_430_000_765n, 1_000_000_000_000n))) ]) assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(1961, JUL, 31, 23, 59, 59, 950))), [ - new Range(new Second(-265_679_998_352_430_000_750n, 1_000_000_000_000n)) + new Range(new Second(new Rat(-265_679_998_352_430_000_750n, 1_000_000_000_000n))) ]) assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(1961, JUL, 31, 23, 59, 59, 951))), []) @@ -229,11 +230,11 @@ describe('TaiConverter', () => { []) assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(1961, AUG, 1, 0, 0, 0, 0))), [ - new Range(new Second(-265_679_998_352_430_000_000n, 1_000_000_000_000n)) + new Range(new Second(new Rat(-265_679_998_352_430_000_000n, 1_000_000_000_000n))) ]) assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(1961, AUG, 1, 0, 0, 0, 1))), [ - new Range(new Second(-265_679_998_351_429_999_985n, 1_000_000_000_000n)) + new Range(new Second(new Rat(-265_679_998_351_429_999_985n, 1_000_000_000_000n))) ]) }) @@ -290,7 +291,7 @@ describe('TaiConverter', () => { 1) assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(1968, JAN, 31, 23, 59, 59, 900))), [ - new Range(new Second(-60_479_993_814_318_003n, 1_000_000_000n)) + new Range(new Second(new Rat(-60_479_993_814_318_003n, 1_000_000_000n))) ]) assert.strictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(1968, JAN, 31, 23, 59, 59, 901))).length, @@ -471,7 +472,7 @@ describe('TaiConverter', () => { describe('atomicToUnix', () => { it('The NEW earliest instant in TAI', () => { // Actual start of TAI: 1961-01-01 00:00:01.422_818 - assert.deepStrictEqual(taiConverter.atomicToUnix(Second.fromMillis(Date.UTC(1961, JAN, 1, 0, 0, 1, 422)).plusS(new Second(818n, 1_000_000n))), + assert.deepStrictEqual(taiConverter.atomicToUnix(Second.fromMillis(Date.UTC(1961, JAN, 1, 0, 0, 1, 422)).plusS(new Second(new Rat(818n, 1_000_000n)))), Second.fromMillis(Date.UTC(1961, JAN, 1, 0, 0, 0, 0))) }) @@ -482,7 +483,7 @@ describe('TaiConverter', () => { it('0.107_758 seconds added, start of 1972', () => { // stall begins at 1972-01-01 00:00:09.892_242 TAI - assert.deepStrictEqual(taiConverter.atomicToUnix(Second.fromMillis(Date.UTC(1972, JAN, 1, 0, 0, 9, 892)).plusS(new Second(242n, 1_000_000n))), + assert.deepStrictEqual(taiConverter.atomicToUnix(Second.fromMillis(Date.UTC(1972, JAN, 1, 0, 0, 9, 892)).plusS(new Second(new Rat(242n, 1_000_000n)))), Second.fromMillis(Date.UTC(1972, JAN, 1, 0, 0, 0, 0))) assert.deepStrictEqual(taiConverter.atomicToUnix(Second.fromMillis(Date.UTC(1972, JAN, 1, 0, 0, 9, 893))), Second.fromMillis(Date.UTC(1972, JAN, 1, 0, 0, 0, 0))) @@ -547,11 +548,11 @@ describe('TaiConverter', () => { // Exact picosecond ratios assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(1962, JAN, 1, 0, 0, 0, 0))), [ - new Range(new Second(-252_460_798_154_142_000_000n, 1_000_000_000_000n)) + new Range(new Second(new Rat(-252_460_798_154_142_000_000n, 1_000_000_000_000n))) ]) assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(1962, JAN, 1, 0, 0, 0, 1))), [ - new Range(new Second(-252_460_798_153_141_999_987n, 1_000_000_000_000n)) + new Range(new Second(new Rat(-252_460_798_153_141_999_987n, 1_000_000_000_000n))) ]) }) @@ -706,7 +707,7 @@ describe('TaiConverter', () => { const atomic = Second.fromMillis(63_072_010_000) assert.deepStrictEqual(taiConverter.unixToAtomic(taiConverter.atomicToUnix(atomic)), [ - new Range(atomic.minusS(new Second(107_758n, 1_000_000n)), atomic) + new Range(atomic.minusS(new Second(new Rat(107_758n, 1_000_000n))), atomic) ]) }) @@ -772,7 +773,7 @@ describe('TaiConverter', () => { ]) assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(2016, DEC, 31, 12, 0, 0, 1))), [ - new Range(Second.fromMillis(Date.UTC(2016, DEC, 31, 12, 0, 36, 1)).plusS(new Second(1n, 86_400_000n))) + new Range(Second.fromMillis(Date.UTC(2016, DEC, 31, 12, 0, 36, 1)).plusS(new Second(new Rat(1n, 86_400_000n)))) ]) // After 86_400 Unix milliseconds, exactly 86_401 TAI milliseconds have passed @@ -790,7 +791,7 @@ describe('TaiConverter', () => { // SMEAR ENDS. After 24 Unix hours, 24 TAI hours and 1 second assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(2017, JAN, 1, 11, 59, 59, 999))), [ - new Range(Second.fromMillis(Date.UTC(2017, JAN, 1, 12, 0, 35, 999)).plusS(new Second(86_399_999n, 86_400_000n))) + new Range(Second.fromMillis(Date.UTC(2017, JAN, 1, 12, 0, 35, 999)).plusS(new Second(new Rat(86_399_999n, 86_400_000n)))) ]) assert.deepStrictEqual(taiConverter.unixToAtomic(Second.fromMillis(Date.UTC(2017, JAN, 1, 12, 0, 0, 0))), [ diff --git a/test/munge.spec.js b/test/munge.spec.js index 87dc080..09f434b 100644 --- a/test/munge.spec.js +++ b/test/munge.spec.js @@ -66,13 +66,13 @@ describe('munge', () => { [9_000, -3], // inserted leap second [13_000, -4] // removed leap second ], MODELS.OVERRUN), [new Segment( - { atomic: new Second(-5n, 1n), unix: new Second(-1n, 1n) }, - { atomic: new Second(6n, 1n) } + { atomic: new Second(new Rat(-5n, 1n)), unix: new Second(new Rat(-1n, 1n)) }, + { atomic: new Second(new Rat(6n, 1n)) } ), new Segment( - { atomic: new Second(6n, 1n), unix: new Second(9n, 1n) }, - { atomic: new Second(9n, 1n) } + { atomic: new Second(new Rat(6n, 1n)), unix: new Second(new Rat(9n, 1n)) }, + { atomic: new Second(new Rat(9n, 1n)) } ), new Segment( - { atomic: new Second(9n, 1n), unix: new Second(13n, 1n) } + { atomic: new Second(new Rat(9n, 1n)), unix: new Second(new Rat(13n, 1n)) } )]) }) @@ -125,7 +125,7 @@ describe('munge', () => { assert.deepStrictEqual(munge([ [Date.UTC(1961, JAN, 1), 1.422_818_0, 37_300, 0.001_296] ], MODELS.OVERRUN), [new Segment( - { atomic: new Second(-283_996_798_577_182n, 1_000_000n), unix: new Second(-283_996_800n, 1n) }, + { atomic: new Second(new Rat(-283_996_798_577_182n, 1_000_000n)), unix: new Second(new Rat(-283_996_800n, 1n)) }, { atomic: Second.END_OF_TIME }, { unixPerAtomic: new Rat(86_400_000_000_000n, 86_400_000_000_000n + 1_296_000n) } )]) @@ -202,46 +202,46 @@ describe('munge', () => { return b.minusS(a) }), [ // Exact ratio of microseconds - new Second(-50_000n, 1_000_000n), - new Second(0n, 1_000_000n), - new Second(100_000n, 1_000_000n), - new Second(0n, 1_000_000n), - new Second(100_000n, 1_000_000n), - new Second(100_000n, 1_000_000n), - new Second(100_000n, 1_000_000n), - new Second(100_000n, 1_000_000n), - new Second(100_000n, 1_000_000n), - new Second(100_000n, 1_000_000n), - new Second(0n, 1_000_000n), - new Second(-100_000n, 1_000_000n), - new Second(107_758n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), - new Second(1_000_000n, 1_000_000n), + new Second(new Rat(-50_000n, 1_000_000n)), + new Second(new Rat(0n, 1_000_000n)), + new Second(new Rat(100_000n, 1_000_000n)), + new Second(new Rat(0n, 1_000_000n)), + new Second(new Rat(100_000n, 1_000_000n)), + new Second(new Rat(100_000n, 1_000_000n)), + new Second(new Rat(100_000n, 1_000_000n)), + new Second(new Rat(100_000n, 1_000_000n)), + new Second(new Rat(100_000n, 1_000_000n)), + new Second(new Rat(100_000n, 1_000_000n)), + new Second(new Rat(0n, 1_000_000n)), + new Second(new Rat(-100_000n, 1_000_000n)), + new Second(new Rat(107_758n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), + new Second(new Rat(1_000_000n, 1_000_000n)), NaN // `Infinity - Infinity` ]) }) @@ -251,7 +251,7 @@ describe('munge', () => { assert.deepStrictEqual(munge([ [Date.UTC(1970, JAN, 1, 0, 0, 0, 1), -0.000_1] ], MODELS.OVERRUN), [new Segment( - { atomic: new Second(900n, 1_000_000n), unix: Second.fromMillis(1) } // ray start intentionally doesn't include TAI epoch + { atomic: new Second(new Rat(900n, 1_000_000n)), unix: Second.fromMillis(1) } // ray start intentionally doesn't include TAI epoch )]) }) @@ -261,10 +261,10 @@ describe('munge', () => { [Date.UTC(1969, DEC, 31, 23, 59, 59, 999), 0.000_1], [Date.UTC(1970, JAN, 1, 0, 0, 0, 1), -0.001_1] ], MODELS.OVERRUN), [new Segment( - { atomic: new Second(-900n, 1_000_000n), unix: Second.fromMillis(-1) }, - { atomic: new Second(-100n, 1_000_000n) } + { atomic: new Second(new Rat(-900n, 1_000_000n)), unix: Second.fromMillis(-1) }, + { atomic: new Second(new Rat(-100n, 1_000_000n)) } ), new Segment( - { atomic: new Second(-100n, 1_000_000n), unix: Second.fromMillis(1) } + { atomic: new Second(new Rat(-100n, 1_000_000n)), unix: Second.fromMillis(1) } )]) }) }) @@ -289,14 +289,14 @@ describe('munge', () => { [9_000, -3], // inserted leap second [13_000, -4] // removed leap second ], MODELS.BREAK), [new Segment( - { atomic: new Second(-5n, 1n), unix: new Second(-1n, 1n) }, - { atomic: new Second(5n, 1n) } + { atomic: new Second(new Rat(-5n, 1n)), unix: new Second(new Rat(-1n, 1n)) }, + { atomic: new Second(new Rat(5n, 1n)) } ), new Segment( // this segment starts a full TAI second after the previous segment ended - { atomic: new Second(6n, 1n), unix: new Second(9n, 1n) }, - { atomic: new Second(9n, 1n) } + { atomic: new Second(new Rat(6n, 1n)), unix: new Second(new Rat(9n, 1n)) }, + { atomic: new Second(new Rat(9n, 1n)) } ), new Segment( - { atomic: new Second(9n, 1n), unix: new Second(13n, 1n) } + { atomic: new Second(new Rat(9n, 1n)), unix: new Second(new Rat(13n, 1n)) } )]) }) }) @@ -335,18 +335,18 @@ describe('munge', () => { [9_000, -3], // inserted leap second [13_000, -4] // removed leap second ], MODELS.STALL), [new Segment( - { atomic: new Second(-5n, 1n), unix: new Second(-1n, 1n) }, - { atomic: new Second(5n, 1n) } + { atomic: new Second(new Rat(-5n, 1n)), unix: new Second(new Rat(-1n, 1n)) }, + { atomic: new Second(new Rat(5n, 1n)) } ), new Segment( // Stall segment inserted here - { atomic: new Second(5n, 1n), unix: new Second(9n, 1n) }, - { atomic: new Second(6n, 1n) }, + { atomic: new Second(new Rat(5n, 1n)), unix: new Second(new Rat(9n, 1n)) }, + { atomic: new Second(new Rat(6n, 1n)) }, { unixPerAtomic: new Rat(0n) } ), new Segment( - { atomic: new Second(6n, 1n), unix: new Second(9n, 1n) }, - { atomic: new Second(9n, 1n) } + { atomic: new Second(new Rat(6n, 1n)), unix: new Second(new Rat(9n, 1n)) }, + { atomic: new Second(new Rat(9n, 1n)) } ), new Segment( - { atomic: new Second(9n, 1n), unix: new Second(13n, 1n) } + { atomic: new Second(new Rat(9n, 1n)), unix: new Second(new Rat(13n, 1n)) } )]) }) @@ -399,7 +399,7 @@ describe('munge', () => { assert.deepStrictEqual(munge([ [Date.UTC(1961, JAN, 1), 1.422_818_0, 37_300, 0.001_296] ], MODELS.STALL), [new Segment( - { atomic: new Second(-283_996_798_577_182n, 1_000_000n), unix: new Second(-283_996_800n, 1n) }, + { atomic: new Second(new Rat(-283_996_798_577_182n, 1_000_000n)), unix: new Second(new Rat(-283_996_800n, 1n)) }, { atomic: Second.END_OF_TIME }, { unixPerAtomic: new Rat(86_400_000_000_000n, 86_400_000_000_000n + 1_296_000n) } )]) @@ -518,81 +518,81 @@ describe('munge', () => { return b.minusS(a) }), [ // Exact ratio expressing milliseconds - new Second(-50n, 1_000n), // 0.05 TAI seconds removed from UTC - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(-100n, 1_000n), // 0.1 TAI seconds removed from UTC - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), - new Second(0n, 1_000n), + new Second(new Rat(-50n, 1_000n)), // 0.05 TAI seconds removed from UTC + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(-100n, 1_000n)), // 0.1 TAI seconds removed from UTC + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), + new Second(new Rat(0n, 1_000n)), NaN ]) }) @@ -613,13 +613,13 @@ describe('munge', () => { [86_400_000, 1] // inserted leap second after one day ], MODELS.SMEAR), [new Segment( { atomic: Second.fromMillis(0), unix: Second.fromMillis(0) }, - { atomic: new Second(43_200n, 1n) } // midday + { atomic: new Second(new Rat(43_200n, 1n)) } // midday ), new Segment( - { atomic: new Second(43_200n, 1n), unix: new Second(43_200n, 1n) }, // midday - { atomic: new Second(129_601n, 1n) }, // midday + { atomic: new Second(new Rat(43_200n, 1n)), unix: new Second(new Rat(43_200n, 1n)) }, // midday + { atomic: new Second(new Rat(129_601n, 1n)) }, // midday { unixPerAtomic: new Rat(86_400n, 86_401n) } // A full Unix day elapses, but a full TAI day plus one second elapses ), new Segment( - { atomic: new Second(129_601n, 1n), unix: new Second(129_600n, 1n) } // midday + { atomic: new Second(new Rat(129_601n, 1n)), unix: new Second(new Rat(129_600n, 1n)) } // midday )]) }) @@ -629,13 +629,13 @@ describe('munge', () => { [86_400_000, -1] // removed leap second after one day ], MODELS.SMEAR), [new Segment( { atomic: Second.fromMillis(0), unix: Second.fromMillis(0) }, - { atomic: new Second(43_200n, 1n) } // midday + { atomic: new Second(new Rat(43_200n, 1n)) } // midday ), new Segment( - { atomic: new Second(43_200n, 1n), unix: new Second(43_200n, 1n) }, // midday - { atomic: new Second(129_599n, 1n) }, // midday + { atomic: new Second(new Rat(43_200n, 1n)), unix: new Second(new Rat(43_200n, 1n)) }, // midday + { atomic: new Second(new Rat(129_599n, 1n)) }, // midday { unixPerAtomic: new Rat(86_400n, 86_399n) } // A full Unix day elapses, but a full TAI day minus one second elapses ), new Segment( - { atomic: new Second(129_599n, 1n), unix: new Second(129_600n, 1n) } // midday + { atomic: new Second(new Rat(129_599n, 1n)), unix: new Second(new Rat(129_600n, 1n)) } // midday )]) }) @@ -752,86 +752,86 @@ describe('munge', () => { return b.minusS(a) }), [ - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), - new Second(0n, 1n), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), + new Second(new Rat(0n, 1n)), NaN ]) }) diff --git a/test/second.spec.js b/test/second.spec.js index 2f6ec4c..16f14c6 100644 --- a/test/second.spec.js +++ b/test/second.spec.js @@ -4,64 +4,53 @@ import { Rat } from '../src/rat.js' import { Second } from '../src/second.js' describe('Second', () => { - it('type checking', () => { - assert.throws(() => new Second(1, 2n), /numerator must be a BigInt/) - assert.throws(() => new Second(1n, 2), /denominator must be a BigInt/) - assert.throws(() => new Second(1n, 0), /denominator must be a BigInt/) - assert.throws(() => new Second(-1n, 0n), /denominator cannot be zero/) - }) - - it('defaults to an integer', () => { - assert.deepStrictEqual(new Second(1n), new Second(1n, 1n)) - }) - it('adds', () => { - assert.deepStrictEqual(new Second(1n, 2n).plusS(new Second(1n, 3n)), new Second(5n, 6n)) - assert.deepStrictEqual(new Second(1n, 2n).plusS(new Second(0n, 3n)), new Second(1n, 2n)) - assert.deepStrictEqual(new Second(0n, 2n).plusS(new Second(1n, 3n)), new Second(1n, 3n)) + assert.deepStrictEqual(new Second(new Rat(1n, 2n)).plusS(new Second(new Rat(1n, 3n))), new Second(new Rat(5n, 6n))) + assert.deepStrictEqual(new Second(new Rat(1n, 2n)).plusS(new Second(new Rat(0n, 3n))), new Second(new Rat(1n, 2n))) + assert.deepStrictEqual(new Second(new Rat(0n, 2n)).plusS(new Second(new Rat(1n, 3n))), new Second(new Rat(1n, 3n))) }) it('subtracts', () => { - assert.deepStrictEqual(new Second(1n, 2n).minusS(new Second(1n, 3n)), new Second(1n, 6n)) - assert.deepStrictEqual(new Second(1n, 2n).minusS(new Second(0n, 3n)), new Second(1n, 2n)) - assert.deepStrictEqual(new Second(0n, 2n).minusS(new Second(1n, 3n)), new Second(-1n, 3n)) + assert.deepStrictEqual(new Second(new Rat(1n, 2n)).minusS(new Second(new Rat(1n, 3n))), new Second(new Rat(1n, 6n))) + assert.deepStrictEqual(new Second(new Rat(1n, 2n)).minusS(new Second(new Rat(0n, 3n))), new Second(new Rat(1n, 2n))) + assert.deepStrictEqual(new Second(new Rat(0n, 2n)).minusS(new Second(new Rat(1n, 3n))), new Second(new Rat(-1n, 3n))) }) it('multiplies', () => { - assert.deepStrictEqual(new Second(6n, 5n).timesR(new Rat(4n, 5n)), new Second(24n, 25n)) - assert.deepStrictEqual(new Second(6n, 5n).timesR(new Rat(0n, 5n)), new Second(0n, 25n)) - assert.deepStrictEqual(new Second(0n, 5n).timesR(new Rat(4n, 5n)), new Second(0n, 25n)) + assert.deepStrictEqual(new Second(new Rat(6n, 5n)).timesR(new Rat(4n, 5n)), new Second(new Rat(24n, 25n))) + assert.deepStrictEqual(new Second(new Rat(6n, 5n)).timesR(new Rat(0n, 5n)), new Second(new Rat(0n, 25n))) + assert.deepStrictEqual(new Second(new Rat(0n, 5n)).timesR(new Rat(4n, 5n)), new Second(new Rat(0n, 25n))) }) it('divides', () => { - assert.deepStrictEqual(new Second(6n, 5n).divideS(new Second(4n, 5n)), new Rat(30n, 20n)) - assert.deepStrictEqual(new Second(0n, 5n).divideS(new Second(4n, 5n)), new Rat(0n, 20n)) + assert.deepStrictEqual(new Second(new Rat(6n, 5n)).divideS(new Second(new Rat(4n, 5n))), new Rat(30n, 20n)) + assert.deepStrictEqual(new Second(new Rat(0n, 5n)).divideS(new Second(new Rat(4n, 5n))), new Rat(0n, 20n)) }) it('greater than', () => { - assert.strictEqual(new Second(-1n, 3n).gtS(new Second(1n, -2n)), true) - assert.strictEqual(new Second(0n).gtS(new Second(1n)), false) + assert.strictEqual(new Second(new Rat(-1n, 3n)).gtS(new Second(new Rat(1n, -2n))), true) + assert.strictEqual(new Second(new Rat(0n)).gtS(new Second(new Rat(1n))), false) }) it('equal', () => { - assert.strictEqual(new Second(-1n, 3n).eqS(new Second(4n, -12n)), true) - assert.strictEqual(new Second(0n).eqS(new Second(-1n)), false) - assert.strictEqual(new Second(0n).eqS(new Second(-0n)), true) + assert.strictEqual(new Second(new Rat(-1n, 3n)).eqS(new Second(new Rat(4n, -12n))), true) + assert.strictEqual(new Second(new Rat(0n)).eqS(new Second(new Rat(-1n))), false) + assert.strictEqual(new Second(new Rat(0n)).eqS(new Second(new Rat(-0n))), true) }) it('less than or equal', () => { - assert.strictEqual(new Second(-2n, -3n).leS(new Second(-2n, -3n)), true) - assert.strictEqual(new Second(-2n, -3n).leS(new Second(2n, 3n)), true) - assert.strictEqual(new Second(9n, 12n).leS(new Second(6n, 8n)), true) - assert.strictEqual(new Second(9n, 13n).leS(new Second(6n, 8n)), true) + assert.strictEqual(new Second(new Rat(-2n, -3n)).leS(new Second(new Rat(-2n, -3n))), true) + assert.strictEqual(new Second(new Rat(-2n, -3n)).leS(new Second(new Rat(2n, 3n))), true) + assert.strictEqual(new Second(new Rat(9n, 12n)).leS(new Second(new Rat(6n, 8n))), true) + assert.strictEqual(new Second(new Rat(9n, 13n)).leS(new Second(new Rat(6n, 8n))), true) }) it('fromMillis', () => { - assert.deepStrictEqual(Second.fromMillis(123), new Second(123n, 1_000n)) + assert.deepStrictEqual(Second.fromMillis(123), new Second(new Rat(123n, 1_000n))) assert.throws(() => Second.fromMillis(Infinity)) }) it('toMillis', () => { - assert.strictEqual(new Second(123n, 1_000n).toMillis(), 123) + assert.strictEqual(new Second(new Rat(123n, 1_000n)).toMillis(), 123) }) }) diff --git a/test/segment.spec.js b/test/segment.spec.js index 967392e..f943253 100644 --- a/test/segment.spec.js +++ b/test/segment.spec.js @@ -22,14 +22,14 @@ describe('Segment', () => { assert.throws(() => new Segment( { atomic: Second.fromMillis(0), unix: Second.fromMillis(0) }, { atomic: Second.fromMillis(1_000) }, - { unixPerAtomic: new Second(1n, 1n) } + { unixPerAtomic: new Second(new Rat(1n, 1n)) } ), /slope must be a `Rat`/) }) it('disallows rays which run backwards', () => { assert.throws(() => new Segment( { atomic: Second.fromMillis(0), unix: Second.fromMillis(0) }, - { atomic: new Second(-1n, 1_000_000_000_000n) } + { atomic: new Second(new Rat(-1n, 1_000_000_000_000n)) } ), /segment length must be positive/) }) @@ -121,7 +121,7 @@ describe('Segment', () => { assert.strictEqual(segment.atomicOnSegment(Second.fromMillis(1_999)), true) assert.deepStrictEqual(segment.atomicToUnix(Second.fromMillis(1_999)), - new Second(1_999n, 2_000n)) // truncates to 999ms + new Second(new Rat(1_999n, 2_000n))) // truncates to 999ms }) it('end point', () => {