fix: show failure details in compact mode#32
Conversation
Previously when running gate with --compact, failures would only show a single line with checkmarks but provide NO details about what failed. This made debugging impossible without re-running in verbose mode. Now compact mode still shows the failure details table when checks fail, providing developers with immediate actionable error information while maintaining the compact summary format. Changes: - Modified CertifyCommand to display failureRows table in compact mode when verdict is rejected - Added tests to verify failure details are shown in compact mode - Maintains 100% test coverage Fixes #24
📝 WalkthroughWalkthroughThis PR adds three branding constants (SECURITY, SYNTAX, CERTIFICATION) to App\Branding, updates CertifyCommand to show failure details in compact mode when the verdict is rejected, and applies widespread stylistic normalization (zero-arg constructor syntax, string-concat spacing, docblock/blank-line tweaks) across production and test files. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant CLI
participant CertifyCommand
participant CheckRunner
participant TableRenderer
User->>CLI: run gate --compact
CLI->>CertifyCommand: invoke handle()
CertifyCommand->>CheckRunner: run checks (Tests, Security, Syntax, ...)
CheckRunner-->>CertifyCommand: results + verdict
CertifyCommand->>CertifyCommand: build compactResults + failureRows
alt verdict approved
CertifyCommand->>CLI: print compact summary (approved)
else verdict rejected
CertifyCommand->>CLI: print compact summary (rejected)
CertifyCommand->>TableRenderer: render failure table (failureRows)
TableRenderer-->>CLI: printed failure details
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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. Comment |
Add expectOutputRegex() calls to tests that output failure tables in compact mode. PHPUnit's beStrictAboutOutputDuringTests setting requires tests to explicitly expect output, otherwise they are marked as risky and fail in CI. Tests now properly declare they expect output when running certify --compact with failures, preventing risky test warnings while maintaining test coverage. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add expectOutputRegex() calls to all tests that output in compact mode. PHPUnit's beStrictAboutOutputDuringTests setting requires tests to explicitly expect output, otherwise they are marked as risky and fail in CI. Tests now properly declare they expect output when running certify --compact, preventing risky test warnings while maintaining 100% test coverage. Fixes: - Added expectOutputRegex to "outputs compact format when --compact option is set and all checks pass" - Added expectOutputRegex to "outputs compact format when --compact option is set and a check fails" - Added expectOutputRegex to "shows failure details in compact mode when checks fail" - Added expectOutputRegex to "shows failure details for multiple failing checks in compact mode" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add expectOutputRegex() to capture table output in compact mode tests
- Add expectsOutputToContain('✗ REJECTED') assertions to verify output
- Fixes risky test warnings for compact mode failure detail tests
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @tests/Unit/Commands/CertifyCommandTest.php:
- Around line 395-424: The test "does not show failure table in compact mode
when all checks pass" is missing the expectOutputRegex('/.*/s') call which other
compact-mode tests include; add ->expectOutputRegex('/.*/s') into the assertion
chain on $this->artisan('certify', ['--compact' => true]) (the same chain that
currently calls ->assertSuccessful()->expectsOutputToContain('✓
APPROVED')->doesntExpectOutputToContain('Check')->doesntExpectOutputToContain('Issue')
) so PHPUnit's strict output mode won't mark the test as risky.
🧹 Nitpick comments (1)
tests/Unit/Commands/CertifyCommandTest.php (1)
362-393: Consider adding explicit assertions for failure detail content.Both tests verify that compact mode "shows failure details" (as stated in their names), but they only assert the presence of the verdict ('✗ REJECTED'), not the actual failure details. To more thoroughly verify the PR objective—that failure details are displayed in compact mode—consider adding assertions for specific failure content.
For example, in the first test you could check for the failure details that were set up:
->expectsOutputToContain('FooTest failed') ->expectsOutputToContain('BarTest failed');Or verify the failure table headers are present:
->expectsOutputToContain('Check') ->expectsOutputToContain('Issue');This would provide stronger evidence that the failure details table is actually rendered, not just the verdict.
Also applies to: 426-454
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
tests/Unit/Commands/CertifyCommandTest.php
🧰 Additional context used
🧬 Code graph analysis (1)
tests/Unit/Commands/CertifyCommandTest.php (3)
app/Commands/CertifyCommand.php (1)
CertifyCommand(21-226)app/Checks/CheckResult.php (3)
CheckResult(7-24)fail(20-23)pass(15-18)app/GitHub/ChecksClient.php (1)
ChecksClient(10-203)
🔇 Additional comments (2)
tests/Unit/Commands/CertifyCommandTest.php (2)
17-17: LGTM: Modern PHP syntax for zero-argument constructors.The removal of parentheses for zero-argument constructor invocation is valid PHP 8.0+ syntax and aligns with the project-wide modernization mentioned in the PR summary.
292-293: LGTM: Proper PHPUnit output expectations.The
expectOutputRegex('/.*/s')calls correctly declare expected output to satisfy PHPUnit's strict output mode, preventing "risky test" warnings. The explanatory comment on line 321 is helpful.Also applies to: 321-322
| it('does not show failure table in compact mode when all checks pass', function () { | ||
| $testsCheck = Mockery::mock(CheckInterface::class); | ||
| $testsCheck->shouldReceive('name')->andReturn('Tests & Coverage'); | ||
| $testsCheck->shouldReceive('run') | ||
| ->once() | ||
| ->andReturn(CheckResult::pass('All tests passed')); | ||
|
|
||
| $securityCheck = Mockery::mock(CheckInterface::class); | ||
| $securityCheck->shouldReceive('name')->andReturn('Security Audit'); | ||
| $securityCheck->shouldReceive('run') | ||
| ->once() | ||
| ->andReturn(CheckResult::pass('No vulnerabilities')); | ||
|
|
||
| $mock = new MockHandler([ | ||
| new Response(201), | ||
| new Response(201), | ||
| new Response(201), | ||
| ]); | ||
| $httpClient = new Client(['handler' => HandlerStack::create($mock)]); | ||
| $checksClient = new ChecksClient('token', $httpClient, 'owner/repo', 'sha123'); | ||
|
|
||
| ($this->createCommand)([$testsCheck, $securityCheck], $checksClient); | ||
|
|
||
| // Should only output compact summary, no failure table | ||
| $this->artisan('certify', ['--compact' => true]) | ||
| ->assertSuccessful() | ||
| ->expectsOutputToContain('✓ APPROVED') | ||
| ->doesntExpectOutputToContain('Check') | ||
| ->doesntExpectOutputToContain('Issue'); | ||
| }); |
There was a problem hiding this comment.
Add expectOutputRegex for consistency and to prevent risky test warnings.
This test produces output (the compact summary) but is missing the expectOutputRegex('/.*/s') call that other compact mode tests include (lines 292, 321, 388, 449). Without it, PHPUnit's strict output mode may flag this test as risky.
🔧 Suggested fix
($this->createCommand)([$testsCheck, $securityCheck], $checksClient);
+ $this->expectOutputRegex('/.*/s');
+
// Should only output compact summary, no failure table
$this->artisan('certify', ['--compact' => true])📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| it('does not show failure table in compact mode when all checks pass', function () { | |
| $testsCheck = Mockery::mock(CheckInterface::class); | |
| $testsCheck->shouldReceive('name')->andReturn('Tests & Coverage'); | |
| $testsCheck->shouldReceive('run') | |
| ->once() | |
| ->andReturn(CheckResult::pass('All tests passed')); | |
| $securityCheck = Mockery::mock(CheckInterface::class); | |
| $securityCheck->shouldReceive('name')->andReturn('Security Audit'); | |
| $securityCheck->shouldReceive('run') | |
| ->once() | |
| ->andReturn(CheckResult::pass('No vulnerabilities')); | |
| $mock = new MockHandler([ | |
| new Response(201), | |
| new Response(201), | |
| new Response(201), | |
| ]); | |
| $httpClient = new Client(['handler' => HandlerStack::create($mock)]); | |
| $checksClient = new ChecksClient('token', $httpClient, 'owner/repo', 'sha123'); | |
| ($this->createCommand)([$testsCheck, $securityCheck], $checksClient); | |
| // Should only output compact summary, no failure table | |
| $this->artisan('certify', ['--compact' => true]) | |
| ->assertSuccessful() | |
| ->expectsOutputToContain('✓ APPROVED') | |
| ->doesntExpectOutputToContain('Check') | |
| ->doesntExpectOutputToContain('Issue'); | |
| }); | |
| it('does not show failure table in compact mode when all checks pass', function () { | |
| $testsCheck = Mockery::mock(CheckInterface::class); | |
| $testsCheck->shouldReceive('name')->andReturn('Tests & Coverage'); | |
| $testsCheck->shouldReceive('run') | |
| ->once() | |
| ->andReturn(CheckResult::pass('All tests passed')); | |
| $securityCheck = Mockery::mock(CheckInterface::class); | |
| $securityCheck->shouldReceive('name')->andReturn('Security Audit'); | |
| $securityCheck->shouldReceive('run') | |
| ->once() | |
| ->andReturn(CheckResult::pass('No vulnerabilities')); | |
| $mock = new MockHandler([ | |
| new Response(201), | |
| new Response(201), | |
| new Response(201), | |
| ]); | |
| $httpClient = new Client(['handler' => HandlerStack::create($mock)]); | |
| $checksClient = new ChecksClient('token', $httpClient, 'owner/repo', 'sha123'); | |
| ($this->createCommand)([$testsCheck, $securityCheck], $checksClient); | |
| $this->expectOutputRegex('/.*/s'); | |
| // Should only output compact summary, no failure table | |
| $this->artisan('certify', ['--compact' => true]) | |
| ->assertSuccessful() | |
| ->expectsOutputToContain('✓ APPROVED') | |
| ->doesntExpectOutputToContain('Check') | |
| ->doesntExpectOutputToContain('Issue'); | |
| }); |
🤖 Prompt for AI Agents
In @tests/Unit/Commands/CertifyCommandTest.php around lines 395 - 424, The test
"does not show failure table in compact mode when all checks pass" is missing
the expectOutputRegex('/.*/s') call which other compact-mode tests include; add
->expectOutputRegex('/.*/s') into the assertion chain on
$this->artisan('certify', ['--compact' => true]) (the same chain that currently
calls ->assertSuccessful()->expectsOutputToContain('✓
APPROVED')->doesntExpectOutputToContain('Check')->doesntExpectOutputToContain('Issue')
) so PHPUnit's strict output mode won't mark the test as risky.
Summary
Fixes #24 - Compact mode now displays failure details when checks fail, preventing developers from having to re-run tests in verbose mode to see what went wrong.
Problem
When running gate with
--compact, failures showed only checkmarks with no details:Developers had no information about:
Solution
Modified
CertifyCommand.phpto display the failure details table even in compact mode when verdict is rejected. The compact summary is still shown first, followed by the detailed failure table.Before:
After:
Changes
CertifyCommand::handle()to showfailureRowstable after compact output when verdict is not approvedTest Plan
Summary by CodeRabbit
New Features
Improvements
Tests
✏️ Tip: You can customize this high-level summary in your review settings.