/** * @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 {HtmlParser} from '@angular/compiler/src/html_parser'; import {ExtractionResult, extractAstMessages} from '@angular/compiler/src/i18n/extractor'; import {beforeEach, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal'; import {serializeHtmlAst} from '../html_ast_serializer_spec' export function main() { ddescribe( 'MessageExtractor', () => { function getExtractionResult( html: string, implicitTags: string[], implicitAttrs: {[k: string]: string[]}): ExtractionResult { const htmlParser = new HtmlParser(); const parseResult = htmlParser.parse(html, 'extractor spec', true); if (parseResult.errors.length > 1) { throw Error(`unexpected parse errors: ${parseResult.errors.join('\n')}`); } return extractAstMessages(parseResult.rootNodes, implicitTags, implicitAttrs); } function extract( html: string, implicitTags: string[] = [], implicitAttrs: {[k: string]: string[]} = {}): [string[], string, string][] { const messages = getExtractionResult(html, implicitTags, implicitAttrs).messages; // clang-format off // https://github.com/angular/clang-format/issues/35 return messages.map( message => [serializeHtmlAst(message.ast), message.meaning, message.description, ]) as [string[], string, string][]; // clang-format on } function extractErrors( html: string, implicitTags: string[] = [], implicitAttrs: {[k: string]: string[]} = {}): any[] { const errors = getExtractionResult(html, implicitTags, implicitAttrs).errors; return errors.map((e): [string, string] => [e.msg, e.span.toString()]); } describe('elements', () => { it('should extract from elements', () => { expect(extract('
htmlnested
{count, plural, =0 {html}}{{interp}}`)) .toEqual([ [['{count, plural, =0 {html}}'], '', ''], [ [ 'text', 'htmlnested
', '{count, plural, =0 {html}}', '{{interp}}' ], '', '' ], ]); }); it('should ignore other comments', () => { expect(extract(`message1`)) .toEqual([ [['message1'], 'meaning1', 'desc1'], ]); }); it('should not create a message for empty blocks', () => { expect(extract(``)).toEqual([]); }); }); describe('ICU messages', () => { it('should extract ICU messages from translatable elements', () => { // single message when ICU is the only children expect(extract(''], '', ''], [['title="msg"'], 'm', 'd'], ]); }); it('should extract from attributes in translatable block', () => { expect( extract('
')) .toEqual([ [['title="msg"'], 'm', 'd'], [['
'], '', ''], ]); }); it('should extract from attributes in translatable ICU', () => { expect( extract( '{count, plural, =0 {
}}')) .toEqual([ [['title="msg"'], 'm', 'd'], [['{count, plural, =0 {
}}'], '', ''], ]); }); it('should extract from attributes in non translatable ICU', () => { expect(extract('{count, plural, =0 {
}}')) .toEqual([ [['title="msg"'], 'm', 'd'], ]); }); it('should not create a message for empty attributes', () => { expect(extract('')).toEqual([]); }); }); describe('implicit tags', () => { it('should extract from implicit tags', () => { expect(extract('bolditalic', ['b'])).toEqual([ [['bold'], '', ''], ]); }); }); describe('implicit attributes', () => { it('should extract implicit attributes', () => { expect(extract('bolditalic', [], {'b': ['title']})) .toEqual([ [['title="bb"'], '', ''], ]); }); }); describe('errors', () => { describe('elements', () => { it('should report nested translatable elements', () => { expect(extractErrors(`
`)).toEqual([ [ 'Could not mark an element as translatable inside a translatable section', '' ], ]); }); it('should report translatable elements in implicit elements', () => { expect(extractErrors(`
`, ['p'])).toEqual([ [ 'Could not mark an element as translatable inside a translatable section', '' ], ]); }); it('should report translatable elements in translatable blocks', () => { expect(extractErrors(``)).toEqual([ [ 'Could not mark an element as translatable inside a translatable section', '' ], ]); }); }); describe('blocks', () => { it('should report nested blocks', () => { expect(extractErrors(``)) .toEqual([ ['Could not start a block inside a translatable section', '`)).toEqual([ ['Unclosed block', '`)).toEqual([ ['Could not start a block inside a translatable section', '`, ['p'])).toEqual([ ['Could not start a block inside a translatable section', '`)).toEqual([ ['I18N blocks should not cross element boundaries', '`)).toEqual([ ['I18N blocks should not cross element boundaries', '`, ['b'])).toEqual([ ['Could not mark an element as translatable inside a translatable section', ''], ]); }); }); }); }); }