From 01ff427685fdf1f68c667bf59d7d1f44b334f195 Mon Sep 17 00:00:00 2001 From: Peter Bacon Darwin Date: Thu, 2 Mar 2017 13:28:28 +0000 Subject: [PATCH] test(aio): reimplemented all the commented-out unit tests --- aio/src/app/app.component.spec.ts | 39 +- aio/src/app/app.component.ts | 9 +- .../app/documents/document.service.spec.ts | 29 +- .../doc-viewer/doc-viewer.component.spec.ts | 495 +++++++++--------- .../layout/doc-viewer/doc-viewer.component.ts | 1 - .../nav-menu/nav-menu.component.spec.ts | 5 +- .../app/navigation/navigation.service.spec.ts | 34 +- 7 files changed, 340 insertions(+), 272 deletions(-) diff --git a/aio/src/app/app.component.spec.ts b/aio/src/app/app.component.spec.ts index f32093b400..8ebac2296a 100644 --- a/aio/src/app/app.component.spec.ts +++ b/aio/src/app/app.component.spec.ts @@ -1,6 +1,8 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { async, inject, ComponentFixture, TestBed } from '@angular/core/testing'; +import { APP_BASE_HREF } from '@angular/common'; import { AppComponent } from './app.component'; import { AppModule } from './app.module'; +import { SearchService } from 'app/search/search.service'; describe('AppComponent', () => { let component: AppComponent; @@ -10,6 +12,7 @@ describe('AppComponent', () => { TestBed.configureTestingModule({ imports: [ AppModule ], providers: [ + { provide: APP_BASE_HREF, useValue: '/' } ] }); TestBed.compileComponents(); @@ -23,4 +26,38 @@ describe('AppComponent', () => { it('should create', () => { expect(component).toBeDefined(); }); + + describe('isHamburgerVisible', () => { + }); + + describe('onResize', () => { + it('should update `isSideBySide` accordingly', () => { + component.onResize(1000); + expect(component.isSideBySide).toBe(true); + component.onResize(500); + expect(component.isSideBySide).toBe(false); + }); + }); + + describe('onSearch', () => { + it('should call the search service', inject([SearchService], (search: SearchService) => { + spyOn(search, 'search'); + component.onSearch('some query'); + expect(search.search).toHaveBeenCalledWith('some query'); + })); + }); + + describe('currentDocument', () => { + + }); + + describe('navigationViews', () => { + + }); + + describe('searchResults', () => { + + }); + + }); diff --git a/aio/src/app/app.component.ts b/aio/src/app/app.component.ts index 813804bba2..b867988f2f 100644 --- a/aio/src/app/app.component.ts +++ b/aio/src/app/app.component.ts @@ -11,7 +11,7 @@ import { SearchService, QueryResults } from 'app/search/search.service'; - + @@ -86,9 +86,10 @@ import { SearchService, QueryResults } from 'app/search/search.service'; ] }) export class AppComponent implements OnInit { + readonly sideBySideWidth = 600; + isHamburgerVisible = true; // always ... for now isSideBySide = false; - sideBySideWidth = 600; currentDocument: Observable; navigationViews: Observable; @@ -111,9 +112,7 @@ export class AppComponent implements OnInit { this.isSideBySide = width > this.sideBySideWidth; } - onSearch(event: KeyboardEvent) { - const query = (event.target as HTMLInputElement).value; - console.log(query); + onSearch(query: string) { this.searchService.search(query); } } diff --git a/aio/src/app/documents/document.service.spec.ts b/aio/src/app/documents/document.service.spec.ts index 95fc21665b..2f185eb507 100644 --- a/aio/src/app/documents/document.service.spec.ts +++ b/aio/src/app/documents/document.service.spec.ts @@ -1,14 +1,31 @@ -import { TestBed, inject } from '@angular/core/testing'; +import { ReflectiveInjector } from '@angular/core'; +import { Location, LocationStrategy } from '@angular/common'; +import { MockLocationStrategy } from '@angular/common/testing'; +import { Http, ConnectionBackend, RequestOptions, BaseRequestOptions } from '@angular/http'; +import { MockBackend } from '@angular/http/testing'; +import { LocationService } from 'app/shared/location.service'; +import { Logger } from 'app/shared/logger.service'; import { DocumentService } from './document.service'; describe('DocumentService', () => { + + let injector: ReflectiveInjector; + beforeEach(() => { - TestBed.configureTestingModule({ - providers: [DocumentService] - }); + injector = ReflectiveInjector.resolveAndCreate([ + DocumentService, + LocationService, + Location, + { provide: LocationStrategy, useClass: MockLocationStrategy }, + { provide: ConnectionBackend, useClass: MockBackend }, + { provide: RequestOptions, useClass: BaseRequestOptions }, + Http, + Logger + ]); }); - it('should ...', inject([DocumentService], (service: DocumentService) => { + it('should be creatable', () => { + const service: DocumentService = injector.get(DocumentService); expect(service).toBeTruthy(); - })); + }); }); diff --git a/aio/src/app/layout/doc-viewer/doc-viewer.component.spec.ts b/aio/src/app/layout/doc-viewer/doc-viewer.component.spec.ts index 1001545dca..a40dee42aa 100644 --- a/aio/src/app/layout/doc-viewer/doc-viewer.component.spec.ts +++ b/aio/src/app/layout/doc-viewer/doc-viewer.component.spec.ts @@ -1,305 +1,300 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { ComponentFactoryResolver, ElementRef, Injector, NgModule, OnInit, ViewChild, Component, DebugElement } from '@angular/core'; import { By } from '@angular/platform-browser'; -import { Component, DebugElement } from '@angular/core'; - -import { ComponentFactoryResolver, ElementRef, Injector, NgModule, OnInit, ViewChild } from '@angular/core'; - import { DocViewerComponent } from './doc-viewer.component'; - +import { DocumentContents } from 'app/documents/document.service'; import { embeddedComponents, EmbeddedComponents } from 'app/embedded'; -// /// Embedded Test Components /// +/// Embedded Test Components /// -// ///// FooComponent ///// +///// FooComponent ///// -// @Component({ -// selector: 'aio-foo', -// template: `Foo Component` -// }) -// class FooComponent { } +@Component({ + selector: 'aio-foo', + template: `Foo Component` +}) +class FooComponent { } -// ///// BarComponent ///// +///// BarComponent ///// -// @Component({ -// selector: 'aio-bar', -// template: ` -//
-//

Bar Component

-//

-//
-// ` -// }) -// class BarComponent implements OnInit { +@Component({ + selector: 'aio-bar', + template: ` +
+

Bar Component

+

+
+ ` +}) +class BarComponent implements OnInit { -// @ViewChild('barContent') barContentRef: ElementRef; + @ViewChild('barContent') barContentRef: ElementRef; -// constructor(public elementRef: ElementRef) { } + constructor(public elementRef: ElementRef) { } -// // Project content in ngOnInit just like CodeExampleComponent -// ngOnInit() { -// // Security: this is a test component; never deployed -// this.barContentRef.nativeElement.innerHTML = this.elementRef.nativeElement.aioBarContent; -// } -// } + // Project content in ngOnInit just like CodeExampleComponent + ngOnInit() { + // Security: this is a test component; never deployed + this.barContentRef.nativeElement.innerHTML = this.elementRef.nativeElement.aioBarContent; + } +} -// ///// BazComponent ///// +///// BazComponent ///// -// @Component({ -// selector: 'aio-baz', -// template: ` -//
++++++++++++++
-//

Baz Component

-//

-//
++++++++++++++
-// ` -// }) -// class BazComponent implements OnInit { +@Component({ + selector: 'aio-baz', + template: ` +
++++++++++++++
+

Baz Component

+

+
++++++++++++++
+ ` +}) +class BazComponent implements OnInit { -// @ViewChild('bazContent') bazContentRef: ElementRef; + @ViewChild('bazContent') bazContentRef: ElementRef; -// constructor(public elementRef: ElementRef) { } + constructor(public elementRef: ElementRef) { } -// // Project content in ngOnInit just like CodeExampleComponent -// ngOnInit() { -// // Security: this is a test component; never deployed -// this.bazContentRef.nativeElement.innerHTML = this.elementRef.nativeElement.aioBazContent; -// } -// } -// ///// Test Module ////// + // Project content in ngOnInit just like CodeExampleComponent + ngOnInit() { + // Security: this is a test component; never deployed + this.bazContentRef.nativeElement.innerHTML = this.elementRef.nativeElement.aioBazContent; + } +} +///// Test Module ////// -// const embeddedTestComponents = [FooComponent, BarComponent, BazComponent, ...embeddedComponents]; +const embeddedTestComponents = [FooComponent, BarComponent, BazComponent, ...embeddedComponents]; -// @NgModule({ -// entryComponents: embeddedTestComponents -// }) -// class TestModule { } +@NgModule({ + entryComponents: embeddedTestComponents +}) +class TestModule { } -// //// Test Component ////// +//// Test Component ////// -// @Component({ -// selector: 'aio-test', -// template: ` -// Test Component -// ` -// }) -// class TestComponent { -// private currentDoc: Doc; +@Component({ + selector: 'aio-test', + template: ` + Test Component + ` +}) +class TestComponent { + currentDoc: DocumentContents; + @ViewChild(DocViewerComponent) docViewer: DocViewerComponent; +} -// @ViewChild(DocViewerComponent) docViewer: DocViewerComponent; +//////// Tests ////////////// -// setDoc(doc: Doc) { -// if (this.docViewer) { -// this.docViewer.doc = doc; -// } -// } -// } +describe('DocViewerComponent', () => { + let component: TestComponent; + let docViewerDE: DebugElement; + let docViewerEl: HTMLElement; + let fixture: ComponentFixture; -// //////// Tests ////////////// + beforeEach(async(() => { + TestBed.configureTestingModule({ + imports: [ TestModule ], + declarations: [ + TestComponent, + DocViewerComponent, + embeddedTestComponents + ], + providers: [ + {provide: EmbeddedComponents, useValue: {components: embeddedTestComponents}} + ] + }) + .compileComponents(); + })); -// describe('DocViewerComponent', () => { -// const fakeDocMetadata: DocMetadata = { docId: 'fake', title: 'fake Doc' }; -// let component: TestComponent; -// let docViewerDE: DebugElement; -// let docViewerEl: HTMLElement; -// let fixture: ComponentFixture; + beforeEach(() => { + fixture = TestBed.createComponent(TestComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + docViewerDE = fixture.debugElement.children[0]; + docViewerEl = docViewerDE.nativeElement; + }); -// beforeEach(async(() => { -// TestBed.configureTestingModule({ -// imports: [ TestModule ], -// declarations: [ -// TestComponent, -// DocViewerComponent, -// embeddedTestComponents -// ], -// providers: [ -// {provide: EmbeddedComponents, useValue: {components: embeddedTestComponents}} -// ] -// }) -// .compileComponents(); -// })); + it('should create a DocViewer', () => { + expect(component.docViewer).toBeTruthy(); + }); -// beforeEach(() => { -// fixture = TestBed.createComponent(TestComponent); -// component = fixture.componentInstance; -// fixture.detectChanges(); -// docViewerDE = fixture.debugElement.children[0]; -// docViewerEl = docViewerDE.nativeElement; -// }); + it(('should display nothing when set currentDoc has no content'), () => { + component.currentDoc = { title: 'fake title', contents: '' }; + fixture.detectChanges(); + expect(docViewerEl.innerHTML).toBe(''); + }); -// it('should create a DocViewer', () => { -// expect(component.docViewer).toBeTruthy(); -// }); + it(('should display simple static content doc'), () => { + const contents = '

Howdy, doc viewer

'; + component.currentDoc = { title: 'fake title', contents }; + fixture.detectChanges(); + expect(docViewerEl.innerHTML).toEqual(contents); + }); -// it(('should display nothing when set DocViewer.doc to doc w/o content'), () => { -// component.docViewer.doc = { metadata: fakeDocMetadata, content: '' }; -// expect(docViewerEl.innerHTML).toBe(''); -// }); + it(('should display nothing after reset static content doc'), () => { + const contents = '

Howdy, doc viewer

'; + component.currentDoc = { title: 'fake title', contents }; + fixture.detectChanges(); + component.currentDoc = { title: 'fake title', contents: '' }; + fixture.detectChanges(); + expect(docViewerEl.innerHTML).toEqual(''); + }); -// it(('should display simple static content doc'), () => { -// const content = '

Howdy, doc viewer

'; -// component.docViewer.doc = { metadata: fakeDocMetadata, content }; -// expect(docViewerEl.innerHTML).toEqual(content); -// }); + it(('should apply FooComponent'), () => { + const contents = ` +

Above Foo

+

+

Below Foo

+ `; + component.currentDoc = { title: 'fake title', contents }; + fixture.detectChanges(); + const fooHtml = docViewerEl.querySelector('aio-foo').innerHTML; + expect(fooHtml).toContain('Foo Component'); + }); -// it(('should display nothing after reset static content doc'), () => { -// const content = '

Howdy, doc viewer

'; -// component.docViewer.doc = { metadata: fakeDocMetadata, content }; -// fixture.detectChanges(); -// component.docViewer.doc = { metadata: fakeDocMetadata, content: '' }; -// expect(docViewerEl.innerHTML).toEqual(''); -// }); + it(('should apply multiple FooComponents'), () => { + const contents = ` +

Above Foo

+

+
+ Holds a + Ignored text +
+

Below Foo

+ `; + component.currentDoc = { title: 'fake title', contents }; + fixture.detectChanges(); + const foos = docViewerEl.querySelectorAll('aio-foo'); + expect(foos.length).toBe(2); + }); -// it(('should apply FooComponent'), () => { -// const content = ` -//

Above Foo

-//

-//

Below Foo

-// `; -// component.docViewer.doc = { metadata: fakeDocMetadata, content }; -// const fooHtml = docViewerEl.querySelector('aio-foo').innerHTML; -// expect(fooHtml).toContain('Foo Component'); -// }); + it(('should apply BarComponent'), () => { + const contents = ` +

Above Bar

+ +

Below Bar

+ `; + component.currentDoc = { title: 'fake title', contents }; + fixture.detectChanges(); + const barHtml = docViewerEl.querySelector('aio-bar').innerHTML; + expect(barHtml).toContain('Bar Component'); + }); -// it(('should apply multiple FooComponents'), () => { -// const content = ` -//

Above Foo

-//

-//
-// Holds a -// Ignored text -//
-//

Below Foo

-// `; -// component.docViewer.doc = { metadata: fakeDocMetadata, content }; -// const foos = docViewerEl.querySelectorAll('aio-foo'); -// expect(foos.length).toBe(2); -// }); + it(('should project bar content into BarComponent'), () => { + const contents = ` +

Above Bar

+ ###bar content### +

Below Bar

+ `; + component.currentDoc = { title: 'fake title', contents }; -// it(('should apply BarComponent'), () => { -// const content = ` -//

Above Bar

-// -//

Below Bar

-// `; -// component.docViewer.doc = { metadata: fakeDocMetadata, content }; -// const barHtml = docViewerEl.querySelector('aio-bar').innerHTML; -// expect(barHtml).toContain('Bar Component'); -// }); + // necessary to trigger projection within ngOnInit + fixture.detectChanges(); -// it(('should project bar content into BarComponent'), () => { -// const content = ` -//

Above Bar

-// ###bar content### -//

Below Bar

-// `; -// component.docViewer.doc = { metadata: fakeDocMetadata, content }; - -// // necessary to trigger projection within ngOnInit -// fixture.detectChanges(); - -// const barHtml = docViewerEl.querySelector('aio-bar').innerHTML; -// expect(barHtml).toContain('###bar content###'); -// }); + const barHtml = docViewerEl.querySelector('aio-bar').innerHTML; + expect(barHtml).toContain('###bar content###'); + }); -// it(('should include Foo and Bar'), () => { -// const content = ` -//

Top

-//

ignored

-// ###bar content### -//

-//

Bottom

-// `; -// component.docViewer.doc = { metadata: fakeDocMetadata, content }; + it(('should include Foo and Bar'), () => { + const contents = ` +

Top

+

ignored

+ ###bar content### +

+

Bottom

+ `; + component.currentDoc = { title: 'fake title', contents }; -// // necessary to trigger Bar's projection within ngOnInit -// fixture.detectChanges(); + // necessary to trigger Bar's projection within ngOnInit + fixture.detectChanges(); -// const foos = docViewerEl.querySelectorAll('aio-foo'); -// expect(foos.length).toBe(2, 'should have 2 foos'); + const foos = docViewerEl.querySelectorAll('aio-foo'); + expect(foos.length).toBe(2, 'should have 2 foos'); -// const barHtml = docViewerEl.querySelector('aio-bar').innerHTML; -// expect(barHtml).toContain('###bar content###', 'should have bar with projected content'); -// }); + const barHtml = docViewerEl.querySelector('aio-bar').innerHTML; + expect(barHtml).toContain('###bar content###', 'should have bar with projected content'); + }); -// it(('should not include Bar within Foo'), () => { -// const content = ` -//

Top

-//
-// -// ###bar content### -// -//
-//

-//

Bottom

-// `; -// component.docViewer.doc = { metadata: fakeDocMetadata, content }; + it(('should not include Bar within Foo'), () => { + const contents = ` +

Top

+
+ + ###bar content### + +
+

+

Bottom

+ `; + component.currentDoc = { title: 'fake title', contents }; -// // necessary to trigger Bar's projection within ngOnInit -// fixture.detectChanges(); + // necessary to trigger Bar's projection within ngOnInit + fixture.detectChanges(); -// const foos = docViewerEl.querySelectorAll('aio-foo'); -// expect(foos.length).toBe(2, 'should have 2 foos'); + const foos = docViewerEl.querySelectorAll('aio-foo'); + expect(foos.length).toBe(2, 'should have 2 foos'); -// const bars = docViewerEl.querySelectorAll('aio-bar'); -// expect(bars.length).toBe(0, 'did not expect Bar inside Foo'); -// }); + const bars = docViewerEl.querySelectorAll('aio-bar'); + expect(bars.length).toBe(0, 'did not expect Bar inside Foo'); + }); -// // because FooComponents are processed before BazComponents -// it(('should include Foo within Bar'), () => { -// const content = ` -//

Top

-// -//
-// Inner -//
-//
-//

-//

Bottom

-// `; -// component.docViewer.doc = { metadata: fakeDocMetadata, content }; + // because FooComponents are processed before BazComponents + it(('should include Foo within Bar'), () => { + const contents = ` +

Top

+ +
+ Inner +
+
+

+

Bottom

+ `; + component.currentDoc = { title: 'fake title', contents }; -// // necessary to trigger Bar's projection within ngOnInit -// fixture.detectChanges(); + // necessary to trigger Bar's projection within ngOnInit + fixture.detectChanges(); -// const foos = docViewerEl.querySelectorAll('aio-foo'); -// expect(foos.length).toBe(2, 'should have 2 foos'); + const foos = docViewerEl.querySelectorAll('aio-foo'); + expect(foos.length).toBe(2, 'should have 2 foos'); -// const bars = docViewerEl.querySelectorAll('aio-bar'); -// expect(bars.length).toBe(1, 'should have a bar'); -// expect(bars[0].innerHTML).toContain('Bar Component', 'should have bar template content'); -// }); + const bars = docViewerEl.querySelectorAll('aio-bar'); + expect(bars.length).toBe(1, 'should have a bar'); + expect(bars[0].innerHTML).toContain('Bar Component', 'should have bar template content'); + }); -// // The tag and its inner content is copied -// // But the BazComponent is not created and therefore its template content is not displayed -// // because BarComponents are processed before BazComponents -// // and no chance for first Baz inside Bar to be processed by builder. -// it(('should NOT include Bar within Baz'), () => { -// const content = ` -//

Top

-// -//
-// Inner ---baz stuff--- -//
-//
-//

---More baz--

-//

Bottom

-// `; -// component.docViewer.doc = { metadata: fakeDocMetadata, content }; + // The tag and its inner content is copied + // But the BazComponent is not created and therefore its template content is not displayed + // because BarComponents are processed before BazComponents + // and no chance for first Baz inside Bar to be processed by builder. + it(('should NOT include Bar within Baz'), () => { + const contents = ` +

Top

+ +
+ Inner ---baz stuff--- +
+
+

---More baz--

+

Bottom

+ `; + component.currentDoc = { title: 'fake title', contents }; -// // necessary to trigger Bar's projection within ngOnInit -// fixture.detectChanges(); -// const bazs = docViewerEl.querySelectorAll('aio-baz'); + // necessary to trigger Bar's projection within ngOnInit + fixture.detectChanges(); + const bazs = docViewerEl.querySelectorAll('aio-baz'); -// // Both baz tags are there ... -// expect(bazs.length).toBe(2, 'should have 2 bazs'); + // Both baz tags are there ... + expect(bazs.length).toBe(2, 'should have 2 bazs'); -// expect(bazs[0].innerHTML).not.toContain('Baz Component', -// 'did not expect 1st Baz template content'); + expect(bazs[0].innerHTML).not.toContain('Baz Component', + 'did not expect 1st Baz template content'); -// expect(bazs[1].innerHTML).toContain('Baz Component', -// 'expected 2nd Baz template content'); + expect(bazs[1].innerHTML).toContain('Baz Component', + 'expected 2nd Baz template content'); -// }); -// }); + }); +}); diff --git a/aio/src/app/layout/doc-viewer/doc-viewer.component.ts b/aio/src/app/layout/doc-viewer/doc-viewer.component.ts index 11f6c6575f..c70848fa26 100644 --- a/aio/src/app/layout/doc-viewer/doc-viewer.component.ts +++ b/aio/src/app/layout/doc-viewer/doc-viewer.component.ts @@ -53,7 +53,6 @@ export class DocViewerComponent implements DoCheck, OnDestroy { @Input() set doc(newDoc: DocumentContents) { - console.log(newDoc); this.ngOnDestroy(); if (newDoc) { window.scrollTo(0, 0); diff --git a/aio/src/app/layout/nav-menu/nav-menu.component.spec.ts b/aio/src/app/layout/nav-menu/nav-menu.component.spec.ts index c6e15c57e5..090c6572f0 100644 --- a/aio/src/app/layout/nav-menu/nav-menu.component.spec.ts +++ b/aio/src/app/layout/nav-menu/nav-menu.component.spec.ts @@ -1,5 +1,5 @@ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - +import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NavMenuComponent } from './nav-menu.component'; describe('NavMenuComponent', () => { @@ -8,7 +8,8 @@ describe('NavMenuComponent', () => { beforeEach(async(() => { TestBed.configureTestingModule({ - declarations: [ NavMenuComponent ] + declarations: [ NavMenuComponent ], + schemas: [NO_ERRORS_SCHEMA] }) .compileComponents(); })); diff --git a/aio/src/app/navigation/navigation.service.spec.ts b/aio/src/app/navigation/navigation.service.spec.ts index 54e5c9c4bf..847fa91829 100644 --- a/aio/src/app/navigation/navigation.service.spec.ts +++ b/aio/src/app/navigation/navigation.service.spec.ts @@ -1,14 +1,34 @@ -import { TestBed, inject } from '@angular/core/testing'; -import { NavigationService } from './navigation.service'; +import { ReflectiveInjector } from '@angular/core'; +import { Location, LocationStrategy } from '@angular/common'; +import { MockLocationStrategy } from '@angular/common/testing'; +import { Http, ConnectionBackend, RequestOptions, BaseRequestOptions } from '@angular/http'; +import { MockBackend } from '@angular/http/testing'; +import { NavigationService } from 'app/navigation/navigation.service'; +import { LocationService } from 'app/shared/location.service'; +import { Logger } from 'app/shared/logger.service'; describe('NavigationService', () => { + + let injector: ReflectiveInjector; + beforeEach(() => { - TestBed.configureTestingModule({ - providers: [NavigationService] - }); + injector = ReflectiveInjector.resolveAndCreate([ + NavigationService, + LocationService, + Location, + { provide: LocationStrategy, useClass: MockLocationStrategy }, + { provide: ConnectionBackend, useClass: MockBackend }, + { provide: RequestOptions, useClass: BaseRequestOptions }, + Http, + Logger + ]); }); - it('should ...', inject([NavigationService], (service: NavigationService) => { + it('should be creatable', () => { + const service: NavigationService = injector.get(NavigationService); expect(service).toBeTruthy(); - })); + }); + + xit('should fetch the navigation views', () => {}); + xit('should compute the navigation map', () => {}); });