|
6 | 6 | import io
|
7 | 7 | import operator
|
8 | 8 | import os
|
| 9 | +import re |
9 | 10 | import shutil
|
10 | 11 | import stat
|
| 12 | +import subprocess |
11 | 13 | import sys
|
12 | 14 | import textwrap
|
13 | 15 | import tempfile
|
|
16 | 18 | import warnings
|
17 | 19 |
|
18 | 20 | from enum import StrEnum
|
| 21 | +from pathlib import Path |
| 22 | +from test.support import REPO_ROOT |
| 23 | +from test.support import TEST_HOME_DIR |
| 24 | +from test.support import captured_stderr |
| 25 | +from test.support import import_helper |
19 | 26 | from test.support import os_helper
|
| 27 | +from test.support import requires_subprocess |
| 28 | +from test.support import script_helper |
| 29 | +from test.test_tools import skip_if_missing |
20 | 30 | from unittest import mock
|
21 | 31 |
|
22 | 32 |
|
@@ -6388,11 +6398,65 @@ def test_os_error(self):
|
6388 | 6398 | self.parser.parse_args, ['@no-such-file'])
|
6389 | 6399 |
|
6390 | 6400 |
|
| 6401 | +# ================= |
| 6402 | +# Translation tests |
| 6403 | +# ================= |
| 6404 | + |
| 6405 | +pygettext = Path(REPO_ROOT) / 'Tools' / 'i18n' / 'pygettext.py' |
| 6406 | +snapshot_path = Path(TEST_HOME_DIR) / 'translationdata' / 'argparse' / 'msgids.txt' |
| 6407 | + |
| 6408 | +msgid_pattern = re.compile(r'msgid(.*?)(?:msgid_plural|msgctxt|msgstr)', re.DOTALL) |
| 6409 | +msgid_string_pattern = re.compile(r'"((?:\\"|[^"])*)"') |
| 6410 | + |
| 6411 | + |
| 6412 | +@requires_subprocess() |
| 6413 | +class TestTranslations(unittest.TestCase): |
| 6414 | + |
| 6415 | + def test_translations(self): |
| 6416 | + # Test messages extracted from the argparse module against a snapshot |
| 6417 | + skip_if_missing('i18n') |
| 6418 | + res = generate_po_file(stdout_only=False) |
| 6419 | + self.assertEqual(res.returncode, 0) |
| 6420 | + self.assertEqual(res.stderr, '') |
| 6421 | + msgids = extract_msgids(res.stdout) |
| 6422 | + snapshot = snapshot_path.read_text().splitlines() |
| 6423 | + self.assertListEqual(msgids, snapshot) |
| 6424 | + |
| 6425 | + |
| 6426 | +def generate_po_file(*, stdout_only=True): |
| 6427 | + res = subprocess.run([sys.executable, pygettext, |
| 6428 | + '--no-location', '-o', '-', argparse.__file__], |
| 6429 | + stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) |
| 6430 | + if stdout_only: |
| 6431 | + return res.stdout |
| 6432 | + return res |
| 6433 | + |
| 6434 | + |
| 6435 | +def extract_msgids(po): |
| 6436 | + msgids = [] |
| 6437 | + for msgid in msgid_pattern.findall(po): |
| 6438 | + msgid_string = ''.join(msgid_string_pattern.findall(msgid)) |
| 6439 | + msgid_string = msgid_string.replace(r'\"', '"') |
| 6440 | + if msgid_string: |
| 6441 | + msgids.append(msgid_string) |
| 6442 | + return sorted(msgids) |
| 6443 | + |
| 6444 | + |
| 6445 | +def update_translation_snapshots(): |
| 6446 | + contents = generate_po_file() |
| 6447 | + msgids = extract_msgids(contents) |
| 6448 | + snapshot_path.write_text('\n'.join(msgids)) |
| 6449 | + |
| 6450 | + |
6391 | 6451 | def tearDownModule():
|
6392 | 6452 | # Remove global references to avoid looking like we have refleaks.
|
6393 | 6453 | RFile.seen = {}
|
6394 | 6454 | WFile.seen = set()
|
6395 | 6455 |
|
6396 | 6456 |
|
6397 | 6457 | if __name__ == '__main__':
|
| 6458 | + # To regenerate translation snapshots |
| 6459 | + if len(sys.argv) > 1 and sys.argv[1] == '--snapshot-update': |
| 6460 | + update_translation_snapshots() |
| 6461 | + sys.exit(0) |
6398 | 6462 | unittest.main()
|
0 commit comments