@itwin/presentation-testing 3.0.0-extension.1 → 3.1.0-dev.6

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 CHANGED
@@ -1,6 +1,81 @@
1
1
  # Change Log - @itwin/presentation-testing
2
2
 
3
- This log was last generated on Tue, 21 Sep 2021 21:06:40 GMT and should not be manually modified.
3
+ This log was last generated on Wed, 12 Jan 2022 14:52:38 GMT and should not be manually modified.
4
+
5
+ ## 2.19.28
6
+ Wed, 12 Jan 2022 14:52:38 GMT
7
+
8
+ _Version update only_
9
+
10
+ ## 2.19.27
11
+ Wed, 05 Jan 2022 20:07:20 GMT
12
+
13
+ _Version update only_
14
+
15
+ ## 2.19.26
16
+ Wed, 08 Dec 2021 20:54:53 GMT
17
+
18
+ _Version update only_
19
+
20
+ ## 2.19.25
21
+ Fri, 03 Dec 2021 20:05:49 GMT
22
+
23
+ _Version update only_
24
+
25
+ ## 2.19.24
26
+ Mon, 29 Nov 2021 18:44:31 GMT
27
+
28
+ _Version update only_
29
+
30
+ ## 2.19.23
31
+ Mon, 22 Nov 2021 20:41:40 GMT
32
+
33
+ _Version update only_
34
+
35
+ ## 2.19.22
36
+ Wed, 17 Nov 2021 01:23:26 GMT
37
+
38
+ _Version update only_
39
+
40
+ ## 2.19.21
41
+ Wed, 10 Nov 2021 10:58:24 GMT
42
+
43
+ _Version update only_
44
+
45
+ ## 2.19.20
46
+ Fri, 29 Oct 2021 16:14:22 GMT
47
+
48
+ _Version update only_
49
+
50
+ ## 2.19.19
51
+ Mon, 25 Oct 2021 16:16:25 GMT
52
+
53
+ _Version update only_
54
+
55
+ ## 2.19.18
56
+ Thu, 21 Oct 2021 20:59:44 GMT
57
+
58
+ _Version update only_
59
+
60
+ ## 2.19.17
61
+ Thu, 14 Oct 2021 21:19:43 GMT
62
+
63
+ _Version update only_
64
+
65
+ ## 2.19.16
66
+ Mon, 11 Oct 2021 17:37:46 GMT
67
+
68
+ _Version update only_
69
+
70
+ ## 2.19.15
71
+ Fri, 08 Oct 2021 16:44:23 GMT
72
+
73
+ _Version update only_
74
+
75
+ ## 2.19.14
76
+ Fri, 01 Oct 2021 13:07:03 GMT
77
+
78
+ _Version update only_
4
79
 
5
80
  ## 2.19.13
6
81
  Tue, 21 Sep 2021 21:06:40 GMT
package/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # MIT License
2
2
 
3
- Copyright © 2017-2021 Bentley Systems, Incorporated. All rights reserved.
3
+ Copyright © 2017-2022 Bentley Systems, Incorporated. All rights reserved.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
6
 
@@ -58,7 +58,7 @@ class ContentBuilder {
58
58
  INNER JOIN meta.ECSchemaDef s ON c.Schema.id = s.ECInstanceId
59
59
  WHERE c.Modifier <> 1 AND c.Type = 0
60
60
  ORDER BY s.Name, c.Name
61
- `, undefined, core_common_1.QueryRowFormat.UseJsPropertyNames)) {
61
+ `, undefined, { rowFormat: core_common_1.QueryRowFormat.UseJsPropertyNames })) {
62
62
  rows.push(row);
63
63
  }
64
64
  return rows;
