fast_gettext 0.4.16
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/CHANGELOG +6 -0
- data/README.markdown +181 -0
- data/Rakefile +42 -0
- data/VERSION +1 -0
- data/benchmark/base.rb +42 -0
- data/benchmark/baseline.rb +5 -0
- data/benchmark/fast_gettext.rb +18 -0
- data/benchmark/i18n_simple.rb +7 -0
- data/benchmark/ideal.rb +22 -0
- data/benchmark/locale/de.yml +127 -0
- data/benchmark/locale/de/LC_MESSAGES/large.mo +0 -0
- data/benchmark/misc/threadsave.rb +21 -0
- data/benchmark/namespace/fast_gettext.rb +15 -0
- data/benchmark/namespace/original.rb +14 -0
- data/benchmark/original.rb +15 -0
- data/examples/db/migration.rb +22 -0
- data/examples/missing_translation_logger.rb +13 -0
- data/fast_gettext.gemspec +114 -0
- data/lib/fast_gettext.rb +30 -0
- data/lib/fast_gettext/mo_file.rb +67 -0
- data/lib/fast_gettext/po_file.rb +14 -0
- data/lib/fast_gettext/storage.rb +188 -0
- data/lib/fast_gettext/translation.rb +53 -0
- data/lib/fast_gettext/translation_repository.rb +15 -0
- data/lib/fast_gettext/translation_repository/base.rb +49 -0
- data/lib/fast_gettext/translation_repository/chain.rb +43 -0
- data/lib/fast_gettext/translation_repository/db.rb +57 -0
- data/lib/fast_gettext/translation_repository/db_models/translation_key.rb +26 -0
- data/lib/fast_gettext/translation_repository/db_models/translation_text.rb +9 -0
- data/lib/fast_gettext/translation_repository/logger.rb +27 -0
- data/lib/fast_gettext/translation_repository/mo.rb +35 -0
- data/lib/fast_gettext/translation_repository/po.rb +18 -0
- data/spec/aa_unconfigued_spec.rb +21 -0
- data/spec/fast_gettext/mo_file_spec.rb +36 -0
- data/spec/fast_gettext/storage_spec.rb +309 -0
- data/spec/fast_gettext/translation_repository/base_spec.rb +21 -0
- data/spec/fast_gettext/translation_repository/chain_spec.rb +82 -0
- data/spec/fast_gettext/translation_repository/db_spec.rb +71 -0
- data/spec/fast_gettext/translation_repository/logger_spec.rb +41 -0
- data/spec/fast_gettext/translation_repository/mo_spec.rb +31 -0
- data/spec/fast_gettext/translation_repository/po_spec.rb +31 -0
- data/spec/fast_gettext/translation_spec.rb +152 -0
- data/spec/fast_gettext_spec.rb +44 -0
- data/spec/locale/de/LC_MESSAGES/test.mo +0 -0
- data/spec/locale/de/test.po +61 -0
- data/spec/locale/en/LC_MESSAGES/plural_test.mo +0 -0
- data/spec/locale/en/LC_MESSAGES/test.mo +0 -0
- data/spec/locale/en/plural_test.po +20 -0
- data/spec/locale/en/test.po +59 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/vendor/fake_load_path/iconv.rb +2 -0
- data/spec/vendor/iconv_spec.rb +27 -0
- data/spec/vendor/string_spec.rb +67 -0
- data/vendor/README.rdoc +236 -0
- data/vendor/empty.mo +0 -0
- data/vendor/iconv.rb +107 -0
- data/vendor/mofile.rb +296 -0
- data/vendor/poparser.rb +331 -0
- data/vendor/string.rb +58 -0
- 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
|