todo-to-issue-action/tests/test_process_diff.py
Robert Alonso c643aecf02 refactor: optionally output log if _standardTest fails
Defaults True for backwards compatibility
2024-11-11 23:52:41 +00:00

114 lines
5.1 KiB
Python

import json
import os
import unittest
import tempfile
import subprocess
import io
import re
from TodoParser import TodoParser
from main import process_diff
class IssueUrlInsertionTest(unittest.TestCase):
orig_cwd = None
tempdir = None
diff_file = None
parser = None
def _setUp(self, diff_files):
# get current working directory
self.orig_cwd = os.getcwd()
# Create temporary directory to hold simulated filesystem.
self.tempdir = tempfile.TemporaryDirectory()
for diff_file in diff_files:
# run patch against the diff file to generate/update the simulated filesystem
subprocess.run(['patch', '-d', self.tempdir.name,
'-i', f'{os.getcwd()}/tests/{diff_file}'],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
check=True)
self.diff_file = open(f'tests/{diff_files[-1]}', 'r')
self.parser = TodoParser()
with open('syntax.json', 'r') as syntax_json:
self.parser.syntax_dict = json.load(syntax_json)
# change to the simulated filesystem directory
os.chdir(self.tempdir.name)
def _standardTest(self, expected_count, output_log_on_failure=True):
# create object to hold output
output = io.StringIO()
# process the diffs
self.raw_issues = process_diff(diff=self.diff_file, insert_issue_urls=True, parser=self.parser, output=output)
# make sure the number of issue URL comments inserted is as expected
self.assertEqual(output.getvalue().count('Issue URL successfully inserted'),
expected_count,
msg=(
'\nProcessing log\n--------------\n'+output.getvalue()
if output_log_on_failure else None))
# this test can take a while and, as far as TodoParser is concerned,
# redundant with the tests of test_todo_parser, so enable the means
# to skip it if desired
@unittest.skipIf(os.getenv('SKIP_PROCESS_DIFF_TEST', 'false') == 'true',
"Skipping because 'SKIP_PROCESS_DIFF_TEST' is 'true'")
def test_url_insertion(self):
self._setUp(['test_new.diff'])
self._standardTest(80)
# There is a known bug related to this issue, so until it's resolved
# this is an expected failure.
# See #225 and #224
@unittest.expectedFailure
def test_same_title_in_same_file(self):
self._setUp(['test_same_title_in_same_file.diff'])
self._standardTest(5)
# There is a known bug related to this issue, so until it's resolved
# this is an expected failure.
# See #229
@unittest.expectedFailure
def test_comment_suffix_after_source_line(self):
self._setUp(['test_comment_suffix_after_source_line.diff'])
self._standardTest(1)
# get details about the issue and source file
issue = self.raw_issues[0]
markers, _ = self.parser._get_file_details(issue.file_name)
with open(f'{self.tempdir.name}/{issue.file_name}', 'r') as source_file:
lines = source_file.read().splitlines()
# regex search the TODO comment and issue URL lines, such that groups are:
# 2: everything from start of line up to (but excluding) comment marker
# 3: comment marker
# 4: anything after comment marker and before identifier
# 1: encompasses all of the above
source_and_todo_line = re.search(fr'^((.*?)({markers[0]["pattern"]})(.*?))(?i:{issue.identifier}).*?{issue.title}',
lines[issue.start_line-1]).groups()
issue_url_line = re.search(fr'^((.*?)({markers[0]["pattern"]})(\s*))Issue URL: N/A$',
lines[issue.start_line]).groups()
# ensure Issue URL is aligned with the TODO above it by verifying
# that length of first group is equal for both lines
self.assertEqual(len(source_and_todo_line[0]), len(issue_url_line[0]), msg='\n'
+ f'Issue URL mis-alignment. {issue.identifier} begins at column '
+ f'{len(source_and_todo_line[0])+1} but\nissue URL begins at column '
+ f'{len(issue_url_line[0])+1}.\n'
+ '-------------------------------------------------------------------\n'
+ f'{lines[issue.start_line-1]}\n'
+ f'{lines[issue.start_line]}\n')
# ensure Issue URL line has only whitespace before the comment marker
self.assertRegex(issue_url_line[1], r'^\s*$', msg='\n'
+ 'Non-whitespace detected prior to comment marker for issue URL line!\n'
+ '-------------------------------------------------------------------\n'
+ f'{lines[issue.start_line]}\n')
def tearDown(self):
# return to original working directory to ensure we don't mess up other tests
os.chdir(self.orig_cwd)
# explicitly cleanup to avoid warning being printed about implicit cleanup
self.tempdir.cleanup()
self.tempdir = None