i18n-js 0.1.6 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/spec/i18n_spec.js ADDED
@@ -0,0 +1,686 @@
1
+ load("source/i18n.js");
2
+
3
+ describe("I18n.js", function(){
4
+ before(function() {
5
+ I18n.defaultLocale = "en";
6
+ I18n.defaultSeparator = ".";
7
+ I18n.locale = null;
8
+
9
+ I18n.translations = {
10
+ en: {
11
+ hello: "Hello World!",
12
+ greetings: {
13
+ stranger: "Hello stranger!",
14
+ name: "Hello {{name}}!"
15
+ },
16
+ profile: {
17
+ details: "{{name}} is {{age}}-years old"
18
+ },
19
+ inbox: {
20
+ one: "You have {{count}} message",
21
+ other: "You have {{count}} messages",
22
+ zero: "You have no messages"
23
+ },
24
+ unread: {
25
+ one: "You have 1 new message ({{unread}} unread)",
26
+ other: "You have {{count}} new messages ({{unread}} unread)",
27
+ zero: "You have no new messages ({{unread}} unread)"
28
+ },
29
+ number: {
30
+ human: {
31
+ storage_units: {
32
+ units: {
33
+ "byte": {
34
+ one: "Byte",
35
+ other: "Bytes"
36
+ },
37
+
38
+ "kb": "KB",
39
+ "mb": "MB",
40
+ "gb": "GB",
41
+ "tb": "TB"
42
+ }
43
+ }
44
+ }
45
+ }
46
+ },
47
+
48
+ "pt-BR": {
49
+ hello: "Olá Mundo!",
50
+ date: {
51
+ formats: {
52
+ "default": "%d/%m/%Y",
53
+ "short": "%d de %B",
54
+ "long": "%d de %B de %Y"
55
+ },
56
+ day_names: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"],
57
+ abbr_day_names: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"],
58
+ month_names: [null, "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"],
59
+ abbr_month_names: [null, "Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"]
60
+ },
61
+ number: {
62
+ percentage: {
63
+ format: {
64
+ delimiter: "",
65
+ separator: ",",
66
+ precision: 2
67
+ }
68
+ }
69
+ },
70
+ time: {
71
+ formats: {
72
+ "default": "%A, %d de %B de %Y, %H:%M h",
73
+ "short": "%d/%m, %H:%M h",
74
+ "long": "%A, %d de %B de %Y, %H:%M h"
75
+ },
76
+ am: "AM",
77
+ pm: "PM"
78
+ }
79
+ }
80
+ };
81
+ });
82
+
83
+ specify("with default options", function(){
84
+ expect(I18n.defaultLocale).toBeEqualTo("en");
85
+ expect(I18n.locale).toBeEqualTo(null);
86
+ expect(I18n.currentLocale()).toBeEqualTo("en");
87
+ });
88
+
89
+ specify("with custom locale", function(){
90
+ I18n.locale = "pt-BR";
91
+ expect(I18n.currentLocale()).toBeEqualTo("pt-BR");
92
+ });
93
+
94
+ specify("aliases", function(){
95
+ expect(I18n.t).toBe(I18n.translate);
96
+ expect(I18n.l).toBe(I18n.localize);
97
+ expect(I18n.p).toBe(I18n.pluralize);
98
+ });
99
+
100
+ specify("translation with single scope", function(){
101
+ expect(I18n.t("hello")).toBeEqualTo("Hello World!");
102
+ });
103
+
104
+ specify("translation as object", function(){
105
+ expect(I18n.t("greetings")).toBeInstanceOf(Object);
106
+ });
107
+
108
+ specify("translation with invalid scope shall not block", function(){
109
+ actual = I18n.t("invalid.scope.shall.not.block");
110
+ expected = '[missing "en.invalid.scope.shall.not.block" translation]';
111
+ expect(actual).toBeEqualTo(expected);
112
+ });
113
+
114
+ specify("translation for single scope on a custom locale", function(){
115
+ I18n.locale = "pt-BR";
116
+ expect(I18n.t("hello")).toBeEqualTo("Olá Mundo!");
117
+ });
118
+
119
+ specify("translation for multiple scopes", function(){
120
+ expect(I18n.t("greetings.stranger")).toBeEqualTo("Hello stranger!");
121
+ });
122
+
123
+ specify("single interpolation", function(){
124
+ actual = I18n.t("greetings.name", {name: "John Doe"});
125
+ expect(actual).toBeEqualTo("Hello John Doe!");
126
+ });
127
+
128
+ specify("multiple interpolation", function(){
129
+ actual = I18n.t("profile.details", {name: "John Doe", age: 27});
130
+ expect(actual).toBeEqualTo("John Doe is 27-years old");
131
+ });
132
+
133
+ specify("translation with count option", function(){
134
+ expect(I18n.t("inbox", {count: 0})).toBeEqualTo("You have no messages");
135
+ expect(I18n.t("inbox", {count: 1})).toBeEqualTo("You have 1 message");
136
+ expect(I18n.t("inbox", {count: 5})).toBeEqualTo("You have 5 messages");
137
+ });
138
+
139
+ specify("translation with count option and multiple placeholders", function(){
140
+ actual = I18n.t("unread", {unread: 5, count: 1});
141
+ expect(actual).toBeEqualTo("You have 1 new message (5 unread)");
142
+
143
+ actual = I18n.t("unread", {unread: 2, count: 10});
144
+ expect(actual).toBeEqualTo("You have 10 new messages (2 unread)");
145
+
146
+ actual = I18n.t("unread", {unread: 5, count: 0});
147
+ expect(actual).toBeEqualTo("You have no new messages (5 unread)");
148
+ });
149
+
150
+ specify("missing translation with count option", function(){
151
+ actual = I18n.t("invalid", {count: 1});
152
+ expect(actual).toBeEqualTo('[missing "en.invalid" translation]');
153
+
154
+ I18n.translations.en.inbox.one = null;
155
+ actual = I18n.t("inbox", {count: 1});
156
+ expect(actual).toBeEqualTo('[missing "en.inbox.one" translation]');
157
+ });
158
+
159
+ specify("pluralization", function(){
160
+ expect(I18n.p(0, "inbox")).toBeEqualTo("You have no messages");
161
+ expect(I18n.p(1, "inbox")).toBeEqualTo("You have 1 message");
162
+ expect(I18n.p(5, "inbox")).toBeEqualTo("You have 5 messages");
163
+ });
164
+
165
+ specify("pluralize should return 'other' scope", function(){
166
+ I18n.translations["en"]["inbox"]["zero"] = null;
167
+ expect(I18n.p(0, "inbox")).toBeEqualTo("You have 0 messages");
168
+ });
169
+
170
+ specify("pluralize should return 'zero' scope", function(){
171
+ I18n.translations["en"]["inbox"]["zero"] = "No messages (zero)";
172
+ I18n.translations["en"]["inbox"]["none"] = "No messages (none)";
173
+
174
+ expect(I18n.p(0, "inbox")).toBeEqualTo("No messages (zero)");
175
+ });
176
+
177
+ specify("pluralize should return 'none' scope", function(){
178
+ I18n.translations["en"]["inbox"]["zero"] = null;
179
+ I18n.translations["en"]["inbox"]["none"] = "No messages (none)";
180
+
181
+ expect(I18n.p(0, "inbox")).toBeEqualTo("No messages (none)");
182
+ });
183
+
184
+ specify("pluralize with negative values", function(){
185
+ expect(I18n.p(-1, "inbox")).toBeEqualTo("You have -1 message");
186
+ expect(I18n.p(-5, "inbox")).toBeEqualTo("You have -5 messages");
187
+ });
188
+
189
+ specify("pluralize with missing scope", function(){
190
+ expect(I18n.p(-1, "missing")).toBeEqualTo('[missing "en.missing" translation]');
191
+ });
192
+
193
+ specify("pluralize with multiple placeholders", function(){
194
+ actual = I18n.p(1, "unread", {unread: 5});
195
+ expect(actual).toBeEqualTo("You have 1 new message (5 unread)");
196
+
197
+ actual = I18n.p(10, "unread", {unread: 2});
198
+ expect(actual).toBeEqualTo("You have 10 new messages (2 unread)");
199
+
200
+ actual = I18n.p(0, "unread", {unread: 5});
201
+ expect(actual).toBeEqualTo("You have no new messages (5 unread)");
202
+ });
203
+
204
+ specify("numbers with default settings", function(){
205
+ expect(I18n.toNumber(1)).toBeEqualTo("1.000");
206
+ expect(I18n.toNumber(12)).toBeEqualTo("12.000");
207
+ expect(I18n.toNumber(123)).toBeEqualTo("123.000");
208
+ expect(I18n.toNumber(1234)).toBeEqualTo("1,234.000");
209
+ expect(I18n.toNumber(12345)).toBeEqualTo("12,345.000");
210
+ expect(I18n.toNumber(123456)).toBeEqualTo("123,456.000");
211
+ expect(I18n.toNumber(1234567)).toBeEqualTo("1,234,567.000");
212
+ expect(I18n.toNumber(12345678)).toBeEqualTo("12,345,678.000");
213
+ expect(I18n.toNumber(123456789)).toBeEqualTo("123,456,789.000");
214
+ });
215
+
216
+ specify("negative numbers with default settings", function(){
217
+ expect(I18n.toNumber(-1)).toBeEqualTo("-1.000");
218
+ expect(I18n.toNumber(-12)).toBeEqualTo("-12.000");
219
+ expect(I18n.toNumber(-123)).toBeEqualTo("-123.000");
220
+ expect(I18n.toNumber(-1234)).toBeEqualTo("-1,234.000");
221
+ expect(I18n.toNumber(-12345)).toBeEqualTo("-12,345.000");
222
+ expect(I18n.toNumber(-123456)).toBeEqualTo("-123,456.000");
223
+ expect(I18n.toNumber(-1234567)).toBeEqualTo("-1,234,567.000");
224
+ expect(I18n.toNumber(-12345678)).toBeEqualTo("-12,345,678.000");
225
+ expect(I18n.toNumber(-123456789)).toBeEqualTo("-123,456,789.000");
226
+ });
227
+
228
+ specify("numbers with partial translation and default options", function(){
229
+ I18n.translations.en.number = {
230
+ format: {
231
+ precision: 2
232
+ }
233
+ };
234
+
235
+ expect(I18n.toNumber(1234)).toBeEqualTo("1,234.00");
236
+ });
237
+
238
+ specify("numbers with full translation and default options", function(){
239
+ I18n.translations.en.number = {
240
+ format: {
241
+ delimiter: ".",
242
+ separator: ",",
243
+ precision: 2
244
+ }
245
+ };
246
+
247
+ expect(I18n.toNumber(1234)).toBeEqualTo("1.234,00");
248
+ });
249
+
250
+ specify("numbers with some custom options that should be merged with default options", function(){
251
+ expect(I18n.toNumber(1234, {precision: 0})).toBeEqualTo("1,234");
252
+ expect(I18n.toNumber(1234, {separator: '-'})).toBeEqualTo("1,234-000");
253
+ expect(I18n.toNumber(1234, {delimiter: '-'})).toBeEqualTo("1-234.000");
254
+ });
255
+
256
+ specify("numbers considering options", function(){
257
+ options = {
258
+ precision: 2,
259
+ separator: ",",
260
+ delimiter: "."
261
+ };
262
+
263
+ expect(I18n.toNumber(1, options)).toBeEqualTo("1,00");
264
+ expect(I18n.toNumber(12, options)).toBeEqualTo("12,00");
265
+ expect(I18n.toNumber(123, options)).toBeEqualTo("123,00");
266
+ expect(I18n.toNumber(1234, options)).toBeEqualTo("1.234,00");
267
+ expect(I18n.toNumber(123456, options)).toBeEqualTo("123.456,00");
268
+ expect(I18n.toNumber(1234567, options)).toBeEqualTo("1.234.567,00");
269
+ expect(I18n.toNumber(12345678, options)).toBeEqualTo("12.345.678,00");
270
+ });
271
+
272
+ specify("numbers with different precisions", function(){
273
+ options = {separator: ".", delimiter: ","};
274
+
275
+ options["precision"] = 2;
276
+ expect(I18n.toNumber(1.98, options)).toBeEqualTo("1.98");
277
+
278
+ options["precision"] = 3;
279
+ expect(I18n.toNumber(1.98, options)).toBeEqualTo("1.980");
280
+
281
+ options["precision"] = 2;
282
+ expect(I18n.toNumber(1.987, options)).toBeEqualTo("1.99");
283
+
284
+ options["precision"] = 1;
285
+ expect(I18n.toNumber(1.98, options)).toBeEqualTo("2.0");
286
+
287
+ options["precision"] = 0;
288
+ expect(I18n.toNumber(1.98, options)).toBeEqualTo("2");
289
+ });
290
+
291
+ specify("currency with default settings", function(){
292
+ expect(I18n.toCurrency(100.99)).toBeEqualTo("$100.99");
293
+ expect(I18n.toCurrency(1000.99)).toBeEqualTo("$1,000.99");
294
+ });
295
+
296
+ specify("currency with custom settings", function(){
297
+ I18n.translations.en.number = {
298
+ currency: {
299
+ format: {
300
+ format: "%n %u",
301
+ unit: "USD",
302
+ delimiter: ".",
303
+ separator: ",",
304
+ precision: 2
305
+ }
306
+ }
307
+ };
308
+
309
+ expect(I18n.toCurrency(12)).toBeEqualTo("12,00 USD");
310
+ expect(I18n.toCurrency(123)).toBeEqualTo("123,00 USD");
311
+ expect(I18n.toCurrency(1234.56)).toBeEqualTo("1.234,56 USD");
312
+ });
313
+
314
+ specify("currency with custom settings and partial overriding", function(){
315
+ I18n.translations.en.number = {
316
+ currency: {
317
+ format: {
318
+ format: "%n %u",
319
+ unit: "USD",
320
+ delimiter: ".",
321
+ separator: ",",
322
+ precision: 2
323
+ }
324
+ }
325
+ };
326
+
327
+ expect(I18n.toCurrency(12, {precision: 0})).toBeEqualTo("12 USD");
328
+ expect(I18n.toCurrency(123, {unit: "bucks"})).toBeEqualTo("123,00 bucks");
329
+ });
330
+
331
+ specify("currency with some custom options that should be merged with default options", function(){
332
+ expect(I18n.toCurrency(1234, {precision: 0})).toBeEqualTo("$1,234");
333
+ expect(I18n.toCurrency(1234, {unit: "º"})).toBeEqualTo("º1,234.00");
334
+ expect(I18n.toCurrency(1234, {separator: "-"})).toBeEqualTo("$1,234-00");
335
+ expect(I18n.toCurrency(1234, {delimiter: "-"})).toBeEqualTo("$1-234.00");
336
+ expect(I18n.toCurrency(1234, {format: "%u %n"})).toBeEqualTo("$ 1,234.00");
337
+ });
338
+
339
+ specify("localize numbers", function(){
340
+ expect(I18n.l("number", 1234567)).toBeEqualTo("1,234,567.000");
341
+ });
342
+
343
+ specify("localize currency", function(){
344
+ expect(I18n.l("currency", 1234567)).toBeEqualTo("$1,234,567.00");
345
+ });
346
+
347
+ specify("parse date", function(){
348
+ expected = new Date(2009, 0, 24, 0, 0, 0);
349
+ actual = I18n.parseDate("2009-01-24");
350
+ expect(actual.toString()).toBeEqualTo(expected.toString());
351
+
352
+ expected = new Date(2009, 0, 24, 0, 15, 0);
353
+ actual = I18n.parseDate("2009-01-24 00:15:00");
354
+ expect(actual.toString()).toBeEqualTo(expected.toString());
355
+
356
+ expected = new Date(2009, 0, 24, 0, 0, 15);
357
+ actual = I18n.parseDate("2009-01-24 00:00:15");
358
+ expect(actual.toString()).toBeEqualTo(expected.toString());
359
+
360
+ expected = new Date(2009, 0, 24, 15, 33, 44);
361
+ actual = I18n.parseDate("2009-01-24 15:33:44");
362
+ expect(actual.toString()).toBeEqualTo(expected.toString());
363
+
364
+ expected = new Date(2009, 0, 24, 0, 0, 0);
365
+ actual = I18n.parseDate(expected.getTime());
366
+ expect(actual.toString()).toBeEqualTo(expected.toString());
367
+
368
+ expected = new Date(2009, 0, 24, 0, 0, 0);
369
+ actual = I18n.parseDate("01/24/2009");
370
+ expect(actual.toString()).toBeEqualTo(expected.toString());
371
+
372
+ expected = new Date(2009, 0, 24, 14, 33, 55);
373
+ actual = I18n.parseDate(expected).toString();
374
+ expect(actual).toBeEqualTo(expected.toString());
375
+
376
+ expected = new Date(2009, 0, 24, 15, 33, 44);
377
+ actual = I18n.parseDate("2009-01-24T15:33:44");
378
+ expect(actual.toString()).toBeEqualTo(expected.toString());
379
+
380
+ expected = new Date(Date.UTC(2009, 0, 24, 15, 33, 44));
381
+ actual = I18n.parseDate("2009-01-24T15:33:44Z");
382
+ expect(actual.toString()).toBeEqualTo(expected.toString());
383
+ });
384
+
385
+ specify("date formatting", function(){
386
+ I18n.locale = "pt-BR";
387
+
388
+ // 2009-04-26 19:35:44 (Sunday)
389
+ var date = new Date(2009, 3, 26, 19, 35, 44);
390
+
391
+ // short week day
392
+ expect(I18n.strftime(date, "%a")).toBeEqualTo("Dom");
393
+
394
+ // full week day
395
+ expect(I18n.strftime(date, "%A")).toBeEqualTo("Domingo");
396
+
397
+ // short month
398
+ expect(I18n.strftime(date, "%b")).toBeEqualTo("Abr");
399
+
400
+ // full month
401
+ expect(I18n.strftime(date, "%B")).toBeEqualTo("Abril");
402
+
403
+ // day
404
+ expect(I18n.strftime(date, "%d")).toBeEqualTo("26");
405
+
406
+ // 24-hour
407
+ expect(I18n.strftime(date, "%H")).toBeEqualTo("19");
408
+
409
+ // 12-hour
410
+ expect(I18n.strftime(date, "%I")).toBeEqualTo("07");
411
+
412
+ // month
413
+ expect(I18n.strftime(date, "%m")).toBeEqualTo("04");
414
+
415
+ // minutes
416
+ expect(I18n.strftime(date, "%M")).toBeEqualTo("35");
417
+
418
+ // meridian
419
+ expect(I18n.strftime(date, "%p")).toBeEqualTo("PM");
420
+
421
+ // seconds
422
+ expect(I18n.strftime(date, "%S")).toBeEqualTo("44");
423
+
424
+ // week day
425
+ expect(I18n.strftime(date, "%w")).toBeEqualTo("0");
426
+
427
+ // short year
428
+ expect(I18n.strftime(date, "%y")).toBeEqualTo("09");
429
+
430
+ // full year
431
+ expect(I18n.strftime(date, "%Y")).toBeEqualTo("2009");
432
+ });
433
+
434
+ specify("date formatting without padding", function(){
435
+ I18n.locale = "pt-BR";
436
+
437
+ // 2009-04-26 19:35:44 (Sunday)
438
+ var date = new Date(2009, 3, 9, 7, 8, 9);
439
+
440
+ // 24-hour without padding
441
+ expect(I18n.strftime(date, "%-H")).toBeEqualTo("7");
442
+
443
+ // 12-hour without padding
444
+ expect(I18n.strftime(date, "%-I")).toBeEqualTo("7");
445
+
446
+ // minutes without padding
447
+ expect(I18n.strftime(date, "%-M")).toBeEqualTo("8");
448
+
449
+ // seconds without padding
450
+ expect(I18n.strftime(date, "%-S")).toBeEqualTo("9");
451
+
452
+ // short year without padding
453
+ expect(I18n.strftime(date, "%-y")).toBeEqualTo("9");
454
+
455
+ // month without padding
456
+ expect(I18n.strftime(date, "%-m")).toBeEqualTo("4");
457
+
458
+ // day without padding
459
+ expect(I18n.strftime(date, "%-d")).toBeEqualTo("9");
460
+ });
461
+
462
+ specify("date formatting with padding", function(){
463
+ I18n.locale = "pt-BR";
464
+
465
+ // 2009-04-26 19:35:44 (Sunday)
466
+ var date = new Date(2009, 3, 9, 7, 8, 9);
467
+
468
+ // 24-hour
469
+ expect(I18n.strftime(date, "%H")).toBeEqualTo("07");
470
+
471
+ // 12-hour
472
+ expect(I18n.strftime(date, "%I")).toBeEqualTo("07");
473
+
474
+ // minutes
475
+ expect(I18n.strftime(date, "%M")).toBeEqualTo("08");
476
+
477
+ // seconds
478
+ expect(I18n.strftime(date, "%S")).toBeEqualTo("09");
479
+
480
+ // short year
481
+ expect(I18n.strftime(date, "%y")).toBeEqualTo("09");
482
+
483
+ // month
484
+ expect(I18n.strftime(date, "%m")).toBeEqualTo("04");
485
+
486
+ // day
487
+ expect(I18n.strftime(date, "%d")).toBeEqualTo("09");
488
+ });
489
+
490
+ specify("date formatting with negative time zone", function(){
491
+ I18n.locale = "pt-BR";
492
+ var date = new Date(2009, 3, 26, 19, 35, 44);
493
+ stub(date, "getTimezoneOffset()", 345);
494
+
495
+ expect(I18n.strftime(date, "%z")).toMatch(/^(\+|-)[\d]{4}$/);
496
+ expect(I18n.strftime(date, "%z")).toBeEqualTo("-0545");
497
+ });
498
+
499
+ specify("date formatting with positive time zone", function(){
500
+ I18n.locale = "pt-BR";
501
+ var date = new Date(2009, 3, 26, 19, 35, 44);
502
+ stub(date, "getTimezoneOffset()", -345);
503
+
504
+ expect(I18n.strftime(date, "%z")).toMatch(/^(\+|-)[\d]{4}$/);
505
+ expect(I18n.strftime(date, "%z")).toBeEqualTo("+0545");
506
+ });
507
+
508
+ specify("localize date strings", function(){
509
+ I18n.locale = "pt-BR";
510
+
511
+ expect(I18n.l("date.formats.default", "2009-11-29")).toBeEqualTo("29/11/2009");
512
+ expect(I18n.l("date.formats.short", "2009-01-07")).toBeEqualTo("07 de Janeiro");
513
+ expect(I18n.l("date.formats.long", "2009-01-07")).toBeEqualTo("07 de Janeiro de 2009");
514
+ });
515
+
516
+ specify("localize time strings", function(){
517
+ I18n.locale = "pt-BR";
518
+
519
+ expect(I18n.l("time.formats.default", "2009-11-29 15:07:59")).toBeEqualTo("Domingo, 29 de Novembro de 2009, 15:07 h");
520
+ expect(I18n.l("time.formats.short", "2009-01-07 09:12:35")).toBeEqualTo("07/01, 09:12 h");
521
+ expect(I18n.l("time.formats.long", "2009-11-29 15:07:59")).toBeEqualTo("Domingo, 29 de Novembro de 2009, 15:07 h");
522
+ });
523
+
524
+ specify("localize percentage", function(){
525
+ I18n.locale = "pt-BR";
526
+ expect(I18n.l("percentage", 123.45)).toBeEqualTo("123,45%");
527
+ });
528
+
529
+ specify("default value for simple translation", function(){
530
+ actual = I18n.t("warning", {defaultValue: "Warning!"});
531
+ expect(actual).toBeEqualTo("Warning!");
532
+ });
533
+
534
+ specify("default value with interpolation", function(){
535
+ actual = I18n.t(
536
+ "alert",
537
+ {defaultValue: "Attention! {{message}}", message: "You're out of quota!"}
538
+ );
539
+
540
+ expect(actual).toBeEqualTo("Attention! You're out of quota!");
541
+ });
542
+
543
+ specify("default value should not be used when scope exist", function(){
544
+ actual = I18n.t("hello", {defaultValue: "What's up?"});
545
+ expect(actual).toBeEqualTo("Hello World!");
546
+ });
547
+
548
+ specify("default value for pluralize", function(){
549
+ options = {defaultValue: {
550
+ none: "No things here!",
551
+ one: "There is {{count}} thing here!",
552
+ other: "There are {{count}} things here!"
553
+ }};
554
+
555
+ expect(I18n.p(0, "things", options)).toBeEqualTo("No things here!");
556
+ expect(I18n.p(1, "things", options)).toBeEqualTo("There is 1 thing here!");
557
+ expect(I18n.p(5, "things", options)).toBeEqualTo("There are 5 things here!");
558
+ });
559
+
560
+ specify("default value for pluralize should not be used when scope exist", function(){
561
+ options = {defaultValue: {
562
+ none: "No things here!",
563
+ one: "There is {{count}} thing here!",
564
+ other: "There are {{count}} things here!"
565
+ }};
566
+
567
+ expect(I18n.pluralize(0, "inbox", options)).toBeEqualTo("You have no messages");
568
+ expect(I18n.pluralize(1, "inbox", options)).toBeEqualTo("You have 1 message");
569
+ expect(I18n.pluralize(5, "inbox", options)).toBeEqualTo("You have 5 messages");
570
+ });
571
+
572
+ specify("prepare options", function(){
573
+ options = I18n.prepareOptions(
574
+ {name: "Mary Doe"},
575
+ {name: "John Doe", role: "user"}
576
+ );
577
+
578
+ expect(options["name"]).toBeEqualTo("Mary Doe");
579
+ expect(options["role"]).toBeEqualTo("user");
580
+ });
581
+
582
+ specify("prepare options with multiple options", function(){
583
+ options = I18n.prepareOptions(
584
+ {name: "Mary Doe"},
585
+ {name: "John Doe", role: "user"},
586
+ {age: 33},
587
+ {email: "mary@doe.com", url: "http://marydoe.com"},
588
+ {role: "admin", email: "john@doe.com"}
589
+ );
590
+
591
+ expect(options["name"]).toBeEqualTo("Mary Doe");
592
+ expect(options["role"]).toBeEqualTo("user");
593
+ expect(options["age"]).toBeEqualTo(33);
594
+ expect(options["email"]).toBeEqualTo("mary@doe.com");
595
+ expect(options["url"]).toBeEqualTo("http://marydoe.com");
596
+ });
597
+
598
+ specify("prepare options should return an empty hash when values are null", function(){
599
+ expect({}).toBeEqualTo(I18n.prepareOptions(null, null));
600
+ });
601
+
602
+ specify("percentage with defaults", function(){
603
+ expect(I18n.toPercentage(1234)).toBeEqualTo("1234.000%");
604
+ });
605
+
606
+ specify("percentage with custom options", function(){
607
+ actual = I18n.toPercentage(1234, {delimiter: "_", precision: 0});
608
+ expect(actual).toBeEqualTo("1_234%");
609
+ });
610
+
611
+ specify("percentage with translation", function(){
612
+ I18n.translations.en.number = {
613
+ percentage: {
614
+ format: {
615
+ precision: 2,
616
+ delimiter: ".",
617
+ separator: ","
618
+ }
619
+ }
620
+ };
621
+
622
+ expect(I18n.toPercentage(1234)).toBeEqualTo("1.234,00%");
623
+ });
624
+
625
+ specify("percentage with translation and custom options", function(){
626
+ I18n.translations.en.number = {
627
+ percentage: {
628
+ format: {
629
+ precision: 2,
630
+ delimiter: ".",
631
+ separator: ","
632
+ }
633
+ }
634
+ };
635
+
636
+ actual = I18n.toPercentage(1234, {precision: 4, delimiter: "-", separator: "+"});
637
+ expect(actual).toBeEqualTo("1-234+0000%");
638
+ });
639
+
640
+ specify("scope option as string", function(){
641
+ actual = I18n.t("stranger", {scope: "greetings"});
642
+ expect(actual).toBeEqualTo("Hello stranger!");
643
+ });
644
+
645
+ specify("scope as array", function(){
646
+ actual = I18n.t(["greetings", "stranger"]);
647
+ expect(actual).toBeEqualTo("Hello stranger!");
648
+ });
649
+
650
+ specify("new placeholder syntax", function(){
651
+ I18n.translations["en"]["new_syntax"] = "Hi %{name}!";
652
+ actual = I18n.t("new_syntax", {name: "John"});
653
+ expect(actual).toBeEqualTo("Hi John!");
654
+ });
655
+
656
+ specify("return translation for custom scope separator", function(){
657
+ I18n.defaultSeparator = "•";
658
+ actual = I18n.t("greetings•stranger");
659
+ expect(actual).toBeEqualTo("Hello stranger!");
660
+ });
661
+
662
+ specify("return number as human size", function(){
663
+ kb = 1024;
664
+
665
+ expect(I18n.toHumanSize(1)).toBeEqualTo("1Byte");
666
+ expect(I18n.toHumanSize(100)).toBeEqualTo("100Bytes");
667
+
668
+ expect(I18n.toHumanSize(kb)).toBeEqualTo("1KB");
669
+ expect(I18n.toHumanSize(kb * 1.5)).toBeEqualTo("1.5KB");
670
+
671
+ expect(I18n.toHumanSize(kb * kb)).toBeEqualTo("1MB");
672
+ expect(I18n.toHumanSize(kb * kb * 1.5)).toBeEqualTo("1.5MB");
673
+
674
+ expect(I18n.toHumanSize(kb * kb * kb)).toBeEqualTo("1GB");
675
+ expect(I18n.toHumanSize(kb * kb * kb * 1.5)).toBeEqualTo("1.5GB");
676
+
677
+ expect(I18n.toHumanSize(kb * kb * kb * kb)).toBeEqualTo("1TB");
678
+ expect(I18n.toHumanSize(kb * kb * kb * kb * 1.5)).toBeEqualTo("1.5TB");
679
+
680
+ expect(I18n.toHumanSize(kb * kb * kb * kb * kb)).toBeEqualTo("1024TB");
681
+ });
682
+
683
+ specify("return number as human size using custom options", function(){
684
+ expect(I18n.toHumanSize(1024 * 1.6, {precision: 0})).toBeEqualTo("2KB");
685
+ });
686
+ });