Skip to content

Commit e4af042

Browse files
committed
Adjust tests
1 parent 28eb74f commit e4af042

File tree

2 files changed

+48
-72
lines changed

2 files changed

+48
-72
lines changed

packages/itwin/tree-widget/src/test/trees/models-tree/internal/ModelsTreeIdsCache.test.ts

Lines changed: 19 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -5,85 +5,32 @@
55

66
import { expect } from "chai";
77
import sinon from "sinon";
8-
import { IModel, IModelReadRpcInterface } from "@itwin/core-common";
9-
import { ECSchemaRpcInterface } from "@itwin/ecschema-rpcinterface-common";
10-
import { ECSchemaRpcImpl } from "@itwin/ecschema-rpcinterface-impl";
11-
import { PresentationRpcInterface } from "@itwin/presentation-common";
128
import { createECSqlQueryExecutor } from "@itwin/presentation-core-interop";
139
import { createLimitingECSqlQueryExecutor } from "@itwin/presentation-hierarchies";
14-
import { HierarchyCacheMode, initialize as initializePresentationTesting, terminate as terminatePresentationTesting } from "@itwin/presentation-testing";
1510
import { ModelsTreeIdsCache } from "../../../../tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js";
1611
import { defaultHierarchyConfiguration } from "../../../../tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.js";
17-
import { buildIModel, insertPhysicalElement, insertPhysicalModelWithPartition, insertSpatialCategory } from "../../../IModelUtils.js";
18-
import { createIModelAccess, createIModelMock } from "../../Common.js";
19-
20-
import type { IModelConnection } from "@itwin/core-frontend";
12+
import { createIModelMock } from "../../Common.js";
2113

