r18n-core 0.3.2 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/ChangeLog +11 -0
  2. data/README.rdoc +225 -53
  3. data/lib/r18n-core/filters.rb +34 -34
  4. data/lib/r18n-core/i18n.rb +110 -46
  5. data/lib/r18n-core/locale.rb +109 -103
  6. data/lib/r18n-core/translated.rb +9 -4
  7. data/lib/r18n-core/translated_string.rb +10 -0
  8. data/lib/r18n-core/translation.rb +55 -99
  9. data/lib/r18n-core/unsupported_locale.rb +1 -13
  10. data/lib/r18n-core/untranslated.rb +18 -16
  11. data/lib/r18n-core/utils.rb +0 -12
  12. data/lib/r18n-core/version.rb +1 -1
  13. data/lib/r18n-core/yaml_loader.rb +67 -0
  14. data/lib/r18n-core.rb +25 -3
  15. data/locales/cs.rb +30 -16
  16. data/locales/de.rb +21 -0
  17. data/locales/en-us.rb +9 -4
  18. data/locales/en.rb +35 -20
  19. data/locales/eo.rb +20 -0
  20. data/locales/es.rb +20 -0
  21. data/locales/fr.rb +24 -9
  22. data/locales/it.rb +21 -9
  23. data/locales/kk.rb +26 -0
  24. data/locales/pl.rb +30 -18
  25. data/locales/pt-br.rb +24 -0
  26. data/locales/ru.rb +30 -12
  27. data/locales/zh.rb +19 -0
  28. data/spec/filters_spec.rb +24 -7
  29. data/spec/i18n_spec.rb +137 -50
  30. data/spec/locale_spec.rb +91 -53
  31. data/spec/locales/cs_spec.rb +9 -7
  32. data/spec/locales/pl_spec.rb +8 -9
  33. data/spec/locales/ru_spec.rb +9 -9
  34. data/spec/r18n_spec.rb +32 -13
  35. data/spec/spec_helper.rb +28 -4
  36. data/spec/translated_spec.rb +1 -1
  37. data/spec/translation_spec.rb +33 -67
  38. data/spec/translations/two/en.yml +0 -1
  39. data/spec/yaml_loader_spec.rb +33 -0
  40. metadata +11 -16
  41. data/locales/cs.yml +0 -26
  42. data/locales/de.yml +0 -26
  43. data/locales/en-us.yml +0 -10
  44. data/locales/en.yml +0 -26
  45. data/locales/eo.yml +0 -26
  46. data/locales/es.yml +0 -26
  47. data/locales/fr.yml +0 -26
  48. data/locales/it.yml +0 -26
  49. data/locales/kk.yml +0 -26
  50. data/locales/pl.yml +0 -26
  51. data/locales/pt-br.yml +0 -26
  52. data/locales/ru.yml +0 -26
  53. data/locales/zh.yml +0 -26
data/locales/it.rb CHANGED
@@ -1,14 +1,26 @@
1
1
  # encoding: utf-8
2
2
  module R18n
3
- module Locales
4
- class It < R18n::Locale
5
- def format_date_full(i18n, date, year = true)
6
- full = super(i18n, date, year)
7
- if ' 1' == full[0..1]
8
- "1º" + full[2..-1]
9
- else
10
- full
11
- end
3
+ class Locales::It < Locale
4
+ set :title => 'Italiano',
5
+
6
+ :wday_names => %w{domenica lunedì martedì mercoledì giovedì venerdì
7
+ sabato},
8
+ :wday_abbrs => %w{dom lun mar mer gio ven sab},
9
+
10
+ :month_names => %w{gennaio febbraio marzo aprile maggio giugno luglio},
11
+ :month_abbrs => %w{gen feb mar apr mag giu lug ago set ott nov dic},
12
+
13
+ :date_format => '%d/%m/%Y',
14
+
15
+ :number_decimal => ",",
16
+ :number_group => " "
17
+
18
+ def format_date_full(date, year = true, *params)
19
+ full = super(date, year)
20
+ if ' 1' == full[0..1]
21
+ "1º" + full[2..-1]
22
+ else
23
+ full
12
24
  end
