UNPKG

12.2 kBJavaScriptView Raw
1'use strict';
2
3var Polyglot = require('../');
4var expect = require('chai').expect;
5
6describe('t', function () {
7 var phrases = {
8 hello: 'Hello',
9 hi_name_welcome_to_place: 'Hi, %{name}, welcome to %{place}!',
10 name_your_name_is_name: '%{name}, your name is %{name}!',
11 empty_string: ''
12 };
13
14 var polyglot;
15 beforeEach(function () {
16 polyglot = new Polyglot({ phrases: phrases });
17 });
18
19 it('translates a simple string', function () {
20 expect(polyglot.t('hello')).to.equal('Hello');
21 });
22
23 it('returns the key if translation not found', function () {
24 expect(polyglot.t('bogus_key')).to.equal('bogus_key');
25 });
26
27 it('interpolates', function () {
28 expect(polyglot.t('hi_name_welcome_to_place', {
29 name: 'Spike',
30 place: 'the webz'
31 })).to.equal('Hi, Spike, welcome to the webz!');
32 });
33
34 it('interpolates with missing substitutions', function () {
35 expect(polyglot.t('hi_name_welcome_to_place', {
36 place: undefined
37 })).to.equal('Hi, , welcome to %{place}!');
38 });
39
40 it('interpolates the same placeholder multiple times', function () {
41 expect(polyglot.t('name_your_name_is_name', {
42 name: 'Spike'
43 })).to.equal('Spike, your name is Spike!');
44 });
45
46 it('allows you to supply default values', function () {
47 expect(polyglot.t('can_i_call_you_name', {
48 _: 'Can I call you %{name}?',
49 name: 'Robert'
50 })).to.equal('Can I call you Robert?');
51 });
52
53 it('returns the non-interpolated key if not initialized with allowMissing and translation not found', function () {
54 expect(polyglot.t('Welcome %{name}', {
55 name: 'Robert'
56 })).to.equal('Welcome %{name}');
57 });
58
59 it('returns an interpolated key if initialized with allowMissing and translation not found', function () {
60 var instance = new Polyglot({ phrases: phrases, allowMissing: true });
61 expect(instance.t('Welcome %{name}', {
62 name: 'Robert'
63 })).to.equal('Welcome Robert');
64 });
65
66 it('returns the translation even if it is an empty string', function () {
67 expect(polyglot.t('empty_string')).to.equal('');
68 });
69
70 it('returns the default value even if it is an empty string', function () {
71 expect(polyglot.t('bogus_key', { _: '' })).to.equal('');
72 });
73
74 it('handles dollar signs in the substitution value', function () {
75 expect(polyglot.t('hi_name_welcome_to_place', {
76 name: '$abc $0',
77 place: '$1 $&'
78 })).to.equal('Hi, $abc $0, welcome to $1 $&!');
79 });
80
81 it('supports nested phrase objects', function () {
82 var nestedPhrases = {
83 nav: {
84 presentations: 'Presentations',
85 hi_user: 'Hi, %{user}.',
86 cta: {
87 join_now: 'Join now!'
88 }
89 },
90 'header.sign_in': 'Sign In'
91 };
92 var instance = new Polyglot({ phrases: nestedPhrases });
93 expect(instance.t('nav.presentations')).to.equal('Presentations');
94 expect(instance.t('nav.hi_user', { user: 'Raph' })).to.equal('Hi, Raph.');
95 expect(instance.t('nav.cta.join_now')).to.equal('Join now!');
96 expect(instance.t('header.sign_in')).to.equal('Sign In');
97 });
98});
99
100describe('pluralize', function () {
101 var phrases = {
102 count_name: '%{smart_count} Name |||| %{smart_count} Names'
103 };
104
105 var polyglot;
106 beforeEach(function () {
107 polyglot = new Polyglot({ phrases: phrases, locale: 'en' });
108 });
109
110 it('supports pluralization with an integer', function () {
111 expect(polyglot.t('count_name', { smart_count: 0 })).to.equal('0 Names');
112 expect(polyglot.t('count_name', { smart_count: 1 })).to.equal('1 Name');
113 expect(polyglot.t('count_name', { smart_count: 2 })).to.equal('2 Names');
114 expect(polyglot.t('count_name', { smart_count: 3 })).to.equal('3 Names');
115 });
116
117 it('accepts a number as a shortcut to pluralize a word', function () {
118 expect(polyglot.t('count_name', 0)).to.equal('0 Names');
119 expect(polyglot.t('count_name', 1)).to.equal('1 Name');
120 expect(polyglot.t('count_name', 2)).to.equal('2 Names');
121 expect(polyglot.t('count_name', 3)).to.equal('3 Names');
122 });
123
124 it('ignores a region subtag when choosing a pluralization rule', function () {
125 var instance = new Polyglot({ phrases: phrases, locale: 'fr-FR' });
126 // French rule: "0" is singular
127 expect(instance.t('count_name', 0)).to.equal('0 Name');
128 });
129});
130
131describe('locale-specific pluralization rules', function () {
132 it('pluralizes in Arabic', function () {
133 // English would be: "1 vote" / "%{smart_count} votes"
134 var whatSomeoneTranslated = [
135 'ولا صوت',
136 'صوت واحد',
137 'صوتان',
138 '%{smart_count} أصوات',
139 '%{smart_count} صوت',
140 '%{smart_count} صوت'
141 ];
142 var phrases = {
143 n_votes: whatSomeoneTranslated.join(' |||| ')
144 };
145
146 var polyglot = new Polyglot({ phrases: phrases, locale: 'ar' });
147
148 expect(polyglot.t('n_votes', 0)).to.equal('ولا صوت');
149 expect(polyglot.t('n_votes', 1)).to.equal('صوت واحد');
150 expect(polyglot.t('n_votes', 2)).to.equal('صوتان');
151 expect(polyglot.t('n_votes', 3)).to.equal('3 أصوات');
152 expect(polyglot.t('n_votes', 11)).to.equal('11 صوت');
153 expect(polyglot.t('n_votes', 102)).to.equal('102 صوت');
154 });
155});
156
157describe('locale', function () {
158 var polyglot;
159 beforeEach(function () {
160 polyglot = new Polyglot();
161 });
162
163 it('defaults to "en"', function () {
164 expect(polyglot.locale()).to.equal('en');
165 });
166
167 it('gets and sets locale', function () {
168 polyglot.locale('es');
169 expect(polyglot.locale()).to.equal('es');
170
171 polyglot.locale('fr');
172 expect(polyglot.locale()).to.equal('fr');
173 });
174});
175
176describe('extend', function () {
177 var polyglot;
178 beforeEach(function () {
179 polyglot = new Polyglot();
180 });
181
182 it('supports multiple extends, overriding old keys', function () {
183 polyglot.extend({ aKey: 'First time' });
184 polyglot.extend({ aKey: 'Second time' });
185 expect(polyglot.t('aKey')).to.equal('Second time');
186 });
187
188 it('does not forget old keys', function () {
189 polyglot.extend({ firstKey: 'Numba one', secondKey: 'Numba two' });
190 polyglot.extend({ secondKey: 'Numero dos' });
191 expect(polyglot.t('firstKey')).to.equal('Numba one');
192 });
193
194 it('supports optional `prefix` argument', function () {
195 polyglot.extend({ click: 'Click', hover: 'Hover' }, 'sidebar');
196 expect(polyglot.phrases['sidebar.click']).to.equal('Click');
197 expect(polyglot.phrases['sidebar.hover']).to.equal('Hover');
198 expect(polyglot.phrases).not.to.have.property('click');
199 });
200
201 it('supports nested object', function () {
202 polyglot.extend({
203 sidebar: {
204 click: 'Click',
205 hover: 'Hover'
206 },
207 nav: {
208 header: {
209 log_in: 'Log In'
210 }
211 }
212 });
213 expect(polyglot.phrases['sidebar.click']).to.equal('Click');
214 expect(polyglot.phrases['sidebar.hover']).to.equal('Hover');
215 expect(polyglot.phrases['nav.header.log_in']).to.equal('Log In');
216 expect(polyglot.phrases).not.to.have.property('click');
217 expect(polyglot.phrases).not.to.have.property('header.log_in');
218 expect(polyglot.phrases).not.to.have.property('log_in');
219 });
220});
221
222describe('clear', function () {
223 var polyglot;
224 beforeEach(function () {
225 polyglot = new Polyglot();
226 });
227
228 it('wipes out old phrases', function () {
229 polyglot.extend({ hiFriend: 'Hi, Friend.' });
230 polyglot.clear();
231 expect(polyglot.t('hiFriend')).to.equal('hiFriend');
232 });
233});
234
235describe('replace', function () {
236 var polyglot;
237 beforeEach(function () {
238 polyglot = new Polyglot();
239 });
240
241 it('wipes out old phrases and replace with new phrases', function () {
242 polyglot.extend({ hiFriend: 'Hi, Friend.', byeFriend: 'Bye, Friend.' });
243 polyglot.replace({ hiFriend: 'Hi, Friend.' });
244 expect(polyglot.t('hiFriend')).to.equal('Hi, Friend.');
245 expect(polyglot.t('byeFriend')).to.equal('byeFriend');
246 });
247});
248
249describe('unset', function () {
250 var polyglot;
251 beforeEach(function () {
252 polyglot = new Polyglot();
253 });
254
255 it('unsets a key based on a string', function () {
256 polyglot.extend({ test_key: 'test_value' });
257 expect(polyglot.has('test_key')).to.equal(true);
258
259 polyglot.unset('test_key');
260 expect(polyglot.has('test_key')).to.equal(false);
261 });
262
263 it('unsets a key based on an object hash', function () {
264 polyglot.extend({ test_key: 'test_value', foo: 'bar' });
265 expect(polyglot.has('test_key')).to.equal(true);
266 expect(polyglot.has('foo')).to.equal(true);
267
268 polyglot.unset({ test_key: 'test_value', foo: 'bar' });
269 expect(polyglot.has('test_key')).to.equal(false);
270 expect(polyglot.has('foo')).to.equal(false);
271 });
272
273 it('unsets nested objects using recursive prefix call', function () {
274 polyglot.extend({ foo: { bar: 'foobar' } });
275 expect(polyglot.has('foo.bar')).to.equal(true);
276
277 polyglot.unset({ foo: { bar: 'foobar' } });
278 expect(polyglot.has('foo.bar')).to.equal(false);
279 });
280});
281
282describe('transformPhrase', function () {
283 var simple = '%{name} is %{attribute}';
284 var english = '%{smart_count} Name |||| %{smart_count} Names';
285 var arabic = [
286 'ولا صوت',
287 'صوت واحد',
288 'صوتان',
289 '%{smart_count} أصوات',
290 '%{smart_count} صوت',
291 '%{smart_count} صوت'
292 ].join(' |||| ');
293
294 it('does simple interpolation', function () {
295 expect(Polyglot.transformPhrase(simple, { name: 'Polyglot', attribute: 'awesome' })).to.equal('Polyglot is awesome');
296 });
297
298 it('removes missing keys', function () {
299 expect(Polyglot.transformPhrase(simple, { name: 'Polyglot' })).to.equal('Polyglot is ');
300 });
301
302 it('selects the correct plural form based on smart_count', function () {
303 expect(Polyglot.transformPhrase(english, { smart_count: 0 }, 'en')).to.equal('0 Names');
304 expect(Polyglot.transformPhrase(english, { smart_count: 1 }, 'en')).to.equal('1 Name');
305 expect(Polyglot.transformPhrase(english, { smart_count: 2 }, 'en')).to.equal('2 Names');
306 expect(Polyglot.transformPhrase(english, { smart_count: 3 }, 'en')).to.equal('3 Names');
307 });
308
309 it('selects the correct locale', function () {
310 // French rule: "0" is singular
311 expect(Polyglot.transformPhrase(english, { smart_count: 0 }, 'fr')).to.equal('0 Name');
312 expect(Polyglot.transformPhrase(english, { smart_count: 1 }, 'fr')).to.equal('1 Name');
313 expect(Polyglot.transformPhrase(english, { smart_count: 2 }, 'fr')).to.equal('2 Names');
314 expect(Polyglot.transformPhrase(english, { smart_count: 3 }, 'fr')).to.equal('3 Names');
315
316 // Arabic has 6 rules
317 expect(Polyglot.transformPhrase(arabic, 0, 'ar')).to.equal('ولا صوت');
318 expect(Polyglot.transformPhrase(arabic, 1, 'ar')).to.equal('صوت واحد');
319 expect(Polyglot.transformPhrase(arabic, 2, 'ar')).to.equal('صوتان');
320 expect(Polyglot.transformPhrase(arabic, 3, 'ar')).to.equal('3 أصوات');
321 expect(Polyglot.transformPhrase(arabic, 11, 'ar')).to.equal('11 صوت');
322 expect(Polyglot.transformPhrase(arabic, 102, 'ar')).to.equal('102 صوت');
323 });
324
325 it('defaults to `en`', function () {
326 // French rule: "0" is singular
327 expect(Polyglot.transformPhrase(english, { smart_count: 0 })).to.equal('0 Names');
328 });
329
330 it('ignores a region subtag when choosing a pluralization rule', function () {
331 // French rule: "0" is singular
332 expect(Polyglot.transformPhrase(english, { smart_count: 0 }, 'fr-FR')).to.equal('0 Name');
333 });
334
335 it('works without arguments', function () {
336 expect(Polyglot.transformPhrase(english)).to.equal(english);
337 });
338
339 it('respects a number as shortcut for smart_count', function () {
340 expect(Polyglot.transformPhrase(english, 0, 'en')).to.equal('0 Names');
341 expect(Polyglot.transformPhrase(english, 1, 'en')).to.equal('1 Name');
342 expect(Polyglot.transformPhrase(english, 5, 'en')).to.equal('5 Names');
343 });
344
345 it('throws without sane phrase string', function () {
346 expect(function () { Polyglot.transformPhrase(); }).to.throw(TypeError);
347 expect(function () { Polyglot.transformPhrase(null); }).to.throw(TypeError);
348 expect(function () { Polyglot.transformPhrase(32); }).to.throw(TypeError);
349 expect(function () { Polyglot.transformPhrase({}); }).to.throw(TypeError);
350 });
351});