style(aio): enforce strict TypeScript checks (#21342)

Closes #20646

PR Close #21342
This commit is contained in:
Pete Bacon Darwin
2018-01-12 14:36:43 -08:00
committed by Alex Eagle
parent 246de65140
commit c5c6d84fe6
57 changed files with 198 additions and 194 deletions
@@ -18,7 +18,6 @@
"@angular/core": "^5.0.0",
"@angular/forms": "^5.0.0",
"@angular/http": "^5.0.0",
"@angular/service-worker": "^5.0.0",
"@angular/platform-browser": "^5.0.0",
"@angular/platform-browser-dynamic": "^5.0.0",
"@angular/router": "^5.0.0",
+1 -1
View File
@@ -25,7 +25,7 @@ export class ApiPage extends SitePage {
// and we want to be able to pull out the code elements from only the first level
// if `onlyDirect` is set to `true`.
const selector = `.descendants.${docType} ${onlyDirect ? '>' : ''} li > :not(ul) code`;
return element.all(by.css(selector)).map<string>(item => item.getText());
return element.all(by.css(selector)).map<string>(item => item && item.getText());
}
getOverview(docType) {
+1 -1
View File
@@ -62,6 +62,6 @@ export class SitePage {
getSearchResults() {
const results = element.all(by.css('.search-results li'));
browser.wait(ExpectedConditions.presenceOf(results.first()), 8000);
return results.map(link => link.getText());
return results.map(link => link && link.getText());
}
}
+12 -12
View File
@@ -314,7 +314,7 @@ describe('AppComponent', () => {
it('should not navigate when change to a version without a url', () => {
setupSelectorForTesting();
const versionWithoutUrlIndex = component.docVersions.length;
const versionWithoutUrl = component.docVersions[versionWithoutUrlIndex] = { title: 'foo', url: null };
const versionWithoutUrl = component.docVersions[versionWithoutUrlIndex] = { title: 'foo' };
selectElement.triggerEventHandler('change', { option: versionWithoutUrl, index: versionWithoutUrlIndex });
expect(locationService.go).not.toHaveBeenCalled();
});
@@ -520,9 +520,9 @@ describe('AppComponent', () => {
describe('aio-toc', () => {
let tocDebugElement: DebugElement;
let tocContainer: DebugElement;
let tocContainer: DebugElement|null;
const setHasFloatingToc = hasFloatingToc => {
const setHasFloatingToc = (hasFloatingToc: boolean) => {
component.hasFloatingToc = hasFloatingToc;
fixture.detectChanges();
@@ -551,12 +551,12 @@ describe('AppComponent', () => {
});
it('should update the TOC container\'s `maxHeight` based on `tocMaxHeight`', () => {
expect(tocContainer.styles['max-height']).toBeNull();
expect(tocContainer!.styles['max-height']).toBeNull();
component.tocMaxHeight = '100';
fixture.detectChanges();
expect(tocContainer.styles['max-height']).toBe('100px');
expect(tocContainer!.styles['max-height']).toBe('100px');
});
it('should restrain scrolling inside the ToC container', () => {
@@ -565,7 +565,7 @@ describe('AppComponent', () => {
expect(restrainScrolling).not.toHaveBeenCalled();
tocContainer.triggerEventHandler('mousewheel', evt);
tocContainer!.triggerEventHandler('mousewheel', evt);
expect(restrainScrolling).toHaveBeenCalledWith(evt);
});
});
@@ -591,7 +591,7 @@ describe('AppComponent', () => {
initializeTest();
fixture.detectChanges();
const banner: HTMLElement = fixture.debugElement.query(By.css('aio-mode-banner')).nativeElement;
expect(banner.textContent.trim()).toEqual('');
expect(banner.textContent!.trim()).toEqual('');
});
});
@@ -985,9 +985,9 @@ describe('AppComponent', () => {
checkHostClass('mode', 'archive');
});
function checkHostClass(type, value) {
function checkHostClass(type: string, value: string) {
const host = fixture.debugElement;
const classes = host.properties['className'];
const classes: string = host.properties['className'];
const classArray = classes.split(' ').filter(c => c.indexOf(`${type}-`) === 0);
expect(classArray.length).toBeLessThanOrEqual(1, `"${classes}" should have only one class matching ${type}-*`);
expect(classArray).toEqual([`${type}-${value}`], `"${classes}" should contain ${type}-${value}`);
@@ -1212,10 +1212,10 @@ class TestHttpClient {
if (/navigation\.json/.test(url)) {
data = this.navJson;
} else {
const match = /generated\/docs\/(.+)\.json/.exec(url);
const id = match[1];
const match = /generated\/docs\/(.+)\.json/.exec(url)!;
const id = match[1]!;
// Make up a title for test purposes
const title = id.split('/').pop().replace(/^([a-z])/, (_, letter) => letter.toUpperCase());
const title = id.split('/').pop()!.replace(/^([a-z])/, (_, letter) => letter.toUpperCase());
const h1 = (id === 'no-title') ? '' : `<h1>${title}</h1>`;
const contents = `${h1}<h2 id="#somewhere">Some heading</h2>`;
data = { id, contents };
+8 -8
View File
@@ -152,19 +152,19 @@ export class AppComponent implements OnInit {
this.navigationService.navigationViews.map(views => views['docVersions']))
.subscribe(([versionInfo, versions]) => {
// TODO(pbd): consider whether we can lookup the stable and next versions from the internet
const computedVersions = [
const computedVersions: NavigationNode[] = [
{ title: 'next', url: 'https://next.angular.io' },
{ title: 'stable', url: 'https://angular.io' },
];
if (this.deployment.mode === 'archive') {
computedVersions.push({ title: `v${versionInfo.major}`, url: null });
computedVersions.push({ title: `v${versionInfo.major}` });
}
this.docVersions = [...computedVersions, ...versions];
// Find the current version - eithers title matches the current deployment mode
// or its title matches the major version of the current version info
this.currentDocVersion = this.docVersions.find(version =>
version.title === this.deployment.mode || version.title === `v${versionInfo.major}`);
version.title === this.deployment.mode || version.title === `v${versionInfo.major}`)!;
this.currentDocVersion.title += ` (v${versionInfo.raw})`;
});
@@ -232,7 +232,7 @@ export class AppComponent implements OnInit {
}
@HostListener('window:resize', ['$event.target.innerWidth'])
onResize(width) {
onResize(width: number) {
this.isSideBySide = width > this.sideBySideWidth;
this.showFloatingToc.next(width > this.showFloatingTocWidth);
}
@@ -252,7 +252,7 @@ export class AppComponent implements OnInit {
}
// Deal with anchor clicks; climb DOM tree until anchor found (or null)
let target = eventTarget;
let target: HTMLElement|null = eventTarget;
while (target && !(target instanceof HTMLAnchorElement)) {
target = target.parentElement;
}
@@ -335,8 +335,8 @@ export class AppComponent implements OnInit {
// Must wait until now for mat-toolbar to be measurable.
const el = this.hostElement.nativeElement as Element;
this.tocMaxHeightOffset =
el.querySelector('footer').clientHeight +
el.querySelector('.app-toolbar').clientHeight +
el.querySelector('footer')!.clientHeight +
el.querySelector('.app-toolbar')!.clientHeight +
24; // fudge margin
}
@@ -375,7 +375,7 @@ export class AppComponent implements OnInit {
}
}
doSearch(query) {
doSearch(query: string) {
this.searchResults = this.searchService.search(query);
this.showSearchResults = !!query;
}
+2 -2
View File
@@ -23,7 +23,7 @@ describe('AppModule', () => {
});
it('should provide a list of eagerly-loaded embedded components', () => {
const eagerSelector = Object.keys(componentsMap).find(selector => Array.isArray(componentsMap[selector]));
const eagerSelector = Object.keys(componentsMap).find(selector => Array.isArray(componentsMap[selector]))!;
const selectorCount = eagerSelector.split(',').length;
expect(eagerSelector).not.toBeNull();
@@ -34,7 +34,7 @@ describe('AppModule', () => {
});
it('should provide a list of lazy-loaded embedded components', () => {
const lazySelector = Object.keys(componentsMap).find(selector => selector.includes('code-example'));
const lazySelector = Object.keys(componentsMap).find(selector => selector.includes('code-example'))!;
const selectorCount = lazySelector.split(',').length;
expect(lazySelector).not.toBeNull();
+1 -1
View File
@@ -2,5 +2,5 @@ export interface DocumentContents {
/** The unique identifier for this document */
id: string;
/** The HTML to display in the doc viewer */
contents: string;
contents: string|null;
}
@@ -50,7 +50,7 @@ describe('DocumentService', () => {
});
it('should emit a document each time the location changes', () => {
let latestDocument: DocumentContents;
let latestDocument: DocumentContents|undefined;
const doc0 = { contents: 'doc 0', id: 'initial/doc' };
const doc1 = { contents: 'doc 1', id: 'new/doc' };
const { docService, locationService } = getServices('initial/doc');
@@ -67,7 +67,7 @@ describe('DocumentService', () => {
});
it('should emit the not-found document if the document is not found on the server', () => {
let currentDocument: DocumentContents;
let currentDocument: DocumentContents|undefined;
const notFoundDoc = { id: FILE_NOT_FOUND_ID, contents: '<h1>Page Not Found</h1>' };
const { docService } = getServices('missing/doc');
docService.currentDocument.subscribe(doc => currentDocument = doc);
@@ -82,7 +82,7 @@ describe('DocumentService', () => {
});
it('should emit a hard-coded not-found document if the not-found document is not found on the server', () => {
let currentDocument: DocumentContents;
let currentDocument: DocumentContents|undefined;
const hardCodedNotFoundDoc = { contents: 'Document not found', id: FILE_NOT_FOUND_ID };
const nextDoc = { contents: 'Next Doc', id: 'new/doc' };
const { docService, locationService } = getServices(FILE_NOT_FOUND_ID);
@@ -99,7 +99,7 @@ describe('DocumentService', () => {
});
it('should use a hard-coded error doc if the request fails (but not cache it)', () => {
let latestDocument: DocumentContents;
let latestDocument: DocumentContents|undefined;
const doc1 = { contents: 'doc 1' };
const doc2 = { contents: 'doc 2' };
const { docService, locationService } = getServices('initial/doc');
@@ -107,7 +107,7 @@ describe('DocumentService', () => {
docService.currentDocument.subscribe(doc => latestDocument = doc);
httpMock.expectOne({}).flush(null, {status: 500, statusText: 'Server Error'});
expect(latestDocument.id).toEqual(FETCHING_ERROR_ID);
expect(latestDocument!.id).toEqual(FETCHING_ERROR_ID);
locationService.go('new/doc');
httpMock.expectOne({}).flush(doc1);
@@ -119,14 +119,14 @@ describe('DocumentService', () => {
});
it('should not crash the app if the response is invalid JSON', () => {
let latestDocument: DocumentContents;
let latestDocument: DocumentContents|undefined;
const doc1 = { contents: 'doc 1' };
const { docService, locationService } = getServices('initial/doc');
docService.currentDocument.subscribe(doc => latestDocument = doc);
httpMock.expectOne({}).flush('this is invalid JSON');
expect(latestDocument.id).toEqual(FETCHING_ERROR_ID);
expect(latestDocument!.id).toEqual(FETCHING_ERROR_ID);
locationService.go('new/doc');
httpMock.expectOne({}).flush(doc1);
@@ -134,7 +134,7 @@ describe('DocumentService', () => {
});
it('should not make a request to the server if the doc is in the cache already', () => {
let latestDocument: DocumentContents;
let latestDocument: DocumentContents|undefined;
let subscription: Subscription;
const doc0 = { contents: 'doc 0' };
+1 -1
View File
@@ -52,7 +52,7 @@ export class DocumentService {
if ( !this.cache.has(id)) {
this.cache.set(id, this.fetchDocument(id));
}
return this.cache.get(id);
return this.cache.get(id)!;
}
private fetchDocument(id: string): Observable<DocumentContents> {
@@ -127,9 +127,9 @@ describe('EmbedComponentsService', () => {
const componentRefs = service.createComponents(host);
componentRefs[0].changeDetectorRef.detectChanges();
const barEl = host.querySelector('aio-eager-bar');
const barEl = host.querySelector('aio-eager-bar')!;
expect(barEl['aioEagerBarContent']).toBe(projectedContent);
expect((barEl as any)['aioEagerBarContent']).toBe(projectedContent);
expect(barEl.innerHTML).toContain(projectedContent);
});
@@ -111,7 +111,7 @@ export class EmbedComponentsService {
// Hack: Preserve the current element content, because the factory will empty it out.
// Security: The source of this `innerHTML` should always be authored by the documentation
// team and is considered to be safe.
host[contentPropertyName] = host.innerHTML;
(host as any)[contentPropertyName] = host.innerHTML;
componentRefs.push(factory.create(this.injector, [], host));
}
});
@@ -141,7 +141,7 @@ export class EmbedComponentsService {
this.componentFactoriesReady.set(compsOrPath, readyPromise);
}
return this.componentFactoriesReady.get(compsOrPath);
return this.componentFactoriesReady.get(compsOrPath)!;
}
/**
@@ -34,7 +34,7 @@ describe('ApiListComponent', () => {
*/
function expectFilteredResult(label: string, itemTest: (item: ApiItem) => boolean) {
component.filteredSections.subscribe(filtered => {
let badItem: ApiItem;
let badItem: ApiItem|undefined;
expect(filtered.length).toBeGreaterThan(0, 'expected something');
expect(filtered.every(section => section.items.every(
item => {
@@ -53,7 +53,7 @@ describe('ApiListComponent', () => {
});
it('should return all complete sections when no criteria', () => {
let filtered: ApiSection[];
let filtered: ApiSection[]|undefined;
component.filteredSections.subscribe(f => filtered = f);
expect(filtered).toEqual(sections);
});
@@ -68,7 +68,7 @@ describe('ApiListComponent', () => {
component.filteredSections.subscribe(filtered => {
expect(filtered.length).toBe(1, 'only one section');
expect(filtered[0].name).toBe('core');
expect(filtered[0].items.every(item => item.show)).toBe(true, 'all core items shown');
expect(filtered[0].items.every(item => !!item.show)).toBe(true, 'all core items shown');
});
});
+2 -2
View File
@@ -35,8 +35,8 @@ describe('ApiService', () => {
let completed = false;
service.sections.subscribe(
null,
null,
undefined,
undefined,
() => completed = true
);
@@ -41,7 +41,7 @@ export class CodeExampleComponent implements OnInit {
const element: HTMLElement = this.elementRef.nativeElement;
this.language = element.getAttribute('language') || '';
this.linenums = element.getAttribute('linenums');
this.linenums = element.getAttribute('linenums') || '';
this.path = element.getAttribute('path') || '';
this.region = element.getAttribute('region') || '';
this.title = element.getAttribute('title') || '';
@@ -2,13 +2,13 @@
import { Component, ElementRef, OnInit } from '@angular/core';
export interface TabInfo {
class: string;
class: string|null;
code: string;
language: string;
language: string|null;
linenums: any;
path: string;
region: string;
title: string;
title: string|null;
}
/**
@@ -36,8 +36,8 @@ describe('CodeComponent', () => {
// we take strict measures to wipe it out in the `afterAll`
// and make sure THAT runs after the tests by making component creation async
afterAll(() => {
delete window['prettyPrint'];
delete window['prettyPrintOne'];
delete (window as any)['prettyPrint'];
delete (window as any)['prettyPrintOne'];
});
beforeEach(() => {
+1 -1
View File
@@ -170,7 +170,7 @@ export class CodeComponent implements OnChanges {
}
}
function leftAlign(text) {
function leftAlign(text: string) {
let indent = Number.MAX_VALUE;
const lines = text.split('\n');
lines.forEach(line => {
@@ -7,7 +7,9 @@ import 'rxjs/add/operator/first';
import { Logger } from 'app/shared/logger.service';
declare const System;
declare const System: {
import(name: string): Promise<any>;
};
type PrettyPrintOne = (code: string, language?: string, linenums?: number | boolean) => string;
@@ -24,12 +26,12 @@ export class PrettyPrinter {
}
private getPrettyPrintOne(): Promise<PrettyPrintOne> {
const ppo = window['prettyPrintOne'];
const ppo = (window as any)['prettyPrintOne'];
return ppo ? Promise.resolve(ppo) :
// prettify.js is not in window global; load it with webpack loader
System.import('assets/js/prettify.js')
.then(
() => window['prettyPrintOne'],
() => (window as any)['prettyPrintOne'],
err => {
const msg = 'Cannot get prettify.js from server';
this.logger.error(msg, err);
@@ -38,7 +38,7 @@ export class ContributorListComponent implements OnInit {
});
}
selectGroup(name) {
selectGroup(name: string) {
name = name.toLowerCase();
this.selectedGroup = this.groups.find(g => g.name.toLowerCase() === name) || this.groups[0];
this.locationService.setSearch('', {group: this.selectedGroup.name});
@@ -40,7 +40,7 @@ export class ContributorComponent {
noPicture = '_no-one.png';
pictureBase = CONTENT_URL_PREFIX + 'images/bios/';
flipCard(person) {
flipCard(person: Contributor) {
person.isFlipped = !person.isFlipped;
}
}
@@ -43,7 +43,7 @@ describe('ContributorService', () => {
it('contributors observable should complete', () => {
let completed = false;
contribService.contributors.subscribe(null, null, () => completed = true);
contribService.contributors.subscribe(undefined, undefined, () => completed = true);
expect(true).toBe(true, 'observable completed');
});
@@ -23,7 +23,7 @@ export class ContributorService {
const contributors = this.http.get<{[key: string]: Contributor}>(contributorsPath)
// Create group map
.map(contribs => {
const contribMap = new Map<string, Contributor[]>();
const contribMap: { [name: string]: Contributor[]} = {};
Object.keys(contribs).forEach(key => {
const contributor = contribs[key];
const group = contributor.group;
@@ -13,7 +13,7 @@ describe('LiveExampleComponent', () => {
let liveExampleComponent: LiveExampleComponent;
let fixture: ComponentFixture<HostComponent>;
let testPath: string;
let liveExampleContent: string;
let liveExampleContent: string|null;
//////// test helpers ////////
@@ -66,7 +66,7 @@ describe('LiveExampleComponent', () => {
.overrideComponent(EmbeddedPlunkerComponent, {set: {template: 'NO IFRAME'}});
testPath = defaultTestPath;
liveExampleContent = undefined;
liveExampleContent = null;
});
describe('when not embedded', () => {
@@ -94,7 +94,7 @@ export class LiveExampleComponent implements OnInit {
let exampleDir = attrs.name;
if (!exampleDir) {
// take last segment, excluding hash fragment and query params
exampleDir = location.path(false).match(/[^\/?\#]+(?=\/?(?:$|\#|\?))/)[0];
exampleDir = (location.path(false).match(/[^\/?\#]+(?=\/?(?:$|\#|\?))/) || [])[0];
}
this.exampleDir = exampleDir.trim();
this.zipName = exampleDir.indexOf('/') === -1 ? this.exampleDir : exampleDir.split('/')[0];
@@ -150,7 +150,7 @@ export class LiveExampleComponent implements OnInit {
}
@HostListener('window:resize', ['$event.target.innerWidth'])
onResize(width) {
onResize(width: number) {
if (this.mode !== 'downloadOnly') {
this.calcPlnkrLink(width);
}
@@ -43,7 +43,7 @@ describe('ResourceService', () => {
it('categories observable should complete', () => {
let completed = false;
resourceService.categories.subscribe(null, null, () => completed = true);
resourceService.categories.subscribe(undefined, undefined, () => completed = true);
expect(true).toBe(true, 'observable completed');
});
@@ -43,7 +43,7 @@ describe('DocViewerComponent', () => {
describe('#doc', () => {
let renderSpy: jasmine.Spy;
const setCurrentDoc = (contents, id = 'fizz/buzz') => {
const setCurrentDoc = (contents: string|null, id = 'fizz/buzz') => {
parentComponent.currentDoc = {contents, id};
parentFixture.detectChanges();
};
@@ -432,7 +432,7 @@ describe('DocViewerComponent', () => {
});
it('should store the embedded components', async () => {
const embeddedComponents = [];
const embeddedComponents: ComponentRef<any>[] = [];
embedIntoSpy.and.returnValue(of(embeddedComponents));
await doRender('Some content');
@@ -678,7 +678,7 @@ describe('DocViewerComponent', () => {
describe(`(.${NO_ANIMATIONS}: ${noAnimations})`, () => {
beforeEach(() => docViewerEl.classList[noAnimations ? 'add' : 'remove'](NO_ANIMATIONS));
it('should return an observable', done => {
it('should return an observable', (done: DoneFn) => {
docViewer.swapViews().subscribe(done, done.fail);
});
@@ -114,12 +114,12 @@ export class DocViewerComponent implements DoCheck, OnDestroy {
const hasToc = !!titleEl && !/no-?toc/i.test(titleEl.className);
if (hasToc) {
titleEl.insertAdjacentHTML('afterend', '<aio-toc class="embedded"></aio-toc>');
titleEl!.insertAdjacentHTML('afterend', '<aio-toc class="embedded"></aio-toc>');
}
return () => {
this.tocService.reset();
let title = '';
let title: string|null = '';
// Only create ToC for docs with an `<h1>` heading.
// If you don't want a ToC, add "no-toc" class to `<h1>`.
@@ -169,7 +169,7 @@ export class DocViewerComponent implements DoCheck, OnDestroy {
* entering animation has been completed. This is useful for work that needs to be done as soon as
* the element has been attached to the DOM.
*/
protected swapViews(onInsertedCb = () => undefined): Observable<void> {
protected swapViews(onInsertedCb = () => {}): Observable<void> {
const raf$ = new Observable<void>(subscriber => {
const rafId = requestAnimationFrame(() => {
subscriber.next();
@@ -182,15 +182,18 @@ export class DocViewerComponent implements DoCheck, OnDestroy {
// According to the [CSSOM spec](https://drafts.csswg.org/cssom/#serializing-css-values),
// `time` values should be returned in seconds.
const getActualDuration = (elem: HTMLElement) => {
const cssValue = getComputedStyle(elem).transitionDuration;
const cssValue = getComputedStyle(elem).transitionDuration || '';
const seconds = Number(cssValue.replace(/s$/, ''));
return 1000 * seconds;
};
const animateProp =
(elem: HTMLElement, prop: string, from: string, to: string, duration = 200) => {
(elem: HTMLElement, prop: keyof CSSStyleDeclaration, from: string, to: string, duration = 200) => {
const animationsDisabled = !DocViewerComponent.animationsEnabled
|| this.hostElement.classList.contains(NO_ANIMATIONS);
if (prop === 'length' || prop === 'parentRule') {
// We cannot animate length or parentRule properties because they are readonly
return this.void$;
}
elem.style.transition = '';
return animationsDisabled
? this.void$.do(() => elem.style[prop] = to)
@@ -201,7 +204,7 @@ export class DocViewerComponent implements DoCheck, OnDestroy {
// setting each style.
.switchMap(() => raf$).do(() => elem.style[prop] = from)
.switchMap(() => raf$).do(() => elem.style.transition = `all ${duration}ms ease-in-out`)
.switchMap(() => raf$).do(() => elem.style[prop] = to)
.switchMap(() => raf$).do(() => (elem.style as any)[prop] = to)
.switchMap(() => timer(getActualDuration(elem))).switchMap(() => this.void$);
};
@@ -214,7 +217,7 @@ export class DocViewerComponent implements DoCheck, OnDestroy {
done$ = done$
// Remove the current view from the viewer.
.switchMap(() => animateLeave(this.currViewContainer))
.do(() => this.currViewContainer.parentElement.removeChild(this.currViewContainer))
.do(() => this.currViewContainer.parentElement!.removeChild(this.currViewContainer))
.do(() => this.docRemoved.emit());
}
+7 -7
View File
@@ -73,18 +73,18 @@ describe('TocComponent', () => {
it('should update when the TocItems are updated', () => {
tocService.tocList.next([tocItem('Heading A')]);
fixture.detectChanges();
expect(tocComponentDe.queryAllNodes(By.css('li')).length).toBe(1);
expect(tocComponentDe.queryAll(By.css('li')).length).toBe(1);
tocService.tocList.next([tocItem('Heading A'), tocItem('Heading B'), tocItem('Heading C')]);
fixture.detectChanges();
expect(tocComponentDe.queryAllNodes(By.css('li')).length).toBe(3);
expect(tocComponentDe.queryAll(By.css('li')).length).toBe(3);
});
it('should only display H2 and H3 TocItems', () => {
tocService.tocList.next([tocItem('Heading A', 'h1'), tocItem('Heading B'), tocItem('Heading C', 'h3')]);
fixture.detectChanges();
const tocItems = tocComponentDe.queryAllNodes(By.css('li'));
const tocItems = tocComponentDe.queryAll(By.css('li'));
const textContents = tocItems.map(item => item.nativeNode.textContent.trim());
expect(tocItems.length).toBe(2);
@@ -97,12 +97,12 @@ describe('TocComponent', () => {
it('should stop listening for TocItems once destroyed', () => {
tocService.tocList.next([tocItem('Heading A')]);
fixture.detectChanges();
expect(tocComponentDe.queryAllNodes(By.css('li')).length).toBe(1);
expect(tocComponentDe.queryAll(By.css('li')).length).toBe(1);
tocComponent.ngOnDestroy();
tocService.tocList.next([tocItem('Heading A', 'h1'), tocItem('Heading B'), tocItem('Heading C')]);
fixture.detectChanges();
expect(tocComponentDe.queryAllNodes(By.css('li')).length).toBe(1);
expect(tocComponentDe.queryAll(By.css('li')).length).toBe(1);
});
describe('when fewer than `maxPrimary` TocItems', () => {
@@ -339,7 +339,7 @@ describe('TocComponent', () => {
it('should re-apply the `active` class when the list elements change', () => {
const getActiveTextContent = () =>
page.listItems.find(By.css('.active')).nativeElement.textContent.trim();
page.listItems.find(By.css('.active'))!.nativeElement.textContent.trim();
tocComponent.activeIndex = 1;
fixture.detectChanges();
@@ -462,7 +462,7 @@ class TestScrollService {
class TestTocService {
tocList = new BehaviorSubject<TocItem[]>(getTestTocList());
activeItemIndex = new BehaviorSubject<number | null>(null);
setActiveIndex(index) {
setActiveIndex(index: number|null) {
this.activeItemIndex.next(index);
if (asap.scheduled) {
asap.flush();
+1 -1
View File
@@ -93,6 +93,6 @@ export class TocComponent implements OnInit, AfterViewInit, OnDestroy {
}
}
function count<T>(array: T[], fn: (T) => boolean) {
function count<T>(array: T[], fn: (item: T) => boolean) {
return array.reduce((count, item) => fn(item) ? count + 1 : count, 0);
}
@@ -45,7 +45,7 @@ describe('NavigationService', () => {
it('navigationViews observable should complete', () => {
let completed = false;
navService.navigationViews.subscribe(null, null, () => completed = true);
navService.navigationViews.subscribe(undefined, undefined, () => completed = true);
expect(true).toBe(true, 'observable completed');
// Stop `$httpMock.verify()` from complaining.
@@ -53,15 +53,15 @@ describe('NavigationService', () => {
});
it('should return the same object to all subscribers', () => {
let views1: NavigationViews;
let views1: NavigationViews|undefined;
navService.navigationViews.subscribe(views => views1 = views);
let views2: NavigationViews;
let views2: NavigationViews|undefined;
navService.navigationViews.subscribe(views => views2 = views);
httpMock.expectOne({}).flush({ TopBar: [{ url: 'a' }] });
let views3: NavigationViews;
let views3: NavigationViews|undefined;
navService.navigationViews.subscribe(views => views3 = views);
expect(views2).toBe(views1);
@@ -143,7 +143,7 @@ describe('NavigationService', () => {
url: 'b',
view: 'SideNav',
nodes: [
sideNavNodes[0].children[0],
sideNavNodes[0].children![0],
sideNavNodes[0]
]
}
@@ -155,8 +155,8 @@ describe('NavigationService', () => {
url: 'd',
view: 'SideNav',
nodes: [
sideNavNodes[0].children[0].children[1],
sideNavNodes[0].children[0],
sideNavNodes[0].children![0].children![1],
sideNavNodes[0].children![0],
sideNavNodes[0]
]
}
@@ -200,8 +200,8 @@ describe('NavigationService', () => {
url: 'c',
view: 'SideNav',
nodes: [
sideNavNodes[0].children[0].children[0],
sideNavNodes[0].children[0],
sideNavNodes[0].children![0].children![0],
sideNavNodes[0].children![0],
sideNavNodes[0]
]
}

Some files were not shown because too many files have changed in this diff Show More