| 
									
										
										
										
											2014-10-27 23:16:31 -07:00
										 |  |  | import {describe, xit, it, expect, beforeEach} from 'test_lib/test_lib'; | 
					
						
							|  |  |  | import {ProtoView, ElementPropertyMemento, DirectivePropertyMemento} from 'core/compiler/view'; | 
					
						
							|  |  |  | import {Record} from 'change_detection/record'; | 
					
						
							| 
									
										
										
										
											2014-10-10 20:44:55 -07:00
										 |  |  | import {ProtoElementInjector, ElementInjector} from 'core/compiler/element_injector'; | 
					
						
							| 
									
										
										
										
											2014-10-29 15:41:50 -07:00
										 |  |  | import {ProtoWatchGroup} from 'change_detection/watch_group'; | 
					
						
							|  |  |  | import {ChangeDetector} from 'change_detection/change_detector'; | 
					
						
							| 
									
										
										
										
											2014-10-10 20:44:55 -07:00
										 |  |  | import {DOM, Element} from 'facade/dom'; | 
					
						
							| 
									
										
										
										
											2014-10-27 23:16:31 -07:00
										 |  |  | import {FIELD} from 'facade/lang'; | 
					
						
							| 
									
										
										
										
											2014-11-05 17:10:37 -08:00
										 |  |  | import {ImplicitReceiver, AccessMember} from 'change_detection/parser/ast'; | 
					
						
							| 
									
										
										
										
											2014-10-29 15:41:50 -07:00
										 |  |  | import {ClosureMap} from 'change_detection/parser/closure_map'; | 
					
						
							| 
									
										
										
										
											2014-10-30 14:41:19 -07:00
										 |  |  | import {ElementBinder} from 'core/compiler/element_binder'; | 
					
						
							| 
									
										
										
										
											2014-10-27 11:47:13 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | class Directive { | 
					
						
							| 
									
										
										
										
											2014-10-27 23:16:31 -07:00
										 |  |  |   @FIELD('prop') | 
					
						
							|  |  |  |   constructor() { | 
					
						
							|  |  |  |     this.prop = 'foo'; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-10-27 11:47:13 -04:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-09-28 20:02:32 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | export function main() { | 
					
						
							| 
									
										
										
										
											2014-11-05 10:00:19 -08:00
										 |  |  |   var oneFieldAst = (fieldName) => { | 
					
						
							|  |  |  |     var cm = new ClosureMap(); | 
					
						
							| 
									
										
										
										
											2014-11-05 17:10:37 -08:00
										 |  |  |     return new AccessMember(new ImplicitReceiver(), fieldName, | 
					
						
							| 
									
										
										
										
											2014-11-05 10:00:19 -08:00
										 |  |  |       cm.getter(fieldName), cm.setter(fieldName)); | 
					
						
							|  |  |  |   }; | 
					
						
							| 
									
										
										
										
											2014-10-29 15:41:50 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-28 13:55:01 -07:00
										 |  |  |   describe('view', function() { | 
					
						
							| 
									
										
										
										
											2014-10-27 23:16:31 -07:00
										 |  |  |     var tempalteWithThreeTypesOfBindings = | 
					
						
							| 
									
										
										
										
											2014-10-27 11:47:13 -04:00
										 |  |  |             '<section class="ng-binding">' + | 
					
						
							| 
									
										
										
										
											2014-10-10 20:44:55 -07:00
										 |  |  |                'Hello {}!' + | 
					
						
							| 
									
										
										
										
											2014-10-27 11:47:13 -04:00
										 |  |  |                '<div directive class="ng-binding">' + | 
					
						
							| 
									
										
										
										
											2014-10-29 15:41:50 -07:00
										 |  |  |                  '<span class="ng-binding" [id]="exp">don\'t show me</span>' + | 
					
						
							| 
									
										
										
										
											2014-10-10 20:44:55 -07:00
										 |  |  |                '</div>' + | 
					
						
							| 
									
										
										
										
											2014-10-27 23:16:31 -07:00
										 |  |  |              '</section>'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-30 14:41:19 -07:00
										 |  |  |     function templateElementBinders() { | 
					
						
							| 
									
										
										
										
											2014-11-04 17:03:35 -08:00
										 |  |  |         var sectionPI = new ElementBinder(new ProtoElementInjector(null, 0, []), | 
					
						
							| 
									
										
										
										
											2014-10-30 14:41:19 -07:00
										 |  |  |             [0], false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         var divPI = new ElementBinder(new ProtoElementInjector( | 
					
						
							| 
									
										
										
										
											2014-11-04 17:03:35 -08:00
										 |  |  |             sectionPI.protoElementInjector, 1, [Directive]), [], false); | 
					
						
							| 
									
										
										
										
											2014-10-30 14:41:19 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         var spanPI = new ElementBinder(new ProtoElementInjector( | 
					
						
							| 
									
										
										
										
											2014-11-04 17:03:35 -08:00
										 |  |  |             divPI.protoElementInjector, 2, []), [], true); | 
					
						
							| 
									
										
										
										
											2014-10-29 15:41:50 -07:00
										 |  |  |         return [sectionPI, divPI, spanPI]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-27 23:16:31 -07:00
										 |  |  |     describe('ProtoView', function() { | 
					
						
							|  |  |  |       it('should create view instance and locate basic parts', function() { | 
					
						
							|  |  |  |         var template = DOM.createTemplate(tempalteWithThreeTypesOfBindings); | 
					
						
							| 
									
										
										
										
											2014-10-27 11:47:13 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         var hasSingleRoot = false; | 
					
						
							| 
									
										
										
										
											2014-10-30 14:41:19 -07:00
										 |  |  |         var pv = new ProtoView(template, templateElementBinders(), | 
					
						
							| 
									
										
										
										
											2014-10-29 15:41:50 -07:00
										 |  |  |             new ProtoWatchGroup(), hasSingleRoot); | 
					
						
							| 
									
										
										
										
											2014-10-27 11:47:13 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-29 15:41:50 -07:00
										 |  |  |         var view = pv.instantiate(null, null); | 
					
						
							| 
									
										
										
										
											2014-10-27 11:47:13 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         var section = DOM.firstChild(template.content); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(DOM.getInnerHTML(DOM.firstChild(view.fragment))).toEqual(DOM.getInnerHTML(section)); // exclude top level <section>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(view.elementInjectors.length).toEqual(3); | 
					
						
							|  |  |  |         expect(view.elementInjectors[0]).toBeNull(); | 
					
						
							|  |  |  |         expect(view.elementInjectors[1]).toBeAnInstanceOf(ElementInjector); | 
					
						
							|  |  |  |         expect(view.elementInjectors[2]).toBeNull(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(view.textNodes.length).toEqual(1); | 
					
						
							| 
									
										
										
										
											2014-10-27 23:16:31 -07:00
										 |  |  |         expect(view.bindElements.length).toEqual(1); | 
					
						
							| 
									
										
										
										
											2014-10-27 11:47:13 -04:00
										 |  |  |         expect(view.textNodes[0].nodeValue).toEqual('Hello {}!'); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       it('should set root element injectors', function() { | 
					
						
							|  |  |  |         var template = DOM.createTemplate( | 
					
						
							|  |  |  |           '<section directive class="ng-binding">' + | 
					
						
							|  |  |  |             '<div directive class="ng-binding"></div>' + | 
					
						
							|  |  |  |           '</section>'); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-30 14:41:19 -07:00
										 |  |  |         var sectionPI = new ElementBinder(new ProtoElementInjector( | 
					
						
							| 
									
										
										
										
											2014-11-04 17:03:35 -08:00
										 |  |  |             null, 0, [Directive]), [], false); | 
					
						
							| 
									
										
										
										
											2014-10-30 14:41:19 -07:00
										 |  |  |         var divPI = new ElementBinder(new ProtoElementInjector( | 
					
						
							| 
									
										
										
										
											2014-11-04 17:03:35 -08:00
										 |  |  |             sectionPI.protoElementInjector, 1, [Directive]), [], false); | 
					
						
							| 
									
										
										
										
											2014-10-27 11:47:13 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-30 14:41:19 -07:00
										 |  |  |         var pv = new ProtoView(template, [sectionPI, divPI], | 
					
						
							| 
									
										
										
										
											2014-10-29 15:41:50 -07:00
										 |  |  |           new ProtoWatchGroup(), false); | 
					
						
							|  |  |  |         var view = pv.instantiate(null, null); | 
					
						
							| 
									
										
										
										
											2014-10-27 11:47:13 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |         expect(view.rootElementInjectors.length).toEqual(1); | 
					
						
							| 
									
										
										
										
											2014-10-10 20:44:55 -07:00
										 |  |  |       }); | 
					
						
							| 
									
										
										
										
											2014-10-27 23:16:31 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       describe('react to watch group changes', function() { | 
					
						
							|  |  |  |         var view; | 
					
						
							|  |  |  |         beforeEach(() => { | 
					
						
							|  |  |  |           var template = DOM.createTemplate(tempalteWithThreeTypesOfBindings); | 
					
						
							| 
									
										
										
										
											2014-10-30 14:41:19 -07:00
										 |  |  |           var pv = new ProtoView(template, templateElementBinders(), | 
					
						
							| 
									
										
										
										
											2014-10-29 15:41:50 -07:00
										 |  |  |             new ProtoWatchGroup(), false); | 
					
						
							|  |  |  |           view = pv.instantiate(null, null); | 
					
						
							| 
									
										
										
										
											2014-10-27 23:16:31 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should consume text node changes', () => { | 
					
						
							|  |  |  |           var record = new Record(null, null); | 
					
						
							|  |  |  |           record.currentValue = 'Hello World!'; | 
					
						
							|  |  |  |           view.onRecordChange(record , 0); | 
					
						
							|  |  |  |           expect(view.textNodes[0].nodeValue).toEqual('Hello World!'); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should consume element binding changes', () => { | 
					
						
							|  |  |  |           var elementWithBinding = view.bindElements[0]; | 
					
						
							| 
									
										
										
										
											2014-10-29 15:41:50 -07:00
										 |  |  |           expect(elementWithBinding.id).toEqual(''); | 
					
						
							| 
									
										
										
										
											2014-10-27 23:16:31 -07:00
										 |  |  |           var record = new Record(null, null); | 
					
						
							| 
									
										
										
										
											2014-10-29 15:41:50 -07:00
										 |  |  |           var memento = new ElementPropertyMemento(0, 'id'); | 
					
						
							|  |  |  |           record.currentValue = 'foo'; | 
					
						
							| 
									
										
										
										
											2014-10-27 23:16:31 -07:00
										 |  |  |           view.onRecordChange(record, memento); | 
					
						
							| 
									
										
										
										
											2014-10-29 15:41:50 -07:00
										 |  |  |           expect(elementWithBinding.id).toEqual('foo'); | 
					
						
							| 
									
										
										
										
											2014-10-27 23:16:31 -07:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should consume directive watch expression change.', () => { | 
					
						
							|  |  |  |           var elInj = view.elementInjectors[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           expect(elInj.get(Directive).prop).toEqual('foo'); | 
					
						
							|  |  |  |           var record = new Record(null, null); | 
					
						
							|  |  |  |           var memento = new DirectivePropertyMemento(1, 0, 'prop', | 
					
						
							|  |  |  |               (o, v) => o.prop = v); | 
					
						
							|  |  |  |           record.currentValue = 'bar'; | 
					
						
							|  |  |  |           view.onRecordChange(record, memento); | 
					
						
							|  |  |  |           expect(elInj.get(Directive).prop).toEqual('bar'); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2014-10-29 15:41:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       describe('integration view update with change detector', () => { | 
					
						
							|  |  |  |         var view, cd, ctx; | 
					
						
							|  |  |  |         function setUp(memento) { | 
					
						
							|  |  |  |           var template = DOM.createTemplate(tempalteWithThreeTypesOfBindings); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           var protoWatchGroup = new ProtoWatchGroup(); | 
					
						
							|  |  |  |           protoWatchGroup.watch(oneFieldAst('foo'), memento); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-30 14:41:19 -07:00
										 |  |  |           var pv = new ProtoView(template, templateElementBinders(), | 
					
						
							| 
									
										
										
										
											2014-10-29 15:41:50 -07:00
										 |  |  |               protoWatchGroup, false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           ctx = new MyEvaluationContext(); | 
					
						
							|  |  |  |           view = pv.instantiate(ctx, null); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           cd = new ChangeDetector(view.watchGroup); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should consume text node changes', () => { | 
					
						
							|  |  |  |           setUp(0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           ctx.foo = 'buz'; | 
					
						
							|  |  |  |           cd.detectChanges(); | 
					
						
							|  |  |  |           expect(view.textNodes[0].nodeValue).toEqual('buz'); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should consume element binding changes', () => { | 
					
						
							|  |  |  |           setUp(new ElementPropertyMemento(0, 'id')); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           var elementWithBinding = view.bindElements[0]; | 
					
						
							|  |  |  |           expect(elementWithBinding.id).toEqual(''); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           ctx.foo = 'buz'; | 
					
						
							|  |  |  |           cd.detectChanges(); | 
					
						
							|  |  |  |           expect(elementWithBinding.id).toEqual('buz'); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it('should consume directive watch expression change.', () => { | 
					
						
							|  |  |  |           var memento = new DirectivePropertyMemento(1, 0, 'prop', | 
					
						
							|  |  |  |               (o, v) => o.prop = v); | 
					
						
							|  |  |  |           setUp(memento); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           var elInj = view.elementInjectors[1]; | 
					
						
							|  |  |  |           expect(elInj.get(Directive).prop).toEqual('foo'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           ctx.foo = 'buz'; | 
					
						
							|  |  |  |           cd.detectChanges(); | 
					
						
							|  |  |  |           expect(elInj.get(Directive).prop).toEqual('buz'); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2014-09-28 20:02:32 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-10-29 15:41:50 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | class MyEvaluationContext { | 
					
						
							|  |  |  |   @FIELD('foo') | 
					
						
							|  |  |  |   constructor() { | 
					
						
							|  |  |  |     this.foo = 'bar'; | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } |