Skip to content

ci: enforce 80% statement coverage gate#1286

Open
spoorcc wants to merge 8 commits into
mainfrom
claude/bestpractices-silver-badge-4zmhea
Open

ci: enforce 80% statement coverage gate#1286
spoorcc wants to merge 8 commits into
mainfrom
claude/bestpractices-silver-badge-4zmhea

Conversation

@spoorcc

@spoorcc spoorcc commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Add fail_under = 80 to [tool.coverage.report] in pyproject.toml and
run coverage report --fail-under=80 in CI before generating the XML
report. Satisfies the OpenSSF silver badge test_statement_coverage80
criterion.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01JnDFTrUYv86A6HGgZ1qwMa

Summary by CodeRabbit

  • Documentation

    • Added governance documentation describing roles, decision-making, and access continuity.
    • Expanded the documentation landing page with a roadmap and governance sections.
    • Updated the security policy to support public reporter credit with an anonymity option.
  • Chores

    • Added a CI coverage gate that fails builds when overall coverage drops below 80%.
  • Tests

    • Significantly expanded unit/pytest coverage across commands, reporters (including SARIF/Jenkins), diff/patch behavior, and terminal/output utilities.

claude added 4 commits June 17, 2026 17:32
Add fail_under = 80 to [tool.coverage.report] in pyproject.toml and
run coverage report --fail-under=80 in CI before generating the XML
report. Satisfies the OpenSSF silver badge test_statement_coverage80
criterion.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JnDFTrUYv86A6HGgZ1qwMa
Single page satisfies three OpenSSF silver badge criteria:
governance (decision-making model), roles_responsibilities, and
access_continuity. Wired into the Explanation toctree.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JnDFTrUYv86A6HGgZ1qwMa
Explicit credit commitment satisfies the OpenSSF silver badge
vulnerability_report_credit criterion.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JnDFTrUYv86A6HGgZ1qwMa
Placeholder satisfies the OpenSSF silver badge documentation_roadmap
criterion. Content will be extended later.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JnDFTrUYv86A6HGgZ1qwMa
@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@spoorcc, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 18 minutes and 24 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan refill rate.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, the refill rate gradually slows as usage increases. The highest same-day bursts are limited more strictly.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9f490706-cde2-472e-a6c2-830359ec7911

📥 Commits

Reviewing files that changed from the base of the PR and between b330530 and fff2b75.

📒 Files selected for processing (17)
  • doc/_ext/latex_tabs.py
  • tests/test_check_reporters.py
  • tests/test_check_stdout_reporter.py
  • tests/test_commands_common.py
  • tests/test_commands_diff.py
  • tests/test_commands_format_patch.py
  • tests/test_commands_freeze.py
  • tests/test_commands_misc.py
  • tests/test_commands_update_patch.py
  • tests/test_jenkins_reporter.py
  • tests/test_sarif_reporter.py
  • tests/test_screen.py
  • tests/test_stdout_reporter.py
  • tests/test_superproject_and_version.py
  • tests/test_svnsubproject.py
  • tests/test_svnsuperproject.py
  • tests/test_terminal_prompt.py

Walkthrough

The PR enforces an 80% code coverage minimum via pyproject.toml and CI workflow, introduces comprehensive unit test coverage for reporter implementations, superproject classes, command utilities, and terminal UI components, adds governance and roadmap documentation pages, and updates the security disclosure policy to explicitly credit reporters.

Changes

Coverage Configuration, Documentation, and Security Policy

Layer / File(s) Summary
Coverage threshold configuration
pyproject.toml, .github/workflows/test.yml
fail_under = 80 added to [tool.coverage.report]; test workflow gains a coverage report --fail-under=80 step that fails the job if coverage is below 80%.
Governance, roadmap docs, and security policy
doc/explanation/governance.rst, doc/reference/roadmap.rst, doc/index.rst, SECURITY.md
New governance.rst describes decision-making, roles, and access continuity. New roadmap.rst stub links to GitHub issues. Both wired into doc/index.rst toctrees. SECURITY.md closing acknowledgement replaced with policy crediting reporters by name in the advisory and changelog, with an opt-out for anonymity.

