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' }) }) })