i18n-js 2.1.2 → 3.0.11

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.
Files changed (107) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +24 -0
  3. data/.gitignore +5 -4
  4. data/.npmignore +27 -0
  5. data/.travis.yml +37 -0
  6. data/Appraisals +20 -0
  7. data/CHANGELOG.md +354 -0
  8. data/Gemfile +1 -1
  9. data/README.md +872 -0
  10. data/Rakefile +19 -7
  11. data/app/assets/javascripts/i18n/filtered.js.erb +23 -0
  12. data/app/assets/javascripts/i18n/shims.js +208 -0
  13. data/app/assets/javascripts/i18n/translations.js +3 -0
  14. data/app/assets/javascripts/i18n.js +1077 -0
  15. data/gemfiles/i18n_0_6.gemfile +7 -0
  16. data/gemfiles/i18n_0_7.gemfile +7 -0
  17. data/gemfiles/i18n_0_8.gemfile +7 -0
  18. data/gemfiles/i18n_0_9.gemfile +7 -0
  19. data/gemfiles/i18n_1_0.gemfile +7 -0
  20. data/i18n-js.gemspec +11 -9
  21. data/lib/i18n/js/dependencies.rb +59 -0
  22. data/lib/i18n/js/engine.rb +87 -0
  23. data/lib/i18n/js/fallback_locales.rb +70 -0
  24. data/lib/{i18n-js → i18n/js}/middleware.rb +32 -9
  25. data/lib/i18n/js/private/hash_with_symbol_keys.rb +36 -0
  26. data/lib/i18n/js/segment.rb +88 -0
  27. data/lib/i18n/js/utils.rb +52 -0
  28. data/lib/i18n/js/version.rb +7 -0
  29. data/lib/i18n/js.rb +242 -0
  30. data/lib/i18n-js.rb +1 -177
  31. data/lib/rails/generators/i18n/js/config/config_generator.rb +19 -0
  32. data/{config → lib/rails/generators/i18n/js/config/templates}/i18n-js.yml +11 -6
  33. data/lib/tasks/export.rake +8 -0
  34. data/package.json +25 -0
  35. data/spec/fixtures/custom_path.yml +5 -0
  36. data/spec/fixtures/default.yml +5 -0
  37. data/spec/fixtures/erb.yml +5 -0
  38. data/spec/fixtures/except_condition.yml +7 -0
  39. data/spec/fixtures/js_export_dir_custom.yml +7 -0
  40. data/spec/fixtures/js_export_dir_none.yml +6 -0
  41. data/spec/fixtures/js_extend_parent.yml +6 -0
  42. data/spec/fixtures/js_extend_segment.yml +6 -0
  43. data/spec/fixtures/js_file_per_locale.yml +7 -0
  44. data/spec/fixtures/js_file_per_locale_with_fallbacks_as_default_locale_symbol.yml +4 -0
  45. data/spec/fixtures/js_file_per_locale_with_fallbacks_as_hash.yml +6 -0
  46. data/spec/fixtures/js_file_per_locale_with_fallbacks_as_locale.yml +4 -0
  47. data/spec/fixtures/js_file_per_locale_with_fallbacks_as_locale_without_fallback_translations.yml +4 -0
  48. data/spec/fixtures/js_file_per_locale_with_fallbacks_enabled.yml +4 -0
  49. data/spec/fixtures/js_file_per_locale_without_fallbacks.yml +4 -0
  50. data/spec/fixtures/js_file_with_namespace_and_pretty_print.yml +7 -0
  51. data/spec/fixtures/js_sort_translation_keys_false.yml +6 -0
  52. data/spec/fixtures/js_sort_translation_keys_true.yml +6 -0
  53. data/spec/{resources → fixtures}/locales.yml +13 -1
  54. data/spec/fixtures/multiple_conditions.yml +7 -0
  55. data/spec/fixtures/multiple_conditions_per_locale.yml +7 -0
  56. data/spec/fixtures/multiple_files.yml +7 -0
  57. data/spec/{resources → fixtures}/no_config.yml +0 -0
  58. data/spec/fixtures/no_scope.yml +4 -0
  59. data/spec/fixtures/simple_scope.yml +5 -0
  60. data/spec/js/currency.spec.js +62 -0
  61. data/spec/js/current_locale.spec.js +19 -0
  62. data/spec/js/dates.spec.js +265 -0
  63. data/spec/js/defaults.spec.js +31 -0
  64. data/spec/js/extend.spec.js +110 -0
  65. data/spec/js/interpolation.spec.js +124 -0
  66. data/spec/js/jasmine/MIT.LICENSE +20 -0
  67. data/spec/js/jasmine/jasmine-html.js +190 -0
  68. data/spec/js/jasmine/jasmine.css +166 -0
  69. data/spec/js/jasmine/jasmine.js +2476 -0
  70. data/spec/js/jasmine/jasmine_favicon.png +0 -0
  71. data/spec/js/locales.spec.js +31 -0
  72. data/spec/js/localization.spec.js +48 -0
  73. data/spec/js/numbers.spec.js +170 -0
  74. data/spec/js/placeholder.spec.js +24 -0
  75. data/spec/js/pluralization.spec.js +211 -0
  76. data/spec/js/prepare_options.spec.js +41 -0
  77. data/spec/js/require.js +2083 -0
  78. data/spec/js/specs.html +49 -0
  79. data/spec/js/specs_requirejs.html +72 -0
  80. data/spec/js/translate.spec.js +277 -0
  81. data/spec/js/translations.js +164 -0
  82. data/spec/js/utility_functions.spec.js +20 -0
  83. data/spec/ruby/i18n/js/fallback_locales_spec.rb +84 -0
  84. data/spec/ruby/i18n/js/segment_spec.rb +157 -0
  85. data/spec/ruby/i18n/js/utils_spec.rb +106 -0
  86. data/spec/ruby/i18n/js_spec.rb +627 -0
  87. data/spec/spec_helper.rb +55 -14
  88. data/yarn.lock +131 -0
  89. metadata +188 -96
  90. data/.rspec +0 -1
  91. data/Gemfile.lock +0 -51
  92. data/README.rdoc +0 -305
  93. data/lib/i18n-js/engine.rb +0 -62
  94. data/lib/i18n-js/railtie.rb +0 -13
  95. data/lib/i18n-js/rake.rb +0 -16
  96. data/lib/i18n-js/version.rb +0 -10
  97. data/spec/i18n_spec.js +0 -768
  98. data/spec/i18n_spec.rb +0 -205
  99. data/spec/resources/custom_path.yml +0 -4
  100. data/spec/resources/default.yml +0 -4
  101. data/spec/resources/js_file_per_locale.yml +0 -3
  102. data/spec/resources/multiple_conditions.yml +0 -6
  103. data/spec/resources/multiple_files.yml +0 -6
  104. data/spec/resources/no_scope.yml +0 -3
  105. data/spec/resources/simple_scope.yml +0 -4
  106. data/vendor/assets/javascripts/i18n/translations.js.erb +0 -7
  107. data/vendor/assets/javascripts/i18n.js +0 -450
