UNPKG

@itwin/presentation-testing

Version:

Testing utilities for iTwin.js Presentation library

131 lines 5.09 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Bentley Systems, Incorporated. All rights reserved. * See LICENSE.md in the project root for license terms and full copyright notice. *--------------------------------------------------------------------------------------------*/ /** @packageDocumentation * @module Helpers */ import { join } from "path"; import { IModelHost } from "@itwin/core-backend"; import { Guid, Logger, LogLevel } from "@itwin/core-bentley"; import { IModelReadRpcInterface, RpcConfiguration, RpcDefaultConfiguration } from "@itwin/core-common"; import { IModelApp, NoRenderApp } from "@itwin/core-frontend"; import { HierarchyCacheMode, Presentation as PresentationBackend, PresentationBackendNativeLoggerCategory, } from "@itwin/presentation-backend"; import { PresentationRpcInterface } from "@itwin/presentation-common"; import { Presentation as PresentationFrontend } from "@itwin/presentation-frontend"; import { getTestOutputDir, setTestOutputDir } from "./FilenameUtils.js"; function initializeRpcInterfaces(interfaces) { const config = class extends RpcDefaultConfiguration { interfaces = () => interfaces; }; for (const definition of interfaces) { // eslint-disable-next-line @itwin/no-internal RpcConfiguration.assign(definition, /* istanbul ignore next */ () => config); } const instance = RpcConfiguration.obtain(config); try { RpcConfiguration.initializeInterfaces(instance); /* c8 ignore start */ } catch { // this may fail with "Error: RPC interface "xxx" is already initialized." because // multiple different tests want to set up rpc interfaces } /* c8 ignore end */ } let isInitialized = false; // eslint-disable-next-line @typescript-eslint/no-deprecated export { HierarchyCacheMode }; /** * Initialize the framework for presentation testing. The function sets up backend, * frontend and RPC communication between them. * * @see `terminate` * * @public */ export const initialize = async (props) => { if (isInitialized) { return; } if (!props) { props = {}; } Logger.initializeToConsole(); Logger.setLevelDefault(LogLevel.Warning); Logger.setLevel("i18n", LogLevel.Error); Logger.setLevel("SQLite", LogLevel.Error); Logger.setLevel(PresentationBackendNativeLoggerCategory.ECObjects, LogLevel.Warning); // set up rpc interfaces initializeRpcInterfaces(props.rpcs ?? [IModelReadRpcInterface, PresentationRpcInterface]); // init backend // make sure backend gets assigned an id which puts its resources into a unique directory props.backendProps = props.backendProps ?? {}; if (!props.backendProps.id) { props.backendProps.id = `test-${Guid.createValue()}`; } await IModelHost.startup({ cacheDir: join(getTestOutputDir(), ".cache", `${process.pid}`), ...props.backendHostProps, }); PresentationBackend.initialize(props.backendProps); // init frontend if (!props.frontendApp) { props.frontendApp = NoRenderApp; } await props.frontendApp.startup(props.frontendAppOptions); const defaultFrontendProps = { presentation: { activeLocale: IModelApp.localization.getLanguageList()[0], }, }; await PresentationFrontend.initialize({ ...defaultFrontendProps, ...props.frontendProps }); setTestOutputDir(props.testOutputDir); isInitialized = true; }; /** * Undoes the setup made by `initialize`. * @param frontendApp IModelApp implementation * * @see `initialize` * * @public */ export const terminate = async (frontendApp = IModelApp) => { if (!isInitialized) { return; } // store directory that needs to be cleaned-up let hierarchiesCacheDirectory; // eslint-disable-next-line @typescript-eslint/no-deprecated const hierarchiesCacheConfig = PresentationBackend.initProps?.caching?.hierarchies; // eslint-disable-next-line @typescript-eslint/no-deprecated if (hierarchiesCacheConfig?.mode === HierarchyCacheMode.Disk) { hierarchiesCacheDirectory = hierarchiesCacheConfig?.directory; // eslint-disable-next-line @typescript-eslint/no-deprecated } else if (hierarchiesCacheConfig?.mode === HierarchyCacheMode.Hybrid) { hierarchiesCacheDirectory = hierarchiesCacheConfig?.disk?.directory; } // terminate backend PresentationBackend.terminate(); await IModelHost.shutdown(); if (hierarchiesCacheDirectory) { const { sync: rimrafSync } = await import("rimraf"); rimrafSync(hierarchiesCacheDirectory); } // terminate frontend PresentationFrontend.terminate(); await frontendApp.shutdown(); isInitialized = false; }; /** @internal */ export function safeDispose(disposable) { if ("dispose" in disposable) { disposable.dispose(); } else if (Symbol.dispose in disposable) { disposable[Symbol.dispose](); } } //# sourceMappingURL=Helpers.js.map