i18n-js 3.3.0 → 3.9.2
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.
- checksums.yaml +4 -4
- data/.editorconfig +1 -1
- data/.github/FUNDING.yml +3 -0
- data/.github/workflows/tests.yaml +106 -0
- data/Appraisals +16 -0
- data/CHANGELOG.md +153 -4
- data/README.md +505 -333
- data/app/assets/javascripts/i18n/shims.js +35 -3
- data/app/assets/javascripts/i18n.js +37 -33
- data/gemfiles/i18n_1_10.gemfile +7 -0
- data/gemfiles/i18n_1_7.gemfile +7 -0
- data/gemfiles/i18n_1_8.gemfile +7 -0
- data/gemfiles/i18n_1_9.gemfile +7 -0
- data/i18n-js.gemspec +2 -2
- data/i18njs.png +0 -0
- data/lib/i18n/js/dependencies.rb +6 -2
- data/lib/i18n/js/engine.rb +1 -1
- data/lib/i18n/js/formatters/base.rb +3 -1
- data/lib/i18n/js/formatters/js.rb +12 -4
- data/lib/i18n/js/middleware.rb +1 -1
- data/lib/i18n/js/private/config_store.rb +31 -0
- data/lib/i18n/js/segment.rb +9 -3
- data/lib/i18n/js/utils.rb +34 -8
- data/lib/i18n/js/version.rb +1 -1
- data/lib/i18n/js.rb +25 -10
- data/package.json +2 -2
- data/spec/fixtures/js_available_locales_custom.yml +1 -0
- data/spec/fixtures/{js_file_with_namespace_and_pretty_print.yml → js_file_with_namespace_prefix_and_pretty_print.yml} +2 -0
- data/spec/fixtures/locales.yml +38 -0
- data/spec/fixtures/merge_plurals_with_no_overrides.yml +4 -0
- data/spec/fixtures/merge_plurals_with_partial_overrides.yml +4 -0
- data/spec/fixtures/millions.yml +4 -0
- data/spec/js/dates.spec.js +1 -0
- data/spec/js/json_parsable.spec.js +14 -0
- data/spec/js/localization.spec.js +38 -14
- data/spec/js/numbers.spec.js +4 -0
- data/spec/js/pluralization.spec.js +19 -2
- data/spec/js/require.js +4 -4
- data/spec/js/translate.spec.js +68 -48
- data/spec/js/translations.js +27 -2
- data/spec/ruby/i18n/js/segment_spec.rb +75 -8
- data/spec/ruby/i18n/js/utils_spec.rb +32 -0
- data/spec/ruby/i18n/js_spec.rb +169 -35
- data/spec/spec_helper.rb +1 -0
- data/yarn.lock +32 -25
- metadata +26 -9
- data/.travis.yml +0 -37
data/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "i18n-js",
|
3
|
-
"version": "3.
|
3
|
+
"version": "3.9.2",
|
4
4
|
"description": "A javascript library similar to Ruby on Rails i18n gem",
|
5
5
|
"author": "Nando Vieira",
|
6
6
|
"license": "MIT",
|
@@ -8,7 +8,7 @@
|
|
8
8
|
"i18n"
|
9
9
|
],
|
10
10
|
"devDependencies": {
|
11
|
-
"jasmine-node": "^
|
11
|
+
"jasmine-node": "^3.0.0"
|
12
12
|
},
|
13
13
|
"main": "app/assets/javascripts/i18n.js",
|
14
14
|
"scripts": {
|
@@ -0,0 +1 @@
|
|
1
|
+
js_available_locales: ["en", "foo"]
|
data/spec/fixtures/locales.yml
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
en:
|
2
2
|
number:
|
3
|
+
human:
|
4
|
+
decimal_units:
|
5
|
+
units:
|
6
|
+
million: Million
|
3
7
|
format:
|
4
8
|
separator: "."
|
5
9
|
delimiter: ","
|
@@ -40,6 +44,29 @@ en:
|
|
40
44
|
merge_plurals:
|
41
45
|
one: Apple
|
42
46
|
other: Apples
|
47
|
+
merge_plurals_with_no_overrides:
|
48
|
+
zero: "No Apple"
|
49
|
+
one: Apple
|
50
|
+
other: Apples
|
51
|
+
merge_plurals_with_partial_overrides:
|
52
|
+
one: Cat
|
53
|
+
other: Cats
|
54
|
+
|
55
|
+
es:
|
56
|
+
number:
|
57
|
+
human:
|
58
|
+
decimal_units:
|
59
|
+
units:
|
60
|
+
million:
|
61
|
+
one: millón
|
62
|
+
other: millones
|
63
|
+
|
64
|
+
ru:
|
65
|
+
merge_plurals_with_no_overrides:
|
66
|
+
one: кот
|
67
|
+
few: кошек
|
68
|
+
many: кошка
|
69
|
+
other: кошек
|
43
70
|
|
44
71
|
de:
|
45
72
|
fallback_test: "Erfolg"
|
@@ -89,6 +116,17 @@ fr:
|
|
89
116
|
one: Pomme
|
90
117
|
other: Pommes
|
91
118
|
|
119
|
+
en-US:
|
120
|
+
merge_plurals_with_no_overrides:
|
121
|
+
zero:
|
122
|
+
one:
|
123
|
+
other:
|
124
|
+
merge_plurals_with_partial_overrides:
|
125
|
+
one: Cat
|
126
|
+
few:
|
127
|
+
many:
|
128
|
+
other:
|
129
|
+
|
92
130
|
ja:
|
93
131
|
admin:
|
94
132
|
show:
|
data/spec/js/dates.spec.js
CHANGED
@@ -132,6 +132,7 @@ describe("Dates", function(){
|
|
132
132
|
|
133
133
|
// 24-hour without padding
|
134
134
|
expect(I18n.strftime(date, "%-H")).toEqual("7");
|
135
|
+
expect(I18n.strftime(date, "%k")).toEqual("7");
|
135
136
|
|
136
137
|
// 12-hour without padding
|
137
138
|
expect(I18n.strftime(date, "%-I")).toEqual("7");
|
@@ -0,0 +1,14 @@
|
|
1
|
+
describe("JSON.parse", function () {
|
2
|
+
it('should parse', function () {
|
3
|
+
expect(JSON.parse('{"a":"Test\'s"}')).toEqual({
|
4
|
+
a: "Test's"
|
5
|
+
})
|
6
|
+
|
7
|
+
expect(JSON.parse('{"a":"say \\"hello\\""}')).toEqual({
|
8
|
+
a: 'say "hello"'
|
9
|
+
});
|
10
|
+
expect(JSON.parse('{"double-backslash-in-double-quote":"\\"\\\\\\\\\\""}')).toEqual({
|
11
|
+
'double-backslash-in-double-quote': '"\\\\"'
|
12
|
+
});
|
13
|
+
})
|
14
|
+
})
|
@@ -10,45 +10,69 @@ describe("Localization", function(){
|
|
10
10
|
I18n.translations = Translations();
|
11
11
|
});
|
12
12
|
|
13
|
+
it("sets bound alias", function() {
|
14
|
+
expect(I18n.l).toEqual(jasmine.any(Function));
|
15
|
+
expect(I18n.l).not.toBe(I18n.localize);
|
16
|
+
});
|
17
|
+
|
13
18
|
it("localizes number", function(){
|
14
|
-
expect(I18n.
|
19
|
+
expect(I18n.localize("number", 1234567)).toEqual("1,234,567.000");
|
20
|
+
});
|
21
|
+
|
22
|
+
it("localizes number with 'l' shortcut", function(){
|
23
|
+
var l = I18n.l;
|
24
|
+
expect(l("number", 1234567)).toEqual("1,234,567.000");
|
15
25
|
});
|
16
26
|
|
17
27
|
it("localizes currency", function(){
|
18
|
-
expect(I18n.
|
28
|
+
expect(I18n.localize("currency", 1234567)).toEqual("$1,234,567.00");
|
19
29
|
});
|
20
30
|
|
21
31
|
it("localizes date strings", function(){
|
22
32
|
I18n.locale = "pt-BR";
|
23
33
|
|
24
|
-
expect(I18n.
|
25
|
-
expect(I18n.
|
26
|
-
expect(I18n.
|
34
|
+
expect(I18n.localize("date.formats.default", "2009-11-29")).toEqual("29/11/2009");
|
35
|
+
expect(I18n.localize("date.formats.short", "2009-01-07")).toEqual("07 de Janeiro");
|
36
|
+
expect(I18n.localize("date.formats.long", "2009-01-07")).toEqual("07 de Janeiro de 2009");
|
37
|
+
});
|
38
|
+
|
39
|
+
it("localizes strings with locale from options", function(){
|
40
|
+
I18n.locale = "en";
|
41
|
+
|
42
|
+
expect(I18n.localize("date.formats.default", "2009-11-29", { locale: "pt-BR" })).toEqual("29/11/2009");
|
43
|
+
expect(I18n.localize("date.formats.short", "2009-01-07", { locale: "pt-BR" })).toEqual("07 de Janeiro");
|
44
|
+
expect(I18n.localize("date.formats.long", "2009-01-07", { locale: "pt-BR" })).toEqual("07 de Janeiro de 2009");
|
45
|
+
expect(I18n.localize("time.formats.default", "2009-11-29 15:07:59", { locale: "pt-BR" })).toEqual("Domingo, 29 de Novembro de 2009, 15:07 h");
|
46
|
+
expect(I18n.localize("time.formats.short", "2009-01-07 09:12:35", { locale: "pt-BR" })).toEqual("07/01, 09:12 h");
|
47
|
+
expect(I18n.localize("time.formats.long", "2009-11-29 15:07:59", { locale: "pt-BR" })).toEqual("Domingo, 29 de Novembro de 2009, 15:07 h");
|
48
|
+
expect(I18n.localize("number", 1234567, { locale: "pt-BR" })).toEqual("1,234,567.000");
|
49
|
+
expect(I18n.localize("currency", 1234567, { locale: "pt-BR" })).toEqual("R$ 1.234.567,00");
|
50
|
+
expect(I18n.localize("percentage", 123.45, { locale: "pt-BR" })).toEqual("123,45%");
|
27
51
|
});
|
28
52
|
|
29
53
|
it("localizes time strings", function(){
|
30
54
|
I18n.locale = "pt-BR";
|
31
55
|
|
32
|
-
expect(I18n.
|
33
|
-
expect(I18n.
|
34
|
-
expect(I18n.
|
56
|
+
expect(I18n.localize("time.formats.default", "2009-11-29 15:07:59")).toEqual("Domingo, 29 de Novembro de 2009, 15:07 h");
|
57
|
+
expect(I18n.localize("time.formats.short", "2009-01-07 09:12:35")).toEqual("07/01, 09:12 h");
|
58
|
+
expect(I18n.localize("time.formats.long", "2009-11-29 15:07:59")).toEqual("Domingo, 29 de Novembro de 2009, 15:07 h");
|
35
59
|
});
|
36
60
|
|
37
61
|
it("return 'Invalid Date' or original value for invalid input", function(){
|
38
|
-
expect(I18n.
|
39
|
-
expect(I18n.
|
40
|
-
expect(I18n.
|
62
|
+
expect(I18n.localize("time.formats.default", "")).toEqual("Invalid Date");
|
63
|
+
expect(I18n.localize("time.formats.default", null)).toEqual(null);
|
64
|
+
expect(I18n.localize("time.formats.default", undefined)).toEqual(undefined);
|
41
65
|
});
|
42
66
|
|
43
67
|
it("localizes date/time strings with placeholders", function(){
|
44
68
|
I18n.locale = "pt-BR";
|
45
69
|
|
46
|
-
expect(I18n.
|
47
|
-
expect(I18n.
|
70
|
+
expect(I18n.localize("date.formats.short_with_placeholders", "2009-01-07", { p1: "!", p2: "?" })).toEqual("07 de Janeiro ! ?");
|
71
|
+
expect(I18n.localize("time.formats.short_with_placeholders", "2009-01-07 09:12:35", { p1: "!" })).toEqual("07/01, 09:12 h !");
|
48
72
|
});
|
49
73
|
|
50
74
|
it("localizes percentage", function(){
|
51
75
|
I18n.locale = "pt-BR";
|
52
|
-
expect(I18n.
|
76
|
+
expect(I18n.localize("percentage", 123.45)).toEqual("123,45%");
|
53
77
|
});
|
54
78
|
});
|
data/spec/js/numbers.spec.js
CHANGED
@@ -150,6 +150,10 @@ describe("Numbers", function(){
|
|
150
150
|
expect(I18n.toHumanSize(1024 * 1.6, {precision: 0})).toEqual("2KB");
|
151
151
|
});
|
152
152
|
|
153
|
+
it("returns number as human size using custom scope", function(){
|
154
|
+
expect(I18n.toHumanSize(1024 * 1024, {scope: "extended"})).toEqual("1Megabyte");
|
155
|
+
});
|
156
|
+
|
153
157
|
it("formats numbers with strip insignificant zero", function() {
|
154
158
|
options = {separator: ".", delimiter: ",", strip_insignificant_zeros: true};
|
155
159
|
|
@@ -10,8 +10,9 @@ describe("Pluralization", function(){
|
|
10
10
|
I18n.translations = Translations();
|
11
11
|
});
|
12
12
|
|
13
|
-
it("sets alias", function() {
|
14
|
-
expect(I18n.p).toEqual(
|
13
|
+
it("sets bound alias", function() {
|
14
|
+
expect(I18n.p).toEqual(jasmine.any(Function));
|
15
|
+
expect(I18n.p).not.toBe(I18n.pluralize);
|
15
16
|
});
|
16
17
|
|
17
18
|
it("pluralizes scope", function(){
|
@@ -20,6 +21,13 @@ describe("Pluralization", function(){
|
|
20
21
|
expect(I18n.p(5, "inbox")).toEqual("You have 5 messages");
|
21
22
|
});
|
22
23
|
|
24
|
+
it("pluralizes scope with 'p' shortcut", function(){
|
25
|
+
var p = I18n.p;
|
26
|
+
expect(p(0, "inbox")).toEqual("You have no messages");
|
27
|
+
expect(p(1, "inbox")).toEqual("You have 1 message");
|
28
|
+
expect(p(5, "inbox")).toEqual("You have 5 messages");
|
29
|
+
});
|
30
|
+
|
23
31
|
it("pluralizes using the 'other' scope", function(){
|
24
32
|
I18n.translations["en"]["inbox"]["zero"] = null;
|
25
33
|
expect(I18n.p(0, "inbox")).toEqual("You have 0 messages");
|
@@ -140,6 +148,15 @@ describe("Pluralization", function(){
|
|
140
148
|
expect(I18n.p(5, "inbox", { count: 5 })).toEqual('You have 5 messages');
|
141
149
|
});
|
142
150
|
|
151
|
+
it("fallback to default locale when I18n.fallbacks is enabled and value is null", function() {
|
152
|
+
I18n.locale = "pt-BR";
|
153
|
+
I18n.fallbacks = true;
|
154
|
+
I18n.translations["pt-BR"].inbox = null;
|
155
|
+
expect(I18n.p(0, "inbox", { count: 0 })).toEqual("You have no messages");
|
156
|
+
expect(I18n.p(1, "inbox", { count: 1 })).toEqual("You have 1 message");
|
157
|
+
expect(I18n.p(5, "inbox", { count: 5 })).toEqual("You have 5 messages");
|
158
|
+
});
|
159
|
+
|
143
160
|
it("fallback to 'other' scope", function() {
|
144
161
|
I18n.locale = "pt-BR";
|
145
162
|
I18n.fallbacks = true;
|
data/spec/js/require.js
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/** vim: et:ts=4:sw=4:sts=4
|
2
2
|
* @license RequireJS 2.1.16 Copyright (c) 2010-2015, The Dojo Foundation All Rights Reserved.
|
3
3
|
* Available via the MIT or new BSD license.
|
4
|
-
* see:
|
4
|
+
* see: https://github.com/jrburke/requirejs for details
|
5
5
|
*/
|
6
6
|
//Not using strict: uneven strict support in browsers, #392, and causes
|
7
7
|
//problems with requirejs.exec()/transpiler plugins that may not be strict.
|
@@ -163,7 +163,7 @@ var requirejs, require, define;
|
|
163
163
|
* @returns {Error}
|
164
164
|
*/
|
165
165
|
function makeError(id, msg, err, requireModules) {
|
166
|
-
var e = new Error(msg + '\
|
166
|
+
var e = new Error(msg + '\nhttps://requirejs.org/docs/errors.html#' + id);
|
167
167
|
e.requireType = id;
|
168
168
|
e.requireModules = requireModules;
|
169
169
|
if (err) {
|
@@ -1810,7 +1810,7 @@ var requirejs, require, define;
|
|
1810
1810
|
head = s.head = document.getElementsByTagName('head')[0];
|
1811
1811
|
//If BASE tag is in play, using appendChild is a problem for IE6.
|
1812
1812
|
//When that browser dies, this can be removed. Details in this jQuery bug:
|
1813
|
-
//
|
1813
|
+
//https://dev.jquery.com/ticket/2709
|
1814
1814
|
baseElement = document.getElementsByTagName('base')[0];
|
1815
1815
|
if (baseElement) {
|
1816
1816
|
head = s.head = baseElement.parentNode;
|
@@ -1829,7 +1829,7 @@ var requirejs, require, define;
|
|
1829
1829
|
*/
|
1830
1830
|
req.createNode = function (config, moduleName, url) {
|
1831
1831
|
var node = config.xhtml ?
|
1832
|
-
document.createElementNS('
|
1832
|
+
document.createElementNS('https://www.w3.org/1999/xhtml', 'html:script') :
|
1833
1833
|
document.createElement('script');
|
1834
1834
|
node.type = config.scriptType || 'text/javascript';
|
1835
1835
|
node.charset = 'utf-8';
|
data/spec/js/translate.spec.js
CHANGED
@@ -10,83 +10,98 @@ describe("Translate", function(){
|
|
10
10
|
I18n.translations = Translations();
|
11
11
|
});
|
12
12
|
|
13
|
+
it("sets bound alias", function() {
|
14
|
+
expect(I18n.t).toEqual(jasmine.any(Function));
|
15
|
+
expect(I18n.t).not.toBe(I18n.translate);
|
16
|
+
});
|
17
|
+
|
13
18
|
it("returns translation for single scope", function(){
|
14
|
-
expect(I18n.
|
19
|
+
expect(I18n.translate("hello")).toEqual("Hello World!");
|
20
|
+
});
|
21
|
+
|
22
|
+
it("returns translation with 't' shortcut", function(){
|
23
|
+
var t = I18n.t;
|
24
|
+
expect(t("hello")).toEqual("Hello World!");
|
15
25
|
});
|
16
26
|
|
17
27
|
it("returns translation as object", function(){
|
18
|
-
expect(I18n.
|
28
|
+
expect(I18n.translate("greetings")).toEqual(I18n.translations.en.greetings);
|
19
29
|
});
|
20
30
|
|
21
31
|
it("returns missing message translation for valid scope with null", function(){
|
22
|
-
actual = I18n.
|
32
|
+
actual = I18n.translate("null_key");
|
23
33
|
expected = '[missing "en.null_key" translation]';
|
24
34
|
expect(actual).toEqual(expected);
|
25
35
|
});
|
26
36
|
|
27
37
|
it("returns missing message translation for invalid scope", function(){
|
28
|
-
actual = I18n.
|
38
|
+
actual = I18n.translate("invalid.scope");
|
29
39
|
expected = '[missing "en.invalid.scope" translation]';
|
30
40
|
expect(actual).toEqual(expected);
|
31
41
|
});
|
32
42
|
|
33
43
|
it("returns missing message translation with provided locale for invalid scope", function(){
|
34
|
-
actual = I18n.
|
44
|
+
actual = I18n.translate("invalid.scope", { locale: "ja" });
|
35
45
|
expected = '[missing "ja.invalid.scope" translation]';
|
36
46
|
expect(actual).toEqual(expected);
|
37
47
|
});
|
38
48
|
|
39
49
|
it("returns guessed translation if missingBehaviour is set to guess", function(){
|
40
50
|
I18n.missingBehaviour = 'guess'
|
41
|
-
|
42
|
-
|
43
|
-
|
51
|
+
|
52
|
+
var actual_1 = I18n.translate("invalid.thisIsAutomaticallyGeneratedTranslation");
|
53
|
+
var expected_1 = 'this is automatically generated translation';
|
54
|
+
expect(actual_1).toEqual(expected_1);
|
55
|
+
|
56
|
+
var actual_2 = I18n.translate("invalid.this_is_automatically_generated_translation");
|
57
|
+
var expected_2 = 'this is automatically generated translation';
|
58
|
+
expect(actual_2).toEqual(expected_2);
|
44
59
|
});
|
45
60
|
|
46
61
|
it("returns guessed translation with prefix if missingBehaviour is set to guess and prefix is also provided", function(){
|
47
62
|
I18n.missingBehaviour = 'guess'
|
48
63
|
I18n.missingTranslationPrefix = 'EE: '
|
49
|
-
actual = I18n.
|
64
|
+
actual = I18n.translate("invalid.thisIsAutomaticallyGeneratedTranslation");
|
50
65
|
expected = 'EE: this is automatically generated translation';
|
51
66
|
expect(actual).toEqual(expected);
|
52
67
|
});
|
53
68
|
|
54
69
|
it("returns missing message translation for valid scope with scope", function(){
|
55
|
-
actual = I18n.
|
70
|
+
actual = I18n.translate("monster", {scope: "greetings"});
|
56
71
|
expected = '[missing "en.greetings.monster" translation]';
|
57
72
|
expect(actual).toEqual(expected);
|
58
73
|
});
|
59
74
|
|
60
75
|
it("returns translation for single scope on a custom locale", function(){
|
61
76
|
I18n.locale = "pt-BR";
|
62
|
-
expect(I18n.
|
77
|
+
expect(I18n.translate("hello")).toEqual("Olá Mundo!");
|
63
78
|
});
|
64
79
|
|
65
80
|
it("returns translation for multiple scopes", function(){
|
66
|
-
expect(I18n.
|
81
|
+
expect(I18n.translate("greetings.stranger")).toEqual("Hello stranger!");
|
67
82
|
});
|
68
83
|
|
69
84
|
it("returns translation with default locale option", function(){
|
70
|
-
expect(I18n.
|
71
|
-
expect(I18n.
|
85
|
+
expect(I18n.translate("hello", {locale: "en"})).toEqual("Hello World!");
|
86
|
+
expect(I18n.translate("hello", {locale: "pt-BR"})).toEqual("Olá Mundo!");
|
72
87
|
});
|
73
88
|
|
74
89
|
it("fallbacks to the default locale when I18n.fallbacks is enabled", function(){
|
75
90
|
I18n.locale = "pt-BR";
|
76
91
|
I18n.fallbacks = true;
|
77
|
-
expect(I18n.
|
92
|
+
expect(I18n.translate("greetings.stranger")).toEqual("Hello stranger!");
|
78
93
|
});
|
79
94
|
|
80
95
|
it("fallbacks to default locale when providing an unknown locale", function(){
|
81
96
|
I18n.locale = "fr";
|
82
97
|
I18n.fallbacks = true;
|
83
|
-
expect(I18n.
|
98
|
+
expect(I18n.translate("greetings.stranger")).toEqual("Hello stranger!");
|
84
99
|
});
|
85
100
|
|
86
101
|
it("fallbacks to less specific locale", function(){
|
87
102
|
I18n.locale = "de-DE";
|
88
103
|
I18n.fallbacks = true;
|
89
|
-
expect(I18n.
|
104
|
+
expect(I18n.translate("hello")).toEqual("Hallo Welt!");
|
90
105
|
});
|
91
106
|
|
92
107
|
describe("when a 3-part locale is used", function(){
|
@@ -96,15 +111,15 @@ describe("Translate", function(){
|
|
96
111
|
});
|
97
112
|
|
98
113
|
it("fallbacks to 2-part locale when absent", function(){
|
99
|
-
expect(I18n.
|
114
|
+
expect(I18n.translate("cat")).toEqual("貓");
|
100
115
|
});
|
101
116
|
|
102
117
|
it("fallbacks to 1-part locale when 2-part missing requested translation", function(){
|
103
|
-
expect(I18n.
|
118
|
+
expect(I18n.translate("dog")).toEqual("狗");
|
104
119
|
});
|
105
120
|
|
106
121
|
it("fallbacks to 2-part for the first time", function(){
|
107
|
-
expect(I18n.
|
122
|
+
expect(I18n.translate("dragon")).toEqual("龍");
|
108
123
|
});
|
109
124
|
});
|
110
125
|
|
@@ -115,7 +130,7 @@ describe("Translate", function(){
|
|
115
130
|
return ["nb"];
|
116
131
|
};
|
117
132
|
|
118
|
-
expect(I18n.
|
133
|
+
expect(I18n.translate("hello")).toEqual("Hei Verden!");
|
119
134
|
});
|
120
135
|
|
121
136
|
it("fallbacks using custom rules (array)", function() {
|
@@ -123,7 +138,7 @@ describe("Translate", function(){
|
|
123
138
|
I18n.fallbacks = true;
|
124
139
|
I18n.locales["no"] = ["no", "nb"];
|
125
140
|
|
126
|
-
expect(I18n.
|
141
|
+
expect(I18n.translate("hello")).toEqual("Hei Verden!");
|
127
142
|
});
|
128
143
|
|
129
144
|
it("fallbacks using custom rules (string)", function() {
|
@@ -131,25 +146,25 @@ describe("Translate", function(){
|
|
131
146
|
I18n.fallbacks = true;
|
132
147
|
I18n.locales["no"] = "nb";
|
133
148
|
|
134
|
-
expect(I18n.
|
149
|
+
expect(I18n.translate("hello")).toEqual("Hei Verden!");
|
135
150
|
});
|
136
151
|
|
137
152
|
describe("when provided default values", function() {
|
138
153
|
it("uses scope provided in defaults if scope doesn't exist", function() {
|
139
|
-
actual = I18n.
|
154
|
+
actual = I18n.translate("Hello!", {defaults: [{scope: "greetings.stranger"}]});
|
140
155
|
expect(actual).toEqual("Hello stranger!");
|
141
156
|
});
|
142
157
|
|
143
158
|
it("continues to fallback until a scope is found", function() {
|
144
159
|
var defaults = [{scope: "foo"}, {scope: "hello"}];
|
145
160
|
|
146
|
-
actual = I18n.
|
161
|
+
actual = I18n.translate("foo", {defaults: defaults});
|
147
162
|
expect(actual).toEqual("Hello World!");
|
148
163
|
});
|
149
164
|
|
150
165
|
it("uses message if specified as a default", function() {
|
151
166
|
var defaults = [{message: "Hello all!"}];
|
152
|
-
actual = I18n.
|
167
|
+
actual = I18n.translate("foo", {defaults: defaults});
|
153
168
|
expect(actual).toEqual("Hello all!");
|
154
169
|
});
|
155
170
|
|
@@ -158,7 +173,7 @@ describe("Translate", function(){
|
|
158
173
|
{scope: "bar"}
|
159
174
|
, {message: "Hello all!"}
|
160
175
|
, {scope: "hello"}];
|
161
|
-
actual = I18n.
|
176
|
+
actual = I18n.translate("foo", {defaults: defaults});
|
162
177
|
expect(actual).toEqual("Hello all!");
|
163
178
|
});
|
164
179
|
|
@@ -167,7 +182,7 @@ describe("Translate", function(){
|
|
167
182
|
defaults: [{scope: "bar"}]
|
168
183
|
, defaultValue: "Hello all!"
|
169
184
|
};
|
170
|
-
actual = I18n.
|
185
|
+
actual = I18n.translate("foo", options);
|
171
186
|
expect(actual).toEqual("Hello all!");
|
172
187
|
});
|
173
188
|
|
@@ -176,7 +191,7 @@ describe("Translate", function(){
|
|
176
191
|
defaults: [{scope: "hello"}]
|
177
192
|
, defaultValue: "Hello all!"
|
178
193
|
};
|
179
|
-
actual = I18n.
|
194
|
+
actual = I18n.translate("foo", options);
|
180
195
|
expect(actual).toEqual("Hello World!");
|
181
196
|
})
|
182
197
|
|
@@ -187,36 +202,36 @@ describe("Translate", function(){
|
|
187
202
|
return scope.toUpperCase();
|
188
203
|
}
|
189
204
|
};
|
190
|
-
actual = I18n.
|
205
|
+
actual = I18n.translate("foo", options);
|
191
206
|
expect(actual).toEqual("FOO");
|
192
207
|
})
|
193
208
|
|
194
209
|
it("pluralizes using the correct scope if translation is found within default scope", function() {
|
195
210
|
expect(I18n.translations["en"]["mailbox"]).toEqual(undefined);
|
196
|
-
actual = I18n.
|
197
|
-
expected = I18n.
|
211
|
+
actual = I18n.translate("mailbox.inbox", {count: 1, defaults: [{scope: "inbox"}]});
|
212
|
+
expected = I18n.translate("inbox", {count: 1})
|
198
213
|
expect(actual).toEqual(expected)
|
199
214
|
})
|
200
215
|
});
|
201
216
|
|
202
217
|
it("uses default value for simple translation", function(){
|
203
|
-
actual = I18n.
|
218
|
+
actual = I18n.translate("warning", {defaultValue: "Warning!"});
|
204
219
|
expect(actual).toEqual("Warning!");
|
205
220
|
});
|
206
221
|
|
207
222
|
it("uses default value for plural translation", function(){
|
208
|
-
actual = I18n.
|
223
|
+
actual = I18n.translate("message", {defaultValue: { one: '%{count} message', other: '%{count} messages'}, count: 1});
|
209
224
|
expect(actual).toEqual("1 message");
|
210
225
|
});
|
211
226
|
|
212
227
|
it("uses default value for unknown locale", function(){
|
213
228
|
I18n.locale = "fr";
|
214
|
-
actual = I18n.
|
229
|
+
actual = I18n.translate("warning", {defaultValue: "Warning!"});
|
215
230
|
expect(actual).toEqual("Warning!");
|
216
231
|
});
|
217
232
|
|
218
233
|
it("uses default value with interpolation", function(){
|
219
|
-
actual = I18n.
|
234
|
+
actual = I18n.translate(
|
220
235
|
"alert",
|
221
236
|
{defaultValue: "Attention! {{message}}", message: "You're out of quota!"}
|
222
237
|
);
|
@@ -225,33 +240,33 @@ describe("Translate", function(){
|
|
225
240
|
});
|
226
241
|
|
227
242
|
it("ignores default value when scope exists", function(){
|
228
|
-
actual = I18n.
|
243
|
+
actual = I18n.translate("hello", {defaultValue: "What's up?"});
|
229
244
|
expect(actual).toEqual("Hello World!");
|
230
245
|
});
|
231
246
|
|
232
247
|
it("returns translation for custom scope separator", function(){
|
233
248
|
I18n.defaultSeparator = "•";
|
234
|
-
actual = I18n.
|
249
|
+
actual = I18n.translate("greetings•stranger");
|
235
250
|
expect(actual).toEqual("Hello stranger!");
|
236
251
|
});
|
237
252
|
|
238
253
|
it("returns boolean values", function() {
|
239
|
-
expect(I18n.
|
240
|
-
expect(I18n.
|
254
|
+
expect(I18n.translate("booleans.yes")).toEqual(true);
|
255
|
+
expect(I18n.translate("booleans.no")).toEqual(false);
|
241
256
|
});
|
242
257
|
|
243
258
|
it("escapes $ when doing substitution (IE)", function(){
|
244
259
|
I18n.locale = "en";
|
245
260
|
|
246
|
-
expect(I18n.
|
247
|
-
expect(I18n.
|
248
|
-
expect(I18n.
|
261
|
+
expect(I18n.translate("paid", {price: "$0"})).toEqual("You were paid $0");
|
262
|
+
expect(I18n.translate("paid", {price: "$0.12"})).toEqual("You were paid $0.12");
|
263
|
+
expect(I18n.translate("paid", {price: "$1.35"})).toEqual("You were paid $1.35");
|
249
264
|
});
|
250
265
|
|
251
266
|
it("replaces all occurrences of escaped $", function(){
|
252
267
|
I18n.locale = "en";
|
253
268
|
|
254
|
-
expect(I18n.
|
269
|
+
expect(I18n.translate("paid_with_vat", {
|
255
270
|
price: "$0.12",
|
256
271
|
vat: "$0.02"}
|
257
272
|
)).toEqual("You were paid $0.12 (incl. VAT $0.02)");
|
@@ -259,20 +274,20 @@ describe("Translate", function(){
|
|
259
274
|
|
260
275
|
it("sets default scope", function(){
|
261
276
|
var options = {scope: "greetings"};
|
262
|
-
expect(I18n.
|
277
|
+
expect(I18n.translate("stranger", options)).toEqual("Hello stranger!");
|
263
278
|
});
|
264
279
|
|
265
280
|
it("accepts the scope as an array", function(){
|
266
|
-
expect(I18n.
|
281
|
+
expect(I18n.translate(["greetings", "stranger"])).toEqual("Hello stranger!");
|
267
282
|
});
|
268
283
|
|
269
284
|
it("accepts the scope as an array using a base scope", function(){
|
270
|
-
expect(I18n.
|
285
|
+
expect(I18n.translate(["stranger"], {scope: "greetings"})).toEqual("Hello stranger!");
|
271
286
|
});
|
272
287
|
|
273
288
|
it("returns an array with values interpolated", function(){
|
274
289
|
var options = {value: 314};
|
275
|
-
expect(I18n.
|
290
|
+
expect(I18n.translate("arrayWithParams", options)).toEqual([
|
276
291
|
null,
|
277
292
|
"An item with a param of " + options.value,
|
278
293
|
"Another item with a param of " + options.value,
|
@@ -281,4 +296,9 @@ describe("Translate", function(){
|
|
281
296
|
{foo: "bar"}
|
282
297
|
]);
|
283
298
|
});
|
299
|
+
|
300
|
+
|
301
|
+
it("returns value with key containing dot but different separator specified", function() {
|
302
|
+
expect(I18n.t(["A implies B means something."], {scope: "sentences_with_dots", separator: "|"})).toEqual("A implies B means that when A is true, B must be true.");
|
303
|
+
});
|
284
304
|
});
|