Skip to content

feat!: laravel 13 support, PHP 8.3 requirement, Composer dependencies update#766

Open
JauheniS wants to merge 16 commits intowayofdev:masterfrom
JauheniS:laravel-updates
Open

feat!: laravel 13 support, PHP 8.3 requirement, Composer dependencies update#766
JauheniS wants to merge 16 commits intowayofdev:masterfrom
JauheniS:laravel-updates

Conversation

@JauheniS
Copy link
Copy Markdown

@JauheniS JauheniS commented Mar 22, 2026

🔍 Changes Made

  • Raised the minimum supported PHP version to 8.3 to match the current Laravel ecosystem and avoid using 8.2 that is not supported by Laravel 13, and Laravel 10 and PHP 8.2 are already out of active support
  • Updated the documentation to explicitly state that this bridge supports Laravel 13
  • Updated the installation docs to reflect the new PHP 8.3 requirement and Laravel 13 compatibility
  • Refreshed dependency metadata in composer.json and composer.lock to keep the project aligned with the current supported stack
  • Updated GitHub workflows so the CI matrix runs against PHP versions starting from 8.3 through 8.5
  • Adjusted the local container setup in docker-compose.yaml to enable interactive terminal support, also to use mssql18 in command for the sqlserver

🤔 Rationale

  • The repository should clearly reflect the versions it supports, both in documentation and automation
  • PHP 8.3 is the practical minimum now for Laravel 12/13-era projects, and documenting it avoids confusion for users
  • Adding Laravel 13 support in docs helps users adopt the bridge
  • Updating CI ensures the project is verified on the PHP versions it is expected to support
  • The Docker configuration change improves developer experience when working interactively in the container

🎟️ Related Tickets & Documents

📋 Checklist

  • My code follows the contributing guidelines of this project
  • I have performed a self-review of my own code
  • I have made corresponding changes to the documentation (if necessary)
  • Tests via make test passes locally with my changes
  • Linting via make lint passes locally with my changes

🧪 Added or updated tests?

  • Yes
  • No, and this is why: these changes are limited to version/support updates, documentation, and CI/container configuration. Existing test coverage is sufficient for validating behavior.
  • I need help with writing tests

Summary by CodeRabbit

  • New Features

    • Database assertion helpers accept models/iterables/table names and added assertDatabaseEmpty.
  • Bug Fixes

    • Improved service readiness/health-check reliability and CLI output handling.
  • Documentation

    • Raised PHP requirement to 8.3+, updated compatibility/installation tables, clarified security-issue link text, and documented the new assertion.
  • Tests

    • Added validation-rule and database integration tests.
  • Chores

    • Updated PHP platform/dependency constraints, Docker image tag, and pre-commit hook execution behavior.

@JauheniS JauheniS requested a review from lotyp as a code owner March 22, 2026 12:56
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 22, 2026

@JauheniS is attempting to deploy a commit to the wayofdev Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 22, 2026

📝 Walkthrough

Walkthrough

Bumps PHP and Docker images to 8.3/8.4, updates many Composer constraints, refactors DB rule/constraint queries to use the query builder, extends testing assertion helpers to accept iterables and model-to-table normalization, adds docblocks/#[Override] attributes, updates docs, CI, pre-commit hooks, and adds new DB-focused tests.

Changes

