Skip to content

.pr_agent_auto_best_practices

root edited this page Mar 14, 2025 · 3 revisions

Pattern 1: Add error handling for edge cases that could cause runtime errors, particularly for division by zero, missing arguments, or invalid paths.

Example code before:

total_coverage = sum(covered) / sum(total_lines)

file_path = os.path.join(base_dir, user_input)
process_file(file_path)

Example code after:

total_lines = sum(total_lines)
total_coverage = sum(covered) / total_lines if total_lines > 0 else 0.0

file_path = os.path.join(base_dir, user_input)
if not os.path.exists(file_path):
    print(f"File not found: {file_path}")
    return
process_file(file_path)
Relevant past accepted suggestions:
Suggestion 1:

Add protection against division by zero when calculating coverage percentages

Add error handling for division by zero when calculating total_coverage in CoverageReportFilter.filter_report()

cover_agent/coverage/processor.py [244-246]

-total_coverage=(sum(cov.covered_lines for cov in filtered_coverage.values()) / 
-                     sum(cov.covered_lines + cov.missed_lines for cov in filtered_coverage.values()))
-                     if filtered_coverage else 0.0,
+total_lines = sum(len(cov.covered_lines) + len(cov.missed_lines) for cov in filtered_coverage.values())
+total_coverage = (sum(len(cov.covered_lines) for cov in filtered_coverage.values()) / total_lines) if total_lines > 0 else 0.0,

Suggestion 2:

Validate test folder path exists before attempting to use it

Add validation to ensure that test_folder exists when provided, similar to the validation done for test_file. This prevents silent failures when an invalid folder is specified.

cover_agent/utils.py [303-305]

 if hasattr(args, "test_folder") and args.test_folder:
+    test_folder_path = os.path.join(project_dir, args.test_folder)
+    if not os.path.exists(test_folder_path):
+        print(f"Test folder not found: `{test_folder_path}`, exiting.\n")
+        exit(-1)
     if args.test_folder not in root:
         continue

Suggestion 3:

Add error handling for missing command line arguments in test command parsing

Add error handling for the case when 'pytest' is found in the command but the '--' substring is not found, which would cause an IndexError.

cover_agent/CoverAgent.py [72-75]

 if 'pytest' in test_command:
     ind1 = test_command.index('pytest')
-    ind2 = test_command[ind1:].index('--')
-    new_command_line = f"{test_command[:ind1]}pytest {test_file_relative_path} {test_command[ind1 + ind2:]}"
+    try:
+        ind2 = test_command[ind1:].index('--')
+        new_command_line = f"{test_command[:ind1]}pytest {test_file_relative_path} {test_command[ind1 + ind2:]}"
+    except ValueError:
+        new_command_line = f"{test_command[:ind1]}pytest {test_file_relative_path}"

Suggestion 4:

Prevent potential division by zero error in token clipping function

In the clip_tokens function, handle the case where max_tokens is zero to prevent a potential division by zero error when calculating chars_per_token.

cover_agent/settings/token_handling.py [26-43]

 def clip_tokens(text: str, max_tokens: int, add_three_dots=True, num_input_tokens=None, delete_last_line=False) -> str:
     if not text:
         return text
 
     try:
         if num_input_tokens is None:
             encoder = TokenEncoder.get_token_encoder()
             num_input_tokens = len(encoder.encode(text))
         if num_input_tokens <= max_tokens:
             return text
-        if max_tokens < 0:
+        if max_tokens <= 0:
             return ""
 
         # calculate the number of characters to keep
         num_chars = len(text)
         chars_per_token = num_chars / num_input_tokens
         factor = 0.9  # reduce by 10% to be safe
         num_output_chars = int(factor * chars_per_token * max_tokens)

Suggestion 5:

Handle empty project root in relative path calculation

Ensure that the get_included_files method handles the case where project_root is not provided or is an empty string. This could lead to unexpected behavior when calculating relative paths.

cover_agent/UnitTestGenerator.py [231-240]

 def get_included_files(included_files: list, project_root: str = "", disable_tokens=False) -> str:
     if included_files:
         included_files_content = []
         file_names_rel = []
         for file_path in included_files:
             try:
                 with open(file_path, "r") as file:
                     included_files_content.append(file.read())
