import {AsyncTestCompleter, beforeEach, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from 'angular2/testing_internal';
import {I18nHtmlParser} from 'angular2/src/i18n/i18n_html_parser';
import {Message, id} from 'angular2/src/i18n/message';
import {Parser} from 'angular2/src/core/change_detection/parser/parser';
import {Lexer} from 'angular2/src/core/change_detection/parser/lexer';
import {StringMapWrapper} from 'angular2/src/facade/collection';
import {HtmlParser, HtmlParseTreeResult} from 'angular2/src/compiler/html_parser';
import {HtmlAst, HtmlAstVisitor, HtmlElementAst, HtmlAttrAst, HtmlTextAst, HtmlCommentAst, htmlVisitAll} from 'angular2/src/compiler/html_ast';
import {serializeXmb, deserializeXmb} from 'angular2/src/i18n/xmb_serializer';
import {ParseError, ParseLocation} from 'angular2/src/compiler/parse_util';
import {humanizeDom} from '../../test/compiler/html_ast_spec_utils';
export function main() {
describe('I18nHtmlParser', () => {
function parse(template: string, messages: {[key: string]: string}): HtmlParseTreeResult {
var parser = new Parser(new Lexer());
let htmlParser = new HtmlParser();
let msgs = '';
StringMapWrapper.forEach(messages, (v, k) => msgs += `${v}`);
let res = deserializeXmb(`${msgs}`, 'someUrl');
return new I18nHtmlParser(htmlParser, parser, res.content, res.messages)
.parse(template, 'someurl');
}
it('should delegate to the provided parser when no i18n', () => {
expect(humanizeDom(parse('
a
', {}))).toEqual([
[HtmlElementAst, 'div', 0], [HtmlTextAst, 'a', 1]
]);
});
it('should replace attributes', () => {
let translations: {[key: string]: string} = {};
translations[id(new Message('some message', 'meaning', null))] = 'another message';
expect(
humanizeDom(parse(
'', translations)))
.toEqual([[HtmlElementAst, 'div', 0], [HtmlAttrAst, 'value', 'another message']]);
});
it('should replace elements with the i18n attr', () => {
let translations: {[key: string]: string} = {};
translations[id(new Message('message', 'meaning', null))] = 'another message';
expect(humanizeDom(parse('message
', translations))).toEqual([
[HtmlElementAst, 'div', 0], [HtmlTextAst, 'another message', 1]
]);
});
it('should handle interpolation', () => {
let translations: {[key: string]: string} = {};
translations[id(new Message(' and ', null, null))] =
' or ';
expect(humanizeDom(parse('', translations)))
.toEqual([[HtmlElementAst, 'div', 0], [HtmlAttrAst, 'value', '{{b}} or {{a}}']]);
});
it('should handle nested html', () => {
let translations: {[key: string]: string} = {};
translations[id(new Message('ab', null, null))] =
'BA';
expect(humanizeDom(parse('', translations))).toEqual([
[HtmlElementAst, 'div', 0],
[HtmlElementAst, 'b', 1],
[HtmlTextAst, 'B', 2],
[HtmlElementAst, 'a', 1],
[HtmlTextAst, 'A', 2],
]);
});
it('should support interpolation', () => {
let translations: {[key: string]: string} = {};
translations[id(new Message(
'ab', null,
null))] = 'BA';
expect(humanizeDom(parse('', translations))).toEqual([
[HtmlElementAst, 'div', 0],
[HtmlElementAst, 'b', 1],
[HtmlTextAst, '{{i}}B', 2],
[HtmlElementAst, 'a', 1],
[HtmlTextAst, 'A', 2],
]);
});
it('should i18n attributes of placeholder elements', () => {
let translations: {[key: string]: string} = {};
translations[id(new Message('a', null, null))] = 'A';
translations[id(new Message('b', null, null))] = 'B';
expect(humanizeDom(parse('', translations)))
.toEqual([
[HtmlElementAst, 'div', 0],
[HtmlElementAst, 'a', 1],
[HtmlAttrAst, 'value', 'B'],
[HtmlTextAst, 'A', 2],
]);
});
it('should preserve non-i18n attributes', () => {
let translations: {[key: string]: string} = {};
translations[id(new Message('message', null, null))] = 'another message';
expect(humanizeDom(parse('message
', translations))).toEqual([
[HtmlElementAst, 'div', 0], [HtmlAttrAst, 'value', 'b'],
[HtmlTextAst, 'another message', 1]
]);
});
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(`message1message2`, translations);
expect(humanizeDom(res)).toEqual([
[HtmlTextAst, 'another message1', 0],
[HtmlTextAst, 'another message2', 0],
]);
});
it('should preserve original positions', () => {
let translations: {[key: string]: string} = {};
translations[id(new Message('ab', null, null))] =
'BA';
let res =
(parse('', translations).rootNodes[0]).children;
expect(res[0].sourceSpan.start.offset).toEqual(18);
expect(res[1].sourceSpan.start.offset).toEqual(10);
});
describe('errors', () => {
it('should error when giving an invalid template', () => {
expect(humanizeErrors(parse('a', {}).errors)).toEqual([
'Unexpected closing tag "b"'
]);
});
it('should error when no matching message (attr)', () => {
let mid = id(new Message('some message', null, null));
expect(humanizeErrors(parse('', {}).errors))
.toEqual([`Cannot find message for id '${mid}'`]);
});
it('should error when no matching message (text)', () => {
let mid = id(new Message('some message', null, null));
expect(humanizeErrors(parse('some message
', {}).errors)).toEqual([
`Cannot find message for id '${mid}'`
]);
});
it('should error when a non-placeholder element appears in translation', () => {
let translations: {[key: string]: string} = {};
translations[id(new Message('some message', null, null))] = 'a';
expect(humanizeErrors(parse('some message
', translations).errors)).toEqual([
`Unexpected tag "a". Only "ph" tags are allowed.`
]);
});
it('should error when a placeholder element does not have the name attribute', () => {
let translations: {[key: string]: string} = {};
translations[id(new Message('some message', null, null))] = 'a';
expect(humanizeErrors(parse('some message
', translations).errors)).toEqual([
`Missing "name" attribute.`
]);
});
it('should error when the translation refers to an invalid expression', () => {
let translations: {[key: string]: string} = {};
translations[id(new Message('hi ', null, null))] = 'hi ';
expect(
humanizeErrors(parse('', translations).errors))
.toEqual(['Invalid interpolation index \'99\'']);
});
});
});
}
function humanizeErrors(errors: ParseError[]): string[] {
return errors.map(error => error.msg);
}