Files
pr-agent/tests/unittest/test_convert_to_markdown.py

273 lines
11 KiB
Python
Raw Normal View History

2023-07-06 00:21:08 +03:00
# Generated by CodiumAI
import textwrap
from unittest.mock import Mock
2024-07-03 08:47:59 +03:00
from pr_agent.algo.utils import PRReviewHeader, convert_to_markdown_v2
2024-02-05 09:20:36 +02:00
from pr_agent.tools.pr_description import insert_br_after_x_chars
2023-07-06 00:21:08 +03:00
"""
Code Analysis
Objective:
The objective of the 'convert_to_markdown' function is to convert a dictionary of data into a markdown-formatted text.
The function takes in a dictionary as input and recursively iterates through its keys and values to generate the
2023-07-06 00:21:08 +03:00
markdown text.
Inputs:
- A dictionary of data containing information about a pull request.
Flow:
- Initialize an empty string variable 'markdown_text'.
- Create a dictionary 'emojis' containing emojis for each key in the input dictionary.
- Iterate through the input dictionary:
- If the value is empty, continue to the next iteration.
- If the value is a dictionary, recursively call the 'convert_to_markdown' function with the value as input and
2023-07-06 00:21:08 +03:00
append the returned markdown text to 'markdown_text'.
- If the value is a list:
- If the key is 'code suggestions', add an additional line break to 'markdown_text'.
- Get the corresponding emoji for the key from the 'emojis' dictionary. If no emoji is found, use a dash.
- Append the emoji and key to 'markdown_text'.
- Iterate through the items in the list:
- If the item is a dictionary and the key is 'code suggestions', call the 'parse_code_suggestion' function with
2023-07-06 00:21:08 +03:00
the item as input and append the returned markdown text to 'markdown_text'.
- If the item is not empty, append it to 'markdown_text'.
- If the value is not 'n/a', get the corresponding emoji for the key from the 'emojis' dictionary. If no emoji is
2023-07-06 00:21:08 +03:00
found, use a dash. Append the emoji, key, and value to 'markdown_text'.
- Return 'markdown_text'.
Outputs:
- A markdown-formatted string containing the information from the input dictionary.
Additional aspects:
- The function uses recursion to handle nested dictionaries.
- The 'parse_code_suggestion' function is called for items in the 'code suggestions' list.
- The function uses emojis to add visual cues to the markdown text.
"""
class TestConvertToMarkdown:
# Tests that the function works correctly with a simple dictionary input
def test_simple_dictionary_input(self):
2024-02-08 20:14:25 +02:00
input_data = {'review': {
'estimated_effort_to_review_[1-5]': '1, because the changes are minimal and straightforward, focusing on a single functionality addition.\n',
'relevant_tests': 'No\n', 'possible_issues': 'No\n', 'security_concerns': 'No\n'}}
expected_output = textwrap.dedent(f"""\
{PRReviewHeader.REGULAR.value} 🔍
Here are some key observations to aid the review process:
<table>
<tr><td>&nbsp;<strong>Estimated effort to review</strong>: 1 🔵</td></tr>
<tr><td>🧪&nbsp;<strong>No relevant tests</strong></td></tr>
<tr><td>&nbsp;<strong>Possible issues</strong>: No
</td></tr>
<tr><td>🔒&nbsp;<strong>No security concerns identified</strong></td></tr>
</table>
""")
assert convert_to_markdown_v2(input_data).strip() == expected_output.strip()
def test_simple_dictionary_input_without_gfm_supported(self):
input_data = {'review': {
'estimated_effort_to_review_[1-5]': '1, because the changes are minimal and straightforward, focusing on a single functionality addition.\n',
'relevant_tests': 'No\n', 'possible_issues': 'No\n', 'security_concerns': 'No\n'}}
expected_output = textwrap.dedent("""\
## PR Reviewer Guide 🔍
Here are some key observations to aid the review process:
### ⏱️ Estimated effort to review: 1 🔵⚪⚪⚪⚪
2024-02-08 20:14:25 +02:00
### 🧪 No relevant tests
2024-02-08 20:14:25 +02:00
### Possible issues: No
### 🔒 No security concerns identified
""")
assert convert_to_markdown_v2(input_data, gfm_supported=False).strip() == expected_output.strip()
def test_key_issues_to_review(self):
input_data = {'review': {
'key_issues_to_review': [
{
'relevant_file' : 'src/utils.py',
'issue_header' : 'Code Smell',
'issue_content' : 'The function is too long and complex.',
'start_line': 30,
'end_line': 50,
}
]
}}
mock_git_provider = Mock()
reference_link = 'https://github.com/qodo/pr-agent/pull/1/files#diff-hashvalue-R174'
mock_git_provider.get_line_link.return_value = reference_link
expected_output = textwrap.dedent(f"""\
## PR Reviewer Guide 🔍
Here are some key observations to aid the review process:
<table>
<tr><td>&nbsp;<strong>Recommended focus areas for review</strong><br><br>
<a href='{reference_link}'><strong>Code Smell</strong></a><br>The function is too long and complex.
</td></tr>
</table>
""")
assert convert_to_markdown_v2(input_data, git_provider=mock_git_provider).strip() == expected_output.strip()
mock_git_provider.get_line_link.assert_called_with('src/utils.py', 30, 50)
def test_ticket_compliance(self):
input_data = {'review': {
'ticket_compliance_check': [
{
'ticket_url': 'https://example.com/ticket/123',
'ticket_requirements': '- Requirement 1\n- Requirement 2\n',
'fully_compliant_requirements': '- Requirement 1\n- Requirement 2\n',
'not_compliant_requirements': '',
'requires_further_human_verification': '',
}
]
}}
expected_output = textwrap.dedent("""\
## PR Reviewer Guide 🔍
Here are some key observations to aid the review process:
<table>
<tr><td>
**🎫 Ticket compliance analysis **
**[123](https://example.com/ticket/123) - Fully compliant**
Compliant requirements:
- Requirement 1
- Requirement 2
</td></tr>
</table>
""")
assert convert_to_markdown_v2(input_data).strip() == expected_output.strip()
def test_can_be_split(self):
input_data = {'review': {
'can_be_split': [
{
'relevant_files': [
'src/file1.py',
'src/file2.py'
],
'title': 'Refactoring',
},
{
'relevant_files': [
'src/file3.py'
],
'title': 'Bug Fix',
}
]
}
}
expected_output = textwrap.dedent("""\
## PR Reviewer Guide 🔍
Here are some key observations to aid the review process:
<table>
<tr><td>🔀 <strong>Multiple PR themes</strong><br><br>
<details><summary>
Sub-PR theme: <b>Refactoring</b></summary>
___
Relevant files:
- src/file1.py
- src/file2.py
___
</details>
<details><summary>
Sub-PR theme: <b>Bug Fix</b></summary>
___
Relevant files:
- src/file3.py
___
</details>
</td></tr>
</table>
""")
2024-07-03 08:47:59 +03:00
assert convert_to_markdown_v2(input_data).strip() == expected_output.strip()
2023-07-06 00:21:08 +03:00
# Tests that the function works correctly with an empty dictionary input
def test_empty_dictionary_input(self):
input_data = {}
2023-08-22 20:21:52 +03:00
expected_output = ''
2024-02-08 20:14:25 +02:00
2024-07-03 08:47:59 +03:00
assert convert_to_markdown_v2(input_data).strip() == expected_output.strip()
2024-02-05 09:20:36 +02:00
2024-02-08 20:14:25 +02:00
def test_dictionary_with_empty_dictionaries(self):
input_data = {'review': {}}
2024-02-08 20:14:25 +02:00
expected_output = ''
2024-07-03 08:47:59 +03:00
assert convert_to_markdown_v2(input_data).strip() == expected_output.strip()
2024-02-05 09:20:36 +02:00
class TestBR:
def test_br1(self):
2024-02-05 10:12:47 +02:00
file_change_description = '- Imported `FilePatchInfo` and `EDIT_TYPE` from `pr_agent.algo.types` instead of `pr_agent.git_providers.git_provider`.'
2024-02-05 09:20:36 +02:00
file_change_description_br = insert_br_after_x_chars(file_change_description)
2024-02-05 10:12:47 +02:00
expected_output = ('<li>Imported <code>FilePatchInfo</code> and <code>EDIT_TYPE</code> from '
'<code>pr_agent.algo.types</code> instead <br>of '
'<code>pr_agent.git_providers.git_provider</code>.')
2024-02-05 09:20:36 +02:00
assert file_change_description_br == expected_output
# print("-----")
# print(file_change_description_br)
def test_br2(self):
2024-02-08 20:14:25 +02:00
file_change_description = (
'- Created a - new -class `ColorPaletteResourcesCollection ColorPaletteResourcesCollection '
'ColorPaletteResourcesCollection ColorPaletteResourcesCollection`')
2024-02-05 09:20:36 +02:00
file_change_description_br = insert_br_after_x_chars(file_change_description)
2024-02-05 10:12:47 +02:00
expected_output = ('<li>Created a - new -class <code>ColorPaletteResourcesCollection </code><br><code>'
2024-02-05 13:00:57 +02:00
'ColorPaletteResourcesCollection ColorPaletteResourcesCollection '
'</code><br><code>ColorPaletteResourcesCollection</code>')
2024-02-05 09:20:36 +02:00
assert file_change_description_br == expected_output
# print("-----")
2024-02-05 10:12:47 +02:00
# print(file_change_description_br)
2024-02-05 13:00:57 +02:00
def test_br3(self):
file_change_description = 'Created a new class `ColorPaletteResourcesCollection` which extends `AvaloniaDictionary<ThemeVariant, ColorPaletteResources>` and implements aaa'
file_change_description_br = insert_br_after_x_chars(file_change_description)
assert file_change_description_br == ('Created a new class <code>ColorPaletteResourcesCollection</code> which '
'extends <br><code>AvaloniaDictionary<ThemeVariant, ColorPaletteResources>'
'</code> and implements <br>aaa')
# print("-----")
# print(file_change_description_br)