fast_gettext 0.4.16

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 (61) hide show
  1. data/.gitignore +2 -0
  2. data/CHANGELOG +6 -0
  3. data/README.markdown +181 -0
  4. data/Rakefile +42 -0
  5. data/VERSION +1 -0
  6. data/benchmark/base.rb +42 -0
  7. data/benchmark/baseline.rb +5 -0
  8. data/benchmark/fast_gettext.rb +18 -0
  9. data/benchmark/i18n_simple.rb +7 -0
  10. data/benchmark/ideal.rb +22 -0
  11. data/benchmark/locale/de.yml +127 -0
  12. data/benchmark/locale/de/LC_MESSAGES/large.mo +0 -0
  13. data/benchmark/misc/threadsave.rb +21 -0
  14. data/benchmark/namespace/fast_gettext.rb +15 -0
  15. data/benchmark/namespace/original.rb +14 -0
  16. data/benchmark/original.rb +15 -0
  17. data/examples/db/migration.rb +22 -0
  18. data/examples/missing_translation_logger.rb +13 -0
  19. data/fast_gettext.gemspec +114 -0
  20. data/lib/fast_gettext.rb +30 -0
  21. data/lib/fast_gettext/mo_file.rb +67 -0
  22. data/lib/fast_gettext/po_file.rb +14 -0
  23. data/lib/fast_gettext/storage.rb +188 -0
  24. data/lib/fast_gettext/translation.rb +53 -0
  25. data/lib/fast_gettext/translation_repository.rb +15 -0
  26. data/lib/fast_gettext/translation_repository/base.rb +49 -0
  27. data/lib/fast_gettext/translation_repository/chain.rb +43 -0
  28. data/lib/fast_gettext/translation_repository/db.rb +57 -0
  29. data/lib/fast_gettext/translation_repository/db_models/translation_key.rb +26 -0
  30. data/lib/fast_gettext/translation_repository/db_models/translation_text.rb +9 -0
  31. data/lib/fast_gettext/translation_repository/logger.rb +27 -0
  32. data/lib/fast_gettext/translation_repository/mo.rb +35 -0
  33. data/lib/fast_gettext/translation_repository/po.rb +18 -0
  34. data/spec/aa_unconfigued_spec.rb +21 -0
  35. data/spec/fast_gettext/mo_file_spec.rb +36 -0
  36. data/spec/fast_gettext/storage_spec.rb +309 -0
  37. data/spec/fast_gettext/translation_repository/base_spec.rb +21 -0
  38. data/spec/fast_gettext/translation_repository/chain_spec.rb +82 -0
  39. data/spec/fast_gettext/translation_repository/db_spec.rb +71 -0
  40. data/spec/fast_gettext/translation_repository/logger_spec.rb +41 -0
  41. data/spec/fast_gettext/translation_repository/mo_spec.rb +31 -0
  42. data/spec/fast_gettext/translation_repository/po_spec.rb +31 -0
  43. data/spec/fast_gettext/translation_spec.rb +152 -0
  44. data/spec/fast_gettext_spec.rb +44 -0
  45. data/spec/locale/de/LC_MESSAGES/test.mo +0 -0
  46. data/spec/locale/de/test.po +61 -0
  47. data/spec/locale/en/LC_MESSAGES/plural_test.mo +0 -0
  48. data/spec/locale/en/LC_MESSAGES/test.mo +0 -0
  49. data/spec/locale/en/plural_test.po +20 -0
  50. data/spec/locale/en/test.po +59 -0
  51. data/spec/spec_helper.rb +26 -0
  52. data/spec/vendor/fake_load_path/iconv.rb +2 -0
  53. data/spec/vendor/iconv_spec.rb +27 -0
  54. data/spec/vendor/string_spec.rb +67 -0
  55. data/vendor/README.rdoc +236 -0
  56. data/vendor/empty.mo +0 -0
  57. data/vendor/iconv.rb +107 -0
  58. data/vendor/mofile.rb +296 -0
  59. data/vendor/poparser.rb +331 -0
  60. data/vendor/string.rb +58 -0
  61. metadata +130 -0
