@itwin/core-backend
Version:
iTwin.js backend components
208 lines • 17.5 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import { assert } from "chai";
import * as path from "path";
import { Id64 } from "@itwin/core-bentley";
import { Point3d } from "@itwin/core-geometry";
import { IModel } from "@itwin/core-common";
import { CategorySelector, DisplayStyle2d, DisplayStyle3d, DrawingCategory, DrawingViewDefinition, GeometryPart, IModelJsFs, InformationPartitionElement, ModelSelector, OrthographicViewDefinition, RenderMaterialElement, SnapshotDb, SpatialCategory, SubCategory, Subject, Texture, } from "../../core-backend";
import { ExtensiveTestScenario, IModelTestUtils } from "../IModelTestUtils";
import { KnownTestLocations } from "../KnownTestLocations";
describe("DeleteDefinitionElements", () => {
const outputDir = path.join(KnownTestLocations.outputDir, "DeleteDefinitionElements");
before(async () => {
if (!IModelJsFs.existsSync(KnownTestLocations.outputDir)) {
IModelJsFs.mkdirSync(KnownTestLocations.outputDir);
}
if (!IModelJsFs.existsSync(outputDir)) {
IModelJsFs.mkdirSync(outputDir);
}
});
it("should delete if not used", async () => {
const iModelFile = IModelTestUtils.prepareOutputFile("DeleteDefinitionElements", "DeleteDefinitionElements.bim");
const iModelDb = SnapshotDb.createEmpty(iModelFile, { rootSubject: { name: "DeleteDefinitionElements" } });
await ExtensiveTestScenario.prepareDb(iModelDb);
await ExtensiveTestScenario.populateDb(iModelDb);
// Get ElementIds of DefinitionElements created by populateDb
const subjectId = iModelDb.elements.queryElementIdByCode(Subject.createCode(iModelDb, IModel.rootSubjectId, "Subject"));
const definitionModelId = iModelDb.elements.queryElementIdByCode(InformationPartitionElement.createCode(iModelDb, subjectId, "Definition"));
const spatialCategoryId = iModelDb.elements.queryElementIdByCode(SpatialCategory.createCode(iModelDb, definitionModelId, "SpatialCategory"));
const subCategoryId = iModelDb.elements.queryElementIdByCode(SubCategory.createCode(iModelDb, spatialCategoryId, "SubCategory"));
const spatialCategorySelectorId = iModelDb.elements.queryElementIdByCode(CategorySelector.createCode(iModelDb, definitionModelId, "SpatialCategories"));
const modelSelectorId = iModelDb.elements.queryElementIdByCode(ModelSelector.createCode(iModelDb, definitionModelId, "SpatialModels"));
const displayStyle3dId = iModelDb.elements.queryElementIdByCode(DisplayStyle3d.createCode(iModelDb, definitionModelId, "DisplayStyle3d"));
const viewId = iModelDb.elements.queryElementIdByCode(OrthographicViewDefinition.createCode(iModelDb, definitionModelId, "Orthographic View"));
const drawingCategoryId = iModelDb.elements.queryElementIdByCode(DrawingCategory.createCode(iModelDb, definitionModelId, "DrawingCategory"));
const drawingCategorySelectorId = iModelDb.elements.queryElementIdByCode(CategorySelector.createCode(iModelDb, definitionModelId, "DrawingCategories"));
const displayStyle2dId = iModelDb.elements.queryElementIdByCode(DisplayStyle2d.createCode(iModelDb, definitionModelId, "DisplayStyle2d"));
const drawingViewId = iModelDb.elements.queryElementIdByCode(DrawingViewDefinition.createCode(iModelDb, definitionModelId, "Drawing View"));
const geometryPartId = iModelDb.elements.queryElementIdByCode(GeometryPart.createCode(iModelDb, definitionModelId, "GeometryPart"));
const renderMaterialId = iModelDb.elements.queryElementIdByCode(RenderMaterialElement.createCode(iModelDb, definitionModelId, "RenderMaterial"));
const textureId = iModelDb.elements.queryElementIdByCode(Texture.createCode(iModelDb, definitionModelId, "Texture"));
const physicalObjectId1 = IModelTestUtils.queryByUserLabel(iModelDb, "PhysicalObject1");
const physicalObjectId2 = IModelTestUtils.queryByUserLabel(iModelDb, "PhysicalObject2");
const physicalObjectId3 = IModelTestUtils.queryByUserLabel(iModelDb, "PhysicalObject3");
assert.isTrue(Id64.isValidId64(spatialCategoryId));
assert.isTrue(Id64.isValidId64(subCategoryId));
assert.isTrue(Id64.isValidId64(spatialCategorySelectorId));
assert.isTrue(Id64.isValidId64(modelSelectorId));
assert.isTrue(Id64.isValidId64(displayStyle3dId));
assert.isTrue(Id64.isValidId64(viewId));
assert.isTrue(Id64.isValidId64(drawingCategoryId));
assert.isTrue(Id64.isValidId64(drawingCategorySelectorId));
assert.isTrue(Id64.isValidId64(displayStyle2dId));
assert.isTrue(Id64.isValidId64(drawingViewId));
assert.isTrue(Id64.isValidId64(geometryPartId));
assert.isTrue(Id64.isValidId64(renderMaterialId));
assert.isTrue(Id64.isValidId64(textureId));
assert.isTrue(Id64.isValidId64(physicalObjectId1));
assert.isTrue(Id64.isValidId64(physicalObjectId2));
assert.isTrue(Id64.isValidId64(physicalObjectId3));
let usedDefinitionElementIds;
// make sure deleteDefinitionElements skips Elements that are not DefinitionElements
usedDefinitionElementIds = iModelDb.elements.deleteDefinitionElements([physicalObjectId1, physicalObjectId2, physicalObjectId3, subjectId]);
assert.equal(usedDefinitionElementIds.size, 0);
assert.isDefined(iModelDb.elements.tryGetElement(physicalObjectId1));
assert.isDefined(iModelDb.elements.tryGetElement(physicalObjectId2));
assert.isDefined(iModelDb.elements.tryGetElement(physicalObjectId3));
assert.isDefined(iModelDb.elements.tryGetElement(subjectId));
// make sure deleteDefinitionElements skips invalid Ids
usedDefinitionElementIds = iModelDb.elements.deleteDefinitionElements([Id64.invalid, Id64.invalid]);
assert.equal(usedDefinitionElementIds.size, 0);
// delete/deleteDefinitionElements for a used GeometryPart should fail
assert.throws(() => iModelDb.elements.deleteElement(geometryPartId));
usedDefinitionElementIds = iModelDb.elements.deleteDefinitionElements([geometryPartId]);
assert.isTrue(usedDefinitionElementIds.has(geometryPartId));
assert.isDefined(iModelDb.elements.tryGetElement(geometryPartId));
// deleteDefinitionElements for an unused GeometryPart should succeed, delete should still fail
const unusedGeometryPartProps = {
classFullName: GeometryPart.classFullName,
model: definitionModelId,
code: GeometryPart.createCode(iModelDb, definitionModelId, "Unused GeometryPart"),
geom: IModelTestUtils.createBox(Point3d.create(1, 1, 1)),
};
const unusedGeometryPartId = iModelDb.elements.insertElement(unusedGeometryPartProps);
assert.isTrue(Id64.isValidId64(unusedGeometryPartId));
assert.throws(() => iModelDb.elements.deleteElement(unusedGeometryPartId));
usedDefinitionElementIds = iModelDb.elements.deleteDefinitionElements([unusedGeometryPartId]);
assert.equal(usedDefinitionElementIds.size, 0);
assert.isUndefined(iModelDb.elements.tryGetElement(unusedGeometryPartId));
// delete/deleteDefinitionElements for a used RenderMaterial should fail
assert.throws(() => iModelDb.elements.deleteElement(renderMaterialId));
usedDefinitionElementIds = iModelDb.elements.deleteDefinitionElements([renderMaterialId]);
assert.isTrue(usedDefinitionElementIds.has(renderMaterialId));
assert.isDefined(iModelDb.elements.tryGetElement(renderMaterialId));
// deleteDefinitionElements for an unused RenderMaterial should succeed, delete should still fail
const unusedRenderMaterialId = RenderMaterialElement.insert(iModelDb, definitionModelId, "Unused RenderMaterial", { paletteName: "PaletteName" });
assert.isTrue(Id64.isValidId64(unusedRenderMaterialId));
assert.throws(() => iModelDb.elements.deleteElement(unusedRenderMaterialId));
usedDefinitionElementIds = iModelDb.elements.deleteDefinitionElements([unusedRenderMaterialId]);
assert.equal(usedDefinitionElementIds.size, 0);
assert.isUndefined(iModelDb.elements.tryGetElement(unusedRenderMaterialId));
// delete/deleteDefinitionElements for a used Texture should fail
assert.throws(() => iModelDb.elements.deleteElement(textureId));
usedDefinitionElementIds = iModelDb.elements.deleteDefinitionElements([textureId]);
assert.isTrue(usedDefinitionElementIds.has(textureId));
assert.isDefined(iModelDb.elements.tryGetElement(textureId));
// deleteDefinitionElements for an unused Texture should succeed, delete should still fail
const unusedTextureId = IModelTestUtils.insertTextureElement(iModelDb, definitionModelId, "Unused Texture");
assert.isTrue(Id64.isValidId64(unusedTextureId));
assert.throws(() => iModelDb.elements.deleteElement(unusedTextureId));
usedDefinitionElementIds = iModelDb.elements.deleteDefinitionElements([unusedTextureId]);
assert.equal(usedDefinitionElementIds.size, 0);
assert.isUndefined(iModelDb.elements.tryGetElement(unusedTextureId));
// delete/deleteDefinitionElements for a used SpatialCategory should fail
assert.throws(() => iModelDb.elements.deleteElement(spatialCategoryId));
usedDefinitionElementIds = iModelDb.elements.deleteDefinitionElements([spatialCategoryId]);
assert.isTrue(usedDefinitionElementIds.has(spatialCategoryId));
assert.isDefined(iModelDb.elements.tryGetElement(spatialCategoryId));
// delete/deleteDefinitionElements for a default SubCategory should fail
const spatialCategory = iModelDb.elements.getElement(spatialCategoryId, SpatialCategory);
const defaultSpatialSubCategoryId = spatialCategory.myDefaultSubCategoryId();
assert.throws(() => iModelDb.elements.deleteElement(defaultSpatialSubCategoryId));
usedDefinitionElementIds = iModelDb.elements.deleteDefinitionElements([defaultSpatialSubCategoryId]);
assert.isTrue(usedDefinitionElementIds.has(defaultSpatialSubCategoryId));
assert.isDefined(iModelDb.elements.tryGetElement(defaultSpatialSubCategoryId));
// delete/deleteDefinitionElements for a used, non-default SubCategory should fail
assert.throws(() => iModelDb.elements.deleteElement(subCategoryId));
usedDefinitionElementIds = iModelDb.elements.deleteDefinitionElements([subCategoryId]);
assert.isTrue(usedDefinitionElementIds.has(subCategoryId));
assert.isDefined(iModelDb.elements.tryGetElement(subCategoryId));
// deleteDefinitionElements for an unused SubCategory should succeed, delete should still fail
const unusedSubCategoryId = SubCategory.insert(iModelDb, spatialCategoryId, "Unused SubCategory", {});
assert.isTrue(Id64.isValidId64(unusedSubCategoryId));
assert.throws(() => iModelDb.elements.deleteElement(unusedSubCategoryId));
usedDefinitionElementIds = iModelDb.elements.deleteDefinitionElements([unusedSubCategoryId]);
assert.equal(usedDefinitionElementIds.size, 0);
assert.isUndefined(iModelDb.elements.tryGetElement(unusedSubCategoryId));
// deleteDefinitionElements for an unused SpatialCategory should succeed, delete should still fail
const unusedSpatialCategoryId = SpatialCategory.insert(iModelDb, definitionModelId, "Unused SpatialCategory", {});
assert.isTrue(Id64.isValidId64(unusedSpatialCategoryId));
const unusedSpatialCategory = iModelDb.elements.getElement(unusedSpatialCategoryId, SpatialCategory);
const unusedSpatialCategoryDefaultSubCategoryId = unusedSpatialCategory.myDefaultSubCategoryId();
assert.isTrue(Id64.isValidId64(unusedSpatialCategoryDefaultSubCategoryId));
assert.throws(() => iModelDb.elements.deleteElement(unusedSpatialCategoryId));
assert.throws(() => iModelDb.elements.deleteElement(unusedSpatialCategoryDefaultSubCategoryId));
usedDefinitionElementIds = iModelDb.elements.deleteDefinitionElements([unusedSpatialCategoryId]);
assert.equal(usedDefinitionElementIds.size, 0);
assert.isUndefined(iModelDb.elements.tryGetElement(unusedSpatialCategoryId));
assert.isUndefined(iModelDb.elements.tryGetElement(unusedSpatialCategoryDefaultSubCategoryId));
// delete/deleteDefinitionElements of a used DrawingCategory should fail
assert.throws(() => iModelDb.elements.deleteElement(drawingCategoryId));
usedDefinitionElementIds = iModelDb.elements.deleteDefinitionElements([drawingCategoryId]);
assert.isTrue(usedDefinitionElementIds.has(drawingCategoryId));
assert.isDefined(iModelDb.elements.tryGetElement(drawingCategoryId));
// deleteDefinitionElements for an unused DrawingCategory should succeed, delete should still fail
const unusedDrawingCategoryId = DrawingCategory.insert(iModelDb, definitionModelId, "Unused DrawingCategory", {});
assert.isTrue(Id64.isValidId64(unusedDrawingCategoryId));
const unusedDrawingCategory = iModelDb.elements.getElement(unusedDrawingCategoryId, DrawingCategory);
const unusedDrawingSubCategoryId = unusedDrawingCategory.myDefaultSubCategoryId();
assert.isTrue(Id64.isValidId64(unusedDrawingSubCategoryId));
assert.throws(() => iModelDb.elements.deleteElement(unusedDrawingSubCategoryId));
usedDefinitionElementIds = iModelDb.elements.deleteDefinitionElements([unusedDrawingCategoryId]);
assert.equal(usedDefinitionElementIds.size, 0);
assert.isUndefined(iModelDb.elements.tryGetElement(unusedDrawingCategoryId));
assert.isUndefined(iModelDb.elements.tryGetElement(unusedDrawingSubCategoryId));
// delete/deleteDefinitionElements of DefinitionElements used by an existing SpatialViewDefinition should fail
assert.throws(() => iModelDb.elements.deleteElement(spatialCategorySelectorId));
assert.throws(() => iModelDb.elements.deleteElement(modelSelectorId));
assert.throws(() => iModelDb.elements.deleteElement(displayStyle3dId));
usedDefinitionElementIds = iModelDb.elements.deleteDefinitionElements([spatialCategorySelectorId, modelSelectorId, displayStyle3dId]);
assert.isTrue(usedDefinitionElementIds.has(spatialCategorySelectorId));
assert.isTrue(usedDefinitionElementIds.has(modelSelectorId));
assert.isTrue(usedDefinitionElementIds.has(displayStyle3dId));
assert.isDefined(iModelDb.elements.tryGetElement(spatialCategorySelectorId));
assert.isDefined(iModelDb.elements.tryGetElement(modelSelectorId));
assert.isDefined(iModelDb.elements.tryGetElement(displayStyle3dId));
assert.isDefined(iModelDb.elements.tryGetElement(viewId));
// deleteDefinitionElements should succeed when the list includes the SpatialViewDefinition as the only thing referencing other DefinitionElements, delete should still fail
assert.throws(() => iModelDb.elements.deleteElement(viewId));
usedDefinitionElementIds = iModelDb.elements.deleteDefinitionElements([viewId, spatialCategorySelectorId, modelSelectorId, displayStyle3dId]);
assert.equal(usedDefinitionElementIds.size, 0);
assert.isUndefined(iModelDb.elements.tryGetElement(spatialCategorySelectorId));
assert.isUndefined(iModelDb.elements.tryGetElement(modelSelectorId));
assert.isUndefined(iModelDb.elements.tryGetElement(displayStyle3dId));
assert.isUndefined(iModelDb.elements.tryGetElement(viewId));
// delete/deleteDefinitionElements of DefinitionElements used by an existing DrawingViewDefinition should fail
assert.throws(() => iModelDb.elements.deleteElement(drawingCategorySelectorId));
assert.throws(() => iModelDb.elements.deleteElement(displayStyle2dId));
usedDefinitionElementIds = iModelDb.elements.deleteDefinitionElements([drawingCategorySelectorId, displayStyle2dId]);
assert.isTrue(usedDefinitionElementIds.has(drawingCategorySelectorId));
assert.isTrue(usedDefinitionElementIds.has(displayStyle2dId));
assert.isDefined(iModelDb.elements.tryGetElement(drawingCategorySelectorId));
assert.isDefined(iModelDb.elements.tryGetElement(displayStyle2dId));
assert.isDefined(iModelDb.elements.tryGetElement(drawingViewId));
// deleteDefinitionElements should succeed when the list includes the DrawingViewDefinition as the only thing referencing other DefinitionElements, delete should still fail
assert.throws(() => iModelDb.elements.deleteElement(drawingViewId));
usedDefinitionElementIds = iModelDb.elements.deleteDefinitionElements([drawingViewId, drawingCategorySelectorId, displayStyle2dId]);
assert.equal(usedDefinitionElementIds.size, 0);
assert.isUndefined(iModelDb.elements.tryGetElement(drawingCategorySelectorId));
assert.isUndefined(iModelDb.elements.tryGetElement(displayStyle2dId));
assert.isUndefined(iModelDb.elements.tryGetElement(drawingViewId));
iModelDb.saveChanges();
iModelDb.close();
});
});
//# sourceMappingURL=DeleteDefinitionElements.test.js.map