test: make `NgMatchers` type-aware (#19904)

PR Close #19904
This commit is contained in:
George Kalpakas 2018-07-05 15:24:53 +03:00 committed by Miško Hevery
parent 00c110b055
commit 809e8f742e
9 changed files with 39 additions and 59 deletions

View File

@ -217,7 +217,7 @@ function factoryFn(a: any){}
const injector = Injector.create([CarWithOptionalEngine.PROVIDER]);
const car = injector.get<CarWithOptionalEngine>(CarWithOptionalEngine);
expect(car.engine).toEqual(null);
expect(car.engine).toBeNull();
});
it('should flatten passed-in providers', () => {
@ -288,8 +288,8 @@ function factoryFn(a: any){}
Injector.create([CarWithDashboard.PROVIDER, Engine.PROVIDER, Dashboard.PROVIDER]);
expect(() => injector.get(CarWithDashboard))
.toThrowError(
`StaticInjectorError[${stringify(CarWithDashboard)} -> ${stringify(Dashboard)} -> DashboardSoftware]:
NullInjectorError: No provider for DashboardSoftware!`);
`StaticInjectorError[${stringify(CarWithDashboard)} -> ${stringify(Dashboard)} -> DashboardSoftware]: \n` +
' NullInjectorError: No provider for DashboardSoftware!');
});
it('should throw when trying to instantiate a cyclic dependency', () => {
@ -415,8 +415,9 @@ function factoryFn(a: any){}
parent);
expect(() => child.get(Car))
.toThrowError(`StaticInjectorError[${stringify(Car)} -> ${stringify(Engine)}]:
NullInjectorError: No provider for Engine!`);
.toThrowError(
`StaticInjectorError[${stringify(Car)} -> ${stringify(Engine)}]: \n` +
' NullInjectorError: No provider for Engine!');
});
});

View File