13
25
  end
14
26
  end
data/locales/kk.rb ADDED
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+ module R18n
3
+ class Locales::Kk < Locale
4
+ set :title => 'Қазақша',
5
+ :sublocales => %w{ru en},
6
+
7
+ :wday_names => %w{Жексенбі Дүйсенбі Сейсенбі Сәрсенбі Бейсенбі Жұма
8
+ Сенбі},
9
+ :wday_abbrs => %w{Жк Дс Сс Ср Бс Жм Сн},
10
+
11
+ :month_names => %w{қаңтар ақпан наурыз сәуір мамыр маусым шілде тамыз
12
+ қырқүйек қазан қараша желтоқсан},
13
+ :month_abbrs => %w{қаң ақп нау сәу мам мау шіл там қыр қаз қар жел},
14
+ :month_standalone => %w{Қаңтар Ақпан Наурыз Сәуір Мамыр Маусым Шілде
15
+ Тамыз Қыркүйек Қазан Қараша Желтоқсан},
16
+
17
+ :time_am => ' ертеңің',
18
+ :time_pm => ' кештің',
19
+ :date_format => '%Y-%m-%d',
20
+ :full_format => '%B %e-і',
21
+ :year_format => '%Y жылы _',
22
+
23
+ :number_decimal => ",",
24
+ :number_group => " "
25
+ end
26
+ end
data/locales/pl.rb CHANGED
@@ -1,22 +1,34 @@
1
+ # encoding: utf-8
1
2
  module R18n
2
- module Locales
3
- class Pl < R18n::Locale
4
- def pluralize(n)
5
- return 0 if n == 0
6
- # 0 - 0
7
- # 1 - 1
8
- # 2..4 - 2
9
- # n
10
-
11
- case n % 10
12
- when 1
13
- n > 10 ? 'n' : 1
14
- when 2..4
15
- n % 100 > 10 && n % 100 < 20 ? 'n' : 2
16
- else
17
- 'n'
18
- end
3
+ class Locales::Pl < R18n::Locale
4
+ set :title => 'Polski',
5
+
6
+ :wday_names => %w{niedziela poniedziałek wtorek środa czwartek piątek
7
+ sobota},
8
+ :wday_abbrs => %w{nd pn wt śr czw pt sob},
9
+
10
+ :month_names => %w{stycznia lutego marca kwietnia maja czerwca lipca
11
+ sierpnia września pażdziernika listopada grudnia},
12
+ :month_abbrs => %w{I II III IV V VI VII VIII IX X XI XII},
13
+ :month_standalone => %w{styczeń luty marzec kwiecień maj czerwiec lipiec
14
+ sierpień wrzesień październik listopad
15
+ grudzień},
16
+
17
+ :date_format => '%d/%m/%Y',
18
+
19
+ :number_decimal => ",",
20
+ :number_group => " "
21
+
22
+ def pluralize(n)
23
+ return 0 if n == 0
24
+ case n % 10
25
+ when 1
26
+ n > 10 ? 'n' : 1
27
+ when 2..4
28
+ n % 100 > 10 && n % 100 < 20 ? 'n' : 2
29
+ else
30
+ 'n'
19
31
  end
20
32
  end
21
33
  end
22
- end
34
+ end
data/locales/pt-br.rb ADDED
@@ -0,0 +1,24 @@
1
+ # encoding: utf-8
2
+ module R18n
3
+ class Locales::PtBr < R18n::Locale
4
+ set :title => 'Português brasileiro',
5
+ :code => 'pt-BR',
6
+
7
+ :wday_names => %w{domingo segunda-feira terça-feira quarta-feira
8
+ quinta-feira sexta-feira sábado},
9
+ :wday_abbrs => %w{dom seg ter qua qui sex sab},
10
+
11
+ :month_names => %w{janeiro fevereiro março abril maio junho julho agosto
12
+ setembro outubro novembro dezembro},
13
+ :month_abbrs => %w{jan fev mar abr mai jun jul ago set out nov dez},
14
+ :month_standalone => %w{Janeiro Fevereiro Março Abril Maio Junho Julho
15
+ Agosto Setembro Outubro Novembro Dezembro},
16
+
17
+ :date_format => '%d/%m/%Y',
18
+ :full_format => '%d de %B',
19
+ :year_format => '_ de %Y',
20
+
21
+ :number_decimal => ",",
22
+ :number_group => "."
23
+ end
24
+ end
data/locales/ru.rb CHANGED
@@ -1,16 +1,34 @@
1
+ # encoding: utf-8
1
2
  module R18n