SuperProject Implementation Tests

Layer / File(s) Summary
GitSuperProject behavior tests
tests/test_gitsuperproject.py
Covers check() delegation to GitLocalRepo, get_sub_project() instantiation, ignored_files() with path resolution and traversal checks, has_local_changes_in_dir() delegation, username/email fallback behavior, file revision and eol preferences delegation, and diff() modes with/without new revision including untracked patch concatenation.
SvnSuperProject behavior tests
tests/test_svnsuperproject.py
Covers check() delegation to SvnRepo.is_svn(), get_sub_project() delegation, ignored_files() and has_local_changes_in_dir() delegation, username/email fallback with getpass integration, file revision and eol_preferences delegation, diff() modes for new vs. existing revisions, and import_projects() externals handling.
SvnSubProject parsing and Version field tests
tests/test_svnsubproject.py, tests/test_superproject_and_version.py
Expands SvnSubProject._parse_file_pattern (zero/single/multiple globs), _determine_what_to_fetch (tag/trunk/branch routing, explicit revision skip), check() delegation, and branch/revision listing. Adds Version.field tuple selection and NoVcsSuperProject deterministic behavior coverage (constant returns, empty-string outputs, import error, username/email fallback).

Reporter Implementation Tests

Layer / File(s) Summary
JenkinsReporter and CodeClimateReporter tests
tests/test_check_reporters.py, tests/test_jenkins_reporter.py
Covers add_issue() append behavior, severity-to-string conversion, project name inclusion, JSON dump output, manifest location-based field population (lineStart/columnStart/columnEnd), and CodeClimateReporter's severity mapping and deterministic fingerprint generation.
SarifReporter and CheckStdoutReporter tests
tests/test_sarif_reporter.py, tests/test_check_stdout_reporter.py
Validates severity-to-SARIF-level mapping, add_issue() result appending with level/rule_id, JSON dump output, and inherited report-generation methods (unfetched_project, unavailable_project_version, pinned_but_out_of_date_project, out_of_date_project, local_changes, up_to_date_project) with log message content and call-count assertions.
StdoutReporter dependencies field tests
tests/test_stdout_reporter.py
Adds two test cases validating add_project() behavior when meta.dependencies is present, asserting dependency-related field labels are logged and a dependencies section header is emitted.

Command Implementation Tests

Layer / File(s) Summary
Command common helpers tests
tests/test_commands_common.py
Covers check_sub_manifests() with mock ProjectEntry/manifest/submanifest objects across five scenarios (no-warning and warning paths) and _make_recommendation() warning content including project name and submanifest path.
Diff command tests
tests/test_commands_diff.py
Covers Diff._parse_revs() parsing for empty/single/two rev formats, Diff._rev_msg() output formatting, and Diff.__call__() error handling (no-VCS superproject, missing project destination, missing old revision) plus success paths for writing patches and logging no-diff messages.
FormatPatch command tests
tests/test_commands_format_patch.py, tests/test_commands_misc.py
Validates _determine_target_patch_type() routing for Git/SVN/other subprojects and FormatPatch.__call__() control flow: no-error when no projects, warning-and-continue when no patch files, RuntimeError deferred until end of loop.
Freeze command tests
tests/test_commands_freeze.py
Covers scenarios: no-project no-dump, version return dumps manifest, None return with/without on_disk_version logs appropriate messages, RuntimeError propagation, and backup behavior (NoVcsSuperProject creates .backup, VCS does not).
UpdatePatch command tests
tests/test_commands_update_patch.py, tests/test_commands_misc.py
Covers UpdatePatch.__call__() routing (rejects non-VCS, warns on SVN), no-projects success, _process_project() early-return warnings, and _update_patch() behavior (write on non-empty, no-write on empty with message, path traversal detection).
Environment, Init, Validate command tests
tests/test_commands_misc.py
Covers Environment version output and type-specific tool info, Init template creation vs. overwrite with warnings, and Validate manifest loading/validation reporting.

Terminal and UI Tests

