Skip to content

Commit 73b5ac8

Browse files
committed
Add test for current behaviour of msgfmt.py
Test option processing, and conversion of one single file with or without the -o option. Also test the little documented behaviour of merging two input files with -o option.
1 parent 32bc11c commit 73b5ac8

File tree

1 file changed

+183
-2
lines changed

1 file changed

+183
-2
lines changed

Lib/test/test_tools/test_i18n.py

Lines changed: 183 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
import unittest
66
from textwrap import dedent
77

8-
from test.support.script_helper import assert_python_ok
8+
from test.support.script_helper import assert_python_ok, assert_python_failure
99
from test.test_tools import skip_if_missing, toolsdir
10-
from test.support import temp_cwd, temp_dir
10+
from test.support import temp_cwd, temp_dir, unload, change_cwd
1111

1212

1313
skip_if_missing()
@@ -243,3 +243,184 @@ def test_files_list(self):
243243
self.assertIn(f'msgid "{text1}"', data)
244244
self.assertIn(f'msgid "{text2}"', data)
245245
self.assertNotIn(text3, data)
246+
247+
248+
class Test_msgfmt(unittest.TestCase):
249+
"""Tests for the msgfmt.py tool
250+
bpo-35335 - bpo-9741
251+
"""
252+
253+
script = os.path.join(toolsdir,'i18n', 'msgfmt.py')
254+
255+
# binary images of tiny po files
256+
# windows end of lines for first one
257+
file1_fr_po = b'''# French translations for python package.\r
258+
# Copyright (C) 2018 THE python\'S COPYRIGHT HOLDER\r
259+
# This file is distributed under the same license as the python package.\r
260+
# s-ball <[email protected]>, 2018.\r
261+
#\r
262+
msgid ""\r
263+
msgstr ""\r
264+
"Project-Id-Version: python 3.8\\n"\r
265+
"Report-Msgid-Bugs-To: \\n"\r
266+
"POT-Creation-Date: 2018-11-30 23:46+0100\\n"\r
267+
"PO-Revision-Date: 2018-11-30 23:47+0100\\n"\r
268+
"Last-Translator: s-ball <[email protected]>\\n"\r
269+
"Language-Team: French\\n"\r\n"Language: fr\\n"\r
270+
"MIME-Version: 1.0\\n"\r
271+
"Content-Type: text/plain; charset=UTF-8\\n"\r
272+
"Content-Transfer-Encoding: 8bit\\n"\r
273+
"Plural-Forms: nplurals=2; plural=(n > 1);\\n"\r
274+
\r
275+
#: file1.py:6\r
276+
msgid "Hello!"\r
277+
msgstr "Bonjour !"\r
278+
\r
279+
#: file1.py:7\r
280+
#, python-brace-format\r
281+
msgid "{n} horse"\r
282+
msgid_plural "{n} horses"\r
283+
msgstr[0] "{n} cheval"\r
284+
msgstr[1] "{n} chevaux"\r
285+
'''
286+
287+
# Unix end of file and a non ascii character for second one
288+
file2_fr_po = rb'''# French translations for python package.
289+
# Copyright (C) 2018 THE python'S COPYRIGHT HOLDER
290+
# This file is distributed under the same license as the python package.
291+
# s-ball <[email protected]>, 2018.
292+
#
293+
msgid ""
294+
msgstr ""
295+
"Project-Id-Version: python 3.8\n"
296+
"Report-Msgid-Bugs-To: \n"
297+
"POT-Creation-Date: 2018-11-30 23:57+0100\n"
298+
"PO-Revision-Date: 2018-11-30 23:57+0100\n"
299+
"Last-Translator: s-ball <[email protected]>\n"
300+
"Language-Team: French\n"
301+
"Language: fr\n"
302+
"MIME-Version: 1.0\n"
303+
"Content-Type: text/plain; charset=UTF-8\n"
304+
"Content-Transfer-Encoding: 8bit\n"
305+
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
306+
307+
#: file2.py:6
308+
msgid "It's over."
309+
msgstr "C'est termin\xc3\xa9."
310+
311+
#: file2.py:7
312+
msgid "Bye..."
313+
msgstr "Au revoir ..."
314+
'''
315+
316+
# binary images of corresponding compiled mo files
317+
file1_fr_mo = b'\xde\x12\x04\x95\x00\x00\x00\x00\x03\x00\x00\x00\x1c' \
318+
b'\x00\x00\x004\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \
319+
b'\x00\x00\x00\x00\x00L\x00\x00\x00\x06\x00\x00\x00M' \
320+
b'\x00\x00\x00\x14\x00\x00\x00T\x00\x00\x00[\x01\x00' \
321+
b'\x00i\x00\x00\x00\t\x00\x00\x00\xc5\x01\x00\x00\x16' \
322+
b'\x00\x00\x00\xcf\x01\x00\x00\x00Hello!\x00{n} horse' \
323+
b'\x00{n} horses\x00Project-Id-Version: python 3.8\n' \
324+
b'Report-Msgid-Bugs-To: \nPOT-Creation-Date: 2018-11-30 ' \
325+
b'23:46+0100\nPO-Revision-Date: 2018-11-30 23:47+0100\n'\
326+
b'Last-Translator: s-ball <[email protected]>\n' \
327+
b'Language-Team: French\nLanguage: fr\nMIME-Version: 1.0' \
328+
b'\nContent-Type: text/plain; charset=UTF-8\nContent-' \
329+
b'Transfer-Encoding: 8bit\nPlural-Forms: nplurals=2' \
330+
b'; plural=(n > 1);\n\x00Bonjour !\x00{n} cheval\x00{n' \
331+
b'} chevaux\x00'
332+
file2_fr_mo = b"\xde\x12\x04\x95\x00\x00\x00\x00\x03\x00\x00\x00" \
333+
b"\x1c\x00\x00\x004\x00\x00\x00\x00\x00\x00\x00\x00" \
334+
b"\x00\x00\x00\x00\x00\x00\x00L\x00\x00\x00\x06\x00" \
335+
b"\x00\x00M\x00\x00\x00\n\x00\x00\x00T\x00\x00\x00[" \
336+
b"\x01\x00\x00_\x00\x00\x00\r\x00\x00\x00\xbb\x01" \
337+
b"\x00\x00\x0f\x00\x00\x00\xc9\x01\x00\x00\x00Bye.." \
338+
b".\x00It's over.\x00Project-Id-Version: python 3.8" \
339+
b"\nReport-Msgid-Bugs-To: \nPOT-Creation-Date: 2018" \
340+
b"-11-30 23:57+0100\nPO-Revision-Date: 2018-11-30 2" \
341+
b"3:57+0100\nLast-Translator: s-ball <s-ball@lapost" \
342+
b"e.net>\nLanguage-Team: French\nLanguage: fr\nMIME" \
343+
b"-Version: 1.0\nContent-Type: text/plain; charset=" \
344+
b"UTF-8\nContent-Transfer-Encoding: 8bit\nPlural-Fo" \
345+
b"rms: nplurals=2; plural=(n > 1);\n\x00Au revoir ." \
346+
b"..\x00C'est termin\xc3\xa9.\x00"
347+
348+
# image of merging both po files keeping second header
349+
file12_fr_mo = b"\xde\x12\x04\x95\x00\x00\x00\x00\x05\x00\x00\x00" \
350+
b"\x1c\x00\x00\x00D\x00\x00\x00\x00\x00\x00\x00\x00" \
351+
b"\x00\x00\x00\x00\x00\x00\x00l\x00\x00\x00\x06\x00" \
352+
b"\x00\x00m\x00\x00\x00\x06\x00\x00\x00t\x00\x00\x00" \
353+
b"\n\x00\x00\x00{\x00\x00\x00\x14\x00\x00\x00\x86" \
354+
b"\x00\x00\x00[\x01\x00\x00\x9b\x00\x00\x00\r\x00" \
355+
b"\x00\x00\xf7\x01\x00\x00\t\x00\x00\x00\x05\x02\x00" \
356+
b"\x00\x0f\x00\x00\x00\x0f\x02\x00\x00\x16\x00\x00" \
357+
b"\x00\x1f\x02\x00\x00\x00Bye...\x00Hello!\x00It's " \
358+
b"over.\x00{n} horse\x00{n} horses\x00Project-Id-Ver" \
359+
b"sion: python 3.8\nReport-Msgid-Bugs-To: \nPOT-Crea" \
360+
b"tion-Date: 2018-11-30 23:57+0100\nPO-Revision-Date" \
361+
b": 2018-11-30 23:57+0100\nLast-Translator: s-ball <" \
362+
b"[email protected]>\nLanguage-Team: French\nLangua" \
363+
b"ge: fr\nMIME-Version: 1.0\nContent-Type: text/plai" \
364+
b"n; charset=UTF-8\nContent-Transfer-Encoding: 8bit" \
365+
b"\nPlural-Forms: nplurals=2; plural=(n > 1);\n\x00A" \
366+
b"u revoir ...\x00Bonjour !\x00C'est termin\xc3\xa9." \
367+
b"\x00{n} cheval\x00{n} chevaux\x00"
368+
def imp(self):
369+
i18ndir = os.path.join(toolsdir, 'i18n')
370+
sys.path.append(i18ndir)
371+
import msgfmt
372+
sys.path.remove(i18ndir)
373+
return msgfmt
374+
375+
def test_help(self):
376+
"""Test option -h"""
377+
rc, stdout, stderr = assert_python_ok(self.script, '-h')
378+
self.assertEqual(0, rc)
379+
self.assertTrue(stderr.startswith(
380+
b'Generate binary message catalog from textual'
381+
b' translation description.'
382+
)
383+
)
384+
385+
def test_wrong(self):
386+
"""Test wrong option"""
387+
rc, stdout, stderr = assert_python_failure(self.script, '-x')
388+
self.assertEqual(1, rc)
389+
self.assertTrue(stderr.startswith(
390+
b'Generate binary message catalog from textual'
391+
b' translation description.'
392+
)
393+
)
394+
395+
def test_outputfile(self):
396+
"""Test script with -o option - 1 single file, Windows EOL"""
397+
with temp_cwd(None):
398+
with open("file1_fr.po", "wb") as out:
399+
out.write(self.file1_fr_po)
400+
assert_python_ok(self.script, '-o', 'file1.mo', 'file1_fr.po')
401+
with open('file1.mo', 'rb') as fin:
402+
self.assertEqual(self.file1_fr_mo, fin.read())
403+
404+
def test_no_outputfile(self):
405+
"""Test script without -o option - 1 single file, Unix EOL"""
406+
with temp_cwd(None):
407+
with open("file2_fr.po", "wb") as out:
408+
out.write(self.file2_fr_po)
409+
assert_python_ok(self.script, 'file2_fr.po')
410+
with open('file2_fr.mo', 'rb') as fin:
411+
self.assertEqual(self.file2_fr_mo, fin.read())
412+
413+
def test_both_with_outputfile(self):
414+
"""Test script with -o option and 2 input files"""
415+
# msgfmt.py version 1.2 behaviour is to correctly merge the input
416+
# files and to keep last entry when same entry occurs in more than
417+
# one file
418+
with temp_cwd(None):
419+
with open("file1_fr.po", "wb") as out:
420+
out.write(self.file1_fr_po)
421+
with open("file2_fr.po", "wb") as out:
422+
out.write(self.file2_fr_po)
423+
assert_python_ok(self.script, '-o', 'file1.mo',
424+
'file1_fr.po', 'file2_fr.po')
425+
with open('file1.mo', 'rb') as fin:
426+
self.assertEqual(self.file12_fr_mo, fin.read())

0 commit comments

Comments
 (0)