| 
									
										
										
										
											2018-02-14 10:54:00 -08: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
 | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import {setup} from '../aot/test_util'; | 
					
						
							|  |  |  | import {compile, expectEmit} from './mock_compile'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-23 10:37:40 -07:00
										 |  |  | const TRANSLATION_NAME_REGEXP = /^MSG_[A-Z0-9]+/; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-14 10:54:00 -08:00
										 |  |  | describe('i18n support in the view compiler', () => { | 
					
						
							|  |  |  |   const angularFiles = setup({ | 
					
						
							|  |  |  |     compileAngular: true, | 
					
						
							|  |  |  |     compileAnimations: false, | 
					
						
							|  |  |  |     compileCommon: true, | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('single text nodes', () => { | 
					
						
							|  |  |  |     it('should translate single text nodes with the i18n attribute', () => { | 
					
						
							|  |  |  |       const files = { | 
					
						
							|  |  |  |         app: { | 
					
						
							|  |  |  |           'spec.ts': `
 | 
					
						
							|  |  |  |             import {Component, NgModule} from '@angular/core'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             @Component({ | 
					
						
							|  |  |  |               selector: 'my-component', | 
					
						
							|  |  |  |               template: \`
 | 
					
						
							|  |  |  |                 <div i18n>Hello world</div> | 
					
						
							|  |  |  |                 <div>&</div> | 
					
						
							|  |  |  |                 <div i18n>farewell</div> | 
					
						
							| 
									
										
										
										
											2018-03-22 15:03:06 -07:00
										 |  |  |                 <div i18n>farewell</div> | 
					
						
							| 
									
										
										
										
											2018-02-14 10:54:00 -08:00
										 |  |  |               \`
 | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |             export class MyComponent {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             @NgModule({declarations: [MyComponent]}) | 
					
						
							|  |  |  |             export class MyModule {} | 
					
						
							|  |  |  |         `
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const template = `
 | 
					
						
							| 
									
										
										
										
											2018-03-22 15:03:06 -07:00
										 |  |  |       const $msg_1$ = goog.getMsg('Hello world'); | 
					
						
							|  |  |  |       const $msg_2$ = goog.getMsg('farewell'); | 
					
						
							|  |  |  |       … | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:20 -07:00
										 |  |  |       template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { | 
					
						
							|  |  |  |         if (rf & 1) { | 
					
						
							| 
									
										
										
										
											2018-02-14 10:54:00 -08:00
										 |  |  |           … | 
					
						
							| 
									
										
										
										
											2018-03-22 15:03:06 -07:00
										 |  |  |           $r3$.ɵT(1, $msg_1$); | 
					
						
							| 
									
										
										
										
											2018-02-14 10:54:00 -08:00
										 |  |  |           … | 
					
						
							|  |  |  |           $r3$.ɵT(3,'&'); | 
					
						
							|  |  |  |           … | 
					
						
							| 
									
										
										
										
											2018-03-22 15:03:06 -07:00
										 |  |  |           $r3$.ɵT(5, $msg_2$); | 
					
						
							|  |  |  |           … | 
					
						
							|  |  |  |           $r3$.ɵT(7, $msg_2$); | 
					
						
							| 
									
										
										
										
											2018-02-14 10:54:00 -08:00
										 |  |  |           … | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     `;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const result = compile(files, angularFiles); | 
					
						
							| 
									
										
										
										
											2018-03-23 10:37:40 -07:00
										 |  |  |       expectEmit(result.source, template, 'Incorrect template', { | 
					
						
							|  |  |  |         '$msg_1$': TRANSLATION_NAME_REGEXP, | 
					
						
							|  |  |  |         '$msg_2$': TRANSLATION_NAME_REGEXP, | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-02-14 10:54:00 -08:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should add the meaning and description as JsDoc comments', () => { | 
					
						
							|  |  |  |       const files = { | 
					
						
							|  |  |  |         app: { | 
					
						
							|  |  |  |           'spec.ts': `
 | 
					
						
							|  |  |  |             import {Component, NgModule} from '@angular/core'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             @Component({ | 
					
						
							|  |  |  |               selector: 'my-component', | 
					
						
							|  |  |  |               template: \`
 | 
					
						
							|  |  |  |                 <div i18n="meaning|desc@@id" i18n-title="desc" title="introduction">Hello world</div> | 
					
						
							|  |  |  |               \`
 | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |             export class MyComponent {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             @NgModule({declarations: [MyComponent]}) | 
					
						
							|  |  |  |             export class MyModule {} | 
					
						
							|  |  |  |         `
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const template = `
 | 
					
						
							| 
									
										
										
										
											2018-03-22 15:03:06 -07:00
										 |  |  |       /** | 
					
						
							|  |  |  |        * @desc desc | 
					
						
							|  |  |  |        */ | 
					
						
							|  |  |  |       const $msg_1$ = goog.getMsg('introduction'); | 
					
						
							| 
									
										
										
										
											2018-05-10 15:58:27 -07:00
										 |  |  |       const $c1$ = ['title', $msg_1$]; | 
					
						
							| 
									
										
										
										
											2018-02-14 10:54:00 -08:00
										 |  |  |       … | 
					
						
							| 
									
										
										
										
											2018-03-22 15:03:06 -07:00
										 |  |  |       /** | 
					
						
							|  |  |  |        * @desc desc | 
					
						
							|  |  |  |        * @meaning meaning | 
					
						
							|  |  |  |        */ | 
					
						
							|  |  |  |       const $msg_2$ = goog.getMsg('Hello world'); | 
					
						
							|  |  |  |       … | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:20 -07:00
										 |  |  |       template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { | 
					
						
							|  |  |  |         if (rf & 1) { | 
					
						
							| 
									
										
										
										
											2018-05-10 15:58:27 -07:00
										 |  |  |           $r3$.ɵE(0, 'div', $c1$); | 
					
						
							| 
									
										
										
										
											2018-03-22 15:03:06 -07:00
										 |  |  |           $r3$.ɵT(1, $msg_2$); | 
					
						
							| 
									
										
										
										
											2018-02-14 10:54:00 -08:00
										 |  |  |           $r3$.ɵe(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-03-22 15:03:06 -07:00
										 |  |  |       `;
 | 
					
						
							| 
									
										
										
										
											2018-02-14 10:54:00 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       const result = compile(files, angularFiles); | 
					
						
							| 
									
										
										
										
											2018-03-23 10:37:40 -07:00
										 |  |  |       expectEmit(result.source, template, 'Incorrect template', { | 
					
						
							|  |  |  |         '$msg_1$': TRANSLATION_NAME_REGEXP, | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-02-14 10:54:00 -08:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('static attributes', () => { | 
					
						
							|  |  |  |     it('should translate static attributes', () => { | 
					
						
							|  |  |  |       const files = { | 
					
						
							|  |  |  |         app: { | 
					
						
							|  |  |  |           'spec.ts': `
 | 
					
						
							|  |  |  |             import {Component, NgModule} from '@angular/core'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             @Component({ | 
					
						
							|  |  |  |               selector: 'my-component', | 
					
						
							|  |  |  |               template: \`
 | 
					
						
							|  |  |  |                 <div i18n id="static" i18n-title="m|d" title="introduction"></div> | 
					
						
							|  |  |  |               \`
 | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |             export class MyComponent {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             @NgModule({declarations: [MyComponent]}) | 
					
						
							|  |  |  |             export class MyModule {} | 
					
						
							|  |  |  |         `
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const template = `
 | 
					
						
							| 
									
										
										
										
											2018-03-22 15:03:06 -07:00
										 |  |  |       /** | 
					
						
							|  |  |  |        * @desc d | 
					
						
							|  |  |  |        * @meaning m | 
					
						
							|  |  |  |        */ | 
					
						
							|  |  |  |       const $msg_1$ = goog.getMsg('introduction'); | 
					
						
							| 
									
										
										
										
											2018-05-10 15:58:27 -07:00
										 |  |  |       const $c1$ = ['id', 'static', 'title', $msg_1$]; | 
					
						
							| 
									
										
										
										
											2018-02-14 10:54:00 -08:00
										 |  |  |       … | 
					
						
							| 
									
										
										
										
											2018-04-10 20:57:20 -07:00
										 |  |  |       template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { | 
					
						
							|  |  |  |         if (rf & 1) { | 
					
						
							| 
									
										
										
										
											2018-06-08 10:48:27 -07:00
										 |  |  |           $r3$.ɵEe(0, 'div', $c1$); | 
					
						
							| 
									
										
										
										
											2018-02-14 10:54:00 -08:00
										 |  |  |         } | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     `;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const result = compile(files, angularFiles); | 
					
						
							| 
									
										
										
										
											2018-03-23 10:37:40 -07:00
										 |  |  |       expectEmit(result.source, template, 'Incorrect template', { | 
					
						
							|  |  |  |         '$msg_1$': TRANSLATION_NAME_REGEXP, | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-02-14 10:54:00 -08:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // TODO(vicb): this feature is not supported yet
 | 
					
						
							|  |  |  |   xdescribe('nested nodes', () => { | 
					
						
							|  |  |  |     it('should generate the placeholders maps', () => { | 
					
						
							|  |  |  |       const files = { | 
					
						
							|  |  |  |         app: { | 
					
						
							|  |  |  |           'spec.ts': `
 | 
					
						
							|  |  |  |             import {Component, NgModule} from '@angular/core'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             @Component({ | 
					
						
							|  |  |  |               selector: 'my-component', | 
					
						
							|  |  |  |               template: \`
 | 
					
						
							|  |  |  |                 <div i18n>Hello <b>{{name}}<i>!</i><i>!</i></b></div> | 
					
						
							|  |  |  |                 <div>Other</div> | 
					
						
							|  |  |  |                 <div i18n>2nd</div> | 
					
						
							|  |  |  |                 <div i18n><i>3rd</i></div> | 
					
						
							|  |  |  |               \`
 | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |             export class MyComponent {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             @NgModule({declarations: [MyComponent]}) | 
					
						
							|  |  |  |             export class MyModule {} | 
					
						
							|  |  |  |         `
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const template = `
 | 
					
						
							|  |  |  |       const $r1$ = {'b':[2], 'i':[4, 6]}; | 
					
						
							|  |  |  |       const $r2$ = {'i':[13]}; | 
					
						
							|  |  |  |     `;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const result = compile(files, angularFiles); | 
					
						
							|  |  |  |       expectEmit(result.source, template, 'Incorrect template'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('errors', () => { | 
					
						
							|  |  |  |     it('should throw on nested i18n sections', () => { | 
					
						
							|  |  |  |       const files = { | 
					
						
							|  |  |  |         app: { | 
					
						
							|  |  |  |           'spec.ts': `
 | 
					
						
							|  |  |  |             import {Component, NgModule} from '@angular/core'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             @Component({ | 
					
						
							|  |  |  |               selector: 'my-component', | 
					
						
							|  |  |  |               template: \`
 | 
					
						
							|  |  |  |                 <div i18n><div i18n></div></div> | 
					
						
							|  |  |  |               \`
 | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |             export class MyComponent {} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             @NgModule({declarations: [MyComponent]}) | 
					
						
							|  |  |  |             export class MyModule {} | 
					
						
							|  |  |  |         `
 | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |       }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       expect(() => compile(files, angularFiles)) | 
					
						
							|  |  |  |           .toThrowError( | 
					
						
							|  |  |  |               'Could not mark an element as translatable inside of a translatable section'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }); |