gettext 2.3.3 → 2.3.4

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.
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