fast_gettext 0.7.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,8 +13,7 @@ module FastGettext
13
13
  [:available_locales, :_locale, :text_domain, :pluralisation_rule].each do |method_name|
14
14
  key = "fast_gettext_#{method_name}".to_sym
15
15
  define_method "#{method_name}=" do |value|
16
- Thread.current[key]=value
17
- update_current_cache
16
+ update_current_cache if Thread.current[key] != Thread.current[key]=value
18
17
  end
19
18
  end
20
19
 
@@ -17,15 +17,15 @@ module FastGettext
17
17
  klas.extend self
18
18
  end
19
19
 
20
- def _(key)
21
- FastGettext.cached_find(key) or key
20
+ def _(key, &block)
21
+ FastGettext.cached_find(key) or (block ? block.call : key)
22
22
  end
23
23
 
24
24
  #translate pluralized
25
25
  # some languages have up to 4 plural forms...
26
26
  # n_(singular, plural, plural form 2, ..., count)
27
27
  # n_('apple','apples',3)
28
- def n_(*keys)
28
+ def n_(*keys, &block)
29
29
  count = keys.pop
30
30
  translations = FastGettext.cached_plural_find(*keys)
31
31
 
@@ -38,15 +38,15 @@ module FastGettext
38
38
  elsif keys[selected]
39
39
  _(keys[selected])
40
40
  else
41
- keys.last
41
+ block ? block.call : keys.last
42
42
  end
43
43
  end
44
44
 
45
45
  #translate, but discard namespace if nothing was found
46
46
  # Car|Tire -> Tire if no translation could be found
47
- def s_(key,separator=nil)
47
+ def s_(key, separator=nil, &block)
48
48
  translation = FastGettext.cached_find(key) and return translation
49
- key.split(separator||NAMESPACE_SEPARATOR).last
49
+ block ? block.call : key.split(separator||NAMESPACE_SEPARATOR).last
50
50
  end
51
51
 
52
52
  #tell gettext: this string need translation (will be found during parsing)
@@ -59,8 +59,92 @@ module FastGettext
59
59
  keys
60
60
  end
61
61
 
62
- def ns_(*args)
63
- n_(*args).split(NAMESPACE_SEPARATOR).last
62
+ def ns_(*args, &block)
63
+ translation = n_(*args, &block)
64
+ # block is called once again to compare result
65
+ block && translation == block.call ? translation : translation.split(NAMESPACE_SEPARATOR).last
66
+ end
67
+ end
68
+
69
+ # this module should be included for multi-domain support
70
+ module TranslationMultidomain
71
+ extend self
72
+
73
+ #make it usable in class definition, e.g.
74
+ # class Y
75
+ # include FastGettext::TranslationMultidomain
76
+ # @@x = d_('domain', 'y')
77
+ # end
78
+ def self.included(klas) #:nodoc:
79
+ klas.extend self
80
+ end
81
+
82
+ # helper block for changing domains
83
+ def _in_domain domain
84
+ old_domain = FastGettext.text_domain
85
+ FastGettext.text_domain = domain
86
+ yield if block_given?
87
+ ensure
88
+ FastGettext.text_domain = old_domain
89
+ end
90
+
91
+ # gettext functions to translate in the context of given domain
92
+ def d_(domain, key, &block)
93
+ _in_domain domain do
94
+ FastGettext::Translation._(key, &block)
95
+ end
96
+ end
97
+
98
+ def dn_(domain, *keys, &block)
99
+ _in_domain domain do
100
+ FastGettext::Translation.n_(*keys, &block)
101
+ end
102
+ end
103
+
104
+ def ds_(domain, key, separator=nil, &block)
105
+ _in_domain domain do
106
+ FastGettext::Translation.s_(key, separator, &block)
107
+ end
108
+ end
109
+
110
+ def dns_(domain, *keys, &block)
111
+ _in_domain domain do
112
+ FastGettext::Translation.ns_(*keys, &block)
113
+ end
114
+ end
115
+
116
+ # gettext functions to translate in the context of any domain
117
+ # (note: if mutiple domains contains key, random translation is returned)
118
+ def D_(key)
119
+ FastGettext.translation_repositories.each_key do |domain|
120
+ result = FastGettext::TranslationMultidomain.d_(domain, key) {nil}
121
+ return result unless result.nil?
122
+ end
123
+ key
124
+ end
125
+
126
+ def Dn_(*keys)
127
+ FastGettext.translation_repositories.each_key do |domain|
128
+ result = FastGettext::TranslationMultidomain.dn_(domain, *keys) {nil}
129
+ return result unless result.nil?
130
+ end
131
+ keys[-3].split(keys[-2]||NAMESPACE_SEPARATOR).last
132
+ end
133
+
134
+ def Ds_(key, separator=nil)
135
+ FastGettext.translation_repositories.each_key do |domain|
136
+ result = FastGettext::TranslationMultidomain.ds_(domain, key, separator) {nil}
137
+ return result unless result.nil?
138
+ end
139
+ key.split(separator||NAMESPACE_SEPARATOR).last
140
+ end
141
+
142
+ def Dns_(*keys)
143
+ FastGettext.translation_repositories.each_key do |domain|
144
+ result = FastGettext::TranslationMultidomain.dns_(domain, *keys) {nil}
145
+ return result unless result.nil?
146
+ end
147
+ keys[-2].split(NAMESPACE_SEPARATOR).last
64
148
  end
