def get_transifex_command(): """Return an instance of the Transifex Django command that works in all Django versions. After Django 2.0+, attempting to run `call_command(command, 'subcommand', option=value)` with `option` not being defined on the main command results to a TypeError, e.g. Unknown option(s) for transifex command: dry_run This is solved by adding all possible options to the command's `stealth_options` attribute. """ command = Command() command.stealth_options = ( # Migrate 'files', 'path', 'text', 'save_policy', 'review_policy', 'mark_policy', 'verbose', # Push 'extension', 'append_tags', 'with_tags_only', 'without_tags_only', 'dry_run', 'symlinks', # Invalidate 'purge', ) return command
def test_replace_save_string_review(mock_find_files, mock_read, mock_prompt_file, mock_prompt_string, mock_save_file, mock_prompt_to_start1): mock_find_files.return_value = [ TranslatableFile('dir1/dir2', '1.html', 'locdir1'), TranslatableFile('dir4/dir5', '1.txt', 'locdir1'), ] mock_read.side_effect = [ HTML_SAMPLE_1, # 1.html HTML_SAMPLE_2, # 1.txt ] command = Command() call_command(command, 'migrate', save_policy='replace', review_policy='string') assert isinstance(command.subcommands['migrate'].executor.save_policy, ReplaceSavePolicy) assert isinstance(command.subcommands['migrate'].executor.review_policy, StringReviewPolicy) assert mock_prompt_file.call_count == 0 assert mock_prompt_string.call_count == 13 # The path and content that reached the save object # should have the correct values assert mock_save_file.call_args[0][0] == 'dir1/dir2/1.html' migration_compile = mock_save_file.call_args[0][1] assert migration_compile() == HTML_COMPILED_1
def test_backup_save_string_review(mock_find_files, mock_read, mock_prompt_file, mock_prompt_string, mock_save_file, mock_prompt_to_start1): mock_find_files.return_value = [ TranslatableFile('dir1/dir2', '1.html', 'locdir1'), TranslatableFile('dir4/dir5', '1.txt', 'locdir1'), ] mock_read.side_effect = [ HTML_SAMPLE_1, # 1.html HTML_SAMPLE_2, # 1.txt ] command = Command() call_command(command, 'migrate', save_policy='backup', review_policy='string') assert isinstance(command.subcommands['migrate'].executor.save_policy, BackupSavePolicy) assert isinstance(command.subcommands['migrate'].executor.review_policy, StringReviewPolicy) assert mock_prompt_file.call_count == 0 assert mock_prompt_string.call_count == 13 # 11 migrated strings # The path and content that reached the save object # should have the correct values, one for the backup and one for # the new content assert mock_save_file.call_args_list[0][0][0] == 'dir1/dir2/1.html.bak' original_content_getter = mock_save_file.call_args_list[0][0][1] assert original_content_getter() == HTML_SAMPLE_1 assert mock_save_file.call_args_list[1][0][0] == 'dir1/dir2/1.html' migration_compile = mock_save_file.call_args_list[1][0][1] assert migration_compile() == HTML_COMPILED_1
def test_no_detection_for_non_transifex(mock_find_files, mock_read, mock_push_strings): """No strings should be detected if a format other than Transifex Native is used in Python files and templates. """ mock_find_files.return_value = [ # 2 files with valid extension but no translatable content TranslatableFile('dir4/dir5', 'empty.py', 'locdir1'), TranslatableFile('dir4/dir5', 'empty.txt', 'locdir1'), ] mock_read.side_effect = [ # empty.py - shouldn't detect any strings as non-transifex PYTHON_TEMPLATE.format( _import='from django.utils.translation import ugettext_lazy as _', call1='_', call2='_', string1=u'A Django string', string2=u'Another Django string', ), # empty.txt - shouldn't detect any strings as non-transifex ( u'{% load i18n %}\n' u'{% trans "A Django string %}\n' u'{% blocktrans %}Another Django string{% endblocktrans %}', ), ] command = Command() call_command(command, 'push', domain='djangojs') # command.string_collection.strings is like: {<key>: <SourceString>} found = command.subcommands['push'].string_collection.strings.values() assert set(found) == set([])
def compare(expected): """Run the command and compare the detected strings with the expected ones. :param list expected: a list of SourceString objects """ command = Command() call_command(command, 'push') # command.string_collection.strings is like: {<key>: <SourceString>} found = command.subcommands['push'].string_collection.strings.values() assert set(found) == set(expected)
def test_python_parsing_no_strings(mock_extract, mock_find_files): mock_extract.return_value = [] mock_find_files.return_value = [ TranslatableFile('dir1', '1.py', 'locdir1'), TranslatableFile('dir1/dir2', '2.py', 'locdir1'), TranslatableFile('dir1/dir3', '3.py', 'locdir1'), ] command = Command() call_command(command, 'push') # command.string_collection.strings is like: {<key>: <SourceString>} found = command.subcommands['push'].string_collection.strings.values() assert set(found) == set([])
def test_python_parsing_raises_unicode_error(mock_read, mock_find_files): o = b'\x00\x00' mock_read.side_effect = UnicodeDecodeError('funnycodec', o, 1, 2, 'This is just a fake reason!') mock_find_files.return_value = [ TranslatableFile('dir1', '1.py', 'locdir1'), ] command = Command() call_command(command, 'push') # command.string_collection.strings is like: {<key>: <SourceString>} found = command.subcommands['push'].string_collection.strings.values() assert set(found) == set([])
def test_dry_run_save_none_review(mock_find_files, mock_read, mock_prompt_to_start1): mock_find_files.return_value = [ TranslatableFile('dir1/dir2', '1.html', 'locdir1'), TranslatableFile('dir4/dir5', '1.txt', 'locdir1'), ] mock_read.side_effect = [ HTML_SAMPLE_1, # 1.html HTML_SAMPLE_2, # 1.txt, ] command = Command() call_command(command, 'migrate', save_policy='none', review_policy='none') assert isinstance(command.subcommands['migrate'].executor.save_policy, NoopSavePolicy) assert isinstance(command.subcommands['migrate'].executor.review_policy, NoopReviewPolicy)
def test_dry_run_save_none_review0(mock_cur_dir, mock_read, mock_prompt_to_start1): mock_cur_dir.return_value = 'dir1/dir2' mock_read.side_effect = [ HTML_SAMPLE_1, # 1.html ] command = Command() call_command(command, 'migrate', save_policy='none', review_policy='none', files=['1.html']) assert isinstance(command.subcommands['migrate'].executor.save_policy, NoopSavePolicy) assert isinstance(command.subcommands['migrate'].executor.review_policy, NoopReviewPolicy)
def test_text_migration_python_code(mock_echo): """Test the mode that migrates directly given text instead of files (Python/gettext code).""" command = Command() call_command(command, 'migrate', text=PYTHON_SAMPLE) expected = Color.format( '\n[high]Transifex Native syntax:[end]\n[green]{}[end]'.format( PYTHON_SAMPLE_MIGRATED)) native = Color.format(mock_echo.call_args_list[1][0][0]) assert expected == native # Make sure it's idempotent mock_echo.reset_mock() call_command(command, 'migrate', text=PYTHON_SAMPLE_MIGRATED) actual = Color.format(mock_echo.call_args_list[1][0][0]) assert expected == actual
def test_text_migration_template_code(mock_echo): """Test the mode that migrates directly given text instead of files (Django HTML templates).""" command = Command() call_command(command, 'migrate', text=DJANGO_TEMPLATE) expected = Color.format( '\n[high]Transifex Native syntax:[end]\n[green]{}[end]'.format( TRANSIFEX_TEMPLATE)) actual = Color.format(mock_echo.call_args_list[1][0][0]) assert expected == actual # Make sure it's idempotent mock_echo.reset_mock() call_command(command, 'migrate', text=TRANSIFEX_TEMPLATE) actual = Color.format(mock_echo.call_args_list[1][0][0]) assert expected == actual
def test_new_file_save_file_review(mock_find_files, mock_read, mock_prompt_file, mock_prompt_string, mock_save_file, mock_prompt_to_start1): mock_find_files.return_value = [ TranslatableFile('dir1/dir2', '1.html', 'locdir1'), TranslatableFile('dir4/dir5', '1.txt', 'locdir1'), TranslatableFile('dir4/dir5', '1.py', 'locdir1'), ] mock_read.side_effect = [ HTML_SAMPLE_1, # 1.html HTML_SAMPLE_2, # 1.txt PYTHON_SAMPLE, # 1.py ] command = Command() call_command(command, 'migrate', save_policy='new', review_policy='file') assert isinstance(command.subcommands['migrate'].executor.save_policy, NewFileSavePolicy) assert isinstance(command.subcommands['migrate'].executor.review_policy, FileReviewPolicy) # The first FileMigration instance that reached the review object # should compile to the proper Native syntax (1.html) file_migration1 = mock_prompt_file.call_args_list[0][0][0] assert file_migration1.compile() == HTML_COMPILED_1 # The same for 1.py file_migration2 = mock_prompt_file.call_args_list[1][0][0] assert file_migration2.compile() == PYTHON_SAMPLE_MIGRATED # No string review should have taken place assert mock_prompt_string.call_count == 0 # The path and content that reached the save object # should have the correct values assert mock_save_file.call_args_list[0][0][0] == 'dir1/dir2/1__native.html' migration_compile = mock_save_file.call_args_list[0][0][1] assert migration_compile() == HTML_COMPILED_1 assert mock_save_file.call_args_list[1][0][0] == 'dir4/dir5/1__native.py' migration_compile = mock_save_file.call_args_list[1][0][1] assert migration_compile() == PYTHON_SAMPLE_MIGRATED