import { describe, expect, it } from 'vitest'; import type { ToolcraftTimelineKeyframeEasing } from '../../state/types'; import { findTimelineEasingPresetName, getEasingEditorControlPoints, getEasingInputValue, getToolcraftTimelineKeyframeEasing, interpolateTimelineEasingControlPoints, normalizeToolcraftTimelineKeyframeEasing, parseToolcraftTimelineKeyframeEasing, } from './timeline-easing-model'; describe('timeline easing model', () => { it('parses bare and CSS cubic-bezier control point values', () => { expect(parseToolcraftTimelineKeyframeEasing('0.19, 1, 0.22, 1')).toEqual({ controlPoints: [0.19, 1, 0.22, 1], type: 'bezier', }); expect( parseToolcraftTimelineKeyframeEasing('cubic-bezier(0.19, 1, 0.22, 1)'), ).toEqual({ controlPoints: [0.19, 1, 0.22, 1], type: 'bezier', }); }); it('parses step easing and fills partial bezier values from the active easing', () => { expect(parseToolcraftTimelineKeyframeEasing('step')).toEqual({ type: 'step' }); expect( parseToolcraftTimelineKeyframeEasing('0.2, 0.7', { controlPoints: [0.1, 0.3, 0.6, 0.9], type: 'bezier', }), ).toEqual({ controlPoints: [0.2, 0.7, 0.6, 0.9], type: 'bezier', }); }); it('normalizes external easing objects into bounded runtime easing values', () => { expect( normalizeToolcraftTimelineKeyframeEasing({ controlPoints: [-1, -3, 2, 5], type: 'bezier', }), ).toEqual({ controlPoints: [0, -1, 1, 2], type: 'bezier', }); expect(normalizeToolcraftTimelineKeyframeEasing({ type: 'step' })).toEqual({ type: 'step', }); }); it('clones fallback easing values instead of exposing shared control point arrays', () => { const easing = getToolcraftTimelineKeyframeEasing(undefined); expect(easing).toEqual({ controlPoints: [0.65, 0, 0.35, 1], type: 'bezier', }); if (easing.type === 'bezier') { easing.controlPoints[0] = 0; } expect(getToolcraftTimelineKeyframeEasing(undefined)).toEqual({ controlPoints: [0.65, 0, 0.35, 1], type: 'bezier', }); }); it('maps known presets, editor points, interpolation, and input formatting', () => { const smooth = { controlPoints: [0.65, 0, 0.35, 1], type: 'bezier', } satisfies ToolcraftTimelineKeyframeEasing; expect(findTimelineEasingPresetName(smooth)).toBe('smooth'); expect(getEasingEditorControlPoints({ type: 'step' })).toEqual([0, 0, 1, 1]); expect(getEasingInputValue(smooth)).toBe('0.65, 0, 0.35, 1'); expect(interpolateTimelineEasingControlPoints([0, 0, 1, 1], [1, 1, 0, 0], 1)).toEqual([ 1, 1, 0, 0, ]); }); });