Skip to content

Conversation

@miroslavpojer
Copy link
Collaborator

@miroslavpojer miroslavpojer commented Oct 16, 2025

Summary by CodeRabbit

  • Documentation

    • Added a new Python Unit Test Conventions principle and standardized function/class template wording.
  • Tests

    • Reworked unit tests to a typed, fixture-driven approach and significantly expanded coverage for label handling, YAML parsing, edge cases, logging, and related behaviors.
  • Chores

    • Updated project ignore rules to exclude common OS/editor and desktop artifacts.

Fixes #203

@miroslavpojer miroslavpojer self-assigned this Oct 16, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 16, 2025

Walkthrough

Added OS/editor ignores to .gitignore, expanded principles with a new Python Unit Test Conventions section and standardized template wording, and refactored tests/unit/release_notes_generator/chapters/test_custom_chapters.py to use a typed RecordStub fixture and broader, parameterized test scenarios.

Changes

Cohort / File(s) Change Summary
Config: VCS ignores
/.gitignore
Added OS/editor artifact ignores: .DS_Store and .vscode/ entries under a new comment header.
Documentation: testing principles & templates
.specify/memory/principles.md
Added Principle 5 (PID:K-5) — Python Unit Test Conventions covering pytest layout, naming, isolation, determinism, fixtures, execution style, and maintenance. Standardized canonical function/method and class template wording by removing trailing punctuation in the one-sentence summary lines.
Tests: custom chapters
tests/unit/release_notes_generator/chapters/test_custom_chapters.py
Reworked tests to use a concrete RecordStub fixture (typed minimal Record), introduced a centralized factory, reduced mocks, and expanded parametrized coverage for chapter init, population/label matching, duplicity scope variants, YAML config parsing/validation, label normalization edge cases, skip conditions, and verbose logging paths.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • Zejnilovic

Poem

🐰 I hop through docs and tests with glee,
Stubs and fixtures snug as can be,
Ignored the crumbs of editors small,
Chapters tidy, ready for all,
Carrot cheers for an easy spree.

Pre-merge checks and finishing touches

