1 | 'use strict';
|
2 |
|
3 | var Polyglot = require('../');
|
4 | var expect = require('chai').expect;
|
5 |
|
6 | describe('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 |
|
100 | describe('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 |
|
127 | expect(instance.t('count_name', 0)).to.equal('0 Name');
|
128 | });
|
129 | });
|
130 |
|
131 | describe('locale-specific pluralization rules', function () {
|
132 | it('pluralizes in Arabic', function () {
|
133 |
|
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 |
|
157 | describe('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 |
|
176 | describe('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 |
|
222 | describe('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 |
|
235 | describe('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 |
|
249 | describe('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 |
|
282 | describe('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 |
|
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 |
|
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 |
|
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 |
|
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 | });
|