From c0235c87771447345cd43c67c9f3b9474e17855f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Kov=C3=A1cs?= Date: Wed, 17 Jul 2024 13:49:08 +0200 Subject: [PATCH 1/2] ISSUE-21: Enhance parsing in no-todos --- hooks/no_todos.py | 13 +++++++++++-- tests/test_no_todos.py | 28 ++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/hooks/no_todos.py b/hooks/no_todos.py index 1eeac81..34c6b69 100644 --- a/hooks/no_todos.py +++ b/hooks/no_todos.py @@ -27,8 +27,17 @@ def main(argv: Sequence[str] | None = None) -> int: result = 0 for filename in args.filenames: - with open(filename, encoding='utf-8') as f: - lines = f.readlines() + try: + with open(filename, encoding='utf-8-sig') as f: + lines = f.readlines() + except (UnicodeDecodeError, UnicodeError): + print(f'{filename}: cannot be read as UTF-8, trying UTF-16') + try: + with open(filename, encoding='utf-16') as f: + lines = f.readlines() + except (UnicodeDecodeError, UnicodeError): + print(f'{filename}: cannot be read as UTF-16, skipping it') + continue for tag in disallowed: for line in lines: diff --git a/tests/test_no_todos.py b/tests/test_no_todos.py index 3f5672c..888571e 100644 --- a/tests/test_no_todos.py +++ b/tests/test_no_todos.py @@ -18,7 +18,7 @@ def test_has_todo(tmpdir): # noinspection SpellCheckingInspection f.write_text('TODO: ¥eßűs, ∂éñ∂ þħïs!', encoding='utf-8') assert no_todos.main((str(f),)) == 1 - assert mocked_print.call_args_list[0].args[0] \ + assert mocked_print.call_args_list[-1].args[0] \ .endswith('todo.txt: contains TODO') @@ -42,7 +42,7 @@ def test_has_todo_but_excepted(tmpdir): # noinspection SpellCheckingInspection f.write_text('TODO: ฿űþ ñ∅™ þħïs!', encoding='utf-8') assert no_todos.main(('-e', 'todo.txt', str(f))) == 0 - assert mocked_print.call_args_list[0].args[0] \ + assert mocked_print.call_args_list[-1].args[0] \ .endswith('todo.txt: contains TODO, but is on the exception list') @@ -64,3 +64,27 @@ def test_complex_case(tmpdir): # noinspection SpellCheckingInspection f3.write_text('TODO: ¥eßűs, ∂éñ∂ þħïs!-3', encoding='utf-8') assert no_todos.main(('-e', 'todo_2.txt', str(f1), str(f2), str(f3))) == 2 + + +def test_non_utf_8(tmpdir): + with patch('builtins.print') as mocked_print: + f1 = tmpdir.join('todo_utf8_bom.txt') + # noinspection SpellCheckingInspection + f1.write_text('TODO: ¥eßűs, ∂éñ∂ þħïs!-1', encoding='utf-8-sig') + assert no_todos.main((str(f1),)) == 1 + for a in mocked_print.call_args_list: + assert not a.args[0].endswith( + 'todo_utf8_bom.txt: cannot be read as UTF-8, trying UTF-16' + ) + f2 = tmpdir.join('todo_utf16.txt') + # noinspection SpellCheckingInspection + f2.write_text('TODO: ¥eßűs, ∂éñ∂ þħïs!-1', encoding='utf-16') + assert no_todos.main((str(f1),str(f2))) == 2 + assert mocked_print.call_args_list[-2].args[0] \ + .endswith('todo_utf16.txt: cannot be read as UTF-8, trying UTF-16') + f3 = tmpdir.join('todo_greek.txt') + # noinspection SpellCheckingInspection + f3.write_text('TODO: Υeσΰς, δέηδ ΤΞΪΣ!-1', encoding='ISO-8859-7') + assert no_todos.main((str(f1),str(f2),str(f3))) == 2 + assert mocked_print.call_args_list[-1].args[0] \ + .endswith('todo_greek.txt: cannot be read as UTF-16, skipping it') From 5a3c99e8d03efd3d1d583f64bdd4ffde2877fe02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1niel=20Kov=C3=A1cs?= Date: Wed, 17 Jul 2024 13:49:20 +0200 Subject: [PATCH 2/2] ISSUE-21: Refactor tests checking output --- tests/test_cojira.py | 102 ++++++++++++++---------------- tests/test_commiticketing.py | 90 ++++++++++++++------------ tests/test_lint_commit_message.py | 50 ++++++++------- tests/test_no_boms.py | 34 +++++----- tests/test_no_todos.py | 8 +-- 5 files changed, 143 insertions(+), 141 deletions(-) diff --git a/tests/test_cojira.py b/tests/test_cojira.py index 6046cd9..2b3a108 100644 --- a/tests/test_cojira.py +++ b/tests/test_cojira.py @@ -1,11 +1,11 @@ from __future__ import annotations import json +import re import subprocess -import unittest from os import environ from typing import Any -from unittest.mock import call +from unittest.mock import patch from urllib import request from urllib.error import HTTPError from urllib.error import URLError @@ -461,7 +461,7 @@ def test_jira_pat_as_env_var(tmpdir): ( 'pseudo_commit_msg.txt', '-e=none', '-u=http://banana', '-p=$YYYJIRA_PAT', - ) + ), ) == 0 @@ -470,7 +470,7 @@ def test_version_empty_via_env_var(tmpdir): environ['EMPTY_VERSION'] = '' with ( tmpdir.as_cwd(), - unittest.mock.patch('builtins.print') as mocked_print, + patch('builtins.print') as mocked_print, ): exec_cmd('git', 'init') f = tmpdir.join('pseudo_commit_msg.txt') @@ -478,12 +478,14 @@ def test_version_empty_via_env_var(tmpdir): assert cojira.main( ( 'pseudo_commit_msg.txt', - f'-v=$EMPTY_VERSION', + '-v=$EMPTY_VERSION', '-u=http://banana', '-p=pat_on_the_back', ), ) == 0 - assert call('Ticket fix version not checked') \ - in mocked_print.mock_calls + assert mocked_print.call_args_list[-2].args[0] \ + .endswith('Ticket fix version not checked') + assert mocked_print.call_args_list[-1].args[0] \ + .endswith('Ticket is OK according to COJIRA rules') def test_version_multiple_via_env_var(tmpdir): @@ -491,7 +493,7 @@ def test_version_multiple_via_env_var(tmpdir): environ['EMPTY_VERSION'] = 'a,b,version' with ( tmpdir.as_cwd(), - unittest.mock.patch('builtins.print') as mocked_print, + patch('builtins.print') as mocked_print, ): exec_cmd('git', 'init') f = tmpdir.join('pseudo_commit_msg.txt') @@ -499,26 +501,34 @@ def test_version_multiple_via_env_var(tmpdir): assert cojira.main( ( 'pseudo_commit_msg.txt', - f'-v=$EMPTY_VERSION', + '-v=$EMPTY_VERSION', '-u=http://banana', '-p=pat_on_the_back', ), ) == 0 - assert call('Ticket fix version ("version") is allowed') \ - in mocked_print.mock_calls + assert mocked_print.call_args_list[-3].args[0] \ + .startswith('Ticket fix version ("version") is allowed') assert ( - call('\t(allowed versions are: ({\'a\', \'b\', \'version\'}))') \ - in mocked_print.mock_calls or - call('\t(allowed versions are: ({\'a\', \'version\', \'b\'}))') \ - in mocked_print.mock_calls or - call('\t(allowed versions are: ({\'version\', \'a\', \'b\'}))') \ - in mocked_print.mock_calls or - call('\t(allowed versions are: ({\'b\', \'a\', \'version\'}))') \ - in mocked_print.mock_calls or - call('\t(allowed versions are: ({\'b\', \'version\', \'a\'}))') \ - in mocked_print.mock_calls or - call('\t(allowed versions are: ({\'version\', \'b\', \'a\'}))') \ - in mocked_print.mock_calls + mocked_print.call_args_list[-2].args[0].endswith( + '\t(allowed versions are: ({\'a\', \'b\', \'version\'}))', + ) or + mocked_print.call_args_list[-2].args[0].endswith( + '\t(allowed versions are: ({\'a\', \'version\', \'b\'}))', + ) or + mocked_print.call_args_list[-2].args[0].endswith( + '\t(allowed versions are: ({\'version\', \'a\', \'b\'}))', + ) or + mocked_print.call_args_list[-2].args[0].endswith( + '\t(allowed versions are: ({\'b\', \'a\', \'version\'}))', + ) or + mocked_print.call_args_list[-2].args[0].endswith( + '\t(allowed versions are: ({\'b\', \'version\', \'a\'}))', + ) or + mocked_print.call_args_list[-2].args[0].endswith( + '\t(allowed versions are: ({\'version\', \'b\', \'a\'}))', + ) ) + assert mocked_print.call_args_list[-1].args[0] \ + .endswith('Ticket is OK according to COJIRA rules') @pytest.mark.parametrize( @@ -531,7 +541,6 @@ def test_version_multiple_via_env_var(tmpdir): texts=[ 'Lenient early exit, because no JIRA URI given', ], - alts=[], ), dict( e=4, @@ -541,7 +550,6 @@ def test_version_multiple_via_env_var(tmpdir): texts=[ 'Could not reify ticket from commit message', ], - alts=[], ), dict( e=3, @@ -552,10 +560,9 @@ def test_version_multiple_via_env_var(tmpdir): '-u=http://banana', ), texts=[ + '\t\\(allowed versions are: \\({\'not-this-version\'}\\)\\)', 'Ticket has no fix version, but it is expected', - '\t(allowed versions are: ({\'not-this-version\'}))', ], - alts=[], ), dict( e=1, @@ -563,12 +570,11 @@ def test_version_multiple_via_env_var(tmpdir): u=lambda _: MockedResponse(''), args=('pseudo_commit_msg.txt', '-u=http://banana'), texts=[ + '\t disallowed categories are: \\({\'done\'}\\)\\)', + '\t\\(allowed categories are: \\(\\),', + r'Ticket status category \("None"\) is not allowed', 'Ticket fix version not checked', - 'Ticket status category ("None") is not allowed', - '\t(allowed categories are: (),', - '\t disallowed categories are: ({\'done\'}))', ], - alts=[], ), dict( e=2, @@ -579,13 +585,9 @@ def test_version_multiple_via_env_var(tmpdir): '-u=http://banana', ), texts=[ - 'Fix version of ticket ("version") is not allowed', - ], - alts=[ - [ - '\t(allowed versions are: ({\'version2\', \'version3\'}))', - '\t(allowed versions are: ({\'version3\', \'version2\'}))', - ], + '\t\\(allowed versions are: \\({\'version[23]\',' + ' \'version[23]\'}\\)\\)', + r'Fix version of ticket \("version"\) is not allowed', ], ), dict( @@ -597,15 +599,11 @@ def test_version_multiple_via_env_var(tmpdir): '-u=http://banana', ), texts=[ - 'Checking ticket "ABC-123"', - 'Ticket fix version ("version") is allowed', 'Ticket is OK according to COJIRA rules', - ], - alts=[ - [ - '\t(allowed versions are: ({\'version2\', \'version\'}))', - '\t(allowed versions are: ({\'version\', \'version2\'}))', - ], + '\t\\(allowed versions are: \\({\'version2?\',' + ' \'version2?\'}\\)\\)', + r'Ticket fix version \("version"\) is allowed', + 'Checking ticket "ABC-123"', ], ), ], @@ -613,7 +611,7 @@ def test_version_multiple_via_env_var(tmpdir): def test_cojira_outputs(tmpdir, params): with ( tmpdir.as_cwd(), - unittest.mock.patch('builtins.print') as mocked_print, + patch('builtins.print') as mocked_print, ): if params['u'] is not None: cojira.request.urlopen = params['u'] @@ -621,10 +619,8 @@ def test_cojira_outputs(tmpdir, params): f = tmpdir.join('pseudo_commit_msg.txt') f.write_text(params['msg'], encoding='utf-8') assert cojira.main(params['args']) == params['e'] + index = -1 for t in params['texts']: - assert call(t) in mocked_print.mock_calls - for p in params['alts']: - assert ( - call(p[0]) in mocked_print.mock_calls or - call(p[1]) in mocked_print.mock_calls - ) + assert re.match(t, mocked_print.call_args_list[index].args[0]) \ + is not None + index -= 1 diff --git a/tests/test_commiticketing.py b/tests/test_commiticketing.py index efee4ee..d311464 100644 --- a/tests/test_commiticketing.py +++ b/tests/test_commiticketing.py @@ -2,10 +2,9 @@ import random import subprocess -import unittest from pathlib import Path from typing import Any -from unittest.mock import call +from unittest.mock import patch import pytest from typing_extensions import Buffer @@ -166,13 +165,13 @@ def test_get_prefix(tmpdir, params): def test_not_reified(tmpdir): - with unittest.mock.patch('builtins.print') as mocked_print: + with patch('builtins.print') as mocked_print: with tmpdir.as_cwd(): f = tmpdir.join('pseudo_commit_msg.txt') f.write_text('Abracadabra', encoding='utf-8') assert commiticketing.main((str(f),)) == 3 - assert call('Could not reify branch name.') \ - in mocked_print.mock_calls + assert mocked_print.call_args_list[-1].args[0] \ + .endswith('Could not reify branch name.') @pytest.mark.parametrize('branch_name', test_set_2) @@ -193,7 +192,7 @@ def test_out_of_scope_branch_default(tmpdir, branch_name): ], ) def test_out_of_scope_branch_non_default(tmpdir, params): - with unittest.mock.patch('builtins.print') as mocked_print: + with patch('builtins.print') as mocked_print: with tmpdir.as_cwd(): exec_cmd('git', 'init') exec_cmd('git', 'checkout', '-b', params['branch']) @@ -202,10 +201,11 @@ def test_out_of_scope_branch_non_default(tmpdir, params): assert commiticketing.main( ('-b', params['proc'], '-t', params['leveled'], str(f)), ) == 1 - assert call( + assert mocked_print.call_args_list[-1].args[0] \ + .endswith( f"You wanted to commit to a branch [{params['branch']}], " 'which does not correspond to the commiticketing setup.', - ) in mocked_print.mock_calls + ) @pytest.mark.parametrize( @@ -216,17 +216,18 @@ def test_out_of_scope_branch_non_default(tmpdir, params): ), ) def test_in_scope_mismatched_default(tmpdir, branch_name): - with unittest.mock.patch('builtins.print') as mocked_print: + with patch('builtins.print') as mocked_print: with tmpdir.as_cwd(): exec_cmd('git', 'init') exec_cmd('git', 'checkout', '-b', branch_name) f = tmpdir.join('pseudo_commit_msg.txt') f.write_text('Abracadabra', encoding='utf-8') assert commiticketing.main((str(f),)) == 2 - assert call( - f'[{branch_name}] does not correspond to branch naming ' - 'rules, consult guidelines.', - ) in mocked_print.mock_calls + assert mocked_print.call_args_list[-1].args[0] \ + .endswith( + f'[{branch_name}] does not correspond to branch naming ' + 'rules, consult guidelines.', + ) @pytest.mark.parametrize( @@ -264,22 +265,25 @@ def test_in_scope_mismatched_non_default(tmpdir, params): ) def test_prefix_if_not_there(tmpdir, branch_name): prefix = commiticketing.get_prefix(branch_name, ['user', 'backup']) - with tmpdir.as_cwd(): - with unittest.mock.patch('builtins.print') as mocked_print: - exec_cmd('git', 'init') - exec_cmd('git', 'checkout', '-b', branch_name) - f = tmpdir.join('pseudo_commit_msg.txt') - f.write_text('abracadabra', encoding='utf-8') - assert commiticketing.main((str(f),)) == 0 - assert call('Commiticketing did not change your subject line.') \ - not in mocked_print.mock_calls - assert call( + with ( + tmpdir.as_cwd(), + patch('builtins.print') as mocked_print, + ): + exec_cmd('git', 'init') + exec_cmd('git', 'checkout', '-b', branch_name) + f = tmpdir.join('pseudo_commit_msg.txt') + f.write_text('abracadabra', encoding='utf-8') + assert commiticketing.main((str(f),)) == 0 + assert not mocked_print.call_args_list[-1].args[0] \ + .endswith('Commiticketing did not change your subject line.') + assert mocked_print.call_args_list[-1].args[0] \ + .endswith( 'Commiticketing prefixed your subject line ' f'with [{prefix}: ] and made it sentence case' ' after.', - ) in mocked_print.mock_calls - with open(f) as msg: - assert msg.readline() == f'{prefix}: Abracadabra' + ) + with open(f) as msg: + assert msg.readline() == f'{prefix}: Abracadabra' @pytest.mark.parametrize( @@ -299,24 +303,26 @@ def test_prefix_if_not_there(tmpdir, branch_name): ) def test_prefix_not_doubling(tmpdir, params): prefix = commiticketing.get_prefix(params['branch'], ['user', 'backup']) - with tmpdir.as_cwd(): - with unittest.mock.patch('builtins.print') as mocked_print: - exec_cmd('git', 'init') - exec_cmd('git', 'checkout', '-b', params['branch']) - f = tmpdir.join('pseudo_commit_msg.txt') - f.write_text( - f"{prefix}: {params['msg']}", - encoding='utf-8', - ) - assert commiticketing.main((str(f),)) == 0 - with open(f) as msg: - assert msg.readline() == f'{prefix}: Abracadabra' + with ( + tmpdir.as_cwd(), + patch('builtins.print') as mocked_print, + ): + exec_cmd('git', 'init') + exec_cmd('git', 'checkout', '-b', params['branch']) + f = tmpdir.join('pseudo_commit_msg.txt') + f.write_text( + f"{prefix}: {params['msg']}", + encoding='utf-8', + ) + assert commiticketing.main((str(f),)) == 0 + with open(f) as msg: + assert msg.readline() == f'{prefix}: Abracadabra' if params['msg'] == 'Abracadabra': - assert call('Commiticketing did not change your subject line.') \ - in mocked_print.mock_calls + assert mocked_print.call_args_list[-1].args[0] \ + .endswith('Commiticketing did not change your subject line.') elif params['msg'] == 'abracadabra': - assert call('Commiticketing did not change your subject line.') \ - not in mocked_print.mock_calls + assert not mocked_print.call_args_list[-1].args[0] \ + .endswith('Commiticketing did not change your subject line.') @pytest.mark.parametrize( diff --git a/tests/test_lint_commit_message.py b/tests/test_lint_commit_message.py index c95ff38..cb82868 100644 --- a/tests/test_lint_commit_message.py +++ b/tests/test_lint_commit_message.py @@ -1,7 +1,6 @@ from __future__ import annotations -import unittest -from unittest.mock import call +from unittest.mock import patch import pytest @@ -9,23 +8,24 @@ def test_empty(tmpdir): - with unittest.mock.patch('builtins.print') as mocked_print: + with patch('builtins.print') as mocked_print: f = tmpdir.join('empty.txt') f.write_text('', encoding='utf-8') assert lint_commit_message.main((str(f),)) == 10 - assert call('The commit message must not be empty.') \ - in mocked_print.mock_calls + assert mocked_print.call_args_list[-1].args[0] \ + .endswith('The commit message must not be empty.') def test_no_empty_line_after_subject(tmpdir): - with unittest.mock.patch('builtins.print') as mocked_print: + with patch('builtins.print') as mocked_print: f = tmpdir.join('pseudo_commit_msg.txt') f.write_text('Subject\nBody\nBody2', encoding='utf-8') assert lint_commit_message.main((str(f),)) == 1 - assert call( - 'The subject line and body must be separated by an empty ' - 'line.', - ) in mocked_print.mock_calls + assert mocked_print.call_args_list[-1].args[0] \ + .endswith( + 'The subject line and body must be separated by an empty' + ' line.', + ) def test_empty_line_after_subject(tmpdir): @@ -35,7 +35,7 @@ def test_empty_line_after_subject(tmpdir): def test_subject_line_too_long(tmpdir): - with unittest.mock.patch('builtins.print') as mocked_print: + with patch('builtins.print') as mocked_print: f = tmpdir.join('pseudo_commit_msg.txt') f.write_text( '12345678901234567890123456789012345678901234567890' @@ -43,10 +43,11 @@ def test_subject_line_too_long(tmpdir): encoding='utf-8', ) assert lint_commit_message.main((str(f),)) == 2 - assert call( - 'The subject line must not be longer than 72, currently ' - 'it is 73.', - ) in mocked_print.mock_calls + assert mocked_print.call_args_list[-1].args[0] \ + .endswith( + 'The subject line must not be longer than 72, currently ' + 'it is 73.', + ) def test_subject_line_relaxed_not_too_long(tmpdir): @@ -74,12 +75,12 @@ def test_subject_line_relaxed_too_long(tmpdir): ['Hello!', 'Bye?', 'Oy.', 'Some (thing)', 'Hey /ho/'], ) def test_subject_line_ends_with_punctuation_and_regex(tmpdir, commit_msg): - with unittest.mock.patch('builtins.print') as mocked_print: + with patch('builtins.print') as mocked_print: f = tmpdir.join('pseudo_commit_msg.txt') f.write_text(commit_msg, encoding='utf-8') assert lint_commit_message.main(('-e', '\\W', str(f))) == 4 - assert call('The subject line must not end with punctuation.') \ - in mocked_print.mock_calls + assert mocked_print.call_args_list[-1].args[0] \ + .endswith('The subject line must not end with punctuation.') @pytest.mark.parametrize( @@ -87,12 +88,12 @@ def test_subject_line_ends_with_punctuation_and_regex(tmpdir, commit_msg): ['Hello!', 'Bye?', 'Oy.'], ) def test_subject_line_ends_forbidden_default(tmpdir, commit_msg): - with unittest.mock.patch('builtins.print') as mocked_print: + with patch('builtins.print') as mocked_print: f = tmpdir.join('pseudo_commit_msg.txt') f.write_text(commit_msg, encoding='utf-8') assert lint_commit_message.main((str(f),)) == 4 - assert call('The subject line must not end with punctuation.') \ - in mocked_print.mock_calls + assert mocked_print.call_args_list[-1].args[0] \ + .endswith('The subject line must not end with punctuation.') @pytest.mark.parametrize( @@ -106,7 +107,7 @@ def test_subject_line_ends_enabled_default(tmpdir, commit_msg): def test_body_line_too_long(tmpdir): - with unittest.mock.patch('builtins.print') as mocked_print: + with patch('builtins.print') as mocked_print: f = tmpdir.join('pseudo_commit_msg.txt') f.write_text( 'A\n\n' @@ -116,13 +117,14 @@ def test_body_line_too_long(tmpdir): encoding='utf-8', ) assert lint_commit_message.main((str(f),)) == 6 - assert call( + assert mocked_print.call_args_list[-1].args[0] \ + .endswith( 'Wrap lines of the message body after 120 characters, ' 'currently line 1 is 121 long. The line is: ' '"12345678901234567890123456789012345678901234567890' '12345678901234567890123456789012345678901234567890' '123456789012345678901".', - ) in mocked_print.mock_calls + ) def test_body_line_relaxed_not_too_long(tmpdir): diff --git a/tests/test_no_boms.py b/tests/test_no_boms.py index 018c003..4f303c9 100644 --- a/tests/test_no_boms.py +++ b/tests/test_no_boms.py @@ -1,15 +1,13 @@ from __future__ import annotations -import re -import unittest from pathlib import Path -from unittest.mock import call +from unittest.mock import patch from hooks import no_boms def test_utf32_bom_le(tmpdir): - with unittest.mock.patch('builtins.print') as mocked_print: + with patch('builtins.print') as mocked_print: f = Path(tmpdir.join('bom32le.txt')) f.write_bytes( b'\xff\xfe\x00\x00' @@ -21,12 +19,12 @@ def test_utf32_bom_le(tmpdir): b'\x86\x98\xe3\x86\x92\xe3\x86\x9d', ) assert no_boms.main((str(f),)) == 13 - assert re.match(r'^.*[\\/]bom32le\.txt: has a UTF-32 BOM \(LE\)$', - mocked_print.call_args.args[0]) is not None + assert mocked_print.call_args_list[-1].args[0] \ + .endswith('bom32le.txt: has a UTF-32 BOM (LE)') def test_utf32_bom_be(tmpdir): - with unittest.mock.patch('builtins.print') as mocked_print: + with patch('builtins.print') as mocked_print: f = Path(tmpdir.join('bom32be.txt')) f.write_bytes( b'\x00\x00\xfe\xff' @@ -38,12 +36,12 @@ def test_utf32_bom_be(tmpdir): b'\x86\x98\xe3\x86\x92\xe3\x86\x9d', ) assert no_boms.main((str(f),)) == 11 - assert re.match(r'^.*[\\/]bom32be\.txt: has a UTF-32 BOM \(BE\)$', - mocked_print.call_args.args[0]) is not None + assert mocked_print.call_args_list[-1].args[0] \ + .endswith('bom32be.txt: has a UTF-32 BOM (BE)') def test_utf16_bom_le(tmpdir): - with unittest.mock.patch('builtins.print') as mocked_print: + with patch('builtins.print') as mocked_print: f = Path(tmpdir.join('bom16le.txt')) f.write_bytes( b'\xff\xfe' @@ -55,12 +53,12 @@ def test_utf16_bom_le(tmpdir): b'\x86\x98\xe3\x86\x92\xe3\x86\x9d', ) assert no_boms.main((str(f),)) == 7 - assert re.match(r'^.*[\\/]bom16le\.txt: has a UTF-16 BOM \(LE\)$', - mocked_print.call_args.args[0]) is not None + assert mocked_print.call_args_list[-1].args[0] \ + .endswith('bom16le.txt: has a UTF-16 BOM (LE)') def test_utf16_bom_be(tmpdir): - with unittest.mock.patch('builtins.print') as mocked_print: + with patch('builtins.print') as mocked_print: f = Path(tmpdir.join('bom16be.txt')) f.write_bytes( b'\xfe\xff' @@ -72,12 +70,12 @@ def test_utf16_bom_be(tmpdir): b'\x86\x98\xe3\x86\x92\xe3\x86\x9d', ) assert no_boms.main((str(f),)) == 5 - assert re.match(r'^.*[\\/]bom16be\.txt: has a UTF-16 BOM \(BE\)$', - mocked_print.call_args.args[0]) is not None + assert mocked_print.call_args_list[-1].args[0] \ + .endswith('bom16be.txt: has a UTF-16 BOM (BE)') def test_utf8_bom_directly(tmpdir): - with unittest.mock.patch('builtins.print') as mocked_print: + with patch('builtins.print') as mocked_print: f = Path(tmpdir.join('bom8.txt')) f.write_bytes( b'\xef\xbb\xbf' @@ -89,8 +87,8 @@ def test_utf8_bom_directly(tmpdir): b'\x86\x98\xe3\x86\x92\xe3\x86\x9d', ) assert no_boms.main((str(f),)) == 3 - assert re.match(r'^.*[\\/]bom8\.txt: has a UTF-8 BOM$', - mocked_print.call_args.args[0]) is not None + assert mocked_print.call_args_list[-1].args[0] \ + .endswith('bom8.txt: has a UTF-8 BOM') def test_utf8_bom_via_encoding(tmpdir): diff --git a/tests/test_no_todos.py b/tests/test_no_todos.py index 888571e..62c83a3 100644 --- a/tests/test_no_todos.py +++ b/tests/test_no_todos.py @@ -74,17 +74,17 @@ def test_non_utf_8(tmpdir): assert no_todos.main((str(f1),)) == 1 for a in mocked_print.call_args_list: assert not a.args[0].endswith( - 'todo_utf8_bom.txt: cannot be read as UTF-8, trying UTF-16' + 'todo_utf8_bom.txt: cannot be read as UTF-8, trying UTF-16', ) f2 = tmpdir.join('todo_utf16.txt') # noinspection SpellCheckingInspection f2.write_text('TODO: ¥eßűs, ∂éñ∂ þħïs!-1', encoding='utf-16') - assert no_todos.main((str(f1),str(f2))) == 2 + assert no_todos.main((str(f1), str(f2))) == 2 assert mocked_print.call_args_list[-2].args[0] \ .endswith('todo_utf16.txt: cannot be read as UTF-8, trying UTF-16') f3 = tmpdir.join('todo_greek.txt') # noinspection SpellCheckingInspection f3.write_text('TODO: Υeσΰς, δέηδ ΤΞΪΣ!-1', encoding='ISO-8859-7') - assert no_todos.main((str(f1),str(f2),str(f3))) == 2 - assert mocked_print.call_args_list[-1].args[0] \ + assert no_todos.main((str(f1), str(f3), str(f2))) == 2 + assert mocked_print.call_args_list[-3].args[0] \ .endswith('todo_greek.txt: cannot be read as UTF-16, skipping it')