Layer / File(s) Summary
Screen rendering and terminal prompt tests
tests/test_screen.py, tests/test_terminal_prompt.py
Covers erase_last_line() TTY vs non-TTY behavior, Screen lifecycle (first draw without cursor movement, subsequent draws with up+clear, clear() with/without content, _line_count updates), _ghost_handle_backspace() and _ghost_handle_char() buffer mutations, and ANSI escape output for ghost text and character echoing.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • dfetch-org/dfetch#960: The PR adds new unit tests for dfetch.commands.common._make_recommendation/check_sub_manifests, and the retrieved PR directly modifies _make_recommendation's logging output pathway.
  • dfetch-org/dfetch#1017: The PR's newly added tests/test_stdout_reporter.py assertions around metadata.dependencies directly target behavior changes in retrieved PR #1017.
  • dfetch-org/dfetch#1070: The PR adds/validates reporter output message formatting in new unit tests (e.g., tests/test_check_reporters.py), which depend on underlying issue description string changes in dfetch/reporting/check/reporter.py from retrieved PR #1070.

Suggested labels

testing

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 62.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: enforcing an 80% statement coverage gate in CI, which is the primary objective of the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/bestpractices-silver-badge-4zmhea

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tests for check_sub_manifests and _make_recommendation covering the
warning logic for submanifest projects not present in the parent
manifest.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JnDFTrUYv86A6HGgZ1qwMa
# mypy: ignore-errors
# flake8: noqa

from unittest.mock import MagicMock, Mock, call, patch

from unittest.mock import MagicMock, Mock, call, patch

import pytest
New test files covering previously under-tested modules:
- commands/diff, freeze, format_patch, update_patch, misc
- reporting/check: sarif_reporter, jenkins_reporter, stdout_reporter
- project: gitsuperproject, svnsuperproject, svnsubproject
- terminal: screen, prompt
- superproject and version helpers

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JnDFTrUYv86A6HGgZ1qwMa
# mypy: ignore-errors
# flake8: noqa

import json
import json
from unittest.mock import MagicMock, Mock, mock_open, patch

import pytest

import argparse
from pathlib import Path
from unittest.mock import MagicMock, Mock, patch

import argparse
from pathlib import Path
from unittest.mock import MagicMock, Mock, patch

import argparse
from pathlib import Path
from unittest.mock import MagicMock, Mock, call, patch
import pathlib
from unittest.mock import MagicMock, Mock, patch

import pytest
# mypy: ignore-errors
# flake8: noqa

import json
# mypy: ignore-errors
# flake8: noqa

import json
Adds one test covering the list_tool_info() loop in environment.py,
bringing total coverage to 80.19%.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JnDFTrUYv86A6HGgZ1qwMa
@spoorcc

spoorcc commented Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
tests/test_jenkins_reporter.py (1)

85-89: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Tighten _class assertion to prevent false positives.

The current check allows many invalid values because it only checks for one of two substrings. Assert the exact expected _class value (or exact schema shape) so this test actually guards reporter output structure.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_jenkins_reporter.py` around lines 85 - 89, The assertion in the
test_report_has_correct_class_key function uses loose substring checks that
allow invalid values to pass. Replace the current assertion that checks for
"issues" or "jenkins" substrings with an exact equality check against the
specific expected value for the _class field, ensuring the test properly
validates the reporter's output schema rather than allowing partial matches that
could be false positives.
tests/test_check_reporters.py (1)

1-170: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Split mixed reporter tests into module-mirrored files.

tests/test_check_reporters.py mixes tests for jenkins_reporter and code_climate_reporter in a single non-mirrored filename. Please split/rename into module-aligned files (for example, tests/test_code_climate_reporter.py) to match repository test naming policy and keep ownership clear.

As per coding guidelines, "tests/test_*.py: Use pytest for unit tests; test files should mirror module names (e.g., tests/test_manifest.py for dfetch/manifest.py)."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_check_reporters.py` around lines 1 - 170, Split the mixed test
file tests/test_check_reporters.py into two separate module-aligned files
following the repository naming policy. Create tests/test_jenkins_reporter.py
containing all test functions prefixed with test_jenkins
(test_jenkins_reporter_init_creates_empty_issues,
test_jenkins_add_issue_appends_entry, test_jenkins_add_issue_contains_severity,
test_jenkins_add_issue_contains_project_name,
test_jenkins_dump_to_file_writes_json) and their associated imports and helper
functions. Create tests/test_code_climate_reporter.py containing all test
functions prefixed with test_code_climate
(test_code_climate_severity_high_maps_to_major,
test_code_climate_severity_normal_maps_to_minor,
test_code_climate_severity_low_maps_to_info,
test_code_climate_add_issue_appends_entry,
test_code_climate_add_issue_contains_check_name,
test_code_climate_add_issue_severity_value,
test_code_climate_dump_to_file_writes_json,
test_code_climate_fingerprint_is_deterministic) with their associated imports
and helper functions. The shared helper functions _make_manifest, _make_project,
and _make_issue should be included in both files or moved to a conftest.py.

