/** * @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 {Lexer as ExpressionLexer} from '@angular/compiler/src/expression_parser/lexer'; import {Parser as ExpressionParser} from '@angular/compiler/src/expression_parser/parser'; import {HtmlParser} from '@angular/compiler/src/html_parser'; import {Message} from '@angular/compiler/src/i18n/message'; import {MessageExtractor, removeDuplicates} from '@angular/compiler/src/i18n/message_extractor'; import {beforeEach, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal'; export function main() { describe('MessageExtractor', () => { let extractor: MessageExtractor; beforeEach(() => { const expParser = new ExpressionParser(new ExpressionLexer()); const htmlParser = new HtmlParser(expParser); // TODO: pass expression parser extractor = new MessageExtractor(htmlParser, expParser, ['i18n-tag'], {'i18n-el': ['trans']}); }); it('should extract from elements with the i18n attr', () => { let res = extractor.extract('
message
', 'someurl'); expect(res.messages).toEqual([new Message('message', 'meaning', 'desc')]); }); it('should extract from elements with the i18n attr without a desc', () => { let res = extractor.extract('
message
', 'someurl'); expect(res.messages).toEqual([new Message('message', 'meaning', null)]); }); it('should extract from elements with the i18n attr without a meaning', () => { let res = extractor.extract('
message
', 'someurl'); expect(res.messages).toEqual([new Message('message', null, null)]); }); it('should extract from attributes', () => { let res = extractor.extract( `
`, 'someurl'); expect(res.messages).toEqual([ new Message('message1', 'meaning1', 'desc1'), new Message('message2', 'meaning2', 'desc2') ]); }); it('should extract from partitions', () => { let res = extractor.extract( ` message1 message2 message3`, 'someUrl'); expect(res.messages).toEqual([ new Message('message1', 'meaning1', 'desc1'), new Message('message2', 'meaning2'), new Message('message3', null), ]); }); it('should ignore other comments', () => { let res = extractor.extract( ` message1`, 'someUrl'); expect(res.messages).toEqual([new Message('message1', 'meaning1', 'desc1')]); }); it('should replace interpolation with placeholders (text nodes)', () => { let res = extractor.extract('
Hi {{one}} and {{two}}
', 'someurl'); expect(res.messages).toEqual([new Message( 'Hi and ', null, null)]); }); it('should replace interpolation with placeholders (attributes)', () => { let res = extractor.extract('
', 'someurl'); expect(res.messages).toEqual([new Message( 'Hi and ', null, null)]); }); it('should replace interpolation with named placeholders if provided (text nodes)', () => { let res = extractor.extract( `
Hi {{one //i18n(ph="FIRST")}} and {{two //i18n(ph="SECOND")}}
`, 'someurl'); expect(res.messages).toEqual([new Message( 'Hi and ', null, null)]); }); it('should replace interpolation with named placeholders if provided (attributes)', () => { let res = extractor.extract( `
`, 'someurl'); expect(res.messages).toEqual([new Message( 'Hi and ', null, null)]); }); it('should match named placeholders with extra spacing', () => { let res = extractor.extract( `
`, 'someurl'); expect(res.messages).toEqual([new Message( 'Hi and ', null, null)]); }); it('should suffix duplicate placeholder names with numbers', () => { let res = extractor.extract( `
`, 'someurl'); expect(res.messages).toEqual([new Message( 'Hi and and ', null, null)]); }); it('should handle html content', () => { let res = extractor.extract( '
zero
one
two
', 'someurl'); expect(res.messages).toEqual([new Message( 'zeroonetwo', null, null)]); }); it('should handle html content with interpolation', () => { let res = extractor.extract('
zero{{a}}
{{b}}
', 'someurl'); expect(res.messages).toEqual([new Message( 'zero', null, null)]); }); it('should extract from nested elements', () => { let res = extractor.extract( '
message2
', 'someurl'); expect(res.messages).toEqual([ new Message('message2', 'meaning2', 'desc2'), new Message('message1', 'meaning1', 'desc1') ]); }); it('should extract messages from attributes in i18n blocks', () => { let res = extractor.extract( '
message
', 'someurl'); expect(res.messages).toEqual([ new Message('message', null, null), new Message('value', 'meaning', 'desc') ]); }); it('should remove duplicate messages', () => { let res = extractor.extract( ` message message`, 'someUrl'); expect(removeDuplicates(res.messages)).toEqual([ new Message('message', 'meaning', 'desc1'), ]); }); describe('implicit translation', () => { it('should extract from elements', () => { let res = extractor.extract('message', 'someurl'); expect(res.messages).toEqual([new Message('message', null, null)]); }); it('should extract meaning and description from elements when present', () => { let res = extractor.extract( 'message', 'someurl'); expect(res.messages).toEqual([new Message('message', 'meaning', 'description')]); }); it('should extract from attributes', () => { let res = extractor.extract(``, 'someurl'); expect(res.messages).toEqual([new Message('message', null, null)]); }); it('should extract meaning and description from attributes when present', () => { let res = extractor.extract( ``, 'someurl'); expect(res.messages).toEqual([new Message('message', 'meaning', 'desc')]); }); }); describe('errors', () => { it('should error on i18n attributes without matching "real" attributes', () => { let res = extractor.extract( `
`, 'someurl'); expect(res.errors.length).toEqual(1); expect(res.errors[0].msg).toEqual('Missing attribute \'title2\'.'); }); it('should error when i18n comments are unbalanced', () => { const res = extractor.extract('message1', 'someUrl'); expect(res.errors.length).toEqual(1); expect(res.errors[0].msg).toEqual('Missing closing \'i18n\' comment.'); }); it('should error when i18n comments are unbalanced', () => { const res = extractor.extract('', 'someUrl'); expect(res.errors.length).toEqual(1); expect(res.errors[0].msg).toEqual('Missing closing \'i18n\' comment.'); }); it('should return parse errors when the template is invalid', () => { let res = extractor.extract('