| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | // Based on https://github.com/angular/angular/blob/master/modules/angular2/test/testing/testing_public_spec.ts
 | 
					
						
							|  |  |  | /* tslint:disable:no-unused-variable */ | 
					
						
							|  |  |  | import { | 
					
						
							|  |  |  |   BadTemplateUrl, ButtonComp, | 
					
						
							|  |  |  |   ChildChildComp, ChildComp, ChildWithChildComp, | 
					
						
							|  |  |  |   ExternalTemplateComp, | 
					
						
							|  |  |  |   FancyService, MockFancyService, | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  |   InputComp, | 
					
						
							|  |  |  |   MyIfComp, MyIfChildComp, MyIfParentComp, | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |   MockChildComp, MockChildChildComp, | 
					
						
							|  |  |  |   ParentComp, | 
					
						
							|  |  |  |   TestProvidersComp, TestViewProvidersComp | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  | } from './bag'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-27 11:28:22 -07:00
										 |  |  | import { DebugElement } from '@angular/core'; | 
					
						
							|  |  |  | import { By }           from '@angular/platform-browser'; | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | import { | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  |   beforeEach, beforeEachProviders, withProviders, | 
					
						
							|  |  |  |   describe, ddescribe, xdescribe, | 
					
						
							|  |  |  |   expect, it, iit, xit, | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |   async, inject, fakeAsync, tick, | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  |   ComponentFixture, TestComponentBuilder | 
					
						
							| 
									
										
										
										
											2016-04-27 11:28:22 -07:00
										 |  |  | } from '@angular/testing'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import { provide }        from '@angular/core'; | 
					
						
							|  |  |  | import { ViewMetadata }   from '@angular/core'; | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  | import { Observable }     from 'rxjs/Rx'; | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | ////////  SPECS  /////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// Verify can use Angular testing's DOM abstraction to access DOM
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | describe('angular2 jasmine matchers', () => { | 
					
						
							|  |  |  |   describe('toHaveCssClass', () => { | 
					
						
							|  |  |  |     it('should assert that the CSS class is present', () => { | 
					
						
							|  |  |  |       let el = document.createElement('div'); | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  |       el.classList.add('bombasto'); | 
					
						
							|  |  |  |       expect(el).toHaveCssClass('bombasto'); | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should assert that the CSS class is not present', () => { | 
					
						
							|  |  |  |       let el = document.createElement('div'); | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  |       el.classList.add('bombasto'); | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |       expect(el).not.toHaveCssClass('fatias'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('toHaveCssStyle', () => { | 
					
						
							|  |  |  |     it('should assert that the CSS style is present', () => { | 
					
						
							|  |  |  |       let el = document.createElement('div'); | 
					
						
							|  |  |  |       expect(el).not.toHaveCssStyle('width'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       el.style.setProperty('width', '100px'); | 
					
						
							|  |  |  |       expect(el).toHaveCssStyle('width'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should assert that the styles are matched against the element', () => { | 
					
						
							|  |  |  |       let el = document.createElement('div'); | 
					
						
							|  |  |  |       expect(el).not.toHaveCssStyle({width: '100px', height: '555px'}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       el.style.setProperty('width', '100px'); | 
					
						
							|  |  |  |       expect(el).toHaveCssStyle({width: '100px'}); | 
					
						
							|  |  |  |       expect(el).not.toHaveCssStyle({width: '100px', height: '555px'}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       el.style.setProperty('height', '555px'); | 
					
						
							|  |  |  |       expect(el).toHaveCssStyle({height: '555px'}); | 
					
						
							|  |  |  |       expect(el).toHaveCssStyle({width: '100px', height: '555px'}); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  | describe('using the async helper', () => { | 
					
						
							|  |  |  |   let actuallyDone = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   beforeEach(() => { actuallyDone = false; }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   afterEach(() => { expect(actuallyDone).toEqual(true); }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should run normal test', () => { actuallyDone = true; }); | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |   it('should run normal async test', (done: DoneFn) => { | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |     setTimeout(() => { | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       actuallyDone = true; | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |       done(); | 
					
						
							|  |  |  |     }, 0); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |   it('should run async test with task', | 
					
						
							|  |  |  |       async(() => { setTimeout(() => { actuallyDone = true; }, 0); })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should run async test with successful promise', async(() => { | 
					
						
							|  |  |  |     let p = new Promise(resolve => { setTimeout(resolve, 10); }); | 
					
						
							|  |  |  |     p.then(() => { actuallyDone = true; }); | 
					
						
							|  |  |  |   })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should run async test with failed promise', async(() => { | 
					
						
							|  |  |  |     let p = new Promise((resolve, reject) => { setTimeout(reject, 10); }); | 
					
						
							|  |  |  |     p.catch(() => { actuallyDone = true; }); | 
					
						
							|  |  |  |   })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should run async test with successful Observable', async(() => { | 
					
						
							|  |  |  |       let source = Observable.of(true).delay(10); | 
					
						
							|  |  |  |       source.subscribe( | 
					
						
							|  |  |  |         val => {}, | 
					
						
							|  |  |  |         err => fail(err), | 
					
						
							|  |  |  |         () => {  actuallyDone = true; } // completed
 | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     })); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | describe('using the test injector with the inject helper', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |   describe('setting up Providers with FancyService', () => { | 
					
						
							|  |  |  |     beforeEachProviders(() => [ | 
					
						
							|  |  |  |       provide(FancyService, {useValue: new FancyService()}) | 
					
						
							|  |  |  |     ]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should use FancyService', | 
					
						
							|  |  |  |       inject([FancyService], (service: FancyService) => { | 
					
						
							|  |  |  |         expect(service.value).toEqual('real value'); | 
					
						
							|  |  |  |     })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('test should wait for FancyService.getAsyncValue', | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       async(inject([FancyService], (service: FancyService) => { | 
					
						
							|  |  |  |         service.getAsyncValue().then( | 
					
						
							|  |  |  |           value => { expect(value).toEqual('async value'); }); | 
					
						
							|  |  |  |     }))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('test should wait for FancyService.getTimeoutValue', | 
					
						
							|  |  |  |       async(inject([FancyService], (service: FancyService) => { | 
					
						
							|  |  |  |         service.getTimeoutValue().then( | 
					
						
							|  |  |  |           value => { expect(value).toEqual('timeout value'); }); | 
					
						
							|  |  |  |     }))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('test should wait for FancyService.getObservableValue', | 
					
						
							|  |  |  |       async(inject([FancyService], (service: FancyService) => { | 
					
						
							|  |  |  |         service.getObservableValue().subscribe( | 
					
						
							|  |  |  |           value => { expect(value).toEqual('observable value'); } | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |     }))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('test should wait for FancyService.getObservableDelayValue', | 
					
						
							|  |  |  |       async(inject([FancyService], (service: FancyService) => { | 
					
						
							|  |  |  |         service.getObservableDelayValue().subscribe( | 
					
						
							|  |  |  |           value => { expect(value).toEqual('observable delay value'); } | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |     }))); | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     it('should allow the use of fakeAsync (Experimental)', | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       fakeAsync(inject([FancyService], (service: FancyService) => { | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |         let value: any; | 
					
						
							|  |  |  |         service.getAsyncValue().then((val: any) => value = val); | 
					
						
							|  |  |  |         tick(); // Trigger JS engine cycle until all promises resolve.
 | 
					
						
							|  |  |  |         expect(value).toEqual('async value'); | 
					
						
							|  |  |  |       }))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     describe('using inner beforeEach to inject-and-modify FancyService', () => { | 
					
						
							|  |  |  |       beforeEach(inject([FancyService], (service: FancyService) => { | 
					
						
							|  |  |  |         service.value = 'value modified in beforeEach'; | 
					
						
							|  |  |  |       })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should use modified providers', | 
					
						
							|  |  |  |         inject([FancyService], (service: FancyService) => { | 
					
						
							|  |  |  |           expect(service.value).toEqual('value modified in beforeEach'); | 
					
						
							|  |  |  |         })); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     describe('using async within beforeEach', () => { | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       beforeEach(async(inject([FancyService], (service: FancyService) => { | 
					
						
							|  |  |  |         service.getAsyncValue().then(value => { service.value = value; }); | 
					
						
							|  |  |  |       }))); | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it('should use asynchronously modified value ... in synchronous test', | 
					
						
							|  |  |  |           inject([FancyService], (service: FancyService) => { | 
					
						
							|  |  |  |             expect(service.value).toEqual('async value'); })); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('using `withProviders` for per-test provision', () => { | 
					
						
							|  |  |  |     it('should inject test-local FancyService for this test', | 
					
						
							|  |  |  |       // `withProviders`:  set up providers at individual test level
 | 
					
						
							|  |  |  |       withProviders(() => [provide(FancyService, {useValue: {value: 'fake value'}})]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // now inject and test
 | 
					
						
							|  |  |  |         .inject([FancyService], (service: FancyService) => { | 
					
						
							|  |  |  |           expect(service.value).toEqual('fake value'); | 
					
						
							|  |  |  |         })); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | describe('test component builder', function() { | 
					
						
							|  |  |  |   it('should instantiate a component with valid DOM', | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |         tcb.createAsync(ChildComp).then(fixture => { | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |           fixture.detectChanges(); | 
					
						
							|  |  |  |           expect(fixture.nativeElement).toHaveText('Original Child'); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       }))); | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   it('should allow changing members of the component', | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |        tcb.createAsync(MyIfComp).then(fixture => { | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |           fixture.detectChanges(); | 
					
						
							|  |  |  |           expect(fixture.nativeElement).toHaveText('MyIf()'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           fixture.debugElement.componentInstance.showMore = true; | 
					
						
							|  |  |  |           fixture.detectChanges(); | 
					
						
							|  |  |  |           expect(fixture.nativeElement).toHaveText('MyIf(More)'); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       }))); | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   it('should support clicking a button', | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |         tcb.createAsync(ButtonComp).then(fixture => { | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |           let comp = <ButtonComp> fixture.componentInstance; | 
					
						
							|  |  |  |           expect(comp.wasClicked).toEqual(false, 'wasClicked should be false at start'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  |           let btn = fixture.debugElement.query(By.css('button')); | 
					
						
							|  |  |  |           // let btn = fixture.debugElement.query(el => el.name === 'button'); // the hard way
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |           btn.triggerEventHandler('click', null); | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  |           // btn.nativeElement.click(); // this often works too ... but not all the time!
 | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |           expect(comp.wasClicked).toEqual(true, 'wasClicked should be true after click'); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       }))); | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  |   it('should support entering text in input box (ngModel)', | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  |         let origName = 'John'; | 
					
						
							|  |  |  |         let newName = 'Sally'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |         tcb.createAsync(InputComp).then(fixture => { | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |           let comp = <InputComp> fixture.componentInstance; | 
					
						
							|  |  |  |           expect(comp.name).toEqual(origName, `At start name should be ${origName} `); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           let inputBox = <HTMLInputElement> fixture.debugElement.query(By.css('input')).nativeElement; | 
					
						
							|  |  |  |           fixture.detectChanges(); | 
					
						
							|  |  |  |           expect(inputBox.value).toEqual(origName, `At start input box value should be ${origName} `); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           inputBox.value = newName; | 
					
						
							|  |  |  |           expect(comp.name).toEqual(origName, | 
					
						
							|  |  |  |            `Name should still be ${origName} after value change, before detectChanges`); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           fixture.detectChanges(); | 
					
						
							|  |  |  |           expect(inputBox.value).toEqual(newName, | 
					
						
							|  |  |  |           `After value change and detectChanges, name should now be ${newName} `); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       }))); | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |   it('should override a template', | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |         tcb.overrideTemplate(MockChildComp, '<span>Mock</span>') | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |             .createAsync(MockChildComp) | 
					
						
							|  |  |  |             .then(fixture => { | 
					
						
							|  |  |  |               fixture.detectChanges(); | 
					
						
							|  |  |  |               expect(fixture.nativeElement).toHaveText('Mock'); | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       }))); | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   it('should override a view', | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |         tcb.overrideView( | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |               ChildComp, | 
					
						
							|  |  |  |               new ViewMetadata({template: '<span>Modified {{childBinding}}</span>'}) | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             .createAsync(ChildComp) | 
					
						
							|  |  |  |             .then(fixture => { | 
					
						
							|  |  |  |               fixture.detectChanges(); | 
					
						
							|  |  |  |               expect(fixture.nativeElement).toHaveText('Modified Child'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       }))); | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  |   it('should override component directives', | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |         tcb.overrideDirective(ParentComp, ChildComp, MockChildComp) | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |             .createAsync(ParentComp) | 
					
						
							|  |  |  |             .then(fixture => { | 
					
						
							|  |  |  |               fixture.detectChanges(); | 
					
						
							|  |  |  |               expect(fixture.nativeElement).toHaveText('Parent(Mock)'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       }))); | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  |   it('should override child component\'s directives', | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |         tcb.overrideDirective(ParentComp, ChildComp, ChildWithChildComp) | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |             .overrideDirective(ChildWithChildComp, ChildChildComp, MockChildChildComp) | 
					
						
							|  |  |  |             .createAsync(ParentComp) | 
					
						
							|  |  |  |             .then(fixture => { | 
					
						
							|  |  |  |               fixture.detectChanges(); | 
					
						
							|  |  |  |               expect(fixture.nativeElement) | 
					
						
							|  |  |  |                   .toHaveText('Parent(Original Child(ChildChild Mock))'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       }))); | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   it('should override a provider', | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |         tcb.overrideProviders( | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |               TestProvidersComp, | 
					
						
							|  |  |  |               [provide(FancyService, {useClass: MockFancyService})] | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             .createAsync(TestProvidersComp) | 
					
						
							|  |  |  |             .then(fixture => { | 
					
						
							|  |  |  |               fixture.detectChanges(); | 
					
						
							|  |  |  |               expect(fixture.nativeElement) | 
					
						
							|  |  |  |                   .toHaveText('injected value: mocked out value'); | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       }))); | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   it('should override a viewProvider', | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |         tcb.overrideViewProviders( | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |               TestViewProvidersComp, | 
					
						
							|  |  |  |               [provide(FancyService, {useClass: MockFancyService})] | 
					
						
							|  |  |  |             ) | 
					
						
							|  |  |  |             .createAsync(TestViewProvidersComp) | 
					
						
							|  |  |  |             .then(fixture => { | 
					
						
							|  |  |  |               fixture.detectChanges(); | 
					
						
							|  |  |  |               expect(fixture.nativeElement) | 
					
						
							|  |  |  |                   .toHaveText('injected value: mocked out value'); | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       }))); | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   it('should allow an external templateUrl', | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |         tcb.createAsync(ExternalTemplateComp) | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |             .then(fixture => { | 
					
						
							|  |  |  |               fixture.detectChanges(); | 
					
						
							|  |  |  |               expect(fixture.nativeElement) | 
					
						
							|  |  |  |                   .toHaveText('from external template\n'); | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       })), 10000);  // Long timeout because this test makes an actual XHR.
 | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     describe('(lifecycle hooks w/ MyIfParentComp)', () => { | 
					
						
							|  |  |  |       let fixture: ComponentFixture; | 
					
						
							|  |  |  |       let parent:  MyIfParentComp; | 
					
						
							|  |  |  |       let child:   MyIfChildComp; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       /** | 
					
						
							|  |  |  |        * Get the MyIfChildComp from parent; fail w/ good message if cannot. | 
					
						
							|  |  |  |        */ | 
					
						
							|  |  |  |       function getChild() { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let childDe: DebugElement; // DebugElement that should hold the MyIfChildComp
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // The Hard Way: requires detailed knowledge of the parent template
 | 
					
						
							|  |  |  |         try { | 
					
						
							|  |  |  |           childDe = fixture.debugElement.children[4].children[0]; | 
					
						
							|  |  |  |         } catch (err) { /* we'll report the error */ } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // DebugElement.queryAll: if we wanted all of many instances:
 | 
					
						
							|  |  |  |         childDe = fixture.debugElement | 
					
						
							|  |  |  |           .queryAll(function (de) { return de.componentInstance instanceof MyIfChildComp; })[0]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // WE'LL USE THIS APPROACH !
 | 
					
						
							|  |  |  |         // DebugElement.query: find first instance (if any)
 | 
					
						
							|  |  |  |         childDe = fixture.debugElement | 
					
						
							|  |  |  |           .query(function (de) { return de.componentInstance instanceof MyIfChildComp; }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (childDe && childDe.componentInstance) { | 
					
						
							|  |  |  |           child = childDe.componentInstance; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           fail('Unable to find MyIfChildComp within MyIfParentComp'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return child; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // Create MyIfParentComp TCB and component instance before each test (async beforeEach)
 | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       beforeEach(async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | 
					
						
							|  |  |  |          tcb.createAsync(MyIfParentComp) | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  |             .then(fix => { | 
					
						
							|  |  |  |               fixture = fix; | 
					
						
							|  |  |  |               parent = fixture.debugElement.componentInstance; | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       }))); | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       it('should instantiate parent component', () => { | 
					
						
							|  |  |  |         expect(parent).not.toBeNull('parent component should exist'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('parent component OnInit should NOT be called before first detectChanges()', () => { | 
					
						
							|  |  |  |         expect(parent.ngOnInitCalled).toEqual(false); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('parent component OnInit should be called after first detectChanges()', () => { | 
					
						
							|  |  |  |         fixture.detectChanges(); | 
					
						
							|  |  |  |         expect(parent.ngOnInitCalled).toEqual(true); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('child component should exist after OnInit', () => { | 
					
						
							|  |  |  |         fixture.detectChanges(); | 
					
						
							|  |  |  |         getChild(); | 
					
						
							|  |  |  |         expect(child instanceof MyIfChildComp).toEqual(true, 'should create child'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should have called child component\'s OnInit ', () => { | 
					
						
							|  |  |  |         fixture.detectChanges(); | 
					
						
							|  |  |  |         getChild(); | 
					
						
							|  |  |  |         expect(child.ngOnInitCalled).toEqual(true); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('child component called OnChanges once', () => { | 
					
						
							|  |  |  |         fixture.detectChanges(); | 
					
						
							|  |  |  |         getChild(); | 
					
						
							|  |  |  |         expect(child.ngOnChangesCounter).toEqual(1); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('changed parent value flows to child', () => { | 
					
						
							|  |  |  |         fixture.detectChanges(); | 
					
						
							|  |  |  |         getChild(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         parent.parentValue = 'foo'; | 
					
						
							|  |  |  |         fixture.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(child.ngOnChangesCounter).toEqual(2, | 
					
						
							|  |  |  |           'expected 2 changes: initial value and changed value'); | 
					
						
							|  |  |  |         expect(child.childValue).toEqual('foo', | 
					
						
							|  |  |  |           'childValue should eq changed parent value'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |       it('changed child value flows to parent', async(() => { | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  |         fixture.detectChanges(); | 
					
						
							|  |  |  |         getChild(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         child.childValue = 'bar'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-27 11:28:22 -07:00
										 |  |  |         return new Promise(resolve => { | 
					
						
							|  |  |  |           // Wait one JS engine turn!
 | 
					
						
							|  |  |  |           setTimeout(() => resolve(), 0); | 
					
						
							|  |  |  |         }).then(() => { | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  |           fixture.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           expect(child.ngOnChangesCounter).toEqual(2, | 
					
						
							|  |  |  |             'expected 2 changes: initial value and changed value'); | 
					
						
							|  |  |  |           expect(parent.parentValue).toEqual('bar', | 
					
						
							|  |  |  |             'parentValue should eq changed parent value'); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('clicking "Close Child" triggers child OnDestroy', () => { | 
					
						
							|  |  |  |         fixture.detectChanges(); | 
					
						
							|  |  |  |         getChild(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let btn = fixture.debugElement.query(By.css('button')); | 
					
						
							|  |  |  |         btn.triggerEventHandler('click', null); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         fixture.detectChanges(); | 
					
						
							|  |  |  |         expect(child.ngOnDestroyCalled).toEqual(true); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | //////// Testing Framework Bugs? /////
 | 
					
						
							|  |  |  | import { HeroService }  from './hero.service'; | 
					
						
							| 
									
										
										
										
											2016-04-27 11:28:22 -07:00
										 |  |  | import { Component }    from '@angular/core'; | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'another-comp', | 
					
						
							|  |  |  |   template: `AnotherProvidersComp()`, | 
					
						
							|  |  |  |   providers: [FancyService] // <======= BOOM! if we comment out
 | 
					
						
							|  |  |  |   // Failed: 'undefined' is not an object (evaluating 'dm.providers.concat')
 | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | export class AnotherProvidersComp { | 
					
						
							|  |  |  |   constructor( | 
					
						
							|  |  |  |     private _heroService: HeroService | 
					
						
							|  |  |  |     ) {  } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | describe('tcb.overrideProviders', () => { | 
					
						
							|  |  |  |   it('Component must have at least one provider else crash', | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |     async(inject([TestComponentBuilder], (tcb: TestComponentBuilder) => { | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |     tcb.overrideProviders( | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  |           AnotherProvidersComp, | 
					
						
							|  |  |  |           [provide(HeroService, {useValue: {}})] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         .createAsync(AnotherProvidersComp); | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  |     }))); | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  | }); |