Skip to content

refactor: implement object-oriented validation architecture with unified rendering system#18

Merged
konradmichalik merged 4 commits intomainfrom
validation-run
Jul 7, 2025
Merged

refactor: implement object-oriented validation architecture with unified rendering system#18
konradmichalik merged 4 commits intomainfrom
validation-run

Conversation

@konradmichalik
Copy link
Copy Markdown
Contributor

@konradmichalik konradmichalik commented Jul 7, 2025

Summary

Major architectural refactoring that transforms the translation validator from legacy array-based processing to a modern object-oriented architecture. This change eliminates nested loops, improves maintainability, and provides unified rendering for both CLI and JSON output formats.

Key Architectural Changes

  • Eliminated 4-level nested loop in ValidateTranslationCommand.php:132 → Clean 3-line validation approach
  • Object-oriented result handling with ValidationResult, ValidationRun, Issue, and FileSet classes
  • Unified rendering system with ValidationResultCliRenderer and ValidationResultJsonRenderer
  • Enhanced validator interface with hasIssues(), getIssues(), and addIssue() methods

New Classes

  • ValidationResult - Core result aggregation with validator instances
  • ValidationRun - Orchestrates validation execution across file sets
  • Issue - Encapsulates individual validation issues
  • FileSet - Represents grouped translation files
  • ValidationResultCliRenderer - Object-oriented CLI output rendering
  • ValidationResultJsonRenderer - Object-oriented JSON output rendering

Benefits

  • 94.55% test coverage (increased from 85.83%)
  • Maintainable code with clear separation of concerns
  • Consistent API across CLI and JSON output formats
  • Extensible architecture for future renderer types
  • Backward compatibility maintained for existing functionality

Test Coverage

  • 184 tests, 421 assertions - All passing
  • Comprehensive test suite for all new classes and methods
  • PHPStan clean - Zero static analysis errors

Test plan

  • All existing tests pass
  • New comprehensive test suite covers all new functionality
  • CLI output maintains exact same formatting and behavior
  • JSON output maintains exact same structure and compatibility
  • PHPStan static analysis passes with zero errors
  • Code coverage exceeds 94% (target was 93%+)
  • Manual testing of both CLI and JSON formats with real validation files

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Introduced structured validation results and issue reporting for translation validation.
    • Added CLI and JSON output renderers for validation results with improved grouping and summaries.
    • Enhanced validator interface with standardized issue management methods.
    • Added new classes for encapsulating file sets and issues.
  • Refactor

    • Centralized validation logic and result aggregation, simplifying command execution and output handling.
    • Refactored validators to use dedicated issue objects and improved state management.
  • Bug Fixes

    • Improved compatibility in issue rendering and ensured correct state resets between validation runs.
  • Tests

    • Added comprehensive tests for new classes, validation result aggregation, CLI/JSON renderers, and validator state management.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jul 7, 2025

Walkthrough

This update introduces a major refactor of the translation validation system. It adds new classes to encapsulate file sets, issues, validation results, and output rendering. The validation execution is centralized in a new ValidationRun class, and validators now use a formal Issue object. Output handling and test coverage are updated to reflect these structural changes.

Changes