2
- module Locales
3
- class Ru < R18n::Locale
4
- def pluralize(n)
5
- if 0 == n
6
- 0
7
- elsif 1 == n % 10 and 11 != n % 100
8
- 1
9
- elsif 2 <= n % 10 and 4 >= n % 10 and (10 > n % 100 or 20 <= n % 100)
10
- 2
11
- else
12
- 'n'
13
- end
3
+ class Locales::Ru < Locale
4
+ set :title => 'Русский',
5
+
6
+ :wday_names => %w{Воскресенье Понедельник Вторник Среда Четверг Пятница
7
+ Суббота},
8
+ :wday_abbrs => %w{Вск Пнд Втр Срд Чтв Птн Сбт},
9
+
10
+ :month_names => %w{января февраля марта апреля мая июня июля августа
11
+ сентября октября ноября декабря},
12
+ :month_abbrs => %w{янв фев мар апр май июн июл авг сен окт ноя дек},
13
+ :month_standalone => %w{Январь Февраль Март Апрель Май Июнь Июль Август
14
+ Сентябрь Октябрь Ноябрь Декабрь},
15
+
16
+ :time_am => ' утра',
17
+ :time_pm => ' вечера',
18
+ :date_format => '%d.%m.%Y',
19
+
20
+ :number_decimal => ",",
21
+ :number_group => " "
22
+
23
+ def pluralize(n)
24
+ if 0 == n
25
+ 0
26
+ elsif 1 == n % 10 and 11 != n % 100
27
+ 1
28
+ elsif 2 <= n % 10 and 4 >= n % 10 and (10 > n % 100 or 20 <= n % 100)
29
+ 2
30
+ else
31
+ 'n'
14
32
  end
15
33
  end
16
34
  end
data/locales/zh.rb ADDED
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+ module R18n
3
+ class Locales::Zh < R18n::Locale
4
+ set :title => '中文',
5
+
6
+ :wday_names => %w{星期日 星期一 星期二 星期三 星期四 星期五 星期六},
7
+ :wday_abbrs => %w{周日 周一 周二 周三 周四 周五 周六},
8
+
9
+ :month_names => %w{一月 二月 三月 四月 五月 六月 七月 八月 九月 十月 十一月 十二月},
10
+ :month_abbrs => %w{一月 二月 三月 四月 五月 六月 七月 八月 九月 十月 十一月 十二月},
11
+
12
+ :date_format => '%Y年%m月%d日',
13
+ :full_format => '%m月%d日',
14
+ :year_format => '%Y年_',
15
+
16
+ :number_decimal => ".",
17
+ :number_group => " "
18
+ end
19
+ end
data/spec/filters_spec.rb CHANGED
@@ -88,21 +88,21 @@ describe R18n::Filters do
88
88
 
89
89
  it "should send config to filter" do
90
90
  R18n::Filters.add('my') do |i, config|
91
- config.secret_value = 1
91
+ config[:secret_value] = 1
92
92
  config
93
93
  end
94
- @i18n.my_filter.locale.should == @i18n.locale
95
- @i18n.my_filter.path.should == 'my_filter'
96
- @i18n.my_filter.secret_value.should == 1
97
- @i18n.my_filter.unknown_value.should be_nil
94
+ @i18n.my_filter[:locale].should == @i18n.locale
95
+ @i18n.my_filter[:path].should == 'my_filter'
96
+ @i18n.my_filter[:secret_value].should == 1
97
+ @i18n.my_filter[:unknown_value].should be_nil
98
98
  end