Source: Coding guidelines

tests/test_commands_misc.py (1)

1-397: 🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy lift

Split this mixed test module to match module-mirroring policy.

This file bundles tests for multiple command modules; please split into module-aligned files so test files mirror source modules.

As per coding guidelines, "tests/test_*.py: Use pytest for unit tests; test files should mirror module names (e.g., tests/test_manifest.py for dfetch/manifest.py)."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_commands_misc.py` around lines 1 - 397, The test file bundles
tests for multiple command modules (Environment, Init, Validate, FormatPatch,
and UpdatePatch) which violates the module-mirroring policy. Split this file
into separate test files: create tests/test_environment.py containing
test_environment_prints_version,
test_environment_logs_newer_version_when_available,
test_environment_no_newer_version_notice,
test_environment_calls_list_tool_info_for_each_project_type, and
test_environment_create_menu; create tests/test_init.py with
test_init_creates_manifest_when_absent,
test_init_does_not_overwrite_existing_manifest, and test_init_create_menu;
create tests/test_validate.py with test_validate_calls_manifest_from_file,
test_validate_prints_valid, and test_validate_create_menu; create
tests/test_format_patch.py with test_determine_target_patch_type_git,
test_determine_target_patch_type_svn, test_determine_target_patch_type_plain,
test_format_patch_no_patch_logs_warning, and
test_format_patch_runtime_error_raises; and create tests/test_update_patch.py
with all remaining test_update_patch_* tests. Each new file should include
relevant imports and be named to match its corresponding source module in
dfetch/commands/.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_commands_freeze.py`:
- Line 56: The patch target string in the test_commands_freeze.py file for
mocking create_sub_project contains an incorrect attribute chain that does not
exist. Review where create_sub_project is actually imported or referenced in the
dfetch.commands.freeze module and correct the patch target accordingly. The
patch strings on lines 56, 75, 97, and 119 all need to be updated to point to
the correct location where create_sub_project is accessed within the freeze
module, ensuring the mock is applied at the point where the function is actually
used.

In `@tests/test_commands_misc.py`:
- Line 186: The patch target paths in the test cases are unstable and contain
redundant module references that cause AttributeError failures. In the mock
patch calls on lines 186, 212, 254, 280, 309, and 337, replace the patch target
string from the current format to use a direct import path to where
create_sub_project is actually defined or used. The path should reference
dfetch.project.create_sub_project or the appropriate module where this function
is imported within the format_patch module, removing the redundant dfetch
reference in the middle of the path to ensure the patch target is valid and
stable.

In `@tests/test_superproject_and_version.py`:
- Line 1: The test file `tests/test_superproject_and_version.py` combines tests
for two separate modules (NoVcsSuperProject from dfetch/project/superproject.py
and version functionality from dfetch/manifest/version.py), violating the naming
convention. Split this file into two separate test files that mirror their
respective module names: create `tests/test_superproject.py` containing all
tests related to NoVcsSuperProject, and create `tests/test_version.py` (or
appropriate naming for the manifest version module) containing all tests related
to version functionality, then remove the original combined test file.

---