65
149
  end
66
150
  end
@@ -1,3 +1,5 @@
1
+ require "protected_attributes" if ActiveRecord::VERSION::MAJOR >= 4
2
+
1
3
  class TranslationKey < ActiveRecord::Base
2
4
  has_many :translations, :class_name => 'TranslationText', :dependent => :destroy
3
5
 
@@ -17,7 +19,13 @@ class TranslationKey < ActiveRecord::Base
17
19
  end
18
20
 
19
21
  def self.available_locales
20
- @@available_locales ||= TranslationText.count(:group=>:locale).keys.sort
22
+ @@available_locales ||= begin
23
+ if ActiveRecord::VERSION::MAJOR >= 3
24
+ TranslationText.group(:locale).count
25
+ else
26
+ TranslationText.count(:group=>:locale)
27
+ end.keys.sort
28
+ end
21
29
  end
22
30
 
23
31
  protected
@@ -1,3 +1,5 @@
1
+ require "protected_attributes" if ActiveRecord::VERSION::MAJOR >= 4
2
+
1
3
  class TranslationText < ActiveRecord::Base
2
4
  belongs_to :translation_key, :class_name => 'TranslationKey'
3
5
  validates_presence_of :locale
@@ -1,3 +1,3 @@
1
1
  module FastGettext
2
- VERSION = Version = '0.7.1'
2
+ VERSION = Version = '0.8.0'
3
3
  end
@@ -61,7 +61,7 @@ describe 'Storage' do
61
61
 
62
62
  describe :pluralisation_rule do
63
63
  it "defaults to singular-if-1 when it is not set" do
64
- stub!(:current_repository).and_return mock('',:pluralisation_rule=>nil)
64
+ should_receive(:current_repository).at_least(1).and_return double(:pluralisation_rule => nil)
65
65
  self.pluralisation_rule = nil
66
66
  pluralisation_rule.call(1).should == false
67
67
  pluralisation_rule.call(0).should == true
@@ -256,8 +256,8 @@ describe 'Storage' do
256
256
  FastGettext.text_domain = 'xxx'
257
257
  FastGettext.available_locales = ['de','en']
258
258
  FastGettext.locale = 'de'
259
- FastGettext.current_repository.stub!(:"[]").with('abc').and_return 'old'
260
- FastGettext.current_repository.stub!(:"[]").with('unfound').and_return nil
259
+ FastGettext.current_repository.stub(:"[]").with('abc').and_return 'old'
260
+ FastGettext.current_repository.stub(:"[]").with('unfound').and_return nil
261
261
  FastGettext._('abc')
262
262
  FastGettext._('unfound')
263
263
  FastGettext.locale = 'en'
@@ -333,7 +333,6 @@ describe 'Storage' do
333
333
 
