Skip to content

fix(material/core): avoid running sanity checks on some test environments #23374

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 7 additions & 28 deletions src/cdk/overlay/overlay-container.ts
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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