Cohort / File(s) Summary
Composer & Container
composer.json, docker-compose.yaml
Raise PHP requirement (^8.2→^8.3; platform 8.4), bump multiple deps/dev-deps, and update app image to PHP 8.4 tag and sqlcmd path/flags.
CI & Hooks
.github/workflows/testing-mssql.yml, .pre-commit-config.yaml
Quote shell variables/substitutions in MSSQL readiness script and docker logs; pre-commit hook runs php-cs-fixer locally if php exists, otherwise via docker compose.
Docs & README
README.md, docs/pages/getting-started/installation.mdx, docs/pages/services/testing.mdx, .github/SECURITY.md
Add PHP column to compatibility map and raise PHP/Laravel ranges; document assertDatabaseEmpty; change SECURITY link text.
Static Analysis Baselines
phpstan.neon.dist, psalm-baseline.xml
Add PHPStan ignore rule; update Psalm baseline and remove several baselined issues.
Database Assertions / Trait
src/Testing/Concerns/InteractsWithDatabase.php, src/Testing/Constraints/*, src/Testing/RefreshDatabase.php
Assertions accept iterable tables, add normalizeTable() (model/class→table name resolution), delegate emptiness to count, switch constraint query construction to select()->from(...)->where(...)->count(), simplify exception catches, add docblocks/#[Override].
Validation Rules
src/Bridge/Laravel/Rules/Exists.php, src/Bridge/Laravel/Rules/Unique.php
Replace table() usage with select()->from(...)->where(...)->count() chains; remove SelectQuery imports; add constructor docblocks.
Console & Provider Docs
src/Bridge/Laravel/Console/Commands/Database/ListCommand.php, src/Bridge/Laravel/Console/Commands/Database/TableCommand.php, src/Bridge/Laravel/Providers/CycleServiceProvider.php, src/Bridge/Laravel/Facades/Cycle.php
Add/extend PHPDoc blocks; change ListCommand empty output to $this->error(...); add method docblocks in TableCommand; small doc updates.
Contracts & Schema Docs
src/Contracts/GeneratorLoader.php, src/Contracts/CacheManager.php, src/Schema/..., src/Support/Arr.php, src/Schema/Cache/Manager.php
Add/adjust PHPDoc (e.g., @return static) across generator, cache, schema, and support helpers; no signature changes.
Tests Added / Updated
tests/src/...
Add tests for Exists/Unique rules and InteractsWithDatabase behaviors; annotate overrides in TestCase; small test cleanup and import removals.
Small docs/config tweaks
.github/SECURITY.md
Change link text to instruct readers to "create a new issue" (URL unchanged).

Sequence Diagram(s)

sequenceDiagram
  participant Test as "Test\n(caller)"
  participant Trait as "InteractsWithDatabase\n(assertion trait)"
  participant Resolver as "ORM/Schema\nResolver"
  participant DB as "DatabaseProvider\n(select/count)"
  participant Constraint as "Constraint\n(Count/Has/SoftDelete)"

  Test->>Trait: call assertDatabaseX(tableOrIterable, ...)
  Trait->>Trait: if iterable -> for each item -> recurse
  Trait->>Resolver: normalizeTable(item) (Model/class -> tableName)
  Resolver-->>Trait: tableName
  Trait->>DB: select()->from(tableName)->where(...)->count()
  DB-->>Trait: rowCount
  Trait->>Constraint: evaluate(rowCount vs expectation)
  Constraint-->>Test: assertion result (pass/fail)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

type: maintenance, type: enhancement, type: documentation

Poem

🐇 I hopped through branches, nibbled docs with glee,
switched PHP versions and queries to spree.
Tests now find tables, rules count true and neat,
CI and pre-commit march with tidy feet.
A rabbit cheers — all changes stitched and sweet.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically summarizes the main changes: raising PHP requirement to 8.3, adding Laravel 13 support, and updating Composer dependencies.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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
Copy Markdown

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

Caution

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

⚠️ Outside diff range comments (1)
src/Testing/Concerns/InteractsWithDatabase.php (1)

90-111: ⚠️ Potential issue | 🟠 Major

Iterable support is documented but not implemented in four assertions.

Line 90, Line 106, Line 130, and Line 152 advertise iterable<Model>|string, but assertDatabaseCount, assertDatabaseEmpty, assertSoftDeleted, and assertNotSoftDeleted do not branch on is_iterable($table). This creates a contract/runtime mismatch.

Either add the same iterable loop used in assertDatabaseHas/assertDatabaseMissing or narrow those docblocks back to supported input types.

Also applies to: 129-171

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

In `@src/Testing/Concerns/InteractsWithDatabase.php` around lines 90 - 111, The
docblocks for assertDatabaseCount, assertDatabaseEmpty, assertSoftDeleted, and
assertNotSoftDeleted claim they accept iterable<Model>|string but the methods
don’t handle iterables; update each method (assertDatabaseCount,
assertDatabaseEmpty, assertSoftDeleted, assertNotSoftDeleted) to branch on
is_iterable($table) and iterate over each Model/string entry, calling the
existing single-item assertion logic for each element (same pattern as
assertDatabaseHas/assertDatabaseMissing), or alternatively remove iterable from
the docblocks if you prefer to restrict inputs—implement the iterable loop to
preserve the documented contract.
🧹 Nitpick comments (5)
docs/pages/getting-started/installation.mdx (1)

11-21: Clarify that Laravel 10 rows are legacy compatibility entries.

Line 11 says current prerequisites are Laravel 11.x–13.x, but Lines 18–20 still list Laravel 10 combinations. A short note like “legacy adapter compatibility” above those rows would remove ambiguity for new installs.

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

In `@docs/pages/getting-started/installation.mdx` around lines 11 - 21, Add a
short clarifying note above the Compatibility Map table (or directly above the
rows containing `^10.28`) stating that entries referencing Laravel 10 are legacy
adapter compatibility entries; update the table label or insert a one-line
annotation such as "Note: rows referencing `^10.28` indicate legacy adapter
compatibility for Laravel 10" so readers understand the current prerequisites
are Laravel 11.x–13.x while still preserving the older compatibility rows.
docker-compose.yaml (1)

5-5: Consider parameterizing the PHP dev image tag.

Line 5 hardcodes 8.4-cli-alpine-latest; exposing this via env (with 8.4 default) would make local compatibility checks against 8.3 easier without editing the compose file.

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

In `@docker-compose.yaml` at line 5, The docker-compose service hardcodes the PHP
dev image tag ("wayofdev/php-dev:8.4-cli-alpine-latest") which makes switching
versions cumbersome; change the service's image field to use an environment
variable (e.g. PHP_DEV_IMAGE) with a default of
"wayofdev/php-dev:8.4-cli-alpine-latest" so consumers can override at runtime,
and add a note/example in the project .env or README showing how to set
PHP_DEV_IMAGE to "wayofdev/php-dev:8.3-cli-alpine-latest" for local
compatibility checks.
tests/src/Testing/InteractsWithDatabaseTest.php (1)

20-23: Consider centralizing DB migration bootstrap for tests.

This migration sequence is duplicated in tests/src/Bridge/Laravel/Rules/ValidationRulesTest.php (Line 28-30). Moving it into a shared test helper/trait would reduce maintenance drift.

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

In `@tests/src/Testing/InteractsWithDatabaseTest.php` around lines 20 - 23, The
three artisan migration calls are duplicated; extract them into a shared test
trait (e.g., DatabaseMigrationBootstrapTrait) with a single public method (e.g.,
bootstrapDatabaseMigrations() or use setUpDatabaseMigrations() called from
setUp) that runs $this->artisan('cycle:migrate:init'),
$this->artisan('cycle:orm:migrate', ['--force' => true]) and
$this->artisan('cycle:migrate', ['--force' => true]); add that trait to
InteractsWithDatabaseTest and Bridge/Laravel/Rules/ValidationRulesTest and
replace the duplicated lines with a single call to the trait method (or rely on
the trait to run in setUp), ensuring method and trait names match where
referenced.
.pre-commit-config.yaml (1)

24-24: Avoid duplicating the php-cs-fixer invocation string.

The same command flags are repeated in both branches, which is easy to desynchronize later. Consider extracting it into one variable.

♻️ Suggested simplification
-        entry: bash -c "if command -v php &> /dev/null; then php vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --verbose --diff; else docker compose run --rm --no-deps app php vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --verbose --diff; fi"
+        entry: bash -c 'cmd="php vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --verbose --diff"; if command -v php > /dev/null 2>&1; then $cmd; else docker compose run --rm --no-deps app $cmd; fi'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.pre-commit-config.yaml at line 24, The pre-commit entry duplicates the
php-cs-fixer invocation; refactor the bash -c string to define a single variable
for the php-cs-fixer command (e.g., CMD="php vendor/bin/php-cs-fixer fix
--config=.php-cs-fixer.dist.php --verbose --diff") and then use that variable in
both branches of the if/else so the flags are declared once; update the existing
entry value (the entry string currently containing the full if/then/else) to set
the variable and invoke it in both branches (use the same variable name) to
avoid duplication.
tests/src/Bridge/Laravel/Rules/ValidationRulesTest.php (1)

44-48: Minor duplication: extract the fail-callback builder.

The same closure body appears four times; pulling it into a tiny private helper would keep this test easier to evolve.

Also applies to: 53-57, 73-77, 82-86

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

In `@tests/src/Bridge/Laravel/Rules/ValidationRulesTest.php` around lines 44 - 48,
In ValidationRulesTest, extract the duplicated fail-callback closure used in
calls to $rule->validate(...) that constructs a PotentiallyTranslatedString into
a small private helper (e.g., a method on the test class like buildFailCallback
or makeFailCallback) so each test calls $rule->validate('id', $post->id(),
$this->makeFailCallback()) instead of duplicating the closure; ensure the helper
returns a Closure matching the validate signature and constructs new
PotentiallyTranslatedString($message, app('translator')) so you can replace the
four identical inline closures (lines shown around the validate calls) with a
single helper invocation.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@composer.json`:
- Line 45: The composer.json currently requires "php": "^8.3" but pins
config.platform.php to 8.4.19; update composer.json so config.platform.php
matches the declared minimum by either changing config.platform.php to "8.3.0"
or removing the entire "platform" override section; locate the "config" →
"platform" → "php" entry in composer.json and make the change so dependency
resolution and tests run against the documented minimum PHP version.

In `@phpstan.neon.dist`:
- Around line 13-15: The phpstan suppression for the message "#Called 'env'
outside of the config directory#" is a blanket rule that should be removed or
justified; either delete the ignoreErrors entry that contains that message from
phpstan.neon.dist, or retain it but add a clear comment immediately above the
ignoreErrors block documenting why it was added (include the original risk,
file/PR/ticket that introduced it, and any conditions under which it can be
safely removed) so future reviewers know why the suppression exists; reference
the message string "#Called 'env' outside of the config directory#" to locate
the exact rule to remove or annotate.

In `@README.md`:
- Around line 62-63: The adapter range in the row with "`11.x, 12.x, 13.x`"
currently reads "`≥5.0.0`" which overlaps the above row's "`5.0.0`"; update that
cell to a non-overlapping value by replacing "`≥5.0.0`" with either the exact
first post-5.0.0 release that added Laravel 13 support (e.g. "`5.0.1`" if that's
the correct release) or with a strictly-greater range such as "`>5.0.0`" so the
table no longer implies `5.0.0` belongs to both rows.

In `@src/Bridge/Laravel/Console/Commands/Database/ListCommand.php`:
- Around line 55-58: The error branch in ListCommand (when count($databases) ===
0) currently calls $this->error('No databases found.') but returns
self::SUCCESS; change the return to self::FAILURE so the handle/execute method
returns a non-zero exit code on error. Locate the conditional in the ListCommand
class (the method handling the command, e.g., handle/execute) and replace the
success constant with self::FAILURE to ensure CI/scripts detect the failure.

In `@src/Testing/Concerns/InteractsWithDatabase.php`:
- Around line 39-57: The documented support for Model|iterable<Model>|string
isn't being normalized to table names; update all six assertion
methods—assertDatabaseHas, assertDatabaseMissing, assertDatabaseCount,
assertDatabaseEmpty, assertSoftDeleted, and assertNotSoftDeleted—to call
$this->normalizeTable($table) before passing the value to the constraint classes
(e.g., HasInDatabase, CountInDatabase, etc.), and ensure iterable handling
mirrors assertDatabaseHas/assertDatabaseMissing by normalizing each item when
$table is iterable so constraints always receive a string table name.

In `@src/Testing/Constraints/NotSoftDeletedInDatabase.php`:
- Around line 52-55: The toString() method in NotSoftDeletedInDatabase returns
json_encode($this->data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) which can
return false despite the string return type; update the flags to include
JSON_THROW_ON_ERROR (matching the approach used in HasInDatabase) so
json_encode() will throw on failure and guarantee a string return, i.e., adjust
NotSoftDeletedInDatabase::toString() to pass JSON_THROW_ON_ERROR along with the
existing flags.

In `@src/Testing/Constraints/SoftDeletedInDatabase.php`:
- Around line 52-55: The toString() method in SoftDeletedInDatabase currently
returns json_encode(...), which can return false and break the declared string
return type; change it to call json_encode($this->data, JSON_PRETTY_PRINT |
JSON_UNESCAPED_UNICODE) into a variable, check if the result is === false, and
if so return a safe string fallback (e.g. a compact fallback using
print_r($this->data, true) or a JSON string containing json_last_error_msg()),
otherwise return the encoded string—this ensures toString() always returns a
string and preserves error details for debugging.

---

Outside diff comments:
In `@src/Testing/Concerns/InteractsWithDatabase.php`:
- Around line 90-111: The docblocks for assertDatabaseCount,
assertDatabaseEmpty, assertSoftDeleted, and assertNotSoftDeleted claim they
accept iterable<Model>|string but the methods don’t handle iterables; update
each method (assertDatabaseCount, assertDatabaseEmpty, assertSoftDeleted,
assertNotSoftDeleted) to branch on is_iterable($table) and iterate over each
Model/string entry, calling the existing single-item assertion logic for each
element (same pattern as assertDatabaseHas/assertDatabaseMissing), or
alternatively remove iterable from the docblocks if you prefer to restrict
inputs—implement the iterable loop to preserve the documented contract.

---

Nitpick comments:
In @.pre-commit-config.yaml:
- Line 24: The pre-commit entry duplicates the php-cs-fixer invocation; refactor
the bash -c string to define a single variable for the php-cs-fixer command
(e.g., CMD="php vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php
--verbose --diff") and then use that variable in both branches of the if/else so
the flags are declared once; update the existing entry value (the entry string
currently containing the full if/then/else) to set the variable and invoke it in
both branches (use the same variable name) to avoid duplication.

In `@docker-compose.yaml`:
- Line 5: The docker-compose service hardcodes the PHP dev image tag
("wayofdev/php-dev:8.4-cli-alpine-latest") which makes switching versions
cumbersome; change the service's image field to use an environment variable
(e.g. PHP_DEV_IMAGE) with a default of "wayofdev/php-dev:8.4-cli-alpine-latest"
so consumers can override at runtime, and add a note/example in the project .env
or README showing how to set PHP_DEV_IMAGE to
"wayofdev/php-dev:8.3-cli-alpine-latest" for local compatibility checks.

In `@docs/pages/getting-started/installation.mdx`:
- Around line 11-21: Add a short clarifying note above the Compatibility Map
table (or directly above the rows containing `^10.28`) stating that entries
referencing Laravel 10 are legacy adapter compatibility entries; update the
table label or insert a one-line annotation such as "Note: rows referencing
`^10.28` indicate legacy adapter compatibility for Laravel 10" so readers
understand the current prerequisites are Laravel 11.x–13.x while still
preserving the older compatibility rows.

In `@tests/src/Bridge/Laravel/Rules/ValidationRulesTest.php`:
- Around line 44-48: In ValidationRulesTest, extract the duplicated
fail-callback closure used in calls to $rule->validate(...) that constructs a
PotentiallyTranslatedString into a small private helper (e.g., a method on the
test class like buildFailCallback or makeFailCallback) so each test calls
$rule->validate('id', $post->id(), $this->makeFailCallback()) instead of
duplicating the closure; ensure the helper returns a Closure matching the
validate signature and constructs new PotentiallyTranslatedString($message,
app('translator')) so you can replace the four identical inline closures (lines
shown around the validate calls) with a single helper invocation.

In `@tests/src/Testing/InteractsWithDatabaseTest.php`:
- Around line 20-23: The three artisan migration calls are duplicated; extract
them into a shared test trait (e.g., DatabaseMigrationBootstrapTrait) with a
single public method (e.g., bootstrapDatabaseMigrations() or use
setUpDatabaseMigrations() called from setUp) that runs
$this->artisan('cycle:migrate:init'), $this->artisan('cycle:orm:migrate',
['--force' => true]) and $this->artisan('cycle:migrate', ['--force' => true]);
add that trait to InteractsWithDatabaseTest and
Bridge/Laravel/Rules/ValidationRulesTest and replace the duplicated lines with a
single call to the trait method (or rely on the trait to run in setUp), ensuring
method and trait names match where referenced.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 22af0bdc-46ef-419c-8250-69fbe8feb207

📥 Commits

Reviewing files that changed from the base of the PR and between 9e411a2 and 1b5b109.

⛔ Files ignored due to path filters (1)
  • composer.lock is excluded by !**/*.lock
