i18n-js 3.8.0 → 3.8.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +3 -0
- data/.github/workflows/tests.yaml +100 -0
- data/CHANGELOG.md +41 -1
- data/README.md +461 -344
- data/i18njs.png +0 -0
- data/lib/i18n/js.rb +13 -8
- data/lib/i18n/js/formatters/js.rb +9 -2
- data/lib/i18n/js/middleware.rb +1 -1
- data/lib/i18n/js/private/config_store.rb +31 -0
- data/lib/i18n/js/segment.rb +1 -0
- data/lib/i18n/js/utils.rb +13 -0
- data/lib/i18n/js/version.rb +1 -1
- data/package.json +1 -1
- data/spec/js/json_parsable.spec.js +14 -0
- 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 +31 -31
- data/spec/spec_helper.rb +1 -0
- data/yarn.lock +32 -25
- metadata +9 -4
- data/.travis.yml +0 -39
data/i18njs.png
ADDED
Binary file
|
data/lib/i18n/js.rb
CHANGED
@@ -4,6 +4,7 @@ require "i18n"
|
|
4
4
|
|
5
5
|
require "i18n/js/utils"
|
6
6
|
require "i18n/js/private/hash_with_symbol_keys"
|
7
|
+
require "i18n/js/private/config_store"
|
7
8
|
|
8
9
|
module I18n
|
9
10
|
module JS
|
@@ -26,6 +27,8 @@ module I18n
|
|
26
27
|
|
27
28
|
def self.config_file_path=(new_path)
|
28
29
|
@config_file_path = new_path
|
30
|
+
# new config file path = need to re-read config from new file
|
31
|
+
Private::ConfigStore.instance.flush_cache
|
29
32
|
end
|
30
33
|
|
31
34
|
# Allow using a different backend than the one globally configured
|
@@ -108,14 +111,16 @@ module I18n
|
|
108
111
|
# Load configuration file for partial exporting and
|
109
112
|
# custom output directory
|
110
113
|
def self.config
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
114
|
+
Private::ConfigStore.instance.fetch do
|
115
|
+
if config_file_exists?
|
116
|
+
erb_result_from_yaml_file = ERB.new(File.read(config_file_path)).result
|
117
|
+
Private::HashWithSymbolKeys.new(
|
118
|
+
(::YAML.load(erb_result_from_yaml_file) || {})
|
119
|
+
)
|
120
|
+
else
|
121
|
+
Private::HashWithSymbolKeys.new({})
|
122
|
+
end.freeze
|
123
|
+
end
|
119
124
|
end
|
120
125
|
|
121
126
|
# @api private
|
@@ -4,6 +4,12 @@ module I18n
|
|
4
4
|
module JS
|
5
5
|
module Formatters
|
6
6
|
class JS < Base
|
7
|
+
JSON_ESCAPE_MAP = {
|
8
|
+
"'" => "\\'",
|
9
|
+
"\\" => "\\\\"
|
10
|
+
}.freeze
|
11
|
+
private_constant :JSON_ESCAPE_MAP
|
12
|
+
|
7
13
|
def format(translations)
|
8
14
|
contents = header
|
9
15
|
translations.each do |locale, translations_for_locale|
|
@@ -20,10 +26,11 @@ module I18n
|
|
20
26
|
end
|
21
27
|
|
22
28
|
def line(locale, translations)
|
29
|
+
json_literal = @pretty_print ? translations : %(JSON.parse('#{translations.gsub(/#{Regexp.union(JSON_ESCAPE_MAP.keys)}/){|match| JSON_ESCAPE_MAP.fetch(match) }}'))
|
23
30
|
if @js_extend
|
24
|
-
%(#{@namespace}.translations["#{locale}"] = I18n.extend((#{@namespace}.translations["#{locale}"] || {}), #{
|
31
|
+
%(#{@namespace}.translations["#{locale}"] = I18n.extend((#{@namespace}.translations["#{locale}"] || {}), #{json_literal});\n)
|
25
32
|
else
|
26
|
-
%(#{@namespace}.translations["#{locale}"] = #{
|
33
|
+
%(#{@namespace}.translations["#{locale}"] = #{json_literal};\n)
|
27
34
|
end
|
28
35
|
end
|
29
36
|
end
|
data/lib/i18n/js/middleware.rb
CHANGED
@@ -45,7 +45,7 @@ module I18n
|
|
45
45
|
|
46
46
|
def save_cache(new_cache)
|
47
47
|
# path could be a symbolic link
|
48
|
-
FileUtils.mkdir_p(cache_dir) unless File.
|
48
|
+
FileUtils.mkdir_p(cache_dir) unless File.exist?(cache_dir)
|
49
49
|
File.open(cache_path, "w+") do |file|
|
50
50
|
file << new_cache.to_yaml
|
51
51
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "singleton"
|
4
|
+
|
5
|
+
module I18n
|
6
|
+
module JS
|
7
|
+
# @api private
|
8
|
+
module Private
|
9
|
+
# Caching implementation for I18n::JS.config
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
class ConfigStore
|
13
|
+
include Singleton
|
14
|
+
|
15
|
+
def fetch
|
16
|
+
return @config if @config
|
17
|
+
|
18
|
+
yield.tap do |obj|
|
19
|
+
raise ArgumentError, "unexpected falsy object from block" unless obj
|
20
|
+
|
21
|
+
@config = obj
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def flush_cache
|
26
|
+
@config = nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/i18n/js/segment.rb
CHANGED
@@ -50,6 +50,7 @@ module I18n
|
|
50
50
|
def write_file(_file = @file, _translations = @translations)
|
51
51
|
FileUtils.mkdir_p File.dirname(_file)
|
52
52
|
_translations = Utils.deep_key_sort(_translations) if @sort_translation_keys
|
53
|
+
_translations = Utils.deep_remove_procs(_translations)
|
53
54
|
contents = formatter.format(_translations)
|
54
55
|
|
55
56
|
return if File.exist?(_file) && File.read(_file) == contents
|
data/lib/i18n/js/utils.rb
CHANGED
@@ -73,6 +73,19 @@ module I18n
|
|
73
73
|
seed[key] = value.is_a?(Hash) ? deep_key_sort(value) : value
|
74
74
|
end
|
75
75
|
end
|
76
|
+
|
77
|
+
def self.deep_remove_procs(hash)
|
78
|
+
# procs exist in `i18n.plural.rule` as pluralizer
|
79
|
+
# But having it in translation causes the exported JS/JSON changes every time
|
80
|
+
# https://github.com/ruby-i18n/i18n/blob/v1.8.7/lib/i18n/backend/pluralization.rb#L51
|
81
|
+
hash.keys.
|
82
|
+
each_with_object({}) do |key, seed|
|
83
|
+
value = hash[key]
|
84
|
+
next if value.is_a?(Proc)
|
85
|
+
|
86
|
+
seed[key] = value.is_a?(Hash) ? deep_remove_procs(value) : value
|
87
|
+
end
|
88
|
+
end
|
76
89
|
end
|
77
90
|
end
|
78
91
|
end
|
data/lib/i18n/js/version.rb
CHANGED
data/package.json
CHANGED
@@ -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
|
+
})
|
@@ -131,8 +131,8 @@ EOS
|
|
131
131
|
|
132
132
|
expect(File.open(File.join(temp_path, "segment.js")){|f| f.read}).to eql <<-EOF
|
133
133
|
MyNamespace.translations || (MyNamespace.translations = {});
|
134
|
-
MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), {"test":"Test"});
|
135
|
-
MyNamespace.translations["fr"] = I18n.extend((MyNamespace.translations["fr"] || {}), {"test":"Test2"});
|
134
|
+
MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), JSON.parse('{"test":"Test"}'));
|
135
|
+
MyNamespace.translations["fr"] = I18n.extend((MyNamespace.translations["fr"] || {}), JSON.parse('{"test":"Test2"}'));
|
136
136
|
EOF
|
137
137
|
end
|
138
138
|
end
|
@@ -146,12 +146,54 @@ MyNamespace.translations["fr"] = I18n.extend((MyNamespace.translations["fr"] ||
|
|
146
146
|
|
147
147
|
expect(File.open(File.join(temp_path, "en.js")){|f| f.read}).to eql <<-EOF
|
148
148
|
MyNamespace.translations || (MyNamespace.translations = {});
|
149
|
-
MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), {"test":"Test"});
|
149
|
+
MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), JSON.parse('{"test":"Test"}'));
|
150
150
|
EOF
|
151
151
|
|
152
152
|
expect(File.open(File.join(temp_path, "fr.js")){|f| f.read}).to eql <<-EOF
|
153
153
|
MyNamespace.translations || (MyNamespace.translations = {});
|
154
|
-
MyNamespace.translations["fr"] = I18n.extend((MyNamespace.translations["fr"] || {}), {"test":"Test2"});
|
154
|
+
MyNamespace.translations["fr"] = I18n.extend((MyNamespace.translations["fr"] || {}), JSON.parse('{"test":"Test2"}'));
|
155
|
+
EOF
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
context "when file includes single quote" do
|
160
|
+
let(:file){ "tmp/i18n-js/%{locale}.js" }
|
161
|
+
let(:translations){ { en: { "a" => "Test's" } } }
|
162
|
+
|
163
|
+
it "should write files" do
|
164
|
+
file_should_exist "en.js"
|
165
|
+
|
166
|
+
expect(File.open(File.join(temp_path, "en.js")){|f| f.read}).to eql <<-EOF
|
167
|
+
MyNamespace.translations || (MyNamespace.translations = {});
|
168
|
+
MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), JSON.parse('{"a":"Test\\'s"}'));
|
169
|
+
EOF
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context "when file includes escaped double quote" do
|
174
|
+
let(:file){ "tmp/i18n-js/%{locale}.js" }
|
175
|
+
let(:translations){ { en: { "a" => 'say "hello"' } } }
|
176
|
+
|
177
|
+
it "should escape double quote" do
|
178
|
+
file_should_exist "en.js"
|
179
|
+
|
180
|
+
expect(File.open(File.join(temp_path, "en.js")){|f| f.read}).to eql <<-EOF
|
181
|
+
MyNamespace.translations || (MyNamespace.translations = {});
|
182
|
+
MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), JSON.parse('{"a":"say \\\\"hello\\\\""}'));
|
183
|
+
EOF
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
context "when file includes backslash in double quote" do
|
188
|
+
let(:file){ "tmp/i18n-js/%{locale}.js" }
|
189
|
+
let(:translations){ { en: { "double-backslash-in-double-quote" => '"\\\\"' } } }
|
190
|
+
|
191
|
+
it "should escape backslash" do
|
192
|
+
file_should_exist "en.js"
|
193
|
+
|
194
|
+
expect(File.open(File.join(temp_path, "en.js")){|f| f.read}).to eql <<-EOF
|
195
|
+
MyNamespace.translations || (MyNamespace.translations = {});
|
196
|
+
MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), JSON.parse('{"double-backslash-in-double-quote":"\\\\"\\\\\\\\\\\\\\\\\\\\""}'));
|
155
197
|
EOF
|
156
198
|
end
|
157
199
|
end
|
@@ -166,7 +208,7 @@ MyNamespace.translations["fr"] = I18n.extend((MyNamespace.translations["fr"] ||
|
|
166
208
|
|
167
209
|
expect(File.open(File.join(temp_path, "segment.js")){|f| f.read}).to eql <<-EOF
|
168
210
|
MyNamespace.translations || (MyNamespace.translations = {});
|
169
|
-
MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), {"a":"Test","b":"Test"});
|
211
|
+
MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), JSON.parse('{"a":"Test","b":"Test"}'));
|
170
212
|
EOF
|
171
213
|
end
|
172
214
|
end
|
@@ -181,7 +223,7 @@ MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] ||
|
|
181
223
|
|
182
224
|
expect(File.open(File.join(temp_path, "segment.js")){|f| f.read}).to eql <<-EOF
|
183
225
|
MyNamespace.translations || (MyNamespace.translations = {});
|
184
|
-
MyNamespace.translations["en"] = {"a":"Test","b":"Test"};
|
226
|
+
MyNamespace.translations["en"] = JSON.parse('{"a":"Test","b":"Test"}');
|
185
227
|
EOF
|
186
228
|
end
|
187
229
|
end
|
@@ -196,7 +238,7 @@ MyNamespace.translations["en"] = {"a":"Test","b":"Test"};
|
|
196
238
|
|
197
239
|
expect(File.open(File.join(temp_path, "segment.js")){|f| f.read}).to eql <<-EOF
|
198
240
|
MyNamespace.translations || (MyNamespace.translations = {});
|
199
|
-
MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), {"a":"Test","b":"Test"});
|
241
|
+
MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), JSON.parse('{"a":"Test","b":"Test"}'));
|
200
242
|
EOF
|
201
243
|
end
|
202
244
|
end
|
@@ -211,7 +253,32 @@ MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] ||
|
|
211
253
|
|
212
254
|
expect(File.open(File.join(temp_path, "segment.js")){|f| f.read}).to eql <<-EOF
|
213
255
|
MyNamespace.translations || (MyNamespace.translations = {});
|
214
|
-
MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), {"b":"Test","a":"Test"});
|
256
|
+
MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), JSON.parse('{"b":"Test","a":"Test"}'));
|
257
|
+
EOF
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
context "when translation entries contain procs" do
|
262
|
+
let(:translations) do
|
263
|
+
{
|
264
|
+
en: {
|
265
|
+
"test" => "Test",
|
266
|
+
"i18n" => {"plural" => {"rule" => proc {} }},
|
267
|
+
},
|
268
|
+
fr: {
|
269
|
+
"test" => "Test2",
|
270
|
+
"i18n" => {"plural" => {"rule" => proc {} }},
|
271
|
+
},
|
272
|
+
}
|
273
|
+
end
|
274
|
+
|
275
|
+
it "should write files without procs or their string representations" do
|
276
|
+
file_should_exist "segment.js"
|
277
|
+
|
278
|
+
expect(File.open(File.join(temp_path, "segment.js")){|f| f.read}).to eql <<-EOF
|
279
|
+
MyNamespace.translations || (MyNamespace.translations = {});
|
280
|
+
MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), JSON.parse('{"i18n":{"plural":{}},"test":"Test"}'));
|
281
|
+
MyNamespace.translations["fr"] = I18n.extend((MyNamespace.translations["fr"] || {}), JSON.parse('{"i18n":{"plural":{}},"test":"Test2"}'));
|
215
282
|
EOF
|
216
283
|
end
|
217
284
|
end
|
@@ -103,4 +103,36 @@ describe I18n::JS::Utils do
|
|
103
103
|
expect(described_class.scopes_match?([:a, :b, :c], [:a, '*', '*'])).to eql true
|
104
104
|
end
|
105
105
|
end
|
106
|
+
|
107
|
+
describe ".deep_remove_procs" do
|
108
|
+
let(:proc_obj) { proc {} }
|
109
|
+
let(:hash_with_proc) do
|
110
|
+
{
|
111
|
+
:a => :b,
|
112
|
+
:c => proc_obj,
|
113
|
+
:d => {
|
114
|
+
:e => proc_obj,
|
115
|
+
:f => :g,
|
116
|
+
}
|
117
|
+
}
|
118
|
+
end
|
119
|
+
subject { described_class.deep_remove_procs(hash_with_proc) }
|
120
|
+
|
121
|
+
it "performs a deep keys sort without changing the original hash" do
|
122
|
+
should eql({
|
123
|
+
:a => :b,
|
124
|
+
:d => {
|
125
|
+
:f => :g,
|
126
|
+
}
|
127
|
+
})
|
128
|
+
expect(hash_with_proc).to eql({
|
129
|
+
:a => :b,
|
130
|
+
:c => proc_obj,
|
131
|
+
:d => {
|
132
|
+
:e => proc_obj,
|
133
|
+
:f => :g,
|
134
|
+
}
|
135
|
+
})
|
136
|
+
end
|
137
|
+
end
|
106
138
|
end
|
data/spec/ruby/i18n/js_spec.rb
CHANGED
@@ -67,13 +67,13 @@ describe I18n::JS do
|
|
67
67
|
en_output = File.read(File.join(I18n::JS.export_i18n_js_dir_path, "en.js"))
|
68
68
|
expect(en_output).to eq(<<EOS
|
69
69
|
I18n.translations || (I18n.translations = {});
|
70
|
-
I18n.translations["en"] = I18n.extend((I18n.translations["en"] || {}), {"admin":{"edit":{"title":"Edit"},"show":{"note":"more details","title":"Show"}},"date":{"abbr_day_names":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"abbr_month_names":[null,"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"day_names":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"formats":{"default":"%Y-%m-%d","long":"%B %d, %Y","short":"%b %d"},"month_names":[null,"January","February","March","April","May","June","July","August","September","October","November","December"]}});
|
70
|
+
I18n.translations["en"] = I18n.extend((I18n.translations["en"] || {}), JSON.parse('{"admin":{"edit":{"title":"Edit"},"show":{"note":"more details","title":"Show"}},"date":{"abbr_day_names":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"abbr_month_names":[null,"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"day_names":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"formats":{"default":"%Y-%m-%d","long":"%B %d, %Y","short":"%b %d"},"month_names":[null,"January","February","March","April","May","June","July","August","September","October","November","December"]}}'));
|
71
71
|
EOS
|
72
72
|
)
|
73
73
|
fr_output = File.read(File.join(I18n::JS.export_i18n_js_dir_path, "fr.js"))
|
74
74
|
expect(fr_output).to eq(<<EOS
|
75
75
|
I18n.translations || (I18n.translations = {});
|
76
|
-
I18n.translations["fr"] = I18n.extend((I18n.translations["fr"] || {}), {"admin":{"edit":{"title":"Editer"},"show":{"note":"plus de détails","title":"Visualiser"}},"date":{"abbr_day_names":["dim","lun","mar","mer","jeu","ven","sam"],"abbr_month_names":[null,"jan.","fév.","mar.","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc."],"day_names":["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],"formats":{"default":"%d/%m/%Y","long":"%e %B %Y","long_ordinal":"%e %B %Y","only_day":"%e","short":"%e %b"},"month_names":[null,"janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"]}});
|
76
|
+
I18n.translations["fr"] = I18n.extend((I18n.translations["fr"] || {}), JSON.parse('{"admin":{"edit":{"title":"Editer"},"show":{"note":"plus de détails","title":"Visualiser"}},"date":{"abbr_day_names":["dim","lun","mar","mer","jeu","ven","sam"],"abbr_month_names":[null,"jan.","fév.","mar.","avr.","mai","juin","juil.","août","sept.","oct.","nov.","déc."],"day_names":["dimanche","lundi","mardi","mercredi","jeudi","vendredi","samedi"],"formats":{"default":"%d/%m/%Y","long":"%e %B %Y","long_ordinal":"%e %B %Y","only_day":"%e","short":"%e %b"},"month_names":[null,"janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre"]}}'));
|
77
77
|
EOS
|
78
78
|
)
|
79
79
|
end
|
@@ -98,13 +98,13 @@ EOS
|
|
98
98
|
en_output = File.read(File.join(I18n::JS.export_i18n_js_dir_path, "bits.en.js"))
|
99
99
|
expect(en_output).to eq(<<EOS
|
100
100
|
I18n.translations || (I18n.translations = {});
|
101
|
-
I18n.translations["en"] = I18n.extend((I18n.translations["en"] || {}), {"date":{"formats":{"default":"%Y-%m-%d","long":"%B %d, %Y","short":"%b %d"}},"number":{"currency":{"format":{"delimiter":",","format":"%u%n","precision":2,"separator":".","unit":"$"}}}});
|
101
|
+
I18n.translations["en"] = I18n.extend((I18n.translations["en"] || {}), JSON.parse('{"date":{"formats":{"default":"%Y-%m-%d","long":"%B %d, %Y","short":"%b %d"}},"number":{"currency":{"format":{"delimiter":",","format":"%u%n","precision":2,"separator":".","unit":"$"}}}}'));
|
102
102
|
EOS
|
103
103
|
)
|
104
104
|
fr_output = File.read(File.join(I18n::JS.export_i18n_js_dir_path, "bits.fr.js"))
|
105
105
|
expect(fr_output).to eq(<<EOS
|
106
106
|
I18n.translations || (I18n.translations = {});
|
107
|
-
I18n.translations["fr"] = I18n.extend((I18n.translations["fr"] || {}), {"date":{"formats":{"default":"%d/%m/%Y","long":"%e %B %Y","long_ordinal":"%e %B %Y","only_day":"%e","short":"%e %b"}},"number":{"currency":{"format":{"format":"%n %u","precision":2,"unit":"€"}}}});
|
107
|
+
I18n.translations["fr"] = I18n.extend((I18n.translations["fr"] || {}), JSON.parse('{"date":{"formats":{"default":"%d/%m/%Y","long":"%e %B %Y","long_ordinal":"%e %B %Y","only_day":"%e","short":"%e %b"}},"number":{"currency":{"format":{"format":"%n %u","precision":2,"unit":"€"}}}}'));
|
108
108
|
EOS
|
109
109
|
)
|
110
110
|
end
|
@@ -599,7 +599,7 @@ EOS
|
|
599
599
|
it "exports with the keys sorted" do
|
600
600
|
expect(subject).to eq <<EOS
|
601
601
|
I18n.translations || (I18n.translations = {});
|
602
|
-
I18n.translations["en"] = I18n.extend((I18n.translations["en"] || {}), {"admin":{"edit":{"title":"Edit"},"show":{"note":"more details","title":"Show"}},"date":{"abbr_day_names":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"abbr_month_names":[null,"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"day_names":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"formats":{"default":"%Y-%m-%d","long":"%B %d, %Y","short":"%b %d"},"month_names":[null,"January","February","March","April","May","June","July","August","September","October","November","December"]},"fallback_test":"Success","foo":"Foo","merge_plurals":{"one":"Apple","other":"Apples"},"merge_plurals_with_no_overrides":{"one":"Apple","other":"Apples","zero":"No Apple"},"merge_plurals_with_partial_overrides":{"one":"Cat","other":"Cats"},"null_test":"fallback for null","number":{"currency":{"format":{"delimiter":",","format":"%u%n","precision":2,"separator":".","unit":"$"}},"format":{"delimiter":",","precision":3,"separator":"."},"human":{"decimal_units":{"units":{"million":"Million"}}}},"time":{"am":"am","formats":{"default":"%a, %d %b %Y %H:%M:%S %z","long":"%B %d, %Y %H:%M","short":"%d %b %H:%M"},"pm":"pm"}});
|
602
|
+
I18n.translations["en"] = I18n.extend((I18n.translations["en"] || {}), JSON.parse('{"admin":{"edit":{"title":"Edit"},"show":{"note":"more details","title":"Show"}},"date":{"abbr_day_names":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"abbr_month_names":[null,"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"day_names":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"formats":{"default":"%Y-%m-%d","long":"%B %d, %Y","short":"%b %d"},"month_names":[null,"January","February","March","April","May","June","July","August","September","October","November","December"]},"fallback_test":"Success","foo":"Foo","merge_plurals":{"one":"Apple","other":"Apples"},"merge_plurals_with_no_overrides":{"one":"Apple","other":"Apples","zero":"No Apple"},"merge_plurals_with_partial_overrides":{"one":"Cat","other":"Cats"},"null_test":"fallback for null","number":{"currency":{"format":{"delimiter":",","format":"%u%n","precision":2,"separator":".","unit":"$"}},"format":{"delimiter":",","precision":3,"separator":"."},"human":{"decimal_units":{"units":{"million":"Million"}}}},"time":{"am":"am","formats":{"default":"%a, %d %b %Y %H:%M:%S %z","long":"%B %d, %Y %H:%M","short":"%d %b %H:%M"},"pm":"pm"}}'));
|
603
603
|
EOS
|
604
604
|
end
|
605
605
|
end
|
@@ -628,13 +628,13 @@ EOS
|
|
628
628
|
|
629
629
|
expect(subject).to eq <<EOS
|
630
630
|
I18n.translations || (I18n.translations = {});
|
631
|
-
I18n.translations[\"de\"] = I18n.extend((I18n.translations[\"de\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}});
|
632
|
-
I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}});
|
633
|
-
I18n.translations[\"en-US\"] = I18n.extend((I18n.translations[\"en-US\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}});
|
634
|
-
I18n.translations[\"es\"] = I18n.extend((I18n.translations[\"es\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":{\"one\":\"millón\",\"other\":\"millones\"}}}}}});
|
635
|
-
I18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}});
|
636
|
-
I18n.translations[\"ja\"] = I18n.extend((I18n.translations[\"ja\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}});
|
637
|
-
I18n.translations[\"ru\"] = I18n.extend((I18n.translations[\"ru\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}});
|
631
|
+
I18n.translations[\"de\"] = I18n.extend((I18n.translations[\"de\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}}'));
|
632
|
+
I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}}'));
|
633
|
+
I18n.translations[\"en-US\"] = I18n.extend((I18n.translations[\"en-US\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}}'));
|
634
|
+
I18n.translations[\"es\"] = I18n.extend((I18n.translations[\"es\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":{\"one\":\"millón\",\"other\":\"millones\"}}}}}}'));
|
635
|
+
I18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}}'));
|
636
|
+
I18n.translations[\"ja\"] = I18n.extend((I18n.translations[\"ja\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}}'));
|
637
|
+
I18n.translations[\"ru\"] = I18n.extend((I18n.translations[\"ru\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}}'));
|
638
638
|
EOS
|
639
639
|
end
|
640
640
|
end
|
@@ -648,8 +648,8 @@ EOS
|
|
648
648
|
output = File.read(File.join(I18n::JS.export_i18n_js_dir_path, "js_extend_parent.js"))
|
649
649
|
expect(output).to eq(<<EOS
|
650
650
|
I18n.translations || (I18n.translations = {});
|
651
|
-
I18n.translations[\"en\"] = {\"date\":{\"formats\":{\"default\":\"%Y-%m-%d\",\"long\":\"%B %d, %Y\",\"short\":\"%b %d\"}}};
|
652
|
-
I18n.translations[\"fr\"] = {\"date\":{\"formats\":{\"default\":\"%d/%m/%Y\",\"long\":\"%e %B %Y\",\"long_ordinal\":\"%e %B %Y\",\"only_day\":\"%e\",\"short\":\"%e %b\"}}};
|
651
|
+
I18n.translations[\"en\"] = JSON.parse('{\"date\":{\"formats\":{\"default\":\"%Y-%m-%d\",\"long\":\"%B %d, %Y\",\"short\":\"%b %d\"}}}');
|
652
|
+
I18n.translations[\"fr\"] = JSON.parse('{\"date\":{\"formats\":{\"default\":\"%d/%m/%Y\",\"long\":\"%e %B %Y\",\"long_ordinal\":\"%e %B %Y\",\"only_day\":\"%e\",\"short\":\"%e %b\"}}}');
|
653
653
|
EOS
|
654
654
|
)
|
655
655
|
end
|
@@ -663,8 +663,8 @@ EOS
|
|
663
663
|
output = File.read(File.join(I18n::JS.export_i18n_js_dir_path, "js_extend_segment.js"))
|
664
664
|
expect(output).to eq(<<EOS
|
665
665
|
I18n.translations || (I18n.translations = {});
|
666
|
-
I18n.translations[\"en\"] = {\"date\":{\"formats\":{\"default\":\"%Y-%m-%d\",\"long\":\"%B %d, %Y\",\"short\":\"%b %d\"}}};
|
667
|
-
I18n.translations[\"fr\"] = {\"date\":{\"formats\":{\"default\":\"%d/%m/%Y\",\"long\":\"%e %B %Y\",\"long_ordinal\":\"%e %B %Y\",\"only_day\":\"%e\",\"short\":\"%e %b\"}}};
|
666
|
+
I18n.translations[\"en\"] = JSON.parse('{\"date\":{\"formats\":{\"default\":\"%Y-%m-%d\",\"long\":\"%B %d, %Y\",\"short\":\"%b %d\"}}}');
|
667
|
+
I18n.translations[\"fr\"] = JSON.parse('{\"date\":{\"formats\":{\"default\":\"%d/%m/%Y\",\"long\":\"%e %B %Y\",\"long_ordinal\":\"%e %B %Y\",\"only_day\":\"%e\",\"short\":\"%e %b\"}}}');
|
668
668
|
EOS
|
669
669
|
)
|
670
670
|
end
|
@@ -686,7 +686,7 @@ EOS
|
|
686
686
|
|
687
687
|
expect(subject).to eq <<EOS
|
688
688
|
I18n.translations || (I18n.translations = {});
|
689
|
-
I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), {\"merge_plurals\":{\"one\":\"Apple\",\"other\":\"Apples\"}});\nI18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), {\"merge_plurals\":{\"one\":\"Pomme\",\"other\":\"Pommes\",\"zero\":\"Pomme\"}});
|
689
|
+
I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), JSON.parse('{\"merge_plurals\":{\"one\":\"Apple\",\"other\":\"Apples\"}}'));\nI18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), JSON.parse('{\"merge_plurals\":{\"one\":\"Pomme\",\"other\":\"Pommes\",\"zero\":\"Pomme\"}}'));
|
690
690
|
EOS
|
691
691
|
end
|
692
692
|
end
|
@@ -707,13 +707,13 @@ EOS
|
|
707
707
|
|
708
708
|
expect(subject).to eq <<EOS
|
709
709
|
I18n.translations || (I18n.translations = {});
|
710
|
-
I18n.translations[\"de\"] = I18n.extend((I18n.translations[\"de\"] || {}), {\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}});
|
711
|
-
I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), {\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}});
|
712
|
-
I18n.translations[\"en-US\"] = I18n.extend((I18n.translations[\"en-US\"] || {}), {\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}});
|
713
|
-
I18n.translations[\"es\"] = I18n.extend((I18n.translations[\"es\"] || {}), {\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}});
|
714
|
-
I18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), {\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}});
|
715
|
-
I18n.translations[\"ja\"] = I18n.extend((I18n.translations[\"ja\"] || {}), {\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}});
|
716
|
-
I18n.translations[\"ru\"] = I18n.extend((I18n.translations[\"ru\"] || {}), {\"merge_plurals_with_no_overrides\":{\"few\":\"кошек\",\"many\":\"кошка\",\"one\":\"кот\",\"other\":\"кошек\"}});
|
710
|
+
I18n.translations[\"de\"] = I18n.extend((I18n.translations[\"de\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}}'));
|
711
|
+
I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}}'));
|
712
|
+
I18n.translations[\"en-US\"] = I18n.extend((I18n.translations[\"en-US\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}}'));
|
713
|
+
I18n.translations[\"es\"] = I18n.extend((I18n.translations[\"es\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}}'));
|
714
|
+
I18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}}'));
|
715
|
+
I18n.translations[\"ja\"] = I18n.extend((I18n.translations[\"ja\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}}'));
|
716
|
+
I18n.translations[\"ru\"] = I18n.extend((I18n.translations[\"ru\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"few\":\"кошек\",\"many\":\"кошка\",\"one\":\"кот\",\"other\":\"кошек\"}}'));
|
717
717
|
EOS
|
718
718
|
end
|
719
719
|
end
|
@@ -735,13 +735,13 @@ EOS
|
|
735
735
|
|
736
736
|
expect(subject).to eq <<EOS
|
737
737
|
I18n.translations || (I18n.translations = {});
|
738
|
-
I18n.translations[\"de\"] = I18n.extend((I18n.translations[\"de\"] || {}), {\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}});
|
739
|
-
I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), {\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}});
|
740
|
-
I18n.translations[\"en-US\"] = I18n.extend((I18n.translations[\"en-US\"] || {}), {\"merge_plurals_with_partial_overrides\":{\"few\":null,\"many\":null,\"one\":\"Cat\",\"other\":\"Cats\"}});
|
741
|
-
I18n.translations[\"es\"] = I18n.extend((I18n.translations[\"es\"] || {}), {\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}});
|
742
|
-
I18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), {\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}});
|
743
|
-
I18n.translations[\"ja\"] = I18n.extend((I18n.translations[\"ja\"] || {}), {\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}});
|
744
|
-
I18n.translations[\"ru\"] = I18n.extend((I18n.translations[\"ru\"] || {}), {\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}});
|
738
|
+
I18n.translations[\"de\"] = I18n.extend((I18n.translations[\"de\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}}'));
|
739
|
+
I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}}'));
|
740
|
+
I18n.translations[\"en-US\"] = I18n.extend((I18n.translations[\"en-US\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"few\":null,\"many\":null,\"one\":\"Cat\",\"other\":\"Cats\"}}'));
|
741
|
+
I18n.translations[\"es\"] = I18n.extend((I18n.translations[\"es\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}}'));
|
742
|
+
I18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}}'));
|
743
|
+
I18n.translations[\"ja\"] = I18n.extend((I18n.translations[\"ja\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}}'));
|
744
|
+
I18n.translations[\"ru\"] = I18n.extend((I18n.translations[\"ru\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}}'));
|
745
745
|
EOS
|
746
746
|
end
|
747
747
|
end
|