❌ Failed checks (3 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The pull request includes changes to the .gitignore file and modifications to the principles documentation, neither of which aligns with the test refactoring objectives defined in issue #203. These additions introduce unrelated scope beyond migrating the custom chapter tests to the new structure and conventions. Split the .gitignore and principles documentation updates into a separate pull request or remove them from this change to ensure the current PR remains focused on refactoring the custom chapter tests as per the linked issue.
Description Check ⚠️ Warning The pull request description only contains a reference to “Fixes #203” and lacks the required template sections, including a summary of changes, a completed checklist, and additional context. The provided template structure is not followed, so the description fails to provide the necessary information for reviewers to verify compliance with repository guidelines. Please expand the description using the repository template by adding a concise summary of changes, completing the checklist tasks, and including any additional context relevant to the pull request.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Linked Issues Check ❓ Inconclusive The pull request updates documentation and refactors tests to follow the new unit testing principles, which addresses the requirement to adhere to the newly defined conventions and pilot them for custom chapters. However, the summary does not confirm whether test methods have been grouped into classes as specified in issue #203. Without explicit evidence of grouping tests into classes, compliance with that particular objective is unclear. Please verify that test methods are organized into test classes where appropriate and update the pull request description or code to demonstrate that grouping has been implemented as required by the linked issue.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly summarizes the main change by indicating a refactor of the custom chapter using new principles, which aligns with the primary objective of the pull request. It avoids extraneous detail and remains concise. Although it includes the issue number and omits the word “tests,” it still conveys the core update and will help teammates quickly understand the intent without scanning file changes.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/203-refactor-custom-chapters-tests

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 18919be and 526a1fa.

📒 Files selected for processing (1)
  • tests/unit/release_notes_generator/chapters/test_custom_chapters.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tests/unit/release_notes_generator/chapters/test_custom_chapters.py (7)
release_notes_generator/utils/enums.py (1)
  • DuplicityScopeEnum (24-32)
release_notes_generator/action_inputs.py (1)
  • ActionInputs (64-518)
release_notes_generator/model/record/record.py (1)
  • skip (76-78)
tests/unit/conftest.py (1)
  • custom_chapters (74-80)
release_notes_generator/chapters/custom_chapters.py (4)
  • populate (76-105)
  • CustomChapters (71-176)
  • from_yaml_array (107-176)
  • _normalize_labels (33-68)
release_notes_generator/model/record/issue_record.py (1)
  • IssueRecord (17-268)
release_notes_generator/model/record/commit_record.py (2)
  • commit (54-59)
  • CommitRecord (13-87)
🪛 Ruff (0.14.0)
tests/unit/release_notes_generator/chapters/test_custom_chapters.py

65-65: Unused method argument: add_into_chapters

(ARG002)

🔇 Additional comments (3)
tests/unit/release_notes_generator/chapters/test_custom_chapters.py (3)

26-86: Excellent refactoring with a typed stub fixture.

The RecordStub fixture effectively replaces brittle mocks with a concrete, minimal implementation. The factory pattern with sensible defaults improves test readability and maintainability.

Note on static analysis hint: The unused add_into_chapters argument at line 65 is intentional for this stub implementation and can be safely ignored.


258-268: Verify the token leakage check is comprehensive.

Line 268 checks that "token" doesn't appear in log messages, presumably to prevent token leakage in verbose mode. However, this assertion might not catch all cases of sensitive information leakage:

  • GitHub tokens, API keys, or secrets might not contain the word "token"
  • The check only looks for the lowercase word "token" in isolation

Please verify this check is sufficient for your security requirements. Consider:

  1. Are there specific token formats or patterns that should be checked (e.g., ghp_, ghs_ prefixes for GitHub tokens)?
  2. Should this check be more specific about what tokens/secrets need protection?
  3. Is there a better way to ensure no sensitive data leaks in verbose logging?

Alternatively, if this check is intentionally minimal and serves as a reminder rather than comprehensive security validation, consider adding a comment explaining the intent.


285-333: Well-structured skip condition tests.

The parametrized test comprehensively covers all skip scenarios, and the brittle mocking issues from the previous review have been properly addressed:

  • Lines 308-312: IssueRecord mock correctly uses create_autospec with explicit return_value for contains_change_increment
  • Lines 320-324: CommitRecord mock properly includes explicit labels = [] attribute

The test coverage for skip conditions is thorough and the mocking is now robust.


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.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
.specify/memory/principles.md (1)

309-370: Great pytest conventions; add pytest.ini markers to avoid unknown‑marker warnings

Document defines slow/integration/internal markers; ensure pytest.ini declares them so pytest doesn’t warn and default runs can exclude them.

As a follow‑up, add:

# pytest.ini
[pytest]
markers =
    slow: long-running unit tests
    integration: integration tests excluded from default run
    smoke: high-signal subset
    internal: tests for non-public internals

As per coding guidelines

tests/unit/release_notes_generator/chapters/test_custom_chapters.py (1)

26-89: Tidy the stub: drop unused noqa and prefix unused params

Silence Ruff warnings and keep signature compatibility by prefixing unused args; remove unused D401 noqa.

Apply:

-        def to_chapter_row(self, add_into_chapters: bool = True) -> str:  # noqa: D401
+        def to_chapter_row(self, _add_into_chapters: bool = True) -> str:
             return f"{self._rid} row"

-        def get_rls_notes(self, line_marks: list[str] | None = None) -> str:  # noqa: D401
+        def get_rls_notes(self, _line_marks: list[str] | None = None) -> str:
             return ""
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d0e2307 and 6c1f316.

📒 Files selected for processing (3)
  • .gitignore (1 hunks)
  • .specify/memory/principles.md (2 hunks)
  • tests/unit/release_notes_generator/chapters/test_custom_chapters.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tests/unit/release_notes_generator/chapters/test_custom_chapters.py (6)
release_notes_generator/utils/enums.py (1)
  • DuplicityScopeEnum (24-32)
release_notes_generator/action_inputs.py (1)
  • ActionInputs (64-518)
release_notes_generator/model/record/record.py (2)
  • skip (76-78)
  • is_present_in_chapters (49-55)
tests/unit/conftest.py (1)
  • custom_chapters (74-80)
release_notes_generator/chapters/custom_chapters.py (4)
  • populate (76-105)
  • CustomChapters (71-176)
  • from_yaml_array (107-176)
  • _normalize_labels (33-68)
release_notes_generator/model/record/commit_record.py (2)
  • commit (54-59)
  • CommitRecord (13-87)
🪛 LanguageTool
.specify/memory/principles.md

[grammar] ~267-~267: There might be a mistake here.
Context: ...entence imperative summary. Parameters: - name: concise description - ... Returns...

(QB_NEW_EN)


[grammar] ~268-~268: There might be a mistake here.
Context: ... Parameters: - name: concise description - ... Returns: - Description of value sem...

(QB_NEW_EN)


[grammar] ~271-~271: There might be a mistake here.
Context: ...ame: concise description - ... Returns: - Description of value semantics. Raises:...

(QB_NEW_EN)


[grammar] ~274-~274: There might be a mistake here.
Context: ... of value semantics. Raises: (optional) - ExceptionType: condition """ Canonical ...

(QB_NEW_EN)


[grammar] ~311-~311: There might be a mistake here.
Context: ...mplement PID:A-1 through PID:A-4. Scope: - Applies to all files under tests/ for ...

(QB_NEW_EN)


[grammar] ~320-~320: There might be a mistake here.
Context: ...o, make_user`). Functions vs Classes: - Default style: free test functions. Clas...

(QB_NEW_EN)


[grammar] ~321-~321: There might be a mistake here.
Context: ...h / edge / error) improving readability. - Test classes MUST be named `Test<ThingOr...

(QB_NEW_EN)


[grammar] ~331-~331: There might be a mistake here.
Context: ...ions—no production logic or test bodies. - Fixture default scope MUST remain `funct...

(QB_NEW_EN)


[grammar] ~342-~342: There might be a mistake here.
Context: ...ation adds value. - Logging checks MUST set explicit level (`with caplog.at_level("...

(QB_NEW_EN)


[grammar] ~346-~346: There might be a mistake here.
Context: ...Y identify a minimal high-signal subset. - Known unfixed bugs MUST use `pytest.mark...

(QB_NEW_EN)


[grammar] ~348-~348: There might be a mistake here.
Context: ...on absence (e.g., OS-specific behavior). - Internal-only tests touching non-public ...

(QB_NEW_EN)


[grammar] ~351-~351: There might be a mistake here.
Context: ... @pytest.mark.internal. Test Doubles: - Fakes (simple dataclasses, lambdas, smal...

(QB_NEW_EN)


[grammar] ~352-~352: There might be a mistake here.
Context: ...ns) SHOULD be preferred over deep mocks. - Monkeypatches MUST patch where an object...

(QB_NEW_EN)


[grammar] ~363-~363: There might be a mistake here.
Context: ...on Checklist (Guidance / NON-NORMATIVE): - Is a class genuinely clearer than multip...

(QB_NEW_EN)


[grammar] ~367-~367: There might be a mistake here.
Context: ...ork/time/FS? If yes, isolate or mark. - Does failure message clearly show diff? If n...

(QB_NEW_EN)


[grammar] ~367-~367: There might be a mistake here.
Context: ...or mark. - Does failure message clearly show diff? If not, prefer equality or add `m...

(QB_NEW_EN)

🪛 Ruff (0.14.0)
tests/unit/release_notes_generator/chapters/test_custom_chapters.py

67-67: Unused method argument: add_into_chapters

(ARG002)


67-67: Unused noqa directive (non-enabled: D401)

Remove unused noqa directive

(RUF100)


76-76: Unused method argument: line_marks

(ARG002)


76-76: Unused noqa directive (non-enabled: D401)

Remove unused noqa directive

(RUF100)

🔇 Additional comments (4)
.gitignore (1)

161-164: OS/editor artifacts ignore — LGTM

Good adds; prevents accidental commits of local artifacts.

.specify/memory/principles.md (1)

265-276: Docstring template alignment — LGTM

Template wording is consistent and clear.

tests/unit/release_notes_generator/chapters/test_custom_chapters.py (2)

100-116: Populate happy-path coverage — LGTM

Good AAA structure and clear assertions.


118-136: Duplicity scope invariance — LGTM

Patch scope and assert dual population; concise and deterministic.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (6)
tests/unit/release_notes_generator/chapters/test_custom_chapters.py (6)

67-77: Silence lint: mark unused parameters with underscores

Both parameters are unused; rename to underscore to satisfy Ruff ARG002.

-        def to_chapter_row(self, add_into_chapters: bool = True) -> str:
+        def to_chapter_row(self, _add_into_chapters: bool = True) -> str:
             return f"{self._rid} row"
@@
-        def get_rls_notes(self, line_marks: list[str] | None = None) -> str:
+        def get_rls_notes(self, _line_marks: list[str] | None = None) -> str:
             return ""

Based on static analysis hints.


29-41: Remove unused constructor parameter pulls_count

The stub never uses pulls_count; dropping it reduces noise and avoids misleading callers.

-        def __init__(
-            self,
-            rid: str,
-            labels: list[str] | None,
-            pulls_count: int,
-            skip: bool,
-            contains_change_increment: bool,
-        ):
-            super().__init__(labels=labels, skip=skip)
-            self.pulls_count = pulls_count
+        def __init__(
+            self,
+            rid: str,
+            labels: list[str] | None,
+            skip: bool,
+            contains_change_increment: bool,
+        ):
+            super().__init__(labels=labels, skip=skip)
             self._rid = rid
             self._contains = contains_change_increment

79-86: Align factory with constructor change (remove pulls_count)

Update the factory to mirror the simplified stub signature.

-    def _make(
-        rid: str = "org/repo#X",
-        labels: list[str] | None = None,
-        pulls_count: int = 1,
-        skip: bool = False,
-        contains_change_increment: bool = True,
-    ) -> Record:
-        return RecordStub(rid, labels or [], pulls_count, skip, contains_change_increment)
+    def _make(
+        rid: str = "org/repo#X",
+        labels: list[str] | None = None,
+        skip: bool = False,
+        contains_change_increment: bool = True,
+    ) -> Record:
+        return RecordStub(rid, labels or [], skip, contains_change_increment)

118-126: Add DuplicityScopeEnum.BOTH to param set

For completeness, include BOTH in scope coverage.

-    [DuplicityScopeEnum.SERVICE, DuplicityScopeEnum.NONE],
-    ids=["duplicity-scope-service", "duplicity-scope-none"],
+    [DuplicityScopeEnum.SERVICE, DuplicityScopeEnum.NONE, DuplicityScopeEnum.BOTH],
+    ids=["duplicity-scope-service", "duplicity-scope-none", "duplicity-scope-both"],

171-186: Scope caplog to the module logger to avoid cross-test noise

Target the logger used by custom_chapters for more deterministic assertions.

-    caplog.set_level("WARNING")
+    caplog.set_level("WARNING", logger="release_notes_generator.chapters.custom_chapters")

244-259: Also scope caplog here to the module logger

Keeps skip message assertions precise per logger.

-    caplog.set_level("WARNING")
+    caplog.set_level("WARNING", logger="release_notes_generator.chapters.custom_chapters")
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6c1f316 and 18919be.

📒 Files selected for processing (1)
  • tests/unit/release_notes_generator/chapters/test_custom_chapters.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tests/unit/release_notes_generator/chapters/test_custom_chapters.py (6)
release_notes_generator/action_inputs.py (1)
  • ActionInputs (64-518)
release_notes_generator/model/record/record.py (1)
  • skip (76-78)
tests/unit/conftest.py (1)
  • custom_chapters (74-80)
release_notes_generator/chapters/custom_chapters.py (4)
  • populate (76-105)
  • CustomChapters (71-176)
  • from_yaml_array (107-176)
  • _normalize_labels (33-68)
release_notes_generator/model/record/issue_record.py (1)
  • IssueRecord (17-268)
release_notes_generator/model/record/commit_record.py (2)
  • commit (54-59)
  • CommitRecord (13-87)
🪛 Ruff (0.14.0)
tests/unit/release_notes_generator/chapters/test_custom_chapters.py

67-67: Unused method argument: add_into_chapters

(ARG002)


76-76: Unused method argument: line_marks

(ARG002)

🔇 Additional comments (1)
tests/unit/release_notes_generator/chapters/test_custom_chapters.py (1)

16-21: The review comment is based on an incorrect assumption about Python 3.8 support.

The project's Black configuration explicitly targets Python 3.11 (target-version = ['py311']), and there is no evidence of Python 3.8 support in the codebase. The list[str] and dict[str, Record] type hints used throughout the test file are fully compatible with Python 3.11 and do not require the from __future__ import annotations import. The code is correct as-is.

Likely an incorrect or invalid review comment.

@miroslavpojer miroslavpojer merged commit dcf920a into master Oct 16, 2025
7 checks passed
@miroslavpojer miroslavpojer deleted the feature/203-refactor-custom-chapters-tests branch October 16, 2025 10:51
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.

Refactor custom chapter using new principles

1 participant