| 
									
										
										
										
											2016-06-23 09:47:54 -07:00
										 |  |  | /** | 
					
						
							|  |  |  |  * @license | 
					
						
							|  |  |  |  * Copyright Google Inc. All Rights Reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Use of this source code is governed by an MIT-style license that can be | 
					
						
							|  |  |  |  * found in the LICENSE file at https://angular.io/license
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-01 12:19:09 -07:00
										 |  |  | import * as html from '../../src/ml_parser/ast'; | 
					
						
							|  |  |  | import {HtmlParser} from '../../src/ml_parser/html_parser'; | 
					
						
							|  |  |  | import {ExpansionResult, expandNodes} from '../../src/ml_parser/icu_ast_expander'; | 
					
						
							| 
									
										
										
										
											2016-07-21 11:41:25 -07:00
										 |  |  | import {ParseError} from '../../src/parse_util'; | 
					
						
							| 
									
										
										
										
											2016-06-30 14:59:23 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-21 13:56:58 -07:00
										 |  |  | import {humanizeNodes} from './ast_spec_utils'; | 
					
						
							| 
									
										
										
										
											2016-06-17 11:38:24 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-12-16 14:42:55 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-06-17 11:38:24 -07:00
										 |  |  |   describe('Expander', () => { | 
					
						
							|  |  |  |     function expand(template: string): ExpansionResult { | 
					
						
							| 
									
										
										
										
											2016-06-24 14:31:35 -07:00
										 |  |  |       const htmlParser = new HtmlParser(); | 
					
						
							| 
									
										
										
										
											2019-02-08 22:10:19 +00:00
										 |  |  |       const res = htmlParser.parse(template, 'url', {tokenizeExpansionForms: true}); | 
					
						
							| 
									
										
										
										
											2016-06-17 11:38:24 -07:00
										 |  |  |       return expandNodes(res.rootNodes); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should handle the plural expansion form', () => { | 
					
						
							|  |  |  |       const res = expand(`{messages.length, plural,=0 {zero<b>bold</b>}}`); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(humanizeNodes(res.nodes)).toEqual([ | 
					
						
							| 
									
										
										
										
											2016-07-21 13:56:58 -07:00
										 |  |  |         [html.Element, 'ng-container', 0], | 
					
						
							|  |  |  |         [html.Attribute, '[ngPlural]', 'messages.length'], | 
					
						
							| 
									
										
										
										
											2017-01-09 13:16:46 -08:00
										 |  |  |         [html.Element, 'ng-template', 1], | 
					
						
							| 
									
										
										
										
											2016-07-21 13:56:58 -07:00
										 |  |  |         [html.Attribute, 'ngPluralCase', '=0'], | 
					
						
							|  |  |  |         [html.Text, 'zero', 2], | 
					
						
							|  |  |  |         [html.Element, 'b', 2], | 
					
						
							|  |  |  |         [html.Text, 'bold', 3], | 
					
						
							| 
									
										
										
										
											2016-06-17 11:38:24 -07:00
										 |  |  |       ]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should handle nested expansion forms', () => { | 
					
						
							| 
									
										
										
										
											2018-01-22 12:23:10 -08:00
										 |  |  |       const res = expand(`{messages.length, plural, =0 { {p.gender, select, male {m}} }}`); | 
					
						
							| 
									
										
										
										
											2016-06-17 11:38:24 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       expect(humanizeNodes(res.nodes)).toEqual([ | 
					
						
							| 
									
										
										
										
											2016-07-21 13:56:58 -07:00
										 |  |  |         [html.Element, 'ng-container', 0], | 
					
						
							|  |  |  |         [html.Attribute, '[ngPlural]', 'messages.length'], | 
					
						
							| 
									
										
										
										
											2017-01-09 13:16:46 -08:00
										 |  |  |         [html.Element, 'ng-template', 1], | 
					
						
							| 
									
										
										
										
											2016-07-21 13:56:58 -07:00
										 |  |  |         [html.Attribute, 'ngPluralCase', '=0'], | 
					
						
							|  |  |  |         [html.Element, 'ng-container', 2], | 
					
						
							|  |  |  |         [html.Attribute, '[ngSwitch]', 'p.gender'], | 
					
						
							| 
									
										
										
										
											2017-01-09 13:16:46 -08:00
										 |  |  |         [html.Element, 'ng-template', 3], | 
					
						
							| 
									
										
										
										
											2018-01-22 12:23:10 -08:00
										 |  |  |         [html.Attribute, 'ngSwitchCase', 'male'], | 
					
						
							| 
									
										
										
										
											2016-07-21 13:56:58 -07:00
										 |  |  |         [html.Text, 'm', 4], | 
					
						
							|  |  |  |         [html.Text, ' ', 2], | 
					
						
							| 
									
										
										
										
											2016-06-17 11:38:24 -07:00
										 |  |  |       ]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should correctly set source code positions', () => { | 
					
						
							|  |  |  |       const nodes = expand(`{messages.length, plural,=0 {<b>bold</b>}}`).nodes; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-21 13:56:58 -07:00
										 |  |  |       const container: html.Element = <html.Element>nodes[0]; | 
					
						
							| 
									
										
										
										
											2017-03-24 09:59:58 -07:00
										 |  |  |       expect(container.sourceSpan !.start.col).toEqual(0); | 
					
						
							|  |  |  |       expect(container.sourceSpan !.end.col).toEqual(42); | 
					
						
							|  |  |  |       expect(container.startSourceSpan !.start.col).toEqual(0); | 
					
						
							|  |  |  |       expect(container.startSourceSpan !.end.col).toEqual(42); | 
					
						
							|  |  |  |       expect(container.endSourceSpan !.start.col).toEqual(0); | 
					
						
							|  |  |  |       expect(container.endSourceSpan !.end.col).toEqual(42); | 
					
						
							| 
									
										
										
										
											2016-06-17 11:38:24 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       const switchExp = container.attrs[0]; | 
					
						
							|  |  |  |       expect(switchExp.sourceSpan.start.col).toEqual(1); | 
					
						
							|  |  |  |       expect(switchExp.sourceSpan.end.col).toEqual(16); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-21 13:56:58 -07:00
										 |  |  |       const template: html.Element = <html.Element>container.children[0]; | 
					
						
							| 
									
										
										
										
											2017-03-24 09:59:58 -07:00
										 |  |  |       expect(template.sourceSpan !.start.col).toEqual(25); | 
					
						
							|  |  |  |       expect(template.sourceSpan !.end.col).toEqual(41); | 
					
						
							| 
									
										
										
										
											2016-06-17 11:38:24 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       const switchCheck = template.attrs[0]; | 
					
						
							|  |  |  |       expect(switchCheck.sourceSpan.start.col).toEqual(25); | 
					
						
							|  |  |  |       expect(switchCheck.sourceSpan.end.col).toEqual(28); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-21 13:56:58 -07:00
										 |  |  |       const b: html.Element = <html.Element>template.children[0]; | 
					
						
							| 
									
										
										
										
											2017-03-24 09:59:58 -07:00
										 |  |  |       expect(b.sourceSpan !.start.col).toEqual(29); | 
					
						
							|  |  |  |       expect(b.endSourceSpan !.end.col).toEqual(40); | 
					
						
							| 
									
										
										
										
											2016-06-17 11:38:24 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should handle other special forms', () => { | 
					
						
							| 
									
										
										
										
											2016-11-04 14:52:02 -07:00
										 |  |  |       const res = expand(`{person.gender, select, male {m} other {default}}`); | 
					
						
							| 
									
										
										
										
											2016-06-17 11:38:24 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       expect(humanizeNodes(res.nodes)).toEqual([ | 
					
						
							| 
									
										
										
										
											2016-07-21 13:56:58 -07:00
										 |  |  |         [html.Element, 'ng-container', 0], | 
					
						
							|  |  |  |         [html.Attribute, '[ngSwitch]', 'person.gender'], | 
					
						
							| 
									
										
										
										
											2017-01-09 13:16:46 -08:00
										 |  |  |         [html.Element, 'ng-template', 1], | 
					
						
							| 
									
										
										
										
											2016-11-04 14:52:02 -07:00
										 |  |  |         [html.Attribute, 'ngSwitchCase', 'male'], | 
					
						
							| 
									
										
										
										
											2016-07-21 13:56:58 -07:00
										 |  |  |         [html.Text, 'm', 2], | 
					
						
							| 
									
										
										
										
											2017-01-09 13:16:46 -08:00
										 |  |  |         [html.Element, 'ng-template', 1], | 
					
						
							| 
									
										
										
										
											2016-11-04 14:52:02 -07:00
										 |  |  |         [html.Attribute, 'ngSwitchDefault', ''], | 
					
						
							|  |  |  |         [html.Text, 'default', 2], | 
					
						
							| 
									
										
										
										
											2016-06-17 11:38:24 -07:00
										 |  |  |       ]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-12-16 15:33:16 -08:00
										 |  |  |     it('should parse an expansion form as a tag single child', () => { | 
					
						
							|  |  |  |       const res = expand(`<div><span>{a, b, =4 {c}}</span></div>`); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(humanizeNodes(res.nodes)).toEqual([ | 
					
						
							|  |  |  |         [html.Element, 'div', 0], | 
					
						
							|  |  |  |         [html.Element, 'span', 1], | 
					
						
							|  |  |  |         [html.Element, 'ng-container', 2], | 
					
						
							|  |  |  |         [html.Attribute, '[ngSwitch]', 'a'], | 
					
						
							| 
									
										
										
										
											2017-01-09 13:16:46 -08:00
										 |  |  |         [html.Element, 'ng-template', 3], | 
					
						
							| 
									
										
										
										
											2016-12-16 15:33:16 -08:00
										 |  |  |         [html.Attribute, 'ngSwitchCase', '=4'], | 
					
						
							|  |  |  |         [html.Text, 'c', 4], | 
					
						
							|  |  |  |       ]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-17 11:38:24 -07:00
										 |  |  |     describe('errors', () => { | 
					
						
							|  |  |  |       it('should error on unknown plural cases', () => { | 
					
						
							|  |  |  |         expect(humanizeErrors(expand('{n, plural, unknown {-}}').errors)).toEqual([ | 
					
						
							|  |  |  |           `Plural cases should be "=<number>" or one of zero, one, two, few, many, other`, | 
					
						
							|  |  |  |         ]); | 
					
						
							|  |  |  |       }); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function humanizeErrors(errors: ParseError[]): string[] { | 
					
						
							|  |  |  |   return errors.map(error => error.msg); | 
					
						
							|  |  |  | } |