UNPKG

5.78 kBJavaScriptView Raw
1const {expect} = require('chai');
2
3import {extractMessages as extract} from '../src/extract';
4import translateMessagesToBundle from '../src/translate';
5
6
7describe('translation', function() {
8 it('generates correct translator functions', function() {
9 var translations = {
10 'Hello': 'Helo',
11 'world': 'byd',
12 '<a href="foo">tag with only safe attributes</a>': '<a href="bar">Mae tag sydd <span>wedi</span> dim ond priodoleddau sy\'n ddiogel</a>',
13 '<a:link href="foo">tag with unsafe attributes</a:link>': '<a:link href="bar">tag gyda phriodoleddau anniogel</a:link>',
14 '<SelfClosing />': 'Translated: <SelfClosing />',
15 '<SelfClosing:foo />': 'Translated: <SelfClosing:foo />',
16 '<Member.Name />': 'Translated: <Member.Name />',
17 'Cat: {nested}': 'Cat : {nested}',
18 'hatters': 'hetwyr',
19 'And now {a.member.expression}': 'Ac yn awr {a.member.expression}',
20 '<Re /><Ordering />': '<Ordering /><Re />',
21 'Check out: <Component />': '<Component/> "checked" out!',
22 '<span:stat><ReactIntl.FormattedNumber /></span:stat>opportunities': '<span:stat><ReactIntl.FormattedNumber /></span:stat>oportunidades',
23 '<Pluralize:items><Match when="=0">You have no items in your cart</Match><Match when="one">You have one item in your cart</Match><Match when="other">You have {this.state.count} items in your cart</Match></Pluralize:items>':
24 '<Pluralize:items><Match when="=0">No tiene nada in su carrito</Match><Match when="one">Tiene ún articulo en su carrito</Match><Match when="other">Tiene {this.state.count} articulos en su carrito</Match></Pluralize:items>'
25 };
26
27 var expectedResultsForTranslationBundles = {
28 '<I18N>Hello</I18N>': 'function() { return <span>Helo</span>; }',
29 'i18n("world")': 'function() { return "byd"; }',
30 '<I18N><a href="foo">tag with only safe attributes</a></I18N>': 'function() { return <span><a href="bar">Mae tag sydd <span>wedi</span> dim ond priodoleddau sy\'n ddiogel</a></span>; }',
31 '<I18N><a:link href="foo" target="_blank">tag with unsafe attributes</a:link></I18N>': 'function() { return <span><a href="bar" target="_blank">tag gyda phriodoleddau anniogel</a></span>; }',
32 '<I18N><a href="foo" target="_blank" i18n-id="link">tag with unsafe attributes</a></I18N>': 'function() { return <span><a href="bar" target="_blank">tag gyda phriodoleddau anniogel</a></span>; }',
33 '<I18N><SelfClosing i18n-id="foo" attr="attr" /></I18N>': 'function(SelfClosing) { return <span>Translated: <SelfClosing attr="attr" /></span>; }',
34 '<I18N><SelfClosing {...foo}/></I18N>': 'function(SelfClosing, foo) { return <span>Translated: <SelfClosing {...foo} /></span>; }',
35 '<I18N><Member.Name /></I18N>': 'function(Member) { return <span>Translated: <Member.Name /></span>; }',
36 '<I18N>Cat: {nested}</I18N>': "function(nested) { return <span>Cat : {nested}</span>; }",
37 '<I18N>And now {a.member.expression}</I18N>': 'function(a) { return <span>Ac yn awr {a.member.expression}</span>; }',
38 '<I18N>Check out: <Component gnar={3 * shnar}/></I18N>': 'function(Component, shnar) { return <span><Component gnar={3 * shnar} /> "checked" out!</span>; }',
39 '<I18N><Re /><Ordering /></I18N>': 'function(Re, Ordering) { return <span><Ordering /><Re /></span>; }',
40 '<I18N><Pluralize:items on={this.state.count}><Match when="=0">You have no items in your cart</Match><Match when="one">You have one item in your cart</Match><Match when="other">You have {this.state.count} items in your cart</Match></Pluralize:items></I18N>':
41 'function(Pluralize, Match) { return <span><Pluralize on={this.state.count}><Match when="=0">No tiene nada in su carrito</Match><Match when="one">Tiene ún articulo en su carrito</Match><Match when="other">Tiene {this.state.count} articulos en su carrito</Match></Pluralize></span>; }'
42 };
43
44 Object.keys(expectedResultsForTranslationBundles).forEach(original => {
45 const expected = expectedResultsForTranslationBundles[original];
46 const bundle = translateMessagesToBundle(original, translations, {inputFormat: 'js'}).bundle;
47 expect(bundle[Object.keys(bundle)[0]]).to.equal(expected);
48 });
49 });
50
51 it('warns on invalid translations', function() {
52 const originalSource = `
53 function render () {
54 return <p>
55 <I18N>Hello, world. <Component />{foo}{bar.baz}</I18N>
56 </p>
57 }
58 `;
59
60 // Translations for above source that should cause errors:
61 const invalidTranslations = [
62 '<a target="_blank">Unsafe attribute</a> <Component />{foo}{bar.baz}',
63 '<a:made-up-id></a:made-up-id><Component />{foo}{bar.baz}',
64 '{random + expression + in + placeholder}<Component />{foo}{bar.baz}',
65 '{non.existant.name}<Component />{foo}{bar.baz}',
66 '<Component /> Duplicated expressions: {foo}{foo}{bar.baz}',
67 'Missing component.',
68 'Duplicated component. <Component /> <Component />',
69 ];
70 var correctTranslation = 'Helo, byd. <Component />{foo}{bar.baz}';
71
72 var extraction = extract(originalSource)[0];
73
74 function translateMessage(translation) {
75 translateMessagesToBundle(originalSource, {[extraction]: translation}, {inputFormat: 'js'});
76 }
77
78 expect(() => translateMessage(correctTranslation)).to.not.throw();
79
80 invalidTranslations.forEach(translation => {
81 expect(() => translateMessage(translation)).to.throw();
82 });
83 });
84});