99
99
 
100
100
  it "should use one config for cascade filters" do
101
- R18n::Filters.add('my') { |content, config| config.new_secret ? 2 : 1 }
101
+ R18n::Filters.add('my') { |content, config| config[:new_secret] ? 2 : 1 }
102
102
  @i18n.my_filter.should == 1
103
103
 
104
104
  R18n::Filters.add('my', nil, 0) do |content, config|
105
- config.new_secret = true
105
+ config[:new_secret] = true
106
106
  content
107
107
  end
108
108
  @i18n.my_filter.should == 2
@@ -127,6 +127,11 @@ describe R18n::Filters do
127
127
  @i18n.files(-5.5).should == '−5.5 files'
128
128
  @i18n.files(5000).should == '5,000 files'
129
129
  end
130
+
131
+ it "shouldn't pluralize without first numeric parameter" do
132
+ @i18n.files.should == { 1 => '1 file', 'n' => '%1 files' }
133
+ @i18n.files('').should == { 1 => '1 file', 'n' => '%1 files' }
134
+ end
130
135
 
131
136
  it "should pluralize translation without locale" do
132
137
  i18n = R18n::I18n.new('no-LC', DIR)
@@ -150,6 +155,18 @@ describe R18n::Filters do
150
155
  @i18n.in.not.to_s.should == 'in.not in.[not]'
151
156
  end
152
157
 
158
+ it "should format translation path" do
159
+ @i18n.in.another.to_s.should == 'in.another[]'
160
+
161
+ R18n::Filters.off(:untranslated)
162
+ @i18n.in.another.to_s.should == 'in.another'
163
+
164
+ R18n::Filters.add(R18n::Untranslated) do |v, c, trans, untrans, path|
165
+ "#{path} #{trans}[#{untrans}]"
166
+ end
167
+ @i18n.in.another.to_s.should == 'in.another in.another[]'
168
+ end
169
+
153
170
  it "should have filter for escape HTML" do
154
171
  @i18n.html.should == '&lt;script&gt;true &amp;&amp; false&lt;/script&gt;'
155
172
  end
data/spec/i18n_spec.rb CHANGED
@@ -2,8 +2,15 @@
2
2
  require File.join(File.dirname(__FILE__), 'spec_helper')
3
3
 
4
4
  describe R18n::I18n do
5
+ before do
6
+ @extension_places = R18n.extension_places.clone
7
+ R18n.cache.clear
8
+ end
9
+
5
10
  after do
6
11
  R18n::I18n.default = 'en'
12
+ R18n.default_loader = R18n::Loader::YAML
13
+ R18n.extension_places = @extension_places
7
14
  end
8
15
 
9
16
  it "should parse HTTP_ACCEPT_LANGUAGE" do
@@ -26,20 +33,68 @@ describe R18n::I18n do
26
33
  i18n.locales.should == [R18n::Locale.load('ru'),
27
34
  R18n::UnsupportedLocale.new('no-LC'),
28
35
  R18n::UnsupportedLocale.new('no'),
29
- R18n::UnsupportedLocale.new('en')]
36
+ R18n::Locale.load('en')]
30
37
  end
31
38
 
32
- it "should return translations dir" do
39
+ it "should return translations loaders" do
33
40
  i18n = R18n::I18n.new('en', DIR)
34
- i18n.translation_dirs.expand_path.to_s.should == DIR.expand_path.to_s
41
+ i18n.translation_places.should == [R18n::Loader::YAML.new(DIR)]
42
+ end
43
+
44
+ it "should load translations by loader" do
45
+ loader = Class.new do
46
+ def available; [R18n::Locale.load('en')]; end
47
+ def load(locale); { 'custom' => 'Custom' }; end
48
+ end
49
+ R18n::I18n.new('en', loader.new).custom.should == 'Custom'
50
+ end
51
+
52
+ it "should pass parameters to default loader" do
53
+ loader = Class.new do
54
+ def initialize(param); @param = param; end
55
+ def available; [R18n::Locale.load('en')]; end
56
+ def load(locale); { 'custom' => @param }; end
57
+ end
58
+ R18n.default_loader = loader
59
+ R18n::I18n.new('en', 'default').custom.should == 'default'
35
60
  end