334
334
  it "does not overwrite an existing cache value" do
335
335
  current_cache['xxx']='xxx'
336
- stub!(:current_repository).and_return 'xxx'=>'1'
337
336
  key_exist?('xxx')
338
337
  current_cache['xxx'].should == 'xxx'
339
338
  end
@@ -36,9 +36,9 @@ describe 'FastGettext::TranslationRepository::Chain' do
36
36
  describe "filled chain" do
37
37
  before do
38
38
  @one = MockRepo.new
39
- @one.stub!(:singular).with('xx').and_return 'one'
39
+ @one.stub(:singular).with('xx').and_return 'one'
40
40
  @two = MockRepo.new
41
- @two.stub!(:singular).with('xx').and_return 'two'
41
+ @two.stub(:singular).with('xx').and_return 'two'
42
42
  @rep = FastGettext::TranslationRepository.build('chain', :chain=>[@one, @two], :type=>:chain)
43
43
  end
44
44
 
@@ -31,11 +31,11 @@ describe 'FastGettext::TranslationRepository::Mo' do
31
31
  it "can reload" do
32
32
  FastGettext.locale = 'de'
33
33
 
34
- @rep['Untranslated'].should be_nil
34
+ @rep['Untranslated and translated in test2'].should be_nil
35
35
 
36
36
  @rep.reload
37
37
 
38
- @rep['Untranslated'].should == 'Translated'
38
+ @rep['Untranslated and translated in test2'].should == 'Translated'
39
39
  end
40
40
 
41
41
  it "returns true" do
@@ -51,6 +51,8 @@ describe 'FastGettext::TranslationRepository::Mo' do
51
51
  end
52
52
 
53
53
  it "can work in SAFE mode" do
54
- `ruby spec/cases/safe_mode_can_handle_locales.rb 2>&1`.should == 'true'
54
+ pending_if RUBY_VERSION > "2.0" do
55
+ `ruby spec/cases/safe_mode_can_handle_locales.rb 2>&1`.should == 'true'
56
+ end
55
57
  end
56
58
  end
@@ -61,7 +61,7 @@ describe 'FastGettext::TranslationRepository::Yaml' do
61
61
  end
62
62
 
63
63
  it "can be used to translate plural forms" do
64
- FastGettext.stub!(:current_repository).and_return @rep
64
+ FastGettext.stub(:current_repository).and_return @rep
65
65
  FastGettext.n_('cars.axis','cars.axis',2).should == 'Achsen'
66
66
  FastGettext.n_('cars.axis',2).should == 'Achsen'
67
67
  FastGettext.n_('cars.axis',1).should == 'Achse'
@@ -69,8 +69,8 @@ describe 'FastGettext::TranslationRepository::Yaml' do
69
69
 
70
70
  4.times do |i|
71
71
  it "can be used to do wanky pluralisation rules #{i}" do
72
- FastGettext.stub!(:current_repository).and_return @rep
73
- @rep.stub!(:pluralisation_rule).and_return lambda{|x| i}
72
+ FastGettext.stub(:current_repository).and_return @rep
73
+ @rep.stub(:pluralisation_rule).and_return lambda{|x| i}
74
74
  FastGettext.n_('cars.silly',1).should == i.to_s # cars.silly translations are 0,1,2,3
75
75
  end
76
76
  end
@@ -2,6 +2,7 @@ require "spec_helper"
2
2
 
3
3
  describe FastGettext::Translation do
4
4
  include FastGettext::Translation
5
+ include FastGettext::TranslationMultidomain
5
6
 
6
7
  before do
7
8
  default_setup
@@ -42,6 +43,14 @@ describe FastGettext::Translation do
42
43
  it "does not return the gettext meta information" do
43
44
  _('').should == ''
44
45
  end
46
+
47
+ it "returns nil when specified" do
48
+ _('not found'){nil}.should be_nil
49
+ end
50
+
51
+ it "returns block when specified" do
52
+ _('not found'){:block}.should == :block
53
+ end
45
54
  end
46
55
 
47
56
  describe :n_ do
