UNPKG

@ngx-i18nsupport/ngx-i18nsupport-lib

Version:

A Typescript library to work with Angular generated i18n files (xliff, xmb)

211 lines (182 loc) 11.7 kB
import {XliffMessageParser} from './xliff-message-parser'; import {ParsedMessage} from './parsed-message'; import {DOMParser} from 'xmldom'; import {INormalizedMessage} from '../api/index'; /** * Created by martin on 17.05.2017. * Testcases for parsing normalized messages to XLIFF 1.2 and vive versa. */ describe('message parse XLIFF 1.2 test spec', () => { /** * Helperfunction to create a parsed message from normalized string. * @param normalizedString normalizedString * @param sourceMessage sourceMessage * @return ParsedMessage */ function parsedMessageFor(normalizedString: string, sourceMessage?: ParsedMessage): ParsedMessage { const parser = new XliffMessageParser(); return parser.parseNormalizedString(normalizedString, sourceMessage); } /** * Helperfunction to create a parsed message from native xml. * @param xmlContent xmlContent * @param sourceMessage sourceMessage * @return ParsedMessage */ function parsedMessageFromXML(xmlContent: string, sourceMessage?: ParsedMessage): ParsedMessage { const parser = new XliffMessageParser(); return parser.createNormalizedMessageFromXMLString(xmlContent, sourceMessage); } /** * create normalized message from string, then create one from generated xml. * Check that it is the same. * @param normalizedMessage normalizedMessage */ function checkToXmlAndBack(normalizedMessage: string) { const xml = parsedMessageFor(normalizedMessage).asNativeString(); expect(parsedMessageFromXML('<source>' + xml + '</source>').asDisplayString()).toBe(normalizedMessage); } describe('normalized message to xml', () => { it('should parse plain text', () => { const normalizedMessage = 'a text without anything special'; const parsedMessage = parsedMessageFor(normalizedMessage); expect(parsedMessage.asDisplayString()).toBe(normalizedMessage); expect(parsedMessage.asNativeString()).toBe(normalizedMessage); }); it('should parse text with placeholder', () => { const normalizedMessage = 'a placeholder: {{0}}'; const parsedMessage = parsedMessageFor(normalizedMessage); expect(parsedMessage.asDisplayString()).toBe(normalizedMessage); expect(parsedMessage.asNativeString()).toBe('a placeholder: <x id="INTERPOLATION"/>'); checkToXmlAndBack(normalizedMessage); }); it('should parse text with 2 placeholders', () => { const normalizedMessage = '{{1}}: a placeholder: {{0}}'; const parsedMessage = parsedMessageFor(normalizedMessage); expect(parsedMessage.asDisplayString()).toBe(normalizedMessage); expect(parsedMessage.asNativeString()).toBe('<x id="INTERPOLATION_1"/>: a placeholder: <x id="INTERPOLATION"/>'); checkToXmlAndBack(normalizedMessage); }); it('should parse simple bold tag', () => { const normalizedMessage = 'a text <b>with</b> a bold text'; const parsedMessage = parsedMessageFor(normalizedMessage); expect(parsedMessage.asDisplayString()).toBe(normalizedMessage); expect(parsedMessage.asNativeString()) .toBe('a text <x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b>"/>' + 'with<x id="CLOSE_BOLD_TEXT" ctype="x-b"/> a bold text'); checkToXmlAndBack(normalizedMessage); }); it('should parse simple italic tag', () => { const normalizedMessage = 'a text <i>with</i> emphasis'; const parsedMessage = parsedMessageFor(normalizedMessage); expect(parsedMessage.asDisplayString()).toBe(normalizedMessage); expect(parsedMessage.asNativeString()) .toBe('a text <x id="START_ITALIC_TEXT" ctype="x-i" equiv-text="&lt;i>"/>' + 'with<x id="CLOSE_ITALIC_TEXT" ctype="x-i"/> emphasis'); checkToXmlAndBack(normalizedMessage); }); it('should parse unknown tag', () => { const normalizedMessage = 'a text with <strange>strange emphasis</strange>'; const parsedMessage = parsedMessageFor(normalizedMessage); expect(parsedMessage.asDisplayString()).toBe(normalizedMessage); expect(parsedMessage.asNativeString()) .toBe('a text with <x id="START_TAG_STRANGE" ctype="x-strange" equiv-text="&lt;strange>"/>' + 'strange emphasis<x id="CLOSE_TAG_STRANGE" ctype="x-strange"/>'); checkToXmlAndBack(normalizedMessage); }); it('should parse embedded tags with placeholder inside', () => { const normalizedMessage = '<b><i><strange>Placeholder {{0}}</strange></i></b>'; const parsedMessage = parsedMessageFor(normalizedMessage); expect(parsedMessage.asDisplayString()).toBe(normalizedMessage); expect(parsedMessage.asNativeString()) .toBe('<x id="START_BOLD_TEXT" ctype="x-b" equiv-text="&lt;b>"/><x id="START_ITALIC_TEXT"' + ' ctype="x-i" equiv-text="&lt;i>"/><x id="START_TAG_STRANGE" ctype="x-strange" equiv-text="&lt;strange>"/>' + 'Placeholder <x id="INTERPOLATION"/><x id="CLOSE_TAG_STRANGE" ctype="x-strange"/><x id="CLOSE_ITALIC_TEXT"' + ' ctype="x-i"/><x id="CLOSE_BOLD_TEXT" ctype="x-b"/>'); checkToXmlAndBack(normalizedMessage); }); it('should parse empty tag like <br>', () => { const normalizedMessage = 'one line<br>second line'; const parsedMessage = parsedMessageFor(normalizedMessage); expect(parsedMessage.asDisplayString()).toBe(normalizedMessage); expect(parsedMessage.asNativeString()).toBe('one line<x id="LINE_BREAK" ctype="lb" equiv-text="&lt;br/>"/>second line'); checkToXmlAndBack(normalizedMessage); }); it('should parse ICU Refs', () => { const normalizedMessage = 'a text with <ICU-Message-Ref_0/>'; const parsedMessage = parsedMessageFor(normalizedMessage); expect(parsedMessage.asDisplayString()).toBe(normalizedMessage); expect(parsedMessage.asNativeString()).toBe('a text with <x id="ICU"/>'); checkToXmlAndBack(normalizedMessage); }); }); describe('xml to normalized message', () => { it('should parse simple text content', () => { const parsedMessage = parsedMessageFromXML('a simple content'); expect(parsedMessage.asDisplayString()).toBe('a simple content'); }); it('should parse strange tag with placeholder content', () => { const parsedMessage = parsedMessageFromXML('Diese Nachricht ist <x id="START_TAG_STRANGE" ctype="x-strange"/>' + '<x id="INTERPOLATION"/><x id="CLOSE_TAG_STRANGE" ctype="x-strange"/>'); expect(parsedMessage.asDisplayString()).toBe('Diese Nachricht ist <strange>{{0}}</strange>'); }); it('should parse embedded tags', () => { const parsedMessage = parsedMessageFromXML('Diese Nachricht ist <x id="START_BOLD_TEXT" ctype="x-b"/>' + '<x id="START_TAG_STRANGE" ctype="x-strange"/>SEHR WICHTIG<x id="CLOSE_TAG_STRANGE"' + ' ctype="x-strange"/><x id="CLOSE_BOLD_TEXT" ctype="x-b"/>'); expect(parsedMessage.asDisplayString()).toBe('Diese Nachricht ist <b><strange>SEHR WICHTIG</strange></b>'); }); it('should parse complex message with embedded placeholder', () => { const parsedMessage = parsedMessageFromXML('<x id="START_LINK" ctype="x-a"/>link1 with placeholder ' + '<x id="INTERPOLATION"/><x id="CLOSE_LINK" ctype="x-a"/>'); expect(parsedMessage.asDisplayString()).toBe('<a>link1 with placeholder {{0}}</a>'); }); it('should throw an error due to not well formed elements <b><strange></b>', () => { try { const parsedMessage = parsedMessageFromXML('Diese Nachricht ist falsch geschachtelt: ' + '<x id="START_BOLD_TEXT" ctype="x-b"/><x id="START_TAG_STRANGE" ctype="x-strange"/>' + 'FALSCH<x id="CLOSE_BOLD_TEXT" ctype="x-b"/><x id="CLOSE_TAG_STRANGE" ctype="x-strange"/>'); expect(parsedMessage.toString()).toBe('should throw an error'); } catch (e) { expect(e.message).toContain('unexpected close tag b'); } }); it('should parse message with embedded ICU message reference', () => { const parsedMessage = parsedMessageFromXML('first: <x id="ICU"/>'); expect(parsedMessage.asDisplayString()).toBe('first: <ICU-Message-Ref_0/>'); }); it('should parse message with 2 embedded ICU message reference', () => { const parsedMessage = parsedMessageFromXML('first: <x id="ICU"/>, second <x id="ICU_1"/>'); expect(parsedMessage.asDisplayString()).toBe('first: <ICU-Message-Ref_0/>, second <ICU-Message-Ref_1/>'); }); it('should set correct placeholer index (issue #84 ngx-i18nsupport) ', () => { const messageWith2Indexes = 'New <x id="START_TAG_XY" ctype="x-xy" equiv-text="&lt;xy&gt;"/>' + '<x id="CLOSE_TAG_XY" ctype="x-xy" equiv-text="&lt;/xy&gt;"/> was reported by <x id="START_TAG_XY_1" ctype="x-xy"' + ' equiv-text="&lt;xy&gt;"/><x id="CLOSE_TAG_XY" ctype="x-xy" equiv-text="&lt;/xy&gt;"/>'; const parsedMessage = parsedMessageFromXML(messageWith2Indexes); const normalizedMessageString = parsedMessage.asDisplayString(); expect(normalizedMessageString).toBe('New <xy></xy> was reported by <xy id="1"></xy>'); const translatedMessage: INormalizedMessage = parsedMessage.translate('New <xy></xy> was reported by <xy id="1"></xy>'); expect(translatedMessage.asNativeString()).toBe('New <x id="START_TAG_XY" ctype="x-xy" equiv-text="&lt;xy>"/>' + '<x id="CLOSE_TAG_XY" ctype="x-xy"/> was reported by <x id="START_TAG_XY_1" ctype="x-xy"' + ' equiv-text="&lt;xy>"/><x id="CLOSE_TAG_XY" ctype="x-xy"/>'); }); it('should parse simple plural ICU message', () => { const parsedMessage = parsedMessageFromXML('{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago} other {a few minutes ago} }'); expect(parsedMessage.asDisplayString()).toBe('<ICU-Message/>'); expect(parsedMessage.getICUMessage()).toBeTruthy(); const icuMessage = parsedMessage.getICUMessage(); expect(icuMessage.getCategories().length).toBe(3); }); it('should parse plural ICU message with placeholder', () => { const parsedMessage = parsedMessageFromXML('{VAR_PLURAL, plural, =0 {just now} =1 {one minute ago}' + ' other {<x id="INTERPOLATION" equiv-text="{{minutes}}"/> minutes ago} }'); expect(parsedMessage.asDisplayString()).toBe('<ICU-Message/>'); expect(parsedMessage.getICUMessage()).toBeTruthy(); const icuMessage = parsedMessage.getICUMessage(); expect(icuMessage.getCategories().length).toBe(3); expect(icuMessage.getCategories()[2].getMessageNormalized().asDisplayString()).toBe('{{0}} minutes ago'); }); }); });