/**
* @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 {NgLocalization} from '@angular/common';
import {ResourceLoader} from '@angular/compiler';
import {MessageBundle} from '@angular/compiler/src/i18n/message_bundle';
import {Xmb} from '@angular/compiler/src/i18n/serializers/xmb';
import {HtmlParser} from '@angular/compiler/src/ml_parser/html_parser';
import {DEFAULT_INTERPOLATION_CONFIG} from '@angular/compiler/src/ml_parser/interpolation_config';
import {Component, DebugElement, TRANSLATIONS, TRANSLATIONS_FORMAT} from '@angular/core';
import {TestBed, async} from '@angular/core/testing';
import {By} from '@angular/platform-browser/src/dom/debug/by';
import {stringifyElement} from '@angular/platform-browser/testing/browser_util';
import {expect} from '@angular/platform-browser/testing/matchers';
import {SpyResourceLoader} from '../spies';
export function main() {
describe('i18n integration spec', () => {
beforeEach(async(() => {
TestBed.configureCompiler({
providers: [
{provide: ResourceLoader, useClass: SpyResourceLoader},
{provide: NgLocalization, useClass: FrLocalization},
{provide: TRANSLATIONS, useValue: XTB},
{provide: TRANSLATIONS_FORMAT, useValue: 'xtb'},
]
});
TestBed.configureTestingModule({declarations: [I18nComponent]});
}));
it('should extract from templates', () => {
const catalog = new MessageBundle(new HtmlParser, [], {});
const serializer = new Xmb();
catalog.updateFromTemplate(HTML, '', DEFAULT_INTERPOLATION_CONFIG);
expect(catalog.write(serializer)).toContain(XMB);
});
it('should translate templates', () => {
const tb = TestBed.overrideTemplate(I18nComponent, HTML).createComponent(I18nComponent);
const cmp = tb.componentInstance;
const el = tb.debugElement;
expectHtml(el, 'h1').toBe('
attributs i18n sur les balises
');
expectHtml(el, '#i18n-1').toBe('');
expectHtml(el, '#i18n-2').toBe('');
expectHtml(el, '#i18n-3')
.toBe('avec des espaces réservés
');
expectHtml(el, '#i18n-3b')
.toBe(
'avec des espaces réservés
');
expectHtml(el, '#i18n-4')
.toBe('');
expectHtml(el, '#i18n-5').toBe('');
expectHtml(el, '#i18n-6').toBe('');
cmp.count = 0;
tb.detectChanges();
expect(el.query(By.css('#i18n-7')).nativeElement).toHaveText('zero');
expect(el.query(By.css('#i18n-14')).nativeElement).toHaveText('zero');
cmp.count = 1;
tb.detectChanges();
expect(el.query(By.css('#i18n-7')).nativeElement).toHaveText('un');
expect(el.query(By.css('#i18n-14')).nativeElement).toHaveText('un');
expect(el.query(By.css('#i18n-17')).nativeElement).toHaveText('un');
cmp.count = 2;
tb.detectChanges();
expect(el.query(By.css('#i18n-7')).nativeElement).toHaveText('deux');
expect(el.query(By.css('#i18n-14')).nativeElement).toHaveText('deux');
expect(el.query(By.css('#i18n-17')).nativeElement).toHaveText('deux');
cmp.count = 3;
tb.detectChanges();
expect(el.query(By.css('#i18n-7')).nativeElement).toHaveText('beaucoup');
expect(el.query(By.css('#i18n-14')).nativeElement).toHaveText('beaucoup');
expect(el.query(By.css('#i18n-17')).nativeElement).toHaveText('beaucoup');
cmp.sex = 'm';
cmp.sexB = 'f';
tb.detectChanges();
expect(el.query(By.css('#i18n-8')).nativeElement).toHaveText('homme');
expect(el.query(By.css('#i18n-8b')).nativeElement).toHaveText('femme');
cmp.sex = 'f';
tb.detectChanges();
expect(el.query(By.css('#i18n-8')).nativeElement).toHaveText('femme');
cmp.count = 123;
tb.detectChanges();
expectHtml(el, '#i18n-9').toEqual('count = 123
');
cmp.sex = 'f';
tb.detectChanges();
expectHtml(el, '#i18n-10').toEqual('sexe = f
');
expectHtml(el, '#i18n-11').toEqual('custom name
');
expectHtml(el, '#i18n-12')
.toEqual('Balises dans les commentaires html
');
expectHtml(el, '#i18n-13')
.toBe('');
expectHtml(el, '#i18n-15').toMatch(/ca devrait<\/b> marcher/);
expectHtml(el, '#i18n-16').toMatch(/avec un ID explicite/);
});
});
}
function expectHtml(el: DebugElement, cssSelector: string): any {
return expect(stringifyElement(el.query(By.css(cssSelector)).nativeElement));
}
@Component({
selector: 'i18n-cmp',
template: '',
})
class I18nComponent {
count: number;
sex: string;
sexB: string;
response: any = {getItemsList: (): any[] => []};
}
class FrLocalization extends NgLocalization {
getPluralCategory(value: number): string {
switch (value) {
case 0:
case 1:
return 'one';
default:
return 'other';
}
}
}
const XTB = `
attributs i18n sur les balises
imbriqué
imbriqué
avec des espaces réservés
sur des balises non traductibles
sur des balises traductibles
{VAR_PLURAL, plural, =0 {zero} =1 {un} =2 {deux} other {beaucoup}}
{VAR_SELECT, select, m {homme} f {femme}}
sexe =
dans une section traductible
Balises dans les commentaires html
ca devrait marcher
avec un ID explicite
{VAR_PLURAL, plural, =0 {zero} =1 {un} =2 {deux} other {<b>beaucoup</b>} }
{VAR_PLURAL, plural, =0 {Pas de réponse} =1 {une réponse} other {INTERPOLATION réponse} }
`;
const XMB = ` i18n attribute on tags
nested
nested
<i>with placeholders</i>
on not translatable node
on translatable node
{VAR_PLURAL, plural, =0 {zero} =1 {one} =2 {two} other {<b>many</b>} }
ICU
{VAR_SELECT, select, m {male} f {female} }
INTERPOLATION
sex = INTERPOLATION
CUSTOM_NAME
in a translatable section
<h1>Markers in html comments</h1>
<div></div>
<div>ICU</div>
it <b>should</b> work
with an explicit ID
{VAR_PLURAL, plural, =0 {zero} =1 {one} =2 {two} other {<b>many</b>} }
{VAR_PLURAL, plural, =0 {Found no results} =1 {Found one result} other {Found INTERPOLATION results} }`;
const HTML = `
i18n attribute on tags
{count, plural, =0 {zero} =1 {one} =2 {two} other {many}}
{sex, select, m {male} f {female}}
{sexB, select, m {male} f {female}}
{{ "count = " + count }}
sex = {{ sex }}
{{ "custom name" //i18n(ph="CUSTOM_NAME") }}
Markers in html comments
{count, plural, =0 {zero} =1 {one} =2 {two} other {many}}
it should work
with an explicit ID
{count, plural, =0 {zero} =1 {one} =2 {two} other {many}}
{
response.getItemsList().length,
plural,
=0 {Found no results}
=1 {Found one result}
other {Found {{response.getItemsList().length}} results}
}
`;