r18n-core 4.0.0 → 5.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ChangeLog.md +398 -0
- data/README.md +23 -13
- data/lib/r18n-core.rb +10 -25
- data/lib/r18n-core/filter_list.rb +6 -3
- data/lib/r18n-core/filters.rb +21 -22
- data/lib/r18n-core/i18n.rb +9 -16
- data/lib/r18n-core/locale.rb +20 -21
- data/lib/r18n-core/locales/cy.rb +1 -1
- data/lib/r18n-core/locales/en-au.rb +1 -1
- data/lib/r18n-core/locales/en-gb.rb +1 -1
- data/lib/r18n-core/locales/en-us.rb +1 -1
- data/lib/r18n-core/locales/en.rb +2 -2
- data/lib/r18n-core/locales/es-cl.rb +1 -1
- data/lib/r18n-core/locales/es-us.rb +1 -1
- data/lib/r18n-core/locales/es.rb +2 -0
- data/lib/r18n-core/locales/fi.rb +2 -2
- data/lib/r18n-core/locales/fr.rb +3 -3
- data/lib/r18n-core/locales/it.rb +3 -3
- data/lib/r18n-core/locales/pt.rb +2 -0
- data/lib/r18n-core/locales/zh-cn.rb +1 -1
- data/lib/r18n-core/locales/zh-tw.rb +1 -1
- data/lib/r18n-core/locales/zh.rb +2 -0
- data/lib/r18n-core/translated.rb +4 -4
- data/lib/r18n-core/translated_string.rb +1 -6
- data/lib/r18n-core/translation.rb +1 -1
- data/lib/r18n-core/unsupported_locale.rb +2 -0
- data/lib/r18n-core/utils.rb +1 -1
- data/lib/r18n-core/version.rb +1 -1
- metadata +198 -89
- data/.rspec +0 -1
- data/Rakefile +0 -13
- data/r18n-core.gemspec +0 -29
- data/spec/filters_spec.rb +0 -327
- data/spec/i18n_spec.rb +0 -274
- data/spec/locale_spec.rb +0 -251
- data/spec/locales/af_spec.rb +0 -9
- data/spec/locales/cs_spec.rb +0 -23
- data/spec/locales/en-us_spec.rb +0 -28
- data/spec/locales/en_spec.rb +0 -13
- data/spec/locales/es-us_spec.rb +0 -11
- data/spec/locales/fa_spec.rb +0 -10
- data/spec/locales/fi_spec.rb +0 -9
- data/spec/locales/fr_spec.rb +0 -9
- data/spec/locales/hu_spec.rb +0 -19
- data/spec/locales/id_spec.rb +0 -23
- data/spec/locales/it_spec.rb +0 -10
- data/spec/locales/no_spec.rb +0 -9
- data/spec/locales/pl_spec.rb +0 -23
- data/spec/locales/ru_spec.rb +0 -23
- data/spec/locales/sk_spec.rb +0 -23
- data/spec/locales/th_spec.rb +0 -9
- data/spec/locales/vi_spec.rb +0 -9
- data/spec/r18n_spec.rb +0 -192
- data/spec/spec_helper.rb +0 -38
- data/spec/translated_spec.rb +0 -225
- data/spec/translation_spec.rb +0 -189
- data/spec/translations/extension/deep/en.yml +0 -1
- data/spec/translations/extension/en.yml +0 -2
- data/spec/translations/extension/notransl.yml +0 -1
- data/spec/translations/general/en.yml +0 -52
- data/spec/translations/general/nolocale.yml +0 -6
- data/spec/translations/general/ru.yml +0 -7
- data/spec/translations/two/en.yml +0 -2
- data/spec/translations/two/fr.yml +0 -0
- data/spec/translations/with_regions/en-US.yml +0 -0
- data/spec/translations/yaml/en-GB.yml +0 -1
- data/spec/translations/yaml/en-us.yml +0 -1
- data/spec/translations/yaml/en.yaml +0 -1
- data/spec/yaml_loader_spec.rb +0 -63
data/.rspec
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
--format documentation --colour --warnings --require spec_helper
|
data/Rakefile
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'bundler/setup'
|
4
|
-
Bundler::GemHelper.install_tasks
|
5
|
-
|
6
|
-
require 'rspec/core/rake_task'
|
7
|
-
RSpec::Core::RakeTask.new
|
8
|
-
task default: :spec
|
9
|
-
|
10
|
-
task :clobber_package do
|
11
|
-
rm_rf 'pkg'
|
12
|
-
end
|
13
|
-
task clobber: [:clobber_package]
|
data/r18n-core.gemspec
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'lib/r18n-core/version'
|
4
|
-
|
5
|
-
Gem::Specification.new do |s|
|
6
|
-
s.platform = Gem::Platform::RUBY
|
7
|
-
s.name = 'r18n-core'
|
8
|
-
s.version = R18n::VERSION.dup
|
9
|
-
s.date = Time.now.strftime('%Y-%m-%d')
|
10
|
-
|
11
|
-
s.summary = 'I18n tool to translate your Ruby application.'
|
12
|
-
s.description = <<-DESC
|
13
|
-
R18n is a i18n tool to translate your Ruby application.
|
14
|
-
It has nice Ruby-style syntax, filters, flexible locales, custom loaders,
|
15
|
-
translation support for any classes, time and number localization, several
|
16
|
-
user language support, agnostic core package with out-of-box support for
|
17
|
-
Rails, Sinatra and desktop applications.
|
18
|
-
DESC
|
19
|
-
|
20
|
-
s.files = `git ls-files`.split("\n")
|
21
|
-
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
22
|
-
s.extra_rdoc_files = ['README.md', 'LICENSE']
|
23
|
-
s.require_path = 'lib'
|
24
|
-
|
25
|
-
s.author = 'Andrey Sitnik'
|
26
|
-
s.email = 'andrey@sitnik.ru'
|
27
|
-
s.homepage = 'https://github.com/r18n/r18n'
|
28
|
-
s.license = 'LGPL-3.0'
|
29
|
-
end
|
data/spec/filters_spec.rb
DELETED
@@ -1,327 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
describe R18n::Filters do
|
4
|
-
before do
|
5
|
-
@system = R18n::Filters.defined.values
|
6
|
-
@enabled = R18n::Filters.defined.values.select(&:enabled?)
|
7
|
-
@i18n = R18n::I18n.new('en', DIR)
|
8
|
-
@i18n.reload!
|
9
|
-
end
|
10
|
-
|
11
|
-
after do
|
12
|
-
R18n::Filters.defined.each_value do |filter|
|
13
|
-
next if @system.include? filter
|
14
|
-
|
15
|
-
R18n::Filters.delete(filter)
|
16
|
-
end
|
17
|
-
|
18
|
-
@enabled.each { |i| R18n::Filters.on(i) unless i.enabled? }
|
19
|
-
(@system - @enabled).each { |i| R18n::Filters.off(i) if i.enabled? }
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'adds new filter' do
|
23
|
-
filter = R18n::Filters.add('my', :my_filter) { |i, _config| i }
|
24
|
-
|
25
|
-
expect(filter).to be_kind_of(R18n::Filters::Filter)
|
26
|
-
expect(filter.name).to eq(:my_filter)
|
27
|
-
expect(filter.types).to eq(['my'])
|
28
|
-
expect(filter).to be_enabled
|
29
|
-
|
30
|
-
expect(R18n::Filters.defined).to have_key(:my_filter)
|
31
|
-
|
32
|
-
@i18n.reload!
|
33
|
-
expect(@i18n.my_filter).to eq('value')
|
34
|
-
expect(@i18n.my_tree_filter).to eq('name' => 'value')
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'adds filter for several types' do
|
38
|
-
R18n::Filters.add(%w[my your]) { |i, _config| i + '1' }
|
39
|
-
@i18n.reload!
|
40
|
-
expect(@i18n.my_filter).to eq('value1')
|
41
|
-
expect(@i18n.your_filter).to eq('another1')
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'uses passive filters' do
|
45
|
-
filter = double
|
46
|
-
expect(filter).to receive(:process).twice.and_return(1)
|
47
|
-
|
48
|
-
R18n::Filters.add('my', :passive, passive: true) { filter.process }
|
49
|
-
|
50
|
-
expect(@i18n.my_filter).to eq('value')
|
51
|
-
@i18n.reload!
|
52
|
-
|
53
|
-
expect(@i18n.my_tree_filter).to eq(1)
|
54
|
-
expect(@i18n.my_filter).to eq(1)
|
55
|
-
expect(@i18n.my_filter).to eq(1)
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'uses cascade filters' do
|
59
|
-
R18n::Filters.add('my', :one) { |i, _config| i + '1' }
|
60
|
-
R18n::Filters.add('my', :two) { |i, _config| i + '2' }
|
61
|
-
R18n::Filters.add('my', :three, position: 0) { |i, _c| i + '3' }
|
62
|
-
expect(@i18n.my_filter).to eq('value312')
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'returns name for nameless filter' do
|
66
|
-
R18n::Filters.instance_variable_set(:@last_auto_name, 0)
|
67
|
-
|
68
|
-
expect(R18n::Filters.add('some').name).to eq(1)
|
69
|
-
expect(R18n::Filters.add('some', position: 0).name).to eq(2)
|
70
|
-
|
71
|
-
R18n::Filters.add('some', 3)
|
72
|
-
expect(R18n::Filters.add('some').name).to eq(4)
|
73
|
-
end
|
74
|
-
|
75
|
-
it 'deletes filter by name' do
|
76
|
-
R18n::Filters.add('my', :my_filter) { '1' }
|
77
|
-
expect(@i18n.my_filter).to eq('1')
|
78
|
-
|
79
|
-
R18n::Filters.delete(:my_filter)
|
80
|
-
expect(R18n::Filters.defined).not_to have_key(:my_filter)
|
81
|
-
expect(@i18n.my_filter).to eq('value')
|
82
|
-
end
|
83
|
-
|
84
|
-
it 'deletes filter by object' do
|
85
|
-
filter = R18n::Filters.add('my') { '1' }
|
86
|
-
expect(@i18n.my_filter).to eq('1')
|
87
|
-
|
88
|
-
R18n::Filters.delete(filter)
|
89
|
-
expect(R18n::Filters.defined).not_to have_key(filter.name)
|
90
|
-
expect(@i18n.my_filter).to eq('value')
|
91
|
-
end
|
92
|
-
|
93
|
-
it 'uses global filters' do
|
94
|
-
R18n::Filters.add(String) { |result, _config, a, b| result + a + b }
|
95
|
-
R18n::Filters.add(String) { |result, _config| result + '!' }
|
96
|
-
|
97
|
-
expect(@i18n.one('1', '2')).to eq('One12!')
|
98
|
-
end
|
99
|
-
|
100
|
-
it 'turns off filter' do
|
101
|
-
R18n::Filters.add('my', :one) { |i, _config| i + '1' }
|
102
|
-
R18n::Filters.add('my', :two) { |i, _config| i + '2' }
|
103
|
-
|
104
|
-
R18n::Filters.off(:one)
|
105
|
-
expect(R18n::Filters.defined[:one]).not_to be_enabled
|
106
|
-
expect(@i18n.my_filter).to eq('value2')
|
107
|
-
|
108
|
-
R18n::Filters.on(:one)
|
109
|
-
expect(R18n::Filters.defined[:one]).to be_enabled
|
110
|
-
expect(@i18n.my_filter).to eq('value12')
|
111
|
-
end
|
112
|
-
|
113
|
-
it 'sends config to filter' do
|
114
|
-
R18n::Filters.add('my') do |_i, config|
|
115
|
-
config[:secret_value] = 1
|
116
|
-
config
|
117
|
-
end
|
118
|
-
expect(@i18n.my_filter[:locale]).to eq(@i18n.locale)
|
119
|
-
expect(@i18n.my_filter[:path]).to eq('my_filter')
|
120
|
-
expect(@i18n.my_filter[:secret_value]).to eq(1)
|
121
|
-
expect(@i18n.my_filter[:unknown_value]).to be_nil
|
122
|
-
end
|
123
|
-
|
124
|
-
it 'sets path in config' do
|
125
|
-
R18n::Filters.add(String) do |_i, config|
|
126
|
-
config[:path]
|
127
|
-
end
|
128
|
-
|
129
|
-
expect(@i18n.in.another.level).to eq('in.another.level')
|
130
|
-
end
|
131
|
-
|
132
|
-
it 'returns translated string after filters' do
|
133
|
-
R18n::Filters.add(String) { |i, _config| i + '1' }
|
134
|
-
|
135
|
-
expect(@i18n.one).to be_kind_of(R18n::TranslatedString)
|
136
|
-
expect(@i18n.one.path).to eq('one')
|
137
|
-
expect(@i18n.one.locale).to eq(R18n.locale('en'))
|
138
|
-
end
|
139
|
-
|
140
|
-
it 'uses one config for cascade filters' do
|
141
|
-
R18n::Filters.add('my') { |_content, config| config[:new_secret] ? 2 : 1 }
|
142
|
-
expect(@i18n.my_filter).to eq(1)
|
143
|
-
|
144
|
-
R18n::Filters.add('my', :second, position: 0) do |content, config|
|
145
|
-
config[:new_secret] = true
|
146
|
-
content
|
147
|
-
end
|
148
|
-
expect(@i18n.my_filter).to eq(2)
|
149
|
-
end
|
150
|
-
|
151
|
-
it 'sends parameters to filter' do
|
152
|
-
R18n::Filters.add('my') { |i, _config, a, b| "#{i}#{a}#{b}" }
|
153
|
-
expect(@i18n['my_filter', 1, 2]).to eq('value12')
|
154
|
-
expect(@i18n.my_filter(1, 2)).to eq('value12')
|
155
|
-
end
|
156
|
-
|
157
|
-
it 'pluralizes translation' do
|
158
|
-
expect(@i18n.comments(0, 'article')).to eq('no comments for article')
|
159
|
-
expect(@i18n.comments(1, 'article')).to eq('one comment for article')
|
160
|
-
expect(@i18n.comments(5, 'article')).to eq('5 comments for article')
|
161
|
-
|
162
|
-
expect(@i18n.files(0)).to eq('0 files')
|
163
|
-
expect(@i18n.files(-5.5)).to eq('−5.5 files')
|
164
|
-
expect(@i18n.files(5000)).to eq('5,000 files')
|
165
|
-
end
|
166
|
-
|
167
|
-
it "doesn't pluralize without first numeric parameter" do
|
168
|
-
expect(@i18n.files).to be_kind_of(R18n::UnpluralizetedTranslation)
|
169
|
-
expect(@i18n.files('')).to be_kind_of(R18n::UnpluralizetedTranslation)
|
170
|
-
expect(@i18n.files[1]).to eq('1 file')
|
171
|
-
expect(@i18n.files.n(5)).to eq('5 files')
|
172
|
-
end
|
173
|
-
|
174
|
-
it 'converts first float parameter to number' do
|
175
|
-
expect(@i18n.files(1.2)).to eq('1 file')
|
176
|
-
end
|
177
|
-
|
178
|
-
it 'pluralizes translation without locale' do
|
179
|
-
i18n = R18n::I18n.new('nolocale', DIR)
|
180
|
-
expect(i18n.entries(1)).to eq('ONE')
|
181
|
-
expect(i18n.entries(5)).to eq('N')
|
182
|
-
end
|
183
|
-
|
184
|
-
it 'cans use params in translation' do
|
185
|
-
expect(@i18n.params(-1, 2)).to eq('Is −1 between −1 and 2?')
|
186
|
-
end
|
187
|
-
|
188
|
-
it "substitutes '%2' as param but not value of second param" do
|
189
|
-
expect(@i18n.params('%2 FIRST', 'SECOND')).to eq(
|
190
|
-
'Is %2 FIRST between %2 FIRST and SECOND?'
|
191
|
-
)
|
192
|
-
end
|
193
|
-
|
194
|
-
# rubocop:disable Style/FormatStringToken
|
195
|
-
it 'interpolates named variables' do
|
196
|
-
R18n::Filters.off(:named_variables)
|
197
|
-
expect(@i18n.echo(value: 'R18n')).to eq 'Value is %{value}'
|
198
|
-
|
199
|
-
R18n::Filters.on(:named_variables)
|
200
|
-
expect(@i18n.echo(value: 'R18n')).to eq 'Value is R18n'
|
201
|
-
expect(@i18n.echo(value: -5.5)).to eq 'Value is −5.5'
|
202
|
-
expect(@i18n.echo(value: 5000)).to eq 'Value is 5,000'
|
203
|
-
expect(@i18n.echo(value: '<b>')).to eq 'Value is <b>'
|
204
|
-
expect(@i18n.echo).to eq 'Value is %{value}'
|
205
|
-
|
206
|
-
expect(@i18n.echo2(value: 'R18n')).to eq 'Value2 is R18n'
|
207
|
-
expect(@i18n.echo2).to eq 'Value2 is {{value}}'
|
208
|
-
end
|
209
|
-
# rubocop:enable Style/FormatStringToken
|
210
|
-
|
211
|
-
it 'formats untranslated' do
|
212
|
-
expect(@i18n.in.not.to_s).to eq('in.[not]')
|
213
|
-
expect(@i18n.in.not.to_str).to eq('in.[not]')
|
214
|
-
|
215
|
-
expect(@i18n.one.not_exists.to_s).to eq('one.[not_exists]')
|
216
|
-
|
217
|
-
R18n::Filters.off(:untranslated)
|
218
|
-
expect(@i18n.in.not.to_s).to eq('in.not')
|
219
|
-
|
220
|
-
R18n::Filters.add(R18n::Untranslated) do |_v, _c, trans, untrans, path|
|
221
|
-
"#{path} #{trans}[#{untrans}]"
|
222
|
-
end
|
223
|
-
expect(@i18n.in.not.to_s).to eq('in.not in.[not]')
|
224
|
-
end
|
225
|
-
|
226
|
-
it 'formats translation path' do
|
227
|
-
expect(@i18n.in.another.to_s).to eq('in.another[]')
|
228
|
-
|
229
|
-
R18n::Filters.off(:untranslated)
|
230
|
-
expect(@i18n.in.another.to_s).to eq('in.another')
|
231
|
-
|
232
|
-
R18n::Filters.add(R18n::Untranslated) do |_v, _c, trans, untrans, path|
|
233
|
-
"#{path} #{trans}[#{untrans}]"
|
234
|
-
end
|
235
|
-
expect(@i18n.in.another.to_s).to eq('in.another in.another[]')
|
236
|
-
end
|
237
|
-
|
238
|
-
it 'formats untranslated for web' do
|
239
|
-
R18n::Filters.off(:untranslated)
|
240
|
-
R18n::Filters.on(:untranslated_html)
|
241
|
-
expect(@i18n.in.not.to_s).to eq('in.<span style="color: red">[not]</span>')
|
242
|
-
expect(@i18n['<b>'].to_s).to eq(
|
243
|
-
'<span style="color: red">[<b>]</span>'
|
244
|
-
)
|
245
|
-
end
|
246
|
-
|
247
|
-
it 'allows to set custom filters' do
|
248
|
-
R18n::Filters.add(R18n::Untranslated, :a) { |v, _c| "a #{v}" }
|
249
|
-
R18n::Filters.off(:a)
|
250
|
-
|
251
|
-
html = R18n::I18n.new(
|
252
|
-
'en', DIR,
|
253
|
-
off_filters: :untranslated, on_filters: %i[untranslated_html a]
|
254
|
-
)
|
255
|
-
expect(html.in.not.to_s).to eq('a in.<span style="color: red">[not]</span>')
|
256
|
-
end
|
257
|
-
|
258
|
-
it 'has filter for escape HTML' do
|
259
|
-
expect(@i18n.html).to eq(
|
260
|
-
'<script>true && false</script>'
|
261
|
-
)
|
262
|
-
end
|
263
|
-
|
264
|
-
it 'has disabled global filter for escape HTML' do
|
265
|
-
expect(@i18n.greater('true')).to eq('1 < 2 is true')
|
266
|
-
|
267
|
-
R18n::Filters.on(:global_escape_html)
|
268
|
-
@i18n.reload!
|
269
|
-
expect(@i18n.greater('true')).to eq('1 < 2 is true')
|
270
|
-
expect(@i18n.html).to eq(
|
271
|
-
'<script>true && false</script>'
|
272
|
-
)
|
273
|
-
end
|
274
|
-
|
275
|
-
it 'has filter to disable global HTML escape' do
|
276
|
-
expect(@i18n.no_escape).to eq('<b>Warning</b>')
|
277
|
-
|
278
|
-
R18n::Filters.on(:global_escape_html)
|
279
|
-
@i18n.reload!
|
280
|
-
expect(@i18n.no_escape).to eq('<b>Warning</b>')
|
281
|
-
end
|
282
|
-
|
283
|
-
it 'has Markdown filter' do
|
284
|
-
expect(@i18n.markdown.simple).to eq("<p><strong>Hi!</strong></p>\n")
|
285
|
-
end
|
286
|
-
|
287
|
-
it 'has Textile filter' do
|
288
|
-
expect(@i18n.textile.simple).to eq('<p><em>Hi!</em></p>')
|
289
|
-
end
|
290
|
-
|
291
|
-
it 'HTML escapes before Markdown and Textile filters' do
|
292
|
-
expect(@i18n.markdown.html).to eq("<p><strong>Hi!</strong> <br /></p>\n")
|
293
|
-
expect(@i18n.textile.html).to eq('<p><em>Hi!</em><br /></p>')
|
294
|
-
|
295
|
-
R18n::Filters.on(:global_escape_html)
|
296
|
-
@i18n.reload!
|
297
|
-
expect(@i18n.markdown.html).to eq(
|
298
|
-
"<p><strong>Hi!</strong> <br /></p>\n"
|
299
|
-
)
|
300
|
-
expect(@i18n.textile.html).to eq(
|
301
|
-
'<p><em>Hi!</em><br /></p>'
|
302
|
-
)
|
303
|
-
end
|
304
|
-
|
305
|
-
it 'allows to listen filters adding' do
|
306
|
-
expect(R18n::Filters.listen do
|
307
|
-
R18n::Filters.add(String, :a) {}
|
308
|
-
end).to eq([R18n::Filters.defined[:a]])
|
309
|
-
end
|
310
|
-
|
311
|
-
it 'escapes variables if ActiveSupport is loaded' do
|
312
|
-
expect(@i18n.escape_params('<br>')).to eq('<b><br></b>')
|
313
|
-
|
314
|
-
require 'active_support'
|
315
|
-
|
316
|
-
expect(@i18n.escape_params('<br>')).to eq('<b><br></b>')
|
317
|
-
|
318
|
-
R18n::Filters.on(:global_escape_html)
|
319
|
-
@i18n.reload!
|
320
|
-
|
321
|
-
expect(@i18n.greater('<b>'.html_safe)).to eq('1 < 2 is <b>')
|
322
|
-
|
323
|
-
R18n::Filters.on(:named_variables)
|
324
|
-
|
325
|
-
expect(@i18n.echo(value: '<b>')).to eq 'Value is <b>'
|
326
|
-
end
|
327
|
-
end
|
data/spec/i18n_spec.rb
DELETED
@@ -1,274 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
describe R18n::I18n do
|
4
|
-
before do
|
5
|
-
@extension_places = R18n.extension_places.clone
|
6
|
-
end
|
7
|
-
|
8
|
-
after do
|
9
|
-
R18n::I18n.default = 'en'
|
10
|
-
R18n.default_loader = R18n::Loader::YAML
|
11
|
-
R18n.extension_places = @extension_places
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'parses HTTP_ACCEPT_LANGUAGE' do
|
15
|
-
expect(R18n::I18n.parse_http(nil)).to eq([])
|
16
|
-
expect(R18n::I18n.parse_http('')).to eq([])
|
17
|
-
expect(R18n::I18n.parse_http('ru,en;q=0.9')).to eq(%w[ru en])
|
18
|
-
expect(R18n::I18n.parse_http('ru;q=0.8,en;q=0.9')).to eq(%w[en ru])
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'has default locale' do
|
22
|
-
R18n::I18n.default = 'ru'
|
23
|
-
expect(R18n::I18n.default).to eq('ru')
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'loads locales' do
|
27
|
-
i18n = R18n::I18n.new('en', DIR)
|
28
|
-
expect(i18n.locales).to eq([R18n.locale('en')])
|
29
|
-
|
30
|
-
i18n = R18n::I18n.new(%w[ru nolocale-DL], DIR)
|
31
|
-
expect(i18n.locales).to eq([
|
32
|
-
R18n.locale('ru'),
|
33
|
-
R18n::UnsupportedLocale.new('nolocale-DL'),
|
34
|
-
R18n::UnsupportedLocale.new('nolocale'),
|
35
|
-
R18n.locale('en')
|
36
|
-
])
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'returns translations loaders' do
|
40
|
-
i18n = R18n::I18n.new('en', DIR)
|
41
|
-
expect(i18n.translation_places).to eq([R18n::Loader::YAML.new(DIR)])
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'loads translations by loader' do
|
45
|
-
loader = Class.new do
|
46
|
-
def available
|
47
|
-
[R18n.locale('en')]
|
48
|
-
end
|
49
|
-
|
50
|
-
def load(_locale)
|
51
|
-
{ 'custom' => 'Custom' }
|
52
|
-
end
|
53
|
-
end
|
54
|
-
expect(R18n::I18n.new('en', loader.new).custom).to eq('Custom')
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'passes parameters to default loader' do
|
58
|
-
loader = Class.new do
|
59
|
-
def initialize(param)
|
60
|
-
@param = param
|
61
|
-
end
|
62
|
-
|
63
|
-
def available
|
64
|
-
[R18n.locale('en')]
|
65
|
-
end
|
66
|
-
|
67
|
-
def load(_locale)
|
68
|
-
{ 'custom' => @param }
|
69
|
-
end
|
70
|
-
end
|
71
|
-
R18n.default_loader = loader
|
72
|
-
expect(R18n::I18n.new('en', 'default').custom).to eq('default')
|
73
|
-
end
|
74
|
-
|
75
|
-
it 'loads translations' do
|
76
|
-
i18n = R18n::I18n.new(%w[ru en], DIR)
|
77
|
-
expect(i18n.one).to eq('Один')
|
78
|
-
expect(i18n[:one]).to eq('Один')
|
79
|
-
expect(i18n['one']).to eq('Один')
|
80
|
-
expect(i18n.only.english).to eq('Only in English')
|
81
|
-
end
|
82
|
-
|
83
|
-
it 'loads translations from several dirs' do
|
84
|
-
i18n = R18n::I18n.new(%w[nolocale en], [TWO, DIR])
|
85
|
-
expect(i18n.in.two).to eq('Two')
|
86
|
-
expect(i18n.in.another.level).to eq('Hierarchical')
|
87
|
-
end
|
88
|
-
|
89
|
-
it 'uses extension places' do
|
90
|
-
R18n.extension_places << EXT
|
91
|
-
|
92
|
-
i18n = R18n::I18n.new('en', DIR)
|
93
|
-
expect(i18n.ext).to eq('Extension')
|
94
|
-
expect(i18n.one).to eq('One')
|
95
|
-
end
|
96
|
-
|
97
|
-
it "doesn't use extension without app translations with same locale" do
|
98
|
-
R18n.extension_places << EXT
|
99
|
-
|
100
|
-
i18n = R18n::I18n.new(%w[notransl en], DIR)
|
101
|
-
expect(i18n.ext).to eq('Extension')
|
102
|
-
end
|
103
|
-
|
104
|
-
it 'ignores case on loading' do
|
105
|
-
i18n = R18n::I18n.new('nolocale', [DIR])
|
106
|
-
expect(i18n.one).to eq('ONE')
|
107
|
-
|
108
|
-
i18n = R18n::I18n.new('nolocale', [DIR])
|
109
|
-
expect(i18n.one).to eq('ONE')
|
110
|
-
end
|
111
|
-
|
112
|
-
it 'loads default translation' do
|
113
|
-
i18n = R18n::I18n.new('nolocale', DIR)
|
114
|
-
expect(i18n.one).to eq('ONE')
|
115
|
-
expect(i18n.two).to eq('Two')
|
116
|
-
end
|
117
|
-
|
118
|
-
it 'loads sublocales for first locale' do
|
119
|
-
R18n::I18n.default = 'notransl'
|
120
|
-
|
121
|
-
i18n = R18n::I18n.new('ru', DIR)
|
122
|
-
expect(i18n.one).to eq('Один')
|
123
|
-
expect(i18n.two).to eq('Two')
|
124
|
-
end
|
125
|
-
|
126
|
-
it 'loads base translations from parent locale' do
|
127
|
-
i18n = R18n::I18n.new('en-US', File.join(TRANSLATIONS, 'with_regions'))
|
128
|
-
expect(i18n.save).to eq('Save')
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'returns available translations' do
|
132
|
-
i18n = R18n::I18n.new('en', DIR)
|
133
|
-
expect(i18n.available_locales).to match_array([
|
134
|
-
R18n.locale('nolocale'),
|
135
|
-
R18n.locale('ru'),
|
136
|
-
R18n.locale('en')
|
137
|
-
])
|
138
|
-
end
|
139
|
-
|
140
|
-
it 'caches translations' do
|
141
|
-
counter = CounterLoader.new('en')
|
142
|
-
|
143
|
-
R18n::I18n.new('en', counter)
|
144
|
-
expect(counter.loaded).to eq(1)
|
145
|
-
|
146
|
-
R18n::I18n.new('en', counter)
|
147
|
-
expect(counter.loaded).to eq(1)
|
148
|
-
|
149
|
-
R18n.clear_cache!
|
150
|
-
R18n::I18n.new('en', counter)
|
151
|
-
expect(counter.loaded).to eq(2)
|
152
|
-
end
|
153
|
-
|
154
|
-
it "doesn't clear cache when custom filters are specified" do
|
155
|
-
counter = CounterLoader.new('en')
|
156
|
-
|
157
|
-
R18n::I18n.new(
|
158
|
-
'en', counter, off_filters: :untranslated, on_filters: :untranslated_html
|
159
|
-
)
|
160
|
-
expect(counter.loaded).to eq(1)
|
161
|
-
|
162
|
-
R18n::I18n.new(
|
163
|
-
'en', counter, off_filters: :untranslated, on_filters: :untranslated_html
|
164
|
-
)
|
165
|
-
expect(counter.loaded).to eq(1)
|
166
|
-
end
|
167
|
-
|
168
|
-
it 'caches translations by used locales' do
|
169
|
-
counter = CounterLoader.new('en', 'ru')
|
170
|
-
|
171
|
-
R18n::I18n.new('en', counter)
|
172
|
-
expect(counter.loaded).to eq(1)
|
173
|
-
|
174
|
-
R18n::I18n.new(%w[en fr], counter)
|
175
|
-
expect(counter.loaded).to eq(1)
|
176
|
-
|
177
|
-
R18n::I18n.new(%w[en ru], counter)
|
178
|
-
expect(counter.loaded).to eq(3)
|
179
|
-
|
180
|
-
R18n::I18n.new(%w[ru en], counter)
|
181
|
-
expect(counter.loaded).to eq(5)
|
182
|
-
end
|
183
|
-
|
184
|
-
it 'caches translations by places' do
|
185
|
-
counter = CounterLoader.new('en', 'ru')
|
186
|
-
|
187
|
-
R18n::I18n.new('en', counter)
|
188
|
-
expect(counter.loaded).to eq(1)
|
189
|
-
|
190
|
-
R18n::I18n.new('en', [counter, DIR])
|
191
|
-
expect(counter.loaded).to eq(2)
|
192
|
-
|
193
|
-
R18n.extension_places << EXT
|
194
|
-
R18n::I18n.new('en', counter)
|
195
|
-
expect(counter.loaded).to eq(3)
|
196
|
-
|
197
|
-
same = CounterLoader.new('en', 'ru')
|
198
|
-
R18n::I18n.new('en', same)
|
199
|
-
expect(same.loaded).to eq(0)
|
200
|
-
|
201
|
-
different = CounterLoader.new('en', 'fr')
|
202
|
-
R18n::I18n.new('en', different)
|
203
|
-
expect(different.loaded).to eq(1)
|
204
|
-
end
|
205
|
-
|
206
|
-
it 'reloads translations' do
|
207
|
-
loader = Class.new do
|
208
|
-
def available
|
209
|
-
[R18n.locale('en')]
|
210
|
-
end
|
211
|
-
|
212
|
-
def load(_locale)
|
213
|
-
@answer ||= 0
|
214
|
-
@answer += 1
|
215
|
-
{ 'one' => @answer }
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
i18n = R18n::I18n.new('en', loader.new)
|
220
|
-
expect(i18n.one).to eq(1)
|
221
|
-
|
222
|
-
i18n.reload!
|
223
|
-
expect(i18n.one).to eq(2)
|
224
|
-
end
|
225
|
-
|
226
|
-
it 'returns translations' do
|
227
|
-
i18n = R18n::I18n.new('en', DIR)
|
228
|
-
expect(i18n.t).to be_kind_of(R18n::Translation)
|
229
|
-
expect(i18n.t.one).to eq('One')
|
230
|
-
end
|
231
|
-
|
232
|
-
it 'returns first locale with locale file' do
|
233
|
-
i18n = R18n::I18n.new(%w[notransl nolocale ru en], DIR)
|
234
|
-
expect(i18n.locale).to eq(R18n.locale('nolocale'))
|
235
|
-
expect(i18n.locale.base).to eq(R18n.locale('ru'))
|
236
|
-
end
|
237
|
-
|
238
|
-
it 'localizes objects' do
|
239
|
-
i18n = R18n::I18n.new('ru')
|
240
|
-
|
241
|
-
expect(i18n.l(-123_456_789)).to eq('−123 456 789')
|
242
|
-
expect(i18n.l(-12_345.67)).to eq('−12 345,67')
|
243
|
-
|
244
|
-
time = Time.utc(2014, 5, 6, 7, 8, 9)
|
245
|
-
expect(i18n.l(time, '%A'))
|
246
|
-
.to eq('Вторник')
|
247
|
-
expect(i18n.l(time, :month))
|
248
|
-
.to eq('Май')
|
249
|
-
expect(i18n.l(time, :standard))
|
250
|
-
.to eq('06.05.2014 07:08')
|
251
|
-
expect(i18n.l(time, :standard, with_seconds: true))
|
252
|
-
.to eq('06.05.2014 07:08:09')
|
253
|
-
expect(i18n.l(time, :full))
|
254
|
-
.to eq('6 мая 2014 07:08')
|
255
|
-
expect(i18n.l(time, :full, with_seconds: true))
|
256
|
-
.to eq('6 мая 2014 07:08:09')
|
257
|
-
|
258
|
-
expect(i18n.l(Date.new(0))).to eq('01.01.0000')
|
259
|
-
end
|
260
|
-
|
261
|
-
it 'returns marshalizable values' do
|
262
|
-
i18n = R18n::I18n.new(
|
263
|
-
'en', DIR, off_filters: :untranslated, on_filters: :untranslated_html
|
264
|
-
)
|
265
|
-
demarsh = Marshal.load(Marshal.dump(i18n.t.one))
|
266
|
-
|
267
|
-
expect(i18n.t.one).to eq(demarsh)
|
268
|
-
expect(i18n.t.one.path).to eq(demarsh.path)
|
269
|
-
expect(i18n.t.one.locale).to eq(demarsh.locale)
|
270
|
-
|
271
|
-
demarsh = Marshal.load(Marshal.dump(i18n.t.no_translation))
|
272
|
-
expect(i18n.t.no_translation).to eq(demarsh)
|
273
|
-
end
|
274
|
-
end
|