36
61
 
37
62
  it "should load translations" do
38
63
  i18n = R18n::I18n.new(['ru', 'en'], DIR)
39
64
  i18n.one.should == 'Один'
65
+ i18n[:one].should == 'Один'
40
66
  i18n['one'].should == 'Один'
41
67
  i18n.only.english.should == 'Only in English'
42
68
  end
69
+
70
+ it "should load translations from several dirs" do
71
+ i18n = R18n::I18n.new(['no-LC', 'en'], [TWO, DIR])
72
+ i18n.in.two.should == 'Two'
73
+ i18n.in.another.level.should == 'Hierarchical'
74
+ end
75
+
76
+ it "should use extension places" do
77
+ R18n.extension_places << EXT
78
+
79
+ i18n = R18n::I18n.new('en', DIR)
80
+ i18n.ext.should == 'Extension'
81
+ i18n.one.should == 'One'
82
+ end
83
+
84
+ it "shouldn't use extension without app translations with same locale" do
85
+ R18n.extension_places << EXT
86
+
87
+ i18n = R18n::I18n.new(['no-TR', 'en'], DIR)
88
+ i18n.ext.should == 'Extension'
89
+ end
90
+
91
+ it "should ignore case on loading" do
92
+ i18n = R18n::I18n.new('no-lc', [DIR])
93
+ i18n.one.should == 'ONE'
94
+
95
+ i18n = R18n::I18n.new('no-LC', [DIR])
96
+ i18n.one.should == 'ONE'
97
+ end
43
98
 
44
99
  it "should load default translation" do
45
100
  i18n = R18n::I18n.new('no-LC', DIR)
@@ -56,9 +111,86 @@ describe R18n::I18n do
56
111
  end
57
112
 
58
113
  it "should return available translations" do
114
+ R18n::I18n.available_locales(DIR).should =~ [R18n::Locale.load('no-lc'),
115
+ R18n::Locale.load('ru'),
116
+ R18n::Locale.load('en')]
59
117
  i18n = R18n::I18n.new('en', DIR)
60
- i18n.translations.should == { 'no-lc' => 'no-lc', 'ru' => 'Русский',
61
- 'en' => 'English' }
118
+ i18n.available_locales.should =~ [R18n::Locale.load('no-lc'),
119
+ R18n::Locale.load('ru'),
120
+ R18n::Locale.load('en')]
121
+ end
122
+
123
+ it "should cache translations" do
124
+ counter = CounterLoader.new('en')
125
+
126
+ R18n::I18n.new('en', counter)
127
+ counter.loaded.should == 1
128
+
129
+ R18n::I18n.new('en', counter)
130
+ counter.loaded.should == 1
131
+
132
+ R18n.cache.clear
133
+ R18n::I18n.new('en', counter)
134
+ counter.loaded.should == 2
135
+ end
136
+
137
+ it "should cache translations by used locales" do
138
+ counter = CounterLoader.new('en', 'ru')
139
+
140
+ R18n::I18n.new('en', counter)
141
+ counter.loaded.should == 1
142
+
143
+ R18n::I18n.new(['en', 'fr'], counter)
144
+ counter.loaded.should == 1
145
+
146
+ R18n::I18n.new(['en', 'ru'], counter)
147
+ counter.loaded.should == 3
148
+
149
+ R18n::I18n.new(['ru', 'en'], counter)
150
+ counter.loaded.should == 5
151
+ end
152
+
153
+ it "should cache translations by places" do
154
+ counter = CounterLoader.new('en', 'ru')
155
+
156
+ R18n::I18n.new('en', counter)
157
+ counter.loaded.should == 1
158
+
159
+ R18n::I18n.new('en', [counter, DIR])
160
+ counter.loaded.should == 2
161
+
162
+ R18n.extension_places << EXT
163
+ R18n::I18n.new('en', counter)
164
+ counter.loaded.should == 3
165
+
166
+ same = CounterLoader.new('en', 'ru')
167
+ R18n::I18n.new('en', same)
168
+ same.loaded.should == 0
169
+
170
+ different = CounterLoader.new('en', 'fr')
171
+ R18n::I18n.new('en', different)
172
+ different.loaded.should == 1
173
+ end
174
+
175
+ it "should reload translations" do
176
+ loader = Class.new do
177
+ @@answer = 1
178
+ def available; [R18n::Locale.load('en')]; end
179
+ def load(locale); { 'one' => @@answer }; end
180
+ end
181
+
182
+ i18n = R18n::I18n.new('en', loader.new)
183
+ i18n.one.should == 1
184
+
185
+ loader.class_eval { @@answer = 2 }
186
+ i18n.reload!
187
+ i18n.one.should == 2
188
+ end
189
+
190
+ it "should return translations" do
191
+ i18n = R18n::I18n.new('en', DIR)
192
+ i18n.t.should be_a(R18n::Translation)
193
+ i18n.t.one.should == 'One'
62
194
  end
