i18n-js 3.0.0.rc14 → 3.0.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/.travis.yml +8 -6
- data/Appraisals +4 -0
- data/CHANGELOG.md +56 -1
- data/README.md +38 -5
- data/app/assets/javascripts/i18n/filtered.js.erb +15 -10
- data/app/assets/javascripts/i18n.js +112 -37
- data/gemfiles/i18n_0_8.gemfile +7 -0
- data/i18n-js.gemspec +4 -4
- data/lib/i18n/js/engine.rb +4 -1
- data/lib/i18n/js/fallback_locales.rb +0 -11
- data/lib/i18n/js/middleware.rb +9 -1
- data/lib/i18n/js/private/hash_with_symbol_keys.rb +36 -0
- data/lib/i18n/js/segment.rb +9 -1
- data/lib/i18n/js/version.rb +1 -6
- data/lib/i18n/js.rb +33 -12
- data/package.json +1 -1
- data/spec/js/extend.spec.js +24 -1
- data/spec/js/interpolation.spec.js +11 -0
- data/spec/js/pluralization.spec.js +105 -0
- data/spec/js/translate.spec.js +5 -0
- data/spec/js/translations.js +6 -0
- data/spec/ruby/i18n/js/fallback_locales_spec.rb +1 -11
- data/spec/ruby/i18n/js_spec.rb +1 -1
- data/spec/spec_helper.rb +4 -2
- metadata +10 -23
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 353417f345acd62bc99d23f7a5fec4009cc0ee3e
|
|
4
|
+
data.tar.gz: f06f7d88940146630ad37d71dc64d0ed7e746a75
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 40cb6d125502a38e0a9e87bb57fb57f3a4913ad6647a0431bd9c81cfa40b60b37b77562bec24c93c0a3b40687be33163107c63e9af7abc7a2d35a323dfc8fcee
|
|
7
|
+
data.tar.gz: a6503dbaecb63aa9638f348e28625df2854399dd5c4cacacc776a13f2fdfd88aef8ca21f0aed3d6b6e1cb56571c83d8ca270ba6f949c4b14c452cdf177472fcd
|
data/.travis.yml
CHANGED
|
@@ -5,18 +5,20 @@ language: ruby
|
|
|
5
5
|
cache:
|
|
6
6
|
- bundler
|
|
7
7
|
rvm:
|
|
8
|
-
- 2.
|
|
9
|
-
- 2.
|
|
10
|
-
- 2.2
|
|
8
|
+
- 2.1.10
|
|
9
|
+
- 2.2.5
|
|
11
10
|
# Since the Travis Build Env does not recognize `2.3` alias yet
|
|
12
11
|
# We need to specify the version precisely
|
|
13
|
-
- 2.3.
|
|
12
|
+
- 2.3.3
|
|
13
|
+
- 2.4.0
|
|
14
14
|
- ruby-head
|
|
15
|
-
before_install:
|
|
16
|
-
|
|
15
|
+
before_install:
|
|
16
|
+
# Need to install something extra to test JS
|
|
17
|
+
- npm install
|
|
17
18
|
gemfile:
|
|
18
19
|
- gemfiles/i18n_0_6.gemfile
|
|
19
20
|
- gemfiles/i18n_0_7.gemfile
|
|
21
|
+
- gemfiles/i18n_0_8.gemfile
|
|
20
22
|
matrix:
|
|
21
23
|
fast_finish: true
|
|
22
24
|
allow_failures:
|
data/Appraisals
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
All notable changes to this project will be documented in this file.
|
|
3
3
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
|
4
4
|
|
|
5
|
+
|
|
5
6
|
## [Unreleased]
|
|
6
7
|
|
|
7
8
|
### Added
|
|
@@ -17,6 +18,57 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
|
17
18
|
- Nothing
|
|
18
19
|
|
|
19
20
|
|
|
21
|
+
## [3.0.0] - 2017-04-01
|
|
22
|
+
|
|
23
|
+
This is a fake official release, the *real* one will be `3.0.0.rc17`
|
|
24
|
+
And today is not April Fools' Day
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- Ends the longest Release Candidate period among all ruby gems
|
|
29
|
+
(v3.0.0.rc1 released at 2012-05-10)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
## [3.0.0.rc16] - 2017-03-13
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- [Ruby] Drop support for Ruby < `2.1.0`
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
|
|
40
|
+
- [JS] Make defaultValue works on plural translation
|
|
41
|
+
- [JS] Fix UMD pattern so the global/root won’t be undefined
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
## [3.0.0.rc15] - 2016-12-07
|
|
45
|
+
|
|
46
|
+
### Added
|
|
47
|
+
|
|
48
|
+
- Nothing
|
|
49
|
+
|
|
50
|
+
### Changed
|
|
51
|
+
|
|
52
|
+
- [JS] Allow `defaultValue` to work in pluralization
|
|
53
|
+
(PR: https://github.com/fnando/i18n-js/pull/433)
|
|
54
|
+
- [Ruby] Stop validating the fallback locales against `I18n.available_locales`
|
|
55
|
+
This allows some locales to be used as fallback locales, but not to be generated in JS.
|
|
56
|
+
(PR: https://github.com/fnando/i18n-js/pull/425)
|
|
57
|
+
- [Ruby] Remove dependency on gem `activesupport`
|
|
58
|
+
|
|
59
|
+
### Fixed
|
|
60
|
+
|
|
61
|
+
- [JS] Stop converting numeric & boolean values into objects
|
|
62
|
+
when merging objects with `I18n.extend`
|
|
63
|
+
(PR: https://github.com/fnando/i18n-js/pull/420)
|
|
64
|
+
- [JS] Fix I18n pluralization fallback when tree is empty
|
|
65
|
+
(PR: https://github.com/fnando/i18n-js/pull/435)
|
|
66
|
+
- [Ruby] Use old syntax to define lambda for compatibility with older Rubies
|
|
67
|
+
(Issue: https://github.com/fnando/i18n-js/issues/419)
|
|
68
|
+
- [Ruby] Fix error raised in middleware cache cleaning in parallel test
|
|
69
|
+
(Issue: https://github.com/fnando/i18n-js/issues/436)
|
|
70
|
+
|
|
71
|
+
|
|
20
72
|
## [3.0.0.rc14] - 2016-08-29
|
|
21
73
|
|
|
22
74
|
### Changed
|
|
@@ -188,7 +240,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
|
188
240
|
|
|
189
241
|
|
|
190
242
|
|
|
191
|
-
[Unreleased]: https://github.com/fnando/i18n-js/compare/v3.0.0
|
|
243
|
+
[Unreleased]: https://github.com/fnando/i18n-js/compare/v3.0.0...HEAD
|
|
244
|
+
[3.0.0]: https://github.com/fnando/i18n-js/compare/v3.0.0.rc16...v3.0.0
|
|
245
|
+
[3.0.0.rc16]: https://github.com/fnando/i18n-js/compare/v3.0.0.rc15...v3.0.0.rc16
|
|
246
|
+
[3.0.0.rc15]: https://github.com/fnando/i18n-js/compare/v3.0.0.rc14...v3.0.0.rc15
|
|
192
247
|
[3.0.0.rc14]: https://github.com/fnando/i18n-js/compare/v3.0.0.rc13...v3.0.0.rc14
|
|
193
248
|
[3.0.0.rc13]: https://github.com/fnando/i18n-js/compare/v3.0.0.rc12...v3.0.0.rc13
|
|
194
249
|
[3.0.0.rc12]: https://github.com/fnando/i18n-js/compare/v3.0.0.rc11...v3.0.0.rc12
|
data/README.md
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
# I18n.js
|
|
2
2
|
|
|
3
|
+
[](http://badge.fury.io/rb/i18n-js)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
|
|
3
6
|
[](https://travis-ci.org/fnando/i18n-js)
|
|
7
|
+
[](https://gemnasium.com/fnando/i18n-js)
|
|
4
8
|
[](https://codeclimate.com/github/fnando/i18n-js)
|
|
9
|
+
|
|
5
10
|
[](https://gitter.im/fnando/i18n-js)
|
|
6
11
|
|
|
7
12
|
It's a small library to provide the Rails I18n translations on the JavaScript.
|
|
@@ -27,11 +32,7 @@ The `master` branch (including this README) is for latest `3.0.0.rc` instead of
|
|
|
27
32
|
|
|
28
33
|
Add the gem to your Gemfile.
|
|
29
34
|
```ruby
|
|
30
|
-
|
|
31
|
-
gem "rails", "your_rails_version"
|
|
32
|
-
# You only need this RC version constraint during the development of `3.0.0`, once stable version is released you can remove `rc11` suffix
|
|
33
|
-
# `3.0.0.rc11` is the latest version of released RC version when this entry is changed, you might want to change it later
|
|
34
|
-
gem "i18n-js", ">= 3.0.0.rc11"
|
|
35
|
+
gem "i18n-js"
|
|
35
36
|
```
|
|
36
37
|
|
|
37
38
|
#### Rails app with [Asset Pipeline](http://guides.rubyonrails.org/asset_pipeline.html)
|
|
@@ -603,6 +604,27 @@ The accepted formats are:
|
|
|
603
604
|
|
|
604
605
|
Check out `spec/*.spec.js` files for more examples!
|
|
605
606
|
|
|
607
|
+
#### Using pluralization and number formatting together
|
|
608
|
+
Sometimes you might want to display translation with formatted number, like adding thousand delimiters to displayed number
|
|
609
|
+
You can do this:
|
|
610
|
+
```json
|
|
611
|
+
{
|
|
612
|
+
"en": {
|
|
613
|
+
"point": {
|
|
614
|
+
"one": "1 Point",
|
|
615
|
+
"other": "{{formatted_number}} Points",
|
|
616
|
+
"zero": "0 Points"
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
```
|
|
621
|
+
```js
|
|
622
|
+
var point_in_number = 1000;
|
|
623
|
+
I18n.t('point', { count: point_in_number, formatted_number: I18n.toNumber(point_in_number) });
|
|
624
|
+
```
|
|
625
|
+
Output should be `1,000 points`
|
|
626
|
+
|
|
627
|
+
|
|
606
628
|
## Using multiple exported translation files on a page.
|
|
607
629
|
This method is useful for very large apps where a single contained translations.js file is not desirable. Examples would be a global translations file and a more specific route translation file.
|
|
608
630
|
|
|
@@ -742,6 +764,7 @@ I18n.translations["pt-BR"] = {
|
|
|
742
764
|
}
|
|
743
765
|
```
|
|
744
766
|
|
|
767
|
+
|
|
745
768
|
## Known Issues
|
|
746
769
|
|
|
747
770
|
### Missing translations in precompiled file(s) after adding any new locale file
|
|
@@ -774,6 +797,16 @@ This means that new locale files will not be detected, and so they will not trig
|
|
|
774
797
|
|
|
775
798
|
**Note:** See issue [#213](https://github.com/fnando/i18n-js/issues/213) for more details and discussion of this issue.
|
|
776
799
|
|
|
800
|
+
### Translations in JS are not updated when Sprockets not loaded before this gem
|
|
801
|
+
|
|
802
|
+
The "rails engine" declaration will try to detect existence of "sprockets" before adding the initailizer
|
|
803
|
+
If sprockets is loaded after this gem, the preprocessor for
|
|
804
|
+
making JS translations file cache to depend on content of locale files will not be hooked.
|
|
805
|
+
So ensure sprockets is loaded before this gem like moving entry of sprockets in Gemfile or adding "require" statements for sprockets somewhere.
|
|
806
|
+
|
|
807
|
+
**Note:** See issue [#404](https://github.com/fnando/i18n-js/issues/404) for more details and discussion of this issue.
|
|
808
|
+
|
|
809
|
+
|
|
777
810
|
## Maintainer
|
|
778
811
|
|
|
779
812
|
- Nando Vieira - <http://nandovieira.com.br>
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
<%# encoding: utf-8 %>
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
// AMD
|
|
9
|
-
define([
|
|
3
|
+
// Using UMD pattern from
|
|
4
|
+
// https://github.com/umdjs/umd#regular-module
|
|
5
|
+
// `returnExports.js` version
|
|
6
|
+
;(function (root, factory) {
|
|
7
|
+
if (typeof define === 'function' && define.amd) {
|
|
8
|
+
// AMD. Register as an anonymous module.
|
|
9
|
+
define(["i18n"], factory);
|
|
10
|
+
} else if (typeof module === 'object' && module.exports) {
|
|
11
|
+
// Node. Does not work with strict CommonJS, but
|
|
12
|
+
// only CommonJS-like environments that support module.exports,
|
|
13
|
+
// like Node.
|
|
14
|
+
factory(require("i18n"));
|
|
10
15
|
} else {
|
|
11
|
-
// Browser globals
|
|
12
|
-
factory(
|
|
16
|
+
// Browser globals (root is window)
|
|
17
|
+
factory(root.I18n);
|
|
13
18
|
}
|
|
14
|
-
}(function(I18n) {
|
|
19
|
+
}(this, function(I18n) {
|
|
15
20
|
"use strict";
|
|
16
21
|
|
|
17
22
|
I18n.translations = <%= I18n::JS.filtered_translations.to_json %>;
|
|
@@ -12,19 +12,23 @@
|
|
|
12
12
|
// See tests for specific formatting like numbers and dates.
|
|
13
13
|
//
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
// AMD
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
// Using UMD pattern from
|
|
16
|
+
// https://github.com/umdjs/umd#regular-module
|
|
17
|
+
// `returnExports.js` version
|
|
18
|
+
;(function (root, factory) {
|
|
19
|
+
if (typeof define === 'function' && define.amd) {
|
|
20
|
+
// AMD. Register as an anonymous module.
|
|
21
|
+
define("i18n", function(){ return factory(root);});
|
|
22
|
+
} else if (typeof module === 'object' && module.exports) {
|
|
23
|
+
// Node. Does not work with strict CommonJS, but
|
|
24
|
+
// only CommonJS-like environments that support module.exports,
|
|
25
|
+
// like Node.
|
|
26
|
+
module.exports = factory(root);
|
|
23
27
|
} else {
|
|
24
|
-
// Browser globals
|
|
25
|
-
|
|
28
|
+
// Browser globals (root is window)
|
|
29
|
+
root.I18n = factory(root);
|
|
26
30
|
}
|
|
27
|
-
}(function(global) {
|
|
31
|
+
}(this, function(global) {
|
|
28
32
|
"use strict";
|
|
29
33
|
|
|
30
34
|
// Use previously defined object if exists in current scope
|
|
@@ -53,11 +57,23 @@
|
|
|
53
57
|
|
|
54
58
|
// Is a given value an array?
|
|
55
59
|
// Borrowed from Underscore.js
|
|
56
|
-
var isArray = function(
|
|
60
|
+
var isArray = function(val) {
|
|
57
61
|
if (Array.isArray) {
|
|
58
|
-
return Array.isArray(
|
|
62
|
+
return Array.isArray(val);
|
|
59
63
|
};
|
|
60
|
-
return Object.prototype.toString.call(
|
|
64
|
+
return Object.prototype.toString.call(val) === '[object Array]';
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
var isString = function(val) {
|
|
68
|
+
return typeof value == 'string' || Object.prototype.toString.call(val) === '[object String]';
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
var isNumber = function(val) {
|
|
72
|
+
return typeof val == 'number' || Object.prototype.toString.call(val) === '[object Number]';
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
var isBoolean = function(val) {
|
|
76
|
+
return val === true || val === false;
|
|
61
77
|
};
|
|
62
78
|
|
|
63
79
|
var decimalAdjust = function(type, value, exp) {
|
|
@@ -83,7 +99,7 @@
|
|
|
83
99
|
var key, value;
|
|
84
100
|
for (key in obj) if (obj.hasOwnProperty(key)) {
|
|
85
101
|
value = obj[key];
|
|
86
|
-
if (
|
|
102
|
+
if (isString(value) || isNumber(value) || isBoolean(value)) {
|
|
87
103
|
dest[key] = value;
|
|
88
104
|
} else {
|
|
89
105
|
if (dest[key] == null) dest[key] = {};
|
|
@@ -347,7 +363,6 @@
|
|
|
347
363
|
if (!translations) {
|
|
348
364
|
continue;
|
|
349
365
|
}
|
|
350
|
-
|
|
351
366
|
while (scopes.length) {
|
|
352
367
|
translations = translations[scopes.shift()];
|
|
353
368
|
|
|
@@ -366,6 +381,75 @@
|
|
|
366
381
|
}
|
|
367
382
|
};
|
|
368
383
|
|
|
384
|
+
// lookup pluralization rule key into translations
|
|
385
|
+
I18n.pluralizationLookupWithoutFallback = function(count, locale, translations) {
|
|
386
|
+
var pluralizer = this.pluralization.get(locale)
|
|
387
|
+
, pluralizerKeys = pluralizer(count)
|
|
388
|
+
, pluralizerKey
|
|
389
|
+
, message;
|
|
390
|
+
|
|
391
|
+
if (isObject(translations)) {
|
|
392
|
+
while (pluralizerKeys.length) {
|
|
393
|
+
pluralizerKey = pluralizerKeys.shift();
|
|
394
|
+
if (this.isSet(translations[pluralizerKey])) {
|
|
395
|
+
message = translations[pluralizerKey];
|
|
396
|
+
break;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
return message;
|
|
402
|
+
};
|
|
403
|
+
|
|
404
|
+
// Lookup dedicated to pluralization
|
|
405
|
+
I18n.pluralizationLookup = function(count, scope, options) {
|
|
406
|
+
options = this.prepareOptions(options);
|
|
407
|
+
var locales = this.locales.get(options.locale).slice()
|
|
408
|
+
, requestedLocale = locales[0]
|
|
409
|
+
, locale
|
|
410
|
+
, scopes
|
|
411
|
+
, translations
|
|
412
|
+
, message
|
|
413
|
+
;
|
|
414
|
+
scope = this.getFullScope(scope, options);
|
|
415
|
+
|
|
416
|
+
while (locales.length) {
|
|
417
|
+
locale = locales.shift();
|
|
418
|
+
scopes = scope.split(this.defaultSeparator);
|
|
419
|
+
translations = this.translations[locale];
|
|
420
|
+
|
|
421
|
+
if (!translations) {
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
while (scopes.length) {
|
|
426
|
+
translations = translations[scopes.shift()];
|
|
427
|
+
if (!isObject(translations)) {
|
|
428
|
+
break;
|
|
429
|
+
}
|
|
430
|
+
if (scopes.length == 0) {
|
|
431
|
+
message = this.pluralizationLookupWithoutFallback(count, locale, translations);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
if (message != null && message != undefined) {
|
|
435
|
+
break;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
if (message == null || message == undefined) {
|
|
440
|
+
if (this.isSet(options.defaultValue)) {
|
|
441
|
+
if (isObject(options.defaultValue)) {
|
|
442
|
+
message = this.pluralizationLookupWithoutFallback(count, options.locale, options.defaultValue);
|
|
443
|
+
} else {
|
|
444
|
+
message = options.defaultValue;
|
|
445
|
+
}
|
|
446
|
+
translations = options.defaultValue;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
return { message: message, translations: translations };
|
|
451
|
+
};
|
|
452
|
+
|
|
369
453
|
// Rails changed the way the meridian is stored.
|
|
370
454
|
// It started with `date.meridian` returning an array,
|
|
371
455
|
// then it switched to `time.am` and `time.pm`.
|
|
@@ -445,6 +529,7 @@
|
|
|
445
529
|
I18n.translate = function(scope, options) {
|
|
446
530
|
options = this.prepareOptions(options);
|
|
447
531
|
|
|
532
|
+
var copiedOptions = this.prepareOptions(options);
|
|
448
533
|
var translationOptions = this.createTranslationOptions(scope, options);
|
|
449
534
|
|
|
450
535
|
var translation;
|
|
@@ -470,7 +555,7 @@
|
|
|
470
555
|
if (typeof(translation) === "string") {
|
|
471
556
|
translation = this.interpolate(translation, options);
|
|
472
557
|
} else if (isObject(translation) && this.isSet(options.count)) {
|
|
473
|
-
translation = this.pluralize(options.count,
|
|
558
|
+
translation = this.pluralize(options.count, scope, copiedOptions);
|
|
474
559
|
}
|
|
475
560
|
|
|
476
561
|
return translation;
|
|
@@ -516,32 +601,22 @@
|
|
|
516
601
|
// which will be retrieved from `options`.
|
|
517
602
|
I18n.pluralize = function(count, scope, options) {
|
|
518
603
|
options = this.prepareOptions(options);
|
|
519
|
-
var
|
|
604
|
+
var pluralizer, message, result;
|
|
520
605
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
} else {
|
|
524
|
-
translations = this.lookup(scope, options);
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
if (!translations) {
|
|
606
|
+
result = this.pluralizationLookup(count, scope, options);
|
|
607
|
+
if (result.translations == undefined || result.translations == null) {
|
|
528
608
|
return this.missingTranslation(scope, options);
|
|
529
609
|
}
|
|
530
610
|
|
|
531
|
-
|
|
532
|
-
keys = pluralizer(count);
|
|
533
|
-
|
|
534
|
-
while (keys.length) {
|
|
535
|
-
key = keys.shift();
|
|
611
|
+
options.count = String(count);
|
|
536
612
|
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
613
|
+
if (result.message != undefined && result.message != null) {
|
|
614
|
+
return this.interpolate(result.message, options);
|
|
615
|
+
}
|
|
616
|
+
else {
|
|
617
|
+
pluralizer = this.pluralization.get(options.locale);
|
|
618
|
+
return this.missingTranslation(scope + '.' + pluralizer(count)[0], options);
|
|
541
619
|
}
|
|
542
|
-
|
|
543
|
-
options.count = String(count);
|
|
544
|
-
return this.interpolate(message, options);
|
|
545
620
|
};
|
|
546
621
|
|
|
547
622
|
// Return a missing translation message for the given parameters.
|
data/i18n-js.gemspec
CHANGED
|
@@ -4,7 +4,7 @@ require "i18n/js/version"
|
|
|
4
4
|
|
|
5
5
|
Gem::Specification.new do |s|
|
|
6
6
|
s.name = "i18n-js"
|
|
7
|
-
s.version = I18n::JS::
|
|
7
|
+
s.version = I18n::JS::VERSION
|
|
8
8
|
s.platform = Gem::Platform::RUBY
|
|
9
9
|
s.authors = ["Nando Vieira"]
|
|
10
10
|
s.email = ["fnando.vieira@gmail.com"]
|
|
@@ -19,11 +19,11 @@ Gem::Specification.new do |s|
|
|
|
19
19
|
s.require_paths = ["lib"]
|
|
20
20
|
|
|
21
21
|
s.add_dependency "i18n", "~> 0.6", ">= 0.6.6"
|
|
22
|
+
|
|
22
23
|
s.add_development_dependency "appraisal", "~> 2.0"
|
|
23
|
-
s.add_development_dependency "activesupport", ">= 3.2.22"
|
|
24
24
|
s.add_development_dependency "rspec", "~> 3.0"
|
|
25
|
-
s.add_development_dependency "rake", "~>
|
|
25
|
+
s.add_development_dependency "rake", "~> 12.0"
|
|
26
26
|
s.add_development_dependency "gem-release", ">= 0.7"
|
|
27
27
|
|
|
28
|
-
s.required_ruby_version = ">= 1.
|
|
28
|
+
s.required_ruby_version = ">= 2.1.0"
|
|
29
29
|
end
|
data/lib/i18n/js/engine.rb
CHANGED
|
@@ -32,8 +32,11 @@ module I18n
|
|
|
32
32
|
#
|
|
33
33
|
# For detail see Pull Request:
|
|
34
34
|
# https://github.com/fnando/i18n-js/pull/371
|
|
35
|
+
#
|
|
36
|
+
# Not using -> for JRuby compatibility
|
|
37
|
+
# See https://github.com/fnando/i18n-js/issues/419
|
|
35
38
|
initializer_args = case sprockets_version
|
|
36
|
-
when
|
|
39
|
+
when lambda {|v| v2_only.match?("", v) || v3_plus.match?("", v) }
|
|
37
40
|
{ after: :engines_blank_point, before: :finisher_hook }
|
|
38
41
|
else
|
|
39
42
|
raise StandardError, "Sprockets version #{sprockets_version} is not supported"
|
|
@@ -32,7 +32,6 @@ module I18n
|
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
locales.map! { |locale| locale.to_sym }
|
|
35
|
-
ensure_valid_locales!(locales)
|
|
36
35
|
locales
|
|
37
36
|
end
|
|
38
37
|
|
|
@@ -66,16 +65,6 @@ module I18n
|
|
|
66
65
|
|
|
67
66
|
fail ArgumentError, "If fallbacks is passed as Array, it must ony include Strings or Symbols. Given: #{fallbacks}"
|
|
68
67
|
end
|
|
69
|
-
|
|
70
|
-
# Ensures that only valid locales are returned.
|
|
71
|
-
#
|
|
72
|
-
# @note
|
|
73
|
-
# This ignores option `I18n.enforce_available_locales`
|
|
74
|
-
def ensure_valid_locales!(locales)
|
|
75
|
-
if locales.any? { |locale| !::I18n.available_locales.include?(locale) }
|
|
76
|
-
fail ArgumentError, "Valid locales: #{::I18n.available_locales.join(", ")} - Given Locales: #{locales.join(", ")}"
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
68
|
end
|
|
80
69
|
end
|
|
81
70
|
end
|
data/lib/i18n/js/middleware.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require "fileutils"
|
|
2
|
+
|
|
1
3
|
module I18n
|
|
2
4
|
module JS
|
|
3
5
|
class Middleware
|
|
@@ -32,7 +34,13 @@ module I18n
|
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
def clear_cache
|
|
35
|
-
File.delete
|
|
37
|
+
# `File.delete` will raise error when "multiple worker"
|
|
38
|
+
# Are running at the same time, like in a parallel test
|
|
39
|
+
#
|
|
40
|
+
# `FileUtils.rm_f` is tested manually
|
|
41
|
+
#
|
|
42
|
+
# See https://github.com/fnando/i18n-js/issues/436
|
|
43
|
+
FileUtils.rm_f(cache_path) if File.exist?(cache_path)
|
|
36
44
|
end
|
|
37
45
|
|
|
38
46
|
def save_cache(new_cache)
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module I18n
|
|
2
|
+
module JS
|
|
3
|
+
# @api private
|
|
4
|
+
module Private
|
|
5
|
+
# Hash with string keys converted to symbol keys
|
|
6
|
+
# Used for handling values read on YAML
|
|
7
|
+
#
|
|
8
|
+
# @api private
|
|
9
|
+
class HashWithSymbolKeys < ::Hash
|
|
10
|
+
# An instance can only be created by passing in another hash
|
|
11
|
+
def initialize(hash)
|
|
12
|
+
raise TypeError unless hash.is_a?(::Hash)
|
|
13
|
+
|
|
14
|
+
hash.each_key do |key|
|
|
15
|
+
# Objects like `Integer` does not have `to_sym`
|
|
16
|
+
new_key = key.respond_to?(:to_sym) ? key.to_sym : key
|
|
17
|
+
self[new_key] = hash[key]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
self.default = hash.default if hash.default
|
|
21
|
+
self.default_proc = hash.default_proc if hash.default_proc
|
|
22
|
+
|
|
23
|
+
freeze
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# From AS Core extension
|
|
27
|
+
def slice(*keys)
|
|
28
|
+
hash = keys.each_with_object(Hash.new) do |k, hash|
|
|
29
|
+
hash[k] = self[k] if has_key?(k)
|
|
30
|
+
end
|
|
31
|
+
self.class.new(hash)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/i18n/js/segment.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require "i18n/js/private/hash_with_symbol_keys"
|
|
2
|
+
|
|
1
3
|
module I18n
|
|
2
4
|
module JS
|
|
3
5
|
|
|
@@ -10,7 +12,13 @@ module I18n
|
|
|
10
12
|
|
|
11
13
|
def initialize(file, translations, options = {})
|
|
12
14
|
@file = file
|
|
13
|
-
|
|
15
|
+
# `#slice` will be used
|
|
16
|
+
# But when activesupport is absent,
|
|
17
|
+
# the core extension from `i18n` gem will be used instead
|
|
18
|
+
# And it's causing errors (at least in test)
|
|
19
|
+
#
|
|
20
|
+
# So the input is wrapped by our class for better `#slice`
|
|
21
|
+
@translations = Private::HashWithSymbolKeys.new(translations)
|
|
14
22
|
@namespace = options[:namespace] || 'I18n'
|
|
15
23
|
@pretty_print = !!options[:pretty_print]
|
|
16
24
|
@js_extend = options.key?(:js_extend) ? !!options[:js_extend] : true
|
data/lib/i18n/js/version.rb
CHANGED
data/lib/i18n/js.rb
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
require "yaml"
|
|
2
|
-
require "i18n"
|
|
3
2
|
require "fileutils"
|
|
3
|
+
require "i18n"
|
|
4
|
+
|
|
4
5
|
require "i18n/js/utils"
|
|
6
|
+
require "i18n/js/private/hash_with_symbol_keys"
|
|
5
7
|
|
|
6
8
|
module I18n
|
|
7
9
|
module JS
|
|
@@ -43,16 +45,23 @@ module I18n
|
|
|
43
45
|
end
|
|
44
46
|
|
|
45
47
|
def self.configured_segments
|
|
46
|
-
config[:translations].inject([]) do |segments,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
48
|
+
config[:translations].inject([]) do |segments, options_hash|
|
|
49
|
+
options_hash_with_symbol_keys = Private::HashWithSymbolKeys.new(options_hash)
|
|
50
|
+
file = options_hash_with_symbol_keys[:file]
|
|
51
|
+
only = options_hash_with_symbol_keys[:only] || '*'
|
|
52
|
+
exceptions = [options_hash_with_symbol_keys[:except] || []].flatten
|
|
50
53
|
|
|
51
54
|
result = segment_for_scope(only, exceptions)
|
|
52
55
|
|
|
53
56
|
merge_with_fallbacks!(result) if fallbacks
|
|
54
57
|
|
|
55
|
-
|
|
58
|
+
unless result.empty?
|
|
59
|
+
segments << Segment.new(
|
|
60
|
+
file,
|
|
61
|
+
result,
|
|
62
|
+
extract_segment_options(options_hash_with_symbol_keys),
|
|
63
|
+
)
|
|
64
|
+
end
|
|
56
65
|
|
|
57
66
|
segments
|
|
58
67
|
end
|
|
@@ -91,11 +100,13 @@ module I18n
|
|
|
91
100
|
# custom output directory
|
|
92
101
|
def self.config
|
|
93
102
|
if config?
|
|
94
|
-
|
|
95
|
-
|
|
103
|
+
erb_result_from_yaml_file = ERB.new(File.read(config_file_path)).result
|
|
104
|
+
Private::HashWithSymbolKeys.new(
|
|
105
|
+
(::YAML.load(erb_result_from_yaml_file) || {})
|
|
106
|
+
)
|
|
96
107
|
else
|
|
97
|
-
{}
|
|
98
|
-
end
|
|
108
|
+
Private::HashWithSymbolKeys.new({})
|
|
109
|
+
end.freeze
|
|
99
110
|
end
|
|
100
111
|
|
|
101
112
|
# Check if configuration file exist
|
|
@@ -151,7 +162,14 @@ module I18n
|
|
|
151
162
|
def self.translations
|
|
152
163
|
::I18n.backend.instance_eval do
|
|
153
164
|
init_translations unless initialized?
|
|
154
|
-
|
|
165
|
+
# When activesupport is absent,
|
|
166
|
+
# the core extension (`#slice`) from `i18n` gem will be used instead
|
|
167
|
+
# And it's causing errors (at least in test)
|
|
168
|
+
#
|
|
169
|
+
# So the input is wrapped by our class for better `#slice`
|
|
170
|
+
Private::HashWithSymbolKeys.new(translations).
|
|
171
|
+
slice(*::I18n.available_locales).
|
|
172
|
+
to_h
|
|
155
173
|
end
|
|
156
174
|
end
|
|
157
175
|
|
|
@@ -184,7 +202,10 @@ module I18n
|
|
|
184
202
|
end
|
|
185
203
|
|
|
186
204
|
def self.extract_segment_options(options)
|
|
187
|
-
segment_options = {
|
|
205
|
+
segment_options = Private::HashWithSymbolKeys.new({
|
|
206
|
+
js_extend: js_extend,
|
|
207
|
+
sort_translation_keys: sort_translation_keys?,
|
|
208
|
+
}).freeze
|
|
188
209
|
segment_options.merge(options.slice(*Segment::OPTIONS))
|
|
189
210
|
end
|
|
190
211
|
|
data/package.json
CHANGED
data/spec/js/extend.spec.js
CHANGED
|
@@ -58,5 +58,28 @@ describe("Extend", function () {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
expect(I18n.extend(obj1, obj2)).toEqual(expected);
|
|
61
|
-
})
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("should correctly merge string, numberic and boolean values", function() {
|
|
64
|
+
var obj1 = {
|
|
65
|
+
test1: {
|
|
66
|
+
test2: false
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
, obj2 = {
|
|
70
|
+
test1: {
|
|
71
|
+
test3: 23,
|
|
72
|
+
test4: 'abc'
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
, expected = {
|
|
76
|
+
test1: {
|
|
77
|
+
test2: false
|
|
78
|
+
, test3: 23
|
|
79
|
+
, test4: 'abc'
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
expect(I18n.extend(obj1, obj2)).toEqual(expected);
|
|
84
|
+
});
|
|
62
85
|
});
|
|
@@ -46,6 +46,17 @@ describe("Interpolation", function(){
|
|
|
46
46
|
expect(I18n.t(translation_key, {count: 5})).toEqual("Hello World!");
|
|
47
47
|
});
|
|
48
48
|
});
|
|
49
|
+
describe("and translation key does contain pluralization with null content", function() {
|
|
50
|
+
beforeEach(function() {
|
|
51
|
+
translation_key = "sent";
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("return empty string", function() {
|
|
55
|
+
expect(I18n.t(translation_key, {count: 0})).toEqual('[missing "en.sent.zero" translation]');
|
|
56
|
+
expect(I18n.t(translation_key, {count: 1})).toEqual('[missing "en.sent.one" translation]');
|
|
57
|
+
expect(I18n.t(translation_key, {count: 5})).toEqual('[missing "en.sent.other" translation]');
|
|
58
|
+
});
|
|
59
|
+
});
|
|
49
60
|
});
|
|
50
61
|
|
|
51
62
|
describe("when count is NOT passed in", function() {
|
|
@@ -57,6 +57,16 @@ describe("Pluralization", function(){
|
|
|
57
57
|
expect(I18n.p(0, "inbox")).toEqual("");
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
+
it("returns missing message on null values", function(){
|
|
61
|
+
I18n.translations["en"]["sent"]["zero"] = null;
|
|
62
|
+
I18n.translations["en"]["sent"]["one"] = null;
|
|
63
|
+
I18n.translations["en"]["sent"]["other"] = null;
|
|
64
|
+
|
|
65
|
+
expect(I18n.p(0, "sent")).toEqual('[missing "en.sent.zero" translation]');
|
|
66
|
+
expect(I18n.p(1, "sent")).toEqual('[missing "en.sent.one" translation]');
|
|
67
|
+
expect(I18n.p(5, "sent")).toEqual('[missing "en.sent.other" translation]');
|
|
68
|
+
});
|
|
69
|
+
|
|
60
70
|
it("pluralizes using custom rules", function() {
|
|
61
71
|
I18n.locale = "custom";
|
|
62
72
|
|
|
@@ -103,4 +113,99 @@ describe("Pluralization", function(){
|
|
|
103
113
|
expect(I18n.p(1, "inbox", options)).toEqual("You have 1 message");
|
|
104
114
|
expect(I18n.p(5, "inbox", options)).toEqual("You have 5 messages");
|
|
105
115
|
});
|
|
116
|
+
|
|
117
|
+
it("fallback to default locale when I18n.fallbacks is enabled", function() {
|
|
118
|
+
I18n.locale = "pt-BR";
|
|
119
|
+
I18n.fallbacks = true;
|
|
120
|
+
I18n.translations["pt-BR"].inbox= {
|
|
121
|
+
one: null
|
|
122
|
+
, other: null
|
|
123
|
+
, zero: null
|
|
124
|
+
};
|
|
125
|
+
expect(I18n.p(0, "inbox", { count: 0 })).toEqual("You have no messages");
|
|
126
|
+
expect(I18n.p(1, "inbox", { count: 1 })).toEqual("You have 1 message");
|
|
127
|
+
expect(I18n.p(5, "inbox", { count: 5 })).toEqual("You have 5 messages");
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
it("fallback to default locale when I18n.fallbacks is enabled", function() {
|
|
131
|
+
I18n.locale = "pt-BR";
|
|
132
|
+
I18n.fallbacks = true;
|
|
133
|
+
I18n.translations["pt-BR"].inbox= {
|
|
134
|
+
one: "Você tem uma mensagem"
|
|
135
|
+
, other: null
|
|
136
|
+
, zero: "Você não tem nenhuma mensagem"
|
|
137
|
+
};
|
|
138
|
+
expect(I18n.p(0, "inbox", { count: 0 })).toEqual("Você não tem nenhuma mensagem");
|
|
139
|
+
expect(I18n.p(1, "inbox", { count: 1 })).toEqual("Você tem uma mensagem");
|
|
140
|
+
expect(I18n.p(5, "inbox", { count: 5 })).toEqual('You have 5 messages');
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it("fallback to 'other' scope", function() {
|
|
144
|
+
I18n.locale = "pt-BR";
|
|
145
|
+
I18n.fallbacks = true;
|
|
146
|
+
I18n.translations["pt-BR"].inbox= {
|
|
147
|
+
one: "Você tem uma mensagem"
|
|
148
|
+
, other: "Você tem {{count}} mensagens"
|
|
149
|
+
, zero: null
|
|
150
|
+
}
|
|
151
|
+
expect(I18n.p(0, "inbox", { count: 0 })).toEqual("Você tem 0 mensagens");
|
|
152
|
+
expect(I18n.p(1, "inbox", { count: 1 })).toEqual("Você tem uma mensagem");
|
|
153
|
+
expect(I18n.p(5, "inbox", { count: 5 })).toEqual("Você tem 5 mensagens");
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it("fallback to defaulValue when defaultValue is string", function() {
|
|
157
|
+
I18n.locale = "pt-BR";
|
|
158
|
+
I18n.fallbacks = true;
|
|
159
|
+
I18n.translations["en"]["inbox"]["zero"] = null;
|
|
160
|
+
I18n.translations["en"]["inbox"]["one"] = null;
|
|
161
|
+
I18n.translations["en"]["inbox"]["other"] = null;
|
|
162
|
+
I18n.translations["pt-BR"].inbox= {
|
|
163
|
+
one: "Você tem uma mensagem"
|
|
164
|
+
, other: null
|
|
165
|
+
, zero: null
|
|
166
|
+
}
|
|
167
|
+
options = {
|
|
168
|
+
defaultValue: "default message"
|
|
169
|
+
};
|
|
170
|
+
expect(I18n.p(0, "inbox", options)).toEqual("default message");
|
|
171
|
+
expect(I18n.p(1, "inbox", options)).toEqual("Você tem uma mensagem");
|
|
172
|
+
expect(I18n.p(5, "inbox", options)).toEqual("default message");
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it("fallback to defaulValue when defaultValue is an object", function() {
|
|
176
|
+
I18n.locale = "pt-BR";
|
|
177
|
+
I18n.fallbacks = true;
|
|
178
|
+
I18n.translations["en"]["inbox"]["zero"] = null;
|
|
179
|
+
I18n.translations["en"]["inbox"]["one"] = null;
|
|
180
|
+
I18n.translations["en"]["inbox"]["other"] = null;
|
|
181
|
+
I18n.translations["pt-BR"].inbox= {
|
|
182
|
+
one: "Você tem uma mensagem"
|
|
183
|
+
, other: null
|
|
184
|
+
, zero: null
|
|
185
|
+
}
|
|
186
|
+
options = {
|
|
187
|
+
defaultValue: {
|
|
188
|
+
zero: "default message for no message"
|
|
189
|
+
, one: "default message for 1 message"
|
|
190
|
+
, other: "default message for {{count}} messages"
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
expect(I18n.p(0, "inbox", options)).toEqual("default message for no message");
|
|
194
|
+
expect(I18n.p(1, "inbox", options)).toEqual("Você tem uma mensagem");
|
|
195
|
+
expect(I18n.p(5, "inbox", options)).toEqual("default message for 5 messages");
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it("fallback to default locale when I18n.fallbacks is enabled and no translations in sub scope", function() {
|
|
199
|
+
I18n.locale = "pt-BR";
|
|
200
|
+
I18n.fallbacks = true;
|
|
201
|
+
I18n.translations["en"]["mailbox"] = {
|
|
202
|
+
inbox: I18n.translations["en"].inbox
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
expect(I18n.translations["pt-BR"]["mailbox"]).toEqual(undefined);
|
|
206
|
+
expect(I18n.p(0, "mailbox.inbox", { count: 0 })).toEqual("You have no messages");
|
|
207
|
+
expect(I18n.p(1, "mailbox.inbox", { count: 1 })).toEqual("You have 1 message");
|
|
208
|
+
expect(I18n.p(5, "mailbox.inbox", { count: 5 })).toEqual("You have 5 messages");
|
|
209
|
+
});
|
|
210
|
+
|
|
106
211
|
});
|
data/spec/js/translate.spec.js
CHANGED
|
@@ -152,6 +152,11 @@ describe("Translate", function(){
|
|
|
152
152
|
expect(actual).toEqual("Warning!");
|
|
153
153
|
});
|
|
154
154
|
|
|
155
|
+
it("uses default value for plural translation", function(){
|
|
156
|
+
actual = I18n.t("message", {defaultValue: { one: '%{count} message', other: '%{count} messages'}, count: 1});
|
|
157
|
+
expect(actual).toEqual("1 message");
|
|
158
|
+
});
|
|
159
|
+
|
|
155
160
|
it("uses default value for unknown locale", function(){
|
|
156
161
|
I18n.locale = "fr";
|
|
157
162
|
actual = I18n.t("warning", {defaultValue: "Warning!"});
|
data/spec/js/translations.js
CHANGED
|
@@ -30,6 +30,12 @@ var DEBUG = false;
|
|
|
30
30
|
, zero: "You have no messages"
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
, sent: {
|
|
34
|
+
one: null
|
|
35
|
+
, other: null
|
|
36
|
+
, zero: null
|
|
37
|
+
}
|
|
38
|
+
|
|
33
39
|
, unread: {
|
|
34
40
|
one: "You have 1 new message ({{unread}} unread)"
|
|
35
41
|
, other: "You have {{count}} new messages ({{unread}} unread)"
|
|
@@ -42,7 +42,7 @@ describe I18n::JS::FallbackLocales do
|
|
|
42
42
|
|
|
43
43
|
context "when given a invalid locale as fallbacks" do
|
|
44
44
|
let(:fallbacks) { :invalid_locale }
|
|
45
|
-
it {
|
|
45
|
+
it { should eq([:invalid_locale]) }
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
context "when given a invalid type as fallbacks" do
|
|
@@ -50,16 +50,6 @@ describe I18n::JS::FallbackLocales do
|
|
|
50
50
|
it { expect(fetching_locales).to raise_error(ArgumentError) }
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
context "when given an invalid Array as fallbacks" do
|
|
54
|
-
let(:fallbacks) { [:de, :en, :invalid_locale] }
|
|
55
|
-
it { expect(fetching_locales).to raise_error(ArgumentError) }
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
context "when given a invalid Hash as fallbacks" do
|
|
59
|
-
let(:fallbacks) do { :fr => [:de, :en, :invalid_locale] } end
|
|
60
|
-
it { expect(fetching_locales).to raise_error(ArgumentError) }
|
|
61
|
-
end
|
|
62
|
-
|
|
63
53
|
# I18n::Backend::Fallbacks
|
|
64
54
|
context "when I18n::Backend::Fallbacks is used" do
|
|
65
55
|
let(:backend_with_fallbacks) { backend_class_with_fallbacks.new }
|
data/spec/ruby/i18n/js_spec.rb
CHANGED
|
@@ -405,7 +405,7 @@ EOS
|
|
|
405
405
|
it "executes erb in config file" do
|
|
406
406
|
set_config "erb.yml"
|
|
407
407
|
|
|
408
|
-
config_entry = I18n::JS.config[
|
|
408
|
+
config_entry = I18n::JS.config[:translations].first
|
|
409
409
|
config_entry["only"].should eq("*.date.formats")
|
|
410
410
|
end
|
|
411
411
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
require "i18n"
|
|
2
2
|
require "json"
|
|
3
3
|
|
|
4
|
-
require "active_support/all"
|
|
5
4
|
require "i18n/js"
|
|
6
5
|
|
|
7
6
|
module Helpers
|
|
8
7
|
# Set the configuration as the current one
|
|
9
8
|
def set_config(path)
|
|
10
9
|
config_file_path = File.dirname(__FILE__) + "/fixtures/#{path}"
|
|
11
|
-
I18n::JS.
|
|
10
|
+
allow(I18n::JS).to receive_messages(
|
|
11
|
+
:config? => true,
|
|
12
|
+
:config_file_path => config_file_path,
|
|
13
|
+
)
|
|
12
14
|
end
|
|
13
15
|
|
|
14
16
|
# Shortcut to I18n::JS.translations
|
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.0.0
|
|
4
|
+
version: 3.0.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:
|
|
11
|
+
date: 2017-04-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: i18n
|
|
@@ -44,20 +44,6 @@ dependencies:
|
|
|
44
44
|
- - "~>"
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
46
|
version: '2.0'
|
|
47
|
-
- !ruby/object:Gem::Dependency
|
|
48
|
-
name: activesupport
|
|
49
|
-
requirement: !ruby/object:Gem::Requirement
|
|
50
|
-
requirements:
|
|
51
|
-
- - ">="
|
|
52
|
-
- !ruby/object:Gem::Version
|
|
53
|
-
version: 3.2.22
|
|
54
|
-
type: :development
|
|
55
|
-
prerelease: false
|
|
56
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
-
requirements:
|
|
58
|
-
- - ">="
|
|
59
|
-
- !ruby/object:Gem::Version
|
|
60
|
-
version: 3.2.22
|
|
61
47
|
- !ruby/object:Gem::Dependency
|
|
62
48
|
name: rspec
|
|
63
49
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -78,14 +64,14 @@ dependencies:
|
|
|
78
64
|
requirements:
|
|
79
65
|
- - "~>"
|
|
80
66
|
- !ruby/object:Gem::Version
|
|
81
|
-
version: '
|
|
67
|
+
version: '12.0'
|
|
82
68
|
type: :development
|
|
83
69
|
prerelease: false
|
|
84
70
|
version_requirements: !ruby/object:Gem::Requirement
|
|
85
71
|
requirements:
|
|
86
72
|
- - "~>"
|
|
87
73
|
- !ruby/object:Gem::Version
|
|
88
|
-
version: '
|
|
74
|
+
version: '12.0'
|
|
89
75
|
- !ruby/object:Gem::Dependency
|
|
90
76
|
name: gem-release
|
|
91
77
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -120,6 +106,7 @@ files:
|
|
|
120
106
|
- app/assets/javascripts/i18n/translations.js
|
|
121
107
|
- gemfiles/i18n_0_6.gemfile
|
|
122
108
|
- gemfiles/i18n_0_7.gemfile
|
|
109
|
+
- gemfiles/i18n_0_8.gemfile
|
|
123
110
|
- i18n-js.gemspec
|
|
124
111
|
- lib/i18n-js.rb
|
|
125
112
|
- lib/i18n/js.rb
|
|
@@ -127,6 +114,7 @@ files:
|
|
|
127
114
|
- lib/i18n/js/engine.rb
|
|
128
115
|
- lib/i18n/js/fallback_locales.rb
|
|
129
116
|
- lib/i18n/js/middleware.rb
|
|
117
|
+
- lib/i18n/js/private/hash_with_symbol_keys.rb
|
|
130
118
|
- lib/i18n/js/segment.rb
|
|
131
119
|
- lib/i18n/js/utils.rb
|
|
132
120
|
- lib/i18n/js/version.rb
|
|
@@ -200,15 +188,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
200
188
|
requirements:
|
|
201
189
|
- - ">="
|
|
202
190
|
- !ruby/object:Gem::Version
|
|
203
|
-
version: 1.
|
|
191
|
+
version: 2.1.0
|
|
204
192
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
205
193
|
requirements:
|
|
206
|
-
- - "
|
|
194
|
+
- - ">="
|
|
207
195
|
- !ruby/object:Gem::Version
|
|
208
|
-
version:
|
|
196
|
+
version: '0'
|
|
209
197
|
requirements: []
|
|
210
198
|
rubyforge_project:
|
|
211
|
-
rubygems_version: 2.6.
|
|
199
|
+
rubygems_version: 2.6.11
|
|
212
200
|
signing_key:
|
|
213
201
|
specification_version: 4
|
|
214
202
|
summary: It's a small library to provide the Rails I18n translations on the Javascript.
|
|
@@ -267,4 +255,3 @@ test_files:
|
|
|
267
255
|
- spec/ruby/i18n/js/utils_spec.rb
|
|
268
256
|
- spec/ruby/i18n/js_spec.rb
|
|
269
257
|
- spec/spec_helper.rb
|
|
270
|
-
has_rdoc:
|