Files
usenet-indexer/tests/unit/services/group_dates.spec.ts
T
Daan MeijerandClaude Fable 5.1 137e931e9e
Test and deploy / test (push) Successful in 55s
Test and deploy / edge (push) Successful in 2m2s
Test and deploy / deploy (push) Successful in 2m12s
Posting-time windows into the corpus: ranges:dates, ranges:capture
ranges:dates samples each active group's posting dates from the news
server (group_dates) and estimates every range's date (ranges.est_date).
ranges:capture --from --to marks a window's ranges of every group for the
corpus. The corpus fill takes capture ranges in priority order, done ones
too, and remembers complete ones (ranges.stored_at).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-25 09:47:28 +01:00

76 lines
2.9 KiB
TypeScript

import { test } from '@japa/runner'
import type { Overview } from '#lib/nntp/index'
import {
estimateDate,
medianDate,
monotone,
sampleCount,
samplePoints,
} from '#services/group_dates'
const now = new Date('2026-10-25T10:00:00Z')
const overview = (n: number, date: string): Overview => [n, { subject: 's', from: 'f', date }]
const day = (d: string) => new Date(`${d}T00:00:00Z`)
test.group('group dates', () => {
test('the median of the plausible Date headers, or null for too few', ({ assert }) => {
const slice = [
overview(1, 'Mon, 02 Mar 2015 10:00:00 +0000'),
overview(2, 'Tue, 03 Mar 2015 10:00:00 GMT'),
overview(3, 'Wed, 04 Mar 2015 10:00:00 UTC'),
// A broken clock, a future one, and junk: left out.
overview(4, 'Sat, 01 Jan 1980 00:00:00 +0000'),
overview(5, 'Fri, 01 Jan 2027 00:00:00 +0000'),
overview(6, 'not a date'),
overview(7, 'Thu, 05 Mar 2015 10:00:00 +0100'),
]
assert.equal(medianDate(slice, now)!.toISOString(), '2015-03-04T10:00:00.000Z')
assert.isNull(medianDate(slice.slice(0, 2), now))
assert.isNull(medianDate([], now))
})
test('sample points span low to high, the last slice ending at high', ({ assert }) => {
assert.deepEqual(samplePoints(100, 1099, 5, 100), [100, 325, 550, 775, 1000])
assert.deepEqual(samplePoints(100, 150, 5, 100), [100])
assert.equal(sampleCount(0, 161e9, 500e6), 323)
assert.equal(sampleCount(0, 1000, 500e6), 16)
assert.equal(sampleCount(0, 10e12, 500e6), 1000)
})
test('the curve drops a spike, raises a dip, and keeps the order', ({ assert }) => {
const curve = monotone([
{ article: 300, postedAt: day('2015-03-01') },
{ article: 100, postedAt: day('2015-01-01') },
// One poster's clock in the future for a whole slice.
{ article: 200, postedAt: day('2019-06-01') },
// Old crossposts: earlier than the sample before.
{ article: 400, postedAt: day('2014-12-01') },
{ article: 500, postedAt: day('2015-05-01') },
])
assert.deepEqual(
curve.map((s) => [s.article, s.postedAt.toISOString().slice(0, 10)]),
[
[100, '2015-01-01'],
[300, '2015-03-01'],
[400, '2015-03-01'],
[500, '2015-05-01'],
]
)
})
test('a date is interpolated between the samples around it and clamped beyond them', ({
assert,
}) => {
const curve = [
{ article: 100, postedAt: day('2015-01-01') },
{ article: 300, postedAt: day('2015-03-02') },
{ article: 500, postedAt: day('2015-05-01') },
]
assert.equal(estimateDate(curve, 200)!.toISOString().slice(0, 10), '2015-01-31')
assert.equal(estimateDate(curve, 300)!.toISOString().slice(0, 10), '2015-03-02')
assert.equal(estimateDate(curve, 1)!.toISOString().slice(0, 10), '2015-01-01')
assert.equal(estimateDate(curve, 900)!.toISOString().slice(0, 10), '2015-05-01')
assert.isNull(estimateDate([], 200))
})
})