@ -343,7 +343,7 @@ function declareTests({useJit}: {useJit: boolean}) {
const fixture = TestBed.createComponent(MyComp);
const tc = fixture.debugElement.children[0];
expect(tc.injector.get(EventDir)).not.toBe(null);
expect(tc.injector.get(EventDir)).not.toBeNull();
});
it('should read directives metadata from their binding token', () => {
@ -1237,7 +1237,7 @@ function declareTests({useJit}: {useJit: boolean}) {
const needsAttribute = tc.injector.get(NeedsAttribute);
expect(needsAttribute.typeAttribute).toEqual('text');
expect(needsAttribute.staticAttribute).toEqual('');
expect(needsAttribute.fooAttribute).toEqual(null);
expect(needsAttribute.fooAttribute).toBeNull();
});
it('should support custom interpolation', () => {

View File

@ -33,37 +33,27 @@ class TurboEngine extends Engine {}
const CARS = new InjectionToken<Car[]>('Cars');
@Injectable()
class Car {
engine: Engine;
constructor(engine: Engine) { this.engine = engine; }
constructor(public engine: Engine) {}
}
@Injectable()
class CarWithOptionalEngine {
engine: Engine;
constructor(@Optional() engine: Engine) { this.engine = engine; }
constructor(@Optional() public engine: Engine) {}
}
@Injectable()
class CarWithDashboard {
engine: Engine;
dashboard: Dashboard;
constructor(engine: Engine, dashboard: Dashboard) {
this.engine = engine;
this.dashboard = dashboard;
}
constructor(public engine: Engine, public dashboard: Dashboard) {}
}
@Injectable()
class SportsCar extends Car {
// TODO(issue/24571): remove '!'.
engine !: Engine;
constructor(engine: Engine) { super(engine); }
}
@Injectable()
class CarWithInject {
engine: Engine;
constructor(@Inject(TurboEngine) engine: Engine) { this.engine = engine; }
constructor(@Inject(TurboEngine) public engine: Engine) {}
}
@Injectable()
@ -747,7 +737,7 @@ function declareTests({useJit}: {useJit: boolean}) {
const injector = createInjector([CarWithOptionalEngine]);
const car = injector.get(CarWithOptionalEngine);
expect(car.engine).toEqual(null);
expect(car.engine).toBeNull();
});
it('should flatten passed-in providers', () => {

View File

@ -659,7 +659,7 @@ class TestComp {
TestBed.configureTestingModule({declarations: [OptionallyNeedsDirective]});
const el = createComponent('<div optionallyNeedsDirective></div>');
const d = el.children[0].injector.get(OptionallyNeedsDirective);
expect(d.dependency).toEqual(null);
expect(d.dependency).toBeNull();
});
it('should instantiate directives that depends on the host component', () => {

View File

@ -115,12 +115,8 @@ class MockBrowserJsonp extends BrowserJsonp {
inject([AsyncTestCompleter], (async: AsyncTestCompleter) => {
const connection = new (JSONPConnection as any)(sampleRequest, new MockBrowserJsonp());
connection.response.subscribe(
(res: Response) => {
expect('response listener called').toBe(false);
async.done();
},
(err: Response) => {
expect(err.text()).toEqual('JSONP injected script did not invoke callback.');
() => async.fail('Response listener should not be called'), (err: Response) => {
expect(err.text()).toBe('JSONP injected script did not invoke callback.');
async.done();
});
@ -132,11 +128,7 @@ class MockBrowserJsonp extends BrowserJsonp {
const connection = new (JSONPConnection as any)(sampleRequest, new MockBrowserJsonp());
connection.response.subscribe(
(res: Response) => {
expect('response listener called').toBe(false);
async.done();
},
(err: Response) => {
() => async.fail('Response listener should not be called'), (err: Response) => {
expect(err.text()).toBe('Oops!');
async.done();
});

View File

@ -212,9 +212,10 @@ function bootstrap(
bootstrap(RootCmp, [{provide: ErrorHandler, useValue: errorHandler}], [], [
CustomModule
]).then(null, (e: Error) => {
expect(e.message).toContain(`StaticInjectorError(TestModule)[CustomCmp -> IDontExist]:
StaticInjectorError(Platform: core)[CustomCmp -> IDontExist]:
NullInjectorError: No provider for IDontExist!`);
expect(e.message).toContain(
'StaticInjectorError(TestModule)[CustomCmp -> IDontExist]: \n' +
' StaticInjectorError(Platform: core)[CustomCmp -> IDontExist]: \n' +
' NullInjectorError: No provider for IDontExist!');
async.done();
return null;
});
@ -255,7 +256,7 @@ function bootstrap(
it('should create an injector promise', () => {
const refPromise = bootstrap(HelloRootCmp, testProviders);
expect(refPromise).not.toBe(null);
expect(refPromise).toEqual(jasmine.any(Promise));
});
it('should set platform name to browser',

View File

@ -15,7 +15,7 @@ import {ɵgetDOM as getDOM} from '@angular/platform-browser';
/**
* Jasmine matchers that check Angular specific conditions.
*/
export interface NgMatchers extends jasmine.Matchers<any> {
export interface NgMatchers<T = any> extends jasmine.Matchers<T> {
/**
* Expect the value to be a `Promise`.
*
@ -82,7 +82,7 @@ export interface NgMatchers extends jasmine.Matchers<any> {
/**
* Invert the matchers.
*/
not: NgMatchers;
not: NgMatchers<T>;
}
const _global = <any>(typeof window === 'undefined' ? global : window);
@ -94,7 +94,7 @@ const _global = <any>(typeof window === 'undefined' ? global : window);
*
* {@example testing/ts/matchers.ts region='toHaveText'}
*/
export const expect: (actual: any) => NgMatchers = <any>_global.expect;
export const expect: <T = any>(actual: T) => NgMatchers<T> = _global.expect;
// Some Map polyfills don't polyfill Map.toString correctly, which

View File

@ -98,7 +98,7 @@ let lastCreatedRenderer: Renderer2;
.createComponent(MyComp2);
const checkSetters = (componentRef: ComponentRef<any>, workerEl: any) => {
expect(lastCreatedRenderer).not.toEqual(null);
expect(lastCreatedRenderer).not.toBeNull();
const el = getRenderElement(workerEl);
lastCreatedRenderer.setProperty(workerEl, 'tabIndex', 1);

View File

@ -187,8 +187,6 @@ describe('Integration', () => {
});
describe('should advance the parent route after deactivating its children', () => {
let log: string[] = [];
@Component({template: '<router-outlet></router-outlet>'})
class Parent {
constructor(route: ActivatedRoute) {
@ -214,10 +212,7 @@ describe('Integration', () => {
class TestModule {
}
beforeEach(() => {
log = [];
TestBed.configureTestingModule({imports: [TestModule]});
});
beforeEach(() => TestBed.configureTestingModule({imports: [TestModule]}));
it('should work',
fakeAsync(inject([Router, Location], (router: Router, location: Location) => {
@ -874,8 +869,8 @@ describe('Integration', () => {
})));
it('should dispatch NavigationError after the url has been reset back', fakeAsync(() => {
const router = TestBed.get(Router);
const location = TestBed.get(Location);
const router: Router = TestBed.get(Router);
const location: SpyLocation = TestBed.get(Location);
const fixture = createRoot(router, RootCmp);
router.resetConfig(
@ -884,9 +879,9 @@ describe('Integration', () => {
router.navigateByUrl('/simple');
advance(fixture);
let routerUrlBeforeEmittingError;
let locationUrlBeforeEmittingError;
router.events.forEach((e: any) => {
let routerUrlBeforeEmittingError = '';
let locationUrlBeforeEmittingError = '';
router.events.forEach(e => {
if (e instanceof NavigationError) {
routerUrlBeforeEmittingError = router.url;
locationUrlBeforeEmittingError = location.path();
@ -965,8 +960,8 @@ describe('Integration', () => {
TestBed.configureTestingModule(
{providers: [{provide: 'returnsFalse', useValue: () => false}]});
const router = TestBed.get(Router);
const location = TestBed.get(Location);
const router: Router = TestBed.get(Router);
const location: SpyLocation = TestBed.get(Location);
const fixture = createRoot(router, RootCmp);
@ -978,18 +973,19 @@ describe('Integration', () => {
router.navigateByUrl('/simple');
advance(fixture);
let routerUrlBeforeEmittingError;
let locationUrlBeforeEmittingError;
router.events.forEach((e: any) => {
let routerUrlBeforeEmittingError = '';
let locationUrlBeforeEmittingError = '';
router.events.forEach(e => {
if (e instanceof NavigationCancel) {
routerUrlBeforeEmittingError = router.url;
locationUrlBeforeEmittingError = location.path();
}
});
(<any>location).simulateHashChange('/throwing');
location.simulateHashChange('/throwing');
advance(fixture);
expect(routerUrlBeforeEmittingError).toEqual('/simple');
expect(locationUrlBeforeEmittingError).toEqual('/simple');
}));