| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  | import { | 
					
						
							|  |  |  |   beforeEach, | 
					
						
							|  |  |  |   ddescribe, | 
					
						
							|  |  |  |   describe, | 
					
						
							|  |  |  |   expect, | 
					
						
							|  |  |  |   iit, | 
					
						
							|  |  |  |   inject, | 
					
						
							|  |  |  |   it, | 
					
						
							|  |  |  |   xdescribe, | 
					
						
							|  |  |  |   xit | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | } from '@angular/core/testing/testing_internal'; | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | import {I18nHtmlParser} from '@angular/compiler/src/i18n/i18n_html_parser'; | 
					
						
							|  |  |  | import {Message, id} from '@angular/compiler/src/i18n/message'; | 
					
						
							|  |  |  | import {Parser} from '@angular/compiler/src/expression_parser/parser'; | 
					
						
							|  |  |  | import {Lexer} from '@angular/compiler/src/expression_parser/lexer'; | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | import {StringMapWrapper} from '../../src/facade/collection'; | 
					
						
							|  |  |  | import {HtmlParser, HtmlParseTreeResult} from '@angular/compiler/src/html_parser'; | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  | import { | 
					
						
							|  |  |  |   HtmlAst, | 
					
						
							|  |  |  |   HtmlAstVisitor, | 
					
						
							|  |  |  |   HtmlElementAst, | 
					
						
							|  |  |  |   HtmlAttrAst, | 
					
						
							|  |  |  |   HtmlTextAst, | 
					
						
							|  |  |  |   HtmlCommentAst, | 
					
						
							|  |  |  |   htmlVisitAll | 
					
						
							| 
									
										
										
										
											2016-04-28 17:50:03 -07:00
										 |  |  | } from '@angular/compiler/src/html_ast'; | 
					
						
							|  |  |  | import {serializeXmb, deserializeXmb} from '@angular/compiler/src/i18n/xmb_serializer'; | 
					
						
							|  |  |  | import {ParseError, ParseLocation} from '@angular/compiler/src/parse_util'; | 
					
						
							|  |  |  | import {humanizeDom} from '@angular/compiler/test/html_ast_spec_utils'; | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | export function main() { | 
					
						
							|  |  |  |   describe('I18nHtmlParser', () => { | 
					
						
							|  |  |  |     function parse(template: string, messages: {[key: string]: string}): HtmlParseTreeResult { | 
					
						
							|  |  |  |       var parser = new Parser(new Lexer()); | 
					
						
							|  |  |  |       let htmlParser = new HtmlParser(); | 
					
						
							| 
									
										
										
										
											2016-03-27 18:31:02 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |       let msgs = ''; | 
					
						
							|  |  |  |       StringMapWrapper.forEach(messages, (v, k) => msgs += `<msg id="${k}">${v}</msg>`); | 
					
						
							|  |  |  |       let res = deserializeXmb(`<message-bundle>${msgs}</message-bundle>`, 'someUrl'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       return new I18nHtmlParser(htmlParser, parser, res.content, res.messages) | 
					
						
							| 
									
										
										
										
											2016-04-12 11:46:49 -07:00
										 |  |  |           .parse(template, "someurl", true); | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |     it("should delegate to the provided parser when no i18n", () => { | 
					
						
							|  |  |  |       expect(humanizeDom(parse('<div>a</div>', {}))) | 
					
						
							|  |  |  |           .toEqual([[HtmlElementAst, 'div', 0], [HtmlTextAst, 'a', 1]]); | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |     it("should replace attributes", () => { | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |       let translations: {[key: string]: string} = {}; | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       translations[id(new Message("some message", "meaning", null))] = "another message"; | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       expect(humanizeDom(parse("<div value='some message' i18n-value='meaning|comment'></div>", | 
					
						
							|  |  |  |                                translations))) | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |           .toEqual([[HtmlElementAst, 'div', 0], [HtmlAttrAst, 'value', 'another message']]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |     it("should replace elements with the i18n attr", () => { | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |       let translations: {[key: string]: string} = {}; | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       translations[id(new Message("message", "meaning", null))] = "another message"; | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       expect(humanizeDom(parse("<div i18n='meaning|desc'>message</div>", translations))) | 
					
						
							|  |  |  |           .toEqual([[HtmlElementAst, 'div', 0], [HtmlTextAst, 'another message', 1]]); | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |     it("should handle interpolation", () => { | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |       let translations: {[key: string]: string} = {}; | 
					
						
							|  |  |  |       translations[id(new Message('<ph name="0"/> and <ph name="1"/>', null, null))] = | 
					
						
							|  |  |  |           '<ph name="1"/> or <ph name="0"/>'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       expect(humanizeDom(parse("<div value='{{a}} and {{b}}' i18n-value></div>", translations))) | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |           .toEqual([[HtmlElementAst, 'div', 0], [HtmlAttrAst, 'value', '{{b}} or {{a}}']]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-14 16:16:22 -07:00
										 |  |  |     it('should handle interpolation with custom placeholder names', () => { | 
					
						
							|  |  |  |       let translations: {[key: string]: string} = {}; | 
					
						
							|  |  |  |       translations[id(new Message('<ph name="FIRST"/> and <ph name="SECOND"/>', null, null))] = | 
					
						
							|  |  |  |           '<ph name="SECOND"/> or <ph name="FIRST"/>'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect( | 
					
						
							|  |  |  |           humanizeDom(parse( | 
					
						
							|  |  |  |               `<div value='{{a //i18n(ph="FIRST")}} and {{b //i18n(ph="SECOND")}}' i18n-value></div>`, | 
					
						
							|  |  |  |               translations))) | 
					
						
							|  |  |  |           .toEqual([ | 
					
						
							|  |  |  |             [HtmlElementAst, 'div', 0], | 
					
						
							|  |  |  |             [HtmlAttrAst, 'value', '{{b //i18n(ph="SECOND")}} or {{a //i18n(ph="FIRST")}}'] | 
					
						
							|  |  |  |           ]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should handle interpolation with duplicate placeholder names', () => { | 
					
						
							|  |  |  |       let translations: {[key: string]: string} = {}; | 
					
						
							|  |  |  |       translations[id(new Message('<ph name="FIRST"/> and <ph name="FIRST_1"/>', null, null))] = | 
					
						
							|  |  |  |           '<ph name="FIRST_1"/> or <ph name="FIRST"/>'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect( | 
					
						
							|  |  |  |           humanizeDom(parse( | 
					
						
							|  |  |  |               `<div value='{{a //i18n(ph="FIRST")}} and {{b //i18n(ph="FIRST")}}' i18n-value></div>`, | 
					
						
							|  |  |  |               translations))) | 
					
						
							|  |  |  |           .toEqual([ | 
					
						
							|  |  |  |             [HtmlElementAst, 'div', 0], | 
					
						
							|  |  |  |             [HtmlAttrAst, 'value', '{{b //i18n(ph="FIRST")}} or {{a //i18n(ph="FIRST")}}'] | 
					
						
							|  |  |  |           ]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |     it("should handle nested html", () => { | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |       let translations: {[key: string]: string} = {}; | 
					
						
							|  |  |  |       translations[id(new Message('<ph name="e0">a</ph><ph name="e2">b</ph>', null, null))] = | 
					
						
							|  |  |  |           '<ph name="e2">B</ph><ph name="e0">A</ph>'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       expect(humanizeDom(parse('<div i18n><a>a</a><b>b</b></div>', translations))) | 
					
						
							|  |  |  |           .toEqual([ | 
					
						
							|  |  |  |             [HtmlElementAst, 'div', 0], | 
					
						
							|  |  |  |             [HtmlElementAst, 'b', 1], | 
					
						
							|  |  |  |             [HtmlTextAst, 'B', 2], | 
					
						
							|  |  |  |             [HtmlElementAst, 'a', 1], | 
					
						
							|  |  |  |             [HtmlTextAst, 'A', 2], | 
					
						
							|  |  |  |           ]); | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |     it("should support interpolation", () => { | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |       let translations: {[key: string]: string} = {}; | 
					
						
							|  |  |  |       translations[id(new Message( | 
					
						
							|  |  |  |           '<ph name="e0">a</ph><ph name="e2"><ph name="t3">b<ph name="0"/></ph></ph>', null, | 
					
						
							|  |  |  |           null))] = '<ph name="e2"><ph name="t3"><ph name="0"/>B</ph></ph><ph name="e0">A</ph>'; | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       expect(humanizeDom(parse('<div i18n><a>a</a><b>b{{i}}</b></div>', translations))) | 
					
						
							|  |  |  |           .toEqual([ | 
					
						
							|  |  |  |             [HtmlElementAst, 'div', 0], | 
					
						
							|  |  |  |             [HtmlElementAst, 'b', 1], | 
					
						
							|  |  |  |             [HtmlTextAst, '{{i}}B', 2], | 
					
						
							|  |  |  |             [HtmlElementAst, 'a', 1], | 
					
						
							|  |  |  |             [HtmlTextAst, 'A', 2], | 
					
						
							|  |  |  |           ]); | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |     it("should i18n attributes of placeholder elements", () => { | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |       let translations: {[key: string]: string} = {}; | 
					
						
							|  |  |  |       translations[id(new Message('<ph name="e0">a</ph>', null, null))] = '<ph name="e0">A</ph>'; | 
					
						
							|  |  |  |       translations[id(new Message('b', null, null))] = 'B'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(humanizeDom(parse('<div i18n><a value="b" i18n-value>a</a></div>', translations))) | 
					
						
							|  |  |  |           .toEqual([ | 
					
						
							|  |  |  |             [HtmlElementAst, 'div', 0], | 
					
						
							|  |  |  |             [HtmlElementAst, 'a', 1], | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |             [HtmlAttrAst, 'value', "B"], | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |             [HtmlTextAst, 'A', 2], | 
					
						
							|  |  |  |           ]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |     it("should preserve non-i18n attributes", () => { | 
					
						
							| 
									
										
										
										
											2016-03-27 18:31:02 -07:00
										 |  |  |       let translations: {[key: string]: string} = {}; | 
					
						
							|  |  |  |       translations[id(new Message('message', null, null))] = 'another message'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       expect(humanizeDom(parse('<div i18n value="b">message</div>', translations))) | 
					
						
							|  |  |  |           .toEqual([ | 
					
						
							|  |  |  |             [HtmlElementAst, 'div', 0], | 
					
						
							|  |  |  |             [HtmlAttrAst, 'value', "b"], | 
					
						
							|  |  |  |             [HtmlTextAst, 'another message', 1] | 
					
						
							|  |  |  |           ]); | 
					
						
							| 
									
										
										
										
											2016-03-27 18:31:02 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |     it('should extract from partitions', () => { | 
					
						
							|  |  |  |       let translations: {[key: string]: string} = {}; | 
					
						
							|  |  |  |       translations[id(new Message('message1', 'meaning1', null))] = 'another message1'; | 
					
						
							|  |  |  |       translations[id(new Message('message2', 'meaning2', null))] = 'another message2'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       let res = parse(`<!-- i18n: meaning1|desc1 -->message1<!-- /i18n --><!-- i18n: meaning2|desc2 -->message2<!-- /i18n -->`, translations); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       expect(humanizeDom(res)) | 
					
						
							|  |  |  |           .toEqual([ | 
					
						
							|  |  |  |             [HtmlTextAst, 'another message1', 0], | 
					
						
							|  |  |  |             [HtmlTextAst, 'another message2', 0], | 
					
						
							|  |  |  |           ]); | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |     it("should preserve original positions", () => { | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |       let translations: {[key: string]: string} = {}; | 
					
						
							|  |  |  |       translations[id(new Message('<ph name="e0">a</ph><ph name="e2">b</ph>', null, null))] = | 
					
						
							|  |  |  |           '<ph name="e2">B</ph><ph name="e0">A</ph>'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       let res = | 
					
						
							|  |  |  |           (<any>parse('<div i18n><a>a</a><b>b</b></div>', translations).rootNodes[0]).children; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(res[0].sourceSpan.start.offset).toEqual(18); | 
					
						
							|  |  |  |       expect(res[1].sourceSpan.start.offset).toEqual(10); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-13 16:01:25 -07:00
										 |  |  |     it("should handle the plural expansion form", () => { | 
					
						
							| 
									
										
										
										
											2016-04-12 11:46:49 -07:00
										 |  |  |       let translations: {[key: string]: string} = {}; | 
					
						
							|  |  |  |       translations[id(new Message('zero<ph name="e1">bold</ph>', "plural_0", null))] = | 
					
						
							|  |  |  |           'ZERO<ph name="e1">BOLD</ph>'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       let res = parse(`{messages.length, plural,=0 {zero<b>bold</b>}}`, translations); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(humanizeDom(res)) | 
					
						
							|  |  |  |           .toEqual([ | 
					
						
							|  |  |  |             [HtmlElementAst, 'ul', 0], | 
					
						
							|  |  |  |             [HtmlAttrAst, '[ngPlural]', 'messages.length'], | 
					
						
							|  |  |  |             [HtmlElementAst, 'template', 1], | 
					
						
							| 
									
										
										
										
											2016-04-13 16:01:25 -07:00
										 |  |  |             [HtmlAttrAst, 'ngPluralCase', '0'], | 
					
						
							| 
									
										
										
										
											2016-04-12 11:46:49 -07:00
										 |  |  |             [HtmlElementAst, 'li', 2], | 
					
						
							|  |  |  |             [HtmlTextAst, 'ZERO', 3], | 
					
						
							|  |  |  |             [HtmlElementAst, 'b', 3], | 
					
						
							|  |  |  |             [HtmlTextAst, 'BOLD', 4] | 
					
						
							|  |  |  |           ]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-13 16:01:25 -07:00
										 |  |  |     it("should handle nested expansion forms", () => { | 
					
						
							|  |  |  |       let translations: {[key: string]: string} = {}; | 
					
						
							|  |  |  |       translations[id(new Message('m', "gender_m", null))] = 'M'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       let res = parse(`{messages.length, plural, =0 { {p.gender, gender, =m {m}} }}`, translations); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(humanizeDom(res)) | 
					
						
							|  |  |  |           .toEqual([ | 
					
						
							|  |  |  |             [HtmlElementAst, 'ul', 0], | 
					
						
							|  |  |  |             [HtmlAttrAst, '[ngPlural]', 'messages.length'], | 
					
						
							|  |  |  |             [HtmlElementAst, 'template', 1], | 
					
						
							|  |  |  |             [HtmlAttrAst, 'ngPluralCase', '0'], | 
					
						
							|  |  |  |             [HtmlElementAst, 'li', 2], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             [HtmlElementAst, 'ul', 3], | 
					
						
							|  |  |  |             [HtmlAttrAst, '[ngSwitch]', 'p.gender'], | 
					
						
							|  |  |  |             [HtmlElementAst, 'template', 4], | 
					
						
							|  |  |  |             [HtmlAttrAst, 'ngSwitchWhen', 'm'], | 
					
						
							|  |  |  |             [HtmlElementAst, 'li', 5], | 
					
						
							|  |  |  |             [HtmlTextAst, 'M', 6], | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             [HtmlTextAst, ' ', 3] | 
					
						
							|  |  |  |           ]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 11:46:49 -07:00
										 |  |  |     it("should correctly set source code positions", () => { | 
					
						
							|  |  |  |       let translations: {[key: string]: string} = {}; | 
					
						
							|  |  |  |       translations[id(new Message('<ph name="e0">bold</ph>', "plural_0", null))] = | 
					
						
							|  |  |  |           '<ph name="e0">BOLD</ph>'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       let nodes = parse(`{messages.length, plural,=0 {<b>bold</b>}}`, translations).rootNodes; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       let ul: HtmlElementAst = <HtmlElementAst>nodes[0]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(ul.sourceSpan.start.col).toEqual(0); | 
					
						
							|  |  |  |       expect(ul.sourceSpan.end.col).toEqual(42); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(ul.startSourceSpan.start.col).toEqual(0); | 
					
						
							|  |  |  |       expect(ul.startSourceSpan.end.col).toEqual(42); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(ul.endSourceSpan.start.col).toEqual(0); | 
					
						
							|  |  |  |       expect(ul.endSourceSpan.end.col).toEqual(42); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       let switchExp = ul.attrs[0]; | 
					
						
							|  |  |  |       expect(switchExp.sourceSpan.start.col).toEqual(1); | 
					
						
							|  |  |  |       expect(switchExp.sourceSpan.end.col).toEqual(16); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       let template: HtmlElementAst = <HtmlElementAst>ul.children[0]; | 
					
						
							|  |  |  |       expect(template.sourceSpan.start.col).toEqual(26); | 
					
						
							|  |  |  |       expect(template.sourceSpan.end.col).toEqual(41); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       let switchCheck = template.attrs[0]; | 
					
						
							|  |  |  |       expect(switchCheck.sourceSpan.start.col).toEqual(26); | 
					
						
							|  |  |  |       expect(switchCheck.sourceSpan.end.col).toEqual(28); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       let li: HtmlElementAst = <HtmlElementAst>template.children[0]; | 
					
						
							|  |  |  |       expect(li.sourceSpan.start.col).toEqual(26); | 
					
						
							|  |  |  |       expect(li.sourceSpan.end.col).toEqual(41); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       let b: HtmlElementAst = <HtmlElementAst>li.children[0]; | 
					
						
							|  |  |  |       expect(b.sourceSpan.start.col).toEqual(29); | 
					
						
							|  |  |  |       expect(b.sourceSpan.end.col).toEqual(32); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it("should handle other special forms", () => { | 
					
						
							|  |  |  |       let translations: {[key: string]: string} = {}; | 
					
						
							|  |  |  |       translations[id(new Message('m', "gender_male", null))] = 'M'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       let res = parse(`{person.gender, gender,=male {m}}`, translations); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(humanizeDom(res)) | 
					
						
							|  |  |  |           .toEqual([ | 
					
						
							|  |  |  |             [HtmlElementAst, 'ul', 0], | 
					
						
							|  |  |  |             [HtmlAttrAst, '[ngSwitch]', 'person.gender'], | 
					
						
							|  |  |  |             [HtmlElementAst, 'template', 1], | 
					
						
							| 
									
										
										
										
											2016-04-13 16:01:25 -07:00
										 |  |  |             [HtmlAttrAst, 'ngSwitchWhen', 'male'], | 
					
						
							| 
									
										
										
										
											2016-04-12 11:46:49 -07:00
										 |  |  |             [HtmlElementAst, 'li', 2], | 
					
						
							|  |  |  |             [HtmlTextAst, 'M', 3], | 
					
						
							|  |  |  |           ]); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |     describe("errors", () => { | 
					
						
							|  |  |  |       it("should error when giving an invalid template", () => { | 
					
						
							|  |  |  |         expect(humanizeErrors(parse("<a>a</b>", {}).errors)) | 
					
						
							|  |  |  |             .toEqual(['Unexpected closing tag "b"']); | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       it("should error when no matching message (attr)", () => { | 
					
						
							|  |  |  |         let mid = id(new Message("some message", null, null)); | 
					
						
							|  |  |  |         expect(humanizeErrors(parse("<div value='some message' i18n-value></div>", {}).errors)) | 
					
						
							| 
									
										
										
										
											2016-04-13 16:01:25 -07:00
										 |  |  |             .toEqual([`Cannot find message for id '${mid}', content 'some message'.`]); | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       it("should error when no matching message (text)", () => { | 
					
						
							|  |  |  |         let mid = id(new Message("some message", null, null)); | 
					
						
							|  |  |  |         expect(humanizeErrors(parse("<div i18n>some message</div>", {}).errors)) | 
					
						
							| 
									
										
										
										
											2016-04-13 16:01:25 -07:00
										 |  |  |             .toEqual([`Cannot find message for id '${mid}', content 'some message'.`]); | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       it("should error when a non-placeholder element appears in translation", () => { | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |         let translations: {[key: string]: string} = {}; | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         translations[id(new Message("some message", null, null))] = "<a>a</a>"; | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeErrors(parse("<div i18n>some message</div>", translations).errors)) | 
					
						
							|  |  |  |             .toEqual([`Unexpected tag "a". Only "ph" tags are allowed.`]); | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       it("should error when a placeholder element does not have the name attribute", () => { | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |         let translations: {[key: string]: string} = {}; | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         translations[id(new Message("some message", null, null))] = "<ph>a</ph>"; | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |         expect(humanizeErrors(parse("<div i18n>some message</div>", translations).errors)) | 
					
						
							|  |  |  |             .toEqual([`Missing "name" attribute.`]); | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |       it("should error when the translation refers to an invalid expression", () => { | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |         let translations: {[key: string]: string} = {}; | 
					
						
							|  |  |  |         translations[id(new Message('hi <ph name="0"/>', null, null))] = 'hi <ph name="99"/>'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect( | 
					
						
							| 
									
										
										
										
											2016-04-12 09:40:37 -07:00
										 |  |  |             humanizeErrors(parse("<div value='hi {{a}}' i18n-value></div>", translations).errors)) | 
					
						
							| 
									
										
										
										
											2016-04-14 16:16:22 -07:00
										 |  |  |             .toEqual(["Invalid interpolation name '99'"]); | 
					
						
							| 
									
										
										
										
											2016-03-23 13:45:04 -07:00
										 |  |  |       }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function humanizeErrors(errors: ParseError[]): string[] { | 
					
						
							|  |  |  |   return errors.map(error => error.msg); | 
					
						
							| 
									
										
										
										
											2016-04-14 16:16:22 -07:00
										 |  |  | } |