gettext 2.3.3 → 2.3.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/doc/text/news.md +37 -0
  2. data/gettext.gemspec +1 -0
  3. data/lib/gettext/runtime/mo.rb +382 -0
  4. data/lib/gettext/runtime/mofile.rb +24 -366
  5. data/lib/gettext/runtime/textdomain.rb +17 -17
  6. data/lib/gettext/tools.rb +1 -1
  7. data/lib/gettext/tools/msgfmt.rb +2 -2
  8. data/lib/gettext/tools/msginit.rb +16 -15
  9. data/lib/gettext/tools/msgmerge.rb +258 -255
  10. data/lib/gettext/tools/parser/ruby.rb +24 -24
  11. data/lib/gettext/tools/po.rb +256 -0
  12. data/lib/gettext/tools/po_entry.rb +355 -0
  13. data/lib/gettext/tools/poparser.rb +118 -16
  14. data/lib/gettext/tools/xgettext.rb +56 -58
  15. data/lib/gettext/version.rb +1 -1
  16. data/samples/po/hello.pot +3 -3
  17. data/samples/po/hello2.pot +3 -3
  18. data/samples/po/hello_glade2.pot +3 -3
  19. data/samples/po/hello_gtk2.pot +3 -3
  20. data/samples/po/hello_noop.pot +3 -3
  21. data/samples/po/hello_plural.pot +3 -3
  22. data/samples/po/hello_tk.pot +3 -3
  23. data/src/poparser.ry +111 -9
  24. data/test/parser/test_ruby.rb +17 -13
  25. data/test/po/_.pot +3 -3
  26. data/test/po/backslash.pot +3 -3
  27. data/test/po/non_ascii.pot +3 -3
  28. data/test/po/np_.pot +5 -4
  29. data/test/po/ns_.pot +3 -3
  30. data/test/po/p_.pot +3 -3
  31. data/test/po/s_.pot +3 -3
  32. data/test/po/untranslated.pot +3 -3
  33. data/test/{test_mofile.rb → test_mo.rb} +3 -3
  34. data/test/test_parser.rb +13 -12
  35. data/test/test_po_entry.rb +329 -0
  36. data/test/test_po_parser.rb +209 -8
  37. data/test/tools/test_msginit.rb +0 -2
  38. data/test/tools/test_msgmerge.rb +427 -50
  39. data/test/tools/test_po.rb +487 -0
  40. data/test/tools/test_xgettext.rb +1 -1
  41. metadata +28 -45
  42. data/data/locale/de/LC_MESSAGES/gettext.mo +0 -0
  43. data/data/locale/de/LC_MESSAGES/rgettext.mo +0 -0
  44. data/data/locale/el/LC_MESSAGES/gettext.mo +0 -0
  45. data/data/locale/el/LC_MESSAGES/rgettext.mo +0 -0
  46. data/data/locale/sr/LC_MESSAGES/gettext.mo +0 -0
  47. data/data/locale/sr/LC_MESSAGES/rgettext.mo +0 -0
  48. data/data/locale/uk/LC_MESSAGES/gettext.mo +0 -0
  49. data/data/locale/uk/LC_MESSAGES/rgettext.mo +0 -0
  50. data/lib/gettext/tools/pomessage.rb +0 -232
  51. data/samples/locale/bg/LC_MESSAGES/hello_gtk.mo +0 -0
  52. data/samples/locale/bs/LC_MESSAGES/hello_gtk.mo +0 -0
  53. data/samples/locale/ca/LC_MESSAGES/hello_gtk.mo +0 -0
  54. data/samples/locale/cs/LC_MESSAGES/hello_gtk.mo +0 -0
  55. data/samples/locale/de/LC_MESSAGES/hello_gtk.mo +0 -0
  56. data/samples/locale/el/LC_MESSAGES/hello_gtk.mo +0 -0
  57. data/samples/locale/eo/LC_MESSAGES/hello_gtk.mo +0 -0
  58. data/samples/locale/es/LC_MESSAGES/hello_gtk.mo +0 -0
  59. data/samples/locale/fr/LC_MESSAGES/hello_gtk.mo +0 -0
  60. data/samples/locale/hr/LC_MESSAGES/hello_gtk.mo +0 -0
  61. data/samples/locale/hu/LC_MESSAGES/hello_gtk.mo +0 -0
  62. data/samples/locale/it/LC_MESSAGES/hello_gtk.mo +0 -0
  63. data/samples/locale/ja/LC_MESSAGES/hello_gtk.mo +0 -0
  64. data/samples/locale/ko/LC_MESSAGES/hello_gtk.mo +0 -0
  65. data/samples/locale/lv/LC_MESSAGES/hello_gtk.mo +0 -0
  66. data/samples/locale/nb/LC_MESSAGES/hello_gtk.mo +0 -0
  67. data/samples/locale/nl/LC_MESSAGES/hello_gtk.mo +0 -0
  68. data/samples/locale/pt_BR/LC_MESSAGES/hello_gtk.mo +0 -0
  69. data/samples/locale/ru/LC_MESSAGES/hello_gtk.mo +0 -0
  70. data/samples/locale/sr/LC_MESSAGES/hello_gtk.mo +0 -0
  71. data/samples/locale/sv/LC_MESSAGES/hello_gtk.mo +0 -0
  72. data/samples/locale/uk/LC_MESSAGES/hello_gtk.mo +0 -0
  73. data/samples/locale/vi/LC_MESSAGES/hello_gtk.mo +0 -0
  74. data/samples/locale/zh/LC_MESSAGES/hello_gtk.mo +0 -0
  75. data/samples/locale/zh_TW/LC_MESSAGES/hello_gtk.mo +0 -0
  76. data/test/po/ascii.pot +0 -23
  77. data/test/po/no_exist_msgid.pot +0 -20
  78. data/test/po/not_existed_msgid.pot +0 -20
  79. data/test/test_po_message.rb +0 -118