-                    file_path_rel = os.path.relpath(file_path, project_root)
+                    file_path_rel = os.path.relpath(file_path, project_root) if project_root else file_path
                     file_names_rel.append(file_path_rel)

Pattern 2: Fix variable reference issues where variables are used before assignment or incorrect variable names are referenced in code.

Example code before:

if variable is None:
    return

variable = get_value()

log.info(f"Value updated from {old_value} to {wrong_variable_name}")

Example code after:

variable = get_value()

if variable is None:
    return

log.info(f"Value updated from {old_value} to {variable}")
Relevant past accepted suggestions:
Suggestion 1:

Fix variable reference before assignment bug by removing unnecessary newline

The sourcefile variable is used before it's defined. Move the 'if sourcefile is None' check after the variable assignment to prevent NameError.

cover_agent/CoverageProcessor.py [241-244]

 sourcefile = root.find(f".//sourcefile[@name='{class_name}.java']") or root.find(f".//sourcefile[@name='{class_name}.kt']")
-
 if sourcefile is None:

Suggestion 2:

Ensure consistent state tracking by accessing coverage data from the appropriate object

Access coverage percentage from test_validator instead of test_gen to maintain consistent state tracking.

cover_agent/CoverAgent.py [194]

-+                failure_message = f"Reached maximum iteration limit without achieving desired diff coverage. Current Coverage: {round(self.test_gen.diff_coverage_percentage * 100, 2)}%"
++                failure_message = f"Reached maximum iteration limit without achieving desired diff coverage. Current Coverage: {round(self.test_validator.current_coverage * 100, 2)}%"

Suggestion 3:

Fix incorrect variable reference in logging statement to prevent undefined variable error

Fix incorrect variable reference in logging statement where coverage_percentages is used instead of new_coverage_percentages.

cover_agent/UnitTestValidator.py [565-567]

 self.logger.info(
-    f"Coverage for provided source file: {key} increased from {round(self.last_coverage_percentages[key] * 100, 2)} to {round(coverage_percentages[key] * 100, 2)}"
+    f"Coverage for provided source file: {key} increased from {round(self.last_coverage_percentages[key] * 100, 2)} to {round(new_coverage_percentages[key] * 100, 2)}"
 )

Pattern 3: Improve documentation clarity by providing specific examples, explaining command usage, and listing prerequisites in README files.

Example code before:

## Running the app

app-command --param ... --other-param ...

Example code after:

## Running the app

### Prerequisites
- Python 3.8+
- Docker

### Usage

app-command --param --other-param


Replace `<file-path>` with the path to your source file and `<value>` with your desired configuration.
Relevant past accepted suggestions:
Suggestion 1:

Provide more context and explanation for the command usage in the README

Consider adding a brief explanation of what the cover-agent command does and what the ellipsis (...) represent in the command example. This will help users understand how to properly use the command.

README.md [253-261]

 3. Run the app
     ```shell
    poetry run cover-agent \
-     --source-file-path ... \
-     ...
+     --source-file-path  \
+     [other_options...]
     ```
 
+Replace `` with the actual path to your source file.
+Add any other necessary options as described in the [Running the Code](#running-the-code) section.
+
 (i.e. prepending `poetry run` to your `cover-agent` commands --
-see the [Running the Code](#running-the-code) section above).
+see the [Running the Code](#running-the-code) section above for more details on available options).

Suggestion 2:

Add prerequisites section to clarify system requirements before running the app locally

Consider adding a note about potential system requirements or dependencies that might be needed before running the app locally. This could include Python version, operating system compatibility, or any other prerequisites.

README.md [243-258]

 ### Running the app locally from source
+
+#### Prerequisites
+- Python 3.x (specify minimum version)
+- Poetry
+
+#### Steps
 1. Install the dependencies
     ```shell
     poetry install
     ```
 2. Let Poetry manage / create the environment
     ```shell
    poetry shell
    ```
 
 3. Run the app
     ```shell
    poetry run cover-agent \
      --source-file-path ... \
      ...
     ```

[Auto-generated best practices - 2025-03-14]

Clone this wiki locally