File(s) Change Summary
src/Command/ValidateTranslationCommand.php Refactored to delegate validation to ValidationRun and use ValidationResult for output.
src/FileDetector/FileSet.php New FileSet class for grouping files and metadata.
src/Result/Issue.php New Issue class for encapsulating validation issues.
src/Result/Output.php Constructor now takes ValidationResult; refactored to use new renderers.
src/Result/ValidationResult.php New ValidationResult class for aggregating results and issues.
src/Result/ValidationResultCliRenderer.php New class for CLI rendering of validation results.
src/Result/ValidationResultJsonRenderer.php New class for JSON rendering of validation results.
src/Result/ValidationRun.php New ValidationRun class for executing validators over file sets.
src/Validator/AbstractValidator.php Now implements ValidatorInterface; uses Issue objects; adds state reset and issue management methods.
src/Validator/DuplicateValuesValidator.php, src/Validator/MismatchValidator.php Refactored to use Issue objects, state reset, and updated issue handling.
src/Validator/ValidatorInterface.php Interface extended with methods for issue management (hasIssues, getIssues, addIssue).
tests/src/FileDetector/FileSetTest.php New tests for FileSet.
tests/src/Result/IssueTest.php New tests for Issue.
tests/src/Result/OutputTest.php Updated to use ValidationResult in output tests.
tests/src/Result/ValidationResultCliRendererTest.php New tests for CLI renderer.
tests/src/Result/ValidationResultJsonRendererTest.php New tests for JSON renderer.
tests/src/Result/ValidationResultTest.php New tests for ValidationResult.
tests/src/Result/ValidationRunTest.php New tests for ValidationRun.
tests/src/Validator/AbstractValidatorTest.php, tests/src/Validator/DuplicateValuesValidatorTest.php, tests/src/Validator/MismatchValidatorTest.php Added/updated tests for validator state reset and issue management.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ValidateTranslationCommand
    participant ValidationRun
    participant Validator(s)
    participant ValidationResult
    participant Output
    participant Renderer

    User->>ValidateTranslationCommand: execute()
    ValidateTranslationCommand->>ValidationRun: createFileSetsFromArray()
    ValidateTranslationCommand->>ValidationRun: executeFor(fileSets, validators)
    ValidationRun->>Validator(s): validate(files)
    Validator(s)->>ValidationRun: return issues
    ValidationRun->>ValidationResult: aggregate results
    ValidateTranslationCommand->>Output: new Output(validationResult)
    Output->>Renderer: render(validationResult)
    Renderer->>User: display results
Loading

Possibly related PRs

  • #15: Adds DuplicateValuesValidator, which is refactored here to use the new Issue class and reset logic.
  • #14: Refactors output rendering in ValidateTranslationCommand, which is further updated in this PR to use new result structures.
  • #3: Adds new validators and modifies selection logic, which is now integrated with the new validation flow.

Poem

🐇
Refactor hops through fields of code,
Wrapping issues in a structured load.
Validators now reset and run,
Results and outputs—unified as one!
CLI and JSON, both now shine,
With tests that keep it all in line.
Hooray for code that’s neat and fine!

✨ 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 (1)
tests/src/Validator/AbstractValidatorTest.php (1)

293-318: Remove unused variable to address static analysis warning.

The test logic is sound but the $result variable is assigned but never used.

Apply this diff to remove the unused variable:

 // Call validate - this should reset state
 $files = ['/path/to/some_file.xlf'];
 $parserClass = TestParser::class;
-$result = $validator->validate($files, $parserClass);
+$validator->validate($files, $parserClass);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between a4eb896 and 77fb2af.

