/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import assert from 'node:assert/strict'; import { describe, it } from 'node:test'; import type { DataModel } from '@ifc-lite/server-client'; import { IfcTypeEnum, RelationshipType } from '@ifc-lite/data'; import { convertServerDataModel, type ServerParseResult } from './serverDataModel'; const parseResult: ServerParseResult = { cache_key: 'test', metadata: { schema_version: 'IFC4X3', }, stats: { total_time_ms: 1, parse_time_ms: 1, geometry_time_ms: 0, total_vertices: 0, total_triangles: 0, }, }; describe('convertServerDataModel', () => { it('preserves IFC4.3 facility-part hierarchies from server spatial data', () => { const dataModel: DataModel = { entities: new Map([ [1, { entity_id: 1, type_name: 'IFCPROJECT', global_id: '0', name: 'Infra Project', has_geometry: false }], [2, { entity_id: 2, type_name: 'IFCBRIDGE', global_id: '1', name: 'Bridge A', has_geometry: false }], [3, { entity_id: 3, type_name: 'IFCBRIDGEPART', global_id: '2', name: 'Deck', has_geometry: false }], [4, { entity_id: 4, type_name: 'IFCWALL', global_id: '3', name: 'Barrier', has_geometry: true }], ]), propertySets: new Map(), quantitySets: new Map(), relationships: [ { rel_type: 'IFCRELAGGREGATES', relating_id: 1, related_id: 2 }, { rel_type: 'IFCRELAGGREGATES', relating_id: 2, related_id: 3 }, { rel_type: 'IFCRELCONTAINEDINSPATIALSTRUCTURE', relating_id: 3, related_id: 4 }, ], classifications: [], materials: [], documents: [], spatialHierarchy: { nodes: [ { entity_id: 1, parent_id: 0, level: 0, path: 'Infra Project', type_name: 'IFCPROJECT', name: 'Infra Project', children_ids: [2], element_ids: [], }, { entity_id: 2, parent_id: 1, level: 1, path: 'Infra Project/Bridge A', type_name: 'IFCBRIDGE', name: 'Bridge A', children_ids: [3], element_ids: [], }, { entity_id: 3, parent_id: 2, level: 2, path: 'Infra Project/Bridge A/Deck', type_name: 'IFCBRIDGEPART', name: 'Deck', children_ids: [], element_ids: [4], }, ], project_id: 1, element_to_storey: new Map(), element_to_building: new Map([[4, 2]]), element_to_site: new Map(), element_to_space: new Map(), }, }; const dataStore = convertServerDataModel(dataModel, parseResult, { size: 1 }, []); assert.equal(dataStore.spatialHierarchy?.project.children[0].type, IfcTypeEnum.IfcBridge); assert.equal(dataStore.spatialHierarchy?.project.children[0].children[0].type, IfcTypeEnum.IfcBridgePart); assert.deepEqual(dataStore.spatialHierarchy?.project.children[0].children[0].elements, [4]); assert.deepEqual(dataStore.spatialHierarchy?.getPath(4).map((node) => node.expressId), [1, 2, 3]); assert.deepEqual(dataStore.spatialHierarchy?.byBuilding.get(2), []); }); it('uses the canonical parser relationship map for server relationships', () => { const dataModel: DataModel = { entities: new Map([ [1, { entity_id: 1, type_name: 'IFCPROJECT', global_id: '0', name: 'Project', has_geometry: false }], [2, { entity_id: 2, type_name: 'IFCBUILDING', global_id: '1', name: 'Building', has_geometry: false }], [3, { entity_id: 3, type_name: 'IFCDOCUMENTREFERENCE', global_id: '', name: 'Spec', has_geometry: false }], ]), propertySets: new Map(), quantitySets: new Map(), relationships: [ { rel_type: 'IFCRELNESTS', relating_id: 1, related_id: 2 }, { rel_type: 'IFCRELASSOCIATESDOCUMENT', relating_id: 3, related_id: 2 }, ], classifications: [], materials: [], documents: [], spatialHierarchy: { nodes: [ { entity_id: 1, parent_id: 0, level: 0, path: 'Project', type_name: 'IFCPROJECT', name: 'Project', children_ids: [2], element_ids: [], }, { entity_id: 2, parent_id: 1, level: 1, path: 'Project/Building', type_name: 'IFCBUILDING', name: 'Building', children_ids: [], element_ids: [], }, ], project_id: 1, element_to_storey: new Map(), element_to_building: new Map(), element_to_site: new Map(), element_to_space: new Map(), }, }; const dataStore = convertServerDataModel(dataModel, parseResult, { size: 1 }, []); assert.deepEqual(dataStore.relationships.getRelated(1, RelationshipType.Aggregates, 'forward'), [2]); assert.deepEqual(dataStore.relationships.getRelated(3, RelationshipType.AssociatesDocument, 'forward'), [2]); }); });