From 7ceb7ad27e41be3e42e5cd8de245711a74102243 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Sun, 29 Aug 2021 15:29:08 +0200 Subject: [PATCH] fix(material/core): avoid running sanity checks on some test environments Fixes that the sanity checks were running on some testing environments like Jest. These changes also move the test environment check into a centralized place so that it's easier to keep up to date. Fixes #23365. --- src/cdk/overlay/overlay-container.ts | 35 ++++--------------- src/cdk/platform/features/test-environment.ts | 28 +++++++++++++++ src/cdk/platform/public-api.ts | 1 + .../core/common-behaviors/common-module.ts | 15 ++------ tools/public_api_guard/cdk/platform.md | 3 ++ 5 files changed, 41 insertions(+), 41 deletions(-) create mode 100644 src/cdk/platform/features/test-environment.ts diff --git a/src/cdk/overlay/overlay-container.ts b/src/cdk/overlay/overlay-container.ts index fac5e1bba66b..e04a84ef3703 100644 --- a/src/cdk/overlay/overlay-container.ts +++ b/src/cdk/overlay/overlay-container.ts @@ -8,31 +8,7 @@ import {DOCUMENT} from '@angular/common'; import {Inject, Injectable, OnDestroy} from '@angular/core'; -import {Platform} from '@angular/cdk/platform'; - -// Avoid using `declare const` because it caused conflicts inside Google -// with the real typings for these symbols. We use `declare interface` instead -// of just `interface` for interop with Closure Compiler (prevents property renaming): -// https://github.com/angular/tsickle/blob/master/README.md#differences-from-typescript -declare interface TestGlobals { - jasmine: unknown; - __karma__: unknown; - jest: unknown; - Mocha: unknown; -} - -const globalsForTest = (typeof window !== 'undefined' ? window : {}) as {} as TestGlobals; - -/** - * Whether we're in a testing environment. - * TODO(crisbeto): remove this once we have an overlay testing module or Angular starts tearing - * down the testing `NgModule` (see https://github.com/angular/angular/issues/18831). - */ -const isTestEnvironment = - (typeof globalsForTest.__karma__ !== 'undefined' && !!globalsForTest.__karma__) || - (typeof globalsForTest.jasmine !== 'undefined' && !!globalsForTest.jasmine) || - (typeof globalsForTest.jest !== 'undefined' && !!globalsForTest.jest) || - (typeof globalsForTest.Mocha !== 'undefined' && !!globalsForTest.Mocha); +import {Platform, _isTestEnvironment} from '@angular/cdk/platform'; /** Container inside which all overlays will render. */ @Injectable({providedIn: 'root'}) @@ -54,7 +30,7 @@ export class OverlayContainer implements OnDestroy { /** * This method returns the overlay container element. It will lazily - * create the element the first time it is called to facilitate using + * create the element the first time it is called to facilitate using * the container in non-browser environments. * @returns the container element */ @@ -73,7 +49,10 @@ export class OverlayContainer implements OnDestroy { protected _createContainer(): void { const containerClass = 'cdk-overlay-container'; - if (this._platform.isBrowser || isTestEnvironment) { + // TODO(crisbeto): remove the testing check once we have an overlay testing + // module or Angular starts tearing down the testing `NgModule`. See: + // https://github.com/angular/angular/issues/18831 + if (this._platform.isBrowser || _isTestEnvironment()) { const oppositePlatformContainers = this._document.querySelectorAll(`.${containerClass}[platform="server"], ` + `.${containerClass}[platform="test"]`); @@ -97,7 +76,7 @@ export class OverlayContainer implements OnDestroy { // module which does the cleanup, we try to detect that we're in a test environment and we // always clear the container. See #17006. // TODO(crisbeto): remove the test environment check once we have an overlay testing module. - if (isTestEnvironment) { + if (_isTestEnvironment()) { container.setAttribute('platform', 'test'); } else if (!this._platform.isBrowser) { container.setAttribute('platform', 'server'); diff --git a/src/cdk/platform/features/test-environment.ts b/src/cdk/platform/features/test-environment.ts new file mode 100644 index 000000000000..b5a6fb4b4ed7 --- /dev/null +++ b/src/cdk/platform/features/test-environment.ts @@ -0,0 +1,28 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +// Avoid using `declare const` because it caused conflicts inside Google +// with the real typings for these symbols. We use `declare interface` instead +// of just `interface` for interop with Closure Compiler (prevents property renaming): +// https://github.com/angular/tsickle/blob/master/README.md#differences-from-typescript +declare interface TestGlobals { + jasmine: unknown; + __karma__: unknown; + jest: unknown; + Mocha: unknown; +} + +const testGlobals = (typeof window !== 'undefined' ? window : {}) as {} as TestGlobals; + +/** Gets whether the code is currently running in a test environment. */ +export function _isTestEnvironment(): boolean { + return (typeof testGlobals.__karma__ !== 'undefined' && !!testGlobals.__karma__) || + (typeof testGlobals.jasmine !== 'undefined' && !!testGlobals.jasmine) || + (typeof testGlobals.jest !== 'undefined' && !!testGlobals.jest) || + (typeof testGlobals.Mocha !== 'undefined' && !!testGlobals.Mocha); +} diff --git a/src/cdk/platform/public-api.ts b/src/cdk/platform/public-api.ts index 65f9e72f89a9..61c8b1acb24b 100644 --- a/src/cdk/platform/public-api.ts +++ b/src/cdk/platform/public-api.ts @@ -12,3 +12,4 @@ export * from './features/input-types'; export * from './features/passive-listeners'; export * from './features/scrolling'; export * from './features/shadow-dom'; +export * from './features/test-environment'; diff --git a/src/material/core/common-behaviors/common-module.ts b/src/material/core/common-behaviors/common-module.ts index e4579f16f356..a2e0189baa20 100644 --- a/src/material/core/common-behaviors/common-module.ts +++ b/src/material/core/common-behaviors/common-module.ts @@ -11,6 +11,7 @@ import {BidiModule} from '@angular/cdk/bidi'; import {Inject, InjectionToken, isDevMode, NgModule, Optional, Version} from '@angular/core'; import {VERSION as CDK_VERSION} from '@angular/cdk'; import {DOCUMENT} from '@angular/common'; +import {_isTestEnvironment} from '@angular/cdk/platform'; // Private version constant to circumvent test/build issues, // i.e. avoid core to depend on the @angular/material primary entry-point @@ -84,19 +85,13 @@ export class MatCommonModule { } } - /** Use defaultView of injected document if available or fallback to global window reference */ - private _getWindow(): Window | null { - const win = this._document.defaultView || window; - return typeof win === 'object' && win ? win : null; - } - /** Gets whether a specific sanity check is enabled. */ private _checkIsEnabled(name: keyof GranularSanityChecks): boolean { // TODO(crisbeto): we can't use `ngDevMode` here yet, because ViewEngine apps might not support // it. Since these checks can have performance implications and they aren't tree shakeable // in their current form, we can leave the `isDevMode` check in for now. // tslint:disable-next-line:ban - if (!isDevMode() || this._isTestEnv()) { + if (!isDevMode() || _isTestEnvironment()) { return false; } @@ -107,12 +102,6 @@ export class MatCommonModule { return !!this._sanityChecks[name]; } - /** Whether the code is running in tests. */ - private _isTestEnv() { - const window = this._getWindow() as any; - return window && (window.__karma__ || window.jasmine); - } - private _checkDoctypeIsDefined(): void { if (this._checkIsEnabled('doctype') && !this._document.doctype) { console.warn( diff --git a/tools/public_api_guard/cdk/platform.md b/tools/public_api_guard/cdk/platform.md index b11b4aabc481..054d150551a0 100644 --- a/tools/public_api_guard/cdk/platform.md +++ b/tools/public_api_guard/cdk/platform.md @@ -21,6 +21,9 @@ export function _getShadowRoot(element: HTMLElement): ShadowRoot | null; // @public (undocumented) export function getSupportedInputTypes(): Set; +// @public +export function _isTestEnvironment(): boolean; + // @public export function normalizePassiveListenerOptions(options: AddEventListenerOptions): AddEventListenerOptions | boolean;