| 
									
										
										
										
											2015-02-05 13:08:05 -08:00
										 |  |  | import {ddescribe, describe, it, iit, xit, expect, beforeEach, afterEach, IS_DARTIUM} from 'angular2/test_lib'; | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-05 13:08:05 -08:00
										 |  |  | import {isPresent, isBlank, isJsObject, BaseException, FunctionWrapper} from 'angular2/src/facade/lang'; | 
					
						
							|  |  |  | import {List, ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection'; | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-05 13:08:05 -08:00
										 |  |  | import {Parser} from 'angular2/src/change_detection/parser/parser'; | 
					
						
							|  |  |  | import {Lexer} from 'angular2/src/change_detection/parser/lexer'; | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-02 17:40:54 -08:00
										 |  |  | import {ChangeDispatcher, DynamicChangeDetector, ChangeDetectionError, ContextWithVariableBindings, | 
					
						
							| 
									
										
										
										
											2015-02-27 07:56:50 -08:00
										 |  |  |   PipeRegistry, Pipe, NO_CHANGE, CHECK_ALWAYS, CHECK_ONCE, CHECKED, DETACHED} from 'angular2/change_detection'; | 
					
						
							| 
									
										
										
										
											2015-02-20 16:23:16 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import {ChangeDetectionUtil} from 'angular2/src/change_detection/change_detection_util'; | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-05 13:08:05 -08:00
										 |  |  | import {JitProtoChangeDetector, DynamicProtoChangeDetector} from 'angular2/src/change_detection/proto_change_detector'; | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | export function main() { | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |   describe("change detection", () => { | 
					
						
							|  |  |  |     StringMapWrapper.forEach( | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |       { "dynamic": (registry = null) => new DynamicProtoChangeDetector(registry), | 
					
						
							|  |  |  |         "JIT": (registry = null) => new JitProtoChangeDetector(registry) | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |       }, (createProtoChangeDetector, name) => { | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |         if (name == "JIT" && IS_DARTIUM) return; | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |         function ast(exp:string, location:string = 'location') { | 
					
						
							|  |  |  |           var parser = new Parser(new Lexer()); | 
					
						
							|  |  |  |           return parser.parseBinding(exp, location); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 10:59:14 -08:00
										 |  |  |         function createChangeDetector(memo:string, exp:string, context = null, registry = null) { | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |           var pcd = createProtoChangeDetector(registry); | 
					
						
							| 
									
										
										
										
											2015-02-20 10:59:14 -08:00
										 |  |  |           pcd.addAst(ast(exp), memo, memo); | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |           var dispatcher = new TestDispatcher(); | 
					
						
							| 
									
										
										
										
											2015-02-20 10:59:14 -08:00
										 |  |  |           var cd = pcd.instantiate(dispatcher); | 
					
						
							| 
									
										
										
										
											2015-02-27 07:56:50 -08:00
										 |  |  |           cd.hydrate(context); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |           return {"changeDetector" : cd, "dispatcher" : dispatcher}; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 10:59:14 -08:00
										 |  |  |         function executeWatch(memo:string, exp:string, context = null) { | 
					
						
							|  |  |  |           var res = createChangeDetector(memo, exp, context); | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |           res["changeDetector"].detectChanges(); | 
					
						
							|  |  |  |           return res["dispatcher"].log; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |         describe(`${name} change detection`, () => { | 
					
						
							|  |  |  |           it('should do simple watching', () => { | 
					
						
							|  |  |  |             var person = new Person("misko"); | 
					
						
							|  |  |  |             var c = createChangeDetector('name', 'name', person); | 
					
						
							|  |  |  |             var cd = c["changeDetector"]; | 
					
						
							|  |  |  |             var dispatcher = c["dispatcher"]; | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |             cd.detectChanges(); | 
					
						
							|  |  |  |             expect(dispatcher.log).toEqual(['name=misko']); | 
					
						
							|  |  |  |             dispatcher.clear(); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-27 17:30:32 -08:00
										 |  |  |             cd.detectChanges(); | 
					
						
							|  |  |  |             expect(dispatcher.log).toEqual([]); | 
					
						
							|  |  |  |             dispatcher.clear(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |             person.name = "Misko"; | 
					
						
							|  |  |  |             cd.detectChanges(); | 
					
						
							|  |  |  |             expect(dispatcher.log).toEqual(['name=Misko']); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |           it('should report all changes on the first run including uninitialized values', () => { | 
					
						
							|  |  |  |             expect(executeWatch('value', 'value', new Uninitialized())).toEqual(['value=null']); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |           it('should report all changes on the first run including null values', () => { | 
					
						
							|  |  |  |             var td = new TestData(null); | 
					
						
							|  |  |  |             expect(executeWatch('a', 'a', td)).toEqual(['a=null']); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |           it("should support literals", () => { | 
					
						
							|  |  |  |             expect(executeWatch('const', '10')).toEqual(['const=10']); | 
					
						
							|  |  |  |             expect(executeWatch('const', '"str"')).toEqual(['const=str']); | 
					
						
							|  |  |  |             expect(executeWatch('const', '"a\n\nb"')).toEqual(['const=a\n\nb']); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |           it('simple chained property access', () => { | 
					
						
							|  |  |  |             var address = new Address('Grenoble'); | 
					
						
							|  |  |  |             var person = new Person('Victor', address); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |             expect(executeWatch('address.city', 'address.city', person)) | 
					
						
							|  |  |  |               .toEqual(['address.city=Grenoble']); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |           it("should support method calls", () => { | 
					
						
							|  |  |  |             var person = new Person('Victor'); | 
					
						
							|  |  |  |             expect(executeWatch('m', 'sayHi("Jim")', person)).toEqual(['m=Hi, Jim']); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |           it("should support function calls", () => { | 
					
						
							|  |  |  |             var td = new TestData(() => (a) => a); | 
					
						
							|  |  |  |             expect(executeWatch('value', 'a()(99)', td)).toEqual(['value=99']); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |           it("should support chained method calls", () => { | 
					
						
							|  |  |  |             var person = new Person('Victor'); | 
					
						
							|  |  |  |             var td = new TestData(person); | 
					
						
							|  |  |  |             expect(executeWatch('m', 'a.sayHi("Jim")', td)).toEqual(['m=Hi, Jim']); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |           it("should support literal array", () => { | 
					
						
							|  |  |  |             var c = createChangeDetector('array', '[1,2]'); | 
					
						
							|  |  |  |             c["changeDetector"].detectChanges(); | 
					
						
							|  |  |  |             expect(c["dispatcher"].loggedValues).toEqual([[[1, 2]]]); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |             c = createChangeDetector('array', '[1,a]', new TestData(2)); | 
					
						
							|  |  |  |             c["changeDetector"].detectChanges(); | 
					
						
							|  |  |  |             expect(c["dispatcher"].loggedValues).toEqual([[[1, 2]]]); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |           it("should support literal maps", () => { | 
					
						
							|  |  |  |             var c = createChangeDetector('map', '{z:1}'); | 
					
						
							|  |  |  |             c["changeDetector"].detectChanges(); | 
					
						
							|  |  |  |             expect(c["dispatcher"].loggedValues[0][0]['z']).toEqual(1); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |             c = createChangeDetector('map', '{z:a}', new TestData(1)); | 
					
						
							|  |  |  |             c["changeDetector"].detectChanges(); | 
					
						
							|  |  |  |             expect(c["dispatcher"].loggedValues[0][0]['z']).toEqual(1); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |           it("should support binary operations", () => { | 
					
						
							|  |  |  |             expect(executeWatch('exp', '10 + 2')).toEqual(['exp=12']); | 
					
						
							|  |  |  |             expect(executeWatch('exp', '10 - 2')).toEqual(['exp=8']); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |             expect(executeWatch('exp', '10 * 2')).toEqual(['exp=20']); | 
					
						
							|  |  |  |             expect(executeWatch('exp', '10 / 2')).toEqual([`exp=${5.0}`]); //dart exp=5.0, js exp=5
 | 
					
						
							|  |  |  |             expect(executeWatch('exp', '11 % 2')).toEqual(['exp=1']); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |             expect(executeWatch('exp', '1 == 1')).toEqual(['exp=true']); | 
					
						
							|  |  |  |             expect(executeWatch('exp', '1 != 1')).toEqual(['exp=false']); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |             expect(executeWatch('exp', '1 < 2')).toEqual(['exp=true']); | 
					
						
							|  |  |  |             expect(executeWatch('exp', '2 < 1')).toEqual(['exp=false']); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |             expect(executeWatch('exp', '2 > 1')).toEqual(['exp=true']); | 
					
						
							|  |  |  |             expect(executeWatch('exp', '2 < 1')).toEqual(['exp=false']); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |             expect(executeWatch('exp', '1 <= 2')).toEqual(['exp=true']); | 
					
						
							|  |  |  |             expect(executeWatch('exp', '2 <= 2')).toEqual(['exp=true']); | 
					
						
							|  |  |  |             expect(executeWatch('exp', '2 <= 1')).toEqual(['exp=false']); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |             expect(executeWatch('exp', '2 >= 1')).toEqual(['exp=true']); | 
					
						
							|  |  |  |             expect(executeWatch('exp', '2 >= 2')).toEqual(['exp=true']); | 
					
						
							|  |  |  |             expect(executeWatch('exp', '1 >= 2')).toEqual(['exp=false']); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |             expect(executeWatch('exp', 'true && true')).toEqual(['exp=true']); | 
					
						
							|  |  |  |             expect(executeWatch('exp', 'true && false')).toEqual(['exp=false']); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |             expect(executeWatch('exp', 'true || false')).toEqual(['exp=true']); | 
					
						
							|  |  |  |             expect(executeWatch('exp', 'false || false')).toEqual(['exp=false']); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |           it("should support negate", () => { | 
					
						
							|  |  |  |             expect(executeWatch('exp', '!true')).toEqual(['exp=false']); | 
					
						
							|  |  |  |             expect(executeWatch('exp', '!!true')).toEqual(['exp=true']); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |           it("should support conditionals", () => { | 
					
						
							|  |  |  |             expect(executeWatch('m', '1 < 2 ? 1 : 2')).toEqual(['m=1']); | 
					
						
							|  |  |  |             expect(executeWatch('m', '1 > 2 ? 1 : 2')).toEqual(['m=2']); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |           describe("keyed access", () => { | 
					
						
							|  |  |  |             it("should support accessing a list item", () => { | 
					
						
							|  |  |  |               expect(executeWatch('array[0]', '["foo", "bar"][0]')).toEqual(['array[0]=foo']); | 
					
						
							|  |  |  |             }); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |             it("should support accessing a map item", () => { | 
					
						
							|  |  |  |               expect(executeWatch('map[foo]', '{"foo": "bar"}["foo"]')).toEqual(['map[foo]=bar']); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |           it("should support interpolation", () => { | 
					
						
							|  |  |  |             var parser = new Parser(new Lexer()); | 
					
						
							|  |  |  |             var pcd = createProtoChangeDetector(); | 
					
						
							|  |  |  |             var ast = parser.parseInterpolation("B{{a}}A", "location"); | 
					
						
							| 
									
										
										
										
											2015-02-19 17:47:25 -08:00
										 |  |  |             pcd.addAst(ast, "memo", "memo"); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |             var dispatcher = new TestDispatcher(); | 
					
						
							| 
									
										
										
										
											2015-02-20 10:59:14 -08:00
										 |  |  |             var cd = pcd.instantiate(dispatcher); | 
					
						
							| 
									
										
										
										
											2015-02-27 07:56:50 -08:00
										 |  |  |             cd.hydrate(new TestData("value")); | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |             cd.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             expect(dispatcher.log).toEqual(["memo=BvalueA"]); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-02-20 16:23:16 -08:00
										 |  |  |   | 
					
						
							|  |  |  |           describe("change notification", () => { | 
					
						
							|  |  |  |             describe("simple checks", () => { | 
					
						
							|  |  |  |               it("should pass a change record to the dispatcher", () => { | 
					
						
							|  |  |  |                 var person = new Person('bob'); | 
					
						
							|  |  |  |                 var c = createChangeDetector('name', 'name', person); | 
					
						
							|  |  |  |                 var cd = c["changeDetector"]; | 
					
						
							|  |  |  |                 var dispatcher = c["dispatcher"]; | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 16:23:16 -08:00
										 |  |  |                 cd.detectChanges(); | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 16:23:16 -08:00
										 |  |  |                 var changeRecord = dispatcher.changeRecords[0][0]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 expect(changeRecord.bindingMemento).toEqual('name'); | 
					
						
							|  |  |  |                 expect(changeRecord.change.currentValue).toEqual('bob'); | 
					
						
							|  |  |  |                 expect(changeRecord.change.previousValue).toEqual(ChangeDetectionUtil.unitialized()); | 
					
						
							|  |  |  |               }); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             describe("pipes", () => { | 
					
						
							|  |  |  |               it("should pass a change record to the dispatcher", () => { | 
					
						
							|  |  |  |                 var registry = new FakePipeRegistry('pipe', () => new CountingPipe()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 var person = new Person('bob'); | 
					
						
							|  |  |  |                 var c = createChangeDetector('name', 'name | pipe', person, registry); | 
					
						
							|  |  |  |                 var cd = c["changeDetector"]; | 
					
						
							|  |  |  |                 var dispatcher = c["dispatcher"]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 cd.detectChanges(); | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 16:23:16 -08:00
										 |  |  |                 var changeRecord = dispatcher.changeRecords[0][0]; | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 16:23:16 -08:00
										 |  |  |                 expect(changeRecord.bindingMemento).toEqual('name'); | 
					
						
							|  |  |  |                 expect(changeRecord.change.currentValue).toEqual('bob state:0'); | 
					
						
							|  |  |  |                 expect(changeRecord.change.previousValue).toEqual(ChangeDetectionUtil.unitialized()); | 
					
						
							|  |  |  |               }); | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 16:23:16 -08:00
										 |  |  |             describe("group changes", () => { | 
					
						
							|  |  |  |               it("should notify the dispatcher when a group of records changes", () => { | 
					
						
							|  |  |  |                 var pcd = createProtoChangeDetector(); | 
					
						
							|  |  |  |                 pcd.addAst(ast("1 + 2"), "memo", "1"); | 
					
						
							|  |  |  |                 pcd.addAst(ast("10 + 20"), "memo", "1"); | 
					
						
							|  |  |  |                 pcd.addAst(ast("100 + 200"), "memo2", "2"); | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 16:23:16 -08:00
										 |  |  |                 var dispatcher = new TestDispatcher(); | 
					
						
							|  |  |  |                 var cd = pcd.instantiate(dispatcher); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 cd.detectChanges(); | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 16:23:16 -08:00
										 |  |  |                 expect(dispatcher.loggedValues).toEqual([[3, 30], [300]]); | 
					
						
							|  |  |  |               }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               it("should notify the dispatcher before switching to the next group", () => { | 
					
						
							|  |  |  |                 var pcd = createProtoChangeDetector(); | 
					
						
							|  |  |  |                 pcd.addAst(ast("a()"), "a", "1"); | 
					
						
							|  |  |  |                 pcd.addAst(ast("b()"), "b", "2"); | 
					
						
							|  |  |  |                 pcd.addAst(ast("c()"), "c", "2"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 var dispatcher = new TestDispatcher(); | 
					
						
							|  |  |  |                 var cd = pcd.instantiate(dispatcher); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 var tr = new TestRecord(); | 
					
						
							|  |  |  |                 tr.a = () => { | 
					
						
							|  |  |  |                   dispatcher.logValue('InvokeA'); | 
					
						
							|  |  |  |                   return 'a' | 
					
						
							|  |  |  |                 }; | 
					
						
							|  |  |  |                 tr.b = () => { | 
					
						
							|  |  |  |                   dispatcher.logValue('InvokeB'); | 
					
						
							|  |  |  |                   return 'b' | 
					
						
							|  |  |  |                 }; | 
					
						
							|  |  |  |                 tr.c = () => { | 
					
						
							|  |  |  |                   dispatcher.logValue('InvokeC'); | 
					
						
							|  |  |  |                   return 'c' | 
					
						
							|  |  |  |                 }; | 
					
						
							| 
									
										
										
										
											2015-02-27 07:56:50 -08:00
										 |  |  |                 cd.hydrate(tr); | 
					
						
							| 
									
										
										
										
											2015-02-20 16:23:16 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 cd.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 expect(dispatcher.loggedValues).toEqual(['InvokeA', ['a'], 'InvokeB', 'InvokeC', ['b', 'c']]); | 
					
						
							|  |  |  |               }); | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |             }); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-02-20 16:23:16 -08:00
										 |  |  |            | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |           describe("enforce no new changes", () => { | 
					
						
							|  |  |  |             it("should throw when a record gets changed after it has been checked", () => { | 
					
						
							|  |  |  |               var pcd = createProtoChangeDetector(); | 
					
						
							|  |  |  |               pcd.addAst(ast("a"), "a", 1); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |               var dispatcher = new TestDispatcher(); | 
					
						
							| 
									
										
										
										
											2015-02-20 10:59:14 -08:00
										 |  |  |               var cd = pcd.instantiate(dispatcher); | 
					
						
							| 
									
										
										
										
											2015-02-27 07:56:50 -08:00
										 |  |  |               cd.hydrate(new TestData('value')); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |               expect(() => { | 
					
						
							|  |  |  |                 cd.checkNoChanges(); | 
					
						
							|  |  |  |               }).toThrowError(new RegExp("Expression 'a in location' has changed after it was checked")); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           //TODO vsavkin: implement it
 | 
					
						
							|  |  |  |           describe("error handling", () => { | 
					
						
							|  |  |  |             xit("should wrap exceptions into ChangeDetectionError", () => { | 
					
						
							|  |  |  |               var pcd = createProtoChangeDetector(); | 
					
						
							|  |  |  |               pcd.addAst(ast('invalidProp', 'someComponent'), "a", 1); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 10:59:14 -08:00
										 |  |  |               var cd = pcd.instantiate(new TestDispatcher()); | 
					
						
							| 
									
										
										
										
											2015-02-27 07:56:50 -08:00
										 |  |  |               cd.hydrate(null); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |               try { | 
					
						
							|  |  |  |                 cd.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 throw new BaseException("fail"); | 
					
						
							|  |  |  |               } catch (e) { | 
					
						
							|  |  |  |                 expect(e).toBeAnInstanceOf(ChangeDetectionError); | 
					
						
							|  |  |  |                 expect(e.location).toEqual("invalidProp in someComponent"); | 
					
						
							|  |  |  |               } | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           describe("ContextWithVariableBindings", () => { | 
					
						
							|  |  |  |             it('should read a field from ContextWithVariableBindings', () => { | 
					
						
							|  |  |  |               var locals = new ContextWithVariableBindings(null, | 
					
						
							|  |  |  |                 MapWrapper.createFromPairs([["key", "value"]])); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               expect(executeWatch('key', 'key', locals)) | 
					
						
							|  |  |  |                 .toEqual(['key=value']); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 15:50:12 -08:00
										 |  |  |             it('should invoke a function from ContextWithVariableBindings', () => { | 
					
						
							|  |  |  |               var locals = new ContextWithVariableBindings(null, | 
					
						
							|  |  |  |                 MapWrapper.createFromPairs([["key", () => "value"]])); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               expect(executeWatch('key', 'key()', locals)) | 
					
						
							|  |  |  |                 .toEqual(['key=value']); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |             it('should handle nested ContextWithVariableBindings', () => { | 
					
						
							|  |  |  |               var nested = new ContextWithVariableBindings(null, | 
					
						
							|  |  |  |                 MapWrapper.createFromPairs([["key", "value"]])); | 
					
						
							|  |  |  |               var locals = new ContextWithVariableBindings(nested, MapWrapper.create()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               expect(executeWatch('key', 'key', locals)) | 
					
						
							|  |  |  |                 .toEqual(['key=value']); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             it("should fall back to a regular field read when ContextWithVariableBindings " + | 
					
						
							|  |  |  |             "does not have the requested field", () => { | 
					
						
							|  |  |  |               var locals = new ContextWithVariableBindings(new Person("Jim"), | 
					
						
							|  |  |  |                 MapWrapper.createFromPairs([["key", "value"]])); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               expect(executeWatch('name', 'name', locals)) | 
					
						
							|  |  |  |                 .toEqual(['name=Jim']); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           describe("handle children", () => { | 
					
						
							|  |  |  |             var parent, child; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             beforeEach(() => { | 
					
						
							|  |  |  |               var protoParent = createProtoChangeDetector(); | 
					
						
							| 
									
										
										
										
											2015-02-20 10:59:14 -08:00
										 |  |  |               parent = protoParent.instantiate(null); | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |               var protoChild = createProtoChangeDetector(); | 
					
						
							| 
									
										
										
										
											2015-02-20 10:59:14 -08:00
										 |  |  |               child = protoChild.instantiate(null); | 
					
						
							| 
									
										
										
										
											2015-01-21 12:05:52 -08:00
										 |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             it("should add children", () => { | 
					
						
							|  |  |  |               parent.addChild(child); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               expect(parent.children.length).toEqual(1); | 
					
						
							|  |  |  |               expect(parent.children[0]).toBe(child); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             it("should remove children", () => { | 
					
						
							|  |  |  |               parent.addChild(child); | 
					
						
							|  |  |  |               parent.removeChild(child); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |               expect(parent.children).toEqual([]); | 
					
						
							|  |  |  |             }); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-01-26 16:16:17 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-01 12:09:35 -08:00
										 |  |  |         describe("mode", () => { | 
					
						
							|  |  |  |           it("should not check a detached change detector", () => { | 
					
						
							|  |  |  |             var c = createChangeDetector('name', 'a', new TestData("value")); | 
					
						
							|  |  |  |             var cd = c["changeDetector"]; | 
					
						
							|  |  |  |             var dispatcher = c["dispatcher"]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             cd.mode = DETACHED; | 
					
						
							|  |  |  |             cd.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             expect(dispatcher.log).toEqual([]); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           it("should not check a checked change detector", () => { | 
					
						
							|  |  |  |             var c = createChangeDetector('name', 'a', new TestData("value")); | 
					
						
							|  |  |  |             var cd = c["changeDetector"]; | 
					
						
							|  |  |  |             var dispatcher = c["dispatcher"]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             cd.mode = CHECKED; | 
					
						
							|  |  |  |             cd.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             expect(dispatcher.log).toEqual([]); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           it("should change CHECK_ONCE to CHECKED", () => { | 
					
						
							| 
									
										
										
										
											2015-02-20 10:59:14 -08:00
										 |  |  |             var cd = createProtoChangeDetector().instantiate(null); | 
					
						
							| 
									
										
										
										
											2015-02-01 12:09:35 -08:00
										 |  |  |             cd.mode = CHECK_ONCE; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             cd.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             expect(cd.mode).toEqual(CHECKED); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           it("should not change the CHECK_ALWAYS", () => { | 
					
						
							| 
									
										
										
										
											2015-02-20 10:59:14 -08:00
										 |  |  |             var cd = createProtoChangeDetector().instantiate(null); | 
					
						
							| 
									
										
										
										
											2015-02-01 12:09:35 -08:00
										 |  |  |             cd.mode = CHECK_ALWAYS; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             cd.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             expect(cd.mode).toEqual(CHECK_ALWAYS); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-02 17:40:54 -08:00
										 |  |  |         describe("markPathToRootAsCheckOnce", () => { | 
					
						
							| 
									
										
										
										
											2015-02-01 12:09:35 -08:00
										 |  |  |           function changeDetector(mode, parent) { | 
					
						
							| 
									
										
										
										
											2015-02-20 10:59:14 -08:00
										 |  |  |             var cd = createProtoChangeDetector().instantiate(null); | 
					
						
							| 
									
										
										
										
											2015-02-01 12:09:35 -08:00
										 |  |  |             cd.mode = mode; | 
					
						
							|  |  |  |             if (isPresent(parent)) parent.addChild(cd); | 
					
						
							|  |  |  |             return cd; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           it("should mark all checked detectors as CHECK_ONCE " + | 
					
						
							|  |  |  |             "until reaching a detached one", () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             var root = changeDetector(CHECK_ALWAYS, null); | 
					
						
							|  |  |  |             var disabled = changeDetector(DETACHED, root); | 
					
						
							|  |  |  |             var parent = changeDetector(CHECKED, disabled); | 
					
						
							| 
									
										
										
										
											2015-02-02 17:40:54 -08:00
										 |  |  |             var checkAlwaysChild = changeDetector(CHECK_ALWAYS, parent); | 
					
						
							|  |  |  |             var checkOnceChild = changeDetector(CHECK_ONCE, checkAlwaysChild); | 
					
						
							|  |  |  |             var checkedChild = changeDetector(CHECKED, checkOnceChild); | 
					
						
							| 
									
										
										
										
											2015-02-01 12:09:35 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-11 16:28:10 -08:00
										 |  |  |             checkedChild.markPathToRootAsCheckOnce(); | 
					
						
							| 
									
										
										
										
											2015-02-01 12:09:35 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |             expect(root.mode).toEqual(CHECK_ALWAYS); | 
					
						
							|  |  |  |             expect(disabled.mode).toEqual(DETACHED); | 
					
						
							|  |  |  |             expect(parent.mode).toEqual(CHECK_ONCE); | 
					
						
							| 
									
										
										
										
											2015-02-02 17:40:54 -08:00
										 |  |  |             expect(checkAlwaysChild.mode).toEqual(CHECK_ALWAYS); | 
					
						
							|  |  |  |             expect(checkOnceChild.mode).toEqual(CHECK_ONCE); | 
					
						
							|  |  |  |             expect(checkedChild.mode).toEqual(CHECK_ONCE); | 
					
						
							| 
									
										
										
										
											2015-02-01 12:09:35 -08:00
										 |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-27 07:56:50 -08:00
										 |  |  |         describe("hydration", () => { | 
					
						
							|  |  |  |           it("should be able to rehydrate a change detector", () => { | 
					
						
							|  |  |  |             var c  = createChangeDetector("memo", "name"); | 
					
						
							|  |  |  |             var cd = c["changeDetector"]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             cd.hydrate("some context"); | 
					
						
							|  |  |  |             expect(cd.hydrated()).toBe(true); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             cd.dehydrate(); | 
					
						
							|  |  |  |             expect(cd.hydrated()).toBe(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             cd.hydrate("other context"); | 
					
						
							|  |  |  |             expect(cd.hydrated()).toBe(true); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           it("should destroy all active pipes during dehyration", () => { | 
					
						
							|  |  |  |             var pipe = new OncePipe(); | 
					
						
							|  |  |  |             var registry = new FakePipeRegistry('pipe', () => pipe); | 
					
						
							|  |  |  |             var c  = createChangeDetector("memo", "name | pipe", new Person('bob'), registry); | 
					
						
							|  |  |  |             var cd = c["changeDetector"]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             cd.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             cd.dehydrate(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             expect(pipe.destroyCalled).toBe(true); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |         describe("pipes", () => { | 
					
						
							|  |  |  |           it("should support pipes", () => { | 
					
						
							| 
									
										
										
										
											2015-02-19 17:47:25 -08:00
										 |  |  |             var registry = new FakePipeRegistry('pipe', () => new CountingPipe()); | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |             var ctx = new Person("Megatron"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 10:59:14 -08:00
										 |  |  |             var c  = createChangeDetector("memo", "name | pipe", ctx, registry); | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |             var cd = c["changeDetector"]; | 
					
						
							|  |  |  |             var dispatcher = c["dispatcher"]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             cd.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             expect(dispatcher.log).toEqual(['memo=Megatron state:0']); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             dispatcher.clear(); | 
					
						
							|  |  |  |             cd.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             expect(dispatcher.log).toEqual(['memo=Megatron state:1']); | 
					
						
							|  |  |  |           }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           it("should lookup pipes in the registry when the context is not supported", () => { | 
					
						
							| 
									
										
										
										
											2015-02-19 17:47:25 -08:00
										 |  |  |             var registry = new FakePipeRegistry('pipe', () => new OncePipe()); | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |             var ctx = new Person("Megatron"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 10:59:14 -08:00
										 |  |  |             var c  = createChangeDetector("memo", "name | pipe", ctx, registry); | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |             var cd = c["changeDetector"]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             cd.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             expect(registry.numberOfLookups).toEqual(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             ctx.name = "Optimus Prime"; | 
					
						
							|  |  |  |             cd.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             expect(registry.numberOfLookups).toEqual(2); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-02-27 07:56:50 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |           it("should invoke onDestroy on a pipe before switching to another one", () => { | 
					
						
							|  |  |  |             var pipe = new OncePipe(); | 
					
						
							|  |  |  |             var registry = new FakePipeRegistry('pipe', () => pipe); | 
					
						
							|  |  |  |             var ctx = new Person("Megatron"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             var c  = createChangeDetector("memo", "name | pipe", ctx, registry); | 
					
						
							|  |  |  |             var cd = c["changeDetector"]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             cd.detectChanges(); | 
					
						
							|  |  |  |             ctx.name = "Optimus Prime"; | 
					
						
							|  |  |  |             cd.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             expect(pipe.destroyCalled).toEqual(true); | 
					
						
							|  |  |  |           }); | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         it("should do nothing when returns NO_CHANGE", () => { | 
					
						
							| 
									
										
										
										
											2015-02-19 17:47:25 -08:00
										 |  |  |           var registry = new FakePipeRegistry('pipe', () => new IdentityPipe()) | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |           var ctx = new Person("Megatron"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 10:59:14 -08:00
										 |  |  |           var c  = createChangeDetector("memo", "name | pipe", ctx, registry); | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |           var cd = c["changeDetector"]; | 
					
						
							|  |  |  |           var dispatcher = c["dispatcher"]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           cd.detectChanges(); | 
					
						
							|  |  |  |           cd.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           expect(dispatcher.log).toEqual(['memo=Megatron']); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           ctx.name = "Optimus Prime"; | 
					
						
							|  |  |  |           dispatcher.clear(); | 
					
						
							|  |  |  |           cd.detectChanges(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           expect(dispatcher.log).toEqual(['memo=Optimus Prime']); | 
					
						
							|  |  |  |         }); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  |       }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-27 07:56:50 -08:00
										 |  |  | class CountingPipe extends Pipe { | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |   state:number; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   constructor() { | 
					
						
							| 
									
										
										
										
											2015-02-27 07:56:50 -08:00
										 |  |  |     super(); | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |     this.state = 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   supports(newValue) { | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   transform(value) { | 
					
						
							|  |  |  |     return `${value} state:${this.state ++}`; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-27 07:56:50 -08:00
										 |  |  | class OncePipe extends Pipe { | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |   called:boolean; | 
					
						
							| 
									
										
										
										
											2015-02-27 07:56:50 -08:00
										 |  |  |   destroyCalled:boolean; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |   constructor() { | 
					
						
							| 
									
										
										
										
											2015-02-27 07:56:50 -08:00
										 |  |  |     super(); | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |     this.called = false;; | 
					
						
							| 
									
										
										
										
											2015-02-27 07:56:50 -08:00
										 |  |  |     this.destroyCalled = false; | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   supports(newValue) { | 
					
						
							|  |  |  |     return !this.called; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-27 07:56:50 -08:00
										 |  |  |   onDestroy() { | 
					
						
							|  |  |  |     this.destroyCalled = true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |   transform(value) { | 
					
						
							|  |  |  |     this.called = true; | 
					
						
							|  |  |  |     return value; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-27 07:56:50 -08:00
										 |  |  | class IdentityPipe extends Pipe { | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |   state:any; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   supports(newValue) { | 
					
						
							|  |  |  |     return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   transform(value) { | 
					
						
							|  |  |  |     if (this.state === value) { | 
					
						
							|  |  |  |       return NO_CHANGE; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       this.state = value; | 
					
						
							|  |  |  |       return value; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class FakePipeRegistry extends PipeRegistry { | 
					
						
							|  |  |  |   numberOfLookups:number; | 
					
						
							| 
									
										
										
										
											2015-02-19 17:47:25 -08:00
										 |  |  |   pipeType:string; | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |   factory:Function; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-19 17:47:25 -08:00
										 |  |  |   constructor(pipeType, factory) { | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |     super({}); | 
					
						
							| 
									
										
										
										
											2015-02-19 17:47:25 -08:00
										 |  |  |     this.pipeType = pipeType; | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |     this.factory = factory; | 
					
						
							|  |  |  |     this.numberOfLookups = 0; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   get(type:string, obj) { | 
					
						
							| 
									
										
										
										
											2015-02-19 17:47:25 -08:00
										 |  |  |     if (type != this.pipeType) return null; | 
					
						
							| 
									
										
										
										
											2015-02-12 14:56:41 -08:00
										 |  |  |     this.numberOfLookups ++; | 
					
						
							|  |  |  |     return this.factory(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | class TestRecord { | 
					
						
							|  |  |  |   a; | 
					
						
							|  |  |  |   b; | 
					
						
							|  |  |  |   c; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Person { | 
					
						
							|  |  |  |   name:string; | 
					
						
							|  |  |  |   age:number; | 
					
						
							|  |  |  |   address:Address; | 
					
						
							|  |  |  |   constructor(name:string, address:Address = null) { | 
					
						
							|  |  |  |     this.name = name; | 
					
						
							|  |  |  |     this.address = address; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   sayHi(m) { | 
					
						
							|  |  |  |     return `Hi, ${m}`; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   toString():string { | 
					
						
							|  |  |  |     var address = this.address == null ? '' : ' address=' + this.address.toString(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return 'name=' + this.name + address; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class Address { | 
					
						
							|  |  |  |   city:string; | 
					
						
							|  |  |  |   constructor(city:string) { | 
					
						
							|  |  |  |     this.city = city; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   toString():string { | 
					
						
							|  |  |  |     return this.city; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-22 11:52:36 +01:00
										 |  |  | class Uninitialized { | 
					
						
							|  |  |  |   value:any; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  | class TestData { | 
					
						
							|  |  |  |   a; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   constructor(a) { | 
					
						
							|  |  |  |     this.a = a; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class TestDispatcher extends ChangeDispatcher { | 
					
						
							|  |  |  |   log:List; | 
					
						
							|  |  |  |   loggedValues:List; | 
					
						
							| 
									
										
										
										
											2015-02-20 16:23:16 -08:00
										 |  |  |   changeRecords:List; | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  |   onChange:Function; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   constructor() { | 
					
						
							| 
									
										
										
										
											2015-02-06 13:38:52 -08:00
										 |  |  |     super(); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  |     this.log = null; | 
					
						
							|  |  |  |     this.loggedValues = null; | 
					
						
							|  |  |  |     this.onChange = (_, __) => {}; | 
					
						
							|  |  |  |     this.clear(); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   clear() { | 
					
						
							|  |  |  |     this.log = ListWrapper.create(); | 
					
						
							|  |  |  |     this.loggedValues = ListWrapper.create(); | 
					
						
							| 
									
										
										
										
											2015-02-20 16:23:16 -08:00
										 |  |  |     this.changeRecords = ListWrapper.create(); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   logValue(value) { | 
					
						
							|  |  |  |     ListWrapper.push(this.loggedValues, value); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 16:23:16 -08:00
										 |  |  |   onRecordChange(group, changeRecords:List) { | 
					
						
							|  |  |  |     var value = changeRecords[0].change.currentValue; | 
					
						
							|  |  |  |     var memento = changeRecords[0].bindingMemento; | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  |     ListWrapper.push(this.log, memento + '=' + this._asString(value)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 16:23:16 -08:00
										 |  |  |     var values = ListWrapper.map(changeRecords, (r) => r.change.currentValue); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  |     ListWrapper.push(this.loggedValues, values); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-20 16:23:16 -08:00
										 |  |  |     ListWrapper.push(this.changeRecords, changeRecords); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     this.onChange(group, changeRecords); | 
					
						
							| 
									
										
										
										
											2015-01-14 13:51:16 -08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   _asString(value) { | 
					
						
							|  |  |  |     return (isBlank(value) ? 'null' : value.toString()); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-01-22 11:52:36 +01:00
										 |  |  | } |