Skip to content

feat: introduce ResultType enum for improved validation result handling#13

Merged
konradmichalik merged 3 commits intomainfrom
result-type
Jul 2, 2025
Merged

feat: introduce ResultType enum for improved validation result handling#13
konradmichalik merged 3 commits intomainfrom
result-type

Conversation

@konradmichalik
Copy link
Copy Markdown
Contributor

@konradmichalik konradmichalik commented Jul 1, 2025

Summary by CodeRabbit

  • New Features

    • Improved validation feedback in the command-line tool with more detailed result states (Success, Warning, Error).
    • Command-line output now provides clearer messages and exit codes based on overall validation results and mode (dry-run or strict).
    • Added a strict mode option to treat warnings as errors during validation.
  • Refactor

    • Centralized and formalized handling of validation outcomes for more consistent user experience.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jul 1, 2025

Walkthrough

A new ResultType enum was introduced to standardize validation result states across the codebase. The validation command now aggregates result types from each validator using this enum, centralizing outcome handling and exit code determination. Validator interfaces and base classes were updated to specify their failure result type via a new method.

Changes

File(s) Change Summary
src/Command/ValidateTranslationCommand.php Refactored to track and aggregate validation results using ResultType; added strict option; updated CLI rendering and exit code logic.
src/Validator/ResultType.php Introduced ResultType enum with cases SUCCESS, WARNING, ERROR and methods for comparison, status checking, and exit code resolution.
src/Validator/ValidatorInterface.php
src/Validator/AbstractValidator.php
Added resultTypeOnValidationFailure() method to interface and base class for specifying failure result type.
tests/src/Validator/ResultTypeTest.php Added PHPUnit tests covering ResultType methods and their logic for severity comparison and exit code resolution.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant CLI
    participant ValidateTranslationCommand
    participant Validator(s)
    participant ResultType

    User->>CLI: Run validation command
    CLI->>ValidateTranslationCommand: execute()
    loop For each Validator
        ValidateTranslationCommand->>Validator(s): validate()
        Validator(s)-->>ValidateTranslationCommand: issues, resultTypeOnValidationFailure()
        ValidateTranslationCommand->>ResultType: max(current, validatorResultType)
        ResultType-->>ValidateTranslationCommand: updated resultType
    end
    ValidateTranslationCommand->>CLI: renderCliResult() using aggregated ResultType
    CLI-->>User: Output message and exit code based on ResultType
Loading

Possibly related PRs

Poem

A hop and a skip through the code we go,
With enums and types, our results now show.
Validators report if things go awry,
And the command sums up, never shy.
With warnings and errors now neatly in tow,
The rabbit approves—onward we grow! 🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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 (3)
src/Validator/ResultType.php (1)

25-36: Consider documenting the strict mode behavior.

The method handles strict mode only for WARNING cases but not for ERROR. This is likely intentional (errors always fail regardless of strict mode), but it would be helpful to add a PHPDoc comment explaining this behavior for clarity.

+    /**
+     * Resolves the result type to a command exit code.
+     * 
+     * @param bool $dryRun If true, always returns SUCCESS
+     * @param bool $strict If true, treats WARNINGs as failures
+     * @return int Command exit code (SUCCESS or FAILURE)
+     */
     public function resolveErrorToCommandExitCode(bool $dryRun, bool $strict): int
src/Command/ValidateTranslationCommand.php (2)

111-117: Consider performance impact of instantiating validators in the loop.

Moving validator instantiation inside the nested loops (line 111) means the same validator class could be instantiated multiple times. This might impact performance for large file sets.

Consider caching validator instances:

 $validators = $input->getOption('validator') ? [$input->getOption('validator')] : ValidatorRegistry::getAvailableValidators();
 $issues = [];
