fast_gettext 0.4.16

Sign up to get free protection for your applications and to get access to all the features.
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