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

62 lines
2.3 KiB
TypeScript

import { describe, expect, it, vi } from 'vitest'
import * as THREE from 'three'
import {
isolateMeshMaterialsForFocus,
restoreIsolatedFocusMaterials
} from '@/components/map/focusMaterialIsolation'
describe('选中模型材质隔离', () => {
it('仅修改选中 Mesh 的克隆材质并在清理时恢复共享引用', () => {
const sharedMaterial = new THREE.MeshStandardMaterial({ color: '#ffffff' })
const selectedMesh = new THREE.Mesh(new THREE.BoxGeometry(), sharedMaterial)
const siblingMesh = new THREE.Mesh(new THREE.BoxGeometry(), sharedMaterial)
const state = isolateMeshMaterialsForFocus(selectedMesh)
const selectedMaterial = selectedMesh.material as THREE.MeshStandardMaterial
const disposeSpy = vi.spyOn(selectedMaterial, 'dispose')
expect(selectedMaterial).not.toBe(sharedMaterial)
expect(siblingMesh.material).toBe(sharedMaterial)
selectedMaterial.color.set('#e0df00')
selectedMaterial.emissive.set('#e0df00')
expect(sharedMaterial.color.getHexString()).toBe('ffffff')
expect(sharedMaterial.emissive.getHexString()).toBe('000000')
expect(siblingMesh.material).toBe(sharedMaterial)
restoreIsolatedFocusMaterials(state)
expect(selectedMesh.material).toBe(sharedMaterial)
expect(disposeSpy).toHaveBeenCalledOnce()
selectedMesh.geometry.dispose()
siblingMesh.geometry.dispose()
sharedMaterial.dispose()
})
it('材质数组逐项克隆并完整恢复原数组引用', () => {
const materials = [
new THREE.MeshBasicMaterial({ color: '#ffffff' }),
new THREE.MeshBasicMaterial({ color: '#000000' })
]
const mesh = new THREE.Mesh(new THREE.BoxGeometry(), materials)
const state = isolateMeshMaterialsForFocus(mesh)
const clonedMaterials = mesh.material as THREE.Material[]
const disposeSpies = clonedMaterials.map((material) => vi.spyOn(material, 'dispose'))
expect(clonedMaterials).not.toBe(materials)
expect(clonedMaterials[0]).not.toBe(materials[0])
expect(clonedMaterials[1]).not.toBe(materials[1])
restoreIsolatedFocusMaterials(state)
expect(mesh.material).toBe(materials)
disposeSpies.forEach((spy) => expect(spy).toHaveBeenCalledOnce())
mesh.geometry.dispose()
materials.forEach((material) => material.dispose())
})
})