/**
* @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 {escapeRegExp} from '@angular/core/src/facade/lang';
import {MessageBundle} from '../../../src/i18n/message_bundle';
import {Xtb} from '../../../src/i18n/serializers/xtb';
import {HtmlParser} from '../../../src/ml_parser/html_parser';
import {DEFAULT_INTERPOLATION_CONFIG} from '../../../src/ml_parser/interpolation_config';
import {serializeNodes} from '../../ml_parser/ast_serializer_spec';
export function main(): void {
describe('XTB serializer', () => {
let serializer: Xtb;
let htmlParser: HtmlParser;
function loadAsText(template: string, xtb: string): {[id: string]: string} {
const messageBundle = new MessageBundle(htmlParser, [], {});
messageBundle.updateFromTemplate(template, 'url', DEFAULT_INTERPOLATION_CONFIG);
const asAst = serializer.load(xtb, 'url', messageBundle);
const asText: {[id: string]: string} = {};
Object.keys(asAst).forEach(id => { asText[id] = serializeNodes(asAst[id]).join(''); });
return asText;
}
beforeEach(() => {
htmlParser = new HtmlParser();
serializer = new Xtb(htmlParser, DEFAULT_INTERPOLATION_CONFIG);
});
describe('load', () => {
it('should load XTB files with a doctype', () => {
const HTML = `
bar
`;
const XTB = `
]>
rab
`;
expect(loadAsText(HTML, XTB)).toEqual({'8841459487341224498': 'rab'});
});
it('should load XTB files without placeholders', () => {
const HTML = `bar
`;
const XTB = `
rab
`;
expect(loadAsText(HTML, XTB)).toEqual({'8841459487341224498': 'rab'});
});
it('should load XTB files with placeholders', () => {
const HTML = ``;
const XTB = `
rab
`;
expect(loadAsText(HTML, XTB)).toEqual({'8877975308926375834': 'rab
'});
});
it('should replace ICU placeholders with their translations', () => {
const HTML = `-{ count, plural, =0 {
bar
}}-
`;
const XTB = `
**
{ count, plural, =1 {rab}}
`;
expect(loadAsText(HTML, XTB)).toEqual({
'1430521728694081603': `*{ count, plural, =1 {rab
}}*`,
'4004755025589356097': `{ count, plural, =1 {rab
}}`,
});
});
it('should load complex XTB files', () => {
const HTML = `
foo bar {{ a + b }}
{ count, plural, =0 {
bar
}}
foo
{ count, plural, =0 {{ sex, select, other {
bar
}} }}
`;
const XTB = `
rab oof
{ count, plural, =1 {rab}}
oof
{ count, plural, =1 {{ sex, gender, male {rab}} }}
`;
expect(loadAsText(HTML, XTB)).toEqual({
'8281795707202401639': `{{ a + b }}rab oof`,
'4004755025589356097': `{ count, plural, =1 {rab
}}`,
'130772889486467622': `oof`,
'4244993204427636474': `{ count, plural, =1 {{ sex, gender, male {rab
}} }}`,
});
});
});
describe('errors', () => {
it('should throw on nested ', () => {
const XTB =
'';
expect(() => {
loadAsText('', XTB);
}).toThrowError(/ elements can not be nested/);
});
it('should throw when a has no id attribute', () => {
const XTB = `
`;
expect(() => {
loadAsText('', XTB);
}).toThrowError(/ misses the "id" attribute/);
});
it('should throw when a placeholder has no name attribute', () => {
const HTML = 'give me a message
';
const XTB = `
`;
expect(() => { loadAsText(HTML, XTB); }).toThrowError(/ misses the "name" attribute/);
});
it('should throw when a placeholder is not present in the source message', () => {
const HTML = `bar
`;
const XTB = `
`;
expect(() => {
loadAsText(HTML, XTB);
}).toThrowError(/The placeholder "UNKNOWN" does not exists in the source message/);
});
});
it('should throw when the translation results in invalid html', () => {
const HTML = ``;
const XTB = `
rab
`;
expect(() => {
loadAsText(HTML, XTB);
}).toThrowError(/xtb parse errors:\nUnexpected closing tag "p"/);
});
it('should throw on unknown tags', () => {
const XTB = ``;
expect(() => {
loadAsText('', XTB);
}).toThrowError(new RegExp(escapeRegExp(`Unexpected tag ("[ERROR ->]")`)));
});
it('should throw when trying to save an xtb file',
() => { expect(() => { serializer.write([]); }).toThrowError(/Unsupported/); });
});
}