|
12 | 12 |
|
13 | 13 | from __future__ import annotations |
14 | 14 |
|
| 15 | +import io |
15 | 16 | import os |
16 | 17 | import shutil |
| 18 | +import sys |
17 | 19 | from datetime import datetime |
| 20 | +from unittest.mock import patch |
18 | 21 |
|
19 | 22 | import pytest |
20 | 23 | from freezegun import freeze_time |
@@ -300,6 +303,137 @@ def test_more_than(self): |
300 | 303 | actual_content = f.read() |
301 | 304 | assert expected_content == actual_content |
302 | 305 |
|
| 306 | + def test_no_wrap_width_exclusive(self): |
| 307 | + self.cmd.input_files = [self.temp1] |
| 308 | + self.cmd.no_wrap = True |
| 309 | + self.cmd.width = 80 |
| 310 | + with pytest.raises(OptionError): |
| 311 | + self.cmd.finalize_options() |
| 312 | + |
| 313 | + def _capture_stdout(self): |
| 314 | + buf = io.BytesIO() |
| 315 | + |
| 316 | + class FakeStdout: |
| 317 | + buffer = buf |
| 318 | + |
| 319 | + return FakeStdout(), buf |
| 320 | + |
| 321 | + def test_stdout_output(self): |
| 322 | + self.cmd.input_files = [self.temp1] |
| 323 | + self.cmd.finalize_options() |
| 324 | + |
| 325 | + fake_stdout, buf = self._capture_stdout() |
| 326 | + with patch('sys.stdout', fake_stdout): |
| 327 | + self.cmd.run() |
| 328 | + |
| 329 | + content = buf.getvalue().decode('utf-8') |
| 330 | + assert 'msgid "other1"' in content |
| 331 | + assert 'msgstr "Other 1"' in content |
| 332 | + assert 'msgid "same"' in content |
| 333 | + |
| 334 | + def test_stdout_dash(self): |
| 335 | + self.cmd.input_files = [self.temp1] |
| 336 | + self.cmd.output_file = '-' |
| 337 | + self.cmd.finalize_options() |
| 338 | + |
| 339 | + fake_stdout, buf = self._capture_stdout() |
| 340 | + with patch('sys.stdout', fake_stdout): |
| 341 | + self.cmd.run() |
| 342 | + |
| 343 | + content = buf.getvalue().decode('utf-8') |
| 344 | + assert 'msgid "other1"' in content |
| 345 | + |
| 346 | + def test_same_string_no_conflict(self): |
| 347 | + self.cmd.input_files = [self.temp1, self.temp2] |
| 348 | + self.cmd.output_file = self.output_file |
| 349 | + self.cmd.finalize_options() |
| 350 | + self.cmd.run() |
| 351 | + |
| 352 | + with open(self.output_file, 'r') as f: |
| 353 | + content = f.read() |
| 354 | + |
| 355 | + same_block = [line for line in content.split('\n\n') if 'msgid "same"' in line] |
| 356 | + assert same_block |
| 357 | + block = same_block[0] |
| 358 | + assert 'fuzzy' not in block |
| 359 | + assert '#-#-#-#-#' not in block |
| 360 | + assert 'msgstr "Same"' in block |
| 361 | + |
| 362 | + def test_no_location(self): |
| 363 | + self.cmd.input_files = [self.temp1, self.temp2] |
| 364 | + self.cmd.output_file = self.output_file |
| 365 | + self.cmd.no_location = True |
| 366 | + self.cmd.finalize_options() |
| 367 | + self.cmd.run() |
| 368 | + |
| 369 | + with open(self.output_file, 'r') as f: |
| 370 | + content = f.read() |
| 371 | + |
| 372 | + assert '#: ' not in content |
| 373 | + assert 'msgid "other1"' in content |
| 374 | + |
| 375 | + def test_sort_output(self): |
| 376 | + self.cmd.input_files = [self.temp1, self.temp2] |
| 377 | + self.cmd.output_file = self.output_file |
| 378 | + self.cmd.sort_output = True |
| 379 | + self.cmd.finalize_options() |
| 380 | + self.cmd.run() |
| 381 | + |
| 382 | + with open(self.output_file, 'r') as f: |
| 383 | + content = f.read() |
| 384 | + |
| 385 | + msgid_positions = { |
| 386 | + 'almost_same': content.index('msgid "almost_same"'), |
| 387 | + 'other1': content.index('msgid "other1"'), |
| 388 | + 'other2': content.index('msgid "other2"'), |
| 389 | + 'other3': content.index('msgid "other3"'), |
| 390 | + 'other4': content.index('msgid "other4"'), |
| 391 | + 'same': content.index('msgid "same"'), |
| 392 | + } |
| 393 | + ordered = sorted(msgid_positions, key=msgid_positions.get) |
| 394 | + assert ordered == ['almost_same', 'other1', 'other2', 'other3', 'other4', 'same'] |
| 395 | + |
| 396 | + def test_single_input_file(self): |
| 397 | + self.cmd.input_files = [self.temp1] |
| 398 | + self.cmd.output_file = self.output_file |
| 399 | + self.cmd.finalize_options() |
| 400 | + self.cmd.run() |
| 401 | + |
| 402 | + with open(self.output_file, 'r') as f: |
| 403 | + content = f.read() |
| 404 | + |
| 405 | + assert 'msgid "other1"' in content |
| 406 | + assert 'msgid "other2"' in content |
| 407 | + assert 'msgid "same"' in content |
| 408 | + assert '#-#-#-#-#' not in content |
| 409 | + assert 'fuzzy' not in content |
| 410 | + |
| 411 | + def test_unique_exclusive_with_more_than_nonzero(self): |
| 412 | + self.cmd.input_files = [self.temp1, self.temp2] |
| 413 | + self.cmd.unique = True |
| 414 | + self.cmd.more_than = 0 |
| 415 | + self.cmd.finalize_options() |
| 416 | + |
| 417 | + def test_less_than_equivalent_to_unique(self): |
| 418 | + self.cmd.input_files = [self.temp1, self.temp2] |
| 419 | + self.cmd.output_file = self.output_file |
| 420 | + self.cmd.less_than = 2 |
| 421 | + self.cmd.finalize_options() |
| 422 | + self.cmd.run() |
| 423 | + |
| 424 | + with open(self.output_file, 'r') as f: |
| 425 | + less_than_content = f.read() |
| 426 | + |
| 427 | + self.cmd.less_than = None |
| 428 | + self.cmd.unique = True |
| 429 | + self.cmd.finalize_options() |
| 430 | + self.cmd.run() |
| 431 | + |
| 432 | + with open(self.output_file, 'r') as f: |
| 433 | + unique_content = f.read() |
| 434 | + |
| 435 | + assert less_than_content == unique_content |
| 436 | + |
303 | 437 |
|
304 | 438 | class TestMergeCatalog: |
305 | 439 |
|
@@ -532,3 +666,141 @@ def test_update_backup(self): |
532 | 666 | with open(self.temp_def + '.bac', 'r') as f: |
533 | 667 | actual_content = f.read() |
534 | 668 | assert before_content == actual_content |
| 669 | + |
| 670 | + def test_no_wrap_width_exclusive(self): |
| 671 | + self.cmd.input_files = [self.temp_def, self.temp_ref] |
| 672 | + self.cmd.output_file = self.output_file |
| 673 | + self.cmd.no_wrap = True |
| 674 | + self.cmd.width = 80 |
| 675 | + with pytest.raises(OptionError): |
| 676 | + self.cmd.finalize_options() |
| 677 | + |
| 678 | + def test_compendium_with_comment(self): |
| 679 | + self.cmd.input_files = [self.temp_def, self.temp_ref] |
| 680 | + self.cmd.output_file = self.output_file |
| 681 | + self.cmd.compendium = [self.compendium] |
| 682 | + self.cmd.no_fuzzy_matching = True |
| 683 | + self.cmd.finalize_options() |
| 684 | + self.cmd.run() |
| 685 | + |
| 686 | + with open(self.output_file, 'r') as f: |
| 687 | + content = f.read() |
| 688 | + |
| 689 | + assert f'#. {self.compendium}' in content |
| 690 | + assert 'msgid "word4"' in content |
| 691 | + assert 'msgstr "Word 4"' in content |
| 692 | + |
| 693 | + def test_compendium_does_not_overwrite_existing(self): |
| 694 | + self.cmd.input_files = [self.temp_def, self.temp_ref] |
| 695 | + self.cmd.output_file = self.output_file |
| 696 | + self.cmd.compendium = [self.compendium] |
| 697 | + self.cmd.no_fuzzy_matching = True |
| 698 | + self.cmd.no_compendium_comment = True |
| 699 | + self.cmd.finalize_options() |
| 700 | + self.cmd.run() |
| 701 | + |
| 702 | + with open(self.output_file, 'r') as f: |
| 703 | + content = f.read() |
| 704 | + |
| 705 | + blocks = content.split('\n\n') |
| 706 | + word1_block = next((b for b in blocks if 'msgid "word1"' in b), None) |
| 707 | + assert word1_block is not None |
| 708 | + assert 'msgstr "Word 1"' in word1_block |
| 709 | + assert 'Comp Word 1' not in word1_block |
| 710 | + |
| 711 | + def test_multiple_compendiums(self): |
| 712 | + compendium2 = f'{i18n_dir}/compendium2.po' |
| 713 | + try: |
| 714 | + with open(compendium2, 'wb') as f: |
| 715 | + cat = Catalog() |
| 716 | + cat.add('word3', string='Word 3 from comp2') |
| 717 | + pofile.write_po(f, cat) |
| 718 | + |
| 719 | + self.cmd.input_files = [self.temp_def, self.temp_ref] |
| 720 | + self.cmd.output_file = self.output_file |
| 721 | + self.cmd.compendium = [self.compendium, compendium2] |
| 722 | + self.cmd.no_fuzzy_matching = True |
| 723 | + self.cmd.no_compendium_comment = True |
| 724 | + self.cmd.finalize_options() |
| 725 | + self.cmd.run() |
| 726 | + |
| 727 | + with open(self.output_file, 'r') as f: |
| 728 | + content = f.read() |
| 729 | + |
| 730 | + assert 'msgstr "Word 4"' in content |
| 731 | + assert 'msgstr "Word 3 from comp2"' in content |
| 732 | + finally: |
| 733 | + if os.path.exists(compendium2): |
| 734 | + os.unlink(compendium2) |
| 735 | + |
| 736 | + def test_compendium_fills_empty_translation(self): |
| 737 | + compendium_with_word3 = f'{i18n_dir}/comp_word3.po' |
| 738 | + try: |
| 739 | + with open(compendium_with_word3, 'wb') as f: |
| 740 | + cat = Catalog() |
| 741 | + cat.add('word3', string='Word 3 comp') |
| 742 | + pofile.write_po(f, cat) |
| 743 | + |
| 744 | + self.cmd.input_files = [self.temp_def, self.temp_ref] |
| 745 | + self.cmd.output_file = self.output_file |
| 746 | + self.cmd.compendium = [compendium_with_word3] |
| 747 | + self.cmd.no_fuzzy_matching = True |
| 748 | + self.cmd.no_compendium_comment = True |
| 749 | + self.cmd.finalize_options() |
| 750 | + self.cmd.run() |
| 751 | + |
| 752 | + with open(self.output_file, 'r') as f: |
| 753 | + content = f.read() |
| 754 | + |
| 755 | + assert 'msgstr "Word 3 comp"' in content |
| 756 | + finally: |
| 757 | + if os.path.exists(compendium_with_word3): |
| 758 | + os.unlink(compendium_with_word3) |
| 759 | + |
| 760 | + def test_obsolete_messages(self): |
| 761 | + self.cmd.input_files = [self.temp_def, self.temp_ref] |
| 762 | + self.cmd.output_file = self.output_file |
| 763 | + self.cmd.no_fuzzy_matching = True |
| 764 | + self.cmd.finalize_options() |
| 765 | + self.cmd.run() |
| 766 | + |
| 767 | + with open(self.output_file, 'r') as f: |
| 768 | + content = f.read() |
| 769 | + |
| 770 | + assert '#~ msgid' not in content |
| 771 | + |
| 772 | + extra_def = f'{i18n_dir}/extra_def.po' |
| 773 | + try: |
| 774 | + with open(extra_def, 'wb') as f: |
| 775 | + cat = Catalog() |
| 776 | + cat.add('word1', string='Word 1') |
| 777 | + cat.add('old_word', string='Old Word') |
| 778 | + pofile.write_po(f, cat) |
| 779 | + |
| 780 | + self.cmd.input_files = [extra_def, self.temp_ref] |
| 781 | + self.cmd.finalize_options() |
| 782 | + self.cmd.run() |
| 783 | + |
| 784 | + with open(self.output_file, 'r') as f: |
| 785 | + content = f.read() |
| 786 | + |
| 787 | + assert '#~ msgid "old_word"' in content |
| 788 | + assert '#~ msgstr "Old Word"' in content |
| 789 | + finally: |
| 790 | + if os.path.exists(extra_def): |
| 791 | + os.unlink(extra_def) |
| 792 | + |
| 793 | + def test_compendium_not_applied_for_absent_messages(self): |
| 794 | + self.cmd.input_files = [self.temp_def, self.temp_ref] |
| 795 | + self.cmd.output_file = self.output_file |
| 796 | + self.cmd.compendium = [self.compendium] |
| 797 | + self.cmd.no_fuzzy_matching = True |
| 798 | + self.cmd.no_compendium_comment = True |
| 799 | + self.cmd.finalize_options() |
| 800 | + self.cmd.run() |
| 801 | + |
| 802 | + with open(self.output_file, 'r') as f: |
| 803 | + content = f.read() |
| 804 | + |
| 805 | + active_blocks = content.split('#~')[0] |
| 806 | + assert 'word5' not in active_blocks |
0 commit comments