i18n-js 3.8.1 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|