@@ -71,7 +71,7 @@ class ContentBuilder {
71
71
  const instanceIds = [];
72
72
  for await (const row of this._iModel.query(`
73
73
  SELECT ECInstanceId FROM ONLY "${nameEntry.schemaName}"."${nameEntry.className}"
74
- ORDER BY ECInstanceId`, undefined, core_common_1.QueryRowFormat.UseJsPropertyNames, { limit: { count: limitInstances ? 1 : 4000 } })) {
74
+ ORDER BY ECInstanceId`, undefined, { rowFormat: core_common_1.QueryRowFormat.UseJsPropertyNames, limit: { count: limitInstances ? 1 : 4000 } })) {
75
75
  instanceIds.push(row.id);
76
76
  }
77
77
  if (!instanceIds.length)
@@ -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, 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, 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, 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"]}
@@ -73,6 +73,8 @@ const initialize = async (props) => {
73
73
  return;
74
74
  if (!props)
75
75
  props = {};
76
+ // set up rpc interfaces
77
+ initializeRpcInterfaces([core_common_1.SnapshotIModelRpcInterface, core_common_1.IModelReadRpcInterface, presentation_common_1.PresentationRpcInterface]);
76
78
  // init backend
77
79
  // make sure backend gets assigned an id which puts its resources into a unique directory
78
80
  props.backendProps = (_a = props.backendProps) !== null && _a !== void 0 ? _a : {};
@@ -80,8 +82,6 @@ const initialize = async (props) => {
80
82
  props.backendProps.id = `test-${core_bentley_1.Guid.createValue()}`;
81
83
  await core_backend_1.IModelHost.startup();
82
84
  presentation_backend_1.Presentation.initialize(props.backendProps);
83
- // set up rpc interfaces
84
- initializeRpcInterfaces([core_common_1.SnapshotIModelRpcInterface, core_common_1.IModelReadRpcInterface, presentation_common_1.PresentationRpcInterface]);
85
85
  // init frontend
86
86
  if (!props.frontendApp)
87
87
  props.frontendApp = core_frontend_1.NoRenderApp;
@@ -1 +1 @@
1
- {"version":3,"file":"Helpers.js","sourceRoot":"","sources":["../../../src/presentation-testing/Helpers.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/** @packageDocumentation\r\n * @module Helpers\r\n */\r\nimport * as rimraf from \"rimraf\";\r\n// common includes\r\nimport { Guid } from \"@itwin/core-bentley\";\r\n// backend includes\r\nimport { IModelHost } from \"@itwin/core-backend\";\r\n// frontend includes\r\nimport {\r\n IModelReadRpcInterface, RpcConfiguration, RpcDefaultConfiguration, RpcInterfaceDefinition, SnapshotIModelRpcInterface,\r\n} from \"@itwin/core-common\";\r\nimport { IModelApp, IModelAppOptions, NoRenderApp } from \"@itwin/core-frontend\";\r\nimport { HierarchyCacheMode, Presentation as PresentationBackend, PresentationManagerProps as PresentationBackendProps, PresentationManagerMode } from \"@itwin/presentation-backend\";\r\nimport { PresentationRpcInterface } from \"@itwin/presentation-common\";\r\nimport { Presentation as PresentationFrontend, PresentationProps as PresentationFrontendProps } from \"@itwin/presentation-frontend\";\r\n\r\nfunction initializeRpcInterfaces(interfaces: RpcInterfaceDefinition[]) {\r\n const config = class extends RpcDefaultConfiguration {\r\n public override interfaces: any = () => interfaces;\r\n };\r\n\r\n for (const definition of interfaces)\r\n RpcConfiguration.assign(definition, () => config);\r\n\r\n const instance = RpcConfiguration.obtain(config);\r\n\r\n try {\r\n RpcConfiguration.initializeInterfaces(instance);\r\n } catch {\r\n // this may fail with \"Error: RPC interface \"xxx\" is already initialized.\" because\r\n // multiple different tests want to set up rpc interfaces\r\n }\r\n}\r\n\r\nlet isInitialized = false;\r\n\r\nexport { HierarchyCacheMode, PresentationManagerMode, PresentationBackendProps };\r\n\r\n/** @public */\r\nexport interface PresentationTestingInitProps {\r\n /** Properties for backend initialization */\r\n backendProps?: PresentationBackendProps;\r\n /** Properties for frontend initialization */\r\n frontendProps?: PresentationFrontendProps;\r\n /** IModelApp implementation */\r\n frontendApp?: { startup: (opts?: IModelAppOptions) => Promise<void> };\r\n /** IModelApp options */\r\n frontendAppOptions?: IModelAppOptions;\r\n}\r\n\r\n/**\r\n * Initialize the framework for presentation testing. The function sets up backend,\r\n * frontend and RPC communication between them.\r\n *\r\n * @see `terminate`\r\n *\r\n * @public\r\n */\r\nexport const initialize = async (props?: PresentationTestingInitProps) => {\r\n if (isInitialized)\r\n return;\r\n\r\n if (!props)\r\n props = {};\r\n\r\n // init backend\r\n // make sure backend gets assigned an id which puts its resources into a unique directory\r\n props.backendProps = props.backendProps ?? {};\r\n if (!props.backendProps.id)\r\n props.backendProps.id = `test-${Guid.createValue()}`;\r\n await IModelHost.startup();\r\n PresentationBackend.initialize(props.backendProps);\r\n\r\n // set up rpc interfaces\r\n initializeRpcInterfaces([SnapshotIModelRpcInterface, IModelReadRpcInterface, PresentationRpcInterface]);\r\n\r\n // init frontend\r\n if (!props.frontendApp)\r\n props.frontendApp = NoRenderApp;\r\n await props.frontendApp.startup(props.frontendAppOptions);\r\n const defaultFrontendProps: PresentationFrontendProps = {\r\n presentation: {\r\n activeLocale: IModelApp.localization.getLanguageList()[0],\r\n },\r\n };\r\n await PresentationFrontend.initialize({ ...defaultFrontendProps, ...props.frontendProps });\r\n\r\n isInitialized = true;\r\n};\r\n\r\n/**\r\n * Undoes the setup made by `initialize`.\r\n * @param frontendApp IModelApp implementation\r\n *\r\n * @see `initialize`\r\n *\r\n * @public\r\n */\r\nexport const terminate = async (frontendApp = IModelApp) => {\r\n if (!isInitialized)\r\n return;\r\n\r\n // store directory that needs to be cleaned-up\r\n let hierarchiesCacheDirectory: string | undefined;\r\n const hierarchiesCacheConfig = PresentationBackend.initProps?.caching?.hierarchies;\r\n if (hierarchiesCacheConfig?.mode === HierarchyCacheMode.Disk)\r\n hierarchiesCacheDirectory = hierarchiesCacheConfig?.directory;\r\n else if (hierarchiesCacheConfig?.mode === HierarchyCacheMode.Hybrid)\r\n hierarchiesCacheDirectory = hierarchiesCacheConfig?.disk?.directory;\r\n\r\n // terminate backend\r\n PresentationBackend.terminate();\r\n await IModelHost.shutdown();\r\n if (hierarchiesCacheDirectory)\r\n rimraf.sync(hierarchiesCacheDirectory);\r\n\r\n // terminate frontend\r\n PresentationFrontend.terminate();\r\n await frontendApp.shutdown();\r\n\r\n isInitialized = false;\r\n};\r\n"]}
1
+ {"version":3,"file":"Helpers.js","sourceRoot":"","sources":["../../../src/presentation-testing/Helpers.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/** @packageDocumentation\r\n * @module Helpers\r\n */\r\nimport * as rimraf from \"rimraf\";\r\n// common includes\r\nimport { Guid } from \"@itwin/core-bentley\";\r\n// backend includes\r\nimport { IModelHost } from \"@itwin/core-backend\";\r\n// frontend includes\r\nimport {\r\n IModelReadRpcInterface, RpcConfiguration, RpcDefaultConfiguration, RpcInterfaceDefinition, SnapshotIModelRpcInterface,\r\n} from \"@itwin/core-common\";\r\nimport { IModelApp, IModelAppOptions, NoRenderApp } from \"@itwin/core-frontend\";\r\nimport { HierarchyCacheMode, Presentation as PresentationBackend, PresentationManagerProps as PresentationBackendProps, PresentationManagerMode } from \"@itwin/presentation-backend\";\r\nimport { PresentationRpcInterface } from \"@itwin/presentation-common\";\r\nimport { Presentation as PresentationFrontend, PresentationProps as PresentationFrontendProps } from \"@itwin/presentation-frontend\";\r\n\r\nfunction initializeRpcInterfaces(interfaces: RpcInterfaceDefinition[]) {\r\n const config = class extends RpcDefaultConfiguration {\r\n public override interfaces: any = () => interfaces;\r\n };\r\n\r\n for (const definition of interfaces)\r\n RpcConfiguration.assign(definition, () => config);\r\n\r\n const instance = RpcConfiguration.obtain(config);\r\n\r\n try {\r\n RpcConfiguration.initializeInterfaces(instance);\r\n } catch {\r\n // this may fail with \"Error: RPC interface \"xxx\" is already initialized.\" because\r\n // multiple different tests want to set up rpc interfaces\r\n }\r\n}\r\n\r\nlet isInitialized = false;\r\n\r\nexport { HierarchyCacheMode, PresentationManagerMode, PresentationBackendProps };\r\n\r\n/** @public */\r\nexport interface PresentationTestingInitProps {\r\n /** Properties for backend initialization */\r\n backendProps?: PresentationBackendProps;\r\n /** Properties for frontend initialization */\r\n frontendProps?: PresentationFrontendProps;\r\n /** IModelApp implementation */\r\n frontendApp?: { startup: (opts?: IModelAppOptions) => Promise<void> };\r\n /** IModelApp options */\r\n frontendAppOptions?: IModelAppOptions;\r\n}\r\n\r\n/**\r\n * Initialize the framework for presentation testing. The function sets up backend,\r\n * frontend and RPC communication between them.\r\n *\r\n * @see `terminate`\r\n *\r\n * @public\r\n */\r\nexport const initialize = async (props?: PresentationTestingInitProps) => {\r\n if (isInitialized)\r\n return;\r\n\r\n if (!props)\r\n props = {};\r\n\r\n // set up rpc interfaces\r\n initializeRpcInterfaces([SnapshotIModelRpcInterface, IModelReadRpcInterface, PresentationRpcInterface]);\r\n\r\n // init backend\r\n // make sure backend gets assigned an id which puts its resources into a unique directory\r\n props.backendProps = props.backendProps ?? {};\r\n if (!props.backendProps.id)\r\n props.backendProps.id = `test-${Guid.createValue()}`;\r\n await IModelHost.startup();\r\n PresentationBackend.initialize(props.backendProps);\r\n\r\n // init frontend\r\n if (!props.frontendApp)\r\n props.frontendApp = NoRenderApp;\r\n await props.frontendApp.startup(props.frontendAppOptions);\r\n const defaultFrontendProps: PresentationFrontendProps = {\r\n presentation: {\r\n activeLocale: IModelApp.localization.getLanguageList()[0],\r\n },\r\n };\r\n await PresentationFrontend.initialize({ ...defaultFrontendProps, ...props.frontendProps });\r\n\r\n isInitialized = true;\r\n};\r\n\r\n/**\r\n * Undoes the setup made by `initialize`.\r\n * @param frontendApp IModelApp implementation\r\n *\r\n * @see `initialize`\r\n *\r\n * @public\r\n */\r\nexport const terminate = async (frontendApp = IModelApp) => {\r\n if (!isInitialized)\r\n return;\r\n\r\n // store directory that needs to be cleaned-up\r\n let hierarchiesCacheDirectory: string | undefined;\r\n const hierarchiesCacheConfig = PresentationBackend.initProps?.caching?.hierarchies;\r\n if (hierarchiesCacheConfig?.mode === HierarchyCacheMode.Disk)\r\n hierarchiesCacheDirectory = hierarchiesCacheConfig?.directory;\r\n else if (hierarchiesCacheConfig?.mode === HierarchyCacheMode.Hybrid)\r\n hierarchiesCacheDirectory = hierarchiesCacheConfig?.disk?.directory;\r\n\r\n // terminate backend\r\n PresentationBackend.terminate();\r\n await IModelHost.shutdown();\r\n if (hierarchiesCacheDirectory)\r\n rimraf.sync(hierarchiesCacheDirectory);\r\n\r\n // terminate frontend\r\n PresentationFrontend.terminate();\r\n await frontendApp.shutdown();\r\n\r\n isInitialized = false;\r\n};\r\n"]}
@@ -55,7 +55,7 @@ export class ContentBuilder {
55
55
  INNER JOIN meta.ECSchemaDef s ON c.Schema.id = s.ECInstanceId
56
56
  WHERE c.Modifier <> 1 AND c.Type = 0
57
57
  ORDER BY s.Name, c.Name
58
- `, undefined, QueryRowFormat.UseJsPropertyNames)) {
58
+ `, undefined, { rowFormat: QueryRowFormat.UseJsPropertyNames })) {
59
59
  rows.push(row);
60
60
  }
61
61
  return rows;
@@ -68,7 +68,7 @@ export class ContentBuilder {
68
68
  const instanceIds = [];
69
69
  for await (const row of this._iModel.query(`
70
70
  SELECT ECInstanceId FROM ONLY "${nameEntry.schemaName}"."${nameEntry.className}"
71
- ORDER BY ECInstanceId`, undefined, QueryRowFormat.UseJsPropertyNames, { limit: { count: limitInstances ? 1 : 4000 } })) {
71
+ ORDER BY ECInstanceId`, undefined, { rowFormat: QueryRowFormat.UseJsPropertyNames, limit: { count: limitInstances ? 1 : 4000 } })) {
72
72
  instanceIds.push(row.id);
73
73
  }
