@itwin/core-backend 5.2.0-dev.3 → 5.2.0-dev.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +79 -1
- package/lib/cjs/BackendHubAccess.d.ts +2 -0
- package/lib/cjs/BackendHubAccess.d.ts.map +1 -1
- package/lib/cjs/BackendHubAccess.js.map +1 -1
- package/lib/cjs/BackendLoggerCategory.d.ts +6 -0
- package/lib/cjs/BackendLoggerCategory.d.ts.map +1 -1
- package/lib/cjs/BackendLoggerCategory.js +6 -0
- package/lib/cjs/BackendLoggerCategory.js.map +1 -1
- package/lib/cjs/BriefcaseManager.d.ts +57 -3
- package/lib/cjs/BriefcaseManager.d.ts.map +1 -1
- package/lib/cjs/BriefcaseManager.js +153 -44
- package/lib/cjs/BriefcaseManager.js.map +1 -1
- package/lib/cjs/ClassRegistry.js +2 -2
- package/lib/cjs/ClassRegistry.js.map +1 -1
- package/lib/cjs/CloudSqlite.d.ts +4 -0
- package/lib/cjs/CloudSqlite.d.ts.map +1 -1
- package/lib/cjs/CloudSqlite.js.map +1 -1
- package/lib/cjs/ECDb.d.ts +8 -0
- package/lib/cjs/ECDb.d.ts.map +1 -1
- package/lib/cjs/ECDb.js +22 -0
- package/lib/cjs/ECDb.js.map +1 -1
- package/lib/cjs/IModelDb.d.ts +54 -3
- package/lib/cjs/IModelDb.d.ts.map +1 -1
- package/lib/cjs/IModelDb.js +88 -10
- package/lib/cjs/IModelDb.js.map +1 -1
- package/lib/cjs/IModelHost.d.ts +11 -1
- package/lib/cjs/IModelHost.d.ts.map +1 -1
- package/lib/cjs/IModelHost.js +5 -0
- package/lib/cjs/IModelHost.js.map +1 -1
- package/lib/cjs/IModelIncrementalSchemaLocater.d.ts +1 -5
- package/lib/cjs/IModelIncrementalSchemaLocater.d.ts.map +1 -1
- package/lib/cjs/IModelIncrementalSchemaLocater.js +0 -6
- package/lib/cjs/IModelIncrementalSchemaLocater.js.map +1 -1
- package/lib/cjs/StashManager.d.ts +175 -0
- package/lib/cjs/StashManager.d.ts.map +1 -0
- package/lib/cjs/StashManager.js +306 -0
- package/lib/cjs/StashManager.js.map +1 -0
- package/lib/cjs/TxnManager.d.ts +226 -15
- package/lib/cjs/TxnManager.d.ts.map +1 -1
- package/lib/cjs/TxnManager.js +249 -23
- package/lib/cjs/TxnManager.js.map +1 -1
- package/lib/cjs/annotations/ElementDrivesTextAnnotation.d.ts +10 -1
- package/lib/cjs/annotations/ElementDrivesTextAnnotation.d.ts.map +1 -1
- package/lib/cjs/annotations/ElementDrivesTextAnnotation.js +12 -1
- package/lib/cjs/annotations/ElementDrivesTextAnnotation.js.map +1 -1
- package/lib/cjs/annotations/LeaderGeometry.d.ts +3 -2
- package/lib/cjs/annotations/LeaderGeometry.d.ts.map +1 -1
- package/lib/cjs/annotations/LeaderGeometry.js +4 -3
- package/lib/cjs/annotations/LeaderGeometry.js.map +1 -1
- package/lib/cjs/annotations/TextAnnotationElement.d.ts +52 -24
- package/lib/cjs/annotations/TextAnnotationElement.d.ts.map +1 -1
- package/lib/cjs/annotations/TextAnnotationElement.js +49 -59
- package/lib/cjs/annotations/TextAnnotationElement.js.map +1 -1
- package/lib/cjs/annotations/TextAnnotationGeometry.d.ts +2 -0
- package/lib/cjs/annotations/TextAnnotationGeometry.d.ts.map +1 -1
- package/lib/cjs/annotations/TextAnnotationGeometry.js +2 -2
- package/lib/cjs/annotations/TextAnnotationGeometry.js.map +1 -1
- package/lib/cjs/annotations/TextBlockLayout.d.ts +3 -9
- package/lib/cjs/annotations/TextBlockLayout.d.ts.map +1 -1
- package/lib/cjs/annotations/TextBlockLayout.js +3 -22
- package/lib/cjs/annotations/TextBlockLayout.js.map +1 -1
- package/lib/cjs/internal/ChannelAdmin.js +1 -1
- package/lib/cjs/internal/ChannelAdmin.js.map +1 -1
- package/lib/cjs/internal/Symbols.d.ts +1 -0
- package/lib/cjs/internal/Symbols.d.ts.map +1 -1
- package/lib/cjs/internal/Symbols.js +2 -1
- package/lib/cjs/internal/Symbols.js.map +1 -1
- package/lib/cjs/internal/annotations/fields.d.ts +2 -12
- package/lib/cjs/internal/annotations/fields.d.ts.map +1 -1
- package/lib/cjs/internal/annotations/fields.js +47 -40
- package/lib/cjs/internal/annotations/fields.js.map +1 -1
- package/lib/cjs/internal/workspace/SettingsImpl.js +1 -1
- package/lib/cjs/internal/workspace/SettingsImpl.js.map +1 -1
- package/lib/cjs/internal/workspace/SettingsSchemasImpl.js +2 -2
- package/lib/cjs/internal/workspace/SettingsSchemasImpl.js.map +1 -1
- package/lib/cjs/workspace/Workspace.d.ts +1 -1
- package/lib/cjs/workspace/Workspace.js.map +1 -1
- package/lib/esm/BackendHubAccess.d.ts +2 -0
- package/lib/esm/BackendHubAccess.d.ts.map +1 -1
- package/lib/esm/BackendHubAccess.js.map +1 -1
- package/lib/esm/BackendLoggerCategory.d.ts +6 -0
- package/lib/esm/BackendLoggerCategory.d.ts.map +1 -1
- package/lib/esm/BackendLoggerCategory.js +6 -0
- package/lib/esm/BackendLoggerCategory.js.map +1 -1
- package/lib/esm/BriefcaseManager.d.ts +57 -3
- package/lib/esm/BriefcaseManager.d.ts.map +1 -1
- package/lib/esm/BriefcaseManager.js +154 -45
- package/lib/esm/BriefcaseManager.js.map +1 -1
- package/lib/esm/ClassRegistry.js +2 -2
- package/lib/esm/ClassRegistry.js.map +1 -1
- package/lib/esm/CloudSqlite.d.ts +4 -0
- package/lib/esm/CloudSqlite.d.ts.map +1 -1
- package/lib/esm/CloudSqlite.js.map +1 -1
- package/lib/esm/ECDb.d.ts +8 -0
- package/lib/esm/ECDb.d.ts.map +1 -1
- package/lib/esm/ECDb.js +22 -0
- package/lib/esm/ECDb.js.map +1 -1
- package/lib/esm/IModelDb.d.ts +54 -3
- package/lib/esm/IModelDb.d.ts.map +1 -1
- package/lib/esm/IModelDb.js +89 -11
- package/lib/esm/IModelDb.js.map +1 -1
- package/lib/esm/IModelHost.d.ts +11 -1
- package/lib/esm/IModelHost.d.ts.map +1 -1
- package/lib/esm/IModelHost.js +5 -0
- package/lib/esm/IModelHost.js.map +1 -1
- package/lib/esm/IModelIncrementalSchemaLocater.d.ts +1 -5
- package/lib/esm/IModelIncrementalSchemaLocater.d.ts.map +1 -1
- package/lib/esm/IModelIncrementalSchemaLocater.js +0 -6
- package/lib/esm/IModelIncrementalSchemaLocater.js.map +1 -1
- package/lib/esm/StashManager.d.ts +175 -0
- package/lib/esm/StashManager.d.ts.map +1 -0
- package/lib/esm/StashManager.js +301 -0
- package/lib/esm/StashManager.js.map +1 -0
- package/lib/esm/TxnManager.d.ts +226 -15
- package/lib/esm/TxnManager.d.ts.map +1 -1
- package/lib/esm/TxnManager.js +247 -21
- package/lib/esm/TxnManager.js.map +1 -1
- package/lib/esm/annotations/ElementDrivesTextAnnotation.d.ts +10 -1
- package/lib/esm/annotations/ElementDrivesTextAnnotation.d.ts.map +1 -1
- package/lib/esm/annotations/ElementDrivesTextAnnotation.js +10 -0
- package/lib/esm/annotations/ElementDrivesTextAnnotation.js.map +1 -1
- package/lib/esm/annotations/LeaderGeometry.d.ts +3 -2
- package/lib/esm/annotations/LeaderGeometry.d.ts.map +1 -1
- package/lib/esm/annotations/LeaderGeometry.js +4 -3
- package/lib/esm/annotations/LeaderGeometry.js.map +1 -1
- package/lib/esm/annotations/TextAnnotationElement.d.ts +52 -24
- package/lib/esm/annotations/TextAnnotationElement.d.ts.map +1 -1
- package/lib/esm/annotations/TextAnnotationElement.js +51 -61
- package/lib/esm/annotations/TextAnnotationElement.js.map +1 -1
- package/lib/esm/annotations/TextAnnotationGeometry.d.ts +2 -0
- package/lib/esm/annotations/TextAnnotationGeometry.d.ts.map +1 -1
- package/lib/esm/annotations/TextAnnotationGeometry.js +2 -2
- package/lib/esm/annotations/TextAnnotationGeometry.js.map +1 -1
- package/lib/esm/annotations/TextBlockLayout.d.ts +3 -9
- package/lib/esm/annotations/TextBlockLayout.d.ts.map +1 -1
- package/lib/esm/annotations/TextBlockLayout.js +3 -22
- package/lib/esm/annotations/TextBlockLayout.js.map +1 -1
- package/lib/esm/internal/ChannelAdmin.js +1 -1
- package/lib/esm/internal/ChannelAdmin.js.map +1 -1
- package/lib/esm/internal/Symbols.d.ts +1 -0
- package/lib/esm/internal/Symbols.d.ts.map +1 -1
- package/lib/esm/internal/Symbols.js +1 -0
- package/lib/esm/internal/Symbols.js.map +1 -1
- package/lib/esm/internal/annotations/fields.d.ts +2 -12
- package/lib/esm/internal/annotations/fields.d.ts.map +1 -1
- package/lib/esm/internal/annotations/fields.js +50 -43
- package/lib/esm/internal/annotations/fields.js.map +1 -1
- package/lib/esm/internal/workspace/SettingsImpl.js +1 -1
- package/lib/esm/internal/workspace/SettingsImpl.js.map +1 -1
- package/lib/esm/internal/workspace/SettingsSchemasImpl.js +2 -2
- package/lib/esm/internal/workspace/SettingsSchemasImpl.js.map +1 -1
- package/lib/esm/test/AnnotationTestUtils.d.ts +5 -1
- package/lib/esm/test/AnnotationTestUtils.d.ts.map +1 -1
- package/lib/esm/test/AnnotationTestUtils.js +6 -1
- package/lib/esm/test/AnnotationTestUtils.js.map +1 -1
- package/lib/esm/test/annotations/Fields.test.js +158 -43
- package/lib/esm/test/annotations/Fields.test.js.map +1 -1
- package/lib/esm/test/annotations/LeaderGeometry.test.js +12 -10
- package/lib/esm/test/annotations/LeaderGeometry.test.js.map +1 -1
- package/lib/esm/test/annotations/TextAnnotation.test.js +299 -43
- package/lib/esm/test/annotations/TextAnnotation.test.js.map +1 -1
- package/lib/esm/test/annotations/TextBlock.test.js +39 -35
- package/lib/esm/test/annotations/TextBlock.test.js.map +1 -1
- package/lib/esm/test/assets/IncrementalSchemaLocater/configs/simple.config.d.ts +46 -0
- package/lib/esm/test/assets/IncrementalSchemaLocater/configs/simple.config.d.ts.map +1 -1
- package/lib/esm/test/assets/IncrementalSchemaLocater/configs/simple.config.js +20 -2
- package/lib/esm/test/assets/IncrementalSchemaLocater/configs/simple.config.js.map +1 -1
- package/lib/esm/test/ecdb/ECDb.test.js +71 -1
- package/lib/esm/test/ecdb/ECDb.test.js.map +1 -1
- package/lib/esm/test/ecsql/dataset/ECSqlDatasets.d.ts.map +1 -1
- package/lib/esm/test/ecsql/dataset/ECSqlDatasets.js +8 -2
- package/lib/esm/test/ecsql/dataset/ECSqlDatasets.js.map +1 -1
- package/lib/esm/test/hubaccess/Rebase.test.d.ts +2 -0
- package/lib/esm/test/hubaccess/Rebase.test.d.ts.map +1 -0
- package/lib/esm/test/hubaccess/Rebase.test.js +640 -0
- package/lib/esm/test/hubaccess/Rebase.test.js.map +1 -0
- package/lib/esm/test/incrementalSchemaLocater/ECSqlQueries.test.js +20 -20
- package/lib/esm/test/incrementalSchemaLocater/ECSqlQueries.test.js.map +1 -1
- package/lib/esm/test/incrementalSchemaLocater/IncrementalLoading.test.js +3 -3
- package/lib/esm/test/incrementalSchemaLocater/IncrementalLoading.test.js.map +1 -1
- package/lib/esm/test/incrementalSchemaLocater/utils/TestSqlSchemaLocater.d.ts +16 -1
- package/lib/esm/test/incrementalSchemaLocater/utils/TestSqlSchemaLocater.d.ts.map +1 -1
- package/lib/esm/test/incrementalSchemaLocater/utils/TestSqlSchemaLocater.js +47 -0
- package/lib/esm/test/incrementalSchemaLocater/utils/TestSqlSchemaLocater.js.map +1 -1
- package/lib/esm/test/standalone/ChangeMerge.test.js +15 -19
- package/lib/esm/test/standalone/ChangeMerge.test.js.map +1 -1
- package/lib/esm/test/standalone/MergeConflict.test.js +3 -3
- package/lib/esm/test/standalone/MergeConflict.test.js.map +1 -1
- package/lib/esm/test/standalone/NativeAppStorage.test.js +2 -2
- package/lib/esm/test/standalone/NativeAppStorage.test.js.map +1 -1
- package/lib/esm/workspace/Workspace.d.ts +1 -1
- package/lib/esm/workspace/Workspace.js.map +1 -1
- package/package.json +14 -14
|
@@ -7,14 +7,20 @@ import { Code, FieldRun, SubCategoryAppearance, TextAnnotation, TextBlock, TextR
|
|
|
7
7
|
import { StandaloneDb } from "../../IModelDb";
|
|
8
8
|
import { IModelTestUtils } from "../IModelTestUtils";
|
|
9
9
|
import { createUpdateContext, updateField, updateFields } from "../../internal/annotations/fields";
|
|
10
|
-
import { DbResult, Id64 } from "@itwin/core-bentley";
|
|
10
|
+
import { DbResult, Id64, ProcessDetector } from "@itwin/core-bentley";
|
|
11
11
|
import { SpatialCategory } from "../../Category";
|
|
12
12
|
import { Point3d, YawPitchRollAngles } from "@itwin/core-geometry";
|
|
13
13
|
import { Schema, Schemas } from "../../Schema";
|
|
14
14
|
import { ClassRegistry } from "../../ClassRegistry";
|
|
15
15
|
import { PhysicalElement } from "../../Element";
|
|
16
16
|
import { ElementOwnsUniqueAspect, ElementUniqueAspect, FontFile, TextAnnotation3d } from "../../core-backend";
|
|
17
|
-
import { ElementDrivesTextAnnotation } from "../../annotations/ElementDrivesTextAnnotation";
|
|
17
|
+
import { ElementDrivesTextAnnotation, TextAnnotationUsesTextStyleByDefault } from "../../annotations/ElementDrivesTextAnnotation";
|
|
18
|
+
function isIntlSupported() {
|
|
19
|
+
// Node in the mobile add-on does not include Intl, so this test fails. Right now, mobile
|
|
20
|
+
// users are not expected to do any editing, but long term we will attempt to find a better
|
|
21
|
+
// solution.
|
|
22
|
+
return !ProcessDetector.isMobileAppBackend;
|
|
23
|
+
}
|
|
18
24
|
describe("updateField", () => {
|
|
19
25
|
const mockElementId = "0x1";
|
|
20
26
|
const mockPath = {
|
|
@@ -31,7 +37,7 @@ describe("updateField", () => {
|
|
|
31
37
|
propertyPath.accessors?.[0] === 0 &&
|
|
32
38
|
propertyPath.accessors?.[1] === "nestedProperty" &&
|
|
33
39
|
propertyValue !== undefined) {
|
|
34
|
-
return { value: propertyValue,
|
|
40
|
+
return { value: propertyValue, type: "string" };
|
|
35
41
|
}
|
|
36
42
|
return undefined;
|
|
37
43
|
},
|
|
@@ -102,6 +108,11 @@ const fieldsSchemaXml = `
|
|
|
102
108
|
<ECSchema schemaName="Fields" alias="ts" version="01.00.00" xmlns="http://www.bentley.com/schemas/Bentley.ECXML.3.2">
|
|
103
109
|
<ECSchemaReference name="BisCore" version="01.00.04" alias="bis"/>
|
|
104
110
|
|
|
111
|
+
<ECEnumeration typeName="IntEnum" backingTypeName="int">
|
|
112
|
+
<ECEnumerator name="one" displayLabel="One" value="1" />
|
|
113
|
+
<ECEnumerator name="two" displayLabel="Two" value="2"/>
|
|
114
|
+
</ECEnumeration>
|
|
115
|
+
|
|
105
116
|
<ECStructClass typeName="InnerStruct" modifier="None">
|
|
106
117
|
<ECProperty propertyName="bool" typeName="boolean"/>
|
|
107
118
|
<ECArrayProperty propertyName="doubles" typeName="double" minOccurs="0" maxOccurs="unbounded"/>
|
|
@@ -117,9 +128,11 @@ const fieldsSchemaXml = `
|
|
|
117
128
|
<ECProperty propertyName="intProp" typeName="int"/>
|
|
118
129
|
<ECProperty propertyName="point" typeName="point3d"/>
|
|
119
130
|
<ECProperty propertyName="maybeNull" typeName="int"/>
|
|
131
|
+
<ECProperty propertyName="datetime" typeName="dateTime"/>
|
|
120
132
|
<ECArrayProperty propertyName="strings" typeName="string" minOccurs="0" maxOccurs="unbounded"/>
|
|
121
133
|
<ECStructProperty propertyName="outerStruct" typeName="OuterStruct"/>
|
|
122
134
|
<ECStructArrayProperty propertyName="outerStructs" typeName="OuterStruct" minOccurs="0" maxOccurs="unbounded"/>
|
|
135
|
+
<ECProperty propertyName="intEnum" typeName="IntEnum"/>
|
|
123
136
|
</ECEntityClass>
|
|
124
137
|
|
|
125
138
|
<ECEntityClass typeName="TestAspect" modifier="None">
|
|
@@ -174,6 +187,8 @@ describe("Field evaluation", () => {
|
|
|
174
187
|
intProp: 100,
|
|
175
188
|
point: { x: 1, y: 2, z: 3 },
|
|
176
189
|
strings: ["a", "b", `"name": "c"`],
|
|
190
|
+
datetime: new Date("2025-08-28T13:45:30.123Z"),
|
|
191
|
+
intEnum: 1,
|
|
177
192
|
outerStruct: {
|
|
178
193
|
innerStruct: { bool: false, doubles: [1, 2, 3] },
|
|
179
194
|
innerStructs: [{ bool: true, doubles: [] }, { bool: false, doubles: [5, 4, 3, 2, 1] }],
|
|
@@ -189,6 +204,7 @@ describe("Field evaluation", () => {
|
|
|
189
204
|
jsonProperties: {
|
|
190
205
|
stringProp: "abc",
|
|
191
206
|
ints: [10, 11, 12, 13],
|
|
207
|
+
bool: true,
|
|
192
208
|
zoo: {
|
|
193
209
|
address: {
|
|
194
210
|
zipcode: 12345,
|
|
@@ -210,22 +226,27 @@ describe("Field evaluation", () => {
|
|
|
210
226
|
imodel.saveChanges();
|
|
211
227
|
return id;
|
|
212
228
|
}
|
|
229
|
+
function evaluateField(propertyPath, propertyHost, deletedDependency = false) {
|
|
230
|
+
if (typeof propertyHost === "string") {
|
|
231
|
+
propertyHost = { schemaName: "Fields", className: "TestElement", elementId: propertyHost };
|
|
232
|
+
}
|
|
233
|
+
const field = FieldRun.create({
|
|
234
|
+
propertyPath,
|
|
235
|
+
propertyHost,
|
|
236
|
+
});
|
|
237
|
+
const context = createUpdateContext(propertyHost.elementId, imodel, deletedDependency);
|
|
238
|
+
return context.getProperty(field);
|
|
239
|
+
}
|
|
213
240
|
describe("getProperty", () => {
|
|
214
241
|
function expectValue(expected, propertyPath, propertyHost, deletedDependency = false) {
|
|
215
|
-
|
|
216
|
-
propertyHost = { schemaName: "Fields", className: "TestElement", elementId: propertyHost };
|
|
217
|
-
}
|
|
218
|
-
const field = FieldRun.create({
|
|
219
|
-
propertyPath,
|
|
220
|
-
propertyHost,
|
|
221
|
-
});
|
|
222
|
-
const context = createUpdateContext(propertyHost.elementId, imodel, deletedDependency);
|
|
223
|
-
const actual = context.getProperty(field);
|
|
224
|
-
expect(actual?.value).to.deep.equal(expected);
|
|
242
|
+
expect(evaluateField(propertyPath, propertyHost, deletedDependency)?.value).to.deep.equal(expected);
|
|
225
243
|
}
|
|
226
244
|
it("returns a primitive property value", () => {
|
|
227
245
|
expectValue(100, { propertyName: "intProp" }, sourceElementId);
|
|
228
246
|
});
|
|
247
|
+
it("returns an integer enum property value", () => {
|
|
248
|
+
expectValue(1, { propertyName: "intEnum" }, sourceElementId);
|
|
249
|
+
});
|
|
229
250
|
it("treats points as primitive values", () => {
|
|
230
251
|
expectValue({ x: 1, y: 2, z: 3 }, { propertyName: "point" }, sourceElementId);
|
|
231
252
|
expectValue(undefined, { propertyName: "point", accessors: ["x"] }, sourceElementId);
|
|
@@ -284,28 +305,62 @@ describe("Field evaluation", () => {
|
|
|
284
305
|
expectValue(false, { propertyName: "outerStructs", accessors: [0, "innerStructs", -1, "bool"] }, sourceElementId);
|
|
285
306
|
expectValue(5, { propertyName: "outerStructs", accessors: [0, "innerStructs", 0, "doubles", 0] }, sourceElementId);
|
|
286
307
|
});
|
|
287
|
-
it("returns arbitrarily-nested JSON properties", () => {
|
|
288
|
-
expectValue("abc", { propertyName: "jsonProperties", jsonAccessors: ["stringProp"] }, sourceElementId);
|
|
289
|
-
expectValue(10, { propertyName: "jsonProperties", jsonAccessors: ["ints", 0] }, sourceElementId);
|
|
290
|
-
expectValue(13, { propertyName: "jsonProperties", jsonAccessors: ["ints", 3] }, sourceElementId);
|
|
291
|
-
expectValue(13, { propertyName: "jsonProperties", jsonAccessors: ["ints", -1] }, sourceElementId);
|
|
292
|
-
expectValue(11, { propertyName: "jsonProperties", jsonAccessors: ["ints", -3] }, sourceElementId);
|
|
293
|
-
expectValue(12345, { propertyName: "jsonProperties", jsonAccessors: ["zoo", "address", "zipcode"] }, sourceElementId);
|
|
294
|
-
expectValue("scree!", { propertyName: "jsonProperties", jsonAccessors: ["zoo", "birds", 1, "sound"] }, sourceElementId);
|
|
295
|
-
});
|
|
296
|
-
it("returns undefined if JSON accessors applied to non-JSON property", () => {
|
|
297
|
-
expectValue(undefined, { propertyName: "int", jsonAccessors: ["whatever"] }, sourceElementId);
|
|
298
|
-
expectValue(undefined, { propertyName: "strings", accessors: [2, "name"] }, sourceElementId);
|
|
299
|
-
expectValue(undefined, { propertyName: "outerStruct", accessors: ["innerStruct"], jsonAccessors: ["bool"] }, sourceElementId);
|
|
300
|
-
});
|
|
301
308
|
it("returns the value of a property of an aspect", () => {
|
|
302
309
|
expect(imodel.elements.getAspects(sourceElementId, "Fields:TestAspect").length).to.equal(1);
|
|
303
310
|
expectValue(999, { propertyName: "aspectProp" }, { elementId: sourceElementId, schemaName: "Fields", className: "TestAspect" });
|
|
304
311
|
});
|
|
312
|
+
it("should fail to evaluate if prop type does not match", () => {
|
|
313
|
+
const fieldRun = FieldRun.create({
|
|
314
|
+
propertyHost: { elementId: sourceElementId, schemaName: "Fields", className: "TestElement" },
|
|
315
|
+
propertyPath: { propertyName: "string", accessors: [0] },
|
|
316
|
+
cachedContent: "oldValue",
|
|
317
|
+
formatOptions: {
|
|
318
|
+
case: "upper",
|
|
319
|
+
prefix: "Value: ",
|
|
320
|
+
suffix: "!"
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
const context = createUpdateContext(sourceElementId, imodel, false);
|
|
324
|
+
const updated = updateField(fieldRun, context);
|
|
325
|
+
expect(updated).to.be.true;
|
|
326
|
+
expect(fieldRun.cachedContent).to.equal(FieldRun.invalidContentIndicator);
|
|
327
|
+
});
|
|
328
|
+
function getPropertyType(propertyHost, propertyPath) {
|
|
329
|
+
if (typeof propertyPath === "string") {
|
|
330
|
+
propertyPath = { propertyName: propertyPath };
|
|
331
|
+
}
|
|
332
|
+
return evaluateField(propertyPath, propertyHost)?.type;
|
|
333
|
+
}
|
|
334
|
+
it("deduces type for primitive properties", () => {
|
|
335
|
+
const propertyHost = { elementId: sourceElementId, schemaName: "Fields", className: "TestElement" };
|
|
336
|
+
expect(getPropertyType(propertyHost, "intProp")).to.equal("string");
|
|
337
|
+
expect(getPropertyType(propertyHost, "point")).to.equal("coordinate");
|
|
338
|
+
expect(getPropertyType(propertyHost, { propertyName: "strings", accessors: [0] })).to.equal("string");
|
|
339
|
+
expect(getPropertyType(propertyHost, "intEnum")).to.equal("int-enum");
|
|
340
|
+
expect(getPropertyType(propertyHost, { propertyName: "outerStruct", accessors: ["innerStruct", "doubles", 0] })).to.equal("quantity");
|
|
341
|
+
expect(getPropertyType(propertyHost, { propertyName: "outerStruct", accessors: ["innerStruct", "bool"] })).to.equal("boolean");
|
|
342
|
+
propertyHost.schemaName = "BisCore";
|
|
343
|
+
propertyHost.className = "GeometricElement3d";
|
|
344
|
+
expect(getPropertyType(propertyHost, "LastMod")).to.equal("datetime");
|
|
345
|
+
expect(getPropertyType(propertyHost, "FederationGuid")).to.equal("string");
|
|
346
|
+
});
|
|
347
|
+
it("returns undefined for non-primitive properties", () => {
|
|
348
|
+
const propertyHost = { elementId: sourceElementId, schemaName: "Fields", className: "TestElement" };
|
|
349
|
+
expect(getPropertyType(propertyHost, "outerStruct")).to.equal(undefined);
|
|
350
|
+
expect(getPropertyType(propertyHost, "outerStructs")).to.equal(undefined);
|
|
351
|
+
});
|
|
352
|
+
it("returns undefined for invalid property paths", () => {
|
|
353
|
+
const propertyHost = { elementId: sourceElementId, schemaName: "Fields", className: "TestElement" };
|
|
354
|
+
expect(getPropertyType(propertyHost, "unknownPropertyName")).to.be.undefined;
|
|
355
|
+
});
|
|
356
|
+
it("should return undefined for unsupported primitive types", () => {
|
|
357
|
+
const host = { elementId: sourceElementId, schemaName: "BisCore", className: "GeometricElement3d" };
|
|
358
|
+
expect(getPropertyType(host, "GeometryStream")).to.be.undefined;
|
|
359
|
+
});
|
|
305
360
|
});
|
|
306
361
|
describe("updateFields", () => {
|
|
307
362
|
it("recomputes cached content", () => {
|
|
308
|
-
const textBlock = TextBlock.create(
|
|
363
|
+
const textBlock = TextBlock.create();
|
|
309
364
|
const fieldRun = FieldRun.create({
|
|
310
365
|
propertyHost: { elementId: sourceElementId, schemaName: "Fields", className: "TestElement" },
|
|
311
366
|
propertyPath: { propertyName: "intProp" },
|
|
@@ -318,7 +373,7 @@ describe("Field evaluation", () => {
|
|
|
318
373
|
expect(fieldRun.cachedContent).to.equal("100"); // `intProp` value from the test element
|
|
319
374
|
});
|
|
320
375
|
it("does not update a field if recomputed content matches cached content", () => {
|
|
321
|
-
const textBlock = TextBlock.create(
|
|
376
|
+
const textBlock = TextBlock.create();
|
|
322
377
|
const fieldRun = FieldRun.create({
|
|
323
378
|
propertyHost: { elementId: sourceElementId, schemaName: "Fields", className: "TestElement" },
|
|
324
379
|
propertyPath: { propertyName: "intProp" },
|
|
@@ -331,7 +386,7 @@ describe("Field evaluation", () => {
|
|
|
331
386
|
expect(fieldRun.cachedContent).to.equal("100");
|
|
332
387
|
});
|
|
333
388
|
it("returns the number of fields updated", () => {
|
|
334
|
-
const textBlock = TextBlock.create(
|
|
389
|
+
const textBlock = TextBlock.create();
|
|
335
390
|
const fieldRun1 = FieldRun.create({
|
|
336
391
|
propertyHost: { elementId: sourceElementId, schemaName: "Fields", className: "TestElement" },
|
|
337
392
|
propertyPath: { propertyName: "intProp" },
|
|
@@ -361,6 +416,7 @@ describe("Field evaluation", () => {
|
|
|
361
416
|
angles: YawPitchRollAngles.createDegrees(0, 0, 0).toJSON(),
|
|
362
417
|
},
|
|
363
418
|
classFullName: TextAnnotation3d.classFullName,
|
|
419
|
+
defaultTextStyle: new TextAnnotationUsesTextStyleByDefault("0x123").toJSON(),
|
|
364
420
|
}, imodel);
|
|
365
421
|
if (textBlock) {
|
|
366
422
|
const annotation = TextAnnotation.fromJSON({ textBlock: textBlock.toJSON() });
|
|
@@ -395,7 +451,7 @@ describe("Field evaluation", () => {
|
|
|
395
451
|
expect(relationship.sourceId).to.equal(sourceElementId);
|
|
396
452
|
expect(relationship.targetId).to.equal(targetId);
|
|
397
453
|
});
|
|
398
|
-
function createField(propertyHost, cachedContent, propertyName = "intProp", accessors
|
|
454
|
+
function createField(propertyHost, cachedContent, propertyName = "intProp", accessors) {
|
|
399
455
|
if (typeof propertyHost === "string") {
|
|
400
456
|
propertyHost = { schemaName: "Fields", className: "TestElement", elementId: propertyHost };
|
|
401
457
|
}
|
|
@@ -403,13 +459,13 @@ describe("Field evaluation", () => {
|
|
|
403
459
|
styleOverrides: { fontName: "Karla" },
|
|
404
460
|
propertyHost,
|
|
405
461
|
cachedContent,
|
|
406
|
-
propertyPath: { propertyName, accessors
|
|
462
|
+
propertyPath: { propertyName, accessors },
|
|
407
463
|
});
|
|
408
464
|
}
|
|
409
465
|
describe("updateFieldDependencies", () => {
|
|
410
466
|
it("creates exactly one relationship for each unique source element on insert and update", () => {
|
|
411
467
|
const source1 = insertTestElement();
|
|
412
|
-
const block = TextBlock.create(
|
|
468
|
+
const block = TextBlock.create();
|
|
413
469
|
block.appendRun(createField(source1, "1"));
|
|
414
470
|
const targetId = insertAnnotationElement(block);
|
|
415
471
|
imodel.saveChanges();
|
|
@@ -437,7 +493,7 @@ describe("Field evaluation", () => {
|
|
|
437
493
|
it("deletes stale relationships", () => {
|
|
438
494
|
const sourceA = insertTestElement();
|
|
439
495
|
const sourceB = insertTestElement();
|
|
440
|
-
const block = TextBlock.create(
|
|
496
|
+
const block = TextBlock.create();
|
|
441
497
|
block.appendRun(createField(sourceA, "A"));
|
|
442
498
|
block.appendRun(createField(sourceB, "B"));
|
|
443
499
|
const targetId = insertAnnotationElement(block);
|
|
@@ -476,7 +532,7 @@ describe("Field evaluation", () => {
|
|
|
476
532
|
});
|
|
477
533
|
it("ignores invalid source element Ids", () => {
|
|
478
534
|
const source = insertTestElement();
|
|
479
|
-
const block = TextBlock.create(
|
|
535
|
+
const block = TextBlock.create();
|
|
480
536
|
block.appendRun(createField(Id64.invalid, "invalid"));
|
|
481
537
|
block.appendRun(createField("0xbaadf00d", "non-existent"));
|
|
482
538
|
block.appendRun(createField(source, "valid"));
|
|
@@ -491,9 +547,19 @@ describe("Field evaluation", () => {
|
|
|
491
547
|
const actual = anno.textBlock.stringify();
|
|
492
548
|
expect(actual).to.equal(expected);
|
|
493
549
|
}
|
|
550
|
+
it("evaluates cachedContent when annotation element is inserted", () => {
|
|
551
|
+
const sourceId = insertTestElement();
|
|
552
|
+
const block = TextBlock.create();
|
|
553
|
+
block.appendRun(createField(sourceId, "initial cached content"));
|
|
554
|
+
expect(block.stringify()).to.equal("initial cached content");
|
|
555
|
+
const targetId = insertAnnotationElement(block);
|
|
556
|
+
imodel.saveChanges();
|
|
557
|
+
const target = imodel.elements.getElement(targetId);
|
|
558
|
+
expect(target.getAnnotation().textBlock.stringify()).to.equal("100");
|
|
559
|
+
});
|
|
494
560
|
it("updates fields when source element is modified or deleted", () => {
|
|
495
561
|
const sourceId = insertTestElement();
|
|
496
|
-
const block = TextBlock.create(
|
|
562
|
+
const block = TextBlock.create();
|
|
497
563
|
block.appendRun(createField(sourceId, "old value"));
|
|
498
564
|
;
|
|
499
565
|
const targetId = insertAnnotationElement(block);
|
|
@@ -516,7 +582,7 @@ describe("Field evaluation", () => {
|
|
|
516
582
|
});
|
|
517
583
|
it("updates fields when source element aspect is modified, deleted, or recreated", () => {
|
|
518
584
|
const sourceId = insertTestElement();
|
|
519
|
-
const block = TextBlock.create(
|
|
585
|
+
const block = TextBlock.create();
|
|
520
586
|
block.appendRun(createField({ elementId: sourceId, schemaName: "Fields", className: "TestAspect" }, "", "aspectProp"));
|
|
521
587
|
const targetId = insertAnnotationElement(block);
|
|
522
588
|
imodel.saveChanges();
|
|
@@ -544,7 +610,7 @@ describe("Field evaluation", () => {
|
|
|
544
610
|
it("updates only fields for specific modified element", () => {
|
|
545
611
|
const sourceA = insertTestElement();
|
|
546
612
|
const sourceB = insertTestElement();
|
|
547
|
-
const block = TextBlock.create(
|
|
613
|
+
const block = TextBlock.create();
|
|
548
614
|
block.appendRun(createField(sourceA, "A"));
|
|
549
615
|
block.appendRun(createField(sourceB, "B"));
|
|
550
616
|
const targetId = insertAnnotationElement(block);
|
|
@@ -558,18 +624,67 @@ describe("Field evaluation", () => {
|
|
|
558
624
|
});
|
|
559
625
|
it("supports complex property paths", () => {
|
|
560
626
|
const sourceId = insertTestElement();
|
|
561
|
-
const block = TextBlock.create(
|
|
627
|
+
const block = TextBlock.create();
|
|
562
628
|
block.appendRun(createField(sourceId, "", "outerStruct", ["innerStructs", 1, "doubles", -2]));
|
|
563
|
-
block.appendRun(createField(sourceId, "", "jsonProperties", undefined, ["zoo", "birds", 0, "name"]));
|
|
564
629
|
const targetId = insertAnnotationElement(block);
|
|
565
630
|
imodel.saveChanges();
|
|
566
|
-
expectText("
|
|
631
|
+
expectText("2", targetId);
|
|
567
632
|
const source = imodel.elements.getElement(sourceId);
|
|
568
633
|
source.outerStruct.innerStructs[1].doubles[3] = 12.5;
|
|
569
|
-
source.jsonProperties.zoo.birds[0].name = "parrot";
|
|
570
634
|
source.update();
|
|
571
635
|
imodel.saveChanges();
|
|
572
|
-
expectText("12.
|
|
636
|
+
expectText("12.5", targetId);
|
|
637
|
+
});
|
|
638
|
+
});
|
|
639
|
+
describe("Format Validation", () => {
|
|
640
|
+
it("validates formatting options for string property type", () => {
|
|
641
|
+
// Create a FieldRun with string property type and some format options
|
|
642
|
+
const fieldRun = FieldRun.create({
|
|
643
|
+
propertyHost: { elementId: sourceElementId, schemaName: "Fields", className: "TestElement" },
|
|
644
|
+
propertyPath: { propertyName: "strings", accessors: [0] },
|
|
645
|
+
cachedContent: "oldValue",
|
|
646
|
+
formatOptions: {
|
|
647
|
+
case: "upper",
|
|
648
|
+
prefix: "Value: ",
|
|
649
|
+
suffix: "!"
|
|
650
|
+
}
|
|
651
|
+
});
|
|
652
|
+
// Context returns a string value for the property
|
|
653
|
+
const context = {
|
|
654
|
+
hostElementId: sourceElementId,
|
|
655
|
+
getProperty: () => { return { value: "abc", type: "string" }; },
|
|
656
|
+
};
|
|
657
|
+
// Update the field and check the result
|
|
658
|
+
const updated = updateField(fieldRun, context);
|
|
659
|
+
// The formatted value should be uppercased and have prefix/suffix applied
|
|
660
|
+
expect(updated).to.be.true;
|
|
661
|
+
expect(fieldRun.cachedContent).to.equal("Value: ABC!");
|
|
662
|
+
});
|
|
663
|
+
it("validates formatting options for datetime objects", function () {
|
|
664
|
+
if (!isIntlSupported()) {
|
|
665
|
+
this.skip();
|
|
666
|
+
}
|
|
667
|
+
const propertyHost = { elementId: sourceElementId, schemaName: "Fields", className: "TestElement" };
|
|
668
|
+
const fieldRun = FieldRun.create({
|
|
669
|
+
propertyHost,
|
|
670
|
+
propertyPath: { propertyName: "datetime" },
|
|
671
|
+
cachedContent: "oldval",
|
|
672
|
+
formatOptions: {
|
|
673
|
+
dateTime: {
|
|
674
|
+
formatOptions: {
|
|
675
|
+
month: "short",
|
|
676
|
+
day: "2-digit",
|
|
677
|
+
year: "numeric",
|
|
678
|
+
timeZone: "UTC"
|
|
679
|
+
},
|
|
680
|
+
locale: "en-US",
|
|
681
|
+
},
|
|
682
|
+
},
|
|
683
|
+
});
|
|
684
|
+
const context = createUpdateContext(sourceElementId, imodel, false);
|
|
685
|
+
const updated = updateField(fieldRun, context);
|
|
686
|
+
expect(updated).to.be.true;
|
|
687
|
+
expect(fieldRun.cachedContent).to.equal("Aug 28, 2025");
|
|
573
688
|
});
|
|
574
689
|
});
|
|
575
690
|
});
|