| 
									
										
										
										
											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
 | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  | /* tslint:disable:forin */ | 
					
						
							|  |  |  | import { Component, EventEmitter, Injectable, Input, Output, | 
					
						
							| 
									
										
										
										
											2016-04-27 11:28:22 -07:00
										 |  |  |          OnInit, OnChanges, OnDestroy, SimpleChange } 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
										 |  |  | ////////// The App: Services and Components for the tests. //////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ////////// Services ///////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Injectable() | 
					
						
							|  |  |  | export class FancyService { | 
					
						
							|  |  |  |   value: string = 'real value'; | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |   getAsyncValue() { return Promise.resolve('async value'); } | 
					
						
							| 
									
										
										
										
											2016-04-26 16:15:40 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   getObservableValue() { return Observable.of('observable value'); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   getTimeoutValue() { | 
					
						
							|  |  |  |     return new Promise((resolve, reject) => { setTimeout(() => {resolve('timeout value'); }, 10); }); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   getObservableDelayValue() { return Observable.of('observable delay value').delay(10); } | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Injectable() | 
					
						
							|  |  |  | export class MockFancyService extends FancyService { | 
					
						
							|  |  |  |   value: string = 'mocked out value'; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //////////// Components /////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'button-comp', | 
					
						
							|  |  |  |   template: `<button (click)='clicked()'>Click me!</button>` | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | export class ButtonComp { | 
					
						
							|  |  |  |   wasClicked = false; | 
					
						
							|  |  |  |   clicked() { this.wasClicked = true; } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'input-comp', | 
					
						
							|  |  |  |   template: `<input [(ngModel)]="name">` | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | export class InputComp { | 
					
						
							|  |  |  |   name = 'John'; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'child-comp', | 
					
						
							|  |  |  |   template: `<span>Original {{childBinding}}</span>` | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | export class ChildComp { | 
					
						
							|  |  |  |   childBinding = 'Child'; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'child-comp', | 
					
						
							|  |  |  |   template: `<span>Mock</span>` | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | export class MockChildComp { } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'parent-comp', | 
					
						
							|  |  |  |   template: `Parent(<child-comp></child-comp>)`, | 
					
						
							|  |  |  |   directives: [ChildComp] | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | export class ParentComp { } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'my-if-comp', | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  |   template: `MyIf(<span *ngIf="showMore">More</span>)` | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | }) | 
					
						
							|  |  |  | export class MyIfComp { | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  |   showMore = false; | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'child-child-comp', | 
					
						
							|  |  |  |   template: '<span>ChildChild</span>' | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | export class ChildChildComp { } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'child-comp', | 
					
						
							|  |  |  |   template: `<span>Original {{childBinding}}(<child-child-comp></child-child-comp>)</span>`, | 
					
						
							|  |  |  |   directives: [ChildChildComp] | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | export class ChildWithChildComp { | 
					
						
							|  |  |  |   childBinding = 'Child'; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'child-child-comp', | 
					
						
							|  |  |  |   template: `<span>ChildChild Mock</span>` | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | export class MockChildChildComp { } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'my-service-comp', | 
					
						
							|  |  |  |   template: `injected value: {{fancyService.value}}`, | 
					
						
							|  |  |  |   providers: [FancyService] | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | export class TestProvidersComp { | 
					
						
							|  |  |  |   constructor(private fancyService: FancyService) {} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'my-service-comp', | 
					
						
							|  |  |  |   template: `injected value: {{fancyService.value}}`, | 
					
						
							|  |  |  |   viewProviders: [FancyService] | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | export class TestViewProvidersComp { | 
					
						
							|  |  |  |   constructor(private fancyService: FancyService) {} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({ | 
					
						
							| 
									
										
										
										
											2016-05-02 23:09:54 -06:00
										 |  |  |   moduleId: module.id, | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  |   selector: 'external-template-comp', | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  |   templateUrl: 'bag-external-template.html' | 
					
						
							| 
									
										
										
										
											2016-04-10 15:04:04 -07:00
										 |  |  | }) | 
					
						
							|  |  |  | export class ExternalTemplateComp { } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'bad-template-comp', | 
					
						
							|  |  |  |   templateUrl: 'non-existant.html' | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | export class BadTemplateUrl { } | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ///////// MyIfChildComp ////////
 | 
					
						
							|  |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'my-if-child-comp', | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   template: `
 | 
					
						
							|  |  |  |     <h4>MyIfChildComp</h4> | 
					
						
							|  |  |  |     <div> | 
					
						
							|  |  |  |       <label>Child value: <input [(ngModel)]="childValue"> </label> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |     <p><i>Change log:</i></p> | 
					
						
							| 
									
										
										
										
											2016-04-29 01:36:35 +01:00
										 |  |  |     <div *ngFor="let log of changeLog; let i=index">{{i + 1}} - {{log}}</div>`
 | 
					
						
							| 
									
										
										
										
											2016-04-14 10:36:38 -07:00
										 |  |  | }) | 
					
						
							|  |  |  | export class MyIfChildComp implements OnInit, OnChanges, OnDestroy { | 
					
						
							|  |  |  |   @Input() value = ''; | 
					
						
							|  |  |  |   @Output() valueChange = new EventEmitter<string>(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   get childValue() { return this.value; } | 
					
						
							|  |  |  |   set childValue(v: string) { | 
					
						
							|  |  |  |     if (this.value === v) { return; } | 
					
						
							|  |  |  |     this.value = v; | 
					
						
							|  |  |  |     this.valueChange.emit(v); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   changeLog: string[] = []; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ngOnInitCalled = false; | 
					
						
							|  |  |  |   ngOnChangesCounter = 0; | 
					
						
							|  |  |  |   ngOnDestroyCalled = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ngOnInit()    { | 
					
						
							|  |  |  |     this.ngOnInitCalled = true; | 
					
						
							|  |  |  |     this.changeLog.push('ngOnInit called'); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ngOnDestroy() { | 
					
						
							|  |  |  |     this.ngOnDestroyCalled = true; | 
					
						
							|  |  |  |     this.changeLog.push('ngOnDestroy called'); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ngOnChanges(changes: {[propertyName: string]: SimpleChange}) { | 
					
						
							|  |  |  |     for (let propName in changes) { | 
					
						
							|  |  |  |       this.ngOnChangesCounter += 1; | 
					
						
							|  |  |  |       let prop = changes[propName]; | 
					
						
							|  |  |  |       let cur  = JSON.stringify(prop.currentValue); | 
					
						
							|  |  |  |       let prev = JSON.stringify(prop.previousValue); | 
					
						
							|  |  |  |       this.changeLog.push(`${propName}: currentValue = ${cur}, previousValue = ${prev}`); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ///////// MyIfParentComp ////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @Component({ | 
					
						
							|  |  |  |   selector: 'my-if-parent-comp', | 
					
						
							|  |  |  |   template: `
 | 
					
						
							|  |  |  |     <h3>MyIfParentComp</h3> | 
					
						
							|  |  |  |     <label>Parent value: | 
					
						
							|  |  |  |       <input [(ngModel)]="parentValue"> | 
					
						
							|  |  |  |     </label> | 
					
						
							|  |  |  |     <button (click)='clicked()'>{{toggleLabel}} Child</button><br> | 
					
						
							|  |  |  |     <div *ngIf="showChild" | 
					
						
							|  |  |  |          style="margin: 4px; padding: 4px; background-color: aliceblue;"> | 
					
						
							|  |  |  |       <my-if-child-comp  [(value)]="parentValue"></my-if-child-comp> | 
					
						
							|  |  |  |     </div> | 
					
						
							|  |  |  |   `,
 | 
					
						
							|  |  |  |   directives: [MyIfChildComp] | 
					
						
							|  |  |  | }) | 
					
						
							|  |  |  | export class MyIfParentComp implements OnInit { | 
					
						
							|  |  |  |   ngOnInitCalled = false; | 
					
						
							|  |  |  |   parentValue = 'Hello, World'; | 
					
						
							|  |  |  |   showChild = false; | 
					
						
							|  |  |  |   toggleLabel = 'Unknown'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ngOnInit() { | 
					
						
							|  |  |  |     this.ngOnInitCalled = true; | 
					
						
							|  |  |  |     this.clicked(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   clicked() { | 
					
						
							|  |  |  |     this.showChild = !this.showChild; | 
					
						
							|  |  |  |     this.toggleLabel = this.showChild ? 'Close' : 'Show'; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } |