i18n-js 3.4.1 → 3.7.0

This diff has not been reviewed by any users.
Sign up to get free protection for your applications and to get access to all the features.
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