@@ -0,0 +1,157 @@
1
+ require "spec_helper"
2
+
3
+ describe I18n::JS::Segment do
4
+
5
+ let(:file) { "tmp/i18n-js/segment.js" }
6
+ let(:translations){ { en: { "test" => "Test" }, fr: { "test" => "Test2" } } }
7
+ let(:namespace) { "MyNamespace" }
8
+ let(:pretty_print){ nil }
9
+ let(:js_extend) { nil }
10
+ let(:sort_translation_keys){ nil }
11
+ let(:options) { { namespace: namespace,
12
+ pretty_print: pretty_print,
13
+ js_extend: js_extend,
14
+ sort_translation_keys: sort_translation_keys }.delete_if{|k,v| v.nil?} }
15
+ subject { I18n::JS::Segment.new(file, translations, options) }
16
+
17
+ describe ".new" do
18
+
19
+ it "should persist the file path variable" do
20
+ subject.file.should eql("tmp/i18n-js/segment.js")
21
+ end
22
+
23
+ it "should persist the translations variable" do
24
+ subject.translations.should eql(translations)
25
+ end
26
+
27
+ it "should persist the namespace variable" do
28
+ subject.namespace.should eql("MyNamespace")
29
+ end
30
+
31
+ context "when namespace is nil" do
32
+ let(:namespace){ nil }
33
+
34
+ it "should default namespace to `I18n`" do
35
+ subject.namespace.should eql("I18n")
36
+ end
37
+ end
38
+
39
+ context "when namespace is not set" do
40
+ subject { I18n::JS::Segment.new(file, translations) }
41
+
42
+ it "should default namespace to `I18n`" do
43
+ subject.namespace.should eql("I18n")
44
+ end
45
+ end
46
+
47
+ context "when pretty_print is nil" do
48
+ it "should set pretty_print to false" do
49
+ subject.pretty_print.should be false
50
+ end
51
+ end
52
+
53
+ context "when pretty_print is truthy" do
54
+ let(:pretty_print){ 1 }
55
+
56
+ it "should set pretty_print to true" do
57
+ subject.pretty_print.should be true
58
+ end
59
+ end
60
+ end
61
+
62
+ describe "#save!" do
63
+ before { allow(I18n::JS).to receive(:export_i18n_js_dir_path).and_return(temp_path) }
64
+ before { subject.save! }
65
+
66
+ context "when file does not include %{locale}" do
67
+ it "should write the file" do
68
+ file_should_exist "segment.js"
69
+
70
+ File.open(File.join(temp_path, "segment.js")){|f| f.read}.should eql <<-EOF
71
+ MyNamespace.translations || (MyNamespace.translations = {});
72
+ MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), {"test":"Test"});
73
+ MyNamespace.translations["fr"] = I18n.extend((MyNamespace.translations["fr"] || {}), {"test":"Test2"});
74
+ EOF
75
+ end
76
+ end
77
+
78
+ context "when file includes %{locale}" do
79
+ let(:file){ "tmp/i18n-js/%{locale}.js" }
80
+
81
+ it "should write files" do
82
+ file_should_exist "en.js"
83
+ file_should_exist "fr.js"
84
+
85
+ File.open(File.join(temp_path, "en.js")){|f| f.read}.should eql <<-EOF
86
+ MyNamespace.translations || (MyNamespace.translations = {});
87
+ MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), {"test":"Test"});
88
+ EOF
89
+
90
+ File.open(File.join(temp_path, "fr.js")){|f| f.read}.should eql <<-EOF
91
+ MyNamespace.translations || (MyNamespace.translations = {});
92
+ MyNamespace.translations["fr"] = I18n.extend((MyNamespace.translations["fr"] || {}), {"test":"Test2"});
93
+ EOF
94
+ end
95
+ end
96
+
97
+ context "when js_extend is true" do
98
+ let(:js_extend){ true }
99
+
100
+ let(:translations){ { en: { "b" => "Test", "a" => "Test" } } }
101
+
102
+ it 'should output the keys as sorted' do
103
+ file_should_exist "segment.js"
104
+
105
+ File.open(File.join(temp_path, "segment.js")){|f| f.read}.should eql <<-EOF
106
+ MyNamespace.translations || (MyNamespace.translations = {});
107
+ MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), {"a":"Test","b":"Test"});
108
+ EOF
109
+ end
110
+ end
111
+
112
+ context "when js_extend is false" do
113
+ let(:js_extend){ false }
114
+
115
+ let(:translations){ { en: { "b" => "Test", "a" => "Test" } } }
116
+
117
+ it 'should output the keys as sorted' do
118
+ file_should_exist "segment.js"
119
+
120
+ File.open(File.join(temp_path, "segment.js")){|f| f.read}.should eql <<-EOF
121
+ MyNamespace.translations || (MyNamespace.translations = {});
122
+ MyNamespace.translations["en"] = {"a":"Test","b":"Test"};
123
+ EOF
124
+ end
125
+ end
126
+
127
+ context "when sort_translation_keys is true" do
128
+ let(:sort_translation_keys){ true }
129
+
130
+ let(:translations){ { en: { "b" => "Test", "a" => "Test" } } }
131
+
132
+ it 'should output the keys as sorted' do
133
+ file_should_exist "segment.js"
134
+
135
+ File.open(File.join(temp_path, "segment.js")){|f| f.read}.should eql <<-EOF
136
+ MyNamespace.translations || (MyNamespace.translations = {});
137
+ MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), {"a":"Test","b":"Test"});
138
+ EOF
139
+ end
140
+ end
141
+
142
+ context "when sort_translation_keys is false" do
143
+ let(:sort_translation_keys){ false }
144
+
145
+ let(:translations){ { en: { "b" => "Test", "a" => "Test" } } }
146
+
147
+ it 'should output the keys as sorted' do
148
+ file_should_exist "segment.js"
149
+
150
+ File.open(File.join(temp_path, "segment.js")){|f| f.read}.should eql <<-EOF
151
+ MyNamespace.translations || (MyNamespace.translations = {});
152
+ MyNamespace.translations["en"] = I18n.extend((MyNamespace.translations["en"] || {}), {"b":"Test","a":"Test"});
153
+ EOF
154
+ end
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,106 @@
1
+ require "spec_helper"
2
+
3
+ describe I18n::JS::Utils do
4
+
5
+ describe ".strip_keys_with_nil_values" do
6
+ subject { described_class.strip_keys_with_nil_values(input_hash) }
7
+
8
+ context 'when input_hash does NOT contain nil value' do
9
+ let(:input_hash) { {a: 1, b: { c: 2 }} }
10
+ let(:expected_hash) { input_hash }
11
+
12
+ it 'returns the original input' do
13
+ is_expected.to eq expected_hash
14
+ end
15
+ end
16
+ context 'when input_hash does contain nil value' do
17
+ let(:input_hash) { {a: 1, b: { c: 2, d: nil }, e: { f: nil }} }
18
+ let(:expected_hash) { {a: 1, b: { c: 2 }, e: {}} }
19
+
20
+ it 'returns the original input with nil values removed' do
21
+ is_expected.to eq expected_hash
22
+ end
23
+ end
24
+ end
25
+
26
+ context "hash merging" do
27
+ it "performs a deep merge" do
28
+ target = {:a => {:b => 1}}
29
+ result = described_class.deep_merge(target, {:a => {:c => 2}})
30
+
31
+ result[:a].should eql({:b => 1, :c => 2})
32
+ end
33
+
34
+ it "performs a banged deep merge" do
35
+ target = {:a => {:b => 1}}
36
+ described_class.deep_merge!(target, {:a => {:c => 2}})
37
+
38
+ target[:a].should eql({:b => 1, :c => 2})
39
+ end
40
+ end
41
+
42
+ describe ".deep_reject" do
43
+ it "performs a deep keys rejection" do
44
+ hash = {:a => {:b => 1}}
45
+
46
+ result = described_class.deep_reject(hash) { |k, v| k == :b }
47
+
48
+ result.should eql({:a => {}})
49
+ end
50
+
51
+ it "performs a deep keys rejection prunning the whole tree if necessary" do
52
+ hash = {:a => {:b => {:c => {:d => 1, :e => 2}}}}
53
+
54
+ result = described_class.deep_reject(hash) { |k, v| k == :b }
55
+
56
+ result.should eql({:a => {}})
57
+ end
58
+
59
+
60
+ it "performs a deep keys rejection without changing the original hash" do
61
+ hash = {:a => {:b => 1, :c => 2}}
62
+
63
+ result = described_class.deep_reject(hash) { |k, v| k == :b }
64
+
65
+ result.should eql({:a => {:c => 2}})
66
+ hash.should eql({:a => {:b => 1, :c => 2}})
67
+ end
68
+ end
69
+
70
+ describe ".deep_key_sort" do
71
+ let(:unsorted_hash) { {:z => {:b => 1, :a => 2}, :y => 3} }
72
+ subject(:sorting) { described_class.deep_key_sort(unsorted_hash) }
73
+
74
+ it "performs a deep keys sort without changing the original hash" do
75
+ should eql({:y => 3, :z => {:a => 2, :b => 1}})
76
+ unsorted_hash.should eql({:z => {:b => 1, :a => 2}, :y => 3})
77
+ end
78
+
79
+ # Idea from gem `rails_admin`
80
+ context "when hash contain non-Symbol as key" do
81
+ let(:unsorted_hash) { {:z => {1 => 1, true => 2}, :y => 3} }
82
+
83
+ it "performs a deep keys sort without error" do
84
+ expect{ sorting }.to_not raise_error
85
+ end
86
+ it "converts keys to symbols" do
87
+ should eql({:y => 3, :z => {1 => 1, true => 2}})
88
+ end
89
+ end
90
+ end
91
+
92
+ describe ".scopes_match?" do
93
+ it "performs a comparison of literal scopes" do
94
+ described_class.scopes_match?([:a, :b], [:a, :b, :c]).should_not eql true
95
+ described_class.scopes_match?([:a, :b, :c], [:a, :b, :c]).should eql true
96
+ described_class.scopes_match?([:a, :b, :c], [:a, :b, :d]).should_not eql true
97
+ end
98
+
99
+ it "performs a comparison of wildcard scopes" do
100
+ described_class.scopes_match?([:a, '*'], [:a, :b, :c]).should_not eql true
101
+ described_class.scopes_match?([:a, '*', :c], [:a, :b, :c]).should eql true
102
+ described_class.scopes_match?([:a, :b, :c], [:a, '*', :c]).should eql true
103
+ described_class.scopes_match?([:a, :b, :c], [:a, '*', '*']).should eql true
104
+ end
105
+ end
106
+ end