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,21 @@
1
+ current_folder = File.dirname(__FILE__)
2
+ require File.join(current_folder,'..','..','spec_helper')
3
+ require 'fast_gettext/translation_repository/base'
4
+
5
+ describe 'FastGettext::TranslationRepository::Base' do
6
+ before do
7
+ @rep = FastGettext::TranslationRepository::Base.new('x')
8
+ end
9
+
10
+ it "can be built" do
11
+ @rep.available_locales.should == []
12
+ end
13
+
14
+ it "cannot translate" do
15
+ @rep['car'].should == nil
16
+ end
17
+
18
+ it "cannot pluralize" do
19
+ @rep.plural('Axis','Axis').should == ['Axis','Axis']
20
+ end
21
+ end
@@ -0,0 +1,82 @@
1
+ current_folder = File.dirname(__FILE__)
2
+ require File.join(current_folder,'..','..','spec_helper')
3
+
4
+ class MockRepo
5
+ def [](key)#should_receive :[] does not work so well...
6
+ singular key
7
+ end
8
+ end
9
+
10
+ describe 'FastGettext::TranslationRepository::Chain' do
11
+ describe "empty chain" do
12
+ before do
13
+ @rep = FastGettext::TranslationRepository.build('chain', :chain=>[], :type=>:chain)
14
+ end
15
+
16
+ it "has no locales" do
17
+ @rep.available_locales.should == []
18
+ end
19
+
20
+ it "cannot translate" do
21
+ @rep['car'].should == nil
22
+ end
23
+
24
+ it "cannot pluralize" do
25
+ @rep.plural('Axis','Axis').should == []
26
+ end
27
+
28
+ it "has no pluralisation rule" do
29
+ @rep.pluralisation_rule.should == nil
30
+ end
31
+ end
32
+
33
+ describe "filled chain" do
34
+ before do
35
+ @one = MockRepo.new
36
+ @one.stub!(:singular).with('xx').and_return 'one'
37
+ @two = MockRepo.new
38
+ @two.stub!(:singular).with('xx').and_return 'two'
39
+ @rep = FastGettext::TranslationRepository.build('chain', :chain=>[@one, @two], :type=>:chain)
40
+ end
41
+
42
+ describe :singular do
43
+ it "uses the first repo in the chain if it responds" do
44
+ @rep['xx'].should == 'one'
45
+ end
46
+
47
+ it "uses the second repo in the chain if the first does not respond" do
48
+ @one.should_receive(:singular).and_return nil
49
+ @rep['xx'].should == 'two'
50
+ end
51
+ end
52
+
53
+ describe :plural do
54
+ it "uses the first repo in the chain if it responds" do
55
+ @one.should_receive(:plural).with('a','b').and_return ['A','B']
56
+ @rep.plural('a','b').should == ['A','B']
57
+ end
58
+
59
+ it "uses the second repo in the chain if the first does not respond" do
60
+ @one.should_receive(:plural).with('a','b').and_return [nil,nil]
61
+ @two.should_receive(:plural).with('a','b').and_return ['A','B']
62
+ @rep.plural('a','b').should == ['A','B']
63
+ end
64
+ end
65
+
66
+ describe :available_locales do
67
+ it "should be the sum of all added repositories" do
68
+ @one.should_receive(:available_locales).and_return ['de']
69
+ @two.should_receive(:available_locales).and_return ['de','en']
70
+ @rep.available_locales.should == ['de','en']
71
+ end
72
+ end
73
+
74
+ describe :pluralisation_rule do
75
+ it "chooses the first that exists" do
76
+ @one.should_receive(:pluralisation_rule).and_return nil
77
+ @two.should_receive(:pluralisation_rule).and_return 'x'
78
+ @rep.pluralisation_rule.should == 'x'
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,71 @@
1
+ current_folder = File.dirname(__FILE__)
2
+ require File.join(current_folder,'..','..','spec_helper')
3
+
4
+ require 'activerecord'
5
+ require 'fast_gettext/translation_repository/db'
6
+ include FastGettext::TranslationRepository::Db.require_models
7
+
8
+ describe FastGettext::TranslationRepository::Db do
9
+ before :all do
10
+ ActiveRecord::Base.establish_connection({
11
+ :adapter => "sqlite3",
12
+ :database => ":memory:"
13
+ })
14
+
15
+ #create model table
16
+ #TODO surpress output ?
17
+ ActiveRecord::Schema.define(:version => 1) do
18
+ create_table :translation_keys do |t|
19
+ t.string :key, :unique=>true, :null=>false
20
+ t.timestamps
21
+ end
22
+ create_table :translation_texts do |t|
23
+ t.string :text, :locale
24
+ t.integer :translation_key_id, :null=>false
25
+ t.timestamps
26
+ end
27
+ end
28
+ end
29
+
30
+ before do
31
+ TranslationKey.delete_all
32
+ TranslationText.delete_all
33
+ FastGettext.locale = 'de'
34
+ @rep = FastGettext::TranslationRepository::Db.new('x', :model=>TranslationKey)
35
+ end
36
+
37
+ def create_translation(key, text)
38
+ translation_key = TranslationKey.create!(:key=>key)
39
+ TranslationText.create!(:translation_key_id=>translation_key.id, :text=>text, :locale=>'de')
40
+ end
41
+
42
+ it "reads locales from the db" do
43
+ locales = ['de','en','es']
44
+ locales.reverse.each do |locale|
45
+ TranslationText.create!(:translation_key_id=>1, :text=>'asdasd', :locale=>locale)
46
+ end
47
+ @rep.available_locales.should == locales
48
+ end
49
+
50
+ it "has no pluralisation_rule by default" do
51
+ @rep.pluralisation_rule.should == nil
52
+ end
53
+
54
+ it "cannot translate when no models are present" do
55
+ @rep['car'].should == nil
56
+ end
57
+
58
+ it "can translate" do
59
+ create_translation 'car', 'Auto'
60
+ @rep['car'].should == 'Auto'
61
+ end
62
+
63
+ it "cannot pluralize when no model is present" do
64
+ @rep.plural('Axis','Axis').should == []
65
+ end
66
+
67
+ it "can pluralize" do
68
+ create_translation 'Axis||||Axis', 'Achse||||Achsen'
69
+ @rep.plural('Axis','Axis').should == ['Achse','Achsen']
70
+ end
71
+ end
@@ -0,0 +1,41 @@
1
+ current_folder = File.dirname(__FILE__)
2
+ require File.join(current_folder,'..','..','spec_helper')
3
+
4
+ describe 'FastGettext::TranslationRepository::Logger' do
5
+ before do
6
+ @callback = lambda{}
7
+ @rep = FastGettext::TranslationRepository.build('test', :type=>:logger, :callback=>@callback)
8
+ @rep.is_a?(FastGettext::TranslationRepository::Logger).should be_true
9
+ end
10
+ subject{@rep}
11
+
12
+ it{ should have(0).available_locales}
13
+
14
+ it "has no pluralisation_rule" do
15
+ @rep.pluralisation_rule.should == nil
16
+ end
17
+
18
+ describe :single do
19
+ it "logs every call" do
20
+ @callback.should_receive(:call).with('the_key')
21
+ @rep['the_key']
22
+ end
23
+
24
+ it "returns nil" do
25
+ @callback.should_receive(:call).with('the_key').and_return 'something'
26
+ @rep['the_key'].should == nil
27
+ end
28
+ end
29
+
30
+ describe :plural do
31
+ it "logs every call" do
32
+ @callback.should_receive(:call).with(['a','b'])
33
+ @rep.plural('a','b')
34
+ end
35
+
36
+ it "returns an empty array" do
37
+ @callback.should_receive(:call).with(['a','b']).and_return 'something'
38
+ @rep.plural('a','b').should == []
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,31 @@
1
+ current_folder = File.dirname(__FILE__)
2
+ require File.join(current_folder,'..','..','spec_helper')
3
+
4
+
5
+ describe 'FastGettext::TranslationRepository::Mo' do
6
+ before do
7
+ @rep = FastGettext::TranslationRepository.build('test',:path=>File.join(current_folder,'..','..','locale'))
8
+ @rep.is_a?(FastGettext::TranslationRepository::Mo).should be_true
9
+ end
10
+
11
+ it "can be built" do
12
+ @rep.available_locales.should == ['de','en']
13
+ end
14
+
15
+ it "can translate" do
16
+ FastGettext.locale = 'de'
17
+ @rep['car'].should == 'Auto'
18
+ end
19
+
20
+ it "can pluralize" do
21
+ FastGettext.locale = 'de'
22
+ @rep.plural('Axis','Axis').should == ['Achse','Achsen']
23
+ end
24
+
25
+ it "has access to the mo repositories pluralisation rule" do
26
+ FastGettext.locale = 'en'
27
+ rep = FastGettext::TranslationRepository.build('plural_test',:path=>File.join(current_folder,'..','..','locale'))
28
+ rep['car'].should == 'Test'#just check it is loaded correctly
29
+ rep.pluralisation_rule.call(2).should == 3
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ current_folder = File.dirname(__FILE__)
2
+ require File.join(current_folder,'..','..','spec_helper')
3
+
4
+
5
+ describe 'FastGettext::TranslationRepository::Po' do
6
+ before do
7
+ @rep = FastGettext::TranslationRepository.build('test',:path=>File.join(current_folder,'..','..','locale'),:type=>:po)
8
+ @rep.is_a?(FastGettext::TranslationRepository::Po).should be_true
9
+ end
10
+
11
+ it "can be built" do
12
+ @rep.available_locales.should == ['de','en']
13
+ end
14
+
15
+ it "can translate" do
16
+ FastGettext.locale = 'de'
17
+ @rep['car'].should == 'Auto'
18
+ end
19
+
20
+ it "can pluralize" do
21
+ FastGettext.locale = 'de'
22
+ @rep.plural('Axis','Axis').should == ['Achse','Achsen']
23
+ end
24
+
25
+ it "has access to the mo repositories pluralisation rule" do
26
+ FastGettext.locale = 'en'
27
+ rep = FastGettext::TranslationRepository.build('plural_test',:path=>File.join(current_folder,'..','..','locale'),:type=>:po)
28
+ rep['car'].should == 'Test'#just check it is loaded correctly
29
+ rep.pluralisation_rule.call(2).should == 3
30
+ end
31
+ end
@@ -0,0 +1,152 @@
1
+ current_folder = File.dirname(__FILE__)
2
+ require File.join(current_folder,'..','spec_helper')
3
+
4
+ include FastGettext::Translation
5
+
6
+ describe FastGettext::Translation do
7
+ before do
8
+ default_setup
9
+ end
10
+
11
+ describe "unknown locale" do
12
+ before do
13
+ FastGettext.available_locales = nil
14
+ FastGettext.locale = 'xx'
15
+ end
16
+
17
+ it "does not translate" do
18
+ _('car').should == 'car'
19
+ end
20
+
21
+ it "does not translate plurals" do
22
+ n_('car','cars',2).should == 'cars'
23
+ end
24
+ end
25
+
26
+ describe :_ do
27
+ it "translates simple text" do
28
+ _('car').should == 'Auto'
29
+ end
30
+
31
+ it "returns key if not translation was found" do
32
+ _('NOT|FOUND').should == 'NOT|FOUND'
33
+ end
34
+
35
+ it "does not return the gettext meta information" do
36
+ _('').should == ''
37
+ end
38
+ end
39
+
40
+ describe :n_ do
41
+ before do
42
+ FastGettext.pluralisation_rule = nil
43
+ end
44
+
45
+ it "translates pluralized" do
46
+ n_('Axis','Axis',1).should == 'Achse'
47
+ n_('Axis','Axis',2).should == 'Achsen'
48
+ n_('Axis','Axis',0).should == 'Achsen'
49
+ end
50
+
51
+ describe "pluralisations rules" do
52
+ it "supports abstract pluralisation rules" do
53
+ FastGettext.pluralisation_rule = lambda{|n|2}
54
+ n_('a','b','c','d',4).should == 'c'
55
+ end
56
+
57
+ it "supports false as singular" do
58
+ FastGettext.pluralisation_rule = lambda{|n|n!=2}
59
+ n_('singular','plural','c','d',2).should == 'singular'
60
+ end
61
+
62
+ it "supports true as plural" do
63
+ FastGettext.pluralisation_rule = lambda{|n|n==2}
64
+ n_('singular','plural','c','d',2).should == 'plural'
65
+ end
66
+ end
67
+
68
+ it "returns the appropriate key if no translation was found" do
69
+ n_('NOTFOUND','NOTFOUNDs',1).should == 'NOTFOUND'
70
+ n_('NOTFOUND','NOTFOUNDs',2).should == 'NOTFOUNDs'
71
+ end
72
+
73
+ it "returns the last key when no translation was found and keys where to short" do
74
+ FastGettext.pluralisation_rule = lambda{|x|4}
75
+ n_('Apple','Apples',2).should == 'Apples'
76
+ end
77
+ end
78
+
79
+ describe :s_ do
80
+ it "translates simple text" do
81
+ s_('car').should == 'Auto'
82
+ end
83
+
84
+ it "returns cleaned key if a translation was not found" do
85
+ s_("XXX|not found").should == "not found"
86
+ end
87
+
88
+ it "can use a custom seperator" do
89
+ s_("XXX/not found",'/').should == "not found"
90
+ end
91
+ end
92
+
93
+ describe :N_ do
94
+ it "returns the key" do
95
+ N_('XXXXX').should == 'XXXXX'
96
+ end
97
+ end
98
+
99
+ describe :Nn_ do
100
+ it "returns the keys as array" do
101
+ Nn_('X','Y').should == ['X','Y']
102
+ end
103
+ end
104
+
105
+ describe :caching do
106
+ describe :cache_hit do
107
+ before do
108
+ FastGettext.translation_repositories.replace({})
109
+ #singular cache keys
110
+ current_cache['xxx'] = '1'
111
+
112
+ #plural cache keys
113
+ current_cache['||||xxx'] = ['1','2']
114
+ current_cache['||||xxx||||yyy'] = ['1','2']
115
+ end
116
+
117
+ it "uses the cache when translating with _" do
118
+ _('xxx').should == '1'
119
+ end
120
+
121
+ it "uses the cache when translating with s_" do
122
+ s_('xxx').should == '1'
123
+ end
124
+
125
+ it "uses the cache when translating with n_" do
126
+ n_('xxx','yyy',1).should == '1'
127
+ end
128
+
129
+ it "uses the cache when translating with n_ and single argument" do
130
+ n_('xxx',1).should == '1'
131
+ end
132
+ end
133
+
134
+ it "caches different locales seperatly" do
135
+ FastGettext.locale = 'en'
136
+ _('car').should == 'car'
137
+ FastGettext.locale = 'de'
138
+ _('car').should == 'Auto'
139
+ end
140
+
141
+ it "caches different textdomains seperatly" do
142
+ _('car').should == 'Auto'
143
+
144
+ FastGettext.translation_repositories['fake'] = {}
145
+ FastGettext.text_domain = 'fake'
146
+ _('car').should == 'car'
147
+
148
+ FastGettext.text_domain = 'test'
149
+ _('car').should == 'Auto'
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,44 @@
1
+ require File.expand_path("spec_helper", File.dirname(__FILE__))
2
+
3
+ default_setup
4
+ class IncludeTest
5
+ include FastGettext::Translation
6
+ @@xx = _('car')
7
+ def self.ext
8
+ _('car')
9
+ end
10
+ def inc
11
+ _('car')
12
+ end
13
+ def self.xx
14
+ @@xx
15
+ end
16
+ end
17
+
18
+ include FastGettext
19
+
20
+ describe FastGettext do
21
+ before :all do
22
+ default_setup
23
+ end
24
+
25
+ it "provides access to FastGettext::Translations methods" do
26
+ FastGettext._('car').should == 'Auto'
27
+ _('car').should == 'Auto'
28
+ s_("XXX|not found").should == "not found"
29
+ n_('Axis','Axis',1).should == 'Achse'
30
+ N_('XXXXX').should == 'XXXXX'
31
+ Nn_('X','Y').should == ['X','Y']
32
+ end
33
+
34
+ it "is extended to a class and included into a class" do
35
+ IncludeTest.ext.should == 'Auto'
36
+ IncludeTest.ext.should == 'Auto'
37
+ IncludeTest.new.inc.should == 'Auto'
38
+ IncludeTest.xx.should == 'Auto'
39
+ end
40
+
41
+ it "has a VERSION" do
42
+ FastGettext::VERSION.should =~ /^\d+\.\d+\.\d+$/
43
+ end
44
+ end