Back to home page

EIC code displayed by LXR

 
 

    


Warning, /firebird/firebird-ng/src/app/utils/three.utils.spec.ts is written in an unsupported language. File is not indexed.

0001 import type { Mock } from "vitest";
0002 import { walkObject3DNodes, findObject3DNodes } from './three.utils';
0003 import * as THREE from 'three';
0004 import { isColorable, getColorOrDefault } from './three.utils';
0005 
0006 describe('walkObject3dNodes', () => {
0007     let root: THREE.Object3D;
0008     let callback: Mock;
0009 
0010     beforeEach(() => {
0011         // Create a simple scene graph: root -> child -> grandchild
0012         root = new THREE.Object3D();
0013         root.name = 'root';
0014 
0015         const child = new THREE.Object3D();
0016         child.name = 'child';
0017         root.add(child);
0018 
0019         const grandchild = new THREE.Object3D();
0020         grandchild.name = 'grandchild';
0021         child.add(grandchild);
0022 
0023         // Setup callback spy
0024         callback = vi.fn();
0025     });
0026 
0027     it('should invoke callback for each node when no pattern is given', () => {
0028         walkObject3DNodes(root, callback);
0029         expect(vi.mocked(callback).mock.calls.length).toBe(3);
0030         expect(vi.mocked(callback).mock.calls[0]).toEqual([root, 'root', 0]);
0031         expect(vi.mocked(callback).mock.calls[1]).toEqual([root.children[0], 'root/child', 1]);
0032         expect(vi.mocked(callback).mock.calls[2]).toEqual([root.children[0].children[0], 'root/child/grandchild', 2]);
0033     });
0034 
0035     it('should respect the maxLevel parameter', () => {
0036         walkObject3DNodes(root, callback, { maxLevel: 1 });
0037         expect(vi.mocked(callback).mock.calls.length).toBe(2);
0038     });
0039 
0040     it('should correctly match nodes when a pattern is given', () => {
0041         const pattern = 'root/child';
0042         walkObject3DNodes(root, callback, { pattern: pattern });
0043         expect(callback).toHaveBeenCalledWith(expect.objectContaining({ name: 'child' }), 'root/child', 1);
0044     });
0045 
0046     it('should return the correct number of processed nodes', () => {
0047         const processed = walkObject3DNodes(root, callback);
0048         expect(processed).toBe(3); // Including root, child, grandchild
0049     });
0050 
0051     it('should not invoke callback for non-matching pattern', () => {
0052         const pattern = 'nonexistent';
0053         walkObject3DNodes(root, callback, { pattern: pattern });
0054         expect(callback).not.toHaveBeenCalled();
0055     });
0056 });
0057 
0058 
0059 describe('Material color functions', () => {
0060     describe('isColorable', () => {
0061         it('should return true if material has a color property', () => {
0062             const colorableMaterial = { color: new THREE.Color(255, 0, 0) };
0063             expect(isColorable(colorableMaterial)).toBe(true);
0064         });
0065 
0066         it('should return false if material does not have a color property', () => {
0067             const nonColorableMaterial = { noColor: true };
0068             expect(isColorable(nonColorableMaterial)).toBe(false);
0069         });
0070     });
0071 
0072     describe('getColorOrDefault', () => {
0073         it('should return the material color if material is colorable', () => {
0074             const colorableMaterial = { color: new THREE.Color(255, 0, 0) };
0075             const defaultColor = new THREE.Color(0, 0, 0);
0076             expect(getColorOrDefault(colorableMaterial, defaultColor)).toEqual(colorableMaterial.color);
0077         });
0078 
0079         it('should return the default color if material is not colorable', () => {
0080             const nonColorableMaterial = { noColor: true };
0081             const defaultColor = new THREE.Color(0, 0, 0);
0082             expect(getColorOrDefault(nonColorableMaterial, defaultColor)).toEqual(defaultColor);
0083         });
0084     });
0085 });
0086 
0087 describe('findObject3DNodes', () => {
0088     let root: THREE.Object3D, child1: THREE.Object3D, child2: THREE.Object3D, subchild1: THREE.Object3D, subchild2: THREE.Object3D;
0089 
0090     beforeEach(() => {
0091         // Setup a mock hierarchy of THREE.Object3D nodes
0092         root = new THREE.Object3D();
0093         root.name = 'root';
0094 
0095         child1 = new THREE.Object3D();
0096         child1.name = 'child1';
0097         root.add(child1);
0098 
0099         child2 = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1));
0100         child2.name = 'child2';
0101         root.add(child2);
0102 
0103         subchild1 = new THREE.Object3D();
0104         subchild1.name = 'subchild1';
0105         child1.add(subchild1);
0106 
0107         subchild2 = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1));
0108         subchild2.name = 'match';
0109         child2.add(subchild2);
0110     });
0111 
0112     it('should return all nodes when no pattern or type is provided', () => {
0113         const results = findObject3DNodes(root, '');
0114         expect(results.nodes.length).toBe(5);
0115         expect(results.deepestLevel).toBe(2);
0116         expect(results.totalWalked).toBe(5);
0117     });
0118 
0119     it('should handle no matches found', () => {
0120         const results = findObject3DNodes(root, 'nonexistent');
0121         expect(results.nodes.length).toBe(0);
0122     });
0123 
0124     it('should match nodes based on a pattern', () => {
0125         const results = findObject3DNodes(root, '**/match');
0126         expect(results.nodes.length).toBe(1);
0127         expect(results.nodes[0]).toBe(subchild2);
0128         expect(results.fullPaths[0]).toBe('root/child2/match');
0129     });
0130 
0131     it('should filter nodes based on type', () => {
0132         const results = findObject3DNodes(root, '', 'Mesh');
0133         expect(results.nodes.every(node => node instanceof THREE.Mesh)).toBe(true);
0134         expect(results.nodes.length).toBe(2); // Only child2 and subchild2 are Meshes
0135     });
0136 
0137     it('should respect the maxLevel parameter', () => {
0138         const results = findObject3DNodes(root, '', '', 1);
0139         expect(results.deepestLevel).toBe(1);
0140         expect(results.totalWalked).toBe(3); // root, child1, child2
0141     });
0142 
0143     it('should throw an error for invalid parentNode', () => {
0144         expect(() => {
0145             findObject3DNodes(null, '');
0146         }).toThrow();
0147     });
0148 });