refactor(core): ensure compatibility with typescript strict flag (#30993)

As part of FW-1265, the `@angular/core` package is made compatible
with the TypeScript `--strict` flag. This already unveiled a few bugs,
so the strictness flag seems to help with increasing the overall code health.

Read more about the strict flag [here](https://www.typescriptlang.org/docs/handbook/compiler-options.html)

PR Close #30993
This commit is contained in:
Paul Gschwendtner
2019-06-14 09:27:41 +02:00
committed by Miško Hevery
parent 78e7fdd98d
commit 2200884e55
29 changed files with 122 additions and 86 deletions

View File

@ -36,7 +36,7 @@ export function asyncFallback(fn: Function): (done: any) => any {
// function when asynchronous activity is finished.
if (_global.jasmine) {
// Not using an arrow function to preserve context passed from call site
return function(done: any) {
return function(this: unknown, done: any) {
if (!done) {
// if we run beforeEach in @angular/core/testing/testing_internal then we get no done
// fake it here and assume sync.
@ -56,7 +56,7 @@ export function asyncFallback(fn: Function): (done: any) => any {
// is finished. This will be correctly consumed by the Mocha framework with
// it('...', async(myFn)); or can be used in a custom framework.
// Not using an arrow function to preserve context passed from call site
return function() {
return function(this: unknown) {
return new Promise<void>((finishCallback, failCallback) => {
runInTestZone(fn, this, finishCallback, failCallback);
});

View File

@ -55,7 +55,7 @@ let _inFakeAsyncCall = false;
*/
export function fakeAsyncFallback(fn: Function): (...args: any[]) => any {
// Not using an arrow function to preserve context passed from call site
return function(...args: any[]) {
return function(this: unknown, ...args: any[]) {
const proxyZoneSpec = ProxyZoneSpec.assertPresent();
if (_inFakeAsyncCall) {
throw new Error('fakeAsync() calls can not be nested');

View File

@ -517,20 +517,21 @@ export class R3TestBedCompiler {
op.def[op.field] = op.original;
}
// Restore initial component/directive/pipe defs
this.initialNgDefs.forEach((value: [string, PropertyDescriptor], type: Type<any>) => {
const [prop, descriptor] = value;
if (!descriptor) {
// Delete operations are generally undesirable since they have performance implications
// on objects they were applied to. In this particular case, situations where this code is
// invoked should be quite rare to cause any noticable impact, since it's applied only to
// some test cases (for example when class with no annotations extends some @Component)
// when we need to clear 'ngComponentDef' field on a given class to restore its original
// state (before applying overrides and running tests).
delete (type as any)[prop];
} else {
Object.defineProperty(type, prop, descriptor);
}
});
this.initialNgDefs.forEach(
(value: [string, PropertyDescriptor | undefined], type: Type<any>) => {
const [prop, descriptor] = value;
if (!descriptor) {
// Delete operations are generally undesirable since they have performance implications
// on objects they were applied to. In this particular case, situations where this code
// is invoked should be quite rare to cause any noticeable impact, since it's applied
// only to some test cases (for example when class with no annotations extends some
// @Component) when we need to clear 'ngComponentDef' field on a given class to restore
// its original state (before applying overrides and running tests).
delete (type as any)[prop];
} else {
Object.defineProperty(type, prop, descriptor);
}
});
this.initialNgDefs.clear();
this.moduleProvidersOverridden.clear();
this.restoreComponentResolutionQueue();

View File

@ -654,7 +654,7 @@ export function inject(tokens: any[], fn: Function): () => any {
const testBed = getTestBed();
if (tokens.indexOf(AsyncTestCompleter) >= 0) {
// Not using an arrow function to preserve context passed from call site
return function() {
return function(this: unknown) {
// Return an async test method that returns a Promise if AsyncTestCompleter is one of
// the injected tokens.
return testBed.compileComponents().then(() => {
@ -665,7 +665,7 @@ export function inject(tokens: any[], fn: Function): () => any {
};
} else {
// Not using an arrow function to preserve context passed from call site
return function() { return testBed.execute(tokens, fn, this); };
return function(this: unknown) { return testBed.execute(tokens, fn, this); };
}
}
@ -685,7 +685,7 @@ export class InjectSetupWrapper {
inject(tokens: any[], fn: Function): () => any {
const self = this;
// Not using an arrow function to preserve context passed from call site
return function() {
return function(this: unknown) {
self._addModule();
return inject(tokens, fn).call(this);
};
@ -701,7 +701,7 @@ export function withModule(moduleDef: TestModuleMetadata, fn?: Function | null):
InjectSetupWrapper {
if (fn) {
// Not using an arrow function to preserve context passed from call site
return function() {
return function(this: unknown) {
const testBed = getTestBed();
if (moduleDef) {
testBed.configureTestingModule(moduleDef);

View File

@ -39,6 +39,8 @@ const globalTimeOut = jasmine.DEFAULT_TIMEOUT_INTERVAL;
const testBed = getTestBed();
export type TestFn = ((done: DoneFn) => any) | (() => any);
/**
* Mechanism to run `beforeEach()` functions of Angular tests.
*
@ -112,8 +114,7 @@ export function beforeEachProviders(fn: Function): void {
}
function _it(
jsmFn: Function, testName: string, testFn: (done?: DoneFn) => any, testTimeout = 0): void {
function _it(jsmFn: Function, testName: string, testFn: TestFn, testTimeout = 0): void {
if (runnerStack.length == 0) {
// This left here intentionally, as we should never get here, and it aids debugging.
// tslint:disable-next-line
@ -135,7 +136,9 @@ function _it(
runner.run();
if (testFn.length === 0) {
const retVal = testFn();
// TypeScript doesn't infer the TestFn type without parameters here, so we
// need to manually cast it.
const retVal = (testFn as() => any)();
if (isPromise(retVal)) {
// Asynchronous test function that returns a Promise - wait for completion.
retVal.then(done, done.fail);
@ -150,15 +153,15 @@ function _it(
}, timeout);
}
export function it(expectation: string, assertion: (done: DoneFn) => any, timeout?: number): void {
export function it(expectation: string, assertion: TestFn, timeout?: number): void {
return _it(jsmIt, expectation, assertion, timeout);
}
export function fit(expectation: string, assertion: (done: DoneFn) => any, timeout?: number): void {
export function fit(expectation: string, assertion: TestFn, timeout?: number): void {
return _it(jsmFIt, expectation, assertion, timeout);
}
export function xit(expectation: string, assertion: (done: DoneFn) => any, timeout?: number): void {
export function xit(expectation: string, assertion: TestFn, timeout?: number): void {
return _it(jsmXIt, expectation, assertion, timeout);
}