roda-i18n 0.1.0

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.
@@ -0,0 +1,14 @@
1
+ hello: "Hallo aus app/i18n/de.yml"
2
+
3
+ do:
4
+ you:
5
+ speak:
6
+ german: "Sprechen Sie Deutsch?"
7
+
8
+
9
+ user:
10
+ edit: Benutzer bearbeiten
11
+ name: Benutzername ist %1
12
+ count: !!pl
13
+ 1: Ist 1 Benutzer
14
+ n: Es gibt %1 Benutzer
@@ -0,0 +1,14 @@
1
+ hello: "Hello from ./app/i18n/en.yml"
2
+
3
+ do:
4
+ you:
5
+ speak:
6
+ english: Do you speak English?
7
+
8
+ user:
9
+ edit: Edit user
10
+ name: User name is %1
11
+ count: !!pl
12
+ 1: There is 1 user
13
+ n: There are %1 users
14
+
@@ -0,0 +1,8 @@
1
+ hello: "Hola de app/i18n/es.yml"
2
+
3
+ one: 'Uno'
4
+ two: 'Dos'
5
+ do:
6
+ you:
7
+ speak:
8
+ spanish: "¿Hablas español?"
@@ -0,0 +1,34 @@
1
+ hello: "Hallo aus i18n/de.yml"
2
+
3
+ one: Ein
4
+ two: Zwei
5
+
6
+ params: "Ist %1 zwischen %1 und %2?"
7
+
8
+ in:
9
+ another: Hierarchisch
10
+
11
+ # only:
12
+ # english: "Nein, nicht auf Englisch"
13
+
14
+ # sum: !!proc |x, y| x + y
15
+
16
+ post:
17
+ title: "Blog-beitrag: '%1'"
18
+ comments: !!pl
19
+ 0: "noch keine kommentare zu '%2'"
20
+ 1: "einen kommentar '%2'"
21
+ n: "%1 kommentare zum '%2'"
22
+
23
+ greater: 1 < 2 ist wahr
24
+
25
+ warning: !!html <b>Warnung</b>
26
+
27
+
28
+
29
+ files: !!pl
30
+ 1: 1 datei
31
+ n: "%1 dateien"
32
+
33
+ my_type: !!special_type
34
+ attr: value
@@ -0,0 +1,68 @@
1
+ hello: "Hello from ./i18n/en.yml"
2
+
3
+ one: One
4
+ two: Two
5
+
6
+ params: Is %1 between %1 and %2?
7
+
8
+ in:
9
+ another: Hierarchical
10
+
11
+ only:
12
+ english: Only in English
13
+
14
+ robots: !!pl
15
+ 0: No robots
16
+ 1: One robot
17
+ n: "%1 robots"
18
+
19
+ # sum: !!proc |x, y| x + y
20
+
21
+ post:
22
+ title: "Blog post: '%1'"
23
+ comments: !!pl
24
+ 0: "no comments for '%2'"
25
+ 1: "one comment for '%2'"
26
+ n: "%1 comments for '%2'"
27
+
28
+ greater: 1 < 2 is true
29
+
30
+ warning: !!html <b>It works!</b>
31
+
32
+ files: !!pl
33
+ 1: 1 file
34
+ n: "%1 files"
35
+
36
+ my_type: !!special_type
37
+ attr: value
38
+
39
+
40
+ as:
41
+ html: !!html
42
+ <h1>Embedded HTML!</h>
43
+ <p>It just works!</p>
44
+
45
+ md: !!markdown
46
+ Hello **Markdown**!
47
+
48
+
49
+
50
+ _html: !!html
51
+ <h1>Embedded HTML!</h>
52
+ <p>It just works!</p>
53
+
54
+ md: !!markdown
55
+ Hello **Markdown**!
56
+
57
+
58
+ example: >
59
+ HTML goes into YAML without modification
60
+ message: |
61
+
62
+ <blockquote style="font: italic 12pt Times">
63
+ <p>"Three is always greater than two,
64
+ even for large values of two"</p>
65
+ <p>--Author Unknown</p>
66
+ </blockquote>
67
+
68
+ date: 2007-06-01
@@ -0,0 +1,53 @@
1
+ hello: "Hej från ./i18n/sv-se.yml"
2
+
3
+ one: Ett
4
+ two: Två
5
+
6
+ do:
7
+ you:
8
+ speak:
9
+ swedish: "Pratar du svenska?"
10
+
11
+
12
+ user:
13
+ # edit: Edit user
14
+ # name: User name is %1
15
+ count: !!pl
16
+ 1: Det finns en användare
17
+ n: Det finns %1 användare
18
+
19
+
20
+ params: Är %1 mellan %1 och %2?
21
+
22
+ in:
23
+ another: Hierarkisk
24
+
25
+ # only:
26
+ # english: "Nej, inte på engelska"
27
+
28
+
29
+ robots: !!pl
30
+ 0: Inga robotar
31
+ 1: En robot
32
+ n: "%1 robotar"
33
+
34
+
35
+ svenska: "Denna finns bara i svenska översättningarna"
36
+
37
+ post:
38
+ title: "Blogginlägg: '%1'"
39
+ comments: !!pl
40
+ 0: "ingen kommentar för '%2'"
41
+ 1: "en kommentar för '%2'"
42
+ n: "%1 kommentarer för '%2'"
43
+
44
+ greater: 1 < 2 är sant
45
+
46
+ warning: !!html <b>Warning</b>
47
+
48
+ files: !!pl
49
+ 1: 1 fil
50
+ n: "%1 filer"
51
+
52
+ my_type: !!special_type
53
+ attr: value
@@ -0,0 +1,13 @@
1
+ require 'coverage'
2
+ require 'simplecov'
3
+
4
+ def SimpleCov.roda_i18n_coverage(opts = {})
5
+ start do
6
+ add_filter "/spec/"
7
+ add_group('Missing'){|src| src.covered_percent < 100}
8
+ add_group('Covered'){|src| src.covered_percent == 100}
9
+ yield self if block_given?
10
+ end
11
+ end
12
+
13
+ ENV.delete('COVERAGE')
@@ -0,0 +1,413 @@
1
+ require_relative 'spec_helper'
2
+
3
+ describe "i18n - plugin configuration - basic " do
4
+
5
+ before do
6
+ app(:bare) do
7
+ # setting app[:root] to fixtures directory
8
+ opts[:root] = File.expand_path('../fixtures', __FILE__)
9
+ plugin :i18n
10
+ route do |r|
11
+ r.is('default/locale') { erb("<%= ::R18n::I18n.default %>") }
12
+ r.is('i18n/available/locales') { i18n_available_locales }
13
+ r.is('i18n/default/places') { erb '<%= i18n_default_places %>' }
14
+ r.is('t/one') { erb("<%= t.one %>") }
15
+ end
16
+ end
17
+ end
18
+
19
+ it "should return the correct default locale 'en' " do
20
+ rt('/default/locale').must_equal "en"
21
+ end
22
+
23
+ it "should return the correct path to the i18n locales directory" do
24
+ rt('/i18n/default/places').must_equal "#{File.expand_path('../fixtures/i18n', __FILE__)}"
25
+ end
26
+
27
+ it "should return the correct translation of 't.one' from the default locale (EN)" do
28
+ get '/t/one'
29
+ _body.must_equal "One"
30
+ end
31
+
32
+ end
33
+
34
+ describe "i18n - plugin configuration - with ':locale => :de' " do
35
+
36
+ before do
37
+ app(:bare) do
38
+ # setting app[:root] to fixtures directory
39
+ opts[:root] = File.expand_path('../fixtures', __FILE__)
40
+ plugin :i18n, :locale => [:de] #, :translations => "#{File.dirname(__FILE__)}/../spec/**/i18n"
41
+ route do |r|
42
+ r.is('default/locale') { erb("<%= ::R18n::I18n.default %>") }
43
+ r.is('i18n/available/locales') { i18n_available_locales }
44
+ r.is('i18n/default/places') { erb '<%= i18n_default_places %>' }
45
+ r.is('t/one') { erb("<%= t.one %>") }
46
+ end
47
+ end
48
+ end
49
+
50
+ it "should return the correct default locale 'de' " do
51
+ rt('/default/locale').must_equal "de"
52
+ end
53
+
54
+ it "should return the correct path to the i18n locales directory" do
55
+ rt('/i18n/default/places').must_equal "#{File.expand_path('../fixtures/i18n', __FILE__)}"
56
+ end
57
+
58
+ it "should return the correct translation of 't.one' from the default locale (DE)" do
59
+ get '/t/one'
60
+ _body.must_equal "Ein"
61
+ end
62
+
63
+ end
64
+
65
+
66
+ describe 'i18n - Translations & Localisations' do
67
+
68
+ before do
69
+ app(:bare) do
70
+ plugin :i18n, :locale => 'de', :translations => "#{File.dirname(__FILE__)}/../spec/**/i18n"
71
+ route do |r|
72
+ r.is('l/date') { erb '<%= l Date.parse("October 5, 2011") %>' }
73
+ r.is('l/full') { erb '<%= l Date.parse("October 5, 2011"), :full %>' }
74
+
75
+ r.is('t/hello') { erb("<%= t.hello %>") }
76
+
77
+ r.is('t/two') { erb("<%= t.two %>") }
78
+
79
+ r.is('t/only/in/english') { erb '<%= t.only.english %>' }
80
+
81
+ r.is('t/do/you/speak/german') { erb '<%= t.do.you.speak.german %>' }
82
+ r.is('t/do/you/speak/spanish') { erb '<%= t.do.you.speak.spanish %>' }
83
+ r.is('t/do/you/speak/swedish') { erb '<%= t.do.you.speak.swedish %>' }
84
+ r.is('t/do/you/speak/english') { erb '<%= t.do.you.speak.english %>' }
85
+
86
+ r.is('t/user/count/:num') { |num| erb '<%= t.user.count(n) %>', :locals => { :n => num.to_i } }
87
+ r.is('t/user/name/:name') { |name| erb '<%= t.user.name(n) %>', :locals => { :n => name } }
88
+
89
+ r.is('t/as/markdown') { erb '<%= t.as.md %>' }
90
+ r.is('t/as/html') { erb '<%= t.as.html %>' }
91
+ end
92
+ end
93
+ end
94
+
95
+ # LOCALISATION
96
+ it "should correctly translate 'l date'" do
97
+ rt('/l/date').must_equal '05.10.2011'
98
+ end
99
+
100
+ it "should correctly translate 'l date, :full'" do
101
+ rt('/l/full').must_equal ' 5. Oktober 2011'
102
+ end
103
+
104
+ # TRANSLATION
105
+
106
+ it "should correctly load translations from multiple source directories 't.hello'" do
107
+ rt('/t/hello').must_equal "Hallo aus i18n/de.yml" # loaded from the highest level
108
+ end
109
+
110
+ it "should correctly translate 't.two'" do
111
+ rt('/t/two').must_equal 'Zwei'
112
+ end
113
+
114
+ it "should return the default EN translations of 't.only.english' " do
115
+ rt('/t/only/in/english').must_equal "Only in English"
116
+ end
117
+
118
+ it "should correctly translate 't.user.count' " do
119
+ rt('/t/user/count/1').must_equal "Ist 1 Benutzer"
120
+ rt('/t/user/count/8').must_equal "Es gibt 8 Benutzer"
121
+ end
122
+
123
+ it "should correctly translate 't.user.name' " do
124
+ rt('/t/user/name/James').must_equal "Benutzername ist James"
125
+ end
126
+
127
+ it "should return Markdown formatted translations 't.as.md'" do
128
+ rt('/t/as/markdown').must_equal "<p>Hello <strong>Markdown</strong>!</p>\n"
129
+ end
130
+
131
+ it "should correctly translate 't.as.html' " do
132
+ rt('/t/as/html').must_equal "<h1>Embedded HTML!</h> <p>It just works!</p>"
133
+ end
134
+
135
+ it "should return an error for a missing translation 't.do.you.speak.swedish' " do
136
+ rt('/t/do/you/speak/swedish').must_equal "do.you.speak.<span style=\"color: red\">[swedish]</span>"
137
+ end
138
+
139
+ end
140
+
141
+ describe 'i18n - #locale() - set locale based upon route prefix' do
142
+
143
+ before do
144
+ app(:bare) do
145
+ plugin :i18n, :locale => ['en'], :translations => "#{File.dirname(__FILE__)}/../spec/**/i18n"
146
+ route do |r|
147
+ r.locale do
148
+ r.is('t/one') { erb("<%= t.one %>") }
149
+ r.is('l/date') { erb '<%= l Date.parse("October 5, 2011") %>' }
150
+ end
151
+ end
152
+ end
153
+ end
154
+
155
+ describe "#locale defined translations" do
156
+
157
+ it "should return the correct translation of 't.one' for locale ES (Spanish)" do
158
+ rt('/es/t/one').must_equal 'Uno'
159
+ end
160
+
161
+ it "should return the correct translation of 't.one' for locale SV-SE (Swedish)" do
162
+ rt('/sv-se/t/one').must_equal 'Ett'
163
+ end
164
+
165
+ it "should return the correct default translation of 't.one' for missing :locales" do
166
+ rt('/my/t/one').must_equal 'One'
167
+ end
168
+
169
+ end
170
+
171
+ describe '#locale based localisations' do
172
+
173
+ it "should correctly translate 'l date' for locale ES (Spanish)" do
174
+ rt('/es/l/date').must_equal '05/10/2011'
175
+ end
176
+
177
+ it "should correctly translate 'l date' for locale DE (German)" do
178
+ rt('/de/l/date').must_equal '05.10.2011'
179
+ end
180
+
181
+ end
182
+
183
+ end
184
+
185
+
186
+ describe 'i18n - #i18n_set_locale_from(:session) - obtaining locale from sessions' do
187
+
188
+ before do
189
+ app(:bare) do
190
+ plugin :i18n, :locale => ['es'], :translations => "#{File.dirname(__FILE__)}/../spec/**/i18n"
191
+ route do |r|
192
+ r.i18n_set_locale_from(:session)
193
+ r.is('t/one') { erb("<%= t.one %>") }
194
+ r.is('t/only/in/english') { erb '<%= t.only.english %>' }
195
+ r.is('t/do/you/speak/spanish') { erb '<%= t.do.you.speak.spanish %>' }
196
+ r.is('t/do/you/speak/german') { erb '<%= t.do.you.speak.german %>' }
197
+ end
198
+ end
199
+ end
200
+
201
+ [ ['sv-se', 'Ett'], ['de','Ein'], ['en', 'One'] ].each do |l|
202
+
203
+ describe "with session[:locale]='#{l[0]}' " do
204
+
205
+ it "should return the correct translation of 't.one' " do
206
+ get '/t/one', {},{ 'rack.session' => { :locale => "#{l[0]}" } }
207
+ _body.must_equal "#{l[1]}"
208
+ end
209
+
210
+ end
211
+
212
+ end
213
+
214
+ it "should return the correct translation from the default locale 'es' " do
215
+ get '/t/do/you/speak/spanish', {},{ 'rack.session' => { :locale => 'sv-se'} }
216
+ _body.must_equal '¿Hablas español?'
217
+ end
218
+
219
+ it "should return a missing translation error for non-loaded locale 'de' " do
220
+ get '/t/do/you/speak/german', {},{ 'rack.session' => { :locale => 'sv-se'} }
221
+ _body.must_equal 'do.you.speak.<span style="color: red">[german]</span>'
222
+ end
223
+
224
+ it "should return the correct default English translation 't.only.english' " do
225
+ get '/t/only/in/english', {},{ 'rack.session' => { :locale => 'sv-se'} }
226
+ _body.must_equal 'Only in English'
227
+ end
228
+
229
+ end
230
+
231
+ describe 'i18n - #i18n_set_locale_from(:params) - obtaining locale from params' do
232
+
233
+ before do
234
+ app(:bare) do
235
+ plugin :i18n, :locale => ['es'], :translations => "#{File.dirname(__FILE__)}/../spec/**/i18n"
236
+ route do |r|
237
+ r.i18n_set_locale_from(:params)
238
+ r.is('t/one') { erb("<%= t.one %>") }
239
+ end
240
+ end
241
+ end
242
+
243
+ [ ['sv-se', 'Ett'], ['de','Ein'], ['en', 'One'] ].each do |l|
244
+
245
+ describe "with 'params?locale=#{l[0]}' " do
246
+
247
+ it "should return the correct translation of 't.one' " do
248
+ get '/t/one', { :locale => "#{l[0]}" }, { 'rack.session' => { } }
249
+ _body.must_equal "#{l[1]}"
250
+ end
251
+
252
+ end
253
+
254
+ end
255
+
256
+ end
257
+
258
+ describe "i18n - #i18n_set_locale_from(:ENV) - obtaining locale from ENV['LANG']" do
259
+
260
+ before do
261
+ app(:bare) do
262
+ plugin :i18n, :locale => ['es'], :translations => "#{File.dirname(__FILE__)}/../spec/**/i18n"
263
+ route do |r|
264
+ r.i18n_set_locale_from(:ENV)
265
+ r.is('env') { erb("<%= ENV['LANG'] %>") }
266
+ r.is('t/one') { erb("<%= t.one %>") }
267
+ r.is('t/two') { erb("<%= t.two %>") }
268
+ r.is('t/only/in/english') { erb '<%= t.only.english %>' }
269
+ r.is('t/do/you/speak/spanish') { erb '<%= t.do.you.speak.spanish %>' }
270
+ r.is('t/do/you/speak/german') { erb '<%= t.do.you.speak.german %>' }
271
+ end
272
+ end
273
+ end
274
+
275
+ [ ['sv-se', 'Ett'], ['de','Ein'], ['en', 'One'] ].each do |l|
276
+
277
+ describe "with 'ENV['LANG']=#{l[0]}' " do
278
+
279
+ it "should return the correct translation of 't.one' " do
280
+ ENV['LANG'] = "#{l[0]}"
281
+ get '/t/one', { }, { 'rack.session' => { } }
282
+ _body.must_equal "#{l[1]}"
283
+ end
284
+
285
+ end
286
+ end
287
+
288
+ end
289
+
290
+ describe "i18n - #i18n_set_locale_from(:http) - obtaining locale from the browser aka HTTP_ACCEPT_LANGUAGE " do
291
+
292
+ before do
293
+ app(:bare) do
294
+ plugin :i18n, :locale => ['es'], :translations => "#{File.dirname(__FILE__)}/../spec/**/i18n"
295
+ route do |r|
296
+ r.i18n_set_locale_from(:http)
297
+ r.is('t/one') { erb("<%= t.one %>") }
298
+ r.is('t/do/you/speak/german') { erb '<%= t.do.you.speak.german %>' }
299
+ r.is('t/do/you/speak/spanish') { erb '<%= t.do.you.speak.spanish %>' }
300
+ r.is('t/do/you/speak/swedish') { erb '<%= t.do.you.speak.swedish %>' }
301
+ r.is('t/do/you/speak/english') { erb '<%= t.do.you.speak.english %>' }
302
+ end
303
+ end
304
+ end
305
+
306
+ [
307
+ ['SV-SE','sv-se;q=1,es;q=0.8,en;q=0.6,de;q=0.2', 'Ett', 'spanish'],
308
+ ['DE','de;q=1,en-ca,en;q=0.6,en-us;q=0.5','Ein', 'english'],
309
+ ['EN','en-ca,en;q=0.8,en-us;q=0.6,de-de;q=0.4,de;q=0.2', 'One', 'german']
310
+ ].each do |l|
311
+
312
+ describe "with 'ENV['HTTP_ACCEPT_LANGUAGE'] = #{l[0]}' " do
313
+
314
+ it "should return the correct translation of 't.one' from the preferred locale " do
315
+ get '/t/one', { }, { 'rack.session' => { }, 'HTTP_ACCEPT_LANGUAGE' => "#{l[1]}" }
316
+ _body.must_equal "#{l[2]}"
317
+ end
318
+
319
+ it "should return the correct translation from the second priority locale " do
320
+ get "/t/do/you/speak/#{l[3]}", { }, { 'rack.session' => { }, 'HTTP_ACCEPT_LANGUAGE' => "#{l[1]}" }
321
+ _body.wont_equal "do.you.speak.<span style=\"color: red\">[#{l[3]}]</span>"
322
+ _body.wont_match /style="color: red"/
323
+ end
324
+
325
+ end
326
+ end
327
+ end
328
+
329
+ describe "i18n - #i18n_set_locale_from(:invalid) - obtaining locale from invalid value (defaulting)" do
330
+
331
+ before do
332
+ app(:bare) do
333
+ plugin :i18n, :locale => ['es'], :translations => "#{File.dirname(__FILE__)}/../spec/**/i18n"
334
+ route do |r|
335
+ r.i18n_set_locale_from(:invalid_non_existant_value)
336
+ r.is('t/one') { erb("<%= t.one %>") }
337
+ end
338
+ end
339
+ end
340
+
341
+ it "should return the correct translation of 't.one' from the default locale (ES)" do
342
+ get '/t/one'
343
+ _body.must_equal "Uno"
344
+ end
345
+
346
+ end
347
+
348
+
349
+ describe 'i18n - #i18n_set_locale(:locale) - setting a temporary locale within a route block' do
350
+
351
+ before do
352
+ app(:bare) do
353
+ plugin :i18n, :locale => ['es'], :translations => "#{File.dirname(__FILE__)}/../spec/**/i18n"
354
+ route do |r|
355
+ r.is('t/hello') { erb("<%= t.hello %>") }
356
+
357
+ r.i18n_set_locale('de') do
358
+ r.is('t/hello/block') { erb("<%= t.hello %>") }
359
+ r.on('posts/:id') do
360
+ r.on('comments') do
361
+ r.is(':id') { erb("<%= t.one %>") }
362
+ end
363
+ end
364
+ end
365
+
366
+ end
367
+ end
368
+ end
369
+
370
+ it "should return the correct translation from the default locale 'es' " do
371
+ get '/t/hello'
372
+ _body.must_equal 'Hola de app/i18n/es.yml'
373
+ end
374
+
375
+ it "should return the correct translation from the temporary scope locale 'de' " do
376
+ get '/t/hello/block'
377
+ _body.must_equal "Hallo aus i18n/de.yml"
378
+ end
379
+
380
+ it "should return the correct translation from the temporary scope locale 'de' deeply nested routes " do
381
+ get '/posts/10/comments/20'
382
+ _body.must_equal "Ein"
383
+ end
384
+
385
+ end
386
+
387
+
388
+ describe 'i18n - Instance & Class Methods' do
389
+ before do
390
+ app(:bare) do
391
+ plugin :i18n, :locale => ['es','de','sv-se'], :translations => "#{File.dirname(__FILE__)}/../spec/**/i18n"
392
+ plugin :json
393
+ route do |r|
394
+ r.is('i18n/opts') { self.class.i18n_opts }
395
+ r.is('i18n/available/locales') { i18n_available_locales }
396
+ r.is('i18n/default/places') { erb '<%= i18n_default_places %>' }
397
+ end
398
+ end
399
+ end
400
+
401
+ it "#i18n_available_locales should return available locales as an array" do
402
+ rt('/i18n/available/locales').must_equal "[[\"de\",\"Deutsch\"],[\"en\",\"English\"],[\"es\",\"Español\"],[\"sv-SE\",\"Svenska\"]]"
403
+ end
404
+
405
+ it "#i18n_default_places should return the locations load path" do
406
+ rt('/i18n/default/places').must_match /\/\.\.\/spec\/\*\*\/i18n/
407
+ end
408
+
409
+ it "#i18n_opts should return an array of configuration options" do
410
+ rt('/i18n/opts').must_match /"default_locale":"es"/
411
+ end
412
+
413
+ end