i18n-js 3.8.1 → 3.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -1
- data/README.md +34 -5
- data/lib/i18n/js.rb +12 -2
- 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 +1 -1
- data/lib/i18n/js/segment.rb +2 -1
- data/lib/i18n/js/utils.rb +13 -0
- data/lib/i18n/js/version.rb +1 -1
- data/package.json +1 -1
- data/spec/fixtures/js_available_locales_custom.yml +1 -0
- 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 +103 -54
- data/yarn.lock +32 -25
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '08599ed12ef6edb132d1a71b74e5ca2f3b3c04dc4463286414540f4631676984'
|
4
|
+
data.tar.gz: 3dd94b7a9974952a5cb7996c222d1aaeb3e5c756cc811a8890e4d5fa79ffccb3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 26138b1fafc184b7858a97969130f29f9562cdaab41d1f05c1e31a37064a2f40a31b4d0a349e12ddaa6f769ab229618a854efaee0102f99821edd489b9d1deb5
|
7
|
+
data.tar.gz: d763f7ebe8d1bba649c521bba03fa7fb77e4283b90ce6f1a1bb78ebf22dc7146f4e2eb02484f7d9f104d4d5454d90d0622af14128c6b383cd399e52aabaaf08b
|
data/CHANGELOG.md
CHANGED
@@ -18,6 +18,42 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
18
18
|
- Nothing
|
19
19
|
|
20
20
|
|
21
|
+
## [3.9.0]
|
22
|
+
|
23
|
+
### Added
|
24
|
+
|
25
|
+
- [Ruby] Allow to set custom locales instead of using only `I18n.available_locales`.
|
26
|
+
(PR: https://github.com/fnando/i18n-js/pull/617)
|
27
|
+
|
28
|
+
|
29
|
+
## [3.8.4]
|
30
|
+
|
31
|
+
### Fixed
|
32
|
+
|
33
|
+
- [Ruby] Fix proc exported to JS/JSON file(s) causing issues like git merge conflicts
|
34
|
+
(PR: https://github.com/fnando/i18n-js/pull/591)
|
35
|
+
|
36
|
+
|
37
|
+
## [3.8.3]
|
38
|
+
|
39
|
+
### Changed
|
40
|
+
|
41
|
+
- [Ruby] Generate translations in JS as `JSON.parse` instead of object literal for performance
|
42
|
+
(PR: https://github.com/fnando/i18n-js/pull/605)
|
43
|
+
(PR: https://github.com/fnando/i18n-js/pull/606)
|
44
|
+
(PR: https://github.com/fnando/i18n-js/pull/607)
|
45
|
+
|
46
|
+
|
47
|
+
## [3.8.2] - 2021-03-18
|
48
|
+
|
49
|
+
### Fixed
|
50
|
+
|
51
|
+
- [Ruby] Stop using deprecated method
|
52
|
+
(PR: https://github.com/fnando/i18n-js/pull/598)
|
53
|
+
- [Ruby] Fix typo in error class reference
|
54
|
+
(Commit: https://github.com/fnando/i18n-js/commit/cc075ad0a36e940205d0a14390379d69013d188e)
|
55
|
+
|
56
|
+
|
21
57
|
## [3.8.1] - 2021-02-25
|
22
58
|
|
23
59
|
### Fixed
|
@@ -481,7 +517,11 @@ And today is not April Fools' Day
|
|
481
517
|
|
482
518
|
|
483
519
|
|
484
|
-
[Unreleased]: https://github.com/fnando/i18n-js/compare/v3.
|
520
|
+
[Unreleased]: https://github.com/fnando/i18n-js/compare/v3.9.0...HEAD
|
521
|
+
[3.9.0]: https://github.com/fnando/i18n-js/compare/v3.8.4...v3.9.0
|
522
|
+
[3.8.4]: https://github.com/fnando/i18n-js/compare/v3.8.3...v3.8.4
|
523
|
+
[3.8.3]: https://github.com/fnando/i18n-js/compare/v3.8.2...v3.8.3
|
524
|
+
[3.8.2]: https://github.com/fnando/i18n-js/compare/v3.8.1...v3.8.2
|
485
525
|
[3.8.1]: https://github.com/fnando/i18n-js/compare/v3.8.0...v3.8.1
|
486
526
|
[3.8.0]: https://github.com/fnando/i18n-js/compare/v3.7.1...v3.8.0
|
487
527
|
[3.7.1]: https://github.com/fnando/i18n-js/compare/v3.7.0...v3.7.1
|
data/README.md
CHANGED
@@ -55,8 +55,9 @@ yarn add i18n-js
|
|
55
55
|
npm install i18n-js
|
56
56
|
```
|
57
57
|
|
58
|
-
For more details, see
|
59
|
-
[this gist](https://gist.github.com/bazzel/ecdff4718962e57c2d5569cf01d332fe)
|
58
|
+
For more details, see:
|
59
|
+
- [this gist](https://gist.github.com/bazzel/ecdff4718962e57c2d5569cf01d332fe)
|
60
|
+
- https://github.com/fnando/i18n-js/issues/597
|
60
61
|
|
61
62
|
#### Rails app with [Asset Pipeline](http://guides.rubyonrails.org/asset_pipeline.html)
|
62
63
|
|
@@ -270,6 +271,17 @@ You must disable this feature by setting the option to `false`.
|
|
270
271
|
To find more examples on how to use the configuration file please refer to the
|
271
272
|
tests.
|
272
273
|
|
274
|
+
#### Available locales
|
275
|
+
|
276
|
+
By specifying option `js_available_locales` with a list of locales, this list
|
277
|
+
would be used instead of default `I18n.available_locales` to generate translations.
|
278
|
+
|
279
|
+
Example:
|
280
|
+
|
281
|
+
```yaml
|
282
|
+
js_available_locales: ["de", "en"]
|
283
|
+
```
|
284
|
+
|
273
285
|
#### Namespace
|
274
286
|
|
275
287
|
Setting the `namespace` option will change the namespace of the output
|
@@ -479,6 +491,8 @@ I18n.locales.no = function (locale) {
|
|
479
491
|
};
|
480
492
|
```
|
481
493
|
|
494
|
+
### Translation Missing Behaviour Control
|
495
|
+
|
482
496
|
By default a missing translation will be displayed as
|
483
497
|
|
484
498
|
[missing "name of scope" translation]
|
@@ -497,8 +511,10 @@ Camel case becomes lower cased text and underscores are replaced with space
|
|
497
511
|
|
498
512
|
becomes "what is your favorite Christmas present"
|
499
513
|
|
514
|
+
#### Option `missingTranslationPrefix`
|
515
|
+
|
500
516
|
In order to still detect untranslated strings, you can set
|
501
|
-
`
|
517
|
+
`I18n.missingTranslationPrefix` to something like:
|
502
518
|
|
503
519
|
```javascript
|
504
520
|
I18n.missingTranslationPrefix = "EE: ";
|
@@ -513,14 +529,27 @@ And result will be:
|
|
513
529
|
|
514
530
|
This will help you doing automated tests against your localisation assets.
|
515
531
|
|
516
|
-
|
532
|
+
#### Customize return when translation entry missing
|
533
|
+
|
534
|
+
Some people prefer returning `null`/`undefined` for missing translation:
|
517
535
|
|
518
536
|
```javascript
|
519
|
-
I18n.missingTranslation = function () {
|
537
|
+
I18n.missingTranslation = function (scope, options) {
|
520
538
|
return undefined;
|
521
539
|
};
|
522
540
|
```
|
523
541
|
|
542
|
+
### Option `defaultSeparator` (global) / `separator` (local)
|
543
|
+
|
544
|
+
Default separator of translation key is `.` (dot)
|
545
|
+
Meaning `I18n.t("scope.entry")` would search for translation entry `I18n.translations[locale].scope.entry`
|
546
|
+
Using a different separator can be done either globally or locally.
|
547
|
+
|
548
|
+
Globally: `I18n.defaultSeparator = newSeparator`
|
549
|
+
Locally: `I18n.t("full_sentences|Server Busy. Please retry later", {separator: '|'})`
|
550
|
+
|
551
|
+
### Pluralization
|
552
|
+
|
524
553
|
Pluralization is possible as well and by default provides English rules:
|
525
554
|
|
526
555
|
```javascript
|
data/lib/i18n/js.rb
CHANGED
@@ -81,7 +81,7 @@ module I18n
|
|
81
81
|
|
82
82
|
# deep_merge! given result with result for fallback locale
|
83
83
|
def self.merge_with_fallbacks!(result)
|
84
|
-
|
84
|
+
js_available_locales.each do |locale|
|
85
85
|
fallback_locales = FallbackLocales.new(fallbacks, locale)
|
86
86
|
fallback_locales.each do |fallback_locale|
|
87
87
|
# `result[fallback_locale]` could be missing
|
@@ -183,7 +183,7 @@ module I18n
|
|
183
183
|
#
|
184
184
|
# So the input is wrapped by our class for better `#slice`
|
185
185
|
Private::HashWithSymbolKeys.new(translations).
|
186
|
-
slice(*::I18n.
|
186
|
+
slice(*::I18n::JS.js_available_locales).
|
187
187
|
to_h
|
188
188
|
end
|
189
189
|
end
|
@@ -213,6 +213,16 @@ module I18n
|
|
213
213
|
end
|
214
214
|
end
|
215
215
|
|
216
|
+
# Get all available locales.
|
217
|
+
#
|
218
|
+
# @return [Array<Symbol>] the locales.
|
219
|
+
def self.js_available_locales
|
220
|
+
config.fetch(:js_available_locales) do
|
221
|
+
# default value
|
222
|
+
I18n.available_locales
|
223
|
+
end.map(&:to_sym)
|
224
|
+
end
|
225
|
+
|
216
226
|
def self.sort_translation_keys?
|
217
227
|
@sort_translation_keys ||= (config[:sort_translation_keys]) if config.key?(:sort_translation_keys)
|
218
228
|
@sort_translation_keys = true if @sort_translation_keys.nil?
|
@@ -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
|
data/lib/i18n/js/segment.rb
CHANGED
@@ -33,7 +33,7 @@ module I18n
|
|
33
33
|
# Saves JSON file containing translations
|
34
34
|
def save!
|
35
35
|
if @file =~ LOCALE_INTERPOLATOR
|
36
|
-
I18n.
|
36
|
+
I18n::JS.js_available_locales.each do |locale|
|
37
37
|
write_file(file_for_locale(locale), @translations.slice(locale))
|
38
38
|
end
|
39
39
|
else
|
@@ -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 @@
|
|
1
|
+
js_available_locales: ["en", "foo"]
|
@@ -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
|
@@ -307,21 +307,30 @@ EOS
|
|
307
307
|
expect(subject[:de][:null_test]).to eql(nil)
|
308
308
|
end
|
309
309
|
|
310
|
-
context
|
310
|
+
context 'when given locale is in `I18n.available_locales` but its translation is missing' do
|
311
311
|
subject { translations[:fr][:fallback_test] }
|
312
312
|
|
313
|
-
let(:
|
314
|
-
|
315
|
-
let!(:new_available_locales) { I18n.config.available_locales + [new_locale] }
|
313
|
+
let(:available_locales) { %i[fr pirate] }
|
314
|
+
|
316
315
|
before do
|
317
|
-
I18n.
|
318
|
-
set_config
|
316
|
+
allow(::I18n).to receive(:available_locales).and_return(available_locales)
|
317
|
+
set_config 'js_file_per_locale_with_fallbacks_as_locale_without_fallback_translations.yml'
|
319
318
|
end
|
320
|
-
|
321
|
-
|
319
|
+
|
320
|
+
it { should eql(nil) }
|
321
|
+
end
|
322
|
+
|
323
|
+
context 'when given locale is in `.js_available_locales` but its translation is missing' do
|
324
|
+
subject { translations[:fr][:fallback_test] }
|
325
|
+
|
326
|
+
let(:available_locales) { %i[fr pirate] }
|
327
|
+
|
328
|
+
before do
|
329
|
+
allow(described_class).to receive(:js_available_locales).and_return(available_locales)
|
330
|
+
set_config 'js_file_per_locale_with_fallbacks_as_locale_without_fallback_translations.yml'
|
322
331
|
end
|
323
332
|
|
324
|
-
it {should eql(nil)}
|
333
|
+
it { should eql(nil) }
|
325
334
|
end
|
326
335
|
|
327
336
|
context "with I18n::Fallbacks enabled" do
|
@@ -385,27 +394,67 @@ EOS
|
|
385
394
|
end
|
386
395
|
end
|
387
396
|
|
388
|
-
|
397
|
+
describe '.js_available_locales' do
|
398
|
+
subject { described_class.js_available_locales }
|
399
|
+
|
400
|
+
let(:results) { described_class.scoped_translations('*.admin.*.title') }
|
401
|
+
let(:result) { ->(locale) { results[locale][:admin][:show][:title] } }
|
389
402
|
|
390
|
-
context
|
391
|
-
it
|
392
|
-
result = I18n::JS.scoped_translations("*.admin.*.title")
|
403
|
+
context 'when I18n.available_locales is not set' do
|
404
|
+
it { expect(subject).to eq ::I18n.available_locales }
|
393
405
|
|
394
|
-
|
395
|
-
expect(result
|
396
|
-
expect(result
|
406
|
+
it 'should allow all locales' do
|
407
|
+
expect(result.call(:en)).to eql('Show')
|
408
|
+
expect(result.call(:fr)).to eql('Visualiser')
|
409
|
+
expect(result.call(:ja)).to eql('Ignore me')
|
397
410
|
end
|
398
411
|
end
|
399
412
|
|
400
|
-
context
|
401
|
-
|
413
|
+
context 'when I18n.available_locales is set' do
|
414
|
+
let(:available_locales) { %i[en fr] }
|
415
|
+
|
416
|
+
before { allow(::I18n).to receive(:available_locales).and_return(available_locales) }
|
417
|
+
|
418
|
+
it { expect(subject).to eq available_locales }
|
419
|
+
|
420
|
+
it 'should ignore non-valid locales' do
|
421
|
+
expect(result.call(:en)).to eql('Show')
|
422
|
+
expect(result.call(:fr)).to eql('Visualiser')
|
423
|
+
expect(results).not_to include(:ja)
|
424
|
+
end
|
425
|
+
|
426
|
+
context 'when :js_available_locales set in config' do
|
427
|
+
before { set_config 'js_available_locales_custom.yml' }
|
402
428
|
|
403
|
-
|
404
|
-
|
429
|
+
it { expect(subject).to eq %i[en foo] }
|
430
|
+
|
431
|
+
it 'should ignore non-valid locales' do
|
432
|
+
expect(result.call(:en)).to eql('Show')
|
433
|
+
expect(results).not_to include(:fr, :ja)
|
434
|
+
end
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
context 'I18n.available_locales' do
|
440
|
+
let(:results) { described_class.scoped_translations('*.admin.*.title') }
|
441
|
+
let(:result) { ->(locale) { results[locale][:admin][:show][:title] } }
|
442
|
+
|
443
|
+
context 'when I18n.available_locales is not set' do
|
444
|
+
it 'should allow all locales' do
|
445
|
+
expect(result.call(:en)).to eql('Show')
|
446
|
+
expect(result.call(:fr)).to eql('Visualiser')
|
447
|
+
expect(result.call(:ja)).to eql('Ignore me')
|
448
|
+
end
|
449
|
+
end
|
450
|
+
|
451
|
+
context 'when I18n.available_locales is set' do
|
452
|
+
before { allow(::I18n).to receive(:available_locales){ [:en, :fr] } }
|
405
453
|
|
406
|
-
|
407
|
-
expect(result
|
408
|
-
expect(result.
|
454
|
+
it 'should ignore non-valid locales' do
|
455
|
+
expect(result.call(:en)).to eql('Show')
|
456
|
+
expect(result.call(:fr)).to eql('Visualiser')
|
457
|
+
expect(results).not_to include(:ja)
|
409
458
|
end
|
410
459
|
end
|
411
460
|
end
|
@@ -599,7 +648,7 @@ EOS
|
|
599
648
|
it "exports with the keys sorted" do
|
600
649
|
expect(subject).to eq <<EOS
|
601
650
|
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"}});
|
651
|
+
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
652
|
EOS
|
604
653
|
end
|
605
654
|
end
|
@@ -628,13 +677,13 @@ EOS
|
|
628
677
|
|
629
678
|
expect(subject).to eq <<EOS
|
630
679
|
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\"}}}}});
|
680
|
+
I18n.translations[\"de\"] = I18n.extend((I18n.translations[\"de\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}}'));
|
681
|
+
I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}}'));
|
682
|
+
I18n.translations[\"en-US\"] = I18n.extend((I18n.translations[\"en-US\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}}'));
|
683
|
+
I18n.translations[\"es\"] = I18n.extend((I18n.translations[\"es\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":{\"one\":\"millón\",\"other\":\"millones\"}}}}}}'));
|
684
|
+
I18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}}'));
|
685
|
+
I18n.translations[\"ja\"] = I18n.extend((I18n.translations[\"ja\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}}'));
|
686
|
+
I18n.translations[\"ru\"] = I18n.extend((I18n.translations[\"ru\"] || {}), JSON.parse('{\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}}'));
|
638
687
|
EOS
|
639
688
|
end
|
640
689
|
end
|
@@ -648,8 +697,8 @@ EOS
|
|
648
697
|
output = File.read(File.join(I18n::JS.export_i18n_js_dir_path, "js_extend_parent.js"))
|
649
698
|
expect(output).to eq(<<EOS
|
650
699
|
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\"}}};
|
700
|
+
I18n.translations[\"en\"] = JSON.parse('{\"date\":{\"formats\":{\"default\":\"%Y-%m-%d\",\"long\":\"%B %d, %Y\",\"short\":\"%b %d\"}}}');
|
701
|
+
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
702
|
EOS
|
654
703
|
)
|
655
704
|
end
|
@@ -663,8 +712,8 @@ EOS
|
|
663
712
|
output = File.read(File.join(I18n::JS.export_i18n_js_dir_path, "js_extend_segment.js"))
|
664
713
|
expect(output).to eq(<<EOS
|
665
714
|
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\"}}};
|
715
|
+
I18n.translations[\"en\"] = JSON.parse('{\"date\":{\"formats\":{\"default\":\"%Y-%m-%d\",\"long\":\"%B %d, %Y\",\"short\":\"%b %d\"}}}');
|
716
|
+
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
717
|
EOS
|
669
718
|
)
|
670
719
|
end
|
@@ -686,7 +735,7 @@ EOS
|
|
686
735
|
|
687
736
|
expect(subject).to eq <<EOS
|
688
737
|
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\"}});
|
738
|
+
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
739
|
EOS
|
691
740
|
end
|
692
741
|
end
|
@@ -707,13 +756,13 @@ EOS
|
|
707
756
|
|
708
757
|
expect(subject).to eq <<EOS
|
709
758
|
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\":\"кошек\"}});
|
759
|
+
I18n.translations[\"de\"] = I18n.extend((I18n.translations[\"de\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}}'));
|
760
|
+
I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}}'));
|
761
|
+
I18n.translations[\"en-US\"] = I18n.extend((I18n.translations[\"en-US\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}}'));
|
762
|
+
I18n.translations[\"es\"] = I18n.extend((I18n.translations[\"es\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}}'));
|
763
|
+
I18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}}'));
|
764
|
+
I18n.translations[\"ja\"] = I18n.extend((I18n.translations[\"ja\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}}'));
|
765
|
+
I18n.translations[\"ru\"] = I18n.extend((I18n.translations[\"ru\"] || {}), JSON.parse('{\"merge_plurals_with_no_overrides\":{\"few\":\"кошек\",\"many\":\"кошка\",\"one\":\"кот\",\"other\":\"кошек\"}}'));
|
717
766
|
EOS
|
718
767
|
end
|
719
768
|
end
|
@@ -735,13 +784,13 @@ EOS
|
|
735
784
|
|
736
785
|
expect(subject).to eq <<EOS
|
737
786
|
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\"}});
|
787
|
+
I18n.translations[\"de\"] = I18n.extend((I18n.translations[\"de\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}}'));
|
788
|
+
I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}}'));
|
789
|
+
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\"}}'));
|
790
|
+
I18n.translations[\"es\"] = I18n.extend((I18n.translations[\"es\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}}'));
|
791
|
+
I18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}}'));
|
792
|
+
I18n.translations[\"ja\"] = I18n.extend((I18n.translations[\"ja\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}}'));
|
793
|
+
I18n.translations[\"ru\"] = I18n.extend((I18n.translations[\"ru\"] || {}), JSON.parse('{\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}}'));
|
745
794
|
EOS
|
746
795
|
end
|
747
796
|
end
|
data/yarn.lock
CHANGED
@@ -13,9 +13,10 @@ brace-expansion@^1.1.7:
|
|
13
13
|
balanced-match "^1.0.0"
|
14
14
|
concat-map "0.0.1"
|
15
15
|
|
16
|
-
coffeescript
|
17
|
-
version "
|
18
|
-
resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-
|
16
|
+
coffeescript@~1.12.7:
|
17
|
+
version "1.12.7"
|
18
|
+
resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-1.12.7.tgz#e57ee4c4867cf7f606bfc4a0f2d550c0981ddd27"
|
19
|
+
integrity sha512-pLXHFxQMPklVoEekowk8b3erNynC+DVJzChxS/LCBBgR6/8AJkHivkm//zbowcfc7BTCAjryuhx6gPqPRfsFoA==
|
19
20
|
|
20
21
|
concat-map@0.0.1:
|
21
22
|
version "0.0.1"
|
@@ -50,9 +51,10 @@ globule@^1.0.0:
|
|
50
51
|
lodash "~4.17.10"
|
51
52
|
minimatch "~3.0.2"
|
52
53
|
|
53
|
-
growl@^1.10.
|
54
|
+
growl@^1.10.5:
|
54
55
|
version "1.10.5"
|
55
56
|
resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e"
|
57
|
+
integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==
|
56
58
|
|
57
59
|
inflight@^1.0.4:
|
58
60
|
version "1.0.6"
|
@@ -65,24 +67,26 @@ inherits@2:
|
|
65
67
|
version "2.0.3"
|
66
68
|
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
67
69
|
|
68
|
-
jasmine-growl-reporter@~
|
69
|
-
version "
|
70
|
-
resolved "https://registry.yarnpkg.com/jasmine-growl-reporter/-/jasmine-growl-reporter-
|
70
|
+
jasmine-growl-reporter@~2.0.0:
|
71
|
+
version "2.0.0"
|
72
|
+
resolved "https://registry.yarnpkg.com/jasmine-growl-reporter/-/jasmine-growl-reporter-2.0.0.tgz#4943a2481193d66a8a68ee2f38b6c360fb037859"
|
73
|
+
integrity sha512-RYwVfPaGgxQQSHDOt6jQ99/KAkFQ/Fiwg/AzBS+uO9A4UhGhxb7hwXaUUSU/Zs0MxBoFNqmIRC+7P4/+5O3lXg==
|
71
74
|
dependencies:
|
72
|
-
growl "^1.10.
|
75
|
+
growl "^1.10.5"
|
73
76
|
|
74
|
-
jasmine-node@^
|
75
|
-
version "
|
76
|
-
resolved "https://registry.yarnpkg.com/jasmine-node/-/jasmine-node-
|
77
|
+
jasmine-node@^3.0.0:
|
78
|
+
version "3.0.0"
|
79
|
+
resolved "https://registry.yarnpkg.com/jasmine-node/-/jasmine-node-3.0.0.tgz#f12b6fdd24633402ec23e8ea6fef6ffbcb464f90"
|
80
|
+
integrity sha512-vUa5Q7bQYwHHqi6FlJYndiKqZp+d+c3MKe0QUMwwrC4JRmoRV3zkg0buxB/uQ6qLh0NO34TNstpAnvaZ6xGlAA==
|
77
81
|
dependencies:
|
78
|
-
coffeescript "
|
82
|
+
coffeescript "~1.12.7"
|
79
83
|
gaze "~1.1.2"
|
80
|
-
jasmine-growl-reporter "~
|
84
|
+
jasmine-growl-reporter "~2.0.0"
|
81
85
|
jasmine-reporters "~1.0.0"
|
82
86
|
mkdirp "~0.3.5"
|
83
|
-
requirejs "
|
84
|
-
underscore "
|
85
|
-
walkdir "
|
87
|
+
requirejs "~2.3.6"
|
88
|
+
underscore "~1.9.1"
|
89
|
+
walkdir "~0.0.12"
|
86
90
|
|
87
91
|
jasmine-reporters@~1.0.0:
|
88
92
|
version "1.0.2"
|
@@ -91,8 +95,8 @@ jasmine-reporters@~1.0.0:
|
|
91
95
|
mkdirp "~0.3.5"
|
92
96
|
|
93
97
|
lodash@~4.17.10:
|
94
|
-
version "4.17.
|
95
|
-
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.
|
98
|
+
version "4.17.21"
|
99
|
+
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
96
100
|
|
97
101
|
minimatch@^3.0.4, minimatch@~3.0.2:
|
98
102
|
version "3.0.4"
|
@@ -114,17 +118,20 @@ path-is-absolute@^1.0.0:
|
|
114
118
|
version "1.0.1"
|
115
119
|
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
116
120
|
|
117
|
-
requirejs
|
118
|
-
version "2.3.
|
119
|
-
resolved "https://registry.yarnpkg.com/requirejs/-/requirejs-2.3.
|
121
|
+
requirejs@~2.3.6:
|
122
|
+
version "2.3.6"
|
123
|
+
resolved "https://registry.yarnpkg.com/requirejs/-/requirejs-2.3.6.tgz#e5093d9601c2829251258c0b9445d4d19fa9e7c9"
|
124
|
+
integrity sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg==
|
120
125
|
|
121
|
-
|
122
|
-
version "1.9.
|
123
|
-
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.
|
126
|
+
underscore@~1.9.1:
|
127
|
+
version "1.9.2"
|
128
|
+
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.2.tgz#0c8d6f536d6f378a5af264a72f7bec50feb7cf2f"
|
129
|
+
integrity sha512-D39qtimx0c1fI3ya1Lnhk3E9nONswSKhnffBI0gME9C99fYOkNi04xs8K6pePLhvl1frbDemkaBQ5ikWllR2HQ==
|
124
130
|
|
125
|
-
|
131
|
+
walkdir@~0.0.12:
|
126
132
|
version "0.0.12"
|
127
133
|
resolved "https://registry.yarnpkg.com/walkdir/-/walkdir-0.0.12.tgz#2f24f1ade64aab1e458591d4442c8868356e9281"
|
134
|
+
integrity sha512-HFhaD4mMWPzFSqhpyDG48KDdrjfn409YQuVW7ckZYhW4sE87mYtWifdB/+73RA7+p4s4K18n5Jfx1kHthE1gBw==
|
128
135
|
|
129
136
|
wrappy@1:
|
130
137
|
version "1.0.2"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i18n-js
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nando Vieira
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: i18n
|
@@ -152,6 +152,7 @@ files:
|
|
152
152
|
- spec/fixtures/default.yml
|
153
153
|
- spec/fixtures/erb.yml
|
154
154
|
- spec/fixtures/except_condition.yml
|
155
|
+
- spec/fixtures/js_available_locales_custom.yml
|
155
156
|
- spec/fixtures/js_export_dir_custom.yml
|
156
157
|
- spec/fixtures/js_export_dir_none.yml
|
157
158
|
- spec/fixtures/js_extend_parent.yml
|
@@ -189,6 +190,7 @@ files:
|
|
189
190
|
- spec/js/jasmine/jasmine.css
|
190
191
|
- spec/js/jasmine/jasmine.js
|
191
192
|
- spec/js/jasmine/jasmine_favicon.png
|
193
|
+
- spec/js/json_parsable.spec.js
|
192
194
|
- spec/js/locales.spec.js
|
193
195
|
- spec/js/localization.spec.js
|
194
196
|
- spec/js/numbers.spec.js
|
@@ -226,7 +228,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
226
228
|
- !ruby/object:Gem::Version
|
227
229
|
version: '0'
|
228
230
|
requirements: []
|
229
|
-
rubygems_version: 3.2.
|
231
|
+
rubygems_version: 3.2.24
|
230
232
|
signing_key:
|
231
233
|
specification_version: 4
|
232
234
|
summary: It's a small library to provide the Rails I18n translations on the Javascript.
|
@@ -235,6 +237,7 @@ test_files:
|
|
235
237
|
- spec/fixtures/default.yml
|
236
238
|
- spec/fixtures/erb.yml
|
237
239
|
- spec/fixtures/except_condition.yml
|
240
|
+
- spec/fixtures/js_available_locales_custom.yml
|
238
241
|
- spec/fixtures/js_export_dir_custom.yml
|
239
242
|
- spec/fixtures/js_export_dir_none.yml
|
240
243
|
- spec/fixtures/js_extend_parent.yml
|
@@ -272,6 +275,7 @@ test_files:
|
|
272
275
|
- spec/js/jasmine/jasmine.css
|
273
276
|
- spec/js/jasmine/jasmine.js
|
274
277
|
- spec/js/jasmine/jasmine_favicon.png
|
278
|
+
- spec/js/json_parsable.spec.js
|
275
279
|
- spec/js/locales.spec.js
|
276
280
|
- spec/js/localization.spec.js
|
277
281
|
- spec/js/numbers.spec.js
|