Skip to content

Built for people who want to own their automations. Join the waitlist for an invite.

Package listing

@kentcdodds/lineage

src/ui/time-axis.node.test.ts

50 lines · 2.3 KB · TypeScript
import assert from 'node:assert/strict'
import test from 'node:test'
import { chooseTimeAxisStep, timeAxisTicks } from './time-axis.ts'

function series(from: Date, to: Date, count: number): Array<{ at: string }> {
	const start = from.getTime()
	const span = to.getTime() - start
	return Array.from({ length: count }, (_, index) => ({
		at: new Date(start + (count === 1 ? 0 : (span * index) / (count - 1))).toISOString(),
	}))
}

test('picks a tick step that matches the selected span', () => {
	assert.deepEqual(chooseTimeAxisStep(6 * 60 * 60 * 1000), { unit: 'hour', step: 1 })
	assert.deepEqual(chooseTimeAxisStep(7 * 24 * 60 * 60 * 1000), { unit: 'day', step: 1 })
	assert.deepEqual(chooseTimeAxisStep(30 * 24 * 60 * 60 * 1000), { unit: 'day', step: 7 })
	assert.deepEqual(chooseTimeAxisStep(90 * 24 * 60 * 60 * 1000), { unit: 'month', step: 1 })
	assert.deepEqual(chooseTimeAxisStep(365 * 24 * 60 * 60 * 1000), { unit: 'month', step: 2 })
	assert.deepEqual(chooseTimeAxisStep(900 * 24 * 60 * 60 * 1000), { unit: 'month', step: 6 })
})

test('labels a week of commits by day', () => {
	const points = series(new Date(2026, 2, 18, 9), new Date(2026, 2, 25, 9), 15)
	const labels = timeAxisTicks(points, { locale: 'en-US' }).map((tick) => tick.label)
	assert.ok(labels.length >= 5 && labels.length <= 8)
	assert.match(labels[0] ?? '', /Mar 18/)
	assert.ok(labels.some((label) => /21/.test(label)))
	assert.doesNotMatch(labels.join(' | '), /,\s*\d{1,2}:\d{2}/)
})

test('labels a multi-year range by month and year, not clock time', () => {
	const points = series(new Date(2024, 2, 18, 12), new Date(2026, 7, 29, 12), 40)
	const labels = timeAxisTicks(points, { locale: 'en-US' }).map((tick) => tick.label)
	assert.ok(labels.length >= 4 && labels.length <= 8)
	assert.match(labels.join(' | '), /2024/)
	assert.match(labels[labels.length - 1] ?? '', /2026|Aug/)
	assert.doesNotMatch(labels.join(' | '), /AM|PM/)
})

test('maps ticks onto the nearest commit index', () => {
	const points = [
		{ at: new Date(2026, 0, 1, 12).toISOString() },
		{ at: new Date(2026, 3, 1, 12).toISOString() },
		{ at: new Date(2026, 6, 1, 12).toISOString() },
	]
	const ticks = timeAxisTicks(points, { locale: 'en-US' })
	assert.equal(ticks[0]?.index, 0)
	assert.equal(ticks[ticks.length - 1]?.index, 2)
	assert.equal(new Set(ticks.map((tick) => tick.index)).size, ticks.length)
})