Skip to content

Commit

Permalink
fix(material/core): avoid running sanity checks on some test environm…
Browse files Browse the repository at this point in the history
…ents (#23374)

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.

(cherry picked from commit ca67623)
  • Loading branch information
crisbeto authored and wagnermaciel committed Sep 21, 2021
1 parent dc658be commit 01d8e89
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 41 deletions.
35 changes: 7 additions & 28 deletions src/cdk/overlay/overlay-container.ts
Expand Up @@ -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'})
Expand All @@ -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
*/
Expand All @@ -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"]`);
Expand All @@ -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');
Expand Down
28 changes: 28 additions & 0 deletions 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);
}
1 change: 1 addition & 0 deletions src/cdk/platform/public-api.ts
Expand Up @@ -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';
15 changes: 2 additions & 13 deletions src/material/core/common-behaviors/common-module.ts
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand All @@ -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(
Expand Down
3 changes: 3 additions & 0 deletions tools/public_api_guard/cdk/platform.md
Expand Up @@ -21,6 +21,9 @@ export function _getShadowRoot(element: HTMLElement): ShadowRoot | null;
// @public (undocumented)
export function getSupportedInputTypes(): Set<string>;

// @public
export function _isTestEnvironment(): boolean;

// @public
export function normalizePassiveListenerOptions(options: AddEventListenerOptions): AddEventListenerOptions | boolean;

Expand Down

0 comments on commit 01d8e89

Please sign in to comment.