Skip to content

[#17] Fixed variable references in comments not being updated during auto-fix.#18

Merged
AlexSkrypnyk merged 4 commits intomainfrom
feature/17-fix-comment-vars
Mar 12, 2026
Merged

[#17] Fixed variable references in comments not being updated during auto-fix.#18
AlexSkrypnyk merged 4 commits intomainfrom
feature/17-fix-comment-vars

Conversation

@AlexSkrypnyk
Copy link
Member

@AlexSkrypnyk AlexSkrypnyk commented Mar 12, 2026

Closes #17

Summary by CodeRabbit

  • New Features

    • Auto-fix now updates local-variable references inside preceding doc comments when safe.
    • New configurable option to control which comment types are updated (defaults to doc); skips ambiguous, multi-variable, trailing-comment, or separated-by-code cases.
  • Tests

    • Added comprehensive unit and functional tests and fixtures covering docblock, inline/C-style, multi-variable, spacing and auto-fix scenarios; added a helper to run auto-fix and capture results.

@coderabbitai
Copy link

coderabbitai bot commented Mar 12, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds comment-aware auto-fix support to LocalVariableNamingSniff: a public fixCommentTypes option, helpers to locate preceding comments and safely replace variable references in eligible comments, and test coverage including functional PHPCBF integration and unit tests for the new behavior.

Changes

Cohort / File(s) Summary
Core Sniff Implementation
src/DrevOps/Sniffs/NamingConventions/LocalVariableNamingSniff.php
Added public $fixCommentTypes = 'doc'; added findPrecedingComment() and fixCommentVariable() helpers; logic to collect preceding comment tokens (skipping trailing comments on prior statements); extended auto-fix flow to update eligible comment variable references and avoid ambiguous multi-variable edits.
Test Fixtures
tests/Fixtures/CommentVariableNaming.php, tests/Fixtures/VariableNaming.php
Added CommentVariableNaming fixture covering docblock/inline/C-style comments, multi-variable and edge cases; added functionWithVarComments() with @var annotated local variables.
Functional Tests & Helpers
tests/Functional/LocalVariableNamingSniffFunctionalTest.php, tests/Functional/FunctionalTestCase.php
Added testCommentVariableNaming() and testPhpcbfFixesCommentVariableReferences() functional tests; added runPhpcbf() helper to execute PHPCBF on a temp copy and return fixed content.
Unit Tests
tests/Unit/LocalVariableNamingSniffTest.php
Added testFixCommentTypesDefault() and testFindPrecedingComment() with dataProviderFindPrecedingComment() to validate detection of preceding comments and default configuration.

Sequence Diagram

sequenceDiagram
    participant Sniff as LocalVariableNamingSniff
    participant File as PHP Token Stream
    participant Comments as Comment Tokens
    participant Fixer as PHPCBF/Fixer

    Sniff->>File: process() detect NotSnakeCase variable (oldName)
    Sniff->>Comments: findPrecedingComment(stackPtr)
    Comments-->>Sniff: comment token range or empty

    alt comment(s) found and eligible per fixCommentTypes
        Sniff->>Fixer: fixCommentVariable(file, commentTokens, oldName, newName)
        Fixer->>Comments: scan comment text for variable references
        alt single matching variable reference
            Fixer->>Comments: replace oldName -> newName in comment
            Comments-->>Fixer: replacement recorded
        else multiple distinct variables referenced
            Fixer-->>Fixer: skip comment (ambiguous)
        end
        Fixer-->>Sniff: comment fix applied or skipped
    end

    Sniff->>File: update variable token to newName
    Sniff-->>Fixer: submit fixes
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: fixing variable references in comments to be updated during auto-fix, matching the core objective in issue #17.
Linked Issues check ✅ Passed The PR successfully implements the primary requirement from issue #17: variable references in comments are now updated when variable names are auto-fixed, with comprehensive test coverage and configurable comment type handling.
Out of Scope Changes check ✅ Passed All changes are directly related to issue #17: the sniff enhancement updates variable references in comments, test fixtures validate the behavior across various scenarios, and helper utilities support the new functionality with no extraneous changes.
Docstring Coverage ✅ Passed Docstring coverage is 90.32% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/17-fix-comment-vars
📝 Coding Plan
  • Generate coding plan for human review comments

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

@codecov
Copy link

codecov bot commented Mar 12, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (0b89521) to head (3bc8173).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff            @@
##              main       #18   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            6         6           
  Lines          420       444   +24     
=========================================
+ Hits           420       444   +24     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

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: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/DrevOps/Sniffs/NamingConventions/LocalVariableNamingSniff.php`:
- Around line 133-147: The backward scan in LocalVariableNamingSniff currently
treats any preceding T_COMMENT/T_DOC as attachable and can capture trailing
comments from the previous statement; update the loop that walks from $stackPtr
backwards to only collect comment tokens when they are actually adjacent to the
variable (e.g. same line for end-of-line comments or immediately preceding lines
with no intervening non-whitespace tokens). Concretely, inside the for loop that
inspects $tokens[$i] (the scan in LocalVariableNamingSniff around $stackPtr),
add checks using $tokens[$i]['line'] vs $tokens[$stackPtr]['line'] (and allow a
one-line difference for a directly preceding block comment) and stop the scan
when a comment token is on an earlier non-adjacent line so you don’t attach
comments from the previous statement.
- Around line 178-190: The guard that builds $all_text from $commentTokens and
then checks $unique_vars before calling fixCommentTypes is too broad and can
block valid `@var` fixes because it aggregates neighboring comments; instead,
restrict the distinct-variable check to the single comment being processed (use
the individual token content rather than concatenating $commentTokens) or move
the unique-variable logic into the per-comment processing path (so
fixCommentTypes inspects only that token's content); update the logic around
$all_text, $commentTokens and the unique_vars check so that fixCommentTypes is
called for a comment token unless that specific token contains multiple distinct
$variables.

In `@tests/Functional/LocalVariableNamingSniffFunctionalTest.php`:
- Around line 106-186: Add a fix-mode assertion to the existing
testCommentVariableNaming() functional test: after the current runPhpcs(...)
violation-only check for the CommentVariableNaming.php fixture, invoke the PHPCS
fix runner (e.g. the project helper used for tests that runs phpcbf/fix mode) on
the same fixture and assert the resulting file contents (or fixed output)
include the corrected snake_case variable names in comments (e.g.
"$module_handler", "$first_handler", "$second_handler") and that comment
references were rewritten; update the test to call the fix-runner for
CommentVariableNaming.php and assert the fixed comment text matches expected
replacements.

In `@tests/Unit/LocalVariableNamingSniffTest.php`:
- Around line 175-244: Add a regression case to dataProviderFindPrecedingComment
that covers a previous statement with a trailing inline comment (e.g. "$other =
1; // $myVar") and assert findPrecedingComment() does not attach that trailing
comment to the following variable; specifically add a provider entry (similar to
'code_between_comment_and_variable') where the source has a line with code plus
a trailing "// $myVar" followed by "$myVar = get_service();" and set the
expected boolean to FALSE so the test ensures findPrecedingComment() returns
empty for the next variable.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0e950c51-ec14-432c-a30d-21a0c1b644d8

📥 Commits

Reviewing files that changed from the base of the PR and between 0b89521 and 953d8ef.

📒 Files selected for processing (5)
  • src/DrevOps/Sniffs/NamingConventions/LocalVariableNamingSniff.php
  • tests/Fixtures/CommentVariableNaming.php
  • tests/Fixtures/VariableNaming.php
  • tests/Functional/LocalVariableNamingSniffFunctionalTest.php
  • tests/Unit/LocalVariableNamingSniffTest.php

@AlexSkrypnyk AlexSkrypnyk force-pushed the feature/17-fix-comment-vars branch from 953d8ef to b555a97 Compare March 12, 2026 23:06
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: 2

♻️ Duplicate comments (1)
src/DrevOps/Sniffs/NamingConventions/LocalVariableNamingSniff.php (1)

188-207: ⚠️ Potential issue | 🟠 Major

Scope the multi-variable skip check to each comment token, not the whole collected block.

The current $all_text aggregation can still block a valid @var rewrite when an adjacent eligible comment references a different variable. Skip should be decided per token being rewritten.

💡 Proposed fix
-    // Collect text only from eligible comment token types to check for
-    // multiple variables. This prevents unrelated neighboring comments
-    // from blocking a valid fix.
-    $all_text = '';
-    foreach ($commentTokens as $ptr) {
-      $code = $tokens[$ptr]['code'];
-      $is_doc = ($code === T_DOC_COMMENT_STRING);
-      $is_inline = ($code === T_COMMENT);
-      if (($is_doc && in_array('doc', $fix_types, TRUE)) || ($is_inline && in_array('inline', $fix_types, TRUE))) {
-        $all_text .= $tokens[$ptr]['content'];
-      }
-    }
-
-    // Count distinct $variable references in the eligible comment text.
-    preg_match_all('/\$[a-zA-Z_]\w*/', $all_text, $matches);
-    $unique_vars = array_unique($matches[0]);
-    if (count($unique_vars) > 1) {
-      // Multiple variables in comment — skip (requires manual fix).
-      return;
-    }
-
     $pattern = '/\$' . preg_quote($oldName, '/') . '(?![a-zA-Z0-9_])/';
@@
       // Only process tokens that can contain variable references.
       if (!$is_doc && !$is_inline) {
         continue;
       }
+
+      // Skip only this token when it references multiple distinct variables.
+      preg_match_all('/\$[a-zA-Z_]\w*/', $content, $matches);
+      $unique_vars = array_unique($matches[0]);
+      if (count($unique_vars) > 1) {
+        continue;
+      }
 
       if (preg_match($pattern, $content) === 1) {
         $new_content = (string) preg_replace($pattern, '$' . $newName, $content);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/DrevOps/Sniffs/NamingConventions/LocalVariableNamingSniff.php` around
lines 188 - 207, The current multi-variable skip uses an aggregated $all_text
across $commentTokens which can wrongfully block a rewrite when only an adjacent
comment contains another variable; change the logic to scope the check per
token: inside the loop over $commentTokens (using $ptr and
$tokens[$ptr]['content']) run the variable extraction
(preg_match_all('/\$[a-zA-Z_]\\w*/', ...)) and compute array_unique on that
single token's matches, and if count($unique_vars) > 1 for that token then skip
rewriting that token only; otherwise allow the rewrite for that token (remove
the global $all_text aggregation and use per-token $matches/$unique_vars
checks).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/Functional/FunctionalTestCase.php`:
- Around line 147-158: The temp-file handling in runPhpcbf() is fragile: verify
tempnam() succeeded and that copy() returned true before calling processRun,
read contents only after confirming file exists, and always remove the temp file
in a finally block to avoid leaks; specifically, check the result of tempnam()
(temp_file) and throw/abort if false, check copy($file_path, $temp_file)
returned true and handle/fail on error, call processRun(...) as before, use try
{ ... $content = file_get_contents($temp_file); } finally { if
(isset($temp_file) && file_exists($temp_file)) unlink($temp_file); } so unlink
always runs, and handle file_get_contents returning false appropriately in
runPhpcbf().

In `@tests/Functional/LocalVariableNamingSniffFunctionalTest.php`:
- Around line 211-214: The test uses brittle exact string assertions in
LocalVariableNamingSniffFunctionalTest (assertStringContainsString against
$fixed) — replace the exact check on the `@var` line (currently checking for
'@var \Drupal\Core\Extension\ModuleHandler $module_handler */') with a regex
assertion that validates the renamed variable reference (allowing an optional
leading backslash and any namespace) and the new variable name ($moduleHandler);
for example swap the assertStringContainsString call for a PHPUnit regex
assertion (assertMatchesRegularExpression or assertRegExp depending on the test
suite) against $fixed using a pattern like
'/@var\s+\\?\S*ModuleHandler\s+\$moduleHandler\b/' so the test accepts
namespaced or non-namespaced `ModuleHandler` and the renamed variable.

---

Duplicate comments:
In `@src/DrevOps/Sniffs/NamingConventions/LocalVariableNamingSniff.php`:
- Around line 188-207: The current multi-variable skip uses an aggregated
$all_text across $commentTokens which can wrongfully block a rewrite when only
an adjacent comment contains another variable; change the logic to scope the
check per token: inside the loop over $commentTokens (using $ptr and
$tokens[$ptr]['content']) run the variable extraction
(preg_match_all('/\$[a-zA-Z_]\\w*/', ...)) and compute array_unique on that
single token's matches, and if count($unique_vars) > 1 for that token then skip
rewriting that token only; otherwise allow the rewrite for that token (remove
the global $all_text aggregation and use per-token $matches/$unique_vars
checks).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: f85e9d82-841b-4db4-ae9a-9ed13c267e00

📥 Commits

Reviewing files that changed from the base of the PR and between 953d8ef and b555a97.

📒 Files selected for processing (6)
  • src/DrevOps/Sniffs/NamingConventions/LocalVariableNamingSniff.php
  • tests/Fixtures/CommentVariableNaming.php
  • tests/Fixtures/VariableNaming.php
  • tests/Functional/FunctionalTestCase.php
  • tests/Functional/LocalVariableNamingSniffFunctionalTest.php
  • tests/Unit/LocalVariableNamingSniffTest.php

Comment on lines +147 to +158
$temp_file = tempnam(sys_get_temp_dir(), 'phpcbf_test_');
copy($file_path, $temp_file);

$this->processRun(
$phpcbf_bin,
['--standard=DrevOps', '--sniffs=' . $sniff, $temp_file],
timeout: 120
);

$content = file_get_contents($temp_file);
unlink($temp_file);

Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Harden temp-file handling in runPhpcbf() to avoid leaks and silent IO failures.

Guard tempnam()/copy() and move unlink() into finally so cleanup still happens on assertion/process failures.

♻️ Proposed refactor
-    $temp_file = tempnam(sys_get_temp_dir(), 'phpcbf_test_');
-    copy($file_path, $temp_file);
-
-    $this->processRun(
-      $phpcbf_bin,
-      ['--standard=DrevOps', '--sniffs=' . $sniff, $temp_file],
-      timeout: 120
-    );
-
-    $content = file_get_contents($temp_file);
-    unlink($temp_file);
+    $temp_file = tempnam(sys_get_temp_dir(), 'phpcbf_test_');
+    $this->assertNotFalse($temp_file, 'Failed to create temp file');
+    $this->assertTrue(copy($file_path, $temp_file), 'Failed to copy fixture to temp file');
+
+    try {
+      $this->processRun(
+        $phpcbf_bin,
+        ['--standard=DrevOps', '--sniffs=' . $sniff, $temp_file],
+        timeout: 120
+      );
+
+      $content = file_get_contents($temp_file);
+    }
+    finally {
+      if (is_file($temp_file)) {
+        unlink($temp_file);
+      }
+    }
🧰 Tools
🪛 PHPMD (2.15.0)

[error] 147-147: The variable $temp_file is not named in camelCase. (undefined)

(CamelCaseVariableName)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/Functional/FunctionalTestCase.php` around lines 147 - 158, The
temp-file handling in runPhpcbf() is fragile: verify tempnam() succeeded and
that copy() returned true before calling processRun, read contents only after
confirming file exists, and always remove the temp file in a finally block to
avoid leaks; specifically, check the result of tempnam() (temp_file) and
throw/abort if false, check copy($file_path, $temp_file) returned true and
handle/fail on error, call processRun(...) as before, use try { ... $content =
file_get_contents($temp_file); } finally { if (isset($temp_file) &&
file_exists($temp_file)) unlink($temp_file); } so unlink always runs, and handle
file_get_contents returning false appropriately in runPhpcbf().

Comment on lines +211 to +214
$this->assertStringContainsString('@var \SomeClass $module_handler */', $fixed);
$this->assertStringContainsString('@var \Drupal\Core\Extension\ModuleHandler $module_handler */', $fixed);
$this->assertStringContainsString('@var Drupal\Core\Extension\ModuleHandler $module_handler */', $fixed);
$this->assertStringContainsString('@var \Very\Long\Namespace\Path\To\SomeClass $module_handler */', $fixed);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix the brittle assertion causing the current CI failure (Line 213).

The check is too exact for @var text shape. Assert on the renamed variable reference with a regex (optionally allowing a leading \) so the test validates the intended behavior reliably.

💡 Proposed fix
-    $this->assertStringContainsString('@var Drupal\Core\Extension\ModuleHandler $module_handler */', $fixed);
+    $this->assertMatchesRegularExpression(
+      '/@var\s+\\\\?Drupal\\\\Core\\\\Extension\\\\ModuleHandler\s+\$module_handler\b/',
+      $fixed
+    );
🧰 Tools
🪛 GitHub Actions: Test PHP

[error] 213-213: PHPUnit failure: testPhpcbfFixesCommentVariableReferences failed. Script 'phpunit' exited with code 1 during test-coverage.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/Functional/LocalVariableNamingSniffFunctionalTest.php` around lines 211
- 214, The test uses brittle exact string assertions in
LocalVariableNamingSniffFunctionalTest (assertStringContainsString against
$fixed) — replace the exact check on the `@var` line (currently checking for
'@var \Drupal\Core\Extension\ModuleHandler $module_handler */') with a regex
assertion that validates the renamed variable reference (allowing an optional
leading backslash and any namespace) and the new variable name ($moduleHandler);
for example swap the assertStringContainsString call for a PHPUnit regex
assertion (assertMatchesRegularExpression or assertRegExp depending on the test
suite) against $fixed using a pattern like
'/@var\s+\\?\S*ModuleHandler\s+\$moduleHandler\b/' so the test accepts
namespaced or non-namespaced `ModuleHandler` and the renamed variable.

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

♻️ Duplicate comments (1)
tests/Functional/LocalVariableNamingSniffFunctionalTest.php (1)

211-213: ⚠️ Potential issue | 🔴 Critical

Replace brittle exact @var assertions with regex matching.

These exact full-line string checks are fragile and are already causing CI instability; assert the semantic contract (type + renamed variable) instead.

💡 Proposed fix
-    $this->assertStringContainsString('@var \SomeClass $module_handler */', $fixed);
-    $this->assertStringContainsString('@var \Drupal\Core\Extension\ModuleHandler $module_handler */', $fixed);
-    $this->assertStringContainsString('@var \Very\Long\Namespace\Path\To\SomeClass $module_handler */', $fixed);
+    $this->assertMatchesRegularExpression(
+      '/@var\s+\\\\?SomeClass\s+\$module_handler\b/',
+      $fixed
+    );
+    $this->assertMatchesRegularExpression(
+      '/@var\s+\\\\?Drupal\\\\Core\\\\Extension\\\\ModuleHandler\s+\$module_handler\b/',
+      $fixed
+    );
+    $this->assertMatchesRegularExpression(
+      '/@var\s+\\\\?Very\\\\Long\\\\Namespace\\\\Path\\\\To\\\\SomeClass\s+\$module_handler\b/',
+      $fixed
+    );
#!/bin/bash
set -euo pipefail

test_file="$(fd -p 'LocalVariableNamingSniffFunctionalTest.php' tests | head -n1)"
nl -ba "$test_file" | sed -n '204,222p'

# Expectation after fix: no exact `@var` string assertions for $module_handler remain.
rg -n "assertStringContainsString\('@var .*\\$module_handler" "$test_file" || true
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/Functional/LocalVariableNamingSniffFunctionalTest.php` around lines 211
- 213, The three brittle exact-string assertions in
LocalVariableNamingSniffFunctionalTest that call assertStringContainsString
(checking '@var \SomeClass $module_handler */', '@var
\Drupal\Core\Extension\ModuleHandler $module_handler */', and '@var
\Very\Long\Namespace\Path\To\SomeClass $module_handler */') should be replaced
with assertions that use a regex to validate "type + renamed variable"
semantics; update the tests to use PHPUnit's assertMatchesRegularExpression (or
assertRegExp) against $fixed to match a pattern like
/^@var\s+[\w\\]+\s+\$module_handler\b/ (or equivalent) so the test checks the
type token and $module_handler rather than exact full-line strings, and remove
the three exact assertStringContainsString calls.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/Functional/LocalVariableNamingSniffFunctionalTest.php`:
- Around line 205-242: The local variable $fixed in the test method violates the
snake_case rule; rename it to a snake_case identifier (e.g., $fixed_content)
where it is assigned from runPhpcbf and update every subsequent reference in the
method (all assertions and str_contains calls) to use the new name; ensure the
symbol to change is the variable assigned from runPhpcbf in
LocalVariableNamingSniffFunctionalTest (the $fixed variable) and update only its
usages within that test method so behavior remains identical.

---

Duplicate comments:
In `@tests/Functional/LocalVariableNamingSniffFunctionalTest.php`:
- Around line 211-213: The three brittle exact-string assertions in
LocalVariableNamingSniffFunctionalTest that call assertStringContainsString
(checking '@var \SomeClass $module_handler */', '@var
\Drupal\Core\Extension\ModuleHandler $module_handler */', and '@var
\Very\Long\Namespace\Path\To\SomeClass $module_handler */') should be replaced
with assertions that use a regex to validate "type + renamed variable"
semantics; update the tests to use PHPUnit's assertMatchesRegularExpression (or
assertRegExp) against $fixed to match a pattern like
/^@var\s+[\w\\]+\s+\$module_handler\b/ (or equivalent) so the test checks the
type token and $module_handler rather than exact full-line strings, and remove
the three exact assertStringContainsString calls.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 47263a86-13a7-4a99-9214-087d521a23f9

📥 Commits

Reviewing files that changed from the base of the PR and between b555a97 and 432f093.

📒 Files selected for processing (1)
  • tests/Functional/LocalVariableNamingSniffFunctionalTest.php

Comment on lines +205 to +242
$fixed = $this->runPhpcbf(
static::$fixtures . DIRECTORY_SEPARATOR . 'CommentVariableNaming.php',
'DrevOps.NamingConventions.LocalVariableNaming'
);

// Doc comments should be fixed.
$this->assertStringContainsString('@var \SomeClass $module_handler */', $fixed);
$this->assertStringContainsString('@var \Drupal\Core\Extension\ModuleHandler $module_handler */', $fixed);
$this->assertStringContainsString('@var \Very\Long\Namespace\Path\To\SomeClass $module_handler */', $fixed);

// FQN without leading backslash: PHPCS 3 tokenizes doc comment strings
// differently, so the fix may not apply. Assert either form is present.
$this->assertTrue(
str_contains($fixed, '@var Drupal\Core\Extension\ModuleHandler $module_handler */')
|| str_contains($fixed, '@var Drupal\Core\Extension\ModuleHandler $moduleHandler */'),
'FQN without leading backslash: variable should be fixed or original preserved.'
);

// Multi-line doc comment should be fixed.
$this->assertStringContainsString('@var \Drupal\Core\Extension\ModuleHandler $module_handler', $fixed);

// Mixed: doc comment var should be fixed.
$this->assertStringContainsString('@var \SomeClass $first_handler */', $fixed);

// Inline comments should NOT be fixed (default fixCommentTypes = 'doc').
$this->assertStringContainsString('// $moduleHandler holds the module handler.', $fixed);
$this->assertStringContainsString('/* $moduleHandler holds the module handler. */', $fixed);
$this->assertStringContainsString('// $secondHandler holds the second handler.', $fixed);

// Multi-variable comment should NOT be fixed.
$this->assertStringContainsString('@var \SomeClass $moduleHandler See also $otherService */', $fixed);

// Code between comment and variable: comment should NOT be fixed.
$this->assertStringContainsString('@var \SomeClass $moduleHandler */', $fixed);

// Trailing comment on previous statement should NOT be fixed.
$this->assertStringContainsString('// $moduleHandler trailing.', $fixed);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use snake_case for the local fixed-content variable.

$fixed violates the repository naming rule for local variables in PHP files.

♻️ Proposed rename
-    $fixed = $this->runPhpcbf(
+    $fixed_output = $this->runPhpcbf(
       static::$fixtures . DIRECTORY_SEPARATOR . 'CommentVariableNaming.php',
       'DrevOps.NamingConventions.LocalVariableNaming'
     );
@@
-    $this->assertStringContainsString('@var \SomeClass $module_handler */', $fixed);
+    $this->assertStringContainsString('@var \SomeClass $module_handler */', $fixed_output);
@@
-      str_contains($fixed, '@var Drupal\Core\Extension\ModuleHandler $module_handler */')
-      || str_contains($fixed, '@var Drupal\Core\Extension\ModuleHandler $moduleHandler */'),
+      str_contains($fixed_output, '@var Drupal\Core\Extension\ModuleHandler $module_handler */')
+      || str_contains($fixed_output, '@var Drupal\Core\Extension\ModuleHandler $moduleHandler */'),
@@
-    $this->assertStringContainsString('@var \Drupal\Core\Extension\ModuleHandler $module_handler', $fixed);
+    $this->assertStringContainsString('@var \Drupal\Core\Extension\ModuleHandler $module_handler', $fixed_output);
As per coding guidelines: `**/*.php`: Use snake_case for local variables and method parameters.
🧰 Tools
🪛 GitHub Actions: Test PHP

[error] 213-213: PHPUnit test 'testPhpcbfFixesCommentVariableReferences' failed: assertion did not pass for LocalVariableNamingSniffFunctionalTest. The generated fixture output contains a long FQN in a @var docblock ("@var \Very\Long\Namespace\Path\To\SomeClass $module_handler */"), causing the mismatch in the expected versus actual code after phpcbf autofix.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/Functional/LocalVariableNamingSniffFunctionalTest.php` around lines 205
- 242, The local variable $fixed in the test method violates the snake_case
rule; rename it to a snake_case identifier (e.g., $fixed_content) where it is
assigned from runPhpcbf and update every subsequent reference in the method (all
assertions and str_contains calls) to use the new name; ensure the symbol to
change is the variable assigned from runPhpcbf in
LocalVariableNamingSniffFunctionalTest (the $fixed variable) and update only its
usages within that test method so behavior remains identical.

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

♻️ Duplicate comments (1)
tests/Functional/LocalVariableNamingSniffFunctionalTest.php (1)

216-218: ⚠️ Potential issue | 🟠 Major

Pipeline failure: Assertion on line 218 is too brittle for cross-version compatibility.

The CI failure indicates the exact string match fails because PHPCS versions may produce different FQN formatting in the output. Since PHPCS 3 tokenization can vary (as noted in the commit message and line 210-211 comments), consider using a more flexible assertion.

🛠️ Proposed fix using regex assertion
       // Doc comments should be fixed.
       $this->assertStringContainsString('@var \SomeClass $module_handler */', $fixed);
       $this->assertStringContainsString('@var \Drupal\Core\Extension\ModuleHandler $module_handler */', $fixed);
-      $this->assertStringContainsString('@var \Very\Long\Namespace\Path\To\SomeClass $module_handler */', $fixed);
+      $this->assertMatchesRegularExpression(
+        '/@var\s+\\\\?Very\\\\Long\\\\Namespace\\\\Path\\\\To\\\\SomeClass\s+\$module_handler\b/',
+        $fixed
+      );

Alternatively, if the FQN output is inconsistent across PHPCS versions, consider checking only the essential part (the renamed variable):

$this->assertMatchesRegularExpression(
  '/@var\s+.*SomeClass\s+\$module_handler\s/',
  $fixed
);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/Functional/LocalVariableNamingSniffFunctionalTest.php` around lines 216
- 218, Replace the brittle exact-FQN assertion that uses
$this->assertStringContainsString with a regex-based assertion to tolerate PHPCS
FQN formatting differences: update the check against $fixed to use
$this->assertMatchesRegularExpression('/@var\s+.*SomeClass\s+\$module_handler\s/',
$fixed) (or a similar pattern) so the test only verifies the essential renamed
variable and class token (SomeClass and $module_handler) rather than an exact
fully-qualified namespace string.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/Functional/LocalVariableNamingSniffFunctionalTest.php`:
- Around line 210-212: Add a brief note about which PHPCS versions support
auto-fix for this sniff so future maintainers understand why the test condition
around $fixes_applied uses str_contains($fixed, '$module_handler =
get_service('). Add this documentation either as a one-line comment immediately
above the $fixes_applied check in LocalVariableNamingSniffFunctionalTest (to
explain the test behavior) and/or in the docblock of the
LocalVariableNamingSniff class (to document the sniff capability), stating the
minimum PHPCS version that provides auto-fix for this sniff.

---

Duplicate comments:
In `@tests/Functional/LocalVariableNamingSniffFunctionalTest.php`:
- Around line 216-218: Replace the brittle exact-FQN assertion that uses
$this->assertStringContainsString with a regex-based assertion to tolerate PHPCS
FQN formatting differences: update the check against $fixed to use
$this->assertMatchesRegularExpression('/@var\s+.*SomeClass\s+\$module_handler\s/',
$fixed) (or a similar pattern) so the test only verifies the essential renamed
variable and class token (SomeClass and $module_handler) rather than an exact
fully-qualified namespace string.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 236f8836-6e75-4a61-bfd8-cbca86a5f67c

📥 Commits

Reviewing files that changed from the base of the PR and between 432f093 and 5109da3.

📒 Files selected for processing (1)
  • tests/Functional/LocalVariableNamingSniffFunctionalTest.php

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.

♻️ Duplicate comments (1)
tests/Functional/LocalVariableNamingSniffFunctionalTest.php (1)

205-208: 🛠️ Refactor suggestion | 🟠 Major

Use snake_case for the $fixed variable.

The local variable $fixed should follow the snake_case convention. Consider renaming to $fixed_output or $fixed_content.

♻️ Proposed rename
-    $fixed = $this->runPhpcbf(
+    $fixed_output = $this->runPhpcbf(
       static::$fixtures . DIRECTORY_SEPARATOR . 'CommentVariableNaming.php',
       'DrevOps.NamingConventions.LocalVariableNaming'
     );

Then update all references to $fixed in the method to use $fixed_output.

As per coding guidelines: **/*.php: Use snake_case for local variables and method parameters.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/Functional/LocalVariableNamingSniffFunctionalTest.php` around lines 205
- 208, The local variable $fixed in LocalVariableNamingSniffFunctionalTest
should use snake_case; rename $fixed to $fixed_output and update every reference
in this test method (including the call to $this->runPhpcbf(...) and any
subsequent assertions or uses) to $fixed_output so the variable name follows the
project's snake_case convention.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@tests/Functional/LocalVariableNamingSniffFunctionalTest.php`:
- Around line 205-208: The local variable $fixed in
LocalVariableNamingSniffFunctionalTest should use snake_case; rename $fixed to
$fixed_output and update every reference in this test method (including the call
to $this->runPhpcbf(...) and any subsequent assertions or uses) to $fixed_output
so the variable name follows the project's snake_case convention.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 95562606-b008-4df8-bcb1-5138cbe401e9

📥 Commits

Reviewing files that changed from the base of the PR and between 5109da3 and 3bc8173.

📒 Files selected for processing (1)
  • tests/Functional/LocalVariableNamingSniffFunctionalTest.php

@AlexSkrypnyk AlexSkrypnyk merged commit caee870 into main Mar 12, 2026
11 checks passed
@AlexSkrypnyk AlexSkrypnyk deleted the feature/17-fix-comment-vars branch March 12, 2026 23:43
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.

Variables references in comments are not updated when variable name was updated

1 participant