Outside diff comments:
In `@tests/test_check_reporters.py`:
- Around line 1-170: Split the mixed test file tests/test_check_reporters.py
into two separate module-aligned files following the repository naming policy.
Create tests/test_jenkins_reporter.py containing all test functions prefixed
with test_jenkins (test_jenkins_reporter_init_creates_empty_issues,
test_jenkins_add_issue_appends_entry, test_jenkins_add_issue_contains_severity,
test_jenkins_add_issue_contains_project_name,
test_jenkins_dump_to_file_writes_json) and their associated imports and helper
functions. Create tests/test_code_climate_reporter.py containing all test
functions prefixed with test_code_climate
(test_code_climate_severity_high_maps_to_major,
test_code_climate_severity_normal_maps_to_minor,
test_code_climate_severity_low_maps_to_info,
test_code_climate_add_issue_appends_entry,
test_code_climate_add_issue_contains_check_name,
test_code_climate_add_issue_severity_value,
test_code_climate_dump_to_file_writes_json,
test_code_climate_fingerprint_is_deterministic) with their associated imports
and helper functions. The shared helper functions _make_manifest, _make_project,
and _make_issue should be included in both files or moved to a conftest.py.

In `@tests/test_commands_misc.py`:
- Around line 1-397: The test file bundles tests for multiple command modules
(Environment, Init, Validate, FormatPatch, and UpdatePatch) which violates the
module-mirroring policy. Split this file into separate test files: create
tests/test_environment.py containing test_environment_prints_version,
test_environment_logs_newer_version_when_available,
test_environment_no_newer_version_notice,
test_environment_calls_list_tool_info_for_each_project_type, and
test_environment_create_menu; create tests/test_init.py with
test_init_creates_manifest_when_absent,
test_init_does_not_overwrite_existing_manifest, and test_init_create_menu;
create tests/test_validate.py with test_validate_calls_manifest_from_file,
test_validate_prints_valid, and test_validate_create_menu; create
tests/test_format_patch.py with test_determine_target_patch_type_git,
test_determine_target_patch_type_svn, test_determine_target_patch_type_plain,
test_format_patch_no_patch_logs_warning, and
test_format_patch_runtime_error_raises; and create tests/test_update_patch.py
with all remaining test_update_patch_* tests. Each new file should include
relevant imports and be named to match its corresponding source module in
dfetch/commands/.

In `@tests/test_jenkins_reporter.py`:
- Around line 85-89: The assertion in the test_report_has_correct_class_key
function uses loose substring checks that allow invalid values to pass. Replace
the current assertion that checks for "issues" or "jenkins" substrings with an
exact equality check against the specific expected value for the _class field,
ensuring the test properly validates the reporter's output schema rather than
allowing partial matches that could be false positives.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: ffaa8672-4536-40f2-960d-8ed1263ee063

📥 Commits

Reviewing files that changed from the base of the PR and between 5226ecd and b330530.

📒 Files selected for processing (16)
  • tests/test_check_reporters.py
  • tests/test_check_stdout_reporter.py
  • tests/test_commands_diff.py
  • tests/test_commands_format_patch.py
  • tests/test_commands_freeze.py
  • tests/test_commands_misc.py
  • tests/test_commands_update_patch.py
  • tests/test_gitsuperproject.py
  • tests/test_jenkins_reporter.py
  • tests/test_sarif_reporter.py
  • tests/test_screen.py
  • tests/test_stdout_reporter.py
  • tests/test_superproject_and_version.py
  • tests/test_svnsubproject.py
  • tests/test_svnsuperproject.py
  • tests/test_terminal_prompt.py

Comment thread tests/test_commands_freeze.py Outdated

with patch("dfetch.commands.freeze.create_super_project", return_value=superproject):
with patch("dfetch.commands.freeze.in_directory"):
with patch("dfetch.commands.freeze.dfetch.project.create_sub_project") as mock_create:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Correct patch target for create_sub_project in Freeze tests.

These patch strings likely point to a non-existent attribute chain and can fail before test logic executes.

Proposed fix
- with patch("dfetch.commands.freeze.dfetch.project.create_sub_project") as mock_create:
+ with patch("dfetch.project.create_sub_project") as mock_create:

- with patch("dfetch.commands.freeze.dfetch.project.create_sub_project") as mock_create:
+ with patch("dfetch.project.create_sub_project") as mock_create:

