@itwin/presentation-testing 3.2.0-dev.9 → 3.2.2
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 +43 -1
- package/lib/cjs/presentation-testing/ContentBuilder.d.ts +11 -0
- package/lib/cjs/presentation-testing/ContentBuilder.d.ts.map +1 -1
- package/lib/cjs/presentation-testing/ContentBuilder.js +26 -3
- package/lib/cjs/presentation-testing/ContentBuilder.js.map +1 -1
- package/lib/esm/presentation-testing/ContentBuilder.d.ts +11 -0
- package/lib/esm/presentation-testing/ContentBuilder.d.ts.map +1 -1
- package/lib/esm/presentation-testing/ContentBuilder.js +26 -3
- package/lib/esm/presentation-testing/ContentBuilder.js.map +1 -1
- package/package.json +14 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,48 @@
|
|
|
1
1
|
# Change Log - @itwin/presentation-testing
|
|
2
2
|
|
|
3
|
-
This log was last generated on
|
|
3
|
+
This log was last generated on Fri, 10 Jun 2022 16:11:37 GMT and should not be manually modified.
|
|
4
|
+
|
|
5
|
+
## 3.2.2
|
|
6
|
+
Fri, 10 Jun 2022 16:11:37 GMT
|
|
7
|
+
|
|
8
|
+
_Version update only_
|
|
9
|
+
|
|
10
|
+
## 3.2.1
|
|
11
|
+
Tue, 07 Jun 2022 15:02:57 GMT
|
|
12
|
+
|
|
13
|
+
_Version update only_
|
|
14
|
+
|
|
15
|
+
## 3.2.0
|
|
16
|
+
Fri, 20 May 2022 13:10:54 GMT
|
|
17
|
+
|
|
18
|
+
### Updates
|
|
19
|
+
|
|
20
|
+
- Add a way to reduce raw numeric values' decimal precision to overcome rounding differences across platforms
|
|
21
|
+
|
|
22
|
+
## 3.1.3
|
|
23
|
+
Fri, 15 Apr 2022 13:49:25 GMT
|
|
24
|
+
|
|
25
|
+
_Version update only_
|
|
26
|
+
|
|
27
|
+
## 3.1.2
|
|
28
|
+
Wed, 06 Apr 2022 22:27:56 GMT
|
|
29
|
+
|
|
30
|
+
_Version update only_
|
|
31
|
+
|
|
32
|
+
## 3.1.1
|
|
33
|
+
Thu, 31 Mar 2022 15:55:48 GMT
|
|
34
|
+
|
|
35
|
+
_Version update only_
|
|
36
|
+
|
|
37
|
+
## 3.1.0
|
|
38
|
+
Tue, 29 Mar 2022 20:53:47 GMT
|
|
39
|
+
|
|
40
|
+
_Version update only_
|
|
41
|
+
|
|
42
|
+
## 3.0.3
|
|
43
|
+
Fri, 25 Mar 2022 15:10:02 GMT
|
|
44
|
+
|
|
45
|
+
_Version update only_
|
|
4
46
|
|
|
5
47
|
## 3.0.2
|
|
6
48
|
Thu, 10 Mar 2022 21:18:13 GMT
|
|
@@ -32,6 +32,16 @@ export interface ContentBuilderProps {
|
|
|
32
32
|
imodel: IModelConnection;
|
|
33
33
|
/** Custom data provider that allows mocking data ContentBuilder receives */
|
|
34
34
|
dataProvider?: IContentBuilderDataProvider;
|
|
35
|
+
/**
|
|
36
|
+
* Decimal precision or numeric types.
|
|
37
|
+
*
|
|
38
|
+
* Raw numeric values with high precision may slightly differ from platform to platform due to
|
|
39
|
+
* rounding differences on different platforms. This may be a problem when used with snapshot testing,
|
|
40
|
+
* in which case this attribute may be set to supply the maximum precision of raw numeric values.
|
|
41
|
+
*
|
|
42
|
+
* By default no rounding is applied.
|
|
43
|
+
*/
|
|
44
|
+
decimalPrecision?: number;
|
|
35
45
|
}
|
|
36
46
|
/**
|
|
37
47
|
* A class that constructs content from specified imodel and ruleset.
|
|
@@ -40,6 +50,7 @@ export interface ContentBuilderProps {
|
|
|
40
50
|
export declare class ContentBuilder {
|
|
41
51
|
private readonly _iModel;
|
|
42
52
|
private _dataProvider;
|
|
53
|
+
private _decimalPrecision?;
|
|
43
54
|
/**
|
|
44
55
|
* Constructor
|
|
45
56
|
* @param iModel
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentBuilder.d.ts","sourceRoot":"","sources":["../../../src/presentation-testing/ContentBuilder.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAMvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EACL,OAAO,EAA8B,WAAW,EAAE,MAAM,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"ContentBuilder.d.ts","sourceRoot":"","sources":["../../../src/presentation-testing/ContentBuilder.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAMvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EACL,OAAO,EAA8B,WAAW,EAAE,MAAM,EAAE,WAAW,EAAiD,OAAO,EAE9H,MAAM,4BAA4B,CAAC;AAIpC;;;GAGG;AACH,MAAM,WAAW,2BAA2B;IAC1C,qDAAqD;IACrD,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACvB,yCAAyC;IACzC,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,sBAAsB;IACtB,UAAU,EAAE,CAAC,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;CAC/E;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,mCAAmC;IACnC,MAAM,EAAE,gBAAgB,CAAC;IAEzB,4EAA4E;IAC5E,YAAY,CAAC,EAAE,2BAA2B,CAAC;IAE3C;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,aAAa,CAA0C;IAC/D,OAAO,CAAC,iBAAiB,CAAC,CAAS;IAEnC;;;;OAIG;gBACS,KAAK,EAAE,mBAAmB;YAMxB,eAAe;IAa7B;;;;;;OAMG;IACU,aAAa,CAAC,WAAW,EAAE,OAAO,GAAG,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,WAAW,GAAE,MAAgD;YAStI,eAAe;YAaf,uBAAuB;IA4BrC;;;;;;OAMG;IACU,4BAA4B,CAAC,WAAW,EAAE,OAAO,GAAG,MAAM,EAAE,WAAW,GAAE,MAAgD;IAItI;;;;;;OAMG;IACU,gCAAgC,CAAC,WAAW,EAAE,OAAO,GAAG,MAAM,EAAE,WAAW,GAAE,MAAgD;CAG3I"}
|
|
@@ -26,6 +26,7 @@ class ContentBuilder {
|
|
|
26
26
|
constructor(props) {
|
|
27
27
|
this._iModel = props.imodel;
|
|
28
28
|
this._dataProvider = props.dataProvider;
|
|
29
|
+
this._decimalPrecision = props.decimalPrecision;
|
|
29
30
|
}
|
|
30
31
|
async doCreateContent(rulesetId, instanceKeys, displayType) {
|
|
31
32
|
const dataProvider = this._dataProvider ? this._dataProvider : new presentation_components_1.ContentDataProvider({ imodel: this._iModel, ruleset: rulesetId, displayType });
|
|
@@ -33,7 +34,7 @@ class ContentBuilder {
|
|
|
33
34
|
const content = await dataProvider.getContent();
|
|
34
35
|
if (!content)
|
|
35
36
|
return [];
|
|
36
|
-
const accumulator = new PropertyRecordsAccumulator();
|
|
37
|
+
const accumulator = new PropertyRecordsAccumulator(this._decimalPrecision);
|
|
37
38
|
(0, presentation_common_1.traverseContent)(accumulator, content);
|
|
38
39
|
return accumulator.records;
|
|
39
40
|
}
|
|
@@ -107,9 +108,10 @@ class ContentBuilder {
|
|
|
107
108
|
}
|
|
108
109
|
exports.ContentBuilder = ContentBuilder;
|
|
109
110
|
class PropertyRecordsAccumulator extends presentation_components_1.PropertyRecordsBuilder {
|
|
110
|
-
constructor() {
|
|
111
|
-
super(
|
|
111
|
+
constructor(decimalPrecision) {
|
|
112
|
+
super();
|
|
112
113
|
this._records = [];
|
|
114
|
+
this._decimalPrecision = decimalPrecision;
|
|
113
115
|
}
|
|
114
116
|
get records() {
|
|
115
117
|
return this._records;
|
|
@@ -121,5 +123,26 @@ class PropertyRecordsAccumulator extends presentation_components_1.PropertyRecor
|
|
|
121
123
|
},
|
|
122
124
|
};
|
|
123
125
|
}
|
|
126
|
+
processRawValue(value) {
|
|
127
|
+
if (this._decimalPrecision === undefined)
|
|
128
|
+
return value;
|
|
129
|
+
if (typeof value === "number") {
|
|
130
|
+
return +(Number(value)).toFixed(this._decimalPrecision);
|
|
131
|
+
}
|
|
132
|
+
if (Array.isArray(value)) {
|
|
133
|
+
return value.map((item) => this.processRawValue(item));
|
|
134
|
+
}
|
|
135
|
+
if (value instanceof Object) {
|
|
136
|
+
const res = {};
|
|
137
|
+
Object.entries(value).forEach(([key, memberValue]) => {
|
|
138
|
+
res[key] = this.processRawValue(memberValue);
|
|
139
|
+
});
|
|
140
|
+
return res;
|
|
141
|
+
}
|
|
142
|
+
return value;
|
|
143
|
+
}
|
|
144
|
+
processPrimitiveValue(props) {
|
|
145
|
+
super.processPrimitiveValue({ ...props, rawValue: this.processRawValue(props.rawValue) });
|
|
146
|
+
}
|
|
124
147
|
}
|
|
125
148
|
//# sourceMappingURL=ContentBuilder.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentBuilder.js","sourceRoot":"","sources":["../../../src/presentation-testing/ContentBuilder.ts"],"names":[],"mappings":";AAAA;;;+FAG+F;;;AAG/F;;GAEG;AACH,sDAA4C;AAC5C,oDAAoD;AAEpD,oEAEoC;AACpC,4EAAmH;AACnH,wEAA4D;AAqC5D;;;GAGG;AACH,MAAa,cAAc;IAIzB;;;;OAIG;IACH,YAAY,KAA0B;QACpC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,YAAY,CAAC;IAC1C,CAAC;IAEO,KAAK,CAAC,eAAe,CAAC,SAAiB,EAAE,YAA2B,EAAE,WAAmB;QAC/F,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,6CAAmB,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,CAAC;QAClJ,YAAY,CAAC,IAAI,GAAG,IAAI,4BAAM,CAAC,YAAY,CAAC,CAAC;QAE7C,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,UAAU,EAAE,CAAC;QAChD,IAAI,CAAC,OAAO;YACV,OAAO,EAAE,CAAC;QAEZ,MAAM,WAAW,GAAG,IAAI,0BAA0B,EAAE,CAAC;QACrD,IAAA,qCAAe,EAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACtC,OAAO,WAAW,CAAC,OAAO,CAAC;IAC7B,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,aAAa,CAAC,WAA6B,EAAE,YAA2B,EAAE,cAAsB,gDAA0B,CAAC,YAAY;QAClJ,IAAI,OAAO,WAAW,KAAK,QAAQ;YACjC,OAAO,IAAI,CAAC,eAAe,CAAC,WAAW,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;QAEtE,OAAO,IAAA,oBAAK,EAAC,MAAM,oCAAY,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,OAA0B,EAAE,EAAE;YAC7G,OAAO,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,eAAe;QAC3B,MAAM,IAAI,GAAG,EAAE,CAAC;QAChB,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;;;;;KAK1C,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,4BAAc,CAAC,kBAAkB,EAAE,CAAC,EAAE;YAC/D,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;SAChB;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,KAAK,CAAC,uBAAuB,CAAC,WAA6B,EAAE,cAAuB,EAAE,WAAmB;QAC/G,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAEtD,MAAM,QAAQ,GAA2B,EAAE,CAAC;QAE5C,KAAK,MAAM,SAAS,IAAI,gBAAgB,EAAE;YACxC,QAAQ;YACR,MAAM,WAAW,GAAG,EAAE,CAAC;YACvB,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;uCACV,SAAS,CAAC,UAAU,MAAM,SAAS,CAAC,SAAS;4BACxD,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,4BAAc,CAAC,kBAAkB,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE;gBACjI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;aAC1B;YAED,IAAI,CAAC,WAAW,CAAC,MAAM;gBACrB,SAAS;YAEX,MAAM,YAAY,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,SAAS,CAAC,UAAU,IAAI,SAAS,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,OAAO,EAAkB,CAAA,CAAC,CAAC;YAEjJ,QAAQ,CAAC,IAAI,CAAC;gBACZ,SAAS,EAAE,GAAG,SAAS,CAAC,UAAU,IAAI,SAAS,CAAC,SAAS,EAAE;gBAC3D,OAAO,EAAE,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,YAAY,EAAE,WAAW,CAAC;aAC1E,CAAC,CAAC;SACJ;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,4BAA4B,CAAC,WAA6B,EAAE,cAAsB,gDAA0B,CAAC,YAAY;QACpI,OAAO,IAAI,CAAC,uBAAuB,CAAC,WAAW,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IACvE,CAAC;IAED;;;;;;OAMG;IACI,KAAK,CAAC,gCAAgC,CAAC,WAA6B,EAAE,cAAsB,gDAA0B,CAAC,YAAY;QACxI,OAAO,IAAI,CAAC,uBAAuB,CAAC,WAAW,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC;IACtE,CAAC;CACF;AAzGD,wCAyGC;AAED,MAAM,0BAA2B,SAAQ,gDAAsB;IAA/D;;QACU,aAAQ,GAAqB,EAAE,CAAC;IAa1C,CAAC;IAXC,IAAW,OAAO;QAChB,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAES,4BAA4B;QACpC,OAAO;YACL,MAAM,EAAE,CAAC,MAA4B,EAAE,EAAE;gBACvC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACpC,CAAC;SACF,CAAC;IACJ,CAAC;CACF","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { PropertyRecord } from \"@itwin/appui-abstract\";\r\n/** @packageDocumentation\r\n * @module Content\r\n */\r\nimport { using } from \"@itwin/core-bentley\";\r\nimport { QueryRowFormat } from \"@itwin/core-common\";\r\nimport { IModelConnection } from \"@itwin/core-frontend\";\r\nimport {\r\n Content, DefaultContentDisplayTypes, InstanceKey, KeySet, PageOptions, RegisteredRuleset, Ruleset, traverseContent,\r\n} from \"@itwin/presentation-common\";\r\nimport { ContentDataProvider, FieldHierarchyRecord, PropertyRecordsBuilder } from \"@itwin/presentation-components\";\r\nimport { Presentation } from \"@itwin/presentation-frontend\";\r\n\r\n/**\r\n * Interface for a data provider, which is used by ContentBuilder.\r\n * @public\r\n */\r\nexport interface IContentBuilderDataProvider {\r\n /** Keys the data provider is creating content for */\r\n keys: Readonly<KeySet>;\r\n /** Get the size of content result set */\r\n getContentSetSize: () => Promise<number>;\r\n /** Get the content */\r\n getContent: (options?: PageOptions) => Promise<Readonly<Content> | undefined>;\r\n}\r\n\r\n/**\r\n * Property records grouped under a single className\r\n * @public\r\n */\r\nexport interface ContentBuilderResult {\r\n /** Full name of ECClass whose records are contained in this data structure */\r\n className: string;\r\n /** Property records for the ECClass instance */\r\n records: PropertyRecord[];\r\n}\r\n\r\n/**\r\n * Properties for creating a `ContentBuilder` instance.\r\n * @public\r\n */\r\nexport interface ContentBuilderProps {\r\n /** The iModel to pull data from */\r\n imodel: IModelConnection;\r\n /** Custom data provider that allows mocking data ContentBuilder receives */\r\n dataProvider?: IContentBuilderDataProvider;\r\n}\r\n\r\n/**\r\n * A class that constructs content from specified imodel and ruleset.\r\n * @public\r\n */\r\nexport class ContentBuilder {\r\n private readonly _iModel: IModelConnection;\r\n private _dataProvider: IContentBuilderDataProvider | undefined;\r\n\r\n /**\r\n * Constructor\r\n * @param iModel\r\n * @param dataProvider\r\n */\r\n constructor(props: ContentBuilderProps) {\r\n this._iModel = props.imodel;\r\n this._dataProvider = props.dataProvider;\r\n }\r\n\r\n private async doCreateContent(rulesetId: string, instanceKeys: InstanceKey[], displayType: string): Promise<PropertyRecord[]> {\r\n const dataProvider = this._dataProvider ? this._dataProvider : new ContentDataProvider({ imodel: this._iModel, ruleset: rulesetId, displayType });\r\n dataProvider.keys = new KeySet(instanceKeys);\r\n\r\n const content = await dataProvider.getContent();\r\n if (!content)\r\n return [];\r\n\r\n const accumulator = new PropertyRecordsAccumulator();\r\n traverseContent(accumulator, content);\r\n return accumulator.records;\r\n }\r\n\r\n /**\r\n * Create a list of property records using the supplied presentation ruleset.\r\n * @param rulesetOrId Either a [[Ruleset]] object or a ruleset id.\r\n * @param instanceKeys Keys of instances that should be queried.\r\n * @param displayType Type of content container display. For example:\r\n * \"PropertyPane\", \"Grid\", \"List\" etc.\r\n */\r\n public async createContent(rulesetOrId: Ruleset | string, instanceKeys: InstanceKey[], displayType: string = DefaultContentDisplayTypes.PropertyPane) {\r\n if (typeof rulesetOrId === \"string\")\r\n return this.doCreateContent(rulesetOrId, instanceKeys, displayType);\r\n\r\n return using(await Presentation.presentation.rulesets().add(rulesetOrId), async (ruleset: RegisteredRuleset) => {\r\n return this.doCreateContent(ruleset.id, instanceKeys, displayType);\r\n });\r\n }\r\n\r\n private async getECClassNames(): Promise<Array<{ schemaName: string, className: string }>> {\r\n const rows = [];\r\n for await (const row of this._iModel.query(`\r\n SELECT s.Name schemaName, c.Name className FROM meta.ECClassDef c\r\n INNER JOIN meta.ECSchemaDef s ON c.Schema.id = s.ECInstanceId\r\n WHERE c.Modifier <> 1 AND c.Type = 0\r\n ORDER BY s.Name, c.Name\r\n `, undefined, { rowFormat: QueryRowFormat.UseJsPropertyNames })) {\r\n rows.push(row);\r\n }\r\n return rows;\r\n }\r\n\r\n private async createContentForClasses(rulesetOrId: Ruleset | string, limitInstances: boolean, displayType: string) {\r\n const classNameEntries = await this.getECClassNames();\r\n\r\n const contents: ContentBuilderResult[] = [];\r\n\r\n for (const nameEntry of classNameEntries) {\r\n // try {\r\n const instanceIds = [];\r\n for await (const row of this._iModel.query(`\r\n SELECT ECInstanceId FROM ONLY \"${nameEntry.schemaName}\".\"${nameEntry.className}\"\r\n ORDER BY ECInstanceId`, undefined, { rowFormat: QueryRowFormat.UseJsPropertyNames, limit: { count: limitInstances ? 1 : 4000 } })) {\r\n instanceIds.push(row.id);\r\n }\r\n\r\n if (!instanceIds.length)\r\n continue;\r\n\r\n const instanceKeys = instanceIds.map((idEntry) => ({ className: `${nameEntry.schemaName}:${nameEntry.className}`, id: idEntry } as InstanceKey));\r\n\r\n contents.push({\r\n className: `${nameEntry.schemaName}:${nameEntry.className}`,\r\n records: await this.createContent(rulesetOrId, instanceKeys, displayType),\r\n });\r\n }\r\n\r\n return contents;\r\n }\r\n\r\n /**\r\n * Create a list of grouped property records using the supplied presentation ruleset.\r\n * Each group includes all of the class instances.\r\n * @param rulesetOrId Either a [[Ruleset]] object or a ruleset id.\r\n * @param displayType Type of content container display. For example:\r\n * \"PropertyPane\", \"Grid\", \"List\" etc.\r\n */\r\n public async createContentForAllInstances(rulesetOrId: Ruleset | string, displayType: string = DefaultContentDisplayTypes.PropertyPane) {\r\n return this.createContentForClasses(rulesetOrId, false, displayType);\r\n }\r\n\r\n /**\r\n * Create a list of grouped property records using the supplied presentation ruleset.\r\n * Each group includes at most one class instance.\r\n * @param rulesetOrId Either a [[Ruleset]] object or a ruleset id.\r\n * @param displayType Type of content container display. For example:\r\n * \"PropertyPane\", \"Grid\", \"List\" etc.\r\n */\r\n public async createContentForInstancePerClass(rulesetOrId: Ruleset | string, displayType: string = DefaultContentDisplayTypes.PropertyPane) {\r\n return this.createContentForClasses(rulesetOrId, true, displayType);\r\n }\r\n}\r\n\r\nclass PropertyRecordsAccumulator extends PropertyRecordsBuilder {\r\n private _records: PropertyRecord[] = [];\r\n\r\n public get records(): PropertyRecord[] {\r\n return this._records;\r\n }\r\n\r\n protected createRootPropertiesAppender() {\r\n return {\r\n append: (record: FieldHierarchyRecord) => {\r\n this._records.push(record.record);\r\n },\r\n };\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"ContentBuilder.js","sourceRoot":"","sources":["../../../src/presentation-testing/ContentBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { PropertyRecord } from \"@itwin/appui-abstract\";\r\n/** @packageDocumentation\r\n * @module Content\r\n */\r\nimport { using } from \"@itwin/core-bentley\";\r\nimport { QueryRowFormat } from \"@itwin/core-common\";\r\nimport { IModelConnection } from \"@itwin/core-frontend\";\r\nimport {\r\n Content, DefaultContentDisplayTypes, InstanceKey, KeySet, PageOptions, ProcessPrimitiveValueProps, RegisteredRuleset, Ruleset, traverseContent,\r\n Value, ValuesMap,\r\n} from \"@itwin/presentation-common\";\r\nimport { ContentDataProvider, FieldHierarchyRecord, PropertyRecordsBuilder } from \"@itwin/presentation-components\";\r\nimport { Presentation } from \"@itwin/presentation-frontend\";\r\n\r\n/**\r\n * Interface for a data provider, which is used by ContentBuilder.\r\n * @public\r\n */\r\nexport interface IContentBuilderDataProvider {\r\n /** Keys the data provider is creating content for */\r\n keys: Readonly<KeySet>;\r\n /** Get the size of content result set */\r\n getContentSetSize: () => Promise<number>;\r\n /** Get the content */\r\n getContent: (options?: PageOptions) => Promise<Readonly<Content> | undefined>;\r\n}\r\n\r\n/**\r\n * Property records grouped under a single className\r\n * @public\r\n */\r\nexport interface ContentBuilderResult {\r\n /** Full name of ECClass whose records are contained in this data structure */\r\n className: string;\r\n /** Property records for the ECClass instance */\r\n records: PropertyRecord[];\r\n}\r\n\r\n/**\r\n * Properties for creating a `ContentBuilder` instance.\r\n * @public\r\n */\r\nexport interface ContentBuilderProps {\r\n /** The iModel to pull data from */\r\n imodel: IModelConnection;\r\n\r\n /** Custom data provider that allows mocking data ContentBuilder receives */\r\n dataProvider?: IContentBuilderDataProvider;\r\n\r\n /**\r\n * Decimal precision or numeric types.\r\n *\r\n * Raw numeric values with high precision may slightly differ from platform to platform due to\r\n * rounding differences on different platforms. This may be a problem when used with snapshot testing,\r\n * in which case this attribute may be set to supply the maximum precision of raw numeric values.\r\n *\r\n * By default no rounding is applied.\r\n */\r\n decimalPrecision?: number;\r\n}\r\n\r\n/**\r\n * A class that constructs content from specified imodel and ruleset.\r\n * @public\r\n */\r\nexport class ContentBuilder {\r\n private readonly _iModel: IModelConnection;\r\n private _dataProvider: IContentBuilderDataProvider | undefined;\r\n private _decimalPrecision?: number;\r\n\r\n /**\r\n * Constructor\r\n * @param iModel\r\n * @param dataProvider\r\n */\r\n constructor(props: ContentBuilderProps) {\r\n this._iModel = props.imodel;\r\n this._dataProvider = props.dataProvider;\r\n this._decimalPrecision = props.decimalPrecision;\r\n }\r\n\r\n private async doCreateContent(rulesetId: string, instanceKeys: InstanceKey[], displayType: string): Promise<PropertyRecord[]> {\r\n const dataProvider = this._dataProvider ? this._dataProvider : new ContentDataProvider({ imodel: this._iModel, ruleset: rulesetId, displayType });\r\n dataProvider.keys = new KeySet(instanceKeys);\r\n\r\n const content = await dataProvider.getContent();\r\n if (!content)\r\n return [];\r\n\r\n const accumulator = new PropertyRecordsAccumulator(this._decimalPrecision);\r\n traverseContent(accumulator, content);\r\n return accumulator.records;\r\n }\r\n\r\n /**\r\n * Create a list of property records using the supplied presentation ruleset.\r\n * @param rulesetOrId Either a [[Ruleset]] object or a ruleset id.\r\n * @param instanceKeys Keys of instances that should be queried.\r\n * @param displayType Type of content container display. For example:\r\n * \"PropertyPane\", \"Grid\", \"List\" etc.\r\n */\r\n public async createContent(rulesetOrId: Ruleset | string, instanceKeys: InstanceKey[], displayType: string = DefaultContentDisplayTypes.PropertyPane) {\r\n if (typeof rulesetOrId === \"string\")\r\n return this.doCreateContent(rulesetOrId, instanceKeys, displayType);\r\n\r\n return using(await Presentation.presentation.rulesets().add(rulesetOrId), async (ruleset: RegisteredRuleset) => {\r\n return this.doCreateContent(ruleset.id, instanceKeys, displayType);\r\n });\r\n }\r\n\r\n private async getECClassNames(): Promise<Array<{ schemaName: string, className: string }>> {\r\n const rows = [];\r\n for await (const row of this._iModel.query(`\r\n SELECT s.Name schemaName, c.Name className FROM meta.ECClassDef c\r\n INNER JOIN meta.ECSchemaDef s ON c.Schema.id = s.ECInstanceId\r\n WHERE c.Modifier <> 1 AND c.Type = 0\r\n ORDER BY s.Name, c.Name\r\n `, undefined, { rowFormat: QueryRowFormat.UseJsPropertyNames })) {\r\n rows.push(row);\r\n }\r\n return rows;\r\n }\r\n\r\n private async createContentForClasses(rulesetOrId: Ruleset | string, limitInstances: boolean, displayType: string) {\r\n const classNameEntries = await this.getECClassNames();\r\n\r\n const contents: ContentBuilderResult[] = [];\r\n\r\n for (const nameEntry of classNameEntries) {\r\n // try {\r\n const instanceIds = [];\r\n for await (const row of this._iModel.query(`\r\n SELECT ECInstanceId FROM ONLY \"${nameEntry.schemaName}\".\"${nameEntry.className}\"\r\n ORDER BY ECInstanceId`, undefined, { rowFormat: QueryRowFormat.UseJsPropertyNames, limit: { count: limitInstances ? 1 : 4000 } })) {\r\n instanceIds.push(row.id);\r\n }\r\n\r\n if (!instanceIds.length)\r\n continue;\r\n\r\n const instanceKeys = instanceIds.map((idEntry) => ({ className: `${nameEntry.schemaName}:${nameEntry.className}`, id: idEntry } as InstanceKey));\r\n\r\n contents.push({\r\n className: `${nameEntry.schemaName}:${nameEntry.className}`,\r\n records: await this.createContent(rulesetOrId, instanceKeys, displayType),\r\n });\r\n }\r\n\r\n return contents;\r\n }\r\n\r\n /**\r\n * Create a list of grouped property records using the supplied presentation ruleset.\r\n * Each group includes all of the class instances.\r\n * @param rulesetOrId Either a [[Ruleset]] object or a ruleset id.\r\n * @param displayType Type of content container display. For example:\r\n * \"PropertyPane\", \"Grid\", \"List\" etc.\r\n */\r\n public async createContentForAllInstances(rulesetOrId: Ruleset | string, displayType: string = DefaultContentDisplayTypes.PropertyPane) {\r\n return this.createContentForClasses(rulesetOrId, false, displayType);\r\n }\r\n\r\n /**\r\n * Create a list of grouped property records using the supplied presentation ruleset.\r\n * Each group includes at most one class instance.\r\n * @param rulesetOrId Either a [[Ruleset]] object or a ruleset id.\r\n * @param displayType Type of content container display. For example:\r\n * \"PropertyPane\", \"Grid\", \"List\" etc.\r\n */\r\n public async createContentForInstancePerClass(rulesetOrId: Ruleset | string, displayType: string = DefaultContentDisplayTypes.PropertyPane) {\r\n return this.createContentForClasses(rulesetOrId, true, displayType);\r\n }\r\n}\r\n\r\nclass PropertyRecordsAccumulator extends PropertyRecordsBuilder {\r\n private _records: PropertyRecord[] = [];\r\n private _decimalPrecision?: number;\r\n\r\n public constructor(decimalPrecision?: number) {\r\n super();\r\n this._decimalPrecision = decimalPrecision;\r\n }\r\n\r\n public get records(): PropertyRecord[] {\r\n return this._records;\r\n }\r\n\r\n protected createRootPropertiesAppender() {\r\n return {\r\n append: (record: FieldHierarchyRecord) => {\r\n this._records.push(record.record);\r\n },\r\n };\r\n }\r\n\r\n private processRawValue(value: Value): Value {\r\n if (this._decimalPrecision === undefined)\r\n return value;\r\n\r\n if (typeof value === \"number\") {\r\n return +(Number(value)).toFixed(this._decimalPrecision);\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n return value.map((item) => this.processRawValue(item));\r\n }\r\n\r\n if (value instanceof Object) {\r\n const res: ValuesMap = {};\r\n Object.entries(value).forEach(([key, memberValue]) => {\r\n res[key] = this.processRawValue(memberValue);\r\n });\r\n return res;\r\n }\r\n\r\n return value;\r\n }\r\n\r\n public override processPrimitiveValue(props: ProcessPrimitiveValueProps) {\r\n super.processPrimitiveValue({ ...props, rawValue: this.processRawValue(props.rawValue) });\r\n }\r\n}\r\n"]}
|
|
@@ -32,6 +32,16 @@ export interface ContentBuilderProps {
|
|
|
32
32
|
imodel: IModelConnection;
|
|
33
33
|
/** Custom data provider that allows mocking data ContentBuilder receives */
|
|
34
34
|
dataProvider?: IContentBuilderDataProvider;
|
|
35
|
+
/**
|
|
36
|
+
* Decimal precision or numeric types.
|
|
37
|
+
*
|
|
38
|
+
* Raw numeric values with high precision may slightly differ from platform to platform due to
|
|
39
|
+
* rounding differences on different platforms. This may be a problem when used with snapshot testing,
|
|
40
|
+
* in which case this attribute may be set to supply the maximum precision of raw numeric values.
|
|
41
|
+
*
|
|
42
|
+
* By default no rounding is applied.
|
|
43
|
+
*/
|
|
44
|
+
decimalPrecision?: number;
|
|
35
45
|
}
|
|
36
46
|
/**
|
|
37
47
|
* A class that constructs content from specified imodel and ruleset.
|
|
@@ -40,6 +50,7 @@ export interface ContentBuilderProps {
|
|
|
40
50
|
export declare class ContentBuilder {
|
|
41
51
|
private readonly _iModel;
|
|
42
52
|
private _dataProvider;
|
|
53
|
+
private _decimalPrecision?;
|
|
43
54
|
/**
|
|
44
55
|
* Constructor
|
|
45
56
|
* @param iModel
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentBuilder.d.ts","sourceRoot":"","sources":["../../../src/presentation-testing/ContentBuilder.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAMvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EACL,OAAO,EAA8B,WAAW,EAAE,MAAM,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"ContentBuilder.d.ts","sourceRoot":"","sources":["../../../src/presentation-testing/ContentBuilder.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAMvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EACL,OAAO,EAA8B,WAAW,EAAE,MAAM,EAAE,WAAW,EAAiD,OAAO,EAE9H,MAAM,4BAA4B,CAAC;AAIpC;;;GAGG;AACH,MAAM,WAAW,2BAA2B;IAC1C,qDAAqD;IACrD,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IACvB,yCAAyC;IACzC,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,sBAAsB;IACtB,UAAU,EAAE,CAAC,OAAO,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;CAC/E;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;IAClB,gDAAgD;IAChD,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,mCAAmC;IACnC,MAAM,EAAE,gBAAgB,CAAC;IAEzB,4EAA4E;IAC5E,YAAY,CAAC,EAAE,2BAA2B,CAAC;IAE3C;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;GAGG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAmB;IAC3C,OAAO,CAAC,aAAa,CAA0C;IAC/D,OAAO,CAAC,iBAAiB,CAAC,CAAS;IAEnC;;;;OAIG;gBACS,KAAK,EAAE,mBAAmB;YAMxB,eAAe;IAa7B;;;;;;OAMG;IACU,aAAa,CAAC,WAAW,EAAE,OAAO,GAAG,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,WAAW,GAAE,MAAgD;YAStI,eAAe;YAaf,uBAAuB;IA4BrC;;;;;;OAMG;IACU,4BAA4B,CAAC,WAAW,EAAE,OAAO,GAAG,MAAM,EAAE,WAAW,GAAE,MAAgD;IAItI;;;;;;OAMG;IACU,gCAAgC,CAAC,WAAW,EAAE,OAAO,GAAG,MAAM,EAAE,WAAW,GAAE,MAAgD;CAG3I"}
|
|
@@ -23,6 +23,7 @@ export class ContentBuilder {
|
|
|
23
23
|
constructor(props) {
|
|
24
24
|
this._iModel = props.imodel;
|
|
25
25
|
this._dataProvider = props.dataProvider;
|
|
26
|
+
this._decimalPrecision = props.decimalPrecision;
|
|
26
27
|
}
|
|
27
28
|
async doCreateContent(rulesetId, instanceKeys, displayType) {
|
|
28
29
|
const dataProvider = this._dataProvider ? this._dataProvider : new ContentDataProvider({ imodel: this._iModel, ruleset: rulesetId, displayType });
|
|
@@ -30,7 +31,7 @@ export class ContentBuilder {
|
|
|
30
31
|
const content = await dataProvider.getContent();
|
|
31
32
|
if (!content)
|
|
32
33
|
return [];
|
|
33
|
-
const accumulator = new PropertyRecordsAccumulator();
|
|
34
|
+
const accumulator = new PropertyRecordsAccumulator(this._decimalPrecision);
|
|
34
35
|
traverseContent(accumulator, content);
|
|
35
36
|
return accumulator.records;
|
|
36
37
|
}
|
|
@@ -103,9 +104,10 @@ export class ContentBuilder {
|
|
|
103
104
|
}
|
|
104
105
|
}
|
|
105
106
|
class PropertyRecordsAccumulator extends PropertyRecordsBuilder {
|
|
106
|
-
constructor() {
|
|
107
|
-
super(
|
|
107
|
+
constructor(decimalPrecision) {
|
|
108
|
+
super();
|
|
108
109
|
this._records = [];
|
|
110
|
+
this._decimalPrecision = decimalPrecision;
|
|
109
111
|
}
|
|
110
112
|
get records() {
|
|
111
113
|
return this._records;
|
|
@@ -117,5 +119,26 @@ class PropertyRecordsAccumulator extends PropertyRecordsBuilder {
|
|
|
117
119
|
},
|
|
118
120
|
};
|
|
119
121
|
}
|
|
122
|
+
processRawValue(value) {
|
|
123
|
+
if (this._decimalPrecision === undefined)
|
|
124
|
+
return value;
|
|
125
|
+
if (typeof value === "number") {
|
|
126
|
+
return +(Number(value)).toFixed(this._decimalPrecision);
|
|
127
|
+
}
|
|
128
|
+
if (Array.isArray(value)) {
|
|
129
|
+
return value.map((item) => this.processRawValue(item));
|
|
130
|
+
}
|
|
131
|
+
if (value instanceof Object) {
|
|
132
|
+
const res = {};
|
|
133
|
+
Object.entries(value).forEach(([key, memberValue]) => {
|
|
134
|
+
res[key] = this.processRawValue(memberValue);
|
|
135
|
+
});
|
|
136
|
+
return res;
|
|
137
|
+
}
|
|
138
|
+
return value;
|
|
139
|
+
}
|
|
140
|
+
processPrimitiveValue(props) {
|
|
141
|
+
super.processPrimitiveValue({ ...props, rawValue: this.processRawValue(props.rawValue) });
|
|
142
|
+
}
|
|
120
143
|
}
|
|
121
144
|
//# sourceMappingURL=ContentBuilder.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContentBuilder.js","sourceRoot":"","sources":["../../../src/presentation-testing/ContentBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { PropertyRecord } from \"@itwin/appui-abstract\";\r\n/** @packageDocumentation\r\n * @module Content\r\n */\r\nimport { using } from \"@itwin/core-bentley\";\r\nimport { QueryRowFormat } from \"@itwin/core-common\";\r\nimport { IModelConnection } from \"@itwin/core-frontend\";\r\nimport {\r\n Content, DefaultContentDisplayTypes, InstanceKey, KeySet, PageOptions, RegisteredRuleset, Ruleset, traverseContent,\r\n} from \"@itwin/presentation-common\";\r\nimport { ContentDataProvider, FieldHierarchyRecord, PropertyRecordsBuilder } from \"@itwin/presentation-components\";\r\nimport { Presentation } from \"@itwin/presentation-frontend\";\r\n\r\n/**\r\n * Interface for a data provider, which is used by ContentBuilder.\r\n * @public\r\n */\r\nexport interface IContentBuilderDataProvider {\r\n /** Keys the data provider is creating content for */\r\n keys: Readonly<KeySet>;\r\n /** Get the size of content result set */\r\n getContentSetSize: () => Promise<number>;\r\n /** Get the content */\r\n getContent: (options?: PageOptions) => Promise<Readonly<Content> | undefined>;\r\n}\r\n\r\n/**\r\n * Property records grouped under a single className\r\n * @public\r\n */\r\nexport interface ContentBuilderResult {\r\n /** Full name of ECClass whose records are contained in this data structure */\r\n className: string;\r\n /** Property records for the ECClass instance */\r\n records: PropertyRecord[];\r\n}\r\n\r\n/**\r\n * Properties for creating a `ContentBuilder` instance.\r\n * @public\r\n */\r\nexport interface ContentBuilderProps {\r\n /** The iModel to pull data from */\r\n imodel: IModelConnection;\r\n /** Custom data provider that allows mocking data ContentBuilder receives */\r\n dataProvider?: IContentBuilderDataProvider;\r\n}\r\n\r\n/**\r\n * A class that constructs content from specified imodel and ruleset.\r\n * @public\r\n */\r\nexport class ContentBuilder {\r\n private readonly _iModel: IModelConnection;\r\n private _dataProvider: IContentBuilderDataProvider | undefined;\r\n\r\n /**\r\n * Constructor\r\n * @param iModel\r\n * @param dataProvider\r\n */\r\n constructor(props: ContentBuilderProps) {\r\n this._iModel = props.imodel;\r\n this._dataProvider = props.dataProvider;\r\n }\r\n\r\n private async doCreateContent(rulesetId: string, instanceKeys: InstanceKey[], displayType: string): Promise<PropertyRecord[]> {\r\n const dataProvider = this._dataProvider ? this._dataProvider : new ContentDataProvider({ imodel: this._iModel, ruleset: rulesetId, displayType });\r\n dataProvider.keys = new KeySet(instanceKeys);\r\n\r\n const content = await dataProvider.getContent();\r\n if (!content)\r\n return [];\r\n\r\n const accumulator = new PropertyRecordsAccumulator();\r\n traverseContent(accumulator, content);\r\n return accumulator.records;\r\n }\r\n\r\n /**\r\n * Create a list of property records using the supplied presentation ruleset.\r\n * @param rulesetOrId Either a [[Ruleset]] object or a ruleset id.\r\n * @param instanceKeys Keys of instances that should be queried.\r\n * @param displayType Type of content container display. For example:\r\n * \"PropertyPane\", \"Grid\", \"List\" etc.\r\n */\r\n public async createContent(rulesetOrId: Ruleset | string, instanceKeys: InstanceKey[], displayType: string = DefaultContentDisplayTypes.PropertyPane) {\r\n if (typeof rulesetOrId === \"string\")\r\n return this.doCreateContent(rulesetOrId, instanceKeys, displayType);\r\n\r\n return using(await Presentation.presentation.rulesets().add(rulesetOrId), async (ruleset: RegisteredRuleset) => {\r\n return this.doCreateContent(ruleset.id, instanceKeys, displayType);\r\n });\r\n }\r\n\r\n private async getECClassNames(): Promise<Array<{ schemaName: string, className: string }>> {\r\n const rows = [];\r\n for await (const row of this._iModel.query(`\r\n SELECT s.Name schemaName, c.Name className FROM meta.ECClassDef c\r\n INNER JOIN meta.ECSchemaDef s ON c.Schema.id = s.ECInstanceId\r\n WHERE c.Modifier <> 1 AND c.Type = 0\r\n ORDER BY s.Name, c.Name\r\n `, undefined, { rowFormat: QueryRowFormat.UseJsPropertyNames })) {\r\n rows.push(row);\r\n }\r\n return rows;\r\n }\r\n\r\n private async createContentForClasses(rulesetOrId: Ruleset | string, limitInstances: boolean, displayType: string) {\r\n const classNameEntries = await this.getECClassNames();\r\n\r\n const contents: ContentBuilderResult[] = [];\r\n\r\n for (const nameEntry of classNameEntries) {\r\n // try {\r\n const instanceIds = [];\r\n for await (const row of this._iModel.query(`\r\n SELECT ECInstanceId FROM ONLY \"${nameEntry.schemaName}\".\"${nameEntry.className}\"\r\n ORDER BY ECInstanceId`, undefined, { rowFormat: QueryRowFormat.UseJsPropertyNames, limit: { count: limitInstances ? 1 : 4000 } })) {\r\n instanceIds.push(row.id);\r\n }\r\n\r\n if (!instanceIds.length)\r\n continue;\r\n\r\n const instanceKeys = instanceIds.map((idEntry) => ({ className: `${nameEntry.schemaName}:${nameEntry.className}`, id: idEntry } as InstanceKey));\r\n\r\n contents.push({\r\n className: `${nameEntry.schemaName}:${nameEntry.className}`,\r\n records: await this.createContent(rulesetOrId, instanceKeys, displayType),\r\n });\r\n }\r\n\r\n return contents;\r\n }\r\n\r\n /**\r\n * Create a list of grouped property records using the supplied presentation ruleset.\r\n * Each group includes all of the class instances.\r\n * @param rulesetOrId Either a [[Ruleset]] object or a ruleset id.\r\n * @param displayType Type of content container display. For example:\r\n * \"PropertyPane\", \"Grid\", \"List\" etc.\r\n */\r\n public async createContentForAllInstances(rulesetOrId: Ruleset | string, displayType: string = DefaultContentDisplayTypes.PropertyPane) {\r\n return this.createContentForClasses(rulesetOrId, false, displayType);\r\n }\r\n\r\n /**\r\n * Create a list of grouped property records using the supplied presentation ruleset.\r\n * Each group includes at most one class instance.\r\n * @param rulesetOrId Either a [[Ruleset]] object or a ruleset id.\r\n * @param displayType Type of content container display. For example:\r\n * \"PropertyPane\", \"Grid\", \"List\" etc.\r\n */\r\n public async createContentForInstancePerClass(rulesetOrId: Ruleset | string, displayType: string = DefaultContentDisplayTypes.PropertyPane) {\r\n return this.createContentForClasses(rulesetOrId, true, displayType);\r\n }\r\n}\r\n\r\nclass PropertyRecordsAccumulator extends PropertyRecordsBuilder {\r\n private _records: PropertyRecord[] = [];\r\n\r\n public get records(): PropertyRecord[] {\r\n return this._records;\r\n }\r\n\r\n protected createRootPropertiesAppender() {\r\n return {\r\n append: (record: FieldHierarchyRecord) => {\r\n this._records.push(record.record);\r\n },\r\n };\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"ContentBuilder.js","sourceRoot":"","sources":["../../../src/presentation-testing/ContentBuilder.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\r\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\r\n* See LICENSE.md in the project root for license terms and full copyright notice.\r\n*--------------------------------------------------------------------------------------------*/\r\n\r\nimport { PropertyRecord } from \"@itwin/appui-abstract\";\r\n/** @packageDocumentation\r\n * @module Content\r\n */\r\nimport { using } from \"@itwin/core-bentley\";\r\nimport { QueryRowFormat } from \"@itwin/core-common\";\r\nimport { IModelConnection } from \"@itwin/core-frontend\";\r\nimport {\r\n Content, DefaultContentDisplayTypes, InstanceKey, KeySet, PageOptions, ProcessPrimitiveValueProps, RegisteredRuleset, Ruleset, traverseContent,\r\n Value, ValuesMap,\r\n} from \"@itwin/presentation-common\";\r\nimport { ContentDataProvider, FieldHierarchyRecord, PropertyRecordsBuilder } from \"@itwin/presentation-components\";\r\nimport { Presentation } from \"@itwin/presentation-frontend\";\r\n\r\n/**\r\n * Interface for a data provider, which is used by ContentBuilder.\r\n * @public\r\n */\r\nexport interface IContentBuilderDataProvider {\r\n /** Keys the data provider is creating content for */\r\n keys: Readonly<KeySet>;\r\n /** Get the size of content result set */\r\n getContentSetSize: () => Promise<number>;\r\n /** Get the content */\r\n getContent: (options?: PageOptions) => Promise<Readonly<Content> | undefined>;\r\n}\r\n\r\n/**\r\n * Property records grouped under a single className\r\n * @public\r\n */\r\nexport interface ContentBuilderResult {\r\n /** Full name of ECClass whose records are contained in this data structure */\r\n className: string;\r\n /** Property records for the ECClass instance */\r\n records: PropertyRecord[];\r\n}\r\n\r\n/**\r\n * Properties for creating a `ContentBuilder` instance.\r\n * @public\r\n */\r\nexport interface ContentBuilderProps {\r\n /** The iModel to pull data from */\r\n imodel: IModelConnection;\r\n\r\n /** Custom data provider that allows mocking data ContentBuilder receives */\r\n dataProvider?: IContentBuilderDataProvider;\r\n\r\n /**\r\n * Decimal precision or numeric types.\r\n *\r\n * Raw numeric values with high precision may slightly differ from platform to platform due to\r\n * rounding differences on different platforms. This may be a problem when used with snapshot testing,\r\n * in which case this attribute may be set to supply the maximum precision of raw numeric values.\r\n *\r\n * By default no rounding is applied.\r\n */\r\n decimalPrecision?: number;\r\n}\r\n\r\n/**\r\n * A class that constructs content from specified imodel and ruleset.\r\n * @public\r\n */\r\nexport class ContentBuilder {\r\n private readonly _iModel: IModelConnection;\r\n private _dataProvider: IContentBuilderDataProvider | undefined;\r\n private _decimalPrecision?: number;\r\n\r\n /**\r\n * Constructor\r\n * @param iModel\r\n * @param dataProvider\r\n */\r\n constructor(props: ContentBuilderProps) {\r\n this._iModel = props.imodel;\r\n this._dataProvider = props.dataProvider;\r\n this._decimalPrecision = props.decimalPrecision;\r\n }\r\n\r\n private async doCreateContent(rulesetId: string, instanceKeys: InstanceKey[], displayType: string): Promise<PropertyRecord[]> {\r\n const dataProvider = this._dataProvider ? this._dataProvider : new ContentDataProvider({ imodel: this._iModel, ruleset: rulesetId, displayType });\r\n dataProvider.keys = new KeySet(instanceKeys);\r\n\r\n const content = await dataProvider.getContent();\r\n if (!content)\r\n return [];\r\n\r\n const accumulator = new PropertyRecordsAccumulator(this._decimalPrecision);\r\n traverseContent(accumulator, content);\r\n return accumulator.records;\r\n }\r\n\r\n /**\r\n * Create a list of property records using the supplied presentation ruleset.\r\n * @param rulesetOrId Either a [[Ruleset]] object or a ruleset id.\r\n * @param instanceKeys Keys of instances that should be queried.\r\n * @param displayType Type of content container display. For example:\r\n * \"PropertyPane\", \"Grid\", \"List\" etc.\r\n */\r\n public async createContent(rulesetOrId: Ruleset | string, instanceKeys: InstanceKey[], displayType: string = DefaultContentDisplayTypes.PropertyPane) {\r\n if (typeof rulesetOrId === \"string\")\r\n return this.doCreateContent(rulesetOrId, instanceKeys, displayType);\r\n\r\n return using(await Presentation.presentation.rulesets().add(rulesetOrId), async (ruleset: RegisteredRuleset) => {\r\n return this.doCreateContent(ruleset.id, instanceKeys, displayType);\r\n });\r\n }\r\n\r\n private async getECClassNames(): Promise<Array<{ schemaName: string, className: string }>> {\r\n const rows = [];\r\n for await (const row of this._iModel.query(`\r\n SELECT s.Name schemaName, c.Name className FROM meta.ECClassDef c\r\n INNER JOIN meta.ECSchemaDef s ON c.Schema.id = s.ECInstanceId\r\n WHERE c.Modifier <> 1 AND c.Type = 0\r\n ORDER BY s.Name, c.Name\r\n `, undefined, { rowFormat: QueryRowFormat.UseJsPropertyNames })) {\r\n rows.push(row);\r\n }\r\n return rows;\r\n }\r\n\r\n private async createContentForClasses(rulesetOrId: Ruleset | string, limitInstances: boolean, displayType: string) {\r\n const classNameEntries = await this.getECClassNames();\r\n\r\n const contents: ContentBuilderResult[] = [];\r\n\r\n for (const nameEntry of classNameEntries) {\r\n // try {\r\n const instanceIds = [];\r\n for await (const row of this._iModel.query(`\r\n SELECT ECInstanceId FROM ONLY \"${nameEntry.schemaName}\".\"${nameEntry.className}\"\r\n ORDER BY ECInstanceId`, undefined, { rowFormat: QueryRowFormat.UseJsPropertyNames, limit: { count: limitInstances ? 1 : 4000 } })) {\r\n instanceIds.push(row.id);\r\n }\r\n\r\n if (!instanceIds.length)\r\n continue;\r\n\r\n const instanceKeys = instanceIds.map((idEntry) => ({ className: `${nameEntry.schemaName}:${nameEntry.className}`, id: idEntry } as InstanceKey));\r\n\r\n contents.push({\r\n className: `${nameEntry.schemaName}:${nameEntry.className}`,\r\n records: await this.createContent(rulesetOrId, instanceKeys, displayType),\r\n });\r\n }\r\n\r\n return contents;\r\n }\r\n\r\n /**\r\n * Create a list of grouped property records using the supplied presentation ruleset.\r\n * Each group includes all of the class instances.\r\n * @param rulesetOrId Either a [[Ruleset]] object or a ruleset id.\r\n * @param displayType Type of content container display. For example:\r\n * \"PropertyPane\", \"Grid\", \"List\" etc.\r\n */\r\n public async createContentForAllInstances(rulesetOrId: Ruleset | string, displayType: string = DefaultContentDisplayTypes.PropertyPane) {\r\n return this.createContentForClasses(rulesetOrId, false, displayType);\r\n }\r\n\r\n /**\r\n * Create a list of grouped property records using the supplied presentation ruleset.\r\n * Each group includes at most one class instance.\r\n * @param rulesetOrId Either a [[Ruleset]] object or a ruleset id.\r\n * @param displayType Type of content container display. For example:\r\n * \"PropertyPane\", \"Grid\", \"List\" etc.\r\n */\r\n public async createContentForInstancePerClass(rulesetOrId: Ruleset | string, displayType: string = DefaultContentDisplayTypes.PropertyPane) {\r\n return this.createContentForClasses(rulesetOrId, true, displayType);\r\n }\r\n}\r\n\r\nclass PropertyRecordsAccumulator extends PropertyRecordsBuilder {\r\n private _records: PropertyRecord[] = [];\r\n private _decimalPrecision?: number;\r\n\r\n public constructor(decimalPrecision?: number) {\r\n super();\r\n this._decimalPrecision = decimalPrecision;\r\n }\r\n\r\n public get records(): PropertyRecord[] {\r\n return this._records;\r\n }\r\n\r\n protected createRootPropertiesAppender() {\r\n return {\r\n append: (record: FieldHierarchyRecord) => {\r\n this._records.push(record.record);\r\n },\r\n };\r\n }\r\n\r\n private processRawValue(value: Value): Value {\r\n if (this._decimalPrecision === undefined)\r\n return value;\r\n\r\n if (typeof value === \"number\") {\r\n return +(Number(value)).toFixed(this._decimalPrecision);\r\n }\r\n\r\n if (Array.isArray(value)) {\r\n return value.map((item) => this.processRawValue(item));\r\n }\r\n\r\n if (value instanceof Object) {\r\n const res: ValuesMap = {};\r\n Object.entries(value).forEach(([key, memberValue]) => {\r\n res[key] = this.processRawValue(memberValue);\r\n });\r\n return res;\r\n }\r\n\r\n return value;\r\n }\r\n\r\n public override processPrimitiveValue(props: ProcessPrimitiveValueProps) {\r\n super.processPrimitiveValue({ ...props, rawValue: this.processRawValue(props.rawValue) });\r\n }\r\n}\r\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itwin/presentation-testing",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -25,18 +25,18 @@
|
|
|
25
25
|
"ignore-styles": "^5.0.1"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@itwin/appui-abstract": "3.2.
|
|
29
|
-
"@itwin/build-tools": "3.2.
|
|
30
|
-
"@itwin/components-react": "3.2.
|
|
31
|
-
"@itwin/core-backend": "3.2.
|
|
32
|
-
"@itwin/core-bentley": "3.2.
|
|
33
|
-
"@itwin/core-common": "3.2.
|
|
34
|
-
"@itwin/core-frontend": "3.2.
|
|
35
|
-
"@itwin/eslint-plugin": "3.2.
|
|
36
|
-
"@itwin/presentation-backend": "3.2.
|
|
37
|
-
"@itwin/presentation-common": "3.2.
|
|
38
|
-
"@itwin/presentation-components": "3.2.
|
|
39
|
-
"@itwin/presentation-frontend": "3.2.
|
|
28
|
+
"@itwin/appui-abstract": "3.2.2",
|
|
29
|
+
"@itwin/build-tools": "3.2.2",
|
|
30
|
+
"@itwin/components-react": "3.2.2",
|
|
31
|
+
"@itwin/core-backend": "3.2.2",
|
|
32
|
+
"@itwin/core-bentley": "3.2.2",
|
|
33
|
+
"@itwin/core-common": "3.2.2",
|
|
34
|
+
"@itwin/core-frontend": "3.2.2",
|
|
35
|
+
"@itwin/eslint-plugin": "3.2.2",
|
|
36
|
+
"@itwin/presentation-backend": "3.2.2",
|
|
37
|
+
"@itwin/presentation-common": "3.2.2",
|
|
38
|
+
"@itwin/presentation-components": "3.2.2",
|
|
39
|
+
"@itwin/presentation-frontend": "3.2.2",
|
|
40
40
|
"@types/chai": "^4.1.4",
|
|
41
41
|
"@types/chai-as-promised": "^7",
|
|
42
42
|
"@types/chai-jest-snapshot": "^1.3.0",
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"eslint": "^7.11.0",
|
|
54
54
|
"faker": "^4.1.0",
|
|
55
55
|
"ignore-styles": "^5.0.1",
|
|
56
|
+
"jsdom": "^19.0.0",
|
|
56
57
|
"jsdom-global": "3.0.2",
|
|
57
58
|
"make-dir": "^1.3.0",
|
|
58
59
|
"mocha": "^8.3.2",
|