📒 Files selected for processing (23)
  • .github/SECURITY.md
  • .github/workflows/testing-mssql.yml
  • .pre-commit-config.yaml
  • README.md
  • composer.json
  • docker-compose.yaml
  • docs/pages/getting-started/installation.mdx
  • docs/pages/services/testing.mdx
  • phpstan.neon.dist
  • psalm-baseline.xml
  • src/Bridge/Laravel/Console/Commands/Database/ListCommand.php
  • src/Bridge/Laravel/Console/Commands/Database/TableCommand.php
  • src/Bridge/Laravel/Rules/Exists.php
  • src/Bridge/Laravel/Rules/Unique.php
  • src/Contracts/GeneratorLoader.php
  • src/Testing/Concerns/InteractsWithDatabase.php
  • src/Testing/Constraints/HasInDatabase.php
  • src/Testing/Constraints/NotSoftDeletedInDatabase.php
  • src/Testing/Constraints/SoftDeletedInDatabase.php
  • tests/src/Bridge/Laravel/Providers/CycleServiceProviderTest.php
  • tests/src/Bridge/Laravel/Rules/ValidationRulesTest.php
  • tests/src/TestCase.php
  • tests/src/Testing/InteractsWithDatabaseTest.php

Copy link
Copy Markdown

@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 (1)
src/Testing/Concerns/InteractsWithDatabase.php (1)

