opencode/packages/voice/test/animation.test.ts
2026-07-28 21:00:35 -04:00

53 lines
2.2 KiB
TypeScript

import { describe, expect, test } from "bun:test"
import {
connectionMeterLevels,
connectionTransitioning,
scheduleTextReveal,
textRevealOpacity,
transcriptionPulse,
} from "../src/animation"
describe("voice text animation", () => {
test("stages newly streamed words without delaying them indefinitely", () => {
const first = scheduleTextReveal("", "Hello there", 1_000, 0)
expect(first.reveals).toEqual([
{ offset: 0, at: 1_000 },
{ offset: 6, at: 1_032 },
])
expect(first.animationEndsAt).toBe(1_412)
const queued = scheduleTextReveal("Hello there", " friend", 1_010, 10_000)
expect(queued.reveals).toEqual([{ offset: 12, at: 1_170 }])
})
test("slowly fades text into its stable color", () => {
const opacities = [100, 195, 290, 385, 480].map((now) => textRevealOpacity(now, 100))
expect(opacities[0]).toBe(0.16)
expect(opacities.toSorted((a, b) => a - b)).toEqual(opacities)
expect(opacities.at(-1)).toBe(1)
})
test("keeps transcription pulse bounded and moving", () => {
const levels = [0, 110, 220, 330].map(transcriptionPulse)
expect(levels.every((level) => level >= 0 && level <= 1)).toBe(true)
expect(new Set(levels).size).toBeGreaterThan(1)
})
test("moves the connecting pulse left to right and blends into the connected meter", () => {
const first = connectionMeterLevels(1_000, 0.1, undefined, 1_000)
const next = connectionMeterLevels(1_180, 0.1, undefined, 1_000)
expect(first.indexOf(Math.max(...first))).toBe(0)
expect(first.indexOf(Math.max(...first))).toBeLessThan(next.indexOf(Math.max(...next)))
const samples = Array.from({ length: 16 }, (_, index) => connectionMeterLevels(index * 45, 0.1))
expect(samples.every((levels) => Math.max(...levels) > 0.85)).toBe(true)
const handoff = connectionMeterLevels(1_000, 0.4, 1_000)
expect(handoff).toEqual(connectionMeterLevels(1_000, 0.4))
expect(connectionMeterLevels(1_480, 0.4, 1_000)).toEqual(
[0, 1, 2, 3].map((index) => 0.4 * (0.72 + Math.sin(1_480 / 240 + index * 1.4) * 0.28)),
)
expect(connectionTransitioning(1_479, 1_000)).toBe(true)
expect(connectionTransitioning(1_480, 1_000)).toBe(false)
})
})