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.
- checksums.yaml +7 -0
- data/.editorconfig +24 -0
- data/.gitignore +5 -4
- data/.npmignore +27 -0
- data/.travis.yml +37 -0
- data/Appraisals +20 -0
- data/CHANGELOG.md +354 -0
- data/Gemfile +1 -1
- data/README.md +872 -0
- data/Rakefile +19 -7
- data/app/assets/javascripts/i18n/filtered.js.erb +23 -0
- data/app/assets/javascripts/i18n/shims.js +208 -0
- data/app/assets/javascripts/i18n/translations.js +3 -0
- data/app/assets/javascripts/i18n.js +1077 -0
- data/gemfiles/i18n_0_6.gemfile +7 -0
- data/gemfiles/i18n_0_7.gemfile +7 -0
- data/gemfiles/i18n_0_8.gemfile +7 -0
- data/gemfiles/i18n_0_9.gemfile +7 -0
- data/gemfiles/i18n_1_0.gemfile +7 -0
- data/i18n-js.gemspec +11 -9
- data/lib/i18n/js/dependencies.rb +59 -0
- data/lib/i18n/js/engine.rb +87 -0
- data/lib/i18n/js/fallback_locales.rb +70 -0
- data/lib/{i18n-js → i18n/js}/middleware.rb +32 -9
- data/lib/i18n/js/private/hash_with_symbol_keys.rb +36 -0
- data/lib/i18n/js/segment.rb +88 -0
- data/lib/i18n/js/utils.rb +52 -0
- data/lib/i18n/js/version.rb +7 -0
- data/lib/i18n/js.rb +242 -0
- data/lib/i18n-js.rb +1 -177
- data/lib/rails/generators/i18n/js/config/config_generator.rb +19 -0
- data/{config → lib/rails/generators/i18n/js/config/templates}/i18n-js.yml +11 -6
- data/lib/tasks/export.rake +8 -0
- data/package.json +25 -0
- data/spec/fixtures/custom_path.yml +5 -0
- data/spec/fixtures/default.yml +5 -0
- data/spec/fixtures/erb.yml +5 -0
- data/spec/fixtures/except_condition.yml +7 -0
- data/spec/fixtures/js_export_dir_custom.yml +7 -0
- data/spec/fixtures/js_export_dir_none.yml +6 -0
- data/spec/fixtures/js_extend_parent.yml +6 -0
- data/spec/fixtures/js_extend_segment.yml +6 -0
- data/spec/fixtures/js_file_per_locale.yml +7 -0
- data/spec/fixtures/js_file_per_locale_with_fallbacks_as_default_locale_symbol.yml +4 -0
- data/spec/fixtures/js_file_per_locale_with_fallbacks_as_hash.yml +6 -0
- data/spec/fixtures/js_file_per_locale_with_fallbacks_as_locale.yml +4 -0
- data/spec/fixtures/js_file_per_locale_with_fallbacks_as_locale_without_fallback_translations.yml +4 -0
- data/spec/fixtures/js_file_per_locale_with_fallbacks_enabled.yml +4 -0
- data/spec/fixtures/js_file_per_locale_without_fallbacks.yml +4 -0
- data/spec/fixtures/js_file_with_namespace_and_pretty_print.yml +7 -0
- data/spec/fixtures/js_sort_translation_keys_false.yml +6 -0
- data/spec/fixtures/js_sort_translation_keys_true.yml +6 -0
- data/spec/{resources → fixtures}/locales.yml +13 -1
- data/spec/fixtures/multiple_conditions.yml +7 -0
- data/spec/fixtures/multiple_conditions_per_locale.yml +7 -0
- data/spec/fixtures/multiple_files.yml +7 -0
- data/spec/{resources → fixtures}/no_config.yml +0 -0
- data/spec/fixtures/no_scope.yml +4 -0
- data/spec/fixtures/simple_scope.yml +5 -0
- data/spec/js/currency.spec.js +62 -0
- data/spec/js/current_locale.spec.js +19 -0
- data/spec/js/dates.spec.js +265 -0
- data/spec/js/defaults.spec.js +31 -0
- data/spec/js/extend.spec.js +110 -0
- data/spec/js/interpolation.spec.js +124 -0
- data/spec/js/jasmine/MIT.LICENSE +20 -0
- data/spec/js/jasmine/jasmine-html.js +190 -0
- data/spec/js/jasmine/jasmine.css +166 -0
- data/spec/js/jasmine/jasmine.js +2476 -0
- data/spec/js/jasmine/jasmine_favicon.png +0 -0
- data/spec/js/locales.spec.js +31 -0
- data/spec/js/localization.spec.js +48 -0
- data/spec/js/numbers.spec.js +170 -0
- data/spec/js/placeholder.spec.js +24 -0
- data/spec/js/pluralization.spec.js +211 -0
- data/spec/js/prepare_options.spec.js +41 -0
- data/spec/js/require.js +2083 -0
- data/spec/js/specs.html +49 -0
- data/spec/js/specs_requirejs.html +72 -0
- data/spec/js/translate.spec.js +277 -0
- data/spec/js/translations.js +164 -0
- data/spec/js/utility_functions.spec.js +20 -0
- data/spec/ruby/i18n/js/fallback_locales_spec.rb +84 -0
- data/spec/ruby/i18n/js/segment_spec.rb +157 -0
- data/spec/ruby/i18n/js/utils_spec.rb +106 -0
- data/spec/ruby/i18n/js_spec.rb +627 -0
- data/spec/spec_helper.rb +55 -14
- data/yarn.lock +131 -0
- metadata +188 -96
- data/.rspec +0 -1
- data/Gemfile.lock +0 -51
- data/README.rdoc +0 -305
- data/lib/i18n-js/engine.rb +0 -62
- data/lib/i18n-js/railtie.rb +0 -13
- data/lib/i18n-js/rake.rb +0 -16
- data/lib/i18n-js/version.rb +0 -10
- data/spec/i18n_spec.js +0 -768
- data/spec/i18n_spec.rb +0 -205
- data/spec/resources/custom_path.yml +0 -4
- data/spec/resources/default.yml +0 -4
- data/spec/resources/js_file_per_locale.yml +0 -3
- data/spec/resources/multiple_conditions.yml +0 -6
- data/spec/resources/multiple_files.yml +0 -6
- data/spec/resources/no_scope.yml +0 -3
- data/spec/resources/simple_scope.yml +0 -4
- data/vendor/assets/javascripts/i18n/translations.js.erb +0 -7
- 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
|