| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  | import {BehaviorSubject} from 'rxjs/BehaviorSubject'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import {createUrlTree} from '../src/create_url_tree'; | 
					
						
							| 
									
										
										
										
											2016-06-02 14:44:57 -07:00
										 |  |  | import {ActivatedRoute, ActivatedRouteSnapshot, advanceActivatedRoute} from '../src/router_state'; | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  | import {PRIMARY_OUTLET, Params} from '../src/shared'; | 
					
						
							| 
									
										
										
										
											2016-06-21 11:56:40 -07:00
										 |  |  | import {DefaultUrlSerializer, UrlPathWithParams, UrlSegment, UrlTree} from '../src/url_tree'; | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | describe('createUrlTree', () => { | 
					
						
							|  |  |  |   const serializer = new DefaultUrlSerializer(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |   it('should navigate to the root', () => { | 
					
						
							|  |  |  |     const p = serializer.parse('/'); | 
					
						
							|  |  |  |     const t = createRoot(p, ['/']); | 
					
						
							|  |  |  |     expect(serializer.serialize(t)).toEqual('/'); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |   it('should support nested segments', () => { | 
					
						
							|  |  |  |     const p = serializer.parse('/a/b'); | 
					
						
							|  |  |  |     const t = createRoot(p, ['/one', 11, 'two', 22]); | 
					
						
							|  |  |  |     expect(serializer.serialize(t)).toEqual('/one/11/two/22'); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |   it('should stringify positional parameters', () => { | 
					
						
							|  |  |  |     const p = serializer.parse('/a/b'); | 
					
						
							|  |  |  |     const t = createRoot(p, ['/one', 11]); | 
					
						
							| 
									
										
										
										
											2016-06-16 14:45:16 -07:00
										 |  |  |     const params = t.root.children[PRIMARY_OUTLET].pathsWithParams; | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |     expect(params[0].path).toEqual('one'); | 
					
						
							|  |  |  |     expect(params[1].path).toEqual('11'); | 
					
						
							| 
									
										
										
										
											2016-06-16 14:45:16 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |   it('should preserve secondary segments', () => { | 
					
						
							|  |  |  |     const p = serializer.parse('/a/11/b(right:c)'); | 
					
						
							|  |  |  |     const t = createRoot(p, ['/a', 11, 'd']); | 
					
						
							|  |  |  |     expect(serializer.serialize(t)).toEqual('/a/11/d(right:c)'); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |   it('should support updating secondary segments', () => { | 
					
						
							|  |  |  |     const p = serializer.parse('/a(right:b)'); | 
					
						
							|  |  |  |     const t = createRoot(p, ['right:c', 11, 'd']); | 
					
						
							|  |  |  |     expect(serializer.serialize(t)).toEqual('/a(right:c/11/d)'); | 
					
						
							| 
									
										
										
										
											2016-06-06 18:27:36 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |   it('should support updating secondary segments (nested case)', () => { | 
					
						
							|  |  |  |     const p = serializer.parse('/a/(b//right:c)'); | 
					
						
							|  |  |  |     const t = createRoot(p, ['a', 'right:d', 11, 'e']); | 
					
						
							|  |  |  |     expect(serializer.serialize(t)).toEqual('/a/(b//right:d/11/e)'); | 
					
						
							| 
									
										
										
										
											2016-06-06 18:27:36 -07:00
										 |  |  |   }); | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |   it('should update matrix parameters', () => { | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |     const p = serializer.parse('/a;pp=11'); | 
					
						
							|  |  |  |     const t = createRoot(p, ['/a', {pp: 22, dd: 33}]); | 
					
						
							|  |  |  |     expect(serializer.serialize(t)).toEqual('/a;pp=22;dd=33'); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should create matrix parameters', () => { | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |     const p = serializer.parse('/a'); | 
					
						
							|  |  |  |     const t = createRoot(p, ['/a', {pp: 22, dd: 33}]); | 
					
						
							|  |  |  |     expect(serializer.serialize(t)).toEqual('/a;pp=22;dd=33'); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should create matrix parameters together with other segments', () => { | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |     const p = serializer.parse('/a'); | 
					
						
							|  |  |  |     const t = createRoot(p, ['/a', '/b', {aa: 22, bb: 33}]); | 
					
						
							|  |  |  |     expect(serializer.serialize(t)).toEqual('/a/b;aa=22;bb=33'); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |   describe('relative navigation', () => { | 
					
						
							|  |  |  |     it('should work', () => { | 
					
						
							|  |  |  |       const p = serializer.parse('/a/(c//left:cp)(left:ap)'); | 
					
						
							|  |  |  |       const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ['c2']); | 
					
						
							|  |  |  |       expect(serializer.serialize(t)).toEqual('/a/(c2//left:cp)(left:ap)'); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |     it('should work when the first command starts with a ./', () => { | 
					
						
							|  |  |  |       const p = serializer.parse('/a/(c//left:cp)(left:ap)'); | 
					
						
							|  |  |  |       const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ['./c2']); | 
					
						
							|  |  |  |       expect(serializer.serialize(t)).toEqual('/a/(c2//left:cp)(left:ap)'); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |     it('should work when the first command is ./)', () => { | 
					
						
							|  |  |  |       const p = serializer.parse('/a/(c//left:cp)(left:ap)'); | 
					
						
							|  |  |  |       const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ['./', 'c2']); | 
					
						
							|  |  |  |       expect(serializer.serialize(t)).toEqual('/a/(c2//left:cp)(left:ap)'); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |     it('should work when given params', () => { | 
					
						
							|  |  |  |       const p = serializer.parse('/a/(c//left:cp)(left:ap)'); | 
					
						
							| 
									
										
										
										
											2016-06-14 14:55:59 -07:00
										 |  |  |       const t = create(p.root.children[PRIMARY_OUTLET], 0, p, [{'x': 99}]); | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |       expect(serializer.serialize(t)).toEqual('/a/(c;x=99//left:cp)(left:ap)'); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |     it('should work when index > 0', () => { | 
					
						
							|  |  |  |       const p = serializer.parse('/a/c'); | 
					
						
							|  |  |  |       const t = create(p.root.children[PRIMARY_OUTLET], 1, p, ['c2']); | 
					
						
							|  |  |  |       expect(serializer.serialize(t)).toEqual('/a/c/c2'); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |     it('should support going to a parent (within a segment)', () => { | 
					
						
							|  |  |  |       const p = serializer.parse('/a/c'); | 
					
						
							|  |  |  |       const t = create(p.root.children[PRIMARY_OUTLET], 1, p, ['../c2']); | 
					
						
							|  |  |  |       expect(serializer.serialize(t)).toEqual('/a/c2'); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |     it('should work when given ../', () => { | 
					
						
							|  |  |  |       const p = serializer.parse('/a/c'); | 
					
						
							|  |  |  |       const t = create(p.root.children[PRIMARY_OUTLET], 1, p, ['../', 'c2']); | 
					
						
							|  |  |  |       expect(serializer.serialize(t)).toEqual('/a/c2'); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |     it('should support setting matrix params', () => { | 
					
						
							|  |  |  |       const p = serializer.parse('/a/(c//left:cp)(left:ap)'); | 
					
						
							| 
									
										
										
										
											2016-06-14 14:55:59 -07:00
										 |  |  |       const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ['../', {x: 5}]); | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |       expect(serializer.serialize(t)).toEqual('/a;x=5(left:ap)'); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |     xit('should support going to a parent (across segments)', () => { | 
					
						
							|  |  |  |       const p = serializer.parse('/q/(a/(c//left:cp)//left:qp)(left:ap)'); | 
					
						
							| 
									
										
										
										
											2016-06-14 14:55:59 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |       const t = | 
					
						
							|  |  |  |           create(p.root.children[PRIMARY_OUTLET].children[PRIMARY_OUTLET], 0, p, ['../../q2']); | 
					
						
							|  |  |  |       expect(serializer.serialize(t)).toEqual('/q2(left:ap)'); | 
					
						
							| 
									
										
										
										
											2016-06-14 14:55:59 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |     xit('should navigate to the root', () => { | 
					
						
							|  |  |  |       const p = serializer.parse('/a/c'); | 
					
						
							| 
									
										
										
										
											2016-06-14 14:55:59 -07:00
										 |  |  |       const t = create(p.root.children[PRIMARY_OUTLET], 0, p, ['../']); | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |       expect(serializer.serialize(t)).toEqual(''); | 
					
						
							| 
									
										
										
										
											2016-06-14 14:55:59 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |     it('should throw when too many ..', () => { | 
					
						
							|  |  |  |       const p = serializer.parse('/a/(c//left:cp)(left:ap)'); | 
					
						
							|  |  |  |       expect(() => create(p.root.children[PRIMARY_OUTLET], 0, p, ['../../'])) | 
					
						
							|  |  |  |           .toThrowError('Invalid number of \'../\''); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |   it('should set query params', () => { | 
					
						
							|  |  |  |     const p = serializer.parse('/'); | 
					
						
							| 
									
										
										
										
											2016-06-14 14:55:59 -07:00
										 |  |  |     const t = createRoot(p, [], {a: 'hey'}); | 
					
						
							| 
									
										
										
										
											2016-06-06 16:34:48 -07:00
										 |  |  |     expect(t.queryParams).toEqual({a: 'hey'}); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |   it('should stringify query params', () => { | 
					
						
							|  |  |  |     const p = serializer.parse('/'); | 
					
						
							| 
									
										
										
										
											2016-06-14 14:55:59 -07:00
										 |  |  |     const t = createRoot(p, [], <any>{a: 1}); | 
					
						
							| 
									
										
										
										
											2016-06-06 16:34:48 -07:00
										 |  |  |     expect(t.queryParams).toEqual({a: '1'}); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |   it('should reuse old query params when given undefined', () => { | 
					
						
							|  |  |  |     const p = serializer.parse('/?a=1'); | 
					
						
							| 
									
										
										
										
											2016-06-14 14:55:59 -07:00
										 |  |  |     const t = createRoot(p, [], undefined); | 
					
						
							| 
									
										
										
										
											2016-06-06 16:34:48 -07:00
										 |  |  |     expect(t.queryParams).toEqual({a: '1'}); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |   it('should set fragment', () => { | 
					
						
							|  |  |  |     const p = serializer.parse('/'); | 
					
						
							|  |  |  |     const t = createRoot(p, [], {}, 'fragment'); | 
					
						
							|  |  |  |     expect(t.fragment).toEqual('fragment'); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |   it('should reused old fragment when given undefined', () => { | 
					
						
							|  |  |  |     const p = serializer.parse('/#fragment'); | 
					
						
							| 
									
										
										
										
											2016-06-14 14:55:59 -07:00
										 |  |  |     const t = createRoot(p, [], undefined, undefined); | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |     expect(t.fragment).toEqual('fragment'); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |   }); | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-14 14:55:59 -07:00
										 |  |  | function createRoot(tree: UrlTree, commands: any[], queryParams?: Params, fragment?: string) { | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |   const s = | 
					
						
							|  |  |  |       new ActivatedRouteSnapshot([], <any>{}, PRIMARY_OUTLET, 'someComponent', null, tree.root, -1); | 
					
						
							|  |  |  |   const a = new ActivatedRoute( | 
					
						
							|  |  |  |       new BehaviorSubject(null), new BehaviorSubject(null), PRIMARY_OUTLET, 'someComponent', s); | 
					
						
							| 
									
										
										
										
											2016-06-14 14:55:59 -07:00
										 |  |  |   advanceActivatedRoute(a); | 
					
						
							|  |  |  |   return createUrlTree(a, tree, commands, queryParams, fragment); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  | function create( | 
					
						
							|  |  |  |     segment: UrlSegment, startIndex: number, tree: UrlTree, commands: any[], queryParams?: Params, | 
					
						
							|  |  |  |     fragment?: string) { | 
					
						
							| 
									
										
										
										
											2016-06-14 14:55:59 -07:00
										 |  |  |   if (!segment) { | 
					
						
							|  |  |  |     expect(segment).toBeDefined(); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-06-21 11:49:42 -07:00
										 |  |  |   const s = new ActivatedRouteSnapshot( | 
					
						
							|  |  |  |       [], <any>{}, PRIMARY_OUTLET, 'someComponent', null, <any>segment, startIndex); | 
					
						
							|  |  |  |   const a = new ActivatedRoute( | 
					
						
							|  |  |  |       new BehaviorSubject(null), new BehaviorSubject(null), PRIMARY_OUTLET, 'someComponent', s); | 
					
						
							| 
									
										
										
										
											2016-06-02 14:44:57 -07:00
										 |  |  |   advanceActivatedRoute(a); | 
					
						
							| 
									
										
										
										
											2016-06-06 16:34:48 -07:00
										 |  |  |   return createUrlTree(a, tree, commands, queryParams, fragment); | 
					
						
							| 
									
										
										
										
											2016-05-26 16:51:19 -07:00
										 |  |  | } |