@@ -0,0 +1,53 @@
1
+ module FastGettext
2
+ # this module should be included
3
+ # Responsibility:
4
+ # - direct translation queries to the current repository
5
+ # - handle untranslated values
6
+ # - understand / enforce namespaces
7
+ # - decide which plural form is used
8
+ module Translation
9
+ extend self
10
+
11
+ #make it usable in class definition, e.g.
12
+ # class Y
13
+ # include FastGettext::Translation
14
+ # @@x = _('y')
15
+ # end
16
+ def self.included(klas) #:nodoc:
17
+ klas.extend self
18
+ end
19
+
20
+ def _(key)
21
+ FastGettext.cached_find(key) or key
22
+ end
23
+
24
+ #translate pluralized
25
+ # some languages have up to 4 plural forms...
26
+ # n_(singular, plural, plural form 2, ..., count)
27
+ # n_('apple','apples',3)
28
+ def n_(*keys)
29
+ count = keys.pop
30
+ translations = FastGettext.cached_plural_find *keys
31
+ selected = FastGettext.pluralisation_rule.call(count)
32
+ selected = selected ? 1 : 0 unless selected.is_a? Numeric #convert booleans to numbers
33
+ translations[selected] || keys[selected] || keys.last
34
+ end
35
+
36
+ #translate, but discard namespace if nothing was found
37
+ # Car|Tire -> Tire if no translation could be found
38
+ def s_(key,seperator=nil)
39
+ translation = FastGettext.cached_find(key) and return translation
40
+ key.split(seperator||NAMESPACE_SEPERATOR).last
41
+ end
42
+
43
+ #tell gettext: this string need translation (will be found during parsing)
44
+ def N_(translate)
45
+ translate
46
+ end
47
+
48
+ #tell gettext: this string need translation (will be found during parsing)
49
+ def Nn_(*keys)
50
+ keys
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,15 @@
1
+ module FastGettext
2
+ # Responsibility:
3
+ # - decide which repository to choose from given input
4
+ module TranslationRepository
5
+ extend self
6
+
7
+ # only single-word types supported atm (mytype works, MyType will not)
8
+ def build(name,options)
9
+ type = options[:type] || :mo
10
+ require "fast_gettext/translation_repository/#{type}"
11
+ klas = eval(type.to_s.capitalize)
12
+ klas.new(name,options)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,49 @@
1
+ module FastGettext
2
+ module TranslationRepository
3
+ # Responsibility:
4
+ # - base for all repositories
5
+ # - fallback as empty repository, that cannot translate anything but does not crash
6
+ class Base
7
+ def initialize(name,options={})
8
+ @name = name
9
+ @options = options
10
+ end
11
+
12
+ def pluralisation_rule
13
+ nil
14
+ end
15
+
16
+ def available_locales
17
+ []
18
+ end
19
+
20
+ def [](key)
21
+ current_translations[key]
22
+ end
23
+
24
+ def plural(*keys)
25
+ current_translations.plural(*keys)
26
+ end
27
+
28
+ protected
29
+
30
+ def current_translations
31
+ MoFile.empty
32
+ end
33
+
34
+ def find_files_in_locale_folders(relative_file_path,path)
35
+ path ||= "locale"
36
+ raise "path #{path} cound not be found!" unless File.exist?(path)
37
+
38
+ @files = {}
39
+ Dir[File.join(path,'*')].each do |locale_folder|
40
+ next unless File.basename(locale_folder) =~ LOCALE_REX
41
+ file = File.join(locale_folder,relative_file_path)
42
+ next unless File.exist? file
43
+ locale = File.basename(locale_folder)
44
+ @files[locale] = yield(locale,file)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,43 @@
1
+ require 'fast_gettext/translation_repository/base'
2
+
3
+ module FastGettext
4
+ module TranslationRepository
5
+ # Responsibility:
6
+ # - delegate calls to members of the chain in turn
7
+ #TODO cache should be expired after a repo was added
8
+ class Chain < Base
9
+ attr_accessor :chain
10
+
11
+ def initialize(name,options={})
12
+ super
13
+ self.chain = options[:chain]
14
+ end
15
+
16
+ def available_locales
17
+ chain.map{|c|c.available_locales}.flatten.uniq
18
+ end
19
+
20
+ def pluralisation_rule
21
+ chain.each do |c|
22
+ result = c.pluralisation_rule and return result
23
+ end
24
+ nil
25
+ end
26
+
27
+ def [](key)
28
+ chain.each do |c|
29
+ result = c[key] and return result
30
+ end
31
+ nil
32
+ end
33
+
34
+ def plural(*keys)
35
+ chain.each do |c|
36
+ result = c.plural(*keys)
37
+ return result unless result.compact.empty?
38
+ end
39
+ []
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,57 @@
1
+ require 'active_record'
2
+ module FastGettext
3
+ module TranslationRepository
4
+ # Responsibility:
5
+ # - provide access to translations in database through a database abstraction
6
+ #
7
+ # Options:
8
+ # :model => Model that represents your keys
9
+ # you can either use the models supplied under db/, extend them or build your own
10
+ # only constraints:
11
+ # key: find_by_key, translations
12
+ # translation: text, locale
13
+ class Db
14
+ def initialize(name,options={})
15
+ @model = options[:model]
16
+ end
17
+
18
+ @@seperator = '||||' # string that seperates multiple plurals
19
+ def self.seperator=(sep);@@seperator = sep;end
20
+ def self.seperator;@@seperator;end
21
+
22
+ def available_locales
23
+ if @model.respond_to? :available_locales
24
+ @model.available_locales || []
25
+ else
26
+ []
27
+ end
28
+ end
29
+
30
+ def pluralisation_rule
31
+ if @model.respond_to? :pluralsation_rule
32
+ @model.pluralsation_rule
33
+ else
34
+ nil
35
+ end
36
+ end
37
+
38
+ def [](key)
39
+ @model.translation(key, FastGettext.locale)
40
+ end
41
+
42
+ def plural(*args)
43
+ if translation = @model.translation(args*self.class.seperator, FastGettext.locale)
44
+ translation.to_s.split(self.class.seperator)
45
+ else
46
+ []
47
+ end
48
+ end
49
+
50
+ def self.require_models
51
+ require 'fast_gettext/translation_repository/db_models/translation_key'
52
+ require 'fast_gettext/translation_repository/db_models/translation_text'
53
+ FastGettext::TranslationRepository::DbModels
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,26 @@
1
+ module FastGettext::TranslationRepository
2
+ module DbModels
3
+ class TranslationKey < ActiveRecord::Base
4
+ has_many :translations, :class_name=>'TranslationText'
5
+ accepts_nested_attributes_for :translations, :allow_destroy => true
6
+
7
+ validates_uniqueness_of :key
8
+ validates_presence_of :key
9
+
10
+ def self.translation(key, locale)
11
+ return unless translation_key = find_by_key(key)
12
+ return unless translation_text = translation_key.translations.find_by_locale(locale)
13
+ translation_text.text
14
+ end
15
+
16
+ def self.available_locales
17
+ @@available_locales ||= TranslationText.count(:group=>:locale).keys.sort
18
+ end
19
+
20
+ #this is only for ActiveSupport to get polymorphic_url FastGettext::... namespace free
21
+ def self.model_name
22
+ ActiveSupport::ModelName.new('TranslationKey')
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,9 @@
1
+ module FastGettext::TranslationRepository
2
+ module DbModels
3
+ class TranslationText < ActiveRecord::Base
4
+ belongs_to :key, :class_name=>'TranslationKey'
5
+ validates_presence_of :locale
6
+ validates_uniqueness_of :locale, :scope=>:translation_key_id
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ require 'fast_gettext/translation_repository/base'
2
+
3
+ module FastGettext
4
+ module TranslationRepository
5
+ # This should be used in a TranslationRepository::Chain, so tat untranslated keys can be found
6
+ # Responsibility:
7
+ # - log every translation call
8
+ class Logger < Base
9
+ attr_accessor :callback
10
+
11
+ def initialize(name,options={})
12
+ super
13
+ self.callback = options[:callback]
14
+ end
15
+
16
+ def [](key)
17
+ callback.call(key)
18
+ nil
19
+ end
20
+
21
+ def plural(*keys)
22
+ callback.call(keys)
23
+ []
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,35 @@
1
+ require 'fast_gettext/translation_repository/base'
2
+ module FastGettext
3
+ module TranslationRepository
4
+ # Responsibility:
5
+ # - find and store mo files
6
+ # - provide access to translations in mo files
7
+ class Mo < Base
8
+ def initialize(name,options={})
9
+ find_and_store_files(name,options)
10
+ super
11
+ end
12
+
13
+ def available_locales
14
+ @files.keys
15
+ end
16
+
17
+ def pluralisation_rule
18
+ current_translations.pluralisation_rule
19
+ end
20
+
21
+ protected
22
+
23
+ def find_and_store_files(name,options)
24
+ # parse all .mo files with the right name, that sit in locale/LC_MESSAGES folders
25
+ find_files_in_locale_folders(File.join('LC_MESSAGES',"#{name}.mo"),options[:path]) do |locale,file|
26
+ @files[locale] = MoFile.new(file)
27
+ end
28
+ end
29
+
30
+ def current_translations
31
+ @files[FastGettext.locale] || MoFile.empty
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,18 @@
1
+ require 'fast_gettext/translation_repository/base'
2
+ require 'fast_gettext/translation_repository/mo'
3
+ module FastGettext
4
+ module TranslationRepository
5
+ # Responsibility:
6
+ # - find and store po files
7
+ # - provide access to translations in po files
8
+ class Po < Mo
9
+ protected
10
+ def find_and_store_files(name,options)
11
+ require 'fast_gettext/po_file'
12
+ find_files_in_locale_folders("#{name}.po",options[:path]) do |locale,file|
13
+ @files[locale] = PoFile.to_mo_file(file)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,21 @@
1
+ require File.join(File.dirname(__FILE__),'spec_helper')
2
+
3
+ describe 'unconfigured' do
4
+ it "gives a useful error message when trying to just translate" do
5
+ FastGettext.text_domain = nil
6
+ begin
7
+ FastGettext._('x')
8
+ "".should == "success!?"
9
+ rescue FastGettext::Storage::NoTextDomainConfigured
10
+ end
11
+ end
12
+
13
+ it "gives a useful error message when only locale was set" do
14
+ FastGettext.locale = 'de'
15
+ begin
16
+ FastGettext._('x')
17
+ "".should == "success!?"
18
+ rescue FastGettext::Storage::NoTextDomainConfigured
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,36 @@
1
+ current_folder = File.dirname(__FILE__)
2
+ require File.join(current_folder,'..','spec_helper')
3
+
4
+ include FastGettext
5
+ de_file = File.join(current_folder,'..','locale','de','LC_MESSAGES','test.mo')
6
+ de = MoFile.new(de_file)
7
+
8
+ describe MoFile do
9
+ before :all do
10
+ File.exist?(de_file).should == true
11
+ end
12
+
13
+ it "parses a file" do
14
+ de['car'].should == 'Auto'
15
+ end
16
+
17
+ it "stores untranslated values as nil" do
18
+ de['Car|Model'].should == nil
19
+ end
20
+
21
+ it "finds pluralized values" do
22
+ de.plural('Axis','Axis').should == ['Achse','Achsen']
23
+ end
24
+
25
+ it "returns singular translations when pluralisation could not be found" do
26
+ de.plural('Axis','Axis','Axis').should == ['Achse','Achse','Achse']
27
+ end
28
+
29
+ it "returns ids when not plural and singular translations could not be found" do
30
+ de.plural('Axis','Axis','NOTFOUND').should == ['Achse','Achse','NOTFOUND']
31
+ end
32
+
33
+ it "can access plurals through []" do
34
+ de['Axis'].should == 'Achse' #singular
35
+ end
36
+ end
@@ -0,0 +1,309 @@
1
+ current_folder = File.dirname(__FILE__)
2
+ require File.join(current_folder,'..','spec_helper')
3
+
4
+ include FastGettext::Storage
5
+
6
+ describe 'Storage' do
7
+ before do
8
+ #reset everything to nil
9
+ self.available_locales = nil
10
+ self.default_text_domain = nil
11
+ self.default_locale = nil
12
+ send(:_locale=,nil)#nil is not allowed to be set...
13
+ default_locale.should be_nil
14
+ available_locales.should be_nil
15
+ locale.should == 'en'
16
+ end
17
+
18
+ def thread_save(method, value)
19
+ send("#{method}=",value)
20
+
21
+ # mess around with other threads
22
+ 100.times do
23
+ Thread.new {FastGettext.send("#{method}=",'en')}
24
+ end
25
+
26
+ send(method) == value
27
+ end
28
+
29
+ {:locale=>'de', :available_locales=>['de'], :text_domain=>'xx', :pluralisation_rule=>lambda{|x|x==4}}.each do |method, value|
30
+ it "stores #{method} thread-save" do
31
+ thread_save(method, value).should == true
32
+ end
33
+ end
34
+
35
+ it "stores translation_repositories non-thread-safe" do
36
+ self.translation_repositories[:x]=1
37
+ t = Thread.new{self.translation_repositories[:x]=2}
38
+ t.join
39
+ self.translation_repositories[:x].should == 2
40
+ end
41
+
42
+ describe :pluralisation_rule do
43
+ it "defaults to singular-if-1 when it is not set" do
44
+ stub!(:current_repository).and_return mock('',:pluralisation_rule=>nil)
45
+ self.pluralisation_rule = nil
46
+ pluralisation_rule.call(1).should == false
47
+ pluralisation_rule.call(0).should == true
48
+ pluralisation_rule.call(2).should == true
49
+ end
50
+ end
51
+
52
+ describe :default_locale do
53
+ it "stores default_locale non-thread-safe" do
54
+ thread_save(:default_locale, 'de').should == false
55
+ end
56
+
57
+ it "does not overwrite locale" do
58
+ self.locale = 'de'
59
+ self.default_locale = 'yy'
60
+ self.locale.should == 'de'
61
+ end
62
+
63
+ it "falls back to default if locale is missing" do
64
+ self.default_locale = 'yy'
65
+ self.locale.should == 'yy'
66
+ end
67
+
68
+ it "does not set non-available-locales as default" do
69
+ self.available_locales = ['xx']
70
+ self.default_locale = 'yy'
71
+ self.default_locale.should == nil
72
+ end
73
+
74
+ it "can set default_locale to nil" do
75
+ self.default_locale = 'xx'
76
+ self.default_locale = nil
77
+ default_locale.should be_nil
78
+ end
79
+ end
80
+
81
+ describe :default_text_domain do
82
+ it "stores default_text_domain non-thread-safe" do
83
+ thread_save(:default_text_domain, 'xx').should == false
84
+ end
85
+
86
+ it "uses default_text_domain when text_domain is not set" do
87
+ self.text_domain = nil
88
+ self.default_text_domain = 'x'
89
+ text_domain.should == 'x'
90
+ end
91
+
92
+ it "does not use default when domain is set" do
93
+ self.text_domain = 'x'
94
+ self.default_text_domain = 'y'
95
+ text_domain.should == 'x'
96
+ end
97
+ end
98
+
99
+ describe :default_available_locales do
100
+ after do
101
+ self.default_available_locales = nil
102
+ end
103
+
104
+ it "stores default_available_locales non-thread-safe" do
105
+ thread_save(:default_available_locales, 'xx').should == false
106
+ end
107
+
108
+ it "uses default_available_locales when available_locales is not set" do
109
+ self.available_locales = nil
110
+ self.default_available_locales = 'x'
111
+ available_locales.should == 'x'
112
+ end
113
+
114
+ it "does not use default when available_locales is set" do
115
+ self.available_locales = 'x'
116
+ self.default_available_locales = 'y'
117
+ available_locales.should == 'x'
118
+ end
119
+ end
120
+
121
+ describe :locale do
122
+ it "stores everything as long as available_locales is not set" do
123
+ self.available_locales = nil
124
+ self.locale = 'XXX'
125
+ locale.should == 'XXX'
126
+ end
127
+
128
+ it "is en if no locale and no available_locale were set" do
129
+ FastGettext.send(:_locale=,nil)
130
+ self.available_locales = nil
131
+ locale.should == 'en'
132
+ end
133
+
134
+ it "does not change the locale if locales was called with nil" do
135
+ self.locale = nil
136
+ locale.should == 'en'
137
+ end
138
+
139
+ it "is the first available_locale if one was set" do
140
+ self.available_locales = ['de']
141
+ locale.should == 'de'
142
+ end
143
+
144
+ it "does not store a locale if it is not available" do
145
+ self.available_locales = ['de']
146
+ self.locale = 'en'
147
+ locale.should == 'de'
148
+ end
149
+
150
+ it "set_locale returns the old locale if the new could not be set" do
151
+ self.locale = 'de'
152
+ self.available_locales = ['de']
153
+ self.set_locale('en').should == 'de'
154
+ end
155
+
156
+ {
157
+ 'Opera' => "de-DE,de;q=0.9,en;q=0.8",
158
+ 'Firefox' => "de-de,de;q=0.8,en-us;q=0.5,en;q=0.3",
159
+ }.each do |browser,accept_language|
160
+ it "sets the locale from #{browser} headers" do
161
+ FastGettext.available_locales = ['de_DE','de','xx']
162
+ FastGettext.locale = 'xx'
163
+ FastGettext.locale = accept_language
164
+ FastGettext.locale.should == 'de_DE'
165
+ end
166
+ end
167
+
168
+ it "sets a unimportant locale if it is the only available" do
169
+ FastGettext.available_locales = ['en','xx']
170
+ FastGettext.locale = "de-de,de;q=0.8,en-us;q=0.5,en;q=0.3"
171
+ FastGettext.locale.should == 'en'
172
+ end
173
+
174
+ it "sets the locale with the highest wheight" do
175
+ FastGettext.available_locales = ['en','de']
176
+ FastGettext.locale = "xx-us;q=0.5,de-de,de;q=0.8,en;q=0.9"
177
+ FastGettext.locale.should == 'en'
178
+ end
179
+
180
+ it "sets the locale from languages" do
181
+ FastGettext.available_locales = ['de']
182
+ FastGettext.locale = "xx-us;q=0.5,de-de;q=0.8,en-uk;q=0.9"
183
+ FastGettext.locale.should == 'de'
184
+ end
185
+
186
+ it "sets locale from comma seperated" do
187
+ FastGettext.available_locales = ['de_DE','en','xx']
188
+ FastGettext.locale = "de,de-de,en"
189
+ FastGettext.locale.should == 'de_DE'
190
+ end
191
+ end
192
+
193
+ describe :silence_errors do
194
+ before do
195
+ FastGettext.text_domain = 'xxx'
196
+ end
197
+
198
+ it "raises when a textdomain was empty" do
199
+ begin
200
+ FastGettext._('x')
201
+ "".should == "success!?"
202
+ rescue FastGettext::Storage::NoTextDomainConfigured
203
+ end
204
+ end
205
+
206
+ it "can silence erros" do
207
+ FastGettext.silence_errors
208
+ FastGettext._('x').should == 'x'
209
+ end
210
+ end
211
+
212
+ describe :current_cache do
213
+ before do
214
+ FastGettext.text_domain = 'xxx'
215
+ FastGettext.available_locales = ['de','en']
216
+ FastGettext.locale = 'de'
217
+ FastGettext.current_repository.stub!(:"[]").with('abc').and_return 'old'
218
+ FastGettext.current_repository.stub!(:"[]").with('unfound').and_return nil
219
+ FastGettext._('abc')
220
+ FastGettext._('unfound')
221
+ FastGettext.locale = 'en'
222
+ end
223
+
224
+ it "stores a translation seperate by locale" do
225
+ FastGettext.current_cache['abc'].should == nil
226
+ end
227
+
228
+ it "stores a translation seperate by domain" do
229
+ FastGettext.locale = 'de'
230
+ FastGettext.text_domain = nil
231
+ FastGettext.current_cache['abc'].should == nil
232
+ end
233
+
234
+ it "cache is restored through setting of default_text_domain" do
235
+ FastGettext.locale = 'de'
236
+ FastGettext.text_domain = nil
237
+ FastGettext.default_text_domain = 'xxx'
238
+ FastGettext.current_cache['abc'].should == 'old'
239
+ end
240
+
241
+ it "cache is restored through setting of default_locale" do
242
+ FastGettext.send(:_locale=,nil)#reset locale to nil
243
+ FastGettext.default_locale = 'de'
244
+ FastGettext.locale.should == 'de'
245
+ FastGettext.current_cache['abc'].should == 'old'
246
+ end
247
+
248
+ it "stores a translation permanently" do
249
+ FastGettext.locale = 'de'
250
+ FastGettext.current_cache['abc'].should == 'old'
251
+ end
252
+
253
+ it "stores a unfound translation permanently" do
254
+ FastGettext.locale = 'de'
255
+ FastGettext.current_cache['unfound'].should == false
256
+ end
257
+ end
258
+
259
+ describe :key_exist? do
260
+ it "does not find default keys" do
261
+ _('abcde')
262
+ key_exist?('abcde').should be_false
263
+ end
264
+
265
+ it "finds using the current repository" do
266
+ should_receive(:current_repository).and_return '1234'=>'1'
267
+ key_exist?('1234').should == true
268
+ end
269
+
270
+ it "sets the current cache with a found result" do
271
+ should_receive(:current_repository).and_return 'xxx'=>'1'
272
+ key_exist?('xxx')
273
+ current_cache['xxx'].should == '1'
274
+ end
275
+
276
+ it "does not overwrite an existing cache value" do
277
+ current_cache['xxx']='xxx'
278
+ stub!(:current_repository).and_return 'xxx'=>'1'
279
+ key_exist?('xxx')
280
+ current_cache['xxx'].should == 'xxx'
281
+ end
282
+
283
+ it "is false for gettext meta key" do
284
+ key_exist?("").should == false
285
+ end
286
+ end
287
+
288
+ describe :cached_find do
289
+ it "is nil for gettext meta key" do
290
+ cached_find("").should == false
291
+ end
292
+ end
293
+
294
+ describe NoTextDomainConfigured do
295
+ it "shows what to do" do
296
+ NoTextDomainConfigured.new.to_s.should =~ /FastGettext\.add_text_domain/
297
+ end
298
+
299
+ it "warns when text_domain is nil" do
300
+ FastGettext.text_domain = nil
301
+ NoTextDomainConfigured.new.to_s.should =~ /\(nil\)/
302
+ end
303
+
304
+ it "shows current text_domain" do
305
+ FastGettext.text_domain = 'xxx'
306
+ NoTextDomainConfigured.new('xxx').to_s.should =~ /xxx/
307
+ end
308
+ end
309
+ end