74
74
  if (!instanceIds.length)
@@ -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, 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, 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, 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"]}
@@ -50,6 +50,8 @@ export const initialize = async (props) => {
50
50
  return;
51
51
  if (!props)
52
52
  props = {};
53
+ // set up rpc interfaces
54
+ initializeRpcInterfaces([SnapshotIModelRpcInterface, IModelReadRpcInterface, PresentationRpcInterface]);
53
55
  // init backend
54
56
  // make sure backend gets assigned an id which puts its resources into a unique directory
55
57
  props.backendProps = (_a = props.backendProps) !== null && _a !== void 0 ? _a : {};
@@ -57,8 +59,6 @@ export const initialize = async (props) => {
57
59
  props.backendProps.id = `test-${Guid.createValue()}`;
58
60
  await IModelHost.startup();
59
61
  PresentationBackend.initialize(props.backendProps);
60
- // set up rpc interfaces
61
- initializeRpcInterfaces([SnapshotIModelRpcInterface, IModelReadRpcInterface, PresentationRpcInterface]);
62
62
  // init frontend
63
63
  if (!props.frontendApp)
64
64
  props.frontendApp = NoRenderApp;
@@ -1 +1 @@
1
- {"version":3,"file":"Helpers.js","sourceRoot":"","sources":["../../../src/presentation-testing/Helpers.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/** @packageDocumentation\r\n * @module Helpers\r\n */\r\nimport * as rimraf from \"rimraf\";\r\n// common includes\r\nimport { Guid } from \"@itwin/core-bentley\";\r\n// backend includes\r\nimport { IModelHost } from \"@itwin/core-backend\";\r\n// frontend includes\r\nimport {\r\n IModelReadRpcInterface, RpcConfiguration, RpcDefaultConfiguration, RpcInterfaceDefinition, SnapshotIModelRpcInterface,\r\n} from \"@itwin/core-common\";\r\nimport { IModelApp, IModelAppOptions, NoRenderApp } from \"@itwin/core-frontend\";\r\nimport { HierarchyCacheMode, Presentation as PresentationBackend, PresentationManagerProps as PresentationBackendProps, PresentationManagerMode } from \"@itwin/presentation-backend\";\r\nimport { PresentationRpcInterface } from \"@itwin/presentation-common\";\r\nimport { Presentation as PresentationFrontend, PresentationProps as PresentationFrontendProps } from \"@itwin/presentation-frontend\";\r\n\r\nfunction initializeRpcInterfaces(interfaces: RpcInterfaceDefinition[]) {\r\n const config = class extends RpcDefaultConfiguration {\r\n public override interfaces: any = () => interfaces;\r\n };\r\n\r\n for (const definition of interfaces)\r\n RpcConfiguration.assign(definition, () => config);\r\n\r\n const instance = RpcConfiguration.obtain(config);\r\n\r\n try {\r\n RpcConfiguration.initializeInterfaces(instance);\r\n } catch {\r\n // this may fail with \"Error: RPC interface \"xxx\" is already initialized.\" because\r\n // multiple different tests want to set up rpc interfaces\r\n }\r\n}\r\n\r\nlet isInitialized = false;\r\n\r\nexport { HierarchyCacheMode, PresentationManagerMode, PresentationBackendProps };\r\n\r\n/** @public */\r\nexport interface PresentationTestingInitProps {\r\n /** Properties for backend initialization */\r\n backendProps?: PresentationBackendProps;\r\n /** Properties for frontend initialization */\r\n frontendProps?: PresentationFrontendProps;\r\n /** IModelApp implementation */\r\n frontendApp?: { startup: (opts?: IModelAppOptions) => Promise<void> };\r\n /** IModelApp options */\r\n frontendAppOptions?: IModelAppOptions;\r\n}\r\n\r\n/**\r\n * Initialize the framework for presentation testing. The function sets up backend,\r\n * frontend and RPC communication between them.\r\n *\r\n * @see `terminate`\r\n *\r\n * @public\r\n */\r\nexport const initialize = async (props?: PresentationTestingInitProps) => {\r\n if (isInitialized)\r\n return;\r\n\r\n if (!props)\r\n props = {};\r\n\r\n // init backend\r\n // make sure backend gets assigned an id which puts its resources into a unique directory\r\n props.backendProps = props.backendProps ?? {};\r\n if (!props.backendProps.id)\r\n props.backendProps.id = `test-${Guid.createValue()}`;\r\n await IModelHost.startup();\r\n PresentationBackend.initialize(props.backendProps);\r\n\r\n // set up rpc interfaces\r\n initializeRpcInterfaces([SnapshotIModelRpcInterface, IModelReadRpcInterface, PresentationRpcInterface]);\r\n\r\n // init frontend\r\n if (!props.frontendApp)\r\n props.frontendApp = NoRenderApp;\r\n await props.frontendApp.startup(props.frontendAppOptions);\r\n const defaultFrontendProps: PresentationFrontendProps = {\r\n presentation: {\r\n activeLocale: IModelApp.localization.getLanguageList()[0],\r\n },\r\n };\r\n await PresentationFrontend.initialize({ ...defaultFrontendProps, ...props.frontendProps });\r\n\r\n isInitialized = true;\r\n};\r\n\r\n/**\r\n * Undoes the setup made by `initialize`.\r\n * @param frontendApp IModelApp implementation\r\n *\r\n * @see `initialize`\r\n *\r\n * @public\r\n */\r\nexport const terminate = async (frontendApp = IModelApp) => {\r\n if (!isInitialized)\r\n return;\r\n\r\n // store directory that needs to be cleaned-up\r\n let hierarchiesCacheDirectory: string | undefined;\r\n const hierarchiesCacheConfig = PresentationBackend.initProps?.caching?.hierarchies;\r\n if (hierarchiesCacheConfig?.mode === HierarchyCacheMode.Disk)\r\n hierarchiesCacheDirectory = hierarchiesCacheConfig?.directory;\r\n else if (hierarchiesCacheConfig?.mode === HierarchyCacheMode.Hybrid)\r\n hierarchiesCacheDirectory = hierarchiesCacheConfig?.disk?.directory;\r\n\r\n // terminate backend\r\n PresentationBackend.terminate();\r\n await IModelHost.shutdown();\r\n if (hierarchiesCacheDirectory)\r\n rimraf.sync(hierarchiesCacheDirectory);\r\n\r\n // terminate frontend\r\n PresentationFrontend.terminate();\r\n await frontendApp.shutdown();\r\n\r\n isInitialized = false;\r\n};\r\n"]}
1
+ {"version":3,"file":"Helpers.js","sourceRoot":"","sources":["../../../src/presentation-testing/Helpers.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/** @packageDocumentation\r\n * @module Helpers\r\n */\r\nimport * as rimraf from \"rimraf\";\r\n// common includes\r\nimport { Guid } from \"@itwin/core-bentley\";\r\n// backend includes\r\nimport { IModelHost } from \"@itwin/core-backend\";\r\n// frontend includes\r\nimport {\r\n IModelReadRpcInterface, RpcConfiguration, RpcDefaultConfiguration, RpcInterfaceDefinition, SnapshotIModelRpcInterface,\r\n} from \"@itwin/core-common\";\r\nimport { IModelApp, IModelAppOptions, NoRenderApp } from \"@itwin/core-frontend\";\r\nimport { HierarchyCacheMode, Presentation as PresentationBackend, PresentationManagerProps as PresentationBackendProps, PresentationManagerMode } from \"@itwin/presentation-backend\";\r\nimport { PresentationRpcInterface } from \"@itwin/presentation-common\";\r\nimport { Presentation as PresentationFrontend, PresentationProps as PresentationFrontendProps } from \"@itwin/presentation-frontend\";\r\n\r\nfunction initializeRpcInterfaces(interfaces: RpcInterfaceDefinition[]) {\r\n const config = class extends RpcDefaultConfiguration {\r\n public override interfaces: any = () => interfaces;\r\n };\r\n\r\n for (const definition of interfaces)\r\n RpcConfiguration.assign(definition, () => config);\r\n\r\n const instance = RpcConfiguration.obtain(config);\r\n\r\n try {\r\n RpcConfiguration.initializeInterfaces(instance);\r\n } catch {\r\n // this may fail with \"Error: RPC interface \"xxx\" is already initialized.\" because\r\n // multiple different tests want to set up rpc interfaces\r\n }\r\n}\r\n\r\nlet isInitialized = false;\r\n\r\nexport { HierarchyCacheMode, PresentationManagerMode, PresentationBackendProps };\r\n\r\n/** @public */\r\nexport interface PresentationTestingInitProps {\r\n /** Properties for backend initialization */\r\n backendProps?: PresentationBackendProps;\r\n /** Properties for frontend initialization */\r\n frontendProps?: PresentationFrontendProps;\r\n /** IModelApp implementation */\r\n frontendApp?: { startup: (opts?: IModelAppOptions) => Promise<void> };\r\n /** IModelApp options */\r\n frontendAppOptions?: IModelAppOptions;\r\n}\r\n\r\n/**\r\n * Initialize the framework for presentation testing. The function sets up backend,\r\n * frontend and RPC communication between them.\r\n *\r\n * @see `terminate`\r\n *\r\n * @public\r\n */\r\nexport const initialize = async (props?: PresentationTestingInitProps) => {\r\n if (isInitialized)\r\n return;\r\n\r\n if (!props)\r\n props = {};\r\n\r\n // set up rpc interfaces\r\n initializeRpcInterfaces([SnapshotIModelRpcInterface, IModelReadRpcInterface, PresentationRpcInterface]);\r\n\r\n // init backend\r\n // make sure backend gets assigned an id which puts its resources into a unique directory\r\n props.backendProps = props.backendProps ?? {};\r\n if (!props.backendProps.id)\r\n props.backendProps.id = `test-${Guid.createValue()}`;\r\n await IModelHost.startup();\r\n PresentationBackend.initialize(props.backendProps);\r\n\r\n // init frontend\r\n if (!props.frontendApp)\r\n props.frontendApp = NoRenderApp;\r\n await props.frontendApp.startup(props.frontendAppOptions);\r\n const defaultFrontendProps: PresentationFrontendProps = {\r\n presentation: {\r\n activeLocale: IModelApp.localization.getLanguageList()[0],\r\n },\r\n };\r\n await PresentationFrontend.initialize({ ...defaultFrontendProps, ...props.frontendProps });\r\n\r\n isInitialized = true;\r\n};\r\n\r\n/**\r\n * Undoes the setup made by `initialize`.\r\n * @param frontendApp IModelApp implementation\r\n *\r\n * @see `initialize`\r\n *\r\n * @public\r\n */\r\nexport const terminate = async (frontendApp = IModelApp) => {\r\n if (!isInitialized)\r\n return;\r\n\r\n // store directory that needs to be cleaned-up\r\n let hierarchiesCacheDirectory: string | undefined;\r\n const hierarchiesCacheConfig = PresentationBackend.initProps?.caching?.hierarchies;\r\n if (hierarchiesCacheConfig?.mode === HierarchyCacheMode.Disk)\r\n hierarchiesCacheDirectory = hierarchiesCacheConfig?.directory;\r\n else if (hierarchiesCacheConfig?.mode === HierarchyCacheMode.Hybrid)\r\n hierarchiesCacheDirectory = hierarchiesCacheConfig?.disk?.directory;\r\n\r\n // terminate backend\r\n PresentationBackend.terminate();\r\n await IModelHost.shutdown();\r\n if (hierarchiesCacheDirectory)\r\n rimraf.sync(hierarchiesCacheDirectory);\r\n\r\n // terminate frontend\r\n PresentationFrontend.terminate();\r\n await frontendApp.shutdown();\r\n\r\n isInitialized = false;\r\n};\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/presentation-testing",
3
- "version": "3.0.0-extension.1",
3
+ "version": "3.1.0-dev.6",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -10,7 +10,7 @@
10
10
  "keywords": [
11
11
  "Bentley",
12
12
  "Presentation",
13
- "iModelJS",
13
+ "iTwin.js",
14
14
  "Testing"
15
15
  ],
16
16
  "author": {
@@ -21,23 +21,22 @@
21
21
  "module": "lib/esm/presentation-testing.js",
22
22
  "typings": "lib/cjs/presentation-testing",
23
23
  "devDependencies": {
24
- "cpx": "^1.5.0",
24
+ "cpx2": "^3.0.0",
25
25
  "ignore-styles": "^5.0.1"
26
26
  },
27
27
  "dependencies": {
28
- "@itwin/core-bentley": "3.0.0-extension.1",
29
- "@itwin/build-tools": "3.0.0-extension.1",
30
- "@itwin/eslint-plugin": "3.0.0-extension.1",
31
- "@itwin/core-backend": "3.0.0-extension.1",
32
- "@itwin/core-common": "3.0.0-extension.1",
33
- "@itwin/core-frontend": "3.0.0-extension.1",
34
- "@bentley/itwin-client": "3.0.0-extension.1",
35
- "@itwin/presentation-backend": "3.0.0-extension.1",
36
- "@itwin/presentation-common": "3.0.0-extension.1",
37
- "@itwin/presentation-components": "3.0.0-extension.1",
38
- "@itwin/presentation-frontend": "3.0.0-extension.1",
39
- "@itwin/appui-abstract": "3.0.0-extension.1",
40
- "@itwin/components-react": "3.0.0-extension.1",
28
+ "@itwin/appui-abstract": "3.1.0-dev.6",
29
+ "@itwin/build-tools": "3.1.0-dev.6",
30
+ "@itwin/components-react": "3.1.0-dev.6",
31
+ "@itwin/core-backend": "3.1.0-dev.6",
32
+ "@itwin/core-bentley": "3.1.0-dev.6",
33
+ "@itwin/core-common": "3.1.0-dev.6",
34
+ "@itwin/core-frontend": "3.1.0-dev.6",
35
+ "@itwin/eslint-plugin": "3.1.0-dev.6",
36
+ "@itwin/presentation-backend": "3.1.0-dev.6",
37
+ "@itwin/presentation-common": "3.1.0-dev.6",
38
+ "@itwin/presentation-components": "3.1.0-dev.6",
39
+ "@itwin/presentation-frontend": "3.1.0-dev.6",
41
40
  "@types/chai": "^4.1.4",
42
41
  "@types/chai-as-promised": "^7",
43
42
  "@types/chai-jest-snapshot": "^1.3.0",
@@ -88,10 +87,11 @@
88
87
  "cover": "nyc npm -s test",
89
88
  "docs": "npm run -s docs:reference && npm run -s docs:changelog",
90
89
  "docs:changelog": "cpx ./CHANGELOG.md ../../generated-docs/presentation/presentation-testing",
91
- "docs:reference": "betools docs --includes=../../generated-docs/extract --json=../../generated-docs/presentation/presentation-testing/json/file.json --tsIndexFile=presentation-testing.ts --onlyJson",
90
+ "docs:reference": "",
92
91
  "extract": "betools extract --fileExt=ts --extractFrom=./src/test --recursive --out=../../generated-docs/extract",
93
92
  "extract-api": "betools extract-api --entry=presentation-testing",
94
93
  "lint": "eslint -f visualstudio \"./src/**/*.ts\" 1>&2",
95
94
  "test": "mocha -r ignore-styles -r jsdom-global/register --config ../.mocharc.json \"./lib/cjs/test/**/*.test.js\""
96
- }
95
+ },
96
+ "readme": "# @itwin/presentation-testing\r\n\r\nCopyright © Bentley Systems, Incorporated. All rights reserved. See LICENSE.md for license terms and full copyright notice.\r\n\r\n## Description\r\n\r\nThe __@itwin/presentation-testing__ package contains helper classes and APIs that help test presentation modules."
97
97
  }