205-225: Well-structured normalization with graceful fallback.

The logic correctly prioritizes:

  1. Eloquent Model → getTable()
  2. Cycle ORM entity/class → schema lookup
  3. Fallback → string cast

Consider adding a brief comment to the empty catch block to clarify intent for future maintainers:

💡 Optional: Document the silent catch
             if ($schema->defines($role)) {
                 return (string) $schema->define($role, SchemaInterface::TABLE);
             }
-        } catch (Throwable) {
+        } catch (Throwable) {
+            // ORM unavailable or role not defined; fall through to string cast
         }
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Testing/Concerns/InteractsWithDatabase.php` around lines 205 - 225, The
empty catch in normalizeTable is intentional to silently ignore errors during
schema lookup; add a brief inline comment inside the catch block (in the
normalizeTable method) such as "// ignore schema resolution errors — fall back
to string table name" so future maintainers understand the silence, and ensure
you do not change the existing behavior or remove the fallback return.
🤖 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/Testing/Concerns/InteractsWithDatabase.php`:
- Around line 50-65: The assertion methods (assertDatabaseHas,
assertDatabaseMissing, assertDatabaseCount, assertDatabaseEmpty,
assertSoftDeleted, assertNotSoftDeleted) accept a $connection parameter but
never forward it to the constraint classes; update each method so the created
constraint instances (HasInDatabase, CountInDatabase, SoftDeletedInDatabase,
NotSoftDeletedInDatabase) receive the $connection argument when constructed
(using app(DatabaseProviderInterface::class) as the first arg remains the same),
and ensure recursive iterable handling continues to pass $connection through;
this will make multi-connection assertions actually use the provided connection.