2214
describe("ModelsTreeIdsCache", () => {
23-
describe("#unit", () => {
24-
function createIdsCache(queryHandler: (query: string) => any[]) {
25-
const iModel = createIModelMock(queryHandler);
26-
return new ModelsTreeIdsCache(createLimitingECSqlQueryExecutor(createECSqlQueryExecutor(iModel), "unbounded"), defaultHierarchyConfiguration);
27-
}
28-
29-
it("caches category element count", async () => {
30-
const modelId = "0x1";
31-
const categoryId = "0x2";
32-
const elementIds = ["0x10", "0x20", "0x30"];
33-
const stub = sinon.fake((query: string) => {
34-
if (query.includes(`WHERE Parent.Id IS NULL AND (Model.Id = ${modelId} AND Category.Id IN (${categoryId}))`)) {
35-
return [{ modelId, categoryId, elementsCount: elementIds.length }];
36-
}
37-
throw new Error(`Unexpected query: ${query}`);
38-
});
39-
using cache = createIdsCache(stub);
40-
await expect(cache.getCategoryElementsCount(modelId, categoryId)).to.eventually.eq(elementIds.length);
41-
expect(stub).to.have.callCount(1);
42-
await expect(cache.getCategoryElementsCount(modelId, categoryId)).to.eventually.eq(elementIds.length);
43-
expect(stub).to.have.callCount(1);
44-
});
45-
});
46-
47-
describe("#integration", () => {
48-
before(async () => {
49-
await initializePresentationTesting({
50-
backendProps: {
51-
caching: {
52-
hierarchies: {
53-
mode: HierarchyCacheMode.Memory,
54-
},
55-
},
56-
},
57-
rpcs: [IModelReadRpcInterface, PresentationRpcInterface, ECSchemaRpcInterface],
58-
});
59-
// eslint-disable-next-line @itwin/no-internal
60-
ECSchemaRpcImpl.register();
61-
});
62-
63-
after(async () => {
64-
await terminatePresentationTesting();
65-
});
66-
67-
function createIdsCache(props: { imodel: IModelConnection }) {
68-
const idsCache = new ModelsTreeIdsCache(createIModelAccess(props.imodel), defaultHierarchyConfiguration);
69-
return idsCache;
70-
}
71-
72-
it("Does not throw with many requests to `idsCache.getCategoryElementsCount`", async function () {
73-
await using buildIModelResult = await buildIModel(this, async (builder) => {
74-
const categoryId = insertSpatialCategory({ builder, codeValue: "category" }).id;
75-
const modelId = insertPhysicalModelWithPartition({ builder, partitionParentId: IModel.rootSubjectId, codeValue: "1" }).id;
76-
insertPhysicalElement({ builder, modelId, categoryId });
77-
return { categoryId, modelId };
78-
});
79-
80-
const { imodel, ...keys } = buildIModelResult;
81-
using idsCache = createIdsCache({ imodel });
82-
const promiseToAwait = idsCache.getCategoryElementsCount(keys.modelId, keys.categoryId);
83-
for (let i = 0; i < 5000; ++i) {
84-
void idsCache.getCategoryElementsCount(`0x${i}`, `0x${i}`);
15+
function createIdsCache(queryHandler: (query: string) => any[]) {
16+
const iModel = createIModelMock(queryHandler);
17+
return new ModelsTreeIdsCache(createLimitingECSqlQueryExecutor(createECSqlQueryExecutor(iModel), "unbounded"), defaultHierarchyConfiguration);
18+
}
19+
20+
it("caches category element count", async () => {
21+
const modelId = "0x1";
22+
const categoryId = "0x2";
23+
const elementIds = ["0x10", "0x20", "0x30"];
24+
const stub = sinon.fake((query: string) => {
25+
if (query.includes(`WHERE Parent.Id IS NULL AND (Model.Id = ${modelId} AND Category.Id IN (${categoryId}))`)) {
26+
return [{ modelId, categoryId, elementsCount: elementIds.length }];
8527
}
86-
await promiseToAwait;
28+
throw new Error(`Unexpected query: ${query}`);
8729
});
30+
using cache = createIdsCache(stub);
31+
await expect(cache.getCategoryElementsCount(modelId, categoryId)).to.eventually.eq(elementIds.length);
32+
expect(stub).to.have.callCount(1);
33+
await expect(cache.getCategoryElementsCount(modelId, categoryId)).to.eventually.eq(elementIds.length);
34+
expect(stub).to.have.callCount(1);
8835
});
8936
});

packages/itwin/tree-widget/src/test/trees/models-tree/internal/ModelsTreeVisibilityHandler.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,6 +2196,35 @@ describe("ModelsTreeVisibilityHandler", () => {
21962196
});
21972197
});
21982198

2199+
it("validates visibility for large iModel", async function () {
2200+
await using buildIModelResult = await buildIModel(this, async (builder) => {
2201+
const modelsToTurnOn = new Array<string>();
2202+
let elementId = "";
2203+
for (let i = 0; i < 3; ++i) {
2204+
const model = insertPhysicalModelWithPartition({ builder, partitionParentId: IModel.rootSubjectId, codeValue: `model${i}` }).id;
2205+
modelsToTurnOn.push(model);
2206+
for (let j = 0; j < 1000; ++j) {
2207+
const categoryId = insertSpatialCategory({ builder, codeValue: `category${i}-${j}` }).id;
2208+
elementId = insertPhysicalElement({ builder, modelId: model, categoryId }).id;
2209+
}
2210+
}
2211+
return { modelsToTurnOn, elementId };
2212+
});
2213+
2214+
const { imodel, ...ids } = buildIModelResult;
2215+
using visibilityTestData = createVisibilityTestData({ imodel });
2216+
const { handler, provider, viewport } = visibilityTestData;
2217+
await Promise.all(ids.modelsToTurnOn.map(async (modelId) => handler.changeVisibility(createModelHierarchyNode(modelId), true)));
2218+
viewport.setAlwaysDrawn(new Set([ids.elementId]));
2219+
viewport.renderFrame();
2220+
await validateHierarchyVisibility({
2221+
provider,
2222+
handler,
2223+
viewport,
2224+
visibilityExpectations: VisibilityExpectations.all("visible"),
2225+
});
2226+
});
2227+
21992228
it("showing model makes it, all its categories and elements visible and doesn't affect other models", async function () {
22002229
await using buildIModelResult = await buildIModel(this, async (builder) => {
22012230
const categoryId = insertSpatialCategory({ builder, codeValue: "category" }).id;

0 commit comments

Comments
 (0)