Skip to content

Commit 447eb55

Browse files
committed
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.
1 parent 8424209 commit 447eb55

File tree

5 files changed

+33
-43
lines changed

5 files changed

+33
-43
lines changed

src/cdk/overlay/overlay-container.ts

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,6 @@ import {DOCUMENT} from '@angular/common';
1010
import {Inject, Injectable, OnDestroy} from '@angular/core';
1111
import {Platform} from '@angular/cdk/platform';
1212

13-
// Avoid using `declare const` because it caused conflicts inside Google
14-
// with the real typings for these symbols. We use `declare interface` instead
15-
// of just `interface` for interop with Closure Compiler (prevents property renaming):
16-
// https://github.com/angular/tsickle/blob/master/README.md#differences-from-typescript
17-
declare interface TestGlobals {
18-
jasmine: unknown;
19-
__karma__: unknown;
20-
jest: unknown;
21-
Mocha: unknown;
22-
}
23-
24-
const globalsForTest = (typeof window !== 'undefined' ? window : {}) as {} as TestGlobals;
25-
26-
/**
27-
* Whether we're in a testing environment.
28-
* TODO(crisbeto): remove this once we have an overlay testing module or Angular starts tearing
29-
* down the testing `NgModule` (see https://github.com/angular/angular/issues/18831).
30-
*/
31-
const isTestEnvironment =
32-
(typeof globalsForTest.__karma__ !== 'undefined' && !!globalsForTest.__karma__) ||
33-
(typeof globalsForTest.jasmine !== 'undefined' && !!globalsForTest.jasmine) ||
34-
(typeof globalsForTest.jest !== 'undefined' && !!globalsForTest.jest) ||
35-
(typeof globalsForTest.Mocha !== 'undefined' && !!globalsForTest.Mocha);
36-
3713
/** Container inside which all overlays will render. */
3814
@Injectable({providedIn: 'root'})
3915
export class OverlayContainer implements OnDestroy {
@@ -54,7 +30,7 @@ export class OverlayContainer implements OnDestroy {
5430

5531
/**
5632
* This method returns the overlay container element. It will lazily
57-
* create the element the first time it is called to facilitate using
33+
* create the element the first time it is called to facilitate using
5834
* the container in non-browser environments.
5935
* @returns the container element
6036
*/
@@ -73,7 +49,10 @@ export class OverlayContainer implements OnDestroy {
7349
protected _createContainer(): void {
7450
const containerClass = 'cdk-overlay-container';
7551

76-
if (this._platform.isBrowser || isTestEnvironment) {
52+
// TODO(crisbeto): remove the testing check once we have an overlay testing
53+
// module or Angular starts tearing down the testing `NgModule`. See:
54+
// https://github.com/angular/angular/issues/18831
55+
if (this._platform.isBrowser || this._platform.isTest) {
7756
const oppositePlatformContainers =
7857
this._document.querySelectorAll(`.${containerClass}[platform="server"], ` +
7958
`.${containerClass}[platform="test"]`);
@@ -97,7 +76,7 @@ export class OverlayContainer implements OnDestroy {
9776
// module which does the cleanup, we try to detect that we're in a test environment and we
9877
// always clear the container. See #17006.
9978
// TODO(crisbeto): remove the test environment check once we have an overlay testing module.
100-
if (isTestEnvironment) {
79+
if (this._platform.isTest) {
10180
container.setAttribute('platform', 'test');
10281
} else if (!this._platform.isBrowser) {
10382
container.setAttribute('platform', 'server');

src/cdk/platform/platform.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,19 @@ try {
2424
hasV8BreakIterator = false;
2525
}
2626

27+
// Avoid using `declare const` because it caused conflicts inside Google
28+
// with the real typings for these symbols. We use `declare interface` instead
29+
// of just `interface` for interop with Closure Compiler (prevents property renaming):
30+
// https://github.com/angular/tsickle/blob/master/README.md#differences-from-typescript
31+
declare interface TestGlobals {
32+
jasmine: unknown;
33+
__karma__: unknown;
34+
jest: unknown;
35+
Mocha: unknown;
36+
}
37+
38+
const testGlobals = (typeof window !== 'undefined' ? window : {}) as {} as TestGlobals;
39+
2740
/**
2841
* Service to detect the current platform by comparing the userAgent strings and
2942
* checking browser-specific global properties.
@@ -37,6 +50,13 @@ export class Platform {
3750
isBrowser: boolean = this._platformId ?
3851
isPlatformBrowser(this._platformId) : typeof document === 'object' && !!document;
3952

53+
/** Whether the application is running inside a testing environment. */
54+
isTest: boolean =
55+
(typeof testGlobals.__karma__ !== 'undefined' && !!testGlobals.__karma__) ||
56+
(typeof testGlobals.jasmine !== 'undefined' && !!testGlobals.jasmine) ||
57+
(typeof testGlobals.jest !== 'undefined' && !!testGlobals.jest) ||
58+
(typeof testGlobals.Mocha !== 'undefined' && !!testGlobals.Mocha);
59+
4060
/** Whether the current browser is Microsoft Edge. */
4161
EDGE: boolean = this.isBrowser && /(edge)/i.test(navigator.userAgent);
4262

src/material/core/common-behaviors/common-module.ts

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {BidiModule} from '@angular/cdk/bidi';
1111
import {Inject, InjectionToken, isDevMode, NgModule, Optional, Version} from '@angular/core';
1212
import {VERSION as CDK_VERSION} from '@angular/cdk';
1313
import {DOCUMENT} from '@angular/common';
14+
import {Platform} from '@angular/cdk/platform';
1415

1516
// Private version constant to circumvent test/build issues,
1617
// i.e. avoid core to depend on the @angular/material primary entry-point
@@ -65,7 +66,8 @@ export class MatCommonModule {
6566
constructor(
6667
highContrastModeDetector: HighContrastModeDetector,
6768
@Optional() @Inject(MATERIAL_SANITY_CHECKS) sanityChecks: any,
68-
@Inject(DOCUMENT) document: any) {
69+
@Inject(DOCUMENT) document: any,
70+
@Optional() private _platform?: Platform) {
6971
this._document = document;
7072

7173
// While A11yModule also does this, we repeat it here to avoid importing A11yModule
@@ -84,19 +86,13 @@ export class MatCommonModule {
8486
}
8587
}
8688

87-
/** Use defaultView of injected document if available or fallback to global window reference */
88-
private _getWindow(): Window | null {
89-
const win = this._document.defaultView || window;
90-
return typeof win === 'object' && win ? win : null;
91-
}
92-
9389
/** Gets whether a specific sanity check is enabled. */
9490
private _checkIsEnabled(name: keyof GranularSanityChecks): boolean {
9591
// TODO(crisbeto): we can't use `ngDevMode` here yet, because ViewEngine apps might not support
9692
// it. Since these checks can have performance implications and they aren't tree shakeable
9793
// in their current form, we can leave the `isDevMode` check in for now.
9894
// tslint:disable-next-line:ban
99-
if (!isDevMode() || this._isTestEnv()) {
95+
if (!isDevMode() || this._platform?.isTest) {
10096
return false;
10197
}
10298

@@ -107,12 +103,6 @@ export class MatCommonModule {
107103
return !!this._sanityChecks[name];
108104
}
109105

110-
/** Whether the code is running in tests. */
111-
private _isTestEnv() {
112-
const window = this._getWindow() as any;
113-
return window && (window.__karma__ || window.jasmine);
114-
}
115-
116106
private _checkDoctypeIsDefined(): void {
117107
if (this._checkIsEnabled('doctype') && !this._document.doctype) {
118108
console.warn(

tools/public_api_guard/cdk/platform.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export class Platform {
3333
FIREFOX: boolean;
3434
IOS: boolean;
3535
isBrowser: boolean;
36+
isTest: boolean;
3637
SAFARI: boolean;
3738
TRIDENT: boolean;
3839
WEBKIT: boolean;

tools/public_api_guard/material/core.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,10 @@ export const MAT_RIPPLE_GLOBAL_OPTIONS: InjectionToken<RippleGlobalOptions>;
200200

201201
// @public
202202
export class MatCommonModule {
203-
constructor(highContrastModeDetector: HighContrastModeDetector, sanityChecks: any, document: any);
203+
constructor(highContrastModeDetector: HighContrastModeDetector, sanityChecks: any, document: any, _platform?: Platform | undefined);
204204
protected _document: Document;
205205
// (undocumented)
206-
static ɵfac: i0.ɵɵFactoryDeclaration<MatCommonModule, [null, { optional: true; }, null]>;
206+
static ɵfac: i0.ɵɵFactoryDeclaration<MatCommonModule, [null, { optional: true; }, null, { optional: true; }]>;
207207
// (undocumented)
208208
static ɵinj: i0.ɵɵInjectorDeclaration<MatCommonModule>;
209209
// (undocumented)

0 commit comments

Comments
 (0)