Files
frontend-miniapp/tests/unit/GuideSceneState.spec.ts
lyf 9ea1bfab71
Some checks failed
CI / verify (push) Has been cancelled
同步 sgs-frontend-mobile 源码
2026-07-27 11:26:01 +08:00

149 lines
3.9 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { useGuideSceneState } from '@/composables/useGuideSceneState'
describe('useGuideSceneState', () => {
it('keeps scene and renderer mode as independent state axes', () => {
const scene = useGuideSceneState({
view: 'floor',
floorId: 'L3',
renderMode: 'three-d'
})
scene.renderMode.value = 'two-d'
expect(scene.state.value).toMatchObject({
view: 'floor',
floorId: 'L3',
renderMode: 'two-d'
})
})
it('reduces multi to the active floor in one render-mode transaction', () => {
const scene = useGuideSceneState({
view: 'multi',
floorId: 'L2',
renderMode: 'three-d'
})
const beforeRevision = scene.revision.value
scene.renderMode.value = 'two-d'
expect(scene.state.value).toMatchObject({
view: 'floor',
floorId: 'L2',
renderMode: 'two-d',
revision: beforeRevision + 1
})
})
it('rejects a renderer commit from an obsolete scene revision', () => {
const scene = useGuideSceneState({ view: 'overview', floorId: 'L1' })
const staleRevision = scene.revision.value
scene.renderMode.value = 'two-d'
expect(scene.commitRendererScene({
view: 'floor',
floorId: 'L1',
requestRevision: staleRevision
})).toBe(false)
expect(scene.view.value).toBe('overview')
})
it('does not invalidate an in-flight scene transition when only the viewport changes', () => {
const scene = useGuideSceneState({ view: 'overview', floorId: 'L1' })
const rendererRevision = scene.revision.value
scene.updateViewport({
scene: 'overview',
floorId: '',
centerX: 12,
centerZ: 8,
visibleWorldSpan: 240,
revision: 1
})
expect(scene.commitRendererScene({
view: 'floor',
floorId: 'L1',
requestRevision: rendererRevision
})).toBe(true)
})
it('does not let an older viewport revision overwrite the latest world viewport', () => {
const scene = useGuideSceneState({ view: 'floor', floorId: 'L2' })
scene.updateViewport({
scene: 'floor',
floorId: 'L2',
centerX: 35,
centerZ: -18,
visibleWorldSpan: 90,
revision: 5
})
scene.updateViewport({
scene: 'floor',
floorId: 'L2',
centerX: -100,
centerZ: 200,
visibleWorldSpan: 240,
revision: 4
})
expect(scene.viewport.value).toMatchObject({
centerX: 35,
centerZ: -18,
visibleWorldSpan: 90,
revision: 5
})
expect(scene.getCachedViewport('floor', 'L2')).toEqual(scene.viewport.value)
})
it('keeps floor viewport caches isolated and restores each floor independently', () => {
const scene = useGuideSceneState({ view: 'floor', floorId: 'L1' })
scene.updateViewport({
scene: 'floor',
floorId: 'L1',
centerX: 10,
centerZ: 20,
visibleWorldSpan: 100,
revision: 1
})
scene.commit({ floorId: 'L2' })
scene.updateViewport({
scene: 'floor',
floorId: 'L2',
centerX: -40,
centerZ: 60,
visibleWorldSpan: 80,
revision: 1
})
scene.commit({ floorId: 'L1' })
expect(scene.viewport.value).toMatchObject({ floorId: 'L1', centerX: 10, centerZ: 20 })
scene.commit({ floorId: 'L2' })
expect(scene.viewport.value).toMatchObject({ floorId: 'L2', centerX: -40, centerZ: 60 })
})
it('changes renderer mode without clearing the scene viewport', () => {
const viewport = {
scene: 'floor' as const,
floorId: 'L3',
centerX: -72,
centerZ: 38,
visibleWorldSpan: 120,
revision: 4
}
const scene = useGuideSceneState({
view: 'floor',
floorId: 'L3',
renderMode: 'three-d',
viewport
})
scene.commit({ renderMode: 'two-d' })
expect(scene.viewport.value).toEqual(viewport)
expect(scene.state.value).toMatchObject({ view: 'floor', floorId: 'L3' })
})
})