📒 Files selected for processing (22)
  • src/Command/ValidateTranslationCommand.php (3 hunks)
  • src/FileDetector/FileSet.php (1 hunks)
  • src/Result/Issue.php (1 hunks)
  • src/Result/Output.php (2 hunks)
  • src/Result/ValidationResult.php (1 hunks)
  • src/Result/ValidationResultCliRenderer.php (1 hunks)
  • src/Result/ValidationResultJsonRenderer.php (1 hunks)
  • src/Result/ValidationRun.php (1 hunks)
  • src/Validator/AbstractValidator.php (4 hunks)
  • src/Validator/DuplicateValuesValidator.php (3 hunks)
  • src/Validator/MismatchValidator.php (4 hunks)
  • src/Validator/ValidatorInterface.php (2 hunks)
  • tests/src/FileDetector/FileSetTest.php (1 hunks)
  • tests/src/Result/IssueTest.php (1 hunks)
  • tests/src/Result/OutputTest.php (4 hunks)
  • tests/src/Result/ValidationResultCliRendererTest.php (1 hunks)
  • tests/src/Result/ValidationResultJsonRendererTest.php (1 hunks)
  • tests/src/Result/ValidationResultTest.php (1 hunks)
  • tests/src/Result/ValidationRunTest.php (1 hunks)
  • tests/src/Validator/AbstractValidatorTest.php (4 hunks)
  • tests/src/Validator/DuplicateValuesValidatorTest.php (2 hunks)
  • tests/src/Validator/MismatchValidatorTest.php (2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (5)
src/Validator/DuplicateValuesValidator.php (4)
src/Result/Issue.php (1)
  • Issue (7-55)
src/Validator/AbstractValidator.php (2)
  • addIssue (109-112)
  • resetState (118-121)
src/Validator/ValidatorInterface.php (1)
  • addIssue (48-48)
src/Validator/MismatchValidator.php (1)
  • resetState (130-134)
src/Command/ValidateTranslationCommand.php (1)
src/Result/ValidationRun.php (3)
  • ValidationRun (12-67)
  • createFileSetsFromArray (53-66)
  • executeFor (23-46)
tests/src/Validator/MismatchValidatorTest.php (4)
src/Result/Issue.php (1)
  • toArray (46-54)
src/Validator/MismatchValidator.php (1)
  • MismatchValidator (16-135)
src/Validator/AbstractValidator.php (1)
  • hasIssues (96-99)
src/Validator/ValidatorInterface.php (1)
  • hasIssues (41-41)
tests/src/Validator/DuplicateValuesValidatorTest.php (4)
src/Result/Issue.php (1)
  • toArray (46-54)
src/Validator/DuplicateValuesValidator.php (1)
  • DuplicateValuesValidator (17-126)
src/Validator/AbstractValidator.php (1)
  • hasIssues (96-99)
src/Validator/ValidatorInterface.php (1)
  • hasIssues (41-41)
src/Result/ValidationResult.php (4)
src/Result/Issue.php (2)
  • __construct (12-18)
  • toArray (46-54)
src/FileDetector/FileSet.php (3)
  • __construct (12-18)
  • getPath (25-28)
  • getSetKey (30-33)
src/Validator/AbstractValidator.php (3)
  • __construct (17-19)
  • hasIssues (96-99)
  • getIssues (104-107)
src/Validator/ValidatorInterface.php (2)
  • hasIssues (41-41)
  • getIssues (46-46)
🪛 PHPMD (2.15.0)
tests/src/Result/ValidationRunTest.php

194-194: Avoid unused parameters such as '$files'. (Unused Code Rules)

(UnusedFormalParameter)


194-194: Avoid unused parameters such as '$parserClass'. (Unused Code Rules)

(UnusedFormalParameter)


202-202: Avoid unused parameters such as '$file'. (Unused Code Rules)

(UnusedFormalParameter)


207-207: Avoid unused parameters such as '$input'. (Unused Code Rules)

(UnusedFormalParameter)


207-207: Avoid unused parameters such as '$output'. (Unused Code Rules)

(UnusedFormalParameter)


207-207: Avoid unused parameters such as '$issueSets'. (Unused Code Rules)

(UnusedFormalParameter)


236-236: Avoid unused parameters such as '$issue'. (Unused Code Rules)

(UnusedFormalParameter)


252-252: Avoid unused parameters such as '$files'. (Unused Code Rules)

(UnusedFormalParameter)


252-252: Avoid unused parameters such as '$parserClass'. (Unused Code Rules)

(UnusedFormalParameter)


260-260: Avoid unused parameters such as '$file'. (Unused Code Rules)

(UnusedFormalParameter)


265-265: Avoid unused parameters such as '$input'. (Unused Code Rules)

(UnusedFormalParameter)


265-265: Avoid unused parameters such as '$output'. (Unused Code Rules)

(UnusedFormalParameter)


265-265: Avoid unused parameters such as '$issueSets'. (Unused Code Rules)

(UnusedFormalParameter)


294-294: Avoid unused parameters such as '$issue'. (Unused Code Rules)

(UnusedFormalParameter)

tests/src/Result/ValidationResultTest.php

226-226: Avoid unused parameters such as '$issue'. (Unused Code Rules)

(UnusedFormalParameter)


230-230: Avoid unused parameters such as '$files'. (Unused Code Rules)

(UnusedFormalParameter)


230-230: Avoid unused parameters such as '$parserClass'. (Unused Code Rules)

(UnusedFormalParameter)


235-235: Avoid unused parameters such as '$file'. (Unused Code Rules)

(UnusedFormalParameter)


240-240: Avoid unused parameters such as '$input'. (Unused Code Rules)

(UnusedFormalParameter)


240-240: Avoid unused parameters such as '$output'. (Unused Code Rules)

(UnusedFormalParameter)


240-240: Avoid unused parameters such as '$issueSets'. (Unused Code Rules)

(UnusedFormalParameter)


349-349: Avoid unused parameters such as '$issue'. (Unused Code Rules)

(UnusedFormalParameter)


353-353: Avoid unused parameters such as '$files'. (Unused Code Rules)

(UnusedFormalParameter)


353-353: Avoid unused parameters such as '$parserClass'. (Unused Code Rules)

(UnusedFormalParameter)


358-358: Avoid unused parameters such as '$file'. (Unused Code Rules)

(UnusedFormalParameter)


363-363: Avoid unused parameters such as '$input'. (Unused Code Rules)

(UnusedFormalParameter)


363-363: Avoid unused parameters such as '$output'. (Unused Code Rules)

(UnusedFormalParameter)


363-363: Avoid unused parameters such as '$issueSets'. (Unused Code Rules)

(UnusedFormalParameter)

tests/src/Validator/AbstractValidatorTest.php

311-311: Avoid unused local variables such as '$result'. (Unused Code Rules)

(UnusedLocalVariable)

🔇 Additional comments (52)
src/FileDetector/FileSet.php (1)

1-42: LGTM! Clean data class implementation.

The FileSet class is well-structured with proper immutability using readonly properties, clear type annotations, and simple getters. This design aligns perfectly with the object-oriented refactoring goals.

tests/src/Result/OutputTest.php (3)

34-42: Test correctly updated for ValidationResult architecture.

The test properly creates a ValidationResult instance and passes it to the Output constructor, aligning with the new object-oriented validation result handling.


52-60: Test correctly updated for ValidationResult architecture.

The JSON format test properly uses the new ValidationResult object structure.


75-83: Test correctly updated for ValidationResult architecture.

The failure test case properly uses the new ValidationResult object with ResultType::ERROR.

src/Validator/DuplicateValuesValidator.php (3)

10-10: Correctly imported Issue class.

The import is properly added to support the new object-oriented issue handling.


56-61: Proper Issue object construction.

The Issue object is correctly instantiated with the file name, duplicates data, empty parser string (appropriate for validator-level issues), and validator type. This aligns with the new object-oriented architecture.


116-120: Correct resetState() implementation.

The method properly calls the parent's resetState() and resets the validator's internal state (valuesArray). This follows the established pattern from other validators and ensures clean state between validation runs.

src/Validator/ValidatorInterface.php (2)

8-8: Correctly imported Issue class.

The import is properly added to support the new Issue-based method signatures.


41-48: Well-designed interface extension for issue management.

The three new methods provide a clean API for issue management:

  • hasIssues() for checking if issues exist
  • getIssues() for retrieving Issue objects
  • addIssue() for adding new issues

The method signatures are clear and follow good interface design principles.

tests/src/Validator/DuplicateValuesValidatorTest.php (3)

134-135: Correctly updated expected data structure.

The test properly includes the new parser and type fields that are part of the Issue object structure, aligning with the object-oriented refactoring.

Also applies to: 142-143


147-147: Proper assertion for Issue objects.

The assertion correctly uses array_map with toArray() to compare the Issue objects, which is the appropriate way to test the new object-oriented structure.


174-206: Comprehensive test for resetState() method.

The test thoroughly verifies that resetState() properly clears both the validator's internal valuesArray and the inherited issues. The use of reflection to test private methods and properties is appropriate for ensuring proper state management.

tests/src/FileDetector/FileSetTest.php (1)

1-94: Excellent comprehensive test coverage for FileSet class.

The test suite thoroughly covers all aspects of the FileSet class including:

  • Constructor validation with all parameters
  • Individual getter method testing
  • Edge cases with empty strings and arrays
  • Real-world data scenarios
  • Proper PHPUnit structure and naming conventions

The tests provide good confidence in the FileSet implementation and follow testing best practices.

tests/src/Result/IssueTest.php (1)

1-112: Comprehensive test coverage for the Issue class.

The test suite excellently covers all aspects of the Issue class:

  • Constructor validation with all parameters
  • Individual getter method testing
  • toArray() method with various complexity levels (empty, simple, complex nested structures)
  • Proper assertions and test structure

The tests for toArray() are particularly well-designed, covering edge cases and complex data structures that will likely be encountered in real-world usage.

tests/src/Validator/MismatchValidatorTest.php (3)

89-104: Proper adaptation to new Issue class structure.

The expected issues structure has been correctly updated to match the new Issue class format, including the nested 'issues' key and additional metadata fields ('file', 'parser', 'type').


126-126: Correct assertion adaptation for Issue objects.

The assertion correctly maps Issue objects to their array representation using toArray(), which is the appropriate way to test the new Issue-based structure.


156-183: Valuable addition: resetState test for proper state management.

This new test ensures that the resetState() method properly clears both the validator-specific $keyArray and the inherited issues collection. This is crucial for validators that might be reused across multiple validation runs.

The test correctly uses reflection to access protected members and verify internal state, which is appropriate for testing state management functionality.

src/Result/Issue.php (1)

1-55: Well-designed Issue class with proper encapsulation.

The Issue class demonstrates excellent object-oriented design:

  • Immutability: Uses readonly properties to ensure data integrity
  • Type safety: Proper type declarations and docblocks for array types
  • Encapsulation: Private properties with public getter methods
  • Interoperability: toArray() method for legacy compatibility and serialization
  • Clear structure: Well-organized with logical method ordering

The class effectively replaces the previous ad-hoc array structures with a proper value object, improving type safety and maintainability throughout the validation system.

tests/src/Result/ValidationResultJsonRendererTest.php (1)

1-207: Comprehensive and well-structured JSON renderer test suite.

This test suite excellently covers all aspects of the ValidationResultJsonRenderer:

Coverage highlights:

  • Success scenarios: No issues, proper exit codes and JSON structure
  • Error scenarios: With issues, proper error reporting and exit codes
  • Mode variations: Dry run, strict mode, warning handling
  • Output validation: JSON format validation, proper indentation, valid JSON structure
  • Legacy compatibility: Ensures output structure matches expected format

Implementation quality:

  • Proper use of PHPUnit features (setUp, mocking, assertions)
  • BufferedOutput for clean output capture
  • Helper methods for maintainable test code
  • Comprehensive assertions covering both functional and structural aspects

The tests provide strong confidence in the JSON renderer's behavior across all expected usage scenarios.

src/Command/ValidateTranslationCommand.php (3)

12-12: Import addition aligns with the architectural refactoring.

The addition of the ValidationRun import supports the new object-oriented validation architecture.


130-133: Excellent refactoring that eliminates complex nested loops.

The replacement of the previous 4-level nested loop with this clean object-oriented approach significantly improves maintainability and code clarity:

  1. ValidationRun::createFileSetsFromArray() converts raw arrays to structured FileSet objects
  2. ValidationRun::executeFor() centralizes validation logic and result aggregation
  3. The ValidationResult object encapsulates all validation outcomes

This change aligns perfectly with the PR objectives of implementing a modern object-oriented validation architecture.


148-148: Constructor parameter change aligns with the unified result system.

Passing the ValidationResult object instead of separate parameters simplifies the constructor call and supports the new unified rendering system.

src/Result/ValidationResultJsonRenderer.php (3)

9-16: Well-structured constructor with proper dependency injection.

The constructor follows good design patterns with readonly properties and clear parameter defaults for the dry-run and strict mode flags.


18-33: Robust JSON rendering with proper error handling.

The implementation includes several good practices:

  • Uses ValidationResult::getOverallResult() to calculate exit codes consistently
  • Includes comprehensive JSON output with status, message, and issues
  • Uses proper JSON encoding flags (JSON_THROW_ON_ERROR, JSON_PRETTY_PRINT, JSON_UNESCAPED_UNICODE)
  • Returns the calculated exit code for command execution

51-55: Maintains backward compatibility through legacy array format.

The use of ValidationResult::toLegacyArray() ensures that existing JSON consumers continue to work with the same data structure, which is crucial for maintaining backward compatibility during this architectural refactoring.

src/Result/Output.php (2)

21-21: Constructor simplification supports the unified result system.

The change from separate ResultType and array $issues parameters to a single ValidationResult object encapsulates all validation data in one cohesive structure, improving the API design.


37-50: Clean renderer selection with match expression.

The match expression provides a clear, type-safe way to instantiate the appropriate renderer based on the format. The direct instantiation of ValidationResultCliRenderer and ValidationResultJsonRenderer eliminates the need for a factory pattern, simplifying the codebase while maintaining the same functionality.

src/Result/ValidationResult.php (3)

10-21: Well-designed constructor with proper type safety.

The constructor properly types all parameters and uses readonly properties for immutability. The optional $validatorFileSetPairs parameter with default empty array allows for backward compatibility while supporting the new enhanced functionality.


23-32: Efficient issue detection implementation.

The hasIssues() method uses early return optimization, checking each validator's hasIssues() method and returning immediately when issues are found, which is more efficient than collecting all issues first.


66-112: Comprehensive backward compatibility with dual-mode legacy array conversion.

The toLegacyArray() method excellently handles both scenarios:

  1. New mode (lines 70-95): Uses validator-fileSet pairs to provide accurate path and set key information, organizing issues by validator class, path, and set key
  2. Fallback mode (lines 97-108): Maintains backward compatibility by using empty strings for path and set key when validator-fileSet pairs are not available

The nested array structure preserves the existing JSON format while leveraging the new Issue::toArray() method for consistent issue representation.

tests/src/Result/ValidationResultCliRendererTest.php (5)

19-33: Excellent test setup with proper mocking infrastructure.

The test setup uses BufferedOutput for capturing output and mocked InputInterface for controlled testing, providing a solid foundation for testing the CLI renderer behavior.


35-43: Clean test for success scenario.

The test properly verifies both the exit code (0) and the expected success message, covering the basic happy path scenario.


45-66: Comprehensive test for issues scenario with proper mock setup.

The test creates a realistic scenario with:

  • Mock validator with issues
  • Proper Issue object with test data
  • FileSet with test path and files
  • ValidationResult with validator-fileSet pairs

The assertions verify both exit code and presence of expected output elements.


172-197: Excellent test for multiple validators scenario.

This test verifies the renderer's ability to handle multiple file sets for the same validator, ensuring that both paths are included in the output. This is important for validating the grouping logic in the CLI renderer.


199-206: Well-structured mock validator helper method.

The helper method provides consistent mock setup with proper method stubs for renderIssueSets() and explain(), ensuring all tests use the same mock behavior.

src/Result/ValidationRun.php (2)

23-46: Good state isolation with fresh validator instances

Creating fresh validator instances for each file set (line 32) ensures proper state isolation between validation runs. This prevents issues where validators might accumulate state across different file sets.


34-41: Efficient filtering of validators with issues

The logic correctly filters out validators that don't produce any results, keeping only those with actual issues. This reduces memory usage and simplifies downstream processing.

tests/src/Result/ValidationRunTest.php (1)

14-180: Comprehensive test coverage

The test suite thoroughly covers various scenarios including edge cases (empty inputs), single and multiple validators/file sets, and the static factory method. Good job on the test design!

src/Validator/AbstractValidator.php (2)

31-33: Essential state reset for validator reusability

The resetState() call ensures validators start with a clean state for each validation run. This is crucial for the architecture where validator instances may be reused.


62-73: Improved type safety with Issue objects

The refactoring to use Issue objects internally while maintaining backward compatibility through toArray() mapping is well done. This provides better type safety and structure while preserving existing interfaces.

src/Validator/MismatchValidator.php (1)

86-91: Good backward compatibility handling

The dual format support ensures smooth transition from the old array format to the new Issue-based structure. This prevents breaking changes during the refactoring.

src/Result/ValidationResultCliRenderer.php (1)

14-137: Well-designed CLI renderer with good separation of concerns

The renderer effectively organizes output by validator and path, provides appropriate styling, and maintains backward compatibility. The use of PathUtility::normalizeFolderPath ensures consistent path display across different environments.

tests/src/Result/ValidationResultTest.php (5)

170-213: LGTM! Well-structured anonymous class implementation.

The anonymous class implementation provides a clean way to test different validator behaviors without creating separate test classes. The empty method stubs are appropriate for testing purposes.


215-258: LGTM! Consistent anonymous class pattern.

The second anonymous class follows the same pattern as the first, providing controlled test scenarios for validation result aggregation.


125-141: LGTM! Comprehensive test coverage for legacy array conversion.

The test properly validates the toLegacyArray method behavior when validator-file set pairs are not provided, ensuring the correct nested array structure is maintained.


143-165: LGTM! Validates file set integration in legacy array.

The test confirms that validator-file set pairs are properly integrated into the legacy array structure, maintaining backward compatibility.


291-399: LGTM! Thorough test of mixed validator scenarios.

The test properly validates that only validators with issues are included in the legacy array, which is the expected behavior for maintaining backward compatibility.

tests/src/Validator/AbstractValidatorTest.php (5)

29-32: LGTM! Enhanced test scenario for resetState functionality.

The additional condition provides a specific test case for validating the resetState functionality, which is crucial for ensuring validators start with clean state.


63-68: LGTM! Updated to use Issue objects.

The refactoring to use the new Issue class aligns with the architectural improvements, providing better encapsulation of validation issues.


191-197: LGTM! Updated assertion format.

The test assertion correctly validates the expected array structure after the Issue object refactoring.


199-268: LGTM! Comprehensive issue management API tests.

The new test methods provide thorough coverage of the issue management functionality, including state validation, collection operations, and proper encapsulation.


270-291: LGTM! Validates state reset functionality.

The test properly validates that resetState clears all issues, which is essential for validator reusability.

Comment on lines +65 to +70
$this->addIssue(new Issue(
'',
$result,
'',
'MismatchValidator'
));
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider providing meaningful values for Issue properties

The Issue object is created with empty strings for filename and parserClass. Since this validator works across multiple files, consider using a more descriptive approach, such as:

  • Using a combined filename like "multiple_files" or listing the affected files
  • Specifying the parser class from the processed files
🤖 Prompt for AI Agents
In src/Validator/MismatchValidator.php around lines 65 to 70, the Issue object
is created with empty strings for filename and parserClass, which reduces
clarity. Update the code to provide meaningful values by setting filename to a
descriptive string like "multiple_files" or a list of affected files, and set
parserClass to the relevant parser class name used in the validation process to
improve issue traceability.

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