Add distribution metadata, Strobi app icons, CI, and comprehensive documentation. Migrate the project to pnpm and reorganize the Studio into domain-focused modules and components.
51 lines
1.9 KiB
TypeScript
51 lines
1.9 KiB
TypeScript
import {
|
|
ambientBodyOffset,
|
|
applyAmbientMotion,
|
|
hasAmbientMotion,
|
|
} from '@/features/avatar/ambientMotion'
|
|
import { defaultExpression } from '@/features/avatar/presets'
|
|
|
|
describe('perpetual expression motion', () => {
|
|
it('leaves a motionless expression unchanged', () => {
|
|
const expression = { ...defaultExpression }
|
|
|
|
expect(hasAmbientMotion(expression)).toBe(false)
|
|
expect(applyAmbientMotion(expression, 500)).toEqual(expression)
|
|
})
|
|
|
|
it('moves both eyes together without mutating the saved expression', () => {
|
|
const expression = { ...defaultExpression, eyeMotion: 'microSaccades' as const }
|
|
const animated = applyAmbientMotion(expression, 500)
|
|
|
|
expect(animated.positionXLeft - expression.positionXLeft).toBeCloseTo(
|
|
animated.positionXRight - expression.positionXRight
|
|
)
|
|
expect(animated.positionYLeft - expression.positionYLeft).toBeCloseTo(
|
|
animated.positionYRight - expression.positionYRight
|
|
)
|
|
expect(animated.positionXLeft).not.toBe(expression.positionXLeft)
|
|
expect(expression.positionXLeft).toBe(defaultExpression.positionXLeft)
|
|
})
|
|
|
|
it('adds body motion without changing eye placement', () => {
|
|
const expression = { ...defaultExpression, bodyMotion: 'shake' as const }
|
|
const animated = applyAmbientMotion(expression, 500)
|
|
|
|
expect(animated.headY).not.toBe(expression.headY)
|
|
expect(animated.positionXLeft).toBe(expression.positionXLeft)
|
|
expect(animated.positionYRight).toBe(expression.positionYRight)
|
|
})
|
|
|
|
it('visibly offsets a symmetric body when it shakes', () => {
|
|
const expression = { ...defaultExpression, bodyMotion: 'shake' as const }
|
|
|
|
expect(ambientBodyOffset(expression, 500)).not.toEqual({ x: 0, y: 0 })
|
|
})
|
|
|
|
it('visibly offsets a symmetric body during slow drift', () => {
|
|
const expression = { ...defaultExpression, bodyMotion: 'slowDrift' as const }
|
|
|
|
expect(ambientBodyOffset(expression, 1500)).not.toEqual({ x: 0, y: 0 })
|
|
})
|
|
})
|