63
195
 
64
196
  it "should return first locale with locale file" do
@@ -81,50 +213,5 @@ describe R18n::I18n do
81
213
 
82
214
  i18n.l(Date.new(0)).should == '01.01.0000'
83
215
  end
84
-
85
- it "should localize date for human" do
86
- i18n = R18n::I18n.new('ru')
87
-
88
- i18n.l(Date.today + 2, :human).should == 'через 2 дня'
89
- i18n.l(Date.today + 1, :human).should == 'завтра'
90
- i18n.l(Date.today, :human).should == 'сегодня'
91
- i18n.l(Date.today - 1, :human).should == 'вчера'
92
- i18n.l(Date.today - 3, :human).should == '3 дня назад'
93
-
94
- y2000 = Date.parse('2000-01-08')
95
- i18n.l(y2000, :human, Date.parse('2000-01-01')).should == ' 8 января'
96
- i18n.l(y2000, :human, Date.parse('1999-01-01')).should == ' 8 января 2000'
97
- end
98
-
99
- it "should localize times for human" do
100
- i18n = R18n::I18n.new('ru')
101
- minute = 60
102
- hour = 60 * minute
103
- day = 24 * hour
104
- zero = Time.at(0).utc
105
-
106
- i18n.l( zero + 7 * day, :human, zero).should == ' 8 января 00:00'
107
- i18n.l( zero + 50 * hour, :human, zero).should == 'через 2 дня 02:00'
108
- i18n.l( zero + 25 * hour, :human, zero).should == 'завтра 01:00'
109
- i18n.l( zero + 70 * minute, :human, zero).should == 'через 1 час'
110
- i18n.l( zero + 38 * minute, :human, zero).should == 'через 38 минут'
111
- i18n.l( zero + 5, :human, zero).should == 'сейчас'
112
- i18n.l( zero - 15, :human, zero).should == 'сейчас'
113
- i18n.l( zero - minute, :human, zero).should == '1 минуту назад'
114
- i18n.l( zero - 2 * hour, :human, zero).should == '2 часа назад'
115
- i18n.l( zero - 13 * hour, :human, zero).should == 'вчера 11:00'
116
- i18n.l( zero - 50 * hour, :human, zero).should == '3 дня назад 22:00'
117
- i18n.l( zero - 9 * day, :human, zero).should == '23 декабря 1969 00:00'
118
- end
119
-
120
- it "should use standard formatter by default" do
121
- R18n::I18n.new('ru').l(Time.at(0).utc).should == '01.01.1970 00:00'
122
- end
123
-
124
- it "should raise error on unknown formatter" do
125
- lambda {
126
- R18n::I18n.new('ru').l(Time.at(0).utc, :unknown)
127
- }.should raise_error(ArgumentError, /formatter/)
128
- end
129
216
 
130
217
  end