Skip to content

Commit 5e44d39

Browse files
[3.12] gh-127488: Add tests for Tools/i18n/msgfmt.py (GH-127540) (GH-130181)
(cherry picked from commit 361083b) Co-authored-by: Tomas R <[email protected]>
1 parent b85f061 commit 5e44d39

File tree

6 files changed

+197
-0
lines changed

6 files changed

+197
-0
lines changed
28 Bytes
Binary file not shown.
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Fuzzy translations are not written to the .mo file.
2+
#, fuzzy
3+
msgid "foo"
4+
msgstr "bar"
5+
6+
# comment
7+
#, fuzzy
8+
msgctxt "abc"
9+
msgid "foo"
10+
msgstr "bar"
11+
12+
#, fuzzy
13+
# comment
14+
msgctxt "xyz"
15+
msgid "foo"
16+
msgstr "bar"
17+
18+
#, fuzzy
19+
msgctxt "abc"
20+
msgid "One email sent."
21+
msgid_plural "%d emails sent."
22+
msgstr[0] "One email sent."
23+
msgstr[1] "%d emails sent."
728 Bytes
Binary file not shown.
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
msgid ""
2+
msgstr ""
3+
"Project-Id-Version: PACKAGE VERSION\n"
4+
"POT-Creation-Date: 2024-10-26 18:06+0200\n"
5+
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
6+
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
7+
"Language-Team: LANGUAGE <[email protected]>\n"
8+
"MIME-Version: 1.0\n"
9+
"Content-Type: text/plain; charset=UTF-8\n"
10+
"Content-Transfer-Encoding: 8bit\n"
11+
12+
msgid "foo"
13+
msgstr ""
14+
15+
msgid "bar"
16+
msgstr "baz"
17+
18+
msgctxt "abc"
19+
msgid "foo"
20+
msgstr "bar"
21+
22+
# comment
23+
msgctxt "xyz"
24+
msgid "foo"
25+
msgstr "bar"
26+
27+
msgid "Multiline"
28+
"string"
29+
msgstr "Multiline"
30+
"translation"
31+
32+
msgid "\"escapes\""
33+
msgstr "\"translated\""
34+
35+
msgid "\n newlines \n"
36+
msgstr "\n translated \n"
37+
38+
msgid "One email sent."
39+
msgid_plural "%d emails sent."
40+
msgstr[0] "One email sent."
41+
msgstr[1] "%d emails sent."
42+
43+
msgctxt "abc"
44+
msgid "One email sent."
45+
msgid_plural "%d emails sent."
46+
msgstr[0] "One email sent."
47+
msgstr[1] "%d emails sent."

