i18n-js 3.4.1 → 3.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8e97276215fc1d53677d4a73d8fa078d476fbb6400047e43b42ea723eb0df22d
4
- data.tar.gz: 496f8b37aeaceed790124ddbe359ac11831aa83b9b61a39ae1634ecff2187837
3
+ metadata.gz: dbf33a6af551aff2ea13db6c39e84c568f426aaaacd78b1a27524917a05cc580
4
+ data.tar.gz: a7ba15b0084e0eed0eb8a9f3692131c8786401a3ed257217d0d6ba43cdefd3d3
5
5
  SHA512:
6
- metadata.gz: 7ee645b6b5040548d97df6dbccdbcb90f3f8093ed361c5e83abd822de102bbcf963778b60bc7c76a31f6ada69afe20c1422a420ff052f37eb816d1ef3a22155e
7
- data.tar.gz: 395386008e73365635030bddb34a6211d0bc7914fd1822184b3a14a92097d3693ee5834a4cca85f41d584f2b7e46ec528b0fc285d63a9fd93925ee3ffe7c5ab5
6
+ metadata.gz: f5bb0487ef02b35454d86e92c9d1634cee3ac9eaa302fcc19044e22c80491682fe4e5c44eef2d6aa90ff91ff0f15db4f2bd7539b4de8e66773be54ba880b193d
7
+ data.tar.gz: f6d56fb7550b4cce0d02e25cf98b38be75cfc3d0cb9cfe3ac0ba050621a08363b7ff49abc4ddc5803d8ac3be3f864bbb3187bb3476e18e91479484f8accd0622
@@ -12,6 +12,7 @@ rvm:
12
12
  - 2.4
13
13
  - 2.5
14
14
  - 2.6
15
+ - 2.7
15
16
  - ruby-head
16
17
  before_install:
17
18
  # Needed to test JS
@@ -29,6 +30,7 @@ gemfile:
29
30
  - gemfiles/i18n_1_5.gemfile
30
31
  - gemfiles/i18n_1_6.gemfile
31
32
  - gemfiles/i18n_1_7.gemfile
33
+ - gemfiles/i18n_1_8.gemfile
32
34
  matrix:
33
35
  fast_finish: true
34
36
  allow_failures:
data/Appraisals CHANGED
@@ -38,3 +38,7 @@ end
38
38
  appraise "i18n_1_7" do
39
39
  gem "i18n", "~> 1.7.0"
40
40
  end
