225 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			225 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| // Based on https://github.com/angular/angular/blob/master/modules/angular2/test/testing/testing_public_spec.ts
 | |
| /* tslint:disable:forin */
 | |
| import { Component, EventEmitter, Injectable, Input, Output,
 | |
|          OnInit, OnChanges, OnDestroy, SimpleChange } from '@angular/core';
 | |
| 
 | |
| import { Observable }     from 'rxjs/Rx';
 | |
| 
 | |
| ////////// The App: Services and Components for the tests. //////////////
 | |
| 
 | |
| ////////// Services ///////////////
 | |
| 
 | |
| @Injectable()
 | |
| export class FancyService {
 | |
|   value: string = 'real value';
 | |
| 
 | |
|   getAsyncValue() { return Promise.resolve('async value'); }
 | |
| 
 | |
|   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); }
 | |
| }
 | |
| 
 | |
| @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; }
 | |
| }
 | |
| 
 | |
| @Component({
 | |
|   selector: 'input-comp',
 | |
|   template: `<input [(ngModel)]="name">`
 | |
| })
 | |
| export class InputComp {
 | |
|   name = 'John';
 | |
| }
 | |
| 
 | |
| @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',
 | |
|   template: `MyIf(<span *ngIf="showMore">More</span>)`
 | |
| })
 | |
| export class MyIfComp {
 | |
|   showMore = false;
 | |
| }
 | |
| 
 | |
| @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({
 | |
|   moduleId: module.id,
 | |
|   selector: 'external-template-comp',
 | |
|   templateUrl: 'bag-external-template.html'
 | |
| })
 | |
| export class ExternalTemplateComp { }
 | |
| 
 | |
| 
 | |
| @Component({
 | |
|   selector: 'bad-template-comp',
 | |
|   templateUrl: 'non-existant.html'
 | |
| })
 | |
| export class BadTemplateUrl { }
 | |
| 
 | |
| 
 | |
| ///////// 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>
 | |
|     <div *ngFor="let log of changeLog; let i=index">{{i + 1}} - {{log}}</div>`
 | |
| })
 | |
| 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';
 | |
|   }
 | |
| }
 |