@@ -85,6 +94,10 @@ describe FastGettext::Translation do
85
94
  FastGettext.pluralisation_rule = lambda{|x|4}
86
95
  n_('Apple','Apples',2).should == 'Apples'
87
96
  end
97
+
98
+ it "returns block when specified" do
99
+ n_('not found'){:block}.should == :block
100
+ end
88
101
  end
89
102
 
90
103
  describe :s_ do
@@ -99,6 +112,10 @@ describe FastGettext::Translation do
99
112
  it "can use a custom seperator" do
100
113
  s_("XXX/not found",'/').should == "not found"
101
114
  end
115
+
116
+ it "returns block when specified" do
117
+ s_('not found'){:block}.should == :block
118
+ end
102
119
  end
103
120
 
104
121
  describe :N_ do
@@ -117,13 +134,181 @@ describe FastGettext::Translation do
117
134
  it "translates whith namespace" do
118
135
  ns_('Fruit|Apple','Fruit|Apples',2).should == 'Apples'
119
136
  end
137
+
138
+ it "returns block when specified" do
139
+ ns_('not found'){:block}.should == :block
140
+ ns_('not found'){nil}.should be_nil
141
+ end
120
142
  end
121
143
 
144
+ describe :multi_domain do
145
+ before do
146
+ setup_extra_domain
147
+ end
148
+
149
+ describe :_in_domain do
150
+ it "changes domain via in_domain" do
151
+ Thread.current[:fast_gettext_text_domain].should == "test"
152
+ _in_domain "fake" do
153
+ Thread.current[:fast_gettext_text_domain].should == "fake"
154
+ end
155
+ Thread.current[:fast_gettext_text_domain].should == "test"
156
+ end
157
+ end
158
+
159
+ describe :d_ do
160
+ it "translates simple text" do
161
+ d_('test', 'car').should == 'Auto'
162
+ end
163
+
164
+ it "translates simple text in different domain" do
165
+ d_('test2', 'car').should == 'Auto 2'
166
+ end
167
+
168
+ it "translates simple text in different domain one transaction" do
169
+ d_('test', 'car').should == 'Auto'
170
+ d_('test2', 'car').should == 'Auto 2'
171
+ end
172
+
173
+ it "returns the original string if its translation is blank" do
174
+ d_('test', 'Untranslated').should == 'Untranslated'
175
+ end
176
+
177
+ it "sets text domain back to previous one" do
178
+ old_domain = FastGettext.text_domain
179
+ d_('test2', 'car').should == 'Auto 2'
180
+ FastGettext.text_domain.should == old_domain
181
+ end
182
+
183
+ it "returns appropriate key if translation is not found in a domain" do
184
+ FastGettext.translation_repositories['fake'] = {}
185
+ d_('fake', 'car').should == 'car'
186
+ end
187
+ end
188
+
189
+ describe :dn_ do
190
+ before do
191
+ FastGettext.pluralisation_rule = nil
192
+ end
193
+
194
+ it "translates pluralized" do
195
+ dn_('test', 'Axis','Axis',1).should == 'Achse'
196
+ dn_('test2', 'Axis','Axis',1).should == 'Achse 2'
197
+ end
198
+
199
+ it "returns a simple translation when no combined was found" do
200
+ dn_('test', 'Axis','NOTFOUNDs',1).should == 'Achse'
201
+ dn_('test2', 'Axis','NOTFOUNDs',1).should == 'Achse 2'
202
+ end
203
+
204
+ it "returns the appropriate key if no translation was found" do
205
+ dn_('test', 'NOTFOUND','NOTFOUNDs',1).should == 'NOTFOUND'
206
+ dn_('test', 'NOTFOUND','NOTFOUNDs',2).should == 'NOTFOUNDs'
207
+ end
208
+
209
+ it "returns the last key when no translation was found and keys where to short" do
210
+ FastGettext.pluralisation_rule = lambda{|x|4}
211
+ dn_('test', 'Apple','Apples',2).should == 'Apples'
212
+ end
213
+ end
214
+
215
+ describe :ds_ do
216
+ it "translates simple text" do
217
+ ds_('test2', 'car').should == 'Auto 2'
218
+ ds_('test', 'car').should == 'Auto'
219
+ end
220
+
221
+ it "returns cleaned key if a translation was not found" do
222
+ ds_('test2', "XXX|not found").should == "not found"
223
+ end
224
+
225
+ it "can use a custom seperator" do
226
+ ds_('test2', "XXX/not found",'/').should == "not found"
227
+ end
228
+ end
229
+
230
+ describe :dns_ do
231
+ it "translates whith namespace" do
232
+ dns_('test', 'Fruit|Apple','Fruit|Apples',2).should == 'Apples'
233
+ dns_('test2', 'Fruit|Apple','Fruit|Apples',2).should == 'Apples'
234
+ end
235
+ end
236
+ end
237
+
238
+ describe :multidomain_all do
239
+ before do
240
+ setup_extra_domain
241
+ end
242
+
243
+ describe :D_ do
244
+ it "translates simple text" do
245
+ D_('not found').should == 'not found'
246
+ D_('only in test2 domain').should == 'nur in test2 Domain'
247
+ end
248
+
249
+ it "returns translation from random domain" do
250
+ D_('car').should match('(Auto|Auto 2)')
251
+ end
252
+
253
+ it "sets text domain back to previous one" do
254
+ old_domain = FastGettext.text_domain
255
+ D_('car').should == 'Auto'
256
+ FastGettext.text_domain.should == old_domain
257
+ end
258
+ end
259
+
260
+ describe :Dn_ do
261
+ before do
262
+ FastGettext.pluralisation_rule = nil
263
+ end
264
+
265
+ it "translates pluralized" do
266
+ Dn_('Axis','Axis',1).should match('(Achse|Achse 2)')
267
+ end
268
+
269
+ it "returns a simple translation when no combined was found" do
270
+ Dn_('Axis','NOTFOUNDs',1).should match('(Achse|Achse 2)')
271
+ end
272
+
273
+ it "returns the appropriate key if no translation was found" do
274
+ Dn_('NOTFOUND','NOTFOUNDs',1).should == 'NOTFOUND'
275
+ end
276
+
277
+ it "returns the last key when no translation was found and keys where to short" do
278
+ Dn_('Apple','Apples',2).should == 'Apples'
279
+ end
280
+ end
281
+
282
+ describe :Ds_ do
283
+ it "translates simple text" do
284
+ Ds_('car').should match('(Auto|Auto 2)')
285
+ end
286
+
287
+ it "returns cleaned key if a translation was not found" do
288
+ Ds_("XXX|not found").should == "not found"
289
+ end
290
+
291
+ it "can use a custom seperator" do
292
+ Ds_("XXX/not found",'/').should == "not found"
293
+ end
294
+ end
295
+
296
+ describe :Dns_ do
297
+ it "translates whith namespace" do
298
+ Dns_('Fruit|Apple','Fruit|Apples',1).should == 'Apple'
299
+ Dns_('Fruit|Apple','Fruit|Apples',2).should == 'Apples'
300
+ end
301
+
302
+ it "returns cleaned key if a translation was not found" do
303
+ Dns_("XXX|not found", "YYY|not found", 1).should == "not found"
304
+ Dns_("XXX|not found", "YYY|not found", 2).should == "not found"
305
+ end
306
+ end
307
+ end
122
308
 
123
309
  describe :caching do
124
310
  describe :cache_hit do
125
311
  before do
126
- FastGettext.translation_repositories.replace({})
127
312
  #singular cache keys
128
313
  FastGettext.current_cache['xxx'] = '1'
129
314
 
@@ -166,5 +351,13 @@ describe FastGettext::Translation do
166
351
  FastGettext.text_domain = 'test'
167
352
  _('car').should == 'Auto'
168
353
  end
354
+
355
+ it "caches different textdomains seperatly for d_" do
356
+ _('car').should == 'Auto'
357
+
358
+ FastGettext.translation_repositories['fake'] = {}
359
+ d_('fake', 'car').should == 'car'
360
+ d_('test','car').should == 'Auto'
361
+ end
169
362
  end
170
363
  end