+$validatorInstances = [];

 // ToDo: Simplify this nested loop structure
 foreach ($allFiles as $parser => $paths) {
     foreach ($paths as $path => $translationSets) {
         foreach ($translationSets as $setKey => $files) {
             foreach ($validators as $validator) {
-                $validatorInstance = new $validator($this->logger);
+                if (!isset($validatorInstances[$validator])) {
+                    $validatorInstances[$validator] = new $validator($this->logger);
+                }
+                $validatorInstance = $validatorInstances[$validator];
                 $result = $validatorInstance->validate($files, $parser);

194-199: Consider simplifying the else clause (optional).

The static analysis tool suggests removing the else clause for cleaner code. While the current code is readable, you could consider early return pattern.

 if ($this->resultType->notFullySuccessful()) {
     $this->io->newLine();
     $this->io->{$this->dryRun ? 'warning' : 'error'}(
         $this->dryRun
             ? 'Language validation failed and completed in dry-run mode.'
             : 'Language validation failed.'
     );
-} else {
-    $message = 'Language validation succeeded.';
-    $this->output->isVerbose()
-        ? $this->io->success($message)
-        : $this->output->writeln('<fg=green>'.$message.'</>');
+    return $this->resultType->resolveErrorToCommandExitCode($this->dryRun, false);
 }

-return $this->resultType->resolveErrorToCommandExitCode($this->dryRun, false);
+$message = 'Language validation succeeded.';
+$this->output->isVerbose()
+    ? $this->io->success($message)
+    : $this->output->writeln('<fg=green>'.$message.'</>');
+
+return Command::SUCCESS;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between abafa79 and 47aec35.

📒 Files selected for processing (4)
  • src/Command/ValidateTranslationCommand.php (4 hunks)
  • src/Validator/AbstractValidator.php (1 hunks)
  • src/Validator/ResultType.php (1 hunks)
  • src/Validator/ValidatorInterface.php (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/Validator/ValidatorInterface.php (1)
src/Validator/AbstractValidator.php (1)
  • resultTypeOnValidationFailure (87-90)
src/Validator/AbstractValidator.php (1)
src/Validator/ValidatorInterface.php (1)
  • resultTypeOnValidationFailure (38-38)
🪛 PHPMD (2.15.0)
src/Command/ValidateTranslationCommand.php

194-199: The method renderCliResult uses an else expression. Else clauses are basically not necessary and you can simplify the code by not using them. (Clean Code Rules)

(ElseExpression)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Code Coverage Report
🔇 Additional comments (5)
src/Validator/AbstractValidator.php (1)

87-90: LGTM! Good default implementation.

The method correctly implements the interface requirement with a sensible default of ResultType::ERROR for validation failures.

src/Validator/ValidatorInterface.php (1)

38-38: ResultType import verified; no changes required

ResultType is declared in the same namespace (MoveElevator\ComposerTranslationValidator\Validator) and no other ResultType definitions were found. The method signature in ValidatorInterface.php is correct as-is—no explicit import is needed.

src/Validator/ResultType.php (1)

9-37: Well-designed enum with clear severity levels.

The enum provides a clean abstraction for validation results with appropriate comparison and exit code resolution methods.

src/Command/ValidateTranslationCommand.php (2)

32-32: Good initialization of ResultType property.

Starting with SUCCESS and updating based on validation results is the correct approach.


187-201: Clean refactoring of result handling logic.

The use of ResultType for determining output and exit codes is much cleaner than the previous approach. The logic is now centralized and easier to maintain.

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

🧹 Nitpick comments (1)
tests/src/Validator/ResultTypeTest.php (1)

29-66: Excellent comprehensive testing of resolveErrorToCommandExitCode() method.

The test covers all 12 possible combinations (3 enum values × 2 dryRun flags × 2 strict flags) with clear comments explaining each scenario. The expected results align perfectly with the implementation logic:

  • ERROR fails unless it's a dry run
  • WARNING fails only in strict mode
  • SUCCESS always succeeds

The explicit approach makes the test cases very clear and maintainable.

For future maintenance, you could consider using a data provider to make the test more concise:

/**
 * @dataProvider resolveErrorToCommandExitCodeProvider
 */
public function testResolveErrorToCommandExitCode(ResultType $resultType, bool $dryRun, bool $strict, int $expected): void
{
    $this->assertSame($expected, $resultType->resolveErrorToCommandExitCode($dryRun, $strict));
}

public function resolveErrorToCommandExitCodeProvider(): array
{
    return [
        'ERROR, not dryRun, not strict' => [ResultType::ERROR, false, false, Command::FAILURE],
        'ERROR, dryRun, not strict' => [ResultType::ERROR, true, false, Command::SUCCESS],
        // ... other test cases
    ];
}

However, the current explicit approach is also perfectly valid and may be more readable for this specific case.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 47aec35 and 1493bed.

📒 Files selected for processing (2)
  • src/Command/ValidateTranslationCommand.php (5 hunks)
  • tests/src/Validator/ResultTypeTest.php (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Command/ValidateTranslationCommand.php
🧰 Additional context used
🧬 Code Graph Analysis (1)
tests/src/Validator/ResultTypeTest.php (1)
src/Validator/ResultType.php (3)
  • max (15-18)
  • notFullySuccessful (20-23)
  • resolveErrorToCommandExitCode (25-36)
🔇 Additional comments (3)
tests/src/Validator/ResultTypeTest.php (3)

1-10: Well-structured test file with proper imports and conventions.

The file follows PHP and PHPUnit best practices with proper strict types declaration, namespace organization, and necessary imports.


13-20: Comprehensive test coverage for the max() method.

The test cases cover all possible severity comparisons between ResultType enum values, ensuring the method correctly identifies the more severe result type in all scenarios.


22-27: Complete coverage of notFullySuccessful() method.

All three enum values are tested with correct expected outcomes - SUCCESS returns false while WARNING and ERROR return true.

@konradmichalik konradmichalik merged commit d8972b8 into main Jul 2, 2025
24 checks passed
@konradmichalik konradmichalik deleted the result-type branch July 28, 2025 17:14
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.

1 participant