41
+
42
+ appraise "i18n_1_8" do
43
+ gem "i18n", "~> 1.8.0"
44
+ end
@@ -18,6 +18,46 @@ This project adheres to [Semantic Versioning](http://semver.org/).
18
18
  - Nothing
19
19
 
20
20
 
21
+ ## [3.7.0] - 2020-05-29
22
+
23
+ ### Added
24
+
25
+ - [JS] Allow options to be passed in when calling `I18n.localize`/`I18n.l`
26
+ (PR: https://github.com/fnando/i18n-js/pull/570)
27
+
28
+
29
+ ## [3.6.0] - 2020-02-14
30
+
31
+ ### Added
32
+
33
+ - [Ruby] Allow `suffix` to be added to generated translations files
34
+ (PR: https://github.com/fnando/i18n-js/pull/561)
35
+
36
+
37
+ ## [3.5.1] - 2019-12-21
38
+
39
+ ### Changed
40
+
41
+ - [JS] Bound shortcut functions
42
+ (PR: https://github.com/fnando/i18n-js/pull/560)
43
+
44
+
45
+ ## [3.5.0] - 2019-11-12
46
+
47
+ ### Added
48
+
49
+ - [JS] Support for `%k` strftime format to match Ruby strftime
50
+ (PR: https://github.com/fnando/i18n-js/pull/554)
51
+
52
+
53
+ ## [3.4.2] - 2019-11-11
54
+
55
+ ### Fixed
56
+
57
+ - [Ruby] Fix regression introduced in PR #551
58
+ (PR: https://github.com/fnando/i18n-js/pull/555)
59
+
60
+
21
61
  ## [3.4.1] - 2019-11-01
22
62
 
23
63
  ### Fixed
@@ -417,7 +457,12 @@ And today is not April Fools' Day
417
457
 
418
458
 
419
459
 
420
- [Unreleased]: https://github.com/fnando/i18n-js/compare/v3.4.1...HEAD
460
+ [Unreleased]: https://github.com/fnando/i18n-js/compare/v3.7.0...HEAD
461
+ [3.6.0]: https://github.com/fnando/i18n-js/compare/v3.6.0...v3.7.0
462
+ [3.6.0]: https://github.com/fnando/i18n-js/compare/v3.5.1...v3.6.0
463
+ [3.5.1]: https://github.com/fnando/i18n-js/compare/v3.5.0...v3.5.1
464
+ [3.5.0]: https://github.com/fnando/i18n-js/compare/v3.4.2...v3.5.0
465
+ [3.4.2]: https://github.com/fnando/i18n-js/compare/v3.4.1...v3.4.2
421
466
  [3.4.1]: https://github.com/fnando/i18n-js/compare/v3.4.0...v3.4.1
422
467
  [3.4.0]: https://github.com/fnando/i18n-js/compare/v3.3.0...v3.4.0
423
468
  [3.3.0]: https://github.com/fnando/i18n-js/compare/v3.2.3...v3.3.0
data/README.md CHANGED
@@ -248,9 +248,9 @@ MyNamespace.translations["en"] = { ... }
248
248
  ```
249
249
 
250
250
 
251
- ### Adding a line at the beginning of the translations file (useful for imports)
251
+ ### Adding prefix & suffix to the translations file(s)
252
252
 
253
- Setting the `prefix: "import I18n from 'i18n-js';\n"` option will add the line at the beggining of the resultant translation file.
253
+ Setting the `prefix: "import I18n from 'i18n-js';\n"` option will add the line at the beginning of the resultant translation file.
254
254
  This can be useful to use this gem with the [i18n-js](https://www.npmjs.com/package/i18n-js) npm package, which is quite useful to use it with webpack.
255
255
  The user should provide the semi-colon and the newline character if needed.
256
256
 
@@ -267,6 +267,11 @@ will create:
267
267
  ```
268
268
  import I18n from 'i18n-js';
269
269
  I18n.translations || (I18n.translations = {});
270
+ ```
271
+
272
+
273
+ `suffix` option is added in https://github.com/fnando/i18n-js/pull/561.
274
+ It's similar to `prefix` so won't explain it in details.
270
275
 
271
276
 
272
277
  #### Pretty Print
@@ -623,7 +628,7 @@ The accepted formats for `I18n.strftime` are:
623
628
  %d - Day of the month (01..31)
624
629
  %-d - Day of the month (1..31)
625
630
  %H - Hour of the day, 24-hour clock (00..23)
626
- %-H - Hour of the day, 24-hour clock (0..23)
631
+ %-H/%k - Hour of the day, 24-hour clock (0..23)
627
632
  %I - Hour of the day, 12-hour clock (01..12)
628
633
  %-I/%l - Hour of the day, 12-hour clock (1..12)
629
634
  %m - Month of the year (01..12)
@@ -779,8 +779,8 @@
779
779
  I18n.toCurrency = function(number, options) {
780
780
  options = this.prepareOptions(
781
781
  options
782
- , this.lookup("number.currency.format")
783
- , this.lookup("number.format")
782
+ , this.lookup("number.currency.format", options)
783
+ , this.lookup("number.format", options)
784
784
  , CURRENCY_FORMAT
785
785
  );
786
786
 
@@ -799,17 +799,17 @@
799
799
 
800
800
  switch (scope) {
801
801
  case "currency":
802
- return this.toCurrency(value);
802
+ return this.toCurrency(value, options);
803
803
  case "number":
804
- scope = this.lookup("number.format");
804
+ scope = this.lookup("number.format", options);
805
805
  return this.toNumber(value, scope);
806
806
  case "percentage":
807
- return this.toPercentage(value);
807
+ return this.toPercentage(value, options);
808
808
  default:
809
809
  var localizedValue;
810
810
 
811
811
  if (scope.match(/^(date|time)/)) {
812
- localizedValue = this.toTime(scope, value);
812
+ localizedValue = this.toTime(scope, value, options);
813
813
  } else {
814
814
  localizedValue = value.toString();
815
815
  }
@@ -897,7 +897,7 @@
897
897
  // %d - Day of the month (01..31)
898
898
  // %-d - Day of the month (1..31)
899
899
  // %H - Hour of the day, 24-hour clock (00..23)
900
- // %-H - Hour of the day, 24-hour clock (0..23)
900
+ // %-H/%k - Hour of the day, 24-hour clock (0..23)
901
901
  // %I - Hour of the day, 12-hour clock (01..12)
902
902
  // %-I/%l - Hour of the day, 12-hour clock (1..12)
903
903
  // %m - Month of the year (01..12)
@@ -914,8 +914,8 @@
914
914
  // %Y - Year with century
915
915
  // %z/%Z - Timezone offset (+0545)
916
916
  //
917
- I18n.strftime = function(date, format) {
918
- var options = this.lookup("date")
917
+ I18n.strftime = function(date, format, options) {
918
+ var options = this.lookup("date", options)
919
919
  , meridianOptions = I18n.meridian()
920
920
  ;
921
921
 
@@ -961,6 +961,7 @@
961
961
  format = format.replace("%-d", day);
962
962
  format = format.replace("%H", padding(hour));
963
963
  format = format.replace("%-H", hour);
964
+ format = format.replace("%k", hour);
964
965
  format = format.replace("%I", padding(hour12));
965
966
  format = format.replace("%-I", hour12);
966
967
  format = format.replace("%l", hour12);
@@ -983,9 +984,9 @@
983
984
  };
984
985
 
985
986
  // Convert the given dateString into a formatted date.
986
- I18n.toTime = function(scope, dateString) {
987
+ I18n.toTime = function(scope, dateString, options) {
987
988
  var date = this.parseDate(dateString)
988
- , format = this.lookup(scope)
989
+ , format = this.lookup(scope, options)
989
990
  ;
990
991
 
991
992
  // A date input of `null` or `undefined` will be returned as-is
@@ -1002,15 +1003,15 @@
1002
1003
  return date_string;
1003
1004
  }
1004
1005
 
1005
- return this.strftime(date, format);
1006
+ return this.strftime(date, format, options);
1006
1007
  };
1007
1008
 
1008
1009
  // Convert a number into a formatted percentage value.
1009
1010
  I18n.toPercentage = function(number, options) {
1010
1011
  options = this.prepareOptions(
1011
1012
  options
1012
- , this.lookup("number.percentage.format")
1013
- , this.lookup("number.format")
1013
+ , this.lookup("number.percentage.format", options)
1014
+ , this.lookup("number.format", options)
1014
1015
  , PERCENTAGE_FORMAT
1015
1016
  );
1016
1017
 
@@ -1083,9 +1084,9 @@
1083
1084
  };
1084
1085
 
1085
1086
  // Set aliases, so we can save some typing.
1086
- I18n.t = I18n.translate;
1087
- I18n.l = I18n.localize;
1088
- I18n.p = I18n.pluralize;
1087
+ I18n.t = I18n.translate.bind(I18n);
1088
+ I18n.l = I18n.localize.bind(I18n);
1089
+ I18n.p = I18n.pluralize.bind(I18n);
1089
1090
 
1090
1091
  return I18n;
1091
1092
  }));
@@ -206,3 +206,35 @@ if (!Array.prototype.map) {
206
206
  return A;
207
207
  };
208
208
  }
209
+
210
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind
211
+ if (!Function.prototype.bind) (function(){
212
+ var ArrayPrototypeSlice = Array.prototype.slice;
213
+ Function.prototype.bind = function(otherThis) {
214
+ if (typeof this !== 'function') {
215
+ // closest thing possible to the ECMAScript 5
216
+ // internal IsCallable function
217
+ throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
218
+ }
219
+
220
+ var baseArgs= ArrayPrototypeSlice .call(arguments, 1),
221
+ baseArgsLength = baseArgs.length,
222
+ fToBind = this,
223
+ fNOP = function() {},
224
+ fBound = function() {
225
+ baseArgs.length = baseArgsLength; // reset to default base arguments
226
+ baseArgs.push.apply(baseArgs, arguments);
227
+ return fToBind.apply(
228
+ fNOP.prototype.isPrototypeOf(this) ? this : otherThis, baseArgs
229
+ );
230
+ };
231
+
232
+ if (this.prototype) {
233
+ // Function.prototype doesn't have a prototype property
234
+ fNOP.prototype = this.prototype;
235
+ }
236
+ fBound.prototype = new fNOP();
237
+
238
+ return fBound;
239
+ };
240
+ })();
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "i18n", "~> 1.8.0"
6
+
7
+ gemspec path: "../"
@@ -2,11 +2,12 @@ module I18n
2
2
  module JS
3
3
  module Formatters
4
4
  class Base
5
- def initialize(js_extend: false, namespace: nil, pretty_print: false, prefix: nil)
5
+ def initialize(js_extend: false, namespace: nil, pretty_print: false, prefix: nil, suffix: nil)
6
6
  @js_extend = js_extend
7
7
  @namespace = namespace
8
8
  @pretty_print = pretty_print
9
9
  @prefix = prefix
10
+ @suffix = suffix
10
11
  end
11
12
 
12
13
  protected
@@ -9,7 +9,7 @@ module I18n
9
9
  translations.each do |locale, translations_for_locale|
10
10
  contents << line(locale, format_json(translations_for_locale))
11
11
  end
12
- contents
12
+ contents << (@suffix || '')
13
13
  end
14
14
 
15
15
  protected
@@ -7,7 +7,7 @@ module I18n
7
7
 
8
8
  # Class which enscapulates a translations hash and outputs a single JSON translation file
9
9
  class Segment
10
- OPTIONS = [:namespace, :pretty_print, :js_extend, :prefix, :sort_translation_keys, :json_only].freeze
10
+ OPTIONS = [:namespace, :pretty_print, :js_extend, :prefix, :suffix, :sort_translation_keys, :json_only].freeze
11
11
  LOCALE_INTERPOLATOR = /%\{locale\}/
12
12
 
13
13
  attr_reader *([:file, :translations] | OPTIONS)
@@ -25,6 +25,7 @@ module I18n
25
25
  @pretty_print = !!options[:pretty_print]
26
26
  @js_extend = options.key?(:js_extend) ? !!options[:js_extend] : true
27
27
  @prefix = options.key?(:prefix) ? options[:prefix] : nil
28
+ @suffix = options.key?(:suffix) ? options[:suffix] : nil
28
29
  @sort_translation_keys = options.key?(:sort_translation_keys) ? !!options[:sort_translation_keys] : true
29
30
  @json_only = options.key?(:json_only) ? !!options[:json_only] : false
30
31
  end
@@ -70,7 +71,9 @@ module I18n
70
71
  { js_extend: @js_extend,
71
72
  namespace: @namespace,
72
73
  pretty_print: @pretty_print,
73
- prefix: @prefix }
74
+ prefix: @prefix,
75
+ suffix: @suffix
76
+ }
74
77
  end
75
78
  end
76
79
  end
@@ -14,10 +14,12 @@ module I18n
14
14
  v1 || v2
15
15
  end
16
16
  MERGER = proc do |_key, v1, v2|
17
- if Hash === v2 && (v2.keys - PLURAL_KEYS).empty?
18
- slice(v2.merge(v1, &PLURAL_MERGER), v2.keys)
19
- elsif Hash === v1 && Hash === v2
20
- v1.merge(v2, &MERGER)
17
+ if Hash === v1 && Hash === v2
18
+ if (v2.keys - PLURAL_KEYS).empty?
19
+ slice(v2.merge(v1, &PLURAL_MERGER), v2.keys)
20
+ else
21
+ v1.merge(v2, &MERGER)
22
+ end
21
23
  else
22
24
  v2 || v1
23
25
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module I18n
4
4
  module JS
5
- VERSION = "3.4.1"
5
+ VERSION = "3.7.0"
6
6
  end
7
7
  end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "i18n-js",
3
- "version": "3.3.0",
3
+ "version": "3.5.1",
4
4
  "description": "A javascript library similar to Ruby on Rails i18n gem",
5
5
  "author": "Nando Vieira",
6
6
  "license": "MIT",
@@ -6,3 +6,4 @@ translations:
6
6
  namespace: "Foo"
7
7
  pretty_print: true
8
8
  prefix: "import random from 'random-library';\n"
9
+ suffix: "//test"
@@ -1,5 +1,9 @@
1
1
  en:
2
2
  number:
3
+ human:
4
+ decimal_units:
5
+ units:
6
+ million: Million
3
7
  format:
4
8
  separator: "."
5
9
  delimiter: ","
@@ -48,6 +52,15 @@ en:
48
52
  one: Cat
49
53
  other: Cats
50
54
 
55
+ es:
56
+ number:
57
+ human:
58
+ decimal_units:
59
+ units:
60
+ million:
61
+ one: millón
62
+ other: millones
63
+
51
64
  ru:
52
65
  merge_plurals_with_no_overrides:
53
66
  one: кот
@@ -0,0 +1,4 @@
1
+ translations:
2
+ - file: "tmp/i18n-js/millions.js"
3
+ only:
4
+ - "*.number.human.decimal_units.units"
@@ -132,6 +132,7 @@ describe("Dates", function(){
132
132
 
133
133
  // 24-hour without padding
134
134
  expect(I18n.strftime(date, "%-H")).toEqual("7");
135
+ expect(I18n.strftime(date, "%k")).toEqual("7");
135
136
 
136
137
  // 12-hour without padding
137
138
  expect(I18n.strftime(date, "%-I")).toEqual("7");
@@ -10,45 +10,69 @@ describe("Localization", function(){
10
10
  I18n.translations = Translations();
11
11
  });
12
12
 
13
+ it("sets bound alias", function() {
14
+ expect(I18n.l).toEqual(jasmine.any(Function));
15
+ expect(I18n.l).not.toBe(I18n.localize);
16
+ });
17
+
13
18
  it("localizes number", function(){
14
- expect(I18n.l("number", 1234567)).toEqual("1,234,567.000");
19
+ expect(I18n.localize("number", 1234567)).toEqual("1,234,567.000");
20
+ });
21
+
22
+ it("localizes number with 'l' shortcut", function(){
23
+ var l = I18n.l;
24
+ expect(l("number", 1234567)).toEqual("1,234,567.000");
15
25
  });
16
26
 
17
27
  it("localizes currency", function(){
18
- expect(I18n.l("currency", 1234567)).toEqual("$1,234,567.00");
28
+ expect(I18n.localize("currency", 1234567)).toEqual("$1,234,567.00");
19
29
  });
20
30
 
21
31
  it("localizes date strings", function(){
22
32
  I18n.locale = "pt-BR";
23
33
 
24
- expect(I18n.l("date.formats.default", "2009-11-29")).toEqual("29/11/2009");
25
- expect(I18n.l("date.formats.short", "2009-01-07")).toEqual("07 de Janeiro");
26
- expect(I18n.l("date.formats.long", "2009-01-07")).toEqual("07 de Janeiro de 2009");
34
+ expect(I18n.localize("date.formats.default", "2009-11-29")).toEqual("29/11/2009");
35
+ expect(I18n.localize("date.formats.short", "2009-01-07")).toEqual("07 de Janeiro");
36
+ expect(I18n.localize("date.formats.long", "2009-01-07")).toEqual("07 de Janeiro de 2009");
37
+ });
38
+
39
+ it("localizes strings with locale from options", function(){
40
+ I18n.locale = "en";
41
+
42
+ expect(I18n.localize("date.formats.default", "2009-11-29", { locale: "pt-BR" })).toEqual("29/11/2009");
43
+ expect(I18n.localize("date.formats.short", "2009-01-07", { locale: "pt-BR" })).toEqual("07 de Janeiro");
44
+ expect(I18n.localize("date.formats.long", "2009-01-07", { locale: "pt-BR" })).toEqual("07 de Janeiro de 2009");
45
+ expect(I18n.localize("time.formats.default", "2009-11-29 15:07:59", { locale: "pt-BR" })).toEqual("Domingo, 29 de Novembro de 2009, 15:07 h");
46
+ expect(I18n.localize("time.formats.short", "2009-01-07 09:12:35", { locale: "pt-BR" })).toEqual("07/01, 09:12 h");
47
+ expect(I18n.localize("time.formats.long", "2009-11-29 15:07:59", { locale: "pt-BR" })).toEqual("Domingo, 29 de Novembro de 2009, 15:07 h");
48
+ expect(I18n.localize("number", 1234567, { locale: "pt-BR" })).toEqual("1,234,567.000");
49
+ expect(I18n.localize("currency", 1234567, { locale: "pt-BR" })).toEqual("R$ 1.234.567,00");
50
+ expect(I18n.localize("percentage", 123.45, { locale: "pt-BR" })).toEqual("123,45%");
27
51
  });
28
52
 
29
53
  it("localizes time strings", function(){
30
54
  I18n.locale = "pt-BR";
31
55
 
32
- expect(I18n.l("time.formats.default", "2009-11-29 15:07:59")).toEqual("Domingo, 29 de Novembro de 2009, 15:07 h");
33
- expect(I18n.l("time.formats.short", "2009-01-07 09:12:35")).toEqual("07/01, 09:12 h");
34
- expect(I18n.l("time.formats.long", "2009-11-29 15:07:59")).toEqual("Domingo, 29 de Novembro de 2009, 15:07 h");
56
+ expect(I18n.localize("time.formats.default", "2009-11-29 15:07:59")).toEqual("Domingo, 29 de Novembro de 2009, 15:07 h");
57
+ expect(I18n.localize("time.formats.short", "2009-01-07 09:12:35")).toEqual("07/01, 09:12 h");
58
+ expect(I18n.localize("time.formats.long", "2009-11-29 15:07:59")).toEqual("Domingo, 29 de Novembro de 2009, 15:07 h");
35
59
  });
36
60
 
37
61
  it("return 'Invalid Date' or original value for invalid input", function(){
38
- expect(I18n.l("time.formats.default", "")).toEqual("Invalid Date");
39
- expect(I18n.l("time.formats.default", null)).toEqual(null);
40
- expect(I18n.l("time.formats.default", undefined)).toEqual(undefined);
62
+ expect(I18n.localize("time.formats.default", "")).toEqual("Invalid Date");
63
+ expect(I18n.localize("time.formats.default", null)).toEqual(null);
64
+ expect(I18n.localize("time.formats.default", undefined)).toEqual(undefined);
41
65
  });
42
66
 
43
67
  it("localizes date/time strings with placeholders", function(){
44
68
  I18n.locale = "pt-BR";
45
69
 
46
- expect(I18n.l("date.formats.short_with_placeholders", "2009-01-07", { p1: "!", p2: "?" })).toEqual("07 de Janeiro ! ?");
47
- expect(I18n.l("time.formats.short_with_placeholders", "2009-01-07 09:12:35", { p1: "!" })).toEqual("07/01, 09:12 h !");
70
+ expect(I18n.localize("date.formats.short_with_placeholders", "2009-01-07", { p1: "!", p2: "?" })).toEqual("07 de Janeiro ! ?");
71
+ expect(I18n.localize("time.formats.short_with_placeholders", "2009-01-07 09:12:35", { p1: "!" })).toEqual("07/01, 09:12 h !");
48
72
  });
49
73
 
50
74
  it("localizes percentage", function(){
51
75
  I18n.locale = "pt-BR";
52
- expect(I18n.l("percentage", 123.45)).toEqual("123,45%");
76
+ expect(I18n.localize("percentage", 123.45)).toEqual("123,45%");
53
77
  });
54
78
  });
@@ -10,8 +10,9 @@ describe("Pluralization", function(){
10
10
  I18n.translations = Translations();
11
11
  });
12
12
 
13
- it("sets alias", function() {
14
- expect(I18n.p).toEqual(I18n.pluralize);
13
+ it("sets bound alias", function() {
14
+ expect(I18n.p).toEqual(jasmine.any(Function));
15
+ expect(I18n.p).not.toBe(I18n.pluralize);
15
16
  });
16
17
 
17
18
  it("pluralizes scope", function(){
@@ -20,6 +21,13 @@ describe("Pluralization", function(){
20
21
  expect(I18n.p(5, "inbox")).toEqual("You have 5 messages");
21
22
  });
22
23
 
24
+ it("pluralizes scope with 'p' shortcut", function(){
25
+ var p = I18n.p;
26
+ expect(p(0, "inbox")).toEqual("You have no messages");
27
+ expect(p(1, "inbox")).toEqual("You have 1 message");
28
+ expect(p(5, "inbox")).toEqual("You have 5 messages");
29
+ });
30
+
23
31
  it("pluralizes using the 'other' scope", function(){
24
32
  I18n.translations["en"]["inbox"]["zero"] = null;
25
33
  expect(I18n.p(0, "inbox")).toEqual("You have 0 messages");
@@ -10,35 +10,45 @@ describe("Translate", function(){
10
10
  I18n.translations = Translations();
11
11
  });
12
12
 
13
+ it("sets bound alias", function() {
14
+ expect(I18n.t).toEqual(jasmine.any(Function));
15
+ expect(I18n.t).not.toBe(I18n.translate);
16
+ });
17
+
13
18
  it("returns translation for single scope", function(){
14
- expect(I18n.t("hello")).toEqual("Hello World!");
19
+ expect(I18n.translate("hello")).toEqual("Hello World!");
20
+ });
21
+
22
+ it("returns translation with 't' shortcut", function(){
23
+ var t = I18n.t;
24
+ expect(t("hello")).toEqual("Hello World!");
15
25
  });
16
26
 
17
27
  it("returns translation as object", function(){
18
- expect(I18n.t("greetings")).toEqual(I18n.translations.en.greetings);
28
+ expect(I18n.translate("greetings")).toEqual(I18n.translations.en.greetings);
19
29
  });
20
30
 
21
31
  it("returns missing message translation for valid scope with null", function(){
22
- actual = I18n.t("null_key");
32
+ actual = I18n.translate("null_key");
23
33
  expected = '[missing "en.null_key" translation]';
24
34
  expect(actual).toEqual(expected);
25
35
  });
26
36
 
27
37
  it("returns missing message translation for invalid scope", function(){
28
- actual = I18n.t("invalid.scope");
38
+ actual = I18n.translate("invalid.scope");
29
39
  expected = '[missing "en.invalid.scope" translation]';
30
40
  expect(actual).toEqual(expected);
31
41
  });
32
42
 
33
43
  it("returns missing message translation with provided locale for invalid scope", function(){
34
- actual = I18n.t("invalid.scope", { locale: "ja" });
44
+ actual = I18n.translate("invalid.scope", { locale: "ja" });
35
45
  expected = '[missing "ja.invalid.scope" translation]';
36
46
  expect(actual).toEqual(expected);
37
47
  });
38
48
 
39
49
  it("returns guessed translation if missingBehaviour is set to guess", function(){
40
50
  I18n.missingBehaviour = 'guess'
41
- actual = I18n.t("invalid.thisIsAutomaticallyGeneratedTranslation");
51
+ actual = I18n.translate("invalid.thisIsAutomaticallyGeneratedTranslation");
42
52
  expected = 'this is automatically generated translation';
43
53
  expect(actual).toEqual(expected);
44
54
  });
@@ -46,47 +56,47 @@ describe("Translate", function(){
46
56
  it("returns guessed translation with prefix if missingBehaviour is set to guess and prefix is also provided", function(){
47
57
  I18n.missingBehaviour = 'guess'
48
58
  I18n.missingTranslationPrefix = 'EE: '
49
- actual = I18n.t("invalid.thisIsAutomaticallyGeneratedTranslation");
59
+ actual = I18n.translate("invalid.thisIsAutomaticallyGeneratedTranslation");
50
60
  expected = 'EE: this is automatically generated translation';
51
61
  expect(actual).toEqual(expected);
52
62
  });
53
63
 
54
64
  it("returns missing message translation for valid scope with scope", function(){
55
- actual = I18n.t("monster", {scope: "greetings"});
65
+ actual = I18n.translate("monster", {scope: "greetings"});
56
66
  expected = '[missing "en.greetings.monster" translation]';
57
67
  expect(actual).toEqual(expected);
58
68
  });
59
69
 
60
70
  it("returns translation for single scope on a custom locale", function(){
61
71
  I18n.locale = "pt-BR";
62
- expect(I18n.t("hello")).toEqual("Olá Mundo!");
72
+ expect(I18n.translate("hello")).toEqual("Olá Mundo!");
63
73
  });
64
74
 
65
75
  it("returns translation for multiple scopes", function(){
66
- expect(I18n.t("greetings.stranger")).toEqual("Hello stranger!");
76
+ expect(I18n.translate("greetings.stranger")).toEqual("Hello stranger!");
67
77
  });
68
78
 
69
79
  it("returns translation with default locale option", function(){
70
- expect(I18n.t("hello", {locale: "en"})).toEqual("Hello World!");
71
- expect(I18n.t("hello", {locale: "pt-BR"})).toEqual("Olá Mundo!");
80
+ expect(I18n.translate("hello", {locale: "en"})).toEqual("Hello World!");
81
+ expect(I18n.translate("hello", {locale: "pt-BR"})).toEqual("Olá Mundo!");
72
82
  });
73
83
 
74
84
  it("fallbacks to the default locale when I18n.fallbacks is enabled", function(){
75
85
  I18n.locale = "pt-BR";
76
86
  I18n.fallbacks = true;
77
- expect(I18n.t("greetings.stranger")).toEqual("Hello stranger!");
87
+ expect(I18n.translate("greetings.stranger")).toEqual("Hello stranger!");
78
88
  });
79
89
 
80
90
  it("fallbacks to default locale when providing an unknown locale", function(){
81
91
  I18n.locale = "fr";
82
92
  I18n.fallbacks = true;
83
- expect(I18n.t("greetings.stranger")).toEqual("Hello stranger!");
93
+ expect(I18n.translate("greetings.stranger")).toEqual("Hello stranger!");
84
94
  });
85
95
 
86
96
  it("fallbacks to less specific locale", function(){
87
97
  I18n.locale = "de-DE";
88
98
  I18n.fallbacks = true;
89
- expect(I18n.t("hello")).toEqual("Hallo Welt!");
99
+ expect(I18n.translate("hello")).toEqual("Hallo Welt!");
90
100
  });
91
101
 
92
102
  describe("when a 3-part locale is used", function(){
@@ -96,15 +106,15 @@ describe("Translate", function(){
96
106
  });
97
107
 
98
108
  it("fallbacks to 2-part locale when absent", function(){
99
- expect(I18n.t("cat")).toEqual("貓");
109
+ expect(I18n.translate("cat")).toEqual("貓");
100
110
  });
101
111
 
102
112
  it("fallbacks to 1-part locale when 2-part missing requested translation", function(){
103
- expect(I18n.t("dog")).toEqual("狗");
113
+ expect(I18n.translate("dog")).toEqual("狗");
104
114
  });
105
115
 
106
116
  it("fallbacks to 2-part for the first time", function(){
107
- expect(I18n.t("dragon")).toEqual("龍");
117
+ expect(I18n.translate("dragon")).toEqual("龍");
108
118
  });
109
119
  });
110
120
 
@@ -115,7 +125,7 @@ describe("Translate", function(){
115
125
  return ["nb"];
116
126
  };
117
127
 
118
- expect(I18n.t("hello")).toEqual("Hei Verden!");
128
+ expect(I18n.translate("hello")).toEqual("Hei Verden!");
119
129
  });
120
130
 
121
131
  it("fallbacks using custom rules (array)", function() {
@@ -123,7 +133,7 @@ describe("Translate", function(){
123
133
  I18n.fallbacks = true;
124
134
  I18n.locales["no"] = ["no", "nb"];
125
135
 
126
- expect(I18n.t("hello")).toEqual("Hei Verden!");
136
+ expect(I18n.translate("hello")).toEqual("Hei Verden!");
127
137
  });
128
138
 
129
139
  it("fallbacks using custom rules (string)", function() {
@@ -131,25 +141,25 @@ describe("Translate", function(){
131
141
  I18n.fallbacks = true;
132
142
  I18n.locales["no"] = "nb";
133
143
 
134
- expect(I18n.t("hello")).toEqual("Hei Verden!");
144
+ expect(I18n.translate("hello")).toEqual("Hei Verden!");
135
145
  });
136
146
 
137
147
  describe("when provided default values", function() {
138
148
  it("uses scope provided in defaults if scope doesn't exist", function() {
139
- actual = I18n.t("Hello!", {defaults: [{scope: "greetings.stranger"}]});
149
+ actual = I18n.translate("Hello!", {defaults: [{scope: "greetings.stranger"}]});
140
150
  expect(actual).toEqual("Hello stranger!");
141
151
  });
142
152
 
143
153
  it("continues to fallback until a scope is found", function() {
144
154
  var defaults = [{scope: "foo"}, {scope: "hello"}];
145
155
 
146
- actual = I18n.t("foo", {defaults: defaults});
156
+ actual = I18n.translate("foo", {defaults: defaults});
147
157
  expect(actual).toEqual("Hello World!");
148
158
  });
149
159
 
150
160
  it("uses message if specified as a default", function() {
151
161
  var defaults = [{message: "Hello all!"}];
152
- actual = I18n.t("foo", {defaults: defaults});
162
+ actual = I18n.translate("foo", {defaults: defaults});
153
163
  expect(actual).toEqual("Hello all!");
154
164
  });
155
165
 
@@ -158,7 +168,7 @@ describe("Translate", function(){
158
168
  {scope: "bar"}
159
169
  , {message: "Hello all!"}
160
170
  , {scope: "hello"}];
161
- actual = I18n.t("foo", {defaults: defaults});
171
+ actual = I18n.translate("foo", {defaults: defaults});
162
172
  expect(actual).toEqual("Hello all!");
163
173
  });
164
174
 
@@ -167,7 +177,7 @@ describe("Translate", function(){
167
177
  defaults: [{scope: "bar"}]
168
178
  , defaultValue: "Hello all!"
169
179
  };
170
- actual = I18n.t("foo", options);
180
+ actual = I18n.translate("foo", options);
171
181
  expect(actual).toEqual("Hello all!");
172
182
  });
173
183
 
@@ -176,7 +186,7 @@ describe("Translate", function(){
176
186
  defaults: [{scope: "hello"}]
177
187
  , defaultValue: "Hello all!"
178
188
  };
179
- actual = I18n.t("foo", options);
189
+ actual = I18n.translate("foo", options);
180
190
  expect(actual).toEqual("Hello World!");
181
191
  })
182
192
 
@@ -187,36 +197,36 @@ describe("Translate", function(){
187
197
  return scope.toUpperCase();
188
198
  }
189
199
  };
190
- actual = I18n.t("foo", options);
200
+ actual = I18n.translate("foo", options);
191
201
  expect(actual).toEqual("FOO");
192
202
  })
193
203
 
194
204
  it("pluralizes using the correct scope if translation is found within default scope", function() {
195
205
  expect(I18n.translations["en"]["mailbox"]).toEqual(undefined);
196
- actual = I18n.t("mailbox.inbox", {count: 1, defaults: [{scope: "inbox"}]});
197
- expected = I18n.t("inbox", {count: 1})
206
+ actual = I18n.translate("mailbox.inbox", {count: 1, defaults: [{scope: "inbox"}]});
207
+ expected = I18n.translate("inbox", {count: 1})
198
208
  expect(actual).toEqual(expected)
199
209
  })
200
210
  });
201
211
 
202
212
  it("uses default value for simple translation", function(){
203
- actual = I18n.t("warning", {defaultValue: "Warning!"});
213
+ actual = I18n.translate("warning", {defaultValue: "Warning!"});
204
214
  expect(actual).toEqual("Warning!");
205
215
  });
206
216
 
207
217
  it("uses default value for plural translation", function(){
208
- actual = I18n.t("message", {defaultValue: { one: '%{count} message', other: '%{count} messages'}, count: 1});
218
+ actual = I18n.translate("message", {defaultValue: { one: '%{count} message', other: '%{count} messages'}, count: 1});
209
219
  expect(actual).toEqual("1 message");
210
220
  });
211
221
 
212
222
  it("uses default value for unknown locale", function(){
213
223
  I18n.locale = "fr";
214
- actual = I18n.t("warning", {defaultValue: "Warning!"});
224
+ actual = I18n.translate("warning", {defaultValue: "Warning!"});
215
225
  expect(actual).toEqual("Warning!");
216
226
  });
217
227
 
218
228
  it("uses default value with interpolation", function(){
219
- actual = I18n.t(
229
+ actual = I18n.translate(
220
230
  "alert",
221
231
  {defaultValue: "Attention! {{message}}", message: "You're out of quota!"}
222
232
  );
@@ -225,33 +235,33 @@ describe("Translate", function(){
225
235
  });
226
236
 
227
237
  it("ignores default value when scope exists", function(){
228
- actual = I18n.t("hello", {defaultValue: "What's up?"});
238
+ actual = I18n.translate("hello", {defaultValue: "What's up?"});
229
239
  expect(actual).toEqual("Hello World!");
230
240
  });
231
241
 
232
242
  it("returns translation for custom scope separator", function(){
233
243
  I18n.defaultSeparator = "•";
234
- actual = I18n.t("greetings•stranger");
244
+ actual = I18n.translate("greetings•stranger");
235
245
  expect(actual).toEqual("Hello stranger!");
236
246
  });
237
247
 
238
248
  it("returns boolean values", function() {
239
- expect(I18n.t("booleans.yes")).toEqual(true);
240
- expect(I18n.t("booleans.no")).toEqual(false);
249
+ expect(I18n.translate("booleans.yes")).toEqual(true);
250
+ expect(I18n.translate("booleans.no")).toEqual(false);
241
251
  });
242
252
 
243
253
  it("escapes $ when doing substitution (IE)", function(){
244
254
  I18n.locale = "en";
245
255
 
246
- expect(I18n.t("paid", {price: "$0"})).toEqual("You were paid $0");
247
- expect(I18n.t("paid", {price: "$0.12"})).toEqual("You were paid $0.12");
248
- expect(I18n.t("paid", {price: "$1.35"})).toEqual("You were paid $1.35");
256
+ expect(I18n.translate("paid", {price: "$0"})).toEqual("You were paid $0");
257
+ expect(I18n.translate("paid", {price: "$0.12"})).toEqual("You were paid $0.12");
258
+ expect(I18n.translate("paid", {price: "$1.35"})).toEqual("You were paid $1.35");
249
259
  });
250
260
 
251
261
  it("replaces all occurrences of escaped $", function(){
252
262
  I18n.locale = "en";
253
263
 
254
- expect(I18n.t("paid_with_vat", {
264
+ expect(I18n.translate("paid_with_vat", {
255
265
  price: "$0.12",
256
266
  vat: "$0.02"}
257
267
  )).toEqual("You were paid $0.12 (incl. VAT $0.02)");
@@ -259,20 +269,20 @@ describe("Translate", function(){
259
269
 
260
270
  it("sets default scope", function(){
261
271
  var options = {scope: "greetings"};
262
- expect(I18n.t("stranger", options)).toEqual("Hello stranger!");
272
+ expect(I18n.translate("stranger", options)).toEqual("Hello stranger!");
263
273
  });
264
274
 
265
275
  it("accepts the scope as an array", function(){
266
- expect(I18n.t(["greetings", "stranger"])).toEqual("Hello stranger!");
276
+ expect(I18n.translate(["greetings", "stranger"])).toEqual("Hello stranger!");
267
277
  });
268
278
 
269
279
  it("accepts the scope as an array using a base scope", function(){
270
- expect(I18n.t(["stranger"], {scope: "greetings"})).toEqual("Hello stranger!");
280
+ expect(I18n.translate(["stranger"], {scope: "greetings"})).toEqual("Hello stranger!");
271
281
  });
272
282
 
273
283
  it("returns an array with values interpolated", function(){
274
284
  var options = {value: 314};
275
- expect(I18n.t("arrayWithParams", options)).toEqual([
285
+ expect(I18n.translate("arrayWithParams", options)).toEqual([
276
286
  null,
277
287
  "An item with a param of " + options.value,
278
288
  "Another item with a param of " + options.value,
@@ -90,7 +90,16 @@
90
90
  hello: "Olá Mundo!"
91
91
 
92
92
  , number: {
93
- percentage: {
93
+ currency: {
94
+ format: {
95
+ delimiter: ".",
96
+ format: "%u %n",
97
+ precision: 2,
98
+ separator: ",",
99
+ unit: "R$"
100
+ }
101
+ }
102
+ , percentage: {
94
103
  format: {
95
104
  delimiter: ""
96
105
  , separator: ","
@@ -351,7 +351,7 @@ EOS
351
351
  end
352
352
  end
353
353
 
354
- context "namespace, prefix and pretty_print options" do
354
+ context "namespace, prefix, suffix, and pretty_print options" do
355
355
 
356
356
  before do
357
357
  stub_const('I18n::JS::DEFAULT_EXPORT_DIR_PATH', temp_path)
@@ -379,6 +379,7 @@ EOS
379
379
  "foo": "Foo",
380
380
  "fallback_test": "Success"
381
381
  };
382
+ //test
382
383
  EOS
383
384
  }$/)
384
385
  end
@@ -598,7 +599,7 @@ EOS
598
599
  it "exports with the keys sorted" do
599
600
  expect(subject).to eq <<EOS
600
601
  I18n.translations || (I18n.translations = {});
601
- 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":"."}},"time":{"am":"am","formats":{"default":"%a, %d %b %Y %H:%M:%S %z","long":"%B %d, %Y %H:%M","short":"%d %b %H:%M"},"pm":"pm"}});
602
+ I18n.translations["en"] = I18n.extend((I18n.translations["en"] || {}), {"admin":{"edit":{"title":"Edit"},"show":{"note":"more details","title":"Show"}},"date":{"abbr_day_names":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"abbr_month_names":[null,"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"day_names":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"formats":{"default":"%Y-%m-%d","long":"%B %d, %Y","short":"%b %d"},"month_names":[null,"January","February","March","April","May","June","July","August","September","October","November","December"]},"fallback_test":"Success","foo":"Foo","merge_plurals":{"one":"Apple","other":"Apples"},"merge_plurals_with_no_overrides":{"one":"Apple","other":"Apples","zero":"No Apple"},"merge_plurals_with_partial_overrides":{"one":"Cat","other":"Cats"},"null_test":"fallback for null","number":{"currency":{"format":{"delimiter":",","format":"%u%n","precision":2,"separator":".","unit":"$"}},"format":{"delimiter":",","precision":3,"separator":"."},"human":{"decimal_units":{"units":{"million":"Million"}}}},"time":{"am":"am","formats":{"default":"%a, %d %b %Y %H:%M:%S %z","long":"%B %d, %Y %H:%M","short":"%d %b %H:%M"},"pm":"pm"}});
602
603
  EOS
603
604
  end
604
605
  end
@@ -610,6 +611,34 @@ EOS
610
611
  stub_const('I18n::JS::DEFAULT_EXPORT_DIR_PATH', temp_path)
611
612
  end
612
613
 
614
+ # https://github.com/fnando/i18n-js/issues/553
615
+ describe "millions" do
616
+ before do
617
+ stub_const('I18n::JS::DEFAULT_EXPORT_DIR_PATH', temp_path)
618
+ end
619
+
620
+ subject do
621
+ File.read(File.join(I18n::JS.export_i18n_js_dir_path, "millions.js"))
622
+ end
623
+
624
+ it "should correctly export millions" do
625
+ set_config "millions.yml"
626
+ I18n::JS.export
627
+ file_should_exist "millions.js"
628
+
629
+ expect(subject).to eq <<EOS
630
+ I18n.translations || (I18n.translations = {});
631
+ I18n.translations[\"de\"] = I18n.extend((I18n.translations[\"de\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}});
632
+ I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}});
633
+ I18n.translations[\"en-US\"] = I18n.extend((I18n.translations[\"en-US\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}});
634
+ I18n.translations[\"es\"] = I18n.extend((I18n.translations[\"es\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":{\"one\":\"millón\",\"other\":\"millones\"}}}}}});
635
+ I18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}});
636
+ I18n.translations[\"ja\"] = I18n.extend((I18n.translations[\"ja\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}});
637
+ I18n.translations[\"ru\"] = I18n.extend((I18n.translations[\"ru\"] || {}), {\"number\":{\"human\":{\"decimal_units\":{\"units\":{\"million\":\"Million\"}}}}});
638
+ EOS
639
+ end
640
+ end
641
+
613
642
  it "exports with js_extend option at parent level" do
614
643
  set_config "js_extend_parent.yml"
615
644
  I18n::JS.export
@@ -681,6 +710,7 @@ I18n.translations || (I18n.translations = {});
681
710
  I18n.translations[\"de\"] = I18n.extend((I18n.translations[\"de\"] || {}), {\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}});
682
711
  I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), {\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}});
683
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\"}});
684
714
  I18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), {\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}});
685
715
  I18n.translations[\"ja\"] = I18n.extend((I18n.translations[\"ja\"] || {}), {\"merge_plurals_with_no_overrides\":{\"one\":\"Apple\",\"other\":\"Apples\",\"zero\":\"No Apple\"}});
686
716
  I18n.translations[\"ru\"] = I18n.extend((I18n.translations[\"ru\"] || {}), {\"merge_plurals_with_no_overrides\":{\"few\":\"кошек\",\"many\":\"кошка\",\"one\":\"кот\",\"other\":\"кошек\"}});
@@ -708,6 +738,7 @@ I18n.translations || (I18n.translations = {});
708
738
  I18n.translations[\"de\"] = I18n.extend((I18n.translations[\"de\"] || {}), {\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}});
709
739
  I18n.translations[\"en\"] = I18n.extend((I18n.translations[\"en\"] || {}), {\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}});
710
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\"}});
711
742
  I18n.translations[\"fr\"] = I18n.extend((I18n.translations[\"fr\"] || {}), {\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}});
712
743
  I18n.translations[\"ja\"] = I18n.extend((I18n.translations[\"ja\"] || {}), {\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}});
713
744
  I18n.translations[\"ru\"] = I18n.extend((I18n.translations[\"ru\"] || {}), {\"merge_plurals_with_partial_overrides\":{\"one\":\"Cat\",\"other\":\"Cats\"}});
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.1
4
+ version: 3.7.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: 2019-11-01 00:00:00.000000000 Z
11
+ date: 2020-05-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: i18n
@@ -126,6 +126,7 @@ files:
126
126
  - gemfiles/i18n_1_5.gemfile
127
127
  - gemfiles/i18n_1_6.gemfile
128
128
  - gemfiles/i18n_1_7.gemfile
129
+ - gemfiles/i18n_1_8.gemfile
129
130
  - i18n-js.gemspec
130
131
  - lib/i18n-js.rb
131
132
  - lib/i18n/js.rb
@@ -167,6 +168,7 @@ files:
167
168
  - spec/fixtures/merge_plurals.yml
168
169
  - spec/fixtures/merge_plurals_with_no_overrides.yml
169
170
  - spec/fixtures/merge_plurals_with_partial_overrides.yml
171
+ - spec/fixtures/millions.yml
170
172
  - spec/fixtures/multiple_conditions.yml
171
173
  - spec/fixtures/multiple_conditions_per_locale.yml
172
174
  - spec/fixtures/multiple_files.yml
@@ -221,7 +223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
221
223
  - !ruby/object:Gem::Version
222
224
  version: '0'
223
225
  requirements: []
224
- rubygems_version: 3.0.6
226
+ rubygems_version: 3.1.3
225
227
  signing_key:
226
228
  specification_version: 4
227
229
  summary: It's a small library to provide the Rails I18n translations on the Javascript.
@@ -249,6 +251,7 @@ test_files:
249
251
  - spec/fixtures/merge_plurals.yml
250
252
  - spec/fixtures/merge_plurals_with_no_overrides.yml
251
253
  - spec/fixtures/merge_plurals_with_partial_overrides.yml
254
+ - spec/fixtures/millions.yml
252
255
  - spec/fixtures/multiple_conditions.yml
253
256
  - spec/fixtures/multiple_conditions_per_locale.yml
254
257
  - spec/fixtures/multiple_files.yml