i18n-js-pika 3.0.0.rc6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/CHANGELOG.md +13 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +52 -0
- data/README.md +326 -0
- data/Rakefile +13 -0
- data/app/assets/javascripts/i18n/filtered.js.erb +2 -0
- data/app/assets/javascripts/i18n/shims.js +93 -0
- data/app/assets/javascripts/i18n/translations.js +3 -0
- data/app/assets/javascripts/i18n.js +690 -0
- data/i18n-js.gemspec +27 -0
- data/lib/i18n/js/engine.rb +22 -0
- data/lib/i18n/js/middleware.rb +59 -0
- data/lib/i18n/js/version.rb +12 -0
- data/lib/i18n/js.rb +162 -0
- data/lib/i18n-js.rb +1 -0
- data/lib/tasks/export.rake +8 -0
- data/package.json +11 -0
- data/spec/fixtures/custom_path.yml +4 -0
- data/spec/fixtures/default.yml +4 -0
- data/spec/fixtures/js_file_per_locale.yml +3 -0
- data/spec/fixtures/locales.yml +76 -0
- data/spec/fixtures/multiple_conditions.yml +5 -0
- data/spec/fixtures/multiple_files.yml +6 -0
- data/spec/fixtures/no_config.yml +2 -0
- data/spec/fixtures/no_scope.yml +3 -0
- data/spec/fixtures/simple_scope.yml +4 -0
- data/spec/i18n_js_spec.rb +139 -0
- data/spec/js/currency.spec.js +60 -0
- data/spec/js/current_locale.spec.js +19 -0
- data/spec/js/dates.spec.js +222 -0
- data/spec/js/defaults.spec.js +23 -0
- data/spec/js/interpolation.spec.js +28 -0
- data/spec/js/jasmine/MIT.LICENSE +20 -0
- data/spec/js/jasmine/jasmine-html.js +190 -0
- data/spec/js/jasmine/jasmine.css +166 -0
- data/spec/js/jasmine/jasmine.js +2476 -0
- data/spec/js/jasmine/jasmine_favicon.png +0 -0
- data/spec/js/localization.spec.js +41 -0
- data/spec/js/numbers.spec.js +142 -0
- data/spec/js/placeholder.spec.js +24 -0
- data/spec/js/pluralization.spec.js +105 -0
- data/spec/js/prepare_options.spec.js +41 -0
- data/spec/js/specs.html +46 -0
- data/spec/js/translate.spec.js +120 -0
- data/spec/js/translations.js +120 -0
- data/spec/spec_helper.rb +41 -0
- metadata +196 -0
Binary file
|
@@ -0,0 +1,41 @@
|
|
1
|
+
var I18n = require("../../app/assets/javascripts/i18n")
|
2
|
+
, Translations = require("./translations")
|
3
|
+
;
|
4
|
+
|
5
|
+
describe("Localization", function(){
|
6
|
+
var actual, expected;
|
7
|
+
|
8
|
+
beforeEach(function() {
|
9
|
+
I18n.reset();
|
10
|
+
I18n.translations = Translations();
|
11
|
+
});
|
12
|
+
|
13
|
+
it("localizes number", function(){
|
14
|
+
expect(I18n.l("number", 1234567)).toEqual("1,234,567.000");
|
15
|
+
});
|
16
|
+
|
17
|
+
it("localizes currency", function(){
|
18
|
+
expect(I18n.l("currency", 1234567)).toEqual("$1,234,567.00");
|
19
|
+
});
|
20
|
+
|
21
|
+
it("localizes date strings", function(){
|
22
|
+
I18n.locale = "pt-BR";
|
23
|
+
|
24
|
+
expect(I18n.l("date.formats.default", "2009-11-29")).toEqual("29/11/2009");
|
25
|
+
expect(I18n.l("date.formats.short", "2009-01-07")).toEqual("07 de Janeiro");
|
26
|
+
expect(I18n.l("date.formats.long", "2009-01-07")).toEqual("07 de Janeiro de 2009");
|
27
|
+
});
|
28
|
+
|
29
|
+
it("localizes time strings", function(){
|
30
|
+
I18n.locale = "pt-BR";
|
31
|
+
|
32
|
+
expect(I18n.l("time.formats.default", "2009-11-29 15:07:59")).toEqual("Domingo, 29 de Novembro de 2009, 15:07 h");
|
33
|
+
expect(I18n.l("time.formats.short", "2009-01-07 09:12:35")).toEqual("07/01, 09:12 h");
|
34
|
+
expect(I18n.l("time.formats.long", "2009-11-29 15:07:59")).toEqual("Domingo, 29 de Novembro de 2009, 15:07 h");
|
35
|
+
});
|
36
|
+
|
37
|
+
it("localizes percentage", function(){
|
38
|
+
I18n.locale = "pt-BR";
|
39
|
+
expect(I18n.l("percentage", 123.45)).toEqual("123,45%");
|
40
|
+
});
|
41
|
+
});
|
@@ -0,0 +1,142 @@
|
|
1
|
+
var I18n = require("../../app/assets/javascripts/i18n")
|
2
|
+
, Translations = require("./translations")
|
3
|
+
;
|
4
|
+
|
5
|
+
describe("Numbers", function(){
|
6
|
+
var actual, expected;
|
7
|
+
|
8
|
+
beforeEach(function() {
|
9
|
+
I18n.reset();
|
10
|
+
I18n.translations = Translations();
|
11
|
+
});
|
12
|
+
|
13
|
+
it("formats number with default settings", function(){
|
14
|
+
expect(I18n.toNumber(1)).toEqual("1.000");
|
15
|
+
expect(I18n.toNumber(12)).toEqual("12.000");
|
16
|
+
expect(I18n.toNumber(123)).toEqual("123.000");
|
17
|
+
expect(I18n.toNumber(1234)).toEqual("1,234.000");
|
18
|
+
expect(I18n.toNumber(12345)).toEqual("12,345.000");
|
19
|
+
expect(I18n.toNumber(123456)).toEqual("123,456.000");
|
20
|
+
expect(I18n.toNumber(1234567)).toEqual("1,234,567.000");
|
21
|
+
expect(I18n.toNumber(12345678)).toEqual("12,345,678.000");
|
22
|
+
expect(I18n.toNumber(123456789)).toEqual("123,456,789.000");
|
23
|
+
});
|
24
|
+
|
25
|
+
it("formats negative numbers with default settings", function(){
|
26
|
+
expect(I18n.toNumber(-1)).toEqual("-1.000");
|
27
|
+
expect(I18n.toNumber(-12)).toEqual("-12.000");
|
28
|
+
expect(I18n.toNumber(-123)).toEqual("-123.000");
|
29
|
+
expect(I18n.toNumber(-1234)).toEqual("-1,234.000");
|
30
|
+
expect(I18n.toNumber(-12345)).toEqual("-12,345.000");
|
31
|
+
expect(I18n.toNumber(-123456)).toEqual("-123,456.000");
|
32
|
+
expect(I18n.toNumber(-1234567)).toEqual("-1,234,567.000");
|
33
|
+
expect(I18n.toNumber(-12345678)).toEqual("-12,345,678.000");
|
34
|
+
expect(I18n.toNumber(-123456789)).toEqual("-123,456,789.000");
|
35
|
+
});
|
36
|
+
|
37
|
+
it("formats number with partial translation and default options", function(){
|
38
|
+
I18n.translations.en.number = {
|
39
|
+
format: {
|
40
|
+
precision: 2
|
41
|
+
}
|
42
|
+
};
|
43
|
+
|
44
|
+
expect(I18n.toNumber(1234)).toEqual("1,234.00");
|
45
|
+
});
|
46
|
+
|
47
|
+
it("formats number with full translation and default options", function(){
|
48
|
+
I18n.translations.en.number = {
|
49
|
+
format: {
|
50
|
+
delimiter: ".",
|
51
|
+
separator: ",",
|
52
|
+
precision: 2
|
53
|
+
}
|
54
|
+
};
|
55
|
+
|
56
|
+
expect(I18n.toNumber(1234)).toEqual("1.234,00");
|
57
|
+
});
|
58
|
+
|
59
|
+
it("formats numbers with some custom options that should be merged with default options", function(){
|
60
|
+
expect(I18n.toNumber(1234.56, {precision: 0})).toEqual("1,235");
|
61
|
+
expect(I18n.toNumber(1234, {separator: '-'})).toEqual("1,234-000");
|
62
|
+
expect(I18n.toNumber(1234, {delimiter: '_'})).toEqual("1_234.000");
|
63
|
+
});
|
64
|
+
|
65
|
+
it("formats number considering options", function(){
|
66
|
+
options = {
|
67
|
+
precision: 2,
|
68
|
+
separator: ",",
|
69
|
+
delimiter: "."
|
70
|
+
};
|
71
|
+
|
72
|
+
expect(I18n.toNumber(1, options)).toEqual("1,00");
|
73
|
+
expect(I18n.toNumber(12, options)).toEqual("12,00");
|
74
|
+
expect(I18n.toNumber(123, options)).toEqual("123,00");
|
75
|
+
expect(I18n.toNumber(1234, options)).toEqual("1.234,00");
|
76
|
+
expect(I18n.toNumber(123456, options)).toEqual("123.456,00");
|
77
|
+
expect(I18n.toNumber(1234567, options)).toEqual("1.234.567,00");
|
78
|
+
expect(I18n.toNumber(12345678, options)).toEqual("12.345.678,00");
|
79
|
+
});
|
80
|
+
|
81
|
+
it("formats numbers with different precisions", function(){
|
82
|
+
options = {separator: ".", delimiter: ","};
|
83
|
+
|
84
|
+
options["precision"] = 2;
|
85
|
+
expect(I18n.toNumber(1.98, options)).toEqual("1.98");
|
86
|
+
|
87
|
+
options["precision"] = 3;
|
88
|
+
expect(I18n.toNumber(1.98, options)).toEqual("1.980");
|
89
|
+
|
90
|
+
options["precision"] = 2;
|
91
|
+
expect(I18n.toNumber(1.987, options)).toEqual("1.99");
|
92
|
+
|
93
|
+
options["precision"] = 1;
|
94
|
+
expect(I18n.toNumber(1.98, options)).toEqual("2.0");
|
95
|
+
|
96
|
+
options["precision"] = 0;
|
97
|
+
expect(I18n.toNumber(1.98, options)).toEqual("2");
|
98
|
+
});
|
99
|
+
|
100
|
+
it("returns number as human size", function(){
|
101
|
+
var kb = 1024;
|
102
|
+
|
103
|
+
expect(I18n.toHumanSize(1)).toEqual("1Byte");
|
104
|
+
expect(I18n.toHumanSize(100)).toEqual("100Bytes");
|
105
|
+
|
106
|
+
expect(I18n.toHumanSize(kb)).toEqual("1KB");
|
107
|
+
expect(I18n.toHumanSize(kb * 1.5)).toEqual("1.5KB");
|
108
|
+
|
109
|
+
expect(I18n.toHumanSize(kb * kb)).toEqual("1MB");
|
110
|
+
expect(I18n.toHumanSize(kb * kb * 1.5)).toEqual("1.5MB");
|
111
|
+
|
112
|
+
expect(I18n.toHumanSize(kb * kb * kb)).toEqual("1GB");
|
113
|
+
expect(I18n.toHumanSize(kb * kb * kb * 1.5)).toEqual("1.5GB");
|
114
|
+
|
115
|
+
expect(I18n.toHumanSize(kb * kb * kb * kb)).toEqual("1TB");
|
116
|
+
expect(I18n.toHumanSize(kb * kb * kb * kb * 1.5)).toEqual("1.5TB");
|
117
|
+
|
118
|
+
expect(I18n.toHumanSize(kb * kb * kb * kb * kb)).toEqual("1024TB");
|
119
|
+
});
|
120
|
+
|
121
|
+
it("returns number as human size using custom options", function(){
|
122
|
+
expect(I18n.toHumanSize(1024 * 1.6, {precision: 0})).toEqual("2KB");
|
123
|
+
});
|
124
|
+
|
125
|
+
it("formats numbers with strip insignificant zero", function() {
|
126
|
+
options = {separator: ".", delimiter: ",", strip_insignificant_zeros: true};
|
127
|
+
|
128
|
+
options["precision"] = 2;
|
129
|
+
expect(I18n.toNumber(1.0, options)).toEqual("1");
|
130
|
+
|
131
|
+
options["precision"] = 3;
|
132
|
+
expect(I18n.toNumber(1.98, options)).toEqual("1.98");
|
133
|
+
|
134
|
+
options["precision"] = 4;
|
135
|
+
expect(I18n.toNumber(1.987, options)).toEqual("1.987");
|
136
|
+
});
|
137
|
+
|
138
|
+
it("keeps significant zeros [issue#103]", function() {
|
139
|
+
actual = I18n.toNumber(30, {strip_insignificant_zeros: true, precision: 0});
|
140
|
+
expect(actual).toEqual("30");
|
141
|
+
});
|
142
|
+
});
|
@@ -0,0 +1,24 @@
|
|
1
|
+
var I18n = require("../../app/assets/javascripts/i18n");
|
2
|
+
|
3
|
+
describe("Placeholder", function(){
|
4
|
+
beforeEach(function(){
|
5
|
+
I18n.reset();
|
6
|
+
});
|
7
|
+
|
8
|
+
it("matches {{name}}", function(){
|
9
|
+
expect("{{name}}").toMatch(I18n.placeholder);
|
10
|
+
});
|
11
|
+
|
12
|
+
it("matches %{name}", function(){
|
13
|
+
expect("%{name}").toMatch(I18n.placeholder);
|
14
|
+
});
|
15
|
+
|
16
|
+
it("returns placeholders", function(){
|
17
|
+
var translation = "I like %{javascript}. I also like %{ruby}"
|
18
|
+
, matches = translation.match(I18n.placeholder);
|
19
|
+
;
|
20
|
+
|
21
|
+
expect(matches[0]).toEqual("%{javascript}");
|
22
|
+
expect(matches[1]).toEqual("%{ruby}");
|
23
|
+
});
|
24
|
+
});
|
@@ -0,0 +1,105 @@
|
|
1
|
+
var I18n = require("../../app/assets/javascripts/i18n")
|
2
|
+
, Translations = require("./translations")
|
3
|
+
;
|
4
|
+
|
5
|
+
describe("Pluralization", function(){
|
6
|
+
var actual, expected;
|
7
|
+
|
8
|
+
beforeEach(function(){
|
9
|
+
I18n.reset();
|
10
|
+
I18n.translations = Translations();
|
11
|
+
});
|
12
|
+
|
13
|
+
it("sets alias", function() {
|
14
|
+
expect(I18n.p).toEqual(I18n.pluralize);
|
15
|
+
});
|
16
|
+
|
17
|
+
it("pluralizes scope", function(){
|
18
|
+
expect(I18n.p(0, "inbox")).toEqual("You have no messages");
|
19
|
+
expect(I18n.p(1, "inbox")).toEqual("You have 1 message");
|
20
|
+
expect(I18n.p(5, "inbox")).toEqual("You have 5 messages");
|
21
|
+
});
|
22
|
+
|
23
|
+
it("pluralizes using the 'other' scope", function(){
|
24
|
+
I18n.translations["en"]["inbox"]["zero"] = null;
|
25
|
+
expect(I18n.p(0, "inbox")).toEqual("You have 0 messages");
|
26
|
+
});
|
27
|
+
|
28
|
+
it("pluralizes using the 'zero' scope", function(){
|
29
|
+
I18n.translations["en"]["inbox"]["zero"] = "No messages (zero)";
|
30
|
+
|
31
|
+
expect(I18n.p(0, "inbox")).toEqual("No messages (zero)");
|
32
|
+
});
|
33
|
+
|
34
|
+
it("pluralizes using negative values", function(){
|
35
|
+
expect(I18n.p(-1, "inbox")).toEqual("You have -1 message");
|
36
|
+
expect(I18n.p(-5, "inbox")).toEqual("You have -5 messages");
|
37
|
+
});
|
38
|
+
|
39
|
+
it("returns missing translation", function(){
|
40
|
+
expect(I18n.p(-1, "missing")).toEqual('[missing "en.missing" translation]');
|
41
|
+
});
|
42
|
+
|
43
|
+
it("pluralizes using multiple placeholders", function(){
|
44
|
+
actual = I18n.p(1, "unread", {unread: 5});
|
45
|
+
expect(actual).toEqual("You have 1 new message (5 unread)");
|
46
|
+
|
47
|
+
actual = I18n.p(10, "unread", {unread: 2});
|
48
|
+
expect(actual).toEqual("You have 10 new messages (2 unread)");
|
49
|
+
|
50
|
+
actual = I18n.p(0, "unread", {unread: 5});
|
51
|
+
expect(actual).toEqual("You have no new messages (5 unread)");
|
52
|
+
});
|
53
|
+
|
54
|
+
it("allows empty strings", function(){
|
55
|
+
I18n.translations["en"]["inbox"]["zero"] = "";
|
56
|
+
|
57
|
+
expect(I18n.p(0, "inbox")).toEqual("");
|
58
|
+
});
|
59
|
+
|
60
|
+
it("pluralizes using custom rules", function() {
|
61
|
+
I18n.locale = "custom";
|
62
|
+
|
63
|
+
I18n.pluralization["custom"] = function(count) {
|
64
|
+
if (count === 0) { return ["zero"]; }
|
65
|
+
if (count >= 1 && count <= 5) { return ["few", "other"]; }
|
66
|
+
return ["other"];
|
67
|
+
};
|
68
|
+
|
69
|
+
I18n.translations["custom"] = {
|
70
|
+
"things": {
|
71
|
+
"zero": "No things"
|
72
|
+
, "few": "A few things"
|
73
|
+
, "other": "%{count} things"
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
expect(I18n.p(0, "things")).toEqual("No things");
|
78
|
+
expect(I18n.p(4, "things")).toEqual("A few things");
|
79
|
+
expect(I18n.p(10, "things")).toEqual("10 things");
|
80
|
+
});
|
81
|
+
|
82
|
+
it("pluralizes default value", function(){
|
83
|
+
options = {defaultValue: {
|
84
|
+
zero: "No things here!"
|
85
|
+
, one: "There is {{count}} thing here!"
|
86
|
+
, other: "There are {{count}} things here!"
|
87
|
+
}};
|
88
|
+
|
89
|
+
expect(I18n.p(0, "things", options)).toEqual("No things here!");
|
90
|
+
expect(I18n.p(1, "things", options)).toEqual("There is 1 thing here!");
|
91
|
+
expect(I18n.p(5, "things", options)).toEqual("There are 5 things here!");
|
92
|
+
});
|
93
|
+
|
94
|
+
it("ignores pluralization when scope exists", function(){
|
95
|
+
options = {defaultValue: {
|
96
|
+
zero: "No things here!"
|
97
|
+
, one: "There is {{count}} thing here!"
|
98
|
+
, other: "There are {{count}} things here!"
|
99
|
+
}};
|
100
|
+
|
101
|
+
expect(I18n.p(0, "inbox", options)).toEqual("You have no messages");
|
102
|
+
expect(I18n.p(1, "inbox", options)).toEqual("You have 1 message");
|
103
|
+
expect(I18n.p(5, "inbox", options)).toEqual("You have 5 messages");
|
104
|
+
});
|
105
|
+
});
|
@@ -0,0 +1,41 @@
|
|
1
|
+
var I18n = require("../../app/assets/javascripts/i18n");
|
2
|
+
|
3
|
+
describe("Prepare options", function(){
|
4
|
+
beforeEach(function(){
|
5
|
+
I18n.reset();
|
6
|
+
});
|
7
|
+
|
8
|
+
it("merges two objects", function(){
|
9
|
+
var options = I18n.prepareOptions(
|
10
|
+
{name: "Mary Doe"},
|
11
|
+
{name: "John Doe", role: "user"}
|
12
|
+
);
|
13
|
+
|
14
|
+
expect(options.name).toEqual("Mary Doe");
|
15
|
+
expect(options.role).toEqual("user");
|
16
|
+
});
|
17
|
+
|
18
|
+
it("merges multiple objects", function(){
|
19
|
+
var options = I18n.prepareOptions(
|
20
|
+
{name: "Mary Doe"},
|
21
|
+
{name: "John Doe", role: "user"},
|
22
|
+
{age: 33},
|
23
|
+
{email: "mary@doe.com", url: "http://marydoe.com"},
|
24
|
+
{role: "admin", email: "john@doe.com"}
|
25
|
+
);
|
26
|
+
|
27
|
+
expect(options.name).toEqual("Mary Doe");
|
28
|
+
expect(options.role).toEqual("user");
|
29
|
+
expect(options.age).toEqual(33);
|
30
|
+
expect(options.email).toEqual("mary@doe.com");
|
31
|
+
expect(options.url).toEqual("http://marydoe.com");
|
32
|
+
});
|
33
|
+
|
34
|
+
it("returns an empty object when values are null", function(){
|
35
|
+
expect(I18n.prepareOptions(null, null)).toEqual({});
|
36
|
+
});
|
37
|
+
|
38
|
+
it("returns an empty object when values are undefined", function(){
|
39
|
+
expect(I18n.prepareOptions(undefined, undefined)).toEqual({});
|
40
|
+
});
|
41
|
+
});
|
data/spec/js/specs.html
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="UTF-8">
|
5
|
+
<title>Jasmine Spec Runner</title>
|
6
|
+
<link rel="stylesheet" href="jasmine/jasmine.css" type="text/css">
|
7
|
+
</head>
|
8
|
+
|
9
|
+
<body>
|
10
|
+
<!-- load jasmine -->
|
11
|
+
<script type="text/javascript" src="jasmine/jasmine.js"></script>
|
12
|
+
<script type="text/javascript" src="jasmine/jasmine-html.js"></script>
|
13
|
+
|
14
|
+
<!-- load your javascript files -->
|
15
|
+
<script type="text/javascript" src="../../app/assets/javascripts/i18n.js"></script>
|
16
|
+
<script type="text/javascript">
|
17
|
+
function require(path) {
|
18
|
+
if (path.match(/i18n/)) {
|
19
|
+
return I18n;
|
20
|
+
} else {
|
21
|
+
return Translations;
|
22
|
+
}
|
23
|
+
}
|
24
|
+
</script>
|
25
|
+
|
26
|
+
<!-- load your spec files -->
|
27
|
+
<script type="text/javascript" src="translations.js"></script>
|
28
|
+
<script type="text/javascript" src="currency.spec.js"></script>
|
29
|
+
<script type="text/javascript" src="current_locale.spec.js"></script>
|
30
|
+
<script type="text/javascript" src="dates.spec.js"></script>
|
31
|
+
<script type="text/javascript" src="defaults.spec.js"></script>
|
32
|
+
<script type="text/javascript" src="interpolation.spec.js"></script>
|
33
|
+
<script type="text/javascript" src="localization.spec.js"></script>
|
34
|
+
<script type="text/javascript" src="numbers.spec.js"></script>
|
35
|
+
<script type="text/javascript" src="placeholder.spec.js"></script>
|
36
|
+
<script type="text/javascript" src="pluralization.spec.js"></script>
|
37
|
+
<script type="text/javascript" src="prepare_options.spec.js"></script>
|
38
|
+
<script type="text/javascript" src="translate.spec.js"></script>
|
39
|
+
|
40
|
+
<!-- run specs -->
|
41
|
+
<script type="text/javascript">
|
42
|
+
jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
|
43
|
+
jasmine.getEnv().execute();
|
44
|
+
</script>
|
45
|
+
</body>
|
46
|
+
</html>
|
@@ -0,0 +1,120 @@
|
|
1
|
+
var I18n = require("../../app/assets/javascripts/i18n")
|
2
|
+
, Translations = require("./translations")
|
3
|
+
;
|
4
|
+
|
5
|
+
describe("Translate", function(){
|
6
|
+
var actual, expected;
|
7
|
+
|
8
|
+
beforeEach(function(){
|
9
|
+
I18n.reset();
|
10
|
+
I18n.translations = Translations();
|
11
|
+
});
|
12
|
+
|
13
|
+
it("returns translation for single scope", function(){
|
14
|
+
expect(I18n.t("hello")).toEqual("Hello World!");
|
15
|
+
});
|
16
|
+
|
17
|
+
it("returns translation as object", function(){
|
18
|
+
expect(I18n.t("greetings")).toEqual(I18n.translations.en.greetings);
|
19
|
+
});
|
20
|
+
|
21
|
+
it("returns missing message translation for invalid scope", function(){
|
22
|
+
actual = I18n.t("invalid.scope");
|
23
|
+
expected = '[missing "en.invalid.scope" translation]';
|
24
|
+
expect(actual).toEqual(expected);
|
25
|
+
});
|
26
|
+
|
27
|
+
it("returns translation for single scope on a custom locale", function(){
|
28
|
+
I18n.locale = "pt-BR";
|
29
|
+
expect(I18n.t("hello")).toEqual("Olá Mundo!");
|
30
|
+
});
|
31
|
+
|
32
|
+
it("returns translation for multiple scopes", function(){
|
33
|
+
expect(I18n.t("greetings.stranger")).toEqual("Hello stranger!");
|
34
|
+
});
|
35
|
+
|
36
|
+
it("returns translation with default locale option", function(){
|
37
|
+
expect(I18n.t("hello", {locale: "en"})).toEqual("Hello World!");
|
38
|
+
expect(I18n.t("hello", {locale: "pt-BR"})).toEqual("Olá Mundo!");
|
39
|
+
});
|
40
|
+
|
41
|
+
it("fallbacks to the default locale when I18n.fallbackss is enabled", function(){
|
42
|
+
I18n.locale = "pt-BR";
|
43
|
+
I18n.fallbacks = true;
|
44
|
+
expect(I18n.t("greetings.stranger")).toEqual("Hello stranger!");
|
45
|
+
});
|
46
|
+
|
47
|
+
it("fallbacks to default locale when providing an unknown locale", function(){
|
48
|
+
I18n.locale = "fr";
|
49
|
+
I18n.fallbacks = true;
|
50
|
+
expect(I18n.t("greetings.stranger")).toEqual("Hello stranger!");
|
51
|
+
});
|
52
|
+
|
53
|
+
it("fallbacks to less specific locale", function(){
|
54
|
+
I18n.locale = "de-DE";
|
55
|
+
I18n.fallbacks = true;
|
56
|
+
expect(I18n.t("hello")).toEqual("Hallo Welt!");
|
57
|
+
});
|
58
|
+
|
59
|
+
it("fallbacks using custom rules (function)", function(){
|
60
|
+
I18n.locale = "no";
|
61
|
+
I18n.fallbacks = true;
|
62
|
+
I18n.locales["no"] = function() {
|
63
|
+
return ["nb"];
|
64
|
+
};
|
65
|
+
|
66
|
+
expect(I18n.t("hello")).toEqual("Hei Verden!");
|
67
|
+
});
|
68
|
+
|
69
|
+
it("fallbacks using custom rules (array)", function() {
|
70
|
+
I18n.locale = "no";
|
71
|
+
I18n.fallbacks = true;
|
72
|
+
I18n.locales["no"] = ["no", "nb"];
|
73
|
+
|
74
|
+
expect(I18n.t("hello")).toEqual("Hei Verden!");
|
75
|
+
});
|
76
|
+
|
77
|
+
it("fallbacks using custom rules (string)", function() {
|
78
|
+
I18n.locale = "no";
|
79
|
+
I18n.fallbacks = true;
|
80
|
+
I18n.locales["no"] = "nb";
|
81
|
+
|
82
|
+
expect(I18n.t("hello")).toEqual("Hei Verden!");
|
83
|
+
});
|
84
|
+
|
85
|
+
it("uses default value for simple translation", function(){
|
86
|
+
actual = I18n.t("warning", {defaultValue: "Warning!"});
|
87
|
+
expect(actual).toEqual("Warning!");
|
88
|
+
});
|
89
|
+
|
90
|
+
it("uses default value for unknown locale", function(){
|
91
|
+
I18n.locale = "fr";
|
92
|
+
actual = I18n.t("warning", {defaultValue: "Warning!"});
|
93
|
+
expect(actual).toEqual("Warning!");
|
94
|
+
});
|
95
|
+
|
96
|
+
it("uses default value with interpolation", function(){
|
97
|
+
actual = I18n.t(
|
98
|
+
"alert",
|
99
|
+
{defaultValue: "Attention! {{message}}", message: "You're out of quota!"}
|
100
|
+
);
|
101
|
+
|
102
|
+
expect(actual).toEqual("Attention! You're out of quota!");
|
103
|
+
});
|
104
|
+
|
105
|
+
it("ignores default value when scope exists", function(){
|
106
|
+
actual = I18n.t("hello", {defaultValue: "What's up?"});
|
107
|
+
expect(actual).toEqual("Hello World!");
|
108
|
+
});
|
109
|
+
|
110
|
+
it("returns translation for custom scope separator", function(){
|
111
|
+
I18n.defaultSeparator = "•";
|
112
|
+
actual = I18n.t("greetings•stranger");
|
113
|
+
expect(actual).toEqual("Hello stranger!");
|
114
|
+
});
|
115
|
+
|
116
|
+
it("returns boolean values", function() {
|
117
|
+
expect(I18n.t("booleans.yes")).toEqual(true);
|
118
|
+
expect(I18n.t("booleans.no")).toEqual(false);
|
119
|
+
});
|
120
|
+
});
|
@@ -0,0 +1,120 @@
|
|
1
|
+
;(function(){
|
2
|
+
var generator = function() {
|
3
|
+
var Translations = {};
|
4
|
+
|
5
|
+
Translations.en = {
|
6
|
+
hello: "Hello World!"
|
7
|
+
|
8
|
+
, booleans: {
|
9
|
+
yes: true,
|
10
|
+
no: false
|
11
|
+
}
|
12
|
+
|
13
|
+
, greetings: {
|
14
|
+
stranger: "Hello stranger!"
|
15
|
+
, name: "Hello {{name}}!"
|
16
|
+
}
|
17
|
+
|
18
|
+
, profile: {
|
19
|
+
details: "{{name}} is {{age}}-years old"
|
20
|
+
}
|
21
|
+
|
22
|
+
, inbox: {
|
23
|
+
one: "You have {{count}} message"
|
24
|
+
, other: "You have {{count}} messages"
|
25
|
+
, zero: "You have no messages"
|
26
|
+
}
|
27
|
+
|
28
|
+
, unread: {
|
29
|
+
one: "You have 1 new message ({{unread}} unread)"
|
30
|
+
, other: "You have {{count}} new messages ({{unread}} unread)"
|
31
|
+
, zero: "You have no new messages ({{unread}} unread)"
|
32
|
+
}
|
33
|
+
|
34
|
+
, number: {
|
35
|
+
human: {
|
36
|
+
storage_units: {
|
37
|
+
units: {
|
38
|
+
"byte": {
|
39
|
+
one: "Byte"
|
40
|
+
, other: "Bytes"
|
41
|
+
}
|
42
|
+
, "kb": "KB"
|
43
|
+
, "mb": "MB"
|
44
|
+
, "gb": "GB"
|
45
|
+
, "tb": "TB"
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
}
|
50
|
+
};
|
51
|
+
|
52
|
+
Translations["en-US"] = {
|
53
|
+
date: {
|
54
|
+
formats: {
|
55
|
+
"default": "%d/%m/%Y"
|
56
|
+
, "short": "%d de %B"
|
57
|
+
, "long": "%d de %B de %Y"
|
58
|
+
}
|
59
|
+
|
60
|
+
, day_names: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
|
61
|
+
, abbr_day_names: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
|
62
|
+
, month_names: [null, "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
|
63
|
+
, abbr_month_names: [null, "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec"]
|
64
|
+
, meridian: ["am", "pm"]
|
65
|
+
}
|
66
|
+
};
|
67
|
+
|
68
|
+
Translations["pt-BR"] = {
|
69
|
+
hello: "Olá Mundo!"
|
70
|
+
|
71
|
+
, number: {
|
72
|
+
percentage: {
|
73
|
+
format: {
|
74
|
+
delimiter: ""
|
75
|
+
, separator: ","
|
76
|
+
, precision: 2
|
77
|
+
}
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
, date: {
|
82
|
+
formats: {
|
83
|
+
"default": "%d/%m/%Y"
|
84
|
+
, "short": "%d de %B"
|
85
|
+
, "long": "%d de %B de %Y"
|
86
|
+
}
|
87
|
+
, day_names: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"]
|
88
|
+
, abbr_day_names: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"]
|
89
|
+
, month_names: [null, "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"]
|
90
|
+
, abbr_month_names: [null, "Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"]
|
91
|
+
}
|
92
|
+
|
93
|
+
, time: {
|
94
|
+
formats: {
|
95
|
+
"default": "%A, %d de %B de %Y, %H:%M h"
|
96
|
+
, "short": "%d/%m, %H:%M h"
|
97
|
+
, "long": "%A, %d de %B de %Y, %H:%M h"
|
98
|
+
}
|
99
|
+
, am: "AM"
|
100
|
+
, pm: "PM"
|
101
|
+
}
|
102
|
+
};
|
103
|
+
|
104
|
+
Translations["de"] = {
|
105
|
+
hello: "Hallo Welt!"
|
106
|
+
};
|
107
|
+
|
108
|
+
Translations["nb"] = {
|
109
|
+
hello: "Hei Verden!"
|
110
|
+
};
|
111
|
+
|
112
|
+
return Translations;
|
113
|
+
};
|
114
|
+
|
115
|
+
if (typeof(exports) === "undefined") {
|
116
|
+
window.Translations = generator;
|
117
|
+
} else {
|
118
|
+
module.exports = generator;
|
119
|
+
}
|
120
|
+
})();
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require "i18n"
|
2
|
+
require "json"
|
3
|
+
|
4
|
+
require "active_support/all"
|
5
|
+
require "i18n/js"
|
6
|
+
|
7
|
+
module Helpers
|
8
|
+
# Set the configuration as the current one
|
9
|
+
def set_config(path)
|
10
|
+
config = HashWithIndifferentAccess.new(YAML.load_file(File.dirname(__FILE__) + "/fixtures/#{path}"))
|
11
|
+
I18n::JS.stub(:config? => true, :config => config)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Shortcut to I18n::JS.translations
|
15
|
+
def translations
|
16
|
+
I18n::JS.translations
|
17
|
+
end
|
18
|
+
|
19
|
+
def file_should_exist(name)
|
20
|
+
file_path = File.join(I18n::JS.export_dir, name)
|
21
|
+
File.should be_file(file_path)
|
22
|
+
end
|
23
|
+
|
24
|
+
def temp_path(file_name = "")
|
25
|
+
File.expand_path("../../tmp/i18n-js/#{file_name}", __FILE__)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
RSpec.configure do |config|
|
30
|
+
config.before do
|
31
|
+
I18n.load_path = [File.dirname(__FILE__) + "/fixtures/locales.yml"]
|
32
|
+
FileUtils.rm_rf(temp_path)
|
33
|
+
end
|
34
|
+
|
35
|
+
config.after do
|
36
|
+
FileUtils.rm_rf(temp_path)
|
37
|
+
end
|
38
|
+
|
39
|
+
config.include Helpers
|
40
|
+
end
|
41
|
+
|