Lib/test/test_tools/test_msgfmt.py

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
"""Tests for the Tools/i18n/msgfmt.py tool."""
2+
3+
import sys
4+
import unittest
5+
from gettext import GNUTranslations
6+
from pathlib import Path
7+
8+
from test.support.os_helper import temp_cwd
9+
from test.support.script_helper import assert_python_failure, assert_python_ok
10+
from test.test_tools import skip_if_missing, toolsdir
11+
12+
13+
skip_if_missing('i18n')
14+
15+
data_dir = (Path(__file__).parent / 'msgfmt_data').resolve()
16+
script_dir = Path(toolsdir) / 'i18n'
17+
msgfmt = script_dir / 'msgfmt.py'
18+
19+
20+
def compile_messages(po_file, mo_file):
21+
assert_python_ok(msgfmt, '-o', mo_file, po_file)
22+
23+
24+
class CompilationTest(unittest.TestCase):
25+
26+
def test_compilation(self):
27+
self.maxDiff = None
28+
with temp_cwd():
29+
for po_file in data_dir.glob('*.po'):
30+
with self.subTest(po_file=po_file):
31+
mo_file = po_file.with_suffix('.mo')
32+
with open(mo_file, 'rb') as f:
33+
expected = GNUTranslations(f)
34+
35+
tmp_mo_file = mo_file.name
36+
compile_messages(po_file, tmp_mo_file)
37+
with open(tmp_mo_file, 'rb') as f:
38+
actual = GNUTranslations(f)
39+
40+
self.assertDictEqual(actual._catalog, expected._catalog)
41+
42+
def test_invalid_msgid_plural(self):
43+
with temp_cwd():
44+
Path('invalid.po').write_text('''\
45+
msgid_plural "plural"
46+
msgstr[0] "singular"
47+
''')
48+
49+
res = assert_python_failure(msgfmt, 'invalid.po')
50+
err = res.err.decode('utf-8')
51+
self.assertIn('msgid_plural not preceded by msgid', err)
52+
53+
def test_plural_without_msgid_plural(self):
54+
with temp_cwd():
55+
Path('invalid.po').write_text('''\
56+
msgid "foo"
57+
msgstr[0] "bar"
58+
''')
59+
60+
res = assert_python_failure(msgfmt, 'invalid.po')
61+
err = res.err.decode('utf-8')
62+
self.assertIn('plural without msgid_plural', err)
63+
64+
def test_indexed_msgstr_without_msgid_plural(self):
65+
with temp_cwd():
66+
Path('invalid.po').write_text('''\
67+
msgid "foo"
68+
msgid_plural "foos"
69+
msgstr "bar"
70+
''')
71+
72+
res = assert_python_failure(msgfmt, 'invalid.po')
73+
err = res.err.decode('utf-8')
74+
self.assertIn('indexed msgstr required for plural', err)
75+
76+
def test_generic_syntax_error(self):
77+
with temp_cwd():
78+
Path('invalid.po').write_text('''\
79+
"foo"
80+
''')
81+
82+
res = assert_python_failure(msgfmt, 'invalid.po')
83+
err = res.err.decode('utf-8')
84+
self.assertIn('Syntax error', err)
85+
86+
class CLITest(unittest.TestCase):
87+
88+
def test_help(self):
89+
for option in ('--help', '-h'):
90+
res = assert_python_ok(msgfmt, option)
91+
err = res.err.decode('utf-8')
92+
self.assertIn('Generate binary message catalog from textual translation description.', err)
93+
94+
def test_version(self):
95+
for option in ('--version', '-V'):
96+
res = assert_python_ok(msgfmt, option)
97+
out = res.out.decode('utf-8').strip()
98+
self.assertEqual('msgfmt.py 1.2', out)
99+
100+
def test_invalid_option(self):
101+
res = assert_python_failure(msgfmt, '--invalid-option')
102+
err = res.err.decode('utf-8')
103+
self.assertIn('Generate binary message catalog from textual translation description.', err)
104+
self.assertIn('option --invalid-option not recognized', err)
105+
106+
def test_no_input_file(self):
107+
res = assert_python_ok(msgfmt)
108+
err = res.err.decode('utf-8').replace('\r\n', '\n')
109+
self.assertIn('No input file given\n'
110+
"Try `msgfmt --help' for more information.", err)
111+
112+
def test_nonexistent_file(self):
113+
assert_python_failure(msgfmt, 'nonexistent.po')
114+
115+
116+
def update_catalog_snapshots():
117+
for po_file in data_dir.glob('*.po'):
118+
mo_file = po_file.with_suffix('.mo')
119+
compile_messages(po_file, mo_file)
120+
121+
122+
if __name__ == '__main__':
123+
if len(sys.argv) > 1 and sys.argv[1] == '--snapshot-update':
124+
update_catalog_snapshots()
125+
sys.exit(0)
126+
unittest.main()

Makefile.pre.in

+1
Original file line numberDiff line numberDiff line change
@@ -2237,6 +2237,7 @@ TESTSUBDIRS= idlelib/idle_test \
22372237
test/test_tomllib/data/valid/multiline-basic-str \
22382238
test/test_tools \
22392239
test/test_tools/i18n_data \
2240+
test/test_tools/msgfmt_data \
22402241
test/test_ttk \
22412242
test/test_unittest \
22422243
test/test_unittest/testmock \

0 commit comments

Comments
 (0)