@@ -0,0 +1,487 @@
1
+ # -*- coding: utf-8 -*-
2
+ #
3
+ # Copyright (C) 2012 Haruka Yoshihara <yoshihara@clear-code.com>
4
+ # Copyright (C) 2012 Kouhei Sutou <kou@clear-code.com>
5
+ #
6
+ # License: Ruby's or LGPL
7
+ #
8
+ # This library is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU Lesser General Public License as published by
10
+ # the Free Software Foundation, either version 3 of the License, or
11
+ # (at your option) any later version.
12
+ #
13
+ # This library is distributed in the hope that it will be useful,
14
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ # GNU Lesser General Public License for more details.
17
+ #
18
+ # You should have received a copy of the GNU Lesser General Public License
19
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
20
+
21
+ require "gettext/tools/po"
22
+
23
+ class TestPO < Test::Unit::TestCase
24
+ def setup
25
+ @po = nil
26
+ end
27
+
28
+ class TestHasKey < self
29
+ def setup
30
+ @po = GetText::PO.new
31
+ end
32
+
33
+ def test_msgid_exist
34
+ @po["msgid"] = "msgstr"
35
+
36
+ assert_true(@po.has_key?("msgid"))
37
+ assert_true(@po.has_key?(nil, "msgid"))
38
+ end
39
+
40
+ def test_msgid_notexistent
41
+ assert_false(@po.has_key?("msgid"))
42
+ assert_false(@po.has_key?(nil, "msgid"))
43
+ end
44
+
45
+ def test_msgctxt_and_msgid_exist
46
+ @po["msgctxt", "msgid"] = "msgstr"
47
+
48
+ assert_false(@po.has_key?("msgid"))
49
+ assert_true(@po.has_key?("msgctxt", "msgid"))
50
+ end
51
+
52
+ def test_wrong_arguments
53
+ @po["msgctxt", "msgid"] = "msgstr"
54
+
55
+ assert_raise(ArgumentError) do
56
+ @po.has_key?("msgctxt", "msgid", "wrong_argument")
57
+ end
58
+ end
59
+ end
60
+
61
+ class TestEach < self
62
+ def setup
63
+ @hello = "hello"
64
+ @hello_translation = "bonjour"
65
+ @he = "he"
66
+ @he_translation = "il"
67
+
68
+ @po = GetText::PO.new
69
+ @po[@hello] = @hello_translation
70
+ @po[@he] = @he_translation
71
+ end
72
+
73
+ def test_block_given
74
+ entries = []
75
+ @po.each do |entry|
76
+ entries << entry
77
+ end
78
+
79
+ entries = entries.sort_by do |entry|
80
+ entry.msgid
81
+ end
82
+
83
+ assert_equal(expected_entries, entries)
84
+ end
85
+
86
+ def test_no_block_given
87
+ entries = @po.each.sort_by do |entry|
88
+ entry.msgid
89
+ end
90
+
91
+ assert_equal(expected_entries, entries)
92
+ end
93
+
94
+ private
95
+ def expected_entries
96
+ he_entry = POEntry.new(:normal)
97
+ he_entry.msgid = @he
98
+ he_entry.msgstr = @he_translation
99
+ hello_entry = POEntry.new(:normal)
100
+ hello_entry.msgid = @hello
101
+ hello_entry.msgstr = @hello_translation
102
+
103
+ [he_entry, hello_entry]
104
+ end
105
+ end
106
+
107
+ class TestSetEntry < self
108
+ def test_normal
109
+ msgid = "msgid"
110
+ msgstr = "msgstr"
111
+
112
+ @po = GetText::PO.new
113
+ @po[msgid] = msgstr
114
+
115
+ entry = POEntry.new(:normal)
116
+ entry.msgid = msgid
117
+ entry.msgstr = msgstr
118
+ assert_equal(entry, @po[msgid])
119
+ end
120
+
121
+ def test_msgctxt
122
+ msgctxt = "msgctxt"
123
+ msgid = "msgid"
124
+ msgstr = "msgstr"
125
+
126
+ @po = GetText::PO.new
127
+ @po[msgctxt, msgid] = msgstr
128
+
129
+ entry = POEntry.new(:msgctxt)
130
+ entry.msgctxt = msgctxt
131
+ entry.msgid = msgid
132
+ entry.msgstr = msgstr
133
+ assert_equal(entry, @po[msgctxt, msgid])
134
+ end
135
+
136
+ def test_wrong_arguments
137
+ msgctxt = "msgctxt"
138
+ msgid = "msgid"
139
+ msgstr = "msgstr"
140
+
141
+ @po = GetText::PO.new
142
+ assert_raise(ArgumentError) do
143
+ @po[msgctxt, msgid, "wrong argument"] = msgstr
144
+ end
145
+ end
146
+
147
+ def test_update_existing_entry
148
+ test_normal
149
+
150
+ msgid = "msgid"
151
+ new_msgstr = "new_msgstr"
152
+ @po[msgid] = new_msgstr
153
+
154
+ entry = POEntry.new(:normal)
155
+ entry.msgid = msgid
156
+ entry.msgstr = new_msgstr
157
+ assert_equal(entry, @po[msgid])
158
+ end
159
+
160
+ def test_po_entry
161
+ @po = GetText::PO.new
162
+
163
+ msgid = "msgid"
164
+ msgstr = "msgstr"
165
+ entry = POEntry.new(:normal)
166
+ entry.msgid = msgid
167
+ entry.msgstr = msgstr
168
+
169
+ @po[msgid] = entry
170
+ assert_true(@po.has_key?(nil, msgid))
171
+ assert_equal(msgstr, @po[msgid].msgstr)
172
+ end
173
+ end
174
+
175
+ class TestComment < self
176
+ def test_add
177
+ msgid = "msgid"
178
+ comment = "comment"
179
+
180
+ @po = GetText::PO.new
181
+ @po.set_comment(msgid, comment)
182
+
183
+ entry = POEntry.new(:normal)
184
+ entry.msgid = msgid
185
+ entry.comment = comment
186
+ assert_equal(entry, @po[msgid])
187
+ assert_equal(nil, @po[msgid].msgstr)
188
+ end
189
+
190
+ def test_add_to_existing_entry
191
+ msgid = "msgid"
192
+ msgstr = "msgstr"
193
+ @po = GetText::PO.new
194
+ @po[msgid] = msgstr
195
+
196
+ comment = "comment"
197
+ @po.set_comment(msgid, comment)
198
+
199
+ entry = POEntry.new(:normal)
200
+ entry.msgid = msgid
201
+ entry.msgstr = msgstr
202
+ entry.comment = comment
203
+ assert_equal(entry, @po[msgid])
204
+ end
205
+ end
206
+
207
+ class TestToS < self
208
+ def setup
209
+ @po = GetText::PO.new
210
+ @po[""] = header
211
+ @po[""].translator_comment = header_comment
212
+ end
213
+
214
+ def test_same_filename
215
+ hello = "hello"
216
+ hello_translation = "こんにちは"
217
+ hello_references = ["file.rb:10"]
218
+ hello_comment = "#: file.rb:10"
219
+ bye = "bye"
220
+ bye_translation = "さようなら"
221
+ bye_references = ["file.rb:20"]
222
+ bye_comment = "#: file.rb:20"
223
+
224
+ @po[hello] = hello_translation
225
+ @po[hello].references = hello_references
226
+
227
+ @po[bye] = bye_translation
228
+ @po[bye].references = bye_references
229
+
230
+ expected_po =<<EOP
231
+ #{expected_header_comment}
232
+ #
233
+ msgid ""
234
+ msgstr ""
235
+ #{expected_header}
236
+
237
+ #{hello_comment}
238
+ msgid "#{hello}"
239
+ msgstr "#{hello_translation}"
240
+
241
+ #{bye_comment}
242
+ msgid "#{bye}"
243
+ msgstr "#{bye_translation}"
244
+ EOP
245
+ assert_equal(expected_po, @po.to_s)
246
+ end
247
+
248
+ def test_different_filename
249
+ hello = "hello"
250
+ hello_translation = "こんにちは"
251
+ hello_references = ["file.rb:10"]
252
+ hello_comment = "#: file.rb:10"
253
+ bye = "bye"
254
+ bye_translation = "さようなら"
255
+ bye_references = ["test.rb:10"]
256
+ bye_comment = "#: test.rb:10"
257
+
258
+ @po[hello] = hello_translation
259
+ @po[hello].references = hello_references
260
+
261
+ @po[bye] = bye_translation
262
+ @po[bye].references = bye_references
263
+
264
+ expected_po =<<EOP
265
+ #{expected_header_comment}
266
+ #
267
+ msgid ""
268
+ msgstr ""
269
+ #{expected_header}
270
+
271
+ #{hello_comment}
272
+ msgid "#{hello}"
273
+ msgstr "#{hello_translation}"
274
+
275
+ #{bye_comment}
276
+ msgid "#{bye}"
277
+ msgstr "#{bye_translation}"
278
+ EOP
279
+ assert_equal(expected_po, @po.to_s)
280
+ end
281
+
282
+ def test_including_colon_filename
283
+ hello = "hello"
284
+ hello_translation = "こんにちは"
285
+ hello_references = ["file.rb:10"]
286
+ hello_comment = "#: file.rb:10"
287
+ bye = "bye"
288
+ bye_translation = "さようなら"
289
+ bye_references = ["file:2.rb:10"]
290
+ bye_comment = "#: file:2.rb:10"
291
+
292
+ @po[hello] = hello_translation
293
+ @po[hello].references = hello_references
294
+
295
+ @po[bye] = bye_translation
296
+ @po[bye].references = bye_references
297
+
298
+ expected_po =<<EOP
299
+ #{expected_header_comment}
300
+ #
301
+ msgid ""
302
+ msgstr ""
303
+ #{expected_header}
304
+
305
+ #{hello_comment}
306
+ msgid "#{hello}"
307
+ msgstr "#{hello_translation}"
308
+
309
+ #{bye_comment}
310
+ msgid "#{bye}"
311
+ msgstr "#{bye_translation}"
312
+ EOP
313
+ assert_equal(expected_po, @po.to_s)
314
+ end
315
+
316
+ def test_no_file_number
317
+ hello = "hello"
318
+ hello_translation = "こんにちは"
319
+ hello_references = ["file.rb"]
320
+ hello_comment = "#: file.rb"
321
+ bye = "bye"
322
+ bye_translation = "さようなら"
323
+ bye_references = ["test.rb"]
324
+ bye_comment = "#: test.rb"
325
+
326
+ @po[hello] = hello_translation
327
+ @po[hello].references = hello_references
328
+
329
+ @po[bye] = bye_translation
330
+ @po[bye].references = bye_references
331
+
332
+ expected_po =<<EOP
333
+ #{expected_header_comment}
334
+ #
335
+ msgid ""
336
+ msgstr ""
337
+ #{expected_header}
338
+
339
+ #{hello_comment}
340
+ msgid "#{hello}"
341
+ msgstr "#{hello_translation}"
342
+
343
+ #{bye_comment}
344
+ msgid "#{bye}"
345
+ msgstr "#{bye_translation}"
346
+ EOP
347
+ assert_equal(expected_po, @po.to_s)
348
+ end
349
+
350
+ def test_multiple_filename
351
+ hello = "hello"
352
+ hello_translation = "こんにちは"
353
+ hello_references = ["file.rb:10"]
354
+ hello_comment = "#: file.rb:10"
355
+ bye = "bye"
356
+ bye_translation = "さようなら"
357
+ bye_references = ["test.rb:10", "file.rb:110", "file.rb:20"]
358
+ bye_comment = "#: file.rb:20 file.rb:110 test.rb:10"
359
+
360
+ @po[hello] = hello_translation
361
+ @po[hello].references = hello_references
362
+
363
+ @po[bye] = bye_translation
364
+ @po[bye].references = bye_references
365
+
366
+ expected_po =<<EOP
367
+ #{expected_header_comment}
368
+ #
369
+ msgid ""
370
+ msgstr ""
371
+ #{expected_header}
372
+
373
+ #{hello_comment}
374
+ msgid "#{hello}"
375
+ msgstr "#{hello_translation}"
376
+
377
+ #{bye_comment}
378
+ msgid "#{bye}"
379
+ msgstr "#{bye_translation}"
380
+ EOP
381
+ assert_equal(expected_po, @po.to_s)
382
+ end
383
+
384
+ def test_obsolete_comment
385
+ hello = "hello"
386
+ hello_translation = "こんにちは"
387
+ hello_references = ["file.rb:10"]
388
+
389
+ @po[hello] = hello_translation
390
+ @po[hello].references = hello_references
391
+
392
+ @po.set_comment(:last, obsolete_comment)
393
+
394
+ hello_comment = "#: file.rb:10"
395
+ expected_po =<<EOP
396
+ #{expected_header_comment}
397
+ #
398
+ msgid ""
399
+ msgstr ""
400
+ #{expected_header}
401
+
402
+ #{hello_comment}
403
+ msgid "#{hello}"
404
+ msgstr "#{hello_translation}"
405
+
406
+ #{expected_obsolete_comment}
407
+ EOP
408
+ assert_equal(expected_po, @po.to_s)
409
+ end
410
+
411
+ def test_obsolete_comment_without_header
412
+ @po = GetText::PO.new
413
+
414
+ hello = "hello"
415
+ hello_translation = "こんにちは"
416
+ hello_references = ["file.rb:10"]
417
+
418
+ @po[hello] = hello_translation
419
+ @po[hello].references = hello_references
420
+
421
+ @po.set_comment(:last, obsolete_comment)
422
+
423
+ hello_comment = "#: file.rb:10"
424
+ expected_po =<<EOP
425
+
426
+ #{hello_comment}
427
+ msgid "#{hello}"
428
+ msgstr "#{hello_translation}"
429
+
430
+ #{expected_obsolete_comment}
431
+ EOP
432
+ assert_equal(expected_po, @po.to_s)
433
+ end
434
+
435
+ private
436
+ def header
437
+ <<EOH
438
+ Project-Id-Version: test 1.0.0
439
+ POT-Creation-Date: 2012-10-31 12:40+0900
440
+ PO-Revision-Date: 2012-11-01 17:46+0900
441
+ Last-Translator: FULLNAME <MAIL@ADDRESS>
442
+ Language-Team: Japanese
443
+ Language:
444
+ MIME-Version: 1.0
445
+ Content-Type: text/plain; charset=UTF-8
446
+ Content-Transfer-Encoding: 8bit
447
+ Plural-Forms: nplurals=2; plural=(n != 1)
448
+ EOH
449
+ end
450
+
451
+ def header_comment
452
+ <<EOC
453
+ Japanese translations for test package.
454
+ Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER
455
+ This file is distributed under the same license as the PACKAGE package.
456
+ FULLNAME <MAIL@ADDRESS>, 2012.
457
+
458
+ EOC
459
+ end
460
+
461
+ def expected_header
462
+ expected_header = header.split("\n").collect do |line|
463
+ "\"#{line}\\n\""
464
+ end
465
+ expected_header.join("\n")
466
+ end
467
+
468
+ def expected_header_comment
469
+ expected_header_comment = header_comment.split("\n").collect do |line|
470
+ "# #{line}"
471
+ end
472
+ expected_header_comment.join("\n")
473
+ end
474
+
475
+ def obsolete_comment
476
+ <<EOC
477
+ # test.rb:10
478
+ msgid \"hello\"
479
+ msgstr \"Salut\"
480
+ EOC
481
+ end
482
+
483
+ def expected_obsolete_comment
484
+ obsolete_comment.gsub(/^/, "#~ ").chomp
485
+ end
486
+ end
487
+ end