---

Nitpick comments:
In `@src/Testing/Concerns/InteractsWithDatabase.php`:
- Around line 205-225: The empty catch in normalizeTable is intentional to
silently ignore errors during schema lookup; add a brief inline comment inside
the catch block (in the normalizeTable method) such as "// ignore schema
resolution errors — fall back to string table name" so future maintainers
understand the silence, and ensure you do not change the existing behavior or
remove the fallback return.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 75aa7d69-bfda-4071-887c-7ac94cb57c8e

📥 Commits

Reviewing files that changed from the base of the PR and between 8a737ae and b0f230d.

📒 Files selected for processing (1)
  • src/Testing/Concerns/InteractsWithDatabase.php

@JauheniS JauheniS changed the title Laravel updates Update: Laravel 13 support, PHP 8.3 requirement, Composer dependencies update Mar 23, 2026
Copy link
Copy Markdown

@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.

🧹 Nitpick comments (1)
tests/src/Testing/InteractsWithDatabaseTest.php (1)

34-38: Consider extracting a small post-persistence helper to reduce repetition.

The repeated EntityManagerInterface + Post persist/run blocks can be centralized for cleaner tests and easier future edits.

♻️ Optional refactor
 final class InteractsWithDatabaseTest extends TestCase
 {
+    private function persistPost(string $title = 'Title', string $description = 'Description'): Post
+    {
+        $em = app(EntityManagerInterface::class);
+        $post = new Post($title, $description);
+        $em->persist($post);
+        $em->run();
+
+        return $post;
+    }
+
     #[Test]
     public function it_asserts_database_has_and_missing(): void
     {
-        $em = app(EntityManagerInterface::class);
-        $post = new Post('Title', 'Description');
-        $em->persist($post);
-        $em->run();
+        $post = $this->persistPost();

Also applies to: 55-60, 80-84, 97-103, 113-117, 130-133

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

In `@tests/src/Testing/InteractsWithDatabaseTest.php` around lines 34 - 38,
Extract a small helper that creates and persists a Post to remove the duplicated
EntityManagerInterface + Post + persist + run pattern: add a private method
(e.g., createAndPersistPost(string $title = 'Title', string $description =
'Description')) in the InteractsWithDatabaseTest class or a test trait that
calls app(EntityManagerInterface::class), instantiates new Post($title,
$description), calls $em->persist($post) and $em->run(), then returns the
persisted Post; replace the repeated blocks (the snippets using
EntityManagerInterface, new Post(...), persist, run at lines referenced) with
calls to this helper to centralize behavior and make future changes easier.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/src/Testing/InteractsWithDatabaseTest.php`:
- Around line 34-38: Extract a small helper that creates and persists a Post to
remove the duplicated EntityManagerInterface + Post + persist + run pattern: add
a private method (e.g., createAndPersistPost(string $title = 'Title', string
$description = 'Description')) in the InteractsWithDatabaseTest class or a test
trait that calls app(EntityManagerInterface::class), instantiates new
Post($title, $description), calls $em->persist($post) and $em->run(), then
returns the persisted Post; replace the repeated blocks (the snippets using
EntityManagerInterface, new Post(...), persist, run at lines referenced) with
calls to this helper to centralize behavior and make future changes easier.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5fc8d9b8-9e20-419d-91ee-105bc29fb31b

📥 Commits

Reviewing files that changed from the base of the PR and between b0f230d and 1e9b86f.

📒 Files selected for processing (23)
  • src/Bridge/Laravel/Console/Commands/Database/ListCommand.php
  • src/Bridge/Laravel/Console/Commands/Database/TableCommand.php
  • src/Bridge/Laravel/Facades/Cycle.php
  • src/Bridge/Laravel/Providers/CycleServiceProvider.php
  • src/Bridge/Laravel/Rules/Exists.php
  • src/Bridge/Laravel/Rules/Unique.php
  • src/Contracts/CacheManager.php
  • src/Contracts/GeneratorLoader.php
  • src/Schema/Cache/Manager.php
  • src/Schema/Compiler.php
  • src/Schema/Config/SchemaConfig.php
  • src/Schema/Generators/GeneratorQueue.php
  • src/Support/Arr.php
  • src/Testing/Concerns/InteractsWithDatabase.php
  • src/Testing/Constraints/CountInDatabase.php
  • src/Testing/Constraints/HasInDatabase.php
  • src/Testing/Constraints/NotSoftDeletedInDatabase.php
  • src/Testing/Constraints/SoftDeletedInDatabase.php
  • src/Testing/RefreshDatabase.php
  • tests/src/Bridge/Laravel/Providers/CycleServiceProviderTest.php
  • tests/src/Bridge/Laravel/Rules/ValidationRulesTest.php
  • tests/src/TestCase.php
  • tests/src/Testing/InteractsWithDatabaseTest.php
✅ Files skipped from review due to trivial changes (11)
  • src/Testing/RefreshDatabase.php
  • src/Bridge/Laravel/Facades/Cycle.php
  • src/Schema/Generators/GeneratorQueue.php
  • src/Support/Arr.php
  • src/Schema/Compiler.php
  • src/Bridge/Laravel/Console/Commands/Database/TableCommand.php
  • src/Schema/Config/SchemaConfig.php
  • src/Contracts/CacheManager.php
  • src/Bridge/Laravel/Providers/CycleServiceProvider.php
  • src/Schema/Cache/Manager.php
  • src/Testing/Constraints/CountInDatabase.php
🚧 Files skipped from review as they are similar to previous changes (11)
  • src/Bridge/Laravel/Rules/Exists.php
  • tests/src/Bridge/Laravel/Providers/CycleServiceProviderTest.php
  • src/Contracts/GeneratorLoader.php
  • tests/src/Bridge/Laravel/Rules/ValidationRulesTest.php
  • tests/src/TestCase.php
  • src/Testing/Constraints/HasInDatabase.php
  • src/Bridge/Laravel/Console/Commands/Database/ListCommand.php
  • src/Bridge/Laravel/Rules/Unique.php
  • src/Testing/Concerns/InteractsWithDatabase.php
  • src/Testing/Constraints/SoftDeletedInDatabase.php
  • src/Testing/Constraints/NotSoftDeletedInDatabase.php

@JauheniS
Copy link
Copy Markdown
Author

@coderabbitai resume

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 25, 2026

✅ Actions performed

Reviews resumed.

Copy link
Copy Markdown

@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)
src/Testing/Constraints/NotSoftDeletedInDatabase.php (1)

61-64: ⚠️ Potential issue | 🟡 Minor

Add JSON_THROW_ON_ERROR in toString() to keep the string contract safe.

Line 63 uses json_encode(...) without JSON_THROW_ON_ERROR, so encode failures can still break the declared string return guarantee.

💡 Proposed fix
     public function toString(): string
     {
-        return json_encode($this->data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
+        return json_encode(
+            $this->data,
+            JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR
+        );
     }
#!/bin/bash
# Verify all constraint toString/json_encode usages and check for JSON_THROW_ON_ERROR coverage.
rg -n --type=php 'function\s+toString\s*\(|json_encode\(|JSON_THROW_ON_ERROR' src/Testing/Constraints -C2
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/Testing/Constraints/NotSoftDeletedInDatabase.php` around lines 61 - 64,
Update the NotSoftDeletedInDatabase::toString method to call json_encode with
JSON_THROW_ON_ERROR combined with the existing JSON_PRETTY_PRINT |
JSON_UNESCAPED_UNICODE flags, and wrap the call in a try/catch for
\JsonException so the method still always returns a string (e.g., return a safe
fallback string or a simple error message when encoding fails); adjust the
return path to guarantee the declared string contract while keeping the original
flags (JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/Testing/Constraints/NotSoftDeletedInDatabase.php`:
- Around line 61-64: Update the NotSoftDeletedInDatabase::toString method to
call json_encode with JSON_THROW_ON_ERROR combined with the existing
JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE flags, and wrap the call in a
try/catch for \JsonException so the method still always returns a string (e.g.,
return a safe fallback string or a simple error message when encoding fails);
adjust the return path to guarantee the declared string contract while keeping
the original flags (JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE |
JSON_THROW_ON_ERROR).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 58a6a853-8f77-4673-81be-4a7c47795776

📥 Commits

Reviewing files that changed from the base of the PR and between b0f230d and af8fa2f.

📒 Files selected for processing (23)
  • src/Bridge/Laravel/Console/Commands/Database/ListCommand.php
  • src/Bridge/Laravel/Console/Commands/Database/TableCommand.php
  • src/Bridge/Laravel/Facades/Cycle.php
  • src/Bridge/Laravel/Providers/CycleServiceProvider.php
  • src/Bridge/Laravel/Rules/Exists.php
  • src/Bridge/Laravel/Rules/Unique.php
  • src/Contracts/CacheManager.php
  • src/Contracts/GeneratorLoader.php
  • src/Schema/Cache/Manager.php
  • src/Schema/Compiler.php
  • src/Schema/Config/SchemaConfig.php
  • src/Schema/Generators/GeneratorQueue.php
  • src/Support/Arr.php
  • src/Testing/Concerns/InteractsWithDatabase.php
  • src/Testing/Constraints/CountInDatabase.php
  • src/Testing/Constraints/HasInDatabase.php
  • src/Testing/Constraints/NotSoftDeletedInDatabase.php
  • src/Testing/Constraints/SoftDeletedInDatabase.php
  • src/Testing/RefreshDatabase.php
  • tests/src/Bridge/Laravel/Providers/CycleServiceProviderTest.php
  • tests/src/Bridge/Laravel/Rules/ValidationRulesTest.php
  • tests/src/TestCase.php
  • tests/src/Testing/InteractsWithDatabaseTest.php
✅ Files skipped from review due to trivial changes (12)
  • src/Bridge/Laravel/Facades/Cycle.php
  • src/Testing/RefreshDatabase.php
  • src/Schema/Generators/GeneratorQueue.php
  • src/Schema/Compiler.php
  • src/Schema/Config/SchemaConfig.php
  • src/Bridge/Laravel/Console/Commands/Database/TableCommand.php
  • src/Schema/Cache/Manager.php
  • src/Bridge/Laravel/Providers/CycleServiceProvider.php
  • src/Contracts/GeneratorLoader.php
  • src/Contracts/CacheManager.php
  • src/Testing/Constraints/CountInDatabase.php
  • src/Support/Arr.php
🚧 Files skipped from review as they are similar to previous changes (10)
  • src/Bridge/Laravel/Console/Commands/Database/ListCommand.php
  • src/Bridge/Laravel/Rules/Exists.php
  • src/Bridge/Laravel/Rules/Unique.php
  • src/Testing/Constraints/HasInDatabase.php
  • tests/src/Bridge/Laravel/Providers/CycleServiceProviderTest.php
  • tests/src/Bridge/Laravel/Rules/ValidationRulesTest.php
  • src/Testing/Constraints/SoftDeletedInDatabase.php
  • src/Testing/Concerns/InteractsWithDatabase.php
  • tests/src/TestCase.php
  • tests/src/Testing/InteractsWithDatabaseTest.php

@lotyp lotyp changed the title Update: Laravel 13 support, PHP 8.3 requirement, Composer dependencies update feat!: laravel 13 support, PHP 8.3 requirement, Composer dependencies update Mar 25, 2026
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.

[Feature]: Laravel 13 and PHP 8.5 support

1 participant