149 lines
3.9 KiB
TypeScript
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' })
|
|
})
|
|
})
|