Files
Genarrative/src/components/child-motion-demo/childMotionWarmupModel.test.ts

94 lines
2.7 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import {
applyChildMotionWarmupCompletion,
CHILD_MOTION_CENTER_X,
CHILD_MOTION_WARMUP_STEPS,
createEmptyChildMotionCalibration,
getChildMotionWarmupStep,
isAvatarOnWarmupTarget,
resolveNextChildMotionWarmupStep,
} from './childMotionWarmupModel';
describe('childMotionWarmupModel', () => {
it('keeps the confirmed warmup order as a strict state chain', () => {
expect(CHILD_MOTION_WARMUP_STEPS.map((step) => step.id)).toEqual([
'center_arrive',
'wave_greeting',
'warmup_intro',
'move_left',
'return_center_1',
'move_right',
'return_center_2',
'wave_left_hand',
'wave_right_hand',
'warmup_finish',
'level_select',
]);
expect(resolveNextChildMotionWarmupStep('center_arrive')).toBe(
'wave_greeting',
);
expect(resolveNextChildMotionWarmupStep('level_select')).toBe('level_select');
});
it('checks position completion against the active green ring target', () => {
expect(
isAvatarOnWarmupTarget(
getChildMotionWarmupStep('center_arrive'),
CHILD_MOTION_CENTER_X,
),
).toBe(true);
expect(
isAvatarOnWarmupTarget(getChildMotionWarmupStep('move_left'), 0.66),
).toBe(false);
});
it('records session-only calibration values from completed steps', () => {
const empty = createEmptyChildMotionCalibration();
const withLeft = applyChildMotionWarmupCompletion('move_left', empty, {
type: 'position',
avatarX: 0.34,
});
const withRight = applyChildMotionWarmupCompletion('move_right', withLeft, {
type: 'position',
avatarX: 0.66,
});
const withLeftHand = applyChildMotionWarmupCompletion(
'wave_left_hand',
withRight,
{
type: 'left-hand',
path: [
{ x: 0.3, y: 0.4, armAngleDeg: 12, armReach: 0.2 },
{ x: 0.34, y: 0.32, armAngleDeg: 44, armReach: 0.28 },
],
},
);
const withRightHand = applyChildMotionWarmupCompletion(
'wave_right_hand',
withLeftHand,
{
type: 'right-hand',
path: [
{ x: 0.7, y: 0.42, armAngleDeg: 10, armReach: 0.22 },
{ x: 0.82, y: 0.3, armAngleDeg: 46, armReach: 0.31 },
],
},
);
expect(withRightHand.leftBoundary).toBeCloseTo(0.16);
expect(withRightHand.rightBoundary).toBeCloseTo(0.16);
expect(withRightHand.leftHandPath).toHaveLength(2);
expect(withRightHand.leftHandSpace).toEqual({
minX: 0.3,
maxX: 0.34,
minY: 0.32,
maxY: 0.4,
minAngleDeg: 12,
maxAngleDeg: 44,
maxReach: 0.28,
});
expect(withRightHand.rightHandSpace?.maxReach).toBe(0.31);
});
});