- with patch("dfetch.commands.freeze.dfetch.project.create_sub_project") as mock_create:
+ with patch("dfetch.project.create_sub_project") as mock_create:

- with patch("dfetch.commands.freeze.dfetch.project.create_sub_project") as mock_create:
+ with patch("dfetch.project.create_sub_project") as mock_create:

Also applies to: 75-75, 97-97, 119-119

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_commands_freeze.py` at line 56, The patch target string in the
test_commands_freeze.py file for mocking create_sub_project contains an
incorrect attribute chain that does not exist. Review where create_sub_project
is actually imported or referenced in the dfetch.commands.freeze module and
correct the patch target accordingly. The patch strings on lines 56, 75, 97, and
119 all need to be updated to point to the correct location where
create_sub_project is accessed within the freeze module, ensuring the mock is
applied at the point where the function is actually used.

Comment thread tests/test_commands_misc.py Outdated

with patch("dfetch.commands.format_patch.create_super_project", return_value=superproject):
with patch("dfetch.commands.format_patch.in_directory"):
with patch("dfetch.commands.format_patch.dfetch.project.create_sub_project") as mock_create:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Fix patch target paths; current targets likely fail before assertions run.

patch("dfetch.commands.<...>.dfetch.project.create_sub_project") is not a stable import path and can fail with AttributeError, which makes these tests fail for the wrong reason.

Proposed fix
- with patch("dfetch.commands.format_patch.dfetch.project.create_sub_project") as mock_create:
+ with patch("dfetch.project.create_sub_project") as mock_create:

- with patch("dfetch.commands.format_patch.dfetch.project.create_sub_project") as mock_create:
+ with patch("dfetch.project.create_sub_project") as mock_create:

- with patch("dfetch.commands.update_patch.dfetch.project.create_sub_project") as mock_create:
+ with patch("dfetch.project.create_sub_project") as mock_create:

- with patch("dfetch.commands.update_patch.dfetch.project.create_sub_project") as mock_create:
+ with patch("dfetch.project.create_sub_project") as mock_create:

- with patch("dfetch.commands.update_patch.dfetch.project.create_sub_project") as mock_create:
+ with patch("dfetch.project.create_sub_project") as mock_create:

- with patch("dfetch.commands.update_patch.dfetch.project.create_sub_project") as mock_create:
+ with patch("dfetch.project.create_sub_project") as mock_create:

Also applies to: 212-212, 254-254, 280-280, 309-309, 337-337

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_commands_misc.py` at line 186, The patch target paths in the test
cases are unstable and contain redundant module references that cause
AttributeError failures. In the mock patch calls on lines 186, 212, 254, 280,
309, and 337, replace the patch target string from the current format to use a
direct import path to where create_sub_project is actually defined or used. The
path should reference dfetch.project.create_sub_project or the appropriate
module where this function is imported within the format_patch module, removing
the redundant dfetch reference in the middle of the path to ensure the patch
target is valid and stable.

@@ -0,0 +1,107 @@
"""Tests for dfetch/project/superproject.py (NoVcsSuperProject) and dfetch/manifest/version.py."""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Split this test file so test filenames mirror module names.

This file mixes tests for two modules (dfetch/project/superproject.py and dfetch/manifest/version.py) under one tests/test_*.py file, which breaks the repository naming convention for tests.

As per coding guidelines, “tests/test_*.py: Use pytest for unit tests; test files should mirror module names (e.g., tests/test_manifest.py for dfetch/manifest.py)”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_superproject_and_version.py` at line 1, The test file
`tests/test_superproject_and_version.py` combines tests for two separate modules
(NoVcsSuperProject from dfetch/project/superproject.py and version functionality
from dfetch/manifest/version.py), violating the naming convention. Split this
file into two separate test files that mirror their respective module names:
create `tests/test_superproject.py` containing all tests related to
NoVcsSuperProject, and create `tests/test_version.py` (or appropriate naming for
the manifest version module) containing all tests related to version
functionality, then remove the original combined test file.

Source: Coding guidelines

@spoorcc spoorcc force-pushed the claude/bestpractices-silver-badge-4zmhea branch from 406769a to fff2b75 Compare June 17, 2026 20:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants